Пример #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 string MoveTo(Player bot, string locationDbName, int distance, Action <Player, string> playerEnteredTile = null)
        {
            var botLocation = bot.dbLocationName;

            if (botLocation == locationDbName)
            {
                return(botLocation);
            }

            var start = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == botLocation);
            var end   = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == locationDbName);

            var pathTiles = PathfindingProcedures.GetMovementPath(start, end);

            if (pathTiles.Count == 0)
            {
                return(botLocation);
            }

            var botName = bot.FirstName + " " + bot.LastName;

            var nextTileIndex = 0;
            var nextTile      = botLocation;
            var nextTileName  = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == nextTile).Name;

            var numberOfSteps = Math.Min(distance, pathTiles.Count);

            while (nextTileIndex < numberOfSteps)
            {
                var currentTile     = nextTile;
                var currentTileName = nextTileName;

                nextTile     = pathTiles[nextTileIndex++];
                nextTileName = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == nextTile).Name;

                LocationLogProcedures.AddLocationLog(currentTile, botName + " left toward " + nextTileName);
                LocationLogProcedures.AddLocationLog(nextTile, botName + " entered from " + currentTileName);

                if (playerEnteredTile != null)
                {
                    playerEnteredTile(bot, nextTile);
                }
            }

            return(nextTile);
        }
Пример #3
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);
        }
