예제 #1
0
        public void should_move_player_when_takes_bus()
        {
            var cmd = new TakeBus {
                playerId = player.Id, destination = LocationsStatics.STREET_160_SUNNYGLADE_DRIVE
            };

            DomainRegistry.Repository.Execute(cmd);

            player = DataContext.AsQueryable <Player>().First(p => p.Id == player.Id);
            Assert.That(player.Money, Is.EqualTo(970));
            Assert.That(player.ActionPoints, Is.EqualTo(TurnTimesStatics.GetActionPointReserveLimit() - 3));
            Assert.That(player.Location, Is.EqualTo(LocationsStatics.STREET_160_SUNNYGLADE_DRIVE));
            Assert.That(player.PlayerLogs.First().Message,
                        Is.EqualTo(
                            "You took the bus from <b>Street: 270 W. 9th Avenue</b> to <b>Street: 160 Sunnyglade Drive</b> for <b>30</b> Arpeyjis."));

            Assert.That(
                DataContext.AsQueryable <LocationLog>()
                .First(l => l.dbLocationName == LocationsStatics.STREET_270_WEST_9TH_AVE).Message,
                Is.EqualTo("John Doe got on a bus headed toward Street: 160 Sunnyglade Drive.")); // Moved from
            Assert.That(
                DataContext.AsQueryable <LocationLog>()
                .First(l => l.dbLocationName == LocationsStatics.STREET_160_SUNNYGLADE_DRIVE).Message,
                Is.EqualTo("John Doe arrived via bus from Street: 270 W. 9th Avenue.")); // Moved to
        }
예제 #2
0
 public PlayerBuilder()
 {
     Instance = Create();
     With(u => u.Id, 3);
     With(u => u.Mobility, PvPStatics.MobilityFull);
     With(u => u.Location, LocationsStatics.STREET_70_EAST_9TH_AVE);
     With(p => p.ActionPoints, TurnTimesStatics.GetActionPointLimit());
     With(p => p.ActionPoints_Refill, TurnTimesStatics.GetActionPointReserveLimit());
     With(p => p.FirstName, "John");
     With(p => p.LastName, "Doe");
     With(p => p.LastActionTimestamp, DateTime.UtcNow.AddMinutes(-10));
     With(p => p.LastCombatAttackedTimestamp, DateTime.UtcNow.AddHours(-1));
     With(p => p.LastCombatTimestamp, DateTime.UtcNow.AddHours(-1));
     With(p => p.BotId, AIStatics.ActivePlayerBotId);
     With(p => p.Health, 1000);
     With(p => p.MaxHealth, 1000);
     With(p => p.Mana, 210);
     With(p => p.MaxMana, 210);
     With(p => p.GameMode, (int)GameModeStatics.GameModes.Protection);
     With(p => p.XP, 0);
     With(p => p.Level, 1);
     With(p => p.Gender, PvPStatics.GenderMale);
     With(p => p.OnlineActivityTimestamp, DateTime.Now);
     With(p => p.TFEnergies, new List <TFEnergy>());
     With(p => p.TFEnergiesCast, new List <TFEnergy>());
     With(p => p.PlayerLogs, new List <PlayerLog>());
     With(p => p.Items, new List <TT.Domain.Items.Entities.Item>());
     With(p => p.ShoutsRemaining, 1);
 }
        public static string TeleportToQuest(Player player, Random rand = null)
        {
            var lastAttackTimeAgo = Math.Abs(DateTime.UtcNow.Subtract(player.GetLastCombatTimestamp()).TotalMinutes);

            if (lastAttackTimeAgo < TurnTimesStatics.GetMinutesSinceLastCombatBeforeQuestingOrDuelling())
            {
                return(null);
            }

            var quests = QuestProcedures.GetAllAvailableQuestsForPlayer(player, PvPWorldStatProcedures.GetWorldTurnNumber());

            if (quests == null || !quests.Any())
            {
                return(null);
            }

            rand = rand ?? new Random();
            var index = rand.Next(quests.Count());
            var quest = quests.ToArray()[index];

            if (!Teleport(player, quest.dbName, rand.Next(2) == 0))
            {
                return(null);
            }

            return($"You notice a gold chalice on the shelf, its engraving obscured by dirt.  You decide to blow the dust off and a cloud fills the room.  A frail man with a long white beard and crooked staff emerges from the mist.  \"So, it's a quest you seek?\" comes his shrill, wheezing voice.  \"Well, I have just the thing.  Seek out your victory, young mage.\"  He hands you a scroll.  At the top it is written <b>{quest.Name}</b>.  As you take it you feel yourself transported to a far-off place...");
        }
        public static string TeleportToDungeon(Player player, int meanness, Random rand = null)
        {
            if (!PlayerProcedures.CheckAllowedInDungeon(player, out _))
            {
                return(null);
            }

            var lastAttackTimeAgo = Math.Abs(DateTime.UtcNow.Subtract(player.GetLastCombatTimestamp()).TotalMinutes);

            if (lastAttackTimeAgo < TurnTimesStatics.GetMinutesSinceLastCombatBeforeQuestingOrDuelling())
            {
                return(null);
            }

            var location = LocationsStatics.GetRandomLocation_InDungeon();

            rand = rand ?? new Random();

            if (!Teleport(player, location, rand.Next(2) == 0))
            {
                return(null);
            }

            if (meanness % 2 == 1)
            {
                ResetCombatTimer(player);
            }

            if (meanness >= 2)
            {
                CharacterPrankProcedures.GiveEffect(player, JokeShopProcedures.ROOT_EFFECT);
            }

            return("You feel the room start to shake and shimmer, parts of the shop fading away as it is pulled between realms.  The shelves rattle ever more violently and you try and take shelter under the counter.  But the shop has other ideas and the floor gives way, leaving you tumbling through the air just as the store flickers out of this plane.  That's the last thing you remember.  Nursing a headache, with a bleary blink of your eyes your surroundings slowly come into focus.  You've landed in the deepest depths of the dungeon!");
        }
