Saltar al contenido

Más en DLAN: Nuestras Traducciones | Otras Traducciones | Mods y modding | Revisiones y Guías | Videojuegos | Arte | Literatura | Rol y Rol por foro e IRC | Mapa de la web
Foto

Includes...Includes...brbrb. Problema con un script.

nwn1 nwn Includes system cosa

2 respuestas al tema

#1 Ertos

Ertos

    Elder

  • Miembro
  • PipPipPipPip
  • 683 posts

Posteado 13 April 2013 - 09:41 AM

Buenas, estoy ahora trasteando con un sistema de muerte bastante chulo que encontré en vault "Killer Death System 2.2" para mas detalles, y necesito meter en mi client enter esto:

 

KDS1OnClientEnter();

 

Por supuesto arriba ya hice el Include que me pedia al script, con el onmodule load me funciono, pero este me esta dando error de IDENTIFICADOR NO DEFINIDO ()

 

Mi ClientEnter modificado con el script donde dice el readme del sistema que debe ir:

 

 

 

#include "nw_i0_plot"
#include "nw_i0_plotwizard"
#include "cnr_recipe_utils"
#include "tk_hips_inc"
#include "st_inc"
#include "sgt_inc"
#include "_kds1_inc"


void main()
{
 KDS1OnClientEnter(); //Esto da error :(


 object oJugador = GetEnteringObject();
 int iVidaMaxima = GetMaxHitPoints(oJugador);
 string sRIP = ObjectToString(GetModule());
 int iVidaActual = GetCampaignInt(sRIP, GetName(oJugador));
 string sCount = GetPCPlayerName(oJugador);
 string sKey = GetPCPublicCDKey(oJugador, TRUE);
 string sSeg = GetCampaignString("Seguridad", sCount, GetModule());
 string sBan = GetCampaignString("Baneados", sKey, GetModule());
 string sPj = GetName(oJugador);






    WriteTimestampedLogEntry("< ## ENTRADA DE JUGADOR ## > Ha entrado la cuenta [ " + sCount + " ], con el personaje de [ " + sPj + " ] y con la CDKey [ " + sKey + " ].");


 if(sSeg == "")


 {//B)


  SetCampaignString("Seguridad", sCount, sKey, GetModule());


 }//B)


 else


 {//C)


  if(sSeg != sKey || sBan == sKey)


  {//D)


   BootPC(oJugador);
   return;


  }//D)


 }//C)


//Por si tienen mas vida que la permitida, por bugs de transformaciones.
if (iVidaActual >= iVidaMaxima)
{
RemoveEffect(oJugador, EffectTemporaryHitpoints(EFFECT_TYPE_TEMPORARY_HITPOINTS));
iVidaActual = iVidaMaxima;
}//fin de disipacion de puntos de vida por encima de lo normal.


if ((iVidaActual>0) || (iVidaActual<0))
{
effect eActualizarVida = EffectDamage((iVidaMaxima-iVidaActual), DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_ENERGY);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eActualizarVida, oJugador);
}//fin actualizar vida.


object oDadosAntiguos = GetItemPossessedBy(oJugador, "dmfi_pc_dicebag");
object oEmoteAntiguo = GetItemPossessedBy(oJugador, "dmfi_pc_emote");
if (oDadosAntiguos != OBJECT_INVALID)
{
   DestroyObject(oDadosAntiguos, 1.0);
   DestroyObject(oEmoteAntiguo, 1.0);
}


if(GetXP(oJugador) <= 999)
{//
GiveGoldToCreature(oJugador,1200);
GiveXPToCreature(oJugador, 1000);
}//


if(!HasItem(oJugador, "dmfi_exploder"))
{
if (GetIsDM(oJugador) == TRUE)
{
CreateItemOnObject("dmfi_exploder",oJugador,1,"");
}


}
SendMessageToPC(oJugador,"Bienvenido a Arthena");
ExecuteScript("xp_client_enter", OBJECT_SELF);
object oPC = GetEnteringObject();
  st_HideCheck(oPC);
  DelayCommand(0.8,st_SpellCheck(oPC));
  if (!GetIsPC(oPC)) return;


  ///////////////////////////////////////////////////////////
  // Make sure all players carry the new Tradeskill Journal.
  ///////////////////////////////////////////////////////////


  // First, check if they have either journal, new or old.
  object oJournal = CnrGetItemByResRef("cnrtradejournal", oPC);
  if (oJournal == OBJECT_INVALID)
  {
    //////////////////////////
    // First time in module....
    //////////////////////////


    // Strip player of all default game items here.


    //object oItem = GetFirstItemInInventory(oPC);
    //while (oItem != OBJECT_INVALID)
    //{
    //  DestroyObject(oItem);
    //  oItem = GetNextItemInInventory(oPC);
    //}


    // create a journal for the player
    oJournal = CreateItemOnObject("cnrtradejournal", oPC);
  }
  else
  {
    // The player has a journal. Now determine what type it is, new or old


    if (GetTag(oJournal) != "cnrTradeJournal")
    {
      // Player has the old type journal. We need to convert the XP stored in its tag
      // to the new format, then we can destroy the old journal and create a new journal.


      CnrConvertOldJournalXPToNewFormat(oJournal, oPC);
      DestroyObject(oJournal);
      CreateItemOnObject("cnrtradejournal", oPC);
    }
    //else
    //{
      // Player has the new type journal. nothing needs to be done!
    //}


  }


  // Allow the builder to set the trade level caps for this PC.
  // execute hook script
  ExecuteScript("hook_set_lev_cap", oPC);


  int bInitRecipesOnModuleLoad = CnrGetPersistentInt(OBJECT_SELF, "CnrBoolInitRecipesOnModuleLoad");
  bInitRecipesOnModuleLoad = bInitRecipesOnModuleLoad || CNR_BOOL_INIT_RECIPES_ON_MODULE_LOAD;
  if (bInitRecipesOnModuleLoad == TRUE)
  {
    int nRecipeCount = GetLocalInt(GetModule(), "CnrRecipeCount");
    SendMessageToPC(oPC, "Total CNR recipe count = " + IntToString(nRecipeCount));
  }


        TK_HiPS_OnClientEnter(GetEnteringObject());
        SGT_MensajesServidor(oPC);
        ExecuteScript("s_cliententer", oPC);
        ExecuteScript("50_dye_oce", oPC);








if (!GetIsPC(oPC)) return;
    // Give PC's a Player Server Rule Book.
    if (!GetIsObjectValid(GetItemPossessedBy(oPC, "playerrulebook_s")))
        CreateItemOnObject("playerrulebook_s", oPC);


}
 

 

Aqui el trozo del script del Include relativo al onclient enter:

 

 

 

void KDS1OnClientEnter()
{ object oPC = GetEnteringObject();
  if( !GetIsPC( oPC)) return;


  // Make sure plot flag is reset and effects are cleared out.
  SetPlotFlag( oPC, FALSE);
  RemoveAllEffects( oPC);


  // Check for logout cheaters.
  if( HasItem( oPC, DEATH_TOKEN_TAG))
  { // If his body is still kicking around then the timer is still going and all that
    // is necessary is to send him to purgatory. If his body is gone, send him to the
    // church with the automatic XP penalty.
    object oBody = FindDeadBody( GetPCID( oPC));
    if( GetIsObjectValid( oBody)) AssignCommand( oPC, DelayCommand( 1.0f, GoToPurgatory()));


    // When his body is gone his death spot cannot be determined so he will always go to
    // the Church. All DeadLevel Take Gold Modes will still take gold from dead level players.
    else switch( DEAD_LEVEL_MODE)
    { case DEAD_LEVEL_FREE_RIDE:
      case DEAD_LEVEL_FREE_RIDE_DEATH_SPOT:
        // Choose the XP option. If he is at the exact start of a level he gets free-ride.
        AssignCommand( oPC, DelayCommand( 1.0f, GoToChurch()));
        break;


      case DEAD_LEVEL_TAKE_GOLD:
      case DEAD_LEVEL_TAKE_GOLD_PREFER_CHURCH:
      case DEAD_LEVEL_TAKE_GOLD_DEATH_SPOT:
      case DEAD_LEVEL_TAKE_GOLD_PREFER_DS:
      case DEAD_LEVEL_TAKE_GOLD_PREFER_CHEAPER:
      case DEAD_LEVEL_TAKE_GOLD_PREFER_CHOICE:
        { // Use XP penalty option when the penalty would be > 0. Otherwise use the GP option.
          // If GP is also 0 he gets the free-ride.
          int nLevel   = GetHitDice( oPC);
          int nCurrXP  = GetXP( oPC);
          int nMinXP   = (nLevel *(nLevel -1) *500);
          int nPenalty = PER_LEVEL_XP_LOSS *nLevel;
          int nNewXP   = (((nCurrXP -nPenalty) < nMinXP) ? nMinXP : (nCurrXP -nPenalty));
          if( (nCurrXP -nNewXP) > 0) AssignCommand( oPC, DelayCommand( 1.0f, GoToChurch( DEATH_PENALTY_XP)));
          else                       AssignCommand( oPC, DelayCommand( 1.0f, GoToChurch( DEATH_PENALTY_GP)));
        }
        break;
    }
  }


  // Check for guys that left while carrying a dead PC(s). Get rid of their item-version(s).
  if( HasItem( oPC, DEAD_PC_ITEM_TAG))
  { object oItem = GetFirstItemInInventory( oPC);
    while( GetIsObjectValid( oItem))
    { if( GetResRef( oItem) == DEAD_PC_ITEM_RESREF) DestroyObject( oItem);
      oItem = GetNextItemInInventory( oPC);
    }
  }
}
 

Y por si acaso, todo el script del include entero:

 

 

 

// Killer Death System 1 v2.2 - Library script
//::////////////////////////////////////////////
// _kds1_inc
//
// Remember this is an include library. It will not and does not need to be
// compiled, only saved. If any changes are made to it, save them then
// re-compile all scripts in the module to get the changes to propagate to
// all the parts of your module that use this library.
//::////////////////////////////////////////////
#include "x2_inc_switches"
#include "nw_i0_plot"
#include "x3_inc_horse"
#include "_move_inv_inc"




