2025/07/20 Update

Updated PEPS AI.
Full compile.
This commit is contained in:
Jaysyn904 2025-07-20 16:17:47 -04:00
parent d2a9c50615
commit b4f69b222a
100 changed files with 925 additions and 655 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -11,17 +11,19 @@ void main()
object oCreature = OBJECT_SELF;
// Added code to allow for permanent associates in the battle!
object oModule = GetModule();
if(AI_DEBUG) ai_Debug("0e_c2_7_ondeath", "14", "AI_RULE_PERM_ASSOC: " + IntToString(GetLocalInt(oModule, AI_RULE_PERM_ASSOC)));
if(GetLocalInt(oModule, AI_RULE_PERM_ASSOC))
{
object oAssociate;
int nIndex;
for(nIndex = 1; nIndex < 5; nIndex++)
for(nIndex = 2; nIndex < 6; nIndex++)
{
oAssociate = GetAssociate(nIndex, oCreature);
if(oAssociate != OBJECT_INVALID)
{
SetIsDestroyable(FALSE, FALSE, FALSE);
SetIsDestroyable(FALSE, FALSE, FALSE, oAssociate);
DelayCommand(0.1, ChangeToStandardFaction(oAssociate, STANDARD_FACTION_HOSTILE));
DelayCommand(3.0, SetIsDestroyable(TRUE, FALSE, FALSE, oAssociate));
}
}
}

View File

@ -17,13 +17,14 @@ void main()
{
object oAssociate;
int nIndex;
for(nIndex = 2; nIndex < 5; nIndex++)
for(nIndex = 2; nIndex < 6; nIndex++)
{
oAssociate = GetAssociate(nIndex, oCreature);
if(oAssociate != OBJECT_INVALID)
{
SetIsDestroyable(FALSE, FALSE, FALSE);
ChangeFaction(oAssociate, oCreature);
SetIsDestroyable(FALSE, FALSE, FALSE, oAssociate);
DelayCommand(0.1, ChangeToStandardFaction(oAssociate, STANDARD_FACTION_HOSTILE));
DelayCommand(3.0, SetIsDestroyable(TRUE, FALSE, FALSE, oAssociate));
}
}
}

View File

@ -0,0 +1,277 @@
/*//////////////////////////////////////////////////////////////////////////////
// Script Name: 0e_id_events
////////////////////////////////////////////////////////////////////////////////
Infinite Dungeons monster event handler.
*///////////////////////////////////////////////////////////////////////////////
#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");
//WriteTimestampedLogEntry("0e_id_events [24] " + GetName(oCreature) + " nEvent: " + IntToString(nEvent) +
// " bFollower: " + IntToString(bFollower));
switch (nEvent)
{
case EVENT_SCRIPT_CREATURE_ON_HEARTBEAT:
{
if(bFollower) ai_hen_id1_heart(oCreature);
else ExecuteScript("nw_c2_default1", oCreature);
break;
}
case EVENT_SCRIPT_CREATURE_ON_NOTICE:
{
if(bFollower) ai_hen_id1_percept(oCreature);
else ExecuteScript("nw_c2_default2", 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);
break;
}
case EVENT_SCRIPT_CREATURE_ON_MELEE_ATTACKED:
{
if(bFollower) ExecuteScript("nw_ch_ac5", oCreature);
else ExecuteScript("nw_c2_default5", oCreature);
break;
}
case EVENT_SCRIPT_CREATURE_ON_DAMAGED:
{
if(bFollower) ExecuteScript("nw_ch_ac6", oCreature);
else ExecuteScript("nw_c2_default6", oCreature);
break;
}
case EVENT_SCRIPT_CREATURE_ON_SPELLCASTAT:
{
if(bFollower) ai_hen_id1_castat(oCreature);
else ExecuteScript("nw_c2_defaultb", oCreature);
break;
}
case EVENT_SCRIPT_CREATURE_ON_END_COMBATROUND:
{
ai_hen_id1_endcombat(oCreature, bFollower);
break;
}
case EVENT_SCRIPT_CREATURE_ON_BLOCKED_BY_DOOR:
{
if(bFollower) ExecuteScript("nw_ch_ace", oCreature);
else ExecuteScript("nw_c2_defaulte", oCreature);
break;
}
case EVENT_SCRIPT_CREATURE_ON_RESTED:
{
if(bFollower) ExecuteScript("nw_ch_aca", oCreature);
break;
}
case EVENT_SCRIPT_CREATURE_ON_DISTURBED:
{
if(bFollower) ExecuteScript("nw_ch_ac8", oCreature);
else ExecuteScript("nw_c2_default8", 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 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

@ -1311,7 +1311,8 @@ void main()
jWidget = JsonArray();
if(JsonGetLength(jSpells) == 2) jSpells = JsonArrayInsert(jSpells, JsonArray());
}
if(JsonGetLength(jWidget) < 20)
int nWidgetLength = JsonGetLength(jWidget);
if(nWidgetLength < 20)
{
json jData = NuiGetUserData(oPC, nToken);
json jQuickListArray = JsonArrayGet(jData, 1);
@ -1320,8 +1321,7 @@ void main()
jSpells = JsonArraySet(jSpells, 2, jWidget);
jAIData = JsonArraySet(jAIData, 10, jSpells);
ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData);
DelayCommand(0.0, NuiDestroy(oPC, nToken));
DelayCommand(0.1, ai_CreateQuickWidgetSelectionNUI(oPC, oAssociate));
ai_PopulateWidgetList(oPC, oAssociate, nToken, jWidget);
}
else ai_SendMessages("The quick widget can only have 20 abilities or spells!", AI_COLOR_RED, oPC);
}
@ -1331,7 +1331,7 @@ void main()
json jSpell = JsonArrayGet(jQuickListArray, nIndex);
ai_CreateDescriptionNUI(oPC, jSpell);
}
else if(GetStringLeft(sElem, 11) == "btn_widget_")
else if(GetStringLeft(sElem, 11) == "btn_widget_") // Removes ability from quick use widget
{
string sIndex;
if(GetStringLength(sElem) == 13) sIndex = GetStringRight(sElem, 2);
@ -1343,8 +1343,7 @@ void main()
jSpells = JsonArraySet(jSpells, 2, jWidget);
jAIData = JsonArraySet(jAIData, 10, jSpells);
ai_SetAssociateDbJson(oPC, sAssociateType, "aidata", jAIData);
DelayCommand(0.0, NuiDestroy(oPC, nToken));
DelayCommand(0.1, ai_CreateQuickWidgetSelectionNUI(oPC, oAssociate));
ai_PopulateWidgetList(oPC, oAssociate, nToken, jWidget);
}
}
else if(sEvent == "close")
@ -1393,23 +1392,22 @@ void main()
int nClass = GetClassByPosition(JsonGetInt(JsonArrayGet(jSpells, 0)), oAssociate);
int nLevel = JsonGetInt(JsonArrayGet(jSpells, 1));
json jSpellArray = JsonArrayGet(jData, 1);
int nSpell = JsonGetInt(JsonArrayGet(jSpellArray, nIndex));
string sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
string sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
string sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
int nSlot;
int nMaxMemorizationSlot = GetMemorizedSpellCountByLevel(oAssociate, nClass, nLevel);
int nSlot, nSpell;
string sSlot;
while(nSlot < nMaxMemorizationSlot)
{
if(GetMemorizedSpellId(oAssociate, nClass, nLevel, nSlot) == -1)
{
nSpell = JsonGetInt(JsonArrayGet(jSpellArray, nIndex));
SetMemorizedSpell(oAssociate, nClass, nLevel, nSlot, nSpell, FALSE);
//NuiDestroy(oPC, nToken);
//ai_CreateSpellMemorizationNUI(oPC, oAssociate);
string sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
string sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
string sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
string sIndex = IntToString(nSlot);
NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_image", JsonString(sSpellIcon));
NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")"));
sSlot = IntToString(nSlot);
NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_image", JsonString(sSpellIcon));
NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")"));
return;
}
nSlot++;
@ -1422,19 +1420,17 @@ void main()
int nSpell = JsonGetInt(JsonArrayGet(jSpellArray, nIndex));
ai_CreateDescriptionNUI(oPC, JsonArray(), nSpell);
}
else if(GetStringLeft(sElem, 14) == "btn_memorized_")
else if(GetStringLeft(sElem, 14) == "btn_memorized_") // Remove memorized spell.
{
json jAIData = ai_GetAssociateDbJson(oPC, sAssociateType, "aidata");
json jSpells = JsonArrayGet(jAIData, 10);
int nClass = GetClassByPosition(JsonGetInt(JsonArrayGet(jSpells, 0)), oAssociate);
int nLevel = JsonGetInt(JsonArrayGet(jSpells, 1));
string sIndex = GetStringRight(sElem, 1);
ClearMemorizedSpell(oAssociate, nClass, nLevel, StringToInt(sIndex));
NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl"));
NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_tooltip", JsonString(""));
NuiSetBind(oPC, nToken, "btn_memorized_" + sIndex + "_event", JsonBool(FALSE));
//NuiDestroy(oPC, nToken);
//ai_CreateSpellMemorizationNUI(oPC, oAssociate);
string sSlot = GetStringRight(sElem, 1);
ClearMemorizedSpell(oAssociate, nClass, nLevel, StringToInt(sSlot));
NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_image", JsonString("ctl_cg_btn_splvl"));
NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_tooltip", JsonString(""));
NuiSetBind(oPC, nToken, "btn_memorized_" + sSlot + "_event", JsonBool(FALSE));
}
}
else if(sEvent == "close")
@ -1500,6 +1496,7 @@ void main()
jKnownList = JsonArray();
}
int nMaxKnownSlots, nSlot;
string sClass, sName, sSpellIcon, sSlot;
string sSpellKnownTable = Get2DAString("classes", "SpellKnownTable", nClass);
if(sSpellKnownTable != "") nMaxKnownSlots = StringToInt(Get2DAString(sSpellKnownTable, "SpellLevel" + sLevel, GetLevelByClass(nClass, oAssociate) - 1));
else nMaxKnownSlots = 20;
@ -1511,13 +1508,13 @@ void main()
jSpell = GffAddWord(JsonObject(), "Spell", nSpell);
jSpell = JsonObjectSet(jSpell, "__struct_id", JsonInt(3));
jKnownList = JsonArrayInsert(jKnownList, jSpell);
string sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
string sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
string sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
string sIndex = IntToString(nSlot);
NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_image", JsonString(sSpellIcon));
NuiSetBind(oPC, nToken, "btn_known_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + sLevel + ")"));
sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
sSlot = IntToString(nSlot);
NuiSetBind(oPC, nToken, "btn_known_" + sSlot + "_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_known_" + sSlot + "_image", JsonString(sSpellIcon));
NuiSetBind(oPC, nToken, "btn_known_" + sSlot + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + sLevel + ")"));
SetLocalInt(oAssociate, "AI_KNOWN_SPELL_CHANGE", TRUE);
break;
}

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.12.25";
const string PHILOS_VERSION = "Philos' Enhancing Player System (PEPS) version:07.20.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

