Added Spell Cancelation tool to end spells early. Made several Exalted feats available generally. Fixed prereqs for several Exalted feats. Fixed typo in Chasing Perfection related itemprops. Grouped Exalted feats under a masterfeat. Moved PRC8 Packages far down the packages.2da so as to not conflict with modules. Updated PRC8 Tester module. Epic Spell: Summon Aberration no longer sucks. Creatures were updated to match PnP and now level with caster. Twinfiend summon now receives the correct number of skill points for their bonus HD. Added LevelUpSummon() function for handling creatures w/ class levels. Further tweaking for the prc_2da_cache creature to prevent NPCs from attacking it. Add paragon & psuedonatural template related json functions. Gated errant debug message in prc_amagsys_gain.nss. Add DM Tool for viewing PC's current character sheet, templates & spell effects. Arrow of Bone shouldn't provide free mundane arrows anymore. Needs testing. Fixed a bunch of minor TLK typos.
407 lines
17 KiB
Plaintext
407 lines
17 KiB
Plaintext
//::////////////////////////////////////////////////////////
|
|
//:: ;-. ,-. ,-. ,-.
|
|
//:: | ) | ) / ( )
|
|
//:: |-' |-< | ;-:
|
|
//:: | | \ \ ( )
|
|
//:: ' ' ' `-' `-'
|
|
//::////////////////////////////////////////////////////////
|
|
//:: FileName: "prc_playerinfo"
|
|
//:: Created By: Jaysyn
|
|
//:: Last Updated On: 2025-11-25 08:26:22
|
|
//::
|
|
//::////////////////////////////////////////////////////////
|
|
/*
|
|
|
|
Displays a lot of relevant PC info in an NUI window
|
|
|
|
*/
|
|
//::////////////////////////////////////////////////////////
|
|
#include "nw_inc_nui"
|
|
#include "prc_inc_template"
|
|
|
|
const string CHAR_SHEET_WINDOW_ID = "char_sheet_window";
|
|
|
|
void ShowCharacterSheet(object oPC, object oTarget)
|
|
{
|
|
//:: Close existing window if open
|
|
int nToken = NuiFindWindow(oPC, CHAR_SHEET_WINDOW_ID);
|
|
if (nToken > 0)
|
|
{
|
|
NuiDestroy(oPC, nToken);
|
|
return;
|
|
}
|
|
|
|
//:: Build the layout
|
|
json jCol = JsonArray();
|
|
|
|
//:: === CHARACTER NAME & RACE ===
|
|
json jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Name:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_name"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Race:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_race"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Subrace:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_subrace"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Deity:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_deity"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Templates:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiText(NuiBind("char_templates"), TRUE, NUI_SCROLLBARS_AUTO));
|
|
jCol = JsonArrayInsert(jCol, NuiHeight(NuiRow(jRow), 60.0));
|
|
|
|
//:: === CLASSES ===
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Classes:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiText(NuiBind("char_classes"), TRUE, NUI_SCROLLBARS_AUTO));
|
|
jCol = JsonArrayInsert(jCol, NuiHeight(NuiRow(jRow), 120.0));
|
|
|
|
//:: === LEVEL & EXPERIENCE ===
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Total Level:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_level"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: Only show XP for PCs
|
|
if (GetIsPC(oTarget))
|
|
{
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Experience:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_xp"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
}
|
|
|
|
//:: === HIT POINTS ===
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Hit Points:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_hp"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: === ABILITY SCORES - Two columns ===
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Ability Scores:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: STR and DEX
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("STR:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_str"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("DEX:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_dex"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: CON and INT
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("CON:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_con"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("INT:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_int"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: WIS and CHA
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("WIS:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_wis"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("CHA:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_cha"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: === ENCUMBRANCE ===
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Encumbrance:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_encumbrance"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: === SAVING THROWS ===
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Saving Throws:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: Fortitude
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Fortitude:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_fort"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: Reflex
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Reflex:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_ref"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: Will
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Will:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_will"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: === ARMOR CLASS ===
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Armor Class:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jRow = JsonArrayInsert(jRow, NuiSpacer());
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind("char_ac"), JsonInt(NUI_HALIGN_RIGHT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
//:: === ACTIVE EFFECTS ===
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiLabel(JsonString("Active Spells:"), JsonInt(NUI_HALIGN_LEFT), JsonInt(NUI_VALIGN_MIDDLE)));
|
|
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
|
|
|
|
jRow = JsonArray();
|
|
jRow = JsonArrayInsert(jRow, NuiText(NuiBind("char_effects"), TRUE, NUI_SCROLLBARS_AUTO));
|
|
jCol = JsonArrayInsert(jCol, NuiHeight(NuiRow(jRow), 100.0));
|
|
|
|
//:: Create window
|
|
json jRoot = NuiCol(jCol);
|
|
|
|
string sTitle = "Character Sheet: " + GetName(oTarget);
|
|
json jNui = NuiWindow(
|
|
jRoot,
|
|
JsonString(sTitle),
|
|
NuiBind("geometry"),
|
|
JsonBool(TRUE),
|
|
JsonBool(FALSE),
|
|
JsonBool(TRUE),
|
|
JsonBool(FALSE),
|
|
JsonBool(TRUE)
|
|
);
|
|
|
|
nToken = NuiCreate(oPC, jNui, CHAR_SHEET_WINDOW_ID);
|
|
|
|
//:: Set geometry
|
|
NuiSetBind(oPC, nToken, "geometry", NuiRect(100.0, 100.0, 400.0, 850.0));
|
|
|
|
//:: === POPULATE DATA ===
|
|
|
|
//:: Name
|
|
NuiSetBind(oPC, nToken, "char_name", JsonString(GetName(oTarget)));
|
|
|
|
//:: Race
|
|
string sRace = GetStringByStrRef(StringToInt(Get2DAString("racialtypes", "Name", GetRacialType(oTarget))));
|
|
if (sRace == "") sRace = "Unknown";
|
|
NuiSetBind(oPC, nToken, "char_race", JsonString(sRace));
|
|
|
|
//:: Subrace
|
|
string sSubrace = GetSubRace(oTarget);
|
|
if (sSubrace == "") sSubrace = "None";
|
|
NuiSetBind(oPC, nToken, "char_subrace", JsonString(sSubrace));
|
|
|
|
//:: Deity
|
|
string sDeity = GetDeity(oTarget);
|
|
if (sDeity == "") sDeity = "None";
|
|
NuiSetBind(oPC, nToken, "char_deity", JsonString(sDeity));
|
|
|
|
//:: Templates - Check for persistent local variables named "template_X"
|
|
string sTemplates = "";
|
|
int nTemplateCount = 0;
|
|
int i;
|
|
int nMaxTemplates = 128;
|
|
|
|
for (i = 0; i <= nMaxTemplates; i++)
|
|
{
|
|
string sVarName = "template_" + IntToString(i);
|
|
|
|
//:: Check if this persistent local variable exists and is TRUE
|
|
if (GetPersistantLocalInt(oTarget, sVarName))
|
|
{
|
|
string sNameEntry = Get2DAString("templates", "Name", i);
|
|
|
|
//:: Only process if we got a valid name entry
|
|
if (sNameEntry != "")
|
|
{
|
|
int nNameStrRef = StringToInt(sNameEntry);
|
|
string sTemplateName = GetStringByStrRef(nNameStrRef);
|
|
|
|
if (sTemplateName == "")
|
|
sTemplateName = "Template " + IntToString(i);
|
|
|
|
if (nTemplateCount > 0)
|
|
sTemplates += "\n";
|
|
|
|
sTemplates += sTemplateName;
|
|
nTemplateCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (nTemplateCount == 0)
|
|
sTemplates = "None";
|
|
|
|
NuiSetBind(oPC, nToken, "char_templates", JsonString(sTemplates));
|
|
|
|
//:: Classes
|
|
string sClasses = "";
|
|
for (i = 1; i <= 8; i++)
|
|
{
|
|
int nClass = GetClassByPosition(i, oTarget);
|
|
if (nClass != CLASS_TYPE_INVALID)
|
|
{
|
|
string sClassName = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
|
|
if (sClassName == "") sClassName = "Class " + IntToString(nClass);
|
|
|
|
int nLevel = GetLevelByClass(nClass, oTarget);
|
|
|
|
if (sClasses != "")
|
|
sClasses += "\n";
|
|
|
|
sClasses += sClassName + " " + IntToString(nLevel);
|
|
}
|
|
}
|
|
|
|
if (sClasses == "")
|
|
sClasses = "No classes found";
|
|
|
|
NuiSetBind(oPC, nToken, "char_classes", JsonString(sClasses));
|
|
|
|
//:: Level
|
|
NuiSetBind(oPC, nToken, "char_level", JsonString(IntToString(GetHitDice(oTarget))));
|
|
|
|
//:: XP (only for PCs)
|
|
if (GetIsPC(oTarget))
|
|
{
|
|
NuiSetBind(oPC, nToken, "char_xp", JsonString(IntToString(GetXP(oTarget))));
|
|
}
|
|
|
|
//:: Hit Points
|
|
string sHP = IntToString(GetCurrentHitPoints(oTarget)) + " / " + IntToString(GetMaxHitPoints(oTarget));
|
|
NuiSetBind(oPC, nToken, "char_hp", JsonString(sHP));
|
|
|
|
//:: Ability Scores - Individual binds
|
|
NuiSetBind(oPC, nToken, "char_str", JsonString(IntToString(GetAbilityScore(oTarget, ABILITY_STRENGTH))));
|
|
NuiSetBind(oPC, nToken, "char_dex", JsonString(IntToString(GetAbilityScore(oTarget, ABILITY_DEXTERITY))));
|
|
NuiSetBind(oPC, nToken, "char_con", JsonString(IntToString(GetAbilityScore(oTarget, ABILITY_CONSTITUTION))));
|
|
NuiSetBind(oPC, nToken, "char_int", JsonString(IntToString(GetAbilityScore(oTarget, ABILITY_INTELLIGENCE))));
|
|
NuiSetBind(oPC, nToken, "char_wis", JsonString(IntToString(GetAbilityScore(oTarget, ABILITY_WISDOM))));
|
|
NuiSetBind(oPC, nToken, "char_cha", JsonString(IntToString(GetAbilityScore(oTarget, ABILITY_CHARISMA))));
|
|
|
|
//:: Encumbrance
|
|
int nEncumbrance = GetWeight(oTarget) / 10;
|
|
string sEncumbrance = IntToString(nEncumbrance) + " lbs";
|
|
|
|
//:: Only check for gold bag on PCs
|
|
if (GetIsPC(oTarget) && GetIsObjectValid(GetItemPossessedBy(oTarget, "NW_IT_MNYBAG01")))
|
|
{
|
|
nEncumbrance += GetGold(oTarget) / 50;
|
|
sEncumbrance += " (+" + IntToString(GetGold(oTarget) / 50) + " gold)";
|
|
}
|
|
NuiSetBind(oPC, nToken, "char_encumbrance", JsonString(sEncumbrance));
|
|
|
|
//:: Saves - Individual binds
|
|
NuiSetBind(oPC, nToken, "char_fort", JsonString(IntToString(GetFortitudeSavingThrow(oTarget))));
|
|
NuiSetBind(oPC, nToken, "char_ref", JsonString(IntToString(GetReflexSavingThrow(oTarget))));
|
|
NuiSetBind(oPC, nToken, "char_will", JsonString(IntToString(GetWillSavingThrow(oTarget))));
|
|
|
|
//:: AC
|
|
NuiSetBind(oPC, nToken, "char_ac", JsonString(IntToString(GetAC(oTarget))));
|
|
|
|
//:: Active Spells - Track unique spell IDs to avoid duplicates
|
|
string sEffects = "";
|
|
effect eEffect = GetFirstEffect(oTarget);
|
|
int nEffectCount = 0;
|
|
string sTrackedSpells = ""; //:: Use this to track which spells we've already listed
|
|
|
|
while (GetIsEffectValid(eEffect))
|
|
{
|
|
int nSpellId = GetEffectSpellId(eEffect);
|
|
|
|
//:: Only process if this is a valid spell and we haven't already listed it
|
|
if (nSpellId > 0)
|
|
{
|
|
string sSpellIdStr = IntToString(nSpellId);
|
|
|
|
//:: Check if we've already processed this spell
|
|
if (FindSubString(sTrackedSpells, ":" + sSpellIdStr + ":") == -1)
|
|
{
|
|
//:: Add to tracked list
|
|
sTrackedSpells += ":" + sSpellIdStr + ":";
|
|
|
|
//:: Get spell name from spells.2da -> TLK
|
|
int nNameStrRef = StringToInt(Get2DAString("spells", "Name", nSpellId));
|
|
string sSpellName = GetStringByStrRef(nNameStrRef);
|
|
|
|
if (sSpellName == "")
|
|
sSpellName = "Unknown Spell (ID: " + sSpellIdStr + ")";
|
|
|
|
//:: Get duration for this spell effect
|
|
float fDuration = IntToFloat(GetEffectDurationRemaining(eEffect));
|
|
string sDuration = "";
|
|
|
|
if (fDuration > 0.0)
|
|
{
|
|
int nSeconds = FloatToInt(fDuration);
|
|
int nMinutes = nSeconds / 60;
|
|
nSeconds = nSeconds % 60;
|
|
|
|
if (nMinutes > 0)
|
|
sDuration = IntToString(nMinutes) + "m " + IntToString(nSeconds) + "s";
|
|
else
|
|
sDuration = IntToString(nSeconds) + "s";
|
|
}
|
|
else
|
|
{
|
|
sDuration = "Permanent";
|
|
}
|
|
|
|
if (nEffectCount > 0)
|
|
sEffects += "\n";
|
|
|
|
sEffects += sSpellName + " (" + sDuration + ")";
|
|
nEffectCount++;
|
|
}
|
|
}
|
|
|
|
eEffect = GetNextEffect(oTarget);
|
|
}
|
|
|
|
if (nEffectCount == 0)
|
|
sEffects = "No active spells";
|
|
|
|
NuiSetBind(oPC, nToken, "char_effects", JsonString(sEffects));
|
|
}
|
|
|
|
void main()
|
|
{
|
|
object oPC = OBJECT_SELF;
|
|
object oTarget = oPC;
|
|
|
|
//:: If PC is targeting something else, show that target's sheet instead
|
|
object oTargeted = GetLocalObject(oPC, "EXAMINE_TARGET");
|
|
if (GetIsObjectValid(oTargeted) && GetObjectType(oTargeted) == OBJECT_TYPE_CREATURE)
|
|
{
|
|
oTarget = oTargeted;
|
|
}
|
|
|
|
//:: Show the window
|
|
ShowCharacterSheet(oPC, oTarget);
|
|
}
|