Added BESIE, MS Moneclature

Added BESIE, Markshire's Nomeclature & started initial setup for commoners in Baleas.
This commit is contained in:
Jaysyn904
2021-09-01 23:42:36 -04:00
parent ca4bfe9834
commit ae152d0814
673 changed files with 363454 additions and 26630 deletions

View 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();
}

View 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();
}

View 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)));
}

View 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)));
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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));
}
}
}
}

View 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));
}
}
}
}

View 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))));
}

View 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
}

View 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));
}
}

View 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);
}

View 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;
}
}

View 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);
}

View 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"

View 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

File diff suppressed because it is too large Load Diff

4193
_module/nss/dmfi_execute.nss Normal file

File diff suppressed because it is too large Load Diff

View 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("");
}

View 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);
}

View 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
}

View 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);
}

View 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);
}

View 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
View 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");
}

View 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;
}

File diff suppressed because it is too large Load Diff

View 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;
}

View 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();
}
}

View 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);
}

View File

@@ -0,0 +1,6 @@
void main()
{
object oPC = GetPCSpeaker();
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
SetName(oTarget, "");
}

View File

@@ -0,0 +1,8 @@
#include "dmfi_getln_inc"
void main()
{
object oListener = OBJECT_SELF;
DMFI_cancel_get_line(0, oListener);
}

View 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);
}

View File

@@ -0,0 +1,6 @@
void main()
{
object oPC = GetPCSpeaker();
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
SetName(oTarget, "");
}

View File

@@ -0,0 +1,8 @@
#include "dmfi_getln_inc"
void main()
{
object oListener = OBJECT_SELF;
DMFI_cancel_get_line(0, oListener);
}

View 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;
}

View 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;
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}

View 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;
}

View 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);
}

View 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);
}
}

View 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
}
}
}

View 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;
}

View 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
View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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.
}

View 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);
}

View 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
View 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");
}
}

View 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
View 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
View 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);
}

View File

@@ -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);
}

View File

@@ -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.

View 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));
}

View 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));
}
}
}

View 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);
}
}
}

View 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
}

View 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);
}

View 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);
}

View 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
View 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
View 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);
}

View 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
View 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();
}

View 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());
}
}

View 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();
}
}

View File

@@ -0,0 +1,8 @@
void main()
{
//BESIE Widget
if(GetTag(GetItemActivated()) == "BESIEWidget")
{
AssignCommand(GetItemActivator(), ActionStartConversation(GetItemActivator(), "re_widget", TRUE));
}
}

View 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
View 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
View 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);
}
}
}

View 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
View 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);
}
}*/
}
}

View 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");
}
}
}

View 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
View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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