Initial commit

Initial commit.
This commit is contained in:
Jaysyn904
2024-08-02 23:18:00 -04:00
parent 779bee26ec
commit adeff59f82
3413 changed files with 2837434 additions and 0 deletions

1498
_module/nss/69_hench_lib.nss Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
//Contributed by Mike Daneman aka. Mishenka
//Modified: 69MEH69 Added more items to pick up
#include "69_inc_henai"
void main()
{
object oMaster = GetMaster();
ClearAllActions();
SetAssociateState(NW_ASC_IS_BUSY);
int bFound = FALSE;
string sName;
location lCenter = GetLocation(OBJECT_SELF);
object oThing = GetFirstObjectInShape(SHAPE_SPHERE,15.0,lCenter,TRUE,OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_ITEM);
while(GetIsObjectValid(oThing))
{
if(GetObjectType(oThing)==OBJECT_TYPE_ITEM & GetTag(oThing)!="NW_IT_GOLD001")
{
bFound = TRUE;
/*switch(GetBaseItemType(oThing)) {
case BASE_ITEM_POTIONS:
case BASE_ITEM_HEALERSKIT:
case BASE_ITEM_SPELLSCROLL:
case BASE_ITEM_ARMOR:*/
sName = GetName(oThing);
TurnToFaceObject(oThing);
ActionPickUpItem(oThing);
ActionDoCommand(SendMessageToPC(oMaster,GetName(OBJECT_SELF)+" picked up "+sName+"."));
/*break;
default:
break;
}*/
}
else // oThing is a placeable
{
if(GetHasInventory(oThing)) // Containers (including corpses)
{
// Don't search locked containers
// Only search trapped containers if you can't see the trap
if(!GetLocked(oThing) && (!GetIsTrapped(oThing)
|| (GetIsTrapped(oThing) && !GetTrapDetectedBy(oThing,OBJECT_SELF))))
{
bFound = TRUE;
ActionMoveToObject(oThing);
ActionDoCommand(AssignCommand(oThing,PlayAnimation(ANIMATION_PLACEABLE_OPEN)));
//ActionInteractObject(oThing);
//ActionDoCommand(DoPlaceableObjectAction(oThing,PLACEABLE_ACTION_USE));
TurnToFaceObject(oThing);
ActionPlayAnimation(ANIMATION_LOOPING_GET_MID,1.0,3.0);
object oItem = GetFirstItemInInventory(oThing);
while(GetIsObjectValid(oItem))
{
/* switch(GetBaseItemType(oItem)) {
case BASE_ITEM_POTIONS:
case BASE_ITEM_HEALERSKIT:
case BASE_ITEM_SPELLSCROLL:
case BASE_ITEM_ARMOR:*/
ActionDoCommand(SendMessageToPC(oMaster,GetName(OBJECT_SELF)+" picked up "+GetName(oItem)+" from "+GetName(oThing)+"."));
ActionTakeItem(oItem,oThing);
/* break;
default:
break;
}*/
oItem = GetNextItemInInventory(oThing);
}
ActionDoCommand(AssignCommand(oThing,PlayAnimation(ANIMATION_PLACEABLE_CLOSE)));
}
}
} // else
oThing = GetNextObjectInShape(SHAPE_SPHERE,15.0,lCenter,TRUE,OBJECT_TYPE_PLACEABLE | OBJECT_TYPE_ITEM);
} // while(GetIsObjectValid(oThing))
ActionDoCommand(SetAssociateState(NW_ASC_IS_BUSY,FALSE));
if(!bFound)
SpeakString("I don't see where I can find any around here.");
}

View File

@@ -0,0 +1,23 @@
//69_hench_scout1 (no stealth)
//Henchman will scout enemies and
// attack at first sight
//Created by: 69MEH69 Sep2004
#include "69_inc_henai"
void main()
{
object oClosest = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY,
OBJECT_SELF, 1);
if (GetIsObjectValid(oClosest)) {
ClearAllActions();
SpeakString("Very well.");
SetLocalInt(OBJECT_SELF,"Scouting",TRUE);
SetLocalInt(OBJECT_SELF,"ScoutingReport",FALSE);
DelayCommand(2.0, SetLocalInt(OBJECT_SELF,"Scouting",FALSE));
SetLocalObject(OBJECT_SELF,"ScoutTarget",oClosest);
SetAssociateState(NW_ASC_MODE_DEFEND_MASTER, FALSE);
ActionForceFollowObject(oClosest,5.0);
} else
SetLocalInt(OBJECT_SELF,"Scouting",FALSE);
}

View File

@@ -0,0 +1,7 @@
int StartingConditional()
{
int iResult;
iResult = 1-GetLocalInt(OBJECT_SELF,"Scouting");
return iResult;
}

1150
_module/nss/69_inc_henai.nss Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,214 @@
/*69_leadership
Leadership Library Functions
Created by: 69MEH69
Created on: Sep2004
*/
//void main(){}
//Level of PC when Leadership begins
const int LEADERSHIP_LEVEL = 1;
//Returns Loyalty modifier
int GetHenchLoyalty(object oHench, object oPC);
//Returns TRUE if PC has Leadership (must be level 6 or higher)
int GetHasLeadership(object oPC);
//Returns Leadership Score
int GetLeadershipScore(object oPC);
//Sets maximum number of henchmen based on Leadership
void SetMaxHenchmen69(object oPC);
//Returns maximum number of henchmen based on Leadership
int GetMaxHenchmen69(object oPC);
int GetHenchLoyalty(object oHench, object oPC)
{
int nCharisma = GetAbilityModifier(ABILITY_CHARISMA, oPC);
//Initial roll + charisma
int nLoyalty = d6(3) + nCharisma;
string sLoyalty;
//Test
//sLoyalty = IntToString(nLoyalty);
//SendMessageToPC(oPC, "nLoyalty = " + sLoyalty);
int nHenchAlign = GetAlignmentGoodEvil(oHench);
int nPCAlign = GetAlignmentGoodEvil(oPC);
int nHenchDeath = GetLocalInt(oPC, "Hench_Death");
//Adjustment for alignments
if(nHenchAlign == nPCAlign)
{
++nLoyalty;
}
else
{
--nLoyalty;
}
//Test
//sLoyalty = IntToString(nLoyalty);
//SendMessageToPC(oPC, "nLoyalty - Alignment = " + sLoyalty);
//Adjustment for number of dead henchmen
nLoyalty = nLoyalty - nHenchDeath;
//Test
sLoyalty = IntToString(nLoyalty);
//SendMessageToPC(oPC, "nLoyalty - nHenchDeath = " + sLoyalty);
SendMessageToPC(oPC, "Loyalty score = " + sLoyalty);
return nLoyalty;
}
int GetHasLeadership(object oPC)
{
int nLeadership = GetHitDice(oPC);
if(nLeadership >= LEADERSHIP_LEVEL)
{
//SendMessageToPC(oPC, "Leadership is True"); //Test
return TRUE;
}
else
{
//SendMessageToPC(oPC, "Leadership is False"); //Test
return FALSE;
}
}
int GetLeadershipScore(object oPC)
{
int nPCLevel = GetHitDice(oPC);
int nCharisma = GetAbilityModifier(ABILITY_CHARISMA, oPC);
int nPersuade = GetSkillRank(SKILL_PERSUADE, oPC);
int nLeadershipScore = nPCLevel + nCharisma;
//Test
//string sCharisma = IntToString(nCharisma);
//SendMessageToPC(oPC, "Charisma score = " + sCharisma);
//string sPersuade = IntToString(nPersuade);
//SendMessageToPC(oPC, "Persuade score = " + sPersuade);
string sLeadershipScore = IntToString(nLeadershipScore);
SendMessageToPC(oPC, "Leadership score = " + sLeadershipScore);
//End Test*/
return nLeadershipScore;
}
void SetMaxHenchmen69(object oPC)
{
int nLeadershipScore = GetLeadershipScore(oPC);
//Primary Code
if(GetHasLeadership(oPC) == FALSE)
{
SetLocalInt(oPC, "MaxHenchmen", 0);
}
else if(nLeadershipScore >= 25)
{
SetLocalInt(oPC, "MaxHenchmen", 10);
}
else if(nLeadershipScore >= 20)
{
SetLocalInt(oPC, "MaxHenchmen", 5);
}
else if(nLeadershipScore >= 15)
{
SetLocalInt(oPC, "MaxHenchmen", 4);
}
else if(nLeadershipScore >= 10)
{
SetLocalInt(oPC, "MaxHenchmen", 3);
}
else if(nLeadershipScore >= 8)
{
SetLocalInt(oPC, "MaxHenchmen", 2);
}
else if(nLeadershipScore >= 2)
{
SetLocalInt(oPC, "MaxHenchmen", 1);
}
else
{
SetLocalInt(oPC, "MaxHenchmen", 0);
}
//End Primary Code
//Secondary Code
//Uncomment following code to use this form
//Comment out the Primary Code
/*
if(GetHasLeadership(oPC) == FALSE)
{
SetLocalInt(oPC, "MaxHenchmen", 0);
return;
}
switch(nLeadershipScore)
{
case 0: case -1: case -2: case -3:
SetLocalInt(oPC, "MaxHenchmen", 0);
break;
case 1:
SetLocalInt(oPC, "MaxHenchmen", 1);
break;
case 2:
SetLocalInt(oPC, "MaxHenchmen", 1);
break;
case 3:
SetLocalInt(oPC, "MaxHenchmen", 1);
break;
case 4:
SetLocalInt(oPC, "MaxHenchmen", 2);
break;
case 5:
SetLocalInt(oPC, "MaxHenchmen", 2);
break;
case 6:
SetLocalInt(oPC, "MaxHenchmen", 2);
break;
case 7:
SetLocalInt(oPC, "MaxHenchmen", 3);
break;
case 8:
SetLocalInt(oPC, "MaxHenchmen", 3);
break;
case 9:
SetLocalInt(oPC, "MaxHenchmen", 3);
break;
case 10:
SetLocalInt(oPC, "MaxHenchmen", 4);
break;
case 11:
SetLocalInt(oPC, "MaxHenchmen", 4);
break;
case 12:
SetLocalInt(oPC, "MaxHenchmen", 4);
break;
case 13: case 14: case 15:
SetLocalInt(oPC, "MaxHenchmen", 5);
break;
case 16: case 17: case 18:
SetLocalInt(oPC, "MaxHenchmen", 6);
break;
default:
SetLocalInt(oPC, "MaxHenchmen", 7);
break;
}*/
//End Secondary Code
}
int GetMaxHenchmen69(object oPC)
{
int nMaxHenchmen = GetLocalInt(oPC, "MaxHenchmen");
//Test
string sMaxHenchmen = IntToString(nMaxHenchmen);
SendMessageToPC(oPC, "Maximum allowable henchmen = " + sMaxHenchmen);
return nMaxHenchmen;
}

View File

@@ -0,0 +1,61 @@
////////////////////////////////////////////////////////////////////////////////
//:: ITM_BookOfTownPortal.nss
////////////////////////////////////////////////////////////////////////////////
void main()
{
object oItem = GetItemActivated();
object oPC = GetItemActivator();
object oTownPortal;
if (GetTag(oItem) == "ITM_BookOfTownPortal")
{
if (GetTag(GetArea(oPC)) != "TRISTRAM")
{
if (GetTag(GetArea(oPC)) != "NOTOWNPORTAL")
{
// if player already has a town portal destroy it
oTownPortal = GetLocalObject(oPC,"TownPortal");
if (oTownPortal != OBJECT_INVALID) DestroyObject(oTownPortal);
// create new town portal at player location
oTownPortal = CreateObject(OBJECT_TYPE_PLACEABLE,"townportal",GetLocation(oPC));
SetLocalObject(oPC,"TownPortal",oTownPortal);
switch (d6())
{
case 1: AssignCommand(oTownPortal,PlaySound("sco_lgrinholy01")); break;
case 2: AssignCommand(oTownPortal,PlaySound("sco_lgsprholy01")); break;
case 3: AssignCommand(oTownPortal,PlaySound("sco_lgupholy01")); break;
case 4: AssignCommand(oTownPortal,PlaySound("sco_lgrinodd01")); break;
case 5: AssignCommand(oTownPortal,PlaySound("sco_lgsprodd01")); break;
case 6: AssignCommand(oTownPortal,PlaySound("sco_mehanodd03")); break;
}
DelayCommand(0.3,
ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectVisualEffect(VFX_FNF_SMOKE_PUFF),oTownPortal));
DelayCommand(0.5,SignalEvent(oTownPortal,EventUserDefined(9000)));
// if there is no town portal in Tristram create one
oTownPortal = GetLocalObject(OBJECT_SELF,"TownPortal");
if (!GetIsObjectValid(oTownPortal))
{
oTownPortal = CreateObject(OBJECT_TYPE_PLACEABLE,"townportal",GetLocation(GetObjectByTag("WP_TownPortal")));
SetLocalObject(OBJECT_SELF,"TownPortal",oTownPortal);
DelayCommand(0.6,SignalEvent(oTownPortal,EventUserDefined(9000)));
}
}
else
{
FloatingTextStringOnCreature("The spell fizzles! The town portal does not work here!", oPC);
}
}
else
{
FloatingTextStringOnCreature("The spell fizzles! You're already in town!", oPC);
}
}
ExecuteScript("dmfi_activate", OBJECT_SELF);
ExecuteScript("69_activateheal", OBJECT_SELF);
//ExecuteScript("s_apocalypse", OBJECT_SELF);
//ExecuteScript("s_teleport", OBJECT_SELF);
ExecuteScript(GetTag(GetItemActivated()), OBJECT_SELF);
}

View File

@@ -0,0 +1,33 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_corpse_damg // VERSION 3.3 //
// // //
// by Scrotok on 9 Feb 03 ////////////////////////////
// Thanks to Keron Blackfeld for 99% of the work! //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// NEWBIES: You don't need to place this script anywhere -- it's already //
// taken care of for you. //
// //
// This script works in conjunction with the "_kb_loot_corpse" script. The //
// OnDamaged event of the lootable corpse placeable (tag "invis_corpse_obj") //
// contains this script. //
// //
// This script allows third-party plugins to function (if installed), or //
// runs the default behavior (if no plugins installed). //
// //
////////////////////////////////////////////////////////////////////////////////
void main()
{
/* Register Plugins */
if (!GetLocalInt(GetModule(),"kb_lootcorpse_plugins"))
ExecuteScript("_kb_plugins", OBJECT_SELF);
// PLUGIN BEHAVIOR
// DEFAULT BEHAVIOR if plugin not installed
}

View File

@@ -0,0 +1,219 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_corpse_death // VERSION 3.3 //
// // //
// by Scrotok on 9 Feb 03 ////////////////////////////
// Thanks to Keron Blackfeld for 99% of the work! //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// CAUTION: You MUST re-save/compile (or press F7 for "Save and Compile") //
// the "_kb_corpse_death" and "_kb_corpse_distb" scripts if you make any //
// changes to "_kb_inc_invmgmt" (for programmers only: because it is an //
// #include file). //
// //
// NEWBIES: You don't need to place this script anywhere -- it's already //
// taken care of for you. //
// //
// This script works in conjunction with the "_kb_loot_corpse" script. The //
// OnDeath event of the lootable corpse placeable (tag "invis_corpse_obj") //
// contains this script. //
// //
// This script is used to clean up the loot within that object in the event //
// it is destroyed - such as being caught in a fireball or physically hacked //
// apart by a player (i.e. Bashed). Plot items are not destroyed. //
// //
////////////////////////////////////////////////////////////////////////////////
/* Version 3.3 Change Log:
- added DestroyIfEmpty function to ensure TransferToBones is finished before destroying oLootCorpse
- fixed comments to clarify that "doa_bashbreak" script refers to DOA's "Bashed Loot Breakage" plugin
/* Version 3.2 Change Log:
- renamed script from "_kb_destroy_cpse" to "_kb_corpse_death" for naming consistency
- consolidated inventory management functions to _kb_inc_invmgmt
- DestroyInventory function calls changed to DestroyInventory + DestroyDroppedWeapons in _kb_inc_invmgmt (identical)
- added simple plugin architecture (requires file _kb_plugins)
- integration with DOA's "Bashed Loot Breakage" plugin now requires zero editing (no include call)
- added GetIsObjectValid check before destroying Bloodspot
- moved DestroyDroppedWeapons outside if/else clause, so that plugins don't need to address it
- added nUseBonesBash to create bones when corpse is bashed
- added nBonesFade to determine when bones fade (if ever)
- added nTinyBones to prevent bones from appearing for tiny-sized creatures
- added nKeepInventoryBash to keep all items in a creature's inventory when its corpse is bashed
- changed comments to clarify weapons/shields/torches are affected by "weapons" parameters/functions
- changed comments to reflect that undead/constructs/elementals will not "gib" when bashed
- renamed oHostCorpse to oHostBody for consistency
- added support for DM's Helper wand (used to destroy corpse or bones)
- added support for "Destroy Target" command of DM's Helper wand (used to destroy the corpse or bones)
*/
#include "_kb_inc_invmgmt"
/*******************************************************************************
** This script checks to make sure TransferToBones is done moving all items **
** from oLootCorpse to oBones before destroying oLootCorpse. Note that all **
** items on oLootCorpse are droppable (due to "_kb_loot_corpse"), so **
** TransferToBones will always empty oLootCorpse completely. **
*******************************************************************************/
void DestroyIfEmpty()
{
if (!GetIsObjectValid(GetFirstItemInInventory(OBJECT_SELF)))
{
DestroyObject(OBJECT_SELF);
}
else
{
// SendMessageToPC(GetFirstPC(), "oLootCorpse not empty yet");
DelayCommand(1.0, DestroyIfEmpty());
}
}
void main()
{
/* Register Plugins */
if (!GetLocalInt(GetModule(),"kb_lootcorpse_plugins"))
ExecuteScript("_kb_plugins", OBJECT_SELF);
/*******************************************************************************
** INTEGRATION WITH DM's HELPER **
** Thanks to Bored Bistander for the idea/scripting! **
** **
** If you like the DM's Helper (http://www.nwnguide.com/~nwnbuilder/), you **
** can use the "Destroy Target" command of the DM's Helper wand to destroy **
** the lootable corpse or the bones. Just import the DM's Helper into your **
** module, then paste the following lines at the beginning of the **
** "dmwand_DestroyTarget()" function in the "dmw_func_inc" script: **
*******************************************************************************/
/*
// Added by Scrotok
if ((GetTag(oMyTarget) == "invis_corpse_obj") || (GetTag(oMyTarget) == "loot_bones_obj"))
{
if (GetTag(oMyTarget) == "loot_bones_obj")
{
SetLocalInt(oMyTarget, "nDestroyedByDMsHelper", TRUE);
}
effect eDestroy = EffectVisualEffect(VFX_IMP_SUNSTRIKE);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eDestroy, lMyLoc);
ExecuteScript("_kb_corpse_death", oMyTarget);
dmwand_BuildConversation("Start", "");
return;
}
*/
/*******************************************************************************
** Save your module. Then re-build your module (scripts only); to do this, **
** select Build Module under the Build pull-down menu, then check only the **
** Advanced/Compile/Scripts boxes, then click Build, then Done once the **
** build is finished. Then re-save your module. Once this is done, the **
** code listed below will handle the rest. **
*******************************************************************************/
// Destroy bones if "Destroy Target" command sent by DM's Helper wand
// (OBJECT_SELF in the following section refers to the bones)
if (GetLocalInt(OBJECT_SELF, "nDestroyedByDMsHelper") == TRUE)
{
BonesCleanup(OBJECT_SELF, GetLocalInt(OBJECT_SELF, "nKeepWeaponsBonesFade"));
return;
}
//Get all of our required information
int nUseBlood = GetLocalInt(OBJECT_SELF, "nUseBlood"); //Check for gratiutously Gory Destruction
object oHostBody = 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
// Determine creature size for later use
int nCorpseSize = GetCreatureSize(oHostBody);
object oPC = GetLastKiller();
if (nUseBlood)
{
// Undead/constructs/elementals will never "gib", but all other creatures
// (including Tiny-sized ones) will
effect eBloodyEnd = EffectVisualEffect(VFX_COM_CHUNK_RED_SMALL);
PlaySound("cb_ht_chunk");
ApplyEffectToObject(DURATION_TYPE_INSTANT, eBloodyEnd, OBJECT_SELF, 3.0f);
}
//Delete the BloodSpot (if created)
if (GetIsObjectValid(oCorpseBlood))
{
DestroyObject(oCorpseBlood);
}
// Empty and delete actual creature corpse (body)
DestroyInventory(oHostBody);
/* There is no call to DestroyDroppedWeapons since if the weapons are
dropped, they are already deleted from oHostBody. If the weapons are
not dropped, then the function would still not delete the weapons
since GetItemPossessor would be a valid object */
AssignCommand(oHostBody, SetIsDestroyable(TRUE,FALSE,FALSE));
DestroyObject(oHostBody);
////////////////////////////////////////////////////////////////////////////////
// The following section deletes ALL, SOME, or NONE of the inventory:
// - All (except plot): default if DOA's "Bashed Loot Breakage" plugin ("doa_bashbreak") isn't installed
// - Some (random chance based on item/value): requires "doa_bashbreak" plugin
// - None: not default (only works if nKeepInventoryBash = TRUE)
////////////////////////////////////////////////////////////////////////////////
// PLUGIN BEHAVIOR
if (GetLocalInt(GetModule(),"doa_bashbreak"))
{
// Random chance of inventory items breaking when corpse is bashed
ExecuteScript("doa_bashbreak", OBJECT_SELF);
}
else
{
// DEFAULT BEHAVIOR if plugin not installed
if (GetLocalInt(OBJECT_SELF, "nKeepInventoryBash") == FALSE)
// Delete all items (except Plot) from lootable corpse placeable
DestroyInventory(OBJECT_SELF);
else
{
// Do nothing (delete nothing from lootable corpse placeable)
}
}
// If user wants bones to be created when corpse is bashed...
if (GetLocalInt(OBJECT_SELF, "nUseBonesBash"))
{
if ((GetLocalInt(OBJECT_SELF, "nTinyBones") == FALSE) && (nCorpseSize == CREATURE_SIZE_TINY))
{
// Do nothing -- no bones for tiny creatures if nTinyBones is FALSE
}
else
{
// Create the bones
object oBones = CreateObject(OBJECT_TYPE_PLACEABLE, "loot_bones_obj", GetLocation(OBJECT_SELF), FALSE);
// Move inventory to bones
TransferToBones(OBJECT_SELF, oBones);
// Fade bones after nBoneFade seconds
if (GetLocalInt(OBJECT_SELF, "nBonesFade") > 0)
{
// Remember racial type and Blueprint ResRef for use with Scrotok's Raise Dead/Resurrection plugin
SetLocalInt(oBones, "nRacialType", GetLocalInt(OBJECT_SELF, "nRacialType"));
SetLocalString(oBones, "sHostBodyResRef", GetLocalString(OBJECT_SELF, "sHostBodyResRef"));
// Pass dropped weapon/shield/torch info to bones
SetLocalObject(oBones, "oLeftWpn", GetLocalObject(OBJECT_SELF, "oLeftWpn"));
SetLocalObject(oBones, "oRightWpn", GetLocalObject(OBJECT_SELF, "oRightWpn"));
int nKeepWeaponsBonesFade = GetLocalInt(OBJECT_SELF, "nKeepWeaponsBonesFade");
// Remember nKeepWeaponsBonesFade for use with DM's Helper wand
SetLocalInt(oBones, "nKeepWeaponsBonesFade", nKeepWeaponsBonesFade);
float fBonesFade = IntToFloat(GetLocalInt(OBJECT_SELF, "nBonesFade"));
AssignCommand(oBones, DelayCommand(fBonesFade, BonesCleanup(oBones, nKeepWeaponsBonesFade)));
}
}
}
// Delete unclaimed, dropped, non-Plot weapons/shields/torches unless nKeepWeaponsBash = 1
if (!GetLocalInt(OBJECT_SELF, "nKeepWeaponsBash"))
DestroyDroppedWeapons(OBJECT_SELF);
// Destroy the lootable corpse placeable (once it's empty)
// DelayCommand(1.0f, DestroyObject(OBJECT_SELF)); // Removed in version 3.3
DelayCommand(1.0, DestroyIfEmpty());
}

