Custom loot - too ambitious?
Hey everyone
I am working on a PW and what I'd really like is a custom item drop system, that goes like this:
*Player kills a monster, or opens a chest* - so far it's relatively simple.
Now what I want the game to do is do some rolls to check what the player's going to grab.. to easier understand my weird thoughts, I've added a table

Basically, I'd like a script to roll for a category, then roll for a type of said category and finally pick the item. Since it's 4 categories, the game should roll for categories at a 25% chance to pick from 1, 2, 3 or 4. Then, depending on types inside a category - e.g. armor - roll for 5 different types at a 20% chance and finally pick an item.
There's a bit of an anomaly, since I'd like the game - should it roll for category 3 or 4 - to have the chances be distributed differently than for categories 1 and 2. Regular should have a high chance to drop, common a bit less, rare .. well.. should be rare, expectional should be exceptionally rare and unique should almost never drop.
How do I approach this? Maybe someone has an idea.. or can already tell this ain't going to work^^
I am working on a PW and what I'd really like is a custom item drop system, that goes like this:
*Player kills a monster, or opens a chest* - so far it's relatively simple.
Now what I want the game to do is do some rolls to check what the player's going to grab.. to easier understand my weird thoughts, I've added a table

Basically, I'd like a script to roll for a category, then roll for a type of said category and finally pick the item. Since it's 4 categories, the game should roll for categories at a 25% chance to pick from 1, 2, 3 or 4. Then, depending on types inside a category - e.g. armor - roll for 5 different types at a 20% chance and finally pick an item.
There's a bit of an anomaly, since I'd like the game - should it roll for category 3 or 4 - to have the chances be distributed differently than for categories 1 and 2. Regular should have a high chance to drop, common a bit less, rare .. well.. should be rare, expectional should be exceptionally rare and unique should almost never drop.
How do I approach this? Maybe someone has an idea.. or can already tell this ain't going to work^^
1
Comments
void main() { object oPC = GetLastKiller();//or whatever string sItemResRef; int iCategory = Random(4);//reminder Random is always one number less because it starts at 0. So random 4 would be 0 to 3 if (iCategory == 0)//For example 0 will be the weapon category { int iPercent = Random(100); if (iPercent <= 49)//50% chance to drop this stuff/common stuff or whatever % you want. This could also be its own category such as martial weapon { int iNumItems = 20;//this should equal whatever amount of items you want in common stuff switch (Random(iNumItems)) { case 0: sItemResRef = "resref of weapon 1"; break; case 1: sItemResRef = "resref of weapon 2"; break; //etc.. all the way up to 19 or however many items in this section case 19: sItemResRef = "resref of weapon 19"; break; } } if (iPercent > 49 && iPercent <= 74)//25% chance of this stuff dropping or whatever % you want. Could also be something like ranged weapon category { int iNumItems = 10;//this should equal whatever amount of items you want is better weapons section switch (Random(iNumItems)) { case 0: sItemResRef = "resref of weapon 1"; break; case 1: sItemResRef = "resref of weapon 2"; break; //etc.. all the way up to 9 or however many items in this section case 9: sItemResRef = "resref of weapon 9"; break; } } if (iPercent > 74 && iPercent <= 84)//10% chance { int iNumItems = 5; switch (Random(iNumItems)) { case 0: sItemResRef = "resref of weapon 1"; break; //etc.. } } if (iPercent > 84 && iPercent <= 98)//4% { int iNumItems = 5; switch (Random(iNumItems)) { case 0: sItemResRef = "resref of weapon 1"; break; //etc.. } } if (iPercent > 98)//last 1% { int iNumItems = 5; switch (Random(iNumItems)) { case 0: sItemResRef = "resref of weapon 1"; break; //etc.. } } } if (iCategory == 1)//For example this can be Armor category { //All the same/similar stuff from category 0 } if (iCategory == 2)//For example this could be crafting items { //Same stuff from other categories } if (iCategory == 3)// etc.. { //etc.. } CreateItemOnObject(sItemResRef, oPC);//Or however/wherever you want item created }There are a lot of different approaches you can take to do this via scripting. This is just one example I slapped together.
Thank you very much - although this looks very alien to me (I can reliably use the script wizard) I am definitely going to wrap my head around this work of you and try to make it work!
Awesome community!
Good catch. Shoulda been 94. And I skipped the 84 to 94 section. Just kind of a rough draft example I typed up real quick.
Script:
const string ITEM_DROP_2DA_FILE = "myitemdrop"; int MyStringToInt(string sString) { if (sString=="0") return 0; int nValue = StringToInt(sString); if (nValue==0) return -1; return nValue; } string GetItemResRef() { int nRow=0; int nCol; string sResRef = ""; int nCounter=0; // to prevent 'too many instructions' error in case there something wrong with our 2DA file while ((nRow>=0) && (++nCounter<=10)) { int nColCount = StringToInt(Get2DAString(ITEM_DROP_2DA_FILE, "COUNT", nRow)); if (nColCount>0) { nCol = Random(nColCount); sResRef = Get2DAString(ITEM_DROP_2DA_FILE, "Col"+IntToString(nCol), nRow); nRow = MyStringToInt(sResRef); if (nRow<0) return sResRef; } else { nRow = -1; } } return ""; } void main() { object oPC = GetLastKiller(); string sItemResRef = GetItemResRef(); CreateItemOnObject(sItemResRef, oPC); }2DA file 'myitemdrop':
2DA V2.0 Label COUNT Col0 Col1 Col2 Col3 Col4 Col5 Col6 Col7 Col8 Col9 Col10 Col11 Col12 Col13 Col14 0 Category 4 1 2 3 4 1 Armor 5 10 11 12 13 14 2 Weapons 3 20 21 22 3 Crafting 15 30 30 30 30 30 31 31 31 31 32 32 32 33 33 34 4 Misc 15 40 40 40 40 40 41 41 41 41 42 42 42 43 43 44 5 **** 6 **** 7 **** 8 **** 9 **** 10 HeavyArmor 4 50 51 52 53 11 MediumArmor 4 54 55 56 57 12 LightArmor 5 58 59 60 61 62 13 Body 6 62 63 64 65 66 67 14 Shields 3 68 69 70 .. .. 20 SimpleWeap 11 80 81 ... ... 21 MartialWeap 17 ... ... ... ... 22 ... .. .. 30 CraftReg 2 ... ... 31 CraftCom 2 ... ... 32 CraftRare 2 ... ... 33 ... .. .. 40 MiscReg ... ... 41 MiscCom ... 42 ... .. .. 50 BandedMail ... "ResRef" "ResRef" "ResRef" ... 51 FullPlate ... "ResRef" "ResRef" "ResRef" ... 52 HalfPlate ... "ResRef" "ResRef" "ResRef" ... 53 SplintMail ... "ResRef" "ResRef" "ResRef" ... 54 ChainShirt ... "ResRef" ... 55 ...So how does it work: our script starts at row 0. It reads the column COUNT (= number of columns in that row) and rolls a random between 0 and that number-1. Than it looks at the value in that column and that value will be our new row. Let's say the random was 0 then our new row is 1 (category 'armor'). Again the script looks at column COUNT, rolls a random and gets a new row (something between 10 and 14). This goes on and on until the script is in a row with resrefs. Then it just returns the resref.
For chances distributed differently look at row 3 (Crafting) and row 4 (Misc): item types with higher probability appear more often.
Might be some work to build that 2da file but once it's done it should be easy to maintain. You could even use diffeerent 2da files for different classes, levels,...
The 2da cache size can be changed in settings.tml (in case you want to read many 2da files):