Пример #1
0
        public static void BeginDuel(int duelId)
        {
            IDuelRepository duelRepo = new EFDuelRepository();
            var             duel     = duelRepo.Duels.FirstOrDefault(d => d.Id == duelId);

            duel.StartTurn = PvPWorldStatProcedures.GetWorldTurnNumber();
            duel.Status    = ACTIVE;

            var members     = GetPlayerViewModelsInDuel(duelId);
            var memberNames = "";

            foreach (var p in members)
            {
                memberNames += p.Player.GetFullName() + ", ";
            }

            foreach (var p in members)
            {
                duel.Combatants.FirstOrDefault(f => f.PlayerId == p.Player.Id).StartFormSourceId = p.Player.FormSourceId;
                PlayerProcedures.EnterDuel(p.Player.Id, duel.Id);
                var playerMessage = "<b>Your duel between " + memberNames + " has begun!</b>";
                PlayerLogProcedures.AddPlayerLog(p.Player.Id, playerMessage, true);
            }

            LocationLogProcedures.AddLocationLog(members.First().Player.dbLocationName, "<b class='playerAttackNotification'>A duel started here.</b>");

            duelRepo.SaveDuel(duel);
        }
Пример #2
0
        public static void EndDuel(int duelId, string endStatus)
        {
            IDuelRepository duelRepo = new EFDuelRepository();
            var             duel     = duelRepo.Duels.FirstOrDefault(d => d.Id == duelId);

            duel.CompletionTurn = PvPWorldStatProcedures.GetWorldTurnNumber();
            duel.Status         = endStatus;

            duelRepo.SaveDuel(duel);

            foreach (var d in duel.Combatants)
            {
                PlayerProcedures.EnterDuel(d.PlayerId, 0);

                var message = "";

                if (endStatus == TIMEOUT)
                {
                    message = "<b class='bad'>Your duel has timed out, ending in a disappointing draw.  You feel as if some frustrated spirits have left you weakened by a curse...</b>";
                    EffectProcedures.GivePerkToPlayer(TimeoutCurseEffectSourceId, d.PlayerId);
                }
                else
                {
                    message = "<b>Your duel has ended.</b>";
                }

                PlayerLogProcedures.AddPlayerLog(d.PlayerId, message, true);
            }
        }
        public static string GetProspectsMessage(Player player)
        {
            IInanimateXPRepository inanimXpRepo = new EFInanimateXPRepository();
            IItemRepository        itemRep      = new EFItemRepository();

            var inanimateMe = DomainRegistry.Repository.FindSingle(new GetItemByFormerPlayer {
                PlayerId = player.Id
            });

            if (inanimateMe == null)
            {
                return("");
            }

            var meItem   = itemRep.Items.FirstOrDefault(i => i.Id == inanimateMe.Id);
            var myItemXP = inanimXpRepo.InanimateXPs.FirstOrDefault(i => i.OwnerId == player.Id);

            if (meItem == null || myItemXP == null)
            {
                return(null);
            }

            var turnsSinceLastAction = Math.Max(0, PvPWorldStatProcedures.GetWorldTurnNumber() - myItemXP.LastActionTurnstamp);

            // Time until lock - at 2% per turn  (negative threshold)
            var turnsUntilLocked = (myItemXP.TimesStruggled - TurnTimesStatics.GetStruggleXPBeforeItemPermanentLock()) / 2 - turnsSinceLastAction;

            if (!meItem.IsPermanent && turnsUntilLocked <= TurnTimesStatics.GetItemMaxTurnsBuildup())
            {
                if (turnsUntilLocked <= 1)
                {
                    return("<b style=\"color: red;\">Be careful!</b>  Just one more move and you might never be human again!");
                }
                else
                {
                    var time = turnsUntilLocked * TurnTimesStatics.GetTurnLengthInSeconds();

                    return($"If you keep enjoying your current form you might find yourself locked into it forever!  That could happen in as little as <b>{SecondsToDurationString(time)}</b> or so!");
                }
            }

            // Time until chance of escaping - at 1% per turn outside Chaos
            var turnsUntilAbleToStruggle = 1 - myItemXP.TimesStruggled - turnsSinceLastAction;

            if (ItemProcedures.ItemIncursDungeonPenalty(inanimateMe))
            {
                turnsUntilAbleToStruggle *= 3;
            }

            if (!PvPStatics.ChaosMode && turnsUntilAbleToStruggle > 1 && turnsUntilAbleToStruggle <= TurnTimesStatics.GetItemMaxTurnsBuildup())
            {
                var time = turnsUntilAbleToStruggle * TurnTimesStatics.GetTurnLengthInSeconds();

                return($"You could be free in approximately <b>{SecondsToDurationString(time)}</b> if you keep fighting!");
            }

            return(null);
        }