Пример #4
0
        public static List <Exception> RunPsychopathActions(WorldDetail worldDetail)
        {
            var rand = new Random(DateTime.Now.Millisecond);

            var errors = new List <Exception>();

            IPlayerRepository playerRepo = new EFPlayerRepository();


            //spawn in more bots if there are less than the default
            var botCount = playerRepo.Players.Count(b => b.BotId == AIStatics.PsychopathBotId && b.Mobility == PvPStatics.MobilityFull);

            if (botCount < PvPStatics.PsychopathDefaultAmount)
            {
                SpawnAIPsychopaths(PvPStatics.PsychopathDefaultAmount - botCount);
            }

            var bots = playerRepo.Players.Where(p => p.BotId == AIStatics.PsychopathBotId && p.Mobility == PvPStatics.MobilityFull).ToList();

            foreach (var bot in bots)
            {
                try
                {
                    // if bot is no longer fully animate or is null, skip them
                    if (bot == null || bot.Mobility != PvPStatics.MobilityFull)
                    {
                        continue;
                    }

                    bot.LastActionTimestamp = DateTime.UtcNow;

                    if (!EffectProcedures.PlayerHasActiveEffect(bot.Id, JokeShopProcedures.PSYCHOTIC_EFFECT))
                    {
                        #region drop excess items

                        var botItems = DomainRegistry.Repository.Find(new GetItemsOwnedByPsychopath {
                            OwnerId = bot.Id
                        }).ToList();

                        string[] itemTypes =
                        {
                            PvPStatics.ItemType_Hat,        PvPStatics.ItemType_Accessory, PvPStatics.ItemType_Pants,
                            PvPStatics.ItemType_Pet,        PvPStatics.ItemType_Shirt,     PvPStatics.ItemType_Shoes,
                            PvPStatics.ItemType_Underpants, PvPStatics.ItemType_Undershirt
                        };

                        foreach (var typeToDrop in itemTypes)
                        {
                            if (botItems.Count(i => i.ItemSource.ItemType == typeToDrop) > 1)
                            {
                                var dropList = botItems.Where(i => i.ItemSource.ItemType == typeToDrop).Skip(1);

                                foreach (var i in dropList)
                                {
                                    ItemProcedures.DropItem(i.Id);

                                    var name = "a";

                                    if (i.FormerPlayer != null)
                                    {
                                        name = "<b>" + i.FormerPlayer.FullName + "</b> the";
                                    }

                                    if (i.ItemSource.ItemType == PvPStatics.ItemType_Pet)
                                    {
                                        LocationLogProcedures.AddLocationLog(bot.dbLocationName,
                                                                             "<b>" + bot.GetFullName() + "</b> released " + name + " pet <b>" + i.ItemSource.FriendlyName + "</b> here.");
                                    }
                                    else
                                    {
                                        LocationLogProcedures.AddLocationLog(bot.dbLocationName,
                                                                             "<b>" + bot.GetFullName() + "</b> dropped " + name + " <b>" + i.ItemSource.FriendlyName + "</b> here.");
                                    }
                                }
                            }
                        }

                        #endregion
                    }

                    var botbuffs = ItemProcedures.GetPlayerBuffs(bot);

                    var meditates = 0;

                    // meditate if needed
                    if (bot.Mana < bot.MaxMana * .5M)
                    {
                        var manaroll = (int)Math.Floor(rand.NextDouble() * 4.0D);
                        for (var i = 0; i < manaroll; i++)
                        {
                            DomainRegistry.Repository.Execute(new Meditate
                            {
                                PlayerId   = bot.Id,
                                Buffs      = botbuffs,
                                NoValidate = true
                            });
                            meditates++;
                        }
                    }

                    // cleanse if needed, less if psycho has cleansed lately
                    if (bot.Health < bot.MaxHealth * .5M)
                    {
                        var healthroll = (int)Math.Floor(rand.NextDouble() * 4.0D);
                        for (var i = meditates; i < healthroll; i++)
                        {
                            DomainRegistry.Repository.Execute(new Cleanse
                            {
                                PlayerId   = bot.Id,
                                Buffs      = botbuffs,
                                NoValidate = true
                            });
                        }
                    }


                    var directive = AIDirectiveProcedures.GetAIDirective(bot.Id);

                    // the bot has an attack target, so go chase it
                    if (directive.State == "attack")
                    {
                        var myTarget = PlayerProcedures.GetPlayer(directive.TargetPlayerId);
                        var(mySkills, weakenSkill, inanimateSkill) = GetPsychopathSkills(bot);

                        // if the target is offline, no longer animate, in the dungeon, or in the same form as the spells' target, go into idle mode
                        if (PlayerProcedures.PlayerIsOffline(myTarget) ||
                            myTarget.Mobility != PvPStatics.MobilityFull ||
                            mySkills.IsEmpty() || inanimateSkill == null ||
                            myTarget.FormSourceId == inanimateSkill.StaticSkill.FormSourceId ||
                            myTarget.IsInDungeon() ||
                            myTarget.InDuel > 0 ||
                            myTarget.InQuest > 0)
                        {
                            AIDirectiveProcedures.SetAIDirective_Idle(bot.Id);
                        }

                        // the target is okay for attacking
                        else
                        {
                            // the bot must move to its target location.
                            if (myTarget.dbLocationName != bot.dbLocationName)
                            {
                                if (botbuffs.MoveActionPointDiscount() > -100 && CanMove(worldDetail, myTarget))
                                {
                                    var maxSpaces = NumPsychopathMoveSpaces(bot);
                                    var newplace  = MoveTo(bot, myTarget.dbLocationName, maxSpaces);
                                    bot.dbLocationName = newplace;
                                }
                            }

                            // if the bot is now in the same place as the target, attack away, so long as the target is online and animate
                            if (bot.dbLocationName == myTarget.dbLocationName &&
                                !PlayerProcedures.PlayerIsOffline(myTarget) &&
                                myTarget.Mobility == PvPStatics.MobilityFull &&
                                CanAttack(worldDetail, bot, myTarget)
                                )
                            {
                                playerRepo.SavePlayer(bot);

                                var numAttacks = Math.Min(3, (int)(bot.Mana / PvPStatics.AttackManaCost));
                                var complete   = false;
                                for (var attackIndex = 0; attackIndex < numAttacks && !complete; ++attackIndex)
                                {
                                    var skill = SelectPsychopathSkill(myTarget, mySkills, weakenSkill, rand);
                                    (complete, _) = AttackProcedures.Attack(bot, myTarget, skill);
                                }

                                if (complete)
                                {
                                    EquipDefeatedPlayer(bot, myTarget);
                                }
                            }
                        }
                    }

                    // the bot has no target, so wander and try to find new targets and attack them.
                    else
                    {
                        if (botbuffs.MoveActionPointDiscount() > -100)
                        {
                            var newplace = MoveTo(bot, LocationsStatics.GetRandomLocationNotInDungeon(), 5);
                            bot.dbLocationName = newplace;
                        }


                        // attack stage
                        var playersHere = playerRepo.Players.Where
                                              (p => p.dbLocationName == bot.dbLocationName && p.Mobility == PvPStatics.MobilityFull &&
                                              p.Id != bot.Id && p.BotId == AIStatics.PsychopathBotId && p.Level >= bot.Level).ToList();

                        // filter out offline players and Lindella
                        var onlinePlayersHere = playersHere.Where(p => !PlayerProcedures.PlayerIsOffline(p)).ToList();

                        if (onlinePlayersHere.Count > 0)
                        {
                            var roll   = Math.Floor(rand.NextDouble() * onlinePlayersHere.Count);
                            var victim = onlinePlayersHere.ElementAt((int)roll);
                            AIDirectiveProcedures.SetAIDirective_Attack(bot.Id, victim.Id);
                            playerRepo.SavePlayer(bot);

                            var(mySkills, weakenSkill, inanimateSkill) = GetPsychopathSkills(bot);
                            if (!mySkills.IsEmpty())
                            {
                                var numAttacks = Math.Min(3, (int)(bot.Mana / PvPStatics.AttackManaCost));
                                var complete   = false;
                                for (var attackIndex = 0; attackIndex < numAttacks && !complete; ++attackIndex)
                                {
                                    var skill = SelectPsychopathSkill(victim, mySkills, weakenSkill, rand);
                                    (complete, _) = AttackProcedures.Attack(bot, victim, skill);
                                }

                                if (complete)
                                {
                                    EquipDefeatedPlayer(bot, victim);
                                }
                            }
                        }
                    }

                    playerRepo.SavePlayer(bot);
                }
                catch (Exception e)
                {
                    errors.Add(e);
                }
            }

            return(errors);
        }