예제 #5
0
        internal static void ActOnInstinct(List <int> playersToControl, Random rand = null)
        {
            if (playersToControl == null || playersToControl.IsEmpty())
            {
                return;
            }

            rand = rand ?? new Random();
            var cutoff = DateTime.UtcNow.AddMinutes(-TurnTimesStatics.GetOfflineAfterXMinutes());

            IPlayerRepository playerRepo = new EFPlayerRepository();
            var activePlayers            = playerRepo.Players
                                           .Where(p => p.LastActionTimestamp >= cutoff &&
                                                  p.Mobility == PvPStatics.MobilityFull &&
                                                  p.InDuel <= 0 &&
                                                  p.InQuest <= 0 &&
                                                  p.BotId == AIStatics.ActivePlayerBotId &&
                                                  !p.dbLocationName.StartsWith("dungeon_"))
                                           .Select(p => new InstinctData {
                Id = p.Id, FormSourceId = p.FormSourceId, dbLocationName = p.dbLocationName
            })
                                           .ToList();

            var mcPlayers   = activePlayers.Where(p => playersToControl.Any(victim => p.Id == victim));
            var freePlayers = activePlayers.Where(p => !playersToControl.Any(victim => p.Id == victim));

            (mcPlayers, freePlayers) = SheepActions(playerRepo, mcPlayers, freePlayers, rand);
            (mcPlayers, freePlayers) = DogActions(playerRepo, mcPlayers, freePlayers, rand);
            (mcPlayers, freePlayers) = CatActions(playerRepo, mcPlayers, freePlayers, rand);
            mcPlayers = MaidActions(playerRepo, mcPlayers, rand);
            mcPlayers = StripperActions(playerRepo, mcPlayers, rand);
            mcPlayers = GhostActions(playerRepo, mcPlayers, rand);
        }
예제 #6
0
        public void Should_not_allow_action_point_refills_greater_than_max()
        {
            cmd.ActionPoints_Refill = TurnTimesStatics.GetActionPointReserveLimit() + 1;

            Assert.That(() => Repository.Execute(cmd),
                        Throws.TypeOf <DomainException>().With.Message
                        .EqualTo($"ActionPoints_Refill must be less than {TurnTimesStatics.GetActionPointReserveLimit()}"));
        }
        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);
        }
예제 #8
0
        /// <summary>
        /// Return a list of all the eligible players in a location for Narcissa to attack
        /// </summary>
        /// <param name="player">Narciss</param>
        /// <returns></returns>
        private static List <Player> GetEligibleTargetsInLocation(Player player)
        {
            var cutoff      = DateTime.UtcNow.AddMinutes(-TurnTimesStatics.GetOfflineAfterXMinutes());
            var playersHere = PlayerProcedures.GetPlayersAtLocation(player.dbLocationName).Where(m => m.Mobility == PvPStatics.MobilityFull &&
                                                                                                 m.Id != player.Id &&
                                                                                                 m.BotId >= AIStatics.PsychopathBotId &&
                                                                                                 m.LastActionTimestamp > cutoff &&
                                                                                                 m.InDuel <= 0 &&
                                                                                                 m.InQuest <= 0).ToList();

            return(playersHere);
        }
예제 #9
0
        /// <summary>
        /// Return the tile of the map which has the most targets that Narcissa is allowed to transform
        /// </summary>
        /// <returns>dbName of location found</returns>
        private static string GetLocationWithMostEligibleTargets()
        {
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var cutoff = DateTime.UtcNow.AddMinutes(-TurnTimesStatics.GetOfflineAfterXMinutes());
            IEnumerable <string> locs = playerRepo.Players.Where(p => p.Mobility == PvPStatics.MobilityFull &&
                                                                 p.LastActionTimestamp > cutoff &&
                                                                 p.FormSourceId != GreatFaeFormSourceId &&
                                                                 !p.dbLocationName.Contains("dungeon_") &&
                                                                 p.InDuel <= 0 &&
                                                                 p.InQuest <= 0).GroupBy(p => p.dbLocationName).OrderByDescending(p => p.Count()).Select(p => p.Key);

            return(locs.FirstOrDefault() ?? "fairygrove_entrance"); // default to fairygrove entrance if, for some reason, 0 valid targets exist
        }
