Exemple #1
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...");
        }
        private static IEnumerable <InstinctData> StripperActions(IPlayerRepository playerRepo, IEnumerable <InstinctData> mcPlayers, Random rand)
        {
            // Strippers - remove random item
            var mcStrippers = mcPlayers.Where(p => JokeShopProcedures.STRIPPERS.Any(stripperForm => p.FormSourceId == stripperForm)).ToList();

            foreach (var stripper in mcStrippers)
            {
                var stripperPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == stripper.Id);
                var stripperItems  = ItemProcedures.GetAllPlayerItems(stripperPlayer.Id)
                                     .Where(i => i.dbItem.IsEquipped &&
                                            i.Item.ItemType != PvPStatics.ItemType_Pet &&
                                            i.Item.ItemType != PvPStatics.ItemType_Consumable &&
                                            i.Item.ItemType != PvPStatics.ItemType_Consumable_Reuseable).ToList();

                if (stripperItems.Any())
                {
                    string[] adverbs    = { "seductively", "cautiously", "flirtatiously", "cheekily", "obediently", "enthusiastically", "reluctantly", "hesitantly", "energetically", "sheepishly" };
                    var      adverb     = adverbs[rand.Next(adverbs.Count())];
                    var      itemToDrop = stripperItems[rand.Next(stripperItems.Count())];

                    PlayerLogProcedures.AddPlayerLog(stripper.Id, $"You {adverb} remove your <b>{itemToDrop.Item.FriendlyName}</b>!", true);
                    LocationLogProcedures.AddLocationLog(stripper.dbLocationName, $"{stripperPlayer.GetFullName()} {adverb} removes their <b>{itemToDrop.Item.FriendlyName}</b>!");
                    ItemProcedures.DropItem(itemToDrop.dbItem.Id);
                }

                mcPlayers = mcPlayers.Where(p => p.Id != stripper.Id);
            }

            return(mcPlayers);
        }
Exemple #3
0
        public static string ForceAttack(Player attacker, bool strongAttackerAlerts = false, Random rand = null)
        {
            if (attacker.TimesAttackingThisUpdate >= PvPStatics.MaxAttacksPerUpdate)
            {
                return(null);
            }

            if (attacker.GameMode != (int)GameModeStatics.GameModes.PvP)
            {
                return(null);
            }

            rand = rand ?? new Random();
            var candidates = JokeShopProcedures.ActivePlayersInJokeShopApartFrom(attacker)
                             .Where(p => p.GameMode == (int)GameModeStatics.GameModes.PvP &&
                                    JokeShopProcedures.PlayerHasBeenWarned(p)).ToList();

            if (candidates == null || candidates.IsEmpty())
            {
                return(null);
            }

            var victim = candidates[rand.Next(candidates.Count())];

            var spells = SkillProcedures.AvailableSkills(attacker, victim, true);

            if (spells == null || spells.IsEmpty())
            {
                return(null);
            }

            var spellList = spells.ToArray();
            var spell     = spellList[rand.Next(spellList.Count())];

            var message = $"You are compelled to attack {victim.GetFullName()}!";

            PlayerLogProcedures.AddPlayerLog(attacker.Id, message, strongAttackerAlerts);
            PlayerLogProcedures.AddPlayerLog(victim.Id, $"{attacker.GetFullName()} is compelled to attack you!", true);
            LocationLogProcedures.AddLocationLog(attacker.dbLocationName, $"{attacker.GetFullName()} is compelled to attack {victim.GetFullName()}!");

            // Note we do not apply the full gamut of preconditions of a manual attack present in the controller
            var attack = AttackProcedures.AttackSequence(attacker, victim, spell, false);

            if (strongAttackerAlerts)
            {
                PlayerLogProcedures.AddPlayerLog(attacker.Id, attack, true);
            }

            return($"{message}<br />{attack}");
        }
        private static IEnumerable <InstinctData> MaidActions(IPlayerRepository playerRepo, IEnumerable <InstinctData> mcPlayers, Random rand)
        {
            // Maids - find places to clean
            var mcMaids = mcPlayers.Where(p => JokeShopProcedures.MAIDS.Any(maidForm => p.FormSourceId == maidForm)).ToList();

            foreach (var maid in mcMaids)
            {
                var maidPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == maid.Id);
                var maidLoc    = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == maidPlayer.dbLocationName);

                if (maidLoc != null)
                {
                    string nextLoc;
                    string newContract = "";

                    string[] cleaningContracts = { "coffee_shop", "tavern", "oldoak_apartments", "mansion", "ranch_inside", "castle", "salon" };
                    if (cleaningContracts.Contains(maidLoc.Region))
                    {
                        nextLoc = LocationsStatics.GetRandomLocation_InRegion(maidLoc.Region);
                    }
                    else
                    {
                        newContract = "One of the local facilities has just signed a new contract with you!  ";
                        nextLoc     = LocationsStatics.GetRandomLocation_InRegion(cleaningContracts[rand.Next(cleaningContracts.Count())]);
                    }

                    var stoppedAt = EnvironmentPrankProcedures.MovePlayer(maidPlayer, nextLoc, 20, timestamp: false);

                    if (stoppedAt == nextLoc || maidPlayer.dbLocationName == nextLoc)
                    {
                        var      here       = LocationsStatics.GetConnectionName(nextLoc);
                        string[] activities = { "dusting away the cobwebs", "vaccuuming the floor", "washing up the dishes", "doing the laundry", "serving refreshments", "sweeping the trash", "handing out freshly baked cupcakes" };
                        var      activity   = activities[rand.Next(activities.Count())];

                        PlayerLogProcedures.AddPlayerLog(maidPlayer.Id, $"{newContract}You arrive at <b>{here}</b> and start {activity}!", true);
                        LocationLogProcedures.AddLocationLog(nextLoc, $"{maidPlayer.GetFullName()} arrives here and starts <b>{activity}</b>.");
                    }
                    else if (stoppedAt != null)
                    {
                        var here = LocationsStatics.GetConnectionName(stoppedAt);
                        PlayerLogProcedures.AddPlayerLog(maidPlayer.Id, $"{newContract}You quickly head to your new job but only get as far as <b>{here}</b>.", true);
                    }
                }

                mcPlayers = mcPlayers.Where(p => p.Id != maid.Id);
            }

            return(mcPlayers);
        }
Exemple #5
0
        public static string RandomShout(Player player, Random rand = null)
        {
            rand = rand ?? new Random();

            string[] memes =
            {
                // More memes here
            };
            string meme = null;

            var specialCases = 2;

            var selection = rand.Next(memes.Count() + specialCases);

            if (selection == 0)
            {
                var covens = CovenantProcedures.GetCovenantsList();

                if (player.Covenant.HasValue)
                {
                    covens = covens.Where(c => c.dbCovenant.Id == player.Covenant.Value);
                }

                if (covens.Any())
                {
                    var coven = covens.ElementAt(rand.Next(covens.Count()));
                    meme = $"All hail {coven.Leader.GetFullName()}, leader of {coven.dbCovenant.Name}!";
                }
            }
            else if (selection == 1)
            {
                meme = $"I'm {(rand.Next(2) == 0 ? "" : "not ")}{(rand.Next(2) == 0 ? "cute" : "cyoot")}!!!";
            }
            else
            {
                meme = memes[selection - specialCases];
            }

            if (meme == null)
            {
                return(null);
            }

            LocationLogProcedures.AddLocationLog(player.dbLocationName, $"{player.GetFullName()} shouted <b>\"{meme}\"</b> here.");

            return($"You shouted \"{meme}\"");
        }
        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>");
        }
        private static bool Teleport(Player player, string location, bool logLocations)
        {
            if (location == null)
            {
                return(false);
            }

            var destination = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == location);

            if (destination == null)
            {
                return(false);
            }

            if (player.InDuel > 0 || player.InQuest > 0 || player.MindControlIsActive || player.MoveActionPointDiscount < -TurnTimesStatics.GetActionPointReserveLimit())
            {
                return(false);
            }

            if (ItemProcedures.GetAllPlayerItems(player.Id).Count(i => !i.dbItem.IsEquipped) > PvPStatics.MaxCarryableItemCountBase + player.ExtraInventory)
            {
                // Carryiing too much
                return(false);
            }

            if (destination.dbName.Contains("dungeon_"))
            {
                SkillProcedures.GiveSkillToPlayer(player.Id, PvPStatics.Dungeon_VanquishSpellSourceId);
            }

            PlayerProcedures.MovePlayer_InstantNoLog(player.Id, location);

            if (logLocations)
            {
                LocationLogProcedures.AddLocationLog(player.dbLocationName, $"Strange forces propel {player.GetFullName()} off to {destination.Name}!");
            }
            else
            {
                LocationLogProcedures.AddLocationLog(player.dbLocationName, $"{player.GetFullName()} is whisked off to a faraway place!");
            }
            LocationLogProcedures.AddLocationLog(location, $"{player.GetFullName()} is surprised to find they are suddenly here!");
            PlayerLogProcedures.AddPlayerLog(player.Id, $"You are sent to {destination.Name}", false);

            return(true);
        }
        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);
        }
