//////////////////////////////////////////////////////////////////////// // hos_respawn_h - Respawn related functions // By Deva Bryson Winblood. 04/26/2005 // changed 10-22, JG, fixed elimination game mode //////////////////////////////////////////////////////////////////////// #include "nw_i0_plot" #include "rtsh_multiplay" #include "color_header" #include "death_lock_h" #include "x0_i0_henchman" #include "rtsh_multiplay" #include "equip_h" #include "dla_i0_strings" int fnLevel(object oPC) { // get level int nRet=GetLevelByPosition(1,oPC); nRet=nRet+GetLevelByPosition(2,oPC); nRet=nRet+GetLevelByPosition(3,oPC); return nRet; } // fnLevel void fnReequip(object oPC) { object oItem; object oCloth; struct stEquipment stEq; stEq=GetTeamEquipment(oPC); SwapOutEquipment(oPC,stEq); oItem=CreateItemOnObject("nw_it_torch001",oPC); // torch oItem=CreateItemOnObject("nw_wblcl001",oPC); // club if (GetItemPossessedBy(oPC,"rtstool_rebirth")==OBJECT_INVALID) oItem=CreateItemOnObject("rtstool_rebirth",oPC); // Item of rebirth if (GetItemInSlot(INVENTORY_SLOT_CHEST,oPC)==OBJECT_INVALID) DelayCommand(3.0,AssignCommand(oPC,ActionEquipItem(oCloth,INVENTORY_SLOT_CHEST))); } int fnCountSoulTokens(object oTarget=OBJECT_INVALID) { // return TRUE is soul tokens greater than 4 int nRet=FALSE; object oMe=OBJECT_SELF; object oToken; if (GetIsObjectValid(oTarget)) oMe=oTarget; oToken=GetNearestObjectByTag("SoulToken",oMe,1); int nC=1; while(oToken!=OBJECT_INVALID&&nRet==FALSE) { // count nC++; oToken=GetNearestObjectByTag("SoulToken",oMe,nC); if (nC>4&&oToken!=OBJECT_INVALID) nRet=TRUE; } // count return nRet; } // fnCountSoulTokens() void fnSoulTokenExplode(location lLoc) { // blast all NPCs and PCs within 8 meters object oNPC; effect eKnockdown=EffectKnockdown(); effect eDmg=EffectDamage(2*d20()); float fDist; object oArea; int nC=1; int nSkill; oNPC=GetNearestCreatureToLocation(CREATURE_TYPE_IS_ALIVE,TRUE,lLoc,nC); fDist=GetDistanceBetweenLocations(lLoc,GetLocation(oNPC)); while(oNPC!=OBJECT_INVALID&&fDist<8.1) { // blast the NPC ApplyEffectToObject(DURATION_TYPE_INSTANT,eDmg,oNPC,1.0); nSkill=25-GetSkillRank(SKILL_TUMBLE,oNPC); nSkill=ReflexSave(oNPC,nSkill); if (nSkill!=1&&nSkill!=2) { // knockdown nSkill=5+d4(); ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eKnockdown,oNPC,IntToFloat(nSkill)); } // knockdown // next creature nC++; oNPC=GetNearestCreatureToLocation(CREATURE_TYPE_IS_ALIVE,TRUE,lLoc,nC); fDist=GetDistanceBetweenLocations(lLoc,GetLocation(oNPC)); } // blast the NPC oNPC=GetNearestObjectToLocation(OBJECT_TYPE_ALL,lLoc,1); oArea=GetArea(oNPC); nC=GetLocalInt(oArea,"nBreachCount"); nC++; SetLocalInt(oArea,"nBreachCount",nC); if (nC>8) ExecuteScript("planar_breach",oArea); } // fnSoulTokenExplode() void fnMessageDeath(object oDied,object oKiller) { // send message to players about this players death object oPC=GetFirstPC(); object oMod=GetModule(); string sSay1=GetName(oDied)+" was killed by "+GetName(oKiller)+"!"; string sSay2="You were killed by "+GetName(oKiller)+"!"; while(oPC!=OBJECT_INVALID) { // send message if (oPC==oDied) SendMessageToPC(oPC,DLA_SetStringColor(sSay2,"633")); else { SendMessageToPC(oPC,sSay1); } oPC=GetNextPC(); } // send message } // fnMessageDeath() void fnRemoveHenchman(object oH,object oM) { // remove the henchman FireHenchman(oM,oH); ExecuteScript("hench_leave",oH); } // fnRemoveHenchman() void fnLoseSoulToken(object oPC) { // lose a soul token if die in outer planes object oToken=GetItemPossessedBy(oPC,"SoulToken"); int nCount=fnGetTeamSouls(oPC); if (oToken==OBJECT_INVALID) { // take team souls nCount=nCount-1; SendMessageToPC(oPC,"Your team lost a soul token because, you have died in the outer planes."); if (nCount<0) nCount=0; fnSetTeamSouls(oPC,nCount); } // take team souls else { // destroy one carrying DestroyObject(oToken); } // destroy one carrying } // fnLoseSoulToken() void fnDestroyInventory(object oPC,int nDropMana) { // Drop any mana crystals carried and destroy any non-tool items string sTag; object oNew; object oItem=GetFirstItemInInventory(oPC); while(oItem!=OBJECT_INVALID) { // inventory sTag=GetTag(oItem); if (GetStringLeft(sTag,3)!="RTS"&&GetStringLeft(sTag,3)!="rts"&&sTag!="SoulToken"&&GetStringLeft(sTag,5)!="MANA_"&&GetStringLeft(GetResRef(oItem),3)!="rts"&&GetItemCursedFlag(oItem)!=TRUE) { // Destroy it DestroyObject(oItem); } // Destroy it else if (GetStringLeft(sTag,8)=="RTS_MER_") { // Drop it oNew=CreateObject(OBJECT_TYPE_ITEM,GetResRef(oItem),GetLocation(oPC)); DestroyObject(oItem); } // Drop it else if (GetStringLeft(sTag,5)=="MANA_") { // drop it if set if(GetLocalInt(GetModule(),"nManaDeath")==0&&nDropMana==TRUE) { // drop it oNew=CreateObject(OBJECT_TYPE_ITEM,GetResRef(oItem),GetLocation(oPC),FALSE); } // drop it DestroyObject(oItem); } // drop it if set oItem=GetNextItemInInventory(oPC); } // inventory // get worn inventory items oItem=GetItemInSlot(INVENTORY_SLOT_ARMS,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_BELT,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_BOOTS,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_CHEST,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_CLOAK,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_HEAD,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_LEFTRING,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_NECK,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); oItem=GetItemInSlot(INVENTORY_SLOT_RIGHTRING,oPC); if (GetStringLeft(GetTag(oItem),3)!="rts"&&GetStringLeft(GetResRef(oItem),3)!="rts")DestroyObject(oItem); DelayCommand(2.0,fnReequip(oPC)); } void fnMessageAllPlayers(string sMsg) { // PURPOSE: send message to all players object oPC=GetFirstPC(); while(oPC!=OBJECT_INVALID) { // send messages SendMessageToPC(oPC,sMsg); oPC=GetNextPC(); } // send messages } // fnMessageAllPlayers() void fnCheckForElimVictory() { // PURPOSE: To check for an elimination victory object oPC=GetFirstPC(); int bElim=FALSE; string sID; string sLID; object oWinner; object oMod=GetModule(); object oEnd=GetWaypointByTag("END_GAME_POINT"); int nPlayerTeams; int nLiving=0; int nSPID; int nDWF; int nUND; int nUNC; string sMsg; int nTeams; while(oPC!=OBJECT_INVALID) { // check all PCs if (GetIsDM(oPC)==FALSE) { // not a DM sID=GetLocalString(oPC,"sTeamID"); if (GetArea(oEnd)!=GetArea(oPC)) { // living nLiving++; if (sID=="SPID") nSPID++; else if (sID=="UNC") nUNC++; else if (sID=="DWF") nDWF++; else if (sID=="UND") nUND++; } // living } // not a DM oPC=GetNextPC(); } // check all PCs nTeams=0; if (nSPID>0) { nTeams++; sID="SPID"; } if (nUNC>0) { nTeams++; sID="UNC"; } if (nDWF>0) { nTeams++; sID="DWF"; } if (nUND>0) { nTeams++; sID="UND"; } if (nTeams>1) { // still 2+ teams left sMsg="Players remaining: Spiders:"; if (nSPID>0) sMsg=sMsg+DLA_SetStringColor(IntToString(nSPID),"666"); else {sMsg=sMsg+DLA_SetStringColor(IntToString(nSPID),"000"); } sMsg=sMsg+" Unclean:"; if (nUNC>0) sMsg=sMsg+DLA_SetStringColor(IntToString(nUNC),"666"); else {sMsg=sMsg+DLA_SetStringColor(IntToString(nUNC),"000"); } sMsg=sMsg+" Dwarves:"; if (nDWF>0) sMsg=sMsg+DLA_SetStringColor(IntToString(nDWF),"666"); else {sMsg=sMsg+DLA_SetStringColor(IntToString(nDWF),"000"); } sMsg=sMsg+" Undead:"; if (nUND>0) sMsg=sMsg+DLA_SetStringColor(IntToString(nUND),"666"); else {sMsg=sMsg+DLA_SetStringColor(IntToString(nUND),"000"); } fnMessageAllPlayers(sMsg); } // still 2+ teams left else { // victory oWinner=GetLocalObject(oMod,"oTeamLead"+sID); //SetLocalInt(oMod,"nGameOver",TRUE); SetLocalObject(oMod,"oWinner",oWinner); ExecuteScript("rts_end_game",oMod); } // victory } // fnCheckForElimVictory() void fnHandleDrops(object oPC) { // PURPOSE: Handle soul token drops, and more object oMod=GetModule(); object oItem; effect eEffect; if (GetNearestObjectByTag("OUTER_PLANES",oPC,1)!=OBJECT_INVALID) { //fnLoseSoulToken(oPC); fnDestroyInventory(oPC,TRUE); } else { if (GetLocalInt(oMod,"nRTSDeathMeth")!=0) ExecuteScript("rts_pcdrop",oPC); // Drop Goodies if (GetLocalInt(oMod,"nRTSDeathMeth")==4) fnDestroyInventory(oPC,FALSE); else fnDestroyInventory(oPC,TRUE); } // Drop a soul token oItem=CreateObject(OBJECT_TYPE_ITEM,"soultoken",GetLocation(oPC),TRUE); if (GetNearestObjectByTag("OUTER_PLANES",oPC)!=OBJECT_INVALID) { // make sure not dangerous to drop if (fnCountSoulTokens()==TRUE) { // dangerous soul token eEffect=EffectVisualEffect(VFX_DUR_GLOBE_MINOR); ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY,eEffect,GetLocation(oItem),8.0); DelayCommand(1.5,AssignCommand(oItem,PlaySound("as_mg_telepout1"))); eEffect=EffectVisualEffect(VFX_FNF_FIREBALL); DelayCommand(8.5,ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eEffect,GetLocation(oItem),4.0)); DelayCommand(9.5,fnSoulTokenExplode(GetLocation(oItem))); DelayCommand(9.6,DestroyObject(oItem)); } // dangerous soul token } // make sure not dangerous to drop } // fnHandleDrops() void RespawnPlayer(object oRespawner) { // PURPOSE: To handle the respawn object oPC=oRespawner; string sDestTag = "NW_DEATH_TEMPLE_"+IntToString(d4()); object oMod=GetModule(); object oDest=GetWaypointByTag(sDestTag); int nGT=GetLocalInt(oMod,"nGameType"); int nCost=(GetLevelByPosition(1,oRespawner)+GetLevelByPosition(2,oRespawner)+GetLevelByPosition(3,oRespawner))*2; if (GetNearestObjectByTag("OUTER_PLANES",oRespawner)!=OBJECT_INVALID) nCost=1; fnHandleDrops(oRespawner); ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oRespawner); ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectHeal(GetMaxHitPoints(oRespawner)), oRespawner); RemoveEffects(oRespawner); if (nGT==0&&(fnGetTeamSouls(oRespawner)=GetLocalInt(oMod,"nElimLives"))) { // player is dead for good oDest=GetWaypointByTag("END_GAME_POINT"); sDestTag=ColorRGBString(GetName(oRespawner)+" has died the final death!",6,3,3); fnMessageAllPlayers(sDestTag); SetLocalInt(oRespawner,"bPermaDead",TRUE); DelayCommand(7.0,fnCheckForElimVictory()); } // player is dead for good else if (nGT==0) { // consume souls sDestTag=GetName(oRespawner)+" has respawned and used "+IntToString(nCost)+" of their team's souls."; fnMessageAllPlayers(sDestTag); nGT=fnGetTeamSouls(oRespawner); nGT=nGT-nCost; fnSetTeamSouls(oRespawner,nGT); } // consume souls AssignCommand(oRespawner,JumpToObject(oDest)); SetLocalInt(oRespawner,"nDied",0); ExecuteScript("rts_save_player",oRespawner); DelayCommand(5.0,SendMessageToPC(oPC,DLA_SetStringColor("You have been banished back to the outer planes. You have escaped before and you can do so again. Look for the shadow realm and the path will once again be open.","266"))); } // RespawnPlayer() //void main(){}