// Global Constants and Variables
//::////////////////////////////////////////////
const int    DEATH_PENALTY_XP                    = 1;
const int    DEATH_PENALTY_GP                    = 2;
const int    DEATH_PENALTY_ITEM                  = 3;
const int    DEAD_LEVEL_FREE_RIDE                = 0;       // Free Ride
const int    DEAD_LEVEL_TAKE_GOLD                = 1;       // Take Gold To Church
const int    DEAD_LEVEL_FREE_RIDE_DEATH_SPOT     = 2;       // Free Ride To Death Spot
const int    DEAD_LEVEL_TAKE_GOLD_DEATH_SPOT     = 3;       // Take Gold To Death Spot
const int    DEAD_LEVEL_TAKE_GOLD_PREFER_CHURCH  = 4;       // Take Gold Prefer Church
const int    DEAD_LEVEL_TAKE_GOLD_PREFER_DS      = 5;       // Take Gold Prefer Death Spot
const int    DEAD_LEVEL_TAKE_GOLD_PREFER_CHEAPER = 6;       // Take Gold Prefer Cheaper
const int    DEAD_LEVEL_TAKE_GOLD_PREFER_CHOICE  = 7;       // Take Gold Prefer Choice
const float  THREE_MINUTES                       = 180.0f;  // 3 minutes measured in seconds.
const float  FIVE_MINUTES                        = 300.0f;  // 5 minutes measured in seconds.
const int    PURG_TIMER_TO_CHURCH_MODE           = 0;       // Purg Timer To Church
const int    PURG_TIMER_TO_DS_MODE               = 1;       // Purg Timer To Death Spot
const int    PURG_TIMER_TO_CHEAPEST_CHURCH_MODE  = 2;       // Purg Timer To Cheapest Church
const int    PURG_TIMER_TO_CHEAPEST_DS_MODE      = 3;       // Purg Timer To Cheapest Death Spot
const int    TEST_MODE_ENABLE                    = TRUE;    // Test Mode enabled
const int    TEST_MODE_DISABLE                   = FALSE;   // Test Mode disabled
const int    FIELD_REZ_PENALTY_DISABLE           = 0;       // Disable Field Rez Penalty mode
const int    FIELD_REZ_PENALTY_ASSESS            = 1;       // Assess Field Rez Penalty mode
const int    DEATH_SPOT_CHURCH_ONLY_MODE         = 0;       // Death Spot Church Only mode
const int    DEATH_SPOT_DEATH_SPOT_ONLY_MODE     = 1;       // Death Spot Death Spot Only mode
const int    DEATH_SPOT_CHOICE_MODE              = 2;       // Death Spot Choice mode


const int    DEFAULT_PER_LEVEL_XP_LOSS           = 250;
const int    DEFAULT_PER_LEVEL_GP_LOSS           = 500;
const string DEFAULT_PER_LEVEL_ITEM_LOSS         = "1";
const int    DEFAULT_FIELD_REZ_PENALTY_MODE      = FIELD_REZ_PENALTY_DISABLE;   // No Field Rez penalty by default
const int    DEFAULT_DEAD_LEVEL_MODE             = DEAD_LEVEL_FREE_RIDE;        // Free-ride to Church when XP penalty works out to 0 (i.e. dead level).
const float  DEFAULT_PURGATORY_TIMER             = THREE_MINUTES;               // Change to FIVE_MINUTES to extend the purgatory timer to 5 min. -- read comments at the top.
const int    DEFAULT_PURGATORY_TIMER_MODE        = PURG_TIMER_TO_CHURCH_MODE;   // Sent to Church when purg timer expires.
const int    DEFAULT_PAY_LEVEL                   = 6;                           // Level 6 is the default Pay Level.
const int    DEFAULT_DEATH_SPOT_MODE             = DEATH_SPOT_CHURCH_ONLY_MODE; // Death Spot not an option by default.
const int    DEFAULT_LOOT_DROP_MODE              = LOOT_DROP_MODE_DROP_NOTHING; // Nothing drops by default.
const int    DEFAULT_TEST_MODE                   = TEST_MODE_DISABLE;           // Test mode off by default


const string DEATH_TOKEN_TAG          = "kds1_death_token";  // Note: there is a tag-based item script whose name must match up with this.
const string DEATH_TOKEN_RESREF       = "kds1_death_token";
const string DEAD_PC_TAG              = "kds1_dead_pc";
const string DEAD_PC_RESREF           = "kds1_dead_pc";
const string DEAD_PC_RESREF_F         = "kds1_dead_pc_f";
const string DEAD_PC_ITEM_TAG         = "kds1_dead_pc_itm";  // Note: there is a tag-based item script whose name must match up with this.
const string DEAD_PC_ITEM_RESREF      = "kds1_dead_pc_itm";
const string PURGATORY_WAYPOINT_TAG   = "kds1_purgatory";
const string CHURCH_WAYPOINT_TAG      = "kds1_church";
const string LOOT_BAG_TAG             = "kds1_loot_bag";
const string LOOT_BAG_RESREF          = "kds1_loot_bag";


const string WILD_MAGIC_VAR           = "X2_L_WILD_MAGIC";


const string XP_PENALTY_VAR           = "KDS1_XP/LevelPenalty";            // XP/Level penalty to leave purgatory module variable to override the default.
const string GP_PENALTY_VAR           = "KDS1_GP/LevelPenalty";            // GP/Level penalty to leave purgatory module variable to override the default.
const string XP_PENALTY_DS_VAR        = "KDS1_XP/LevelPenaltyDeathSpot";   // XP/Level penalty to leave purgatory and return to death spot variable to override the default.
const string GP_PENALTY_DS_VAR        = "KDS1_GP/LevelPenaltyDeathSpot";   // XP/Level penalty to leave purgatory and return to death spot variable to override the default.
const string ITEM_PENALTY_VAR         = "KDS1_Item/LevelPenalty";          // Item/Level penalty to leave purgatory and return to church variable to override the default.
const string ITEM_PENALTY_DS_VAR      = "KDS1_Item/LevelPenaltyDeathSpot"; // Item/Level penalty to leave purgatory and return to death spot variable to override the default.
const string XP_PENALTY_FR_VAR        = "KDS1_FieldRezXP/LevelPenalty";    // XP/Level Field Rez penalty to leave purgatory via resurrection variable to override the default.
const string GP_PENALTY_FR_VAR        = "KDS1_FieldRezGP/LevelPenalty";    // GP/Level Field Rez penalty to leave purgatory via resurrection variable to override the default.
const string FIELD_REZ_MODE_VAR       = "KDS1_FieldRezPenaltyMode";        // Field Rez Penalty Mode module variable to override the default.
const string DEAD_LEVEL_MODE_VAR      = "KDS1_DeadLevelMode";              // Dead Level Mode module variable to override the default.
const string PURG_TIMER_VAR           = "KDS1_PurgatoryTimer";             // Purgatory Timer module variable to override the default.
const string PURG_TIMER_MODE_VAR      = "KDS1_PurgatoryTimerMode";         // Purgatory Timer Mode module variable to override the default.
const string PAY_LEVEL_VAR            = "KDS1_PayLevel";                   // Pay Level module variable to override the default.
const string DEATH_SPOT_MODE_VAR      = "KDS1_DeathSpotMode";              // Death Spot Mode module variable to override the default.
const string LOOT_DROP_MODE_VAR       = "KDS1_LootDropMode";               // Loot Drop mode module variable to override the default.
const string TEST_MODE_VAR            = "KDS1_TestMode";                   // Module variable to override default test mode.
const string NO_PURG_AREA_VAR         = "KDS1_NoPurgatory";                // Area variable to mark an area so it won't use purgatory.
const string PCID_VAR                 = "KDS1_PCID";
const string LOCATION_TRACKING_VAR    = "KDS1_LocationTracking";
const string LAST_LOCATION_VAR        = "KDS1_LastLocation";
const string SHOW_OPTIONS_VAR         = "KDS1_ShowOptions";
const string RAISE_IN_PROGRESS_VAR    = "KDS1_RaiseInProgress";
const string DEAD_PC_COUNT_VAR        = "KDS1_DeadPCCount";
const string DEAD_PC_LIST_PREFIX      = "KDS1_DeadPC_";
const string CHEST_COPY_VAR           = "KDS1_ChestCopy";
const string HEAD_COPY_VAR            = "KDS1_HeadCopy";
const string BOOTS_COPY_VAR           = "KDS1_BootsCopy";
const string CLOAK_COPY_VAR           = "KDS1_CloakCopy";


const string DEATH_SPELLHOOK_SCRIPT   = "kds1_spellhook";


      int    PER_LEVEL_XP_LOSS        = ((GetLocalInt( GetModule(), XP_PENALTY_VAR) > 0) ? GetLocalInt( GetModule(), XP_PENALTY_VAR) : ((GetLocalInt( GetModule(), XP_PENALTY_VAR) < 0) ? 0 : DEFAULT_PER_LEVEL_XP_LOSS));           // XP/Level Church penalty
      int    PER_LEVEL_GP_LOSS        = ((GetLocalInt( GetModule(), GP_PENALTY_VAR) > 0) ? GetLocalInt( GetModule(), GP_PENALTY_VAR) : ((GetLocalInt( GetModule(), GP_PENALTY_VAR) < 0) ? 0 : DEFAULT_PER_LEVEL_GP_LOSS));           // GP/Level Church penalty
      int    PER_LEVEL_XP_LOSS_DS     = ((GetLocalInt( GetModule(), XP_PENALTY_DS_VAR) > 0) ? GetLocalInt( GetModule(), XP_PENALTY_DS_VAR) : ((GetLocalInt( GetModule(), XP_PENALTY_DS_VAR) < 0) ? 0 : DEFAULT_PER_LEVEL_XP_LOSS));  // XP/Level Death Spot penalty
      int    PER_LEVEL_GP_LOSS_DS     = ((GetLocalInt( GetModule(), GP_PENALTY_DS_VAR) > 0) ? GetLocalInt( GetModule(), GP_PENALTY_DS_VAR) : ((GetLocalInt( GetModule(), GP_PENALTY_DS_VAR) < 0) ? 0 : DEFAULT_PER_LEVEL_GP_LOSS));  // GP/Level Death Spot penalty
      string PER_LEVEL_ITEM_LOSS      = ((GetLocalString( GetModule(), ITEM_PENALTY_VAR)    != "") ? GetLocalString( GetModule(), ITEM_PENALTY_VAR)    : DEFAULT_PER_LEVEL_ITEM_LOSS);                                               // Item/Level penalty
      string PER_LEVEL_ITEM_LOSS_DS   = ((GetLocalString( GetModule(), ITEM_PENALTY_DS_VAR) != "") ? GetLocalString( GetModule(), ITEM_PENALTY_DS_VAR) : DEFAULT_PER_LEVEL_ITEM_LOSS);                                               // Item/Level Death Spot penalty
      int    PER_LEVEL_XP_LOSS_FR     = ((GetLocalInt( GetModule(), XP_PENALTY_FR_VAR) > 0) ? GetLocalInt( GetModule(), XP_PENALTY_FR_VAR) : ((GetLocalInt( GetModule(), XP_PENALTY_FR_VAR) < 0) ? 0 : DEFAULT_PER_LEVEL_XP_LOSS));  // XP/Level Field Rez penalty
      int    PER_LEVEL_GP_LOSS_FR     = ((GetLocalInt( GetModule(), GP_PENALTY_FR_VAR) > 0) ? GetLocalInt( GetModule(), GP_PENALTY_FR_VAR) : ((GetLocalInt( GetModule(), GP_PENALTY_FR_VAR) < 0) ? 0 : DEFAULT_PER_LEVEL_GP_LOSS));  // GP/Level Field Rez penalty
      int    FIELD_REZ_MODE           = ((GetLocalInt( GetModule(), FIELD_REZ_MODE_VAR) == FIELD_REZ_PENALTY_ASSESS) ? FIELD_REZ_PENALTY_ASSESS : DEFAULT_FIELD_REZ_PENALTY_MODE);                                                                               // Field Rez Mode
      int    DEAD_LEVEL_MODE          = (((GetLocalInt( GetModule(), DEAD_LEVEL_MODE_VAR) >= DEAD_LEVEL_TAKE_GOLD) && (GetLocalInt( GetModule(), DEAD_LEVEL_MODE_VAR) <= DEAD_LEVEL_TAKE_GOLD_PREFER_CHOICE)) ? GetLocalInt( GetModule(), DEAD_LEVEL_MODE_VAR) : DEFAULT_DEAD_LEVEL_MODE); // Dead Level Mode
      float  PURGATORY_TIMER          = ((GetLocalFloat( GetModule(), PURG_TIMER_VAR) > 0.0) ? GetLocalFloat( GetModule(), PURG_TIMER_VAR) : ((GetLocalFloat( GetModule(), PURG_TIMER_VAR) < 0.0) ? 0.0 : DEFAULT_PURGATORY_TIMER)); // Purgatory Timer.
      int    PURGATORY_TIMER_MODE     = (((GetLocalInt( GetModule(), PURG_TIMER_MODE_VAR) >= PURG_TIMER_TO_CHURCH_MODE) && (GetLocalInt( GetModule(), PURG_TIMER_MODE_VAR) <= PURG_TIMER_TO_CHEAPEST_DS_MODE)) ? GetLocalInt( GetModule(), PURG_TIMER_MODE_VAR) : DEFAULT_PURGATORY_TIMER_MODE); // Purgatory Timer Mode
      int    PAY_LEVEL                = (((GetLocalInt( GetModule(), PAY_LEVEL_VAR) > 0) && (GetLocalInt( GetModule(), PAY_LEVEL_VAR) < 42)) ? GetLocalInt( GetModule(), PAY_LEVEL_VAR) : DEFAULT_PAY_LEVEL);                        // Pay Level
      int    DEATH_SPOT_MODE          = (((GetLocalInt( GetModule(), DEATH_SPOT_MODE_VAR) >= DEATH_SPOT_CHURCH_ONLY_MODE) && (GetLocalInt( GetModule(), DEATH_SPOT_MODE_VAR) <= DEATH_SPOT_CHOICE_MODE)) ? GetLocalInt( GetModule(), DEATH_SPOT_MODE_VAR) : DEFAULT_DEATH_SPOT_MODE); // Death Spot Mode
      int    LOOT_DROP_MODE           = (((GetLocalInt( GetModule(), LOOT_DROP_MODE_VAR) >= LOOT_DROP_MODE_DROP_NOTHING) && (GetLocalInt( GetModule(), LOOT_DROP_MODE_VAR) <= LOOT_DROP_MODE_DROP_EVERYTHING)) ? GetLocalInt( GetModule(), LOOT_DROP_MODE_VAR) : DEFAULT_LOOT_DROP_MODE); // Loot Drop Mode
      int    TEST_MODE                = ((GetLocalInt( GetModule(), TEST_MODE_VAR) != TEST_MODE_DISABLE) ? TEST_MODE_ENABLE : DEFAULT_TEST_MODE);  // Set to TRUE so no penalty is actually assessed even though it says so.


    location LOCATION_INVALID         = GetLocation( OBJECT_INVALID);




