예제 #1
0
        public static void SendCovenantMoneyToPlayer(int covId, Player giftee, decimal amount)
        {
            ICovenantRepository covRepo    = new EFCovenantRepository();
            IPlayerRepository   playerRepo = new EFPlayerRepository();
            var dbCov    = covRepo.Covenants.FirstOrDefault(c => c.Id == covId);
            var dbPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == giftee.Id);

            dbCov.Money -= amount;

            // taxes...
            amount *= .95M;
            amount  = Math.Floor(amount);

            if (dbPlayer.Money + amount > PvPStatics.MaxMoney)
            {
                dbPlayer.Money = PvPStatics.MaxMoney;
            }
            else
            {
                dbPlayer.Money += amount;
            }

            playerRepo.SavePlayer(dbPlayer);
            covRepo.SaveCovenant(dbCov);

            var covMessage = (int)amount + " Arpeyjis were gifted out to " + giftee.GetFullName() + " from the covenant treasury.";

            WriteCovenantLog(covMessage, covId, false);
        }
예제 #2
0
        public static bool CovenantHasSafeground(int covenantId)
        {
            ICovenantRepository repo = new EFCovenantRepository();
            var cov = repo.Covenants.FirstOrDefault(c => c.Id == covenantId);

            return(CovenantHasSafeground(cov));
        }
예제 #3
0
        public static bool ACovenantHasASafegroundHere(string location)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var covenantsBasedHere      = covRepo.Covenants.Count(c => c.HomeLocation == location);

            return(covenantsBasedHere > 0);
        }
예제 #4
0
        public static void SetLastMemberJoinTimestamp(Covenant covenant)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var dbCov = covRepo.Covenants.FirstOrDefault(c => c.Id == covenant.Id);

            dbCov.LastMemberAcceptance = DateTime.UtcNow;
            covRepo.SaveCovenant(dbCov);
        }
예제 #5
0
        public static void ChangeNoticeboardMessage(int covId, string newMessage)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var oldcov = covRepo.Covenants.FirstOrDefault(c => c.Id == covId);

            oldcov.NoticeboardMessage = newMessage;
            covRepo.SaveCovenant(oldcov);
        }
예제 #6
0
        public static void UpdateCovenantDescription(int covId, string newDescription, string flagUrl)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var oldcov = covRepo.Covenants.FirstOrDefault(c => c.Id == covId);

            oldcov.SelfDescription = newDescription;
            oldcov.FlagUrl         = flagUrl;
            covRepo.SaveCovenant(oldcov);
        }
예제 #7
0
        public static bool CovenantOfNameExists(string name)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var possible = covRepo.Covenants.FirstOrDefault(c => c.Name == name);

            if (possible != null)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #8
0
        public static bool FlagIsInUse(string flagURL)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var covWithFlag             = covRepo.Covenants.FirstOrDefault(c => c.FlagUrl == flagURL);

            if (covWithFlag != null)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #9
0
        public static string ChangeCovenantLeader(Covenant covenant, Player player)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var dbCovenant = covRepo.Covenants.FirstOrDefault(i => i.Id == covenant.Id);

            if (dbCovenant == null)
            {
                return("Covenant could not be found.");
            }

            dbCovenant.LeaderId = player.Id;
            covRepo.SaveCovenant(dbCovenant);
            WriteCovenantLog(player.GetFullName() + " is now the leader of the covenant.", covenant.Id, true);
            return(player.GetFullName() + " is now the leader of the covenant.");
        }
예제 #10
0
        public static IEnumerable <CovenantListItemViewModel> GetCovenantsList()
        {
            IPlayerRepository   playerRepo = new EFPlayerRepository();
            ICovenantRepository covRepo    = new EFCovenantRepository();

            var dbCovenants = covRepo.Covenants.Where(c => c.Id > 0).ToList();

            return(dbCovenants.Select(c => new CovenantListItemViewModel
            {
                dbCovenant = c,
                MemberCount =
                    playerRepo.Players.Count(p => p.Covenant == c.Id && p.BotId == AIStatics.ActivePlayerBotId),
                Leader = playerRepo.Players.FirstOrDefault(p => p.Id == c.LeaderId)
            }).ToList());
        }
예제 #11
0
        public static List <string> FilterAvailableFlags(List <string> input)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var usedFlags = covRepo.Covenants.Select(c => c.FlagUrl).ToList();

            var output = new List <string>();

            foreach (var s in input)
            {
                if (!usedFlags.Contains(s))
                {
                    output.Add(s);
                }
            }
            return(output);
        }
예제 #12
0
        public static CovenantViewModel GetCovenantViewModel(int id)
        {
            ICovenantRepository covRepo    = new EFCovenantRepository();
            IPlayerRepository   playerRepo = new EFPlayerRepository();

            var output = new CovenantViewModel();

            output.dbCovenant = covRepo.Covenants.FirstOrDefault(c => c.Id == id);

            var playerFormList = PlayerProcedures.GetPlayerFormViewModelsInCovenant(id);

            output.Leader = playerRepo.Players.FirstOrDefault(p => p.Id == output.dbCovenant.LeaderId);

            output.Members = playerFormList;


            return(output);
        }
예제 #13
0
        public static void SetCovenantSafeground(Covenant covenant, string location)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var dbCovenant = covRepo.Covenants.FirstOrDefault(i => i.Id == covenant.Id);

            dbCovenant.HomeLocation = location;
            dbCovenant.Money       -= 2500;
            dbCovenant.Level        = 1;
            covRepo.SaveCovenant(dbCovenant);
            LoadCovenantDictionary();

            var covMessage =
                $"Covenant safeground was establish at {LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == location)?.Name ?? "unknown"}.";

            WriteCovenantLog(covMessage, covenant.Id, true);

            AttackProcedures.InstantTakeoverLocation(dbCovenant, location);
        }
예제 #14
0
        public static string StartNewCovenant(Covenant newcov)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var dbCov = new Covenant();

            //  dbCov.IsPvP = newcov.IsPvP;
            dbCov.IsPvP   = false;
            dbCov.FlagUrl = newcov.FlagUrl;
            dbCov.LastMemberAcceptance = DateTime.UtcNow;
            dbCov.Name            = newcov.Name;
            dbCov.SelfDescription = newcov.SelfDescription;
            dbCov.LeaderId        = newcov.LeaderId;
            dbCov.Captains        = "";

            covRepo.SaveCovenant(dbCov);

            return("");
        }