Пример #4
0
        public static void InstantTakeoverLocation(Covenant cov, string location)
        {
            ILocationInfoRepository repo = new EFLocationInfoRepository();
            var info = repo.LocationInfos.FirstOrDefault(l => l.dbName == location);

            if (info == null)
            {
                info = new LocationInfo
                {
                    dbName = location,
                };
            }
            info.TakeoverAmount   = 100;
            info.CovenantId       = cov.Id;
            info.LastTakeoverTurn = PvPWorldStatProcedures.GetWorldTurnNumber();
            repo.SaveLocationInfo(info);

            LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == location).CovenantController = cov.Id;
        }
Пример #5
0
        public static void SendDuelChallenge(Player challenger, Player target)
        {
            IPlayerRepository playerRepo = new EFPlayerRepository();
            IDuelRepository   duelRepo   = new EFDuelRepository();

            var dbChallenger = playerRepo.Players.FirstOrDefault(p => p.Id == challenger.Id);
            var dbTarget     = playerRepo.Players.FirstOrDefault(p => p.Id == target.Id);


            var newDuel = new Duel
            {
                StartTurn          = -1,
                ProposalTurn       = PvPWorldStatProcedures.GetWorldTurnNumber(),
                CompletionTurn     = -1,
                Status             = PENDING,
                LastResetTimestamp = DateTime.UtcNow,
                Combatants         = new List <DuelCombatant> {
                    new DuelCombatant {
                        PlayerId = challenger.Id,
                        Team     = 1,
                    }, new DuelCombatant {
                        PlayerId = target.Id,
                        Team     = 2,
                    }
                },
            };

            duelRepo.SaveDuel(newDuel);

            // TODO:  make it so target has to accept first
            // dbChallenger.InDuel = newDuel.Id;
            // dbTarget.InDuel = newDuel.Id;

            var messageToTarget = "You have been challenge to a duel by <b>" + challenger.GetFullName() + "</b>!  Will you accept the challenge or show your cowardice?  " +
                                  "<b><u><a href='/Duel/AcceptChallenge/" + newDuel.Id + "'>Click here to Accept</a></b></u>."
            ;

            PlayerLogProcedures.AddPlayerLog(dbTarget.Id, messageToTarget, true);

            playerRepo.SavePlayer(dbChallenger);
            playerRepo.SavePlayer(dbTarget);
        }
Пример #6
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);
        }
Пример #7
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);
        }
