2025/09/06 Update

Fixed damaged baseitems.2da
Updated PEPS.
Full compile.
This commit is contained in:
Jaysyn904
2025-09-06 12:13:11 -04:00
parent c5e44a075b
commit 41bbc115c1
193 changed files with 104993 additions and 2164 deletions

View File

@@ -10,9 +10,6 @@ void main()
{
object oHenchman = OBJECT_SELF;
int nSpell = StringToInt (GetScriptParam ("nSpell"));
// Save the original form so we can check when we turn back (Add 1 so we don't save a 0!).
SetLocalInt (oHenchman, AI_NORMAL_FORM, GetAppearanceType (oHenchman) + 1);
SetLocalString (oHenchman, AI_COMBAT_SCRIPT, "ai_a_polymorphed");
ActionCastSpellAtObject (nSpell, oHenchman, 255, TRUE);
}

View File

@@ -68,7 +68,7 @@ int StartingConditional()
{
string sHealingIn = IntToString(GetLocalInt(oAssociate, AI_HEAL_IN_COMBAT_LIMIT)) + "%";
string sHealingOut = IntToString(GetLocalInt(oAssociate, AI_HEAL_OUT_OF_COMBAT_LIMIT)) + "%";
SetCustomToken(AI_BASE_CUSTOM_TOKEN + 5, "I'm healing our allies if they go below " +
SetCustomToken(AI_BASE_CUSTOM_TOKEN + 4, "I'm healing our allies if they go below " +
sHealingIn + " health in combat and " + sHealingOut + " out of combat.");
}
else if(sParam == "Spells")

View File

@@ -10,8 +10,7 @@ void main()
{
object oCreature = OBJECT_SELF;
// Added code to allow for permanent associates in the battle!
if(AI_DEBUG) ai_Debug("0e_ch_7_ondeath", "13", GetName(oCreature) + " has died!" +
" AI_RULE_PERM_ASSOC: " + IntToString(GetLocalInt(GetModule(), AI_RULE_PERM_ASSOC)));
if(AI_DEBUG) ai_Debug("0e_ch_7_ondeath", "13", GetName(oCreature) + " has died!");
object oModule = GetModule();
if(GetLocalInt(oModule, AI_RULE_PERM_ASSOC))
{
@@ -22,6 +21,7 @@ void main()
oAssociate = GetAssociate(nIndex, oCreature);
if(oAssociate != OBJECT_INVALID)
{
if(AI_DEBUG) ai_Debug("0e_ch_7_ondeath", "24", GetName(oAssociate) + " being set to permanent!");
SetIsDestroyable(FALSE, FALSE, FALSE, oAssociate);
DelayCommand(0.1, ChangeToStandardFaction(oAssociate, STANDARD_FACTION_HOSTILE));
DelayCommand(3.0, SetIsDestroyable(TRUE, FALSE, FALSE, oAssociate));
@@ -31,12 +31,15 @@ void main()
// Remove the widget!
object oPC = GetMaster(oCreature);
if(oPC != OBJECT_INVALID)
{
{
if(AI_DEBUG) ai_Debug("0e_ch_7_ondeath", "35", GetName(oPC) + " Removing associates widget!");
NuiDestroy(oPC, NuiFindWindow(oPC, ai_GetAssociateType(oPC, oCreature) + AI_WIDGET_NUI));
DelayCommand(0.5, ai_CheckXPPartyScale(oCreature));
DelayCommand(2.0, ai_ClearCreatureActions(TRUE));
}
DelayCommand(2.0, ai_ClearCombatState(oCreature));
ExecuteScript(GetLocalString(oCreature, "AI_ON_DEATH"));
ChangeToStandardFaction(oCreature, STANDARD_FACTION_DEFENDER);
if(AI_DEBUG) ai_Debug("0e_ch_7_ondeath", "42", "Execute second OnDeath script: " + GetLocalString(oCreature, "AI_ON_DEATH"));
ExecuteScript(GetLocalString(oCreature, "AI_ON_DEATH"), oCreature);
}

View File

@@ -8,6 +8,7 @@
#include "nw_inc_gff"
#include "x0_i0_assoc"
#include "0i_menus"
#include "0i_module"
#include "0i_player_target"
// Save a window ID to the database.
void ai_SaveWindowLocation(object oPC, int nToken, string sAssociateType, string sWindowID);
@@ -32,10 +33,6 @@ void ai_RulePercDistInc(object oPC, object oModule, int nIncrement, int nToken);
// Adds a spell to a json AI restricted spell list then returns jRules.
// bRestrict = TRUE will add to the list FALSE will remove it from the list.
json ai_AddRestrictedSpell(json jRules, int nSpell, int bRestrict = TRUE);
// Turns on oAssociate AI, Setting all event scripts.
void ai_TurnOn(object oPC, object oAssociate, string sAssociateType);
// Turns off oAssociate AI, Setting all event scripts.
void ai_TurnOff(object oPC, object oAssociate, string sAssociateType);
// Adds a henchman back into the players party.
object ai_AddHenchman(object oPC, json jHenchman, location lLocation, int nFamiliar, int nCompanion);
@@ -94,10 +91,20 @@ void main()
json jData = NuiGetUserData(oPC, nToken);
object oAssociate = StringToObject(JsonGetString(JsonArrayGet(jData, 0)));
string sAssociateType = ai_GetAssociateType(oPC, oAssociate);
if(ai_GetIsDungeonMaster(oPC))
{
if(!NuiFindWindow(oPC, "dm" + AI_WIDGET_NUI))
{
ai_SendMessages(GetName(oPC) + " is now a Dungeon Master! Loading Dungeon Master widget.", AI_COLOR_YELLOW, oPC);
ai_CheckDMStart(oPC);
}
DelayCommand(0.0, NuiDestroy(oPC, nToken));
return;
}
if(!ai_GetIsCharacter(oAssociate) && !GetLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE") &&
(oAssociate == OBJECT_INVALID || GetMaster(oAssociate) != oPC))
{
ai_SendMessages("This creature is no longer in your party!", AI_COLOR_RED, oPC);
ai_SendMessages(GetName(oAssociate) + " is no longer in your party!", AI_COLOR_RED, oPC);
DelayCommand(0.0, NuiDestroy(oPC, nToken));
return;
}
@@ -196,57 +203,6 @@ void main()
aiSaveAssociateModesToDb(oPC, oPC);
}
}
else if(sElem == "btn_toggle_assoc_widget")
{
int bWidgetOff = !ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oPC, "pc");
string sAssocType;
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oPC, "pc", bWidgetOff);
object oAssoc = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
oAssoc = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
oAssoc = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
oAssoc = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
int nIndex;
object oHenchman;
for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++)
{
oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex);
if(oHenchman != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oHenchman);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oHenchman, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oHenchman);
}
}
}
else if(sElem == "btn_effect_icon")
{
if(ai_GetMagicMode(oPC, AI_MAGIC_EFFECT_ICON_REPORT))
@@ -579,6 +535,60 @@ void main()
else if(sElem == "btn_familiar_name") ai_SetCompanionName(oPC, oAssociate, nToken, ASSOCIATE_TYPE_FAMILIAR);
else if(sElem == "btn_companion_name") ai_SetCompanionName(oPC, oAssociate, nToken, ASSOCIATE_TYPE_ANIMALCOMPANION);
else if(GetStringLeft(sElem, 11) == "btn_plugin_") ai_Plugin_Execute(oPC, sElem);
else if(sElem == "btn_toggle_assoc_widget")
{
int bWidgetOff = !ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oPC, "pc");
string sAssocType, sText;
if(bWidgetOff) sText = " Associate Widgets [Off]";
else sText = " Associate Widgets [On]";
ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_toggle_assoc_widget_tooltip", sText);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oPC, "pc", bWidgetOff);
object oAssoc = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
oAssoc = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
oAssoc = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
oAssoc = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
int nIndex;
object oHenchman;
for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++)
{
oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex);
if(oHenchman != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oHenchman);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oHenchman, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oHenchman);
}
}
}
}
else if(sEvent == "watch")
{
@@ -597,10 +607,14 @@ void main()
jPlugin = JsonArraySet(jPlugin, 1, JsonBool(bCheck));
jPlugins = JsonArraySet(jPlugins, nIndex, jPlugin);
ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins);
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC));
if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate)
{
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC));
}
}
else if(sElem == "chbx_buff_rest_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_BUFF_REST, oAssociate, sAssociateType, nToken, sElem);
else if(sElem == "chbx_toggle_assoc_widget_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_ASSOC_WIDGETS_OFF, oAssociate, sAssociateType, nToken, sElem);
else if(sElem == "chbx_cmd_action_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_ACTION, oAssociate, sAssociateType, nToken, sElem);
else if(sElem == "chbx_cmd_guard_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_GUARD, oAssociate, sAssociateType, nToken, sElem);
else if(sElem == "chbx_cmd_hold_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_HOLD, oAssociate, sAssociateType, nToken, sElem);
@@ -623,8 +637,11 @@ void main()
else if(sElem == "chbx_companion_check") ai_SetWidgetButtonToCheckbox(oPC, BTN_CMD_COMPANION, oAssociate, sAssociateType, nToken, sElem);
else if(sElem == "cmb_familiar_selected") ai_SetCompanionType(oPC, oAssociate, nToken, ASSOCIATE_TYPE_FAMILIAR);
else if(sElem == "cmb_companion_selected") ai_SetCompanionType(oPC, oAssociate, nToken, ASSOCIATE_TYPE_ANIMALCOMPANION);
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate)
{
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
}
}
else if(sEvent == "mousescroll")
{
@@ -722,8 +739,11 @@ void main()
else if(sElem == "chbx_ignore_traps_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_IGNORE_TRAPS, oAssociate, sAssociateType, nToken, sElem);
else if(sElem == "chbx_perc_range_check") ai_SetAIButtonToCheckbox(oPC, BTN_AI_PERC_RANGE, oAssociate, sAssociateType, nToken, sElem);
else if(sElem == "cmb_ai_script_selected") ai_SetAIScript(oPC, oAssociate, nToken);
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate)
{
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, sAssociateType + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
}
}
else if(sEvent == "mousescroll")
{
@@ -863,6 +883,60 @@ void main()
else if(sElem == "btn_update_widget") ai_UpdateAssociateWidget(oPC, oAssociate);
else if(GetStringLeft(sElem, 15) == "btn_exe_plugin_") ai_Plugin_Execute(oPC, sElem);
else if(GetStringLeft(sElem, 11) == "btn_widget_") ai_SelectWidgetSpellTarget(oPC, oAssociate, sElem);
else if(sElem == "btn_toggle_assoc_widget")
{
int bWidgetOff = !ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oPC, "pc");
string sAssocType, sText;
if(bWidgetOff) sText = "Associate Widgets [Off]";
else sText = "Associate Widgets [On]";
ai_UpdateToolTipUI(oPC, sAssociateType + AI_COMMAND_NUI, sAssociateType + AI_WIDGET_NUI, "btn_toggle_assoc_widget_tooltip", sText);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oPC, "pc", bWidgetOff);
object oAssoc = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
oAssoc = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
oAssoc = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
oAssoc = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oPC);
if(oAssoc != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oAssoc);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oAssoc, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oAssoc);
}
int nIndex;
object oHenchman;
for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++)
{
oHenchman = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex);
if(oHenchman != OBJECT_INVALID)
{
sAssocType = ai_GetAssociateType(oPC, oHenchman);
ai_SetWidgetButton(oPC, BTN_WIDGET_OFF, oHenchman, sAssocType, bWidgetOff);
if(bWidgetOff) IsWindowClosed(oPC, sAssocType + AI_WIDGET_NUI);
else ai_CreateWidgetNUI(oPC, oHenchman);
}
}
}
}
if(sEvent == "mousescroll")
{
@@ -1209,8 +1283,11 @@ void main()
ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins);
DelayCommand(0.0, NuiDestroy(oPC, nToken));
DelayCommand(0.1, ai_CreatePluginNUI(oPC));
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC));
if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate)
{
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC));
}
}
if(sElem == "btn_clear_plugins")
{
@@ -1229,8 +1306,11 @@ void main()
ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins);
DelayCommand(0.0, NuiDestroy(oPC, nToken));
DelayCommand(0.1, ai_CreatePluginNUI(oPC));
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC));
if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate)
{
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC));
}
}
else if(sElem == "btn_add_plugin")
{
@@ -1249,8 +1329,11 @@ void main()
ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins);
DelayCommand(0.0, NuiDestroy(oPC, nToken));
DelayCommand(0.1, ai_CreatePluginNUI(oPC));
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC));
if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate)
{
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC));
}
}
else if(GetStringLeft(sElem, 11) == "btn_plugin_") ai_Plugin_Execute(oPC, sElem);
}
@@ -1265,8 +1348,11 @@ void main()
jPlugin = JsonArraySet(jPlugin, 1, JsonBool(bCheck));
jPlugins = JsonArraySet(jPlugins, nIndex, jPlugin);
ai_SetAssociateDbJson(oPC, "pc", "plugins", jPlugins);
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC));
if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate)
{
DelayCommand(0.0, NuiDestroy(oPC, NuiFindWindow(oPC, "pc" + AI_WIDGET_NUI)));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oPC));
}
}
}
return;
@@ -1348,11 +1434,14 @@ void main()
}
else if(sEvent == "close")
{
int nUIToken = NuiFindWindow(oPC, sAssociateType + AI_QUICK_WIDGET_NUI);
if(nUIToken)
if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate)
{
DelayCommand(0.0, NuiDestroy(oPC, nUIToken));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
int nUIToken = NuiFindWindow(oPC, sAssociateType + AI_QUICK_WIDGET_NUI);
if(nUIToken)
{
DelayCommand(0.0, NuiDestroy(oPC, nUIToken));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
}
}
}
return;
@@ -1435,11 +1524,14 @@ void main()
}
else if(sEvent == "close")
{
int nUIToken = NuiFindWindow(oPC, sAssociateType + AI_QUICK_WIDGET_NUI);
if(nUIToken)
if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate)
{
DelayCommand(0.0, NuiDestroy(oPC, nUIToken));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
int nUIToken = NuiFindWindow(oPC, sAssociateType + AI_QUICK_WIDGET_NUI);
if(nUIToken)
{
DelayCommand(0.0, NuiDestroy(oPC, nUIToken));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
}
}
}
return;
@@ -1615,6 +1707,7 @@ void main()
if(GetLocalInt(oAssociate, "AI_KNOWN_SPELL_CHANGE"))
{
RemoveHenchman(oPC, oAssociate);
ChangeToStandardFaction(oAssociate, STANDARD_FACTION_DEFENDER);
json jHenchman = ObjectToJson(oAssociate, TRUE);
json jClassList = GetLocalJson(oAssociate, AI_CLASS_LIST_JSON);
jHenchman = GffReplaceList(jHenchman, "ClassList", jClassList);
@@ -1627,8 +1720,12 @@ void main()
AssignCommand(oAssociate, SetIsDestroyable(TRUE, FALSE, FALSE));
DestroyObject(oAssociate);
oAssociate = ai_AddHenchman(oPC, jHenchman, lLocation, nFamiliar, nCompanion);
DeleteLocalJson(oAssociate, AI_CLASS_LIST_JSON);
DeleteLocalInt(oAssociate, "AI_KNOWN_SPELL_CHANGE");
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate)
{
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
}
}
}
return;
@@ -1698,7 +1795,11 @@ void ai_AddAssociate(object oPC, int nToken, json jAssociate, location lLocation
AddHenchman(oPC, oAssociate);
DeleteLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE");
DelayCommand(0.0, NuiDestroy(oPC, nToken));
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
string sAssociateType = ai_GetAssociateType(oPC, oAssociate);
if(!ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oAssociate, sAssociateType) || oPC == oAssociate)
{
DelayCommand(0.1, ai_CreateWidgetNUI(oPC, oAssociate));
}
if(nRange) SetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION, nRange);
if(nFamiliar) SummonFamiliar(oAssociate);
if(nCompanion) SummonAnimalCompanion(oAssociate);
@@ -1816,12 +1917,12 @@ void ai_Perc_Range(object oPC, object oAssociate, int nToken, string sAssociateT
SetLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE", TRUE);
int nBtnPercRange = GetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION + "_MENU");
string sText, sText2;
float fRange = 20.0;
float fRange = 25.0;
if(nBtnPercRange == 8)
{
sText = "short";
sText2 = " Perception Range Short [10 meters Sight / 10 meters Listen]";
fRange = 10.0;
fRange = 15.0;
}
else if(nBtnPercRange == 9)
{
@@ -1832,7 +1933,7 @@ void ai_Perc_Range(object oPC, object oAssociate, int nToken, string sAssociateT
{
sText = "long";
sText2 = " Perception Range Long [35 meters Sight / 20 meters Listen]";
fRange = 35.0;
fRange = 40.0;
}
else if(nBtnPercRange == 11)
{
@@ -1914,49 +2015,6 @@ json ai_AddRestrictedSpell(json jRules, int nSpell, int bRestrict = TRUE)
SetLocalJson(oModule, AI_RULE_RESTRICTED_SPELLS, jRSpells);
return JsonObjectSet(jRules, AI_RULE_RESTRICTED_SPELLS, jRSpells);
}
void ai_TurnOn(object oPC, object oTarget, string sAssociateType)
{
ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ai_tooltip", " AI On");
ai_SendMessages("AI turned on for " + GetName(oTarget) + ".", AI_COLOR_YELLOW, oPC);
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "xx_pc_1_hb");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_NOTICE, "xx_pc_2_percept");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "xx_pc_3_endround");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "xx_pc_4_convers");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "xx_pc_5_phyatked");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "xx_pc_6_damaged");
//SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DEATH, "");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "xx_pc_8_disturb");
//SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, "");
//SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_RESTED, "");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "xx_pc_b_castat");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "xx_pc_e_blocked");
//SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, "");
// This sets the script for the PC to run AI based on class.
ai_SetAssociateAIScript(oTarget, FALSE);
// Set so PC can hear associates talking in combat.
ai_SetListeningPatterns(oTarget);
}
void ai_TurnOff(object oPC, object oAssociate, string sAssociateType)
{
ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ai_tooltip", " AI Off");
ai_SendMessages("AI Turned off for " + GetName(oAssociate) + ".", AI_COLOR_YELLOW, oPC);
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_NOTICE, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "");
//SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DEATH, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "");
//SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, "");
//SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_RESTED, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "");
//SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, "");
DeleteLocalInt(oAssociate, "AI_I_AM_BEING_HEALED");
DeleteLocalString(oAssociate, "AIScript");
ai_ClearCreatureActions();
}
object ai_AddHenchman(object oPC, json jHenchman, location lLocation, int nFamiliar, int nCompanion)
{
jHenchman = GffReplaceResRef(jHenchman, "ScriptSpawn", "");

View File

@@ -5,6 +5,7 @@
Menu event script
sEvent: close, click, mousedown, mouseup, watch (if bindwatch is set).
/*//////////////////////////////////////////////////////////////////////////////
#include "0i_menus"
#include "0i_menus_dm"
void ai_SetDMWidgetButtonToCheckbox(object oDM, int nButton, int nToken, string sElem);
void ai_SetDMWAccessButtonToCheckbox(object oDM, int nButton, int nToken, string sElem);
@@ -32,6 +33,16 @@ void main()
// " nToken: " + IntToString(nToken) + " oPC: " + GetName(oPC));
//WriteTimestampedLogEntry("0e_nui, 58, sWndId: " + sWndId + " sEvent: " + sEvent + " sElem: " + sElem +
// " nToken: " + IntToString(nToken) + " oDM: " + GetName(oDM));
if(ai_GetIsCharacter(oDM))
{
if(!NuiFindWindow(oDM, "pc" + AI_WIDGET_NUI))
{
ai_SendMessages(GetName(oDM) + " is now a Player! Loading player widget.", AI_COLOR_YELLOW, oDM);
ai_CreateWidgetNUI(oDM, oDM);
}
DelayCommand(0.0, NuiDestroy(oDM, nToken));
return;
}
//**************************************************************************
string sName = ai_RemoveIllegalCharacters(GetName(oDM));
// Watch to see if the window moves and save.

View File

@@ -15,9 +15,5 @@ void main()
object oCreature = OBJECT_SELF;
// This can be moved to the OnClientLoad script event of your module.
if(ai_GetIsCharacter(oCreature)) ai_CheckPCStart(oCreature);
// If this is a server you can add this as well.
else if(AI_SERVER && (GetIsDM(oCreature) || GetIsPlayerDM(oCreature)))
{
ai_CheckPCStart(oCreature);
}
else if(ai_GetIsDungeonMaster(oCreature)) ai_CheckDMStart(oCreature);
}

View File

@@ -10,8 +10,17 @@
action of the target.
AI_TARGET_MODE is the constant used.
AI_TARGET_ASSOCIATE is the associate that triggered the target mode.
AI_TARGET_MODE_ON defines if the player is in target mode for a henchman instead of the PC.
/*//////////////////////////////////////////////////////////////////////////////
#include "0i_player_target"
void ai_EnterAssociateTargetMode(object oPC, object oAssociate)
{
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, oAssociate);
SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_ACTION");
SetLocalInt(oPC, AI_TARGET_MODE_ON, TRUE);
EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK);
}
void main()
{
object oPC = GetLastPlayerToSelectTarget();
@@ -47,6 +56,17 @@ void main()
else if(sTargetMode == "ASSOCIATE_ACTION")
{
ai_SendMessages("You have exited selecting an action for " + GetName(oAssociate) + ".", AI_COLOR_YELLOW, oPC);
// Clean up any PC AI being turned on as well as variables.
DeleteLocalObject(oPC, AI_TARGET_ASSOCIATE);
DeleteLocalInt(oPC, AI_TARGET_MODE_ON);
DeleteLocalObject(oPC, AI_TARGET_MODE_ASSOCIATE);
// Make sure the camera goes back to the player since we are leaving henchmen control.
if(GetLocalObject(oPC, "AI_CAMERA_ON_ASSOCIATE") != OBJECT_INVALID)
{
DeleteLocalObject(oPC, "AI_CAMERA_ON_ASSOCIATE");
AttachCamera(oPC, oPC);
if(!GetLocalInt(GetModule(), AI_USING_PRC)) ai_TurnOff(oPC, oPC, "pc");
}
if(ResManGetAliasFor("ai_a_default", RESTYPE_NCS) == "")
{
if(GetLocalInt(oPC, sGhostModeVarname))
@@ -71,16 +91,27 @@ void main()
else if(sTargetMode == "ASSOCIATE_GET_TRAP")
{
ai_SendMessages(GetName(oAssociate) + " has exited selecing a trap!", AI_COLOR_YELLOW, oPC);
if(GetLocalInt(oPC, AI_TARGET_MODE_ON)) ai_EnterAssociateTargetMode(oPC, GetLocalObject(oPC, AI_TARGET_MODE_ASSOCIATE));
}
else if(sTargetMode == "ASSOCIATE_PLACE_TRAP")
{
ai_SendMessages(GetName(oAssociate) + " has exited placing the trap!", AI_COLOR_YELLOW, oPC);
if(GetLocalInt(oPC, AI_TARGET_MODE_ON)) ai_EnterAssociateTargetMode(oPC, GetLocalObject(oPC, AI_TARGET_MODE_ASSOCIATE));
}
else if(sTargetMode == "DM_SELECT_CAMERA_VIEW")
{
AttachCamera(oPC, oPC);
ai_SendMessages(GetName(oPC) + " has defaulted camera view back to the player!", AI_COLOR_YELLOW, oPC);
}
// If these actions are canceled and we are in target mode with a henchmen
// then turn target mode back on for that henchmen.
else if(sTargetMode == "ASSOCIATE_USE_ITEM" ||
sTargetMode == "ASSOCIATE_USE_FEAT" ||
sTargetMode == "ASSOCIATE_CAST_SPELL" ||
sTargetMode == "ASSOCIATE_FOLLOW_TARGET")
{
if(GetLocalInt(oPC, AI_TARGET_MODE_ON)) ai_EnterAssociateTargetMode(oPC, GetLocalObject(oPC, AI_TARGET_MODE_ASSOCIATE));
}
return;
}
// ************************* Targeted Actions **************************
@@ -111,18 +142,21 @@ void main()
if(oTarget == GetArea(oPC)) oTarget = OBJECT_INVALID;
ai_UseWidgetItem(oPC, oAssociate, oTarget, lLocation);
DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate));
if(GetLocalInt(oPC, AI_TARGET_MODE_ON)) ai_EnterAssociateTargetMode(oPC, GetLocalObject(oPC, AI_TARGET_MODE_ASSOCIATE));
}
else if(sTargetMode == "ASSOCIATE_USE_FEAT")
{
if(oTarget == GetArea(oPC)) oTarget = OBJECT_INVALID;
ai_UseWidgetFeat(oPC, oAssociate, oTarget, lLocation);
DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate));
if(GetLocalInt(oPC, AI_TARGET_MODE_ON)) ai_EnterAssociateTargetMode(oPC, GetLocalObject(oPC, AI_TARGET_MODE_ASSOCIATE));
}
else if(sTargetMode == "ASSOCIATE_CAST_SPELL")
{
if(oTarget == GetArea(oPC)) oTarget = OBJECT_INVALID;
ai_CastWidgetSpell(oPC, oAssociate, oTarget, lLocation);
DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate));
if(GetLocalInt(oPC, AI_TARGET_MODE_ON)) ai_EnterAssociateTargetMode(oPC, GetLocalObject(oPC, AI_TARGET_MODE_ASSOCIATE));
}
else if(sTargetMode == "DM_SELECT_CAMERA_VIEW")
{
@@ -147,8 +181,7 @@ void main()
ai_DMAction(oPC, oTarget, lLocation, sTargetMode);
}
// Get saved module player target script and execute it for pass through compatibility.
string sModuleTargetScript = GetLocalString(GetModule(), AI_MODULE_TARGET_EVENT);
ExecuteScript(sModuleTargetScript);
ExecuteScript(GetLocalString(GetModule(), AI_MODULE_TARGET_EVENT));
}
}
}

View File

@@ -0,0 +1,317 @@
/*//////////////////////////////////////////////////////////////////////////////
// Script Name: 0e_prc_id_events
////////////////////////////////////////////////////////////////////////////////
Infinite Dungeons monster event handler while using the PRC.
*///////////////////////////////////////////////////////////////////////////////
#include "0i_actions"
#include "x0_i0_assoc"
// Followers special heartbeat script.
void ai_hen_id1_heart(object oCreature);
// Followers special conversation script.
void ai_hen_id1_convo(object oCreature, int nMatch);
// Followers special perception script.
void ai_hen_id1_percept(object oCreature);
// Followers special end of round script.
void ai_hen_id1_endcombat(object oCreature, int bFollower);
// Followers special castat script.
void ai_hen_id1_castat(object oCreature);
void main()
{
object oCreature = OBJECT_SELF;
int nEvent = GetCurrentlyRunningEvent();
int bFollower = GetLocalInt(oCreature, "bFollower");
switch (nEvent)
{
case EVENT_SCRIPT_CREATURE_ON_HEARTBEAT:
{
if(bFollower)
{
if(GetImmortal(oCreature)) SetImmortal(oCreature, FALSE);
ai_hen_id1_heart(oCreature);
}
else
{
ExecuteScript("nw_c2_default1", oCreature);
ExecuteScript("prc_npc_hb", oCreature);
}
break;
}
case EVENT_SCRIPT_CREATURE_ON_NOTICE:
{
if(bFollower) ai_hen_id1_percept(oCreature);
else
{
ExecuteScript("nw_c2_default2", oCreature);
ExecuteScript("prc_npc_percep", oCreature);
}
break;
}
case EVENT_SCRIPT_CREATURE_ON_DIALOGUE:
{
int nMatch = GetListenPatternNumber();
if(nMatch == -1)
{
if(ai_GetIsBusy(oCreature) || ai_Disabled(oCreature) ||
GetLocalInt(oCreature, AI_AM_I_SEARCHING)) return;
ai_ClearCreatureActions();
string sConversation = GetLocalString(oCreature, "sConversation");
if(sConversation != "") BeginConversation(sConversation);
else BeginConversation();
}
if(bFollower) ai_hen_id1_convo(oCreature, nMatch);
else
{
//ExecuteScript("nw_c2_default4", oCreature);
ExecuteScript("prc_npc_conv", oCreature);
}
break;
}
case EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED:
{
if(bFollower) ExecuteScript("nw_ch_ac5", oCreature);
else
{
ExecuteScript("nw_c2_default5", oCreature);
ExecuteScript("prc_npc_physatt", oCreature);
}
break;
}
case EVENT_SCRIPT_CREATURE_ON_DAMAGED:
{
if(bFollower) ExecuteScript("nw_ch_ac6", oCreature);
else
{
ExecuteScript("nw_c2_default6", oCreature);
ExecuteScript("prc_npc_damaged", oCreature);
}
break;
}
case EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT:
{
if(bFollower) ai_hen_id1_castat(oCreature);
else
{
ExecuteScript("nw_c2_defaultb", oCreature);
ExecuteScript("prc_npc_spellat", oCreature);
}
break;
}
case EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND:
{
if(bFollower) ai_hen_id1_endcombat(oCreature, bFollower);
else
{
ExecuteScript("nw_c2_default3", oCreature);
ExecuteScript("prc_npc_combat", oCreature);
}
break;
}
case EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR:
{
if(bFollower) ExecuteScript("nw_ch_ace", oCreature);
else
{
ExecuteScript("nw_c2_defaulte", oCreature);
ExecuteScript("prc_npc_blocked", oCreature);
}
break;
}
case EVENT_SCRIPT_CREATURE_ON_RESTED:
{
if(bFollower) ExecuteScript("nw_ch_aca", oCreature);
else ExecuteScript("prc_npc_rested", oCreature);
break;
}
case EVENT_SCRIPT_CREATURE_ON_DISTURBED:
{
if(bFollower) ExecuteScript("nw_ch_ac8", oCreature);
else
{
ExecuteScript("nw_c2_default8", oCreature);
ExecuteScript("prc_npc_disturb", oCreature);
}
break;
}
case EVENT_SCRIPT_CREATURE_ON_DEATH:
{
if(bFollower) ExecuteScript("nw_ch_ac7", oCreature);
else
{
ExecuteScript("nw_c2_default7", oCreature);
}
break;
}
}
}
void ai_hen_id1_heart(object oCreature)
{
// Sometimes they slip out of this mode!
if(GetAssociateState(NW_ASC_MODE_DYING, oCreature) &&
GetCommandable())
{
ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT, 1.0, 65.0);
SetCommandable(FALSE);
}
ExecuteScript("nw_ch_ac1", oCreature);
}
void ai_hen_id1_convo(object oCreature, int nMatch)
{
if(nMatch == ASSOCIATE_COMMAND_INVENTORY)
{
// * cannot modify disabled equipment
if(!GetLocalInt(OBJECT_SELF, "X2_JUST_A_DISABLEEQUIP"))
{
OpenInventory(oCreature, GetLastSpeaker());
}
// * feedback as to why
else SendMessageToPCByStrRef(GetMaster(), 100895);
return;
}
else if(nMatch == ASSOCIATE_COMMAND_LEAVEPARTY)
{
object oMaster = GetMaster();
string sTag = GetTag(GetArea(oMaster));
// * henchman cannot be kicked out in the reaper realm
// * Followers can never be kicked out
if (sTag == "GatesofCania" || GetIsFollower(oCreature)) return;
if(GetIsObjectValid(oMaster))
{
ai_ClearCreatureActions();
if(GetAssociateType(oCreature) == ASSOCIATE_TYPE_HENCHMAN)
{
string sConversation = GetLocalString(oCreature, "sConversation");
if (sConversation == "id1_plotgiver")
{
string sVariable = GetLocalString(oCreature, "sVariable");
object oDungeon = GetLocalObject(GetModule(), "oCurrentDungeon");
SetLocalInt(oDungeon, "b" + sVariable + "Gone", FALSE);
}
RemoveHenchman(oMaster);
DestroyObject(oCreature);
}
}
return;
}
ExecuteScript("nw_ch_ac4", oCreature);
}
void ai_hen_id1_percept(object oCreature)
{
// If henchman is dying and Player disappears then force a respawn of the henchman
if (GetIsHenchmanDying(oCreature))
{
// The henchman must be removed otherwise their corpse will follow the player
object oOldMaster = GetMaster();
object oPC = GetLastPerceived();
int bVanish = GetLastPerceptionVanished();
if(GetIsObjectValid(oPC) && bVanish)
{
if (oPC == oOldMaster)
{
RemoveHenchman(oPC, oCreature);
// Only in chapter 1
if(GetTag(GetModule()) == "x0_module1")
{
SetCommandable(TRUE);
DoRespawn(oPC, oCreature); // Should teleport henchman back
}
}
}
}
ExecuteScript("nw_ch_ac2", oCreature);
}
void ai_hen_id1_endcombat(object oCreature, int bFollower)
{
if (ai_GetIsInCombat(oCreature))
{
int nNum;
int nLine;
string sString;
int nCreature;
int bIntelligent;
int nRandom = d100();
// chance of a oneliner
int nOnelinerPercentage = GetLocalInt(GetModule(), "nFlagCombatOneLinerFrequencyValue");
if(nRandom <= nOnelinerPercentage)
{
string sCreature = GetLocalString(oCreature, "sVariable");
// if the current creature is hostile towards PCs
if(sCreature != "")
{
object oDungeon = GetLocalObject(GetModule(), "oCurrentDungeon");
if(GetIsReactionTypeHostile(GetFirstPC()))
{
nCreature = GetLocalInt(oDungeon, "n" + sCreature);
bIntelligent = GetLocalInt(oDungeon, "bListCreature" + IntToString(nCreature) + "Intelligent");
if(bIntelligent)
{
nNum = GetLocalInt(GetModule(), "nLinesHostileNum");
nLine = Random(nNum) + 1;
if(nLine > 0)
{
sString = GetLocalString(GetModule(), "sLinesHostile" + IntToString(nLine));
SpeakString(sString, TALKVOLUME_SHOUT);
}
}
}
else
{
nCreature = GetLocalInt(oDungeon, "n" + sCreature);
bIntelligent = GetLocalInt(oDungeon, "bListCreature" + IntToString(nCreature) + "Intelligent");
if(bIntelligent)
{
nNum = GetLocalInt(GetModule(), "nLinesAlliesNum");
nLine = Random(nNum) + 1;
if (nLine > 0)
{
sString = GetLocalString(GetModule(), "sLinesAllies" + IntToString(nLine));
SpeakString(sString, TALKVOLUME_SHOUT);
}
}
}
}
}
}
if(bFollower) ExecuteScript("nw_ch_ac3", oCreature);
else ExecuteScript("nw_c2_default3", oCreature);
}
void ai_hen_id1_castat(object oCreature)
{
if(!GetLastSpellHarmful())
{
int nSpell = GetLastSpell();
if(nSpell == SPELL_RAISE_DEAD || nSpell == SPELL_RESURRECTION)
{
object oCaster = GetLastSpellCaster();
// Restore merchant faction to neutral
SetStandardFactionReputation(STANDARD_FACTION_MERCHANT, 100, oCaster);
SetStandardFactionReputation(STANDARD_FACTION_COMMONER, 100, oCaster);
SetStandardFactionReputation(STANDARD_FACTION_DEFENDER, 100, oCaster);
ClearPersonalReputation(oCaster, oCreature);
AssignCommand(oCreature, SurrenderToEnemies());
AssignCommand(oCreature, ai_ClearCreatureActions(TRUE));
// Reset henchmen attack state - Oct 28 (BK)
ai_SetAIMode(oCreature, AI_MODE_DEFEND_MASTER, FALSE);
ai_SetAIMode(oCreature, AI_MODE_STAND_GROUND, FALSE);
ai_SetAIMode(oCreature, AI_MODE_SCOUT_AHEAD, FALSE);
ai_SetAIMode(oCreature, AI_MODE_SCOUT_AHEAD, FALSE);
ai_SetAIMode(oCreature, AI_MODE_COMMANDED, FALSE);
// Oct 30 - If player previously hired this hench
// then just have them rejoin automatically
if(GetPlayerHasHired(oCaster, oCreature))
{
// Feb 11, 2004 - Jon: Don't fire the HireHenchman function if the
// henchman is already oCaster's associate. Fixes a silly little problem
// that occured when you try to raise a henchman who wasn't actually dead.
if(GetMaster(oCreature)!= oCaster) HireHenchman(oCaster, oCreature, TRUE);
}
else
{
string sFile = GetDialogFileToUse(oCaster);
AssignCommand(oCaster, ActionStartConversation(oCreature, sFile));
}
}
}
ExecuteScript("nw_ch_acb", oCreature);
}

