1. // HCR v3.0.3 - 18th May, 2005 - SE
  2. //::////////////////////////////////////////////////////////////////////////////
  3. //:: FileName:  NW_CH_AC7
  4. //:: OnDeath handler for summons, familiars, animal companions, and henchmen.
  5. //::////////////////////////////////////////////////////////////////////////////
  6. /*
  7.    REALFAM is the XP penalty set in hc_defaults, 200 by default - SE
  8. */
  9. //::////////////////////////////////////////////////////////////////////////////
  10. //::////////////////////////////////////////////////////////////////////////////
  11. // -----------------------------------------------------------------------------
  12. // The Krit, 2008-01-11
  13. // Deleting henchmen-specific stuff so the code is easier to manage on WoG.
  14. // (There are no henchmen on this persistent world.)
  15. // Rest of the code has been simplified.
  16. // -----------------------------------------------------------------------------
  17. //::////////////////////////////////////////////////////////////////////////////
  18.  
  19. #include "HC_Inc"
  20.  
  21. // :: Delayed Cleanup for remains of familiars and animal companions ::
  22. // Object created to mark the remains of an animal companion or familiar
  23. // This should be any "note" item. The name and description will be set via script.
  24. const string ASSOCIATE_MARKER_RESREF = "notetoimogen";  
  25. // This is the tag the cleanup script will know denotes a fallen familiar/companion.
  26. const string ASSOCIATE_MARKER_TAG = "AssociateRemains"; // must match anewonexit.nss
  27.  
  28. // -----------------------------------------------------------------------------
  29. // Enforces the XP penalty when oMaster's familiar was killed.
  30. // nXPPen is the amount of XP to lose per sorcerer/wizard level.
  31. void FamiliarXPHit(object oMaster, int nXPPen)
  32. {
  33.     // Clean up a local integer. (See nw_ch_ac1 for its purpose.)
  34.     DeleteLocalInt(OBJECT_SELF, "FAMMSG");
  35.  
  36.     // Set the death local on the module.
  37.     SetLocalInt(oMod, "FAMDIED" + GetPlayerID(oMaster), 1);
  38.  
  39.     // Determine amount of XP penalty set in hc_defaults - 9th Jan, Sir Elric
  40.     // Should be per wizard/sorcerer (combined) level -- TK.
  41.     nXPPen *= GetLevelByClass(CLASS_TYPE_WIZARD, oMaster) +
  42.               GetLevelByClass(CLASS_TYPE_SORCERER, oMaster);
  43.     // Halve the penalty on a successful fortitude save.
  44.     if ( FortitudeSave(oMaster, 15) > 0 )
  45.         nXPPen /= 2;
  46.  
  47.     // Apply the XP penalty via the HC script.
  48.     SetLocalInt(oMaster, "TAKEXP", nXPPen);
  49.     ExecuteScript("hc_takexp", oMaster);
  50. }
  51.  
  52.  
  53. // -----------------------------------------------------------------------------
  54. // Enforces the HP penalty when oMaster's familiar was killed.
  55. void FamiliarHPHit(object oMaster)
  56. {
  57.     // Damage is nominally 1d6.
  58.     int nDamage = d6();
  59.  
  60.     // However, familiar death can never kill the PC, only wound them.
  61.     int nCurrentHP = GetCurrentHitPoints(oMaster);
  62.     if ( nDamage >= nCurrentHP )
  63.         nDamage = nCurrentHP - 1;
  64.  
  65.     // Apply the hitpoint damage.
  66.     ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage), oMaster);
  67. }
  68.  
  69.  
  70. //::////////////////////////////////////////////////////////////////////////////
  71. // -----------------------------------------------------------------------------
  72. void main()
  73. {
  74.     object oMaster = GetMaster();
  75.  
  76.     // There is only special handling for the death of a PC's associates.
  77.     if ( GetIsPC(oMaster)  &&  !GetIsDM(oMaster)  &&  !GetIsDMPossessed(oMaster) )
  78.     {
  79.         // IMPORTANT: If special handling is allowed for associates of NPC's,
  80.         // then the next check needs to be more involved. This is because an
  81.         // NPC's familiar and/or animal companion is officially a henchman, as
  82.         // far as the game engine is concerned. (By-product of the AI.)
  83.  
  84.         int nAssocType = GetAssociateType(OBJECT_SELF);
  85.  
  86.         // There is only special handling for familiars.
  87.         if ( nAssocType == ASSOCIATE_TYPE_FAMILIAR )
  88.         {
  89.             // Give the PC some feedback regarding the familiar's death.
  90.             FloatingTextStrRefOnCreature(63489, oMaster, FALSE);
  91.  
  92.             // Familiar death hurts the master.
  93.             // See whether the penalty is XP or HP.
  94.             int nXPPen = GetLocalInt(oMod, "REALFAM");
  95.             if ( nXPPen > 0 )
  96.                 FamiliarXPHit(oMaster, nXPPen);
  97.             else
  98.                 FamiliarHPHit(oMaster);
  99.         }
  100.  
  101.         // Add item to familiar and animal companion inventory, checkable in cleanup scripts.
  102.         if ( ( nAssocType == ASSOCIATE_TYPE_FAMILIAR ) || ( nAssocType == ASSOCIATE_TYPE_ANIMALCOMPANION ) )
  103.         {
  104.             // Check that the fam/comp had something in inventory
  105.             object oAnyItem = GetFirstItemInInventory(OBJECT_SELF);
  106.             if ( GetIsObjectValid(oAnyItem) )
  107.             {
  108.                 // Create a note in inventory
  109.                 object oNote = CreateItemOnObject(ASSOCIATE_MARKER_RESREF, OBJECT_SELF, 1, ASSOCIATE_MARKER_TAG);
  110.                 SetName(oNote, "Note");
  111.                 string sDesc = "Here fell " + GetName(OBJECT_SELF) + ", defending " + GetName(oMaster) + ".";
  112.                 SetDescription(oNote, sDesc);
  113.             }
  114.         }
  115.     }
  116. }
  117. //::////////////////////////////////////////////////////////////////////////////