Exemple #9
0
        public static string PlaceBountyOnPlayersHead(Player player, Random rand = null)
        {
            // Only place bounties on PvP players
            if (player.GameMode != (int)GameModeStatics.GameModes.PvP)
            {
                return(null);
            }

            rand = rand ?? new Random();
            var bountyEffectSourceId = BountyProcedures.PlaceBounty(player, rand);

            if (!bountyEffectSourceId.HasValue)
            {
                return(null);
            }

            var details = BountyProcedures.BountyDetails(player, bountyEffectSourceId.Value);

            if (details == null)
            {
                return(null);
            }

            StatsProcedures.AddStat(player.MembershipId, StatsProcedures.Stat__BountyCount, 1);

            // Put up some wanted posters
            var locations       = LocationsStatics.LocationList.GetLocation.Select(l => l.dbName).ToList();
            var locationMessage = $"<b>Wanted:</b>  A reward is on offer to whoever turns <b>{player.GetFullName()}</b> into a <b>{details.Form?.FriendlyName}</b>!";

            for (var i = 0; i < 10; i++)
            {
                var loc = locations[rand.Next(locations.Count())];
                LocationLogProcedures.AddLocationLog(loc, locationMessage);
                locations.Remove(loc);
            }

            var playerMessage = $"The spirits in the store are enraged by your actions!  They are too out of phase to attack you directly and instead choose to place a bounty on your head!  Beware of the townspeople trying to turn you into a <b>{details.Form?.FriendlyName}</b>!";

            PlayerLogProcedures.AddPlayerLog(player.Id, playerMessage, true);

            return(playerMessage);
        }
Exemple #10
0
        public static string DiceGame(Player player)
        {
            var target = 69;

            // /roll 4d20
            var die1  = PlayerProcedures.RollDie(20);
            var die2  = PlayerProcedures.RollDie(20);
            var die3  = PlayerProcedures.RollDie(20);
            var die4  = PlayerProcedures.RollDie(20);
            var total = die1 + die2 + die3 + die4;

            // Arbitrary score calculation, trying to avoid any big advantage for those who roll more often
            int score;

            if (total == target)
            {
                score = total;
            }
            else
            {
                var distance = Math.Abs(total - target);

                if (distance <= 11)
                {
                    score = (11 - distance) * 4;
                }
                else
                {
                    score = (11 - distance) / 10;
                }
            }

            StatsProcedures.AddStat(player.MembershipId, StatsProcedures.Stat__DiceGameScore, score);

            LocationLogProcedures.AddLocationLog(player.dbLocationName, $"{player.GetFullName()} rolls {die1}, {die2}, {die3} and {die4}, giving a total of <b>{total}</b>.");

            return($"You pick up four 20-sided dice and roll {die1}, {die2}, {die3} and {die4}, giving a total of <b>{total}</b>.  Your score is <b>{score}</b>.");
        }
        private static (IEnumerable <InstinctData> mcPlayers, IEnumerable <InstinctData> freePlayers) SheepActions(IPlayerRepository playerRepo, IEnumerable <InstinctData> mcPlayers, IEnumerable <InstinctData> freePlayers, Random rand)
        {
            // Sheep - find another sheep and follow it
            var mcSheep = mcPlayers.Where(p => JokeShopProcedures.SHEEP.Any(sheepForm => p.FormSourceId == sheepForm)).ToList();

            if (!mcSheep.IsEmpty())
            {
                var freeSheep       = freePlayers.Where(p => JokeShopProcedures.SHEEP.Any(sheepForm => p.FormSourceId == sheepForm)).ToList();
                var flockToPlayer   = -1;
                var flockToLocation = "";

                if (!freeSheep.IsEmpty())
                {
                    var target = freeSheep[rand.Next(freeSheep.Count())];
                    flockToPlayer   = target.Id;
                    flockToLocation = target.dbLocationName;
                }
                else
                {
                    flockToLocation = LocationsStatics.GetRandomLocationNotInDungeonOr(LocationsStatics.JOKE_SHOP);
                }

                foreach (var sheep in mcSheep)
                {
                    var sheepPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == sheep.Id);
                    var stoppedAt   = EnvironmentPrankProcedures.MovePlayer(sheepPlayer, flockToLocation, 15, timestamp: false, callback: (p, loc) =>
                    {
                        if (rand.Next(3) == 0)
                        {
                            LocationLogProcedures.AddLocationLog(loc, $"{p.GetFullName()} bleated here:  <b>Baaaaa!</b>");
                        }
                    });

                    if (stoppedAt == flockToLocation)
                    {
                        if (flockToPlayer >= 0)
                        {
                            PlayerLogProcedures.AddPlayerLog(flockToPlayer, $"{sheepPlayer.GetFullName()} bleated at you:  <b>Baaaaa!</b>", true);
                        }

                        LocationLogProcedures.AddLocationLog(stoppedAt, $"{sheepPlayer.GetFullName()} bleated here:  <b>Baaaaa!</b>");
                    }

                    if (stoppedAt != null)
                    {
                        var here = LocationsStatics.GetConnectionName(stoppedAt);
                        PlayerLogProcedures.AddPlayerLog(sheepPlayer.Id, $"You followed your flock to <b>{here}</b>.", true);
                    }
                }

                // Don't consider affected players for any more actions this turn
                mcPlayers = mcPlayers.Where(p => mcSheep.All(s => p.Id != s.Id));

                if (flockToPlayer >= 0)
                {
                    freePlayers = freePlayers.Where(p => p.Id != flockToPlayer);
                }
            }

            return(mcPlayers, freePlayers);
        }
        private static IEnumerable <InstinctData> GhostActions(IPlayerRepository playerRepo, IEnumerable <InstinctData> mcPlayers, Random rand)
        {
            // Ghosts - haunt old buildings
            var mcGhosts = mcPlayers.Where(p => JokeShopProcedures.GHOSTS.Any(ghostForm => p.FormSourceId == ghostForm)).ToList();

            foreach (var ghost in mcGhosts)
            {
                var ghostPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == ghost.Id);
                var ghostLoc    = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == ghostPlayer.dbLocationName);

                if (ghostLoc != null)
                {
                    string nextLoc;

                    string[] haunts = { "mansion", "castle" };
                    if (haunts.Contains(ghostLoc.Region))
                    {
                        nextLoc = LocationsStatics.GetRandomLocation_InRegion(ghostLoc.Region);
                    }
                    else
                    {
                        nextLoc = LocationsStatics.GetRandomLocation_InRegion(haunts[rand.Next(haunts.Count())]);
                    }

                    // Check whether we can haunt the current tile
                    // An enhancement would be to allow ghosts to move through walls
                    var stoppedAt = EnvironmentPrankProcedures.MovePlayer(ghostPlayer, nextLoc, 20, timestamp: false);

                    var canHaunt = stoppedAt == nextLoc || ghostPlayer.dbLocationName == nextLoc;

                    if (!canHaunt && stoppedAt != null)
                    {
                        var stoppedAtTile = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == stoppedAt);
                        canHaunt = haunts.Contains(stoppedAtTile.Region);
                    }

                    if (canHaunt)
                    {
                        var here   = LocationsStatics.GetConnectionName(nextLoc);
                        var cutoff = DateTime.UtcNow.AddMinutes(-TurnTimesStatics.GetOfflineAfterXMinutes());

                        var candidates = playerRepo.Players
                                         .Where(p => p.dbLocationName == nextLoc &&
                                                p.LastActionTimestamp >= cutoff &&
                                                p.Id != ghostPlayer.Id &&
                                                p.Mobility == PvPStatics.MobilityFull &&
                                                p.InDuel <= 0 &&
                                                p.InQuest <= 0 &&
                                                p.BotId == AIStatics.ActivePlayerBotId)
                                         .ToList();

                        if (candidates.Any())
                        {
                            var      victim = candidates[rand.Next(candidates.Count())];
                            string[] calls  = { "Boo!", "Whooo!" };
                            var      call   = calls[rand.Next(calls.Count())];

                            PlayerLogProcedures.AddPlayerLog(ghostPlayer.Id, $"After entering {here} you tap {victim.GetFullName()} on the shoulder and shout <b>\"{call}\"</b>!", true);
                            PlayerLogProcedures.AddPlayerLog(victim.Id, $"{ghostPlayer.GetFullName()} taps you on the shoulder and shouts <b>\"{call}\"</b>!", true);
                            LocationLogProcedures.AddLocationLog(nextLoc, $"{ghostPlayer.GetFullName()} shouts <b>\"{call}\"</b> at {victim.GetFullName()}.");
                        }
                        else
                        {
                            string[] activities = { "rattles some chains", "wails like a banshee", "floats through a wall", "lights a candle", "makes the lights flicker", "fades into the background", "knocks a book off a shelf", "melts into a pool of ectoplasm", "sends a a chill through the air" };
                            var      activity   = activities[rand.Next(activities.Count())];

                            PlayerLogProcedures.AddPlayerLog(ghostPlayer.Id, $"You begin haunting {here}!", true);
                            LocationLogProcedures.AddLocationLog(nextLoc, $"<b>{ghostPlayer.GetFullName()} {activity}</b>.");
                        }
                    }
                    else if (stoppedAt != null)
                    {
                        var here = LocationsStatics.GetConnectionName(stoppedAt);
                        PlayerLogProcedures.AddPlayerLog(ghostPlayer.Id, $"The spirits call you to <b>{here}</b>.", true);
                    }
                }

                mcPlayers = mcPlayers.Where(p => p.Id != ghost.Id);
            }

            return(mcPlayers);
        }