Пример #5
0
        public static string DoAnimalAction(string actionName, int animalPlayerId, int victimId)
        {
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var animalPlayer             = playerRepo.Players.FirstOrDefault(p => p.Id == animalPlayerId);

            var animalItem = DomainRegistry.Repository.FindSingle(new GetItemByFormerPlayer {
                PlayerId = animalPlayerId
            });

            var victim = playerRepo.Players.FirstOrDefault(p => p.Id == victimId);

            Player attackerOwner = null;

            if (animalItem.Owner != null)
            {
                attackerOwner = playerRepo.Players.FirstOrDefault(p => p.Id == animalItem.Owner.Id);
            }

            var here = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == animalPlayer.dbLocationName);


            var attackerPlus = PlayerProcedures.GetPlayerFormViewModel(animalPlayerId);

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

            var victimMessage   = "";
            var attackerMessage = "";
            var locationMessage = "";

            string victimPronoun;

            if (victim.Gender == PvPStatics.GenderMale)
            {
                victimPronoun = "his";
            }
            else
            {
                victimPronoun = "her";
            }

            if (actionName == "snarl")
            {
                victim.Mana -= 1;

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

                if (attackerOwner != null)
                {
                    victimMessage = "<span class='petActionBad'>" + animalPlayer.GetFullName() + ", a " + attackerPlus.Form.FriendlyName + " kept as a pet by " + attackerOwner.GetFullName() + ", snarls at you, slightly lowering your mana.</span>";
                }
                else
                {
                    victimMessage = "<span class='petActionBad'>" + animalPlayer.GetFullName() + ", a feral " + attackerPlus.Form.FriendlyName + " snarls at you, slightly lowering your mana.</span>";
                }

                attackerMessage = "You snarl at " + victim.GetFullName() + ", lowering " + victimPronoun + " mana slightly.";

                locationMessage = animalPlayer.GetFullName() + ", a " + attackerPlus.Form.FriendlyName + ", snarled at " + victim.GetFullName() + ".";
            }
            else if (actionName == "lick")
            {
                victim.Health += 1;

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

                if (attackerOwner != null)
                {
                    victimMessage = "<span class='petActionGood'>" + animalPlayer.GetFullName() + ", a " + attackerPlus.Form.FriendlyName + " kept as a pet by " + attackerOwner.FirstName + " " + attackerOwner.LastName + ", gently licks you, slightly raising your willpower.</span>";
                }
                else
                {
                    victimMessage = "<span class='petActionGood'>" + animalPlayer.GetFullName() + ", a feral " + attackerPlus.Form.FriendlyName + " gently licks you, slightly raising your willpower.</span>";
                }

                attackerMessage = "You gently lick " + victim.GetFullName() + ", raising " + victimPronoun + " willpower slightly.";

                locationMessage = animalPlayer.GetFullName() + ", a " + attackerPlus.Form.FriendlyName + ", licked " + victim.FirstName + " " + victim.LastName + ".";
            }

            else if (actionName == "nuzzle")
            {
                victim.Mana += 1;

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

                if (attackerOwner != null)
                {
                    victimMessage = "<span class='petActionGood'>" + animalPlayer.GetFullName() + ", a " + attackerPlus.Form.FriendlyName + " kept as a pet by " + attackerOwner.FirstName + " " + attackerOwner.LastName + ", gently nuzzles you, slightly raising your mana.</span>";
                }
                else
                {
                    victimMessage = "<span class='petActionGood'>" + animalPlayer.GetFullName() + ", a feral " + attackerPlus.Form.FriendlyName + " gently nuzzles you, slightly raising your mana.</span>";
                }

                attackerMessage = "You gently nuzzle " + victim.GetFullName() + ", raising " + victimPronoun + " mana slightly.";

                locationMessage = animalPlayer.GetFullName() + ", a " + attackerPlus.Form.FriendlyName + ", nuzzles " + victim.FirstName + " " + victim.LastName + ".";
            }

            if (actionName == "headbutt")
            {
                victim.Health -= 1;

                if (victim.Health < 0)
                {
                    victim.Health = 0;
                }

                if (attackerOwner != null)
                {
                    victimMessage = "<span class='petActionBad'>" + animalPlayer.GetFullName() + ", a " + attackerPlus.Form.FriendlyName + " kept as a pet by " + attackerOwner.GetFullName() + ", lightly headbutts you, slightly lowering your willpower.</span>";
                }
                else
                {
                    victimMessage = "<span class='petActionBad'>" + animalPlayer.GetFullName() + ", a feral " + attackerPlus.Form.FriendlyName + " lightly headbutts you, slightly lowering your willpower.</span>";
                }

                attackerMessage = "You headbutt " + victim.FirstName + " " + victim.LastName + ", lowering " + victimPronoun + " willpower slightly.";

                locationMessage = animalPlayer.GetFullName() + ", a " + attackerPlus.Form.FriendlyName + ", headbutted " + victim.FirstName + " " + victim.LastName + ".";
            }



            PlayerLogProcedures.AddPlayerLog(victim.Id, victimMessage, true);
            PlayerLogProcedures.AddPlayerLog(animalPlayer.Id, attackerMessage, false);
            LocationLogProcedures.AddLocationLog(here.dbName, locationMessage);

            animalPlayer.TimesAttackingThisUpdate++;
            playerRepo.SavePlayer(victim);
            playerRepo.SavePlayer(animalPlayer);

            return(attackerMessage);
        }