View File

@@ -152,6 +152,8 @@ void ai_AmbientAnimations();
void ai_DoAssociateCombatRound(object oCreature, object oTarget = OBJECT_INVALID)
{
object oMaster = GetMaster(oCreature);
if(GetLocalInt(oMaster, AI_TARGET_MODE_ON) && GetLocalObject(oMaster, AI_TARGET_MODE_ASSOCIATE) == oCreature) return;
if(ai_StayClose(oCreature)) return;
// Is the target our Player has locked in dead? If so then clear it.
if(GetIsDead(GetLocalObject(oCreature, AI_PC_LOCKED_TARGET))) DeleteLocalObject(oCreature, AI_PC_LOCKED_TARGET);
@@ -176,21 +178,27 @@ void ai_DoAssociateCombatRound(object oCreature, object oTarget = OBJECT_INVALID
// the polymorph AI script.
if(sAI != "ai_coward" && sAI != "ai_a_peaceful")
{
if(AI_DEBUG) ai_Debug("0i_actions", "173", "Should we use polymorph? " +
IntToString(GetAppearanceType(oCreature) != ai_GetNormalAppearance(oCreature)));
if(AI_DEBUG)
{
ai_Debug("0i_actions", "181", "Should we use polymorph? Current: " +
IntToString(GetAppearanceType(oCreature)) + " Normal: " + IntToString(ai_GetNormalAppearance(oCreature)));
if(ai_GetIsHidden(oCreature))
{
ai_Debug("0i_actions", "179", "We are hidden!" +
ai_Debug("0i_actions", "185", "We are hidden!" +
" Can they see us? " + IntToString(ai_GetNearestIndexThatSeesUs(oCreature)));
}
}
if(GetAppearanceType(oCreature) != ai_GetNormalAppearance(oCreature))
if(ai_GetIsHidden(oCreature) && !ai_GetNearestIndexThatSeesUs(oCreature)) sAI = "ai_a_invisible";
else if(GetAppearanceType(oCreature) != ai_GetNormalAppearance(oCreature))
{
sAI = "ai_a_polymorphed";
if(!GetLocalInt(oCreature, AI_POLYMORPHED))
{
SetLocalInt(oCreature, AI_POLYMORPHED, TRUE);
ai_ClearTalents(oCreature);
ai_SetCreatureSpecialAbilityTalents(oCreature, FALSE, TRUE);
}
}
else if(ai_GetIsHidden(oCreature) && !ai_GetNearestIndexThatSeesUs(oCreature)) sAI = "ai_a_invisible";
}
if(sAI == "") sAI = "ai_a_default";
if(AI_DEBUG) ai_Debug("0i_actions", "190", "********** " + GetName (oCreature) + " **********");
@@ -226,11 +234,24 @@ void ai_DoMonsterCombatRound(object oMonster)
string sAI = GetLocalString(oMonster, AI_COMBAT_SCRIPT);
if(sAI != "ai_coward")
{
if(GetAppearanceType(oMonster) != ai_GetNormalAppearance(oMonster))
if(AI_DEBUG) ai_Debug("0i_actions", "235", "Should we use polymorph? Current: " +
IntToString(GetAppearanceType(oMonster)) + " Normal: " + IntToString(ai_GetNormalAppearance(oMonster)));
if(ai_GetIsHidden(oMonster))
{
if(AI_DEBUG) ai_Debug("0i_actions", "239", "We are hidden!" +
" Can they see us? " + IntToString(ai_GetNearestIndexThatSeesUs(oMonster)));
}
if(ai_GetIsHidden(oMonster) && !ai_GetNearestIndexThatSeesUs(oMonster)) sAI = "ai_invisible";
else if(GetAppearanceType(oMonster) != ai_GetNormalAppearance(oMonster))
{
sAI = "ai_polymorphed";
if(!GetLocalInt(oMonster, AI_POLYMORPHED))
{
SetLocalInt(oMonster, AI_POLYMORPHED, TRUE);
ai_ClearTalents(oMonster);
ai_SetCreatureSpecialAbilityTalents(oMonster, TRUE, TRUE);
}
}
else if(ai_GetIsHidden(oMonster) && !ai_GetNearestIndexThatSeesUs(oMonster)) sAI = "ai_invisible";
}
if(sAI == "") sAI = "ai_default";
if(AI_DEBUG) ai_Debug("0i_actions", "230", "********** " + GetName (oMonster) + " **********");
@@ -277,7 +298,7 @@ int ai_StayClose(object oCreature)
if(fPerceptionDistance == 0.0)
{
fPerceptionDistance = GetLocalFloat(oMaster, AI_ASSOC_PERCEPTION_DISTANCE);
if(fPerceptionDistance == 0.0) fPerceptionDistance = 20.0;
if(fPerceptionDistance == 0.0) fPerceptionDistance = 25.0;
}
object oTarget = GetLocalObject(oCreature, AI_FOLLOW_TARGET);
if(oTarget == OBJECT_INVALID) oTarget = oMaster;
@@ -521,11 +542,11 @@ int ai_MoralCheck(object oCreature)
if(nHpPercent <= AI_HEALTH_WOUNDED)
{
// Debug code to look for multiple moral checks at once by one creature?
if(GetLocalString(GetModule(), AI_RULE_DEBUG_CREATURE) == "")
{
SetLocalString(GetModule(), AI_RULE_DEBUG_CREATURE, GetName(oCreature));
ai_Debug("0i_actions", "424", GetName(oCreature) + " starting debug mode to test Moral checks!");
}
//if(GetLocalString(GetModule(), AI_RULE_DEBUG_CREATURE) == "")
//{
// SetLocalString(GetModule(), AI_RULE_DEBUG_CREATURE, GetName(oCreature));
// ai_Debug("0i_actions", "424", GetName(oCreature) + " starting debug mode to test Moral checks!");
//}
if(nHpPercent <= AI_HEALTH_BLOODY) nDC = AI_BLOODY_MORAL_DC;
else nDC = AI_WOUNDED_MORAL_DC;
nDC = nDC - GetLocalInt(oCreature, AI_ALLY_NUMBERS);
@@ -681,17 +702,17 @@ void ai_DoPhysicalAttackOnBest(object oCreature, int nInMelee, int bAlwaysAtk =
{
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
}
else
{
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
if(AI_DEBUG) ai_Debug("0i_actions", "519", "Do ranged attack against nearest: " + GetName(oTarget) + "!");
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
@@ -739,17 +760,17 @@ void ai_DoPhysicalAttackOnNearest(object oCreature, int nInMelee, int bAlwaysAtk
{
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestPhysicalTarget(oCreature);
}
else
{
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
if(AI_DEBUG) ai_Debug("0i_actions", "519", "Do ranged attack against nearest: " + GetName(oTarget) + "!");
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
@@ -796,17 +817,17 @@ void ai_DoPhysicalAttackOnLowestCR(object oCreature, int nInMelee, int bAlwaysAt
{
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
}
else
{
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
if(AI_DEBUG) ai_Debug("0i_actions", "559", GetName(OBJECT_SELF) + " does ranged attack on weakest: " + GetName(oTarget) + "!");
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
@@ -1112,7 +1133,7 @@ void ai_ActionTryHealing(object oCreature, object oTarget)
}
int ai_TryHealing(object oCreature, object oTarget, int bForce = FALSE)
{
if(AI_DEBUG) ai_Debug("0i_actions", "733", "Try healing: oCreature: " + GetName(oCreature) +
if(AI_DEBUG) ai_Debug("0i_actions", "1136", "Try healing: oCreature: " + GetName(oCreature) +
" oTarget: " + GetName(oTarget) + " No Party Healing: " + IntToString(ai_GetAIMode(oCreature, AI_MODE_PARTY_HEALING_OFF)) +
" No Self Healing: " + IntToString(ai_GetAIMode(oCreature, AI_MODE_SELF_HEALING_OFF)) +
" AI_I_AM_BEING_HEALED: " + IntToString(GetLocalInt(oTarget, "AI_I_AM_BEING_HEALED")) +
@@ -1133,52 +1154,92 @@ int ai_TryHealing(object oCreature, object oTarget, int bForce = FALSE)
oCreature != oTarget) return FALSE;
if(ai_GetAIMode(oCreature, AI_MODE_SELF_HEALING_OFF) &&
oCreature == oTarget) return FALSE;
// Undead don't heal so lets skip this for them, maybe later we can fix this.
if(GetRacialType(oTarget) == RACIAL_TYPE_UNDEAD) return FALSE;
int nHpLost = ai_GetPercHPLoss(oTarget);
// If the player is forcing a heal then we always heal.
if(bForce && nHpLost < 100) nHpLost = 0;
if(AI_DEBUG) ai_Debug("0i_actions", "743", "nHpLost: " + IntToString(nHpLost) +
if(AI_DEBUG) ai_Debug("0i_actions", "1160", "nHpLost: " + IntToString(nHpLost) +
" limit: " + IntToString(ai_GetHealersHpLimit(oTarget, FALSE)));
if(nHpLost >= ai_GetHealersHpLimit(oTarget, FALSE))
// Check to see if we need poison, disease, or ability drain removed.
int nEffectType;
effect eEffect = GetFirstEffect(oTarget);
while(GetIsEffectValid(eEffect))
{
// Check to see if we need poison, disease, or ability drain removed.
int nEffectType;
effect eEffect = GetFirstEffect(oTarget);
while(GetIsEffectValid(eEffect))
nEffectType = GetEffectType(eEffect);
if(AI_DEBUG) ai_Debug("0i_actions", "1168", "Checking to cure(31/32/39) nEffectType: " + IntToString(nEffectType));
if(nEffectType == EFFECT_TYPE_DISEASE)
{
nEffectType = GetEffectType(eEffect);
if(AI_DEBUG) ai_Debug("0i_actions", "1094", "Checking to cure(31/32/39) nEffectType: " + IntToString(nEffectType));
if(nEffectType == EFFECT_TYPE_DISEASE)
if(AI_DEBUG) ai_Debug("0i_actions", "1171", GetName(oTarget) + " is diseased!");
if(ai_HealSickness(oCreature, oTarget, ai_GetPlayerMaster(oCreature), AI_ALLY_IS_DISEASED, bForce)) return TRUE;
if(oCreature == oTarget)
{
if(AI_DEBUG) ai_Debug("0i_actions", "1097", "I am diseased!");
if(ai_HealSickness(oCreature, oTarget, ai_GetPlayerMaster(oCreature), AI_ALLY_IS_DISEASED, bForce)) return TRUE;
if(oCreature == oTarget)
{
if(!d20()) ai_HaveCreatureSpeak(oCreature, 5, ":43:4:14:15:16:");
SpeakString(AI_I_AM_DISEASED, TALKVOLUME_SILENT_TALK);
}
if(!Random(20)) ai_HaveCreatureSpeak(oCreature, 5, ":43:4:14:15:16:");
SpeakString(AI_I_AM_DISEASED, TALKVOLUME_SILENT_TALK);
}
else if(nEffectType == EFFECT_TYPE_POISON)
}
else if(nEffectType == EFFECT_TYPE_POISON)
{
if(AI_DEBUG) ai_Debug("0i_actions", "1181", GetName(oTarget) + " is poisoned!");
if(ai_HealSickness(oCreature, oTarget, ai_GetPlayerMaster(oCreature), AI_ALLY_IS_POISONED, bForce)) return TRUE;
if(oCreature == oTarget)
{
if(AI_DEBUG) ai_Debug("0i_actions", "1107", "I am poisoned!");
if(ai_HealSickness(oCreature, oTarget, ai_GetPlayerMaster(oCreature), AI_ALLY_IS_POISONED, bForce)) return TRUE;
if(oCreature == oTarget)
{
if(!d20()) ai_HaveCreatureSpeak(oCreature, 6, ":43:4:14:15:16:19:");
SpeakString(AI_I_AM_POISONED, TALKVOLUME_SILENT_TALK);
}
if(!Random(20)) ai_HaveCreatureSpeak(oCreature, 6, ":43:4:14:15:16:19:");
SpeakString(AI_I_AM_POISONED, TALKVOLUME_SILENT_TALK);
}
else if(nEffectType == EFFECT_TYPE_ABILITY_DECREASE)
}
else if(nEffectType == EFFECT_TYPE_ABILITY_DECREASE)
{
if(AI_DEBUG) ai_Debug("0i_actions", "1191", GetName(oTarget) + " is weak!");
if(ai_HealSickness(oCreature, oTarget, ai_GetPlayerMaster(oCreature), AI_ALLY_IS_WEAK, bForce)) return TRUE;
if(oCreature == oTarget)
{
if(AI_DEBUG) ai_Debug("0i_actions", "1117", "I am weak!");
if(ai_HealSickness(oCreature, oTarget, ai_GetPlayerMaster(oCreature), AI_ALLY_IS_WEAK, bForce)) return TRUE;
if(oCreature == oTarget)
{
if(!d20()) ai_HaveCreatureSpeak(oCreature, 3, ":43:4:5:");
SpeakString(AI_I_AM_WEAK, TALKVOLUME_SILENT_TALK);
}
if(!Random(20)) ai_HaveCreatureSpeak(oCreature, 3, ":43:4:5:");
SpeakString(AI_I_AM_WEAK, TALKVOLUME_SILENT_TALK);
}
eEffect = GetNextEffect(oTarget);
}
eEffect = GetNextEffect(oTarget);
}
// Everything below here is for healing.
if(nHpLost >= ai_GetHealersHpLimit(oTarget, FALSE)) return FALSE;
// Undead require inflict spells to heal!
object oMaster = ai_GetPlayerMaster(oCreature);
if(GetRacialType(oTarget) == RACIAL_TYPE_UNDEAD)
{
// Do we have no magic on?
if(!ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC))
{
int nClass, nPosition = 1;
string sMemorized;
while(nPosition <= AI_MAX_CLASSES_PER_CHARACTER)
{
nClass = GetClassByPosition(nPosition, oCreature);
if(AI_DEBUG) ai_Debug("0i_actions", "753", "nClass: " + IntToString(nClass));
if(nClass == CLASS_TYPE_INVALID) break;
sMemorized = Get2DAString("classes", "MemorizesSpells", nClass);
// If Memorized column is "" then they are not a caster.
if(sMemorized != "")
{
if(sMemorized == "1")
{
if(ai_CastMemorizedInflict(oCreature, oTarget, oMaster, nClass))
{
SetLocalInt(oTarget, "AI_I_AM_BEING_HEALED", TRUE);
return TRUE;
}
}
else if(ai_CastKnownInflict(oCreature, oTarget, oMaster, nClass))
{
SetLocalInt(oTarget, "AI_I_AM_BEING_HEALED", TRUE);
return TRUE;
}
}
nPosition++;
}
}
// We can't heal ourselves! Can any of our allies? Lets ask.
if(oCreature == oTarget)
{
SetLocalInt(oCreature, "AI_WOUNDED_SHOUT_LIMIT", GetLocalInt(oCreature, "AI_WOUNDED_SHOUT_LIMIT") + 1);
SpeakString(AI_I_AM_WOUNDED, TALKVOLUME_SILENT_TALK);
}
return FALSE;
}
@@ -1192,7 +1253,6 @@ int ai_TryHealing(object oCreature, object oTarget, int bForce = FALSE)
return TRUE;
}
}
object oMaster = ai_GetPlayerMaster(oCreature);
// Do we have no magic on?
if(!ai_GetMagicMode(oCreature, AI_MAGIC_NO_MAGIC))
{

View File

@@ -115,7 +115,7 @@ void ai_Philos_SetStealth(object oMaster, object oCreature, string sAssociateTyp
// Button action for giving commands to associates.
void ai_DoCommand(object oPC, object oAssociate, int nCommand);
// Button action to have associate do an action based on the target via OnPlayer Target event.
void ai_Action(object oPC, object oAssociate);
void ai_Action(object oPC, object oAssociate, int bPCAI = FALSE);
// Toggles between normal ai script and special tactic ai scripts.
void ai_AIScript(object oPC, object oAssociate, string sAssociate, int nToken);
// Has the PC select a Trap and then place it on the ground from an associate.
@@ -130,6 +130,10 @@ void ai_ChangeCameraView(object oPC, object oAssociate);
void ai_OpenInventory(object oAssociate, object oPC);
// Executes an installed plugin.
void ai_Plugin_Execute(object oPC, string sElem, int bUser = 0);
// Turns on oAssociate AI, Setting all event scripts.
void ai_TurnOn(object oPC, object oAssociate, string sAssociateType);
// Turns off oAssociate AI, Setting all event scripts.
void ai_TurnOff(object oPC, object oAssociate, string sAssociateType);
int ai_CanIAttack(object oCreature)
{
@@ -161,7 +165,7 @@ object ai_GetNearestLockedObject(object oCreature)
void ai_FindTheEnemy(object oCreature, object oSpeaker, object oTarget, int bMonster)
{
if(GetLocalInt(oCreature, AI_AM_I_SEARCHING)) return;
if(oSpeaker == oTarget && d100() < 34)
if(oSpeaker == oTarget && d100() < 16)
{
// Let them know we heard something in the distance!.
if(!ai_GetAIMode(oCreature, AI_MODE_DO_NOT_SPEAK))
@@ -232,7 +236,7 @@ void ai_FindTheEnemy(object oCreature, object oSpeaker, object oTarget, int bMon
if(AI_DEBUG) ai_Debug("0i_associates", "176", "Moving and searching for " + GetName(oTarget));
SetActionMode(oCreature, ACTION_MODE_DETECT, TRUE);
ActionMoveToLocation(GetLocation(oTarget), FALSE);
//ActionMoveToObject(oTarget, FALSE, AI_RANGE_MELEE);
//ActionMoveToObject(oTarget, FALSE, AI_RANGE_MELEE);
AssignCommand(oCreature, ActionDoCommand(DeleteLocalInt(oCreature, AI_AM_I_SEARCHING)));
return;
}
@@ -835,7 +839,7 @@ void ai_MonsterEvaluateNewThreat(object oCreature, object oLastPerceived, string
ai_HaveCreatureSpeak(oCreature, 5, ":0:1:2:3:6:");
}
SetLocalObject(oCreature, AI_MY_TARGET, oLastPerceived);
SpeakString(sPerception, TALKVOLUME_SILENT_TALK);
SpeakString(AI_I_SEE_AN_ENEMY, TALKVOLUME_SILENT_TALK);
ai_StartMonsterCombat(oCreature);
}
else ai_FindTheEnemy(oCreature, oLastPerceived, oLastPerceived, TRUE);
@@ -1903,18 +1907,20 @@ void ai_DoCommand(object oPC, object oAssociate, int nCommand)
}
}
}
void ai_Action(object oPC, object oAssociate)
void ai_Action(object oPC, object oAssociate, int bPCAI = FALSE)
{
if(oPC == oAssociate)
{
DeleteLocalObject(oPC, "NW_ASSOCIATE_COMMAND");
SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_ACTION_ALL");
ai_SendMessages("Select an action for the party.", AI_COLOR_YELLOW, oPC);
}
else
{
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, oAssociate);
SetLocalObject(oPC, AI_TARGET_MODE_ASSOCIATE, oAssociate);
SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_ACTION");
SetLocalInt(oPC, AI_TARGET_MODE_ON, TRUE);
if(!GetLocalInt(GetModule(), AI_USING_PRC) && bPCAI) ai_TurnOn(oPC, oPC, "pc");
ai_SendMessages("Select an action for " + GetName(oAssociate) + ".", AI_COLOR_YELLOW, oPC);
}
EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_ACTION, MOUSECURSOR_NOWALK);
@@ -2139,6 +2145,7 @@ void ai_ChangeCameraView(object oPC, object oAssociate)
{
SetLocalObject(oPC, "AI_CAMERA_ON_ASSOCIATE", oAssociate);
AttachCamera(oPC, oAssociate);
if(!ai_GetIsCharacter(oAssociate)) ai_Action(oPC, oAssociate, TRUE);
}
}
void ai_SelectCameraView(object oPC)
@@ -2190,3 +2197,47 @@ void ai_Plugin_Execute(object oPC, string sElem, int bUser = 0)
ExecuteScript(sScript, oPC);
}
}
void ai_TurnOn(object oPC, object oTarget, string sAssociateType)
{
ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ai_tooltip", " AI On");
ai_SendMessages("AI turned on for " + GetName(oTarget) + ".", AI_COLOR_YELLOW, oPC);
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "xx_pc_1_hb");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_NOTICE, "xx_pc_2_percept");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "xx_pc_3_endround");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "xx_pc_4_convers");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "xx_pc_5_phyatked");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "xx_pc_6_damaged");
//SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DEATH, "");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "xx_pc_8_disturb");
//SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, "");
//SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_RESTED, "");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "xx_pc_b_castat");
SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "xx_pc_e_blocked");
//SetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, "");
// This sets the script for the PC to run AI based on class.
ai_SetAssociateAIScript(oTarget, FALSE);
// Set so PC can hear associates talking in combat.
ai_SetListeningPatterns(oTarget);
}
void ai_TurnOff(object oPC, object oAssociate, string sAssociateType)
{
ai_UpdateToolTipUI(oPC, sAssociateType + AI_NUI, sAssociateType + AI_WIDGET_NUI, "btn_ai_tooltip", " AI Off");
ai_SendMessages("AI Turned off for " + GetName(oAssociate) + ".", AI_COLOR_YELLOW, oPC);
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_NOTICE, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DIALOGUE, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DAMAGED, "");
//SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DEATH, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_DISTURBED, "");
//SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPAWN_IN, "");
//SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_RESTED, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT, "");
SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR, "");
//SetEventScript(oAssociate, EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT, "");
DeleteLocalInt(oAssociate, "AI_I_AM_BEING_HEALED");
DeleteLocalString(oAssociate, "AIScript");
ai_ClearCreatureActions();
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
Changes to any constants will not take effect until the scripts are recompiled.
*///////////////////////////////////////////////////////////////////////////////
const string PHILOS_VERSION = "Philos' Enhancing Player System (PEPS) version:07.20.25";
const string PHILOS_VERSION = "Philos' Enhancing Player System (PEPS) version:08.31.25";
// The following constants are designed to be changed to allow the AI to work
// differently based on what a developer wants.
// If you change these constants make sure the database has been removed
@@ -18,7 +18,7 @@ const string PHILOS_VERSION = "Philos' Enhancing Player System (PEPS) version:07
// This will only work if you are using the PEPS menu system.
const int AI_DEBUG = FALSE;
// Defines if we are compiling for single player or a server. Always on for servers!
const int AI_SERVER = FALSE;
const int AI_SERVER = TRUE;
// The number of classes allowed for a creature to take in the server/module.
const int AI_MAX_CLASSES_PER_CHARACTER = 8;
// Taunts cool down time before the AI attemps another Taunt.
@@ -141,7 +141,9 @@ const string AI_EFFECT_ICON_NUI = "ai_effect_icon_nui";
// The following constants are core constants and changing any of these without
// understanding the whole system could cause unforseen results.
// CHANGE AT YOUR OWN RISK.
// Variable used to asave a monster object for changing.
// Variable used to check if the module is running as a server.
const string AI_IS_SERVER = "AI_IS_SERVER";
// Variable used to save a monster object for changing.
const string AI_MONSTER_OBJECT = "AI_MONSTER_OBJECT";
// Variable used to save a monsters json for changing.
const string AI_MONSTER_JSON = "AI_MONSTER_JSON";
@@ -219,7 +221,6 @@ const string AI_I_AM_DEAD = "AI_I_AM_DEAD";
const string AI_I_AM_DISEASED = "AI_I_AM_DISEASED";
const string AI_I_AM_POISONED = "AI_I_AM_POISONED";
const string AI_I_AM_WEAK = "AI_I_AM_WEAK";
const int AI_ALLY_SEES_AN_ENEMY = 1;
const int AI_ALLY_HEARD_AN_ENEMY = 2;
const int AI_ALLY_ATKED_BY_WEAPON = 3;
const int AI_ALLY_ATKED_BY_SPELL = 4;
@@ -228,6 +229,7 @@ const int AI_ALLY_IS_DEAD = 6;
const int AI_ALLY_IS_DISEASED = 7;
const int AI_ALLY_IS_POISONED = 8;
const int AI_ALLY_IS_WEAK = 9;
const int AI_ALLY_SEES_AN_ENEMY = 10;
const string AI_MY_TARGET = "AI_MY_TARGET";
// Constant used by monsters to reduce checks while searching for unseen targets.
const string AI_AM_I_SEARCHING = "AI_AM_I_SEARCHING";
@@ -255,6 +257,8 @@ const string AI_ATTACKED_PHYSICAL = "AI_ATTACKED_PHYSICAL";
const string AI_ATTACKED_SPELL = "AI_ATTACKED_SPELL";
// Variable name used to keep track of a creatures normal polymorph form.
const string AI_NORMAL_FORM = "AI_NORMAL_FORM";
// Variable name used to have associates defined as Polymorphed.
const string AI_POLYMORPHED = "AI_POLYMORPHED";
// Variable name used to keep track if a creature has been buffed yet.
const string AI_CASTER_BUFFS_SET = "AI_CASTER_BUFFS_SET";
// Variable name used to keep track of rounds in combat for a custom ai script.
@@ -320,6 +324,7 @@ const int AI_CONDITION_CONFUSED = 0x00020000;
const int AI_CONDITION_CURSE = 0x00040000;
const int AI_CONDITION_PARALYZE = 0x00080000;
const int AI_CONDITION_DOMINATED = 0x00100000;
const int AI_CONDITION_DEAD = 0x00200000;
// Database constants for Associate modes.
const string AI_MODE_DB_TABLE = "AI_MODE_DB_TABLE";
// Bitwise constants for Associate modes that are used with Get/SetAssociateMode().
@@ -394,30 +399,31 @@ const int AI_MAGIC_NO_SPONTANEOUS_CURE = 0x00000800; // Caster will stop using s
const string AI_NO_NUI_SAVE = "AI_NO_NUI_SAVE";
// Bitwise menu constants for Widget buttons that are used with Get/SetAssociateWidgetButtons().
const string sWidgetButtonsVarname = "ASSOCIATE_WIDGET_BUTTONS";
const int BTN_WIDGET_OFF = 0x00000001; // Removes the widget from the screen, For PC it removes all associates.
const int BTN_WIDGET_LOCK = 0x00000002; // Locks the widget to the current coordinates.
const int BTN_CMD_GUARD = 0x00000004; // Command associates to Guard Me. PC widget only.
const int BTN_CMD_FOLLOW = 0x00000008; // Command associates to Follow. PC widget only.
const int BTN_CMD_HOLD = 0x00000010; // Command associates to Stand Ground. PC widget only.
const int BTN_CMD_ATTACK = 0x00000020; // Command associates to Attack Nearest. PC widget only.
const int BTN_BUFF_REST = 0x00000040; // Buffs with long duration spells after resting. Associate widget only.
const int BTN_BUFF_SHORT = 0x00000080; // Buffs with short duration spells.
const int BTN_BUFF_LONG = 0x00000100; // Buffs with long duration spells.
const int BTN_BUFF_ALL = 0x00000200; // Buffs with all spells.
const int BTN_CMD_ACTION = 0x00000400; // Command associate to do an action.
const int BTN_CMD_GHOST_MODE = 0x00000800; // Toggle's associates ghost mode.
const int BTN_CMD_AI_SCRIPT = 0x00001000; // Toggle's special tactics ai scripts.
const int BTN_CMD_PLACE_TRAP = 0x00002000; // A trapper may place traps.
const int BTN_CMD_CAMERA = 0x00004000; // Places camera view on associate.
const int BTN_CMD_INVENTORY = 0x00008000; // Opens inventory of associate.
const int BTN_CMD_FAMILIAR = 0x00010000; // Summons familiar.
const int BTN_CMD_COMPANION = 0x00020000; // Summons Companion.
const int BTN_CMD_SEARCH = 0x00040000; // Command all associates to use search mode. PC widget only.
const int BTN_CMD_STEALTH = 0x00080000; // Command all associates to use stealth mode. PC widget only.
const int BTN_CMD_SCOUT = 0x00100000; // Command associate to scout ahead of the part.
const int BTN_CMD_SPELL_WIDGET = 0x00200000; // Allows adding or removing spells from Spell Widget.
const int BTN_CMD_JUMP_TO = 0x00400000; // Player can make associates jump to them.
const int BTN_WIDGET_VERTICAL = 0x80000000; // Widget will be displayed vertical.
const int BTN_WIDGET_OFF = 0x00000001; // Removes the widget from the screen, For PC it removes all associates.
const int BTN_WIDGET_LOCK = 0x00000002; // Locks the widget to the current coordinates.
const int BTN_CMD_GUARD = 0x00000004; // Command associates to Guard Me. PC widget only.
const int BTN_CMD_FOLLOW = 0x00000008; // Command associates to Follow. PC widget only.
const int BTN_CMD_HOLD = 0x00000010; // Command associates to Stand Ground. PC widget only.
const int BTN_CMD_ATTACK = 0x00000020; // Command associates to Attack Nearest. PC widget only.
const int BTN_BUFF_REST = 0x00000040; // Buffs with long duration spells after resting. Associate widget only.
const int BTN_BUFF_SHORT = 0x00000080; // Buffs with short duration spells.
const int BTN_BUFF_LONG = 0x00000100; // Buffs with long duration spells.
const int BTN_BUFF_ALL = 0x00000200; // Buffs with all spells.
const int BTN_CMD_ACTION = 0x00000400; // Command associate to do an action.
const int BTN_CMD_GHOST_MODE = 0x00000800; // Toggle's associates ghost mode.
const int BTN_CMD_AI_SCRIPT = 0x00001000; // Toggle's special tactics ai scripts.
const int BTN_CMD_PLACE_TRAP = 0x00002000; // A trapper may place traps.
const int BTN_CMD_CAMERA = 0x00004000; // Places camera view on associate.
const int BTN_CMD_INVENTORY = 0x00008000; // Opens inventory of associate.
const int BTN_CMD_FAMILIAR = 0x00010000; // Summons familiar.
const int BTN_CMD_COMPANION = 0x00020000; // Summons Companion.
const int BTN_CMD_SEARCH = 0x00040000; // Command all associates to use search mode. PC widget only.
const int BTN_CMD_STEALTH = 0x00080000; // Command all associates to use stealth mode. PC widget only.
const int BTN_CMD_SCOUT = 0x00100000; // Command associate to scout ahead of the part.
const int BTN_CMD_SPELL_WIDGET = 0x00200000; // Allows adding or removing spells from Spell Widget.
const int BTN_CMD_JUMP_TO = 0x00400000; // Player can make associates jump to them.
const int BTN_ASSOC_WIDGETS_OFF = 0x00800000; // Turns all associate widgets on/off.
const int BTN_WIDGET_VERTICAL = 0x80000000; // Widget will be displayed vertical.
// Bitwise menu constants for Associate AI buttons that are used with Get/SetAssociateAIButtons().
const string sAIButtonsVarname = "ASSOCIATE_AI_BUTTONS";
const int BTN_AI_FOR_PC = 0x00000001; // PC use AI. PC widget only.
@@ -568,6 +574,12 @@ const string AI_MODULE_GUI_EVENT = "AI_MODULE_GUI_EVENT";
const string AI_TARGET_MODE = "AI_TARGET_MODE";
// Variable used on the player to define which associate triggered the OnPlayer Target.
const string AI_TARGET_ASSOCIATE = "AI_TARGET_ASSOCIATE";
// Variable use on the player to define if the player is using target mode on an associate.
const string AI_TARGET_MODE_ON = "AI_TARGET_MODE_ON";
// Variable used on the player to define what associate has Target Mode set on it.
const string AI_TARGET_MODE_ASSOCIATE = "AI_TARGET_MODE_ASSOCIATE";
// Variable used on a creature to define how long ago their immunities were saved.
const string sIPTimeStampVarname = "AI_IP_TIMESTAMP";
// Bitwise constants for immune damage item properties that is used with Get/SetItemProperty().
const string sIPImmuneVarname = "AI_IP_IMMUNE";
// Bitwise constants for resisted damage item properties that is used with Get/SetItemProperty().

View File

@@ -12,7 +12,7 @@
*/////////////////////////////////////////////////////////////////////////////////////////////////////
#include "0i_constants"
#include "0i_nui"
void ai_SetupModuleGUIEvents(object oCreature)
void ai_SetupModuleGUIEvents()
{
object oModule = GetModule();
string sModuleGUIEvents = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_GUIEVENT);

View File

@@ -25,6 +25,8 @@ const string AI_DM_TABLE = "DM_TABLE";
// Sets PEPS RULES from the database to the module.
// Creates default rules if they do not exist.
void ai_SetAIRules();
// Returns TRUE if the module is being run as a server.
int ai_GetIsServer();
// Returns TRUE if oCreature is controlled by a player.
int ai_GetIsCharacter(object oCreature);
// Returns TRUE if oCreature is controlled by a dungeon master.
@@ -307,13 +309,17 @@ void ai_SetAIRules()
SetLocalInt(oModule, sDMAIAccessVarname, bValue);
}
}
int ai_GetIsServer()
{
return GetLocalInt(GetModule(), AI_IS_SERVER) || AI_SERVER;
}
int ai_GetIsCharacter(object oCreature)
{
return (GetIsPC(oCreature) && !GetIsDM(oCreature) && !GetIsDMPossessed(oCreature));
return (GetIsPC(oCreature) && !GetIsDM(oCreature) && !GetIsDMPossessed(oCreature) && !GetIsPlayerDM(oCreature));
}
int ai_GetIsDungeonMaster(object oCreature)
{
return (GetIsDM(oCreature) || GetIsDMPossessed(oCreature));
return (GetIsDM(oCreature) || GetIsDMPossessed(oCreature) || GetIsPlayerDM(oCreature));
}
object ai_GetPlayerMaster(object oAssociate)
{
@@ -862,7 +868,7 @@ void ai_SetupAIData(object oPlayer, object oAssociate, string sAssociateType)
// We keep it for now as we don't want to move other data.
jAIData = JsonArrayInsert(jAIData, JsonInt(11)); // 7 - Associate Perception DistanceDistance.
SetLocalInt(oAssociate, AI_ASSOCIATE_PERCEPTION, 11);
SetLocalFloat(oAssociate, AI_ASSOC_PERCEPTION_DISTANCE, 20.0);
SetLocalFloat(oAssociate, AI_ASSOC_PERCEPTION_DISTANCE, 25.0);
jAIData = JsonArrayInsert(jAIData, JsonString("")); // 8 - Associate Combat Tactics.
jAIData = JsonArrayInsert(jAIData, JsonFloat(20.0)); // 9 - Open Doors check range.
SetLocalFloat(oAssociate, AI_OPEN_DOORS_RANGE, 20.0);
@@ -1140,7 +1146,7 @@ void ai_SetupDMData(object oPlayer, string sName)
void ai_CheckDMData(object oPlayer)
{
//ai_Debug("0i_main", "898", "Checking data for DM: " + GetName(oPlayer));
string sName = ai_RemoveIllegalCharacters(GetName(oPlayer));
string sName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPlayer)));
// ********** Buttons **********
json jButtons = ai_GetCampaignDbJson("buttons", sName, AI_DM_TABLE);
// if there is no saved AImodes then set the defaults.
@@ -1241,7 +1247,7 @@ json ai_CheckOldPluginJson(object oPC)
json ai_UpdatePluginsForPC(object oPC)
{
// Check if the server is running or single player.
if(!AI_SERVER) return ai_CheckOldPluginJson(oPC);
if(!ai_GetIsServer()) return ai_CheckOldPluginJson(oPC);
int nJsonType, nCounter, nIndex, bWidget, bAllow;
string sScript, sName, sIcon;
json jServerPlugins = ai_GetCampaignDbJson("plugins");
@@ -1283,7 +1289,7 @@ json ai_UpdatePluginsForPC(object oPC)
json ai_UpdatePluginsForDM(object oPC)
{
int nJsonType, nCounter, nIndex, bWidget, bAllow;
string sName, sIcon, sDbName = ai_RemoveIllegalCharacters(GetName(oPC));
string sName, sIcon, sDbName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPC)));
json jServerPlugins = ai_GetCampaignDbJson("plugins");
ai_CheckDMDataAndInitialize(oPC);
json jDMPlugin, jDMPlugins = ai_GetCampaignDbJson("plugins", sDbName, AI_DM_TABLE);
@@ -1323,7 +1329,7 @@ void ai_StartupPlugins(object oPC)
int bUpdatePlugins;
string sScript;
json jPlugins;
if(GetIsDM(oPC)) jPlugins = ai_UpdatePluginsForDM(oPC);
if(ai_GetIsDungeonMaster(oPC)) jPlugins = ai_UpdatePluginsForDM(oPC);
else jPlugins = ai_UpdatePluginsForPC(oPC);
// We delete this so each mod can be added that legally loads.
DeleteLocalJson(GetModule(), AI_MONSTER_MOD_JSON);