Exemple #13
0
        public static void RunActions(int turnNumber)
        {
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var bimboBoss = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.BimboBossBotId);

            // move her toward the location with the most eligible targets
            if (bimboBoss == null || bimboBoss.Mobility != PvPStatics.MobilityFull)
            {
                EndEvent();
                return;
            }

            var targetLocation = GetLocationWithMostEligibleTargets();
            var newlocation    = AIProcedures.MoveTo(bimboBoss, targetLocation, 13);

            bimboBoss.dbLocationName = newlocation;

            playerRepo.SavePlayer(bimboBoss);
            bimboBoss = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.BimboBossBotId);
            var bimboBossBuffs = ItemProcedures.GetPlayerBuffs(bimboBoss);

            // Get mana back up
            if (bimboBoss.Mana < bimboBoss.MaxMana / 4)
            {
                DomainRegistry.Repository.Execute(new Meditate {
                    PlayerId = bimboBoss.Id, Buffs = bimboBossBuffs, NoValidate = true
                });
                DomainRegistry.Repository.Execute(new Meditate {
                    PlayerId = bimboBoss.Id, Buffs = bimboBossBuffs, NoValidate = true
                });
                DomainRegistry.Repository.Execute(new Meditate {
                    PlayerId = bimboBoss.Id, Buffs = bimboBossBuffs, NoValidate = true
                });
            }
            else if (bimboBoss.Mana < bimboBoss.MaxMana / 3)
            {
                DomainRegistry.Repository.Execute(new Meditate {
                    PlayerId = bimboBoss.Id, Buffs = bimboBossBuffs, NoValidate = true
                });
                DomainRegistry.Repository.Execute(new Meditate {
                    PlayerId = bimboBoss.Id, Buffs = bimboBossBuffs, NoValidate = true
                });
            }
            else if (bimboBoss.Mana < bimboBoss.MaxMana / 2)
            {
                DomainRegistry.Repository.Execute(new Meditate {
                    PlayerId = bimboBoss.Id, Buffs = bimboBossBuffs, NoValidate = true
                });
            }

            var rand = new Random(Guid.NewGuid().GetHashCode());

            // attack all eligible targets here, even if it's not her final destination
            var playersHere = GetEligibleTargetsInLocation(newlocation, bimboBoss);

            foreach (var p in playersHere)
            {
                // if the player doesn't currently have it, give them the infection kiss
                if (!EffectProcedures.PlayerHasEffect(p, KissEffectSourceId) && !EffectProcedures.PlayerHasEffect(p, CureEffectSourceId))
                {
                    AttackProcedures.Attack(bimboBoss, p, KissSkillSourceId);
                    AIProcedures.DealBossDamage(bimboBoss, p, false, 1);
                }


                // otherwise run the regular trasformation
                else if (p.FormSourceId != RegularBimboFormSourceId)
                {
                    AttackProcedures.Attack(bimboBoss, p, RegularTFSpellSourceId);
                    AIProcedures.DealBossDamage(bimboBoss, p, false, 1);
                }
            }

            // have a random chance that infected players spontaneously transform
            IEffectRepository effectRepo = new EFEffectRepository();
            var ownerIds = effectRepo.Effects.Where(e => e.EffectSourceId == KissEffectSourceId).Select(e => e.OwnerId).ToList();

            foreach (var effectId in ownerIds)
            {
                var infectee = playerRepo.Players.FirstOrDefault(p => p.Id == effectId);

                // if the infectee is no longer animate or is another boss, skip them
                if (infectee.Mobility != PvPStatics.MobilityFull || infectee.BotId < AIStatics.PsychopathBotId)
                {
                    continue;
                }

                var roll = rand.NextDouble();

                // random chance of spontaneously transforming
                if (infectee.FormSourceId != RegularBimboFormSourceId && !PlayerProcedures.PlayerIsOffline(infectee))
                {
                    if (roll < .16 && infectee.InDuel <= 0 && infectee.InQuest <= 0)
                    {
                        DomainRegistry.Repository.Execute(new ChangeForm
                        {
                            PlayerId     = infectee.Id,
                            FormSourceId = RegularBimboFormSourceId
                        });

                        DomainRegistry.Repository.Execute(new ReadjustMaxes
                        {
                            playerId = infectee.Id,
                            buffs    = ItemProcedures.GetPlayerBuffs(infectee)
                        });

                        infectee = playerRepo.Players.FirstOrDefault(p => p.Id == effectId);

                        var message       = "You gasp, your body shifting as the virus infecting you overwhelms your biological and arcane defenses.  Before long you find that your body has been transformed into that of one of the many bimbonic plague victims and you can't help but succumb to the urges to spread your infection--no, your gift!--on to the rest of mankind.";
                        var loclogMessage = "<b style='color: red'>" + infectee.GetFullName() + " succumbed to the bimbonic virus, spontaneously transforming into one of Lady Lovebringer's bimbos.</b>";

                        PlayerLogProcedures.AddPlayerLog(infectee.Id, message, true);
                        LocationLogProcedures.AddLocationLog(infectee.dbLocationName, loclogMessage);
                    }
                }

                // spread the kiss so long as the player is not offline
                if (infectee.FormSourceId == RegularBimboFormSourceId && !PlayerProcedures.PlayerIsOffline(infectee))
                {
                    // back up the last action timestamp since we don't want these attacks to count against their offline timer
                    var lastActionBackup = infectee.LastActionTimestamp;

                    var eligibleTargets  = GetEligibleTargetsInLocation(infectee.dbLocationName, infectee);
                    var attacksMadeCount = 0;

                    foreach (var p in eligibleTargets)
                    {
                        if (!EffectProcedures.PlayerHasEffect(p, KissEffectSourceId) && !EffectProcedures.PlayerHasEffect(p, CureEffectSourceId) && attacksMadeCount < 3)
                        {
                            attacksMadeCount++;
                            AttackProcedures.Attack(infectee, p, KissSkillSourceId);
                        }
                        else if (attacksMadeCount < 3)
                        {
                            AttackProcedures.Attack(infectee, p, RegularTFSpellSourceId);
                            attacksMadeCount++;
                        }
                    }

                    // if there were any attacked players, restore the old last action timestamp and make sure AP and mana has not gone into negative
                    if (attacksMadeCount > 0)
                    {
                        infectee = playerRepo.Players.FirstOrDefault(p => p.Id == effectId);
                        infectee.LastActionTimestamp = lastActionBackup;

                        if (infectee.ActionPoints < 0)
                        {
                            infectee.ActionPoints = 0;
                        }

                        if (infectee.Mana < 0)
                        {
                            infectee.Mana = 0;
                        }

                        playerRepo.SavePlayer(infectee);
                    }
                }
            }


            // every 5 turns heal the boss based on how many infected bots there are
            if (ShouldHeal(bimboBoss, turnNumber))
            {
                var activeCurses = effectRepo.Effects.Count(eff => eff.EffectSourceId == KissEffectSourceId) * 5;
                activeCurses      = activeCurses > 130 ? 130 : activeCurses;
                bimboBoss.Health += activeCurses;
                playerRepo.SavePlayer(bimboBoss);
                var message = "<b>" + bimboBoss.GetFullName() + " draws energy from her bimbo horde, regenerating her own willpower by " + activeCurses + ".</b>";
                LocationLogProcedures.AddLocationLog(newlocation, message);
            }

            // drop a cure
            DropCure(turnNumber);
        }
        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
                    });
                }
            }
        }
        private static (IEnumerable <InstinctData> mcPlayers, IEnumerable <InstinctData> freePlayers) CatActions(IPlayerRepository playerRepo, IEnumerable <InstinctData> mcPlayers, IEnumerable <InstinctData> freePlayers, Random rand)
        {
            // Cats - chase rodents
            var mcCats2 = mcPlayers.Where(p => JokeShopProcedures.CATS_AND_NEKOS.Any(catForm => p.FormSourceId == catForm)).ToList();

            if (!mcCats2.IsEmpty())
            {
                var mcRodents   = mcPlayers.Where(p => JokeShopProcedures.RODENTS.Any(rodentForm => p.FormSourceId == rodentForm)).ToList();
                var freeRodents = freePlayers.Where(p => JokeShopProcedures.RODENTS.Any(rodentForm => p.FormSourceId == rodentForm)).ToList();

                while (!mcCats2.IsEmpty() && mcRodents.Count() + freeRodents.Count() > 0)
                {
                    // Find a cat
                    var catIndex = rand.Next(mcCats2.Count());
                    var cat      = mcCats2[catIndex];
                    mcCats2.RemoveAt(catIndex);
                    mcPlayers = mcPlayers.Where(p => p.Id != cat.Id);

                    int    rodentId;
                    string rodentLoc;

                    // Find a rodent for them to chase
                    if (!mcRodents.IsEmpty())
                    {
                        var rodentIndex = rand.Next(mcRodents.Count());
                        var rodent      = mcRodents[rodentIndex];
                        mcRodents.RemoveAt(rodentIndex);

                        rodentId  = rodent.Id;
                        rodentLoc = rodent.dbLocationName;
                        mcPlayers = mcPlayers.Where(p => p.Id != rodentId);
                    }
                    else  // !freeRodents.IsEmpty()
                    {
                        var rodentIndex = rand.Next(freeRodents.Count);
                        var rodent      = freeRodents[catIndex];
                        freeRodents.RemoveAt(rodentIndex);

                        rodentId    = rodent.Id;
                        rodentLoc   = rodent.dbLocationName;
                        freePlayers = freePlayers.Where(p => p.Id != rodentId);
                    }

                    var catPlayer    = playerRepo.Players.FirstOrDefault(p => p.Id == cat.Id);
                    var rodentPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == rodentId);

                    // Move cat
                    var stoppedAt = EnvironmentPrankProcedures.MovePlayer(catPlayer, rodentLoc, 15, timestamp: false, callback: (p, loc) =>
                    {
                        var roll = rand.Next(4);
                        if (roll == 0)
                        {
                            LocationLogProcedures.AddLocationLog(loc, $"{catPlayer.GetFullName()} stealthily prowls the area, on the hunt for {rodentPlayer.GetFullName()}");
                        }
                    });

                    if (stoppedAt == rodentLoc)
                    {
                        var here = LocationsStatics.GetConnectionName(stoppedAt);
                        LocationLogProcedures.AddLocationLog(stoppedAt, $"{catPlayer.GetFullName()} lunges at a rodent, but {rodentPlayer.GetFullName()} is too quick and evades the cat's attack!</b>");

                        PlayerLogProcedures.AddPlayerLog(rodentId, $"{catPlayer.GetFullName()} jumps out at you, but you leap from their paws and deprive them of an easy snack!", true);
                        PlayerLogProcedures.AddPlayerLog(catPlayer.Id, $"You prowl to <b>{here}</b>, creep up on {rodentPlayer.GetFullName()} and pounce!  But they're too quick and evade your clutches!", true);
                    }
                    else if (stoppedAt != null)  // Cat moved, but didn't get to the rodent's location
                    {
                        var here = LocationsStatics.GetConnectionName(stoppedAt);
                        PlayerLogProcedures.AddPlayerLog(catPlayer.Id, $"You prowl to <b>{here}</b>, being careful not to get too close to your prey as you prepare for the hunt...", true);
                    }
                    else if (cat.dbLocationName == rodentLoc)
                    {
                        PlayerLogProcedures.AddPlayerLog(rodentId, $"{catPlayer.GetFullName()} hides in a bush, stealthily watching you, getting ready to pounce...", true);
                        PlayerLogProcedures.AddPlayerLog(catPlayer.Id, $"You slink behind a bush and focus your eyes on {rodentPlayer.GetFullName()}, getting ready to strike...", true);
                    }
                }
            }

            return(mcPlayers, freePlayers);
        }
