Added BESIE, MS Moneclature
Added BESIE, Markshire's Nomeclature & started initial setup for commoners in Baleas.
This commit is contained in:
78
_module/nss/ab_desctrig_fnf.nss
Normal file
78
_module/nss/ab_desctrig_fnf.nss
Normal file
@@ -0,0 +1,78 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/////////////// Created By ///////////////
|
||||
/////////////// Abaddon, Angel of the Abyss ///////////////
|
||||
/////////////// Contactabe via Bioware<72> ///////////////
|
||||
/////////////// Forums and Private Message ///////////////
|
||||
/////////////// Utilities: ///////////////
|
||||
/////////////// __Abaddon__ ///////////////
|
||||
/////////////// ///////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/////////////// All Scripts and Hakpak's are ///////////////
|
||||
/////////////// distibuted as is, with no ///////////////
|
||||
/////////////// warranty or responsibility ///////////////
|
||||
/////////////// undertaken by the author. ///////////////
|
||||
/////////////// Caveat Emptor! ///////////////
|
||||
/////////////// This is freeware, You may ///////////////
|
||||
/////////////// distribute it in its ORIGINAL ///////////////
|
||||
/////////////// form at will, if this script ///////////////
|
||||
/////////////// is used in any large projects such ///////////////
|
||||
/////////////// as a PW or story module, the author ///////////////
|
||||
/////////////// would like to be informed, merly as ///////////////
|
||||
/////////////// a curtosey and indicator of both ///////////////
|
||||
/////////////// applicability and success :) ///////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
////////////// Script Name: ab_DescTrig ///////////////
|
||||
////////////// File Name: Descriptive Triggers ///////////////
|
||||
////////////// Author(s): Abaddon ///////////////
|
||||
////////////// Galap ///////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Commentary/Introduction: //
|
||||
// ----------------------- //
|
||||
// Fire and forget trigger. Grabs the name of the trigger
|
||||
// its attatched to and displays it as floaty text on a PC
|
||||
// only one time.
|
||||
// Modified as per Nathraiben's suggestion so that individual tags are no longer
|
||||
// required on the trigers.
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
////////////// Function Headers ///////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
//Fires The name of the trigger at the entering PC*
|
||||
// uses an int to make only fire once.
|
||||
// Int is established on the PC
|
||||
// String Variance == GetTag(of the trigger) + Has Fired
|
||||
// *There is a GetIsPC check in this function.
|
||||
void ab_Trig_Description_FireOnceOnly();
|
||||
|
||||
void ab_Trig_Description_FireOnceOnly()
|
||||
{
|
||||
object oPC = GetEnteringObject();
|
||||
string sDesc = GetName(OBJECT_SELF);
|
||||
//Determine that the trigger hasnt fired for this PC before
|
||||
if (GetLocalInt(OBJECT_SELF, GetName(oPC) + "Has Fired") < 1)
|
||||
{
|
||||
//Determine that the PC is a valid object
|
||||
if (GetIsObjectValid(oPC))
|
||||
{
|
||||
//If conditional just to verify that it is a PC not a wandering NPC or something of that nature
|
||||
if (GetIsPC(oPC))
|
||||
{
|
||||
// I like floaty text :) soo much nicer and more in mood for a player
|
||||
FloatingTextStringOnCreature(sDesc, oPC, FALSE);
|
||||
//Set the Int so that it will no longer fire for the PC
|
||||
SetLocalInt(OBJECT_SELF, GetName(oPC) + "Has Fired", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void main()
|
||||
{
|
||||
ab_Trig_Description_FireOnceOnly();
|
||||
}
|
||||
|
74
_module/nss/ab_desctrig_mult.nss
Normal file
74
_module/nss/ab_desctrig_mult.nss
Normal file
@@ -0,0 +1,74 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/////////////// Created By ///////////////
|
||||
/////////////// Abaddon, Angel of the Abyss ///////////////
|
||||
/////////////// Contactabe via Bioware<72> ///////////////
|
||||
/////////////// Forums and Private Message ///////////////
|
||||
/////////////// Utilities: ///////////////
|
||||
/////////////// __Abaddon__ ///////////////
|
||||
/////////////// ///////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/////////////// All Scripts and Hakpak's are ///////////////
|
||||
/////////////// distibuted as is, with no ///////////////
|
||||
/////////////// warranty or responsibility ///////////////
|
||||
/////////////// undertaken by the author. ///////////////
|
||||
/////////////// Caveat Emptor! ///////////////
|
||||
/////////////// This is freeware, You may ///////////////
|
||||
/////////////// distribute it in its ORIGINAL ///////////////
|
||||
/////////////// form at will, if this script ///////////////
|
||||
/////////////// is used in any large projects such ///////////////
|
||||
/////////////// as a PW or story module, the author ///////////////
|
||||
/////////////// would like to be informed, merly as ///////////////
|
||||
/////////////// a curtosey and indicator of both ///////////////
|
||||
/////////////// applicability and success :) ///////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
////////////// Script Name: ab_DescTrig ///////////////
|
||||
////////////// File Name: Descriptive Triggers ///////////////
|
||||
////////////// Author(s): Abaddon ///////////////
|
||||
////////////// Galap ///////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Commentary/Introduction: //
|
||||
// ----------------------- //
|
||||
// Fire and forget trigger. Grabs the name of the trigger
|
||||
// its attatched to and displays it as floaty text on a PC
|
||||
// every time they activate the trigger.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
////////////// Function Headers ///////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
//Fires The name of the trigger at the entering PC*
|
||||
// uses an int to make only fire once.
|
||||
// Int is established on the PC
|
||||
// String Variance == GetTag(of the trigger) + Has Fired
|
||||
// *There is a GetIsPC check in this function.
|
||||
void ab_Trig_Description_FireOnceOnly();
|
||||
|
||||
void ab_Trig_Description_FireOnceOnly()
|
||||
{
|
||||
object oPC = GetEnteringObject();
|
||||
string sDesc = GetName(OBJECT_SELF);
|
||||
//Determine that the PC is a valid object
|
||||
if (GetIsObjectValid(oPC))
|
||||
{
|
||||
//If conditional just to verify that it is a PC not a wandering NPC or something of that nature
|
||||
if (GetIsPC(oPC))
|
||||
{
|
||||
// I like floaty text :) soo much nicer and more in mood for a player
|
||||
FloatingTextStringOnCreature(sDesc, oPC, FALSE);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void main()
|
||||
{
|
||||
ab_Trig_Description_FireOnceOnly();
|
||||
}
|
||||
|
7
_module/nss/autoclose_door.nss
Normal file
7
_module/nss/autoclose_door.nss
Normal file
@@ -0,0 +1,7 @@
|
||||
void main()
|
||||
{
|
||||
object oDoor = OBJECT_SELF;
|
||||
AssignCommand(oDoor, ActionWait(5.0f));
|
||||
AssignCommand(oDoor, ActionCloseDoor(oDoor));
|
||||
// AssignCommand(oDoor, ActionDoCommand(SetLocked(oDoor, TRUE)));
|
||||
}
|
78
_module/nss/commoner_creator.nss
Normal file
78
_module/nss/commoner_creator.nss
Normal file
@@ -0,0 +1,78 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_creator.nss
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Reads the various needed variables, creates
|
||||
a NPC and sends it to a random waypoint.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
object oArea = GetArea(OBJECT_SELF);
|
||||
object oFirstPlayerInArea = GetLocalObject(oArea, "oFirstPlayerInArea");
|
||||
|
||||
int nWeather = GetLocalInt(oArea, "nWeather");
|
||||
string sCommonerName = GetLocalString(oArea, "sCommonerName");
|
||||
string sResRefBody = GetLocalString(oArea, "sResRefBody");
|
||||
int nTypesOfCommoner = GetLocalInt(oArea, "nTypesOfCommoner");
|
||||
string sResRefClothing = GetLocalString(oArea, "sResRefClothing");
|
||||
int nTypesOfClothing = GetLocalInt(oArea, "nTypesOfClothing");
|
||||
int nClothingRandom = GetLocalInt(oArea, "nClothingRandom");
|
||||
int nCommonerCarry = GetLocalInt(oArea, "nCommonerCarry");
|
||||
int nCommonerTorchOnlyByNight = GetLocalInt(oArea, "nCommonerTorchOnlyByNight");
|
||||
int nCommonerTorch = GetLocalInt(oArea, "nCommonerTorch");
|
||||
int nWalkWayPoints = GetLocalInt(oArea, "nWalkWayPoints");
|
||||
int nDialogLines = GetLocalInt(oArea, "nDialogLines");
|
||||
int nWalkType = GetLocalInt(oArea, "nWalkType");
|
||||
int nRandom;
|
||||
string sZero;
|
||||
|
||||
sZero="00";
|
||||
nRandom = Random(nTypesOfCommoner)+1;
|
||||
if (nRandom>9) {sZero="0";}
|
||||
if (nRandom>99) {sZero="";}
|
||||
string sSpawn = sResRefBody + sZero + IntToString(nRandom);
|
||||
|
||||
object oStartWayPoint = GetNearestObjectByTag("NW_COMMONER_WALKTO", oFirstPlayerInArea, Random(nWalkWayPoints)+1);
|
||||
object oCommoner = CreateObject(OBJECT_TYPE_CREATURE, sSpawn, GetLocation(oStartWayPoint));
|
||||
object oWalkTarget = GetNearestObjectByTag("NW_COMMONER_WALKTO", oStartWayPoint, Random(nWalkWayPoints-1)+1);
|
||||
SetLocalObject(oCommoner, "oWalkTarget", oWalkTarget);
|
||||
|
||||
SetLocalInt(oCommoner, "ambience_dialog", Random(nDialogLines)+1);
|
||||
AssignCommand(oCommoner, ClearAllActions());
|
||||
if (GetName(oCommoner)==sCommonerName)
|
||||
{
|
||||
if (Random(100)+1 <= nClothingRandom)
|
||||
{
|
||||
sZero="00";
|
||||
nRandom = Random(nTypesOfClothing)+1;
|
||||
if (nRandom>9) {sZero="0";}
|
||||
if (nRandom>99) {sZero="";}
|
||||
object oClothing = CreateItemOnObject(sResRefClothing+sZero+IntToString(nRandom), oCommoner);
|
||||
AssignCommand(oCommoner, ActionEquipItem(oClothing, INVENTORY_SLOT_CHEST));
|
||||
}
|
||||
if (Random(100)+1 > nCommonerCarry)
|
||||
{
|
||||
DestroyObject(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCommoner));
|
||||
DestroyObject(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCommoner));
|
||||
}
|
||||
}
|
||||
|
||||
if (nCommonerTorchOnlyByNight==FALSE && Random(100)+1 <= nCommonerTorch)
|
||||
{
|
||||
object oTorch = CreateItemOnObject("NW_IT_TORCH001", oCommoner);
|
||||
AssignCommand(oCommoner, ActionEquipItem(oTorch, INVENTORY_SLOT_LEFTHAND));
|
||||
}
|
||||
else if (GetIsNight() && Random(100)+1 <= nCommonerTorch)
|
||||
{
|
||||
object oTorch = CreateItemOnObject("NW_IT_TORCH001", oCommoner);
|
||||
AssignCommand(oCommoner, ActionEquipItem(oTorch, INVENTORY_SLOT_LEFTHAND));
|
||||
}
|
||||
|
||||
AssignCommand(oCommoner, ActionForceMoveToObject(oWalkTarget, nWalkType, 0.4, 60.0));
|
||||
AssignCommand(oCommoner, ActionDoCommand(DestroyObject(OBJECT_SELF, 0.1)));
|
||||
}
|
18
_module/nss/commoner_dia_1.nss
Normal file
18
_module/nss/commoner_dia_1.nss
Normal file
@@ -0,0 +1,18 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_dia_X (X from 1 to 10)
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Check if dialog line is valid.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
if(!(GetLocalInt(OBJECT_SELF, "ambience_dialog") == 1))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
18
_module/nss/commoner_dia_10.nss
Normal file
18
_module/nss/commoner_dia_10.nss
Normal file
@@ -0,0 +1,18 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_dia_X (X from 1 to 10)
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Check if dialog line is valid.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
if(!(GetLocalInt(OBJECT_SELF, "ambience_dialog") == 10))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
18
_module/nss/commoner_dia_2.nss
Normal file
18
_module/nss/commoner_dia_2.nss
Normal file
@@ -0,0 +1,18 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_dia_X (X from 1 to 10)
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Check if dialog line is valid.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
if(!(GetLocalInt(OBJECT_SELF, "ambience_dialog") == 2))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
18
_module/nss/commoner_dia_3.nss
Normal file
18
_module/nss/commoner_dia_3.nss
Normal file
@@ -0,0 +1,18 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_dia_X (X from 1 to 10)
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Check if dialog line is valid.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
if(!(GetLocalInt(OBJECT_SELF, "ambience_dialog") == 3))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
18
_module/nss/commoner_dia_4.nss
Normal file
18
_module/nss/commoner_dia_4.nss
Normal file
@@ -0,0 +1,18 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_dia_X (X from 1 to 10)
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Check if dialog line is valid.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
if(!(GetLocalInt(OBJECT_SELF, "ambience_dialog") == 4))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
18
_module/nss/commoner_dia_5.nss
Normal file
18
_module/nss/commoner_dia_5.nss
Normal file
@@ -0,0 +1,18 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_dia_X (X from 1 to 10)
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Check if dialog line is valid.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
if(!(GetLocalInt(OBJECT_SELF, "ambience_dialog") == 5))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
18
_module/nss/commoner_dia_6.nss
Normal file
18
_module/nss/commoner_dia_6.nss
Normal file
@@ -0,0 +1,18 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_dia_X (X from 1 to 10)
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Check if dialog line is valid.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
if(!(GetLocalInt(OBJECT_SELF, "ambience_dialog") == 6))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
18
_module/nss/commoner_dia_7.nss
Normal file
18
_module/nss/commoner_dia_7.nss
Normal file
@@ -0,0 +1,18 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_dia_X (X from 1 to 10)
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Check if dialog line is valid.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
if(!(GetLocalInt(OBJECT_SELF, "ambience_dialog") == 7))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
18
_module/nss/commoner_dia_8.nss
Normal file
18
_module/nss/commoner_dia_8.nss
Normal file
@@ -0,0 +1,18 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_dia_X (X from 1 to 10)
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Check if dialog line is valid.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
if(!(GetLocalInt(OBJECT_SELF, "ambience_dialog") == 8))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
18
_module/nss/commoner_dia_9.nss
Normal file
18
_module/nss/commoner_dia_9.nss
Normal file
@@ -0,0 +1,18 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_dia_X (X from 1 to 10)
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Check if dialog line is valid.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
if(!(GetLocalInt(OBJECT_SELF, "ambience_dialog") == 9))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
190
_module/nss/commoner_main.nss
Normal file
190
_module/nss/commoner_main.nss
Normal file
@@ -0,0 +1,190 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_main.nss
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Main script for the commoner spawner. Enter
|
||||
the different parameters in the "Options"
|
||||
block below. See readme.txt for additional
|
||||
help.
|
||||
Use the "Custom" block to add script lines
|
||||
if you need to run some script in the area
|
||||
heartbeat yourself.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
object oArea = GetArea(OBJECT_SELF);
|
||||
if (GetLocalInt(oArea, "initialized")==0)
|
||||
{
|
||||
SetLocalInt(oArea, "initialized", 1);
|
||||
|
||||
//Options:
|
||||
//Required parameters
|
||||
int nWalkWayPoints = 3; //Number of waypoints in area
|
||||
string sCommonerName = "Commoner"; //Name of commoners (used to select which
|
||||
//spawned creatures can be randomized)
|
||||
string sResRefBody = "commoner_"; //ResRef-beginning of commoners in area
|
||||
int nTypesOfCommoner = 2; //Number of different commoners
|
||||
string sResRefClothing = "clothing_"; //ResRef-beginning of clothing
|
||||
int nTypesOfClothing = 2; //Number of different clothings
|
||||
int nDialogLines = 10; //Number of different one liner dialogs
|
||||
|
||||
//Commoner options
|
||||
int nCommonerMax = 10; //Maximum number of commoners spawned
|
||||
//(clear weather & day!)
|
||||
int nCommonerRain = 50; //Percentage when it's raining
|
||||
int nCommonerSnow = 20; //Percentage when it's snowing
|
||||
int nCommonerNight = 100; //Percentage by night
|
||||
int nCommonerTorchOnlyByNight = TRUE; //When to spawn with torch:
|
||||
//TRUE: only by night, FALSE: all day
|
||||
int nCommonerTorch = 50; //Percentage carrying a torch
|
||||
int nClothingRandom = 100; //Percentage with random selected clothing
|
||||
int nCommonerCarry = 50; //Percentage carrying something in hands
|
||||
//(this does not modify the torch chance!)
|
||||
|
||||
//Weather and movement options
|
||||
int nCommonerDayRun = FALSE; //Movement mode by day
|
||||
int nCommonerNightRun = FALSE; //Movement mode by night
|
||||
int nCommonerRainRun = TRUE; //Movement mode if weather = rain
|
||||
int nCommonerSnowRun = FALSE; //Movement mode if weather = snow
|
||||
|
||||
|
||||
//Initialization
|
||||
//Don't change anything in this block or the script package
|
||||
//won't function properly!
|
||||
SetLocalInt(oArea, "nWalkWayPoints", nWalkWayPoints);
|
||||
SetLocalString(oArea, "sCommonerName", sCommonerName);
|
||||
SetLocalString(oArea, "sResRefBody", sResRefBody);
|
||||
SetLocalInt(oArea, "nTypesOfCommoner", nTypesOfCommoner);
|
||||
SetLocalString(oArea, "sResRefClothing", sResRefClothing);
|
||||
SetLocalInt(oArea, "nTypesOfClothing", nTypesOfClothing);
|
||||
SetLocalInt(oArea, "nDialogLines", nDialogLines);
|
||||
|
||||
SetLocalInt(oArea, "nCommonerMax", nCommonerMax);
|
||||
SetLocalInt(oArea, "nCommonerRain", nCommonerRain);
|
||||
SetLocalInt(oArea, "nCommonerSnow", nCommonerSnow);
|
||||
SetLocalInt(oArea, "nCommonerNight", nCommonerNight);
|
||||
SetLocalInt(oArea, "nCommonerTorchOnlyByNight", nCommonerTorchOnlyByNight);
|
||||
SetLocalInt(oArea, "nCommonerTorch", nCommonerTorch);
|
||||
SetLocalInt(oArea, "nClothingRandom", nClothingRandom);
|
||||
SetLocalInt(oArea, "nCommonerCarry", nCommonerCarry);
|
||||
|
||||
SetLocalInt(oArea, "nCommonerDayRun", nCommonerDayRun);
|
||||
SetLocalInt(oArea, "nCommonerNightRun", nCommonerNightRun);
|
||||
SetLocalInt(oArea, "nCommonerRainRun", nCommonerRainRun);
|
||||
SetLocalInt(oArea, "nCommonerSnowRun", nCommonerSnowRun);
|
||||
|
||||
int nWeatherType = GetWeather(oArea);
|
||||
int nNewMovement;
|
||||
if (GetIsNight()) {nNewMovement = GetLocalInt(oArea, "nCommonerNightRun");}
|
||||
else {nNewMovement = GetLocalInt(oArea, "nCommonerDayRun");}
|
||||
|
||||
if ((nWeatherType == WEATHER_RAIN) && (GetLocalInt(oArea, "nCommonerRainRun") == TRUE))
|
||||
{nNewMovement = TRUE;}
|
||||
else if ((nWeatherType == WEATHER_SNOW) && (GetLocalInt(oArea, "nCommonerSnowRun") == TRUE))
|
||||
{nNewMovement = TRUE;}
|
||||
|
||||
SetLocalInt(oArea, "nWalkType", nNewMovement);
|
||||
}
|
||||
|
||||
|
||||
//Custom (insert own code here)
|
||||
|
||||
//Custom end
|
||||
|
||||
|
||||
//Check if any player is in area
|
||||
int i;
|
||||
object oPlayerInArea = OBJECT_INVALID;
|
||||
object oPC = GetFirstPC();
|
||||
while (GetIsObjectValid(oPC))
|
||||
{
|
||||
if (GetArea(OBJECT_SELF)==GetArea(oPC))
|
||||
{
|
||||
oPlayerInArea = oPC;
|
||||
SetLocalObject(oArea, "oFirstPlayerInArea", oPC);
|
||||
break;
|
||||
}
|
||||
else oPC = GetNextPC();
|
||||
}
|
||||
|
||||
//If any player is in area then execute the following script lines
|
||||
if (GetIsObjectValid(oPlayerInArea))
|
||||
{
|
||||
//Weatherblock
|
||||
int nWeatherType = GetWeather(oArea);
|
||||
|
||||
if (nWeatherType != GetLocalInt(oArea, "nWeather"))
|
||||
{
|
||||
int nNewMovement;
|
||||
if (GetIsNight()) {nNewMovement = GetLocalInt(oArea, "nCommonerNightRun");}
|
||||
else {nNewMovement = GetLocalInt(oArea, "nCommonerDayRun");}
|
||||
|
||||
if ((nWeatherType == WEATHER_RAIN) && (GetLocalInt(oArea, "nCommonerRainRun") == TRUE))
|
||||
{nNewMovement = TRUE;}
|
||||
else if ((nWeatherType == WEATHER_SNOW) && (GetLocalInt(oArea, "nCommonerSnowRun") == TRUE))
|
||||
{nNewMovement = TRUE;}
|
||||
|
||||
SetLocalInt(oArea, "nWeather", nWeatherType);
|
||||
SetLocalInt(oArea, "nWalkType", nNewMovement);
|
||||
|
||||
i=1;
|
||||
object oCommoner = GetNearestObjectByTag("NW_COMMONER", oPC,i);
|
||||
while (GetIsObjectValid(oCommoner))
|
||||
{
|
||||
AssignCommand(oCommoner, ExecuteScript("commoner_resume", oCommoner));
|
||||
i++;
|
||||
oCommoner = GetNearestObjectByTag("NW_COMMONER", oPC,i);
|
||||
}
|
||||
}
|
||||
|
||||
//Commonerblock
|
||||
int nCommonersToSpawn;
|
||||
int nMaximumToSpawn = GetLocalInt(oArea, "nCommonerMax");
|
||||
int nRainMultiplier = GetLocalInt(oArea, "nCommonerRain");
|
||||
int nSnowMultiplier = GetLocalInt(oArea, "nCommonerSnow");
|
||||
int nNightMultiplier = GetLocalInt(oArea, "nCommonerNight");
|
||||
|
||||
if (!GetIsNight()) nNightMultiplier = 100;
|
||||
|
||||
if (GetWeather(oArea)==WEATHER_RAIN)
|
||||
{
|
||||
nMaximumToSpawn = (nMaximumToSpawn * nRainMultiplier * nNightMultiplier + 5000)/10000;
|
||||
}
|
||||
else if (GetWeather(oArea)==WEATHER_SNOW)
|
||||
{
|
||||
nMaximumToSpawn = (nMaximumToSpawn * nSnowMultiplier * nNightMultiplier + 5000)/10000;
|
||||
}
|
||||
else
|
||||
{
|
||||
nMaximumToSpawn = (nMaximumToSpawn * nNightMultiplier + 50)/100;
|
||||
}
|
||||
|
||||
int nCommonersSpawned=0;
|
||||
object oCount = GetNearestObjectByTag("NW_COMMONER", oPlayerInArea);
|
||||
while (GetIsObjectValid(oCount))
|
||||
{
|
||||
nCommonersSpawned++;
|
||||
oCount = GetNearestObjectByTag("NW_COMMONER", oPlayerInArea, nCommonersSpawned+1);
|
||||
}
|
||||
|
||||
nCommonersToSpawn = nMaximumToSpawn - nCommonersSpawned;
|
||||
if (nCommonersToSpawn > 0)
|
||||
{
|
||||
int nSpawn = Random(nCommonersToSpawn+1);
|
||||
|
||||
int nSpawnInterval;
|
||||
if (nSpawn!=0) nSpawnInterval = 60 / nSpawn;
|
||||
|
||||
for (i=1; i <= nSpawn; i++)
|
||||
{
|
||||
float fSpawnDelay = IntToFloat(Random(nSpawnInterval))/10 + ((IntToFloat(nSpawnInterval)/10) * (i-1));
|
||||
DelayCommand(fSpawnDelay, ExecuteScript("commoner_creator", OBJECT_SELF));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
190
_module/nss/commoner_main_cb.nss
Normal file
190
_module/nss/commoner_main_cb.nss
Normal file
@@ -0,0 +1,190 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_main.nss
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Main script for the commoner spawner. Enter
|
||||
the different parameters in the "Options"
|
||||
block below. See readme.txt for additional
|
||||
help.
|
||||
Use the "Custom" block to add script lines
|
||||
if you need to run some script in the area
|
||||
heartbeat yourself.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
object oArea = GetArea(OBJECT_SELF);
|
||||
if (GetLocalInt(oArea, "initialized")==0)
|
||||
{
|
||||
SetLocalInt(oArea, "initialized", 1);
|
||||
|
||||
//Options:
|
||||
//Required parameters
|
||||
int nWalkWayPoints = 10; //Number of waypoints in area
|
||||
string sCommonerName = "Baleas Commoner"; //Name of commoners (used to select which
|
||||
//spawned creatures can be randomized)
|
||||
string sResRefBody = "npc_baleas"; //ResRef-beginning of commoners in area
|
||||
int nTypesOfCommoner = 11; //Number of different commoners
|
||||
string sResRefClothing = "baleas_cloth"; //ResRef-beginning of clothing
|
||||
int nTypesOfClothing = 10; //Number of different clothings
|
||||
int nDialogLines = 10; //Number of different one liner dialogs
|
||||
|
||||
//Commoner options
|
||||
int nCommonerMax = 16; //Maximum number of commoners spawned
|
||||
//(clear weather & day!)
|
||||
int nCommonerRain = 50; //Percentage when it's raining
|
||||
int nCommonerSnow = 20; //Percentage when it's snowing
|
||||
int nCommonerNight = 100; //Percentage by night
|
||||
int nCommonerTorchOnlyByNight = TRUE; //When to spawn with torch:
|
||||
//TRUE: only by night, FALSE: all day
|
||||
int nCommonerTorch = 50; //Percentage carrying a torch
|
||||
int nClothingRandom = 100; //Percentage with random selected clothing
|
||||
int nCommonerCarry = 50; //Percentage carrying something in hands
|
||||
//(this does not modify the torch chance!)
|
||||
|
||||
//Weather and movement options
|
||||
int nCommonerDayRun = FALSE; //Movement mode by day
|
||||
int nCommonerNightRun = FALSE; //Movement mode by night
|
||||
int nCommonerRainRun = TRUE; //Movement mode if weather = rain
|
||||
int nCommonerSnowRun = FALSE; //Movement mode if weather = snow
|
||||
|
||||
|
||||
//Initialization
|
||||
//Don't change anything in this block or the script package
|
||||
//won't function properly!
|
||||
SetLocalInt(oArea, "nWalkWayPoints", nWalkWayPoints);
|
||||
SetLocalString(oArea, "sCommonerName", sCommonerName);
|
||||
SetLocalString(oArea, "sResRefBody", sResRefBody);
|
||||
SetLocalInt(oArea, "nTypesOfCommoner", nTypesOfCommoner);
|
||||
SetLocalString(oArea, "sResRefClothing", sResRefClothing);
|
||||
SetLocalInt(oArea, "nTypesOfClothing", nTypesOfClothing);
|
||||
SetLocalInt(oArea, "nDialogLines", nDialogLines);
|
||||
|
||||
SetLocalInt(oArea, "nCommonerMax", nCommonerMax);
|
||||
SetLocalInt(oArea, "nCommonerRain", nCommonerRain);
|
||||
SetLocalInt(oArea, "nCommonerSnow", nCommonerSnow);
|
||||
SetLocalInt(oArea, "nCommonerNight", nCommonerNight);
|
||||
SetLocalInt(oArea, "nCommonerTorchOnlyByNight", nCommonerTorchOnlyByNight);
|
||||
SetLocalInt(oArea, "nCommonerTorch", nCommonerTorch);
|
||||
SetLocalInt(oArea, "nClothingRandom", nClothingRandom);
|
||||
SetLocalInt(oArea, "nCommonerCarry", nCommonerCarry);
|
||||
|
||||
SetLocalInt(oArea, "nCommonerDayRun", nCommonerDayRun);
|
||||
SetLocalInt(oArea, "nCommonerNightRun", nCommonerNightRun);
|
||||
SetLocalInt(oArea, "nCommonerRainRun", nCommonerRainRun);
|
||||
SetLocalInt(oArea, "nCommonerSnowRun", nCommonerSnowRun);
|
||||
|
||||
int nWeatherType = GetWeather(oArea);
|
||||
int nNewMovement;
|
||||
if (GetIsNight()) {nNewMovement = GetLocalInt(oArea, "nCommonerNightRun");}
|
||||
else {nNewMovement = GetLocalInt(oArea, "nCommonerDayRun");}
|
||||
|
||||
if ((nWeatherType == WEATHER_RAIN) && (GetLocalInt(oArea, "nCommonerRainRun") == TRUE))
|
||||
{nNewMovement = TRUE;}
|
||||
else if ((nWeatherType == WEATHER_SNOW) && (GetLocalInt(oArea, "nCommonerSnowRun") == TRUE))
|
||||
{nNewMovement = TRUE;}
|
||||
|
||||
SetLocalInt(oArea, "nWalkType", nNewMovement);
|
||||
}
|
||||
|
||||
|
||||
//Custom (insert own code here)
|
||||
|
||||
//Custom end
|
||||
|
||||
|
||||
//Check if any player is in area
|
||||
int i;
|
||||
object oPlayerInArea = OBJECT_INVALID;
|
||||
object oPC = GetFirstPC();
|
||||
while (GetIsObjectValid(oPC))
|
||||
{
|
||||
if (GetArea(OBJECT_SELF)==GetArea(oPC))
|
||||
{
|
||||
oPlayerInArea = oPC;
|
||||
SetLocalObject(oArea, "oFirstPlayerInArea", oPC);
|
||||
break;
|
||||
}
|
||||
else oPC = GetNextPC();
|
||||
}
|
||||
|
||||
//If any player is in area then execute the following script lines
|
||||
if (GetIsObjectValid(oPlayerInArea))
|
||||
{
|
||||
//Weatherblock
|
||||
int nWeatherType = GetWeather(oArea);
|
||||
|
||||
if (nWeatherType != GetLocalInt(oArea, "nWeather"))
|
||||
{
|
||||
int nNewMovement;
|
||||
if (GetIsNight()) {nNewMovement = GetLocalInt(oArea, "nCommonerNightRun");}
|
||||
else {nNewMovement = GetLocalInt(oArea, "nCommonerDayRun");}
|
||||
|
||||
if ((nWeatherType == WEATHER_RAIN) && (GetLocalInt(oArea, "nCommonerRainRun") == TRUE))
|
||||
{nNewMovement = TRUE;}
|
||||
else if ((nWeatherType == WEATHER_SNOW) && (GetLocalInt(oArea, "nCommonerSnowRun") == TRUE))
|
||||
{nNewMovement = TRUE;}
|
||||
|
||||
SetLocalInt(oArea, "nWeather", nWeatherType);
|
||||
SetLocalInt(oArea, "nWalkType", nNewMovement);
|
||||
|
||||
i=1;
|
||||
object oCommoner = GetNearestObjectByTag("NW_COMMONER", oPC,i);
|
||||
while (GetIsObjectValid(oCommoner))
|
||||
{
|
||||
AssignCommand(oCommoner, ExecuteScript("commoner_resume", oCommoner));
|
||||
i++;
|
||||
oCommoner = GetNearestObjectByTag("NW_COMMONER", oPC,i);
|
||||
}
|
||||
}
|
||||
|
||||
//Commonerblock
|
||||
int nCommonersToSpawn;
|
||||
int nMaximumToSpawn = GetLocalInt(oArea, "nCommonerMax");
|
||||
int nRainMultiplier = GetLocalInt(oArea, "nCommonerRain");
|
||||
int nSnowMultiplier = GetLocalInt(oArea, "nCommonerSnow");
|
||||
int nNightMultiplier = GetLocalInt(oArea, "nCommonerNight");
|
||||
|
||||
if (!GetIsNight()) nNightMultiplier = 100;
|
||||
|
||||
if (GetWeather(oArea)==WEATHER_RAIN)
|
||||
{
|
||||
nMaximumToSpawn = (nMaximumToSpawn * nRainMultiplier * nNightMultiplier + 5000)/10000;
|
||||
}
|
||||
else if (GetWeather(oArea)==WEATHER_SNOW)
|
||||
{
|
||||
nMaximumToSpawn = (nMaximumToSpawn * nSnowMultiplier * nNightMultiplier + 5000)/10000;
|
||||
}
|
||||
else
|
||||
{
|
||||
nMaximumToSpawn = (nMaximumToSpawn * nNightMultiplier + 50)/100;
|
||||
}
|
||||
|
||||
int nCommonersSpawned=0;
|
||||
object oCount = GetNearestObjectByTag("NW_COMMONER", oPlayerInArea);
|
||||
while (GetIsObjectValid(oCount))
|
||||
{
|
||||
nCommonersSpawned++;
|
||||
oCount = GetNearestObjectByTag("NW_COMMONER", oPlayerInArea, nCommonersSpawned+1);
|
||||
}
|
||||
|
||||
nCommonersToSpawn = nMaximumToSpawn - nCommonersSpawned;
|
||||
if (nCommonersToSpawn > 0)
|
||||
{
|
||||
int nSpawn = Random(nCommonersToSpawn+1);
|
||||
|
||||
int nSpawnInterval;
|
||||
if (nSpawn!=0) nSpawnInterval = 60 / nSpawn;
|
||||
|
||||
for (i=1; i <= nSpawn; i++)
|
||||
{
|
||||
float fSpawnDelay = IntToFloat(Random(nSpawnInterval))/10 + ((IntToFloat(nSpawnInterval)/10) * (i-1));
|
||||
DelayCommand(fSpawnDelay, ExecuteScript("commoner_creator", OBJECT_SELF));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
26
_module/nss/commoner_resume.nss
Normal file
26
_module/nss/commoner_resume.nss
Normal file
@@ -0,0 +1,26 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: commoner_resume
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Sends commoner to its destination waypoint after
|
||||
speaking its one liner.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: EntropyDecay
|
||||
//:: Created On: May 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
object oArea = GetArea(OBJECT_SELF);
|
||||
int nWalkType = GetLocalInt(oArea, "nWalkType");
|
||||
|
||||
AssignCommand(OBJECT_SELF, DelayCommand(0.1,ClearAllActions()));
|
||||
AssignCommand(OBJECT_SELF, DelayCommand(0.1,
|
||||
ActionForceMoveToObject(
|
||||
GetLocalObject(OBJECT_SELF, "oWalkTarget"),
|
||||
nWalkType, 0.4, 60.0)));
|
||||
AssignCommand(OBJECT_SELF,
|
||||
DelayCommand(0.1,
|
||||
ActionDoCommand(DestroyObject(OBJECT_SELF, 0.1))));
|
||||
}
|
106
_module/nss/commoner_spawn.nss
Normal file
106
_module/nss/commoner_spawn.nss
Normal file
@@ -0,0 +1,106 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Default: On Spawn In
|
||||
//:: NW_C2_DEFAULT9
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Determines the course of action to be taken
|
||||
after having just been spawned in
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Preston Watamaniuk
|
||||
//:: Created On: Oct 25, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "ms_name_inc"
|
||||
#include "NW_O2_CONINCLUDE"
|
||||
#include "NW_I0_GENERIC"
|
||||
|
||||
void main()
|
||||
{
|
||||
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
|
||||
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
|
||||
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
|
||||
// This causes the creature to say a special greeting in their conversation file
|
||||
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
|
||||
// greeting in order to designate it. As the creature is actually saying this to
|
||||
// himself, don't attach any player responses to the greeting.
|
||||
|
||||
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
|
||||
// This will set the listening pattern on the NPC to attack when allies call
|
||||
//SetSpawnInCondition(NW_FLAG_STEALTH);
|
||||
// If the NPC has stealth and they are a rogue go into stealth mode
|
||||
//SetSpawnInCondition(NW_FLAG_SEARCH);
|
||||
// If the NPC has Search go into Search Mode
|
||||
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
|
||||
// This will set the NPC to give a warning to non-enemies before attacking
|
||||
|
||||
//SetSpawnInCondition(NW_FLAG_SLEEP);
|
||||
//Creatures that spawn in during the night will be asleep.
|
||||
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
|
||||
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
|
||||
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
|
||||
//SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
|
||||
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
|
||||
//NOTE that these animations will play automatically for Encounter Creatures.
|
||||
|
||||
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
|
||||
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
|
||||
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
|
||||
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
|
||||
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
|
||||
|
||||
// CUSTOM USER DEFINED EVENTS
|
||||
/*
|
||||
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
|
||||
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
|
||||
events user 1000 - 1010
|
||||
*/
|
||||
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
|
||||
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
|
||||
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
|
||||
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
|
||||
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
|
||||
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
|
||||
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
|
||||
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
|
||||
|
||||
// DEFAULT GENERIC BEHAVIOR (DO NOT TOUCH) *****************************************************************************************
|
||||
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
|
||||
//WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
|
||||
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
|
||||
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
|
||||
// combat.
|
||||
|
||||
// Randomize appearance
|
||||
int nSkinColor;
|
||||
nSkinColor = Random(15);
|
||||
SetColor(OBJECT_SELF, COLOR_CHANNEL_SKIN, nSkinColor);
|
||||
|
||||
int nKeephead = GetLocalInt(OBJECT_SELF,"RA_KEEPHEAD");
|
||||
int nHeadNumber;
|
||||
nHeadNumber = Random(12)+1;
|
||||
if (nKeephead != 1)
|
||||
{
|
||||
SetCreatureBodyPart(CREATURE_PART_HEAD, nHeadNumber, OBJECT_SELF);
|
||||
}
|
||||
|
||||
int nHairColor;
|
||||
nHairColor = Random(15);
|
||||
SetColor(OBJECT_SELF, COLOR_CHANNEL_HAIR, nHairColor);
|
||||
|
||||
int nTattoo1;
|
||||
nTattoo1 = Random(15);
|
||||
SetColor(OBJECT_SELF, COLOR_CHANNEL_TATTOO_1, nTattoo1);
|
||||
|
||||
int nTattoo2;
|
||||
nTattoo2 = Random(15);
|
||||
SetColor(OBJECT_SELF, COLOR_CHANNEL_TATTOO_2, nTattoo2);
|
||||
|
||||
//Calls the Random Name Generator
|
||||
ms_Nomenclature(OBJECT_SELF);
|
||||
|
||||
//GenerateNPCTreasure(); //* Use this to create a small amount of treasure on the creature
|
||||
}
|
||||
|
||||
|
345
_module/nss/dmfi_activate.nss
Normal file
345
_module/nss/dmfi_activate.nss
Normal file
@@ -0,0 +1,345 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: DMFI - widget activation processor
|
||||
//:: dmfi_activate
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Functions to respond and process DMFI item activations.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: The DMFI Team
|
||||
//:: Created On:
|
||||
//:://////////////////////////////////////////////
|
||||
//:: 2008.05.25 tsunami282 - changes to invisible listeners to work with
|
||||
//:: OnPlayerChat methods.
|
||||
//:: 2008.07.10 tsunami282 - add Naming Wand to the exploder.
|
||||
//:: 2008.08.15 tsunami282 - move init logic to new include.
|
||||
|
||||
#include "dmfi_init_inc"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void dmw_CleanUp(object oMySpeaker)
|
||||
{
|
||||
int nCount;
|
||||
int nCache;
|
||||
DeleteLocalObject(oMySpeaker, "dmfi_univ_target");
|
||||
DeleteLocalLocation(oMySpeaker, "dmfi_univ_location");
|
||||
DeleteLocalObject(oMySpeaker, "dmw_item");
|
||||
DeleteLocalString(oMySpeaker, "dmw_repamt");
|
||||
DeleteLocalString(oMySpeaker, "dmw_repargs");
|
||||
nCache = GetLocalInt(oMySpeaker, "dmw_playercache");
|
||||
for(nCount = 1; nCount <= nCache; nCount++)
|
||||
{
|
||||
DeleteLocalObject(oMySpeaker, "dmw_playercache" + IntToString(nCount));
|
||||
}
|
||||
DeleteLocalInt(oMySpeaker, "dmw_playercache");
|
||||
nCache = GetLocalInt(oMySpeaker, "dmw_itemcache");
|
||||
for(nCount = 1; nCount <= nCache; nCount++)
|
||||
{
|
||||
DeleteLocalObject(oMySpeaker, "dmw_itemcache" + IntToString(nCount));
|
||||
}
|
||||
DeleteLocalInt(oMySpeaker, "dmw_itemcache");
|
||||
for(nCount = 1; nCount <= 10; nCount++)
|
||||
{
|
||||
DeleteLocalString(oMySpeaker, "dmw_dialog" + IntToString(nCount));
|
||||
DeleteLocalString(oMySpeaker, "dmw_function" + IntToString(nCount));
|
||||
DeleteLocalString(oMySpeaker, "dmw_params" + IntToString(nCount));
|
||||
}
|
||||
DeleteLocalString(oMySpeaker, "dmw_playerfunc");
|
||||
DeleteLocalInt(oMySpeaker, "dmw_started");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void main()
|
||||
{
|
||||
object oUser = OBJECT_SELF;
|
||||
object oItem = GetLocalObject(oUser, "dmfi_item");
|
||||
object oOther = GetLocalObject(oUser, "dmfi_target");
|
||||
location lLocation = GetLocalLocation(oUser, "dmfi_location");
|
||||
string sItemTag = GetTag(oItem);
|
||||
|
||||
// listening system initialization moved to new function
|
||||
dmfiInitialize(oUser);
|
||||
|
||||
dmw_CleanUp(oUser);
|
||||
|
||||
if (GetStringLeft(sItemTag,8) == "hlslang_")
|
||||
{
|
||||
// Remove voice stuff
|
||||
string ssLanguage = GetStringRight(sItemTag, GetStringLength(sItemTag) - 8);
|
||||
SetLocalInt(oUser, "hls_MyLanguage", StringToInt(ssLanguage));
|
||||
SetLocalString(oUser, "hls_MyLanguageName", GetName(oItem));
|
||||
DelayCommand(1.0f, FloatingTextStringOnCreature("You are speaking " + GetName(oItem) + ". Type [(what you want to say in brackets)]", oUser, FALSE));
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetStringLeft(sItemTag, 8) == "dmfi_pc_")
|
||||
{
|
||||
if (GetStringLeft(sItemTag, 12) == "dmfi_pc_rest")
|
||||
{
|
||||
CreateObject(OBJECT_TYPE_PLACEABLE, "dmfi_rest" + GetStringRight(sItemTag, 3), GetLocation(oUser));
|
||||
return;
|
||||
}
|
||||
if (sItemTag == "dmfi_pc_follow")
|
||||
{
|
||||
if (GetIsObjectValid(oOther))
|
||||
{
|
||||
FloatingTextStringOnCreature("Now following "+ GetName(oOther),oUser, FALSE);
|
||||
DelayCommand(2.0f, AssignCommand(oUser, ActionForceFollowObject(oOther, 2.0f)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
SetLocalObject(oUser, "dmfi_univ_target", oUser);
|
||||
SetLocalLocation(oUser, "dmfi_univ_location", lLocation);
|
||||
SetLocalString(oUser, "dmfi_univ_conv", GetStringRight(sItemTag, GetStringLength(sItemTag) - 5));
|
||||
AssignCommand(oUser, ClearAllActions());
|
||||
AssignCommand(oUser, ActionStartConversation(OBJECT_SELF, "dmfi_universal", TRUE));
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetStringLeft(sItemTag, 5) == "dmfi_")
|
||||
{
|
||||
int iPass = FALSE;
|
||||
|
||||
if (GetIsDM(oUser) || GetIsDMPossessed(oUser))
|
||||
iPass = TRUE;
|
||||
|
||||
if (!GetIsPC(oUser))
|
||||
iPass = TRUE;
|
||||
|
||||
if (!iPass)
|
||||
{
|
||||
FloatingTextStringOnCreature("You cannot use this item." ,oUser, FALSE);
|
||||
SendMessageToAllDMs(GetName(oUser)+ " is attempting to use a DM item.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sItemTag == "dmfi_exploder")
|
||||
{
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_afflict"))) CreateItemOnObject("dmfi_afflict", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_dicebag"))) CreateItemOnObject("dmfi_dicebag", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_pc_dicebag"))) CreateItemOnObject("dmfi_pc_dicebag", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_pc_follow"))) CreateItemOnObject("dmfi_pc_follow", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_pc_emote"))) CreateItemOnObject("dmfi_pc_emote", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_server"))) CreateItemOnObject("dmfi_server", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_emote"))) CreateItemOnObject("dmfi_emote", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_encounter"))) CreateItemOnObject("dmfi_encounte", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_faction"))) CreateItemOnObject("dmfi_faction", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_fx"))) CreateItemOnObject("dmfi_fx", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_music"))) CreateItemOnObject("dmfi_music", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_sound"))) CreateItemOnObject("dmfi_sound", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_voice"))) CreateItemOnObject("dmfi_voice", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_xp"))) CreateItemOnObject("dmfi_xp", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_500xp"))) CreateItemOnObject("dmfi_500xp", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_en_ditto"))) CreateItemOnObject("dmfi_en_ditto", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_mute"))) CreateItemOnObject("dmfi_mute", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_peace"))) CreateItemOnObject("dmfi_peace", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_voicewidget"))) CreateItemOnObject("dmfi_voicewidget", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_remove"))) CreateItemOnObject("dmfi_remove", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_dmw"))) CreateItemOnObject("dmfi_dmw", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_target"))) CreateItemOnObject("dmfi_target", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_buff"))) CreateItemOnObject("dmfi_buff", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_dmbook"))) CreateItemOnObject("dmfi_dmbook", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_playerbook"))) CreateItemOnObject("dmfi_playerbook", oOther);
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_jail_widget"))) CreateItemOnObject("dmfi_jail_widget", oOther);
|
||||
// 2008.07.10 tsunami282 - add naming wand to the exploder
|
||||
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_naming"))) CreateItemOnObject("dmfi_naming", oOther);
|
||||
return;
|
||||
}
|
||||
if (sItemTag == "dmfi_peace")
|
||||
{ //This widget sets all creatures in the area to a neutral stance and clears combat.
|
||||
object oArea = GetFirstObjectInArea(GetArea(oUser));
|
||||
object oP;
|
||||
while (GetIsObjectValid(oArea))
|
||||
{
|
||||
if (GetObjectType(oArea) == OBJECT_TYPE_CREATURE && !GetIsPC(oArea))
|
||||
{
|
||||
AssignCommand(oArea, ClearAllActions());
|
||||
oP = GetFirstPC();
|
||||
while (GetIsObjectValid(oP))
|
||||
{
|
||||
if (GetArea(oP) == GetArea(oUser))
|
||||
{
|
||||
ClearPersonalReputation(oArea, oP);
|
||||
SetStandardFactionReputation(STANDARD_FACTION_HOSTILE, 25, oP);
|
||||
SetStandardFactionReputation(STANDARD_FACTION_COMMONER, 91, oP);
|
||||
SetStandardFactionReputation(STANDARD_FACTION_MERCHANT, 91, oP);
|
||||
SetStandardFactionReputation(STANDARD_FACTION_DEFENDER, 91, oP);
|
||||
}
|
||||
oP = GetNextPC();
|
||||
}
|
||||
AssignCommand(oArea, ClearAllActions());
|
||||
}
|
||||
oArea = GetNextObjectInArea(GetArea(oUser));
|
||||
}
|
||||
}
|
||||
|
||||
// update / remove invisible listeners as needed for onplayerchat
|
||||
if (sItemTag == "dmfi_voicewidget")
|
||||
{
|
||||
object oVoice;
|
||||
if (GetIsObjectValid(oOther)) // do we have a valid target creature?
|
||||
{
|
||||
// 2008.05.29 tsunami282 - we don't use creature listen stuff anymore
|
||||
SetLocalObject(oUser, "dmfi_VoiceTarget", oOther);
|
||||
|
||||
FloatingTextStringOnCreature("You have targeted " + GetName(oOther) + " with the Voice Widget", oUser, FALSE);
|
||||
|
||||
if (GetLocalInt(GetModule(), "dmfi_voice_initial")!=1)
|
||||
{
|
||||
SetLocalInt(GetModule(), "dmfi_voice_initial", 1);
|
||||
SendMessageToAllDMs("Listening Initialized: .commands, .skill checks, and much more now available.");
|
||||
DelayCommand(4.0, FloatingTextStringOnCreature("Listening Initialized: .commands, .skill checks, and more available", oUser));
|
||||
}
|
||||
return;
|
||||
}
|
||||
else // no valid target of voice wand
|
||||
{
|
||||
//Jump any existing Voice attached to the user
|
||||
if (GetIsObjectValid(GetLocalObject(oUser, "dmfi_StaticVoice")))
|
||||
{
|
||||
DestroyObject(GetLocalObject(oUser, "dmfi_StaticVoice"));
|
||||
}
|
||||
//Create the StationaryVoice
|
||||
object oStaticVoice = CreateObject(OBJECT_TYPE_CREATURE, "dmfi_voice", GetLocation(oUser));
|
||||
//Set Ownership of the Voice to the User
|
||||
SetLocalObject(oUser, "dmfi_StaticVoice", oVoice);
|
||||
SetLocalObject(oUser, "dmfi_VoiceTarget", oStaticVoice);
|
||||
DelayCommand(1.0f, FloatingTextStringOnCreature("A Stationary Voice has been created.", oUser, FALSE));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (sItemTag == "dmfi_mute")
|
||||
{
|
||||
SetLocalObject(oUser, "dmfi_univ_target", oUser);
|
||||
SetLocalString(oUser, "dmfi_univ_conv", "voice");
|
||||
SetLocalInt(oUser, "dmfi_univ_int", 8);
|
||||
ExecuteScript("dmfi_execute", oUser);
|
||||
return;
|
||||
}
|
||||
//encounter ditto widget
|
||||
if (sItemTag == "dmfi_en_ditto")
|
||||
{
|
||||
SetLocalObject(oUser, "dmfi_univ_target", oOther);
|
||||
SetLocalLocation(oUser, "dmfi_univ_location", lLocation);
|
||||
SetLocalString(oUser, "dmfi_univ_conv", "encounter");
|
||||
SetLocalInt(oUser, "dmfi_univ_int", GetLocalInt(oUser, "EncounterType"));
|
||||
ExecuteScript("dmfi_execute", oUser);
|
||||
return;
|
||||
}
|
||||
//Change target widget
|
||||
if (sItemTag == "dmfi_target")
|
||||
{
|
||||
SetLocalObject(oUser, "dmfi_univ_target", oOther);
|
||||
FloatingTextStringOnCreature("DMFI Target set to " + GetName(oOther),oUser);
|
||||
}
|
||||
//Destroy object widget
|
||||
if (sItemTag == "dmfi_remove")
|
||||
{
|
||||
object oKillMe;
|
||||
//Targeting Self
|
||||
if (oUser == oOther)
|
||||
{
|
||||
oKillMe = GetNearestObject(OBJECT_TYPE_PLACEABLE, oUser);
|
||||
FloatingTextStringOnCreature("Destroyed " + GetName(oKillMe) + "(" + GetTag(oKillMe) + ")", oUser, FALSE);
|
||||
DelayCommand(0.1f, DestroyObject(oKillMe));
|
||||
}
|
||||
else if (GetIsObjectValid(oOther)) //Targeting something else
|
||||
{
|
||||
FloatingTextStringOnCreature("Destroyed " + GetName(oOther) + "(" + GetTag(oOther) + ")", oUser, FALSE);
|
||||
DelayCommand(0.1f, DestroyObject(oOther));
|
||||
}
|
||||
else //Targeting the ground
|
||||
{
|
||||
int iReport = 0;
|
||||
oKillMe = GetFirstObjectInShape(SHAPE_SPHERE, 2.0f, lLocation, FALSE, OBJECT_TYPE_ALL);
|
||||
while (GetIsObjectValid(oKillMe))
|
||||
{
|
||||
iReport++;
|
||||
DestroyObject(oKillMe);
|
||||
oKillMe = GetNextObjectInShape(SHAPE_SPHERE, 2.0f, lLocation, FALSE, OBJECT_TYPE_ALL);
|
||||
}
|
||||
FloatingTextStringOnCreature("Destroyed " + IntToString(iReport) + " objects.", oUser, FALSE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (sItemTag == "dmfi_500xp")
|
||||
{
|
||||
SetLocalObject(oUser, "dmfi_univ_target", oOther);
|
||||
SetLocalLocation(oUser, "dmfi_univ_location", lLocation);
|
||||
SetLocalString(oUser, "dmfi_univ_conv", "xp");
|
||||
SetLocalInt(oUser, "dmfi_univ_int", 53);
|
||||
ExecuteScript("dmfi_execute", oUser);
|
||||
return;
|
||||
}
|
||||
if (sItemTag == "dmfi_jail_widget")
|
||||
{
|
||||
if (GetIsObjectValid(oOther) && !GetIsDM(oOther) && oOther != oUser)
|
||||
{
|
||||
object oJail = GetObjectByTag("dmfi_jail");
|
||||
if (!GetIsObjectValid(oJail))
|
||||
oJail = GetObjectByTag("dmfi_jail_default");
|
||||
AssignCommand(oOther, ClearAllActions());
|
||||
AssignCommand(oOther, JumpToObject(oJail));
|
||||
SendMessageToPC(oUser, GetName(oOther) + " (" + GetPCPublicCDKey(oOther) + ")/IP: " + GetPCIPAddress(oOther) + " - has been sent to Jail.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (sItemTag == "dmfi_encounter")
|
||||
{
|
||||
|
||||
if (GetIsObjectValid(GetWaypointByTag("DMFI_E1")))
|
||||
SetCustomToken(20771, GetName(GetWaypointByTag("DMFI_E1")));
|
||||
else
|
||||
SetCustomToken(20771, "Encounter Invalid");
|
||||
if (GetIsObjectValid(GetWaypointByTag("DMFI_E2")))
|
||||
SetCustomToken(20772, GetName(GetWaypointByTag("DMFI_E2")));
|
||||
else
|
||||
SetCustomToken(20772, "Encounter Invalid");
|
||||
if (GetIsObjectValid(GetWaypointByTag("DMFI_E3")))
|
||||
SetCustomToken(20773, GetName(GetWaypointByTag("DMFI_E3")));
|
||||
else
|
||||
SetCustomToken(20773, "Encounter Invalid");
|
||||
if (GetIsObjectValid(GetWaypointByTag("DMFI_E4")))
|
||||
SetCustomToken(20774, GetName(GetWaypointByTag("DMFI_E4")));
|
||||
else
|
||||
SetCustomToken(20774, "Encounter Invalid");
|
||||
if (GetIsObjectValid(GetWaypointByTag("DMFI_E5")))
|
||||
SetCustomToken(20775, GetName(GetWaypointByTag("DMFI_E5")));
|
||||
else
|
||||
SetCustomToken(20775, "Encounter Invalid");
|
||||
if (GetIsObjectValid(GetWaypointByTag("DMFI_E6")))
|
||||
SetCustomToken(20776, GetName(GetWaypointByTag("DMFI_E6")));
|
||||
else
|
||||
SetCustomToken(20776, "Encounter Invalid");
|
||||
if (GetIsObjectValid(GetWaypointByTag("DMFI_E7")))
|
||||
SetCustomToken(20777, GetName(GetWaypointByTag("DMFI_E7")));
|
||||
else
|
||||
SetCustomToken(20777, "Encounter Invalid");
|
||||
if (GetIsObjectValid(GetWaypointByTag("DMFI_E8")))
|
||||
SetCustomToken(20778, GetName(GetWaypointByTag("DMFI_E8")));
|
||||
else
|
||||
SetCustomToken(20778, "Encounter Invalid");
|
||||
if (GetIsObjectValid(GetWaypointByTag("DMFI_E9")))
|
||||
SetCustomToken(20779, GetName(GetWaypointByTag("DMFI_E9")));
|
||||
else
|
||||
SetCustomToken(20779, "Encounter Invalid");
|
||||
}
|
||||
if (sItemTag == "dmfi_afflict")
|
||||
{
|
||||
int nDNum;
|
||||
|
||||
nDNum = GetLocalInt(oUser, "dmfi_damagemodifier");
|
||||
SetCustomToken(20780, IntToString(nDNum));
|
||||
}
|
||||
|
||||
|
||||
SetLocalObject(oUser, "dmfi_univ_target", oOther);
|
||||
SetLocalLocation(oUser, "dmfi_univ_location", lLocation);
|
||||
SetLocalString(oUser, "dmfi_univ_conv", GetStringRight(sItemTag, GetStringLength(sItemTag) - 5));
|
||||
AssignCommand(oUser, ClearAllActions());
|
||||
AssignCommand(oUser, ActionStartConversation(OBJECT_SELF, "dmfi_universal", TRUE, FALSE));
|
||||
}
|
||||
}
|
||||
|
177
_module/nss/dmfi_arrays_inc.nss
Normal file
177
_module/nss/dmfi_arrays_inc.nss
Normal file
@@ -0,0 +1,177 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: DMFI - array functions include
|
||||
//:: dmfi_arrays_inc
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Functions to use object-attached local variables as arrays.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Noel
|
||||
//:: Created On: November 17, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
//:: 2007.12.24 tsunami282 - yanked most of these routines from Bioware's
|
||||
//:: nw_o0_itemmaker, then expanded for bounds management.
|
||||
|
||||
int GetLocalArrayLowerBound(object oidObject, string sVarName);
|
||||
int GetLocalArrayUpperBound(object oidObject, string sVarName);
|
||||
void SetLocalArrayLowerBound(object oidObject, string sVarName, int nMin);
|
||||
void SetLocalArrayUpperBound(object oidObject, string sVarName, int nMax);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
int GetLocalArrayInitialized(object oidObject, string sVarName)
|
||||
{
|
||||
string sFullVarName = sVarName + "_INIT";
|
||||
return GetLocalInt(oidObject, sFullVarName);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void InitializeLocalArray(object oidObject, string sVarName)
|
||||
{
|
||||
int i, iBegin, iEnd;
|
||||
string sFullVarName;
|
||||
|
||||
if (GetLocalArrayInitialized(oidObject, sVarName))
|
||||
{
|
||||
// wipe current contents
|
||||
iBegin = GetLocalArrayLowerBound(oidObject, sVarName);
|
||||
iEnd = GetLocalArrayUpperBound(oidObject, sVarName);
|
||||
for (i = iEnd; i >= iBegin; i--)
|
||||
{
|
||||
sFullVarName = sVarName + IntToString(i);
|
||||
DeleteLocalInt(oidObject, sFullVarName);
|
||||
DeleteLocalFloat(oidObject, sFullVarName);
|
||||
DeleteLocalString(oidObject, sFullVarName);
|
||||
DeleteLocalObject(oidObject, sFullVarName);
|
||||
DeleteLocalLocation(oidObject, sFullVarName);
|
||||
}
|
||||
}
|
||||
|
||||
SetLocalArrayLowerBound(oidObject, sVarName, 0);
|
||||
SetLocalArrayUpperBound(oidObject, sVarName, -1);
|
||||
sFullVarName = sVarName + "_INIT";
|
||||
SetLocalInt(oidObject, sFullVarName, TRUE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
int GetLocalArrayLowerBound(object oidObject, string sVarName)
|
||||
{
|
||||
string sFullVarName = sVarName + "_MIN";
|
||||
return GetLocalInt(oidObject, sFullVarName);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
int GetLocalArrayUpperBound(object oidObject, string sVarName)
|
||||
{
|
||||
string sFullVarName = sVarName + "_MAX";
|
||||
return GetLocalInt(oidObject, sFullVarName);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void SetLocalArrayLowerBound(object oidObject, string sVarName, int nMin)
|
||||
{
|
||||
string sFullVarName = sVarName + "_MIN";
|
||||
SetLocalInt(oidObject, sFullVarName, nMin);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void SetLocalArrayUpperBound(object oidObject, string sVarName, int nMax)
|
||||
{
|
||||
string sFullVarName = sVarName + "_MAX";
|
||||
SetLocalInt(oidObject, sFullVarName, nMax);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
int GetLocalArrayInt(object oidObject, string sVarName, int nVarNum)
|
||||
{
|
||||
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||
return GetLocalInt(oidObject, sFullVarName);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void SetLocalArrayInt(object oidObject, string sVarName, int nVarNum, int nValue)
|
||||
{
|
||||
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||
SetLocalInt(oidObject, sFullVarName, nValue);
|
||||
// update bounds
|
||||
if (nVarNum < GetLocalArrayLowerBound(oidObject, sVarName))
|
||||
SetLocalArrayLowerBound(oidObject, sVarName, nVarNum);
|
||||
if (nVarNum > GetLocalArrayUpperBound(oidObject, sVarName))
|
||||
SetLocalArrayUpperBound(oidObject, sVarName, nVarNum);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
float GetLocalArrayFloat(object oidObject, string sVarName, int nVarNum)
|
||||
{
|
||||
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||
return GetLocalFloat(oidObject, sFullVarName);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void SetLocalArrayFloat(object oidObject, string sVarName, int nVarNum, float fValue)
|
||||
{
|
||||
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||
SetLocalFloat(oidObject, sFullVarName, fValue);
|
||||
// update bounds
|
||||
if (nVarNum < GetLocalArrayLowerBound(oidObject, sVarName))
|
||||
SetLocalArrayLowerBound(oidObject, sVarName, nVarNum);
|
||||
if (nVarNum > GetLocalArrayUpperBound(oidObject, sVarName))
|
||||
SetLocalArrayUpperBound(oidObject, sVarName, nVarNum);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
string GetLocalArrayString(object oidObject, string sVarName, int nVarNum)
|
||||
{
|
||||
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||
return GetLocalString(oidObject, sFullVarName);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void SetLocalArrayString(object oidObject, string sVarName, int nVarNum, string nValue)
|
||||
{
|
||||
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||
SetLocalString(oidObject, sFullVarName, nValue);
|
||||
// update bounds
|
||||
if (nVarNum < GetLocalArrayLowerBound(oidObject, sVarName))
|
||||
SetLocalArrayLowerBound(oidObject, sVarName, nVarNum);
|
||||
if (nVarNum > GetLocalArrayUpperBound(oidObject, sVarName))
|
||||
SetLocalArrayUpperBound(oidObject, sVarName, nVarNum);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
object GetLocalArrayObject(object oidObject, string sVarName, int nVarNum)
|
||||
{
|
||||
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||
return GetLocalObject(oidObject, sFullVarName);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void SetLocalArrayObject(object oidObject, string sVarName, int nVarNum, object oidValue)
|
||||
{
|
||||
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||
SetLocalObject(oidObject, sFullVarName, oidValue);
|
||||
// update bounds
|
||||
if (nVarNum < GetLocalArrayLowerBound(oidObject, sVarName))
|
||||
SetLocalArrayLowerBound(oidObject, sVarName, nVarNum);
|
||||
if (nVarNum > GetLocalArrayUpperBound(oidObject, sVarName))
|
||||
SetLocalArrayUpperBound(oidObject, sVarName, nVarNum);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
location GetLocalArrayLocation(object oidObject, string sVarName, int nVarNum)
|
||||
{
|
||||
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||
return GetLocalLocation(oidObject, sFullVarName);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void SetLocalArrayLocation(object oidObject, string sVarName, int nVarNum, location locValue)
|
||||
{
|
||||
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||
SetLocalLocation(oidObject, sFullVarName, locValue);
|
||||
// update bounds
|
||||
if (nVarNum < GetLocalArrayLowerBound(oidObject, sVarName))
|
||||
SetLocalArrayLowerBound(oidObject, sVarName, nVarNum);
|
||||
if (nVarNum > GetLocalArrayUpperBound(oidObject, sVarName))
|
||||
SetLocalArrayUpperBound(oidObject, sVarName, nVarNum);
|
||||
}
|
||||
|
22
_module/nss/dmfi_cond_dmw.nss
Normal file
22
_module/nss/dmfi_cond_dmw.nss
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
int nMyNum = GetLocalInt(OBJECT_SELF, "dmfi_dmwOffset");
|
||||
SetLocalInt(OBJECT_SELF, "dmfi_dmwOffset", nMyNum+1);
|
||||
|
||||
object oMySpeaker = GetPCSpeaker();
|
||||
object oMyTarget = GetLocalObject(oMySpeaker, "dmfi_univ_target");
|
||||
location lMyLoc = GetLocalLocation(oMySpeaker, "dmfi_univ_location");
|
||||
|
||||
string sMyString = GetLocalString(oMySpeaker, "dmw_dialog" + IntToString(nMyNum));
|
||||
|
||||
if(sMyString == "")
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCustomToken(8000 + nMyNum, sMyString);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
64
_module/nss/dmfi_db_biow_inc.nss
Normal file
64
_module/nss/dmfi_db_biow_inc.nss
Normal file
@@ -0,0 +1,64 @@
|
||||
//DMFI Persistence wrapper functions
|
||||
//This include file contains the wrapper functions for the
|
||||
//persistent settings of the DMFI Wand and Widget package
|
||||
//Advanced users can adapt this to the database system that
|
||||
//they want to use for NWN.
|
||||
//
|
||||
//These functions use the Bioware database by default and use a primitive form
|
||||
//of "caching" to avoid lots of database R/W
|
||||
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: The DMFI Team
|
||||
//:: Created On:
|
||||
//:://////////////////////////////////////////////
|
||||
//:: 2008.07.10 tsunami282 - implemented alternate database support, initially
|
||||
//:: for Knat's NBDE
|
||||
|
||||
|
||||
const int DMFI_DB_TYPE =DMFI_DB_TYPE_BIOWARE;
|
||||
|
||||
void FlushDMFIPersistentData(string sDBName)
|
||||
{
|
||||
// no flushing required for Bioware database
|
||||
}
|
||||
|
||||
int IsDMFIPersistentDataDirty(string sDBName)
|
||||
{
|
||||
return FALSE; // bioware database system has no cache, so is never dirty
|
||||
}
|
||||
|
||||
//Int functions
|
||||
int GetDMFIPersistentInt(string sDBName, string sDBSetting, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
int iReturn = GetCampaignInt(sDBName, sDBSetting, oPlayer);
|
||||
return iReturn;
|
||||
}
|
||||
|
||||
void SetDMFIPersistentInt(string sDBName, string sDBSetting, int iDBValue, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
SetCampaignInt(sDBName, sDBSetting, iDBValue, oPlayer);
|
||||
}
|
||||
|
||||
//Float functions
|
||||
float GetDMFIPersistentFloat(string sDBName, string sDBSetting, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
float fReturn = GetCampaignFloat(sDBName, sDBSetting, oPlayer);
|
||||
return fReturn;
|
||||
}
|
||||
|
||||
void SetDMFIPersistentFloat(string sDBName, string sDBSetting, float fDBValue, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
SetCampaignFloat(sDBName, sDBSetting, fDBValue, oPlayer);
|
||||
}
|
||||
|
||||
//String functions
|
||||
string GetDMFIPersistentString(string sDBName, string sDBSetting, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
string sReturn = GetCampaignString(sDBName, sDBSetting, oPlayer);
|
||||
return sReturn;
|
||||
}
|
||||
|
||||
void SetDMFIPersistentString(string sDBName, string sDBSetting, string sDBValue, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
SetCampaignString(sDBName, sDBSetting, sDBValue, oPlayer);
|
||||
}
|
39
_module/nss/dmfi_db_inc.nss
Normal file
39
_module/nss/dmfi_db_inc.nss
Normal file
@@ -0,0 +1,39 @@
|
||||
//DMFI Persistence wrapper functions
|
||||
//This include file contains the wrapper functions for the
|
||||
//persistent settings of the DMFI Wand and Widget package
|
||||
//Advanced users can adapt this to the database system that
|
||||
//they want to use for NWN.
|
||||
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: The DMFI Team
|
||||
//:: Created On:
|
||||
//:://////////////////////////////////////////////
|
||||
//:: 2008.07.10 tsunami282 - implemented alternate database support, initially
|
||||
//:: for Knat's NBDE
|
||||
|
||||
//Listen Pattern ** variable
|
||||
//Change this to 0 to make the DMFI W&W more compatible with Jasperre's AI
|
||||
const int LISTEN_PATTERN = 20600;
|
||||
|
||||
const int DMFI_DB_TYPE_BIOWARE = 1;
|
||||
const int DMFI_DB_TYPE_NBDE = 2;
|
||||
const int DMFI_DB_TYPE_RESERVED_3 = 3;
|
||||
const int DMFI_DB_TYPE_RESERVED_4 = 4;
|
||||
const int DMFI_DB_TYPE_RESERVED_5 = 5;
|
||||
const int DMFI_DB_TYPE_RESERVED_6 = 6;
|
||||
const int DMFI_DB_TYPE_RESERVED_7 = 7;
|
||||
const int DMFI_DB_TYPE_RESERVED_8 = 8;
|
||||
const int DMFI_DB_TYPE_RESERVED_9 = 9;
|
||||
const int DMFI_DB_TYPE_RESERVED_10 = 10;
|
||||
|
||||
// *** DATABASE SELECTION ***
|
||||
// Only choose one of the following #include lines. Comment out all the others!
|
||||
|
||||
// Standard version uses the default Bioware database
|
||||
#include "dmfi_db_biow_inc"
|
||||
|
||||
// Alternate version: using Knat's NBDE
|
||||
// This provides greatly increased speed, but necessitates occasional flushing to disk.
|
||||
// Flushing requires you to add code to Your module OnHeartbeat event.
|
||||
// #include "dmfi_db_nbde_inc"
|
||||
|
65
_module/nss/dmfi_db_nbde_inc.nss
Normal file
65
_module/nss/dmfi_db_nbde_inc.nss
Normal file
@@ -0,0 +1,65 @@
|
||||
//DMFI Persistence wrapper functions
|
||||
// modified version for Knat's NBDE support
|
||||
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: The DMFI Team
|
||||
//:: Created On:
|
||||
//:://////////////////////////////////////////////
|
||||
//:: 2008.07.10 tsunami282 - implemented alternate database support, initially
|
||||
//:: for Knat's NBDE
|
||||
|
||||
|
||||
const int DMFI_DB_TYPE = DMFI_DB_TYPE_NBDE;
|
||||
|
||||
#include "nbde_inc"
|
||||
|
||||
void FlushDMFIPersistentData(string sDBName)
|
||||
{
|
||||
NBDE_SetCampaignInt(sDBName, "DMFI_DB_DIRTY", FALSE);
|
||||
NBDE_FlushCampaignDatabase(sDBName);
|
||||
}
|
||||
|
||||
int IsDMFIPersistentDataDirty(string sDBName)
|
||||
{
|
||||
return NBDE_GetCampaignInt(sDBName, "DMFI_DB_DIRTY");
|
||||
}
|
||||
|
||||
//Int functions
|
||||
int GetDMFIPersistentInt(string sDBName, string sDBSetting, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
int iReturn = NBDE_GetCampaignInt(sDBName, sDBSetting, oPlayer);
|
||||
return iReturn;
|
||||
}
|
||||
|
||||
void SetDMFIPersistentInt(string sDBName, string sDBSetting, int iDBValue, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
NBDE_SetCampaignInt(sDBName, sDBSetting, iDBValue, oPlayer);
|
||||
NBDE_SetCampaignInt(sDBName, "DMFI_DB_DIRTY", TRUE);
|
||||
}
|
||||
|
||||
//Float functions
|
||||
float GetDMFIPersistentFloat(string sDBName, string sDBSetting, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
float fReturn = NBDE_GetCampaignFloat(sDBName, sDBSetting, oPlayer);
|
||||
return fReturn;
|
||||
}
|
||||
|
||||
void SetDMFIPersistentFloat(string sDBName, string sDBSetting, float fDBValue, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
NBDE_SetCampaignFloat(sDBName, sDBSetting, fDBValue, oPlayer);
|
||||
NBDE_SetCampaignInt(sDBName, "DMFI_DB_DIRTY", TRUE);
|
||||
}
|
||||
|
||||
//String functions
|
||||
string GetDMFIPersistentString(string sDBName, string sDBSetting, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
string sReturn = NBDE_GetCampaignString(sDBName, sDBSetting, oPlayer);
|
||||
return sReturn;
|
||||
}
|
||||
|
||||
void SetDMFIPersistentString(string sDBName, string sDBSetting, string sDBValue, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
NBDE_SetCampaignString(sDBName, sDBSetting, sDBValue, oPlayer);
|
||||
NBDE_SetCampaignInt(sDBName, "DMFI_DB_DIRTY", TRUE);
|
||||
}
|
||||
|
1198
_module/nss/dmfi_dmw_inc.nss
Normal file
1198
_module/nss/dmfi_dmw_inc.nss
Normal file
File diff suppressed because it is too large
Load Diff
4193
_module/nss/dmfi_execute.nss
Normal file
4193
_module/nss/dmfi_execute.nss
Normal file
File diff suppressed because it is too large
Load Diff
35
_module/nss/dmfi_getln_cbtpl.nss
Normal file
35
_module/nss/dmfi_getln_cbtpl.nss
Normal file
@@ -0,0 +1,35 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: DMFI - DMFI_get_line callback template
|
||||
//:: dmfi_getln_cbtpl
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
A template (skeleton) function for DMFI_get_line callback processing.
|
||||
|
||||
Use this template to create your script to be invoked when your scripted call
|
||||
to DMFI_get_line receives input.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: tsunami282
|
||||
//:: Created On: 2008.05.21
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
int nVolume = GetPCChatVolume();
|
||||
object oShouter = GetPCChatSpeaker();
|
||||
string sSaid = GetPCChatMessage();
|
||||
|
||||
// you may wish to define an "abort" input message, such as a line
|
||||
// containing a single period:
|
||||
if (sSaid != ".")
|
||||
{
|
||||
// put your code here to process the input line (in sSaid)
|
||||
|
||||
}
|
||||
|
||||
// after processing, you will likely want to "eat" the text line, so it is
|
||||
// not spoken or available for further processing. If you want the line to
|
||||
// appear, either comment out the following line, or set it to:
|
||||
// SetPCChatMessage(sSaid);
|
||||
SetPCChatMessage("");
|
||||
}
|
61
_module/nss/dmfi_getln_inc.nss
Normal file
61
_module/nss/dmfi_getln_inc.nss
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
// DMFI_get_line: generic input line processing
|
||||
//
|
||||
// You can use this when you want to retrieve a spoken line of text.
|
||||
//
|
||||
// Specify the PC you want to listen to, the channel you want to listen on
|
||||
// (often the TALK channel), and the name of the script to run when a line
|
||||
// of text is heard.
|
||||
//
|
||||
// See the file dmfi_getln_cbtbl for a sample template script for processing
|
||||
// the heard line.
|
||||
|
||||
#include "dmfi_plychat_inc"
|
||||
|
||||
const string DMFI_GETLINE_HOOK_HANDLE_VARNAME = "dmfi_getline_hookhandle";
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tsunami282
|
||||
* @since 1.09
|
||||
*
|
||||
* @param oSpeaker PC we want to listen to.
|
||||
* @param iChannel voice channel to listen on (use TALKVOLUME_ constants).
|
||||
* @param sEventScriptName sEventScriptName = name of script to call upon completion
|
||||
* of input (cannot be blank).
|
||||
* @param oRequester object requesting the result: the sEventScriptName script
|
||||
* will be invoked with this as the caller, and therefore it
|
||||
* must be valid at time of player chat event.
|
||||
* @return handle (positive int) of the chat event hook
|
||||
*/
|
||||
int DMFI_get_line(object oSpeaker, int iChannel, string sEventScriptName,
|
||||
object oRequester = OBJECT_SELF)
|
||||
{
|
||||
int hdlHook = 0;
|
||||
|
||||
if (GetIsObjectValid(oSpeaker) && GetIsObjectValid(oRequester) && sEventScriptName != "")
|
||||
{
|
||||
// SendMessageToPC(GetFirstPC(), "getline - apply hook");
|
||||
hdlHook = DMFI_ChatHookAdd(sEventScriptName, oRequester, (1 << iChannel),
|
||||
FALSE, oSpeaker, TRUE);
|
||||
// SendMessageToPC(GetFirstPC(), "getline - hook handle returned is " + IntToString(hdlHook));
|
||||
SetLocalInt(oRequester, DMFI_GETLINE_HOOK_HANDLE_VARNAME, hdlHook);
|
||||
}
|
||||
|
||||
return hdlHook;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param hdlHookIn handle of hook handler that we want to un-hook.
|
||||
* @param oRequester object requesting the result of DMFI_get_line
|
||||
*/
|
||||
void DMFI_cancel_get_line(int hdlHookIn = 0, object oRequester = OBJECT_SELF)
|
||||
{
|
||||
int hdlHook = hdlHookIn;
|
||||
if (hdlHook == 0) hdlHook = GetLocalInt(oRequester, DMFI_GETLINE_HOOK_HANDLE_VARNAME);
|
||||
DMFI_ChatHookRemove(hdlHook);
|
||||
}
|
||||
|
217
_module/nss/dmfi_init_inc.nss
Normal file
217
_module/nss/dmfi_init_inc.nss
Normal file
@@ -0,0 +1,217 @@
|
||||
|
||||
#include "dmfi_db_inc"
|
||||
|
||||
const int DMFI_DEFAULT_EMOTES_MUTED = FALSE;
|
||||
|
||||
int dmfiInitialize(object oUser)
|
||||
{
|
||||
//*************************************INITIALIZATION CODE***************************************
|
||||
//***************************************RUNS ONE TIME ***************************************
|
||||
|
||||
//voice stuff is module wide
|
||||
|
||||
if (GetLocalInt(GetModule(), "dmfi_initialized") != 1)
|
||||
{
|
||||
SendMessageToPC(oUser,":: DMFI Wands & Widgets System ::");
|
||||
int iLoop = 20610;
|
||||
string sText;
|
||||
while (iLoop < 20680)
|
||||
{
|
||||
sText = GetDMFIPersistentString("dmfi", "hls" + IntToString(iLoop));
|
||||
SetCustomToken(iLoop, sText);
|
||||
iLoop++;
|
||||
}
|
||||
SendMessageToAllDMs("DMFI voice custom tokens initialized.");
|
||||
|
||||
SetLocalInt(GetModule(), "dmfi_initialized", 1);
|
||||
}
|
||||
|
||||
|
||||
//remainder of settings are user based
|
||||
|
||||
if ((GetLocalInt(oUser, "dmfi_initialized")!=1) && (GetIsDM(oUser) || GetIsDMPossessed(oUser)))
|
||||
{
|
||||
//if you have campaign variables set - use those settings
|
||||
if (GetDMFIPersistentInt("dmfi", "Settings", oUser)==1)
|
||||
{
|
||||
FloatingTextStringOnCreature("DMFI Settings Restored", oUser, FALSE);
|
||||
// SendMessageToPC(oUser, "DMFI Settings Restored");
|
||||
|
||||
int n = GetDMFIPersistentInt("dmfi", "dmfi_alignshift", oUser);
|
||||
SetCustomToken(20781, IntToString(n));
|
||||
SetLocalInt(oUser, "dmfi_alignshift", n);
|
||||
SendMessageToPC(oUser, "Settings: Alignment shift: "+IntToString(n));
|
||||
|
||||
n = GetDMFIPersistentInt("dmfi", "dmfi_safe_factions", oUser);
|
||||
SetLocalInt(oUser, "dmfi_safe_factions", n);
|
||||
SendMessageToPC(oUser, "Settings: Factions (1 is DMFI Safe Faction): "+IntToString(n));
|
||||
|
||||
n = GetDMFIPersistentInt("dmfi", "dmfi_damagemodifier", oUser);
|
||||
SetLocalInt(oUser, "dmfi_damagemodifier",n);
|
||||
SendMessageToPC(oUser, "Settings: Damage Modifier: "+IntToString(n));
|
||||
|
||||
n = GetDMFIPersistentInt("dmfi","dmfi_buff_party",oUser);
|
||||
SetLocalInt(oUser, "dmfi_buff_party", n);
|
||||
if (n==1)
|
||||
SetCustomToken(20783, "Party");
|
||||
else
|
||||
SetCustomToken(20783, "Single Target");
|
||||
|
||||
SendMessageToPC(oUser, "Settings: Buff Party (1 is Party): "+IntToString(n));
|
||||
|
||||
string sLevel = GetDMFIPersistentString("dmfi", "dmfi_buff_level", oUser);
|
||||
SetCustomToken(20782, sLevel);
|
||||
SetLocalString(oUser, "dmfi_buff_level", sLevel);
|
||||
SendMessageToPC(oUser, "Settings: Buff Level: "+ sLevel);
|
||||
|
||||
n = GetDMFIPersistentInt("dmfi", "dmfi_dicebag", oUser);
|
||||
SetLocalInt(oUser, "dmfi_dicebag", n);
|
||||
|
||||
string sText;
|
||||
if (n==0)
|
||||
{
|
||||
SetCustomToken(20681, "Private");
|
||||
sText = "Private";
|
||||
}
|
||||
else if (n==1)
|
||||
{
|
||||
SetCustomToken(20681, "Global");
|
||||
sText = "Global";
|
||||
}
|
||||
else if (n==2)
|
||||
{
|
||||
SetCustomToken(20681, "Local");
|
||||
sText = "Local";
|
||||
}
|
||||
else if (n==3)
|
||||
{
|
||||
SetCustomToken(20681, "DM Only");
|
||||
sText = "DM Only";
|
||||
}
|
||||
SendMessageToPC(oUser, "Settings: Dicebag Reporting: "+sText);
|
||||
|
||||
n = GetDMFIPersistentInt("dmfi", "dmfi_dice_no_animate", oUser);
|
||||
SetLocalInt(oUser, "dmfi_dice_no_animate", n);
|
||||
SendMessageToPC(oUser, "Settings: Roll Animations (1 is OFF): "+IntToString(n));
|
||||
|
||||
float f = GetDMFIPersistentFloat("dmfi", "dmfi_reputation", oUser);
|
||||
SetLocalFloat(oUser, "dmfi_reputation", f);
|
||||
SendMessageToPC(oUser, "Settings: Reputation Adjustment: "+FloatToString(f));
|
||||
|
||||
f = GetDMFIPersistentFloat("dmfi", "dmfi_effectduration", oUser);
|
||||
SetLocalFloat(oUser, "dmfi_effectduration", f);
|
||||
SendMessageToPC(oUser, "Settings: Effect Duration: "+FloatToString(f));
|
||||
|
||||
f = GetDMFIPersistentFloat("dmfi", "dmfi_sound_delay", oUser);
|
||||
SetLocalFloat(oUser, "dmfi_sound_delay", f);
|
||||
SendMessageToPC(oUser, "Settings: Sound Delay: "+FloatToString(f));
|
||||
|
||||
f = GetDMFIPersistentFloat("dmfi", "dmfi_beamduration", oUser);
|
||||
SetLocalFloat(oUser, "dmfi_beamduration", f);
|
||||
SendMessageToPC(oUser, "Settings: Beam Duration: "+FloatToString(f));
|
||||
|
||||
f = GetDMFIPersistentFloat("dmfi", "dmfi_stunduration", oUser);
|
||||
SetLocalFloat(oUser, "dmfi_stunduration", f);
|
||||
SendMessageToPC(oUser, "Settings: Stun Duration: "+FloatToString(f));
|
||||
|
||||
f = GetDMFIPersistentFloat("dmfi", "dmfi_saveamount", oUser);
|
||||
SetLocalFloat(oUser, "dmfi_saveamount", f);
|
||||
SendMessageToPC(oUser, "Settings: Save Adjustment: "+FloatToString(f));
|
||||
|
||||
f = GetDMFIPersistentFloat("dmfi", "dmfi_effectdelay", oUser);
|
||||
SetLocalFloat(oUser, "dmfi_effectdelay", f);
|
||||
SendMessageToPC(oUser, "Settings: Effect Delay: "+FloatToString(f));
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
FloatingTextStringOnCreature("DMFI Default Settings Initialized", oUser, FALSE);
|
||||
// SendMessageToPC(oUser, "DMFI Default Settings Initialized");
|
||||
|
||||
//Setting FOUR campaign variables so 1st use will be slow.
|
||||
//Recommend initializing your preferences with no players or
|
||||
//while there is NO fighting.
|
||||
// SetLocalInt(oUser, "dmfi_initialized", 1);
|
||||
SetDMFIPersistentInt("dmfi", "Settings", 1, oUser);
|
||||
|
||||
SetCustomToken(20781, "5");
|
||||
SetLocalInt(oUser, "dmfi_alignshift", 5);
|
||||
SetDMFIPersistentInt("dmfi", "dmfi_alignshift", 5, oUser);
|
||||
SendMessageToPC(oUser, "Settings: Alignment shift: 5");
|
||||
|
||||
SetCustomToken(20783, "Single Target");
|
||||
SetLocalInt(oUser, "dmfi_buff_party", 0);
|
||||
SetDMFIPersistentInt("dmfi", "dmfi_buff_party", 0, oUser);
|
||||
SendMessageToPC(oUser, "Settings: Buff set to Single Target: ");
|
||||
|
||||
SetCustomToken(20782, "Low");
|
||||
SetLocalString(oUser, "dmfi_buff_level", "LOW");
|
||||
SetDMFIPersistentString("dmfi", "dmfi_buff_level", "LOW", oUser);
|
||||
SendMessageToPC(oUser, "Settings: Buff Level set to LOW: ");
|
||||
|
||||
SetLocalInt(oUser, "dmfi_dicebag", 0);
|
||||
SetCustomToken(20681, "Private");
|
||||
SetDMFIPersistentInt("dmfi", "dmfi_dicebag", 0, oUser);
|
||||
SendMessageToPC(oUser, "Settings: Dicebag Rolls set to PRIVATE");
|
||||
|
||||
SetLocalInt(oUser, "", 0);
|
||||
SetDMFIPersistentInt("dmfi", "dmfi_safe_factions", 0, oUser);
|
||||
SendMessageToPC(oUser, "Settings: Factions set to BW base behavior");
|
||||
|
||||
SetLocalFloat(oUser, "dmfi_reputation", 5.0);
|
||||
SetCustomToken(20784, "5");
|
||||
SetDMFIPersistentFloat("dmfi", "dmfi_reputation", 5.0, oUser);
|
||||
SendMessageToPC(oUser, "Settings: Reputation adjustment: 5");
|
||||
|
||||
SetDMFIPersistentFloat("dmfi", "dmfi_effectduration", 60.0, oUser);
|
||||
SetLocalFloat(oUser, "dmfi_effectduration", 60.0);
|
||||
SetDMFIPersistentFloat("dmfi", "dmfi_sound_delay", 0.2, oUser);
|
||||
SetLocalFloat(oUser, "dmfi_sound_delay", 0.2);
|
||||
SetDMFIPersistentFloat("dmfi", "dmfi_beamduration", 5.0, oUser);
|
||||
SetLocalFloat(oUser, "dmfi_beamduration", 5.0);
|
||||
SetDMFIPersistentFloat("dmfi", "dmfi_stunduration", 1000.0, oUser);
|
||||
SetLocalFloat(oUser, "dmfi_stunduration", 1000.0);
|
||||
SetDMFIPersistentFloat("dmfi", "dmfi_saveamount", 5.0, oUser);
|
||||
SetLocalFloat(oUser, "dmfi_saveamount", 5.0);
|
||||
SetDMFIPersistentFloat("dmfi", "dmfi_effectdelay", 1.0, oUser);
|
||||
SetLocalFloat(oUser, "dmfi_effectdelay", 1.0);
|
||||
|
||||
SendMessageToPC(oUser, "Settings: Effect Duration: 60.0");
|
||||
SendMessageToPC(oUser, "Settings: Effect Delay: 1.0");
|
||||
SendMessageToPC(oUser, "Settings: Beam Duration: 5.0");
|
||||
SendMessageToPC(oUser, "Settings: Stun Duration: 1000.0");
|
||||
SendMessageToPC(oUser, "Settings: Sound Delay: 0.2");
|
||||
SendMessageToPC(oUser, "Settings: Save Adjustment: 5.0");
|
||||
}
|
||||
}
|
||||
//********************************END INITIALIZATION***************************
|
||||
|
||||
// inits for all users (DM & player)
|
||||
if (GetLocalInt(oUser, "dmfi_initialized")!=1)
|
||||
{
|
||||
int bEmotesMuted;
|
||||
if (GetDMFIPersistentInt("dmfi", "Settings", oUser)==1)
|
||||
{
|
||||
bEmotesMuted = GetDMFIPersistentInt("dmfi", "dmfi_emotemute", oUser);
|
||||
}
|
||||
else
|
||||
{
|
||||
bEmotesMuted = DMFI_DEFAULT_EMOTES_MUTED;
|
||||
SetDMFIPersistentInt("dmfi", "dmfi_emotemute", bEmotesMuted, oUser);
|
||||
}
|
||||
SetLocalInt(oUser, "hls_emotemute", bEmotesMuted);
|
||||
SendMessageToPC(oUser, "Settings: Emotes "+(bEmotesMuted ? "muted" : "unmuted"));
|
||||
|
||||
SetLocalObject(oUser, "dmfi_VoiceTarget", OBJECT_INVALID);
|
||||
SendMessageToPC(oUser, "Settings: Voice throw target cleared");
|
||||
|
||||
SetLocalObject(oUser, "dmfi_univ_target", oUser);
|
||||
SendMessageToPC(oUser, "Settings: Command target set to self");
|
||||
|
||||
SetLocalInt(oUser, "dmfi_initialized", 1);
|
||||
}
|
||||
|
||||
return TRUE; // no errors detected
|
||||
}
|
||||
|
23
_module/nss/dmfi_onclienter.nss
Normal file
23
_module/nss/dmfi_onclienter.nss
Normal file
@@ -0,0 +1,23 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: DMFI - OnClientEnter event handler
|
||||
//:: dmfi_onclienter
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Event handler for the module-level OnClientEnter event. Initializes DMFI system.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: 2008.08.02 tsunami282 - created.
|
||||
|
||||
#include "dmfi_init_inc"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void main()
|
||||
{
|
||||
object oUser = GetEnteringObject();
|
||||
|
||||
// do any other module OnClientEnter work here
|
||||
ExecuteScript("x3_mod_def_enter", OBJECT_SELF);
|
||||
|
||||
// initialize DMFI
|
||||
dmfiInitialize(oUser);
|
||||
}
|
29
_module/nss/dmfi_onmodhb.nss
Normal file
29
_module/nss/dmfi_onmodhb.nss
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
#include "dmfi_db_inc"
|
||||
|
||||
const int FLUSH_INTERVAL = 30; // seconds between database flushes to disk
|
||||
|
||||
void main()
|
||||
{
|
||||
// see if database is "dirty" (changed since last flush)
|
||||
if (IsDMFIPersistentDataDirty("dmfi"))
|
||||
{
|
||||
// it is, so check if time to flush database
|
||||
object oMod = GetModule();
|
||||
int iTick = GetLocalInt(oMod, "DMFI_MODULE_HEARTBEAT_TICK");
|
||||
int iSecsSinceFlush = iTick * 6;
|
||||
if (iSecsSinceFlush >= FLUSH_INTERVAL)
|
||||
{
|
||||
FlushDMFIPersistentData("dmfi");
|
||||
iTick = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iTick++;
|
||||
}
|
||||
SetLocalInt(oMod, "DMFI_MODULE_HEARTBEAT_TICK", iTick);
|
||||
}
|
||||
|
||||
// do any other module OnHeartbeat work here
|
||||
ExecuteScript("x3_mod_def_hb", OBJECT_SELF);
|
||||
}
|
79
_module/nss/dmfi_onplychat.nss
Normal file
79
_module/nss/dmfi_onplychat.nss
Normal file
@@ -0,0 +1,79 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: DMFI - OnPlayerChat event handler
|
||||
//:: dmfi_onplychat
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Event handler for the module-level OnPlayerChat event. Manages scripter-added
|
||||
event scripts.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Merle, with help from mykael22000 and tsunami282
|
||||
//:: Created On: 2007.12.12
|
||||
//:://////////////////////////////////////////////
|
||||
//:: 2007.12.27 tsunami282 - implemented hooking tree
|
||||
|
||||
#include "dmfi_plychat_inc"
|
||||
|
||||
const string DMFI_PLAYERCHAT_SCRIPTNAME = "dmfi_plychat_exe";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void main()
|
||||
{
|
||||
int nVolume = GetPCChatVolume();
|
||||
object oShouter = GetPCChatSpeaker();
|
||||
|
||||
int bInvoke;
|
||||
string sChatHandlerScript;
|
||||
int maskChannels;
|
||||
// int bListenAll;
|
||||
object oRunner;
|
||||
int bAutoRemove;
|
||||
int bDirtyList = FALSE;
|
||||
int iHook;
|
||||
object oMod = GetModule();
|
||||
// SendMessageToPC(GetFirstPC(), "OnPlayerChat - process hooks");
|
||||
int nHooks = GetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME);
|
||||
for (iHook = nHooks; iHook > 0; iHook--) // reverse-order execution, last hook gets first dibs
|
||||
{
|
||||
// SendMessageToPC(GetFirstPC(), "OnPlayerChat -- process hook #" + IntToString(iHook));
|
||||
maskChannels = GetLocalArrayInt(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, iHook);
|
||||
// SendMessageToPC(GetFirstPC(), "OnPlayerChat -- channel heard=" + IntToString(nVolume) + ", soughtmask=" + IntToString(maskChannels));
|
||||
if (((1 << nVolume) & maskChannels) != 0) // right channel
|
||||
{
|
||||
// SendMessageToPC(GetFirstPC(), "OnPlayerChat --- channel matched");
|
||||
|
||||
bInvoke = FALSE;
|
||||
if (GetLocalArrayInt(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, iHook) != FALSE)
|
||||
{
|
||||
bInvoke = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
object oDesiredSpeaker = GetLocalArrayObject(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, iHook);
|
||||
if (oShouter == oDesiredSpeaker) bInvoke = TRUE;
|
||||
}
|
||||
if (bInvoke) // right speaker
|
||||
{
|
||||
// SendMessageToPC(GetFirstPC(), "OnPlayerChat --- speaker matched");
|
||||
sChatHandlerScript = GetLocalArrayString(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, iHook);
|
||||
oRunner = GetLocalArrayObject(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, iHook);
|
||||
// SendMessageToPC(GetFirstPC(), "OnPlayerChat --- executing script '" + sChatHandlerScript + "' on object '" + GetName(oRunner) +"'");
|
||||
ExecuteScript(sChatHandlerScript, oRunner);
|
||||
bAutoRemove = GetLocalArrayInt(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, iHook);
|
||||
if (bAutoRemove)
|
||||
{
|
||||
// SendMessageToPC(GetFirstPC(), "OnPlayerChat --- scheduling autoremove");
|
||||
bDirtyList = TRUE;
|
||||
SetLocalArrayInt(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, iHook, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bDirtyList) DMFI_ChatHookRemove(0);
|
||||
|
||||
// always execute the DMFI parser
|
||||
ExecuteScript(DMFI_PLAYERCHAT_SCRIPTNAME, OBJECT_SELF);
|
||||
|
||||
}
|
||||
|
463
_module/nss/dmfi_onrest.nss
Normal file
463
_module/nss/dmfi_onrest.nss
Normal file
@@ -0,0 +1,463 @@
|
||||
/*DMFI Rest System Alpha by hahnsoo
|
||||
|
||||
CONTENTS
|
||||
--------
|
||||
Placeables>>Special>>Custom 5 - DMFI Bed Roll, DMFI Campfire, DMFI Invisible
|
||||
Rest Object, DMFI Tent
|
||||
|
||||
Items>>Special>>Custom5 - DMFI Bed Roll (100 gp), DMFI Firewood (1 gp), DMFI
|
||||
Portable Tent (500 gp) (different gp values for different situations)
|
||||
|
||||
Scripts - dmfi_onrest
|
||||
(Yup, that's it)
|
||||
|
||||
Description
|
||||
-----------
|
||||
This is a robust and versatile rest system that incorporates a LOT of options.
|
||||
Perhaps too many, I don't know. I tried to find everything that folks would
|
||||
possibly want in a resting system. The most important "feature" is the rest
|
||||
conversation menu, which governs for both DM and Player the kind of resting that
|
||||
is allowed.
|
||||
|
||||
The ways you can control rest in this system are:
|
||||
1) Global vs. Local - Restrict or release restrictions on resting based on world
|
||||
settings or on a per-area basis
|
||||
2) Unlimited vs. Limited vs. No Rest - Have the Players rest at any time they'd
|
||||
like. Or Limit them according to certain parameters and toggles. Or don't
|
||||
allow them to rest at all. You can set these both globally and locally
|
||||
(Unlimited and No Rest areas).
|
||||
3) Time restriction - The staple of most simple rest restrictions. You can limit
|
||||
resting per 1, 2, 4, 8, 12, or 24 in-game hours, and the amount of real-time
|
||||
minutes are calculated for the DM. Again, you can set these both globally
|
||||
and locally.
|
||||
4) Placeables - Popularized by Demetrious's Supply-Based Rest, this allows you
|
||||
to restrict resting according to proximity to objects. It allows you to use
|
||||
DMFI rest objects (tag = dmfi_restobject), campfires, bedrolls, beds, tents
|
||||
(a "Name-based" rest placeable), and toggles to include/exclude certain
|
||||
classes that typically don't care about such niceties.
|
||||
5) Armor Restrictions - I'm not quite fond of this particular one, but it is a
|
||||
standard feature of many rest systems and thus included in the package.
|
||||
Allows you to set what weight of armor allows a PC to rest.
|
||||
6) Set Hit Point Restrictions - Unlike the other restrictions, this does NOT
|
||||
prevent resting. What it does is determine how many hitpoints are regained
|
||||
upon resting, from a gradient of no hitpoints to all hitpoint, and some
|
||||
interesting options in between (1 HP per level, per 3rd edition, which
|
||||
skews against fighter classes and CON based HP gain, which skews in favor of
|
||||
lower level characters).
|
||||
7) Toggle Spell Memorization - This converts the "rest" into a "pseudorest"
|
||||
which only heals HP. Useful for a "no spell memorization" zone locally, not
|
||||
much use globally.
|
||||
8) Various other "fluff" settings (Snoring, the rest conversation menu,
|
||||
immobilized resting, floating text feedback).
|
||||
|
||||
There is also a "big red button" option that simply full rests all PCs in the
|
||||
area. Useful to quickly work around rest restrictions that you have previously
|
||||
set up.
|
||||
|
||||
Installation
|
||||
------------
|
||||
Change your OnRest event script to the dmfi_onrest script. Or you can do an
|
||||
external execute script call by using ExecuteScript("dmfi_onrest", OBJECT_SELF);
|
||||
in your current script.
|
||||
|
||||
The areas in your module should NOT have the "No Rest" box checked, in the areas
|
||||
which you wish to use this system.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
All configuration of the system is done in-game as a DM. To bring up the Rest
|
||||
Configuration Menu, press R or the rest button.
|
||||
The conversation will detail the settings you have in the area (whether you are
|
||||
using the default Global settings or using the Local area settings to override)
|
||||
and the particular restrictions that you have set.
|
||||
|
||||
Settings are stored Persistently using the Bioware Database, per the DMFI W&W
|
||||
default persistence options. If you want to use another database system, simply
|
||||
edit the the dmfi_db_inc wrapper functions to your liking.
|
||||
|
||||
Unlimited Rest means just that: No restrictions. You may have global
|
||||
restrictions set up, but as long as Unlimited rest is set globally or locally,
|
||||
they are ignored.
|
||||
No Rest means just that: No resting allowed, regardless of restrictions.
|
||||
Limited Rest means that the restrictions you have set globally or locally are in
|
||||
effect. You can restrict resting as stated above in the Description.
|
||||
|
||||
When you set any [LOCAL] Area variables, you automatically set the area to
|
||||
"override" the global rest restrictions. This means that this area follows its
|
||||
own rules, and isn't governed by the global rules. Setting the [LOCAL] Area
|
||||
restrictions will copy the current global restriction variables, but after that,
|
||||
the only way to go back to "global" is to select "Use default [GLOBAL] Module
|
||||
settings"
|
||||
Tip: The most useful way to use this is to simply set areas as Unlimited Rest or
|
||||
No Rest, say an Inn Room or a combat zone, respectively.
|
||||
|
||||
Player Notes
|
||||
------------
|
||||
If you are using the DMFI Rest Menu (on by default), the rest restrictions (if
|
||||
any) are displayed on your Rest Conversation Menu, telling you why you can't
|
||||
rest (if you are restricted). You also have the option to access both the DMFI
|
||||
Dicebag and the DMFI Emote wand directly from the Rest Menu. This allows you to
|
||||
use emotes or dice checks WITHOUT having that silly "Use Unique Power"
|
||||
animation.
|
||||
|
||||
Included in this package is a way to do "Alternate Resting Animations". These
|
||||
animations simply change the way you appear when you rest. Since they use the
|
||||
ForceRest() function, it isn't a "true" rest... rather it sets you for a certain
|
||||
amount of time (equal to a normal rest) as un-moveable, and applies the rest at
|
||||
the end of that time. This just means you don't get the little egg timer.
|
||||
|
||||
This is an ALPHA release, and I'm pretty sure I don't know everything about
|
||||
Resting systems in the universe. I've tried to incorporate nearly all of the
|
||||
elements I've seen in other available resting systems and encorporate them into
|
||||
a small (single script), DMFI-integrated package.
|
||||
|
||||
I would greatly appreciate feedback, suggestions, additions, omissions, bug
|
||||
reports, whatever. Send them to me at hahns_shin@hotmail.com.*/
|
||||
|
||||
#include "dmfi_db_inc"
|
||||
//This function calculates the resting duration based on PC Hit Dice
|
||||
//Based off of restduration.2da
|
||||
void FloatyText(string sText, object oPC, int iSettings)
|
||||
{
|
||||
if (!(iSettings & 0x40000000))
|
||||
FloatingTextStringOnCreature(sText, oPC, FALSE);
|
||||
}
|
||||
|
||||
float GetRestDuration(object oPC)
|
||||
{
|
||||
return 10.0f + 0.5f * IntToFloat(GetHitDice(oPC));
|
||||
}
|
||||
|
||||
// This function is used as a wrapper for the Rest VFX Object
|
||||
void DoRestVFX(object oPC, float fDuration, int nEffect) {
|
||||
effect eEffect;
|
||||
if (nEffect == -1) {
|
||||
eEffect = EffectCutsceneImmobilize();
|
||||
} else {
|
||||
eEffect = EffectVisualEffect(nEffect);
|
||||
}
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eEffect), oPC, fDuration);
|
||||
}
|
||||
|
||||
|
||||
//This function adds the Blindness/Snore effects
|
||||
//Also adds cutscene immobilize to prevent movement
|
||||
//Snoring should only occur at start, then follows on the module's hb
|
||||
void ApplyRestVFX(object oPC, int iSettings)
|
||||
{
|
||||
object oRestVFX = GetObjectByTag("dmfi_restvfxobject");
|
||||
effect eSnore = EffectVisualEffect(VFX_IMP_SLEEP); //Sleepy "ZZZ"s
|
||||
float fDuration = GetRestDuration(oPC);
|
||||
float fSeconds = 6.0f;
|
||||
if (!(iSettings & 0x80000000)) //Immobile Resting flag
|
||||
{
|
||||
// Pass a -1 for EffectCutsceneImmobilize.
|
||||
// For a visual effect, simply pass the VFX constant.
|
||||
AssignCommand(oRestVFX, DoRestVFX(oPC, fDuration, -1));
|
||||
}
|
||||
if (!(iSettings & 0x20000000)) //VFX flag
|
||||
{
|
||||
// AssignCommand(oRestVFX, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eBlind), oPC, fDuration));
|
||||
AssignCommand(oRestVFX, DoRestVFX(oPC, fDuration, VFX_DUR_BLACKOUT));
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eSnore, oPC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Removes blindness & immobilize -- Merle
|
||||
void RemoveRestVFX(object oPC) {
|
||||
object oRestVFX = GetObjectByTag("dmfi_restvfxobject");
|
||||
effect eEffect = GetFirstEffect(oPC);
|
||||
while (GetIsEffectValid(eEffect)) {
|
||||
if (GetEffectCreator(eEffect) == oRestVFX) {
|
||||
RemoveEffect(oPC, eEffect);
|
||||
}
|
||||
eEffect = GetNextEffect(oPC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This function gets the "Final HP" available to the PC after resting
|
||||
int CalculateFinalHitPoints(object oPC, int iSettings)
|
||||
{
|
||||
int iHP = (iSettings & 0x0f000000);
|
||||
switch(iHP)
|
||||
{
|
||||
case 0x01000000: return 0; break;
|
||||
case 0x02000000: return GetHitDice(oPC); break;
|
||||
case 0x03000000: return GetAbilityScore(oPC, ABILITY_CONSTITUTION); break;
|
||||
case 0x04000000: return GetMaxHitPoints(oPC)/10; break;
|
||||
case 0x05000000: return GetMaxHitPoints(oPC)/4; break;
|
||||
case 0x06000000: return GetMaxHitPoints(oPC)/2; break;
|
||||
case 0x07000000: return GetMaxHitPoints(oPC); break;
|
||||
default: return GetMaxHitPoints(oPC); break;
|
||||
}
|
||||
return GetMaxHitPoints(oPC);
|
||||
}
|
||||
|
||||
void RemoveMagicalEffects(object oPC)
|
||||
{
|
||||
effect eEffect = GetFirstEffect(oPC);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
if (GetEffectSubType(eEffect) == SUBTYPE_MAGICAL)
|
||||
RemoveEffect(oPC, eEffect);
|
||||
eEffect = GetNextEffect(oPC);
|
||||
}
|
||||
}
|
||||
|
||||
//This function simulates a rest without restoring spells
|
||||
void DoPseudoRest(object oPC, int iSettings, int iSpells = FALSE)
|
||||
{
|
||||
effect eSnore = EffectVisualEffect(VFX_IMP_SLEEP);
|
||||
effect eBlind = EffectVisualEffect(VFX_DUR_BLACKOUT);
|
||||
effect eStop = EffectCutsceneImmobilize();
|
||||
float fDuration = GetRestDuration(oPC);
|
||||
float fSeconds = 6.0f;
|
||||
int iAnimation = GetLocalInt(oPC, "dmfi_r_alternate");
|
||||
if (!iAnimation)
|
||||
iAnimation = ANIMATION_LOOPING_SIT_CROSS;
|
||||
AssignCommand(oPC, PlayAnimation(iAnimation, 1.0f, fDuration));
|
||||
DelayCommand(0.1, SetCommandable(FALSE, oPC));
|
||||
DelayCommand(fDuration, SetCommandable(TRUE, oPC));
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eStop), oPC, fDuration);
|
||||
if (!(iSettings & 0x20000000) && iAnimation != ANIMATION_LOOPING_MEDITATE && iAnimation != ANIMATION_LOOPING_WORSHIP) //If the No VFX flag is not set, do VFX
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eBlind), oPC, fDuration);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eSnore, oPC);
|
||||
while (fSeconds < fDuration)
|
||||
{
|
||||
DelayCommand(fSeconds, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSnore, oPC));
|
||||
fSeconds += 6.0f;
|
||||
}
|
||||
}
|
||||
if (!iSpells)
|
||||
{
|
||||
effect eHeal = EffectHeal(CalculateFinalHitPoints(oPC, iSettings)); //Heal the PC
|
||||
DelayCommand(fDuration + 0.1f, ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC));
|
||||
DelayCommand(fDuration + 0.1f, RemoveMagicalEffects(oPC)); //Remove all magical effects from PC
|
||||
}
|
||||
else
|
||||
{
|
||||
DelayCommand(fDuration + 0.1f, ForceRest(oPC));
|
||||
}
|
||||
DeleteLocalInt(oPC, "dmfi_r_alternate");
|
||||
}
|
||||
|
||||
//This function determines if the PC is wearing heavy armor
|
||||
int GetIsWearingHeavyArmor(object oPC, int iSettings)
|
||||
{
|
||||
int iArmor = (iSettings & 0x00f00000);
|
||||
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oPC);
|
||||
int iWeight = GetWeight(oArmor);
|
||||
switch(iArmor)
|
||||
{
|
||||
default:
|
||||
case 0x00100000: if (iWeight > 20) return TRUE; break;
|
||||
case 0x00200000: if (iWeight > 60) return TRUE; break;
|
||||
case 0x00300000: if (iWeight > 110) return TRUE; break;
|
||||
case 0x00400000: if (iWeight > 160) return TRUE; break;
|
||||
case 0x00500000: if (iWeight > 310) return TRUE; break;
|
||||
case 0x00600000: if (iWeight > 410) return TRUE; break;
|
||||
case 0x00700000: if (iWeight > 460) return TRUE; break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//This function determines if the PC is near a resting placeable
|
||||
int GetIsNearRestingObject(object oPC, int iSettings)
|
||||
{
|
||||
if (iSettings & 0x00020000) //Ignore Druid
|
||||
{
|
||||
if (GetLevelByClass(CLASS_TYPE_DRUID, oPC))
|
||||
return TRUE;
|
||||
}
|
||||
if (iSettings & 0x00040000) //Ignore Ranger
|
||||
{
|
||||
if (GetLevelByClass(CLASS_TYPE_RANGER, oPC))
|
||||
return TRUE;
|
||||
}
|
||||
if (iSettings & 0x00080000) //Ignore Barb
|
||||
{
|
||||
if (GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC))
|
||||
return TRUE;
|
||||
}
|
||||
object oPlaceable = GetFirstObjectInShape(SHAPE_SPHERE, 6.0f, GetLocation(oPC), TRUE, OBJECT_TYPE_PLACEABLE);
|
||||
while (GetIsObjectValid(oPlaceable))
|
||||
{
|
||||
if (!(iSettings & 0x00001000) && GetTag(oPlaceable) == "dmfi_rest") //DMFI Placeables: by default, ON
|
||||
return TRUE;
|
||||
if ((iSettings & 0x00002000) && GetStringLowerCase(GetName(oPlaceable)) == "campfire") //Campfires
|
||||
return TRUE;
|
||||
if ((iSettings & 0x00004000) && (GetStringLowerCase(GetName(oPlaceable)) == "bed roll" || GetStringLowerCase(GetName(oPlaceable)) == "bedroll")) //Bed rolls
|
||||
return TRUE;
|
||||
if ((iSettings & 0x00008000) && GetStringLowerCase(GetName(oPlaceable)) == "bed") //beds
|
||||
return TRUE;
|
||||
if ((iSettings & 0x00010000) && GetStringLowerCase(GetName(oPlaceable)) == "tent") //tents
|
||||
return TRUE;
|
||||
oPlaceable = GetNextObjectInShape(SHAPE_SPHERE, 6.0f, GetLocation(oPC), TRUE, OBJECT_TYPE_PLACEABLE);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Updated to allow 6 hour breaks and to pass in a percentage if rest is interrupted
|
||||
void SetNextRestTime(object oPC, int iSettings, float fPercentage = 1.0)
|
||||
{
|
||||
if (fPercentage > 1.0 || fPercentage <= 0.0) {
|
||||
fPercentage = 1.0;
|
||||
}
|
||||
int iHours = (iSettings & 0x00000f00);
|
||||
int iTime = GetTimeHour() + GetCalendarDay() * 24 + GetCalendarMonth() * 24 * 28 + GetCalendarYear() * 24 * 28 * 12;
|
||||
|
||||
switch(iHours)
|
||||
{
|
||||
default:
|
||||
case 0x00000100: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(1) * fPercentage)); break;
|
||||
case 0x00000200: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(2) * fPercentage)); break;
|
||||
case 0x00000300: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(4) * fPercentage)); break;
|
||||
case 0x00000400: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(6) * fPercentage)); break;
|
||||
case 0x00000500: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(8) * fPercentage)); break;
|
||||
case 0x00000600: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(12) * fPercentage)); break;
|
||||
case 0x00000700: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(24) * fPercentage)); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This function determines whether or not you can rest.
|
||||
int DMFI_CanIRest(object oPC, int iSettings)
|
||||
{
|
||||
if (GetIsDM(oPC)) return TRUE;
|
||||
if (iSettings & 0x00000002) //No Rest Override
|
||||
{
|
||||
if (iSettings & 0x00000080)
|
||||
FloatyText("This is a No Rest area", oPC, iSettings);
|
||||
return FALSE;
|
||||
}
|
||||
if (!(iSettings & 0x00000001)) //Unlimited Rest Override
|
||||
{
|
||||
if (iSettings & 0x00000080)
|
||||
FloatyText("This is an Unlimited Rest area", oPC, iSettings);
|
||||
return TRUE;
|
||||
}
|
||||
if ((iSettings & 0x00000004) && (iSettings & 0x00000001)) //Time restriction
|
||||
{
|
||||
int iTime = GetTimeHour() + GetCalendarDay() * 24 + GetCalendarMonth() * 24 * 28 + GetCalendarYear() * 24 * 28 * 12;
|
||||
if (iTime < GetLocalInt(oPC, "dmfi_r_nextrest"))
|
||||
{
|
||||
FloatyText("You cannot rest at this time. You may rest again in " + IntToString(GetLocalInt(oPC, "dmfi_r_nextrest") - iTime) + " hours.", oPC, iSettings);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ((iSettings & 0x00000008) && (iSettings & 0x00000001)) //Placeable restriction
|
||||
{
|
||||
if (!GetIsNearRestingObject(oPC, iSettings))
|
||||
{
|
||||
FloatyText("You are not near a rest placeable", oPC, iSettings);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ((iSettings & 0x00000010) && (iSettings & 0x00000001)) //Armor restriction
|
||||
{
|
||||
if (GetIsWearingHeavyArmor(oPC, iSettings))
|
||||
{
|
||||
FloatyText("Your current armor is too heavy to rest", oPC, iSettings);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
object oPC = GetLastPCRested();
|
||||
object oArea = GetArea(oPC);
|
||||
int iSettings;
|
||||
int iModSettings = GetDMFIPersistentInt("dmfi", "dmfi_r_");
|
||||
int iAreaSettings = GetDMFIPersistentInt("dmfi", "dmfi_r_" + GetTag(oArea));
|
||||
if (iAreaSettings & 0x00000080)
|
||||
{
|
||||
iSettings = iAreaSettings;
|
||||
}
|
||||
else
|
||||
{
|
||||
iSettings = iModSettings;
|
||||
}
|
||||
SetLocalInt(oPC, "dmfi_r_settings", iSettings);
|
||||
|
||||
if (GetLastRestEventType()==REST_EVENTTYPE_REST_STARTED)
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_norest", !(DMFI_CanIRest(oPC, iSettings)));
|
||||
SetLocalInt(oPC, "dmfi_r_hitpoints", GetCurrentHitPoints(oPC));
|
||||
if (GetIsDM(oPC) || (!(iSettings & 0x10000000) && !GetLocalInt(oPC, "dmfi_r_bypass")))
|
||||
{ //If the Rest Conversation variable is set, then activate the rest conversation here.
|
||||
AssignCommand(oPC, ClearAllActions());
|
||||
SetLocalString(oPC, "dmfi_univ_conv", "rest");
|
||||
AssignCommand(oPC, ActionStartConversation(oPC, "dmfi_universal", TRUE));
|
||||
return;
|
||||
}
|
||||
if (GetLocalInt(oPC, "dmfi_norest")) //PC cannot rest
|
||||
{
|
||||
AssignCommand(oPC, ClearAllActions());
|
||||
DeleteLocalInt(oPC, "dmfi_r_bypass");
|
||||
return;
|
||||
}
|
||||
if ((iSettings & 0x00000004) && (iSettings & 0x00000001)) //Time restriction
|
||||
SetNextRestTime(oPC, iSettings);
|
||||
|
||||
if (GetLocalInt(oPC, "dmfi_r_alternate") || ((iSettings & 0x00000040) && (iSettings & 0x00000001)))
|
||||
{
|
||||
AssignCommand(oPC, ClearAllActions());
|
||||
if ((iSettings & 0x00000040) && (iSettings & 0x00000001))
|
||||
FloatyText("You cannot regain your spells in this area",oPC, iSettings);
|
||||
DoPseudoRest(oPC, iSettings, ((iSettings & 0x00000040) && (iSettings & 0x00000001)));
|
||||
DeleteLocalInt(oPC, "dmfi_r_bypass");
|
||||
return;
|
||||
}
|
||||
else if (!(iSettings & 0x20000000))
|
||||
{ //Rest VFX
|
||||
ApplyRestVFX(oPC, iSettings);
|
||||
}
|
||||
if ((iSettings & 0x00000020) && (iSettings & 0x00000001))
|
||||
{ //Auto Party Drop
|
||||
FloatyText("You have been removed from the party to prevent rest canceling",oPC, iSettings);
|
||||
RemoveFromParty(oPC);
|
||||
}
|
||||
}
|
||||
else if (GetLastRestEventType()==REST_EVENTTYPE_REST_CANCELLED)
|
||||
{
|
||||
// Make sure that resting has been initialized and the start time has been set. Otherwise, the Cancelled Rest Event was fired by
|
||||
// the Resting conversation.
|
||||
if (GetLocalInt(oPC, "dmfi_r_init"))
|
||||
{
|
||||
int iTime = GetTimeSecond() + GetTimeMinute() * 60 + GetTimeHour() * 3600 + GetCalendarDay() * 24 * 3600 + GetCalendarMonth() *3600 * 24 * 28 + GetCalendarYear() * 24 * 28 * 12 * 3600;
|
||||
int nTimeRested = iTime - GetLocalInt(oPC, "dmfi_r_startseconds");
|
||||
int nFullTime = FloatToInt(GetRestDuration(oPC));
|
||||
float fPercentage = IntToFloat(nTimeRested) / IntToFloat(nFullTime);
|
||||
SetNextRestTime(oPC, iSettings, fPercentage);
|
||||
// SendMessageToPC(oPC, "Rest interrupted; resting for " + IntToString(nTimeRested) + " out of " + IntToString(nFullTime) + " seconds (" + FloatToString(fPercentage) + "%).");
|
||||
SetLocalInt(oPC, "dmfi_r_init", FALSE);
|
||||
if ((iSettings & 0x00000020) && GetCurrentHitPoints(oPC) > GetLocalInt(oPC, "dmfi_r_hitpoints") && iSettings & 0x00000001) //HP restriction
|
||||
{
|
||||
effect eDam = EffectDamage(GetMaxHitPoints(oPC) - GetLocalInt(oPC, "dmfi_r_hitpoints"));
|
||||
FloatyText("Your hitpoints have been reset",oPC, iSettings);
|
||||
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oPC));
|
||||
|
||||
}
|
||||
}
|
||||
RemoveRestVFX(oPC);
|
||||
}
|
||||
else if (GetLastRestEventType()==REST_EVENTTYPE_REST_FINISHED)
|
||||
{
|
||||
if ((iSettings & 0x00000020) && (iSettings & 0x00000001)) //HP restriction
|
||||
{
|
||||
int iDam = GetMaxHitPoints(oPC) - GetLocalInt(oPC, "dmfi_r_hitpoints") - CalculateFinalHitPoints(oPC, iSettings);
|
||||
if (iDam > 0)
|
||||
{
|
||||
effect eDam = EffectDamage(iDam);
|
||||
FloatyText("You gain back limited HP from this rest",oPC, iSettings);
|
||||
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oPC));
|
||||
}
|
||||
}
|
||||
}
|
||||
DeleteLocalInt(oPC, "dmfi_r_bypass");
|
||||
}
|
117
_module/nss/dmfi_plchlishk_i.nss
Normal file
117
_module/nss/dmfi_plchlishk_i.nss
Normal file
@@ -0,0 +1,117 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: DMFI - internal player chat listener hooking include
|
||||
//:: dmfi_plchlishk_i
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Include file containing routines for managing the internal DMFI chain of
|
||||
"listeners", which are now implemented as OnPlayerChat event handlers rather
|
||||
than creatures.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: tsunami282
|
||||
//:: Created On: 2008.03.24
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
const int DMFI_LISTEN_ON_CHANNEL_TALK = 1;
|
||||
const int DMFI_LISTEN_ON_CHANNEL_WHISPER = 1;
|
||||
const int DMFI_LISTEN_ON_CHANNEL_SHOUT = 1;
|
||||
const int DMFI_LISTEN_ON_CHANNEL_DM = 1;
|
||||
const int DMFI_LISTEN_ON_CHANNEL_PARTY = 1;
|
||||
|
||||
const string DMFI_EAVESDROP_HOOK_VARNAME = "dmfi_Eavesdrop";
|
||||
|
||||
const float WHISPER_DISTANCE = 1.0;
|
||||
const float TALK_DISTANCE = 30.0;
|
||||
|
||||
string sHookTypeVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_Type"; // 1=PC (says), 2=NPC/location (hears)
|
||||
string sHookCreatureVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_Creature"; // must be valid for type 1, for type 2 object_invalid means location only
|
||||
string sHookRangeModeVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_RangeMode"; // listening range: for type 1, 0=pc only, 1=pc's party; for type 2, 0=earshot, 1=area, 2=module
|
||||
string sHookLocationVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_Location"; // for type 2, location of "listening post"
|
||||
string sHookChannelsVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_Channels"; // bitmask of TALKVOLUME channels to listen to
|
||||
string sHookOwnerVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_Owner"; // unique ID of owner of this hook (he who will get the captured text)
|
||||
string sHookBcastDMsVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_BcastDMs"; // 0=relay message to owner only, 1=broadcast to all DMs
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void RemoveListenerHook(int hooknum)
|
||||
{
|
||||
int hooktype;
|
||||
object hookcreature;
|
||||
location hooklocation;
|
||||
int hookchannels;
|
||||
object hookowner;
|
||||
int hookparty, hookbcast;
|
||||
|
||||
int iHook = hooknum;
|
||||
string siHook = "", siHookN = "";
|
||||
object oMod = GetModule();
|
||||
|
||||
while (1)
|
||||
{
|
||||
siHook = IntToString(iHook);
|
||||
siHookN = IntToString(iHook+1);
|
||||
|
||||
hooktype = GetLocalInt(oMod, sHookTypeVarname+siHookN);
|
||||
if (hooktype != 0)
|
||||
{
|
||||
hookcreature = GetLocalObject(oMod, sHookCreatureVarname+siHookN);
|
||||
hooklocation = GetLocalLocation(oMod, sHookLocationVarname+siHookN);
|
||||
hookchannels = GetLocalInt(oMod, sHookChannelsVarname+siHookN);
|
||||
hookowner = GetLocalObject(oMod, sHookOwnerVarname+siHookN);
|
||||
hookparty = GetLocalInt(oMod, sHookRangeModeVarname+siHookN);
|
||||
hookbcast = GetLocalInt(oMod, sHookBcastDMsVarname+siHookN);
|
||||
|
||||
SetLocalInt(oMod, sHookTypeVarname+siHook, hooktype);
|
||||
SetLocalObject(oMod, sHookCreatureVarname+siHook, hookcreature);
|
||||
SetLocalLocation(oMod, sHookLocationVarname+siHook, hooklocation);
|
||||
SetLocalInt(oMod, sHookChannelsVarname+siHook, hookchannels);
|
||||
SetLocalObject(oMod, sHookOwnerVarname+siHook, hookowner);
|
||||
SetLocalInt(oMod, sHookRangeModeVarname+siHook, hookparty);
|
||||
SetLocalInt(oMod, sHookBcastDMsVarname+siHook, hookbcast);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeleteLocalInt(oMod, sHookTypeVarname+siHook);
|
||||
DeleteLocalObject(oMod, sHookCreatureVarname+siHook);
|
||||
DeleteLocalLocation(oMod, sHookLocationVarname+siHook);
|
||||
DeleteLocalInt(oMod, sHookChannelsVarname+siHook);
|
||||
DeleteLocalObject(oMod, sHookOwnerVarname+siHook);
|
||||
DeleteLocalInt(oMod, sHookRangeModeVarname+siHook);
|
||||
DeleteLocalInt(oMod, sHookBcastDMsVarname+siHook);
|
||||
|
||||
break;
|
||||
}
|
||||
iHook++;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
int AppendListenerHook(int hooktype, object hookcreature, location hooklocation,
|
||||
int hookchannels, int hookparty, int hookbcast, object hookowner)
|
||||
{
|
||||
int iHook = 0;
|
||||
|
||||
if (hooktype != 0)
|
||||
{
|
||||
int iHookType;
|
||||
string siHook = "";
|
||||
object oMod = GetModule();
|
||||
iHook = 1;
|
||||
while (1)
|
||||
{
|
||||
siHook = IntToString(iHook);
|
||||
iHookType = GetLocalInt(oMod, sHookTypeVarname+siHook);
|
||||
if (iHookType == 0) break; // end of list
|
||||
iHook++;
|
||||
}
|
||||
SetLocalInt(oMod, sHookTypeVarname+siHook, hooktype);
|
||||
SetLocalObject(oMod, sHookCreatureVarname+siHook, hookcreature);
|
||||
SetLocalLocation(oMod, sHookLocationVarname+siHook, hooklocation);
|
||||
SetLocalInt(oMod, sHookChannelsVarname+siHook, hookchannels);
|
||||
SetLocalObject(oMod, sHookOwnerVarname+siHook, hookowner);
|
||||
SetLocalInt(oMod, sHookRangeModeVarname+siHook, hookparty);
|
||||
SetLocalInt(oMod, sHookBcastDMsVarname+siHook, hookbcast);
|
||||
}
|
||||
|
||||
return iHook;
|
||||
}
|
||||
|
3911
_module/nss/dmfi_plychat_exe.nss
Normal file
3911
_module/nss/dmfi_plychat_exe.nss
Normal file
File diff suppressed because it is too large
Load Diff
142
_module/nss/dmfi_plychat_inc.nss
Normal file
142
_module/nss/dmfi_plychat_inc.nss
Normal file
@@ -0,0 +1,142 @@
|
||||
|
||||
// DMFI OnPlayerChat routines :: event hooking functions
|
||||
//
|
||||
// history
|
||||
// 2008.03.23 tsunami282 - created.
|
||||
//
|
||||
|
||||
#include "dmfi_arrays_inc"
|
||||
|
||||
const string DMFI_CHATHOOK_HANDLE_ARRAYNAME = "DMFI_CHATHOOK_HANDLE";
|
||||
const string DMFI_CHATHOOK_SCRIPT_ARRAYNAME = "DMFI_CHATHOOK_SCRIPT";
|
||||
const string DMFI_CHATHOOK_RUNNER_ARRAYNAME = "DMFI_CHATHOOK_RUNNER";
|
||||
const string DMFI_CHATHOOK_CHANNELS_ARRAYNAME = "DMFI_CHATHOOK_CHANNELS";
|
||||
const string DMFI_CHATHOOK_LISTENALL_ARRAYNAME = "DMFI_CHATHOOK_LISTENALL";
|
||||
const string DMFI_CHATHOOK_SPEAKER_ARRAYNAME = "DMFI_CHATHOOK_SPEAKER";
|
||||
const string DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME = "DMFI_CHATHOOK_AUTOREMOVE";
|
||||
const string DMFI_CHATHOOK_PREVHANDLE_VARNAME = "DMFI_CHATHOOK_PREVHANDLE";
|
||||
|
||||
int DMFI_CHANNELMASK_TALK = (1 << TALKVOLUME_TALK);
|
||||
int DMFI_CHANNELMASK_WHISPER = (1 << TALKVOLUME_WHISPER);
|
||||
int DMFI_CHANNELMASK_SHOUT = (1 << TALKVOLUME_SHOUT);
|
||||
// * this channel not hookable ** int DMFI_CHANNELMASK_SILENT_TALK = (1 << TALKVOLUME_SILENT_TALK);
|
||||
int DMFI_CHANNELMASK_DM = (1 << TALKVOLUME_SILENT_SHOUT);
|
||||
int DMFI_CHANNELMASK_PARTY = (1 << TALKVOLUME_PARTY);
|
||||
// * this channel not hookable ** int DMFI_CHANNELMASK_TELL = (1 << TALKVOLUME_TELL);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void dmfi__init_chathook_data()
|
||||
{
|
||||
object oMod = GetModule();
|
||||
|
||||
if (!GetLocalArrayInitialized(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME))
|
||||
{
|
||||
InitializeLocalArray(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME);
|
||||
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, 1);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, 0);
|
||||
InitializeLocalArray(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME);
|
||||
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, 1);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, 0);
|
||||
InitializeLocalArray(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME);
|
||||
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, 1);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, 0);
|
||||
InitializeLocalArray(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME);
|
||||
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, 1);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, 0);
|
||||
InitializeLocalArray(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME);
|
||||
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, 1);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, 0);
|
||||
InitializeLocalArray(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME);
|
||||
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, 1);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, 0);
|
||||
InitializeLocalArray(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME);
|
||||
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, 1);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, 0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//! Adds a callback function to the OnPlayerChat list.
|
||||
//!
|
||||
//! \param sChatHandlerScript name of script to invoke on receiving input
|
||||
//! \param oScriptRunner object to execute the sChatHandlerScript on
|
||||
//! \param maskChannels mask of channels to listen on (defaults to all channels)
|
||||
//! \param bListenAll TRUE to listen to all PC speakers everywhere
|
||||
//! \param oSpeaker if bListenAll is FALSE, creature to listen to (others will be ignored)
|
||||
//! \param bAutoRemove - automatically unhook this chathook after first use
|
||||
//! \return hook handle (needed to remove the hook later); 0 means failed to add the hook
|
||||
int DMFI_ChatHookAdd(string sChatHandlerScript, object oScriptRunner = OBJECT_SELF,
|
||||
int maskChannels = -1, int bListenAll = TRUE, object oSpeaker = OBJECT_INVALID,
|
||||
int bAutoRemove = FALSE)
|
||||
{
|
||||
dmfi__init_chathook_data();
|
||||
|
||||
object oMod = GetModule();
|
||||
|
||||
int iHook = GetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME);
|
||||
iHook++;
|
||||
int hdlHook = GetLocalInt(oMod, DMFI_CHATHOOK_PREVHANDLE_VARNAME);
|
||||
hdlHook++;
|
||||
if (hdlHook < 1) hdlHook = 1; // reserving 0 and negatives
|
||||
// SendMessageToPC(GetFirstPC(), "chathookadd - adding hook #" + IntToString(iHook));
|
||||
SetLocalInt(oMod, DMFI_CHATHOOK_PREVHANDLE_VARNAME, hdlHook);
|
||||
SetLocalArrayInt(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, iHook, hdlHook);
|
||||
SetLocalArrayString(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, iHook, sChatHandlerScript);
|
||||
SetLocalArrayObject(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, iHook, oScriptRunner);
|
||||
SetLocalArrayInt(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, iHook, maskChannels);
|
||||
SetLocalArrayInt(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, iHook, bListenAll);
|
||||
SetLocalArrayObject(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, iHook, oSpeaker);
|
||||
SetLocalArrayInt(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, iHook, bAutoRemove);
|
||||
|
||||
return hdlHook;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//! removes a callback function from the OnPlayerChat list.
|
||||
//! \param hdlHookIn handle of hook to remove (0 for clean up orphans)
|
||||
//! \return TRUE if requested hook found and removed
|
||||
int DMFI_ChatHookRemove(int hdlHookIn)
|
||||
{
|
||||
int bRemoved = FALSE;
|
||||
int hdlHook;
|
||||
int iHook, iHook2;
|
||||
object oMod = GetModule();
|
||||
int nHooks = GetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME);
|
||||
for (iHook = 1; iHook <= nHooks; iHook++)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
hdlHook = GetLocalArrayInt(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, iHook);
|
||||
if (hdlHook != 0 && hdlHook != hdlHookIn) break;
|
||||
|
||||
// kill this one
|
||||
for (iHook2 = iHook; iHook2 < nHooks; iHook2++)
|
||||
{
|
||||
SetLocalArrayInt(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, iHook2, GetLocalArrayInt(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, iHook2+1));
|
||||
SetLocalArrayString(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, iHook2, GetLocalArrayString(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, iHook2+1));
|
||||
SetLocalArrayObject(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, iHook2, GetLocalArrayObject(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, iHook2+1));
|
||||
SetLocalArrayInt(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, iHook2, GetLocalArrayInt(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, iHook2+1));
|
||||
SetLocalArrayInt(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, iHook2, GetLocalArrayInt(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, iHook2+1));
|
||||
SetLocalArrayObject(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, iHook2, GetLocalArrayObject(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, iHook2+1));
|
||||
SetLocalArrayInt(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, iHook2, GetLocalArrayInt(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, iHook2+1));
|
||||
}
|
||||
bRemoved = TRUE;
|
||||
nHooks--;
|
||||
if (nHooks < iHook) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bRemoved)
|
||||
{
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, nHooks);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, nHooks);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, nHooks);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, nHooks);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, nHooks);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, nHooks);
|
||||
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, nHooks);
|
||||
}
|
||||
|
||||
return bRemoved;
|
||||
}
|
||||
|
71
_module/nss/dmfi_string_inc.nss
Normal file
71
_module/nss/dmfi_string_inc.nss
Normal file
@@ -0,0 +1,71 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: DMFI - string functions and constants
|
||||
//:: dmfi_string_inc
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Library of functions relating to strings for DMFI.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: tsunami282
|
||||
//:: Created On: 2008.08.11
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "x3_inc_string"
|
||||
|
||||
const string DMFI_MESSAGE_COLOR_ALERT = "733"; // default 733 - brite red
|
||||
const string DMFI_MESSAGE_COLOR_STATUS = "773"; // default 773 - yellow
|
||||
const string DMFI_MESSAGE_COLOR_EAVESDROP = "777"; // default 777 - white
|
||||
const string DMFI_MESSAGE_COLOR_TRANSLATION = "555"; // default 733 - lite gray
|
||||
const string DMFI_MESSAGE_COLOR_OTHER = ""; // default blank
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
string LTrim(string sTrimMe, string sDelim = " ")
|
||||
{
|
||||
int l;
|
||||
|
||||
if (sDelim != "")
|
||||
{
|
||||
l = GetStringLength(sTrimMe);
|
||||
while (GetStringLeft(sTrimMe, 1) == sDelim)
|
||||
{
|
||||
l--;
|
||||
if (l < 1)
|
||||
{
|
||||
sTrimMe = "";
|
||||
break;
|
||||
}
|
||||
sTrimMe = GetStringRight(sTrimMe, l);
|
||||
}
|
||||
}
|
||||
|
||||
return sTrimMe;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void DMFISendMessageToPC(object oPC, string sMsg, int bAllDMs=FALSE,
|
||||
string sRGB="")
|
||||
{
|
||||
string sColMsg;
|
||||
object oTarget = oPC;
|
||||
if (bAllDMs) oTarget = GetFirstPC();
|
||||
while (GetIsObjectValid(oTarget))
|
||||
{
|
||||
if ((!bAllDMs) || (GetIsDM(oTarget) || GetIsDMPossessed(oTarget)))
|
||||
{
|
||||
if (sRGB != "")
|
||||
{
|
||||
sColMsg = StringToRGBString(sMsg, sRGB);
|
||||
}
|
||||
else
|
||||
{
|
||||
sColMsg = sMsg;
|
||||
}
|
||||
SendMessageToPC(oTarget, sColMsg);
|
||||
}
|
||||
|
||||
if (!bAllDMs) break;
|
||||
oTarget = GetNextPC();
|
||||
}
|
||||
|
||||
}
|
||||
|
12
_module/nss/dmfi_unact_nam02.nss
Normal file
12
_module/nss/dmfi_unact_nam02.nss
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include "dmfi_getln_inc"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oListener = OBJECT_SELF;
|
||||
object oPC = GetPCSpeaker();
|
||||
|
||||
// attach our listener event
|
||||
SetLocalString(oListener, "dmfi_getln_mode", "name");
|
||||
DMFI_get_line(oPC, TALKVOLUME_TALK, "dmfi_univ_listen", oListener);
|
||||
}
|
6
_module/nss/dmfi_unact_nam03.nss
Normal file
6
_module/nss/dmfi_unact_nam03.nss
Normal file
@@ -0,0 +1,6 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
SetName(oTarget, "");
|
||||
}
|
8
_module/nss/dmfi_unact_nam04.nss
Normal file
8
_module/nss/dmfi_unact_nam04.nss
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
#include "dmfi_getln_inc"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oListener = OBJECT_SELF;
|
||||
DMFI_cancel_get_line(0, oListener);
|
||||
}
|
12
_module/nss/dmfi_unact_nam06.nss
Normal file
12
_module/nss/dmfi_unact_nam06.nss
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#include "dmfi_getln_inc"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oListener = OBJECT_SELF;
|
||||
object oPC = GetPCSpeaker();
|
||||
|
||||
// attach our listener event
|
||||
SetLocalString(oListener, "dmfi_getln_mode", "desc");
|
||||
DMFI_get_line(oPC, TALKVOLUME_TALK, "dmfi_univ_listen", oListener);
|
||||
}
|
6
_module/nss/dmfi_unact_nam07.nss
Normal file
6
_module/nss/dmfi_unact_nam07.nss
Normal file
@@ -0,0 +1,6 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
SetName(oTarget, "");
|
||||
}
|
8
_module/nss/dmfi_unact_nam08.nss
Normal file
8
_module/nss/dmfi_unact_nam08.nss
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
#include "dmfi_getln_inc"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oListener = OBJECT_SELF;
|
||||
DMFI_cancel_get_line(0, oListener);
|
||||
}
|
13
_module/nss/dmfi_uncnd_nam01.nss
Normal file
13
_module/nss/dmfi_uncnd_nam01.nss
Normal file
@@ -0,0 +1,13 @@
|
||||
int StartingConditional()
|
||||
{
|
||||
// set the custom tokens
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
|
||||
string sName = GetName(oTarget);
|
||||
SetCustomToken(20680, sName);
|
||||
string sOrigName = GetName(oTarget, TRUE);
|
||||
SetCustomToken(20681, sOrigName);
|
||||
|
||||
return TRUE;
|
||||
}
|
13
_module/nss/dmfi_uncnd_nam05.nss
Normal file
13
_module/nss/dmfi_uncnd_nam05.nss
Normal file
@@ -0,0 +1,13 @@
|
||||
int StartingConditional()
|
||||
{
|
||||
// set the custom tokens
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
|
||||
string sName = GetDescription(oTarget);
|
||||
SetCustomToken(20682, sName);
|
||||
string sOrigName = GetDescription(oTarget, TRUE);
|
||||
SetCustomToken(20683, sOrigName);
|
||||
|
||||
return TRUE;
|
||||
}
|
26
_module/nss/dmfi_univ_1.nss
Normal file
26
_module/nss/dmfi_univ_1.nss
Normal file
@@ -0,0 +1,26 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||
|
||||
if (GetLocalInt(oPC, "Tens"))
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 1);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering")
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 1);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
}
|
||||
else
|
||||
SetLocalInt(oPC, "Tens", 1);
|
||||
return;
|
||||
}
|
||||
}
|
27
_module/nss/dmfi_univ_10.nss
Normal file
27
_module/nss/dmfi_univ_10.nss
Normal file
@@ -0,0 +1,27 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||
|
||||
if (GetLocalInt(oPC, "Tens"))
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens"));
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sConv == "voice" || sConv == "pc_emote" || sConv == "faction")
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 10);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
return;
|
||||
}
|
||||
else
|
||||
SetLocalInt(oPC, "Tens", 10);
|
||||
return;
|
||||
}
|
||||
}
|
26
_module/nss/dmfi_univ_2.nss
Normal file
26
_module/nss/dmfi_univ_2.nss
Normal file
@@ -0,0 +1,26 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||
|
||||
if (GetLocalInt(oPC, "Tens"))
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 2);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering")
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 2);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
}
|
||||
else
|
||||
SetLocalInt(oPC, "Tens", 2);
|
||||
return;
|
||||
}
|
||||
}
|
27
_module/nss/dmfi_univ_3.nss
Normal file
27
_module/nss/dmfi_univ_3.nss
Normal file
@@ -0,0 +1,27 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||
|
||||
if (GetLocalInt(oPC, "Tens"))
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 3);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering")
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 3);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
return;
|
||||
}
|
||||
else
|
||||
SetLocalInt(oPC, "Tens", 3);
|
||||
return;
|
||||
}
|
||||
}
|
27
_module/nss/dmfi_univ_4.nss
Normal file
27
_module/nss/dmfi_univ_4.nss
Normal file
@@ -0,0 +1,27 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||
|
||||
if (GetLocalInt(oPC, "Tens"))
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 4);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering")
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 4);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
return;
|
||||
}
|
||||
else
|
||||
SetLocalInt(oPC, "Tens", 4);
|
||||
return;
|
||||
}
|
||||
}
|
27
_module/nss/dmfi_univ_5.nss
Normal file
27
_module/nss/dmfi_univ_5.nss
Normal file
@@ -0,0 +1,27 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||
|
||||
if (GetLocalInt(oPC, "Tens"))
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 5);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering")
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 5);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
return;
|
||||
}
|
||||
else
|
||||
SetLocalInt(oPC, "Tens", 5);
|
||||
return;
|
||||
}
|
||||
}
|
28
_module/nss/dmfi_univ_6.nss
Normal file
28
_module/nss/dmfi_univ_6.nss
Normal file
@@ -0,0 +1,28 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||
|
||||
if (GetLocalInt(oPC, "Tens"))
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 6);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sConv == "pc_emote" || sConv == "emote" ||
|
||||
sConv == "server" || sConv == "onering")
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 6);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
return;
|
||||
}
|
||||
else
|
||||
SetLocalInt(oPC, "Tens", 6);
|
||||
return;
|
||||
}
|
||||
}
|
27
_module/nss/dmfi_univ_7.nss
Normal file
27
_module/nss/dmfi_univ_7.nss
Normal file
@@ -0,0 +1,27 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||
|
||||
if (GetLocalInt(oPC, "Tens"))
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 7);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering" || sConv == "rest")
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 7);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
return;
|
||||
}
|
||||
else
|
||||
SetLocalInt(oPC, "Tens", 7);
|
||||
return;
|
||||
}
|
||||
}
|
28
_module/nss/dmfi_univ_8.nss
Normal file
28
_module/nss/dmfi_univ_8.nss
Normal file
@@ -0,0 +1,28 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||
|
||||
if (GetLocalInt(oPC, "Tens"))
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 8);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(( sConv == "server") || (sConv == "xp") ||
|
||||
(sConv == "voice") || (sConv == "onering") || (sConv == "rest"))
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 8);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
return;
|
||||
}
|
||||
else
|
||||
SetLocalInt(oPC, "Tens", 8);
|
||||
return;
|
||||
}
|
||||
}
|
27
_module/nss/dmfi_univ_9.nss
Normal file
27
_module/nss/dmfi_univ_9.nss
Normal file
@@ -0,0 +1,27 @@
|
||||
void main()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||
|
||||
if (GetLocalInt(oPC, "Tens"))
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 9);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sConv == "server" || sConv == "voice" || sConv == "faction" || sConv == "rest")
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_int", 9);
|
||||
ExecuteScript("dmfi_execute", oPC);
|
||||
return;
|
||||
}
|
||||
else
|
||||
SetLocalInt(oPC, "Tens", 9);
|
||||
return;
|
||||
}
|
||||
}
|
363
_module/nss/dmfi_univ_cond.nss
Normal file
363
_module/nss/dmfi_univ_cond.nss
Normal file
@@ -0,0 +1,363 @@
|
||||
//DMFI Universal Wand scripts by hahnsoo
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//This initializes the rest dialog.
|
||||
//If limited by Time, report how long it will take before the PC can rest again
|
||||
//If DM, tell the DM the interval of time between rests.
|
||||
//If limited by placeable, report that the PC needs a restable object nearby
|
||||
//If DM, tell the DM that the rest is limited by placeables.
|
||||
//If limited by Armor, report that the PC is wearing armor that prevents resting
|
||||
//If DM, tell the DM that the rest is limited by armor weight.
|
||||
//If in an area that doesn't allow spell memorization, report this to the PC
|
||||
//If DM, tell the DM that spell memorization is restricted in this area.
|
||||
//If hit point restrictions are "up", tell the PC how many hitpoints they would gain by resting
|
||||
//If DM, tell the DM what level of Hitpoint restrictions are in effect.
|
||||
void SetRestTokens(object oPC)
|
||||
{
|
||||
object oArea = GetArea(oPC);
|
||||
int iSettings = GetLocalInt(oPC, "dmfi_r_settings");
|
||||
int iMinutesPerHour = FloatToInt(HoursToSeconds(1))/60;
|
||||
SetCustomToken(20792, IntToString(iMinutesPerHour));
|
||||
SetCustomToken(20793, IntToString(iMinutesPerHour * 2));
|
||||
SetCustomToken(20794, IntToString(iMinutesPerHour * 4));
|
||||
SetCustomToken(20795, IntToString(iMinutesPerHour * 6));
|
||||
SetCustomToken(20796, IntToString(iMinutesPerHour * 8));
|
||||
SetCustomToken(20797, IntToString(iMinutesPerHour * 12));
|
||||
SetCustomToken(20798, IntToString(iMinutesPerHour * 24));
|
||||
|
||||
if (GetIsDM(oPC))
|
||||
{
|
||||
string sRest = "";
|
||||
if (iSettings & 0x00000080)
|
||||
{
|
||||
SetCustomToken(20789, "[LOCAL]");
|
||||
sRest = sRest + "[LOCAL] settings in effect";
|
||||
if (iSettings & 0x00000002)
|
||||
sRest = sRest + "\nThis is a No Rest area";
|
||||
else if (!(iSettings & 0x00000001))
|
||||
sRest = sRest + "\nThis is an Unlimited Rest area";
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCustomToken(20789, "[GLOBAL]");
|
||||
sRest = sRest + "[GLOBAL] settings in effect";
|
||||
if (iSettings & 0x00000002)
|
||||
sRest = sRest + "\nNo Rest is set globally";
|
||||
else if (!(iSettings & 0x00000001))
|
||||
sRest = sRest + "\nUnlimited Rest is set globally";
|
||||
}
|
||||
if (iSettings & 0x00000004)
|
||||
{
|
||||
sRest = sRest + "\nRest is limited by Time: ";
|
||||
switch (iSettings & 0x00000f00)
|
||||
{
|
||||
default:
|
||||
case 0x00000100: sRest = sRest + "1 hour"; break;
|
||||
case 0x00000200: sRest = sRest + "2 hours"; break;
|
||||
case 0x00000300: sRest = sRest + "4 hours"; break;
|
||||
case 0x00000400: sRest = sRest + "6 hours"; break;
|
||||
case 0x00000500: sRest = sRest + "8 hours"; break;
|
||||
case 0x00000600: sRest = sRest + "12 hours"; break;
|
||||
case 0x00000700: sRest = sRest + "24 hours"; break;
|
||||
}
|
||||
}
|
||||
if (iSettings & 0x00000008) //Placeables
|
||||
{
|
||||
sRest = sRest + "\nRest is limited by Placeables: ";
|
||||
if (!(iSettings & 0x00001000)) sRest = sRest + "DMFI_placeables ";
|
||||
if (iSettings & 0x00002000) sRest = sRest + "Campfires ";
|
||||
if (iSettings & 0x00004000) sRest = sRest + "Bed_Rolls ";
|
||||
if (iSettings & 0x00008000) sRest = sRest + "Beds ";
|
||||
if (iSettings & 0x00010000) sRest = sRest + "Tents ";
|
||||
if ((iSettings & 0x00020000) || (iSettings & 0x00040000) || (iSettings & 0x00080000))
|
||||
{
|
||||
sRest = sRest + "\nClasses that ignore restrictions: ";
|
||||
if (iSettings & 0x00020000) sRest = sRest + "Druids ";
|
||||
if (iSettings & 0x00040000) sRest = sRest + "Rangers ";
|
||||
if (iSettings & 0x00080000) sRest = sRest + "Barbarians ";
|
||||
}
|
||||
}
|
||||
if (iSettings & 0x00000010) //Armor
|
||||
{
|
||||
sRest = sRest + "\nRest is limited by Armor: ";
|
||||
switch (iSettings & 0x00f00000)
|
||||
{
|
||||
default:
|
||||
case 0x00100000: sRest = sRest + "2 pounds"; break;
|
||||
case 0x00200000: sRest = sRest + "6 pounds"; break;
|
||||
case 0x00300000: sRest = sRest + "11 pounds"; break;
|
||||
case 0x00400000: sRest = sRest + "16 pounds"; break;
|
||||
case 0x00500000: sRest = sRest + "31 pounds"; break;
|
||||
case 0x00600000: sRest = sRest + "41 pounds"; break;
|
||||
case 0x00700000: sRest = sRest + "46 pounds"; break;
|
||||
}
|
||||
}
|
||||
if (iSettings & 0x00000020) //Hit point limits
|
||||
{
|
||||
sRest = sRest + "\nHit points are limited to: ";
|
||||
switch (iSettings & 0x0f000000)
|
||||
{
|
||||
case 0x01000000: sRest = sRest + "0 HP"; break;
|
||||
case 0x02000000: sRest = sRest + "1 HP/level"; break;
|
||||
case 0x03000000: sRest = sRest + "(CON) HP"; break;
|
||||
case 0x04000000: sRest = sRest + "10 percent of max"; break;
|
||||
case 0x05000000: sRest = sRest + "25 percent of max"; break;
|
||||
case 0x06000000: sRest = sRest + "50 percent of max"; break;
|
||||
default:
|
||||
case 0x07000000: sRest = sRest + "100 percent"; break;
|
||||
}
|
||||
}
|
||||
if (iSettings & 0x00000040) //Spell memorization
|
||||
{
|
||||
sRest = sRest + "\nSpell memorization is OFF";
|
||||
}
|
||||
SetCustomToken(20791, sRest);
|
||||
}
|
||||
else //For PCs
|
||||
{ //Setting rest tokens
|
||||
string sRest = "";
|
||||
if (iSettings & 0x00000080)
|
||||
{
|
||||
if (iSettings & 0x00000002)
|
||||
sRest = sRest + "\nThis is a No Rest area";
|
||||
else if (!(iSettings & 0x00000001))
|
||||
sRest = sRest + "\nThis is an Unlimited Rest area";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iSettings & 0x00000002)
|
||||
sRest = sRest + "\nNo Rest is set globally";
|
||||
else if (!(iSettings & 0x00000001))
|
||||
sRest = sRest + "\nUnlimited Rest is set globally";
|
||||
}
|
||||
if (iSettings & 0x00000004 && iSettings & 0x00000001)
|
||||
{
|
||||
int iTime = GetTimeHour() + GetCalendarDay() * 24 + GetCalendarMonth() * 24 * 28 + GetCalendarYear() * 24 * 28 * 12;
|
||||
int iNext = GetLocalInt(oPC, "dmfi_r_nextrest");
|
||||
if (iNext > iTime)
|
||||
sRest = sRest + "\nYou may rest again in " + IntToString(iNext - iTime) + " hours";
|
||||
}
|
||||
if (iSettings & 0x00000008 && iSettings & 0x00000001) //Placeables
|
||||
{
|
||||
if (!(GetLevelByClass(CLASS_TYPE_DRUID, oPC) && (iSettings & 0x00020000)) ||
|
||||
!(GetLevelByClass(CLASS_TYPE_RANGER, oPC) && (iSettings & 0x00040000)) ||
|
||||
!(GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC) && (iSettings & 0x00080000)))
|
||||
{
|
||||
object oPlaceable = GetFirstObjectInShape(SHAPE_SPHERE, 6.0f, GetLocation(oPC), TRUE, OBJECT_TYPE_PLACEABLE);
|
||||
int iBreak = 0;
|
||||
while (GetIsObjectValid(oPlaceable) && !iBreak)
|
||||
{
|
||||
if (!(iSettings & 0x00001000) && GetTag(oPlaceable) == "dmfi_rest") //DMFI Placeables: by default, ON
|
||||
iBreak = 1;
|
||||
if ((iSettings & 0x00002000) && GetStringLowerCase(GetName(oPlaceable)) == "campfire") //Campfires
|
||||
iBreak = 1;
|
||||
if ((iSettings & 0x00004000) && (GetStringLowerCase(GetName(oPlaceable)) == "bed roll" || GetStringLowerCase(GetName(oPlaceable)) == "bedroll")) //Bed rolls
|
||||
iBreak = 1;
|
||||
if ((iSettings & 0x00008000) && GetStringLowerCase(GetName(oPlaceable)) == "bed") //beds
|
||||
iBreak = 1;
|
||||
if ((iSettings & 0x00010000) && GetStringLowerCase(GetName(oPlaceable)) == "tent") //tents
|
||||
iBreak = 1;
|
||||
oPlaceable = GetNextObjectInShape(SHAPE_SPHERE, 6.0f, GetLocation(oPC), TRUE, OBJECT_TYPE_PLACEABLE);
|
||||
}
|
||||
if (!iBreak)
|
||||
{
|
||||
sRest = sRest + "\nYou are not near a rest placeable";
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((iSettings & 0x00000010) && iSettings & 0x00000001)//Armor
|
||||
{
|
||||
int iArmor = (iSettings & 0x00f00000);
|
||||
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oPC);
|
||||
int iWeight = GetWeight(oArmor);
|
||||
switch(iArmor)
|
||||
{
|
||||
default:
|
||||
case 0x00100000: if (iWeight > 20) sRest = sRest + "\nYou cannot rest in armor heavier than Clothing"; break;
|
||||
case 0x00200000: if (iWeight > 60) sRest = sRest + "\nYou cannot rest in armor heavier than Padded"; break;
|
||||
case 0x00300000: if (iWeight > 110) sRest = sRest + "\nYou cannot rest in armor heavier than Leather"; break;
|
||||
case 0x00400000: if (iWeight > 160) sRest = sRest + "\nYou cannot rest in armor heavier than Studded Leather"; break;
|
||||
case 0x00500000: if (iWeight > 310) sRest = sRest + "\nYou cannot rest in armor heavier than Chain Shirt"; break;
|
||||
case 0x00600000: if (iWeight > 410) sRest = sRest + "\nYou cannot rest in armor heavier than Chain Mail"; break;
|
||||
case 0x00700000: if (iWeight > 460) sRest = sRest + "\nYou cannot rest in armor heavier than Banded Mail"; break;
|
||||
}
|
||||
}
|
||||
if (iSettings & 0x00000020 && iSettings & 0x00000001) //Hit point limits
|
||||
{
|
||||
sRest = sRest + "\nOn Rest, you will regain ";
|
||||
switch (iSettings & 0x0f000000)
|
||||
{
|
||||
case 0x01000000: sRest = sRest + "0 HP"; break;
|
||||
case 0x02000000: sRest = sRest + IntToString(GetHitDice(oPC)) + " HP"; break;
|
||||
case 0x03000000: sRest = sRest + IntToString(GetAbilityScore(oPC, ABILITY_CONSTITUTION)) + " HP"; break;
|
||||
case 0x04000000: sRest = sRest + IntToString(GetMaxHitPoints(oPC)/10) + " HP"; break;
|
||||
case 0x05000000: sRest = sRest + IntToString(GetMaxHitPoints(oPC)/4) + " HP"; break;
|
||||
case 0x06000000: sRest = sRest + IntToString(GetMaxHitPoints(oPC)/2) + " HP"; break;
|
||||
default:
|
||||
case 0x07000000: sRest = sRest + "full HP"; break;
|
||||
}
|
||||
sRest = sRest + "\nResting will drop you from the party";
|
||||
}
|
||||
if (iSettings & 0x00000040 && iSettings & 0x00000001) //Spell memorization
|
||||
{
|
||||
sRest = sRest + "\nYou cannot memorize spells here";
|
||||
}
|
||||
SetCustomToken(20790, sRest);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
int StartingConditional()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
int iOffset = GetLocalInt(oPC, "dmfi_univ_offset")+1;
|
||||
string sOffset = GetLocalString(oPC, "dmfi_univ_conv");
|
||||
SetLocalInt(oPC, "dmfi_univ_offset", iOffset);
|
||||
|
||||
if (sOffset == "afflict" && iOffset==1)
|
||||
return TRUE;
|
||||
else if (sOffset == "pc_emote" && iOffset==2)
|
||||
return TRUE;
|
||||
else if (sOffset == "emote" && iOffset==2)
|
||||
return TRUE;
|
||||
else if (sOffset == "encounter" && iOffset==3)
|
||||
return TRUE;
|
||||
else if (sOffset == "fx" && iOffset==4)
|
||||
return TRUE;
|
||||
else if (sOffset == "music" && iOffset==5)
|
||||
return TRUE;
|
||||
else if (sOffset == "sound" && iOffset==6)
|
||||
return TRUE;
|
||||
else if (sOffset == "xp" && iOffset==7)
|
||||
return TRUE;
|
||||
else if (sOffset == "onering" && iOffset==8)
|
||||
return TRUE;
|
||||
else if (sOffset == "pc_dicebag" && iOffset==9)
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_offset", 8);
|
||||
|
||||
if (GetLocalInt(oPC, "dmfi_dicebag")==0)
|
||||
SetCustomToken(20681, "Private");
|
||||
else if (GetLocalInt(oPC, "dmfi_dicebag")==1)
|
||||
SetCustomToken(20681, "Global");
|
||||
else if (GetLocalInt(oPC, "dmfi_dicebag")==2)
|
||||
SetCustomToken(20681, "Local");
|
||||
else if (GetLocalInt(oPC, "dmfi_dicebag")==3)
|
||||
SetCustomToken(20681, "DM Only");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (sOffset == "dicebag" && iOffset==10)
|
||||
{
|
||||
SetLocalInt(oPC, "dmfi_univ_offset", 9);
|
||||
|
||||
if (GetLocalInt(oPC, "dmfi_dicebag")==0)
|
||||
SetCustomToken(20681, "Private");
|
||||
else if (GetLocalInt(oPC, "dmfi_dicebag")==1)
|
||||
SetCustomToken(20681, "Global");
|
||||
else if (GetLocalInt(oPC, "dmfi_dicebag")==2)
|
||||
SetCustomToken(20681, "Local");
|
||||
else if (GetLocalInt(oPC, "dmfi_dicebag")==3)
|
||||
SetCustomToken(20681, "DM Only");
|
||||
|
||||
string sName = GetName(GetLocalObject(oPC, "dmfi_univ_target"));
|
||||
SetCustomToken(20680, sName);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (sOffset == "voice" &&
|
||||
GetIsObjectValid(GetLocalObject(oPC, "dmfi_univ_target")) &&
|
||||
oPC != GetLocalObject(oPC, "dmfi_univ_target") &&
|
||||
iOffset==11)
|
||||
{
|
||||
string sName = GetName(GetLocalObject(oPC, "dmfi_univ_target"));
|
||||
SetCustomToken(20680, sName);
|
||||
// pc range single/party
|
||||
int hookparty = GetLocalInt(oPC, "dmfi_MyListenerPartyMode");
|
||||
if (hookparty == 0) SetCustomToken(20681, "*Single* / Party");
|
||||
else SetCustomToken(20681, "Single / *Party*");
|
||||
return TRUE;
|
||||
}
|
||||
else if (sOffset == "voice" &&
|
||||
!GetIsObjectValid(GetLocalObject(oPC, "dmfi_univ_target")) &&
|
||||
iOffset==12)
|
||||
{
|
||||
string sName = GetName(GetLocalObject(oPC, "dmfi_univ_target"));
|
||||
SetCustomToken(20680, sName);
|
||||
// loc range earshot/area/module
|
||||
int hookparty = GetLocalInt(oPC, "dmfi_MyListenerPartyMode");
|
||||
if (hookparty == 0) SetCustomToken(20681, "*Earshot* / Area / Module");
|
||||
else if (hookparty == 1) SetCustomToken(20681, "Earshot / *Area* / Module");
|
||||
else SetCustomToken(20681, "Earshot / Area / *Module*");
|
||||
return TRUE;
|
||||
}
|
||||
else if (sOffset == "voice" &&
|
||||
GetIsObjectValid(GetLocalObject(oPC, "dmfi_univ_target")) &&
|
||||
oPC == GetLocalObject(oPC, "dmfi_univ_target") &&
|
||||
iOffset==13)
|
||||
{
|
||||
string sName = GetName(GetLocalObject(oPC, "dmfi_univ_target"));
|
||||
SetCustomToken(20680, sName);
|
||||
// self bcast one dm/all dm
|
||||
int hookbcast = GetLocalInt(oPC, "dmfi_MyListenerBcastMode");
|
||||
if (hookbcast == 0) SetCustomToken(20681, "*Self* / All DMs");
|
||||
else SetCustomToken(20681, "Self / *All DMs*");
|
||||
return TRUE;
|
||||
}
|
||||
else if (sOffset == "faction" && iOffset==14)
|
||||
{
|
||||
int iLoop = 1;
|
||||
string sName;
|
||||
object sFaction;
|
||||
while (iLoop < 10)
|
||||
{
|
||||
sFaction = GetLocalObject(oPC, "dmfi_customfaction" + IntToString(iLoop));
|
||||
sName = GetName(sFaction);
|
||||
SetCustomToken(20690 + iLoop, sName + "'s Faction ");
|
||||
iLoop++;
|
||||
}
|
||||
|
||||
SetCustomToken(20690, GetName(GetLocalObject(oPC, "dmfi_henchman")));
|
||||
SetCustomToken(20784, FloatToString(GetLocalFloat(oPC, "dmfi_reputation")));
|
||||
sName = GetName(GetLocalObject(oPC, "dmfi_univ_target"));
|
||||
SetCustomToken(20680, sName);
|
||||
return TRUE;
|
||||
}
|
||||
else if (sOffset == "dmw" && iOffset ==15)
|
||||
{
|
||||
SetCustomToken(20781, IntToString(GetLocalInt(oPC, "dmfi_alignshift")));
|
||||
return TRUE;
|
||||
}
|
||||
else if (sOffset == "buff" && iOffset ==16)
|
||||
{
|
||||
if (GetLocalInt(oPC, "dmfi_buff_party")==0)
|
||||
SetCustomToken(20783, "Single Target");
|
||||
else
|
||||
SetCustomToken(20783, "Party");
|
||||
SetCustomToken(20782, GetLocalString(oPC, "dmfi_buff_level"));
|
||||
return TRUE;
|
||||
}
|
||||
else if (sOffset == "rest" && iOffset == 17 && !GetIsDM(oPC) && GetLocalInt(oPC, "dmfi_norest")) //This is the case of a No-Rest situation
|
||||
{
|
||||
SetRestTokens(oPC);
|
||||
return TRUE;
|
||||
}
|
||||
else if (sOffset == "rest" && iOffset == 18 && !GetIsDM(oPC) && !GetLocalInt(oPC, "dmfi_norest")) //This is the case of a Rest situation
|
||||
{
|
||||
SetRestTokens(oPC);
|
||||
return TRUE;
|
||||
}
|
||||
else if (sOffset == "rest" && iOffset == 19 && GetIsDM(oPC)) //This is the case of a DM activating the rest menu
|
||||
{
|
||||
SetRestTokens(oPC);
|
||||
return TRUE;
|
||||
}
|
||||
else if (sOffset == "naming" && iOffset==20)
|
||||
{
|
||||
string sName = GetName(GetLocalObject(oPC, "dmfi_univ_target"));
|
||||
SetCustomToken(20680, sName);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
334
_module/nss/dmfi_univ_dmw.nss
Normal file
334
_module/nss/dmfi_univ_dmw.nss
Normal file
@@ -0,0 +1,334 @@
|
||||
//DMFI Universal Wand scripts by hahnsoo
|
||||
int DMW_START_CUSTOM_TOKEN = 8000;
|
||||
|
||||
//Retrieve targetting information
|
||||
object oMySpeaker = GetLastSpeaker();
|
||||
object oMyTarget = GetLocalObject(oMySpeaker, "dmfi_univ_target");
|
||||
location lMyLoc = GetLocalLocation(oMySpeaker, "dmfi_univ_location");
|
||||
|
||||
int dmwand_isnearbydestroyable()
|
||||
{
|
||||
object oMyTest = GetFirstObjectInShape(SHAPE_CUBE, 0.6, lMyLoc, FALSE, OBJECT_TYPE_ALL);
|
||||
int nTargetType = GetObjectType(oMyTest);
|
||||
return (GetIsObjectValid(oMyTest) && (! GetIsPC(oMyTest)) && ((nTargetType == OBJECT_TYPE_ITEM) || (nTargetType == OBJECT_TYPE_PLACEABLE) || (nTargetType == OBJECT_TYPE_CREATURE)));
|
||||
}
|
||||
|
||||
int dmwand_istargetcreateable()
|
||||
{
|
||||
if(! GetIsObjectValid(oMyTarget)) { return FALSE; }
|
||||
|
||||
int nTargetType = GetObjectType(oMyTarget);
|
||||
return ((nTargetType == OBJECT_TYPE_ITEM) || (nTargetType == OBJECT_TYPE_PLACEABLE) || (nTargetType == OBJECT_TYPE_CREATURE));
|
||||
}
|
||||
|
||||
int dmwand_istargetdestroyable()
|
||||
{
|
||||
if(! GetIsObjectValid(oMyTarget)) { return FALSE; }
|
||||
|
||||
int nTargetType = GetObjectType(oMyTarget);
|
||||
if(! GetIsPC(oMyTarget))
|
||||
{
|
||||
return ((nTargetType == OBJECT_TYPE_ITEM) || (nTargetType == OBJECT_TYPE_PLACEABLE) || (nTargetType == OBJECT_TYPE_CREATURE));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int dmwand_istargetinvalid()
|
||||
{
|
||||
return !GetIsObjectValid(oMyTarget);
|
||||
}
|
||||
|
||||
int dmwand_istargetinventory()
|
||||
{
|
||||
return (GetIsObjectValid(oMyTarget) && GetHasInventory(oMyTarget));
|
||||
}
|
||||
|
||||
int dmwand_istargetnotme()
|
||||
{
|
||||
return (GetIsObjectValid(oMyTarget) && (oMySpeaker != oMyTarget));
|
||||
}
|
||||
|
||||
int dmwand_istargetpcornpc()
|
||||
{
|
||||
return (GetIsObjectValid(oMyTarget) && GetAbilityScore(oMyTarget, ABILITY_CONSTITUTION));
|
||||
}
|
||||
|
||||
int dmwand_istargetnpc()
|
||||
{
|
||||
return (dmwand_istargetpcornpc() && (! GetIsPC(oMyTarget)));
|
||||
}
|
||||
|
||||
int dmwand_istargetpc()
|
||||
{
|
||||
return (GetIsObjectValid(oMyTarget) && GetIsPC(oMyTarget));
|
||||
}
|
||||
|
||||
int dmwand_istargetpcnme()
|
||||
{
|
||||
return (GetIsObjectValid(oMyTarget) && GetIsPC(oMyTarget) && (oMySpeaker != oMyTarget));
|
||||
}
|
||||
|
||||
int dmwand_istargetpcornpcnme()
|
||||
{
|
||||
return (dmwand_istargetpcornpc() && (oMySpeaker != oMyTarget));
|
||||
}
|
||||
|
||||
int dmwand_istargetplaceable()
|
||||
{
|
||||
if(! GetIsObjectValid(oMyTarget)) { return FALSE; }
|
||||
|
||||
int nTargetType = GetObjectType(oMyTarget);
|
||||
return (nTargetType == OBJECT_TYPE_PLACEABLE);
|
||||
}
|
||||
|
||||
int dmw_conv_Start(int nCurrent, int nChoice, string sParams = "")
|
||||
{
|
||||
string sText = "";
|
||||
string sCall = "";
|
||||
string sCallParams = "";
|
||||
|
||||
switch(nCurrent)
|
||||
{
|
||||
case 0:
|
||||
nCurrent = 0;
|
||||
sText = "Welcome to the Server tool: This will allow you to find any player to perform simple functions.";
|
||||
sCall = "";
|
||||
sCallParams = "";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
nCurrent = 1;
|
||||
if(dmwand_istargetpcnme())
|
||||
{
|
||||
sText = "Penguin this player.";
|
||||
sCall = "func_Toad";
|
||||
sCallParams = "";
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
nCurrent = 2;
|
||||
if(dmwand_istargetpcnme())
|
||||
{
|
||||
sText = "Unpenguin this player.";
|
||||
sCall = "func_Untoad";
|
||||
sCallParams = "";
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
nCurrent = 3;
|
||||
if(dmwand_istargetpcnme())
|
||||
{
|
||||
sText = "Boot this player.";
|
||||
sCall = "func_KickPC";
|
||||
sCallParams = "";
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
nCurrent = 4;
|
||||
if(dmwand_istargetinvalid())
|
||||
{
|
||||
sText = "List all players...";
|
||||
sCall = "conv_ListPlayers";
|
||||
sCallParams = "func_PlayerListConv";
|
||||
break;
|
||||
}
|
||||
|
||||
case 5:
|
||||
nCurrent = 5;
|
||||
if(dmwand_istargetpcnme())
|
||||
{
|
||||
sText = "Jump this player to my location.";
|
||||
sCall = "func_JumpPlayerHere";
|
||||
sCallParams = "";
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
nCurrent = 6;
|
||||
if(dmwand_istargetpcnme())
|
||||
{
|
||||
sText = "Jump me to this player's location.";
|
||||
sCall = "func_JumpToPlayer";
|
||||
sCallParams = "";
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
nCurrent = 7;
|
||||
if(dmwand_istargetpcnme())
|
||||
{
|
||||
sText = "Jump this player's party to my location.";
|
||||
sCall = "func_JumpPartyHere";
|
||||
sCallParams = "";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
nCurrent = 0;
|
||||
sText = "";
|
||||
sCall = "";
|
||||
sCallParams = "";
|
||||
break;
|
||||
}
|
||||
|
||||
SetLocalString(oMySpeaker, "dmw_dialog" + IntToString(nChoice), sText);
|
||||
SetLocalString(oMySpeaker, "dmw_function" + IntToString(nChoice), sCall);
|
||||
SetLocalString(oMySpeaker, "dmw_params" + IntToString(nChoice), sCallParams);
|
||||
|
||||
return nCurrent;
|
||||
}
|
||||
|
||||
int dmwand_BuildConversationDialog(int nCurrent, int nChoice, string sConversation, string sParams)
|
||||
{
|
||||
if(TestStringAgainstPattern(sConversation, "Start"))
|
||||
{
|
||||
return dmw_conv_Start(nCurrent, nChoice, sParams);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void dmwand_BuildConversation(string sConversation, string sParams)
|
||||
{
|
||||
int nLast;
|
||||
int nTemp;
|
||||
int nChoice = 1;
|
||||
int nCurrent = 1;
|
||||
int nMatch;
|
||||
|
||||
if(TestStringAgainstPattern(sParams, "prev"))
|
||||
{
|
||||
//Get the number choice to start with
|
||||
nCurrent = GetLocalInt(oMySpeaker, "dmw_dialogprev");
|
||||
|
||||
//Since we're going to the previous page, there will be a next
|
||||
SetLocalString(oMySpeaker, "dmw_dialog9", "Next ->");
|
||||
SetLocalString(oMySpeaker, "dmw_function9", "conv_" + sConversation);
|
||||
SetLocalString(oMySpeaker, "dmw_params9", "next");
|
||||
SetLocalInt(oMySpeaker, "dmw_dialognext", nCurrent);
|
||||
|
||||
nChoice = 8;
|
||||
for(;nChoice >= 0; nChoice--)
|
||||
{
|
||||
int nTemp1 = nCurrent;
|
||||
int nTemp2 = nCurrent;
|
||||
nMatch = nTemp2;
|
||||
while((nCurrent == nMatch) && (nTemp2 > 0))
|
||||
{
|
||||
nTemp2--;
|
||||
nMatch = dmwand_BuildConversationDialog(nTemp2, nChoice, sConversation, sParams);
|
||||
}
|
||||
|
||||
if(nTemp2 <= 0)
|
||||
{
|
||||
//we went back too far for some reason, so make this choice blank
|
||||
SetLocalString(oMySpeaker, "dmw_dialog" + IntToString(nChoice), "");
|
||||
SetLocalString(oMySpeaker, "dmw_function" + IntToString(nChoice), "");
|
||||
SetLocalString(oMySpeaker, "dmw_params" + IntToString(nChoice), "");
|
||||
}
|
||||
nLast = nTemp;
|
||||
nTemp = nTemp1;
|
||||
nTemp1 = nMatch;
|
||||
nCurrent = nMatch;
|
||||
}
|
||||
|
||||
if(nMatch > 0)
|
||||
{
|
||||
SetLocalString(oMySpeaker, "dmw_dialog1", "<- previous");
|
||||
SetLocalString(oMySpeaker, "dmw_function1", "conv_" + sConversation);
|
||||
SetLocalString(oMySpeaker, "dmw_params1", "prev");
|
||||
SetLocalInt(oMySpeaker, "dmw_dialogprev", nLast);
|
||||
}
|
||||
|
||||
//fill the NPC's dialog spot
|
||||
//(saved for last because the build process tromps on it)
|
||||
dmwand_BuildConversationDialog(0, 0, sConversation, sParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
//fill the NPC's dialog spot
|
||||
dmwand_BuildConversationDialog(0, 0, sConversation, sParams);
|
||||
|
||||
//No parameters specified, start at the top of the conversation
|
||||
if(sParams == "")
|
||||
{
|
||||
nChoice = 1;
|
||||
nCurrent = 1;
|
||||
}
|
||||
|
||||
//A "next->" choice was selected
|
||||
if(TestStringAgainstPattern(sParams, "next"))
|
||||
{
|
||||
//get the number choice to start with
|
||||
nCurrent = GetLocalInt(oMySpeaker, "dmw_dialognext");
|
||||
|
||||
//set this as the number for the "previous" choice to use
|
||||
SetLocalInt(oMySpeaker, "dmw_dialogprev", nCurrent);
|
||||
|
||||
//Set the first dialog choice to be "previous"
|
||||
nChoice = 2;
|
||||
SetLocalString(oMySpeaker, "dmw_dialog1", "<- Previous");
|
||||
SetLocalString(oMySpeaker, "dmw_function1", "conv_" + sConversation);
|
||||
SetLocalString(oMySpeaker, "dmw_params1", "prev");
|
||||
}
|
||||
|
||||
//Loop through to build the dialog list
|
||||
for(;nChoice <= 10; nChoice++)
|
||||
{
|
||||
nMatch = dmwand_BuildConversationDialog(nCurrent, nChoice, sConversation, sParams);
|
||||
//nLast will be the value of the choice before the last one
|
||||
nLast = nTemp;
|
||||
nTemp = nMatch;
|
||||
if(nMatch > 0) { nCurrent = nMatch; }
|
||||
if(nMatch == 0) { nLast = 0; }
|
||||
nCurrent++;
|
||||
}
|
||||
|
||||
//If there were enough choices to fill 10 spots, make spot 9 a "next"
|
||||
if(nLast > 0)
|
||||
{
|
||||
SetLocalString(oMySpeaker, "dmw_dialog9", "Next ->");
|
||||
SetLocalString(oMySpeaker, "dmw_function9", "conv_" + sConversation);
|
||||
SetLocalString(oMySpeaker, "dmw_params9", "next");
|
||||
SetLocalInt(oMySpeaker, "dmw_dialognext", nLast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dmwand_StartConversation()
|
||||
{
|
||||
if(! GetIsObjectValid(oMySpeaker))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dmwand_BuildConversation("Start", "");
|
||||
}
|
||||
|
||||
int StartingConditional()
|
||||
{
|
||||
object oPC = GetPCSpeaker();
|
||||
int nMyNum = 0;
|
||||
|
||||
DeleteLocalInt(oPC, "Tens");
|
||||
DeleteLocalInt(oPC, "dmfi_univ_offset");
|
||||
SetLocalInt(OBJECT_SELF, "dmfi_dmwOffset", 1);
|
||||
//Check whether this conversation has been started already, start it if not.
|
||||
int nStarted = GetLocalInt(oMySpeaker, "dmw_started");
|
||||
if(! nStarted)
|
||||
{
|
||||
SetLocalInt(oMySpeaker, "dmw_started", 1);
|
||||
dmwand_StartConversation();
|
||||
}
|
||||
|
||||
string sMyString = GetLocalString(oMySpeaker, "dmw_dialog" + IntToString(nMyNum));
|
||||
|
||||
if(sMyString == "")
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else if (GetLocalString(oPC, "dmfi_univ_conv") == "server")
|
||||
{
|
||||
SetCustomToken(DMW_START_CUSTOM_TOKEN + nMyNum, sMyString);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
115
_module/nss/dmfi_univ_listen.nss
Normal file
115
_module/nss/dmfi_univ_listen.nss
Normal file
@@ -0,0 +1,115 @@
|
||||
|
||||
// dmfi_univ_listen
|
||||
|
||||
// template: dmfi_getln_cbtpl
|
||||
// triggered from OnPlayerChat callback
|
||||
|
||||
#include "dmfi_db_inc"
|
||||
|
||||
void main()
|
||||
{
|
||||
int nVolume = GetPCChatVolume();
|
||||
object oShouter = GetPCChatSpeaker();
|
||||
string sSaid = GetPCChatMessage();
|
||||
|
||||
// SendMessageToPC(GetFirstPC(), "ENTER dmfi_univ_listen: speaker=" + GetName(oShouter) + ", channel=" + IntToString(nVolume) + ", said=" + sSaid);
|
||||
// first, lets deal with a getln event
|
||||
string getln_mode = GetLocalString(OBJECT_SELF, "dmfi_getln_mode");
|
||||
if (getln_mode == "name")
|
||||
{
|
||||
if (sSaid != ".")
|
||||
{
|
||||
object oTarget = GetLocalObject(oShouter, "dmfi_univ_target");
|
||||
SetName(oTarget, sSaid);
|
||||
}
|
||||
DeleteLocalString(OBJECT_SELF, "dmfi_getln_mode");
|
||||
}
|
||||
else if (getln_mode == "desc")
|
||||
{
|
||||
if (sSaid != ".")
|
||||
{
|
||||
object oTarget = GetLocalObject(oShouter, "dmfi_univ_target");
|
||||
SetDescription(oTarget, sSaid);
|
||||
}
|
||||
DeleteLocalString(OBJECT_SELF, "dmfi_getln_mode");
|
||||
}
|
||||
else
|
||||
{
|
||||
// you may wish to define an "abort" input message, such as a line
|
||||
// containing a single period:
|
||||
if (sSaid != ".")
|
||||
{
|
||||
// put your code here to process the input line (in sSaid)
|
||||
|
||||
if (GetIsDM(oShouter)) SetLocalInt(GetModule(), "dmfi_Admin" + GetPCPublicCDKey(oShouter), 1);
|
||||
if (GetIsDMPossessed(oShouter)) SetLocalObject(GetMaster(oShouter), "dmfi_familiar", oShouter);
|
||||
|
||||
object oTarget = GetLocalObject(oShouter, "dmfi_VoiceTarget");
|
||||
object oMaster = OBJECT_INVALID;
|
||||
if (GetIsObjectValid(oTarget)) oMaster = oShouter;
|
||||
|
||||
int iPhrase = GetLocalInt(oShouter, "hls_EditPhrase");
|
||||
|
||||
object oSummon;
|
||||
|
||||
if (GetIsObjectValid(oShouter) && GetIsDM(oShouter))
|
||||
{
|
||||
if (GetTag(OBJECT_SELF) == "dmfi_setting" && GetLocalString(oShouter, "EffectSetting") != "")
|
||||
{
|
||||
string sPhrase = GetLocalString(oShouter, "EffectSetting");
|
||||
SetLocalFloat(oShouter, sPhrase, StringToFloat(sSaid));
|
||||
SetDMFIPersistentFloat("dmfi", sPhrase, StringToFloat(sSaid), oShouter);
|
||||
DeleteLocalString(oShouter, "EffectSetting");
|
||||
DelayCommand(0.5, ActionSpeakString("The setting " + sPhrase + " has been changed to " + FloatToString(GetLocalFloat(oShouter, sPhrase))));
|
||||
DelayCommand(1.5, DestroyObject(OBJECT_SELF));
|
||||
}
|
||||
}
|
||||
|
||||
if (GetIsObjectValid(oShouter) && GetIsPC(oShouter))
|
||||
{
|
||||
if (sSaid != GetLocalString(GetModule(), "hls_voicebuffer"))
|
||||
{
|
||||
SetLocalString(GetModule(), "hls_voicebuffer", sSaid);
|
||||
|
||||
// PrintString("<Conv>"+GetName(GetArea(oShouter))+ " " + GetName(oShouter) + ": " + sSaid + " </Conv>");
|
||||
|
||||
// if the phrase begins with .MyName, reparse the string as a voice throw
|
||||
if (GetStringLeft(sSaid, GetStringLength("." + GetName(OBJECT_SELF))) == "." + GetName(OBJECT_SELF) &&
|
||||
(GetLocalInt(GetModule(), "dmfi_Admin" + GetPCPublicCDKey(oShouter)) ||
|
||||
GetIsDM(oShouter) || GetIsDMPossessed(oShouter)))
|
||||
{
|
||||
oTarget = OBJECT_SELF;
|
||||
sSaid = GetStringRight(sSaid, GetStringLength(sSaid) - GetStringLength("." + GetName(OBJECT_SELF)));
|
||||
if (GetStringLeft(sSaid, 1) == " ") sSaid = GetStringRight(sSaid, GetStringLength(sSaid) - 1);
|
||||
sSaid = ":" + sSaid;
|
||||
SetPCChatMessage(sSaid);
|
||||
// SendMessageToPC(GetFirstPC(), "LEAVE(1) dmfi_univ_listen: speaker=" + GetName(oShouter) + ", channel=" + IntToString(nVolume) + ", said=" + sSaid);
|
||||
return; // must bail out here to prevent clearing of message at end
|
||||
}
|
||||
|
||||
if (iPhrase)
|
||||
{
|
||||
if (iPhrase > 0)
|
||||
{
|
||||
SetCustomToken(iPhrase, sSaid);
|
||||
SetDMFIPersistentString("dmfi", "hls" + IntToString(iPhrase), sSaid);
|
||||
FloatingTextStringOnCreature("Phrase " + IntToString(iPhrase) + " has been recorded", oShouter, FALSE);
|
||||
}
|
||||
else if (iPhrase < 0)
|
||||
{
|
||||
|
||||
}
|
||||
DeleteLocalInt(oShouter, "hls_EditPhrase");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// after processing, you will likely want to "eat" the text line, so it is
|
||||
// not spoken or available for further processing
|
||||
SetPCChatMessage("");
|
||||
|
||||
// SendMessageToPC(GetFirstPC(), "LEAVE(2) dmfi_univ_listen: speaker=" + GetName(oShouter) + ", channel=" + IntToString(nVolume) + ", said=" + sSaid);
|
||||
|
||||
}
|
65
_module/nss/dmfi_voice1.nss
Normal file
65
_module/nss/dmfi_voice1.nss
Normal file
@@ -0,0 +1,65 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Default On Heartbeat
|
||||
//:: NW_C2_DEFAULT1
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This script will have people perform default
|
||||
animations.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Preston Watamaniuk
|
||||
//:: Created On: Nov 23, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
#include "dmfi_db_inc"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oFollow = GetLocalObject(OBJECT_SELF, "dmfi_follow");
|
||||
int iLoiter = GetLocalInt(OBJECT_SELF, "dmfi_Loiter");
|
||||
|
||||
// Will fire ONE time only - makes the thing hard to see
|
||||
if (!GetLocalInt(OBJECT_SELF, "hls_invis"))
|
||||
{
|
||||
SetListenPattern(OBJECT_SELF, "**", LISTEN_PATTERN); //listen to all text
|
||||
SetLocalInt(OBJECT_SELF, "hls_Listening", 1); //listen to all text
|
||||
SetListening(OBJECT_SELF, TRUE); //be sure NPC is listening
|
||||
|
||||
//leave it here rather than add the one time loop to EVERY creature through a OS script change
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), OBJECT_SELF);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneGhost(), OBJECT_SELF);
|
||||
SetLocalInt(OBJECT_SELF, "hls_invis",1);
|
||||
}
|
||||
|
||||
if (GetIsObjectValid(oFollow))
|
||||
{
|
||||
if (GetArea(oFollow)==GetArea(OBJECT_SELF))
|
||||
{
|
||||
AssignCommand(OBJECT_SELF, ClearAllActions(TRUE));
|
||||
AssignCommand(OBJECT_SELF, ActionForceFollowObject(oFollow));
|
||||
}
|
||||
else
|
||||
{
|
||||
AssignCommand(OBJECT_SELF, ClearAllActions(TRUE));
|
||||
AssignCommand(OBJECT_SELF, ActionJumpToObject(oFollow));
|
||||
AssignCommand(OBJECT_SELF, ActionForceFollowObject(oFollow));
|
||||
}
|
||||
}
|
||||
// If just following and listening, then return.
|
||||
if (!iLoiter)
|
||||
return;
|
||||
|
||||
// If in loiter mode, look for a PC and make the announcement when appropraite
|
||||
object oPC = GetFirstObjectInShape(SHAPE_SPHERE, 10.0f, GetLocation(OBJECT_SELF), TRUE);
|
||||
while(GetIsObjectValid(oPC))
|
||||
{
|
||||
if (GetIsPC(oPC) &&
|
||||
!GetIsDM(oPC) &&
|
||||
iLoiter)
|
||||
{
|
||||
SpeakString(GetLocalString(OBJECT_SELF, "dmfi_LoiterSay"));
|
||||
DestroyObject(OBJECT_SELF);
|
||||
}
|
||||
oPC = GetNextObjectInShape(SHAPE_SPHERE, 10.0f, GetLocation(OBJECT_SELF), TRUE);
|
||||
}
|
||||
}
|
53
_module/nss/dmfi_voice_exe.nss
Normal file
53
_module/nss/dmfi_voice_exe.nss
Normal file
@@ -0,0 +1,53 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: DMFI - settings voice command handler
|
||||
//:: dmfi_voice_exe
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Processor for the text heard by the settings adjuster creature.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: The DMFI Team
|
||||
//:: Created On:
|
||||
//:://////////////////////////////////////////////
|
||||
//:: 2008.08.02 tsunami282 - most code transferred to dmfi_plychat_exe, this
|
||||
//:: script now used for processing what the Settings Adjuster creature hears.
|
||||
|
||||
#include "dmfi_db_inc"
|
||||
|
||||
void main()
|
||||
{
|
||||
int nMatch = GetListenPatternNumber();
|
||||
object oShouter = GetLastSpeaker();
|
||||
|
||||
if (GetIsDM(oShouter))
|
||||
SetLocalInt(GetModule(), "dmfi_Admin" + GetPCPublicCDKey(oShouter), 1);
|
||||
|
||||
if (GetIsDMPossessed(oShouter))
|
||||
SetLocalObject(GetMaster(oShouter), "dmfi_familiar", oShouter);
|
||||
|
||||
object oTarget = GetLocalObject(oShouter, "dmfi_VoiceTarget");
|
||||
object oMaster = OBJECT_INVALID;
|
||||
if (GetIsObjectValid(oTarget))
|
||||
oMaster = oShouter;
|
||||
|
||||
int iPhrase = GetLocalInt(oShouter, "hls_EditPhrase");
|
||||
|
||||
object oSummon;
|
||||
|
||||
if (nMatch == LISTEN_PATTERN && GetIsObjectValid(oShouter) && GetIsDM(oShouter))
|
||||
{
|
||||
string sSaid = GetMatchedSubstring(0);
|
||||
|
||||
if (GetTag(OBJECT_SELF) == "dmfi_setting" && GetLocalString(oShouter, "EffectSetting") != "")
|
||||
{
|
||||
string sPhrase = GetLocalString(oShouter, "EffectSetting");
|
||||
SetLocalFloat(oShouter, sPhrase, StringToFloat(sSaid));
|
||||
SetDMFIPersistentFloat("dmfi", sPhrase, StringToFloat(sSaid), oShouter);
|
||||
DeleteLocalString(oShouter, "EffectSetting");
|
||||
DelayCommand(0.5, ActionSpeakString("The setting " + sPhrase + " has been changed to " + FloatToString(GetLocalFloat(oShouter, sPhrase))));
|
||||
DelayCommand(1.5, DestroyObject(OBJECT_SELF));
|
||||
//maybe add a return here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
377
_module/nss/dmfi_x_afflict.nss
Normal file
377
_module/nss/dmfi_x_afflict.nss
Normal file
@@ -0,0 +1,377 @@
|
||||
#include "dmfi_db_inc"
|
||||
|
||||
|
||||
object DMFI_NextTarget(object oTarget, object oUser)
|
||||
{
|
||||
object oNew;
|
||||
|
||||
if (GetIsPC(oTarget))
|
||||
{
|
||||
if (GetIsObjectValid(GetNextFactionMember(oTarget)))
|
||||
oNew = GetNextFactionMember(oTarget);
|
||||
else
|
||||
oNew = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oTarget, 1);
|
||||
}
|
||||
else
|
||||
oNew = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC, oTarget, 1);
|
||||
|
||||
|
||||
if (!GetIsObjectValid(oNew))
|
||||
{
|
||||
SendMessageToPC(oUser, "No valid target to transfer to.");
|
||||
oNew = oTarget;
|
||||
}
|
||||
|
||||
SetLocalObject(oUser, "dmfi_univ_target", oNew);
|
||||
SetCustomToken(20680, GetName(oNew));
|
||||
FloatingTextStringOnCreature("Target changed to: "+ GetName(oNew), oUser);
|
||||
return oNew;
|
||||
}
|
||||
|
||||
//DMFI Creates the "settings" creature
|
||||
void CreateSetting(object oUser)
|
||||
{
|
||||
object oSetting = CreateObject(OBJECT_TYPE_CREATURE, "dmfi_setting", GetLocation(oUser));
|
||||
DelayCommand(0.5f, AssignCommand(oSetting, ActionSpeakString(GetLocalString(oUser, "EffectSetting") + " is currently set at " + FloatToString(GetLocalFloat(oUser, GetLocalString(oUser, "EffectSetting"))))));
|
||||
SetLocalObject(oSetting, "MyMaster", oUser);
|
||||
SetListenPattern(oSetting, "**", LISTEN_PATTERN); //listen to all text
|
||||
SetLocalInt(oSetting, "hls_Listening", 1); //listen to all text
|
||||
SetListening(oSetting, TRUE); //be sure NPC is listening
|
||||
}
|
||||
|
||||
//This function is for the DMFI Affliction Wand
|
||||
void ReportImmunity(object oT, object oUser)
|
||||
{
|
||||
SendMessageToPC(oUser, "Immunities Reported: (blank if none)");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_ABILITY_DECREASE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Ability Decrease");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_AC_DECREASE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE AC Decrease");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_ATTACK_DECREASE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Attack Decrease");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_BLINDNESS))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Blindness");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_CHARM))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Charm");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_CONFUSED))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Confusion");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_CRITICAL_HIT))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Critical Hit");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_CURSED))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Cursed");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_DAMAGE_DECREASE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Damage Decrease");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_DAMAGE_IMMUNITY_DECREASE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Damage Immunity Decrease");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_DAZED))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Dazed");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_DEAFNESS))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Deafness");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_DEATH))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Death");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_DISEASE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Disease");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_DOMINATE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Dominate");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_ENTANGLE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Entangle");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_FEAR))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Fear");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_KNOCKDOWN))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Knockdown");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_MIND_SPELLS))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Mind Spells");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_MOVEMENT_SPEED_DECREASE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Movement Speed Decrease");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_NEGATIVE_LEVEL))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Negative Level");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_PARALYSIS))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Paralysis");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_POISON))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Poison");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_SAVING_THROW_DECREASE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Saving Throw Decrease");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_SILENCE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Silence");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_SKILL_DECREASE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Skill Decrease");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_SLEEP))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Sleep");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_SLOW))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Slow");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_SNEAK_ATTACK))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Sneak Attack");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_SPELL_RESISTANCE_DECREASE))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Spell Resistance Decrease");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_STUN))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Stun");
|
||||
if (GetIsImmune(oT, IMMUNITY_TYPE_TRAP))
|
||||
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Trap");
|
||||
}
|
||||
|
||||
void CheckForEffect(effect eA, object oT, object oUser)
|
||||
{
|
||||
int Result = FALSE;
|
||||
effect Check = GetFirstEffect(oT);
|
||||
|
||||
while (GetIsEffectValid(Check))
|
||||
{
|
||||
if (Check == eA)
|
||||
Result = TRUE;
|
||||
|
||||
Check = GetNextEffect(oT);
|
||||
}
|
||||
if (Result)
|
||||
FloatingTextStringOnCreature("Affliction Wand Saving Throw Failure: " + GetName(oT), oUser);
|
||||
else
|
||||
FloatingTextStringOnCreature("Affliction Wand Saving Throw Success: No Effect: " + GetName(oT), oUser);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int iAfflict = GetLocalInt(OBJECT_SELF, "dmfi_univ_int");
|
||||
object oUser = OBJECT_SELF;
|
||||
effect eEffect;
|
||||
object oTarget = GetLocalObject(oUser, "dmfi_univ_target");
|
||||
float fDuration;
|
||||
int nDNum;
|
||||
effect eD;
|
||||
effect eA;
|
||||
effect eT;
|
||||
effect eVis;
|
||||
int nBug = 0;
|
||||
int nSaveAmount; float fSaveAmount;
|
||||
|
||||
nDNum = GetLocalInt(oUser, "dmfi_damagemodifier");
|
||||
fDuration = GetLocalFloat(oUser, "dmfi_stunduration");
|
||||
fSaveAmount = GetLocalFloat(oUser, "dmfi_saveamount");
|
||||
|
||||
nSaveAmount = FloatToInt(fSaveAmount);
|
||||
|
||||
if (!(GetObjectType(oTarget) == OBJECT_TYPE_CREATURE) ||
|
||||
GetIsDM(oTarget))
|
||||
{
|
||||
FloatingTextStringOnCreature("You must target a valid creature!", oUser, FALSE);
|
||||
return;
|
||||
}
|
||||
switch(iAfflict)
|
||||
{
|
||||
case 11: eD= EffectDamage(d4(nDNum), DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||
eVis = EffectVisualEffect(VFX_COM_BLOOD_SPARK_SMALL); break;
|
||||
case 12: eD = EffectDamage(d6(nDNum), DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||
eVis = EffectVisualEffect(VFX_COM_BLOOD_LRG_RED); break;
|
||||
case 13: eD = EffectDamage(d8(nDNum), DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||
eVis = EffectVisualEffect(VFX_COM_BLOOD_LRG_RED); break;
|
||||
case 14: eD = EffectDamage(d10(nDNum), DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||
eVis = EffectVisualEffect(VFX_COM_BLOOD_SPARK_SMALL); break;
|
||||
case 15: eD = EffectDamage(d12(nDNum), DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||
eVis = EffectVisualEffect(VFX_COM_BLOOD_SPARK_SMALL); break;
|
||||
case 16: eD = EffectDamage(GetCurrentHitPoints(oTarget)/4, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||
eVis = EffectVisualEffect(VFX_COM_BLOOD_LRG_RED); break;
|
||||
case 17: eD = EffectDamage(GetCurrentHitPoints(oTarget)/2, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||
eVis = EffectVisualEffect(VFX_COM_BLOOD_LRG_RED); break;
|
||||
case 18: eD = EffectDamage(GetCurrentHitPoints(oTarget) * 3 / 4, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||
eVis =EffectVisualEffect(VFX_COM_CHUNK_RED_SMALL); break;
|
||||
case 19: eD = EffectDamage(GetCurrentHitPoints(oTarget)-1, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||
eVis =EffectVisualEffect(VFX_COM_CHUNK_RED_SMALL); break;
|
||||
case 21: eA =EffectDisease(DISEASE_FILTH_FEVER); break;
|
||||
case 22: eA =EffectDisease(DISEASE_MINDFIRE); break;
|
||||
case 23: eA =EffectDisease(DISEASE_DREAD_BLISTERS); break;
|
||||
case 24: eA =EffectDisease(DISEASE_SHAKES); break;
|
||||
case 25: eA =EffectDisease(DISEASE_VERMIN_MADNESS); break;
|
||||
case 26: eA =EffectDisease(DISEASE_DEVIL_CHILLS); break;
|
||||
case 27: eA =EffectDisease(DISEASE_SLIMY_DOOM); break;
|
||||
case 28: eA =EffectDisease(DISEASE_RED_ACHE); break;
|
||||
case 29: eA =EffectDisease(DISEASE_ZOMBIE_CREEP); break;
|
||||
case 31: eA =EffectDisease(DISEASE_BLINDING_SICKNESS); break;
|
||||
case 32: eA =EffectDisease(DISEASE_CACKLE_FEVER); break;
|
||||
case 33: eA =EffectDisease(DISEASE_BURROW_MAGGOTS); break;
|
||||
case 34: eA =EffectDisease(DISEASE_RED_SLAAD_EGGS); break;
|
||||
case 35: eA =EffectDisease(DISEASE_DEMON_FEVER); break;
|
||||
case 36: eA =EffectDisease(DISEASE_GHOUL_ROT); break;
|
||||
case 37: eA =EffectDisease(DISEASE_MUMMY_ROT); break;
|
||||
case 38: eA =EffectDisease(DISEASE_SOLDIER_SHAKES); break;
|
||||
case 39: eA =EffectDisease(DISEASE_SOLDIER_SHAKES); break;
|
||||
case 41: eA =EffectPoison(POISON_TINY_SPIDER_VENOM); break;
|
||||
case 42: eA =EffectPoison(POISON_ARANEA_VENOM); break;
|
||||
case 43: eA =EffectPoison(POISON_MEDIUM_SPIDER_VENOM); break;
|
||||
case 44: eA = EffectPoison(POISON_CARRION_CRAWLER_BRAIN_JUICE); break;
|
||||
case 45: eA = EffectPoison(POISON_OIL_OF_TAGGIT); break;
|
||||
case 46: eA = EffectPoison(POISON_ARSENIC); break;
|
||||
case 47: eA = EffectPoison(POISON_GREENBLOOD_OIL); break;
|
||||
case 48: eA = EffectPoison(POISON_NITHARIT); break;
|
||||
case 49: eA = EffectPoison(POISON_PHASE_SPIDER_VENOM); break;
|
||||
case 51: eA = EffectPoison(POISON_LICH_DUST); break;
|
||||
case 52: eA = EffectPoison(POISON_SHADOW_ESSENCE); break;
|
||||
case 53: eA = EffectPoison(POISON_LARGE_SPIDER_VENOM); break;
|
||||
case 54: eA = EffectPoison(POISON_PURPLE_WORM_POISON); break;
|
||||
case 55: eA = EffectPoison(POISON_IRON_GOLEM); break;
|
||||
case 56: eA = EffectPoison(POISON_PIT_FIEND_ICHOR); break;
|
||||
case 57: eA = EffectPoison(POISON_WYVERN_POISON); break;
|
||||
case 58: eA = EffectPoison(POISON_BLACK_LOTUS_EXTRACT); break;
|
||||
case 59: eA = EffectPoison(POISON_GARGANTUAN_SPIDER_VENOM); break;
|
||||
case 60: eT = EffectPetrify(); break;
|
||||
case 61: eT = EffectBlindness(); break;
|
||||
case 62: eT = EffectCurse(4,4,4,4,4,4); break;
|
||||
case 63: eT = EffectFrightened(); break;
|
||||
case 64: eT = EffectStunned(); break;
|
||||
case 65: eT = EffectSilence(); break;
|
||||
case 66: eT = EffectSleep(); break;
|
||||
case 67: eT = EffectSlow(); break;
|
||||
case 68: eT = EffectKnockdown(); nBug = 1; break;
|
||||
case 69: eD = EffectDamage( GetCurrentHitPoints(oTarget)-1, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_NORMAL);
|
||||
AssignCommand( oTarget, ClearAllActions());
|
||||
AssignCommand( oTarget, ActionPlayAnimation( ANIMATION_LOOPING_DEAD_FRONT, 1.0, 99999.0));
|
||||
DelayCommand(0.5, SetCommandable( FALSE, oTarget)); break;
|
||||
case 71: eA = EffectCutsceneDominated();break;
|
||||
case 72: eA = EffectCutsceneGhost(); break;
|
||||
case 73: eA = EffectCutsceneImmobilize(); break;
|
||||
case 74: eA = EffectCutsceneParalyze(); break;
|
||||
case 75: nBug = -1; break; //special case for combo death effect
|
||||
case 81: eEffect = GetFirstEffect(oTarget);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
if (GetEffectType(eEffect) == EFFECT_TYPE_POISON) RemoveEffect(oTarget, eEffect);
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
} break;
|
||||
case 82: eEffect = GetFirstEffect(oTarget);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
if (GetEffectType(eEffect) == EFFECT_TYPE_DISEASE) RemoveEffect(oTarget, eEffect);
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
} break;
|
||||
case 83: eEffect = GetFirstEffect(oTarget);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
if (GetEffectType(eEffect) == EFFECT_TYPE_BLINDNESS) RemoveEffect(oTarget, eEffect);
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
} break;
|
||||
case 84: eEffect = GetFirstEffect(oTarget);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
if (GetEffectType(eEffect) == EFFECT_TYPE_CURSE) RemoveEffect(oTarget, eEffect);
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
} break;
|
||||
case 85: eEffect = GetFirstEffect(oTarget);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
if (GetEffectType(eEffect) == EFFECT_TYPE_FRIGHTENED) RemoveEffect(oTarget, eEffect);
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
} break;
|
||||
case 86: eEffect = GetFirstEffect(oTarget);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
if (GetEffectType(eEffect) == EFFECT_TYPE_STUNNED) RemoveEffect(oTarget, eEffect);
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
} break;
|
||||
case 87: eEffect = GetFirstEffect(oTarget);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
if (GetEffectType(eEffect) == EFFECT_TYPE_SILENCE) RemoveEffect(oTarget, eEffect);
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
} break;
|
||||
case 88: eEffect = GetFirstEffect(oTarget);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
RemoveEffect(oTarget, eEffect);
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
} break;
|
||||
case 89: SetCommandable(TRUE, oTarget);
|
||||
AssignCommand(oTarget, ClearAllActions()); break;
|
||||
case 80: eEffect = GetFirstEffect(oTarget);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
if (GetEffectType(eEffect) == EFFECT_TYPE_PETRIFY) RemoveEffect(oTarget, eEffect);
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
} break;//Added July 5, 2003
|
||||
|
||||
// 99 is a duplicate instance - simple copy. - Demetrious
|
||||
case 91: SetLocalString(oUser, "EffectSetting", "dmfi_stunduration");
|
||||
CreateSetting(oUser);
|
||||
case 92: SetDMFIPersistentInt("dmfi", "DamageModifier", nDNum+1); SetCustomToken(20780, IntToString(nDNum+1));; break;
|
||||
case 93:
|
||||
if (nDNum==1)
|
||||
{
|
||||
FloatingTextStringOnCreature("Illegal operation: Minimum modifier is 1.", oUser);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDMFIPersistentInt("dmfi", "DamageModifier", nDNum-1); SetCustomToken(20780, IntToString(nDNum-1)); ;break;
|
||||
break;
|
||||
}
|
||||
case 94: ReportImmunity(oTarget, oUser); break;
|
||||
case 95: DMFI_NextTarget(oTarget, oUser); break;
|
||||
case 99: SetLocalString(oUser, "EffectSetting", "SaveEffectAmount");
|
||||
CreateSetting(oUser); break;
|
||||
case 101: eT = EffectSavingThrowDecrease(SAVING_THROW_FORT, nSaveAmount); break;
|
||||
case 102: eT = EffectSavingThrowDecrease(SAVING_THROW_REFLEX, nSaveAmount); break;
|
||||
case 103: eT = EffectSavingThrowDecrease(SAVING_THROW_WILL, nSaveAmount); break;
|
||||
case 104: eT = EffectSavingThrowIncrease(SAVING_THROW_FORT, nSaveAmount); break;
|
||||
case 105: eT = EffectSavingThrowIncrease(SAVING_THROW_REFLEX, nSaveAmount); break;
|
||||
case 106: eT = EffectSavingThrowIncrease(SAVING_THROW_WILL, nSaveAmount); break;
|
||||
case 107: eT = EffectSavingThrowDecrease(SAVING_THROW_ALL, nSaveAmount); break;
|
||||
case 108: eT = EffectSavingThrowIncrease(SAVING_THROW_ALL, nSaveAmount); break;
|
||||
case 109: SetLocalString(oUser, "EffectSetting", "SaveEffectAmount");
|
||||
CreateSetting(oUser);
|
||||
case 100: eEffect = GetFirstEffect(oTarget);
|
||||
while (GetIsEffectValid(eEffect))
|
||||
{
|
||||
if ((GetEffectType(eEffect) == EFFECT_TYPE_SAVING_THROW_INCREASE)
|
||||
||(GetEffectType(eEffect) == EFFECT_TYPE_SAVING_THROW_DECREASE))
|
||||
RemoveEffect(oTarget, eEffect);
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
} break;//Added July 5, 2003
|
||||
|
||||
|
||||
|
||||
default: break;
|
||||
}
|
||||
//code down here to apply the effects an then go back and see if the
|
||||
//player successfully saved or did not for the diseases and poisons.
|
||||
|
||||
if ((GetEffectType(eD)!= EFFECT_TYPE_INVALIDEFFECT) ||
|
||||
(GetEffectType(eVis) != EFFECT_TYPE_INVALIDEFFECT))
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eD, oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVis, oTarget);
|
||||
return;
|
||||
}
|
||||
if (GetEffectType(eA)!= EFFECT_TYPE_INVALIDEFFECT)
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eA, oTarget);
|
||||
DelayCommand(5.0, CheckForEffect(eA, oTarget, oUser));
|
||||
return;
|
||||
}
|
||||
if ((GetEffectType(eT)!= EFFECT_TYPE_INVALIDEFFECT) || (nBug ==1))
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eT, oTarget, fDuration);
|
||||
|
||||
if ((GetEffectType(eT)==EFFECT_TYPE_SAVING_THROW_INCREASE) ||
|
||||
(GetEffectType(eT)==EFFECT_TYPE_SAVING_THROW_DECREASE))
|
||||
{
|
||||
DelayCommand(1.0, FloatingTextStringOnCreature("Target Saves: Fortitude " + IntToString(GetFortitudeSavingThrow(oTarget))
|
||||
+ " Reflex " + IntToString(GetReflexSavingThrow(oTarget)) + " Will " + IntToString(GetWillSavingThrow(oTarget)), oUser));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (nBug == -1)
|
||||
{
|
||||
object oFollowMe = GetFirstFactionMember(oTarget, TRUE);
|
||||
|
||||
if (!GetIsObjectValid(oFollowMe))
|
||||
oFollowMe = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oTarget, 1,CREATURE_TYPE_IS_ALIVE, TRUE);
|
||||
|
||||
if (GetIsDM(oFollowMe) || GetIsDMPossessed(oFollowMe))
|
||||
oFollowMe = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oTarget, 2,CREATURE_TYPE_IS_ALIVE, TRUE);
|
||||
|
||||
if (!GetIsObjectValid(oFollowMe))
|
||||
oFollowMe = oUser;
|
||||
|
||||
AssignCommand(oFollowMe, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneDominated(), oTarget));
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneGhost(), oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), oTarget);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
218
_module/nss/dmfi_x_emote.nss
Normal file
218
_module/nss/dmfi_x_emote.nss
Normal file
@@ -0,0 +1,218 @@
|
||||
//Smoking Function by Jason Robinson
|
||||
location GetLocationAboveAndInFrontOf(object oPC, float fDist, float fHeight)
|
||||
{
|
||||
float fDistance = -fDist;
|
||||
object oTarget = (oPC);
|
||||
object oArea = GetArea(oTarget);
|
||||
vector vPosition = GetPosition(oTarget);
|
||||
vPosition.z += fHeight;
|
||||
float fOrientation = GetFacing(oTarget);
|
||||
vector vNewPos = AngleToVector(fOrientation);
|
||||
float vZ = vPosition.z;
|
||||
float vX = vPosition.x - fDistance * vNewPos.x;
|
||||
float vY = vPosition.y - fDistance * vNewPos.y;
|
||||
fOrientation = GetFacing(oTarget);
|
||||
vX = vPosition.x - fDistance * vNewPos.x;
|
||||
vY = vPosition.y - fDistance * vNewPos.y;
|
||||
vNewPos = AngleToVector(fOrientation);
|
||||
vZ = vPosition.z;
|
||||
vNewPos = Vector(vX, vY, vZ);
|
||||
return Location(oArea, vNewPos, fOrientation);
|
||||
}
|
||||
|
||||
//Smoking Function by Jason Robinson
|
||||
void SmokePipe(object oActivator)
|
||||
{
|
||||
string sEmote1 = "*puffs on a pipe*";
|
||||
string sEmote2 = "*inhales from a pipe*";
|
||||
string sEmote3 = "*pulls a mouthful of smoke from a pipe*";
|
||||
float fHeight = 1.7;
|
||||
float fDistance = 0.1;
|
||||
// Set height based on race and gender
|
||||
if (GetGender(oActivator) == GENDER_MALE)
|
||||
{
|
||||
switch (GetRacialType(oActivator))
|
||||
{
|
||||
case RACIAL_TYPE_HUMAN:
|
||||
case RACIAL_TYPE_HALFELF: fHeight = 1.7; fDistance = 0.12; break;
|
||||
case RACIAL_TYPE_ELF: fHeight = 1.55; fDistance = 0.08; break;
|
||||
case RACIAL_TYPE_GNOME:
|
||||
case RACIAL_TYPE_HALFLING: fHeight = 1.15; fDistance = 0.12; break;
|
||||
case RACIAL_TYPE_DWARF: fHeight = 1.2; fDistance = 0.12; break;
|
||||
case RACIAL_TYPE_HALFORC: fHeight = 1.9; fDistance = 0.2; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// FEMALES
|
||||
switch (GetRacialType(oActivator))
|
||||
{
|
||||
case RACIAL_TYPE_HUMAN:
|
||||
case RACIAL_TYPE_HALFELF: fHeight = 1.6; fDistance = 0.12; break;
|
||||
case RACIAL_TYPE_ELF: fHeight = 1.45; fDistance = 0.12; break;
|
||||
case RACIAL_TYPE_GNOME:
|
||||
case RACIAL_TYPE_HALFLING: fHeight = 1.1; fDistance = 0.075; break;
|
||||
case RACIAL_TYPE_DWARF: fHeight = 1.2; fDistance = 0.1; break;
|
||||
case RACIAL_TYPE_HALFORC: fHeight = 1.8; fDistance = 0.13; break;
|
||||
}
|
||||
}
|
||||
location lAboveHead = GetLocationAboveAndInFrontOf(oActivator, fDistance, fHeight);
|
||||
// emotes
|
||||
switch (d3())
|
||||
{
|
||||
case 1: AssignCommand(oActivator, ActionSpeakString(sEmote1)); break;
|
||||
case 2: AssignCommand(oActivator, ActionSpeakString(sEmote2)); break;
|
||||
case 3: AssignCommand(oActivator, ActionSpeakString(sEmote3));break;
|
||||
}
|
||||
// glow red
|
||||
AssignCommand(oActivator, ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_RED_5), oActivator, 0.15)));
|
||||
// wait a moment
|
||||
AssignCommand(oActivator, ActionWait(3.0));
|
||||
// puff of smoke above and in front of head
|
||||
AssignCommand(oActivator, ActionDoCommand(ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), lAboveHead)));
|
||||
// if female, turn head to left
|
||||
if ((GetGender(oActivator) == GENDER_FEMALE) && (GetRacialType(oActivator) != RACIAL_TYPE_DWARF))
|
||||
AssignCommand(oActivator, ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 1.0, 5.0));
|
||||
}
|
||||
|
||||
void EmoteDance(object oPC)
|
||||
{
|
||||
object oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
|
||||
object oLeftHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
|
||||
|
||||
AssignCommand(oPC,ActionUnequipItem(oRightHand));
|
||||
AssignCommand(oPC,ActionUnequipItem(oLeftHand));
|
||||
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY2,1.0));
|
||||
AssignCommand(oPC,ActionDoCommand(PlayVoiceChat(VOICE_CHAT_LAUGH,oPC)));
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_LOOPING_TALK_LAUGHING, 2.0, 2.0));
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY1,1.0));
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY3,2.0));
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_LOOPING_GET_MID, 3.0, 1.0));
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_LOOPING_TALK_FORCEFUL,1.0));
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY2,1.0));
|
||||
AssignCommand(oPC,ActionDoCommand(PlayVoiceChat(VOICE_CHAT_LAUGH,oPC)));
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_LOOPING_TALK_LAUGHING, 2.0, 2.0));
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY1,1.0));
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY3,2.0));
|
||||
AssignCommand(oPC,ActionDoCommand(PlayVoiceChat(VOICE_CHAT_LAUGH,oPC)));
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_LOOPING_GET_MID, 3.0, 1.0));
|
||||
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY2,1.0));
|
||||
|
||||
AssignCommand(oPC,ActionDoCommand(ActionEquipItem(oLeftHand,INVENTORY_SLOT_LEFTHAND)));
|
||||
AssignCommand(oPC,ActionDoCommand(ActionEquipItem(oRightHand,INVENTORY_SLOT_RIGHTHAND)));
|
||||
}
|
||||
|
||||
void SitInNearestChair(object oPC)
|
||||
{
|
||||
object oSit,oRightHand,oLeftHand,oChair,oCouch,oBenchPew,oStool;
|
||||
float fDistSit;int nth;
|
||||
// get the closest chair, couch bench or stool
|
||||
nth = 1;oChair = GetNearestObjectByTag("Chair", oPC,nth);
|
||||
while(oChair != OBJECT_INVALID && GetSittingCreature(oChair) != OBJECT_INVALID)
|
||||
{nth++;oChair = GetNearestObjectByTag("Chair", oPC,nth);}
|
||||
|
||||
nth = 1;oCouch = GetNearestObjectByTag("Couch", oPC,nth);
|
||||
while(oCouch != OBJECT_INVALID && GetSittingCreature(oCouch) != OBJECT_INVALID)
|
||||
{nth++;oChair = GetNearestObjectByTag("Couch", oPC,nth);}
|
||||
|
||||
nth = 1;oBenchPew = GetNearestObjectByTag("BenchPew", oPC,nth);
|
||||
while(oBenchPew != OBJECT_INVALID && GetSittingCreature(oBenchPew) != OBJECT_INVALID)
|
||||
{nth++;oChair = GetNearestObjectByTag("BenchPew", oPC,nth);}
|
||||
/* 1.27 bug
|
||||
nth = 1;oStool = GetNearestObjectByTag("Stool", oPC,nth);
|
||||
while(oStool != OBJECT_INVALID && GetSittingCreature(oStool) != OBJECT_INVALID)
|
||||
{nth++;oStool = GetNearestObjectByTag("Stool", oPC,nth);}
|
||||
*/
|
||||
// get the distance between the user and each object (-1.0 is the result if no
|
||||
// object is found
|
||||
float fDistanceChair = GetDistanceToObject(oChair);
|
||||
float fDistanceBench = GetDistanceToObject(oBenchPew);
|
||||
float fDistanceCouch = GetDistanceToObject(oCouch);
|
||||
float fDistanceStool = GetDistanceToObject(oStool);
|
||||
|
||||
// if any of the objects are invalid (not there), change the return value
|
||||
// to a high number so the distance math can work
|
||||
if (fDistanceChair == -1.0)
|
||||
{fDistanceChair =1000.0;}
|
||||
|
||||
if (fDistanceBench == -1.0)
|
||||
{fDistanceBench = 1000.0;}
|
||||
|
||||
if (fDistanceCouch == -1.0)
|
||||
{fDistanceCouch = 1000.0;}
|
||||
|
||||
if (fDistanceStool == -1.0)
|
||||
{fDistanceStool = 1000.0;}
|
||||
|
||||
// find out which object is closest to the PC
|
||||
if (fDistanceChair<fDistanceBench && fDistanceChair<fDistanceCouch && fDistanceChair<fDistanceStool)
|
||||
{oSit=oChair;fDistSit=fDistanceChair;}
|
||||
else if (fDistanceBench<fDistanceChair && fDistanceBench<fDistanceCouch && fDistanceBench<fDistanceStool)
|
||||
{oSit=oBenchPew;fDistSit=fDistanceBench;}
|
||||
else if (fDistanceCouch<fDistanceChair && fDistanceCouch<fDistanceBench && fDistanceCouch<fDistanceStool)
|
||||
{oSit=oCouch;fDistSit=fDistanceCouch;}
|
||||
else
|
||||
//if (fDistanceStool<fDistanceChair && fDistanceStool<fDistanceBench && fDistanceStool<fDistanceCouch)
|
||||
{oSit=oStool;fDistSit=fDistanceStool;}
|
||||
|
||||
if(oSit != OBJECT_INVALID && fDistSit < 12.0)
|
||||
{
|
||||
// if no one is sitting in the object the PC is closest to, have him sit in it
|
||||
if (GetSittingCreature(oSit) == OBJECT_INVALID)
|
||||
{
|
||||
oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
|
||||
oLeftHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
|
||||
AssignCommand(oPC,ActionMoveToObject(oSit,FALSE,2.0)); //:: Presumably this will be fixed in a patch so that Plares will not run to chair
|
||||
ActionUnequipItem(oRightHand); //:: Added to resolve clipping issues when seated
|
||||
ActionUnequipItem(oLeftHand); //:: Added to resolve clipping issues when seated
|
||||
ActionDoCommand(AssignCommand(oPC,ActionSit(oSit)));
|
||||
|
||||
}
|
||||
else
|
||||
{SendMessageToPC(oPC,"The nearest chair is already taken ");}
|
||||
}
|
||||
else
|
||||
{SendMessageToPC(oPC,"There are no chairs nearby");}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int iEmote = GetLocalInt(OBJECT_SELF, "dmfi_univ_int");
|
||||
object oUser = OBJECT_SELF;
|
||||
object oTarget = GetLocalObject(oUser, "dmfi_univ_target");
|
||||
if (!GetIsObjectValid(oTarget))
|
||||
oTarget = oUser;
|
||||
float fDur = 9999.0f; //Duration
|
||||
|
||||
switch(iEmote)
|
||||
{
|
||||
case 1: AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_DODGE_SIDE, 1.0)); break;
|
||||
case 2: AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_DRINK, 1.0)); break;
|
||||
case 3: AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_DODGE_DUCK, 1.0)); break;
|
||||
case 4: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_DEAD_BACK, 1.0, fDur)); break;
|
||||
case 5: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_DEAD_FRONT, 1.0, fDur)); break;
|
||||
case 6: AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_READ, 1.0)); DelayCommand(3.0f, AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_READ, 1.0)));break;
|
||||
case 7: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, fDur)); break;
|
||||
case 81: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_TALK_PLEADING, 1.0, fDur)); break;
|
||||
case 82: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_CONJURE1, 1.0, fDur)); break;
|
||||
case 83: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_CONJURE2, 1.0, fDur)); break;
|
||||
case 84: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_GET_LOW, 1.0, fDur)); break;
|
||||
case 85: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_GET_MID, 1.0, fDur)); break;
|
||||
case 86: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_MEDITATE, 1.0, fDur)); break;
|
||||
case 87: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_TALK_FORCEFUL, 1.0, fDur)); break;
|
||||
case 88: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_WORSHIP, 1.0, fDur)); break;
|
||||
case 10: if (!GetLocalInt(oTarget, "hls_emotemute")) FloatingTextStringOnCreature("*emote* commands are off", oTarget, FALSE);
|
||||
else FloatingTextStringOnCreature("*emote* commands are on", oTarget, FALSE);
|
||||
SetLocalInt(oTarget, "hls_emotemute", abs(GetLocalInt(oTarget, "hls_emotemute") - 1)); break;
|
||||
case 91: EmoteDance(oTarget); break;
|
||||
case 92: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_PAUSE_DRUNK, 1.0, fDur)); break;
|
||||
case 93: AssignCommand(oTarget, ActionForceFollowObject(GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oTarget), 2.0f)); break;
|
||||
case 94: SitInNearestChair(oTarget); break;
|
||||
case 95: AssignCommand(oTarget, ActionPlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, fDur)); DelayCommand(1.0f, AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_DRINK, 1.0))); DelayCommand(3.0f, AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, fDur)));break;
|
||||
case 96: AssignCommand(oTarget, ActionPlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, fDur)); DelayCommand(1.0f, AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_READ, 1.0))); DelayCommand(3.0f, AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, fDur)));break;
|
||||
case 97: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_SPASM, 1.0, fDur)); break;
|
||||
case 98: SmokePipe(oTarget); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
288
_module/nss/dmfi_x_fx.nss
Normal file
288
_module/nss/dmfi_x_fx.nss
Normal file
@@ -0,0 +1,288 @@
|
||||
void CreateSetting(object oUser)
|
||||
{
|
||||
object oSetting = CreateObject(OBJECT_TYPE_CREATURE, "dmfi_setting", GetLocation(oUser));
|
||||
DelayCommand(0.5f, AssignCommand(oSetting, ActionSpeakString(GetLocalString(oUser, "EffectSetting") + " is currently set at " + FloatToString(GetLocalFloat(oUser, GetLocalString(oUser, "EffectSetting"))))));
|
||||
SetLocalObject(oSetting, "MyMaster", oUser);
|
||||
SetLocalInt(oSetting, "hls_Listening", 1); //listen to all text
|
||||
SetListening(oSetting, TRUE); //be sure NPC is listening
|
||||
}
|
||||
|
||||
//An FX Wand function
|
||||
void FXWand_Firestorm(object oDM)
|
||||
{
|
||||
|
||||
// FireStorm Effect
|
||||
location lDMLoc = GetLocation ( oDM);
|
||||
|
||||
|
||||
// tell the DM object to rain fire and destruction
|
||||
AssignCommand ( oDM, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect ( VFX_FNF_METEOR_SWARM), lDMLoc));
|
||||
AssignCommand ( oDM, DelayCommand (1.0, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect (VFX_FNF_SCREEN_SHAKE), lDMLoc)));
|
||||
|
||||
// create some fires
|
||||
object oTargetArea = GetArea(oDM);
|
||||
int nXPos, nYPos, nCount;
|
||||
for(nCount = 0; nCount < 15; nCount++)
|
||||
{
|
||||
nXPos = Random(30) - 15;
|
||||
nYPos = Random(30) - 15;
|
||||
|
||||
vector vNewVector = GetPosition(oDM);
|
||||
vNewVector.x += nXPos;
|
||||
vNewVector.y += nYPos;
|
||||
|
||||
location lFireLoc = Location(oTargetArea, vNewVector, 0.0);
|
||||
object oFire = CreateObject ( OBJECT_TYPE_PLACEABLE, "plc_flamelarge", lFireLoc, FALSE);
|
||||
object oDust = CreateObject ( OBJECT_TYPE_PLACEABLE, "plc_dustplume", lFireLoc, FALSE);
|
||||
DelayCommand ( 10.0, DestroyObject ( oFire));
|
||||
DelayCommand ( 14.0, DestroyObject ( oDust));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//An FX Wand function
|
||||
void FXWand_Earthquake(object oDM)
|
||||
{
|
||||
// Earthquake Effect by Jhenne, 06/29/02
|
||||
// declare variables used for targetting and commands.
|
||||
location lDMLoc = GetLocation ( oDM);
|
||||
|
||||
// tell the DM object to shake the screen
|
||||
AssignCommand( oDM, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SCREEN_SHAKE), lDMLoc));
|
||||
AssignCommand ( oDM, DelayCommand( 2.8, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect ( VFX_FNF_SCREEN_BUMP), lDMLoc)));
|
||||
AssignCommand ( oDM, DelayCommand( 3.0, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect ( VFX_FNF_SCREEN_SHAKE), lDMLoc)));
|
||||
AssignCommand ( oDM, DelayCommand( 4.5, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect ( VFX_FNF_SCREEN_BUMP), lDMLoc)));
|
||||
AssignCommand ( oDM, DelayCommand( 5.8, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect ( VFX_FNF_SCREEN_BUMP), lDMLoc)));
|
||||
// tell the DM object to play an earthquake sound
|
||||
AssignCommand ( oDM, PlaySound ("as_cv_boomdist1"));
|
||||
AssignCommand ( oDM, DelayCommand ( 2.0, PlaySound ("as_wt_thunderds3")));
|
||||
AssignCommand ( oDM, DelayCommand ( 4.0, PlaySound ("as_cv_boomdist1")));
|
||||
// create a dust plume at the DM and clicking location
|
||||
object oTargetArea = GetArea(oDM);
|
||||
int nXPos, nYPos, nCount;
|
||||
for(nCount = 0; nCount < 15; nCount++)
|
||||
{
|
||||
nXPos = Random(30) - 15;
|
||||
nYPos = Random(30) - 15;
|
||||
|
||||
vector vNewVector = GetPosition(oDM);
|
||||
vNewVector.x += nXPos;
|
||||
vNewVector.y += nYPos;
|
||||
|
||||
location lDustLoc = Location(oTargetArea, vNewVector, 0.0);
|
||||
object oDust = CreateObject ( OBJECT_TYPE_PLACEABLE, "plc_dustplume", lDustLoc, FALSE);
|
||||
DelayCommand ( 4.0, DestroyObject ( oDust));
|
||||
}
|
||||
}
|
||||
|
||||
//An FX Wand function
|
||||
void FXWand_Lightning(object oDM, location lDMLoc)
|
||||
{
|
||||
// Lightning Strike by Jhenne. 06/29/02
|
||||
// tell the DM object to create a Lightning visual effect at targetted location
|
||||
AssignCommand( oDM, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_LIGHTNING_M), lDMLoc));
|
||||
// tell the DM object to play a thunderclap
|
||||
AssignCommand ( oDM, PlaySound ("as_wt_thundercl3"));
|
||||
// create a scorch mark where the lightning hit
|
||||
object oScorch = CreateObject ( OBJECT_TYPE_PLACEABLE, "plc_weathmark", lDMLoc, FALSE);
|
||||
object oTargetArea = GetArea(oDM);
|
||||
int nXPos, nYPos, nCount;
|
||||
for(nCount = 0; nCount < 5; nCount++)
|
||||
{
|
||||
nXPos = Random(10) - 5;
|
||||
nYPos = Random(10) - 5;
|
||||
|
||||
vector vNewVector = GetPositionFromLocation(lDMLoc);
|
||||
vNewVector.x += nXPos;
|
||||
vNewVector.y += nYPos;
|
||||
|
||||
location lNewLoc = Location(oTargetArea, vNewVector, 0.0);
|
||||
AssignCommand( oDM, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_LIGHTNING_S), lNewLoc));
|
||||
}
|
||||
DelayCommand ( 20.0, DestroyObject ( oScorch));
|
||||
}
|
||||
|
||||
void FnFEffect(object oUser, int iVFX, location lEffect, float fDelay)
|
||||
{
|
||||
if (fDelay>2.0) FloatingTextStringOnCreature("Delay effect created", oUser, FALSE);
|
||||
DelayCommand( fDelay, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(iVFX),lEffect));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int iDayMusic, iNightMusic, iBattleMusic;
|
||||
int iEffect = GetLocalInt(OBJECT_SELF, "dmfi_univ_int");
|
||||
location lEffect = GetLocalLocation(OBJECT_SELF, "dmfi_univ_location");
|
||||
object oUser = OBJECT_SELF;
|
||||
float fDelay;
|
||||
float fDuration;
|
||||
float fBeamDuration;
|
||||
object oTarget;
|
||||
|
||||
fDelay = GetLocalFloat(oUser, "dmfi_effectdelay");
|
||||
fDuration = GetLocalFloat(oUser, "dmfi_effectduration");
|
||||
fBeamDuration = GetLocalFloat(oUser, "dmfi_beamduration");
|
||||
|
||||
if (!GetIsObjectValid(GetLocalObject(oUser, "dmfi_univ_target")))
|
||||
oTarget = oUser;
|
||||
else
|
||||
oTarget = GetLocalObject(oUser, "dmfi_univ_target");
|
||||
switch(iEffect)
|
||||
{
|
||||
//SoU/HotU Duration Effects(must have a target)
|
||||
case 101: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BIGBYS_CLENCHED_FIST), oTarget, fDuration); break;
|
||||
case 102: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BIGBYS_CRUSHING_HAND), oTarget, fDuration); break;
|
||||
case 103: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BIGBYS_GRASPING_HAND), oTarget, fDuration); break;
|
||||
case 104: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BIGBYS_INTERPOSING_HAND), oTarget, fDuration); break;
|
||||
case 105: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_ICESKIN), oTarget, fDuration); break;
|
||||
case 106: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_INFERNO), oTarget, fDuration); break;
|
||||
case 107: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PIXIEDUST), oTarget, fDuration); break;
|
||||
case 108: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), oTarget, fDuration); break;
|
||||
case 109: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_FREEZE_ANIMATION), oTarget, fDuration); break;
|
||||
case 100: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_GHOSTLY_PULSE), oTarget, fDuration); break;
|
||||
//Magical Duration Effects
|
||||
case 10: ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_CALTROPS),lEffect, fDuration); break;
|
||||
case 11: ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_TENTACLE),lEffect, fDuration); break;
|
||||
case 12: ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_WEB_MASS),lEffect, fDuration); break;
|
||||
case 13: FnFEffect(oUser, VFX_FNF_GAS_EXPLOSION_MIND,lEffect, fDelay); break;
|
||||
case 14: FnFEffect(oUser, VFX_FNF_LOS_HOLY_30,lEffect, fDelay); break;
|
||||
case 15: FnFEffect(oUser, VFX_FNF_LOS_EVIL_30,lEffect, fDelay); break;
|
||||
case 16: FnFEffect(oUser, VFX_FNF_SMOKE_PUFF,lEffect, fDelay); break;
|
||||
case 17: FnFEffect(oUser, VFX_FNF_GAS_EXPLOSION_NATURE,lEffect, fDelay); break;
|
||||
case 18: FnFEffect(oUser, VFX_FNF_DISPEL_DISJUNCTION,lEffect, fDelay); break;
|
||||
case 19: FnFEffect(oUser, VFX_FNF_GAS_EXPLOSION_EVIL,lEffect, fDelay); break;
|
||||
//Magical Status Effects (must have a target)
|
||||
case 21: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PROT_BARKSKIN), oTarget, fDuration); break;
|
||||
case 22: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PROT_GREATER_STONESKIN), oTarget, fDuration); break;
|
||||
case 23: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_ENTANGLE), oTarget, fDuration); break;
|
||||
case 24: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_ETHEREAL_VISAGE), oTarget, fDuration); break;
|
||||
case 25: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_GHOSTLY_VISAGE), oTarget, fDuration); break;
|
||||
case 26: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_INVISIBILITY), oTarget, fDuration); break;
|
||||
case 27: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BARD_SONG), oTarget, fDuration); break;
|
||||
case 28: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_GLOBE_INVULNERABILITY), oTarget, fDuration); break;
|
||||
case 29: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PARALYZED), oTarget, fDuration); break;
|
||||
case 20: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PROT_SHADOW_ARMOR), oTarget, fDuration); break;
|
||||
//Magical Burst Effects
|
||||
case 31: FnFEffect(oUser, VFX_FNF_FIREBALL,lEffect, fDelay); break;
|
||||
case 32: FnFEffect(oUser, VFX_FNF_FIRESTORM,lEffect, fDelay); break;
|
||||
case 33: FnFEffect(oUser, VFX_FNF_HORRID_WILTING,lEffect, fDelay); break;
|
||||
case 34: FnFEffect(oUser, VFX_FNF_HOWL_WAR_CRY,lEffect, fDelay); break;
|
||||
case 35: FnFEffect(oUser, VFX_FNF_IMPLOSION,lEffect, fDelay); break;
|
||||
case 36: FnFEffect(oUser, VFX_FNF_PWKILL,lEffect, fDelay); break;
|
||||
case 37: FnFEffect(oUser, VFX_FNF_PWSTUN,lEffect, fDelay); break;
|
||||
case 38: FnFEffect(oUser, VFX_FNF_SOUND_BURST,lEffect, fDelay); break;
|
||||
case 39: FnFEffect(oUser, VFX_FNF_STRIKE_HOLY,lEffect, fDelay); break;
|
||||
case 30: FnFEffect(oUser, VFX_FNF_WORD,lEffect, fDelay); break;
|
||||
//Lighting Effects
|
||||
case 41: ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BLACKOUT),lEffect, fDuration); break;
|
||||
case 42: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_ANTI_LIGHT_10),oTarget, fDuration); break;
|
||||
case 43: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_BLUE_20),oTarget, fDuration); break;
|
||||
case 44: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_GREY_20),oTarget, fDuration); break;
|
||||
case 45: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_ORANGE_20),oTarget, fDuration); break;
|
||||
case 46: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_PURPLE_20),oTarget, fDuration); break;
|
||||
case 47: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_RED_20),oTarget, fDuration); break;
|
||||
case 48: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_WHITE_20),oTarget, fDuration); break;
|
||||
case 49: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_YELLOW_20),oTarget, fDuration); break;
|
||||
//Beam Effects
|
||||
case 50: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_CHAIN, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||
case 51: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_COLD, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||
case 52: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_EVIL, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||
case 53: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_FIRE, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||
case 54: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_FIRE_LASH, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||
case 55: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_HOLY, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||
case 56: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_LIGHTNING, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||
case 57: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_MIND, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||
case 58: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_ODD, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||
case 59: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_COLD, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_EVIL, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_FIRE, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_FIRE_LASH, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_HOLY, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_LIGHTNING, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_MIND, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_ODD, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||
|
||||
//Environmental Effects
|
||||
case 60: FnFEffect(oUser, VFX_FNF_NATURES_BALANCE,lEffect, fDelay);break;
|
||||
case 61: FXWand_Lightning(oTarget, lEffect); break;
|
||||
case 62: FXWand_Firestorm(oTarget); break;
|
||||
case 63: FXWand_Earthquake(oTarget); break;
|
||||
case 64: FnFEffect(oUser, VFX_FNF_ICESTORM,lEffect, fDelay); break;
|
||||
case 65: FnFEffect(oUser, VFX_FNF_SUNBEAM,lEffect, fDelay); break;
|
||||
case 66: SetWeather(GetArea(oUser), WEATHER_CLEAR); break;
|
||||
case 67: SetWeather(GetArea(oUser), WEATHER_RAIN); break;
|
||||
case 68: SetWeather(GetArea(oUser), WEATHER_SNOW); break;
|
||||
case 69: SetWeather(GetArea(oUser), WEATHER_USE_AREA_SETTINGS); break;
|
||||
//Summon Effects
|
||||
case 71: FnFEffect(oUser, VFX_FNF_SUMMON_MONSTER_1,lEffect, fDelay); break;
|
||||
case 72: FnFEffect(oUser, VFX_FNF_SUMMON_MONSTER_2,lEffect, fDelay); break;
|
||||
case 73: FnFEffect(oUser, VFX_FNF_SUMMON_MONSTER_3,lEffect, fDelay); break;
|
||||
case 74: FnFEffect(oUser, VFX_FNF_SUMMON_CELESTIAL,lEffect, fDelay); break;
|
||||
case 75: FnFEffect(oUser, VFX_FNF_SUMMONDRAGON,lEffect, fDelay); break;
|
||||
case 76: FnFEffect(oUser, VFX_FNF_SUMMON_EPIC_UNDEAD,lEffect, fDelay); break;
|
||||
case 77: FnFEffect(oUser, VFX_FNF_SUMMON_GATE,lEffect, fDelay); break;
|
||||
case 78: FnFEffect(oUser, VFX_FNF_SUMMON_UNDEAD,lEffect, fDelay); break;
|
||||
case 79: FnFEffect(oUser, VFX_FNF_UNDEAD_DRAGON,lEffect, fDelay); break;
|
||||
case 70: FnFEffect(oUser, VFX_FNF_WAIL_O_BANSHEES,lEffect, fDelay); break;
|
||||
//SoU/HotU Effects
|
||||
case 80: ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(322), oTarget, fDuration); break;
|
||||
case 81: ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(132), oTarget, fDuration); break;
|
||||
case 82: ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(133), oTarget, fDuration); break;
|
||||
case 83: ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(136), oTarget, fDuration); break;
|
||||
case 84: ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(137), oTarget, fDuration); break;
|
||||
case 85: FnFEffect(oUser, VFX_FNF_DEMON_HAND,lEffect, fDelay); break;
|
||||
case 86: FnFEffect(oUser, VFX_FNF_ELECTRIC_EXPLOSION,lEffect, fDelay); break;
|
||||
case 87: FnFEffect(oUser, VFX_FNF_GREATER_RUIN,lEffect, fDelay); break;
|
||||
case 88: FnFEffect(oUser, VFX_FNF_MYSTICAL_EXPLOSION,lEffect, fDelay); break;
|
||||
case 89: FnFEffect(oUser, VFX_FNF_SWINGING_BLADE,lEffect, fDelay); break;
|
||||
//Settings
|
||||
case 91:
|
||||
SetLocalString(oUser, "EffectSetting", "dmfi_effectduration");
|
||||
CreateSetting(oUser);
|
||||
break;
|
||||
case 92:
|
||||
SetLocalString(oUser, "EffectSetting", "dmfi_effectdelay");
|
||||
CreateSetting(oUser);
|
||||
break;
|
||||
case 93:
|
||||
SetLocalString(oUser, "EffectSetting", "dmfi_beamduration");
|
||||
CreateSetting(oUser);
|
||||
break;
|
||||
case 94: //Change Day Music
|
||||
iDayMusic = MusicBackgroundGetDayTrack(GetArea(oUser)) + 1;
|
||||
if (iDayMusic > 33) iDayMusic = 49;
|
||||
if (iDayMusic > 55) iDayMusic = 1;
|
||||
MusicBackgroundStop(GetArea(oUser));
|
||||
MusicBackgroundChangeDay(GetArea(oUser), iDayMusic);
|
||||
MusicBackgroundPlay(GetArea(oUser));
|
||||
break;
|
||||
case 95: //Change Night Music
|
||||
iNightMusic = MusicBackgroundGetDayTrack(GetArea(oUser)) + 1;
|
||||
if (iNightMusic > 33) iNightMusic = 49;
|
||||
if (iNightMusic > 55) iNightMusic = 1;
|
||||
MusicBackgroundStop(GetArea(oUser));
|
||||
MusicBackgroundChangeNight(GetArea(oUser), iNightMusic);
|
||||
MusicBackgroundPlay(GetArea(oUser));
|
||||
break;
|
||||
case 96: //Play Background Music
|
||||
MusicBackgroundPlay(GetArea(oUser));
|
||||
break;
|
||||
case 97: //Stop Background Music
|
||||
MusicBackgroundStop(GetArea(oUser));
|
||||
break;
|
||||
case 98: //Change and Play Battle Music
|
||||
iBattleMusic = MusicBackgroundGetBattleTrack(GetArea(oUser)) + 1;
|
||||
if (iBattleMusic < 34 || iBattleMusic > 48) iBattleMusic = 34;
|
||||
MusicBattleStop(GetArea(oUser));
|
||||
MusicBattleChange(GetArea(oUser), iBattleMusic);
|
||||
MusicBattlePlay(GetArea(oUser));
|
||||
break;
|
||||
case 99: //Stop Battle Music
|
||||
MusicBattleStop(GetArea(oUser));
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
DeleteLocalObject(oUser, "EffectTarget");
|
||||
return;
|
||||
}
|
31
_module/nss/gz_chair_use.nss
Normal file
31
_module/nss/gz_chair_use.nss
Normal file
@@ -0,0 +1,31 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: gz_chair_use
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Dom Queron
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
// This script was explained by David Gaider/Bioware in this topic.
|
||||
// You should read this topic if you are interested in Nwn scripting
|
||||
// http://nwn.bioware.com/forums/viewtopic.html?topic=74275&forum=47
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
ClearAllActions();
|
||||
float fFacing = GetFacing(OBJECT_SELF);
|
||||
object oPlayer = GetLastUsedBy();
|
||||
object oChair = OBJECT_SELF;
|
||||
if (GetIsPC(oPlayer))
|
||||
{
|
||||
if (GetIsObjectValid(oChair) && !GetIsObjectValid (GetSittingCreature(oChair)))
|
||||
{
|
||||
AssignCommand(oPlayer, ActionSit(oChair));
|
||||
AssignCommand(oPlayer, SetFacing(fFacing));
|
||||
}
|
||||
}
|
||||
}
|
1709
_module/nss/habd_include.nss
Normal file
1709
_module/nss/habd_include.nss
Normal file
File diff suppressed because it is too large
Load Diff
732
_module/nss/habd_onpcdeath.nss
Normal file
732
_module/nss/habd_onpcdeath.nss
Normal file
@@ -0,0 +1,732 @@
|
||||
// Hemophiliacs Always Bleed to Death
|
||||
// By Demetrious and OldManWhistler
|
||||
//
|
||||
// PLEASE READ "habd_include" FOR MORE INFORMATION.
|
||||
//
|
||||
// OnPlayerDeath event handler.
|
||||
|
||||
#include "habd_include"
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// This function is used to create a pseudo-heartbeat on the death bag placeable
|
||||
// that contains all of the dropped items on player death.
|
||||
void DeathBagHeartbeat ();
|
||||
|
||||
void DeathBagHeartbeat ()
|
||||
{
|
||||
if (GetIsObjectValid(GetFirstItemInInventory()))
|
||||
{
|
||||
// Set up timer.
|
||||
DelayCommand(HABD_BAG_SELF_DESTRUCT_TIMER, DeathBagHeartbeat());
|
||||
// Try to alert the owner.
|
||||
object oPC = GetLocalObject(OBJECT_SELF, HABD_BAG_OWNER);
|
||||
if (GetIsObjectValid(oPC))
|
||||
{
|
||||
if (GetLocalInt(OBJECT_SELF, HABD_NPC_BLEED) == 1) FloatingTextStringOnCreature("OOC: Your henchman/companion still has items in its death bag.", GetMaster(oPC), FALSE);
|
||||
else FloatingTextStringOnCreature("OOC: You still have items in your death bag.", oPC, FALSE);
|
||||
} else {
|
||||
// No valid owner, so destroy the variable.
|
||||
DeleteLocalObject(OBJECT_SELF, HABD_BAG_OWNER);
|
||||
}
|
||||
} else {
|
||||
// No valid items left inside, so self-destruct.
|
||||
SetPlotFlag(OBJECT_SELF, FALSE);
|
||||
DestroyObject(OBJECT_SELF);
|
||||
}
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Creates a placeable object and drops all the items into it based on the
|
||||
// configured options.
|
||||
// oPC - the dead player who is losing their items.
|
||||
void DropItems (object oPC);
|
||||
|
||||
void DropItems (object oPC)
|
||||
{
|
||||
object oItem;
|
||||
// Check that something is configured to drop.
|
||||
if ((HABD_DROP_GOLD == 0) &&
|
||||
(HABD_DROP_RAISE_REZ == 0) &&
|
||||
(HABD_DROP_BACKPACK == 0) &&
|
||||
(HABD_DROP_WEAPON_SHIELD == 0) &&
|
||||
(HABD_DROP_EQUIPPED == 0) &&
|
||||
(HABD_DROP_RANDOM_EQUIPPED == 0) &&
|
||||
(HABD_DROP_RANDOM_BACKPACK == 0) &&
|
||||
(HABD_DROP_MOST_EXPENSIVE_EQUIPPED == 0) &&
|
||||
(HABD_DROP_MOST_EXPENSIVE_BACKPACK == 0)
|
||||
) return;
|
||||
|
||||
object oBag;
|
||||
|
||||
// Only build the placeable if something is configured to drop.
|
||||
if ((HABD_DROP_GOLD == 1) ||
|
||||
(HABD_DROP_RAISE_REZ == 1) ||
|
||||
(HABD_DROP_BACKPACK == 1) ||
|
||||
(HABD_DROP_WEAPON_SHIELD == 1) ||
|
||||
(HABD_DROP_EQUIPPED == 1) ||
|
||||
(HABD_DROP_RANDOM_EQUIPPED == 1) ||
|
||||
(HABD_DROP_RANDOM_BACKPACK == 1) ||
|
||||
(HABD_DROP_MOST_EXPENSIVE_EQUIPPED == 1) ||
|
||||
(HABD_DROP_MOST_EXPENSIVE_BACKPACK == 1)
|
||||
)
|
||||
{
|
||||
// Create the bag and set up a heartbeat on it.
|
||||
oBag = CreateObject(OBJECT_TYPE_PLACEABLE, HABD_PLACEABLE_BAG, GetLocation(oPC), TRUE);
|
||||
// Sanity test.
|
||||
if (!GetIsObjectValid(oBag)) return;
|
||||
SetLocalObject(oBag, HABD_BAG_OWNER, oPC);
|
||||
AssignCommand(oBag, DelayCommand(HABD_BAG_SELF_DESTRUCT_TIMER, DeathBagHeartbeat()));
|
||||
}
|
||||
|
||||
// Should we drop all gold?
|
||||
if (HABD_DROP_GOLD != 0)
|
||||
{
|
||||
if (HABD_DROP_GOLD == 2) SendMessageToPC(oPC, "Destroying all gold.");
|
||||
else SendMessageToPC(oPC, "Dropping all gold.");
|
||||
if (HABD_DROP_GOLD == 2) TakeGoldFromCreature(GetGold(oPC), oPC, TRUE);
|
||||
else AssignCommand(oBag, TakeGoldFromCreature(GetGold(oPC), oPC));
|
||||
}
|
||||
// Should we only drop the right hand and left hand equipped items that aren't plot?
|
||||
if (HABD_DROP_WEAPON_SHIELD != 0)
|
||||
{
|
||||
if (HABD_DROP_WEAPON_SHIELD == 2) SendMessageToPC(oPC, "Destroying equipped weapon and shield.");
|
||||
else SendMessageToPC(oPC, "Dropping equipped weapon and shield.");
|
||||
oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC);
|
||||
if (GetIsObjectValid(oItem) && (!GetPlotFlag(oItem)))
|
||||
{
|
||||
if (HABD_DROP_WEAPON_SHIELD == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
if (GetIsObjectValid(oItem) && (!GetPlotFlag(oItem)))
|
||||
{
|
||||
if (HABD_DROP_WEAPON_SHIELD == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
}
|
||||
// Should we drop a random equipped item?
|
||||
if ((HABD_DROP_RANDOM_EQUIPPED != 0) || (HABD_DROP_MOST_EXPENSIVE_EQUIPPED != 0 ))
|
||||
{
|
||||
int iRandomEquipped;
|
||||
int i;
|
||||
int iRandomCount = 0;
|
||||
int iGP = 0;
|
||||
int iHighestGP = 0;
|
||||
int iHighestGPPos = 0;
|
||||
if (HABD_DROP_RANDOM_EQUIPPED == 2) SendMessageToPC(oPC, "Destroying a random equipped items.");
|
||||
else if (HABD_DROP_RANDOM_EQUIPPED == 1) SendMessageToPC(oPC, "Dropping a random equipped items.");
|
||||
if (HABD_DROP_MOST_EXPENSIVE_EQUIPPED == 2) SendMessageToPC(oPC, "Destroying most expensive equipped items.");
|
||||
else if (HABD_DROP_MOST_EXPENSIVE_EQUIPPED == 1) SendMessageToPC(oPC, "Dropping most expensive equipped items.");
|
||||
// Find the random item.
|
||||
for (i=0; i<NUM_INVENTORY_SLOTS; i++)
|
||||
{
|
||||
oItem = GetItemInSlot(i, oPC);
|
||||
if (GetIsObjectValid(oItem) && (!GetPlotFlag(oItem)))
|
||||
{
|
||||
iRandomCount++;
|
||||
if (HABD_DROP_MOST_EXPENSIVE_EQUIPPED != 0)
|
||||
{
|
||||
// Increment the number of random items and check
|
||||
// for the highest GP item.
|
||||
iGP = GetGoldPieceValue(oItem);
|
||||
if (iGP > iHighestGP)
|
||||
{
|
||||
iHighestGP = iGP;
|
||||
iHighestGPPos = iRandomCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
iRandomEquipped = Random(iRandomCount)+1;
|
||||
iRandomCount = 0;
|
||||
// Drop the item.
|
||||
for (i=0; i<NUM_INVENTORY_SLOTS; i++)
|
||||
{
|
||||
oItem = GetItemInSlot(i, oPC);
|
||||
if (GetIsObjectValid(oItem) && (!GetPlotFlag(oItem)))
|
||||
{
|
||||
iRandomCount++;
|
||||
// If this is the random item then drop it.
|
||||
if ((HABD_DROP_RANDOM_EQUIPPED != 0) && (iRandomCount == iRandomEquipped))
|
||||
{
|
||||
if (HABD_DROP_RANDOM_EQUIPPED == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
// If this is the most expensive item then drop it.
|
||||
if ((HABD_DROP_MOST_EXPENSIVE_EQUIPPED != 0) && (iRandomCount == iHighestGPPos))
|
||||
{
|
||||
if (HABD_DROP_MOST_EXPENSIVE_EQUIPPED == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Should we drop all equiped items that aren't plot?
|
||||
if (HABD_DROP_EQUIPPED != 0)
|
||||
{
|
||||
int i;
|
||||
if (HABD_DROP_EQUIPPED == 2) SendMessageToPC(oPC, "Destroying all equipped items.");
|
||||
else SendMessageToPC(oPC, "Dropping all equipped items.");
|
||||
for (i=0; i<NUM_INVENTORY_SLOTS; i++)
|
||||
{
|
||||
oItem = GetItemInSlot(i, oPC);
|
||||
if (GetIsObjectValid(oItem) && (!GetPlotFlag(oItem)))
|
||||
{
|
||||
if (HABD_DROP_EQUIPPED == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Should we only drop raise/rez scrolls in inventory?
|
||||
if ((HABD_DROP_RAISE_REZ != 0) && (!HABD_FORCE_RAISE_USES_SCROLLS))
|
||||
{
|
||||
if (HABD_DROP_RAISE_REZ == 2) SendMessageToPC(oPC, "Destroying all Raise Dead/Resurrection scrolls.");
|
||||
else SendMessageToPC(oPC, "Dropping all Raise Dead/Resurrection scrolls.");
|
||||
int iBaseItemType;
|
||||
oItem = GetFirstItemInInventory(oPC);
|
||||
while (GetIsObjectValid(oItem))
|
||||
{
|
||||
// Search through the scrolls
|
||||
iBaseItemType = GetBaseItemType(oItem);
|
||||
if ((iBaseItemType == BASE_ITEM_SCROLL) ||
|
||||
(iBaseItemType == BASE_ITEM_SPELLSCROLL))
|
||||
{
|
||||
// Default scrolls cannot be made plot so don't worry about it.
|
||||
// See if it matches the tags we are looking for.
|
||||
if (FindSubString(HABD_SCROLL_TAGS, ":"+GetTag(oItem)+":") != -1)
|
||||
{
|
||||
if (HABD_DROP_RAISE_REZ == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
}
|
||||
oItem = GetNextItemInInventory(oPC);
|
||||
}
|
||||
}
|
||||
// Should we drop a random backpack item?
|
||||
if ((HABD_DROP_RANDOM_BACKPACK != 0) || (HABD_DROP_MOST_EXPENSIVE_BACKPACK != 0))
|
||||
{
|
||||
int iRandomBackpack;
|
||||
int iGP = 0;
|
||||
int iHighestGP = 0;
|
||||
int iHighestGPPos = 0;
|
||||
if (HABD_DROP_RANDOM_BACKPACK == 2) SendMessageToPC(oPC, "Destroying a random backpack item.");
|
||||
else if (HABD_DROP_RANDOM_BACKPACK == 1) SendMessageToPC(oPC, "Dropping a random backpack item.");
|
||||
if (HABD_DROP_MOST_EXPENSIVE_BACKPACK == 2) SendMessageToPC(oPC, "Destroying most expensive backpack item.");
|
||||
else if (HABD_DROP_MOST_EXPENSIVE_BACKPACK == 1) SendMessageToPC(oPC, "Dropping most expensive backpack item.");
|
||||
int iRandomCount = 0;
|
||||
int iBaseItemType;
|
||||
// Find the random item.
|
||||
oItem = GetFirstItemInInventory(oPC);
|
||||
while (GetIsObjectValid(oItem))
|
||||
{
|
||||
if (HABD_FORCE_RAISE_USES_SCROLLS)
|
||||
{
|
||||
// Search through the scrolls and skill the raise/rez scrolls
|
||||
iBaseItemType = GetBaseItemType(oItem);
|
||||
if ((iBaseItemType == BASE_ITEM_SCROLL) ||
|
||||
(iBaseItemType == BASE_ITEM_SPELLSCROLL))
|
||||
{
|
||||
// Default scrolls cannot be made plot so don't worry about it.
|
||||
// See if it matches the tags we are looking for.
|
||||
if (FindSubString(HABD_SCROLL_TAGS, ":"+GetTag(oItem)+":") == -1)
|
||||
{
|
||||
// Increment the number of random items and check
|
||||
// for the highest GP item.
|
||||
iRandomCount++;
|
||||
if (HABD_DROP_MOST_EXPENSIVE_BACKPACK != 0)
|
||||
{
|
||||
iGP = GetGoldPieceValue(oItem);
|
||||
if (iGP > iHighestGP)
|
||||
{
|
||||
iHighestGP = iGP;
|
||||
iHighestGPPos = iRandomCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Increment the number of random items and check
|
||||
// for the highest GP item.
|
||||
iRandomCount++;
|
||||
if (HABD_DROP_MOST_EXPENSIVE_BACKPACK != 0)
|
||||
{
|
||||
iGP = GetGoldPieceValue(oItem);
|
||||
if (iGP > iHighestGP)
|
||||
{
|
||||
iHighestGP = iGP;
|
||||
iHighestGPPos = iRandomCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
oItem = GetNextItemInInventory(oPC);
|
||||
}
|
||||
iRandomBackpack = Random(iRandomCount)+1;
|
||||
iRandomCount = 0;
|
||||
// Drop the random item.
|
||||
// Find the random item.
|
||||
oItem = GetFirstItemInInventory(oPC);
|
||||
while (GetIsObjectValid(oItem))
|
||||
{
|
||||
if (HABD_FORCE_RAISE_USES_SCROLLS)
|
||||
{
|
||||
// Search through the scrolls and skill the raise/rez scrolls
|
||||
iBaseItemType = GetBaseItemType(oItem);
|
||||
if ((iBaseItemType == BASE_ITEM_SCROLL) ||
|
||||
(iBaseItemType == BASE_ITEM_SPELLSCROLL))
|
||||
{
|
||||
// Default scrolls cannot be made plot so don't worry about it.
|
||||
// See if it matches the tags we are looking for.
|
||||
if (FindSubString(HABD_SCROLL_TAGS, ":"+GetTag(oItem)+":") == -1)
|
||||
{
|
||||
iRandomCount++;
|
||||
// If this is the random item then drop it.
|
||||
if ((HABD_DROP_RANDOM_BACKPACK != 0) && (iRandomCount == iRandomBackpack))
|
||||
{
|
||||
if (HABD_DROP_RANDOM_BACKPACK == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
// If this is the most expensive item then drop it.
|
||||
if ((HABD_DROP_MOST_EXPENSIVE_BACKPACK != 0) && (iRandomCount == iHighestGPPos))
|
||||
{
|
||||
if (HABD_DROP_MOST_EXPENSIVE_BACKPACK == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iRandomCount++;
|
||||
// If this is the random item then drop it.
|
||||
if ((HABD_DROP_RANDOM_BACKPACK != 0) && (iRandomCount == iRandomBackpack))
|
||||
{
|
||||
if (HABD_DROP_RANDOM_BACKPACK == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
// If this is the most expensive item then drop it.
|
||||
if ((HABD_DROP_MOST_EXPENSIVE_BACKPACK != 0) && (iRandomCount == iHighestGPPos))
|
||||
{
|
||||
if (HABD_DROP_MOST_EXPENSIVE_BACKPACK == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
}
|
||||
}
|
||||
oItem = GetNextItemInInventory(oPC);
|
||||
}
|
||||
}
|
||||
// Should we drop everything in the backpack that isn't plot?
|
||||
if (HABD_DROP_BACKPACK != 0)
|
||||
{
|
||||
int iBaseItemType;
|
||||
if (HABD_DROP_BACKPACK == 2) SendMessageToPC(oPC, "Destroying all backpack items.");
|
||||
else SendMessageToPC(oPC, "Dropping all backpack items.");
|
||||
oItem = GetFirstItemInInventory(oPC);
|
||||
while (GetIsObjectValid(oItem))
|
||||
{
|
||||
if (HABD_FORCE_RAISE_USES_SCROLLS)
|
||||
{
|
||||
// Search through the scrolls and skill the raise/rez scrolls
|
||||
iBaseItemType = GetBaseItemType(oItem);
|
||||
if ((iBaseItemType == BASE_ITEM_SCROLL) ||
|
||||
(iBaseItemType == BASE_ITEM_SPELLSCROLL))
|
||||
{
|
||||
// Default scrolls cannot be made plot so don't worry about it.
|
||||
// See if it matches the tags we are looking for.
|
||||
if (FindSubString(HABD_SCROLL_TAGS, ":"+GetTag(oItem)+":") == -1)
|
||||
if (GetIsObjectValid(oItem) && (!GetPlotFlag(oItem)))
|
||||
{
|
||||
if (HABD_DROP_BACKPACK == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
} else {
|
||||
if (GetIsObjectValid(oItem) && (!GetPlotFlag(oItem)))
|
||||
{
|
||||
if (HABD_DROP_BACKPACK == 2) DestroyObject(oItem);
|
||||
else AssignCommand(oBag, ActionTakeItem(oItem, oPC));
|
||||
}
|
||||
}
|
||||
}
|
||||
oItem = GetNextItemInInventory(oPC);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Report that a player died. OBJECT_SELF is the dead player.
|
||||
void ReportPlayerDeath();
|
||||
|
||||
void ReportPlayerDeath()
|
||||
{
|
||||
object oPC = OBJECT_SELF;
|
||||
|
||||
// Abort is not a player
|
||||
if (!GetIsPC(oPC)) return;
|
||||
|
||||
int iHPs = GetCurrentHitPoints(oPC);
|
||||
// Abort if player isn't dying
|
||||
if (iHPs > 0) return;
|
||||
|
||||
// Display notification.
|
||||
FloatingTextStringOnCreature(GetName(oPC)+" HAS DIED!", oPC);
|
||||
// Vocal notification.
|
||||
AssignCommand(oPC, PlayVoiceChat(VOICE_CHAT_DEATH, oPC));
|
||||
if (HABD_DM_NOTIFICATION_ON_DEATH) SendMessageToAllDMs("DEAD: "+GetName(oPC)+" HAS DIED");
|
||||
DelayCommand(0.2,FloatingTextStringOnCreature("OOC: YOU HAVE JUST DIED, SO BE QUIET UNTIL YOU ARE RAISED. -DM", oPC, FALSE));
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Recover a player from instant death. This is one of the key functions of
|
||||
// this death system. Instant death isn't possible, you always bleed.
|
||||
// oPC - the player who instantly died.
|
||||
void RecoverInstantDeath(object oPC);
|
||||
|
||||
void RecoverInstantDeath(object oPC)
|
||||
{
|
||||
// Should regeneration items be removed from bleeding players?
|
||||
if (HABD_NERF_REGENERATION_ITEMS)
|
||||
{
|
||||
AssignCommand(oPC, HABDRegenerationItemsUnequip(oPC));
|
||||
}
|
||||
|
||||
// Bring the player back from death and make them bleed.
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oPC);
|
||||
int iBleed = 6+Random(4);
|
||||
SetPlotFlag(oPC, FALSE);
|
||||
// Will leave player at -6 to -9
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDamage(iBleed, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_FIVE), oPC);
|
||||
SetPlotFlag(oPC, TRUE);
|
||||
FloatingTextStringOnCreature("You nearly died! Bleeding starts at -"+IntToString(iBleed), oPC, FALSE);
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// Check to see if the player has any raise or resurrection scrolls on them.
|
||||
// If they do have them then a local object will be set pointing to that item.
|
||||
// oPC - the dead player.
|
||||
// Returns the number of scrolls that they possess.
|
||||
int CheckForRaiseRezScrolls(object oPC);
|
||||
|
||||
int CheckForRaiseRezScrolls(object oPC)
|
||||
{
|
||||
DeleteLocalObject(oPC, HABD_STORED_SCROLL);
|
||||
int iStoredCost = 1000000;
|
||||
int iCost = 0;
|
||||
int iBaseItemType;
|
||||
int iNumFound = 0;
|
||||
object oItem = GetFirstItemInInventory(oPC);
|
||||
while (GetIsObjectValid(oItem))
|
||||
{
|
||||
// Search through the scrolls
|
||||
iBaseItemType = GetBaseItemType(oItem);
|
||||
if ((iBaseItemType == BASE_ITEM_SCROLL) ||
|
||||
(iBaseItemType == BASE_ITEM_SPELLSCROLL))
|
||||
{
|
||||
// Default scrolls cannot be made plot so don't worry about it.
|
||||
// See if it matches the tags we are looking for.
|
||||
if (FindSubString(HABD_SCROLL_TAGS, ":"+GetTag(oItem)+":") != -1)
|
||||
{
|
||||
// Use the least expensive scroll the player has.
|
||||
iCost = GetGoldPieceValue(oItem) / GetItemStackSize(oItem);
|
||||
iNumFound = iNumFound + GetItemStackSize(oItem);
|
||||
if (iCost < iStoredCost)
|
||||
{
|
||||
iStoredCost = iCost;
|
||||
// Store the item because this is what we want to use to
|
||||
// bring them back from the dead.
|
||||
SetLocalObject(oPC, HABD_STORED_SCROLL, oItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
oItem = GetNextItemInInventory(oPC);
|
||||
}
|
||||
return (iNumFound);
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Warn player that they will auto-respawn in fTime seconds.
|
||||
// oPC - the dead player.
|
||||
// fTime - the amount of time until auto-respawn.
|
||||
void AutoRespawnWarning(object oPC, float fTime);
|
||||
|
||||
void AutoRespawnWarning(object oPC, float fTime)
|
||||
{
|
||||
// If the player is no longer dead then kill the warning.
|
||||
if (!GetIsDead(oPC)) return;
|
||||
if (GetLocalInt(GetModule(), HABD_PLAYER_STATE+GetPCPlayerName(oPC)+GetName(oPC)) != HABD_STATE_PLAYER_DEAD) return;
|
||||
// Store
|
||||
SetLocalInt(GetModule(), HABD_RESPAWN_TIMER+GetPCPlayerName(oPC)+GetName(oPC), FloatToInt(fTime));
|
||||
// Warn the player.
|
||||
if(fTime > 1.0) FloatingTextStringOnCreature("OOC: "+GetName(oPC)+" will automatically respawn in "+FloatToString(fTime,4,1)+" seconds.", oPC, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Warn player that they will auto-raise in fTime seconds.
|
||||
// oPC - the dead player.
|
||||
// fTime - the amount of time until auto-raise.
|
||||
void AutoRaiseWarning(object oPC, float fTime);
|
||||
|
||||
void AutoRaiseWarning(object oPC, float fTime)
|
||||
{
|
||||
// If the player is no longer dead then kill the warning.
|
||||
if (!GetIsDead(oPC)) return;
|
||||
if (GetLocalInt(GetModule(), HABD_PLAYER_STATE+GetPCPlayerName(oPC)+GetName(oPC)) != HABD_STATE_PLAYER_DEAD) return;
|
||||
// Store
|
||||
SetLocalInt(GetModule(), HABD_RAISE_TIMER+GetPCPlayerName(oPC)+GetName(oPC), FloatToInt(fTime));
|
||||
// Warn the player.
|
||||
if(fTime > 1.0) FloatingTextStringOnCreature("OOC: "+GetName(oPC)+" will automatically raise in "+FloatToString(fTime,4,1)+" seconds.", oPC, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Forces a dead player to automatically respawn.
|
||||
// oPC - the dead player who is being forced to respawn.
|
||||
void ForceAutoRespawn(object oPC);
|
||||
|
||||
void ForceAutoRespawn(object oPC)
|
||||
{
|
||||
// Make sure the player is dead.
|
||||
if (!GetIsDead(oPC) ||
|
||||
(GetLocalInt(GetModule(), HABD_PLAYER_STATE+GetPCPlayerName(oPC)+GetName(oPC)) != HABD_STATE_PLAYER_DEAD))
|
||||
{
|
||||
DeleteLocalInt(GetModule(), HABD_RESPAWN_TIMER+GetPCPlayerName(oPC)+GetName(oPC));
|
||||
return;
|
||||
}
|
||||
|
||||
// Force the player to respawn.
|
||||
SetLocalInt(oPC, HABD_FORCED_RESPAWN, 1);
|
||||
AssignCommand(oPC, ExecuteScript(HABD_RESPAWN_SCRIPT, oPC));
|
||||
DeleteLocalInt(GetModule(), HABD_RESPAWN_TIMER+GetPCPlayerName(oPC)+GetName(oPC));
|
||||
FloatingTextStringOnCreature("OOC: Automatically respawning "+GetName(oPC)+" because timer elapsed.", oPC, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Forces a dead player to automatically raise.
|
||||
// oPC - the dead player who is being forced to raise.
|
||||
void ForceAutoRaise(object oPC);
|
||||
|
||||
void ForceAutoRaise(object oPC)
|
||||
{
|
||||
// Make sure the player is dead.
|
||||
int iState = GetLocalInt(GetModule(), HABD_PLAYER_STATE+GetPCPlayerName(oPC)+GetName(oPC));
|
||||
if ((iState != HABD_STATE_PLAYER_DEAD) &&
|
||||
(iState != HABD_STATE_RESPAWNED_GHOST))
|
||||
{
|
||||
DeleteLocalInt(GetModule(), HABD_RAISE_TIMER+GetPCPlayerName(oPC)+GetName(oPC));
|
||||
return;
|
||||
}
|
||||
DeleteLocalInt(GetModule(), HABD_RAISE_TIMER+GetPCPlayerName(oPC)+GetName(oPC));
|
||||
// If force raise uses up scrolls, then do so.
|
||||
if (HABD_FORCE_RAISE_USES_SCROLLS)
|
||||
{
|
||||
object oScroll = GetLocalObject(oPC, HABD_STORED_SCROLL);
|
||||
if (GetItemPossessor(oScroll) == oPC)
|
||||
{
|
||||
int iStackSize = GetItemStackSize(oScroll);
|
||||
// Only one item so destroy it, this is why it should only use scrolls.
|
||||
// If it uses a charged item, then this could be wasted.
|
||||
if (iStackSize == 1) DestroyObject(oScroll);
|
||||
else SetItemStackSize(oScroll, iStackSize - 1);
|
||||
} else {
|
||||
FloatingTextStringOnCreature("OOC: Auto-raise aborted for "+GetName(oPC)+" because could not find any scrolls.", oPC, TRUE);
|
||||
return;
|
||||
}
|
||||
DeleteLocalObject(oPC, HABD_STORED_SCROLL);
|
||||
}
|
||||
// Copy of Raise Dead spell script since you can't make a dead player cast raise at themself.
|
||||
if (GetIsDead(oPC))
|
||||
{
|
||||
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_RAISE_DEAD), GetLocation(oPC));
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), oPC);
|
||||
HABDApplyPenaltyIfDead(oPC, SPELL_RAISE_DEAD);
|
||||
} else {
|
||||
HABDCureRespawnGhost(oPC, SPELL_RAISE_DEAD);
|
||||
}
|
||||
// Force the player to respawn.
|
||||
FloatingTextStringOnCreature("OOC: Automatically raising "+GetName(oPC)+" because timer elapsed.", oPC, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Check if a player has spontaneously come back to life.
|
||||
// oPC - the dead player.
|
||||
// fTime - the duration to wait until the next health check.
|
||||
|
||||
void CheckForDMHeal(object oPC, float fTime)
|
||||
{
|
||||
object oMod = GetModule();
|
||||
string sID = GetPCPlayerName(oPC)+GetName(oPC);
|
||||
// Check to see if the player is still alive.
|
||||
int iState = GetLocalInt(oMod, HABD_PLAYER_STATE+sID);
|
||||
if (
|
||||
(iState == HABD_STATE_RESPAWNED_GHOST) ||
|
||||
(iState == HABD_STATE_PLAYER_ALIVE)
|
||||
) return;
|
||||
|
||||
// Quick little timer to check that PCs recover from a DM heal properly.
|
||||
if (GetIsDead(oPC))
|
||||
{
|
||||
DelayCommand(fTime, CheckForDMHeal(oPC, fTime));
|
||||
} else {
|
||||
// Player has been DM healed.
|
||||
SetPlotFlag(oPC, FALSE);
|
||||
SetLocalInt(oMod, HABD_PLAYER_STATE+sID, HABD_STATE_PLAYER_ALIVE);
|
||||
}
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// This is the OnPlayerDeath event handler.
|
||||
|
||||
void main()
|
||||
{
|
||||
object oMod = GetModule();
|
||||
object oPC = GetLastPlayerDied();
|
||||
int iNPC = GetLocalInt(OBJECT_SELF, HABD_NPC_BLEED);
|
||||
if (iNPC == 1) oPC = OBJECT_SELF;
|
||||
string sID = GetPCPlayerName(oPC)+GetName(oPC);
|
||||
|
||||
// If an NPC is running this script, then set up its master. The master was
|
||||
// automatically wiped out when the henchman died.
|
||||
if (iNPC)
|
||||
{
|
||||
if (!GetIsObjectValid(GetAssociate(ASSOCIATE_TYPE_HENCHMAN, GetLocalObject(OBJECT_SELF, HABD_NPC_MASTER))))
|
||||
AddHenchman(GetLocalObject(OBJECT_SELF, HABD_NPC_MASTER), oPC);
|
||||
}
|
||||
|
||||
if (HABD_DEBUG) SpeakString("DEBUG: HABD OnDeath, "+GetName(oPC)+", HP: "+IntToString(GetCurrentHitPoints(oPC))+", master: "+GetName(GetMaster(oPC))+", state:"+HABDGetPlayerStateName(oPC), TALKVOLUME_SHOUT);
|
||||
|
||||
// Check to see if they have bled at all - if not then give them a chance to bleed.
|
||||
if (GetLocalInt(oMod, HABD_PLAYER_STATE+sID) != HABD_STATE_PLAYER_DEAD)
|
||||
{
|
||||
// Player died without going through bleeding.
|
||||
|
||||
// Keep the player from taking additional damage while bleeding.
|
||||
SetPlotFlag(oPC, TRUE);
|
||||
// Special state for this circumstance.
|
||||
SetLocalInt(oMod, HABD_PLAYER_STATE+sID, HABD_STATE_PLAYER_INSTANT_DEATH);
|
||||
// Bring the player to near-death.
|
||||
AssignCommand(oPC, RecoverInstantDeath(oPC));
|
||||
// Force friendly to hostile faction.
|
||||
if (!GetLocalInt(oPC, HABD_OLD_FACTION_SET))
|
||||
{
|
||||
SetLocalInt(oPC, HABD_OLD_FACTION, GetStandardFactionReputation(STANDARD_FACTION_HOSTILE, oPC));
|
||||
SetLocalInt(oPC, HABD_OLD_FACTION_SET, 1);
|
||||
}
|
||||
SetStandardFactionReputation(STANDARD_FACTION_HOSTILE, 100, oPC);
|
||||
// stop nearby attackers
|
||||
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectInvisibility(INVISIBILITY_TYPE_NORMAL), oPC, 6.0));
|
||||
return;
|
||||
}
|
||||
|
||||
// Player has properly died.
|
||||
|
||||
// Check for a DM Heal.
|
||||
AssignCommand(oPC, DelayCommand(6.0, CheckForDMHeal(oPC, 6.0)));
|
||||
|
||||
// Ensure that plot is not still set.
|
||||
SetPlotFlag(oPC, FALSE);
|
||||
// Set playerstate to dead not dying.
|
||||
SetLocalInt(oMod, HABD_PLAYER_STATE+sID, HABD_STATE_PLAYER_DEAD);
|
||||
// Alert that the player died.
|
||||
AssignCommand(oPC, ReportPlayerDeath());
|
||||
|
||||
// Check if we are re-entering this state from persistence.
|
||||
if (GetLocalInt(oPC, HABD_PERSISTANT_REAPPLY) != 1)
|
||||
{
|
||||
// Set the auto-respawn/raise timers to maximum.
|
||||
SetLocalInt(oMod, HABD_RESPAWN_TIMER+sID, FloatToInt(HABD_FORCE_RESPAWN_TIMER));
|
||||
if ((HABD_SOLO_FORCE_RAISE_TIMER > 0.0) && (HABDGetPartySize(oPC)))
|
||||
{
|
||||
SetLocalInt(oMod, HABD_RAISE_TIMER+sID, FloatToInt(HABD_SOLO_FORCE_RAISE_TIMER));
|
||||
} else {
|
||||
SetLocalInt(oMod, HABD_RAISE_TIMER+sID, FloatToInt(HABD_FORCE_RAISE_TIMER));
|
||||
}
|
||||
// Increment the counters.
|
||||
SetLocalInt(oMod, HABD_CURRENT_DEATH_COUNT+sID, GetLocalInt(oMod, HABD_CURRENT_DEATH_COUNT+sID) + 1);
|
||||
SetLocalInt(oMod, HABD_DEATH_COUNT+sID, GetLocalInt(oMod, HABD_DEATH_COUNT+sID) + 1);
|
||||
} else {
|
||||
// State was reapplied, do not increment the counters.
|
||||
DeleteLocalInt(oPC, HABD_PERSISTANT_REAPPLY);
|
||||
// Autoraise timers will use their persistent values.
|
||||
}
|
||||
|
||||
// Should we reequip any regeneraton items?
|
||||
if (HABD_NERF_REGENERATION_ITEMS)
|
||||
{
|
||||
AssignCommand(oPC, HABDRegenerationItemsReEquip(oPC));
|
||||
}
|
||||
|
||||
// Drop items
|
||||
AssignCommand(oPC, DropItems(oPC));
|
||||
|
||||
// Respawn option can be disabled.
|
||||
if (HABD_RESPAWN_ALLOWED)
|
||||
{
|
||||
PopUpDeathGUIPanel (oPC, HABD_INSTANT_RESPAWN_ALLOWED, TRUE, 0, "Press the Respawn button to respawn as a DM controlled ghost. "+IntToString(HABD_RESPAWN_XP_LOSS)+"% XP & "+IntToString(HABD_RESPAWN_GP_LOSS)+"% GP penalty applies.");
|
||||
} else {
|
||||
FloatingTextStringOnCreature("OOC: Respawn is turned off. You must wait for your party to help you, DM intervention or automatic respawn/raise.", oPC, FALSE);
|
||||
}
|
||||
|
||||
// Handle the auto-respawn and auto-raise timers.
|
||||
float fRespawn = IntToFloat(GetLocalInt(oMod, HABD_RESPAWN_TIMER+sID));
|
||||
float fRaise = IntToFloat(GetLocalInt(oMod, HABD_RAISE_TIMER+sID));
|
||||
if (iNPC)
|
||||
{
|
||||
// The respawn timer must be less than the raise timer for it to execute.
|
||||
if ((fRespawn > 0.0) && ((fRespawn < fRaise) || (fRaise == 0.0)))
|
||||
{
|
||||
AssignCommand(oPC, DelayCommand(HABD_NPC_FORCE_RESPAWN_TIMER, ForceAutoRespawn(oPC)));
|
||||
}
|
||||
if (fRaise > 0.0)
|
||||
{
|
||||
if (HABD_FORCE_RAISE_USES_SCROLLS)
|
||||
{
|
||||
if (CheckForRaiseRezScrolls(oPC) <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
AssignCommand(oPC, DelayCommand(HABD_NPC_FORCE_RAISE_TIMER, ForceAutoRaise(oPC)));
|
||||
}
|
||||
} else {
|
||||
// The respawn timer must be less than the raise timer for it to execute.
|
||||
if ((fRespawn > 0.0) && ((fRespawn < fRaise) || (fRaise == 0.0)))
|
||||
{
|
||||
AssignCommand(oPC, AutoRespawnWarning(oPC, fRespawn));
|
||||
AssignCommand(oPC, DelayCommand(0.5 * fRespawn, AutoRespawnWarning(oPC, 0.5 * fRespawn)));
|
||||
AssignCommand(oPC, DelayCommand(0.75*fRespawn, AutoRespawnWarning(oPC, 0.25*fRespawn)));
|
||||
AssignCommand(oPC, DelayCommand(9*fRespawn, AutoRespawnWarning(oPC, 0.1*fRespawn)));
|
||||
AssignCommand(oPC, DelayCommand(fRespawn, ForceAutoRespawn(oPC)));
|
||||
}
|
||||
if (fRaise > 0.0)
|
||||
{
|
||||
if (HABD_FORCE_RAISE_USES_SCROLLS)
|
||||
{
|
||||
if (CheckForRaiseRezScrolls(oPC) <= 0)
|
||||
{
|
||||
FloatingTextStringOnCreature("OOC: Out of scrolls. You have to wait for help.", oPC, FALSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
AssignCommand(oPC, AutoRaiseWarning(oPC, fRaise));
|
||||
AssignCommand(oPC, DelayCommand(0.5 * fRaise, AutoRaiseWarning(oPC, 0.5 * fRaise)));
|
||||
AssignCommand(oPC, DelayCommand(0.75*fRaise, AutoRaiseWarning(oPC, 0.25*fRaise)));
|
||||
AssignCommand(oPC, DelayCommand(9*fRaise, AutoRaiseWarning(oPC, 0.1*fRaise)));
|
||||
AssignCommand(oPC, DelayCommand(fRaise, ForceAutoRaise(oPC)));
|
||||
}
|
||||
}
|
||||
// DO NOT ADD ANY CODE HERE. IT MIGHT NOT BE EXECUTED.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
361
_module/nss/habd_onpcdying.nss
Normal file
361
_module/nss/habd_onpcdying.nss
Normal file
@@ -0,0 +1,361 @@
|
||||
// Hemophiliacs Always Bleed to Death
|
||||
// By Demtrious and OldManWhistler
|
||||
//
|
||||
// PLEASE READ "habd_include" FOR MORE INFORMATION.
|
||||
//
|
||||
// OnPlayerDying event handler.
|
||||
|
||||
#include "habd_include"
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// This function plays a random bleeding VoiceChat on a player.
|
||||
// oPC - the player to make play a bleed voice.
|
||||
void PlayBleedVoice (object oPC);
|
||||
|
||||
void PlayBleedVoice (object oPC)
|
||||
{
|
||||
switch (d6())
|
||||
{
|
||||
case 1: PlayVoiceChat (VOICE_CHAT_PAIN1, oPC); break;
|
||||
case 2: PlayVoiceChat (VOICE_CHAT_PAIN2, oPC); break;
|
||||
case 3: PlayVoiceChat (VOICE_CHAT_PAIN3, oPC); break;
|
||||
case 4: PlayVoiceChat (VOICE_CHAT_HEALME, oPC); break;
|
||||
case 5: PlayVoiceChat (VOICE_CHAT_NEARDEATH, oPC); break;
|
||||
case 6: PlayVoiceChat (VOICE_CHAT_HELP, oPC); break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Heals players to 1 hp and to removes negative effects. In also calls the
|
||||
// user defined bleed stabilization function.
|
||||
// oPC - the player to heal.
|
||||
void HealTo1HP(object oPC);
|
||||
|
||||
void HealTo1HP(object oPC)
|
||||
{
|
||||
object oMod = GetModule();
|
||||
string sID = GetPCPlayerName(oPC)+GetName(oPC);
|
||||
// If player is already alive then abort.
|
||||
if (GetLocalInt(oMod, HABD_PLAYER_STATE+sID) == HABD_STATE_PLAYER_ALIVE) return;
|
||||
int iNPC = GetLocalInt(OBJECT_SELF, HABD_NPC_BLEED);
|
||||
|
||||
// Give the player a chance to run away
|
||||
if (HABD_POST_BLEED_INVIS_DUR > 0.0) ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectInvisibility(INVISIBILITY_TYPE_NORMAL), oPC, HABD_POST_BLEED_INVIS_DUR);
|
||||
// Turn the plot flag off after a specific period of time.
|
||||
SetPlotFlag(oPC, FALSE);
|
||||
// Raises the player to 1 hp.
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(1 - (GetCurrentHitPoints(oPC))), oPC);
|
||||
SetLocalInt(oMod,HABD_PLAYER_STATE+sID, HABD_STATE_PLAYER_ALIVE); //set player state to alive
|
||||
// If this is a henchmen, then take them out of the busy state.
|
||||
if (iNPC)
|
||||
{
|
||||
HABDAssociateNotBusy();
|
||||
}
|
||||
|
||||
// Keep the player from being attacked, stop nearby attackers
|
||||
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectInvisibility(INVISIBILITY_TYPE_NORMAL), oPC, 6.0));
|
||||
// Make the player hostile again.
|
||||
SetStandardFactionReputation(STANDARD_FACTION_HOSTILE, GetLocalInt(oPC, HABD_OLD_FACTION), oPC);
|
||||
DeleteLocalInt(oPC, HABD_OLD_FACTION_SET);
|
||||
AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_PAUSE_DRUNK, 1.0, 5.0));
|
||||
|
||||
// Notify the player that they were healed.
|
||||
DelayCommand(0.5, SendMessageToPC(oPC, "You have healed."));
|
||||
|
||||
// Apply user defined penalties.
|
||||
AssignCommand(oPC, HABDUserDefinedBleed());
|
||||
|
||||
//Give a little visual effect for flare.
|
||||
effect eVisual = EffectVisualEffect(VFX_IMP_RESTORATION);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVisual, oPC);
|
||||
|
||||
// If regeneration items were removed then reequip them.
|
||||
if (HABD_NERF_REGENERATION_ITEMS)
|
||||
{
|
||||
AssignCommand(oPC, HABDRegenerationItemsReEquip(oPC));
|
||||
}
|
||||
|
||||
// Fixes the inital respawn issue with monsters not reattacking.
|
||||
//object oMonster = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oPC, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
|
||||
//DelayCommand(9.0, AssignCommand(oMonster, ActionAttack(oPC)));
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Returns TRUE if the player has stabilized by gaining any HP since the last
|
||||
// time they bled.
|
||||
int CheckForStabilization(object oPC);
|
||||
|
||||
int CheckForStabilization(object oPC)
|
||||
{
|
||||
object oMod = GetModule();
|
||||
string sID = GetPCPlayerName(oPC)+GetName(oPC);
|
||||
//Section deals with possiblity for healing by other players
|
||||
if (GetCurrentHitPoints(oPC) > GetLocalInt(oMod, HABD_LAST_HP+sID)) //if hitpoint have increased
|
||||
{
|
||||
DelayCommand(1.0, HealTo1HP(oPC));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Report the bleed count for OBJECT_SELF.
|
||||
void ReportPlayerBleed();
|
||||
|
||||
void ReportPlayerBleed()
|
||||
{
|
||||
object oPC = OBJECT_SELF;
|
||||
object oMod = GetModule();
|
||||
string sID = GetPCPlayerName(oPC)+GetName(oPC);
|
||||
int iHPs = GetCurrentHitPoints(oPC);
|
||||
int iNPC = GetLocalInt(OBJECT_SELF, HABD_NPC_BLEED);
|
||||
if (iNPC) iHPs = iHPs - 10;
|
||||
|
||||
if (
|
||||
(GetLocalInt(oMod, HABD_PLAYER_STATE+sID) != HABD_STATE_PLAYER_BLEEDING) || // check if player is still bleeding
|
||||
(iHPs > 0) || // player has healed
|
||||
(iHPs <= -10) || // player is a goner, let the death script kick in
|
||||
(CheckForStabilization(oPC)) // check if player has gained any HP
|
||||
)
|
||||
{
|
||||
DeleteLocalInt(oPC, HABD_REPORT_BLEED_RUNNING);
|
||||
return;
|
||||
}
|
||||
// The delay will effect how often players are vocal about bleeding.
|
||||
DelayCommand(6.0, AssignCommand(oPC, ReportPlayerBleed()));
|
||||
|
||||
// Prevent calling this function multiple times
|
||||
SetLocalInt(oPC, HABD_REPORT_BLEED_RUNNING, 1);
|
||||
|
||||
DelayCommand(0.1, FloatingTextStringOnCreature(GetName(oPC)+" is bleeding to death! At "+IntToString(iHPs)+" hitpoints.", oPC));
|
||||
if (HABD_DM_NOTIFICATION_ON_BLEED) SendMessageToAllDMs(GetName(oPC)+" is bleeding to death! At "+IntToString(iHPs)+" hitpoints.");
|
||||
PlayBleedVoice(oPC);
|
||||
AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_DEAD_BACK, 1.0, 6.0));
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// This function exists to fix the problem that occurs in bleeding scripts
|
||||
// when the summoned familiar is being possessed by the player (sorc or wiz).
|
||||
// That creates a condition where GetIsPC returns true for the familiar.
|
||||
// What usually happens is that when the possessed familiar dies, the player
|
||||
// is trapped in its body until the DM manually kills the player.
|
||||
// While stuck in the dead familiar, the player is unable to run the unpossess
|
||||
// action and the bleed count on the familiar usually does not work properly.
|
||||
|
||||
// This function DOES NOT kill the familiar when the player is bleeding if the player
|
||||
// is not possessing the familiar. The familiar will be able to continue fighting
|
||||
// for its unconcious and bleeding master.
|
||||
// oTarget - the possibly "possessed" player.
|
||||
int KillPet(object oTarget, int nEffect = TRUE, int nVisualEffectId = VFX_IMP_UNSUMMON);
|
||||
|
||||
int KillPet(object oTarget, int nEffect = TRUE, int nVisualEffectId = VFX_IMP_UNSUMMON)
|
||||
{
|
||||
// Usage: place in your bleeding script with a call that looks something like
|
||||
// if (KillPet(oPC)) return; // abort from the bleed script, oPC no longer exists
|
||||
|
||||
effect eDeath = EffectDeath(FALSE, FALSE);
|
||||
effect eVis = EffectVisualEffect(nVisualEffectId);
|
||||
object oCreature = oTarget;
|
||||
if(GetIsObjectValid(oCreature))
|
||||
{
|
||||
object oMaster = GetMaster(oCreature);
|
||||
if(GetIsObjectValid(oMaster))
|
||||
{
|
||||
//Is the creature a summoned associate
|
||||
if(GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oMaster) == oCreature)
|
||||
{
|
||||
//Apply the VFX and delay the destruction of the summoned monster so
|
||||
//that the script and VFX can play.
|
||||
if(nEffect)
|
||||
DelayCommand(0.001,ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY,eVis,GetLocation(oCreature),1.0f));
|
||||
SetPlotFlag(oCreature, FALSE);
|
||||
DelayCommand(0.002,FloatingTextStringOnCreature(GetName(oMaster)+" HAS LOST FAMILIAR '"+GetName(oCreature)+"'", oCreature));
|
||||
if (HABD_DM_NOTIFICATION_ON_BLEED) SendMessageToAllDMs(GetName(oMaster)+" HAS LOST FAMILIAR '"+GetName(oCreature)+"'");
|
||||
DelayCommand(0.003, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDeath, oCreature));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// Applies -1 HP to the player and checks for stabilization.
|
||||
// fBleedTimer - the time duration between bleeding -1 HP.
|
||||
void BleedToDeath(float fBleedTimer)
|
||||
{
|
||||
object oMod = GetModule();
|
||||
object oPC = OBJECT_SELF;
|
||||
string sID = GetPCPlayerName(oPC)+GetName(oPC);
|
||||
int iNPC = GetLocalInt(OBJECT_SELF, HABD_NPC_BLEED);
|
||||
if (HABD_DEBUG) SpeakString("DEBUG: HABD OnBleed, "+GetName(oPC)+", HP: "+IntToString(GetCurrentHitPoints(oPC))+", master: "+GetName(GetMaster(oPC))+", state:"+HABDGetPlayerStateName(oPC), TALKVOLUME_SHOUT);
|
||||
|
||||
int iPlayerState = GetLocalInt(oMod, HABD_PLAYER_STATE+sID);
|
||||
if (iPlayerState != HABD_STATE_PLAYER_BLEEDING) return;
|
||||
if (CheckForStabilization(oPC)) return;
|
||||
|
||||
// if you get here - you are dying and have not been healed
|
||||
// so you need to roll to see if you stablize
|
||||
int nSavingRoll = d10();
|
||||
|
||||
// Death can be disabled before a certain level by "faking" the stabilization
|
||||
// check. Do not let the players know that death is disabled because it will
|
||||
// only encourage them to be idiots.
|
||||
if ((HABD_NO_DEATH_UNTIL_LEVEL) && (GetHitDice(oPC) < HABD_NO_DEATH_UNTIL_LEVEL))
|
||||
{
|
||||
switch (GetCurrentHitPoints(oPC))
|
||||
{
|
||||
case 10:
|
||||
case -1: nSavingRoll = nSavingRoll + 2; break;
|
||||
case 9:
|
||||
case -2: nSavingRoll = nSavingRoll + 3; break;
|
||||
case 8:
|
||||
case -3: nSavingRoll = nSavingRoll + 4; break;
|
||||
case 7:
|
||||
case -4: nSavingRoll = nSavingRoll + 5; break;
|
||||
case 6:
|
||||
case -5: nSavingRoll = nSavingRoll + 6; break;
|
||||
case 5:
|
||||
case -6: nSavingRoll = nSavingRoll + 7; break;
|
||||
case 4:
|
||||
case -7: nSavingRoll = nSavingRoll + 8; break;
|
||||
case 3:
|
||||
case -8: nSavingRoll = nSavingRoll + 9; break;
|
||||
case 2:
|
||||
case -9:
|
||||
default: nSavingRoll = nSavingRoll + 10; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nSavingRoll > 9) //set to 9 for 3E - lower for easier stabilization
|
||||
{
|
||||
DelayCommand(1.0, HealTo1HP(oPC)); //call heal subroutine
|
||||
// Always make it look like they rolled a 10 to stabilize
|
||||
SendMessageToPC(oPC,"Saving Roll to stop bleeding (at "+IntToString(GetCurrentHitPoints(oPC))+") = 10");
|
||||
FloatingTextStringOnCreature(GetName(oPC)+" has self-stabilized.", oPC);
|
||||
DelayCommand(6.0, SendMessageToPC(oPC, "In a life or death effort you have survived, alive but barely."));
|
||||
return;
|
||||
}
|
||||
//if you get here, you have not been healed and did not successfully stabilize
|
||||
else
|
||||
{
|
||||
// Most important, keep the bleeding chain going.
|
||||
DelayCommand(fBleedTimer, AssignCommand(oPC, BleedToDeath(fBleedTimer)));
|
||||
SendMessageToPC(oPC,"Saving Roll to stop bleeding (at "+IntToString(GetCurrentHitPoints(oPC))+") = " +IntToString(nSavingRoll));
|
||||
SetPlotFlag(oPC, FALSE);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectDamage(1,DAMAGE_TYPE_MAGICAL,DAMAGE_POWER_PLUS_FIVE), oPC);
|
||||
SetPlotFlag(oPC, TRUE);
|
||||
// Update local variable with hitpoints for healing option.
|
||||
SetLocalInt(oMod,HABD_LAST_HP+sID, GetCurrentHitPoints(oPC));
|
||||
|
||||
// if this is true then the player has died.
|
||||
if (GetCurrentHitPoints(oPC) <= -10)
|
||||
{
|
||||
SendMessageToPC(oPC,"You have died.");
|
||||
// Ensure that plot is not still set.
|
||||
SetPlotFlag(oPC, FALSE);
|
||||
// Set up the hostile faction again.
|
||||
SetStandardFactionReputation(STANDARD_FACTION_HOSTILE, GetLocalInt(oPC, HABD_OLD_FACTION), oPC);
|
||||
DeleteLocalInt(oPC, HABD_OLD_FACTION_SET);
|
||||
// Set playerstate to dead not dying
|
||||
SetLocalInt(oMod,HABD_PLAYER_STATE+sID, HABD_STATE_PLAYER_DEAD);
|
||||
// OnPlayerDead script will be called after this.
|
||||
// BleedToDeath will be called one more time, but it will instantly
|
||||
// abort because the player is not in the bleeding state.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// OnPlayerDying event handler.
|
||||
void main()
|
||||
{
|
||||
object oMod = GetModule();
|
||||
object oPC = GetLastPlayerDying();
|
||||
int iNPC = GetLocalInt(OBJECT_SELF, HABD_NPC_BLEED);
|
||||
if (iNPC == 1) oPC = OBJECT_SELF;
|
||||
string sID = GetPCPlayerName(oPC)+GetName(oPC);
|
||||
|
||||
// If an NPC is running this script, then set up its master. The master was
|
||||
// automatically wiped out when the henchman died.
|
||||
if (iNPC)
|
||||
{
|
||||
if (!GetIsObjectValid(GetAssociate(ASSOCIATE_TYPE_HENCHMAN, GetLocalObject(OBJECT_SELF, HABD_NPC_MASTER))))
|
||||
AddHenchman(GetLocalObject(OBJECT_SELF, HABD_NPC_MASTER), oPC);
|
||||
}
|
||||
|
||||
if (HABD_DEBUG) SpeakString("DEBUG: HABD OnDying, "+GetName(oPC)+", HP: "+IntToString(GetCurrentHitPoints(oPC))+", master: "+GetName(GetMaster(oPC))+", state:"+HABDGetPlayerStateName(oPC), TALKVOLUME_SHOUT);
|
||||
|
||||
// Check if bleeding is running on DM or DM possessed, then abort.
|
||||
if(GetIsDM(oPC) || GetIsDM(GetMaster(oPC))) return;
|
||||
|
||||
// whistler: if this is a player in a possessed familiar, then just kill it.
|
||||
// Familiar penalties will kick in when familiar dies.
|
||||
if (KillPet(oPC)) return;
|
||||
|
||||
int iState = GetLocalInt(oMod,HABD_PLAYER_STATE+sID);
|
||||
if ((iState == HABD_STATE_PLAYER_DEAD) || (iState == HABD_STATE_RESPAWNED_GHOST)) return;
|
||||
|
||||
// Most important, issue the commands to start the bleeding chain.
|
||||
float fBleedTimer = HABDGetBleedTimer(oPC);
|
||||
AssignCommand(oPC, DelayCommand(fBleedTimer, BleedToDeath(fBleedTimer)));
|
||||
if (GetLocalInt(oPC, HABD_REPORT_BLEED_RUNNING) == 0) DelayCommand(6.0, AssignCommand(oPC, ReportPlayerBleed()));
|
||||
|
||||
int iHPs = GetCurrentHitPoints(oPC);
|
||||
SetPlotFlag(oPC, TRUE);
|
||||
// Force friendly to hostile faction.
|
||||
if (!GetLocalInt(oPC, HABD_OLD_FACTION_SET))
|
||||
{
|
||||
SetLocalInt(oPC, HABD_OLD_FACTION, GetStandardFactionReputation(STANDARD_FACTION_HOSTILE, oPC));
|
||||
SetLocalInt(oPC, HABD_OLD_FACTION_SET, 1);
|
||||
}
|
||||
SetStandardFactionReputation(STANDARD_FACTION_HOSTILE, 100, oPC);
|
||||
// Keep the player from being attacked, stop nearby attackers
|
||||
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectInvisibility(INVISIBILITY_TYPE_NORMAL), oPC, 6.0));
|
||||
|
||||
// Allow a good chance for healing - will limit HP to -5 on a bleed level hit.
|
||||
if (
|
||||
(iHPs<-5) &&
|
||||
(iState == HABD_STATE_PLAYER_ALIVE)
|
||||
)
|
||||
{
|
||||
int nHeal = -5 - iHPs; //should heal player to -5
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHeal), oPC);
|
||||
}
|
||||
|
||||
// Set the state variables.
|
||||
iHPs = GetCurrentHitPoints(oPC);
|
||||
SetLocalInt(oMod,HABD_PLAYER_STATE+sID, HABD_STATE_PLAYER_BLEEDING);
|
||||
SetLocalInt(oMod,HABD_LAST_HP+sID, GetCurrentHitPoints(oPC));
|
||||
|
||||
// Check if we are re-entering this state from persistence.
|
||||
if (GetLocalInt(oPC, HABD_PERSISTANT_REAPPLY) != 1)
|
||||
{
|
||||
// Increment the counters.
|
||||
SetLocalInt(oMod, HABD_CURRENT_BLEED_COUNT+sID, GetLocalInt(oMod, HABD_CURRENT_BLEED_COUNT+sID) + 1);
|
||||
SetLocalInt(oMod, HABD_BLEED_COUNT+sID, GetLocalInt(oMod, HABD_BLEED_COUNT+sID) + 1);
|
||||
} else {
|
||||
DeleteLocalInt(oPC, HABD_PERSISTANT_REAPPLY);
|
||||
}
|
||||
|
||||
// Nerf regeneration items.
|
||||
if (HABD_NERF_REGENERATION_ITEMS)
|
||||
{
|
||||
AssignCommand(oPC, HABDRegenerationItemsUnequip(oPC));
|
||||
}
|
||||
|
||||
// Notify that bleeding has started.
|
||||
if (iNPC) iHPs = iHPs - 10;
|
||||
string sMsg = GetName(oPC)+" is bleeding to death! At "+IntToString(iHPs)+" hitpoints. Will die in "+FloatToString((10 + iHPs)*fBleedTimer, 3, 0)+" seconds.";
|
||||
if (HABD_DM_NOTIFICATION_ON_BLEED) SendMessageToAllDMs(sMsg);
|
||||
FloatingTextStringOnCreature(sMsg, oPC);
|
||||
}
|
165
_module/nss/habd_onpcrespawn.nss
Normal file
165
_module/nss/habd_onpcrespawn.nss
Normal file
@@ -0,0 +1,165 @@
|
||||
// Hemophiliacs Always Bleed to Death
|
||||
// By Demtrious and OldManWhistler
|
||||
//
|
||||
// PLEASE READ "habd_include" FOR MORE INFORMATION.
|
||||
//
|
||||
// OnPlayerRespawn event handler.
|
||||
|
||||
#include "habd_include"
|
||||
|
||||
// Change this value if it is causing server lag.
|
||||
const float GHOST_LOOP_TIMER = 6.0f;
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// This function acts as a player heartbeat while the player is under the
|
||||
// "respawn effect".
|
||||
// oOldFollow - is the last object the player was told to follow.
|
||||
|
||||
void Ghost(object oOldFollow = OBJECT_INVALID)
|
||||
{
|
||||
object oMod = GetModule();
|
||||
object oPC = OBJECT_SELF;
|
||||
string sID = GetPCPlayerName(oPC)+GetName(oPC);
|
||||
|
||||
if (HABD_DEBUG) SpeakString("DEBUG: HABD OnGhostHB, "+GetName(oPC)+", PlotFlag:"+IntToString(GetPlotFlag(OBJECT_SELF))+", CommandableFlag:"+IntToString(GetCommandable())+", HP: "+IntToString(GetCurrentHitPoints(oPC))+", master: "+GetName(GetMaster(oPC))+", state:"+HABDGetPlayerStateName(oPC), TALKVOLUME_SHOUT);
|
||||
|
||||
if (
|
||||
(GetPlotFlag(OBJECT_SELF)) &&
|
||||
(GetLocalInt(oMod, HABD_PLAYER_STATE+sID) == HABD_STATE_RESPAWNED_GHOST)
|
||||
)
|
||||
{
|
||||
// Is there someone to follow?
|
||||
object oFollow = GetLocalObject(oPC, HABD_GHOST_AUTOFOLLOW);
|
||||
HABDAssociateBusy();
|
||||
SetCommandable(TRUE);
|
||||
// Most important, schedule the next iteration of the heartbeat.
|
||||
DelayCommand(GHOST_LOOP_TIMER, Ghost(oFollow));
|
||||
if (GetIsObjectValid(oFollow))
|
||||
{
|
||||
if (oFollow != oOldFollow) FloatingTextStringOnCreature(GetName(OBJECT_SELF)+" is now following "+ GetName(oFollow), oPC, TRUE);
|
||||
if (GetArea(OBJECT_SELF) != GetArea(oFollow))
|
||||
{
|
||||
SendMessageToPC(oPC, "Jumping to "+GetName(oFollow));
|
||||
// Not in same area, jump them there
|
||||
ClearAllActions();
|
||||
ActionJumpToObject(oFollow);
|
||||
} else {
|
||||
// In same area, move them there
|
||||
ClearAllActions();
|
||||
DelayCommand(0.5, ActionForceFollowObject(oFollow, 6.0f));
|
||||
}
|
||||
}
|
||||
// Remove their ability to control themselves
|
||||
SetCommandable(FALSE);
|
||||
} else {
|
||||
// Respawn state has been removed. Restore the player to normal.
|
||||
SetCommandable(TRUE);
|
||||
SetPlotFlag(OBJECT_SELF, FALSE);
|
||||
// Set playerstate to alive.
|
||||
SetLocalInt(oMod, HABD_PLAYER_STATE+sID, HABD_STATE_PLAYER_ALIVE);
|
||||
FloatingTextStringOnCreature("OOC: You shake off the ghostly effects.", OBJECT_SELF, FALSE);
|
||||
// Restore the player's reputation with HOSTILE faction.
|
||||
SetStandardFactionReputation(STANDARD_FACTION_HOSTILE, GetLocalInt(oPC, HABD_OLD_FACTION), oPC);
|
||||
DeleteLocalInt(oPC, HABD_OLD_FACTION_SET);
|
||||
effect eEffect = GetFirstEffect(OBJECT_SELF);
|
||||
while(GetIsEffectValid(eEffect))
|
||||
{
|
||||
// They are rezzed, remove sanctuary visual effects.
|
||||
if (GetEffectType(eEffect) == EFFECT_TYPE_CONCEALMENT)
|
||||
{
|
||||
RemoveEffect(OBJECT_SELF, eEffect);
|
||||
}
|
||||
eEffect = GetNextEffect(OBJECT_SELF);
|
||||
}
|
||||
HABDAssociateNotBusy();
|
||||
AssignCommand(OBJECT_SELF, ClearAllActions());
|
||||
// Fixes the inital respawn issue with monsters not reattacking.
|
||||
object oMonster = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY,oPC, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
|
||||
DelayCommand(9.0, AssignCommand(oMonster, ActionAttack(oPC)));
|
||||
}
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// OnPlayerRespawn event handler.
|
||||
|
||||
void main()
|
||||
{
|
||||
// Check to see if the system is supposed to run this script, otherwise
|
||||
// it may be configured improperly.
|
||||
if (HABD_RESPAWN_SCRIPT != "habd_onpcrespawn")
|
||||
{
|
||||
ExecuteScript(HABD_RESPAWN_SCRIPT, OBJECT_SELF);
|
||||
return;
|
||||
}
|
||||
|
||||
object oPC;
|
||||
// Catch if the script was forced to executed.
|
||||
if (GetLocalInt(OBJECT_SELF, HABD_FORCED_RESPAWN) == 1)
|
||||
{
|
||||
oPC = OBJECT_SELF;
|
||||
HABDAssociateBusy();
|
||||
} else {
|
||||
oPC = GetLastRespawnButtonPresser();
|
||||
}
|
||||
object oMod = GetModule();
|
||||
string sID = GetPCPlayerName(oPC)+GetName(oPC);
|
||||
|
||||
if (HABD_DEBUG) SpeakString("DEBUG: HABD OnRespawn, "+GetName(oPC)+", HP: "+IntToString(GetCurrentHitPoints(oPC))+", master: "+GetName(GetMaster(oPC))+", state:"+HABDGetPlayerStateName(oPC), TALKVOLUME_SHOUT);
|
||||
/*
|
||||
// Set the player state to respawn.
|
||||
SetLocalInt(oMod, HABD_PLAYER_STATE+sID, HABD_STATE_RESPAWNED_GHOST); //set playerstate to DM raised.
|
||||
|
||||
// Make it look like something happened.
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_DOOM), oPC);
|
||||
*/
|
||||
// Raise the player.
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), oPC);
|
||||
/*
|
||||
// Most important, schedule the ghost heartbeat.
|
||||
AssignCommand(oPC, DelayCommand(3.0, Ghost()));
|
||||
|
||||
// If they have a master, set up the master as the autofollow.
|
||||
if (GetIsObjectValid(GetMaster(oPC))) SetLocalObject(oPC, HABD_GHOST_AUTOFOLLOW, GetMaster(oPC));
|
||||
else
|
||||
{
|
||||
// Remove any old autofollow objects.
|
||||
DeleteLocalObject(oPC, HABD_GHOST_AUTOFOLLOW);
|
||||
}
|
||||
|
||||
// Apply the user defined effects.
|
||||
AssignCommand(oPC, HABDUserDefinedRespawn());
|
||||
*/
|
||||
// Check if we are re-entering this state from persistence.
|
||||
if (GetLocalInt(oPC, HABD_PERSISTANT_REAPPLY) != 1)
|
||||
{
|
||||
// Apply the respawn penalty.
|
||||
HABDApplyPenalty(oPC, HABD_RESPAWN_XP_LOSS, HABD_RESPAWN_GP_LOSS);
|
||||
} else {
|
||||
DeleteLocalInt(oPC, HABD_PERSISTANT_REAPPLY);
|
||||
}
|
||||
/*
|
||||
// Make them invulnerable
|
||||
SetPlotFlag(oPC, TRUE);
|
||||
|
||||
// Make them ignored by hostiles
|
||||
if (!GetLocalInt(oPC, HABD_OLD_FACTION_SET))
|
||||
{
|
||||
SetLocalInt(oPC, HABD_OLD_FACTION, GetStandardFactionReputation(STANDARD_FACTION_HOSTILE, oPC));
|
||||
SetLocalInt(oPC, HABD_OLD_FACTION_SET, 1);
|
||||
}
|
||||
SetStandardFactionReputation(STANDARD_FACTION_HOSTILE, 100, oPC);
|
||||
|
||||
// Apply effects to make them a ghost.
|
||||
// Don't set the concealment too high just incase they find a way to abuse the system.
|
||||
effect eBad = EffectConcealment(1);
|
||||
eBad = EffectLinkEffects(EffectVisualEffect(VFX_DUR_PROT_SHADOW_ARMOR), eBad);
|
||||
eBad = EffectLinkEffects(EffectVisualEffect(VFX_DUR_GHOSTLY_VISAGE), eBad);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBad, oPC);
|
||||
|
||||
FloatingTextStringOnCreature("OOC: You are a ghost. Do not interact with the other players.", oPC, FALSE);
|
||||
SetCommandable(FALSE, oPC);
|
||||
*/
|
||||
}
|
||||
|
333
_module/nss/j_inc_walk.nss
Normal file
333
_module/nss/j_inc_walk.nss
Normal file
@@ -0,0 +1,333 @@
|
||||
// Walk waypoints include.
|
||||
|
||||
int NW_FLAG_STEALTH = 0x00000004;
|
||||
int NW_FLAG_SEARCH = 0x00000008;
|
||||
int NW_FLAG_DAY_NIGHT_POSTING = 0x00100000;
|
||||
|
||||
// Animations:
|
||||
// Randomwalk normally, or move to nearest ally.
|
||||
int AMBIENT_ANIMATIONS = 1;
|
||||
// These will face nearest ally, and talk or laugh. If no ally then look right/left.
|
||||
int IMMOBILE_AMBIENT_ANIMATIONS = 2;
|
||||
// This is the bird animations.
|
||||
int AMBIENT_ANIMATIONS_AVIAN = 3;
|
||||
// This will make the creatures "group" and sit, and normally talk.
|
||||
int AMBIENT_GROUP_ANIMATIONS = 4;
|
||||
// This will make the creature talk with nearby allies, as to not look dead.
|
||||
// Also, if alone, it will take drinks, and things like that.
|
||||
int IMMOBILE_ANIMATIONS_AND_SOLO = 5;
|
||||
// This is a consitution for just random walking, nothing else.
|
||||
int AMBIENT_ANIMAL_WALKING = 6;
|
||||
|
||||
// Run the circuit.
|
||||
void RunCircuit(int nTens, int nNum, int nRun = FALSE, float fPause = 1.0);
|
||||
// Base for moving round thier waypoints
|
||||
void WalkWayPoints(int nRun = FALSE, float fPause = 1.0);
|
||||
// Used in walk waypoints
|
||||
void RunNextCircuit(int nRun = FALSE, float fPause = 1.0);
|
||||
// Checks which waypoint they are on, if any valid. TRUE if got any waypoints in range.
|
||||
int CheckWayPoints(object oWalker = OBJECT_SELF);
|
||||
//Returns true if the object is walking any waypoints.
|
||||
int GetIsPostOrWalking(object oWalker = OBJECT_SELF);
|
||||
// Returns the string to use - depending on day or night.
|
||||
string GetStringPrefix(string sPrefix, object oWalker = OBJECT_SELF);
|
||||
// This sets a spawn in condition.
|
||||
void SetSpawnInCondition(int nCondition, int bValid = TRUE, string sName = "NW_GENERIC_MASTER");
|
||||
//Gets the spawn in condition.Can set things to different ints if you like.
|
||||
int GetSpawnInCondition(int nCondition, string sName = "NW_GENERIC_MASTER");
|
||||
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Master Local Set
|
||||
//:: FileName
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
All On Spawn in conditions in the game are now
|
||||
being stored within one local. The get and set
|
||||
changed or checks the condition of this one
|
||||
Hex local. The NW_FLAG_XXX variables above
|
||||
allow for the user of these functions throughout
|
||||
the generic scripts.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Preston Watamaniuk
|
||||
//:: Created On: Nov 14, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
void SetSpawnInCondition(int nCondition, int bValid, string sName)
|
||||
{
|
||||
int nPlot = GetLocalInt(OBJECT_SELF, sName);
|
||||
if(bValid == TRUE)
|
||||
{
|
||||
nPlot = nPlot | nCondition;
|
||||
SetLocalInt(OBJECT_SELF, sName, nPlot);
|
||||
}
|
||||
else if (bValid == FALSE)
|
||||
{
|
||||
nPlot = nPlot & ~nCondition;
|
||||
SetLocalInt(OBJECT_SELF, sName, nPlot);
|
||||
}
|
||||
}
|
||||
|
||||
int GetSpawnInCondition(int nCondition, string sName)
|
||||
{
|
||||
int nPlot = GetLocalInt(OBJECT_SELF, sName);
|
||||
if(nPlot & nCondition)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//***************************
|
||||
//***************************
|
||||
//
|
||||
//WAY POINT WALK FUNCTIONS
|
||||
//
|
||||
//***************************
|
||||
//***************************
|
||||
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Walk Way Point Path
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Allows specified person walk a waypoint path
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Aidan Scanlan
|
||||
//:: Created On: July 10, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void WalkWayPoints(int nRun = FALSE, float fPause = 1.0) //Run first circuit
|
||||
{
|
||||
if(CheckWayPoints())
|
||||
{
|
||||
ClearAllActions();
|
||||
}
|
||||
|
||||
string NightWayString;
|
||||
string NightPostString;
|
||||
string sWay;
|
||||
string sPost;
|
||||
|
||||
//The block of code below deals with night and day cycle for postings and walkway points.
|
||||
if(GetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING))
|
||||
{
|
||||
NightWayString = "WN_";
|
||||
NightPostString = "NIGHT_";
|
||||
}
|
||||
else
|
||||
{
|
||||
NightWayString = "WP_";
|
||||
NightPostString = "POST_";
|
||||
}
|
||||
|
||||
// We will set what strings to use.
|
||||
SetLocalString(OBJECT_SELF, "NW_GENERIC_WALKWAYS_DAY", "WP_");
|
||||
SetLocalString(OBJECT_SELF, "NW_GENERIC_WALKWAYS_NIGHT", NightWayString);
|
||||
SetLocalString(OBJECT_SELF, "NW_GENERIC_POSTING_DAY", "POST_");
|
||||
SetLocalString(OBJECT_SELF, "NW_GENERIC_POSTING_NIGHT", NightPostString);
|
||||
|
||||
// Which shall we use? Day or night?
|
||||
sWay = GetStringPrefix("NW_GENERIC_WALKWAYS");
|
||||
sPost = GetStringPrefix("NW_GENERIC_POSTING");
|
||||
|
||||
//I have now determined what the prefixs for the current walkways and postings are and will use them instead
|
||||
// of POST_ and WP_
|
||||
|
||||
if(GetSpawnInCondition(NW_FLAG_STEALTH))
|
||||
{
|
||||
// Will hide all the time, when they walk
|
||||
ActionUseSkill(SKILL_HIDE, OBJECT_SELF);
|
||||
}
|
||||
else if(GetSpawnInCondition(NW_FLAG_SEARCH) || GetLocalInt(OBJECT_SELF, "ANIMATIONS") == IMMOBILE_AMBIENT_ANIMATIONS)
|
||||
{
|
||||
// Will search all the time, when they walk, or if we are not going to move.
|
||||
ActionUseSkill(SKILL_SEARCH, OBJECT_SELF);
|
||||
}
|
||||
|
||||
//Test if OBJECT_SELF has waypoints to walk
|
||||
string sWayTag = GetTag(OBJECT_SELF);
|
||||
sWayTag = sWay + sWayTag + "_01";
|
||||
object oWay1 = GetNearestObjectByTag(sWayTag);
|
||||
// Get the object, if nearest (IE in area one) is not valid.
|
||||
if(!GetIsObjectValid(oWay1))
|
||||
{
|
||||
oWay1 = GetObjectByTag(sWayTag);
|
||||
}
|
||||
|
||||
if(GetIsObjectValid(oWay1))
|
||||
{
|
||||
int nNth = 1;
|
||||
int nTens;
|
||||
int nNum;
|
||||
object oNearest = GetNearestObject(OBJECT_TYPE_WAYPOINT, OBJECT_SELF, nNth);
|
||||
while (GetIsObjectValid(oNearest))
|
||||
{
|
||||
string sNearestTag = GetTag(oNearest);
|
||||
//removes the first 3 and last three characters from the waypoint's tag
|
||||
//and checks it against his own tag. Waypoint tag format is WP_MyTag_XX.
|
||||
if(GetSubString(sNearestTag, 3, GetStringLength(sNearestTag) - 6) == GetTag(OBJECT_SELF))
|
||||
{
|
||||
string sTens = GetStringRight(GetTag(oNearest), 2);
|
||||
nTens = StringToInt(sTens)/10;
|
||||
nNum= StringToInt(GetStringRight(GetTag(oNearest), 1));
|
||||
oNearest = OBJECT_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
nNth++;
|
||||
oNearest = GetNearestObject(OBJECT_TYPE_WAYPOINT,OBJECT_SELF,nNth);
|
||||
}
|
||||
}
|
||||
RunCircuit(nTens, nNum, nRun, fPause); //***************************************
|
||||
ActionWait(fPause);
|
||||
ActionDoCommand(RunNextCircuit(nRun, fPause));
|
||||
}
|
||||
else // Else go to the post we have set.
|
||||
{
|
||||
sWayTag = GetTag(OBJECT_SELF);
|
||||
sWayTag = sPost + sWayTag;
|
||||
oWay1 = GetNearestObjectByTag(sWayTag);
|
||||
if(!GetIsObjectValid(oWay1))
|
||||
{
|
||||
oWay1 = GetObjectByTag(sWayTag);
|
||||
}
|
||||
if(GetIsObjectValid(oWay1))
|
||||
{
|
||||
ActionForceMoveToObject(oWay1, nRun, 1.0, 60.0);
|
||||
float fFacing = GetFacing(oWay1);
|
||||
ActionDoCommand(SetFacing(fFacing));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunNextCircuit(int nRun = FALSE, float fPause = 1.0)
|
||||
{
|
||||
RunCircuit(0, 1, nRun, fPause);
|
||||
ActionWait(fPause);
|
||||
ActionDoCommand(RunNextCircuit(nRun, fPause));
|
||||
}
|
||||
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Run Circuit
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Calculates the proper path to follow along a
|
||||
predetermined set of way points
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Aidan Scanlan
|
||||
//:: Created On: July 10, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void RunCircuit(int nTens, int nNum, int nRun = FALSE, float fPause = 1.0)
|
||||
{
|
||||
// starting at a given way point, move sequentialy through incrementally
|
||||
// increasing points until there are no more valid ones.
|
||||
// We will check for day/night in these instead of heartbeats.
|
||||
string sWay = GetStringPrefix("NW_GENERIC_WALKWAYS");
|
||||
string sNewString;
|
||||
object oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) + IntToString(nNum));
|
||||
|
||||
while(GetIsObjectValid(oTargetPoint))
|
||||
{
|
||||
ActionWait(fPause);
|
||||
ActionMoveToObject(oTargetPoint, nRun);
|
||||
nNum++;
|
||||
if (nNum > 9)
|
||||
{
|
||||
nTens++;
|
||||
nNum = 0;
|
||||
}
|
||||
// Maybe change string prefix to use.
|
||||
sNewString = GetStringPrefix("NW_GENERIC_WALKWAYS");
|
||||
if(sNewString != sWay)
|
||||
{
|
||||
WalkWayPoints(nRun, fPause);
|
||||
return;
|
||||
}
|
||||
oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) + IntToString(nNum));
|
||||
}
|
||||
// once there are no more waypoints available, decriment back to the last
|
||||
// valid point.
|
||||
nNum--;
|
||||
if (nNum < 0)
|
||||
{
|
||||
nTens--;
|
||||
nNum = 9;
|
||||
}
|
||||
|
||||
// start the cycle again going back to point 01
|
||||
oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) + IntToString(nNum));
|
||||
while(GetIsObjectValid(oTargetPoint))
|
||||
{
|
||||
ActionWait(fPause);
|
||||
ActionMoveToObject(oTargetPoint, nRun);
|
||||
nNum--;
|
||||
if (nNum < 0)
|
||||
{
|
||||
nTens--;
|
||||
nNum = 9;
|
||||
}
|
||||
// Maybe change string prefix to use.
|
||||
sNewString = GetStringPrefix("NW_GENERIC_WALKWAYS");
|
||||
if(sNewString != sWay)
|
||||
{
|
||||
WalkWayPoints(nRun, fPause);
|
||||
return;
|
||||
}
|
||||
oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) + IntToString(nNum));
|
||||
}
|
||||
}
|
||||
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Check Walkways
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This function checks the passed in object to
|
||||
see if they are supposed to be walking to
|
||||
day or night postings.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Preston Watamaniuk
|
||||
//:: Created On: Feb 26, 2002
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
int CheckWayPoints(object oWalker)
|
||||
{
|
||||
object oWay1;
|
||||
object oWay2;
|
||||
object oWay3;
|
||||
object oWay4;
|
||||
string sTag = GetTag(oWalker);
|
||||
if(GetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING))
|
||||
{
|
||||
oWay2 = GetWaypointByTag("NIGHT_" + sTag);
|
||||
oWay4 = GetWaypointByTag("WN_" + sTag + "_01");
|
||||
}
|
||||
|
||||
oWay1 = GetWaypointByTag("POST_" + sTag);
|
||||
oWay3 = GetWaypointByTag("WP_" + sTag + "_01");
|
||||
|
||||
if(GetIsObjectValid(oWay2) || GetIsObjectValid(oWay4) || GetIsObjectValid(oWay1) || GetIsObjectValid(oWay3))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Returns the string to use - depending on day or night.
|
||||
string GetStringPrefix(string sPrefix, object oWalker)
|
||||
{
|
||||
if(GetIsDay() || GetIsDawn())
|
||||
{
|
||||
return GetLocalString(OBJECT_SELF, sPrefix + "_DAY");
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetLocalString(OBJECT_SELF, sPrefix + "_NIGHT");
|
||||
}
|
||||
}
|
61
_module/nss/mod_ctrl_bk_set.nss
Normal file
61
_module/nss/mod_ctrl_bk_set.nss
Normal file
@@ -0,0 +1,61 @@
|
||||
// DMFI MP Starter Mod
|
||||
// mod_ctrl_bk_set
|
||||
// called from the module control settings conversation
|
||||
// sends a message on the DM channel (to all DMs) with current settings
|
||||
|
||||
void main ()
|
||||
{
|
||||
|
||||
// determine current module settings for rest, death, and respawn systems
|
||||
|
||||
int restchoice = GetLocalInt(GetModule(), "rest_system");
|
||||
int deathchoice = GetLocalInt(GetModule(), "death_system");
|
||||
int rspchoice = GetLocalInt(GetModule(), "respawn_system");
|
||||
|
||||
// initialize message variables
|
||||
|
||||
string msg1;
|
||||
string msg2;
|
||||
string msg3;
|
||||
|
||||
// determine current rest system
|
||||
|
||||
if (restchoice == 1)
|
||||
msg1 = "Time-based rest (time interval between rests)";
|
||||
if (restchoice == 2)
|
||||
msg1 = "Supply-based rest (requires tagged item)";
|
||||
if (restchoice == 3)
|
||||
msg1 = "DMFI resting system";
|
||||
if (restchoice == 4)
|
||||
msg1 = "Unlimited rest (normal NWN:EE system)";
|
||||
if (restchoice == 5)
|
||||
msg1 = "Resting disabled";
|
||||
|
||||
// determine current death system
|
||||
|
||||
if (deathchoice == 1)
|
||||
msg2 = "Parthenon Easy Death System (PCs revivable if party member still alive)";
|
||||
if (deathchoice == 2)
|
||||
msg2 = "HABD death / bleeding system";
|
||||
if (deathchoice == 3)
|
||||
msg2 = "Unlimited respawn (no penalty)";
|
||||
if (deathchoice == 4)
|
||||
msg2 = "Unlimited respawn (with penalty)";
|
||||
|
||||
// determine current respawn system
|
||||
|
||||
if (rspchoice == 1)
|
||||
msg3 = "Respawn location set to current PC location";
|
||||
if (rspchoice == 2)
|
||||
msg3 = "Respawn location set to module starting location";
|
||||
if (rspchoice == 3)
|
||||
msg3 = "Respawn location set to custom waypoint";
|
||||
|
||||
// send DM channel messages with settings
|
||||
SendMessageToAllDMs("CURRENT MOD CONTROL SETTINGS");
|
||||
SendMessageToAllDMs(msg1);
|
||||
SendMessageToAllDMs(msg2);
|
||||
SendMessageToAllDMs(msg3);
|
||||
|
||||
}
|
||||
|
151
_module/nss/ms_name_inc.nss
Normal file
151
_module/nss/ms_name_inc.nss
Normal file
@@ -0,0 +1,151 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Markshire's Nomenclature //
|
||||
// //
|
||||
// By Thrym of Markshire 5/21/06 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// FUNCTION: //
|
||||
// The Nomenclature is an include file placed in the spawn script //
|
||||
// nw_c2_default9 designed to assign a name to a generic NPC who may //
|
||||
// wander towns, roads, shops, etc. //
|
||||
// //
|
||||
// Utilizing both SetName and RandomName the system will name the NPC in //
|
||||
// one of two ways ... //
|
||||
// //
|
||||
// "SET_NAME": By setting the variable "SET_NAME" on the NPC and //
|
||||
// assigning it a string the creature will rename itself upon spawning. //
|
||||
// This is handy for DM's and builders to create more precisely named //
|
||||
// creatures for the palette and then generize them upon spawn. //
|
||||
// //
|
||||
// eg. Ancient White Dragon in the Creator becomes White Dragon on Spawn. //
|
||||
// //
|
||||
// "SET_NAME" = "RANDOM": By setting the same variable to the name "RANDOM" //
|
||||
// the NPC then is given a random name generated by RACE and GENDER using //
|
||||
// the RandomName function. //
|
||||
// //
|
||||
// eg. Male Dwarven Villager in the creator becomes Gloigan on spawn //
|
||||
// this time and perhaps Rufus on the next spawned Villager. //
|
||||
// //
|
||||
// "NAME_TYPE": Setting this int variable to "1" will cause a Full Name //
|
||||
// to be generated if the "SET_NAME" is set to "RANDOM". //
|
||||
// //
|
||||
// eg. Male Dwarven Villager becomes Gloigan Stonecutter or Rufus Mason. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//void main (){}
|
||||
|
||||
///// FUNCTION DECLARATIONS ////////////////////////////////////////////////////
|
||||
|
||||
// Generates a Random First Name
|
||||
// based on Race and Gender
|
||||
// For all Standard PC Races and Animals
|
||||
string ms_RandomFirstName(object oNPC = OBJECT_SELF);
|
||||
|
||||
// Generates a Random Last Name
|
||||
// based on Race For all
|
||||
// Standard PC Races and Animals
|
||||
string ms_RandomLastName(object oNPC = OBJECT_SELF);
|
||||
|
||||
// Function designed to read the variable
|
||||
// "SET_NAME" and assign a new name to the NPC
|
||||
// If the variable is set to "RANDOM" a
|
||||
// random name is assigned.
|
||||
// A second variable can be assigned to
|
||||
// have the random name be a random Full Name.
|
||||
void ms_Nomenclature(object oNPC = OBJECT_SELF);
|
||||
|
||||
|
||||
///// FUNCTIONS ////////////////////////////////////////////////////////////////
|
||||
|
||||
void ms_Nomenclature(object oNPC = OBJECT_SELF)
|
||||
{
|
||||
string sRandomName = GetLocalString(oNPC, "SET_NAME");
|
||||
string sTitle = GetLocalString(oNPC, "TITLE");
|
||||
string sPostfix = GetLocalString(oNPC, "POSTFIX");
|
||||
|
||||
if (sRandomName != "")
|
||||
{
|
||||
if (sRandomName == "RANDOM")
|
||||
{
|
||||
switch (GetLocalInt(oNPC, "NAME_TYPE"))
|
||||
{
|
||||
case 1: sRandomName = sTitle + " " + ms_RandomFirstName(oNPC) + " " + ms_RandomLastName(oNPC); break;
|
||||
default: sRandomName = sTitle + " " + ms_RandomFirstName(oNPC) + " " + sPostfix; break;
|
||||
}
|
||||
}
|
||||
|
||||
SetName(oNPC, (sRandomName));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
string ms_RandomFirstName(object oNPC = OBJECT_SELF)
|
||||
{
|
||||
int Gender = GetGender(oNPC);
|
||||
int Race = GetRacialType(oNPC);
|
||||
|
||||
string Name;
|
||||
|
||||
switch (Race)
|
||||
{
|
||||
case RACIAL_TYPE_ANIMAL: Name = RandomName(0); break;
|
||||
case RACIAL_TYPE_DWARF:
|
||||
switch (Gender)
|
||||
{ default: Name = RandomName(2); break;
|
||||
case GENDER_FEMALE: Name = RandomName(3); break; } break;
|
||||
case RACIAL_TYPE_ELF:
|
||||
switch (Gender)
|
||||
{ default: Name = RandomName(5); break;
|
||||
case GENDER_FEMALE: Name = RandomName(6); break; } break;
|
||||
case RACIAL_TYPE_GNOME:
|
||||
switch (Gender)
|
||||
{ default: Name = RandomName(8); break;
|
||||
case GENDER_FEMALE: Name = RandomName(9); break; } break;
|
||||
case RACIAL_TYPE_HALFELF:
|
||||
switch (Gender)
|
||||
{ default: Name = RandomName(11); break;
|
||||
case GENDER_FEMALE: Name = RandomName(12); break; } break;
|
||||
case RACIAL_TYPE_HALFLING:
|
||||
switch (Gender)
|
||||
{ default: Name = RandomName(14); break;
|
||||
case GENDER_FEMALE: Name = RandomName(15); break; } break;
|
||||
case RACIAL_TYPE_HALFORC:
|
||||
switch (Gender)
|
||||
{ default: Name = RandomName(17); break;
|
||||
case GENDER_FEMALE: Name = RandomName(18); break; } break;
|
||||
case RACIAL_TYPE_HUMAN:
|
||||
switch (Gender)
|
||||
{ default: Name = RandomName(20); break;
|
||||
case GENDER_FEMALE: Name = RandomName(21); break; } break;
|
||||
default:
|
||||
switch (Gender)
|
||||
{ default: Name = RandomName(-1); break;
|
||||
case GENDER_FEMALE: Name = RandomName(0); break; } break;
|
||||
}
|
||||
|
||||
return Name;
|
||||
}
|
||||
|
||||
string ms_RandomLastName(object oNPC = OBJECT_SELF)
|
||||
{
|
||||
int Race = GetRacialType(oNPC);
|
||||
|
||||
string Name;
|
||||
|
||||
switch (Race)
|
||||
{
|
||||
case RACIAL_TYPE_DWARF: Name = RandomName(4); break;
|
||||
case RACIAL_TYPE_ELF: Name = RandomName(7); break;
|
||||
case RACIAL_TYPE_GNOME: Name = RandomName(10); break;
|
||||
case RACIAL_TYPE_HALFELF: Name = RandomName(13); break;
|
||||
case RACIAL_TYPE_HALFLING: Name = RandomName(16); break;
|
||||
case RACIAL_TYPE_HALFORC: Name = RandomName(19); break;
|
||||
case RACIAL_TYPE_HUMAN: Name = RandomName(22); break;
|
||||
default: Name = RandomName(1); break;
|
||||
}
|
||||
|
||||
return Name;
|
||||
}
|
747
_module/nss/nbde_inc.nss
Normal file
747
_module/nss/nbde_inc.nss
Normal file
@@ -0,0 +1,747 @@
|
||||
//void main(){}
|
||||
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Natural Bioware Database Extension v1.0
|
||||
//:: nbde_inc
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Knat
|
||||
//:: Created On: 8/2004
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
|
||||
Natural Bioware Database Extension v1.0
|
||||
"Andale, Andale! EEEE-ha....!"
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
--- What is NBDE ?
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
NBDE is basically a wrapper for the standard bioware database system,
|
||||
eliminating most of its restrictions. But even more important, it significantly
|
||||
boosts both reading and writing speed.
|
||||
|
||||
It will make your db scripts more secure and always keeps your database files
|
||||
in the best possible shape. It furthermore reduces the amount of overhead in
|
||||
your database and keeps it as slim as possible.
|
||||
|
||||
there is no need to periodically use a pack utility, which further
|
||||
reduces administrative tasks...
|
||||
|
||||
and this all gets achieved with the use of this simple script. I recommend any
|
||||
scripter to check this out if he plans to use biowares onboard database
|
||||
functionality. It should also be very easy to convert already existing scripts.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
--- Installation
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Simply import nbde.erf and you are done.
|
||||
|
||||
It includes the following stuff:
|
||||
|
||||
Scripts:
|
||||
|
||||
name: nbde_inc
|
||||
main include script...
|
||||
|
||||
Areas:
|
||||
|
||||
name: _NBDE
|
||||
special area. this is a 2x2 microset area holding the database vault container.
|
||||
you can delete this area and move the container to another place if you want.
|
||||
|
||||
Items:
|
||||
|
||||
Custom > Special > Custom 4
|
||||
name: Database
|
||||
special database item with the resref "nbde_database"
|
||||
don't touch this item...
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
--- Eliminated Restrictions ?
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Biowares database system mimics the interface of Local Variables.
|
||||
Instead of SetLocalInt() you use SetCampaignInt(), GetLocalInt() turns into
|
||||
GetCampaignInt(). This makes it very easy to use, even for novice scripters.
|
||||
But the normal bioware database does not consequently implement this approach.
|
||||
Several stumbling blocks, slight differences to normal Set-/GetLocal functions,
|
||||
may lead to severe functional problems and hard to track bugs if you try to
|
||||
achieve a bit more complex goals...
|
||||
|
||||
>>> 32-Char sVarName Limitation:
|
||||
--------------------------------
|
||||
|
||||
the sVarName parameter in the original functions only accepts strings with a
|
||||
maximum length of 32 chars. it will simply cut the string if it exceeds this
|
||||
limit...
|
||||
|
||||
example:
|
||||
|
||||
SetCampaignInt("MYDB", "PREFIX" + GetTag(oArea), 100);
|
||||
|
||||
The second parameter is the sVarName one, with the 32 char limit. The above
|
||||
statement is a bit risky, because GetTag(oArea) could return a string with a
|
||||
maximum length of 32. "PREFIX" has a length of 6 chars, so any area with a
|
||||
tag of length >26 could lead to unintended sVarNames.
|
||||
|
||||
Same for this example:
|
||||
|
||||
SetCampaignInt("MYDB", GetName(oPC) + GetPCPlayerName(oPC), 100);
|
||||
|
||||
same problem. GetName() alone may return a string with a length >32, which
|
||||
could again lead to a problematic sVarName.
|
||||
|
||||
NBDE completely eliminates the 32-char sVarName limitation and enables the
|
||||
scripter to use the full scope of dynamically concatenated sVarNames,
|
||||
without the need of hashing systems or other workarounds, which generally
|
||||
consume a bit of extra cpu time...
|
||||
|
||||
>>> UNIQUE sVarName Limitation:
|
||||
-------------------------------
|
||||
|
||||
the sVarName parameter in the original functions MUST be unique across the
|
||||
entire database, regardless of the variable type.
|
||||
|
||||
example:
|
||||
|
||||
SetCampaignInt("MYDB", "TEST", 10);
|
||||
SetCampaignString("MYDB", "TEST", "ABCD");
|
||||
|
||||
the second line will OVERWRITE the former integer variable "TEST" with a string.
|
||||
This means a GetCampaignInt("MYDB", "TEST") returns 0
|
||||
|
||||
using NBDE eliminates this limitation.
|
||||
It works now similar to LocalVariables (the intended goal)
|
||||
|
||||
NBDE conversion of the above example:
|
||||
|
||||
NBDE_SetCampaignInt("MYDB", "TEST", 10);
|
||||
NBDE_SetCampaignString("MYDB", "TEST", "ABCD");
|
||||
|
||||
second line will not overwrite the integer variable
|
||||
|
||||
NBDE_GetCampaignInt("MYDB", "TEST") returns the correct 10
|
||||
NBDE_GetCampaignString("MYDB", "TEST") returns "ABCD"
|
||||
|
||||
The original function set contains only one delete command, called
|
||||
DeleteCampaignVariable(), because of the unique nature of sVarNames.
|
||||
|
||||
NBDE contains one delete command for each variable type, to account for the
|
||||
possible non uniqueness:
|
||||
|
||||
NBDE_DeleteCampaignInt()
|
||||
NBDE_DeleteCampaignFloat()
|
||||
NBDE_DeleteCampaignString()
|
||||
NBDE_DeleteCampaignVector()
|
||||
NBDE_DeleteCampaignLocation()
|
||||
|
||||
this again now works similar to the LocalVariables interface, which also
|
||||
gives you a delete command for each variable type:
|
||||
|
||||
aka DeleteLoaclInt(), DeleteLocalFloat(), DeleteLocalString(),
|
||||
DeleteLocalVector(), DeleteLocalLocation()
|
||||
|
||||
>>> Broken Locations:
|
||||
---------------------
|
||||
|
||||
the original SetCampaignLocation/GetCampaignLocation functions are not very
|
||||
reliable, because they are using the areas object-id for reference, which
|
||||
is a runtime generated ID. stored locations in the database can get invalid
|
||||
if you change the area layout in the toolset (e.g. deleting old areas, etc.)
|
||||
|
||||
nbde location functions are 100% reliable, as long as you use unique TAGs for
|
||||
your areas. I repeat, you need to use UNIQUE TAGS for your areas...
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
--- No need to pack the database
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
NWN's database files grow very large, very fast, because deleted entries get
|
||||
only "flagged" as deleted. but they still reside in the dabase file physically.
|
||||
|
||||
to stop this evergrowing database, you usually call an external "pack"
|
||||
utility which reorganizes the database files (deletion of flagged entries,
|
||||
index re-ordering, etc.)
|
||||
|
||||
unfortunately, the only working pack utility is the one you find in the
|
||||
/utils directory, called DataPack.exe . But some people reported problems
|
||||
on large database files... (i never had problems with this tool, though)
|
||||
|
||||
the good news is, you don't need to touch this utility ever, while using
|
||||
this extension. NBDE will automatically keep all your database files as
|
||||
compact/small as possible.
|
||||
|
||||
no external maintenance needed...
|
||||
|
||||
NBDE_Delete commands immediately shrink your database in size (physically
|
||||
deleted records) after a flushing command (read more about that in a minute).
|
||||
|
||||
attention:
|
||||
there is a known problem in the linux version:
|
||||
|
||||
The DestroyCampaignDatabase command doesnt always work in linux. i think
|
||||
this relates to the different file systems used.
|
||||
|
||||
you should be ok using the following rules for your database
|
||||
names (sCampaignName parameter):
|
||||
|
||||
- max length 16 chars
|
||||
- only use alphanumeric chars and underscore
|
||||
- NO space
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
--- Usage
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
first, include nbde_inc to all scripts using this extension:
|
||||
|
||||
#include "nbde_inc"
|
||||
|
||||
You basically use it the same way you would use the original
|
||||
database. just add the NBDE_ prefix infront of the function.
|
||||
|
||||
original example:
|
||||
|
||||
int n = GetCampaignInt("MYDB", "MYVAR");
|
||||
|
||||
nbde conversion:
|
||||
|
||||
#include "nbde_inc"
|
||||
|
||||
int n = NBDE_GetCampaignInt("MYDB", "MYVAR");
|
||||
|
||||
Important differences:
|
||||
|
||||
Database Flushing:
|
||||
------------------
|
||||
|
||||
writing to the database will not issue a physical write directly.
|
||||
You need to "Flush" a database in order to physically write the contents of
|
||||
a complete database to your HD. this sounds slow, but its not, because of
|
||||
the large overhead of standard SetCampaign calls...
|
||||
Writing out a single integer via SetCampaignInt takes roughly
|
||||
100ms (0.1 seconds), writing out an object with 1000 integers via
|
||||
SetCampaignObject takes roughly 150ms. that's the whole
|
||||
magic behind the system. it basically just consolidates your writes..
|
||||
|
||||
original example:
|
||||
|
||||
SetCampaignInt("MYDB", "MYVAR1", 10);
|
||||
SetCampaignInt("MYDB", "MYVAR2", 20);
|
||||
SetCampaignInt("MYDB", "MYVAR3", 30);
|
||||
SetCampaignInt("MYDB", "MYVAR4", 40);
|
||||
SetCampaignInt("MYDB", "MYVAR5", 50);
|
||||
|
||||
nbde conversion:
|
||||
|
||||
NBDE_SetCampaignInt("MYDB", "MYVAR1", 10);
|
||||
NBDE_SetCampaignInt("MYDB", "MYVAR2", 20);
|
||||
NBDE_SetCampaignInt("MYDB", "MYVAR3", 30);
|
||||
NBDE_SetCampaignInt("MYDB", "MYVAR4", 40);
|
||||
NBDE_SetCampaignInt("MYDB", "MYVAR5", 50);
|
||||
NBDE_FlushCampaignDatabase("MYDB");
|
||||
|
||||
the original example takes roughly half a second (500ms),
|
||||
the converted example only 100ms.
|
||||
|
||||
you can gain a lot of speed and do things impossible with the original
|
||||
database using the right flushing scheme. you can flush critical data asap
|
||||
but you can get away flushing not so critical stuff only once every few
|
||||
minutes, or during onClientLeave, or once an Area is out of players, and so on...
|
||||
|
||||
keep in mind: you can loose data if the server crashes before
|
||||
you flushed your database.
|
||||
|
||||
delete function:
|
||||
----------------
|
||||
|
||||
the original version only got one delete function, DeleteCampaignVariable.
|
||||
That's because of the unique nature of sVarNames...
|
||||
NBDE eliminates this restriction and therefore exposes one delete
|
||||
function for each data-type.
|
||||
|
||||
original example:
|
||||
|
||||
DeleteCampaignVariable("MYDB", "MYVAR");
|
||||
|
||||
you need to know the datatype of "MYVAR" in order to correctly convert this
|
||||
line to NBDE. lets assume it's an integer...
|
||||
|
||||
nbde conversion:
|
||||
|
||||
NBDE_DeleteCampaignInt("MYDB", "MYVAR");
|
||||
|
||||
|
||||
Unloading a Database:
|
||||
---------------------
|
||||
|
||||
nbde databases are kept in memory. NBDE_UnloadCampaignDatabase() unloads
|
||||
the database with the name sCampaignName from memory.
|
||||
|
||||
useful to unload databases you don't need often. unloading/reloading is quite
|
||||
fast, so don't hesitate to use this regulary...
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// database item name, used as sVarName parameter in Store-/RetrieveCampaignObject
|
||||
const string NBDE_DATABASE_ITEM_VARNAME = "+++_DATABASE_ITEM_+++";
|
||||
|
||||
// database item resref, needed for auto-creation
|
||||
const string NBDE_DATABASE_ITEM_RESREF = "nbde_database";
|
||||
|
||||
// database index prefix
|
||||
// used to index a database via Get/SetLocalObject
|
||||
const string NBDE_INDEX_PREFIX = "NBDE_DATABASE_";
|
||||
|
||||
// database vault tag
|
||||
// this vault is usually a container
|
||||
const string NBDE_VAULT_TAG = "NBDE_VAULT";
|
||||
|
||||
// prefixes used to store locations/vectors as strings
|
||||
// this should eliminate collisions with normal strings
|
||||
const string NBDE_LOC_PREFIX = "<22>ƥ";
|
||||
const string NBDE_VEC_PREFIX = "<22><><EFBFBD>";
|
||||
|
||||
// This stores an int out to the specified campaign database
|
||||
// The database name IS case sensitive and it must be the same for both set and get functions.
|
||||
// If you want a variable to pertain to a specific player in the game, provide a player object.
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// Vastly improved writing speed...
|
||||
// There is no limit on the length of sVarname (original function is limited to 32 chars)
|
||||
// sVarname must NOT be unique. you can use the same sVarname with a different data-type
|
||||
void NBDE_SetCampaignInt(string sCampaignName, string sVarname, int nInt, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// This stores a float out to the specified campaign database
|
||||
// The database name IS case sensitive and it must be the same for both set and get functions.
|
||||
// If you want a variable to pertain to a specific player in the game, provide a player object.
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// Vastly improved writing speed...
|
||||
// There is no limit on the length of sVarname (original function is limited to 32 chars)
|
||||
// sVarname must NOT be unique. you can use the same sVarname with a different data-type
|
||||
void NBDE_SetCampaignFloat(string sCampaignName, string sVarname, float flFloat, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// This stores a string out to the specified campaign database
|
||||
// The database name IS case sensitive and it must be the same for both set and get functions.
|
||||
// If you want a variable to pertain to a specific player in the game, provide a player object.
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// Vastly improved writing speed...
|
||||
// There is no limit on the length of sVarname (original function is limited to 32 chars)
|
||||
// sVarname must NOT be unique. you can use the same sVarname with a different data-type
|
||||
void NBDE_SetCampaignString(string sCampaignName, string sVarname, string sString, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// This stores a location out to the specified campaign database
|
||||
// The database name IS case sensitive and it must be the same for both set and get functions.
|
||||
// If you want a variable to pertain to a specific player in the game, provide a player object.
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// Vastly improved writing speed...
|
||||
// There is no limit on the length of sVarname (original function is limited to 32 chars)
|
||||
// sVarname must NOT be unique. you can use the same sVarname with a different data-type
|
||||
//
|
||||
// Original function is not very reliable, because it is using the areas object-id, which is
|
||||
// a runtime generated ID. Stored locations may turn invalid in case you change the area layout in the toolset.
|
||||
// (e.g. deleting old areas)
|
||||
//
|
||||
// This function is 100% reliable, as long as you use unique TAGs for your areas
|
||||
void NBDE_SetCampaignLocation(string sCampaignName, string sVarname, location locLocation, object oPlayer = OBJECT_SELF);
|
||||
|
||||
// This stores a vector out to the specified campaign database
|
||||
// The database name IS case sensitive and it must be the same for both set and get functions.
|
||||
// If you want a variable to pertain to a specific player in the game, provide a player object.
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// Vastly improved writing speed...
|
||||
// There is no limit on the length of sVarname (original function is limited to 32 chars)
|
||||
// sVarname must NOT be unique. you can use the same sVarname with a different data-type
|
||||
void NBDE_SetCampaignVector(string sCampaignName, string sVarname, vector vVector, object oPlayer = OBJECT_SELF);
|
||||
|
||||
// This will read an int from the specified campaign database
|
||||
// The database name IS case sensitive and it must be the same for both set and get functions.
|
||||
// If you want a variable to pertain to a specific player in the game, provide a player object.
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// Improved reading speed...
|
||||
// There is no limit on the length of sVarname (original function is limited to 32 chars)
|
||||
// sVarname must NOT be unique. you can use the same sVarname with a different data-type
|
||||
int NBDE_GetCampaignInt(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// This will read a float from the specified campaign database
|
||||
// The database name IS case sensitive and it must be the same for both set and get functions.
|
||||
// If you want a variable to pertain to a specific player in the game, provide a player object.
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// Improved reading speed...
|
||||
// There is no limit on the length of sVarname (original function is limited to 32 chars)
|
||||
// sVarname must NOT be unique. you can use the same sVarname with a different data-type
|
||||
float NBDE_GetCampaignFloat(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// This will read a string from the specified campaign database
|
||||
// The database name IS case sensitive and it must be the same for both set and get functions.
|
||||
// If you want a variable to pertain to a specific player in the game, provide a player object.
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// Improved reading speed...
|
||||
// There is no limit on the length of sVarname (original function is limited to 32 chars)
|
||||
// sVarname must NOT be unique. you can use the same sVarname with a different data-type
|
||||
string NBDE_GetCampaignString(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// This will read a location from the specified campaign database
|
||||
// The database name IS case sensitive and it must be the same for both set and get functions.
|
||||
// If you want a variable to pertain to a specific player in the game, provide a player object.
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// Improved reading speed...
|
||||
// There is no limit on the length of sVarname (original function is limited to 32 chars)
|
||||
// sVarname must NOT be unique. you can use the same sVarname with a different data-type
|
||||
//
|
||||
// Original function is not very reliable, because it is using the areas object-id, which is
|
||||
// a runtime generated ID. Stored locations may turn invalid in case you change the area layout in the toolset.
|
||||
// (e.g. deleting old areas)
|
||||
//
|
||||
// This function is 100% reliable, as long as you use unique TAGs for your areas
|
||||
location NBDE_GetCampaignLocation(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// This will read a vector from the specified campaign database
|
||||
// The database name IS case sensitive and it must be the same for both set and get functions.
|
||||
// If you want a variable to pertain to a specific player in the game, provide a player object.
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// Improved reading speed...
|
||||
// There is no limit on the length of sVarname (original function is limited to 32 chars)
|
||||
// sVarname must NOT be unique. you can use the same sVarname with a different data-type
|
||||
vector NBDE_GetCampaignVector(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// this will remove an integer from the specified campaign database
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// This will physically delete the variable from the database, not only flagging it
|
||||
// Database will shrink in size
|
||||
// No need to pack your database ever
|
||||
void NBDE_DeleteCampaignInt(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// this will remove a float from the specified campaign database
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// This will physically delete the variable from the database, not only flagging it
|
||||
// Database will shrink in size
|
||||
// No need to pack your database ever
|
||||
void NBDE_DeleteCampaignFloat(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// This will remove a string from the specified campaign database
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// This will physically delete the variable from the database, not only flagging it
|
||||
// Database will shrink in size
|
||||
// No need to pack your database ever
|
||||
void NBDE_DeleteCampaignString(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// This will remove a location from the specified campaign database
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// This will physically delete the variable from the database, not only flagging it
|
||||
// Database will shrink in size
|
||||
// No need to pack your database ever
|
||||
void NBDE_DeleteCampaignLocation(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// This will remove a vector from the specified campaign database
|
||||
//
|
||||
// Improvements to original bioware function:
|
||||
// This will physically delete the variable from the database, not only flagging it
|
||||
// Database will shrink in size
|
||||
// No need to pack your database ever
|
||||
void NBDE_DeleteCampaignVector(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID);
|
||||
|
||||
// This will flush a database to disk with a SINGLE StoreCampaignObject() call
|
||||
//
|
||||
// Don't use this function in a rapid manner.
|
||||
// Delay each call to this function by at least 1 second (using delaycommand)
|
||||
// in order to eliminate possible spikes...
|
||||
void NBDE_FlushCampaignDatabase(string sCampaignName);
|
||||
|
||||
// NBDE databases are kept in memory. this commands unloads
|
||||
// the database with the name sCampaignName from memory.
|
||||
//
|
||||
// Useful to unload databases you don't need often.
|
||||
// Unloading/reloading is quite fast, so don't hesitate to use
|
||||
// this regulary...
|
||||
//
|
||||
// Reloading happens automatically, btw...
|
||||
void NBDE_UnloadCampaignDatabase(string sCampaignName);
|
||||
|
||||
|
||||
// --------------------------- IMPLEMENTATION ----------------------------
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
// everything not in here gets considered an illegal character
|
||||
// - mixed up for additional security
|
||||
const string HASH_INDEX = "#i!j$k%l{&M/n(o)p=q?r^<5E>Xs`Tu'v]AwBxCyDzE1F2-G3t;4I}5Y:J6_K7+Z[Lm9N\ l0kOjPhQ,gRfSeHdU8cVbWa.";
|
||||
|
||||
const int HASH_PRIME = 3021377;
|
||||
|
||||
// simple hash
|
||||
// returns -1 if string contains illegal character
|
||||
int NBDE_Hash(string sData)
|
||||
{
|
||||
int nLen = GetStringLength(sData);
|
||||
int i, nHash, nChar;
|
||||
for(i=0;i<nLen;i++)
|
||||
{
|
||||
nChar = FindSubString(HASH_INDEX, GetSubString(sData,i,1));
|
||||
if(nChar == -1) return -1;
|
||||
nHash = ((nHash<<5) ^ (nHash>>27)) ^ nChar;
|
||||
}
|
||||
return nHash % HASH_PRIME;
|
||||
}
|
||||
|
||||
// serialize location to padded string
|
||||
string NBDE_LocationToString(location lLoc)
|
||||
{
|
||||
// serialization garbage... more or less "redo if it screws" code
|
||||
string sLoc = IntToString(FloatToInt(GetPositionFromLocation(lLoc).x*100));
|
||||
sLoc = (GetStringLength(sLoc) < 5) ? sLoc + GetStringLeft(" ",5 - GetStringLength(sLoc)) : GetStringLeft(sLoc,5);
|
||||
sLoc += IntToString(FloatToInt(GetPositionFromLocation(lLoc).y*100));
|
||||
sLoc = (GetStringLength(sLoc) < 10) ? sLoc + GetStringLeft(" ",10 - GetStringLength(sLoc)) : GetStringLeft(sLoc,10);
|
||||
sLoc += IntToString(FloatToInt(GetPositionFromLocation(lLoc).z*100));
|
||||
sLoc = (GetStringLength(sLoc) < 15) ? sLoc + GetStringLeft(" ",15 - GetStringLength(sLoc)) : GetStringLeft(sLoc,15);
|
||||
sLoc += IntToString(FloatToInt(GetFacingFromLocation(lLoc)*100));
|
||||
sLoc = (GetStringLength(sLoc) < 20) ? sLoc + GetStringLeft(" ",20 - GetStringLength(sLoc)) : GetStringLeft(sLoc,20);
|
||||
sLoc += GetTag(GetAreaFromLocation(lLoc));
|
||||
sLoc = (GetStringLength(sLoc) < 52) ? sLoc + GetStringLeft(" ",52 - GetStringLength(sLoc)) : GetStringLeft(sLoc,52);
|
||||
return sLoc;
|
||||
}
|
||||
|
||||
// de-serialize string to location
|
||||
location NBDE_StringToLocation(string sLoc)
|
||||
{
|
||||
// fast de-serialize code using padded strings
|
||||
vector vVec;
|
||||
// build vector
|
||||
vVec.x = StringToFloat(GetStringLeft(sLoc,5)) / 100;
|
||||
vVec.y = StringToFloat(GetSubString(sLoc,5,5)) / 100;
|
||||
vVec.z = StringToFloat(GetSubString(sLoc,10,5)) / 100;;
|
||||
int nPad = FindSubString(GetSubString(sLoc, 20,32)," ");
|
||||
// build & return location
|
||||
return Location(GetObjectByTag((nPad != -1) ? GetSubString(sLoc, 20,nPad) : GetSubString(sLoc, 20,32)), vVec, StringToFloat(GetSubString(sLoc,15,5)) / 100);
|
||||
}
|
||||
|
||||
// serialize vector to padded string
|
||||
string NBDE_VectorToString(vector vVec)
|
||||
{
|
||||
// serialization garbage... more or less "redo if it screws" code
|
||||
string sVec = IntToString(FloatToInt(vVec.x*100));
|
||||
sVec = (GetStringLength(sVec) < 5) ? sVec + GetStringLeft(" ",5 - GetStringLength(sVec)) : GetStringLeft(sVec,5);
|
||||
sVec += IntToString(FloatToInt(vVec.y*100));
|
||||
sVec = (GetStringLength(sVec) < 10) ? sVec + GetStringLeft(" ",10 - GetStringLength(sVec)) : GetStringLeft(sVec,10);
|
||||
sVec += IntToString(FloatToInt(vVec.z*100));
|
||||
sVec = (GetStringLength(sVec) < 15) ? sVec + GetStringLeft(" ",15 - GetStringLength(sVec)) : GetStringLeft(sVec,15);
|
||||
return sVec;
|
||||
}
|
||||
|
||||
vector NBDE_StringToVector(string sVec)
|
||||
{
|
||||
// fast de-serialize code using padded strings
|
||||
vector vVec;
|
||||
vVec.x = StringToFloat(GetStringLeft(sVec,5)) / 100;
|
||||
vVec.y = StringToFloat(GetSubString(sVec,5,5)) / 100;
|
||||
vVec.z = StringToFloat(GetSubString(sVec,10,5)) / 100;
|
||||
return vVec;
|
||||
}
|
||||
|
||||
// returns player key with hopefully safe delimiter
|
||||
string NBDE_GetPlayerKey(object oPC)
|
||||
{
|
||||
return GetName(oPC)+"<22>"+GetPCPlayerName(oPC);
|
||||
}
|
||||
|
||||
// returns database object for the specified campaign database
|
||||
//
|
||||
// - auto-creates database object in case it doesn't exist
|
||||
// - builds index for fast access
|
||||
//
|
||||
// you usually don't need to use this function directly...
|
||||
object NBDE_GetCampaignDatabaseObject(string sCampaignName)
|
||||
{
|
||||
// get database item
|
||||
object oDatabase = GetLocalObject(GetObjectByTag(NBDE_VAULT_TAG), NBDE_INDEX_PREFIX + sCampaignName);
|
||||
// retrieve/create database if not indexed already
|
||||
if(!GetIsObjectValid(oDatabase))
|
||||
{
|
||||
// get database vault object
|
||||
// this container holds all database objects/items
|
||||
object oVault = GetObjectByTag(NBDE_VAULT_TAG);
|
||||
// check for valid vault
|
||||
if(!GetIsObjectValid(oVault))
|
||||
{
|
||||
WriteTimestampedLogEntry("NBDE> Error: unable to locate '"+NBDE_VAULT_TAG+"' vault container object");
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
// one time load
|
||||
oDatabase = RetrieveCampaignObject(sCampaignName, NBDE_DATABASE_ITEM_VARNAME, GetLocation(oVault), oVault);
|
||||
// not found ? create it
|
||||
if(!GetIsObjectValid(oDatabase)) oDatabase = CreateItemOnObject(NBDE_DATABASE_ITEM_RESREF, oVault);
|
||||
// check for valid database object
|
||||
if(!GetIsObjectValid(oDatabase))
|
||||
{
|
||||
WriteTimestampedLogEntry("NBDE> Error: unable to create '"+sCampaignName+"' database object");
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
// index item for fast access
|
||||
SetLocalObject(oVault, NBDE_INDEX_PREFIX + sCampaignName, oDatabase);
|
||||
}
|
||||
return oDatabase;
|
||||
}
|
||||
|
||||
// this will flush (aka write to disk) the specified campaign database in one big swoop
|
||||
//
|
||||
// don't use this function in a rapid manner.
|
||||
// delay each subsequent call to this function by at least 1 second (using delaycommand)
|
||||
// this way you completely eliminate cpu-spikes, no matter how many database
|
||||
// you flush.
|
||||
void NBDE_FlushCampaignDatabase(string sCampaignName)
|
||||
{
|
||||
// get database vault, it holds all database items
|
||||
object oVault = GetObjectByTag(NBDE_VAULT_TAG);
|
||||
if(GetIsObjectValid(oVault))
|
||||
{
|
||||
// get database item
|
||||
object oDatabase = GetLocalObject(oVault, NBDE_INDEX_PREFIX + sCampaignName);
|
||||
// store the whole database via one single StoreCampaignObject call
|
||||
// all variables on the item get stored with the item
|
||||
if(GetIsObjectValid(oDatabase))
|
||||
{
|
||||
// delete database on each flush to keep it compact and clean
|
||||
DestroyCampaignDatabase(sCampaignName);
|
||||
// store database
|
||||
StoreCampaignObject(sCampaignName, NBDE_DATABASE_ITEM_VARNAME , oDatabase);
|
||||
}
|
||||
// database not loaded, no need to flush...
|
||||
}
|
||||
else // vault container missing
|
||||
WriteTimestampedLogEntry("NBDE> Error: unable to locate '"+NBDE_VAULT_TAG+"' vault container object");
|
||||
}
|
||||
|
||||
void NBDE_UnloadCampaignDatabase(string sCampaignName)
|
||||
{
|
||||
// get database vault, it holds all database items
|
||||
object oVault = GetObjectByTag(NBDE_VAULT_TAG);
|
||||
if(GetIsObjectValid(oVault))
|
||||
{
|
||||
// get database item
|
||||
object oDatabase = GetLocalObject(oVault, NBDE_INDEX_PREFIX + sCampaignName);
|
||||
if(GetIsObjectValid(oDatabase))
|
||||
{
|
||||
// delete index
|
||||
DeleteLocalObject(oVault, NBDE_INDEX_PREFIX + sCampaignName);
|
||||
// delete database object
|
||||
DestroyObject(oDatabase);
|
||||
}
|
||||
// database not loaded, do nothing
|
||||
}
|
||||
else // vault container missing
|
||||
WriteTimestampedLogEntry("NBDE> Error: unable to locate '"+NBDE_VAULT_TAG+"' vault container object");
|
||||
}
|
||||
|
||||
void NBDE_SetCampaignInt(string sCampaignName, string sVarname, int nInt, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
SetLocalInt(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname, nInt );
|
||||
}
|
||||
|
||||
void NBDE_SetCampaignFloat(string sCampaignName, string sVarname, float fFloat, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
SetLocalFloat(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname, fFloat);
|
||||
}
|
||||
|
||||
void NBDE_SetCampaignString(string sCampaignName, string sVarname, string sString, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
SetLocalString(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname, sString);
|
||||
}
|
||||
|
||||
void NBDE_SetCampaignLocation(string sCampaignName, string sVarname, location locLocation, object oPlayer = OBJECT_SELF)
|
||||
{
|
||||
SetLocalString( NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
NBDE_LOC_PREFIX + ((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname ,
|
||||
NBDE_LocationToString(locLocation) );
|
||||
}
|
||||
|
||||
void NBDE_SetCampaignVector(string sCampaignName, string sVarname, vector vVector, object oPlayer = OBJECT_SELF)
|
||||
{
|
||||
SetLocalString(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
NBDE_VEC_PREFIX + ((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname ,
|
||||
NBDE_VectorToString(vVector) );
|
||||
}
|
||||
|
||||
int NBDE_GetCampaignInt(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
return GetLocalInt(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname );
|
||||
}
|
||||
|
||||
float NBDE_GetCampaignFloat(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
return GetLocalFloat(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname );
|
||||
}
|
||||
|
||||
string NBDE_GetCampaignString(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
return GetLocalString(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname );
|
||||
}
|
||||
|
||||
location NBDE_GetCampaignLocation(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
return NBDE_StringToLocation( GetLocalString(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
NBDE_LOC_PREFIX + ((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname) );
|
||||
}
|
||||
|
||||
vector NBDE_GetCampaignVector(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
return NBDE_StringToVector( GetLocalString(NBDE_GetCampaignDatabaseObject(sCampaignName),
|
||||
NBDE_VEC_PREFIX + ((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname) );
|
||||
}
|
||||
|
||||
void NBDE_DeleteCampaignInt(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
DeleteLocalInt(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname);
|
||||
}
|
||||
|
||||
void NBDE_DeleteCampaignFloat(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
DeleteLocalFloat(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname);
|
||||
}
|
||||
|
||||
void NBDE_DeleteCampaignString(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
DeleteLocalString(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname);
|
||||
}
|
||||
|
||||
void NBDE_DeleteCampaignLocation(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
DeleteLocalString(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
NBDE_LOC_PREFIX + ((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname);
|
||||
}
|
||||
|
||||
void NBDE_DeleteCampaignVector(string sCampaignName, string sVarname, object oPlayer = OBJECT_INVALID)
|
||||
{
|
||||
DeleteLocalString(NBDE_GetCampaignDatabaseObject(sCampaignName) ,
|
||||
NBDE_VEC_PREFIX + ((GetIsObjectValid(oPlayer)) ? NBDE_GetPlayerKey(oPlayer) : "") + sVarname);
|
||||
}
|
||||
|
||||
|
@@ -32,6 +32,39 @@
|
||||
|
||||
void main()
|
||||
{
|
||||
// * if petrified, jump out
|
||||
if (GetHasEffect(EFFECT_TYPE_PETRIFY, OBJECT_SELF) == TRUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// * If dead, exit directly.
|
||||
if (GetIsDead(OBJECT_SELF) == TRUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// See if what we just 'heard' matches any of our
|
||||
// predefined patterns
|
||||
int nMatch = GetListenPatternNumber();
|
||||
object oShouter = GetLastSpeaker();
|
||||
string sSpoken = GetMatchedSubstring(0);
|
||||
|
||||
// 2008.05.25 tsunami282 - removed for NWN 1.69 (no longer needed)
|
||||
//DMFI CODE ADDITIONS BEGIN HERE
|
||||
// if (GetIsPC(oShouter) || GetIsDM(oShouter) || GetIsDMPossessed(oShouter))
|
||||
// {
|
||||
// ExecuteScript("dmfi_voice_exe", OBJECT_SELF);
|
||||
// }
|
||||
|
||||
if (nMatch == -1 && GetIsPC(oShouter) &&(GetLocalInt(GetModule(), "dmfi_AllMute") || GetLocalInt(OBJECT_SELF, "dmfi_Mute")))
|
||||
{
|
||||
SendMessageToAllDMs(GetName(oShouter) + " is trying to speak to a muted NPC, " + GetName(OBJECT_SELF) + ", in area " + GetName(GetArea(OBJECT_SELF)));
|
||||
SendMessageToPC(oShouter, "This NPC is muted. A DM will be here shortly.");
|
||||
return;
|
||||
}
|
||||
//DMFI CODE ADDITIONS END HERE
|
||||
|
||||
// Pre-conversation-event. Returns TRUE if we interrupt this script call.
|
||||
if(FirePreUserEvent(AI_FLAG_UDE_ON_DIALOGUE_PRE_EVENT, EVENT_ON_DIALOGUE_PRE_EVENT)) return;
|
||||
|
||||
@@ -39,10 +72,6 @@ void main()
|
||||
if(GetAIOff()) return;
|
||||
|
||||
// Declarations
|
||||
int nMatch = GetListenPatternNumber();
|
||||
object oShouter = GetLastSpeaker();
|
||||
string sSpoken = GetMatchedSubstring(0);
|
||||
|
||||
// We can ignore everything under special cases - EG no valid shouter,
|
||||
// we are fleeing, its us, or we are not in the same area.
|
||||
// - We break out of the script if this happens.
|
||||
@@ -57,11 +86,14 @@ void main()
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Conversation if not a shout.
|
||||
|
||||
if(nMatch == -1)
|
||||
{
|
||||
// * Don't speak when dead. 1.4 change (an obvious one to make)
|
||||
if(CanSpeak())
|
||||
|
||||
{
|
||||
// Make sure it is a PC and we are not fighting.
|
||||
if(!GetIsFighting() && (GetIsPC(oShouter) || GetIsDMPossessed(oShouter)))
|
||||
@@ -96,6 +128,8 @@ void main()
|
||||
(!GetHasEffect(EFFECT_TYPE_DEAF) || GetObjectSeen(oShouter)))
|
||||
{
|
||||
if(GetIsFriend(oShouter) || GetFactionEqual(oShouter))
|
||||
|
||||
|
||||
{
|
||||
// If they are a friend, not a PC, and a valid number, react.
|
||||
// In the actual RespondToShout call, we do check to see if we bother.
|
||||
@@ -146,6 +180,7 @@ void main()
|
||||
// Short non-respond
|
||||
SetLocalTimer(AI_TIMER_SHOUT_IGNORE_ANYTHING_SAID, 6.0);
|
||||
|
||||
|
||||
// Attack the enemy!
|
||||
ClearAllActions();
|
||||
DetermineCombatRound(oShouter);
|
||||
@@ -158,3 +193,4 @@ void main()
|
||||
// Fire End of Dialogue event
|
||||
FireUserEvent(AI_FLAG_UDE_ON_DIALOGUE_EVENT, EVENT_ON_DIALOGUE_EVENT);
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,28 @@
|
||||
|
||||
#include "J_INC_OTHER_AI"
|
||||
|
||||
|
||||
//DMFI CODE ADDITIONS*****************************
|
||||
void SafeFaction(object oCurrent, object oAttacker)
|
||||
{
|
||||
AssignCommand(oAttacker, ClearAllActions());
|
||||
AssignCommand(oCurrent, ClearAllActions());
|
||||
// * Note: waiting for Sophia to make SetStandardFactionReptuation to clear all personal reputation
|
||||
if (GetStandardFactionReputation(STANDARD_FACTION_COMMONER, oAttacker) <= 10)
|
||||
{ SetLocalInt(oAttacker, "NW_G_Playerhasbeenbad", 10); // * Player bad
|
||||
SetStandardFactionReputation(STANDARD_FACTION_COMMONER, 80, oAttacker);
|
||||
}
|
||||
if (GetStandardFactionReputation(STANDARD_FACTION_MERCHANT, oAttacker) <= 10)
|
||||
{ SetLocalInt(oAttacker, "NW_G_Playerhasbeenbad", 10); // * Player bad
|
||||
SetStandardFactionReputation(STANDARD_FACTION_MERCHANT, 80, oAttacker);
|
||||
}
|
||||
if (GetStandardFactionReputation(STANDARD_FACTION_DEFENDER, oAttacker) <= 10)
|
||||
{ SetLocalInt(oAttacker, "NW_G_Playerhasbeenbad", 10); // * Player bad
|
||||
SetStandardFactionReputation(STANDARD_FACTION_DEFENDER, 80, oAttacker);
|
||||
}
|
||||
}
|
||||
//END DMFI CODE ADDITIONS*************************
|
||||
|
||||
void main()
|
||||
{
|
||||
// Pre-attacked-event. Returns TRUE if we interrupt this script call.
|
||||
|
32
_module/nss/nw_s3_actitem01.nss
Normal file
32
_module/nss/nw_s3_actitem01.nss
Normal file
@@ -0,0 +1,32 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Actuvate Item Script
|
||||
//:: NW_S3_ActItem01
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This fires the event on the module that allows
|
||||
for items to have special powers.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Preston Watamaniuk
|
||||
//:: Created On: Dec 19, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Modified by The DMFI Team to handle activation of DMFI Wands & Widgets
|
||||
|
||||
void main()
|
||||
{
|
||||
object oItem = GetSpellCastItem();
|
||||
object oTarget = GetSpellTargetObject();
|
||||
location lLocal = GetSpellTargetLocation();
|
||||
|
||||
if (GetStringLeft(GetTag(oItem), 5) == "dmfi_" ||
|
||||
GetStringLeft(GetTag(oItem), 8) == "hlslang_")
|
||||
{
|
||||
SetLocalObject(OBJECT_SELF, "dmfi_item", oItem);
|
||||
SetLocalObject(OBJECT_SELF, "dmfi_target", oTarget);
|
||||
SetLocalLocation(OBJECT_SELF, "dmfi_location", lLocal);
|
||||
ExecuteScript("dmfi_activate", OBJECT_SELF);
|
||||
return;
|
||||
}
|
||||
SignalEvent(GetModule(), EventActivateItem(oItem, lLocal, oTarget));
|
||||
}
|
89
_module/nss/portal_start.nss
Normal file
89
_module/nss/portal_start.nss
Normal file
@@ -0,0 +1,89 @@
|
||||
/////////////////////////////////////////////////
|
||||
// Ultimate Teleport Script 1.0
|
||||
/////////////////////////////////////////////////
|
||||
// by Amurayi (mschdesign@hotmail.com)
|
||||
//
|
||||
// based on SirLestat's Secret Trapdoorscripts
|
||||
/////////////////////////////////////////////////
|
||||
/* The problem with most of the teleport scripts out there is that your companions
|
||||
won't be teleported with you if you ar ebeing teleported within the same area.
|
||||
This easy to configure script here is the solution for this old problem. Simply
|
||||
alter the way how the teleport shall work by turning the options on and off be
|
||||
setting the variables to 0 or 1 in the first ppart of this script.
|
||||
|
||||
What this script can do:
|
||||
- teleports player out of conversation, trigger or item
|
||||
- teleports player with or without companions
|
||||
- teleports player alone or the whole party (players)
|
||||
*/
|
||||
void JumpAssociate(object i_oPC, int i_type, object i_oWP)
|
||||
{
|
||||
object oAssociate = GetAssociate(i_type, i_oPC);
|
||||
if(GetIsObjectValid(oAssociate))
|
||||
AssignCommand(oAssociate, JumpToObject(i_oWP));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// uncomment one of the next 3 lines depending where you use the script:
|
||||
object oPC = GetPCSpeaker(); // for conversations
|
||||
// object oPC = GetEnteringObject; // for triggers
|
||||
// object oPC = GetLastUsedBy(); // for items/objects
|
||||
|
||||
// set to 1 if you want to teleport the whole party of the player, whereever every member is:
|
||||
int iTeleportWholeParty = 1;
|
||||
// set to 1 if you want the Associates of the player to be teleported as well, otherwise to 0:
|
||||
int iTeleportAssociateToo = 1;
|
||||
// Enter the destination Waypoint in here:
|
||||
object oDWP = GetWaypointByTag("wp_portal_start");
|
||||
// Make the player say something on his departure (so others will now that he teleported but crashed):
|
||||
string sGoodbye = "*fades out*";
|
||||
// Enter the message being send to the player when teleport starts:
|
||||
string sTeleportmessage = "Your surroundings begin to fade...";
|
||||
|
||||
|
||||
// Don't start Teleport at all if activator isn't a player or DM
|
||||
if(!GetIsPC(oPC))
|
||||
return;
|
||||
|
||||
if (iTeleportWholeParty == 1)
|
||||
{
|
||||
object oFM = GetFirstFactionMember(oPC);
|
||||
// Step through the party members.
|
||||
while(GetIsObjectValid(oFM))
|
||||
{
|
||||
AssignCommand(oFM, ActionSpeakString(sGoodbye));
|
||||
SendMessageToPC(oFM, sTeleportmessage);
|
||||
AssignCommand(oFM, DelayCommand(2.0, JumpToObject(oDWP)));
|
||||
if (iTeleportAssociateToo == 1)
|
||||
{
|
||||
// now send the players companions over as well:
|
||||
DelayCommand(2.0, JumpAssociate(oFM, ASSOCIATE_TYPE_ANIMALCOMPANION, oDWP));
|
||||
DelayCommand(2.0, JumpAssociate(oFM, ASSOCIATE_TYPE_DOMINATED, oDWP));
|
||||
DelayCommand(2.0, JumpAssociate(oFM, ASSOCIATE_TYPE_FAMILIAR, oDWP));
|
||||
DelayCommand(2.0, JumpAssociate(oFM, ASSOCIATE_TYPE_HENCHMAN, oDWP));
|
||||
DelayCommand(2.0, JumpAssociate(oFM, ASSOCIATE_TYPE_SUMMONED, oDWP));
|
||||
}
|
||||
// Select the next member of the faction and loop.
|
||||
oFM = GetNextFactionMember(oFM);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Uncomment the next 2 lines if you like fancy animations (plays the summon monster 3 animation)
|
||||
// effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3);
|
||||
// ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oFM);
|
||||
AssignCommand(oPC, ActionSpeakString(sGoodbye));
|
||||
SendMessageToPC(oPC, sTeleportmessage);
|
||||
AssignCommand(oPC, DelayCommand(2.0, JumpToObject(oDWP)));
|
||||
if (iTeleportAssociateToo == 1)
|
||||
{
|
||||
// now send the players companions over as well:
|
||||
DelayCommand(2.0, JumpAssociate(oPC, ASSOCIATE_TYPE_ANIMALCOMPANION, oDWP));
|
||||
DelayCommand(2.0, JumpAssociate(oPC, ASSOCIATE_TYPE_DOMINATED, oDWP));
|
||||
DelayCommand(2.0, JumpAssociate(oPC, ASSOCIATE_TYPE_FAMILIAR, oDWP));
|
||||
DelayCommand(2.0, JumpAssociate(oPC, ASSOCIATE_TYPE_HENCHMAN, oDWP));
|
||||
DelayCommand(2.0, JumpAssociate(oPC, ASSOCIATE_TYPE_SUMMONED, oDWP));
|
||||
}
|
||||
}
|
||||
}
|
33
_module/nss/re_common_blkd.nss
Normal file
33
_module/nss/re_common_blkd.nss
Normal file
@@ -0,0 +1,33 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: On Blocked script for BESIE commoners
|
||||
//:: re_common_blkd
|
||||
//:: Original On Blocked script Copyright (c) 2001 Bioware Corp.
|
||||
// modifications by Carlo
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This will cause blocked creatures to open
|
||||
doors, or failing that clear their action queue.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Preston Watamaniuk
|
||||
//:: Created On: Nov 23, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
void main()
|
||||
{
|
||||
object oDoor = GetBlockingDoor();
|
||||
// * Increment number of times blocked
|
||||
SetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED", GetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED") + 1);
|
||||
if (GetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED") > 1)
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED",0);
|
||||
ClearAllActions();
|
||||
}
|
||||
if(GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE) >= 5)
|
||||
{
|
||||
if(GetIsDoorActionPossible(oDoor, DOOR_ACTION_OPEN) && GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE) >= 7 )
|
||||
{
|
||||
DoDoorAction(oDoor, DOOR_ACTION_OPEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
96
_module/nss/re_common_spawn.nss
Normal file
96
_module/nss/re_common_spawn.nss
Normal file
@@ -0,0 +1,96 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Default: On Spawn In
|
||||
//:: NW_C2_DEFAULT9
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Determines the course of action to be taken
|
||||
after having just been spawned in
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Preston Watamaniuk
|
||||
//:: Created On: Oct 25, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "ms_name_inc"
|
||||
#include "rnd_commoner_inc"
|
||||
#include "NW_O2_CONINCLUDE"
|
||||
#include "NW_I0_GENERIC"
|
||||
|
||||
void main()
|
||||
{
|
||||
// Randomize Skin Tone
|
||||
rnd_skin(OBJECT_SELF);
|
||||
|
||||
// Randomize Head & Hair color
|
||||
rnd_head(OBJECT_SELF);
|
||||
|
||||
// Randomize Tattoos
|
||||
rnd_tattoo(OBJECT_SELF);
|
||||
|
||||
//Randomize Clothing
|
||||
rnd_clothes(OBJECT_SELF);
|
||||
|
||||
//Calls the Random Name Generator
|
||||
ms_Nomenclature(OBJECT_SELF);
|
||||
|
||||
// OPTIONAL BEHAVIORS (Comment In or Out to Activate )****************************************************************************
|
||||
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
|
||||
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
|
||||
// This causes the creature to say a special greeting in their conversation file
|
||||
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
|
||||
// greeting in order to designate it. As the creature is actually saying this to
|
||||
// himself, don't attach any player responses to the greeting.
|
||||
|
||||
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
|
||||
// This will set the listening pattern on the NPC to attack when allies call
|
||||
//SetSpawnInCondition(NW_FLAG_STEALTH);
|
||||
// If the NPC has stealth and they are a rogue go into stealth mode
|
||||
//SetSpawnInCondition(NW_FLAG_SEARCH);
|
||||
// If the NPC has Search go into Search Mode
|
||||
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
|
||||
// This will set the NPC to give a warning to non-enemies before attacking
|
||||
|
||||
//SetSpawnInCondition(NW_FLAG_SLEEP);
|
||||
//Creatures that spawn in during the night will be asleep.
|
||||
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
|
||||
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
|
||||
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
|
||||
//SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
|
||||
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
|
||||
//NOTE that these animations will play automatically for Encounter Creatures.
|
||||
|
||||
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
|
||||
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
|
||||
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
|
||||
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
|
||||
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
|
||||
|
||||
// CUSTOM USER DEFINED EVENTS
|
||||
/*
|
||||
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
|
||||
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
|
||||
events user 1000 - 1010
|
||||
*/
|
||||
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
|
||||
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
|
||||
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
|
||||
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
|
||||
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
|
||||
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
|
||||
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
|
||||
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
|
||||
|
||||
// DEFAULT GENERIC BEHAVIOR (DO NOT TOUCH) *****************************************************************************************
|
||||
|
||||
SetLocalInt(OBJECT_SELF, "iDialogue", Random(10) + 1);
|
||||
|
||||
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
|
||||
//WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
|
||||
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
|
||||
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
|
||||
// combat.
|
||||
GenerateNPCTreasure(); //* Use this to create a small amount of treasure on the creature
|
||||
}
|
||||
|
||||
|
98
_module/nss/re_commoner0.nss
Normal file
98
_module/nss/re_commoner0.nss
Normal file
@@ -0,0 +1,98 @@
|
||||
////////////////////////////////////////////////////
|
||||
/*
|
||||
Custom Random Commoner Table for use with the BESIE
|
||||
Random Encounter Package by Ray Miller
|
||||
*/
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
int iVarNum = GetLocalInt(OBJECT_SELF, "re_iVarNum");
|
||||
int END;
|
||||
int iWeight;
|
||||
int iCounter1;
|
||||
int iCounter2;
|
||||
string sChoice;
|
||||
object oMod = GetModule();
|
||||
while(!END)
|
||||
{
|
||||
sChoice = "";
|
||||
switch(iCounter1)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//DO NOT EDIT ABOVE THIS LINE/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//CUSTOM ENCOUNTER TABLE BELOW:///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Creature rezref goes between the " marks.
|
||||
// iWeight = number of times this mob should be considered for the likelyhood of appearing.
|
||||
|
||||
case 0:sChoice = "npc_com_hu_m001"; // Human Male
|
||||
iWeight = 10;
|
||||
break;
|
||||
|
||||
case 1:sChoice = "npc_com_hu_m002"; // Portly Human Male
|
||||
iWeight = 10;
|
||||
break;
|
||||
|
||||
case 2:sChoice = "npc_com_hu_f001"; // Human Female
|
||||
iWeight = 10;
|
||||
break;
|
||||
|
||||
case 3:sChoice = "npc_com_hu_f002"; // Portly Human Female
|
||||
iWeight = 10;
|
||||
break;
|
||||
|
||||
case 4:sChoice = "NPC_COM_HU_CM001"; // Human Male Child 01
|
||||
iWeight = 4;
|
||||
break;
|
||||
|
||||
case 5:sChoice = "NPC_COM_HU_CM002"; // Human Male Child 02
|
||||
iWeight = 4;
|
||||
break;
|
||||
|
||||
case 6:sChoice = "NPC_COM_HU_CF001"; // Human Female Child 01
|
||||
iWeight = 4;
|
||||
break;
|
||||
|
||||
case 7:sChoice = "NPC_COM_HU_CF002"; // Human Female Child 02
|
||||
iWeight = 4;
|
||||
break;
|
||||
|
||||
case 8:sChoice = "NPC_COM_DW_F001"; // Dwarven Female
|
||||
iWeight = 4;
|
||||
break;
|
||||
|
||||
case 9:sChoice = "NPC_COM_DW_F002"; // Portly Dwarven Female
|
||||
iWeight = 4;
|
||||
break;
|
||||
|
||||
case 10:sChoice = "NPC_COM_DW_M001"; // Dwarven Male
|
||||
iWeight = 3;
|
||||
break;
|
||||
|
||||
case 11:sChoice = "NPC_COM_DW_M002"; // Portly Dwarven Male
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 12:sChoice = "mhalforc";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//END OF CUSTOM ENCOUNTER TABLE! DO NOT EDIT BELOW THIS LINE//////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
default:END = TRUE;
|
||||
break;
|
||||
}
|
||||
if(GetStringLowerCase(sChoice) != "")
|
||||
{
|
||||
for(iCounter2 = 1; iCounter2 <= iWeight; iCounter2++)
|
||||
{
|
||||
SetLocalString(oMod, "re_sCreatureList" + IntToString(iVarNum), sChoice);
|
||||
iVarNum++;
|
||||
}
|
||||
}
|
||||
iCounter1++;
|
||||
}
|
||||
SetLocalInt(OBJECT_SELF, "re_iVarNum", iVarNum);
|
||||
}
|
169
_module/nss/re_commoner1.nss
Normal file
169
_module/nss/re_commoner1.nss
Normal file
@@ -0,0 +1,169 @@
|
||||
////////////////////////////////////////////////////
|
||||
/*
|
||||
Custom Random Commoner Table for use with the BESIE
|
||||
Random Encounter Package by Ray Miller
|
||||
*/
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
int iVarNum = GetLocalInt(OBJECT_SELF, "re_iVarNum");
|
||||
int END;
|
||||
int iWeight;
|
||||
int iCounter1;
|
||||
int iCounter2;
|
||||
string sChoice;
|
||||
object oMod = GetModule();
|
||||
while(!END)
|
||||
{
|
||||
sChoice = "";
|
||||
switch(iCounter1)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//DO NOT EDIT ABOVE THIS LINE/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//CUSTOM ENCOUNTER TABLE BELOW:///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
case 0:sChoice = "mhuman_1";// Creature tag goes between the " marks.
|
||||
iWeight = 2; // This is the number of times this mob should be considered for the likelyhood of appearing.
|
||||
break;
|
||||
|
||||
case 1:sChoice = "mhuman_2";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 2:sChoice = "mhuman_3";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 3:sChoice = "mhuman_4";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 4:sChoice = "mhuman_5";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 5:sChoice = "mhuman_6";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 6:sChoice = "mhuman_7";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 7:sChoice = "mhuman_8";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 8:sChoice = "mhuman_9";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 9:sChoice = "mhuman_10";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 10:sChoice = "fhuman_1";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 11:sChoice = "fhuman_2";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 12:sChoice = "fhuman_3";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 13:sChoice = "fhuman_4";// Creature tag goes between the " marks.
|
||||
iWeight = 2; // This is the number of times this mob should be considered for the likelyhood of appearing.
|
||||
break;
|
||||
|
||||
case 14:sChoice = "fhuman_5";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 15:sChoice = "fhuman_6";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 16:sChoice = "fhuman_7";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 17:sChoice = "fhuman_8";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 18:sChoice = "fhuman_9";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 19:sChoice = "fhuman_10";
|
||||
iWeight = 2;
|
||||
break;
|
||||
|
||||
case 20:sChoice = "melf";
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 21:sChoice = "felf";
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 22:sChoice = "mhalfelf";
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 23:sChoice = "fhalfelf";
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 24:sChoice = "mdwarf";
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 25:sChoice = "fhalforc";
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 26:sChoice = "mhalfling";
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 27:sChoice = "fhalfling";
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 28:sChoice = "mgnome";
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 29:sChoice = "fgnome";
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 30:sChoice = "mhalforc";
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//END OF CUSTOM ENCOUNTER TABLE! DO NOT EDIT BELOW THIS LINE//////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
default:END = TRUE;
|
||||
break;
|
||||
}
|
||||
if(GetStringLowerCase(sChoice) != "")
|
||||
{
|
||||
for(iCounter2 = 1; iCounter2 <= iWeight; iCounter2++)
|
||||
{
|
||||
SetLocalString(oMod, "re_sCreatureList" + IntToString(iVarNum), sChoice);
|
||||
iVarNum++;
|
||||
}
|
||||
}
|
||||
iCounter1++;
|
||||
}
|
||||
SetLocalInt(OBJECT_SELF, "re_iVarNum", iVarNum);
|
||||
}
|
139
_module/nss/re_commonspwnrhb.nss
Normal file
139
_module/nss/re_commonspwnrhb.nss
Normal file
@@ -0,0 +1,139 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: FileName re_mmorpghb.nss
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This script is used in the heartbeat of the
|
||||
BESIE Commoner Spawner tool, part of the BESIE
|
||||
Random Encounter System by Ray Miller.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 9-2-02
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "re_rndenc"
|
||||
void DoFacing(object oSource)
|
||||
{
|
||||
object oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oSource, 1, CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC);
|
||||
vector vTarget = GetPositionFromLocation(GetLocation(oTarget));
|
||||
vector vSource = GetPositionFromLocation(GetLocation(oSource));
|
||||
AssignCommand(oSource, SetFacingPoint(vTarget));
|
||||
if(oSource == GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oTarget, 1, CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC))
|
||||
{
|
||||
if(GetTag(oTarget) == "Patron"
|
||||
|| GetTag(oTarget) == "Citizen"
|
||||
|| GetTag(oTarget) == "Commoner"
|
||||
|| GetLocalObject(oTarget, "re_oRandomEncounterSpawner") == OBJECT_SELF)
|
||||
{
|
||||
if(!GetIsPC(oTarget)) AssignCommand(oTarget, SetFacingPoint(vSource));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
if(!GetLocalInt(OBJECT_SELF, "re_BESIE"))
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, "re_BESIE", TRUE);
|
||||
SetLocalString(OBJECT_SELF, "re_ToolType", "Commoner Spawner");
|
||||
}
|
||||
if(GetLocalInt(GetModule(), "re_disableCommonerSpawner") || GetLocalInt(GetArea(OBJECT_SELF), "re_disableCommonerSpawner") || GetLocalInt(OBJECT_SELF, "re_disable"))
|
||||
{
|
||||
if(!GetIsObjectValid(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner"))) SetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner", OBJECT_SELF);
|
||||
if(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner") == OBJECT_SELF) CleanHouse();
|
||||
return;
|
||||
}
|
||||
object oCreature;
|
||||
object oAmIASpawn;
|
||||
object oArea = GetArea(OBJECT_SELF);
|
||||
int iCounter1;
|
||||
int iCounter2;
|
||||
int iCounterSpawn;
|
||||
int bTimeIn;
|
||||
int bSpawn;
|
||||
int iSpawnRadius = GetFortitudeSavingThrow(OBJECT_SELF) * 5;
|
||||
int iTableNumber = GetReflexSavingThrow(OBJECT_SELF);
|
||||
int iMaxSpawns = GetWillSavingThrow(OBJECT_SELF);
|
||||
int iSpawnAmount;
|
||||
string sBuild;
|
||||
string sCustom = "nil";
|
||||
string sTemplate = "re_commoner" + IntToString(iTableNumber);
|
||||
if(!GetLocalInt(OBJECT_SELF, "re_bCommonerSpawner")) SetLocalInt(OBJECT_SELF, "bCommonerSpawner", TRUE);
|
||||
if(!GetLocalInt(OBJECT_SELF, "bFirstRun"))
|
||||
{
|
||||
if(GetStringLeft(GetTag(OBJECT_SELF), 3) == "re_")
|
||||
{
|
||||
for(iCounter1 = 3; iCounter1 <= GetStringLength(GetTag(OBJECT_SELF)); iCounter1++)
|
||||
{
|
||||
if(sCustom != "nil"
|
||||
&& (GetSubString(GetTag(OBJECT_SELF), iCounter1, 1) == "0" || StringToInt(GetSubString(GetTag(OBJECT_SELF), iCounter1, 1)) > 0))
|
||||
{
|
||||
sBuild = sBuild + GetSubString(GetTag(OBJECT_SELF), iCounter1, 1);
|
||||
}
|
||||
else if(sCustom != "nil")
|
||||
{
|
||||
if(sCustom == "b") SetLocalInt(OBJECT_SELF, "re_iBegin", StringToInt(sBuild));
|
||||
if(sCustom == "e") SetLocalInt(OBJECT_SELF, "re_iEnd", StringToInt(sBuild));
|
||||
sCustom = "nil";
|
||||
sBuild = "";
|
||||
}
|
||||
if(GetSubString(GetTag(OBJECT_SELF), iCounter1, 1) == "b" || GetSubString(GetTag(OBJECT_SELF), iCounter1, 1) == "e")
|
||||
{
|
||||
sCustom = GetSubString(GetTag(OBJECT_SELF), iCounter1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
SetLocalInt(OBJECT_SELF, "bFirstRun", TRUE);
|
||||
}
|
||||
if(GetLocalInt(OBJECT_SELF, "re_iBegin") > 23) SetLocalInt(OBJECT_SELF, "re_iBegin", 23);
|
||||
if(GetLocalInt(OBJECT_SELF, "re_iEnd") > 23) SetLocalInt(OBJECT_SELF, "re_iEnd", 23);
|
||||
int iStartTime = GetLocalInt(OBJECT_SELF, "re_iBegin");
|
||||
int iStopTime = GetLocalInt(OBJECT_SELF, "re_iEnd");
|
||||
if((iStartTime <= iStopTime && (GetTimeHour() >= iStartTime && GetTimeHour() < iStopTime))
|
||||
|| (iStartTime >= iStopTime && (GetTimeHour() >= iStartTime || GetTimeHour() < iStopTime)))
|
||||
bTimeIn = TRUE;
|
||||
else bTimeIn = FALSE;
|
||||
if(iMaxSpawns < 0)iMaxSpawns = 1;
|
||||
oAmIASpawn = GetFirstObjectInArea(oArea);
|
||||
while(GetIsObjectValid(oAmIASpawn))
|
||||
{
|
||||
if(GetIsPC(oAmIASpawn) && !GetLocalInt(GetModule(), "re_" + GetPCPlayerName(oAmIASpawn))) bSpawn = TRUE;
|
||||
if(GetLocalObject(oAmIASpawn, "re_oRandomEncounterSpawner") == OBJECT_SELF && bTimeIn)
|
||||
{
|
||||
iCounterSpawn++;
|
||||
|
||||
//This is so the CleanHouse function doesn't clean up the commoners.
|
||||
if(GetLocalInt(oAmIASpawn, "re_bRandomEncounter")) DeleteLocalInt(oAmIASpawn, "re_bRandomEncounter");
|
||||
|
||||
int iShouldIWalk = Random(100) + 1;
|
||||
if(Random(100) + 1 < GetMaxHitPoints(OBJECT_SELF) && !GetIsInCombat(oAmIASpawn) && !IsInConversation(oAmIASpawn) && !GetIsPC(oAmIASpawn))
|
||||
{
|
||||
ClearAllActions();
|
||||
RandomWalk2(GetLocation(OBJECT_SELF), iSpawnRadius, oAmIASpawn);
|
||||
}
|
||||
if(!GetIsInCombat(oAmIASpawn) && !IsInConversation(oAmIASpawn) && !GetIsPC(oAmIASpawn)) AssignCommand(oAmIASpawn, ActionDoCommand(DoFacing(oAmIASpawn)));
|
||||
}
|
||||
if(GetLocalObject(oAmIASpawn, "re_oRandomEncounterSpawner") == OBJECT_SELF && (!bTimeIn || GetLocalInt(OBJECT_SELF, "re_bDespawn")))
|
||||
{
|
||||
if(!GetIsInCombat(oAmIASpawn) && !IsInConversation(oAmIASpawn) && !GetIsPC(oAmIASpawn)) DestroyObject(oAmIASpawn);
|
||||
}
|
||||
oAmIASpawn = GetNextObjectInArea(oArea);
|
||||
}
|
||||
if(!bSpawn) SetLocalInt(OBJECT_SELF, "re_bDespawn", TRUE);
|
||||
else DeleteLocalInt(OBJECT_SELF, "re_bDespawn");
|
||||
if(iCounterSpawn < iMaxSpawns && bSpawn && bTimeIn)
|
||||
{
|
||||
//This is to prevent a Too Many Instructions error that occurs if more than 23 spawns are generated
|
||||
//in a single loop.
|
||||
if(iMaxSpawns - iCounterSpawn > 20) iSpawnAmount = 20;
|
||||
else iSpawnAmount = iMaxSpawns - iCounterSpawn;
|
||||
for(iCounter2 = 1; iCounter2 <= iSpawnAmount; iCounter2++)
|
||||
{
|
||||
oCreature = RandomEncounter(100.0, OBJECT_SELF, sTemplate, 0, 1, 1, iSpawnRadius, 360);
|
||||
DelayCommand(2.0, DoFacing(oCreature));
|
||||
}
|
||||
}
|
||||
if(!GetIsObjectValid(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner"))) SetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner", OBJECT_SELF);
|
||||
if(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner") == OBJECT_SELF) CleanHouse();
|
||||
}
|
125
_module/nss/re_custom.nss
Normal file
125
_module/nss/re_custom.nss
Normal file
@@ -0,0 +1,125 @@
|
||||
////////////////////////////////////////////////////
|
||||
/*
|
||||
Custom Random Encounter Table for use with the BESIE
|
||||
Random Encounter Package by Ray Miller
|
||||
*/
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
int iVarNum = GetLocalInt(OBJECT_SELF, "iVarNum");
|
||||
float fMinCR = GetLocalFloat(OBJECT_SELF, "fMinCR");
|
||||
float fMaxCR = GetLocalFloat(OBJECT_SELF, "fMaxCR");
|
||||
int iCounter1;
|
||||
int iCounter2;
|
||||
int iMaxNum;
|
||||
int iMinNum;
|
||||
int iWeight;
|
||||
float fCR;
|
||||
string sChoice = "nil";
|
||||
object oMod = GetModule();
|
||||
while(sChoice != "")
|
||||
{
|
||||
sChoice = "";
|
||||
switch(iCounter1)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//DO NOT EDIT ABOVE THIS LINE/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//CUSTOM ENCOUNTER TABLE BELOW:///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
case 0:sChoice = "";// Creature tag goes between the " marks.
|
||||
fCR = 0.0; // Set this to the challenge rating of the creature as shown on the creature pallette.
|
||||
iMinNum = 0; //
|
||||
iMaxNum = 0; // If these are left at zero then an appropriate number of creatures will be spawned based on the CR.
|
||||
iWeight = 1; // This is the number of times this mob should be considered for the likelyhood of appearing.
|
||||
break;
|
||||
|
||||
case 1:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 2:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 3:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 4:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 5:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 6:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 7:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 8:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 9:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 10:sChoice = "";
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
fCR = 0.0;
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//END OF CUSTOM ENCOUNTER TABLE! DO NOT EDIT BELOW THIS LINE//////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
if(fCR >= fMinCR && fCR <= fMaxCR && GetStringLowerCase(sChoice) != "")
|
||||
{
|
||||
for(iCounter2 = 1; iCounter2 <= iWeight; iCounter2++)
|
||||
{
|
||||
SetLocalString(oMod, "sCreatureList" + IntToString(iVarNum), sChoice);
|
||||
SetLocalInt(oMod, "iMaxNumberOfCreatures" + IntToString(iVarNum), iMaxNum);
|
||||
SetLocalInt(oMod, "iMinNumberOfCreatures" + IntToString(iVarNum), iMinNum);
|
||||
iVarNum++;
|
||||
}
|
||||
}
|
||||
iCounter1++;
|
||||
}
|
||||
SetLocalInt(OBJECT_SELF, "iVarNum", iVarNum);
|
||||
}
|
125
_module/nss/re_custom1.nss
Normal file
125
_module/nss/re_custom1.nss
Normal file
@@ -0,0 +1,125 @@
|
||||
////////////////////////////////////////////////////
|
||||
/*
|
||||
Custom Random Encounter Table for use with the BESIE
|
||||
Random Encounter Package by Ray Miller
|
||||
*/
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
int iVarNum = GetLocalInt(OBJECT_SELF, "iVarNum");
|
||||
float fMinCR = GetLocalFloat(OBJECT_SELF, "fMinCR");
|
||||
float fMaxCR = GetLocalFloat(OBJECT_SELF, "fMaxCR");
|
||||
int iCounter1;
|
||||
int iCounter2;
|
||||
int iMaxNum;
|
||||
int iMinNum;
|
||||
int iWeight;
|
||||
float fCR;
|
||||
string sChoice = "nil";
|
||||
object oMod = GetModule();
|
||||
while(sChoice != "")
|
||||
{
|
||||
sChoice = "";
|
||||
switch(iCounter1)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//DO NOT EDIT ABOVE THIS LINE/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//CUSTOM ENCOUNTER TABLE BELOW:///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
case 0:sChoice = "darkened_wolf";// Creature tag goes between the " marks.
|
||||
fCR = 1.5; // Set this to the challenge rating of the creature as shown on the creature pallette.
|
||||
iMinNum = 2; //
|
||||
iMaxNum = 8; // If these are left at zero then an appropriate number of creatures will be spawned based on the CR.
|
||||
iWeight = 1; // This is the number of times this mob should be considered for the likelyhood of appearing.
|
||||
break;
|
||||
|
||||
case 1:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 2:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 3:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 4:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 5:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 6:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 7:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 8:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 9:sChoice = "";
|
||||
fCR = 0.0;
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
break;
|
||||
|
||||
case 10:sChoice = "";
|
||||
iMinNum = 0;
|
||||
iMaxNum = 0;
|
||||
iWeight = 1;
|
||||
fCR = 0.0;
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//END OF CUSTOM ENCOUNTER TABLE! DO NOT EDIT BELOW THIS LINE//////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
if(fCR >= fMinCR && fCR <= fMaxCR && GetStringLowerCase(sChoice) != "")
|
||||
{
|
||||
for(iCounter2 = 1; iCounter2 <= iWeight; iCounter2++)
|
||||
{
|
||||
SetLocalString(oMod, "sCreatureList" + IntToString(iVarNum), sChoice);
|
||||
SetLocalInt(oMod, "iMaxNumberOfCreatures" + IntToString(iVarNum), iMaxNum);
|
||||
SetLocalInt(oMod, "iMinNumberOfCreatures" + IntToString(iVarNum), iMinNum);
|
||||
iVarNum++;
|
||||
}
|
||||
}
|
||||
iCounter1++;
|
||||
}
|
||||
SetLocalInt(OBJECT_SELF, "iVarNum", iVarNum);
|
||||
}
|
109
_module/nss/re_levspawnerhb.nss
Normal file
109
_module/nss/re_levspawnerhb.nss
Normal file
@@ -0,0 +1,109 @@
|
||||
//:://///////////////////////////////////////////////////////////////
|
||||
//:: FileName re_spawnerhb
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://///////////////////////////////////////////////////////////////
|
||||
/*
|
||||
This script is used in the heartbeat of the
|
||||
BESIE RES tool, part of the BESIE Random
|
||||
Encounter package by Ray Miller.
|
||||
*/
|
||||
//:://///////////////////////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 9-2-02
|
||||
//:://///////////////////////////////////////////////////////////////
|
||||
#include "re_rndenc"
|
||||
void main()
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//Set this parameter to FALSE if you wish
|
||||
//your encounter distances to be constant
|
||||
int RandomDistance = TRUE;
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
/*
|
||||
If you want a PW RES tool to start and stop spawning
|
||||
creatures at particular game times, set the following variables
|
||||
to the appropriate times and save the script under a different
|
||||
name. You could also set the local integers "re_iBegin" and
|
||||
"re_iEnd" on the spawner externally if you wanted.
|
||||
*/
|
||||
int StartTime = 0;
|
||||
int StopTime = 0;
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
float fChanceOfEncounter;
|
||||
if(StartTime || StopTime)
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, "re_iBegin", StartTime);
|
||||
SetLocalInt(OBJECT_SELF, "re_iEnd", StopTime);
|
||||
}
|
||||
if(GetLocalInt(OBJECT_SELF, "re_iBegin") > 23) SetLocalInt(OBJECT_SELF, "re_iBegin", 23);
|
||||
if(GetLocalInt(OBJECT_SELF, "re_iEnd") > 23) SetLocalInt(OBJECT_SELF, "re_iEnd", 23);
|
||||
if(!GetLocalInt(OBJECT_SELF, "re_BESIE"))
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, "re_BESIE", TRUE);
|
||||
SetLocalString(OBJECT_SELF, "re_ToolType", "PW RES");
|
||||
}
|
||||
if(GetLocalInt(GetModule(), "re_disablePWRES") || GetLocalInt(GetArea(OBJECT_SELF), "re_disablePWRES") || GetLocalInt(OBJECT_SELF, "re_disable"))
|
||||
{
|
||||
if(!GetIsObjectValid(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner"))) SetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner", OBJECT_SELF);
|
||||
if(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner") == OBJECT_SELF) CleanHouse();
|
||||
return;
|
||||
}
|
||||
int iStartTime = GetLocalInt(OBJECT_SELF, "re_iBegin");
|
||||
int iStopTime = GetLocalInt(OBJECT_SELF, "re_iEnd");
|
||||
if((iStartTime <= iStopTime && (GetTimeHour() >= iStartTime && GetTimeHour() < iStopTime))
|
||||
|| (iStartTime >= iStopTime && (GetTimeHour() >= iStartTime || GetTimeHour() < iStopTime)))
|
||||
fChanceOfEncounter = IntToFloat(GetMaxHitPoints(OBJECT_SELF)) / 100;
|
||||
else fChanceOfEncounter = 0.0;
|
||||
int iFaction;
|
||||
int iCounterX;
|
||||
object oEncounterObject;
|
||||
object oArea = GetArea(OBJECT_SELF);
|
||||
object oPC = GetFirstPC();
|
||||
while(GetIsObjectValid(oPC))
|
||||
{
|
||||
if(GetArea(oPC) == oArea)
|
||||
{
|
||||
string sLeader = GetPCPlayerName(GetFactionLeader(oPC)) + GetName(GetFactionLeader(oPC));
|
||||
if(!GetLocalInt(OBJECT_SELF, "i" + sLeader))
|
||||
{
|
||||
iFaction++;
|
||||
SetLocalString(OBJECT_SELF, "sFaction" + IntToString(iFaction), sLeader);
|
||||
}
|
||||
SetLocalInt(OBJECT_SELF, "i" + sLeader, GetLocalInt(OBJECT_SELF, "i" + sLeader) + 1);
|
||||
SetLocalObject(OBJECT_SELF, "o" + sLeader + IntToString(GetLocalInt(OBJECT_SELF, "i" + sLeader)), oPC);
|
||||
}
|
||||
oPC = GetNextPC();
|
||||
}
|
||||
if(!GetIsObjectValid(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner"))) SetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner", OBJECT_SELF);
|
||||
if(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner") == OBJECT_SELF) CleanHouse();
|
||||
if(!iFaction) return;
|
||||
string sLeader = GetLocalString(OBJECT_SELF, "sFaction" + IntToString(Random(iFaction) + 1));
|
||||
int iMember = Random(GetLocalInt(OBJECT_SELF, "i" + sLeader)) + 1;
|
||||
oEncounterObject = GetLocalObject(OBJECT_SELF, "o" + sLeader + IntToString(iMember));
|
||||
for(iCounterX = 1; iCounterX <= iFaction; iCounterX++)
|
||||
{
|
||||
DeleteLocalInt(OBJECT_SELF, "i" + GetLocalString(OBJECT_SELF, "sFaction" + IntToString(iCounterX)));
|
||||
DeleteLocalString(OBJECT_SELF, "sFaction" + IntToString(iCounterX));
|
||||
}
|
||||
string sTemplate = GetTag(OBJECT_SELF);
|
||||
int iNumberOfParties;
|
||||
int iMinDistance = RandomDistance;
|
||||
int iLevel = GetFortitudeSavingThrow(OBJECT_SELF);
|
||||
int iCheckDistance = GetReflexSavingThrow(OBJECT_SELF);
|
||||
int iMaxDistance = GetWillSavingThrow(OBJECT_SELF);
|
||||
|
||||
// Return if the resting variable is set by the re_onrest script.
|
||||
if(GetLocalInt(oEncounterObject, "re_resting")) return;
|
||||
|
||||
if(!iMaxDistance)
|
||||
{
|
||||
iMaxDistance = 1;
|
||||
}
|
||||
if(GetStringLeft(sTemplate, 3) != "re_")
|
||||
sTemplate = "random";
|
||||
fChanceOfEncounter = IntToFloat(iFaction) * fChanceOfEncounter;
|
||||
RandomEncounter(fChanceOfEncounter, oEncounterObject, sTemplate, 0, 0, iMinDistance, iMaxDistance, 360, 0, iCheckDistance, iLevel, 0);
|
||||
}
|
153
_module/nss/re_mmorpghb.nss
Normal file
153
_module/nss/re_mmorpghb.nss
Normal file
@@ -0,0 +1,153 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: FileName re_mmorpghb.nss
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This script is used in the heartbeat of the
|
||||
BESIE RES tool, part of the BESIE Random Encounter
|
||||
package by Ray Miller.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 9-2-02
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "re_rndenc"
|
||||
void main()
|
||||
{
|
||||
///////////////////////////////////////////////////////////
|
||||
/*
|
||||
if you don't want a DM possessed NPC to produce spawns,
|
||||
insert the following code into your module OnClientEnter
|
||||
handler.
|
||||
|
||||
note: this code is contained in the script "re_oncliententer"
|
||||
|
||||
if(GetIsDM(GetEnteringObject())) SetLocalInt(GetModule(), "re_" + GetName(GetEnteringObject()), TRUE);
|
||||
else DeleteLocalInt(GetModule(), "re_" + GetName(GetEnteringObject()));
|
||||
*/
|
||||
///////////////////////////////////////////////////////////
|
||||
/*
|
||||
If you want a MMORPG Spawner to start and stop spawning
|
||||
creatures at particular game times, set the following variables
|
||||
to the appropriate times and save the script under a different
|
||||
name. You could also set the local integers "re_iBegin" and
|
||||
"re_iEnd" on the spawner externally if you wanted.
|
||||
*/
|
||||
int StartTime = 0;
|
||||
int StopTime = 0;
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
int bTimeIn;
|
||||
if(StartTime || StopTime)
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, "re_iBegin", StartTime);
|
||||
SetLocalInt(OBJECT_SELF, "re_iEnd", StopTime);
|
||||
}
|
||||
if(GetLocalInt(OBJECT_SELF, "re_iBegin") > 23) SetLocalInt(OBJECT_SELF, "re_iBegin", 23);
|
||||
if(GetLocalInt(OBJECT_SELF, "re_iEnd") > 23) SetLocalInt(OBJECT_SELF, "re_iEnd", 23);
|
||||
if(!GetLocalInt(OBJECT_SELF, "re_BESIE"))
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, "re_BESIE", TRUE);
|
||||
SetLocalString(OBJECT_SELF, "re_ToolType", "MMORPG Spawner");
|
||||
}
|
||||
if(GetLocalInt(GetModule(), "re_disableMMORPG") || GetLocalInt(GetArea(OBJECT_SELF), "re_disableMMORPG") || GetLocalInt(OBJECT_SELF, "re_disable"))
|
||||
{
|
||||
if(!GetIsObjectValid(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner"))) SetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner", OBJECT_SELF);
|
||||
if(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner") == OBJECT_SELF) CleanHouse();
|
||||
return;
|
||||
}
|
||||
int iStartTime = GetLocalInt(OBJECT_SELF, "re_iBegin");
|
||||
int iStopTime = GetLocalInt(OBJECT_SELF, "re_iEnd");
|
||||
if((iStartTime <= iStopTime && (GetTimeHour() >= iStartTime && GetTimeHour() < iStopTime))
|
||||
|| (iStartTime >= iStopTime && (GetTimeHour() >= iStartTime || GetTimeHour() < iStopTime)))
|
||||
bTimeIn = TRUE;
|
||||
else bTimeIn = FALSE;
|
||||
string sTemplate;
|
||||
object oCreature;
|
||||
object oAmIASpawn;
|
||||
object oArea = GetArea(OBJECT_SELF);
|
||||
int iTreasure;
|
||||
int iType;
|
||||
int bSpawnOne;
|
||||
int iCounterPC;
|
||||
int iCounterParty;
|
||||
int iCounterSpawn;
|
||||
int iSpawnRadius = GetFortitudeSavingThrow(OBJECT_SELF) * 5;
|
||||
int iEncounterLevel = GetReflexSavingThrow(OBJECT_SELF);
|
||||
int iMaxSpawns = GetWillSavingThrow(OBJECT_SELF);
|
||||
float fZeroTest;
|
||||
float fPCFactor;
|
||||
float fChanceOfSpawn;
|
||||
float fChallengeFactor;
|
||||
float fFactor;
|
||||
if(!iMaxSpawns) return;
|
||||
if(!iEncounterLevel)
|
||||
{
|
||||
oAmIASpawn = GetFirstObjectInArea(oArea);
|
||||
while(GetIsObjectValid(oAmIASpawn))
|
||||
{
|
||||
if(GetIsPC(oAmIASpawn))
|
||||
{
|
||||
iCounterPC++;
|
||||
if(GetFactionLeader(oAmIASpawn) == oAmIASpawn)
|
||||
{
|
||||
iCounterParty++;
|
||||
}
|
||||
iEncounterLevel = iEncounterLevel + GetLevelByPosition(1, oAmIASpawn) + GetLevelByPosition(2, oAmIASpawn) + GetLevelByPosition(3, oAmIASpawn);
|
||||
if(GetIsObjectValid(GetHenchman(oAmIASpawn)))
|
||||
{
|
||||
iEncounterLevel = iEncounterLevel + GetLevelByPosition(1, GetHenchman(oAmIASpawn)) + GetLevelByPosition(2, GetHenchman(oAmIASpawn)) + GetLevelByPosition(3, GetHenchman(oAmIASpawn));
|
||||
}
|
||||
}
|
||||
oAmIASpawn = GetNextObjectInArea(oArea);
|
||||
}
|
||||
if(iCounterParty < 1) iCounterParty = 1;
|
||||
iEncounterLevel = FloatToInt(IntToFloat(iEncounterLevel) / IntToFloat(iCounterParty));
|
||||
}
|
||||
if(iMaxSpawns < 0)iMaxSpawns = 1;
|
||||
|
||||
//This code was removed in v1.8. I'm not sure why I was doing things this way.
|
||||
//if(GetStringLeft(GetTag(OBJECT_SELF), 3) == "re_")
|
||||
// {
|
||||
sTemplate = GetTag(OBJECT_SELF);
|
||||
// }
|
||||
//else
|
||||
// {
|
||||
// sTemplate = "random";
|
||||
// }
|
||||
oAmIASpawn = GetFirstObjectInArea(oArea);
|
||||
while(GetIsObjectValid(oAmIASpawn))
|
||||
{
|
||||
if(GetLocalInt(oAmIASpawn, "re_bRandomEncounter") && GetLocalObject(oAmIASpawn, "re_oRandomEncounterSpawner") == OBJECT_SELF)
|
||||
{
|
||||
iCounterSpawn++;
|
||||
if(!bTimeIn && !GetIsInCombat(oAmIASpawn) && !IsInConversation(oAmIASpawn)) DestroyObject(oAmIASpawn);
|
||||
if(!iEncounterLevel) SetLocalInt(oAmIASpawn, "re_iRandomEncounterLifeTime", 450);
|
||||
else SetLocalInt(oAmIASpawn, "re_iRandomEncounterLifeTime", 900);
|
||||
int iShouldIWalk = Random(100) + 1;
|
||||
if(Random(100) + 1 < GetMaxHitPoints(OBJECT_SELF) && !GetIsInCombat(oAmIASpawn) && !GetIsPC(oAmIASpawn))
|
||||
{
|
||||
ClearAllActions();
|
||||
RandomWalk2(GetLocation(OBJECT_SELF), iSpawnRadius, oAmIASpawn);
|
||||
}
|
||||
}
|
||||
if(GetIsPC(oAmIASpawn) && !GetLocalInt(GetModule(), "re_" + GetPCPlayerName(oAmIASpawn))) bSpawnOne = TRUE;
|
||||
oAmIASpawn = GetNextObjectInArea(oArea);
|
||||
}
|
||||
if(bSpawnOne && bTimeIn && iCounterSpawn < iMaxSpawns)
|
||||
{
|
||||
if(iCounterPC > iMaxSpawns / 4) iCounterPC = iMaxSpawns / 4;
|
||||
//The following two lines were put in place with v1.8 because of some rare div by zero reports. This is
|
||||
//the only place where this spawner could generate this error. I suspect it has to do with the presence
|
||||
//of a dm possessed creature, or something of that nature. At any rate, this should eliminate the error.
|
||||
fZeroTest = (IntToFloat(iMaxSpawns) - ((IntToFloat(iCounterPC) / (IntToFloat(iMaxSpawns) * 0.25)) * IntToFloat(iCounterSpawn)));
|
||||
if(fZeroTest == 0.0) return;
|
||||
|
||||
fPCFactor = IntToFloat(iMaxSpawns) / fZeroTest;
|
||||
fChanceOfSpawn = ((100.0 - ((IntToFloat(iCounterSpawn) / IntToFloat(iMaxSpawns)) * 100.0)) * fPCFactor);
|
||||
oCreature = RandomEncounter(fChanceOfSpawn, OBJECT_SELF, sTemplate, 0, 1, 1, iSpawnRadius, 360, 0, 0, iEncounterLevel, 5);
|
||||
}
|
||||
if(!GetIsObjectValid(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner"))) SetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner", OBJECT_SELF);
|
||||
if(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner") == OBJECT_SELF) CleanHouse();
|
||||
}
|
38
_module/nss/re_moditemdrop.nss
Normal file
38
_module/nss/re_moditemdrop.nss
Normal file
@@ -0,0 +1,38 @@
|
||||
//:://////////////////////////////////////////////
|
||||
//:: FileName re_moditemdrop.nss
|
||||
//:: Copyright (c) 2002 Ray Miller
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Note: This script goes on the Item Unacquired
|
||||
handler for the module object and is used to
|
||||
stamp dropped items with a local time variable
|
||||
for use with the "CleanHouse()" function of the
|
||||
BESIE Random Encounter Package by Ray Miller.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 7/6/2002
|
||||
//:://////////////////////////////////////////////
|
||||
void main()
|
||||
{
|
||||
int iMph;
|
||||
if(!GetLocalInt(GetModule(), "iMph"))
|
||||
{
|
||||
iMph = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
iMph = GetLocalInt(GetModule(), "iMph");
|
||||
}
|
||||
int iMin = 60;
|
||||
int iHr = iMin * iMph;
|
||||
int iDay = iHr * 24;
|
||||
int iMth = iDay * 28;
|
||||
int iYr = iMth * 12;
|
||||
object oAmIDroppedLoot = GetModuleItemLost();
|
||||
if(GetIsObjectValid(oAmIDroppedLoot))
|
||||
{
|
||||
SetLocalInt(oAmIDroppedLoot, "bDroppedItem", TRUE);
|
||||
SetLocalInt(oAmIDroppedLoot, "iDropTime", (GetCalendarYear() * iYr) + (GetCalendarMonth() * iMth) + (GetCalendarDay()* iDay) + (GetTimeHour()* iHr) + (GetTimeMinute() * iMin) + GetTimeSecond());
|
||||
}
|
||||
}
|
30
_module/nss/re_modulehb.nss
Normal file
30
_module/nss/re_modulehb.nss
Normal file
@@ -0,0 +1,30 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name re_modheartbeat.nss
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This script is part of the BESIE Random Encounter
|
||||
System by Ray Miller. It is meant to be placed in
|
||||
the Module OnHeartbeat Handler. It is used to run
|
||||
the CleanHouse() function on all areas in which PCs
|
||||
currently reside.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 1-6-03
|
||||
//:://////////////////////////////////////////////
|
||||
#include "re_rndenc"
|
||||
void main()
|
||||
{
|
||||
object oArea;
|
||||
object oPC = GetFirstPC();
|
||||
while(GetIsObjectValid(oPC))
|
||||
{
|
||||
oArea = GetArea(oPC);
|
||||
if(!GetIsObjectValid(GetLocalObject(oArea, "re_oHouseCleaner")))
|
||||
{
|
||||
CleanHouse(FALSE, oArea);
|
||||
}
|
||||
oPC = GetNextPC();
|
||||
}
|
||||
}
|
8
_module/nss/re_onactivate.nss
Normal file
8
_module/nss/re_onactivate.nss
Normal file
@@ -0,0 +1,8 @@
|
||||
void main()
|
||||
{
|
||||
//BESIE Widget
|
||||
if(GetTag(GetItemActivated()) == "BESIEWidget")
|
||||
{
|
||||
AssignCommand(GetItemActivator(), ActionStartConversation(GetItemActivator(), "re_widget", TRUE));
|
||||
}
|
||||
}
|
31
_module/nss/re_oncliententer.nss
Normal file
31
_module/nss/re_oncliententer.nss
Normal file
@@ -0,0 +1,31 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: FileName re_oncliententer.nss
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This is part of the BESIE Random Encounter System.
|
||||
It is intended to be placed in the module
|
||||
OnClientEnter handler. Its purpose is to set a
|
||||
local int on the DM so the he does not produce
|
||||
random encounters when possessing an NPC.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 10/14/02
|
||||
//:://////////////////////////////////////////////
|
||||
void main()
|
||||
{
|
||||
object oPC = GetEnteringObject();
|
||||
int bBESIEWidget;
|
||||
if(GetIsDM(oPC))
|
||||
{
|
||||
SetLocalInt(GetModule(), "re_" + GetPCPlayerName(oPC), TRUE);
|
||||
object oItem = GetFirstItemInInventory(oPC);
|
||||
while(GetIsObjectValid(oItem))
|
||||
{
|
||||
if(GetTag(oItem) == "BESIEWidget") bBESIEWidget = TRUE;
|
||||
oItem = GetNextItemInInventory(oPC);
|
||||
}
|
||||
if(!bBESIEWidget) CreateItemOnObject("besiewidget", oPC);
|
||||
}
|
||||
else DeleteLocalInt(GetModule(), "re_" + GetName(oPC));
|
||||
}
|
30
_module/nss/re_onload.nss
Normal file
30
_module/nss/re_onload.nss
Normal file
@@ -0,0 +1,30 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: FileName re_onload.nss
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This is the default OnLoad script for the BESIE
|
||||
Random Encounter system. This script is really just
|
||||
a template. The OnLoad handler is the best place
|
||||
to set the random encounter properties for the areas
|
||||
of your module.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 5/17/03
|
||||
//:://////////////////////////////////////////////
|
||||
#include"re_rndenc"
|
||||
void main()
|
||||
{
|
||||
//Notice that everything here matches the default settings of the SetRndEncProperties function except
|
||||
//the iChanceOnRest parameter, which is set to 0. The purpose of this statement is to make every area
|
||||
//of this module, that is not explicitley set, safe for resting.
|
||||
SetRndEncProperties(GetModule(), 4, TRUE, "re_ceghimpubt0", 180, 2, 4, FALSE, 0);
|
||||
|
||||
|
||||
//This sets the chance of a resting encounter in the area to 20 percent. Remember that when players
|
||||
//are resting it is because they are wounded and/or are low on resources. It is important not to set
|
||||
//the random encounter difficulty too high, especially in areas that are not safe for resting.
|
||||
// Repeat the following function call for each area that needs specific properties set.
|
||||
//SetRndEncProperties(GetObjectByTag("<Area tag goes here>"), 4, TRUE, "re_ceghimpubt0", 180, 2, 4, FALSE, 20);
|
||||
}
|
92
_module/nss/re_onrest.nss
Normal file
92
_module/nss/re_onrest.nss
Normal file
@@ -0,0 +1,92 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: FileName re_onrest.nss
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
If placed in the module OnPlayerRest handler, this
|
||||
script will generate a chance of a random encounter
|
||||
whenever a player rests. All of the parameters of
|
||||
this encounter are determined by the Random Encouter
|
||||
Properties placed on the Area object in which the
|
||||
player is resting, as set by the SetRndEncProperties()
|
||||
function. If no properties are set on the Area Object
|
||||
then the Module Object will be used. If none are set
|
||||
on the Module Object, the module object will be set
|
||||
with defaults and they will be used.
|
||||
|
||||
To make an area safe for resting encounters use 0
|
||||
for the iChanceOnRest Property of the
|
||||
SetRndEncProperties() function.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 1/6/03
|
||||
//:://////////////////////////////////////////////
|
||||
#include "re_rndenc"
|
||||
int GetTotalLevels(object oPC = OBJECT_SELF)
|
||||
{
|
||||
int iLevel = GetLevelByPosition(1, oPC) + GetLevelByPosition(2, oPC) + GetLevelByPosition(3, oPC);
|
||||
return iLevel;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
//////////////////////////////////////////////////
|
||||
//This should be set to the number of seconds that
|
||||
//players have to wait between rests.
|
||||
int iRestPeriod = 480
|
||||
;/////////////////////////////////////////////////
|
||||
//Set this to false to disable the darkness effect
|
||||
//when a PC rests.
|
||||
int iDark = TRUE
|
||||
;/////////////////////////////////////////////////
|
||||
|
||||
object oPC = GetLastPCRested();
|
||||
object oArea = GetArea(oPC);
|
||||
struct RndEncProperties strProps = GetRndEncProperties(oArea);
|
||||
if(!strProps.bInitialized) strProps = GetRndEncProperties(GetModule());
|
||||
if(!strProps.bInitialized)
|
||||
{
|
||||
SetRndEncProperties(GetModule());
|
||||
strProps = GetRndEncProperties(GetModule());
|
||||
}
|
||||
if(GetLastRestEventType() == REST_EVENTTYPE_REST_STARTED)
|
||||
{
|
||||
int iTimeSinceRest = GetTimeInSeconds() - GetLocalInt(oPC, "re_iLastRestTime");
|
||||
if(iTimeSinceRest < iRestPeriod)
|
||||
{
|
||||
int iMph;
|
||||
if(!GetLocalInt(GetModule(), "re_iMph")) iMph = 2;
|
||||
else iMph = GetLocalInt(GetModule(), "re_iMph");
|
||||
int iTimeLeft = iRestPeriod - iTimeSinceRest;
|
||||
int iInGameHours = iTimeLeft / 120;
|
||||
int iInGameMinutes = (iTimeLeft - (iInGameHours * 120)) / iMph;
|
||||
SendMessageToPC(oPC, "You may not rest for another " + IntToString(iInGameHours) + " hours " + IntToString(iInGameMinutes) + " minutes of game time.");
|
||||
AssignCommand(oPC, ClearAllActions());
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLocalInt(oPC, "re_resting", TRUE);
|
||||
SetLocalInt(oPC, "re_iLastRestTime", GetTimeInSeconds());
|
||||
|
||||
//Apply visual effects to resting PC
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SLEEP), oPC);
|
||||
if(iDark) ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBlindness(), oPC, 7.0 + IntToFloat(GetTotalLevels(oPC)) / 2.5);
|
||||
|
||||
float fDelay = IntToFloat(Random(8 + FloatToInt(IntToFloat(GetTotalLevels(oPC)) / 2.5))+1);
|
||||
DelayCommand(fDelay, ExecuteScript("re_or", oPC));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DeleteLocalInt(oPC, "re_resting");
|
||||
effect eEffect = GetFirstEffect(oPC);
|
||||
while(GetIsEffectValid(eEffect))
|
||||
{
|
||||
if(GetEffectType(eEffect) == EFFECT_TYPE_BLINDNESS && GetEffectCreator(eEffect) == GetModule()) RemoveEffect(oPC, eEffect);
|
||||
if(GetEffectType(eEffect) == VFX_IMP_SLEEP && GetEffectCreator(eEffect) == GetModule()) RemoveEffect(oPC, eEffect);
|
||||
eEffect = GetNextEffect(oPC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
38
_module/nss/re_onunacquire.nss
Normal file
38
_module/nss/re_onunacquire.nss
Normal file
@@ -0,0 +1,38 @@
|
||||
//:://////////////////////////////////////////////
|
||||
//:: FileName re_moditemdrop.nss
|
||||
//:: Copyright (c) 2002 Ray Miller
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Note: This script goes in the OnUnAcquired
|
||||
handler for the module object and is used to
|
||||
stamp dropped items with a local time variable
|
||||
for use with the "CleanHouse()" function of the
|
||||
BESIE Random Encounter Package by Ray Miller.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 7/6/2002
|
||||
//:://////////////////////////////////////////////
|
||||
void main()
|
||||
{
|
||||
int iMph;
|
||||
if(!GetLocalInt(GetModule(), "re_iMph"))
|
||||
{
|
||||
iMph = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
iMph = GetLocalInt(GetModule(), "re_iMph");
|
||||
}
|
||||
int iMin = 60;
|
||||
int iHr = iMin * iMph;
|
||||
int iDay = iHr * 24;
|
||||
int iMth = iDay * 28;
|
||||
int iYr = iMth * 12;
|
||||
object oAmIDroppedLoot = GetModuleItemLost();
|
||||
if(GetIsObjectValid(oAmIDroppedLoot))
|
||||
{
|
||||
SetLocalInt(oAmIDroppedLoot, "re_bDroppedItem", TRUE);
|
||||
SetLocalInt(oAmIDroppedLoot, "re_iDropTime", (GetCalendarYear() * iYr) + (GetCalendarMonth() * iMth) + (GetCalendarDay()* iDay) + (GetTimeHour()* iHr) + (GetTimeMinute() * iMin) + GetTimeSecond());
|
||||
}
|
||||
}
|
59
_module/nss/re_or.nss
Normal file
59
_module/nss/re_or.nss
Normal file
@@ -0,0 +1,59 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name re_or.nss
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This script is intended to be executed by
|
||||
"re_onrest". It should not be executed alone
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 1-6-03
|
||||
//:://////////////////////////////////////////////
|
||||
#include "re_rndenc"
|
||||
void main()
|
||||
{
|
||||
object oPC = OBJECT_SELF;
|
||||
if(GetLocalInt(oPC, "re_resting"))
|
||||
{
|
||||
object oArea = GetArea(oPC);
|
||||
int iMinDistance = 1;
|
||||
int iMaxDistance = 5;
|
||||
struct RndEncProperties strProps = GetRndEncProperties(oArea);
|
||||
if(!strProps.bInitialized) strProps = GetRndEncProperties(GetModule());
|
||||
if(!strProps.bInitialized)
|
||||
{
|
||||
SetRndEncProperties(GetModule());
|
||||
strProps = GetRndEncProperties(GetModule());
|
||||
}
|
||||
//If a friendly creature is awake and within 20 meters, then increase
|
||||
//the distance at which the encounter can spawn.
|
||||
int iCounter1 = 1;
|
||||
object oPlayer = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oPC, iCounter1);
|
||||
while(GetIsObjectValid(oPlayer) && GetDistanceToObject(oPlayer) <= 20.0)
|
||||
{
|
||||
iCounter1++;
|
||||
if(GetIsFriend(oPlayer, oPC))
|
||||
{
|
||||
iMinDistance = 6;
|
||||
iMaxDistance = 12;
|
||||
}
|
||||
oPlayer = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oPC, iCounter1);
|
||||
}
|
||||
//The purpose of the following local int is to cause the spawns
|
||||
//to be facing the PC who generated the encounter.
|
||||
SetLocalInt(oPC, "re_Facing", TRUE);
|
||||
|
||||
object oEncounter = RandomEncounter(IntToFloat(strProps.iChanceOnRest), oPC, strProps.sCreatureTable, 0, 0, iMinDistance, iMaxDistance, 360, 0, 0, 0, strProps.iDifficulty);
|
||||
/*if(GetIsObjectValid(oEncounter))
|
||||
{
|
||||
//DeleteLocalInt(oPC, "re_resting");
|
||||
effect eEffect = GetFirstEffect(oPC);
|
||||
while(GetIsEffectValid(eEffect))
|
||||
{
|
||||
if(GetEffectType(eEffect) == EFFECT_TYPE_BLINDNESS && GetEffectCreator(eEffect) == GetModule()) RemoveEffect(oPC, eEffect);
|
||||
eEffect = GetNextEffect(oPC);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
44
_module/nss/re_placespawnhb.nss
Normal file
44
_module/nss/re_placespawnhb.nss
Normal file
@@ -0,0 +1,44 @@
|
||||
void main()
|
||||
{
|
||||
if(!GetLocalInt(OBJECT_SELF, "re_BESIE"))
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, "re_BESIE", TRUE);
|
||||
SetLocalString(OBJECT_SELF, "re_ToolType", "Placeable Spawner");
|
||||
}
|
||||
if(GetLocalInt(GetModule(), "re_disablePlaceableSpawner") || GetLocalInt(GetArea(OBJECT_SELF), "re_disablePlaceableSpawner") || GetLocalInt(OBJECT_SELF, "re_disable")) return;
|
||||
int iStartTime = GetFortitudeSavingThrow(OBJECT_SELF);
|
||||
int iStopTime = GetReflexSavingThrow(OBJECT_SELF);
|
||||
int iID = GetWillSavingThrow(OBJECT_SELF);
|
||||
int iChanceOfSpawn = GetMaxHitPoints(OBJECT_SELF);
|
||||
int iHappens = Random(10000) + 1;
|
||||
object oObject;
|
||||
string sTemplate = GetTag(OBJECT_SELF);
|
||||
if(!GetLocalInt(OBJECT_SELF, "re_bFirstRun"))
|
||||
{
|
||||
iHappens = 0;
|
||||
SetLocalInt(OBJECT_SELF, "re_bFirstRun", TRUE);
|
||||
}
|
||||
if(iStartTime > 23) iStartTime = 23;
|
||||
if(iStopTime > 23) iStopTime = 23;
|
||||
if((iStartTime <= iStopTime && (GetTimeHour() >= iStartTime && GetTimeHour() < iStopTime))
|
||||
|| (iStartTime >= iStopTime && (GetTimeHour() >= iStartTime || GetTimeHour() < iStopTime)))
|
||||
{
|
||||
if(!GetIsObjectValid(GetLocalObject(OBJECT_SELF, "re_oObject")))
|
||||
{
|
||||
if(iChanceOfSpawn >= iHappens)
|
||||
{
|
||||
oObject = CreateObject(OBJECT_TYPE_PLACEABLE, sTemplate, GetLocation(OBJECT_SELF));
|
||||
SetLocalInt(oObject, "re_iID", iID);
|
||||
SetLocalObject(OBJECT_SELF, "re_oObject", oObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GetIsObjectValid(GetLocalObject(OBJECT_SELF, "re_oObject")))
|
||||
{
|
||||
DestroyObject(GetLocalObject(OBJECT_SELF, "re_oObject"));
|
||||
DeleteLocalObject(OBJECT_SELF, "re_oObject");
|
||||
}
|
||||
}
|
||||
}
|
235
_module/nss/re_pwrespawnerhb.nss
Normal file
235
_module/nss/re_pwrespawnerhb.nss
Normal file
@@ -0,0 +1,235 @@
|
||||
//:://///////////////////////////////////////////////////////////////
|
||||
//:: FileName re_spawnerhb
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://///////////////////////////////////////////////////////////////
|
||||
/*
|
||||
This script is used in the heartbeat of the
|
||||
BESIE Persistent World Respawner tool, part
|
||||
of the BESIE Random Encounter System.
|
||||
*/
|
||||
//:://///////////////////////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 3-30-03
|
||||
//:://///////////////////////////////////////////////////////////////
|
||||
|
||||
#include "re_rndenc"
|
||||
|
||||
void main()
|
||||
{
|
||||
// DEFINE VARIABLES
|
||||
if(!GetLocalInt(OBJECT_SELF, "re_BESIE"))
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, "re_BESIE", TRUE);
|
||||
SetLocalString(OBJECT_SELF, "re_ToolType", "PW Respawner");
|
||||
}
|
||||
if(GetLocalInt(GetModule(), "re_disablePWRespawner") || GetLocalInt(GetArea(OBJECT_SELF), "re_disablePWRespawner") || GetLocalInt(OBJECT_SELF, "re_disable"))
|
||||
{
|
||||
if(!GetIsObjectValid(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner"))) SetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner", OBJECT_SELF);
|
||||
if(GetLocalObject(GetArea(OBJECT_SELF), "re_oHouseCleaner") == OBJECT_SELF) CleanHouse();
|
||||
return;
|
||||
}
|
||||
int iRespawnTime = GetReflexSavingThrow(OBJECT_SELF);
|
||||
int iLevel = GetFortitudeSavingThrow(OBJECT_SELF);
|
||||
int iSpawnerNumber = GetWillSavingThrow(OBJECT_SELF);
|
||||
int iCounter1;
|
||||
int iCounter2 = 1;
|
||||
int iCounter3;
|
||||
float fChanceOfEncounter = IntToFloat(GetMaxHitPoints(OBJECT_SELF)) / 100;
|
||||
string sTemplate = GetTag(OBJECT_SELF);
|
||||
string sMatchString;
|
||||
object oArea = GetArea(OBJECT_SELF);
|
||||
object oCreature;
|
||||
object oSpawner;
|
||||
if(iSpawnerNumber > 99) iSpawnerNumber = 99;
|
||||
if(iSpawnerNumber < 10) sMatchString = "PWS0" + IntToString(iSpawnerNumber);
|
||||
else sMatchString = "PWS" + IntToString(iSpawnerNumber);
|
||||
|
||||
// IF THIS IS THE FIRST RUN THEN INITIALIZE EACH SPAWN POINT BY PARSING THE TAG FOR SWITCHES AND SETTING
|
||||
// LOCAL VARIABLES.
|
||||
if(!GetLocalInt(OBJECT_SELF, "re_bFirstRun"))
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, "re_bFirstRun", TRUE);
|
||||
SetLocalInt(OBJECT_SELF, "re_bSpawnNow", TRUE);
|
||||
fChanceOfEncounter = 100.00;
|
||||
object oObject = GetFirstObjectInArea(oArea);
|
||||
string sCustom = "nil";
|
||||
string sBuild;
|
||||
while(GetIsObjectValid(oObject))
|
||||
{
|
||||
if(GetStringLeft(GetTag(oObject), 5) == sMatchString)
|
||||
{
|
||||
iCounter1++;
|
||||
SetLocalObject(OBJECT_SELF, "re_oPWWaypoint" + IntToString(iCounter1), oObject);
|
||||
for(iCounter3 = 5; iCounter3 <= GetStringLength(GetTag(oObject)); iCounter3++)
|
||||
{
|
||||
if(sCustom != "nil"
|
||||
&& (GetSubString(GetTag(oObject), iCounter3, 1) == "0" || StringToInt(GetSubString(GetTag(oObject), iCounter3, 1)) > 0))
|
||||
{
|
||||
sBuild = sBuild + GetSubString(GetTag(oObject), iCounter3, 1);
|
||||
}
|
||||
else if(sCustom != "nil")
|
||||
{
|
||||
if(sCustom == "s") SetLocalInt(oObject, "re_bSwitch" + sBuild, TRUE);
|
||||
if(sCustom == "b")
|
||||
{
|
||||
int iBegin = StringToInt(sBuild);
|
||||
if(iBegin > 23) iBegin = 23;
|
||||
if(iBegin < 0) iBegin = 0; //Don't think this is necessary, but... safety first!
|
||||
SetLocalInt(oObject, "re_iBegin", iBegin);
|
||||
}
|
||||
if(sCustom == "e")
|
||||
{
|
||||
int iEnd = StringToInt(sBuild);
|
||||
if(iEnd > 23) iEnd = 23;
|
||||
if(iEnd < 0) iEnd = 0;
|
||||
SetLocalInt(oObject, "re_iEnd", iEnd);
|
||||
}
|
||||
if(sCustom == "t")
|
||||
{
|
||||
SetLocalInt(oObject, "re_iTerritory", StringToInt(sBuild));
|
||||
if(GetLocalInt(oObject, "re_iTerritory") < 30) SetLocalInt(oObject, "re_iTerritory", 30);
|
||||
}
|
||||
sCustom = "nil";
|
||||
sBuild = "";
|
||||
}
|
||||
if(GetSubString(GetTag(oObject), iCounter3, 1) == "s"
|
||||
|| GetSubString(GetTag(oObject), iCounter3, 1) == "t"
|
||||
|| GetSubString(GetTag(oObject), iCounter3, 1) == "b"
|
||||
|| GetSubString(GetTag(oObject), iCounter3, 1) == "e")
|
||||
{
|
||||
sCustom = GetSubString(GetTag(oObject), iCounter3, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
oObject = GetNextObjectInArea(oArea);
|
||||
}
|
||||
SetLocalInt(OBJECT_SELF, "re_iTotalSpawnpoints", iCounter1);
|
||||
}
|
||||
|
||||
// CYCLE THROUGH THE SPAWN POINTS.
|
||||
for(iCounter2 = 1; iCounter2 <= GetLocalInt(OBJECT_SELF, "re_iTotalSpawnpoints"); iCounter2++)
|
||||
{
|
||||
oSpawner = GetLocalObject(OBJECT_SELF, "re_oPWWaypoint" + IntToString(iCounter2));
|
||||
oCreature = GetLocalObject(oSpawner, "re_oLastRandomEncounterSpawned");
|
||||
int bTimeIn = TRUE;
|
||||
struct RndEncProperties stEncProperties = GetRndEncProperties(oSpawner);
|
||||
if(!stEncProperties.bInitialized) stEncProperties = GetRndEncProperties(GetArea(OBJECT_SELF));
|
||||
if(!stEncProperties.bInitialized) stEncProperties = GetRndEncProperties(GetModule());
|
||||
if(!iLevel) SetRndEncProperties(oSpawner, stEncProperties.iDifficulty, FALSE, stEncProperties.sCreatureTable, stEncProperties.iLifeTime, stEncProperties.iMph, stEncProperties.iEncounterType, stEncProperties.bConflict, stEncProperties.iChanceOnRest, stEncProperties.bLOSCheck);
|
||||
else SetRndEncProperties(oSpawner, stEncProperties.iDifficulty, TRUE, stEncProperties.sCreatureTable, stEncProperties.iLifeTime, stEncProperties.iMph, stEncProperties.iEncounterType, stEncProperties.bConflict, stEncProperties.iChanceOnRest, stEncProperties.bLOSCheck);
|
||||
if(GetLocalInt(oSpawner, "re_iBegin") || GetLocalInt(oSpawner, "re_iEnd"))
|
||||
{
|
||||
int iStartTime = GetLocalInt(oSpawner, "re_iBegin");
|
||||
int iStopTime = GetLocalInt(oSpawner, "re_iEnd");
|
||||
if((iStartTime <= iStopTime && (GetTimeHour() >= iStartTime && GetTimeHour() < iStopTime))
|
||||
|| (iStartTime >= iStopTime && (GetTimeHour() >= iStartTime || GetTimeHour() < iStopTime)))
|
||||
bTimeIn = TRUE;
|
||||
else bTimeIn = FALSE;
|
||||
}
|
||||
if(GetLocalInt(oSpawner, "re_bDay"))
|
||||
{
|
||||
if(GetIsDusk() || GetIsNight())
|
||||
{
|
||||
DeleteLocalInt(oSpawner, "re_bDay");
|
||||
if(GetLocalInt(oSpawner, "re_bSwitch6")) fChanceOfEncounter = 100.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GetIsDawn() || GetIsDay())
|
||||
{
|
||||
SetLocalInt(oSpawner, "re_bDay", TRUE);
|
||||
if(GetLocalInt(oSpawner, "re_bSwitch5")) fChanceOfEncounter = 100.0;
|
||||
}
|
||||
}
|
||||
// If the creature is dead or not valid then attempt to spawn him.
|
||||
if(!GetIsObjectValid(oCreature) || GetIsDead(oCreature))
|
||||
{
|
||||
if(!GetLocalInt(oSpawner, "re_TimeOfDeath")) SetLocalInt(oSpawner, "re_TimeOfDeath", GetTimeInSeconds());
|
||||
if((GetTimeInSeconds() - GetLocalInt(oSpawner, "re_TimeOfDeath")) / 60 >= iRespawnTime || GetLocalInt(OBJECT_SELF, "re_bSpawnNow"))
|
||||
{
|
||||
if((!GetLocalInt(oSpawner, "re_bSwitch5") && !GetLocalInt(oSpawner, "re_bSwitch6") && bTimeIn)
|
||||
|| (GetLocalInt(oSpawner, "re_bSwitch5") && (GetIsDawn() || GetIsDay()) && bTimeIn)
|
||||
|| (GetLocalInt(oSpawner, "re_bSwitch6") && (GetIsDusk() || GetIsNight()) && bTimeIn))
|
||||
{
|
||||
oCreature = RandomEncounter(fChanceOfEncounter, oSpawner, sTemplate, 0, 1, 0, 0, 0, 0, 0, iLevel, 5);
|
||||
if(GetIsObjectValid(oCreature))
|
||||
{
|
||||
if(GetLocalInt(oSpawner, "re_bSwitch2")) AssignCommand(oCreature, ActionRandomWalk());
|
||||
if(GetLocalInt(oSpawner, "re_bSwitch3")) AssignCommand(oCreature, ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0, 4000.0));
|
||||
AssignCommand(oCreature, SetFacing(GetFacing(oSpawner)));
|
||||
DeleteLocalInt(oSpawner, "re_TimeOfDeath");
|
||||
DeleteLocalInt(oCreature, "re_bRandomEncounter"); //This is so this creature isn't destroyed by the CleanHouse() function
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
location lLocation = GetLocation(oSpawner);
|
||||
location lCreature = GetLocation(oCreature);
|
||||
vector vLocation = GetPositionFromLocation(lLocation);
|
||||
vector vCreature = GetPositionFromLocation(lCreature);
|
||||
object oAttacker = GetLastHostileActor(oCreature);
|
||||
location lAttacker = GetLocation(oAttacker);
|
||||
|
||||
// Send the creature home if the territory switch is set and the creature is out of his territory
|
||||
// and not in combat and not DM controlled.
|
||||
if(GetLocalInt(oSpawner, "re_iTerritory") && GetDistanceBetweenLocations(lLocation, lCreature) > IntToFloat(GetLocalInt(oSpawner, "re_iTerritory")))
|
||||
{
|
||||
if(!GetIsObjectValid(oAttacker)
|
||||
|| (!GetIsInCombat(oAttacker) && !GetIsPC(oCreature) && GetDistanceBetweenLocations(lLocation, lAttacker) > IntToFloat(GetLocalInt(oSpawner, "re_iTerritory"))))
|
||||
{
|
||||
AssignCommand(oCreature, ClearAllActions());
|
||||
AssignCommand(oCreature, JumpToLocation(lLocation));
|
||||
AssignCommand(oCreature, SetFacing(GetFacing(oSpawner)));
|
||||
}
|
||||
}
|
||||
|
||||
// Things to do if creature is valid, alive, not in combat, and not DM controlled.
|
||||
if(!GetIsInCombat(oCreature) && !GetIsPC(oCreature))
|
||||
{
|
||||
float fDamage = IntToFloat(GetMaxHitPoints(oCreature) - GetCurrentHitPoints(oCreature)) / 5.0;
|
||||
if(fDamage < 1.0 && fDamage > 0.0) fDamage = 1.0;
|
||||
int iDamage = FloatToInt(fDamage);
|
||||
if(GetLocalInt(oSpawner, "re_bSwitch5") && (GetIsDusk() || GetIsNight())
|
||||
|| GetLocalInt(oSpawner, "re_bSwitch6") && (GetIsDawn() || GetIsDay())
|
||||
|| !bTimeIn)
|
||||
{
|
||||
DestroyObject(oCreature);
|
||||
}
|
||||
if(vLocation.x != vCreature.x || vLocation.y != vCreature.y || GetFacing(oCreature) != GetFacing(oSpawner))
|
||||
{
|
||||
if(!GetLocalInt(oSpawner, "re_bSwitch1"))
|
||||
{
|
||||
if(!GetLocalInt(oSpawner, "re_bSwitch2") || GetDistanceBetweenLocations(lLocation, lCreature) >= 15.0)
|
||||
{
|
||||
//AssignCommand(oCreature, ClearAllActions());
|
||||
if(GetLocalInt(oSpawner, "re_iTerritory")) AssignCommand(oCreature, ActionMoveToLocation(lLocation));
|
||||
else AssignCommand(oCreature, ActionMoveToLocation(lLocation));
|
||||
AssignCommand(oCreature, ActionDoCommand(SetFacing(GetFacing(oSpawner))));
|
||||
if(GetLocalInt(oSpawner, "re_bSwitch3")) AssignCommand(oCreature, ActionDoCommand(PlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0, 4000.0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(lLocation == lCreature && GetFacing(oCreature) != GetFacing(oSpawner)) AssignCommand(oCreature, ActionDoCommand(SetFacing(GetFacing(oSpawner))));
|
||||
if(!GetLocalInt(oSpawner, "re_bSwitch4") && iDamage) ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(iDamage), oCreature);
|
||||
if(GetLocalInt(oSpawner, "re_bSwitch2")) AssignCommand(oCreature, ActionDoCommand(ActionRandomWalk()));
|
||||
if(GetLocalInt(oSpawner, "re_bSwitch3"))
|
||||
{
|
||||
if(GetLocalInt(oSpawner, "re_bSwitch1"))
|
||||
{
|
||||
AssignCommand(oCreature, ClearAllActions());
|
||||
AssignCommand(oCreature, PlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0, 4000.0));
|
||||
}
|
||||
else if(lLocation == lCreature)
|
||||
{
|
||||
AssignCommand(oCreature, ClearAllActions());
|
||||
AssignCommand(oCreature, PlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0, 4000.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(GetLocalInt(OBJECT_SELF, "re_bSpawnNow")) DeleteLocalInt(OBJECT_SELF, "re_bSpawnNow");
|
||||
}
|
896
_module/nss/re_rndenc.nss
Normal file
896
_module/nss/re_rndenc.nss
Normal file
@@ -0,0 +1,896 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name re_rndenc
|
||||
//:: FileName re_rndenc.nss
|
||||
//:: Copyright (c) 2002 Raymond Miller
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This script creates functions called RandomEncounter(),
|
||||
CleanHouse(), and SetRndEncProperties() for use in the NWN
|
||||
scripting language. This script is meant to be used as an #include
|
||||
and is part of the BESIE Random Encounter package by Ray Miller
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Ray Miller
|
||||
//:: Created On: 7/6/2002
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
// Encounter Type Constants
|
||||
int ENCOUNTER_TYPE_AREA = 3;
|
||||
int ENCOUNTER_TYPE_PARTY = 1;
|
||||
int ENCOUNTER_TYPE_IND = 2;
|
||||
int ENCOUNTER_TYPE_TOTALPARTYLEVELS = 4;
|
||||
|
||||
struct RndEncProperties
|
||||
{
|
||||
int bInitialized;
|
||||
int iDifficulty;
|
||||
int bConsiderCR;
|
||||
string sCreatureTable;
|
||||
int iLifeTime;
|
||||
int iMph;
|
||||
int iEncounterType;
|
||||
int bConflict;
|
||||
int iChanceOnRest;
|
||||
int bLOSCheck;
|
||||
};
|
||||
|
||||
// FUNCTION DECLARATIONS
|
||||
|
||||
// Sets properties for random encounters that are likely to seldom change
|
||||
// - oObject: The object that holds these properties.
|
||||
// - iDifficulty: 1 to 10
|
||||
// - bConsiderCR: If TRUE takes CR of creature into consideration when
|
||||
// choosing an encounter.
|
||||
// - sCreatureTable: "re_***" - where *** is a string of letter and/or numbers to indicate to the function what type
|
||||
// of creatures to spawn. They are as follows:
|
||||
// a - animals
|
||||
// c - construct
|
||||
// d - dragon
|
||||
// e - elemental
|
||||
// g - giant
|
||||
// h - humanoid
|
||||
// i - insect
|
||||
// m - miscellaneous
|
||||
// p - planar
|
||||
// u - undead
|
||||
// b - bandit
|
||||
// x1 through x### - These are for custom encounter tables.
|
||||
// t1 through t### - These are for treasure tables.
|
||||
// - iLifeTime: Time in seconds before unengaged encounters decay.
|
||||
// - Mph: Should equal the Minutes Per Hour setting of the Module.
|
||||
// - iEncounterType:
|
||||
// ENCOUNTER_TYPE_PARTY - Takes into consideration the average level of the entire party of the PC who is to
|
||||
// receive the encounter when choosing an encounter of appropriate difficulty level.
|
||||
// ENCOUNTER_TYPE_TOTALPARTYLEVELS (default) - Takes into consideration the TOTAL of all the levels of the PC's party who
|
||||
// currently reside in the same area as the PC to receive the encounter.
|
||||
// ENCOUNTER_TYPE_AREA - Takes into consideration the levels off all PCs and henchmen within a 20m radius of the PC
|
||||
// who is to receive the encounter.
|
||||
// ENCOUNTER_TYPE_IND - Takes into consideration only the levels of the individual PC who is to receive the encounter.
|
||||
// - bConflict: If set to TRUE then random encounters can occur during combat.
|
||||
// - iChanceOnRest: The chance of a random encounter occuring when a PC rests (only matters on Area Object and the "re_onrest"
|
||||
// script must be placed in PlayerOnRest handler of the module object).
|
||||
// - bLOSCheck: Dependant upon a broken scripting function. (future use!)
|
||||
// Note: This function is best called by the OnModuleLoad or OnAreaLoad handler.
|
||||
void SetRndEncProperties(object oObject = OBJECT_SELF, int iDifficulty = 4, int bConsiderCR = TRUE, string sCreatureTable = "re_ceghimpubt0", int iLifeTime = 180, int iMph = 2, int iEncounterType = 4, int bConflict = FALSE, int iChanceOnRest = 20, int bLOSCheck = FALSE);
|
||||
|
||||
// Returns the structure "RndEncProperties" containing all the Random Encounter Properties set on oObject.
|
||||
// The elements of the structure are as follows:
|
||||
// - bInitialized: TRUE if properties have been set on this object.
|
||||
// - iDifficulty: 1 to 10
|
||||
// - bConsiderCR: If TRUE, takes CR of creature into consideration when
|
||||
// choosing an encounter.
|
||||
// - sCreatureTable: "re_***" - where *** is a string of letter and/or numbers to indicate to the function what type
|
||||
// of creatures to spawn. They are as follows:
|
||||
// a - animals
|
||||
// c - construct
|
||||
// d - dragon
|
||||
// e - elemental
|
||||
// g - giant
|
||||
// h - humanoid
|
||||
// i - insect
|
||||
// m - miscellaneous
|
||||
// p - planar
|
||||
// u - undead
|
||||
// b - bandit
|
||||
// x1 through x### - These are for custom encounter tables.
|
||||
// t1 through t### - These are for treasure tables.
|
||||
// - iLifeTime: Time in seconds before unengaged encounters decay.
|
||||
// - iMph: Should equal the Minutes Per Hour setting of the Module.
|
||||
// - iEncounterType:
|
||||
// ENCOUNTER_TYPE_PARTY - Takes into consideration the average level of the entire party of the PC who is to
|
||||
// receive the encounter when choosing an encounter of appropriate difficulty level.
|
||||
// ENCOUNTER_TYPE_TOTALPARTYLEVELS (default) - Takes into consideration the TOTAL of all the levels of the PC's party who
|
||||
// currently reside in the same area as the PC to receive the encounter.
|
||||
// ENCOUNTER_TYPE_AREA - Takes into consideration the levels off all PCs and henchmen within a 20m radius of the PC
|
||||
// who is to receive the encounter.
|
||||
// ENCOUNTER_TYPE_IND - Takes into consideration only the levels of the individual PC who is to receive the encounter.
|
||||
// - bConflict: If TRUE then random encounters can occur during combat.
|
||||
// - iChanceOnRest: The chance of a random encounter occuring when a PC rests (only matters on Area Object and the "re_onrest"
|
||||
// script must be placed in PlayerOnRest handler of the module object).
|
||||
// - bLOSCheck: Dependant upon a broken scripting function. (future use!)
|
||||
struct RndEncProperties GetRndEncProperties(object oObject);
|
||||
|
||||
// Generates the likelihood of a random encounter.
|
||||
// - fChanceOfEncounter: Odds of encounter spawning when funciton is called. Accurate to two
|
||||
// decimal places. .01 to 100.00 percent chance.
|
||||
// - oEncounterObject: The object about which the encounter will spawn, whose levels (if a player)
|
||||
// will be considered when determining an appropriate creature.
|
||||
// - sTemplate: When used as the sCreatureTable parameter in the SetRndEncProperties()
|
||||
// function this parameter has higher priority. It can also be set to the tag of a
|
||||
// specific creature, or to "random" to use the default table set by SetRndEncProperties()
|
||||
// - iMinNumberOfCreatures: If > 0, a random number of creatures between this and iMaxNumberOfCreatures
|
||||
// will spawn. If set to 0, then exactly the number of creatures set by iMaxNumberOfCreatures will
|
||||
// spawn.
|
||||
// - iMaxNumberOfCreatures: If this and iMinNumberOfCreatures is set to 0 then the number of Creatures
|
||||
// spawned will be determined by the CR of the creature spawned compared to the levels of the player(s).
|
||||
// - iMinEncounterDistance: If set to 0, encounter distance will always be at the number set by iMaxEncounterDistance.
|
||||
// - iMaxEncounterDistance: Farthest distance the encounter can be from oEncounterObject.
|
||||
// - iOrientation: 0 to 360. Counterclockwise representing the angle from facing where the encounter will spawn.
|
||||
// a value of 0 will spawn the encounter directly in front of oEncounterObject. 360 will generate a random angle.
|
||||
// - iTolerance: The number of degrees by which the angle can randomly be off from iOrientation.
|
||||
// - iCheckDistance: The distance a PC has to move before a Random Encounter check can be made against him. If the PC has
|
||||
// not covered this much distance, then a call to the RandomEncounter() function for this PC will yield
|
||||
// OBJECT_INVALID.
|
||||
// - iLevelOverride: Use this to force the function to base the encounter on a character level other than that
|
||||
// determined by oEncounterObject.
|
||||
// - iDifficulty: Overrides the difficulty setting determined by the SetRndEncProperties() function.
|
||||
object RandomEncounter(float fChanceOfEncounter = 100.0, object oEncounterObject = OBJECT_SELF, string sTemplate = "random", int iMinNumberOfCreatures = 0, int iMaxNumberOfCreatures = 0, int iMinEncounterDistance = 1, int iMaxEncounterDistance = 15, int iOrientation = 360, int iTolerance = 0, int iCheckDistance = 0, int iLevelOverride = 0, int iDifficulty = 0);
|
||||
|
||||
// Used to "clean up" an area that has become littered by random encounters.
|
||||
// - bDestroyPlotItems - Tells the function whether or not to destroy items with their plot flags set. If set to TRUE,
|
||||
// plot items will be destroyed just like any other item.
|
||||
// - oArea - The area to clean up.
|
||||
// - iSpawnOverride - Overrides the default (set by the SetRndEncProperties() function) time to destroy random encounter
|
||||
// creatures who are not engaged by PCs.
|
||||
// - iItemOverride - Overrides the default time of 30 minutes after which to destroy items dropped by PCs
|
||||
// Note: Only works if the "re_moditemdrop" script included with the BESIE Random Encounter package
|
||||
// is placed in the module OnItemUnacquire handler.
|
||||
// - iBodyBagOverride - Overrides the default time of 5 minutes after which to destroy loot that was dropped by creatures
|
||||
// who were killed.
|
||||
// NOTE: If there is bDestroyPlotItems is FALSE and there is a plot item or items inside a container or body bag, the container
|
||||
// and all non-plot items will decay but the plot item(s) will be left.
|
||||
// NOTE: A value of zero assigned to the override parameters will cause the function to use the default value for that parameter.
|
||||
void CleanHouse(int bDestroyPlotItems = FALSE, object oArea = OBJECT_SELF, int iSpawnOverride = 0, int iItemOverride = 0, int iBodyBagOverride = 0);
|
||||
|
||||
// Returns the game's calander time in seconds since time zero.
|
||||
// - iMph: Minutes Per Hour. This should match the module's setting.
|
||||
int GetTimeInSeconds(int iMph = 2);
|
||||
|
||||
// Causes oCreature to walk to a randomly determined location.
|
||||
// - lCenter: The center of a circle in which random destinations can be generated.
|
||||
// - iDistance: The distance from lCenter in which to randomly generate destinations.
|
||||
// - oCreature: The creature to perform the random walk.
|
||||
// Note: Unlike the default RandomWalk function, this function does not persist until a ClearAllActions is called. Instead this
|
||||
// function generates a single random desitination and the move to that destination is added to the creatures action que only once
|
||||
// per call.
|
||||
location RandomWalk2(location lCenter, int iDistance = 20, object oCreature = OBJECT_SELF);
|
||||
|
||||
void SetRndEncProperties(object oObject = OBJECT_SELF, int iDifficulty = 4, int bConsiderCR = TRUE, string sCreatureTable = "re_ceghimpubt0", int iLifeTime = 180, int iMph = 2, int iEncounterType = 4, int bConflict = TRUE, int iChanceOnRest = 20, int bLOSCheck = FALSE)
|
||||
{
|
||||
SetLocalInt(oObject, "re_bInitialized", TRUE);
|
||||
SetLocalInt(oObject, "re_iDifficulty", iDifficulty);
|
||||
SetLocalInt(oObject, "re_bConsiderCR", bConsiderCR);
|
||||
SetLocalString(oObject, "re_sCreatureTable", sCreatureTable);
|
||||
SetLocalInt(oObject, "re_iLifeTime", iLifeTime);
|
||||
SetLocalInt(oObject, "re_iMph", iMph);
|
||||
SetLocalInt(oObject, "re_iEncounterType", iEncounterType);
|
||||
SetLocalInt(oObject, "re_bConflict", bConflict);
|
||||
SetLocalInt(oObject, "re_iChanceOnRest", iChanceOnRest);
|
||||
SetLocalInt(oObject, "re_bLOSCheck", bLOSCheck);
|
||||
}
|
||||
|
||||
struct RndEncProperties GetRndEncProperties(object oObject = OBJECT_SELF)
|
||||
{
|
||||
if(oObject == GetModule() && !GetLocalInt(GetModule(), "re_bInitialized")) SetRndEncProperties(GetModule());
|
||||
struct RndEncProperties strProps;
|
||||
strProps.bInitialized = GetLocalInt(oObject, "re_bInitialized");
|
||||
strProps.iDifficulty = GetLocalInt(oObject, "re_iDifficulty");
|
||||
strProps.bConsiderCR = GetLocalInt(oObject, "re_bConsiderCR");
|
||||
strProps.sCreatureTable = GetLocalString(oObject, "re_sCreatureTable");
|
||||
strProps.iLifeTime = GetLocalInt(oObject, "re_iLifeTime");
|
||||
strProps.iMph = GetLocalInt(oObject, "re_iMph");
|
||||
strProps.iEncounterType = GetLocalInt(oObject, "re_iEncounterType");
|
||||
strProps.bConflict = GetLocalInt(oObject, "re_bConflict");
|
||||
strProps.iChanceOnRest = GetLocalInt(oObject, "re_iChanceOnRest");
|
||||
strProps.bLOSCheck = GetLocalInt(oObject, "re_bLOSCheck");
|
||||
return strProps;
|
||||
}
|
||||
|
||||
#include "re_table"
|
||||
object RandomEncounter(float fChanceOfEncounter = 100.0, object oEncounterObject = OBJECT_SELF, string sTemplate = "random", int iMinNumberOfCreatures = 0, int iMaxNumberOfCreatures = 0, int iMinEncounterDistance = 1, int iMaxEncounterDistance = 15, int iOrientation = 360, int iTolerance = 0, int iCheckDistance = 0, int iLevelOverride = 0, int iDifficulty = 0)
|
||||
{
|
||||
// IF PROPERTIES ARE NOT SET ON MODULE OBJECT THEN SET THEM WITH DEFAULTS
|
||||
if(!GetLocalInt(GetModule(), "re_bInitialized"))
|
||||
{
|
||||
SetRndEncProperties(GetModule());
|
||||
}
|
||||
|
||||
// DETERMINE IF ENCOUNTER HAPPENS
|
||||
//Has the player moved farther than the CheckDistance?
|
||||
float fTravelDistance;
|
||||
if(GetIsPC(oEncounterObject))
|
||||
{
|
||||
if(!GetLocalInt(oEncounterObject, "re_bOldLocationSet"))
|
||||
{
|
||||
SetLocalInt(oEncounterObject, "re_bOldLocationSet", TRUE);
|
||||
SetLocalLocation(oEncounterObject, "re_lOldLocation", GetLocation(oEncounterObject));
|
||||
if(iCheckDistance) return OBJECT_INVALID;
|
||||
}
|
||||
if(GetDistanceBetweenLocations(GetLocation(oEncounterObject), GetLocalLocation(oEncounterObject, "re_lOldLocation")) < 0.0)
|
||||
{
|
||||
SetLocalLocation(oEncounterObject, "re_lOldLocation", GetLocation(oEncounterObject));
|
||||
if(iCheckDistance) return OBJECT_INVALID;
|
||||
}
|
||||
fTravelDistance = GetDistanceBetweenLocations(GetLocation(oEncounterObject), GetLocalLocation(oEncounterObject, "re_lOldLocation"));
|
||||
SetLocalFloat(oEncounterObject, "re_fTravelDistance", GetLocalFloat(oEncounterObject, "re_fTravelDistance") + fTravelDistance);
|
||||
SetLocalLocation(oEncounterObject, "re_lOldLocation", GetLocation(oEncounterObject));
|
||||
if(GetLocalFloat(oEncounterObject, "re_fTravelDistance") >= IntToFloat(iCheckDistance)) DeleteLocalFloat(oEncounterObject, "re_fTravelDistance");
|
||||
else return OBJECT_INVALID;
|
||||
}
|
||||
// The following two lines allow for a chance of encounter with a precision of up to
|
||||
// two decimal places. ie. 100.00. An encounter can have as little as a 0.01 chance
|
||||
// of occuring.
|
||||
int iHappens = Random(10000)+1;
|
||||
int iChanceOfEncounter = FloatToInt(fChanceOfEncounter * 100);
|
||||
if(iChanceOfEncounter < iHappens)
|
||||
{
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
//Are encounters disabled for this player?
|
||||
if(GetLocalInt(GetModule(), "re_" + GetPCPlayerName(oEncounterObject)))
|
||||
{
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
//Are random encounters disabled altogether?
|
||||
if(GetLocalInt(GetModule(), "re_disable"))
|
||||
{
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
//Is the player in combat with bConflict equal to false?
|
||||
object oHolder;
|
||||
int iCounter7 = 1; // Used in checking for nearby enemies.
|
||||
if(GetLocalInt(oEncounterObject, "re_bInitialized")) oHolder = oEncounterObject;
|
||||
else if(GetLocalInt(GetArea(oEncounterObject), "re_bInitialized")) oHolder = GetArea(oEncounterObject);
|
||||
else oHolder = GetModule();
|
||||
int bConflict = GetLocalInt(oHolder, "re_bConflict");
|
||||
if(!bConflict && GetIsPC(oEncounterObject))
|
||||
{
|
||||
if(GetIsInCombat(oEncounterObject)) return OBJECT_INVALID;
|
||||
object oNearest = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oEncounterObject, iCounter7);
|
||||
while(GetIsObjectValid(oNearest) && GetDistanceToObject(oNearest) < 35.0)
|
||||
{
|
||||
if(GetIsEnemy(oNearest) && (GetIsInCombat(oNearest) || GetObjectSeen(oNearest))) return OBJECT_INVALID;
|
||||
iCounter7++;
|
||||
oNearest = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oEncounterObject, iCounter7);
|
||||
}
|
||||
}
|
||||
//Are any nearby party members in a conversation?
|
||||
object oAmIAPC;
|
||||
oAmIAPC = GetFirstObjectInShape(SHAPE_SPHERE, 35.0, GetLocation(oEncounterObject), FALSE, OBJECT_TYPE_CREATURE);
|
||||
if(GetIsObjectValid(oAmIAPC))
|
||||
{
|
||||
while(GetIsObjectValid(oAmIAPC))
|
||||
{
|
||||
if(GetIsPC(oAmIAPC))
|
||||
{
|
||||
if(GetFactionEqual(oEncounterObject, oAmIAPC))
|
||||
{
|
||||
if(IsInConversation(oAmIAPC))
|
||||
{
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
oAmIAPC = GetNextObjectInShape(SHAPE_SPHERE, 25.0, GetLocation(oEncounterObject), FALSE, OBJECT_TYPE_CREATURE);
|
||||
}
|
||||
}
|
||||
|
||||
// DECLARE AND INITIALIZE VARIABLES
|
||||
object oMod = GetModule();
|
||||
int iMph;
|
||||
if(!iDifficulty) iDifficulty = GetLocalInt(oHolder, "re_iDifficulty");
|
||||
int bConsiderCR = GetLocalInt(oHolder, "re_bConsiderCR");
|
||||
if(GetStringLowerCase(sTemplate) == "random") sTemplate = GetLocalString(GetModule(), "re_sCreatureTable");
|
||||
int iLifeTime = GetLocalInt(oHolder, "re_iLifeTime");
|
||||
if(!GetLocalInt(oHolder, "re_iMph")) iMph = 2;
|
||||
else iMph = GetLocalInt(oHolder, "re_iMph");
|
||||
int bLOSCheck = GetLocalInt(oHolder, "re_bLOSCheck");
|
||||
int iEncounterType = GetLocalInt(oHolder, "re_iEncounterType");
|
||||
int iCounter1 = 1; // Used to count the creatures when spawning them.
|
||||
int iCounter2 = 1; // Used in loop to set difficulty level.
|
||||
int iCounter3 = 1; // Used in loop to check line of sight float fEncounterDistance (future use!).
|
||||
int iCounter4;// Used in determining the PC to spawn the encounter if the encounter object passed is an area or the module.
|
||||
int iCounter5; // Used in determining treasure table.
|
||||
int iCounter6; // Used in giving treasure.
|
||||
int iNumberOfCreatures;
|
||||
int iEncounterDistance;
|
||||
int iFacingSameWay;
|
||||
int iLevels;
|
||||
int iTableNumber;
|
||||
int bNumberByLevel = FALSE;
|
||||
int bNoEncounter = FALSE;
|
||||
int bComplete1 = FALSE;
|
||||
int bComplete2 = FALSE;
|
||||
int bTreasure;
|
||||
float fMinCR;
|
||||
float fMaxCR;
|
||||
float fEncounterDistance;
|
||||
float fNewEncounterDistance;
|
||||
float fCreatureFacing;
|
||||
float fEncounterAngle;
|
||||
float fEncounterVector;
|
||||
float fAngleOffset;
|
||||
float fLevels;
|
||||
float fDifficulty = 0.167;
|
||||
string sBuild;
|
||||
string sTreasure = sTemplate;
|
||||
vector vEncounterVector;
|
||||
vector vVectorOffset;
|
||||
vector vCreatureVector;
|
||||
object oObject;
|
||||
object oCreature;
|
||||
object oArea;
|
||||
if(oEncounterObject == GetModule())
|
||||
{
|
||||
oAmIAPC = GetFirstPC();
|
||||
while(GetIsObjectValid(oAmIAPC))
|
||||
{
|
||||
if(!GetLocalInt(GetModule(), "re_" + GetPCPlayerName(oAmIAPC)))
|
||||
{
|
||||
SetLocalObject(oMod, "re_oEncounterObject" + IntToString(iCounter4), oAmIAPC);
|
||||
iCounter4++;
|
||||
}
|
||||
oAmIAPC = GetNextPC();
|
||||
}
|
||||
oEncounterObject = GetLocalObject(oMod, "re_oEncounterObject" + IntToString(Random(iCounter4)));
|
||||
}
|
||||
else if(GetObjectType(oEncounterObject) == 0 && oEncounterObject != GetModule())
|
||||
{
|
||||
oArea = oEncounterObject;
|
||||
oAmIAPC = GetFirstObjectInArea(oArea);
|
||||
while(GetIsObjectValid(oAmIAPC))
|
||||
{
|
||||
if(GetIsPC(oAmIAPC) && !GetLocalInt(GetModule(), "re_" + GetPCPlayerName(oAmIAPC)))
|
||||
{
|
||||
SetLocalObject(oArea, "re_oEncounterObject" + IntToString(iCounter4), oAmIAPC);
|
||||
iCounter4++;
|
||||
}
|
||||
oAmIAPC = GetNextObjectInArea(oArea);
|
||||
}
|
||||
oEncounterObject = GetLocalObject(oArea, "re_oEncounterObject" + IntToString(Random(iCounter4)));
|
||||
}
|
||||
else
|
||||
{
|
||||
oArea = GetArea(oEncounterObject);
|
||||
}
|
||||
if(!GetIsPC(oEncounterObject))
|
||||
iEncounterType = ENCOUNTER_TYPE_AREA;
|
||||
location lCreatureLocation;
|
||||
vector vEncounterObjectVector = GetPosition(oEncounterObject);
|
||||
int iMin = 60;
|
||||
int iHr = iMin * iMph;
|
||||
int iDay = iHr * 24;
|
||||
int iMth = iDay * 28;
|
||||
int iYr = iMth * 12;
|
||||
if(iDifficulty > 10)
|
||||
{
|
||||
iDifficulty = 10;
|
||||
}
|
||||
if(iDifficulty == 0)
|
||||
{
|
||||
iDifficulty = GetGameDifficulty() * 2;
|
||||
}
|
||||
while(iCounter2 <= iDifficulty)
|
||||
{
|
||||
fDifficulty = fDifficulty * 1.5;
|
||||
iCounter2++;
|
||||
}
|
||||
|
||||
// ERROR CORRECTION
|
||||
if(iMaxNumberOfCreatures < iMinNumberOfCreatures)
|
||||
{
|
||||
iMaxNumberOfCreatures = iMinNumberOfCreatures;
|
||||
}
|
||||
if(iMaxEncounterDistance < iMinEncounterDistance)
|
||||
{
|
||||
iMaxEncounterDistance = iMinEncounterDistance;
|
||||
}
|
||||
if(!GetIsPC(oEncounterObject))
|
||||
{
|
||||
iEncounterType = ENCOUNTER_TYPE_AREA;
|
||||
}
|
||||
|
||||
// CHECK TO SEE IF PC IS RESTING VIA THE BESIE "re_onrest" SCRIPT AND IF SO
|
||||
// REMOVE RESTING EFFECTS.
|
||||
if(GetIsPC(oEncounterObject) && GetLocalInt(oEncounterObject, "re_resting"))
|
||||
{
|
||||
DeleteLocalInt(oEncounterObject, "re_resting");
|
||||
effect eEffect = GetFirstEffect(oEncounterObject);
|
||||
while(GetIsEffectValid(eEffect))
|
||||
{
|
||||
if(GetEffectType(eEffect) == EFFECT_TYPE_BLINDNESS && GetEffectCreator(eEffect) == GetModule()) RemoveEffect(oEncounterObject, eEffect);
|
||||
if(GetEffectType(eEffect) == VFX_IMP_SLEEP && GetEffectCreator(eEffect) == GetModule()) RemoveEffect(oEncounterObject, eEffect);
|
||||
eEffect = GetNextEffect(oEncounterObject);
|
||||
}
|
||||
}
|
||||
|
||||
// DETERMINE THE ANGLE OFFSET OF THE SPAWN
|
||||
if(iOrientation == 360)
|
||||
{
|
||||
fEncounterAngle = IntToFloat(Random(360));
|
||||
}
|
||||
else
|
||||
{
|
||||
fEncounterAngle = GetFacingFromLocation(GetLocation(oEncounterObject)) + IntToFloat(iOrientation);
|
||||
fEncounterAngle = (fEncounterAngle + (IntToFloat(iTolerance) * 0.5)) - (IntToFloat(Random(iTolerance)));
|
||||
}
|
||||
|
||||
// DETERMINE THE DISTANCE FROM THE SPAWNING OBJECT
|
||||
if(iMinEncounterDistance == 0)
|
||||
{
|
||||
iMinEncounterDistance = iMaxEncounterDistance;
|
||||
fEncounterDistance = IntToFloat(iMaxEncounterDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
fEncounterDistance = IntToFloat(iMinEncounterDistance + Random((iMaxEncounterDistance - iMinEncounterDistance) + 1));
|
||||
}
|
||||
iEncounterDistance = FloatToInt(fEncounterDistance);
|
||||
|
||||
// DETERMINE THE FACING OF THE SPAWN
|
||||
if(GetLocalInt(oEncounterObject, "re_Facing"))
|
||||
{
|
||||
fCreatureFacing = fEncounterAngle + 180.0;
|
||||
iFacingSameWay = TRUE;
|
||||
DeleteLocalInt(oEncounterObject, "re_Facing");
|
||||
}
|
||||
else
|
||||
{
|
||||
fCreatureFacing = IntToFloat(Random(360));
|
||||
iFacingSameWay = Random(2); // Note: If there is more than one creature there is a 50% chance they will all be facing the same direction
|
||||
}
|
||||
|
||||
// DETERMINE TOTAL CHARACTER LEVELS TO CONSIDER WHEN CHOOSING A CREATURE
|
||||
// AND/OR DETERMINING THE NUMBER OF CREATURES TO SPAWN.
|
||||
// If the variable iEncounterType is AREA, this routine
|
||||
// determines the total character levels
|
||||
// based upon the character levels of all PCs
|
||||
// in a 20 meter radius around the object that spawned
|
||||
// the encounter.
|
||||
// Later on the total character levels will be compared to
|
||||
// the challenge rating of the creature spawned, and a number
|
||||
// of creatures will be determined from that comparison.
|
||||
if(iEncounterType == ENCOUNTER_TYPE_AREA)
|
||||
{
|
||||
oAmIAPC = GetFirstObjectInShape(SHAPE_SPHERE, 20.0, GetLocation(oEncounterObject), FALSE, OBJECT_TYPE_CREATURE);
|
||||
while(GetIsObjectValid(oAmIAPC))
|
||||
{
|
||||
if(GetIsPC(oAmIAPC))
|
||||
{
|
||||
iLevels = iLevels + GetLevelByPosition(1, oAmIAPC) + GetLevelByPosition(2, oAmIAPC) + GetLevelByPosition(3, oAmIAPC);
|
||||
if(GetIsObjectValid(GetHenchman(oAmIAPC)))
|
||||
{
|
||||
iLevels = iLevels + GetLevelByPosition(1, GetHenchman(oAmIAPC)) + GetLevelByPosition(2, GetHenchman(oAmIAPC)) + GetLevelByPosition(3, GetHenchman(oAmIAPC));
|
||||
}
|
||||
}
|
||||
oAmIAPC = GetNextObjectInShape(SHAPE_SPHERE, 20.0, GetLocation(oEncounterObject), FALSE, OBJECT_TYPE_CREATURE);
|
||||
}
|
||||
}
|
||||
else if(iEncounterType == ENCOUNTER_TYPE_PARTY)
|
||||
{
|
||||
iLevels = GetFactionAverageLevel(oEncounterObject);
|
||||
}
|
||||
else if(iEncounterType == ENCOUNTER_TYPE_TOTALPARTYLEVELS)
|
||||
{
|
||||
oObject = GetFirstFactionMember(oEncounterObject);
|
||||
while(GetIsObjectValid(oObject))
|
||||
{
|
||||
if(GetArea(oObject) == GetArea(oEncounterObject))
|
||||
{
|
||||
iLevels = iLevels + GetLevelByPosition(1, oObject) + GetLevelByPosition(2, oObject) + GetLevelByPosition(3, oObject);
|
||||
}
|
||||
oObject = GetNextFactionMember(oEncounterObject);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the variable iEncounterType is set to IND, this
|
||||
// routine determines the total character levels based upon the
|
||||
// character level of the object that spawned the encounter.
|
||||
// if the object that spawned the encounter is NOT a PC then
|
||||
// the number of creatures spawned will be one. This shouldn't
|
||||
// happen since the the encounter type sets itself to AREA if
|
||||
// the encounter object is a placeable.
|
||||
if(GetIsPC(oEncounterObject))
|
||||
{
|
||||
iLevels = GetLevelByPosition(1, oEncounterObject) + GetLevelByPosition(2, oEncounterObject) + GetLevelByPosition(3, oEncounterObject);
|
||||
}
|
||||
}
|
||||
// Modify the float representing the total levels by the difficulty level.
|
||||
if(iLevelOverride)
|
||||
{
|
||||
iLevels = iLevelOverride;
|
||||
}
|
||||
fLevels = IntToFloat(iLevels) * fDifficulty;
|
||||
|
||||
// CHOOSE A CREATURE TO SPAWN
|
||||
if(GetStringLowerCase(sTemplate) == "random" || GetStringLowerCase(GetStringLeft(sTemplate, 3)) == "re_")
|
||||
{
|
||||
if(GetStringLowerCase(GetStringLeft(sTemplate, 3)) == "re_")
|
||||
{
|
||||
sTemplate = GetStringRight(sTemplate, GetStringLength(sTemplate) - 3);
|
||||
}
|
||||
if(fLevels < 0.25)
|
||||
{
|
||||
fMaxCR = 0.25;
|
||||
}
|
||||
else
|
||||
{
|
||||
fMaxCR = fLevels;
|
||||
}
|
||||
fMinCR = IntToFloat(FloatToInt(fMaxCR * 0.3));
|
||||
//If there is a definative number of creatures to spawn passed to
|
||||
//the RandomEncounter function when it is called, then do not
|
||||
//allow as much play in the low end, and a little more in the
|
||||
// high end challange ratings.
|
||||
if(iMinNumberOfCreatures == 0 && iMaxNumberOfCreatures > 1)
|
||||
{
|
||||
fMinCR = IntToFloat(FloatToInt(fMaxCR * 0.4));
|
||||
fMaxCR = fMaxCR * 1.2;
|
||||
fMinCR = IntToFloat(FloatToInt(fMinCR));
|
||||
}
|
||||
if(iMinNumberOfCreatures == 0 && iMaxNumberOfCreatures == 1)
|
||||
{
|
||||
fMinCR = IntToFloat(FloatToInt(fMaxCR * 0.6));
|
||||
fMaxCR = fMaxCR * 1.2;
|
||||
fMinCR = IntToFloat(FloatToInt(fMinCR));// Round off the CR.
|
||||
}
|
||||
if(GetLocalInt(oHolder, "re_bConsiderCR") == FALSE)
|
||||
{
|
||||
fMaxCR = 9999.0;
|
||||
fMinCR = 0.0;
|
||||
}
|
||||
sTemplate = GetRndEncCreature(fMinCR, fMaxCR, sTemplate);
|
||||
if(sTemplate == "") return OBJECT_INVALID;
|
||||
}
|
||||
|
||||
// DETERMINE IF CREATURE IS TO HAVE TREASURE AND WHAT TABLES TO USE
|
||||
if(GetLocalString(oMod, "re_s2DATreasure") != "")
|
||||
{
|
||||
sTreasure = GetLocalString(oMod, "re_s2DATreasure");
|
||||
DeleteLocalString(oMod, "re_s2DATreasure");
|
||||
}
|
||||
for(iCounter5 = 0; iCounter5 <= GetStringLength(sTreasure); iCounter5++)
|
||||
{
|
||||
if(bTreasure
|
||||
&& (GetSubString(sTreasure, iCounter5, 1) == "0" || StringToInt(GetSubString(sTreasure, iCounter5, 1)) > 0))
|
||||
{
|
||||
sBuild = sBuild + GetSubString(sTreasure, iCounter5, 1);
|
||||
}
|
||||
else if(bTreasure)
|
||||
{
|
||||
iTableNumber++;
|
||||
SetLocalString(OBJECT_SELF, "re_sTreasureTable" + IntToString(iTableNumber), sBuild);
|
||||
bTreasure = FALSE;
|
||||
sBuild = "";
|
||||
}
|
||||
if(GetStringLowerCase(GetSubString(sTreasure, iCounter5, 1)) == "t")
|
||||
{
|
||||
bTreasure = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// DETERMINE LOCATION AND SPAWN ONE CREATURE
|
||||
// NOTE: Line Of Sight checks have a bug. Bioware says they are looking
|
||||
// into the bug. I have spent an ungodly amount of hours trying to come
|
||||
// up with an acceptable work-around to the Line Of Sight functionality
|
||||
// of Get**ObjectInShape(). Unless somebody else can come up with a working
|
||||
// LOS check, I have no choice but to disregard LOS checks until they are
|
||||
// fixed.
|
||||
//
|
||||
// if(LOSCheck = TRUE)
|
||||
// {
|
||||
// <LOS code goes here>
|
||||
// }
|
||||
//
|
||||
// note: one creature is spawned in now so its challange rating can be
|
||||
// used to determine if more are needed. (if that option is set)
|
||||
vEncounterVector = AngleToVector(fEncounterAngle);
|
||||
vVectorOffset = vEncounterVector * fEncounterDistance;
|
||||
vCreatureVector = vEncounterObjectVector + vVectorOffset;
|
||||
lCreatureLocation = Location(oArea, vCreatureVector, fCreatureFacing);
|
||||
oCreature = CreateObject(OBJECT_TYPE_CREATURE, sTemplate, lCreatureLocation, FALSE);
|
||||
|
||||
// VERIFY THE RESREF OF THE SPAWNED CREATURE AGAINST THE TEMPLATE AND RETURN AN ERROR IF THEY DO NOT MATCH
|
||||
if(GetStringLowerCase(GetResRef(oCreature)) != GetStringLowerCase(sTemplate))
|
||||
{
|
||||
string sError = "BESIE Error: " + sTemplate + " does not match the blueprint of a valid creature object!";
|
||||
DestroyObject(oCreature);
|
||||
if(GetIsPC(oEncounterObject)) SendMessageToPC(oEncounterObject, sError);
|
||||
else
|
||||
{
|
||||
object oPC = GetFirstPC();
|
||||
while(GetIsObjectValid(oPC))
|
||||
{
|
||||
if(GetArea(oPC) == GetArea(oEncounterObject)) SendMessageToPC(oPC, sError);
|
||||
oPC = GetNextPC();
|
||||
}
|
||||
}
|
||||
SendMessageToAllDMs(sError);
|
||||
WriteTimestampedLogEntry(sError);
|
||||
return OBJECT_INVALID;
|
||||
}
|
||||
|
||||
// DETERMINE THE NUMBER OF ADDITIONAL CREATURES TO SPAWN.
|
||||
// If the min and max number of creatures in the function call are zero
|
||||
// then get the min and max number from the local variables in the module
|
||||
// object.
|
||||
if(iMinNumberOfCreatures == 0 && iMaxNumberOfCreatures == 0)
|
||||
{
|
||||
iMinNumberOfCreatures = GetLocalInt(oMod, "re_iMinNumberOfCreatures");
|
||||
iMaxNumberOfCreatures = GetLocalInt(oMod, "re_iMaxNumberOfCreatures");
|
||||
}
|
||||
// Now that we are done with these local integers, we need to clean reset
|
||||
// them to their defaults so we don't accidentally use old numbers later.
|
||||
SetLocalInt(oMod, "re_iMinNumberOfCreatures", 0);
|
||||
SetLocalInt(oMod, "re_iMaxNumberOfCreatures", 0);
|
||||
if(iMinNumberOfCreatures == 0 && iMaxNumberOfCreatures != 0)
|
||||
{
|
||||
iNumberOfCreatures = iMaxNumberOfCreatures;
|
||||
}
|
||||
if(iMinNumberOfCreatures != 0 && iMaxNumberOfCreatures != 0)
|
||||
{
|
||||
iNumberOfCreatures = iMinNumberOfCreatures + Random((iMaxNumberOfCreatures - iMinNumberOfCreatures) + 1);
|
||||
}
|
||||
if(iMinNumberOfCreatures == 0 && iMaxNumberOfCreatures == 0)
|
||||
{
|
||||
// This is the routine that sets the number of creatures to spawn
|
||||
// based on their challenge rating and the total character levels.
|
||||
// It chooses a random number between one half (truncated) and 120
|
||||
// percent (1 for every 4) of the number of creatures ideal for the
|
||||
// difficulty level set.
|
||||
iMaxNumberOfCreatures = FloatToInt(fLevels / GetChallengeRating(oCreature));
|
||||
iMinNumberOfCreatures = FloatToInt(IntToFloat(iMaxNumberOfCreatures) * 0.5);
|
||||
iMaxNumberOfCreatures = FloatToInt(IntToFloat(iMaxNumberOfCreatures) * 1.25);
|
||||
|
||||
//These lines were added with the v1.7 release because I noticed a situation where characters of
|
||||
//up to level 4 would still spawn orcs, goblins and other < CR1 creatures but they would
|
||||
//spawn a rediculous amount of them because of the low CR/LV ratio. This is just to eliminate
|
||||
//that.
|
||||
if(iMinNumberOfCreatures > 8) iMinNumberOfCreatures = 8;
|
||||
if(iMaxNumberOfCreatures > 9) iMaxNumberOfCreatures = 9;
|
||||
|
||||
iNumberOfCreatures = iMinNumberOfCreatures + Random((iMaxNumberOfCreatures - iMinNumberOfCreatures) + 1);
|
||||
if((iNumberOfCreatures < 1) && (iLevels > 0))
|
||||
{
|
||||
iNumberOfCreatures = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// SPAWN THOSE SUCKERS!
|
||||
while(iCounter1 <= iNumberOfCreatures)
|
||||
{
|
||||
// Stick some labels on the creature for record keeping and reference (future use!)
|
||||
SetLocalInt(oCreature, "re_bRandomEncounter", TRUE);
|
||||
SetLocalObject(oCreature, "re_oRandomEncounterSpawner", oEncounterObject);
|
||||
SetLocalInt(oCreature, "re_iRandomEncounterCounter", 1);
|
||||
SetLocalInt(oCreature, "re_iRandomEncounterSpawnTime", (GetCalendarYear() * iYr) + (GetCalendarMonth() * iMth) + (GetCalendarDay()* iDay) + (GetTimeHour()* iHr) + (GetTimeMinute() * iMin) + GetTimeSecond());
|
||||
SetLocalInt(oCreature, "re_iRandomEncounterLifeTime", iLifeTime);
|
||||
/*-------------------------
|
||||
This routine was removed in v1.8 because the standard treasure tables were removed and replaced
|
||||
with a routine that simply awards an appropriate amount of coin.
|
||||
if(!GetLocalInt(GetModule(), "re_standardtable")
|
||||
|| (GetLocalInt(GetModule(), "re_standardtable") && iCounter1 < 4))
|
||||
// The preceding if statement looks for a local variable set by the
|
||||
// standard treasure table included with BESIE. If this variable is
|
||||
// set then it halts execution of the treasure script after the first
|
||||
// 3 creatures. This prevents a Too Many Instructions error.
|
||||
{
|
||||
DeleteLocalInt(GetModule(), "re_standardtable"); //delete standard table int so as not to interfere with custom scripts.
|
||||
*/
|
||||
// Give treasure to the creature if any tables are set.
|
||||
for(iCounter6 = 1; iCounter6 <= iTableNumber; iCounter6++)
|
||||
{
|
||||
ExecuteScript("re_treasure" + GetLocalString(OBJECT_SELF, "re_sTreasureTable" + IntToString(iCounter6)), oCreature);
|
||||
}
|
||||
//}
|
||||
if(iCounter1 < iNumberOfCreatures)
|
||||
{
|
||||
oCreature = CreateObject(OBJECT_TYPE_CREATURE, sTemplate, lCreatureLocation, FALSE);
|
||||
}
|
||||
iCounter1++;
|
||||
// Determine the facing of the next creature
|
||||
if(iFacingSameWay == FALSE)
|
||||
{
|
||||
fCreatureFacing = IntToFloat(Random(360));
|
||||
lCreatureLocation = Location(oArea, vCreatureVector, fCreatureFacing);
|
||||
}
|
||||
}
|
||||
// Stick a lable on the spawning object for record keeping and reference (future use?)
|
||||
SetLocalObject(oEncounterObject, "re_oLastRandomEncounterSpawned", oCreature);
|
||||
return oCreature;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CleanHouse(int bDestroyPlotItems = FALSE, object oArea = OBJECT_SELF, int iSpawnOverride = 0, int iItemOverride = 0, int iBodyBagOverride = 0)
|
||||
{
|
||||
// GET THE TIME SCALE FOR THE MODULE
|
||||
int iMph;
|
||||
if(!GetLocalInt(GetModule(), "re_iMph"))
|
||||
{
|
||||
iMph = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
iMph = GetLocalInt(GetModule(), "re_iMph");
|
||||
}
|
||||
|
||||
// DECLARE AND INTIALIZE VARIABLES
|
||||
int iMin = 60;
|
||||
int iHr = iMin * iMph;
|
||||
int iDay = iHr * 24;
|
||||
int iMth = iDay * 28;
|
||||
int iYr = iMth * 12;
|
||||
int bShouldIKillHim = TRUE;
|
||||
int iLifeTime;
|
||||
int iItemLifeTime;
|
||||
int iBodyBagLifeTime;
|
||||
int iPresentTime = (GetCalendarYear() * iYr) + (GetCalendarMonth() * iMth) + (GetCalendarDay() * iDay) + (GetTimeHour() * iHr) + (GetTimeMinute() * iMin) + GetTimeSecond();
|
||||
object oObject;
|
||||
|
||||
|
||||
// GET EACH OBJECT IN THE AREA AND TEST FOR VALIDITY
|
||||
//The following assignment uses a peculiar property of the GetArea() function in that if the GetArea() function
|
||||
//is called on an area then the area is returned. So the oArea parameter of the CleanHouse function can be set
|
||||
//to an area or an object within that area and the function will work. (unless and/or until this is changed).
|
||||
object oAmIASpawn = GetFirstObjectInArea(GetArea(oArea));
|
||||
while(GetIsObjectValid(oAmIASpawn))
|
||||
{
|
||||
// IS IT A BODY BAG?
|
||||
if(GetTag(oAmIASpawn) == "BodyBag" && !GetLocalInt(oAmIASpawn, "re_bDroppedItem"))
|
||||
{
|
||||
SetLocalInt(oAmIASpawn, "re_bDroppedItem", TRUE);
|
||||
SetLocalInt(oAmIASpawn, "re_iDropTime", iPresentTime);
|
||||
object oItem = GetFirstItemInInventory(oAmIASpawn);
|
||||
while(GetIsObjectValid(oItem))
|
||||
{
|
||||
if(GetLocalInt(oItem, "bItemForGold")) DestroyObject(oItem);
|
||||
oItem = GetNextItemInInventory(oAmIASpawn);
|
||||
}
|
||||
}
|
||||
// IS IT A DROPPED ITEM?
|
||||
if(GetLocalInt(oAmIASpawn, "re_bDroppedItem"))
|
||||
{
|
||||
// HAS IT BEEN AROUND TOO LONG?
|
||||
if(iItemOverride)
|
||||
{
|
||||
iItemLifeTime = iItemOverride;
|
||||
}
|
||||
else
|
||||
{
|
||||
iItemLifeTime = 1800;
|
||||
}
|
||||
if(iBodyBagOverride)
|
||||
{
|
||||
iBodyBagLifeTime = iBodyBagOverride;
|
||||
}
|
||||
else
|
||||
{
|
||||
iBodyBagLifeTime = 300;
|
||||
}
|
||||
if((iPresentTime - GetLocalInt(oAmIASpawn, "re_iDropTime") > iItemLifeTime && GetTag(oAmIASpawn) != "BodyBag") || (iPresentTime - GetLocalInt(oAmIASpawn, "re_iDropTime") > iBodyBagLifeTime && GetTag(oAmIASpawn) == "BodyBag"))// && !GetPlotFlag(oAmIASpawn))
|
||||
{
|
||||
if(GetHasInventory(oAmIASpawn))
|
||||
{
|
||||
oObject = GetFirstItemInInventory(oAmIASpawn);
|
||||
while(GetIsObjectValid(oObject))
|
||||
{
|
||||
if(!GetPlotFlag(oObject) || bDestroyPlotItems)
|
||||
{
|
||||
DestroyObject(oObject, 0.0);
|
||||
}
|
||||
oObject = GetNextItemInInventory(oAmIASpawn);
|
||||
}
|
||||
}
|
||||
if(!GetPlotFlag(oAmIASpawn) || bDestroyPlotItems)
|
||||
{
|
||||
DestroyObject(oAmIASpawn, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
// IS HE IS A RANDOM ENCOUNTER?
|
||||
if(GetLocalInt(oAmIASpawn, "re_bRandomEncounter"))
|
||||
{
|
||||
// HAS HE BEEN AROUND TOO LONG?
|
||||
if(iSpawnOverride)
|
||||
{
|
||||
iLifeTime = iSpawnOverride;
|
||||
}
|
||||
else
|
||||
{
|
||||
iLifeTime = GetLocalInt(oAmIASpawn, "re_iRandomEncounterLifeTime");
|
||||
}
|
||||
if(iPresentTime - GetLocalInt(oAmIASpawn, "re_iRandomEncounterSpawnTime") > iLifeTime)
|
||||
{
|
||||
// IS HE IN COMBAT?
|
||||
if(!GetIsInCombat(oAmIASpawn))
|
||||
{
|
||||
// GET EACH PC AND TEST IF THE CREATURE SEES HIM
|
||||
// Note: this is because the creature might be charmed
|
||||
// or influenced not to attack the PCs by other means.
|
||||
object oPC = GetFirstPC();
|
||||
if(GetIsObjectValid(oPC))
|
||||
{
|
||||
while(GetIsObjectValid(oPC))
|
||||
{
|
||||
if(GetObjectSeen(oPC, oAmIASpawn))
|
||||
{
|
||||
bShouldIKillHim = FALSE;
|
||||
}
|
||||
oPC = GetNextPC();
|
||||
}
|
||||
}
|
||||
// IF THE CREATURE HAS PASSED ALL OF THESE CHECKS, DESTROY HIM.
|
||||
if(bShouldIKillHim)
|
||||
{
|
||||
if(!GetIsPC(oAmIASpawn)) //This is prevent despawning of creatures while possessed by a DM.
|
||||
{
|
||||
DestroyObject(oAmIASpawn, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
oAmIASpawn = GetNextObjectInArea(oArea);
|
||||
}
|
||||
}
|
||||
|
||||
//GET TIME IN SECONDS FUNCTION
|
||||
int GetTimeInSeconds(int iMph = 2)
|
||||
{
|
||||
if(!iMph) iMph = GetLocalInt(GetModule(), "re_iMph");
|
||||
int iMin = 60;
|
||||
int iHr = iMin * iMph;
|
||||
int iDay = iHr * 24;
|
||||
int iMth = iDay * 28;
|
||||
int iYr = iMth * 12;
|
||||
int iPresentTime = (GetCalendarYear() * iYr) + (GetCalendarMonth() * iMth) + (GetCalendarDay() * iDay) + (GetTimeHour() * iHr) + (GetTimeMinute() * iMin) + GetTimeSecond();
|
||||
return iPresentTime;
|
||||
}
|
||||
|
||||
location RandomWalk2(location lCenter, int iDistance = 20, object oCreature = OBJECT_SELF)
|
||||
{
|
||||
vector vVector;
|
||||
vector vVectorOffset;
|
||||
vector vFinalVector;
|
||||
location lLocation;
|
||||
object oArea = GetAreaFromLocation(lCenter);
|
||||
object oWaypoint;
|
||||
int nLocationValid = 0;
|
||||
float fDistanceToDoor;
|
||||
object oDoor;
|
||||
// determine location of invisible object to be used as target of ActionMoveToLocation command
|
||||
// if object is too near a door, location will be changed
|
||||
while (nLocationValid != 1)
|
||||
{
|
||||
// determine random location of invisible object to be placed as target of walk command
|
||||
float fAngle = IntToFloat(Random(360));
|
||||
float fDistance = IntToFloat(Random(iDistance) + 1);
|
||||
vVector = AngleToVector(fAngle);
|
||||
vVectorOffset = vVector * fDistance;
|
||||
vFinalVector = GetPositionFromLocation(lCenter) + vVectorOffset;
|
||||
lLocation = Location(oArea, vFinalVector, fAngle);
|
||||
// check distance for nearest door, set LocationValid flag if beyond 1 meter
|
||||
oWaypoint = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_invisobj", lLocation);
|
||||
oDoor = GetNearestObject(OBJECT_TYPE_DOOR, oWaypoint);
|
||||
fDistanceToDoor = GetDistanceBetween (oWaypoint, oDoor);
|
||||
if (fDistanceToDoor > 1.0)
|
||||
nLocationValid = 1; // terminates loop with current oWaypoint if door further away than 1 meter
|
||||
}
|
||||
lLocation = GetLocation(oWaypoint);
|
||||
AssignCommand(oCreature, ActionDoCommand(ActionMoveToLocation(lLocation)));
|
||||
DestroyObject(oWaypoint);
|
||||
return lLocation;
|
||||
|
||||
}
|
16
_module/nss/re_sc_dialogue1.nss
Normal file
16
_module/nss/re_sc_dialogue1.nss
Normal file
@@ -0,0 +1,16 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: FileName sc_dialogue1
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Script Wizard
|
||||
//:: Created On: 5/16/2003 9:32:45 PM
|
||||
//:://////////////////////////////////////////////
|
||||
int StartingConditional()
|
||||
{
|
||||
|
||||
// Inspect local variables
|
||||
if(!(GetLocalInt(OBJECT_SELF, "iDialogue") == 1))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
16
_module/nss/re_sc_dialogue10.nss
Normal file
16
_module/nss/re_sc_dialogue10.nss
Normal file
@@ -0,0 +1,16 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: FileName sc_dialogue1
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Script Wizard
|
||||
//:: Created On: 5/16/2003 9:32:45 PM
|
||||
//:://////////////////////////////////////////////
|
||||
int StartingConditional()
|
||||
{
|
||||
|
||||
// Inspect local variables
|
||||
if(!(GetLocalInt(OBJECT_SELF, "iDialogue") == 10))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
16
_module/nss/re_sc_dialogue2.nss
Normal file
16
_module/nss/re_sc_dialogue2.nss
Normal file
@@ -0,0 +1,16 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: FileName sc_dialogue1
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Script Wizard
|
||||
//:: Created On: 5/16/2003 9:32:45 PM
|
||||
//:://////////////////////////////////////////////
|
||||
int StartingConditional()
|
||||
{
|
||||
|
||||
// Inspect local variables
|
||||
if(!(GetLocalInt(OBJECT_SELF, "iDialogue") == 2))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
16
_module/nss/re_sc_dialogue3.nss
Normal file
16
_module/nss/re_sc_dialogue3.nss
Normal file
@@ -0,0 +1,16 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: FileName sc_dialogue1
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Script Wizard
|
||||
//:: Created On: 5/16/2003 9:32:45 PM
|
||||
//:://////////////////////////////////////////////
|
||||
int StartingConditional()
|
||||
{
|
||||
|
||||
// Inspect local variables
|
||||
if(!(GetLocalInt(OBJECT_SELF, "iDialogue") == 3))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user