View File

@ -121,9 +121,8 @@ void ai_SetAIRules()
json jRules = ai_GetCampaignDbJson("rules");
if(JsonGetType(JsonObjectGet(jRules, AI_RULE_MORAL_CHECKS)) == JSON_TYPE_NULL)
{
jRules = JsonObject();
// Variable name set to a creatures full name to set debugging on.
jRules = JsonObjectSet(jRules, AI_RULE_DEBUG_CREATURE, JsonString(""));
jRules = JsonObjectSet(JsonObject(), AI_RULE_DEBUG_CREATURE, JsonString(""));
// Moral checks on or off.
SetLocalInt(oModule, AI_RULE_MORAL_CHECKS, AI_MORAL_CHECKS);
jRules = JsonObjectSet(jRules, AI_RULE_MORAL_CHECKS, JsonInt(AI_MORAL_CHECKS));
@ -702,28 +701,48 @@ void ai_CheckAssociateDataAndInitialize(object oPlayer, string sAssociateType)
string ai_GetAssociateType(object oPlayer, object oAssociate)
{
if(GetIsPC(oAssociate)) return "pc";
int nIndex = 1;
string sAITag = GetLocalString(oAssociate, AI_TAG);
object oCreature;
if(sAITag == "")
{
int nAssociateType = GetAssociateType(oAssociate);
if(nAssociateType == ASSOCIATE_TYPE_ANIMALCOMPANION) sAITag = "companion";
else if(nAssociateType == ASSOCIATE_TYPE_FAMILIAR) sAITag = "familiar";
else if(nAssociateType == ASSOCIATE_TYPE_SUMMONED) sAITag = "summons";
else if(nAssociateType == ASSOCIATE_TYPE_DOMINATED) sAITag = "dominated";
else if(nAssociateType == ASSOCIATE_TYPE_HENCHMAN) sAITag = GetTag(oAssociate);
string sCurrentAITag;
// Check for duplicate tags and change.
int nIndex;
object oCreature;
for(nIndex = 1; nIndex <= AI_MAX_HENCHMAN; nIndex++)
if(nAssociateType == ASSOCIATE_TYPE_HENCHMAN)
{
sAITag = GetTag(oAssociate);
oCreature = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPlayer, nIndex);
if(oAssociate != oCreature && sAITag == GetTag(oCreature)) sAITag += IntToString(Random(1000));
// Check for duplicate tags and change.
while(nIndex <= AI_MAX_HENCHMAN && oCreature != OBJECT_INVALID)
{
if(oAssociate != oCreature && sAITag == GetTag(oCreature))
{
sAITag += IntToString(Random(1000));
break;
}
oCreature = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPlayer, ++nIndex);
}
}
for(nIndex = 2; nIndex < 6; nIndex++)
else if(nAssociateType == ASSOCIATE_TYPE_SUMMONED)
{
oCreature = GetAssociate(nIndex, oPlayer, 1);
if(oAssociate != oCreature && sAITag == GetTag(oCreature)) sAITag += IntToString(Random(1000));
int nCounter;
sAITag = GetTag(oAssociate);
oCreature = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPlayer, nIndex);
while(nIndex <= 10 && oCreature != OBJECT_INVALID)
{
if(oAssociate != oCreature && sAITag == GetTag(oCreature))
{
nCounter++;
sAITag += IntToString(nCounter);
nIndex = 0;
}
oCreature = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPlayer, ++nIndex);
}
}
else
{
if(nAssociateType == ASSOCIATE_TYPE_ANIMALCOMPANION) sAITag = "companion";
else if(nAssociateType == ASSOCIATE_TYPE_FAMILIAR) sAITag = "familiar";
else if(nAssociateType == ASSOCIATE_TYPE_DOMINATED) sAITag = "dominated";
}
SetLocalString(oAssociate, AI_TAG, sAITag);
}
@ -773,7 +792,7 @@ float ai_GetAssociateDbFloat(object oPlayer, string sAssociatetype, string sData
}
void ai_SetAssociateDbJson(object oPlayer, string sAssociateType, string sDataField, json jData, string sTable = AI_TABLE)
{
//SendMessageToPC(oPlayer, "0i_main, 629, Set DbJson - sAssociateType: " + sAssociateType + " sDataField: " + sDataField + " jData: " + JsonDump(jData));
//SendMessageToPC(oPlayer, "0i_main, 777, Set DbJson - sAssociateType: " + sAssociateType + " sDataField: " + sDataField + " jData: " + JsonDump(jData));
string sQuery = "UPDATE " + sTable + " SET " + sDataField +
" = @data WHERE name = @name;";
sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery);
@ -783,7 +802,7 @@ void ai_SetAssociateDbJson(object oPlayer, string sAssociateType, string sDataFi
}
json ai_GetAssociateDbJson(object oPlayer, string sAssociateType, string sDataField, string sTable = AI_TABLE)
{
//SendMessageToPC(oPlayer, "0i_main, 638, Get DbJson - sAssociateType: " + sAssociateType + " sDataField: " + sDataField);
//SendMessageToPC(oPlayer, "0i_main, 787, Get DbJson - sAssociateType: " + sAssociateType + " sDataField: " + sDataField);
string sQuery = "SELECT " + sDataField + " FROM " + sTable + " WHERE name = @name;";
sqlquery sql = SqlPrepareQueryObject(oPlayer, sQuery);
SqlBindString (sql, "@name", sAssociateType);
@ -1082,7 +1101,7 @@ void ai_CheckAssociateData(object oPlayer, object oAssociate, string sAssociateT
// These are pulled straight from the database.
// ********** Locations **********
json jLocations = ai_GetAssociateDbJson(oPlayer, sAssociateType, "locations");
if(JsonGetType(JsonObjectGet(jLocations, AI_WIDGET_NUI)) == JSON_TYPE_NULL)
if(JsonGetType(JsonObjectGet(jLocations, sAssociateType + AI_WIDGET_NUI)) == JSON_TYPE_NULL)
{
ai_SetupLocations(oPlayer, oAssociate, sAssociateType);
}

View File

@ -26,6 +26,8 @@ int ai_GetAIButton2(object oPlayer, int nButton, object oAssociate, string sAsso
json ai_CreateCompanionJson(object oPC, string sCompanion2da);
// Return any Metamagic or Domain attributes to place on a spell icon image.
string ai_GetSpellIconAttributes(object oCaster, int nMetaMagic, int nDomain);
// Populates the Quick widget list menu.
void ai_PopulateWidgetList(object oPC, object oAssociate, int nToken, json jWidget);
// Creates the AI options menu.
void ai_CreateAIMainNUI(object oPC);
// Creates the AI options menu.
@ -129,6 +131,211 @@ string ai_GetSpellIconAttributes(object oCaster, int nMetaMagic, int nDomain)
if(nDomain > 0) sAttributeText += "D";
return sAttributeText;
}
void ai_PopulateWidgetList(object oPC, object oAssociate, int nToken, json jWidget)
{
int nSAIndex, nSpell, nClass, nFeat, nBaseItemType, nIprpSubType, nUses;
int nLevel, nMetaMagic, nDomain, nIndex;
string sIndex, sBaseName, sName, sSpellIcon, sText, sClass, sMetaMagicText;
object oItem;
json jSpell;
while(nIndex < 10)
{
jSpell = JsonArrayGet(jWidget, nIndex);
sIndex = IntToString(nIndex);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE));
if(JsonGetType(jSpell) != JSON_TYPE_NULL)
{
nSpell = JsonGetInt(JsonArrayGet(jSpell, 0));
nClass = JsonGetInt(JsonArrayGet(jSpell, 1));
nFeat = JsonGetInt(JsonArrayGet(jSpell, 5));
if(nClass == -1) // This is an Item.
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
nBaseItemType = JsonGetInt(JsonArrayGet(jSpell, 3));
nIprpSubType = JsonGetInt(JsonArrayGet(jSpell, 4));
if(nSpell == SPELL_HEALINGKIT)
{
sName = "Healer's Kit +" + IntToString(nIprpSubType);
sSpellIcon = "isk_heal";
sBaseName = "Healer's Kit";
}
else if(nBaseItemType == BASE_ITEM_ENCHANTED_SCROLL ||
nBaseItemType == BASE_ITEM_SCROLL ||
nBaseItemType == BASE_ITEM_SPELLSCROLL)
{
sSpellIcon = Get2DAString("iprp_spells", "Icon", nIprpSubType);
sBaseName = "Scroll";
}
else
{
if(nBaseItemType == BASE_ITEM_ENCHANTED_POTION ||
nBaseItemType == BASE_ITEM_POTIONS) sBaseName = "Potion";
else if(nBaseItemType == BASE_ITEM_ENCHANTED_WAND ||
nBaseItemType == BASE_ITEM_MAGICWAND ||
nBaseItemType == FEAT_CRAFT_WAND) sBaseName = "Wand";
else sBaseName = ai_StripColorCodes(GetName(GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5)))));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
}
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5)));
nUses = ai_GetItemUses(oItem, nIprpSubType);
if(nUses)
{
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE));
if(nUses == 999) sText = "Unlimited";
else sText = IntToString(nUses);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sBaseName + " / " + sText + ")"));
}
}
else if(nFeat) // This is a feat.
{
sSpellIcon = "";
if(nSpell)
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
}
if(sSpellIcon == "" || sSpellIcon == "IR_USE")
{
sName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat)));
sSpellIcon = Get2DAString("feat", "ICON", nFeat);
}
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName));
}
else // This is a spell.
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
nLevel = JsonGetInt(JsonArrayGet(jSpell, 2));
nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3));
nDomain = JsonGetInt(JsonArrayGet(jSpell, 4));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
if(nClass == 255)
{
nSAIndex = JsonGetInt(JsonArrayGet(jSpell, 6));
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (Special Ability / " + IntToString(nLevel) + ")"));
}
else
{
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")"));
sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain);
NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText));
}
}
}
else
{
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl"));
NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(""));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE));
}
++nIndex;
}
if(nIndex < 10) return;
// Row 6 Quick widget List2
while(nIndex < 20)
{
jSpell = JsonArrayGet(jWidget, nIndex);
sIndex = IntToString(nIndex);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE));
if(JsonGetType(jSpell) != JSON_TYPE_NULL)
{
nSpell = JsonGetInt(JsonArrayGet(jSpell, 0));
nClass = JsonGetInt(JsonArrayGet(jSpell, 1));
nFeat = JsonGetInt(JsonArrayGet(jSpell, 5));
if(nClass == -1) // This is an Item.
{
string sBaseName;
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
int nBaseItemType = JsonGetInt(JsonArrayGet(jSpell, 3));
int nIprpSubType = JsonGetInt(JsonArrayGet(jSpell, 4));
if(nSpell == SPELL_HEALINGKIT)
{
sName = "Healer's Kit +" + IntToString(nIprpSubType);
sSpellIcon = "isk_heal";
sBaseName = "Healer's Kit";
}
else if(nBaseItemType == BASE_ITEM_ENCHANTED_SCROLL ||
nBaseItemType == BASE_ITEM_SCROLL ||
nBaseItemType == BASE_ITEM_SPELLSCROLL)
{
sSpellIcon = Get2DAString("iprp_spells", "Icon", nIprpSubType);
sBaseName = "Scroll";
}
else
{
if(nBaseItemType == BASE_ITEM_ENCHANTED_POTION ||
nBaseItemType == BASE_ITEM_POTIONS) sBaseName = "Potion";
else if(nBaseItemType == BASE_ITEM_ENCHANTED_WAND ||
nBaseItemType == BASE_ITEM_MAGICWAND ||
nBaseItemType == FEAT_CRAFT_WAND) sBaseName = "Wand";
else sBaseName = ai_StripColorCodes(GetName(GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5)))));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
}
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5)));
int nUses = ai_GetItemUses(oItem, nIprpSubType);
if(nUses)
{
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE));
if(nUses == 999) sText = "Unlimited";
else sText = IntToString(nUses);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sBaseName + " / " + sText + ")"));
}
}
else if(nFeat) // This is a feat.
{
sSpellIcon = "";
if(nSpell)
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
}
if(sSpellIcon == "" || sSpellIcon == "IR_USE")
{
sName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat)));
sSpellIcon = Get2DAString("feat", "ICON", nFeat);
}
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName));
}
else // This is a spell.
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
nLevel = JsonGetInt(JsonArrayGet(jSpell, 2));
nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
if(nClass == 255)
{
nSAIndex = JsonGetInt(JsonArrayGet(jSpell, 6));
if(GetSpellAbilityReady(oAssociate, nSAIndex))
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (Special Ability / " + IntToString(nLevel) + ")"));
}
}
else
{
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")"));
sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain);
NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText));
}
}
}
else
{
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl"));
NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(""));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE));
}
++nIndex;
}
}
void ai_CreateAIMainNUI(object oPC)
{
// Set window to not save until it has been created.
@ -1174,6 +1381,7 @@ void ai_CreateAssociateAINUI(object oPC, object oAssociate)
SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE);
DelayCommand (2.0, DeleteLocalInt (oPC, AI_NO_NUI_SAVE));
int bRight, bLeft;
int nAssociateType = GetAssociateType(oAssociate);
float fHeight = 45.0;
// ************************************************************************* Width / Height
int bIsPC = ai_GetIsCharacter(oAssociate);
@ -1436,7 +1644,7 @@ void ai_CreateAssociateAINUI(object oPC, object oAssociate)
jRow = JsonArrayInsert(jRow, NuiSpacer());
if(bLeft)
{
if(sAssociateType != "summons" && sAssociateType != "dominated")
if(nAssociateType != ASSOCIATE_TYPE_SUMMONED && nAssociateType != ASSOCIATE_TYPE_DOMINATED)
{
jRow = CreateButton(jRow, "Auto Looting", "btn_loot", 200.0, 20.0, -1.0, "btn_loot_tooltip");
jRow = CreateCheckBox(jRow, "", "chbx_loot", 25.0, 20.0);
@ -1751,7 +1959,7 @@ void ai_CreateAssociateAINUI(object oPC, object oAssociate)
if(ai_GetMagicMode(oAssociate, AI_MAGIC_CURE_SPELLS_OFF)) sText = " Cast Cure Spells Off";
else sText = " Cast Cure Spells On";
NuiSetBind(oPC, nToken, "btn_cure_onoff_tooltip", JsonString(sText));
if(sAssociateType != "summons" && sAssociateType != "dominated")
if(nAssociateType != ASSOCIATE_TYPE_SUMMONED && nAssociateType != ASSOCIATE_TYPE_DOMINATED)
{
sRange = FloatToString(GetLocalFloat(oAssociate, AI_LOOT_CHECK_RANGE), 0, 0);
if(ai_GetAIMode(oAssociate, AI_MODE_PICKUP_ITEMS)) sText = " Looting On [" + sRange + " meters]";
@ -2238,7 +2446,7 @@ void ai_SetWidgetBinds(object oPC, object oAssociate, string sAssociateType, int
object oItem;
if(JsonGetType(jWidget) != JSON_TYPE_NULL)
{
int nLevel, nSpell, nIndex, nClass, nMetaMagic, nDomain, nSubSpell, nFeat;
int nLevel, nSpell, nIndex, nClass, nMetaMagic, nDomain, nSubSpell, nFeat, nSAIndex;
string sSpellIcon, sMetaMagicText, sSubSpell, sClass, sIndex;
while(nIndex < 10)
{
@ -2319,14 +2527,20 @@ void ai_SetWidgetBinds(object oPC, object oAssociate, string sAssociateType, int
nSpell = JsonGetInt(JsonArrayGet(jSpell, 0));
nClass = JsonGetInt(JsonArrayGet(jSpell, 1));
nLevel = JsonGetInt(JsonArrayGet(jSpell, 2));
nDomain = JsonGetInt(JsonArrayGet(jSpell, 4));
nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3));
nDomain = JsonGetInt(JsonArrayGet(jSpell, 4));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain);
NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText));
if(GetSpellUsesLeft(oAssociate, nClass, nSpell, nMetaMagic, nDomain))
nSAIndex = JsonGetInt(JsonArrayGet(jSpell, 6));
if(nClass == 255 && GetSpellAbilityReady(oAssociate, nSAIndex))
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (Special Ability / " + IntToString(nLevel) + ")"));
}
else if(GetSpellUsesLeft(oAssociate, nClass, nSpell, nMetaMagic, nDomain))
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
@ -2419,8 +2633,8 @@ void ai_SetWidgetBinds(object oPC, object oAssociate, string sAssociateType, int
{
nSpell = JsonGetInt(JsonArrayGet(jSpell, 0));
nClass = JsonGetInt(JsonArrayGet(jSpell, 1));
nDomain = JsonGetInt(JsonArrayGet(jSpell, 4));
nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3));
nDomain = JsonGetInt(JsonArrayGet(jSpell, 4));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
//SendMessageToPC(oPC, GetName(oAssociate) + " nSpell: " + IntToString(nSpell) +
// " nClass: " + IntToString(nClass) + " nMetaMagic: " + IntToString(nMetaMagic) +
@ -2431,15 +2645,20 @@ void ai_SetWidgetBinds(object oPC, object oAssociate, string sAssociateType, int
NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText));
sSubSpell = Get2DAString("spells", "Master", nSpell);
if(sSubSpell != "") nSpell = StringToInt(sSubSpell);
if(nDomain == -1 || GetSpellUsesLeft(oAssociate, nClass, nSpell, nMetaMagic, nDomain))
if(nClass == 255)
{
nSAIndex = JsonGetInt(JsonArrayGet(jSpell, 6));
if(GetSpellAbilityReady(oAssociate, nSAIndex))
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (Special Ability / " + IntToString(nLevel) + ")"));
}
}
else if(GetSpellUsesLeft(oAssociate, nClass, nSpell, nMetaMagic, nDomain))
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
if(nDomain == -1) NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName));
else
{
sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")"));
}
sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")"));
}
else NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE));
}
@ -2876,7 +3095,6 @@ void ai_CreateWidgetNUI(object oPC, object oAssociate)
}
// Get the window location to restore it from the database.
json jLocations = ai_GetAssociateDbJson(oPC, sAssociateType, "locations");
//SendMessageToPC(oPC, "0i_menu, 2124, sAssociateType: " + sAssociateType + " jLocations: " + JsonDump(jLocations, 1));
if(JsonGetType(jLocations) == JSON_TYPE_NULL)
{
ai_SetupAssociateData(oPC, oAssociate, sAssociateType);
@ -2885,14 +3103,16 @@ void ai_CreateWidgetNUI(object oPC, object oAssociate)
jLocations = JsonObjectGet(jLocations, sAssociateType + AI_WIDGET_NUI);
float fX = JsonGetFloat(JsonObjectGet(jLocations, "x"));
float fY = JsonGetFloat(JsonObjectGet(jLocations, "y"));
//SendMessageToPC(oPC, "0i_menu, 2901, sAssociateType: " + sAssociateType + AI_WIDGET_NUI + " jLocations: " + JsonDump(jLocations, 1));
// Keeps the widgets from bunching up in the top corner.
if(fY == 0.0 && fX == 0.0)
{
int nAssociateType = GetAssociateType(oAssociate);
if(sAssociateType == "pc") fY = 1.0;
else if(sAssociateType == "familiar") fY = 96.0 * fScale;
else if(sAssociateType == "companion") fY = 192.0 * fScale;
else if(sAssociateType == "summons") fY = 288.0 * fScale;
else if(sAssociateType == "dominated") fY = 384.0 * fScale;
else if(nAssociateType == ASSOCIATE_TYPE_FAMILIAR) fY = 96.0 * fScale;
else if(nAssociateType == ASSOCIATE_TYPE_ANIMALCOMPANION) fY = 192.0 * fScale;
else if(nAssociateType == ASSOCIATE_TYPE_SUMMONED) fY = 288.0 * fScale;
else if(nAssociateType == ASSOCIATE_TYPE_DOMINATED) fY = 384.0 * fScale;
else
{
int nIndex = 1;
@ -3178,24 +3398,34 @@ void ai_CreateCopySettingsNUI(object oPC, object oAssociate)
jRow = JsonArrayInsert(jRow, NuiSpacer());
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 4 ******************************************************************* 244 / 185
jRow = JsonArrayInsert(JsonArray(), NuiSpacer());
jRow = CreateButton(jRow, "Summons", "btn_paste_summons", 220.0, 20.0);
jRow = JsonArrayInsert(jRow, NuiSpacer());
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 5 ******************************************************************* 244 / 213
// Row 4 ******************************************************************* 244 / 213
jRow = JsonArrayInsert(JsonArray(), NuiSpacer());
jRow = CreateButton(jRow, "Dominated", "btn_paste_dominated", 220.0, 20.0);
jRow = JsonArrayInsert(jRow, NuiSpacer());
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 5+ ****************************************************************** 244 / 241
float fHeight = 241.0;
// Row 5+ ******************************************************************* 244 / 185
float fHeight = 213.0;
int nIndex;
string sAssocName;
object oAssoc;
for(nIndex = 1; nIndex < AI_MAX_HENCHMAN; nIndex++)
{
oAssoc = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oPC, nIndex);
if(oAssoc != OBJECT_INVALID)
{
sAssocName = GetName(oAssoc);
if(GetStringRight(sAssocName, 1) == "s") sAssocName = sAssocName + "'";
else sAssocName = sAssocName + "'s";
jRow = CreateButton(JsonArray(), sAssocName, "btn_paste_summons" + IntToString(nIndex), 220.0, 20.0);
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
fHeight += 28.0;
}
else break;
}
// Row 5+ ****************************************************************** 244 / 241
for(nIndex = 1; nIndex < AI_MAX_HENCHMAN; nIndex++)
{
oAssoc = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex);
if(oAssoc != OBJECT_INVALID)
@ -3661,7 +3891,7 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate)
{
if(StringToInt(Get2DAString("classes", "SpellCaster", nClass)))
{
int nClassLevel = GetLevelByClass(nClass, oAssociate);
int nClassLevel = ai_GetCasterTotalLevel(oAssociate, nClass);
string sSpellsGained = Get2DAString("classes", "SpellGainTable", nClass);
int nMaxSpellLevel = StringToInt(Get2DAString(sSpellsGained, "NumSpellLevels", nClassLevel - 1));
for(nLevelIndex = 0; nLevelIndex <= 9; nLevelIndex++)
@ -3741,8 +3971,8 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate)
jQuickListArray = ai_CheckItemAbilities(jQuickListArray, oAssociate, oItem, jSpell_Icon, jSpell_Text, FALSE);
jSpell_Icon = GetLocalJson(oAssociate, "JSPELL_ICON");
jSpell_Text = GetLocalJson(oAssociate, "JSPELL_NAME");
WriteTimestampedLogEntry("0i_menus, 3643, oAssociate: " + GetName(oAssociate) +
" jSpell_Text: " + JsonDump(jSpell_Text, 4));
//WriteTimestampedLogEntry("0i_menus, 3643, oAssociate: " + GetName(oAssociate) +
// " jSpell_Text: " + JsonDump(jSpell_Text, 4));
}
}
oItem = GetNextItemInInventory(oAssociate);
@ -3811,9 +4041,9 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate)
jSpell = JsonArray();
jSpell = JsonArrayInsert(jSpell, JsonInt(nSubSpell));
jSpell = JsonArrayInsert(jSpell, JsonInt(nClass));
jSpell = JsonArrayInsert(jSpell, JsonInt(0));
jSpell = JsonArrayInsert(jSpell, JsonInt(255));
jSpell = JsonArrayInsert(jSpell, JsonInt(0));
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);
}
@ -3828,9 +4058,9 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate)
jSpell = JsonArray();
jSpell = JsonArrayInsert(jSpell, JsonInt(nSpell));
jSpell = JsonArrayInsert(jSpell, JsonInt(nClass));
jSpell = JsonArrayInsert(jSpell, JsonInt(0));
jSpell = JsonArrayInsert(jSpell, JsonInt(255));
jSpell = JsonArrayInsert(jSpell, JsonInt(0));
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);
}
@ -3840,6 +4070,66 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate)
}
}
}
// Checks for monsters special abilities.
int nCounter = 0, nPreviousSpell = -1, nMaxSpellAbility = GetSpellAbilityCount(oAssociate);
while(nCounter < nMaxSpellAbility)
{
nSpell = GetSpellAbilitySpell(oAssociate, nCounter);
if(nPreviousSpell != nSpell)
{
nPreviousSpell = nSpell;
// Check for subfeats.
nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell1", nSpell));
if(nSubSpell)
{
for(nSubSpellIndex = 1; nSubSpellIndex <= 5; nSubSpellIndex++)
{
sSubSpellIndex = IntToString(nSubSpellIndex);
nSubSpell = StringToInt(Get2DAString("spells", "SubRadSpell" + sSubSpellIndex, nSpell));
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(0)); // Level
jSpell = JsonArrayInsert(jSpell, JsonInt(255)); // MetaMagic
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Domain
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // Feat
jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell);
}
}
}
else
{
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
jSpell_Icon = JsonArrayInsert(jSpell_Icon, JsonString(sSpellIcon));
sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
jSpell_Text = JsonArrayInsert(jSpell_Text, JsonString(sSpellName));
sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain);
jMetaMagic_Text = JsonArrayInsert(jMetaMagic_Text, JsonString(sMetaMagicText));
jSpell = JsonArray();
jSpell = JsonArrayInsert(jSpell, JsonInt(nSpell));
jSpell = JsonArrayInsert(jSpell, JsonInt(255)); // Class - Special abilities is always 255.
jSpell = JsonArrayInsert(jSpell, JsonInt(GetSpellAbilityCasterLevel(oAssociate, nCounter)));
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // metamagic
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // domain
jSpell = JsonArrayInsert(jSpell, JsonInt(0)); // feat
// Index of Special ability on monster.
jSpell = JsonArrayInsert(jSpell, JsonInt(nCounter));
jQuickListArray = JsonArrayInsert(jQuickListArray, jSpell);
//SendMessageToPC(oPC, "nSpell: " + IntToString(nSpell) +
// " sSpellIcon: " + sSpellIcon +
// " sSpellName: " + sSpellName+
// " nMaxSlot: " + IntToString(nMaxSpellAbility) +
// " nSpellAbilityIndex: " + IntToString(nCounter));
}
}
nCounter++;
}
// Used in the execution script to get the special abilities.
//jData = JsonArrayInsert(jData, jQuickListArray);
}
@ -3944,185 +4234,7 @@ void ai_CreateQuickWidgetSelectionNUI(object oPC, object oAssociate)
NuiSetUserData(oPC, nToken, jData);
// Row 4 Quick widget list label.
// Row 5 Quick widget List 1
json jWidget = JsonArrayGet(jSpells, 2);
nIndex = 0;
while(nIndex < 10)
{
jSpell = JsonArrayGet(jWidget, nIndex);
sIndex = IntToString(nIndex);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE));
if(JsonGetType(jSpell) != JSON_TYPE_NULL)
{
nSpell = JsonGetInt(JsonArrayGet(jSpell, 0));
nClass = JsonGetInt(JsonArrayGet(jSpell, 1));
nFeat = JsonGetInt(JsonArrayGet(jSpell, 5));
if(nClass == -1) // This is an Item.
{
string sBaseName;
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
int nBaseItemType = JsonGetInt(JsonArrayGet(jSpell, 3));
int nIprpSubType = JsonGetInt(JsonArrayGet(jSpell, 4));
if(nSpell == SPELL_HEALINGKIT)
{
sName = "Healer's Kit +" + IntToString(nIprpSubType);
sSpellIcon = "isk_heal";
sBaseName = "Healer's Kit";
}
else if(nBaseItemType == BASE_ITEM_ENCHANTED_SCROLL ||
nBaseItemType == BASE_ITEM_SCROLL ||
nBaseItemType == BASE_ITEM_SPELLSCROLL)
{
sSpellIcon = Get2DAString("iprp_spells", "Icon", nIprpSubType);
sBaseName = "Scroll";
}
else
{
if(nBaseItemType == BASE_ITEM_ENCHANTED_POTION ||
nBaseItemType == BASE_ITEM_POTIONS) sBaseName = "Potion";
else if(nBaseItemType == BASE_ITEM_ENCHANTED_WAND ||
nBaseItemType == BASE_ITEM_MAGICWAND ||
nBaseItemType == FEAT_CRAFT_WAND) sBaseName = "Wand";
else sBaseName = ai_StripColorCodes(GetName(GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5)))));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
}
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5)));
int nUses = ai_GetItemUses(oItem, nIprpSubType);
if(nUses)
{
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE));
if(nUses == 999) sText = "Unlimited";
else sText = IntToString(nUses);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sBaseName + " / " + sText + ")"));
}
}
else if(nFeat) // This is a feat.
{
sSpellIcon = "";
if(nSpell)
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
}
if(sSpellIcon == "" || sSpellIcon == "IR_USE")
{
sName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat)));
sSpellIcon = Get2DAString("feat", "ICON", nFeat);
}
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName));
}
else // This is a spell.
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
nLevel = JsonGetInt(JsonArrayGet(jSpell, 2));
nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3));
nDomain = JsonGetInt(JsonArrayGet(jSpell, 4));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")"));
sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain);
NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText));
}
}
else
{
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl"));
NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(""));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE));
}
++nIndex;
}
if(nIndex < 10) return;
// Row 6 Quick widget List2
while(nIndex < 20)
{
jSpell = JsonArrayGet(jWidget, nIndex);
sIndex = IntToString(nIndex);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE));
if(JsonGetType(jSpell) != JSON_TYPE_NULL)
{
nSpell = JsonGetInt(JsonArrayGet(jSpell, 0));
nClass = JsonGetInt(JsonArrayGet(jSpell, 1));
nFeat = JsonGetInt(JsonArrayGet(jSpell, 5));
if(nClass == -1) // This is an Item.
{
string sBaseName;
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
int nBaseItemType = JsonGetInt(JsonArrayGet(jSpell, 3));
int nIprpSubType = JsonGetInt(JsonArrayGet(jSpell, 4));
if(nSpell == SPELL_HEALINGKIT)
{
sName = "Healer's Kit +" + IntToString(nIprpSubType);
sSpellIcon = "isk_heal";
sBaseName = "Healer's Kit";
}
else if(nBaseItemType == BASE_ITEM_ENCHANTED_SCROLL ||
nBaseItemType == BASE_ITEM_SCROLL ||
nBaseItemType == BASE_ITEM_SPELLSCROLL)
{
sSpellIcon = Get2DAString("iprp_spells", "Icon", nIprpSubType);
sBaseName = "Scroll";
}
else
{
if(nBaseItemType == BASE_ITEM_ENCHANTED_POTION ||
nBaseItemType == BASE_ITEM_POTIONS) sBaseName = "Potion";
else if(nBaseItemType == BASE_ITEM_ENCHANTED_WAND ||
nBaseItemType == BASE_ITEM_MAGICWAND ||
nBaseItemType == FEAT_CRAFT_WAND) sBaseName = "Wand";
else sBaseName = ai_StripColorCodes(GetName(GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5)))));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
}
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jSpell, 5)));
int nUses = ai_GetItemUses(oItem, nIprpSubType);
if(nUses)
{
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(TRUE));
if(nUses == 999) sText = "Unlimited";
else sText = IntToString(nUses);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sBaseName + " / " + sText + ")"));
}
}
else if(nFeat) // This is a feat.
{
sSpellIcon = "";
if(nSpell)
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
}
if(sSpellIcon == "" || sSpellIcon == "IR_USE")
{
sName = GetStringByStrRef(StringToInt(Get2DAString("feat", "FEAT", nFeat)));
sSpellIcon = Get2DAString("feat", "ICON", nFeat);
}
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName));
}
else // This is a spell.
{
sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
sClass = GetStringByStrRef(StringToInt(Get2DAString("classes", "Name", nClass)));
nLevel = JsonGetInt(JsonArrayGet(jSpell, 2));
nMetaMagic = JsonGetInt(JsonArrayGet(jSpell, 3));
sSpellIcon = Get2DAString("spells", "IconResRef", nSpell);
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString(sSpellIcon));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_tooltip", JsonString(" " + sName + " (" + sClass + " / " + IntToString(nLevel) + ")"));
sMetaMagicText = ai_GetSpellIconAttributes(oAssociate, nMetaMagic, nDomain);
NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(sMetaMagicText));
}
}
else
{
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_image", JsonString("ctl_cg_btn_splvl"));
NuiSetBind(oPC, nToken, "metamagic_" + sIndex + "_text", JsonString(""));
NuiSetBind(oPC, nToken, "btn_widget_" + sIndex + "_event", JsonBool(FALSE));
}
++nIndex;
}
ai_PopulateWidgetList(oPC, oAssociate, nToken, JsonArrayGet(jSpells, 2));
}
void ai_CreateSpellMemorizationNUI(object oPC, object oAssociate)
{
@ -4289,7 +4401,7 @@ void ai_CreateSpellMemorizationNUI(object oPC, object oAssociate)
NuiSetBind(oPC, nToken, "btn_class_" + sIndex + "_tooltip", JsonString(" " + sClass));
if(nClassSelected == nIndex)
{
int nClassLevel = GetLevelByClass(nClass, oAssociate);
int nClassLevel = ai_GetCasterTotalLevel(oAssociate, nClass);
string sSpellsGained = Get2DAString("classes", "SpellGainTable", nClass);
int nMaxSpellLevel = StringToInt(Get2DAString(sSpellsGained, "NumSpellLevels", nClassLevel - 1));
for(nIndexLevel = 0; nIndexLevel <= 9; nIndexLevel++)
@ -4605,7 +4717,7 @@ void ai_CreateSpellKnownNUI(object oPC, object oAssociate)
NuiSetBind(oPC, nToken, "btn_class_" + sIndex + "_tooltip", JsonString(" " + sClass));
if(nClassSelected == nIndex)
{
nClassLevel = GetLevelByClass(nClass, oAssociate);
nClassLevel = ai_GetCasterTotalLevel(oAssociate, nClass);
sSpellsGained = Get2DAString("classes", "SpellGainTable", nClass);
nMaxSpellLevel = StringToInt(Get2DAString(sSpellsGained, "NumSpellLevels", nClassLevel - 1));
for(nIndexLevel = 0; nIndexLevel <= 9; nIndexLevel++)

View File

@ -69,6 +69,8 @@ struct stSpell
int nMaxSlots;
int nSlot;
};
// Gets the total caster levels for nClass for oCreature.
int ai_GetCasterTotalLevel(object oCreature, int nClass);
// Returns TRUE if oCreature can cast nSpell from nLevel.
int ai_GetCanCastSpell(object oCreature, int nSpell, int nClass, int nLevel, int nMetaMagic = 0, int nDomain = 0);
// Returns TRUE if oCreature is immune to petrification.
@ -184,6 +186,23 @@ void ai_CastWidgetSpell(object oPC, object oAssociate, object oTarget, location
void ai_UseWidgetFeat(object oPC, object oAssociate, object oTarget, location lLocation);
// Uses the item on the current target for oAssociate.
void ai_UseWidgetItem(object oPC, object oAssociate, object oTarget, location lLocation);
int ai_GetCasterTotalLevel(object oCreature, int nClass)
{
int nIndex, nCheckClass;
int nLevel = GetLevelByClass(nClass, oCreature);
if(nClass == CLASS_TYPE_BARD || nClass == CLASS_TYPE_SORCERER || nClass == CLASS_TYPE_WIZARD)
{
for(nIndex = 1; nIndex <= AI_MAX_CLASSES_PER_CHARACTER; nIndex ++)
{
nCheckClass = GetClassByPosition(nIndex, oCreature);
if(nCheckClass == CLASS_TYPE_PALE_MASTER)
{
nLevel += (GetLevelByClass(CLASS_TYPE_PALE_MASTER, oCreature) + 1) / 2;
}
}
}
return nLevel;
}
int ai_GetCanCastSpell(object oCreature, int nSpell, int nClass, int nLevel, int nMetaMagic = 0, int nDomain = 0)
{
int nIndex, nSpellCount, nClassPosition, nSlot, nMaxSlots, nPosition = 1;
@ -2111,13 +2130,17 @@ void ai_UseWidgetFeat(object oPC, object oAssociate, object oTarget, location lL
json jWidget = JsonArrayGet(jSpells, 2);
json jFeat = JsonArrayGet(jWidget, nIndex);
int nFeat = JsonGetInt(JsonArrayGet(jFeat, 5));
int nLevel = JsonGetInt(JsonArrayGet(jFeat, 2));
// We use nLevel at -1 to denote this is a feat with a subradial spell.
int nSubSpell;
if(nLevel == -1) nSubSpell = JsonGetInt(JsonArrayGet(jFeat, 0));
if(ai_GetIsInCombat(oAssociate)) AssignCommand(oAssociate, ai_ClearCreatureActions(TRUE));
//SendMessageToPC(oPC, "0i_spells, 2104, nFeat: " + IntToString(nFeat) + " oTarget: " + GetName(oTarget));
if(!GetIsObjectValid(oTarget))
{
AssignCommand(oAssociate, ActionUseFeat(nFeat, OBJECT_INVALID, 0, lLocation));
AssignCommand(oAssociate, ActionUseFeat(nFeat, OBJECT_INVALID, nSubSpell, lLocation));
}
else AssignCommand(oAssociate, ActionUseFeat(nFeat, oTarget));
else AssignCommand(oAssociate, ActionUseFeat(nFeat, oTarget, nSubSpell));
}
void ai_UseWidgetItem(object oPC, object oAssociate, object oTarget, location lLocation)
{

View File

@ -854,6 +854,8 @@ int ai_TryKnockdownFeat(object oCreature, object oTarget)
}
int ai_TryPolymorphSelfFeat(object oCreature)
{
// Lets check to see if we should actually Polymorph?
if(GetHasFeat(FEAT_EPIC_OUTSIDER_SHAPE))
{
int nSubFeat = Random(3) + 733; // 733 azer, 734 rakshasa, 735 Slaad.

View File

@ -54,13 +54,6 @@ void main()
if(ai_TryDivineShieldFeat(oCreature, nInMelee)) return;
if(ai_TryDivineMightFeat(oCreature, nInMelee)) return;
}
//************************** SKILL FEATURES **************************
if(ai_TryAnimalEmpathy(oCreature)) return;
// ************************** CLASS FEATURES ***************************
if(ai_TryBarbarianRageFeat(oCreature)) return;
if(ai_TryBardSongFeat(oCreature)) return;
if(ai_TrySummonAnimalCompanionTalent(oCreature)) return;
if(ai_TrySummonFamiliarTalent(oCreature)) return;
}
// Class and Offensive single target talents.
if(nDifficulty >= AI_COMBAT_EFFORTLESS)
@ -74,6 +67,17 @@ void main()
if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) return;
}
}
if(nDifficulty >= AI_COMBAT_MODERATE)
{
//************************** SKILL FEATURES **************************
if(ai_TryAnimalEmpathy(oCreature)) return;
// ************************** CLASS FEATURES ***************************
if(ai_TryPolymorphSelfFeat(oCreature)) return;
if(ai_TryBarbarianRageFeat(oCreature)) return;
if(ai_TryBardSongFeat(oCreature)) return;
if(ai_TrySummonAnimalCompanionTalent(oCreature)) return;
if(ai_TrySummonFamiliarTalent(oCreature)) return;
}
// PHYSICAL ATTACKS - Either we don't have talents or we are saving them.
ai_DoPhysicalAttackOnBest(oCreature, nInMelee, !ai_GetAIMode(oCreature, AI_MODE_CHECK_ATTACK));
}