Exemple #16
0
        public static string SummonPsychopath(Player player, Random rand = null, int?strengthOverride = null, bool?aggro = null)
        {
            rand = rand ?? new Random();

            var baseStrength = Math.Min(Math.Max(0, (player.Level - 1) / 3), 3);
            var strength     = strengthOverride ?? (baseStrength + Math.Max(0, rand.Next(6) - 1));

            var prefix = "";
            int level;
            int perk;
            int?extraPerk = null;
            var gender    = rand.Next(2);
            int form;

            var turnNumber = PvPWorldStatProcedures.GetWorldTurnNumber();

            if (strength <= 0 || (turnNumber < 300 && !strengthOverride.HasValue))
            {
                strength = 0;
                level    = 1;
                perk     = AIProcedures.PsychopathicForLevelOneEffectSourceId;
                form     = gender == 0 ? AIProcedures.Psycho1MId : AIProcedures.Psycho1FId;
            }
            else if (strength == 1 || (turnNumber < 600 && !strengthOverride.HasValue))
            {
                strength = 1;
                level    = 3;
                prefix   = "Fierce";
                perk     = AIProcedures.PsychopathicForLevelThreeEffectSourceId;
                form     = gender == 0 ? AIProcedures.Psycho3MId : AIProcedures.Psycho3FId;
            }
            else if (strength == 2 || (turnNumber < 900 && !strengthOverride.HasValue))
            {
                strength = 2;
                level    = 5;
                prefix   = "Wrathful";
                perk     = AIProcedures.PsychopathicForLevelFiveEffectSourceId;
                form     = gender == 0 ? AIProcedures.Psycho5MId : AIProcedures.Psycho5FId;
            }
            else if (strength == 3 || (turnNumber < 1500 && !strengthOverride.HasValue))
            {
                strength = 3;
                level    = 7;
                prefix   = "Loathful";
                perk     = AIProcedures.PsychopathicForLevelSevenEffectSourceId;
                form     = gender == 0 ? AIProcedures.Psycho7MId : AIProcedures.Psycho7FId;
            }
            else if (strength == 4 || (turnNumber < 2400 && !strengthOverride.HasValue))
            {
                strength = 4;
                level    = 9;
                prefix   = "Soulless";
                perk     = AIProcedures.PsychopathicForLevelNineEffectSourceId;
                form     = gender == 0 ? AIProcedures.Psycho9MId : AIProcedures.Psycho9FId;
            }
            else if (strength == 5 || (turnNumber < 3600 && !strengthOverride.HasValue))
            {
                strength  = 5;
                level     = 11;
                prefix    = "Ruthless";
                perk      = AIProcedures.PsychopathicForLevelNineEffectSourceId;
                extraPerk = AIProcedures.PsychopathicForLevelThreeEffectSourceId;
                form      = gender == 0 ? AIProcedures.Psycho9MId : AIProcedures.Psycho9FId;
            }
            else
            {
                strength  = 6;
                level     = 13;
                prefix    = "Eternal";
                perk      = AIProcedures.PsychopathicForLevelNineEffectSourceId;
                extraPerk = AIProcedures.PsychopathicForLevelFiveEffectSourceId;
                form      = gender == 0 ? AIProcedures.Psycho9MId : AIProcedures.Psycho9FId;
            }

            var firstName = "Psychopath";
            var lastName  = NameService.GetRandomLastName();

            if (!prefix.IsEmpty())
            {
                firstName = $"{prefix} {firstName}";
            }

            IPlayerRepository playerRepo = new EFPlayerRepository();
            var cmd = new CreatePlayer
            {
                FirstName          = firstName,
                LastName           = lastName,
                Location           = player.dbLocationName,
                FormSourceId       = form,
                Level              = level,
                Health             = 100000,
                MaxHealth          = 100000,
                Mana               = 100000,
                MaxMana            = 100000,
                BotId              = AIStatics.PsychopathBotId,
                UnusedLevelUpPerks = 0,
                XP     = 0,
                Money  = (strength + 1) * 50,
                Gender = gender == 0 ? PvPStatics.GenderMale : PvPStatics.GenderFemale,
            };

            var botId = DomainRegistry.Repository.Execute(cmd);

            // Give spells
            var eligibleSkills = SkillStatics.GetLearnablePsychopathSkills().ToList();

            SkillProcedures.GiveSkillToPlayer(botId, eligibleSkills[rand.Next(eligibleSkills.Count())].Id);

            if (strength >= 5)
            {
                SkillProcedures.GiveSkillToPlayer(botId, PvPStatics.Spell_WeakenId);
            }

            if (strength >= 6)
            {
                var limitedMobilityForms = JokeShopProcedures.AnimateForms().Where(f => f.Category == JokeShopProcedures.LIMITED_MOBILITY).ToArray();

                if (limitedMobilityForms.Any())
                {
                    IDbStaticSkillRepository skillsRepo = new EFDbStaticSkillRepository();

                    var formId        = limitedMobilityForms[rand.Next(limitedMobilityForms.Count())].FormSourceId;
                    var immobileSkill = skillsRepo.DbStaticSkills.FirstOrDefault(spell => spell.FormSourceId == formId);

                    if (immobileSkill != null)
                    {
                        SkillProcedures.GiveSkillToPlayer(botId, immobileSkill.Id);
                    }
                }
            }

            // Give bonuses
            EffectProcedures.GivePerkToPlayer(perk, botId);

            if (extraPerk.HasValue)
            {
                EffectProcedures.GivePerkToPlayer(extraPerk.Value, botId);
            }

            // Give runes
            var quantity = rand.Next(1, 3);

            for (var c = 0; c < quantity; c++)
            {
                var runeId = DomainRegistry.Repository.FindSingle(new GetRandomRuneAtLevel {
                    RuneLevel = strength * 2 + 1, Random = rand
                });
                DomainRegistry.Repository.Execute(new GiveRune {
                    ItemSourceId = runeId, PlayerId = botId
                });
            }

            // Balance stats
            var psychoEF = playerRepo.Players.FirstOrDefault(p => p.Id == botId);

            psychoEF.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(psychoEF));
            playerRepo.SavePlayer(psychoEF);

            // Tell the bot to attack the player
            if (!aggro.HasValue || aggro.Value)
            {
                AIDirectiveProcedures.SetAIDirective_Attack(botId, player.Id);
            }

            PlayerLogProcedures.AddPlayerLog(player.Id, $"<b>You have summoned {firstName} {lastName}!</b>  Beware!  They are not friendly!!", true);
            LocationLogProcedures.AddLocationLog(player.dbLocationName, $"{player.GetFullName()} has summoned <b>{firstName} {lastName}</b>!");

            return("Near the counter is an altar with a leather-bound book resting open upon it.  You take a look and try to read one of the jokes aloud.  It seems to be some consonant-heavy tongue twister that soon leaves you faltering.  You're not quite sure what the set up means, but hope the punchline will be worth it.  As you spurt out the last syllable a puff of red smoke explodes out from the book with an audible bang.  You're not laughing, and that remains the case when you close the book to see a large pentagram seared into the cover.  As the smoke subsides there seems to be a strange neon flicker to the light and a crackling to the air.  You turn sharply to see the psychopath you just summoned readying their attack against you!");
        }