View File

@@ -51,7 +51,7 @@ void ai_CreateDescriptionNUI(object oPC, json jSpell, int nSpell = 0);
string ai_GetRandomTip()
{
int nRoll;
if(AI_SERVER) nRoll = Random(26);
if(ai_GetIsServer()) nRoll = Random(26);
else nRoll = Random(46);
return Get2DAString("ai_messages", "Text", nRoll);
}
@@ -344,7 +344,7 @@ void ai_CreateAIMainNUI(object oPC)
int nMonsterAI = (ResManGetAliasFor("ai_default", RESTYPE_NCS) != "");
int nAssociateAI = (ResManGetAliasFor("ai_a_default", RESTYPE_NCS) != "");
string sText = " [Single player]";
if(AI_SERVER) sText = " [Server]";
if(ai_GetIsServer()) sText = " [Server]";
// ************************************************************************* Width / Height
// Row 1 ******************************************************************* 500 / 73
json jRow = JsonArrayInsert(JsonArray(), NuiSpacer());
@@ -352,15 +352,17 @@ void ai_CreateAIMainNUI(object oPC)
jRow = JsonArrayInsert(jRow, NuiSpacer());
// Add row to the column.
json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow));
// Row 2 ******************************************************************* 500 / 101
jRow = CreateLabel(JsonArray(), "", "lbl_ai_info", 510.0f, 20.0f, NUI_HALIGN_CENTER);
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
if(!AI_SERVER)
{
// Row 2 ******************************************************************* 500 / 101
jRow = CreateLabel(JsonArray(), "", "lbl_ai_info", 510.0f, 20.0f, NUI_HALIGN_CENTER);
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
}
// Row 3 ******************************************************************* 500 / 129
jRow = CreateButton(JsonArray(), "Plugin Manager", "btn_plugin_manager", 120.0f, 20.0f, -1.0, "btn_plugin_manager_tooltip");
if(nAssociateAI) jRow = CreateButtonSelect(jRow, "Associate Widgets", "btn_toggle_assoc_widget", 140.0f, 20.0f, "btn_assoc_widget_tooltip");
jRow = CreateButtonSelect(jRow, "Action Ghost Mode", "btn_action_ghost", 160.0f, 20.0f, "btn_action_ghost_tooltip");
jRow = CreateButtonSelect(jRow, "Effect Icons", "btn_effect_icon", 100.0f, 20.0f, "btn_effect_icon_tooltip");
jRow = CreateButton(JsonArray(), "Plugin Manager", "btn_plugin_manager", 175.0f, 20.0f, -1.0, "btn_plugin_manager_tooltip");
jRow = CreateButtonSelect(jRow, "Action Ghost Mode", "btn_action_ghost", 175.0f, 20.0f, "btn_action_ghost_tooltip");
jRow = CreateButtonSelect(jRow, "Effect Icons", "btn_effect_icon", 175.0f, 20.0f, "btn_effect_icon_tooltip");
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 4 ******************************************************************* 500 / 157
@@ -448,7 +450,7 @@ void ai_CreateAIMainNUI(object oPC)
float fY = JsonGetFloat(JsonObjectGet(jLocations, "y"));
// Set the Layout of the window.
json jLayout = NuiCol(jCol);
string sName = GetName(oPC);
string sName = ai_StripColorCodes(GetName(oPC));
if(GetStringRight(sName, 1) == "s") sName = sName + "'";
else sName = sName + "'s";
int nToken = SetWindow(oPC, jLayout, AI_MAIN_NUI, sName + " PEPS Main Menu",
@@ -464,49 +466,45 @@ void ai_CreateAIMainNUI(object oPC)
// Row 1 - Version label.
// Row 2
int nUsing;
// Check the monster AI.
string sLocation = ResManGetAliasFor("ai_default", RESTYPE_NCS);
if(sLocation != "")
if(!AI_SERVER)
{
nUsing = TRUE;
string sLocation = ResManGetAliasFor("nw_c2_default1", RESTYPE_NCS);
if(sLocation != "OVERRIDE:" && sLocation != "PATCH:peps" && sLocation != "DEVELOPMENT:") nUsing = FALSE;
if(nUsing) sText = "Monster AI working";
else sText = "Monster AI not working";
// Check the monster AI.
string sLocation = ResManGetAliasFor("ai_default", RESTYPE_NCS);
if(sLocation != "")
{
nUsing = TRUE;
string sLocation = ResManGetAliasFor("nw_c2_default1", RESTYPE_NCS);
if(sLocation != "OVERRIDE:" && sLocation != "PATCH:peps" && sLocation != "DEVELOPMENT:") nUsing = FALSE;
if(nUsing) sText = "Monster AI working";
else sText = "Monster AI not working";
}
else sText = "Monster AI not loaded";
// Check the associate AI.
sLocation = ResManGetAliasFor("ai_a_default", RESTYPE_NCS);
if(sLocation != "")
{
nUsing = TRUE;
string sLocation = ResManGetAliasFor("nw_ch_ac1", RESTYPE_NCS);
if(sLocation != "OVERRIDE:" && sLocation != "PATCH:peps" && sLocation != "DEVELOPMENT:") nUsing = FALSE;
if(nUsing) sText += ", Associate AI working";
else sText += ", Associate AI not working";
}
else sText += ", Associate AI not loaded";
// Check for PRC.
sLocation = ResManGetAliasFor("prc_ai_fam_percp", RESTYPE_NCS);
if(sLocation != "") sText += ", PRC loaded.";
else
{
// Check the player AI.
sLocation = ResManGetAliasFor("xx_pc_1_hb", RESTYPE_NCS);
if(sLocation != "") sText += ", Player AI loaded.";
else sText += ", Player AI not loaded.";
}
NuiSetBind(oPC, nToken, "lbl_ai_info_label", JsonString(sText));
}
else sText = "Monster AI not loaded";
// Check the associate AI.
sLocation = ResManGetAliasFor("ai_a_default", RESTYPE_NCS);
if(sLocation != "")
{
nUsing = TRUE;
string sLocation = ResManGetAliasFor("nw_ch_ac1", RESTYPE_NCS);
if(sLocation != "OVERRIDE:" && sLocation != "PATCH:peps" && sLocation != "DEVELOPMENT:") nUsing = FALSE;
if(nUsing) sText += ", Associate AI working";
else sText += ", Associate AI not working";
}
else sText += ", Associate AI not loaded";
// Check for PRC.
sLocation = ResManGetAliasFor("prc_ai_fam_percp", RESTYPE_NCS);
if(sLocation != "") sText += ", PRC loaded.";
else
{
// Check the player AI.
sLocation = ResManGetAliasFor("xx_pc_1_hb", RESTYPE_NCS);
if(sLocation != "") sText += ", Player AI loaded.";
else sText += ", Player AI not loaded.";
}
NuiSetBind(oPC, nToken, "lbl_ai_info_label", JsonString(sText));
// Row 3
NuiSetBind(oPC, nToken, "btn_plugin_manager_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_plugin_manager_tooltip", JsonString(" Manages external executable scripts."));
if(nAssociateAI)
{
NuiSetBind(oPC, nToken, "btn_toggle_assoc_widget_event", JsonBool(TRUE));
int bWidgetOn = !ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, OBJECT_INVALID, "pc");
NuiSetBind(oPC, nToken, "btn_toggle_assoc_widget", JsonBool(bWidgetOn));
NuiSetBind(oPC, nToken, "btn_assoc_widget_tooltip", JsonString(" Turns On/Off all associate widgets."));
}
int bActionGhost = ai_GetAIMode(oPC, AI_MODE_ACTION_GHOST);
NuiSetBind(oPC, nToken, "btn_action_ghost", JsonBool (bActionGhost));
NuiSetBind(oPC, nToken, "btn_action_ghost_event", JsonBool(TRUE));
@@ -649,13 +647,14 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
{
if(bIsPC)
{
if(bUsingPCAI || !AI_SERVER)
bLeft = ai_GetIsServer();
if(bUsingPCAI || !bLeft)
{
if(bUsingPCAI)
{
jRow = CreateButton(jRow, "AI Menu", "btn_ai_menu", 232.0, 20.0, -1.0, "btn_ai_menu_tooltip");
}
if(!AI_SERVER)
if(!bLeft)
{
jRow = CreateButton(jRow, "Main Menu", "btn_main_menu", 232.0, 20.0, -1.0, "btn_main_menu_tooltip");
}
@@ -681,6 +680,29 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jRow = CreateButtonSelect(jRow, "Vertical Widget", "btn_vertical_widget", 154.0, 20.0, "btn_vertical_widget_tooltip");
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 3 ******************************************************************* 500 / 129
bRight = !ai_GetDMWAccessButton(BTN_ASSOC_WIDGETS_OFF);
//bLeft = !ai_GetDMWAccessButton(BTN_CMD_GUARD);
if(bRight)// || bLeft)
{
jRow = JsonArray();
if(bRight)
{
if(bIsPC && bUsingHenchAI)
{
jRow = CreateButton(jRow, "Associate Widgets", "btn_toggle_assoc_widget", 200.0f, 20.0f, -1.0, "btn_toggle_assoc_widget_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_toggle_assoc_widget", 25.0, 20.0);
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight += 28.0;
}
}
jRow = JsonArrayInsert(jRow, NuiSpacer());
//if(bLeft)
//{
//}
//jCol = JsonArrayInsert(jCol, NuiRow(jRow));
//fHeight += 28.0;
}
// Row 4 ******************************************************************* 500 / 129
bRight = !ai_GetDMWAccessButton(BTN_CMD_ACTION);
bLeft = !ai_GetDMWAccessButton(BTN_CMD_GUARD);
if(bRight || bLeft)
@@ -700,7 +722,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight += 28.0;
}
// Row 4 ******************************************************************* 500 / 157
// Row 5 ******************************************************************* 500 / 157
jRow = JsonArray();
bRight = !ai_GetDMWAccessButton(BTN_CMD_HOLD);
bLeft = !ai_GetDMWAccessButton(BTN_CMD_ATTACK);
@@ -721,7 +743,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight += 28.0;
}
// Row 5 ******************************************************************* 500 / 213
// Row 6 ******************************************************************* 500 / 213
bRight = !ai_GetDMWAccessButton(BTN_CMD_FOLLOW);
bLeft = !ai_GetDMAIAccessButton(BTN_AI_FOLLOW_TARGET);
if(bRight || bLeft)
@@ -741,7 +763,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight += 28.0;
}
// Row 6 ******************************************************************* 500 / 185
// Row 7 ******************************************************************* 500 / 185
if(bIsPC)
{
bRight = !ai_GetDMWAccessButton(BTN_CMD_SEARCH);
@@ -764,7 +786,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
fHeight = fHeight + 28.0;
}
}
// Row 7 ******************************************************************* 500 / 241
// Row 8 ******************************************************************* 500 / 241
bRight = !ai_GetDMWAccessButton(BTN_CMD_AI_SCRIPT);
bLeft = !ai_GetDMWAccessButton(BTN_CMD_PLACE_TRAP);
if(bRight || bLeft)
@@ -785,7 +807,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight = fHeight + 28.0;
}
// Row 8 ******************************************************************* 500 / ---
// Row 9 ******************************************************************* 500 / ---
int bMemorize = ai_GetIsSpellCaster(oAssociate);
int bSpellbook = ai_GetIsSpellBookRestrictedCaster(oAssociate);
bRight = !ai_GetDMWAccessButton(BTN_CMD_SPELL_WIDGET);
@@ -821,7 +843,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight = fHeight + 28.0;
}
// Row 9 ******************************************************************* 500 / 269
// Row 10 ******************************************************************* 500 / 269
bRight = !ai_GetDMWAccessButton(BTN_BUFF_SHORT);
bLeft = !ai_GetDMWAccessButton(BTN_BUFF_LONG);
if(bRight || bLeft)
@@ -842,7 +864,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight = fHeight + 28.0;
}
// Row 10 ******************************************************************* 500 / 297
// Row 11 ******************************************************************* 500 / 297
bRight = !ai_GetDMWAccessButton(BTN_BUFF_ALL);
bLeft = !ai_GetDMWAccessButton(BTN_BUFF_REST);
if(bRight || bLeft)
@@ -863,7 +885,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight = fHeight + 28.0;
}
// Row 11 ******************************************************************* 500 / 325
// Row 12 ******************************************************************* 500 / 325
bRight = !ai_GetDMWAccessButton(BTN_CMD_JUMP_TO);
bLeft = !ai_GetDMWAccessButton(BTN_CMD_GHOST_MODE);
if(bRight || bLeft)
@@ -884,7 +906,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight = fHeight + 28.0;
}
// Row 12 ****************************************************************** 500 / 353
// Row 13 ****************************************************************** 500 / 353
bRight = !ai_GetDMWAccessButton(BTN_CMD_CAMERA);
bLeft = !ai_GetDMWAccessButton(BTN_CMD_INVENTORY);
if(bRight || bLeft)
@@ -905,7 +927,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight = fHeight + 28.0;
}
// Row 13 ******************************************************************* 500 / ---
// Row 14 ******************************************************************* 500 / ---
int bFamiliar = GetHasFeat(FEAT_SUMMON_FAMILIAR, oAssociate, TRUE);
if(!ai_GetDMWAccessButton(BTN_CMD_FAMILIAR) && bFamiliar)
{
@@ -916,7 +938,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight = fHeight + 28.0;
// Row 14 ******************************************************************* 500 / ---
// Row 15 ******************************************************************* 500 / ---
jRow = JsonArray();
jRow = CreateCombo(jRow, ai_CreateCompanionJson(oPC, "hen_familiar"), "cmb_familiar", 200.0, 20.0);
jRow = CreateCheckBox(jRow, "", "chbx_familiar", 25.0, 20.0);
@@ -926,7 +948,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight = fHeight + 28.0;
}
// Row 15 ******************************************************************* 500 / ---
// Row 16 ******************************************************************* 500 / ---
int bCompanion = GetHasFeat(FEAT_ANIMAL_COMPANION, oAssociate, TRUE);
if(!ai_GetDMWAccessButton(BTN_CMD_COMPANION) && bCompanion)
{
@@ -937,7 +959,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight = fHeight + 28.0;
// Row 16 ******************************************************************* 500 / ---
// Row 17 ******************************************************************* 500 / ---
jRow = JsonArray();
jRow = CreateCombo(jRow, ai_CreateCompanionJson(oPC, "hen_companion"), "cmb_companion", 200.0, 20.0);
jRow = CreateCheckBox(jRow, "", "chbx_companion", 25.0, 20.0);
@@ -947,7 +969,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight = fHeight + 28.0;
}
// Row 17+ ****************************************************************** 500 / ---
// Row 18+ ****************************************************************** 500 / ---
string sAssociateType = ai_GetAssociateType(oPC, oAssociate);
json jPCPlugins;
if(bIsPC)
@@ -986,7 +1008,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
jPlugin = JsonArrayGet(jPCPlugins, ++nIndex);
}
}
// Row 18 ****************************************************************** 500 / ---
// Row 19+ ****************************************************************** 500 / ---
jRow = JsonArray();
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = CreateLabel(jRow, "", "lbl_info_1", 475.0, 20.0, NUI_HALIGN_CENTER);
@@ -1005,7 +1027,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
}
// Set the Layout of the window.
json jLayout = NuiCol(jCol);
string sName = GetName(oAssociate);
string sName = ai_StripColorCodes(GetName(oAssociate));
if(GetStringRight(sName, 1) == "s") sName = sName + "'";
else sName = sName + "'s";
int nToken = SetWindow(oPC, jLayout, sAssociateType + AI_COMMAND_NUI, sName + " Command Menu",
@@ -1033,6 +1055,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
int bInventory = ai_GetWidgetButton(oPC, BTN_CMD_INVENTORY, oAssociate, sAssociateType);
int bBtnFamiliar = ai_GetWidgetButton(oPC, BTN_CMD_FAMILIAR, oAssociate, sAssociateType);
int bBtnCompanion = ai_GetWidgetButton(oPC, BTN_CMD_COMPANION, oAssociate, sAssociateType);
int bAssocWidgetOff = ai_GetWidgetButton(oPC, BTN_ASSOC_WIDGETS_OFF, oAssociate, sAssociateType);
int bVertical = ai_GetWidgetButton(oPC, BTN_WIDGET_VERTICAL, oAssociate, sAssociateType);
// Save the associate to the nui for use in 0e_nui
json jData = JsonArray();
@@ -1056,7 +1079,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
NuiSetBind(oPC, nToken, "btn_copy_settings_event", JsonBool (TRUE));
sText = " Copy AI and command settings for one creature to others.";
NuiSetBind(oPC, nToken, "btn_copy_settings_tooltip", JsonString(sText));
if(!AI_SERVER)
if(!ai_GetIsServer())
{
NuiSetBind(oPC, nToken, "btn_main_menu_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_main_menu_tooltip", JsonString(" Module Options"));
@@ -1102,6 +1125,17 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
NuiSetBind(oPC, nToken, "btn_vertical_widget_tooltip", JsonString(
" " + sName + " widget will display vertically"));
// Row 3
if(bIsPC && bUsingHenchAI)
{
NuiSetBind(oPC, nToken, "btn_toggle_assoc_widget_event", JsonBool(TRUE));
if(ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oPC, "pc")) sText = " Associate Widgets [Off]";
else sText = " Associate Widgets [On]";
NuiSetBind(oPC, nToken, "btn_toggle_assoc_widget_tooltip", JsonString(sText));
NuiSetBind(oPC, nToken, "chbx_toggle_assoc_widget_check", JsonBool (bAssocWidgetOff));
NuiSetBindWatch (oPC, nToken, "chbx_toggle_assoc_widget_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_toggle_assoc_widget_event", JsonBool(TRUE));
}
// Row 4
NuiSetBind(oPC, nToken, "chbx_cmd_action_check", JsonBool (bCmdAction));
NuiSetBindWatch(oPC, nToken, "chbx_cmd_action_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_cmd_action_event", JsonBool(TRUE));
@@ -1110,7 +1144,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
NuiSetBindWatch (oPC, nToken, "chbx_cmd_guard_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_cmd_guard_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_cmd_guard_event", JsonBool (TRUE));
// Row 4
// Row 5
NuiSetBind(oPC, nToken, "chbx_cmd_hold_check", JsonBool (bCmdHold));
NuiSetBindWatch (oPC, nToken, "chbx_cmd_hold_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_cmd_hold_event", JsonBool(TRUE));
@@ -1119,7 +1153,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
NuiSetBindWatch (oPC, nToken, "chbx_cmd_attack_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_cmd_attack_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_cmd_attack_event", JsonBool (TRUE));
// Row 5
// Row 6
NuiSetBind(oPC, nToken, "chbx_cmd_follow_check", JsonBool (bCmdFollow));
NuiSetBindWatch (oPC, nToken, "chbx_cmd_follow_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_cmd_follow_event", JsonBool(TRUE));
@@ -1128,7 +1162,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
NuiSetBindWatch (oPC, nToken, "chbx_follow_target_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_follow_target_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_follow_target_event", JsonBool (TRUE));
// Row 6
// Row 7
if(bIsPC)
{
NuiSetBind(oPC, nToken, "chbx_cmd_search_check", JsonBool (bCmdSearch));
@@ -1181,7 +1215,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
else sTarget = GetName(oPC);
}
NuiSetBind(oPC, nToken, "btn_follow_target_tooltip", JsonString(" " + GetName(oAssociate) + " following " + sTarget + " [" + sRange + " meters]"));
// Row 7
// Row 8
NuiSetBind(oPC, nToken, "chbx_cmd_ai_script_check", JsonBool (bCmdAIScript));
NuiSetBindWatch (oPC, nToken, "chbx_cmd_ai_script_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_cmd_ai_script_event", JsonBool(TRUE));
@@ -1214,7 +1248,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
NuiSetBind(oPC, nToken, "btn_cmd_place_trap_tooltip", JsonString (
" Place a trap at the location selected"));
}
// Row 8
// Row 9
NuiSetBind(oPC, nToken, "btn_quick_widget_event", JsonBool(TRUE));
NuiSetBind (oPC, nToken, "btn_quick_widget_tooltip", JsonString(
" Add/Remove abilities and spells from creatures widget"));
@@ -1233,7 +1267,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
NuiSetBind (oPC, nToken, "btn_spell_known_tooltip", JsonString(
" Change known spell list."));
}
// Row 9
// Row 10
NuiSetBind(oPC, nToken, "chbx_buff_short_check", JsonBool (bBuffShort));
NuiSetBindWatch (oPC, nToken, "chbx_buff_short_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_buff_short_event", JsonBool(TRUE));
@@ -1246,7 +1280,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
NuiSetBind(oPC, nToken, "btn_buff_long_event", JsonBool (TRUE));
NuiSetBind(oPC, nToken, "btn_buff_long_tooltip", JsonString (
" Buff the party with long duration spells"));
// Row 10
// Row 11
NuiSetBind(oPC, nToken, "chbx_buff_all_check", JsonBool (bBuffAll));
NuiSetBindWatch (oPC, nToken, "chbx_buff_all_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_buff_all_event", JsonBool(TRUE));
@@ -1263,7 +1297,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
else sText = " [Off] Turn buffing after resting on";
NuiSetBind (oPC, nToken, "btn_buff_rest_tooltip", JsonString (sText));
}
// Row 11
// Row 12
NuiSetBind(oPC, nToken, "chbx_jump_to_check", JsonBool(bJumpTo));
NuiSetBindWatch (oPC, nToken, "chbx_jump_to_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_jump_to_event", JsonBool(TRUE));
@@ -1283,7 +1317,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
if(ai_GetAIMode(oAssociate, AI_MODE_GHOST)) sText = "Off";
NuiSetBind(oPC, nToken, "btn_ghost_mode_tooltip", JsonString (
" Turn " + sText + " clipping through creatures for " + GetName(oAssociate)));
// Row 12
// Row 13
NuiSetBind(oPC, nToken, "chbx_camera_check", JsonBool (bCamera));
NuiSetBindWatch (oPC, nToken, "chbx_camera_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_camera_event", JsonBool(TRUE));
@@ -1296,7 +1330,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
NuiSetBind(oPC, nToken, "btn_inventory_event", JsonBool (TRUE));
NuiSetBind(oPC, nToken, "btn_inventory_tooltip", JsonString (
" Open " + sName + " inventory"));
// Row 13 & 14
// Row 14 & 15
if(bFamiliar)
{
NuiSetBind(oPC, nToken, "chbx_familiar_check", JsonBool(bBtnFamiliar));
@@ -1322,7 +1356,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
NuiSetBind(oPC, nToken, "lbl_familiar_name_label", JsonString("Familiar name"));
}
}
// Row 15 & 16
// Row 16 & 17
if(bCompanion)
{
NuiSetBind(oPC, nToken, "chbx_companion_check", JsonBool(bBtnCompanion));
@@ -1350,7 +1384,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
}
if(bIsPC)
{
// Row 17+
// Row 18+
int nIndex, bWidget;
string sButton, sText;
json jPlugin = JsonArrayGet(jPCPlugins, nIndex);
@@ -1371,7 +1405,7 @@ void ai_CreateAssociateCommandNUI(object oPC, object oAssociate)
}
NuiSetBind(oPC, nToken, "chbx_plugin_tooltip", JsonString(" Adds the plugin to your widget."));
}
// Row 18
// Row 19+
sText = ai_GetRandomTip();
NuiSetBind(oPC, nToken, "lbl_info_1_label", JsonString(sText));
}
@@ -1393,7 +1427,8 @@ void ai_CreateAssociateAINUI(object oPC, object oAssociate)
if(bIsPC)
{
bRight = GetLocalInt(GetModule(), sDMWidgetAccessVarname) != 7340028;
if(!AI_SERVER || bRight)
bLeft = ai_GetIsServer();
if(!bLeft || bRight)
{
// If all the Command buttons are blocked then don't load the menu.
if(bRight)
@@ -1402,10 +1437,10 @@ void ai_CreateAssociateAINUI(object oPC, object oAssociate)
jRow = CreateLabel(jRow, "", "blank_label_2", 25.0, 20.0);
}
jRow = JsonArrayInsert(jRow, NuiSpacer());
if(!AI_SERVER)
if(!bLeft)
{
CreateButton(jRow, "Main Menu", "btn_main_menu", 200.0, 20.0, -1.0, "btn_main_menu_tooltip");
CreateLabel(jRow, "", "blank_label_2", 25.0, 20.0);
jRow = CreateButton(jRow, "Main Menu", "btn_main_menu", 200.0, 20.0, -1.0, "btn_main_menu_tooltip");
jRow = CreateLabel(jRow, "", "blank_label_2", 25.0, 20.0);
}
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight += 28.0;
@@ -1724,7 +1759,7 @@ void ai_CreateAssociateAINUI(object oPC, object oAssociate)
}
// Set the Layout of the window.
json jLayout = NuiCol(jCol);
string sText, sName = GetName(oAssociate);
string sText, sName = ai_StripColorCodes(GetName(oAssociate));
if(GetStringRight(sName, 1) == "s") sName = sName + "'";
else sName = sName + "'s";
int nToken = SetWindow(oPC, jLayout, sAssociateType + AI_NUI, sName + " AI Menu",
@@ -1767,7 +1802,7 @@ void ai_CreateAssociateAINUI(object oPC, object oAssociate)
if(bIsPC)
{
bRight = GetLocalInt(GetModule(), sDMWidgetAccessVarname) != 7340028;
if(!AI_SERVER || bRight)
if(!ai_GetIsServer() || bRight)
{
// If all the Command buttons are blocked then don't load the menu.
if(bRight)
@@ -1775,7 +1810,7 @@ void ai_CreateAssociateAINUI(object oPC, object oAssociate)
NuiSetBind(oPC, nToken, "btn_command_menu_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_command_menu_tooltip", JsonString(" " + sName + " Command options"));
}
if(!AI_SERVER)
if(!ai_GetIsServer())
{
NuiSetBind(oPC, nToken, "btn_main_menu_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_main_menu_tooltip", JsonString(" Module Options"));
@@ -2028,8 +2063,20 @@ void ai_SetWidgetBinds(object oPC, object oAssociate, string sAssociateType, int
NuiSetBind(oPC, nToken, "btn_open_main_image", JsonString(GetPortraitResRef(oAssociate) + "s"));
NuiSetBind(oPC, nToken, "btn_open_main_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_open_main_tooltip", JsonString(" " + sName + " widget menu"));
if(ai_GetWidgetButton(oPC, BTN_ASSOC_WIDGETS_OFF, oAssociate, sAssociateType))
{
NuiSetBind(oPC, nToken, "btn_toggle_assoc_widget_event", JsonBool(TRUE));
if(ai_GetWidgetButton(oPC, BTN_WIDGET_OFF, oPC, "pc")) sText = " Associate Widgets [Off]";
else sText = " Associate Widgets [On]";
NuiSetBind(oPC, nToken, "btn_toggle_assoc_widget_tooltip", JsonString(sText));
}
if(bIsPC) sText = " All associates";
else sText = " " + GetName(oAssociate);
if(ai_GetWidgetButton(oPC, BTN_CMD_CAMERA, oAssociate, sAssociateType))
{
NuiSetBind(oPC, nToken, "btn_camera_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_camera_tooltip", JsonString(" Toggle camera view for " + sName));
}
if(ai_GetWidgetButton(oPC, BTN_CMD_ACTION, oAssociate, sAssociateType))
{
NuiSetBind(oPC, nToken, "btn_cmd_action_event", JsonBool(TRUE));
@@ -2196,11 +2243,6 @@ void ai_SetWidgetBinds(object oPC, object oAssociate, string sAssociateType, int
NuiSetBind(oPC, nToken, "btn_ghost_mode_tooltip", JsonString (
" Turn " + sText + " clipping through creatures for " + GetName(oAssociate)));
}
if(ai_GetWidgetButton(oPC, BTN_CMD_CAMERA, oAssociate, sAssociateType))
{
NuiSetBind(oPC, nToken, "btn_camera_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_camera_tooltip", JsonString(" Toggle camera view for " + sName));
}
if(ai_GetWidgetButton(oPC, BTN_CMD_INVENTORY, oAssociate, sAssociateType))
{
NuiSetBind(oPC, nToken, "btn_inventory_event", JsonBool(TRUE));
@@ -2689,6 +2731,16 @@ void ai_CreateWidgetNUI(object oPC, object oAssociate)
jButton = NuiTooltip(jButton, NuiBind ("btn_open_main_tooltip"));
jButton = NuiImageRegion(jButton, NuiRect(0.0, 0.0, 32.0, 35.0));
json jRow = JsonArrayInsert(JsonArray(), jButton);
if(ai_GetWidgetButton(oPC, BTN_ASSOC_WIDGETS_OFF, oAssociate, sAssociateType))
{
jRow = CreateButtonImage(jRow, "ir_invite", "btn_toggle_assoc_widget", 35.0f, 35.0f, 0.0, "btn_toggle_assoc_widget_tooltip");
fButtons += 1.0;
}
if(ai_GetWidgetButton(oPC, BTN_CMD_CAMERA, oAssociate, sAssociateType))
{
jRow = CreateButtonImage(jRow, "ir_examine", "btn_camera", 35.0f, 35.0f, 0.0, "btn_camera_tooltip");
fButtons += 1.0;
}
if(ai_GetWidgetButton(oPC, BTN_CMD_ACTION, oAssociate, sAssociateType))
{
jRow = CreateButtonImage(jRow, "ir_action", "btn_cmd_action", 35.0f, 35.0f, 0.0, "btn_cmd_action_tooltip");
@@ -2772,11 +2824,6 @@ void ai_CreateWidgetNUI(object oPC, object oAssociate)
jRow = CreateButtonImage(jRow, "dm_limbo", "btn_ghost_mode", 35.0f, 35.0f, 0.0, "btn_ghost_mode_tooltip");
fButtons += 1.0;
}
if(ai_GetWidgetButton(oPC, BTN_CMD_CAMERA, oAssociate, sAssociateType))
{
jRow = CreateButtonImage(jRow, "ir_examine", "btn_camera", 35.0f, 35.0f, 0.0, "btn_camera_tooltip");
fButtons += 1.0;
}
if(ai_GetWidgetButton(oPC, BTN_CMD_INVENTORY, oAssociate, sAssociateType))
{
jRow = CreateButtonImage(jRow, "ir_pickup", "btn_inventory", 35.0f, 35.0f, 0.0, "btn_inventory_tooltip");
@@ -3149,7 +3196,7 @@ void ai_CreateWidgetNUI(object oPC, object oAssociate)
json jLayout;
int nToken, bBool;
string sHeal, sText, sRange;
string sName = GetName(oAssociate);
string sName = ai_StripColorCodes(GetName(oAssociate));
if(GetStringRight(sName, 1) == "s") sName = sName + "'";
else sName = sName + "'s";
if(bVertical)
@@ -3294,7 +3341,7 @@ void ai_CreateLootFilterNUI(object oPC, object oAssociate)
}
// Set the Layout of the window.
json jLayout = NuiCol(jCol);
string sText, sName = GetName(oAssociate);
string sText, sName = ai_StripColorCodes(GetName(oAssociate));
if(GetStringRight(sName, 1) == "s") sName = sName + "'";
else sName = sName + "'s";
int nToken = SetWindow(oPC, jLayout, sAssociateType + AI_LOOTFILTER_NUI, sName + " Loot Filter",
@@ -3372,7 +3419,7 @@ void ai_CreateCopySettingsNUI(object oPC, object oAssociate)
DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE));
// ************************************************************************* Width / Height
// Row 1 ******************************************************************* 244 / 73
string sName = GetName(oAssociate);
string sName = ai_StripColorCodes(GetName(oAssociate));
if(GetStringRight(sName, 1) == "s") sName = sName + "'";
else sName = sName + "'s";
json jRow = JsonArrayInsert(JsonArray(), NuiSpacer());
@@ -3539,7 +3586,7 @@ void ai_CreatePluginNUI(object oPC)
}
// Set the Layout of the window.
json jLayout = NuiCol(jCol);
sName = GetName(oPC);
sName = ai_StripColorCodes(GetName(oPC));
if(GetStringRight(sName, 1) == "s") sName = sName + "'";
else sName = sName + "'s";
int nToken = SetWindow(oPC, jLayout, AI_PLUGIN_NUI, sName + " PEPS Plugin Manager",
@@ -3814,7 +3861,7 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate)
}
// Set the Layout of the window.
json jLayout = NuiCol(jCol);
string sText, sName = GetName(oAssociate);
string sText, sName = ai_StripColorCodes(GetName(oAssociate));
if(GetStringRight(sName, 1) == "s") sName = sName + "'";
else sName = sName + "'s";
int nToken = SetWindow(oPC, jLayout, sAssociateType + AI_QUICK_WIDGET_NUI, sName + " Quick Widget Menu",
@@ -4003,72 +4050,70 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate)
// Special abilities and skills.
else if(nLevel == 10)
{
for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex++)
json jCreature = ObjectToJson(oAssociate);
json jFeatList = GffGetList(jCreature, "FeatList");
int nIndex, nSuccessor;
json jFeat = JsonArrayGet(jFeatList, nIndex);
while(JsonGetType(jFeat) != JSON_TYPE_NULL)
{
nClassIndex = GetClassByPosition(nIndex, oAssociate);
if(nClassIndex != CLASS_TYPE_INVALID)
nFeat = JsonGetInt(GffGetWord(jFeat, "Feat"));
if(Get2DAString("feat", "USESPERDAY", nFeat) != "" ||
Get2DAString("feat", "HostileFeat", nFeat) != "")
{
nCounter = 0;
sClassFeats = Get2DAString("classes", "FeatsTable", nClassIndex);
nMax2daRow = Get2DARowCount(sClassFeats);
while(nCounter < nMax2daRow)
// Check for subfeats.
nSpell = StringToInt(Get2DAString("feat", "SPELLID", nFeat));
nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell1", nSpell));
//SendMessageToPC(oPC, "nFeat: " + IntToString(nFeat) +
// " nSpell: " + IntToString(nSpell) +
// " nSubSpell: " + IntToString(nSubSpell));
if(nSubSpell)
{
if(Get2DAString(sClassFeats, "OnMenu", nCounter) != "0")
for(nSubSpellIndex = 1; nSubSpellIndex <= 5; nSubSpellIndex++)
{
nFeat = StringToInt(Get2DAString(sClassFeats, "FeatIndex", nCounter));
if(GetHasFeat(nFeat, oAssociate, TRUE))
sSubSpellIndex = IntToString(nSubSpellIndex);
nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell" + sSubSpellIndex, nSpell));
//SendMessageToPC(oPC, " nSpell: " + IntToString(nSpell) +
// " nSubSpell: " + IntToString(nSubSpell));
if(nSubSpell != 0)
{
// Check for subfeats.
nSpell = StringToInt(Get2DAString("feat", "SPELLID", nFeat));
nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell1", nSpell));
//SendMessageToPC(oPC, "nFeat: " + IntToString(nFeat) +
// " nSpell: " + IntToString(nSpell) +
// " nSubSpell: " + IntToString(nSubSpell));
if(nSubSpell)
{
for(nSubSpellIndex = 1; nSubSpellIndex <= 5; nSubSpellIndex++)
{
sSubSpellIndex = IntToString(nSubSpellIndex);
nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell" + sSubSpellIndex, nSpell));
//SendMessageToPC(oPC, " nSpell: " + IntToString(nSpell) +
// " nSubSpell: " + IntToString(nSubSpell));
if(nSubSpell != 0)
{
sSpellIcon = Get2DAString("spells", "iConResRef", nSubSpell);
jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon));
sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSubSpell)));
jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName));
jSpell = JsonArray();
jSpell = JsonArrayInsert(jSpell, JsonInt(nSubSpell));
jSpell = JsonArrayInsert(jSpell, JsonInt(nClass));
jSpell = JsonArrayInsert(jSpell, JsonInt(-1)); // Level
jSpell = JsonArrayInsert(jSpell, JsonInt(255)); // MetaMagic
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Domain
jSpell = JsonArrayInsert(jSpell, JsonInt(nFeat));
jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell);
}
}
}
else if((nFeat < 71 || nFeat > 81))
{
sSpellIcon = Get2DAString("feat", "ICON", nFeat);
jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon));
sSpellName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat)));
jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName));
jSpell = JsonArray();
jSpell = JsonArrayInsert(jSpell, JsonInt(nSpell));
jSpell = JsonArrayInsert(jSpell, JsonInt(nClass));
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Level
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // MetaMagic
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Domain
jSpell = JsonArrayInsert(jSpell, JsonInt(nFeat));
jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell);
}
sSpellIcon = Get2DAString("spells", "iConResRef", nSubSpell);
jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon));
sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSubSpell)));
jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName));
jSpell = JsonArray();
jSpell = JsonArrayInsert(jSpell, JsonInt(nSubSpell));
jSpell = JsonArrayInsert(jSpell, JsonInt(nClass));
jSpell = JsonArrayInsert(jSpell, JsonInt(-1)); // Level
jSpell = JsonArrayInsert(jSpell, JsonInt(255)); // MetaMagic
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Domain
jSpell = JsonArrayInsert(jSpell, JsonInt(nFeat));
jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell);
}
}
nCounter++;
}
else if((nFeat < 71 || nFeat > 81))
{
nSuccessor = StringToInt(Get2DAString("feat", "SUCCESSOR", nFeat));
if(nSuccessor && GetHasFeat(nSuccessor, oAssociate, TRUE))
{ /* Don't do anything we just skip adding this feat. */}
else
{
sSpellIcon = Get2DAString("feat", "ICON", nFeat);
jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon));
sSpellName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat)));
jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName));
jSpell = JsonArray();
jSpell = JsonArrayInsert(jSpell, JsonInt(nSpell));
jSpell = JsonArrayInsert(jSpell, JsonInt(nClass));
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Level
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // MetaMagic
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Domain
jSpell = JsonArrayInsert(jSpell, JsonInt(nFeat));
jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell);
}
}
}
jFeat = JsonArrayGet(jFeatList, ++nIndex);
}
// Checks for monsters special abilities.
int nCounter = 0, nPreviousSpell = -1, nMaxSpellAbility = GetSpellAbilityCount(oAssociate);
@@ -4340,7 +4385,13 @@ void ai_CreateSpellMemorizationNUI(object oPC, object oAssociate)
jAIData = JsonArraySet(jAIData, 10, jSpells);
ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData);
}
if(nClassSelected < 1 || nClassSelected > AI_MAX_CLASSES_PER_CHARACTER) nClassSelected = 1;
if(nClassSelected < 1 || nClassSelected > AI_MAX_CLASSES_PER_CHARACTER)
{
nClassSelected = 1;
jSpells = JsonArraySet(jSpells, 0, JsonInt(1));
jAIData = JsonArraySet(jAIData, 10, jSpells);
ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData);
}
nClass = GetClassByPosition(nClassSelected, oAssociate);
int nMaxMemorizationSlots = GetMemorizedSpellCountByLevel(oAssociate, nClass, nLevelSelected);
jRow = JsonArray();
@@ -4372,7 +4423,7 @@ void ai_CreateSpellMemorizationNUI(object oPC, object oAssociate)
fX = JsonGetFloat(JsonObjectGet(jLocations, "x"));
fY = JsonGetFloat(JsonObjectGet(jLocations, "y"));
}
string sText, sName = GetName(oAssociate);
string sText, sName = ai_StripColorCodes(GetName(oAssociate));
if(GetStringRight(sName, 1) == "s") sName = sName + "'";
else sName = sName + "'s";
// Set the Layout of the window.
@@ -4637,7 +4688,13 @@ void ai_CreateSpellKnownNUI(object oPC, object oAssociate)
jAIData = JsonArraySet(jAIData, 10, jSpells);
ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData);
}
if(nClassSelected < 1 || nClassSelected > AI_MAX_CLASSES_PER_CHARACTER) nClassSelected = 1;
if(nClassSelected < 1 || nClassSelected > AI_MAX_CLASSES_PER_CHARACTER)
{
nClassSelected = 1;
jSpells = JsonArraySet(jSpells, 0, JsonInt(1));
jAIData = JsonArraySet(jAIData, 10, jSpells);
ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData);
}
nClass = GetClassByPosition(nClassSelected, oAssociate);
jRow = JsonArray();
for(nIndex = 0; nIndex < 10; nIndex++)
@@ -4688,7 +4745,7 @@ void ai_CreateSpellKnownNUI(object oPC, object oAssociate)
fX = JsonGetFloat(JsonObjectGet(jLocations, "x"));
fY = JsonGetFloat(JsonObjectGet(jLocations, "y"));
}
string sText, sName = GetName(oAssociate);
string sText, sName = ai_StripColorCodes(GetName(oAssociate));
if(GetStringRight(sName, 1) == "s") sName = sName + "'";
else sName = sName + "'s";
// Set the Layout of the window.