View File

@@ -0,0 +1,189 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_corpse_distb // VERSION 3.3 //
// // //
// by Scrotok on 9 Feb 03 ////////////////////////////
// Thanks to Keron Blackfeld for 99% of the work! //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// CAUTION: You MUST re-save/compile (or press F7 for "Save and Compile") //
// the "_kb_corpse_death" and "_kb_corpse_distb" scripts if you make any //
// changes to "_kb_inc_invmgmt" (for programmers only: because it is an //
// #include file). //
// //
// NEWBIES: You don't need to place this script anywhere -- it's already //
// taken care of for you. //
// //
// NOTE: If you were using the old "_kb_ohb_lootable", be sure to delete //
// that script, and remove it from the OnHeartbeat of your lootable corpse //
// placeable (tag "invis_corpse_obj"). This only applies if you have an OLD //
// version of Keron's lootable corpses script. //
// //
// This script works in conjunction with the "_kb_loot_corpse" script. The //
// OnDisturbed event of the lootable corpse placeable (tag //
// "invis_corpse_obj") contains this script. This script checks the //
// inventory of OBJECT_SELF, and when it is empty (and dropped weapons have //
// been claimed), it checks a LocalInt to see if the now-empty corpse should //
// be destroyed along with the lootable corpse placeable. Plot items are //
// not destroyed. If nKeepWeaponsEmpty is TRUE, empties will be destroyed //
// even if dropped weapons/shields/torches are unclaimed. //
// //
// If the inventory is NOT empty, this script will also check to see if the //
// lootable armour (oLootArmour) was removed; if so, it destroys the //
// original armour (oOrigArmour) on the corpse. A similar check is made for //
// oLootHelmet and oOrigHelmet. //
// //
// The "_kb_loot_corpse" script must have this line: //
// int nKeepEmpties = FALSE; //
// in order for the empty corpse to destroy itself in this script. //
// //
////////////////////////////////////////////////////////////////////////////////
/* Version 3.3 Change Log:
- fixed comments to clarify that "doa_lootnotify" script refers to DOA's "Party Loot Notification" plugin
/* Version 3.2 Change Log:
- renamed script from "_kb_ondist_loot" to "_kb_corpse_distb" for naming consistency
- consolidated inventory management functions to _kb_inc_invmgmt
- ClearInventory function calls changed to DestroyInventory in _kb_inc_invmgmt (identical)
- get low animation moved to end of script (see DEFAULT BEHAVIOR)
- added simple plugin architecture (requires file _kb_plugins)
- integration with DOA's "Party Loot Notification" plugin ("doa_lootnotify") now requires zero editing (no include call)
- added GetIsObjectValid check before destroying Bloodspot
- changed comments to clarify weapons/shields/torches are affected by "weapons" parameters/functions
- renamed oHostCorpse to oHostBody for consistency
- added check for oLootHelmet and oOrigHelmet
*/
#include "_kb_inc_invmgmt"
/*********************************************************************
** This function checks to see if our corpse's discarded weapons **
** have been picked up. If so, it returns TRUE. Returns TRUE if **
** no weapons have been dropped. Returns TRUE if any weapon is **
** unclaimed but nKeepWeaponsEmpty is set to TRUE. **
** **
** NOTE: Shields/torches are also considered "weapons" for the **
** purposes of this script. **
*********************************************************************/
int CheckWeapons(object oCorpse)
{
//Check to see if anyone possesses the Left Weapon
object oLeftWpn = GetLocalObject(oCorpse, "oLeftWpn");
object oLeftTest = GetItemPossessor(oLeftWpn);
//Check to see if anyone possesses the Right Weapon
object oRightWpn = GetLocalObject(oCorpse, "oRightWpn");
object oRightTest = GetItemPossessor(oRightWpn);
if (oLeftWpn == OBJECT_INVALID && oRightWpn == OBJECT_INVALID)
{
// No weapons have been dropped
return TRUE;
}
else
{
if (oLeftTest != OBJECT_INVALID && oRightTest != OBJECT_INVALID)
{
// All dropped weapons have been claimed
return TRUE;
}
else
{
if (GetLocalInt(oCorpse, "nKeepWeaponsEmpty"))
{
// One or both dropped weapons are unclaimed, but nKeepWeaponsEmpty == TRUE
return TRUE;
}
else
{
return FALSE;
}
}
}
}
/*********************************************************************
** Here is our main script, which is fired if the Inventory is **
** disturbed. It then checks to see if it needs to either clean **
** up the corpse, destroy the original suit of armour still on **
** the corpse, or destroy the original helmet still on the corpse. **
*********************************************************************/
void main()
{
/* Register Plugins */
if (!GetLocalInt(GetModule(),"kb_lootcorpse_plugins"))
ExecuteScript("_kb_plugins", OBJECT_SELF);
//Get all of our required information
object oInvDisturbed = GetInventoryDisturbItem(); //Get item that was disturbed to trigger event
int nInvDistType = GetInventoryDisturbType(); //Get type of inventory disturbance
object oHostBody = 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
object oOrigArmour = GetLocalObject(OBJECT_SELF, "oOrigArmour"); //Get Value set by _kb_loot_corpse at creation
object oLootArmour = GetLocalObject(OBJECT_SELF, "oLootArmour"); //Get Value set by _kb_loot_corpse at creation
object oOrigHelmet = GetLocalObject(OBJECT_SELF, "oOrigHelmet"); //Get Value set by _kb_loot_corpse at creation
object oLootHelmet = GetLocalObject(OBJECT_SELF, "oLootHelmet"); //Get Value set by _kb_loot_corpse at creation
object oPC = GetLastDisturbed();
object oHasInventory = GetFirstItemInInventory(OBJECT_SELF); //Check for inventory
if (oHasInventory == OBJECT_INVALID && CheckWeapons(OBJECT_SELF)) //If no inventory found and Weapons have been claimed
{
/*******************************************
** Inventory is empty. Now we check the **
** nKeepEmpty value. **
*******************************************/
int nKeepEmpty = GetLocalInt(OBJECT_SELF, "nKeepEmpty"); //Get Value set by _kb_loot_corpse at creation
if (!nKeepEmpty)
{
/*******************************************
** nKeepEmpty is FALSE. Delete empty. **
*******************************************/
//Delete the BloodSpot (if created)
if (GetIsObjectValid(oCorpseBlood))
{
DestroyObject(oCorpseBlood);
}
// Empty and delete actual creature corpse (body)
DestroyInventory(oHostBody);
AssignCommand(oHostBody, SetIsDestroyable(TRUE,FALSE,FALSE));
DestroyObject(oHostBody);
// Empty and delete lootable corpse object (self)
DelayCommand(1.0f, DestroyObject(OBJECT_SELF));
}
}
//Check to see if the Armour has been taken
if (oInvDisturbed == oLootArmour && nInvDistType == INVENTORY_DISTURB_TYPE_REMOVED)
{
/*******************************************
** The Armour is gone - destroy original **
** armour still showing on corpse. **
*******************************************/
DestroyObject(oOrigArmour);
}
//Check to see if the Helmet has been taken
if (oInvDisturbed == oLootHelmet && nInvDistType == INVENTORY_DISTURB_TYPE_REMOVED)
{
/*******************************************
** The Helmet is gone - destroy original **
** helmet still showing on corpse. **
*******************************************/
DestroyObject(oOrigHelmet);
}
// PLUGIN BEHAVIOR
if (GetLocalInt(GetModule(),"doa_lootnotify"))
{
ExecuteScript("doa_lootnotify", OBJECT_SELF);
}
else
{
// DEFAULT BEHAVIOR if plugin not installed
AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 1.2f));
}
}

View File

@@ -0,0 +1,33 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_corpse_phatk // VERSION 3.3 //
// // //
// by Scrotok on 9 Feb 03 ////////////////////////////
// Thanks to Keron Blackfeld for 99% of the work! //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// NEWBIES: You don't need to place this script anywhere -- it's already //
// taken care of for you. //
// //
// This script works in conjunction with the "_kb_loot_corpse" script. The //
// OnPhysicalAttacked event of the lootable corpse placeable (tag //
// "invis_corpse_obj") contains this script. //
// //
// This script allows third-party plugins to function (if installed), or //
// runs the default behavior (if no plugins installed). //
// //
////////////////////////////////////////////////////////////////////////////////
void main()
{
/* Register Plugins */
if (!GetLocalInt(GetModule(),"kb_lootcorpse_plugins"))
ExecuteScript("_kb_plugins", OBJECT_SELF);
// PLUGIN BEHAVIOR
// DEFAULT BEHAVIOR if plugin not installed
}

View File

@@ -0,0 +1,37 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_corpse_spell // VERSION 3.3 //
// // //
// by Scrotok on 9 Feb 03 ////////////////////////////
// Thanks to Keron Blackfeld for 99% of the work! //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// NEWBIES: You don't need to place this script anywhere -- it's already //
// taken care of for you. //
// //
// This script works in conjunction with the "_kb_loot_corpse" script. The //
// OnSpellCastAt events of the lootable corpse placeable (tag //
// "invis_corpse_obj") and the lootable bones placeable ("loot_bones_obj") //
// contain this script. //
// //
// This script allows third-party plugins to function (if installed), or //
// runs the default behavior (if no plugins installed). //
// //
////////////////////////////////////////////////////////////////////////////////
void main()
{
/* Register Plugins */
if (!GetLocalInt(GetModule(),"kb_lootcorpse_plugins"))
ExecuteScript("_kb_plugins", OBJECT_SELF);
// PLUGIN BEHAVIOR
// Scrotok's Raise Dead/Resurrection plugin
if (GetLocalInt(GetModule(),"kb_raise_res"))
ExecuteScript("_kb_raise_res", OBJECT_SELF);
// DEFAULT BEHAVIOR if plugin not installed
}

View File

@@ -0,0 +1,59 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_corpse_used // VERSION 3.3 //
// // //
// by Scrotok on 9 Feb 03 ////////////////////////////
// Thanks to Keron Blackfeld for 99% of the work! //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// NEWBIES: You don't need to place this script anywhere -- it's already //
// taken care of for you. //
// //
// This script works in conjunction with the "_kb_loot_corpse" script. The //
// OnUsed event of the lootable corpse placeable (tag "invis_corpse_obj") //
// contains this script. This script causes the PC searching the corpse to //
// crouch down and visibly reach for the corpse. //
// //
////////////////////////////////////////////////////////////////////////////////
/* Version 3.3 Change Log:
- fixed comments to clarify that "doa_lootnotify" script refers to DOA's "Party Loot Notification" plugin
/* Version 3.2 Change Log:
- renamed script from "_kb_loot_crouch" to "_kb_corpse_used" for naming consistency
- added simple plugin architecture (requires file _kb_plugins)
- integration with DOA's "Party Loot Notification" plugin ("doa_lootnotify") now requires zero editing (no include call)
- added check of GetIsOpen to ensure crouch animation only plays when corpse is opened
*/
void main()
{
/* Register Plugins */
if (!GetLocalInt(GetModule(),"kb_lootcorpse_plugins"))
ExecuteScript("_kb_plugins", OBJECT_SELF);
// PLUGIN BEHAVIOR
if (GetLocalInt(GetModule(),"doa_lootnotify"))
{
ExecuteScript("doa_lootnotify_o", OBJECT_SELF);
}
else
{
// DEFAULT BEHAVIOR if plugin not installed
object oPC = GetLastUsedBy();
// Play crouch animation only if PC just opened the corpse inventory GUI
// EXCEPTION: If the PC opens the corpse inventory, then quickly presses
// the "I" key (to open the PC inventory), a BioWare software bug will
// trick the software into permanently thinking the corpse inventory is
// open (even though the GUI can be opened and closed normally). This will
// cause the animation to play when corpse is opened or closed (a minor
// bug).
if (GetIsOpen(OBJECT_SELF))
{
AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW, 1.0f, 1.2f));
}
}
}

View File

@@ -0,0 +1,34 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_corpse_user // VERSION 3.3 //
// // //
// by Scrotok on 9 Feb 03 ////////////////////////////
// Thanks to Keron Blackfeld for 99% of the work! //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// NEWBIES: You don't need to place this script anywhere -- it's already //
// taken care of for you. //
// //
// This script works in conjunction with the "_kb_loot_corpse" script. The //
// OnUserDefined event of the lootable corpse placeable (tag //
// "invis_corpse_obj") contains this script. //
// //
// This script allows third-party plugins to function (if installed), or //
// runs the default behavior (if no plugins installed). //
// //
////////////////////////////////////////////////////////////////////////////////
void main()
{
/* Register Plugins */
if (!GetLocalInt(GetModule(),"kb_lootcorpse_plugins"))
ExecuteScript("_kb_plugins", OBJECT_SELF);
// PLUGIN BEHAVIOR
// DEFAULT BEHAVIOR if plugin not installed
int iEvent = GetUserDefinedEventNumber();
}

View File