예제 #10
0
        /// <summary>
        /// Have the player cleanse, restoring some willpower and reduce TF Energies, modified by the player's buffs
        /// </summary>
        /// <param name="buffs">Player's buffs</param>
        /// <returns>Cleanse amount</returns>
        public string Cleanse(BuffBox buffs)
        {
            CleansesMeditatesThisRound++;
            ActionPoints       -= PvPStatics.CleanseCost;
            Mana               -= PvPStatics.CleanseManaCost;
            LastActionTimestamp = DateTime.UtcNow;

            var result = "";
            var cleanseBonusTFEnergyRemovalPercent = buffs.CleanseExtraTFEnergyRemovalPercent() + PvPStatics.CleanseTFEnergyPercentDecrease;
            var cleanseWPRestore = PvPStatics.CleanseHealthRestoreBase + buffs.CleanseExtraHealth();
            var outOfCombat      = false;

            //  Increase the rate of cleansing outside of combat
            var lastAttackTimeAgo = Math.Abs(Math.Floor(GetLastCombatTimestamp().Subtract(DateTime.UtcNow).TotalSeconds));

            if (lastAttackTimeAgo > 3 * TurnTimesStatics.GetTurnLengthInSeconds())
            {
                outOfCombat = true;
            }

            if (cleanseWPRestore <= 0)
            {
                result = "You try to cleanse, but due to the magical effects on your body you fail to restore any willpower.";
            }
            else
            {
                if (outOfCombat)
                {
                    AddHealth(cleanseWPRestore * 3);
                    result = $"You take your time cleansing yourself, restoring {cleanseWPRestore * 3:#} willpower.";
                }
                else
                {
                    AddHealth(cleanseWPRestore);
                    result = $"You quickly cleanse, restoring {cleanseWPRestore:#} willpower.";
                }
            }

            if (cleanseBonusTFEnergyRemovalPercent > 0)
            {
                CleanseTFEnergies(buffs);
            }

            if (BotId == AIStatics.ActivePlayerBotId)
            {
                var location = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == Location);
                AddLog($"You cleansed at {location.Name}.", false);
            }

            return(result);
        }
예제 #11
0
        private static string GetLocationWithMostEligibleTargets()
        {
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var cutoff = DateTime.UtcNow.AddMinutes(-TurnTimesStatics.GetOfflineAfterXMinutes());
            IEnumerable <string> locs = playerRepo.Players.Where(p => p.Mobility == PvPStatics.MobilityFull &&
                                                                 p.LastActionTimestamp > cutoff &&
                                                                 p.FormSourceId != RegularBimboFormSourceId &&
                                                                 !p.dbLocationName.Contains("dungeon_") &&
                                                                 p.InDuel <= 0 &&
                                                                 p.InQuest <= 0)
                                        .GroupBy(p => p.dbLocationName).OrderByDescending(p => p.Count()).Select(p => p.Key).ToList();

            return(locs.First());
        }
예제 #12
0
 public void Init()
 {
     player = new PlayerBuilder()
              .With(p => p.FirstName, "John")
              .With(p => p.LastName, "Doe")
              .With(n => n.Id, 1)
              .With(p => p.User, new UserBuilder().BuildAndSave())
              .With(p => p.Money, 1000)
              .With(p => p.Mobility, PvPStatics.MobilityFull)
              .With(p => p.ActionPoints, TurnTimesStatics.GetActionPointReserveLimit())
              .With(p => p.Location, LocationsStatics.STREET_270_WEST_9TH_AVE)
              .With(p => p.LastCombatTimestamp, DateTime.UtcNow.AddHours(-3))
              .BuildAndSave();
 }
예제 #13
0
        private static List <Player> GetEligibleTargetsInLocation(string location, Player attacker)
        {
            var cutoff      = DateTime.UtcNow.AddMinutes(-TurnTimesStatics.GetOfflineAfterXMinutes());
            var playersHere = PlayerProcedures.GetPlayersAtLocation(location).Where(m => m.Mobility == PvPStatics.MobilityFull &&
                                                                                    m.Id != attacker.Id &&
                                                                                    m.FormSourceId != RegularBimboFormSourceId &&
                                                                                    m.BotId >= AIStatics.PsychopathBotId &&
                                                                                    m.LastActionTimestamp > cutoff &&
                                                                                    m.BotId != AIStatics.BimboBossBotId &&
                                                                                    m.InDuel <= 0 &&
                                                                                    m.InQuest <= 0).ToList();

            return(playersHere);
        }
