#include "vamp_checkarmor" #include "vamp_gaseous" // needed // needed for loosing XP & GP on dying object oMod = GetModule(); //Applies nice effect when vampire dies permanently. void VampSmoke(object oPC) { effect eInvis = EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY); effect eSmoke = EffectVisualEffect(VFX_FNF_SMOKE_PUFF); effect eImplosion = EffectVisualEffect(VFX_FNF_IMPLOSION); effect eExplosion = EffectVisualEffect(VFX_FNF_HOWL_MIND); effect eLink = EffectLinkEffects(eSmoke, eExplosion); effect eLink2 = EffectLinkEffects(eLink, eImplosion); if (GetLocalInt(oMod, "iVampCutsceneInvis")==1) ApplyEffectToObject(DURATION_TYPE_PERMANENT, eInvis, oPC); ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eLink2, GetLocation(oPC)); } //This method checks has vampire rest 5 hours after he dies. If not, he is permanently dead. void CheckHasVampireRest(object oPC) { if (GetCampaignInt("Vampire", "VampireMustRest", oPC)==1) { PrintString("vamp_subrace: CheckHasVampireRest() - " + GetName(oPC) + "failed to reach coffin and is permanently dead."); SendMessageToPC(oPC, "You failed to reach your coffin. You are permanently dead."); SendMessageToAllDMs(GetName(oPC)+ " failed to reach their coffin. They are permanently dead."); ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDeath(),oPC); SetCampaignInt("Vampire","VampIsDead",1,oPC); return; } } //This will assign vampire +6 natural ac bonus and makes sure he has his hide. void init_vampire(object oPC) { PrintString("vamp_subrace: init_vampire() - " + GetName(oPC) + " - This will assign vampire +6 natural ac bonus and makes sure he has his hide."); effect NaturalAC = EffectACIncrease(6, AC_NATURAL_BONUS, AC_VS_DAMAGE_TYPE_ALL); ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(NaturalAC), oPC); //For some strange reason vampire does not equip his skin again. //This scripts destroyes old skin and creates new one. DestroyObject(GetItemPossessedBy(oPC,"pcvampireskin"),0.0f); object oItem = CreateItemOnObject("pcvampireskin", oPC); DelayCommand(0.1f,AssignCommand(oPC, ActionEquipItem (oItem, INVENTORY_SLOT_CARMOUR))); } // This function checks has object gained Constitutition damage over his constituion //If yes, kill object. NOTE: Vampire does not gain any constitution losses. He is immune for ability drain :/ //At the moment I there is only counter what couts how much he has gained "damage" void vamp_modifyconst(object oPC) { SetLocalInt(oPC,"VampHungryCounter",(GetLocalInt(oPC,"VampHungryCounter")+2)); if (( GetLocalInt(oPC,"VampHungry")!=0 )&&( GetLocalInt(oPC,"VampHungryCounter") >= GetAbilityScore(oPC,ABILITY_CONSTITUTION) )) { ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDeath(),oPC); SendMessageToPC(oPC,"You died to starvation."); SendMessageToAllDMs(GetName(oPC)+ " died to starvation."); } } //Vampire Hunger system. NOTE: INFINITE LOOP void vamp_hunger(object oPC) { PrintString("vamp_subrace: vamp_hunger() "+GetName(oPC)+"... are they hungry?"); effect eSpeed = EffectMovementSpeedDecrease(30); // Vampire is not hungry. Check again after 12hours. if (GetLocalInt(oPC,"VampHungry")==0) { PrintString("vamp_subrace: vamp_hunger() "+GetName(oPC)+" 0: Vampire isn't hungry. We'll check again in 12 hours or "+FloatToString(HoursToSeconds(12))+" seconds."); SetLocalInt(oPC,"VampHungry",1); DelayCommand(HoursToSeconds(12), vamp_hunger(oPC)); return; } // Vampire is getting little hungry. Check again after 6 hours. if (GetLocalInt(oPC,"VampHungry")==1) { PrintString("vamp_subrace: vamp_hunger() "+GetName(oPC)+" 1: Vampire is a little hungry. We'll check again in 6 hours or "+FloatToString(HoursToSeconds(6))+" seconds."); SendMessageToPC(oPC, "You begin to feel hungry."); SetLocalInt(oPC,"VampHungry",2); DelayCommand(HoursToSeconds(6), vamp_hunger(oPC)); return; } // Vampire is very hungry. Check again after 3 hours. else if (GetLocalInt(oPC,"VampHungry")==2) { PrintString("vamp_subrace: vamp_hunger() "+GetName(oPC)+" 2: Vampire is very hungry. We'll check again in 3 hours or "+FloatToString(HoursToSeconds(3))+" seconds."); SendMessageToPC(oPC, "You are very hungry."); SetLocalInt(oPC,"VampHungry",3); DelayCommand(HoursToSeconds(3), vamp_hunger(oPC)); return; } // Vampire is starving. Give 2 constitution "damage" per 3 hours he is starving. // When "Damage" is over vampire constitution score, vampire is dead. else if (GetLocalInt(oPC,"VampHungry")==3) { PrintString("vamp_subrace: vamp_hunger() "+GetName(oPC)+" 3: Vampire is starving. We'll check again in 3 hours or "+FloatToString(HoursToSeconds(3))+" seconds."); SendMessageToPC(oPC, "You are starving."); vamp_modifyconst(oPC); DelayCommand(HoursToSeconds(3), vamp_hunger(oPC)); return; } } //Handles vampire respawn penalty. // DAVIDBEOULVE: I commented this out as it is far too easy for a // vampire to die repeatedly. If XP is taken, that will drive // the player mad. Something has to be done about how they die... // enemies whack on gaseous forms way too much. void vamp_takexp(object oPC) { // if the Vampire is not ALREADY dead... if (GetCampaignInt("Vampire", "VampireMustRest", oPC)!=1 || GetAppearanceType(oPC)!=APPEARANCE_TYPE_SPECTRE) { PrintString(GetName(oPC)+" is a Vampire who has died and wasn't already a spectre." +" Appearance type:["+IntToString(GetAppearanceType(oPC))+"]" +" Vampire Must Rest:["+IntToString(GetCampaignInt("Vampire", "VampireMustRest", oPC))+"]"); //SetXP(oPC,GetXP(oPC)-(GetHitDice(oPC)*100)); //HABDApplyPenalty(oPC, 20, 20); } } //This method pop-ups Death Panel void vamp_deathpanel(object oPC) { PrintString("vamp_subrace: vamp_deathpanel() - " + GetName(oPC) + " - Death Panel displayed."); DelayCommand(5.0f, PopUpDeathGUIPanel(oPC,FALSE,TRUE,1,"You are permanently dead.")); VampSmoke(oPC); } //This little method handles what happens to vampire if he dies. void vamp_dead(object oPC) { PrintString("vamp_subrace: vamp_dead() - " + GetName(oPC) + " - Function called."); if (GetLocalInt(oMod, "iCoffin")==1 ) { PrintString("vamp_subrace: vamp_dead() - Coffin system is in effect."); //Gets area where vampire died. object oArea = GetArea(oPC); //Checks if vampire has logged out and logged back to in while he is dead. If false we keep going on if (GetCampaignInt("Vampire", "VampIsDead", oPC)==0) { PrintString("vamp_subrace: vamp_dead() - " + GetName(oPC) + " - VampIsDead==0."); // Checks if vampire is outside and is a dead spectre. // script will inform vampire that he is permanently dead // and SetCampaignInt to TRUE to make sure that // relogging wont raise him. // In this way, we won't see spectres dying repeatedly // in the sunlight... and we also won't see hardened vampires // die permanently if killed in the sunlight, if they have the // proper equipment on. string sArmor = vamp_checkArmor(oPC); if (GetIsDay()==TRUE && GetIsAreaAboveGround(oArea)==TRUE && GetIsAreaNatural(oArea)==TRUE // GetWeather(oArea)==WEATHER_CLEAR && GetAppearanceType(oPC)==APPEARANCE_TYPE_SPECTRE && (GetItemInSlot(INVENTORY_SLOT_HEAD,oPC)==OBJECT_INVALID || sArmor != "Vamp")) { PrintString("vamp_subrace: vamp_dead() - " + GetName(oPC) + " - Vampire was found in daylight; vampire is burned to dust."); DelayCommand(4.0f, SendMessageToPC(oPC, "You have burned down to dust. You cannot return to your coffin.")); SendMessageToAllDMs(GetName(oPC)+" has burned down to dust. They cannot return to their coffin."); PrintString("vamp_subrace: " + GetName(oPC) + "You have burned down to dust. You cannot return to your coffin."); SetCampaignInt("Vampire","VampIsDead",1,oPC); //Pop-ups death panel. DelayCommand(4.0f, vamp_deathpanel(oPC)); } else { PrintString("vamp_subrace: vamp_dead() - " + GetName(oPC) + " - Vampire is not in daylight."); //Checks that vampire dont have vampire token on inventory. If he dont have script will keep going on. if((GetIsObjectValid(GetItemPossessedBy(oPC,"VampireCoffinToken")))==FALSE) { PrintString("vamp_subrace: vamp_dead() - " + GetName(oPC) + " - Vampire does not have his coffin in inventory."); //Attempt to locate vampires coffin via PublicCDKey. //If playing single player trying to locate "VampireCoffin" string sCoffin = GetPCPublicCDKey(oPC); if (sCoffin == "") { sCoffin = "VampireCoffin"; } PrintString("vamp_subrace: vamp_dead() - Looking for Coffin named " + sCoffin); object oTarget = GetObjectByTag(sCoffin); //If coffin is found, respawn vampire next to it. if (GetIsObjectValid(oTarget) ==TRUE) { PrintString("vamp_subrace: vamp_dead() - " + GetName(oPC) + " - Coffin '"+sCoffin+"' exists."); if (GetLocalInt(oMod,"iVampMistForm")==0) { PrintString("vamp_subrace: vamp_dead() - " + GetName(oPC) + " - Mist form not used; respawning vampire near coffin."); //Gets coffins location. location lLoc = GetCampaignLocation("Vampire", "VampCoffinLocation", oPC); effect eSmoke = EffectVisualEffect(VFX_FNF_SMOKE_PUFF); DelayCommand(4.0f,ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eSmoke,GetLocation(oPC))); DelayCommand(5.5f,ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eSmoke,lLoc)); DelayCommand(5.0f,AssignCommand(oPC,JumpToLocation(lLoc))); DelayCommand(5.0f,ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oPC)); } else { PrintString("vamp_subrace: vamp_dead() - " + GetName(oPC) + " - Vampire must now find coffin '"+sCoffin+"' in mist form."); // Now vampire must reach his coffin in 5 hours and rest. If he fails he is permanently dead. SetCampaignInt("Vampire", "VampireMustRest",1,oPC); DelayCommand(5.0f,ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(),oPC)); DelayCommand(5.0f,ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(GetMaxHitPoints(oPC)),oPC)); // Make the vampire a gaseous form, forcibly. DelayCommand(6.0f,vamp_gaseous(oPC)); // Try to get the vampire's AI enemies to leave // him/her alone for a moment. ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectEthereal(),oPC,2.0f); DelayCommand(6.0f, SendMessageToPC(oPC, "You must rest in your coffin within 5 hours!")); DelayCommand(HoursToSeconds(5), CheckHasVampireRest(oPC)); } //Call method that handles vampire respawn penalties. DelayCommand(5.1f,vamp_takexp(oPC)); //Gives +6 natural ac effect NaturalAC = EffectACIncrease(6, AC_NATURAL_BONUS, AC_VS_DAMAGE_TYPE_ALL); DelayCommand(5.1f,ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(NaturalAC), oPC)); } //If vampire dont have respawn waypoint (somebody has destroyed his coffin) he is permanently dead. else { PrintString("vamp_subrace: vamp_dead() - " + GetName(oPC) + " - There is no coffin '"+sCoffin+"' to return to (death)."); SendMessageToPC(oPC, "You don't have a coffin to return to. You are permanently dead."); SendMessageToAllDMs(GetName(oPC)+" didn't have a coffin to return to. They are permanently dead."); PrintString("vamp_subrace: " + GetName(oPC) + "You dont have a coffin where to return. 1"); SetCampaignInt("Vampire","VampIsDead",1,oPC); //Pop-ups death panel. vamp_deathpanel(oPC); } } //If vampire has coffin token. That means that he doesn't have coffin where to return. He is now permanently dead. else { PrintString("vamp_subrace: " + GetName(oPC) + "You dont have a coffin where to return. 2"); SendMessageToPC(oPC, "You dont have a coffin to return to. You are permanently dead."); SendMessageToAllDMs(GetName(oPC)+" didn't have a coffin to return to. They are permanently dead."); SetCampaignInt("Vampire","VampIsDead",1,oPC); //Pop-ups death panel. vamp_deathpanel(oPC); } } } //If LocalInt "IsDead" is TRUE (vampire is permanently dead) this little script will inform it to vampire. else { PrintString("vamp_subrace: vamp_dead() - " + GetName(oPC) + " - Inform vampire of his death."); SendMessageToPC(oPC, "You are permanently dead."); SendMessageToAllDMs(GetName(oPC)+" found out they are permanently dead."); vamp_deathpanel(oPC); } } } //This little fuction loops INFINITY for every 5s checking is vampire walking under sun. void vamp_day(object oPC) { //Checks on what area vampire is. object oArea = GetArea(oPC); //Checks what armor vampire is wearing if any. string sItem = GetSubString(GetTag(GetItemInSlot(INVENTORY_SLOT_CHEST,oPC)),0,4); //Checks if vampire needs special clothes. If not change string to "Vamp" if (GetLocalInt(oMod, "iVampSpecialClothes")==0 && GetItemInSlot(INVENTORY_SLOT_CHEST,oPC)!=OBJECT_INVALID) { sItem = "Vamp"; } //What Visual Effect will happen if vampire dies. effect vDamage = EffectVisualEffect(VFX_IMP_SUNSTRIKE); //If it is day and vampire is abovegroud and day is clear. And if vampire isnt wearing anything on his head. If everything is TRUE sun will kill vampire. if (GetIsDay()==TRUE &&GetIsAreaAboveGround(oArea)==TRUE //&&GetWeather(oArea)==WEATHER_CLEAR &&GetIsAreaNatural(oArea)==TRUE &&GetSubRace(oPC)=="Vampire" &&GetIsDead(oPC)==FALSE &&(GetItemInSlot(INVENTORY_SLOT_HEAD,oPC)==OBJECT_INVALID || sItem != "Vamp")) { //Checks is vampire allready dead. If false this will make sure he is. (No point of killing allready dead vampire) if (GetIsDead(oPC) == FALSE) { //Is Sun system set to kill isntant? //If yes kill vampire. if ( GetLocalInt(oMod, "iSunKillInstant")==1 ) { //Applies death effect ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDeath(),oPC); //And kills vampire. ApplyEffectToObject(DURATION_TYPE_INSTANT,vDamage,oPC); } //If not do x damage. else { int iDamage = GetLocalInt(oMod, "iSunDamageX"); effect eDamage = EffectDamage(iDamage,DAMAGE_TYPE_MAGICAL,DAMAGE_POWER_NORMAL); ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oPC); } } } //Waits for five seconds before running method again. DelayCommand(5.0f, vamp_day(oPC)); } //Aplies vampire stats and starts checking is vampire under sun. void init_subrace(object oPC) { PrintString("vamp_subrace: init_subrace() - PC|" + GetName(oPC) + "| function called."); if (GetSubRace(oPC) == "Vampire") { PrintString("vamp_subrace: init_subrace() - PC|" + GetName(oPC) + "| Object is a Vampire."); object oMod = GetModule(); //Checks that oPC is player character. if (GetIsPC(oPC) == TRUE) { PrintString("vamp_subrace: init_subrace() - PC|" + GetName(oPC) + "| Object is a Player Vampire."); //Checks if vampire has died permanently and logged out. if (GetCampaignInt("Vampire", "VampIsDead", oPC)==1) //if (GetLocalInt(oPC,"IsDead")==1) { PrintString("vamp_subrace: init_subrace() - PC|" + GetName(oPC) + "| Vampire is permanently dead and shouldn't be coming back, so we kill him here."); ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDeath(),oPC); return; } else { PrintString("vamp_subrace: init_subrace() - PC|" + GetName(oPC) + "| Vampire is still undead. Give them their stuff if they don't have it."); //Give Vampire Special Items. if(( GetIsObjectValid(GetItemPossessedBy(oPC,"VampireDetectTemplars"))==FALSE) && (GetLocalInt(oMod, "iVampDetectTemplars")==1)) CreateItemOnObject("VampireDetectTemplars", oPC); if(( GetIsObjectValid(GetItemPossessedBy(oPC,"VampireLineage"))==FALSE) && (GetLocalInt(oMod, "iVampireLineage")==1)) CreateItemOnObject("VampireLineage", oPC); if(( GetIsObjectValid(GetItemPossessedBy(oPC,"VampireAlternateWolfForm"))==FALSE) && (GetLocalInt(oMod, "iAlternateWolf")==1)) CreateItemOnObject("vampirealternate", oPC); if(( GetIsObjectValid(GetItemPossessedBy(oPC,"VampireAlternateFormDireWolf"))==FALSE) && (GetLocalInt(oMod, "iAlternateDireWolf")==1)) CreateItemOnObject("vampirealtern001", oPC); if(( GetIsObjectValid(GetItemPossessedBy(oPC,"VampireDomination"))==FALSE) && (GetLocalInt(oMod, "iDomination")==1)) CreateItemOnObject("vampiredominatio", oPC); if(( GetIsObjectValid(GetItemPossessedBy(oPC,"VampireChildrenoftheNight"))==FALSE) && (GetLocalInt(oMod, "iChildrenWolf")==1)) CreateItemOnObject("childrenwolf", oPC); if(( GetIsObjectValid(GetItemPossessedBy(oPC,"ChildrenoftheNightRat"))==FALSE) && (GetLocalInt(oMod, "iChildrenRat")==1)) CreateItemOnObject("childrenofthenig", oPC); if(( GetIsObjectValid(GetItemPossessedBy(oPC,"BloodDrain"))==FALSE) && (GetLocalInt(oMod, "iBloodDrain")==1)) CreateItemOnObject("blooddrain", oPC); if(( GetIsObjectValid(GetItemPossessedBy(oPC,"SlamAttack"))==FALSE) && (GetLocalInt(oMod, "iSlamAttack")==1)) CreateItemOnObject("slamattack", oPC); if(( GetIsObjectValid(GetItemPossessedBy(oPC,"gaseous"))==FALSE) && (GetLocalInt(oMod, "iGaseousForm")==1)) CreateItemOnObject("gaseous", oPC); // make sure vampires have an empty blood bottles to fill //if(( GetIsObjectValid(GetItemPossessedBy(oPC,"EmptyBottle"))==FALSE) && (GetLocalInt(oMod, "iDrinkBlood")==1)) //{ //CreateItemOnObject("vampemptybottle", oPC); // CreateItemOnObject("vampemptybottle", oPC); //CreateItemOnObject("vampemptybottle", oPC); //CreateItemOnObject("vampemptybottle", oPC); //CreateItemOnObject("vampemptybottle", oPC); //CreateItemOnObject("vampemptybottle", oPC); //EmptyBottle // } PrintString("vamp_subrace: init_subrace() Coffin in Inventory was ["+IntToString(GetLocalInt(oPC,"iCoffinInInventory"))+"]."); // This is all the important Coffin code. Basically it checks if // it the local variable says it should be in the player's // inventory, if it's not there, place it there. // Otherwise check to see if it exists in the world and report // findings to the vampire. // "i"+GetName(oPC)+"loggedInToday" = iKaliloggedInToday ... // tells whether ornot it's the player's first time back since // a server restart. PrintString("vamp_subrace: init_subrace() "+GetName(oPC)+" has logged in today ["+IntToString(GetLocalInt(oPC,"iCoffinInInventory"))+"]"); // if we are keeping track of coffins... if (GetLocalInt(oMod, "iCoffin")==1) { // if they should have their coffin in their inventory, // or if it is the first time they have logged in since // a server reset, give them a coffin if they don't have one. if (GetLocalInt(oPC,"iCoffinInInventory")==TRUE || GetLocalInt(oPC,"i"+GetName(oPC)+"loggedInToday")==FALSE) { //SetLocalInt(oPC,"iCoffinInInventory",TRUE); SetLocalInt(oPC,"i"+GetName(oPC)+"loggedInToday",TRUE); if( GetIsObjectValid(GetItemPossessedBy(oPC,"VampireCoffinToken"))==FALSE ) { CreateItemOnObject("vampirecoffintok", oPC); PrintString("vamp_subrace: init_subrace() Coffin wasn't found in "+GetName(oPC)+"'s inventory, so we put a new one in inventory."); } PrintString("vamp_subrace: init_subrace() Coffin in Inventory is now ["+IntToString(GetLocalInt(oPC,"iCoffinInInventory"))+"]."); } else { // their coffin is either in the world, // in their inventory, or destroyed. if(GetIsObjectValid(GetItemPossessedBy(oPC,"VampireCoffinToken"))==FALSE) { // They don't have it in their inventory... // does it exist in the world? string sCoffin = GetPCPublicCDKey(oPC); if (sCoffin == "") { sCoffin = "VampireCoffin"; } object oTarget = GetObjectByTag(sCoffin); if (GetIsObjectValid(oTarget)) { SendMessageToPC(oPC,"Your coffin is already in the world. Be sure no one destroys it."); PrintString("vamp_subrace: init_subrace() Coffin wasn't listed as being in "+GetName(oPC)+"'s inventory. It is already be in the module (verified)."); } else { // the coffin is destroyed. SendMessageToPC(oPC,"Your coffin is not in your inventory, and you don't sense it in the world... it may have been destroyed!"); PrintString("vamp_subrace: init_subrace() Coffin wasn't listed as being in "+GetName(oPC)+"'s inventory. Could not find item with tag ["+GetPCPublicCDKey(oPC)+"] IT HAS BEEN DESTROYED!!! (verified)."); } } else { SendMessageToPC(oPC,"Your coffin is inventory... don't get killed with it in your possession or you will die permanently."); } } } //Create and Equip Hide if(GetIsObjectValid(GetItemPossessedBy(oPC,"pcvampireskin"))==FALSE) { object oItem = CreateItemOnObject("pcvampireskin", oPC); AssignCommand(oPC, ActionEquipItem (oItem, INVENTORY_SLOT_CARMOUR)); } //Sets and starts vampire hunger system. if (GetLocalInt(oMod, "iHungry")==1) { SetLocalInt(oPC,"VampHungry",0); SetLocalInt(oPC,"VampHungryCounter",0); vamp_hunger(oPC); } //This will assign vampire +6 natural ac bonus and makes sure he has his hide. init_vampire(oPC); } //Starts script that checks if it is day. if (GetLocalInt(oMod, "iSunKill")==1) { vamp_day(oPC); } if (GetCampaignInt("Vampire", "VampireMustRest", oPC)==1) DelayCommand(HoursToSeconds(5),CheckHasVampireRest(oPC)); } } }