Esempio n. 1
0
        /// <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>
        /// 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);
        }
Esempio n. 3
0
        public static string OpenPsychoNip(Player player)
        {
            IAIDirectiveRepository directiveRepo = new EFAIDirectiveRepository();
            var idleBots = directiveRepo.AIDirectives.Where(d => d.State == "idle")
                           .Select(d => d.OwnerId)
                           .ToArray();

            // Set three lowest level psychos without targets on the player
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var botsToAttract            = playerRepo.Players.Where(p => idleBots.Contains(p.Id) &&
                                                                    p.BotId == AIStatics.PsychopathBotId &&
                                                                    p.Mobility == PvPStatics.MobilityFull)
                                           .OrderBy(p => p.Level)
                                           .Select(p => p.Id)
                                           .Take(3)
                                           .ToArray();

            foreach (var botId in botsToAttract)
            {
                AIDirectiveProcedures.SetAIDirective_Attack(botId, player.Id);
            }

            PlayerLogProcedures.AddPlayerLog(player.Id, $"You open a tin pf PsychoNip", false);
            LocationLogProcedures.AddLocationLog(player.dbLocationName, $"{player.GetFullName()} opened a tin of PsychoNip!");

            return("You spot a tin with a colorful insignia on a shelf.  You move over to take a closer look, but accidentally knock the tin to the floor and spill its contents!  You gather up the fallen leaves and place them back in the tin.  \"PsychoNip,\" it reads.  Perhaps you should stay alert for the next few turns in case the scent has caught anyone's attention...");
        }
Esempio n. 4
0
        /// <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 DeleteAIDirectiveByPlayerId(int ownerId)
        {
            IAIDirectiveRepository directiveRepo = new EFAIDirectiveRepository();
            var directive = directiveRepo.AIDirectives.FirstOrDefault(d => d.OwnerId == ownerId);

            if (directive != null)
            {
                directiveRepo.DeleteAIDirective(directive.Id);
            }
        }
Esempio n. 6
0
        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 bool PlayerHasHadRecentInteraction(Player player, Player fae)
        {
            IAIDirectiveRepository aiRepo = new EFAIDirectiveRepository();
            var directive = aiRepo.AIDirectives.FirstOrDefault(i => i.OwnerId == fae.Id);

            PlayerProcedures.SetTimestampToNow(fae);

            if (directive.sVar1.Contains(";" + player.Id + ";"))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        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 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 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 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 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_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);
        }
Esempio n. 14
0
        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
        }
Esempio n. 15
0
        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 RunPetMerchantActions(int turnNumber)
        {
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var petMerchant = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.WuffieBotId);


            if (petMerchant.Mobility == PvPStatics.MobilityFull)
            {
                if (petMerchant.Health < petMerchant.MaxHealth || petMerchant.Mana < petMerchant.MaxMana)
                {
                    var buffs = ItemProcedures.GetPlayerBuffs(petMerchant);
                    if (petMerchant.Health < petMerchant.MaxHealth)
                    {
                        petMerchant.Health += 200;
                        var logmessage = "<span class='playerCleansingNotification'>" + petMerchant.GetFullName() + " cleansed here.</span>";
                        LocationLogProcedures.AddLocationLog(petMerchant.dbLocationName, logmessage);
                    }
                    if (petMerchant.Mana < petMerchant.MaxMana)
                    {
                        petMerchant.Mana += 200;
                        var logmessage = "<span class='playerMediatingNotification'>" + petMerchant.GetFullName() + " meditated here.</span>";
                        LocationLogProcedures.AddLocationLog(petMerchant.dbLocationName, logmessage);
                    }

                    petMerchant.NormalizeHealthMana();
                }

                IAIDirectiveRepository aiRepo = new EFAIDirectiveRepository();

                var turnMod     = turnNumber % (24 * 4);
                var regionIndex = turnMod / 24;

                var newLocation = "";
                switch (regionIndex)
                {
                case 0:
                    newLocation = LocationsStatics.GetRandomLocation_InRegion("ranch_outside");
                    break;

                case 1:
                    newLocation = LocationsStatics.GetRandomLocation_InRegion("forest");
                    break;

                case 2:
                    newLocation = LocationsStatics.GetRandomLocation_InRegion("campground");
                    break;

                default:
                    newLocation = LocationsStatics.GetRandomLocation_InRegion("park");
                    break;
                }

                var actualNewLocation = AIProcedures.MoveTo(petMerchant, newLocation, 6);
                petMerchant.dbLocationName = actualNewLocation;
                playerRepo.SavePlayer(petMerchant);

                if (turnNumber % 11 == 5)
                {
                    DomainRegistry.Repository.Execute(new MoveAbandonedPetsToWuffie {
                        WuffieId = petMerchant.Id
                    });
                }
            }
        }
        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
                    });
                }
            }
        }