예제 #14
0
        public static string UseFurniture(int furnitureId, Player user)
        {
            IFurnitureRepository furnRepo = new EFFurnitureRepository();
            var dbFurniture = furnRepo.Furnitures.FirstOrDefault(f => f.Id == furnitureId);

            dbFurniture.LastUseTimestamp = DateTime.UtcNow;
            dbFurniture.LastUsersIds     = user.Id.ToString();
            furnRepo.SaveFurniture(dbFurniture);

            var furnitureStatic = furnRepo.DbStaticFurniture.FirstOrDefault(f => f.dbType == dbFurniture.dbType);

            var logMessage = "<b>" + user.GetFullName() + "</b> used <b>" + dbFurniture.HumanName + "</b>.";

            CovenantProcedures.WriteCovenantLog(logMessage, (int)user.Covenant, false);

            // furniture gives AP reserve bonus
            if (furnitureStatic.APReserveRefillAmount > 0)
            {
                IPlayerRepository playerRepo = new EFPlayerRepository();
                var dbPlayer = playerRepo.Players.FirstOrDefault(p => p.Id == user.Id);
                dbPlayer.ActionPoints_Refill += furnitureStatic.APReserveRefillAmount;
                if (dbPlayer.ActionPoints_Refill > TurnTimesStatics.GetActionPointReserveLimit())
                {
                    dbPlayer.ActionPoints_Refill = TurnTimesStatics.GetActionPointReserveLimit();
                }
                dbPlayer.LastActionTimestamp = DateTime.UtcNow;
                playerRepo.SavePlayer(dbPlayer);

                return("You used " + dbFurniture.HumanName + ", a human voluntarily transformed into furniture and leased by your covenant, and gained " + furnitureStatic.APReserveRefillAmount + " reserve action points.");
            }

            // furniture gives effect
            else if (furnitureStatic.GivesEffectSourceId != null)
            {
                EffectProcedures.GivePerkToPlayer(furnitureStatic.GivesEffectSourceId.Value, user);
                PlayerProcedures.SetTimestampToNow(user);
                return("You used " + dbFurniture.HumanName + ", a human voluntarily transformed into furniture and leased by your covenant, and gained the " + EffectStatics.GetDbStaticEffect(furnitureStatic.GivesEffectSourceId.Value).FriendlyName + " effect.");
            }

            //furniture gives item
            else if (furnitureStatic.GivesItemSourceId != null)
            {
                ItemProcedures.GiveNewItemToPlayer(user, furnitureStatic.GivesItemSourceId.Value);
                PlayerProcedures.SetTimestampToNow(user);
                var itemGained = ItemStatics.GetStaticItem(furnitureStatic.GivesItemSourceId.Value);
                return("You used " + dbFurniture.HumanName + ", a human voluntarily transformed into furniture and leased by your covenant, gaining a " + itemGained.FriendlyName + ".");
            }

            return("ERROR");
        }
예제 #15
0
        public string Meditate(BuffBox buffs)
        {
            CleansesMeditatesThisRound++;
            ActionPoints       -= PvPStatics.MeditateCost;
            LastActionTimestamp = DateTime.UtcNow;

            var result = "";
            var meditateManaRestore = PvPStatics.MeditateManaRestoreBase + buffs.MeditationExtraMana();
            var outOfCombat         = false;

            //  Increase the rate of meditation outside of combat
            var lastAttackTimeAgo = Math.Abs(Math.Floor(GetLastCombatTimestamp().Subtract(DateTime.UtcNow).TotalSeconds));

            if (lastAttackTimeAgo > 3 * TurnTimesStatics.GetTurnLengthInSeconds())
            {
                outOfCombat = true;
            }

            if (meditateManaRestore < 0)
            {
                result = "You try to meditate, but due to the magical effects on your body you fail to restore any mana.";
            }
            else
            {
                if (outOfCombat)
                {
                    AddMana(meditateManaRestore * 3);
                    result = $"You take your time meditating, restoring {meditateManaRestore * 3:#} mana.";
                }
                else
                {
                    AddMana(meditateManaRestore);
                    result = $"You quickly meditate, restoring {meditateManaRestore:#} mana.";
                }
            }

            if (BotId == AIStatics.ActivePlayerBotId)
            {
                var location = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == Location);
                AddLog($"You meditated at {location.Name}.", false);
            }

            return(result);
        }
예제 #16
0
        /// <summary>
        /// Removes a percentage of TF energy that this player has, determined by the stats passed in
        /// </summary>
        /// <param name="buffs">Buffs owned by the player</param>
        public void CleanseTFEnergies(BuffBox buffs)
        {
            var cleansePercentage = buffs.CleanseExtraTFEnergyRemovalPercent() + PvPStatics.CleanseTFEnergyPercentDecrease;


            //  Increase the rate of TFE cleansing outside of combat
            var lastAttackTimeAgo = Math.Abs(Math.Floor(GetLastCombatTimestamp().Subtract(DateTime.UtcNow).TotalSeconds));

            if (lastAttackTimeAgo > 3 * TurnTimesStatics.GetTurnLengthInSeconds())
            {
                cleansePercentage = (cleansePercentage * 5);
            }

            foreach (var energy in TFEnergies)
            {
                var newValue = energy.Amount - cleansePercentage;
                energy.SetAmount(newValue);
            }
        }
