public static void StopAnimation(ItemEquippable item = null)
        {
            if (ActiveItem?.Owner?.IsLocallyOwned != true)
            {
                return;
            }

            Instance.LogDebug("Aborting animation coroutine");
            if (item != null && item.Owner != ActiveItem.Owner)
            {
                Instance.LogError("The item is not owned by the local player.");
                return;
            }

            ActiveItem.StopCoroutine(AnimationSequence);

            if (item != null)
            {
                var gearPartHolder = item.GearPartHolder;
                gearPartHolder.FrontPartAnimator?.Rebind();
                gearPartHolder.ReceiverPartAnimator?.Rebind();
                gearPartHolder.StockPartAnimator?.Rebind();
                ActiveItem.Owner.AnimatorArms.Rebind();

                // This resets the animation weights, which fixes the
                // funky fingers created by rebinding AnimatorArms.
                ActiveItem.Owner.Inventory.PlayAnimationsForWieldedItem();
            }

            ActiveItem        = null;
            AnimationSequence = null;
        }
예제 #2
0
        // Handle selection effect and grid updates
        private void ItemSwitched(ItemEquippable item)
        {
            DividedBarShaderController UIBar = null;

            foreach (DividedBarShaderController d in UIMappings.Values)
            {
                d.SetUnselected();
            }
            UIMappings.TryGetValue(item.ItemDataBlock.inventorySlot, out UIBar);

            if (UIBar)
            {
                UIBar.SetSelected();
            }

            if (ItemEquippableEvents.IsCurrentItemShootableWeapon())
            {
                //Debug.Log("Item changed event: " + "MaxAmmo: " + item.GetMaxClip() + " Current ammo: " + item.GetCurrentClip() + " Inventory slot: " + item.ItemDataBlock.inventorySlot);
                BulletsInMag.maxAmmo     = item.GetMaxClip();
                BulletsInMag.currentAmmo = item.GetCurrentClip();
                BulletsInMag.UpdateAmmoGridDivisions();
                BulletsInMag.inventorySlot = item.ItemDataBlock.inventorySlot;
            }
            else
            {
                BulletsInMag.currentAmmo = 0;
                BulletsInMag.UpdateShaderVals(1, 1);
            }
        }
예제 #3
0
        private static void PlayerSwitchedWeapon(ItemEquippable item)
        {
            float muzzleDistance = 0;

            if (item.MuzzleAlign)
            {
                muzzleDistance = Vector3.Distance(item.transform.position, item.MuzzleAlign.position);
            }

            Log.Debug($"Item {item.ArchetypeName} - MuzzleDistance {muzzleDistance} - Allows DH? {muzzleDistance > 0.25f}");

            if (weaponArchetypes.TryGetValue(item.ArchetypeName, out VRWeaponData data))
            {
                m_current = data;

                item.transform.localScale = Vector3.one * m_current.scaleMultiplier;
            }
            else
            {
                if (item.ItemDataBlock.inventorySlot.Equals(Player.InventorySlot.GearStandard) || item.ItemDataBlock.inventorySlot.Equals(Player.InventorySlot.GearSpecial))
                {
                    VRWeaponData currentData = new VRWeaponData(Vector3.zero, Quaternion.identity, false);
                    currentData.allowsDoubleHanded = muzzleDistance > 0.25f;
                    weaponArchetypes.Add(item.ArchetypeName, currentData);
                    m_current = currentData;
                    Log.Debug($"Item {item.ArchetypeName} - MuzzleDistance {muzzleDistance} - Allows DH? {currentData.allowsDoubleHanded}");
                }
                else
                {
                    m_current = weaponArchetypes["Default"];
                }
            }
        }
 public static VRWeaponData GetVRWeaponData(ItemEquippable item)
 {
     if (item == null)
     {
         return(weaponArchetypes["Default"]);
     }
     else
     {
         return(GetVRWeaponData(item.ArchetypeName));
     }
 }
예제 #5
0
 internal void UpdateTransform()
 {
     if (ItemEquippableEvents.IsCurrentItemShootableWeapon())
     {
         ItemEquippable current = ItemEquippableEvents.currentItem;
         m_holoHolder.transform.rotation = Quaternion.LookRotation(current.MuzzleAlign.forward, current.MuzzleAlign.up);
         Vector3 posOffset      = VRConfig.configUseLeftHand.Value ? -offset : offset;
         float   muzzleDistance = (current.transform.position - current.MuzzleAlign.position).magnitude;
         m_holoHolder.transform.position = current.transform.TransformPoint(posOffset + new Vector3(0, 0, muzzleDistance * .5f));
     }
 }
