Update for NWN .35
Update for NWN .35
This commit is contained in:
BIN
_haks/poa_dev/default.ncs
Normal file
BIN
_haks/poa_dev/default.ncs
Normal file
Binary file not shown.
417
_haks/poa_dev/default.nss
Normal file
417
_haks/poa_dev/default.nss
Normal file
@@ -0,0 +1,417 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Default eventscript
|
||||
//:: default
|
||||
//:://////////////////////////////////////////////
|
||||
/** @file
|
||||
This script is executed by the engine for events
|
||||
when a creature does not have a script defined
|
||||
for the event in question. This includes PCs.
|
||||
|
||||
The purpose of this script is to determine
|
||||
which particular event triggered it's execution
|
||||
and to route execution to scripts dedicated to
|
||||
that event.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_alterations"
|
||||
#include "prc_inc_leadersh"
|
||||
|
||||
const int LOCAL_DEBUG = FALSE; //DEBUG;
|
||||
|
||||
/**************************/
|
||||
/* Declarations for Tests */
|
||||
/**************************/
|
||||
|
||||
int IsBlocked(); // test GetBlockingDoor()
|
||||
int IsCombatRoundEnd(); // Need to fake this
|
||||
int IsConversation(); // test a local variable
|
||||
int IsDamaged(); // test GetLastDamager()
|
||||
int IsDeath(); // test GetIsDead(OBJECT_SELF)
|
||||
int IsDisturbed(); // test GetLastDisturbed()
|
||||
int IsHeartbeat(); // test game time
|
||||
int IsPerception(); // test GetLastPerceived()
|
||||
int IsPhysicalAttacked(); // test GetLastAttacker()
|
||||
int IsRested(); // test GetIsResting(GetMaster())
|
||||
int IsSpawn(); // run once, never again
|
||||
int IsSpellCastAt(); // test GetLastSpellCaster()
|
||||
int IsUserDefined(); // test GetUserDefinedEventNumber()
|
||||
|
||||
/*********************************/
|
||||
/* Utility Function declarations */
|
||||
/*********************************/
|
||||
|
||||
//void ForceAddHenchman(object oHenchman);
|
||||
//int IsLinkboyAttached();
|
||||
//void GetLinkboy();
|
||||
int IsObjectChanged(object oTest, string sVarname);
|
||||
int IsIntChanged(int iTest, string sVarname);
|
||||
int IsStringChanged(string sTest, string sVarname);
|
||||
void RunScript(int nEvent);
|
||||
//void SpawnRecallLocals(object oPC);
|
||||
//void StartGroupDiscussion();
|
||||
|
||||
/*****************************/
|
||||
/* Implementation of Actions */
|
||||
/*****************************/
|
||||
|
||||
void OnSpawn() { RunScript(EVENT_VIRTUAL_ONSPAWNED); }
|
||||
void OnDeath() { RunScript(EVENT_VIRTUAL_ONDEATH); }
|
||||
void OnRested() { RunScript(EVENT_VIRTUAL_ONRESTED); }
|
||||
void OnHeartbeat() { RunScript(EVENT_VIRTUAL_ONHEARTBEAT); }
|
||||
void OnPerception() { RunScript(EVENT_VIRTUAL_ONPERCEPTION); }
|
||||
void OnBlocked() { RunScript(EVENT_VIRTUAL_ONBLOCKED); }
|
||||
void OnCombatRoundEnd() { RunScript(EVENT_VIRTUAL_ONCOMBATROUNDEND); }
|
||||
void OnDisturbed() { RunScript(EVENT_VIRTUAL_ONDISTURBED); }
|
||||
void OnPhysicalAttacked() { RunScript(EVENT_VIRTUAL_ONPHYSICALATTACKED); }
|
||||
void OnSpellCastAt() { RunScript(EVENT_VIRTUAL_ONSPELLCASTAT); }
|
||||
void OnDamaged() { RunScript(EVENT_VIRTUAL_ONDAMAGED); }
|
||||
void OnUserDefined() { RunScript(EVENT_VIRTUAL_ONUSERDEFINED); }
|
||||
void OnConversation() { RunScript(EVENT_VIRTUAL_ONCONVERSATION); }
|
||||
|
||||
/******************/
|
||||
/* Main Procedure */
|
||||
/******************/
|
||||
|
||||
void main()
|
||||
{
|
||||
if(LOCAL_DEBUG) DoDebug("default running for " + DebugObject2Str(OBJECT_SELF));
|
||||
|
||||
// OnConversation is exclusive of everything else, since it is just routed through this script
|
||||
if(IsConversation()) OnConversation();
|
||||
else
|
||||
{
|
||||
if(IsBlocked()) OnBlocked();
|
||||
if(IsCombatRoundEnd()) OnCombatRoundEnd();
|
||||
if(IsDamaged()) OnDamaged();
|
||||
if(IsDeath()) OnDeath();
|
||||
if(IsDisturbed()) OnDisturbed();
|
||||
if(IsHeartbeat()) OnHeartbeat();
|
||||
if(IsPerception()) OnPerception();
|
||||
if(IsPhysicalAttacked()) OnPhysicalAttacked();
|
||||
if(IsRested()) OnRested();
|
||||
if(IsSpawn()) OnSpawn();
|
||||
if(IsSpellCastAt()) OnSpellCastAt();
|
||||
if(IsUserDefined()) OnUserDefined();
|
||||
}
|
||||
}
|
||||
|
||||
/************************/
|
||||
/* Tests for conditions */
|
||||
/************************/
|
||||
|
||||
int IsBlocked()
|
||||
{
|
||||
return IsObjectChanged(GetBlockingDoor(), "BlockingDoor");
|
||||
}
|
||||
|
||||
int IsCombatRoundEnd()
|
||||
{
|
||||
// Need to fake this.
|
||||
// Return TRUE iff you are in combat and not doing anything useful
|
||||
if(GetIsInCombat() ||
|
||||
(GetIsObjectValid(GetMaster()) &&
|
||||
GetIsInCombat(GetMaster())
|
||||
)
|
||||
)
|
||||
{
|
||||
int nGCA = GetCurrentAction();
|
||||
if(nGCA == ACTION_ATTACKOBJECT ||
|
||||
nGCA == ACTION_CASTSPELL ||
|
||||
nGCA == ACTION_COUNTERSPELL ||
|
||||
nGCA == ACTION_HEAL ||
|
||||
nGCA == ACTION_FOLLOW ||
|
||||
nGCA == ACTION_ITEMCASTSPELL ||
|
||||
nGCA == ACTION_KIDAMAGE ||
|
||||
nGCA == ACTION_OPENDOOR ||
|
||||
nGCA == ACTION_SMITEGOOD
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int IsConversation()
|
||||
{
|
||||
object oCreature = OBJECT_SELF;
|
||||
if(GetLocalInt(oCreature, "default_conversation_event"))
|
||||
{
|
||||
DeleteLocalInt(oCreature, "default_conversation_event");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int IsDamaged()
|
||||
{
|
||||
object oCreature = OBJECT_SELF;
|
||||
object oDamager = GetLastDamager(oCreature);
|
||||
|
||||
// The damage source must be valid
|
||||
if(GetIsObjectValid(oDamager))
|
||||
{
|
||||
// Get previous damage data
|
||||
string sOldDamage = GetLocalString(oCreature, "PRC_Event_OnDamaged_Data");
|
||||
|
||||
// Create string based on current damage values
|
||||
// Start with the damaging object
|
||||
string sNewDamage = ObjectToString(oDamager);
|
||||
// Catenate amount of damage of each damage type
|
||||
int i;
|
||||
for(i = DAMAGE_TYPE_BLUDGEONING; i <= DAMAGE_TYPE_BASE_WEAPON; i = i << 1)
|
||||
sNewDamage += IntToString(GetDamageDealtByType(i));
|
||||
|
||||
// Determine if the damage dealt has changed
|
||||
if(sOldDamage != sNewDamage)
|
||||
{
|
||||
if(LOCAL_DEBUG) DoDebug("default: Damage has changed:\n" + sNewDamage);
|
||||
SetLocalString(oCreature, "PRC_Event_OnDamaged_Data", sNewDamage);
|
||||
|
||||
// Update damage counter
|
||||
SetLocalInt(oCreature, "PRC_LastDamageTaken", GetTotalDamageDealt());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int IsDeath()
|
||||
{
|
||||
return GetIsDead(OBJECT_SELF);
|
||||
}
|
||||
|
||||
int IsDisturbed()
|
||||
{
|
||||
object oCreature = OBJECT_SELF;
|
||||
object oDisturber = GetLastDisturbed();
|
||||
|
||||
if(GetIsObjectValid(oDisturber)) // The creature has been disturbed at least once during the game
|
||||
{
|
||||
// Get previous disturb data
|
||||
string sOldDisturb = GetLocalString(oCreature, "PRC_Event_OnDisturbed_Data");
|
||||
|
||||
// Create string based on current disturb values
|
||||
string sNewDisturb = ObjectToString(oDisturber);
|
||||
sNewDisturb += IntToString(GetInventoryDisturbType());
|
||||
sNewDisturb += ObjectToString(GetInventoryDisturbItem());
|
||||
|
||||
// Determine if the data has changed
|
||||
if(sOldDisturb != sNewDisturb)
|
||||
{
|
||||
if(LOCAL_DEBUG) DoDebug("default: Disturbed has changed:\n" + sNewDisturb);
|
||||
SetLocalString(oCreature, "PRC_Event_OnDisturbed_Data", sNewDisturb);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int IsHeartbeat()
|
||||
{
|
||||
object oCreature = OBJECT_SELF;
|
||||
// PCs use the module HB
|
||||
if(!GetIsPC(oCreature))
|
||||
{
|
||||
// Check how long since last recorded heartbeat
|
||||
int nSecsChange = (GetTimeSecond() - GetLocalInt(oCreature, "PRC_LastHeartbeatSeconds") + 60) % 60;
|
||||
|
||||
// See if the master clock has ticked or 9 seconds have elapsed anyway
|
||||
if(nSecsChange >= 6)
|
||||
{
|
||||
SetLocalInt(oCreature, "PRC_LastHeartbeatSeconds", GetTimeSecond());
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int IsPerception()
|
||||
{
|
||||
object oCreature = OBJECT_SELF;
|
||||
object oPerceived = GetLastPerceived();
|
||||
|
||||
if(GetIsObjectValid(oPerceived)) // The creature has perceived something at least once during the game
|
||||
{
|
||||
// Get previous perception data
|
||||
string sOldPerception = GetLocalString(oCreature, "PRC_Event_OnPerception_Data");
|
||||
|
||||
// Create string based on current perception values
|
||||
string sNewPerception = ObjectToString(oPerceived);
|
||||
sNewPerception += IntToString(GetLastPerceptionHeard());
|
||||
sNewPerception += IntToString(GetLastPerceptionInaudible());
|
||||
sNewPerception += IntToString(GetLastPerceptionSeen());
|
||||
sNewPerception += IntToString(GetLastPerceptionVanished());;
|
||||
|
||||
// Determine if the data has changed
|
||||
if(sOldPerception != sNewPerception)
|
||||
{
|
||||
if(LOCAL_DEBUG) DoDebug("default: Perception has changed:\n" + sNewPerception);
|
||||
SetLocalString(oCreature, "PRC_Event_OnPerception_Data", sNewPerception);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int IsPhysicalAttacked()
|
||||
{
|
||||
object oCreature = OBJECT_SELF;
|
||||
object oAttacker = GetLastAttacker();
|
||||
|
||||
// Recent enough event that the attacker is at least still valid
|
||||
if(GetIsObjectValid(oAttacker))
|
||||
{
|
||||
// Get previous attack data
|
||||
string sOldAttack = GetLocalString(oCreature, "PRC_Event_OnPhysicalAttacked_Data");
|
||||
|
||||
// Create string for the current attack data
|
||||
string sNewAttack = ObjectToString(oAttacker);
|
||||
sNewAttack += ObjectToString(GetLastWeaponUsed(oAttacker));
|
||||
sNewAttack += IntToString(GetLastAttackMode(oAttacker));
|
||||
sNewAttack += IntToString(GetLastAttackType(oAttacker));
|
||||
|
||||
// Determine if the data has changed
|
||||
if(sOldAttack != sNewAttack)
|
||||
{
|
||||
if(LOCAL_DEBUG) DoDebug("default: Attack has changed:\n" + sNewAttack);
|
||||
SetLocalString(oCreature, "PRC_Event_OnPhysicalAttacked_Data", sNewAttack);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int IsRested()
|
||||
{
|
||||
// PCs use the module OnRest events
|
||||
if(!GetIsPC(OBJECT_SELF))
|
||||
{
|
||||
// Goes TRUE when Master starts resting
|
||||
int bMasterIsResting = GetIsResting(GetMaster());
|
||||
return IsIntChanged(bMasterIsResting,"MasterIsResting") && bMasterIsResting;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int IsSpawn()
|
||||
{
|
||||
object oCreature = OBJECT_SELF;
|
||||
if(!GetLocalInt(oCreature, "PRC_OnSpawn_Marker"))
|
||||
{
|
||||
SetLocalInt(oCreature, "PRC_OnSpawn_Marker", TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int IsSpellCastAt()
|
||||
{
|
||||
object oCreature = OBJECT_SELF;
|
||||
if(LOCAL_DEBUG) DoDebug("default: IsSpellCastAt():\n"
|
||||
+ "GetLastSpellCaster() = " + DebugObject2Str(GetLastSpellCaster()) + "\n"
|
||||
+ "GetLastSpell() = " + IntToString(GetLastSpell()) + "\n"
|
||||
+ "GetLastSpellHarmful() = " + IntToString(GetLastSpellHarmful()) + "\n"
|
||||
);
|
||||
// If the event data does not contain the fake value, a spell has been cast
|
||||
if(GetLastSpell() != -1)
|
||||
{
|
||||
// Reset the event data to the fake value
|
||||
DelayCommand(0.0f, SignalEvent(oCreature, EventSpellCastAt(oCreature, -1, FALSE)));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int IsUserDefined()
|
||||
{
|
||||
object oCreature = OBJECT_SELF;
|
||||
if(LOCAL_DEBUG) DoDebug("default: IsUserDefined():\n"
|
||||
+ "GetUserDefinedEventNumber() = " + IntToString(GetUserDefinedEventNumber()) + "\n"
|
||||
);
|
||||
|
||||
if(GetUserDefinedEventNumber() != -1)
|
||||
{
|
||||
// Reset the event data to the fake value
|
||||
DelayCommand(0.0f, SignalEvent(oCreature, EventUserDefined(-1)));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*********************/
|
||||
/* Utility Functions */
|
||||
/*********************/
|
||||
|
||||
int IsObjectChanged(object oTest, string sName)
|
||||
{
|
||||
if(oTest != GetLocalObject(OBJECT_SELF, "PRC_Event_" + sName))
|
||||
{
|
||||
SetLocalObject(OBJECT_SELF, "PRC_Event_" + sName, oTest);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int IsIntChanged(int iTest, string sName)
|
||||
{
|
||||
if(iTest != GetLocalInt(OBJECT_SELF, "PRC_Event_" + sName))
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, "PRC_Event_" + sName, iTest);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int IsStringChanged(string sTest, string sName)
|
||||
{
|
||||
if(sTest != GetLocalString(OBJECT_SELF, "PRC_Event_" + sName))
|
||||
{
|
||||
SetLocalString(OBJECT_SELF, "PRC_Event_" + sName, sTest);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void RunScript(int nEvent)
|
||||
{
|
||||
object oSelf = OBJECT_SELF;
|
||||
|
||||
if(LOCAL_DEBUG) DoDebug("default, event = " + IntToString(nEvent));
|
||||
|
||||
if(nEvent == EVENT_VIRTUAL_ONDAMAGED)
|
||||
SignalEvent(oSelf, EventUserDefined(EVENT_DAMAGED));
|
||||
// Determine NPC script name and run generic eventhook
|
||||
ExecuteAllScriptsHookedToEvent(oSelf, nEvent);
|
||||
}
|
371
_haks/poa_dev/inc_ecl.nss
Normal file
371
_haks/poa_dev/inc_ecl.nss
Normal file
@@ -0,0 +1,371 @@
|
||||
/** @file
|
||||
* ECL handling.
|
||||
*
|
||||
* @author Primogenitor
|
||||
*
|
||||
* @todo Primo, could you document this one? More details to header and comment function prototypes
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function prototypes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
// returns oTarget's LA value, including their race and template(s) LA
|
||||
int GetTotalLA(object oTarget);
|
||||
|
||||
// returns oTarget's level adjusted by their LA
|
||||
int GetECL(object oTarget);
|
||||
void GiveXPReward(object oCreature, int nXP, int bIsPC = TRUE);
|
||||
void GiveXPRewardToParty(object oKiller, object oDead, int nCR = 0);
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Include section */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
//#include "inc_utility"
|
||||
//#include "prc_inc_template"
|
||||
#include "inc_npc"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function definitions */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
int GetTotalLA(object oTarget)
|
||||
{
|
||||
int nLA;
|
||||
int nRace = GetRacialType(oTarget);
|
||||
if(GetPRCSwitch(PRC_XP_USE_SIMPLE_LA))
|
||||
nLA += StringToInt(Get2DACache("ECL", "LA", nRace));
|
||||
if(GetPRCSwitch(PRC_XP_INCLUDE_RACIAL_HIT_DIE_IN_LA))
|
||||
nLA += StringToInt(Get2DACache("ECL", "RaceHD", nRace));
|
||||
nLA += GetPersistantLocalInt(oTarget, "template_LA");
|
||||
nLA -= GetPersistantLocalInt(oTarget, "LA_Buyoff");
|
||||
return nLA;
|
||||
}
|
||||
|
||||
int GetECL(object oTarget)
|
||||
{
|
||||
int nLevel;
|
||||
// we need to use a derivation of the base xp formular to compute the
|
||||
// pc level based on total XP.
|
||||
//
|
||||
// base XP formula (x = pc level, t = total xp):
|
||||
//
|
||||
// t = x * (x-1) * 500
|
||||
//
|
||||
// need to use some base math..
|
||||
// transform for pq formula use (remove brackets with x inside and zero right side)
|
||||
//
|
||||
// x^2 - x - (t / 500) = 0
|
||||
//
|
||||
// use pq formula to solve it [ x^2 + px + q = 0, p = -1, q = -(t/500) ]...
|
||||
//
|
||||
// that's our new formula to get the level based on total xp:
|
||||
// level = 0.5 + sqrt(0.25 + (t/500))
|
||||
//
|
||||
if(GetPRCSwitch(PRC_ECL_USES_XP_NOT_HD) && GetIsPC(oTarget))
|
||||
nLevel = FloatToInt(0.5 + sqrt(0.25 + ( IntToFloat(GetXP(oTarget)) / 500 )));
|
||||
else
|
||||
nLevel = GetHitDice(oTarget);
|
||||
nLevel += GetTotalLA(oTarget);
|
||||
return nLevel;
|
||||
}
|
||||
|
||||
int CheckDistance(object oDead, object oTest)
|
||||
{
|
||||
if(GetPRCSwitch(PRC_XP_MUST_BE_IN_AREA))
|
||||
{
|
||||
if(GetArea(oDead) != GetArea(oTest))
|
||||
return FALSE;
|
||||
if(GetDistanceBetween(oDead, oTest) > IntToFloat(GetPRCSwitch(PRC_XP_MAX_PHYSICAL_DISTANCE)))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
float GetGroupBonusModifier(int nPartySize)
|
||||
{
|
||||
return 1 + ((nPartySize-1) * IntToFloat(GetPRCSwitch(PRC_XP_GROUP_BONUS))/100.0);
|
||||
}
|
||||
|
||||
void GiveXPRewardToParty(object oKiller, object oDead, int nCR = 0)
|
||||
{
|
||||
//get prc switches
|
||||
int bSPAM = GetPRCSwitch(PRC_XP_DISABLE_SPAM);
|
||||
float fPRC_XP_DIVISOR_PC = IntToFloat(GetPRCSwitch(PRC_XP_PC_PARTY_COUNT_x100))/100.0;
|
||||
float fPRC_XP_DIVISOR_HENCHMAN = IntToFloat(GetPRCSwitch(PRC_XP_HENCHMAN_PARTY_COUNT_x100))/100.0;
|
||||
float fPRC_XP_DIVISOR_ANIMALCOMPANION = IntToFloat(GetPRCSwitch(PRC_XP_ANIMALCOMPANION_PARTY_COUNT_x100))/100.0;
|
||||
float fPRC_XP_DIVISOR_FAMILIAR = IntToFloat(GetPRCSwitch(PRC_XP_FAMILIAR_PARTY_COUNT_x100))/100.0;
|
||||
float fPRC_XP_DIVISOR_DOMINATED = IntToFloat(GetPRCSwitch(PRC_XP_DOMINATED_PARTY_COUNT_x100))/100.0;
|
||||
float fPRC_XP_DIVISOR_SUMMONED = IntToFloat(GetPRCSwitch(PRC_XP_SUMMONED_PARTY_COUNT_x100))/100.0;
|
||||
float fPRC_XP_DIVISOR_UNKNOWN = IntToFloat(GetPRCSwitch(PRC_XP_UNKNOWN_PARTY_COUNT_x100))/100.0;
|
||||
|
||||
//number of PCs in the party, average party level
|
||||
int nPartySize, nAvgLevel;
|
||||
//xp divisor
|
||||
float fDivisor;
|
||||
|
||||
//get some basic group data like average PC level , PC group size, and XP divisor
|
||||
object oTest = GetFirstFactionMember(oKiller, FALSE);
|
||||
while(GetIsObjectValid(oTest))
|
||||
{
|
||||
if(CheckDistance(oDead, oTest))
|
||||
{
|
||||
if(GetIsPC(oTest))
|
||||
{
|
||||
nPartySize++;
|
||||
nAvgLevel += GetECL(oTest);
|
||||
fDivisor += fPRC_XP_DIVISOR_PC;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(GetAssociateTypeNPC(oTest))
|
||||
{
|
||||
case ASSOCIATE_TYPE_HENCHMAN: fDivisor += fPRC_XP_DIVISOR_HENCHMAN; break;
|
||||
case ASSOCIATE_TYPE_ANIMALCOMPANION: fDivisor += fPRC_XP_DIVISOR_ANIMALCOMPANION; break;
|
||||
case ASSOCIATE_TYPE_FAMILIAR: fDivisor += fPRC_XP_DIVISOR_FAMILIAR; break;
|
||||
case ASSOCIATE_TYPE_DOMINATED: fDivisor += fPRC_XP_DIVISOR_DOMINATED; break;
|
||||
case ASSOCIATE_TYPE_SUMMONED: fDivisor += fPRC_XP_DIVISOR_SUMMONED; break;
|
||||
default: fDivisor += fPRC_XP_DIVISOR_UNKNOWN; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!bSPAM && GetIsPC(oTest))
|
||||
SendMessageToPC(oTest, "You are too far away from the combat to gain any experience.");
|
||||
|
||||
oTest = GetNextFactionMember(oKiller, FALSE);
|
||||
}
|
||||
|
||||
//in case something weird is happenening
|
||||
if(fDivisor == 0.0f)
|
||||
return;
|
||||
|
||||
//calculate average partylevel
|
||||
nAvgLevel /= nPartySize;
|
||||
|
||||
int nBaseXP;
|
||||
if(!nCR) nCR = GetPRCSwitch(PRC_XP_USE_ECL_NOT_CR) ? GetECL(oDead) : FloatToInt(GetChallengeRating(oDead));
|
||||
if(nCR < 1) nCR = 1;
|
||||
|
||||
if(GetPRCSwitch(PRC_XP_USE_BIOWARE_XPTABLE))
|
||||
{
|
||||
if(nCR > 40) nCR = 40;
|
||||
if(nAvgLevel > 40) nAvgLevel = 40;
|
||||
nBaseXP = StringToInt(Get2DACache("xptable", "C"+IntToString(nCR), nAvgLevel-1));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(nCR > 70) nCR = 70;
|
||||
if(nAvgLevel > 60) nAvgLevel = 60;
|
||||
nBaseXP = StringToInt(Get2DACache("dmgxp", IntToString(nCR), nAvgLevel-1));
|
||||
}
|
||||
|
||||
//average xp per party member
|
||||
int nXPAward = FloatToInt(IntToFloat(nBaseXP)/fDivisor);
|
||||
|
||||
//now the module slider
|
||||
nXPAward = FloatToInt(IntToFloat(nXPAward) * IntToFloat(GetPRCSwitch(PRC_XP_SLIDER_x100))/100.0);
|
||||
|
||||
//xp = 0, quit
|
||||
if(!nXPAward)
|
||||
return;
|
||||
|
||||
//group bonus
|
||||
nXPAward = FloatToInt(IntToFloat(nXPAward) * GetGroupBonusModifier(nPartySize));
|
||||
|
||||
int nKillerLevel = GetECL(oKiller);
|
||||
//calculate xp for each party member individually
|
||||
oTest = GetFirstFactionMember(oKiller, FALSE);
|
||||
float fPCAdjust;
|
||||
int nMbrLevel;
|
||||
while(GetIsObjectValid(oTest))
|
||||
{
|
||||
if(CheckDistance(oDead, oTest))
|
||||
{
|
||||
if(GetIsPC(oTest))
|
||||
{
|
||||
nMbrLevel = GetECL(oTest);
|
||||
if(abs(nMbrLevel - nKillerLevel) <= GetPRCSwitch(PRC_XP_MAX_LEVEL_DIFF))
|
||||
{
|
||||
//now the individual slider
|
||||
fPCAdjust = IntToFloat(GetLocalInt(oTest, PRC_XP_SLIDER_x100))/100.0;
|
||||
if(fPCAdjust == 0.0) fPCAdjust = 1.0;
|
||||
nXPAward = FloatToInt(IntToFloat(nXPAward) * fPCAdjust);
|
||||
|
||||
GiveXPReward(oTest, nXPAward);
|
||||
}
|
||||
else if(!bSPAM)
|
||||
SendMessageToPC(oTest, "You are too high level to gain any experience.");
|
||||
}
|
||||
else
|
||||
GiveXPReward(oTest, nXPAward, FALSE);
|
||||
}
|
||||
oTest = GetNextFactionMember(oKiller, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void GiveXPReward(object oCreature, int nXP, int bIsPC = TRUE)
|
||||
{
|
||||
//actually give the XP
|
||||
if(bIsPC)
|
||||
{
|
||||
if(GetPRCSwitch(PRC_XP_USE_SETXP))
|
||||
SetXP(oCreature, GetXP(oCreature)+nXP);
|
||||
else
|
||||
GiveXPToCreature(oCreature, nXP);
|
||||
}
|
||||
else if(GetPRCSwitch(PRC_XP_GIVE_XP_TO_NPCS))
|
||||
SetLocalInt(oCreature, "NPC_XP", GetLocalInt(oCreature, "NPC_XP")+nXP);
|
||||
}
|
||||
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Effective Character Level Experience Script
|
||||
//:: ecl_exp
|
||||
//:: Copyright (c) 2004 Theo Brinkman
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Call ApplyECLToXP() from applicable heartbeat script(s)
|
||||
to cause experience to be adjusted according to ECL.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Theo Brinkman
|
||||
//:: Last Updated On: 2004-07-28
|
||||
//:://////////////////////////////////////////////
|
||||
// CONSTANTS
|
||||
const string sLEVEL_ADJUSTMENT = "ecl_LevelAdjustment";
|
||||
const string sXP_AT_LAST_HEARTBEAT = "ecl_LastExperience";
|
||||
|
||||
int GetXPForLevel(int nLevel)
|
||||
{
|
||||
return nLevel*(nLevel-1)*500;
|
||||
}
|
||||
|
||||
void ApplyECLToXP(object oPC)
|
||||
{
|
||||
//abort if simple LA is disabled
|
||||
if(!GetPRCSwitch(PRC_XP_USE_SIMPLE_LA))
|
||||
return;
|
||||
|
||||
//abort if it's not valid, still loading, or a PC
|
||||
if(!GetIsObjectValid(oPC) || GetLocalInt(oPC, "PRC_ECL_Delay") || !GetIsPC(oPC))
|
||||
return;
|
||||
|
||||
// Abort if they are registering as a cohort
|
||||
if(GetLocalInt(oPC, "OriginalXP") || GetPersistantLocalInt(oPC, "RegisteringAsCohort"))
|
||||
return;
|
||||
|
||||
// Let them make it to level 3 in peace
|
||||
if(GetTag(GetModule()) == "Prelude")
|
||||
return;
|
||||
|
||||
// And start HotU in peace
|
||||
if(GetTag(GetArea(oPC)) == "q2a_yprooms")
|
||||
return;
|
||||
|
||||
// Abort if they were just relevelled
|
||||
if(GetLocalInt(oPC, "RelevelXP"))
|
||||
{
|
||||
DeleteLocalInt(oPC, "RelevelXP");
|
||||
return;
|
||||
}
|
||||
|
||||
//this is done first because leadership uses it too
|
||||
int iCurXP = GetXP(oPC);
|
||||
//if (DEBUG) DoDebug("ApplyECLToXP - iCurXP "+IntToString(iCurXP));
|
||||
|
||||
int iLastXP = GetPersistantLocalInt(oPC, sXP_AT_LAST_HEARTBEAT);
|
||||
//if (DEBUG) DoDebug("ApplyECLToXP - iLastXP "+IntToString(iLastXP));
|
||||
if(iCurXP > iLastXP)
|
||||
{
|
||||
//if (DEBUG) DoDebug("ApplyECLToXP - gained XP");
|
||||
int iLvlAdj = GetTotalLA(oPC);
|
||||
if(iLvlAdj)
|
||||
{
|
||||
//if (DEBUG) DoDebug("ApplyECLToXP - have LA");
|
||||
int iPCLvl = GetHitDice(oPC);
|
||||
// Get XP Ratio (multiply new XP by this to see what to subtract)
|
||||
float fRealXPToLevel = IntToFloat(GetXPForLevel(iPCLvl+1));
|
||||
float fECLXPToLevel = IntToFloat(GetXPForLevel(iPCLvl+1+iLvlAdj));
|
||||
float fXPRatio = 1.0 - (fRealXPToLevel/fECLXPToLevel);
|
||||
//At this point the ratio is based on total XP
|
||||
//This is not correct, it should be based on the XP required to reach
|
||||
//the next level.
|
||||
//fRealXPToLevel = IntToFloat(iPCLvl*1000);
|
||||
//fECLXPToLevel = IntToFloat((iPCLvl+iLvlAdj)*1000);
|
||||
//fXPRatio = 1.0 - (fRealXPToLevel/fECLXPToLevel);
|
||||
|
||||
float fXPDif = IntToFloat(iCurXP - iLastXP);
|
||||
int iXPDif = FloatToInt(fXPDif * fXPRatio);
|
||||
int newXP = iCurXP - iXPDif;
|
||||
SendMessageToPC(oPC, "XP gained since last heartbeat "+IntToString(FloatToInt(fXPDif)));
|
||||
SendMessageToPC(oPC, "Real XP to level: "+IntToString(FloatToInt(fRealXPToLevel)));
|
||||
SendMessageToPC(oPC, "ECL XP to level: "+IntToString(FloatToInt(fECLXPToLevel)));
|
||||
SendMessageToPC(oPC, "Level Adjustment +"+IntToString(iLvlAdj)+". Reducing XP by " + IntToString(iXPDif));
|
||||
SetXP(oPC, newXP);
|
||||
}
|
||||
}
|
||||
iCurXP = GetXP(oPC);
|
||||
SetPersistantLocalInt(oPC, sXP_AT_LAST_HEARTBEAT, iCurXP);
|
||||
}
|
||||
|
||||
int GetBuyoffCost(object oPC)
|
||||
{
|
||||
int nECL = GetECL(oPC);
|
||||
int nXP = (nECL-1) * 1000;
|
||||
return nXP;
|
||||
}
|
||||
|
||||
void BuyoffLevel(object oPC)
|
||||
{
|
||||
int nECL = GetECL(oPC);
|
||||
int nXP = (nECL-1) * 1000;
|
||||
SetXP(oPC, GetXP(oPC)-nXP);
|
||||
int nBuyoff = GetPersistantLocalInt(oPC, "LA_Buyoff");
|
||||
SetPersistantLocalInt(oPC, "LA_Buyoff", nBuyoff+1);
|
||||
}
|
||||
|
||||
int GetCanBuyoffLA(object oPC)
|
||||
{
|
||||
int nReturn = FALSE;
|
||||
int nBuyoff = GetPersistantLocalInt(oPC, "LA_Buyoff");
|
||||
int nChar = GetHitDice(oPC);
|
||||
int nLA = StringToInt(Get2DACache("ECL", "LA", GetRacialType(oPC))) + GetPersistantLocalInt(oPC, "template_LA");
|
||||
int nCheck = nLA - nBuyoff;
|
||||
if (DEBUG) DoDebug("PRE-LA nBuyoff "+IntToString(nBuyoff)+" nChar "+IntToString(nChar)+" nLA "+IntToString(nLA)+" nCheck "+IntToString(nCheck));
|
||||
if (0 >= nCheck) // no LA
|
||||
return FALSE;
|
||||
|
||||
if (!nBuyoff) // Not purchased anything yet
|
||||
{
|
||||
if (nChar >= StringToInt(Get2DACache("la_buyoff", "1st", nLA)))
|
||||
nReturn = TRUE;
|
||||
}
|
||||
if (nBuyoff == 1) // Purchased first already
|
||||
{
|
||||
if (nChar >= StringToInt(Get2DACache("la_buyoff", "2nd", nLA)))
|
||||
nReturn = TRUE;
|
||||
}
|
||||
if (nBuyoff == 2) // Purchased second already
|
||||
{
|
||||
if (nChar >= StringToInt(Get2DACache("la_buyoff", "3rd", nLA)))
|
||||
nReturn = TRUE;
|
||||
}
|
||||
if (nBuyoff == 3) // Purchased third already
|
||||
{
|
||||
if (nChar >= StringToInt(Get2DACache("la_buyoff", "4th", nLA)))
|
||||
nReturn = TRUE;
|
||||
}
|
||||
if (nBuyoff == 4) // Purchased fourth already
|
||||
{
|
||||
if (nChar >= StringToInt(Get2DACache("la_buyoff", "5th", nLA)))
|
||||
nReturn = TRUE;
|
||||
}
|
||||
if (nBuyoff == 5) // Purchased fifth already
|
||||
{
|
||||
if (nChar >= StringToInt(Get2DACache("la_buyoff", "6th", nLA)))
|
||||
nReturn = TRUE;
|
||||
}
|
||||
if (DEBUG) DoDebug("nReturn "+IntToString(nReturn)+" nBuyoff "+IntToString(nBuyoff)+" nChar "+IntToString(nChar)+" nLA "+IntToString(nLA));
|
||||
|
||||
return nReturn;
|
||||
}
|
BIN
_haks/poa_dev/prc_ai_coh_hb.ncs
Normal file
BIN
_haks/poa_dev/prc_ai_coh_hb.ncs
Normal file
Binary file not shown.
151
_haks/poa_dev/prc_ai_coh_hb.nss
Normal file
151
_haks/poa_dev/prc_ai_coh_hb.nss
Normal file
@@ -0,0 +1,151 @@
|
||||
//Cohort HB script
|
||||
|
||||
#include "prc_alterations"
|
||||
#include "prc_inc_leadersh"
|
||||
void main()
|
||||
{
|
||||
object oCohort = OBJECT_SELF;
|
||||
object oPC = GetMaster(oCohort);
|
||||
object oMaster = GetLocalObject(oCohort, "MasterObject");
|
||||
if(!GetIsObjectValid(oPC) && GetIsObjectValid(oMaster))
|
||||
{
|
||||
//must have become disconnected from master
|
||||
//re-add it as a cohort, but dont re-setup it
|
||||
AddCohortToPlayerByObject(oCohort, oMaster, FALSE);
|
||||
//dont continue this script, allow next HB to kick in instead
|
||||
return;
|
||||
}
|
||||
else if(!GetIsObjectValid(oPC) && !GetIsObjectValid(oMaster))
|
||||
{
|
||||
//master no longer exists
|
||||
RemoveCohortFromPlayer(oCohort, oPC);
|
||||
return;
|
||||
}
|
||||
//if it doesnt have a tag, abort
|
||||
if(GetTag(OBJECT_SELF) == "")
|
||||
return;
|
||||
|
||||
//cohort XP gain
|
||||
//get the amount the PC has gained
|
||||
int XPGained = GetXP(oPC)-GetLocalInt(OBJECT_SELF, "MastersXP");
|
||||
//correct for simple LA XP penalty
|
||||
if(GetPRCSwitch(PRC_XP_USE_SIMPLE_LA))
|
||||
{
|
||||
int iPCLvl = GetHitDice(oPC);
|
||||
int nRace = GetRacialType(oPC);
|
||||
int iLvlAdj = StringToInt(Get2DACache("ECL", "LA", nRace));
|
||||
if(GetPRCSwitch(PRC_XP_INCLUDE_RACIAL_HIT_DIE_IN_LA))
|
||||
iLvlAdj += StringToInt(Get2DACache("ECL", "RaceHD", nRace));
|
||||
float fRealXPToLevel = IntToFloat(GetXPForLevel(iPCLvl+1));
|
||||
float fECLXPToLevel = IntToFloat(GetXPForLevel(iPCLvl+1+iLvlAdj));
|
||||
float fXPRatio = fECLXPToLevel/fRealXPToLevel;
|
||||
XPGained = FloatToInt(IntToFloat(XPGained)*fXPRatio);
|
||||
}
|
||||
//store the amount the PC now has for the next HB
|
||||
SetLocalInt(OBJECT_SELF, "MastersXP", GetXP(oPC));
|
||||
//work out proportion based on relative ECLs
|
||||
int nPCECL = GetECL(oPC);
|
||||
int nCohortECL = GetECL(oCohort);
|
||||
int nCohortLag = GetLocalInt(oCohort, "CohortLevelLag");
|
||||
int nCohortMaxHD = nPCECL-nCohortLag-StringToInt(Get2DACache("ECL", "LA", GetRacialType(oCohort)));
|
||||
if(GetPRCSwitch(PRC_XP_INCLUDE_RACIAL_HIT_DIE_IN_LA))
|
||||
nCohortMaxHD -= StringToInt(Get2DACache("ECL", "RaceHD", GetRacialType(oCohort)));
|
||||
float ECLRatio = IntToFloat(nPCECL)/IntToFloat(nCohortECL);
|
||||
//get the amount to gain
|
||||
int nCohortXPGain = FloatToInt(IntToFloat(XPGained)*ECLRatio);
|
||||
//get the current amount
|
||||
int nCohortXP = GetXP(oCohort);
|
||||
//work out the new amount
|
||||
int nCohortNewXP = nCohortXP+nCohortXPGain;
|
||||
//get the cap based on PC level and cohort LA
|
||||
int nCohortXPCap = ((nCohortMaxHD)*(nCohortMaxHD+1)*500)-1;
|
||||
//this is how much XP the next levelup will be at
|
||||
int nCohortXPLevel = nCohortECL*(nCohortECL+1)*500;
|
||||
//DoDebug("XPGained = "+IntToString(XPGained));
|
||||
//DoDebug("nPCECL = "+IntToString(nPCECL));
|
||||
//DoDebug("nCohortECL = "+IntToString(nCohortECL));
|
||||
//DoDebug("nCohortXPGain = "+IntToString(nCohortXPGain));
|
||||
//DoDebug("nCohortXP = "+IntToString(nCohortXP));
|
||||
//DoDebug("nCohortNewXP = "+IntToString(nCohortNewXP));
|
||||
//DoDebug("nCohortXPCap = "+IntToString(nCohortXPCap));
|
||||
//DoDebug("nCohortXPLevel = "+IntToString(nCohortXPLevel));
|
||||
//apply the cap
|
||||
if(nCohortNewXP > nCohortXPCap)
|
||||
nCohortNewXP = nCohortXPCap;
|
||||
//give the XP
|
||||
SetXP(oCohort, nCohortNewXP);
|
||||
//handle levelup
|
||||
if(nCohortNewXP >= nCohortXPLevel)
|
||||
{
|
||||
//standard
|
||||
if(GetResRef(oCohort) != "")
|
||||
{
|
||||
LevelUpHenchman(oCohort, CLASS_TYPE_INVALID, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
//custom
|
||||
//resummon it but dont decrease XP as much
|
||||
int nCohortID = GetLocalInt(oCohort, "CohortID");
|
||||
|
||||
//Call creation of new cohort
|
||||
object oNewCohort = AddCohortToPlayer(nCohortID, oPC);
|
||||
object oTest;
|
||||
//copy its equipment & inventory
|
||||
// object oTest = GetFirstItemInInventory(oCohort);
|
||||
// while(GetIsObjectValid(oTest))
|
||||
// {
|
||||
// if(!GetLocalInt(oTest, "CohortCopied"))
|
||||
// object oNewTest = CopyItem(oTest, oNewCohort, TRUE);
|
||||
// SetLocalInt(oTest, "CohortCopied", TRUE);
|
||||
// DestroyObject(oTest, 0.01);
|
||||
// oTest = GetNextItemInInventory(oCohort);
|
||||
//}
|
||||
|
||||
//Delete new cohorts items (todo: prevent having them added in first place)
|
||||
object currItem = GetFirstItemInInventory(oNewCohort);
|
||||
while(GetIsObjectValid(currItem)){
|
||||
DestroyObject(currItem, 0.01);
|
||||
currItem = GetNextItemInInventory(oNewCohort);
|
||||
}
|
||||
|
||||
//Copy Inventory Items
|
||||
currItem = GetFirstItemInInventory(oCohort);
|
||||
while(GetIsObjectValid(currItem)){
|
||||
CopyItem(currItem,oNewCohort,TRUE);
|
||||
DestroyObject(currItem, 0.01);
|
||||
currItem = GetNextItemInInventory(oCohort);
|
||||
}
|
||||
|
||||
//Copy Equiped items (todo: fix equipping)
|
||||
int nSlot;
|
||||
for(nSlot = 0;nSlot<14;nSlot++)
|
||||
{
|
||||
oTest = GetItemInSlot(nSlot, OBJECT_SELF);
|
||||
object oTest2 = CopyItem(oTest, oNewCohort, TRUE);
|
||||
//currently isn't equiping it
|
||||
AssignCommand(oNewCohort, ClearAllActions());
|
||||
AssignCommand(oNewCohort, ActionEquipItem(oTest2, nSlot));
|
||||
DestroyObject(oTest, 0.01);
|
||||
}
|
||||
|
||||
//destroy old cohort
|
||||
SetIsDestroyable(TRUE, FALSE, FALSE);
|
||||
DestroyObject(OBJECT_SELF, 0.1);
|
||||
}
|
||||
}/*
|
||||
|
||||
//and now for some intelligence to the AI
|
||||
//if you have a familiar, summon it
|
||||
if(GetHasFeat(FEAT_SUMMON_FAMILIAR, oCohort)
|
||||
//&& !GetIsObjectValid(GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oCohort))
|
||||
)
|
||||
ActionUseFeat(FEAT_SUMMON_FAMILIAR, oCohort);
|
||||
//SummonFamiliar(oCohort);
|
||||
//if you have an animal companion, summon it
|
||||
if(GetHasFeat(FEAT_ANIMAL_COMPANION, oCohort)
|
||||
//&& !GetIsObjectValid(GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oCohort))
|
||||
)
|
||||
ActionUseFeat(FEAT_ANIMAL_COMPANION, oCohort);
|
||||
//SummonAnimalCompanion(oCohort);*/
|
||||
}
|
BIN
_haks/poa_dev/prc_cohort_convo.ncs
Normal file
BIN
_haks/poa_dev/prc_cohort_convo.ncs
Normal file
Binary file not shown.
1081
_haks/poa_dev/prc_cohort_convo.nss
Normal file
1081
_haks/poa_dev/prc_cohort_convo.nss
Normal file
File diff suppressed because it is too large
Load Diff
BIN
_haks/poa_dev/prc_enforce_feat.ncs
Normal file
BIN
_haks/poa_dev/prc_enforce_feat.ncs
Normal file
Binary file not shown.
2594
_haks/poa_dev/prc_enforce_feat.nss
Normal file
2594
_haks/poa_dev/prc_enforce_feat.nss
Normal file
File diff suppressed because it is too large
Load Diff
BIN
_haks/poa_dev/prc_ondeath.ncs
Normal file
BIN
_haks/poa_dev/prc_ondeath.ncs
Normal file
Binary file not shown.
141
_haks/poa_dev/prc_ondeath.nss
Normal file
141
_haks/poa_dev/prc_ondeath.nss
Normal file
@@ -0,0 +1,141 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: OnPlayerDeath eventscript
|
||||
//:: prc_ondeath
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This is also triggered by the NPC OnDeath event.
|
||||
*/
|
||||
|
||||
#include "prc_inc_combat"
|
||||
#include "psi_inc_psifunc"
|
||||
#include "inc_ecl"
|
||||
#include "prc_inc_assoc"
|
||||
|
||||
void PreyOnTheWeak(object oDead)
|
||||
{
|
||||
float fRange = FeetToMeters(10.0);
|
||||
|
||||
int i = 1;
|
||||
object oPrey = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oDead, i, CREATURE_TYPE_IS_ALIVE, TRUE);
|
||||
while(GetIsObjectValid(oPrey) && GetDistanceBetween(oPrey, oDead) < fRange)
|
||||
{
|
||||
if(GetHasSpellEffect(MOVE_TC_PREY_ON_THE_WEAK, oPrey))
|
||||
{
|
||||
if(!GetLocalInt(oPrey, "PRC_POTW_HAS_ATTACKED"))
|
||||
{
|
||||
//GetNearestEnemy
|
||||
object oAoOTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oPrey, 1, CREATURE_TYPE_IS_ALIVE, TRUE);
|
||||
if(GetIsObjectValid(oAoOTarget) && GetDistanceBetween(oPrey, oAoOTarget) < fRange)
|
||||
{
|
||||
effect eNone;
|
||||
object oWeap = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPrey);
|
||||
//SetLocalInt
|
||||
SetLocalInt(oPrey, "PRC_POTW_HAS_ATTACKED", 1);
|
||||
|
||||
PerformAttack(oAoOTarget, oPrey, eNone, 0.0, 0, 0, GetWeaponDamageType(oWeap), "Prey on the Weak Hit", "Prey on the Weak Miss");
|
||||
|
||||
//Set up removal
|
||||
DelayCommand(RoundsToSeconds(1), DeleteLocalInt(oPrey, "PRC_POTW_HAS_ATTACKED"));
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
oPrey = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oDead, i, CREATURE_TYPE_IS_ALIVE, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
object oDead = GetLastBeingDied();
|
||||
object oKiller = MyGetLastKiller();
|
||||
|
||||
// We are not actually dead until -10
|
||||
// Unless it's a spell death
|
||||
|
||||
//int nHP = GetCurrentHitPoints(oDead);
|
||||
//if ((nHP >= -9) || (GetLocalInt(oTarget, "PRC_PNP_EfectDeathApplied"))
|
||||
// return;
|
||||
|
||||
|
||||
// Unsummon familiar/animal companions
|
||||
DelayCommand(0.1f, UnsummonCompanions(oDead));
|
||||
|
||||
// Clear a damage tracking variable. Oni's stuff uses this
|
||||
SetLocalInt(oDead, "PC_Damage", 0);
|
||||
|
||||
// Do Lolth's Meat for the killer
|
||||
if(GetAbilityScore(oDead, ABILITY_INTELLIGENCE) >= 4 && GetHasFeat(FEAT_LOLTHS_MEAT, oKiller))
|
||||
{
|
||||
/*effect eLink = EffectSavingThrowIncrease(SAVING_THROW_ALL, 1, SAVING_THROW_TYPE_ALL);
|
||||
eLink = EffectLinkEffects(eLink, EffectAttackIncrease(1, ATTACK_BONUS_MISC));
|
||||
eLink = EffectLinkEffects(eLink, EffectDamageIncrease(DAMAGE_BONUS_1, DAMAGE_TYPE_DIVINE));
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oKiller, RoundsToSeconds(5));
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_EVIL_HELP), oKiller);*/
|
||||
ExecuteScript("prc_lolthmeat", oKiller);
|
||||
}
|
||||
|
||||
// Do Mind Cleave feat
|
||||
if(GetHasFeat(FEAT_MIND_CLEAVE, oKiller))
|
||||
{
|
||||
SetLocalInt(oKiller, "MindCleave", TRUE);
|
||||
ExecuteScript("psi_sk_psychsrtk", oKiller);
|
||||
DelayCommand(0.25, DeleteLocalInt(oKiller, "MindCleave"));
|
||||
}
|
||||
|
||||
// Do Merciless Purity from Shadowbane Inq
|
||||
if(GetLocalInt(oDead, "MercilessPurity") && GetIsObjectValid(GetLocalObject(oDead, "Shadowbane")))
|
||||
{
|
||||
object oShadow = GetLocalObject(oDead, "Shadowbane");
|
||||
effect eLink = EffectSavingThrowIncrease(SAVING_THROW_FORT, 1, SAVING_THROW_TYPE_ALL);
|
||||
eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_REFLEX, 1, SAVING_THROW_TYPE_ALL));
|
||||
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oShadow, HoursToSeconds(24));
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_GOOD_HELP), oShadow);
|
||||
if (DEBUG) FloatingTextStringOnCreature("Merciless Purity activated", oShadow, FALSE);
|
||||
}
|
||||
|
||||
if(GetPRCSwitch(PRC_XP_USE_PNP_XP))
|
||||
{
|
||||
if(GetObjectType(oKiller) == OBJECT_TYPE_TRIGGER)
|
||||
oKiller = GetTrapCreator(oKiller);
|
||||
if(oKiller != oDead
|
||||
&& GetIsObjectValid(oKiller)
|
||||
&& !GetIsFriend(oKiller, oDead)
|
||||
&& (GetIsObjectValid(GetFirstFactionMember(oKiller, TRUE))
|
||||
|| GetPRCSwitch(PRC_XP_GIVE_XP_TO_NON_PC_FACTIONS)))
|
||||
{
|
||||
GiveXPRewardToParty(oKiller, oDead);
|
||||
|
||||
/* Not needed as we now disabled the bioware system if this is enabled
|
||||
*
|
||||
//bypass bioware XP system
|
||||
//AssignCommand(oDead, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), oDead));
|
||||
SetLocalInt(oDead, "PRC_PNP_XP_DEATH", 1);
|
||||
//AssignCommand(oDead, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(10000, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY), oDead));
|
||||
AssignCommand(oDead, ApplyEffectToObject(DURATION_TYPE_INSTANT, SupernaturalEffect(EffectDeath()), oDead));
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
// Prey on the Weak
|
||||
PreyOnTheWeak(oDead);
|
||||
|
||||
if(GetPRCSwitch(PRC_PW_DEATH_TRACKING) && GetIsPC(oDead))
|
||||
SetPersistantLocalInt(oDead, "persist_dead", TRUE);
|
||||
|
||||
// Psionic creatures lose all PP on death
|
||||
if(GetIsPsionicCharacter(oDead))
|
||||
LoseAllPowerPoints(oDead, TRUE);
|
||||
|
||||
DeleteLocalInt(oDead, "PRC_SPELL_CHARGE_COUNT");
|
||||
DeleteLocalInt(oDead, "PRC_SPELL_HOLD");
|
||||
|
||||
// Trigger the death/bleed if the PRC Death system is enabled (ElgarL).
|
||||
if((GetPRCSwitch(PRC_PNP_DEATH_ENABLE)) && GetIsPC(oDead))
|
||||
AddEventScript(oDead, EVENT_ONHEARTBEAT, "prc_timer_dying", TRUE, FALSE);
|
||||
|
||||
// Execute scripts hooked to this event for the player triggering it
|
||||
ExecuteAllScriptsHookedToEvent(oDead, EVENT_ONPLAYERDEATH);
|
||||
}
|
||||
|
BIN
_haks/poa_dev/prc_onenter.ncs
Normal file
BIN
_haks/poa_dev/prc_onenter.ncs
Normal file
Binary file not shown.
405
_haks/poa_dev/prc_onenter.nss
Normal file
405
_haks/poa_dev/prc_onenter.nss
Normal file
@@ -0,0 +1,405 @@
|
||||
//:: Updated for .35 by Jaysyn 2023/03/11
|
||||
|
||||
#include "inc_leto_prc"
|
||||
#include "x2_inc_switches"
|
||||
#include "prc_inc_teleport"
|
||||
#include "prc_inc_leadersh"
|
||||
#include "prc_inc_domain"
|
||||
#include "prc_inc_shifting"
|
||||
#include "true_inc_trufunc"
|
||||
#include "prc_craft_inc"
|
||||
#include "prc_inc_dragsham"
|
||||
#include "shd_inc_myst"
|
||||
#include "prc_inc_template"
|
||||
|
||||
/**
|
||||
* Reads the 2da file onenter_locals.2da and sets local variables
|
||||
* on the entering PC accordingly. 2da format same as personal_switches.2da,
|
||||
* see prc_inc_switches header comment for details.
|
||||
*
|
||||
* @param oPC The PC that just entered the module
|
||||
*/
|
||||
void DoAutoLocals(object oPC)
|
||||
{
|
||||
int i = 0;
|
||||
string sSwitchName, sSwitchType, sSwitchValue;
|
||||
// Use Get2DAString() instead of Get2DACache() to avoid caching.
|
||||
while((sSwitchName = Get2DAString("onenter_locals", "SwitchName", i)) != "")
|
||||
{
|
||||
// Read rest of the line
|
||||
sSwitchType = Get2DAString("onenter_locals", "SwitchType", i);
|
||||
sSwitchValue = Get2DAString("onenter_locals", "SwitchValue", i);
|
||||
|
||||
// Determine switch type and set the var
|
||||
if (sSwitchType == "float")
|
||||
SetLocalFloat(oPC, sSwitchName, StringToFloat(sSwitchValue));
|
||||
else if(sSwitchType == "int")
|
||||
SetLocalInt(oPC, sSwitchName, StringToInt(sSwitchValue));
|
||||
else if(sSwitchType == "string")
|
||||
SetLocalString(oPC, sSwitchName, sSwitchValue);
|
||||
|
||||
// Increment loop counter
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
//Restore appearance
|
||||
void RestoreAppearance(object oCreature)
|
||||
{
|
||||
if(!RestoreTrueAppearance(oCreature) && DEBUG)
|
||||
DoDebug("prc_onenter: RestoreAppearance failed");
|
||||
}
|
||||
|
||||
void CopyAMSArray(object oHideToken, object oAMSToken, int nClass, string sArray, int nMin, int nMax, int nLoopSize = 100)
|
||||
{
|
||||
int i = nMin;
|
||||
while(i < nMin + nLoopSize && i < nMax)
|
||||
{
|
||||
int nSpell = array_get_int(oAMSToken, sArray, i);
|
||||
int nSpellbookID = RealSpellToSpellbookID(nClass, nSpell);
|
||||
if(nSpellbookID)
|
||||
array_set_int(oHideToken, sArray, i, nSpellbookID);
|
||||
i++;
|
||||
}
|
||||
if(i < nMax)
|
||||
DelayCommand(0.0, CopyAMSArray(oHideToken, oAMSToken, nClass, sArray, i, nMax));
|
||||
}
|
||||
|
||||
void DoRestoreAMS(object oPC, int nClass, object oHideToken, object oAMSToken)
|
||||
{
|
||||
string sSpellbook;
|
||||
int nSpellbookType = GetSpellbookTypeForClass(nClass);
|
||||
if(nSpellbookType == SPELLBOOK_TYPE_SPONTANEOUS)
|
||||
{
|
||||
sSpellbook = "Spellbook"+IntToString(nClass);
|
||||
if(DEBUG) DoDebug("DoRestoreAMS: "+sSpellbook);
|
||||
if(persistant_array_exists(oPC, sSpellbook))
|
||||
array_delete(oHideToken, sSpellbook);
|
||||
array_create(oHideToken, sSpellbook);
|
||||
int nSize = array_get_size(oAMSToken, sSpellbook);
|
||||
if(DEBUG) DoDebug("DoRestoreAMS: array size = "+IntToString(nSize));
|
||||
if(nSize)
|
||||
DelayCommand(0.0, CopyAMSArray(oHideToken, oAMSToken, nClass, sSpellbook, 0, nSize));
|
||||
}
|
||||
else if(nSpellbookType == SPELLBOOK_TYPE_PREPARED)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i <= 9; i++)
|
||||
{
|
||||
sSpellbook = "Spellbook_Known_"+IntToString(nClass)+"_"+IntToString(i);
|
||||
if(DEBUG) DoDebug("DoRestoreAMS: "+sSpellbook);
|
||||
if(array_exists(oHideToken, sSpellbook))
|
||||
array_delete(oHideToken, sSpellbook);
|
||||
array_create(oHideToken, sSpellbook);
|
||||
int nSize = array_get_size(oAMSToken, sSpellbook);
|
||||
if(DEBUG) DoDebug("DoRestoreAMS: array size = "+IntToString(nSize));
|
||||
if(nSize)
|
||||
DelayCommand(0.0, CopyAMSArray(oHideToken, oAMSToken, nClass, sSpellbook, 0, nSize));
|
||||
array_delete(oHideToken, "Spellbook"+IntToString(i)+"_"+IntToString(nClass));
|
||||
array_delete(oHideToken, "NewSpellbookMem_"+IntToString(nClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnter_AMSCompatibilityCheck(object oPC)
|
||||
{
|
||||
object oAMSToken = GetHideToken(oPC, TRUE);
|
||||
object oHideToken = GetHideToken(oPC);
|
||||
|
||||
//check PRC version
|
||||
string sVersion = GetLocalString(oAMSToken, "ams_version");
|
||||
//DoDebug("AMS version = "+sVersion);
|
||||
if(sVersion != AMS_VERSION)
|
||||
{
|
||||
SetLocalInt(oPC, "AMS_RESTORE", 1);
|
||||
int i;
|
||||
for(i = 1; i <= 8; i++)
|
||||
{
|
||||
int nClass = GetClassByPosition(i, oPC);
|
||||
DelayCommand(0.2, DoRestoreAMS(oPC, nClass, oHideToken, oAMSToken));
|
||||
}
|
||||
DelayCommand(2.0, WipeSpellbookHideFeats(oPC));
|
||||
SetLocalString(oAMSToken, "ams_version", AMS_VERSION);
|
||||
DelayCommand(5.0, DeleteLocalInt(oPC, "AMS_RESTORE"));
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
//The composite properties system gets confused when an exported
|
||||
//character re-enters. Local Variables are lost and most properties
|
||||
//get re-added, sometimes resulting in larger than normal bonuses.
|
||||
//The only real solution is to wipe the skin on entry. This will
|
||||
//mess up the lich, but only until I hook it into the EvalPRC event -
|
||||
//hopefully in the next update
|
||||
// -Aaon Graywolf
|
||||
object oPC = GetEnteringObject();
|
||||
|
||||
//FloatingTextStringOnCreature("PRC on enter was called", oPC, FALSE);
|
||||
|
||||
// Since OnEnter event fires for the PC when loading a saved game (no idea why,
|
||||
// since it makes saving and reloading change the state of the module),
|
||||
// make sure that the event gets run only once
|
||||
// but not in MP games, so check if it's single player or not!!
|
||||
if(GetLocalInt(oPC, "PRC_ModuleOnEnterDone") && (GetPCPublicCDKey(oPC) == ""))
|
||||
return;
|
||||
// Use a local integer to mark the event as done for the PC, so that it gets
|
||||
// cleared when the character is saved.
|
||||
else
|
||||
SetLocalInt(oPC, "PRC_ModuleOnEnterDone", TRUE);
|
||||
|
||||
//if server is loading, boot player
|
||||
if(GetLocalInt(GetModule(), PRC_PW_LOGON_DELAY+"_TIMER"))
|
||||
{
|
||||
BootPC(oPC);
|
||||
return;
|
||||
}
|
||||
|
||||
DoDebug("Running modified prc_onenter with PW CD check");
|
||||
// Verify players CD key
|
||||
if(GetPRCSwitch(PRC_PW_SECURITY_CD_CHECK))
|
||||
{
|
||||
DoDebug("PRC_PW_SECURITY_CD_CHECK switch set on the module");
|
||||
if(ExecuteScriptAndReturnInt("prc_onenter_cd", oPC))
|
||||
return;
|
||||
}
|
||||
DoDebug("CD-check OK - continue executing prc_onenter");
|
||||
|
||||
|
||||
// Prevent Items on area creation from trigering the GetPCSkin script
|
||||
if (GetObjectType(oPC) != OBJECT_TYPE_CREATURE)
|
||||
return;
|
||||
|
||||
// return here for DMs as they don't need all this stuff
|
||||
if(GetIsDM(oPC))
|
||||
return;
|
||||
|
||||
// Setup class info for EvalPRCFeats()
|
||||
SetupCharacterData(oPC);
|
||||
|
||||
//do this first so other things dont interfere with it
|
||||
if(GetPRCSwitch(PRC_USE_LETOSCRIPT))
|
||||
LetoPCEnter(oPC);
|
||||
if(GetPRCSwitch(PRC_CONVOCC_ENABLE) && !GetPRCSwitch(PRC_CONVOCC_CUSTOM_START_LOCATION) && ExecuteScriptAndReturnInt("prc_ccc_main", OBJECT_SELF))
|
||||
return;
|
||||
|
||||
// ebonfowl: taking a risk here and commenting this out, it seems obsolete and it is very hard to fix without having an AMS token
|
||||
//check spellbooks for compatibility with other PRC versions
|
||||
//DelayCommand(10.0f, OnEnter_AMSCompatibilityCheck(oPC));
|
||||
|
||||
object oSkin = GetPCSkin(oPC);
|
||||
ScrubPCSkin(oPC, oSkin);
|
||||
DeletePRCLocalInts(oSkin);
|
||||
|
||||
// Gives people the proper spells from their bonus domains
|
||||
// This should run before EvalPRCFeats, because it sets a variable
|
||||
DelayCommand(0.0, CheckBonusDomains(oPC));
|
||||
// Set the uses per day for domains
|
||||
DelayCommand(0.0, BonusDomainRest(oPC));
|
||||
// Clear old variables for AMS
|
||||
DelayCommand(0.0, ClearLawLocalVars(oPC));
|
||||
DelayCommand(0.0, ClearMystLocalVars(oPC));
|
||||
DelayCommand(0.0, ClearLegacyUses(oPC));
|
||||
DelayCommand(0.0, DeleteLocalInt(oPC, "RestTimer"));
|
||||
|
||||
//remove effects from hides, can stack otherwise
|
||||
effect eTest=GetFirstEffect(oPC);
|
||||
|
||||
while (GetIsEffectValid(eTest))
|
||||
{
|
||||
if(GetEffectSubType(eTest) == SUBTYPE_SUPERNATURAL
|
||||
&& (GetEffectType(eTest) == EFFECT_TYPE_MOVEMENT_SPEED_DECREASE
|
||||
|| GetEffectType(eTest) == EFFECT_TYPE_MOVEMENT_SPEED_INCREASE
|
||||
//add other types here
|
||||
)
|
||||
&& !GetIsObjectValid(GetEffectCreator(eTest))
|
||||
)
|
||||
RemoveEffect(oPC, eTest);
|
||||
eTest=GetNextEffect(oPC);
|
||||
}
|
||||
|
||||
SetLocalInt(oPC,"ONENTER",1);
|
||||
// Make sure we reapply any bonuses before the player notices they are gone.
|
||||
DelayCommand(0.1, EvalPRCFeats(oPC));
|
||||
DelayCommand(0.1, FeatSpecialUsePerDay(oPC));
|
||||
// Check to see which special prc requirements (i.e. those that can't be done)
|
||||
// through the .2da's, the entering player already meets.
|
||||
ExecuteScript("prc_prereq", oPC);
|
||||
ExecuteScript("prc_psi_ppoints", oPC);
|
||||
ResetTouchOfVitality(oPC);
|
||||
DelayCommand(0.15, DeleteLocalInt(oPC,"ONENTER"));
|
||||
|
||||
if(GetPRCSwitch(PRC_LETOSCRIPT_FIX_ABILITIES) && !GetIsDM(oPC))
|
||||
PRCLetoEnter(oPC);
|
||||
|
||||
//PW tracking starts here
|
||||
|
||||
if(GetPRCSwitch(PRC_PNP_DEATH_ENABLE))
|
||||
{
|
||||
//cleanup.
|
||||
int nStatus = GetPersistantLocalInt(oPC, "STATUS");
|
||||
if (nStatus != ALIVE)
|
||||
AddEventScript(oPC, EVENT_ONHEARTBEAT, "prc_timer_dying", TRUE, FALSE);
|
||||
// Make us fall over if we should be on the floor.
|
||||
if (nStatus == BLEEDING || STABLE || DEAD)
|
||||
AssignCommand(oPC, DelayCommand(0.03, PlayAnimation(ANIMATION_LOOPING_DEAD_BACK, 1.0, 4.0)));
|
||||
// If PRC Death is enabled we require HP tracking too
|
||||
SetPRCSwitch(PRC_PW_HP_TRACKING, TRUE);
|
||||
}
|
||||
if(GetPRCSwitch(PRC_PW_HP_TRACKING))
|
||||
{
|
||||
// Make sure we actually have stored HP data to read
|
||||
if(GetPersistantLocalInt(oPC, "persist_HP_stored") == -1)
|
||||
{
|
||||
// Read the stored level and set accordingly.
|
||||
int nHP = GetPersistantLocalInt(oPC, "persist_HP");
|
||||
int nDamage = GetCurrentHitPoints(oPC)-nHP;
|
||||
|
||||
if (nDamage >= 1) ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL), oPC);
|
||||
}
|
||||
|
||||
}
|
||||
if(GetPRCSwitch(PRC_PW_TIME))
|
||||
{
|
||||
struct time tTime = GetPersistantLocalTime(oPC, "persist_Time");
|
||||
//first pc logging on
|
||||
if(GetIsObjectValid(GetFirstPC())
|
||||
&& !GetIsObjectValid(GetNextPC()))
|
||||
{
|
||||
SetTimeAndDate(tTime);
|
||||
}
|
||||
RecalculateTime();
|
||||
}
|
||||
if(GetPRCSwitch(PRC_PW_LOCATION_TRACKING))
|
||||
{
|
||||
struct metalocation lLoc = GetPersistantLocalMetalocation(oPC, "persist_loc");
|
||||
DelayCommand(6.0, AssignCommand(oPC, JumpToLocation(MetalocationToLocation(lLoc))));
|
||||
}
|
||||
if(GetPRCSwitch(PRC_PW_MAPPIN_TRACKING)
|
||||
&& !GetLocalInt(oPC, "PRC_PW_MAPPIN_TRACKING_Done"))
|
||||
{
|
||||
//this local is set so that this is only done once per server session
|
||||
SetLocalInt(oPC, "PRC_PW_MAPPIN_TRACKING_Done", TRUE);
|
||||
int nCount = GetPersistantLocalInt(oPC, "MapPinCount");
|
||||
int i;
|
||||
for(i=1; i<=nCount; i++)
|
||||
{
|
||||
struct metalocation mlocLoc = GetPersistantLocalMetalocation(oPC, "MapPin_"+IntToString(i));
|
||||
CreateMapPinFromMetalocation(mlocLoc, oPC);
|
||||
}
|
||||
}
|
||||
if(GetPRCSwitch(PRC_PW_DEATH_TRACKING))
|
||||
{
|
||||
if(GetPersistantLocalInt(oPC, "persist_dead"))
|
||||
{
|
||||
int nDamage=9999;
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(DAMAGE_TYPE_MAGICAL, nDamage), oPC);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oPC);
|
||||
}
|
||||
}
|
||||
if(GetPRCSwitch(PRC_PW_SPELL_TRACKING))
|
||||
{
|
||||
string sSpellList = GetPersistantLocalString(oPC, "persist_spells");
|
||||
string sTest;
|
||||
string sChar;
|
||||
while(GetStringLength(sSpellList))
|
||||
{
|
||||
sChar = GetStringLeft(sSpellList,1);
|
||||
if(sChar == "|")
|
||||
{
|
||||
int nSpell = StringToInt(sTest);
|
||||
DecrementRemainingSpellUses(oPC, nSpell);
|
||||
sTest == "";
|
||||
}
|
||||
else
|
||||
sTest += sChar;
|
||||
sSpellList = GetStringRight(sSpellList, GetStringLength(sSpellList)-1);
|
||||
}
|
||||
}
|
||||
//check for persistant golems
|
||||
if(persistant_array_exists(oPC, "GolemList"))
|
||||
{
|
||||
MultisummonPreSummon(oPC, TRUE);
|
||||
int i;
|
||||
for(i=1;i<persistant_array_get_size(oPC, "GolemList");i++)
|
||||
{
|
||||
string sResRef = persistant_array_get_string(oPC, "GolemList",i);
|
||||
effect eSummon = SupernaturalEffect(EffectSummonCreature(sResRef));
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSummon, oPC);
|
||||
}
|
||||
}
|
||||
|
||||
if(GetPRCSwitch(PRC_PNP_ANIMATE_DEAD) || GetPRCSwitch(PRC_MULTISUMMON))
|
||||
{
|
||||
MultisummonPreSummon(oPC, TRUE);
|
||||
}
|
||||
|
||||
// Create map pins from marked teleport locations if the PC has requested that such be done.
|
||||
if(GetLocalInt(oPC, PRC_TELEPORT_CREATE_MAP_PINS))
|
||||
DelayCommand(10.0f, TeleportLocationsToMapPins(oPC));
|
||||
|
||||
if(GetPRCSwitch(PRC_XP_USE_SIMPLE_RACIAL_HD)
|
||||
&& !GetXP(oPC))
|
||||
{
|
||||
int nRealRace = GetRacialType(oPC);
|
||||
int nRacialHD = StringToInt(Get2DACache("ECL", "RaceHD", nRealRace));
|
||||
int nRacialClass = StringToInt(Get2DACache("ECL", "RaceClass", nRealRace));
|
||||
if(nRacialHD)
|
||||
{
|
||||
if(!GetPRCSwitch(PRC_XP_USE_SIMPLE_RACIAL_HD_NO_FREE_XP))
|
||||
{
|
||||
int nNewXP = nRacialHD*(nRacialHD+1)*500; //+1 for the original class level
|
||||
SetXP(oPC, nNewXP);
|
||||
if(GetPRCSwitch(PRC_XP_USE_SIMPLE_LA))
|
||||
DelayCommand(1.0, SetPersistantLocalInt(oPC, sXP_AT_LAST_HEARTBEAT, nNewXP));
|
||||
}
|
||||
if(GetPRCSwitch(PRC_XP_USE_SIMPLE_RACIAL_HD_NO_SELECTION))
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<nRacialHD;i++)
|
||||
{
|
||||
LevelUpHenchman(oPC, nRacialClass, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert various debug things here
|
||||
if(DEBUG)
|
||||
{
|
||||
// Duplicate PRCItemPropertyBonusFeat monitor
|
||||
SpawnNewThread("PRC_Duplicate_IPBFeat_Mon", "prc_debug_hfeatm", 30.0f, oPC);
|
||||
}
|
||||
|
||||
if(GetHasFeat(FEAT_SPELLFIRE_WIELDER, oPC))
|
||||
SpawnNewThread("PRC_Spellfire", "prc_spellfire_hb", 6.0f, oPC);
|
||||
|
||||
//if the player logged off while being registered as a cohort
|
||||
if(GetPersistantLocalInt(oPC, "RegisteringAsCohort"))
|
||||
AssignCommand(GetModule(), CheckHB(oPC));
|
||||
|
||||
// If the PC logs in shifted, unshift them
|
||||
if(GetPersistantLocalInt(oPC, SHIFTER_ISSHIFTED_MARKER))
|
||||
UnShift(oPC);
|
||||
if(GetPRCSwitch(PRC_ON_ENTER_RESTORE_APPEARANCE))
|
||||
DelayCommand(2.0f, RestoreAppearance(oPC));
|
||||
|
||||
// Set up local variables based on a 2da file
|
||||
DelayCommand(1.0 ,DoAutoLocals(oPC));
|
||||
|
||||
ExecuteScript("tob_evnt_recover", oPC);
|
||||
|
||||
// This prevents the LA function from eating XP on login
|
||||
SetLocalInt(oPC, "PRC_ECL_Delay", TRUE);
|
||||
SetPersistantLocalInt(oPC, sXP_AT_LAST_HEARTBEAT, GetXP(oPC));
|
||||
DelayCommand(10.0, DeleteLocalInt(oPC, "PRC_ECL_Delay"));
|
||||
|
||||
// Execute scripts hooked to this event for the player triggering it
|
||||
//How can this work? The PC isnt a valid object before this. - Primogenitor
|
||||
//Some stuff may have gone "When this PC next logs in, run script X" - Ornedan
|
||||
ExecuteAllScriptsHookedToEvent(oPC, EVENT_ONCLIENTENTER);
|
||||
|
||||
// Start the PC HeartBeat for PC's
|
||||
if(GetIsPC(oPC))
|
||||
AssignCommand(GetModule(), ExecuteScript("prc_onhb_indiv", oPC));
|
||||
}
|
BIN
_haks/poa_dev/prc_onhb_indiv.ncs
Normal file
BIN
_haks/poa_dev/prc_onhb_indiv.ncs
Normal file
Binary file not shown.
139
_haks/poa_dev/prc_onhb_indiv.nss
Normal file
139
_haks/poa_dev/prc_onhb_indiv.nss
Normal file
@@ -0,0 +1,139 @@
|
||||
/** @file prc_onhb_indiv
|
||||
|
||||
Invidual Heartbeat event
|
||||
|
||||
This script is run every heartbeat for every PC via the prc_onheartbeat event
|
||||
This script is run every heartbeat for every NPC via the prc_npc_hb event
|
||||
|
||||
Its main purposes is to provide a unified individual hb script interface
|
||||
Slighly less efficient because things like switches are checked for each individual.
|
||||
|
||||
*/
|
||||
|
||||
#include "prc_alterations"
|
||||
#include "prc_inc_nat_hb"
|
||||
#include "inc_ecl"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oPC = OBJECT_SELF;
|
||||
|
||||
// HB code removed from the Module OnHeartbeat (ElgarL)
|
||||
// This is now executed as a delayed timer when the player logs in.
|
||||
|
||||
if(!GetIsObjectValid(oPC))
|
||||
return;
|
||||
|
||||
// no running stuff for DMs or NPC's
|
||||
if((!GetIsDM(oPC)) && (GetIsPC(oPC)))
|
||||
{
|
||||
int bPWPCAutoexport = GetPRCSwitch(PRC_PW_PC_AUTOEXPORT);
|
||||
|
||||
// Persistent World time tracking
|
||||
if(GetPRCSwitch(PRC_PW_TIME))
|
||||
{
|
||||
//store it on all PCs separately
|
||||
SetPersistantLocalTime(oPC, "persist_Time", GetTimeAndDate());
|
||||
}
|
||||
// Automatic character export every 6n seconds
|
||||
// Check the counter to see if it is time to export
|
||||
if(bPWPCAutoexport)
|
||||
{
|
||||
int nCount = GetLocalInt(oPC, "AutoexportCount");
|
||||
if(nCount == bPWPCAutoexport)
|
||||
DeleteLocalInt(oPC, "AutoexportCount");
|
||||
else
|
||||
{
|
||||
nCount++;
|
||||
SetLocalInt(oPC, "AutoexportCount", nCount);
|
||||
bPWPCAutoexport = FALSE;
|
||||
}
|
||||
}
|
||||
// Export if the counter has run down
|
||||
if(bPWPCAutoexport)
|
||||
{
|
||||
if(!GetIsPolyMorphedOrShifted(oPC))
|
||||
ExportSingleCharacter(oPC);
|
||||
}
|
||||
// Persistant hit point tracking
|
||||
if(GetPRCSwitch(PRC_PW_HP_TRACKING))
|
||||
{
|
||||
//Flag that we have saved the HP as testing for Zero is faulty logic
|
||||
//
|
||||
SetPersistantLocalInt(oPC, "persist_HP_stored", -1);
|
||||
// Now store the current HP.
|
||||
SetPersistantLocalInt(oPC, "persist_HP", GetCurrentHitPoints(oPC));
|
||||
}
|
||||
// Persistant location tracking
|
||||
if(GetPRCSwitch(PRC_PW_LOCATION_TRACKING) && GetStartingLocation() != GetLocation(oPC))
|
||||
SetPersistantLocalMetalocation(oPC, "persist_loc", LocationToMetalocation(GetLocation(oPC)));
|
||||
// Persistant map pin tracking
|
||||
if(GetPRCSwitch(PRC_PW_MAPPIN_TRACKING))
|
||||
{
|
||||
int i;
|
||||
int nMapPinCount = GetNumberOfMapPins(oPC);
|
||||
struct metalocation mLoc;
|
||||
for(i = 1; i <= nMapPinCount; i++)
|
||||
{
|
||||
mLoc = CreateMetalocationFromMapPin(oPC, i);
|
||||
SetPersistantLocalMetalocation(oPC, "MapPin_" + IntToString(i), mLoc);
|
||||
}
|
||||
SetPersistantLocalInt(oPC, "MapPinCount", nMapPinCount);
|
||||
}
|
||||
|
||||
// Death - Bleed - ElgarL
|
||||
if(GetPRCSwitch(PRC_PNP_DEATH_ENABLE))
|
||||
{
|
||||
// PC doing anything that requires attention while disabled take damage
|
||||
if(GetPersistantLocalInt(oPC, "STATUS") == 3)
|
||||
{
|
||||
int nAction = GetCurrentAction(oPC);
|
||||
if(nAction == ACTION_DISABLETRAP || nAction == ACTION_TAUNT
|
||||
|| nAction == ACTION_PICKPOCKET || nAction == ACTION_ATTACKOBJECT
|
||||
|| nAction == ACTION_COUNTERSPELL || nAction == ACTION_FLAGTRAP
|
||||
|| nAction == ACTION_CASTSPELL || nAction == ACTION_ITEMCASTSPELL)
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(1), oPC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Continue the HeartBeat Timer.
|
||||
DelayCommand(6.0, ExecuteScript("prc_onhb_indiv", oPC));
|
||||
}
|
||||
|
||||
/* PC_damage code to support oni's scripts
|
||||
* If HP is over 1 apply the damage and let
|
||||
* the OnDying deal with the consequences
|
||||
*/
|
||||
int nDamage = GetLocalInt(oPC, "PC_Damage");
|
||||
if(nDamage && GetCurrentHitPoints(oPC) > 1)
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage), oPC);
|
||||
SetLocalInt(oPC, "PC_Damage", 0);
|
||||
}
|
||||
|
||||
// ECL
|
||||
if(GetIsPC(oPC) || (!GetIsPC(oPC) && GetPRCSwitch(PRC_XP_GIVE_XP_TO_NPCS)))
|
||||
ApplyECLToXP(oPC);
|
||||
|
||||
// Check if the character has lost a level since last HB
|
||||
if(GetHitDice(oPC) != GetLocalInt(oPC, "PRC_HitDiceTracking"))
|
||||
{
|
||||
if(GetHitDice(oPC) < GetLocalInt(oPC, "PRC_HitDiceTracking"))
|
||||
{
|
||||
SetLocalInt(oPC, "PRC_OnLevelDown_OldLevel", GetLocalInt(oPC, "PRC_HitDiceTracking"));
|
||||
DelayCommand(0.0f, ExecuteScript("prc_onleveldown", oPC));
|
||||
}
|
||||
SetLocalInt(oPC, "PRC_HitDiceTracking", GetHitDice(oPC));
|
||||
}
|
||||
|
||||
// Race Pack Code
|
||||
ExecuteScript("race_hb", oPC);
|
||||
//natural weapons
|
||||
//SpawnScriptDebugger();
|
||||
DoNaturalWeaponHB(oPC);
|
||||
|
||||
// Eventhook
|
||||
ExecuteAllScriptsHookedToEvent(oPC, EVENT_ONHEARTBEAT);
|
||||
}
|
BIN
_haks/poa_dev/prc_onheartbeat.ncs
Normal file
BIN
_haks/poa_dev/prc_onheartbeat.ncs
Normal file
Binary file not shown.
55
_haks/poa_dev/prc_onheartbeat.nss
Normal file
55
_haks/poa_dev/prc_onheartbeat.nss
Normal file
@@ -0,0 +1,55 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: OnHeartbeat eventscript
|
||||
//:: prc_onheartbeat
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_alterations"
|
||||
#include "prc_inc_leadersh"
|
||||
|
||||
void main()
|
||||
{
|
||||
// Item creation code
|
||||
ExecuteScript("hd_o0_heartbeat", OBJECT_SELF);
|
||||
|
||||
int bBiowareDBCache = GetPRCSwitch(PRC_USE_BIOWARE_DATABASE);
|
||||
|
||||
if(bBiowareDBCache)
|
||||
{
|
||||
//decide if to cache bioware 2da yet
|
||||
object oModule = GetModule();
|
||||
if(GetLocalInt(oModule, "Bioware2dacacheCount") >= bBiowareDBCache)
|
||||
DeleteLocalInt(oModule, "Bioware2dacacheCount");
|
||||
else
|
||||
{
|
||||
SetLocalInt(oModule, "Bioware2dacacheCount", GetLocalInt(oModule, "Bioware2dacacheCount") + 1);
|
||||
bBiowareDBCache = FALSE;
|
||||
}
|
||||
if(bBiowareDBCache)
|
||||
{
|
||||
//due to biowares piss-poor database coding, you have to destroy the old database before storing
|
||||
//the object
|
||||
//If you dont, the dataabse will bloat infinitely because when overriting an existing
|
||||
//database entry really marks the old entry as "deleted" ( but doesnt actually remove it)
|
||||
//and creates a new entry instead.
|
||||
|
||||
if(DEBUG) DoDebug ("Storing Bioware2DACache");
|
||||
else WriteTimestampedLogEntry("Storing Bioware2DACache");
|
||||
string sDBName = GetBiowareDBName();
|
||||
DestroyCampaignDatabase(sDBName);
|
||||
object o2daCache = GetObjectByTag("Bioware2DACache");
|
||||
// Rebuild the DB
|
||||
StoreCampaignObject(sDBName, "CacheChest", o2daCache);
|
||||
SetCampaignString(sDBName, "version", PRC_VERSION);
|
||||
SetCampaignString(sDBName, "PRC_2DA_Cache_Fingerprint", GetLocalString(oModule, "PRC_2DA_Cache_Fingerprint"));
|
||||
if(DEBUG) DoDebug ("Finished storing Bioware2DACache");
|
||||
else WriteTimestampedLogEntry("Finished storing Bioware2DACache");
|
||||
|
||||
// Updated last access fingerprint
|
||||
SetLocalString(oModule, "PRC_2DA_Cache_Fingerprint_LastAccessed", GetLocalString(oModule, "PRC_2DA_Cache_Fingerprint"));
|
||||
}
|
||||
}
|
||||
|
||||
// Player HB code moved to prc_onhb_indiv
|
||||
// Removes a LOT of load from teh Module HB
|
||||
// and should prevent TMI problems.
|
||||
}
|
BIN
_haks/poa_dev/prc_onmodload.ncs
Normal file
BIN
_haks/poa_dev/prc_onmodload.ncs
Normal file
Binary file not shown.
319
_haks/poa_dev/prc_onmodload.nss
Normal file
319
_haks/poa_dev/prc_onmodload.nss
Normal file
@@ -0,0 +1,319 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: PRC On Module Load event handler
|
||||
//:: prc_onmodload
|
||||
//::///////////////////////////////////////////////
|
||||
/** @file prc_onmodload
|
||||
Things we need to happen upon a module being
|
||||
loaded. For example, setting up caches and
|
||||
switches.
|
||||
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_alterations"
|
||||
#include "prc_inc_leadersh"
|
||||
#include "inc_switch_setup"
|
||||
#include "inc_cache_setup"
|
||||
#include "inc_sql"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function prototypes */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
void OnLoad_Always(object oModule);
|
||||
void OnLoad_Save(object oModule);
|
||||
void OnLoad_Fresh(object oModule);
|
||||
void PersonalSwitch(object oModule);
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/* Function definitions */
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
void CheckDB()
|
||||
{
|
||||
string sDBName = GetBiowareDBName();
|
||||
//check PRC version
|
||||
if(GetCampaignString(sDBName, "version") != PRC_VERSION)
|
||||
{
|
||||
DoDebug("Removing old PRC version databases");
|
||||
DestroyCampaignDatabase(sDBName);
|
||||
DestroyCampaignDatabase(COHORT_DATABASE);
|
||||
}
|
||||
SetCampaignString(sDBName, "version", PRC_VERSION);
|
||||
|
||||
// 2da cache fingerprint handling
|
||||
// This is for detecting a cache updated by someone else upon loading a saved game
|
||||
// and avoiding clobbering it.
|
||||
string sFingerprint;
|
||||
|
||||
// Generate the fingerprint from module name, current millisecond value and
|
||||
// 31-bit random number.
|
||||
sFingerprint = GetModuleName() + "_" + IntToString(GetTimeMillisecond()) + "_" + IntToString(Random(0x7fffffff));
|
||||
|
||||
DoDebug("Module 2da cache fingerprint: " + sFingerprint);
|
||||
|
||||
// Store the fingerprint on the module - it will be written to the DB upon cache storage
|
||||
SetLocalString(GetModule(), "PRC_2DA_Cache_Fingerprint", sFingerprint);
|
||||
|
||||
// Also store the fingerprint of the DB we will be loading shortly
|
||||
SetLocalString(GetModule(), "PRC_2DA_Cache_Fingerprint_LastAccessed", GetCampaignString(sDBName, "PRC_2DA_Cache_Fingerprint"));
|
||||
|
||||
location lLoc = GetLocation(GetObjectByTag("HEARTOFCHAOS"));
|
||||
// only get it if one doesnt already exist (saved games)
|
||||
// This never gets run on saved games due to the "prc_mod_load_done" check.
|
||||
// However, it is still usefull cleanup in case some unforseen condition does
|
||||
// leave a cache object present in a freshly loaded module - Ornedan 20061229
|
||||
if(GetIsObjectValid(GetObjectByTag("Bioware2DACache")))
|
||||
DestroyObject(GetObjectByTag("Bioware2DACache"));
|
||||
DoDebug("Starting to load 2da cache object from " + sDBName);
|
||||
object oChest = RetrieveCampaignObject(sDBName, "CacheChest", lLoc);
|
||||
if(!GetIsObjectValid(oChest))
|
||||
{
|
||||
DoDebug("WARNING: Unable to load 2da cache object (CacheChest) from " + sDBName);
|
||||
oChest = CreateObject(OBJECT_TYPE_CREATURE, "prc_2da_cache", lLoc, FALSE, "Bioware2DACache");
|
||||
}
|
||||
else
|
||||
{
|
||||
DoDebug("Finished loading 2da cache object from " + sDBName);
|
||||
}
|
||||
|
||||
//DB is ready run 2da lookup stuff
|
||||
DelayCommand(0.1f, RunLookupLoop());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a saved game load is detected. Determines if the
|
||||
* 2da cache DB has changed in the meanwhile. If it has, reload the
|
||||
* cache creature from the DB.
|
||||
*/
|
||||
void CheckDBUpdate()
|
||||
{
|
||||
// Get last loaded (or saved) and DB fingerprints
|
||||
string sDBName = GetBiowareDBName();
|
||||
string sModuleFingerprint = GetLocalString(GetModule(), "PRC_2DA_Cache_Fingerprint_LastAccessed");
|
||||
string sDBFingerprint = GetCampaignString(sDBName, "PRC_2DA_Cache_Fingerprint");
|
||||
|
||||
DoDebug("CheckDBUpdate():\n"
|
||||
+ " Module last access fingerprint: " + sModuleFingerprint + "\n"
|
||||
+ " Database fingerprint: " + sDBFingerprint
|
||||
);
|
||||
// If they differ, the DB has changed in meanwhile and we need to reload the cache chest
|
||||
if(sModuleFingerprint != sDBFingerprint)
|
||||
{
|
||||
DoDebug("Fingerprint mismatch, reloading 2da cache from " + sDBName);
|
||||
location lLoc = GetLocation(GetObjectByTag("HEARTOFCHAOS"));
|
||||
DestroyObject(GetObjectByTag("Bioware2DACache"));
|
||||
|
||||
DoDebug("Starting to load 2da cache object from " + sDBName);
|
||||
object oChest = RetrieveCampaignObject(sDBName, "CacheChest", lLoc);
|
||||
if(!GetIsObjectValid(oChest))
|
||||
DoDebug("ERROR: Unable to load 2da cache object (CacheChest) from " + sDBName);
|
||||
else
|
||||
{
|
||||
DoDebug("Finished loading 2da cache object from " + sDBName);
|
||||
|
||||
//DB is ready run 2da lookup stuff
|
||||
DelayCommand(0.1f, RunLookupLoop());
|
||||
}
|
||||
|
||||
// Updated last access fingerprint
|
||||
SetLocalString(GetModule(), "PRC_2DA_Cache_Fingerprint_LastAccessed", sDBFingerprint);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckXPSwitches(object oModule)
|
||||
{
|
||||
if(!GetLocalInt(oModule, PRC_XP_PC_PARTY_COUNT_x100))//player will get 0 xp for kills - we assume that the XP system was not setup
|
||||
{
|
||||
SetLocalInt(oModule, PRC_XP_SLIDER_x100, 100);
|
||||
SetLocalInt(oModule, PRC_XP_GROUP_BONUS, 10);
|
||||
SetLocalInt(oModule, PRC_XP_PC_PARTY_COUNT_x100, 100);
|
||||
SetLocalInt(oModule, PRC_XP_DOMINATED_PARTY_COUNT_x100, 0);
|
||||
SetLocalInt(oModule, PRC_XP_HENCHMAN_PARTY_COUNT_x100, 50);
|
||||
SetLocalInt(oModule, PRC_XP_UNKNOWN_PARTY_COUNT_x100, 0);
|
||||
SetLocalInt(oModule, PRC_XP_SUMMONED_PARTY_COUNT_x100, 0);
|
||||
SetLocalInt(oModule, PRC_XP_FAMILIAR_PARTY_COUNT_x100, 0);
|
||||
SetLocalInt(oModule, PRC_XP_ANIMALCOMPANION_PARTY_COUNT_x100, 0);
|
||||
SetLocalInt(oModule, PRC_XP_MUST_BE_IN_AREA, 1);
|
||||
SetLocalInt(oModule, PRC_XP_MAX_PHYSICAL_DISTANCE, 100);
|
||||
}
|
||||
//
|
||||
if(!GetLocalInt(oModule, PRC_XP_MAX_LEVEL_DIFF))
|
||||
SetLocalInt(oModule, PRC_XP_MAX_LEVEL_DIFF, 5);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
object oModule = GetModule();
|
||||
PersonalSwitch(oModule);
|
||||
|
||||
OnLoad_Always(oModule);
|
||||
|
||||
// Determine if we are loading a saved game or entering a fresh module
|
||||
// Some things should only be run in one situation or the other.
|
||||
if(GetLocalInt(oModule, "prc_mod_load_done"))
|
||||
{
|
||||
OnLoad_Save(oModule);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLocalInt(oModule, "prc_mod_load_done", TRUE);
|
||||
OnLoad_Fresh(oModule);
|
||||
}
|
||||
|
||||
//NWNX_Funcs plugin test:
|
||||
//PRC_Funcs_Init(oModule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Things that should always be run on loading a module,
|
||||
* irrespective of whether it's a fresh load or a save.
|
||||
*/
|
||||
void OnLoad_Always(object oModule)
|
||||
{
|
||||
//this triggers NWNX on Linux
|
||||
//SetLocalInt(oModule, "NWNX!INIT", 1);
|
||||
//SetLocalString(oModule, "NWNX!INIT", "1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Things that should be run only when a saved game is loaded.
|
||||
*/
|
||||
void OnLoad_Save(object oModule)
|
||||
{
|
||||
CheckDBUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Things that should only be run when a module is first loaded.
|
||||
*/
|
||||
void OnLoad_Fresh(object oModule)
|
||||
{
|
||||
// Set PRC presence & version marker. If plugins ever happen, this would be useful.
|
||||
SetLocalString(oModule, "PRC_VERSION", PRC_VERSION);
|
||||
|
||||
SetModuleSwitch(MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS, TRUE); /// @todo This is somewhat intrusive, make it unnecessary and remove
|
||||
|
||||
// Run a script to determine if the PRC Companion is present
|
||||
ExecuteScript("hakmarker", OBJECT_SELF);
|
||||
|
||||
//delay this to avoid TMIs
|
||||
DelayCommand(0.01, CreateSwitchNameArray());
|
||||
DelayCommand(0.01, DoEpicSpellDefaults());
|
||||
DelayCommand(0.01, DoSamuraiBanDefaults());
|
||||
SetDefaultFileEnds();
|
||||
if(GetPRCSwitch(PRC_CONVOCC_ENABLE))
|
||||
{
|
||||
SetPRCSwitch(PRC_USE_DATABASE, TRUE);
|
||||
//SetPRCSwitch(PRC_DB_PRECACHE, TRUE);
|
||||
SetPRCSwitch(PRC_USE_LETOSCRIPT, TRUE);
|
||||
// set up the convoCC combination switches
|
||||
if(GetPRCSwitch(PRC_CONVOCC_ENFORCE_FEATS))
|
||||
{
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_BLOOD_OF_THE_WARLORD, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_NIMBUSLIGHT, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_HOLYRADIANCE, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_SERVHEAVEN, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_SAC_VOW, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_VOW_OBED, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_THRALL_TO_DEMON, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_DISCIPLE_OF_DARKNESS, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_LICHLOVED, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_EVIL_BRANDS, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_VILE_WILL_DEFORM, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_VILE_DEFORM_OBESE, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_VILE_DEFORM_GAUNT, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_ENFORCE_FEAT_LOLTHS_MEAT, TRUE);
|
||||
}
|
||||
if(GetPRCSwitch(PRC_CONVOCC_ENFORCE_PNP_RACIAL))
|
||||
{
|
||||
SetPRCSwitch(PRC_CONVOCC_RAKSHASA_FEMALE_APPEARANCE, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_GENASI_ENFORCE_DOMAINS, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_DROW_ENFORCE_GENDER, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_TIEFLING_TAIL, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_FEYRI_TAIL, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_FEYRI_WINGS, TRUE);
|
||||
SetPRCSwitch(PRC_CONVOCC_AVARIEL_WINGS, TRUE);
|
||||
}
|
||||
}
|
||||
if(GetPRCSwitch(PRC_USE_BIOWARE_DATABASE) == 0)
|
||||
SetPRCSwitch(PRC_USE_BIOWARE_DATABASE, 300);//100 HBs = 1800sec = 30min
|
||||
if(GetPRCSwitch(PRC_USE_BIOWARE_DATABASE))
|
||||
DelayCommand(0.1, CheckDB());
|
||||
|
||||
if(GetPRCSwitch(PRC_USE_DATABASE))
|
||||
{
|
||||
PRC_SQLInit();
|
||||
if(GetPRCSwitch(PRC_DB_SQLITE))
|
||||
{
|
||||
StartSQLiteCommitHB();
|
||||
CreateXChestDB_SQLite();
|
||||
}
|
||||
else if(GetPRCSwitch(PRC_DB_MYSQL))
|
||||
CreateXChestDB_MySQL();
|
||||
}
|
||||
if(GetPRCSwitch(PRC_DB_PRECACHE))
|
||||
Cache_2da_data();
|
||||
|
||||
// Disable Bioware XP as it's being handled by PRC
|
||||
if(GetPRCSwitch(PRC_XP_USE_PNP_XP))
|
||||
{
|
||||
SetModuleXPScale(0);
|
||||
DelayCommand(5.0f, CheckXPSwitches(oModule));
|
||||
}
|
||||
|
||||
//pre-made cohorts
|
||||
//DelayCommand(6.0, AddPremadeCohortsToDB());
|
||||
//done differently now
|
||||
|
||||
//check for letoscript dir
|
||||
/* if(GetLocalString(oModule, PRC_LETOSCRIPT_NWN_DIR) == "")
|
||||
{
|
||||
string sDir = Get2DACache("directory", "Dir", 0);
|
||||
if(sDir != "")
|
||||
SetLocalString(oModule, PRC_LETOSCRIPT_NWN_DIR, sDir);
|
||||
} */
|
||||
|
||||
//mark server as loading
|
||||
float fDelay = IntToFloat(GetPRCSwitch(PRC_PW_LOGON_DELAY))*60.0;
|
||||
if(fDelay>0.0)
|
||||
{
|
||||
SetLocalInt(GetModule(), PRC_PW_LOGON_DELAY+"_TIMER", TRUE);
|
||||
DelayCommand(fDelay, DeleteLocalInt(GetModule(), PRC_PW_LOGON_DELAY+"_TIMER"));
|
||||
}
|
||||
}
|
||||
|
||||
void PersonalSwitch(object oModule)
|
||||
{
|
||||
DoDebug("PersonalSwitch Running");
|
||||
//load any default switch 2da
|
||||
int i = 0;
|
||||
string sSwitchName, sSwitchType, sSwitchValue;
|
||||
// Use Get2DAString() instead of Get2DACache() to avoid caching.
|
||||
// People might want to set different switch values when playing in different modules.
|
||||
// Or just change the switch values midplay.
|
||||
sSwitchName = Get2DAString("personal_switch", "SwitchName", i);
|
||||
while(sSwitchName != "") // Brute force
|
||||
{
|
||||
DoDebug("SwitchName: "+sSwitchName);
|
||||
// Read rest of the line
|
||||
sSwitchType = Get2DAString("personal_switch", "SwitchType", i);
|
||||
sSwitchValue = Get2DAString("personal_switch", "SwitchValue", i);
|
||||
DoDebug("SwitchType: "+sSwitchType);
|
||||
DoDebug("SwitchValue: "+sSwitchValue);
|
||||
|
||||
// Determine switch type and set the var
|
||||
if (sSwitchType == "float")
|
||||
SetLocalFloat(oModule, sSwitchName, StringToFloat(sSwitchValue));
|
||||
else if(sSwitchType == "int")
|
||||
SetPRCSwitch(sSwitchName, StringToInt(sSwitchValue));
|
||||
else if(sSwitchType == "string")
|
||||
SetLocalString(oModule, sSwitchName, sSwitchValue);
|
||||
|
||||
// Increment loop counter
|
||||
i += 1;
|
||||
sSwitchName = Get2DAString("personal_switch", "SwitchName", i);
|
||||
}
|
||||
}
|
BIN
_haks/poa_dev/prc_switchesc.ncs
Normal file
BIN
_haks/poa_dev/prc_switchesc.ncs
Normal file
Binary file not shown.
1927
_haks/poa_dev/prc_switchesc.nss
Normal file
1927
_haks/poa_dev/prc_switchesc.nss
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user