/// <summary> /// Checks that the user and target of a /// <see cref="AfterInteractEventArgs"/> are within a certain distance /// without any entity that matches the collision mask obstructing them. /// If the <paramref name="range"/> is zero or negative, /// this method will only check if nothing obstructs the entity and component. /// </summary> /// <param name="args">The event args to use.</param> /// <param name="range"> /// Maximum distance between the two entity and set of map coordinates. /// </param> /// <param name="collisionMask">The mask to check for collisions.</param> /// <param name="predicate"> /// A predicate to check whether to ignore an entity or not. /// If it returns true, it will be ignored. /// </param> /// <param name="ignoreInsideBlocker"> /// If true and both the user and target are inside /// the obstruction, ignores the obstruction and considers the interaction /// unobstructed. /// Therefore, setting this to true makes this check more permissive, /// such as allowing an interaction to occur inside something impassable /// (like a wall). The default, false, makes the check more restrictive. /// </param> /// <param name="popup"> /// Whether or not to popup a feedback message on the user entity for /// it to see. /// </param> /// <returns> /// True if the two points are within a given range without being obstructed. /// </returns> public bool InRangeUnobstructed( AfterInteractEventArgs args, float range = InteractionRange, CollisionGroup collisionMask = CollisionGroup.Impassable, Ignored?predicate = null, bool ignoreInsideBlocker = false, bool popup = false) { var user = args.User; var target = args.Target; predicate ??= e => e == user; MapCoordinates otherPosition; if (target == null) { otherPosition = args.ClickLocation.ToMap(EntityManager); } else { otherPosition = target.Transform.MapPosition; predicate += e => e == target; } return(InRangeUnobstructed(user, otherPosition, range, collisionMask, predicate, ignoreInsideBlocker, popup)); }
public void AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null) { return; } if (!eventArgs.Target.TryGetComponent(out ISharedBodyManagerComponent body)) { return; } if (!ActionBlockerSystem.CanInteract(eventArgs.User)) { return; } if (eventArgs.User != eventArgs.Target && !eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true)) { return; } if (Owner.TryGetComponent(out StackComponent stack) && !stack.Use(1)) { return; } foreach (var(type, amount) in Heal) { body.ChangeDamage(type, -amount, true); } }
private void SendBodyPartListToUser(AfterInteractEventArgs eventArgs, IBody body) { // Create dictionary to send to client (text to be shown : data sent back if selected) var toSend = new Dictionary <string, int>(); foreach (var(key, value) in body.Parts) { // For each limb in the target, add it to our cache if it is a valid option. if (value.CanAddMechanism(this)) { OptionsCache.Add(IdHash, value); toSend.Add(key + ": " + value.Name, IdHash++); } } if (OptionsCache.Count > 0 && eventArgs.User.TryGetComponent(out IActorComponent? actor)) { OpenSurgeryUI(actor.playerSession); UpdateSurgeryUIBodyPartRequest(actor.playerSession, toSend); PerformerCache = eventArgs.User; BodyCache = body; } else // If surgery cannot be performed, show message saying so. { eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("You see no way to install the {0}.", Owner.Name)); } }
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (!InteractionChecks.InRangeUnobstructed(eventArgs)) { return; } if (eventArgs.Target == null) { return; } if (!eventArgs.Target.TryGetComponent(out DamageableComponent damagecomponent)) { return; } if (Owner.TryGetComponent(out StackComponent stackComponent)) { if (!stackComponent.Use(1)) { Owner.Delete(); return; } damagecomponent.TakeHealing(Damage, Heal); return; } damagecomponent.TakeHealing(Damage, Heal); Owner.Delete(); }
public static bool InRangeUnOccluded(AfterInteractEventArgs args, float range, Ignored?predicate, bool ignoreInsideBlocker = true) { var originPos = args.User.Transform.MapPosition; var otherPos = args.Target.Transform.MapPosition; return(InRangeUnOccluded(originPos, otherPos, range, predicate, ignoreInsideBlocker)); }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: false, popup: true, collisionMask: Shared.Physics.CollisionGroup.MobImpassable)) { return(true); } if (Charges <= 0) { eventArgs.User.PopupMessage(Loc.GetString("crayon-interact-not-enough-left-text")); return(true); } var entityManager = IoCManager.Resolve <IServerEntityManager>(); var entity = entityManager.SpawnEntity("CrayonDecal", eventArgs.ClickLocation); if (entity.TryGetComponent(out AppearanceComponent? appearance)) { appearance.SetData(CrayonVisuals.State, SelectedState); appearance.SetData(CrayonVisuals.Color, _color); appearance.SetData(CrayonVisuals.Rotation, eventArgs.User.Transform.LocalRotation); } if (!string.IsNullOrEmpty(_useSound)) { SoundSystem.Play(Filter.Pvs(Owner), _useSound, Owner, AudioHelpers.WithVariation(0.125f)); } // Decrease "Ammo" Charges--; Dirty(); return(true); }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true)) { return(true); } if (!Owner.TryGetComponent(out StackComponent? stack)) { return(true); } var mapManager = IoCManager.Resolve <IMapManager>(); var location = eventArgs.ClickLocation.AlignWithClosestGridTile(); var locationMap = location.ToMap(Owner.EntityManager); if (locationMap.MapId == MapId.Nullspace) { return(true); } mapManager.TryGetGrid(location.GetGridId(Owner.EntityManager), out var mapGrid); if (_outputTiles == null) { return(true); } foreach (var currentTile in _outputTiles) { var currentTileDefinition = (ContentTileDefinition)_tileDefinitionManager[currentTile]; if (mapGrid != null) { var tile = mapGrid.GetTileRef(location); var baseTurf = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId]; if (HasBaseTurf(currentTileDefinition, baseTurf.Name)) { if (!EntitySystem.Get <StackSystem>().Use(Owner.Uid, stack, 1)) { continue; } PlaceAt(mapGrid, location, currentTileDefinition.TileId); break; } } else if (HasBaseTurf(currentTileDefinition, "space")) { mapGrid = mapManager.CreateGrid(locationMap.MapId); mapGrid.WorldPosition = locationMap.Position; location = new EntityCoordinates(mapGrid.GridEntityId, Vector2.Zero); PlaceAt(mapGrid, location, _tileDefinitionManager[_outputTiles[0]].TileId, mapGrid.TileSize / 2f); break; } } return(true); }
/// <inheritdoc /> public void AfterInteract(AfterInteractEventArgs eventArgs) { if (!InteractionChecks.InRangeUnobstructed(eventArgs)) { return; } if (!_mapManager.TryGetGrid(eventArgs.ClickLocation.GridID, out var grid)) { return; } var snapPos = grid.SnapGridCellFor(eventArgs.ClickLocation, SnapGridOffset.Center); var snapCell = grid.GetSnapGridCell(snapPos, SnapGridOffset.Center); if (grid.GetTileRef(snapPos).Tile.IsEmpty) { return; } foreach (var snapComp in snapCell) { if (snapComp.Owner.TryGetComponent <WireComponent>(out var wire) && wire.WireType == _blockingWireType) { return; } } if (Owner.TryGetComponent(out StackComponent stack) && !stack.Use(1)) { return; } _entityManager.SpawnEntity(_wirePrototypeID, grid.GridTileToLocal(snapPos)); }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null) { return(false); } CloseAllSurgeryUIs(); OptionsCache.Clear(); PerformerCache = null; BodyCache = null; if (_entities.TryGetComponent(eventArgs.Target.Value, out SharedBodyComponent? body)) { SendBodyPartListToUser(eventArgs, body); } else if (_entities.TryGetComponent <SharedBodyPartComponent?>(eventArgs.Target.Value, out var part)) { DebugTools.AssertNotNull(part); if (!part.TryAddMechanism(this)) { eventArgs.Target.Value.PopupMessage(eventArgs.User, Loc.GetString("mechanism-component-cannot-fit-message")); } } return(true); }
private void SendBodyPartListToUser(AfterInteractEventArgs eventArgs, SharedBodyComponent body) { // Create dictionary to send to client (text to be shown : data sent back if selected) var toSend = new Dictionary <string, int>(); foreach (var(part, slot) in body.Parts) { // For each limb in the target, add it to our cache if it is a valid option. if (part.CanAddMechanism(this)) { OptionsCache.Add(IdHash, slot); toSend.Add(part + ": " + part.Name, IdHash++); } } if (OptionsCache.Count > 0 && _entities.TryGetComponent(eventArgs.User, out ActorComponent? actor)) { OpenSurgeryUI(actor.PlayerSession); UpdateSurgeryUIBodyPartRequest(actor.PlayerSession, toSend); PerformerCache = eventArgs.User; BodyCache = body; } else // If surgery cannot be performed, show message saying so. { eventArgs.Target?.PopupMessage(eventArgs.User, Loc.GetString("mechanism-component-no-way-to-install-message", ("partName", Name: _entities.GetComponent <MetaDataComponent>(Owner).EntityName))); } }
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (!InteractionChecks.InRangeUnobstructed(eventArgs)) { return; } if (eventArgs.Target == null) { return; } if (eventArgs.Target.TryGetComponent <BodySystem.BodyManagerComponent>(out BodySystem.BodyManagerComponent bodyManager)) { _surgeryOptionsCache.Clear(); var toSend = new Dictionary <string, string>(); foreach (var(key, value) in bodyManager.PartDictionary) { if (value.SurgeryCheck(_surgeryToolClass)) { _surgeryOptionsCache.Add(key, value); toSend.Add(key, value.Name); } } if (_surgeryOptionsCache.Count > 0) { OpenSurgeryUI(eventArgs.User); UpdateSurgeryUI(eventArgs.User, toSend); _performerCache = eventArgs.User; _targetCache = bodyManager; } } }
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true)) { return; } //Make sure we have the attacking entity if (eventArgs.Target == null || !Owner.TryGetComponent(out SolutionComponent? solution) || !solution.Injector) { return; } var targetEntity = eventArgs.Target; //Handle injecting/drawing for solutions if (targetEntity.TryGetComponent <SolutionComponent>(out var targetSolution) && targetSolution.Injectable) { if (_toggleState == InjectorToggleMode.Inject) { TryInject(targetSolution, eventArgs.User); } else if (_toggleState == InjectorToggleMode.Draw) { TryDraw(targetSolution, eventArgs.User); } }
public async Task <bool> AfterInteract(AfterInteractEventArgs eventArgs) { if (_wirePrototypeID == null) { return(true); } if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true)) { return(true); } if (!_mapManager.TryGetGrid(eventArgs.ClickLocation.GetGridId(Owner.EntityManager), out var grid)) { return(true); } var snapPos = grid.SnapGridCellFor(eventArgs.ClickLocation, SnapGridOffset.Center); var snapCell = grid.GetSnapGridCell(snapPos, SnapGridOffset.Center); if (grid.GetTileRef(snapPos).Tile.IsEmpty) { return(true); } foreach (var snapComp in snapCell) { if (snapComp.Owner.TryGetComponent <WireComponent>(out var wire) && wire.WireType == _blockingWireType) { return(true); } } if (Owner.TryGetComponent <StackComponent>(out var stack) && !stack.Use(1)) { return(true); } Owner.EntityManager.SpawnEntity(_wirePrototypeID, grid.GridTileToLocal(snapPos)); return(true); }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { var solutionContainerSystem = EntitySystem.Get <SolutionContainerSystem>(); if (eventArgs.Target == null || !eventArgs.CanReach) { return(false); } var targetEntity = eventArgs.Target; if (eventArgs.Target.HasComponent <ReagentTankComponent>() && solutionContainerSystem.TryGetDrainableSolution(targetEntity.Uid, out var targetSolution) && solutionContainerSystem.TryGetDrainableSolution(Owner.Uid, out var container)) { var transfer = ReagentUnit.Min(container.AvailableVolume, targetSolution.DrainAvailable); if (transfer > 0) { var drained = solutionContainerSystem.Drain(targetEntity.Uid, targetSolution, transfer); solutionContainerSystem.TryAddSolution(Owner.Uid, container, drained); SoundSystem.Play(Filter.Pvs(Owner), _refillSound.GetSound(), Owner); eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("fire-extinguisher-component-after-interact-refilled-message", ("owner", Owner))); } return(true); } return(false); }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null) { return(false); } // This area is dirty but not sure of an easier way to do it besides add an interface or somethin bool changed = false; if (eventArgs.Target.TryGetComponent(out RevolverBarrelComponent revolverBarrel)) { for (var i = 0; i < Capacity; i++) { var ammo = TakeAmmo(); if (ammo == null) { break; } if (revolverBarrel.TryInsertBullet(eventArgs.User, ammo)) { changed = true; continue; } // Take the ammo back TryInsertAmmo(eventArgs.User, ammo); break; } } else if (eventArgs.Target.TryGetComponent(out BoltActionBarrelComponent boltActionBarrel)) { for (var i = 0; i < Capacity; i++) { var ammo = TakeAmmo(); if (ammo == null) { break; } if (boltActionBarrel.TryInsertBullet(eventArgs.User, ammo)) { changed = true; continue; } // Take the ammo back TryInsertAmmo(eventArgs.User, ammo); break; } } if (changed) { UpdateAppearance(); } return(true); }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null) { return(false); } if (!eventArgs.Target.HasComponent <DamageableComponent>()) { return(true); } if (!EntitySystem.Get <ActionBlockerSystem>().CanInteract(eventArgs.User)) { return(true); } if (eventArgs.User != eventArgs.Target && !eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true)) { return(true); } if (Owner.TryGetComponent <SharedStackComponent>(out var stack) && !EntitySystem.Get <StackSystem>().Use(Owner.Uid, 1, stack)) { return(true); } EntitySystem.Get <DamageableSystem>().TryChangeDamage(eventArgs.Target.Uid, Damage, true); return(true); }
public void AfterInteract(AfterInteractEventArgs eventArgs) { if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true)) { return; } if (!Owner.TryGetComponent(out StackComponent stack)) { return; } var location = eventArgs.ClickLocation.AlignWithClosestGridTile(); var locationMap = location.ToMap(Owner.EntityManager); var desiredTile = (ContentTileDefinition)_tileDefinitionManager[_outputTile]; if (_mapManager.TryGetGrid(location.GetGridId(Owner.EntityManager), out var mapGrid)) { var tile = mapGrid.GetTileRef(location); var baseTurf = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId]; if (HasBaseTurf(desiredTile, baseTurf.Name) && eventArgs.Target == null && stack.Use(1)) { PlaceAt(mapGrid, location, desiredTile.TileId); } } else if (HasBaseTurf(desiredTile, "space")) { mapGrid = _mapManager.CreateGrid(locationMap.MapId); mapGrid.WorldPosition = locationMap.Position; location = new EntityCoordinates(mapGrid.GridEntityId, Vector2.Zero); PlaceAt(mapGrid, location, desiredTile.TileId, mapGrid.TileSize / 2f); } }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null || !eventArgs.CanReach) { return(false); } if (eventArgs.Target.TryGetComponent(out ReagentTankComponent? tank) && eventArgs.Target.TryGetComponent(out ISolutionInteractionsComponent? targetSolution) && targetSolution.CanDrain && Owner.TryGetComponent(out SolutionContainerComponent? container)) { var trans = ReagentUnit.Min(container.EmptyVolume, targetSolution.DrainAvailable); if (trans > 0) { var drained = targetSolution.Drain(trans); container.TryAddSolution(drained); SoundSystem.Play(Filter.Pvs(Owner), _refillSound.GetSound(), Owner); eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("fire-extinguisher-component-after-interact-refilled-message", ("owner", Owner))); } return(true); } return(false); }
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null) { return; } CloseAllSurgeryUIs(); OptionsCache.Clear(); PerformerCache = null; BodyCache = null; if (eventArgs.Target.TryGetComponent(out IBody? body)) { SendBodyPartListToUser(eventArgs, body); } else if (eventArgs.Target.TryGetComponent <IBodyPart>(out var part)) { DebugTools.AssertNotNull(part); if (!part.TryAddMechanism(this)) { eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("You can't fit it in!")); } } }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (_wirePrototypeID == null) { return(true); } if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true)) { return(true); } if (!_mapManager.TryGetGrid(eventArgs.ClickLocation.GetGridId(Owner.EntityManager), out var grid)) { return(true); } var snapPos = grid.TileIndicesFor(eventArgs.ClickLocation); if (grid.GetTileRef(snapPos).Tile.IsEmpty) { return(true); } foreach (var anchored in grid.GetAnchoredEntities(snapPos)) { if (Owner.EntityManager.ComponentManager.TryGetComponent <WireComponent>(anchored, out var wire) && wire.WireType == _blockingWireType) { return(true); } } if (Owner.TryGetComponent <StackComponent>(out var stack) && !stack.Use(1)) { return(true); } Owner.EntityManager.SpawnEntity(_wirePrototypeID, grid.GridTileToLocal(snapPos)); return(true); }
/// <summary> /// Called when clicking on entities while holding in active hand /// </summary> /// <param name="eventArgs"></param> void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (!InteractionChecks.InRangeUnobstructed(eventArgs)) { return; } //Make sure we have the attacking entity if (eventArgs.Target == null || !_internalContents.Injector) { return; } var targetEntity = eventArgs.Target; //Handle injecting/drawing for solutions if (targetEntity.TryGetComponent <SolutionComponent>(out var targetSolution) && targetSolution.Injectable) { if (_toggleState == InjectorToggleMode.Inject) { TryInject(targetSolution, eventArgs.User); } else if (_toggleState == InjectorToggleMode.Draw) { TryDraw(targetSolution, eventArgs.User); } }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null || !eventArgs.CanReach) { return(false); } if (eventArgs.Target.TryGetComponent(out ReagentTankComponent? tank) && eventArgs.Target.TryGetComponent(out ISolutionInteractionsComponent? targetSolution) && targetSolution.CanDrain && Owner.TryGetComponent(out SolutionContainerComponent? container)) { var trans = ReagentUnit.Min(container.EmptyVolume, targetSolution.DrainAvailable); if (trans > 0) { var drained = targetSolution.Drain(trans); container.TryAddSolution(drained); EntitySystem.Get <AudioSystem>().PlayFromEntity("/Audio/Effects/refill.ogg", Owner); eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("{0:TheName} is now refilled", Owner)); } return(true); } return(false); }
private void SendBodyPartListToUser(AfterInteractEventArgs eventArgs, BodyManagerComponent bodyManager) { // Create dictionary to send to client (text to be shown : data sent back if selected) var toSend = new Dictionary <string, int>(); foreach (var(key, value) in bodyManager.Parts) { // For each limb in the target, add it to our cache if it is a valid option. if (value.CanInstallMechanism(ContainedMechanism)) { _optionsCache.Add(_idHash, value); toSend.Add(key + ": " + value.Name, _idHash++); } } if (_optionsCache.Count > 0) { OpenSurgeryUI(eventArgs.User.GetComponent <BasicActorComponent>().playerSession); UpdateSurgeryUIBodyPartRequest(eventArgs.User.GetComponent <BasicActorComponent>().playerSession, toSend); _performerCache = eventArgs.User; _bodyManagerComponentCache = bodyManager; } else // If surgery cannot be performed, show message saying so. { eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("You see no way to install the {0}.", Owner.Name)); } }
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null) { return; } CloseAllSurgeryUIs(); _optionsCache.Clear(); _performerCache = null; _bodyManagerComponentCache = null; if (eventArgs.Target.TryGetComponent <BodyManagerComponent>(out var bodyManager)) { SendBodyPartListToUser(eventArgs, bodyManager); } else if (eventArgs.Target.TryGetComponent <DroppedBodyPartComponent>(out var droppedBodyPart)) { DebugTools.AssertNotNull(droppedBodyPart.ContainedBodyPart); if (!droppedBodyPart.ContainedBodyPart.TryInstallDroppedMechanism(this)) { eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("You can't fit it in!")); } } }
/// <summary> /// Default interaction check for after attack interaction types. /// Same as <see cref="SharedInteractionSystem.InRangeUnobstructed"/>, but defaults to allow inside blockers. /// Validates that attacker is in range of the attacked entity, if there is such an entity. /// If there is no attacked entity, validates that they are in range of the clicked position. /// Additionally shows a popup if validation fails. /// </summary> public static bool InRangeUnobstructed(AfterInteractEventArgs eventArgs, bool insideBlockerValid = true) { if (eventArgs.Target != null) { if (!EntitySystem.Get <SharedInteractionSystem>().InRangeUnobstructed(eventArgs.User.Transform.MapPosition, eventArgs.Target.Transform.WorldPosition, ignoredEnt: eventArgs.Target, insideBlockerValid: insideBlockerValid)) { var localizationManager = IoCManager.Resolve <ILocalizationManager>(); eventArgs.Target.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!")); return(false); } } else { var mapManager = IoCManager.Resolve <IMapManager>(); if (!EntitySystem.Get <SharedInteractionSystem>().InRangeUnobstructed(eventArgs.User.Transform.MapPosition, eventArgs.ClickLocation.ToMapPos(mapManager), ignoredEnt: eventArgs.User, insideBlockerValid: insideBlockerValid)) { var localizationManager = IoCManager.Resolve <ILocalizationManager>(); eventArgs.User.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!")); return(false); } } return(true); }
void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null) { return; } CloseAllSurgeryUIs(); _optionsCache.Clear(); _performerCache = null; _bodyManagerComponentCache = null; if (eventArgs.Target.TryGetComponent <BodyManagerComponent>(out BodyManagerComponent bodyManager)) { SendBodyPartListToUser(eventArgs, bodyManager); } else if (eventArgs.Target.TryGetComponent <DroppedBodyPartComponent>(out DroppedBodyPartComponent droppedBodyPart)) { if (droppedBodyPart.ContainedBodyPart == null) { Logger.Debug("Installing a mechanism was attempted on an IEntity with a DroppedBodyPartComponent that doesn't have a BodyPart in it!"); throw new InvalidOperationException("A DroppedBodyPartComponent exists without a BodyPart in it!"); } if (!droppedBodyPart.ContainedBodyPart.TryInstallDroppedMechanism(this)) { _sharedNotifyManager.PopupMessage(eventArgs.Target, eventArgs.User, Loc.GetString("You can't fit it in!")); } } }
public void AfterInteract(AfterInteractEventArgs eventArgs) { if (!Owner.TryGetComponent(out SolutionComponent tank)) { return; } if (tank.Solution.GetReagentQuantity(_fuelType) == 0) { Owner.PopupMessage(eventArgs.User, Loc.GetString("{0:theName} is out of {1}!", Owner, _fuelName)); } else { tank.TryRemoveReagent(_fuelType, ReagentUnit.New(_fuelCost)); var playerPos = eventArgs.User.Transform.Coordinates; var direction = (eventArgs.ClickLocation.Position - playerPos.Position).Normalized; playerPos.Offset(direction / 2); var spray = _serverEntityManager.SpawnEntity(_sprayType, playerPos); spray.GetComponent <AppearanceComponent>() .SetData(ExtinguisherVisuals.Rotation, direction.ToAngle().Degrees); spray.GetComponent <GasVaporComponent>().StartMove(direction, 5); EntitySystem.Get <AudioSystem>().PlayFromEntity(_spraySound, Owner); } }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { var solutionsSys = EntitySystem.Get <SolutionContainerSystem>(); if (!eventArgs.InRangeUnobstructed() || eventArgs.Target == null) { return(false); } if (!_entities.HasComponent <SolutionContainerManagerComponent>(Owner)) { return(false); } var target = eventArgs.Target !.Value; if (!_entities.HasComponent <SolutionContainerManagerComponent>(target)) { return(false); } if (CanReceive && _entities.TryGetComponent(target, out ReagentTankComponent? tank) && solutionsSys.TryGetRefillableSolution(Owner, out var ownerRefill) && solutionsSys.TryGetDrainableSolution(target, out var targetDrain)) { var transferred = DoTransfer(eventArgs.User, target, targetDrain, Owner, ownerRefill, tank.TransferAmount); if (transferred > 0) { var toTheBrim = ownerRefill.AvailableVolume == 0; var msg = toTheBrim ? "comp-solution-transfer-fill-fully" : "comp-solution-transfer-fill-normal"; target.PopupMessage(eventArgs.User, Loc.GetString(msg, ("owner", eventArgs.Target), ("amount", transferred), ("target", Owner))); return(true); } } if (CanSend && solutionsSys.TryGetRefillableSolution(target, out var targetRefill) && solutionsSys.TryGetDrainableSolution(Owner, out var ownerDrain)) { var transferred = DoTransfer(eventArgs.User, Owner, ownerDrain, target, targetRefill, TransferAmount); if (transferred > 0) { Owner.PopupMessage(eventArgs.User, Loc.GetString("comp-solution-transfer-transfer-solution", ("amount", transferred), ("target", target))); return(true); } } return(true); }
// Feeding someone else void IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null) { return; } TryUseFood(eventArgs.User, eventArgs.Target); }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (!eventArgs.CanReach) { return(false); } return(TryDoInject(eventArgs.Target, eventArgs.User)); }