View File

@ -17,8 +17,6 @@ void main()
if(ai_TryCureConditionTalent(oCreature, nInMelee)) return;
int nDifficulty = ai_GetDifficulty(oCreature);
int nMaxLevel;
//************************** SKILL FEATURES **************************
if(ai_TryAnimalEmpathy(oCreature)) return;
// Check for moral and get the maximum spell level we should use.
if(nDifficulty >= AI_COMBAT_EFFORTLESS)
{
@ -30,7 +28,6 @@ void main()
{
// ************************** CLASS FEATURES ***************************
if(ai_TrySummonAnimalCompanionTalent(oCreature)) return;
if(ai_TryPolymorphSelfFeat(oCreature)) return;
// *************************** SPELL TALENTS ***************************
if(ai_CheckForAssociateSpellTalent(oCreature, nInMelee, nMaxLevel)) return;
}
@ -44,6 +41,9 @@ void main()
if(ai_UseCreatureTalent(oCreature, AI_TALENT_RANGED, nInMelee, nMaxLevel)) 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;

View File

@ -26,15 +26,11 @@ void main()
//**************************** SKILL FEATURES ****************************
if(ai_TryAnimalEmpathy(oCreature)) return;
//**************************** CLASS FEATURES ****************************
if(ai_TryBarbarianRageFeat(oCreature)) return;
if(ai_TryBardSongFeat(oCreature)) return;
if(ai_TryTurningTalent(oCreature)) return;
if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS))
{
if(ai_TrySummonFamiliarTalent(oCreature)) return;
if(ai_TrySummonAnimalCompanionTalent(oCreature)) return;
}
if(ai_TryPolymorphSelfFeat(oCreature)) return;
//************************** DEFENSIVE TALENTS ***************************
int nRound = ai_GetCurrentRound(oCreature);
if(ai_TryDefensiveTalents(oCreature, nInMelee, nMaxLevel, nRound)) return;
@ -44,6 +40,11 @@ void main()
// 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;
//**************************** CLASS FEATURES ****************************
if(ai_TryPolymorphSelfFeat(oCreature)) return;
if(ai_TryBarbarianRageFeat(oCreature)) return;
if(ai_TryBardSongFeat(oCreature)) return;
if(ai_TryTurningTalent(oCreature)) return;
// PHYSICAL ATTACKS - Either we don't have talents or we are saving them.
ai_DoPhysicalAttackOnNearest(oCreature, nInMelee);
}

