示例#1
0
        public override void Execute(IDataContext context)
        {
            ContextQuery = ctx =>
            {
                var player = ctx.AsQueryable <Player>()
                             .Include(p => p.User)
                             .Include(i => i.PlayerLogs)
                             .SingleOrDefault(p => p.User.Id == UserId);

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

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

                if (player.ShoutsRemaining <= 0)
                {
                    throw new DomainException("You can only shout once per turn.");
                }

                var hushed = ctx.AsQueryable <Effect>()
                             .Where(e => e.EffectSource.Id == CharacterPrankProcedures.HUSHED_EFFECT &&
                                    e.Owner.Id == player.Id &&
                                    e.Duration > 0)
                             .Any();

                if (hushed)
                {
                    throw new DomainException("You have been hushed and cannot currently shout.");
                }


                Message = Message.Replace("<", "&lt;").Replace(">", "&gt;"); // remove suspicious characters

                var log = LocationLog.Create(player.Location, $"<span class='playerShoutNotification'>{player.GetFullName()} shouted <b>\"{Message}\"</b> here.</span>");

                player.Shout(Message);
                ctx.Update(player);
                ctx.Add(log);

                ctx.Commit();
            };

            ExecuteInternal(context);
        }
示例#2
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);
        }
示例#3
0
        public override string Execute(IDataContext context)
        {
            var result = "";

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

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

                if (!NoValidate)
                {
                    if (player.ActionPoints < PvPStatics.MeditateCost)
                    {
                        throw new DomainException("You don't have enough action points to meditate!");
                    }

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

                    if (player.CleansesMeditatesThisRound >= PvPStatics.MaxCleansesMeditatesPerUpdate)
                    {
                        throw new DomainException("You have cleansed and meditated the maximum number of times this update.");
                    }

                    var mcs = player.VictimMindControls.Select(m => m.FormSourceId);

                    if (mcs.Contains(MindControlStatics.MindControl__MeditateFormSourceId))
                    {
                        throw new DomainException("You try to meditate but find you cannot!  The moment you try and focus, your head swims with nonsensical thoughts implanted by someone partially mind controlling you!");
                    }
                }

                result = player.Meditate(Buffs);

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

                ctx.Update(player);

                // TODO: Perform this as part of the Meditate method on the Player entity once known how
                var locationLog = LocationLog.Create(player.Location, $"<span class='playerMediatingNotification'>{player.GetFullName()} meditated here.</span>");
                ctx.Add(locationLog);

                ctx.Commit();
            };

            ExecuteInternal(context);

            return(result);
        }
示例#4
0
        public override string Execute(IDataContext context)
        {
            var result = "";

            ContextQuery = ctx =>
            {
                var player = ctx.AsQueryable <Player>()
                             .Include(p => p.TFEnergies)
                             .Include(p => p.PlayerLogs)
                             .Include(p => p.User)
                             .Include(p => p.User.Stats)
                             .SingleOrDefault(cr => cr.Id == PlayerId);

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

                if (!NoValidate)
                {
                    if (player.ActionPoints < PvPStatics.CleanseCost)
                    {
                        throw new DomainException("You don't have enough action points to cleanse!");
                    }

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

                    if (player.Mana < PvPStatics.CleanseManaCost)
                    {
                        throw new DomainException("You don't have enough mana to cleanse!");
                    }

                    if (player.CleansesMeditatesThisRound >= PvPStatics.MaxCleansesMeditatesPerUpdate)
                    {
                        throw new DomainException("You have cleansed and meditated the maximum number of times this update.");
                    }
                }

                result = player.Cleanse(Buffs);

                foreach (var energy in player.TFEnergies.ToList().Where(energy => energy.Amount <= 0))
                {
                    ctx.Remove(energy);
                }

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

                ctx.Update(player);

                // TODO: Perform this as part of the Cleanse method on the Player entity once known how
                var locationLog = LocationLog.Create(player.Location, $"<span class='playerCleansingNotification'>{player.GetFullName()} cleansed here.</span>");
                ctx.Add(locationLog);

                ctx.Commit();
            };

            ExecuteInternal(context);

            return(result);
        }
