public void AddCharToCombat(Player character) { if (!_cache.IsCharInCombat(character.Id.ToString())) { _cache.AddCharToCombat(character.Id.ToString(), character); } }
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); } } }