View File

@@ -268,7 +268,7 @@ void ai_CreateDMOptionsNUI(object oPC)
int nMonsterAI = (ResManGetAliasFor("ai_default", RESTYPE_NCS) != "");
int nAssociateAI = (ResManGetAliasFor("ai_a_default", RESTYPE_NCS) != "");
string sText = " [Single player]";
if(AI_SERVER) sText = " [Server]";
if(ai_GetIsServer()) sText = " [Server]";
// ************************************************************************* Width / Height
// Row 1 ******************************************************************* 500 / 73
json jRow = JsonArrayInsert(JsonArray(), NuiSpacer());
@@ -876,6 +876,9 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
jRow = CreateLabel(JsonArray(), "Having a check next to a button will remove that button from the players menus.", "lbl_info2", 636.0, 15.0);
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 4 ******************************************************************* 575 / 162
jRow = CreateButtonImage(jRow, "ir_invite", "btn_toggle_assoc_widget", 35.0f, 35.0f, 0.0, "btn_toggle_assoc_widget_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_toggle_assoc_widget", 25.0, 20.0, "btn_toggle_assoc_widget_tooltip");
jRow = CreateButtonImage(JsonArray(), "ir_action", "btn_cmd_action", 35.0f, 35.0f, 0.0, "btn_cmd_action_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_cmd_action", 25.0, 20.0, "btn_cmd_action_tooltip");
@@ -903,10 +906,11 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
jRow = CreateButtonImage(jRow, "ir_scommand", "btn_cmd_ai_script", 35.0f, 35.0f, 0.0, "btn_cmd_ai_script_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_cmd_ai_script", 25.0, 20.0, "btn_cmd_ai_script_tooltip");
jRow = CreateButtonImage(jRow, "isk_settrap", "btn_cmd_place_trap", 35.0f, 35.0f, 0.0, "btn_cmd_place_trap_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_cmd_place_trap", 25.0, 20.0, "btn_cmd_place_trap_tooltip");
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 5 ******************************************************************* 575 / 205
jRow = CreateButtonImage(jRow, "isk_settrap", "btn_cmd_place_trap", 35.0f, 35.0f, 0.0, "btn_cmd_place_trap_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_cmd_place_trap", 25.0, 20.0, "btn_cmd_place_trap_tooltip");
jRow = CreateButtonImage(JsonArray(), "isk_spellcraft", "btn_quick_widget", 35.0f, 35.0f, 0.0, "btn_quick_widget_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_quick_widget", 25.0, 20.0, "btn_quick_widget_tooltip");
@@ -934,10 +938,10 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
jRow = CreateButtonImage(jRow, "ir_examine", "btn_camera", 35.0f, 35.0f, 0.0, "btn_camera_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_camera", 25.0, 20.0, "btn_camera_tooltip");
jRow = CreateButtonImage(jRow, "ir_pickup", "btn_inventory", 35.0f, 35.0f, 0.0, "btn_inventory_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_inventory", 25.0, 20.0, "btn_inventory_tooltip");
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 6 ******************************************************************* 575 / 248
jRow = CreateButtonImage(jRow, "ir_pickup", "btn_inventory", 35.0f, 35.0f, 0.0, "btn_inventory_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_inventory", 25.0, 20.0, "btn_inventory_tooltip");
jRow = CreateButtonImage(JsonArray(), "ife_familiar", "btn_familiar", 35.0f, 35.0f, 0.0, "btn_familiar_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_familiar", 25.0, 20.0, "btn_familiar_tooltip");
@@ -966,10 +970,10 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
jRow = CreateButtonImage(jRow, "ir_open", "btn_open_door", 35.0f, 35.0f, 0.0, "btn_open_door_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_open_door", 25.0, 20.0, "btn_open_door_tooltip");
jRow = CreateButtonImage(jRow, "isk_distrap", "btn_traps", 35.0f, 35.0f, 0.0, "btn_traps_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_traps", 25.0, 20.0, "btn_traps_tooltip");
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 7 ******************************************************************* 575 / 291
jRow = CreateButtonImage(jRow, "isk_distrap", "btn_traps", 35.0f, 35.0f, 0.0, "btn_traps_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_traps", 25.0, 20.0, "btn_traps_tooltip");
jRow = CreateButtonImage(JsonArray(), "isk_olock", "btn_pick_locks", 35.0f, 35.0f, 0.0, "btn_pick_locks_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_pick_locks", 25.0, 20.0, "btn_pick_locks_tooltip");
@@ -998,10 +1002,11 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
jRow = CreateButtonImage(jRow, "isk_heal", "btn_heal_out", 35.0f, 35.0f, 0.0, "btn_heal_out_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_heal_out", 25.0, 20.0, "btn_heal_out_tooltip");
jRow = CreateButtonImage(jRow, "dm_heal", "btn_heal_in", 35.0f, 35.0f, 0.0, "btn_heal_in_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_heal_in", 25.0, 20.0, "btn_heal_in_tooltip");
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 8 ******************************************************************* 575 / 334
jRow = CreateButtonImage(jRow, "dm_heal", "btn_heal_in", 35.0f, 35.0f, 0.0, "btn_heal_in_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_heal_in", 25.0, 20.0, "btn_heal_in_tooltip");
jRow = CreateButtonImage(JsonArray(), "ir_heal", "btn_heals_onoff", 35.0f, 35.0f, 0.0, "btn_heals_onoff_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_heals_onoff", 25.0, 20.0, "btn_heals_onoff_tooltip");
@@ -1023,7 +1028,6 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
jRow = CreateButtonImage(jRow, "ir_dmchat", "btn_perc_range", 35.0f, 35.0f, 0.0, "btn_perc_range_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_perc_range", 25.0, 20.0, "btn_perc_range_tooltip");
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
float fHeight = 334.0;
// Get the window location to restore it from the database.
@@ -1049,6 +1053,7 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
// Row 2 & 3 Labels.
// Load all the buttons states.
//int bAIWidgetLock = ai_GetDMWAccessButton(BTN_WIDGET_LOCK);
int bAssocWidgetOff = ai_GetDMWAccessButton(BTN_ASSOC_WIDGETS_OFF);
int bCmdAction = ai_GetDMWAccessButton(BTN_CMD_ACTION);
int bCmdGuard = ai_GetDMWAccessButton(BTN_CMD_GUARD);
int bCmdHold = ai_GetDMWAccessButton(BTN_CMD_HOLD);
@@ -1101,6 +1106,12 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
SetLocalInt(oPC, "CHBX_SKIP", TRUE);
DelayCommand(2.0, DeleteLocalInt(oPC, "CHBX_SKIP"));
// Row 4
NuiSetBind(oPC, nToken, "chbx_toggle_assoc_widget_check", JsonBool (bCmdAction));
NuiSetBindWatch(oPC, nToken, "chbx_toggle_assoc_widget_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_toggle_assoc_widget_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_toggle_assoc_widget_event", JsonBool (TRUE));
NuiSetBind(oPC, nToken, "btn_toggle_assoc_widget_tooltip", JsonString(" Associate widgets"));
NuiSetBind(oPC, nToken, "chbx_cmd_action_check", JsonBool (bCmdAction));
NuiSetBindWatch(oPC, nToken, "chbx_cmd_action_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_cmd_action_event", JsonBool(TRUE));
@@ -1154,13 +1165,13 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
NuiSetBind(oPC, nToken, "chbx_cmd_ai_script_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_cmd_ai_script_event", JsonBool (TRUE));
NuiSetBind(oPC, nToken, "btn_cmd_ai_script_tooltip", JsonString(" Combat Tactics button"));
// Row 5
NuiSetBind(oPC, nToken, "chbx_cmd_place_trap_check", JsonBool (bCmdPlacetrap));
NuiSetBindWatch (oPC, nToken, "chbx_cmd_place_trap_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_cmd_place_trap_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_cmd_place_trap_event", JsonBool (TRUE));
NuiSetBind(oPC, nToken, "btn_cmd_place_trap_tooltip", JsonString (" Place Trap button"));
// Row 5
NuiSetBind(oPC, nToken, "chbx_quick_widget_check", JsonBool (bSpellWidget));
NuiSetBindWatch (oPC, nToken, "chbx_quick_widget_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_quick_widget_event", JsonBool(TRUE));
@@ -1214,13 +1225,13 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
NuiSetBind(oPC, nToken, "chbx_camera_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_camera_event", JsonBool (TRUE));
NuiSetBind(oPC, nToken, "btn_camera_tooltip", JsonString(" Change Camera button"));
// Row 6
NuiSetBind(oPC, nToken, "chbx_inventory_check", JsonBool (bInventory));
NuiSetBindWatch (oPC, nToken, "chbx_inventory_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_inventory_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_inventory_event", JsonBool (TRUE));
NuiSetBind(oPC, nToken, "btn_inventory_tooltip", JsonString(" Open Inventory button"));
// Row 6
NuiSetBind(oPC, nToken, "chbx_familiar_check", JsonBool(bBtnFamiliar));
NuiSetBindWatch (oPC, nToken, "chbx_familiar_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_familiar_event", JsonBool(TRUE));
@@ -1274,13 +1285,13 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
NuiSetBind(oPC, nToken, "chbx_open_door_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_open_door_event", JsonBool(TRUE));
NuiSetBind (oPC, nToken, "btn_open_door_tooltip", JsonString(" Open Door button"));
// Row 7
NuiSetBind(oPC, nToken, "chbx_traps_check", JsonBool(bTraps));
NuiSetBindWatch (oPC, nToken, "chbx_traps_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_traps_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_traps_event", JsonBool(TRUE));
NuiSetBind (oPC, nToken, "btn_traps_tooltip", JsonString(" Disable Traps button"));
// Row 7
NuiSetBind(oPC, nToken, "chbx_pick_locks_check", JsonBool(bPickLocks));
NuiSetBindWatch(oPC, nToken, "chbx_pick_locks_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_pick_locks_event", JsonBool(TRUE));
@@ -1334,13 +1345,13 @@ void ai_CreateDMWidgetManagerNUI(object oPC)
NuiSetBind(oPC, nToken, "chbx_heal_out_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_heal_out_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_heal_out_tooltip", JsonString(" Heal Out of Combat button"));
// Row 8
NuiSetBind(oPC, nToken, "chbx_heal_in_check", JsonBool(bHealIn));
NuiSetBindWatch (oPC, nToken, "chbx_heal_in_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_heal_in_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_heal_in_event", JsonBool (TRUE));
NuiSetBind(oPC, nToken, "btn_heal_in_tooltip", JsonString(" Heal In Combat button"));
// Row 8
NuiSetBind(oPC, nToken, "chbx_heals_onoff_check", JsonBool(bSelfHealOnOff));
NuiSetBindWatch (oPC, nToken, "chbx_heals_onoff_check", TRUE);
NuiSetBind(oPC, nToken, "chbx_heals_onoff_event", JsonBool(TRUE));

View File

@@ -7,15 +7,18 @@
#include "x2_inc_switches"
#include "0i_associates"
#include "0i_menus"
#include "0i_menus_dm"
#include "0i_player_target"
#include "0i_gui_events"
// Add to nw_c2_default9 OnSpawn event script of monsters and
int ai_OnMonsterSpawn(object oCreature);
// Add to nw_ch_ac9 OnSpawn event script of henchman.
void ai_OnAssociateSpawn(object oCreature);
// Run all of the players starting scripts.
// Run all of the game setup scripts and build for PC.
// If oPC is passed as Invalid then it will get the firt PC in the game.
void ai_CheckPCStart(object oPC = OBJECT_INVALID);
// Run all of the games setup scripts and build for DM.
void ai_CheckDMStart(object oDM);
// Checks to see if we should change the monster via Json.
int ai_ChangeMonster(object oCreature, object oModule);
// Checks to see if we should change the associate via Json.
@@ -45,7 +48,7 @@ int ai_OnMonsterSpawn(object oCreature)
int nInfiniteDungeons;
int nPRC = GetLocalInt(oModule, AI_USING_PRC);
// If you are running a server this will not affect the module.
if(!AI_SERVER)
if(!ai_GetIsServer())
{
ai_CheckPCStart();
string sModuleName = GetModuleName();
@@ -107,7 +110,7 @@ void ai_OnAssociateSpawn(object oCreature)
SetLocalInt(oCreature, AI_ONSPAWN_EVENT, TRUE);
int bPRC = GetLocalInt(GetModule(), AI_USING_PRC);
// If you are running a server this will not affect the module.
if(!AI_SERVER)
if(!ai_GetIsServer())
{
if(bPRC) ai_SetPRCAssociateEventScripts(oCreature);
}
@@ -117,8 +120,17 @@ void ai_OnAssociateSpawn(object oCreature)
// We change this script so we can setup permanent summons on/off.
// If you don't use this you may remove the next three lines.
string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH);
SetLocalString(oCreature, "AI_ON_DEATH", sScript);
SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH, "0e_ch_7_ondeath");
// If our script is set in the OnDeath event then don't save as secondary.
if(sScript != "0e_ch_7_ondeath")
{
SetLocalString(oCreature, "AI_ON_DEATH", sScript);
SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_DEATH, "0e_ch_7_ondeath");
}
else if(GetLocalString(oCreature, "AI_ON_DEATH") == "0e_ch_7_ondeath")
{
// If we have somehow saved our death script then change to default.
SetLocalString(oCreature, "AI_ON_DEATH", "nw_ch_ac7");
}
}
// Initialize Associate modes for basic use.
ai_SetListeningPatterns(oCreature);
@@ -147,12 +159,28 @@ void ai_CheckPCStart(object oPC = OBJECT_INVALID)
ai_SetAIRules();
ai_CheckAssociateData(oPC, oPC, "pc");
ai_StartupPlugins(oPC);
ai_SetupPlayerTarget(oPC);
ai_SetupModuleGUIEvents(oPC);
ai_SetupPlayerTarget();
ai_SetupModuleGUIEvents();
ai_CreateWidgetNUI(oPC, oPC);
ai_SetNormalAppearance(oPC);
}
}
void ai_CheckDMStart(object oDM)
{
if(!NuiFindWindow(oDM, "dm" + AI_WIDGET_NUI))
{
object oModule = GetModule();
// Do PRC check and save variable to the module.
if(ResManGetAliasFor("prc_ai_fam_percp", RESTYPE_NCS) != "")
SetLocalInt(oModule, AI_USING_PRC, TRUE);
ai_SetAIRules();
ai_CheckDMData(oDM);
ai_StartupPlugins(oDM);
ai_SetupPlayerTarget();
ai_SetupModuleGUIEvents();
ai_CreateDMWidgetNUI(oDM);
}
}
void ai_CopyMonster(object oCreature, object oModule)
{
// After setting the monster lets see if we should copy it.
@@ -188,6 +216,12 @@ void ai_CreateMonster(json jCreature, location lLocation, object oModule)
} */
if(AI_DEBUG) ai_Debug("0i_module", "187", GetName(oCreature));
ai_CopyMonster(oCreature, oModule);
// This is a hak to allow wild shaped creatures to be able to attack!
if(GetHasFeat(FEAT_WILD_SHAPE, oCreature))
{
AssignCommand(oCreature, ActionUseFeat(FEAT_WILD_SHAPE, oCreature, SUBFEAT_WILD_SHAPE_BADGER));
DelayCommand(4.0, ai_RemoveASpecificEffect(oCreature, EFFECT_TYPE_POLYMORPH));
}
return;
}
json ai_SetCompanionSummoning(object oCreature, json jCreature)
@@ -198,7 +232,7 @@ json ai_SetCompanionSummoning(object oCreature, json jCreature)
jFamiliar = JsonObjectSet(jFamiliar, "value", JsonString("Summoned Familiar"));
jCreature = JsonObjectSet(jCreature, "FamiliarName", jFamiliar);
jFamiliar = JsonObjectGet(jCreature, "FamiliarType");
jFamiliar = JsonObjectSet(jFamiliar, "value", JsonInt(Random(11)));
jFamiliar = JsonObjectSet(jFamiliar, "value", JsonInt(10)); //JsonInt(Random(11)));
return JsonObjectSet(jCreature, "FamiliarType", jFamiliar);
}
if(GetHasFeat(FEAT_ANIMAL_COMPANION , oCreature, TRUE))
@@ -217,9 +251,9 @@ int ai_ChangeMonster(object oCreature, object oModule)
object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oCreature);
// Lets not mess up the cutscenes with silly RULES.
if(GetCutsceneMode(oPC)) return FALSE;
//float fDistance = GetDistanceBetween(oCreature, oPC);
float fDistance = GetDistanceBetween(oCreature, oPC);
// Looks bad to see creatures wink in and out plus could cause module errors.
//if(fDistance != 0.0 && fDistance < AI_RANGE_PERCEPTION) return oCreature;
if(fDistance != 0.0 && fDistance < 20.0) return FALSE;
if(IsInConversation(oCreature)) return FALSE;
json jCreature = ObjectToJson(oCreature, TRUE);
// We now use plugins to mod our monsters.
@@ -238,8 +272,8 @@ int ai_ChangeMonster(object oCreature, object oModule)
jCreature = GetLocalJson(oModule, AI_MONSTER_JSON);
}
int nSummon = GetLocalInt(oModule, AI_RULE_SUMMON_COMPANIONS) &&
(GetHasFeat(FEAT_SUMMON_FAMILIAR, oCreature, TRUE)) ||
GetHasFeat(FEAT_ANIMAL_COMPANION, oCreature, TRUE);
(GetHasFeat(FEAT_SUMMON_FAMILIAR, oCreature, TRUE) ||
GetHasFeat(FEAT_ANIMAL_COMPANION, oCreature, TRUE));
int nPercDist = GetLocalInt(oModule, AI_RULE_MON_PERC_DISTANCE) != 11 &&
GetReputation(oCreature, oPC) < 11;
//WriteTimestampedLogEntry(GetName(oCreature) + ": fDistance: " + FloatToString(fDistance, 0, 2) + " nSummon: " + IntToString(nSummon) +
@@ -256,6 +290,7 @@ int ai_ChangeMonster(object oCreature, object oModule)
if(nSummon) jCreature = ai_SetCompanionSummoning(oCreature, jCreature);
SetLocalInt(oModule, AI_MONSTER_CHANGED, TRUE);
}
// Did any of the Monster mods get used? These are done in independent mod scripts.
if(GetLocalInt(oModule, AI_MONSTER_CHANGED))
{
SetIsDestroyable(TRUE, FALSE, FALSE, oCreature);
@@ -268,11 +303,18 @@ int ai_ChangeMonster(object oCreature, object oModule)
else ai_CopyMonster(oCreature, oModule);
DeleteLocalJson(oModule, AI_MONSTER_JSON);
DeleteLocalObject(oModule, AI_MONSTER_OBJECT);
// This is a hak to allow wild shaped creatures to be able to attack!
if(GetHasFeat(FEAT_WILD_SHAPE))
{
AssignCommand(oCreature, ActionUseFeat(FEAT_WILD_SHAPE, oCreature, SUBFEAT_WILD_SHAPE_BADGER));
DelayCommand(4.0, ai_RemoveASpecificEffect(oCreature, EFFECT_TYPE_POLYMORPH));
}
return FALSE;
}
// Special event scripts for Infinite Dungeons!
void ai_SetIDMonsterEventScripts(object oCreature)
{
if(GetIsPC(oCreature)) return;
//if(AI_DEBUG) ai_Debug("0i_module", "433", "Changing " + GetName(oCreature) + "'s Infinte Dungeons event scripts.");
//********** On Heartbeat **********
string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT);
@@ -355,6 +397,7 @@ void ai_SetIDMonsterEventScripts(object oCreature)
// Special event scripts for Infinite Dungeons with PRC!
void ai_SetPRCIDMonsterEventScripts(object oCreature)
{
if(GetIsPC(oCreature)) return;
//if(AI_DEBUG) ai_Debug("0i_module", "433", "Changing " + GetName(oCreature) + "'s Infinte Dungeons event scripts for PRC.");
//********** On Heartbeat **********
string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT);
@@ -437,6 +480,7 @@ void ai_SetPRCIDMonsterEventScripts(object oCreature)
// Special event scripts for PRC associates!
void ai_SetPRCAssociateEventScripts(object oCreature)
{
if(GetIsPC(oCreature)) return;
//if(AI_DEBUG) ai_Debug("0i_module", "433", "Changing " + GetName(oCreature) + "'s Infinte Dungeons event scripts for PRC.");
//********** On Heartbeat **********
string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT);
@@ -494,6 +538,7 @@ void ai_SetPRCAssociateEventScripts(object oCreature)
}
void ai_ChangeEventScriptsForMonster(object oCreature)
{
if(GetIsPC(oCreature)) return;
//********** On Heartbeat **********
string sScript = GetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT);
if(sScript == "0e_c2_1_hb") SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "nw_c2_default1");
@@ -528,6 +573,7 @@ void ai_ChangeEventScriptsForMonster(object oCreature)
}
void ai_ChangeEventScriptsForAssociate(object oCreature)
{
if(GetIsPC(oCreature)) return;
SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT, "nw_ch_ac1");
SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_NOTICE, "nw_ch_ac2");
SetEventScript(oCreature, EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND, "nw_ch_ac3");

View File

