Esempio n. 1
0
 public void AddCharToCombat(Player character)
 {
     if (!_cache.IsCharInCombat(character.Id.ToString()))
     {
         _cache.AddCharToCombat(character.Id.ToString(), character);
     }
 }
Esempio n. 2
0
        public void Fight(Player player, string victim, Room room, bool isMurder)
        {
            var target = FindTarget(player, victim, room, isMurder);

            if (target == null)
            {
                if (player.Status == CharacterStatus.Status.Fighting)
                {
                    player.Target = "";
                    player.Status = CharacterStatus.Status.Standing;

                    _cache.RemoveCharFromCombat(player.Id.ToString());
                }

                _writer.WriteLine("<p>They are not here.</p>", player.ConnectionId);
                return;
            }

            if (player.Attributes.Attribute[EffectLocation.Hitpoints] <= 0)
            {
                _writer.WriteLine("<p>You cannot do that while dead.</p>", player.ConnectionId);
                return;
            }

            if (target.Attributes.Attribute[EffectLocation.Hitpoints] <= 0)
            {
                _writer.WriteLine("<p>They are already dead.</p>", player.ConnectionId);
                return;
            }

            // For the UI to create a nice gap between rounds of auto attacks
            _writer.WriteLine($"<p class='combat-start'></p>", player.ConnectionId);

            player.Target = target.Name;
            player.Status = CharacterStatus.Status.Fighting;
            target.Status = CharacterStatus.Status.Fighting;
            target.Target = string.IsNullOrEmpty(target.Target) ? player.Name : target.Target; //for group combat, if target is ganged, there target should not be changed when combat is initiated.

            if (!_cache.IsCharInCombat(player.Id.ToString()))
            {
                _cache.AddCharToCombat(player.Id.ToString(), player);
            }

            if (!_cache.IsCharInCombat(target.Id.ToString()))
            {
                _cache.AddCharToCombat(target.Id.ToString(), target);
            }
            var chanceToHit = _formulas.ToHitChance(player, target);
            var doesHit     = _formulas.DoesHit(chanceToHit);
            var weapon      = GetWeapon(player);

            if (doesHit)
            {
                // avoidance percentage can be improved by core skills
                // such as improved parry, acrobatic etc
                // instead of rolling a D10, roll a D6 for a close to 15% increase in chance

                // Move to formula, needs to use _dice instead of making a new instance
                var avoidanceRoll = new Dice().Roll(1, 1, 10);


                //10% chance to attempt a dodge
                if (avoidanceRoll == 1)
                {
                    var dodge = GetSkill("dodge", player);

                    if (dodge != null)
                    {
                        _writer.WriteLine($"<p>You dodge {target.Name}'s attack.</p>", player.ConnectionId);
                        _writer.WriteLine($"<p>{player.Name} dodges your attack.</p>", target.ConnectionId);
                        return;
                    }
                }

                //10% chance to parry
                if (avoidanceRoll == 2)
                {
                    var skill = GetSkill("parry", player);

                    if (skill != null)
                    {
                        _writer.WriteLine($"<p>You parry {target.Name}'s attack.</p>", player.ConnectionId);
                        _writer.WriteLine($"<p>{player.Name} parries your attack.</p>", target.ConnectionId);
                        return;
                    }
                }

                // Block
                if (avoidanceRoll == 3)
                {
                    //var chanceToBlock = _formulas.ToBlockChance(target, player);
                    //var doesBlock = _formulas.DoesHit(chanceToBlock);

                    //if (doesBlock)
                    //{
                    //    var skill = GetSkill("shieldblock", player);

                    //    if (skill != null)
                    //    {
                    //        _writer.WriteLine($"You block {target.Name}'s attack with your shield.", player.ConnectionId);
                    //        _writer.WriteLine($"{player.Name} blocks your attack with their shield.", player.ConnectionId);
                    //    }
                    //}
                    //else
                    //{
                    //    // block fail
                    //}
                }


                var damage = _formulas.CalculateDamage(player, target, weapon);

                if (_formulas.IsCriticalHit())
                {
                    // double damage
                    damage *= 2;
                }


                HarmTarget(target, damage);

                DisplayDamage(player, target, room, weapon, damage);

                _clientUi.UpdateHP(target);

                if (!IsTargetAlive(target))
                {
                    player.Target = String.Empty;
                    player.Status = CharacterStatus.Status.Standing;
                    target.Status = CharacterStatus.Status.Ghost;
                    target.Target = string.Empty;

                    DeathCry(room, target);

                    _gain.GainExperiencePoints(player, target);

                    _writer.WriteLine("<p class='dead'>You are dead. R.I.P.</p>", target.ConnectionId);

                    var targetName = target.Name.ToLower(CultureInfo.CurrentCulture);
                    var corpse     = new Item.Item()
                    {
                        Name        = $"The corpse of {targetName}.",
                        Description = new Description()
                        {
                            Room = $"The corpse of {targetName} is laying here.",
                            Exam = $"The corpse of {targetName} is laying here. {target.Description}",
                            Look = $"The corpse of {targetName} is laying here. {target.Description}",
                        },
                        Slot      = Equipment.EqSlot.Held,
                        Level     = 1,
                        Stuck     = true,
                        Container = new Container()
                        {
                            Items   = new ItemList(),
                            CanLock = false,
                            IsOpen  = true,
                            CanOpen = false,
                        },
                        ItemType   = Item.Item.ItemTypes.Container,
                        DecayTimer = 300 // 5 minutes
                    };

                    foreach (var item in target.Inventory)
                    {
                        corpse.Container.Items.Add(item);
                    }

                    // clear list
                    target.Inventory = new ItemList();
                    // clear equipped
                    target.Equipped = new Equipment();

                    // add corpse to room
                    room.Items.Add(corpse);
                    _clientUi.UpdateInventory(target);
                    _clientUi.UpdateEquipment(target);
                    _clientUi.UpdateScore(target);

                    room.Clean = false;

                    _cache.RemoveCharFromCombat(target.Id.ToString());
                    _cache.RemoveCharFromCombat(player.Id.ToString());

                    if (target.ConnectionId.Equals("mob", StringComparison.CurrentCultureIgnoreCase))
                    {
                        room.Mobs.Remove(target);
                    }
                    else
                    {
                        room.Players.Remove(target);
                    }
                    // take player to Temple / recall area
                }
            }
            else
            {
                DisplayMiss(player, target, room, weapon);
                // miss message
                // gain improvements on weapon skill


                SkillList getWeaponSkill = null;
                if (weapon != null && !player.ConnectionId.Equals("mob", StringComparison.CurrentCultureIgnoreCase))
                {
                    // urgh this is ugly
                    getWeaponSkill = player.Skills.FirstOrDefault(x =>
                                                                  x.SkillName.Replace(" ", string.Empty)
                                                                  .Equals(Enum.GetName(typeof(Item.Item.WeaponTypes), weapon.WeaponType)));
                }

                if (weapon == null && !player.ConnectionId.Equals("mob", StringComparison.CurrentCultureIgnoreCase))
                {
                    getWeaponSkill = player.Skills.FirstOrDefault(x =>
                                                                  x.SkillName.Equals("Hand To Hand", StringComparison.CurrentCultureIgnoreCase));
                }

                if (getWeaponSkill != null)
                {
                    getWeaponSkill.Proficiency += 1;
                    _writer.WriteLine($"<p class='improve'>Your proficiency in {getWeaponSkill.SkillName} has increased.</p>");

                    _gain.GainExperiencePoints(player, getWeaponSkill.Level * 50);
                }
            }
        }