Пример #6
0
        public static (bool, string) Attack(Player attackingPlayer, Player attackedPlayer, SkillViewModel skillBeingUsed, bool timestamp = true)
        {
            var result = "";

            var attacker = PlayerProcedures.GetPlayer(attackingPlayer.Id);
            var victim   = PlayerProcedures.GetPlayer(attackedPlayer.Id);

            if (victim.Mobility != PvPStatics.MobilityFull ||
                attacker.Mobility != PvPStatics.MobilityFull ||
                victim.GameMode == (int)GameModeStatics.GameModes.Invisible ||
                attacker.GameMode == (int)GameModeStatics.GameModes.Invisible)
            {
                return(false, "");
            }

            var complete = false;
            var logs     = new LogBox();

            // all of our checks seem to be okay.  So let's lower the player's mana and action points
            PlayerProcedures.ChangePlayerActionMana(-PvPStatics.AttackCost, 0, -PvPStatics.AttackManaCost, attacker.Id, timestamp);

            PlayerProcedures.LogCombatTimestampsAndAddAttackCount(victim, attacker);

            var attackerFullName = attacker.GetFullName();
            var victimFullName   = victim.GetFullName();

            // if the spell is a curse, give the effect and that's all
            if (skillBeingUsed.StaticSkill.GivesEffectSourceId != null)
            {
                var effectBeingGiven = EffectStatics.GetDbStaticEffect(skillBeingUsed.StaticSkill.GivesEffectSourceId.Value);

                EffectProcedures.GivePerkToPlayer(skillBeingUsed.StaticSkill.GivesEffectSourceId.Value, victim);

                if (attacker.Gender == PvPStatics.GenderMale && !effectBeingGiven.AttackerWhenHit_M.IsNullOrEmpty())
                {
                    logs.AttackerLog += effectBeingGiven.AttackerWhenHit_M;
                }
                else if (attacker.Gender == PvPStatics.GenderFemale && !effectBeingGiven.AttackerWhenHit_F.IsNullOrEmpty())
                {
                    logs.AttackerLog += effectBeingGiven.AttackerWhenHit_F;
                }
                else
                {
                    logs.AttackerLog += effectBeingGiven.AttackerWhenHit;
                }

                if (!String.IsNullOrEmpty(logs.AttackerLog))
                {
                    logs.AttackerLog += "<br><br>";
                }

                logs.LocationLog  = "<span class='playerAttackNotification'>" + attackerFullName + " cursed " + victimFullName + " with " + skillBeingUsed.StaticSkill.FriendlyName + ".</span>";
                logs.AttackerLog += "You cursed " + victimFullName + " with " + skillBeingUsed.StaticSkill.FriendlyName + ".";
                logs.AttackerLog += "  (+1 XP)  ";
                logs.AttackerLog += PlayerProcedures.GiveXP(attacker, 1);
                logs.VictimLog    = effectBeingGiven.MessageWhenHit;
                logs.VictimLog   += "  <span class='playerAttackNotification'>" + attackerFullName + " cursed you with <b>" + skillBeingUsed.StaticSkill.FriendlyName + "</b>.</b></span>  ";
                result            = logs.AttackerLog;
            }

            // the spell is a regular attack
            else
            {
                logs.LocationLog = "<span class='playerAttackNotification'>" + attackerFullName + " cast " + skillBeingUsed.StaticSkill.FriendlyName + " against " + victimFullName + ".</span>";
                logs.AttackerLog = "You cast " + skillBeingUsed.StaticSkill.FriendlyName + " against " + victimFullName + ".  ";
                logs.VictimLog   = "<span class='playerAttackNotification'>" + attackerFullName + " cast " + skillBeingUsed.StaticSkill.FriendlyName + " against you.</span>  ";

                var meBuffs       = ItemProcedures.GetPlayerBuffs(attacker);
                var targetedBuffs = ItemProcedures.GetPlayerBuffs(victim);

                var rand          = new Random(Guid.NewGuid().GetHashCode());
                var basehitChance = rand.NextDouble() * 100;

                var meDmgExtra = meBuffs.SpellExtraHealthDamagePercent();

                var criticalMissPercentChance = PvPStatics.CriticalMissPercentChance - meBuffs.SpellMisfireChanceReduction();

                var criticalPercentChance = meBuffs.ExtraSkillCriticalPercent() + PvPStatics.CriticalHitPercentChance;
                var evasionPercentChance  = targetedBuffs.EvasionPercent() - meBuffs.EvasionNegationPercent();
                var evasionUpgrade        = false;
                var failedAttack          = false;

                // clamp modifiedEvasion at 50% max
                if (evasionPercentChance > 50)
                {
                    evasionPercentChance = 50;
                }

                // critical miss!  damage caster instead
                if (basehitChance < (double)criticalMissPercentChance)
                {
                    // check if there is a health damage aspect to this spell
                    if (skillBeingUsed.StaticSkill.HealthDamageAmount > 0)
                    {
                        var amountToDamage = skillBeingUsed.StaticSkill.HealthDamageAmount *
                                             (1 + meDmgExtra / 100);
                        PlayerProcedures.DamagePlayerHealth(attacker.Id, amountToDamage);
                        logs.AttackerLog += $"Misfire!  Your spell accidentally lowered your own willpower by {amountToDamage:N2}.  ";
                        logs.VictimLog   += $"Misfire!  {GetPronoun_HisHer(attacker.Gender)} spell accidentally lowered {GetPronoun_hisher(attacker.Gender)} own willpower by {amountToDamage:N2}.";
                        result           += logs.AttackerLog;
                    }
                    failedAttack = true;
                }
                // spell is evaded
                else if (basehitChance < (double)criticalMissPercentChance + (double)evasionPercentChance)
                {
                    // Check for a crit to upgrade the miss to a hit
                    var criticalHitChance = rand.NextDouble() * 100;
                    if (criticalHitChance < (double)criticalPercentChance)
                    {
                        evasionUpgrade = true;
                    }
                    else
                    {
                        logs.AttackerLog += victimFullName + " managed to leap out of the way of your spell.";
                        logs.VictimLog   += "You managed to leap out of the way " + attackerFullName + "'s spell.";
                        result            = logs.AttackerLog;
                        failedAttack      = true;
                    }
                }

                // not a  miss, so let's deal some damage, possibly
                if (!failedAttack)
                {
                    decimal criticalModifier = 1;

                    if (evasionUpgrade)
                    {
                        logs.AttackerLog += "<b>Piercing hit!</b>  ";
                        logs.VictimLog   += "<b>Piercing hit!</b>  ";
                    }
                    else if (rand.NextDouble() * 100 < (double)criticalPercentChance)
                    {
                        criticalModifier  = 2;
                        logs.AttackerLog += "<b>Critical hit!</b>  ";
                        logs.VictimLog   += "<b>Critical hit!</b>  ";
                    }

                    var initialVictimHealth = victim.Health;

                    // check if there is a health damage aspect to this spell
                    if (skillBeingUsed.StaticSkill.HealthDamageAmount > 0)
                    {
                        var targetProt = targetedBuffs.SpellHealthDamageResistance();

                        // calculator the modifier as extra attack - defense.      15 - 20 = -5 modifier
                        var willpowerDamageModifierFromBonuses = 1 + ((meDmgExtra - targetProt) / 100.0M);

                        // cap the modifier at at 50 % IF the target is a human
                        if (willpowerDamageModifierFromBonuses < .5M)
                        {
                            willpowerDamageModifierFromBonuses = .5M;
                        }

                        // cap the modifier at 200 % IF the target is a human
                        if (willpowerDamageModifierFromBonuses > 2 && victim.BotId == AIStatics.ActivePlayerBotId)
                        {
                            willpowerDamageModifierFromBonuses = 2;
                        }

                        var totalHealthDamage = skillBeingUsed.StaticSkill.HealthDamageAmount * willpowerDamageModifierFromBonuses * criticalModifier;

                        // make sure damage is never in the negatives (which would heal instead)
                        if (totalHealthDamage < 0)
                        {
                            totalHealthDamage = 0;
                        }

                        PlayerProcedures.DamagePlayerHealth(victim.Id, totalHealthDamage);

                        // even though it's been done in the db, change the player health here as well
                        victim.Health -= totalHealthDamage;


                        logs.AttackerLog += $"Your spell lowered {GetPronoun_hisher(victim.Gender)} willpower by {Math.Round(totalHealthDamage, 2)}.  ";
                        logs.VictimLog   += $"{GetPronoun_HisHer(attacker.Gender)} spell lowered your willpower by {Math.Round(totalHealthDamage, 2)}.  ";
                        result           += logs.AttackerLog;
                    }

                    // if this skill has any TF power, add energy and check for form change
                    if (skillBeingUsed.StaticSkill.TFPointsAmount > 0)
                    {
                        var TFEnergyDmg   = meBuffs.SpellExtraTFEnergyPercent();
                        var TFEnergyArmor = targetedBuffs.SpellTFEnergyDamageResistance();

                        // calculator the modifier as extra attack - defense.
                        var tfEnergyDamageModifierFromBonuses = 1 + ((TFEnergyDmg - TFEnergyArmor) / 100.0M);

                        // cap the modifier at at 50 % IF the target is a human
                        if (tfEnergyDamageModifierFromBonuses < .5M)
                        {
                            tfEnergyDamageModifierFromBonuses = .5M;
                        }

                        // cap the modifier at at 200 % IF the target is a human
                        if (tfEnergyDamageModifierFromBonuses > 2 && victim.BotId == AIStatics.ActivePlayerBotId)
                        {
                            tfEnergyDamageModifierFromBonuses = 2;
                        }

                        var totalTFEnergyModifier = criticalModifier * tfEnergyDamageModifierFromBonuses;

                        LogBox tfEnergyResult;
                        (complete, tfEnergyResult) = TFEnergyProcedures.AddTFEnergyToPlayer(victim, attacker, skillBeingUsed, totalTFEnergyModifier, initialVictimHealth);
                        logs.Add(tfEnergyResult);

                        result = logs.AttackerLog;
                    }
                }
            }

            LocationLogProcedures.AddLocationLog(attacker.dbLocationName, logs.LocationLog);
            PlayerLogProcedures.AddPlayerLog(attacker.Id, logs.AttackerLog, false);
            PlayerLogProcedures.AddPlayerLog(victim.Id, logs.VictimLog, true);

            DomainRegistry.AttackNotificationBroker.Notify(victim.Id, logs.VictimLog);

            // if this is a psycho-on-psycho battle, have a chance for the victim bot to switch targets to the attacker bot
            if (attacker.BotId == AIStatics.PsychopathBotId && victim.BotId == AIStatics.PsychopathBotId)
            {
                var rand         = new Random(Guid.NewGuid().GetHashCode());
                var botAggroRoll = rand.NextDouble();
                if (botAggroRoll < .08)
                {
                    AIDirectiveProcedures.SetAIDirective_Attack(victim.Id, attacker.Id);
                }
            }

            return(complete, result);
        }
