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 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); }