| Author: | Keron Blackfeld | ||||
| Author Website: | n/a | ||||
| Script Name: | Lootable Creature Corpse | ||||
| Description: | This script, when placed in a creature's onDeath event, causes the critter's corpse to remain either indefinitely or for a specified amount of time (see below) - and it can be looted! That's not exactly true what it does is set the corpse to not selectable and then spawns an invisible, lootable "corpse" object under the actual body. It then moves all of the creature's inventory to that object so it "fakes" actual lootable bodies. | ||||
| Instructions on Use: | You can now set a delay for the corpses to hang out before they
automatically fade - and you can also set them to auto fade upon the
emptying of their inventories. To do the auto fade on empties... you actually need a second script that goes in the onheatbeat of the lootable object. If you are concerned about the onHeartbeats being a problem in your module... just don't use them and just use the "Corpse Fade" delay. There are a couple of settings you can toy with in the beginning of the script. These are: nUseBlood - Set this to true and it will spawn a bloodspot under the corpse upon death. This will also be destroyed during the CorpseFade event. nCorpseFade - Setting this to 0 (zero) will toggle it off. Use this to set your delay. i.e. nCorpseFade = 60 will keep the corpses around for 1 minute (real time). nKeepEmpties - Setting this to TRUE means that Empty corpses will hang out for the delay period as well. Setting this to FALSE will trigger the auto fade when the inventory is empty. The auto fade on empty will ONLY WORK IF YOU USE THE ONHEARTBEAT SCRIPT AS WELL. nOverrideForPlacedCorpses - I use this to make the corpses that I
place in the toolset permanent. They way this works is you place any
creature - then add "Dead" as a prefix to it's TAG. Now place the _kb_loot_corpse
in that creature's onSpawn event. It will kill the critter upon spawning -
thereby creating a lootable corpse. I call this a creature that is "Spawned
Dead". When the nOverrideForPlacedCorpses is set to TRUE, the script
overrides the nCorpseFade and nKeepEmpties settings for creatures who are
"Spawned Dead" - those corpses will NEVER FADE. Setting this to FALSE just
means that this corpse will be handled exactly as any other in your module
(i.e. it will fade after the delay or when emptied - if your settings
indicate such). ONE LAST NOTE: When a corpse with stuff still in its inventory fades, it leaves behind a normal loot bag with the inventory contents in it. If there are a few people out there who would prefer this NOT TO BE THE CASE, let me know here and I'll add an option to clean the inventory before the corpses fade, that way NOTHING will be left behind to litter the landscape after the corpses fade. I just haven't decided for myself if I want to get rid of the bags or not... |
||||
| Comments from site visitors: |
|
Script 1 (OnHearbeat):
//////////////////////////////////////////////////////////////////////////////// // // // _kb_ohb_lootable // // // // by Keron Blackfeld on 07/14/2002 // // email Questions and Comments to: keron@broadswordgaming.com or catch me // // in Bioware's NWN Community - Builder's NWN Scripting Forum // // // //////////////////////////////////////////////////////////////////////////////// // // // This is an OnHearbeat Script to go with my _kb_loot_corpse script for // // LOOTABLE MONSTER/NPC CORPSES. // // // // PLACE THIS SCRIPT IN THE ONHEARTBEAT EVEN OF YOUR "invis_corpse_obj" // // BLUEPRINT. This script checks the inventory of OBJECT_SELF, and when it // // is empty, it checks the LocalInt to see if the now empty corpse should // // be Destroyed along with the Lootable Corpse Object. // // // // The _kb_loot_corpse script must have this line: // // int nKeepEmpties = FALSE; // // in order for the Empty Corpse to Destroy itself in this script. // // // //////////////////////////////////////////////////////////////////////////////// void main() { /******************************************* ** Check inventory, does nothing else if ** ** the inventory is not empty. Delayed ** ** Corpse Fade is handled within the ** ** _kb_loot_corpse script. ** *******************************************/ object oHasInventory = GetFirstItemInInventory(OBJECT_SELF); //Check for inventory if (oHasInventory == OBJECT_INVALID) { /******************************************* ** Inventory is empty. Now we check the ** ** nKeepEmpty value. ** *******************************************/ object oHostCorpse = GetLocalObject(OBJECT_SELF, "oHostBody"); //Get Value set by _kb_loot_corpse at creation object oCorpseBlood = GetLocalObject(OBJECT_SELF, "oBloodSpot"); //Get Value set by _kb_loot_corpse at creation int nKeepEmpty = GetLocalInt(OBJECT_SELF, "oKeepEmpty"); //Get Value set by _kb_loot_corpse at creation if (!nKeepEmpty) { /******************************************* ** nKeepEmpty is FALSE. Delete empty. ** *******************************************/ AssignCommand(oHostCorpse,SetIsDestroyable(TRUE,FALSE,FALSE)); //Set actual corpse to destroyable DestroyObject(oHostCorpse); //Delete the actual Creature Corpse DestroyObject(oCorpseBlood); //Delete the BloodSpot DelayCommand(1.0f,DestroyObject(OBJECT_SELF)); //Delete Lootable Object (Self) } } } |
Script 2 (OnDeath -or- OnSpawn):
//////////////////////////////////////////////////////////////////////////////// // // // _kb_loot_corpse // // // // by Keron Blackfeld on 07/13/2002 // // email Questions and Comments to: keron@broadswordgaming.com or catch me // // in Bioware's NWN Community - Builder's NWN Scripting Forum // // // //////////////////////////////////////////////////////////////////////////////// // // // strip_equiped function was borrowed from the Hard Core Ruleset, which // // looks REALLY incredible by the way - Thanks guys! // // // // THE ONLY OTHER THING NEEDED for this script to work is a custom PLACEABLE // // INVISIBLE OBJECT with a Blueprint ResRef of "invis_corpse_obj". Also, set // // its name to "corpse" or something equally appropriate - this will be the // // TEXT your players see when they put their mouse over the body. // // // // This script can perform its functions in two ways. // // // // #1 PLACED IN THE onDeath EVENT: If used in place of or added to the // // onDeath script of any creature, it will keep their corpse from decaying // // for either a delayed period (set in this script) or until the module is // // closed. It then creates an invisible corpse object under the body that // // may be clicked for looting. // // // // #2 PLACED IN THE onSpawn EVENT: If the creature's tag is set so that it // // starts with the string 'Dead' and this script is used in the onSpawn // // event, it will kill the creature at spawn, preserve the corpse, and add // // an invisible, lootable corpse object (as in #1). This functionality gives // // you placeable, lootable corpses of all types. Please note tha by default // // this script is set to override the Corpse Fade and Keep Empties on placed // // 'Dead' creatures (or creatures that are "Spawned Dead"). This may be // // changed by setting nOverrideForPlacedCorpses = TRUE; in the beginning of // // the script. // // // //////////////////////////////////////////////////////////////////////////////// #include "NW_I0_GENERIC" /******************************************************************************* ** This script was borrowed from the Hard Core Ruleset, where they use it to ** ** move a Dead PC's inventory to a lootable corpse object. Credit where ** ** credit is due, I always say. :) ** *******************************************************************************/ void strip_equiped(object oDeadNPC, object oLootCorpse, object oEquip) { if(GetIsObjectValid(oEquip)) { AssignCommand(oLootCorpse, ActionTakeItem(oEquip, oDeadNPC)); } } void main() { //SET YOUR BLOOD, CORPSE FADE, KEEP EMPTY, AND SPAWNED DEAD OVERRIDE PREFERENCES HERE /////////////////////////// int nUseBlood = FALSE; // Set this to TRUE if you want a Bloodspot to appear under the corpse // int nCorpseFade = 60; // Set this to 0 (ZERO) if you DO NOT want the corpses to fade // int nKeepEmpties = FALSE; //Set this to FALSE if you want EMPTY corpses to fade immediately // int nOverrideForPlacedCorpses = TRUE; //Set this to TRUE if you want the 'Spawned Corpses' you // // //place to be permament. Setting it to FALSE will cause // // //your Placed Dead creatures to act as the settings above dictate. // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// //ALTER THE FOLLOWING AT YOUR OWN RISK :) object oDeadNPC = OBJECT_SELF; //Get the Dead Creature Object string sBaseTag = GetTag(oDeadNPC); //Get that TAG of the dead creature string sPrefix = GetStringLeft(sBaseTag, 4); //Look for Dead Prefix int nKillMe; if (sPrefix == "Dead") //Do Spawned Cropse { nKillMe = 1; //Set nKillMe to 1 if you need this creature to 'spawn dead' } else //Do Default On Death Functions from Bioware Script: nw_c2_default7 { int nClass = GetLevelByClass(CLASS_TYPE_COMMONER); int nAlign = GetAlignmentGoodEvil(OBJECT_SELF); if(nClass > 0 && (nAlign == ALIGNMENT_GOOD || nAlign == ALIGNMENT_NEUTRAL)) { object oKiller = GetLastKiller(); AdjustAlignment(oKiller, ALIGNMENT_EVIL, 5); } 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); if(GetSpawnInCondition(NW_FLAG_DEATH_EVENT)) { SignalEvent(OBJECT_SELF, EventUserDefined(1007)); } } location lCorpseLoc = GetLocation(oDeadNPC); //Set the spawnpoint for our lootable object //Do 'spawned corpse' if desired if(nKillMe) { //Set up and Deliver our Death Blow /* this is only needed if you need this creature to SPAWN as a corpse. */ effect eDamage = EffectDamage(1000); //Set up for the kill ApplyEffectToObject (DURATION_TYPE_INSTANT, eDamage, oDeadNPC); //Deliver the killing effect if (nOverrideForPlacedCorpses) { nKeepEmpties = TRUE; //Set 'Spawned Dead' corpses to Keep Empties nCorpseFade = 0; //Disable Corpse Fade for 'Spawned Dead' corpses } } SetIsDestroyable(FALSE,FALSE,FALSE); //Protect our corpse from decaying object oCorpseBlood; if (nUseBlood) { oCorpseBlood = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_bloodstain", lCorpseLoc, FALSE); //Spawn some blood for effect (if nUseBlood == TRUE) } object oLootCorpse = CreateObject(OBJECT_TYPE_PLACEABLE, "invis_corpse_obj", lCorpseLoc, FALSE); //Spawn our lootable object SetLocalObject(oLootCorpse, "oHostBody", oDeadNPC); //Set Local for deletion later if needed SetLocalObject(oLootCorpse, "oBloodSpot", oCorpseBlood); //Set Local for deletion later if needed SetLocalInt(oLootCorpse, "oKeepEmpty", nKeepEmpties); //Set Local for deletion later if needed //Get DEAD CREATURE'S INVENTORY int nAmtGold = GetGold(oDeadNPC); //Get any gold from the dead creature if(nAmtGold) { object oGold = CreateItemOnObject("nw_it_gold001", oLootCorpse, nAmtGold); AssignCommand(oLootCorpse,TakeGoldFromCreature(nAmtGold,oDeadNPC,TRUE)); } //Get any loot the dead creature has equipped - thanks again to the HCR for strip-equiped strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_ARMS, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_ARROWS, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_BELT, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_BOLTS, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_BOOTS, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_BULLETS, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_CHEST, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_CLOAK, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_HEAD, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_LEFTRING, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_NECK, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oDeadNPC)); strip_equiped(oDeadNPC, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oDeadNPC)); //Get the remaining loot from the dead creature and move it to the lootable object object oLootEQ = GetFirstItemInInventory(oDeadNPC); while(GetIsObjectValid(oLootEQ)) { AssignCommand(oLootCorpse, ActionTakeItem(oLootEQ, oDeadNPC)); oLootEQ = GetNextItemInInventory(oDeadNPC); } //Do Corpse Fade out after specified delay (unless flagged 0) if (nCorpseFade > 0) { float fCorpseFade = IntToFloat(nCorpseFade); ActionWait(fCorpseFade); DelayCommand(fCorpseFade, DestroyObject(oLootCorpse)); DelayCommand(fCorpseFade + 1.0f, SetIsDestroyable(TRUE,FALSE,FALSE)); DelayCommand(fCorpseFade + 1.5f, DestroyObject(oDeadNPC)); } } |