Exemple #17
0
        public static void CounterAttack(Player attacker)
        {
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var malethief   = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.MaleRatBotId);
            var femalethief = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.FemaleRatBotId);
            var rand        = new Random(Guid.NewGuid().GetHashCode());

            // both thieves are full, dont' attack too hard
            if (malethief.Mobility == PvPStatics.MobilityFull && femalethief.Mobility == PvPStatics.MobilityFull)
            {
                if (malethief.Mobility == PvPStatics.MobilityFull)
                {
                    AttackProcedures.Attack(malethief, attacker, PvPStatics.Spell_WeakenId);
                    AIProcedures.DealBossDamage(malethief, attacker, true, 1);
                    malethief = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.MaleRatBotId);
                }

                if (femalethief.Mobility == PvPStatics.MobilityFull)
                {
                    AttackProcedures.Attack(femalethief, attacker, GoldenTrophySpellSourceId);
                    AttackProcedures.Attack(femalethief, attacker, GoldenTrophySpellSourceId);
                    AIProcedures.DealBossDamage(femalethief, attacker, true, 2);
                    femalethief = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.FemaleRatBotId);
                }


                var roll = rand.NextDouble();

                // random chance of moving to a new random location
                if (roll < .166)
                {
                    AttackProcedures.Attack(femalethief, attacker, StunSpellSourceId);
                    AIProcedures.DealBossDamage(femalethief, attacker, false, 1);
                    var locationMessage = "<b>" + malethief.GetFullName() + " and " + femalethief.GetFullName() + " ran off in an unknown direction.</b>";
                    LocationLogProcedures.AddLocationLog(femalethief.dbLocationName, locationMessage);
                    var newlocation = LocationsStatics.GetRandomLocation_NoStreets();
                    malethief.dbLocationName   = newlocation;
                    femalethief.dbLocationName = newlocation;
                    playerRepo.SavePlayer(malethief);
                    playerRepo.SavePlayer(femalethief);
                }
            }

            // one thief is defeated, the other goes berserk
            else
            {
                var roll = rand.NextDouble() * 3;
                if (malethief.Mobility == PvPStatics.MobilityFull)
                {
                    for (var i = 0; i < roll; i++)
                    {
                        AttackProcedures.Attack(malethief, attacker, GoldenTrophySpellSourceId);
                        AIProcedures.DealBossDamage(malethief, attacker, false, 2);
                    }
                }
                else if (femalethief.Mobility == PvPStatics.MobilityFull)
                {
                    for (var i = 0; i < roll; i++)
                    {
                        AttackProcedures.Attack(femalethief, attacker, GoldenTrophySpellSourceId);
                        AIProcedures.DealBossDamage(femalethief, attacker, false, 2);
                    }
                }
            }
        }
