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); } } }
public void Fight(Player player, string victim, Room room, bool isMurder) { try { if (player.Affects.Stunned) { _writer.WriteLine("<p>You are too stunned to attack this round.<p>", player.ConnectionId); return; } // refactor this, makes no sense // murder command need its on'y check here should be generic find the target player or mob var target = FindTarget(player, victim, room, isMurder) ?? FindTarget(player, victim, room, true); if (target == null) { if (player.Status == CharacterStatus.Status.Fighting) { player.Target = ""; player.Status = CharacterStatus.Status.Standing; _cache.RemoveCharFromCombat(player.Id.ToString()); } if (player.Status != CharacterStatus.Status.Fighting) { _writer.WriteLine("<p>They are not here.</p>", player.ConnectionId); return; } _writer.WriteLine("<p>They are not here.</p>", player.ConnectionId); return; } if (target.Name == player.Name) { _writer.WriteLine("<p>You can't start a fight with yourself!</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); player.Target = String.Empty; 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); } /* * This section crying out for a refactor */ var weapon = GetWeapon(player); var chanceToHit = _formulas.ToHitChance(player, target, false); if (chanceToHit < 5) { chanceToHit = 5; } //if player bind and don't have blind fighting // reduce chance to hit by 40% if (player.Affects.Blind && !BlindFighting(player)) { chanceToHit = (int)(chanceToHit - (chanceToHit * .70)); } var doesHit = _formulas.DoesHit(chanceToHit); 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", target); if (dodge != null) { _writer.WriteLine($"<p>You dodge {player.Name}'s attack.</p>", target.ConnectionId); _writer.WriteLine($"<p>{target.Name} dodges your attack.</p>", player.ConnectionId); return; } } //10% chance to parry if (avoidanceRoll == 2) { var skill = GetSkill("parry", target); if (skill != null) { _writer.WriteLine($"<p>You parry {player.Name}'s attack.</p>", target.ConnectionId); _writer.WriteLine($"<p>{target.Name} parries your attack.</p>", player.ConnectionId); var riposte = GetSkill("Riposte", target); if (riposte != null) { _writer.WriteLine($"<p>You riposte {player.Name}'s attack.</p>", target.ConnectionId); _writer.WriteLine($"<p>{target.Name} riposte's your attack.</p>", player.ConnectionId); var ripDamage = _formulas.CalculateDamage(target, player, weapon); ripDamage /= 3; HarmTarget(player, ripDamage); DisplayDamage(target, player, room, weapon, ripDamage); _clientUi.UpdateHP(player); if (!IsTargetAlive(player)) { TargetKilled(target, player, room); } } return; } } // Block if (avoidanceRoll == 3 && player.Equipped.Shield != null) { var chanceToBlock = _formulas.ToBlockChance(target, player); var doesBlock = _formulas.DoesHit(chanceToBlock); if (doesBlock) { var skill = GetSkill("shieldblock", target); if (skill != null) { _writer.WriteLine($"You block {player.Name}'s attack with your shield.", target.ConnectionId); _writer.WriteLine($"{target.Name} blocks your attack with their shield.", player.ConnectionId); return; } } else { // block fail } } var damage = _formulas.CalculateDamage(player, target, weapon); var enhancedDamageChance = _dice.Roll(1, 1, 100); var hasEnhancedDamage = player.Skills.FirstOrDefault(x => x.SkillName.Equals("Enhanced Damage")); if (_formulas.IsCriticalHit()) { // double damage damage *= 2; } if (hasEnhancedDamage != null) { if (hasEnhancedDamage.Proficiency >= enhancedDamageChance && player.Level >= hasEnhancedDamage.Level) { var bonusDam = Helpers.GetPercentage(15, damage); damage += bonusDam; } } HarmTarget(target, damage); DisplayDamage(player, target, room, weapon, damage); _clientUi.UpdateHP(target); if (!IsTargetAlive(target)) { TargetKilled(player, target, room); } } 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 < 100) { getWeaponSkill.Proficiency += 1; _writer.WriteLine( $"<p class='improve'>Your proficiency in {getWeaponSkill.SkillName} has increased.</p>", player.ConnectionId); _gain.GainExperiencePoints(player, getWeaponSkill.Level * 50, true); } } if (player.Equipped.Secondary != null) { weapon = GetWeapon(player, true); chanceToHit = _formulas.ToHitChance(player, target, true); if (player.ConnectionId == "mob" && chanceToHit < 45) { chanceToHit = 45; } //if player bind and don't have blind fighting // reduce chance to hit by 40% if (player.Affects.Blind && !BlindFighting(player)) { chanceToHit = (int)(chanceToHit - (chanceToHit * .40)); } doesHit = _formulas.DoesHit(chanceToHit); 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", target); if (dodge != null) { _writer.WriteLine($"<p>You dodge {player.Name}'s attack.</p>", target.ConnectionId); _writer.WriteLine($"<p>{target.Name} dodges your attack.</p>", player.ConnectionId); return; } } //10% chance to parry if (avoidanceRoll == 2) { var skill = GetSkill("parry", target); if (skill != null) { _writer.WriteLine($"<p>You parry {player.Name}'s attack.</p>", target.ConnectionId); _writer.WriteLine($"<p>{target.Name} parries your attack.</p>", player.ConnectionId); var riposte = GetSkill("Riposte", target); if (riposte != null) { _writer.WriteLine($"<p>You riposte {player.Name}'s attack.</p>", target.ConnectionId); _writer.WriteLine($"<p>{target.Name} riposte's your attack.</p>", player.ConnectionId); var ripDamage = _formulas.CalculateDamage(target, player, weapon); ripDamage /= 3; HarmTarget(player, ripDamage); DisplayDamage(target, player, room, weapon, ripDamage); _clientUi.UpdateHP(player); if (!IsTargetAlive(player)) { TargetKilled(target, player, room); } } return; } } // Block if (avoidanceRoll == 3 && player.Equipped.Shield != null) { var chanceToBlock = _formulas.ToBlockChance(target, player); var doesBlock = _formulas.DoesHit(chanceToBlock); if (doesBlock) { var skill = GetSkill("shieldblock", target); if (skill != null) { _writer.WriteLine($"You block {player.Name}'s attack with your shield.", target.ConnectionId); _writer.WriteLine($"{target.Name} blocks your attack with their shield.", player.ConnectionId); return; } } else { // block fail } } var damage = _formulas.CalculateDamage(player, target, weapon); if (_formulas.IsCriticalHit()) { // double damage damage *= 2; } var enhancedDamageChance = _dice.Roll(1, 1, 100); var hasEnhancedDamage = player.Skills.FirstOrDefault(x => x.SkillName.Equals("Enhanced Damage")); if (hasEnhancedDamage != null) { if (hasEnhancedDamage.Proficiency >= enhancedDamageChance) { var bonusDam = Helpers.GetPercentage(15, damage); damage += bonusDam; } } HarmTarget(target, damage); DisplayDamage(player, target, room, weapon, damage); _clientUi.UpdateHP(target); if (!IsTargetAlive(target)) { TargetKilled(player, target, room); } } 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>", player.ConnectionId); _gain.GainExperiencePoints(player, getWeaponSkill.Level * 50, true); } } } } catch (Exception e) { Console.WriteLine(e); throw; } }