20250530 Late Update

Added @Rakiov's brilliant NUI spellcast system & power attack GUI.
Fixed incorrect constants for Charming the Arrow and Investigator.
Updated loadhints.2da.
This commit is contained in:
Jaysyn904
2025-05-30 23:23:08 -04:00
parent a85b0de327
commit 1fa8b68d5d
23 changed files with 2718 additions and 7818 deletions

View File

@@ -115,6 +115,7 @@ void PRCFeat_Equip(object oPC, object oSkin, int iEquip)
SetCompositeAttackBonus(oPC, "BrutalThrow", 0);
}
}
//:: Charming the Arrow - Apply bonus if Charisma > Dexterity for bows & crossbows
if (GetHasFeat(FEAT_CHARMING_THE_ARROW, oPC))
{
@@ -134,6 +135,11 @@ void PRCFeat_Equip(object oPC, object oSkin, int iEquip)
SetCompositeAttackBonus(oPC, "CharmingTheArrow", 0);
}
}
else
{
// Remove the bonus if Charisma is not greater
SetCompositeAttackBonus(oPC, "CharmingTheArrow", 0);
}
}
}
}

View File

@@ -0,0 +1,100 @@
//::///////////////////////////////////////////////
//:: Power Attack NUI Events
//:: prc_nui_pa_event
//:://////////////////////////////////////////////
/*
A class that handles the event firings from
the Power Attack NUI
*/
//:://////////////////////////////////////////////
//:: Created By: Rakiov
//:: Created On: 24.05.2005
//:://////////////////////////////////////////////
#include "prc_nui_consts"
void SetWindowGeometry(object oPlayer, int nToken);
void main()
{
object oPlayer = NuiGetEventPlayer();
int nToken = NuiGetEventWindow();
string sEvent = NuiGetEventType();
string sElement = NuiGetEventElement();
int nIndex = NuiGetEventArrayIndex();
// Get the current Power Attack value for player
int currentPAAmount = GetLocalInt(oPlayer, "PRC_PowerAttack_Level");
// if the window is closed, save the geometry
if (sEvent == "close")
{
SetWindowGeometry(oPlayer, nToken);
return;
}
// Not a mouseup event, nothing to do.
if (sEvent != "mouseup")
{
return;
}
// set the geometry to the player since we only get mouseup events on button presses :(
SetWindowGeometry(oPlayer, nToken);
int currentBAB = GetBaseAttackBonus(oPlayer);
if (sElement == NUI_PRC_PA_LEFT_BUTTON_EVENT)
{
// if the decreased power attack doesn't go below 0 then perform PA decrease
if(currentPAAmount-1 >= 0)
{
SetLocalInt(oPlayer, "PRC_PowerAttack_Level", currentPAAmount-1);
ExecuteScript("prc_nui_pa_trggr", oPlayer);
// if decreased pwoer attack is lower than the current BAB then allow
// the incrase button
if(currentPAAmount-1 <= currentBAB)
{
NuiSetBind(oPlayer, nToken, NUI_PRC_PA_RIGHT_BUTTON_ENABLED_BIND, JsonBool(TRUE));
}
}
else
{
// otherwise we have hit the limit and disable the left button
NuiSetBind(oPlayer, nToken, NUI_PRC_PA_LEFT_BUTTON_ENABLED_BIND, JsonBool(FALSE));
}
}
if (sElement == NUI_PRC_PA_RIGHT_BUTTON_EVENT)
{
//if the incrased power attack amount is less than or equal to the BAB
// then perform the PA increase
if(currentPAAmount+1 <= currentBAB)
{
SetLocalInt(oPlayer, "PRC_PowerAttack_Level", currentPAAmount+1);
ExecuteScript("prc_nui_pa_trggr", oPlayer);
// if the increased power attack amount is greater than 0 then enable
// the decrease button
if (currentPAAmount+1 > 0)
{
NuiSetBind(oPlayer, nToken, NUI_PRC_PA_LEFT_BUTTON_ENABLED_BIND, JsonBool(TRUE));
}
}
else
{
// otherwise we have hit the limit and disable the right button
NuiSetBind(oPlayer, nToken, NUI_PRC_PA_RIGHT_BUTTON_ENABLED_BIND, JsonBool(FALSE));
}
}
currentPAAmount = GetLocalInt(oPlayer, "PRC_PowerAttack_Level");
NuiSetBind(oPlayer, nToken, NUI_PRC_PA_TEXT_BIND, JsonString(IntToString(currentPAAmount)));
}
void SetWindowGeometry(object oPlayer, int nToken)
{
json dimensions = NuiGetBind(oPlayer, nToken, "geometry");
SetLocalJson(oPlayer, NUI_PRC_PA_GEOMETRY_VAR, dimensions);
}

View File

@@ -0,0 +1,94 @@
//::///////////////////////////////////////////////
//:: Power Attack Script
//:: prc_nui_pa_trggr
//:://////////////////////////////////////////////
/*
A script that sets the power attack on a player based on the amount
given.
*/
//:://////////////////////////////////////////////
//:: Created By: Rakiov
//:: Created On: 22.05.2005
//:://////////////////////////////////////////////
#include "prc_spell_const"
#include "inc_2dacache"
//
// ExecutePowerAttackChange
// Takes a Power Attack SpellID and checks to see what it's spell2da Master is.
// it then takes the Master's FeatID and the spell's spellId and does UseActionFeat
// to execute the power attack change.
//
// Arguments:
// spellId:int the Power attack spell Id this is being executed for
//
void ExecutePowerAttackChange(int spellId);
//
// Sets the power attack for a player, if the player has power attack and the
// amount is less than or equal to the players BAB it will apply the
// power attack and set the current power attack to the player at variable
// 'prcPaScriptPaVariable', otherwise it will tell the player it can't.
//
// Arguments:
// amount int the amount of power attack you want
// oPlayer object the player to apply the power attack to
//
void main()
{
int amount = GetLocalInt(OBJECT_SELF, "PRC_PowerAttack_Level");
int prevPowerAttack5 = GetLocalInt(OBJECT_SELF, "prevPowerAttack5");
int prevPowerAttack1 = GetLocalInt(OBJECT_SELF, "prevPowerAttack1");
int powerAttack5Amount = amount / 5;
int powerAttack1Amount = amount % 5;
//sets the 5 values for Power attack ranging from 0,5,10,15,20 respectivly
if (prevPowerAttack5 != powerAttack5Amount)
{
if (powerAttack5Amount == 0) // Power Attack 0
ExecutePowerAttackChange(SPELL_POWER_ATTACK6);
if (powerAttack5Amount == 1) // Power Attack 5
ExecutePowerAttackChange(SPELL_POWER_ATTACK7);
if (powerAttack5Amount == 2) // Power Attack 10
ExecutePowerAttackChange(SPELL_POWER_ATTACK8);
if (powerAttack5Amount == 3) // Power Attack 15
ExecutePowerAttackChange(SPELL_POWER_ATTACK9);
if (powerAttack5Amount == 4) // Power Attack 20
ExecutePowerAttackChange(SPELL_POWER_ATTACK10);
SetLocalInt(OBJECT_SELF, "prevPowerAttack5", powerAttack5Amount);
}
if (prevPowerAttack1 != powerAttack1Amount)
{
//sets the 1 values for Power attack ranging from 0,1,2,3,4 respectivly
if (powerAttack1Amount == 0) // Power Attack 0
ExecutePowerAttackChange(SPELL_POWER_ATTACK1);
if (powerAttack1Amount == 1) // Power Attack 1
ExecutePowerAttackChange(SPELL_POWER_ATTACK2);
if (powerAttack1Amount == 2) // Power Attack 2
ExecutePowerAttackChange(SPELL_POWER_ATTACK3);
if (powerAttack1Amount == 3) // Power Attack 3
ExecutePowerAttackChange(SPELL_POWER_ATTACK4);
if (powerAttack1Amount == 4) // Power Attack 4
ExecutePowerAttackChange(SPELL_POWER_ATTACK5);
SetLocalInt(OBJECT_SELF, "prevPowerAttack1", powerAttack1Amount);
}
}
void ExecutePowerAttackChange(int spellId)
{
int masterSpellId = StringToInt(Get2DACache("spells", "Master", spellId));
int featID;
int subSpellId = 0;
if (masterSpellId)
{
featID = StringToInt(Get2DACache("spells", "FeatID", masterSpellId));
subSpellId = spellId;
}
else
featID = StringToInt(Get2DACache("spells", "FeatID", spellId));
ActionUseFeat(featID, OBJECT_SELF, subSpellId);
}