Exemple #18
0
        public static void RunTurnLogic()
        {
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var boss = playerRepo.Players.FirstOrDefault(f => f.BotId == AIStatics.MotorcycleGangLeaderBotId);

            // motorcycle gang boss is no longer animate; end the event
            if (boss.Mobility != PvPStatics.MobilityFull)
            {
                EndEvent();
                return;
            }

            // Step 1:  Find the most online characters (psychos and players) on the streets and move there.  Move anyone in the biker follower form to her.

            var targetLocation = GetLocationWithMostEligibleTargets();

            targetLocation = String.IsNullOrEmpty(targetLocation) ? boss.dbLocationName : targetLocation;

            var newlocation = AIProcedures.MoveTo(boss, targetLocation, 9);

            boss.dbLocationName = newlocation;
            boss.Mana           = boss.MaxMana;
            playerRepo.SavePlayer(boss);

            var followers = GetFollowers();

            // move all followers to the new location
            foreach (var follower in followers)
            {
                Player followerEF          = playerRepo.Players.First(p => p.Id == follower.Id);
                var    followerNewLocation = AIProcedures.MoveTo(follower, newlocation, 100000);

                // leave location log and penalize some 5 AP
                if (followerEF.dbLocationName != followerNewLocation)
                {
                    var newlocationFriendlyName = LocationsStatics.LocationList.GetLocation
                                                  .First(l => l.dbName == followerNewLocation).Name;

                    LocationLogProcedures.AddLocationLog(followerNewLocation, $"{followerEF.GetFullName()} rode off to <b>{newlocationFriendlyName}</b> to help protect {boss.GetFullName()}.");
                    followerEF.ActionPoints = Math.Max(0, followerEF.ActionPoints - SummonToBossAPPenalty);
                }

                followerEF.dbLocationName = followerNewLocation;

                if (follower.BotId == AIStatics.ActivePlayerBotId)
                {
                    PlayerLogProcedures.AddPlayerLog(follower.Id, $"<b>The leader of your gang, {boss.GetFullName()}, beckons for you to follow!  You have no choice but to comply.</b>", true);
                }
                else if (follower.BotId == AIStatics.PsychopathBotId)
                {
                    followerEF.Health += 25;
                    followerEF.Health  = followerEF.Health > followerEF.MaxHealth ? followerEF.MaxHealth : followerEF.Health;
                    followerEF.LastActionTimestamp = DateTime.UtcNow;
                }
                playerRepo.SavePlayer(followerEF);
            }

            // Step 2:  Give the boss the appropriate effect, determined by how many followers she has.
            EffectProcedures.GivePerkToPlayer(GetPerkSourceIdToGive(followers.Count), boss);

            // Step 3:  Attack everyone in the region 2-3 times with the biker follower spell if they are not already that form.
            var victims = GetEligibleTargetsAtLocation(newlocation);

            // try and turn everyone there into biker gang followers
            foreach (var victim in victims)
            {
                AttackProcedures.Attack(boss, victim, BikerFollowerSpellSourceId);
                AttackProcedures.Attack(boss, victim, BikerFollowerSpellSourceId);
                AttackProcedures.Attack(boss, victim, BikerFollowerSpellSourceId);
            }
        }
        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);
                }
            }
        }
Exemple #20
0
        public static string SummonDoppelganger(Player player, Random rand = null, bool?aggro = null)
        {
            rand = rand ?? new Random();

            IPlayerRepository playerRepo = new EFPlayerRepository();
            var cmd = new CreatePlayer
            {
                FirstName          = $"Evil {player.FirstName}",
                LastName           = player.LastName,
                Location           = player.dbLocationName,
                FormSourceId       = player.FormSourceId,
                Level              = Math.Min(9, player.Level),
                Health             = player.Health,
                MaxHealth          = player.MaxHealth,
                Mana               = player.Mana,
                MaxMana            = player.MaxMana,
                BotId              = AIStatics.PsychopathBotId,
                UnusedLevelUpPerks = 0,
                XP     = 0,
                Money  = 100 + player.Money / 10,
                Gender = player.Gender,
            };

            var botId = DomainRegistry.Repository.Execute(cmd);

            // Give spells
            var eligibleSkills = SkillStatics.GetLearnablePsychopathSkills().ToList();

            SkillProcedures.GiveSkillToPlayer(botId, eligibleSkills[rand.Next(eligibleSkills.Count())].Id);
            SkillProcedures.GiveSkillToPlayer(botId, PvPStatics.Spell_WeakenId);

            // Give bonuses - we exclude some with no stats, with side effects, or that serve no purpose on psychos
            var sourcePerks = EffectProcedures.GetPlayerEffects2(player.Id);

            int[] effectsToExclude = { JokeShopProcedures.FIRST_WARNING_EFFECT,
                                       JokeShopProcedures.SECOND_WARNING_EFFECT,
                                       JokeShopProcedures.BANNED_FROM_JOKE_SHOP_EFFECT,
                                       JokeShopProcedures.INVISIBILITY_EFFECT,  // Ensure twin is visible, even if player can't yet attack
                                       JokeShopProcedures.PSYCHOTIC_EFFECT,     // Prevent psycho twin leaving rehab  (Sorry, Pinocchio)
                                       JokeShopProcedures.INSTINCT_EFFECT,      // Should be safe, but just to be on the safe side
                                       JokeShopProcedures.AUTO_RESTORE_EFFECT,  // No free second chances for twins, bad ends are forever
            };

            foreach (var sourcePerk in sourcePerks)
            {
                var effect = sourcePerk.dbEffect;
                if (!effectsToExclude.Contains(effect.EffectSourceId) && effect.Duration > 0)
                {
                    EffectProcedures.GivePerkToPlayer(effect.EffectSourceId, botId, effect.Duration, effect.Cooldown);
                }
            }

            // Approximately mirror the buffs the player gets from their items.
            // (Actually equipping equivalent items and runes could easily be abused so use perks)
            var itemBuffs = ItemProcedures.GetPlayerBuffs(player).ItemBuffs();

            itemBuffs += 30;  // level 1 psycho effect gives -30 stats
            if (itemBuffs >= 315)
            {
                itemBuffs -= 315;
                EffectProcedures.GivePerkToPlayer(AIProcedures.PsychopathicForLevelNineEffectSourceId, botId);
            }
            if (itemBuffs >= 225)
            {
                itemBuffs -= 225;
                EffectProcedures.GivePerkToPlayer(AIProcedures.PsychopathicForLevelSevenEffectSourceId, botId);
            }
            if (itemBuffs >= 135)
            {
                itemBuffs -= 135;
                EffectProcedures.GivePerkToPlayer(AIProcedures.PsychopathicForLevelFiveEffectSourceId, botId);
            }
            if (itemBuffs >= 70)
            {
                itemBuffs -= 70;
                EffectProcedures.GivePerkToPlayer(AIProcedures.PsychopathicForLevelThreeEffectSourceId, botId);
            }
            if (itemBuffs < 30)
            {
                itemBuffs += 30;
                EffectProcedures.GivePerkToPlayer(AIProcedures.PsychopathicForLevelOneEffectSourceId, botId);
            }

            // Give runes (round level down to odd)
            var runeLevel = cmd.Level - 1;

            runeLevel = runeLevel - (runeLevel % 2) + 1;
            var quantity = rand.Next(1, 3);

            for (var c = 0; c < quantity; c++)
            {
                var runeId = DomainRegistry.Repository.FindSingle(new GetRandomRuneAtLevel {
                    RuneLevel = runeLevel, Random = rand
                });
                DomainRegistry.Repository.Execute(new GiveRune {
                    ItemSourceId = runeId, PlayerId = botId
                });
            }

            // Balance stats
            var psychoEF = playerRepo.Players.FirstOrDefault(p => p.Id == botId);

            psychoEF.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(psychoEF));
            playerRepo.SavePlayer(psychoEF);

            // Tell the bot to attack the player
            if (!aggro.HasValue || aggro.Value)
            {
                AIDirectiveProcedures.SetAIDirective_Attack(botId, player.Id);
            }

            PlayerLogProcedures.AddPlayerLog(player.Id, $"<b>You have summoned your evil twin!</b>  Beware!  They are not friendly!", true);
            LocationLogProcedures.AddLocationLog(player.dbLocationName, $"{player.GetFullName()} has summoned their evil twin!");

            return("In the corner of the room is a freestanding mirror with a silver gilt frame.  You smear some of the dust off the glass to see your reflection staring back at you through the clearing in the misty haze.  As you look into it you catch sight of yourself twitching slightly, but you don't actually feel anything.  Then your reflection narrows their gaze into a scowl and steps through the rippling glazed portal, bringing you face-to-face with your mirror self!  You should be careful.  Meeting your doppelganger never ends well..");
        }
