/// <summary> /// Initializes a new instance of the <see cref="ContainerToMapMovementEvent"/> class. /// </summary> /// <param name="logger">A reference to the logger in use.</param> /// <param name="game">A reference to the game instance.</param> /// <param name="connectionManager">A reference to the connection manager in use.</param> /// <param name="tileAccessor">A reference to the tile accessor in use.</param> /// <param name="creatureFinder">A reference to the creture finder in use.</param> /// <param name="creatureRequestingId">The id of the creature requesting the movement.</param> /// <param name="thingMoving">The thing being moved.</param> /// <param name="fromCreatureId">The id of the creature in which the movement is happening.</param> /// <param name="fromCreatureContainerId">The id of the container from which the movement is happening.</param> /// <param name="fromCreatureContainerIndex">The index in the container from which the movement is happening.</param> /// <param name="toLocation">The location in the map to which the movement is happening.</param> /// <param name="amount">Optional. The amount of the thing to move. Must be positive. Defaults to 1.</param> /// <param name="evaluationTime">Optional. The evaluation time policy for this event. Defaults to <see cref="EvaluationTime.OnBoth"/>.</param> public ContainerToMapMovementEvent( ILogger logger, IGame game, IConnectionManager connectionManager, ITileAccessor tileAccessor, ICreatureFinder creatureFinder, uint creatureRequestingId, IThing thingMoving, uint fromCreatureId, byte fromCreatureContainerId, byte fromCreatureContainerIndex, Location toLocation, byte amount = 1, EvaluationTime evaluationTime = EvaluationTime.OnBoth) : base(logger, game, connectionManager, creatureFinder, creatureRequestingId, evaluationTime) { tileAccessor.ThrowIfNull(nameof(tileAccessor)); if (amount == 0) { throw new ArgumentException("Invalid count zero.", nameof(amount)); } this.Conditions.Add(new LocationNotObstructedEventCondition(tileAccessor, this.Requestor, () => thingMoving, () => toLocation)); this.Conditions.Add(new LocationHasTileWithGroundEventCondition(tileAccessor, () => toLocation)); this.Conditions.Add(new ContainerIsOpenEventCondition(() => creatureFinder.FindCreatureById(fromCreatureId), fromCreatureContainerId)); var onPassAction = new GenericEventAction(() => { bool moveSuccessful = thingMoving is IItem item && creatureFinder.FindCreatureById(fromCreatureId) is IPlayer targetPlayer && tileAccessor.GetTileAt(toLocation, out ITile toTile) && this.Game.PerformItemMovement(item, targetPlayer.GetContainerById(fromCreatureContainerId), toTile, fromIndex: fromCreatureContainerIndex, amountToMove: amount); if (!moveSuccessful) { // handles check for isPlayer. this.NotifyOfFailure(); return; } if (this.Requestor is IPlayer player && toLocation != player.Location && player != thingMoving) { var directionToDestination = player.Location.DirectionTo(toLocation); this.Game.PlayerRequest_TurnToDirection(player, directionToDestination); } this.Game.EvaluateCollisionEventRules(toLocation, thingMoving, this.Requestor); this.Game.EvaluateMovementEventRules(thingMoving, this.Requestor); }); this.ActionsOnPass.Add(onPassAction); }
/// <summary> /// Initializes a new instance of the <see cref="BaseEvent"/> class. /// </summary> /// <param name="evaluationTime">Optional. The time at which the event's conditions should be evaluated. Default is <see cref="EvaluationTime.OnExecute"/>.</param> public BaseEvent(EvaluationTime evaluationTime = EvaluationTime.OnExecute) { EventId = Guid.NewGuid().ToString("N"); RequestorId = 0; EvaluateAt = evaluationTime; Conditions = new List <IEventCondition>(); ActionsOnPass = new List <IEventAction>(); ActionsOnFail = new List <IEventAction>(); }
/// <summary> /// Initializes a new instance of the <see cref="BaseEvent"/> class. /// </summary> /// <param name="logger">The logger to use.</param> /// <param name="evaluationTime">Optional. The time at which the event's conditions should be evaluated. Default is <see cref="EvaluationTime.OnExecute"/>.</param> public BaseEvent(ILogger logger, EvaluationTime evaluationTime = EvaluationTime.OnExecute) { logger.ThrowIfNull(nameof(logger)); this.EventId = Guid.NewGuid().ToString("N"); this.RequestorId = 0; this.EvaluateAt = evaluationTime; this.Logger = logger.ForContext(this.GetType()); this.Conditions = new List <IEventCondition>(); this.ActionsOnPass = new List <IEventAction>(); this.ActionsOnFail = new List <IEventAction>(); }
/// <summary> /// Initializes a new instance of the <see cref="MapToContainerMovementEvent"/> class. /// </summary> /// <param name="logger">A reference to the logger in use.</param> /// <param name="game">A reference to the game instance.</param> /// <param name="connectionManager">A reference to the connection manager in use.</param> /// <param name="tileAccessor">A reference to the tile accessor in use.</param> /// <param name="creatureFinder">A reference to the creture finder in use.</param> /// <param name="creatureRequestingId">The id of the creature requesting the movement.</param> /// <param name="thingMoving">The thing being moved.</param> /// <param name="fromLocation">The location from which the movement is happening.</param> /// <param name="toCreatureId">The id of the creature that should known the container to which the movement is happening.</param> /// <param name="toCreatureContainerId">The id of the container to which the movement is happening.</param> /// <param name="toCreatureContainerIndex">The index in the container to which the movement is happening.</param> /// <param name="amount">Optional. The amount of the thing to move. Must be positive. Defaults to 1.</param> /// <param name="evaluationTime">Optional. The evaluation time policy for this event. Defaults to <see cref="EvaluationTime.OnBoth"/>.</param> public MapToContainerMovementEvent( ILogger logger, IGame game, IConnectionManager connectionManager, ITileAccessor tileAccessor, ICreatureFinder creatureFinder, uint creatureRequestingId, IThing thingMoving, Location fromLocation, uint toCreatureId, byte toCreatureContainerId, byte toCreatureContainerIndex, byte amount = 1, EvaluationTime evaluationTime = EvaluationTime.OnBoth) : base(logger, game, connectionManager, creatureFinder, creatureRequestingId, evaluationTime) { tileAccessor.ThrowIfNull(nameof(tileAccessor)); if (amount == 0) { throw new ArgumentException("Invalid count zero.", nameof(amount)); } this.Conditions.Add(new TileContainsThingEventCondition(tileAccessor, thingMoving, fromLocation, amount)); this.Conditions.Add(new RequestorIsInRangeToMoveEventCondition(this.Requestor, () => fromLocation)); this.Conditions.Add(new LocationsMatchEventCondition(() => thingMoving?.Location ?? default, () => fromLocation)); this.Conditions.Add(new ContainerIsOpenEventCondition(() => creatureFinder.FindCreatureById(toCreatureId), toCreatureContainerId)); var onPassAction = new GenericEventAction(() => { bool moveSuccessful = thingMoving is IItem item && creatureFinder.FindCreatureById(toCreatureId) is IPlayer targetPlayer && tileAccessor.GetTileAt(fromLocation, out ITile fromTile) && this.Game.PerformItemMovement(item, fromTile, targetPlayer.GetContainerById(toCreatureContainerId), toIndex: toCreatureContainerIndex, amountToMove: amount); if (!moveSuccessful) { // handles check for isPlayer. this.NotifyOfFailure(); return; } this.Game.EvaluateSeparationEventRules(fromLocation, thingMoving, this.Requestor); this.Game.EvaluateMovementEventRules(thingMoving, this.Requestor); }); this.ActionsOnPass.Add(onPassAction); }
/// <summary> /// Initializes a new instance of the <see cref="ContainerToContainerMovementEvent"/> class. /// </summary> /// <param name="logger">A reference to the logger in use.</param> /// <param name="game">A reference to the game instance.</param> /// <param name="connectionManager">A reference to the connection manager in use.</param> /// <param name="tileAccessor">A reference to the tile accessor in use.</param> /// <param name="creatureFinder">A reference to the creture finder in use.</param> /// <param name="creatureRequestingId">The id of the creature requesting the movement.</param> /// <param name="thingMoving">The thing being moved.</param> /// <param name="targetCreatureId">The id of the creature in which the movement is happening.</param> /// <param name="fromCreatureContainerId">The id of the container from which the movement is happening.</param> /// <param name="fromCreatureContainerIndex">The index in the container from which the movement is happening.</param> /// <param name="toCreatureContainerId">The id of the container to which the movement is happening.</param> /// <param name="toCreatureContainerIndex">The index in the container to which the movement is happening.</param> /// <param name="amount">Optional. The amount of the thing to move. Must be positive. Defaults to 1.</param> /// <param name="evaluationTime">Optional. The evaluation time policy for this event. Defaults to <see cref="EvaluationTime.OnBoth"/>.</param> public ContainerToContainerMovementEvent( ILogger logger, IGame game, IConnectionManager connectionManager, ITileAccessor tileAccessor, ICreatureFinder creatureFinder, uint creatureRequestingId, IThing thingMoving, uint targetCreatureId, byte fromCreatureContainerId, byte fromCreatureContainerIndex, byte toCreatureContainerId, byte toCreatureContainerIndex, byte amount = 1, EvaluationTime evaluationTime = EvaluationTime.OnBoth) : base(logger, game, connectionManager, creatureFinder, creatureRequestingId, evaluationTime) { tileAccessor.ThrowIfNull(nameof(tileAccessor)); if (amount == 0) { throw new ArgumentException("Invalid count zero.", nameof(amount)); } this.Conditions.Add(new ContainerIsOpenEventCondition(() => creatureFinder.FindCreatureById(targetCreatureId), fromCreatureContainerId)); this.Conditions.Add(new ContainerIsOpenEventCondition(() => creatureFinder.FindCreatureById(targetCreatureId), toCreatureContainerId)); var onPassAction = new GenericEventAction(() => { bool moveSuccessful = thingMoving is IItem item && creatureFinder.FindCreatureById(targetCreatureId) is IPlayer targetPlayer && this.Game.PerformItemMovement(item, targetPlayer.GetContainerById(fromCreatureContainerId), targetPlayer.GetContainerById(toCreatureContainerId), fromCreatureContainerIndex, toCreatureContainerIndex, amount); if (!moveSuccessful) { // handles check for isPlayer. this.NotifyOfFailure(); return; } this.Game.EvaluateMovementEventRules(thingMoving, this.Requestor); }); this.ActionsOnPass.Add(onPassAction); }
/// <summary> /// Initializes a new instance of the <see cref="ChangeItemEvent"/> class. /// </summary> /// <param name="logger">A reference to the logger in use.</param> /// <param name="game">A reference to the game instance.</param> /// <param name="connectionManager">A reference to the connection manager in use.</param> /// <param name="tileAccessor">A reference to the tile accessor in use.</param> /// <param name="creatureFinder">A reference to the creature finder in use.</param> /// <param name="requestorId">The id of the creature requesting the use.</param> /// <param name="typeId">The type id of the item being used.</param> /// <param name="fromLocation">The location from which the item is being used.</param> /// <param name="toTypeId">The type id of the item to change to.</param> /// <param name="fromStackPos">The position in the stack from which the item is being used.</param> /// <param name="index">The index of the item being used.</param> /// <param name="evaluationTime">The time to evaluate the movement.</param> public ChangeItemEvent( ILogger logger, IGame game, IConnectionManager connectionManager, ITileAccessor tileAccessor, ICreatureFinder creatureFinder, uint requestorId, ushort typeId, Location fromLocation, ushort toTypeId, byte fromStackPos = byte.MaxValue, byte index = 1, EvaluationTime evaluationTime = EvaluationTime.OnBoth) : base(logger, requestorId, evaluationTime) { game.ThrowIfNull(nameof(game)); tileAccessor.ThrowIfNull(nameof(tileAccessor)); connectionManager.ThrowIfNull(nameof(connectionManager)); creatureFinder.ThrowIfNull(nameof(creatureFinder)); this.ConnectionManager = connectionManager; this.CreatureFinder = creatureFinder; this.Game = game; this.ActionsOnFail.Add(new GenericEventAction(this.NotifyOfFailure)); var onPassAction = new GenericEventAction(() => { var fromCylinder = this.Game.GetCyclinder(fromLocation, ref fromStackPos, ref index, this.Requestor); var item = this.Game.FindItemByIdAtLocation(typeId, fromLocation, this.Requestor); bool successfulUse = this.Game.PerformItemChange(item, toTypeId, fromCylinder, index, this.Requestor); if (!successfulUse) { // handles check for isPlayer. this.NotifyOfFailure(); return; } }); this.ActionsOnPass.Add(onPassAction); }
/// <summary> /// Initializes a new instance of the <see cref="DeleteItemEvent"/> class. /// </summary> /// <param name="logger">A reference to the logger in use.</param> /// <param name="game">A reference to the game instance.</param> /// <param name="connectionManager">A reference to the connection manager in use.</param> /// <param name="tileAccessor">A reference to the tile accessor in use.</param> /// <param name="creatureFinder">A reference to the creature finder in use.</param> /// <param name="requestorId">The id of the creature requesting the deletion.</param> /// <param name="typeId">The type id of the item being deleted.</param> /// <param name="atLocation">The location from which the item is being deleted.</param> /// <param name="evaluationTime">The time to evaluate the event.</param> public DeleteItemEvent( ILogger logger, IGame game, IConnectionManager connectionManager, ITileAccessor tileAccessor, ICreatureFinder creatureFinder, uint requestorId, ushort typeId, Location atLocation, EvaluationTime evaluationTime = EvaluationTime.OnBoth) : base(logger, requestorId, evaluationTime) { game.ThrowIfNull(nameof(game)); tileAccessor.ThrowIfNull(nameof(tileAccessor)); connectionManager.ThrowIfNull(nameof(connectionManager)); creatureFinder.ThrowIfNull(nameof(creatureFinder)); this.ConnectionManager = connectionManager; this.CreatureFinder = creatureFinder; this.Game = game; this.ActionsOnFail.Add(new GenericEventAction(this.NotifyOfFailure)); var onPassAction = new GenericEventAction(() => { byte index = 0, subIndex = 0; var fromCylinder = this.Game.GetCyclinder(atLocation, ref index, ref subIndex, this.Requestor); var item = this.Game.FindItemByIdAtLocation(typeId, atLocation, this.Requestor); bool successfulDeletion = this.Game.PerformItemDeletion(item, fromCylinder, subIndex, this.Requestor); if (!successfulDeletion) { // handles check for isPlayer. this.NotifyOfFailure(); return; } }); this.ActionsOnPass.Add(onPassAction); }
/// <summary> /// Initializes a new instance of the <see cref="MovementBase"/> class. /// </summary> /// <param name="requestorId">The id of the creature requesting the movement.</param> /// <param name="evaluationTime">The time to evaluate the movement.</param> protected MovementBase(uint requestorId, EvaluationTime evaluationTime) : base(requestorId, evaluationTime) { ActionsOnFail.Add( new GenericEventAction( () => { var player = Requestor as Player; if (player != null) { Game.Instance.NotifySinglePlayer(player, conn => new GenericNotification( conn, new PlayerWalkCancelPacket { Direction = player.ClientSafeDirection }, new TextMessagePacket { Message = ErrorMessage ?? "Sorry, not possible.", Type = MessageType.StatusSmall })); } })); }
/// <summary> /// Initializes a new instance of the <see cref="MapToMapMovementEvent"/> class. /// </summary> /// <param name="logger">A reference to the logger in use.</param> /// <param name="game">A reference to the game instance.</param> /// <param name="connectionManager">A reference to the connection manager in use.</param> /// <param name="tileAccessor">A reference to the tile accessor in use.</param> /// <param name="creatureFinder">A reference to the creture finder in use.</param> /// <param name="creatureRequestingId">The id of the creature requesting the movement.</param> /// <param name="thingMoving">The thing being moved.</param> /// <param name="fromLocation">The location in the map from which the movement is happening.</param> /// <param name="toLocation">The location in the map to which the movement is happening.</param> /// <param name="fromStackPos">Optional. The position in the stack of the location from which the movement is happening. Defaults to <see cref="byte.MaxValue"/>, which makes the system take the top thing at the location.</param> /// <param name="amount">Optional. The amount of the thing to move. Must be positive. Defaults to 1.</param> /// <param name="isTeleport">Optional. A value indicating whether the movement is considered a teleportation. Defaults to false.</param> /// <param name="evaluationTime">Optional. The evaluation time policy for this event. Defaults to <see cref="EvaluationTime.OnBoth"/>.</param> public MapToMapMovementEvent( ILogger logger, IGame game, IConnectionManager connectionManager, ITileAccessor tileAccessor, ICreatureFinder creatureFinder, uint creatureRequestingId, IThing thingMoving, Location fromLocation, Location toLocation, byte fromStackPos = byte.MaxValue, byte amount = 1, bool isTeleport = false, EvaluationTime evaluationTime = EvaluationTime.OnBoth) : base(logger, game, connectionManager, creatureFinder, creatureRequestingId, evaluationTime) { tileAccessor.ThrowIfNull(nameof(tileAccessor)); if (amount == 0) { throw new ArgumentException("Invalid count zero.", nameof(amount)); } if (!isTeleport && this.Requestor != null) { this.Conditions.Add(new CanThrowBetweenEventCondition(game, this.Requestor, () => fromLocation, () => toLocation)); } if (thingMoving is ICreature creatureMoving) { // Don't add any conditions if this wasn't a creature requesting, i.e. if the request comes from a script. if (!isTeleport && this.Requestor != null) { this.Conditions.Add(new LocationNotAvoidEventCondition(tileAccessor, this.Requestor, () => creatureMoving, () => toLocation)); this.Conditions.Add(new LocationsAreDistantByEventCondition(() => fromLocation, () => toLocation)); this.Conditions.Add(new CreatureThrowBetweenFloorsEventCondition(this.Requestor, () => creatureMoving, () => toLocation)); } } this.Conditions.Add(new RequestorIsInRangeToMoveEventCondition(this.Requestor, () => fromLocation)); this.Conditions.Add(new LocationNotObstructedEventCondition(tileAccessor, this.Requestor, () => thingMoving, () => toLocation)); this.Conditions.Add(new LocationHasTileWithGroundEventCondition(tileAccessor, () => toLocation)); this.Conditions.Add(new UnpassItemsInRangeEventCondition(this.Requestor, () => thingMoving, () => toLocation)); this.Conditions.Add(new LocationsMatchEventCondition(() => thingMoving?.Location ?? default, () => fromLocation)); this.Conditions.Add(new TileContainsThingEventCondition(tileAccessor, thingMoving, fromLocation, amount)); var onPassAction = new GenericEventAction(() => { bool moveSuccessful = false; if (thingMoving is ICreature creatureMoving) { moveSuccessful = this.Game.PerformCreatureMovement(creatureMoving, toLocation); } else if (thingMoving is IItem item) { moveSuccessful = tileAccessor.GetTileAt(fromLocation, out ITile fromTile) && tileAccessor.GetTileAt(toLocation, out ITile toTile) && this.Game.PerformItemMovement(item, fromTile, toTile, fromStackPos, amountToMove: amount); } if (!moveSuccessful) { // handles check for whether there is a player to notify. this.NotifyOfFailure(); return; } if (this.Requestor is IPlayer player && toLocation != player.Location && player != thingMoving) { var directionToDestination = player.Location.DirectionTo(toLocation); this.Game.PlayerRequest_TurnToDirection(player, directionToDestination); } this.Game.EvaluateSeparationEventRules(fromLocation, thingMoving, this.Requestor); this.Game.EvaluateCollisionEventRules(toLocation, thingMoving, this.Requestor); this.Game.EvaluateMovementEventRules(thingMoving, this.Requestor); }); this.ActionsOnPass.Add(onPassAction); }
/// <summary> /// Initializes a new instance of the <see cref="GenericEvent"/> class. /// </summary> /// <param name="requestorId">The id of the creature requesting this event.</param> /// <param name="conditions">The conditions of the event.</param> /// <param name="onSuccessActions">The actions to run if the event passes conditions.</param> /// <param name="onFailActions">The actions to run if the event fails to pass conditions.</param> /// <param name="evaluationTime">Optional. The time on which the event's conditions should be evaluated. Default is <see cref="EvaluationTime.OnBoth"/>.</param> public GenericEvent(uint requestorId, IEventCondition [] conditions, IEventAction [] onSuccessActions, IEventAction[] onFailActions, EvaluationTime evaluationTime = EvaluationTime.OnBoth) : base(requestorId, evaluationTime) { if (conditions != null) { foreach (var condition in conditions) { Conditions.Add(condition); } } if (onSuccessActions != null) { foreach (var action in onSuccessActions) { ActionsOnPass.Add(action); } } if (onFailActions != null) { foreach (var action in onFailActions) { ActionsOnFail.Add(action); } } }
/// <summary> /// Initializes a new instance of the <see cref="BaseEvent"/> class. /// </summary> /// <param name="logger">The logger to use.</param> /// <param name="requestorId">Optional. The id of the creature or entity requesting the event. Default is 0.</param> /// <param name="evaluationTime">Optional. The time at which the event's conditions should be evaluated. Default is <see cref="EvaluationTime.OnExecute"/>.</param> public BaseEvent(ILogger logger, uint requestorId = 0, EvaluationTime evaluationTime = EvaluationTime.OnExecute) : this(logger, evaluationTime) { this.RequestorId = requestorId; }
/// <summary> /// Initializes a new instance of the <see cref="BaseMovementEvent"/> class. /// </summary> /// <param name="logger">A reference to the logger in use.</param> /// <param name="game">A reference to the game instance.</param> /// <param name="connectionManager">A reference to the connection manager in use.</param> /// <param name="creatureFinder">A reference to the creature finder in use.</param> /// <param name="requestorId">The id of the creature requesting the movement.</param> /// <param name="evaluationTime">The time to evaluate the movement.</param> protected BaseMovementEvent(ILogger logger, IGame game, IConnectionManager connectionManager, ICreatureFinder creatureFinder, uint requestorId, EvaluationTime evaluationTime) : base(logger, requestorId, evaluationTime) { game.ThrowIfNull(nameof(game)); connectionManager.ThrowIfNull(nameof(connectionManager)); creatureFinder.ThrowIfNull(nameof(creatureFinder)); this.ConnectionManager = connectionManager; this.CreatureFinder = creatureFinder; this.Game = game; this.ActionsOnFail.Add(new GenericEventAction(this.NotifyOfFailure)); }
/// <summary> /// Initializes a new instance of the <see cref="BaseEvent"/> class. /// </summary> /// <param name="requestorId">Optional. The id of the creature or entity requesting the event. Default is 0.</param> /// <param name="evaluationTime">Optional. The time at which the event's conditions should be evaluated. Default is <see cref="EvaluationTime.OnExecute"/>.</param> public BaseEvent(uint requestorId = 0, EvaluationTime evaluationTime = EvaluationTime.OnExecute) : this(evaluationTime) { RequestorId = requestorId; }