@@ -8,7 +8,7 @@
#include "0i_menus"
// Setup an AI OnPlayerTarget Event script while allowing any module onplayer
// target event script to still work.
void ai_SetupPlayerTarget(object oCreature);
void ai_SetupPlayerTarget();
// Selects a target for oAssocite to follow.
void ai_AllSelectTarget(object oPC, object oAssociate, object oTarget);
// Removes the Cutscene ghosts and variables from all associates. For original AI scripts.
@@ -30,7 +30,7 @@ void ai_UpdateAssociateWidget(object oPC, object oAssociate);
// Sets oAssociates action mode for nFeat from the quick widget menu
int ai_SetActionMode(object oAssociate, int nFeat);
void ai_SetupPlayerTarget(object oCreature)
void ai_SetupPlayerTarget()
{
object oModule = GetModule();
string sModuleTargetEvent = GetEventScript(oModule, EVENT_SCRIPT_MODULE_ON_PLAYER_TARGET);
@@ -204,12 +204,14 @@ void ai_ActionAssociate(object oPC, object oTarget, location lLocation)
{
SetLocalString(oAssociate, AI_COMBAT_SCRIPT, GetLocalString(oAssociate, AI_DEFAULT_SCRIPT));
}
if(ai_GetIsInCombat(oAssociate)) ai_DoAssociateCombatRound(oAssociate, oTarget);
else
{
ai_HaveCreatureSpeak(oAssociate, 5, ":0:1:2:3:6:");
ai_StartAssociateCombat(oAssociate, oTarget);
}
//if(ai_GetIsInCombat(oAssociate)) ai_DoAssociateCombatRound(oAssociate, oTarget);
//else
//{
// ai_HaveCreatureSpeak(oAssociate, 5, ":0:1:2:3:6:");
// ai_StartAssociateCombat(oAssociate, oTarget);
//}
if(ai_GetIsRangeWeapon(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oAssociate))) ActionAttack(oTarget, TRUE);
else ActionAttack(oTarget);
ai_SendMessages(GetName(oAssociate) + " is attacking " + GetName(oTarget), AI_COLOR_RED, oPC);
}
else
@@ -317,6 +319,7 @@ void ai_SelectFollowTarget(object oPC, object oAssociate, object oTarget)
{
ai_SetAIMode(oAssociate, AI_MODE_FOLLOW, FALSE);
DeleteLocalObject(oAssociate, AI_FOLLOW_TARGET);
ClearAllActions(FALSE, oAssociate);
string sTarget;
if(ai_GetIsCharacter(oAssociate))
{
@@ -634,6 +637,7 @@ void ai_SelectWidgetSpellTarget(object oPC, object oAssociate, string sElem)
json jSpell = JsonArrayGet(jWidget, nIndex);
int nSpell = JsonGetInt(JsonArrayGet(jSpell, 0));
int nClass = JsonGetInt(JsonArrayGet(jSpell, 1));
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, oAssociate);
if(nClass == -1) // This is an Item.
{
object oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5)));
@@ -693,8 +697,7 @@ void ai_SelectWidgetSpellTarget(object oPC, object oAssociate, string sElem)
EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_ATTACK, MOUSECURSOR_NOATTACK);
}
// Check feat and adjust if it is an action mode feat.
if(ai_SetActionMode(oAssociate, nFeat)) return;
AssignCommand(oAssociate, ActionUseFeat(nFeat, oAssociate, nSpell));
if(!ai_SetActionMode(oAssociate, nFeat)) AssignCommand(oAssociate, ActionUseFeat(nFeat, oAssociate, nSpell));
DelayCommand(6.0, ai_UpdateAssociateWidget(oPC, oAssociate));
return;
}
@@ -702,7 +705,6 @@ void ai_SelectWidgetSpellTarget(object oPC, object oAssociate, string sElem)
}
else SetLocalString(oPC, AI_TARGET_MODE, "ASSOCIATE_CAST_SPELL");
}
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, oAssociate);
int nObjectType;
string sTarget = Get2DAString("spells", "TargetType", nSpell);
int nTarget = ai_HexStringToInt(sTarget);
@@ -784,6 +786,7 @@ int ai_SetActionMode(object oAssociate, int nFeat)
else if(nFeat == FEAT_EXPERTISE) nMode = ACTION_MODE_EXPERTISE;
else if(nFeat == FEAT_IMPROVED_EXPERTISE) nMode = ACTION_MODE_IMPROVED_EXPERTISE;
else if(nFeat == FEAT_DIRTY_FIGHTING) nMode = ACTION_MODE_DIRTY_FIGHTING;
else if(nFeat == FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE) nMode = 12; // ACTION_MODE_DEFENSIVE_STANCE
if(nMode)
{
SetActionMode(oAssociate, nMode, !GetActionMode(oAssociate, nMode));

View File

@@ -163,6 +163,12 @@ void ai_CastBuffs(object oCaster, int nBuffType, int nTarget, object oPC);
// Returns TRUE if oCaster cast spontaneous cure spell on oTarget.
// This uses an action and must use AssignCommand or OBJECT_SELF is the caster!
int ai_CastSpontaneousCure(object oCreature, object oTarget, object oPC);
// Returns TRUE if oCaster casts a memorized inflict spell on oTarget.
// This uses an action and must use AssignCommand or OBJECT_SELF is the caster!
int ai_CastMemorizedInflict(object oCreature, object oTarget, object oPC, int nClass);
// Returns TRUE if oCaster casts a known inflict spell on oTarget.
// This uses an action and must use AssignCommand or OBJECT_SELF is the caster!
int ai_CastKnownInflict(object oCreature, object oTarget, object oPC, int nClass);
// Returns TRUE if oCaster casts a memorized cure spell on oTarget.
// This uses an action and must use AssignCommand or OBJECT_SELF is the caster!
int ai_CastMemorizedHealing(object oCreature, object oTarget, object oPC, int nClass);
@@ -178,6 +184,8 @@ void ai_SpellConcentrationCheck(object oCaster);
int ai_CastInMelee(object oCreature, int nSpell, int nInMelee);
// Returns a float range for the caster to search for a target of an offensive spell.
float ai_GetOffensiveSpellSearchRange(object oCreature, int nSpell);
// Returns TRUE if nSpell is an inflict spell and will not over heal for nDamage.
int ai_ShouldWeCastThisInflictSpell(int nSpell, int nDamage);
// Returns TRUE if nSpell is a cure spell and will not over heal for nDamage.
int ai_ShouldWeCastThisCureSpell(int nSpell, int nDamage);
// Casts the spell on the current target for oAssociate.
@@ -394,73 +402,198 @@ int ai_GetIsSpellBookRestrictedCaster(object oAssociate)
}
return FALSE;
}
// This is used to set immunities on a creature not using the AI.
// Should only update every minute.
void ai_SetCreatureItemImmunities(object oCreature)
{
// Create an Immunity in json so we can check item immunities quickly for non-AI creatures.
SetLocalInt(oCreature, sIPTimeStampVarname, ai_GetCurrentTimeStamp());
if(AI_DEBUG) ai_Debug("0i_spells", "402", "Checking for Item immunities on " + GetName(oCreature));
int nSpellImmunity, bHasItemImmunity, nSlot;
json jImmunity = JsonArray();
DeleteLocalInt(oCreature, sIPImmuneVarname);
DeleteLocalInt(oCreature, sIPResistVarname);
DeleteLocalInt(oCreature, sIPReducedVarname);
int nIprpSubType, nSpell, nLevel, nIPType, nIndex;
itemproperty ipProp;
// Cycle through all the creatures equiped items.
object oItem = GetItemInSlot(nSlot, oCreature);
while(nSlot < 12)
{
if(oItem != OBJECT_INVALID)
{
if(AI_DEBUG) ai_Debug("0i_spells", "416", "Checking Item immunities on " + GetName(oItem));
ipProp = GetFirstItemProperty(oItem);
// Check for immunities on items.
while(GetIsItemPropertyValid(ipProp))
{
nIPType = GetItemPropertyType(ipProp);
if(AI_DEBUG) ai_Debug("0i_spells", "422", "ItempropertyType(53/20/23/22): " + IntToString(nIPType));
if(nIPType == ITEM_PROPERTY_IMMUNITY_SPECIFIC_SPELL)
{
bHasItemImmunity = TRUE;
nSpellImmunity = GetItemPropertyCostTableValue(ipProp);
nSpellImmunity = StringToInt(Get2DAString("iprp_spellcost", "SpellIndex", nSpellImmunity));
//if(AI_DEBUG) ai_Debug("0i_talents", "1950", "SpellImmunity to " + Get2DAString("spells", "Label", nSpellImmunity));
jImmunity = JsonArrayInsert(jImmunity, JsonInt(nSpellImmunity));
}
else if(nIPType == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE)
{
int nBit, nIpSubType = GetItemPropertySubType(ipProp);
if(AI_DEBUG) ai_Debug("0i_talents", "434", "Immune DmgType: nIPSubType: " + IntToString(nIpSubType));
if(nIpSubType == 0) nBit = DAMAGE_TYPE_BLUDGEONING;
else if(nIpSubType == 1) nBit = DAMAGE_TYPE_PIERCING;
else if(nIpSubType == 2) nBit = DAMAGE_TYPE_SLASHING;
else if(nIpSubType == 5) nBit = DAMAGE_TYPE_MAGICAL;
else if(nIpSubType == 6) nBit = DAMAGE_TYPE_ACID;
else if(nIpSubType == 7) nBit = DAMAGE_TYPE_COLD;
else if(nIpSubType == 8) nBit = DAMAGE_TYPE_DIVINE;
else if(nIpSubType == 9) nBit = DAMAGE_TYPE_ELECTRICAL;
else if(nIpSubType == 10) nBit = DAMAGE_TYPE_FIRE;
else if(nIpSubType == 11) nBit = DAMAGE_TYPE_NEGATIVE;
else if(nIpSubType == 12) nBit = DAMAGE_TYPE_POSITIVE;
else if(nIpSubType == 13) nBit = DAMAGE_TYPE_SONIC;
if(nBit > 0) ai_SetItemProperty(oCreature, sIPImmuneVarname, nBit, TRUE);
}
else if(nIPType == ITEM_PROPERTY_DAMAGE_RESISTANCE)
{
int nBit, nIpSubType = GetItemPropertySubType(ipProp);
if(AI_DEBUG) ai_Debug("0i_talents", "452", "Dmg Resist: nIPSubType: " + IntToString(nIpSubType));
if(nIpSubType == 0) nBit = DAMAGE_TYPE_BLUDGEONING;
else if(nIpSubType == 1) nBit = DAMAGE_TYPE_PIERCING;
else if(nIpSubType == 2) nBit = DAMAGE_TYPE_SLASHING;
else if(nIpSubType == 5) nBit = DAMAGE_TYPE_MAGICAL;
else if(nIpSubType == 6) nBit = DAMAGE_TYPE_ACID;
else if(nIpSubType == 7) nBit = DAMAGE_TYPE_COLD;
else if(nIpSubType == 8) nBit = DAMAGE_TYPE_DIVINE;
else if(nIpSubType == 9) nBit = DAMAGE_TYPE_ELECTRICAL;
else if(nIpSubType == 10) nBit = DAMAGE_TYPE_FIRE;
else if(nIpSubType == 11) nBit = DAMAGE_TYPE_NEGATIVE;
else if(nIpSubType == 12) nBit = DAMAGE_TYPE_POSITIVE;
else if(nIpSubType == 13) nBit = DAMAGE_TYPE_SONIC;
if(nBit > 0) ai_SetItemProperty(oCreature, sIPResistVarname, nBit, TRUE);
}
else if(nIPType == ITEM_PROPERTY_DAMAGE_REDUCTION)
{
int nIpSubType = GetItemPropertySubType(ipProp);
if(AI_DEBUG) ai_Debug("0i_talents", "470", "Dmg Reduction: nIPSubType: " + IntToString(nIpSubType));
SetLocalInt(oCreature, sIPReducedVarname, nIpSubType);
}
nIndex++;
ipProp = GetNextItemProperty(oItem);
}
// If nSpellImmunity has been set then we need to save our Immunity json.
if(bHasItemImmunity) SetLocalJson(oCreature, AI_TALENT_IMMUNITY, jImmunity);
}
oItem = GetItemInSlot(++nSlot, oCreature);
// Make the final check the creatures hide.
if(nSlot == 11) oItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oCreature);
}
}
int ai_CreatureImmuneToEffect(object oCaster, object oCreature, int nSpell)
{
// This checks for creatures not using the AI system (usually players).
// Creatures using the AI system will always have a value in sIPReducedVarname!
// Updates thier immunity values every minute. Should be good as we only update
// equiped items. Spell effects are checked on the creature and are not saved.
if(AI_DEBUG)
{
if(GetLocalInt(oCreature, sIPReducedVarname) == 0) ai_Debug("0i_spells", "492",
" Immunities last saved: " + IntToString(GetLocalInt(oCreature, sIPTimeStampVarname)) +
" + 60 < " + IntToString(ai_GetCurrentTimeStamp()));
}
if(GetLocalInt(oCreature, sIPReducedVarname) == 0 &&
GetLocalInt(oCreature, sIPTimeStampVarname) + 60 < ai_GetCurrentTimeStamp()) ai_SetCreatureItemImmunities(oCreature);
string sIType = Get2DAString("ai_spells", "ImmunityType", nSpell);
// Let us check if the creature is disabled while we look for immunities.
int nDisabled = ai_Disabled(oCreature);
if(AI_DEBUG) ai_Debug("0i_spells", "499", "Checking spell immunity type(" + sIType + ").");
if(sIType != "")
{
if(AI_DEBUG) ai_Debug("0i_spells", "290", "Checking spell immunity type(" + sIType + ").");
if(sIType == "Death" && GetIsImmune(oCreature, IMMUNITY_TYPE_DEATH)) return TRUE;
else if(sIType == "Level_Drain" && GetIsImmune(oCreature, IMMUNITY_TYPE_NEGATIVE_LEVEL)) return TRUE;
else if(sIType == "Ability_Drain" && GetIsImmune(oCreature, IMMUNITY_TYPE_ABILITY_DECREASE)) return TRUE;
else if(sIType == "Poison" && GetIsImmune(oCreature, IMMUNITY_TYPE_POISON)) return TRUE;
else if(sIType == "Disease" && GetIsImmune(oCreature, IMMUNITY_TYPE_DISEASE)) return TRUE;
else if(sIType == "Curse" && GetIsImmune(oCreature, IMMUNITY_TYPE_CURSED)) return TRUE;
else if(sIType == "Mind_Affecting" && GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS)) return TRUE;
else if(sIType == "Petrification" && ai_IsImmuneToPetrification(oCaster, oCreature)) return TRUE;
else if(sIType == "Mind_Affecting" &&
(GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
else if(sIType == "Petrification" &&
(ai_IsImmuneToPetrification(oCaster, oCreature) && nDisabled)) return TRUE;
else if(sIType == "Fear" &&
(GetIsImmune(oCreature, IMMUNITY_TYPE_FEAR) ||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
else if(sIType == "Sleep" &&
(GetIsImmune(oCreature, IMMUNITY_TYPE_SLEEP) ||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
else if(sIType == "Paralysis" &&
(GetIsImmune(oCreature, IMMUNITY_TYPE_PARALYSIS) ||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
else if(sIType == "Domination" &&
(GetIsImmune(oCreature, IMMUNITY_TYPE_DOMINATE) ||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
else if(sIType == "Confusion" &&
(GetIsImmune(oCreature, IMMUNITY_TYPE_CONFUSED) ||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
else if(sIType == "Blindness" &&
(GetIsImmune(oCreature, IMMUNITY_TYPE_BLINDNESS) ||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || ai_GetHasEffectType(oCreature, EFFECT_TYPE_BLINDNESS))) return TRUE;
else if(sIType == "Dazed" &&
(GetIsImmune(oCreature, IMMUNITY_TYPE_DAZED) ||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
else if(sIType == "Charm" &&
(GetIsImmune(oCreature, IMMUNITY_TYPE_CHARM) ||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
// Check for damage immunities.
// Negative damage does not work on undead!
else if(sIType == "Negative" && GetRacialType(oCreature) == RACIAL_TYPE_UNDEAD)
{
if(AI_DEBUG) ai_Debug("0i_spell", "325", "Undead are immune to Negative energy!");
if(AI_DEBUG) ai_Debug("0i_spell", "538", "Undead are immune to Negative energy!");
return TRUE;
}
else if(sIType == "Poison" && ai_GetHasEffectType(oCreature, EFFECT_TYPE_POISON)) return TRUE;
else if(sIType == "Disease" && ai_GetHasEffectType(oCreature, EFFECT_TYPE_DISEASE)) return TRUE;
// Elemental damage resistances should be checked.
if(sIType == "Acid" || sIType == "Cold" || sIType == "Fire" ||
sIType == "Electricty" || sIType == "Sonic")
{
if(ai_GetHasEffectType(oCreature, EFFECT_TYPE_DAMAGE_RESISTANCE))
{
if(AI_DEBUG) ai_Debug("0i_spell", "334", GetName(oCreature) + " has damage resistance to my " + sIType + " spell!");
if(AI_DEBUG) ai_Debug("0i_spell", "547", GetName(oCreature) + " has damage resistance to my " + sIType + " spell!");
return TRUE;
}
// Check for resistances and immunities. Treat resistance as immune.
int nIPResist = GetLocalInt(oCreature, sIPResistVarname);
if(AI_DEBUG) ai_Debug("0i_spell", "372", "nIPResist:" + IntToString(nIPResist));
if(AI_DEBUG) ai_Debug("0i_spell", "552", "nIPResist:" + IntToString(nIPResist));
int nIPImmune = GetLocalInt(oCreature, sIPImmuneVarname) | nIPResist;
if(AI_DEBUG) ai_Debug("0i_spell", "374", "nIPImmune:" + IntToString(nIPImmune));
if(nIPImmune > 0)
if(AI_DEBUG) ai_Debug("0i_spell", "554", "nIPImmune:" + IntToString(nIPImmune));
int bImmune;
if(nIPImmune > 0) {
if(sIType == "Acid" && (nIPImmune & DAMAGE_TYPE_ACID)) bImmune = TRUE;
else if(sIType == "Cold" && (nIPImmune & DAMAGE_TYPE_COLD)) bImmune = TRUE;
else if(sIType == "Fire" && (nIPImmune & DAMAGE_TYPE_FIRE)) bImmune = TRUE;
else if(sIType == "Electricity" && (nIPImmune & DAMAGE_TYPE_ELECTRICAL)) bImmune = TRUE;
else if(sIType == "Sonic" && (nIPImmune & DAMAGE_TYPE_SONIC)) bImmune = TRUE;
}
if(bImmune)
{
if(AI_DEBUG) ai_Debug("0i_spell", "391", GetName(oCreature) + " is immune/resistant to my " + sIType + " spell through an item!");
if(sIType == "Acid" && (nIPImmune & DAMAGE_TYPE_ACID)) return TRUE;
else if(sIType == "Cold" && (nIPImmune & DAMAGE_TYPE_COLD)) return TRUE;
else if(sIType == "Fire" && (nIPImmune & DAMAGE_TYPE_FIRE)) return TRUE;
else if(sIType == "Electricity" && (nIPImmune & DAMAGE_TYPE_ELECTRICAL)) return TRUE;
else if(sIType == "Sonic" && (nIPImmune & DAMAGE_TYPE_SONIC)) return TRUE;
if(AI_DEBUG) ai_Debug("0i_spell", "567", GetName(oCreature) + " is immune/resistant to my " + sIType + " spell through an item!");
return TRUE;
}
}
// Lets also check undead and constructs vs mind spells.
int nRace = GetRacialType(oCreature);
int nClass = GetClassByPosition(1, oCreature);
if(nRace == RACIAL_TYPE_UNDEAD || nRace == RACIAL_TYPE_CONSTRUCT ||
nClass == CLASS_TYPE_UNDEAD || nClass == CLASS_TYPE_CONSTRUCT)
{
if(sIType == "Mind_Affecting" || sIType == "Fear" || sIType == "Sleep" ||
sIType == "Confusion" || sIType == "Blindness" || sIType == "Daze" ||
sIType == "Poison" || sIType == "Disease" || sIType == "Charm")
{
if(AI_DEBUG) ai_Debug("0i_spell", "595", GetName(oCreature) + " is immune/resistant to my " + sIType + " spell because they are Undead or a Construct!");
return TRUE;
}
}
}
@@ -479,12 +612,12 @@ int ai_CreatureImmuneToEffect(object oCaster, object oCreature, int nSpell)
{
if(nSpell == JsonGetInt(jSpell))
{
if(AI_DEBUG) ai_Debug("0i_spells", "407", GetName(oCreature) + " is immune to the spell via an Item!");
if(AI_DEBUG) ai_Debug("0i_spells", "581", GetName(oCreature) + " is immune to the spell via an Item!");
return TRUE;
}
jSpell = JsonArrayGet(jSpellImmunity, ++nIndex);
}
if(AI_DEBUG) ai_Debug("0i_spell", "347", GetName(oCreature) + " is not immune to the spell.");
if(AI_DEBUG) ai_Debug("0i_spell", "586", GetName(oCreature) + " is not immune to the spell.");
return FALSE;
}
float ai_GetSpellRange(int nSpell)
@@ -651,9 +784,9 @@ int ai_IsSilenced(object oCreature, int nSpell)
}
int ai_ArcaneSpellFailureTooHigh(object oCreature, int nClass, int nLevel, int nSlot)
{
if(AI_DEBUG) ai_Debug("0i_spells", "561", "Arcane Spells: " + Get2DAString("classes", "ASF", nClass) +
if(AI_DEBUG) ai_Debug("0i_spells", "746", "Arcane Spells: " + Get2DAString("classes", "ASF", nClass) +
" Arcane Spell Failure: " + IntToString(GetArcaneSpellFailure(oCreature)) +
" AI_ASF_WILL_USE: " + IntToString(AI_ASF_WILL_USE));
" > " + IntToString(AI_ASF_WILL_USE) + " skip.");
if(Get2DAString("classes", "ASF", nClass) == "1" &&
GetArcaneSpellFailure(oCreature) > AI_ASF_WILL_USE)
{
@@ -1883,6 +2016,98 @@ int ai_CastSpontaneousCure(object oCreature, object oTarget, object oPC)
}
return FALSE;
}
int ai_CastMemorizedInflict(object oCreature, object oTarget, object oPC, int nClass)
{
if(AI_DEBUG) ai_Debug("0i_spells", "1993", GetName(oCreature) + " is looking to cast a memorized inflict spell.");
int nDamage = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget);
int nSpell, nSlot, nMaxSlots, nLevel = 9;
int nClassSave, nSlotSave, nLevelSave = 10;
while(nLevel > -1)
{
nMaxSlots = GetMemorizedSpellCountByLevel(oCreature, nClass, nLevel);
nSlot = 0;
if(AI_DEBUG) ai_Debug("0i_spells", "2001", "nLevel: " + IntToString(nLevel) + " nMaxSlots: " + IntToString(nMaxSlots));
while(nSlot < nMaxSlots)
{
if(AI_DEBUG) ai_Debug("0i_spells", "2004", "nSlot: " + IntToString(nSlot) +
" Spell Ready: " + IntToString(GetMemorizedSpellReady(oCreature, nClass, nLevel, nSlot)));
if(GetMemorizedSpellReady(oCreature, nClass, nLevel, nSlot))
{
nSpell = GetMemorizedSpellId(oCreature, nClass, nLevel, nSlot);
if(ai_ShouldWeCastThisInflictSpell(nSpell, nDamage))
{
string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
if(AI_DEBUG) ai_Debug("0i_spells", "2012", GetName(oCreature) + " has cast " + sSpellName + " on " + GetName(oTarget) + ".");
ai_CastMemorizedSpell(oCreature, nClass, nLevel, nSlot, oTarget, FALSE, oPC);
return TRUE;
}
// Save the lowest level inflict spell as we might need to cast it.
else if(nLevel < nLevelSave && (nSpell > 430 && nSpell < 436))
{
nClassSave = nClass;
nLevelSave = nLevel;
nSlotSave = nSlot;
}
}
nSlot++;
}
nLevel--;
}
// Did we find a cure spell? If we did then use it.
if(nLevelSave < 10)
{
if(AI_DEBUG) ai_Debug("0i_spells", "1740", GetName(oCreature) + " has cast the lowest level cure spell on " + GetName(oTarget) + ".");
ai_CastMemorizedSpell(oCreature, nClassSave, nLevelSave, nSlotSave, oTarget, FALSE, oPC);
return TRUE;
}
return FALSE;
}
int ai_CastKnownInflict(object oCreature, object oTarget, object oPC, int nClass)
{
if(AI_DEBUG) ai_Debug("0i_spells", "2041", GetName(oCreature) + " is looking to cast a known inflict spell.");
int nDamage = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget);
int nSpell, nSlot, nMaxSlots, nLevel = 9;
int nClassSave, nSpellSave, nLevelSave = 10;
while(nLevel > -1)
{
nMaxSlots = GetKnownSpellCount(oCreature, nClass, nLevel);
nSlot = 0;
if(AI_DEBUG) ai_Debug("0i_spells", "2049", "nLevel: " + IntToString(nLevel) + " nMaxSlots: " + IntToString(nMaxSlots));
while(nSlot < nMaxSlots)
{
nSpell = GetKnownSpellId(oCreature, nClass, nLevel, nSlot);
if(AI_DEBUG) ai_Debug("0i_spells", "2053", "nSlot: " + IntToString(nSlot) +
" Spell Ready: " + IntToString(GetSpellUsesLeft(oCreature, nClass, nSpell)));
if(GetSpellUsesLeft(oCreature, nClass, nSpell))
{
if(ai_ShouldWeCastThisInflictSpell(nSpell, nDamage))
{
string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
if(AI_DEBUG) ai_Debug("0i_spells", "2060", GetName(oCreature) + " has cast " + sSpellName + " on " + GetName(oTarget) + ".");
ai_CastKnownSpell(oCreature, nClass, nSpell, oTarget, FALSE, oPC);
return TRUE;
}
// Save the lowest level cure spell as we might need to cast it.
else if(nLevel < nLevelSave && (nSpell > 430 && nSpell < 436))
{
nClassSave = nClass;
nLevelSave = nLevel;
nSpellSave = nSpell;
}
}
nSlot++;
}
nLevel--;
}
return FALSE;
// Did we find a cure spell? If we did then use it.
if(nLevelSave < 10)
{
if(AI_DEBUG) ai_Debug("0i_spells", "1781", GetName(oCreature) + " has cast the lowest level cure spell on " + GetName(oTarget) + ".");
ai_CastKnownSpell(oCreature, nClassSave, nSpellSave, oTarget, FALSE, oPC);
return TRUE;
}
}
int ai_CastMemorizedHealing(object oCreature, object oTarget, object oPC, int nClass)
{
if(AI_DEBUG) ai_Debug("0i_spells", "1702", GetName(oCreature) + " is looking to cast a memorized cure spell.");
@@ -1909,7 +2134,7 @@ int ai_CastMemorizedHealing(object oCreature, object oTarget, object oPC, int nC
return TRUE;
}
// Save the lowest level cure spell as we might need to cast it.
else if(nLevel < nLevelSave && (nSpell > 26 && nSpell < 32))
else if(nLevel < nLevelSave && (nSpell > 30 && nSpell < 36))
{
nClassSave = nClass;
nLevelSave = nLevel;
@@ -1955,7 +2180,7 @@ int ai_CastKnownHealing(object oCreature, object oTarget, object oPC, int nClass
return TRUE;
}
// Save the lowest level cure spell as we might need to cast it.
else if(nLevel < nLevelSave && (nSpell > 26 && nSpell < 32))
else if(nLevel < nLevelSave && (nSpell > 30 && nSpell < 36))
{
nClassSave = nClass;
nLevelSave = nLevel;
@@ -2074,7 +2299,7 @@ float ai_GetOffensiveSpellSearchRange(object oCreature, int nSpell)
// We check this because if the enemy is moving or has not started acting
// then we don't want to move up on them as they might move towards us!
int nAction = GetCurrentAction(oNearestEnemy);
if(AI_DEBUG) ai_Debug("0i_spells", "1130", GetName(oNearestEnemy) + " current action: " + IntToString(nAction));
if(AI_DEBUG) ai_Debug("0i_spells", "2228", GetName(oNearestEnemy) + " current action: " + IntToString(nAction));
if(nAction != ACTION_MOVETOPOINT || nAction != ACTION_ITEMCASTSPELL ||
nAction != ACTION_INVALID || nAction != ACTION_USEOBJECT ||
nAction != ACTION_RANDOMWALK) fRange = fEnemyDistance + (fRange - 7.5);
@@ -2083,6 +2308,18 @@ float ai_GetOffensiveSpellSearchRange(object oCreature, int nSpell)
else if(fRange < 0.1f) return 0.1f;
return fRange;
}
int ai_ShouldWeCastThisInflictSpell(int nSpell, int nDamage)
{
if(AI_DEBUG) ai_Debug("0i_spells", "2239", "nSpell: " + IntToString(nSpell) + " nDamage: " +
IntToString(nDamage));
if(nSpell == SPELL_HEAL && nDamage > 50) return TRUE;
else if(nSpell == SPELL_INFLICT_CRITICAL_WOUNDS && nDamage > 31) return TRUE;
else if(nSpell == SPELL_INFLICT_SERIOUS_WOUNDS && nDamage > 23) return TRUE;
else if(nSpell == SPELL_INFLICT_MODERATE_WOUNDS && nDamage > 15) return TRUE;
else if(nSpell == SPELL_INFLICT_LIGHT_WOUNDS && nDamage > 6) return TRUE;
else if(nSpell == SPELL_INFLICT_MINOR_WOUNDS) return TRUE;
return FALSE;
}
int ai_ShouldWeCastThisCureSpell(int nSpell, int nDamage)
{
if(AI_DEBUG) ai_Debug("0i_spells", "1127", "nSpell: " + IntToString(nSpell) + " nDamage: " +

View File

@@ -105,6 +105,7 @@ int ai_CompareLastAction(object oCreature, int nAction)
}
void ai_SetListeningPatterns(object oCreature)
{
SetListening(oCreature, TRUE);
SetListenPattern(oCreature, AI_I_SEE_AN_ENEMY, AI_ALLY_SEES_AN_ENEMY);
SetListenPattern(oCreature, AI_I_HEARD_AN_ENEMY, AI_ALLY_HEARD_AN_ENEMY);
SetListenPattern(oCreature, AI_ATKED_BY_WEAPON, AI_ALLY_ATKED_BY_WEAPON);
@@ -114,7 +115,6 @@ void ai_SetListeningPatterns(object oCreature)
SetListenPattern(oCreature, AI_I_AM_DISEASED, AI_ALLY_IS_DISEASED);
SetListenPattern(oCreature, AI_I_AM_POISONED, AI_ALLY_IS_POISONED);
SetListenPattern(oCreature, AI_I_AM_WEAK, AI_ALLY_IS_WEAK);
SetListening(oCreature, TRUE);
}
int ai_IsNonliving(int nRacialType)
{
@@ -134,12 +134,12 @@ int ai_GetIsInCombat(object oCreature)
}
void ai_SetCombatRound(object oCreature)
{
SetLocalInt(oCreature, "AI_COMBAT_ROUND_START", SQLite_GetTimeStamp());
if(AI_DEBUG) ai_Debug("0i_states_cond", "116", " ===============> " + GetName(oCreature) + " ROUND START:" + IntToString(SQLite_GetTimeStamp()) + " <===============");
SetLocalInt(oCreature, "AI_COMBAT_ROUND_START", ai_GetCurrentTimeStamp());
if(AI_DEBUG) ai_Debug("0i_states_cond", "116", " ===============> " + GetName(oCreature) + " ROUND START:" + IntToString(ai_GetCurrentTimeStamp()) + " <===============");
}
void ai_EndCombatRound(object oCreature)
{
if(AI_DEBUG) ai_Debug("0i_states_cond", "120", " ===============> " + GetName(oCreature) + " ROUND END:" + IntToString(SQLite_GetTimeStamp()) + " <===============");
if(AI_DEBUG) ai_Debug("0i_states_cond", "120", " ===============> " + GetName(oCreature) + " ROUND END:" + IntToString(ai_GetCurrentTimeStamp()) + " <===============");
DeleteLocalInt(oCreature, "AI_COMBAT_ROUND_START");
}
int ai_IsInCombatRound(object oCreature, int nCombatRound = AI_COMBAT_ROUND_IN_SECONDS)
@@ -148,10 +148,10 @@ int ai_IsInCombatRound(object oCreature, int nCombatRound = AI_COMBAT_ROUND_IN_S
if(AI_DEBUG) ai_Debug("0i_states_cond", "148", " nCombatRoundStart: " + IntToString(nCombatRoundStart));
if(!nCombatRoundStart) return FALSE;
// New combat round calculator. If 6 seconds has passed then we are on a new round!
int nSQLTime = SQLite_GetTimeStamp();
int nCombatRoundTime = nSQLTime - nCombatRoundStart;
if(AI_DEBUG) ai_Debug("0i_states_cond", "153", " SQLite_GetTimeStamp: " + IntToString(nSQLTime) +
"(" + IntToString(nSQLTime - nCombatRoundStart) + ")");
int nTime = ai_GetCurrentTimeStamp();
int nCombatRoundTime = nTime - nCombatRoundStart;
if(AI_DEBUG) ai_Debug("0i_states_cond", "153", " nTime + (nTime - Round Start): " + IntToString(nTime) +
"(" + IntToString(nTime - nCombatRoundStart) + ")");
if(nCombatRoundTime < nCombatRound) return TRUE;
ai_EndCombatRound(oCreature);
return FALSE;
@@ -200,9 +200,11 @@ int ai_Disabled(object oCreature)
effect eEffect = GetFirstEffect(oCreature);
while(GetIsEffectValid(eEffect))
{
switch(GetEffectType(eEffect))
switch(GetEffectType(eEffect, TRUE))
{
WriteTimestampedLogEntry("Effect Type: " + IntToString(GetEffectType(eEffect, TRUE)));
case EFFECT_TYPE_DOMINATED :
case EFFECT_TYPE_CUTSCENE_DOMINATED :
{
if(!GetCommandable(oCreature)) SetCommandable(TRUE, oCreature);
return FALSE;
@@ -213,6 +215,7 @@ int ai_Disabled(object oCreature)
case EFFECT_TYPE_CONFUSED :
case EFFECT_TYPE_FRIGHTENED :
case EFFECT_TYPE_PARALYZE :
case EFFECT_TYPE_CUTSCENE_PARALYZE :
case EFFECT_TYPE_TURNED :
case EFFECT_TYPE_CHARMED :
case EFFECT_TYPE_PETRIFY :

File diff suppressed because it is too large Load Diff

View File

@@ -8,55 +8,42 @@ int GetPosixTimestamp();
string GetCurrentDateTime();
*///////////////////////////////////////////////////////////////////////////////
// RETURNS a Timestamp in seconds since 1970-01-01.
int GetCurrentTimeInSeconds();
// RETURNS a formated date, good for timestamping logs and text.
// Returns a Timestamp in seconds since 1970-01-01.
int ai_GetCurrentTimeStamp();
// Returns a formated date, good for Dating logs and text.
string GetCurrentDateTime();
// Sends a server shutdown message 1800 seconds i.e 30 minutes before.
// nDuration is in seconds. i.e. one hours is 3600 defaults to 24 hours (86400).
// Should be put into the servers OnHeartBeat.
void CheckServerShutdownMessage(int nDuration = 86400);
/// Returns the current time formatted according to the provided sqlite date time format string.
/// Format string as used by sqlites STRFTIME().
/// Returns the current time in the requested format. Empty string on error.
string SQLite_GetFormattedSystemTime(string format);
/// Returns the number of milliseconds since midnight on January 1, 1970.
int SQLite_GetTimeMilliseconds();
/// Returns the date in the format (mm/dd/yyyy).
string SQLite_GetSystemDate();
/// Returns the current time in the format (24:mm:ss).
string SQLite_GetSystemTime();
int GetCurrentTimeInSeconds()
int ai_GetCurrentTimeStamp()
{
string stmt = "SELECT strftime('%s','now');";
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
SqlStep(sqlQuery);
return SqlGetInt(sqlQuery, 0);
sqlquery query = SqlPrepareQueryObject(GetModule(), "SELECT STRFTIME('%s', 'now')");
SqlStep(query);
return SqlGetInt(query, 0);
}
string GetCurrentDateTime()
{
string stmt = "SELECT datetime('now', 'localtime')";
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), "SELECT datetime('now', 'localtime')");
SqlStep(sqlQuery);
return SqlGetString(sqlQuery, 0);
}
/// @addtogroup time Time
/// @brief Provides various time related functions.
/// @brief Returns the current time formatted according to the provided sqlite date time format string.
/// @param format Format string as used by sqlites STRFTIME().
/// @return The current time in the requested format. Empty string on error.
string SQLite_GetFormattedSystemTime(string format);
/// @return Returns the number of seconds since midnight on January 1, 1970.
int SQLite_GetTimeStamp();
/// @return Returns the number of milliseconds since midnight on January 1, 1970.
int SQLite_GetTimeMilliseconds();
/// @brief A millisecond timestamp
struct SQLite_MillisecondTimeStamp
{
int seconds; ///< Seconds since epoch
int milliseconds; ///< Milliseconds
};
/// @remark For mircosecond timestamps use NWNX_Utility_GetHighResTimeStamp().
/// @return Returns the number of milliseconds since midnight on January 1, 1970.
struct SQLite_MillisecondTimeStamp SQLite_GetMillisecondTimeStamp();
/// @brief Returns the current date.
/// @return The date in the format (mm/dd/yyyy).
string SQLite_GetSystemDate();
/// @brief Returns current time.
/// @return The current time in the format (24:mm:ss).
string SQLite_GetSystemTime();
/// @}
string SQLite_GetFormattedSystemTime(string format)
{
sqlquery query = SqlPrepareQueryObject(GetModule(), "SELECT STRFTIME(@format, 'now', 'localtime')");
@@ -64,27 +51,12 @@ string SQLite_GetFormattedSystemTime(string format)
SqlStep(query); // sqlite returns NULL for invalid format in STRFTIME()
return SqlGetString(query, 0);
}
int SQLite_GetTimeStamp()
{
sqlquery query = SqlPrepareQueryObject(GetModule(), "SELECT STRFTIME('%s', 'now')");
SqlStep(query);
return SqlGetInt(query, 0);
}
int SQLite_GetTimeMillisecond()
{
sqlquery query = SqlPrepareQueryObject(GetModule(), "select cast((julianday('now') - 2440587.5) * 86400 * 1000 as integer)");
SqlStep(query);
return SqlGetInt(query, 0);
}
struct SQLite_MillisecondTimeStamp SQLite_GetMillisecondTimeStamp()
{
sqlquery query = SqlPrepareQueryObject(GetModule(), "SELECT STRFTIME('%s', 'now'), SUBSTR(STRFTIME('%f', 'now'), 4)");
SqlStep(query);
struct SQLite_MillisecondTimeStamp t;
t.seconds = SqlGetInt(query, 0);
t.milliseconds = SqlGetInt(query, 1);
return t;
}
string SQLite_GetSystemDate()
{
return SQLite_GetFormattedSystemTime("%m/%d/%Y");

View File

@@ -92,18 +92,18 @@ void main()
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature);
if(oTarget == OBJECT_INVALID) ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
}
else
{
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
if(AI_DEBUG) ai_Debug("0i_actions", "519", "Do ranged attack against nearest: " + GetName(oTarget) + "!");
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
@@ -133,7 +133,7 @@ void main()
{
oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER, AI_RANGE_MELEE, AI_ENEMY, bAlwaysAtk);
// If we didn't get a target then get any target within range.
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE, AI_ENEMY, bAlwaysAtk);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE, AI_ENEMY, bAlwaysAtk);
}
// If not then lets go find someone to attack!
else
@@ -141,7 +141,7 @@ void main()
// Get the nearest enemy.
oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_CASTER, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk);
// If we didn't get a target then get any target within range.
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk);
}
}
}

View File

@@ -92,18 +92,18 @@ void main()
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature);
if(oTarget == OBJECT_INVALID) ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_WARRIOR);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
}
else
{
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_WARRIOR, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
if(AI_DEBUG) ai_Debug("0i_actions", "519", "Do ranged attack against nearest: " + GetName(oTarget) + "!");
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
@@ -133,7 +133,7 @@ void main()
{
oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_WARRIOR, AI_RANGE_MELEE, AI_ENEMY, bAlwaysAtk);
// If we didn't get a target then get any target within range.
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE, AI_ENEMY, bAlwaysAtk);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE, AI_ENEMY, bAlwaysAtk);
}
// If not then lets go find someone to attack!
else
@@ -141,7 +141,7 @@ void main()
// Get the nearest enemy.
oTarget = ai_GetNearestClassTarget(oCreature, AI_CLASS_TYPE_WARRIOR, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk);
// If we didn't get a target then get any target within range.
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_PERCEPTION, AI_ENEMY, bAlwaysAtk);
}
}
}

View File

@@ -55,12 +55,12 @@ void main()
if(oTarget == OBJECT_INVALID)
{
// Lets pick off the weakest targets.
if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature);
else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
else oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -52,12 +52,12 @@ void main()
if(oTarget == OBJECT_INVALID)
{
// Lets pick off the weakest targets.
if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature);
else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
else oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -72,12 +72,12 @@ void main()
if(oTarget == OBJECT_INVALID)
{
// Lets pick off the weakest targets.
if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature);
else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
else oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -61,7 +61,7 @@ void main()
if(ai_TryImprovedExpertiseFeat(oCreature)) return;
if(ai_TryExpertiseFeat(oCreature)) return;
// Lets get the strongest melee opponent in melee with us.
oTarget = ai_GetHighestCRTarget(oCreature, AI_RANGE_MELEE);
oTarget = ai_GetHighestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = oNearestEnemy;
// Use knockdown when appropriate and the target is not immune.
if(ai_TryKnockdownFeat(oCreature, oTarget)) return;

View File