예제 #6
0
 private void ChangedWeapon(ItemEquippable e)
 {
     if (ItemEquippableEvents.IsCurrentItemShootableWeapon() && PlayerLocomotionEvents.InControllablePLOCState())
     {
         Toggle(true);
     }
     else
     {
         Toggle(false);
     }
 }
예제 #7
0
 public static void ItemEquipped(ItemEquippable item)
 {
     if (OnPlayerWieldItem != null && item.Owner.IsLocallyOwned)
     {
         currentItem = item;
         Debug.Log("Item equip changed---");
         Debug.Log(item.ArchetypeName);
         Debug.Log(item.PublicName);
         OnPlayerWieldItem.Invoke(item);
     }
 }
예제 #8
0
        public static Vector3 GetCorrectedGripPosition(ItemEquippable item)
        {
            if (!currentItem.LeftHandGripTrans || !currentItem.MuzzleAlign)
            {
                Log.Warning("Trying to get grip position for null leftHandGripTrans or Muzzle!");
                return(Vector3.zero);
            }
            Vector3 offsetToGrip   = item.LeftHandGripTrans.position - item.transform.position;
            Vector3 normalToMuzzle = (item.MuzzleAlign.transform.position - item.transform.position).normalized;

            return(item.transform.position + Vector3.Project(offsetToGrip, normalToMuzzle) + normalToMuzzle * .1f);
        }
예제 #9
0
        private void HandleSelectionEffect(ItemEquippable item)
        {
            foreach (DividedBarShaderController d in m_inventoryToAmmoDisplayMapping.Values)
            {
                d.SetUnselected();
            }
            m_inventoryToAmmoDisplayMapping.TryGetValue(item.ItemDataBlock.inventorySlot, out DividedBarShaderController UIBar);

            if (UIBar)
            {
                UIBar.SetSelected();
            }
        }
예제 #10
0
        private void TryGetIcon(InventorySlotAmmo item, RadialItem radialItem)
        {
            if (m_retrievedIcons.ContainsKey(item.Slot))
            {
                return;
            }
            if (item.Slot == InventorySlot.GearMelee || item.Slot == InventorySlot.GearSpecial || item.Slot == InventorySlot.GearStandard || item.Slot == InventorySlot.GearClass)
            {
                if (PlayerBackpackManager.LocalBackpack.TryGetBackpackItem(item.Slot, out BackpackItem bp))
                {
                    if (bp == null || bp.Instance == null)
                    {
                        Log.Debug($"Got null BP or instance for {item.Slot}");
                        return;
                    }
                    ItemEquippable equippable = bp.Instance.Cast <ItemEquippable>();
                    if (equippable == null || equippable.GearIDRange == null)
                    {
                        Log.Debug("Equippable was null or GearIDRange was null when retrieving icon!");
                        return;
                    }
                    if (GearIconRendering.TryGetGearIconSprite(equippable.GearIDRange.GetChecksum(), out Sprite icon))
                    {
                        if (icon == null)
                        {
                            m_retrievedIcons[item.Slot] = null;
                            Log.Debug($"Failed to retrieve icon for {equippable.ArchetypeName}");
                            return;
                        }
                        m_retrievedIcons[item.Slot] = icon;

                        if (item.Slot == InventorySlot.GearMelee)
                        {
                            radialItem.SetIcon(icon, 1.5f);
                        }
                        else
                        {
                            radialItem.SetIcon(icon);
                        }

                        Log.Debug($"Retrieved icon for {equippable.ArchetypeName}!");
                    }
                    else
                    {
                        m_retrievedIcons[item.Slot] = null;
                        Log.Debug($"Failed to retrieve icon for {equippable.ArchetypeName}");
                    }
                }
            }
        }
예제 #11
0
 public void PlayerChangedItem(ItemEquippable item)
 {
     if (!m_setup || item == null)
     {
         return;
     }
     if (item.HasFlashlight && item.AmmoType != Player.AmmoType.None && VRConfig.configUseLaserPointerOnWeapons.Value)
     {
         TogglePointer(true);
         SetHolderTransform(item.MuzzleAlign);
     }
     else
     {
         TogglePointer(false);
     }
 }