View File

@ -22,8 +22,6 @@ void main()
// 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;
//**************************** SKILL FEATURES ****************************
if(ai_TryAnimalEmpathy(oCreature)) return;
//**************************** CLASS FEATURES ****************************
if(GetLocalInt(GetModule(), AI_RULE_SUMMON_COMPANIONS) && ai_TrySummonAnimalCompanionTalent(oCreature)) return;
if(ai_TryPolymorphSelfFeat(oCreature)) return;
@ -34,6 +32,8 @@ void main()
// 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;
//**************************** SKILL FEATURES ****************************
if(ai_TryAnimalEmpathy(oCreature)) return;
// All else fails lets see if we have any good potions.
// PHYSICAL ATTACKS - Either we don't have talents or we are saving them.
// ************************ RANGED ATTACKS *******************************

View File

@ -32,7 +32,7 @@
/// Local Override (int): PS_FORCE_SEARCH_BUTTON
/// 1 = PS_TRUE
/// -1 = PS_FALSE
const int PS_FORCE_SEARCH_BUTTON_DEFAULT = PS_TRUE;
const int PS_FORCE_SEARCH_BUTTON_DEFAULT = PS_FALSE;
/// @brief Determines whether item object state is saved to the database. The
/// object state includes variables and effects.
@ -51,7 +51,7 @@ const int PS_FORCE_OBJECT_STATE_DEFAULT = PS_TRUE;
/// Local Override (int): PS_STORAGE_LIMIT
/// -1 = PS_UNLIMITED
/// Set to any positive integer to limit item storage to that amount.
const int PS_STORAGE_LIMIT_DEFAULT = 500;
const int PS_STORAGE_LIMIT_DEFAULT = 200;
/// @brief Set the maximum distance (meters) a PC can travel from the container
/// before the form will auto-close.
@ -61,7 +61,7 @@ const int PS_STORAGE_LIMIT_DEFAULT = 500;
/// Local Override (float): PS_DISTANCE
/// -1.0 = PS_UNLIMITED_DISTANCE
/// Set to any positive float to limit distance to that amount.
const float PS_DISTANCE_DEFAULT = 5.0;
const float PS_DISTANCE_DEFAULT = 2.0;
/// @brief Set the container access type. Container inventories can be accessed
/// by two methods: exclusive and contentious.
@ -101,7 +101,7 @@ const int PS_ACCESS_TYPE_DEFAULT = PS_ACCESS_EXCLUSIVE;
/// 1 = PS_CONTAINER_PUBLIC
/// 2 = PS_CONTAINER_CHARACTER
/// 3 = PS_CONTAINER_CDKEY
const int PS_CONTAINER_TYPE_DEFAULT = PS_CONTAINER_CDKEY;
const int PS_CONTAINER_TYPE_DEFAULT = PS_CONTAINER_PUBLIC;
/// @brief Set the default container type, if the container is an item. Containers
/// can be of multiple types:
@ -148,7 +148,7 @@ const int PS_OPEN_INVENTORY_DEFAULT = PS_TRUE;
/// -1 = PS_UNLIMITED
/// -2 = PS_NONE
/// Set to any positive integer to limit gold to that amount.
const int PS_MAX_GOLD_DEFAULT = 1500000;
const int PS_MAX_GOLD_DEFAULT = 1000000;
/// @note Reference these terms for the following option:
/// Container: A persistent storage object in the game, such as a chest.
@ -168,7 +168,7 @@ const int PS_MAX_GOLD_DEFAULT = 1500000;
/// -2 = PS_NONE
/// Set to any positive integer to limit storage to that number of container
/// items.
const int PS_MAX_CONTAINER_ITEMS_DEFAULT = 100;
const int PS_MAX_CONTAINER_ITEMS_DEFAULT = 10;
/// @brief Determines how many items can be stored in stored container items.
/// Configuration File:
@ -191,7 +191,7 @@ const int PS_MAX_CONTAINER_ITEMS_DEFAULT = 100;
/// @warning Items that fail check involved with container item limitations do
/// not have default messages reported to the player. The item will simply fail
/// to be stored.
const int PS_MAX_CONTAINER_ITEMS_INVENTORY_DEFAULT = 1000;
const int PS_MAX_CONTAINER_ITEMS_INVENTORY_DEFAULT = 100;
/// @brief Creates the form's title.
/// @param oContainer The container object being used.