예제 #17
0
        private static string GetRichestPlayerIds()
        {
            IPlayerRepository playerRepo = new EFPlayerRepository();
            var cutoff            = DateTime.UtcNow.AddMinutes(-TurnTimesStatics.GetOfflineAfterXMinutes());
            IEnumerable <int> ids = playerRepo.Players.Where(p => p.Mobility == PvPStatics.MobilityFull &&
                                                             p.BotId >= AIStatics.PsychopathBotId &&
                                                             p.OnlineActivityTimestamp >= cutoff &&
                                                             !p.dbLocationName.Contains("dungeon_") &&
                                                             p.InDuel <= 0 &&
                                                             p.InQuest <= 0).OrderByDescending(p => p.Money).Take(20).Select(p => p.Id);

            var output = "";

            foreach (var s in ids)
            {
                output += s.ToString() + ";";
            }

            return(output);
        }
예제 #18
0
        public void Should_throw_exception_if_player_cannot_afford_ticket()
        {
            player = new PlayerBuilder()
                     .With(n => n.Id, 6)
                     .With(p => p.User, new UserBuilder().BuildAndSave())
                     .With(p => p.Money, 3)
                     .With(p => p.Mobility, PvPStatics.MobilityFull)
                     .With(p => p.ActionPoints, TurnTimesStatics.GetActionPointReserveLimit())
                     .With(p => p.Mobility, PvPStatics.MobilityFull)
                     .With(p => p.Location, LocationsStatics.STREET_270_WEST_9TH_AVE)
                     .With(p => p.LastCombatTimestamp, DateTime.UtcNow.AddHours(-3))
                     .BuildAndSave();

            var cmd = new TakeBus {
                playerId = player.Id, destination = LocationsStatics.STREET_160_SUNNYGLADE_DRIVE
            };

            Assert.That(() => Repository.Execute(cmd),
                        Throws.TypeOf <DomainException>().With.Message.EqualTo("You can't afford this bus ticket!"));
        }
예제 #19
0
 public override void SetUp()
 {
     base.SetUp();
     player = new Player
     {
         dbLocationName              = "location",
         Mobility                    = PvPStatics.MobilityFull,
         Gender                      = PvPStatics.GenderMale,
         LastCombatTimestamp         = DateTime.UtcNow.AddYears(-1),
         LastCombatAttackedTimestamp = DateTime.UtcNow.AddYears(-1),
         BotId               = AIStatics.ActivePlayerBotId,
         FirstName           = "FirstName",
         LastName            = "Lastname",
         Level               = 1,
         ActionPoints        = TurnTimesStatics.GetActionPointLimit(),
         Id                  = 1,
         LastActionTimestamp = DateTime.UtcNow.AddYears(-1),
         GameMode            = 0,
         Health              = 100,
         MaxHealth           = 100,
         Mana                = 100,
         MaxMana             = 100,
     };
     questStart = new QuestStart
     {
         RequiredGender    = (int)QuestStatics.Gender.Any,
         PrerequisiteQuest = 0,
         IsLive            = true,
         Location          = "location",
         Id            = fakeTestId,
         MinStartLevel = 0,
         MaxStartLevel = 99999,
         MinStartTurn  = 0,
         MaxStartTurn  = 99999,
         Name          = "TestQuest",
         StartState    = 1
     };
     turnNumber          = 2000;
     questPlayerStatuses = new List <QuestPlayerStatus>();
 }
예제 #20
0
        public void Init()
        {
            var item1 = new ItemBuilder()
                        .With(i => i.dbLocationName, LocationsStatics.STREET_230_SUNNYGLADE_DRIVE)
                        .With(i => i.ItemSource, new ItemSourceBuilder()
                              .With(i => i.ItemType, PvPStatics.ItemType_Pants)
                              .BuildAndSave())
                        .BuildAndSave();

            var item2 = new ItemBuilder()
                        .With(i => i.dbLocationName, LocationsStatics.STREET_230_SUNNYGLADE_DRIVE)
                        .With(i => i.ItemSource, new ItemSourceBuilder()
                              .With(i => i.ItemType, PvPStatics.ItemType_Pet)
                              .BuildAndSave())
                        .BuildAndSave();

            items = new List <Item> {
                item1, item2
            };

            stats = new List <Stat>
            {
                new StatBuilder().With(t => t.AchievementType, StatsProcedures.Stat__TimesMoved).With(t => t.Amount, 88).BuildAndSave()
            };

            player = new PlayerBuilder()
                     .With(p => p.Id, 50)
                     .With(p => p.ActionPoints, TurnTimesStatics.GetActionPointReserveLimit())
                     .With(p => p.User, new UserBuilder()
                           .With(u => u.Id, "abcde")
                           .With(u => u.Stats, stats)
                           .BuildAndSave())
                     .With(p => p.Items, items)
                     .With(p => p.Location, LocationsStatics.STREET_200_MAIN_STREET)
                     .With(p => p.Mobility, PvPStatics.MobilityFull)
                     .BuildAndSave();

            destination = "coffee_shop_patio";
        }