// Function Definitions
//::////////////////////////////////////////////
object GetDefaultPurgatoryWaypoint()
{ return GetObjectByTag( PURGATORY_WAYPOINT_TAG);
}




object GetDefaultChurchWaypoint()
{ return GetObjectByTag( CHURCH_WAYPOINT_TAG);
}




object GetPurgatoryWaypoint( object oPC)
{ if( !GetIsPC( oPC)) return GetDefaultPurgatoryWaypoint();


  string sFullAlign = "";
  string sGERAlign  = "";
  string sGEAlign   = "";
  string sLCRAlign  = "";
  string sLCAlign   = "";
  switch( GetAlignmentGoodEvil( oPC))
  { case ALIGNMENT_GOOD:
      sGERAlign = "G";
      sGEAlign  = "Good";
      switch( GetAlignmentLawChaos( oPC))
      { case ALIGNMENT_LAWFUL:  sFullAlign = "LG";   sLCRAlign = "L";   sLCAlign = "Lawful";    break;
        case ALIGNMENT_CHAOTIC: sFullAlign = "CG";   sLCRAlign = "C";   sLCAlign = "Chaotic";   break;
        default:                sFullAlign = "NG";   sLCRAlign = "N";   sLCAlign = "Neutral";   break;
      }
      break;
    case ALIGNMENT_EVIL:
      sGERAlign = "E";
      sGEAlign  = "Evil";
      switch( GetAlignmentLawChaos( oPC))
      { case ALIGNMENT_LAWFUL:  sFullAlign = "LE";   sLCRAlign = "L";   sLCAlign = "Lawful";    break;
        case ALIGNMENT_CHAOTIC: sFullAlign = "CE";   sLCRAlign = "C";   sLCAlign = "Chaotic";   break;
        default:                sFullAlign = "NE";   sLCRAlign = "N";   sLCAlign = "Neutral";   break;
      }
      break;
    default:
      sGERAlign = "N";
      sGEAlign  = "Neutral";
      switch( GetAlignmentLawChaos( oPC))
      { case ALIGNMENT_LAWFUL:  sFullAlign = "LN";   sLCRAlign = "L";   sLCAlign = "Lawful";    break;
        case ALIGNMENT_CHAOTIC: sFullAlign = "CN";   sLCRAlign = "C";   sLCAlign = "Chaotic";   break;
        default:                sFullAlign = "TN";   sLCRAlign = "N";   sLCAlign = "Neutral";   break;
      }
      break;
  }
  string sRace = "";
  switch( GetRacialType( oPC))
  { case RACIAL_TYPE_DWARF:    sRace = "Dwarf";      break;
    case RACIAL_TYPE_ELF:      sRace = "Elf";        break;
    case RACIAL_TYPE_GNOME:    sRace = "Gnome";      break;
    case RACIAL_TYPE_HALFLING: sRace = "Halfling";   break;
    case RACIAL_TYPE_HALFELF:  sRace = "Half-Elf";   break;
    case RACIAL_TYPE_HALFORC:  sRace = "Half-Orc";   break;
    default:                   sRace = "Human";      break;
  }


  string sTAG = PURGATORY_WAYPOINT_TAG +"_" +sFullAlign +"_" +sRace;
  object oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = PURGATORY_WAYPOINT_TAG +"_" +sGERAlign +"_" +sRace;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = PURGATORY_WAYPOINT_TAG +"_" +sLCRAlign +"_" +sRace;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = PURGATORY_WAYPOINT_TAG +"_" +sFullAlign;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = PURGATORY_WAYPOINT_TAG +"_" +sGEAlign;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = PURGATORY_WAYPOINT_TAG +"_" +sLCAlign;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = PURGATORY_WAYPOINT_TAG +"_" +sRace;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  return GetDefaultPurgatoryWaypoint();
}




object GetChurchWaypoint( object oPC)
{ if( !GetIsPC( oPC)) return GetDefaultChurchWaypoint();


  string sFullAlign = "";
  string sGERAlign  = "";
  string sGEAlign   = "";
  string sLCRAlign  = "";
  string sLCAlign   = "";
  switch( GetAlignmentGoodEvil( oPC))
  { case ALIGNMENT_GOOD:
      sGERAlign = "G";
      sGEAlign  = "Good";
      switch( GetAlignmentLawChaos( oPC))
      { case ALIGNMENT_LAWFUL:  sFullAlign = "LG";   sLCRAlign = "L";   sLCAlign = "Lawful";    break;
        case ALIGNMENT_CHAOTIC: sFullAlign = "CG";   sLCRAlign = "C";   sLCAlign = "Chaotic";   break;
        default:                sFullAlign = "NG";   sLCRAlign = "N";   sLCAlign = "Neutral";   break;
      }
      break;
    case ALIGNMENT_EVIL:
      sGERAlign = "E";
      sGEAlign  = "Evil";
      switch( GetAlignmentLawChaos( oPC))
      { case ALIGNMENT_LAWFUL:  sFullAlign = "LE";   sLCRAlign = "L";   sLCAlign = "Lawful";    break;
        case ALIGNMENT_CHAOTIC: sFullAlign = "CE";   sLCRAlign = "C";   sLCAlign = "Chaotic";   break;
        default:                sFullAlign = "NE";   sLCRAlign = "N";   sLCAlign = "Neutral";   break;
      }
      break;
    default:
      sGERAlign = "N";
      sGEAlign  = "Neutral";
      switch( GetAlignmentLawChaos( oPC))
      { case ALIGNMENT_LAWFUL:  sFullAlign = "LN";   sLCRAlign = "L";   sLCAlign = "Lawful";    break;
        case ALIGNMENT_CHAOTIC: sFullAlign = "CN";   sLCRAlign = "C";   sLCAlign = "Chaotic";   break;
        default:                sFullAlign = "TN";   sLCRAlign = "N";   sLCAlign = "Neutral";   break;
      }
      break;
  }
  string sRace = "";
  switch( GetRacialType( oPC))
  { case RACIAL_TYPE_DWARF:    sRace = "Dwarf";      break;
    case RACIAL_TYPE_ELF:      sRace = "Elf";        break;
    case RACIAL_TYPE_GNOME:    sRace = "Gnome";      break;
    case RACIAL_TYPE_HALFLING: sRace = "Halfling";   break;
    case RACIAL_TYPE_HALFELF:  sRace = "Half-Elf";   break;
    case RACIAL_TYPE_HALFORC:  sRace = "Half-Orc";   break;
    default:                   sRace = "Human";      break;
  }


  string sTAG = CHURCH_WAYPOINT_TAG +"_" +sFullAlign +"_" +sRace;
  object oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = CHURCH_WAYPOINT_TAG +"_" +sGERAlign +"_" +sRace;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = CHURCH_WAYPOINT_TAG +"_" +sLCRAlign +"_" +sRace;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = CHURCH_WAYPOINT_TAG +"_" +sFullAlign;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = CHURCH_WAYPOINT_TAG +"_" +sGEAlign;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = CHURCH_WAYPOINT_TAG +"_" +sLCAlign;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  sTAG = CHURCH_WAYPOINT_TAG +"_" +sRace;
  oWP  = GetObjectByTag( sTAG);
  if( GetIsObjectValid( oWP)) return oWP;


  return GetDefaultChurchWaypoint();
}




string StripFirstInt( string sString)
{ if( sString == "") return "";


  int iFound = FindSubString( sString, ",");
  if( iFound < 0) return "";
  return GetStringRight( sString, GetStringLength( sString) -(iFound +1));
}




int GetFirstInt( string sString)
{ if( sString == "") return 0;


  int iFound = FindSubString( sString, ",");
  if( iFound < 0) return StringToInt( sString);
  return StringToInt( GetStringLeft( sString, iFound));
}




void SetItemLossVariables()
{ int iLoop = 2;
  while( --iLoop >= 0)
  { string sItemLossVarPrefix = (iLoop ? ITEM_PENALTY_VAR    : ITEM_PENALTY_DS_VAR);
    string sItemLoss          = (iLoop ? PER_LEVEL_ITEM_LOSS : PER_LEVEL_ITEM_LOSS_DS);
    if( (sItemLoss == "") || (sItemLoss == "0") || (sItemLoss == "1"))
    { int iLevel = 41;
      while( --iLevel > 0) SetLocalInt( GetModule(), sItemLossVarPrefix +"_" +IntToString( iLevel), 1);
    }
    else
    { int iLevel = 1;
      int iLoss  = 1;
      do
      { iLoss = GetFirstInt( sItemLoss);
        iLoss = ((iLoss < 0) ? 0 : ((iLoss == 0) ? 1 : iLoss));
        SetLocalInt( GetModule(), sItemLossVarPrefix +"_" +IntToString( iLevel++), iLoss);
        sItemLoss  = StripFirstInt( sItemLoss);
      } while( GetStringLength( sItemLoss) > 0);


      while( iLevel < 41) SetLocalInt( GetModule(), sItemLossVarPrefix +"_" +IntToString( iLevel++), iLoss);
    }
  }
}




