/// <summary> /// Allow honking when barely conscious and when clicking anything /// </summary> public bool WillInteract(PositionalHandApply interaction, NetworkSide side) { if (interaction.HandObject != gameObject) { return(false); } return(Validations.CanApply(interaction.Performer, interaction.TargetObject, side, true, ReachRange.Unlimited, interaction.TargetVector) && allowUse); }
/// <summary> /// Performs common tool usage logic and also sends start / end action messages, and invokes a callback on success. /// </summary> /// <param name="handApply">interaction causing the tool use</param> /// <param name="seconds">seconds taken to perform the action, 0 if it should be instant</param> /// <param name="performerStartActionMessage">message to show performer when action begins.</param> /// <param name="othersStartActionMessage">message to show others when action begins.</param> /// <param name="performerFinishActionMessage">message to show performer when action completes successfully.</param> /// <param name="othersFinishActionMessage">message to show others when action completes successfully.</param> /// <param name="onSuccessfulCompletion">called when action is completed</param> public static void ServerUseToolWithActionMessages(PositionalHandApply handApply, float seconds, string performerStartActionMessage, string othersStartActionMessage, string performerFinishActionMessage, string othersFinishActionMessage, Action onSuccessfulCompletion) { ServerUseToolWithActionMessages(handApply.Performer, handApply.HandObject, ActionTarget.Tile(handApply.WorldPositionTarget), seconds, performerStartActionMessage, othersStartActionMessage, performerFinishActionMessage, othersFinishActionMessage, onSuccessfulCompletion); }
private IEnumerator CritHonk(PositionalHandApply clickData, LivingHealthMasterBase livingHealth) { yield return(WaitFor.Seconds(0.02f)); AudioSourceParameters audioSourceParameters = new AudioSourceParameters(pitch: -1f); //This plays it backwards, is that what you wanted? ShakeParameters shakeParameters = new ShakeParameters(true, 20, 5); SoundManager.PlayNetworkedAtPos(CommonSounds.Instance.ClownHonk, gameObject.AssumedWorldPosServer(), audioSourceParameters, true, sourceObj: GetHonkSoundObject(), shakeParameters: shakeParameters); livingHealth.ApplyDamageToBodyPart(clickData.Performer, CritDamage, AttackType.Energy, DamageType.Brute, BodyPartType.Head); }
/// <summary> /// Check if interaction is possible /// </summary> private bool WillInteract(PositionalHandApply apply) { if (!DefaultWillInteract.Default(apply, NetworkSide.Client)) { return(false); } return(Validations.HasItemTrait( PlayerManager.LocalPlayerScript.DynamicItemStorage.GetActiveHandSlot().ItemObject, CommonTraits.Instance.Wirecutter)); }
/// <summary> /// For most cases you should use InteractionMessageUtils.SendRequest() instead of this. /// /// Sends a request to the server to validate + perform the interaction. /// </summary> /// <param name="handApply">info on the interaction being performed. Each object involved in the interaction /// must have a networkidentity.</param> /// <param name="processorObject">object who has a component implementing IInteractionProcessor<PositionalHandApply> which /// will process the interaction on the server-side. This object must have a NetworkIdentity and there must only be one instance /// of this component on the object. For organization, we suggest that the component which is sending this message /// should be on the processorObject, as such this parameter should almost always be passed using "this.gameObject", and /// should almost always be either a component on the target object or a component on the used object</param> public static void Send(PositionalHandApply handApply, GameObject processorObject) { var msg = new RequestPositionalHandApplyMessage { TargetObject = handApply.TargetObject.GetComponent <NetworkIdentity>().netId, ProcessorObject = processorObject.GetComponent <NetworkIdentity>().netId, TargetVector = handApply.TargetVector }; msg.Send(); }
bool IMultitoolSlaveable.TrySetMaster(PositionalHandApply interaction, IMultitoolMasterable master) { SetMaster(master); if (Controller != null) { Controller.AddSlave(device); } return(true); }
/// <summary> /// Performs common tool usage logic and also sends start / end action messages, and invokes a callback on success. /// </summary> /// <param name="handApply">interaction causing the tool use</param> /// <param name="seconds">seconds taken to perform the action, 0 if it should be instant</param> /// <param name="performerStartActionMessage">message to show performer when action begins.</param> /// <param name="othersStartActionMessage">message to show others when action begins.</param> /// <param name="performerFinishActionMessage">message to show performer when action completes successfully.</param> /// <param name="othersFinishActionMessage">message to show others when action completes successfully.</param> /// <param name="onSuccessfulCompletion">called when action is completed</param> /// <param name="performerFailMessage">message to show performer when action completes unsuccessfully.</param> /// <param name="othersFailMessage">message to show others when action completes unsuccessfully.</param> /// <param name="onFailComplete">called when action is completed unsuccessfully.</param> /// <param name="playSound">Whether to play default tool sound</param> public static void ServerUseToolWithActionMessages(PositionalHandApply handApply, float seconds, string performerStartActionMessage, string othersStartActionMessage, string performerFinishActionMessage, string othersFinishActionMessage, Action onSuccessfulCompletion, string performerFailMessage = "", string othersFailMessage = "", Action onFailComplete = null, bool playSound = true) { ServerUseToolWithActionMessages(handApply.Performer, handApply.HandObject, ActionTarget.Tile(handApply.WorldPositionTarget), seconds, performerStartActionMessage, othersStartActionMessage, performerFinishActionMessage, othersFinishActionMessage, onSuccessfulCompletion, performerFailMessage, othersFailMessage, onFailComplete, playSound); }
public bool WillInteract(PositionalHandApply interaction, NetworkSide side) { if (interaction.HandObject == null) { return(false); } if (Validations.IsInReach(interaction.PerformerPlayerScript.WorldPos, interaction.WorldPositionTarget) == false) { return(false); } return(true); }
public void ServerPerformInteraction(PositionalHandApply interaction) { Vector3 worldPosition = interaction.WorldPositionTarget; var matrix = MatrixManager.AtPoint(worldPosition.CutToInt(), true); var localPosition = MatrixManager.WorldToLocal(worldPosition, matrix).CutToInt(); var metaDataNode = matrix.MetaDataLayer.Get(localPosition, false); if (metaDataNode.PipeData.Count > 0) { var gasMix = metaDataNode.PipeData[0].pipeData.GetMixAndVolume.GetGasMix(); Chat.AddExamineMsgFromServer(interaction.Performer, GetGasMixInfo(gasMix)); } }
protected override bool WillInteract(PositionalHandApply interaction, NetworkSide side) { if (!base.WillInteract(interaction, side)) { return(false); } //can only be used on tiles if (!Validations.HasComponent <InteractableTiles>(interaction.TargetObject)) { return(false); } return(true); }
private bool TryTransferToOven(PositionalHandApply interaction) { // Close the oven if nothing is held. if (interaction == null || interaction.UsedObject == null) { SoundManager.PlayNetworkedAtPos(doorCloseSfx, WorldPosition, sourceObj: gameObject); return(false); } // Add held item to the oven. ItemSlot storageSlot = storage.GetNextFreeIndexedSlot(); bool added = false; if (interaction.HandSlot.ItemObject.TryGetComponent(out Stackable stack)) { if (stack.Amount == 1) { added = Inventory.ServerTransfer(interaction.HandSlot, storageSlot); } else { var item = stack.ServerRemoveOne(); added = Inventory.ServerAdd(item, storageSlot); if (!added) { stack.ServerIncrease(1); // adds back the lost amount to prevent ovens from eating stackable items } } } else { added = Inventory.ServerTransfer(interaction.HandSlot, storageSlot); } if (storageSlot == null || added == false) { Chat.AddActionMsgToChat(interaction, "The oven's matter bins are full!", string.Empty); return(true); } if (storageSlot.ItemObject.TryGetComponent(out Cookable cookable) && cookable.CookableBy.HasFlag(CookSource.Oven)) { storedCookables.Add(storageSlot, cookable); } Chat.AddActionMsgToChat( interaction, $"You add the {interaction.HandObject.ExpensiveName()} to the oven.", $"{interaction.PerformerPlayerScript.visibleName} adds the {interaction.HandObject.ExpensiveName()} to the oven."); return(true); }
public bool WillInteract(PositionalHandApply interaction, NetworkSide side) { if (DefaultWillInteract.Default(interaction, side) == false) { return(false); } if (interaction.TargetObject == gameObject) { return(false); } return(true); }
private void ProcessPositionalHandApply(GameObject handObject, GameObject targetObj, Vector2 targetVector, GameObject processorObj, GameObject performerObj, HandSlot usedSlot) { //try to look up the components on the processor that can handle this interaction var processorComponents = InteractionMessageUtils.TryGetProcessors <PositionalHandApply>(processorObj); //invoke each component that can handle this interaction var handApply = PositionalHandApply.ByClient(performerObj, handObject, targetObj, targetVector, usedSlot); foreach (var processorComponent in processorComponents) { if (processorComponent.ServerProcessInteraction(handApply)) { //something happened, don't check further components return; } } }
public void ServerPerformInteraction(PositionalHandApply interaction) { Vector3Int worldPosInt = interaction.WorldPositionTarget.To2Int().To3Int(); MatrixInfo matrixinfo = MatrixManager.AtPoint(worldPosInt, true); var localPosInt = MatrixManager.WorldToLocalInt(worldPosInt, matrixinfo); var matrix = interaction.Performer.GetComponentInParent <Matrix>(); string toShow = ""; foreach (var pipeNode in matrix.GetPipeConnections(localPosInt)) { toShow += pipeNode.ToAnalyserExamineString() + "\n"; } Chat.AddExamineMsgFromServer(interaction.Performer, toShow); }
protected override bool WillInteract(PositionalHandApply interaction, NetworkSide side) { if (!base.WillInteract(interaction, side)) { return(false); } if (!Validations.IsTool(interaction.HandObject, ToolType.Wirecutter)) { return(false); } if (interaction.TargetObject != gameObject) { return(false); } return(true); }
public override void FinnishSurgeryProcedure(BodyPart OnBodyPart, PositionalHandApply interaction, Dissectible.PresentProcedure PresentProcedure) { base.FinnishSurgeryProcedure(OnBodyPart, interaction, PresentProcedure); if (PresentProcedure.RelatedBodyPart.ContainedIn != null) { PresentProcedure.ISon.SetBodyPartIsOpen(false, true); PresentProcedure.ISon.currentlyOn = PresentProcedure.RelatedBodyPart.ContainedIn.gameObject; } else { PresentProcedure.ISon.SetBodyPartIsOpen(false, false); PresentProcedure.ISon.currentlyOn = null; } OnBodyPart.RemoveFromBodyThis(); }
public override void FinnishSurgeryProcedure(BodyPart OnBodyPart, PositionalHandApply interaction, Dissectible.PresentProcedure PresentProcedure) { if (interaction.HandSlot.Item != null && interaction.HandSlot.Item.GetComponent <ItemAttributesV2>().HasTrait(RequiredTrait)) { OnBodyPart.HealDamage(interaction.UsedObject, HeelStrength, Affects); var stackable = interaction.UsedObject.GetComponent <Stackable>(); if (stackable != null) { stackable.ServerConsume(1); } else { Despawn.ServerSingle(interaction.UsedObject); } } }
public override void FinnishSurgeryProcedure(BodyPart OnBodyPart, PositionalHandApply interaction, Dissectible.PresentProcedure PresentProcedure) { base.FinnishSurgeryProcedure(OnBodyPart, interaction, PresentProcedure); if (interaction.HandSlot.Item != null && interaction.HandSlot.Item.GetComponent <ItemAttributesV2>().HasTrait(RequiredImplantTrait)) { if (OnBodyPart != null) { OnBodyPart.OrganStorage.ServerTryTransferFrom(interaction.HandSlot); } else { PresentProcedure.ISon.GetComponent <LivingHealthMasterBase>().BodyPartStorage.ServerTryTransferFrom(interaction.HandSlot); PresentProcedure.ISon.currentlyOn = null; } } }
// Click on disposal bin public override bool WillInteract(PositionalHandApply interaction, NetworkSide side) { if (DefaultWillInteract.Default(interaction, side) == false) { return(false); } if (interaction.HandObject == null) { return(false); } if (base.WillInteract(interaction, side)) { return(true); } // Bin accepts all items for disposal. return(MachineSecured); }
private bool CheckHandApply(GameObject target) { //call the used object's handapply interaction methods if it has any, for each object we are applying to var handApply = HandApply.ByLocalPlayer(target); var posHandApply = PositionalHandApply.ByLocalPlayer(target); //if handobj is null, then its an empty hand apply so we only need to check the receiving object if (handApply.HandObject != null) { //get all components that can handapply or PositionalHandApply var handAppliables = handApply.HandObject.GetComponents <MonoBehaviour>() .Where(c => c != null && c.enabled && (c is IInteractable <HandApply> || c is IInteractable <PositionalHandApply>)); foreach (var handAppliable in handAppliables) { var interacted = handAppliable is IInteractable <HandApply>? (handAppliable as IInteractable <HandApply>).Interact(handApply) : (handAppliable as IInteractable <PositionalHandApply>).Interact(posHandApply); if (interacted) { //we're done checking, something happened return(true); } } } //call the hand apply interaction methods on the target object if it has any var targetHandAppliables = handApply.TargetObject.GetComponents <MonoBehaviour>() .Where(c => c.enabled && (c is IInteractable <HandApply> || c is IInteractable <PositionalHandApply>)); foreach (var targetHandAppliable in targetHandAppliables) { var interacted = targetHandAppliable is IInteractable <HandApply>? (targetHandAppliable as IInteractable <HandApply>).Interact(handApply) : (targetHandAppliable as IInteractable <PositionalHandApply>).Interact(posHandApply); if (interacted) { //we're done checking, something happened return(true); } } return(false); }
private bool TryTransferToMicrowave(PositionalHandApply interaction) { // Close the microwave if nothing is held. if (interaction == null || interaction.UsedObject == null) { SoundManager.PlayNetworkedAtPos(doorSFX.GetRandomClip(), WorldPosition, sourceObj: gameObject); return(false); } // Add held item to the microwave. ItemSlot storageSlot = storage.GetNextFreeIndexedSlot(); bool added = false; if (interaction.HandSlot.ItemObject.TryGetComponent(out Stackable stack)) { if (stack.Amount == 1) { added = Inventory.ServerTransfer(interaction.HandSlot, storageSlot); } else { var item = stack.ServerRemoveOne(); added = Inventory.ServerAdd(item, storageSlot); if (!added) { stack.ServerIncrease(1); // adds back the lost amount to prevent microwaves from eating stackable items } } } else { added = Inventory.ServerTransfer(interaction.HandSlot, storageSlot); } if (storageSlot == null || added == false) { Chat.AddActionMsgToChat(interaction, "The microwave's matter bins are full!", string.Empty); return(true); } if (storageSlot.ItemObject.TryGetComponent(out Cookable cookable) && cookable.CookableBy.HasFlag(CookSource.Microwave)) { storedCookables.Add(storageSlot, cookable); }
// Click on disposal bin public override void ServerPerformInteraction(PositionalHandApply interaction) { currentInteraction = interaction; if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wrench) && MachineWrenchable) { TryUseWrench(); } else if (Validations.HasUsedActiveWelder(interaction) && MachineWeldable) { TryUseWelder(); } else if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver) && Screwdriverable) { TryUseScrewdriver(); } else if (MachineSecured) { StoreItem(); } }
protected override void ServerPerformInteraction(PositionalHandApply interaction) { //wirecutters can be used to cut this cable Vector3Int worldPosInt = interaction.WorldPositionTarget.To2Int().To3Int(); MatrixInfo matrix = MatrixManager.AtPoint(worldPosInt, true); var localPosInt = MatrixManager.WorldToLocalInt(worldPosInt, matrix); if (matrix.Matrix != null) { if (!matrix.Matrix.IsClearUnderfloorConstruction(localPosInt, true)) { return; } } else { return; } toDestroy(); }
private bool TryTransferToMicrowave(PositionalHandApply interaction) { // Close the microwave if nothing is held. if (interaction == null || interaction.UsedObject == null) { SoundManager.PlayNetworkedAtPos(doorSFX.GetRandomClip(), WorldPosition, sourceObj: gameObject); return(false); } // Add held item to the microwave. ItemSlot storageSlot = storage.GetNextFreeIndexedSlot(); if (storageSlot == null || Inventory.ServerTransfer(interaction.HandSlot, storageSlot) == false) { Chat.AddActionMsgToChat(interaction, "The microwave's matter bins are full!", string.Empty); return(true); } if (storageSlot.ItemObject.TryGetComponent(out Cookable cookable) && cookable.CookableBy.HasFlag(CookSource.Microwave)) { storedCookables.Add(storageSlot, cookable); }
private bool CheckClick() { ChangeDirection(); //currently there is nothing for ghosts to interact with, they only can change facing if (PlayerManager.LocalPlayerScript.IsGhost) { return(false); } bool ctrlClick = KeyboardInputManager.IsControlPressed(); if (!ctrlClick) { var handApplyTargets = MouseUtils.GetOrderedObjectsUnderMouse(); //go through the stack of objects and call any interaction components we find foreach (GameObject applyTarget in handApplyTargets) { if (CheckHandApply(applyTarget)) { return(true); } } //check empty space positional hand apply var posHandApply = PositionalHandApply.ByLocalPlayer(null); if (posHandApply.HandObject != null) { var handAppliables = posHandApply.HandObject.GetComponents <IBaseInteractable <PositionalHandApply> >() .Where(c => c != null && (c as MonoBehaviour).enabled); if (InteractionUtils.ClientCheckAndTrigger(handAppliables, posHandApply) != null) { return(true); } } } return(false); }
/// <summary> /// Server: /// Allow items to be stored by clicking on bags with item in hand /// and clicking items with bag in hand if CanClickPickup is enabled /// </summary> public void ServerPerformInteraction(PositionalHandApply interaction) { if (allowedToInteract == false) { return; } // See which item needs to be stored if (Validations.IsTarget(gameObject, interaction)) { // Add hand item to this storage Inventory.ServerTransfer(interaction.HandSlot, itemStorage.GetBestSlotFor(interaction.HandObject)); } // See if this item can click pickup else if (canClickPickup) { bool pickedUpSomething = false; Pickupable pickup; switch (pickupMode) { case PickupMode.Single: // Don't pick up items which aren't set as CanPickup pickup = interaction.TargetObject.GetComponent <Pickupable>(); if (pickup == null || pickup.CanPickup == false) { Chat.AddExamineMsgFromServer(interaction.Performer, "There's nothing to pickup!"); return; } // Store the clicked item var slot = itemStorage.GetBestSlotFor(interaction.TargetObject); if (slot == null) { Chat.AddExamineMsgFromServer(interaction.Performer, $"The {interaction.TargetObject.ExpensiveName()} doesn't fit!"); return; } Inventory.ServerAdd(interaction.TargetObject, slot); break; case PickupMode.Same: if (interaction.TargetObject == null || interaction.TargetObject.Item() == null) { Chat.AddExamineMsgFromServer(interaction.Performer, "There's nothing to pickup!"); return; } // Get all items of the same type on the tile and try to store them var itemsOnTileSame = MatrixManager.GetAt <ItemAttributesV2>(interaction.WorldPositionTarget.To2Int().To3Int(), true); if (itemsOnTileSame.Count == 0) { Chat.AddExamineMsgFromServer(interaction.Performer, "There's nothing to pickup!"); return; } foreach (var item in itemsOnTileSame) { // Don't pick up items which aren't set as CanPickup pickup = item.gameObject.GetComponent <Pickupable>(); if (pickup == null || pickup.CanPickup == false) { continue; } // Only try to add it if it matches the target object's traits if (item.HasAllTraits(interaction.TargetObject.Item().GetTraits())) { // Try to add each item to the storage // Can't break this loop when it fails because some items might not fit and // there might be stacks with space still if (Inventory.ServerAdd(item.gameObject, itemStorage.GetBestSlotFor(item.gameObject))) { pickedUpSomething = true; } } } Chat.AddExamineMsgFromServer(interaction.Performer, $"You put everything you could in the {gameObject.ExpensiveName()}."); break; case PickupMode.All: // Get all items on the tile and try to store them var itemsOnTileAll = MatrixManager.GetAt <ItemAttributesV2>(interaction.WorldPositionTarget.To2Int().To3Int(), true); if (itemsOnTileAll.Count == 0) { Chat.AddExamineMsgFromServer(interaction.Performer, "There's nothing to pickup!"); return; } foreach (var item in itemsOnTileAll) { // Don't pick up items which aren't set as CanPickup pickup = item.gameObject.GetComponent <Pickupable>(); if (pickup == null || pickup.CanPickup == false) { continue; } // Try to add each item to the storage // Can't break this loop when it fails because some items might not fit and // there might be stacks with space still if (Inventory.ServerAdd(item.gameObject, itemStorage.GetBestSlotFor(item.gameObject))) { pickedUpSomething = true; } } if (pickedUpSomething) { Chat.AddExamineMsgFromServer(interaction.Performer, $"You put everything you could in the {gameObject.ExpensiveName()}."); } else { Chat.AddExamineMsgFromServer(interaction.Performer, "There's nothing to pickup!"); } break; case PickupMode.DropClick: if (canQuickEmpty) { // Drop all items that are inside this storage var slots = itemStorage.GetItemSlots(); if (slots == null) { Chat.AddExamineMsgFromServer(interaction.Performer, "It's already empty!"); return; } if (PlayerManager.PlayerScript == null) { return; } if (Validations.IsInReachDistanceByPositions(PlayerManager.PlayerScript.registerTile.WorldPosition, interaction.WorldPositionTarget) == false) { return; } if (MatrixManager.IsPassableAtAllMatricesOneTile(interaction.WorldPositionTarget.RoundToInt(), CustomNetworkManager.Instance._isServer) == false) { return; } PlayerManager.PlayerScript.playerNetworkActions.CmdDropAllItems(itemStorage.GetIndexedItemSlot(0) .ItemStorageNetID, interaction.WorldPositionTarget); Chat.AddExamineMsgFromServer(interaction.Performer, $"You start dumping out the {gameObject.ExpensiveName()}."); } break; } } }
/// <summary> /// Client: /// Allow items to be stored by clicking on bags with item in hand /// and clicking items with bag in hand if CanClickPickup is enabled /// </summary> public bool WillInteract(PositionalHandApply interaction, NetworkSide side) { if (allowedToInteract == false) { return(false); } // Use default interaction checks if (DefaultWillInteract.Default(interaction, side) == false) { return(false); } // See which item needs to be stored if (Validations.IsTarget(gameObject, interaction)) { // We're the target // If player's hands are empty let Pickupable handle the interaction if (interaction.HandObject == null) { return(false); } // There's something in the player's hands // Check if item from the hand slot fits in this storage sitting in the world if (Validations.CanPutItemToStorage(interaction.PerformerPlayerScript, itemStorage, interaction.HandObject, side, examineRecipient: interaction.Performer) == false) { Chat.AddExamineMsgToClient($"The {interaction.HandObject.ExpensiveName()} doesn't fit!"); return(false); } return(true); } else if (canClickPickup) { // If we can click pickup then try to store the target object switch (pickupMode) { case PickupMode.Single: // See if there's an item to pickup if (interaction.TargetObject == null || interaction.TargetObject.Item() == null) { Chat.AddExamineMsgToClient("There's nothing to pickup!"); return(false); } if (!Validations.CanPutItemToStorage(interaction.PerformerPlayerScript, itemStorage, interaction.TargetObject, side, examineRecipient: interaction.Performer)) { // In Single pickup mode if the target item doesn't // fit then don't interact Chat.AddExamineMsgToClient($"The {interaction.TargetObject.ExpensiveName()} doesn't fit!"); return(false); } break; case PickupMode.Same: if (interaction.TargetObject == null) { // If there's nothing to compare then don't interact Chat.AddExamineMsgToClient("There's nothing to pickup!"); return(false); } break; } // In Same and All pickup modes other items on the // tile could still be picked up, so we interact return(true); } else { // We're not the target and we can't click pickup so don't do anything return(false); } }
// TODO: should be requireLink but hardcoded to false for now, // doors don't know about links, only the switches bool IMultitoolSlaveable.TrySetMaster(PositionalHandApply interaction, IMultitoolMasterable master) { SetMaster(master); return(true); }
public override void UnsuccessfulStep(BodyPart OnBodyPart, PositionalHandApply interaction, Dissectible.PresentProcedure PresentProcedure) { OnBodyPart.TakeDamage(interaction.UsedObject, HeelStrength * 0.1f, FailAttackType, Affects); }
public override void Process() { var performer = SentByPlayer.GameObject; if (SentByPlayer == null || SentByPlayer.Script == null || SentByPlayer.Script.ItemStorage == null) { return; } if (InteractionType == typeof(PositionalHandApply)) { //look up item in active hand slot var clientStorage = SentByPlayer.Script.ItemStorage; var usedSlot = clientStorage.GetActiveHandSlot(); var usedObject = clientStorage.GetActiveHandSlot().ItemObject; LoadMultipleObjects(new uint[] { TargetObject, ProcessorObject }); var targetObj = NetworkObjects[0]; var processorObj = NetworkObjects[1]; var interaction = PositionalHandApply.ByClient(performer, usedObject, targetObj, TargetVector, usedSlot, Intent, TargetBodyPart); ProcessInteraction(interaction, processorObj); } else if (InteractionType == typeof(HandApply)) { var clientStorage = SentByPlayer.Script.ItemStorage; var usedSlot = clientStorage.GetActiveHandSlot(); var usedObject = clientStorage.GetActiveHandSlot().ItemObject; LoadMultipleObjects(new uint[] { TargetObject, ProcessorObject }); var targetObj = NetworkObjects[0]; var processorObj = NetworkObjects[1]; var interaction = HandApply.ByClient(performer, usedObject, targetObj, TargetBodyPart, usedSlot, Intent, IsAltUsed); ProcessInteraction(interaction, processorObj); } else if (InteractionType == typeof(AimApply)) { var clientStorage = SentByPlayer.Script.ItemStorage; var usedSlot = clientStorage.GetActiveHandSlot(); var usedObject = clientStorage.GetActiveHandSlot().ItemObject; LoadNetworkObject(ProcessorObject); var processorObj = NetworkObject; var interaction = AimApply.ByClient(performer, TargetVector, usedObject, usedSlot, MouseButtonState, Intent); ProcessInteraction(interaction, processorObj); } else if (InteractionType == typeof(MouseDrop)) { LoadMultipleObjects(new uint[] { UsedObject, TargetObject, ProcessorObject }); var usedObj = NetworkObjects[0]; var targetObj = NetworkObjects[1]; var processorObj = NetworkObjects[2]; var interaction = MouseDrop.ByClient(performer, usedObj, targetObj, Intent); ProcessInteraction(interaction, processorObj); } else if (InteractionType == typeof(HandActivate)) { LoadNetworkObject(ProcessorObject); var processorObj = NetworkObject; var performerObj = SentByPlayer.GameObject; //look up item in active hand slot var clientStorage = SentByPlayer.Script.ItemStorage; var usedSlot = clientStorage.GetActiveHandSlot(); var usedObject = clientStorage.GetActiveHandSlot().ItemObject; var interaction = HandActivate.ByClient(performer, usedObject, usedSlot, Intent); ProcessInteraction(interaction, processorObj); } else if (InteractionType == typeof(InventoryApply)) { LoadMultipleObjects(new uint[] { ProcessorObject, UsedObject, Storage }); var processorObj = NetworkObjects[0]; var usedObj = NetworkObjects[1]; var storageObj = NetworkObjects[2]; ItemSlot targetSlot = null; if (SlotIndex == -1) { targetSlot = ItemSlot.GetNamed(storageObj.GetComponent <ItemStorage>(), NamedSlot); } else { targetSlot = ItemSlot.GetIndexed(storageObj.GetComponent <ItemStorage>(), SlotIndex); } //if used object is null, then empty hand was used ItemSlot fromSlot = null; if (usedObj == null) { fromSlot = SentByPlayer.Script.ItemStorage.GetActiveHandSlot(); } else { fromSlot = usedObj.GetComponent <Pickupable>().ItemSlot; } var interaction = InventoryApply.ByClient(performer, targetSlot, fromSlot, Intent, IsAltUsed); ProcessInteraction(interaction, processorObj); } else if (InteractionType == typeof(TileApply)) { var clientStorage = SentByPlayer.Script.ItemStorage; var usedSlot = clientStorage.GetActiveHandSlot(); var usedObject = clientStorage.GetActiveHandSlot().ItemObject; LoadNetworkObject(ProcessorObject); var processorObj = NetworkObject; processorObj.GetComponent <InteractableTiles>().ServerProcessInteraction(TileInteractionIndex, SentByPlayer.GameObject, TargetVector, processorObj, usedSlot, usedObject, Intent, TileApply.ApplyType.HandApply); } else if (InteractionType == typeof(TileMouseDrop)) { LoadMultipleObjects(new uint[] { UsedObject, ProcessorObject }); var usedObj = NetworkObjects[0]; var processorObj = NetworkObjects[1]; processorObj.GetComponent <InteractableTiles>().ServerProcessInteraction(TileInteractionIndex, SentByPlayer.GameObject, TargetVector, processorObj, null, usedObj, Intent, TileApply.ApplyType.MouseDrop); } }