예제 #21
0
        public void can_move_as_animal()
        {
            player = new PlayerBuilder()
                     .With(p => p.Id, 55)
                     .With(p => p.ActionPoints, TurnTimesStatics.GetActionPointReserveLimit())
                     .With(p => p.User, new UserBuilder()
                           .With(u => u.Stats, stats)
                           .BuildAndSave())
                     .With(p => p.Location, LocationsStatics.STREET_200_MAIN_STREET)
                     .With(p => p.Mobility, PvPStatics.MobilityPet)
                     .With(p => p.Item, new ItemBuilder()
                           .With(i => i.Id, 500)
                           .With(i => i.dbLocationName, "someplace")
                           .BuildAndSave()
                           )
                     .BuildAndSave();

            Assert.That(() => DomainRegistry.Repository.Execute(new Move {
                PlayerId = 55, destination = destination
            }),
                        Throws.Nothing);

            Assert.That(
                DataContext.AsQueryable <LocationLog>()
                .First(l => l.dbLocationName == LocationsStatics.STREET_200_MAIN_STREET).Message,
                Is.EqualTo("John Doe (feral) left toward Carolyne's Coffee Shop (Patio)")); // Moved from

            Assert.That(
                DataContext.AsQueryable <LocationLog>().First(l => l.dbLocationName == destination).Message,
                Is.EqualTo("John Doe (feral) entered from Street: 200 Main Street")); // Moved to

            Assert.That(DataContext.AsQueryable <PlayerLog>().First(p => p.Owner.Id == 55).Message,
                        Is.EqualTo("You moved from <b>Street: 200 Main Street</b> to <b>Carolyne's Coffee Shop (Patio)</b>."));

            Assert.That(player.Location, Is.EqualTo(destination));
            Assert.That(player.Item.dbLocationName, Is.EqualTo(destination));
            Assert.That(player.User.Stats.First(s => s.AchievementType == StatsProcedures.Stat__TimesMoved).Amount,
                        Is.EqualTo(89));
        }
예제 #22
0
 public CreatePlayer()
 {
     Health    = 1000;
     MaxHealth = 1000;
     Mana      = 210;
     MaxMana   = 210;
     Level     = 1;
     XP        = 0;
     TimesAttackingThisUpdate = 0;
     ActionPoints             = TurnTimesStatics.GetActionPointLimit();
     ActionPoints_Refill      = TurnTimesStatics.GetActionPointReserveLimit();
     Gender                      = PvPStatics.GenderFemale;
     Mobility                    = PvPStatics.MobilityFull;
     LastActionTimestamp         = DateTime.UtcNow.AddHours(-TurnTimesStatics.GetMinutesSinceLastCombatBeforeQuestingOrDuelling());
     LastCombatTimestamp         = DateTime.UtcNow.AddHours(-TurnTimesStatics.GetMinutesSinceLastCombatBeforeQuestingOrDuelling());
     LastCombatAttackedTimestamp = DateTime.UtcNow.AddHours(-TurnTimesStatics.GetMinutesSinceLastCombatBeforeQuestingOrDuelling());
     GameMode                    = 1;
     OnlineActivityTimestamp     = DateTime.UtcNow;
     Money = 0;
     CleansesMeditatesThisRound = 0;
     ChatColor = "black";
 }
예제 #23
0
        public void feral_animal_cannot_be_immobilized()
        {
            player = new PlayerBuilder()
                     .With(p => p.Id, 55)
                     .With(p => p.ActionPoints, TurnTimesStatics.GetActionPointReserveLimit())
                     .With(p => p.MoveActionPointDiscount, -999) // Makes animate form immobile
                     .With(p => p.User, new UserBuilder()
                           .With(u => u.Stats, stats)
                           .BuildAndSave())
                     .With(p => p.Location, LocationsStatics.STREET_200_MAIN_STREET)
                     .With(p => p.Mobility, PvPStatics.MobilityPet)
                     .With(p => p.Item, new ItemBuilder()
                           .With(i => i.Id, 500)
                           .With(i => i.dbLocationName, "someplace")
                           .BuildAndSave()
                           )
                     .BuildAndSave();

            Assert.That(() => DomainRegistry.Repository.Execute(new Move {
                PlayerId = 55, destination = destination
            }),
                        Throws.Nothing);
        }
예제 #24
0
        public virtual ActionResult Settings()
        {
            var myMembershipId = User.Identity.GetUserId();
            var me             = PlayerProcedures.GetPlayerFromMembership(myMembershipId);

            var output = new SettingsPageViewModel
            {
                TimeUntilReroll = Math.Round(RerollProcedures.GetTimeUntilReroll(me).TotalMinutes),
                TimeUntilLogout = TurnTimesStatics.GetOfflineAfterXMinutes() - Math.Abs(Math.Floor(me.LastActionTimestamp.Subtract(DateTime.UtcNow).TotalMinutes)),
                Player          = me,
                PlayerItem      = DomainRegistry.Repository.FindSingle(new GetItemByFormerPlayer {
                    PlayerId = me.Id
                }),
                Strikes = DomainRegistry.Repository.Find(new GetUserStrikes {
                    UserId = myMembershipId
                }),
                ChaosChangesEnabled = DomainRegistry.Repository.FindSingle(new IsChaosChangesEnabled {
                    UserId = myMembershipId
                })
            };

            return(View(MVC.Settings.Views.Settings, output));
        }
