public void Fight(Player player, string victim, Room room, bool isMurder) { try { 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); _quest.IsQuestMob(player, target.Name); _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); } } } catch (Exception e) { Console.WriteLine(e); throw; } }
public void TargetKilled(Player player, Player target, Room room) { 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); _quest.IsQuestMob(player, target.Name); if (target.ConnectionId != "mob") { Helpers.PostToDiscord($"{target.Name} got killed by {player.Name}!", "event", _cache.GetConfig()); if (player.ConnectionId != "mob") { target.PlayerDeaths += 1; player.PlayerKills += 1; } else { target.MobDeaths += 1; } } _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 = target.Description, Look = 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, Decay = target.ConnectionId.Equals("mob", StringComparison.OrdinalIgnoreCase) ? 10 : 20, DecayTimer = 300 // 5 minutes, }; foreach (var item in target.Inventory) { item.Equipped = false; corpse.Container.Items.Add(item); } if (target.ConnectionId.Equals("mob", StringComparison.CurrentCultureIgnoreCase)) { player.MobKills += 1; var randomItem = _randomItem.WeaponDrop(player); if (randomItem != null) { corpse.Container.Items.Add(randomItem); } } // clear list target.Inventory = new ItemList(); // clear equipped target.Equipped = new Equipment(); var mount = target.Pets.FirstOrDefault(x => x.Name.Equals(target.Mounted.Name)); if (mount != null) { target.Pets.Remove(mount); target.Mounted.Name = string.Empty; } // add corpse to room room.Items.Add(corpse); _clientUi.UpdateInventory(target); _clientUi.UpdateEquipment(target); _clientUi.UpdateScore(target); _clientUi.UpdateScore(player); room.Clean = false; _cache.RemoveCharFromCombat(target.Id.ToString()); _cache.RemoveCharFromCombat(player.Id.ToString()); if (target.ConnectionId.Equals("mob", StringComparison.CurrentCultureIgnoreCase)) { room.Mobs.Remove(target); var getTodayMobStats = _pdb.GetList <MobStats>(PlayerDataBase.Collections.MobStats).FirstOrDefault(x => x.Date.Date.Equals(DateTime.Today)); if (getTodayMobStats != null) { getTodayMobStats.MobKills += 1; } else { getTodayMobStats = new MobStats() { MobKills = 1, PlayerDeaths = 0, Date = DateTime.Now, }; } _pdb.Save <MobStats>(getTodayMobStats, PlayerDataBase.Collections.MobStats); } else { room.Players.Remove(target); var getTodayMobStats = _pdb.GetList <MobStats>(PlayerDataBase.Collections.MobStats).FirstOrDefault(x => x.Date.Date.Equals(DateTime.Today)); if (getTodayMobStats != null) { getTodayMobStats.PlayerDeaths += 1; } else { getTodayMobStats = new MobStats() { MobKills = 0, PlayerDeaths = 1, Date = DateTime.Now, }; } _pdb.Save <MobStats>(getTodayMobStats, PlayerDataBase.Collections.MobStats); } // take player to Temple / recall area if (target.ConnectionId != "mob") { target.Status = CharacterStatus.Status.Resting; var newRoom = _cache.GetRoom(target.RecallId); target.Buffer = new Queue <string>(); target.RoomId = Helpers.ReturnRoomId(newRoom); newRoom.Players.Add(target); target.Buffer.Enqueue("look"); } }