View File

@@ -0,0 +1,98 @@
//::///////////////////////////////////////////////
//:: Power Attack NUI
//:: ha_pa_view
//:://////////////////////////////////////////////
/*
A NUI that sets the power attack on a player based on the amount
given.
*/
//:://////////////////////////////////////////////
//:: Created By: Rakiov
//:: Created On: 22.05.2005
//:://////////////////////////////////////////////
#include "nw_inc_nui"
#include "prc_nui_consts"
// #include "nw_inc_nui_insp" // used to debug
void main()
{
// First we look for any previous windows, if found (ie, non-zero) we destory them so we can start fresh.
int nPreviousToken = NuiFindWindow(OBJECT_SELF, NUI_PRC_POWER_ATTACK_WINDOW);
if (nPreviousToken != 0)
{
NuiDestroy(OBJECT_SELF, nPreviousToken);
}
// base element for NUI
json jRoot = JsonArray();
// Create and set parameters for left button
json jLeftButton = NuiId(NuiButton(JsonString("-")), NUI_PRC_PA_LEFT_BUTTON_EVENT);
jLeftButton = NuiWidth(jLeftButton, 32.0f);
jLeftButton = NuiHeight(jLeftButton, 32.0f);
jLeftButton = NuiEnabled(jLeftButton, NuiBind(NUI_PRC_PA_LEFT_BUTTON_ENABLED_BIND));
// Create and set parameters for text field
json jText = NuiText(NuiBind(NUI_PRC_PA_TEXT_BIND), TRUE, NUI_SCROLLBARS_NONE);
jText = NuiWidth(jText, 32.0f);
jText = NuiHeight(jText, 32.0f);
// Create and set parameters for right button
json jRightButton = NuiId(NuiButton(JsonString("+")), NUI_PRC_PA_RIGHT_BUTTON_EVENT);
jRightButton = NuiWidth(jRightButton, 32.0f);
jRightButton = NuiHeight(jRightButton, 32.0f);
jRightButton = NuiEnabled(jRightButton, NuiBind(NUI_PRC_PA_RIGHT_BUTTON_ENABLED_BIND));
// create button layout
json jRow = JsonArray();
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = JsonArrayInsert(jRow, jLeftButton);
jRow = JsonArrayInsert(jRow, jText);
jRow = JsonArrayInsert(jRow, jRightButton);
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = NuiRow(jRow);
jRoot = JsonArrayInsert(jRoot, jRow);
// set overall layout
jRoot = NuiCol(jRoot);
// Create the window and set binds for parameters in case we want to change them later
json nui = NuiWindow(jRoot, JsonString("Power Attack"), NuiBind("geometry"), NuiBind("resizable"), NuiBind("collapsed"), NuiBind("closable"), NuiBind("transparent"), NuiBind("border"));
int nToken = NuiCreate(OBJECT_SELF, nui, NUI_PRC_POWER_ATTACK_WINDOW);
// get the geometry of the window in case we opened this before and have a
// preference for location
json geometry = GetLocalJson(OBJECT_SELF, NUI_PRC_PA_GEOMETRY_VAR);
// Default to put this near the middle and let the person adjust its location
if (geometry == JsonNull())
{
geometry = NuiRect(1095.0f,312.0f, 166.0f, 93.0f);
}
// Set the binds to their default values
NuiSetBind(OBJECT_SELF, nToken, "geometry", geometry);
NuiSetBind(OBJECT_SELF, nToken, "collapsed", JsonBool(FALSE));
NuiSetBind(OBJECT_SELF, nToken, "resizable", JsonBool(FALSE));
NuiSetBind(OBJECT_SELF, nToken, "closable", JsonBool(TRUE));
NuiSetBind(OBJECT_SELF, nToken, "transparent", JsonBool(TRUE));
NuiSetBind(OBJECT_SELF, nToken, "border", JsonBool(FALSE));
int paAmount = GetLocalInt(OBJECT_SELF, "PRC_PowerAttack_Level");
int currentBAB = GetBaseAttackBonus(OBJECT_SELF);
// if we reach the left or right limits of the power attack, then disable the buttons
json leftButtonEnabled = (paAmount == 0) ? JsonBool(FALSE) : JsonBool(TRUE);
json rightButtonEnabled = (paAmount == currentBAB) ? JsonBool(FALSE) : JsonBool(TRUE);
// set the current PA amount to the window
NuiSetBind(OBJECT_SELF, nToken, NUI_PRC_PA_TEXT_BIND, JsonString(IntToString(paAmount)));
NuiSetBind(OBJECT_SELF, nToken, NUI_PRC_PA_LEFT_BUTTON_ENABLED_BIND, leftButtonEnabled);
NuiSetBind(OBJECT_SELF, nToken, NUI_PRC_PA_RIGHT_BUTTON_ENABLED_BIND, rightButtonEnabled);
}

View File

