generated from Jaysyn/ModuleTemplate
Hooked up new GUI module event. Removed CEP3 haks. Updated PRC8 includes. Updated readme.
395 lines
13 KiB
Plaintext
395 lines
13 KiB
Plaintext
//::///////////////////////////////////////////////
|
||
//:: NPC associate include
|
||
//:: inc_npc
|
||
//:://////////////////////////////////////////////
|
||
/*
|
||
*/
|
||
//:://////////////////////////////////////////////
|
||
//:://////////////////////////////////////////////
|
||
|
||
//:: Levels up an NPC according to variables set on NPC.
|
||
void LevelUpSummon(object oSummon, int iTargetLvl);
|
||
|
||
// Get the master of oAssociate.
|
||
object GetMasterNPC(object oAssociate0 = OBJECT_SELF);
|
||
|
||
// Returns the associate type of the specified creature.
|
||
// - Returns ASSOCIATE_TYPE_NONE if the creature is not the associate of anyone.
|
||
int GetAssociateTypeNPC( object oAssociate );
|
||
|
||
// Get the henchman belonging to oMaster.
|
||
// * Return OBJECT_INVALID if oMaster does not have a henchman.
|
||
// -nNth: Which henchman to return.
|
||
object GetHenchmanNPC(object oMaster=OBJECT_SELF,int nNth=1);
|
||
|
||
// Get the associate of type nAssociateType belonging to oMaster.
|
||
// - nAssociateType: ASSOCIATE_TYPE_*
|
||
// - nMaster
|
||
// - nTh: Which associate of the specified type to return
|
||
// * Returns OBJECT_INVALID if no such associate exists.
|
||
object GetAssociateNPC(int nAssociateType, object oMaster=OBJECT_SELF, int nTh=1);
|
||
|
||
// Returns TRUE if the specified condition flag is set on
|
||
// the associate.
|
||
int GetAssociateStateNPC(int nCondition, object oAssoc=OBJECT_SELF);
|
||
|
||
// Determine if this henchman is currently dying
|
||
int GetIsHenchmanDyingNPC(object oHench=OBJECT_SELF);
|
||
|
||
// Determine if Should I Heal My Master
|
||
int GetAssociateHealMasterNPC();
|
||
|
||
// Create the next AssociateType creature
|
||
object CreateLocalNextNPC(object oMaster,int nAssociateType,string sTemplate,location loc,string sTag="");
|
||
|
||
// Create a AssociateType creature
|
||
object CreateLocalNPC(object oMaster,int nAssociateType,string sTemplate,location loc,int Nth=1,string sTag="");
|
||
|
||
|
||
#include "prc_inc_function"
|
||
#include "x0_i0_assoc"
|
||
|
||
void SetLocalNPC(object oMaster,object oAssociate,int nAssociateType ,int nNth=1)
|
||
{
|
||
SetLocalObject(oAssociate, "oMaster", oMaster);
|
||
SetLocalInt(oAssociate, "iAssocType", nAssociateType);
|
||
SetLocalObject(oMaster, IntToString(nAssociateType)+"oHench"+IntToString(nNth), oAssociate);
|
||
SetLocalInt(oAssociate, "iAssocNth", nNth);
|
||
|
||
}
|
||
|
||
void DeleteLocalNPC(object oAssociate=OBJECT_SELF)
|
||
{
|
||
int nType = GetLocalInt(oAssociate, "iAssocType");
|
||
object oMaster = GetMasterNPC(oAssociate);
|
||
int Nth = GetLocalInt(oAssociate, "iAssocNth");
|
||
|
||
DeleteLocalInt(oMaster, IntToString(nType)+"oHench"+IntToString(Nth));
|
||
DeleteLocalInt(oAssociate, "iAssocNth");
|
||
DeleteLocalObject(oAssociate, "oMaster");
|
||
DeleteLocalInt(oAssociate, "iAssocType");
|
||
}
|
||
|
||
void DestroySummon(object oSummon)
|
||
{
|
||
effect eVis = EffectVisualEffect(VFX_IMP_UNSUMMON);
|
||
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eVis, GetLocation(oSummon));
|
||
DeleteLocalNPC(oSummon);
|
||
DestroyObject(oSummon);
|
||
}
|
||
|
||
object CreateLocalNPC(object oMaster,int nAssociateType,string sTemplate,location loc,int Nth=1,string sTag="")
|
||
{
|
||
object oSummon=CreateObject(OBJECT_TYPE_CREATURE,sTemplate,loc,FALSE,sTag);
|
||
|
||
SetLocalNPC(oMaster,oSummon,nAssociateType ,Nth);
|
||
SetAssociateState(NW_ASC_HAVE_MASTER,TRUE,oSummon);
|
||
SetAssociateState(NW_ASC_DISTANCE_2_METERS);
|
||
SetAssociateState(NW_ASC_DISTANCE_4_METERS, FALSE);
|
||
SetAssociateState(NW_ASC_DISTANCE_6_METERS, FALSE);
|
||
|
||
if (nAssociateType == ASSOCIATE_TYPE_FAMILIAR) SetLocalInt(oMaster, "FamiliarToTheDeath", 100);
|
||
if (nAssociateType == ASSOCIATE_TYPE_ANIMALCOMPANION) SetLocalInt(oMaster, "AniCompToTheDeath", 100);
|
||
|
||
effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_UNDEAD);
|
||
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oSummon));
|
||
|
||
return oSummon;
|
||
}
|
||
|
||
object CreateLocalNextNPC(object oMaster,int nAssociateType,string sTemplate,location loc,string sTag="")
|
||
{
|
||
object oSummon=CreateObject(OBJECT_TYPE_CREATURE,sTemplate,loc,FALSE,sTag);
|
||
int nCount=1;
|
||
|
||
while (GetIsObjectValid(GetAssociateNPC(ASSOCIATE_TYPE_SUMMONED,OBJECT_SELF,nCount)))
|
||
{
|
||
nCount++;
|
||
SendMessageToPC(OBJECT_SELF," nCount:"+IntToString(nCount));
|
||
}
|
||
|
||
SetLocalObject(oSummon, "oMaster", oMaster);
|
||
SetLocalInt(oSummon, "iAssocType", nAssociateType);
|
||
SetLocalObject(oMaster, IntToString(nAssociateType)+"oHench"+IntToString(nCount), oSummon);
|
||
SetLocalInt(oSummon, "iAssocNth", nCount);
|
||
|
||
SetAssociateState(NW_ASC_HAVE_MASTER, TRUE, oSummon);
|
||
SetAssociateState(NW_ASC_DISTANCE_2_METERS);
|
||
SetAssociateState(NW_ASC_DISTANCE_4_METERS, FALSE);
|
||
SetAssociateState(NW_ASC_DISTANCE_6_METERS, FALSE);
|
||
|
||
if (nAssociateType ==ASSOCIATE_TYPE_FAMILIAR) SetLocalInt(oMaster, "FamiliarToTheDeath", 100);
|
||
if (nAssociateType ==ASSOCIATE_TYPE_ANIMALCOMPANION) SetLocalInt(oMaster, "AniCompToTheDeath", 100);
|
||
|
||
return oSummon;
|
||
|
||
}
|
||
|
||
object GetMasterNPC(object oAssociate=OBJECT_SELF)
|
||
{
|
||
object oMaster = GetLocalObject(oAssociate, "oMaster");
|
||
|
||
if (GetIsObjectValid(oMaster))
|
||
return oMaster;
|
||
else
|
||
return GetMaster(oAssociate);
|
||
}
|
||
|
||
int GetAssociateTypeNPC( object oAssociate )
|
||
{
|
||
int iType = GetLocalInt(oAssociate, "iAssocType");
|
||
if (iType)
|
||
return iType;
|
||
else
|
||
return GetAssociateType(oAssociate);
|
||
}
|
||
|
||
object GetHenchmanNPC(object oMaster=OBJECT_SELF,int nNth=1)
|
||
{
|
||
object oAssociate = GetLocalObject(oMaster,IntToString(ASSOCIATE_TYPE_HENCHMAN)+"oHench"+IntToString(nNth));
|
||
|
||
if (GetIsObjectValid(oAssociate))
|
||
return oAssociate;
|
||
else
|
||
return GetHenchman(oMaster,nNth);
|
||
}
|
||
|
||
object GetAssociateNPC(int nAssociateType, object oMaster=OBJECT_SELF, int nTh=1)
|
||
{
|
||
object oAssociate = GetLocalObject(oMaster,IntToString(nAssociateType)+"oHench"+IntToString(nTh));
|
||
|
||
if (GetIsObjectValid(oAssociate))
|
||
return oAssociate;
|
||
else
|
||
return GetAssociate(nAssociateType,oMaster,nTh);
|
||
}
|
||
|
||
int GetAssociateStateNPC(int nCondition, object oAssoc=OBJECT_SELF)
|
||
{
|
||
//SpawnScriptDebugger();
|
||
|
||
if(nCondition == NW_ASC_HAVE_MASTER)
|
||
{
|
||
if(GetIsObjectValid(GetMasterNPC(oAssoc)))
|
||
return TRUE;
|
||
}
|
||
else
|
||
{
|
||
int nPlot = GetLocalInt(oAssoc, sAssociateMasterConditionVarname);
|
||
|
||
if(nPlot & nCondition)
|
||
return TRUE;
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
int GetIsHenchmanDyingNPC(object oHench=OBJECT_SELF)
|
||
{
|
||
int bHenchmanDying = GetAssociateStateNPC(NW_ASC_MODE_DYING, oHench);
|
||
|
||
if (bHenchmanDying == TRUE)
|
||
{
|
||
return TRUE;
|
||
}
|
||
else
|
||
{
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
int GetAssociateHealMasterNPC()
|
||
{
|
||
if(GetAssociateStateNPC(NW_ASC_HAVE_MASTER))
|
||
{
|
||
object oMaster = GetMasterNPC();
|
||
int nLoss = GetPercentageHPLoss(oMaster);
|
||
|
||
if(!GetIsDead(oMaster))
|
||
{
|
||
if(GetAssociateStateNPC(NW_ASC_HEAL_AT_75) && nLoss <= 75)
|
||
{
|
||
return TRUE;
|
||
}
|
||
else if(GetAssociateStateNPC(NW_ASC_HEAL_AT_50) && nLoss <= 50)
|
||
{
|
||
return TRUE;
|
||
}
|
||
else if(GetAssociateStateNPC(NW_ASC_HEAL_AT_25) && nLoss <= 25)
|
||
{
|
||
return TRUE;
|
||
}
|
||
}
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
/**
|
||
* @brief Levels up a summoned creature based on its master's total casting level,
|
||
* while respecting configured HD limits and multiclass transition rules.
|
||
* Should only be called on the NPC onSpawn event.
|
||
*
|
||
* This function:
|
||
* - Retrieves the master<65>s total casting level and clamps it to the creature<72>s
|
||
* minimum and maximum HD (iMinHD, iMaxHD).
|
||
* - Repeatedly calls LevelUpHenchman() until the creature reaches that level,
|
||
* switching classes when the creature's stored "ClassXStart" thresholds are met.
|
||
*
|
||
* Local variables recognized on the summoned creature:
|
||
*
|
||
* | Variable Name | Purpose |
|
||
* |-----------------|-------------------------------------------------------------|
|
||
* | iMinHD | Minimum HD allowed |
|
||
* | iMaxHD | Maximum HD allowed |
|
||
* | Class2Start | Level to begin second class progression |
|
||
* | Class2 | Class type for second progression |
|
||
* | Class2Package | Package for second progression |
|
||
* | Class3Start | Level to begin third class progression |
|
||
* | Class3 | Class type for third progression |
|
||
* | Class3Package | Package for third progression |
|
||
* | Class4Start | Level to begin fourth class progression |
|
||
* | Class4 | Class type for fourth progression |
|
||
* | Class4Package | Package for fourth progression |
|
||
*
|
||
* Behavior notes:
|
||
* - Leveling continues until the creature reaches the master<65>s effective
|
||
* casting level (bounded by iMinHD/iMaxHD).
|
||
* - If LevelUpHenchman() returns 0, the creature shouts a failure message.
|
||
* - CLASS_TYPE_INVALID causes the creature to level in its current class.
|
||
*
|
||
* @param oCreature The summoned creature being leveled. Defaults to OBJECT_SELF.
|
||
*
|
||
* @see LevelUpHenchman
|
||
* @see GetLocalInt
|
||
* @see GetHitDice
|
||
*/
|
||
void LevelUpSummon(object oSummon, int iTargetLvl)
|
||
{
|
||
int nCurrentHD = GetHitDice(oSummon);
|
||
int iNewHD = nCurrentHD;
|
||
|
||
// Read multiclassing info from locals
|
||
int iClass2Start = GetLocalInt(oSummon, "Class2Start");
|
||
int iClass2 = GetLocalInt(oSummon, "Class2");
|
||
int iClass2Package = GetLocalInt(oSummon, "Class2Package");
|
||
|
||
int iClass3Start = GetLocalInt(oSummon, "Class3Start");
|
||
int iClass3 = GetLocalInt(oSummon, "Class3");
|
||
int iClass3Package = GetLocalInt(oSummon, "Class3Package");
|
||
|
||
int iClass4Start = GetLocalInt(oSummon, "Class4Start");
|
||
int iClass4 = GetLocalInt(oSummon, "Class4");
|
||
int iClass4Package = GetLocalInt(oSummon, "Class4Package");
|
||
|
||
int iClass; // current class to level
|
||
int iPackage; // package to use
|
||
|
||
// Main leveling loop
|
||
while (nCurrentHD < iTargetLvl && nCurrentHD > 0)
|
||
{
|
||
// Determine which class and package to use
|
||
if (iClass4Start != 0 && nCurrentHD >= iClass4Start)
|
||
{
|
||
iClass = iClass4;
|
||
iPackage = iClass4Package;
|
||
}
|
||
else if (iClass3Start != 0 && nCurrentHD >= iClass3Start)
|
||
{
|
||
iClass = iClass3;
|
||
iPackage = iClass3Package;
|
||
}
|
||
else if (iClass2Start != 0 && nCurrentHD >= iClass2Start)
|
||
{
|
||
iClass = iClass2;
|
||
iPackage = iClass2Package;
|
||
}
|
||
else
|
||
{
|
||
// Base class (first class in the sheet)
|
||
iClass = CLASS_TYPE_INVALID; // keeps current
|
||
iPackage = PACKAGE_INVALID;
|
||
}
|
||
|
||
// Level up one HD
|
||
iNewHD = LevelUpHenchman(oSummon, iClass, TRUE, iPackage);
|
||
|
||
if (iNewHD == 0)
|
||
{
|
||
SpeakString(GetName(oSummon) + " failed to level properly!", TALKVOLUME_SHOUT);
|
||
break;
|
||
}
|
||
|
||
nCurrentHD = iNewHD;
|
||
}
|
||
|
||
// Force the creature to rest to memorize spells
|
||
// PRCForceRest(oSummon);
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/* void LevelUpSummon(object oSummon, int iTargetLvl)
|
||
{
|
||
//get the default hit dice of the summon
|
||
int nDefaultHD = GetHitDice(oSummon);
|
||
|
||
if (DEBUG) DoDebug("inc_npc >> LevelUpSummon: nDefaultHD = " +IntToString(nDefaultHD)+".");
|
||
|
||
if (DEBUG) DoDebug("inc_npc >> LevelUpSummon: iTargetLvl = " +IntToString(iTargetLvl)+".");
|
||
|
||
//get the multiclassing variables to see if we need to change classes from its base class
|
||
int iClass2Start = GetLocalInt(oSummon, "Class2Start");
|
||
int iClass2 = GetLocalInt(oSummon, "Class2");
|
||
int iClass2Package = GetLocalInt(oSummon, "Class2Package");
|
||
|
||
int iClass3Start = GetLocalInt(oSummon, "Class3Start");
|
||
int iClass3 = GetLocalInt(oSummon, "Class3");
|
||
int iClass3Package = GetLocalInt(oSummon, "Class3Package");
|
||
|
||
int iClass4Start = GetLocalInt(oSummon, "Class4Start");
|
||
int iClass4 = GetLocalInt(oSummon, "Class4");
|
||
int iClass4Package = GetLocalInt(oSummon, "Class4Package");
|
||
|
||
//check for zero cause thats an error
|
||
//if creatures are not leveling then best bet is they are not legal creatures
|
||
while( (nDefaultHD < iTargetLvl) && (nDefaultHD > 0) )
|
||
{
|
||
//check the multiclassing numbers to change classes
|
||
if( (iClass4Start != 0) && (nDefaultHD >= iClass4Start) )
|
||
{
|
||
//level up using the new class and Packageage
|
||
nDefaultHD = LevelUpHenchman(oSummon, iClass4 ,TRUE, iClass4Package);
|
||
|
||
if(nDefaultHD == 0)
|
||
SpeakString(GetName(oSummon) + " Failed on fourth class", TALKVOLUME_SHOUT);
|
||
}
|
||
else if( (iClass3Start != 0) && (nDefaultHD >= iClass3Start) )
|
||
{
|
||
//level up using the new class and Packageage
|
||
nDefaultHD = LevelUpHenchman(oSummon, iClass3 ,TRUE, iClass3Package);
|
||
|
||
if(nDefaultHD == 0)
|
||
SpeakString(GetName(oSummon) + " Failed on third class", TALKVOLUME_SHOUT);
|
||
}
|
||
else if( (iClass2Start != 0) && (nDefaultHD >= iClass2Start) )
|
||
{
|
||
//level up using the new class and Packageage
|
||
nDefaultHD = LevelUpHenchman(oSummon, iClass2 ,TRUE, iClass2Package);
|
||
|
||
if(nDefaultHD == 0)
|
||
SpeakString(GetName(oSummon) + " Failed on second class", TALKVOLUME_SHOUT);
|
||
}
|
||
else
|
||
{
|
||
//just level up using the class it already has
|
||
nDefaultHD = LevelUpHenchman(oSummon, CLASS_TYPE_INVALID ,TRUE);
|
||
|
||
if(nDefaultHD == 0)
|
||
SpeakString(GetName(oSummon) + " Failed to level properly", TALKVOLUME_SHOUT);
|
||
}
|
||
}
|
||
}
|
||
*/
|
||
//:: void main() {} |