public static string AttackSequence(Player attacker, Player victim, SkillViewModel skillBeingUsed, bool timestamp = true) { // Actual attack var(_, message) = AttackProcedures.Attack(attacker, victim, skillBeingUsed, timestamp); // record into statistics StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__SpellsCast, 1); if (AIStatics.IsABoss(victim.BotId)) { StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__BossAllAttacks, 1); } if (victim.BotId == AIStatics.FemaleRatBotId || victim.BotId == AIStatics.MaleRatBotId) { StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__BossRatThiefAttacks, 1); } else if (victim.BotId == AIStatics.BimboBossBotId) { StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__BossLovebringerAttacks, 1); } else if (victim.BotId == AIStatics.DonnaBotId) { StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__BossDonnaAttacks, 1); } else if (victim.BotId == AIStatics.FaebossBotId) { StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__FaebossAttacks, 1); } else if (victim.BotId == AIStatics.MouseNerdBotId || victim.BotId == AIStatics.MouseBimboBotId) { StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__MouseSisterAttacks, 1); } else if (victim.BotId == AIStatics.MotorcycleGangLeaderBotId) { StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__MotorcycleGangAttacks, 1); } else if (AIStatics.IsAMiniboss(victim.BotId) && victim.BotId != AIStatics.MinibossPlushAngelId) // The plush just wants to make friends. No rewards for monsters. { StatsProcedures.AddStat(attacker.MembershipId, StatsProcedures.Stat__MinibossAttacks, 1); } // Trigger any counterattack AIProcedures.CheckAICounterattackRoutine(attacker, victim); return(message); }
public static void SetCovenantSafeground(Covenant covenant, string location) { ICovenantRepository covRepo = new EFCovenantRepository(); var dbCovenant = covRepo.Covenants.FirstOrDefault(i => i.Id == covenant.Id); dbCovenant.HomeLocation = location; dbCovenant.Money -= 2500; dbCovenant.Level = 1; covRepo.SaveCovenant(dbCovenant); LoadCovenantDictionary(); var covMessage = $"Covenant safeground was establish at {LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == location)?.Name ?? "unknown"}."; WriteCovenantLog(covMessage, covenant.Id, true); AttackProcedures.InstantTakeoverLocation(dbCovenant, location); }
public static void CheckAICounterattackRoutine(Player personAttacking, Player bot) { // person attacking is a boss and not a psychopath, so do nothing if (personAttacking.BotId < AIStatics.PsychopathBotId) { return; } // attacking the psychopath. Random chance the psychopath will set the attacker as their target. if (bot.BotId == AIStatics.PsychopathBotId) { if (personAttacking.BotId == AIStatics.ActivePlayerBotId) { var rand = new Random(); var numAttacks = NumPsychopathCounterAttacks(bot, rand); var(mySkills, weakenSkill, _) = GetPsychopathSkills(bot); if (!mySkills.IsEmpty()) { var complete = false; for (int i = 0; i < numAttacks && !complete; i++) { var skill = SelectPsychopathSkill(personAttacking, mySkills, weakenSkill, rand); (complete, _) = AttackProcedures.Attack(bot, personAttacking, skill); } if (complete) { EquipDefeatedPlayer(bot, personAttacking); } } } var directive = AIDirectiveProcedures.GetAIDirective(bot.Id); // no previous target, so set this player as the new one if (directive.TargetPlayerId == -1 || directive.State == "idle") { AIDirectiveProcedures.SetAIDirective_Attack(bot.Id, personAttacking.Id); } // random chance to see if the attacker becomes the new target else { var rand = new Random(); var roll = rand.NextDouble(); if (roll < .08) { AIDirectiveProcedures.SetAIDirective_Attack(bot.Id, personAttacking.Id); } } } // if the target is Donna, counterattack and set that player as her target immediately if (bot.BotId == AIStatics.DonnaBotId) { BossProcedures_Donna.DonnaCounterattack(personAttacking, bot); } // Valentine counterattack if (bot.BotId == AIStatics.ValentineBotId) { BossProcedures_Valentine.CounterAttack(personAttacking, bot); } // Bimbo boss counterattack else if (bot.BotId == AIStatics.BimboBossBotId) { BossProcedures_BimboBoss.CounterAttack(personAttacking, bot); } // rat thieves counterattack else if (bot.BotId == AIStatics.MaleRatBotId || bot.BotId == AIStatics.FemaleRatBotId) { AIProcedures.DealBossDamage(bot, personAttacking, true, 1); BossProcedures_Thieves.CounterAttack(personAttacking); } // fae boss counterattack else if (bot.BotId == AIStatics.FaebossBotId) { AIProcedures.DealBossDamage(bot, personAttacking, true, 1); BossProcedures_FaeBoss.CounterAttack(personAttacking); } // motocycle boss counterattack else if (bot.BotId == AIStatics.MotorcycleGangLeaderBotId) { AIProcedures.DealBossDamage(bot, personAttacking, true, 1); BossProcedures_MotorcycleGang.CounterAttack(personAttacking, bot); } // mouse sisters counterattack else if (bot.BotId == AIStatics.MouseNerdBotId || bot.BotId == AIStatics.MouseBimboBotId) { BossProcedures_Sisters.CounterAttack(personAttacking, bot); } // demon counterattack else if (bot.BotId == AIStatics.DemonBotId) { BossProcedures_DungeonDemon.CounterAttack(bot, personAttacking); } // miniboss counterattack else if (AIStatics.IsAMiniboss(bot.BotId)) { BossProcedures_Minibosses.CounterAttack(personAttacking, bot); } }
public static List <Exception> RunPsychopathActions(WorldDetail worldDetail) { var rand = new Random(DateTime.Now.Millisecond); var errors = new List <Exception>(); IPlayerRepository playerRepo = new EFPlayerRepository(); //spawn in more bots if there are less than the default var botCount = playerRepo.Players.Count(b => b.BotId == AIStatics.PsychopathBotId && b.Mobility == PvPStatics.MobilityFull); if (botCount < PvPStatics.PsychopathDefaultAmount) { SpawnAIPsychopaths(PvPStatics.PsychopathDefaultAmount - botCount); } var bots = playerRepo.Players.Where(p => p.BotId == AIStatics.PsychopathBotId && p.Mobility == PvPStatics.MobilityFull).ToList(); foreach (var bot in bots) { try { // if bot is no longer fully animate or is null, skip them if (bot == null || bot.Mobility != PvPStatics.MobilityFull) { continue; } bot.LastActionTimestamp = DateTime.UtcNow; if (!EffectProcedures.PlayerHasActiveEffect(bot.Id, JokeShopProcedures.PSYCHOTIC_EFFECT)) { #region drop excess items var botItems = DomainRegistry.Repository.Find(new GetItemsOwnedByPsychopath { OwnerId = bot.Id }).ToList(); string[] itemTypes = { PvPStatics.ItemType_Hat, PvPStatics.ItemType_Accessory, PvPStatics.ItemType_Pants, PvPStatics.ItemType_Pet, PvPStatics.ItemType_Shirt, PvPStatics.ItemType_Shoes, PvPStatics.ItemType_Underpants, PvPStatics.ItemType_Undershirt }; foreach (var typeToDrop in itemTypes) { if (botItems.Count(i => i.ItemSource.ItemType == typeToDrop) > 1) { var dropList = botItems.Where(i => i.ItemSource.ItemType == typeToDrop).Skip(1); foreach (var i in dropList) { ItemProcedures.DropItem(i.Id); var name = "a"; if (i.FormerPlayer != null) { name = "<b>" + i.FormerPlayer.FullName + "</b> the"; } if (i.ItemSource.ItemType == PvPStatics.ItemType_Pet) { LocationLogProcedures.AddLocationLog(bot.dbLocationName, "<b>" + bot.GetFullName() + "</b> released " + name + " pet <b>" + i.ItemSource.FriendlyName + "</b> here."); } else { LocationLogProcedures.AddLocationLog(bot.dbLocationName, "<b>" + bot.GetFullName() + "</b> dropped " + name + " <b>" + i.ItemSource.FriendlyName + "</b> here."); } } } } #endregion } var botbuffs = ItemProcedures.GetPlayerBuffs(bot); var meditates = 0; // meditate if needed if (bot.Mana < bot.MaxMana * .5M) { var manaroll = (int)Math.Floor(rand.NextDouble() * 4.0D); for (var i = 0; i < manaroll; i++) { DomainRegistry.Repository.Execute(new Meditate { PlayerId = bot.Id, Buffs = botbuffs, NoValidate = true }); meditates++; } } // cleanse if needed, less if psycho has cleansed lately if (bot.Health < bot.MaxHealth * .5M) { var healthroll = (int)Math.Floor(rand.NextDouble() * 4.0D); for (var i = meditates; i < healthroll; i++) { DomainRegistry.Repository.Execute(new Cleanse { PlayerId = bot.Id, Buffs = botbuffs, NoValidate = true }); } } var directive = AIDirectiveProcedures.GetAIDirective(bot.Id); // the bot has an attack target, so go chase it if (directive.State == "attack") { var myTarget = PlayerProcedures.GetPlayer(directive.TargetPlayerId); var(mySkills, weakenSkill, inanimateSkill) = GetPsychopathSkills(bot); // if the target is offline, no longer animate, in the dungeon, or in the same form as the spells' target, go into idle mode if (PlayerProcedures.PlayerIsOffline(myTarget) || myTarget.Mobility != PvPStatics.MobilityFull || mySkills.IsEmpty() || inanimateSkill == null || myTarget.FormSourceId == inanimateSkill.StaticSkill.FormSourceId || myTarget.IsInDungeon() || myTarget.InDuel > 0 || myTarget.InQuest > 0) { AIDirectiveProcedures.SetAIDirective_Idle(bot.Id); } // the target is okay for attacking else { // the bot must move to its target location. if (myTarget.dbLocationName != bot.dbLocationName) { if (botbuffs.MoveActionPointDiscount() > -100 && CanMove(worldDetail, myTarget)) { var maxSpaces = NumPsychopathMoveSpaces(bot); var newplace = MoveTo(bot, myTarget.dbLocationName, maxSpaces); bot.dbLocationName = newplace; } } // if the bot is now in the same place as the target, attack away, so long as the target is online and animate if (bot.dbLocationName == myTarget.dbLocationName && !PlayerProcedures.PlayerIsOffline(myTarget) && myTarget.Mobility == PvPStatics.MobilityFull && CanAttack(worldDetail, bot, myTarget) ) { playerRepo.SavePlayer(bot); var numAttacks = Math.Min(3, (int)(bot.Mana / PvPStatics.AttackManaCost)); var complete = false; for (var attackIndex = 0; attackIndex < numAttacks && !complete; ++attackIndex) { var skill = SelectPsychopathSkill(myTarget, mySkills, weakenSkill, rand); (complete, _) = AttackProcedures.Attack(bot, myTarget, skill); } if (complete) { EquipDefeatedPlayer(bot, myTarget); } } } } // the bot has no target, so wander and try to find new targets and attack them. else { if (botbuffs.MoveActionPointDiscount() > -100) { var newplace = MoveTo(bot, LocationsStatics.GetRandomLocationNotInDungeon(), 5); bot.dbLocationName = newplace; } // attack stage var playersHere = playerRepo.Players.Where (p => p.dbLocationName == bot.dbLocationName && p.Mobility == PvPStatics.MobilityFull && p.Id != bot.Id && p.BotId == AIStatics.PsychopathBotId && p.Level >= bot.Level).ToList(); // filter out offline players and Lindella var onlinePlayersHere = playersHere.Where(p => !PlayerProcedures.PlayerIsOffline(p)).ToList(); if (onlinePlayersHere.Count > 0) { var roll = Math.Floor(rand.NextDouble() * onlinePlayersHere.Count); var victim = onlinePlayersHere.ElementAt((int)roll); AIDirectiveProcedures.SetAIDirective_Attack(bot.Id, victim.Id); playerRepo.SavePlayer(bot); var(mySkills, weakenSkill, inanimateSkill) = GetPsychopathSkills(bot); if (!mySkills.IsEmpty()) { var numAttacks = Math.Min(3, (int)(bot.Mana / PvPStatics.AttackManaCost)); var complete = false; for (var attackIndex = 0; attackIndex < numAttacks && !complete; ++attackIndex) { var skill = SelectPsychopathSkill(victim, mySkills, weakenSkill, rand); (complete, _) = AttackProcedures.Attack(bot, victim, skill); } if (complete) { EquipDefeatedPlayer(bot, victim); } } } } playerRepo.SavePlayer(bot); } catch (Exception e) { errors.Add(e); } } return(errors); }
private static decimal AddExtraHealthDamage(Player victim, Player attacker, decimal energyRequired, decimal energyAccumulated, decimal modifiedTFEnergyPercent, LogBox output) { var playerRepo = new EFPlayerRepository(); var dbVictim = playerRepo.Players.FirstOrDefault(p => p.Id == victim.Id); // add in some extra WP damage if TF energy high enough for TF but WP is still high // Explode the victim if they somehow reach 1,000 TFEnergy in a PvP encounter if (dbVictim.Health > 0) { if (energyAccumulated > energyRequired * 10M && attacker.BotId == AIStatics.ActivePlayerBotId && victim.BotId == AIStatics.ActivePlayerBotId) { var healthDamage = 9999 * modifiedTFEnergyPercent; output.VictimLog += $" <br />Despite your iron will there is only so much transformation energy that a single person can contain within their body, unfortunately for you that limit has been reached. In a spectacular shower of vibrant energy you are consumed. You take an extra {healthDamage:#} willpower damage."; output.AttackerLog += $"<br />Your victim stands resolute for their final moments before a brilliant cascade of chaos errupts from inside of their form. They suffer an extra {healthDamage:#} willpower damage."; dbVictim.Health -= healthDamage; dbVictim.NormalizeHealthMana(); playerRepo.SavePlayer(dbVictim); // Causes the victim to 'explode' and deal damage in their area AttackProcedures.SuddenDeathExplosion(attacker, victim, 240); } else { var healthDamage = 0m; if (energyAccumulated > energyRequired * 3M) { healthDamage = 60 * modifiedTFEnergyPercent; if (attacker.BotId == AIStatics.ActivePlayerBotId) { healthDamage *= 2; } output.VictimLog += $"<br />You collapse to your knees and your vision wavers as transformation energy threatens to transform you spontaneously. You fight it but only after it drains you of more of your precious remaining willpower! You take an extra {healthDamage:#} willpower damage."; output.AttackerLog += $"<br />Your victim has an extremely high amount of transformation energy built up and takes an extra {healthDamage:#} willpower damage."; } else if (energyAccumulated > energyRequired * 2M) { healthDamage = 30 * modifiedTFEnergyPercent; if (attacker.BotId == AIStatics.ActivePlayerBotId) { healthDamage *= 2; } output.VictimLog += $"<br />You body spasms as the surplus of transformation energy threatens to transform you spontaneously. You fight it but only after it drains you of more of your precious remaining willpower! You take an extra {healthDamage:#} willpower damage."; output.AttackerLog += $"<br />Your victim has a very high amount of transformation energy built up and takes an extra {healthDamage:#} willpower damage."; } else if (energyAccumulated > energyRequired * 1M) { healthDamage = 15 * modifiedTFEnergyPercent; if (attacker.BotId == AIStatics.ActivePlayerBotId) { healthDamage *= 2; } output.VictimLog += $"<br />You gasp as your body shivers with a surplus of transformation energy built up within it, leaving you distracted and your willpower increasingly impaired. You take an extra {healthDamage:#} willpower damage."; output.AttackerLog += $"<br />Your victim has a high amount of transformation energy built up and takes an extra {healthDamage:#} willpower damage."; } if (healthDamage > 0) { dbVictim.Health -= healthDamage; dbVictim.NormalizeHealthMana(); playerRepo.SavePlayer(dbVictim); } } } return(dbVictim.Health); }