generated from Jaysyn/ModuleTemplate
2026/03/17 Update
Added DMFI components Updated dynamic conversations.
This commit is contained in:
2525
src/2da/feat.2da
2525
src/2da/feat.2da
File diff suppressed because it is too large
Load Diff
345
src/dmfi/dmfi_activate.nss
Normal file
345
src/dmfi/dmfi_activate.nss
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: DMFI - widget activation processor
|
||||||
|
//:: dmfi_activate
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Functions to respond and process DMFI item activations.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: The DMFI Team
|
||||||
|
//:: Created On:
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: 2008.05.25 tsunami282 - changes to invisible listeners to work with
|
||||||
|
//:: OnPlayerChat methods.
|
||||||
|
//:: 2008.07.10 tsunami282 - add Naming Wand to the exploder.
|
||||||
|
//:: 2008.08.15 tsunami282 - move init logic to new include.
|
||||||
|
|
||||||
|
#include "dmfi_init_inc"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void dmw_CleanUp(object oMySpeaker)
|
||||||
|
{
|
||||||
|
int nCount;
|
||||||
|
int nCache;
|
||||||
|
DeleteLocalObject(oMySpeaker, "dmfi_univ_target");
|
||||||
|
DeleteLocalLocation(oMySpeaker, "dmfi_univ_location");
|
||||||
|
DeleteLocalObject(oMySpeaker, "dmw_item");
|
||||||
|
DeleteLocalString(oMySpeaker, "dmw_repamt");
|
||||||
|
DeleteLocalString(oMySpeaker, "dmw_repargs");
|
||||||
|
nCache = GetLocalInt(oMySpeaker, "dmw_playercache");
|
||||||
|
for(nCount = 1; nCount <= nCache; nCount++)
|
||||||
|
{
|
||||||
|
DeleteLocalObject(oMySpeaker, "dmw_playercache" + IntToString(nCount));
|
||||||
|
}
|
||||||
|
DeleteLocalInt(oMySpeaker, "dmw_playercache");
|
||||||
|
nCache = GetLocalInt(oMySpeaker, "dmw_itemcache");
|
||||||
|
for(nCount = 1; nCount <= nCache; nCount++)
|
||||||
|
{
|
||||||
|
DeleteLocalObject(oMySpeaker, "dmw_itemcache" + IntToString(nCount));
|
||||||
|
}
|
||||||
|
DeleteLocalInt(oMySpeaker, "dmw_itemcache");
|
||||||
|
for(nCount = 1; nCount <= 10; nCount++)
|
||||||
|
{
|
||||||
|
DeleteLocalString(oMySpeaker, "dmw_dialog" + IntToString(nCount));
|
||||||
|
DeleteLocalString(oMySpeaker, "dmw_function" + IntToString(nCount));
|
||||||
|
DeleteLocalString(oMySpeaker, "dmw_params" + IntToString(nCount));
|
||||||
|
}
|
||||||
|
DeleteLocalString(oMySpeaker, "dmw_playerfunc");
|
||||||
|
DeleteLocalInt(oMySpeaker, "dmw_started");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oUser = OBJECT_SELF;
|
||||||
|
object oItem = GetLocalObject(oUser, "dmfi_item");
|
||||||
|
object oOther = GetLocalObject(oUser, "dmfi_target");
|
||||||
|
location lLocation = GetLocalLocation(oUser, "dmfi_location");
|
||||||
|
string sItemTag = GetTag(oItem);
|
||||||
|
|
||||||
|
// listening system initialization moved to new function
|
||||||
|
dmfiInitialize(oUser);
|
||||||
|
|
||||||
|
dmw_CleanUp(oUser);
|
||||||
|
|
||||||
|
if (GetStringLeft(sItemTag,8) == "hlslang_")
|
||||||
|
{
|
||||||
|
// Remove voice stuff
|
||||||
|
string ssLanguage = GetStringRight(sItemTag, GetStringLength(sItemTag) - 8);
|
||||||
|
SetLocalInt(oUser, "hls_MyLanguage", StringToInt(ssLanguage));
|
||||||
|
SetLocalString(oUser, "hls_MyLanguageName", GetName(oItem));
|
||||||
|
DelayCommand(1.0f, FloatingTextStringOnCreature("You are speaking " + GetName(oItem) + ". Type [(what you want to say in brackets)]", oUser, FALSE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetStringLeft(sItemTag, 8) == "dmfi_pc_")
|
||||||
|
{
|
||||||
|
if (GetStringLeft(sItemTag, 12) == "dmfi_pc_rest")
|
||||||
|
{
|
||||||
|
CreateObject(OBJECT_TYPE_PLACEABLE, "dmfi_rest" + GetStringRight(sItemTag, 3), GetLocation(oUser));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sItemTag == "dmfi_pc_follow")
|
||||||
|
{
|
||||||
|
if (GetIsObjectValid(oOther))
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("Now following "+ GetName(oOther),oUser, FALSE);
|
||||||
|
DelayCommand(2.0f, AssignCommand(oUser, ActionForceFollowObject(oOther, 2.0f)));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetLocalObject(oUser, "dmfi_univ_target", oUser);
|
||||||
|
SetLocalLocation(oUser, "dmfi_univ_location", lLocation);
|
||||||
|
SetLocalString(oUser, "dmfi_univ_conv", GetStringRight(sItemTag, GetStringLength(sItemTag) - 5));
|
||||||
|
AssignCommand(oUser, ClearAllActions());
|
||||||
|
AssignCommand(oUser, ActionStartConversation(OBJECT_SELF, "dmfi_universal", TRUE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetStringLeft(sItemTag, 5) == "dmfi_")
|
||||||
|
{
|
||||||
|
int iPass = FALSE;
|
||||||
|
|
||||||
|
if (GetIsDM(oUser) || GetIsDMPossessed(oUser))
|
||||||
|
iPass = TRUE;
|
||||||
|
|
||||||
|
if (!GetIsPC(oUser))
|
||||||
|
iPass = TRUE;
|
||||||
|
|
||||||
|
if (!iPass)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("You cannot use this item." ,oUser, FALSE);
|
||||||
|
SendMessageToAllDMs(GetName(oUser)+ " is attempting to use a DM item.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sItemTag == "dmfi_exploder")
|
||||||
|
{
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_afflict"))) CreateItemOnObject("dmfi_afflict", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_dicebag"))) CreateItemOnObject("dmfi_dicebag", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_pc_dicebag"))) CreateItemOnObject("dmfi_pc_dicebag", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_pc_follow"))) CreateItemOnObject("dmfi_pc_follow", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_pc_emote"))) CreateItemOnObject("dmfi_pc_emote", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_server"))) CreateItemOnObject("dmfi_server", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_emote"))) CreateItemOnObject("dmfi_emote", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_encounter"))) CreateItemOnObject("dmfi_encounte", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_faction"))) CreateItemOnObject("dmfi_faction", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_fx"))) CreateItemOnObject("dmfi_fx", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_music"))) CreateItemOnObject("dmfi_music", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_sound"))) CreateItemOnObject("dmfi_sound", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_voice"))) CreateItemOnObject("dmfi_voice", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_xp"))) CreateItemOnObject("dmfi_xp", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_500xp"))) CreateItemOnObject("dmfi_500xp", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_en_ditto"))) CreateItemOnObject("dmfi_en_ditto", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_mute"))) CreateItemOnObject("dmfi_mute", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_peace"))) CreateItemOnObject("dmfi_peace", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_voicewidget"))) CreateItemOnObject("dmfi_voicewidget", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_remove"))) CreateItemOnObject("dmfi_remove", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_dmw"))) CreateItemOnObject("dmfi_dmw", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_target"))) CreateItemOnObject("dmfi_target", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_buff"))) CreateItemOnObject("dmfi_buff", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_dmbook"))) CreateItemOnObject("dmfi_dmbook", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_playerbook"))) CreateItemOnObject("dmfi_playerbook", oOther);
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_jail_widget"))) CreateItemOnObject("dmfi_jail_widget", oOther);
|
||||||
|
// 2008.07.10 tsunami282 - add naming wand to the exploder
|
||||||
|
if(!GetIsObjectValid(GetItemPossessedBy(oOther, "dmfi_naming"))) CreateItemOnObject("dmfi_naming", oOther);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sItemTag == "dmfi_peace")
|
||||||
|
{ //This widget sets all creatures in the area to a neutral stance and clears combat.
|
||||||
|
object oArea = GetFirstObjectInArea(GetArea(oUser));
|
||||||
|
object oP;
|
||||||
|
while (GetIsObjectValid(oArea))
|
||||||
|
{
|
||||||
|
if (GetObjectType(oArea) == OBJECT_TYPE_CREATURE && !GetIsPC(oArea))
|
||||||
|
{
|
||||||
|
AssignCommand(oArea, ClearAllActions());
|
||||||
|
oP = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oP))
|
||||||
|
{
|
||||||
|
if (GetArea(oP) == GetArea(oUser))
|
||||||
|
{
|
||||||
|
ClearPersonalReputation(oArea, oP);
|
||||||
|
SetStandardFactionReputation(STANDARD_FACTION_HOSTILE, 25, oP);
|
||||||
|
SetStandardFactionReputation(STANDARD_FACTION_COMMONER, 91, oP);
|
||||||
|
SetStandardFactionReputation(STANDARD_FACTION_MERCHANT, 91, oP);
|
||||||
|
SetStandardFactionReputation(STANDARD_FACTION_DEFENDER, 91, oP);
|
||||||
|
}
|
||||||
|
oP = GetNextPC();
|
||||||
|
}
|
||||||
|
AssignCommand(oArea, ClearAllActions());
|
||||||
|
}
|
||||||
|
oArea = GetNextObjectInArea(GetArea(oUser));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update / remove invisible listeners as needed for onplayerchat
|
||||||
|
if (sItemTag == "dmfi_voicewidget")
|
||||||
|
{
|
||||||
|
object oVoice;
|
||||||
|
if (GetIsObjectValid(oOther)) // do we have a valid target creature?
|
||||||
|
{
|
||||||
|
// 2008.05.29 tsunami282 - we don't use creature listen stuff anymore
|
||||||
|
SetLocalObject(oUser, "dmfi_VoiceTarget", oOther);
|
||||||
|
|
||||||
|
FloatingTextStringOnCreature("You have targeted " + GetName(oOther) + " with the Voice Widget", oUser, FALSE);
|
||||||
|
|
||||||
|
if (GetLocalInt(GetModule(), "dmfi_voice_initial")!=1)
|
||||||
|
{
|
||||||
|
SetLocalInt(GetModule(), "dmfi_voice_initial", 1);
|
||||||
|
SendMessageToAllDMs("Listening Initialized: .commands, .skill checks, and much more now available.");
|
||||||
|
DelayCommand(4.0, FloatingTextStringOnCreature("Listening Initialized: .commands, .skill checks, and more available", oUser));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else // no valid target of voice wand
|
||||||
|
{
|
||||||
|
//Jump any existing Voice attached to the user
|
||||||
|
if (GetIsObjectValid(GetLocalObject(oUser, "dmfi_StaticVoice")))
|
||||||
|
{
|
||||||
|
DestroyObject(GetLocalObject(oUser, "dmfi_StaticVoice"));
|
||||||
|
}
|
||||||
|
//Create the StationaryVoice
|
||||||
|
object oStaticVoice = CreateObject(OBJECT_TYPE_CREATURE, "dmfi_voice", GetLocation(oUser));
|
||||||
|
//Set Ownership of the Voice to the User
|
||||||
|
SetLocalObject(oUser, "dmfi_StaticVoice", oVoice);
|
||||||
|
SetLocalObject(oUser, "dmfi_VoiceTarget", oStaticVoice);
|
||||||
|
DelayCommand(1.0f, FloatingTextStringOnCreature("A Stationary Voice has been created.", oUser, FALSE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sItemTag == "dmfi_mute")
|
||||||
|
{
|
||||||
|
SetLocalObject(oUser, "dmfi_univ_target", oUser);
|
||||||
|
SetLocalString(oUser, "dmfi_univ_conv", "voice");
|
||||||
|
SetLocalInt(oUser, "dmfi_univ_int", 8);
|
||||||
|
ExecuteScript("dmfi_execute", oUser);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//encounter ditto widget
|
||||||
|
if (sItemTag == "dmfi_en_ditto")
|
||||||
|
{
|
||||||
|
SetLocalObject(oUser, "dmfi_univ_target", oOther);
|
||||||
|
SetLocalLocation(oUser, "dmfi_univ_location", lLocation);
|
||||||
|
SetLocalString(oUser, "dmfi_univ_conv", "encounter");
|
||||||
|
SetLocalInt(oUser, "dmfi_univ_int", GetLocalInt(oUser, "EncounterType"));
|
||||||
|
ExecuteScript("dmfi_execute", oUser);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Change target widget
|
||||||
|
if (sItemTag == "dmfi_target")
|
||||||
|
{
|
||||||
|
SetLocalObject(oUser, "dmfi_univ_target", oOther);
|
||||||
|
FloatingTextStringOnCreature("DMFI Target set to " + GetName(oOther),oUser);
|
||||||
|
}
|
||||||
|
//Destroy object widget
|
||||||
|
if (sItemTag == "dmfi_remove")
|
||||||
|
{
|
||||||
|
object oKillMe;
|
||||||
|
//Targeting Self
|
||||||
|
if (oUser == oOther)
|
||||||
|
{
|
||||||
|
oKillMe = GetNearestObject(OBJECT_TYPE_PLACEABLE, oUser);
|
||||||
|
FloatingTextStringOnCreature("Destroyed " + GetName(oKillMe) + "(" + GetTag(oKillMe) + ")", oUser, FALSE);
|
||||||
|
DelayCommand(0.1f, DestroyObject(oKillMe));
|
||||||
|
}
|
||||||
|
else if (GetIsObjectValid(oOther)) //Targeting something else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("Destroyed " + GetName(oOther) + "(" + GetTag(oOther) + ")", oUser, FALSE);
|
||||||
|
DelayCommand(0.1f, DestroyObject(oOther));
|
||||||
|
}
|
||||||
|
else //Targeting the ground
|
||||||
|
{
|
||||||
|
int iReport = 0;
|
||||||
|
oKillMe = GetFirstObjectInShape(SHAPE_SPHERE, 2.0f, lLocation, FALSE, OBJECT_TYPE_ALL);
|
||||||
|
while (GetIsObjectValid(oKillMe))
|
||||||
|
{
|
||||||
|
iReport++;
|
||||||
|
DestroyObject(oKillMe);
|
||||||
|
oKillMe = GetNextObjectInShape(SHAPE_SPHERE, 2.0f, lLocation, FALSE, OBJECT_TYPE_ALL);
|
||||||
|
}
|
||||||
|
FloatingTextStringOnCreature("Destroyed " + IntToString(iReport) + " objects.", oUser, FALSE);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sItemTag == "dmfi_500xp")
|
||||||
|
{
|
||||||
|
SetLocalObject(oUser, "dmfi_univ_target", oOther);
|
||||||
|
SetLocalLocation(oUser, "dmfi_univ_location", lLocation);
|
||||||
|
SetLocalString(oUser, "dmfi_univ_conv", "xp");
|
||||||
|
SetLocalInt(oUser, "dmfi_univ_int", 53);
|
||||||
|
ExecuteScript("dmfi_execute", oUser);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sItemTag == "dmfi_jail_widget")
|
||||||
|
{
|
||||||
|
if (GetIsObjectValid(oOther) && !GetIsDM(oOther) && oOther != oUser)
|
||||||
|
{
|
||||||
|
object oJail = GetObjectByTag("dmfi_jail");
|
||||||
|
if (!GetIsObjectValid(oJail))
|
||||||
|
oJail = GetObjectByTag("dmfi_jail_default");
|
||||||
|
AssignCommand(oOther, ClearAllActions());
|
||||||
|
AssignCommand(oOther, JumpToObject(oJail));
|
||||||
|
SendMessageToPC(oUser, GetName(oOther) + " (" + GetPCPublicCDKey(oOther) + ")/IP: " + GetPCIPAddress(oOther) + " - has been sent to Jail.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sItemTag == "dmfi_encounter")
|
||||||
|
{
|
||||||
|
|
||||||
|
if (GetIsObjectValid(GetWaypointByTag("DMFI_E1")))
|
||||||
|
SetCustomToken(20771, GetName(GetWaypointByTag("DMFI_E1")));
|
||||||
|
else
|
||||||
|
SetCustomToken(20771, "Encounter Invalid");
|
||||||
|
if (GetIsObjectValid(GetWaypointByTag("DMFI_E2")))
|
||||||
|
SetCustomToken(20772, GetName(GetWaypointByTag("DMFI_E2")));
|
||||||
|
else
|
||||||
|
SetCustomToken(20772, "Encounter Invalid");
|
||||||
|
if (GetIsObjectValid(GetWaypointByTag("DMFI_E3")))
|
||||||
|
SetCustomToken(20773, GetName(GetWaypointByTag("DMFI_E3")));
|
||||||
|
else
|
||||||
|
SetCustomToken(20773, "Encounter Invalid");
|
||||||
|
if (GetIsObjectValid(GetWaypointByTag("DMFI_E4")))
|
||||||
|
SetCustomToken(20774, GetName(GetWaypointByTag("DMFI_E4")));
|
||||||
|
else
|
||||||
|
SetCustomToken(20774, "Encounter Invalid");
|
||||||
|
if (GetIsObjectValid(GetWaypointByTag("DMFI_E5")))
|
||||||
|
SetCustomToken(20775, GetName(GetWaypointByTag("DMFI_E5")));
|
||||||
|
else
|
||||||
|
SetCustomToken(20775, "Encounter Invalid");
|
||||||
|
if (GetIsObjectValid(GetWaypointByTag("DMFI_E6")))
|
||||||
|
SetCustomToken(20776, GetName(GetWaypointByTag("DMFI_E6")));
|
||||||
|
else
|
||||||
|
SetCustomToken(20776, "Encounter Invalid");
|
||||||
|
if (GetIsObjectValid(GetWaypointByTag("DMFI_E7")))
|
||||||
|
SetCustomToken(20777, GetName(GetWaypointByTag("DMFI_E7")));
|
||||||
|
else
|
||||||
|
SetCustomToken(20777, "Encounter Invalid");
|
||||||
|
if (GetIsObjectValid(GetWaypointByTag("DMFI_E8")))
|
||||||
|
SetCustomToken(20778, GetName(GetWaypointByTag("DMFI_E8")));
|
||||||
|
else
|
||||||
|
SetCustomToken(20778, "Encounter Invalid");
|
||||||
|
if (GetIsObjectValid(GetWaypointByTag("DMFI_E9")))
|
||||||
|
SetCustomToken(20779, GetName(GetWaypointByTag("DMFI_E9")));
|
||||||
|
else
|
||||||
|
SetCustomToken(20779, "Encounter Invalid");
|
||||||
|
}
|
||||||
|
if (sItemTag == "dmfi_afflict")
|
||||||
|
{
|
||||||
|
int nDNum;
|
||||||
|
|
||||||
|
nDNum = GetLocalInt(oUser, "dmfi_damagemodifier");
|
||||||
|
SetCustomToken(20780, IntToString(nDNum));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SetLocalObject(oUser, "dmfi_univ_target", oOther);
|
||||||
|
SetLocalLocation(oUser, "dmfi_univ_location", lLocation);
|
||||||
|
SetLocalString(oUser, "dmfi_univ_conv", GetStringRight(sItemTag, GetStringLength(sItemTag) - 5));
|
||||||
|
AssignCommand(oUser, ClearAllActions());
|
||||||
|
AssignCommand(oUser, ActionStartConversation(OBJECT_SELF, "dmfi_universal", TRUE, FALSE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
177
src/dmfi/dmfi_arrays_inc.nss
Normal file
177
src/dmfi/dmfi_arrays_inc.nss
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: DMFI - array functions include
|
||||||
|
//:: dmfi_arrays_inc
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Functions to use object-attached local variables as arrays.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: Noel
|
||||||
|
//:: Created On: November 17, 2001
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: 2007.12.24 tsunami282 - yanked most of these routines from Bioware's
|
||||||
|
//:: nw_o0_itemmaker, then expanded for bounds management.
|
||||||
|
|
||||||
|
int GetLocalArrayLowerBound(object oidObject, string sVarName);
|
||||||
|
int GetLocalArrayUpperBound(object oidObject, string sVarName);
|
||||||
|
void SetLocalArrayLowerBound(object oidObject, string sVarName, int nMin);
|
||||||
|
void SetLocalArrayUpperBound(object oidObject, string sVarName, int nMax);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
int GetLocalArrayInitialized(object oidObject, string sVarName)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + "_INIT";
|
||||||
|
return GetLocalInt(oidObject, sFullVarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void InitializeLocalArray(object oidObject, string sVarName)
|
||||||
|
{
|
||||||
|
int i, iBegin, iEnd;
|
||||||
|
string sFullVarName;
|
||||||
|
|
||||||
|
if (GetLocalArrayInitialized(oidObject, sVarName))
|
||||||
|
{
|
||||||
|
// wipe current contents
|
||||||
|
iBegin = GetLocalArrayLowerBound(oidObject, sVarName);
|
||||||
|
iEnd = GetLocalArrayUpperBound(oidObject, sVarName);
|
||||||
|
for (i = iEnd; i >= iBegin; i--)
|
||||||
|
{
|
||||||
|
sFullVarName = sVarName + IntToString(i);
|
||||||
|
DeleteLocalInt(oidObject, sFullVarName);
|
||||||
|
DeleteLocalFloat(oidObject, sFullVarName);
|
||||||
|
DeleteLocalString(oidObject, sFullVarName);
|
||||||
|
DeleteLocalObject(oidObject, sFullVarName);
|
||||||
|
DeleteLocalLocation(oidObject, sFullVarName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLocalArrayLowerBound(oidObject, sVarName, 0);
|
||||||
|
SetLocalArrayUpperBound(oidObject, sVarName, -1);
|
||||||
|
sFullVarName = sVarName + "_INIT";
|
||||||
|
SetLocalInt(oidObject, sFullVarName, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
int GetLocalArrayLowerBound(object oidObject, string sVarName)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + "_MIN";
|
||||||
|
return GetLocalInt(oidObject, sFullVarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
int GetLocalArrayUpperBound(object oidObject, string sVarName)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + "_MAX";
|
||||||
|
return GetLocalInt(oidObject, sFullVarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void SetLocalArrayLowerBound(object oidObject, string sVarName, int nMin)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + "_MIN";
|
||||||
|
SetLocalInt(oidObject, sFullVarName, nMin);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void SetLocalArrayUpperBound(object oidObject, string sVarName, int nMax)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + "_MAX";
|
||||||
|
SetLocalInt(oidObject, sFullVarName, nMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
int GetLocalArrayInt(object oidObject, string sVarName, int nVarNum)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||||
|
return GetLocalInt(oidObject, sFullVarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void SetLocalArrayInt(object oidObject, string sVarName, int nVarNum, int nValue)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||||
|
SetLocalInt(oidObject, sFullVarName, nValue);
|
||||||
|
// update bounds
|
||||||
|
if (nVarNum < GetLocalArrayLowerBound(oidObject, sVarName))
|
||||||
|
SetLocalArrayLowerBound(oidObject, sVarName, nVarNum);
|
||||||
|
if (nVarNum > GetLocalArrayUpperBound(oidObject, sVarName))
|
||||||
|
SetLocalArrayUpperBound(oidObject, sVarName, nVarNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
float GetLocalArrayFloat(object oidObject, string sVarName, int nVarNum)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||||
|
return GetLocalFloat(oidObject, sFullVarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void SetLocalArrayFloat(object oidObject, string sVarName, int nVarNum, float fValue)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||||
|
SetLocalFloat(oidObject, sFullVarName, fValue);
|
||||||
|
// update bounds
|
||||||
|
if (nVarNum < GetLocalArrayLowerBound(oidObject, sVarName))
|
||||||
|
SetLocalArrayLowerBound(oidObject, sVarName, nVarNum);
|
||||||
|
if (nVarNum > GetLocalArrayUpperBound(oidObject, sVarName))
|
||||||
|
SetLocalArrayUpperBound(oidObject, sVarName, nVarNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
string GetLocalArrayString(object oidObject, string sVarName, int nVarNum)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||||
|
return GetLocalString(oidObject, sFullVarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void SetLocalArrayString(object oidObject, string sVarName, int nVarNum, string nValue)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||||
|
SetLocalString(oidObject, sFullVarName, nValue);
|
||||||
|
// update bounds
|
||||||
|
if (nVarNum < GetLocalArrayLowerBound(oidObject, sVarName))
|
||||||
|
SetLocalArrayLowerBound(oidObject, sVarName, nVarNum);
|
||||||
|
if (nVarNum > GetLocalArrayUpperBound(oidObject, sVarName))
|
||||||
|
SetLocalArrayUpperBound(oidObject, sVarName, nVarNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
object GetLocalArrayObject(object oidObject, string sVarName, int nVarNum)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||||
|
return GetLocalObject(oidObject, sFullVarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void SetLocalArrayObject(object oidObject, string sVarName, int nVarNum, object oidValue)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||||
|
SetLocalObject(oidObject, sFullVarName, oidValue);
|
||||||
|
// update bounds
|
||||||
|
if (nVarNum < GetLocalArrayLowerBound(oidObject, sVarName))
|
||||||
|
SetLocalArrayLowerBound(oidObject, sVarName, nVarNum);
|
||||||
|
if (nVarNum > GetLocalArrayUpperBound(oidObject, sVarName))
|
||||||
|
SetLocalArrayUpperBound(oidObject, sVarName, nVarNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
location GetLocalArrayLocation(object oidObject, string sVarName, int nVarNum)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||||
|
return GetLocalLocation(oidObject, sFullVarName);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void SetLocalArrayLocation(object oidObject, string sVarName, int nVarNum, location locValue)
|
||||||
|
{
|
||||||
|
string sFullVarName = sVarName + IntToString(nVarNum) ;
|
||||||
|
SetLocalLocation(oidObject, sFullVarName, locValue);
|
||||||
|
// update bounds
|
||||||
|
if (nVarNum < GetLocalArrayLowerBound(oidObject, sVarName))
|
||||||
|
SetLocalArrayLowerBound(oidObject, sVarName, nVarNum);
|
||||||
|
if (nVarNum > GetLocalArrayUpperBound(oidObject, sVarName))
|
||||||
|
SetLocalArrayUpperBound(oidObject, sVarName, nVarNum);
|
||||||
|
}
|
||||||
|
|
||||||
22
src/dmfi/dmfi_cond_dmw.nss
Normal file
22
src/dmfi/dmfi_cond_dmw.nss
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
int StartingConditional()
|
||||||
|
{
|
||||||
|
int nMyNum = GetLocalInt(OBJECT_SELF, "dmfi_dmwOffset");
|
||||||
|
SetLocalInt(OBJECT_SELF, "dmfi_dmwOffset", nMyNum+1);
|
||||||
|
|
||||||
|
object oMySpeaker = GetPCSpeaker();
|
||||||
|
object oMyTarget = GetLocalObject(oMySpeaker, "dmfi_univ_target");
|
||||||
|
location lMyLoc = GetLocalLocation(oMySpeaker, "dmfi_univ_location");
|
||||||
|
|
||||||
|
string sMyString = GetLocalString(oMySpeaker, "dmw_dialog" + IntToString(nMyNum));
|
||||||
|
|
||||||
|
if(sMyString == "")
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetCustomToken(8000 + nMyNum, sMyString);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
64
src/dmfi/dmfi_db_biow_inc.nss
Normal file
64
src/dmfi/dmfi_db_biow_inc.nss
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
//DMFI Persistence wrapper functions
|
||||||
|
//This include file contains the wrapper functions for the
|
||||||
|
//persistent settings of the DMFI Wand and Widget package
|
||||||
|
//Advanced users can adapt this to the database system that
|
||||||
|
//they want to use for NWN.
|
||||||
|
//
|
||||||
|
//These functions use the Bioware database by default and use a primitive form
|
||||||
|
//of "caching" to avoid lots of database R/W
|
||||||
|
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: The DMFI Team
|
||||||
|
//:: Created On:
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: 2008.07.10 tsunami282 - implemented alternate database support, initially
|
||||||
|
//:: for Knat's NBDE
|
||||||
|
|
||||||
|
|
||||||
|
const int DMFI_DB_TYPE =1;
|
||||||
|
|
||||||
|
void FlushDMFIPersistentData(string sDBName)
|
||||||
|
{
|
||||||
|
// no flushing required for Bioware database
|
||||||
|
}
|
||||||
|
|
||||||
|
int IsDMFIPersistentDataDirty(string sDBName)
|
||||||
|
{
|
||||||
|
return FALSE; // bioware database system has no cache, so is never dirty
|
||||||
|
}
|
||||||
|
|
||||||
|
//Int functions
|
||||||
|
int GetDMFIPersistentInt(string sDBName, string sDBSetting, object oPlayer = OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
int iReturn = GetCampaignInt(sDBName, sDBSetting, oPlayer);
|
||||||
|
return iReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDMFIPersistentInt(string sDBName, string sDBSetting, int iDBValue, object oPlayer = OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
SetCampaignInt(sDBName, sDBSetting, iDBValue, oPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Float functions
|
||||||
|
float GetDMFIPersistentFloat(string sDBName, string sDBSetting, object oPlayer = OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
float fReturn = GetCampaignFloat(sDBName, sDBSetting, oPlayer);
|
||||||
|
return fReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDMFIPersistentFloat(string sDBName, string sDBSetting, float fDBValue, object oPlayer = OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
SetCampaignFloat(sDBName, sDBSetting, fDBValue, oPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//String functions
|
||||||
|
string GetDMFIPersistentString(string sDBName, string sDBSetting, object oPlayer = OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
string sReturn = GetCampaignString(sDBName, sDBSetting, oPlayer);
|
||||||
|
return sReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDMFIPersistentString(string sDBName, string sDBSetting, string sDBValue, object oPlayer = OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
SetCampaignString(sDBName, sDBSetting, sDBValue, oPlayer);
|
||||||
|
}
|
||||||
39
src/dmfi/dmfi_db_inc.nss
Normal file
39
src/dmfi/dmfi_db_inc.nss
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
//DMFI Persistence wrapper functions
|
||||||
|
//This include file contains the wrapper functions for the
|
||||||
|
//persistent settings of the DMFI Wand and Widget package
|
||||||
|
//Advanced users can adapt this to the database system that
|
||||||
|
//they want to use for NWN.
|
||||||
|
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: The DMFI Team
|
||||||
|
//:: Created On:
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: 2008.07.10 tsunami282 - implemented alternate database support, initially
|
||||||
|
//:: for Knat's NBDE
|
||||||
|
|
||||||
|
//Listen Pattern ** variable
|
||||||
|
//Change this to 0 to make the DMFI W&W more compatible with Jasperre's AI
|
||||||
|
const int LISTEN_PATTERN = 20600;
|
||||||
|
|
||||||
|
const int DMFI_DB_TYPE_BIOWARE = 1;
|
||||||
|
const int DMFI_DB_TYPE_NBDE = 2;
|
||||||
|
const int DMFI_DB_TYPE_RESERVED_3 = 3;
|
||||||
|
const int DMFI_DB_TYPE_RESERVED_4 = 4;
|
||||||
|
const int DMFI_DB_TYPE_RESERVED_5 = 5;
|
||||||
|
const int DMFI_DB_TYPE_RESERVED_6 = 6;
|
||||||
|
const int DMFI_DB_TYPE_RESERVED_7 = 7;
|
||||||
|
const int DMFI_DB_TYPE_RESERVED_8 = 8;
|
||||||
|
const int DMFI_DB_TYPE_RESERVED_9 = 9;
|
||||||
|
const int DMFI_DB_TYPE_RESERVED_10 = 10;
|
||||||
|
|
||||||
|
// *** DATABASE SELECTION ***
|
||||||
|
// Only choose one of the following #include lines. Comment out all the others!
|
||||||
|
|
||||||
|
// Standard version uses the default Bioware database
|
||||||
|
#include "dmfi_db_biow_inc"
|
||||||
|
|
||||||
|
// Alternate version: using Knat's NBDE
|
||||||
|
// This provides greatly increased speed, but necessitates occasional flushing to disk.
|
||||||
|
// Flushing requires you to add code to Your module OnHeartbeat event.
|
||||||
|
// #include "dmfi_db_nbde_inc"
|
||||||
|
|
||||||
65
src/dmfi/dmfi_db_nbde_inc.nss
Normal file
65
src/dmfi/dmfi_db_nbde_inc.nss
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
//DMFI Persistence wrapper functions
|
||||||
|
// modified version for Knat's NBDE support
|
||||||
|
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: The DMFI Team
|
||||||
|
//:: Created On:
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: 2008.07.10 tsunami282 - implemented alternate database support, initially
|
||||||
|
//:: for Knat's NBDE
|
||||||
|
|
||||||
|
|
||||||
|
const int DMFI_DB_TYPE = 2;
|
||||||
|
|
||||||
|
#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
src/dmfi/dmfi_dmw_inc.nss
Normal file
1198
src/dmfi/dmfi_dmw_inc.nss
Normal file
File diff suppressed because it is too large
Load Diff
1198
src/dmfi/dmfi_dmwx_inc.nss
Normal file
1198
src/dmfi/dmfi_dmwx_inc.nss
Normal file
File diff suppressed because it is too large
Load Diff
4199
src/dmfi/dmfi_execute.nss
Normal file
4199
src/dmfi/dmfi_execute.nss
Normal file
File diff suppressed because it is too large
Load Diff
35
src/dmfi/dmfi_getln_cbtpl.nss
Normal file
35
src/dmfi/dmfi_getln_cbtpl.nss
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: DMFI - DMFI_get_line callback template
|
||||||
|
//:: dmfi_getln_cbtpl
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
A template (skeleton) function for DMFI_get_line callback processing.
|
||||||
|
|
||||||
|
Use this template to create your script to be invoked when your scripted call
|
||||||
|
to DMFI_get_line receives input.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: tsunami282
|
||||||
|
//:: Created On: 2008.05.21
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int nVolume = GetPCChatVolume();
|
||||||
|
object oShouter = GetPCChatSpeaker();
|
||||||
|
string sSaid = GetPCChatMessage();
|
||||||
|
|
||||||
|
// you may wish to define an "abort" input message, such as a line
|
||||||
|
// containing a single period:
|
||||||
|
if (sSaid != ".")
|
||||||
|
{
|
||||||
|
// put your code here to process the input line (in sSaid)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// after processing, you will likely want to "eat" the text line, so it is
|
||||||
|
// not spoken or available for further processing. If you want the line to
|
||||||
|
// appear, either comment out the following line, or set it to:
|
||||||
|
// SetPCChatMessage(sSaid);
|
||||||
|
SetPCChatMessage("");
|
||||||
|
}
|
||||||
61
src/dmfi/dmfi_getln_inc.nss
Normal file
61
src/dmfi/dmfi_getln_inc.nss
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
// DMFI_get_line: generic input line processing
|
||||||
|
//
|
||||||
|
// You can use this when you want to retrieve a spoken line of text.
|
||||||
|
//
|
||||||
|
// Specify the PC you want to listen to, the channel you want to listen on
|
||||||
|
// (often the TALK channel), and the name of the script to run when a line
|
||||||
|
// of text is heard.
|
||||||
|
//
|
||||||
|
// See the file dmfi_getln_cbtbl for a sample template script for processing
|
||||||
|
// the heard line.
|
||||||
|
|
||||||
|
#include "dmfi_plychat_inc"
|
||||||
|
|
||||||
|
const string DMFI_GETLINE_HOOK_HANDLE_VARNAME = "dmfi_getline_hookhandle";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author tsunami282
|
||||||
|
* @since 1.09
|
||||||
|
*
|
||||||
|
* @param oSpeaker PC we want to listen to.
|
||||||
|
* @param iChannel voice channel to listen on (use TALKVOLUME_ constants).
|
||||||
|
* @param sEventScriptName sEventScriptName = name of script to call upon completion
|
||||||
|
* of input (cannot be blank).
|
||||||
|
* @param oRequester object requesting the result: the sEventScriptName script
|
||||||
|
* will be invoked with this as the caller, and therefore it
|
||||||
|
* must be valid at time of player chat event.
|
||||||
|
* @return handle (positive int) of the chat event hook
|
||||||
|
*/
|
||||||
|
int DMFI_get_line(object oSpeaker, int iChannel, string sEventScriptName,
|
||||||
|
object oRequester = OBJECT_SELF)
|
||||||
|
{
|
||||||
|
int hdlHook = 0;
|
||||||
|
|
||||||
|
if (GetIsObjectValid(oSpeaker) && GetIsObjectValid(oRequester) && sEventScriptName != "")
|
||||||
|
{
|
||||||
|
// SendMessageToPC(GetFirstPC(), "getline - apply hook");
|
||||||
|
hdlHook = DMFI_ChatHookAdd(sEventScriptName, oRequester, (1 << iChannel),
|
||||||
|
FALSE, oSpeaker, TRUE);
|
||||||
|
// SendMessageToPC(GetFirstPC(), "getline - hook handle returned is " + IntToString(hdlHook));
|
||||||
|
SetLocalInt(oRequester, DMFI_GETLINE_HOOK_HANDLE_VARNAME, hdlHook);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hdlHook;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param hdlHookIn handle of hook handler that we want to un-hook.
|
||||||
|
* @param oRequester object requesting the result of DMFI_get_line
|
||||||
|
*/
|
||||||
|
void DMFI_cancel_get_line(int hdlHookIn = 0, object oRequester = OBJECT_SELF)
|
||||||
|
{
|
||||||
|
int hdlHook = hdlHookIn;
|
||||||
|
if (hdlHook == 0) hdlHook = GetLocalInt(oRequester, DMFI_GETLINE_HOOK_HANDLE_VARNAME);
|
||||||
|
DMFI_ChatHookRemove(hdlHook);
|
||||||
|
}
|
||||||
|
|
||||||
217
src/dmfi/dmfi_init_inc.nss
Normal file
217
src/dmfi/dmfi_init_inc.nss
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
|
||||||
|
#include "dmfi_db_inc"
|
||||||
|
|
||||||
|
const int DMFI_DEFAULT_EMOTES_MUTED = FALSE;
|
||||||
|
|
||||||
|
int dmfiInitialize(object oUser)
|
||||||
|
{
|
||||||
|
//*************************************INITIALIZATION CODE***************************************
|
||||||
|
//***************************************RUNS ONE TIME ***************************************
|
||||||
|
|
||||||
|
//voice stuff is module wide
|
||||||
|
|
||||||
|
if (GetLocalInt(GetModule(), "dmfi_initialized") != 1)
|
||||||
|
{
|
||||||
|
SendMessageToPC(oUser,":: DMFI Wands & Widgets System ::");
|
||||||
|
int iLoop = 20610;
|
||||||
|
string sText;
|
||||||
|
while (iLoop < 20680)
|
||||||
|
{
|
||||||
|
sText = GetDMFIPersistentString("dmfi", "hls" + IntToString(iLoop));
|
||||||
|
SetCustomToken(iLoop, sText);
|
||||||
|
iLoop++;
|
||||||
|
}
|
||||||
|
SendMessageToAllDMs("DMFI voice custom tokens initialized.");
|
||||||
|
|
||||||
|
SetLocalInt(GetModule(), "dmfi_initialized", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//remainder of settings are user based
|
||||||
|
|
||||||
|
if ((GetLocalInt(oUser, "dmfi_initialized")!=1) && (GetIsDM(oUser) || GetIsDMPossessed(oUser)))
|
||||||
|
{
|
||||||
|
//if you have campaign variables set - use those settings
|
||||||
|
if (GetDMFIPersistentInt("dmfi", "Settings", oUser)==1)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("DMFI Settings Restored", oUser, FALSE);
|
||||||
|
// SendMessageToPC(oUser, "DMFI Settings Restored");
|
||||||
|
|
||||||
|
int n = GetDMFIPersistentInt("dmfi", "dmfi_alignshift", oUser);
|
||||||
|
SetCustomToken(20781, IntToString(n));
|
||||||
|
SetLocalInt(oUser, "dmfi_alignshift", n);
|
||||||
|
SendMessageToPC(oUser, "Settings: Alignment shift: "+IntToString(n));
|
||||||
|
|
||||||
|
n = GetDMFIPersistentInt("dmfi", "dmfi_safe_factions", oUser);
|
||||||
|
SetLocalInt(oUser, "dmfi_safe_factions", n);
|
||||||
|
SendMessageToPC(oUser, "Settings: Factions (1 is DMFI Safe Faction): "+IntToString(n));
|
||||||
|
|
||||||
|
n = GetDMFIPersistentInt("dmfi", "dmfi_damagemodifier", oUser);
|
||||||
|
SetLocalInt(oUser, "dmfi_damagemodifier",n);
|
||||||
|
SendMessageToPC(oUser, "Settings: Damage Modifier: "+IntToString(n));
|
||||||
|
|
||||||
|
n = GetDMFIPersistentInt("dmfi","dmfi_buff_party",oUser);
|
||||||
|
SetLocalInt(oUser, "dmfi_buff_party", n);
|
||||||
|
if (n==1)
|
||||||
|
SetCustomToken(20783, "Party");
|
||||||
|
else
|
||||||
|
SetCustomToken(20783, "Single Target");
|
||||||
|
|
||||||
|
SendMessageToPC(oUser, "Settings: Buff Party (1 is Party): "+IntToString(n));
|
||||||
|
|
||||||
|
string sLevel = GetDMFIPersistentString("dmfi", "dmfi_buff_level", oUser);
|
||||||
|
SetCustomToken(20782, sLevel);
|
||||||
|
SetLocalString(oUser, "dmfi_buff_level", sLevel);
|
||||||
|
SendMessageToPC(oUser, "Settings: Buff Level: "+ sLevel);
|
||||||
|
|
||||||
|
n = GetDMFIPersistentInt("dmfi", "dmfi_dicebag", oUser);
|
||||||
|
SetLocalInt(oUser, "dmfi_dicebag", n);
|
||||||
|
|
||||||
|
string sText;
|
||||||
|
if (n==0)
|
||||||
|
{
|
||||||
|
SetCustomToken(20681, "Private");
|
||||||
|
sText = "Private";
|
||||||
|
}
|
||||||
|
else if (n==1)
|
||||||
|
{
|
||||||
|
SetCustomToken(20681, "Global");
|
||||||
|
sText = "Global";
|
||||||
|
}
|
||||||
|
else if (n==2)
|
||||||
|
{
|
||||||
|
SetCustomToken(20681, "Local");
|
||||||
|
sText = "Local";
|
||||||
|
}
|
||||||
|
else if (n==3)
|
||||||
|
{
|
||||||
|
SetCustomToken(20681, "DM Only");
|
||||||
|
sText = "DM Only";
|
||||||
|
}
|
||||||
|
SendMessageToPC(oUser, "Settings: Dicebag Reporting: "+sText);
|
||||||
|
|
||||||
|
n = GetDMFIPersistentInt("dmfi", "dmfi_dice_no_animate", oUser);
|
||||||
|
SetLocalInt(oUser, "dmfi_dice_no_animate", n);
|
||||||
|
SendMessageToPC(oUser, "Settings: Roll Animations (1 is OFF): "+IntToString(n));
|
||||||
|
|
||||||
|
float f = GetDMFIPersistentFloat("dmfi", "dmfi_reputation", oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_reputation", f);
|
||||||
|
SendMessageToPC(oUser, "Settings: Reputation Adjustment: "+FloatToString(f));
|
||||||
|
|
||||||
|
f = GetDMFIPersistentFloat("dmfi", "dmfi_effectduration", oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_effectduration", f);
|
||||||
|
SendMessageToPC(oUser, "Settings: Effect Duration: "+FloatToString(f));
|
||||||
|
|
||||||
|
f = GetDMFIPersistentFloat("dmfi", "dmfi_sound_delay", oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_sound_delay", f);
|
||||||
|
SendMessageToPC(oUser, "Settings: Sound Delay: "+FloatToString(f));
|
||||||
|
|
||||||
|
f = GetDMFIPersistentFloat("dmfi", "dmfi_beamduration", oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_beamduration", f);
|
||||||
|
SendMessageToPC(oUser, "Settings: Beam Duration: "+FloatToString(f));
|
||||||
|
|
||||||
|
f = GetDMFIPersistentFloat("dmfi", "dmfi_stunduration", oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_stunduration", f);
|
||||||
|
SendMessageToPC(oUser, "Settings: Stun Duration: "+FloatToString(f));
|
||||||
|
|
||||||
|
f = GetDMFIPersistentFloat("dmfi", "dmfi_saveamount", oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_saveamount", f);
|
||||||
|
SendMessageToPC(oUser, "Settings: Save Adjustment: "+FloatToString(f));
|
||||||
|
|
||||||
|
f = GetDMFIPersistentFloat("dmfi", "dmfi_effectdelay", oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_effectdelay", f);
|
||||||
|
SendMessageToPC(oUser, "Settings: Effect Delay: "+FloatToString(f));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("DMFI Default Settings Initialized", oUser, FALSE);
|
||||||
|
// SendMessageToPC(oUser, "DMFI Default Settings Initialized");
|
||||||
|
|
||||||
|
//Setting FOUR campaign variables so 1st use will be slow.
|
||||||
|
//Recommend initializing your preferences with no players or
|
||||||
|
//while there is NO fighting.
|
||||||
|
// SetLocalInt(oUser, "dmfi_initialized", 1);
|
||||||
|
SetDMFIPersistentInt("dmfi", "Settings", 1, oUser);
|
||||||
|
|
||||||
|
SetCustomToken(20781, "5");
|
||||||
|
SetLocalInt(oUser, "dmfi_alignshift", 5);
|
||||||
|
SetDMFIPersistentInt("dmfi", "dmfi_alignshift", 5, oUser);
|
||||||
|
SendMessageToPC(oUser, "Settings: Alignment shift: 5");
|
||||||
|
|
||||||
|
SetCustomToken(20783, "Single Target");
|
||||||
|
SetLocalInt(oUser, "dmfi_buff_party", 0);
|
||||||
|
SetDMFIPersistentInt("dmfi", "dmfi_buff_party", 0, oUser);
|
||||||
|
SendMessageToPC(oUser, "Settings: Buff set to Single Target: ");
|
||||||
|
|
||||||
|
SetCustomToken(20782, "Low");
|
||||||
|
SetLocalString(oUser, "dmfi_buff_level", "LOW");
|
||||||
|
SetDMFIPersistentString("dmfi", "dmfi_buff_level", "LOW", oUser);
|
||||||
|
SendMessageToPC(oUser, "Settings: Buff Level set to LOW: ");
|
||||||
|
|
||||||
|
SetLocalInt(oUser, "dmfi_dicebag", 0);
|
||||||
|
SetCustomToken(20681, "Private");
|
||||||
|
SetDMFIPersistentInt("dmfi", "dmfi_dicebag", 0, oUser);
|
||||||
|
SendMessageToPC(oUser, "Settings: Dicebag Rolls set to PRIVATE");
|
||||||
|
|
||||||
|
SetLocalInt(oUser, "", 0);
|
||||||
|
SetDMFIPersistentInt("dmfi", "dmfi_safe_factions", 0, oUser);
|
||||||
|
SendMessageToPC(oUser, "Settings: Factions set to BW base behavior");
|
||||||
|
|
||||||
|
SetLocalFloat(oUser, "dmfi_reputation", 5.0);
|
||||||
|
SetCustomToken(20784, "5");
|
||||||
|
SetDMFIPersistentFloat("dmfi", "dmfi_reputation", 5.0, oUser);
|
||||||
|
SendMessageToPC(oUser, "Settings: Reputation adjustment: 5");
|
||||||
|
|
||||||
|
SetDMFIPersistentFloat("dmfi", "dmfi_effectduration", 60.0, oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_effectduration", 60.0);
|
||||||
|
SetDMFIPersistentFloat("dmfi", "dmfi_sound_delay", 0.2, oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_sound_delay", 0.2);
|
||||||
|
SetDMFIPersistentFloat("dmfi", "dmfi_beamduration", 5.0, oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_beamduration", 5.0);
|
||||||
|
SetDMFIPersistentFloat("dmfi", "dmfi_stunduration", 1000.0, oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_stunduration", 1000.0);
|
||||||
|
SetDMFIPersistentFloat("dmfi", "dmfi_saveamount", 5.0, oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_saveamount", 5.0);
|
||||||
|
SetDMFIPersistentFloat("dmfi", "dmfi_effectdelay", 1.0, oUser);
|
||||||
|
SetLocalFloat(oUser, "dmfi_effectdelay", 1.0);
|
||||||
|
|
||||||
|
SendMessageToPC(oUser, "Settings: Effect Duration: 60.0");
|
||||||
|
SendMessageToPC(oUser, "Settings: Effect Delay: 1.0");
|
||||||
|
SendMessageToPC(oUser, "Settings: Beam Duration: 5.0");
|
||||||
|
SendMessageToPC(oUser, "Settings: Stun Duration: 1000.0");
|
||||||
|
SendMessageToPC(oUser, "Settings: Sound Delay: 0.2");
|
||||||
|
SendMessageToPC(oUser, "Settings: Save Adjustment: 5.0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//********************************END INITIALIZATION***************************
|
||||||
|
|
||||||
|
// inits for all users (DM & player)
|
||||||
|
if (GetLocalInt(oUser, "dmfi_initialized")!=1)
|
||||||
|
{
|
||||||
|
int bEmotesMuted;
|
||||||
|
if (GetDMFIPersistentInt("dmfi", "Settings", oUser)==1)
|
||||||
|
{
|
||||||
|
bEmotesMuted = GetDMFIPersistentInt("dmfi", "dmfi_emotemute", oUser);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bEmotesMuted = DMFI_DEFAULT_EMOTES_MUTED;
|
||||||
|
SetDMFIPersistentInt("dmfi", "dmfi_emotemute", bEmotesMuted, oUser);
|
||||||
|
}
|
||||||
|
SetLocalInt(oUser, "hls_emotemute", bEmotesMuted);
|
||||||
|
SendMessageToPC(oUser, "Settings: Emotes "+(bEmotesMuted ? "muted" : "unmuted"));
|
||||||
|
|
||||||
|
SetLocalObject(oUser, "dmfi_VoiceTarget", OBJECT_INVALID);
|
||||||
|
SendMessageToPC(oUser, "Settings: Voice throw target cleared");
|
||||||
|
|
||||||
|
SetLocalObject(oUser, "dmfi_univ_target", oUser);
|
||||||
|
SendMessageToPC(oUser, "Settings: Command target set to self");
|
||||||
|
|
||||||
|
SetLocalInt(oUser, "dmfi_initialized", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE; // no errors detected
|
||||||
|
}
|
||||||
|
|
||||||
31
src/dmfi/dmfi_onclienter.nss
Normal file
31
src/dmfi/dmfi_onclienter.nss
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: 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();
|
||||||
|
|
||||||
|
effect eGhost = SupernaturalEffect( EffectCutsceneGhost());
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eGhost,oUser);
|
||||||
|
|
||||||
|
if(GetIsDM(oUser) == TRUE)
|
||||||
|
{
|
||||||
|
SetLocalInt(oUser,"cstrlvl",20);
|
||||||
|
}
|
||||||
|
|
||||||
|
// do any other module OnClientEnter work here
|
||||||
|
ExecuteScript("x3_mod_def_enter", OBJECT_SELF);
|
||||||
|
|
||||||
|
// initialize DMFI
|
||||||
|
dmfiInitialize(oUser);
|
||||||
|
}
|
||||||
29
src/dmfi/dmfi_onmodhb.nss
Normal file
29
src/dmfi/dmfi_onmodhb.nss
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
#include "dmfi_db_inc"
|
||||||
|
|
||||||
|
const int FLUSH_INTERVAL = 30; // seconds between database flushes to disk
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// see if database is "dirty" (changed since last flush)
|
||||||
|
if (IsDMFIPersistentDataDirty("dmfi"))
|
||||||
|
{
|
||||||
|
// it is, so check if time to flush database
|
||||||
|
object oMod = GetModule();
|
||||||
|
int iTick = GetLocalInt(oMod, "DMFI_MODULE_HEARTBEAT_TICK");
|
||||||
|
int iSecsSinceFlush = iTick * 6;
|
||||||
|
if (iSecsSinceFlush >= FLUSH_INTERVAL)
|
||||||
|
{
|
||||||
|
FlushDMFIPersistentData("dmfi");
|
||||||
|
iTick = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iTick++;
|
||||||
|
}
|
||||||
|
SetLocalInt(oMod, "DMFI_MODULE_HEARTBEAT_TICK", iTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
// do any other module OnHeartbeat work here
|
||||||
|
ExecuteScript("x3_mod_def_hb", OBJECT_SELF);
|
||||||
|
}
|
||||||
3696
src/dmfi/dmfi_onplychat.nss
Normal file
3696
src/dmfi/dmfi_onplychat.nss
Normal file
File diff suppressed because it is too large
Load Diff
463
src/dmfi/dmfi_onrest.nss
Normal file
463
src/dmfi/dmfi_onrest.nss
Normal file
@@ -0,0 +1,463 @@
|
|||||||
|
/*DMFI Rest System Alpha by hahnsoo
|
||||||
|
|
||||||
|
CONTENTS
|
||||||
|
--------
|
||||||
|
Placeables>>Special>>Custom 5 - DMFI Bed Roll, DMFI Campfire, DMFI Invisible
|
||||||
|
Rest Object, DMFI Tent
|
||||||
|
|
||||||
|
Items>>Special>>Custom5 - DMFI Bed Roll (100 gp), DMFI Firewood (1 gp), DMFI
|
||||||
|
Portable Tent (500 gp) (different gp values for different situations)
|
||||||
|
|
||||||
|
Scripts - dmfi_onrest
|
||||||
|
(Yup, that's it)
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
This is a robust and versatile rest system that incorporates a LOT of options.
|
||||||
|
Perhaps too many, I don't know. I tried to find everything that folks would
|
||||||
|
possibly want in a resting system. The most important "feature" is the rest
|
||||||
|
conversation menu, which governs for both DM and Player the kind of resting that
|
||||||
|
is allowed.
|
||||||
|
|
||||||
|
The ways you can control rest in this system are:
|
||||||
|
1) Global vs. Local - Restrict or release restrictions on resting based on world
|
||||||
|
settings or on a per-area basis
|
||||||
|
2) Unlimited vs. Limited vs. No Rest - Have the Players rest at any time they'd
|
||||||
|
like. Or Limit them according to certain parameters and toggles. Or don't
|
||||||
|
allow them to rest at all. You can set these both globally and locally
|
||||||
|
(Unlimited and No Rest areas).
|
||||||
|
3) Time restriction - The staple of most simple rest restrictions. You can limit
|
||||||
|
resting per 1, 2, 4, 8, 12, or 24 in-game hours, and the amount of real-time
|
||||||
|
minutes are calculated for the DM. Again, you can set these both globally
|
||||||
|
and locally.
|
||||||
|
4) Placeables - Popularized by Demetrious's Supply-Based Rest, this allows you
|
||||||
|
to restrict resting according to proximity to objects. It allows you to use
|
||||||
|
DMFI rest objects (tag = dmfi_restobject), campfires, bedrolls, beds, tents
|
||||||
|
(a "Name-based" rest placeable), and toggles to include/exclude certain
|
||||||
|
classes that typically don't care about such niceties.
|
||||||
|
5) Armor Restrictions - I'm not quite fond of this particular one, but it is a
|
||||||
|
standard feature of many rest systems and thus included in the package.
|
||||||
|
Allows you to set what weight of armor allows a PC to rest.
|
||||||
|
6) Set Hit Point Restrictions - Unlike the other restrictions, this does NOT
|
||||||
|
prevent resting. What it does is determine how many hitpoints are regained
|
||||||
|
upon resting, from a gradient of no hitpoints to all hitpoint, and some
|
||||||
|
interesting options in between (1 HP per level, per 3rd edition, which
|
||||||
|
skews against fighter classes and CON based HP gain, which skews in favor of
|
||||||
|
lower level characters).
|
||||||
|
7) Toggle Spell Memorization - This converts the "rest" into a "pseudorest"
|
||||||
|
which only heals HP. Useful for a "no spell memorization" zone locally, not
|
||||||
|
much use globally.
|
||||||
|
8) Various other "fluff" settings (Snoring, the rest conversation menu,
|
||||||
|
immobilized resting, floating text feedback).
|
||||||
|
|
||||||
|
There is also a "big red button" option that simply full rests all PCs in the
|
||||||
|
area. Useful to quickly work around rest restrictions that you have previously
|
||||||
|
set up.
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
Change your OnRest event script to the dmfi_onrest script. Or you can do an
|
||||||
|
external execute script call by using ExecuteScript("dmfi_onrest", OBJECT_SELF);
|
||||||
|
in your current script.
|
||||||
|
|
||||||
|
The areas in your module should NOT have the "No Rest" box checked, in the areas
|
||||||
|
which you wish to use this system.
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
All configuration of the system is done in-game as a DM. To bring up the Rest
|
||||||
|
Configuration Menu, press R or the rest button.
|
||||||
|
The conversation will detail the settings you have in the area (whether you are
|
||||||
|
using the default Global settings or using the Local area settings to override)
|
||||||
|
and the particular restrictions that you have set.
|
||||||
|
|
||||||
|
Settings are stored Persistently using the Bioware Database, per the DMFI W&W
|
||||||
|
default persistence options. If you want to use another database system, simply
|
||||||
|
edit the the dmfi_db_inc wrapper functions to your liking.
|
||||||
|
|
||||||
|
Unlimited Rest means just that: No restrictions. You may have global
|
||||||
|
restrictions set up, but as long as Unlimited rest is set globally or locally,
|
||||||
|
they are ignored.
|
||||||
|
No Rest means just that: No resting allowed, regardless of restrictions.
|
||||||
|
Limited Rest means that the restrictions you have set globally or locally are in
|
||||||
|
effect. You can restrict resting as stated above in the Description.
|
||||||
|
|
||||||
|
When you set any [LOCAL] Area variables, you automatically set the area to
|
||||||
|
"override" the global rest restrictions. This means that this area follows its
|
||||||
|
own rules, and isn't governed by the global rules. Setting the [LOCAL] Area
|
||||||
|
restrictions will copy the current global restriction variables, but after that,
|
||||||
|
the only way to go back to "global" is to select "Use default [GLOBAL] Module
|
||||||
|
settings"
|
||||||
|
Tip: The most useful way to use this is to simply set areas as Unlimited Rest or
|
||||||
|
No Rest, say an Inn Room or a combat zone, respectively.
|
||||||
|
|
||||||
|
Player Notes
|
||||||
|
------------
|
||||||
|
If you are using the DMFI Rest Menu (on by default), the rest restrictions (if
|
||||||
|
any) are displayed on your Rest Conversation Menu, telling you why you can't
|
||||||
|
rest (if you are restricted). You also have the option to access both the DMFI
|
||||||
|
Dicebag and the DMFI Emote wand directly from the Rest Menu. This allows you to
|
||||||
|
use emotes or dice checks WITHOUT having that silly "Use Unique Power"
|
||||||
|
animation.
|
||||||
|
|
||||||
|
Included in this package is a way to do "Alternate Resting Animations". These
|
||||||
|
animations simply change the way you appear when you rest. Since they use the
|
||||||
|
ForceRest() function, it isn't a "true" rest... rather it sets you for a certain
|
||||||
|
amount of time (equal to a normal rest) as un-moveable, and applies the rest at
|
||||||
|
the end of that time. This just means you don't get the little egg timer.
|
||||||
|
|
||||||
|
This is an ALPHA release, and I'm pretty sure I don't know everything about
|
||||||
|
Resting systems in the universe. I've tried to incorporate nearly all of the
|
||||||
|
elements I've seen in other available resting systems and encorporate them into
|
||||||
|
a small (single script), DMFI-integrated package.
|
||||||
|
|
||||||
|
I would greatly appreciate feedback, suggestions, additions, omissions, bug
|
||||||
|
reports, whatever. Send them to me at hahns_shin@hotmail.com.*/
|
||||||
|
|
||||||
|
#include "dmfi_db_inc"
|
||||||
|
//This function calculates the resting duration based on PC Hit Dice
|
||||||
|
//Based off of restduration.2da
|
||||||
|
void FloatyText(string sText, object oPC, int iSettings)
|
||||||
|
{
|
||||||
|
if (!(iSettings & 0x40000000))
|
||||||
|
FloatingTextStringOnCreature(sText, oPC, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetRestDuration(object oPC)
|
||||||
|
{
|
||||||
|
return 10.0f + 0.5f * IntToFloat(GetHitDice(oPC));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is used as a wrapper for the Rest VFX Object
|
||||||
|
void DoRestVFX(object oPC, float fDuration, int nEffect) {
|
||||||
|
effect eEffect;
|
||||||
|
if (nEffect == -1) {
|
||||||
|
eEffect = EffectCutsceneImmobilize();
|
||||||
|
} else {
|
||||||
|
eEffect = EffectVisualEffect(nEffect);
|
||||||
|
}
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eEffect), oPC, fDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//This function adds the Blindness/Snore effects
|
||||||
|
//Also adds cutscene immobilize to prevent movement
|
||||||
|
//Snoring should only occur at start, then follows on the module's hb
|
||||||
|
void ApplyRestVFX(object oPC, int iSettings)
|
||||||
|
{
|
||||||
|
object oRestVFX = GetObjectByTag("dmfi_restvfxobject");
|
||||||
|
effect eSnore = EffectVisualEffect(VFX_IMP_SLEEP); //Sleepy "ZZZ"s
|
||||||
|
float fDuration = GetRestDuration(oPC);
|
||||||
|
float fSeconds = 6.0f;
|
||||||
|
if (!(iSettings & 0x80000000)) //Immobile Resting flag
|
||||||
|
{
|
||||||
|
// Pass a -1 for EffectCutsceneImmobilize.
|
||||||
|
// For a visual effect, simply pass the VFX constant.
|
||||||
|
AssignCommand(oRestVFX, DoRestVFX(oPC, fDuration, -1));
|
||||||
|
}
|
||||||
|
if (!(iSettings & 0x20000000)) //VFX flag
|
||||||
|
{
|
||||||
|
// AssignCommand(oRestVFX, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eBlind), oPC, fDuration));
|
||||||
|
AssignCommand(oRestVFX, DoRestVFX(oPC, fDuration, VFX_DUR_BLACKOUT));
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eSnore, oPC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Removes blindness & immobilize -- Merle
|
||||||
|
void RemoveRestVFX(object oPC) {
|
||||||
|
object oRestVFX = GetObjectByTag("dmfi_restvfxobject");
|
||||||
|
effect eEffect = GetFirstEffect(oPC);
|
||||||
|
while (GetIsEffectValid(eEffect)) {
|
||||||
|
if (GetEffectCreator(eEffect) == oRestVFX) {
|
||||||
|
RemoveEffect(oPC, eEffect);
|
||||||
|
}
|
||||||
|
eEffect = GetNextEffect(oPC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//This function gets the "Final HP" available to the PC after resting
|
||||||
|
int CalculateFinalHitPoints(object oPC, int iSettings)
|
||||||
|
{
|
||||||
|
int iHP = (iSettings & 0x0f000000);
|
||||||
|
switch(iHP)
|
||||||
|
{
|
||||||
|
case 0x01000000: return 0; break;
|
||||||
|
case 0x02000000: return GetHitDice(oPC); break;
|
||||||
|
case 0x03000000: return GetAbilityScore(oPC, ABILITY_CONSTITUTION); break;
|
||||||
|
case 0x04000000: return GetMaxHitPoints(oPC)/10; break;
|
||||||
|
case 0x05000000: return GetMaxHitPoints(oPC)/4; break;
|
||||||
|
case 0x06000000: return GetMaxHitPoints(oPC)/2; break;
|
||||||
|
case 0x07000000: return GetMaxHitPoints(oPC); break;
|
||||||
|
default: return GetMaxHitPoints(oPC); break;
|
||||||
|
}
|
||||||
|
return GetMaxHitPoints(oPC);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveMagicalEffects(object oPC)
|
||||||
|
{
|
||||||
|
effect eEffect = GetFirstEffect(oPC);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
if (GetEffectSubType(eEffect) == SUBTYPE_MAGICAL)
|
||||||
|
RemoveEffect(oPC, eEffect);
|
||||||
|
eEffect = GetNextEffect(oPC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//This function simulates a rest without restoring spells
|
||||||
|
void DoPseudoRest(object oPC, int iSettings, int iSpells = FALSE)
|
||||||
|
{
|
||||||
|
effect eSnore = EffectVisualEffect(VFX_IMP_SLEEP);
|
||||||
|
effect eBlind = EffectVisualEffect(VFX_DUR_BLACKOUT);
|
||||||
|
effect eStop = EffectCutsceneImmobilize();
|
||||||
|
float fDuration = GetRestDuration(oPC);
|
||||||
|
float fSeconds = 6.0f;
|
||||||
|
int iAnimation = GetLocalInt(oPC, "dmfi_r_alternate");
|
||||||
|
if (!iAnimation)
|
||||||
|
iAnimation = ANIMATION_LOOPING_SIT_CROSS;
|
||||||
|
AssignCommand(oPC, PlayAnimation(iAnimation, 1.0f, fDuration));
|
||||||
|
DelayCommand(0.1, SetCommandable(FALSE, oPC));
|
||||||
|
DelayCommand(fDuration, SetCommandable(TRUE, oPC));
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eStop), oPC, fDuration);
|
||||||
|
if (!(iSettings & 0x20000000) && iAnimation != ANIMATION_LOOPING_MEDITATE && iAnimation != ANIMATION_LOOPING_WORSHIP) //If the No VFX flag is not set, do VFX
|
||||||
|
{
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eBlind), oPC, fDuration);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eSnore, oPC);
|
||||||
|
while (fSeconds < fDuration)
|
||||||
|
{
|
||||||
|
DelayCommand(fSeconds, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSnore, oPC));
|
||||||
|
fSeconds += 6.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!iSpells)
|
||||||
|
{
|
||||||
|
effect eHeal = EffectHeal(CalculateFinalHitPoints(oPC, iSettings)); //Heal the PC
|
||||||
|
DelayCommand(fDuration + 0.1f, ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC));
|
||||||
|
DelayCommand(fDuration + 0.1f, RemoveMagicalEffects(oPC)); //Remove all magical effects from PC
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DelayCommand(fDuration + 0.1f, ForceRest(oPC));
|
||||||
|
}
|
||||||
|
DeleteLocalInt(oPC, "dmfi_r_alternate");
|
||||||
|
}
|
||||||
|
|
||||||
|
//This function determines if the PC is wearing heavy armor
|
||||||
|
int GetIsWearingHeavyArmor(object oPC, int iSettings)
|
||||||
|
{
|
||||||
|
int iArmor = (iSettings & 0x00f00000);
|
||||||
|
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oPC);
|
||||||
|
int iWeight = GetWeight(oArmor);
|
||||||
|
switch(iArmor)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0x00100000: if (iWeight > 20) return TRUE; break;
|
||||||
|
case 0x00200000: if (iWeight > 60) return TRUE; break;
|
||||||
|
case 0x00300000: if (iWeight > 110) return TRUE; break;
|
||||||
|
case 0x00400000: if (iWeight > 160) return TRUE; break;
|
||||||
|
case 0x00500000: if (iWeight > 310) return TRUE; break;
|
||||||
|
case 0x00600000: if (iWeight > 410) return TRUE; break;
|
||||||
|
case 0x00700000: if (iWeight > 460) return TRUE; break;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//This function determines if the PC is near a resting placeable
|
||||||
|
int GetIsNearRestingObject(object oPC, int iSettings)
|
||||||
|
{
|
||||||
|
if (iSettings & 0x00020000) //Ignore Druid
|
||||||
|
{
|
||||||
|
if (GetLevelByClass(CLASS_TYPE_DRUID, oPC))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (iSettings & 0x00040000) //Ignore Ranger
|
||||||
|
{
|
||||||
|
if (GetLevelByClass(CLASS_TYPE_RANGER, oPC))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (iSettings & 0x00080000) //Ignore Barb
|
||||||
|
{
|
||||||
|
if (GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
object oPlaceable = GetFirstObjectInShape(SHAPE_SPHERE, 6.0f, GetLocation(oPC), TRUE, OBJECT_TYPE_PLACEABLE);
|
||||||
|
while (GetIsObjectValid(oPlaceable))
|
||||||
|
{
|
||||||
|
if (!(iSettings & 0x00001000) && GetTag(oPlaceable) == "dmfi_rest") //DMFI Placeables: by default, ON
|
||||||
|
return TRUE;
|
||||||
|
if ((iSettings & 0x00002000) && GetStringLowerCase(GetName(oPlaceable)) == "campfire") //Campfires
|
||||||
|
return TRUE;
|
||||||
|
if ((iSettings & 0x00004000) && (GetStringLowerCase(GetName(oPlaceable)) == "bed roll" || GetStringLowerCase(GetName(oPlaceable)) == "bedroll")) //Bed rolls
|
||||||
|
return TRUE;
|
||||||
|
if ((iSettings & 0x00008000) && GetStringLowerCase(GetName(oPlaceable)) == "bed") //beds
|
||||||
|
return TRUE;
|
||||||
|
if ((iSettings & 0x00010000) && GetStringLowerCase(GetName(oPlaceable)) == "tent") //tents
|
||||||
|
return TRUE;
|
||||||
|
oPlaceable = GetNextObjectInShape(SHAPE_SPHERE, 6.0f, GetLocation(oPC), TRUE, OBJECT_TYPE_PLACEABLE);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updated to allow 6 hour breaks and to pass in a percentage if rest is interrupted
|
||||||
|
void SetNextRestTime(object oPC, int iSettings, float fPercentage = 1.0)
|
||||||
|
{
|
||||||
|
if (fPercentage > 1.0 || fPercentage <= 0.0) {
|
||||||
|
fPercentage = 1.0;
|
||||||
|
}
|
||||||
|
int iHours = (iSettings & 0x00000f00);
|
||||||
|
int iTime = GetTimeHour() + GetCalendarDay() * 24 + GetCalendarMonth() * 24 * 28 + GetCalendarYear() * 24 * 28 * 12;
|
||||||
|
|
||||||
|
switch(iHours)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0x00000100: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(1) * fPercentage)); break;
|
||||||
|
case 0x00000200: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(2) * fPercentage)); break;
|
||||||
|
case 0x00000300: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(4) * fPercentage)); break;
|
||||||
|
case 0x00000400: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(6) * fPercentage)); break;
|
||||||
|
case 0x00000500: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(8) * fPercentage)); break;
|
||||||
|
case 0x00000600: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(12) * fPercentage)); break;
|
||||||
|
case 0x00000700: SetLocalInt(oPC, "dmfi_r_nextrest", iTime + FloatToInt(IntToFloat(24) * fPercentage)); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//This function determines whether or not you can rest.
|
||||||
|
int DMFI_CanIRest(object oPC, int iSettings)
|
||||||
|
{
|
||||||
|
if (GetIsDM(oPC)) return TRUE;
|
||||||
|
if (iSettings & 0x00000002) //No Rest Override
|
||||||
|
{
|
||||||
|
if (iSettings & 0x00000080)
|
||||||
|
FloatyText("This is a No Rest area", oPC, iSettings);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!(iSettings & 0x00000001)) //Unlimited Rest Override
|
||||||
|
{
|
||||||
|
if (iSettings & 0x00000080)
|
||||||
|
FloatyText("This is an Unlimited Rest area", oPC, iSettings);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if ((iSettings & 0x00000004) && (iSettings & 0x00000001)) //Time restriction
|
||||||
|
{
|
||||||
|
int iTime = GetTimeHour() + GetCalendarDay() * 24 + GetCalendarMonth() * 24 * 28 + GetCalendarYear() * 24 * 28 * 12;
|
||||||
|
if (iTime < GetLocalInt(oPC, "dmfi_r_nextrest"))
|
||||||
|
{
|
||||||
|
FloatyText("You cannot rest at this time. You may rest again in " + IntToString(GetLocalInt(oPC, "dmfi_r_nextrest") - iTime) + " hours.", oPC, iSettings);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((iSettings & 0x00000008) && (iSettings & 0x00000001)) //Placeable restriction
|
||||||
|
{
|
||||||
|
if (!GetIsNearRestingObject(oPC, iSettings))
|
||||||
|
{
|
||||||
|
FloatyText("You are not near a rest placeable", oPC, iSettings);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((iSettings & 0x00000010) && (iSettings & 0x00000001)) //Armor restriction
|
||||||
|
{
|
||||||
|
if (GetIsWearingHeavyArmor(oPC, iSettings))
|
||||||
|
{
|
||||||
|
FloatyText("Your current armor is too heavy to rest", oPC, iSettings);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetLastPCRested();
|
||||||
|
object oArea = GetArea(oPC);
|
||||||
|
int iSettings;
|
||||||
|
int iModSettings = GetDMFIPersistentInt("dmfi", "dmfi_r_");
|
||||||
|
int iAreaSettings = GetDMFIPersistentInt("dmfi", "dmfi_r_" + GetTag(oArea));
|
||||||
|
if (iAreaSettings & 0x00000080)
|
||||||
|
{
|
||||||
|
iSettings = iAreaSettings;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iSettings = iModSettings;
|
||||||
|
}
|
||||||
|
SetLocalInt(oPC, "dmfi_r_settings", iSettings);
|
||||||
|
|
||||||
|
if (GetLastRestEventType()==REST_EVENTTYPE_REST_STARTED)
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_norest", !(DMFI_CanIRest(oPC, iSettings)));
|
||||||
|
SetLocalInt(oPC, "dmfi_r_hitpoints", GetCurrentHitPoints(oPC));
|
||||||
|
if (GetIsDM(oPC) || (!(iSettings & 0x10000000) && !GetLocalInt(oPC, "dmfi_r_bypass")))
|
||||||
|
{ //If the Rest Conversation variable is set, then activate the rest conversation here.
|
||||||
|
AssignCommand(oPC, ClearAllActions());
|
||||||
|
SetLocalString(oPC, "dmfi_univ_conv", "rest");
|
||||||
|
AssignCommand(oPC, ActionStartConversation(oPC, "dmfi_universal", TRUE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (GetLocalInt(oPC, "dmfi_norest")) //PC cannot rest
|
||||||
|
{
|
||||||
|
AssignCommand(oPC, ClearAllActions());
|
||||||
|
DeleteLocalInt(oPC, "dmfi_r_bypass");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((iSettings & 0x00000004) && (iSettings & 0x00000001)) //Time restriction
|
||||||
|
SetNextRestTime(oPC, iSettings);
|
||||||
|
|
||||||
|
if (GetLocalInt(oPC, "dmfi_r_alternate") || ((iSettings & 0x00000040) && (iSettings & 0x00000001)))
|
||||||
|
{
|
||||||
|
AssignCommand(oPC, ClearAllActions());
|
||||||
|
if ((iSettings & 0x00000040) && (iSettings & 0x00000001))
|
||||||
|
FloatyText("You cannot regain your spells in this area",oPC, iSettings);
|
||||||
|
DoPseudoRest(oPC, iSettings, ((iSettings & 0x00000040) && (iSettings & 0x00000001)));
|
||||||
|
DeleteLocalInt(oPC, "dmfi_r_bypass");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!(iSettings & 0x20000000))
|
||||||
|
{ //Rest VFX
|
||||||
|
ApplyRestVFX(oPC, iSettings);
|
||||||
|
}
|
||||||
|
if ((iSettings & 0x00000020) && (iSettings & 0x00000001))
|
||||||
|
{ //Auto Party Drop
|
||||||
|
FloatyText("You have been removed from the party to prevent rest canceling",oPC, iSettings);
|
||||||
|
RemoveFromParty(oPC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (GetLastRestEventType()==REST_EVENTTYPE_REST_CANCELLED)
|
||||||
|
{
|
||||||
|
// Make sure that resting has been initialized and the start time has been set. Otherwise, the Cancelled Rest Event was fired by
|
||||||
|
// the Resting conversation.
|
||||||
|
if (GetLocalInt(oPC, "dmfi_r_init"))
|
||||||
|
{
|
||||||
|
int iTime = GetTimeSecond() + GetTimeMinute() * 60 + GetTimeHour() * 3600 + GetCalendarDay() * 24 * 3600 + GetCalendarMonth() *3600 * 24 * 28 + GetCalendarYear() * 24 * 28 * 12 * 3600;
|
||||||
|
int nTimeRested = iTime - GetLocalInt(oPC, "dmfi_r_startseconds");
|
||||||
|
int nFullTime = FloatToInt(GetRestDuration(oPC));
|
||||||
|
float fPercentage = IntToFloat(nTimeRested) / IntToFloat(nFullTime);
|
||||||
|
SetNextRestTime(oPC, iSettings, fPercentage);
|
||||||
|
// SendMessageToPC(oPC, "Rest interrupted; resting for " + IntToString(nTimeRested) + " out of " + IntToString(nFullTime) + " seconds (" + FloatToString(fPercentage) + "%).");
|
||||||
|
SetLocalInt(oPC, "dmfi_r_init", FALSE);
|
||||||
|
if ((iSettings & 0x00000020) && GetCurrentHitPoints(oPC) > GetLocalInt(oPC, "dmfi_r_hitpoints") && iSettings & 0x00000001) //HP restriction
|
||||||
|
{
|
||||||
|
effect eDam = EffectDamage(GetMaxHitPoints(oPC) - GetLocalInt(oPC, "dmfi_r_hitpoints"));
|
||||||
|
FloatyText("Your hitpoints have been reset",oPC, iSettings);
|
||||||
|
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oPC));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RemoveRestVFX(oPC);
|
||||||
|
}
|
||||||
|
else if (GetLastRestEventType()==REST_EVENTTYPE_REST_FINISHED)
|
||||||
|
{
|
||||||
|
if ((iSettings & 0x00000020) && (iSettings & 0x00000001)) //HP restriction
|
||||||
|
{
|
||||||
|
int iDam = GetMaxHitPoints(oPC) - GetLocalInt(oPC, "dmfi_r_hitpoints") - CalculateFinalHitPoints(oPC, iSettings);
|
||||||
|
if (iDam > 0)
|
||||||
|
{
|
||||||
|
effect eDam = EffectDamage(iDam);
|
||||||
|
FloatyText("You gain back limited HP from this rest",oPC, iSettings);
|
||||||
|
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oPC));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DeleteLocalInt(oPC, "dmfi_r_bypass");
|
||||||
|
}
|
||||||
117
src/dmfi/dmfi_plchlishk_i.nss
Normal file
117
src/dmfi/dmfi_plchlishk_i.nss
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: DMFI - internal player chat listener hooking include
|
||||||
|
//:: dmfi_plchlishk_i
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Include file containing routines for managing the internal DMFI chain of
|
||||||
|
"listeners", which are now implemented as OnPlayerChat event handlers rather
|
||||||
|
than creatures.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: tsunami282
|
||||||
|
//:: Created On: 2008.03.24
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
const int DMFI_LISTEN_ON_CHANNEL_TALK = 1;
|
||||||
|
const int DMFI_LISTEN_ON_CHANNEL_WHISPER = 1;
|
||||||
|
const int DMFI_LISTEN_ON_CHANNEL_SHOUT = 1;
|
||||||
|
const int DMFI_LISTEN_ON_CHANNEL_DM = 1;
|
||||||
|
const int DMFI_LISTEN_ON_CHANNEL_PARTY = 1;
|
||||||
|
|
||||||
|
const string DMFI_EAVESDROP_HOOK_VARNAME = "dmfi_Eavesdrop";
|
||||||
|
|
||||||
|
const float WHISPER_DISTANCE = 1.0;
|
||||||
|
const float TALK_DISTANCE = 30.0;
|
||||||
|
|
||||||
|
string sHookTypeVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_Type"; // 1=PC (says), 2=NPC/location (hears)
|
||||||
|
string sHookCreatureVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_Creature"; // must be valid for type 1, for type 2 object_invalid means location only
|
||||||
|
string sHookRangeModeVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_RangeMode"; // listening range: for type 1, 0=pc only, 1=pc's party; for type 2, 0=earshot, 1=area, 2=module
|
||||||
|
string sHookLocationVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_Location"; // for type 2, location of "listening post"
|
||||||
|
string sHookChannelsVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_Channels"; // bitmask of TALKVOLUME channels to listen to
|
||||||
|
string sHookOwnerVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_Owner"; // unique ID of owner of this hook (he who will get the captured text)
|
||||||
|
string sHookBcastDMsVarname = DMFI_EAVESDROP_HOOK_VARNAME + "_BcastDMs"; // 0=relay message to owner only, 1=broadcast to all DMs
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void RemoveListenerHook(int hooknum)
|
||||||
|
{
|
||||||
|
int hooktype;
|
||||||
|
object hookcreature;
|
||||||
|
location hooklocation;
|
||||||
|
int hookchannels;
|
||||||
|
object hookowner;
|
||||||
|
int hookparty, hookbcast;
|
||||||
|
|
||||||
|
int iHook = hooknum;
|
||||||
|
string siHook = "", siHookN = "";
|
||||||
|
object oMod = GetModule();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
siHook = IntToString(iHook);
|
||||||
|
siHookN = IntToString(iHook+1);
|
||||||
|
|
||||||
|
hooktype = GetLocalInt(oMod, sHookTypeVarname+siHookN);
|
||||||
|
if (hooktype != 0)
|
||||||
|
{
|
||||||
|
hookcreature = GetLocalObject(oMod, sHookCreatureVarname+siHookN);
|
||||||
|
hooklocation = GetLocalLocation(oMod, sHookLocationVarname+siHookN);
|
||||||
|
hookchannels = GetLocalInt(oMod, sHookChannelsVarname+siHookN);
|
||||||
|
hookowner = GetLocalObject(oMod, sHookOwnerVarname+siHookN);
|
||||||
|
hookparty = GetLocalInt(oMod, sHookRangeModeVarname+siHookN);
|
||||||
|
hookbcast = GetLocalInt(oMod, sHookBcastDMsVarname+siHookN);
|
||||||
|
|
||||||
|
SetLocalInt(oMod, sHookTypeVarname+siHook, hooktype);
|
||||||
|
SetLocalObject(oMod, sHookCreatureVarname+siHook, hookcreature);
|
||||||
|
SetLocalLocation(oMod, sHookLocationVarname+siHook, hooklocation);
|
||||||
|
SetLocalInt(oMod, sHookChannelsVarname+siHook, hookchannels);
|
||||||
|
SetLocalObject(oMod, sHookOwnerVarname+siHook, hookowner);
|
||||||
|
SetLocalInt(oMod, sHookRangeModeVarname+siHook, hookparty);
|
||||||
|
SetLocalInt(oMod, sHookBcastDMsVarname+siHook, hookbcast);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DeleteLocalInt(oMod, sHookTypeVarname+siHook);
|
||||||
|
DeleteLocalObject(oMod, sHookCreatureVarname+siHook);
|
||||||
|
DeleteLocalLocation(oMod, sHookLocationVarname+siHook);
|
||||||
|
DeleteLocalInt(oMod, sHookChannelsVarname+siHook);
|
||||||
|
DeleteLocalObject(oMod, sHookOwnerVarname+siHook);
|
||||||
|
DeleteLocalInt(oMod, sHookRangeModeVarname+siHook);
|
||||||
|
DeleteLocalInt(oMod, sHookBcastDMsVarname+siHook);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iHook++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
int AppendListenerHook(int hooktype, object hookcreature, location hooklocation,
|
||||||
|
int hookchannels, int hookparty, int hookbcast, object hookowner)
|
||||||
|
{
|
||||||
|
int iHook = 0;
|
||||||
|
|
||||||
|
if (hooktype != 0)
|
||||||
|
{
|
||||||
|
int iHookType;
|
||||||
|
string siHook = "";
|
||||||
|
object oMod = GetModule();
|
||||||
|
iHook = 1;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
siHook = IntToString(iHook);
|
||||||
|
iHookType = GetLocalInt(oMod, sHookTypeVarname+siHook);
|
||||||
|
if (iHookType == 0) break; // end of list
|
||||||
|
iHook++;
|
||||||
|
}
|
||||||
|
SetLocalInt(oMod, sHookTypeVarname+siHook, hooktype);
|
||||||
|
SetLocalObject(oMod, sHookCreatureVarname+siHook, hookcreature);
|
||||||
|
SetLocalLocation(oMod, sHookLocationVarname+siHook, hooklocation);
|
||||||
|
SetLocalInt(oMod, sHookChannelsVarname+siHook, hookchannels);
|
||||||
|
SetLocalObject(oMod, sHookOwnerVarname+siHook, hookowner);
|
||||||
|
SetLocalInt(oMod, sHookRangeModeVarname+siHook, hookparty);
|
||||||
|
SetLocalInt(oMod, sHookBcastDMsVarname+siHook, hookbcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
return iHook;
|
||||||
|
}
|
||||||
|
|
||||||
3920
src/dmfi/dmfi_plychat_exe.nss
Normal file
3920
src/dmfi/dmfi_plychat_exe.nss
Normal file
File diff suppressed because it is too large
Load Diff
142
src/dmfi/dmfi_plychat_inc.nss
Normal file
142
src/dmfi/dmfi_plychat_inc.nss
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
|
||||||
|
// DMFI OnPlayerChat routines :: event hooking functions
|
||||||
|
//
|
||||||
|
// history
|
||||||
|
// 2008.03.23 tsunami282 - created.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "dmfi_arrays_inc"
|
||||||
|
|
||||||
|
const string DMFI_CHATHOOK_HANDLE_ARRAYNAME = "DMFI_CHATHOOK_HANDLE";
|
||||||
|
const string DMFI_CHATHOOK_SCRIPT_ARRAYNAME = "DMFI_CHATHOOK_SCRIPT";
|
||||||
|
const string DMFI_CHATHOOK_RUNNER_ARRAYNAME = "DMFI_CHATHOOK_RUNNER";
|
||||||
|
const string DMFI_CHATHOOK_CHANNELS_ARRAYNAME = "DMFI_CHATHOOK_CHANNELS";
|
||||||
|
const string DMFI_CHATHOOK_LISTENALL_ARRAYNAME = "DMFI_CHATHOOK_LISTENALL";
|
||||||
|
const string DMFI_CHATHOOK_SPEAKER_ARRAYNAME = "DMFI_CHATHOOK_SPEAKER";
|
||||||
|
const string DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME = "DMFI_CHATHOOK_AUTOREMOVE";
|
||||||
|
const string DMFI_CHATHOOK_PREVHANDLE_VARNAME = "DMFI_CHATHOOK_PREVHANDLE";
|
||||||
|
|
||||||
|
int DMFI_CHANNELMASK_TALK = (1 << TALKVOLUME_TALK);
|
||||||
|
int DMFI_CHANNELMASK_WHISPER = (1 << TALKVOLUME_WHISPER);
|
||||||
|
int DMFI_CHANNELMASK_SHOUT = (1 << TALKVOLUME_SHOUT);
|
||||||
|
// * this channel not hookable ** int DMFI_CHANNELMASK_SILENT_TALK = (1 << TALKVOLUME_SILENT_TALK);
|
||||||
|
int DMFI_CHANNELMASK_DM = (1 << TALKVOLUME_SILENT_SHOUT);
|
||||||
|
int DMFI_CHANNELMASK_PARTY = (1 << TALKVOLUME_PARTY);
|
||||||
|
// * this channel not hookable ** int DMFI_CHANNELMASK_TELL = (1 << TALKVOLUME_TELL);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void dmfi__init_chathook_data()
|
||||||
|
{
|
||||||
|
object oMod = GetModule();
|
||||||
|
|
||||||
|
if (!GetLocalArrayInitialized(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME))
|
||||||
|
{
|
||||||
|
InitializeLocalArray(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME);
|
||||||
|
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, 1);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, 0);
|
||||||
|
InitializeLocalArray(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME);
|
||||||
|
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, 1);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, 0);
|
||||||
|
InitializeLocalArray(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME);
|
||||||
|
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, 1);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, 0);
|
||||||
|
InitializeLocalArray(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME);
|
||||||
|
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, 1);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, 0);
|
||||||
|
InitializeLocalArray(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME);
|
||||||
|
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, 1);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, 0);
|
||||||
|
InitializeLocalArray(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME);
|
||||||
|
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, 1);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, 0);
|
||||||
|
InitializeLocalArray(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME);
|
||||||
|
SetLocalArrayLowerBound(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, 1);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
//! Adds a callback function to the OnPlayerChat list.
|
||||||
|
//!
|
||||||
|
//! \param sChatHandlerScript name of script to invoke on receiving input
|
||||||
|
//! \param oScriptRunner object to execute the sChatHandlerScript on
|
||||||
|
//! \param maskChannels mask of channels to listen on (defaults to all channels)
|
||||||
|
//! \param bListenAll TRUE to listen to all PC speakers everywhere
|
||||||
|
//! \param oSpeaker if bListenAll is FALSE, creature to listen to (others will be ignored)
|
||||||
|
//! \param bAutoRemove - automatically unhook this chathook after first use
|
||||||
|
//! \return hook handle (needed to remove the hook later); 0 means failed to add the hook
|
||||||
|
int DMFI_ChatHookAdd(string sChatHandlerScript, object oScriptRunner = OBJECT_SELF,
|
||||||
|
int maskChannels = -1, int bListenAll = TRUE, object oSpeaker = OBJECT_INVALID,
|
||||||
|
int bAutoRemove = FALSE)
|
||||||
|
{
|
||||||
|
dmfi__init_chathook_data();
|
||||||
|
|
||||||
|
object oMod = GetModule();
|
||||||
|
|
||||||
|
int iHook = GetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME);
|
||||||
|
iHook++;
|
||||||
|
int hdlHook = GetLocalInt(oMod, DMFI_CHATHOOK_PREVHANDLE_VARNAME);
|
||||||
|
hdlHook++;
|
||||||
|
if (hdlHook < 1) hdlHook = 1; // reserving 0 and negatives
|
||||||
|
// SendMessageToPC(GetFirstPC(), "chathookadd - adding hook #" + IntToString(iHook));
|
||||||
|
SetLocalInt(oMod, DMFI_CHATHOOK_PREVHANDLE_VARNAME, hdlHook);
|
||||||
|
SetLocalArrayInt(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, iHook, hdlHook);
|
||||||
|
SetLocalArrayString(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, iHook, sChatHandlerScript);
|
||||||
|
SetLocalArrayObject(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, iHook, oScriptRunner);
|
||||||
|
SetLocalArrayInt(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, iHook, maskChannels);
|
||||||
|
SetLocalArrayInt(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, iHook, bListenAll);
|
||||||
|
SetLocalArrayObject(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, iHook, oSpeaker);
|
||||||
|
SetLocalArrayInt(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, iHook, bAutoRemove);
|
||||||
|
|
||||||
|
return hdlHook;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
//! removes a callback function from the OnPlayerChat list.
|
||||||
|
//! \param hdlHookIn handle of hook to remove (0 for clean up orphans)
|
||||||
|
//! \return TRUE if requested hook found and removed
|
||||||
|
int DMFI_ChatHookRemove(int hdlHookIn)
|
||||||
|
{
|
||||||
|
int bRemoved = FALSE;
|
||||||
|
int hdlHook;
|
||||||
|
int iHook, iHook2;
|
||||||
|
object oMod = GetModule();
|
||||||
|
int nHooks = GetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME);
|
||||||
|
for (iHook = 1; iHook <= nHooks; iHook++)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
hdlHook = GetLocalArrayInt(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, iHook);
|
||||||
|
if (hdlHook != 0 && hdlHook != hdlHookIn) break;
|
||||||
|
|
||||||
|
// kill this one
|
||||||
|
for (iHook2 = iHook; iHook2 < nHooks; iHook2++)
|
||||||
|
{
|
||||||
|
SetLocalArrayInt(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, iHook2, GetLocalArrayInt(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, iHook2+1));
|
||||||
|
SetLocalArrayString(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, iHook2, GetLocalArrayString(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, iHook2+1));
|
||||||
|
SetLocalArrayObject(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, iHook2, GetLocalArrayObject(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, iHook2+1));
|
||||||
|
SetLocalArrayInt(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, iHook2, GetLocalArrayInt(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, iHook2+1));
|
||||||
|
SetLocalArrayInt(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, iHook2, GetLocalArrayInt(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, iHook2+1));
|
||||||
|
SetLocalArrayObject(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, iHook2, GetLocalArrayObject(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, iHook2+1));
|
||||||
|
SetLocalArrayInt(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, iHook2, GetLocalArrayInt(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, iHook2+1));
|
||||||
|
}
|
||||||
|
bRemoved = TRUE;
|
||||||
|
nHooks--;
|
||||||
|
if (nHooks < iHook) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bRemoved)
|
||||||
|
{
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_HANDLE_ARRAYNAME, nHooks);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_SCRIPT_ARRAYNAME, nHooks);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_RUNNER_ARRAYNAME, nHooks);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_CHANNELS_ARRAYNAME, nHooks);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_LISTENALL_ARRAYNAME, nHooks);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_SPEAKER_ARRAYNAME, nHooks);
|
||||||
|
SetLocalArrayUpperBound(oMod, DMFI_CHATHOOK_AUTOREMOVE_ARRAYNAME, nHooks);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bRemoved;
|
||||||
|
}
|
||||||
|
|
||||||
71
src/dmfi/dmfi_string_inc.nss
Normal file
71
src/dmfi/dmfi_string_inc.nss
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: DMFI - string functions and constants
|
||||||
|
//:: dmfi_string_inc
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Library of functions relating to strings for DMFI.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: tsunami282
|
||||||
|
//:: Created On: 2008.08.11
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "x3_inc_string"
|
||||||
|
|
||||||
|
const string DMFI_MESSAGE_COLOR_ALERT = "733"; // default 733 - brite red
|
||||||
|
const string DMFI_MESSAGE_COLOR_STATUS = "773"; // default 773 - yellow
|
||||||
|
const string DMFI_MESSAGE_COLOR_EAVESDROP = "777"; // default 777 - white
|
||||||
|
const string DMFI_MESSAGE_COLOR_TRANSLATION = "555"; // default 733 - lite gray
|
||||||
|
const string DMFI_MESSAGE_COLOR_OTHER = ""; // default blank
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
string LTrim(string sTrimMe, string sDelim = " ")
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
|
||||||
|
if (sDelim != "")
|
||||||
|
{
|
||||||
|
l = GetStringLength(sTrimMe);
|
||||||
|
while (GetStringLeft(sTrimMe, 1) == sDelim)
|
||||||
|
{
|
||||||
|
l--;
|
||||||
|
if (l < 1)
|
||||||
|
{
|
||||||
|
sTrimMe = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sTrimMe = GetStringRight(sTrimMe, l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sTrimMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
void DMFISendMessageToPC(object oPC, string sMsg, int bAllDMs=FALSE,
|
||||||
|
string sRGB="")
|
||||||
|
{
|
||||||
|
string sColMsg;
|
||||||
|
object oTarget = oPC;
|
||||||
|
if (bAllDMs) oTarget = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
if ((!bAllDMs) || (GetIsDM(oTarget) || GetIsDMPossessed(oTarget)))
|
||||||
|
{
|
||||||
|
if (sRGB != "")
|
||||||
|
{
|
||||||
|
sColMsg = StringToRGBString(sMsg, sRGB);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sColMsg = sMsg;
|
||||||
|
}
|
||||||
|
SendMessageToPC(oTarget, sColMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bAllDMs) break;
|
||||||
|
oTarget = GetNextPC();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
12
src/dmfi/dmfi_unact_nam02.nss
Normal file
12
src/dmfi/dmfi_unact_nam02.nss
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
#include "dmfi_getln_inc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oListener = OBJECT_SELF;
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
|
||||||
|
// attach our listener event
|
||||||
|
SetLocalString(oListener, "dmfi_getln_mode", "name");
|
||||||
|
DMFI_get_line(oPC, TALKVOLUME_TALK, "dmfi_univ_listen", oListener);
|
||||||
|
}
|
||||||
6
src/dmfi/dmfi_unact_nam03.nss
Normal file
6
src/dmfi/dmfi_unact_nam03.nss
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
SetName(oTarget, "");
|
||||||
|
}
|
||||||
8
src/dmfi/dmfi_unact_nam04.nss
Normal file
8
src/dmfi/dmfi_unact_nam04.nss
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
#include "dmfi_getln_inc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oListener = OBJECT_SELF;
|
||||||
|
DMFI_cancel_get_line(0, oListener);
|
||||||
|
}
|
||||||
12
src/dmfi/dmfi_unact_nam06.nss
Normal file
12
src/dmfi/dmfi_unact_nam06.nss
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
#include "dmfi_getln_inc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oListener = OBJECT_SELF;
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
|
||||||
|
// attach our listener event
|
||||||
|
SetLocalString(oListener, "dmfi_getln_mode", "desc");
|
||||||
|
DMFI_get_line(oPC, TALKVOLUME_TALK, "dmfi_univ_listen", oListener);
|
||||||
|
}
|
||||||
6
src/dmfi/dmfi_unact_nam07.nss
Normal file
6
src/dmfi/dmfi_unact_nam07.nss
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
SetName(oTarget, "");
|
||||||
|
}
|
||||||
8
src/dmfi/dmfi_unact_nam08.nss
Normal file
8
src/dmfi/dmfi_unact_nam08.nss
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
#include "dmfi_getln_inc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oListener = OBJECT_SELF;
|
||||||
|
DMFI_cancel_get_line(0, oListener);
|
||||||
|
}
|
||||||
13
src/dmfi/dmfi_uncnd_nam01.nss
Normal file
13
src/dmfi/dmfi_uncnd_nam01.nss
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
int StartingConditional()
|
||||||
|
{
|
||||||
|
// set the custom tokens
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
|
||||||
|
string sName = GetName(oTarget);
|
||||||
|
SetCustomToken(20680, sName);
|
||||||
|
string sOrigName = GetName(oTarget, TRUE);
|
||||||
|
SetCustomToken(20681, sOrigName);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
13
src/dmfi/dmfi_uncnd_nam05.nss
Normal file
13
src/dmfi/dmfi_uncnd_nam05.nss
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
int StartingConditional()
|
||||||
|
{
|
||||||
|
// set the custom tokens
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
|
||||||
|
string sName = GetDescription(oTarget);
|
||||||
|
SetCustomToken(20682, sName);
|
||||||
|
string sOrigName = GetDescription(oTarget, TRUE);
|
||||||
|
SetCustomToken(20683, sOrigName);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
26
src/dmfi/dmfi_univ_1.nss
Normal file
26
src/dmfi/dmfi_univ_1.nss
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||||
|
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||||
|
|
||||||
|
if (GetLocalInt(oPC, "Tens"))
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 1);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
DeleteLocalInt(oPC, "Tens");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering")
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 1);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLocalInt(oPC, "Tens", 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/dmfi/dmfi_univ_10.nss
Normal file
27
src/dmfi/dmfi_univ_10.nss
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||||
|
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||||
|
|
||||||
|
if (GetLocalInt(oPC, "Tens"))
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens"));
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
DeleteLocalInt(oPC, "Tens");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(sConv == "voice" || sConv == "pc_emote" || sConv == "faction")
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 10);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLocalInt(oPC, "Tens", 10);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/dmfi/dmfi_univ_2.nss
Normal file
26
src/dmfi/dmfi_univ_2.nss
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||||
|
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||||
|
|
||||||
|
if (GetLocalInt(oPC, "Tens"))
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 2);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
DeleteLocalInt(oPC, "Tens");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering")
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 2);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLocalInt(oPC, "Tens", 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/dmfi/dmfi_univ_3.nss
Normal file
27
src/dmfi/dmfi_univ_3.nss
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||||
|
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||||
|
|
||||||
|
if (GetLocalInt(oPC, "Tens"))
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 3);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
DeleteLocalInt(oPC, "Tens");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering")
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 3);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLocalInt(oPC, "Tens", 3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/dmfi/dmfi_univ_4.nss
Normal file
27
src/dmfi/dmfi_univ_4.nss
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||||
|
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||||
|
|
||||||
|
if (GetLocalInt(oPC, "Tens"))
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 4);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
DeleteLocalInt(oPC, "Tens");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering")
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 4);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLocalInt(oPC, "Tens", 4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/dmfi/dmfi_univ_5.nss
Normal file
27
src/dmfi/dmfi_univ_5.nss
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||||
|
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||||
|
|
||||||
|
if (GetLocalInt(oPC, "Tens"))
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 5);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
DeleteLocalInt(oPC, "Tens");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering")
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 5);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLocalInt(oPC, "Tens", 5);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/dmfi/dmfi_univ_6.nss
Normal file
28
src/dmfi/dmfi_univ_6.nss
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||||
|
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||||
|
|
||||||
|
if (GetLocalInt(oPC, "Tens"))
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 6);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
DeleteLocalInt(oPC, "Tens");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(sConv == "pc_emote" || sConv == "emote" ||
|
||||||
|
sConv == "server" || sConv == "onering")
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 6);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLocalInt(oPC, "Tens", 6);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/dmfi/dmfi_univ_7.nss
Normal file
27
src/dmfi/dmfi_univ_7.nss
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||||
|
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||||
|
|
||||||
|
if (GetLocalInt(oPC, "Tens"))
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 7);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
DeleteLocalInt(oPC, "Tens");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(sConv == "pc_emote" || sConv == "emote" || sConv == "server" || sConv == "onering" || sConv == "rest")
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 7);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLocalInt(oPC, "Tens", 7);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/dmfi/dmfi_univ_8.nss
Normal file
28
src/dmfi/dmfi_univ_8.nss
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||||
|
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||||
|
|
||||||
|
if (GetLocalInt(oPC, "Tens"))
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 8);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
DeleteLocalInt(oPC, "Tens");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(( sConv == "server") || (sConv == "xp") ||
|
||||||
|
(sConv == "voice") || (sConv == "onering") || (sConv == "rest"))
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 8);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLocalInt(oPC, "Tens", 8);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/dmfi/dmfi_univ_9.nss
Normal file
27
src/dmfi/dmfi_univ_9.nss
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_univ_target");
|
||||||
|
location lLocation = GetLocalLocation(oPC, "dmfi_univ_location");
|
||||||
|
string sConv = GetLocalString(oPC, "dmfi_univ_conv");
|
||||||
|
|
||||||
|
if (GetLocalInt(oPC, "Tens"))
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 10*GetLocalInt(oPC, "Tens") + 9);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
DeleteLocalInt(oPC, "Tens");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(sConv == "server" || sConv == "voice" || sConv == "faction" || sConv == "rest")
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "dmfi_univ_int", 9);
|
||||||
|
ExecuteScript("dmfi_execute", oPC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLocalInt(oPC, "Tens", 9);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
368
src/dmfi/dmfi_univ_cond.nss
Normal file
368
src/dmfi/dmfi_univ_cond.nss
Normal file
@@ -0,0 +1,368 @@
|
|||||||
|
//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")));
|
||||||
|
// Added (LordValinar - 11/03/2023): Incorporated the MCS
|
||||||
|
// --Multilayered Conversation System--
|
||||||
|
object oTarget = GetLocalObject(oPC, "dmfi_target");
|
||||||
|
SetCustomToken(20680, GetName(oTarget));
|
||||||
|
ExecuteScript("lv_conv_set", OBJECT_SELF);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (sOffset == "buff" && iOffset ==16)
|
||||||
|
{
|
||||||
|
if (GetLocalInt(oPC, "dmfi_buff_party")==0)
|
||||||
|
SetCustomToken(20783, "Single Target");
|
||||||
|
else
|
||||||
|
SetCustomToken(20783, "Party");
|
||||||
|
SetCustomToken(20782, GetLocalString(oPC, "dmfi_buff_level"));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (sOffset == "rest" && iOffset == 17 && !GetIsDM(oPC) && GetLocalInt(oPC, "dmfi_norest")) //This is the case of a No-Rest situation
|
||||||
|
{
|
||||||
|
SetRestTokens(oPC);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (sOffset == "rest" && iOffset == 18 && !GetIsDM(oPC) && !GetLocalInt(oPC, "dmfi_norest")) //This is the case of a Rest situation
|
||||||
|
{
|
||||||
|
SetRestTokens(oPC);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (sOffset == "rest" && iOffset == 19 && GetIsDM(oPC)) //This is the case of a DM activating the rest menu
|
||||||
|
{
|
||||||
|
SetRestTokens(oPC);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (sOffset == "naming" && iOffset==20)
|
||||||
|
{
|
||||||
|
string sName = GetName(GetLocalObject(oPC, "dmfi_univ_target"));
|
||||||
|
SetCustomToken(20680, sName);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
334
src/dmfi/dmfi_univ_dmw.nss
Normal file
334
src/dmfi/dmfi_univ_dmw.nss
Normal file
@@ -0,0 +1,334 @@
|
|||||||
|
//DMFI Universal Wand scripts by hahnsoo
|
||||||
|
int DMW_START_CUSTOM_TOKEN = 8000;
|
||||||
|
|
||||||
|
//Retrieve targetting information
|
||||||
|
object oMySpeaker = GetLastSpeaker();
|
||||||
|
object oMyTarget = GetLocalObject(oMySpeaker, "dmfi_univ_target");
|
||||||
|
location lMyLoc = GetLocalLocation(oMySpeaker, "dmfi_univ_location");
|
||||||
|
|
||||||
|
int dmwand_isnearbydestroyable()
|
||||||
|
{
|
||||||
|
object oMyTest = GetFirstObjectInShape(SHAPE_CUBE, 0.6, lMyLoc, FALSE, OBJECT_TYPE_ALL);
|
||||||
|
int nTargetType = GetObjectType(oMyTest);
|
||||||
|
return (GetIsObjectValid(oMyTest) && (! GetIsPC(oMyTest)) && ((nTargetType == OBJECT_TYPE_ITEM) || (nTargetType == OBJECT_TYPE_PLACEABLE) || (nTargetType == OBJECT_TYPE_CREATURE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_istargetcreateable()
|
||||||
|
{
|
||||||
|
if(! GetIsObjectValid(oMyTarget)) { return FALSE; }
|
||||||
|
|
||||||
|
int nTargetType = GetObjectType(oMyTarget);
|
||||||
|
return ((nTargetType == OBJECT_TYPE_ITEM) || (nTargetType == OBJECT_TYPE_PLACEABLE) || (nTargetType == OBJECT_TYPE_CREATURE));
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_istargetdestroyable()
|
||||||
|
{
|
||||||
|
if(! GetIsObjectValid(oMyTarget)) { return FALSE; }
|
||||||
|
|
||||||
|
int nTargetType = GetObjectType(oMyTarget);
|
||||||
|
if(! GetIsPC(oMyTarget))
|
||||||
|
{
|
||||||
|
return ((nTargetType == OBJECT_TYPE_ITEM) || (nTargetType == OBJECT_TYPE_PLACEABLE) || (nTargetType == OBJECT_TYPE_CREATURE));
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_istargetinvalid()
|
||||||
|
{
|
||||||
|
return !GetIsObjectValid(oMyTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_istargetinventory()
|
||||||
|
{
|
||||||
|
return (GetIsObjectValid(oMyTarget) && GetHasInventory(oMyTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_istargetnotme()
|
||||||
|
{
|
||||||
|
return (GetIsObjectValid(oMyTarget) && (oMySpeaker != oMyTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_istargetpcornpc()
|
||||||
|
{
|
||||||
|
return (GetIsObjectValid(oMyTarget) && GetAbilityScore(oMyTarget, ABILITY_CONSTITUTION));
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_istargetnpc()
|
||||||
|
{
|
||||||
|
return (dmwand_istargetpcornpc() && (! GetIsPC(oMyTarget)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_istargetpc()
|
||||||
|
{
|
||||||
|
return (GetIsObjectValid(oMyTarget) && GetIsPC(oMyTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_istargetpcnme()
|
||||||
|
{
|
||||||
|
return (GetIsObjectValid(oMyTarget) && GetIsPC(oMyTarget) && (oMySpeaker != oMyTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_istargetpcornpcnme()
|
||||||
|
{
|
||||||
|
return (dmwand_istargetpcornpc() && (oMySpeaker != oMyTarget));
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_istargetplaceable()
|
||||||
|
{
|
||||||
|
if(! GetIsObjectValid(oMyTarget)) { return FALSE; }
|
||||||
|
|
||||||
|
int nTargetType = GetObjectType(oMyTarget);
|
||||||
|
return (nTargetType == OBJECT_TYPE_PLACEABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmw_conv_Start(int nCurrent, int nChoice, string sParams = "")
|
||||||
|
{
|
||||||
|
string sText = "";
|
||||||
|
string sCall = "";
|
||||||
|
string sCallParams = "";
|
||||||
|
|
||||||
|
switch(nCurrent)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
nCurrent = 0;
|
||||||
|
sText = "Welcome to the Server tool: This will allow you to find any player to perform simple functions.";
|
||||||
|
sCall = "";
|
||||||
|
sCallParams = "";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
nCurrent = 1;
|
||||||
|
if(dmwand_istargetpcnme())
|
||||||
|
{
|
||||||
|
sText = "Penguin this player.";
|
||||||
|
sCall = "func_Toad";
|
||||||
|
sCallParams = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
nCurrent = 2;
|
||||||
|
if(dmwand_istargetpcnme())
|
||||||
|
{
|
||||||
|
sText = "Unpenguin this player.";
|
||||||
|
sCall = "func_Untoad";
|
||||||
|
sCallParams = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
nCurrent = 3;
|
||||||
|
if(dmwand_istargetpcnme())
|
||||||
|
{
|
||||||
|
sText = "Boot this player.";
|
||||||
|
sCall = "func_KickPC";
|
||||||
|
sCallParams = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
nCurrent = 4;
|
||||||
|
if(dmwand_istargetinvalid())
|
||||||
|
{
|
||||||
|
sText = "List all players...";
|
||||||
|
sCall = "conv_ListPlayers";
|
||||||
|
sCallParams = "func_PlayerListConv";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
nCurrent = 5;
|
||||||
|
if(dmwand_istargetpcnme())
|
||||||
|
{
|
||||||
|
sText = "Jump this player to my location.";
|
||||||
|
sCall = "func_JumpPlayerHere";
|
||||||
|
sCallParams = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6:
|
||||||
|
nCurrent = 6;
|
||||||
|
if(dmwand_istargetpcnme())
|
||||||
|
{
|
||||||
|
sText = "Jump me to this player's location.";
|
||||||
|
sCall = "func_JumpToPlayer";
|
||||||
|
sCallParams = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 7:
|
||||||
|
nCurrent = 7;
|
||||||
|
if(dmwand_istargetpcnme())
|
||||||
|
{
|
||||||
|
sText = "Jump this player's party to my location.";
|
||||||
|
sCall = "func_JumpPartyHere";
|
||||||
|
sCallParams = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
nCurrent = 0;
|
||||||
|
sText = "";
|
||||||
|
sCall = "";
|
||||||
|
sCallParams = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLocalString(oMySpeaker, "dmw_dialog" + IntToString(nChoice), sText);
|
||||||
|
SetLocalString(oMySpeaker, "dmw_function" + IntToString(nChoice), sCall);
|
||||||
|
SetLocalString(oMySpeaker, "dmw_params" + IntToString(nChoice), sCallParams);
|
||||||
|
|
||||||
|
return nCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dmwand_BuildConversationDialog(int nCurrent, int nChoice, string sConversation, string sParams)
|
||||||
|
{
|
||||||
|
if(TestStringAgainstPattern(sConversation, "Start"))
|
||||||
|
{
|
||||||
|
return dmw_conv_Start(nCurrent, nChoice, sParams);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dmwand_BuildConversation(string sConversation, string sParams)
|
||||||
|
{
|
||||||
|
int nLast;
|
||||||
|
int nTemp;
|
||||||
|
int nChoice = 1;
|
||||||
|
int nCurrent = 1;
|
||||||
|
int nMatch;
|
||||||
|
|
||||||
|
if(TestStringAgainstPattern(sParams, "prev"))
|
||||||
|
{
|
||||||
|
//Get the number choice to start with
|
||||||
|
nCurrent = GetLocalInt(oMySpeaker, "dmw_dialogprev");
|
||||||
|
|
||||||
|
//Since we're going to the previous page, there will be a next
|
||||||
|
SetLocalString(oMySpeaker, "dmw_dialog9", "Next ->");
|
||||||
|
SetLocalString(oMySpeaker, "dmw_function9", "conv_" + sConversation);
|
||||||
|
SetLocalString(oMySpeaker, "dmw_params9", "next");
|
||||||
|
SetLocalInt(oMySpeaker, "dmw_dialognext", nCurrent);
|
||||||
|
|
||||||
|
nChoice = 8;
|
||||||
|
for(;nChoice >= 0; nChoice--)
|
||||||
|
{
|
||||||
|
int nTemp1 = nCurrent;
|
||||||
|
int nTemp2 = nCurrent;
|
||||||
|
nMatch = nTemp2;
|
||||||
|
while((nCurrent == nMatch) && (nTemp2 > 0))
|
||||||
|
{
|
||||||
|
nTemp2--;
|
||||||
|
nMatch = dmwand_BuildConversationDialog(nTemp2, nChoice, sConversation, sParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nTemp2 <= 0)
|
||||||
|
{
|
||||||
|
//we went back too far for some reason, so make this choice blank
|
||||||
|
SetLocalString(oMySpeaker, "dmw_dialog" + IntToString(nChoice), "");
|
||||||
|
SetLocalString(oMySpeaker, "dmw_function" + IntToString(nChoice), "");
|
||||||
|
SetLocalString(oMySpeaker, "dmw_params" + IntToString(nChoice), "");
|
||||||
|
}
|
||||||
|
nLast = nTemp;
|
||||||
|
nTemp = nTemp1;
|
||||||
|
nTemp1 = nMatch;
|
||||||
|
nCurrent = nMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nMatch > 0)
|
||||||
|
{
|
||||||
|
SetLocalString(oMySpeaker, "dmw_dialog1", "<- previous");
|
||||||
|
SetLocalString(oMySpeaker, "dmw_function1", "conv_" + sConversation);
|
||||||
|
SetLocalString(oMySpeaker, "dmw_params1", "prev");
|
||||||
|
SetLocalInt(oMySpeaker, "dmw_dialogprev", nLast);
|
||||||
|
}
|
||||||
|
|
||||||
|
//fill the NPC's dialog spot
|
||||||
|
//(saved for last because the build process tromps on it)
|
||||||
|
dmwand_BuildConversationDialog(0, 0, sConversation, sParams);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//fill the NPC's dialog spot
|
||||||
|
dmwand_BuildConversationDialog(0, 0, sConversation, sParams);
|
||||||
|
|
||||||
|
//No parameters specified, start at the top of the conversation
|
||||||
|
if(sParams == "")
|
||||||
|
{
|
||||||
|
nChoice = 1;
|
||||||
|
nCurrent = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//A "next->" choice was selected
|
||||||
|
if(TestStringAgainstPattern(sParams, "next"))
|
||||||
|
{
|
||||||
|
//get the number choice to start with
|
||||||
|
nCurrent = GetLocalInt(oMySpeaker, "dmw_dialognext");
|
||||||
|
|
||||||
|
//set this as the number for the "previous" choice to use
|
||||||
|
SetLocalInt(oMySpeaker, "dmw_dialogprev", nCurrent);
|
||||||
|
|
||||||
|
//Set the first dialog choice to be "previous"
|
||||||
|
nChoice = 2;
|
||||||
|
SetLocalString(oMySpeaker, "dmw_dialog1", "<- Previous");
|
||||||
|
SetLocalString(oMySpeaker, "dmw_function1", "conv_" + sConversation);
|
||||||
|
SetLocalString(oMySpeaker, "dmw_params1", "prev");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Loop through to build the dialog list
|
||||||
|
for(;nChoice <= 10; nChoice++)
|
||||||
|
{
|
||||||
|
nMatch = dmwand_BuildConversationDialog(nCurrent, nChoice, sConversation, sParams);
|
||||||
|
//nLast will be the value of the choice before the last one
|
||||||
|
nLast = nTemp;
|
||||||
|
nTemp = nMatch;
|
||||||
|
if(nMatch > 0) { nCurrent = nMatch; }
|
||||||
|
if(nMatch == 0) { nLast = 0; }
|
||||||
|
nCurrent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If there were enough choices to fill 10 spots, make spot 9 a "next"
|
||||||
|
if(nLast > 0)
|
||||||
|
{
|
||||||
|
SetLocalString(oMySpeaker, "dmw_dialog9", "Next ->");
|
||||||
|
SetLocalString(oMySpeaker, "dmw_function9", "conv_" + sConversation);
|
||||||
|
SetLocalString(oMySpeaker, "dmw_params9", "next");
|
||||||
|
SetLocalInt(oMySpeaker, "dmw_dialognext", nLast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dmwand_StartConversation()
|
||||||
|
{
|
||||||
|
if(! GetIsObjectValid(oMySpeaker))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dmwand_BuildConversation("Start", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
int StartingConditional()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
int nMyNum = 0;
|
||||||
|
|
||||||
|
DeleteLocalInt(oPC, "Tens");
|
||||||
|
DeleteLocalInt(oPC, "dmfi_univ_offset");
|
||||||
|
SetLocalInt(OBJECT_SELF, "dmfi_dmwOffset", 1);
|
||||||
|
//Check whether this conversation has been started already, start it if not.
|
||||||
|
int nStarted = GetLocalInt(oMySpeaker, "dmw_started");
|
||||||
|
if(! nStarted)
|
||||||
|
{
|
||||||
|
SetLocalInt(oMySpeaker, "dmw_started", 1);
|
||||||
|
dmwand_StartConversation();
|
||||||
|
}
|
||||||
|
|
||||||
|
string sMyString = GetLocalString(oMySpeaker, "dmw_dialog" + IntToString(nMyNum));
|
||||||
|
|
||||||
|
if(sMyString == "")
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (GetLocalString(oPC, "dmfi_univ_conv") == "server")
|
||||||
|
{
|
||||||
|
SetCustomToken(DMW_START_CUSTOM_TOKEN + nMyNum, sMyString);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
115
src/dmfi/dmfi_univ_listen.nss
Normal file
115
src/dmfi/dmfi_univ_listen.nss
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
|
||||||
|
// dmfi_univ_listen
|
||||||
|
|
||||||
|
// template: dmfi_getln_cbtpl
|
||||||
|
// triggered from OnPlayerChat callback
|
||||||
|
|
||||||
|
#include "dmfi_db_inc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int nVolume = GetPCChatVolume();
|
||||||
|
object oShouter = GetPCChatSpeaker();
|
||||||
|
string sSaid = GetPCChatMessage();
|
||||||
|
|
||||||
|
// SendMessageToPC(GetFirstPC(), "ENTER dmfi_univ_listen: speaker=" + GetName(oShouter) + ", channel=" + IntToString(nVolume) + ", said=" + sSaid);
|
||||||
|
// first, lets deal with a getln event
|
||||||
|
string getln_mode = GetLocalString(OBJECT_SELF, "dmfi_getln_mode");
|
||||||
|
if (getln_mode == "name")
|
||||||
|
{
|
||||||
|
if (sSaid != ".")
|
||||||
|
{
|
||||||
|
object oTarget = GetLocalObject(oShouter, "dmfi_univ_target");
|
||||||
|
SetName(oTarget, sSaid);
|
||||||
|
}
|
||||||
|
DeleteLocalString(OBJECT_SELF, "dmfi_getln_mode");
|
||||||
|
}
|
||||||
|
else if (getln_mode == "desc")
|
||||||
|
{
|
||||||
|
if (sSaid != ".")
|
||||||
|
{
|
||||||
|
object oTarget = GetLocalObject(oShouter, "dmfi_univ_target");
|
||||||
|
SetDescription(oTarget, sSaid);
|
||||||
|
}
|
||||||
|
DeleteLocalString(OBJECT_SELF, "dmfi_getln_mode");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// you may wish to define an "abort" input message, such as a line
|
||||||
|
// containing a single period:
|
||||||
|
if (sSaid != ".")
|
||||||
|
{
|
||||||
|
// put your code here to process the input line (in sSaid)
|
||||||
|
|
||||||
|
if (GetIsDM(oShouter)) SetLocalInt(GetModule(), "dmfi_Admin" + GetPCPublicCDKey(oShouter), 1);
|
||||||
|
if (GetIsDMPossessed(oShouter)) SetLocalObject(GetMaster(oShouter), "dmfi_familiar", oShouter);
|
||||||
|
|
||||||
|
object oTarget = GetLocalObject(oShouter, "dmfi_VoiceTarget");
|
||||||
|
object oMaster = OBJECT_INVALID;
|
||||||
|
if (GetIsObjectValid(oTarget)) oMaster = oShouter;
|
||||||
|
|
||||||
|
int iPhrase = GetLocalInt(oShouter, "hls_EditPhrase");
|
||||||
|
|
||||||
|
object oSummon;
|
||||||
|
|
||||||
|
if (GetIsObjectValid(oShouter) && GetIsDM(oShouter))
|
||||||
|
{
|
||||||
|
if (GetTag(OBJECT_SELF) == "dmfi_setting" && GetLocalString(oShouter, "EffectSetting") != "")
|
||||||
|
{
|
||||||
|
string sPhrase = GetLocalString(oShouter, "EffectSetting");
|
||||||
|
SetLocalFloat(oShouter, sPhrase, StringToFloat(sSaid));
|
||||||
|
SetDMFIPersistentFloat("dmfi", sPhrase, StringToFloat(sSaid), oShouter);
|
||||||
|
DeleteLocalString(oShouter, "EffectSetting");
|
||||||
|
DelayCommand(0.5, ActionSpeakString("The setting " + sPhrase + " has been changed to " + FloatToString(GetLocalFloat(oShouter, sPhrase))));
|
||||||
|
DelayCommand(1.5, DestroyObject(OBJECT_SELF));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetIsObjectValid(oShouter) && GetIsPC(oShouter))
|
||||||
|
{
|
||||||
|
if (sSaid != GetLocalString(GetModule(), "hls_voicebuffer"))
|
||||||
|
{
|
||||||
|
SetLocalString(GetModule(), "hls_voicebuffer", sSaid);
|
||||||
|
|
||||||
|
// PrintString("<Conv>"+GetName(GetArea(oShouter))+ " " + GetName(oShouter) + ": " + sSaid + " </Conv>");
|
||||||
|
|
||||||
|
// if the phrase begins with .MyName, reparse the string as a voice throw
|
||||||
|
if (GetStringLeft(sSaid, GetStringLength("." + GetName(OBJECT_SELF))) == "." + GetName(OBJECT_SELF) &&
|
||||||
|
(GetLocalInt(GetModule(), "dmfi_Admin" + GetPCPublicCDKey(oShouter)) ||
|
||||||
|
GetIsDM(oShouter) || GetIsDMPossessed(oShouter)))
|
||||||
|
{
|
||||||
|
oTarget = OBJECT_SELF;
|
||||||
|
sSaid = GetStringRight(sSaid, GetStringLength(sSaid) - GetStringLength("." + GetName(OBJECT_SELF)));
|
||||||
|
if (GetStringLeft(sSaid, 1) == " ") sSaid = GetStringRight(sSaid, GetStringLength(sSaid) - 1);
|
||||||
|
sSaid = ":" + sSaid;
|
||||||
|
SetPCChatMessage(sSaid);
|
||||||
|
// SendMessageToPC(GetFirstPC(), "LEAVE(1) dmfi_univ_listen: speaker=" + GetName(oShouter) + ", channel=" + IntToString(nVolume) + ", said=" + sSaid);
|
||||||
|
return; // must bail out here to prevent clearing of message at end
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iPhrase)
|
||||||
|
{
|
||||||
|
if (iPhrase > 0)
|
||||||
|
{
|
||||||
|
SetCustomToken(iPhrase, sSaid);
|
||||||
|
SetDMFIPersistentString("dmfi", "hls" + IntToString(iPhrase), sSaid);
|
||||||
|
FloatingTextStringOnCreature("Phrase " + IntToString(iPhrase) + " has been recorded", oShouter, FALSE);
|
||||||
|
}
|
||||||
|
else if (iPhrase < 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
DeleteLocalInt(oShouter, "hls_EditPhrase");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// after processing, you will likely want to "eat" the text line, so it is
|
||||||
|
// not spoken or available for further processing
|
||||||
|
SetPCChatMessage("");
|
||||||
|
|
||||||
|
// SendMessageToPC(GetFirstPC(), "LEAVE(2) dmfi_univ_listen: speaker=" + GetName(oShouter) + ", channel=" + IntToString(nVolume) + ", said=" + sSaid);
|
||||||
|
|
||||||
|
}
|
||||||
65
src/dmfi/dmfi_voice1.nss
Normal file
65
src/dmfi/dmfi_voice1.nss
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Default On Heartbeat
|
||||||
|
//:: NW_C2_DEFAULT1
|
||||||
|
//:: Copyright (c) 2001 Bioware Corp.
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
This script will have people perform default
|
||||||
|
animations.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: Preston Watamaniuk
|
||||||
|
//:: Created On: Nov 23, 2001
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
#include "dmfi_db_inc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oFollow = GetLocalObject(OBJECT_SELF, "dmfi_follow");
|
||||||
|
int iLoiter = GetLocalInt(OBJECT_SELF, "dmfi_Loiter");
|
||||||
|
|
||||||
|
// Will fire ONE time only - makes the thing hard to see
|
||||||
|
if (!GetLocalInt(OBJECT_SELF, "hls_invis"))
|
||||||
|
{
|
||||||
|
SetListenPattern(OBJECT_SELF, "**", LISTEN_PATTERN); //listen to all text
|
||||||
|
SetLocalInt(OBJECT_SELF, "hls_Listening", 1); //listen to all text
|
||||||
|
SetListening(OBJECT_SELF, TRUE); //be sure NPC is listening
|
||||||
|
|
||||||
|
//leave it here rather than add the one time loop to EVERY creature through a OS script change
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), OBJECT_SELF);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneGhost(), OBJECT_SELF);
|
||||||
|
SetLocalInt(OBJECT_SELF, "hls_invis",1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetIsObjectValid(oFollow))
|
||||||
|
{
|
||||||
|
if (GetArea(oFollow)==GetArea(OBJECT_SELF))
|
||||||
|
{
|
||||||
|
AssignCommand(OBJECT_SELF, ClearAllActions(TRUE));
|
||||||
|
AssignCommand(OBJECT_SELF, ActionForceFollowObject(oFollow));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AssignCommand(OBJECT_SELF, ClearAllActions(TRUE));
|
||||||
|
AssignCommand(OBJECT_SELF, ActionJumpToObject(oFollow));
|
||||||
|
AssignCommand(OBJECT_SELF, ActionForceFollowObject(oFollow));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If just following and listening, then return.
|
||||||
|
if (!iLoiter)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If in loiter mode, look for a PC and make the announcement when appropraite
|
||||||
|
object oPC = GetFirstObjectInShape(SHAPE_SPHERE, 10.0f, GetLocation(OBJECT_SELF), TRUE);
|
||||||
|
while(GetIsObjectValid(oPC))
|
||||||
|
{
|
||||||
|
if (GetIsPC(oPC) &&
|
||||||
|
!GetIsDM(oPC) &&
|
||||||
|
iLoiter)
|
||||||
|
{
|
||||||
|
SpeakString(GetLocalString(OBJECT_SELF, "dmfi_LoiterSay"));
|
||||||
|
DestroyObject(OBJECT_SELF);
|
||||||
|
}
|
||||||
|
oPC = GetNextObjectInShape(SHAPE_SPHERE, 10.0f, GetLocation(OBJECT_SELF), TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
53
src/dmfi/dmfi_voice_exe.nss
Normal file
53
src/dmfi/dmfi_voice_exe.nss
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: DMFI - settings voice command handler
|
||||||
|
//:: dmfi_voice_exe
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Processor for the text heard by the settings adjuster creature.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: The DMFI Team
|
||||||
|
//:: Created On:
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: 2008.08.02 tsunami282 - most code transferred to dmfi_plychat_exe, this
|
||||||
|
//:: script now used for processing what the Settings Adjuster creature hears.
|
||||||
|
|
||||||
|
#include "dmfi_db_inc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int nMatch = GetListenPatternNumber();
|
||||||
|
object oShouter = GetLastSpeaker();
|
||||||
|
|
||||||
|
if (GetIsDM(oShouter))
|
||||||
|
SetLocalInt(GetModule(), "dmfi_Admin" + GetPCPublicCDKey(oShouter), 1);
|
||||||
|
|
||||||
|
if (GetIsDMPossessed(oShouter))
|
||||||
|
SetLocalObject(GetMaster(oShouter), "dmfi_familiar", oShouter);
|
||||||
|
|
||||||
|
object oTarget = GetLocalObject(oShouter, "dmfi_VoiceTarget");
|
||||||
|
object oMaster = OBJECT_INVALID;
|
||||||
|
if (GetIsObjectValid(oTarget))
|
||||||
|
oMaster = oShouter;
|
||||||
|
|
||||||
|
int iPhrase = GetLocalInt(oShouter, "hls_EditPhrase");
|
||||||
|
|
||||||
|
object oSummon;
|
||||||
|
|
||||||
|
if (nMatch == LISTEN_PATTERN && GetIsObjectValid(oShouter) && GetIsDM(oShouter))
|
||||||
|
{
|
||||||
|
string sSaid = GetMatchedSubstring(0);
|
||||||
|
|
||||||
|
if (GetTag(OBJECT_SELF) == "dmfi_setting" && GetLocalString(oShouter, "EffectSetting") != "")
|
||||||
|
{
|
||||||
|
string sPhrase = GetLocalString(oShouter, "EffectSetting");
|
||||||
|
SetLocalFloat(oShouter, sPhrase, StringToFloat(sSaid));
|
||||||
|
SetDMFIPersistentFloat("dmfi", sPhrase, StringToFloat(sSaid), oShouter);
|
||||||
|
DeleteLocalString(oShouter, "EffectSetting");
|
||||||
|
DelayCommand(0.5, ActionSpeakString("The setting " + sPhrase + " has been changed to " + FloatToString(GetLocalFloat(oShouter, sPhrase))));
|
||||||
|
DelayCommand(1.5, DestroyObject(OBJECT_SELF));
|
||||||
|
//maybe add a return here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
377
src/dmfi/dmfi_x_afflict.nss
Normal file
377
src/dmfi/dmfi_x_afflict.nss
Normal file
@@ -0,0 +1,377 @@
|
|||||||
|
#include "dmfi_db_inc"
|
||||||
|
|
||||||
|
|
||||||
|
object DMFI_NextTarget(object oTarget, object oUser)
|
||||||
|
{
|
||||||
|
object oNew;
|
||||||
|
|
||||||
|
if (GetIsPC(oTarget))
|
||||||
|
{
|
||||||
|
if (GetIsObjectValid(GetNextFactionMember(oTarget)))
|
||||||
|
oNew = GetNextFactionMember(oTarget);
|
||||||
|
else
|
||||||
|
oNew = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oTarget, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
oNew = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC, oTarget, 1);
|
||||||
|
|
||||||
|
|
||||||
|
if (!GetIsObjectValid(oNew))
|
||||||
|
{
|
||||||
|
SendMessageToPC(oUser, "No valid target to transfer to.");
|
||||||
|
oNew = oTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLocalObject(oUser, "dmfi_univ_target", oNew);
|
||||||
|
SetCustomToken(20680, GetName(oNew));
|
||||||
|
FloatingTextStringOnCreature("Target changed to: "+ GetName(oNew), oUser);
|
||||||
|
return oNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
//DMFI Creates the "settings" creature
|
||||||
|
void CreateSetting(object oUser)
|
||||||
|
{
|
||||||
|
object oSetting = CreateObject(OBJECT_TYPE_CREATURE, "dmfi_setting", GetLocation(oUser));
|
||||||
|
DelayCommand(0.5f, AssignCommand(oSetting, ActionSpeakString(GetLocalString(oUser, "EffectSetting") + " is currently set at " + FloatToString(GetLocalFloat(oUser, GetLocalString(oUser, "EffectSetting"))))));
|
||||||
|
SetLocalObject(oSetting, "MyMaster", oUser);
|
||||||
|
SetListenPattern(oSetting, "**", LISTEN_PATTERN); //listen to all text
|
||||||
|
SetLocalInt(oSetting, "hls_Listening", 1); //listen to all text
|
||||||
|
SetListening(oSetting, TRUE); //be sure NPC is listening
|
||||||
|
}
|
||||||
|
|
||||||
|
//This function is for the DMFI Affliction Wand
|
||||||
|
void ReportImmunity(object oT, object oUser)
|
||||||
|
{
|
||||||
|
SendMessageToPC(oUser, "Immunities Reported: (blank if none)");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_ABILITY_DECREASE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Ability Decrease");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_AC_DECREASE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE AC Decrease");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_ATTACK_DECREASE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Attack Decrease");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_BLINDNESS))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Blindness");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_CHARM))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Charm");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_CONFUSED))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Confusion");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_CRITICAL_HIT))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Critical Hit");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_CURSED))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Cursed");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_DAMAGE_DECREASE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Damage Decrease");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_DAMAGE_IMMUNITY_DECREASE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Damage Immunity Decrease");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_DAZED))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Dazed");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_DEAFNESS))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Deafness");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_DEATH))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Death");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_DISEASE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Disease");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_DOMINATE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Dominate");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_ENTANGLE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Entangle");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_FEAR))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Fear");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_KNOCKDOWN))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Knockdown");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_MIND_SPELLS))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Mind Spells");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_MOVEMENT_SPEED_DECREASE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Movement Speed Decrease");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_NEGATIVE_LEVEL))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Negative Level");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_PARALYSIS))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Paralysis");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_POISON))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Poison");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_SAVING_THROW_DECREASE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Saving Throw Decrease");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_SILENCE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Silence");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_SKILL_DECREASE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Skill Decrease");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_SLEEP))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Sleep");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_SLOW))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Slow");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_SNEAK_ATTACK))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Sneak Attack");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_SPELL_RESISTANCE_DECREASE))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Spell Resistance Decrease");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_STUN))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Stun");
|
||||||
|
if (GetIsImmune(oT, IMMUNITY_TYPE_TRAP))
|
||||||
|
SendMessageToPC(oUser, GetName(oT) + " IMMUNE Trap");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckForEffect(effect eA, object oT, object oUser)
|
||||||
|
{
|
||||||
|
int Result = FALSE;
|
||||||
|
effect Check = GetFirstEffect(oT);
|
||||||
|
|
||||||
|
while (GetIsEffectValid(Check))
|
||||||
|
{
|
||||||
|
if (Check == eA)
|
||||||
|
Result = TRUE;
|
||||||
|
|
||||||
|
Check = GetNextEffect(oT);
|
||||||
|
}
|
||||||
|
if (Result)
|
||||||
|
FloatingTextStringOnCreature("Affliction Wand Saving Throw Failure: " + GetName(oT), oUser);
|
||||||
|
else
|
||||||
|
FloatingTextStringOnCreature("Affliction Wand Saving Throw Success: No Effect: " + GetName(oT), oUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int iAfflict = GetLocalInt(OBJECT_SELF, "dmfi_univ_int");
|
||||||
|
object oUser = OBJECT_SELF;
|
||||||
|
effect eEffect;
|
||||||
|
object oTarget = GetLocalObject(oUser, "dmfi_univ_target");
|
||||||
|
float fDuration;
|
||||||
|
int nDNum;
|
||||||
|
effect eD;
|
||||||
|
effect eA;
|
||||||
|
effect eT;
|
||||||
|
effect eVis;
|
||||||
|
int nBug = 0;
|
||||||
|
int nSaveAmount; float fSaveAmount;
|
||||||
|
|
||||||
|
nDNum = GetLocalInt(oUser, "dmfi_damagemodifier");
|
||||||
|
fDuration = GetLocalFloat(oUser, "dmfi_stunduration");
|
||||||
|
fSaveAmount = GetLocalFloat(oUser, "dmfi_saveamount");
|
||||||
|
|
||||||
|
nSaveAmount = FloatToInt(fSaveAmount);
|
||||||
|
|
||||||
|
if (!(GetObjectType(oTarget) == OBJECT_TYPE_CREATURE) ||
|
||||||
|
GetIsDM(oTarget))
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("You must target a valid creature!", oUser, FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch(iAfflict)
|
||||||
|
{
|
||||||
|
case 11: eD= EffectDamage(d4(nDNum), DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||||
|
eVis = EffectVisualEffect(VFX_COM_BLOOD_SPARK_SMALL); break;
|
||||||
|
case 12: eD = EffectDamage(d6(nDNum), DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||||
|
eVis = EffectVisualEffect(VFX_COM_BLOOD_LRG_RED); break;
|
||||||
|
case 13: eD = EffectDamage(d8(nDNum), DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||||
|
eVis = EffectVisualEffect(VFX_COM_BLOOD_LRG_RED); break;
|
||||||
|
case 14: eD = EffectDamage(d10(nDNum), DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||||
|
eVis = EffectVisualEffect(VFX_COM_BLOOD_SPARK_SMALL); break;
|
||||||
|
case 15: eD = EffectDamage(d12(nDNum), DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||||
|
eVis = EffectVisualEffect(VFX_COM_BLOOD_SPARK_SMALL); break;
|
||||||
|
case 16: eD = EffectDamage(GetCurrentHitPoints(oTarget)/4, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||||
|
eVis = EffectVisualEffect(VFX_COM_BLOOD_LRG_RED); break;
|
||||||
|
case 17: eD = EffectDamage(GetCurrentHitPoints(oTarget)/2, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||||
|
eVis = EffectVisualEffect(VFX_COM_BLOOD_LRG_RED); break;
|
||||||
|
case 18: eD = EffectDamage(GetCurrentHitPoints(oTarget) * 3 / 4, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||||
|
eVis =EffectVisualEffect(VFX_COM_CHUNK_RED_SMALL); break;
|
||||||
|
case 19: eD = EffectDamage(GetCurrentHitPoints(oTarget)-1, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
|
||||||
|
eVis =EffectVisualEffect(VFX_COM_CHUNK_RED_SMALL); break;
|
||||||
|
case 21: eA =EffectDisease(DISEASE_FILTH_FEVER); break;
|
||||||
|
case 22: eA =EffectDisease(DISEASE_MINDFIRE); break;
|
||||||
|
case 23: eA =EffectDisease(DISEASE_DREAD_BLISTERS); break;
|
||||||
|
case 24: eA =EffectDisease(DISEASE_SHAKES); break;
|
||||||
|
case 25: eA =EffectDisease(DISEASE_VERMIN_MADNESS); break;
|
||||||
|
case 26: eA =EffectDisease(DISEASE_DEVIL_CHILLS); break;
|
||||||
|
case 27: eA =EffectDisease(DISEASE_SLIMY_DOOM); break;
|
||||||
|
case 28: eA =EffectDisease(DISEASE_RED_ACHE); break;
|
||||||
|
case 29: eA =EffectDisease(DISEASE_ZOMBIE_CREEP); break;
|
||||||
|
case 31: eA =EffectDisease(DISEASE_BLINDING_SICKNESS); break;
|
||||||
|
case 32: eA =EffectDisease(DISEASE_CACKLE_FEVER); break;
|
||||||
|
case 33: eA =EffectDisease(DISEASE_BURROW_MAGGOTS); break;
|
||||||
|
case 34: eA =EffectDisease(DISEASE_RED_SLAAD_EGGS); break;
|
||||||
|
case 35: eA =EffectDisease(DISEASE_DEMON_FEVER); break;
|
||||||
|
case 36: eA =EffectDisease(DISEASE_GHOUL_ROT); break;
|
||||||
|
case 37: eA =EffectDisease(DISEASE_MUMMY_ROT); break;
|
||||||
|
case 38: eA =EffectDisease(DISEASE_SOLDIER_SHAKES); break;
|
||||||
|
case 39: eA =EffectDisease(DISEASE_SOLDIER_SHAKES); break;
|
||||||
|
case 41: eA =EffectPoison(POISON_TINY_SPIDER_VENOM); break;
|
||||||
|
case 42: eA =EffectPoison(POISON_ARANEA_VENOM); break;
|
||||||
|
case 43: eA =EffectPoison(POISON_MEDIUM_SPIDER_VENOM); break;
|
||||||
|
case 44: eA = EffectPoison(POISON_CARRION_CRAWLER_BRAIN_JUICE); break;
|
||||||
|
case 45: eA = EffectPoison(POISON_OIL_OF_TAGGIT); break;
|
||||||
|
case 46: eA = EffectPoison(POISON_ARSENIC); break;
|
||||||
|
case 47: eA = EffectPoison(POISON_GREENBLOOD_OIL); break;
|
||||||
|
case 48: eA = EffectPoison(POISON_NITHARIT); break;
|
||||||
|
case 49: eA = EffectPoison(POISON_PHASE_SPIDER_VENOM); break;
|
||||||
|
case 51: eA = EffectPoison(POISON_LICH_DUST); break;
|
||||||
|
case 52: eA = EffectPoison(POISON_SHADOW_ESSENCE); break;
|
||||||
|
case 53: eA = EffectPoison(POISON_LARGE_SPIDER_VENOM); break;
|
||||||
|
case 54: eA = EffectPoison(POISON_PURPLE_WORM_POISON); break;
|
||||||
|
case 55: eA = EffectPoison(POISON_IRON_GOLEM); break;
|
||||||
|
case 56: eA = EffectPoison(POISON_PIT_FIEND_ICHOR); break;
|
||||||
|
case 57: eA = EffectPoison(POISON_WYVERN_POISON); break;
|
||||||
|
case 58: eA = EffectPoison(POISON_BLACK_LOTUS_EXTRACT); break;
|
||||||
|
case 59: eA = EffectPoison(POISON_GARGANTUAN_SPIDER_VENOM); break;
|
||||||
|
case 60: eT = EffectPetrify(); break;
|
||||||
|
case 61: eT = EffectBlindness(); break;
|
||||||
|
case 62: eT = EffectCurse(4,4,4,4,4,4); break;
|
||||||
|
case 63: eT = EffectFrightened(); break;
|
||||||
|
case 64: eT = EffectStunned(); break;
|
||||||
|
case 65: eT = EffectSilence(); break;
|
||||||
|
case 66: eT = EffectSleep(); break;
|
||||||
|
case 67: eT = EffectSlow(); break;
|
||||||
|
case 68: eT = EffectKnockdown(); nBug = 1; break;
|
||||||
|
case 69: eD = EffectDamage( GetCurrentHitPoints(oTarget)-1, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_NORMAL);
|
||||||
|
AssignCommand( oTarget, ClearAllActions());
|
||||||
|
AssignCommand( oTarget, ActionPlayAnimation( ANIMATION_LOOPING_DEAD_FRONT, 1.0, 99999.0));
|
||||||
|
DelayCommand(0.5, SetCommandable( FALSE, oTarget)); break;
|
||||||
|
case 71: eA = EffectCutsceneDominated();break;
|
||||||
|
case 72: eA = EffectCutsceneGhost(); break;
|
||||||
|
case 73: eA = EffectCutsceneImmobilize(); break;
|
||||||
|
case 74: eA = EffectCutsceneParalyze(); break;
|
||||||
|
case 75: nBug = -1; break; //special case for combo death effect
|
||||||
|
case 81: eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eEffect) == EFFECT_TYPE_POISON) RemoveEffect(oTarget, eEffect);
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
} break;
|
||||||
|
case 82: eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eEffect) == EFFECT_TYPE_DISEASE) RemoveEffect(oTarget, eEffect);
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
} break;
|
||||||
|
case 83: eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eEffect) == EFFECT_TYPE_BLINDNESS) RemoveEffect(oTarget, eEffect);
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
} break;
|
||||||
|
case 84: eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eEffect) == EFFECT_TYPE_CURSE) RemoveEffect(oTarget, eEffect);
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
} break;
|
||||||
|
case 85: eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eEffect) == EFFECT_TYPE_FRIGHTENED) RemoveEffect(oTarget, eEffect);
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
} break;
|
||||||
|
case 86: eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eEffect) == EFFECT_TYPE_STUNNED) RemoveEffect(oTarget, eEffect);
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
} break;
|
||||||
|
case 87: eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eEffect) == EFFECT_TYPE_SILENCE) RemoveEffect(oTarget, eEffect);
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
} break;
|
||||||
|
case 88: eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eEffect);
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
} break;
|
||||||
|
case 89: SetCommandable(TRUE, oTarget);
|
||||||
|
AssignCommand(oTarget, ClearAllActions()); break;
|
||||||
|
case 80: eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eEffect) == EFFECT_TYPE_PETRIFY) RemoveEffect(oTarget, eEffect);
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
} break;//Added July 5, 2003
|
||||||
|
|
||||||
|
// 99 is a duplicate instance - simple copy. - Demetrious
|
||||||
|
case 91: SetLocalString(oUser, "EffectSetting", "dmfi_stunduration");
|
||||||
|
CreateSetting(oUser);
|
||||||
|
case 92: SetDMFIPersistentInt("dmfi", "DamageModifier", nDNum+1); SetCustomToken(20780, IntToString(nDNum+1));; break;
|
||||||
|
case 93:
|
||||||
|
if (nDNum==1)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("Illegal operation: Minimum modifier is 1.", oUser);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetDMFIPersistentInt("dmfi", "DamageModifier", nDNum-1); SetCustomToken(20780, IntToString(nDNum-1)); ;break;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 94: ReportImmunity(oTarget, oUser); break;
|
||||||
|
case 95: DMFI_NextTarget(oTarget, oUser); break;
|
||||||
|
case 99: SetLocalString(oUser, "EffectSetting", "SaveEffectAmount");
|
||||||
|
CreateSetting(oUser); break;
|
||||||
|
case 101: eT = EffectSavingThrowDecrease(SAVING_THROW_FORT, nSaveAmount); break;
|
||||||
|
case 102: eT = EffectSavingThrowDecrease(SAVING_THROW_REFLEX, nSaveAmount); break;
|
||||||
|
case 103: eT = EffectSavingThrowDecrease(SAVING_THROW_WILL, nSaveAmount); break;
|
||||||
|
case 104: eT = EffectSavingThrowIncrease(SAVING_THROW_FORT, nSaveAmount); break;
|
||||||
|
case 105: eT = EffectSavingThrowIncrease(SAVING_THROW_REFLEX, nSaveAmount); break;
|
||||||
|
case 106: eT = EffectSavingThrowIncrease(SAVING_THROW_WILL, nSaveAmount); break;
|
||||||
|
case 107: eT = EffectSavingThrowDecrease(SAVING_THROW_ALL, nSaveAmount); break;
|
||||||
|
case 108: eT = EffectSavingThrowIncrease(SAVING_THROW_ALL, nSaveAmount); break;
|
||||||
|
case 109: SetLocalString(oUser, "EffectSetting", "SaveEffectAmount");
|
||||||
|
CreateSetting(oUser);
|
||||||
|
case 100: eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
if ((GetEffectType(eEffect) == EFFECT_TYPE_SAVING_THROW_INCREASE)
|
||||||
|
||(GetEffectType(eEffect) == EFFECT_TYPE_SAVING_THROW_DECREASE))
|
||||||
|
RemoveEffect(oTarget, eEffect);
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
} break;//Added July 5, 2003
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
//code down here to apply the effects an then go back and see if the
|
||||||
|
//player successfully saved or did not for the diseases and poisons.
|
||||||
|
|
||||||
|
if ((GetEffectType(eD)!= EFFECT_TYPE_INVALIDEFFECT) ||
|
||||||
|
(GetEffectType(eVis) != EFFECT_TYPE_INVALIDEFFECT))
|
||||||
|
{
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eD, oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVis, oTarget);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (GetEffectType(eA)!= EFFECT_TYPE_INVALIDEFFECT)
|
||||||
|
{
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eA, oTarget);
|
||||||
|
DelayCommand(5.0, CheckForEffect(eA, oTarget, oUser));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((GetEffectType(eT)!= EFFECT_TYPE_INVALIDEFFECT) || (nBug ==1))
|
||||||
|
{
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eT, oTarget, fDuration);
|
||||||
|
|
||||||
|
if ((GetEffectType(eT)==EFFECT_TYPE_SAVING_THROW_INCREASE) ||
|
||||||
|
(GetEffectType(eT)==EFFECT_TYPE_SAVING_THROW_DECREASE))
|
||||||
|
{
|
||||||
|
DelayCommand(1.0, FloatingTextStringOnCreature("Target Saves: Fortitude " + IntToString(GetFortitudeSavingThrow(oTarget))
|
||||||
|
+ " Reflex " + IntToString(GetReflexSavingThrow(oTarget)) + " Will " + IntToString(GetWillSavingThrow(oTarget)), oUser));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (nBug == -1)
|
||||||
|
{
|
||||||
|
object oFollowMe = GetFirstFactionMember(oTarget, TRUE);
|
||||||
|
|
||||||
|
if (!GetIsObjectValid(oFollowMe))
|
||||||
|
oFollowMe = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oTarget, 1,CREATURE_TYPE_IS_ALIVE, TRUE);
|
||||||
|
|
||||||
|
if (GetIsDM(oFollowMe) || GetIsDMPossessed(oFollowMe))
|
||||||
|
oFollowMe = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oTarget, 2,CREATURE_TYPE_IS_ALIVE, TRUE);
|
||||||
|
|
||||||
|
if (!GetIsObjectValid(oFollowMe))
|
||||||
|
oFollowMe = oUser;
|
||||||
|
|
||||||
|
AssignCommand(oFollowMe, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneDominated(), oTarget));
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneGhost(), oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
218
src/dmfi/dmfi_x_emote.nss
Normal file
218
src/dmfi/dmfi_x_emote.nss
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
//Smoking Function by Jason Robinson
|
||||||
|
location GetLocationAboveAndInFrontOf(object oPC, float fDist, float fHeight)
|
||||||
|
{
|
||||||
|
float fDistance = -fDist;
|
||||||
|
object oTarget = (oPC);
|
||||||
|
object oArea = GetArea(oTarget);
|
||||||
|
vector vPosition = GetPosition(oTarget);
|
||||||
|
vPosition.z += fHeight;
|
||||||
|
float fOrientation = GetFacing(oTarget);
|
||||||
|
vector vNewPos = AngleToVector(fOrientation);
|
||||||
|
float vZ = vPosition.z;
|
||||||
|
float vX = vPosition.x - fDistance * vNewPos.x;
|
||||||
|
float vY = vPosition.y - fDistance * vNewPos.y;
|
||||||
|
fOrientation = GetFacing(oTarget);
|
||||||
|
vX = vPosition.x - fDistance * vNewPos.x;
|
||||||
|
vY = vPosition.y - fDistance * vNewPos.y;
|
||||||
|
vNewPos = AngleToVector(fOrientation);
|
||||||
|
vZ = vPosition.z;
|
||||||
|
vNewPos = Vector(vX, vY, vZ);
|
||||||
|
return Location(oArea, vNewPos, fOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Smoking Function by Jason Robinson
|
||||||
|
void SmokePipe(object oActivator)
|
||||||
|
{
|
||||||
|
string sEmote1 = "*puffs on a pipe*";
|
||||||
|
string sEmote2 = "*inhales from a pipe*";
|
||||||
|
string sEmote3 = "*pulls a mouthful of smoke from a pipe*";
|
||||||
|
float fHeight = 1.7;
|
||||||
|
float fDistance = 0.1;
|
||||||
|
// Set height based on race and gender
|
||||||
|
if (GetGender(oActivator) == GENDER_MALE)
|
||||||
|
{
|
||||||
|
switch (GetRacialType(oActivator))
|
||||||
|
{
|
||||||
|
case RACIAL_TYPE_HUMAN:
|
||||||
|
case RACIAL_TYPE_HALFELF: fHeight = 1.7; fDistance = 0.12; break;
|
||||||
|
case RACIAL_TYPE_ELF: fHeight = 1.55; fDistance = 0.08; break;
|
||||||
|
case RACIAL_TYPE_GNOME:
|
||||||
|
case RACIAL_TYPE_HALFLING: fHeight = 1.15; fDistance = 0.12; break;
|
||||||
|
case RACIAL_TYPE_DWARF: fHeight = 1.2; fDistance = 0.12; break;
|
||||||
|
case RACIAL_TYPE_HALFORC: fHeight = 1.9; fDistance = 0.2; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// FEMALES
|
||||||
|
switch (GetRacialType(oActivator))
|
||||||
|
{
|
||||||
|
case RACIAL_TYPE_HUMAN:
|
||||||
|
case RACIAL_TYPE_HALFELF: fHeight = 1.6; fDistance = 0.12; break;
|
||||||
|
case RACIAL_TYPE_ELF: fHeight = 1.45; fDistance = 0.12; break;
|
||||||
|
case RACIAL_TYPE_GNOME:
|
||||||
|
case RACIAL_TYPE_HALFLING: fHeight = 1.1; fDistance = 0.075; break;
|
||||||
|
case RACIAL_TYPE_DWARF: fHeight = 1.2; fDistance = 0.1; break;
|
||||||
|
case RACIAL_TYPE_HALFORC: fHeight = 1.8; fDistance = 0.13; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
location lAboveHead = GetLocationAboveAndInFrontOf(oActivator, fDistance, fHeight);
|
||||||
|
// emotes
|
||||||
|
switch (d3())
|
||||||
|
{
|
||||||
|
case 1: AssignCommand(oActivator, ActionSpeakString(sEmote1)); break;
|
||||||
|
case 2: AssignCommand(oActivator, ActionSpeakString(sEmote2)); break;
|
||||||
|
case 3: AssignCommand(oActivator, ActionSpeakString(sEmote3));break;
|
||||||
|
}
|
||||||
|
// glow red
|
||||||
|
AssignCommand(oActivator, ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_RED_5), oActivator, 0.15)));
|
||||||
|
// wait a moment
|
||||||
|
AssignCommand(oActivator, ActionWait(3.0));
|
||||||
|
// puff of smoke above and in front of head
|
||||||
|
AssignCommand(oActivator, ActionDoCommand(ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), lAboveHead)));
|
||||||
|
// if female, turn head to left
|
||||||
|
if ((GetGender(oActivator) == GENDER_FEMALE) && (GetRacialType(oActivator) != RACIAL_TYPE_DWARF))
|
||||||
|
AssignCommand(oActivator, ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 1.0, 5.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmoteDance(object oPC)
|
||||||
|
{
|
||||||
|
object oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
|
||||||
|
object oLeftHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
|
||||||
|
|
||||||
|
AssignCommand(oPC,ActionUnequipItem(oRightHand));
|
||||||
|
AssignCommand(oPC,ActionUnequipItem(oLeftHand));
|
||||||
|
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY2,1.0));
|
||||||
|
AssignCommand(oPC,ActionDoCommand(PlayVoiceChat(VOICE_CHAT_LAUGH,oPC)));
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_LOOPING_TALK_LAUGHING, 2.0, 2.0));
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY1,1.0));
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY3,2.0));
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_LOOPING_GET_MID, 3.0, 1.0));
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_LOOPING_TALK_FORCEFUL,1.0));
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY2,1.0));
|
||||||
|
AssignCommand(oPC,ActionDoCommand(PlayVoiceChat(VOICE_CHAT_LAUGH,oPC)));
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_LOOPING_TALK_LAUGHING, 2.0, 2.0));
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY1,1.0));
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY3,2.0));
|
||||||
|
AssignCommand(oPC,ActionDoCommand(PlayVoiceChat(VOICE_CHAT_LAUGH,oPC)));
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_LOOPING_GET_MID, 3.0, 1.0));
|
||||||
|
AssignCommand(oPC,ActionPlayAnimation( ANIMATION_FIREFORGET_VICTORY2,1.0));
|
||||||
|
|
||||||
|
AssignCommand(oPC,ActionDoCommand(ActionEquipItem(oLeftHand,INVENTORY_SLOT_LEFTHAND)));
|
||||||
|
AssignCommand(oPC,ActionDoCommand(ActionEquipItem(oRightHand,INVENTORY_SLOT_RIGHTHAND)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SitInNearestChair(object oPC)
|
||||||
|
{
|
||||||
|
object oSit,oRightHand,oLeftHand,oChair,oCouch,oBenchPew,oStool;
|
||||||
|
float fDistSit;int nth;
|
||||||
|
// get the closest chair, couch bench or stool
|
||||||
|
nth = 1;oChair = GetNearestObjectByTag("Chair", oPC,nth);
|
||||||
|
while(oChair != OBJECT_INVALID && GetSittingCreature(oChair) != OBJECT_INVALID)
|
||||||
|
{nth++;oChair = GetNearestObjectByTag("Chair", oPC,nth);}
|
||||||
|
|
||||||
|
nth = 1;oCouch = GetNearestObjectByTag("Couch", oPC,nth);
|
||||||
|
while(oCouch != OBJECT_INVALID && GetSittingCreature(oCouch) != OBJECT_INVALID)
|
||||||
|
{nth++;oChair = GetNearestObjectByTag("Couch", oPC,nth);}
|
||||||
|
|
||||||
|
nth = 1;oBenchPew = GetNearestObjectByTag("BenchPew", oPC,nth);
|
||||||
|
while(oBenchPew != OBJECT_INVALID && GetSittingCreature(oBenchPew) != OBJECT_INVALID)
|
||||||
|
{nth++;oChair = GetNearestObjectByTag("BenchPew", oPC,nth);}
|
||||||
|
/* 1.27 bug
|
||||||
|
nth = 1;oStool = GetNearestObjectByTag("Stool", oPC,nth);
|
||||||
|
while(oStool != OBJECT_INVALID && GetSittingCreature(oStool) != OBJECT_INVALID)
|
||||||
|
{nth++;oStool = GetNearestObjectByTag("Stool", oPC,nth);}
|
||||||
|
*/
|
||||||
|
// get the distance between the user and each object (-1.0 is the result if no
|
||||||
|
// object is found
|
||||||
|
float fDistanceChair = GetDistanceToObject(oChair);
|
||||||
|
float fDistanceBench = GetDistanceToObject(oBenchPew);
|
||||||
|
float fDistanceCouch = GetDistanceToObject(oCouch);
|
||||||
|
float fDistanceStool = GetDistanceToObject(oStool);
|
||||||
|
|
||||||
|
// if any of the objects are invalid (not there), change the return value
|
||||||
|
// to a high number so the distance math can work
|
||||||
|
if (fDistanceChair == -1.0)
|
||||||
|
{fDistanceChair =1000.0;}
|
||||||
|
|
||||||
|
if (fDistanceBench == -1.0)
|
||||||
|
{fDistanceBench = 1000.0;}
|
||||||
|
|
||||||
|
if (fDistanceCouch == -1.0)
|
||||||
|
{fDistanceCouch = 1000.0;}
|
||||||
|
|
||||||
|
if (fDistanceStool == -1.0)
|
||||||
|
{fDistanceStool = 1000.0;}
|
||||||
|
|
||||||
|
// find out which object is closest to the PC
|
||||||
|
if (fDistanceChair<fDistanceBench && fDistanceChair<fDistanceCouch && fDistanceChair<fDistanceStool)
|
||||||
|
{oSit=oChair;fDistSit=fDistanceChair;}
|
||||||
|
else if (fDistanceBench<fDistanceChair && fDistanceBench<fDistanceCouch && fDistanceBench<fDistanceStool)
|
||||||
|
{oSit=oBenchPew;fDistSit=fDistanceBench;}
|
||||||
|
else if (fDistanceCouch<fDistanceChair && fDistanceCouch<fDistanceBench && fDistanceCouch<fDistanceStool)
|
||||||
|
{oSit=oCouch;fDistSit=fDistanceCouch;}
|
||||||
|
else
|
||||||
|
//if (fDistanceStool<fDistanceChair && fDistanceStool<fDistanceBench && fDistanceStool<fDistanceCouch)
|
||||||
|
{oSit=oStool;fDistSit=fDistanceStool;}
|
||||||
|
|
||||||
|
if(oSit != OBJECT_INVALID && fDistSit < 12.0)
|
||||||
|
{
|
||||||
|
// if no one is sitting in the object the PC is closest to, have him sit in it
|
||||||
|
if (GetSittingCreature(oSit) == OBJECT_INVALID)
|
||||||
|
{
|
||||||
|
oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
|
||||||
|
oLeftHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
|
||||||
|
AssignCommand(oPC,ActionMoveToObject(oSit,FALSE,2.0)); //:: Presumably this will be fixed in a patch so that Plares will not run to chair
|
||||||
|
ActionUnequipItem(oRightHand); //:: Added to resolve clipping issues when seated
|
||||||
|
ActionUnequipItem(oLeftHand); //:: Added to resolve clipping issues when seated
|
||||||
|
ActionDoCommand(AssignCommand(oPC,ActionSit(oSit)));
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{SendMessageToPC(oPC,"The nearest chair is already taken ");}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{SendMessageToPC(oPC,"There are no chairs nearby");}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int iEmote = GetLocalInt(OBJECT_SELF, "dmfi_univ_int");
|
||||||
|
object oUser = OBJECT_SELF;
|
||||||
|
object oTarget = GetLocalObject(oUser, "dmfi_univ_target");
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
oTarget = oUser;
|
||||||
|
float fDur = 9999.0f; //Duration
|
||||||
|
|
||||||
|
switch(iEmote)
|
||||||
|
{
|
||||||
|
case 1: AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_DODGE_SIDE, 1.0)); break;
|
||||||
|
case 2: AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_DRINK, 1.0)); break;
|
||||||
|
case 3: AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_DODGE_DUCK, 1.0)); break;
|
||||||
|
case 4: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_DEAD_BACK, 1.0, fDur)); break;
|
||||||
|
case 5: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_DEAD_FRONT, 1.0, fDur)); break;
|
||||||
|
case 6: AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_READ, 1.0)); DelayCommand(3.0f, AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_READ, 1.0)));break;
|
||||||
|
case 7: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, fDur)); break;
|
||||||
|
case 81: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_TALK_PLEADING, 1.0, fDur)); break;
|
||||||
|
case 82: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_CONJURE1, 1.0, fDur)); break;
|
||||||
|
case 83: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_CONJURE2, 1.0, fDur)); break;
|
||||||
|
case 84: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_GET_LOW, 1.0, fDur)); break;
|
||||||
|
case 85: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_GET_MID, 1.0, fDur)); break;
|
||||||
|
case 86: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_MEDITATE, 1.0, fDur)); break;
|
||||||
|
case 87: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_TALK_FORCEFUL, 1.0, fDur)); break;
|
||||||
|
case 88: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_WORSHIP, 1.0, fDur)); break;
|
||||||
|
case 10: if (!GetLocalInt(oTarget, "hls_emotemute")) FloatingTextStringOnCreature("*emote* commands are off", oTarget, FALSE);
|
||||||
|
else FloatingTextStringOnCreature("*emote* commands are on", oTarget, FALSE);
|
||||||
|
SetLocalInt(oTarget, "hls_emotemute", abs(GetLocalInt(oTarget, "hls_emotemute") - 1)); break;
|
||||||
|
case 91: EmoteDance(oTarget); break;
|
||||||
|
case 92: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_PAUSE_DRUNK, 1.0, fDur)); break;
|
||||||
|
case 93: AssignCommand(oTarget, ActionForceFollowObject(GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oTarget), 2.0f)); break;
|
||||||
|
case 94: SitInNearestChair(oTarget); break;
|
||||||
|
case 95: AssignCommand(oTarget, ActionPlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, fDur)); DelayCommand(1.0f, AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_DRINK, 1.0))); DelayCommand(3.0f, AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, fDur)));break;
|
||||||
|
case 96: AssignCommand(oTarget, ActionPlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, fDur)); DelayCommand(1.0f, AssignCommand(oTarget, PlayAnimation( ANIMATION_FIREFORGET_READ, 1.0))); DelayCommand(3.0f, AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0, fDur)));break;
|
||||||
|
case 97: AssignCommand(oTarget, PlayAnimation( ANIMATION_LOOPING_SPASM, 1.0, fDur)); break;
|
||||||
|
case 98: SmokePipe(oTarget); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
288
src/dmfi/dmfi_x_fx.nss
Normal file
288
src/dmfi/dmfi_x_fx.nss
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
void CreateSetting(object oUser)
|
||||||
|
{
|
||||||
|
object oSetting = CreateObject(OBJECT_TYPE_CREATURE, "dmfi_setting", GetLocation(oUser));
|
||||||
|
DelayCommand(0.5f, AssignCommand(oSetting, ActionSpeakString(GetLocalString(oUser, "EffectSetting") + " is currently set at " + FloatToString(GetLocalFloat(oUser, GetLocalString(oUser, "EffectSetting"))))));
|
||||||
|
SetLocalObject(oSetting, "MyMaster", oUser);
|
||||||
|
SetLocalInt(oSetting, "hls_Listening", 1); //listen to all text
|
||||||
|
SetListening(oSetting, TRUE); //be sure NPC is listening
|
||||||
|
}
|
||||||
|
|
||||||
|
//An FX Wand function
|
||||||
|
void FXWand_Firestorm(object oDM)
|
||||||
|
{
|
||||||
|
|
||||||
|
// FireStorm Effect
|
||||||
|
location lDMLoc = GetLocation ( oDM);
|
||||||
|
|
||||||
|
|
||||||
|
// tell the DM object to rain fire and destruction
|
||||||
|
AssignCommand ( oDM, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect ( VFX_FNF_METEOR_SWARM), lDMLoc));
|
||||||
|
AssignCommand ( oDM, DelayCommand (1.0, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect (VFX_FNF_SCREEN_SHAKE), lDMLoc)));
|
||||||
|
|
||||||
|
// create some fires
|
||||||
|
object oTargetArea = GetArea(oDM);
|
||||||
|
int nXPos, nYPos, nCount;
|
||||||
|
for(nCount = 0; nCount < 15; nCount++)
|
||||||
|
{
|
||||||
|
nXPos = Random(30) - 15;
|
||||||
|
nYPos = Random(30) - 15;
|
||||||
|
|
||||||
|
vector vNewVector = GetPosition(oDM);
|
||||||
|
vNewVector.x += nXPos;
|
||||||
|
vNewVector.y += nYPos;
|
||||||
|
|
||||||
|
location lFireLoc = Location(oTargetArea, vNewVector, 0.0);
|
||||||
|
object oFire = CreateObject ( OBJECT_TYPE_PLACEABLE, "plc_flamelarge", lFireLoc, FALSE);
|
||||||
|
object oDust = CreateObject ( OBJECT_TYPE_PLACEABLE, "plc_dustplume", lFireLoc, FALSE);
|
||||||
|
DelayCommand ( 10.0, DestroyObject ( oFire));
|
||||||
|
DelayCommand ( 14.0, DestroyObject ( oDust));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//An FX Wand function
|
||||||
|
void FXWand_Earthquake(object oDM)
|
||||||
|
{
|
||||||
|
// Earthquake Effect by Jhenne, 06/29/02
|
||||||
|
// declare variables used for targetting and commands.
|
||||||
|
location lDMLoc = GetLocation ( oDM);
|
||||||
|
|
||||||
|
// tell the DM object to shake the screen
|
||||||
|
AssignCommand( oDM, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SCREEN_SHAKE), lDMLoc));
|
||||||
|
AssignCommand ( oDM, DelayCommand( 2.8, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect ( VFX_FNF_SCREEN_BUMP), lDMLoc)));
|
||||||
|
AssignCommand ( oDM, DelayCommand( 3.0, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect ( VFX_FNF_SCREEN_SHAKE), lDMLoc)));
|
||||||
|
AssignCommand ( oDM, DelayCommand( 4.5, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect ( VFX_FNF_SCREEN_BUMP), lDMLoc)));
|
||||||
|
AssignCommand ( oDM, DelayCommand( 5.8, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect ( VFX_FNF_SCREEN_BUMP), lDMLoc)));
|
||||||
|
// tell the DM object to play an earthquake sound
|
||||||
|
AssignCommand ( oDM, PlaySound ("as_cv_boomdist1"));
|
||||||
|
AssignCommand ( oDM, DelayCommand ( 2.0, PlaySound ("as_wt_thunderds3")));
|
||||||
|
AssignCommand ( oDM, DelayCommand ( 4.0, PlaySound ("as_cv_boomdist1")));
|
||||||
|
// create a dust plume at the DM and clicking location
|
||||||
|
object oTargetArea = GetArea(oDM);
|
||||||
|
int nXPos, nYPos, nCount;
|
||||||
|
for(nCount = 0; nCount < 15; nCount++)
|
||||||
|
{
|
||||||
|
nXPos = Random(30) - 15;
|
||||||
|
nYPos = Random(30) - 15;
|
||||||
|
|
||||||
|
vector vNewVector = GetPosition(oDM);
|
||||||
|
vNewVector.x += nXPos;
|
||||||
|
vNewVector.y += nYPos;
|
||||||
|
|
||||||
|
location lDustLoc = Location(oTargetArea, vNewVector, 0.0);
|
||||||
|
object oDust = CreateObject ( OBJECT_TYPE_PLACEABLE, "plc_dustplume", lDustLoc, FALSE);
|
||||||
|
DelayCommand ( 4.0, DestroyObject ( oDust));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//An FX Wand function
|
||||||
|
void FXWand_Lightning(object oDM, location lDMLoc)
|
||||||
|
{
|
||||||
|
// Lightning Strike by Jhenne. 06/29/02
|
||||||
|
// tell the DM object to create a Lightning visual effect at targetted location
|
||||||
|
AssignCommand( oDM, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_LIGHTNING_M), lDMLoc));
|
||||||
|
// tell the DM object to play a thunderclap
|
||||||
|
AssignCommand ( oDM, PlaySound ("as_wt_thundercl3"));
|
||||||
|
// create a scorch mark where the lightning hit
|
||||||
|
object oScorch = CreateObject ( OBJECT_TYPE_PLACEABLE, "plc_weathmark", lDMLoc, FALSE);
|
||||||
|
object oTargetArea = GetArea(oDM);
|
||||||
|
int nXPos, nYPos, nCount;
|
||||||
|
for(nCount = 0; nCount < 5; nCount++)
|
||||||
|
{
|
||||||
|
nXPos = Random(10) - 5;
|
||||||
|
nYPos = Random(10) - 5;
|
||||||
|
|
||||||
|
vector vNewVector = GetPositionFromLocation(lDMLoc);
|
||||||
|
vNewVector.x += nXPos;
|
||||||
|
vNewVector.y += nYPos;
|
||||||
|
|
||||||
|
location lNewLoc = Location(oTargetArea, vNewVector, 0.0);
|
||||||
|
AssignCommand( oDM, ApplyEffectAtLocation ( DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_LIGHTNING_S), lNewLoc));
|
||||||
|
}
|
||||||
|
DelayCommand ( 20.0, DestroyObject ( oScorch));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FnFEffect(object oUser, int iVFX, location lEffect, float fDelay)
|
||||||
|
{
|
||||||
|
if (fDelay>2.0) FloatingTextStringOnCreature("Delay effect created", oUser, FALSE);
|
||||||
|
DelayCommand( fDelay, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(iVFX),lEffect));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int iDayMusic, iNightMusic, iBattleMusic;
|
||||||
|
int iEffect = GetLocalInt(OBJECT_SELF, "dmfi_univ_int");
|
||||||
|
location lEffect = GetLocalLocation(OBJECT_SELF, "dmfi_univ_location");
|
||||||
|
object oUser = OBJECT_SELF;
|
||||||
|
float fDelay;
|
||||||
|
float fDuration;
|
||||||
|
float fBeamDuration;
|
||||||
|
object oTarget;
|
||||||
|
|
||||||
|
fDelay = GetLocalFloat(oUser, "dmfi_effectdelay");
|
||||||
|
fDuration = GetLocalFloat(oUser, "dmfi_effectduration");
|
||||||
|
fBeamDuration = GetLocalFloat(oUser, "dmfi_beamduration");
|
||||||
|
|
||||||
|
if (!GetIsObjectValid(GetLocalObject(oUser, "dmfi_univ_target")))
|
||||||
|
oTarget = oUser;
|
||||||
|
else
|
||||||
|
oTarget = GetLocalObject(oUser, "dmfi_univ_target");
|
||||||
|
switch(iEffect)
|
||||||
|
{
|
||||||
|
//SoU/HotU Duration Effects(must have a target)
|
||||||
|
case 101: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BIGBYS_CLENCHED_FIST), oTarget, fDuration); break;
|
||||||
|
case 102: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BIGBYS_CRUSHING_HAND), oTarget, fDuration); break;
|
||||||
|
case 103: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BIGBYS_GRASPING_HAND), oTarget, fDuration); break;
|
||||||
|
case 104: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BIGBYS_INTERPOSING_HAND), oTarget, fDuration); break;
|
||||||
|
case 105: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_ICESKIN), oTarget, fDuration); break;
|
||||||
|
case 106: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_INFERNO), oTarget, fDuration); break;
|
||||||
|
case 107: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PIXIEDUST), oTarget, fDuration); break;
|
||||||
|
case 108: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), oTarget, fDuration); break;
|
||||||
|
case 109: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_FREEZE_ANIMATION), oTarget, fDuration); break;
|
||||||
|
case 100: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_GHOSTLY_PULSE), oTarget, fDuration); break;
|
||||||
|
//Magical Duration Effects
|
||||||
|
case 10: ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_CALTROPS),lEffect, fDuration); break;
|
||||||
|
case 11: ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_TENTACLE),lEffect, fDuration); break;
|
||||||
|
case 12: ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_WEB_MASS),lEffect, fDuration); break;
|
||||||
|
case 13: FnFEffect(oUser, VFX_FNF_GAS_EXPLOSION_MIND,lEffect, fDelay); break;
|
||||||
|
case 14: FnFEffect(oUser, VFX_FNF_LOS_HOLY_30,lEffect, fDelay); break;
|
||||||
|
case 15: FnFEffect(oUser, VFX_FNF_LOS_EVIL_30,lEffect, fDelay); break;
|
||||||
|
case 16: FnFEffect(oUser, VFX_FNF_SMOKE_PUFF,lEffect, fDelay); break;
|
||||||
|
case 17: FnFEffect(oUser, VFX_FNF_GAS_EXPLOSION_NATURE,lEffect, fDelay); break;
|
||||||
|
case 18: FnFEffect(oUser, VFX_FNF_DISPEL_DISJUNCTION,lEffect, fDelay); break;
|
||||||
|
case 19: FnFEffect(oUser, VFX_FNF_GAS_EXPLOSION_EVIL,lEffect, fDelay); break;
|
||||||
|
//Magical Status Effects (must have a target)
|
||||||
|
case 21: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PROT_BARKSKIN), oTarget, fDuration); break;
|
||||||
|
case 22: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PROT_GREATER_STONESKIN), oTarget, fDuration); break;
|
||||||
|
case 23: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_ENTANGLE), oTarget, fDuration); break;
|
||||||
|
case 24: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_ETHEREAL_VISAGE), oTarget, fDuration); break;
|
||||||
|
case 25: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_GHOSTLY_VISAGE), oTarget, fDuration); break;
|
||||||
|
case 26: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_INVISIBILITY), oTarget, fDuration); break;
|
||||||
|
case 27: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BARD_SONG), oTarget, fDuration); break;
|
||||||
|
case 28: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_GLOBE_INVULNERABILITY), oTarget, fDuration); break;
|
||||||
|
case 29: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PARALYZED), oTarget, fDuration); break;
|
||||||
|
case 20: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PROT_SHADOW_ARMOR), oTarget, fDuration); break;
|
||||||
|
//Magical Burst Effects
|
||||||
|
case 31: FnFEffect(oUser, VFX_FNF_FIREBALL,lEffect, fDelay); break;
|
||||||
|
case 32: FnFEffect(oUser, VFX_FNF_FIRESTORM,lEffect, fDelay); break;
|
||||||
|
case 33: FnFEffect(oUser, VFX_FNF_HORRID_WILTING,lEffect, fDelay); break;
|
||||||
|
case 34: FnFEffect(oUser, VFX_FNF_HOWL_WAR_CRY,lEffect, fDelay); break;
|
||||||
|
case 35: FnFEffect(oUser, VFX_FNF_IMPLOSION,lEffect, fDelay); break;
|
||||||
|
case 36: FnFEffect(oUser, VFX_FNF_PWKILL,lEffect, fDelay); break;
|
||||||
|
case 37: FnFEffect(oUser, VFX_FNF_PWSTUN,lEffect, fDelay); break;
|
||||||
|
case 38: FnFEffect(oUser, VFX_FNF_SOUND_BURST,lEffect, fDelay); break;
|
||||||
|
case 39: FnFEffect(oUser, VFX_FNF_STRIKE_HOLY,lEffect, fDelay); break;
|
||||||
|
case 30: FnFEffect(oUser, VFX_FNF_WORD,lEffect, fDelay); break;
|
||||||
|
//Lighting Effects
|
||||||
|
case 41: ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BLACKOUT),lEffect, fDuration); break;
|
||||||
|
case 42: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_ANTI_LIGHT_10),oTarget, fDuration); break;
|
||||||
|
case 43: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_BLUE_20),oTarget, fDuration); break;
|
||||||
|
case 44: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_GREY_20),oTarget, fDuration); break;
|
||||||
|
case 45: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_ORANGE_20),oTarget, fDuration); break;
|
||||||
|
case 46: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_PURPLE_20),oTarget, fDuration); break;
|
||||||
|
case 47: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_RED_20),oTarget, fDuration); break;
|
||||||
|
case 48: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_WHITE_20),oTarget, fDuration); break;
|
||||||
|
case 49: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_LIGHT_YELLOW_20),oTarget, fDuration); break;
|
||||||
|
//Beam Effects
|
||||||
|
case 50: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_CHAIN, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||||
|
case 51: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_COLD, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||||
|
case 52: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_EVIL, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||||
|
case 53: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_FIRE, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||||
|
case 54: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_FIRE_LASH, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||||
|
case 55: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_HOLY, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||||
|
case 56: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_LIGHTNING, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||||
|
case 57: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_MIND, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||||
|
case 58: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_ODD, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||||
|
case 59: ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_COLD, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_EVIL, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_FIRE, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_FIRE_LASH, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_HOLY, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_LIGHTNING, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_MIND, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_ODD, oUser, BODY_NODE_CHEST, FALSE), oTarget, fBeamDuration); break;
|
||||||
|
|
||||||
|
//Environmental Effects
|
||||||
|
case 60: FnFEffect(oUser, VFX_FNF_NATURES_BALANCE,lEffect, fDelay);break;
|
||||||
|
case 61: FXWand_Lightning(oTarget, lEffect); break;
|
||||||
|
case 62: FXWand_Firestorm(oTarget); break;
|
||||||
|
case 63: FXWand_Earthquake(oTarget); break;
|
||||||
|
case 64: FnFEffect(oUser, VFX_FNF_ICESTORM,lEffect, fDelay); break;
|
||||||
|
case 65: FnFEffect(oUser, VFX_FNF_SUNBEAM,lEffect, fDelay); break;
|
||||||
|
case 66: SetWeather(GetArea(oUser), WEATHER_CLEAR); break;
|
||||||
|
case 67: SetWeather(GetArea(oUser), WEATHER_RAIN); break;
|
||||||
|
case 68: SetWeather(GetArea(oUser), WEATHER_SNOW); break;
|
||||||
|
case 69: SetWeather(GetArea(oUser), WEATHER_USE_AREA_SETTINGS); break;
|
||||||
|
//Summon Effects
|
||||||
|
case 71: FnFEffect(oUser, VFX_FNF_SUMMON_MONSTER_1,lEffect, fDelay); break;
|
||||||
|
case 72: FnFEffect(oUser, VFX_FNF_SUMMON_MONSTER_2,lEffect, fDelay); break;
|
||||||
|
case 73: FnFEffect(oUser, VFX_FNF_SUMMON_MONSTER_3,lEffect, fDelay); break;
|
||||||
|
case 74: FnFEffect(oUser, VFX_FNF_SUMMON_CELESTIAL,lEffect, fDelay); break;
|
||||||
|
case 75: FnFEffect(oUser, VFX_FNF_SUMMONDRAGON,lEffect, fDelay); break;
|
||||||
|
case 76: FnFEffect(oUser, VFX_FNF_SUMMON_EPIC_UNDEAD,lEffect, fDelay); break;
|
||||||
|
case 77: FnFEffect(oUser, VFX_FNF_SUMMON_GATE,lEffect, fDelay); break;
|
||||||
|
case 78: FnFEffect(oUser, VFX_FNF_SUMMON_UNDEAD,lEffect, fDelay); break;
|
||||||
|
case 79: FnFEffect(oUser, VFX_FNF_UNDEAD_DRAGON,lEffect, fDelay); break;
|
||||||
|
case 70: FnFEffect(oUser, VFX_FNF_WAIL_O_BANSHEES,lEffect, fDelay); break;
|
||||||
|
//SoU/HotU Effects
|
||||||
|
case 80: ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(322), oTarget, fDuration); break;
|
||||||
|
case 81: ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(132), oTarget, fDuration); break;
|
||||||
|
case 82: ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(133), oTarget, fDuration); break;
|
||||||
|
case 83: ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(136), oTarget, fDuration); break;
|
||||||
|
case 84: ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(137), oTarget, fDuration); break;
|
||||||
|
case 85: FnFEffect(oUser, VFX_FNF_DEMON_HAND,lEffect, fDelay); break;
|
||||||
|
case 86: FnFEffect(oUser, VFX_FNF_ELECTRIC_EXPLOSION,lEffect, fDelay); break;
|
||||||
|
case 87: FnFEffect(oUser, VFX_FNF_GREATER_RUIN,lEffect, fDelay); break;
|
||||||
|
case 88: FnFEffect(oUser, VFX_FNF_MYSTICAL_EXPLOSION,lEffect, fDelay); break;
|
||||||
|
case 89: FnFEffect(oUser, VFX_FNF_SWINGING_BLADE,lEffect, fDelay); break;
|
||||||
|
//Settings
|
||||||
|
case 91:
|
||||||
|
SetLocalString(oUser, "EffectSetting", "dmfi_effectduration");
|
||||||
|
CreateSetting(oUser);
|
||||||
|
break;
|
||||||
|
case 92:
|
||||||
|
SetLocalString(oUser, "EffectSetting", "dmfi_effectdelay");
|
||||||
|
CreateSetting(oUser);
|
||||||
|
break;
|
||||||
|
case 93:
|
||||||
|
SetLocalString(oUser, "EffectSetting", "dmfi_beamduration");
|
||||||
|
CreateSetting(oUser);
|
||||||
|
break;
|
||||||
|
case 94: //Change Day Music
|
||||||
|
iDayMusic = MusicBackgroundGetDayTrack(GetArea(oUser)) + 1;
|
||||||
|
if (iDayMusic > 33) iDayMusic = 49;
|
||||||
|
if (iDayMusic > 55) iDayMusic = 1;
|
||||||
|
MusicBackgroundStop(GetArea(oUser));
|
||||||
|
MusicBackgroundChangeDay(GetArea(oUser), iDayMusic);
|
||||||
|
MusicBackgroundPlay(GetArea(oUser));
|
||||||
|
break;
|
||||||
|
case 95: //Change Night Music
|
||||||
|
iNightMusic = MusicBackgroundGetDayTrack(GetArea(oUser)) + 1;
|
||||||
|
if (iNightMusic > 33) iNightMusic = 49;
|
||||||
|
if (iNightMusic > 55) iNightMusic = 1;
|
||||||
|
MusicBackgroundStop(GetArea(oUser));
|
||||||
|
MusicBackgroundChangeNight(GetArea(oUser), iNightMusic);
|
||||||
|
MusicBackgroundPlay(GetArea(oUser));
|
||||||
|
break;
|
||||||
|
case 96: //Play Background Music
|
||||||
|
MusicBackgroundPlay(GetArea(oUser));
|
||||||
|
break;
|
||||||
|
case 97: //Stop Background Music
|
||||||
|
MusicBackgroundStop(GetArea(oUser));
|
||||||
|
break;
|
||||||
|
case 98: //Change and Play Battle Music
|
||||||
|
iBattleMusic = MusicBackgroundGetBattleTrack(GetArea(oUser)) + 1;
|
||||||
|
if (iBattleMusic < 34 || iBattleMusic > 48) iBattleMusic = 34;
|
||||||
|
MusicBattleStop(GetArea(oUser));
|
||||||
|
MusicBattleChange(GetArea(oUser), iBattleMusic);
|
||||||
|
MusicBattlePlay(GetArea(oUser));
|
||||||
|
break;
|
||||||
|
case 99: //Stop Battle Music
|
||||||
|
MusicBattleStop(GetArea(oUser));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
DeleteLocalObject(oUser, "EffectTarget");
|
||||||
|
return;
|
||||||
|
}
|
||||||
@@ -1,11 +1,144 @@
|
|||||||
// bg_age_cv.nss
|
// bg_age_cv.nss
|
||||||
#include "inc_dynconv"
|
#include "inc_dynconv"
|
||||||
#include "x2_inc_switches"
|
#include "x2_inc_switches"
|
||||||
|
#include "inc_persist_loca"
|
||||||
|
#include "te_afflic_func"
|
||||||
|
|
||||||
const int STAGE_LIST = 0;
|
const int STAGE_LIST = 0;
|
||||||
const int STAGE_CONFIRM = 1;
|
const int STAGE_CONFIRM = 1;
|
||||||
|
|
||||||
void main() {
|
// Ensure the PC Data Object exists; create if missing
|
||||||
|
object EnsurePlayerDataObject(object oPC)
|
||||||
|
{
|
||||||
|
object oItem = GetItemPossessedBy(oPC, "PC_Data_Object");
|
||||||
|
if (!GetIsObjectValid(oItem))
|
||||||
|
{
|
||||||
|
oItem = CreateItemOnObject("pc_data_object", oPC);
|
||||||
|
SendMessageToPC(oPC, "Language data object recreated");
|
||||||
|
WriteTimestampedLogEntry("Language data object recreated");
|
||||||
|
}
|
||||||
|
return oItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = GetPCSpeaker();
|
||||||
|
SendMessageToPC(oPC, "DEBUG: bg_age_cv main() entered");
|
||||||
|
|
||||||
|
object oItem = EnsurePlayerDataObject(oPC);
|
||||||
|
|
||||||
|
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
|
||||||
|
int nStage = GetStage(oPC);
|
||||||
|
|
||||||
|
// Required guard: abort if nValue is 0
|
||||||
|
if (nValue == 0) return;
|
||||||
|
|
||||||
|
if (nValue == DYNCONV_SETUP_STAGE)
|
||||||
|
{
|
||||||
|
if (!GetIsStageSetUp(nStage, oPC))
|
||||||
|
{
|
||||||
|
if (nStage == STAGE_LIST)
|
||||||
|
{
|
||||||
|
SetHeader("Now for the finishing touches. If you would like to apply an age modifier to your character, you may do so. Aging affects are as follows:\n" +
|
||||||
|
"Young Age/Opt Out: No effects\n" +
|
||||||
|
"Middle Age: -1 STR, -1 DEX, -1 CON, +1 INT, +1 WIS, +1 CHA\n" +
|
||||||
|
"Old Age: -2 STR, -2 DEX, -2 CON, +2 INT, +2 WIS, +2 CHA\n" +
|
||||||
|
"Venerable Age: -3 STR, -3 DEX, -3 CON, +3 INT, +3 WIS, +3 CHA");
|
||||||
|
|
||||||
|
// Store descriptive text for each age choice
|
||||||
|
SetLocalString(oPC, "age_text_0", "You are in the prime of your youth, with physical abilities at their peak and mental faculties still developing. This represents a character starting their adventuring career in their late teens or early twenties, with no modifiers to abilities.");
|
||||||
|
SetLocalString(oPC, "age_text_1", "You have reached middle age, where the physical toll of years begins to show, but experience and wisdom have sharpened your mind. Your body has begun to slow (-1 STR, -1 DEX, -1 CON) while your mental faculties have matured (+1 INT, +1 WIS, +1 CHA).");
|
||||||
|
SetLocalString(oPC, "age_text_2", "The weight of many decades rests upon you. Physical decline is more pronounced (-2 STR, -2 DEX, -2 CON) but your accumulated knowledge and insight have grown significantly (+2 INT, +2 WIS, +2 CHA). You are a veteran of life's trials.");
|
||||||
|
SetLocalString(oPC, "age_text_3", "You have lived a very long life, and your body shows the full extent of your years (-3 STR, -3 DEX, -3 CON). However, your mind is a repository of vast knowledge and profound wisdom (+3 INT, +3 WIS, +3 CHA). You are truly an elder whose experience spans generations.");
|
||||||
|
|
||||||
|
AddChoice("Young Age / Opt Out", 0, oPC);
|
||||||
|
AddChoice("Middle Age", 1, oPC);
|
||||||
|
AddChoice("Old Age", 2, oPC);
|
||||||
|
AddChoice("Venerable Age", 3, oPC);
|
||||||
|
MarkStageSetUp(nStage, oPC);
|
||||||
|
SetDefaultTokens();
|
||||||
|
}
|
||||||
|
else if (nStage == STAGE_CONFIRM)
|
||||||
|
{
|
||||||
|
int nSelected = GetLocalInt(oPC, "age_selected");
|
||||||
|
string sAgeText = GetLocalString(oPC, "age_text_" + IntToString(nSelected));
|
||||||
|
string sPrompt = sAgeText + "\n\nAre you sure you want to apply this age modifier?";
|
||||||
|
SetHeader(sPrompt);
|
||||||
|
AddChoice("Yes", nSelected, oPC);
|
||||||
|
AddChoice("No", -1, oPC);
|
||||||
|
MarkStageSetUp(nStage, oPC);
|
||||||
|
SetDefaultTokens();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetupTokens();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int nChoice = GetChoice(oPC);
|
||||||
|
if (nStage == STAGE_LIST)
|
||||||
|
{
|
||||||
|
SetLocalInt(oPC, "age_selected", nChoice);
|
||||||
|
SetStage(STAGE_CONFIRM, oPC);
|
||||||
|
}
|
||||||
|
else if (nStage == STAGE_CONFIRM)
|
||||||
|
{
|
||||||
|
if (nChoice >= 0)
|
||||||
|
{
|
||||||
|
string sGrant;
|
||||||
|
switch (nChoice)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0:
|
||||||
|
{// youthful
|
||||||
|
//sGrant = "te_bg_a_n";
|
||||||
|
SetLocalInt(oItem, "BG_Select",7);
|
||||||
|
SetPersistantLocalInt(oPC, "BG_Select", 7);
|
||||||
|
SetLocalInt(oItem, "CC6", AGE_CATEGORY_YOUTHFUL);
|
||||||
|
SetPersistantLocalInt(oPC, "CC6", AGE_CATEGORY_YOUTHFUL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{// middle-aged
|
||||||
|
//sGrant = "te_bg_a_m";
|
||||||
|
SetLocalInt(oItem, "BG_Select",7);
|
||||||
|
SetPersistantLocalInt(oPC, "BG_Select", 7);
|
||||||
|
SetLocalInt(oItem, "CC6", AGE_CATEGORY_MIDDLE);
|
||||||
|
SetPersistantLocalInt(oPC, "CC6", AGE_CATEGORY_MIDDLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
//sGrant = "te_bg_a_o";
|
||||||
|
SetLocalInt(oItem, "BG_Select",7);
|
||||||
|
SetPersistantLocalInt(oPC, "BG_Select", 7);
|
||||||
|
SetLocalInt(oItem, "CC6", AGE_CATEGORY_OLD);
|
||||||
|
SetPersistantLocalInt(oPC, "CC6", AGE_CATEGORY_OLD);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
//sGrant = "te_bg_a_v"; break;
|
||||||
|
SetLocalInt(oItem, "BG_Select",7);
|
||||||
|
SetPersistantLocalInt(oPC, "BG_Select", 7);
|
||||||
|
SetLocalInt(oItem, "CC6", AGE_CATEGORY_VENERABLE);
|
||||||
|
SetPersistantLocalInt(oPC, "CC6", AGE_CATEGORY_VENERABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if (sGrant != "") ExecuteScript(sGrant, oPC);
|
||||||
|
// Conversation ends naturally
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetStage(STAGE_LIST, oPC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetStage(nStage, oPC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* void main() {
|
||||||
object oPC = GetPCSpeaker();
|
object oPC = GetPCSpeaker();
|
||||||
SendMessageToPC(oPC, "DEBUG: bg_age_cv main() entered");
|
SendMessageToPC(oPC, "DEBUG: bg_age_cv main() entered");
|
||||||
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
|
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
|
||||||
@@ -62,4 +195,4 @@ void main() {
|
|||||||
}
|
}
|
||||||
SetStage(nStage, oPC);
|
SetStage(nStage, oPC);
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
@@ -1,289 +0,0 @@
|
|||||||
// LordValinar's Scripts - Background Application (12/18/2023)
|
|
||||||
// =============================================================================
|
|
||||||
/*
|
|
||||||
The final process, to take all of the saved settings from character
|
|
||||||
creation and apply them here. (This was to prevent exploits)
|
|
||||||
*/
|
|
||||||
// =============================================================================
|
|
||||||
#include "nwnx_creature"
|
|
||||||
#include "te_afflic_func"
|
|
||||||
#include "lv_inc"
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
object oPC = OBJECT_SELF; // from ExecuteScript()
|
|
||||||
object oItem = GetItemPossessedBy(oPC, "PC_Data_Object");
|
|
||||||
int nSubrace = GetLocalInt(oItem, "CC0"); /**/ DeleteLocalInt(oItem, "CC0");
|
|
||||||
int nClass = GetLocalInt(oItem, "CC1"); /**/ DeleteLocalInt(oItem, "CC1");
|
|
||||||
int nBackground = GetLocalInt(oItem, "CC2"); /**/ DeleteLocalInt(oItem, "CC2");
|
|
||||||
int nDeity = GetLocalInt(oItem, "CC3"); /**/ DeleteLocalInt(oItem, "CC3");
|
|
||||||
int nAge = GetLocalInt(oItem, "CC6"); /**/ DeleteLocalInt(oItem, "CC6");
|
|
||||||
int bDisfigured = GetLocalInt(oItem, "CC7"); /**/ DeleteLocalInt(oItem, "CC7");
|
|
||||||
// Stats
|
|
||||||
int iCL = GetHitDice(oPC);
|
|
||||||
int iSTR = GetAbilityScore(oPC, ABILITY_STRENGTH, TRUE);
|
|
||||||
int iDEX = GetAbilityScore(oPC, ABILITY_DEXTERITY, TRUE);
|
|
||||||
int iCON = GetAbilityScore(oPC, ABILITY_CONSTITUTION, TRUE);
|
|
||||||
int iINT = GetAbilityScore(oPC, ABILITY_INTELLIGENCE, TRUE);
|
|
||||||
int iWIS = GetAbilityScore(oPC, ABILITY_WISDOM, TRUE);
|
|
||||||
int iCHA = GetAbilityScore(oPC, ABILITY_CHARISMA, TRUE);
|
|
||||||
// Skills
|
|
||||||
int iHide = GetSkillRank(SKILL_HIDE, oPC, TRUE);
|
|
||||||
int iBluff = GetSkillRank(SKILL_BLUFF, oPC, TRUE);
|
|
||||||
int iSpot = GetSkillRank(SKILL_SPOT, oPC, TRUE);
|
|
||||||
int iListen = GetSkillRank(SKILL_LISTEN, oPC, TRUE);
|
|
||||||
int iLore = GetSkillRank(SKILL_LORE, oPC, TRUE);
|
|
||||||
int iMoveSil = GetSkillRank(SKILL_MOVE_SILENTLY, oPC, TRUE);
|
|
||||||
int iSpellCraft = GetSkillRank(SKILL_SPELLCRAFT, oPC, TRUE);
|
|
||||||
// Effects
|
|
||||||
effect eSpellResist = EffectSpellResistanceIncrease(11+iCL);
|
|
||||||
|
|
||||||
// Step 0: Subrace/Ethnicity
|
|
||||||
if (nSubrace > 0) NWNX_Creature_AddFeatByLevel(oPC, nSubrace, 1);
|
|
||||||
switch (nSubrace)
|
|
||||||
{
|
|
||||||
case ETHNICITY_TETHYRIAN: case ETHNICITY_CALISHITE: {
|
|
||||||
SetLocalInt(oItem, "23", 1); // Language: Alzhedo
|
|
||||||
} break;
|
|
||||||
case ETHNICITY_CHONDATHAN: {
|
|
||||||
SetLocalInt(oItem, "53", 1); // Language: Chondathan
|
|
||||||
} break;
|
|
||||||
case ETHNICITY_DAMARAN: {
|
|
||||||
SetLocalInt(oItem, "56", 1); // Language: Damaran
|
|
||||||
} break;
|
|
||||||
case 1445: { // Talfirian
|
|
||||||
SetLocalInt(oItem, "38", 1); // Language: Talfiric
|
|
||||||
} break;
|
|
||||||
case ETHNICITY_ILLUSKAN: {
|
|
||||||
SetLocalInt(oItem, "22", 1); // Language: Illuskan
|
|
||||||
} break;
|
|
||||||
case 1447: { // Imaskari
|
|
||||||
SetLocalInt(oItem, "46", 1); // Language: Undercommon
|
|
||||||
} break;
|
|
||||||
case ETHNICITY_MULAN: {
|
|
||||||
SetLocalInt(oItem, "27", 1); // Language: Mulanese
|
|
||||||
} break;
|
|
||||||
case ETHNICITY_RASHEMI: {
|
|
||||||
SetLocalInt(oItem, "30", 1); // Langauge: Rashemi
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_TIEFLING: {
|
|
||||||
SetLocalInt(oItem, "iPCSubrace", 11);
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 1);
|
|
||||||
SetSubRace(oPC, "Tiefling");
|
|
||||||
NWNX_Creature_AddFeatByLevel(oPC,228,1); // Darkvision
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT +2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX +2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA -2);
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_BLUFF, iBluff +2);
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_HIDE, iHide+2);
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_NAT_LYCAN: {
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 2);
|
|
||||||
if (GetRacialType(oPC) == RACIAL_TYPE_ELF) {
|
|
||||||
SetSubRace(oPC, "Lythari");
|
|
||||||
} else {
|
|
||||||
SetSubRace(oPC, "Natural Lycanthrope");
|
|
||||||
}
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS + 2);
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_AASIMAR: {
|
|
||||||
SetLocalInt(oItem, "iPCSubrace", 10);
|
|
||||||
SetLocalInt(oItem, "PC_ECL",1);
|
|
||||||
SetSubRace(oPC, "Aasimar");
|
|
||||||
NWNX_Creature_AddFeatByLevel(oPC,228,1); // Darkvision
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS +2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA +2);
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_SPOT, iSpot +2);
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_LISTEN, iListen+2);
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_GOLD_DWARF: {
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 0);
|
|
||||||
SetSubRace(oPC, "Gold Dwarf");
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA +4);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX -2);
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_GREY_DWARF: {
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 2);
|
|
||||||
SetSubRace(oPC, "Grey Dwarf");
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_MOVE_SILENTLY, iMoveSil +4);
|
|
||||||
AddSubraceEffect(oPC, EffectImmunity(IMMUNITY_TYPE_POISON));
|
|
||||||
AddSubraceEffect(oPC, EffectImmunity(IMMUNITY_TYPE_PARALYSIS));
|
|
||||||
SetLocalInt(oItem, "64", 1); // Language: Duergar
|
|
||||||
SetLocalInt(oItem, "46", 1); // Language: Undercommon
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_SHIELD_DWARF: {
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 0);
|
|
||||||
SetSubRace(oPC, "Shield Dwarf");
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_COPPER_ELF: {
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 0);
|
|
||||||
SetSubRace(oPC, "Copper Elf");
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_STRENGTH, iSTR +2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT -2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA -2);
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_DARK_ELF: {
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 2);
|
|
||||||
SetSubRace(oPC, "Dark Elf");
|
|
||||||
NWNX_Creature_AddFeatByLevel(oPC, 228, 1); // Darkvision
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT +2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA +2);
|
|
||||||
AddSubraceEffect(oPC, eSpellResist);
|
|
||||||
SetLocalInt(oItem, "81", 1); // Language: Drow
|
|
||||||
SetLocalInt(oItem, "46", 1); // Language: Undercommon
|
|
||||||
SetLocalInt(oItem, "13", 1); // Language: Drow Sign
|
|
||||||
} break;
|
|
||||||
case 1458: { // BACKGROUND_ELF_FEYRI
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 3);
|
|
||||||
SetSubRace(oPC, "Fey'ri");
|
|
||||||
NWNX_Creature_AddFeatByLevel(oPC, 228, 1); // Darkvision
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX +2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON -2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT +2);
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_BLUFF, iBluff +2);
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_HIDE, iHide +2);
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_GREEN_ELF: {
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 0);
|
|
||||||
SetSubRace(oPC, "Green Elf");
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON +4);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT -2);
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_GOLD_ELF: {
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 0);
|
|
||||||
SetSubRace(oPC, "Gold Elf");
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX -2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT +2);
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_SILVER_ELF: {
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 0);
|
|
||||||
SetSubRace(oPC, "Silver Elf");
|
|
||||||
} break;
|
|
||||||
case 1452: { // BACKGROUND_GNOME_DEEP
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 2);
|
|
||||||
SetSubRace(oPC, "Deep Gnome");
|
|
||||||
NWNX_Creature_AddFeatByLevel(oPC,nSubrace,1);
|
|
||||||
NWNX_Creature_AddFeatByLevel(oPC,228,1); // Darkvision
|
|
||||||
NWNX_Creature_AddFeatByLevel(oPC,227,1); // Stonecunning
|
|
||||||
AddSubraceEffect(oPC, eSpellResist);
|
|
||||||
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX +2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON -4);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS +2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA -4);
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_HIDE, iHide +2);
|
|
||||||
SetLocalInt(oItem,"46",1); // Language: Undercommon
|
|
||||||
} break;
|
|
||||||
case 1453: { // BACKGROUND_GNOME_FOREST
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 1);
|
|
||||||
SetSubRace(oPC, "Forest Gnome");
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_HIDE, iHide + 4);
|
|
||||||
SetLocalInt(oItem, "8", 1); // Language: Animals
|
|
||||||
} break;
|
|
||||||
case 1454: { // BACKGROUND_GNOME_ROCK
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 0);
|
|
||||||
SetSubRace(oPC, "Rock Gnome");
|
|
||||||
} break;
|
|
||||||
case 1455: { // BACKGROUND_HALFLING_GHOSTWISE
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 0);
|
|
||||||
SetSubRace(oPC, "Ghostwise Halfling");
|
|
||||||
} break;
|
|
||||||
case 1456: { // BACKGROUND_HALFLING_LIGHTFOOT
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 0);
|
|
||||||
SetSubRace(oPC, "Lightfoot Halfling");
|
|
||||||
} break;
|
|
||||||
case 1457: { // BACKGROUND_HALFLING_STRONGHEART
|
|
||||||
SetLocalInt(oItem, "PC_ECL", 0);
|
|
||||||
SetSubRace(oPC, "Strongheart Halfling");
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 1: Class Adjustments
|
|
||||||
if (nClass > 0) NWNX_Creature_AddFeatByLevel(oPC, nClass, 1);
|
|
||||||
|
|
||||||
// Step 2: Background Adjustments
|
|
||||||
if (nBackground > 0) NWNX_Creature_AddFeatByLevel(oPC, nBackground, 1);
|
|
||||||
switch (nBackground)
|
|
||||||
{
|
|
||||||
case BACKGROUND_CALISHITE_TRAINED:
|
|
||||||
SetLocalInt(oItem, "23", 1); // Language: Alzhedo
|
|
||||||
break;
|
|
||||||
case BACKGROUND_CIRCLE_BORN:
|
|
||||||
SetLocalInt(oItem, "8", 1); // Language: Animals
|
|
||||||
break;
|
|
||||||
case BACKGROUND_OCCULTIST: {
|
|
||||||
NWNX_Creature_AddFeatByLevel(oPC, PROFICIENCY_ASTROLOGY, 1);
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_LORE, iLore +2);
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_SPELLCRAFT, iSpellCraft +2);
|
|
||||||
} break;
|
|
||||||
case BACKGROUND_TALFIRIAN:
|
|
||||||
SetLocalInt(oItem, "38", 1); // Language: Talfirian
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 4: Deity Adjustments
|
|
||||||
if (nDeity > 0) NWNX_Creature_AddFeat(oPC, nDeity);
|
|
||||||
|
|
||||||
// Step 5: Languages
|
|
||||||
string sArr = GetLocalString(oItem, "ARR_LANGUAGES");
|
|
||||||
int i; for (i = 0; i < ArrayLength(sArr); i++)
|
|
||||||
{
|
|
||||||
string lang = ArrayParse(sArr, i);
|
|
||||||
SetLocalInt(oItem, lang, 1);
|
|
||||||
}
|
|
||||||
DeleteLocalString(oItem, "ARR_LANGUAGES");
|
|
||||||
|
|
||||||
// Step 6: Proficiencies
|
|
||||||
sArr = GetLocalString(oItem, "ARR_PROF");
|
|
||||||
for (i = 0; i < ArrayLength(sArr); i++)
|
|
||||||
{
|
|
||||||
int nFeat = StringToInt(ArrayParse(sArr, i));
|
|
||||||
if (nFeat > 0) NWNX_Creature_AddFeatByLevel(oPC, nFeat, 1);
|
|
||||||
if (nFeat == PROFICIENCY_ASTROLOGY)
|
|
||||||
{
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_LORE, iLore +2);
|
|
||||||
NWNX_Creature_SetSkillRank(oPC, SKILL_SPELLCRAFT, iSpellCraft +2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DeleteLocalString(oItem, "ARR_PROF");
|
|
||||||
|
|
||||||
// Step 7: Age Settings
|
|
||||||
switch (nAge)
|
|
||||||
{
|
|
||||||
case 1: // Middle-Aged
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_STRENGTH, iSTR-1);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON-1);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX-1);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT+1);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA+1);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS+1);
|
|
||||||
break;
|
|
||||||
case 2: // Old-Age
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_STRENGTH, iSTR-2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON-2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX-2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT+2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA+2);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS+2);
|
|
||||||
break;
|
|
||||||
case 3: // Venerable
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_STRENGTH, iSTR-3);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON-3);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX-3);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT+3);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA+3);
|
|
||||||
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS+3);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 8: One-Armed?
|
|
||||||
if (bDisfigured)
|
|
||||||
{
|
|
||||||
NWNX_Creature_AddFeatByLevel(oPC, 2000, 1);//One-Armed
|
|
||||||
//Set Arm to be nonexistent. I set the non-models to be all model number 200.
|
|
||||||
|
|
||||||
SetCreatureBodyPart(CREATURE_PART_LEFT_BICEP, 200, oPC);
|
|
||||||
SetCreatureBodyPart(CREATURE_PART_LEFT_FOREARM, 200, oPC);
|
|
||||||
SetCreatureBodyPart(CREATURE_PART_LEFT_HAND, 200, oPC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
647
src/nss/bg_apply_cv.nss
Normal file
647
src/nss/bg_apply_cv.nss
Normal file
@@ -0,0 +1,647 @@
|
|||||||
|
// LordValinar's Scripts - Background Application (12/18/2023)
|
||||||
|
// =============================================================================
|
||||||
|
/*
|
||||||
|
The final process, to take all of the saved settings from character
|
||||||
|
creation and apply them here. (This was to prevent exploits)
|
||||||
|
*/
|
||||||
|
// =============================================================================
|
||||||
|
#include "nwnx_creature"
|
||||||
|
#include "te_afflic_func"
|
||||||
|
#include "lv_inc"
|
||||||
|
#include "inc_persist_loca"
|
||||||
|
#include "te_lang"
|
||||||
|
|
||||||
|
// Ensure the PC Data Object exists; create if missing
|
||||||
|
object EnsurePlayerDataObject(object oPC)
|
||||||
|
{
|
||||||
|
object oItem = GetItemPossessedBy(oPC, "PC_Data_Object");
|
||||||
|
if (!GetIsObjectValid(oItem))
|
||||||
|
{
|
||||||
|
oItem = CreateItemOnObject("pc_data_object", oPC);
|
||||||
|
SendMessageToPC(oPC, "Language data object recreated");
|
||||||
|
WriteTimestampedLogEntry("Language data object recreated");
|
||||||
|
}
|
||||||
|
return oItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyProficiencies(object oPC)
|
||||||
|
{
|
||||||
|
object oItem = EnsurePlayerDataObject(oPC);
|
||||||
|
if (!GetIsObjectValid(oItem)) {
|
||||||
|
SendMessageToPC(oPC, "DEBUG: Invalid player data object");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iLore = GetSkillRank(SKILL_LORE, oPC, TRUE);
|
||||||
|
int iSpellCraft = GetSkillRank(SKILL_SPELLCRAFT, oPC, TRUE);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
string sSlot;
|
||||||
|
int nFound = 0;
|
||||||
|
|
||||||
|
while (i < 99)
|
||||||
|
{
|
||||||
|
sSlot = "PROFICIENCY_" + (i < 10 ? "0" : "") + IntToString(i);
|
||||||
|
|
||||||
|
int nProficiencyFeat = GetPersistantLocalInt(oPC, sSlot);
|
||||||
|
if (nProficiencyFeat == 0)
|
||||||
|
nProficiencyFeat = GetLocalInt(oItem, sSlot);
|
||||||
|
|
||||||
|
if (nProficiencyFeat > 0)
|
||||||
|
{
|
||||||
|
SendMessageToPC(oPC, "DEBUG: Applying feat " + IntToString(nProficiencyFeat) + " from slot " + sSlot);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, nProficiencyFeat, 1);
|
||||||
|
nFound++;
|
||||||
|
|
||||||
|
if (nProficiencyFeat == PROFICIENCY_ASTROLOGY)
|
||||||
|
{
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_LORE, iLore +2);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_SPELLCRAFT, iSpellCraft +2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageToPC(oPC, "DEBUG: Applied " + IntToString(nFound) + " proficiencies");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* void ApplyProficiencies(object oPC)
|
||||||
|
{
|
||||||
|
object oItem = EnsurePlayerDataObject(oPC);
|
||||||
|
if (!GetIsObjectValid(oItem)) return;
|
||||||
|
|
||||||
|
int iLore = GetSkillRank(SKILL_LORE, oPC, TRUE);
|
||||||
|
int iSpellCraft = GetSkillRank(SKILL_SPELLCRAFT, oPC, TRUE);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
string sSlot;
|
||||||
|
|
||||||
|
// Check all PROFICIENCY_* slots
|
||||||
|
while (i < 99)
|
||||||
|
{
|
||||||
|
sSlot = "PROFICIENCY_" + (i < 10 ? "0" : "") + IntToString(i);
|
||||||
|
|
||||||
|
// Check both persistent and item local variables
|
||||||
|
int nProficiencyFeat = GetPersistantLocalInt(oPC, sSlot);
|
||||||
|
if (nProficiencyFeat == 0)
|
||||||
|
nProficiencyFeat = GetLocalInt(oItem, sSlot);
|
||||||
|
|
||||||
|
// Apply the feat if found
|
||||||
|
if (nProficiencyFeat > 0)
|
||||||
|
{
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, nProficiencyFeat, 1);
|
||||||
|
|
||||||
|
if (nProficiencyFeat == PROFICIENCY_ASTROLOGY)
|
||||||
|
{
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_LORE, iLore +2);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_SPELLCRAFT, iSpellCraft +2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
void ApplyBonusLanguages(object oPC)
|
||||||
|
{
|
||||||
|
object oItem = GetItemPossessedBy(oPC, "PC_Data_Object");
|
||||||
|
if (!GetIsObjectValid(oItem)) return;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
string sSlot;
|
||||||
|
|
||||||
|
// Check all LANGUAGE_* slots
|
||||||
|
while (i < 99)
|
||||||
|
{
|
||||||
|
sSlot = "LANGUAGE_" + (i < 10 ? "0" : "") + IntToString(i);
|
||||||
|
|
||||||
|
// Check both persistent and item local variables
|
||||||
|
int nLanguageFeat = GetPersistantLocalInt(oPC, sSlot);
|
||||||
|
if (nLanguageFeat == 0)
|
||||||
|
nLanguageFeat = GetLocalInt(oItem, sSlot);
|
||||||
|
|
||||||
|
// Apply the feat if found
|
||||||
|
if (nLanguageFeat > 0)
|
||||||
|
{
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, nLanguageFeat, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(nLanguageFeat)), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = OBJECT_SELF; // from ExecuteScript()
|
||||||
|
object oItem = GetItemPossessedBy(oPC, "PC_Data_Object");
|
||||||
|
int nSubrace = GetLocalInt(oItem, "CC0"); /**/ DeleteLocalInt(oItem, "CC0");
|
||||||
|
int nClass = GetLocalInt(oItem, "CC1"); /**/ DeleteLocalInt(oItem, "CC1");
|
||||||
|
int nBackground = GetLocalInt(oItem, "CC2"); /**/ DeleteLocalInt(oItem, "CC2");
|
||||||
|
int nDeity = GetLocalInt(oItem, "CC3"); /**/ DeleteLocalInt(oItem, "CC3");
|
||||||
|
int nAge = GetLocalInt(oItem, "CC6"); /**/ DeleteLocalInt(oItem, "CC6");
|
||||||
|
int bDisfigured = GetLocalInt(oItem, "CC7"); /**/ DeleteLocalInt(oItem, "CC7");
|
||||||
|
// Stats
|
||||||
|
int iCL = GetHitDice(oPC);
|
||||||
|
int iSTR = GetAbilityScore(oPC, ABILITY_STRENGTH, TRUE);
|
||||||
|
int iDEX = GetAbilityScore(oPC, ABILITY_DEXTERITY, TRUE);
|
||||||
|
int iCON = GetAbilityScore(oPC, ABILITY_CONSTITUTION, TRUE);
|
||||||
|
int iINT = GetAbilityScore(oPC, ABILITY_INTELLIGENCE, TRUE);
|
||||||
|
int iWIS = GetAbilityScore(oPC, ABILITY_WISDOM, TRUE);
|
||||||
|
int iCHA = GetAbilityScore(oPC, ABILITY_CHARISMA, TRUE);
|
||||||
|
// Skills
|
||||||
|
int iHide = GetSkillRank(SKILL_HIDE, oPC, TRUE);
|
||||||
|
int iBluff = GetSkillRank(SKILL_BLUFF, oPC, TRUE);
|
||||||
|
int iSpot = GetSkillRank(SKILL_SPOT, oPC, TRUE);
|
||||||
|
int iListen = GetSkillRank(SKILL_LISTEN, oPC, TRUE);
|
||||||
|
int iLore = GetSkillRank(SKILL_LORE, oPC, TRUE);
|
||||||
|
int iMoveSil = GetSkillRank(SKILL_MOVE_SILENTLY, oPC, TRUE);
|
||||||
|
int iSpellCraft = GetSkillRank(SKILL_SPELLCRAFT, oPC, TRUE);
|
||||||
|
// Effects
|
||||||
|
effect eSpellResist = EffectSpellResistanceIncrease(11+iCL);
|
||||||
|
|
||||||
|
|
||||||
|
// Step 0: Subrace/Ethnicity (some of this might be redundant now)
|
||||||
|
if (nSubrace > 0) NWNX_Creature_AddFeatByLevel(oPC, nSubrace, 1);
|
||||||
|
switch (nSubrace)
|
||||||
|
{
|
||||||
|
case ETHNICITY_TETHYRIAN: case ETHNICITY_CALISHITE:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "23", 1); // Language: Alzhedo
|
||||||
|
SetPersistantLocalInt(oPC, "23", 1);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_ALZHEDO, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_ALZHEDO)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_CHONDATHAN:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "53", 1); // Language: Chondathan
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_CHONDATHAN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_CHONDATHAN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_DAMARAN:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "56", 1); // Language: Damaran
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_DAMARAN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_DAMARAN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_FFOLK:
|
||||||
|
{ // Talfiric
|
||||||
|
//SetLocalInt(oItem, "38", 1); // Language: Talfiric
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_TALFIRIC, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_DAMARAN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_ILLUSKAN:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "22", 1); // Language: Illuskan
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_ILLUSKAN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_ILLUSKAN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_IMASKARI:
|
||||||
|
{ // Imaskari
|
||||||
|
//SetLocalInt(oItem, "24", 1); // Language: Imaskari
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_IMASKARI, 1);
|
||||||
|
//SetLocalInt(oItem, "46", 1); // Language: Undercommon
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_UNDERCOMMON, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_IMASKARI)), 1);
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_UNDERCOMMON)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_MULAN:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "27", 1); // Language: Mulanese
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_MULANESE, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_MULANESE)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_RASHEMI:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "30", 1); // Langauge: Rashemi
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_RASHEMI, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_RASHEMI)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_SHAARAN:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "34", 1); // Language: Shaaran
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_SHAARAN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_SHAARAN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_SHOU:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "35", 1); // Language: Shou (no feat for this one)
|
||||||
|
//NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_SHAARAN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
//SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_SHAARAN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_CHULTAN:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "31", 1); // Langauge: Chultan
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_CHULTAN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_CHULTAN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_MAZTILAN:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "32", 1); // Langauge: Maztilan
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_MAZTILAN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_MAZTILAN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_TIEFLING:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "iPCSubrace", 11);
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 1);
|
||||||
|
SetSubRace(oPC, "Tiefling");
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_DARKVISION,1);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT +2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX +2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA -2);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_BLUFF, iBluff +2);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_HIDE, iHide+2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_NAT_LYCAN:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 2);
|
||||||
|
if (GetRacialType(oPC) == RACIAL_TYPE_ELF) {
|
||||||
|
SetSubRace(oPC, "Lythari");
|
||||||
|
} else {
|
||||||
|
SetSubRace(oPC, "Natural Lycanthrope");
|
||||||
|
}
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS + 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_AASIMAR:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "iPCSubrace", 10);
|
||||||
|
SetLocalInt(oItem, "PC_ECL",1);
|
||||||
|
SetSubRace(oPC, "Aasimar");
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC,228,1); // Darkvision
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS +2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA +2);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_SPOT, iSpot +2);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_LISTEN, iListen+2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_GOLD_DWARF:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 0);
|
||||||
|
SetSubRace(oPC, "Gold Dwarf");
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA +4);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX -2);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_DWARVEN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_DWARVEN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_GREY_DWARF:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 2);
|
||||||
|
SetSubRace(oPC, "Grey Dwarf");
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_MOVE_SILENTLY, iMoveSil +4);
|
||||||
|
AddSubraceEffect(oPC, EffectImmunity(IMMUNITY_TYPE_POISON));
|
||||||
|
AddSubraceEffect(oPC, EffectImmunity(IMMUNITY_TYPE_PARALYSIS));
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_DUERGAR, 1);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_UNDERCOMMON, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_DUERGAR)), 1);
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_UNDERCOMMON)), 1);
|
||||||
|
|
||||||
|
//SetLocalInt(oItem, "64", 1); // Language: Duergar
|
||||||
|
//SetLocalInt(oItem, "46", 1); // Language: Undercommon
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_SHIELD_DWARF:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 0);
|
||||||
|
SetSubRace(oPC, "Shield Dwarf");
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_DWARVEN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_DWARVEN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_COPPER_ELF:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 0);
|
||||||
|
SetSubRace(oPC, "Copper Elf");
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_STRENGTH, iSTR +2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT -2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA -2);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_ELVEN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_ELVEN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_DARK_ELF:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 2);
|
||||||
|
SetSubRace(oPC, "Dark Elf");
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, 228, 1); // Darkvision
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT +2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA +2);
|
||||||
|
AddSubraceEffect(oPC, eSpellResist);
|
||||||
|
//SetLocalInt(oItem, "81", 1); // Language: Drow
|
||||||
|
//SetLocalInt(oItem, "46", 1); // Language: Undercommon
|
||||||
|
//SetLocalInt(oItem, "13", 1); // Language: Drow Sign
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_DROW, 1);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_UNDERCOMMON, 1);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_DROW_HAND_CANT, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_DROW)), 1);
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_UNDERCOMMON)), 1);
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_DROW_HAND_CANT)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_FEYRI:
|
||||||
|
{ // BACKGROUND_ELF_FEYRI
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 3);
|
||||||
|
SetSubRace(oPC, "Fey'ri");
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_DARKVISION, 1); // Darkvision
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX +2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON -2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT +2);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_BLUFF, iBluff +2);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_HIDE, iHide +2);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_ELVEN, 1);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_ABYSSAL, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_ELVEN)), 1);
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_ABYSSAL)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_GREEN_ELF:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 0);
|
||||||
|
SetSubRace(oPC, "Green Elf");
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON +4);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT -2);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_ELVEN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_ELVEN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_GOLD_ELF:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 0);
|
||||||
|
SetSubRace(oPC, "Gold Elf");
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX -2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT +2);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_ELVEN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_ELVEN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_SILVER_ELF:
|
||||||
|
{
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 0);
|
||||||
|
SetSubRace(oPC, "Silver Elf");
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_ELVEN, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_ELVEN)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_DEEP_GNOME:
|
||||||
|
{ // BACKGROUND_GNOME_DEEP
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 2);
|
||||||
|
SetSubRace(oPC, "Deep Gnome");
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC,nSubrace,1);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_DARKVISION, 1); // Darkvision
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_STONECUNNING, 1); // Stonecunning
|
||||||
|
AddSubraceEffect(oPC, eSpellResist);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX +2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON -4);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS +2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA -4);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_HIDE, iHide +2);
|
||||||
|
//SetLocalInt(oItem,"46",1); // Language: Undercommon
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_UNDERCOMMON, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_UNDERCOMMON)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_FOREST_GNOME:
|
||||||
|
{ // BACKGROUND_GNOME_FOREST
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 1);
|
||||||
|
SetSubRace(oPC, "Forest Gnome");
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_HIDE, iHide + 4);
|
||||||
|
//SetLocalInt(oItem, "8", 1); // Language: Animals
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_GNOMISH, 1);
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_ANIMAL, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_GNOMISH)), 1);
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_ANIMAL)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_ROCK_GNOME:
|
||||||
|
{ // BACKGROUND_GNOME_ROCK
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 0);
|
||||||
|
SetSubRace(oPC, "Rock Gnome");
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_GNOMISH, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_GNOMISH)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_GHOSTWISE:
|
||||||
|
{ // BACKGROUND_HALFLING_GHOSTWISE
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 0);
|
||||||
|
SetSubRace(oPC, "Ghostwise Halfling");
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_HALFLING, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_HALFLING)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_LIGHTFOOT:
|
||||||
|
{ // BACKGROUND_HALFLING_LIGHTFOOT
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 0);
|
||||||
|
SetSubRace(oPC, "Lightfoot Halfling");
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_HALFLING, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_HALFLING)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ETHNICITY_STRONGHEART:
|
||||||
|
{ // BACKGROUND_HALFLING_STRONGHEART
|
||||||
|
SetLocalInt(oItem, "PC_ECL", 0);
|
||||||
|
SetSubRace(oPC, "Strongheart Halfling");
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_HALFLING, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_HALFLING)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1: Class Adjustments
|
||||||
|
if (nClass > 0) NWNX_Creature_AddFeatByLevel(oPC, nClass, 1);
|
||||||
|
|
||||||
|
// Step 2: Background Adjustments
|
||||||
|
if (nBackground > 0) NWNX_Creature_AddFeatByLevel(oPC, nBackground, 1);
|
||||||
|
switch (nBackground)
|
||||||
|
{
|
||||||
|
case BACKGROUND_CALISHITE_TRAINED:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "23", 1); // Language: Alzhedo
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_ALZHEDO, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_ALZHEDO)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_CIRCLE_BORN:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "8", 1); // Language: Animals
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_ANIMAL, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_ANIMAL)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_OCCULTIST:
|
||||||
|
{
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, PROFICIENCY_ASTROLOGY, 1);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_LORE, iLore +2);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_SPELLCRAFT, iSpellCraft +2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BACKGROUND_TALFIRIAN:
|
||||||
|
{
|
||||||
|
//SetLocalInt(oItem, "38", 1); // Language: Talfirian
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, FEAT_LANGUAGE_TALFIRIC, 1);
|
||||||
|
|
||||||
|
//:: For legacy DMFI
|
||||||
|
SetLocalInt(oItem, IntToString(LangFeatToLangID(FEAT_LANGUAGE_TALFIRIC)), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4: Deity Adjustments
|
||||||
|
if (nDeity > 0) NWNX_Creature_AddFeat(oPC, nDeity);
|
||||||
|
|
||||||
|
// Step 5: Languages
|
||||||
|
ApplyBonusLanguages(oPC);
|
||||||
|
|
||||||
|
/* string sArr = GetLocalString(oItem, "ARR_LANGUAGES");
|
||||||
|
int i; for (i = 0; i < ArrayLength(sArr); i++)
|
||||||
|
{
|
||||||
|
string lang = ArrayParse(sArr, i);
|
||||||
|
SetLocalInt(oItem, lang, 1);
|
||||||
|
}
|
||||||
|
DeleteLocalString(oItem, "ARR_LANGUAGES"); */
|
||||||
|
|
||||||
|
// Step 6: Proficiencies
|
||||||
|
ApplyProficiencies(oPC);
|
||||||
|
|
||||||
|
/* sArr = GetLocalString(oItem, "ARR_PROF");
|
||||||
|
for (i = 0; i < ArrayLength(sArr); i++)
|
||||||
|
{
|
||||||
|
int nFeat = StringToInt(ArrayParse(sArr, i));
|
||||||
|
if (nFeat > 0) NWNX_Creature_AddFeatByLevel(oPC, nFeat, 1);
|
||||||
|
if (nFeat == PROFICIENCY_ASTROLOGY)
|
||||||
|
{
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_LORE, iLore +2);
|
||||||
|
NWNX_Creature_SetSkillRank(oPC, SKILL_SPELLCRAFT, iSpellCraft +2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DeleteLocalString(oItem, "ARR_PROF"); */
|
||||||
|
|
||||||
|
// Step 7: Age Settings
|
||||||
|
switch (nAge)
|
||||||
|
{
|
||||||
|
case AGE_CATEGORY_YOUTHFUL:
|
||||||
|
{
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, AGE_CATEGORY_YOUTHFUL, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AGE_CATEGORY_MIDDLE:
|
||||||
|
{
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, AGE_CATEGORY_MIDDLE, 1);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_STRENGTH, iSTR-1);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON-1);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX-1);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT+1);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA+1);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS+1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AGE_CATEGORY_OLD:
|
||||||
|
{
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, AGE_CATEGORY_OLD, 1);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_STRENGTH, iSTR-2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON-2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX-2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT+2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA+2);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS+2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AGE_CATEGORY_VENERABLE:
|
||||||
|
{
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, AGE_CATEGORY_VENERABLE, 1);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_STRENGTH, iSTR-3);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CONSTITUTION, iCON-3);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_DEXTERITY, iDEX-3);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_INTELLIGENCE, iINT+3);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_CHARISMA, iCHA+3);
|
||||||
|
NWNX_Creature_SetRawAbilityScore(oPC, ABILITY_WISDOM, iWIS+3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 8: One-Armed?
|
||||||
|
if (bDisfigured)
|
||||||
|
{
|
||||||
|
NWNX_Creature_AddFeatByLevel(oPC, DISABILITY_ONE_ARMED, 1);//One-Armed
|
||||||
|
//Set Arm to be nonexistent. I set the non-models to be all model number 200.
|
||||||
|
|
||||||
|
SetCreatureBodyPart(CREATURE_PART_LEFT_BICEP, 200, oPC);
|
||||||
|
SetCreatureBodyPart(CREATURE_PART_LEFT_FOREARM, 200, oPC);
|
||||||
|
SetCreatureBodyPart(CREATURE_PART_LEFT_HAND, 200, oPC);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,10 +20,11 @@ object EnsurePlayerDataObject(object oPC)
|
|||||||
if (!GetIsObjectValid(oItem))
|
if (!GetIsObjectValid(oItem))
|
||||||
{
|
{
|
||||||
oItem = CreateItemOnObject("pc_data_object", oPC);
|
oItem = CreateItemOnObject("pc_data_object", oPC);
|
||||||
|
SendMessageToPC(oPC, "Language data object recreated");
|
||||||
|
WriteTimestampedLogEntry("Language data object recreated");
|
||||||
}
|
}
|
||||||
return oItem;
|
return oItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _CanBeAffluent(object oPC = OBJECT_SELF)
|
int _CanBeAffluent(object oPC = OBJECT_SELF)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ object EnsurePlayerDataObject(object oPC)
|
|||||||
if (!GetIsObjectValid(oItem))
|
if (!GetIsObjectValid(oItem))
|
||||||
{
|
{
|
||||||
oItem = CreateItemOnObject("pc_data_object", oPC);
|
oItem = CreateItemOnObject("pc_data_object", oPC);
|
||||||
|
SendMessageToPC(oPC, "Language data object recreated");
|
||||||
|
WriteTimestampedLogEntry("Language data object recreated");
|
||||||
}
|
}
|
||||||
return oItem;
|
return oItem;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,16 +5,88 @@
|
|||||||
#include "te_afflic_func"
|
#include "te_afflic_func"
|
||||||
|
|
||||||
// Ensure the PC Data Object exists; create if missing
|
// Ensure the PC Data Object exists; create if missing
|
||||||
object EnsurePlayerDataObject(object oPC = OBJECT_SELF)
|
object EnsurePlayerDataObject(object oPC)
|
||||||
{
|
{
|
||||||
object oItem = GetItemPossessedBy(oPC, "PC_Data_Object");
|
object oItem = GetItemPossessedBy(oPC, "PC_Data_Object");
|
||||||
if (!GetIsObjectValid(oItem))
|
if (!GetIsObjectValid(oItem))
|
||||||
{
|
{
|
||||||
oItem = CreateItemOnObject("pc_data_object", oPC);
|
oItem = CreateItemOnObject("pc_data_object", oPC);
|
||||||
|
SendMessageToPC(oPC, "Language data object recreated");
|
||||||
|
WriteTimestampedLogEntry("Language data object recreated");
|
||||||
}
|
}
|
||||||
return oItem;
|
return oItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if PC already knows a proficiency
|
||||||
|
int KnowsProficiency(object oPC, int nProficiencyFeat)
|
||||||
|
{
|
||||||
|
object oItem = EnsurePlayerDataObject(oPC);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
string sSlot;
|
||||||
|
|
||||||
|
while (i < 10)
|
||||||
|
{
|
||||||
|
sSlot = "PROFICIENCY_" + (i < 10 ? "0" : "") + IntToString(i);
|
||||||
|
|
||||||
|
// Check BOTH storage locations where GrantnProficiency saves data
|
||||||
|
if (GetPersistantLocalInt(oPC, sSlot) == nProficiencyFeat)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (GetIsObjectValid(oItem))
|
||||||
|
{
|
||||||
|
if (GetLocalInt(oItem, sSlot) == nProficiencyFeat)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to get the next available proficiency slot
|
||||||
|
int GetNextProficiencySlot(object oPC)
|
||||||
|
{
|
||||||
|
object oItem = EnsurePlayerDataObject(oPC);
|
||||||
|
if (!GetIsObjectValid(oItem)) return 0;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
string sSlot;
|
||||||
|
|
||||||
|
// Find the first empty slot
|
||||||
|
while (i < 99)
|
||||||
|
{
|
||||||
|
sSlot = "PROFICIENCY_" + (i < 10 ? "0" : "") + IntToString(i);
|
||||||
|
if (!GetLocalInt(oItem, sSlot))
|
||||||
|
return i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return -1; // No slots available
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grant a proficiency to PC
|
||||||
|
void GrantProficiency(object oPC, int nProficiencyFeat)
|
||||||
|
{
|
||||||
|
object oItem = EnsurePlayerDataObject(oPC);
|
||||||
|
if (!GetIsObjectValid(oItem)) return;
|
||||||
|
|
||||||
|
if (KnowsProficiency(oPC, nProficiencyFeat))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int nSlot = GetNextProficiencySlot(oPC);
|
||||||
|
if (nSlot >= 0)
|
||||||
|
{
|
||||||
|
string sSlot = "PROFICIENCY_" + (nSlot < 10 ? "0" : "") + IntToString(nSlot);
|
||||||
|
SetLocalInt(oItem, sSlot, nProficiencyFeat);
|
||||||
|
SetPersistantLocalInt(oPC, sSlot, nProficiencyFeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark as selected for the conversation list
|
||||||
|
SetLocalInt(oPC, IntToString(nProficiencyFeat), TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// prof_chk_alchemy
|
// prof_chk_alchemy
|
||||||
// Requirements: Any Standing
|
// Requirements: Any Standing
|
||||||
@@ -193,6 +265,9 @@ const int CHOICE_CONFIRM_NO = 101;
|
|||||||
void main() {
|
void main() {
|
||||||
object oPC = GetPCSpeaker();
|
object oPC = GetPCSpeaker();
|
||||||
SendMessageToPC(oPC, "DEBUG: bg_prof_cv main() entered");
|
SendMessageToPC(oPC, "DEBUG: bg_prof_cv main() entered");
|
||||||
|
|
||||||
|
object oItem = EnsurePlayerDataObject(oPC);
|
||||||
|
|
||||||
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
|
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
|
||||||
int nStage = GetStage(oPC);
|
int nStage = GetStage(oPC);
|
||||||
|
|
||||||
@@ -327,11 +402,15 @@ void main() {
|
|||||||
// Handle PC responses
|
// Handle PC responses
|
||||||
int nChoice = GetChoice(oPC);
|
int nChoice = GetChoice(oPC);
|
||||||
|
|
||||||
if (nStage == STAGE_LIST) {
|
if (nStage == STAGE_LIST)
|
||||||
if (nChoice == 21) {
|
{
|
||||||
|
if (nChoice == 21)
|
||||||
|
{
|
||||||
// Done - finalize and proceed to next step
|
// Done - finalize and proceed to next step
|
||||||
ExecuteScript("prof_give_nomore", oPC);
|
ExecuteScript("prof_give_nomore", oPC);
|
||||||
} else if (nChoice >= 1 && nChoice <= 20) {
|
}
|
||||||
|
else if (nChoice >= 1 && nChoice <= 20)
|
||||||
|
{
|
||||||
// Store proficiency info for confirmation
|
// Store proficiency info for confirmation
|
||||||
string sProfName;
|
string sProfName;
|
||||||
string sProfVar;
|
string sProfVar;
|
||||||
@@ -339,26 +418,166 @@ void main() {
|
|||||||
|
|
||||||
switch (nChoice)
|
switch (nChoice)
|
||||||
{
|
{
|
||||||
case 1: sProfName = "Alchemy"; sProfVar = "ALCHEMY"; sGrant = "prof_give_alchem"; break;
|
case 1:
|
||||||
case 2: sProfName = "Anatomy"; sProfVar = "ANATOMY"; sGrant = "prof_give_anatomy"; break;
|
{
|
||||||
case 3: sProfName = "Armorsmithing"; sProfVar = "ARMOR"; sGrant = "prof_give_armor"; break;
|
sProfName = "Alchemy";
|
||||||
case 4: sProfName = "Astronomy"; sProfVar = "ASTRO"; sGrant = "prof_give_astro"; break;
|
sProfVar = "ALCHEMY";
|
||||||
case 5: sProfName = "Carpentry"; sProfVar = "CARP"; sGrant = "prof_give_carp"; break;
|
//sGrant = "prof_give_alchem";
|
||||||
case 6: sProfName = "Decipher Script"; sProfVar = "DECIPH"; sGrant = "prof_give_deciph"; break;
|
GrantProficiency(oPC, PROFICIENCY_ALCHEMY);
|
||||||
case 7: sProfName = "Disguise"; sProfVar = "DISGUISE"; sGrant = "prof_give_disgui"; break;
|
break;
|
||||||
case 8: sProfName = "Firemaking"; sProfVar = "FIRE"; sGrant = "prof_give_fire"; break;
|
}
|
||||||
case 9: sProfName = "Gunsmithing"; sProfVar = "GUNS"; sGrant = "prof_give_guns"; break;
|
case 2:
|
||||||
case 10: sProfName = "Herbalism"; sProfVar = "HERB"; sGrant = "prof_give_herb"; break;
|
{
|
||||||
case 11: sProfName = "History"; sProfVar = "HIST"; sGrant = "prof_give_hist"; break;
|
sProfName = "Anatomy";
|
||||||
case 12: sProfName = "Hunting"; sProfVar = "HUNT"; sGrant = "prof_give_hunt"; break;
|
sProfVar = "ANATOMY";
|
||||||
case 13: sProfName = "Masonry"; sProfVar = "MASON"; sGrant = "prof_give_mason"; break;
|
//sGrant = "prof_give_anatomy";
|
||||||
case 14: sProfName = "Mining"; sProfVar = "MINING"; sGrant = "prof_give_mine"; break;
|
GrantProficiency(oPC, PROFICIENCY_ANATOMY);
|
||||||
case 15: sProfName = "Observation"; sProfVar = "OBS"; sGrant = "prof_give_obs"; break;
|
break;
|
||||||
case 16: sProfName = "Siege Engineering"; sProfVar = "SIEGE"; sGrant = "prof_give_siege"; break;
|
}
|
||||||
case 17: sProfName = "Smelting"; sProfVar = "SMELT"; sGrant = "prof_give_smelt"; break;
|
case 3:
|
||||||
case 18: sProfName = "Tailoring"; sProfVar = "TAILOR"; sGrant = "prof_give_tailor"; break;
|
{
|
||||||
case 19: sProfName = "Tracking"; sProfVar = "TRACK"; sGrant = "prof_give_track"; break;
|
sProfName = "Armorsmithing";
|
||||||
case 20: sProfName = "Wood Gathering"; sProfVar = "WOOD"; sGrant = "prof_give_wood"; break;
|
sProfVar = "ARMOR";
|
||||||
|
//sGrant = "prof_give_armor";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_ARMORING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
sProfName = "Astrology";
|
||||||
|
sProfVar = "ASTRO";
|
||||||
|
//sGrant = "prof_give_astro";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_ASTROLOGY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
sProfName = "Carpentry";
|
||||||
|
sProfVar = "CARP";
|
||||||
|
//sGrant = "prof_give_carp";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_CARPENTRY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6:
|
||||||
|
{
|
||||||
|
sProfName = "Decipher Script";
|
||||||
|
sProfVar = "DECIPH";
|
||||||
|
//sGrant = "prof_give_deciph";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_DECIPHER);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 7:
|
||||||
|
{
|
||||||
|
sProfName = "Disguise";
|
||||||
|
sProfVar = "DISGUISE";
|
||||||
|
//sGrant = "prof_give_disgui";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_DISGUISE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
sProfName = "Firemaking";
|
||||||
|
sProfVar = "FIRE";
|
||||||
|
//sGrant = "prof_give_fire";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_FIRE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 9:
|
||||||
|
{
|
||||||
|
sProfName = "Gunsmithing";
|
||||||
|
sProfVar = "GUNS";
|
||||||
|
//sGrant = "prof_give_guns";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_GUNSMITHING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 10:
|
||||||
|
{
|
||||||
|
sProfName = "Herbalism";
|
||||||
|
sProfVar = "HERB";
|
||||||
|
//sGrant = "prof_give_herb";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_HERBALISM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 11:
|
||||||
|
{
|
||||||
|
sProfName = "History";
|
||||||
|
sProfVar = "HIST";
|
||||||
|
//sGrant = "prof_give_hist";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_HISTORY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 12:
|
||||||
|
{
|
||||||
|
sProfName = "Hunting";
|
||||||
|
sProfVar = "HUNT";
|
||||||
|
//sGrant = "prof_give_hunt";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_HUNTING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 13:
|
||||||
|
{
|
||||||
|
sProfName = "Masonry";
|
||||||
|
sProfVar = "MASON";
|
||||||
|
//sGrant = "prof_give_mason";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_MASONRY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 14:
|
||||||
|
{
|
||||||
|
sProfName = "Mining";
|
||||||
|
sProfVar = "MINING";
|
||||||
|
//sGrant = "prof_give_mine";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_MINING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 15:
|
||||||
|
{
|
||||||
|
sProfName = "Observation";
|
||||||
|
sProfVar = "OBS";
|
||||||
|
//sGrant = "prof_give_obs";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_OBSERVATION);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
sProfName = "Siege Engineering";
|
||||||
|
sProfVar = "SIEGE";
|
||||||
|
//sGrant = "prof_give_siege";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_SIEGE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 17:
|
||||||
|
{
|
||||||
|
sProfName = "Smelting";
|
||||||
|
sProfVar = "SMELT";
|
||||||
|
//sGrant = "prof_give_smelt";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_SMELTING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 18:
|
||||||
|
{
|
||||||
|
sProfName = "Tailoring";
|
||||||
|
sProfVar = "TAILOR";
|
||||||
|
//sGrant = "prof_give_tailor";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_TAILORING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 19:
|
||||||
|
{
|
||||||
|
sProfName = "Tracking";
|
||||||
|
sProfVar = "TRACK";
|
||||||
|
//sGrant = "prof_give_track";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_TRACKING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 20:
|
||||||
|
{
|
||||||
|
sProfName = "Wood Gathering";
|
||||||
|
sProfVar = "WOOD";
|
||||||
|
//sGrant = "prof_give_wood";
|
||||||
|
GrantProficiency(oPC, PROFICIENCY_WOOD_GATHERING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLocalString(oPC, "TEMP_PROF_NAME", sProfName);
|
SetLocalString(oPC, "TEMP_PROF_NAME", sProfName);
|
||||||
@@ -370,8 +589,10 @@ void main() {
|
|||||||
SetStage(STAGE_CONFIRM, oPC);
|
SetStage(STAGE_CONFIRM, oPC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (nStage == STAGE_CONFIRM) {
|
else if (nStage == STAGE_CONFIRM)
|
||||||
if (nChoice == CHOICE_CONFIRM_YES) {
|
{
|
||||||
|
if (nChoice == CHOICE_CONFIRM_YES)
|
||||||
|
{
|
||||||
// Confirm selection - grant proficiency
|
// Confirm selection - grant proficiency
|
||||||
string sProfVar = GetLocalString(oPC, "TEMP_PROF_VAR");
|
string sProfVar = GetLocalString(oPC, "TEMP_PROF_VAR");
|
||||||
string sGrant = GetLocalString(oPC, "TEMP_PROF_GRANT");
|
string sGrant = GetLocalString(oPC, "TEMP_PROF_GRANT");
|
||||||
@@ -393,23 +614,36 @@ void main() {
|
|||||||
DeleteLocalString(oPC, "TEMP_PROF_DESC");
|
DeleteLocalString(oPC, "TEMP_PROF_DESC");
|
||||||
|
|
||||||
// Check if player has selected 3 proficiencies
|
// Check if player has selected 3 proficiencies
|
||||||
if (nCount >= 3) {
|
if (nCount >= 3)
|
||||||
|
{
|
||||||
// Auto-finish
|
// Auto-finish
|
||||||
ExecuteScript("prof_give_nomore", oPC);
|
SetLocalInt(oItem,"BG_Select",6);
|
||||||
|
ActionStartConversation(oPC,"bg_final",TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Return to list, force refresh
|
// Return to list, force refresh
|
||||||
MarkStageNotSetUp(STAGE_CONFIRM, oPC); // Add this line
|
|
||||||
MarkStageNotSetUp(STAGE_LIST, oPC);
|
|
||||||
SetStage(STAGE_LIST, oPC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (nChoice == CHOICE_CONFIRM_NO) {
|
|
||||||
// Go back to list
|
|
||||||
MarkStageNotSetUp(STAGE_CONFIRM, oPC);
|
MarkStageNotSetUp(STAGE_CONFIRM, oPC);
|
||||||
SetStage(STAGE_LIST, oPC);
|
MarkStageNotSetUp(STAGE_LIST, oPC);
|
||||||
|
nStage = STAGE_LIST; // Add this line
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (nChoice == CHOICE_CONFIRM_NO)
|
||||||
|
{
|
||||||
|
// Clean up temp vars before going back
|
||||||
|
DeleteLocalString(oPC, "TEMP_PROF_NAME");
|
||||||
|
DeleteLocalString(oPC, "TEMP_PROF_VAR");
|
||||||
|
DeleteLocalString(oPC, "TEMP_PROF_GRANT");
|
||||||
|
DeleteLocalString(oPC, "TEMP_PROF_DESC");
|
||||||
|
|
||||||
|
// Go back to list - update local nStage variable
|
||||||
|
MarkStageNotSetUp(STAGE_CONFIRM, oPC);
|
||||||
|
MarkStageNotSetUp(STAGE_LIST, oPC);
|
||||||
|
nStage = STAGE_LIST; // update local nStage
|
||||||
|
}
|
||||||
|
|
||||||
|
SetStage(nStage, oPC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ object EnsurePlayerDataObject(object oPC)
|
|||||||
if (!GetIsObjectValid(oItem))
|
if (!GetIsObjectValid(oItem))
|
||||||
{
|
{
|
||||||
oItem = CreateItemOnObject("pc_data_object", oPC);
|
oItem = CreateItemOnObject("pc_data_object", oPC);
|
||||||
|
SendMessageToPC(oPC, "Language data object recreated");
|
||||||
|
WriteTimestampedLogEntry("Language data object recreated");
|
||||||
}
|
}
|
||||||
return oItem;
|
return oItem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ object EnsurePlayerDataObject(object oPC)
|
|||||||
if (!GetIsObjectValid(oItem))
|
if (!GetIsObjectValid(oItem))
|
||||||
{
|
{
|
||||||
oItem = CreateItemOnObject("pc_data_object", oPC);
|
oItem = CreateItemOnObject("pc_data_object", oPC);
|
||||||
|
SendMessageToPC(oPC, "Language data object recreated");
|
||||||
|
WriteTimestampedLogEntry("Language data object recreated");
|
||||||
}
|
}
|
||||||
return oItem;
|
return oItem;
|
||||||
}
|
}
|
||||||
@@ -71,11 +73,11 @@ void main()
|
|||||||
|
|
||||||
AddChoice("Maztican", 7, oPC);
|
AddChoice("Maztican", 7, oPC);
|
||||||
SetLocalString(oPC, "sub_dyn_text_7",
|
SetLocalString(oPC, "sub_dyn_text_7",
|
||||||
"After the Helmite conquest in Maztica, many people of the differing tribes lumped together by the Easterners began to immigrate to the old world and see what wonders lied across the Trackless Sea. Truely a people displaced, Mazticans are unfamiliar with the customs of the Tethyrians or the Chondathans. Rumors of Helmite abuse and exploitation in Maztica are common, much more common than the sight of a simple Maztican.\n\nDoes this describe you?");
|
"After the Helmite conquest in Maztica, many people of the differing tribes lumped together by the Easterners began to immigrate to the old world and see what wonders lied across the Trackless Sea. Truely a people displaced, Mazticans are unfamiliar with the customs of the Tethyrians or the Chondathans. Rumors of Helmite abuse and exploitation in Maztica are common, much more common than the sight of a simple Maztican. Mazticans receive Maztilan as a bonus language automatically.\n\nDoes this describe you?");
|
||||||
|
|
||||||
AddChoice("Chultan", 8, oPC);
|
AddChoice("Chultan", 8, oPC);
|
||||||
SetLocalString(oPC, "sub_dyn_text_8",
|
SetLocalString(oPC, "sub_dyn_text_8",
|
||||||
"The jungles of Chult are a harsh and unforgiving land that forged together the many disparate tribes of the peninsula into one single culture more than a millennia ago. Most Chultans distrust power and wealth, believing that things that they cannot take with them are ultimately worthless. It is rare to see a Chultan separated from their clan. Chultans are tall and ebony-skinned.\n\nDoes this describe you?");
|
"The jungles of Chult are a harsh and unforgiving land that forged together the many disparate tribes of the peninsula into one single culture more than a millennia ago. Most Chultans distrust power and wealth, believing that things that they cannot take with them are ultimately worthless. It is rare to see a Chultan separated from their clan. Tall and ebony-skinned, Chultans receive Chultan as a bonus language automatically.\n\nDoes this describe you?");
|
||||||
|
|
||||||
AddChoice("Chondathan", 9, oPC);
|
AddChoice("Chondathan", 9, oPC);
|
||||||
SetLocalString(oPC, "sub_dyn_text_9",
|
SetLocalString(oPC, "sub_dyn_text_9",
|
||||||
|
|||||||
@@ -1,165 +0,0 @@
|
|||||||
//:://////////////////////////////////////////////
|
|
||||||
//:: Forsaker Ability Boost Conversation
|
|
||||||
//:: prc_forsake_abil
|
|
||||||
//:://////////////////////////////////////////////
|
|
||||||
/** @file
|
|
||||||
This allows you to choose ability to boost.
|
|
||||||
|
|
||||||
@author Stratovarius
|
|
||||||
@date Created - 27.12.2019
|
|
||||||
@edited by Stratovarius
|
|
||||||
@date 24.12.2024
|
|
||||||
*/
|
|
||||||
//:://////////////////////////////////////////////
|
|
||||||
//:://////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "inc_dynconv"
|
|
||||||
#include "prc_inc_function"
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////
|
|
||||||
/* Constant defintions */
|
|
||||||
//////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const int STAGE_SELECT_ABIL = 0;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////
|
|
||||||
/* Function defintions */
|
|
||||||
//////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
object oPC = GetPCSpeaker();
|
|
||||||
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
|
|
||||||
int nStage = GetStage(oPC);
|
|
||||||
int nClass = GetPersistantLocalInt(oPC, "ForsakerBoostCheck");
|
|
||||||
|
|
||||||
// Check which of the conversation scripts called the scripts
|
|
||||||
if(nValue == 0) // All of them set the DynConv_Var to non-zero value, so something is wrong -> abort
|
|
||||||
{
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: Aborting due to error.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(nValue == DYNCONV_SETUP_STAGE)
|
|
||||||
{
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: Running setup stage for stage " + IntToString(nStage));
|
|
||||||
// Check if this stage is marked as already set up
|
|
||||||
// This stops list duplication when scrolling
|
|
||||||
if(!GetIsStageSetUp(nStage, oPC))
|
|
||||||
{
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: Stage was not set up already. nStage: " + IntToString(nStage));
|
|
||||||
// Maneuver selection stage
|
|
||||||
if(nStage == STAGE_SELECT_ABIL)
|
|
||||||
{
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: Building maneuver selection");
|
|
||||||
SetHeader("Choose which ability to boost for Forsaker level " + IntToString(nClass) + ":");
|
|
||||||
AddChoice("Strength", ABILITY_STRENGTH, oPC);
|
|
||||||
AddChoice("Dexterity", ABILITY_DEXTERITY, oPC);
|
|
||||||
AddChoice("Constitution", ABILITY_CONSTITUTION, oPC);
|
|
||||||
AddChoice("Intelligence", ABILITY_INTELLIGENCE, oPC);
|
|
||||||
AddChoice("Wisdom", ABILITY_WISDOM, oPC);
|
|
||||||
AddChoice("Charisma", ABILITY_CHARISMA, oPC);
|
|
||||||
|
|
||||||
MarkStageSetUp(STAGE_SELECT_ABIL, oPC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do token setup
|
|
||||||
SetupTokens();
|
|
||||||
}
|
|
||||||
else if(nValue == DYNCONV_EXITED)
|
|
||||||
{
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: Running exit handler");
|
|
||||||
if(GetLocalInt(oPC, "PRC_Forsaker_Exit_Ran_VoP_Check")) return;
|
|
||||||
SetLocalInt(oPC, "PRC_Forsaker_Exit_Ran_VoP_Check", TRUE);
|
|
||||||
DelayCommand(3.0f, DeleteLocalInt(oPC, "PRC_Forsaker_Exit_Ran_VoP_Check"));
|
|
||||||
|
|
||||||
if (GetHasFeat(FEAT_VOWOFPOVERTY, oPC))
|
|
||||||
{
|
|
||||||
int nLevel = GetHitDice(oPC) - GetPersistantLocalInt(oPC, "VoPLevel1") + 1;
|
|
||||||
int nLevelCheck;
|
|
||||||
for (nLevelCheck = 1; nLevelCheck <= nLevel; nLevelCheck++)
|
|
||||||
{
|
|
||||||
if (!GetPersistantLocalInt(oPC, "VoPBoost"+IntToString(nLevelCheck))
|
|
||||||
&& (nLevelCheck-(nLevelCheck/4)*4 == 3) && (nLevelCheck >= 7) && (nLevelCheck <= 27))
|
|
||||||
{
|
|
||||||
AssignCommand(oPC, ClearAllActions(TRUE));
|
|
||||||
SetPersistantLocalInt(oPC, "VoPBoostCheck", nLevelCheck);
|
|
||||||
DelayCommand(3.5f, StartDynamicConversation("ft_vowpoverty_ab", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!GetPersistantLocalInt(oPC, "VoPFeat"+IntToString(nLevelCheck)) && (nLevelCheck-(nLevelCheck/2)*2 == 0))
|
|
||||||
{
|
|
||||||
AssignCommand(oPC, ClearAllActions(TRUE));
|
|
||||||
SetPersistantLocalInt(oPC, "VoPFeatCheck", nLevelCheck);
|
|
||||||
DelayCommand(3.5f, StartDynamicConversation("ft_vowpoverty_ft", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(nValue == DYNCONV_ABORTED)
|
|
||||||
{
|
|
||||||
// This section should never be run, since aborting this conversation should
|
|
||||||
// always be forbidden and as such, any attempts to abort the conversation
|
|
||||||
// should be handled transparently by the system
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: ERROR: Conversation abort section run");
|
|
||||||
}
|
|
||||||
// Handle PC response
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int nChoice = GetChoice(oPC);
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: Handling PC response, stage = " + IntToString(nStage) + "; nChoice = " +
|
|
||||||
IntToString(nChoice) + "; choice text = '" + GetChoiceText(oPC) + "'");
|
|
||||||
if(nStage == STAGE_SELECT_ABIL)
|
|
||||||
{
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: nChoice: " + IntToString(nChoice));
|
|
||||||
|
|
||||||
if (GetPRCSwitch("PRC_NWNXEE_ENABLED") && GetPRCSwitch("PRC_PRCX_ENABLED"))
|
|
||||||
{
|
|
||||||
// Apply intrinsic ability bonus via NWNxEE
|
|
||||||
PRC_Funcs_ModAbilityScore(oPC, nChoice, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Fallback to effect-based
|
|
||||||
effect eAbility = EffectAbilityIncrease(nChoice, 1);
|
|
||||||
eAbility = UnyieldingEffect(eAbility);
|
|
||||||
eAbility = TagEffect(eAbility, "ForsakerAbilityBoost");
|
|
||||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAbility, oPC);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetPersistantLocalInt(oPC, "ForsakerBoost"+IntToString(nClass), nChoice+1);
|
|
||||||
DeletePersistantLocalInt(oPC,"ForsakerBoostCheck");
|
|
||||||
AllowExit(DYNCONV_EXIT_FORCE_EXIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: New stage: " + IntToString(nStage));
|
|
||||||
|
|
||||||
// Store the stage value. If it has been changed, this clears out the choices
|
|
||||||
SetStage(nStage, oPC);
|
|
||||||
}
|
|
||||||
/* // Handle PC response
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int nChoice = GetChoice(oPC);
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: Handling PC response, stage = " + IntToString(nStage) + "; nChoice = " +
|
|
||||||
IntToString(nChoice) + "; choice text = '" + GetChoiceText(oPC) + "'");
|
|
||||||
if(nStage == STAGE_SELECT_ABIL)
|
|
||||||
{
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: nChoice: " + IntToString(nChoice));
|
|
||||||
|
|
||||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT,UnyieldingEffect(EffectAbilityIncrease(nChoice,1)),oPC); //Give the boost
|
|
||||||
SetPersistantLocalInt(oPC, "ForsakerBoost"+IntToString(nClass), nChoice+1); //Register the boost has been given
|
|
||||||
DeletePersistantLocalInt(oPC,"ForsakerBoostCheck");
|
|
||||||
|
|
||||||
// And we're all done
|
|
||||||
AllowExit(DYNCONV_EXIT_FORCE_EXIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(DEBUG) DoDebug("prc_forsake_abil: New stage: " + IntToString(nStage));
|
|
||||||
|
|
||||||
// Store the stage value. If it has been changed, this clears out the choices
|
|
||||||
SetStage(nStage, oPC);
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
@@ -2,9 +2,16 @@
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
object oUser = GetLastUsedBy();
|
||||||
|
if (!GetIsObjectValid(oUser)) return;
|
||||||
|
|
||||||
object oPC = OBJECT_SELF;
|
SpeakString("I was last used by: " + GetName(oUser));
|
||||||
|
|
||||||
StartDynamicConversation("bg_background_cv", oPC);
|
if (IsInConversation(oUser)) {
|
||||||
|
SpeakString("DEBUG: PC already in conversation; aborting dynconv start.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpeakString("DEBUG: Starting bg_background_cv for " + GetName(oUser));
|
||||||
|
StartDynamicConversation("bg_background_cv", oUser);
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,6 @@ void main()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpeakString("DEBUG: Starting bg_background_cv for " + GetName(oUser));
|
SpeakString("DEBUG: Starting bg_subrace_cv for " + GetName(oUser));
|
||||||
StartDynamicConversation("bg_subrace_cv", oUser);
|
StartDynamicConversation("bg_subrace_cv", oUser);
|
||||||
}
|
}
|
||||||
22
src/nss/switch_language.nss
Normal file
22
src/nss/switch_language.nss
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include "prc_effect_inc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
object oPC = OBJECT_SELF;
|
||||||
|
int nSpellID = GetSpellId();
|
||||||
|
|
||||||
|
if (GetHasSpellEffect(nSpellID, oPC))
|
||||||
|
{
|
||||||
|
PRCRemoveSpellEffects(nSpellID, oPC, oPC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
int nAC = 2;
|
||||||
|
if (GetSkillRank(SKILL_TUMBLE, oPC, TRUE) >= 5) nAC++;
|
||||||
|
|
||||||
|
effect eLink = EffectLinkEffects(EffectACIncrease(nAC, AC_DODGE_BONUS), EffectAttackDecrease(4));
|
||||||
|
eLink = ExtraordinaryEffect(eLink);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oPC);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -111,18 +111,19 @@ const int FEAT_LANGUAGE_IGNAN = 1672;
|
|||||||
const int FEAT_LANGUAGE_ILLUSKAN = 1673;
|
const int FEAT_LANGUAGE_ILLUSKAN = 1673;
|
||||||
const int FEAT_LANGUAGE_IMASKARI = 1674;
|
const int FEAT_LANGUAGE_IMASKARI = 1674;
|
||||||
const int FEAT_LANGUAGE_INFERNAL = 1675;
|
const int FEAT_LANGUAGE_INFERNAL = 1675;
|
||||||
const int FEAT_LANGUAGE_KOBOLD = 1676;
|
|
||||||
const int FEAT_LANGUAGE_LANTANESE = 1677;
|
const int FEAT_LANGUAGE_LANTANESE = 1677;
|
||||||
const int FEAT_LANGUAGE_MULANESE = 1678;
|
const int FEAT_LANGUAGE_MAZTILAN = 1678;
|
||||||
const int FEAT_LANGUAGE_MULHORANDI = 1679;
|
const int FEAT_LANGUAGE_MULANESE = 1679;
|
||||||
const int FEAT_LANGUAGE_ORCISH = 1680;
|
const int FEAT_LANGUAGE_MULHORANDI = 1680;
|
||||||
const int FEAT_LANGUAGE_RASHEMI = 1681;
|
const int FEAT_LANGUAGE_ORCISH = 1681;
|
||||||
const int FEAT_LANGUAGE_SYLVAN = 1682;
|
const int FEAT_LANGUAGE_RASHEMI = 1682;
|
||||||
const int FEAT_LANGUAGE_TALFIRIC = 1683;
|
const int FEAT_LANGUAGE_SHAARAN = 1683;
|
||||||
const int FEAT_LANGUAGE_TERRAN = 1684;
|
const int FEAT_LANGUAGE_SYLVAN = 1684;
|
||||||
const int FEAT_LANGUAGE_THIEVES_CANT = 1685;
|
const int FEAT_LANGUAGE_TALFIRIC = 1685;
|
||||||
const int FEAT_LANGUAGE_TROGLODYTE = 1686;
|
const int FEAT_LANGUAGE_TERRAN = 1686;
|
||||||
const int FEAT_LANGUAGE_UNDERCOMMON = 1687;
|
const int FEAT_LANGUAGE_THIEVES_CANT = 1687;
|
||||||
|
const int FEAT_LANGUAGE_TROGLODYTE = 1688;
|
||||||
|
const int FEAT_LANGUAGE_UNDERCOMMON = 1689;
|
||||||
|
|
||||||
const int CLASS_TYPE_CURSED_BLOOD = 46;
|
const int CLASS_TYPE_CURSED_BLOOD = 46;
|
||||||
const int CLASS_TYPE_WARLOCK = 47;
|
const int CLASS_TYPE_WARLOCK = 47;
|
||||||
@@ -137,6 +138,12 @@ const int CLASS_TYPE_ELDRITCH_KNIGHT = 55;
|
|||||||
const int CLASS_TYPE_MYSTIC_KNIGHT = 56;
|
const int CLASS_TYPE_MYSTIC_KNIGHT = 56;
|
||||||
const int CLASS_TYPE_ARTIFICER = 57;
|
const int CLASS_TYPE_ARTIFICER = 57;
|
||||||
const int CLASS_TYPE_MAGEBREAKER = 58;
|
const int CLASS_TYPE_MAGEBREAKER = 58;
|
||||||
|
|
||||||
|
const int AGE_CATEGORY_YOUTHFUL = 1373;
|
||||||
|
const int AGE_CATEGORY_MIDDLE = 1374;
|
||||||
|
const int AGE_CATEGORY_OLD = 1375;
|
||||||
|
const int AGE_CATEGORY_VENERABLE = 1376;
|
||||||
|
|
||||||
const int DEITY_Akadi = 1304;
|
const int DEITY_Akadi = 1304;
|
||||||
const int DEITY_Auril = 1305;
|
const int DEITY_Auril = 1305;
|
||||||
const int DEITY_Azuth = 1306;
|
const int DEITY_Azuth = 1306;
|
||||||
@@ -229,7 +236,6 @@ const int ETHNICITY_STRONGHEART = 1457;
|
|||||||
const int ETHNICITY_FEYRI = 1458;
|
const int ETHNICITY_FEYRI = 1458;
|
||||||
const int ETHNICITY_ELMANESSE = 1461;
|
const int ETHNICITY_ELMANESSE = 1461;
|
||||||
|
|
||||||
|
|
||||||
const int PROFICIENCY_HISTORY = 1426;
|
const int PROFICIENCY_HISTORY = 1426;
|
||||||
const int PROFICIENCY_ASTROLOGY = 1427;
|
const int PROFICIENCY_ASTROLOGY = 1427;
|
||||||
const int PROFICIENCY_DECIPHER = 1428;
|
const int PROFICIENCY_DECIPHER = 1428;
|
||||||
@@ -251,6 +257,9 @@ const int PROFICIENCY_GUNSMITHING = 1483;
|
|||||||
const int PROFICIENCY_OBSERVATION = 1484;
|
const int PROFICIENCY_OBSERVATION = 1484;
|
||||||
const int PROFICIENCY_SMELTING = 1485;
|
const int PROFICIENCY_SMELTING = 1485;
|
||||||
|
|
||||||
|
const int DISABILITY_ONE_ARMED = 2000;
|
||||||
|
|
||||||
|
|
||||||
#include "loi_functions"
|
#include "loi_functions"
|
||||||
//Apply Affliction Skins/Tools
|
//Apply Affliction Skins/Tools
|
||||||
//oPC - Target PC
|
//oPC - Target PC
|
||||||
|
|||||||
6460
src/te_includes/te_lang.nss
Normal file
6460
src/te_includes/te_lang.nss
Normal file
File diff suppressed because it is too large
Load Diff
BIN
src/tga/ife_age.tga
Normal file
BIN
src/tga/ife_age.tga
Normal file
Binary file not shown.
Reference in New Issue
Block a user