@@ -0,0 +1,372 @@
//::///////////////////////////////////////////////
//:: PRC Spellbook NUI Events
//:: prc_nui_sb_event
//:://////////////////////////////////////////////
/*
This is the event script for the PRC Spellbook NUI that handles button presses
and the like
*/
//:://////////////////////////////////////////////
//:: Created By: Rakiov
//:: Created On: 24.05.2005
//:://////////////////////////////////////////////
#include "prc_nui_consts"
#include "prc_nui_sb_inc"
#include "prc_nui_sbd_inc"
//
// SetWindowGeometry
// Saves the window geometry of the NUI Spellbook to the player so next time it
// renders it remembers where it was
//
// Arguments:
// oPlayer:object player tied to NUI
// nToken:int the NUI Spellbook window
//
void SetWindowGeometry(object oPlayer, int nToken);
//
// DetermineRangeForSpell
// Takes the string range from the spells.2da of a spell and converts it to
// the appropriate float range for the manual targetting mode
//
// Arguments:
// sRange:string the string range of the spell (P,T,S,M,L)
//
// Returns:
// float The flaot representation of the sRange provided
//
float DetermineRangeForSpell(string sRange);
//
// DetermineShapeForSpell
// Takes the string shape from the spells.2da of a spell and converts it to
// the int representation of the spell's shape. This is case sensitive and
// has to be in all UpperCase
//
// Arguments:
// shape:string the string shape of the spell (SPHERE,CONE, etc.)
//
// Returns:
// int the int representation of the shape provided
//
int DetermineShapeForSpell(string shape);
//
// DetermineTargetType
// Takes the string (actually hex) target type from the spells.2da of a spell and convers it to
// the int representation of the spell's target type. How this works is a bit unintuitive but
// it converts the string hex to a int, then subtracts it by the powers of 2. Each power represents
// the target the spell is allowed to be used on as all the ints are bitwise added together
//
// Arguments:
// targetType:string the hex value of the target type as a string.
//
// Returns:
// int the bitwise int representation of the targetType
int DetermineTargetType(string targetType);
void main()
{
object oPlayer = NuiGetEventPlayer();
int nToken = NuiGetEventWindow();
string sEvent = NuiGetEventType();
string sElement = NuiGetEventElement();
string sWindowId = NuiGetWindowId(oPlayer, nToken);
// if this was the Spell Description NUI and the OK button was clicked
// then we close the window.
if (sWindowId == NUI_SPELL_DESCRIPTION_WINDOW_ID)
{
if (sElement == NUI_SPELL_DESCRIPTION_OK_BUTTON)
NuiDestroy(oPlayer, nToken);
return;
}
// if the window is closed, save the geometry
if (sEvent == "close")
{
SetWindowGeometry(oPlayer, nToken);
return;
}
// Not a mouseup event, nothing to do.
if (sEvent != "mouseup")
{
return;
}
// Save the geometry first
SetWindowGeometry(oPlayer, nToken);
int spellId;
int featId;
int realSpellId;
// Checks to see if the event button has the class button baseId
// Then replaces the baseId with nothing and converts the end of the string to a int
// representing the ClassID gathered. (i.e. "test_123" gets converted to 123)
if (FindSubString(sElement, PRC_SPELLBOOK_NUI_CLASS_BUTTON_BASEID) >= 0)
{
int classId = StringToInt(RegExpReplace(PRC_SPELLBOOK_NUI_CLASS_BUTTON_BASEID, sElement, ""));
SetLocalInt(oPlayer, PRC_SPELLBOOK_SELECTED_CLASSID_VAR, classId);
ExecuteScript("prc_nui_sb_view", oPlayer);
return;
}
// Checks to see if the event button has the circle button baseId
// Then replaces the baseId with nothing and converts the end of the string to a int
// representing the circle number gathered. (i.e. "test_5" gets converted to 5)
if (FindSubString(sElement, PRC_SPELLBOOK_NUI_CIRCLE_BUTTON_BASEID) >= 0)
{
int circle = StringToInt(RegExpReplace(PRC_SPELLBOOK_NUI_CIRCLE_BUTTON_BASEID, sElement, ""));
SetLocalInt(oPlayer, PRC_SPELLBOOK_SELECTED_CIRCLE_VAR, circle);
ExecuteScript("prc_nui_sb_view", oPlayer);
return;
}
// Checks to see if the event button has the meta button baseId
// Then replaces the baseId with nothing and converts the end of the string to a int
// representing the SpellID gathered. (i.e. "test_123" gets converted to 123)
if (FindSubString(sElement, PRC_SPELLBOOK_NUI_META_BUTTON_BASEID) >= 0)
{
spellId = StringToInt(RegExpReplace(PRC_SPELLBOOK_NUI_META_BUTTON_BASEID, sElement, ""));
int masterSpellId = StringToInt(Get2DACache("spells", "Master", spellId));
if (masterSpellId)
{
SetLocalInt(oPlayer, NUI_SPELLBOOK_SELECTED_SUBSPELL_SPELLID_VAR, spellId);
featId = StringToInt(Get2DACache("spells", "FeatID", masterSpellId));
}
else
featId = StringToInt(Get2DACache("spells", "FeatID", spellId));
}
// Checks to see if the event button has the class button baseId
// Then replaces the baseId with nothing and converts the end of the string to a int
// representing the SpellbookID gathered. (i.e. "test_123" gets converted to 123)
if (FindSubString(sElement, PRC_SPELLBOOK_NUI_SPELL_BUTTON_BASEID) >= 0)
{
int spellbookId = StringToInt(RegExpReplace(PRC_SPELLBOOK_NUI_SPELL_BUTTON_BASEID, sElement, ""));
int classId = GetLocalInt(oPlayer, PRC_SPELLBOOK_SELECTED_CLASSID_VAR);
// special case for binders, since they don't have a spell 2da of their own.
if (classId == CLASS_TYPE_BINDER)
{
json binderDict = GetBinderSpellToFeatDictionary(oPlayer);
spellId = spellbookId;
featId = JsonGetInt(JsonObjectGet(binderDict, IntToString(spellId)));
int masterSpellId = StringToInt(Get2DACache("spells", "Master", spellId));
if (masterSpellId)
{
SetLocalInt(oPlayer, NUI_SPELLBOOK_SELECTED_SUBSPELL_SPELLID_VAR, spellId);
featId = StringToInt(Get2DACache("spells", "FeatID", masterSpellId));
}
else
featId = StringToInt(Get2DACache("spells", "FeatID", spellId));
}
else
{
string sFile = GetClassSpellbookFile(classId);
spellId = StringToInt(Get2DACache(sFile, "SpellID", spellbookId));
realSpellId = StringToInt(Get2DACache(sFile, "RealSpellID", spellbookId));
int masterSpellId = StringToInt(Get2DACache("spells", "Master", spellId));
// If this spell is part of a radial we need to send the master featID
// to be used along with the radial spellId
if (masterSpellId)
{
SetLocalInt(oPlayer, NUI_SPELLBOOK_SELECTED_SUBSPELL_SPELLID_VAR, spellId);
spellId = masterSpellId;
}
featId = StringToInt(Get2DACache("spells", "FeatID", spellId));
}
}
json jPayload = NuiGetEventPayload();
int nButton = JsonGetInt(JsonObjectGet(jPayload, "mouse_btn"));
// If right click, open the Spell Description NUI
if (nButton == NUI_PAYLOAD_BUTTON_RIGHT_CLICK)
{
CreateSpellDescriptionNUI(oPlayer, featId, spellId, realSpellId);
return;
}
// If left click, operate normally
if (nButton == NUI_PAYLOAD_BUTTON_LEFT_CLICK)
{
// We use the spell's FeatID to do actions, and we set the OnTarget action
// to PRC_NUI_SPELLBOOK so the handler knows what the action is being done
SetLocalInt(oPlayer, NUI_SPELLBOOK_SELECTED_FEATID_VAR, featId);
string sRange = GetStringUpperCase(Get2DACache("spells", "Range", spellId));
// If its a personal spell/feat than use it directly on the player.
if (sRange == "P")
{
SetLocalInt(oPlayer, NUI_SPELLBOOK_ON_TARGET_IS_PERSONAL_FEAT, 1);
ExecuteScript("prc_nui_sb_trggr", oPlayer);
}
// otherwise enter targetting mode
else
{
SetLocalString(oPlayer, NUI_SPELLBOOK_ON_TARGET_ACTION_VAR, "PRC_NUI_SPELLBOOK");
// These gather the targetting information for the TargetingMode functions
float fRange = DetermineRangeForSpell(sRange);
string sShape = GetStringUpperCase(Get2DACache("spells", "TargetShape", spellId));
int iShape = DetermineShapeForSpell(sShape);
float fSizeX = StringToFloat(Get2DACache("spells", "TargetSizeX", spellId));
float fSizeY = StringToFloat(Get2DACache("spells", "TargetSizeY", spellId));
int nFlags = StringToInt(Get2DACache("spells", "TargetFlags", spellId));
string sTargetType = Get2DACache("spells", "TargetType", spellId);
int iTargetType = DetermineTargetType(sTargetType);
SetEnterTargetingModeData(oPlayer, iShape, fSizeX, fSizeY, nFlags, fRange);
EnterTargetingMode(oPlayer, iTargetType);
}
}
}
void SetWindowGeometry(object oPlayer, int nToken)
{
json dimensions = NuiGetBind(oPlayer, nToken, "geometry");
SetLocalJson(oPlayer, PRC_SPELLBOOK_NUI_GEOMETRY_VAR, dimensions);
}
int DetermineShapeForSpell(string shape)
{
if (shape == "CONE")
{
return SPELL_TARGETING_SHAPE_CONE;
}
if (shape == "SPHERE")
{
return SPELL_TARGETING_SHAPE_SPHERE;
}
if (shape == "RECTANGLE")
{
return SPELL_TARGETING_SHAPE_RECT;
}
if (shape == "HSPHERE")
{
return SPELL_TARGETING_SHAPE_HSPHERE;
}
return SPELL_TARGETING_SHAPE_NONE;
}
float DetermineRangeForSpell(string sRange)
{
//Personal
if (sRange == "P")
{
return StringToFloat(Get2DACache("ranges", "PrimaryRange", 0));
}
//Touch
if(sRange == "T")
{
return StringToFloat(Get2DACache("ranges", "PrimaryRange", 1));
}
//Short
if(sRange == "S")
{
return StringToFloat(Get2DACache("ranges", "PrimaryRange", 2));
}
//Medium
if(sRange == "M")
{
return StringToFloat(Get2DACache("ranges", "PrimaryRange", 3));
}
//Long
if(sRange == "L")
{
return StringToFloat(Get2DACache("ranges", "PrimaryRange", 4));
}
return 0.0;
}
int DetermineTargetType(string targetType)
{
int retValue = -1;
int iTargetType = HexToInt(targetType);
if (iTargetType - 64 >= 0)
{
if (retValue == -1)
{
retValue = OBJECT_TYPE_TRIGGER;
}
else
{
retValue = retValue | OBJECT_TYPE_TRIGGER;
}
iTargetType -= 64;
}
if (iTargetType - 32 >= 0)
{
if (retValue == -1)
{
retValue = OBJECT_TYPE_PLACEABLE;
}
else
{
retValue = retValue | OBJECT_TYPE_PLACEABLE;
}
iTargetType -= 32;
}
if (iTargetType - 16 >= 0)
{
if (retValue == -1)
{
retValue = OBJECT_TYPE_DOOR;
}
else
{
retValue = retValue | OBJECT_TYPE_DOOR;
}
iTargetType -= 16;
}
if (iTargetType - 8 >= 0)
{
if (retValue == -1)
{
retValue = OBJECT_TYPE_ITEM;
}
else
{
retValue = retValue | OBJECT_TYPE_ITEM;
}
iTargetType -= 8;
}
if (iTargetType - 4 >= 0)
{
if (retValue == -1)
{
retValue = OBJECT_TYPE_TILE;
}
else
{
retValue = retValue | OBJECT_TYPE_TILE;
}
iTargetType -= 4;
}
if (iTargetType - 2 >= 0 || iTargetType - 1 >= 0)
{
if (retValue == -1)
{
retValue = OBJECT_TYPE_CREATURE;
}
else
{
retValue = retValue | OBJECT_TYPE_CREATURE;
}
iTargetType = 0;
}
return retValue;
}