예제 #15
0
        public static string ChangeCovenantCaptain(Covenant covenant, Player player, bool removeOnly = false)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var dbCovenant = covRepo.Covenants.FirstOrDefault(i => i.Id == covenant.Id);

            if (dbCovenant == null)
            {
                return("Covenant could not be found.");
            }

            var playerIdString = player.Id + ";";

            // if the captains is null, change it to have an empty string to prevent null exceptions
            if (dbCovenant.Captains == null)
            {
                dbCovenant.Captains = "";
                covRepo.SaveCovenant(dbCovenant);
            }

            var isACaptain = dbCovenant.Captains.Contains(playerIdString);

            if (isACaptain && removeOnly)
            {
                dbCovenant.Captains = dbCovenant.Captains.Replace(playerIdString, "");
                covRepo.SaveCovenant(dbCovenant);
                WriteCovenantLog(player.GetFullName() + " is no longer a captain of the covenant.", covenant.Id, true);
                return(player.GetFullName() + " is no longer a captain of the covenant.");
            }

            if (isACaptain)
            {
                return($"{player.GetFullName()} is already a captain.");
            }

            if (removeOnly)
            {
                return($"{player.GetFullName()} can't be removed as a captain because they are not one currently.");
            }

            dbCovenant.Captains += playerIdString;
            covRepo.SaveCovenant(dbCovenant);
            WriteCovenantLog(player.GetFullName() + " is now a captain of the covenant.", covenant.Id, true);
            return(player.GetFullName() + " is now a captain of the covenant.");
        }
예제 #16
0
        public static void LoadCovenantDictionary()
        {
            ICovenantRepository covRepo = new EFCovenantRepository();

            CovenantDictionary.IdNameFlagLookup.Clear();


            foreach (var c in covRepo.Covenants.Where(c => c.LeaderId > -1))
            {
                var temp = new CovenantNameFlag
                {
                    FlagUrl      = c.FlagUrl,
                    Name         = c.Name,
                    HomeLocation = c.HomeLocation,
                    CovLevel     = c.Level,
                };
                CovenantDictionary.IdNameFlagLookup.Add(c.Id, temp);
            }
        }
예제 #17
0
        public static void RemovePlayerFromCovenant(Player player)
        {
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var dbPlayer = playerRepo.Players.First(p => p.Id == player.Id);

            dbPlayer.Covenant = null;
            playerRepo.SavePlayer(dbPlayer);

            // delete the covenant if it is now empty
            ICovenantRepository covRepo = new EFCovenantRepository();
            var possible = covRepo.Covenants.FirstOrDefault(c => c.Id == player.Covenant);

            var covMemberCount = GetPlayerCountInCovenant(possible, false);

            if (covMemberCount == 0)
            {
                covRepo.DeleteCovenant(possible.Id);
            }

            // the covenant is not empty, so we need to give it a new leader.  For now the new leader is essentially random.
            else if (possible.LeaderId == player.Id)
            {
                var nextleader = playerRepo.Players.FirstOrDefault(p => p.Covenant == possible.Id);
                possible.LeaderId = nextleader.Id;
                covRepo.SaveCovenant(possible);
            }

            // remove the player from the covenant captain list if they are on it.  Catch null because covenant may have been deleted.
            try
            {
                ChangeCovenantCaptain(possible, dbPlayer, true);
            }
            catch
            {
            }

            LoadCovenantDictionary();

            var covMessage = player.GetFullName() + " is no longer a member of the covenant.";

            WriteCovenantLog(covMessage, possible.Id, true);
        }
예제 #18
0
        public static void UpgradeCovenant(Covenant covenant)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();
            var dbCovenant = covRepo.Covenants.FirstOrDefault(i => i.Id == covenant.Id);

            dbCovenant.Money -= GetUpgradeCost(covenant);
            dbCovenant.Level++;

            covRepo.SaveCovenant(dbCovenant);
            ICovenantLogRepository covLogRepo = new EFCovenantLogRepository();
            var newlog = new CovenantLog
            {
                CovenantId  = covenant.Id,
                IsImportant = true,
                Message     = "The covenant leader has upgraded the covenant safeground to level " + (covenant.Level + 1) + ", allowing it to hold more furniture.",
                Timestamp   = DateTime.UtcNow,
            };

            covLogRepo.SaveCovenantLog(newlog);
        }
예제 #19
0
        public static void GiveFurnitureToCovenant(Furniture furniture, Covenant covenant)
        {
            IFurnitureRepository furnRepo = new EFFurnitureRepository();
            ICovenantRepository  covRepo  = new EFCovenantRepository();

            var dbCovenant  = covRepo.Covenants.FirstOrDefault(c => c.Id == covenant.Id);
            var dbFurniture = furnRepo.Furnitures.First(f => f.Id == furniture.Id);

            dbCovenant.Money      -= furniture.Price;
            dbFurniture.CovenantId = covenant.Id;

            // update the contract begin/end dates for this furniture
            dbFurniture.ContractStartTurn = PvPWorldStatProcedures.GetWorldTurnNumber();
            dbFurniture.ContractEndTurn   = dbFurniture.ContractStartTurn + dbFurniture.ContractTurnDuration;

            covRepo.SaveCovenant(dbCovenant);
            furnRepo.SaveFurniture(dbFurniture);

            var message = "The leader of the covenant has purchased the furniture contract for " + dbFurniture.HumanName + ".";

            CovenantProcedures.WriteCovenantLog(message, covenant.Id, true);
        }
예제 #20
0
        public static void SendPlayerMoneyToCovenant(Player player, decimal amount)
        {
            ICovenantRepository covRepo    = new EFCovenantRepository();
            IPlayerRepository   playerRepo = new EFPlayerRepository();
            var dbCov    = covRepo.Covenants.FirstOrDefault(c => c.Id == player.Covenant);
            var dbPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == player.Id);

            // reducing the money transfer amount to prevent the covenant money going over the limit
            if (dbCov.Money + amount > PvPStatics.MaxMoney)
            {
                amount = PvPStatics.MaxMoney - dbCov.Money;
            }

            dbPlayer.Money -= amount;

            dbCov.Money += amount;
            playerRepo.SavePlayer(dbPlayer);
            covRepo.SaveCovenant(dbCov);

            var covMessage = player.GetFullName() + " donated " + (int)amount + " Arpeyjis to the covenant treasury.";

            WriteCovenantLog(covMessage, dbCov.Id, false);
        }