Exemple #21
0
        public virtual ActionResult StripVictim(int id)
        {
            var myMembershipId = User.Identity.GetUserId();
            var me             = PlayerProcedures.GetPlayerFromMembership(myMembershipId);
            var victim         = PlayerProcedures.GetPlayer(id);

            // run generic MC checks
            var errorsBox = MindControlProcedures.AssertBasicMindControlConditions(me, victim, MindControlStatics.MindControl__StripFormSourceId);

            if (errorsBox.HasError)
            {
                TempData["Error"]    = errorsBox.Error;
                TempData["SubError"] = errorsBox.SubError;
                return(RedirectToAction(MVC.MindControl.MindControlList()));
            }

            var victimItems = ItemProcedures.GetAllPlayerItems(victim.Id).ToList();

            if (victimItems.Any())
            {
                double max  = victimItems.Count();
                var    rand = new Random();
                var    num  = rand.NextDouble();

                var index      = Convert.ToInt32(Math.Floor(num * max));
                var itemToDrop = victimItems.ElementAt(index);

                MindControlProcedures.AddCommandUsedToMindControl(me, victim, MindControlStatics.MindControl__StripFormSourceId);

                var attackerMessage = "";

                if (itemToDrop.Item.ItemType != PvPStatics.ItemType_Pet)
                {
                    attackerMessage = "You commanded " + victim.GetFullName() + " to drop something.  They let go of a " + itemToDrop.Item.FriendlyName + " that they were carrying.";
                }
                else
                {
                    attackerMessage = "You commanded " + victim.GetFullName() + " to drop something.  They released their pet " + itemToDrop.Item.FriendlyName + " that they had tamed.";
                }

                PlayerLogProcedures.AddPlayerLog(me.Id, attackerMessage, false);
                TempData["Result"] = attackerMessage;

                var victimMessage = "";

                if (itemToDrop.Item.ItemType != PvPStatics.ItemType_Pet)
                {
                    victimMessage = me.GetFullName() + " commanded you to to drop something. You had no choice but to go of a " + itemToDrop.Item.FriendlyName + " that you were carrying.";
                }
                else
                {
                    victimMessage = me.GetFullName() + " commanded you to drop something. You had no choice but to release your pet " + itemToDrop.Item.FriendlyName + " that you had tamed.";
                }

                PlayerLogProcedures.AddPlayerLog(victim.Id, victimMessage, true);

                ItemProcedures.DropItem(itemToDrop.dbItem.Id);

                var locationLogMessage = victim.GetFullName() + " was forced to drop their <b>" + itemToDrop.Item.FriendlyName + "</b> by someone mind controlling them.";
                LocationLogProcedures.AddLocationLog(victim.dbLocationName, locationLogMessage);

                StatsProcedures.AddStat(me.MembershipId, StatsProcedures.Stat__MindControlCommandsIssued, 1);
            }
            else
            {
                TempData["Error"] = "It seems " + victim.GetFullName() + " was not carrying or wearing anything to drop!";
            }

            return(RedirectToAction(MVC.PvP.Play()));
        }
        public static string WanderAimlessly(Player player, Random rand = null)
        {
            if (player.InDuel > 0 || player.InQuest > 0 || player.MindControlIsActive || player.MoveActionPointDiscount < -TurnTimesStatics.GetActionPointReserveLimit())
            {
                return(null);
            }

            if (ItemProcedures.GetAllPlayerItems(player.Id).Count(i => !i.dbItem.IsEquipped) > PvPStatics.MaxCarryableItemCountBase + player.ExtraInventory)
            {
                // Carryiing too much
                return(null);
            }

            rand = rand ?? new Random();

            IPlayerRepository playerRepo = new EFPlayerRepository();
            var target = playerRepo.Players.FirstOrDefault(p => p.Id == player.Id);
            var name   = target.GetFullName();

            var costPerTile  = Math.Max(0, 1 - target.MoveActionPointDiscount);
            var maxDistance  = (costPerTile == 0) ? 200 : Math.Floor(target.ActionPoints / costPerTile);
            var spacesToMove = (int)Math.Min(maxDistance, rand.Next(10, 16));

            string nextTileId = player.dbLocationName;
            var    nextTile   = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == nextTileId);

            for (var i = spacesToMove; i > 0; i--)
            {
                var currentTile = nextTile;

                switch (rand.Next(4))
                {
                case 0:
                    nextTileId = currentTile.Name_North ?? currentTile.Name_South ?? currentTile.Name_East ?? currentTile.Name_West;
                    break;

                case 1:
                    nextTileId = currentTile.Name_South ?? currentTile.Name_East ?? currentTile.Name_West ?? currentTile.Name_North;
                    break;

                case 2:
                    nextTileId = currentTile.Name_East ?? currentTile.Name_West ?? currentTile.Name_North ?? currentTile.Name_South;
                    break;

                case 3:
                    nextTileId = currentTile.Name_West ?? currentTile.Name_North ?? currentTile.Name_South ?? currentTile.Name_East;
                    break;
                }

                nextTile = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == nextTileId);

                LocationLogProcedures.AddLocationLog(currentTile.dbName, name + " left toward " + nextTile.Name);
                LocationLogProcedures.AddLocationLog(nextTileId, name + " entered from " + currentTile.Name);
            }

            target.ActionPoints  -= spacesToMove * costPerTile;
            target.dbLocationName = nextTileId;
            playerRepo.SavePlayer(target);

            return("The room starts to shake.  A waving cat on a nearby display rattles, edging forward before falling off the shelf and smashing to the ground.  The structure of the room creaks as the ceiling contorts.  All the clown faces seem to be staring at you.  Suddenly this feels a very unsettling place.  You get a bad feeling that something is about to happen to this sinister and claustrophobic shop.  There's only one thing for it:  You race out the door and run.  It doesn't matter which direction you go in, just so long as you get out of here!");
        }
        private static (IEnumerable <InstinctData> mcPlayers, IEnumerable <InstinctData> freePlayers) DogActions(IPlayerRepository playerRepo, IEnumerable <InstinctData> mcPlayers, IEnumerable <InstinctData> freePlayers, Random rand)
        {
            // Dogs - chase cats, possiby up a tree
            var mcDogs = mcPlayers.Where(p => JokeShopProcedures.DOGS.Any(dogForm => p.FormSourceId == dogForm)).ToList();

            if (!mcDogs.IsEmpty())
            {
                var mcCats   = mcPlayers.Where(p => JokeShopProcedures.CATS_AND_NEKOS.Any(catForm => p.FormSourceId == catForm)).ToList();
                var freeCats = freePlayers.Where(p => JokeShopProcedures.CATS_AND_NEKOS.Any(catForm => p.FormSourceId == catForm)).ToList();

                while (!mcDogs.IsEmpty() && mcCats.Count() + freeCats.Count() > 0)
                {
                    // Find a dog
                    var dogIndex = rand.Next(mcDogs.Count());
                    var dog      = mcDogs[dogIndex];
                    mcDogs.RemoveAt(dogIndex);
                    mcPlayers = mcPlayers.Where(p => p.Id != dog.Id);

                    int    catId;
                    string catLoc;
                    bool   catIsMindControlled;

                    // Find a cat for them to chase
                    if (!mcCats.IsEmpty())
                    {
                        var catIndex = rand.Next(mcCats.Count());
                        var cat      = mcCats[catIndex];
                        mcCats.RemoveAt(catIndex);

                        catId  = cat.Id;
                        catLoc = cat.dbLocationName;
                        catIsMindControlled = true;
                        mcPlayers           = mcPlayers.Where(p => p.Id != catId);
                    }
                    else  // !freeCats.IsEmpty()
                    {
                        var catIndex = rand.Next(freeCats.Count);
                        var cat      = freeCats[catIndex];
                        freeCats.RemoveAt(catIndex);

                        catId  = cat.Id;
                        catLoc = cat.dbLocationName;
                        catIsMindControlled = false;
                        freePlayers         = freePlayers.Where(p => p.Id != catId);
                    }

                    var dogPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == dog.Id);
                    var catPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == catId);

                    // Move dog
                    var stoppedAt = EnvironmentPrankProcedures.MovePlayer(dogPlayer, catLoc, 15, timestamp: false, callback: (p, loc) =>
                    {
                        var roll = rand.Next(4);
                        if (roll == 0)
                        {
                            LocationLogProcedures.AddLocationLog(loc, $"{dogPlayer.GetFullName()} barked here as they catch the scent of a cat, {catPlayer.GetFullName()}:  <b>Woof woof!</b>");
                        }
                        else if (roll == 1)
                        {
                            LocationLogProcedures.AddLocationLog(loc, $"{dogPlayer.GetFullName()} growled here as they get closer to {catPlayer.GetFullName()}, the cat:  <b>Grrrrrrrrr!</b>");
                        }
                    });

                    // Dog has arrived at the cat's location
                    if (stoppedAt == catLoc)
                    {
                        var here = LocationsStatics.GetConnectionName(stoppedAt);
                        LocationLogProcedures.AddLocationLog(stoppedAt, $"{dogPlayer.GetFullName()} barked at {catPlayer.GetFullName()}:  <b>Woof woof!</b>");

                        // If cat is mind controlled we can send them up a tree
                        if (catIsMindControlled)
                        {
                            var treeLoc = mcPlayers.FirstOrDefault(p => JokeShopProcedures.TREES.Any(treeForm => p.FormSourceId == treeForm))?.dbLocationName;

                            if (treeLoc == null)
                            {
                                treeLoc = freePlayers.FirstOrDefault(p => JokeShopProcedures.TREES.Any(treeForm => p.FormSourceId == treeForm))?.dbLocationName;
                            }

                            if (treeLoc == null)
                            {
                                treeLoc = "forest_ancestor_tree";
                            }

                            var catStoppedAt = EnvironmentPrankProcedures.MovePlayer(catPlayer, treeLoc, 15, timestamp: false, callback: (p, loc) =>
                            {
                                var roll = rand.Next(3);
                                if (roll == 0)
                                {
                                    LocationLogProcedures.AddLocationLog(loc, $"<b>Meoooww!</b> yowls {catPlayer.GetFullName()} as they quickly flee from {dogPlayer.GetFullName()}, the dog who is chasing them.");
                                }
                            });

                            if (catStoppedAt == treeLoc)
                            {
                                LocationLogProcedures.AddLocationLog(catLoc, $"{catPlayer.GetFullName()} runs to hide from {dogPlayer.GetFullName()}!");
                                LocationLogProcedures.AddLocationLog(treeLoc, $"{catPlayer.GetFullName()} leaps into a tree to hide from {dogPlayer.GetFullName()}, the dog who is chasing them.");
                                PlayerLogProcedures.AddPlayerLog(catId, $"<b>Woof woof!</b>  {dogPlayer.GetFullName()} barks at you, and you run off to the nearest tree!", true);
                                PlayerLogProcedures.AddPlayerLog(dogPlayer.Id, $"You chased a cat to <b>{here}</b> and started barking at {catPlayer.GetFullName()}:  <b>Woof woof!</b>.  They run off to the nearest tree to hide from you!", true);
                            }
                            else if (catStoppedAt == null)
                            {
                                PlayerLogProcedures.AddPlayerLog(catId, $"<b>Woof woof!</b>  {dogPlayer.GetFullName()} barks at you, but you can't seem to escape!", true);
                                PlayerLogProcedures.AddPlayerLog(dogPlayer.Id, $"You chased a cat to <b>{here}</b> and started barking at {catPlayer.GetFullName()}:  <b>Woof woof!</b>.", true);
                            }
                            else
                            {
                                LocationLogProcedures.AddLocationLog(catLoc, $"{catPlayer.GetFullName()} runs to hide from {dogPlayer.GetFullName()}!");
                                PlayerLogProcedures.AddPlayerLog(catId, $"<b>Woof woof!</b>  {dogPlayer.GetFullName()} barks at you, and you run away to try and hide!", true);
                                PlayerLogProcedures.AddPlayerLog(dogPlayer.Id, $"You chased a cat to <b>{here}</b> and started barking at {catPlayer.GetFullName()}:  <b>Woof woof!</b>.  They run off to try and hide from you!", true);
                            }
                        }
                        else  // Cat not mind controlled, dog can only bark
                        {
                            PlayerLogProcedures.AddPlayerLog(catId, $"{dogPlayer.GetFullName()} barked at you:  <b>Woof woof!</b>", true);
                            PlayerLogProcedures.AddPlayerLog(dogPlayer.Id, $"You chased a cat to <b>{here}</b> and started barking at {catPlayer.GetFullName()}:  <b>Woof woof!</b>", true);
                        }
                    }
                    else if (stoppedAt != null)  // Dog moved, but didn't get to the cat's location
                    {
                        var here = LocationsStatics.GetConnectionName(stoppedAt);
                        PlayerLogProcedures.AddPlayerLog(dogPlayer.Id, $"You caught scent of a cat and ran to <b>{here}</b>", true);
                    }
                    else if (dog.dbLocationName == catLoc)
                    {
                        PlayerLogProcedures.AddPlayerLog(catId, $"{dogPlayer.GetFullName()} barked at you:  <b>Woof woof!</b>", true);
                        PlayerLogProcedures.AddPlayerLog(dogPlayer.Id, $"You barked at {catPlayer.GetFullName()}:  <b>Woof woof!</b>", true);
                    }
                }
            }

            return(mcPlayers, freePlayers);
        }