Пример #8
0
        public static string PlayerEndQuest(Player player, int endType)
        {
            var message = "";
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var dbPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == player.Id);

            dbPlayer.InQuest      = 0;
            dbPlayer.InQuestState = 0;
            playerRepo.SavePlayer(dbPlayer);

            IQuestRepository questRepo = new EFQuestRepository();
            var questPlayerStatus      = questRepo.QuestPlayerStatuses.FirstOrDefault(q => q.PlayerId == player.Id && q.QuestId == player.InQuest);

            if (questPlayerStatus == null)
            {
                questPlayerStatus = new QuestPlayerStatus
                {
                    PlayerId = player.Id,
                    QuestId  = player.InQuest,
                };
            }
            questPlayerStatus.LastEndedTurn = PvPWorldStatProcedures.GetWorldTurnNumber();
            questPlayerStatus.Outcome       = endType;

            questRepo.SaveQuestPlayerStatus(questPlayerStatus);

            // assing completion bonuses
            if (endType == (int)QuestStatics.QuestOutcomes.Completed)
            {
                var questState = GetQuestState(player.InQuestState);

                decimal xpGain = 0;

                foreach (var q in questState.QuestEnds)
                {
                    // experience gain
                    if (q.RewardType == (int)QuestStatics.RewardType.Experience)
                    {
                        xpGain += Int32.Parse(q.RewardAmount);
                    }

                    // item gain
                    else if (q.RewardType == (int)QuestStatics.RewardType.Item)
                    {
                        var item = ItemStatics.GetStaticItem(System.Convert.ToInt32(q.RewardAmount));
                        ItemProcedures.GiveNewItemToPlayer(player, item);
                        message += " <br>You received a <b>" + item.FriendlyName + "</b>.";
                    }

                    // effect gain
                    else if (q.RewardType == (int)QuestStatics.RewardType.Effect)
                    {
                        var effect = EffectStatics.GetDbStaticEffect(System.Convert.ToInt32(q.RewardAmount));
                        EffectProcedures.GivePerkToPlayer(effect.Id, player.Id);
                        message += "<br>You received the effect <b>" + effect.FriendlyName + "</b>.";
                    }

                    // spell gain
                    else if (q.RewardType == (int)QuestStatics.RewardType.Spell)
                    {
                        var spell = SkillStatics.GetStaticSkill(System.Convert.ToInt32(q.RewardAmount));
                        SkillProcedures.GiveSkillToPlayer(player.Id, spell.Id);
                        message += "<br>You learned the spell <b>" + spell.FriendlyName + "</b>.";
                    }
                }

                if (xpGain > 0)
                {
                    message += "<br>You earned <b>" + xpGain + "</b> XP.";
                }

                PlayerProcedures.GiveXP(player, xpGain);
            }

            // delete all of the player's quest variables
            var vars = QuestProcedures.GetAllQuestPlayerVariablesFromQuest(player.InQuest, player.Id).ToList();

            foreach (var v in vars)
            {
                questRepo.DeleteQuestPlayerVariable(v.Id);
            }

            return(message);
        }
Пример #9
0
        public static void SpawnAIPsychopaths(int count)
        {
            var rand = new Random();
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var turnNumber = PvPWorldStatProcedures.GetWorldTurnNumber();
            var botCount   = playerRepo.Players.Count(b => b.BotId == AIStatics.PsychopathBotId);

            for (var i = (0 + botCount); i < (count + botCount); i++)
            {
                var cmd = new CreatePlayer
                {
                    FirstName          = "Psychopath",
                    Location           = LocationsStatics.GetRandomLocationNotInDungeon(),
                    Health             = 100000,
                    MaxHealth          = 100000,
                    Mana               = 100000,
                    MaxMana            = 100000,
                    BotId              = AIStatics.PsychopathBotId,
                    UnusedLevelUpPerks = 0,
                    XP       = 0,
                    Money    = 100,
                    LastName = NameService.GetRandomLastName(),
                    Gender   = i % 2 == 1 ? PvPStatics.GenderMale : PvPStatics.GenderFemale,
                };


                var strength = GetPsychopathLevel(turnNumber);

                if (strength == 1)
                {
                    cmd.Level = 1;
                }
                else if (strength == 3)
                {
                    cmd.FirstName = "Fierce " + cmd.FirstName;
                    cmd.Level     = 3;
                }
                else if (strength == 5)
                {
                    cmd.FirstName = "Wrathful " + cmd.FirstName;
                    cmd.Level     = 5;
                }
                else if (strength == 7)
                {
                    cmd.FirstName = "Loathful " + cmd.FirstName;
                    cmd.Level     = 7;
                }
                else if (strength == 9)
                {
                    cmd.FirstName = "Soulless " + cmd.FirstName;
                    cmd.Level     = 9;
                }

                var idAndFormName = GetPsychoFormFromLevelAndSex(cmd.Level, cmd.Gender);
                cmd.FormSourceId = idAndFormName.Item1;

                // assert this name isn't already taken
                var ghost = playerRepo.Players.FirstOrDefault(p => p.FirstName == cmd.FirstName && p.LastName == cmd.LastName);
                if (ghost != null)
                {
                    continue;
                }

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

                // give this bot a random skill
                var eligibleSkills = SkillStatics.GetLearnablePsychopathSkills().ToList();

                double max       = eligibleSkills.Count;
                var    randIndex = Convert.ToInt32(Math.Floor(rand.NextDouble() * max));

                var skillToLearn = eligibleSkills.ElementAt(randIndex);
                SkillProcedures.GiveSkillToPlayer(id, skillToLearn.Id);

                // give this bot the Psychpathic perk
                if (strength == 1)
                {
                    EffectProcedures.GivePerkToPlayer(PsychopathicForLevelOneEffectSourceId, id);
                }
                else if (strength == 3)
                {
                    EffectProcedures.GivePerkToPlayer(PsychopathicForLevelThreeEffectSourceId, id);
                }
                else if (strength == 5)
                {
                    EffectProcedures.GivePerkToPlayer(PsychopathicForLevelFiveEffectSourceId, id);
                }
                else if (strength == 7)
                {
                    EffectProcedures.GivePerkToPlayer(PsychopathicForLevelSevenEffectSourceId, id);
                }
                else if (strength == 9)
                {
                    EffectProcedures.GivePerkToPlayer(PsychopathicForLevelNineEffectSourceId, id);
                }

                // give this psycho a new rune with some random chance it is a higher level than they are, to a max of level 13
                var random = new Random(Guid.NewGuid().GetHashCode());
                var roll   = random.NextDouble();

                if (roll < .1)
                {
                    strength += 4;
                }
                else if (roll < .3)
                {
                    strength += 2;
                }

                var quantity = Math.Floor(random.NextDouble() * 2) + 1; // 1 or 2

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

                var psychoEF = playerRepo.Players.FirstOrDefault(p => p.Id == id);
                psychoEF.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(psychoEF));
                playerRepo.SavePlayer(psychoEF);
            }
        }