View File

@ -10,10 +10,8 @@ void main()
{
// If not runnning normal or better AI then exit for performance reasons
if (GetAILevel(OBJECT_SELF) == AI_LEVEL_VERY_LOW) return;
ExecuteScript("prc_npc_hb", OBJECT_SELF);
object oCreature = OBJECT_SELF;
ExecuteScript("prc_npc_hb", oCreature);
if(AI_DEBUG) ai_Debug("nw_c2_default1", "16", GetName(oCreature) + " Heartbeat." +
" OnSpawn: " + IntToString(GetLocalInt(oCreature, AI_ONSPAWN_EVENT)));
// We run our OnSpawn in the heartbeat so the creator can use the original

View File

@ -16,7 +16,7 @@ void main()
// * if not runnning normal or better AI then exit for performance reasons
//if (GetAILevel() == AI_LEVEL_VERY_LOW) return;
object oCreature = OBJECT_SELF;
ExecuteScript("prc_npc_percep", OBJECT_SELF);
ExecuteScript("prc_npc_percep", oCreature);
if(AI_DEBUG) ai_Debug("nw_c2_default2", "19", "AI_ONSPAWN_EVENT: " + IntToString(GetLocalInt(oCreature, AI_ONSPAWN_EVENT)));
if(!GetLocalInt(oCreature, AI_ONSPAWN_EVENT)) return;
if(GetLastPerceptionSeen())

View File

@ -17,7 +17,7 @@
void main()
{
object oCreature = OBJECT_SELF;
ExecuteScript("prc_npc_combat", OBJECT_SELF);
ExecuteScript("prc_npc_combat", oCreature);
if(AI_DEBUG) ai_Debug("nw_c2_default3", "20", GetName(oCreature) + " ends combat round." +
" Current action: " + IntToString(GetCurrentAction(oCreature)));
if(GetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT))

View File

@ -12,7 +12,7 @@ void ai_MonsterCommands(object oCreature, object oSpeaker, int nMatch);
void main()
{
object oCreature = OBJECT_SELF;
ExecuteScript("prc_npc_conv", OBJECT_SELF);
ExecuteScript("prc_npc_conv", oCreature);
if(AI_DEBUG) ai_Debug("nw_c2_default4", "15", GetName(oCreature) + " listens " +
IntToString(GetListenPatternNumber()) + " to " + GetName(GetLastSpeaker()) + "." +
" AI_AM_I_SEARCHING: " + IntToString(GetLocalInt(oCreature, AI_AM_I_SEARCHING)));

View File

@ -10,7 +10,7 @@
void main()
{
object oCreature = OBJECT_SELF;
ExecuteScript("prc_npc_physatt", OBJECT_SELF);
ExecuteScript("prc_npc_physatt", oCreature);
object oAttacker = GetLastAttacker(oCreature);
if(AI_DEBUG) ai_Debug("nw_c2_default5", "14", GetName(oCreature) + " was attacked by " +
GetName(oAttacker) + ".");

View File

@ -13,9 +13,7 @@
void main()
{
object oCreature = OBJECT_SELF;
ExecuteScript("prc_npc_damaged", OBJECT_SELF);
ExecuteScript("prc_npc_damaged", oCreature);
// Send the user-defined event signal
if(GetSpawnInCondition(NW_FLAG_DAMAGED_EVENT))
{

View File

@ -10,9 +10,9 @@
#include "0i_actions"
void main()
{
ExecuteScript("prc_npc_disturb", OBJECT_SELF);
if(AI_DEBUG) ai_Debug("nw_c2_default8", "13", GetName(OBJECT_SELF) + " is been disturbed!");
object oCreature = OBJECT_SELF;
ExecuteScript("prc_npc_disturb", oCreature);
if(AI_DEBUG) ai_Debug("nw_c2_default8", "13", GetName(oCreature) + " is been disturbed!");
// We do nothing at the moment... lets not mess up our factions ok?
// This should be defined by the server admins and is commented out.
//if(ai_GetIsBusy(OBJECT_SELF, FALSE) || ai_Disabled()) return;
@ -21,6 +21,6 @@ void main()
// Send the disturbed flag if appropriate.
if(GetSpawnInCondition(NW_FLAG_DISTURBED_EVENT))
{
SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_DISTURBED));
SignalEvent(oCreature, EventUserDefined(EVENT_DISTURBED));
}
}

View File

@ -10,10 +10,10 @@
void main()
{
object oCreature = OBJECT_SELF;
ExecuteScript("prc_npc_spellat", oCreature);
object oCaster = GetLastSpellCaster();
SetLocalObject(oCaster, AI_ATTACKED_SPELL, oCreature);
if(ai_Disabled(oCreature)) return;
ExecuteScript("prc_npc_spellat", OBJECT_SELF);
if(!GetLastSpellHarmful()) return;
// Send the user-defined event as appropriate
if(GetSpawnInCondition(NW_FLAG_SPELL_CAST_AT_EVENT))

View File

@ -9,6 +9,7 @@
void main()
{
object oCreature = OBJECT_SELF;
ExecuteScript("prc_npc_blocked", oCreature);
// This actually gets either a Creature or Door that is blocking OBJECT_SELF.
object oObject = GetBlockingDoor();
if(AI_DEBUG) ai_Debug("nw_c2_defaulte", "14", GetName(oCreature) + " is being blocked by " + GetName(oObject));

View File

@ -285,6 +285,7 @@ void main()
if(nChange) nColorId = GetColorIDChange(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected, nChange);
oNewItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, nMaterialSelected, nColorId, TRUE);
DestroyObject(oItem);
SetColorPalletPointer(oPC, nToken, oNewItem);
}
// Lock the new item so they can't change it on the character.
LockItemInCraftingWindow(oPC, oNewItem, oTarget, nToken);
@ -643,6 +644,7 @@ void main()
int nSelected = StringToInt(GetStringRight(sElem, 1));
SetMaterialButtons(oPC, nToken, nSelected);
jCraft = JsonObjectSet(jCraft, CRAFT_MATERIAL_SELECTION, JsonInt(nSelected));
SetLocalJson(oPC, CRAFT_JSON, jCraft);
// Change the pallet for the correct material.
string sColorPallet;
if(nSelected < 4)

View File

@ -1,227 +0,0 @@
/*//////////////////////////////////////////////////////////////////////////////
Script Name: pe_test
Programmer: Philos
////////////////////////////////////////////////////////////////////////////////
PEPS Plugin to help test errors.
Gives gold, Heals, etc.
/*//////////////////////////////////////////////////////////////////////////////
#include "0i_main"
void main()
{
// Get the last player to use targeting mode
object oPC = GetLastPlayerToSelectTarget();
string sTargetMode = GetLocalString(oPC, AI_TARGET_MODE);
if(oPC == OBJECT_SELF && sTargetMode != "")
{
// Get the targeting mode data
object oTarget = GetTargetingModeSelectedObject();
vector vTarget = GetTargetingModeSelectedPosition();
location lLocation = Location(GetArea(oPC), vTarget, GetFacing(oPC));
object oAssociate = GetLocalObject(oPC, AI_TARGET_ASSOCIATE);
// If the user manually exited targeting mode without selecting a target, return
if(!GetIsObjectValid(oTarget) && vTarget == Vector())
{
return;
}
// Targeting code here.
if(sTargetMode == "TEST_LEVEL_TARGET")
{
int nLevel = ai_GetCharacterLevels(oTarget);
int nXPNeeded = StringToInt(Get2DAString("exptable", "XP", nLevel));
int nXPToGive = nXPNeeded - GetXP(oTarget);
GiveXPToCreature(oTarget, nXPToGive);
ai_SendMessages(GetName(oTarget) + " has gained " + IntToString(nXPToGive) + " experience to gain 1 level.", AI_COLOR_YELLOW, oPC);
}
else if(sTargetMode == "TEST_GOLD_TARGET")
{
GiveGoldToCreature(oTarget, 10000);
ai_SendMessages(GetName(oTarget) + " has gained 10,000 gold.", AI_COLOR_YELLOW, oPC);
}
else if(sTargetMode == "TEST_REST_TARGET")
{
ForceRest(oTarget);
ai_SendMessages(GetName(oTarget) + " has rested.", AI_COLOR_GREEN, oPC);
}
else if(sTargetMode == "TEST_HEAL_TARGET")
{
int nHeal = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget);
if(nHeal > 0)
{
effect eHeal = EffectHeal(nHeal);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
ai_SendMessages(GetName(oTarget) + " has been healed.", AI_COLOR_GREEN, oPC);
}
}
else if(sTargetMode == "TEST_ID_TARGET") SetIdentified(oTarget, !GetIdentified(oTarget));
else if(sTargetMode == "TEST_CLEAR_TARGET")
{
ClearAllActions(TRUE, oTarget);
}
else if(sTargetMode == "TEST_KILL_TARGET")
{
effect eDmg = EffectDamage(10000);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget);
ai_SendMessages(GetName(oTarget) + " has been killed.", AI_COLOR_RED, oPC);
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_KILL_TARGET");
EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_KILL, MOUSECURSOR_NOKILL);
}
else if(sTargetMode == "TEST_REMOVE_TARGET")
{
SetIsDestroyable(TRUE, FALSE, FALSE, oTarget);
DestroyObject(oTarget);
ai_SendMessages(GetName(oTarget) + " has been removed!", AI_COLOR_RED, oPC);
}
else if(sTargetMode == "TEST_JUMP")
{
JumpToLocation(lLocation);
int nIndex;
object oAssociate;
for(nIndex = 2; nIndex < 6; nIndex++)
{
oAssociate = GetAssociate(nIndex, oPC);
if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, JumpToLocation(lLocation));
}
for(nIndex = 1; nIndex < AI_MAX_HENCHMAN; nIndex++)
{
oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oPC, nIndex);
if(oAssociate != OBJECT_INVALID) AssignCommand(oAssociate, JumpToLocation(lLocation));
}
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_JUMP");
EnterTargetingMode(oPC, OBJECT_TYPE_TILE, MOUSECURSOR_TRANSITION, MOUSECURSOR_NOWALK);
}
else if(sTargetMode == "TEST_KILL_AREA")
{
effect eDmg = EffectDamage(10000);
object oKill = GetFirstObjectInShape(SHAPE_SPHERE, 6.67, lLocation, FALSE);
while(oKill != OBJECT_INVALID)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oKill);
oKill = GetNextObjectInShape(SHAPE_SPHERE, 6.67, lLocation, FALSE);
}
}
}
// Run all non-targeting code here, usually NUI events.
else
{
object oPC = NuiGetEventPlayer();
int nToken = NuiGetEventWindow();
string sEvent = NuiGetEventType();
string sElem = NuiGetEventElement();
int nIndex = NuiGetEventArrayIndex();
//string sWndId = NuiGetWindowId(oPC, nToken);
//**********************************************************************
//if(GetLocalInt(oPC, AI_NO_NUI_SAVE)) return;
if(sEvent == "click")
{
if(sElem == "btn_level")
{
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_LEVEL_TARGET");
EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE , MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE);
}
else if(sElem == "btn_gold")
{
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_GOLD_TARGET");
EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE , MOUSECURSOR_CREATE, MOUSECURSOR_NOCREATE);
}
else if(sElem == "btn_rest")
{
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_REST_TARGET");
EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE , MOUSECURSOR_EXAMINE, MOUSECURSOR_NOEXAMINE);
}
else if(sElem == "btn_heal")
{
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_HEAL_TARGET");
EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_HEAL, MOUSECURSOR_NOHEAL);
}
else if(sElem == "btn_id_item")
{
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_ID_TARGET");
EnterTargetingMode(oPC, OBJECT_TYPE_ITEM, MOUSECURSOR_HEAL, MOUSECURSOR_NOHEAL);
}
else if(sElem == "btn_clear")
{
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_CLEAR_TARGET");
EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_MAGIC, MOUSECURSOR_NOMAGIC);
}
else if(sElem == "btn_kill")
{
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_KILL_TARGET");
EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE, MOUSECURSOR_KILL, MOUSECURSOR_NOKILL);
}
else if(sElem == "btn_remove")
{
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_REMOVE_TARGET");
EnterTargetingMode(oPC, OBJECT_TYPE_CREATURE |
OBJECT_TYPE_DOOR | OBJECT_TYPE_ITEM |
OBJECT_TYPE_PLACEABLE, MOUSECURSOR_KILL, MOUSECURSOR_NOKILL);
}
else if(sElem == "btn_jump")
{
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_JUMP");
EnterTargetingMode(oPC, OBJECT_TYPE_TILE, MOUSECURSOR_TRANSITION, MOUSECURSOR_NOWALK);
}
else if(sElem == "btn_kill_area")
{
// Set this variable on the player so PEPS can run the targeting script for this plugin.
SetLocalString(oPC, AI_PLUGIN_TARGET_SCRIPT, "pe_test");
// Set Targeting variables.
SetLocalObject(oPC, AI_TARGET_ASSOCIATE, OBJECT_SELF);
SetLocalString(oPC, AI_TARGET_MODE, "TEST_KILL_AREA");
SetEnterTargetingModeData(oPC, SPELL_TARGETING_SHAPE_SPHERE, 6.67, 0.0, 3);
EnterTargetingMode(oPC, OBJECT_TYPE_ALL, MOUSECURSOR_KILL, MOUSECURSOR_NOKILL);
}
}
else if(sEvent == "watch")
{
if(sElem == "txt_debug_creature")
{
}
}
}
}