예제 #21
0
        public static void UpdateWorld()
        {
            var worldStats = DomainRegistry.Repository.FindSingle(new GetWorld());

            var turnNo = worldStats.TurnNumber;

            PvPStatics.LastGameTurn = turnNo;

            if (turnNo < PvPStatics.RoundDuration)
            {
                PvPStatics.AnimateUpdateInProgress = true;

                IServerLogRepository serverLogRepo = new EFServerLogRepository();
                var log = new ServerLog
                {
                    TurnNumber      = turnNo,
                    StartTimestamp  = DateTime.UtcNow,
                    FinishTimestamp = DateTime.UtcNow,
                    Errors          = 0,
                    FullLog         = "",
                    Population      = PlayerProcedures.GetWorldPlayerStats().CurrentOnlinePlayers,
                };
                log.AddLog($"Started new log for turn {turnNo} at <b>{DateTime.UtcNow}</b>.");
                serverLogRepo.SaveServerLog(log);
                var updateTimer = new Stopwatch();
                updateTimer.Start();

                IPlayerRepository playerRepo = new EFPlayerRepository();

                Player lindella = playerRepo.Players.FirstOrDefault(p => p.BotId == AIStatics.LindellaBotId);
                Player wuffie   = playerRepo.Players.FirstOrDefault(p => p.BotId == AIStatics.WuffieBotId);

                #region spawn NPCS
                // make sure the NPCs have been spawned early turn
                if (turnNo <= 3)
                {
                    if (lindella == null)
                    {
                        BossProcedures_Lindella.SpawnLindella();
                        lindella = playerRepo.Players.FirstOrDefault(p => p.BotId == AIStatics.LindellaBotId);
                    }

                    if (wuffie == null)
                    {
                        BossProcedures_PetMerchant.SpawnPetMerchant();
                        wuffie = playerRepo.Players.FirstOrDefault(p => p.BotId == AIStatics.WuffieBotId);
                    }

                    var fae = playerRepo.Players.FirstOrDefault(p => p.BotId == AIStatics.JewdewfaeBotId);
                    if (fae == null)
                    {
                        BossProcedures_Jewdewfae.SpawnFae();
                    }

                    var bartender = playerRepo.Players.FirstOrDefault(p => p.BotId == AIStatics.BartenderBotId);
                    if (bartender == null)
                    {
                        BossProcedures_Bartender.SpawnBartender();
                    }

                    var lorekeeper = playerRepo.Players.FirstOrDefault(p => p.BotId == AIStatics.LoremasterBotId);
                    if (lorekeeper == null)
                    {
                        BossProcedures_Loremaster.SpawnLoremaster();
                    }

                    var soulbinder = playerRepo.Players.FirstOrDefault(p => p.BotId == AIStatics.SoulbinderBotId);
                    if (soulbinder == null)
                    {
                        var id = DomainRegistry.Repository.Execute(new CreatePlayer
                        {
                            FirstName               = "Karin",
                            LastName                = "Kezesul-Adriz the Soulbinder",
                            FormSourceId            = 1000,
                            Location                = "stripclub_office",
                            Level                   = 10,
                            Mobility                = PvPStatics.MobilityFull,
                            Money                   = 0,
                            Gender                  = PvPStatics.GenderFemale,
                            Health                  = 9999,
                            MaxHealth               = 9999,
                            Mana                    = 9999,
                            MaxMana                 = 9999,
                            OnlineActivityTimestamp = DateTime.UtcNow,
                            BotId                   = AIStatics.SoulbinderBotId
                        });

                        var newSoulbinder = playerRepo.Players.FirstOrDefault(p => p.Id == id);
                        newSoulbinder.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(newSoulbinder));
                        playerRepo.SavePlayer(newSoulbinder);
                    }
                }
                #endregion

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started loading animate players");

                IEffectRepository effectRepo = new EFEffectRepository();

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started loading effects");
                var temporaryEffects = effectRepo.Effects.Where(e => !e.IsPermanent).ToList();
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished loading effects");
                var effectsToDelete = new List <Effect>();

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started updating effects");
                var effectsExpiringThisTurn = temporaryEffects.Where(e => e.Duration == 1).ToList();
                var activeOrExpiringEffects = temporaryEffects.Where(e => e.Duration > 0).ToList();

                foreach (var e in temporaryEffects)
                {
                    e.Duration--;
                    e.Cooldown--;

                    if (e.Duration < 0)
                    {
                        e.Duration = 0;
                    }

                    if (e.Cooldown <= 0)
                    {
                        effectsToDelete.Add(e);
                    }
                    else
                    {
                        effectRepo.SaveEffect(e);
                    }
                }
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished updating effects");
                serverLogRepo.SaveServerLog(log);

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started running effect-expiry actions");
                try
                {
                    JokeShopProcedures.RunEffectExpiryActions(effectsExpiringThisTurn);
                }
                catch (Exception e)
                {
                    log.Errors++;
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, " ERROR running effect-expiry actions", e));
                }
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished running effect-expiry actions");
                serverLogRepo.SaveServerLog(log);

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started deleting expired effects");
                foreach (var e in effectsToDelete)
                {
                    effectRepo.DeleteEffect(e.Id);
                }
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished deleting expired effects");
                serverLogRepo.SaveServerLog(log);

                #region playerExtra / protection cooldown loop
                IPlayerExtraRepository playerExtraRepo = new EFPlayerExtraRepository();
                var extrasToIncrement            = playerExtraRepo.PlayerExtras.ToList();
                var extrasToIncrement_SaveList   = new List <PlayerExtra>();
                var extrasToIncrement_DeleteList = new List <PlayerExtra>();
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started updating protection change cooldown (" + extrasToIncrement.Count + ")");

                foreach (var e in extrasToIncrement)
                {
                    var owner = PlayerProcedures.GetPlayer(e.PlayerId);
                    if (PlayerProcedures.PlayerIsOffline(owner))
                    {
                        extrasToIncrement_SaveList.Add(e);
                    }
                }

                foreach (var e in extrasToIncrement_SaveList)
                {
                    if (e.ProtectionToggleTurnsRemaining > 0)
                    {
                        e.ProtectionToggleTurnsRemaining--;
                        playerExtraRepo.SavePlayerExtra(e);
                    }
                    else if (e.ProtectionToggleTurnsRemaining <= 0)
                    {
                        extrasToIncrement_DeleteList.Add(e);
                    }
                }

                foreach (var e in extrasToIncrement_DeleteList)
                {
                    playerExtraRepo.DeletePlayerExtra(e.Id);
                }

                #endregion

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished updating protection change cooldown.");


                #region main player loop

                using (var context = new StatsContext())
                {
                    try
                    {
                        context.Database.ExecuteSqlCommand("UPDATE [dbo].[Players] SET TimesAttackingThisUpdate = 0, CleansesMeditatesThisRound = 0, ShoutsRemaining = 1, ActionPoints = ActionPoints + 10, ItemsUsedThisTurn = 0 WHERE Mobility='full'" +

                                                           $"UPDATE [dbo].[Players] SET ActionPoints_Refill = ActionPoints_Refill + (ActionPoints % {TurnTimesStatics.GetActionPointLimit()} / 2) WHERE ActionPoints >= {TurnTimesStatics.GetActionPointLimit()} AND Mobility='full'" +

                                                           $"UPDATE [dbo].[Players] SET ActionPoints = {TurnTimesStatics.GetActionPointLimit()} WHERE ActionPoints > {TurnTimesStatics.GetActionPointLimit()} AND Mobility='full'" +

                                                           $"UPDATE [dbo].[Players] SET ActionPoints_Refill = {TurnTimesStatics.GetActionPointReserveLimit()} WHERE ActionPoints_Refill > {TurnTimesStatics.GetActionPointReserveLimit()} AND Mobility='full'" +

                                                           $"UPDATE [dbo].[Players] SET ActionPoints = ActionPoints + 20, ActionPoints_Refill = ActionPoints_Refill - 20 WHERE ActionPoints <= {TurnTimesStatics.GetActionPointLimit()-20} AND ActionPoints_Refill >= 20 AND Mobility='full'");

                        if (PvPStatics.ChaosMode)
                        {
                            context.Database.ExecuteSqlCommand($"Update [dbo].[Players] SET ActionPoints = {TurnTimesStatics.GetActionPointLimit()}, ActionPoints_Refill = {TurnTimesStatics.GetActionPointReserveLimit()}, Mana = MaxMana");
                        }

                        log.AddLog(updateTimer.ElapsedMilliseconds + ":  ANIMATE SQL UPDATE SUCCEEDED!");
                        serverLogRepo.SaveServerLog(log);
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, " ANIMATE SQL UPDATE FAILED", e));
                        serverLogRepo.SaveServerLog(log);
                    }
                }

                var timeCutoff    = DateTime.UtcNow.AddHours(-8);
                var playersToSave = playerRepo.Players
                                    .Where(p => p.Mobility == PvPStatics.MobilityFull && p.LastActionTimestamp > timeCutoff).ToList();

                foreach (var player in playersToSave)
                {
                    //Skip regen stuff for those in quests.
                    if (player.InQuest > 0)
                    {
                        continue;
                    }

                    // extra AP condition checks
                    if (player.Covenant > 0)
                    {
                        var playerCov = CovenantDictionary.IdNameFlagLookup.FirstOrDefault(c => c.Key == player.Covenant).Value;

                        // give this player an extra AP refill if they are at their safeground, scaled up by level
                        if (playerCov != null && !playerCov.HomeLocation.IsNullOrEmpty() && player.dbLocationName == playerCov.HomeLocation)
                        {
                            player.ActionPoints_Refill += .25M * playerCov.CovLevel;
                        }

                        // give this player an extra AP refill if they are on a location that their covenane has enchanted
                        var currentLocation = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == player.dbLocationName);

                        if (currentLocation != null && currentLocation.CovenantController == player.Covenant)
                        {
                            if (currentLocation.TakeoverAmount < 25)
                            {
                                player.ActionPoints_Refill += .05M;
                            }
                            else if (currentLocation.TakeoverAmount <= 50)
                            {
                                player.ActionPoints_Refill += .10M;
                            }
                            else if (currentLocation.TakeoverAmount <= 75)
                            {
                                player.ActionPoints_Refill += .15M;
                            }
                            else if (currentLocation.TakeoverAmount < 100)
                            {
                                player.ActionPoints_Refill += .20M;
                            }
                            else if (currentLocation.TakeoverAmount >= 100)
                            {
                                player.ActionPoints_Refill += .25M;
                            }
                        }

                        // make sure AP reserve stays within maximum amount
                        if (player.ActionPoints_Refill > TurnTimesStatics.GetActionPointReserveLimit())
                        {
                            player.ActionPoints_Refill = TurnTimesStatics.GetActionPointReserveLimit();
                        }
                    }

                    var buffs = ItemProcedures.GetPlayerBuffs(player);
                    player.Health += buffs.HealthRecoveryPerUpdate();
                    player.Mana   += buffs.ManaRecoveryPerUpdate();

                    player.ReadjustMaxes(buffs);

                    playerRepo.SavePlayer(player);
                }

                log.AddLog($"{updateTimer.ElapsedMilliseconds}:  Finished updating animate players ({playersToSave.Count})");
                serverLogRepo.SaveServerLog(log);

                #endregion main player loop

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started updating inanimate/animal players");


                using (var context = new StatsContext())
                {
                    try
                    {
                        context.Database.ExecuteSqlCommand("UPDATE [dbo].[Players] SET TimesAttackingThisUpdate = 0, ItemsUsedThisTurn = 0 WHERE (Mobility = 'inanimate' OR Mobility = 'animal') AND BotId = 0");
                        log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished updating inanimate/animal players");
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, " ERROR UPDATING INANIMATE/ANIMAL PLAYERS", e));
                    }
                }

                serverLogRepo.SaveServerLog(log);

                #region decrement mind control timers
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started mind control cooldown.");

                using (var context = new StatsContext())
                {
                    try
                    {
                        context.Database.ExecuteSqlCommand("UPDATE [dbo].[MindControls] SET TurnsRemaining = TurnsRemaining - 1");
                        context.Database.ExecuteSqlCommand("DELETE FROM [dbo].[MindControls] WHERE TurnsRemaining <= 0");
                        context.Database.ExecuteSqlCommand("UPDATE [dbo].[MindControls] SET TimesUsedThisTurn = 0");

                        log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished mind control cooldown.");
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "MIND CONTROL COOLDOWN UPDATE FAILED", e));
                    }
                }
                #endregion

                serverLogRepo.SaveServerLog(log);

                PvPStatics.AnimateUpdateInProgress = false;

                // bump down the timer on all items that are reuseable consumables
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started updating items on cooldown");
                IItemRepository itemsRepo     = new EFItemRepository();
                var             itemsToUpdate = itemsRepo.Items.Where(i => i.TurnsUntilUse > 0).ToList();

                foreach (var item in itemsToUpdate)
                {
                    item.TurnsUntilUse--;
                }

                foreach (var item in itemsToUpdate)
                {
                    itemsRepo.SaveItem(item);
                }
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished updating items on cooldown");
                serverLogRepo.SaveServerLog(log);

                // find the ids for the merchants Lindella and Skaldyr
                var skaldyr      = PlayerProcedures.GetPlayerFromBotId(AIStatics.LoremasterBotId);
                var soulbinderId = PlayerProcedures.GetPlayerFromBotId(AIStatics.SoulbinderBotId).Id;

                // have abandoned items go to Lindella
                if (turnNo % 11 == 3 && lindella.Mobility == PvPStatics.MobilityFull)
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started collecting all abandoned items for Lindella");

                    using (var context = new StatsContext())
                    {
                        try
                        {
                            context.Database.ExecuteSqlCommand($"UPDATE [dbo].[Items] SET OwnerId = {lindella.Id}, dbLocationName = '', PvPEnabled = {(int)GameModeStatics.GameModes.Any}, TimeDropped = '{DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")}' " +
                                                               $"FROM DbStaticItems WHERE dbLocationName <> '' AND dbLocationName IS NOT NULL AND TimeDropped < DATEADD(hour, -8, GETUTCDATE()) AND OwnerId IS NULL AND DbStaticItems.Id = Items.ItemSourceId AND ItemType != '{PvPStatics.ItemType_Pet}' AND ItemSourceId != {ItemStatics.ItemType_DungeonArtifactItemSourceId};" +
                                                               $"UPDATE [dbo].[Players] SET dbLocationName = '' FROM Items WHERE Items.FormerPlayerId = Players.Id AND Items.OwnerId = {lindella.Id};");



                            log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished collecting all abandoned items for Lindella");
                        }
                        catch (Exception e)
                        {
                            log.Errors++;
                            log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "ERROR collecting all abandoned items for Lindella", e));
                        }
                    }
                }

                // delete all consumable type items that have been sitting around on the ground for too long
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started deleting expired consumables");
                DomainRegistry.Repository.Execute(new DeleteExpiredConsumablesOnGround());
                DomainRegistry.Repository.Execute(new DeleteExpiredConsumablesOnMerchants {
                    LindellaId = lindella.Id, LorekeeperId = skaldyr.Id
                });

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished deleting expired consumables");
                serverLogRepo.SaveServerLog(log);

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started deleting expired runes");
                try
                {
                    DomainRegistry.Repository.Execute(new DeleteExpiredRunesOnMerchants());
                }
                catch (Exception e)
                {
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "ERROR deleting expired runes", e));
                    log.Errors++;
                }

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished deleting expired runes");

                serverLogRepo.SaveServerLog(log);

                // allow all items that have been recently equipped to be taken back off
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started resetting items that have been recently equipped");
                var recentlyEquipped = itemsRepo.Items.Where(i => i.EquippedThisTurn).ToList();

                foreach (var item in recentlyEquipped)
                {
                    item.EquippedThisTurn = false;
                    itemsRepo.SaveItem(item);
                }
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished resetting items that have been recently equipped");

                #region give covenants money based on territories
                if (turnNo % 6 == 0)
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started giving covenants money from territories");
                    ICovenantRepository covRepo = new EFCovenantRepository();
                    var covs = covRepo.Covenants.Where(c => c.HomeLocation != null && c.HomeLocation != "").ToList();


                    foreach (var c in covs)
                    {
                        var locationControlledSum = CovenantProcedures.GetLocationControlCount(c);
                        var moneyGain             = (decimal)Math.Floor(Convert.ToDouble(locationControlledSum));
                        c.Money += moneyGain;

                        if (moneyGain > 0)
                        {
                            CovenantProcedures.WriteCovenantLog("Your covenant collected " + moneyGain + " Arpeyjis from the locations you have enchanted.", c.Id, false);
                        }
                        covRepo.SaveCovenant(c);
                    }
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished giving covenants money from territories");
                }
                #endregion

                serverLogRepo.SaveServerLog(log);

                #region drop dungeon artifacts and spawn demons if needed

                try
                {
                    if (turnNo % 7 == 2)
                    {
                        log.AddLog(updateTimer.ElapsedMilliseconds + ":  Starting dungeon item / demon spawning");
                        var dungeonArtifactCount = itemsRepo.Items.Count(i => i.ItemSourceId == ItemStatics.ItemType_DungeonArtifactItemSourceId);
                        for (var x = 0; x < PvPStatics.DungeonArtifact_SpawnLimit - dungeonArtifactCount; x++)
                        {
                            var randDungeon = LocationsStatics.GetRandomLocation_InDungeon();

                            var cmd = new CreateItem
                            {
                                dbLocationName   = randDungeon,
                                OwnerId          = null,
                                EquippedThisTurn = false,
                                IsPermanent      = true,
                                Level            = 0,
                                PvPEnabled       = 2,
                                IsEquipped       = false,
                                TurnsUntilUse    = 0,
                                ItemSourceId     = ItemStatics.ItemType_DungeonArtifactItemSourceId
                            };
                            DomainRegistry.Repository.Execute(cmd);
                        }


                        IEnumerable <Player> demons = playerRepo.Players.Where(i => i.FormSourceId == PvPStatics.DungeonDemonFormSourceId);
                        var dungeonDemonCount       = demons.Count();

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

                        var demonNames = XmlResourceLoader.Load <List <string> >("TT.Domain.XMLs.DungeonDemonNames.xml");

                        for (var x = 0; x < PvPStatics.DungeonDemon_Limit - dungeonDemonCount; x++)
                        {
                            var randDungeon = LocationsStatics.GetRandomLocation_InDungeon();

                            // pull a random last demon name
                            double maxDemonNameCount = demonNames.Count();
                            var    num           = randLevel.NextDouble();
                            var    demonIndex    = Convert.ToInt32(Math.Floor(num * maxDemonNameCount));
                            var    demonlastName = demonNames.ElementAt(demonIndex);

                            // if there's already a demon with this last name, reroll and try again
                            if (demons.FirstOrDefault(d => d.LastName == demonlastName) != null)
                            {
                                x--;
                                continue;
                            }


                            var levelRoll = randLevel.NextDouble();
                            var level     = (int)Math.Floor(levelRoll * 8 + 3);

                            var cmd = new CreatePlayer
                            {
                                BotId        = AIStatics.DemonBotId,
                                FirstName    = "Spirit of ",
                                LastName     = demonlastName,
                                Mobility     = PvPStatics.MobilityFull,
                                FormSourceId = AIStatics.DungeonDemonFormId,
                                Gender       = PvPStatics.GenderFemale,
                                GameMode     = 2,
                                Health       = 10000,
                                Mana         = 10000,
                                Covenant     = -1,
                                Location     = randDungeon,
                                Level        = level,
                                MaxHealth    = 10000,
                                MaxMana      = 10000,
                            };

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

                            var newDemon = playerRepo.Players.FirstOrDefault(p => p.Id == id);

                            if (cmd.Level <= 5)
                            {
                                ItemProcedures.GiveNewItemToPlayer(newDemon, ItemStatics.SpellbookMediumItemSourceId);
                            }
                            else if (cmd.Level <= 7)
                            {
                                ItemProcedures.GiveNewItemToPlayer(newDemon, ItemStatics.SpellbookLargeItemSourceId);
                            }

                            else if (cmd.Level > 7)
                            {
                                ItemProcedures.GiveNewItemToPlayer(newDemon, ItemStatics.SpellbookGiantItemSourceId);
                            }

                            newDemon.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(newDemon));
                            playerRepo.SavePlayer(newDemon);
                        }
                        log.AddLog(updateTimer.ElapsedMilliseconds + ":  FINISHED dungeon item / demon spawning");
                    }
                }
                catch (Exception e)
                {
                    log.Errors++;
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "ERROR running dungeon actions", e));
                }


                #endregion

                serverLogRepo.SaveServerLog(log);

                #region forcibly terminate duels that have timed out
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started duel updates");
                try
                {
                    IDuelRepository duelRepo = new EFDuelRepository();
                    var             duels    = duelRepo.Duels.Where(d => d.Status == DuelProcedures.ACTIVE).ToList();

                    foreach (var d in duels)
                    {
                        // if the duel has timed out, end it forcibly
                        if ((turnNo - d.StartTurn) >= PvPStatics.MaximumDuelTurnLength)
                        {
                            DuelProcedures.EndDuel(d.Id, DuelProcedures.TIMEOUT);
                        }
                    }

                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Successfully completed duel updates");
                }
                catch (Exception e)
                {
                    log.Errors++;
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "ERROR completing duel updates", e));
                }
                #endregion duel updates

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started Lindella actions");
                serverLogRepo.SaveServerLog(log);
                try
                {
                    BossProcedures_Lindella.RunActions(turnNo);
                }
                catch (Exception e)
                {
                    log.Errors++;
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "ERROR running Lindella action", e));
                }
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished Lindella actions");

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started Wuffie actions");
                serverLogRepo.SaveServerLog(log);
                try
                {
                    BossProcedures_PetMerchant.RunPetMerchantActions(turnNo);
                }
                catch (Exception e)
                {
                    log.Errors++;
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "ERROR running Wuffie actions", e));
                }
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished Wuffie actions");

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started running effect-related actions");
                try
                {
                    JokeShopProcedures.RunEffectActions(activeOrExpiringEffects);
                }
                catch (Exception e)
                {
                    log.Errors++;
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, " ERROR running effect-related actions", e));
                }
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished running effect-related actions");
                serverLogRepo.SaveServerLog(log);

                #region furniture
                if (turnNo % 6 == 0)
                {
                    // move some furniture around on the market
                    try
                    {
                        FurnitureProcedures.MoveFurnitureOnMarket();
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(updateTimer.ElapsedMilliseconds + "ERROR MOVING FURNITURE ON MARKET:  " + e);
                    }

                    // move Jewdewfae to a new location if she has been in one place for more than 48 turns, 8 hours
                    try
                    {
                        var fae   = PlayerProcedures.GetPlayerFromBotId(-6);
                        var faeAI = AIDirectiveProcedures.GetAIDirective(fae.Id);

                        // if the turn since her last move has been long enough, relocate her
                        if (turnNo - (int)faeAI.Var2 > 48)
                        {
                            log.AddLog(updateTimer.ElapsedMilliseconds + ":  FORCED JEWDEWFAE TO MOVE.");
                            BossProcedures_Jewdewfae.MoveToNewLocation();
                        }
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(updateTimer.ElapsedMilliseconds + "ERROR TRYING TO MOVE JEWDEWFAE:  " + e);
                    }
                }
                #endregion furniture

                #region bosses

                // DONNA
                if (worldStats.Boss_Donna == AIStatics.ACTIVE)
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started Donna actions");
                    serverLogRepo.SaveServerLog(log);
                    try
                    {
                        BossProcedures_Donna.RunDonnaActions();
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "Error running Donna actions", e));
                    }
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished Donna actions");
                }

                // VALENTINE
                if (worldStats.Boss_Valentine == AIStatics.ACTIVE || PlayerProcedures.GetAnimatePlayerFromBotId(AIStatics.ValentineBotId) != null)
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started Valentine actions");
                    serverLogRepo.SaveServerLog(log);
                    try
                    {
                        BossProcedures_Valentine.RunValentineActions();
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "Error running Valentine actions", e));
                    }
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished Valentine actions");
                }

                // BIMBO
                if (worldStats.Boss_Bimbo == AIStatics.ACTIVE)
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started Bimbo actions");
                    serverLogRepo.SaveServerLog(log);
                    try
                    {
                        BossProcedures_BimboBoss.RunActions(turnNo);
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "Error running Bimbo actions", e));
                    }
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished Bimbo actions");
                }

                // THIEVES
                if (worldStats.Boss_Thief == AIStatics.ACTIVE)
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started Thieves actions");
                    serverLogRepo.SaveServerLog(log);
                    try
                    {
                        BossProcedures_Thieves.RunThievesAction(turnNo);
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "Error running Thieves actions", e));
                    }
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished Thieves actions");
                }

                // SISTERS
                if (worldStats.Boss_Sisters == AIStatics.ACTIVE)
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started Sisters actions");
                    serverLogRepo.SaveServerLog(log);
                    try
                    {
                        BossProcedures_Sisters.RunSistersAction();
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "Error running Sisters actions", e));
                    }
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished Sisters actions");
                }

                // FAEBOSS
                if (worldStats.Boss_Faeboss == AIStatics.ACTIVE)
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started Narcissa actions");
                    serverLogRepo.SaveServerLog(log);
                    try
                    {
                        BossProcedures_FaeBoss.RunTurnLogic();
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "Error running Narcissa actions", e));
                    }
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished Narcissa actions");
                }

                // BIKER GANG BOSS
                if (worldStats.Boss_MotorcycleGang == AIStatics.ACTIVE)
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started BikerBoss actions");
                    serverLogRepo.SaveServerLog(log);
                    try
                    {
                        BossProcedures_MotorcycleGang.RunTurnLogic();
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(updateTimer.ElapsedMilliseconds + ":  BikerBoss ERROR:  " + e);
                    }
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished BikerBoss actions");
                }

                #endregion bosses

                // psychopaths
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started psychopath actions");
                serverLogRepo.SaveServerLog(log);

                var psychoExceptions = AIProcedures.RunPsychopathActions(worldStats);

                foreach (var e in psychoExceptions)
                {
                    log.Errors++;
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "Error running pycho action", e));
                }

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished psychopath actions");

                // minibosses
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started miniboss actions");
                serverLogRepo.SaveServerLog(log);

                var minibossExceptions = BossProcedures_Minibosses.RunAll(worldStats.TurnNumber);

                foreach (var e in minibossExceptions)
                {
                    log.Errors++;
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "Error running miniboss action", e));
                }

                serverLogRepo.SaveServerLog(log);
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished miniboss actions");

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Starting setting update status to done");
                try
                {
                    PvPWorldStatProcedures.UpdateWorldTurnCounter_UpdateDone();
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished setting update status to done");
                }
                catch (Exception e)
                {
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "ERROR setting update status to done: ", e));
                    log.Errors++;
                }

                serverLogRepo.SaveServerLog(log);

                try
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started stored procedure maintenance");
                    using (var context = new StatsContext())
                    {
                        context.Database.ExecuteSqlCommand(
                            "DELETE FROM [dbo].[LocationLogs] WHERE Timestamp < DATEADD(hour, -1, GETUTCDATE())");
                        context.Database.ExecuteSqlCommand(
                            "DELETE FROM [dbo].[Messages] WHERE Timestamp < DATEADD(hour, -72, GETUTCDATE()) AND DoNotRecycleMe = 0");
                        context.Database.ExecuteSqlCommand("DELETE FROM [dbo].[TFEnergies] WHERE Amount < .5");
                        context.Database.ExecuteSqlCommand(
                            "DELETE FROM [dbo].[PlayerLogs] WHERE Timestamp < DATEADD(hour, -72, GETUTCDATE())");
                        context.Database.ExecuteSqlCommand(
                            "DELETE FROM [dbo].[ChatLogs] WHERE Timestamp < DATEADD(hour, -72, GETUTCDATE())");
                        context.Database.ExecuteSqlCommand(
                            "DELETE FROM [dbo].[AIDirectives] WHERE Timestamp < DATEADD(hour, -72, GETUTCDATE()) AND DoNotRecycleMe = 0");
                        context.Database.ExecuteSqlCommand(
                            "DELETE FROM [dbo].[CovenantLogs] WHERE Timestamp < DATEADD(hour, -72, GETUTCDATE())");
                        context.Database.ExecuteSqlCommand(
                            "DELETE FROM [dbo].[RPClassifiedAds] WHERE RefreshTimestamp < DATEADD(hour, -72, GETUTCDATE())");
                        context.Database.ExecuteSqlCommand(
                            "DELETE FROM [dbo].[TFEnergies] WHERE Timestamp < DATEADD(hour, -72, GETUTCDATE())");
                        context.Database.ExecuteSqlCommand(
                            "DELETE FROM [dbo].[SelfRestoreEnergies] WHERE Timestamp < DATEADD(hour, -4, GETUTCDATE())");

                        // move soulbound items on the ground to the soulbinding NPC.
                        context.Database.ExecuteSqlCommand(
                            $"UPDATE[dbo].[Items] SET OwnerId = {soulbinderId}, dbLocationName = '' WHERE dbLocationName <> '' AND SoulboundToPlayerId IS NOT NULL;");
                    }
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished stored procedure maintenance");
                }
                catch (Exception e)
                {
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "ERROR running stored procedure maintenance: ", e));
                    log.Errors++;
                }

                serverLogRepo.SaveServerLog(log);


                #region update joke shop
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Updating joke shop started.");
                try
                {
                    JokeShopProcedures.EjectOfflineCharacters();

                    if (new Random().Next(20) == 0)
                    {
                        LocationsStatics.MoveJokeShop();
                    }

                    ChallengeProcedures.CheckChallenges();
                }
                catch (Exception e)
                {
                    log.Errors++;
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "Updating joke shop FAILED", e));
                }
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Updating joke shop completed.");
                serverLogRepo.SaveServerLog(log);
                #endregion update joke shop


                #region regenerate dungeon
                if (turnNo % 30 == 7)
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Dungeon generation started.");
                    try
                    {
                        DungeonProcedures.GenerateDungeon();
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "Dungeon generation FAILED", e));
                    }
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Dungeon generation completed.");
                    serverLogRepo.SaveServerLog(log);
                }
                #endregion

                #region move tomb quest
                // Just to keep some things consistent, following the update pattern of the dungeon regen.
                if (turnNo > 6665 && turnNo % 30 == 7)
                {
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Updating tomb location started.");
                    try
                    {
                        // Get the quest stuff to start with.
                        int questId           = 39; //Nephthyma's Calling quest ID.
                        IQuestRepository repo = new EFQuestRepository();
                        var questStart        = repo.QuestStarts.FirstOrDefault(q => q.Id == questId);

                        if (questStart != null)
                        {
                            // Pick a random location.
                            string[] locationList   = { "mansion_mausoleum", "gym_laundry", "street_50e9th", "park_shrine" };
                            Random   locationRandom = new Random();
                            int      locationIndex  = locationRandom.Next(locationList.Length);
                            string   location       = locationList[locationIndex];

                            // Set it to the new location.

                            questStart.Location = location;
                            QuestWriterProcedures.SaveQuestStart(questStart);
                        }
                    }
                    catch (Exception e)
                    {
                        log.Errors++;
                        log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "Updating tomb location FAILED", e));
                    }
                    log.AddLog(updateTimer.ElapsedMilliseconds + ":  Updating tomb location completed.");
                    serverLogRepo.SaveServerLog(log);
                }
                #endregion

                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Started deleting unwanted psycho items/pets on Lindella/Wuffie");
                try
                {
                    DomainRegistry.Repository.Execute(new DeleteUnpurchasedPsychoItems());
                }
                catch (Exception e)
                {
                    log.Errors++;
                    log.AddLog(FormatExceptionLog(updateTimer.ElapsedMilliseconds, "ERROR deleting unwanted psycho items", e));
                }
                log.AddLog(updateTimer.ElapsedMilliseconds + ":  Finished deleting unwanted psycho items/pets on Lindella/Wuffie");
                log.FinishTimestamp = DateTime.UtcNow;
                serverLogRepo.SaveServerLog(log);
            }
        }