@@ -0,0 +1,156 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_inc_invmgmt (include file) // VERSION 3.3 //
// // //
// by Scrotok on 9 Feb 03 ////////////////////////////
// Thanks to Keron Blackfeld for 99% of the work! //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// CAUTION: You MUST re-save/compile (or press F7 for "Save and Compile") //
// the "_kb_corpse_death" and "_kb_corpse_distb" scripts if you make any //
// changes to "_kb_inc_invmgmt" (for programmers only: because it is an //
// #include file). //
// //
// CAUTION: You MUST re-save (not the F7 key!) "_kb_loot_corpse" if you make //
// any changes to "_kb_inc_invmgmt" (for programmers only: because it is an //
// #include file). To re-save it, make a change to the script, then UNDO //
// the change, then re-save. //
// //
// NEWBIES: You don't need to place this script anywhere -- it's already //
// taken care of for you. //
// //
// This script works in conjunction with the "_kb_loot_corpse" script. It //
// contains common functions used in "_kb_corpse_death", "_kb_corpse_distb", //
// and "_kb_loot_corpse". //
// //
////////////////////////////////////////////////////////////////////////////////
/* Version 3.2 Change Log:
- ClearInventory was 99% the same as DestroyInventory except for the
dropped weapons, so they were consolidated.
- DestroyInventory rewritten to use equipped item integers in a loop.
- DestroyDroppedWeapons is a new function which does only that.
- added TransferToBones function to move lootable corpse placeable inventory to bones
- added BonesCleanup function to get rid of the bones after nBonesFade
- changed comments to clarify weapons/shields/torches are affected by "weapons" parameters/functions
*/
/************************************************************************
** This function is used to clear the entire inventory of an object **
** (except for Creature Slots, which have no bearing here), so that **
** when the object is destroyed, no Lootbags are left behind to **
** litter up the landscape & devour system resources. Plot items are **
** not affected. **
************************************************************************/
void DestroyInventory(object oCorpse)
{
/* Version 3.2 - function rewritten */
object oLoot; int x;
//Get any gold from the dead creature
x = GetGold(oCorpse);
if (x) TakeGoldFromCreature(x, oCorpse, TRUE);
// Destroy any loot the dead creature has equipped
// 0=head, 1=chest, 2=boot, 3=arms, 4=rhand, 5=lhand, 6=cloak,
// 7=lring, 8=rring, 9=neck, 10=belt, 11=arrow, 12=bullet, 13=bolt
for (x = 0; x < 4; x++)
{
oLoot = GetItemInSlot(x, oCorpse);
if (GetIsObjectValid(oLoot))
{
if (!GetPlotFlag(oLoot))
DestroyObject(oLoot);
}
}
// skipped 4 & 5 = equipped weapons (rhand & lhand)
for (x = 6; x < 14; x++)
{
oLoot = GetItemInSlot(x, oCorpse);
if (GetIsObjectValid(oLoot))
{
if (!GetPlotFlag(oLoot))
DestroyObject(oLoot);
}
}
// Destroy remaining loot on creature
oLoot = GetFirstItemInInventory(oCorpse);
while (GetIsObjectValid(oLoot))
{
if (!GetPlotFlag(oLoot))
DestroyObject(oLoot);
oLoot = GetNextItemInInventory(oCorpse);
}
}
/************************************************************************
** This function is used to destroy unclaimed dropped weapons. **
** Plot items are not affected. **
** **
** NOTE: Shields/torches are also considered "weapons" for the **
** purposes of this script. **
** **
** NOTE: The lootable corpse placeable or the bones can call this **
** script. **
************************************************************************/
void DestroyDroppedWeapons(object oLootCorpse)
{
//Check to see if anyone Possesses the Left Weapon
object oLeftWpn = GetLocalObject(oLootCorpse, "oLeftWpn");
// If Left Weapon is unclaimed...
if (GetItemPossessor(oLeftWpn) == OBJECT_INVALID)
{
// If dropped weapon is not Plot
if (!GetPlotFlag(oLeftWpn))
DestroyObject(oLeftWpn);
}
//Check to see if anyone Possesses the Right Weapon
object oRightWpn = GetLocalObject(oLootCorpse, "oRightWpn");
// If Right Weapon is unclaimed...
if (GetItemPossessor(oRightWpn) == OBJECT_INVALID)
{
// If dropped weapon is not Plot
if (!GetPlotFlag(oRightWpn))
DestroyObject(oRightWpn);
}
}
/*********************************************************
** This script gets rid of the bones after they fade **
*********************************************************/
void BonesCleanup(object oBones, int nKeepWeaponsBonesFade)
{
// Empty the bones inventory
DestroyInventory(oBones);
// Delete unclaimed, dropped, non-Plot weapons unless nKeepWeaponsBonesFade = 1
if (!nKeepWeaponsBonesFade)
DestroyDroppedWeapons(oBones);
// Delete the bones
DestroyObject(oBones);
}
/******************************************************************************
** This script moves all items from lootable corpse placeable to the bones **
******************************************************************************/
void TransferToBones(object oLootCorpse, object oBones)
{
// Move gold to the bones
if (GetGold(oLootCorpse))
{
AssignCommand(oBones, TakeGoldFromCreature(GetGold(oLootCorpse), oLootCorpse, FALSE));
}
// Move inventory items to the bones
object oLoot = GetFirstItemInInventory(oLootCorpse);
while (GetIsObjectValid(oLoot))
{
AssignCommand(oBones, ActionTakeItem(oLoot, oLootCorpse));
oLoot = GetNextItemInInventory(oLootCorpse);
}
}
//void main() {}

View File

