1. Hi,

    I am trying to implement / adapt the robbery plugin to take a random item from the person who has been killed and give that item to the attacker.

    I have tried to combine bits of code from the kits plugin (the bit that gets all items wore by a player creating the kit) and use that to get the items on the victim and then use that list and pick a random item from that list but its not working.

    Code:
            class victimItem
            {
                public int itemid;
                public bool bp;
                public string container;
                public int amount;
                public int skinid;
                public string name;
                public string sname;
                public bool weapon;
                public List<int> mods;
            }        class victimInv
            {
                public string name;
                public string description;
                public int max;
                public double cooldown;
                public int authlevel;
                public bool hide;
                public bool npconly;
                public string permission;
                public string image;
                public static List<victimItem> items = new List<victimItem>();
            }        static List<victimItem> GetPlayerItems(BasePlayer player)
            {
                List<victimItem> victimItems = new List<victimItem>();
                foreach (Item item in player.inventory.containerWear.itemList)
                {
                    if (item != null)
                    {
                        var iteminfo = ProcessItem(item, "wear");
                        victimItems.Add(iteminfo);
                    }
                }
                foreach (Item item in player.inventory.containerMain.itemList)
                {
                    if (item != null)
                    {
                        var iteminfo = ProcessItem(item, "main");
                        victimItems.Add(iteminfo);
                    }
                }
                foreach (Item item in player.inventory.containerBelt.itemList)
                {
                    if (item != null)
                    {
                        var iteminfo = ProcessItem(item, "belt");
                        victimItems.Add(iteminfo);
                    }
                }
                return victimItems;
            }
            static private victimItem ProcessItem(Item item, string container)
            {
                victimItem iItem = new victimItem();
                iItem.amount = item.amount;
                iItem.mods = new List<int>();
                iItem.container = container;
                iItem.bp = item.IsBlueprint();
                iItem.skinid = item.skin;
                iItem.itemid = item.info.itemid;
                iItem.name = item.info.displayName.ToString();
                iItem.sname = item.info.shortname;
                iItem.weapon = false;            if (item.info.category.ToString() == "Weapon")
                {
                    BaseProjectile weapon = item.GetHeldEntity() as BaseProjectile;
                    if (weapon != null)
                    {
                        if (weapon.primaryMagazine != null)
                        {
                            iItem.weapon = true;
                            if (item.contents != null)
                                foreach (var mod in item.contents.itemList)
                                {
                                    if (mod.info.itemid != 0)
                                        iItem.mods.Add(mod.info.itemid);
                                }
                        }
                    }
                }
                return iItem;
            }        void TransferItem(BasePlayer victim, BasePlayer attacker)
            {
                // Check if player is in event/zone with no looting
                var inEvent = EventManager?.Call("isPlaying", victim);
                if (inEvent != null && (bool)inEvent) return;
                if (ZoneManager != null)
                {
                    var noLooting = Enum.Parse(ZoneManager.GetType().GetNestedType("ZoneFlags"), "noplayerloot", true);
                    if ((bool)ZoneManager.CallHook("HasPlayerFlag", victim, noLooting)) return;
                }            // pick random item and give it to the mugger
                System.Random randNum = new System.Random();            victimItem StolenItem;            StolenItem = victimInv.items[randNum.Next(victimInv.items.Count)];            PrintToChat(attacker, "[Debug] Stolen Item: n:" + StolenItem.name + "sn:" + StolenItem.sname);        }//steal the item
                if (victim != null && attacker != null) TransferItem(victim, attacker);
    any help at all is welcomed.

    EDIT: I forgot to include the error message when someone kills me.

    Code:
    [Oxide] 17:53 [Error] Failed to call hook 'OnEntityDeath' on plugin 'Robbery v2.3.0' (ArgumentOutOfRangeException: Argument is out of range.
    Parameter name: Min value is greater than max value.)
    [Oxide] 17:53 [Debug]   at System.Random.Next (Int32 minValue, Int32 maxValue) [0x00000] in <filename unknown>:0
      at Oxide.Plugins.Robbery.TransferItem (.BasePlayer victim, .BasePlayer attacker) [0x00000] in <filename unknown>:0
      at Oxide.Plugins.Robbery.OnEntityDeath (.BaseEntity entity, .HitInfo info) [0x00000] in <filename unknown>:0
      at Oxide.Plugins.Robbery.DirectCallHook (System.String name, System.Object& ret, System.Object[] args) [0x00000] in <filename unknown>:0
      at Oxide.Plugins.CSharpPlugin.InvokeMethod (System.Reflection.MethodInfo method, System.Object[] args) [0x00000] in <filename unknown>:0
      at Oxide.Core.Plugins.CSPlugin.OnCallHook (System.String name, System.Object[] args) [0x00000] in <filename unknown>:0
      at Oxide.Core.Plugins.Plugin.CallHook (System.String hookname, System.Object[] args) [0x00000] in <filename unknown>:0
    MancTwonk[16822/76561198146518365] was killed by [MODS] mattyward35[17662/76561198101979430]
    I think the list code that i am using to get a list of the players items is not working but dont know why. seeing as the min value is greater than max value would suggest that 1 is greater than the count in that list?
    Cheers
     
    Last edited by a moderator: Apr 12, 2016
  2. Where is the OnEntityDeath hook at? That is where the problem is at.
     
  3. Use UnityEngine.Random.Range(0, victimInv.items.Count - 1)
    The first item in the list is 0 so using the count will always be 1 number higher. Also you could do this with out copying the victims inventory to a list. I can't give you a example atm because I'm not home but if you want one I can post it later.
    Also I'm not sure if you can use system.random through plugins, maybe @Wulf can confirm?
     
  4. Wulf

    Wulf Community Admin

    Why not request the feature from the original plugin?
     
  5. if you can provide a example that would be great, ill try and implement the change to the random number .

    I didn't request it as I was using this as a kind of learning curve to get into plugin development. but if this can be added to the roberry plugin that would be awesome :D

    Many thanks for the replies guys
     
  6. This will do what you want
    Code:
     private void OnEntityDeath(BaseCombatEntity entry, HitInfo info)
            {
                if (entry is BasePlayer && info.Initiator is BasePlayer)
                {              
                    var victim = entry.ToPlayer(); //
                    var attacker = info.Initiator.ToPlayer();
                    if (victim?.inventory?.AllItems() != null)
                    {
                        Item[] items = victim.inventory.AllItems(); // An array of all the victims items
                        int num = UnityEngine.Random.Range(0, items.Count() - 1); // Get a random number
                        items[num].MoveToContainer(attacker.inventory.containerMain); // Move item [num] to attackers inventory
                    }
                }
            }
     
  7. Thanks!! I will try this tonight once I finish work.

    Again many thanks.
     
  8. Now, for your learning. If the victim just has the torch and stone and the attacker killed with a weapon that needs some playtime, punish the attacker by giving the victim a random item out of the attackers inventory once the victim spawns again :)
     
  9. quick update @k1lly0u

    there was a slight change to the .Count bit but other than that it worked fine.

    Code:
                if (victim is BasePlayer && attacker is BasePlayer)
                {
                    if (victim?.inventory?.AllItems() != null)
                    {
                        Item[] items = victim.inventory.AllItems();
                        int num = UnityEngine.Random.Range(0, items.Length);
                        items[num].MoveToContainer(attacker.inventory.containerMain);
                        PrintToChat(attacker, ItemStolen.Replace("{item}", items[num].info.displayName.english.ToString()).Replace("{player}", victim.displayName));
                    }
                }
     
  10. Yes, sorry that's what I meant :p