2025/12/15 Update
Updated PEPS Hooked up new PRC8 GUI event. Updated nim tools. Updated readme.
This commit is contained in:
@@ -149,12 +149,12 @@ void ai_SetupAllyHealingTargets(object oCaster, object oPC);
|
||||
// Clears the casters buff targets.
|
||||
void ai_ClearBuffTargets(object oCaster, string sVariable);
|
||||
// Cycles through a casters spells casting all buffs via actions.
|
||||
void ai_ActionCastMemorizedBuff(struct stSpell stSpell);
|
||||
void ai_ActionCastMemorizedBuff(struct stSpell stSpell, float fDelay, int bInstantSpell);
|
||||
// Cycles through a casters spells casting all buffs via actions.
|
||||
void ai_ActionCastKnownBuff(struct stSpell stSpell);
|
||||
void ai_ActionCastKnownBuff(struct stSpell stSpell, float fDelay, int bInstantSpell);
|
||||
// Checks oCaster for buffing spells and casts them based on nTarget;
|
||||
// These are cast as actions and will happen at the speed based on
|
||||
// AI_HENCHMAN_BUFF_DELAY, but are still actions.
|
||||
// These are cast as actions and will happen at the speed based on the delay set
|
||||
// by the player. 6.0 seconds to 0.1 second. Default 0.1 second.
|
||||
// nTarget is 0-9 where 0 is all targets, 1 is oPC, 2 is the caster
|
||||
// 3 Familiar, 4 is Animal Companion, 5 is Summons, 6 is Dominated, and 7+ is henchman.
|
||||
// Targets must be defined in variable AI_ALLY_TARGET_* where * is 1 to #.
|
||||
@@ -163,6 +163,12 @@ void ai_CastBuffs(object oCaster, int nBuffType, int nTarget, object oPC);
|
||||
// Returns TRUE if oCaster cast spontaneous cure spell on oTarget.
|
||||
// This uses an action and must use AssignCommand or OBJECT_SELF is the caster!
|
||||
int ai_CastSpontaneousCure(object oCreature, object oTarget, object oPC);
|
||||
// Returns TRUE if oCaster casts a memorized inflict spell on oTarget.
|
||||
// This uses an action and must use AssignCommand or OBJECT_SELF is the caster!
|
||||
int ai_CastMemorizedInflict(object oCreature, object oTarget, object oPC, int nClass);
|
||||
// Returns TRUE if oCaster casts a known inflict spell on oTarget.
|
||||
// This uses an action and must use AssignCommand or OBJECT_SELF is the caster!
|
||||
int ai_CastKnownInflict(object oCreature, object oTarget, object oPC, int nClass);
|
||||
// Returns TRUE if oCaster casts a memorized cure spell on oTarget.
|
||||
// This uses an action and must use AssignCommand or OBJECT_SELF is the caster!
|
||||
int ai_CastMemorizedHealing(object oCreature, object oTarget, object oPC, int nClass);
|
||||
@@ -178,6 +184,8 @@ void ai_SpellConcentrationCheck(object oCaster);
|
||||
int ai_CastInMelee(object oCreature, int nSpell, int nInMelee);
|
||||
// Returns a float range for the caster to search for a target of an offensive spell.
|
||||
float ai_GetOffensiveSpellSearchRange(object oCreature, int nSpell);
|
||||
// Returns TRUE if nSpell is an inflict spell and will not over heal for nDamage.
|
||||
int ai_ShouldWeCastThisInflictSpell(int nSpell, int nDamage);
|
||||
// Returns TRUE if nSpell is a cure spell and will not over heal for nDamage.
|
||||
int ai_ShouldWeCastThisCureSpell(int nSpell, int nDamage);
|
||||
// Casts the spell on the current target for oAssociate.
|
||||
@@ -394,73 +402,198 @@ int ai_GetIsSpellBookRestrictedCaster(object oAssociate)
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
// This is used to set immunities on a creature not using the AI.
|
||||
// Should only update every minute.
|
||||
void ai_SetCreatureItemImmunities(object oCreature)
|
||||
{
|
||||
// Create an Immunity in json so we can check item immunities quickly for non-AI creatures.
|
||||
SetLocalInt(oCreature, sIPTimeStampVarname, ai_GetCurrentTimeStamp());
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "402", "Checking for Item immunities on " + GetName(oCreature));
|
||||
int nSpellImmunity, bHasItemImmunity, nSlot;
|
||||
json jImmunity = JsonArray();
|
||||
DeleteLocalInt(oCreature, sIPImmuneVarname);
|
||||
DeleteLocalInt(oCreature, sIPResistVarname);
|
||||
DeleteLocalInt(oCreature, sIPReducedVarname);
|
||||
int nIprpSubType, nSpell, nLevel, nIPType, nIndex;
|
||||
itemproperty ipProp;
|
||||
// Cycle through all the creatures equiped items.
|
||||
object oItem = GetItemInSlot(nSlot, oCreature);
|
||||
while(nSlot < 12)
|
||||
{
|
||||
if(oItem != OBJECT_INVALID)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "416", "Checking Item immunities on " + GetName(oItem));
|
||||
ipProp = GetFirstItemProperty(oItem);
|
||||
// Check for immunities on items.
|
||||
while(GetIsItemPropertyValid(ipProp))
|
||||
{
|
||||
nIPType = GetItemPropertyType(ipProp);
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "422", "ItempropertyType(53/20/23/22): " + IntToString(nIPType));
|
||||
if(nIPType == ITEM_PROPERTY_IMMUNITY_SPECIFIC_SPELL)
|
||||
{
|
||||
bHasItemImmunity = TRUE;
|
||||
nSpellImmunity = GetItemPropertyCostTableValue(ipProp);
|
||||
nSpellImmunity = StringToInt(Get2DAString("iprp_spellcost", "SpellIndex", nSpellImmunity));
|
||||
//if(AI_DEBUG) ai_Debug("0i_talents", "1950", "SpellImmunity to " + Get2DAString("spells", "Label", nSpellImmunity));
|
||||
jImmunity = JsonArrayInsert(jImmunity, JsonInt(nSpellImmunity));
|
||||
}
|
||||
else if(nIPType == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE)
|
||||
{
|
||||
int nBit, nIpSubType = GetItemPropertySubType(ipProp);
|
||||
if(AI_DEBUG) ai_Debug("0i_talents", "434", "Immune DmgType: nIPSubType: " + IntToString(nIpSubType));
|
||||
if(nIpSubType == 0) nBit = DAMAGE_TYPE_BLUDGEONING;
|
||||
else if(nIpSubType == 1) nBit = DAMAGE_TYPE_PIERCING;
|
||||
else if(nIpSubType == 2) nBit = DAMAGE_TYPE_SLASHING;
|
||||
else if(nIpSubType == 5) nBit = DAMAGE_TYPE_MAGICAL;
|
||||
else if(nIpSubType == 6) nBit = DAMAGE_TYPE_ACID;
|
||||
else if(nIpSubType == 7) nBit = DAMAGE_TYPE_COLD;
|
||||
else if(nIpSubType == 8) nBit = DAMAGE_TYPE_DIVINE;
|
||||
else if(nIpSubType == 9) nBit = DAMAGE_TYPE_ELECTRICAL;
|
||||
else if(nIpSubType == 10) nBit = DAMAGE_TYPE_FIRE;
|
||||
else if(nIpSubType == 11) nBit = DAMAGE_TYPE_NEGATIVE;
|
||||
else if(nIpSubType == 12) nBit = DAMAGE_TYPE_POSITIVE;
|
||||
else if(nIpSubType == 13) nBit = DAMAGE_TYPE_SONIC;
|
||||
if(nBit > 0) ai_SetItemProperty(oCreature, sIPImmuneVarname, nBit, TRUE);
|
||||
}
|
||||
else if(nIPType == ITEM_PROPERTY_DAMAGE_RESISTANCE)
|
||||
{
|
||||
int nBit, nIpSubType = GetItemPropertySubType(ipProp);
|
||||
if(AI_DEBUG) ai_Debug("0i_talents", "452", "Dmg Resist: nIPSubType: " + IntToString(nIpSubType));
|
||||
if(nIpSubType == 0) nBit = DAMAGE_TYPE_BLUDGEONING;
|
||||
else if(nIpSubType == 1) nBit = DAMAGE_TYPE_PIERCING;
|
||||
else if(nIpSubType == 2) nBit = DAMAGE_TYPE_SLASHING;
|
||||
else if(nIpSubType == 5) nBit = DAMAGE_TYPE_MAGICAL;
|
||||
else if(nIpSubType == 6) nBit = DAMAGE_TYPE_ACID;
|
||||
else if(nIpSubType == 7) nBit = DAMAGE_TYPE_COLD;
|
||||
else if(nIpSubType == 8) nBit = DAMAGE_TYPE_DIVINE;
|
||||
else if(nIpSubType == 9) nBit = DAMAGE_TYPE_ELECTRICAL;
|
||||
else if(nIpSubType == 10) nBit = DAMAGE_TYPE_FIRE;
|
||||
else if(nIpSubType == 11) nBit = DAMAGE_TYPE_NEGATIVE;
|
||||
else if(nIpSubType == 12) nBit = DAMAGE_TYPE_POSITIVE;
|
||||
else if(nIpSubType == 13) nBit = DAMAGE_TYPE_SONIC;
|
||||
if(nBit > 0) ai_SetItemProperty(oCreature, sIPResistVarname, nBit, TRUE);
|
||||
}
|
||||
else if(nIPType == ITEM_PROPERTY_DAMAGE_REDUCTION)
|
||||
{
|
||||
int nIpSubType = GetItemPropertySubType(ipProp);
|
||||
if(AI_DEBUG) ai_Debug("0i_talents", "470", "Dmg Reduction: nIPSubType: " + IntToString(nIpSubType));
|
||||
SetLocalInt(oCreature, sIPReducedVarname, nIpSubType);
|
||||
}
|
||||
nIndex++;
|
||||
ipProp = GetNextItemProperty(oItem);
|
||||
}
|
||||
// If nSpellImmunity has been set then we need to save our Immunity json.
|
||||
if(bHasItemImmunity) SetLocalJson(oCreature, AI_TALENT_IMMUNITY, jImmunity);
|
||||
}
|
||||
oItem = GetItemInSlot(++nSlot, oCreature);
|
||||
// Make the final check the creatures hide.
|
||||
if(nSlot == 11) oItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oCreature);
|
||||
}
|
||||
}
|
||||
int ai_CreatureImmuneToEffect(object oCaster, object oCreature, int nSpell)
|
||||
{
|
||||
// This checks for creatures not using the AI system (usually players).
|
||||
// Creatures using the AI system will always have a value in sIPReducedVarname!
|
||||
// Updates thier immunity values every minute. Should be good as we only update
|
||||
// equiped items. Spell effects are checked on the creature and are not saved.
|
||||
if(AI_DEBUG)
|
||||
{
|
||||
if(GetLocalInt(oCreature, sIPReducedVarname) == 0) ai_Debug("0i_spells", "492",
|
||||
" Immunities last saved: " + IntToString(GetLocalInt(oCreature, sIPTimeStampVarname)) +
|
||||
" + 60 < " + IntToString(ai_GetCurrentTimeStamp()));
|
||||
}
|
||||
if(GetLocalInt(oCreature, sIPReducedVarname) == 0 &&
|
||||
GetLocalInt(oCreature, sIPTimeStampVarname) + 60 < ai_GetCurrentTimeStamp()) ai_SetCreatureItemImmunities(oCreature);
|
||||
string sIType = Get2DAString("ai_spells", "ImmunityType", nSpell);
|
||||
// Let us check if the creature is disabled while we look for immunities.
|
||||
int nDisabled = ai_Disabled(oCreature);
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "499", "Checking spell immunity type(" + sIType + ").");
|
||||
if(sIType != "")
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "290", "Checking spell immunity type(" + sIType + ").");
|
||||
if(sIType == "Death" && GetIsImmune(oCreature, IMMUNITY_TYPE_DEATH)) return TRUE;
|
||||
else if(sIType == "Level_Drain" && GetIsImmune(oCreature, IMMUNITY_TYPE_NEGATIVE_LEVEL)) return TRUE;
|
||||
else if(sIType == "Ability_Drain" && GetIsImmune(oCreature, IMMUNITY_TYPE_ABILITY_DECREASE)) return TRUE;
|
||||
else if(sIType == "Poison" && GetIsImmune(oCreature, IMMUNITY_TYPE_POISON)) return TRUE;
|
||||
else if(sIType == "Disease" && GetIsImmune(oCreature, IMMUNITY_TYPE_DISEASE)) return TRUE;
|
||||
else if(sIType == "Curse" && GetIsImmune(oCreature, IMMUNITY_TYPE_CURSED)) return TRUE;
|
||||
else if(sIType == "Mind_Affecting" && GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS)) return TRUE;
|
||||
else if(sIType == "Petrification" && ai_IsImmuneToPetrification(oCaster, oCreature)) return TRUE;
|
||||
else if(sIType == "Mind_Affecting" &&
|
||||
(GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
|
||||
else if(sIType == "Petrification" &&
|
||||
(ai_IsImmuneToPetrification(oCaster, oCreature) && nDisabled)) return TRUE;
|
||||
else if(sIType == "Fear" &&
|
||||
(GetIsImmune(oCreature, IMMUNITY_TYPE_FEAR) ||
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
|
||||
else if(sIType == "Sleep" &&
|
||||
(GetIsImmune(oCreature, IMMUNITY_TYPE_SLEEP) ||
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
|
||||
else if(sIType == "Paralysis" &&
|
||||
(GetIsImmune(oCreature, IMMUNITY_TYPE_PARALYSIS) ||
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
|
||||
else if(sIType == "Domination" &&
|
||||
(GetIsImmune(oCreature, IMMUNITY_TYPE_DOMINATE) ||
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
|
||||
else if(sIType == "Confusion" &&
|
||||
(GetIsImmune(oCreature, IMMUNITY_TYPE_CONFUSED) ||
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
|
||||
else if(sIType == "Blindness" &&
|
||||
(GetIsImmune(oCreature, IMMUNITY_TYPE_BLINDNESS) ||
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || ai_GetHasEffectType(oCreature, EFFECT_TYPE_BLINDNESS))) return TRUE;
|
||||
else if(sIType == "Dazed" &&
|
||||
(GetIsImmune(oCreature, IMMUNITY_TYPE_DAZED) ||
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
|
||||
else if(sIType == "Charm" &&
|
||||
(GetIsImmune(oCreature, IMMUNITY_TYPE_CHARM) ||
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS))) return TRUE;
|
||||
GetIsImmune(oCreature, IMMUNITY_TYPE_MIND_SPELLS) || nDisabled)) return TRUE;
|
||||
// Check for damage immunities.
|
||||
// Negative damage does not work on undead!
|
||||
else if(sIType == "Negative" && GetRacialType(oCreature) == RACIAL_TYPE_UNDEAD)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "325", "Undead are immune to Negative energy!");
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "538", "Undead are immune to Negative energy!");
|
||||
return TRUE;
|
||||
}
|
||||
else if(sIType == "Poison" && ai_GetHasEffectType(oCreature, EFFECT_TYPE_POISON)) return TRUE;
|
||||
else if(sIType == "Disease" && ai_GetHasEffectType(oCreature, EFFECT_TYPE_DISEASE)) return TRUE;
|
||||
// Elemental damage resistances should be checked.
|
||||
if(sIType == "Acid" || sIType == "Cold" || sIType == "Fire" ||
|
||||
sIType == "Electricty" || sIType == "Sonic")
|
||||
{
|
||||
if(ai_GetHasEffectType(oCreature, EFFECT_TYPE_DAMAGE_RESISTANCE))
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "334", GetName(oCreature) + " has damage resistance to my " + sIType + " spell!");
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "547", GetName(oCreature) + " has damage resistance to my " + sIType + " spell!");
|
||||
return TRUE;
|
||||
}
|
||||
// Check for resistances and immunities. Treat resistance as immune.
|
||||
int nIPResist = GetLocalInt(oCreature, sIPResistVarname);
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "372", "nIPResist:" + IntToString(nIPResist));
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "552", "nIPResist:" + IntToString(nIPResist));
|
||||
int nIPImmune = GetLocalInt(oCreature, sIPImmuneVarname) | nIPResist;
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "374", "nIPImmune:" + IntToString(nIPImmune));
|
||||
if(nIPImmune > 0)
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "554", "nIPImmune:" + IntToString(nIPImmune));
|
||||
int bImmune;
|
||||
if(nIPImmune > 0) {
|
||||
|
||||
if(sIType == "Acid" && (nIPImmune & DAMAGE_TYPE_ACID)) bImmune = TRUE;
|
||||
else if(sIType == "Cold" && (nIPImmune & DAMAGE_TYPE_COLD)) bImmune = TRUE;
|
||||
else if(sIType == "Fire" && (nIPImmune & DAMAGE_TYPE_FIRE)) bImmune = TRUE;
|
||||
else if(sIType == "Electricity" && (nIPImmune & DAMAGE_TYPE_ELECTRICAL)) bImmune = TRUE;
|
||||
else if(sIType == "Sonic" && (nIPImmune & DAMAGE_TYPE_SONIC)) bImmune = TRUE;
|
||||
}
|
||||
if(bImmune)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "391", GetName(oCreature) + " is immune/resistant to my " + sIType + " spell through an item!");
|
||||
if(sIType == "Acid" && (nIPImmune & DAMAGE_TYPE_ACID)) return TRUE;
|
||||
else if(sIType == "Cold" && (nIPImmune & DAMAGE_TYPE_COLD)) return TRUE;
|
||||
else if(sIType == "Fire" && (nIPImmune & DAMAGE_TYPE_FIRE)) return TRUE;
|
||||
else if(sIType == "Electricity" && (nIPImmune & DAMAGE_TYPE_ELECTRICAL)) return TRUE;
|
||||
else if(sIType == "Sonic" && (nIPImmune & DAMAGE_TYPE_SONIC)) return TRUE;
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "567", GetName(oCreature) + " is immune/resistant to my " + sIType + " spell through an item!");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
// Lets also check undead and constructs vs mind spells.
|
||||
int nRace = GetRacialType(oCreature);
|
||||
int nClass = GetClassByPosition(1, oCreature);
|
||||
if(nRace == RACIAL_TYPE_UNDEAD || nRace == RACIAL_TYPE_CONSTRUCT ||
|
||||
nClass == CLASS_TYPE_UNDEAD || nClass == CLASS_TYPE_CONSTRUCT)
|
||||
{
|
||||
if(sIType == "Mind_Affecting" || sIType == "Fear" || sIType == "Sleep" ||
|
||||
sIType == "Confusion" || sIType == "Blindness" || sIType == "Daze" ||
|
||||
sIType == "Poison" || sIType == "Disease" || sIType == "Charm")
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "595", GetName(oCreature) + " is immune/resistant to my " + sIType + " spell because they are Undead or a Construct!");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -479,12 +612,12 @@ int ai_CreatureImmuneToEffect(object oCaster, object oCreature, int nSpell)
|
||||
{
|
||||
if(nSpell == JsonGetInt(jSpell))
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "407", GetName(oCreature) + " is immune to the spell via an Item!");
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "581", GetName(oCreature) + " is immune to the spell via an Item!");
|
||||
return TRUE;
|
||||
}
|
||||
jSpell = JsonArrayGet(jSpellImmunity, ++nIndex);
|
||||
}
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "347", GetName(oCreature) + " is not immune to the spell.");
|
||||
if(AI_DEBUG) ai_Debug("0i_spell", "586", GetName(oCreature) + " is not immune to the spell.");
|
||||
return FALSE;
|
||||
}
|
||||
float ai_GetSpellRange(int nSpell)
|
||||
@@ -651,9 +784,9 @@ int ai_IsSilenced(object oCreature, int nSpell)
|
||||
}
|
||||
int ai_ArcaneSpellFailureTooHigh(object oCreature, int nClass, int nLevel, int nSlot)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "561", "Arcane Spells: " + Get2DAString("classes", "ASF", nClass) +
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "746", "Arcane Spells: " + Get2DAString("classes", "ASF", nClass) +
|
||||
" Arcane Spell Failure: " + IntToString(GetArcaneSpellFailure(oCreature)) +
|
||||
" AI_ASF_WILL_USE: " + IntToString(AI_ASF_WILL_USE));
|
||||
" > " + IntToString(AI_ASF_WILL_USE) + " skip.");
|
||||
if(Get2DAString("classes", "ASF", nClass) == "1" &&
|
||||
GetArcaneSpellFailure(oCreature) > AI_ASF_WILL_USE)
|
||||
{
|
||||
@@ -1181,7 +1314,7 @@ int ai_CheckAndCastSpell(object oCaster, int nSpell, int nSpellGroup, float fDel
|
||||
// Search all memorized spells for the spell.
|
||||
if(Get2DAString("classes", "MemorizesSpells", nClass) == "1")
|
||||
{
|
||||
// Check each level starting with the highest to lowest.
|
||||
// Check each level starting with the lowest to the highest.
|
||||
nSpellLevel = 0;
|
||||
while(nSpellLevel < 10)
|
||||
{
|
||||
@@ -1193,6 +1326,8 @@ int ai_CheckAndCastSpell(object oCaster, int nSpell, int nSpellGroup, float fDel
|
||||
if(GetMemorizedSpellReady(oCaster, nClass, nSpellLevel, nSpellSlot))
|
||||
{
|
||||
nMemorizedSpell = GetMemorizedSpellId(oCaster, nClass, nSpellLevel, nSpellSlot);
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "1326", "nMemorizedSpell: " + IntToString(nMemorizedSpell) +
|
||||
" nSpell: " + IntToString(nSpell));
|
||||
if(nMemorizedSpell == nSpell)
|
||||
{
|
||||
ai_CastMemorizedSpell(oCaster, nClass, nSpellLevel, nSpellSlot, oTarget, FALSE, oPC);
|
||||
@@ -1431,7 +1566,7 @@ void ai_CheckForPerDayItems(object oCreature, object oPC, int nBuffType)
|
||||
nCntr++;
|
||||
}
|
||||
}
|
||||
void ai_CheckForBuffSpells(struct stSpell stSpell)
|
||||
void ai_CheckForBuffSpells(struct stSpell stSpell, float fDelay, int bInstantSpell)
|
||||
{
|
||||
ai_SetupAllyTargets(stSpell.oCaster, stSpell.oPC);
|
||||
stSpell.nPosition = 1;
|
||||
@@ -1452,13 +1587,13 @@ void ai_CheckForBuffSpells(struct stSpell stSpell)
|
||||
if(Get2DAString("classes", "MemorizesSpells", stSpell.nClass) == "1")
|
||||
{
|
||||
stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell));
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell, fDelay, bInstantSpell));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell));
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell, fDelay, bInstantSpell));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1466,7 +1601,7 @@ void ai_CheckForBuffSpells(struct stSpell stSpell)
|
||||
}
|
||||
ai_CheckForPerDayItems(stSpell.oCaster, stSpell.oPC, stSpell.nBuffType);
|
||||
}
|
||||
void ai_ActionCastMemorizedSummons(struct stSpell stSpell)
|
||||
void ai_ActionCastMemorizedSummons(struct stSpell stSpell, float fDelay, int bInstantSpell)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "1122", "Start of ActionCastMemorizedSummons!");
|
||||
int nSpell;
|
||||
@@ -1492,14 +1627,14 @@ void ai_ActionCastMemorizedSummons(struct stSpell stSpell)
|
||||
if(Get2DAString("ai_spells", "Category", nSpell) == "S")
|
||||
{
|
||||
SetLocalInt(stSpell.oCaster, "AI_USED_SPELL_GROUP_-2", TRUE);
|
||||
ai_CastMemorizedSpell(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot, stSpell.oCaster, TRUE, stSpell.oPC);
|
||||
ai_CastMemorizedSpell(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot, stSpell.oCaster, bInstantSpell, stSpell.oPC);
|
||||
stSpell.nPosition = 1;
|
||||
stSpell.nClass = GetClassByPosition(stSpell.nPosition, stSpell.oCaster);
|
||||
stSpell.nLevel = (GetLevelByPosition(stSpell.nPosition, stSpell.oCaster) + 1) / 2;
|
||||
stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
stSpell.nSlot = 0;
|
||||
DelayCommand(2.0, ai_SetupAllyTargets(stSpell.oCaster, stSpell.oPC));
|
||||
DelayCommand(2.0 + 0.5, AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell)));
|
||||
DelayCommand(2.0 + 0.5, AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell, fDelay, bInstantSpell)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1529,14 +1664,14 @@ void ai_ActionCastMemorizedSummons(struct stSpell stSpell)
|
||||
else
|
||||
{
|
||||
stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell));
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell, fDelay, bInstantSpell));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ai_CheckForBuffSpells(stSpell);
|
||||
ai_CheckForBuffSpells(stSpell, fDelay, bInstantSpell);
|
||||
}
|
||||
void ai_ActionCastKnownSummons(struct stSpell stSpell)
|
||||
void ai_ActionCastKnownSummons(struct stSpell stSpell, float fDelay, int bInstantSpell)
|
||||
{
|
||||
//ai_Debug("0i_spells", "1184", "Start of ActionCastKnownSummons!");
|
||||
int nSpell;
|
||||
@@ -1564,14 +1699,14 @@ void ai_ActionCastKnownSummons(struct stSpell stSpell)
|
||||
{
|
||||
SetLocalInt(stSpell.oCaster, "AI_USED_SPELL_GROUP_S", TRUE);
|
||||
//ai_Debug("0i_spells", "1209", "nSpell: " + IntToString(nSpell));
|
||||
ai_CastKnownSpell(stSpell.oCaster, stSpell.nClass, nSpell, stSpell.oCaster, TRUE, stSpell.oPC);
|
||||
ai_CastKnownSpell(stSpell.oCaster, stSpell.nClass, nSpell, stSpell.oCaster, bInstantSpell, stSpell.oPC);
|
||||
stSpell.nPosition = 1;
|
||||
stSpell.nClass = GetClassByPosition(stSpell.nPosition, stSpell.oCaster);
|
||||
stSpell.nLevel = (GetLevelByPosition(stSpell.nPosition, stSpell.oCaster) + 1) / 2;
|
||||
stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
stSpell.nSlot = 0;
|
||||
ai_SetupAllyTargets(stSpell.oCaster, stSpell.oPC);
|
||||
DelayCommand(AI_HENCHMAN_BUFF_DELAY, AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell)));
|
||||
DelayCommand(fDelay, AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell, fDelay, bInstantSpell)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1598,15 +1733,15 @@ void ai_ActionCastKnownSummons(struct stSpell stSpell)
|
||||
if(Get2DAString("classes", "MemorizesSpells", stSpell.nClass) == "1")
|
||||
{
|
||||
stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell));
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell, fDelay, bInstantSpell));
|
||||
return;
|
||||
}
|
||||
else stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
}
|
||||
}
|
||||
ai_CheckForBuffSpells(stSpell);
|
||||
ai_CheckForBuffSpells(stSpell, fDelay, bInstantSpell);
|
||||
}
|
||||
void ai_ActionCastMemorizedBuff(struct stSpell stSpell)
|
||||
void ai_ActionCastMemorizedBuff(struct stSpell stSpell, float fDelay, int bInstantSpell)
|
||||
{
|
||||
int nSpell;
|
||||
string sBuffGroup, sBuffTarget;
|
||||
@@ -1649,9 +1784,9 @@ void ai_ActionCastMemorizedBuff(struct stSpell stSpell)
|
||||
" oTarget: " + GetName(oTarget));
|
||||
if(oTarget != OBJECT_INVALID)
|
||||
{
|
||||
ai_CastMemorizedSpell(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot, oTarget, TRUE, stSpell.oPC);
|
||||
ai_CastMemorizedSpell(stSpell.oCaster, stSpell.nClass, stSpell.nLevel, stSpell.nSlot, oTarget, bInstantSpell, stSpell.oPC);
|
||||
stSpell.nSlot++;
|
||||
DelayCommand(AI_HENCHMAN_BUFF_DELAY, AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell)));
|
||||
DelayCommand(fDelay, AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell, fDelay, bInstantSpell)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1682,14 +1817,14 @@ void ai_ActionCastMemorizedBuff(struct stSpell stSpell)
|
||||
else
|
||||
{
|
||||
stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell));
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell, fDelay, bInstantSpell));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ai_CheckForPerDayItems(stSpell.oCaster, stSpell.oPC, stSpell.nBuffType);
|
||||
}
|
||||
void ai_ActionCastKnownBuff(struct stSpell stSpell)
|
||||
void ai_ActionCastKnownBuff(struct stSpell stSpell, float fDelay, int bInstantSpell)
|
||||
{
|
||||
int nSpell;
|
||||
string sBuffGroup, sBuffTarget;
|
||||
@@ -1734,9 +1869,9 @@ void ai_ActionCastKnownBuff(struct stSpell stSpell)
|
||||
// " oTarget: " + GetName(oTarget));
|
||||
if(oTarget != OBJECT_INVALID)
|
||||
{
|
||||
ai_CastKnownSpell(stSpell.oCaster, stSpell.nClass, nSpell, oTarget, TRUE, stSpell.oPC);
|
||||
ai_CastKnownSpell(stSpell.oCaster, stSpell.nClass, nSpell, oTarget, bInstantSpell, stSpell.oPC);
|
||||
stSpell.nSlot++;
|
||||
DelayCommand(AI_HENCHMAN_BUFF_DELAY, AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell)));
|
||||
DelayCommand(fDelay, AssignCommand(stSpell.oCaster, ai_ActionCastKnownBuff(stSpell, fDelay, bInstantSpell)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1764,7 +1899,7 @@ void ai_ActionCastKnownBuff(struct stSpell stSpell)
|
||||
if(Get2DAString("classes", "MemorizesSpells", stSpell.nClass) == "1")
|
||||
{
|
||||
stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell));
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedBuff(stSpell, fDelay, bInstantSpell));
|
||||
return;
|
||||
}
|
||||
else stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
@@ -1786,8 +1921,12 @@ void ai_CastBuffs(object oCaster, int nBuffType, int nTarget, object oPC)
|
||||
stSpell.nBuffType = nBuffType;
|
||||
stSpell.nTarget = nTarget;
|
||||
stSpell.nPosition = 1;
|
||||
float fDelay = GetLocalFloat(stSpell.oCaster, AI_DELAY_BUFF_CASTING);
|
||||
int bInstantSpell;
|
||||
if(fDelay < 4.9) bInstantSpell = TRUE;
|
||||
else fDelay = 6.0;
|
||||
// Look for summons spells on All, Long durations and the whole party.
|
||||
if((nBuffType == 1 || nBuffType == 3) && nTarget == 0)
|
||||
if((nBuffType == 1 || nBuffType == 3) && nTarget == 0 && GetAssociate(ASSOCIATE_TYPE_SUMMONED, oCaster) == OBJECT_INVALID)
|
||||
{
|
||||
while(stSpell.nPosition <= AI_MAX_CLASSES_PER_CHARACTER)
|
||||
{
|
||||
@@ -1802,13 +1941,13 @@ void ai_CastBuffs(object oCaster, int nBuffType, int nTarget, object oPC)
|
||||
if(Get2DAString("classes", "MemorizesSpells", stSpell.nClass) == "1")
|
||||
{
|
||||
stSpell.nMaxSlots = GetMemorizedSpellCountByLevel(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedSummons(stSpell));
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastMemorizedSummons(stSpell, fDelay, bInstantSpell));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
stSpell.nMaxSlots = GetKnownSpellCount(stSpell.oCaster, stSpell.nClass, stSpell.nLevel);
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastKnownSummons(stSpell));
|
||||
AssignCommand(stSpell.oCaster, ai_ActionCastKnownSummons(stSpell, fDelay, bInstantSpell));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1817,7 +1956,7 @@ void ai_CastBuffs(object oCaster, int nBuffType, int nTarget, object oPC)
|
||||
// Exit here; if we summoned a monster then it linked off of that spell
|
||||
// cast to continue the action queue for all buff spell cast actions.
|
||||
}
|
||||
ai_CheckForBuffSpells(stSpell);
|
||||
ai_CheckForBuffSpells(stSpell, fDelay, bInstantSpell);
|
||||
}
|
||||
int ai_CastSpontaneousCure(object oCreature, object oTarget, object oPC)
|
||||
{
|
||||
@@ -1883,6 +2022,98 @@ int ai_CastSpontaneousCure(object oCreature, object oTarget, object oPC)
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
int ai_CastMemorizedInflict(object oCreature, object oTarget, object oPC, int nClass)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "1993", GetName(oCreature) + " is looking to cast a memorized inflict spell.");
|
||||
int nDamage = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget);
|
||||
int nSpell, nSlot, nMaxSlots, nLevel = 9;
|
||||
int nClassSave, nSlotSave, nLevelSave = 10;
|
||||
while(nLevel > -1)
|
||||
{
|
||||
nMaxSlots = GetMemorizedSpellCountByLevel(oCreature, nClass, nLevel);
|
||||
nSlot = 0;
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "2001", "nLevel: " + IntToString(nLevel) + " nMaxSlots: " + IntToString(nMaxSlots));
|
||||
while(nSlot < nMaxSlots)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "2004", "nSlot: " + IntToString(nSlot) +
|
||||
" Spell Ready: " + IntToString(GetMemorizedSpellReady(oCreature, nClass, nLevel, nSlot)));
|
||||
if(GetMemorizedSpellReady(oCreature, nClass, nLevel, nSlot))
|
||||
{
|
||||
nSpell = GetMemorizedSpellId(oCreature, nClass, nLevel, nSlot);
|
||||
if(ai_ShouldWeCastThisInflictSpell(nSpell, nDamage))
|
||||
{
|
||||
string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "2012", GetName(oCreature) + " has cast " + sSpellName + " on " + GetName(oTarget) + ".");
|
||||
ai_CastMemorizedSpell(oCreature, nClass, nLevel, nSlot, oTarget, FALSE, oPC);
|
||||
return TRUE;
|
||||
}
|
||||
// Save the lowest level inflict spell as we might need to cast it.
|
||||
else if(nLevel < nLevelSave && (nSpell > 430 && nSpell < 436))
|
||||
{
|
||||
nClassSave = nClass;
|
||||
nLevelSave = nLevel;
|
||||
nSlotSave = nSlot;
|
||||
}
|
||||
}
|
||||
nSlot++;
|
||||
}
|
||||
nLevel--;
|
||||
}
|
||||
// Did we find a cure spell? If we did then use it.
|
||||
if(nLevelSave < 10)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "1740", GetName(oCreature) + " has cast the lowest level cure spell on " + GetName(oTarget) + ".");
|
||||
ai_CastMemorizedSpell(oCreature, nClassSave, nLevelSave, nSlotSave, oTarget, FALSE, oPC);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
int ai_CastKnownInflict(object oCreature, object oTarget, object oPC, int nClass)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "2041", GetName(oCreature) + " is looking to cast a known inflict spell.");
|
||||
int nDamage = GetMaxHitPoints(oTarget) - GetCurrentHitPoints(oTarget);
|
||||
int nSpell, nSlot, nMaxSlots, nLevel = 9;
|
||||
int nClassSave, nSpellSave, nLevelSave = 10;
|
||||
while(nLevel > -1)
|
||||
{
|
||||
nMaxSlots = GetKnownSpellCount(oCreature, nClass, nLevel);
|
||||
nSlot = 0;
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "2049", "nLevel: " + IntToString(nLevel) + " nMaxSlots: " + IntToString(nMaxSlots));
|
||||
while(nSlot < nMaxSlots)
|
||||
{
|
||||
nSpell = GetKnownSpellId(oCreature, nClass, nLevel, nSlot);
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "2053", "nSlot: " + IntToString(nSlot) +
|
||||
" Spell Ready: " + IntToString(GetSpellUsesLeft(oCreature, nClass, nSpell)));
|
||||
if(GetSpellUsesLeft(oCreature, nClass, nSpell))
|
||||
{
|
||||
if(ai_ShouldWeCastThisInflictSpell(nSpell, nDamage))
|
||||
{
|
||||
string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpell)));
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "2060", GetName(oCreature) + " has cast " + sSpellName + " on " + GetName(oTarget) + ".");
|
||||
ai_CastKnownSpell(oCreature, nClass, nSpell, oTarget, FALSE, oPC);
|
||||
return TRUE;
|
||||
}
|
||||
// Save the lowest level cure spell as we might need to cast it.
|
||||
else if(nLevel < nLevelSave && (nSpell > 430 && nSpell < 436))
|
||||
{
|
||||
nClassSave = nClass;
|
||||
nLevelSave = nLevel;
|
||||
nSpellSave = nSpell;
|
||||
}
|
||||
}
|
||||
nSlot++;
|
||||
}
|
||||
nLevel--;
|
||||
}
|
||||
return FALSE;
|
||||
// Did we find a cure spell? If we did then use it.
|
||||
if(nLevelSave < 10)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "1781", GetName(oCreature) + " has cast the lowest level cure spell on " + GetName(oTarget) + ".");
|
||||
ai_CastKnownSpell(oCreature, nClassSave, nSpellSave, oTarget, FALSE, oPC);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
int ai_CastMemorizedHealing(object oCreature, object oTarget, object oPC, int nClass)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "1702", GetName(oCreature) + " is looking to cast a memorized cure spell.");
|
||||
@@ -1909,7 +2140,7 @@ int ai_CastMemorizedHealing(object oCreature, object oTarget, object oPC, int nC
|
||||
return TRUE;
|
||||
}
|
||||
// Save the lowest level cure spell as we might need to cast it.
|
||||
else if(nLevel < nLevelSave && (nSpell > 26 && nSpell < 32))
|
||||
else if(nLevel < nLevelSave && (nSpell > 30 && nSpell < 36))
|
||||
{
|
||||
nClassSave = nClass;
|
||||
nLevelSave = nLevel;
|
||||
@@ -1955,7 +2186,7 @@ int ai_CastKnownHealing(object oCreature, object oTarget, object oPC, int nClass
|
||||
return TRUE;
|
||||
}
|
||||
// Save the lowest level cure spell as we might need to cast it.
|
||||
else if(nLevel < nLevelSave && (nSpell > 26 && nSpell < 32))
|
||||
else if(nLevel < nLevelSave && (nSpell > 30 && nSpell < 36))
|
||||
{
|
||||
nClassSave = nClass;
|
||||
nLevelSave = nLevel;
|
||||
@@ -2074,7 +2305,7 @@ float ai_GetOffensiveSpellSearchRange(object oCreature, int nSpell)
|
||||
// We check this because if the enemy is moving or has not started acting
|
||||
// then we don't want to move up on them as they might move towards us!
|
||||
int nAction = GetCurrentAction(oNearestEnemy);
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "1130", GetName(oNearestEnemy) + " current action: " + IntToString(nAction));
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "2228", GetName(oNearestEnemy) + " current action: " + IntToString(nAction));
|
||||
if(nAction != ACTION_MOVETOPOINT || nAction != ACTION_ITEMCASTSPELL ||
|
||||
nAction != ACTION_INVALID || nAction != ACTION_USEOBJECT ||
|
||||
nAction != ACTION_RANDOMWALK) fRange = fEnemyDistance + (fRange - 7.5);
|
||||
@@ -2083,6 +2314,18 @@ float ai_GetOffensiveSpellSearchRange(object oCreature, int nSpell)
|
||||
else if(fRange < 0.1f) return 0.1f;
|
||||
return fRange;
|
||||
}
|
||||
int ai_ShouldWeCastThisInflictSpell(int nSpell, int nDamage)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "2239", "nSpell: " + IntToString(nSpell) + " nDamage: " +
|
||||
IntToString(nDamage));
|
||||
if(nSpell == SPELL_HEAL && nDamage > 50) return TRUE;
|
||||
else if(nSpell == SPELL_INFLICT_CRITICAL_WOUNDS && nDamage > 31) return TRUE;
|
||||
else if(nSpell == SPELL_INFLICT_SERIOUS_WOUNDS && nDamage > 23) return TRUE;
|
||||
else if(nSpell == SPELL_INFLICT_MODERATE_WOUNDS && nDamage > 15) return TRUE;
|
||||
else if(nSpell == SPELL_INFLICT_LIGHT_WOUNDS && nDamage > 6) return TRUE;
|
||||
else if(nSpell == SPELL_INFLICT_MINOR_WOUNDS) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
int ai_ShouldWeCastThisCureSpell(int nSpell, int nDamage)
|
||||
{
|
||||
if(AI_DEBUG) ai_Debug("0i_spells", "1127", "nSpell: " + IntToString(nSpell) + " nDamage: " +
|
||||
@@ -2112,7 +2355,7 @@ void ai_CastWidgetSpell(object oPC, object oAssociate, object oTarget, location
|
||||
// " oTarget: " + GetName(oTarget) +
|
||||
// " nMetaMagic: " + IntToString(nMetaMagic) +
|
||||
// " nDomain: " + IntToString(nDomain));
|
||||
if(GetCurrentAction(oAssociate) != ACTION_CASTSPELL) AssignCommand(oAssociate, ai_ClearCreatureActions(TRUE));
|
||||
if(GetCurrentAction(oAssociate) != ACTION_CASTSPELL) AssignCommand(oAssociate, ai_ClearCreatureActions(FALSE));
|
||||
if(!GetIsObjectValid(oTarget))
|
||||
{
|
||||
AssignCommand(oAssociate, ActionCastSpellAtLocation(nSpell, lLocation, nMetaMagic, FALSE, 0, FALSE, -1, FALSE, nDomain));
|
||||
@@ -2134,7 +2377,7 @@ void ai_UseWidgetFeat(object oPC, object oAssociate, object oTarget, location lL
|
||||
// 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));
|
||||
if(ai_GetIsInCombat(oAssociate)) AssignCommand(oAssociate, ai_ClearCreatureActions(FALSE));
|
||||
//SendMessageToPC(oPC, "0i_spells, 2104, nFeat: " + IntToString(nFeat) + " oTarget: " + GetName(oTarget));
|
||||
if(!GetIsObjectValid(oTarget))
|
||||
{
|
||||
@@ -2155,7 +2398,7 @@ void ai_UseWidgetItem(object oPC, object oAssociate, object oTarget, location lL
|
||||
int nIprpSubType = JsonGetInt(JsonArrayGet(jItem, 4));
|
||||
object oItem = GetObjectByUUID(JsonGetString(JsonArrayGet(jItem, 5)));
|
||||
itemproperty ipProperty;
|
||||
if(ai_GetIsInCombat(oAssociate)) AssignCommand(oAssociate, ai_ClearCreatureActions(TRUE));
|
||||
if(ai_GetIsInCombat(oAssociate)) AssignCommand(oAssociate, ai_ClearCreatureActions(FALSE));
|
||||
if(nSpell == SPELL_HEALINGKIT)
|
||||
{
|
||||
ipProperty = GetFirstItemProperty(oItem);
|
||||
@@ -2172,9 +2415,9 @@ void ai_UseWidgetItem(object oPC, object oAssociate, object oTarget, location lL
|
||||
if(nIprpSubType == GetItemPropertySubType(ipProperty)) break;
|
||||
ipProperty = GetNextItemProperty(oItem);
|
||||
}
|
||||
if(!GetIsObjectValid(oTarget))
|
||||
if(GetIsObjectValid(oTarget))
|
||||
{
|
||||
AssignCommand(oAssociate, ActionUseItemAtLocation(oItem, ipProperty, lLocation));
|
||||
AssignCommand(oAssociate, ActionUseItemOnObject(oItem, ipProperty, oTarget));
|
||||
}
|
||||
else AssignCommand(oAssociate, ActionUseItemOnObject(oItem, ipProperty, oTarget));
|
||||
else AssignCommand(oAssociate, ActionUseItemAtLocation(oItem, ipProperty, lLocation));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user