@@ -0,0 +1,855 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_loot_corpse (include file) // VERSION 3.3 //
// // //
// by Scrotok on 9 Feb 03 ////////////////////////////
// Thanks to Keron Blackfeld for 99% of the work! //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// CAUTION: You MUST re-save/compile (F7 key) "nw_c2_default7" whenever //
// "_kb_loot_corpse" is modified! //
// //
// CAUTION: You MUST re-save (not the F7 key!) "_kb_loot_corpse" if you make //
// any changes to "_kb_inc_invmgmt" (for programmers only: because it is an //
// #include file). To re-save it, make a change to the script, then UNDO //
// the change, then re-save. //
// //
// NEWBIES: You don't need to place this script anywhere -- it's included as //
// part of "nw_c2_default7" using the #include command. All you need to do //
// is configure the script (see below) as desired. //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// //
// CONFIGURING THE SCRIPT //
// //
// This script supports some configuration by the user. Following the //
// void LeaveCorpse() of the _kb_loot_corpse, you'll find a section where //
// you can set a few things. These include: (with default values displayed) //
// //
// //
// int nUseLootable = TRUE This enables the script. Setting is to FALSE //
// disables it. //
// //
// int nMoveEquipped = TRUE Setting this to FALSE will stop the script //
// from moving equipped items (other than //
// Armour/Helmet and Weapons/Shield/Torch) to //
// the lootable corpse placeable. (To prevent //
// the move/copy of Armour/Helmet and Weapons/ //
// Shield/Torch, use the next four toggles.) //
// Remember that CREATURE SLOTTED items are //
// NEVER moved. //
// //
// int nCopyArmour = TRUE This will use the ResRef to create a copy of //
// the Armour/Helmet the creature is wearing. //
// If you do not want to use this function, you //
// may want to consider the next one (called //
// nMoveArmour). nCopyArmour takes precedence //
// over nMoveArmour if both are TRUE. //
// //
// int nMoveArmour = FALSE Setting this TRUE will just move the armour //
// from the Chest slot to the lootable corpse //
// placeable on death; it will also move the //
// helmet from the Head slot to the lootable //
// corpse placeable. This can be a visual issue //
// when used with NPCs - since when the armour //
// is moved, the NPC will become 'naked'. //
// //
// *** If you do not wish to use either of the armour functions, just set //
// both values to FALSE. Then just add an additional suit of armour //
// and/or helmet to the inventory of creatures you want to have drop //
// their armour/helmet. //
// //
// int nDropWeapons = TRUE This will use the ResRef for dropping the //
// weapons on the ground - which is accomplished //
// by creating new ones on the ground and //
// destroying the ones in the creature's //
// inventory. NOTE: Even though the parameter //
// is called nDropWeapons, anything held in the //
// left or right hand (shield, torch, etc.) is //
// affected by this parameter. nDropWeapons //
// takes precedence over nMoveWeapons if both //
// are TRUE. //
// //
// int nMoveWeapons = FALSE Setting this TRUE will just move the weapons //
// to the Lootable Object just as the rest of //
// inventory is handled. NOTE: Even though the //
// parameter is called nMoveWeapons, anything //
// held in the left or right hand (shield, //
// torch, etc.) is affected by this parameter. //
// //
// *** If you do not wish to use either of the weapon functions, just set //
// both values to FALSE. Then just add additional weapons/shields/ //
// torches to the inventory of creatures you want to have drop those //
// items. //
// //
// int nUseBlood = TRUE Set this to TRUE if you want a Bloodspot to //
// appear under the corpse for a little extra //
// gory appeal. In addition, it will allow for //
// a grisly display if the corpse is destroyed. //
// Undead/constructs/elementals will not leave a //
// Bloodspot or "gib" when bashed. //
// //
// int nTinyBlood = FALSE Set this to FALSE if you don't want Tiny- //
// sized creatures (rats, bats, etc.) to leave a //
// Bloodspot, scorch mark, or small flame. They //
// will still "gib" normally. Only applies if //
// nUseBlood = TRUE. //
// //
// int nUseFlame = TRUE Set this to TRUE if you want a scorch mark or //
// a small flame (which burns out after 10-120 //
// seconds, and is replaced by a scorch mark) to //
// appear if 1/3 or more of the damage which //
// killed the creature was fire or electrical. //
// Scorch mark or flame will appear instead of //
// Bloodspot. If the total fire or electrical //
// damage exceeds the creature's max HP, a small //
// flame appears instead of a scorch mark. The //
// corpse will still gib normally. Undead, //
// constructs, and elementals will leave a //
// scorch mark, small flame, or nothing. Only //
// applies if nUseBlood = TRUE. //
// //
// int nCorpseFade = 0 This is the delay in actual seconds that the //
// corpse will remain before it fades. If you //
// set this to 0 (zero) it will turn off the //
// corpse fade - allowing all bodies and loot //
// to remain indefinitely. //
// //
// int nUseBonesBash = TRUE Set this to TRUE if you want bones to appear //
// when the corpse is bashed. The bones cannot //
// be bashed; they will only disappear if //
// nBonesFade > 0. //
// //
// int nUseBonesFade = TRUE Set this to TRUE if you want bones to appear //
// when the corpse fades. The bones cannot //
// be bashed; they will only disappear if //
// nBonesFade > 0. //
// //
// int nBonesFade = 60 This is the delay in actual seconds that the //
// bones will remain before they fade. If you //
// set this to 0 (zero) it will turn off the //
// bones fade - allowing all bones (and loot, //
// if the bones contain any) to remain forever. //
// //
// int nTinyBones = FALSE Set this to FALSE if you don't want Tiny- //
// sized creatures (rats, bats, etc.) to turn //
// into bones when their corpse is bashed or //
// fades. Only applies if nUseBonesBash and/or //
// nUseBonesFade = TRUE. //
// //
// int nKeepInventoryBash = FALSE Set this to TRUE if you want all items //
// in a creature's inventory to remain when //
// its corpse is bashed. If installed, //
// DOA's "Bashed Loot Breakage" plugin //
// ("doa_bashbreak") takes precedence over //
// nKeepInventoryBash. //
// //
// int nKeepInventoryFade = FALSE Set this to TRUE if you want all items //
// in a creature's inventory to remain when //
// its corpse fades. //
// //
// int nKeepEmpties = TRUE Set this to FALSE if you want EMPTY corpses //
// to fade immediately after their inventory is //
// emptied (and dropped weapons are claimed, //
// unless nKeepWeaponsEmpty is TRUE). //
// //
// int nKeepWeaponsBonesFade = FALSE Set this to FALSE if you want //
// dropped, unclaimed, non-plot weapons //
// to be destroyed when bones fade. //
// Only valid if nBonesFade > 0. //
// //
// int nKeepWeaponsCorpseFade = TRUE Set this to FALSE if you want //
// dropped, unclaimed, non-plot weapons //
// to be destroyed when corpses fade. //
// Only valid if nCorpseFade > 0. //
// //
// int nKeepWeaponsBash = TRUE Set this to FALSE if you want //
// dropped, unclaimed, non-plot weapons //
// to be destroyed when corpses are //
// bashed. //
// //
// int nKeepWeaponsEmpty = TRUE Set this to TRUE if you want empty //
// corpses to be destroyed even if //
// dropped weapons are unclaimed. //
// //
// *** Even though the 4 parameters listed above start with "nKeepWeapons", //
// anything held in the left or right hand (shield, torch, etc.) is //
// affected by these parameters, not just weapons. //
// //
// 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. (i.e. Fading Out //
// after the delay or being emptied) //
// To use this functionality, you //
// should place the _kb_plc_corpse //
// script in the OnSpawn of the //
// critter you want to spawn dead. //
// //
////////////////////////////////////////////////////////////////////////////////
/* Version 3.3 Change Log:
- added SetPlotFlag to ensure oLootCorpse can't be destroyed before oHostBody is emptied (and weapons are dropped)
- fixed comments to clarify that "doa_bashbreak" script refers to DOA's "Bashed Loot Breakage" plugin
/* Version 3.2 Change Log:
- consolidated inventory management functions to _kb_inc_invmgmt
- DestroyInventory function calls changed to DestroyInventory + DestroyDroppedWeapons in _kb_inc_invmgmt (identical)
- added nTinyBlood and nUseFlame (added Flameout function and rewrote Bloodspot routine)
- added GetIsObjectValid check before destroying Bloodspot
- removed ActionWait (wasn't needed)
- combined several DelayCommand's into a single function (FadeCorpse) to improve performance
- improved FadeCorpse to take advantage of new functionality (nKeepInventoryFade, nUseBonesFade, etc.)
- fixed bug in DropLeftWeapon/DropRightWeapon that caused dropped weapons to have incorrect GetIdentified value
- fixed bug where 2 copies of droppable, equipped, Plot armor were created instead of 1 when corpse was bashed
- fixed bug that caused copied armor to have incorrect GetPlotFlag and GetIdentified values
- added nUseBonesBash to create bones when corpse is bashed
- added nUseBonesFade to create bones when corpse fades
- added nBonesFade to determine when bones fade (if ever)
- added nTinyBones to prevent bones from appearing for tiny-sized creatures
- added nKeepInventoryBash to keep all items in a creature's inventory when its corpse is bashed
- added nKeepInventoryFade to keep all items in a creature's inventory when its corpse fades
- replaced nKeepWeapons with: nKeepWeaponsBonesFade, nKeepWeaponsCorpseFade, nKeepWeaponsBash, and nKeepWeaponsEmpty
- changed comments to clarify weapons/shields/torches are affected by "weapons" parameters/functions
- changed comments to reflect that undead/constructs/elementals will not leave Bloodspot or "gib" when bashed
- fixed bug so that nCopyArmour takes precedence over nMoveArmour if both are TRUE
- added comments to clarify that nCopyArmour takes precedence over nMoveArmour if both are TRUE
- added comments to clarify that nDropWeapons takes precedence over nMoveWeapons if both are TRUE
- renamed oDeadNPC to oHostBody, and vDeadNPCLoc to vHostBodyLoc for consistency
- fixed bug so that nCopyArmour/nMoveArmour affect helmets equipped in the creature's Head slot, as well
- added support for "Destroy Target" command of DM's Helper wand (used to destroy the corpse or bones)
- added code to pass oLeftWpn/oRightWpn from oHostBody to oLootCorpse for use with Scrotok's Raise Dead/Ressurection Plugin
*/
#include "_kb_inc_invmgmt"
/*******************************************************************************
** 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. :) **
*******************************************************************************/
object strip_equipped(object oHostBody, object oLootCorpse, object oEquip)
{
if(GetIsObjectValid(oEquip) && GetDroppableFlag(oEquip))
{
AssignCommand(oLootCorpse, ActionTakeItem(oEquip, oHostBody));
}
return oEquip;
}
/*******************************************************************************
** These scripts drop weapons/shields/torches held in the corpse's hands. **
** **
** SPECIAL THANKS TO DREZDAR and MOJO for their help in getting these two **
** drop weapon scripts written. I never would have gotten the vectors right, **
** but THEY sure did! **
** **
** (East = 0, North = 90, West = 180, South = 270) **
** **
*******************************************************************************/
void DropLeftWeapon(object oLeftWpn, object oLootCorpse)
{
if(GetIsObjectValid(oLeftWpn) && GetDroppableFlag(oLeftWpn))
{
vector vCorpseLoc = GetPositionFromLocation(GetLocation(oLootCorpse));
float fDifferential = 45.0f + IntToFloat(d20());//Randomize the Drop Angle
float fDistance = 0.5f + (IntToFloat(d10())/10);//Randomize the Drop Distance
float fVarWpnFace = -20.0f - IntToFloat(d20(2));//Randomize the Drop Facing
float fFacing = GetFacing(oLootCorpse);
fFacing = fFacing + fDifferential;
if (fFacing > 360.0f)
{ fFacing = 720.0f - fFacing; }
if (fFacing < 0.0f)
{ fFacing = 360.0f + fFacing; }
float fWpnFacing = GetFacing(oLootCorpse) + fVarWpnFace;
if (fWpnFacing > 360.0f)
{ fWpnFacing = 720.0f - fWpnFacing; }
if (fWpnFacing < 0.0f)
{ fWpnFacing = 360.0f + fWpnFacing; }
object oArea = GetArea(oLootCorpse);
//Generate New Location
float fNewX;
float fNewY;
float fNewZ;
if ((fFacing > 0.0f) && (fFacing < 90.0f))
{ fNewX = vCorpseLoc.x + ((cos(fFacing))*fDistance); fNewY = vCorpseLoc.y + ((sin(fFacing))*fDistance); fNewZ = vCorpseLoc.z; }
else if ((fFacing > 90.0f) && (fFacing < 180.0f))
{ fNewX = vCorpseLoc.x - ((cos(180.0f - fFacing))*fDistance); fNewY = vCorpseLoc.y + ((sin(180.0f - fFacing))*fDistance); fNewZ = vCorpseLoc.z; }
else if ((fFacing > 180.0f) && (fFacing < 270.0f))
{ fNewX = vCorpseLoc.x - ((cos(fFacing - 180.0f))*fDistance); fNewY = vCorpseLoc.y - ((sin(fFacing - 180.0f))*fDistance); fNewZ = vCorpseLoc.z; }
else if ((fFacing > 270.0f) && (fFacing < 360.0f))
{ fNewX = vCorpseLoc.x + ((cos(360.0f - fFacing))*fDistance); fNewY = vCorpseLoc.y - ((sin(360.0f - fFacing))*fDistance); fNewZ = vCorpseLoc.z; }
else if (fFacing == 0.0f)
{ fNewX = vCorpseLoc.x + fDistance; fNewY = vCorpseLoc.y; fNewZ = vCorpseLoc.z; }
else if (fFacing == 90.0f)
{ fNewX = vCorpseLoc.x; fNewY = vCorpseLoc.y + fDistance; fNewZ = vCorpseLoc.z; }
else if (fFacing == 180.0f)
{ fNewX = vCorpseLoc.x - fDistance; fNewY = vCorpseLoc.y; fNewZ = vCorpseLoc.z; }
else if (fFacing == 270.0f)
{ fNewX = vCorpseLoc.x; fNewY = vCorpseLoc.y - fDistance; fNewZ = vCorpseLoc.z; }
vector vNewFinal = Vector(fNewX, fNewY, fNewZ);
location lDropLeft = Location(oArea, vNewFinal, fWpnFacing);
//Drop Weapon
string sLeftWpnRef = GetResRef(oLeftWpn);
int nID = GetIdentified(oLeftWpn);
if (GetPlotFlag(oLeftWpn))
{
SetPlotFlag(oLeftWpn, FALSE);
DestroyObject(oLeftWpn);
oLeftWpn = CreateObject(OBJECT_TYPE_ITEM, sLeftWpnRef, lDropLeft, FALSE);
SetPlotFlag(oLeftWpn, TRUE);
}
else
{
DestroyObject(oLeftWpn);
oLeftWpn = CreateObject(OBJECT_TYPE_ITEM, sLeftWpnRef, lDropLeft, FALSE);
}
SetIdentified(oLeftWpn, nID);
SetLocalObject(oLootCorpse, "oLeftWpn", oLeftWpn);
}
// We're done with oHostBody, so allow oLootCorpse to be destroyable
AssignCommand(oLootCorpse, ActionDoCommand(SetPlotFlag(oLootCorpse, FALSE)));
}
void DropRightWeapon(object oRightWpn, object oLootCorpse)
{
if(GetIsObjectValid(oRightWpn) && GetDroppableFlag(oRightWpn))
{
vector vCorpseLoc = GetPositionFromLocation(GetLocation(oLootCorpse));
float fDifferential = -45.0f + IntToFloat(d20());//Randomize the Drop Angle
float fDistance = 0.5f + (IntToFloat(d10())/10);//Randomize the Drop Distance
float fVarWpnFace = 20.0f - IntToFloat(d20(2));//Randomize the Drop Facing
float fFacing = GetFacing(oLootCorpse);
fFacing = fFacing + fDifferential;
if (fFacing > 360.0f)
{ fFacing = 720.0f - fFacing; }
if (fFacing < 0.0f)
{ fFacing = 360.0f + fFacing; }
float fWpnFacing = GetFacing(oLootCorpse) + fVarWpnFace;
if (fWpnFacing > 360.0f)
{ fWpnFacing = 720.0f - fWpnFacing; }
if (fWpnFacing < 0.0f)
{ fWpnFacing = 360.0f + fWpnFacing; }
object oArea = GetArea(oLootCorpse);
//Generate New Location
float fNewX;
float fNewY;
float fNewZ;
if ((fFacing > 0.0f) && (fFacing < 90.0f))
{ fNewX = vCorpseLoc.x + ((cos(fFacing))*fDistance); fNewY = vCorpseLoc.y + ((sin(fFacing))*fDistance); fNewZ = vCorpseLoc.z; }
else if ((fFacing > 90.0f) && (fFacing < 180.0f))
{ fNewX = vCorpseLoc.x - ((cos(180.0f - fFacing))*fDistance); fNewY = vCorpseLoc.y + ((sin(180.0f - fFacing))*fDistance); fNewZ = vCorpseLoc.z; }
else if ((fFacing > 180.0f) && (fFacing < 270.0f))
{ fNewX = vCorpseLoc.x - ((cos(fFacing - 180.0f))*fDistance); fNewY = vCorpseLoc.y - ((sin(fFacing - 180.0f))*fDistance); fNewZ = vCorpseLoc.z; }
else if ((fFacing > 270.0f) && (fFacing < 360.0f))
{ fNewX = vCorpseLoc.x + ((cos(360.0f - fFacing))*fDistance); fNewY = vCorpseLoc.y - ((sin(360.0f - fFacing))*fDistance); fNewZ = vCorpseLoc.z; }
else if (fFacing == 0.0f)
{ fNewX = vCorpseLoc.x + fDistance; fNewY = vCorpseLoc.y; fNewZ = vCorpseLoc.z; }
else if (fFacing == 90.0f)
{ fNewX = vCorpseLoc.x; fNewY = vCorpseLoc.y + fDistance; fNewZ = vCorpseLoc.z; }
else if (fFacing == 180.0f)
{ fNewX = vCorpseLoc.x - fDistance; fNewY = vCorpseLoc.y; fNewZ = vCorpseLoc.z; }
else if (fFacing == 270.0f)
{ fNewX = vCorpseLoc.x; fNewY = vCorpseLoc.y - fDistance; fNewZ = vCorpseLoc.z; }
vector vNewFinal = Vector(fNewX, fNewY, fNewZ);
location lDropRight = Location(oArea, vNewFinal, fWpnFacing);
//Drop Weapon
string sRightWpnRef = GetResRef(oRightWpn);
int nID = GetIdentified(oRightWpn);
if (GetPlotFlag(oRightWpn))
{
SetPlotFlag(oRightWpn, FALSE);
DestroyObject(oRightWpn);
oRightWpn = CreateObject(OBJECT_TYPE_ITEM, sRightWpnRef, lDropRight, FALSE);
SetPlotFlag(oRightWpn, TRUE);
}
else
{
DestroyObject(oRightWpn);
oRightWpn = CreateObject(OBJECT_TYPE_ITEM, sRightWpnRef, lDropRight, FALSE);
}
SetIdentified(oRightWpn, nID);
SetLocalObject(oLootCorpse, "oRightWpn", oRightWpn);
}
}
/*******************************************************************************
** This script gets rid of the bloodspot, lootable corpse, and creature body **
*******************************************************************************/
void FadeCorpse(object oCorpseBlood, object oLootCorpse, object oHostBody)
{
//Delete the BloodSpot (if created)
if (GetIsObjectValid(oCorpseBlood))
{
DestroyObject(oCorpseBlood);
}
// Empty (or don't empty) the lootable corpse placeable
if (GetLocalInt(oLootCorpse, "nKeepInventoryFade") == FALSE)
// Delete all items (except Plot) from lootable corpse placeable
DestroyInventory(oLootCorpse);
else
{
// Do nothing (delete nothing from lootable corpse placeable)
}
// If user wants bones to be created when corpse fades...
if (GetLocalInt(oLootCorpse, "nUseBonesFade"))
{
if ((GetLocalInt(oLootCorpse, "nTinyBones") == FALSE) && (GetCreatureSize(oHostBody) == CREATURE_SIZE_TINY))
{
// Do nothing -- no bones for tiny creatures if nTinyBones is FALSE
}
else
{
// Create the bones
object oBones = CreateObject(OBJECT_TYPE_PLACEABLE, "loot_bones_obj", GetLocation(oLootCorpse), FALSE);
// Move inventory to bones
TransferToBones(oLootCorpse, oBones);
// Fade bones after nBoneFade seconds
if (GetLocalInt(oLootCorpse, "nBonesFade") > 0)
{
// Remember racial type and Blueprint ResRef for use with Scrotok's Raise Dead/Resurrection plugin
SetLocalInt(oBones, "nRacialType", GetLocalInt(oLootCorpse, "nRacialType"));
SetLocalString(oBones, "sHostBodyResRef", GetLocalString(oLootCorpse, "sHostBodyResRef"));
// Pass dropped weapon/shield/torch info to bones
SetLocalObject(oBones, "oLeftWpn", GetLocalObject(oLootCorpse, "oLeftWpn"));
SetLocalObject(oBones, "oRightWpn", GetLocalObject(oLootCorpse, "oRightWpn"));
int nKeepWeaponsBonesFade = GetLocalInt(oLootCorpse, "nKeepWeaponsBonesFade");
// Remember nKeepWeaponsBonesFade for use with DM's Helper wand
SetLocalInt(oBones, "nKeepWeaponsBonesFade", nKeepWeaponsBonesFade);
float fBonesFade = IntToFloat(GetLocalInt(oLootCorpse, "nBonesFade"));
AssignCommand(oBones, DelayCommand(fBonesFade, BonesCleanup(oBones, nKeepWeaponsBonesFade)));
}
}
}
// Delete unclaimed, dropped, non-Plot weapons unless nKeepWeaponsCorpseFade = 1
if (!GetLocalInt(oLootCorpse, "nKeepWeaponsCorpseFade"))
DestroyDroppedWeapons(oLootCorpse);
// Delete the lootable corpse placeable
DestroyObject(oLootCorpse);
// Empty and delete actual creature corpse (body)
DestroyInventory(oHostBody);
/* There is no call to DestroyDroppedWeapons since if the weapons are
dropped, they are already deleted from oHostBody. If the weapons are
not dropped, then the function would still not delete the weapons
since GetItemPossessor would be a valid object */
SetIsDestroyable(TRUE,FALSE,FALSE);
// NOTE: The following line MUST be last in this script, since oHostBody
// is the same as OBJECT_SELF
DestroyObject(oHostBody);
}
/*******************************************************************************
** This script replaces the small flame with a scorch mark **
*******************************************************************************/
void Flameout(object oCorpseBlood, object oLootCorpse)
{
location lBloodLoc = GetLocation(oCorpseBlood);
/*
// Used for debugging
SendMessageToPC(GetFirstPC(), "Flame script started...");
if (!GetIsObjectValid(oCorpseBlood))
{
// This should never happen (if you bash/fade corpse, oHostBody is
// destroyed, so Flameout won't run (can't add to action queue of invalid
// object)
SendMessageToPC(GetFirstPC(), "Flame already destroyed... location for new scorch unknown?");
}
*/
// Get rid of small flame
DestroyObject(oCorpseBlood);
// ... and turn it into a scorch mark
oCorpseBlood = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_weathmark", lBloodLoc, FALSE);
//Set Local for deletion later if needed
SetLocalObject(oLootCorpse, "oBloodSpot", oCorpseBlood);
}
void LeaveCorpse()
{
//SET YOUR LOOTABLE CORPSES PREFERENCES HERE ///////////////
//
int nUseLootable = TRUE; // Set this to FALSE if you want disable the lootable corpse functionality //
int nMoveEquipped = TRUE; // Set this to FALSE if you don't want to move Equipped items to the corpse //
int nCopyArmour = TRUE; // This will use the ResRef to create a copy of the armour/helmet //
int nMoveArmour = FALSE; // Setting this TRUE will just move the armour/helmet (Naked NPCs) //
int nDropWeapons = TRUE; // This will use the ResRef for dropping the weapons on the ground //
int nMoveWeapons = FALSE; // Setting this TRUE will just move the weapons to the Lootable Object //
int nUseBlood = TRUE; // Set this to TRUE if you want a Bloodspot to appear under the corpse and have //
// "gibs" when a corpse is destroyed. Undead/constructs/elementals won't leave a //
// Bloodspot or gib. //
int nTinyBlood = FALSE; // Set this to FALSE if you don't want Tiny-sized creatures (rats, bats, etc.) to //
// leave a Bloodspot, scorch mark, or small flame. They will still "gib" //
// normally. Only applies if nUseBlood = TRUE. //
int nUseFlame = TRUE; // Set this to TRUE if you want a scorch mark or a small flame (which burns out //
// after 10-120 seconds, and is replaced by a scorch mark) to appear if 1/3 or //
// more of the damage which killed the creature was fire or electrical. Scorch //
// mark or flame will appear instead of Bloodspot. If the total fire or //
// electrical damage exceeds the creature's max HP, a small flame appears instead //
// of a scorch mark. The corpse will still gib normally. Undead, constructs, //
// and elementals will leave a scorch mark, small flame, or nothing. Only //
// applies if nUseBlood = TRUE. //
int nCorpseFade = 0; // Set this to 0 (ZERO) if you DO NOT want the corpses to fade //
int nUseBonesBash = TRUE; // Set this to TRUE if you want bones to appear when the corpse is bashed. The //
// bones cannot be bashed; they will only disappear if nBonesFade > 0. //
int nUseBonesFade = TRUE; // Set this to TRUE if you want bones to appear when the corpse fades. The bones //
// cannot be bashed; they will only disappear if nBonesFade > 0. //
int nBonesFade = 60; // This is the delay in actual seconds that the bones will remain before they fade. //
// If you set this to 0 (zero) it will turn off the bones fade - allowing all //
// bones (and loot, if the bones contain any) to remain forever. //
int nTinyBones = FALSE; // Set this to FALSE if you don't want Tiny-sized creatures (rats, bats, etc.) to //
// turn into bones when their corpse is bashed or fades. Only applies if //
// nUseBonesBash and/or nUseBonesFade = TRUE. //
int nKeepInventoryBash = FALSE; // Set this to TRUE if you want all items in a creature's inventory to remain when //
// its corpse is bashed. If installed, DOA's "Bashed Loot Breakage" plugin //
// ("doa_bashbreak") takes precedence over nKeepInventoryBash. //
int nKeepInventoryFade = FALSE; // Set this to TRUE if you want all items in a creature's inventory to remain when //
// its corpse fades. //
int nKeepEmpties = TRUE; // Set this to FALSE if you want EMPTY corpses to fade immediately. //
int nKeepWeaponsBonesFade = FALSE; // Set this to FALSE if you want dropped, unclaimed, non-plot weapons to be //
// destroyed when bones fade. Only valid if nBonesFade > 0. //
int nKeepWeaponsCorpseFade = TRUE; // Set this to FALSE if you want dropped, unclaimed, non-plot weapons to be //
// destroyed when corpses fade. Only valid if nCorpseFade > 0. //
int nKeepWeaponsBash = TRUE; // Set this to FALSE if you want dropped, unclaimed, non-plot weapons to be //
// destroyed when corpses are bashed. //
int nKeepWeaponsEmpty = TRUE; // Set this to TRUE if you want empty corpses to be destroyed even if dropped //
// weapons are unclaimed. //
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 oHostBody = OBJECT_SELF; //Get the Dead Creature Object
string sBaseTag = GetTag(oHostBody); //Get that TAG of the dead creature
string sPrefix = GetStringLeft(sBaseTag, 4); //Look for Dead Prefix
if(nUseLootable) //If False, do nothing
{
//Do 'spawned corpse' settings if desired
if (sPrefix == "Dead")
{
if (nOverrideForPlacedCorpses)
{
nKeepEmpties = TRUE; //Set 'Spawned Dead' corpses to Keep Empties
nCorpseFade = 0; //Disable Corpse Fade for 'Spawned Dead' corpses
}
}
SetIsDestroyable(FALSE,TRUE,FALSE); //Protect our corpse from decaying
/*
UNDER CONSTRUCTION :)
// Create lootable corpse object only if oHostBody has something to loot
if (GetIsObjectValid(GetFirstItemInInventory(oHostBody)))
{
}
else
{
// Don't create lootable corpse object(nothing to loot)
if (nKeepEmpties == FALSE)
{
// Get rid of corpse immediately, since it's already empty
nCorpseFade = 1;
}
else
{
// Ensure oHostBody is destroyed/fades properly
// Ensure blood spot is created and destroyed/fades properly
}
}
*/
//Set the spawnpoint for our lootable object and sink it
float fSinkCorpseObj = 0.1f; //set depth to sink lootable object
vector vHostBodyLoc = GetPosition(oHostBody); //get original vector so we can change it
float fCorpseFacing = GetFacing(oHostBody); //get original facing
vector vCorpseLoc = Vector(vHostBodyLoc.x, vHostBodyLoc.y, vHostBodyLoc.z - fSinkCorpseObj); //adjust z-axis to sink lootable object
location lCorpseLoc = Location(GetArea(oHostBody), vCorpseLoc, fCorpseFacing); //create new location
object oLootCorpse = CreateObject(OBJECT_TYPE_PLACEABLE, "invis_corpse_obj", lCorpseLoc, FALSE); //Spawn our lootable object
SetLocalObject(oLootCorpse, "oHostBody", oHostBody); //Set Local for deletion later if needed
// Ensure oLootCorpse can't be destroyed until oHostBody is emptied (and weapons are dropped)
SetPlotFlag(oLootCorpse, TRUE);
SetLocalInt(oLootCorpse, "nKeepEmpty", nKeepEmpties); //Set Local for deletion later if needed
SetLocalInt(oLootCorpse, "nUseBonesBash", nUseBonesBash); //Set Local for later use
SetLocalInt(oLootCorpse, "nUseBonesFade", nUseBonesFade); //Set Local for later use
SetLocalInt(oLootCorpse, "nBonesFade", nBonesFade); //Set Local for later use
SetLocalInt(oLootCorpse, "nTinyBones", nTinyBones); //Set Local for later use
SetLocalInt(oLootCorpse, "nKeepInventoryBash", nKeepInventoryBash); //Set Local for later use
SetLocalInt(oLootCorpse, "nKeepInventoryFade", nKeepInventoryFade); //Set Local for later use
// Remember racial type and Blueprint ResRef for use with Scrotok's Raise Dead/Resurrection plugin
SetLocalInt(oLootCorpse, "nRacialType", GetRacialType(oHostBody));
SetLocalString(oLootCorpse, "sHostBodyResRef", GetResRef(oHostBody));
object oCorpseBlood;
// If nUseBlood is TRUE and oHostBody isn't Undead/Construct/Elemental, set Local for later "gibbing" if bashed
if ((nUseBlood) && (GetRacialType(oHostBody) != RACIAL_TYPE_UNDEAD) && (GetRacialType(oHostBody) != RACIAL_TYPE_CONSTRUCT) && (GetRacialType(oHostBody) != RACIAL_TYPE_ELEMENTAL))
{
SetLocalInt(oLootCorpse, "nUseBlood", TRUE);
}
// If nUseBlood = TRUE, continue Bloodspot routine
if (nUseBlood)
{
location lBloodLoc = GetLocation(oHostBody); //get original location for placing blood spot
if ((nTinyBlood == FALSE) && (GetCreatureSize(oHostBody) == CREATURE_SIZE_TINY))
{
// Do nothing -- no bloodspot for tiny creatures if nTinyBlood is FALSE
}
else
{
if (nUseFlame)
{
// If nUseFlame = TRUE, determine if scorch, flame, or bloodspot should appear
int nFireDam = GetDamageDealtByType(DAMAGE_TYPE_FIRE);
int nElecDam = GetDamageDealtByType(DAMAGE_TYPE_ELECTRICAL);
int nTotDam = GetTotalDamageDealt();
int nMaxHP = GetMaxHitPoints();
int nFlameout;
/*
// Used for debugging
SendMessageToPC(GetFirstPC(), "nFireDam: "+IntToString(nFireDam)+" nElecDam: "+IntToString(nElecDam)+" nTotDam: "+IntToString(nTotDam)+" nMaxHP: "+IntToString(nMaxHP)+" nTotDam/3: "+IntToString(nTotDam/3));
*/
// If 1/3 or more of the damage is due to fire or electricity...
// (only the final damage that actually killed the creature is
// considered; tracking the cumulative damage taken would require
// altering the default OnDamaged script for every creature,
// which is not desirable)
if ((nFireDam >= (nTotDam/3)) || (nElecDam >= (nTotDam/3)))
{
// If massive fire or electricity damage, spawn a small flame
// which turns into a scorch mark after 10-120 seconds
// ("massive" means >= max HP)
if ((nFireDam >= nMaxHP) || (nElecDam >= nMaxHP))
{
oCorpseBlood = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_flamesmall", lBloodLoc, FALSE);
/*
// Used for debugging
nFlameout = 30;
*/
nFlameout = d12(10);
DelayCommand(IntToFloat(nFlameout), Flameout(oCorpseBlood, oLootCorpse));
}
else
{
// Otherwise, spawn a scorch mark
oCorpseBlood = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_weathmark", lBloodLoc, FALSE);
}
}
else
{
// Not enough (or zero) fire/electrical damage, so just spawn bloodspot (or do nothing for Undead/Constructs/Elementals)
if ((GetRacialType(oHostBody) != RACIAL_TYPE_UNDEAD) && (GetRacialType(oHostBody) != RACIAL_TYPE_CONSTRUCT) && (GetRacialType(oHostBody) != RACIAL_TYPE_ELEMENTAL))
{
oCorpseBlood = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_bloodstain", lBloodLoc, FALSE);
}
}
}
else
{
// If nUseFlame = FALSE, just spawn the bloodspot (or do nothing for Undead/Constructs/Elementals)
if ((GetRacialType(oHostBody) != RACIAL_TYPE_UNDEAD) && (GetRacialType(oHostBody) != RACIAL_TYPE_CONSTRUCT) && (GetRacialType(oHostBody) != RACIAL_TYPE_ELEMENTAL))
{
oCorpseBlood = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_bloodstain", lBloodLoc, FALSE);
}
}
// oBloodSpot will either be a bloodstain, scorch mark, small flame, or OBJECT_INVALID (for Undead/Constructs/Elementals)
SetLocalObject(oLootCorpse, "oBloodSpot", oCorpseBlood); //Set Local for deletion later if needed
}
}
// Get DEAD CREATURE'S INVENTORY - Move to oLootCorpse
int nAmtGold = GetGold(oHostBody); //Get any gold from the dead creature
if(nAmtGold)
{
AssignCommand(oLootCorpse, TakeGoldFromCreature(nAmtGold, oHostBody, FALSE));
}
if (nMoveEquipped)
{
//Get any DROPPABLE loot the dead creature has equipped
object oEquip1 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_ARMS, oHostBody));
object oEquip2 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_ARROWS, oHostBody));
object oEquip3 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_BELT, oHostBody));
object oEquip4 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_BOLTS, oHostBody));
object oEquip5 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_BOOTS, oHostBody));
object oEquip6 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_BULLETS, oHostBody));
object oEquip7 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_CLOAK, oHostBody));
// Version 3.2: Moved oEquip8 (helmets) to the armour section (see below)
object oEquip9 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_LEFTRING, oHostBody));
object oEquip10 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_NECK, oHostBody));
object oEquip11 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oHostBody));
SetLocalObject(oLootCorpse, "oEquip1", oEquip1);
SetLocalObject(oLootCorpse, "oEquip2", oEquip2);
SetLocalObject(oLootCorpse, "oEquip3", oEquip3);
SetLocalObject(oLootCorpse, "oEquip4", oEquip4);
SetLocalObject(oLootCorpse, "oEquip5", oEquip5);
SetLocalObject(oLootCorpse, "oEquip6", oEquip6);
SetLocalObject(oLootCorpse, "oEquip7", oEquip7);
// Version 3.2: Moved oEquip8 (helmets) to the armour section (see below)
SetLocalObject(oLootCorpse, "oEquip9", oEquip9);
SetLocalObject(oLootCorpse, "oEquip10", oEquip10);
SetLocalObject(oLootCorpse, "oEquip11", oEquip11);
}
// Handle Weapons/Shields/Torches equipped (held) in left/right hands
// NOTE: nDropWeapons takes precedence over nMoveWeapons if both are TRUE
/*
If oHostBody has nothing in left/right hand, and has oLeftWpn/
oRightWpn set (due to Scrotok's Raise Dead/Resurrection plugin),
set oLeftWpn/oRightWpn (dropped weapon info) on oLootCorpse for
later use
*/
if (nDropWeapons)
{
if (GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oHostBody) == OBJECT_INVALID)
{
if (GetIsObjectValid(GetLocalObject(oHostBody, "oRightWpn")))
{
SetLocalObject(oLootCorpse, "oRightWpn", GetLocalObject(oHostBody, "oRightWpn"));
}
}
if (GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oHostBody) == OBJECT_INVALID)
{
if (GetIsObjectValid(GetLocalObject(oHostBody, "oLeftWpn")))
{
SetLocalObject(oLootCorpse, "oLeftWpn", GetLocalObject(oHostBody, "oLeftWpn"));
}
}
}
if (nMoveWeapons || nDropWeapons)
{
//Move equipped Weapons/Shields/Torches from oHostBody to oLootCorpse
object oEquip12 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oHostBody));
object oEquip13 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oHostBody));
// oEquip12/13 == OBJECT_INVALID if oHostBody has nothing in right/left hand slots
SetLocalObject(oLootCorpse, "oEquip12", oEquip12);
SetLocalObject(oLootCorpse, "oEquip13", oEquip13);
}
if (nDropWeapons)
{
// oEquip12/13 == OBJECT_INVALID if oHostBody has nothing in right/left hand slots
object oEquip12 = GetLocalObject(oLootCorpse, "oEquip12");
object oEquip13 = GetLocalObject(oLootCorpse, "oEquip13");
// Drop the weapons/shields/torches
/*
The following commands destroy oEquip12 and oEquip13, and store
the dropped weapons on oLootCorpse as "oLeftWpn" and "oRightWpn".
Nothing gets stored in oLeftWpn/oRightWpn if oEquip12/13 ==
OBJECT_INVALID.
*/
// Make sure DropLeftWeapon comes after DropRightWeapon in the lines
// below, in order for the SetPlotFlag fix (version 3.3) to work
AssignCommand(oLootCorpse, ActionDoCommand(DropRightWeapon(oEquip12, oLootCorpse)));
AssignCommand(oLootCorpse, ActionDoCommand(DropLeftWeapon(oEquip13, oLootCorpse)));
SetLocalInt(oLootCorpse, "nKeepWeaponsBonesFade", nKeepWeaponsBonesFade); //Set Local to prevent deletion later if needed
SetLocalInt(oLootCorpse, "nKeepWeaponsCorpseFade", nKeepWeaponsCorpseFade); //Set Local to prevent deletion later if needed
SetLocalInt(oLootCorpse, "nKeepWeaponsBash", nKeepWeaponsBash); //Set Local to prevent deletion later if needed
SetLocalInt(oLootCorpse, "nKeepWeaponsEmpty", nKeepWeaponsEmpty); //Set Local for later use
}
// Handle Armour/Helmets
// NOTE: nCopyArmour takes precedence over nMoveArmour if both are TRUE
if(nCopyArmour)
{
nMoveArmour = FALSE;
// Handle armour
object oArmour = GetItemInSlot(INVENTORY_SLOT_CHEST, oHostBody);
SetLocalObject(oLootCorpse, "oOrigArmour", oArmour);
if (GetDroppableFlag(oArmour))
{
string sArmourRef = GetResRef(oArmour);
object oLootArmour = CreateItemOnObject(sArmourRef, oLootCorpse);
SetPlotFlag(oLootArmour, GetPlotFlag(oArmour));
SetIdentified(oLootArmour, GetIdentified(oArmour));
// Set Plot flag to FALSE for original armor so it can be
// destroyed later if corpse is bashed
SetPlotFlag(oArmour, FALSE);
SetLocalObject(oLootCorpse, "oLootArmour", oLootArmour);
SetLocalObject(oLootCorpse, "oEquip14", oLootArmour);
}
// Handle helmet
object oHelmet = GetItemInSlot(INVENTORY_SLOT_HEAD, oHostBody);
SetLocalObject(oLootCorpse, "oOrigHelmet", oHelmet);
if (GetDroppableFlag(oHelmet))
{
string sHelmetRef = GetResRef(oHelmet);
object oLootHelmet = CreateItemOnObject(sHelmetRef, oLootCorpse);
SetPlotFlag(oLootHelmet, GetPlotFlag(oHelmet));
SetIdentified(oLootHelmet, GetIdentified(oHelmet));
// Set Plot flag to FALSE for original helmet so it can be
// destroyed later if corpse is bashed
SetPlotFlag(oHelmet, FALSE);
SetLocalObject(oLootCorpse, "oLootHelmet", oLootHelmet);
SetLocalObject(oLootCorpse, "oEquip8", oLootHelmet);
}
}
if(nMoveArmour)
{
nCopyArmour = FALSE;
// Handle armour
object oEquip14 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_CHEST, oHostBody));
SetLocalObject(oLootCorpse, "oEquip14", oEquip14);
// Handle helmet
object oEquip8 = strip_equipped(oHostBody, oLootCorpse, GetItemInSlot(INVENTORY_SLOT_HEAD, oHostBody));
SetLocalObject(oLootCorpse, "oEquip8", oEquip8);
}
//Get the remaining loot from the dead creature and move it to oLootCorpse
int nEquipCount = 14;
object oLootEQ = GetFirstItemInInventory(oHostBody);
while(GetIsObjectValid(oLootEQ))
{
nEquipCount++;
// AssignCommand(oLootCorpse, ActionDoCommand(SendMessageToPC(GetFirstPC(), "oEquip"+IntToString(nEquipCount)+": "+GetTag(oLootEQ))));
object oEquipTemp = strip_equipped(oHostBody, oLootCorpse, oLootEQ);
string sEquipCount = "oEquip" + IntToString(nEquipCount);
SetLocalObject(oLootCorpse, sEquipCount, oEquipTemp);
oLootEQ = GetNextItemInInventory(oHostBody);
}
// We're done with oHostBody, so allow oLootCorpse to be destroyable
if (!nDropWeapons)
{
AssignCommand(oLootCorpse, ActionDoCommand(SetPlotFlag(oLootCorpse, FALSE)));
}
// Fade corpse out of existence after specified delay (unless set to 0)
if (nCorpseFade > 0)
{
float fCorpseFade = IntToFloat(nCorpseFade);
// ActionWait(fCorpseFade); // Removed for version 3.2
DelayCommand(fCorpseFade, FadeCorpse(oCorpseBlood, oLootCorpse, oHostBody));
}
}
}
//void main(){}