void ValidateOperatingModes()
{ switch( DEATH_SPOT_MODE)
  { case DEATH_SPOT_CHURCH_ONLY_MODE:
      switch( DEAD_LEVEL_MODE)
      { case DEAD_LEVEL_FREE_RIDE:
        case DEAD_LEVEL_TAKE_GOLD:
          break;


        case DEAD_LEVEL_FREE_RIDE_DEATH_SPOT:
          DEAD_LEVEL_MODE = DEAD_LEVEL_FREE_RIDE;
          break;


        case DEAD_LEVEL_TAKE_GOLD_DEATH_SPOT:
        case DEAD_LEVEL_TAKE_GOLD_PREFER_CHURCH:
        case DEAD_LEVEL_TAKE_GOLD_PREFER_DS:
        case DEAD_LEVEL_TAKE_GOLD_PREFER_CHEAPER:
        case DEAD_LEVEL_TAKE_GOLD_PREFER_CHOICE:
          DEAD_LEVEL_MODE = DEAD_LEVEL_TAKE_GOLD;
          break;
      }


      switch( PURGATORY_TIMER_MODE)
      { case PURG_TIMER_TO_CHURCH_MODE:
          break;


        case PURG_TIMER_TO_DS_MODE:
        case PURG_TIMER_TO_CHEAPEST_CHURCH_MODE:
        case PURG_TIMER_TO_CHEAPEST_DS_MODE:
          PURGATORY_TIMER_MODE = PURG_TIMER_TO_CHURCH_MODE;
          break;
      }
      break;


    case DEATH_SPOT_DEATH_SPOT_ONLY_MODE:
      switch( DEAD_LEVEL_MODE)
      { case DEAD_LEVEL_FREE_RIDE:
          DEAD_LEVEL_MODE = DEAD_LEVEL_FREE_RIDE_DEATH_SPOT;
          break;


        case DEAD_LEVEL_TAKE_GOLD:
          DEAD_LEVEL_MODE = DEAD_LEVEL_TAKE_GOLD_DEATH_SPOT;
          break;


        case DEAD_LEVEL_FREE_RIDE_DEATH_SPOT:
        case DEAD_LEVEL_TAKE_GOLD_DEATH_SPOT:
          break;


        case DEAD_LEVEL_TAKE_GOLD_PREFER_CHURCH:
        case DEAD_LEVEL_TAKE_GOLD_PREFER_DS:
        case DEAD_LEVEL_TAKE_GOLD_PREFER_CHEAPER:
        case DEAD_LEVEL_TAKE_GOLD_PREFER_CHOICE:
          DEAD_LEVEL_MODE = DEAD_LEVEL_TAKE_GOLD_DEATH_SPOT;
          break;
      }


      switch( PURGATORY_TIMER_MODE)
      { case PURG_TIMER_TO_CHURCH_MODE:
          PURGATORY_TIMER_MODE = PURG_TIMER_TO_DS_MODE;
          break;


        case PURG_TIMER_TO_DS_MODE:
          break;


        case PURG_TIMER_TO_CHEAPEST_CHURCH_MODE:
        case PURG_TIMER_TO_CHEAPEST_DS_MODE:
          PURGATORY_TIMER_MODE = PURG_TIMER_TO_DS_MODE;
          break;
      }
      break;


    case DEATH_SPOT_CHOICE_MODE:
      if( (DEAD_LEVEL_MODE == DEAD_LEVEL_TAKE_GOLD_PREFER_CHEAPER) && (PER_LEVEL_GP_LOSS == PER_LEVEL_GP_LOSS_DS))
        DEAD_LEVEL_MODE = DEAD_LEVEL_TAKE_GOLD_PREFER_CHOICE;
      break;
  }


  if( (FIELD_REZ_MODE == FIELD_REZ_PENALTY_ASSESS) && (PER_LEVEL_XP_LOSS_FR <= 0) && (PER_LEVEL_GP_LOSS_FR <= 0))
    FIELD_REZ_MODE = FIELD_REZ_PENALTY_DISABLE;


  SetItemLossVariables();
}




int GetItemLoss( int iLevel, int bDeathSpot)
{ if( (iLevel < 1) || (iLevel > 40)) return 0;


  return GetLocalInt( GetModule(), (bDeathSpot ? (ITEM_PENALTY_DS_VAR +"_") : (ITEM_PENALTY_VAR +"_")) +IntToString( iLevel));
}




string GetPCID( object oPC)
{ if( !GetIsPC( oPC)) return "";


  return (GetPCPublicCDKey( oPC) +"_" +GetPCPlayerName( oPC) +"_" +GetName( oPC));
}




int GetItemCount( object oPC)
{ return (GetInventoryCount( oPC) +GetEquipmentCount( oPC));
}




void StartLocationTracking( object oPC, int bStartTracking = TRUE)
{ if( !GetIsPC( oPC)) return;
  if( (!bStartTracking && !GetLocalInt( oPC, LOCATION_TRACKING_VAR)) ||
      (bStartTracking  && GetLocalInt( oPC, LOCATION_TRACKING_VAR))    ) return;
  SetLocalInt( oPC, LOCATION_TRACKING_VAR, TRUE);


  location lNow = GetLocation( oPC);
  if( GetIsObjectValid( GetAreaFromLocation( lNow))) SetLocalLocation( oPC, LAST_LOCATION_VAR, lNow);


  DelayCommand( 3.0f, StartLocationTracking( oPC, FALSE));
}




void StopLocationTracking( object oPC)
{ if( HasItem( oPC, DEAD_PC_ITEM_TAG)) return;
  DeleteLocalInt( oPC, LOCATION_TRACKING_VAR);
}




void RemoveAllTemporaryEffects( object oObject = OBJECT_SELF)
{ if( !GetIsObjectValid( oObject)) return;


  effect eRemove = GetFirstEffect( oObject);
  while( GetIsEffectValid( eRemove))
  { if( GetEffectDurationType( eRemove) == DURATION_TYPE_TEMPORARY) RemoveEffect( oObject, eRemove);
    eRemove = GetNextEffect( oObject);
  }
}




void RemoveAllEffects( object oObject = OBJECT_SELF)
{ if( !GetIsObjectValid( oObject)) return;


  RemoveEffects( oObject);
  RemoveAllTemporaryEffects( oObject);
}




void RemoveAllItemProperties( object oItem)
{ if( !GetIsObjectValid( oItem) || (GetObjectType( oItem) != OBJECT_TYPE_ITEM)) return;


  itemproperty ipRemove = GetFirstItemProperty( oItem);
  while( GetIsItemPropertyValid( ipRemove))
  { RemoveItemProperty( oItem, ipRemove);
    ipRemove = GetNextItemProperty( oItem);
  }
}




object GetRandomInventoryItem( object oCreature = OBJECT_SELF)
{ if( !GetIsObjectValid( oCreature)) return OBJECT_INVALID;


  int nNumItems = GetInventoryCount( oCreature);
  if( nNumItems <= 0) return OBJECT_INVALID;


  int    iChoice = Random( nNumItems) +1;
  object oItem   = GetFirstItemInInventory( oCreature);
  while( GetIsObjectValid( oItem))
  { if( !GetPlotFlag( oItem) && !GetItemCursedFlag( oItem) && !GetHasInventory( oItem) && !GetLocalInt( oItem, "DeathPenalty"))
      if( --iChoice <= 0) return oItem;
    oItem = GetNextItemInInventory( oCreature);
  }
  return OBJECT_INVALID;
}




object GetRandomEquipmentItem( object oCreature = OBJECT_SELF)
{ if( !GetIsObjectValid( oCreature)) return OBJECT_INVALID;


  int nNumItems = GetEquipmentCount( oCreature);
  if( nNumItems <= 0) return OBJECT_INVALID;


  int iChoice = Random( nNumItems) +1;
  int iSlot   = INVENTORY_SLOT_BOLTS +1;
  while( --iSlot >= INVENTORY_SLOT_HEAD)
  { object oItem = GetItemInSlot( iSlot, oCreature);
    if( GetIsObjectValid( oItem) && !GetPlotFlag( oItem) && !GetItemCursedFlag( oItem) && !GetLocalInt( oItem, "DeathPenalty"))
      if( --iChoice <= 0) return oItem;
  }
  return OBJECT_INVALID;
}




void DestroyDeathTokens( object oPC)
{ if( !GetIsPC( oPC)) return;


  object oItem = GetFirstItemInInventory( oPC);
  while( GetIsObjectValid( oItem))
  { if( GetResRef( oItem) == DEATH_TOKEN_RESREF) DestroyObject( oItem);
    oItem = GetNextItemInInventory( oPC);
  }
}




void DestroyDeadPCBody( object oPC)
{ if( !GetIsPC( oPC)) return;


  // Get rid of the creature.
  string sResref = ((GetGender( oPC) == GENDER_FEMALE) ? DEAD_PC_RESREF_F : DEAD_PC_RESREF);
  int    iNth    = 0;
  object oBody   = GetObjectByTag( DEAD_PC_TAG);
  while( GetIsObjectValid( oBody))
  { if( (GetResRef( oBody) == sResref) && (GetLocalString( oBody, PCID_VAR) == GetPCID( oPC))) DestroyObject( oBody);
    oBody = GetObjectByTag( DEAD_PC_TAG, ++iNth);
  }


  // Get rid of the item.
  iNth  = 0;
  oBody = GetObjectByTag( DEAD_PC_ITEM_TAG);
  while( GetIsObjectValid( oBody))
  { if( GetLocalString( oBody, PCID_VAR) == GetPCID( oPC))
    { FloatingTextStringOnCreature( "A dead body you were carrying has vanished!", GetItemPossessor( oBody), FALSE);
      DestroyObject( oBody);
    }
    oBody = GetObjectByTag( DEAD_PC_ITEM_TAG, ++iNth);
  }
}