예제 #25
0
        public static string LocatePlayerInCombat(Player player, Random rand = null)
        {
            rand = rand ?? new Random();
            var cutoff = DateTime.UtcNow.AddMinutes(-TurnTimesStatics.GetMinutesSinceLastCombatBeforeQuestingOrDuelling());

            var playerRepo      = new EFPlayerRepository();
            var playersInCombat = playerRepo.Players
                                  .Where(p => p.LastCombatTimestamp >= cutoff &&
                                         p.Id != player.Id &&
                                         p.Mobility == PvPStatics.MobilityFull &&
                                         p.InDuel <= 0 &&
                                         p.InQuest <= 0 &&
                                         p.BotId == AIStatics.ActivePlayerBotId).ToList();

            if (playersInCombat.IsEmpty())
            {
                return(null);
            }

            var detected = playersInCombat[rand.Next(playersInCombat.Count())];
            var location = LocationsStatics.GetConnectionName(detected.dbLocationName);

            return($"You hear a beep from a machine.  It has a radar-like display and shows that <b>{detected.GetFullName()}</b> has recently been in combat and is currently in <b>{location}</b>!");
        }
예제 #26
0
        public IHttpActionResult Post()
        {
            var allowedIps = new List <string> {
                "127.0.0.1", "::1"
            };
            var owinContext = Request.GetOwinContext();

            if (owinContext == null)
            {
                return(BadRequest());
            }

            if (!allowedIps.Contains(owinContext.Request.RemoteIpAddress))
            {
                return(Unauthorized());
            }

            IPvPWorldStatRepository worldStatRepo = new EFPvPWorldStatRepository();
            var world = worldStatRepo.PvPWorldStats.First();

            if (world.TurnNumber == world.RoundDuration && !world.ChaosMode)
            {
                var round = Int32.Parse(PvPStatics.AlphaRound.Split(' ')[2]);
                var errorSavingLeaderboards = false;
                try
                {
                    DomainRegistry.Repository.Execute(new SavePvPLeaderboards {
                        RoundNumber = round
                    });
                }
                catch (DomainException)
                {
                    errorSavingLeaderboards = true;
                }

                try
                {
                    DomainRegistry.Repository.Execute(new SaveXpLeaderboards {
                        RoundNumber = round
                    });
                }
                catch (DomainException)
                {
                    errorSavingLeaderboards = true;
                }

                try
                {
                    DomainRegistry.Repository.Execute(new SaveItemLeaderboards {
                        RoundNumber = round
                    });
                }
                catch (DomainException)
                {
                    errorSavingLeaderboards = true;
                }

                if (errorSavingLeaderboards)
                {
                    return(InternalServerError());
                }

                // TODO: Set the turn number to 0 and enable chaos mode once we are confident that leaderboards are saving properly, including achievements and badges
                return(Ok());
            }

            // Don't do a turn update if the round is over or we're still in an update
            if (world.TurnNumber >= PvPStatics.RoundDuration || world.WorldIsUpdating)
            {
                return(BadRequest());
            }

            // Don't do a turn update if it hasn't been long enough yet
            var gracePeriodSeconds = 10; // account for delays in fetching the URL
            var secondsElapsed     = DateTime.UtcNow.Subtract(world.LastUpdateTimestamp).TotalSeconds + gracePeriodSeconds;

            if (secondsElapsed < TurnTimesStatics.GetTurnLengthInSeconds())
            {
                return(BadRequest());
            }

            world.TurnNumber++;
            world.WorldIsUpdating     = true;
            world.LastUpdateTimestamp = DateTime.UtcNow;

            // save changes to database
            worldStatRepo.SavePvPWorldStat(world);

            try
            {
                JokeShopProcedures.SetJokeShopActive(world.JokeShop);
                WorldUpdateProcedures.UpdateWorld();
            }
            catch (Exception e)
            {
                return(InternalServerError(e));
            }

            return(Ok());
        }
        internal static string MovePlayer(Player player, string destination, int maxSpacesToMove, Action <Player, string> callback = null, bool timestamp = true)
        {
            var start = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == player.dbLocationName);
            var end   = LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == destination);

            if (destination == null || start == null || end == null)
            {
                return(null);
            }

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

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

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

            var pathTiles   = PathfindingProcedures.GetMovementPath(start, end);
            var costPerTile = Math.Max(0, 1 - target.MoveActionPointDiscount);

            // Cap distance, plus don't exceed number of tiles or available AP
            var maxDistance  = (costPerTile == 0) ? 200 : Math.Floor(target.ActionPoints / costPerTile);
            var spacesToMove = (int)Math.Min(maxDistance, pathTiles.Count());

            spacesToMove = Math.Min(maxSpacesToMove, spacesToMove);

            if (spacesToMove <= 0)
            {
                return(null);
            }

            var stoppingTile = pathTiles[spacesToMove - 1];

            PlayerProcedures.MovePlayerMultipleLocations(player, stoppingTile, spacesToMove * costPerTile, timestamp: timestamp, callback: callback);

            return(stoppingTile);
        }