View File

@@ -0,0 +1,38 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_plc_corpse // VERSION 3.3 //
// // //
// by Scrotok on 9 Feb 03 ////////////////////////////
// Thanks to Keron Blackfeld for 99% of the work! //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// This script works in conjunction with the "_kb_loot_corpse" script. //
// Place this script in the OnSpawn event of any creature you want to spawn //
// dead, then add "Dead" as the first 4 letters of its tag -- it will then //
// be lootable! //
// //
////////////////////////////////////////////////////////////////////////////////
/* Version 3.2 Change Log:
- changed EffectDamage to include DAMAGE_POWER_PLUS_FIVE to ensure creature spawns dead
- renamed oDeadNPC to oHostBody for consistency
*/
void main()
{
object oHostBody = OBJECT_SELF; //Get the Dead Creature Object
string sBaseTag = GetTag(oHostBody); //Get that TAG of the dead creature
string sPrefix = GetStringLeft(sBaseTag, 4); //Look for Dead Prefix
if (sPrefix == "Dead") //Do Spawned Corpse
{
//Set up and Deliver our Death Blow
/* this is only needed if you need this
creature to SPAWN as a corpse. */
//Set up for the kill
effect eDamage = EffectDamage(9999, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_FIVE);
//Deliver the killing effect
ApplyEffectToObject (DURATION_TYPE_INSTANT, eDamage, oHostBody);
}
}

View File

@@ -0,0 +1,51 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_plugins // VERSION 3.3 //
// // //
// by Scrotok on 9 Feb 03 ////////////////////////////
// Thanks to Keron Blackfeld for 99% of the work! //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// NEWBIES: You don't need to place this script anywhere -- it's already //
// taken care of for you. //
// //
// This script works in conjunction with the "_kb_loot_corpse" script. //
// //
// When any script (OnDisturbed, OnSpellCastAt, etc.) for the lootable //
// corpse placeable (tag "invis_corpse_obj") is executed, a call is made //
// to "_kb_plugins" (once per module reset) to "register" installed plugins. //
// //
// End-users don't need to make any changes to this script. Plugin creators //
// will need to contact Scrotok so that your plugin can be listed and the //
// appropriate hooks created for distribution. //
// //
////////////////////////////////////////////////////////////////////////////////
/* Version 3.3 Change Log:
- fixed comments to clarify that "doa_bashbreak" script refers to DOA's "Bashed Loot Breakage" plugin
- fixed comments to clarify that "doa_lootnotify" script refers to DOA's "Party Loot Notification" plugin
- fixed comments to clarify that "_kb_raise_res" script refers to Scrotok's "Raise Dead/Resurrection" plugin
*/
void main()
{
// Used for debugging
int bModDebug = GetLocalInt(GetModule(),"bModDebug");
if (bModDebug)
SendMessageToPC(GetFirstPC(),"[kb_lootcorpse] Looking for plugins...");
// Register installed plugins (available plugins listed below)
// ("registration" means setting a module-level variable to 1 for that
// plugin, so that plugin behavior can function)
// IMPORTANT: You must keep OBJECT_INVALID in the lines below!
ExecuteScript("doa_lootnotify", OBJECT_INVALID); // DOA's "Party Loot Notification" plugin
ExecuteScript("_kb_raise_res", OBJECT_INVALID); // Scrotok's "Raise Dead/Resurrection" plugin
ExecuteScript("doa_bashbreak", OBJECT_INVALID); // DOA's "Bashed Loot Breakage" plugin
// Run this script only once
SetLocalInt(GetModule(),"kb_lootcorpse_plugins",1);
}

View File