location GetDeadBodyLocation( object oPC)
{ if( !GetIsPC( oPC)) return LOCATION_INVALID;


  // First look for the body item.
  int    iNth  = 0;
  object oBody = GetObjectByTag( DEAD_PC_ITEM_TAG);
  while( GetIsObjectValid( oBody))
  { if( GetLocalString( oBody, PCID_VAR) == GetPCID( oPC))
    { object oPossessor = GetItemPossessor( oBody);
      if( !GetIsObjectValid( oPossessor)) return GetLocation( oBody);
      else switch( GetObjectType( oPossessor))
      { case OBJECT_TYPE_CREATURE:
        case OBJECT_TYPE_PLACEABLE:
        case OBJECT_TYPE_DOOR:       return GetLocation( oPossessor);


        case OBJECT_TYPE_ITEM:
          while( GetIsObjectValid( oPossessor))
          { oPossessor = GetItemPossessor( oPossessor);
            switch( GetObjectType( oPossessor))
            { case OBJECT_TYPE_CREATURE:
              case OBJECT_TYPE_PLACEABLE:
              case OBJECT_TYPE_DOOR:      return GetLocation( oPossessor);
              case OBJECT_TYPE_ITEM:      break;
              default:                    oPossessor = OBJECT_INVALID;
                                          break;
            }
          }
          break;
      }
      break;
    }
    oBody = GetObjectByTag( DEAD_PC_ITEM_TAG, ++iNth);
  }


  // Body Item not found so look for dead body creature.
  string sResref = ((GetGender( oPC) == GENDER_FEMALE) ? DEAD_PC_RESREF_F : DEAD_PC_RESREF);
  iNth  = 0;
  oBody = GetObjectByTag( DEAD_PC_TAG);
  while( GetIsObjectValid( oBody))
  { if( (GetResRef( oBody) == sResref) && (GetLocalString( oBody, PCID_VAR) == GetPCID( oPC))) return GetLocation( oBody);
    oBody = GetObjectByTag( DEAD_PC_TAG, ++iNth);
  }


  return LOCATION_INVALID;
}




void ActionTransportToLocation( location lLocation)
{ if( !GetIsObjectValid( GetAreaFromLocation( lLocation))) return;


  // Transport OBJECT_SELF
  ActionJumpToLocation( lLocation);


  // Transport all his associates.
  int iAssociateType = ASSOCIATE_TYPE_DOMINATED +1;
  while( --iAssociateType > ASSOCIATE_TYPE_NONE)
  { int    iNth       = 1;
    object oAssociate = GetAssociate( iAssociateType);
    while( GetIsObjectValid( oAssociate))
    { AssignCommand( oAssociate, ClearAllActions( TRUE));
      AssignCommand( oAssociate, JumpToLocation( lLocation));
      oAssociate = GetAssociate( iAssociateType, OBJECT_SELF, ++iNth);
    }
  }
}




void ActionTransportToObject( object oObject)
{ if( !GetIsObjectValid( oObject)) return;


  // Transport OBJECT_SELF
  ActionJumpToObject( oObject);


  // Transport all his associates.
  int iAssociateType = ASSOCIATE_TYPE_DOMINATED +1;
  while( --iAssociateType > ASSOCIATE_TYPE_NONE)
  { int    iNth       = 1;
    object oAssociate = GetAssociate( iAssociateType);
    while( GetIsObjectValid( oAssociate))
    { AssignCommand( oAssociate, ClearAllActions( TRUE));
      AssignCommand( oAssociate, JumpToObject( oObject));
      oAssociate = GetAssociate( iAssociateType, OBJECT_SELF, ++iNth);
    }
  }
}




void FieldRezDeathPenalty( object oPC)
{ if( !GetIsPC( oPC)) return;


  string sMessage = "";


  // Apply XP Penalty
  int nPCLevel      = GetHitDice( oPC);
  int nRezXPPenalty = PER_LEVEL_XP_LOSS_FR *nPCLevel;
  if( nRezXPPenalty > 0)
  { int nMinXP = nPCLevel *(nPCLevel -1) *500;
    int nNewXP = GetXP( oPC) -nRezXPPenalty;
    if( nNewXP < nMinXP) nNewXP = nMinXP;
    int nXPPenalty = GetXP( oPC) -nNewXP;
    if( nXPPenalty > 0)
    { if( !TEST_MODE) SetXP( oPC, nNewXP);
      sMessage = "\nYou have been assessed a " +IntToString( nXPPenalty) +"XP death penalty.";
    }
  }


  // Apply GP Penalty
  int nRezGPPenalty = PER_LEVEL_GP_LOSS_FR *nPCLevel;
  if( nRezGPPenalty > 0)
  { int nPCGold = GetGold( oPC);
    if( nRezGPPenalty > nPCGold) nRezGPPenalty = nPCGold;
    if( nRezGPPenalty > 0)
    { if( !TEST_MODE) AssignCommand( oPC, TakeGoldFromCreature( nRezGPPenalty, oPC, TRUE));
      sMessage = "\nYou have been assessed a " +IntToString( nRezGPPenalty) +" GP death penalty.";
    }
  }


  // Notify the player if necessary.
  if( sMessage != "") SendMessageToPC( oPC, sMessage);
}




void ActionResRaise( object oBody, int iSpellID)
{ if( !GetIsObjectValid( oBody) ||
      ((iSpellID != SPELL_RESURRECTION) && (iSpellID != SPELL_RAISE_DEAD)) ) return;


  // Determine the resurrection location.
  location lBody = GetLocation( OBJECT_INVALID);
  switch( GetObjectType( oBody))
  { case OBJECT_TYPE_ITEM:
      { object oPossessor = GetItemPossessor( oBody);
        while( GetIsObjectValid( oPossessor) && (GetObjectType( oPossessor) != OBJECT_TYPE_CREATURE))
          oPossessor = GetItemPossessor( oPossessor);
        if( GetIsObjectValid( oPossessor)) lBody = GetLocation( oPossessor);
        else                               lBody = GetLocation( oBody);
      }
      break;


    case OBJECT_TYPE_CREATURE: lBody = GetLocation( oBody);   break;
  }


  if( !GetIsObjectValid( GetAreaFromLocation( lBody)))
  { SendMessageToPC( OBJECT_SELF, "Unable to determine resurrection location!!");
    return;
  }
  else if( GetAreaFromLocation( lBody) == GetArea( GetPurgatoryWaypoint( OBJECT_SELF))) return;


  // Prepare the PC to return to life.
  SetCommandable( TRUE);
  ClearAllActions( TRUE);
  SetPlotFlag( OBJECT_SELF, FALSE);


  // If it was a raise dead spell, he will be left at 1 hp. A resurrection
  // provides a full heal. Since we healed him fully when we sent him to
  // purgatory, we need to damage him back down to 1 if a raise dead was used.
  if( iSpellID == SPELL_RAISE_DEAD)
  { effect eDamage = EffectDamage( GetCurrentHitPoints() -1, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_ENERGY);
    ActionDoCommand( ApplyEffectToObject( DURATION_TYPE_INSTANT, eDamage, OBJECT_SELF));
  }


  // Take away his death tokens.
  ActionDoCommand( DestroyDeathTokens( OBJECT_SELF));


  // Play a visual effect on the dead body then destroy it.
  ActionDoCommand( ApplyEffectAtLocation( DURATION_TYPE_INSTANT, EffectVisualEffect( VFX_IMP_RAISE_DEAD), lBody));
  ActionDoCommand( DestroyDeadPCBody( OBJECT_SELF));
  ActionWait( 0.5f);


  // Play a visual effect on the PC then jump him back to his death spot.
  ActionDoCommand( ApplyEffectAtLocation( DURATION_TYPE_INSTANT, EffectVisualEffect( VFX_IMP_UNSUMMON), GetLocation( OBJECT_SELF)));
  ActionTransportToLocation( lBody);
  if( FIELD_REZ_MODE == FIELD_REZ_PENALTY_ASSESS) ActionDoCommand( FieldRezDeathPenalty( OBJECT_SELF));
  ActionDoCommand( SetCommandable( TRUE));
  SetCommandable( FALSE);
}




void ActionNPCResurrectPC( object oBody)
{ if( !GetIsObjectValid( oBody) || ((GetResRef( oBody) != DEAD_PC_RESREF) && (GetResRef( oBody) != DEAD_PC_RESREF_F))) return;


  object oArea      = GetArea( OBJECT_SELF);
  int    bWildMagic = GetLocalInt( oArea, WILD_MAGIC_VAR);


  // Wild magic allows the spellhook to fire for NPC casters.
  ClearAllActions( TRUE);
  ActionDoCommand( SetLocalInt( oArea, WILD_MAGIC_VAR, TRUE));
  ActionCastSpellAtObject( SPELL_RESURRECTION, oBody, METAMAGIC_ANY, TRUE);
  ActionDoCommand( SetLocalInt( oArea, WILD_MAGIC_VAR, bWildMagic));
  ActionDoCommand( DeleteLocalInt( OBJECT_SELF, RAISE_IN_PROGRESS_VAR));
  ActionDoCommand( SetCommandable( TRUE));
  SetCommandable( FALSE);
}




void NPCResurrectPC( object oBody)
{ if( !GetIsObjectValid( oBody) || ((GetResRef( oBody) != DEAD_PC_RESREF) && (GetResRef( oBody) != DEAD_PC_RESREF_F))) return;
  DelayCommand( 3.0f, ActionNPCResurrectPC( oBody));
}




void ActionJumpToChurch( string sMessage)
{ // Turn off the plot flag, do some visuals, and send the guy to church.
  SetCommandable( TRUE);
  ClearAllActions( TRUE);
  ActionDoCommand( SetPlotFlag( OBJECT_SELF, FALSE));
  ActionDoCommand( ApplyEffectAtLocation( DURATION_TYPE_INSTANT, EffectVisualEffect( VFX_IMP_UNSUMMON), GetLocation( OBJECT_SELF)));
  ActionWait( 0.5f);
  ActionTransportToObject( GetChurchWaypoint( OBJECT_SELF));
  ActionDoCommand( ApplyEffectAtLocation( DURATION_TYPE_INSTANT, EffectVisualEffect( VFX_IMP_RAISE_DEAD), GetLocation( GetChurchWaypoint( OBJECT_SELF))));


  if( sMessage != "") ActionDoCommand( SendMessageToPC( OBJECT_SELF, sMessage));
  ActionDoCommand( SetCommandable( TRUE));
  SetCommandable( FALSE);
}




void GoToChurch( int iPenaltyType = DEATH_PENALTY_XP)
{ object oPC = OBJECT_SELF;
  if( !GetIsPC( oPC)) return;


  // Apply death penalty to players at or above the pay level.
  string sMessage = "";
  int    nLevel   = GetHitDice( oPC);
  if( nLevel >= PAY_LEVEL)
  { switch( iPenaltyType)
    { case DEATH_PENALTY_XP:  // XP per level penalty
        { int nCurrXP  = GetXP( oPC);
          int nMinXP   = (nLevel *(nLevel -1) *500);
          int nPenalty = PER_LEVEL_XP_LOSS *nLevel;
          int nNewXP   = (((nCurrXP -nPenalty) < nMinXP) ? nMinXP : (nCurrXP -nPenalty));
          if( (nCurrXP -nNewXP) > 0)
          { if( !TEST_MODE) SetXP( oPC, nNewXP);
            sMessage = "\nYou have been assessed a " +IntToString( nCurrXP -nNewXP) +"XP death penalty.";
          }
        }
        break;


      case DEATH_PENALTY_GP:  // GP per level penalty
        { int nCurrGP  = GetGold( oPC);
          int nMinGP   = 0;
          int nPenalty = PER_LEVEL_GP_LOSS *nLevel;
          int nNewGP   = (((nCurrGP -nPenalty) < nMinGP) ? nMinGP : (nCurrGP -nPenalty));
          if( (nCurrGP -nNewGP) > 0)
          { if( !TEST_MODE) AssignCommand( oPC, TakeGoldFromCreature( (nCurrGP -nNewGP), oPC, TRUE));
            sMessage = "\nYou have been assessed a " +IntToString( nCurrGP -nNewGP) +" GP death penalty.";
          }
        }
        break;


      case DEATH_PENALTY_ITEM:  // Take random items. 80% chance normal inventory item, 20% chance equipment item.
        { int nItemCount = GetLocalInt( GetModule(), ITEM_PENALTY_VAR +"_" +IntToString( nLevel));
          while( --nItemCount >= 0)
          { object oItem = OBJECT_INVALID;
            if( d10() <= 2)
            { oItem = GetRandomEquipmentItem( oPC);
              if( !GetIsObjectValid( oItem)) oItem = GetRandomInventoryItem( oPC);
            }
            else
            { oItem = GetRandomInventoryItem( oPC);
              if( !GetIsObjectValid( oItem)) oItem = GetRandomEquipmentItem( oPC);
            }


            if( GetIsObjectValid( oItem))
            { if( !TEST_MODE) DestroyObject( oItem);
              SetLocalInt( oItem, "DeathPenalty", TRUE);
              sMessage += "\nYou have lost your " +GetName( oItem) +" as a death penalty.";
            }
          }
        }
        break;


      default:  // No death penalty
        sMessage = "";
        break;
    }
  }


  // Get rid of his death tokens.
  DestroyDeathTokens( oPC);


  // Get rid of his body if it still exists.
  DestroyDeadPCBody( oPC);


  // Send him to the church.
  ActionJumpToChurch( sMessage);
}