Exemple #24
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
        }
        public virtual ActionResult StartQuest(int Id)
        {
            var myMembershipId = User.Identity.GetUserId();

            if (PvPStatics.AnimateUpdateInProgress)
            {
                TempData["Error"]    = "Player update portion of the world update is still in progress.";
                TempData["SubError"] = "Try again a bit later when the update has progressed farther along.";
                return(RedirectToAction(MVC.PvP.Play()));
            }

            var me = PlayerProcedures.GetPlayerFromMembership(myMembershipId);

            // assert player is in an okay form to do this
            if (me.Mobility != PvPStatics.MobilityFull)
            {
                TempData["Error"] = "You must be animate in order to begin a quest.";
                return(RedirectToAction(MVC.PvP.Play()));
            }

            // assert that this player is not in a duel
            if (me.InDuel > 0)
            {
                TempData["Error"] = "You must finish your duel before you begin a quest.";
                return(RedirectToAction(MVC.PvP.Play()));
            }

            // assert that this player is not in a quest
            if (me.InQuest > 0)
            {
                TempData["Error"] = "You must finish your current quest before you start another.";
                return(RedirectToAction(MVC.PvP.Play()));
            }

            // assert player has not been in combat recently
            var lastAttackTimeAgo = Math.Abs(Math.Floor(me.GetLastCombatTimestamp().Subtract(DateTime.UtcNow).TotalMinutes));

            if (lastAttackTimeAgo < TurnTimesStatics.GetMinutesSinceLastCombatBeforeQuestingOrDuelling())
            {
                TempData["Error"]    = "You have been in combat too recently in order to begin this quest.";
                TempData["SubError"] = "You must stay out of combat for another " + (TurnTimesStatics.GetMinutesSinceLastCombatBeforeQuestingOrDuelling() - lastAttackTimeAgo) + " minutes.";
                return(RedirectToAction(MVC.PvP.Play()));
            }

            var questStart = QuestProcedures.GetQuest(Id);

            // assert player is in the correct place
            if (me.dbLocationName != questStart.Location)
            {
                TempData["Error"] = "You are not in the correct location to begin this quest.";
                return(RedirectToAction(MVC.PvP.Play()));
            }

            var gameTurnNum = PvPWorldStatProcedures.GetWorldTurnNumber();

            // assert player did not fail or abandon this quest too soon ago
            var lastTurnAttempted = QuestProcedures.GetLastTurnQuestEnded(me, questStart.Id);

            if (PvPWorldStatProcedures.GetWorldTurnNumber() - lastTurnAttempted < QuestStatics.QuestFailCooldownTurnLength)
            {
                TempData["Error"]    = "You recently failed or abandoned this quest.";
                TempData["SubError"] = "You must wait another " + (QuestStatics.QuestFailCooldownTurnLength - (gameTurnNum - lastTurnAttempted)) + " turns before you can attempt this quest again.";
                return(RedirectToAction(MVC.PvP.Play()));
            }

            var questPlayerStatuses = QuestProcedures.GetQuestPlayerStatuses(me);

            var canStartQuest = QuestProcedures.PlayerCanBeginQuest(me, questStart, questPlayerStatuses, gameTurnNum);

            // assert player meets level / game turn requirements for this quest
            if (!canStartQuest)
            {
                TempData["Error"] = "You do not meet all of the criteria to begin this quest.";
                return(RedirectToAction(MVC.PvP.Play()));
            }

            // all checks have passed; start the player on this quest
            QuestProcedures.PlayerBeginQuest(me, questStart);
            LocationLogProcedures.AddLocationLog(me.dbLocationName, "<span class='playerMediatingNotification'><b>" + me.GetFullName() + "</b> began the quest <b>" + questStart.Name + "</b> here.</span>");

            TempData["Result"] = "You started the quest " + questStart.Name + ".";
            return(RedirectToAction(MVC.Quest.Questing()));
        }