@@ -0,0 +1,312 @@
////////////////////////////////////////////////////////////////////////////////
// // //
// _kb_raise_res // VERSION 1.0 //
// // //
// Scrotok's Raise Dead/Resurrection Plugin ////////////////////////////
// by Scrotok on 18 Dec 02 //
// Thanks to Lord Niah and Bored Bistander for help on the Raise/Res idea //
// email Questions and Comments to: jnbplatte@intellisys.net //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// This is an optional plugin for Scrotok's Lootable Corpses. It requires //
// modified versions of "nw_s0_raisdead" and "nw_s0_resserec" (included in //
// the ERF for this plugin). This script enables lootable corpses to be //
// brought back to life with either the Resurrection or Raise Dead spells. //
// This script can be called by lootable corpse placeables or bones. //
// //
// NEWBIES: You don't need to place this script anywhere -- it gets called //
// (using the ExecuteScript function) by another script ("_kb_plugins").
// //
// KNOWN BUG: If Raise Dead or Resurrection is cast, but the spell //
// won't work (based on racial type, or the fact that Raise Dead won't work //
// on bones), the spell or scroll is still wasted in the attempt. //
// //
////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
** Used for debugging to determine where the oEquip items are (or if the **
** items are invalid objects). **
*******************************************************************************/
void DetermineEquipOwner(object oLootCorpse)
{
int x;
string sEquip;
for (x = 1; x < 15; x++)
{
sEquip = "oEquip"+IntToString(x);
// oEquip12 & 13 == OBJECT_INVALID if nDropWeapons is TRUE
// oEquip8 & 14 are destroyed (OBJECT_INVALID) during inventory move to oHostBody (if nCopyArmour is TRUE)
if (GetIsObjectValid(GetLocalObject(oLootCorpse, sEquip)))
{
SendMessageToPC(GetFirstPC(), sEquip+" is possessed by "+GetTag(GetItemPossessor(GetLocalObject(oLootCorpse, sEquip))));
}
else
{
SendMessageToPC(GetFirstPC(), sEquip+" is an invalid object.");
}
}
}
/*******************************************************************************
** Used for debugging to ensure returned items get re-equipped by oHostBody. **
** You can also verify some items are equipped in-game by right-clicking on **
** the creature and selecting Examine; for example, you'll see "Increased **
** Strength" if the creature is wearing Gauntlets of Ogre Power. **
*******************************************************************************/
void VerifyEquipped(object oHostBody)
{
object oItem; int x;
for (x = 0; x < 14; x++)
{
oItem = GetItemInSlot(x, oHostBody);
if (GetIsObjectValid(oItem))
{
SendMessageToPC(GetFirstPC(), GetName(oItem)+" is equipped");
}
}
}
/*******************************************************************************
** This script removes ALL gold and inventory items (even non-Droppable and **
** Plot) from a newly-created oHostBody (as part of Resurrection spell). **
** Creature Slot items are not affected. **
*******************************************************************************/
void RemoveInventory(object oHostBody)
{
// Delete gold
TakeGoldFromCreature(GetGold(oHostBody), oHostBody, TRUE);
// Destroy equipped items
// 0=head, 1=chest, 2=boot, 3=arms, 4=rhand, 5=lhand, 6=cloak,
// 7=lring, 8=rring, 9=neck, 10=belt, 11=arrow, 12=bullet, 13=bolt
object oItem; int x;
for (x = 0; x < 14; x++)
{
oItem = GetItemInSlot(x, oHostBody);
if (GetIsObjectValid(oItem))
{
if (GetPlotFlag(oItem)) SetPlotFlag(oItem, FALSE);
DestroyObject(oItem);
}
}
// Delete items (including non-Droppable and Plot items)
oItem = GetFirstItemInInventory(oHostBody);
while (GetIsObjectValid(oItem))
{
if (GetPlotFlag(oItem)) SetPlotFlag(oItem, FALSE);
DestroyObject(oItem);
oItem = GetNextItemInInventory(oHostBody);
}
}
/*******************************************************************************
** Re-equip previously-equipped items on oHostBody if items were passed back **
** to oHostBody from oLootCorpse (assumes the items weren't looted from **
** oLootCorpse). This script only applies to oLootCorpse; bones don't have **
** local "oEquip" objects, so if bones are resurrected, the items don't get **
** re-equipped (NPCs with "naked" models will appear naked, which is as it **
** should be, since their corpse was too damaged to wear equipment anyway). **
*******************************************************************************/
void ReEquip(object oHostBody, object oLootCorpse)
{
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip1")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip1"), INVENTORY_SLOT_ARMS));
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip2")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip2"), INVENTORY_SLOT_ARROWS));
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip3")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip3"), INVENTORY_SLOT_BELT));
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip4")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip4"), INVENTORY_SLOT_BOLTS));
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip5")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip5"), INVENTORY_SLOT_BOOTS));
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip6")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip6"), INVENTORY_SLOT_BULLETS));
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip7")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip7"), INVENTORY_SLOT_CLOAK));
/*
Helmet (oEquip8) gets handled by "oOrigHelmet" code in ReturnInventory
(if nCopyArmour is TRUE), or gets re-equipped (if nMoveArmour is TRUE and
nCopyArmour is FALSE)
*/
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip8")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip8"), INVENTORY_SLOT_HEAD));
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip9")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip9"), INVENTORY_SLOT_LEFTRING));
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip10")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip10"), INVENTORY_SLOT_NECK));
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip11")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip11"), INVENTORY_SLOT_RIGHTRING));
/*
Weapons (oEquip12 & 13) stay dropped on the ground (if nDropWeapons is
TRUE, oEquip12 & 13 == OBJECT_INVALID), or get re-equipped (if
nMoveWeapons is TRUE and nDropWeapons is FALSE)
*/
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip12")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip12"), INVENTORY_SLOT_RIGHTHAND));
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip13")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip13"), INVENTORY_SLOT_LEFTHAND));
/*
Armour (oEquip14) gets handled by "oOrigArmour" code in ReturnInventory
(if nCopyArmour is TRUE), or gets re-equipped (if nMoveArmour is TRUE and
nCopyArmour is FALSE)
*/
if (GetItemPossessor(GetLocalObject(oLootCorpse, "oEquip14")) == oHostBody)
AssignCommand(oHostBody, ActionEquipItem(GetLocalObject(oLootCorpse, "oEquip14"), INVENTORY_SLOT_CHEST));
}
/*******************************************************************************
** This script returns gold and inventory items from oLootCorpse (or bones) **
** to oHostBody. Dropped, unclaimed weapons remain where they fell. **
** **
** NOTE: Even though one of the parameters is "oLootCorpse = OBJECT_SELF", **
** this script can also be called by bones! **
*******************************************************************************/
void ReturnInventory(object oHostBody, object oLootCorpse = OBJECT_SELF)
{
// Remember dropped weapon info
/*
Store oLeftWpn/oRightWpn on oHostBody, so that if the oHostBody is killed
again, dropped weapons info will be saved (see "_kb_loot_corpse").
*/
SetLocalObject(oHostBody, "oLeftWpn", GetLocalObject(OBJECT_SELF, "oLeftWpn"));
SetLocalObject(oHostBody, "oRightWpn", GetLocalObject(OBJECT_SELF, "oRightWpn"));
// Move gold to oHostBody
// (This was commented out because gold is moved as an inventory item below)
// (if you don't comment out this line, the creature's gold will double)
// AssignCommand(oLootCorpse, GiveGoldToCreature(oHostBody, GetGold(oLootCorpse)));
// Move inventory items to oHostBody
object oEquip = GetFirstItemInInventory(oLootCorpse);
while (GetIsObjectValid(oEquip))
{
// If oHostBody is still wearing oOrigArmor, and no one has removed
// oLootArmor from oLootCorpse, destroy oLootArmor/oEquip14 (no need to
// transfer it back to oHostBody, since oOrigArmor is still there)
// NOTE: This never applies to bones, since if bones exist, oHostBody
// and oOrigArmour were already destroyed, and oLootArmour was already
// transferred to the bones (oLootArmour/oOrigArmour == OBJECT_INVALID)
if ((oEquip == GetLocalObject(OBJECT_SELF, "oLootArmour")) &&
(GetIsObjectValid(GetLocalObject(OBJECT_SELF, "oOrigArmour"))))
DestroyObject(oEquip); // destroys oLootArmour/oEquip14
// Make a similar check for oLootHelmet/oEquip8 and oOrigHelmet
// (doesn't apply to bones either)
else if ((oEquip == GetLocalObject(OBJECT_SELF, "oLootHelmet")) &&
(GetIsObjectValid(GetLocalObject(OBJECT_SELF, "oOrigHelmet"))))
DestroyObject(oEquip); // destroys oLootHelmet/oEquip8
else
{
// This following line doesn't work
// (maybe because combat leads to ClearAllActions on oHostBody?)
// AssignCommand(oHostBody, ActionTakeItem(oEquip, oLootCorpse));
AssignCommand(oLootCorpse, ActionGiveItem(oEquip, oHostBody));
}
oEquip = GetNextItemInInventory(oLootCorpse);
}
/*
// Used for debugging
SendMessageToPC(GetFirstPC(), "MOVING INVENTORY...");
DetermineEquipOwner(oLootCorpse);
DelayCommand(0.5, SendMessageToPC(GetFirstPC(), "MOVE COMPLETE (hopefully)..."));
DelayCommand(0.5, DetermineEquipOwner(oLootCorpse));
*/
// Delay time might need to be increased for slower PC's or large inventories
DelayCommand(0.5, ReEquip(oHostBody, oLootCorpse));
// Used for debugging
// DelayCommand(0.7, VerifyEquipped(oHostBody));
DelayCommand(1.0, DestroyObject(OBJECT_SELF));
}
void main()
{
/* register with other scripts */
int bModDebug = GetLocalInt(GetModule(),"bModDebug");
if (!GetLocalInt(GetModule(),"kb_raise_res"))
{
if (bModDebug) SendMessageToPC(GetFirstPC(),"Registering _kb_raise_res ...");
SetLocalInt(GetModule(),"kb_raise_res",1);
}
/* exit if null object calling - probably registration */
if (OBJECT_SELF == OBJECT_INVALID) return;
/* run plugin code */
int nSpellCast = GetLastSpell();
//Get all of our required information
object oHostBody = GetLocalObject(OBJECT_SELF, "oHostBody"); // returns OBJECT_INVALID if script called by bones
string sHostBodyResRef = GetLocalString(OBJECT_SELF, "sHostBodyResRef");
object oCorpseBlood = GetLocalObject(OBJECT_SELF, "oBloodSpot"); // returns OBJECT_INVALID if script called by bones
// Spell failure effect (for later use)
effect eSpellFail = EffectVisualEffect(VFX_IMP_MAGIC_RESISTANCE_USE);
// Raise Dead and Resurrection won't work on Outsiders, Elementals,
// Constructs, Undead, or RACIAL_TYPE_INVALID
int nRacialType = GetLocalInt(OBJECT_SELF, "nRacialType");
if ((nRacialType == RACIAL_TYPE_OUTSIDER) ||
(nRacialType == RACIAL_TYPE_ELEMENTAL) ||
(nRacialType == RACIAL_TYPE_CONSTRUCT) ||
(nRacialType == RACIAL_TYPE_UNDEAD) ||
(nRacialType == RACIAL_TYPE_INVALID))
{
// Spell failure effect
ApplyEffectToObject(DURATION_TYPE_INSTANT, eSpellFail, OBJECT_SELF);
// Spell failure message
if (nSpellCast == SPELL_RAISE_DEAD)
{
SendMessageToPC(GetLastSpellCaster(), "This type of creature cannot be raised from the dead.");
}
if (nSpellCast == SPELL_RESURRECTION)
{
SendMessageToPC(GetLastSpellCaster(), "This type of creature cannot be resurrected.");
}
// KNOWN BUG: Spell or scroll is wasted in the attempt
return;
}
if (nSpellCast == SPELL_RAISE_DEAD)
{
// Raise Dead won't work on bones
if (GetTag(OBJECT_SELF) == "loot_bones_obj")
{
// Spell failure effect
ApplyEffectToObject(DURATION_TYPE_INSTANT, eSpellFail, OBJECT_SELF);
// Spell failure message
SendMessageToPC(GetLastSpellCaster(), "This corpse is too badly damaged to be raised from the dead.");
// KNOWN BUG: Spell or scroll is wasted in the attempt
return;
}
ActionCastSpellAtObject(nSpellCast, oHostBody, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
if (GetIsObjectValid(oCorpseBlood)) DestroyObject(oCorpseBlood);
ReturnInventory(oHostBody);
}
else if (nSpellCast == SPELL_RESURRECTION)
{
// Works on lootable corpse placeable or bones
if (!GetIsObjectValid(oHostBody))
{
// Resurrect oBones ("transforms" oBones into oHostBody by
// re-creating the creature using sHostBodyResRef)
oHostBody = CreateObject(OBJECT_TYPE_CREATURE, sHostBodyResRef, GetLocation(OBJECT_SELF), FALSE);
// delete all default gold/items from oHostBody
RemoveInventory(oHostBody);
// Resurrection visual and sound effect
effect eResVis = EffectVisualEffect(VFX_IMP_RAISE_DEAD);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eResVis, GetLocation(oHostBody));
PlaySound("sim_healdead");
}
else
{
// Resurrect oHostBody (lootable corpse placeable is OBJECT_SELF)
ActionCastSpellAtObject(nSpellCast, oHostBody, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
if (GetIsObjectValid(oCorpseBlood)) DestroyObject(oCorpseBlood);
}
ReturnInventory(oHostBody);
}
else return;
}

32
_module/nss/addkeen.nss Normal file
View File

@@ -0,0 +1,32 @@
#include "x2_inc_itemprop"
/* Script generated by
Lilac Soul's NWN Script Generator, v. 1.6
For download info, please visit:
http://www.lilacsoul.revility.com */
//Put this on action taken in the conversation editor
void main()
{
object oPC = GetPCSpeaker();
AssignCommand(oPC, TakeGoldFromCreature(10000, oPC, TRUE));
object oTarget;
object oItem;
oTarget = oPC;
oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
itemproperty ipAdd;
ipAdd = ItemPropertyKeen();
IPSafeAddItemProperty(oItem, ipAdd);
ActionMoveToObject(GetObjectByTag("anvil"));
ActionPlayAnimation(ANIMATION_FIREFORGET_STEAL);
}

16
_module/nss/attack_pc.nss Normal file
View File

@@ -0,0 +1,16 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
//Put this on action taken in the conversation editor
void main()
{
object oPC = GetPCSpeaker();
ActionAttack(oPC);
}

View File

@@ -0,0 +1,112 @@
//::///////////////////////////////////////////////
//:: Dying Script
//:: s_dying.NSS
//:://////////////////////////////////////////////
/*
This script handles the default behavior
that occurs when a character is dying. Dying
is when the character is between 0 and -9 hit
points; -10 and below is death. To use, redirect
the OnDying event script of the module to this script.
*/
//:://////////////////////////////////////////////
//:: Author : Scott Thorne
//:: E-mail : Thornex2@wans.net
//:: Updated: July 25, 2002
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Modifier : Peter Abdis
//:: E-mail : xantec@insightbb.com
//:: Updated: March 06, 2003
//:://////////////////////////////////////////////
void bleed(int iBleedAmt)
{
object oDying = GetLocalObject(OBJECT_SELF, "PCName");
int iDCC = GetLocalInt(oDying, "iPCDCC");
iDCC = iDCC + 1;
int iDC;
int iCon = GetAbilityModifier(ABILITY_CONSTITUTION,oDying);
int iDCBase = 16-iCon; /* Decrease/increase this value to lower/raise the base DC. */
iDC = iDCBase;
if(iDCC > iDCBase)
{
iDC = iDCC; /* This is used to decrease the PC's chance to stabilize
should they not stabilize after iDCBase turns.
Is really only effective when iDCBase < 10*/
}
effect eBleedEff;
/* keep executing recursively until character is dead or at +1 hit points */
if (GetCurrentHitPoints() <= 0)
{
/* a positive bleeding amount means damage, otherwise heal the character */
if (iBleedAmt > 0)
{
eBleedEff = EffectDamage(iBleedAmt);
}
else
{
eBleedEff = EffectHeal(-iBleedAmt); /* note the negative sign */
}
ApplyEffectToObject(DURATION_TYPE_INSTANT, eBleedEff, oDying);
/* -10 hit points is the death threshold, at or beyond it the character dies */
if (GetCurrentHitPoints() <= -10)
{
PlayVoiceChat(VOICE_CHAT_DEATH); /* scream one last time */
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_DEATH), OBJECT_SELF); /* make death dramatic */
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oDying); /* now kill them */
return;
}
if (iBleedAmt > 0) /* only check if character has not stablized */
{
int iConBonus = GetAbilityModifier(ABILITY_CONSTITUTION, oDying);
int iStableRoll = d20() + iConBonus;
if(iStableRoll >= iDC)
{
iBleedAmt = -iBleedAmt; /* reverse the bleeding process */
PlayVoiceChat(VOICE_CHAT_LAUGH); /* laugh at death -- this time */
SendMessageToPC(oDying, "You have stabilized and have begun to heal.");
}
else
{
SendMessageToPC(oDying, "You have failed to stabilize this round: DC is "+IntToString(iDCBase)+".");
switch (d6())
{
case 1: PlayVoiceChat(VOICE_CHAT_PAIN1); break;
case 2: PlayVoiceChat(VOICE_CHAT_PAIN2); break;
case 3: PlayVoiceChat(VOICE_CHAT_PAIN3); break;
case 4: PlayVoiceChat(VOICE_CHAT_HEALME); break;
case 5: PlayVoiceChat(VOICE_CHAT_NEARDEATH); break;
case 6: PlayVoiceChat(VOICE_CHAT_HELP);
}
}
}
if(GetCurrentHitPoints() <= 0)
{
SetLocalInt(oDying, "iPCDCC", iDC);
DelayCommand(6.0,bleed(iBleedAmt)); /* do this again next round */
}
}
}
void main()
{
object oDying = GetLastPlayerDying();
SetLocalObject(oDying, "PCName", oDying);
SetLocalInt(oDying, "iPCDCC", 0);
AssignCommand(oDying, ClearAllActions());
AssignCommand(oDying, bleed(1));
effect eEffect;
eEffect = EffectSanctuary(99);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, oDying, 12.0f);
}

24
_module/nss/book_cha.nss Normal file
View File

@@ -0,0 +1,24 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
void main()
{
object oPC;
oPC = GetItemActivator();
object oTarget;
oTarget = oPC;
effect eEffect;
eEffect = EffectAbilityIncrease(ABILITY_CHARISMA, d6(1));
eEffect = SupernaturalEffect(eEffect);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
}

24
_module/nss/book_int.nss Normal file
View File

@@ -0,0 +1,24 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
void main()
{
object oPC;
oPC = GetItemActivator();
object oTarget;
oTarget = oPC;
effect eEffect;
eEffect = EffectAbilityIncrease(ABILITY_INTELLIGENCE, d6(1));
eEffect = SupernaturalEffect(eEffect);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
}

24
_module/nss/book_wis.nss Normal file
View File

@@ -0,0 +1,24 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
void main()
{
object oPC;
oPC = GetItemActivator();
object oTarget;
oTarget = oPC;
effect eEffect;
eEffect = EffectAbilityIncrease(ABILITY_WISDOM, d6(1));
eEffect = SupernaturalEffect(eEffect);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
}

View File

@@ -0,0 +1,60 @@
//::///////////////////////////////////////////////
//:: RIDDLER CONVERSATION
//:: onConv riddler creature
//:://////////////////////////////////////////////
/*
first, check if we have a riddle. (unanswered)
if so, repeat it. (?)
if not, pick one. set answer/riddle number.
listen for answer. pattern 4115
*/
//:://////////////////////////////////////////////
//:: Created By: bloodsong
//:://////////////////////////////////////////////
void main()
{
object oSelf = OBJECT_SELF;
object oPC = GetLastSpeaker();
int nRiddle = GetLocalInt(oSelf, "RIDDLING");
string sRiddle = GetLocalString(oSelf, "RIDDLE");
string sAns1 = GetLocalString(oSelf, "K1");
string sAns2 = GetLocalString(oSelf, "K2");
string sAns3 = GetLocalString(oSelf, "K3");
string sAns4 = GetLocalString(oSelf, "K4");
string sGuess = GetMatchedSubstring(0); //-- i think??
SetLocalString(oSelf, "GUESS", sGuess);
//-- step one: check riddle status
if (nRiddle == 0)
{//-- no riddle selected.
ExecuteScript("riddler_q", oSelf); //-- this should stock our strings and such
SetLocalInt(oSelf, "RIDDLING", 1); //-- remember to zero this on a win case
sRiddle = GetLocalString(oSelf, "RIDDLE");
//-- turn on listen
SetListenPattern(oSelf, "**", 4115);
SetListening(oSelf, TRUE);
//-- ask the riddle
SpeakString(sRiddle);
return;
}
//-- else we have a riddle out
//-- step two: repeating the riddle.
if(GetListenPatternNumber() == -1)
{//-- this means they just clicked to talk? i hope
SpeakString(sRiddle);
return;
}
//-- step three: checking the K
ExecuteScript("riddler_g", oSelf);
ExecuteScript("prc_npc_conv", OBJECT_SELF);
}

View File

@@ -0,0 +1,21 @@
#include "inc_itemprop001"
void main()
{
object oPC = GetPCSpeaker();
object oItem = GetLocalObject(oPC, "MODIFY_ITEM");
itemproperty ip = GetNewProperty(oItem);
//Copy item and modify to get new value
if ( GetIsItemPropertyValid(ip))
{
object oCopy = CopyItem(oItem, OBJECT_SELF);
CustomAddProperty(oCopy, ip);
SetLocalObject(oPC, "MODIFY_COPY", oCopy);
}
else
SendMessageToPC(oPC, "ERROR: Invalid Property");
}

View File

@@ -0,0 +1,126 @@
#include "x2_inc_itemprop"
itemproperty GetNewProperty(object oItem)
{
object oPC = GetPCSpeaker();
string sProp = GetLocalString(oPC, "MODIFY_PROPERTY");
int iParam1 = GetLocalInt(oPC, "MODIFY_PARAM1");
int iParam2 = GetLocalInt(oPC, "MODIFY_PARAM2");
int iParam3 = GetLocalInt(oPC, "MODIFY_PARAM3");
if (iParam3 == -1)
iParam3 = 1;
itemproperty ip;
if ( sProp == "Ability Bonus")
ip = ItemPropertyAbilityBonus(iParam2, iParam3);
else if ( sProp == "AC Bonus")
ip = ItemPropertyACBonus(iParam3);
else if ( sProp == "Enhancement")
ip = ItemPropertyEnhancementBonus(iParam3);
else if ( sProp == "Bonus Feat")
ip = ItemPropertyBonusFeat(iParam3);
else if ( sProp == "Damage Bonus")
ip = ItemPropertyDamageBonus(iParam2, iParam3);
else if ( sProp == "Damage Immunity")
ip = ItemPropertyDamageImmunity(iParam2, iParam3);
else if ( sProp == "Damage Reduction")
ip = ItemPropertyDamageReduction(iParam2, iParam3);
else if ( sProp == "Damage Resistance")
ip = ItemPropertyDamageResistance(iParam2, iParam3);
else if ( sProp == "Darkvision")
ip = ItemPropertyDarkvision();
else if ( sProp == "Haste")
ip = ItemPropertyHaste();
else if ( sProp == "Holy Avenger")
ip = ItemPropertyHolyAvenger();
else if ( sProp == "Improved Magic Resistance")
ip = ItemPropertyBonusSpellResistance(iParam3);
else if ( sProp == "Improved Saving Throws")
ip = ItemPropertyBonusSavingThrow(iParam2, iParam3);
else if ( sProp == "Improved Saving Throws Vs")
ip = ItemPropertyBonusSavingThrowVsX(iParam2, iParam3);
else if ( sProp == "Light")
ip = ItemPropertyLight(iParam2, iParam3);
else if ( sProp == "Keen")
ip = ItemPropertyKeen();
else if ( sProp == "Massive Criticals")
ip = ItemPropertyMassiveCritical(iParam3);
else if ( sProp == "Mighty")
ip = ItemPropertyMaxRangeStrengthMod(iParam3);
else if ( sProp == "Miscellaneous Immunity")
ip = ItemPropertyImmunityMisc(iParam3);
else if ( sProp == "On Hit Properties")
ip = ItemPropertyOnHitProps(iParam1, iParam2, iParam3);
else if ( sProp == "Regeneration")
ip = ItemPropertyRegeneration(iParam3);
else if ( sProp == "Skill Bonus")
ip = ItemPropertySkillBonus(iParam2, iParam3);
else if ( sProp == "Attack Bonus")
ip = ItemPropertyAttackBonus(iParam3);
else if ( sProp == "Vampiric Regeneration")
ip = ItemPropertyVampiricRegeneration(iParam3);
else if ( sProp == "True Seeing")
ip = ItemPropertyTrueSeeing();
else if ( sProp == "Freedom of Movement")
ip = ItemPropertyFreeAction();
else if ( sProp == "Weight Reduction")
ip = ItemPropertyWeightReduction(iParam3);
else if ( sProp == "Arcane Spell Failure")
ip = ItemPropertyArcaneSpellFailure(iParam3);
else if ( sProp == "Unlimited Ammo")
ip = ItemPropertyUnlimitedAmmo(iParam3);
//start styzygy's add
else if ( sProp == "Improved Evasion")
ip = ItemPropertyImprovedEvasion();
else if ( sProp == "Cast Spell")
ip = ItemPropertyCastSpell(iParam1, iParam2);
//end styzygy's add
return ip;
}
//Add property ip to object oItem
void CustomAddProperty(object oItem, itemproperty ip)
{
//Find and remove existing property with same type as ip, then add ip
int iTyp = GetItemPropertyType(ip);
int iSubTyp = GetItemPropertySubType(ip);
//Loop through item properties looking for match
itemproperty ipLoop = GetFirstItemProperty(oItem);
int bFound = FALSE;
while ((! bFound) && GetIsItemPropertyValid(ipLoop))
{
int iTyp1 = GetItemPropertyType(ipLoop);
int iSubTyp1 = GetItemPropertySubType(ipLoop);
bFound = ((iTyp1 == iTyp) && ((iSubTyp == -1) || (iSubTyp1 == iSubTyp)));
if (! bFound)
ipLoop = GetNextItemProperty(oItem);
}
if (bFound)
RemoveItemProperty(oItem, ipLoop);
if (GetLocalInt(GetPCSpeaker(), "MODIFY_PARAM3") > -1)
AddItemProperty(DURATION_TYPE_PERMANENT, ip, oItem);
}
void main()
{
object oPC = GetPCSpeaker();
object oItem = GetLocalObject(oPC, "MODIFY_ITEM");
itemproperty ip = GetNewProperty(oItem);
//Copy item and modify to get new value
if ( GetIsItemPropertyValid(ip))
{
object oCopy = CopyItem(oItem, OBJECT_SELF);
CustomAddProperty(oCopy, ip);
SetLocalObject(oPC, "MODIFY_COPY", oCopy);
}
else
SendMessageToPC(oPC, "ERROR: Invalid Property");
}

View File