void ActionJumpToDeathSpot( string sMessage, location lDeathSpot)
{ // Turn off the plot flag, do some visuals, and send the guy to his death spot.
  SetCommandable( TRUE);
  ClearAllActions( TRUE);
  ActionDoCommand( SetPlotFlag( OBJECT_SELF, FALSE));
  ActionDoCommand( ApplyEffectAtLocation( DURATION_TYPE_INSTANT, EffectVisualEffect( VFX_IMP_UNSUMMON), GetLocation( OBJECT_SELF)));
  ActionWait( 0.5f);
  ActionTransportToLocation( lDeathSpot);
  ActionDoCommand( ApplyEffectAtLocation( DURATION_TYPE_INSTANT, EffectVisualEffect( VFX_IMP_RAISE_DEAD), lDeathSpot));


  if( sMessage != "") ActionDoCommand( SendMessageToPC( OBJECT_SELF, sMessage));
  ActionDoCommand( SetCommandable( TRUE));
  SetCommandable( FALSE);
}




void GoToDeathSpot( int iPenaltyType = DEATH_PENALTY_XP)
{ object oPC = OBJECT_SELF;
  if( !GetIsPC( oPC)) return;


  // Find death spot.
  location lDeathSpot = GetDeadBodyLocation( OBJECT_SELF);
  if( lDeathSpot == LOCATION_INVALID)
  { SendMessageToPC( oPC, "Killer Death System Critical Error.\nUnable to find your death spot. Please notify your DM immediately.\nSorry but you will be stuck in purgatory until the problem can be addressed unless you can get ressurrected or return to a Church.");
    return;
  }


  // Apply death penalty to level 6 and higher players only.
  string sMessage = "";
  int    nLevel   = GetHitDice( oPC);
  if( nLevel >= PAY_LEVEL)
  { switch( iPenaltyType)
    { case DEATH_PENALTY_XP:  // XP per level penalty
        { int nCurrXP  = GetXP( oPC);
          int nMinXP   = (nLevel *(nLevel -1) *500);
          int nPenalty = PER_LEVEL_XP_LOSS_DS *nLevel;
          int nNewXP   = (((nCurrXP -nPenalty) < nMinXP) ? nMinXP : (nCurrXP -nPenalty));
          if( (nCurrXP -nNewXP) > 0)
          { if( !TEST_MODE) SetXP( oPC, nNewXP);
            sMessage = "\nYou have been assessed a " +IntToString( nCurrXP -nNewXP) +"XP death penalty.";
          }
        }
        break;


      case DEATH_PENALTY_GP:  // GP per level penalty
        { int nCurrGP  = GetGold( oPC);
          int nMinGP   = 0;
          int nPenalty = PER_LEVEL_GP_LOSS_DS *nLevel;
          int nNewGP   = (((nCurrGP -nPenalty) < nMinGP) ? nMinGP : (nCurrGP -nPenalty));
          if( (nCurrGP -nNewGP) > 0)
          { if( !TEST_MODE) AssignCommand( oPC, TakeGoldFromCreature( (nCurrGP -nNewGP), oPC, TRUE));
            sMessage = "\nYou have been assessed a " +IntToString( nCurrGP -nNewGP) +" GP death penalty.";
          }
        }
        break;


      case DEATH_PENALTY_ITEM:  // One random item. 80% chance normal inventory item, 20% chance equipment item.
        { int nItemCount = GetLocalInt( GetModule(), ITEM_PENALTY_DS_VAR +"_" +IntToString( nLevel));
          while( --nItemCount >= 0)
          { object oItem = OBJECT_INVALID;
            if( d10() <= 2)
            { oItem = GetRandomEquipmentItem( oPC);
              if( !GetIsObjectValid( oItem)) oItem = GetRandomInventoryItem( oPC);
            }
            else
            { oItem = GetRandomInventoryItem( oPC);
              if( !GetIsObjectValid( oItem)) oItem = GetRandomEquipmentItem( oPC);
            }


            if( GetIsObjectValid( oItem))
            { if( !TEST_MODE) DestroyObject( oItem);
              SetLocalInt( oItem, "DeathPenalty", TRUE);
              sMessage += "\nYou have lost your " +GetName( oItem) +" as a death penalty.";
            }
          }
        }
        break;


      default:  // No death penalty
        sMessage = "";
        break;
    }
  }


  // Get rid of his death tokens.
  DestroyDeathTokens( oPC);


  // Get rid of his body if it still exists.
  DestroyDeadPCBody( oPC);


  // Send him to the his death spot.
  ActionJumpToDeathSpot( sMessage, lDeathSpot);
}




void DeathTimerExpired( object oPC)
{ if( !GetIsPC( oPC))
  { // The PC logged out -- that cheater!! Oh well, he will pay for it when OnClientEnter
    // runs when he re-joins later. Since the timer expired, the body simply needs to be
    // destroyed and OnClientEnter will handle the rest.
    DestroyObject( OBJECT_SELF);


    // Destroy all the item versions too.
    string sPCID = GetLocalString( OBJECT_SELF, PCID_VAR);
    if( sPCID != "")
    { int    iNth  = 0;
      object oItem = GetObjectByTag( DEAD_PC_ITEM_TAG);
      while( GetIsObjectValid( oItem))
      { if( (GetResRef( oItem) == DEAD_PC_ITEM_RESREF) && (GetLocalString( oItem, PCID_VAR) == sPCID))
        { FloatingTextStringOnCreature( "A dead body you were carrying has vanished!", GetItemPossessor( oItem), FALSE);
          DestroyObject( oItem);
        }
        oItem = GetObjectByTag( DEAD_PC_ITEM_TAG, ++iNth);
      }
    }
  }


  // Otherwise auto-send him to church or death spot
  else switch( DEAD_LEVEL_MODE)
  { case DEAD_LEVEL_FREE_RIDE:
      // Choose the XP option. If he is at the exact start of a level he gets free-ride.
      AssignCommand( oPC, GoToChurch());
      break;


    case DEAD_LEVEL_TAKE_GOLD:
    case DEAD_LEVEL_TAKE_GOLD_PREFER_CHURCH:
      { // Use XP penalty option when the penalty would be > 0. Otherwise use the GP option.
        // If GP is also 0 he gets the free-ride.
        int nLevel   = GetHitDice( oPC);
        int nCurrXP  = GetXP( oPC);
        int nMinXP   = (nLevel *(nLevel -1) *500);
        int nPenalty = PER_LEVEL_XP_LOSS *nLevel;
        int nNewXP   = (((nCurrXP -nPenalty) < nMinXP) ? nMinXP : (nCurrXP -nPenalty));
        if( (nCurrXP -nNewXP) > 0) AssignCommand( oPC, GoToChurch( DEATH_PENALTY_XP));
        else                       AssignCommand( oPC, GoToChurch( DEATH_PENALTY_GP));
      }
      break;


    case DEAD_LEVEL_FREE_RIDE_DEATH_SPOT:
      // Choose the XP option. If he is at the exact start of a level he gets free-ride.
      AssignCommand( oPC, GoToDeathSpot());
      break;


    case DEAD_LEVEL_TAKE_GOLD_DEATH_SPOT:
    case DEAD_LEVEL_TAKE_GOLD_PREFER_DS:
      { // Use XP penalty option when the penalty would be > 0. Otherwise use the GP option.
        // If GP is also 0 he gets the free-ride.
        int nLevel   = GetHitDice( oPC);
        int nCurrXP  = GetXP( oPC);
        int nMinXP   = (nLevel *(nLevel -1) *500);
        int nPenalty = PER_LEVEL_XP_LOSS_DS *nLevel;
        int nNewXP   = (((nCurrXP -nPenalty) < nMinXP) ? nMinXP : (nCurrXP -nPenalty));
        if( (nCurrXP -nNewXP) > 0) AssignCommand( oPC, GoToDeathSpot( DEATH_PENALTY_XP));
        else                       AssignCommand( oPC, GoToDeathSpot( DEATH_PENALTY_GP));
      }
      break;


    case DEAD_LEVEL_TAKE_GOLD_PREFER_CHEAPER:
      { // Use XP penalty option when the penalty would be > 0. Otherwise use the GP option.
        // If GP is also 0 he gets the free-ride.
        int nLevel     = GetHitDice( oPC);
        int nCurrXP    = GetXP( oPC);
        int nMinXP     = (nLevel *(nLevel -1) *500);
        int nPenalty   = PER_LEVEL_XP_LOSS_DS *nLevel;
        int nNewXP     = (((nCurrXP -nPenalty) < nMinXP) ? nMinXP : (nCurrXP -nPenalty));
        if( (nCurrXP -nNewXP) > 0)
        { if( PER_LEVEL_XP_LOSS < PER_LEVEL_XP_LOSS_DS) AssignCommand( oPC, GoToChurch( DEATH_PENALTY_XP));
          else                                          AssignCommand( oPC, GoToDeathSpot( DEATH_PENALTY_XP));
        }
        else
        { if( PER_LEVEL_GP_LOSS < PER_LEVEL_GP_LOSS_DS) AssignCommand( oPC, GoToChurch( DEATH_PENALTY_GP));
          else                                          AssignCommand( oPC, GoToDeathSpot( DEATH_PENALTY_GP));
        }
      }
      break;


    case DEAD_LEVEL_TAKE_GOLD_PREFER_CHOICE:
      { // Use XP penalty option when the penalty would be > 0. Otherwise use the GP option.
        // If GP is also 0 he gets the free-ride.
        int nLevel     = GetHitDice( oPC);
        int nCurrXP    = GetXP( oPC);
        int nMinXP     = (nLevel *(nLevel -1) *500);
        int nPenalty   = PER_LEVEL_XP_LOSS_DS *nLevel;
        int nNewXP     = (((nCurrXP -nPenalty) < nMinXP) ? nMinXP : (nCurrXP -nPenalty));
        if( (nCurrXP -nNewXP) > 0)
        { if( PER_LEVEL_XP_LOSS <= PER_LEVEL_XP_LOSS_DS) AssignCommand( oPC, GoToChurch( DEATH_PENALTY_XP));
          else                                           AssignCommand( oPC, GoToDeathSpot( DEATH_PENALTY_XP));
        }
        else
        { if( PER_LEVEL_GP_LOSS <= PER_LEVEL_GP_LOSS_DS) AssignCommand( oPC, GoToChurch( DEATH_PENALTY_GP));
          else                                           AssignCommand( oPC, GoToDeathSpot( DEATH_PENALTY_GP));
        }
      }
      break;
  }
}