View File

@@ -0,0 +1,50 @@
//::///////////////////////////////////////////////
//:: PRC Spellbook OnTrigger Script
//:: prc_nui_sb_trggr
//:://////////////////////////////////////////////
/*
This is the OnTarget action script used to make spell attacks with the
selected spell from the PRC Spellbook NUI
*/
//:://////////////////////////////////////////////
//:: Created By: Rakiov
//:: Created On: 24.05.2005
//:://////////////////////////////////////////////
#include "prc_nui_consts"
#include "inc_newspellbook"
void main()
{
// Get the selected PRC spell we are going to cast
int featId = GetLocalInt(OBJECT_SELF, NUI_SPELLBOOK_SELECTED_FEATID_VAR);
int isPersonalFeat = GetLocalInt(OBJECT_SELF, NUI_SPELLBOOK_ON_TARGET_IS_PERSONAL_FEAT);
// if this is a personal feat then this was called directly since we never entered
// targetting and this should be applied immediatly to the executing player.
if (isPersonalFeat)
{
ActionUseFeat(featId);
// we want to remove this just in case of weird cases.
DeleteLocalInt(OBJECT_SELF, NUI_SPELLBOOK_ON_TARGET_IS_PERSONAL_FEAT);
}
else
{
// if the spell has a master feat this is it. This will return 0 if not set.
int subSpellID = GetLocalInt(OBJECT_SELF, NUI_SPELLBOOK_SELECTED_SUBSPELL_SPELLID_VAR);
// Get the target and location data we are casting at
object oTarget = GetLocalObject(OBJECT_SELF, "TARGETING_OBJECT");
location spellLocation = GetLocalLocation(OBJECT_SELF, "TARGETING_POSITION");
// if the object is valid and isn't empty then cast spell at target
if (GetIsObjectValid(oTarget) && GetObjectType(oTarget))
spellLocation = LOCATION_INVALID;
// otherwise if the area is a valid location to cast at, cast at location
else if (GetIsObjectValid(GetAreaFromLocation(spellLocation)))
oTarget = OBJECT_INVALID;
ActionUseFeat(featId, oTarget, subSpellID, spellLocation);
}
}

View File