@@ -0,0 +1,28 @@
void main()
{
object oPC = GetPCSpeaker();
object oItem = GetLocalObject(oPC, "MODIFY_ITEM");
object oCopy = GetLocalObject(oPC, "MODIFY_COPY");
//Get values of original item and modified copy, then destroy copy
int iCurrentValue = GetGoldPieceValue(oItem);
int iNewValue = GetGoldPieceValue(oCopy);
DestroyObject(oCopy);
//Either amount to pay, refund or no change
int iValue = 0;
int iDiff = 0;
if (iNewValue > iCurrentValue)
{
iValue = iNewValue - iCurrentValue;
iDiff = 1; //iValue is amount to pay
}
else if (iNewValue < iCurrentValue)
{
iValue = iCurrentValue - iNewValue;
iDiff = 0; //iValue is refund
};
SetLocalInt(oPC, "MODIFY_VALUE", iValue);
SetLocalInt(oPC, "MODIFY_DIFF", iDiff);
SetCustomToken(101, IntToString(iValue));
}

View File

@@ -0,0 +1,13 @@
int StartingConditional()
{
object oPC = GetPCSpeaker();
int iDiff = GetLocalInt(oPC, "MODIFY_DIFF");
if (iDiff = 1)
{
int iValue = GetLocalInt(oPC, "MODIFY_VALUE");
int iGold = GetGold(oPC);
return( iGold < iValue);
}
else
return FALSE;
}

View File

@@ -0,0 +1,22 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
//Put this on action taken in the conversation editor
void main()
{
object oPC = GetPCSpeaker();
object oCaster;
oCaster = OBJECT_SELF;
object oTarget;
oTarget = oPC;
AssignCommand(oCaster, ActionCastSpellAtObject(SPELL_HEALING_CIRCLE, oTarget, METAMAGIC_ANY, TRUE, 10, PROJECTILE_PATH_TYPE_DEFAULT, TRUE));
}

View File

@@ -0,0 +1,15 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
int StartingConditional()
{
object oPC = GetPCSpeaker();
if (GetGold(oPC) < 10) return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,15 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
int StartingConditional()
{
object oPC = GetPCSpeaker();
if (GetGold(oPC) < 500) return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,15 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
int StartingConditional()
{
object oPC = GetPCSpeaker();
if (GetGold(oPC) < 5) return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,16 @@
//::///////////////////////////////////////////////
//:: FileName chk_has_persuade
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/18/2006 3:22:24 PM
//:://////////////////////////////////////////////
int StartingConditional()
{
// Inspect local variables
if(!(GetLocalInt(OBJECT_SELF, "hasblu") != 1))
return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,16 @@
//::///////////////////////////////////////////////
//:: FileName chk_has_persuade
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/18/2006 3:22:24 PM
//:://////////////////////////////////////////////
int StartingConditional()
{
// Inspect local variables
if(!(GetLocalInt(OBJECT_SELF, "hasint") != 1))
return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,16 @@
//::///////////////////////////////////////////////
//:: FileName chk_has_persuade
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/18/2006 3:22:24 PM
//:://////////////////////////////////////////////
int StartingConditional()
{
// Inspect local variables
if(!(GetLocalInt(OBJECT_SELF, "hasper") != 1))
return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,15 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
int StartingConditional()
{
object oPC = GetPCSpeaker();
if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC))!="cowhelm") return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,15 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
int StartingConditional()
{
object oPC = GetPCSpeaker();
if (GetAbilityScore(oPC, ABILITY_CHARISMA) < 16) return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,16 @@
//::///////////////////////////////////////////////
//:: FileName chk_is_chaotic
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/5/2006 8:33:23 PM
//:://////////////////////////////////////////////
int StartingConditional()
{
// Restrict based on the player's alignment
if(GetAlignmentLawChaos(GetPCSpeaker()) != ALIGNMENT_CHAOTIC)
return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,16 @@
//::///////////////////////////////////////////////
//:: FileName chk_is_evil
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/2/2006 11:14:03 PM
//:://////////////////////////////////////////////
int StartingConditional()
{
// Restrict based on the player's alignment
if(GetAlignmentGoodEvil(GetPCSpeaker()) != ALIGNMENT_EVIL)
return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,24 @@
//::///////////////////////////////////////////////
//:: FileName chk_is_orc
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/3/2006 2:37:03 AM
//:://////////////////////////////////////////////
#include "prc_inc_racial"
int StartingConditional()
{
object oPC = GetPCSpeaker();
int iRace = MyPRCGetRacialType(oPC);
if(iRace == RACIAL_TYPE_HALFORC)
return TRUE;
if(iRace == RACIAL_TYPE_ORC)
return TRUE;
return FALSE;
}

View File

@@ -0,0 +1,16 @@
//::///////////////////////////////////////////////
//:: FileName chk_isgoodor_nue
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/2/2006 5:34:46 PM
//:://////////////////////////////////////////////
int StartingConditional()
{
// Restrict based on the player's alignment
if(GetAlignmentGoodEvil(GetPCSpeaker()) == ALIGNMENT_EVIL)
return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,15 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
int StartingConditional()
{
object oPC = GetPCSpeaker();
if (GetItemPossessedBy(oPC, "mandrakeroot") == OBJECT_INVALID) return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,14 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
int StartingConditional()
{
object oPC = GetPCSpeaker();
if (GetLocalInt(OBJECT_SELF, "niceorc") != 1) return FALSE;
return TRUE;
}

16
_module/nss/chk_percy.nss Normal file
View File

@@ -0,0 +1,16 @@
//::///////////////////////////////////////////////
//:: FileName chk_percy
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/5/2006 9:23:31 PM
//:://////////////////////////////////////////////
int StartingConditional()
{
// Inspect local variables
if(!(GetLocalInt(OBJECT_SELF, "percy") != 1))
return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,30 @@
//::///////////////////////////////////////////////
//:: FileName chk_pointyears
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/3/2006 12:45:58 AM
//:://////////////////////////////////////////////
#include "prc_inc_racial"
int StartingConditional()
{
object oPC = GetPCSpeaker();
int iRace = MyPRCGetRacialType(oPC);
if(iRace == RACIAL_TYPE_ELF)
return TRUE;
if(iRace == RACIAL_TYPE_HALFELF)
return TRUE;
if(iRace == RACIAL_TYPE_HALFLING)
return TRUE;
if(iRace == RACIAL_TYPE_GNOME)
return TRUE;
return FALSE;
}

View File

@@ -0,0 +1,20 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
int StartingConditional()
{
object oPC = GetPCSpeaker();
int iMyrace = GetRacialType(OBJECT_SELF);
int iYerrace = GetRacialType(oPC);
int iMyclass = GetClassByPosition(1,OBJECT_SELF);
int iYerclass = GetClassByPosition(1,oPC);
if (iMyrace == iYerrace || iMyclass == iYerclass) return TRUE;
return FALSE;
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9000);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9001);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9002);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9003);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9004);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9005);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9006);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9007);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9008);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9009);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9010);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9011);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9012);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9013);
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
SetLocalInt(GetPCSpeaker(),"Token",9014);
}

View File

@@ -0,0 +1,41 @@
////////////////////////////////////////////////////////////////////////////////
// conversation action
////////////////////////////////////////////////////////////////////////////////
void main()
{
object oPC = GetPCSpeaker();
int nToken = GetLocalInt(oPC,"Token");
object oTownPortal = GetLocalObject(oPC,IntToString(nToken));
// oTownPortal is invalid when oPC has selected "Cancel" or
// has aborted the dialog (nToken == 0)
if (GetIsObjectValid(oTownPortal))
{
AssignCommand(oPC,JumpToObject(oTownPortal));
}
// delete local variables
int nTokenMax = GetLocalInt(oPC,"TokenMax");
int nTokenCounter;
for (nTokenCounter = 9000; nTokenCounter <= nTokenMax; nTokenCounter++)
{
DeleteLocalObject(oPC,IntToString(nTokenCounter));
}
DeleteLocalInt(oPC,"TokenMax");
DeleteLocalInt(oPC,"TokenCounter");
DeleteLocalInt(oPC,"Token");
if (nToken == 9000) // 9000 == portal from oPC == his own town portal
{
// destroy town portal
DestroyObject(oTownPortal,0.1);
DeleteLocalObject(oPC,"TownPortal");
if (nTokenMax == 9000)
{
DestroyObject(GetLocalObject(GetModule(),"TownPortal"),0.1);
DeleteLocalObject(GetModule(),"TownPortal");
}
}
}

View File

@@ -0,0 +1,8 @@
////////////////////////////////////////////////////////////////////////////////
// conversation condition
////////////////////////////////////////////////////////////////////////////////
int StartingConditional()
{
return (GetIsObjectValid(GetLocalObject(GetPCSpeaker(),"TownPortal")));
}

View File

@@ -0,0 +1,14 @@
////////////////////////////////////////////////////////////////////////////////
// conversation condition
////////////////////////////////////////////////////////////////////////////////
int StartingConditional()
{
object oPC = GetPCSpeaker();
int nTokenMax = GetLocalInt(oPC,"TokenMax");
int nTokenCounter = GetLocalInt(oPC,"TokenCounter");
SetLocalInt(oPC,"TokenCounter",++nTokenCounter);
return (nTokenCounter <= nTokenMax);
}

30
_module/nss/cook_meat.nss Normal file
View File

@@ -0,0 +1,30 @@
void main()
{
object oFire =OBJECT_SELF;
object oRaw = GetItemPossessedBy(oFire,"rawmeat");
object oPC = GetLastClosedBy();
string sName = GetName(oPC);
int iGood = d20(1);
if (oRaw != OBJECT_INVALID && iGood <= 18)
{
CreateItemOnObject("food",oFire);
DestroyObject(oRaw,0.0f);
FloatingTextStringOnCreature(sName+" has cooked some meat.",oPC,TRUE);
}
if (oRaw != OBJECT_INVALID && iGood == 19)
{
CreateItemOnObject("food_disease",oFire);
DestroyObject(oRaw,0.0f);
FloatingTextStringOnCreature(sName+" has cooked some meat.",oPC,TRUE);
}
if (oRaw != OBJECT_INVALID && iGood == 20)
{
CreateItemOnObject("food_poison",oFire);
DestroyObject(oRaw,0.0f);
FloatingTextStringOnCreature(sName+" has cooked some meat.",oPC,TRUE);
}
}

View File

@@ -0,0 +1,7 @@
void main()
{
location lHere = GetLocation(OBJECT_SELF);
object oStore = GetObjectByTag("gemstore");
if (oStore==OBJECT_INVALID)
CreateObject(OBJECT_TYPE_STORE,"gemstore",lHere);
}

View File

@@ -0,0 +1,7 @@
void main()
{
location lHere = GetLocation(OBJECT_SELF);
object oStore = GetObjectByTag("wandmerch");
if (oStore==OBJECT_INVALID)
CreateObject(OBJECT_TYPE_STORE,"wandmerch",lHere);
}

View File

@@ -0,0 +1,9 @@
void main()
{
location lHere = GetLocation(OBJECT_SELF);
int iOn = GetLocalInt(OBJECT_SELF,"CEP_L_AMION");
if (iOn == 0) return;
CreateObject(OBJECT_TYPE_CREATURE,"victim",lHere);
object oPC = GetLastDamager(OBJECT_SELF);
GiveXPToCreature(oPC,50);
}

13
_module/nss/did_bluff.nss Normal file
View File

@@ -0,0 +1,13 @@
//::///////////////////////////////////////////////
//:: FileName did_persuade
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/18/2006 3:24:05 PM
//:://////////////////////////////////////////////
void main()
{
// Set the variables
SetLocalInt(OBJECT_SELF, "hasblu", 1);
}

View File

@@ -0,0 +1,13 @@
//::///////////////////////////////////////////////
//:: FileName did_persuade
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/18/2006 3:24:05 PM
//:://////////////////////////////////////////////
void main()
{
// Set the variables
SetLocalInt(OBJECT_SELF, "hasint", 1);
}

View File

@@ -0,0 +1,13 @@
//::///////////////////////////////////////////////
//:: FileName did_persuade
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Script Wizard
//:: Created On: 2/18/2006 3:24:05 PM
//:://////////////////////////////////////////////
void main()
{
// Set the variables
SetLocalInt(OBJECT_SELF, "hasper", 1);
}

View File

@@ -0,0 +1,12 @@
void main()
{
object oPC = GetLastDisarmed();
int iTrapDC = GetTrapDisarmDC(OBJECT_SELF);
int iLevel = GetHitDice(oPC);
int iXP = (iTrapDC*5)-iLevel;
if (GetIsPC(oPC) == TRUE)
GiveXPToCreature(oPC,iXP);
}

44
_module/nss/door_bash.nss Normal file
View File

@@ -0,0 +1,44 @@
//:://////////////////////////////////////////////////////////////
//:: ModMan's Bashing Script.
//:: Created: 01/09/03
//:://////////////////////////////////////////////////////////////
//:: This script is placed in OnDamaged Event of a Door or Chest.
//:: When damaged there is roughly a 5% chance of destroying the
//:: weapon of whoever is damaging the object. Weapons with
//:: any kind of enhancements have a reduced chance of breaking.
//:: This encourages players to be more careful about bashing, or
//:: to carry extra, disposable weapons for such a purpose.
//:://////////////////////////////////////////////////////////////
void main()
{
object oPC = GetLastDamager(); // Who is hitting me?
object oPrimary = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
//int oWeaponType = GetBaseItemType (oPrimary);
// Roll to see if the weapon broke
int nBash = d100(2); // Range is 2 to 200, rough 1 in 20 chance of breakage
if (nBash <= 15)
{
DestroyObject(oPrimary);
SendMessageToPC(oPC, "You have broken your weapon trying to bash the object!");
}
string sLevel = IntToString(GetHitDice(oPC));
int nAlert = d100(1);
string sResref = "wm_" + sLevel;
object oWP = GetNearestObjectByTag("wmwp");
location lWP = GetLocation(oWP);
if (nAlert <= 2)
{
FloatingTextStringOnCreature("You are making a lot of noise.",oPC);
object oSpawn = CreateObject(OBJECT_TYPE_CREATURE,sResref,lWP);
AssignCommand(oSpawn,ActionAttack(oPC));
}
}

View File

@@ -0,0 +1,97 @@
void main()
{
object oPC = GetEnteringObject();
if (GetIsPC(oPC) != TRUE) return;
//:: Get own ID number
string sSelf = GetTag(OBJECT_SELF);
int iLength = GetStringLength(sSelf);
string sID;
int iChosen = 0;
switch (iLength)
{
case 6:
sID = GetStringRight(sSelf,1);
break;
case 7:
sID = GetStringRight(sSelf,2);
break;
case 8:
sID = GetStringRight(sSelf,3);
break;
}
//SendMessageToPC(oPC,"my area ID is "+sID);
int iMatch = GetLocalInt(OBJECT_SELF,"match"); //:: Current door's match
string sEntryDir = GetStringLeft(GetTag(OBJECT_SELF),1); //:: Current door's direction
string sExitDir;
//:: This inverts the directions
if (sEntryDir == "n")
sExitDir="s";
else if (sEntryDir == "s")
sExitDir="n";
else if (sEntryDir == "w")
sExitDir="e";
else if (sEntryDir == "e")
sExitDir="w";
//SendMessageToPC(oPC,"i should be on the "+sExitDir+" side of the map");
//:: Now determine if there is already a match
if (iMatch != 0) //:: Door already has a match, teleport PC
{
//SendMessageToPC(oPC,"door has a match");
string sTag = "area4_"+IntToString(iMatch);
object oArea = GetObjectByTag(sTag);
object oTarget = GetObjectByTag("wp4_"+IntToString(iMatch)+sExitDir);
location lTarget = GetLocation(oTarget);
float fFace = GetFacing(oPC);
AssignCommand(oPC,ActionJumpToLocation(lTarget));
AssignCommand(oPC,SetFacing(fFace));
iChosen = 1;
return;
}
int iRand = Random(41)+1; //:: Random # for area selection
string sTag = "area4_"+IntToString(iRand);
object oArea = GetObjectByTag(sTag);
int iUsed = GetLocalInt(oArea,"ispop");
float fFace = GetFacing(oPC);
while (iChosen == 0)//selecting new areas
{
iRand = Random(41)+1;
sTag = "area4_"+IntToString(iRand);
oArea = GetObjectByTag(sTag);
iUsed = GetLocalInt(oArea,"ispop");
if (iUsed == 0)
{
// SendMessageToPC(oPC,"unused area chosen");
object oTarget = GetObjectByTag("wp4_"+IntToString(iRand)+sExitDir);
location lTarget = GetLocation(oTarget);
AssignCommand(oPC,ActionJumpToLocation(lTarget));
AssignCommand(oPC,SetFacing(fFace));
SetLocalInt(oArea,"ispop",1);
object oDoor = GetObjectByTag(sExitDir+"door"+IntToString(iRand));
SetLocalInt(OBJECT_SELF,"match",iRand);
SetLocalInt(oDoor,"match",StringToInt(sID));
iChosen = 1;
break;
}
//choose new area and try again until successful or TMI error
}
}

47
_module/nss/drink.nss Normal file
View File

@@ -0,0 +1,47 @@
void main()
{
object oPC = GetItemActivator();
string sName = GetName(GetItemActivated());
int iThirsty = GetLocalInt(oPC,"drank");
int iDrinks = GetLocalInt(GetItemActivated(),"drinks");
int iFill = GetLocalInt(oPC,"refill");
if (iFill == 1)
{
if (sName == "Water Canteen")
{
SetLocalInt(GetItemActivated(),"drinks",3);
SendMessageToPC(oPC,sName+" is full.");
return;
}
if (sName == "Water Bottle")
{
SetLocalInt(GetItemActivated(),"drinks",1);
SendMessageToPC(oPC,sName+" is full.");
return;
}
}
if (iDrinks >= 1)
{
if (iThirsty <= 0)
{
SetLocalInt(oPC,"drank",1);
FloatingTextStringOnCreature("You drink from the "+ sName +" and are no longer thirsty.",oPC,TRUE);
SetLocalInt(GetItemActivated(),"drinks",iDrinks-1);
return;
}
if (iThirsty == 1)
{
FloatingTextStringOnCreature("You aren't thirsty, but you drink from the "+ sName +" anyway.",oPC,TRUE);
SetLocalInt(GetItemActivated(),"drinks",iDrinks-1);
return;
}
}
if (iDrinks == 0)
FloatingTextStringOnCreature("This "+ sName +" is empty.",oPC,TRUE);
return;
}

View File

@@ -0,0 +1,6 @@
void main()
{
object oAnything = GetFirstItemInInventory(OBJECT_SELF);
if ( oAnything == OBJECT_INVALID )
DestroyObject(OBJECT_SELF,0.0f);
}

View File

@@ -0,0 +1,24 @@
//Create a script called flavortext with the following code as it's content.
void main()
{
object oPC = GetEnteringObject();
if(GetIsPC(oPC) == TRUE) {
string sString = GetName(OBJECT_SELF);
string sVal = GetStringLeft(sString, 6);
string sVar = GetStringRight(sString, 6);
string sTest = GetLocalString(oPC, sVar);
if(sTest != sVal) {
//do once
SetLocalString(oPC, sVar, sVal);
//flavor text
FloatingTextStringOnCreature(sString, oPC, FALSE);
}
}
}
//Simply create a trigger. Put the flavor text you want displayed as the name of the trigger. (The triggers tag has nothing to do with this script). Then assign the [flavortext] script to the trigger's OnEnter script hook. This script will only work when PCs enter the trigger and it will display whatever the trigger's name text is, as floating text over the PC's head. This description will happen only once. This same script can be used in as many different flavor text triggers as you'd like.