void RemoveHideEffects()
{ effect eRemove = GetFirstEffect( OBJECT_SELF);
  while( GetIsEffectValid( eRemove))
  { RemoveEffect( OBJECT_SELF, eRemove);
    eRemove = GetNextEffect( OBJECT_SELF);
  }
}




void ActionCorpse( int bRaiseable = TRUE, int bSelectableWhenDead = FALSE)
{ effect eDeath = SupernaturalEffect( EffectLinkEffects( EffectDamage( GetCurrentHitPoints() +11, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_ENERGY), EffectDeath()));
  ActionDoCommand( SetPlotFlag( OBJECT_SELF, FALSE));
  if( !GetIsPC( OBJECT_SELF)) ActionDoCommand( SetIsDestroyable( FALSE, bRaiseable, bSelectableWhenDead));
  ActionDoCommand( ApplyEffectToObject( DURATION_TYPE_INSTANT, eDeath, OBJECT_SELF));
}




void ActionPlayDead()
{ int iFrontBack = (d2() ? ANIMATION_LOOPING_DEAD_FRONT : ANIMATION_LOOPING_DEAD_BACK);
  ActionPlayAnimation( iFrontBack, 5.0f, 999999999.0f);
}




void ActionMoveDeadBody( location lNewLocation)
{ if( !GetIsObjectValid( GetAreaFromLocation( lNewLocation))) return;


  ClearAllActions( TRUE);
  ActionJumpToLocation( lNewLocation);
  ActionDoCommand( DelayCommand( 1.5f, RemoveHideEffects()));
  ActionPlayDead();
}




void CreateDeadBody( string sPCID, location lBody)
{ object oPC = OBJECT_SELF;
  if( !GetIsPC( oPC) || (sPCID == "") || !GetIsObjectValid( GetAreaFromLocation( lBody))) return;


  // If one already exists for this PC, destroy it. This should never happen anyway.
  DestroyDeadPCBody( oPC);


  // Create the new dead body creature for this pc.
  string sResref = ((GetGender( oPC) == GENDER_FEMALE) ? DEAD_PC_RESREF_F : DEAD_PC_RESREF);
  object oBody = CreateObject( OBJECT_TYPE_CREATURE, sResref, lBody, FALSE, DEAD_PC_TAG);
  if( !GetIsObjectValid( oBody)) return;


  // Make the dead body look like the PC, and set up the PCID variable and name on it.
  SetCreatureAppearanceType( oBody, GetAppearanceType( oPC));
  SetCreatureWingType( GetCreatureWingType( oPC), oBody);
  SetCreatureTailType( GetCreatureTailType( oPC), oBody);
  int iPart = CREATURE_PART_HEAD +1;
  while( --iPart >= CREATURE_PART_RIGHT_FOOT) SetCreatureBodyPart( iPart, GetCreatureBodyPart( iPart, oPC), oBody);
  SetPortraitResRef( oBody, GetPortraitResRef( oPC));
  SetLocalString( oBody, PCID_VAR, sPCID);
  SetName( oBody, GetName( oPC) +"'s Dead Body");


  // Make sure hostiles won't attack the dead body.
  effect eSanctuary = SupernaturalEffect( EffectSanctuary( 1000));
  ApplyEffectToObject( DURATION_TYPE_PERMANENT, eSanctuary, oBody);


  // Equip the dead body with the same stuff the PC is wearing.
  object oEquipment = GetItemInSlot( INVENTORY_SLOT_CHEST, oPC);
  if( GetIsObjectValid( oEquipment))
  { object oCopy = CopyItem( oEquipment, oBody, TRUE);
    if( GetIsObjectValid( oCopy))
    { RemoveAllItemProperties( oCopy);
      SetLocalObject( oBody, CHEST_COPY_VAR, oCopy);
    }
  }


  oEquipment = GetItemInSlot( INVENTORY_SLOT_HEAD, oPC);
  if( GetIsObjectValid( oEquipment))
  { object oCopy = CopyItem( oEquipment, oBody, TRUE);
    if( GetIsObjectValid( oCopy))
    { RemoveAllItemProperties( oCopy);
      SetLocalObject( oBody, HEAD_COPY_VAR, oCopy);
    }
  }


  oEquipment = GetItemInSlot( INVENTORY_SLOT_BOOTS, oPC);
  if( GetIsObjectValid( oEquipment))
  { object oCopy = CopyItem( oEquipment, oBody, TRUE);
    if( GetIsObjectValid( oCopy))
    { RemoveAllItemProperties( oCopy);
      SetLocalObject( oBody, BOOTS_COPY_VAR, oCopy);
    }
  }


  oEquipment = GetItemInSlot( INVENTORY_SLOT_CLOAK, oPC);
  if( GetIsObjectValid( oEquipment))
  { object oCopy = CopyItem( oEquipment, oBody, TRUE);
    if( GetIsObjectValid( oCopy))
    { RemoveAllItemProperties( oCopy);
      SetLocalObject( oBody, CLOAK_COPY_VAR, oCopy);
    }
  }


  // Start up the Purgatory timer if one is being used.
  if( PURGATORY_TIMER > 0.0) AssignCommand( oBody, DelayCommand( PURGATORY_TIMER, DeathTimerExpired( oPC)));
}




void ActionCreateDeadBody( string sPCID, location lBody)
{ ActionDoCommand( CreateDeadBody( sPCID, lBody));
}




object FindDeadBody( string sPCID)
{ if( sPCID == "") return OBJECT_INVALID;


  object oBody = OBJECT_INVALID;
  object oFind = GetObjectByTag( DEAD_PC_TAG);
  int    iNth  = 0;
  while( GetIsObjectValid( oFind))
  { if( ((GetResRef( oFind) == DEAD_PC_RESREF) || (GetResRef( oFind) == DEAD_PC_RESREF_F)) && (GetLocalString( oFind, PCID_VAR) == sPCID))
    { if( GetIsObjectValid( oBody)) DestroyObject( oFind);
      else                          oBody = oFind;
    }
    oFind = GetObjectByTag( DEAD_PC_TAG, ++iNth);
  }
  return oBody;
}




void HideDeadBody( string sPCID)
{ if( sPCID == "") return;


  object oBody = FindDeadBody( sPCID);
  if( GetIsObjectValid( oBody))
  { effect eHide = SupernaturalEffect( EffectLinkEffects( EffectVisualEffect( VFX_DUR_CUTSCENE_INVISIBILITY), EffectCutsceneGhost()));
    ApplyEffectToObject( DURATION_TYPE_PERMANENT, eHide, oBody);
  }
}




void ShowDeadBody( string sPCID, location lNewLocation)
{ if( (sPCID == "") || !GetIsObjectValid( GetAreaFromLocation( lNewLocation))) return;


  // Move the body
  object oBody = FindDeadBody( sPCID);
  if( GetIsObjectValid( oBody)) AssignCommand( oBody, ActionMoveDeadBody( lNewLocation));
}




void ActionJumpToPurgatory( int bCreateBody = FALSE)
{ SetCommandable( TRUE);
  ClearAllActions( TRUE);
  if( TEST_MODE)
  { effect eSanctuary = EffectSanctuary( 1000);
    ApplyEffectToObject( DURATION_TYPE_PERMANENT, eSanctuary, OBJECT_SELF);


    if( bCreateBody) ActionCreateDeadBody( GetPCID( OBJECT_SELF), GetLocation( OBJECT_SELF));
    ActionWait( 5.0f);
    ActionTransportToObject( GetPurgatoryWaypoint( OBJECT_SELF));
    ActionDoCommand( RemoveEffect( OBJECT_SELF, eSanctuary));
  }
  else
  { ActionTransportToObject( GetPurgatoryWaypoint( OBJECT_SELF));
    ActionDoCommand( SetPlotFlag( OBJECT_SELF, TRUE));
    if( bCreateBody) ActionCreateDeadBody( GetPCID( OBJECT_SELF), GetLocation( OBJECT_SELF));
  }
  ActionDoCommand( SetCommandable( TRUE));
  SetCommandable( FALSE);
}




void GoToPurgatory( int bCreateBody = FALSE)
{ object oPC = OBJECT_SELF;
  if( !GetIsPC( oPC)) return;


  ActionJumpToPurgatory( bCreateBody);
}




void KDS1OnModuleLoad()
{ ValidateOperatingModes();
  SetModuleOverrideSpellscript( DEATH_SPELLHOOK_SCRIPT);


  // Mark all purgatory areas as no horse areas.
  object oPurgatory = GetObjectByTag( PURGATORY_WAYPOINT_TAG);
  if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


  int iRace = RACIAL_TYPE_DWARF;
  for( iRace = RACIAL_TYPE_DWARF; iRace <= RACIAL_TYPE_HUMAN; iRace++)
  { string sRace = "";
    switch( iRace)
    { case RACIAL_TYPE_DWARF:    sRace = "Dwarf";      break;
      case RACIAL_TYPE_ELF:      sRace = "Elf";        break;
      case RACIAL_TYPE_GNOME:    sRace = "Gnome";      break;
      case RACIAL_TYPE_HALFLING: sRace = "Halfling";   break;
      case RACIAL_TYPE_HALFELF:  sRace = "Half-Elf";   break;
      case RACIAL_TYPE_HALFORC:  sRace = "Half-Orc";   break;
      default:                   sRace = "Human";      break;
    }


    string sTAG = PURGATORY_WAYPOINT_TAG +"_" +sRace;
    oPurgatory = GetObjectByTag( sTAG);
    if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


    int iGE = 0;
    int iLC = 0;
    for( iGE = 0; iGE < 3; iGE++)
      switch( iGE)
      { case 0:
          { sTAG = PURGATORY_WAYPOINT_TAG +"_G_" +sRace;
            oPurgatory = GetObjectByTag( sTAG);
            if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


            sTAG = PURGATORY_WAYPOINT_TAG +"_Good";
            oPurgatory = GetObjectByTag( sTAG);
            if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


            for( iLC = 0; iLC < 3; iLC++)
              switch( iLC)
              { case 0:
                  sTAG = PURGATORY_WAYPOINT_TAG +"_LG_" +sRace;
                  oPurgatory = GetObjectByTag( sTAG);
                  if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


                  sTAG = PURGATORY_WAYPOINT_TAG +"_L_" +sRace;
                  oPurgatory = GetObjectByTag( sTAG);
                  if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


                  sTAG = PURGATORY_WAYPOINT_TAG +"_Lawful";
                  oPurgatory = GetObjectByTag( sTAG);
                  if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);
                  break;


                case 1:
                  sTAG = PURGATORY_WAYPOINT_TAG +"_CG_" +sRace;
                  oPurgatory = GetObjectByTag( sTAG);
                  if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


                  sTAG = PURGATORY_WAYPOINT_TAG +"_C_" +sRace;
                  oPurgatory = GetObjectByTag( sTAG);
                  if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


                  sTAG = PURGATORY_WAYPOINT_TAG +"_Chaotic";
                  oPurgatory = GetObjectByTag( sTAG);
                  if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);
                  break;


                case 2:
                  sTAG = PURGATORY_WAYPOINT_TAG +"_NG_" +sRace;
                  oPurgatory = GetObjectByTag( sTAG);
                  if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


                  sTAG = PURGATORY_WAYPOINT_TAG +"_N_" +sRace;
                  oPurgatory = GetObjectByTag( sTAG);
                  if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


                  sTAG = PURGATORY_WAYPOINT_TAG +"_Neutral";
                  oPurgatory = GetObjectByTag( sTAG);
                  if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);
                  break;
              }
          }
          break;


        case 1:
          { sTAG = PURGATORY_WAYPOINT_TAG +"_E_" +sRace;
            oPurgatory = GetObjectByTag( sTAG);
            if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


            sTAG = PURGATORY_WAYPOINT_TAG +"_Evil";
            oPurgatory = GetObjectByTag( sTAG);
            if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);


            for( iLC = 0; iLC < 3; iLC++)
            { switch( iLC)
              { case 0: sTAG = PURGATORY_WAYPOINT_TAG +"_LE_" +sRace;   break;
                case 1: sTAG = PURGATORY_WAYPOINT_TAG +"_CE_" +sRace;   break;
                case 2: sTAG = PURGATORY_WAYPOINT_TAG +"_NE_" +sRace;   break;
              }
              oPurgatory = GetObjectByTag( sTAG);
              if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);
            }
          }
          break;


        case 2:
          { for( iLC = 0; iLC < 3; iLC++)
            { switch( iLC)
              { case 0: sTAG = PURGATORY_WAYPOINT_TAG +"_LN_" +sRace;   break;
                case 1: sTAG = PURGATORY_WAYPOINT_TAG +"_CN_" +sRace;   break;
                case 2: sTAG = PURGATORY_WAYPOINT_TAG +"_TN_" +sRace;   break;
              }
              oPurgatory = GetObjectByTag( sTAG);
              if( GetIsObjectValid( oPurgatory)) SetLocalInt( GetArea( oPurgatory), "X3_NO_HORSES", TRUE);
            }
          }
          break;
      }
  }
}




