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.
any help at all is welcomed.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);
EDIT: I forgot to include the error message when someone kills me.
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?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]
Cheers
Solved Help with a bit of code, im new to this :D
Discussion in 'Rust Development' started by MancTwonk, Apr 12, 2016.
-
Where is the OnEntityDeath hook at? That is where the problem is at.
-
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? -
Wulf Community Admin
Why not request the feature from the original plugin?
-
Many thanks for the replies guys -
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 } } }
-
Again many thanks. -
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
-
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)); } }
-
Yes, sorry that's what I meant