예제 #12
0
 public void PlayerChangedItem(ItemEquippable item)
 {
     if (!setup)
     {
         return;
     }
     if (item.HasFlashlight && item.AmmoType != Player.AmmoType.None)
     {
         EnablePointer();
         SetHolderTransform(item.MuzzleAlign);
     }
     else
     {
         DisablePointer();
     }
 }
예제 #13
0
 private void MenuClosedQuick(float timeOpened)
 {
     if (!VRConfig.configUseQuickSwitch.Value)
     {
         return;
     }
     if (timeOpened < m_quickSwitchMaxMenuOpenTime)
     {
         ItemEquippable lastWielded = ItemEquippableEvents.lastWielded;
         if (lastWielded != null && lastWielded.ItemDataBlock != null)
         {
             InventorySlot slot = lastWielded.ItemDataBlock.inventorySlot;
             hackyInput[GetWieldActionForSlot(slot)] = true;
         }
     }
 }
예제 #14
0
        public static void ItemEquipped(ItemEquippable item)
        {
            if (OnPlayerWieldItem != null && item.Owner.IsLocallyOwned)
            {
                lastWielded = currentItem;
                currentItem = item;
                Log.Debug("Item equip changed---");
                Log.Debug(item.ArchetypeName);
                Log.Debug(item.PublicName);
                OnPlayerWieldItem.Invoke(item);

                if (currentItem.LeftHandGripTrans)
                {
                    Log.Debug($"Distance from left hand align to origin = {Vector3.Distance(currentItem.LeftHandGripTrans.position, currentItem.transform.position)}");
                }
            }
        }
예제 #15
0
        private void PlayerChangedItemHaptics(ItemEquippable item)
        {
            if (!VRConfig.configUseBhaptics.Value)
            {
                return;
            }

            StopWeaponReloadHaptics();

            if (Controllers.mainControllerType == HandType.Left)
            {
                m_hapticPlayer.SubmitRegistered(ARMS_CHANGE_ITEM_L_KEY);
            }
            else
            {
                m_hapticPlayer.SubmitRegistered(ARMS_CHANGE_ITEM_R_KEY);
            }
        }
        private static void ItemEquippable__DoTriggerWeaponAnimSequence__Postfix(
            ItemEquippable __instance,
            ref Il2CppSystem.Collections.IEnumerator __result)
        {
            // Even though this shouldn't happen, check just in case.
            if (!__instance.Owner.IsLocallyOwned)
            {
                return;
            }

            if (__instance != __instance.Owner.Inventory.WieldedItem)
            {
                Instance.LogWarning($"{nameof(ItemEquippable.DoTriggerWeaponAnimSequence)} was called on an item that isn't being wielded?");
                return;
            }

            Instance.LogDebug("Starting animation coroutine");
            ActiveItem        = __instance;
            AnimationSequence = __result;
        }
예제 #17
0
        private void UpdateBulletGridDivisions(ItemEquippable item)
        {
            if (ItemEquippableEvents.IsCurrentItemShootableWeapon())
            {
                if (!VRConfig.configUseNumbersForAmmoDisplay.Value)
                {
                    m_bulletsInMagDisplay.MaxValue     = item.GetMaxClip();
                    m_bulletsInMagDisplay.CurrentValue = item.GetCurrentClip();
                    m_bulletsInMagDisplay.UpdateAmmoGridDivisions();
                }
            }
            else
            {
                m_bulletsInMagDisplay.CurrentValue = 0;
                m_bulletsInMagDisplay.UpdateShaderVals(1, 1);

                m_numberBulletsInMagDisplay.text = "";
                m_numberBulletsInMagDisplay.ForceMeshUpdate(false);
            }
        }
예제 #18
0
        static void Postfix(FirstPersonItemHolder __instance, ItemEquippable ___WieldedItem)
        {
            if (PlayerVR.VRSetup && VRSettings.UseVRControllers)
            {
                if (___WieldedItem == null)
                {
                    return;
                }
                Vector3 gripOffset = ___WieldedItem.transform.position - ___WieldedItem.transform.TransformPoint(WeaponArchetypeVRData.GetVRWeaponData(___WieldedItem.ArchetypeName).transformToVRGrip);

                ___WieldedItem.transform.position = Controllers.GetControllerPosition() + gripOffset;

                if (VRSettings.twoHandedAimingEnabled && Controllers.aimingTwoHanded && WeaponArchetypeVRData.GetVRWeaponData(___WieldedItem.ArchetypeName).allowsDoubleHanded)
                {
                    ___WieldedItem.transform.rotation = Controllers.GetTwoHandedRotation();
                }
                else
                {
                    ___WieldedItem.transform.rotation = Controllers.GetControllerAimRotation();
                }
            }
        }