Пример #10
0
        public static string CurseTransformOwner(Player player, Player owner, ItemDetail playerItem, bool isWhitelist)
        {
            var rand = new Random();
            var roll = rand.NextDouble() * 100;


            IInanimateXPRepository inanimateXpRepo = new EFInanimateXPRepository();
            var xp       = inanimateXpRepo.InanimateXPs.FirstOrDefault(x => x.OwnerId == player.Id);
            var gameTurn = PvPWorldStatProcedures.GetWorldTurnNumber();

            // assign the player inanimate XP based on turn building
            if (xp == null)
            {
                xp = new InanimateXP
                {
                    OwnerId             = player.Id,
                    Amount              = 0,
                    TimesStruggled      = -6 * player.Level,
                    LastActionTimestamp = DateTime.UtcNow,
                    LastActionTurnstamp = gameTurn - 1,
                };
            }

            double chanceOfSuccess = (gameTurn - xp.LastActionTurnstamp);

            ITFMessageRepository tfMessageRepo = new EFTFMessageRepository();
            var tf = tfMessageRepo.TFMessages.FirstOrDefault(t => t.FormSourceId == playerItem.ItemSource.CurseTFFormSourceId);

            var ownerSuccessMessage = "";
            var ownerFailureMessage = "";
            var playerMessage       = "";

            var newFormSourceId = -1;

            if (playerItem.ItemSource.CurseTFFormSourceId == null)
            {
                // No item-provided TF curse - reduce chance of transforming to a preset form
                chanceOfSuccess /= 4.0;
                newFormSourceId  = PvPStatics.DefaultTFCurseForms[rand.Next(PvPStatics.DefaultTFCurseForms.Length)];
            }
            else
            {
                // Regular TF curse - load its details
                newFormSourceId = playerItem.ItemSource.CurseTFFormSourceId.Value;

                if (playerItem.Owner.Gender == PvPStatics.GenderMale && !tf.CursedTF_Succeed_M.IsNullOrEmpty())
                {
                    ownerSuccessMessage = tf.CursedTF_Succeed_M;
                }
                else if (playerItem.Owner.Gender == PvPStatics.GenderFemale && !tf.CursedTF_Succeed_F.IsNullOrEmpty())
                {
                    ownerSuccessMessage = tf.CursedTF_Succeed_F;
                }
                else if (!tf.CursedTF_Succeed.IsNullOrEmpty())
                {
                    ownerSuccessMessage = tf.CursedTF_Succeed;
                }

                if (playerItem.Owner.Gender == PvPStatics.GenderMale && !tf.CursedTF_Fail_M.IsNullOrEmpty())
                {
                    ownerFailureMessage = tf.CursedTF_Fail_M;
                }
                else if (playerItem.Owner.Gender == PvPStatics.GenderFemale && !tf.CursedTF_Fail_F.IsNullOrEmpty())
                {
                    ownerFailureMessage = tf.CursedTF_Fail_F;
                }
                else if (!tf.CursedTF_Fail.IsNullOrEmpty())
                {
                    ownerFailureMessage = tf.CursedTF_Fail;
                }
            }


            // success; owner is transformed!
            if (roll < chanceOfSuccess)
            {
                IPlayerRepository playerRepo = new EFPlayerRepository();
                var newForm = FormStatics.GetForm(newFormSourceId);

                if (newForm.MobilityType == PvPStatics.MobilityFull)
                {
                    DomainRegistry.Repository.Execute(new ChangeForm
                    {
                        PlayerId     = playerItem.Owner.Id,
                        FormSourceId = newFormSourceId
                    });

                    var dbOwner = playerRepo.Players.FirstOrDefault(p => p.Id == playerItem.Owner.Id);
                    dbOwner.ReadjustMaxes(ItemProcedures.GetPlayerBuffs(dbOwner));
                    dbOwner.Mana -= dbOwner.MaxMana * .5M;
                    dbOwner.NormalizeHealthMana();
                    playerRepo.SavePlayer(dbOwner);

                    if (ownerSuccessMessage.IsNullOrEmpty())
                    {
                        ownerSuccessMessage = $"One of your items, {playerItem.FormerPlayer.FullName}, attempts to trigger a curse placed upon it.  Suddenly you are overwhelmed as you find yourself transformed into a {newForm.FriendlyName}!";
                    }
                    playerMessage = "Your subtle transformation curse overwhelms your owner, transforming them into a " + newForm.FriendlyName + "!";

                    PlayerLogProcedures.AddPlayerLog(playerItem.Owner.Id, ownerSuccessMessage, true);
                    LocationLogProcedures.AddLocationLog(owner.dbLocationName, "<b> " + owner.GetFullName() + " is suddenly transformed by " + playerItem.FormerPlayer.FullName + " the " + playerItem.ItemSource.FriendlyName + ", one of their belongings!</b>");
                }
            }


            // fail; owner is not transformed
            else
            {
                if (ownerFailureMessage.IsNullOrEmpty())
                {
                    ownerFailureMessage = "One of your items attempts to trigger a curse placed upon it, but it fails to transform you.";
                }
                playerMessage = "Unfortunately your subtle transformation curse fails to transform your owner.";

                PlayerLogProcedures.AddPlayerLog(owner.Id, ownerFailureMessage, true);
            }

            PlayerProcedures.AddAttackCount(player);
            return(playerMessage + GiveInanimateXP(player.MembershipId, isWhitelist));
        }
