public static void SpawnLindella() { var merchant = DomainRegistry.Repository.FindSingle(new GetPlayerByBotId { BotId = AIStatics.LindellaBotId }); if (merchant == null) { var cmd = new CreatePlayer { BotId = AIStatics.LindellaBotId, Level = 5, FirstName = "Lindella", LastName = "the Soul Vendor", Health = 100000, Mana = 100000, MaxHealth = 100000, MaxMana = 100000, Mobility = PvPStatics.MobilityFull, Money = 1000, FormSourceId = LindellaFormId, Location = "270_west_9th_ave", // Lindella starts her rounds here Gender = PvPStatics.GenderFemale, }; var id = DomainRegistry.Repository.Execute(cmd); IPlayerRepository playerRepo = new EFPlayerRepository(); var newMerchant = playerRepo.Players.FirstOrDefault(p => p.Id == id); newMerchant.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(newMerchant)); playerRepo.SavePlayer(newMerchant); AIDirectiveProcedures.GetAIDirective(id); AIDirectiveProcedures.SetAIDirective_MoveTo(id, "street_15th_south"); } }
/// <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); } }
public static void DonnaCounterattack(Player personAttacking, Player donna) { AIProcedures.DealBossDamage(donna, personAttacking, true, 1); var rand = new Random(); var roll = rand.NextDouble() * 3; for (var i = 0; i < roll; i++) { AttackProcedures.Attack(donna, personAttacking, ChooseSpell(PvPStatics.LastGameTurn)); } AIProcedures.DealBossDamage(donna, personAttacking, false, (int)roll); // if Donna is weak enough start having her mega-attack anyone in the room if (donna.Health < donna.MaxHealth / 5) { var PlayersHere = PlayerProcedures.GetPlayersAtLocation(donna.dbLocationName).ToList(); foreach (var p in PlayersHere) { if (p.BotId == AIStatics.ActivePlayerBotId && p.Level > 3 && p.Mobility == PvPStatics.MobilityFull && !PlayerProcedures.PlayerIsOffline(p) && p.Id != personAttacking.Id && p.InDuel <= 0 && p.InQuest <= 0) { AttackProcedures.Attack(donna, p, ChooseSpell(PvPStatics.LastGameTurn)); AIProcedures.DealBossDamage(donna, p, false, 1); } } } //AIDirective directive = AIDirectiveProcedures.GetAIDirective(bot.Id); var directive = AIDirectiveProcedures.GetAIDirective(donna.Id); // if Donna has no target or by a random chance, make her target this attacker if (directive.TargetPlayerId == -1 || directive.State == "idle" || roll < 1) { AIDirectiveProcedures.SetAIDirective_Attack(donna.Id, personAttacking.Id); } }
/// <summary> /// Spawns Narcissa into the world and sets her initial blank AI Directive /// </summary> public static void SpawnFaeBoss() { var faeboss = DomainRegistry.Repository.FindSingle(new GetPlayerByBotId { BotId = AIStatics.FaebossBotId }); if (faeboss == null) { var cmd = new CreatePlayer { FirstName = FirstName, LastName = LastName, Location = SpawnLocation, Gender = PvPStatics.GenderFemale, Health = 100000, Mana = 100000, MaxHealth = 100000, MaxMana = 100000, FormSourceId = FaeBossFormId, Money = 1000, Mobility = PvPStatics.MobilityFull, Level = 25, BotId = AIStatics.FaebossBotId, }; var id = DomainRegistry.Repository.Execute(cmd); var playerRepo = new EFPlayerRepository(); var faebossEF = playerRepo.Players.FirstOrDefault(p => p.Id == id); faebossEF.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(faebossEF)); playerRepo.SavePlayer(faebossEF); AIDirectiveProcedures.GetAIDirective(id); for (var i = 0; i < 2; i++) { DomainRegistry.Repository.Execute(new GiveRune { ItemSourceId = RuneStatics.NARCISSA_RUNE, PlayerId = faebossEF.Id }); } } }
public static void RunActions(int turnNumber) { IPlayerRepository playerRepo = new EFPlayerRepository(); var merchant = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.LindellaBotId && f.Mobility == PvPStatics.MobilityFull); if (merchant != null && merchant.Mobility == PvPStatics.MobilityFull) { var directive = AIDirectiveProcedures.GetAIDirective(merchant.Id); if (directive.TargetLocation.IsEmpty()) { AIDirectiveProcedures.SetAIDirective_MoveTo(merchant.Id, "270_west_9th_ave"); } if (directive.TargetLocation != merchant.dbLocationName) { var newplace = AIProcedures.MoveTo(merchant, directive.TargetLocation, 6); merchant.dbLocationName = newplace; } // if the merchant has arrived, set a new target for next time. // Does this count as turning Lindella into a snail? if (directive.TargetLocation == merchant.dbLocationName && turnNumber % 2 == 0) { if (merchant.dbLocationName == "270_west_9th_ave") { AIDirectiveProcedures.SetAIDirective_MoveTo(merchant.Id, "street_15th_south"); } else if (merchant.dbLocationName == "street_15th_south") { AIDirectiveProcedures.SetAIDirective_MoveTo(merchant.Id, "street_220_sunnyglade_drive"); } else if (merchant.dbLocationName == "street_220_sunnyglade_drive") { AIDirectiveProcedures.SetAIDirective_MoveTo(merchant.Id, "street_70e9th"); } else if (merchant.dbLocationName == "street_70e9th") { AIDirectiveProcedures.SetAIDirective_MoveTo(merchant.Id, "street_130_main"); } else if (merchant.dbLocationName == "street_130_main") { AIDirectiveProcedures.SetAIDirective_MoveTo(merchant.Id, "270_west_9th_ave"); } } playerRepo.SavePlayer(merchant); var box = ItemProcedures.GetPlayerBuffs(merchant); if ((merchant.Health / merchant.MaxHealth) < .75M) { if (merchant.Health < merchant.MaxHealth) { DomainRegistry.Repository.Execute(new Cleanse { PlayerId = merchant.Id, Buffs = box, NoValidate = true }); DomainRegistry.Repository.Execute(new Cleanse { PlayerId = merchant.Id, Buffs = box, NoValidate = true }); DomainRegistry.Repository.Execute(new Meditate { PlayerId = merchant.Id, Buffs = box, NoValidate = true }); } } else { if (merchant.Mana < merchant.MaxMana) { DomainRegistry.Repository.Execute(new Meditate { PlayerId = merchant.Id, Buffs = box, NoValidate = true }); DomainRegistry.Repository.Execute(new Meditate { PlayerId = merchant.Id, Buffs = box, NoValidate = true }); DomainRegistry.Repository.Execute(new Cleanse { PlayerId = merchant.Id, Buffs = box, NoValidate = true }); } } if (turnNumber % 16 == 1) { DomainRegistry.Repository.Execute(new RestockNPC { BotId = AIStatics.LindellaBotId }); DomainRegistry.Repository.Execute(new RestockNPC { BotId = AIStatics.LoremasterBotId }); } } }
public static void RunDonnaActions() { IPlayerRepository playerRepo = new EFPlayerRepository(); var worldTurnNumber = PvPWorldStatProcedures.GetWorldTurnNumber() - 1; var donna = playerRepo.Players.FirstOrDefault(p => p.BotId == AIStatics.DonnaBotId); if (donna.Mobility != PvPStatics.MobilityFull) { EndEvent(donna); } else if (donna.Mobility == PvPStatics.MobilityFull) { var donnasBuffs = ItemProcedures.GetPlayerBuffs(donna); // have donna meditate if (donna.Mana < donna.MaxMana) { DomainRegistry.Repository.Execute(new Meditate { PlayerId = donna.Id, Buffs = donnasBuffs, NoValidate = true }); DomainRegistry.Repository.Execute(new Meditate { PlayerId = donna.Id, Buffs = donnasBuffs, NoValidate = true }); } var directive = AIDirectiveProcedures.GetAIDirective(donna.Id); if (directive.State == "attack" || directive.State == "idle") { var target = playerRepo.Players.FirstOrDefault(p => p.Id == directive.TargetPlayerId); // if Donna's target goes offline, is inanimate, or in the dungeon, have her teleport back to the ranch if (target == null || target.Mobility != PvPStatics.MobilityFull || PlayerProcedures.PlayerIsOffline(target) || target.IsInDungeon() || target.InDuel > 0 || target.InQuest > 0) { if (donna.dbLocationName != "ranch_bedroom") { LocationLogProcedures.AddLocationLog(donna.dbLocationName, donna.FirstName + " " + donna.LastName + " vanished from here in a flash of smoke."); donna.dbLocationName = "ranch_bedroom"; LocationLogProcedures.AddLocationLog(donna.dbLocationName, donna.FirstName + " " + donna.LastName + " appeared here in a flash of smoke."); playerRepo.SavePlayer(donna); } AIDirectiveProcedures.SetAIDirective_Idle(donna.Id); } // Donna has a valid target; go chase it down and attack. Donna does not look for new targets. else { var newplace = AIProcedures.MoveTo(donna, target.dbLocationName, 10); donna.dbLocationName = newplace; playerRepo.SavePlayer(donna); if (target.dbLocationName == newplace) { var rand = new Random(); var roll = rand.NextDouble() * 3 + 2; for (var i = 0; i < roll; i++) { AttackProcedures.Attack(donna, target, ChooseSpell(PvPStatics.LastGameTurn)); } AIProcedures.DealBossDamage(donna, target, false, (int)roll); } else { } } } else { } // have Donna equip all the pets she owns IItemRepository itemRepo = new EFItemRepository(); IEnumerable <Item> donnasItems = itemRepo.Items.Where(i => i.OwnerId == donna.Id && !i.IsEquipped && i.Level > 3); var itemsToEquip = new List <Item>(); foreach (var i in donnasItems) { itemsToEquip.Add(i); } foreach (var i in itemsToEquip) { i.IsEquipped = true; i.dbLocationName = donna.dbLocationName; itemRepo.SaveItem(i); } //The list should only look at pets. var donnasPlayerPets = DomainRegistry.Repository.Find(new GetItemsOwnedByPlayer { OwnerId = donna.Id }).Where(i => i.ItemSource.ItemType == PvPStatics.ItemType_Pet).OrderBy(i => i.Level).ToList(); // have Donna release her weakest pet every so often if (worldTurnNumber % 6 == 0 && donnasPlayerPets.Any()) { var weakestItem = donnasPlayerPets.First(); ItemProcedures.DropItem(weakestItem.Id, donna.dbLocationName); LocationLogProcedures.AddLocationLog(donna.dbLocationName, "Donna released one of her weaker pets, " + weakestItem.FormerPlayer.FullName + ", here."); var luckyVictim = PlayerProcedures.GetPlayerWithExactName(weakestItem.FormerPlayer.FullName); PlayerLogProcedures.AddPlayerLog(luckyVictim.Id, "Donna has released you, allowing you to wander about or be tamed by a new owner.", true); } } }
/// <summary> /// Perform Narcissa's regular actions when a new turn has started. If Narcissa has no aggroed target, she seeks to transform random people into /// certain animate forms. If she has aggro, she will attempt to chase them and cast a pet spell on them. If she can't catch up, she'll cast the animate /// spells in the area instead and resume pursuit next turn. /// </summary> public static void RunTurnLogic() { IPlayerRepository playerRepo = new EFPlayerRepository(); var faeboss = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.FaebossBotId); // fae boss is no longer animate; end the event if (faeboss.Mobility != PvPStatics.MobilityFull) { EndEvent(); return; } // have Narcissa periodically drop all of her pets/belongings so she doesn't get OP with them if (PvPWorldStatProcedures.GetWorldTurnNumber() % 12 == 0) { DomainRegistry.Repository.Execute(new DropAllItems { PlayerId = faeboss.Id, IgnoreRunes = true }); } // have Narcissa meditate to get her mana back up faeboss.Mana = faeboss.MaxMana; var directive = AIDirectiveProcedures.GetAIDirective(faeboss.Id); // no target, go out and hit some random people with animate spells if (!HasValidTarget(directive)) { ResetTarget(directive); var newTargetLocation = GetLocationWithMostEligibleTargets(); var newActualLocation = AIProcedures.MoveTo(faeboss, newTargetLocation, GetRandomChaseDistance()); faeboss.dbLocationName = newActualLocation; playerRepo.SavePlayer(faeboss); CastAnimateSpellsAtLocation(faeboss); } // Narcissa has a valid target, go for them else { var target = PlayerProcedures.GetPlayer((int)directive.Var1); var newTargetLocation = target.dbLocationName; var newActualLocation = AIProcedures.MoveTo(faeboss, newTargetLocation, GetRandomChaseDistance()); faeboss.dbLocationName = newActualLocation; playerRepo.SavePlayer(faeboss); if (faeboss.dbLocationName == target.dbLocationName) { var spell = ChooseSpell(PvPWorldStatProcedures.GetWorldTurnNumber(), PvPStatics.MobilityPet); for (var i = 0; i < 4; i++) { AttackProcedures.Attack(faeboss, target, spell); } } else { CastAnimateSpellsAtLocation(faeboss); } } }