예제 #19
0
        private void CheckShouldDoubleHand(ItemEquippable item)
        {
            if (!VRConfig.configUseTwoHanded.Value)
            {
                return;
            }
            VRWeaponData itemData = GetVRWeaponData(item);

            if (itemData.allowsDoubleHanded)
            {
                Log.Debug("Item allows double hand!");
                if (VRConfig.configAlwaysDoubleHanded.Value)
                {
                    Log.Debug("Always double hand is on!");
                    aimingTwoHanded = true;
                }
            }
            else
            {
                aimingTwoHanded = false;
            }
        }
예제 #20
0
        public static void UpdateHeldItemTransform()
        {
            if (!VRConfig.configUseControllers.Value)
            {
                return;
            }

            ItemEquippable heldItem = PlayerAgent.FPItemHolder.WieldedItem;

            if (heldItem != null)
            {
                heldItem.transform.position = Controllers.GetControllerPosition() + WeaponArchetypeVRData.CalculateGripOffset();
                Vector3 recoilRot = heldItem.GetRecoilRotOffset();

                if (!Controllers.IsFiringFromADS())
                {
                    recoilRot.x *= 2f;
                }
                heldItem.transform.rotation       = Controllers.GetControllerAimRotation();
                heldItem.transform.localRotation *= Quaternion.Euler(recoilRot) * WeaponArchetypeVRData.GetVRWeaponData(heldItem).rotationOffset;
                heldItem.transform.position      += Controllers.GetControllerAimRotation() * heldItem.GetRecoilPosOffset();
            }
        }
예제 #21
0
        private bool AreControllersWithinDoubleHandStartDistance()
        {
            if (ItemEquippableEvents.IsCurrentItemShootableWeapon())
            {
                ItemEquippable currentHeldItem = ItemEquippableEvents.currentItem;
                if (currentHeldItem.LeftHandGripTrans)
                {
                    Vector3 correctedGripPosition = ItemEquippableEvents.GetCorrectedGripPosition();

                    if (GTFO_VR_Plugin.DEBUG_ENABLED)
                    {
                        if (VRConfig.configDebugShowTwoHHitboxes.Value)
                        {
                            DebugDraw3D.DrawSphere(correctedGripPosition, m_doubleHandStartDistance, ColorExt.Blue(0.2f));
                        }
                    }

                    return(Vector3.Distance(offhandController.transform.position, ItemEquippableEvents.GetCorrectedGripPosition()) < m_doubleHandStartDistance);
                }
            }

            return(Vector3.Distance(mainController.transform.position, offhandController.transform.position) < m_doubleHandStartDistance);
        }
