#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); // 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")); //:: 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