Пример #11
0
        public static string ReturnToAnimate(Player player, bool dungeonPenalty)
        {
            IInanimateXPRepository inanimXpRepo = new EFInanimateXPRepository();
            IItemRepository        itemRepo     = new EFItemRepository();

            var inanimXP = inanimXpRepo.InanimateXPs.FirstOrDefault(i => i.OwnerId == player.Id);

            var currentGameTurn = PvPWorldStatProcedures.GetWorldTurnNumber();

            if (inanimXP == null)
            {
                inanimXP = new InanimateXP
                {
                    OwnerId = player.Id,
                    Amount  = 0,

                    // set the initial times struggled proportional to how high of a level the player is
                    TimesStruggled      = -6 * player.Level,
                    LastActionTimestamp = DateTime.UtcNow,
                    LastActionTurnstamp = currentGameTurn - 1,
                };
            }

            double strugglebonus = currentGameTurn - inanimXP.LastActionTurnstamp;

            if (strugglebonus > TurnTimesStatics.GetItemMaxTurnsBuildup())
            {
                strugglebonus = TurnTimesStatics.GetItemMaxTurnsBuildup();
            }

            if (strugglebonus < 0)
            {
                strugglebonus = 0;
            }

            if (PvPStatics.ChaosMode)
            {
                strugglebonus = 100;
            }

            // increment the player's attack count.  Also decrease their player XP some.
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var dbPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == player.Id);

            dbPlayer.TimesAttackingThisUpdate++;

            var strugglesMade = Convert.ToDouble(GetStruggleChance(player, dungeonPenalty));

            var rand = new Random();
            var roll = rand.NextDouble() * 100;

            var dbPlayerItem = DomainRegistry.Repository.FindSingle(new GetItemByFormerPlayer {
                PlayerId = player.Id
            });

            if (dbPlayerItem == null)
            {
                return("Cannot struggle - no player item");
            }

            if (dbPlayerItem.Owner != null)
            {
                var owner = PlayerProcedures.GetPlayer(dbPlayerItem.Owner.Id);
                dbPlayer.dbLocationName = owner.dbLocationName;
            }

            var itemPlus = ItemStatics.GetStaticItem(dbPlayerItem.ItemSource.Id);

            if (roll < strugglesMade)
            {
                // assert that the covenant the victim is in is not too full to accept them back in
                if (dbPlayer.Covenant > 0)
                {
                    var victimCov = CovenantProcedures.GetCovenantViewModel((int)dbPlayer.Covenant).dbCovenant;
                    if (victimCov != null && CovenantProcedures.GetPlayerCountInCovenant(victimCov, true) >= PvPStatics.Covenant_MaximumAnimatePlayerCount)
                    {
                        return("Although you had enough energy to break free from your body as a " + itemPlus.FriendlyName + " and restore your regular body, you were unfortunately not able to break free because there is no more room in your covenant for any more animate mages.");
                    }
                }


                // if the item has an owner, notify them via a message.
                if (dbPlayerItem.Owner != null)
                {
                    var message = player.FirstName + " " + player.LastName + ", your " + itemPlus.FriendlyName + ", successfully struggles against your magic and reverses their transformation.  You can no longer claim them as your property, not unless you manage to turn them back again...";
                    PlayerLogProcedures.AddPlayerLog(dbPlayerItem.Owner.Id, message, true);
                }

                // change the player's form and mobility
                DomainRegistry.Repository.Execute(new ChangeForm
                {
                    PlayerId     = dbPlayer.Id,
                    FormSourceId = dbPlayer.OriginalFormSourceId
                });

                dbPlayer.ActionPoints               = TurnTimesStatics.GetActionPointLimit();
                dbPlayer.ActionPoints_Refill        = TurnTimesStatics.GetActionPointReserveLimit();
                dbPlayer.CleansesMeditatesThisRound = PvPStatics.MaxCleansesMeditatesPerUpdate;
                dbPlayer.TimesAttackingThisUpdate   = PvPStatics.MaxAttacksPerUpdate;

                // don't let the player spawn in the dungeon as they will have Back On Your Feet
                // and may not be meet the level and game mode requirements
                if (dbPlayer.IsInDungeon())
                {
                    dbPlayer.dbLocationName = LocationsStatics.GetRandomLocationNotInDungeon();
                }

                dbPlayer        = PlayerProcedures.ReadjustMaxes(dbPlayer, ItemProcedures.GetPlayerBuffs(dbPlayer));
                dbPlayer.Health = dbPlayer.MaxHealth / 3;
                dbPlayer.Mana   = dbPlayer.MaxHealth / 3;
                playerRepo.SavePlayer(dbPlayer);

                // drop any runes embedded on the player-item, or return them to the former owner's inventory
                DomainRegistry.Repository.Execute(new UnbembedRunesOnItem {
                    ItemId = dbPlayerItem.Id
                });

                // delete the item or animal that this player had turned into
                itemRepo.DeleteItem(dbPlayerItem.Id);

                // delete the inanimate XP item
                inanimXpRepo.DeleteInanimateXP(inanimXP.Id);

                // give the player the recovery buff
                EffectProcedures.GivePerkToPlayer(PvPStatics.Effect_BackOnYourFeetSourceId, dbPlayer);

                var msg = "You have managed to break free from your form as " + itemPlus.FriendlyName + " and occupy an animate body once again!";

                if (PvPStatics.ChaosMode)
                {
                    msg += $" [CHAOS MODE:  Struggle value overriden to {strugglebonus:0}% per struggle.]";
                }

                PlayerLogProcedures.AddPlayerLog(dbPlayer.Id, msg, false);

                StatsProcedures.AddStat(dbPlayer.MembershipId, StatsProcedures.Stat__SuccessfulStruggles, 1);

                return(msg);
            }

            // failure to break free; increase time struggles
            else
            {
                // raise the probability of success for next time somewhat proportion to how many turns they missed
                inanimXP.TimesStruggled     += Convert.ToInt32(strugglebonus);
                inanimXP.LastActionTimestamp = DateTime.UtcNow;
                inanimXP.LastActionTurnstamp = currentGameTurn;
                inanimXpRepo.SaveInanimateXP(inanimXP);

                playerRepo.SavePlayer(dbPlayer);

                if (dbPlayerItem.Owner != null)
                {
                    var message = $"{player.FirstName} {player.LastName}, your {itemPlus.FriendlyName}, struggles but fails to return to an animate form.  [Recovery chance next struggle:  {(int)GetStruggleChance(player, dungeonPenalty)}%]";
                    PlayerLogProcedures.AddPlayerLog(dbPlayerItem.Owner.Id, message, true);
                }

                PlayerLogProcedures.AddPlayerLog(dbPlayer.Id, "You struggled to return to a human form.", false);

                return($"Unfortunately you are not able to struggle free from your form as {itemPlus.FriendlyName}.  Keep trying and you might succeed later... [Recovery chance next struggle:  {(int)GetStruggleChance(player, dungeonPenalty)}%]");
            }
        }