Пример #7
0
        public static string SuddenDeathExplosion(Player attacker, Player victim, decimal damage)
        {
            IPlayerRepository playerREpo = new EFPlayerRepository();

            var attackerLocation = attacker.dbLocationName;
            var here             = LocationsStatics.LocationList.GetLocation.First(l => l.dbName == attackerLocation);

            var playersHere       = new List <Player>();
            var playersHereOnline = new List <Player>();

            if (attacker.GameMode == (int)GameModeStatics.GameModes.PvP)
            {
                playersHere = playerREpo.Players.Where(p => p.dbLocationName == attackerLocation &&
                                                       (p.GameMode == (int)GameModeStatics.GameModes.PvP || p.BotId < AIStatics.RerolledPlayerBotId) &&
                                                       p.Mobility == PvPStatics.MobilityFull &&
                                                       p.InDuel <= 0 &&
                                                       p.InQuest <= 0).ToList();
            }
            else if (attacker.GameMode == (int)GameModeStatics.GameModes.Protection || attacker.GameMode == (int)GameModeStatics.GameModes.Superprotection)
            {
                playersHere = playerREpo.Players.Where(p => p.dbLocationName == attackerLocation &&
                                                       p.BotId < AIStatics.RerolledPlayerBotId &&
                                                       p.Mobility == PvPStatics.MobilityFull &&
                                                       p.InDuel <= 0 &&
                                                       p.InQuest <= 0).ToList();
            }

            // filter out offline players as well as the attacker
            foreach (var p in playersHere)
            {
                if (!PlayerProcedures.PlayerIsOffline(p) && p.Id != attacker.Id)
                {
                    playersHereOnline.Add(p);
                }
            }

            foreach (var p in playersHereOnline)
            {
                p.Health -= damage;
                if (p.Health < 0)
                {
                    p.Health = 0;
                }
                playerREpo.SavePlayer(p);
                var message = "<span class='playerAttackNotification'>" + victim.GetFullName() + " convulses and shakes before exploding into a roiling tide of chaotic energies damaging you for " + damage + " along with " + (playersHereOnline.Count - 1) + " others.</span>";
                PlayerLogProcedures.AddPlayerLog(p.Id, message, true);
            }

            var logMessage = victim.FirstName + " " + victim.LastName + " exploded into a violent shower of chaotic energies.";

            LocationLogProcedures.AddLocationLog(attackerLocation, logMessage);

            var attackerMessage = "The explosion caused by " + victim.FirstName + " " + victim.LastName + " scattered violent energies throughout  " + here + ", lowering " + playersHereOnline.Count + " people's willpower by " + damage + " each.";

            PlayerLogProcedures.AddPlayerLog(attacker.Id, attackerMessage, false);

            // set the player's last action flag
            var dbAttacker = playerREpo.Players.First(p => p.Id == attacker.Id);

            dbAttacker.LastActionTimestamp = DateTime.UtcNow;
            playerREpo.SavePlayer(dbAttacker);

            return(attackerMessage);
        }
