330 lines
13 KiB
Plaintext
330 lines
13 KiB
Plaintext
////////////////////////////////////////////////////////////////////////
|
|
// 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)<nCost||GetLocalInt(oRespawner,"nDeaths")>=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(){}
|