@@ -0,0 +1,519 @@
//::///////////////////////////////////////////////
//:: PRC Spellbook NUI View
//:: prc_nui_sb_view
//:://////////////////////////////////////////////
/*
This is the NUI view for the PRC Spellbook
*/
//:://////////////////////////////////////////////
//:: Created By: Rakiov
//:: Created On: 24.05.2005
//:://////////////////////////////////////////////
#include "nw_inc_nui"
//#include "nw_inc_nui_insp"
#include "prc_nui_sb_inc"
#include "prc_nui_consts"
//
// CreateSpellBookClassButtons
// Gets the list of classes that have Spells, "Spells" and /Spells/ the player has
// that are allowed to use the NUI Spellbook.
//
// Returns:
// json NuiRow the list of class buttons allowed to use the NUI Spellbook
//
json CreateSpellBookClassButtons();
//
// CreateSpellbookSpellButtons
// Creates the NUI buttons for the spells a player knows in the specified class
// and circle provided.
//
// Arguments:
// nClass int the class currently being checked for spells
// circle int the circle level of the spells we want to check for
//
// Returns:
// json:Array<NuiRow> the list of NuiRows of spells we have memorized
//
json CreateSpellbookSpellButtons(int nClass, int circle);
//
// CreateSpellbookSpellButtons
// Creates the buttons for what circles the class is allowed to cast in
// ranging from Cantrips to 9th circle or equivalent for classes that don't have
// a concept of spell circles, like ToB and Psionics
//
// Arguments:
// nClass int the class id this is being constructed for.
//
// Returns:
// json NuiRow the level at which the caster can or does know as buttons
//
json CreateSpellbookCircleButtons(int nClass);
//
// CreateMetaMagicFeatButtons
// Takes a class and creates the appropriate meta feat buttons it can use or
// possibly use.
//
// Arguments:
// nClass:int the ClassID we are checking
//
// Returns:
// json:Array<NuiRow> the list of meta feats the class can use. Can return an
// empty JsonArray if no meta feats are allowed for the class.
//
json CreateMetaMagicFeatButtons(int nClass);
//
// CreateMetaFeatButtonRow
// a helper function for CreateMetaMagicFeatButtons that takes a list of featIds
// and creates buttons for them.
//
// Arguments:
// featList:json:Array<int> the list of featIDs to render
//
// Returns:
// json:Array<NuiButtons> the row of buttons rendered for the FeatIDs.
//
json CreateMetaFeatButtonRow(json spellList);
//
// GetSpellLevelIcon
// Takes the spell circle int and gets the icon appropriate for it (i.e. 0 turns
// into "ir_cantrips"
//
// Arguments:
// spellLevel:int the spell level we want the icon for
//
// Returns:
// string the spell level icon
//
string GetSpellLevelIcon(int spellLevel);
//
// GetSpellLevelToolTip
// Gets the spell level tool tip text based on the int spell level provided (i.e.
// 0 turns into "Cantrips")
//
// Arguments:
// spellLevel:int the spell level we want the tooltip for
//
// Returns:
// string the spell level toop tip
//
string GetSpellLevelToolTip(int spellLevel);
//
// GetSpellIcon
// Gets the spell icon based off the spellId by using the FeatID instead
//
// Arguments:
// nClass:int the class Id
// spellId:int the spell Id we want the icon for
//
// Returns:
// json:String the string of the icon we want.
//
json GetSpellIcon(int spellId, int nClass=0);
void main()
{
// look for existing window and destroy
int nPreviousToken = NuiFindWindow(OBJECT_SELF, PRC_SPELLBOOK_NUI_WINDOW_ID);
if(nPreviousToken != 0)
{
NuiDestroy(OBJECT_SELF, nPreviousToken);
}
json jRoot = JsonArray();
json jRow = CreateSpellBookClassButtons();
jRoot = JsonArrayInsert(jRoot, jRow);
int selectedClassId = GetLocalInt(OBJECT_SELF, PRC_SPELLBOOK_SELECTED_CLASSID_VAR);
// GetLocalInt returns 0 if not set, which is Barb class which conveniently doesn't have spells :)
// if there was no selected class then there is nothing to render
if (selectedClassId != CLASS_TYPE_BARBARIAN)
{
// create the metamagic/metapsionic/metamystery/sudden buttons if applicable
// suddens are on their own row so its possible we can have 2 NuiRows in the list
jRow = CreateMetaMagicFeatButtons(selectedClassId);
int i;
for(i = 0; i < JsonGetLength(jRow); i++)
{
jRoot = JsonArrayInsert(jRoot, JsonArrayGet(jRow, i));
}
// create the spell/feat circle buttons for the class (most use 0-9, but
// ToB uses something similar that ranges from 1-9 and Invokers essentially
// go 1-4 as examples
jRow = CreateSpellbookCircleButtons(selectedClassId);
jRoot = JsonArrayInsert(jRoot, jRow);
// Get the currently selected circle's spell buttons
int currentCircle = GetLocalInt(OBJECT_SELF, PRC_SPELLBOOK_SELECTED_CIRCLE_VAR);
jRow = CreateSpellbookSpellButtons(selectedClassId, currentCircle);
// since we limit how many buttons a row can have here we need to add
// multiple NuiRows if they exist
for(i = 0; i < JsonGetLength(jRow); i++)
{
jRoot = JsonArrayInsert(jRoot, JsonArrayGet(jRow, i));
}
}
jRoot = NuiCol(jRoot);
string title = "PRC Spellbook";
if (selectedClassId != CLASS_TYPE_BARBARIAN)
title = title + ": " + GetStringByStrRef(StringToInt(Get2DACache("classes", "Name", selectedClassId)));
// This is the main window with jRoot as the main pane. It includes titles and parameters (more on those later)
json nui = NuiWindow(jRoot, JsonString(title), NuiBind("geometry"), NuiBind("resizable"), NuiBind("collapsed"), NuiBind("closable"), NuiBind("transparent"), NuiBind("border"));
// finally create it and it'll return us a non-zero token.
int nToken = NuiCreate(OBJECT_SELF, nui, PRC_SPELLBOOK_NUI_WINDOW_ID);
// get the geometry of the window in case we opened this before and have a
// preference for location
json geometry = GetLocalJson(OBJECT_SELF, PRC_SPELLBOOK_NUI_GEOMETRY_VAR);
// Default to put this near the middle and let the person adjust its location
if (geometry == JsonNull())
{
geometry = NuiRect(893.0f,346.0f, 489.0f, 351.0f);
}
// Set the binds to their default values
NuiSetBind(OBJECT_SELF, nToken, "geometry", geometry);
NuiSetBind(OBJECT_SELF, nToken, "collapsed", JsonBool(FALSE));
NuiSetBind(OBJECT_SELF, nToken, "resizable", JsonBool(FALSE));
NuiSetBind(OBJECT_SELF, nToken, "closable", JsonBool(TRUE));
NuiSetBind(OBJECT_SELF, nToken, "transparent", JsonBool(TRUE));
NuiSetBind(OBJECT_SELF, nToken, "border", JsonBool(FALSE));
}
json CreateSpellBookClassButtons()
{
json jRow = JsonArray();
// Get all the Classes that can use the NUI Spellbook
json classList = GetSupportedNUISpellbookClasses(OBJECT_SELF);
// if we have selected a class already due to re-rendering, we need to disable
// the button for it.
int selectedClassId = GetLocalInt(OBJECT_SELF, PRC_SPELLBOOK_SELECTED_CLASSID_VAR);
int i;
for (i = 0; i < JsonGetLength(classList); i++)
{
int classId = JsonGetInt(JsonArrayGet(classList, i));
// if the selected class doen't exist, automatically use the first class allowed
if (selectedClassId == 0)
{
selectedClassId = classId;
SetLocalInt(OBJECT_SELF, PRC_SPELLBOOK_SELECTED_CLASSID_VAR, selectedClassId);
}
// Get the class icon from the classes.2da
json jClassButton = NuiId(NuiButtonImage(JsonString(Get2DACache("classes", "Icon", classId))), PRC_SPELLBOOK_NUI_CLASS_BUTTON_BASEID + IntToString(classId));
jClassButton = NuiWidth(jClassButton, 32.0f);
jClassButton = NuiHeight(jClassButton, 32.0f);
// Get the class name from the classes.2da and set it to the tooltip
jClassButton = NuiTooltip(jClassButton, JsonString(GetStringByStrRef(StringToInt(Get2DACache("classes", "Name", classId)))));
jRow = JsonArrayInsert(jRow, jClassButton);
}
jRow = NuiRow(jRow);
return jRow;
}
json CreateSpellbookCircleButtons(int nClass)
{
json jRow = JsonArray();
int i;
// Get the current selected circle and the class caster level.
int currentCircle = GetLocalInt(OBJECT_SELF, PRC_SPELLBOOK_SELECTED_CIRCLE_VAR);
int casterLevel = GetPrCAdjustedCasterLevel(nClass, OBJECT_SELF);
// Get what the lowest level of a circle is for the class (some start at 1,
// some start higher, some start at cantrips)
int minSpellLevel = GetMinSpellLevel(nClass);
if (minSpellLevel >= 0)
{
// get what is the highest circle the class can cast at
int currentMaxSpellLevel = GetCurrentSpellLevel(nClass, casterLevel);
// Get what the max circle the class can reach at is
int totalMaxSpellLevel = GetMaxSpellLevel(nClass);
// if the current circle is less than the minimum level (possibly due to
// switching classes) then set it to that.
if (currentCircle < minSpellLevel)
{
currentCircle = minSpellLevel;
SetLocalInt(OBJECT_SELF, PRC_SPELLBOOK_SELECTED_CIRCLE_VAR, currentCircle);
}
// conversily if it is higher than the max the class has (possibly due to
// switching classes) then set it to that.
if (currentCircle > currentMaxSpellLevel)
{
currentCircle = currentMaxSpellLevel;
SetLocalInt(OBJECT_SELF, PRC_SPELLBOOK_SELECTED_CIRCLE_VAR, currentCircle);
}
for (i = minSpellLevel; i <= totalMaxSpellLevel; i++)
{
json enabled;
json jButton = NuiId(NuiButtonImage(JsonString(GetSpellLevelIcon(i))), PRC_SPELLBOOK_NUI_CIRCLE_BUTTON_BASEID + IntToString(i));
jButton = NuiWidth(jButton, 42.0f);
jButton = NuiHeight(jButton, 42.0f);
jButton = NuiTooltip(jButton, JsonString(GetSpellLevelToolTip(i)));
// if the current circle is selected or if the person can't cast at
// that circle yet then disable the button.
if (currentCircle == i || i > currentMaxSpellLevel)
{
enabled = JsonBool(FALSE);
}
else
{
enabled = JsonBool(TRUE);
}
jButton = NuiEnabled(jButton, enabled);
jRow = JsonArrayInsert(jRow, jButton);
}
}
jRow = NuiRow(jRow);
return jRow;
}
json CreateSpellbookSpellButtons(int nClass, int circle)
{
json jRows = JsonArray();
// we only want to get spells at the currently selected circle.
int currentCircle = GetLocalInt(OBJECT_SELF, PRC_SPELLBOOK_SELECTED_CIRCLE_VAR);
json spellListAtCircle = GetSpellListForCircle(OBJECT_SELF, nClass, currentCircle);
string sFile = GetClassSpellbookFile(nClass);
// how many buttons a row can have before we have to make a new row.
int rowLimit = NUI_SPELLBOOK_SPELL_BUTTON_LENGTH;
json tempRow = JsonArray();
int i;
for (i = 0; i < JsonGetLength(spellListAtCircle); i++)
{
int spellbookId = JsonGetInt(JsonArrayGet(spellListAtCircle, i));
int spellId;
// Binders don't have a spellbook, so spellbookId is actually SpellID
if (nClass == CLASS_TYPE_BINDER)
spellId = spellbookId;
else
spellId = StringToInt(Get2DACache(sFile, "SpellID", spellbookId));
json jSpellButton = NuiId(NuiButtonImage(GetSpellIcon(spellId, nClass)), PRC_SPELLBOOK_NUI_SPELL_BUTTON_BASEID + IntToString(spellbookId));
jSpellButton = NuiWidth(jSpellButton, 38.0f);
jSpellButton = NuiHeight(jSpellButton, 38.0f);
// the RealSpellID has the accurate descriptions for the spells/abilities
int realSpellId = StringToInt(Get2DACache(sFile, "RealSpellID", spellbookId));
if (!realSpellId)
realSpellId = spellId;
jSpellButton = NuiTooltip(jSpellButton, JsonString(GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", realSpellId)))));
// if the row limit has been reached, make a new row
tempRow = JsonArrayInsert(tempRow, jSpellButton);
if (JsonGetLength(tempRow) >= rowLimit)
{
tempRow = NuiRow(tempRow);
jRows = JsonArrayInsert(jRows, tempRow);
tempRow = JsonArray();
}
}
// if the row was cut short (a remainder) then we finish the row and add it
// to the list
if (JsonGetLength(tempRow) > 0)
{
tempRow = NuiRow(tempRow);
jRows = JsonArrayInsert(jRows, tempRow);
}
return jRows;
}
json CreateMetaMagicFeatButtons(int nClass)
{
json jRows = JsonArray();
json currentRow = JsonArray();
// if an invoker, add the invoker shapes and essences as its own row of buttons
if (nClass == CLASS_TYPE_WARLOCK
|| nClass == CLASS_TYPE_DRAGONFIRE_ADEPT
|| nClass == CLASS_TYPE_DRAGON_SHAMAN)
{
currentRow = CreateMetaFeatButtonRow(GetInvokerShapeSpellList(nClass));
if (JsonGetLength(currentRow) > 0)
{
currentRow = NuiRow(currentRow);
jRows = JsonArrayInsert(jRows, currentRow);
}
currentRow = CreateMetaFeatButtonRow(GetInvokerEssenceSpellList(nClass));
if (JsonGetLength(currentRow) > 0)
{
currentRow = NuiRow(currentRow);
jRows = JsonArrayInsert(jRows, currentRow);
}
}
// if a ToB class, add its stances as its own row of buttons
if (nClass == CLASS_TYPE_WARBLADE
|| nClass == CLASS_TYPE_CRUSADER
|| nClass == CLASS_TYPE_SWORDSAGE)
{
currentRow = CreateMetaFeatButtonRow(GetToBStanceSpellList(nClass));
if (JsonGetLength(currentRow) > 0)
{
currentRow = NuiRow(currentRow);
jRows = JsonArrayInsert(jRows, currentRow);
}
}
currentRow = JsonArray();
// check to see if the class can use any particular meta feats
if (CanClassUseMetamagicFeats(nClass))
currentRow = CreateMetaFeatButtonRow(GetMetaMagicFeatList());
else if (CanClassUseMetaPsionicFeats(nClass))
currentRow = CreateMetaFeatButtonRow(GetMetaPsionicFeatList());
else if (CanClassUseMetaMysteryFeats(nClass))
currentRow = CreateMetaFeatButtonRow(GetMetaMysteryFeatList());
if (JsonGetLength(currentRow) > 0)
{
currentRow = NuiRow(currentRow);
jRows = JsonArrayInsert(jRows, currentRow);
}
// and check to see if the class can use sudden meta feats
currentRow = JsonArray();
if (CanClassUseSuddenMetamagicFeats(nClass))
currentRow = CreateMetaFeatButtonRow(GetSuddenMetaMagicFeatList());
if (JsonGetLength(currentRow) > 0)
{
currentRow = NuiRow(currentRow);
jRows = JsonArrayInsert(jRows, currentRow);
}
return jRows;
}
json CreateMetaFeatButtonRow(json spellList)
{
json jRow = JsonArray();
int i;
for (i = 0; i < JsonGetLength(spellList); i++)
{
int spellId = JsonGetInt(JsonArrayGet(spellList, i));
int featId;
int masterSpell = StringToInt(Get2DACache("spells", "Master", spellId));
if (masterSpell)
featId = StringToInt(Get2DACache("spells", "FeatID", masterSpell));
else
featId = StringToInt(Get2DACache("spells", "FeatID", spellId));
if (GetHasFeat(featId, OBJECT_SELF, TRUE))
{
string featName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", spellId)));
json jMetaButton = NuiId(NuiButtonImage(GetSpellIcon(spellId)), PRC_SPELLBOOK_NUI_META_BUTTON_BASEID + IntToString(spellId));
jMetaButton = NuiWidth(jMetaButton, 32.0f);
jMetaButton = NuiHeight(jMetaButton, 32.0f);
jMetaButton = NuiTooltip(jMetaButton, JsonString(featName));
jRow = JsonArrayInsert(jRow, jMetaButton);
}
}
return jRow;
}
json GetSpellIcon(int spellId,int nClass=0)
{
// Binder's spells don't have the FeatID on the spells.2da, so we have to use
// the mapping we constructed to get it.
if (nClass == CLASS_TYPE_BINDER)
{
json binderDict = GetBinderSpellToFeatDictionary();
int featId = JsonGetInt(JsonObjectGet(binderDict, IntToString(spellId)));
return JsonString(Get2DACache("feat", "Icon", featId));
}
int masterSpellID = StringToInt(Get2DACache("spells", "Master", spellId));
// if this is a sub radial spell, then we use spell's icon instead
if (masterSpellID)
return JsonString(Get2DACache("spells", "IconResRef", spellId));
// the FeatID holds the accurate spell icon, not the SpellID
int featId = StringToInt(Get2DACache("spells", "FeatID", spellId));
return JsonString(Get2DACache("feat", "Icon", featId));
}
string GetSpellLevelIcon(int spellLevel)
{
switch (spellLevel)
{
case 0: return "ir_cantrips";
case 1: return "ir_level1";
case 2: return "ir_level2";
case 3: return "ir_level3";
case 4: return "ir_level4";
case 5: return "ir_level5";
case 6: return "ir_level6";
case 7: return "ir_level789";
case 8: return "ir_level789";
case 9: return "ir_level789";
}
return "";
}
string GetSpellLevelToolTip(int spellLevel)
{
switch (spellLevel)
{
case 0: return "Cantrips";
case 1: return "Level 1";
case 2: return "Level 2";
case 3: return "Level 3";
case 4: return "Level 4";
case 5: return "Level 5";
case 6: return "Level 6";
case 7: return "Level 7";
case 8: return "Level 8";
case 9: return "Level 9";
}
return "";
}

View File

@@ -2,6 +2,15 @@
//:: OnPlayerChat eventscript
//:: prc_onplayerchat
//:://////////////////////////////////////////////
/*
A OnChat script that parses what is said and
uses any commands or NUI associated with
commands.
*/
//:://////////////////////////////////////////////
//:: Updated By: Rakiov
//:: Created On: 22.05.2005
//:://////////////////////////////////////////////
/*
PRC Chat Command Format:
@@ -15,6 +24,10 @@ OR:
#include "prc_inc_chat_dm"
#include "prc_inc_chat_pow"
#include "prc_inc_chat_shf"
#include "nw_inc_nui"
#include "prc_string_inc"
#include "prc_nui_sb_inc"
#include "prc_nui_consts"
const string CHAT_COMMAND_INDICATOR_1 = "~~";
const string CHAT_COMMAND_INDICATOR_2 = "..";
@@ -87,8 +100,54 @@ void main()
ExecuteScript(GetLocalString(oPC, PRC_CHAT_HOOK_SCRIPT), oPC);
_clear_chat_vars(oPC);
}
ExecuteScript("hp_pa_chatscript", oPC);
// get current player message and split it up into a list
string sCommand = GetPCChatMessage();
json sCommandSplit = StringSplit(sChat);
if(JsonGetLength(sCommandSplit) > 0)
{
string firstWord = JsonGetString(JsonArrayGet(sCommandSplit, 0));
// if first word is /pa we are using the power attack interface
if(firstWord == "/pa")
{
if(JsonGetLength(sCommandSplit) >= 2)
{
//if a parameter is given then run the power attack command directly.
string param1 = JsonGetString(JsonArrayGet(sCommandSplit, 1));
int paAmount = StringToInt(param1);
SetLocalInt(oPC, "PRC_PowerAttack_Level", paAmount);
ExecuteScript("prc_nui_pa_trggr", oPC);
// update the NUI so it is in sync
int nToken = NuiFindWindow(oPC, NUI_PRC_POWER_ATTACK_WINDOW);
if (nToken != 0)
{
NuiSetBind(oPC, nToken, NUI_PRC_PA_TEXT_BIND, JsonString(IntToString(paAmount)));
}
}
else
{
// if no param is given then open the NUI
ExecuteScript("prc_nui_pa_view", oPC);
}
// clear message from chat
SetPCChatMessage();
}
// If the first word is /sb then we open the Spellbook NUI
if(firstWord == "/sb")
{
ExecuteScript("prc_nui_sb_view", oPC);
// clear message from chat
SetPCChatMessage();
}
}
// Execute scripts hooked to this event for the player triggering it
ExecuteAllScriptsHookedToEvent(oPC, EVENT_ONPLAYERCHAT);
}

View File

@@ -0,0 +1,37 @@
//::///////////////////////////////////////////////
//:: NUI Events
//:: prc_onplayernui (hp_nui_events)
//:://////////////////////////////////////////////
/*
This handles any NUI events and sends them to
appropriate NUI Event handler depending on the
window Id
*/
//:://////////////////////////////////////////////
//:: Created By: Rakiov
//:: Created On: 22.05.2005
//:://////////////////////////////////////////////
#include "prc_nui_consts"
void main()
{
object oPlayer = NuiGetEventPlayer();
int nToken = NuiGetEventWindow();
string sWindowId = NuiGetWindowId(oPlayer, nToken);
// Open the Power Attack NUI
if(sWindowId == NUI_PRC_POWER_ATTACK_WINDOW)
{
ExecuteScript("prc_nui_pa_event");
}
// Open the Spellbook NUI
if(sWindowId == PRC_SPELLBOOK_NUI_WINDOW_ID
|| sWindowId == NUI_SPELL_DESCRIPTION_WINDOW_ID)
{
ExecuteScript("prc_nui_sb_event");
}
return;
}

View File

@@ -1,43 +1,101 @@
//::
//:: prc_onplaytarget.nss
//::
//::
//::///////////////////////////////////////////////
//:: PRC Spellbook OnTrigger Event
//:: prc_onplaytarget
//:://////////////////////////////////////////////
/*
This is the OnTarget event used set up spell
attacks with the selected spell from the PRC
Spellbook NUI
*/
//:://////////////////////////////////////////////
//:: Updated By: Rakiov
//:: Created On: 24.05.2005
//:://////////////////////////////////////////////
#include "prc_inc_skills"
#include "prc_nui_consts"
void DoJump(object oPC, location lTarget, int bDoKnockdown);
//
// DoSpellbookAction
// This is a OnTarget event action handling the use of the NUI Spellbook's spell.
// All this should do is take the manual targeting information and send it to the
// prc_nui_sb_trggr to handle the use of the spell.
//
// Arguments:
// oPC:object the player executing the action
// oTarget:object the object target of the spell
// lTarget:location the location the spell is being cast at.
//
void DoSpellbookAction(object oPC, object oTarget, location lTarget);
//
// ClearEventVariables
// Clears all the event variables used by the NUI Spellbook that coordinates with
// the OnTarget script to make sure it doesn't leave weird behavior for the next run.
//
// Arguments:
// oPC:object the player we are removing the info from.
//
void ClearEventVariables(object oPC);
void DoJump(object oPC, location lTarget, int bDoKnockdown)
{
object oTarget;
location lSource = GetLocation(oPC);
vector vSource = GetPositionFromLocation(lSource);
float fDistance = GetDistanceBetweenLocations(lTarget, lSource);
string sMessage = "You cannot jump through a closed door.";
oTarget = GetFirstObjectInShape(SHAPE_SPELLCYLINDER, fDistance, lTarget, TRUE, OBJECT_TYPE_DOOR, vSource);
object oTarget;
//:: Check if the first object found is a door.
while (oTarget != OBJECT_INVALID)
{
//:: Check if the door is closed.
if (!GetIsOpen(oTarget))
{
FloatingTextStringOnCreature(sMessage, oPC, FALSE);
DeleteLocalLocation(oPC, "TARGETING_POSITION");
return;
}
location lSource = GetLocation(oPC);
vector vSource = GetPositionFromLocation(lSource);
float fDistance = GetDistanceBetweenLocations(lTarget, lSource);
//:: Select the next target within the spell shape.
oTarget = GetNextObjectInShape(SHAPE_SPELLCYLINDER, fDistance, lTarget, TRUE, OBJECT_TYPE_DOOR,vSource);
}
PerformJump(oPC, lTarget, TRUE);
DeleteLocalLocation(oPC, "TARGETING_POSITION");
string sMessage = "You cannot jump through a closed door.";
oTarget = GetFirstObjectInShape(SHAPE_SPELLCYLINDER, fDistance, lTarget, TRUE, OBJECT_TYPE_DOOR, vSource);
//:: Check if the first object found is a door.
while (oTarget != OBJECT_INVALID)
{
//:: Check if the door is closed.
if (!GetIsOpen(oTarget))
{
FloatingTextStringOnCreature(sMessage, oPC, FALSE);
DeleteLocalLocation(oPC, "TARGETING_POSITION");
return;
}
//:: Select the next target within the spell shape.
oTarget = GetNextObjectInShape(SHAPE_SPELLCYLINDER, fDistance, lTarget, TRUE, OBJECT_TYPE_DOOR,vSource);
}
PerformJump(oPC, lTarget, TRUE);
DeleteLocalLocation(oPC, "TARGETING_POSITION");
}
void DoSpellbookAction(object oPC, object oTarget, location lTarget)
{
object currentTarget = oTarget;
if (GetIsObjectValid(currentTarget))
{
SetLocalObject(oPC, "TARGETING_OBJECT", currentTarget);
}
else
{
SetLocalLocation(oPC, "TARGETING_POSITION", lTarget);
}
ExecuteScript("prc_nui_sb_trggr", oPC);
ClearEventVariables(oPC);
}
void ClearEventVariables(object oPC)
{
DeleteLocalObject(oPC, "TARGETING_OBJECT");
DeleteLocalLocation(oPC, "TARGETING_POSITION");
DeleteLocalString(oPC, "ONPLAYERTARGET_ACTION");
DeleteLocalInt(oPC, NUI_SPELLBOOK_ON_TARGET_IS_PERSONAL_FEAT);
DeleteLocalInt(oPC, NUI_SPELLBOOK_SELECTED_SUBSPELL_SPELLID_VAR);
}
void main()
@@ -45,57 +103,69 @@ void main()
// Get the last player to use targeting mode
object oPC = GetLastPlayerToSelectTarget();
string sAction = GetLocalString(oPC, "ONPLAYERTARGET_ACTION");
string sAction = GetLocalString(oPC, "ONPLAYERTARGET_ACTION");
// Get the targeting mode data
object oTarget = GetTargetingModeSelectedObject();
vector vTarget = GetTargetingModeSelectedPosition();
float fOrientation = GetFacing(oPC);
object oTarget = GetTargetingModeSelectedObject();
vector vTarget = GetTargetingModeSelectedPosition();
float fOrientation = GetFacing(oPC);
// If the user manually exited targeting mode without selecting a target, return
// we also want to clear any existing targeting information we are sending to the script
// so clear all event variables.
if (!GetIsObjectValid(oTarget) && vTarget == Vector())
{
ClearEventVariables(oPC);
return;
}
// Save the targeting data to the PC object for later use
location lTarget = Location(GetArea(oTarget), vTarget, fOrientation);
SetLocalObject(oPC, "TARGETING_OBJECT", oTarget);
SetLocalLocation(oPC, "TARGETING_POSITION", lTarget);
if (sAction == "PRC_JUMP")
{
AssignCommand(oPC, SetFacingPoint(vTarget));
DelayCommand(0.0f, DoJump(oPC, lTarget, TRUE));
}
if (sAction == "PRC_JUMP")
{
AssignCommand(oPC, SetFacingPoint(vTarget));
DelayCommand(0.0f, DoJump(oPC, lTarget, TRUE));
}
// this is being called by the NUI Spellbook, perform the spell action
if (sAction == "PRC_NUI_SPELLBOOK")
{
DoSpellbookAction(oPC, oTarget, lTarget);
}
}
/* object oTarget;
location lTarget = GetLocalLocation(oPC, "TARGETING_POSITION");
location lSource = GetLocation(oPC);
float fDistance = GetDistanceBetweenLocations(lTarget, lSource);
/* object oTarget;
string sMessage = "You cannot jump through a closed door.";
oTarget = GetFirstObjectInShape(SHAPE_SPELLCYLINDER, fDistance, lTarget, TRUE, OBJECT_TYPE_DOOR);
location lTarget = GetLocalLocation(oPC, "TARGETING_POSITION");
location lSource = GetLocation(oPC);
float fDistance = GetDistanceBetweenLocations(lTarget, lSource);
// Check if the first object found is a door.
while (GetIsObjectValid(oTarget))
{
// Check if the door is closed.
if (!GetIsOpen(oTarget))
{
SpeakString(sMessage);
break;
}
string sMessage = "You cannot jump through a closed door.";
oTarget = GetFirstObjectInShape(SHAPE_SPELLCYLINDER, fDistance, lTarget, TRUE, OBJECT_TYPE_DOOR);
// Check if the first object found is a door.
while (GetIsObjectValid(oTarget))
{
// Check if the door is closed.
if (!GetIsOpen(oTarget))
{
SpeakString(sMessage);
break;
}
//Select the next target within the spell shape.
oTarget = GetNextObjectInShape(SHAPE_SPELLCYLINDER, fDistance, lTarget, TRUE, OBJECT_TYPE_DOOR);
}
//location lTarget = PRCGetSpellTargetLocation();
}
//location lTarget = PRCGetSpellTargetLocation();
//PerformJump(oPC, lLoc, TRUE));
DelayCommand(0.0f, DoJump(oPC, lTarget, TRUE)); */
DelayCommand(0.0f, DoJump(oPC, lTarget, TRUE)); */