View File

@@ -0,0 +1,51 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
void main()
{
object oPC;
oPC = GetItemActivator();
if (GetIsObjectValid(GetItemActivatedTarget())
){
SendMessageToPC(GetItemActivator(), "You want to light what on fire?");
return;}
object oWood = GetItemPossessedBy(oPC,"wood");
if (oWood != OBJECT_INVALID)
{
location lTarget;
lTarget = GetItemActivatedTargetLocation();
location lPC = GetLocation(oPC);
float fDistance = GetDistanceBetweenLocations(lPC,lTarget);
if (fDistance <= 2.0)
{
CreateObject(OBJECT_TYPE_PLACEABLE, "campfire", lTarget);
DestroyObject(oWood,0.0f);
}
else
{
SendMessageToPC(GetItemActivator(), "Too far away.");
return;
}
}
else
{
SendMessageToPC(GetItemActivator(), "You have no firewood.");
return;
}
}

18
_module/nss/follow_pc.nss Normal file
View File

@@ -0,0 +1,18 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
//Put this on action taken in the conversation editor
void main()
{
object oPC = GetPCSpeaker();
ClearAllActions();
ActionForceFollowObject(oPC);
}

17
_module/nss/food.nss Normal file
View File

@@ -0,0 +1,17 @@
void main()
{
object oPC = GetItemActivator();
string sName = GetName(GetItemActivated());
int iHungry = GetLocalInt(oPC,"ate");
if (iHungry <= 1)
{
SetLocalInt(oPC,"ate",1);
FloatingTextStringOnCreature("You eat the "+ sName +" and are full.",oPC,TRUE);
}
else if (iHungry == 1)
{
FloatingTextStringOnCreature("You aren't hungry, but you eat the "+ sName +" anyway.",oPC,TRUE);
}
}

View File

@@ -0,0 +1,21 @@
void main()
{
object oPC = GetItemActivator();
string sName = GetName(GetItemActivated());
int iHungry = GetLocalInt(oPC,"ate");
if (iHungry <= 1)
{
effect eEffect = EffectDisease(DISEASE_CACKLE_FEVER);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eEffect,oPC);
SetLocalInt(oPC,"ate",1);
FloatingTextStringOnCreature("You eat the "+ sName +" and feel very sick.",oPC,TRUE);
}
else if (iHungry == 1)
{
effect eEffect = EffectDisease(DISEASE_CACKLE_FEVER);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eEffect,oPC);
FloatingTextStringOnCreature("You aren't hungry, but you eat the "+ sName +" and feel very ill.",oPC,TRUE);
}
}

View File

@@ -0,0 +1,21 @@
void main()
{
object oPC = GetItemActivator();
string sName = GetName(GetItemActivated());
int iHungry = GetLocalInt(oPC,"ate");
if (iHungry <= 1)
{
effect eEffect = EffectPoison(POISON_BLACK_LOTUS_EXTRACT);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eEffect,oPC);
SetLocalInt(oPC,"ate",1);
FloatingTextStringOnCreature("You eat the "+ sName +" and feel very sick.",oPC,TRUE);
}
else if (iHungry == 1)
{
effect eEffect = EffectPoison(POISON_BLACK_LOTUS_EXTRACT);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eEffect,oPC);
FloatingTextStringOnCreature("You aren't hungry, but you eat the "+ sName +" and feel very ill.",oPC,TRUE);
}
}

View File

@@ -0,0 +1,12 @@
// This conditional determines if this henchman is currently
// not actively hired by anyone.
#include "x0_i0_henchman"
int StartingConditional()
{
if (!GetIsHired())
return TRUE;
return FALSE;
}

25
_module/nss/give_root.nss Normal file
View File

@@ -0,0 +1,25 @@
#include "nw_i0_tool"
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
//Put this on action taken in the conversation editor
void main()
{
object oPC = GetPCSpeaker();
object oItem;
oItem = GetItemPossessedBy(oPC, "mandrakeroot");
if (GetIsObjectValid(oItem))
DestroyObject(oItem);
RewardPartyXP(250, oPC, FALSE);
AdjustAlignment(oPC, ALIGNMENT_GOOD, 10);
}

View File

@@ -0,0 +1,22 @@
/* Script generated by
Lilac Soul's NWN Script Generator, v. 2.1
For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625 */
//Put this on action taken in the conversation editor
void main()
{
object oPC = GetPCSpeaker();
object oCaster;
oCaster = OBJECT_SELF;
object oTarget;
oTarget = oPC;
AssignCommand(oCaster, ActionCastSpellAtObject(SPELL_GREATER_RESTORATION, oTarget, METAMAGIC_ANY, TRUE, 12, PROJECTILE_PATH_TYPE_DEFAULT, TRUE));
}

View File

@@ -0,0 +1,7 @@
#include "x0_i0_henchman"
void main()
{
object oPC=GetPCSpeaker();
LevelUpXP1Henchman(oPC);
}

View File

@@ -0,0 +1,13 @@
// prc_onactivate,x2_mod_def_act
/////////////////////////////////////////////////////////////////////
//
// This script has been auto-generated by HakInstaller to call
// multiple handlers for the onactivateitem event.
//
/////////////////////////////////////////////////////////////////////
void main()
{
ExecuteScript("prc_onactivate", OBJECT_SELF);
ExecuteScript("x2_mod_def_act", OBJECT_SELF);
}

View File

@@ -0,0 +1,13 @@
// prc_onenter,on_mod_enter
/////////////////////////////////////////////////////////////////////
//
// This script has been auto-generated by HakInstaller to call
// multiple handlers for the oncliententer event.
//
/////////////////////////////////////////////////////////////////////
void main()
{
ExecuteScript("prc_onenter", OBJECT_SELF);
ExecuteScript("on_mod_enter", OBJECT_SELF);
}

View File

@@ -0,0 +1,13 @@
// prc_onmodload,x2_mod_def_load
/////////////////////////////////////////////////////////////////////
//
// This script has been auto-generated by HakInstaller to call
// multiple handlers for the onmoduleload event.
//
/////////////////////////////////////////////////////////////////////
void main()
{
ExecuteScript("prc_onmodload", OBJECT_SELF);
ExecuteScript("x2_mod_def_load", OBJECT_SELF);
}

View File

@@ -0,0 +1,13 @@
// prc_ondeath,on_pcdie
/////////////////////////////////////////////////////////////////////
//
// This script has been auto-generated by HakInstaller to call
// multiple handlers for the onplayerdeath event.
//
/////////////////////////////////////////////////////////////////////
void main()
{
ExecuteScript("prc_ondeath", OBJECT_SELF);
ExecuteScript("on_pcdie", OBJECT_SELF);
}

View File

@@ -0,0 +1,13 @@
// prc_ondying,bleeding_ondying
/////////////////////////////////////////////////////////////////////
//
// This script has been auto-generated by HakInstaller to call
// multiple handlers for the onplayerdying event.
//
/////////////////////////////////////////////////////////////////////
void main()
{
ExecuteScript("prc_ondying", OBJECT_SELF);
ExecuteScript("bleeding_ondying", OBJECT_SELF);
}

View File

@@ -0,0 +1,13 @@
// prc_equip,x2_mod_def_equ
/////////////////////////////////////////////////////////////////////
//
// This script has been auto-generated by HakInstaller to call
// multiple handlers for the onplayerequipitem event.
//
/////////////////////////////////////////////////////////////////////
void main()
{
ExecuteScript("prc_equip", OBJECT_SELF);
ExecuteScript("x2_mod_def_equ", OBJECT_SELF);
}

View File

@@ -0,0 +1,13 @@
// prc_onrespawn,on_pc_respawn
/////////////////////////////////////////////////////////////////////
//
// This script has been auto-generated by HakInstaller to call
// multiple handlers for the onplayerrespawn event.
//
/////////////////////////////////////////////////////////////////////
void main()
{
ExecuteScript("prc_onrespawn", OBJECT_SELF);
ExecuteScript("on_pc_respawn", OBJECT_SELF);
}

View File

@@ -0,0 +1,13 @@
// prc_rest,onrest
/////////////////////////////////////////////////////////////////////
//
// This script has been auto-generated by HakInstaller to call
// multiple handlers for the onplayerrest event.
//
/////////////////////////////////////////////////////////////////////
void main()
{
ExecuteScript("prc_rest", OBJECT_SELF);
ExecuteScript("onrest", OBJECT_SELF);
}

View File

@@ -0,0 +1,13 @@
// prc_unequip,x2_mod_def_unequ
/////////////////////////////////////////////////////////////////////
//
// This script has been auto-generated by HakInstaller to call
// multiple handlers for the onplayerunequipitem event.
//
/////////////////////////////////////////////////////////////////////
void main()
{
ExecuteScript("prc_unequip", OBJECT_SELF);
ExecuteScript("x2_mod_def_unequ", OBJECT_SELF);
}

View File

@@ -0,0 +1,25 @@
//:://////////////////////////////////////////////////
//:: X0_D1_HEN_HIRED
//:: Copyright (c) 2002 Floodgate Entertainment
//:://////////////////////////////////////////////////
/*
Handles the hiring of a henchman.
*/
//:://////////////////////////////////////////////////
//:: Created By: Naomi Novik
//:: Created On: 09/13/2002
//:://////////////////////////////////////////////////
#include "x0_i0_henchman"
void main()
{
object oPC = GetPCSpeaker();
//Ensure plot/immortal flags has been turned off
SetPlotFlag(OBJECT_SELF, FALSE);
SetImmortal(OBJECT_SELF, FALSE);
AddHenchman(oPC);
LevelUpXP1Henchman(oPC);
SetAssociateState(NW_ASC_RETRY_OPEN_LOCKS, FALSE);
}

View File

@@ -0,0 +1,122 @@
int isArmor(object oItem)
{
int iTyp = GetBaseItemType(oItem);
if (
(iTyp == BASE_ITEM_ARMOR ) ||
(iTyp == BASE_ITEM_LARGESHIELD ) ||
(iTyp == BASE_ITEM_SMALLSHIELD ) ||
(iTyp == BASE_ITEM_TOWERSHIELD )
) return TRUE;
else return FALSE;
}
int isWearable(object oItem)
{
int iTyp = GetBaseItemType(oItem);
if (
(iTyp == BASE_ITEM_HELMET ) ||
(iTyp == BASE_ITEM_BELT ) ||
(iTyp == BASE_ITEM_BOOTS ) ||
(iTyp == BASE_ITEM_BRACER ) ||
(iTyp == BASE_ITEM_CLOAK )||
(iTyp == BASE_ITEM_AMULET ) ||
(iTyp == BASE_ITEM_RING )
) return TRUE;
else return FALSE;
}
int isGauntlet(object oItem)
{
int iTyp = GetBaseItemType(oItem);
if (iTyp == BASE_ITEM_GLOVES )
return TRUE;
else return FALSE;
}
int isMelee(object oItem)
{
int iTyp = GetBaseItemType(oItem);
if (
(iTyp == BASE_ITEM_BASTARDSWORD ) ||
(iTyp == BASE_ITEM_BATTLEAXE ) ||
(iTyp == BASE_ITEM_CLUB ) ||
(iTyp == BASE_ITEM_DAGGER ) ||
(iTyp == BASE_ITEM_DIREMACE ) ||
(iTyp == BASE_ITEM_DOUBLEAXE ) ||
(iTyp == BASE_ITEM_DWARVENWARAXE ) ||
(iTyp == BASE_ITEM_GREATAXE ) ||
(iTyp == BASE_ITEM_GREATSWORD ) ||
(iTyp == BASE_ITEM_HALBERD ) ||
(iTyp == BASE_ITEM_HANDAXE ) ||
(iTyp == BASE_ITEM_HEAVYFLAIL ) ||
(iTyp == BASE_ITEM_KAMA ) ||
(iTyp == BASE_ITEM_KATANA ) ||
(iTyp == BASE_ITEM_KUKRI ) ||
(iTyp == BASE_ITEM_LIGHTFLAIL ) ||
(iTyp == BASE_ITEM_LIGHTHAMMER ) ||
(iTyp == BASE_ITEM_LIGHTMACE ) ||
(iTyp == BASE_ITEM_LONGSWORD ) ||
(iTyp == BASE_ITEM_MAGICSTAFF ) ||
(iTyp == BASE_ITEM_MORNINGSTAR ) ||
(iTyp == BASE_ITEM_QUARTERSTAFF ) ||
(iTyp == BASE_ITEM_RAPIER ) ||
(iTyp == BASE_ITEM_SCIMITAR ) ||
(iTyp == BASE_ITEM_SCYTHE ) ||
(iTyp == BASE_ITEM_SHORTSPEAR ) ||
(iTyp == BASE_ITEM_SHORTSWORD ) ||
(iTyp == BASE_ITEM_SICKLE ) ||
(iTyp == BASE_ITEM_TWOBLADEDSWORD ) ||
(iTyp == BASE_ITEM_WARHAMMER ) ||
(iTyp == BASE_ITEM_WHIP )
) return TRUE;
else return FALSE;
}
int isRanged(object oItem)
{
int iTyp = GetBaseItemType(oItem);
if (
(iTyp == BASE_ITEM_HEAVYCROSSBOW ) ||
(iTyp == BASE_ITEM_LIGHTCROSSBOW ) ||
(iTyp == BASE_ITEM_LONGBOW ) ||
(iTyp == BASE_ITEM_SHORTBOW ) ||
(iTyp == BASE_ITEM_SLING )
) return TRUE;
else return FALSE;
}
int isThrowing(object oItem)
{
int iTyp = GetBaseItemType(oItem);
if (
(iTyp == BASE_ITEM_DART ) ||
(iTyp == BASE_ITEM_SHURIKEN ) ||
(iTyp == BASE_ITEM_THROWINGAXE )
) return TRUE;
else return FALSE;
}
int isAmmunition(object oItem)
{
int iTyp = GetBaseItemType(oItem);
if (
(iTyp == BASE_ITEM_ARROW ) ||
(iTyp == BASE_ITEM_BOLT ) ||
(iTyp == BASE_ITEM_BULLET )
) return TRUE;
else return FALSE;
}
int isArcane(object oItem)
{
int iTyp = GetBaseItemType(oItem);
if (
(iTyp == BASE_ITEM_MAGICROD ) ||
(iTyp == BASE_ITEM_MAGICSTAFF ) ||
(iTyp == BASE_ITEM_MAGICWAND ) ||
(iTyp == BASE_ITEM_BLANK_WAND ) ||
(iTyp == BASE_ITEM_BLANK_SCROLL ) ||
(iTyp == BASE_ITEM_BLANK_POTION )
) return TRUE;
else return FALSE;
}

View File

@@ -0,0 +1,106 @@
#include "x2_inc_itemprop"
itemproperty GetNewProperty(object oItem)
{
object oPC = GetPCSpeaker();
string sProp = GetLocalString(oPC, "MODIFY_PROPERTY");
int iParam1 = GetLocalInt(oPC, "MODIFY_PARAM1");
int iParam2 = GetLocalInt(oPC, "MODIFY_PARAM2");
int iParam3 = GetLocalInt(oPC, "MODIFY_PARAM3");
if (iParam3 == -1)
iParam3 = 1;
itemproperty ip;
if ( sProp == "Ability Bonus")
ip = ItemPropertyAbilityBonus(iParam2, iParam3);
else if ( sProp == "AC Bonus")
ip = ItemPropertyACBonus(iParam3);
else if ( sProp == "Enhancement")
ip = ItemPropertyEnhancementBonus(iParam3);
else if ( sProp == "Bonus Feat")
ip = ItemPropertyBonusFeat(iParam3);
else if ( sProp == "Damage Bonus")
ip = ItemPropertyDamageBonus(iParam2, iParam3);
else if ( sProp == "Damage Immunity")
ip = ItemPropertyDamageImmunity(iParam2, iParam3);
else if ( sProp == "Damage Reduction")
ip = ItemPropertyDamageReduction(iParam2, iParam3);
else if ( sProp == "Damage Resistance")
ip = ItemPropertyDamageResistance(iParam2, iParam3);
else if ( sProp == "Darkvision")
ip = ItemPropertyDarkvision();
else if ( sProp == "Haste")
ip = ItemPropertyHaste();
else if ( sProp == "Holy Avenger")
ip = ItemPropertyHolyAvenger();
else if ( sProp == "Improved Magic Resistance")
ip = ItemPropertyBonusSpellResistance(iParam3);
else if ( sProp == "Improved Saving Throws")
ip = ItemPropertyBonusSavingThrow(iParam2, iParam3);
else if ( sProp == "Improved Saving Throws Vs")
ip = ItemPropertyBonusSavingThrowVsX(iParam2, iParam3);
else if ( sProp == "Light")
ip = ItemPropertyLight(iParam2, iParam3);
else if ( sProp == "Keen")
ip = ItemPropertyKeen();
else if ( sProp == "Massive Criticals")
ip = ItemPropertyMassiveCritical(iParam3);
else if ( sProp == "Mighty")
ip = ItemPropertyMaxRangeStrengthMod(iParam3);
else if ( sProp == "Miscellaneous Immunity")
ip = ItemPropertyImmunityMisc(iParam3);
else if ( sProp == "On Hit Properties")
ip = ItemPropertyOnHitProps(iParam1, iParam2, iParam3);
else if ( sProp == "Regeneration")
ip = ItemPropertyRegeneration(iParam3);
else if ( sProp == "Skill Bonus")
ip = ItemPropertySkillBonus(iParam2, iParam3);
else if ( sProp == "Attack Bonus")
ip = ItemPropertyAttackBonus(iParam3);
else if ( sProp == "Vampiric Regeneration")
ip = ItemPropertyVampiricRegeneration(iParam3);
else if ( sProp == "True Seeing")
ip = ItemPropertyTrueSeeing();
else if ( sProp == "Freedom of Movement")
ip = ItemPropertyFreeAction();
else if ( sProp == "Weight Reduction")
ip = ItemPropertyWeightReduction(iParam3);
else if ( sProp == "Arcane Spell Failure")
ip = ItemPropertyArcaneSpellFailure(iParam3);
else if ( sProp == "Unlimited Ammo")
ip = ItemPropertyUnlimitedAmmo(iParam3);
//start styzygy's add
else if ( sProp == "Improved Evasion")
ip = ItemPropertyImprovedEvasion();
else if ( sProp == "VisualEffect")
ip = ItemPropertyVisualEffect(iParam1);
//end styzygy's add
return ip;
}
//Add property ip to object oItem
void CustomAddProperty(object oItem, itemproperty ip)
{
//Find and remove existing property with same type as ip, then add ip
int iTyp = GetItemPropertyType(ip);
int iSubTyp = GetItemPropertySubType(ip);
//Loop through item properties looking for match
itemproperty ipLoop = GetFirstItemProperty(oItem);
int bFound = FALSE;
while ((! bFound) && GetIsItemPropertyValid(ipLoop))
{
int iTyp1 = GetItemPropertyType(ipLoop);
int iSubTyp1 = GetItemPropertySubType(ipLoop);
bFound = ((iTyp1 == iTyp) && ((iSubTyp == -1) || (iSubTyp1 == iSubTyp)));
if (! bFound)
ipLoop = GetNextItemProperty(oItem);
}
if (bFound)
RemoveItemProperty(oItem, ipLoop);
if (GetLocalInt(GetPCSpeaker(), "MODIFY_PARAM3") > -1)
AddItemProperty(DURATION_TYPE_PERMANENT, ip, oItem);
}

Some files were not shown because too many files have changed in this diff Show More