示例#5
0
        public override string Execute(IDataContext context)
        {
            var result = "";

            ContextQuery = ctx =>
            {
                var player = ctx.AsQueryable <Player>()
                             .Include(p => p.Items)
                             .Include(p => p.Item)
                             .Include(p => p.User)
                             .Include(p => p.User.Stats)
                             .Include(p => p.VictimMindControls)
                             .SingleOrDefault(cr => cr.Id == PlayerId);

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

                if (String.IsNullOrWhiteSpace(destination))
                {
                    throw new DomainException("Destination must be specified");
                }

                if (LocationsStatics.LocationList.GetLocation.FirstOrDefault(l => l.dbName == destination) == null)
                {
                    throw new DomainException($"Location with dbName '{destination}' could not be found");
                }

                if (player.Mobility == PvPStatics.MobilityFull && player.MoveActionPointDiscount < -TurnTimesStatics.GetActionPointReserveLimit())
                {
                    throw new DomainException("You can't move since you have been immobilized!");
                }

                if (player.Mobility == PvPStatics.MobilityFull && player.ActionPoints < Math.Max(0, PvPStatics.LocationMoveCost - player.MoveActionPointDiscount))
                {
                    throw new DomainException("You don't have enough action points to move.");
                }

                if (player.Mobility == PvPStatics.MobilityInanimate)
                {
                    throw new DomainException("You can't move because you are currently inanimate!");
                }

                var lastAttackTimeAgo = Math.Abs(Math.Floor(player.LastCombatTimestamp.Subtract(DateTime.UtcNow).TotalSeconds));
                if (lastAttackTimeAgo < TurnTimesStatics.GetNoMovingAfterAttackSeconds())
                {
                    throw new DomainException($"You are resting from a recent attack.  You must wait {Math.Ceiling(TurnTimesStatics.GetNoMovingAfterAttackSeconds() - lastAttackTimeAgo)} more seconds before moving.");
                }

                if (player.Mobility == PvPStatics.MobilityPet && player.Item != null)
                {
                    if (player.Item.Owner != null)
                    {
                        throw new DomainException($"You can't move because you are a non-feral pet owned by {player.Item.Owner.GetFullName()}.");
                    }
                }

                if (player.Mobility == PvPStatics.MobilityFull && player.IsCarryingTooMuchToMove())
                {
                    var excessItemCount = player.GetCarriedItemCount() - player.GetMaxInventorySize();
                    var pluralize       = excessItemCount == 1 ? "item" : "items";
                    throw new DomainException($"You are carrying too much to move.  You need to drop at least {excessItemCount} {pluralize}.");
                }

                if (player.InDuel > 0)
                {
                    throw new DomainException("You must finish your duel before you can move again.");
                }

                if (player.InQuest > 0)
                {
                    throw new DomainException("You must end your quest before you can move again.");
                }

                // TODO:  This might not work yet because it's considering mind controls this player has on others and not themself
                //if (player.CantMoveBecauseOfForcedMarch())
                //        throw new DomainException("You try to move but discover you cannot!  Some other mage has partial control of your mind, disabling your ability to move on your own!");

                // assert this location does have a connection to the next one
                var currentLocation = LocationsStatics.LocationList.GetLocation.First(l => l.dbName == player.Location);
                var nextLocation    = LocationsStatics.LocationList.GetLocation.First(l => l.dbName == destination);
                if (currentLocation.Name_North != destination && currentLocation.Name_East != destination && currentLocation.Name_South != destination && currentLocation.Name_West != destination)
                {
                    throw new DomainException($"You cannot move directly from {currentLocation.Name} to {nextLocation.Name}.");
                }

                MoveLogBox logs;

                if (player.Mobility == PvPStatics.MobilityPet)
                {
                    logs = player.MoveToAsAnimal(destination);
                }
                else
                {
                    logs = player.MoveTo(destination, Direction);
                }


                var oldLocationLog = LocationLog.Create(currentLocation.dbName, logs.SourceLocationLog, logs.ConcealmentLevel);
                var newLocationLog = LocationLog.Create(nextLocation.dbName, logs.DestinationLocationLog, logs.ConcealmentLevel);
                result = logs.PlayerLog;
                ctx.Add(oldLocationLog);
                ctx.Add(newLocationLog);
                ctx.Update(player);

                ctx.Commit();
            };

            ExecuteInternal(context);

            return(result);
        }