@@ -24,12 +24,38 @@ void main()
nMaxLevel = ai_GetAssociateTalentMaxLevel(oCreature, nDifficulty);
}
// Skill, Class, Offensive AOE's, and Defensive talents.
object oTarget = OBJECT_INVALID;
// Get the Spell Level we should still cast before turning into our polymorph form.
int nSpellLevel = ai_GetHasPolymorphSelfFeat(oCreature);
int nMaxTalentLevel;
if(AI_DEBUG) ai_Debug("ai_a_druid", "31", "nSpellLevel: " + IntToString(nSpellLevel));
if(nDifficulty >= AI_COMBAT_MODERATE)
{
// *************************** SPELL TALENTS ***************************
if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING))
{
if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return;
if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return;
}
// ************************** CLASS FEATURES ***************************
if(ai_TrySummonAnimalCompanionTalent(oCreature)) return;
// *************************** SPELL TALENTS ***************************
if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return;
//************************** DEFENSIVE TALENTS ***************************
if(!ai_GetMagicMode(oCreature, AI_MAGIC_OFFENSIVE_CASTING))
{
if(ai_GetMagicMode(oCreature, AI_MAGIC_BUFF_MASTER)) oTarget = GetMaster(oCreature);
nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_SUMMON);
if(AI_DEBUG) ai_Debug("ai_a_druid", "47", "nMaxTalentLevel 'S' " + IntToString(nMaxTalentLevel));
if(nSpellLevel < nMaxTalentLevel &&
ai_UseCreatureTalent(oCreature, AI_TALENT_SUMMON, nInMelee, nMaxLevel, oTarget)) return;
nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_PROTECTION);
if(AI_DEBUG) ai_Debug("ai_a_druid", "51", "nMaxTalentLevel 'P' " + IntToString(nMaxTalentLevel));
if(nSpellLevel < nMaxTalentLevel &&
ai_UseCreatureTalent(oCreature, AI_TALENT_PROTECTION, nInMelee, nMaxLevel, oTarget)) return;
nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_ENHANCEMENT);
if(AI_DEBUG) ai_Debug("ai_a_druid", "55", "nMaxTalentLevel 'E' " + IntToString(nMaxTalentLevel));
if(nSpellLevel < nMaxTalentLevel &&
ai_UseCreatureTalent(oCreature, AI_TALENT_ENHANCEMENT, nInMelee, nMaxLevel, oTarget)) return;
}
}
// Offensive single target talents.
if(nDifficulty >= AI_COMBAT_EFFORTLESS)
@@ -37,16 +63,24 @@ void main()
// *************************** SPELL TALENTS ***************************
if(!ai_GetMagicMode(oCreature, AI_MAGIC_DEFENSIVE_CASTING))
{
if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return;
if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return;
if(nInMelee > 0)
{
nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_TOUCH);
if(AI_DEBUG) ai_Debug("ai_druid", "69", "nMaxTalentLevel 'T' " + IntToString(nMaxTalentLevel));
if(nSpellLevel < nMaxTalentLevel &&
ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return;
}
nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_RANGED);
if(AI_DEBUG) ai_Debug("ai_druid", "74", "nMaxTalentLevel 'R' " + IntToString(nMaxTalentLevel));
if(nSpellLevel < nMaxTalentLevel &&
ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return;
}
if(nDifficulty >= AI_COMBAT_MODERATE && ai_TryPolymorphSelfFeat(oCreature)) return;
}
if(nDifficulty >= AI_COMBAT_MODERATE && ai_TryPolymorphSelfFeat(oCreature)) return;
//************************** SKILL FEATURES **************************
if(ai_TryAnimalEmpathy(oCreature)) return;
// PHYSICAL ATTACKS - Either we don't have talents or we are saving them.
// ************************** Ranged feat attacks **************************
object oTarget;
if(!ai_GetAIMode(oCreature, AI_MODE_STOP_RANGED) && ai_CanIUseRangedWeapon(oCreature, nInMelee))
{
if(ai_HasRangedWeaponWithAmmo(oCreature))
@@ -56,12 +90,12 @@ void main()
if(oTarget == OBJECT_INVALID)
{
// Lets pick off the weakest targets.
if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature);
else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
else oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -51,12 +51,12 @@ void main()
if(oTarget == OBJECT_INVALID)
{
// Lets pick off the weakest targets.
if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature);
else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
else oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -60,8 +60,8 @@ void main()
{
oTarget = ai_GetFlankTarget(oCreature, AI_RANGE_MELEE);
}
// Ok we are in a serious fight so lets not give attack of opportunities.
else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
// Ok we are in a serious fight so lets not give attacks of opportunities.
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
// If there are no enemies being attacked then lets stay back.
if(oTarget == OBJECT_INVALID)
@@ -83,10 +83,10 @@ void main()
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return;
oTarget = ai_GetLowestCRTarget(oCreature);
oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}
@@ -98,6 +98,12 @@ void main()
return;
}
}
// Make sure we are not the only one here. Moving around looks funny when we are by ourselves.
else if(ai_GetNearestAlly(oCreature, 1, 7, 7) == OBJECT_INVALID)
{
oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget);
}
}
if(oTarget != OBJECT_INVALID)
{

View File

@@ -75,12 +75,12 @@ void main()
if(oTarget == OBJECT_INVALID)
{
// Lets pick off the weakest targets.
if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature);
else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
else oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -52,12 +52,12 @@ void main()
if(oTarget == OBJECT_INVALID)
{
// Lets pick off the weakest targets.
if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature);
else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
else oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -91,17 +91,17 @@ void main()
{
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
}
else
{
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
if(AI_DEBUG) ai_Debug("ai_a_no_modes", "105", GetName(OBJECT_SELF) + " does ranged attack on weakest: " + GetName(oTarget) + "!");
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;

View File

@@ -73,12 +73,12 @@ void main()
if(oTarget == OBJECT_INVALID)
{
// Paladins face off against the strongest opponents first.
if(!nInMelee) oTarget = ai_GetHighestCRTarget(oCreature);
else oTarget = ai_GetHighestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetHighestCRPhysicalTarget(oCreature);
else oTarget = ai_GetHighestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -8,16 +8,21 @@
// Programmer: Philos
//////////////////////////////////////////////////////////////////////////////////////////////////////
#include "0i_actions"
void ai_DoActions(object oCreature, int nForm)
void main()
{
object oCreature = OBJECT_SELF;
int nInMelee = ai_GetNumOfEnemiesInRange(oCreature);
object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST);
if(ai_TryHealingTalent(oCreature, nInMelee)) return;
if(ai_TryCureConditionTalent(oCreature, nInMelee)) return;
if(GetPercentageHPLoss(oCreature) <= AI_HEALTH_BLOODY)
{
//ai_Debug("ai_a_polymorphed", "24", "We are wounded and are transforming back!");
if(AI_DEBUG) ai_Debug("ai_a_polymorphed", "20", "We are wounded and are transforming back!");
ai_RemoveASpecificEffect(oCreature, EFFECT_TYPE_POLYMORPH);
DeleteLocalInt(oCreature, AI_POLYMORPHED);
// We need to create the creatures normal forms talent list.
DelayCommand(0.0, ai_ClearTalents(oCreature));
DelayCommand(0.1, ai_SetCreatureTalents(oCreature, FALSE, TRUE));
return;
}
int nDifficulty = ai_GetDifficulty(oCreature);
@@ -51,20 +56,3 @@ void ai_DoActions(object oCreature, int nForm)
if(oTarget != OBJECT_INVALID) ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget);
else ai_SearchForHiddenCreature(oCreature, FALSE);
}
void main()
{
object oCreature = OBJECT_SELF;
// Need to know who we are so we can use thier abilities.
int nForm = GetAppearanceType(oCreature);
// Check to see if we are back to our normal form?(-1 to get the actual form #)
if(nForm == GetLocalInt(oCreature, AI_NORMAL_FORM) - 1)
{
// If we are transformed back then go back to our primary ai.
ai_SetCreatureAIScript(oCreature);
DeleteLocalInt(oCreature, AI_NORMAL_FORM);
string sAI = GetLocalString(oCreature, AI_COMBAT_SCRIPT);
if(sAI == "ai_a_polymorphed" || sAI == "") sAI = "ai_a_default";
ExecuteScript(sAI, oCreature);
}
else ai_DoActions(oCreature, nForm);
}

View File

@@ -68,17 +68,17 @@ void main()
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget == ai_GetRangedTarget(oCreature);
if(oTarget == OBJECT_INVALID && ai_TryRangedSneakAttack(oCreature, nInMelee)) return;
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
}
else
{
if(ai_GetAIMode(oCreature, AI_MODE_DEFEND_MASTER)) oTarget = ai_GetLowestCRAttackerOnMaster(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -59,17 +59,17 @@ void main()
if(!nInMelee)
{
oTarget = ai_GetNearestFavoredEnemyTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
}
else
{
oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -52,12 +52,12 @@ void main()
{
if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return;
// Lets pick off the weakest targets.
if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature);
else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
else oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -50,8 +50,8 @@ void main()
if(oTarget == OBJECT_INVALID)
{
// Lets pick off the weakest targets.
if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature);
else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
else oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{

View File

@@ -52,8 +52,8 @@ void main()
if(oTarget == OBJECT_INVALID)
{
// Lets pick off the weakest targets.
if(!nInMelee) oTarget = ai_GetLowestCRTarget(oCreature);
else oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetLowestCRPhysicalTarget(oCreature);
else oTarget = ai_GetLowestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{

View File

@@ -41,11 +41,11 @@ void main()
{
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature);
else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetNearestPhysicalTarget(oCreature);
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -39,11 +39,11 @@ void main()
{
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature);
else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetNearestPhysicalTarget(oCreature);
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -0,0 +1,38 @@
/*////////////////////////////////////////////////////////////////////////////////////////////////////
// Script Name: ai_bloodmane
//////////////////////////////////////////////////////////////////////////////////////////////////////
AI combat action scripts for Bloodmane - Orc Warlord(Barbarian - Example).
To use this AI set the variable string "AI_DEFAULT_SCRIPT" to "ai_bloodmane" on the creature.
*/////////////////////////////////////////////////////////////////////////////////////////////////////
// Programmer: Philos
//////////////////////////////////////////////////////////////////////////////////////////////////////
#include "0i_actions"
void main()
{
object oCreature = OBJECT_SELF;
//**************************************************************************
//************************ START SPECIAL AI SCRIPTS ************************
//**************************************************************************
int nRound = ai_GetCurrentRound(oCreature);
// First round cuss and animate!
if(nRound == 1)
{
// Make him taunt the player!
ActionPlayAnimation(ANIMATION_FIREFORGET_TAUNT);
PlayVoiceChat(Random(4), oCreature);
}
// Second round go into a Rage.
else if(nRound == 2)
{
// Use Rage!
if(ai_TryBarbarianRageFeat(oCreature)) return;
// If for some reason he doesn't have a rage then charge into melee!
object oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, ai_GetNumOfEnemiesInRange(oCreature));
if(oTarget != OBJECT_INVALID) ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget);
// Change Bloodmane's ai to Barbarian since we are done with his special ai.
SetLocalString(oCreature, AI_COMBAT_SCRIPT, "ai_barbarian");
}
//**************************************************************************
//************************ END SPECIAL AI SCRIPTS **************************
//**************************************************************************
}

View File

@@ -41,8 +41,8 @@ void main()
{
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature);
else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetNearestPhysicalTarget(oCreature);
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);

View File

@@ -0,0 +1,103 @@
/*////////////////////////////////////////////////////////////////////////////////////////////////////
// Script Name: ai_dragon_boss
//////////////////////////////////////////////////////////////////////////////////////////////////////
ai script a unique dragon that lives deep in a dark cave using it as a defense.
OBJECT_SELF is the dragon running the ai.
*/////////////////////////////////////////////////////////////////////////////////////////////////////
// Programmer: Philos
//////////////////////////////////////////////////////////////////////////////////////////////////////
#include "0i_actions"
void main()
{
object oCreature = OBJECT_SELF;
// Get the number of enemies that we are in melee combat with.
int nInMelee = ai_GetNumOfEnemiesInRange(oCreature);
//**************************************************************************
//************************ ROUND BASED AI SCRIPTS *************************
//**************************************************************************
int nRound = ai_GetCurrentRound(oCreature);
// First time fly to our enemy, the rest of combat lets not do that!
object oTarget;
if(!GetLocalInt(OBJECT_SELF, "AI_DONE_FLYING"))
{
SetLocalInt(OBJECT_SELF, "AI_DONE_FLYING", TRUE);
oTarget = ai_GetLowestCRTarget(oCreature);
// We assign the voice to the PC so they get to hear it.
object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
AssignCommand(oPC, PlaySound("vs_ndredm_bat2"));
// Can we do a crush attack(HD 18+)?
if(ai_TryCrushAttack(oCreature, oTarget)) return;
ai_FlyToTarget(oCreature, oTarget);
return;
}
else if(nRound == 2)
{
oTarget = ai_GetLowestCRTarget(oCreature, AI_RANGE_CLOSE);
ai_TryDragonBreathAttack(oCreature, nRound, oTarget);
return;
}
//*************************** HEALING & CURES ****************************
if(ai_TryHealingTalent(oCreature, nInMelee)) return;
if(ai_TryCureConditionTalent(oCreature, nInMelee)) return;
// Check to see if we need to retreat to get healing.
int nPercentageHP = ai_GetPercHPLoss(oCreature);
//ai_Debug("ai_dragon_boss", "43", "nPercentageHP: " + IntToString(nPercentageHP));
if(nPercentageHP < 75 && !GetLocalInt(oCreature, "AI_HOME"))
{
string sWaypoint;
// If we are below half then go to last defensive position.
if(nPercentageHP < 50)
{
SetLocalInt(oCreature, "AI_HOME", TRUE);
sWaypoint = "0_wp_dragon2";
}
// else we just go back a little bit to heal up.
else sWaypoint = "0_wp_dragon1";
if(!GetLocalInt(oCreature, sWaypoint))
{
string sVoice;
switch(d6())
{
case 1 :
case 2 : sVoice = "vs_ndredm_attk"; break;
case 3 :sVoice = "vs_ndredm_heal"; break;
case 4 :sVoice = "vs_ndredm_help"; break;
case 5 :sVoice = "vs_ndredm_no"; break;
case 6 :sVoice = "vs_ndredm_bat3"; break;
}
SetImmortal(oCreature, TRUE);
DelayCommand(6.0f, SetImmortal(oCreature, FALSE));
AssignCommand(ai_GetNearestTarget(oCreature), PlaySound(sVoice));
object oWaypoint = GetNearestObjectByTag(sWaypoint);
//ai_Debug("ai_dragon_boss", "71", "Flying to " + sWaypoint + ".");
effect eFly = EffectDisappearAppear(GetLocation(oWaypoint));
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFly, oCreature, 6.0f);
SetLocalInt(oCreature, sWaypoint, TRUE);
return;
}
}
int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature);
//******************* OFFENSIVE AREA OF EFFECT TALENTS *******************
// Check the battlefield for a group of enemies to shoot a big talent at!
// We are checking here since these opportunities are rare and we need
// to take advantage of them as often as possible.
if(ai_UseCreatureTalent(oCreature, AI_TALENT_INDISCRIMINANT_AOE, nInMelee, nMaxLevel)) return;
if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return;
//************************** DEFENSIVE TALENTS ***************************
if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return;
//********************** OFFENSIVE TARGETED TALENTS **********************
// Look for a touch attack since we are in melee.
if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return;
if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return;
// ************************ MELEE ATTACKS ********************************
oTarget = ai_GetLowestCRTargetForMeleeCombat(oCreature, nInMelee);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryDragonBreathAttack(oCreature, nRound)) return;
ai_TryWingAttacks(oCreature);
// If we don't do a Tail sweep attack(HD 30+) then see if we can do a Tail slap(HD 12+)!
if(!ai_TryTailSweepAttack(oCreature)) ai_TryTailSlap(oCreature);
ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget);
}
else ai_SearchForHiddenCreature(oCreature, TRUE);
}

View File

@@ -24,14 +24,36 @@ void main()
if(ai_UseCreatureTalent(oCreature, AI_TALENT_DISCRIMINANT_AOE, nInMelee, nMaxLevel)) return;
//**************************** CLASS FEATURES ****************************
if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS) && ai_TrySummonAnimalCompanionTalent(oCreature)) return;
if(ai_TryPolymorphSelfFeat(oCreature)) return;
//************************** DEFENSIVE TALENTS ***************************
int nRound = ai_GetCurrentRound(oCreature);
if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return;
// Get the Spell Level we should still cast before turning into our polymorph form.
int nSpellLevel = ai_GetHasPolymorphSelfFeat(oCreature);
if(AI_DEBUG) ai_Debug("ai_druid", "30", "nSpellLevel: " + IntToString(nSpellLevel));
int nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_SUMMON);
if(AI_DEBUG) ai_Debug("ai_druid", "32", "nMaxTalentLevel 'S' " + IntToString(nMaxTalentLevel));
if(nSpellLevel < nMaxTalentLevel &&
ai_UseCreatureTalent(oCreature, AI_TALENT_SUMMON, nInMelee, nMaxLevel)) return;
nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_PROTECTION);
if(AI_DEBUG) ai_Debug("ai_druid", "36", "nMaxTalentLevel 'P' " + IntToString(nMaxTalentLevel));
if(nSpellLevel < nMaxTalentLevel &&
ai_UseCreatureTalent(oCreature, AI_TALENT_PROTECTION, nInMelee, nMaxLevel)) return;
nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_ENHANCEMENT);
if(AI_DEBUG) ai_Debug("ai_druid", "40", "nMaxTalentLevel 'E' " + IntToString(nMaxTalentLevel));
if(nSpellLevel < nMaxTalentLevel &&
ai_UseCreatureTalent(oCreature, AI_TALENT_ENHANCEMENT, nInMelee, nMaxLevel)) return;
//********************** OFFENSIVE TARGETED TALENTS **********************
// Look for a touch attack since we are in melee.
if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return;
if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return;
if(nInMelee > 0)
{
nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_TOUCH);
if(AI_DEBUG) ai_Debug("ai_druid", "48", "nMaxTalentLevel 'T' " + IntToString(nMaxTalentLevel));
if(nSpellLevel < nMaxTalentLevel &&
ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return;
}
nMaxTalentLevel = GetLocalInt(oCreature, AI_MAX_TALENT + AI_TALENT_RANGED);
if(AI_DEBUG) ai_Debug("ai_druid", "53", "nMaxTalentLevel 'R' " + IntToString(nMaxTalentLevel));
if(nSpellLevel < nMaxTalentLevel &&
ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return;
if(ai_TryPolymorphSelfFeat(oCreature)) return;
//**************************** SKILL FEATURES ****************************
if(ai_TryAnimalEmpathy(oCreature)) return;
// All else fails lets see if we have any good potions.
@@ -43,10 +65,11 @@ void main()
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
// Lets pick off the nearest targets.
if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature);
else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetNearestPhysicalTarget(oCreature);
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -36,11 +36,11 @@ void main()
{
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature);
else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetNearestPhysicalTarget(oCreature);
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}
@@ -54,7 +54,7 @@ void main()
}
// **************************** MELEE ATTACKS ****************************
if(ai_InCombatEquipBestMeleeWeapon(oCreature)) return;
if(ai_TryWhirlwindFeat (oCreature)) return;
if(ai_TryWhirlwindFeat(oCreature)) return;
oTarget = ai_GetNearestTargetForMeleeCombat (oCreature, nInMelee);
if (oTarget != OBJECT_INVALID)
{

View File

@@ -53,7 +53,7 @@ void main()
oTarget = ai_GetFlankTarget(oCreature, AI_RANGE_MELEE);
}
// Ok we are in a serious fight so lets not give attack of opportunities.
else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
// If there are no enemies being attacked then lets stay back.
if(oTarget == OBJECT_INVALID)
@@ -75,10 +75,10 @@ void main()
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if(ai_TryRangedSneakAttack(oCreature, nInMelee)) return;
oTarget = ai_GetNearestTarget(oCreature);
oTarget = ai_GetNearestPhysicalTarget(oCreature);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -44,8 +44,8 @@ void main()
{
if (ai_TryRangedSneakAttack (oCreature, nInMelee)) return;
string sIndex;
if (!nInMelee) oTarget = ai_GetNearestTarget(oCreature);
else oTarget = ai_GetNearestTarget (oCreature, AI_RANGE_MELEE);
if (!nInMelee) oTarget = ai_GetNearestPhysicalTarget(oCreature);
else oTarget = ai_GetNearestPhysicalTarget (oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat (oCreature, oTarget, nInMelee)) return;

View File

@@ -47,11 +47,11 @@ void main()
{
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature);
else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetNearestPhysicalTarget(oCreature);
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -38,8 +38,8 @@ void main()
{
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if (!nInMelee) oTarget = ai_GetNearestTarget (oCreature);
else oTarget = ai_GetNearestTarget (oCreature, AI_RANGE_MELEE);
if (!nInMelee) oTarget = ai_GetNearestPhysicalTarget (oCreature);
else oTarget = ai_GetNearestPhysicalTarget (oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);

View File

@@ -43,8 +43,8 @@ void main()
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
// Paladins face the biggest challenges first!
if(!nInMelee) oTarget = ai_GetHighestCRTarget(oCreature);
else oTarget = ai_GetHighestCRTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetHighestCRPhysicalTarget(oCreature);
else oTarget = ai_GetHighestCRPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);

View File

@@ -8,16 +8,21 @@
// Programmer: Philos
//////////////////////////////////////////////////////////////////////////////////////////////////////
#include "0i_actions"
void ai_DoActions(object oCreature, int nForm)
void main()
{
object oCreature = OBJECT_SELF;
int nInMelee = ai_GetNumOfEnemiesInRange(oCreature);
object oNearestEnemy = GetLocalObject(oCreature, AI_ENEMY_NEAREST);
if(ai_TryHealingTalent(oCreature, nInMelee)) return;
if(ai_TryCureConditionTalent(oCreature, nInMelee)) return;
if(GetPercentageHPLoss(oCreature) <= AI_HEALTH_BLOODY)
{
if(AI_DEBUG) ai_Debug("ai_polymorphed", "19", "We are wounded and are transforming back!");
if(AI_DEBUG) ai_Debug("ai_polymorphed", "20", "We are wounded and are transforming back!");
ai_RemoveASpecificEffect(oCreature, EFFECT_TYPE_POLYMORPH);
DeleteLocalInt(oCreature, AI_POLYMORPHED);
// We need to create the creatures normal forms talent list.
DelayCommand(0.0, ai_ClearTalents(oCreature));
DelayCommand(0.1, ai_SetCreatureTalents(oCreature, TRUE, TRUE));
return;
}
int nMaxLevel = ai_GetMonsterTalentMaxLevel(oCreature);
@@ -31,25 +36,30 @@ void ai_DoActions(object oCreature, int nForm)
if(nInMelee > 0 && ai_UseCreatureTalent(oCreature, AI_TALENT_TOUCH, nInMelee, nMaxLevel)) return;
if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return;
// PHYSICAL ATTACKS - Either we don't have talents or we are saving them.
object oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee);
// If we don't find a target then we don't want to fight anyone!
// *************************** RANGED ATTACKS ****************************
object oTarget;
if(ai_CanIUseRangedWeapon(oCreature, nInMelee))
{
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if(!nInMelee) oTarget = ai_GetNearestPhysicalTarget(oCreature);
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}
else
{
ai_SearchForHiddenCreature(oCreature, TRUE);
return;
}
}
else if(ai_InCombatEquipBestRangedWeapon(oCreature)) return;
}
// **************************** MELEE ATTACKS ****************************
oTarget = ai_GetNearestTargetForMeleeCombat(oCreature, nInMelee);
if(oTarget != OBJECT_INVALID) ai_ActionAttack(oCreature, AI_LAST_ACTION_MELEE_ATK, oTarget);
else ai_SearchForHiddenCreature(oCreature, TRUE);
}
void main()
{
object oCreature = OBJECT_SELF;
// Need to know who we are so we can use thier abilities.
int nForm = GetAppearanceType(oCreature);
// Check to see if we are back to our normal form?(-1 to get the actual form #)
if(nForm == GetLocalInt(oCreature, AI_NORMAL_FORM) - 1)
{
// If we are transformed back then go back to our primary ai.
ai_SetCreatureAIScript(oCreature);
DeleteLocalInt(oCreature, AI_NORMAL_FORM);
string sAI = GetLocalString(oCreature, AI_COMBAT_SCRIPT);
if(sAI == "ai_polymorphed" || sAI == "") sAI = "ai_default";
ExecuteScript(sAI, oCreature);
}
else ai_DoActions(oCreature, nForm);
}

View File

@@ -59,16 +59,16 @@ void main()
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget == ai_GetRangedTarget(oCreature);
if(oTarget == OBJECT_INVALID && ai_TryRangedSneakAttack(oCreature, nInMelee)) return;
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestPhysicalTarget(oCreature);
}
else
{
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -45,16 +45,16 @@ void main()
if(!nInMelee)
{
oTarget = ai_GetNearestFavoredEnemyTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestPhysicalTarget(oCreature);
}
else
{
oTarget = ai_GetNearestFavoredEnemyTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(oTarget == OBJECT_INVALID) oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
}
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -38,7 +38,7 @@ void main()
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if (ai_TryRangedSneakAttack (oCreature, nInMelee)) return;
oTarget = ai_GetNearestTarget (oCreature);
oTarget = ai_GetNearestPhysicalTarget (oCreature);
if(oTarget != OBJECT_INVALID)
{
if (ai_TryRapidShotFeat (oCreature, oTarget, nInMelee)) return;

View File

@@ -38,11 +38,11 @@ void main()
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
string sIndex;
if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature);
else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetNearestPhysicalTarget(oCreature);
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -37,8 +37,8 @@ void main()
{
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature);
else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetNearestPhysicalTarget(oCreature);
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);

View File

@@ -49,11 +49,11 @@ void main()
{
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if (!nInMelee) oTarget = ai_GetNearestTarget (oCreature);
else oTarget = ai_GetNearestTarget (oCreature, AI_RANGE_MELEE);
if (!nInMelee) oTarget = ai_GetNearestPhysicalTarget (oCreature);
else oTarget = ai_GetNearestPhysicalTarget (oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
if(ai_TryRapidShotFeat(oCreature, oTarget, nInMelee)) return;
if(ai_TryRangedTalents(oCreature, oTarget, nInMelee)) return;
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);
return;
}

View File

@@ -39,8 +39,8 @@ void main()
{
if(ai_HasRangedWeaponWithAmmo(oCreature))
{
if(!nInMelee) oTarget = ai_GetNearestTarget(oCreature);
else oTarget = ai_GetNearestTarget(oCreature, AI_RANGE_MELEE);
if(!nInMelee) oTarget = ai_GetNearestPhysicalTarget(oCreature);
else oTarget = ai_GetNearestPhysicalTarget(oCreature, AI_RANGE_MELEE);
if(oTarget != OBJECT_INVALID)
{
ai_ActionAttack(oCreature, AI_LAST_ACTION_RANGED_ATK, oTarget, nInMelee, TRUE);

View File

@@ -59,7 +59,7 @@ void main()
}
if(ai_GetIsInCombat(oCreature))
{
ai_DoAssociateCombatRound (oCreature);
ai_DoMonsterCombatRound (oCreature);
return;
}
if(ai_GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) ai_DetermineSpecialBehavior(oCreature);

View File

@@ -12,6 +12,7 @@ void ai_MonsterCommands(object oCreature, object oSpeaker, int nMatch);
void main()
{
object oCreature = OBJECT_SELF;
object oLastSpeaker = GetLastSpeaker();
ExecuteScript("prc_npc_conv", oCreature);
if(AI_DEBUG) ai_Debug("nw_c2_default4", "15", GetName(oCreature) + " listens " +
IntToString(GetListenPatternNumber()) + " to " + GetName(GetLastSpeaker()) + "." +
@@ -22,7 +23,7 @@ void main()
ai_DoMonsterCombatRound(oCreature);
return;
}
object oLastSpeaker = GetLastSpeaker();
//object oLastSpeaker = GetLastSpeaker();
int nMatch = GetListenPatternNumber();
if(nMatch != -1)
{

View File

@@ -27,7 +27,10 @@ void main()
int nSpell = GetLastSpell();
if(AI_DEBUG) ai_Debug("nw_ch_acb", "21", GetName(OBJECT_SELF) + " has been hit by a harmful spell(" +
Get2DAString("spells", "Label", nSpell) + ")!");
if(ai_GetInAOEReaction(oCreature, oCaster, nSpell) &&
object oMaster = GetMaster(oCreature);
if((!GetLocalInt(oMaster, AI_TARGET_MODE_ON) ||
GetLocalObject(oMaster, AI_TARGET_MODE_ASSOCIATE) != oCreature) &&
ai_GetInAOEReaction(oCreature, oCaster, nSpell) &&
ai_IsInADangerousAOE(oCreature, AI_RANGE_BATTLEFIELD, TRUE)) return;
if(ai_GetIsBusy(oCreature)) return;
if(ai_CheckForCombat(oCreature, FALSE)) return;

View File

@@ -65,10 +65,14 @@ void main()
// second pass.
if(oTarget != oCaster)
{
SetLocalObject(oPC, "AI_BUFF_TARGET", oTarget);
SetLocalObject(oPC, "AI_BUFF_CASTER", oCaster);
SetLocalInt(oPC, "AI_BUFF_SPELL", nSpell);
ExecuteScript("pc_savebuffs", oPC);
// if it is an area of effect spell then we skip it on all but the caster.
if(Get2DAString("spells", "TargetShape", nSpell) == "")
{
SetLocalObject(oPC, "AI_BUFF_TARGET", oTarget);
SetLocalObject(oPC, "AI_BUFF_CASTER", oCaster);
SetLocalInt(oPC, "AI_BUFF_SPELL", nSpell);
ExecuteScript("pc_savebuffs", oPC);
}
return;
}
// If this is the first pass and we get here then oCaster is casting a spell
@@ -114,9 +118,9 @@ void main()
jSpell = JsonArrayInsert(jSpell, JsonInt(nLevel));
jSpell = JsonArrayInsert(jSpell, JsonInt(nMetaMagic));
jSpell = JsonArrayInsert(jSpell, JsonInt(nDomain));
string sTargetName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oTarget, TRUE)));
string sTargetName = ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oTarget)));
jSpell = JsonArrayInsert(jSpell, JsonString(sTargetName));
jSpell = JsonArrayInsert(jSpells, jSpell);
jSpells = JsonArrayInsert(jSpells, jSpell);
SetBuffDatabaseJson(oPC, "spells", jSpells, sList);
SendMessageToPC(oPC, sName + " has been saved for fast buffing on " + sTargetName + ".");
ExecuteScript("pi_buffing", oPC);

View File