Пример #8
0
        public static string ThrowGrenade(Player attacker, decimal damage, string orbStrengthName)
        {
            IPlayerRepository playerREpo = new EFPlayerRepository();

            var attackerLocation = attacker.dbLocationName;
            var here             = LocationsStatics.LocationList.GetLocation.First(l => l.dbName == attackerLocation);

            var playersHere       = new List <Player>();
            var playersHereOnline = new List <Player>();

            if (attacker.GameMode == (int)GameModeStatics.GameModes.PvP)
            {
                playersHere = playerREpo.Players.Where(p => p.dbLocationName == attackerLocation &&
                                                       (p.GameMode == (int)GameModeStatics.GameModes.PvP || p.BotId < AIStatics.RerolledPlayerBotId) &&
                                                       p.Mobility == PvPStatics.MobilityFull &&
                                                       p.InDuel <= 0 &&
                                                       p.InQuest <= 0).ToList();
            }
            else if (attacker.GameMode == (int)GameModeStatics.GameModes.Protection || attacker.GameMode == (int)GameModeStatics.GameModes.Superprotection)
            {
                playersHere = playerREpo.Players.Where(p => p.dbLocationName == attackerLocation &&
                                                       p.BotId < AIStatics.RerolledPlayerBotId &&
                                                       p.Mobility == PvPStatics.MobilityFull &&
                                                       p.InDuel <= 0 &&
                                                       p.InQuest <= 0).ToList();
            }

            // filter out offline players as well as the attacker
            foreach (var p in playersHere)
            {
                if (!PlayerProcedures.PlayerIsOffline(p) && p.Id != attacker.Id)
                {
                    playersHereOnline.Add(p);
                }
            }

            foreach (var p in playersHereOnline)
            {
                p.Health -= damage;
                if (p.Health < 0)
                {
                    p.Health = 0;
                }
                playerREpo.SavePlayer(p);
                var message = "<span class='playerAttackNotification'>" + attacker.GetFullName() + " threw a " + orbStrengthName + " Submissiveness Splash Orb at " + here.Name + ", lowering your willpower by " + damage + " along with " + (playersHereOnline.Count - 1) + " others.</span>";
                PlayerLogProcedures.AddPlayerLog(p.Id, message, true);
            }

            var logMessage = attacker.FirstName + " " + attacker.LastName + " threw a Submissiveness Splash Orb here.";

            LocationLogProcedures.AddLocationLog(attackerLocation, logMessage);

            var attackerMessage = "You threw a " + orbStrengthName + " Submissiveness Splash Orb at " + here.Name + ", lowering " + playersHereOnline.Count + " people's willpower by " + damage + " each.";

            PlayerLogProcedures.AddPlayerLog(attacker.Id, attackerMessage, false);

            // set the player's last action flag, combat time
            var dbAttacker = playerREpo.Players.First(p => p.Id == attacker.Id);

            dbAttacker.LastActionTimestamp = DateTime.UtcNow;
            dbAttacker.LastCombatTimestamp = DateTime.UtcNow;
            dbAttacker.TimesAttackingThisUpdate++;
            playerREpo.SavePlayer(dbAttacker);


            return(attackerMessage);
        }
        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));
        }