2025/07/21 Update

Updated PEPS AI.
Full compile.
This commit is contained in:
Jaysyn904
2025-07-21 09:41:55 -04:00
parent 0e9e2c6950
commit ca8d5eba41
282 changed files with 920 additions and 646 deletions

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

@@ -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

@@ -15,7 +15,7 @@
//:://////////////////////////////////////////////
#include "NW_O2_CONINCLUDE"
#include "prc_class_const"
void CreateBastardSword(object oTarget, object oAdventurer)

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

@@ -42,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));
@@ -125,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));

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");
}