@@ -333,14 +333,14 @@ void CastSavedBuffSpells(object oPC)
string sTargetName = JsonGetString(JsonArrayGet(jSpell, 5));
object oTarget;
location lLocation = GetLocation(oPC);
if(sTargetName == "" || sTargetName == ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName (oPC)))) oTarget = oPC;
if(sTargetName == "" || sTargetName == ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oPC)))) oTarget = oPC;
else
{
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 10.0, lLocation, TRUE);
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 20.0, lLocation, TRUE);
while(oTarget != OBJECT_INVALID)
{
if(sTargetName == ai_RemoveIllegalCharacters(ai_StripColorCodes(GetName(oTarget)))) break;
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 10.0, lLocation, TRUE);
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 20.0, lLocation, TRUE);
}
}
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
@@ -397,6 +397,7 @@ int GetSpellReady(object oCaster, int nSpell, int nClass, int nLevel, int nMetam
if(StringToInt(Get2DAString("classes", "MemorizesSpells", nClass)))
{
int nSpellMemorized;
nMaxIndex = GetMemorizedSpellCountByLevel(oCaster, nClass, nLevel);
while(nIndex < nMaxIndex)
{
nMSpell = GetMemorizedSpellId(oCaster, nClass, nLevel, nIndex);
@@ -404,20 +405,18 @@ int GetSpellReady(object oCaster, int nSpell, int nClass, int nLevel, int nMetam
{
nMmSpell = GetMemorizedSpellMetaMagic(oCaster, nClass, nLevel, nIndex);
nDSpell = GetMemorizedSpellIsDomainSpell(oCaster, nClass, nLevel, nIndex);
//ai_Debug("pe_buffing", "308", "nMmSpell: " + IntToString(nMmSpell) +
//SendMessageToPC(oCaster, "pe_buffing, 308, nSpell: " + IntToString(nSpell) +
// " nMSpell: " + IntToString(nMSpell) +
// " nMmSpell: " + IntToString(nMmSpell) +
// " nMetamagic: " + IntToString(nMetamagic) +
// " nDomain: " + IntToString(nDomain) +
// " nDSpell: " + IntToString(nDSpell));
// Cannot save the domain status so we just use the first spell ID.
// Then return the domain statusl.
//if(nMmSpell == nMetamagic &&
// ((nDomain > 0 && nDSpell == TRUE) || nDomain == 0 && nDSpell == FALSE))
if(nMmSpell == nMetamagic)
{
nSpellMemorized = TRUE;
if(GetMemorizedSpellReady(oCaster, nClass, nLevel, nIndex))
{
if(nDSpell == nDomain) return TRUE;
if((nDomain && nDSpell) || (!nDomain && !nDSpell)) return TRUE;
}
}
}
@@ -425,18 +424,20 @@ int GetSpellReady(object oCaster, int nSpell, int nClass, int nLevel, int nMetam
{
sSubRadSpell = "SubRadSpell" + IntToString(nSubRadSpell);
if(nSpell == StringToInt(Get2DAString("spells", sSubRadSpell, nMSpell)))
nMmSpell = GetMemorizedSpellMetaMagic(oCaster, nClass, nLevel, nIndex);
nDSpell = GetMemorizedSpellIsDomainSpell(oCaster, nClass, nLevel, nIndex);
ai_Debug("pe_buffing", "421", "nMmSpell: " + IntToString(nMmSpell) +
" nMetamagic: " + IntToString(nMetamagic) +
" nDomain: " + IntToString(nDomain) +
" nDSpell: " + IntToString(nDSpell));
if(nMmSpell == nMetamagic)
{
nSpellMemorized = TRUE;
if(GetMemorizedSpellReady(oCaster, nClass, nLevel, nIndex))
nMmSpell = GetMemorizedSpellMetaMagic(oCaster, nClass, nLevel, nIndex);
nDSpell = GetMemorizedSpellIsDomainSpell(oCaster, nClass, nLevel, nIndex);
//SendMessageToPC(oCaster, "pe_buffing, 433, nMmSpell: " + IntToString(nMmSpell) +
// " nMetamagic: " + IntToString(nMetamagic) +
// " nDomain: " + IntToString(nDomain) +
// " nDSpell: " + IntToString(nDSpell));
if(nMmSpell == nMetamagic)
{
if(nDSpell == nDomain) return TRUE;
nSpellMemorized = TRUE;
if(GetMemorizedSpellReady(oCaster, nClass, nLevel, nIndex))
{
if((nDomain && nDSpell) || (!nDomain && !nDSpell)) return TRUE;
}
}
}
}
@@ -479,7 +480,6 @@ void PopupWidgetBuffGUIPanel(object oPC)
SetLocalInt(oPC, AI_NO_NUI_SAVE, TRUE);
DelayCommand(0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE));
// Row 1 (buttons)**********************************************************
json jRow = CreateButtonImage(JsonArray(), "ir_level1", "btn_one", 35.0f, 35.0f, 0.0);
jRow = CreateButtonImage(jRow, "ir_level2", "btn_two", 35.0f, 35.0f, 0.0);
jRow = CreateButtonImage(jRow, "ir_level3", "btn_three", 35.0f, 35.0f, 0.0);

File diff suppressed because it is too large Load Diff

View File

@@ -81,6 +81,8 @@ void main()
json jObject = ObjectToJson(oTarget);
string sConversation = JsonGetString(GffGetResRef(jObject, "Conversation"));
ai_SendMessages("Conversation: " + sConversation, AI_COLOR_CYAN, oPC);
int nCurrentAction = GetCurrentAction(oTarget);
ai_SendMessages("Current Action: " + IntToString(nCurrentAction), AI_COLOR_RED, oPC);
SendMessageToPC(oPC, "Creature Event Scripts:");
string sScript = GetEventScript(oTarget, EVENT_SCRIPT_CREATURE_ON_HEARTBEAT);
sScript += " [" + ResManGetAliasFor(sScript, RESTYPE_NCS) + "]";

View File

@@ -32,6 +32,7 @@ void main()
vector vTarget = GetTargetingModeSelectedPosition();
location lLocation = Location(GetArea(oPC), vTarget, GetFacing(oPC));
object oObject = GetLocalObject(oPC, "AI_TARGET_OBJECT");
DeleteLocalString(oPC, AI_TARGET_MODE);
// If the user manually exited targeting mode without selecting a target, return
if(!GetIsObjectValid(oTarget) && vTarget == Vector())
{
@@ -327,6 +328,7 @@ void main()
if(JsonGetType(jLvlStatList) == JSON_TYPE_NULL)
{
RemoveHenchman(oPC, oHenchman);
ChangeToStandardFaction(oHenchman, STANDARD_FACTION_DEFENDER);
// Make sure to get a clean faction version of the henchman here.
jHenchman = ObjectToJson(oHenchman, TRUE);
jHenchman = CreateLevelStatList(jHenchman, oHenchman, oPC);

View File

@@ -54,22 +54,29 @@ void main()
if(StartingUp(oPC)) return;
// Row 1 (Buttons) ********************************************************* 83
json jRow = CreateButtonSelect(JsonArray(), "Save", "btn_save", 60.0f, 30.0f, "btn_save_tooltip");
CreateButton(jRow, "Clear", "btn_clear", 60.0f, 30.0f, -1.0, "btn_clear_tooltip");
CreateButton(jRow, "Buff", "btn_buff", 60.0f, 30.0f, -1.0, "btn_buff_tooltip");
CreateButtonSelect(jRow, "List 1", "btn_list1", 60.0f, 30.0f);
CreateButtonSelect(jRow, "List 2", "btn_list2", 60.0f, 30.0f);
CreateButtonSelect(jRow, "List 3", "btn_list3", 60.0f, 30.0f);
CreateButtonSelect(jRow, "List 4", "btn_list4", 60.0f, 30.0f);
jRow = CreateButton(jRow, "Clear", "btn_clear", 60.0f, 30.0f, -1.0, "btn_clear_tooltip");
jRow = CreateButton(jRow, "Buff", "btn_buff", 60.0f, 30.0f, -1.0, "btn_buff_tooltip");
jRow = CreateButtonSelect(jRow, "List 1", "btn_list1", 60.0f, 30.0f);
jRow = CreateButtonSelect(jRow, "List 2", "btn_list2", 60.0f, 30.0f);
jRow = CreateButtonSelect(jRow, "List 3", "btn_list3", 60.0f, 30.0f);
jRow = CreateButtonSelect(jRow, "List 4", "btn_list4", 60.0f, 30.0f);
// Add the row to the column.
json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow));
// Row 2 (Buttons) ********************************************************* 121
jRow = JsonArrayInsert(JsonArray(), NuiSpacer());
jRow = CreateCheckBox(jRow, "Buff Widget", "buff_widget", 110.0, 30.0f, "buff_widget_tooltip");
jRow = CreateCheckBox(jRow, "Lock Widget", "lock_buff_widget", 110.0, 30.0f, "lock_buff_widget_tooltip");
if(!AI_SERVER)
if(!ai_GetIsServer())
{
jRow = CreateCheckBox(jRow, "Don't Check for Monsters", "chbx_no_monster_check", 200.0, 30.0f, "chbx_no_monster_check_tooltip");
}
else
{
if(ai_GetIsDungeonMaster(oPC))
{
jRow = CreateCheckBox(jRow, "Don't Check for Monsters", "chbx_no_monster_check", 200.0, 30.0f, "chbx_no_monster_check_tooltip");
}
}
jRow = JsonArrayInsert(jRow, NuiSpacer());
// Add the row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
@@ -143,7 +150,7 @@ void main()
NuiSetBindWatch(oPC, nToken, "lock_buff_widget_check", TRUE);
sText = " Locks the buffing widget in place reducing its size.";
NuiSetBind(oPC, nToken, "lock_buff_widget_tooltip", JsonString(sText));
if(!AI_SERVER)
if(!ai_GetIsServer())
{
NuiSetBind(oPC, nToken, "chbx_no_monster_check_event", JsonBool(TRUE));
nValue = GetLocalInt(oPC, FB_NO_MONSTER_CHECK);
@@ -295,44 +302,55 @@ void PopupWidgetBuffGUIPanel(object oPC)
SetLocalInt(oPC, AI_NO_NUI_SAVE, TRUE);
DelayCommand(0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE));
// Row 1 (buttons)**********************************************************
json jRow = JsonArray();
CreateButtonImage(jRow, "ir_level1", "btn_one", 35.0f, 35.0f, 0.0);
CreateButtonImage(jRow, "ir_level2", "btn_two", 35.0f, 35.0f, 0.0);
CreateButtonImage(jRow, "ir_level3", "btn_three", 35.0f, 35.0f, 0.0);
CreateButtonImage(jRow, "ir_level4", "btn_four", 35.0f, 35.0f, 0.0);
json jRow = CreateButtonImage(JsonArray(), "ir_level1", "btn_one", 35.0f, 35.0f, 0.0);
jRow = CreateButtonImage(jRow, "ir_level2", "btn_two", 35.0f, 35.0f, 0.0);
jRow = CreateButtonImage(jRow, "ir_level3", "btn_three", 35.0f, 35.0f, 0.0);
jRow = CreateButtonImage(jRow, "ir_level4", "btn_four", 35.0f, 35.0f, 0.0);
// Add the row to the column.
json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow));
json jWidget = GetBuffDatabaseJson(oPC, "spells", "menudata");
int bAIBuffWidgetLock = JsonGetInt(JsonArrayGet(jWidget, 4));
json jMenuData = GetBuffDatabaseJson(oPC, "spells", "menudata");
int bAIBuffWidgetLock = JsonGetInt(JsonArrayGet(jMenuData, 4));
// Get the window location to restore it from the database.
float fX = JsonGetFloat(JsonArrayGet(jWidget, 5));
float fY = JsonGetFloat(JsonArrayGet(jWidget, 6));
float fX = JsonGetFloat(JsonArrayGet(jMenuData, 5));
float fY = JsonGetFloat(JsonArrayGet(jMenuData, 6));
if(fX == 0.0f && fY == 0.0f)
{
fX = 10.0f;
fY = 10.0f;
}
float fGUI_Scale = IntToFloat(GetPlayerDeviceProperty(oPC, PLAYER_DEVICE_PROPERTY_GUI_SCALE)) / 100.0;
if(bAIBuffWidgetLock)
{
fX = fX + 4.0f;
fY = fY + 45.0f;
fX += 4.0f;
// GUI scales are a mess, I just figured them out per scale to keep the widget from moving.
if(fGUI_Scale == 1.0) fY += 37.0;
else if(fGUI_Scale == 1.1) fY += 38.0;
else if(fGUI_Scale == 1.2) fY += 40.0;
else if(fGUI_Scale == 1.3) fY += 42.0;
else if(fGUI_Scale == 1.4) fY += 43.0;
else if(fGUI_Scale == 1.5) fY += 45.0;
else if(fGUI_Scale == 1.6) fY += 47.0;
else if(fGUI_Scale == 1.7) fY += 48.0;
else if(fGUI_Scale == 1.8) fY += 50.0;
else if(fGUI_Scale == 1.9) fY += 52.0;
else if(fGUI_Scale == 2.0) fY += 54.0;
}
// Set the layout of the window.
json jLayout = NuiCol (jCol);
json jLayout = NuiCol(jCol);
int nToken;
if(bAIBuffWidgetLock) nToken = SetWindow(oPC, jLayout, "widgetbuffwin", "Fast Buff Widget", fX, fY, 160.0, 62.0, FALSE, FALSE, FALSE, TRUE, FALSE, "pe_buffing");
else nToken = SetWindow(oPC, jLayout, "widgetbuffwin", "Fast Buff Widget", fX, fY, 160.0, 95.0, FALSE, FALSE, FALSE, TRUE, TRUE, "pe_buffing");
if(bAIBuffWidgetLock) nToken = SetWindow (oPC, jLayout, "widgetbuffwin", "Fast Buff Widget", fX, fY, 160.0, 62.0, FALSE, FALSE, FALSE, TRUE, FALSE, "pe_buffing");
else nToken = SetWindow (oPC, jLayout, "widgetbuffwin", "Fast Buff Widget", fX, fY, 160.0, 95.0, FALSE, FALSE, FALSE, TRUE, TRUE, "pe_buffing");
// Set event watches for window inspector and save window location.
//NuiSetBindWatch(oPC, nToken, "collapsed", TRUE);
NuiSetBindWatch(oPC, nToken, "window_geometry", TRUE);
NuiSetBindWatch (oPC, nToken, "collapsed", TRUE);
NuiSetBindWatch (oPC, nToken, "window_geometry", TRUE);
// Set the buttons to show events.
//NuiSetBind (oPC, nToken, "btn_one", JsonBool (TRUE));
NuiSetBind(oPC, nToken, "btn_one_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_two", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_two_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_three", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_three_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_four", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_four_event", JsonBool(TRUE));
NuiSetBind (oPC, nToken, "btn_one_event", JsonBool (TRUE));
NuiSetBind (oPC, nToken, "btn_two", JsonBool (TRUE));
NuiSetBind (oPC, nToken, "btn_two_event", JsonBool (TRUE));
NuiSetBind (oPC, nToken, "btn_three", JsonBool (TRUE));
NuiSetBind (oPC, nToken, "btn_three_event", JsonBool (TRUE));
NuiSetBind (oPC, nToken, "btn_four", JsonBool (TRUE));
NuiSetBind (oPC, nToken, "btn_four_event", JsonBool (TRUE));
}

View File

@@ -8,694 +8,20 @@
#include "0i_nui"
#include "0i_items"
#include "nw_inc_gff"
const string CRAFT_JSON = "CRAFT_JSON";
const string CRAFT_COOL_DOWN = "CRAFT_COOL_DOWN";
const string CRAFT_ITEM_SELECTION = "CRAFT_ITEM_SELECTION";
const string CRAFT_MATERIAL_SELECTION = "CRAFT_MATERIAL_SELECTION";
const string CRAFT_MODEL_SELECTION = "CRAFT_MODEL_SELECTION";
const string CRAFT_COLOR_PALLET = "CRAFT_COLOR_PALLET";
const string CRAFT_LEFT_PART_COLOR = "CRAFT_LEFT_PART_COLOR";
const string CRAFT_ALL_COLOR = "CRAFT_ALL_COLOR";
const string CRAFT_RIGHT_PART_COLOR = "CRAFT_RIGHT_PART_COLOR";
const string CRAFT_TARGET = "CRAFT_TARGET";
// Tag used in lighting effects.
const string CRAFT_HIGHLIGHT = "CRAFT_HIGHLIGHT";
const string CRAFT_ULTRALIGHT = "CRAFT_ULTRALIGHT";
json CreateItemCombo(object oPC, json jRow, string sComboBind);
json CreateModelCombo(object oPC, object oTarget, json jRow, string sComboBind);
json CreateMaterialCombo(object oPC, json jRow, string sComboBind);
// Sets the material buttons for use.
// nMaterial 0,1 Cloth 2,3 Leather 4,5 Metal -1 None.
void SetMaterialButtons(object oPC, int nToken, int nMaterial);
// Returns the correct item based on the crafting menu selected item.
object GetSelectedItem(object oTarget, int nItemSelected);
int GetArmorModelSelected(object oPC);
// Returns True if oItem, nPart has a per part color for sSide.
int GetHasPartColor(object oItem, int nPart, string sSide);
// Does startup check if the game has just been loaded.
int StartingUp(object oPC);
void main()
{
object oPC = OBJECT_SELF;
object oTarget = GetLocalObject(oPC, CRAFT_TARGET);
if(oTarget == OBJECT_INVALID) oTarget = oPC;
if(StartingUp(oPC)) return;
json jCraft = GetLocalJson(oPC, CRAFT_JSON);
if(JsonGetType(jCraft) == JSON_TYPE_NULL) jCraft = JsonObject();
// Row 1 (Object Name)****************************************************** 508 / 83
json jRow = CreateTextEditBox(JsonArray(), "plc_hold_bind", "txt_item_name", 50, FALSE, 486.0f, 30.0f); // 419
json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow));
// Row 2 (Object Name)****************************************************** 508 / 121
jRow = JsonArray();
if(!AI_SERVER) jRow = CreateButton(jRow, "Information", "btn_info", 160.0f, 30.0f, -1.0, "btn_info_tooltip");
else
{
if(GetIsDM(oTarget))
{
jRow = CreateButton(jRow, "Information", "btn_info", 160.0f, 30.0f, -1.0, "btn_info_tooltip");
}
else jRow = JsonArrayInsert(jRow, NuiSpacer());
}
jRow = CreateButton(jRow, "Wardrobe", "btn_wardrobe", 158.0f, 30.0f, -1.0, "btn_wardrobe_tooltip");
jRow = CreateButtonSelect(jRow, "Add Light", "btn_highlight", 160.0f, 30.0f, "btn_highlight_tooltip");
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 3 (Object Name)****************************************************** 508 / 159
jRow = CreateButton(JsonArray(), "Save", "btn_save", 160.0f, 30.0f, -1.0, "btn_save_tooltip");
jRow = CreateButton(jRow, "Select Target", "btn_select_target", 158.0f, 30.0f);
jRow = CreateButton(jRow, "", "btn_cancel", 160.0f, 30.0f, -1.0, "btn_cancel_tooltip");
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 4 (labels)*********************************************************** 508 / 177
jRow = CreateLabel(JsonArray(), "Model", "module_title", 143.0f, 10.0f);
jRow = CreateLabel(jRow, "Color", "color_title", 339.0f, 10.0f);
jRow = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 5 (groups)
// Row 51 (title)*********************************************************** 508 / 195 / 18
json jGroupRow = CreateLabel(JsonArray(), "Item", "item__cmb_title", 128.0f, 10.0f);
json jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow));
// Row 52 (combo)*********************************************************** 508 / 233 / 56
jGroupRow = CreateItemCombo(oPC, JsonArray(), "item_combo");
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 53 (title)*********************************************************** 508 / 251 / 74
jGroupRow = CreateLabel(JsonArray(), "Model", "model_cmb_title",128.0f, 10.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 54 (combo)*********************************************************** 508 / 289 / 112
jGroupRow = CreateModelCombo(oPC, oTarget, JsonArray(), "model_combo");
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 55 (title)*********************************************************** 508 / 307 / 120
jGroupRow = CreateLabel(JsonArray(), "", "top_title",128.0f, 10.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 56 (top)************************************************************* 508 / 355 / 168
jGroupRow = CreateButtonImage(JsonArray(), "nui_shld_left", "btn_prev_t", 40.0f, 40.0f);
// Removed TextEditBox for mobile
jGroupRow = CreateTextEditBox(jGroupRow, "place_holder", "txt_model_number_t", 3, FALSE, 40.0, 40.0);
//CreateLabel(jGroupRow, "", "txt_model_number_t", 40.0, 40.0);
jGroupRow = CreateButtonImage(jGroupRow, "nui_shld_right", "btn_next_t", 40.0f, 40.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 57 (title)*********************************************************** 508 / 373 / 186
jGroupRow = CreateLabel(JsonArray(), "", "middle_title",128.0f, 10.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 58 (middle)********************************************************** 508 / 421 /234
jGroupRow = CreateButtonImage(JsonArray(), "nui_shld_left", "btn_prev_m", 40.0f, 40.0f);
// Removed TextEditBox for mobile
jGroupRow = CreateTextEditBox(jGroupRow, "place_holder", "txt_model_number_m", 3, FALSE, 40.0, 40.0);
//CreateLabel(jGroupRow, "", "txt_model_number_m", 40.0, 40.0);
jGroupRow = CreateButtonImage(jGroupRow, "nui_shld_right", "btn_next_m", 40.0f, 40.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 59 (title)*********************************************************** 508 / 439 / 252
jGroupRow = CreateLabel(JsonArray(), "", "bottom_title",128.0f, 10.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 510 (bottom)********************************************************* 508 / 487 /300
jGroupRow = CreateButtonImage(JsonArray(), "nui_shld_left", "btn_prev_b", 40.0f, 40.0f);
// Removed TextEditBox for mobile
jGroupRow = CreateTextEditBox(jGroupRow, "place_holder", "txt_model_number_b", 3, FALSE, 40.0, 40.0);
//CreateLabel(jGroupRow, "", "txt_model_number_b", 40.0, 40.0);
jGroupRow = CreateButtonImage(jGroupRow, "nui_shld_right", "btn_next_b", 40.0f, 40.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 511 (blank spacer)
jGroupRow = CreateLabel(JsonArray(), "", "blank_space",128.0f, 20.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 512 (light)********************************************************** 508 / 487 /300
jGroupRow = CreateButtonSelect(JsonArray(), "Randomize", "btn_randomize", 128.0f, 30.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
jGroupCol = JsonArrayInsert(jGroupCol, NuiSpacer());
jRow = JsonArrayInsert(JsonArray(), NuiHeight(NuiWidth(NuiGroup(NuiCol(jGroupCol)), 143.0), 442.0));
// Make the Color Group.
// Row 550 (groups)********************************************************* 508 / 361 / 184
json jImage = NuiEnabled(NuiId(NuiImage(NuiBind("color_pallet_image"), JsonInt(0), JsonInt(0), JsonInt(1)), "color_pallet"), NuiBind("color_pallet_event"));
jImage = NuiWidth(jImage, 320.0); // 256 + 64
jImage = NuiHeight(jImage, 220.0); // 176 + 44
jImage = NuiTooltip(jImage, NuiBind("color_pallet_tooltip"));
json jIndicator = JsonArrayInsert(JsonArray(), NuiDrawListRect(JsonBool(TRUE), NuiColor(255,0,0), JsonBool(FALSE), JsonFloat(2.0), NuiBind("color_pallet_pointer")));
jImage = NuiDrawList(jImage, JsonBool(FALSE), jIndicator);
jGroupRow = JsonArrayInsert(JsonArray(), jImage);
jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow));
// Row 551 (groups)********************************************************* 508 / 379 /202
jGroupRow = CreateLabel(JsonArray(), "Part To Color", "lbl_color_parts", 320.0f, 10.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 552 (groups)********************************************************* 508 / 417 /240
jGroupRow = CreateButtonSelect(JsonArray(), "Right", "btn_right_part_color", 98.0, 30.0, "btn_right_part_color_tooltip");
jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer());
jGroupRow = CreateButtonSelect(jGroupRow, "All", "btn_all_color", 98.0, 30.0, "btn_all_color_tooltip");
jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer());
jGroupRow = CreateButtonSelect(jGroupRow, "Left", "btn_left_part_color", 98.0, 30.0, "btn_left_part_color_tooltip");
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 553 (groups)********************************************************* 508 / 435 / 258
jGroupRow = CreateLabel(JsonArray(), "Part Color To Reset", "lbl_reset_parts", 320.0f, 10.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 554 (groups)********************************************************* 508 / 473 /296
jGroupRow = CreateButton(JsonArray(), "Right", "btn_right_part_reset", 98.0, 30.0, -1.0, "btn_right_part_reset_tooltip");
jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer());
jGroupRow = CreateButton(jGroupRow, "All", "btn_all_reset", 50.0, 30.0, -1.0, "btn_all_reset_tooltip");
jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer());
jGroupRow = CreateButton(jGroupRow, "Left", "btn_left_part_reset", 98.0, 30.0, -1.0, "btn_left_part_reset_tooltip");
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 555 (groups)********************************************************* 508 / 491 / 314
jGroupRow = CreateLabel(JsonArray(), "Material to Color", "lbl_material_color", 320.0f, 10.0f);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 556 (groups)********************************************************* 508 / 529 /352
jGroupRow = CreateButtonSelect(JsonArray(), "Cloth 1", "btn_material_0", 98.0, 30.0);
jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer());
jGroupRow = CreateButtonSelect(jGroupRow, "Leather 1", "btn_material_2", 98.0, 30.0);
jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer());
jGroupRow = CreateButtonSelect(jGroupRow, "Metal 1", "btn_material_4", 98.0, 30.0);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
// Row 557 (groups)********************************************************* 508 / 567 / 390
jGroupRow = CreateButtonSelect(JsonArray(), "Cloth 2", "btn_material_1", 98.0, 30.0);
jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer());
jGroupRow = CreateButtonSelect(jGroupRow, "Leather 2", "btn_material_3", 98.0, 30.0);
jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer());
jGroupRow = CreateButtonSelect(jGroupRow, "Metal 2", "btn_material_5", 98.0, 30.0);
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
jGroupCol = JsonArrayInsert(jGroupCol, NuiSpacer());
jRow = JsonArrayInsert(jRow, NuiHeight(NuiWidth(NuiGroup(NuiCol(jGroupCol)), 339.0), 442.0)); // 275 398
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
json jLayout = NuiCol(jCol);
// Get the window location to restore it from the database.
json jGeometry = JsonObjectGet(jCraft, "CRAFT_MENU");
float fX = JsonGetFloat(JsonObjectGet(jGeometry, "x"));
float fY = JsonGetFloat(JsonObjectGet(jGeometry, "y"));
string sPCWindow;
int nToken = SetWindow(oPC, jLayout, "crafting_nui", "Crafting",
fX, fY, 508.0, 700.0, FALSE, FALSE, FALSE, FALSE, TRUE, "pe_crafting"); // 444 645
// Set all binds, events, and watches.
NuiSetBindWatch (oPC, nToken, "window_geometry", TRUE);
int nItem = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION));
object oItem = GetSelectedItem(oTarget, nItem);
// Row 1
NuiSetBind(oPC, nToken, "txt_item_name", JsonString(GetName(oItem)));
NuiSetBind(oPC, nToken, "txt_item_name_event", JsonBool(TRUE));
NuiSetBindWatch(oPC, nToken, "txt_item_name", TRUE);
// Row 2
NuiSetBind(oPC, nToken, "btn_info_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_info_tooltip", JsonString(" Look at and change item information"));
NuiSetBind(oPC, nToken, "btn_wardrobe_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_wardrobe_tooltip", JsonString(" Use your wardrobe to save/load item appearances"));
int nLight = GetLocalInt(oPC, CRAFT_HIGHLIGHT) + GetLocalInt(oPC, CRAFT_ULTRALIGHT);
NuiSetBind(oPC, nToken, "btn_highlight", JsonBool(nLight));
NuiSetBind(oPC, nToken, "btn_highlight_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_highlight_tooltip", JsonString(" Left click for White light, Right click for Ultravision"));
// Row 3
NuiSetBind(oPC, nToken, "btn_save_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_save_tooltip", JsonString(" Save current changes"));
NuiSetBind(oPC, nToken, "btn_select_target_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_cancel_label", JsonString("Exit"));
NuiSetBind(oPC, nToken, "btn_cancel_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_cancel_tooltip", JsonString(" Exit the crafting menu"));
// Row 4 Labels.
// Row 5 Groups.
// Row 51 title.
// Row 52
NuiSetBind(oPC, nToken, "item_combo_selected", JsonInt(nItem));
NuiSetBind(oPC, nToken, "item_combo_event", JsonBool(TRUE));
NuiSetBindWatch(oPC, nToken, "item_combo_selected", TRUE);
// Row 53 title.
// Row 54
int nSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MODEL_SELECTION));
if(nItem == 1 || nItem == 2 || nItem == 4)
{
if(GetHiddenWhenEquipped(oItem)) nSelected = 1;
else nSelected = 0;
}
NuiSetBind(oPC, nToken, "model_combo_selected", JsonInt (nSelected));
NuiSetBind(oPC, nToken, "model_combo_event", JsonBool (TRUE));
NuiSetBindWatch(oPC, nToken, "model_combo_selected", TRUE);
// Row 55, 56, 57 titles
// Row 58 top, 59 middle, 510 bottom
string sModelTop, sModelMiddle, sModelBottom;
// Model Group
if(ai_GetIsWeapon(oItem))
{
int nModel = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, 0);
int nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_COLOR, 0);
int nModelNumber = (nModel * 10) + nColor;
sModelTop = IntToString(nModelNumber);
nModel = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, 1);
nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_COLOR, 1);
nModelNumber = (nModel * 10) + nColor;
sModelMiddle = IntToString(nModelNumber);
nModel = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_MODEL, 2);
nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_WEAPON_COLOR, 2);
nModelNumber = (nModel * 10) + nColor;
sModelBottom = IntToString(nModelNumber);
// Row 55
NuiSetBind(oPC, nToken, "top_title_label", JsonString("Top"));
// Row 56
//NuiSetBind(oPC, nToken, "txt_model_number_t_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "txt_model_number_t", JsonString(sModelTop));
NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(TRUE));
// Row 57
NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Middle"));
// Row 58
//NuiSetBind(oPC, nToken, "txt_model_number_m_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelMiddle));
NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE));
// Row 59
NuiSetBind(oPC, nToken, "bottom_title_label", JsonString("Bottom"));
// Row 510
//NuiSetBind(oPC, nToken, "txt_model_number_b_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString(sModelBottom));
NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(TRUE));
// Row 511
NuiSetBind(oPC, nToken, "btn_randomize_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_randomize_tooltip", JsonString(" Randomize the selected weapon"));
}
// Armor and clothing
else if(nItem == 0)
{
nSelected = GetArmorModelSelected(oPC);
// These models only have one side so make sure we are not linked.
if (nSelected == ITEM_APPR_ARMOR_MODEL_NECK ||
nSelected == ITEM_APPR_ARMOR_MODEL_TORSO ||
nSelected == ITEM_APPR_ARMOR_MODEL_BELT ||
nSelected == ITEM_APPR_ARMOR_MODEL_PELVIS ||
nSelected == ITEM_APPR_ARMOR_MODEL_ROBE)
{
sModelMiddle = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nSelected));
// Row 55
NuiSetBind(oPC, nToken, "top_title_label", JsonString(""));
// Row 56
//NuiSetBind(oPC, nToken, "txt_model_number_t_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "txt_model_name_t", JsonString(""));
NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(FALSE));
// Row 57
NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Model"));
// Row 58
//NuiSetBind(oPC, nToken, "txt_model_number_m_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelMiddle));
NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE));
// Row 59
NuiSetBind(oPC, nToken, "bottom_title_label", JsonString(""));
// Row 510
//NuiSetBind(oPC, nToken, "txt_model_number_b_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString(""));
NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(FALSE));
}
else
{
sModelTop = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nSelected));
if(nSelected == ITEM_APPR_ARMOR_MODEL_RTHIGH) nSelected--;
else nSelected++;
sModelBottom = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, nSelected));
// Row 55
NuiSetBind(oPC, nToken, "top_title_label", JsonString("Right"));
// Row 56
//NuiSetBind(oPC, nToken, "txt_model_number_t_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "txt_model_number_t", JsonString(sModelTop));
NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(TRUE));
// Row 57
NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Right & Left"));
// Row 58
//NuiSetBind(oPC, nToken, "txt_model_number_m_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelTop));
NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE));
// Row 59
NuiSetBind(oPC, nToken, "bottom_title_label", JsonString("Left"));
// Row 510
//NuiSetBind(oPC, nToken, "txt_model_number_b_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString(sModelBottom));
NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(TRUE));
}
// Row 511
NuiSetBind(oPC, nToken, "btn_randomize_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_randomize_tooltip", JsonString(" Randomize the selected armor"));
}
// Shields, Cloaks, and Helmets.
else
{
sModelMiddle = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0));
// Row 55
NuiSetBind(oPC, nToken, "top_title_label", JsonString(""));
// Row 56
//NuiSetBind(oPC, nToken, "txt_model_number_t_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "txt_model_number_t", JsonString(""));
NuiSetBind(oPC, nToken, "btn_prev_t_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_next_t_event", JsonBool(FALSE));
// Row 57
NuiSetBind(oPC, nToken, "middle_title_label", JsonString("Model"));
// Row 58
//NuiSetBind(oPC, nToken, "txt_model_number_m_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "txt_model_number_m", JsonString(sModelMiddle));
NuiSetBind(oPC, nToken, "btn_prev_m_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_next_m_event", JsonBool(TRUE));
// Row 59
NuiSetBind(oPC, nToken, "bottom_title_label", JsonString(""));
// Row 510
//NuiSetBind(oPC, nToken, "txt_model_number_b_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "txt_model_number_b", JsonString(""));
NuiSetBind(oPC, nToken, "btn_prev_b_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_next_b_event", JsonBool(FALSE));
// Row 511
NuiSetBind(oPC, nToken, "btn_randomize_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_randomize_tooltip", JsonString(" Randomize the selected item"));
}
// Color Group
if(ai_GetIsWeapon(oItem) || ai_GetIsShield(oItem))
{
// Need to disable the color widgets.
// Row 511
NuiSetBind(oPC, nToken, "color_pallet_image", JsonString("gui_pal_tattoo"));
NuiSetBind(oPC, nToken, "color_pallet_image_event", JsonBool(FALSE));
// Row 512 - Label Part to Color
// Row 5l3
NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(FALSE));
// Row 514 - Label Part Color to Reset
// Row 515
NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(FALSE));
// Row 516 - Label Material to Color
// Row 517
NuiSetBind(oPC, nToken, "btn_material_0", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_material_2", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_material_4", JsonBool(FALSE));
// Row 518
NuiSetBind(oPC, nToken, "btn_material_1", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_material_3", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_material_5", JsonBool(FALSE));
SetMaterialButtons(oPC, nToken, -1);
}
// Armor and clothing
else if(nItem == 0)
{
// Row 511
string sColorPallet = GetLocalString(oPC, CRAFT_COLOR_PALLET);
if(sColorPallet == "") sColorPallet = "gui_pal_tattoo";
int nMaterialSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION));
int nModelSelected = GetArmorModelSelected(oPC);
// Row 511
NuiSetBind(oPC, nToken, "color_pallet_image", JsonString(sColorPallet));
NuiSetBind(oPC, nToken, "color_pallet_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "color_pallet_tooltip", JsonString(" Select a color or use the mouse wheel"));
int nSelectedRight, nSelectedAll, nSelectedLeft;
string sColorAll = IntToString(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected));
// These models only have one side so make sure we are not linked.
if (nModelSelected == ITEM_APPR_ARMOR_MODEL_NECK ||
nModelSelected == ITEM_APPR_ARMOR_MODEL_TORSO ||
nModelSelected == ITEM_APPR_ARMOR_MODEL_BELT ||
nModelSelected == ITEM_APPR_ARMOR_MODEL_PELVIS ||
nModelSelected == ITEM_APPR_ARMOR_MODEL_ROBE)
{
// Row 512 - Label Part to Color
// Row 5l3
int nPartColor = GetHasPartColor(oItem, nModelSelected, "Right");
nSelectedRight = JsonGetInt(JsonObjectGet(jCraft, CRAFT_RIGHT_PART_COLOR));
if(!nSelectedRight && nPartColor)
{
nSelectedRight = TRUE;
nSelectedLeft = FALSE;
}
nSelectedAll = !nSelectedRight;
jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonBool(nSelectedAll));
jCraft = JsonObjectSet(jCraft, CRAFT_RIGHT_PART_COLOR, JsonBool(nSelectedRight));
NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(nSelectedRight));
NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(nSelectedAll));
NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(FALSE));
// Row 514 - Label Part Color to Reset
// Row 5l5
nSelectedRight = GetHasPartColor(oItem, nModelSelected, "Right");
nSelectedAll = nSelectedRight;
NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(nSelectedRight));
NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(nSelectedAll));
NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(FALSE));
}
else
{
// Row 512 - Label Part to Color
// Row 5l3
int nPartColor = GetHasPartColor(oItem, nModelSelected, "Right");
nSelectedRight = JsonGetInt(JsonObjectGet(jCraft, CRAFT_RIGHT_PART_COLOR));
if(!nSelectedRight && nPartColor)
{
nSelectedRight = TRUE;
nSelectedLeft = FALSE;
}
else
{
nPartColor = GetHasPartColor(oItem, nModelSelected, "Left");
nSelectedLeft = JsonGetInt(JsonObjectGet(jCraft, CRAFT_LEFT_PART_COLOR));
if(!nSelectedLeft && nPartColor)
{
nSelectedLeft = TRUE;
nSelectedRight = FALSE;
}
}
nSelectedAll = !nSelectedRight && !nSelectedLeft;
jCraft = JsonObjectSet(jCraft, CRAFT_LEFT_PART_COLOR, JsonBool(nSelectedLeft));
jCraft = JsonObjectSet(jCraft, CRAFT_ALL_COLOR, JsonBool(nSelectedAll));
jCraft = JsonObjectSet(jCraft, CRAFT_RIGHT_PART_COLOR, JsonBool(nSelectedRight));
NuiSetBind(oPC, nToken, "btn_right_part_color", JsonBool(nSelectedRight));
NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(nSelectedAll));
NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(nSelectedLeft));
NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(TRUE));
// Row 514 - Label Part Color to Reset
// Row 5l5
nSelectedRight = GetHasPartColor(oItem, nModelSelected, "Right");
nSelectedLeft = GetHasPartColor(oItem, nModelSelected, "Left");
nSelectedAll = nSelectedRight || nSelectedLeft;
NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(nSelectedRight));
NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(nSelectedAll));
NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(nSelectedLeft));
}
int nColor;
if(!JsonGetInt(NuiGetBind(oPC, nToken, "btn_all_color")))
{
int nModelSelected = GetArmorModelSelected(oPC);
if(!JsonGetInt(JsonObjectGet(jCraft, CRAFT_RIGHT_PART_COLOR)))
{
// Note: Right Thigh and Left Thigh are backwards so this fixes that!
if (nModelSelected == ITEM_APPR_ARMOR_MODEL_RTHIGH) nModelSelected--;
else nModelSelected++;
}
int nIndex = ITEM_APPR_ARMOR_NUM_COLORS + (nModelSelected * ITEM_APPR_ARMOR_NUM_COLORS) + nMaterialSelected;
nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nIndex);
}
else nColor = 255;
if(nColor == 255) nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected);
float fPointX = IntToFloat((nColor - ((nColor / 16) * 16)) * 20);
float fPointY = IntToFloat((nColor / 16) * 20);
NuiSetBind(oPC, nToken, "color_pallet_pointer", NuiRect(fPointX, fPointY, 20.0, 20.0));
// Row 516 - Label Material to Color
// Row 517 & 518
NuiSetBind(oPC, nToken, "btn_right_part_color_tooltip", JsonString(" Select the right part to be uniquely colored"));
NuiSetBind(oPC, nToken, "btn_all_color_tooltip", JsonString(" Select all parts to be colored"));
NuiSetBind(oPC, nToken, "btn_left_part_color_tooltip", JsonString(" Select the left part to be uniquely colored"));
NuiSetBind(oPC, nToken, "btn_right_part_reset_tooltip", JsonString(" Clears the right part's unique color"));
NuiSetBind(oPC, nToken, "btn_all_reset_tooltip", JsonString(" Clears all parts unique colors"));
NuiSetBind(oPC, nToken, "btn_left_part_reset_tooltip", JsonString(" Clears the left part's unique color"));
nSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION));
SetMaterialButtons(oPC, nToken, nSelected);
SetLocalJson(oPC, CRAFT_JSON, jCraft);
}
// Cloaks and Helmets.
else
{
// Row 511
string sColorPallet = GetLocalString(oPC, CRAFT_COLOR_PALLET);
if(sColorPallet == "") sColorPallet = "gui_pal_tattoo";
int nMaterialSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION));
int nModelSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MODEL_SELECTION));
int nColor = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected);
float fPointX = IntToFloat((nColor - ((nColor / 16) * 16)) * 20);
float fPointY = IntToFloat((nColor / 16) * 20);
NuiSetBind(oPC, nToken, "color_pallet_pointer", NuiRect(fPointX, fPointY, 20.0, 20.0));
NuiSetBind(oPC, nToken, "color_pallet_image", JsonString(sColorPallet));
NuiSetBind(oPC, nToken, "color_pallet_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "color_pallet_tooltip", JsonString(" Select a color or use the mouse wheel"));
// Row 512 - Label Part to Color
// Row 5l3
NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_right_part_color_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_all_color_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_all_color", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_left_part_color_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_left_part_color", JsonBool(FALSE));
// Row 514 - Label Part Color to Reset
// Row 5l5
NuiSetBind(oPC, nToken, "btn_right_part_reset_event", JsonBool(FALSE));
//NuiSetBind(oPC, nToken, "btn_all_reset_event", JsonBool(FALSE));
NuiSetBind(oPC, nToken, "btn_left_part_reset_event", JsonBool(FALSE));
// Row 516 - Label Material to Color
// Row 517 & 518
nSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MATERIAL_SELECTION));
SetMaterialButtons(oPC, nToken, nSelected);
}
// Lets make sure we clean up any cool down variables.
//DeleteLocalInt(oPC, CRAFT_COOL_DOWN);
}
json CreateItemCombo(object oPC, json jRow, string sComboBind)
{
int nCnt;
// Create the list.
json jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Armor", 0));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Cloak", 1));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Headgear", 2));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Right hand", 3));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Left hand", 4));
return CreateCombo(jRow, jCombo, sComboBind, 128.0, 40.0);
}
json CreateModelCombo(object oPC, object oTarget, json jRow, string sComboBind)
{
float fFacing = GetFacing(oTarget);
json jCombo, jCraft = GetLocalJson(oPC, CRAFT_JSON);
int nSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_ITEM_SELECTION));
// Create the list.
// Armor.
if(nSelected == 0)
{
fFacing += 180.0f;
if (fFacing > 359.0) fFacing -=359.0;
AssignCommand(oPC, SetCameraFacing(fFacing, 4.5f, 75.0, CAMERA_TRANSITION_TYPE_VERY_FAST));
jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Neck", 0));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Shoulder", 1));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Bicep", 2));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Forearm", 3));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Hand", 4));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Torso", 5));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Belt", 6));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Pelvis", 7));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Thigh", 8));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Shin", 9));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Foot", 10));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Robe", 11));
}
// Cloak.
else if(nSelected == 1)
{
if(fFacing > 359.0) fFacing -=359.0;
AssignCommand (oPC, SetCameraFacing(fFacing, 4.5f, 75.0, CAMERA_TRANSITION_TYPE_VERY_FAST));
jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Cloak", 0));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Invisible", 1));
}
// Headgear.
else if (nSelected == 2)
{
fFacing += 180.0f;
if(fFacing > 359.0) fFacing -=359.0;
AssignCommand(oPC, SetCameraFacing(fFacing, 2.5f, 75.0, CAMERA_TRANSITION_TYPE_VERY_FAST));
jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Headgear", 0));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Invisible", 1));
}
// Weapon.
else if (nSelected == 3)
{
// If they are changing a bow then face the opposite side.
object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
int nBaseItemType = GetBaseItemType(oItem);
if(nBaseItemType == BASE_ITEM_LONGBOW || nBaseItemType == BASE_ITEM_SHORTBOW) fFacing -= 90.00;
// This will make the camera face a melee weapon.
else fFacing += 90.0;
if(fFacing > 359.0) fFacing -=359.0;
AssignCommand(oPC, SetCameraFacing(fFacing, 3.5f, 75.0, CAMERA_TRANSITION_TYPE_VERY_FAST));
jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Weapon", 0));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Acidic", 1));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Frost", 2));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Electric", 3));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Unholy", 4));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Flaming", 5));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Holy", 6));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Sonic", 7));
}
// Weapon/Shield.
else if(nSelected == 4)
{
fFacing += 270.0f;
if(fFacing > 359.0) fFacing -=359.0;
AssignCommand(oPC, SetCameraFacing(fFacing, 3.5f, 75.0, CAMERA_TRANSITION_TYPE_VERY_FAST));
object oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC);
if(ai_GetIsShield(oItem))
{
jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Shield", 0));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Invisible", 1));
}
else
{
jCombo = JsonArrayInsert(JsonArray(), NuiComboEntry("Weapon", 0));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Acidic", 1));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Frost", 2));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Electric", 3));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Unholy", 4));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Flaming", 5));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Holy", 6));
jCombo = JsonArrayInsert(jCombo, NuiComboEntry("Sonic", 7));
}
}
return CreateCombo(jRow, jCombo, sComboBind, 128.0, 40.0);
}
void SetMaterialButtons(object oPC, int nToken, int nMaterial)
{
int nIndex, bBool, bUseable;
string sIndex;
if(nMaterial > -1) bUseable = TRUE;
for(nIndex = 0;nIndex < 6;nIndex++)
{
if(nIndex == nMaterial) bBool = TRUE;
else bBool = FALSE;
sIndex = IntToString(nIndex);
NuiSetBind(oPC, nToken, "btn_material_" + sIndex + "_event", JsonBool(bUseable));
NuiSetBind(oPC, nToken, "btn_material_" + sIndex, JsonBool(bBool));
}
}
object GetSelectedItem(object oTarget, int nItemSelected)
{
if(nItemSelected == 0) return GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget);
else if(nItemSelected == 1) return GetItemInSlot(INVENTORY_SLOT_CLOAK, oTarget);
else if(nItemSelected == 2) return GetItemInSlot(INVENTORY_SLOT_HEAD, oTarget);
else if(nItemSelected == 3) return GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
else if(nItemSelected == 4) return GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget);
return OBJECT_INVALID;
}
int GetArmorModelSelected(object oPC)
{
json jCraft = GetLocalJson(oPC, CRAFT_JSON);
int nModelSelected = JsonGetInt(JsonObjectGet(jCraft, CRAFT_MODEL_SELECTION));
if(nModelSelected == 0) return ITEM_APPR_ARMOR_MODEL_NECK;
if(nModelSelected == 1) return ITEM_APPR_ARMOR_MODEL_RSHOULDER;
if(nModelSelected == 2) return ITEM_APPR_ARMOR_MODEL_RBICEP;
if(nModelSelected == 3) return ITEM_APPR_ARMOR_MODEL_RFOREARM;
if(nModelSelected == 4) return ITEM_APPR_ARMOR_MODEL_RHAND;
if(nModelSelected == 5) return ITEM_APPR_ARMOR_MODEL_TORSO;
if(nModelSelected == 6) return ITEM_APPR_ARMOR_MODEL_BELT;
if(nModelSelected == 7) return ITEM_APPR_ARMOR_MODEL_PELVIS;
if(nModelSelected == 8) return ITEM_APPR_ARMOR_MODEL_RTHIGH;
if(nModelSelected == 9) return ITEM_APPR_ARMOR_MODEL_RSHIN;
if(nModelSelected == 10) return ITEM_APPR_ARMOR_MODEL_RFOOT;
return ITEM_APPR_ARMOR_MODEL_ROBE;
}
int GetHasPartColor(object oItem, int nPart, string sSide)
{
json jItem = ObjectToJson(oItem);
string sPartName = "APart_";
if(sSide == "Left")
{
// Note: Right Thigh and Left Thigh are backwards so this fixes that!
if (nPart == ITEM_APPR_ARMOR_MODEL_RTHIGH) nPart--;
else nPart++;
}
sPartName += IntToString(nPart) + "_Col_";
int nPartColor = JsonGetInt(GffGetByte(jItem, sPartName + "0"));
nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "1"));
nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "2"));
nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "3"));
nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "4"));
nPartColor += JsonGetInt(GffGetByte(jItem, sPartName + "5"));
return nPartColor;
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_crafting");
// Set Targeting variables.
SetLocalString(oPC, AI_TARGET_MODE, "SELECT_TARGET");
ai_SendMessages("Select your charcter, a henchman or an item possessed by one.", AI_COLOR_YELLOW, oPC);
EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE | OBJECT_TYPE_ITEM , MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE);
}
int StartingUp(object oPC)
{

View File

@@ -16,7 +16,7 @@ void main()
//SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE);
//DelayCommand (0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE));
string sText = " [Single player]";
if(AI_SERVER) sText = " [Server]";
if(ai_GetIsServer()) sText = " [Server]";
// ************************************************************************* Width / Height
// Row 1 ******************************************************************* 500 / 73
json jRow = JsonArrayInsert(JsonArray(), NuiSpacer());
@@ -30,20 +30,26 @@ void main()
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 3 ******************************************************************* 500 / 101
sText = "Monster AI (nw_c2_default1): " + ResManGetAliasFor("nw_c2_default1", RESTYPE_NCS);
jRow = CreateLabel(JsonArray(), sText, "monster_1_ai", 470.0f, 20.0f, NUI_HALIGN_CENTER);
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
sText = ResManGetAliasFor("nw_c2_default1", RESTYPE_NCS);
if(sText != "")
{
jRow = CreateLabel(JsonArray(), "Monster AI (nw_c2_default1): " + sText, "monster_1_ai", 470.0f, 20.0f);
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
}
// Row 4 ******************************************************************* 500 / 157
sText = "Monster AI (j_ai_onheartbeat): " + ResManGetAliasFor("j_ai_onheartbeat", RESTYPE_NCS);
jRow = CreateLabel(JsonArray(), sText, "monster_2_ai", 470.0f, 20.0f, NUI_HALIGN_CENTER);
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
sText = ResManGetAliasFor("j_ai_onheartbeat", RESTYPE_NCS);
if(sText != "")
{
jRow = CreateLabel(JsonArray(), "Monster AI (j_ai_onheartbeat): " + sText, "monster_2_ai", 470.0f, 20.0f);
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
}
// Row 5 ******************************************************************* 500 / 213
sText = "Associate AI (nw_ch_ac1): " + ResManGetAliasFor("nw_ch_ac1", RESTYPE_NCS);
jRow = CreateLabel(JsonArray(), sText, "henchman_ai", 470.0f, 20.0f, NUI_HALIGN_CENTER);
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
sText = ResManGetAliasFor("nw_ch_ac1", RESTYPE_NCS);
if(sText != "")
{
jRow = CreateLabel(JsonArray(), "Associate AI (nw_ch_ac1): " + sText, "henchman_ai", 470.0f, 20.0f);
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
}
// Row 6 ******************************************************************* 500 / 241
jRow = JsonArrayInsert(JsonArray(), NuiSpacer());
jRow = CreateButton(jRow, "Set NPC's scripts", "btn_npc_scripts", 150.0f, 20.0f, -1.0, "btn_npc_scripts_tooltip");

View File

@@ -369,11 +369,12 @@ void RemoveYourHenchman(object oPC, int nToken, string sParty)
else
{
RemoveHenchman(oPC, oHenchman);
ChangeToStandardFaction(oHenchman, STANDARD_FACTION_DEFENDER);
AssignCommand(oHenchman, SetIsDestroyable(TRUE, FALSE, FALSE));
NuiDestroy(oPC, NuiFindWindow(oPC, ai_GetAssociateType(oPC, oHenchman) + AI_WIDGET_NUI));
DestroyObject(oHenchman);
ai_SendMessages(GetName(oHenchman) + " has been removed from the party!", AI_COLOR_GREEN, oPC);
}
ai_SendMessages(GetName(oHenchman) + " has been removed from the party!", AI_COLOR_GREEN, oPC);
NuiDestroy(oPC, nToken);
ExecuteScript("pi_henchmen", oPC);
}
@@ -388,6 +389,7 @@ void RemoveWholeParty(object oPC, int nToken, string sParty)
{
ai_SendMessages(GetName(oHenchman) + " has been remove from your Party.", AI_COLOR_YELLOW, oPC);
RemoveHenchman(oPC, oHenchman);
ChangeToStandardFaction(oHenchman, STANDARD_FACTION_DEFENDER);
AssignCommand(oHenchman, SetIsDestroyable(TRUE, FALSE, FALSE));
NuiDestroy(oPC, NuiFindWindow(oPC, ai_GetAssociateType(oPC, oHenchman) + AI_WIDGET_NUI));
DestroyObject(oHenchman);
@@ -417,7 +419,11 @@ void SaveYourHenchman(object oPC, int nToken, string sParty)
if(sName == sHenchmanName || sName == "")
{
sSlot = sParty + sIndex;
if(!bPC) RemoveHenchman(oPC, oHenchman);
if(!bPC)
{
RemoveHenchman(oPC, oHenchman);
ChangeToStandardFaction(oHenchman, STANDARD_FACTION_DEFENDER);
}
// Special check for Infinite Dungeon plot givers to be changed into henchman.
if(GetStringLeft(GetLocalString(oHenchman, "sConversation"), 8) == "id1_plot")
{
@@ -426,10 +432,13 @@ void SaveYourHenchman(object oPC, int nToken, string sParty)
ChangeToStandardFaction(oHenchman, STANDARD_FACTION_DEFENDER);
json jHenchman = ObjectToJson(oHenchman, TRUE);
if(!bPC) AddHenchman(oPC, oHenchman);
else DestroyObject(oHenchman);
//string sPatch = "[{\"op\":\"replace\",\"path\":\"/FactionID/value\",\"value\":1}]";
//json jPatch = JsonParse(sPatch);
//jHenchman = JsonPatch(jHenchman, jPatch);
else
{
DestroyObject(oHenchman);
// We need to make sure the henchman is not seen as a PC or DM!
jHenchman = GffReplaceByte(jHenchman, "IsPC", 0);
jHenchman = GffReplaceByte(jHenchman, "IsDM", 0);
}
CheckHenchmanDataAndInitialize(oPC, sSlot);
SetHenchmanDbString(oPC, "image", GetPortraitResRef(oHenchman), sSlot);
SetHenchmanDbString(oPC, "henchname", sHenchmanName, sSlot);
@@ -456,9 +465,7 @@ void SaveYourHenchman(object oPC, int nToken, string sParty)
}
nIndex++;
}
if(nIndex == nMaxHenchman) ai_SendMessages("This party is full!", AI_COLOR_RED, oPC);
NuiDestroy(oPC, nToken);
ExecuteScript("pi_henchmen", oPC);
if(nIndex == nMaxHenchman) ai_SendMessages("This party is full!", AI_COLOR_RED, oPC);
}
void SaveWholeParty(object oPC, int nToken, string sParty)
{
@@ -672,11 +679,11 @@ int GetSelectionByPackage2DA(string sClass, int nPackage)
if(Get2DAString("packages", "ClassID", nIndex) == sClass)
{
sPackageName = GetStringByStrRef(StringToInt(Get2DAString("packages", "Name", nIndex)));
if(sPackageName != "Bad Strref" && sPackageName != "")
{
//if(sPackageName != "Bad Strref" && sPackageName != "")
//{
if(nPackage == nIndex) return nSelection;
nSelection++;
}
//}
}
nIndex++;
}
@@ -817,7 +824,22 @@ json CreateLevelStatList(json jHenchman, object oHenchman, object oPC, int nLeve
WriteTimestampedLogEntry("pinc_henchmen, 813, Creating LvlStatList for " + GetName(oHenchman));
return GffAddList(jHenchman, "LvlStatList", jLevelArray);
}
int CanSelectFeat(json jCreature, object oCreature, int nFeat, int nPosition = 1)
int GetHasJFeat(int nFeat, json jFeatList)
{
int nIndex, nJFeat, nMaxFeats = JsonGetLength(jFeatList);
json jFeat;
//WriteTimestampedLogEntry("pinc_henchmen, 831, nFeat: " + IntToString(nFeat) + " nMaxFeats: " + IntToString(nMaxFeats) + ".");
while(nIndex < nMaxFeats)
{
jFeat = JsonArrayGet(jFeatList, nIndex);
nJFeat = JsonGetInt(GffGetWord(jFeat, "Feat"));
//WriteTimestampedLogEntry("pinc_henchmen, 831, nJFeat: " + IntToString(nJFeat) + ".");
if(nJFeat == nFeat) return TRUE;
nIndex++;
}
return FALSE;
}
int CanSelectFeat(json jCreature, object oCreature, int nFeat, json jFeats, int nPosition = 1)
{
// Check if all classes can use.
int n2DAStat = StringToInt(Get2DAString("feat", "ALLCLASSESCANUSE", nFeat));
@@ -855,28 +877,30 @@ int CanSelectFeat(json jCreature, object oCreature, int nFeat, int nPosition = 1
n2DAStat = StringToInt(Get2DAString("feat", "MINSPELLLVL", nFeat));
int nSpellLevel = 0, nClass = GetClassByPosition(nPosition, oCreature);
string s2DAName = Get2DAString("classes", "SpellGainTable", nClass);
int nLevel = GetLevelByPosition(nPosition, oCreature);
if(s2DAName != "")
{
int nLevel = GetLevelByPosition(nPosition, oCreature);
nSpellLevel = StringToInt(Get2DAString(s2DAName, "NumSpellLevels", nLevel - 1)) - 1;
if(nSpellLevel < 0) nSpellLevel = 0;
}
if(nSpellLevel < n2DAStat) return FALSE;
n2DAStat = StringToInt(Get2DAString("feat", "PREREQFEAT1", nFeat));
if(n2DAStat > 0)
if(n2DAStat > 0 && GetHasJFeat(n2DAStat, jFeats))
{
// ************************************** Add code to search jCreature's feats!
if(!GetHasFeat(n2DAStat, oCreature)) return FALSE;
n2DAStat = StringToInt(Get2DAString("feat", "PREREQFEAT2", nFeat));
if(!GetHasFeat(n2DAStat, oCreature)) return FALSE;
if(n2DAStat > 0 && !GetHasJFeat(n2DAStat, jFeats)) return FALSE;
}
int nIndex;
while(nIndex < 5)
{
n2DAStat = StringToInt(Get2DAString("feat", "OrReqFeat" + IntToString(nIndex), nFeat));
if(nIndex == 0 && n2DAStat == 0) break;
if(GetHasFeat(n2DAStat, oCreature)) break;
nIndex++;
if(nIndex == 5) return FALSE;
if(n2DAStat > 0)
{
if(GetHasJFeat(n2DAStat, jFeats)) break;
}
else return FALSE;
++nIndex;
}
string s2DAStat = Get2DAString("feat", "REQSKILL", nFeat);
if(s2DAStat != "")
@@ -969,7 +993,7 @@ json ResetFeats(json jHenchman, object oHenchman)
int nRace = GetRacialType(oHenchman);
string sRace2DAName = Get2DAString("racialtypes", "FeatsTable", nRace);
// Give racial feats.
WriteTimestampedLogEntry("pinc_henchmen, 972, Checking for racial feats.");
WriteTimestampedLogEntry("pinc_henchmen, 996, Checking for racial feats.");
int nRaceRow, nRaceFeat;
int nRaceMaxRow = Get2DARowCount(sRace2DAName);
while(nRaceRow < nRaceMaxRow)
@@ -979,12 +1003,12 @@ json ResetFeats(json jHenchman, object oHenchman)
jFeat = GffAddWord(jFeat, "Feat", nRaceFeat);
jFeat = JsonObjectSet(jFeat, "__struct_id", JsonInt(1));
jFeatList = JsonArrayInsert(jFeatList, jFeat);
WriteTimestampedLogEntry("pinc_henchmen, 982, Adding racial feat: " +
WriteTimestampedLogEntry("pinc_henchmen, 1006, Adding racial feat: " +
Get2DAString("feat", "LABEL", nRaceFeat));
nRaceRow++;
}
// Give class feats.
WriteTimestampedLogEntry("pinc_henchmen, 972, Checking for class feats.");
WriteTimestampedLogEntry("pinc_henchmen, 1011, Checking for class feats.");
int nClass = GetClassByPosition(1, oHenchman);
string sGranted, sList;
string sClsFeat2DAName = Get2DAString("classes", "FeatsTable", nClass);
@@ -1002,17 +1026,17 @@ json ResetFeats(json jHenchman, object oHenchman)
jFeat = GffAddWord(jFeat, "Feat", nClassFeat);
jFeat = JsonObjectSet(jFeat, "__struct_id", JsonInt(1));
jFeatList = JsonArrayInsert(jFeatList, jFeat);
WriteTimestampedLogEntry("pinc_henchmen, 1005, Adding class feat: " +
WriteTimestampedLogEntry("pinc_henchmen, 1029, Adding class feat: " +
Get2DAString("feat", "LABEL", nClassFeat));
}
}
nClassRow++;
}
// Give any bonus feats from package.
WriteTimestampedLogEntry("pinc_henchmen, 1012, Checking for selectable feats.");
int nPackageFeat, nPackageRow;
string sBonusFeat2DAName = Get2DAString("classes", "BonusFeatsTable", nClass);
int nNumOfFeats = StringToInt(Get2DAString(sBonusFeat2DAName, "Bonus", nLevel));
WriteTimestampedLogEntry("pinc_henchmen, 1039, Select " + IntToString(nNumOfFeats) + " bonus feats.");
string sPackage2DAName = Get2DAString("packages", "FeatPref2DA", nClass);
int nPackageMaxRow = Get2DARowCount(sPackage2DAName);
// Give bonus feats based on the package.
@@ -1029,13 +1053,13 @@ json ResetFeats(json jHenchman, object oHenchman)
if(nClassFeat == nPackageFeat)
{
sList = Get2DAString(sClsFeat2DAName, "List", nClassRow);
if((sList == "1" || sList == "2") && CanSelectFeat(jHenchman, oHenchman, nClassFeat))
if((sList == "1" || sList == "2") && CanSelectFeat(jHenchman, oHenchman, nClassFeat, jFeatList))
{
jFeat = JsonObject();
jFeat = GffAddWord(jFeat, "Feat", nClassFeat);
jFeat = JsonObjectSet(jFeat, "__struct_id", JsonInt(1));
jFeatList = JsonArrayInsert(jFeatList, jFeat);
WriteTimestampedLogEntry("pinc_henchmen, 1028, Adding class bonus feat: " +
WriteTimestampedLogEntry("pinc_henchmen, 1062, Adding class bonus feat: " +
Get2DAString("feat", "LABEL", nPackageFeat));
nNumOfFeats--;
}
@@ -1047,44 +1071,46 @@ json ResetFeats(json jHenchman, object oHenchman)
}
}
// Give picked feats from package.
WriteTimestampedLogEntry("pinc_henchmen, 972, Checking for select feats.");
nNumOfFeats = 1;
if(GetHasFeat(FEAT_QUICK_TO_MASTER, oHenchman)) nNumOfFeats++;
WriteTimestampedLogEntry("pinc_henchmen, 1076, Select " + IntToString(nNumOfFeats) + " feats for character.");
nPackageRow = 0;
while(nPackageRow < nPackageMaxRow || nNumOfFeats > 0)
{
nClassRow = 0;
nPackageFeat = StringToInt(Get2DAString(sPackage2DAName, "FeatIndex", nPackageRow));
if(CanSelectFeat(jHenchman, oHenchman, nPackageFeat))
//WriteTimestampedLogEntry("pinc_henchmen, 1082, nPackageFeat: " + Get2DAString("feat", "LABEL", nPackageFeat) + ".");
if(CanSelectFeat(jHenchman, oHenchman, nPackageFeat, jFeatList))
{
jFeat = JsonObject();
jFeat = GffAddWord(jFeat, "Feat", nPackageFeat);
jFeat = JsonObjectSet(jFeat, "__struct_id", JsonInt(1));
jFeatList = JsonArrayInsert(jFeatList, jFeat);
WriteTimestampedLogEntry("pinc_henchmen, 1053, Adding character bonus feat: " +
WriteTimestampedLogEntry("pinc_henchmen, 1089, Selecting character feat: " +
Get2DAString("feat", "LABEL", nPackageFeat));
nNumOfFeats--;
}
if(nNumOfFeats < 1) break;
nPackageRow++;
}
WriteTimestampedLogEntry("pinc_henchmen, 1071, Adding feat list.");
WriteTimestampedLogEntry("pinc_henchmen, 1096, Adding feat list.");
jHenchman = GffReplaceList(jHenchman, "FeatList", jFeatList);
return jHenchman;
}
json ResetSkills(json jHenchman, object oHenchman)
json ResetSkills(json jHenchman, object oHenchman, int nLevel)
{
// We remake the Skill List if the character doesn't have a level list!
int nClass = GetClassByPosition(1, oHenchman);
int nSkillPoints, nIntMod = GetAbilityModifier(ABILITY_INTELLIGENCE, oHenchman);
if(nIntMod > 0) nSkillPoints = nIntMod * 4;
if(GetRacialType(oHenchman) == RACIAL_TYPE_HUMAN) nSkillPoints += 4;
nSkillPoints += StringToInt(Get2DAString("classes", "SkillPointBase", nClass)) * 4;
int nMaxRanks = 5;
if(nIntMod > 0) nSkillPoints = nIntMod;
if(GetRacialType(oHenchman) == RACIAL_TYPE_HUMAN) nSkillPoints += 1;
nSkillPoints += StringToInt(Get2DAString("classes", "SkillPointBase", nClass));
nSkillPoints = nSkillPoints * (nLevel + 3);
int nMaxRanks = 3 + nLevel;
json jSkillList = JsonArray();
json jSkill;
// Setup the Skill List.
WriteTimestampedLogEntry("pinc_henchmen, 1087, Generating skill list.");
WriteTimestampedLogEntry("pinc_henchmen, 1112, Generating skill list.");
int nIndex, nSkillMaxRow = Get2DARowCount("skills");
for(nIndex = 0; nIndex < nSkillMaxRow; nIndex++)
{
@@ -1094,7 +1120,7 @@ json ResetSkills(json jHenchman, object oHenchman)
jSkillList = JsonArrayInsert(jSkillList, jSkill);
}
// Give skill points based on the package.
WriteTimestampedLogEntry("pinc_henchmen, 1097, Gets " + IntToString(nSkillPoints) + " skill points.");
WriteTimestampedLogEntry("pinc_henchmen, 1122, Gets " + IntToString(nSkillPoints) + " skill points.");
int nPackageSkill, nPackageRow, nCurrentRanks, bCrossClass, nClassRow, nNewRanks;
string sPackage2DAName = Get2DAString("packages", "SkillPref2DA", nClass);
int nPackageMaxRow = Get2DARowCount(sPackage2DAName);
@@ -1123,7 +1149,7 @@ json ResetSkills(json jHenchman, object oHenchman)
{
jSkill = GffReplaceByte(jSkill, "Rank", nCurrentRanks + nNewRanks);
jSkillList = JsonArraySet(jSkillList, nPackageSkill, jSkill);
WriteTimestampedLogEntry("pinc_henchmen, 1126, Adding " + IntToString(nNewRanks) +
WriteTimestampedLogEntry("pinc_henchmen, 1151, Adding " + IntToString(nNewRanks) +
" ranks to " + Get2DAString("skills", "Label", nPackageSkill) +
" CrossClass: " + IntToString(bCrossClass));
nSkillPoints -= nNewRanks;
@@ -1135,9 +1161,9 @@ json ResetSkills(json jHenchman, object oHenchman)
}
json ResetSpellsKnown(json jClass, object oHenchman)
{
WriteTimestampedLogEntry("pinc_henchmen, 1138, Checking for spells known.");
WriteTimestampedLogEntry("pinc_henchmen, 1163, Checking for spells known.");
int nClass = GetClassByPosition(1, oHenchman);
WriteTimestampedLogEntry("pinc_henchmen, 1140, SpellCaster: " + Get2DAString("classes", "SpellCaster", nClass));
WriteTimestampedLogEntry("pinc_henchmen, 1165, SpellCaster: " + Get2DAString("classes", "SpellCaster", nClass));
if(Get2DAString("classes", "SpellCaster", nClass) == "0") return jClass;
int nLevel = 0;
// We remake the Known spell list if the character doesn't have a level list!
@@ -1157,7 +1183,7 @@ json ResetSpellsKnown(json jClass, object oHenchman)
while(nSpellLevel < 10)
{
sSpellLevel = IntToString(nSpellLevel);
WriteTimestampedLogEntry("pinc_henchmen, 1143, Checking Spell Level: " + sSpellLevel);
WriteTimestampedLogEntry("pinc_henchmen, 1185, Checking Spell Level: " + sSpellLevel);
// Recreate the 0th and 1st level based on the package.
if(nSpellLevel < 2 && bSpellBookRestricted)
{
@@ -1179,7 +1205,7 @@ json ResetSpellsKnown(json jClass, object oHenchman)
{
nSpellsKnown = StringToInt(Get2DAString(sSpellKnown2DAName, "SpellLevel" + sSpellLevel, nLevel));
}
WriteTimestampedLogEntry("pinc_henchmen, 1165, nSpellsKnown: " + IntToString(nSpellsKnown));
WriteTimestampedLogEntry("pinc_henchmen, 1207, nSpellsKnown: " + IntToString(nSpellsKnown));
jKnownList = JsonArray();
nPackageRow = 0;
while(nPackageRow < nPackageMaxRow && nSpellsKnown > 0)
@@ -1201,7 +1227,7 @@ json ResetSpellsKnown(json jClass, object oHenchman)
if(JsonGetLength(jKnownList) == 0)
{
jClass = GffRemoveList(jClass, "KnownList" + sSpellLevel);
WriteTimestampedLogEntry("pinc_henchmen, 1187, Removing KnownList" + sSpellLevel);
WriteTimestampedLogEntry("pinc_henchmen, 1229, Removing KnownList" + sSpellLevel);
}
else if(JsonGetType(GffGetList(jClass, "KnownList" + sSpellLevel)) != JSON_TYPE_NULL)
{
@@ -1217,7 +1243,7 @@ json ResetSpellsKnown(json jClass, object oHenchman)
if(JsonGetType(jKnownList) != JSON_TYPE_NULL)
{
jClass = GffRemoveList(jClass, "KnownList" + sSpellLevel);
WriteTimestampedLogEntry("pinc_henchmen, 1203, Removing KnownList" + sSpellLevel);
WriteTimestampedLogEntry("pinc_henchmen, 1245, Removing KnownList" + sSpellLevel);
}
}
if(bMemorizesSpells)
@@ -1226,7 +1252,7 @@ json ResetSpellsKnown(json jClass, object oHenchman)
if(JsonGetType(jMemorizedList) != JSON_TYPE_NULL)
{
jClass = GffRemoveList(jClass, "MemorizedList" + sSpellLevel);
WriteTimestampedLogEntry("pinc_henchmen, 1210, Removing MemorizedList" + sSpellLevel);
WriteTimestampedLogEntry("pinc_henchmen, 1254, Removing MemorizedList" + sSpellLevel);
}
}
else
@@ -1237,7 +1263,7 @@ json ResetSpellsKnown(json jClass, object oHenchman)
jSpell = GffReplaceByte(jSpell, "NumSpellsLeft", nSpellsKnown);
jSpellsPerDayList = JsonArraySet(jSpellsPerDayList, nSpellLevel, jSpell);
jClass = GffReplaceList(jClass, "SpellsPerDayList", jSpellsPerDayList);
WriteTimestampedLogEntry("pinc_henchmen, 1223, Setting SpellsPerDay to " +
WriteTimestampedLogEntry("pinc_henchmen, 1265, Setting SpellsPerDay to " +
IntToString(nSpellsKnown));
}
nSpellLevel++;
@@ -1248,11 +1274,12 @@ object ResetCharacter(object oPC, object oHenchman)
{
SetLocalInt(oPC, "AI_IGNORE_NO_ASSOCIATE", TRUE);
RemoveHenchman(oPC, oHenchman);
ChangeToStandardFaction(oHenchman, STANDARD_FACTION_DEFENDER);
json jHenchman = ObjectToJson(oHenchman, TRUE);
json jClassList = GffGetList(jHenchman, "ClassList");
json jClass = JsonArrayGet(jClassList, 0);
// Set the Class list to the first class only and put at level 1.
int nClass = JsonGetInt(JsonObjectGet(jClass, "Class"));
int nClass = JsonGetInt(GffGetInt(jClass, "Class"));
jClass = GffReplaceShort(jClass, "ClassLevel", 1);
// Delete extra classes.
int nClassIndex = JsonGetLength(jClassList) - 1;
@@ -1260,15 +1287,10 @@ object ResetCharacter(object oPC, object oHenchman)
{
jClassList = JsonArrayDel(jClassList, nClassIndex--);
}
int nHitPoints = StringToInt(Get2DAString("classes", "HitDie", nClass));
int nMod = JsonGetInt(GffGetByte(jHenchman, "Con"));
if(nMod > 9) nHitPoints += (nMod - 10) / 2;
else nHitPoints += (nMod - 11) / 2;
jHenchman = GffReplaceShort(jHenchman, "CurrentHitPoints", nHitPoints);
jHenchman = GffReplaceShort(jHenchman, "HitPoints", nHitPoints);
jHenchman = GffReplaceShort(jHenchman, "MaxHitPoints", nHitPoints);
jHenchman = GffReplaceDword(jHenchman, "Experience", 0);
jHenchman = GffReplaceFloat(jHenchman, "ChallengeRating", 1.0);
int nPackage = GetLocalInt(oHenchman, "PACKAGE_SELECTED_1");
if(nPackage) jHenchman = GffReplaceByte(jHenchman, "StartingPackage", nPackage);
string s2DA = Get2DAString("classes", "AttackBonusTable", nClass);
int nAtk = StringToInt(Get2DAString(s2DA, "BAB", 0));
jHenchman = GffReplaceByte(jHenchman, "BaseAttackBonus", nAtk);
@@ -1282,7 +1304,7 @@ object ResetCharacter(object oPC, object oHenchman)
json jLvlStatList = GffGetList(jHenchman, "LvlStatList");
if(JsonGetType(jLvlStatList) != JSON_TYPE_NULL)
{
WriteTimestampedLogEntry("pinc_henchmen 1275, jLvlStatList: " + JsonDump(jLvlStatList, 4));
//WriteTimestampedLogEntry("pinc_henchmen 1289, jLvlStatList: " + JsonDump(jLvlStatList, 4));
int nLevel = 1, nLevelTrack = 1;
int nAbilityStatIncrease, nAbility;
string sAbility;
@@ -1290,7 +1312,7 @@ object ResetCharacter(object oPC, object oHenchman)
json jLevel = JsonArrayGet(jLvlStatList, nLevel);
while(JsonGetType(jLevel) != JSON_TYPE_NULL)
{
WriteTimestampedLogEntry("inc_henchmen, 1297, Checking level " + IntToString(nLevelTrack));
WriteTimestampedLogEntry("inc_henchmen, 1314, Checking level " + IntToString(nLevelTrack));
// Remove all Ability score increases for each level from ability scores.
jAbility = GffGetByte(jLevel, "LvlStatAbility");
if(JsonGetType(jAbility) != JSON_TYPE_NULL)
@@ -1304,7 +1326,7 @@ object ResetCharacter(object oPC, object oHenchman)
if(nAbilityStatIncrease == ABILITY_CHARISMA) sAbility = "Cha";
nAbility = JsonGetInt(GffGetByte(jHenchman, sAbility)) - 1;
jHenchman = GffReplaceByte(jHenchman, sAbility, nAbility);
WriteTimestampedLogEntry("pinc_henchmen, 1314, Removing " + sAbility + " level bonus ability score point.");
WriteTimestampedLogEntry("pinc_henchmen, 1328, Removing " + sAbility + " level bonus ability score point.");
}
jLvlStatList = JsonArrayDel(jLvlStatList, nLevel);
// Note: nLevel is not incremented since we are removing the previous level.
@@ -1316,12 +1338,21 @@ object ResetCharacter(object oPC, object oHenchman)
jHenchman = GffRemoveList(jHenchman, "LvlStatList");
}
jHenchman = CreateLevelStatList(jHenchman, oHenchman, oPC, 1);
jHenchman = ResetSkills(jHenchman, oHenchman);
int nHitPoints = StringToInt(Get2DAString("classes", "HitDie", nClass));
int nConstitution = JsonGetInt(GffGetByte(jHenchman, "Con"));
int nRace = JsonGetInt(GffGetByte(jHenchman, "Race"));
nConstitution += StringToInt(Get2DAString("racialtypes", "ConAdjust", nRace));
if(nConstitution > 9) nHitPoints += (nConstitution - 10) / 2;
else nHitPoints += (nConstitution - 11) / 2;
jHenchman = GffReplaceShort(jHenchman, "CurrentHitPoints", nHitPoints);
jHenchman = GffReplaceShort(jHenchman, "HitPoints", nHitPoints);
jHenchman = GffReplaceShort(jHenchman, "MaxHitPoints", nHitPoints);
jHenchman = ResetSkills(jHenchman, oHenchman, 1);
jHenchman = ResetFeats(jHenchman, oHenchman);
jClass = ResetSpellsKnown(jClass, oHenchman);
jClassList = JsonArraySet(jClassList, 0, jClass);
jHenchman = GffReplaceList(jHenchman, "ClassList", jClassList);
//WriteTimestampedLogEntry("pinc_henchmen 1397, jHenchman: " + JsonDump(jHenchman, 4));
//WriteTimestampedLogEntry("pinc_henchmen 1331, jHenchman: " + JsonDump(jHenchman, 4));
location lLocation = GetLocation(oHenchman);
int nFamiliar, nCompanion;
object oCompanion = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oHenchman);
@@ -1342,13 +1373,13 @@ void CreateCharacterEditGUIPanel(object oPC, object oHenchman)
// Group 1 (Portrait)******************************************************* 151 / 73
// Group 1 Row 1 *********************************************************** 350 / 91
json jGroupRow = JsonArrayInsert(JsonArray(), NuiSpacer());
jGroupRow = CreateTextEditBox (jGroupRow, "name_placeholder", "char_name", 15, FALSE, 140.0, 20.0);
jGroupRow = CreateTextEditBox (jGroupRow, "name_placeholder", "char_name", 50, FALSE, 140.0, 20.0);
jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer());
// Add the group row to the group column.
json jGroupCol = JsonArrayInsert(JsonArray(), NuiRow(jGroupRow));
// Group 1 Row 1 *********************************************************** 350 / 91
jGroupRow = JsonArrayInsert(JsonArray(), NuiSpacer());
jGroupRow = CreateTextEditBox (jGroupRow, "port_placeholder", "port_name", 15, FALSE, 140.0, 20.0, "port_tooltip");
jGroupRow = CreateTextEditBox (jGroupRow, "port_placeholder", "port_name", 16, FALSE, 140.0, 20.0, "port_tooltip");
jGroupRow = JsonArrayInsert(jGroupRow, NuiSpacer());
// Add the group row to the group column.
jGroupCol = JsonArrayInsert(jGroupCol, NuiRow(jGroupRow));
@@ -1503,11 +1534,13 @@ void CreateCharacterEditGUIPanel(object oPC, object oHenchman)
NuiSetBindWatch(oPC, nToken, "cmb_class_selected", bNoClass);
NuiSetBind(oPC, nToken, "cmb_class_event", JsonBool(bNoClass));
int nPackage = GetLocalInt(oHenchman, "PACKAGE_SELECTED_" + IntToString(nClassOption + 1));
//SendMessageToPC(oPC, "nPackage: " + IntToString(nPackage) + " nSelection: " + IntToString(GetSelectionByPackage2DA(sClass, nPackage)));
if(nPackage == 0)
{
nPackage = GetPackageBySelection2DA(sClass, 0);
SetLocalInt(oHenchman, "PACKAGE_SELECTED_" + IntToString(nClassOption + 1), nPackage);
}
//SendMessageToPC(oPC, "nPackage: " + IntToString(nPackage) + " sClass: " + sClass);
NuiSetBind(oPC, nToken, "cmb_package_selected", JsonInt(GetSelectionByPackage2DA(sClass, nPackage)));
NuiSetBindWatch(oPC, nToken, "cmb_package_selected", bNoClass);
NuiSetBind(oPC, nToken, "cmb_package_event", JsonBool(bNoClass));