/// <summary> /// Retrieves the AI directive. If no directive is found, a new one is automatically created with default settings /// </summary> /// <param name="botId">Id of the Player with this AI directive</param> /// <returns>the AI directive belonging to the passed in player ID</returns> public static AIDirective GetAIDirective(int botId) { IAIDirectiveRepository directiveRepo = new EFAIDirectiveRepository(); var directive = directiveRepo.AIDirectives.FirstOrDefault(ad => ad.OwnerId == botId); if (directive == null) { directive = new AIDirective { OwnerId = botId, State = "idle", // attack, move, flee TargetLocation = "", TargetPlayerId = -1, Timestamp = DateTime.UtcNow, Var1 = -1, Var2 = -1, Var3 = -1, Var4 = -1, Var5 = -1 }; directiveRepo.SaveAIDirective(directive); } return(directive); }
/// <summary> /// Attack an attacking player back. There is a random chance to draw Narcissa's aggro from doing this if she has a target. If she has no active target, /// the attacker instantly becomes her new target. /// </summary> /// <param name="attacker"></param> public static void CounterAttack(Player attacker) { IPlayerRepository playerRepo = new EFPlayerRepository(); var faeboss = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.FaebossBotId); AIProcedures.DealBossDamage(faeboss, attacker, true, 1); // log attack for human on boss var spell = ChooseSpell(PvPWorldStatProcedures.GetWorldTurnNumber(), PvPStatics.MobilityInanimate); for (var i = 0; i < 3; i++) { AttackProcedures.Attack(faeboss, attacker, spell); AIProcedures.DealBossDamage(faeboss, attacker, false, 1); // log attack for boss on human } var directive = AIDirectiveProcedures.GetAIDirective(faeboss.Id); // random chance to aggro faeboss var rand = new Random(Guid.NewGuid().GetHashCode()); var num = rand.NextDouble(); if (num < AggroChance || directive.Var1 == 0) { IAIDirectiveRepository aiRepo = new EFAIDirectiveRepository(); var dbDirective = aiRepo.AIDirectives.FirstOrDefault(a => a.Id == directive.Id); dbDirective.Var1 = attacker.Id; aiRepo.SaveAIDirective(dbDirective); } }
/// <summary> /// Clears Narcissa's target /// </summary> /// <param name="directive"></param> private static void ResetTarget(AIDirective directive) { IAIDirectiveRepository aiRepo = new EFAIDirectiveRepository(); var ai = aiRepo.AIDirectives.FirstOrDefault(a => a.Id == directive.Id); ai.Var1 = 0; aiRepo.SaveAIDirective(ai); }
public static void SpawnBimboBoss() { var bimboBoss = DomainRegistry.Repository.FindSingle(new GetPlayerByBotId { BotId = AIStatics.BimboBossBotId }); if (bimboBoss == null) { var cmd = new CreatePlayer { FirstName = BossFirstName, LastName = BossLastName, Location = "stripclub_bar_seats", Gender = PvPStatics.GenderFemale, Health = 100000, Mana = 100000, MaxHealth = 100000, MaxMana = 100000, FormSourceId = BimboBossFormSourceId, Money = 2500, Level = 15, BotId = AIStatics.BimboBossBotId, }; var id = DomainRegistry.Repository.Execute(cmd); var playerRepo = new EFPlayerRepository(); var bimboEF = playerRepo.Players.FirstOrDefault(p => p.Id == id); bimboEF.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(bimboEF)); playerRepo.SavePlayer(bimboEF); // set up her AI directive so it is not deleted IAIDirectiveRepository aiRepo = new EFAIDirectiveRepository(); var directive = new AIDirective { OwnerId = id, Timestamp = DateTime.UtcNow, SpawnTurn = PvPWorldStatProcedures.GetWorldTurnNumber(), DoNotRecycleMe = true, }; aiRepo.SaveAIDirective(directive); for (var i = 0; i < 2; i++) { DomainRegistry.Repository.Execute(new GiveRune { ItemSourceId = RuneStatics.BIMBO_RUNE, PlayerId = bimboEF.Id }); } } }
public static void MoveToNewLocation() { IPlayerRepository playerRepo = new EFPlayerRepository(); var fae = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.JewdewfaeBotId); IJewdewfaeEncounterRepository faeRepo = new EFJewdewfaeEncounterRepository(); IAIDirectiveRepository aiRepo = new EFAIDirectiveRepository(); var directive = aiRepo.AIDirectives.FirstOrDefault(i => i.OwnerId == fae.Id); // add fae's current location to the list of places visited directive.sVar2 += fae.dbLocationName + ";"; var fairyLocations = faeRepo.JewdewfaeEncounters.Where(f => f.IsLive).Select(f => f.dbLocationName).ToList(); var visitedFairyLocations = directive.sVar2.Split(';').Where(f => f.Length > 1).ToList(); var possibleLocations = fairyLocations.Except(visitedFairyLocations).ToList(); // if there are no locations left to visit, reset if (!possibleLocations.Any()) { possibleLocations = fairyLocations; directive.sVar2 = ""; } double max = possibleLocations.Count(); var rand = new Random(); var num = rand.NextDouble(); var index = Convert.ToInt32(Math.Floor(num * max)); var newLocation = possibleLocations.ElementAt(index); directive.Var1 = 0; directive.Var2 = PvPWorldStatProcedures.GetWorldTurnNumber(); directive.sVar1 = ";"; aiRepo.SaveAIDirective(directive); LocationLogProcedures.AddLocationLog(fae.dbLocationName, "<b>Jewdewfae got bored and flew away from here.</b>"); fae.dbLocationName = newLocation; playerRepo.SavePlayer(fae); LocationLogProcedures.AddLocationLog(fae.dbLocationName, "<b>Jewdewfae flew here. She looks bored and wants to play with someone.</b>"); }
public static void SpawnFae() { var fae = DomainRegistry.Repository.FindSingle(new GetPlayerByBotId { BotId = AIStatics.JewdewfaeBotId }); if (fae == null) { var cmd = new CreatePlayer { FirstName = FirstName, LastName = LastName, Location = "apartment_dog_park", Gender = PvPStatics.GenderFemale, Health = 100000, Mana = 100000, MaxHealth = 100000, MaxMana = 100000, FormSourceId = FaeFormId, Money = 1000, Level = 7, BotId = AIStatics.JewdewfaeBotId }; var id = DomainRegistry.Repository.Execute(cmd); var playerRepo = new EFPlayerRepository(); var faeEF = playerRepo.Players.FirstOrDefault(p => p.Id == id); faeEF.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(faeEF)); playerRepo.SavePlayer(faeEF); // set up her AI directive so it is not deleted IAIDirectiveRepository aiRepo = new EFAIDirectiveRepository(); var directive = new AIDirective { OwnerId = id, Timestamp = DateTime.UtcNow, SpawnTurn = 0, DoNotRecycleMe = true, sVar1 = ";", // this is used to keep track of which players have interacted with her by appending their id to this string sVar2 = "", // this is used to keep track of which locations Jewdewfae has been in during the past cycle Var1 = 0, // this keeps track of how many people she has played with in the current location Var2 = 0 // this stores the turn number of Jewdewfae's last move }; aiRepo.SaveAIDirective(directive); } }
public static void DeaggroPsychopathsOnPlayer(Player player) { IAIDirectiveRepository directiveRepo = new EFAIDirectiveRepository(); IPlayerRepository playerRepo = new EFPlayerRepository(); var directives = directiveRepo.AIDirectives.Where(d => d.TargetPlayerId == player.Id).ToList(); foreach (var d in directives) { var p = playerRepo.Players.FirstOrDefault(x => x.Id == d.OwnerId); if (p.BotId == AIStatics.PsychopathBotId) { d.TargetPlayerId = -1; d.State = "idle"; directiveRepo.SaveAIDirective(d); } } }
public static decimal AddInteraction(Player player) { IPlayerRepository playerRepo = new EFPlayerRepository(); var fae = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.JewdewfaeBotId); IAIDirectiveRepository aiRepo = new EFAIDirectiveRepository(); var directive = aiRepo.AIDirectives.FirstOrDefault(i => i.OwnerId == fae.Id); if (directive == null) { directive = new AIDirective { OwnerId = fae.Id, Timestamp = DateTime.UtcNow, sVar1 = ";", }; } // Var1 will keep track how how many interactions Jewdewfae has had. Award a bit less XP based on how many people she has played with down to 15 at lowest var xpGain = 75 - directive.Var1 * 3; if (xpGain < 15) { xpGain = 15; } directive.Var1 += 1; // add this player's ID to the list of people interacted with; one playtime per location! directive.sVar1 += player.Id.ToString() + ";"; aiRepo.SaveAIDirective(directive); if (directive.Var1 >= 18) { MoveToNewLocation(); } LocationLogProcedures.AddLocationLog(fae.dbLocationName, "<b>Jewdewfae played with " + player.FirstName + " " + player.LastName + " here.</b>"); return(xpGain); }
public static void SetAIDirective_Idle(int botId) { IAIDirectiveRepository directiveRepo = new EFAIDirectiveRepository(); var directive = directiveRepo.AIDirectives.FirstOrDefault(i => i.OwnerId == botId) ?? new AIDirective { OwnerId = botId, TargetLocation = "", Var1 = -1, Var2 = -1, Var3 = -1, Var4 = -1, Var5 = -1 }; directive.State = "idle"; directive.TargetPlayerId = 0; directive.Timestamp = DateTime.UtcNow; directiveRepo.SaveAIDirective(directive); }
public static void SetAIDirective_MoveTo(int botId, string dblocationName) { IAIDirectiveRepository directiveRepo = new EFAIDirectiveRepository(); var directive = directiveRepo.AIDirectives.FirstOrDefault(i => i.OwnerId == botId) ?? new AIDirective { OwnerId = botId, State = "idle", TargetPlayerId = -1, Var1 = -1, Var2 = -1, Var3 = -1, Var4 = -1, Var5 = -1 }; //directive.State = "move"; directive.Timestamp = DateTime.UtcNow; directive.TargetLocation = dblocationName; directiveRepo.SaveAIDirective(directive); }
public static void SpawnValentine() { var valentine = DomainRegistry.Repository.FindSingle(new GetPlayerByBotId { BotId = AIStatics.ValentineBotId }); if (valentine == null) { var cmd = new CreatePlayer { FirstName = ValentineFirstName, LastName = ValentineLastName, Location = GetStanceLocation(), Gender = PvPStatics.GenderMale, Health = 100000, Mana = 100000, MaxHealth = 100000, MaxMana = 100000, FormSourceId = ValentineFormSourceId, Money = 1000, Mobility = PvPStatics.MobilityFull, Level = 30, BotId = AIStatics.ValentineBotId, }; var id = DomainRegistry.Repository.Execute(cmd); var playerRepo = new EFPlayerRepository(); var valentineEF = playerRepo.Players.FirstOrDefault(p => p.Id == id); valentineEF.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(valentineEF)); playerRepo.SavePlayer(valentineEF); // give Valentine his reward item drop var createItemCmd = new CreateItem { dbLocationName = "", EquippedThisTurn = false, IsEquipped = false, IsPermanent = false, Level = 6, OwnerId = id, PvPEnabled = -1, ItemSourceId = ItemStatics.GetStaticItem(QueensPantiesItemSourceId).Id }; DomainRegistry.Repository.Execute(createItemCmd); // save his aiDirective, just for the sake of knowing his spawn turn IAIDirectiveRepository aiRepo = new EFAIDirectiveRepository(); var directive = new AIDirective { OwnerId = id, Timestamp = DateTime.UtcNow, SpawnTurn = PvPWorldStatProcedures.GetWorldTurnNumber(), DoNotRecycleMe = true, }; aiRepo.SaveAIDirective(directive); for (var i = 0; i < 2; i++) { DomainRegistry.Repository.Execute(new GiveRune { ItemSourceId = RuneStatics.VAMPIRE_RUNE, PlayerId = valentineEF.Id }); } } }
public static void SpawnThieves() { var malethief = DomainRegistry.Repository.FindSingle(new GetPlayerByBotId { BotId = AIStatics.MaleRatBotId }); if (malethief == null) { var cmd = new CreatePlayer { FirstName = MaleBossFirstName, LastName = MaleBossLastName, Location = "tavern_pool", Gender = PvPStatics.GenderMale, Health = 100000, Mana = 100000, MaxHealth = 100000, MaxMana = 100000, FormSourceId = MaleBossFormSourceId, Money = 0, Mobility = PvPStatics.MobilityFull, Level = 5, BotId = AIStatics.MaleRatBotId }; var id = DomainRegistry.Repository.Execute(cmd); var playerRepo = new EFPlayerRepository(); var malethiefEF = playerRepo.Players.FirstOrDefault(p => p.Id == id); malethiefEF.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(malethiefEF)); playerRepo.SavePlayer(malethiefEF); var aiRepo = new EFAIDirectiveRepository(); var maleDirective = new AIDirective { OwnerId = id, DoNotRecycleMe = true, Timestamp = DateTime.UtcNow, SpawnTurn = PvPWorldStatProcedures.GetWorldTurnNumber(), sVar1 = GetRichestPlayerIds(), Var1 = 0, }; aiRepo.SaveAIDirective(maleDirective); for (var i = 0; i < 2; i++) { DomainRegistry.Repository.Execute(new GiveRune { ItemSourceId = RuneStatics.RAT_THIEF_RUNE, PlayerId = malethiefEF.Id }); } } var femalethief = DomainRegistry.Repository.FindSingle(new GetPlayerByBotId { BotId = AIStatics.FemaleRatBotId }); if (femalethief == null) { var cmd = new CreatePlayer { FirstName = FemaleBossFirstName, LastName = FemaleBossLastName, Location = "tavern_pool", Gender = PvPStatics.GenderFemale, Health = 100000, Mana = 100000, MaxHealth = 100000, MaxMana = 100000, FormSourceId = FemaleBossFormSourceId, Money = 0, Mobility = PvPStatics.MobilityFull, Level = 7, BotId = AIStatics.FemaleRatBotId, }; var id = DomainRegistry.Repository.Execute(cmd); var playerRepo = new EFPlayerRepository(); var femalethiefEF = playerRepo.Players.FirstOrDefault(p => p.Id == id); femalethiefEF.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(femalethiefEF)); playerRepo.SavePlayer(femalethiefEF); var aiRepo = new EFAIDirectiveRepository(); var femaleDirective = new AIDirective { OwnerId = id, DoNotRecycleMe = true, Timestamp = DateTime.UtcNow, SpawnTurn = PvPWorldStatProcedures.GetWorldTurnNumber(), sVar1 = GetRichestPlayerIds(), Var1 = 0, }; aiRepo.SaveAIDirective(femaleDirective); for (var i = 0; i < 2; i++) { DomainRegistry.Repository.Execute(new GiveRune { ItemSourceId = RuneStatics.RAT_THIEF_RUNE, PlayerId = femalethiefEF.Id }); } } }
public static void RunThievesAction(int turnNumber) { IPlayerRepository playerRepo = new EFPlayerRepository(); var malethief = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.MaleRatBotId); var femalethief = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.FemaleRatBotId); IAIDirectiveRepository aiRepo = new EFAIDirectiveRepository(); var maleAI = aiRepo.AIDirectives.FirstOrDefault(i => i.OwnerId == malethief.Id); var femaleAI = aiRepo.AIDirectives.FirstOrDefault(i => i.OwnerId == femalethief.Id); // both male and female are no longer animate, end boss event if (malethief.Mobility != PvPStatics.MobilityFull && femalethief.Mobility != PvPStatics.MobilityFull) { EndEvent(); } #region both animate // both male and female are animate, have them go to players and loot them! if (malethief.Mobility == PvPStatics.MobilityFull && femalethief.Mobility == PvPStatics.MobilityFull) { // periodically refresh list of targets if (turnNumber % 12 == 0) { maleAI.sVar1 = GetRichestPlayerIds(); maleAI.Var1 = 0; } if (malethief.Health < malethief.MaxHealth / 6) { var malebuffs = ItemProcedures.GetPlayerBuffs(malethief); DomainRegistry.Repository.Execute(new Cleanse { PlayerId = malethief.Id, Buffs = malebuffs, NoValidate = true }); malethief = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.MaleRatBotId); } if (femalethief.Health < femalethief.MaxHealth / 4) { var femalebuffs = ItemProcedures.GetPlayerBuffs(femalethief); DomainRegistry.Repository.Execute(new Cleanse { PlayerId = femalethief.Id, Buffs = femalebuffs, NoValidate = true }); femalethief = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.FemaleRatBotId); } var idArray = maleAI.sVar1.Split(';'); idArray = idArray.Take(idArray.Length - 1).ToArray(); if (maleAI.Var1 >= idArray.Length) { maleAI.Var1 = 0; } var targetId = Convert.ToInt32(idArray[Convert.ToInt32(maleAI.Var1)]); var target = playerRepo.Players.FirstOrDefault(p => p.Id == targetId); while ((target == null || PlayerProcedures.PlayerIsOffline(target) || target.Mobility != PvPStatics.MobilityFull || target.Money < 20) && maleAI.Var1 < idArray.Length - 1) { maleAI.Var1++; targetId = Convert.ToInt32(idArray[Convert.ToInt32(maleAI.Var1)]); target = playerRepo.Players.FirstOrDefault(p => p.Id == targetId); } // we should hopefully by now have a valid target. Hopefully. Now move to them and loot away. try { // Sometimes the rats will still teleport to a person in the dungeon if they move after being targetted. // Check target location again. var player = PlayerProcedures.GetPlayer(target.Id); // This check should prevent that at the cost of the rats losing their turn, which seems alright to me. if (!player.dbLocationName.Contains("dungeon_")) { malethief.dbLocationName = target.dbLocationName; femalethief.dbLocationName = target.dbLocationName; // take money from victim and give some to the thieves with an uneven split. Multiple the thieves' gain by 3 // because only about a third of Arpeyis are actually collected from a completed inanimation target.Money = Math.Floor(target.Money * .90M); malethief.Money += Math.Floor(target.Money * .025M); femalethief.Money += Math.Floor(target.Money * .075M); playerRepo.SavePlayer(target); playerRepo.SavePlayer(malethief); playerRepo.SavePlayer(femalethief); AttackProcedures.Attack(femalethief, target, StunSpellSourceId); AIProcedures.DealBossDamage(femalethief, target, false, 1); var message = malethief.GetFullName() + " and " + femalethief.GetFullName() + " the Seekshadow rat thieves suddenly appear in front of you! In the blink of an eye they've swept you off your feet and have expertly swiped " + Math.Floor(target.Money * .10M) + " of your Arpeyjis."; var locationMessage = "<b>" + malethief.GetFullName() + " and " + femalethief.GetFullName() + " robbed " + target.GetFullName() + " here.</b>"; PlayerLogProcedures.AddPlayerLog(target.Id, message, true); LocationLogProcedures.AddLocationLog(malethief.dbLocationName, locationMessage); maleAI.Var1++; if (maleAI.Var1 >= 20) { maleAI.Var1 = 0; } aiRepo.SaveAIDirective(maleAI); } else { // If the target is in the dungeon, move it on to the next target. maleAI.Var1++; if (maleAI.Var1 >= 20) { maleAI.Var1 = 0; } aiRepo.SaveAIDirective(maleAI); } } catch { maleAI.Var1 = 0; } } #endregion #region veangance mode // one of the thieves has been taken down. The other will try and steal their inanimate friend back! if (malethief.Mobility != PvPStatics.MobilityFull || femalethief.Mobility != PvPStatics.MobilityFull) { Player attackingThief; Player itemThief; if (malethief.Mobility == PvPStatics.MobilityFull && femalethief.Mobility != PvPStatics.MobilityFull) { attackingThief = malethief; itemThief = femalethief; } else { attackingThief = femalethief; itemThief = malethief; } var victimThiefItem = DomainRegistry.Repository.FindSingle(new GetItemByFormerPlayer { PlayerId = itemThief.Id }); // the transformed thief is owned by someone, try and get it back! if (victimThiefItem.Owner != null) { var target = playerRepo.Players.FirstOrDefault(p => p.Id == victimThiefItem.Owner.Id); if (target.BotId == AIStatics.MaleRatBotId || target.BotId == AIStatics.FemaleRatBotId) { // do nothing, the thief already has the item... equip it if not if (!victimThiefItem.IsEquipped) { ItemProcedures.EquipItem(victimThiefItem.Id, true); } var newlocation = LocationsStatics.GetRandomLocation_NoStreets(); AIProcedures.MoveTo(attackingThief, newlocation, 100000); attackingThief.dbLocationName = newlocation; playerRepo.SavePlayer(attackingThief); var buffs = ItemProcedures.GetPlayerBuffs(attackingThief); if (attackingThief.Health < attackingThief.Health / 10) { DomainRegistry.Repository.Execute(new Cleanse { PlayerId = attackingThief.Id, Buffs = buffs, NoValidate = true }); } DomainRegistry.Repository.Execute(new Meditate { PlayerId = attackingThief.Id, Buffs = buffs, NoValidate = true }); } // Lindella, steal from her right away else if (target.BotId == AIStatics.LindellaBotId) { ItemProcedures.GiveItemToPlayer(victimThiefItem.Id, attackingThief.Id); LocationLogProcedures.AddLocationLog(target.dbLocationName, "<b>" + attackingThief.GetFullName() + " stole " + victimThiefItem.FormerPlayer.FullName + " the " + victimThiefItem.ItemSource.FriendlyName + " from Lindella.</b>"); } // target is a human and they are not offline else if (target != null && target.Mobility == PvPStatics.MobilityFull && !PlayerProcedures.PlayerIsOffline(target) && victimThiefItem.SoulboundToPlayer == null) { attackingThief.dbLocationName = target.dbLocationName; playerRepo.SavePlayer(attackingThief); AttackProcedures.Attack(attackingThief, target, PvPStatics.Spell_WeakenId); AttackProcedures.Attack(attackingThief, target, PvPStatics.Spell_WeakenId); AttackProcedures.Attack(attackingThief, target, GoldenTrophySpellSourceId); AttackProcedures.Attack(attackingThief, target, GoldenTrophySpellSourceId); AIProcedures.DealBossDamage(attackingThief, target, false, 4); target = playerRepo.Players.FirstOrDefault(p => p.Id == victimThiefItem.Owner.Id && p.BotId != AIStatics.MaleRatBotId && p.BotId != AIStatics.FemaleRatBotId); // if we have managed to turn the target, take back the victim-item if (target.Mobility != PvPStatics.MobilityFull) { ItemProcedures.GiveItemToPlayer(victimThiefItem.Id, attackingThief.Id); LocationLogProcedures.AddLocationLog(target.dbLocationName, "<b>" + attackingThief.GetFullName() + " recovered " + victimThiefItem.FormerPlayer.FullName + " the " + victimThiefItem.ItemSource.FriendlyName + ".</b>"); } } // target is a human and they are offline... just go and camp out there. else if (target != null && PlayerProcedures.PlayerIsOffline(target)) { attackingThief.dbLocationName = target.dbLocationName; playerRepo.SavePlayer(attackingThief); } } // item is on the ground, just go and pick it up. else { attackingThief.dbLocationName = victimThiefItem.dbLocationName; playerRepo.SavePlayer(attackingThief); ItemProcedures.GiveItemToPlayer(victimThiefItem.Id, attackingThief.Id); LocationLogProcedures.AddLocationLog(attackingThief.dbLocationName, "<b>" + attackingThief.GetFullName() + " recovered " + victimThiefItem.FormerPlayer.FullName + " the " + victimThiefItem.ItemSource.FriendlyName + ".</b>"); } } #endregion }