예제 #22
0
 private bool AreControllersOutsideOfDoubleHandExitDistance()
 {
     if (ItemEquippableEvents.IsCurrentItemShootableWeapon())
     {
         ItemEquippable currentHeldItem = ItemEquippableEvents.currentItem;
         if (currentHeldItem.IsReloading)
         {
             return(false);
         }
         if (currentHeldItem.LeftHandGripTrans)
         {
             Vector3 correctedGripPosition = ItemEquippableEvents.GetCorrectedGripPosition();
             if (GTFO_VR_Plugin.DEBUG_ENABLED)
             {
                 if (VRConfig.configDebugShowTwoHHitboxes.Value)
                 {
                     DebugDraw3D.DrawSphere(correctedGripPosition, m_doubleHandLeaveDistance, ColorExt.Red(0.1f));
                 }
             }
             return(Vector3.Distance(offhandController.transform.position, ItemEquippableEvents.GetCorrectedGripPosition()) > m_doubleHandLeaveDistance);
         }
     }
     return(Vector3.Distance(mainController.transform.position, offhandController.transform.position) > m_doubleHandLeaveDistance);
 }
            private void Update()
            {
                if (GameStateManager.CurrentStateName != eGameStateName.InLevel)
                {
                    return;
                }

#if DEBUG_PLACEHOLDERS
                StorageSlotManager.Update();
#endif

                var raycast = GTFOUtils.GetComponentInSight <StorageSlotPlaceholder>(
                    playerAgent: this.playerAgent,
                    comp: out var placeholder,
                    hitPos: out var hitPos,
                    maxDistance: 1.5f,
                    layerMask: LayerManager.MASK_PLAYER_INTERACT_SPHERE);

                var wieldedItem = this.playerAgent.Inventory?.WieldedItem;
                var wieldedSlot = this.playerAgent.Inventory?.WieldedSlot;
                var isDroppable = wieldedSlot switch
                {
                    InventorySlot.ResourcePack => true,
                    InventorySlot.Consumable => true,
                    _ => false,
                };

                if (!raycast || placeholder?.enabled != true || !isDroppable)
                {
                    if (this.currentPlaceholder != null)
                    {
                        DisableInteractions = false;
                        if (this.ghostGO != null)
                        {
                            Destroy(this.ghostGO);
                            this.ghostGO = null;
                        }
                        // Clear the placeholder interaction
                        this.interact.PlayerSetSelected(false, this.playerAgent);
                        this.UpdateInteractionMessage("");
                        this.currentPlaceholder = null;
                    }
                    return;
                }

                var placeholderChanged = false;

                if (this.currentPlaceholder?.GetInstanceID() != placeholder.GetInstanceID())
                {
                    Instance.LogDebug("Changing placeholder");
#if DEBUG_PLACEHOLDERS
                    var wireframe = placeholder.GetComponent <RectangleWireframe>();
                    if (wireframe != null)
                    {
                        Instance.LogDebug($"Default placeholder position: {wireframe.DefaultPosition.ToString()}");
                    }
#endif
                    placeholderChanged      = true;
                    this.currentPlaceholder = placeholder;
                    DisableInteractions     = true;
                    // Disable the previous interaction
                    this.playerAgent.Interaction.UnSelectCurrentBestInteraction();
                    // This causes PlayerInteraction.HasWorldInteraction to
                    // evaluate to true. This is used to trick other
                    // interactions into thinking that the user already has an
                    // interaction prompt.
                    this.playerAgent.Interaction.m_bestSelectedInteract        = this.interact.Cast <IInteractable>();
                    this.playerAgent.Interaction.m_bestInteractInCurrentSearch = this.interact;
                }

                var wieldedItemChanged = false;

                if (this.currentWieldedItem?.GetInstanceID() != wieldedItem?.GetInstanceID())
                {
                    this.currentWieldedItem = wieldedItem;
                    wieldedItemChanged      = true;
                }

                if (placeholderChanged || wieldedItemChanged)
                {
                    this.UpdateInteractionMessage($"Drop {wieldedItem?.ItemDataBlock?.publicName ?? "item"}");

                    var prefabParts = ItemSpawnManager.m_loadedPrefabsPerItemMode[(int)ItemMode.Pickup][wieldedItem.ItemDataBlock.persistentID];
                    var transform   = wieldedSlot switch
                    {
                        InventorySlot.ResourcePack => this.currentPlaceholder.Slot.ResourcePack,
                        InventorySlot.Consumable => this.currentPlaceholder.Slot.Consumable,
                        _ => this.currentPlaceholder.Slot.Consumable,
                    };

                    if (this.ghostGO != null)
                    {
                        Destroy(this.ghostGO);
                        this.ghostGO = null;
                    }

                    this.ghostGO = Instantiate(prefabParts[0], transform.position, transform.rotation);
                    foreach (var renderer in this.ghostGO.GetComponentsInChildren <Renderer>())
                    {
                        foreach (var material in renderer.materials)
                        {
                            material.shader = Shader.Find("Transparent/Diffuse");
                            material.color  = Color.black.AlphaMultiplied(0.25f);
                        }
                    }
                }

                this.interact.PlayerSetSelected(true, this.playerAgent);
                this.interact.ManualUpdateWithCondition(true, this.playerAgent, true);
            }
예제 #24
0
 private void ItemSwitched(ItemEquippable item)
 {
     HandleSelectionEffect(item);
     UpdateBulletGridDivisions(item);
 }
예제 #25
0
 public static VRWeaponData GetVRWeaponData(ItemEquippable item)
 {
     return(m_current);
 }
 private static void Postfix(ItemEquippable __instance)
 {
     ItemEquippableEvents.ItemEquipped(__instance);
 }
예제 #27
0
 public static bool IsItemShootableWeapon(ItemEquippable item)
 {
     return(item != null && item.IsWeapon && item.AmmoType != Player.AmmoType.None && item.HasFlashlight);
 }