示例#6
0
        public override string Execute(IDataContext context)
        {
            var result = "";

            ContextQuery = ctx =>
            {
                var player = ctx.AsQueryable <Player>()
                             .Include(p => p.Items)
                             .Include(p => p.Item.ItemSource)
                             .Include(p => p.User)
                             .Include(p => p.User.Stats)
                             .FirstOrDefault(p => p.Id == PlayerId);

                if (player == null)
                {
                    throw new DomainException($"player with ID {PlayerId} could not be found.");
                }

                var item = player.Items.FirstOrDefault(i => i.Id == ItemId);

                if (item == null)
                {
                    throw new DomainException($"Item with ID {ItemId} could not be found or does not belong to you.");
                }

                var cutoff = DateTime.UtcNow.AddMinutes(-TurnTimesStatics.GetOfflineAfterXMinutes());

                var affectedPlayers = ctx.AsQueryable <Player>()
                                      .Where(p => p.Location == player.Location &&
                                             p.Id != PlayerId &&
                                             p.GameMode != (int)GameModeStatics.GameModes.Superprotection &&
                                             p.InDuel <= 0 &&
                                             p.InQuest <= 0 &&
                                             p.FormSource.AltSexFormSource != null &&
                                             p.LastActionTimestamp > cutoff
                                             ).Include(p => p.FormSource)
                                      .Include(p => p.FormSource.AltSexFormSource)
                                      .ToList();

                foreach (var p in affectedPlayers)
                {
                    p.ChangeForm(p.FormSource.AltSexFormSource);
                    p.AddLog($"You yelp and feel your body change to that of the opposite sex from <b>{player.GetFullName()}</b>'s use of a TG Splash Orb in your location!", true);
                }

                player.SetOnlineActivityToNow();
                player.UpdateItemUseCounter(1);

                if (affectedPlayers.Any())
                {
                    var xpGained = affectedPlayers.Where(p => p.Level >= player.Level - 2).Sum(p => p.Level < 3 ? 3 : p.Level);

                    player.AddXP(xpGained);

                    // can't do this as a LINQ select due to calling the a.GetFullName() method
                    var playerNames = new List <string>();
                    foreach (var a in affectedPlayers)
                    {
                        playerNames.Add(a.GetFullName());
                    }

                    result = $"You throw your TG Splash Orb and swap the sex of {affectedPlayers.Count()} other mages near you: {ListifyHelper.Listify(playerNames, true)} and gain <b>{xpGained}</b> XP!";
                    player.AddLog(result, false);

                    // log statistics only for human players
                    if (player.BotId == AIStatics.ActivePlayerBotId)
                    {
                        player.User.AddStat(StatsProcedures.Stat__TgOrbVictims, affectedPlayers.Count());
                    }
                }
                else
                {
                    result = "You throw your TG Splash Orb, but unfortunately nobody is affected in this location.";
                }
                var locationLog = LocationLog.Create(player.Location, $"{player.GetFullName()} threw a TG splash orb, affecting {affectedPlayers.Count()} mages.");
                ctx.Add(locationLog);
                ctx.Update(player);
                ctx.Remove(item);

                ctx.Commit();
            };

            ExecuteInternal(context);
            return(result); // TODO: use event handler
        }