Пример #12
0
        public static string GiveInanimateXP(string membershipId, bool isWhitelist)
        {
            IInanimateXPRepository inanimXpRepo = new EFInanimateXPRepository();
            IItemRepository        itemRep      = new EFItemRepository();

            // get the current level of this player based on what item they are
            var me = PlayerProcedures.GetPlayerFromMembership(membershipId);
            var inanimateMeHack = DomainRegistry.Repository.FindSingle(new GetItemByFormerPlayer {
                PlayerId = me.Id
            });
            var inanimateMe = itemRep.Items.FirstOrDefault(i => i.Id == inanimateMeHack.Id); // TODO: Replace with proper Command

            var currentGameTurn = PvPWorldStatProcedures.GetWorldTurnNumber();

            decimal xpGain = 0;

            // get the number of inanimate accounts under this IP
            IPlayerRepository playerRepo  = new EFPlayerRepository();
            decimal           playerCount = playerRepo.Players.Count(p => p.IpAddress == me.IpAddress && (p.Mobility == PvPStatics.MobilityInanimate || p.Mobility == PvPStatics.MobilityPet) && p.BotId == AIStatics.ActivePlayerBotId);

            if (playerCount == 0 || isWhitelist)
            {
                playerCount = 1;
            }

            var xp = inanimXpRepo.InanimateXPs.FirstOrDefault(i => i.OwnerId == me.Id);

            if (xp == null)
            {
                xp = new InanimateXP
                {
                    OwnerId             = me.Id,
                    Amount              = xpGain / playerCount,
                    TimesStruggled      = -6 * me.Level,
                    LastActionTimestamp = DateTime.UtcNow,
                    LastActionTurnstamp = currentGameTurn - 1,
                };

                if (me.Mobility == PvPStatics.MobilityInanimate)
                {
                    StatsProcedures.AddStat(me.MembershipId, StatsProcedures.Stat__InanimateXPEarned, (float)xpGain);
                }
                else if (me.Mobility == PvPStatics.MobilityPet)
                {
                    StatsProcedures.AddStat(me.MembershipId, StatsProcedures.Stat__PetXPEarned, (float)xpGain);
                }
            }
            else
            {
                double turnsSinceLastAction = currentGameTurn - xp.LastActionTurnstamp;

                if (turnsSinceLastAction > TurnTimesStatics.GetItemMaxTurnsBuildup())
                {
                    turnsSinceLastAction = TurnTimesStatics.GetItemMaxTurnsBuildup();
                }

                if (turnsSinceLastAction < 0)
                {
                    turnsSinceLastAction = 0;
                }

                xpGain += Convert.ToDecimal(turnsSinceLastAction) * InanimateXPStatics.XPGainPerInanimateAction;
                xpGain  = xpGain / playerCount;

                if (me.Mobility == PvPStatics.MobilityInanimate)
                {
                    StatsProcedures.AddStat(me.MembershipId, StatsProcedures.Stat__InanimateXPEarned, (float)xpGain);
                }
                else if (me.Mobility == PvPStatics.MobilityPet)
                {
                    StatsProcedures.AddStat(me.MembershipId, StatsProcedures.Stat__PetXPEarned, (float)xpGain);
                }

                xp.Amount             += xpGain;
                xp.TimesStruggled     -= 2 * Convert.ToInt32(turnsSinceLastAction);
                xp.LastActionTimestamp = DateTime.UtcNow;
                xp.LastActionTurnstamp = currentGameTurn;
            }

            var resultMessage = "  ";

            if (xp.Amount >= Convert.ToDecimal(ItemProcedures.GetXPRequiredForItemPetLevelup(inanimateMe.Level)))
            {
                xp.Amount -= Convert.ToDecimal(ItemProcedures.GetXPRequiredForItemPetLevelup(inanimateMe.Level));
                inanimateMe.Level++;
                itemRep.SaveItem(inanimateMe);

                resultMessage += $"  You have gained {xpGain:0.#} xp.  <b>Congratulations, you have gained a level!  Your owner will be so proud...</b>";

                var wearerMessage = "<span style='color: darkgreen'>" + me.FirstName + " " + me.LastName + ", currently your " + ItemStatics.GetStaticItem(inanimateMe.ItemSourceId).FriendlyName + ", has gained a level!  Treat them kindly and they might keep helping you out...</span>";

                // now we need to change the owner's max health or mana based on this leveling
                if (inanimateMe.OwnerId > 0)
                {
                    PlayerLogProcedures.AddPlayerLog((int)inanimateMe.OwnerId, wearerMessage, true);
                    var inanimateMePlus = ItemProcedures.GetItemViewModel(inanimateMe.Id);

                    if (inanimateMePlus.Item.HealthBonusPercent != 0.0M || inanimateMePlus.Item.ManaBonusPercent != 0.0M)
                    {
                        var myowner = playerRepo.Players.FirstOrDefault(p => p.Id == inanimateMe.OwnerId);

                        var healthChange = PvPStatics.Item_LevelBonusModifier * inanimateMePlus.Item.HealthBonusPercent;
                        var manaChange   = PvPStatics.Item_LevelBonusModifier * inanimateMePlus.Item.ManaBonusPercent;

                        myowner.MaxHealth += healthChange;
                        myowner.MaxMana   += manaChange;

                        if (myowner.MaxHealth < 1)
                        {
                            myowner.MaxHealth = 1;
                        }

                        if (myowner.MaxMana < 1)
                        {
                            myowner.MaxMana = 1;
                        }

                        if (myowner.Health > myowner.MaxHealth)
                        {
                            myowner.Health = myowner.MaxHealth;
                        }

                        if (myowner.Mana > myowner.MaxMana)
                        {
                            myowner.Mana = myowner.MaxMana;
                        }

                        playerRepo.SavePlayer(myowner);
                    }
                }
            }
            else
            {
                resultMessage = $"  You have gained {xpGain:0.#} xp.  ({xp.Amount:0.#}/{ItemProcedures.GetXPRequiredForItemPetLevelup(inanimateMe.Level):0.#} to next level).";
            }

            inanimXpRepo.SaveInanimateXP(xp);

            // lock the player into their fate if their inanimate XP gets too high
            if (xp.TimesStruggled <= TurnTimesStatics.GetStruggleXPBeforeItemPermanentLock() * .5 && xp.TimesStruggled > TurnTimesStatics.GetStruggleXPBeforeItemPermanentLock() && !inanimateMe.IsPermanent)
            {
                resultMessage += "  Careful, if you keep doing this you may find yourself stuck in your current form forever...";
            }

            if (xp.TimesStruggled <= TurnTimesStatics.GetStruggleXPBeforeItemPermanentLock() && !inanimateMe.IsPermanent)
            {
                inanimateMe.IsPermanent = true;
                itemRep.SaveItem(inanimateMe);
                DomainRegistry.Repository.Execute(new RemoveSoulbindingOnPlayerItems {
                    PlayerId = me.Id
                });
                DomainRegistry.Repository.Execute(new DropAllItems {
                    PlayerId = me.Id, IgnoreRunes = false
                });

                var formRepo = new EFDbStaticFormRepository();
                var form     = formRepo.DbStaticForms.FirstOrDefault(f => f.Id == me.FormSourceId);

                if (inanimateMe.OwnerId != null && form != null)
                {
                    PlayerLogProcedures.AddPlayerLog(inanimateMe.OwnerId.Value, $"{me.GetFullName()} has locked and is now unable to escape their form as your {form.FriendlyName}!", true);
                }

                PlayerLogProcedures.AddPlayerLog(me.Id, $"You have locked in your current form as a {form.FriendlyName}!", false);
                resultMessage += "  <b>You find the last of your old human self slip away as you permanently embrace your new form.</b>";
            }

            return(resultMessage);
        }