Chance that a special item drops in creatures inventory, chosen randomly from the list of items
Ugly_Duck
Member Posts: 182
If I got a list of 50 or so items, how would I make one of them, randomly drop into a creatures inventory after it is killed? So:
1.) Kill creature
2.) "Possible" chance that a special item drops in its inventory, chosen randomly from the list of items.
1.) Kill creature
2.) "Possible" chance that a special item drops in its inventory, chosen randomly from the list of items.
0
Comments
https://nwnlexicon.com/index.php?title=X0_i0_treasure
If you are like myself and have a hard time figuring out how to get the NWN treasure scripts to work with custom items you could create a merchant with all 50 of your items and then use the on death script to pick a random item from the merchant. Axe Murderer helped me with this feature on original NWN and I still use it today so the least I can do is pay it forward. You could use any object with inventory but I use merchants for ease of inventory management and they are not visible to other players.
Here is an example...
First, create an object with inventory, add your items and then set the tag to "Treasure_Chest_01".
Second, modify the on death script of the creature with the lines listed at the bottom of the on death script posted below.
Third, create a new script using the second script posted below and save it as "treasure_01".
The name of the script called from ExecuteScript in the ondeath code has to match the name of the second script.
The tag of the object with inventory has to match the tag in the second script.
This is a modified nw_c2_default7 with the added lines needed at the bottom of the script.
Save this new script as "treasure_01".
Glad it worked out for you.
Any ideas?
For my areas I use the tag to simplify things.
'Goblin_Dungeon_1'
'Bugbear_Dungeon_2'
'Dragon_Dungeon_4'
I then get the right string of the tag and do a switch statement
case 1: //player is in level 1 dungeon etc.
I have maybe 7 or 8 levels of treasure on my module so obviously that many containers and scripts but yet only one ondeath script.
So my containers for my system are tagged Drop_Chest_1, Drop_Chest_2, etc. then I have a script for each chest, drop_chest_01, drop_chest_02, etc. I then just execute the script for the treasure intended. I don't need to check the creatures tag since I know what creatures are in what area.
My ondeath script does check the tag of the creature to see if it is a boss or if a certain key needs to be created but that's something I can explain later if needed.
Here are a couple examples from my module.
and then an example of a higher dungeon check, iHD is the players level
As you can see I do things a little different in my module than the example I posted, a drop on my module will go directly into the killers inventory so they don't have to click on a body or bag, they don't have to worry about someone else taking their loot and it just keeps the module fast paced as intended. With so many different levels of loot I use random(1000) rather than d(100) I have a spreadsheet with all the area rates and then it also lists each areas total rate for easy reference. Those numbers look pretty low for the checks in dungeon 4 but the items actually drop a lot more than you would think.
If a players level isn't 7 than the dungeon 4 rate isn't exactly 18%... then again a level 6 player probably wont be in dungeon 4 so I don't worry about it.
Let me know if you have any more questions,
Most of my dungeons have locked doors to prevent players running straight to the boss. All of the locked doors take the same key so all the creatures I want to drop a key have the tag set to DKEY_creaturename. The script checks the right string of the tag and creates the key when needed.
I understand I could just put the key in their inventory but there was some issues with players going invisible and pickpocketing the key. What happens then is the next player or party running the dungeon doesn't get the key and it causes issues... "Hey, this dungeon is broken, this creature isn't dropping the key" and then on top of that they say it in shout for everyone to see... you get the point, lol.
// Get the object that killed the caller.
object GetLastKiller()
object oPC = GetLastKiller();
Just change OBJECT_SELF to oPC where the ondeath calls the ExecuteScript.
As is, it still works fine. But I'm not sure if there will be negative setbacks due to the lack of said lines of code.
The "missing" lins from 4BOLTMAIN was not part of the code you needed to add. That was showing the name and short description of the function to use. You don't need that in the script.
meaglyn is right. oKiller is already called out in the original script so just change OBJECT_SELF to oKiller where ExecuteScript is.
[code]
//:://////////////////////////////////////////////////
//::
// MODIFIED: NW_C2_DEFAULT7
// Random Loot Generator Addition
/*
Default OnDeath event handler for NPCs.
Adjusts killer's alignment if appropriate and
alerts allies to our death.
*/
//:://////////////////////////////////////////////////
//:: Copyright (c) 2002 Floodgate Entertainment
//:: Created By: Naomi Novik
//:: Created On: 12/22/2002
//:://////////////////////////////////////////////////
//:://////////////////////////////////////////////////
//:: Modified By: Deva Winblood
//:: Modified On: April 1st, 2008
//:: Added Support for Dying Wile Mounted
//:://///////////////////////////////////////////////
#include "x2_inc_compon"
#include "x0_i0_spawncond"
#include "x3_inc_horse"
#include "_kb_loot_corpse"
void main()
{
int nClass = GetLevelByClass(CLASS_TYPE_COMMONER);
int nAlign = GetAlignmentGoodEvil(OBJECT_SELF);
object oKiller = GetLastKiller();
if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")&&GetIsObjectValid(GetMaster(OBJECT_SELF))) SetLocalInt(GetMaster(OBJECT_SELF),"bX3_STORE_MOUNT_INFO",TRUE);
// If we're a good/neutral commoner,
// adjust the killer's alignment evil
if(nClass > 0 && (nAlign == ALIGNMENT_GOOD || nAlign == ALIGNMENT_NEUTRAL))
{
AdjustAlignment(oKiller, ALIGNMENT_EVIL, 5);
}
// Call to allies to let them know we're dead
SpeakString("NW_I_AM_DEAD", TALKVOLUME_SILENT_TALK);
//Shout Attack my target, only works with the On Spawn In setup
SpeakString("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK);
// NOTE: the OnDeath user-defined event does not
// trigger reliably and should probably be removed
if(GetSpawnInCondition(NW_FLAG_DEATH_EVENT))
{
SignalEvent(OBJECT_SELF, EventUserDefined(1007));
}
craft_drop_items(oKiller);
LeaveCorpse();
//:://////////////////////////////////////////////////
/*
Custom Treasure
Change 100 to any number that will work for your goals.
You can leave it at 100 for testing.
100 = 100% drop rate
75 = 75% drop rate
35 = 35% drop rate
*/
if (d100() <= 4) ExecuteScript("treasure_01", oKiller);
}
[\code]
Goal: Have a few particular items drop into the players inventory when logging into the starting area. Only give them these items 1 time. This is the script I got so far:
The issue:
I made all the items undroppable, other than the recall stone (nw_it_recall). I couldn't make the recall stone undroppable because I'd have to make a copy of it and the recall function seems to not work anymore with a copy of the original (can't figure out how to do this also). So, if a player keeps all the items in their inventory, when they log in again, everything is fine. But, if they drop the recall stone, when they log back in, they get the recall stone back, but also more copies of the other items.
There is a simpler wrapper function HasItem() in nw_i0_tool which does the same thing.
See also https://nwnlexicon.com/index.php?title=Grimlar_-_Guide_To_The_Stone_Of_Recall to get the stone working.
There's no need for "if X if Y if Z then create X Y Z" which will only work if all the items are missing.