void KDS1OnClientEnter()
{ object oPC = GetEnteringObject();
  if( !GetIsPC( oPC)) return;


  // Make sure plot flag is reset and effects are cleared out.
  SetPlotFlag( oPC, FALSE);
  RemoveAllEffects( oPC);


  // Check for logout cheaters.
  if( HasItem( oPC, DEATH_TOKEN_TAG))
  { // If his body is still kicking around then the timer is still going and all that
    // is necessary is to send him to purgatory. If his body is gone, send him to the
    // church with the automatic XP penalty.
    object oBody = FindDeadBody( GetPCID( oPC));
    if( GetIsObjectValid( oBody)) AssignCommand( oPC, DelayCommand( 1.0f, GoToPurgatory()));


    // When his body is gone his death spot cannot be determined so he will always go to
    // the Church. All DeadLevel Take Gold Modes will still take gold from dead level players.
    else switch( DEAD_LEVEL_MODE)
    { case DEAD_LEVEL_FREE_RIDE:
      case DEAD_LEVEL_FREE_RIDE_DEATH_SPOT:
        // Choose the XP option. If he is at the exact start of a level he gets free-ride.
        AssignCommand( oPC, DelayCommand( 1.0f, GoToChurch()));
        break;


      case DEAD_LEVEL_TAKE_GOLD:
      case DEAD_LEVEL_TAKE_GOLD_PREFER_CHURCH:
      case DEAD_LEVEL_TAKE_GOLD_DEATH_SPOT:
      case DEAD_LEVEL_TAKE_GOLD_PREFER_DS:
      case DEAD_LEVEL_TAKE_GOLD_PREFER_CHEAPER:
      case DEAD_LEVEL_TAKE_GOLD_PREFER_CHOICE:
        { // Use XP penalty option when the penalty would be > 0. Otherwise use the GP option.
          // If GP is also 0 he gets the free-ride.
          int nLevel   = GetHitDice( oPC);
          int nCurrXP  = GetXP( oPC);
          int nMinXP   = (nLevel *(nLevel -1) *500);
          int nPenalty = PER_LEVEL_XP_LOSS *nLevel;
          int nNewXP   = (((nCurrXP -nPenalty) < nMinXP) ? nMinXP : (nCurrXP -nPenalty));
          if( (nCurrXP -nNewXP) > 0) AssignCommand( oPC, DelayCommand( 1.0f, GoToChurch( DEATH_PENALTY_XP)));
          else                       AssignCommand( oPC, DelayCommand( 1.0f, GoToChurch( DEATH_PENALTY_GP)));
        }
        break;
    }
  }


  // Check for guys that left while carrying a dead PC(s). Get rid of their item-version(s).
  if( HasItem( oPC, DEAD_PC_ITEM_TAG))
  { object oItem = GetFirstItemInInventory( oPC);
    while( GetIsObjectValid( oItem))
    { if( GetResRef( oItem) == DEAD_PC_ITEM_RESREF) DestroyObject( oItem);
      oItem = GetNextItemInInventory( oPC);
    }
  }
}




void DropAllDeadPCs( object oPC, location lDropAt)
{ DeleteLocalInt( oPC, LOCATION_TRACKING_VAR);
  if( GetIsObjectValid( GetAreaFromLocation( lDropAt)))
  { // If he has any dead PC's on him, make him "drop them". Actually the creature version
    // of the dead PC is moved to the current location and made visible.
    int nPCCount = GetLocalInt( oPC, DEAD_PC_COUNT_VAR) +1;
    while( --nPCCount > 0)
    { string sPCID = GetLocalString( oPC, DEAD_PC_LIST_PREFIX +IntToString( nPCCount));
      if( sPCID != "")
      { // If a PC is found that he was carrying, move the dead body to his last location.
        object oBody = FindDeadBody( sPCID);
        if( GetIsObjectValid( oBody)) AssignCommand( oBody, ActionMoveDeadBody( lDropAt));
      }
      DeleteLocalString( oPC, DEAD_PC_LIST_PREFIX +IntToString( nPCCount));
    }


    // Destroy all the dead pc items he is carrying unless this is being called from
    // the OnClientLeave script in which case it cannot be done and will be handled by
    // OnClientEnter when he rejoins the module.
    if( GetIsPC( oPC))
    { // Not being called from OnClientLeave
      object oItem = GetFirstItemInInventory( oPC);
      while( GetIsObjectValid( oItem))
      { if( GetResRef( oItem) == DEAD_PC_ITEM_RESREF) DestroyObject( oItem);
        oItem = GetNextItemInInventory( oPC);
      }
    }
  }
  DeleteLocalInt( oPC, DEAD_PC_COUNT_VAR);
  DeleteLocalInt( oPC, LOCATION_TRACKING_VAR);
}




void KDS1OnClientLeave()
{ object oPC = GetExitingObject();
  DropAllDeadPCs( oPC, GetLocalLocation( oPC, LAST_LOCATION_VAR));
}




void ActionEquipCopies()
{ object oEquipment = GetLocalObject( OBJECT_SELF, CHEST_COPY_VAR);
  if( GetIsObjectValid( oEquipment)) ActionEquipItem( oEquipment, INVENTORY_SLOT_CHEST);


  oEquipment = GetLocalObject( OBJECT_SELF, HEAD_COPY_VAR);
  if( GetIsObjectValid( oEquipment)) ActionEquipItem( oEquipment, INVENTORY_SLOT_HEAD);


  oEquipment = GetLocalObject( OBJECT_SELF, BOOTS_COPY_VAR);
  if( GetIsObjectValid( oEquipment)) ActionEquipItem( oEquipment, INVENTORY_SLOT_BOOTS);


  oEquipment = GetLocalObject( OBJECT_SELF, CLOAK_COPY_VAR);
  if( GetIsObjectValid( oEquipment)) ActionEquipItem( oEquipment, INVENTORY_SLOT_CLOAK);


  DeleteLocalObject( OBJECT_SELF, CHEST_COPY_VAR);
  DeleteLocalObject( OBJECT_SELF, HEAD_COPY_VAR);
  DeleteLocalObject( OBJECT_SELF, BOOTS_COPY_VAR);
  DeleteLocalObject( OBJECT_SELF, CLOAK_COPY_VAR);
}




void KDS1OnSpawn()
{ SetPlotFlag( OBJECT_SELF, FALSE);
  ClearAllActions( TRUE);
  ActionDoCommand( SetPlotFlag( OBJECT_SELF, TRUE));
  ActionDoCommand( ActionEquipCopies());  // Equip the stuff given to the body when it was created.
  ActionDoCommand( ActionPlayDead());
}




void KDS1OnConversation()
{ object oPC = GetLastSpeaker();
  if( !GetIsPC( oPC) || (!TEST_MODE && GetIsObjectValid( GetItemPossessedBy( oPC, DEAD_PC_ITEM_TAG)))) return;


  string sPCID = GetLocalString( OBJECT_SELF, PCID_VAR);
  if( sPCID == "")
  { if( (GetResRef( OBJECT_SELF) == DEAD_PC_RESREF) || (GetResRef( OBJECT_SELF) == DEAD_PC_RESREF_F)) DestroyObject( OBJECT_SELF);   return; }


  // Create the dead body item on the clicker, and hide the dead body creature.
  object oBodyItem = CreateItemOnObject( DEAD_PC_ITEM_RESREF, oPC);
  if( GetIsObjectValid( oBodyItem))
  { SetLocalString( oBodyItem, PCID_VAR, sPCID);
    SetName( oBodyItem, GetName( oPC) +"'s Dead Body");
    SetPortraitResRef( oBodyItem, GetPortraitResRef( oPC));
    HideDeadBody( sPCID);
  }
}


//void main(){}
 

 

 

 

 


76561198051392382.png


#2 AlthorDeMalavir

AlthorDeMalavir

    Neonato

  • Miembro
  • PipPip
  • 117 posts

Posteado 15 April 2013 - 05:11 PM

Suponiendo que lo hayas hecho bien, yo primero verificaría que no te haya sobreescrito tu nw_i0_plot , porque lo tiene en uno de sus includes, si tienes el nw_i0_plot entre tus scripts, borralo, para que use el que lleva el juego por defecto, puede ser una versión antigua del nw_i0_plot y por eso te da error.

 

Otra cosa que haría es quitar uno de los includes referidos al nw_i0_plot porque lo está cargando dos veces, una en tu script y otra en el de el.


YourServerList.com Listado de servidores de Minecraft, Neverwinter Nights 1 y 2 y Terraria.


#3 Ertos

Ertos

    Elder

  • Miembro
  • PipPipPipPip
  • 683 posts

Posteado 15 April 2013 - 05:13 PM

Umh...A ver si me vuelvo a armar de paciencia y me pongo a trastear de nuevo.


76561198051392382.png




Responder



  



También marcado con nwn1, nwn, Includes, system, cosa

A Bragol. Tus amigos te echan de menos.