예제 #22
0
        public static IEnumerable <Covenant> GetAllCovenants()
        {
            ICovenantRepository covRepo = new EFCovenantRepository();

            return(covRepo.Covenants.Where(c => c.Id > 0));
        }
예제 #23
0
        public static Covenant GetDbCovenant(int id)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();

            return(covRepo.Covenants.FirstOrDefault(c => c.Id == id));
        }
예제 #24
0
        public static Covenant GetDbCovenant(string name)
        {
            ICovenantRepository covRepo = new EFCovenantRepository();

            return(covRepo.Covenants.FirstOrDefault(c => c.Name == name));
        }
예제 #25
0
        public static string AttackLocation(Player player, BuffBox buffs)
        {
            ILocationInfoRepository repo    = new EFLocationInfoRepository();
            ICovenantRepository     covRepo = new EFCovenantRepository();
            var location = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == player.dbLocationName);
            var output   = "";

            if (location == null)
            {
                output = "You cast an enchantment here, but you aren't actually anywhere!";
                return(output);
            }

            var info = repo.LocationInfos.FirstOrDefault(l => l.dbName == player.dbLocationName) ?? new LocationInfo
            {
                TakeoverAmount = 75,
                CovenantId     = -1,
                dbName         = player.dbLocationName,
            };

            if (player.Covenant == null)
            {
                output = "You cast an enchantment here, but it did no effect as you aren't part of a covenant";
                return(output);
            }

            if (info.TakeoverAmount >= 100 && info.CovenantId == player.Covenant)
            {
                output = "You cast an enchantment here, but it did no effect as this location's enchantment is already at its highest possible level, 100.";
                return(output);
            }

            var takeoverAmount = (float)player.Level / 2.0F;

            takeoverAmount += buffs.EnchantmentBoost;

            decimal XPGain = 0;

            try
            {
                XPGain = 40 / Math.Round(Convert.ToDecimal(101 - Math.Abs(info.TakeoverAmount)), 1);
            }
            catch (Exception)
            {
                XPGain = 0;
            }

            if (XPGain > PvPStatics.XP__EnchantmentMaxXP)
            {
                XPGain = PvPStatics.XP__EnchantmentMaxXP;
            }

            var XPGainText = String.Format("{0:0.#}", XPGain);

            // location is not controlled; give it to whichever covenant is attacking it
            if (info.TakeoverAmount <= 0)
            {
                info.CovenantId     = (int)player.Covenant;
                info.TakeoverAmount = takeoverAmount;


                if (info.TakeoverAmount > 100)
                {
                    info.TakeoverAmount = 100;
                }

                info.LastTakeoverTurn = PvPWorldStatProcedures.GetWorldTurnNumber();
                output = "<b>Your enchantment settles in this location, converting its energies from the previous controlling covenant to your own!  (+" + XPGainText + " XP)</b>";
                location.CovenantController = (int)player.Covenant;
                location.TakeoverAmount     = info.TakeoverAmount;
                var myCov = covRepo.Covenants.First(c => c.Id == player.Covenant);

                var locationLogMessage = "<b class='playerAttackNotification'>" + player.GetFullName() + " enchanted this location and claimed it for " + myCov.Name + "!</b>";
                LocationLogProcedures.AddLocationLog(player.dbLocationName, locationLogMessage);


                var covLogWinner = player.GetFullName() + " enchanted " + location.Name + " and has claimed it for this covenant.";
                CovenantProcedures.WriteCovenantLog(covLogWinner, myCov.Id, true);
            }

            // otherwise the location is controlled by someone
            else
            {
                // add points toward the attacker's covenant or take them away if it belongs to another
                if (info.CovenantId == player.Covenant)
                {
                    info.TakeoverAmount    += takeoverAmount;
                    location.TakeoverAmount = info.TakeoverAmount;
                    var cov = covRepo.Covenants.FirstOrDefault(c => c.Id == player.Covenant);
                    output =
                        $"Your enchantment reinforces this location by {takeoverAmount}.  New influence level is {info.TakeoverAmount} for your covenant, {cov?.Name ?? "unknown"}.  (+{XPGainText} XP)</b>";
                }
                else
                {
                    info.TakeoverAmount    -= takeoverAmount;
                    location.TakeoverAmount = info.TakeoverAmount;
                    var cov = info.CovenantId == null
                        ? null
                        : covRepo.Covenants.FirstOrDefault(c => c.Id == info.CovenantId);

                    if (info.TakeoverAmount <= 0)
                    {
                        // notify old covenant who stole the location and their covenant
                        if (info.CovenantId != null && info.CovenantId > 0)
                        {
                            var attackingCov = CovenantProcedures.GetCovenantViewModel((int)player.Covenant);
                            var covLogLoser  = player.GetFullName() + " of " + attackingCov.dbCovenant.Name + " enchanted " + location.Name + ", removing it from this covenant's influence!";
                            CovenantProcedures.WriteCovenantLog(covLogLoser, (int)info.CovenantId, true);
                        }

                        info.CovenantId       = -1;
                        info.LastTakeoverTurn = PvPWorldStatProcedures.GetWorldTurnNumber();
                    }

                    if (cov != null)
                    {
                        output = "You dispel the enchantment at this location by " + takeoverAmount + ".  New influence level is " + info.TakeoverAmount + " for the location's existing controller, " + cov.Name + ".  (+" + XPGainText + " XP)</b>";
                    }
                    else
                    {
                        output = "You dispel the enchantment at this location by " + takeoverAmount + ".  New influence level is " + info.TakeoverAmount + ".  (+" + XPGainText + " XP)</b>";
                    }
                }

                var locationLogMessage = "<span class='playerAttackNotification'>" + player.GetFullName() + " cast an enchantment on this location.</span>";
                LocationLogProcedures.AddLocationLog(player.dbLocationName, locationLogMessage);
            }


            if (info.TakeoverAmount > 100)
            {
                info.TakeoverAmount = 100;
            }

            // cap at 0 to 100 points
            else if (info.TakeoverAmount <= 0)
            {
                info.CovenantId     = -1;
                info.TakeoverAmount = 0;
            }



            repo.SaveLocationInfo(info);
            PlayerProcedures.GiveXP(player, XPGain);
            PlayerLogProcedures.AddPlayerLog(player.Id, output, false);

            return(output);
        }