Пример #1
0
    // TODO this is weird to pass slotindex too. needed because hands option though.
    void TryUseItem(UsableItem itemData, int slotIndex)
    {
        // note: no .amount > 0 check because it's either an item or hands

        // use current item or hands

        // repeated or one time use while holding mouse down?
        if (itemData.keepUsingWhileButtonDown || Input.GetMouseButtonDown(0))
        {
            // get the exact look position on whatever object we aim at
            Vector3 lookAt = look.lookPositionRaycasted;

            // use it
            Usability usability = itemData.CanUse(this, slotIndex, lookAt);
            if (usability == Usability.Usable)
            {
                // attack by using the weapon item
                //Debug.DrawLine(Camera.main.transform.position, lookAt, Color.gray, 1);
                UseItem(slotIndex, lookAt);

                // simulate OnUsed locally without waiting for the Rpc to avoid
                // latency effects:
                // - usedEndTime would be synced too slowly, hence fire interval
                //   would be too slow on clients
                // - TryUseItem would be called immediately again afterwards
                //   because useEndTime wouldn't be reset yet due to latency
                // - decals/muzzle flash would be delayed by latency and feel
                //   bad
                OnUsedItem(itemData, lookAt);
            }
            else if (usability == Usability.Empty)
            {
                // play empty sound locally (if any)
                // -> feels best to only play it when clicking the mouse button once, not while holding
                if (Input.GetMouseButtonDown(0))
                {
                    if (itemData.emptySound)
                    {
                        audioSource.PlayOneShot(itemData.emptySound);
                    }
                }
            }
            // do nothing if on cooldown (just wait) or if not usable at all
        }
    }
Пример #2
0
 public void UseItem(int index)
 {
     // validate
     // note: checks durability only if it should be used (if max > 0)
     if (health.current > 0 &&
         0 <= index && index < slots.Count &&
         slots[index].amount > 0 &&
         slots[index].item.data is UsableItem)
     {
         // use item
         // note: we don't decrease amount / destroy in all cases because
         // some items may swap to other slots in .Use()
         UsableItem itemData = (UsableItem)slots[index].item.data;
         if (itemData.CanUse(this, index) == Usability.Usable)
         {
             // .Use might clear the slot, so we backup the Item first for the Rpc
             Item item = slots[index].item;
             itemData.Use(this, index);
             OnUsedItem(item);
         }
     }
 }
Пример #3
0
    // note: lookAt is available in PlayerLook, but we still pass the exact
    // uncompressed Vector3 here, because it needs to be PRECISE when shooting,
    // building structures, etc.
    public void UseItem(int index, Vector3 lookAt)
    {
        // validate
        if (0 <= index && index < slots.Count &&
            health.current > 0)
        {
            // use item at index, or hands
            // note: we don't decrease amount / destroy in all cases because
            // some items may swap to other slots in .Use()
            UsableItem itemData = GetUsableItemOrHands(index);
            if (itemData.CanUse(this, index, lookAt) == Usability.Usable)
            {
                // use it
                itemData.Use(this, index, lookAt);

                // reset usage time
                usageEndTime = Time.time + itemData.cooldown;

                // RpcUsedItem needs itemData, but we can't send that as Rpc
                // -> we could send the Item at slots[index], but .data is null
                //    for hands because hands actually live in '.hands' variable
                // -> we could create a new Item(itemData) and send, but it's
                //    kinda odd that it's different from slot
                // => only sending hash saves A LOT of bandwidth over time since
                //    this rpc is called very frequently (each weapon shot etc.)
                //    (we reuse Item's hash generation for simplicity)
                OnUsedItem(itemData, lookAt);
            }
            else
            {
                // CanUse is checked locally before calling this Cmd, so if we
                // get here then either our prediction is off (in which case we
                // really should show a message for easier debugging), or someone
                // tried to cheat, or there's some networking issue, etc.
                Debug.LogWarning("UseItem rejected for: " + name + " item=" + itemData.name + "@" + Time.time);
            }
        }
    }