UpdateActiveItem and OnReceiveTick

I am having an issue trying to set a players held item. 

What I am doing is calling UpdateActiveItem and the player is getting the item, however immediately switching back to the previous item. I have tracked it down to what I am assuming is the next tick is resetting it in OnReceiveTick as that also calls UpdateActiveItem but with the item id from the PlayerTick msg. 

Does anyone know how to bypass this?

Thanks

Adding my mod code

 

[Info("GiveSpear", "Me", "0.0.1")]
    public class GiveSpear : RustPlugin
    {
        private void Init()
        {
            cmd.AddChatCommand("spear", this, GivePlayerSpear);
        }

        private void GivePlayerSpear(BasePlayer player, string command, string[] args)
        {
            if (player == null)
                return;

            Server.Broadcast("Giving Spear");

            var item = ItemManager.CreateByName("spear.stone", 1);
            if (item == null)
            {
                Puts($"Spear was not able to be created properly");
                return;
            }

            if (!item.MoveToContainer(player.inventory.containerBelt))
            {
                item.Remove();
                return;
            }

            player.UpdateActiveItem(item.uid);
            player.SendNetworkUpdate();
        }
    }


Merged post

This gives the player a spear and then does try to activate it, however just reselects the previous active item. The player does do the animation to re-pull out their previous item.

Merged post

I have also tried to do the following, and this lowers the players active item, however doesnt change it to the new item. - and the original item is still highlighted blue in their inventory

            var heldItem = player.GetActiveItem()?.GetHeldEntity() as HeldEntity;
            heldItem.SetHeld(false);
            //player.UpdateActiveItem(item.uid);
            var spearHeldItem = item.GetHeldEntity() as HeldEntity;
            spearHeldItem?.SetHeld(true);
            player.SendNetworkUpdate();​


If I uncomment the UpdateActiveItem it behaves the same as before



Merged post

I added this function and I can se it is switching and switching back

 

        void OnActiveItemChanged(BasePlayer player, Item oldItem, Item newItem)
        {
            Server.Broadcast($"{oldItem?.info?.displayName.english} => {newItem?.info?.displayName.english}");
        }

And this is what I see in the output

Hammer => Stone Spear
Stone Spear => Hammer


Merged post

I even tried adding the following, however it still switches back, i see in the output "Attempting Stopping of switch?"  however i still see

Stone Spear => Hammer also

 


        private ConcurrentDictionary<ulong, uint> _waiting = new ConcurrentDictionary<ulong, uint>();
private void GivePlayerSpear(BasePlayer player, string command, string[] args)
        {
            if (player == null)
                return;

            var item = ItemManager.CreateByName("spear.stone", 1);
            if (item == null)
            {
                Puts($"Spear was not able to be created properly");
                return;
            }

            if (!item.MoveToContainer(player.inventory.containerBelt, 4, false))
            {
                item.Remove();
                return;
            }

            player.UpdateActiveItem(item.uid);
            _waiting.AddOrUpdate(player.userID, item.uid, (uid, iid) => { return iid; });
        }

object OnActiveItemChange(BasePlayer player, Item oldItem, uint newItemId)
        {
            uint uid;
            if (_waiting.TryRemove(player.userID, out uid))
            {
                if (uid == oldItem?.uid)
                {
                    Server.Broadcast("Attempting Stopping of switch?");
                    return false;
                }
            }
            
            return null;
        }


Merged post

Anyone know how to set a players active item?

Maybe the client is reasserting what it thinks it should be doing, by saying "No, I'm still on belt slot #1".

Might help to put the stone spear into the exact same belt spot as their current item is. 

Just a guess, but not everything done server side will get sent to the client.