예제 #28
0
        public override string Execute(IDataContext context)
        {
            var output = "";

            ContextQuery = ctx =>
            {
                var player = ctx.AsQueryable <Player>()
                             .Include(p => p.Effects)
                             .Include(p => p.User)
                             .Include(p => p.User.Stats)
                             .SingleOrDefault(p => p.Id == playerId);

                if (player == null)
                {
                    throw new DomainException($"Player with Id '{playerId}' could not be found");
                }

                if (player.Mobility != PvPStatics.MobilityFull)
                {
                    throw new DomainException("You must be animate in order to take the bus.");
                }

                var originLocation = LocationsStatics.LocationList.GetLocation.First(l => l.dbName == player.Location);

                if (!LocationsStatics.BusStops.Contains(originLocation.dbName))
                {
                    throw new DomainException("You aren't at a valid bus stop.");
                }

                var destinationLocation = LocationsStatics.LocationList.GetLocation.First(l => l.dbName == destination);
                if (!LocationsStatics.BusStops.Contains(destinationLocation.dbName))
                {
                    throw new DomainException("Your destination is not a valid bus stop.");
                }

                if (originLocation.dbName == destinationLocation.dbName)
                {
                    throw new DomainException("You can't take the bus to the location you're already at.");
                }

                if (DateTime.UtcNow.Subtract(player.GetLastCombatTimestamp()).TotalMinutes < 15)
                {
                    throw new DomainException("You have been in combat too recently to take a bus.");
                }

                if (player.InDuel > 0)
                {
                    throw new DomainException("You cannot take the bus whilst in a duel.");
                }

                if (player.InQuest > 0)
                {
                    throw new DomainException("You cannot take the bus whilst in a quest.");
                }

                var distance    = LocationsStatics.GetDistanceBetweenLocations(player.Location, destination);
                var ticketPrice = LocationsStatics.GetTicketPriceBetweenLocations(player.Location, destination);

                if (player.ActionPoints < 3)
                {
                    throw new DomainException("You don't have enough AP to take the bus.");
                }

                if (player.Money < ticketPrice)
                {
                    throw new DomainException("You can't afford this bus ticket!");
                }

                if (player.Effects.FirstOrDefault(e => e.EffectSource != null && e.EffectSource.Id == MindControlStatics.MindControl__Movement_DebuffEffectSourceId) != null)
                {
                    throw new DomainException("You can't ride the bus while under the Forced March! mind control spell.");
                }

                if (player.MoveActionPointDiscount < -TurnTimesStatics.GetActionPointReserveLimit())
                {
                    throw new DomainException("You can't ride the bus while immobilized.");
                }

                output = $"You took the bus from <b>{originLocation.Name}</b> to <b>{destinationLocation.Name}</b> for <b>{ticketPrice}</b> Arpeyjis.";
                player.SetLocation(destination);
                player.AddLog(output, false);
                player.ChangeMoney(-ticketPrice);
                player.ChangeActionPoints(-3);
                player.SetOnlineActivityToNow();

                var originLocationLog      = LocationLog.Create(originLocation.dbName, $"{player.GetFullName()} got on a bus headed toward {destinationLocation.Name}.", 0);
                var destinationLocationLog = LocationLog.Create(destinationLocation.dbName, $"{player.GetFullName()} arrived via bus from {originLocation.Name}.", 0);

                // log statistics only for human players
                if (player.BotId == AIStatics.ActivePlayerBotId)
                {
                    player.User.AddStat(StatsProcedures.Stat__BusRides, distance);
                }

                ctx.Add(originLocationLog);
                ctx.Add(destinationLocationLog);
                ctx.Commit();
            };

            ExecuteInternal(context);
            return(output);
        }
예제 #29
0
 private static DateTime GetOnlineCutoffTime()
 {
     return(DateTime.UtcNow.AddMinutes(-TurnTimesStatics.GetOfflineAfterXMinutes()));
 }
        public static string WanderAimlessly(Player player, Random rand = null)
        {
            if (player.InDuel > 0 || player.InQuest > 0 || player.MindControlIsActive || player.MoveActionPointDiscount < -TurnTimesStatics.GetActionPointReserveLimit())
            {
                return(null);
            }

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

            rand = rand ?? new Random();

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

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

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

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

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

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

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

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

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

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

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

            return("The room starts to shake.  A waving cat on a nearby display rattles, edging forward before falling off the shelf and smashing to the ground.  The structure of the room creaks as the ceiling contorts.  All the clown faces seem to be staring at you.  Suddenly this feels a very unsettling place.  You get a bad feeling that something is about to happen to this sinister and claustrophobic shop.  There's only one thing for it:  You race out the door and run.  It doesn't matter which direction you go in, just so long as you get out of here!");
        }