Guest User

Untitled

a guest
Apr 22nd, 2018
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.86 KB | None | 0 0
  1. #include "inc_common"
  2. #include "inc_player"
  3. #include "X0_I0_POSITION"
  4.  
  5.  
  6. const string DEATH_ITEMVARPERSIST = "kemo_scry";
  7. const string DEATH_ITEMCORPSE = "corpse_token";
  8. const string DEATH_ITEMRAISE = "NW_IT_SPDVSCR501";
  9. const string DEATH_ITEMRESURRECT = "NW_IT_SPDVSCR702";
  10.  
  11. const int DEATH_SPELLRAISE = SPELL_RAISE_DEAD;
  12. const int DEATH_SPELLRESURRECT = SPELL_RESURRECTION;
  13.  
  14. const int DEATH_FEATRAISE = 2027;
  15.  
  16. const string DEATH_PLACEABLECORPSEMALE = "pc_corpse_male";
  17. const string DEATH_PLACEABLECORPSEFEMALE = "pc_corpse_female";
  18.  
  19. const string DEATH_VARISDEAD = "IsDead";
  20. const string DEATH_VARLOCATION = "LocationDeath";
  21. const string DEATH_VARCORPSECREATURE = "MY_CORPSE_CREATURE";
  22. const string DEATH_VARCORPSEITEM = "MY_CORPSE_ITEM";
  23. const string DEATH_VAROWNER = "MY_OWNER";
  24. const string DEATH_VARCORPSELOCATION = "LocationCorpse";
  25. const string DEATH_VARKILLERISPC = "SUBDUAL";
  26. const string DEATH_VARMDEATHS = "Count_MDeaths";
  27. const string DEATH_VARPDEATHS = "Count_PDeaths";
  28. const string DEATH_VARTOTALDEATHS = "Count_Deaths";
  29. const string DEATH_VARMKILLS = "Count_MKills";
  30. const string DEATH_VARPKILLS = "Count_PKills";
  31. const string DEATH_VARTOTALKILLS = "Count_Kills";
  32.  
  33. const string DEATH_WPDEATHAREA = "WP_FUGUE1";
  34. const string DEATH_WPDEFAULTSPAWNUD = "sshamath_glouras_wings";
  35. const string DEATH_WPDEFAULTSPAWNNORMAL = "WP_TownportalElfsong";
  36.  
  37. /*
  38. ********************************
  39. */
  40.  
  41. // OnLogin event specific to PCs
  42. void Death_OnPcLogin(object oPC);
  43.  
  44. // OnDying event specific to PCs
  45. void Death_OnPcDying(object oPC);
  46.  
  47. // OnDyingBleed event specific to PCs
  48. void Death_OnPcDyingBleed(object oPC);
  49.  
  50. // OnDeath event common to all monsters, NPCs, and PCs
  51. void Death_OnDeath(object oCreature, object oKiller);
  52.  
  53. // OnDeath event add-on specific to PCs
  54. void Death_OnPcDeath(object oPC, object oKiller);
  55.  
  56. // OnSpawn event specific to PCs
  57. void Death_OnPcRespawn(object oPC);
  58.  
  59. // Returns wether or not the PC is dead
  60. int Death_GetIsPcDead(object oPC);
  61.  
  62. // Returns the owner of oCorpse
  63. object Death_GetCorpseOwner(object oCorpse);
  64.  
  65. // Sets the corpse properties for oPC
  66. void Death_SetCorpse(object oPC, object oCorpse);
  67.  
  68. // Create an interactive corpse of oPC at location lLoc
  69. void Death_CreateCorpseAtLocation(object oPC, location lLocation, int PlaceToken = TRUE, int iGruesome = FALSE);
  70.  
  71. // Create an interactive corpse of oPC in oCreature's inventory
  72. void Death_CreateCorpseOnCreature(object oPC, object oCreature, int iDestroyCreatureCorpse = TRUE);
  73.  
  74. // Forces oPC to drop any corpses it may be carrying
  75. void Death_DropAllCorpses(object oPC);
  76.  
  77. // Remove any existing corpse of oPC
  78. void Death_RemoveCorpse(object oPC, int iCorpseItemToo = 0);
  79.  
  80. // Returns whether or not oCreature can raise oCorpse by the specified nRaiseType
  81. // nRaiseType = 0 : Raise Dead by Spell
  82. // 1 : Raise Dead by Scroll
  83. // 2 : Raise Dead by Recall Spirit
  84. // 4 : Resurrect by Spell
  85. // 5 : Resurrect by Scroll
  86. int Death_CanRaiseCorpse(object oCreature, object oCorpse, int nRaiseType);
  87.  
  88. // Attempts to have oCreature raise the corpse by using nRaiseType, returns true if successful
  89. // nRaiseType = 0 : Raise Dead by Spell
  90. // 1 : Raise Dead by Scroll
  91. // 2 : Raise Dead by Recall Spirit
  92. // 4 : Resurrect by Spell
  93. // 5 : Resurrect by Scroll
  94. int Death_RaiseCorpse(object oCreature, object oCorpse, int nRaiseType);
  95.  
  96. // Brings oPC back to the world of the living
  97. // nDestination = 1 : DefaultRespawn
  98. // 2 : Corpse
  99. // 3 : Module Starting Location
  100. void Death_BringToLife(object oPC, int nDestination);
  101.  
  102. // Apply death penalty consequences to oCreature
  103. void Death_ApplyConsequences(object oCreature, int bIsPvP);
  104.  
  105.  
  106. /*
  107. Implementations
  108. */
  109.  
  110. //reset death override
  111. void ResetDeathLocationVar(object oPC)
  112. {
  113. SetLocalInt(oPC, "death_override", 0);
  114. }
  115.  
  116. void Death_OnPcLogin(object oPC)
  117. {
  118. object oItem;
  119. object oCorpse;
  120. location lLocation;
  121.  
  122. oItem = GetRequiredItem(oPC, DEATH_ITEMVARPERSIST);
  123.  
  124. if (GetIsObjectValid(oItem) == FALSE)
  125. { return; }
  126.  
  127. if (GetLocalInt(oItem, DEATH_VARISDEAD))
  128. {
  129. location lLoc = GetLocalLocation(oItem, "last_death_location");
  130. if(GetIsLocationValid(lLoc) == TRUE) {SetLocalInt(oPC, "death_override", 1);}
  131. //oCorpse = GetLocalObject(oItem, DEATH_VARCORPSE);
  132. DelayCommand(0.5, ResetDeathLocationVar(oPC));
  133.  
  134. effect eDeath = EffectDeath(FALSE, FALSE, TRUE, TRUE);
  135. ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oPC, 0.0);
  136.  
  137.  
  138. //if (GetIsObjectValid(oCorpse) == FALSE)
  139. //{
  140. //lLocation = GetLocalLocation(oItem, DEATH_VARCORPSELOCATION);
  141. //Death_CreateCorpseAtLocation(oPC, lLocation);
  142.  
  143. /*
  144. if (GetIsLocationValid(lLocation))
  145. { Death_CreateCorpseAtLocation(oPC, lLocation); }
  146. else
  147. {
  148. lLocation = GetLocalLocation(oItem, DEATH_VARLOCATION);
  149.  
  150. if (GetIsLocationValid(lLocation))
  151. { Death_CreateCorpseAtLocation(oPC, lLocation); }
  152. else
  153. { WriteTimestampedLogEntry("[Death System]: No corpse or death location available for '" + GetName(oPC) + "'."); }
  154. }
  155. */
  156. //}
  157.  
  158. // todo: Seems to me that we should automatically port anyone that is dead to the Fugue if they aren't there already.
  159. }
  160. }
  161.  
  162. void Death_OnPcDying(object oPC)
  163. {
  164. }
  165.  
  166. void Death_OnPcDyingBleed(object oPC)
  167. {
  168. }
  169.  
  170. void Death_OnDeath(object oCreature, object oKiller)
  171. {
  172. //SendMessageToPC(oCreature, "Death onDeath");
  173.  
  174. object oItemKiller;
  175. object oMaster;
  176. int iKills;
  177.  
  178. if (GetIsObjectValid(oCreature) == FALSE)
  179. { return; }
  180.  
  181. if (GetIsObjectValid(oKiller))
  182. {
  183. oMaster = GetMaster(oKiller);
  184.  
  185. if (GetIsObjectValid(oMaster))
  186. { oKiller = oMaster; }
  187. }
  188. //set killer to be trap creator
  189. if(GetBaseItemType(GetLastDamager(oCreature))==BASE_ITEM_TRAPKIT)
  190. {
  191. object oTrapCreator = GetTrapCreator(GetLastDamager(oCreature));
  192. if(GetIsPC(oTrapCreator) && GetIsObjectValid(oTrapCreator) == TRUE)
  193. {
  194. oKiller = oTrapCreator;
  195. }
  196. }
  197.  
  198. if (GetIsPC(oCreature) == TRUE)
  199. {
  200. // drop all corpses before the next piece of code
  201. Death_DropAllCorpses(oCreature);
  202. Death_OnPcDeath(oCreature, oKiller);
  203. }
  204.  
  205.  
  206. if (GetIsObjectValid(oKiller) == TRUE && GetIsPC(oKiller) == TRUE)
  207. {
  208. oItemKiller = GetRequiredItem(oKiller, DEATH_ITEMVARPERSIST);
  209.  
  210. if (GetIsObjectValid(oItemKiller))
  211. {
  212. iKills = GetLocalInt(oItemKiller, DEATH_VARTOTALKILLS);
  213. iKills++;
  214. SetLocalInt(oItemKiller, DEATH_VARTOTALKILLS, iKills);
  215.  
  216. if (GetIsPC(oCreature) == FALSE)
  217. {
  218. iKills = GetLocalInt(oItemKiller, DEATH_VARMKILLS);
  219. iKills++;
  220. SetLocalInt(oItemKiller, DEATH_VARMKILLS, iKills);
  221. }
  222. }
  223. }
  224. }
  225.  
  226. //remove this variable after a delay
  227. void RemovePvPKiller(object oPC)
  228. {
  229. DeleteLocalObject(oPC, "MyKiller");
  230. }
  231.  
  232. //send messages and set subdual status
  233. void UnPlot(object oPC)
  234. {
  235. if(GetArea(oPC) == OBJECT_INVALID) {DelayCommand(4.0, UnPlot(oPC)); return;}
  236. else
  237. {
  238. SetImmortal(oPC,FALSE);
  239. }
  240. }
  241.  
  242. //send messages and set subdual status
  243. void CoupDeGracePeriod(object oPC, object oKiller)
  244. {
  245. SetLocalInt(oPC,"SUBDUAL", 2); //set to status 2 so can be coup de graced
  246.  
  247. SetImmortal(oPC,FALSE);
  248.  
  249. SendMessageToPC(oKiller, "You can now perform a coup de grâce action on "+GetName(oPC));
  250. SendMessageToPC(oPC, "A coup de grâce action can be performed on you by "+GetName(oKiller));
  251. }
  252.  
  253. void Death_OnPcDeath(object oPC, object oKiller)
  254. {
  255. //SendMessageToPC(oPC, "Death on PC Death");
  256.  
  257. object oItemPC;
  258. object oItemKiller;
  259. object oCorpsePlaceable;
  260. object oWaypoint;
  261. location lLocation;
  262. location lWpLocation;
  263. int iKills;
  264. int iDeaths;
  265. int bIsPvP;
  266. int iHpCurrent;
  267. effect eEffect;
  268. string sReport;
  269.  
  270. int iTrapDeath=0;
  271. object oDamager = GetLastDamager(oPC);
  272. if(GetBaseItemType(oDamager)==BASE_ITEM_TRAPKIT)
  273. {
  274. object oTrapCreator = GetTrapCreator(oDamager);
  275. if(GetIsPC(oTrapCreator) && GetIsObjectValid(oTrapCreator) == TRUE)
  276. {
  277. iTrapDeath=1;
  278. oKiller = oTrapCreator;
  279. }
  280. }
  281.  
  282. //counts creatures as attacking for their masters
  283. if(GetMaster(oKiller) != OBJECT_INVALID)
  284. {
  285. oKiller = GetMaster(oKiller);
  286. }
  287.  
  288. if(GetIsObjectValid(oKiller) == FALSE && iTrapDeath == 0 && GetIsObjectValid(GetLastDamager(oPC)) == TRUE)
  289. {oKiller = GetLastDamager(oPC);}
  290.  
  291. bIsPvP = FALSE;
  292.  
  293. oItemPC = GetRequiredItem(oPC, DEATH_ITEMVARPERSIST);
  294.  
  295. if (GetIsObjectValid(oItemPC) == FALSE)
  296. {SendMessageToPC(oPC, "Invalid Persistent kemo scry item"); return;}
  297.  
  298. //this person is already dead...
  299. if (GetLocalInt(oItemPC, DEATH_VARISDEAD) == TRUE)
  300. {
  301. SendMessageToPC(oPC, "You are supposed to be dead already...");
  302. ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), oPC);
  303. ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(GetMaxHitPoints(oPC)), oPC);
  304. ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectEthereal(), oPC, 10.0);
  305.  
  306. SetImmortal(oPC, TRUE);
  307. DelayCommand(8.0, UnPlot(oPC));
  308.  
  309. DeleteLocalInt(oPC,"SUBDUAL"); //remove subdual
  310. DeleteLocalInt(oPC,"SUB_COOL"); //remove subdual
  311.  
  312. oWaypoint = GetWaypointByTag(DEATH_WPDEATHAREA);
  313. lWpLocation = GetLocation(oWaypoint);
  314.  
  315. DelayCommand(0.8, AssignCommand(oPC, ClearAllActions(TRUE)));
  316. DelayCommand(0.81, AssignCommand(oPC, JumpToLocation(lWpLocation)));
  317.  
  318. object oMyCorpse = GetLocalObject(oItemPC, DEATH_VARCORPSECREATURE);
  319. if(GetIsObjectValid(oMyCorpse) == FALSE) {oMyCorpse = GetLocalObject(oItemPC, DEATH_VARCORPSEITEM);}
  320.  
  321. //I am just entering the server but am dead...or I am dead but have no corpse
  322. if(GetLocalInt(oPC, "death_override") == 1 || GetIsObjectValid(oMyCorpse) == FALSE)
  323. {
  324. SetLocalInt(oPC, "death_override", 0);
  325. location lDeath = GetLocalLocation(oItemPC, "last_death_location");
  326. //make sure we have a location
  327. if(GetIsLocationValid(lDeath) == FALSE) {lDeath = GetLocalLocation(oItemPC, DEATH_VARCORPSELOCATION);}
  328. if(GetIsLocationValid(lDeath) == FALSE) {lDeath = GetLocalLocation(oItemPC, DEATH_VARLOCATION);}
  329. if(GetIsLocationValid(lDeath) == FALSE) {lDeath = CalcSafeLocation(oPC, GetLocation(oPC), 2.2, FALSE, TRUE);}
  330. Death_CreateCorpseAtLocation(oPC, lDeath, TRUE);
  331. }
  332.  
  333. return;
  334. }
  335.  
  336. lLocation = GetLocation(oPC);
  337.  
  338. //already subdued, can we coup de grace?
  339. if(GetLocalInt(oPC,"SUBDUAL") == 2)
  340. {
  341. object oSubduer = GetLocalObject(oPC, "MyKiller");
  342. //death
  343. if(GetLastDamager(oPC) == oSubduer)
  344. {
  345.  
  346. ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), oPC);
  347. ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectEthereal(), oPC, 10.0);
  348. ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(GetMaxHitPoints(oPC)), oPC);
  349.  
  350. SetImmortal(oPC,TRUE);
  351. DelayCommand(8.0, UnPlot(oPC));
  352.  
  353. SetLocalInt(oItemPC, DEATH_VARISDEAD, TRUE);
  354. DeleteLocalInt(oPC,"SUBDUAL"); //remove subdual
  355. DeleteLocalInt(oPC,"SUB_COOL"); //remove subdual
  356.  
  357. //upon PvP Death don't deduct XP
  358. SetLocalInt(oItemPC, "free_xp_death", TRUE);
  359.  
  360. SendMessageToPC(oSubduer, "You performed Coup de grâce action on "+GetName(oPC));
  361. SendMessageToPC(oPC, "A Coup de grâce action was performed on you by "+GetName(oSubduer));
  362.  
  363. //die
  364. SendMessageToPC(oPC, "You feel yourself being drawn to the light...");
  365. oWaypoint = GetWaypointByTag(DEATH_WPDEATHAREA);
  366. lWpLocation = GetLocation(oWaypoint);
  367. AssignCommand(oPC, ClearAllActions(TRUE));
  368. AssignCommand(oPC, JumpToLocation(lWpLocation));
  369.  
  370. Death_CreateCorpseAtLocation(oPC, lLocation, TRUE, TRUE);
  371. return;
  372. }
  373. //no death - rez if killed by unauthorized player
  374. else
  375. {
  376. SendMessageToPC(oKiller, GetName(oPC)+" cannot be killed while incapacitated except through a coup de grâce action by his subduer");
  377. effect eRessurect = EffectResurrection();
  378. ApplyEffectToObject(DURATION_TYPE_INSTANT, eRessurect, oPC, 0.0);
  379. SetLocalInt(oItemPC, DEATH_VARISDEAD, FALSE);
  380. if(GetIsDead(oPC, FALSE) == TRUE)
  381. {
  382. int iHP = GetCurrentHitPoints(oPC);
  383. if(iHP < 3)
  384. {
  385. effect eHeal = EffectHeal(13);
  386. ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC, 0.0);
  387. }
  388. else if(iHP > 3)
  389. {
  390. effect eDamage = EffectDamage(iHP - 3, DAMAGE_TYPE_POSITIVE, DAMAGE_POWER_PLUS_TWENTY, TRUE);
  391. ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC, 0.0);
  392. }
  393. //ExecuteScript("subdual_cooldown",oPC);
  394. //enable subdual again
  395. }
  396. //effect eParalyze = EffectCutsceneDominated();
  397. //eParalyze = SetEffectSpellId(eParalyze, 147000); //any effect
  398. //DelayCommand(0.15, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eParalyze, oPC, IntToFloat(GetLocalInt(oPC,"SUB_COOL")) - 0.15));
  399. SendMessageToPC(oPC, "You can only be killed by your subduer");
  400. return;
  401. }
  402. }
  403.  
  404. SetLocalInt(oItemPC, DEATH_VARISDEAD, TRUE);
  405.  
  406. iDeaths = GetLocalInt(oItemPC, DEATH_VARTOTALDEATHS);
  407. iDeaths++;
  408. SetLocalInt(oItemPC, DEATH_VARTOTALDEATHS, iDeaths);
  409.  
  410. //Killed by PC and not Subdued yet, trap death too
  411. if(GetIsPC(GetLastHostileActor(oPC)) == TRUE || GetIsPC(GetMaster(GetLastHostileActor(oPC))) == TRUE || iTrapDeath == 1 && GetLocalInt(oPC,"SUBDUAL") == 0)
  412. {
  413. if (GetIsPC(oKiller) == TRUE)
  414. {
  415. bIsPvP = TRUE;
  416.  
  417. SetLocalInt(oItemPC, DEATH_VARKILLERISPC, TRUE);
  418.  
  419. oItemKiller = GetRequiredItem(oKiller, DEATH_ITEMVARPERSIST);
  420.  
  421. if (GetIsObjectValid(oItemKiller))
  422. {
  423. iKills = GetLocalInt(oItemKiller, DEATH_VARPKILLS);
  424. iKills++;
  425. SetLocalInt(oItemKiller, DEATH_VARPKILLS, iKills);
  426. }
  427.  
  428. iDeaths = GetLocalInt(oItemPC, DEATH_VARPDEATHS);
  429. iDeaths++;
  430. SetLocalInt(oItemPC, DEATH_VARPDEATHS, iDeaths);
  431. }
  432. else
  433. {
  434. SetLocalInt(oItemPC, DEATH_VARKILLERISPC, FALSE);
  435.  
  436. iDeaths = GetLocalInt(oItemPC, DEATH_VARMDEATHS);
  437. iDeaths++;
  438. SetLocalInt(oItemPC, DEATH_VARMDEATHS, iDeaths);
  439. }
  440. }
  441. else
  442. {
  443. SetLocalInt(oItemPC, DEATH_VARKILLERISPC, FALSE);
  444.  
  445. iDeaths = GetLocalInt(oItemPC, DEATH_VARMDEATHS);
  446. iDeaths++;
  447. SetLocalInt(oItemPC, DEATH_VARMDEATHS, iDeaths);
  448. }
  449.  
  450. SetLocalLocation(oItemPC, "last_death_location", lLocation);
  451. SetLocalLocation(oItemPC, DEATH_VARLOCATION, lLocation);
  452. SetLocalLocation(oItemPC, DEATH_VARCORPSELOCATION, lLocation);
  453.  
  454. sReport = "<c=skyblue>You have died " + IntToString(GetLocalInt(oItemPC, DEATH_VARTOTALDEATHS)) + " times. ";
  455. sReport = sReport + IntToString(GetLocalInt(oItemPC, DEATH_VARPDEATHS)) + " times from players and ";
  456. sReport = sReport + IntToString(GetLocalInt(oItemPC, DEATH_VARMDEATHS)) + " times from monsters.</c>";
  457. SendMessageToPC(oPC, sReport);
  458.  
  459. eEffect = GetFirstEffect(oPC);
  460.  
  461. while (GetIsEffectValid(eEffect))
  462. {
  463. RemoveEffect(oPC, eEffect);
  464. eEffect = GetNextEffect(oPC);
  465. }
  466.  
  467. if (bIsPvP == TRUE && GetLocalInt(oPC,"SUBDUAL") == 0)
  468. {
  469. ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), oPC);
  470. ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectEthereal(), oPC, 20.0);
  471. //ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(GetMaxHitPoints(oPC)), oPC);
  472.  
  473. effect eParalyze1 = EffectCutsceneParalyze();
  474. eParalyze1 = EffectLinkEffects(eParalyze1, EffectKnockdown());
  475. eParalyze1 = SetEffectSpellId(eParalyze1, 147000); //any effect
  476. ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eParalyze1, oPC, 90.0);
  477.  
  478. DeleteLocalInt(oPC,"SUB_COOL"); //remove subdual
  479. SetImmortal(oPC,TRUE);
  480. SetLocalInt(oPC,"SUBDUAL", 1); //set to status 1 so cannot die
  481. SetLocalObject(oPC, "MyKiller", oKiller);
  482. SetLocalObject(oKiller, "LastPvPKilled", oPC);
  483. DelayCommand(90.0, RemovePvPKiller(oPC)); //delete after subdual period
  484. SendMessageToPC(oPC, "You are incapacitated...");
  485. SetLocalInt(oItemPC, DEATH_VARISDEAD, FALSE);
  486. SendMessageToAllDMs("PVP DEATH: "+GetFirstName(oKiller)+" "+GetLastName(oKiller)+" "+IntToString(GetHitDice(oKiller))+" has killed "+GetFirstName(oPC)+" "+GetLastName(oPC)+" ("+IntToString(GetHitDice(oPC))+") at "+GetName(GetArea(oKiller)));
  487.  
  488. int iHP = GetCurrentHitPoints(oPC);
  489. if(iHP < 3)
  490. {
  491. effect eHeal = EffectHeal(13);
  492. ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC, 0.0);
  493. }
  494. else if(iHP > 3)
  495. {
  496. effect eDamage = EffectDamage(iHP - 3, DAMAGE_TYPE_POSITIVE, DAMAGE_POWER_PLUS_TWENTY, TRUE);
  497. ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC, 0.0);
  498. }
  499.  
  500. //after 20 seconds a coup de grace can be done
  501. DelayCommand(20.0, CoupDeGracePeriod(oPC, oKiller));
  502.  
  503. //set subdual
  504. ExecuteScript("subdual_cooldown",oPC);
  505. return;
  506. }
  507. else
  508. {
  509. ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), oPC);
  510. ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectEthereal(), oPC, 10.0);
  511. ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(GetMaxHitPoints(oPC)), oPC);
  512.  
  513. SendMessageToPC(oPC, "You feel yourself being drawn to the light...");
  514. oWaypoint = GetWaypointByTag(DEATH_WPDEATHAREA);
  515. lWpLocation = GetLocation(oWaypoint);
  516. AssignCommand(oPC, ClearAllActions(TRUE));
  517. AssignCommand(oPC, JumpToLocation(lWpLocation));
  518.  
  519. Death_CreateCorpseAtLocation(oPC, lLocation, TRUE);
  520. }
  521. }
  522.  
  523. void Death_OnPcRespawn(object oPC)
  524. {
  525. }
  526.  
  527. int Death_GetIsPcDead(object oPC)
  528. {
  529. object oItem;
  530.  
  531. if (GetIsObjectValid(oPC) == FALSE)
  532. { return FALSE; }
  533.  
  534. oItem = GetRequiredItem(oPC, DEATH_ITEMVARPERSIST);
  535.  
  536. if (GetIsObjectValid(oItem) == FALSE)
  537. { return FALSE; }
  538.  
  539. if (GetLocalInt(oItem, DEATH_VARISDEAD) == TRUE)
  540. { return TRUE; }
  541.  
  542. return FALSE;
  543. }
  544.  
  545. object Death_GetCorpseOwner(object oCorpse)
  546. {
  547. object oOwner;
  548.  
  549. if (GetIsObjectValid(oCorpse) == FALSE)
  550. { return OBJECT_INVALID; }
  551.  
  552. oOwner = GetLocalObject(oCorpse, DEATH_VAROWNER);
  553.  
  554. if (GetIsObjectValid(oOwner) == FALSE)
  555. { return OBJECT_INVALID; }
  556.  
  557. return oOwner;
  558. }
  559.  
  560. void Death_SetCorpse(object oPC, object oCorpse)
  561. {
  562. //SendMessageToPC(oPC, "Setting Corpse");
  563.  
  564. object oItem;
  565. string sName;
  566. string sDescription;
  567. string sAppearance;
  568. int iAppearance;
  569. string sScale;
  570. float fScaleX;
  571. float fScaleY;
  572. float fScaleZ;
  573.  
  574. if (GetIsObjectValid(oPC) == FALSE
  575. || GetIsObjectValid(oCorpse) == FALSE)
  576. {
  577. SendMessageToPC(oPC, "<color=RED><b>ERROR_1_: PC OR CORPSE INVALID. Please report this to a DM.</b></color>");
  578. return;
  579. }
  580.  
  581. oItem = GetRequiredItem(oPC, DEATH_ITEMVARPERSIST);
  582.  
  583. if (GetIsObjectValid(oItem) == FALSE)
  584. {
  585. SendMessageToPC(oPC, "<color=RED><b>ERROR_2_: INVALID DEATH_ITEMVARPERSIST. Please report this to a DM.</b></color>");
  586. return;
  587. }
  588.  
  589. sName = GetName(oPC); //GetFirstName(oPC) + " " + GetLastName(oPC);
  590. sDescription = "This is the corpse of " + sName;
  591.  
  592. SetDescription(oCorpse, sDescription);
  593.  
  594. int iType = GetObjectType(oCorpse);
  595. if(iType == OBJECT_TYPE_CREATURE) {SetLocalObject(oItem, DEATH_VARCORPSECREATURE, oCorpse); SendMessageToPC(oPC, "Set Corpse Creature");} //set creature
  596. else {SetLocalObject(oItem, DEATH_VARCORPSEITEM, oCorpse); SetFirstName(oCorpse, sName); SendMessageToPC(oPC, "Set Corpse Item");} //set item
  597.  
  598. SetLocalObject(oCorpse, DEATH_VAROWNER, oPC);
  599. SendMessageToPC(oPC, "Owner of "+GetName(oCorpse)+" = "+GetName(oPC));
  600. }
  601.  
  602. //destroy all items on corpse oPC
  603. void Unlootable(object xPC)
  604. {
  605. //Set variables
  606. int xGold, xCount;
  607. xGold = GetGold(xPC);
  608. AssignCommand(xPC, ClearAllActions(TRUE));
  609. DelayCommand(0.5, AssignCommand(xPC, TakeGoldFromCreature( xGold,xPC,TRUE)));
  610. object xItem;
  611. //Let's see who we're ripping off today..
  612. //Destroy the inventory items
  613. xItem = GetFirstItemInInventory(xPC);
  614.  
  615. while(GetIsObjectValid(xItem))
  616. {
  617. //DestroyObject(xItem);
  618. SetDroppableFlag(xItem, FALSE);
  619. xItem = GetNextItemInInventory(xPC);
  620. }
  621. // Empty all inventory slots
  622. // Change 18 to 14 to not strip creature slots
  623. for (xCount = 0; xCount < 18; xCount++)
  624. //DestroyObject( GetItemInSlot( xCount, xPC));
  625. SetDroppableFlag(GetItemInSlot( xCount, xPC), FALSE );
  626. //Now let's get greedy and take the gold!
  627. }
  628.  
  629. void Death_CreateCorpseAtLocation(object oPC, location lLocation, int PlaceToken = TRUE, int iGruesome = FALSE)
  630. {
  631. //SendMessageToPC(oPC, "Creating Corpse at Location");
  632.  
  633. object oItem;
  634. object oCorpse;
  635. string sPlaceable;
  636. //string sId = GetLocalString(oPC, "SID");
  637. string sId = GetName(oPC);
  638. int nGender = GetGender(oPC);
  639. string sResRef;
  640.  
  641.  
  642. if (nGender == GENDER_MALE)
  643. sResRef = "pc_corpse_male";
  644. else
  645. sResRef = "pc_corpse_female";
  646.  
  647. string sTag = sId + "_corpse";
  648.  
  649.  
  650. if (GetIsObjectValid(oPC) == FALSE)
  651. {
  652. SendMessageToPC(oPC, "<color=RED><b>ERROR1: INVALID PC. Please report this to a DM.</b></color>");
  653. return;
  654. }
  655.  
  656. oItem = GetRequiredItem(oPC, DEATH_ITEMVARPERSIST);
  657.  
  658. if (GetIsObjectValid(oItem) == FALSE)
  659. {
  660. SendMessageToPC(oPC, "<color=RED><b>ERROR2: INVALID DEATH_ITEMVARPERSIST. Please report this to a DM.</b></color>");
  661. return;
  662. }
  663.  
  664. oCorpse = GetLocalObject(oItem, DEATH_VARCORPSECREATURE);
  665.  
  666. if(GetIsLocationValid(lLocation) == FALSE)
  667. {
  668. lLocation = CalcSafeLocation(oPC, lLocation, 2.2, FALSE, TRUE);
  669. }
  670.  
  671. //destroy corpse item if it already exists
  672. int iSetToDestroy = 0;
  673. object oCorpse2 = GetLocalObject(oItem, DEATH_VARCORPSEITEM);
  674. if (GetIsObjectValid(oCorpse2) == TRUE)
  675. {
  676. //SendMessageToPC(oPC, "<color=RED><b>Corpse already detected</b></color>");
  677. SetImmortal(oCorpse2, FALSE);
  678. AssignCommand(oCorpse2, SetIsDestroyable(TRUE, FALSE, FALSE));
  679. object oTalker2 = GetObjectByTag(GetTag(oCorpse2)+"_conv", 0);
  680. if(GetIsObjectValid(oTalker2) == TRUE)
  681. {
  682. AssignCommand(oTalker2, SetIsDestroyable(TRUE, FALSE, FALSE));
  683. DestroyObject(oTalker2);
  684. oTalker2 = OBJECT_INVALID;
  685. }
  686. DestroyObject(oCorpse2, 2.5);
  687. oCorpse2 = OBJECT_INVALID; //set corpse to be invalid again
  688. SetLocalObject(oItem, DEATH_VARCORPSEITEM, OBJECT_INVALID);
  689. iSetToDestroy = 1;
  690. }
  691.  
  692. //destroy corpse body if it already exists
  693. if (GetIsObjectValid(oCorpse) == TRUE)
  694. {
  695. Unlootable(oCorpse);
  696. //SendMessageToPC(oPC, "<color=RED><b>Corpse already detected</b></color>");
  697. SetImmortal(oCorpse, FALSE);
  698. AssignCommand(oCorpse, SetIsDestroyable(TRUE, FALSE, FALSE));
  699. object oTalker = GetObjectByTag(GetTag(oCorpse)+"_conv", 0);
  700. if(GetIsObjectValid(oTalker) == TRUE)
  701. {
  702. AssignCommand(oTalker, SetIsDestroyable(TRUE, FALSE, FALSE));
  703. DestroyObject(oTalker);
  704. oTalker = OBJECT_INVALID;
  705. }
  706. DestroyObject(oCorpse, 2.5);
  707. oCorpse = OBJECT_INVALID; //set corpse to be invalid again
  708. SetLocalObject(oItem, DEATH_VARCORPSECREATURE, OBJECT_INVALID);
  709. iSetToDestroy = 1;
  710. }
  711.  
  712. if (GetGender(oPC) == GENDER_FEMALE)
  713. { sPlaceable = DEATH_PLACEABLECORPSEFEMALE; }
  714. else
  715. { sPlaceable = DEATH_PLACEABLECORPSEMALE; }
  716.  
  717. if(GetIsObjectValid(oCorpse) == FALSE || iSetToDestroy == 1)
  718. {
  719. lLocation = CalcSafeLocation(oPC, lLocation, 3.0, FALSE, FALSE);
  720. //SendMessageToPC(oPC, "<color=RED><b>Creating Corpse</b></color>");
  721. //corpse
  722. oCorpse = CopyObject(oPC, lLocation, OBJECT_INVALID, sTag);
  723.  
  724. if(GetIsObjectValid(oCorpse) == TRUE)
  725. {
  726. SetLocalInt(oCorpse, "is_player_lookalike_corpse", 1); //allow ressurection
  727. DelayCommand(0.1, Unlootable(oCorpse));
  728. //place corpse token on the corpse
  729. if(PlaceToken == TRUE) {DelayCommand(0.5, Death_CreateCorpseOnCreature(oPC, oCorpse, FALSE));}
  730. SetLootable(oCorpse, TRUE);
  731. SetCreatureScriptsToSet(oCorpse, 0);
  732. ChangeToStandardFaction(oCorpse, STANDARD_FACTION_DEFENDER);
  733. SetBumpState(oCorpse, BUMPSTATE_UNBUMPABLE);
  734. effect eDeath = EffectDeath(FALSE, FALSE, TRUE, TRUE);
  735. if(iGruesome == TRUE) {eDeath = EffectDeath(TRUE, FALSE, TRUE, TRUE);}
  736. DelayCommand(1.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oCorpse, 0.0));
  737. AssignCommand(oCorpse, SetIsDestroyable(FALSE, FALSE, TRUE));
  738.  
  739.  
  740. //placeable blood
  741. string sBlueprint = "pc_corpse_talker1";
  742. int i4 = d6();
  743. if(i4 == 4) {sBlueprint = "pc_corpse_talker4";}
  744. if(i4 == 6) {sBlueprint = "pc_corpse_talker5";}
  745. if(i4 == 5) {sBlueprint = "pc_corpse_talker6";}
  746. else if(i4 == 3) {sBlueprint = "pc_corpse_talker3";}
  747. else if(i4 == 2) {sBlueprint = "pc_corpse_talker2";}
  748.  
  749. //spawn backup plc
  750. object oPlc = CreateObject(OBJECT_TYPE_PLACEABLE, sBlueprint, lLocation, FALSE, sTag+"_conv");
  751. if(GetIsObjectValid(oPlc) == FALSE)
  752. {
  753. lLocation = CalcSafeLocation(oPC, lLocation, 3.0, FALSE, TRUE);
  754. oPlc = CreateObject(OBJECT_TYPE_PLACEABLE, sBlueprint, lLocation, FALSE, sTag+"_conv");
  755. }
  756. if(GetIsObjectValid(oPlc) == TRUE)
  757. {
  758. AssignCommand(oPlc, SetFacing(IntToFloat(Random(360) + 1), FALSE));
  759. SetLocalObject(oPlc, "pc_corpse_talker", oCorpse);
  760. SetFirstName(oPlc, GetName(oPC)+"'s Grave");
  761. AssignCommand(oPlc, SetIsDestroyable(FALSE, FALSE, TRUE));
  762. }
  763. if (GetIsObjectValid(oPlc) == FALSE)
  764. {
  765. object oMe = GetPrimaryPlayer();
  766. SendMessageToPC(oMe, "<color=RED><b>ERROR3: INVALID BLOOD POOL. Please report this to a DM.</b></color>");
  767. }
  768. }
  769. }
  770.  
  771. if (GetIsObjectValid(oCorpse) == FALSE)
  772. {
  773. oCorpse = CreateObject(OBJECT_TYPE_PLACEABLE, sPlaceable, lLocation, FALSE, sTag);
  774. }
  775. if (GetIsObjectValid(oCorpse) == FALSE)
  776. {
  777. oCorpse = GetObjectByTag(sTag);
  778. if (GetIsObjectValid(oCorpse) == FALSE)
  779. {
  780. //Add a safe location search if the original is invalid for some reason
  781. location lSafe = CalcSafeLocation(oPC, lLocation, 2.0, FALSE, FALSE);
  782. if(GetIsLocationValid(lLocation) == TRUE)
  783. {
  784. oCorpse = CreateObject(OBJECT_TYPE_PLACEABLE, sPlaceable, lLocation, FALSE, sTag);
  785. if (GetIsObjectValid(oCorpse) == FALSE)
  786. {
  787. oCorpse = GetObjectByTag(sTag);
  788. if (GetIsObjectValid(oCorpse) == FALSE)
  789. {
  790. SendMessageToPC(oPC, "<color=RED><b>ERROR3: Corpse is Invalid. Please report this to a DM.</b></color>");
  791. }
  792. }
  793. }
  794. }
  795. else
  796. {
  797. SendMessageToPC(oPC, "<color=RED><b>ERROR3: Corpse is Invalid, backup location failed. Please report this to a DM.</b></color>");
  798. }
  799. }
  800.  
  801. if(GetEventHandler(oCorpse, 12) != "p_corpse_us")
  802. {
  803. SetEventHandler(oCorpse, 12, "p_corpse_us"); //on used dialogue
  804. }
  805.  
  806. if (GetIsObjectValid(oCorpse) == FALSE)
  807. {
  808. SendMessageToPC(oPC, "<color=RED><b>ERROR3: Corpse is Invalid, backup location failed. Please report this to a DM.</b></color>");
  809. }
  810.  
  811. SetLocalLocation(oItem, DEATH_VARLOCATION, lLocation);
  812. SetLocalLocation(oItem, DEATH_VARCORPSELOCATION, lLocation);
  813.  
  814. Death_SetCorpse(oPC, oCorpse);
  815.  
  816. SaveCharacter(oPC);
  817. }
  818.  
  819. void Death_CreateCorpseOnCreature(object oPC, object oCreature, int iDestroyCreatureCorpse = TRUE)
  820. {
  821. object oItem;
  822. object oCorpse;
  823.  
  824. if (GetIsObjectValid(oPC) == FALSE || GetIsObjectValid(oCreature) == FALSE)
  825. { return; }
  826.  
  827. oItem = GetRequiredItem(oPC, DEATH_ITEMVARPERSIST);
  828.  
  829. if (GetIsObjectValid(oItem) == FALSE)
  830. { return; }
  831.  
  832. object oCorpse2 = GetLocalObject(oItem, DEATH_VARCORPSEITEM);
  833. if (GetIsObjectValid(oCorpse2) == TRUE && iDestroyCreatureCorpse == TRUE)
  834. {
  835. SetImmortal(oCorpse2, FALSE);
  836. AssignCommand(oCorpse2, SetIsDestroyable(TRUE, FALSE, FALSE));
  837. object oTalker2 = GetObjectByTag(GetTag(oCorpse2)+"_conv", 0);
  838. if(GetIsObjectValid(oTalker2) == TRUE)
  839. {
  840. AssignCommand(oTalker2, SetIsDestroyable(TRUE, FALSE, FALSE));
  841. DestroyObject(oTalker2);
  842. oTalker2 = OBJECT_INVALID;
  843. }
  844. int iType = GetObjectType(oCorpse2);
  845. if(iType == OBJECT_TYPE_CREATURE) {DeleteLocalObject(oItem, DEATH_VARCORPSECREATURE);} //set creature
  846. else {DeleteLocalObject(oItem, DEATH_VARCORPSEITEM);} //set item
  847.  
  848. DestroyObject(oCorpse2);
  849. oCorpse2 = OBJECT_INVALID;
  850. }
  851.  
  852. oCorpse = GetLocalObject(oItem, DEATH_VARCORPSECREATURE);
  853. if (GetIsObjectValid(oCorpse) == TRUE && iDestroyCreatureCorpse == TRUE)
  854. {
  855. Unlootable(oCorpse);
  856. SetImmortal(oCorpse, FALSE);
  857. AssignCommand(oCorpse, SetIsDestroyable(TRUE, FALSE, FALSE));
  858. object oTalker = GetObjectByTag(GetTag(oCorpse)+"_conv", 0);
  859. if(GetIsObjectValid(oTalker) == TRUE)
  860. {
  861. AssignCommand(oTalker, SetIsDestroyable(TRUE, FALSE, FALSE));
  862. DestroyObject(oTalker);
  863. oTalker = OBJECT_INVALID;
  864. }
  865. int iType = GetObjectType(oCorpse);
  866. if(iType == OBJECT_TYPE_CREATURE) {DeleteLocalObject(oItem, DEATH_VARCORPSECREATURE);} //set creature
  867. else {DeleteLocalObject(oItem, DEATH_VARCORPSEITEM);} //set item
  868.  
  869. DestroyObject(oCorpse);
  870. oCorpse = OBJECT_INVALID;
  871. }
  872.  
  873. object oCorpseItem = CreateItemOnObject(DEATH_ITEMCORPSE, oCreature);
  874. Death_SetCorpse(oPC, oCorpseItem);
  875.  
  876. SaveCharacter(oPC);
  877. }
  878.  
  879. void Death_DropAllCorpses(object oPC)
  880. {
  881. //SendMessageToPC(oPC, "Dropping Corpses");
  882.  
  883. object oCorpseItem;
  884. object oCorpsePlaceable;
  885. object oCorpseOwner;
  886. location lLocation;
  887.  
  888. if (GetIsObjectValid(oPC) == FALSE)
  889. {SendMessageToPC(oPC, "Invalid PC"); return; }
  890.  
  891. lLocation = GetLocation(oPC);
  892.  
  893. //only loop inventory if there is a corpse
  894. oCorpseItem = GetItemPossessedBy(oPC, DEATH_ITEMCORPSE);
  895. while (GetIsObjectValid(oCorpseItem) == TRUE)
  896. {
  897. oCorpseOwner = GetLocalObject(oCorpseItem, DEATH_VAROWNER);
  898. string sName = GetName(oCorpseOwner);
  899. SendMessageToPC(oPC, "Dropping Corpse "+sName);
  900. if (GetIsObjectValid(oCorpseOwner) == TRUE)
  901. {
  902. Death_CreateCorpseAtLocation(oCorpseOwner, lLocation);
  903. }
  904. else
  905. {
  906. DestroyObject(oCorpseItem);
  907. }
  908. oCorpseItem = GetNextItemInInventory(oPC);
  909. //oCorpseItem = GetItemPossessedBy(oPC, DEATH_ITEMCORPSE);
  910. }
  911. }
  912.  
  913. void Death_RemoveCorpse(object oPC, int iCorpseItemToo = 0)
  914. {
  915. object oItem;
  916. object oCorpse;
  917.  
  918. if (GetIsObjectValid(oPC) == FALSE)
  919. { return; }
  920.  
  921. oItem = GetRequiredItem(oPC, DEATH_ITEMVARPERSIST);
  922.  
  923. if (GetIsObjectValid(oItem) == FALSE)
  924. { return; }
  925.  
  926. object oCorpse2 = GetLocalObject(oItem, DEATH_VARCORPSEITEM);
  927. if (GetIsObjectValid(oCorpse2) == TRUE && iCorpseItemToo == TRUE)
  928. {
  929. SetImmortal(oCorpse2, FALSE);
  930. AssignCommand(oCorpse2, SetIsDestroyable(TRUE, FALSE, FALSE));
  931. object oTalker2 = GetObjectByTag(GetTag(oCorpse2)+"_conv", 0);
  932. if(GetIsObjectValid(oTalker2) == TRUE)
  933. {
  934. AssignCommand(oTalker2, SetIsDestroyable(TRUE, FALSE, FALSE));
  935. DestroyObject(oTalker2);
  936. oTalker2 = OBJECT_INVALID;
  937. }
  938. int iType = GetObjectType(oCorpse2);
  939. if(iType == OBJECT_TYPE_CREATURE) {DeleteLocalObject(oItem, DEATH_VARCORPSECREATURE);} //set creature
  940. else {DeleteLocalObject(oItem, DEATH_VARCORPSEITEM);} //set item
  941.  
  942. DestroyObject(oCorpse2);
  943. oCorpse2 = OBJECT_INVALID;
  944. }
  945.  
  946. oCorpse = GetLocalObject(oItem, DEATH_VARCORPSECREATURE);
  947. if (GetIsObjectValid(oCorpse))
  948. {
  949. Unlootable(oCorpse);
  950. SetImmortal(oCorpse, FALSE);
  951. AssignCommand(oCorpse, SetIsDestroyable(TRUE, FALSE, FALSE));
  952. object oTalker = GetObjectByTag(GetTag(oCorpse)+"_conv", 0);
  953. if(GetIsObjectValid(oTalker) == TRUE)
  954. {
  955. AssignCommand(oTalker, SetIsDestroyable(TRUE, FALSE, FALSE));
  956. DestroyObject(oTalker);
  957. oTalker = OBJECT_INVALID;
  958. }
  959. int iType = GetObjectType(oCorpse);
  960. if(iType == OBJECT_TYPE_CREATURE) {DeleteLocalObject(oItem, DEATH_VARCORPSECREATURE);} //set creature
  961. else {DeleteLocalObject(oItem, DEATH_VARCORPSEITEM);} //set item
  962.  
  963. DestroyObject(oCorpse);
  964. oCorpse = OBJECT_INVALID;
  965. }
  966. }
  967.  
  968. int Death_CanRaiseCorpse(object oCreature, object oCorpse, int nRaiseType)
  969. {
  970. object oCorpseOwner;
  971. object oItem;
  972. int bCanRaise;
  973.  
  974. if (GetIsObjectValid(oCreature) == FALSE
  975. || GetIsObjectValid(oCorpse) == FALSE)
  976. {
  977. return FALSE;
  978. }
  979.  
  980. oCorpseOwner = GetLocalObject(oCorpse, DEATH_VAROWNER);
  981.  
  982. if (GetIsObjectValid(oCorpseOwner) == FALSE)
  983. {
  984. return FALSE;
  985. }
  986.  
  987. oItem = GetRequiredItem(oCorpseOwner, DEATH_ITEMVARPERSIST);
  988.  
  989. if (GetIsObjectValid(oItem))
  990. {
  991. if (GetLocalInt(oItem, DEATH_VARISDEAD) == FALSE)
  992. {
  993. SetImmortal(oCorpse, FALSE);
  994. AssignCommand(oCorpse, SetIsDestroyable(TRUE, FALSE, FALSE));
  995. object oTalker = GetObjectByTag(GetTag(oCorpse)+"_conv", 0);
  996. if(GetIsObjectValid(oTalker) == TRUE)
  997. {
  998. AssignCommand(oTalker, SetIsDestroyable(TRUE, FALSE, FALSE));
  999. DestroyObject(oTalker);
  1000. oTalker = OBJECT_INVALID;
  1001. }
  1002. int iType = GetObjectType(oCorpse);
  1003. if(iType == OBJECT_TYPE_CREATURE) {DeleteLocalObject(oItem, DEATH_VARCORPSECREATURE);} //set creature
  1004. else {DeleteLocalObject(oItem, DEATH_VARCORPSEITEM);} //set item
  1005.  
  1006. DestroyObject(oCorpse);
  1007. oCorpse = OBJECT_INVALID;
  1008. return FALSE;
  1009. }
  1010. }
  1011.  
  1012. bCanRaise = FALSE;
  1013.  
  1014. switch (nRaiseType)
  1015. {
  1016. case 0:
  1017. if (GetHasSpell(DEATH_SPELLRAISE, oCreature) > 0)
  1018. { bCanRaise = TRUE; }
  1019. break;
  1020.  
  1021. case 1:
  1022. if (GetIsObjectValid(GetItemPossessedBy(oCreature, DEATH_ITEMRAISE)))
  1023. { bCanRaise = TRUE; }
  1024. break;
  1025.  
  1026. case 2:
  1027. if (GetHasFeat(DEATH_FEATRAISE, oCreature))
  1028. { bCanRaise = TRUE; }
  1029. break;
  1030.  
  1031. case 4:
  1032. if (GetHasSpell(DEATH_SPELLRESURRECT, oCreature) > 0)
  1033. { bCanRaise = TRUE; }
  1034. break;
  1035.  
  1036. case 5:
  1037. if (GetIsObjectValid(GetItemPossessedBy(oCreature, DEATH_ITEMRESURRECT)))
  1038. { bCanRaise = TRUE; }
  1039. break;
  1040. }
  1041. //debug code added yyrkoon -11-19-2009 to be removed begin
  1042. if(!bCanRaise)
  1043. {
  1044. //SendMessageToPC(oCreature, "<c=red>[Error] Raise method is not identified or failed </c>");
  1045. //SendMessageToPC(oCreature, "<c=red>[Error] Raise method is </c>" + IntToString(nRaiseType) + " please pm yyrkoon on forums with this error" );
  1046. //WriteTimestampedLogEntry("[Death System] yyrk error - Raise method is not identified or failed and nRaiseType = " + IntToString(nRaiseType) );
  1047. }
  1048. //debug code added by yyrkoon -11-19-2009 end
  1049. return bCanRaise;
  1050. }
  1051.  
  1052. void RaiseCorpseDelay(object oCreature, object oCorpse, int nRaiseType)
  1053. {
  1054. Death_RaiseCorpse(oCreature, oCorpse, nRaiseType);
  1055. }
  1056.  
  1057. int Death_RaiseCorpse(object oCreature, object oCorpse, int nRaiseType)
  1058. {
  1059. object oCorpseOwner;
  1060. object oItem;
  1061. effect eHeal;
  1062. location lLocation;
  1063.  
  1064. if (GetIsObjectValid(oCreature) == FALSE)
  1065. {
  1066. return FALSE;
  1067. }
  1068.  
  1069. if (GetIsObjectValid(oCorpse) == FALSE)
  1070. {
  1071. return FALSE;
  1072. }
  1073.  
  1074. //transition?
  1075. location lCurrent = GetLocation(oCreature);
  1076. if(GetArea(oCreature) == OBJECT_INVALID)
  1077. {
  1078. return FALSE;
  1079. }
  1080.  
  1081. oCorpseOwner = GetLocalObject(oCorpse, DEATH_VAROWNER);
  1082.  
  1083. if (GetIsObjectValid(oCorpseOwner) == FALSE)
  1084. {
  1085. return FALSE;
  1086. }
  1087.  
  1088. oItem = GetRequiredItem(oCorpseOwner, DEATH_ITEMVARPERSIST);
  1089. /*
  1090. if (GetIsObjectValid(oItem) == TRUE)
  1091. {
  1092. if (GetLocalInt(oItem, DEATH_VARISDEAD) == FALSE)
  1093. {
  1094. SetImmortal(oCorpse, FALSE);
  1095. AssignCommand(oCorpse, SetIsDestroyable(TRUE, FALSE, FALSE));
  1096. object oTalker = GetObjectByTag(GetTag(oCorpse)+"_conv", 0);
  1097. if(GetIsObjectValid(oTalker) == TRUE)
  1098. {
  1099. AssignCommand(oTalker, SetIsDestroyable(TRUE, FALSE, FALSE));
  1100. DestroyObject(oTalker);
  1101. oTalker = OBJECT_INVALID;
  1102. }
  1103. int iType = GetObjectType(oCorpse);
  1104. if(iType == OBJECT_TYPE_CREATURE) {DeleteLocalObject(oItem, DEATH_VARCORPSECREATURE);} //set creature
  1105. else {DeleteLocalObject(oItem, DEATH_VARCORPSEITEM);} //set item
  1106.  
  1107. DestroyObject(oCorpse);
  1108. oCorpse = OBJECT_INVALID;
  1109. return FALSE;
  1110. }
  1111. }
  1112. */
  1113. //full heal
  1114. if (nRaiseType == 4 || nRaiseType == 5)
  1115. {
  1116. eHeal = EffectHeal(GetMaxHitPoints(oCorpseOwner));
  1117. ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oCorpseOwner);
  1118. }
  1119. //Reincarnate
  1120. else if(nRaiseType == 6)
  1121. {
  1122. eHeal = EffectHeal(GetMaxHitPoints(oCorpseOwner));
  1123. ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oCorpseOwner);
  1124. //chance of complication
  1125. int iChance = d100();
  1126. if(iChance <= 10)
  1127. {
  1128. //change gender
  1129. int iGender = GetGender(oCorpseOwner);
  1130. if(iGender == GENDER_FEMALE) {iGender = GENDER_MALE;}
  1131. else {iGender = GENDER_FEMALE;}
  1132. SetGender(oCorpseOwner, iGender);
  1133. SendMessageToPC(oCorpseOwner, "<c=pink><i>Your gender has changed as a result of the Reincarnation spell!");
  1134. }
  1135. }
  1136. //bring back at 1 HP
  1137. else if(GetCurrentHitPoints(oCorpseOwner) >= 2)
  1138. {
  1139. eHeal = EffectDamage(GetCurrentHitPoints(oCorpseOwner) - 1, DAMAGE_TYPE_POSITIVE, DAMAGE_POWER_PLUS_TWENTY, TRUE);
  1140. ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oCorpseOwner);
  1141. }
  1142.  
  1143. lLocation = GetLocation(oCreature);
  1144. SetLocalLocation(oItem, DEATH_VARLOCATION, lLocation);
  1145. SetLocalLocation(oItem, DEATH_VARCORPSELOCATION, lLocation);
  1146.  
  1147. Death_BringToLife(oCorpseOwner, 2);
  1148.  
  1149. return TRUE;
  1150. }
  1151.  
  1152. void Death_BringToLife(object oPC, int nDestination)
  1153. {
  1154.  
  1155. object oItem;
  1156. object oCorpse;
  1157. object oCarrier;
  1158. object oWayPoint;
  1159. location lLocation;
  1160. int bSuccess;
  1161.  
  1162. //PC left the game
  1163. if (GetIsObjectValid(oPC) == FALSE)
  1164. {
  1165. return;
  1166. }
  1167.  
  1168. //transition?
  1169. if(GetArea(oPC) == OBJECT_INVALID)
  1170. {
  1171. return;
  1172. }
  1173.  
  1174. bSuccess = TRUE;
  1175. oItem = GetRequiredItem(oPC, DEATH_ITEMVARPERSIST);
  1176.  
  1177. if (GetIsObjectValid(oItem) == FALSE)
  1178. {
  1179. return;
  1180. }
  1181.  
  1182. if (GetLocalInt(oItem, DEATH_VARISDEAD) == FALSE)
  1183. {
  1184. return;
  1185. }
  1186.  
  1187. switch (nDestination)
  1188. {
  1189. //jump to default spawn place
  1190. case 1:
  1191. if (GetIsUnderdarkRace(oPC))
  1192. { oWayPoint = GetWaypointByTag(DEATH_WPDEFAULTSPAWNUD); }
  1193. else
  1194. { oWayPoint = GetWaypointByTag(DEATH_WPDEFAULTSPAWNNORMAL); }
  1195.  
  1196. if (GetIsObjectValid(oWayPoint))
  1197. {
  1198. AssignCommand(oPC, ActionJumpToObject(oWayPoint));
  1199. }
  1200. else
  1201. {
  1202. bSuccess = FALSE;
  1203. WriteTimestampedLogEntry("[Death System]: Waypoint does not exist.");
  1204. }
  1205.  
  1206. break;
  1207.  
  1208. //jump to corpse / carrier of corpse
  1209. case 2:
  1210. oCorpse = GetLocalObject(oItem, DEATH_VARCORPSECREATURE);
  1211. if (GetIsObjectValid(oCorpse) == FALSE) {oCorpse = GetLocalObject(oItem, DEATH_VARCORPSEITEM);}
  1212.  
  1213. if (GetIsObjectValid(oCorpse) == TRUE)
  1214. {
  1215. if (GetObjectType(oCorpse) == OBJECT_TYPE_PLACEABLE || GetObjectType(oCorpse) == OBJECT_TYPE_CREATURE)
  1216. {
  1217. AssignCommand(oPC, JumpToObject(oCorpse));
  1218. }
  1219. else
  1220. {
  1221. oCarrier = GetItemPossessor(oCorpse);
  1222.  
  1223. if (GetIsObjectValid(oCarrier))
  1224. {
  1225. AssignCommand(oPC, JumpToObject(oCarrier));
  1226. }
  1227. else
  1228. {
  1229. bSuccess = FALSE;
  1230. WriteTimestampedLogEntry("[Death System]: Corpse carrier is invalid.");
  1231. }
  1232. }
  1233. }
  1234. else
  1235. {
  1236. WriteTimestampedLogEntry("[Death System]: " + GetName(oPC) + "'s corpse is invalid.");
  1237.  
  1238. lLocation = GetLocalLocation(oItem, DEATH_VARCORPSELOCATION);
  1239. AssignCommand(oPC, JumpToLocation(lLocation));
  1240. }
  1241.  
  1242. break;
  1243.  
  1244. //jump to starting location
  1245. case 3:
  1246. {
  1247. lLocation = GetStartingLocation();
  1248. object oWPStart = GetWaypointByTag("wp_lobby_place");
  1249. if(oWPStart == OBJECT_INVALID)
  1250. {
  1251. oWPStart = CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", lLocation, FALSE, "wp_lobby_place");
  1252. }
  1253. //AssignCommand(oPC, JumpToLocation(lLocation));
  1254. AssignCommand(oPC, JumpToObject(oWPStart));
  1255. break;
  1256. }
  1257. case 4:
  1258. {
  1259. if (GetIsUnderdarkRace(oPC))
  1260. { oWayPoint = GetWaypointByTag("VARALLA_FROM_FUGUE"); }
  1261. else
  1262. { oWayPoint = GetWaypointByTag("FAI_NEXUS_JUMP"); }
  1263.  
  1264. if (GetIsObjectValid(oWayPoint))
  1265. {
  1266. AssignCommand(oPC, JumpToObject(oWayPoint));
  1267. }
  1268. else
  1269. {
  1270. bSuccess = FALSE;
  1271. WriteTimestampedLogEntry("[Death System]: Waypoint does not exist.");
  1272. }
  1273.  
  1274. break;
  1275. }
  1276. }
  1277.  
  1278. if (bSuccess)
  1279. {
  1280. SendMessageToPC(oPC, "<c=pink><i>You feel groggy and light-headed having life flow through your veins once again.");
  1281.  
  1282. //delete PvP no XP penalty variable
  1283. if(GetLocalInt(oItem, "free_xp_death") != 0)
  1284. {DeleteLocalInt(oItem, "free_xp_death");}
  1285.  
  1286. SetLocalInt(oItem, DEATH_VARISDEAD, FALSE);
  1287. SaveCharacter(oPC);
  1288.  
  1289. DelayCommand(2.0, Death_RemoveCorpse(oPC, TRUE));
  1290. DelayCommand(10.0, SaveCharacter(oPC));
  1291. }
  1292. }
  1293.  
  1294. void Death_ApplyConsequences(object oCreature, int bIsPvP)
  1295. {
  1296. int iLevel;
  1297. int iXpCurrent;
  1298. int iXpMinimum;
  1299. int iXpConsequence;
  1300. int iGoldConsequence;
  1301.  
  1302. //upon PvP Death don't deduct XP
  1303. object oItemPC = GetRequiredItem(oCreature, DEATH_ITEMVARPERSIST);
  1304. if(bIsPvP != TRUE && GetLocalInt(oItemPC, "free_xp_death") != 0)
  1305. {bIsPvP = TRUE; DeleteLocalInt(oItemPC, "free_xp_death");}
  1306.  
  1307. if (GetIsObjectValid(oCreature) == FALSE || bIsPvP != FALSE)
  1308. { return; }
  1309.  
  1310. iXpCurrent = GetXP(oCreature);
  1311. iLevel = GetLevelFromXp(oCreature);
  1312. iXpMinimum = GetXpForLevel(oCreature, iLevel);
  1313.  
  1314. iXpConsequence = iLevel * 100;
  1315.  
  1316. if (iXpCurrent - iXpConsequence < iXpMinimum)
  1317. { iXpConsequence = iXpCurrent - iXpMinimum; }
  1318.  
  1319. iGoldConsequence = GetGold(oCreature) * 5 / 100;
  1320.  
  1321. /* Commented until a banking system is in place */
  1322. //TakeGoldFromCreature(iGoldConsequence, oCreature, TRUE);
  1323. SetXP(oCreature, iXpCurrent - iXpConsequence);
  1324.  
  1325. SaveCharacter(oCreature);
  1326. }
Add Comment
Please, Sign In to add comment