280 lines
11 KiB
Plaintext
280 lines
11 KiB
Plaintext
#include "hench_i0_ai"
|
|
#include "quest_inc"
|
|
#include "nw_i0_plot"
|
|
|
|
void CastInitialBuffs()
|
|
{
|
|
int nLevel = GetHitDice(OBJECT_SELF);
|
|
ClearAllActions();
|
|
|
|
//mage buffs
|
|
if (GetLevelByClass(CLASS_TYPE_WIZARD, OBJECT_SELF) != 0)
|
|
{
|
|
if (nLevel <= 2)
|
|
{
|
|
ActionCastSpellAtObject(SPELL_MAGE_ARMOR, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
}
|
|
else if (nLevel <= 4)
|
|
{
|
|
ActionCastSpellAtObject(SPELL_MAGE_ARMOR, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
ActionCastSpellAtObject(SPELL_DEATH_ARMOR, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
}
|
|
else if (nLevel <= 6)
|
|
{
|
|
ActionCastSpellAtObject(SPELL_MAGE_ARMOR, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
ActionCastSpellAtObject(SPELL_DEATH_ARMOR, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
ActionCastSpellAtObject(SPELL_DISPLACEMENT, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
}
|
|
else if (nLevel <= 8)
|
|
{
|
|
ActionCastSpellAtObject(SPELL_MAGE_ARMOR, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
ActionCastSpellAtObject(SPELL_ELEMENTAL_SHIELD, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
ActionCastSpellAtObject(SPELL_IMPROVED_INVISIBILITY, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
}
|
|
else
|
|
{
|
|
ActionCastSpellAtObject(SPELL_MAGE_ARMOR, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
ActionCastSpellAtObject(SPELL_MESTILS_ACID_SHEATH, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
ActionCastSpellAtObject(SPELL_IMPROVED_INVISIBILITY, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
}
|
|
}
|
|
|
|
//cleric buffs
|
|
if (GetLevelByClass(CLASS_TYPE_CLERIC, OBJECT_SELF) != 0)
|
|
{
|
|
if (nLevel <= 2)
|
|
{
|
|
ActionCastSpellAtObject(SPELL_ENDURE_ELEMENTS, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
ActionCastSpellAtObject(SPELL_SHIELD_OF_FAITH, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
}
|
|
else if (nLevel <= 4)
|
|
{
|
|
ActionCastSpellAtObject(SPELL_RESIST_ELEMENTS, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
ActionCastSpellAtObject(SPELL_SHIELD_OF_FAITH, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
}
|
|
else if (nLevel <= 8)
|
|
{
|
|
ActionCastSpellAtObject(SPELL_PROTECTION_FROM_ELEMENTS, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
ActionCastSpellAtObject(SPELL_PRAYER, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
}
|
|
else
|
|
{
|
|
ActionCastSpellAtObject(SPELL_PROTECTION_FROM_ELEMENTS, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
ActionCastSpellAtObject(SPELL_BATTLETIDE, OBJECT_SELF, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
|
|
}
|
|
}
|
|
|
|
DelayCommand(0.5, ActionDoCommand(HenchDetermineCombatRound()));
|
|
}
|
|
|
|
void StartConversation(object oSpeaker, string sConversation)
|
|
{
|
|
ActionStartConversation(oSpeaker, sConversation, FALSE, FALSE);
|
|
}
|
|
|
|
int InitiativeCheck()
|
|
{
|
|
object oPC = GetPCSpeaker();
|
|
|
|
int nBonus = 0;
|
|
if (GetHasFeat(FEAT_BLOODED, oPC)) nBonus = nBonus + 2;
|
|
if (GetHasFeat(FEAT_THUG, oPC)) nBonus = nBonus + 2;
|
|
if (GetHasFeat(FEAT_IMPROVED_INITIATIVE, oPC)) nBonus = nBonus + 4;
|
|
if (GetHasFeat(FEAT_EPIC_SUPERIOR_INITIATIVE, oPC)) nBonus = nBonus + 4;
|
|
|
|
if (d20() + nBonus >= 12) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
void main()
|
|
{
|
|
object oPC = GetPCSpeaker();
|
|
string sDB = CharacterDB(oPC);
|
|
|
|
//Just a precaution not to have it accidentally launched multiple times
|
|
if (GetLocalInt(OBJECT_SELF, "ConvCancel") == TRUE) return;
|
|
else
|
|
{
|
|
SetLocalInt(OBJECT_SELF, "ConvCancel", TRUE);
|
|
DelayCommand(0.5, DeleteLocalInt(OBJECT_SELF, "ConvCancel"));
|
|
}
|
|
|
|
//If the NPC is an adventurer that wants to kill us
|
|
if (GetLocalInt(OBJECT_SELF, "Adventurer") == TRUE && GetLocalInt(OBJECT_SELF, "WillAttack") == 1)
|
|
{
|
|
SetIsTemporaryEnemy(oPC, OBJECT_SELF);
|
|
SetPlotFlag(OBJECT_SELF, FALSE);
|
|
CastInitialBuffs();
|
|
//HenchDetermineCombatRound();
|
|
}
|
|
|
|
//If the NPC is a nemesis
|
|
if (GetLocalInt(OBJECT_SELF, "Nemesis") == TRUE)
|
|
{
|
|
effect eEffect = GetFirstEffect(oPC);
|
|
while (GetIsEffectValid(eEffect))
|
|
{
|
|
if (GetEffectCreator(eEffect) == OBJECT_SELF) RemoveEffect(oPC, eEffect);
|
|
eEffect = GetNextEffect(oPC);
|
|
}
|
|
|
|
SetIsTemporaryEnemy(oPC, OBJECT_SELF);
|
|
SetPlotFlag(OBJECT_SELF, FALSE);
|
|
if (Random(2) == 0) SetLocalInt(OBJECT_SELF, "WillRun", TRUE);
|
|
CastInitialBuffs();
|
|
//HenchDetermineCombatRound();
|
|
}
|
|
|
|
//If the quest target is successfully kidnapped and is going to be escorted by hirelings
|
|
object oEscort;
|
|
if (GetLocalInt(OBJECT_SELF, "KidnapTarget") == TRUE && GetLocalInt(OBJECT_SELF, "Kidnapped") == TRUE)
|
|
{
|
|
AddRandomQuestJournalEntry(oPC, 2);
|
|
|
|
oEscort = CreateObject(OBJECT_TYPE_CREATURE, "anc_kidnap_escor", GetLocation(OBJECT_SELF), FALSE);
|
|
AssignCommand(oEscort, ClearAllActions());
|
|
AssignCommand(oEscort, StartConversation(oPC, "hireling"));
|
|
AssignCommand(oEscort, EscapeArea(FALSE));
|
|
DelayCommand(25.0, DestroyObject(oEscort));
|
|
//SetCommandable(FALSE, oEscort);
|
|
|
|
oEscort = CreateObject(OBJECT_TYPE_CREATURE, "anc_kidnap_escor", GetLocation(OBJECT_SELF), FALSE);
|
|
AssignCommand(oEscort, ClearAllActions());
|
|
AssignCommand(oEscort, EscapeArea(FALSE));
|
|
DelayCommand(25.0, DestroyObject(oEscort));
|
|
//SetCommandable(FALSE, oEscort);
|
|
|
|
AssignCommand(OBJECT_SELF, ClearAllActions());
|
|
AssignCommand(OBJECT_SELF, EscapeArea(FALSE));
|
|
DelayCommand(25.0, DestroyObject(OBJECT_SELF));
|
|
//SetCommandable(FALSE, OBJECT_SELF);
|
|
}
|
|
|
|
//If the quest target is going to attack
|
|
if (GetLocalInt(OBJECT_SELF, "Quest_Attack") == TRUE)
|
|
{
|
|
if (GetLocalInt(OBJECT_SELF, "Kidnapper") == TRUE)
|
|
{
|
|
//Find the kidnapped NPC
|
|
object oKidnapped = GetFirstObjectInArea(GetArea(OBJECT_SELF));
|
|
while (oKidnapped != OBJECT_INVALID)
|
|
{
|
|
if (GetLocalInt(oKidnapped, "RansomQuest") == TRUE) break;
|
|
oKidnapped = GetNextObjectInArea(GetArea(OBJECT_SELF));
|
|
}
|
|
|
|
if (InitiativeCheck() == TRUE)
|
|
{
|
|
SetLocalInt(oKidnapped, "Rescued", TRUE);
|
|
}
|
|
else
|
|
{
|
|
SetPlotFlag(oKidnapped, FALSE);
|
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oKidnapped);
|
|
AddRandomQuestJournalEntry(oPC, 3);
|
|
switch (Random(3))
|
|
{
|
|
case 0: AssignCommand(OBJECT_SELF, SpeakString("Bad move!")); break;
|
|
case 1: AssignCommand(OBJECT_SELF, SpeakString("The blood is on your hands!")); break;
|
|
case 2: AssignCommand(OBJECT_SELF, SpeakString("This death was not necessary!")); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (GetLocalInt(OBJECT_SELF, "BeganAttacking") == FALSE && (GetCampaignString(sDB, "QUEST_TEMPLATE") == "interrogate" || GetCampaignString(sDB, "QUEST_TEMPLATE") == "kill") && GetCampaignInt(sDB, "QUEST_COMPLICATION") == 2) //add conditions for quest types (kill, interrogate...)
|
|
{
|
|
SetLocalInt(OBJECT_SELF, "BeganAttacking", TRUE);
|
|
string sAreaString = GetLocalString(GetArea(OBJECT_SELF), "AreaString");
|
|
string sRace = GetCampaignString(sDB, "QUEST_NPC_RACE");
|
|
object oWaypoint = GetWaypointByTag("event_wp_"+sAreaString+"_2");
|
|
location lLocation = GetLocation(oWaypoint);
|
|
object oMob1 = CreateObject(OBJECT_TYPE_CREATURE, "quest_bguard_"+sRace, lLocation);
|
|
|
|
oWaypoint = GetWaypointByTag("event_wp_"+sAreaString+"_3");
|
|
lLocation = GetLocation(oWaypoint);
|
|
object oMob2 = CreateObject(OBJECT_TYPE_CREATURE, "quest_bguard_"+sRace, lLocation);
|
|
|
|
LevelHenchmanUpTo(oMob1, GetHitDice(oPC)-3, CLASS_TYPE_INVALID, 0, GetCreatureStartingPackage(oMob1), PACKAGE_INVALID);
|
|
LevelHenchmanUpTo(oMob2, GetHitDice(oPC)-3, CLASS_TYPE_INVALID, 0, GetCreatureStartingPackage(oMob2), PACKAGE_INVALID);
|
|
|
|
int nBonus;
|
|
switch (GetHitDice(oPC)-25)
|
|
{
|
|
case 1:
|
|
case 2: nBonus = 1; break;
|
|
case 3:
|
|
case 4: nBonus = 2; break;
|
|
case 5: nBonus = 3; break;
|
|
case 6:
|
|
case 7: nBonus = 4; break;
|
|
case 8:
|
|
case 9: nBonus = 5; break;
|
|
case 10: nBonus = 6; break;
|
|
case 11:
|
|
case 12: nBonus = 7; break;
|
|
case 13:
|
|
case 14: nBonus = 8; break;
|
|
case 15: nBonus = 9; break;
|
|
default: nBonus = 0;
|
|
}
|
|
|
|
if (nBonus != 0)
|
|
{
|
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectAttackIncrease(nBonus), oMob1);
|
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectAttackIncrease(nBonus), oMob2);
|
|
}
|
|
}
|
|
|
|
|
|
SetIsTemporaryEnemy(oPC);
|
|
SetPlotFlag(OBJECT_SELF, FALSE);
|
|
ClearAllActions();
|
|
if (Random(10) == 0 && (GetCampaignInt(sDB, "1_NPC_OCCUPIED") == FALSE || GetCampaignInt(sDB, "2_NPC_OCCUPIED") == FALSE || GetCampaignInt(sDB, "3_NPC_OCCUPIED") == FALSE)) SetLocalInt(OBJECT_SELF, "WillRun", TRUE);
|
|
CastInitialBuffs();
|
|
//HenchDetermineCombatRound();
|
|
|
|
object oMob = GetFirstObjectInArea(GetArea(OBJECT_SELF));
|
|
while (GetIsObjectValid(oMob))
|
|
{
|
|
if (GetLocalInt(oMob, "Bodyguard") == TRUE)
|
|
{
|
|
SetIsTemporaryEnemy(oPC, oMob);
|
|
SetPlotFlag(oMob, FALSE);
|
|
AssignCommand(oMob, ClearAllActions());
|
|
AssignCommand(oMob, ActionAttack(oPC));
|
|
}
|
|
oMob = GetNextObjectInArea(GetArea(OBJECT_SELF));
|
|
}
|
|
return;
|
|
}
|
|
|
|
//If the quest is halted
|
|
if (GetLocalInt(OBJECT_SELF, "Quest_Halt") == TRUE)
|
|
{
|
|
//If the PC is supposed to kill the NPC
|
|
if (GetCampaignString(sDB, "QUEST_EXTRA2") == "mustkill")
|
|
{
|
|
AddRandomQuestJournalEntry(oPC, 3);
|
|
}
|
|
|
|
SetPlotFlag(OBJECT_SELF, TRUE);
|
|
ClearAllActions();
|
|
ActionMoveAwayFromObject(GetPCSpeaker(), FALSE);
|
|
ActionDoCommand(DestroyObject(OBJECT_SELF));
|
|
|
|
object oMob = GetFirstObjectInArea(GetArea(OBJECT_SELF));
|
|
while (GetIsObjectValid(oMob))
|
|
{
|
|
if (GetLocalInt(oMob, "Bodyguard") == TRUE)
|
|
{
|
|
SetPlotFlag(oMob, TRUE);
|
|
AssignCommand(oMob, ClearAllActions());
|
|
AssignCommand(oMob, ActionMoveAwayFromObject(GetPCSpeaker(), FALSE));
|
|
AssignCommand(oMob, ActionDoCommand(DestroyObject(oMob)));
|
|
}
|
|
oMob = GetNextObjectInArea(GetArea(OBJECT_SELF));
|
|
}
|
|
}
|
|
|
|
}
|