View File

@ -5,12 +5,9 @@
Crafting UI for players items.
*///////////////////////////////////////////////////////////////////////////////
#include "nw_inc_nui"
#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";
@ -45,6 +42,7 @@ void main()
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));
@ -128,7 +126,7 @@ void main()
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,255,255), JsonBool(FALSE), JsonFloat(2.0), NuiBind("color_pallet_pointer")));
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));
@ -541,7 +539,6 @@ void main()
// 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;

View File

@ -1,103 +0,0 @@
/*//////////////////////////////////////////////////////////////////////////////
Script: pi_test
Programmer: Philos
////////////////////////////////////////////////////////////////////////////////
Plugin for debugging.
*///////////////////////////////////////////////////////////////////////////////
#include "0i_nui"
#include "0i_player_target"
// Does startup check if the game has just been loaded.
int StartingUp(object oPC);
void main()
{
object oPC = OBJECT_SELF;
if(StartingUp(oPC)) return;
string sText;
// Set window to not save until it has been created.
//SetLocalInt (oPC, AI_NO_NUI_SAVE, TRUE);
//DelayCommand (0.5f, DeleteLocalInt (oPC, AI_NO_NUI_SAVE));
// ************************************************************************* Width / Height
// Row 1 ******************************************************************* 636 / 73
json jRow = JsonArrayInsert(JsonArray(), NuiSpacer());
jRow = CreateButton(jRow, "Level Up Creature", "btn_level", 150.0f, 20.0f, -1.0, "btn_level_tooltip");
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = CreateButton(jRow, "Gold for Creature", "btn_gold", 150.0f, 20.0f, -1.0, "btn_gold_tooltip");
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = CreateButton(jRow, "Force Rest Creature", "btn_rest", 150.0f, 20.0f, -1.0, "btn_rest_tooltip");
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = CreateButton(jRow, "ID/UnID Item", "btn_id_item", 150.0f, 20.0f, -1.0, "btn_id_item_tooltip");
jRow = JsonArrayInsert(jRow, NuiSpacer());
// Add row to the column.
json jCol = JsonArrayInsert(JsonArray(), NuiRow(jRow));
// Row 2 ******************************************************************* 636 / 101
jRow = JsonArrayInsert(JsonArray(), NuiSpacer());
jRow = CreateButton(jRow, "Heal Creature", "btn_heal", 150.0f, 20.0f, -1.0, "btn_heal_tooltip");
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = CreateButton(jRow, "Clear Creature Actions", "btn_clear", 150.0f, 20.0f, -1.0, "btn_clear_tooltip");
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = CreateButton(jRow, "Kill Creature", "btn_kill", 150.0f, 20.0f, -1.0, "btn_kill_tooltip");
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = CreateButton(jRow, "Remove Object", "btn_remove", 150.0f, 20.0f, -1.0, "btn_remove_tooltip");
jRow = JsonArrayInsert(jRow, NuiSpacer());
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
// Row 3 ******************************************************************* 636 / 101
jRow = JsonArrayInsert(JsonArray(), NuiSpacer());
jRow = CreateButton(jRow, "Jump To", "btn_jump", 150.0f, 20.0f, -1.0, "btn_jump_tooltip");
jRow = JsonArrayInsert(jRow, NuiSpacer());
jRow = CreateButton(jRow, "Kill In Area", "btn_kill_area", 150.0f, 20.0f, -1.0, "btn_kill_area_tooltip");
jRow = JsonArrayInsert(jRow, NuiSpacer());
// Add row to the column.
jCol = JsonArrayInsert(jCol, NuiRow(jRow));
float fHeight = 129.0;
// Set the Layout of the window.
json jLayout = NuiCol(jCol);
string sName = GetName(oPC);
if(GetStringRight(sName, 1) == "s") sName = sName + "'";
else sName = sName + "'s";
int nToken = SetWindow(oPC, jLayout, "pi_test_nui", sName + " PEPS Testing Menu",
-1.0, -1.0, 636.0f, fHeight + 12.0f, FALSE, FALSE, TRUE, FALSE, TRUE, "pe_test");
// Set all binds, events, and watches.
// Row 1
NuiSetBind(oPC, nToken, "btn_level_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_level_tooltip", JsonString(" Give level to target creature."));
NuiSetBind(oPC, nToken, "btn_gold_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_gold_tooltip", JsonString(" Give Gold to target creature."));
NuiSetBind(oPC, nToken, "btn_rest_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_rest_tooltip", JsonString(" Force rest target creature."));
NuiSetBind(oPC, nToken, "btn_id_item_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_id_item_tooltip", JsonString(" Identify or UnIdentify the target item."));
// Row 2
NuiSetBind(oPC, nToken, "btn_heal_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_heal_tooltip", JsonString(" Heal target creature to max hitpoints."));
NuiSetBind(oPC, nToken, "btn_clear_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_clear_tooltip", JsonString(" Clears a creature's actions including combat."));
NuiSetBind(oPC, nToken, "btn_kill_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_kill_tooltip", JsonString(" Kill target creature doing 10,000 magic damage."));
NuiSetBind(oPC, nToken, "btn_remove_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_remove_tooltip", JsonString(" Remove selected object or the nearest object to ground selection."));
// Row 3
NuiSetBind(oPC, nToken, "btn_jump_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_jump_tooltip", JsonString(" Jump to target location."));
NuiSetBind(oPC, nToken, "btn_kill_area_event", JsonBool(TRUE));
NuiSetBind(oPC, nToken, "btn_kill_area_tooltip", JsonString(" Kills all creatures in target area."));
}
int StartingUp(object oPC)
{
if(GetLocalInt(oPC, AI_ADD_PLUGIN))
{
json jPlugin = JsonArray();
jPlugin = JsonArrayInsert(jPlugin, JsonString("pi_test"));
jPlugin = JsonArrayInsert(jPlugin, JsonInt(FALSE));
jPlugin = JsonArrayInsert(jPlugin, JsonString("Testing Menu"));
jPlugin = JsonArrayInsert(jPlugin, JsonString("ir_charsheet"));
json jPlugins = GetLocalJson(oPC, AI_JSON_PLUGINS);
jPlugins = JsonArrayInsert(jPlugins, jPlugin);
SetLocalJson(oPC, AI_JSON_PLUGINS, jPlugin);
SetLocalInt(oPC, AI_PLUGIN_SET, TRUE);
return TRUE;
}
if(!GetLocalInt(oPC, AI_STARTING_UP)) return FALSE;
return TRUE;
}

View File

@ -814,7 +814,7 @@ json CreateLevelStatList(json jHenchman, object oHenchman, object oPC, int nLeve
{
jLevelArray = JsonArrayInsert(jLevelArray, jLevel);
}
WriteTimestampedLogEntry("pinc_henchmen, 813, Adding LvlStatList to " + GetName(oHenchman));
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)
@ -969,6 +969,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.");
int nRaceRow, nRaceFeat;
int nRaceMaxRow = Get2DARowCount(sRace2DAName);
while(nRaceRow < nRaceMaxRow)
@ -978,11 +979,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, 973, Adding racial feat: " +
WriteTimestampedLogEntry("pinc_henchmen, 982, Adding racial feat: " +
Get2DAString("feat", "LABEL", nRaceFeat));
nRaceRow++;
}
// Give class feats.
WriteTimestampedLogEntry("pinc_henchmen, 972, Checking for class feats.");
int nClass = GetClassByPosition(1, oHenchman);
string sGranted, sList;
string sClsFeat2DAName = Get2DAString("classes", "FeatsTable", nClass);
@ -1000,13 +1002,14 @@ 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, 995, Adding class feat: " +
WriteTimestampedLogEntry("pinc_henchmen, 1005, 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));
@ -1044,10 +1047,11 @@ 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++;
nPackageRow = 0;
while(nPackageRow < nPackageMaxRow)
while(nPackageRow < nPackageMaxRow || nNumOfFeats > 0)
{
nClassRow = 0;
nPackageFeat = StringToInt(Get2DAString(sPackage2DAName, "FeatIndex", nPackageRow));
@ -1064,6 +1068,7 @@ json ResetFeats(json jHenchman, object oHenchman)
if(nNumOfFeats < 1) break;
nPackageRow++;
}
WriteTimestampedLogEntry("pinc_henchmen, 1071, Adding feat list.");
jHenchman = GffReplaceList(jHenchman, "FeatList", jFeatList);
return jHenchman;
}
@ -1079,6 +1084,7 @@ json ResetSkills(json jHenchman, object oHenchman)
json jSkillList = JsonArray();
json jSkill;
// Setup the Skill List.
WriteTimestampedLogEntry("pinc_henchmen, 1087, Generating skill list.");
int nIndex, nSkillMaxRow = Get2DARowCount("skills");
for(nIndex = 0; nIndex < nSkillMaxRow; nIndex++)
{
@ -1088,6 +1094,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.");
int nPackageSkill, nPackageRow, nCurrentRanks, bCrossClass, nClassRow, nNewRanks;
string sPackage2DAName = Get2DAString("packages", "SkillPref2DA", nClass);
int nPackageMaxRow = Get2DARowCount(sPackage2DAName);
@ -1116,8 +1123,9 @@ json ResetSkills(json jHenchman, object oHenchman)
{
jSkill = GffReplaceByte(jSkill, "Rank", nCurrentRanks + nNewRanks);
jSkillList = JsonArraySet(jSkillList, nPackageSkill, jSkill);
WriteTimestampedLogEntry("pinc_henchmen, 1110, Adding " + IntToString(nNewRanks) +
" ranks to " + Get2DAString("skills", "Label", nPackageSkill));
WriteTimestampedLogEntry("pinc_henchmen, 1126, Adding " + IntToString(nNewRanks) +
" ranks to " + Get2DAString("skills", "Label", nPackageSkill) +
" CrossClass: " + IntToString(bCrossClass));
nSkillPoints -= nNewRanks;
}
nPackageRow++;
@ -1127,7 +1135,9 @@ json ResetSkills(json jHenchman, object oHenchman)
}
json ResetSpellsKnown(json jClass, object oHenchman)
{
WriteTimestampedLogEntry("pinc_henchmen, 1138, Checking for spells known.");
int nClass = GetClassByPosition(1, oHenchman);
WriteTimestampedLogEntry("pinc_henchmen, 1140, 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!

View File

@ -0,0 +1,14 @@
//:://////////////////////////////////////////////////
//:: X0_CH_HEN_BLOCK
/*
OnBlocked handler for henchmen/associates.
*/
//:://////////////////////////////////////////////////
//:: Copyright (c) 2002 Floodgate Entertainment
//:: Created By: Naomi Novik
//:: Created On: 01/06/2003
//:://////////////////////////////////////////////////
void main()
{
ExecuteScript("nw_ch_ace");
}

View File

@ -0,0 +1,36 @@
//::///////////////////////////////////////////////
//:: Associate: End of Combat End
//:: NW_CH_AC3
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Calls the end of combat script every round
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2001
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Modified By: Deva Winblood
//:: Modified On: Jan 16th, 2008
//:: Added Support for Mounted Combat Feat Support
//:://////////////////////////////////////////////
#include "x0_inc_henai"
void main()
{
if (!GetLocalInt(GetModule(),"X3_NO_MOUNTED_COMBAT_FEAT"))
{ // set variables on target for mounted combat
DeleteLocalInt(OBJECT_SELF,"bX3_LAST_ATTACK_PHYSICAL");
DeleteLocalInt(OBJECT_SELF,"nX3_HP_BEFORE");
DeleteLocalInt(OBJECT_SELF,"bX3_ALREADY_MOUNTED_COMBAT");
} // set variables on target for mounted combat
if(!GetSpawnInCondition(NW_FLAG_SET_WARNINGS))
{
ExecuteScript("nw_ch_ac3");
}
if(GetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT))
{
SignalEvent(OBJECT_SELF, EventUserDefined(1003));
}
}

View File

@ -0,0 +1,91 @@
//:://////////////////////////////////////////////////
//:: X0_CH_HEN_CONV
// OnDialogue event handler for henchmen/associates.
//:://////////////////////////////////////////////////
//:: Copyright (c) 2002 Floodgate Entertainment
//:: Created By: Naomi Novik
//:: Created On: 01/05/2003
//:://////////////////////////////////////////////////
#include "x0_inc_henai"
#include "x0_i0_henchman"
#include "0i_associates"
//* GeorgZ - Put in a fix for henchmen talking even if they are petrified
int AbleToTalk(object oSelf)
{
if (GetHasEffect(EFFECT_TYPE_CONFUSED, oSelf) || GetHasEffect(EFFECT_TYPE_DOMINATED, oSelf) ||
GetHasEffect(EFFECT_TYPE_PETRIFY, oSelf) || GetHasEffect(EFFECT_TYPE_PARALYZE, oSelf) ||
GetHasEffect(EFFECT_TYPE_STUNNED, oSelf) || GetHasEffect(EFFECT_TYPE_FRIGHTENED, oSelf)
)
{
return FALSE;
}
return TRUE;
}
void main()
{
object oCreature = OBJECT_SELF;
// * XP2, special handling code for interjections
// * This script only fires if someone inits with me.
// * with that in mind, I am now clearing any interjections
// * that the character might have on themselves.
if (GetLocalInt(GetModule(), "X2_L_XP2") == TRUE)
{
SetLocalInt(oCreature, "X2_BANTER_TRY", 0);
SetHasInterjection(GetMaster(oCreature), FALSE);
SetLocalInt(oCreature, "X0_L_BUSY_SPEAKING_ONE_LINER", 0);
SetOneLiner(FALSE, 0);
}
object oLastSpeaker = GetLastSpeaker();
if (GetTag(oCreature) == "x0_hen_dee")
{
string sCall = GetCampaignString("Deekin", "q6_Deekin_Call"+ GetName(oLastSpeaker), oLastSpeaker);
if (sCall == "") SetCustomToken(1001, GetStringByStrRef(40570));
else SetCustomToken(1001, sCall);
}
// If we are disabled then we can't listen or talk, Busy is checked in ai_SelectAssociateCommand().
if (GetIsHenchmanDying(oCreature) || ai_Disabled(oCreature)) return;
object oMaster = GetMaster();
int nMatch = GetListenPatternNumber();
object oIntruder;
if (nMatch == -1)
{
if (!ai_GetIsBusy(oCreature))
{
ai_ClearCreatureActions();
string sDialogFileToUse = GetDialogFileToUse(GetLastSpeaker());
BeginConversation(sDialogFileToUse);
}
}
else
{
// listening pattern matched
if (GetIsObjectValid(oMaster)) ai_SelectAssociateCommand(oCreature, oLastSpeaker, nMatch);
// we don't have a master, behave in default way
else if (GetIsObjectValid(oLastSpeaker) &&
!GetIsPC(oLastSpeaker) &&
GetIsFriend(oLastSpeaker))
{
object oIntruder = OBJECT_INVALID;
// Determine the intruder if any
if(nMatch == 4) oIntruder = GetLocalObject(oLastSpeaker, "NW_BLOCKER_INTRUDER");
else if (nMatch == 5)
{
oIntruder = GetLastHostileActor(oLastSpeaker);
if(!GetIsObjectValid(oIntruder))
{
oIntruder = GetAttemptedAttackTarget();
if(!GetIsObjectValid(oIntruder)) oIntruder = GetAttemptedSpellTarget();
}
}
// Actually respond to the shout
RespondToShout(oLastSpeaker, nMatch, oIntruder);
}
}
// Signal user-defined event
if(GetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT))
{
SignalEvent(oCreature, EventUserDefined(EVENT_DIALOGUE));
}
}

View File

@ -0,0 +1,15 @@
//:://////////////////////////////////////////////////
//:: X0_CH_HEN_REST
/*
OnRest event handler for henchmen/associates.
*/
//:://////////////////////////////////////////////////
//:: Copyright (c) 2002 Floodgate Entertainment
//:: Created By: Naomi Novik
//:: Created On: 01/06/2003
//:://////////////////////////////////////////////////
void main()
{
ExecuteScript("nw_ch_aca");
}