Advertisement
Guest User

Untitled

a guest
Jul 20th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.13 KB | None | 0 0
  1. //::///////////////////////////////////////////////
  2. //:: rest_include
  3. //:://////////////////////////////////////////////
  4. /*
  5. MAGUS REST SYSTEM - INCLUDE
  6. DO NOT EDIT UNCONFIGURABLE PARTS OF THIS FILE
  7.  
  8.  
  9. SPECIALLY MARKED CONSTANTS, FUNCTIONS AND INCLUDES MAY BE ADJUSTED BY USER
  10.  
  11. EXPLANATION
  12. Rest restrictions are assumed to be on module wide
  13. (unless module int REST_UNRESTRICTED = 1 )
  14. Rest in an area can be restricted or unrestricted
  15. : area int REST_RESTRICTED = 1
  16. - set rest restrictions in a specific area, when rest is unrestricted module wide
  17. : area int REST_UNRESTRICTED = 1
  18. - remove rest restrictions in a specific area, when rest is restricted module wide
  19.  
  20. Rest Restriction rules
  21. Can be completely rewritten. See ResterRequirements()
  22.  
  23. Example Rules included in this config file are as follows:
  24. : can only rest once every 8 game hours
  25. : comfortable rest (regain ALL hitpoints and spells) has the following requirements:
  26. - campfire: required in cold conditions (eg. outdoors at night)
  27. - food: must have eaten recently, or have food to consume while resting
  28. - bedroll: required when sleeping in the wild unless the character is accustomed to it
  29.  
  30. */
  31. //:://////////////////////////////////////////////
  32. //:: Creator : The Magus (2013 july 13)
  33. //:: Modified : henesua (2014 june 1) pulled all includes into one to make this lean
  34. //:://////////////////////////////////////////////
  35.  
  36. // INCLUDES --------------------------------------------------------------------
  37.  
  38. // used for configurable functions
  39. // the following includes may contain functions or constants which you have defined elsewhere
  40. // if that is the case feel free to use your own includes and delete these provided
  41. #include "x3_inc_skin"
  42. #include "_inc_constants"
  43. #include "_inc_color"
  44. #include "_inc_util"
  45. // includes for add on systems. add or remove these as needed
  46. // Magus' Camp System - campfires and campsites (also include Magus' Food System)
  47. #include "camp_include"
  48.  
  49.  
  50. // CONSTANTS -------------------------------------------------------------------
  51.  
  52. // ========= CONFIGURABLE ===============
  53.  
  54. // REST REQUIREMENTS - MAX NUMBER OF TESTS
  55. // number of tests to perform when resting. see ResterRequirements(int nTest)
  56. // rest rules are tested in order from 1 to the value of LAST_REST_TEST
  57. const int LAST_REST_TEST = 5;
  58.  
  59. // SPELL LIMITS
  60. // the flag REST_LIMIT_SPELLS when applied in ResterRequirements() triggers the limit of spells recovered by the pc
  61. // you can apply limits to the level of spells that a PC recovers during rest by reducing their ability scores
  62. // turn off particular spell limits permanently by adjusting one or more of the following values to 0
  63. const int REST_SPELL_LIMIT_INT = 1;
  64. const int REST_SPELL_LIMIT_WIS = 1;
  65. const int REST_SPELL_LIMIT_CHA = 1;
  66. // also see REST_NO_SPELL_LIMIT_ in rest_globals as a means to temporarily turn off spell limits for a PC
  67. // SPELL ABILITY DAMAGE MINIMUMS and MAXIMUMS
  68. const int REST_MAX_DAMAGE_INT = 10;
  69. const int REST_MIN_DAMAGE_INT = 1;
  70. const int REST_MAX_DAMAGE_WIS = 10;
  71. const int REST_MIN_DAMAGE_WIS = 1;
  72. const int REST_MAX_DAMAGE_CHA = 10;
  73. const int REST_MIN_DAMAGE_CHA = 1;
  74.  
  75. // REST PREPARATORY ACTIONS/SCRIPTS
  76. // add or change or remove these as you see fit
  77. // see ResterPrepares ()
  78. // each codeblock in ResterPrepares() is an action specified by index
  79. const int REST_ACTION_MAKE_CAMPFIRE = 1;
  80. const int REST_ACTION_LIGHT_CAMPFIRE = 2;
  81.  
  82.  
  83. // USER ADDED VALUES (OR EXAMPLES OF SUCH)
  84.  
  85. // Test 1 of RestRequirements() determines whether enough time has passed since the last rest by this PC
  86. // See GetIsTimeToRest() this value is used in ResterFinishesRest() to establish when the PC can rest again
  87. // 1+ = hours required between rests OR 0 = no required time between rests
  88. const int HOURS_BETWEEN_RESTS = 2;
  89. // local set on rester to track when they may next rest. Changing the value makes no difference as it is merely a label for a local variable.
  90. const string NEXT_REST_TIME = "REST_NEXT";
  91.  
  92. // Test 2 of RestRequirements() determines whether the resting PC is cold
  93. // set area variable int "AREA_COLD" = 1 to specify that the area is cold (see GetIsCold() )
  94. const string AREA_COLD = "AREA_COLD";
  95.  
  96. // Test 3 of RestRequirements() determines whether the PC has had enough to eat - see GetIsHungry() in food_configure
  97. // and if they are hungry, they need to eat a food item in inventory
  98. // ----------- see food_include ----------
  99.  
  100. // Test 4 of RestRequirements() determines whether the PC is comfortable sleeping on the ground
  101. // a bedroll may or may not be required depending on the PC - see GetNeedsBedToRestComfortably()
  102. // Tag for bed roll item - an item with the bedroll tag can be used as a bed roll
  103. const string TAG_BEDROLL = "bedroll"; // see GetHasBed()
  104.  
  105.  
  106.  
  107. // ================= NOT CONFIGURABLE ==================
  108.  
  109. // RESTRICTING REST
  110. // set these local integers on the module and areas to explicitly declare whether resting is restricted
  111. // the assumption is that module wide resting is restricted
  112. // to remove rest restriction only in a specific area set int REST_UNRESTRICTED = 1 on that area
  113. // if you wish to set resting as unrestricted module wide set int REST_UNRESTRICTED = 1 on the module
  114. // to ensure that an area has rest restriction rules set int REST_RESTRICTED = 1 on that area
  115. const string REST_RESTRICTED = "REST_RESTRICTED";
  116. const string REST_UNRESTRICTED = "REST_UNRESTRICTED";
  117. // local used to store which rest restrictions are ignored here
  118. const string REST_SHELTER = "REST_SHELTER";
  119. const int REST_IGNORE_TIME = 1;
  120. const int REST_IGNORE_WARMTH = 2;
  121. const int REST_IGNORE_BED = 4;
  122. const int REST_IGNORE_FOOD = 8;
  123.  
  124. // local int that when set on the PC prevents temporary ability score damage while resting
  125. const string REST_NO_SPELL_LIMIT_INT = "REST_NO_SPELL_LIMIT_INT";
  126. const string REST_NO_SPELL_LIMIT_WIS = "REST_NO_SPELL_LIMIT_WIS";
  127. const string REST_NO_SPELL_LIMIT_CHA = "REST_NO_SPELL_LIMIT_CHA";
  128.  
  129. // locals set on rester by the rest system
  130. const string REST_TEST_RESULTS = "REST_RESULTS";
  131. const string CAUSE_OF_REST_FAILURE = "REST_FAIL_ID";
  132. const string DESCRIBE_REST = "REST_FEEDBACK_STRING";
  133. const string REST_FATIGUE = "REST_FATIGUE";
  134. const string REST_HP = "REST_HITPOINTS";
  135.  
  136. const string REST_PREPARATION_COUNT = "PREPARATION_COUNT";
  137. const string REST_PREPARATION_ = "PREPARATION_";
  138. const string REST_CONSUME_COUNT = "CONSUME_COUNT";
  139. const string REST_CONSUME_ = "CONSUME_";
  140.  
  141. // REST SYSTEM FLAGS
  142. // Flags which are set in response to test results (each is a bit which can be set or removed)
  143. // each flag when found on the rester determines how the rester's rest proceeds
  144. // see function TestRestRules in file aa_rest_config
  145. const int REST_POSTPONE = 1; // cancel the rest action (see RestStarted() in rest_include )
  146. const int REST_PREPARE = 2; // set up an action for rester to perform when rest is cancelled (you should also set the postpone flag) (see RestPreparation() in rest_include )
  147. const int REST_CONSUME = 4; // destroy the item (see RestConsumeItems() in rest_include )
  148. const int REST_UNCOMFORTABLE = 8; // signal fatigue (but you must script responses to fatigue) (see RestComfortable() in rest_include )
  149. const int REST_LIMIT_HP = 16;// limit HP restored (see RestLimitHP() in rest_include )
  150. const int REST_LIMIT_SPELLS = 32;// limit spell levels restored (see RestLimitSpells() in rest_include )
  151.  
  152.  
  153.  
  154.  
  155. // FUNCTION DECLARATIONS -------------------------------------------------------
  156.  
  157. // ========== CONFIGURABLE ===========
  158. // these functions should not be deleted, and must keep their names, types, and arguments
  159. // you may however alter the contents of these functions
  160. // if only specific parts of a function are configurable those parts are marked with CONFIGURABLE
  161.  
  162. // configure your tests for resting here. returns a bit flag [FILE: rest_config]
  163. // each rule will be tested in order from 1 until LAST_REST_TEST (see constants above) is reached.
  164. int ResterRequirements(int nTest);
  165. // Feedback string for failed rest to be given to character [FILE: rest_config]
  166. string ResterFailureText(int nTestFailed);
  167. // Caller Begins a Successful Rest. [FILE: rest_config]
  168. // Customize rest beginning here
  169. void ResterBeginsRest();
  170. // Caller Fails to Rest Successfully. [FILE: rest_config]
  171. // Customize rest cancellation here
  172. void ResterFailsToRest();
  173. // Caller Finishes Resting Successfully. [FILE: rest_config]
  174. // Customize rest completion here
  175. void ResterFinishesRest();
  176. // configure how consumables affect the character (if at all). [FILE: rest_config]
  177. // returns TRUE if the item needs to be destroyed
  178. int ResterConsumes(object oConsume);
  179. // configure rest preparation scripts here. [FILE: rest_config]
  180. // each code block that is executed enters the action queue of the resting PC
  181. void ResterPrepares(int nScript);
  182. // wrapper function for Getting a persistent fatigue value [FILE: rest_config]
  183. // returns a count of consecutive number of uncomfortable rests.
  184. int ResterGetFatigue(object oRester=OBJECT_SELF);
  185. // wrapper function for Setting a persistent fatigue value [FILE: rest_config]
  186. // sets the count of consecutive uncomfortable rests.
  187. void ResterSetFatigue(int nFatigue, object oRester=OBJECT_SELF);
  188. // Configure max spell level recovered when resting. [FILE: rest_config]
  189. // see RestLimitSpells() in rest_include
  190. // the flag REST_LIMIT_SPELLS triggers execution of RestLimitSpells()
  191. int ResterMaxSpellLevelRecovered();
  192. // Configure the amount of damage to apply after a rest. [FILE: rest_config]
  193. // this can be used to limit HP recovery while resting
  194. // see RestLimitHP() in rest_include
  195. // the flag REST_LIMIT_HP triggers execution of RestLimitHP()
  196. int ResterDamageLimitsHPRecovery();
  197.  
  198. // ........ Individual Rest Tests (user configurable)
  199.  
  200. // Returns TRUE if enough time has passed since last rest [FILE: rest_config]
  201. int GetIsTimeToRest(object oPC=OBJECT_SELF);
  202. // Returns TRUE if oPC is cold (needs a fire to rest) [FILE: rest_config]
  203. int GetIsCold(object oPC=OBJECT_SELF);
  204. // Returns TRUE if oPC needs a bed to rest [FILE: rest_config]
  205. int GetNeedsBedToRestComfortably(object oPC=OBJECT_SELF);
  206.  
  207. // ........ You may have already defined similar functions ........
  208.  
  209. // Returns TRUE if oPC has a bed to rest on [FILE: rest_config]
  210. int GetHasBed(object oPC=OBJECT_SELF);
  211.  
  212.  
  213. // ========== NOT CONFIGURABLE ============
  214.  
  215. // REST SUB-EVENTS ............................
  216.  
  217. // Rest Event Begins. Executes on Resting PC [FILE: rest_include]
  218. void RestStarted();
  219. // Rest Event Is Cancelled. Executes on Resting PC [FILE: rest_include]
  220. void RestCanceled();
  221. // Rest Event Completes. Executes on Resting PC [FILE: rest_include]
  222. void RestFinished();
  223.  
  224. // REST RULE HANDLING .........................
  225.  
  226. // returns TRUE if resting is unrestricted for oRester under current circumstances [FILE: rest_include]
  227. int GetRestUnrestricted(object oRester=OBJECT_SELF);
  228. // Tests rest requirements for caller and returns the results. [FILE: rest_include]
  229. // result is an integer containing flags to be tested with bitwise operators
  230. // see rest_globals under the REST TEST FLAGS heading for constants to use
  231. int TestRestRequirements();
  232.  
  233. // REST RESULTS .................................
  234.  
  235. // Consume items required for resting. Executes on Resting PC [FILE: rest_include]
  236. // this function should not be deleted nor have its name changed
  237. void RestConsumeItems();
  238. // Iterate through preparatory actions prior to resting. Executes on Resting PC [FILE: rest_include]
  239. void RestPreparation();
  240. // Track fatigue in number of consecutive uncomfortable rests. Executes on Resting PC [FILE: rest_include]
  241. void RestComfortable(int bSuccess=TRUE);
  242. // Limit spell levels memorized. Executes on Resting PC [FILE: rest_include]
  243. void RestLimitSpells();
  244. // Limit HP recovered by percentage. Executes on Resting PC [FILE: rest_include]
  245. void RestLimitHP();
  246.  
  247. // REST SYSTEM UTILITIES .........................
  248.  
  249. // Provide feedback to explain rest results. Executes on Resting PC [FILE: rest_include]
  250. void RestFeedback(int nRestSuccess=TRUE);
  251. // Clean up locals set on rester. Executes on Resting PC [FILE: rest_include]
  252. void RestGarbageCollection();
  253. // Rester adds item to array of items to consume while resting [FILE: rest_include]
  254. // see ResterConsumes
  255. void ResterAddConsumable(object oConsumable);
  256.  
  257. // Put a preparatory script in rester's action queue. [FILE: rest_include]
  258. // the preparatory action script is executed from a code block see ResterPrepares
  259. void ResterAddPreparatoryAction(int nPrepScript);
  260.  
  261.  
  262.  
  263. // FUNCTION IMPLEMENTATIONS ----------------------------------------------------
  264.  
  265. // ============== CONFIGURABLE =======================================
  266.  
  267. int ResterRequirements(int nTest)
  268. {
  269. int nResult;
  270.  
  271. // CONFIGURABLE
  272. // you may change code within a code block
  273. // and you may add or remove code blocks
  274. // LAST_REST_TEST is the index of the last code block to execute (see constants above)
  275.  
  276. // This function defines the rest requirements for a player with active rest restrictions
  277. // each code block is a requirement (aka test) for resting
  278. // the results of success or failure are up to you
  279. // but are limited to REST SYSTEM FLAGS unless you create your own bitwise flags,
  280. // and implement a function that runs when the flag is tripped.
  281. // these custom rest results should be executed on rest completion (see ResterFailsToRest() and ResterFinishesRest() )
  282.  
  283. // "nTest" identifies which code block to execute
  284. // this function is called recursively by TestRestRequirements() in the file rest_include
  285. // which means that the code blocks are executed in order until LAST_REST_TEST is reached (see constants above)
  286. // the first test which results in REST_POSTPONE will also end recursion in TestRestRequirements() (meaning that that code block will be the last executed)
  287. // in this way tests with a lower index have a higher priority
  288. // see REST SYSTEM FLAGS in rest_globals for a list of possible results
  289.  
  290. int nShelter = GetLocalInt(OBJECT_SELF,REST_SHELTER);
  291.  
  292. // require HOURS_BETWEEN_RESTS
  293. if( nTest==1 && !(nShelter&REST_IGNORE_TIME) )
  294. {
  295. if(!GetIsTimeToRest())
  296. {
  297. nResult |= REST_POSTPONE; // current rest action will be cancelled
  298. SetLocalInt(OBJECT_SELF, CAUSE_OF_REST_FAILURE, nTest);// setup explanation for why the PC can not rest
  299. }
  300. }
  301. // require WARMTH if the PC is COLD
  302. else if(nTest==2 && !(nShelter&REST_IGNORE_WARMTH) )
  303. {
  304. if(GetIsCold())
  305. {
  306. // THE MAGUS' CAMP SYSTEM
  307. // Search for firewood in inventory, and store results on PC for use later
  308. object oFirewood = GetFirewoodInInventory();
  309. SetLocalObject(OBJECT_SELF, CAMP_FIREWOOD, oFirewood);
  310. // determine if a nearby campsite is unlit
  311. if(GetIsNearCamp()==1)
  312. {
  313. nResult |= REST_POSTPONE; // current rest action will be cancelled
  314. SetLocalInt(OBJECT_SELF, CAUSE_OF_REST_FAILURE, nTest);// setup explanation for why a campfire has to be light
  315.  
  316. nResult |= REST_PREPARE; // pc will conduct an action (to prepare for rest)
  317. ResterAddPreparatoryAction(REST_ACTION_LIGHT_CAMPFIRE); // give PC the "light campfire" action
  318. }
  319. // determine whether PC is able to make a campfire
  320. else if(oFirewood!=OBJECT_INVALID && GetCanCreatureMakeCampfire())
  321. {
  322. nResult |= REST_POSTPONE; // current rest action will be cancelled
  323. SetLocalInt(OBJECT_SELF, CAUSE_OF_REST_FAILURE, nTest);// setup explanation for why a campfire has to be built
  324.  
  325. nResult |= REST_PREPARE; // pc will conduct an action (to prepare for rest)
  326. ResterAddPreparatoryAction(REST_ACTION_MAKE_CAMPFIRE); // give PC the "make campfire" action
  327. }
  328. else
  329. {
  330. string sResponse = GetLocalString(OBJECT_SELF,DESCRIBE_REST);
  331. if(sResponse=="")
  332. sResponse = RED+"You rest uncomfortably.";
  333. SetLocalString(OBJECT_SELF,DESCRIBE_REST, sResponse+" "+PINK+"It is cold." );
  334.  
  335. // rest will proceed but be uncomfortable
  336. nResult |= REST_UNCOMFORTABLE; // uncomfortable rest (fatigue)
  337. nResult |= REST_LIMIT_HP; // limit hp recovered
  338. nResult |= REST_LIMIT_SPELLS; // limit spells recovered
  339. }
  340. }
  341. }
  342. // require FOOD
  343. else if(nTest==3 && !(nShelter&REST_IGNORE_FOOD) )
  344. {
  345. if(GetIsHungry())
  346. {
  347. object oFood = GetFoodInInventory();
  348. if(oFood!=OBJECT_INVALID)
  349. {
  350. ResterAddConsumable(oFood); // add oFood to the list of items to consume when resting
  351. nResult |= REST_CONSUME; // consume items required for rest
  352. }
  353. else
  354. {
  355. string sResponse = GetLocalString(OBJECT_SELF,DESCRIBE_REST);
  356. if(sResponse=="")
  357. sResponse = RED+"You rest uncomfortably.";
  358. SetLocalString(OBJECT_SELF,DESCRIBE_REST, sResponse+" "+PINK+"You are hungry." );
  359.  
  360. // rest will proceed but be uncomfortable
  361. nResult |= REST_UNCOMFORTABLE; // uncomfortable rest (fatigue)
  362. nResult |= REST_LIMIT_HP; // limit hp recovered
  363. }
  364. }
  365. }
  366. // require BED
  367. else if(nTest==4 && !(nShelter&REST_IGNORE_BED) )
  368. {
  369. if(GetNeedsBedToRestComfortably()&&!GetHasBed())
  370. {
  371. string sResponse = GetLocalString(OBJECT_SELF,DESCRIBE_REST);
  372. if(sResponse=="")
  373. sResponse = RED+"You rest uncomfortably.";
  374. SetLocalString(OBJECT_SELF,DESCRIBE_REST, sResponse+" "+PINK+"The ground is hard without a bed roll." );
  375.  
  376. // rest will proceed but be uncomfortable
  377. nResult |= REST_UNCOMFORTABLE; // uncomfortable rest (fatigue)
  378. nResult |= REST_LIMIT_SPELLS; // limit spells recovered
  379. }
  380. }
  381. // require that the character's breathing is unimpacted
  382. else if(nTest==5 && GetLocalString(OBJECT_SELF,"UNDERWATER_ID")!="")
  383. {
  384. // is their breathing impacted?
  385. if( GetLocalInt(OBJECT_SELF,"UNDERWATER_EFFECTS")&IMPACT_BREATHING )
  386. {
  387. nResult |= REST_POSTPONE; // current rest action will be cancelled
  388. SetLocalInt(OBJECT_SELF, CAUSE_OF_REST_FAILURE, nTest);// setup explanation for why the PC can not rest
  389. }
  390. }
  391.  
  392.  
  393. return nResult;
  394. }
  395.  
  396. string ResterFailureText(int nTestFailed)
  397. {
  398. // CONFIGURABLE
  399. // CUSTOMIZE THE RESPONSES AS YOU SEE FIT
  400. // the index of each block/case correlates with the index of blocks in ResterRequirements()
  401. // these messages appear for the player when a rest requirement resulted in a REST_POSTPONE flag
  402. int time = (GetLocalInt(OBJECT_SELF, NEXT_REST_TIME)-GetTimeCumulative())/GetLocalInt(GetModule(), "IGMINUTES_PER_RLMINUTE");
  403. if(time<=0)
  404. time = 2;
  405. switch(nTestFailed)
  406. {
  407. // test: tired/time limit
  408. case 1:
  409. return ( RED+"You may only rest once every "+IntToString(HOURS_BETWEEN_RESTS)+" game hours. "
  410. +PINK+"Try again in approximately " +YELLOW+ IntToString(time)+" real minutes."
  411. );
  412. break;
  413. // test: cold (stops to build or use a campfire)
  414. case 2:
  415. return ( RED+"You are cold."
  416. );
  417. break;
  418. case 5:
  419. return ( RED+"You are unable to rest while holding your breath."
  420. );
  421. break;
  422. }
  423.  
  424. return (RED+"You are unable to rest.");
  425. }
  426.  
  427. void ResterBeginsRest()
  428. {
  429. // CONFIGURE for start of a successful rest
  430. // this is a good place to do vfx changes like black outs etc...
  431.  
  432. }
  433.  
  434. void ResterFailsToRest()
  435. {
  436. // CONFIGURE for rest cancelation events (ie. occurs when you postpone rest)
  437.  
  438. }
  439.  
  440. void ResterFinishesRest()
  441. {
  442. object oPC = OBJECT_SELF;
  443.  
  444. // CONFIGURE for successful completion of rest
  445. // this is a good place to track state on the player related to rest
  446. if(MODULE_DEBUG_MODE)
  447. SendMessageToPC(OBJECT_SELF, "REST: ResterFinishesRest()");
  448.  
  449. // Sets up time for next rest to check against in "GetIsTimeToRest"
  450. // assumes time between rests is calculated in game minutes
  451.  
  452. if(!GetRestUnrestricted())
  453. SetLocalInt(OBJECT_SELF, NEXT_REST_TIME, GetTimeCumulative()+(HOURS_BETWEEN_RESTS*60) );
  454.  
  455. // VFX like horns, necklaces, quivers, glowing eyes etc....
  456. DeleteLocalInt(oPC, "vfx_do_op");
  457. ExecuteScript("_vfx_do_op", oPC);
  458.  
  459. // THE MAGUS' INNOCUOUS FAMILIARS
  460. SetLocalInt(oPC, "pets_tmp_op", 1);
  461. ExecuteScript("pets_do_op", oPC);
  462.  
  463. // update PC persistence
  464. Data_SavePC(OBJECT_SELF, TRUE);
  465. }
  466.  
  467. int ResterConsumes(object oConsume)
  468. {
  469. // most items will need to be explicitly destroyed which is why bDestroy is set to TRUE.
  470. // for items which will destroy themselves, set bDestroy to FALSE in their section below
  471. int bDestroy = TRUE;
  472.  
  473. // Configure what each item does when consumed
  474. // (eg. you may want certain items to "activate" their special powers)
  475.  
  476. int nType = GetBaseItemType(oConsume);
  477. // Eat Food
  478. if(GetIsFood(oConsume))
  479. {
  480. CreatureEatsFood(oConsume);
  481. bDestroy = FALSE;
  482. }
  483. return bDestroy;
  484. }
  485.  
  486. void ResterPrepares(int nScript)
  487. {
  488. // Configure each code block to suit your rest system
  489. // these are typicaly actions which need to be completed prior to resting (eg. building a campfire in a cold environment)
  490.  
  491. // script 1 -- REST_ACTION_MAKE_CAMPFIRE ---
  492. if(nScript==REST_ACTION_MAKE_CAMPFIRE)
  493. {
  494. // THE MAGUS' CAMP SYSTEM
  495. CamperCreatesCampsite(GetLocation(OBJECT_SELF), GetLocalObject(OBJECT_SELF,CAMP_FIREWOOD));
  496. }
  497. // script 2 -- REST_ACTION_LIGHT_CAMPFIRE ---
  498. else if(nScript==REST_ACTION_LIGHT_CAMPFIRE)
  499. {
  500. // THE MAGUS' CAMP SYSTEM
  501. CamperUsesCampfire();
  502. }
  503. // script 3 -- write your own ... ---
  504. else if(nScript==3)
  505. {
  506.  
  507. }
  508. // script x -- there can be any number of these preparation scripts ---
  509. }
  510.  
  511. int ResterGetFatigue(object oRester=OBJECT_SELF)
  512. {
  513. return GetSkinInt(oRester, REST_FATIGUE);
  514. }
  515.  
  516. void ResterSetFatigue(int nFatigue, object oRester=OBJECT_SELF)
  517. {
  518. SetSkinInt(oRester, REST_FATIGUE, nFatigue);
  519. }
  520.  
  521. int ResterMaxSpellLevelRecovered()
  522. {
  523. // maximum spell level to allow the PC to recover
  524. int nMaxSpellLevel = 9;
  525.  
  526. // fatigue = # of consecutive uncomfortable rests
  527. int nFatigue = ResterGetFatigue();
  528.  
  529. // max spell level is reduced by 1 for every point of fatigue
  530. nMaxSpellLevel -= nFatigue;
  531. // always allow PCs to memorize spell levels 0-2
  532. if(nMaxSpellLevel<2)
  533. nMaxSpellLevel = 2;
  534.  
  535. return nMaxSpellLevel;
  536. }
  537.  
  538. int ResterDamageLimitsHPRecovery()
  539. {
  540. // some calculations to help with your own determinations
  541. int nMaxHealed = GetMaxHitPoints()-GetLocalInt(OBJECT_SELF, REST_HP); // determine how much they are healing by resting
  542.  
  543. float fPercentageHealed = 1.0/(1+ResterGetFatigue()); // calculate the most you want the player to heal
  544. float fPercentageDamage = 1.0 - fPercentageHealed; // calculate the percentage of damage as an inverse of healing limit
  545.  
  546. int nDamage = FloatToInt( nMaxHealed * fPercentageDamage );
  547.  
  548. // Insurance: lets not kill them
  549. int nCurrent = GetCurrentHitPoints();
  550. if(nDamage>=nCurrent)
  551. nDamage = nCurrent-1;
  552.  
  553. return nDamage;
  554. }
  555.  
  556. // ........ Individual Rest Tests --> used by ResterRequirements()
  557. // you may modify these, add your own, or even delete these if you won't be using them
  558.  
  559. int GetIsTimeToRest(object oPC=OBJECT_SELF)
  560. {
  561. int bTired = FALSE;
  562.  
  563. // Adding a check here to make sure the value is sane.
  564. int nNext = GetLocalInt(oPC, NEXT_REST_TIME);
  565. int nCur = GetTimeCumulative();
  566. int nMaxNext = nCur +(HOURS_BETWEEN_RESTS*60);
  567. if (nNext > nMaxNext) {
  568. WriteTimestampedLogEntry("Rest - fixing next rest " + IntToString(nNext)
  569. + " time now = " + IntToString(nCur) + " for " + GetName(oPC));
  570. nNext = nMaxNext;
  571. SetLocalInt(oPC, NEXT_REST_TIME, nNext);
  572. }
  573.  
  574. if(nNext <= nCur)
  575. bTired = TRUE;
  576.  
  577. return bTired;
  578. }
  579.  
  580. int GetIsCold(object oPC=OBJECT_SELF)
  581. {
  582. int nExposed;
  583.  
  584. object oArea = GetArea(oPC);
  585.  
  586. int wet = ( GetLocalString(oPC,"UNDERWATER_ID")!=""
  587. || GetLocalString(oPC,"SWAMP_ID")!=""
  588. || GetWeather(oArea)==WEATHER_RAIN
  589. );
  590.  
  591. // COLD AREAS
  592. if( GetLocalInt(oArea, AREA_COLD) // area flagged as cold?
  593. || GetWeather(oArea)==WEATHER_SNOW // snowing in area?
  594. || (GetIsNight() && !GetIsAreaInterior(oArea)) // outside at night?
  595. || (wet && !CreatureGetIsAquatic(oPC)) // non-aquatic who is wet
  596. )
  597. {
  598. nExposed = TRUE;
  599.  
  600. // MAGUS CAMP SYSTEM
  601. // determine whether there is a lit campfire nearby
  602. int nCampState = GetIsNearCamp();
  603. if(nCampState==2)
  604. {
  605. nExposed = FALSE;
  606. }
  607. // Search for Protection from cold
  608. // no lit campfire nearby so look for another way to stay warm...
  609. else
  610. {
  611. // determine whether character has protection from cold
  612. // iterate through all equipped items for cold immunity or resistance properties
  613. int nSlot;
  614. object oItem = GetItemInSlot(nSlot,oPC);
  615. while(nSlot<=17 && nExposed)
  616. {
  617. if(oItem!=OBJECT_INVALID)
  618. {
  619. // a check for cold weather clothing
  620. /*
  621. if( nSlot==INVENTORY_SLOT_CHEST )
  622. {
  623. // check for a warm coat
  624. int nRobe = GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_ROBE);
  625. if(nRobe==121) // ROBE_PARKA
  626. {
  627. nExposed = FALSE;
  628. break;
  629. }
  630. }
  631. else if( nSlot==INVENTORY_SLOT_CLOAK )
  632. {
  633.  
  634. }
  635. */
  636.  
  637. // look for props : resistance or immunity to cold
  638. itemproperty ip = GetFirstItemProperty(oItem);
  639. while(GetIsItemPropertyValid(ip))
  640. {
  641. int nType = GetItemPropertyType(ip);
  642. if( ( nType == ITEM_PROPERTY_DAMAGE_RESISTANCE
  643. || nType == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE
  644. )
  645. && GetItemPropertySubType(ip) == IP_CONST_DAMAGETYPE_COLD
  646. )
  647. {
  648. nExposed = FALSE;
  649. break;
  650. }
  651.  
  652. ip = GetNextItemProperty(oItem);
  653. }
  654. }
  655. nSlot++;
  656. oItem = GetItemInSlot(nSlot,oPC);
  657. }
  658. }
  659. // end Search for Protection from cold
  660.  
  661. }
  662. // end COLD AREAS
  663.  
  664. return nExposed;
  665. }
  666.  
  667. int GetNeedsBedToRestComfortably(object oPC=OBJECT_SELF)
  668. {
  669. object oArea = GetArea(oPC);
  670.  
  671. // underwater or in a swamp
  672. if( GetLocalString(oPC,"UNDERWATER_ID")!=""
  673. || GetLocalString(oPC,"SWAMP_ID")!=""
  674. )
  675. {
  676. if(CreatureGetIsAquatic(oPC))
  677. return FALSE;
  678. else
  679. return TRUE;
  680. }
  681.  
  682. // wild characters can avoid beds in natural areas
  683. if( GetIsAreaNatural(oArea)
  684. &&( GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC)
  685. || GetLevelByClass(CLASS_TYPE_DRUID, oPC)
  686. || GetLevelByClass(CLASS_TYPE_RANGER, oPC)
  687. )
  688. // all wildlings can sleep outside
  689. // and dwarves and gnomes are also comfortable underground
  690. &&( !GetIsAreaInterior(oArea)
  691. ||( !GetIsAreaAboveGround(oArea)
  692. &&( GetRacialType(oPC)==RACIAL_TYPE_DWARF
  693. || GetRacialType(oPC)==RACIAL_TYPE_GNOME
  694. )
  695. )
  696. )
  697. )
  698. return FALSE;
  699.  
  700. return TRUE;
  701. }
  702.  
  703. // ........ You may have already defined these functions ........
  704.  
  705. int GetHasBed(object oPC=OBJECT_SELF)
  706. {
  707. int bHas = FALSE;
  708.  
  709. if( GetItemPossessedBy(oPC,TAG_BEDROLL)!=OBJECT_INVALID )
  710. bHas = TRUE;
  711.  
  712. return bHas;
  713. }
  714.  
  715.  
  716. // ============== NOT CONFIGURABLE =======================================
  717.  
  718. // REST SUB-EVENTS ............................
  719.  
  720. void RestStarted()
  721. {
  722. RestGarbageCollection();
  723.  
  724. // In an area with unrestricted resting?
  725. if(GetRestUnrestricted())
  726. {
  727. return;
  728. }
  729. // check resting rules
  730. else
  731. {
  732. int nResult = TestRestRequirements();
  733.  
  734. // Rest cancelled
  735. if(nResult & REST_POSTPONE)
  736. {
  737. ClearAllActions();
  738. // explain why the rest action is cancelled
  739. RestFeedback(FALSE);
  740. }
  741. // Rest proceeds
  742. else
  743. {
  744. // customize rest start (successful rest)
  745. // good place for black out VFX and the like
  746. ResterBeginsRest();
  747.  
  748. // track HP at start of rest
  749. SetLocalInt(OBJECT_SELF, REST_HP, GetCurrentHitPoints());
  750.  
  751. // consume items required for rest
  752. if(nResult & REST_CONSUME)
  753. RestConsumeItems();
  754.  
  755. if( nResult & REST_UNCOMFORTABLE )
  756. RestComfortable(FALSE);
  757. else
  758. RestComfortable(TRUE);
  759.  
  760. // Was the rest not comfortable enough to replenish spells?
  761. if(nResult & REST_LIMIT_SPELLS)
  762. RestLimitSpells();
  763.  
  764. // describe rest
  765. RestFeedback();
  766. }
  767. }
  768. }
  769.  
  770. void RestCanceled()
  771. {
  772. int nResult = GetLocalInt(OBJECT_SELF, REST_TEST_RESULTS);
  773. // fill action queue with preparatory action
  774. if(nResult & REST_PREPARE)
  775. RestPreparation();
  776.  
  777. // custom cancellation
  778. ResterFailsToRest();
  779.  
  780. // not a good place for garbage collection
  781. }
  782.  
  783. void RestFinished()
  784. {
  785. int nResult = GetLocalInt(OBJECT_SELF, REST_TEST_RESULTS);
  786. if(nResult & REST_LIMIT_HP)
  787. RestLimitHP();
  788.  
  789. // customize rest completion
  790. // good place to track data related to resting
  791. ResterFinishesRest();
  792.  
  793. RestGarbageCollection();
  794. }
  795.  
  796.  
  797. // REST RULE HANDLING .........................
  798.  
  799. int GetRestUnrestricted(object oRester=OBJECT_SELF)
  800. {
  801. object oArea = GetArea(oRester);
  802.  
  803. // assumption is that rest is restricted unless REST_UNRESTRICTED is specified
  804. // when determining whether rest restrictions are active in a particular circumstance
  805. // order of priority is player, area, module
  806.  
  807. if( GetLocalInt(oRester, REST_UNRESTRICTED) )
  808. return TRUE;
  809. else if( GetLocalInt(oRester, REST_RESTRICTED) )
  810. return FALSE;
  811. else if( GetLocalInt(oArea, REST_UNRESTRICTED) )
  812. return TRUE;
  813. else if( GetLocalInt(oArea, REST_RESTRICTED) )
  814. return FALSE;
  815. // else if( GetLocalInt(GetModule(), REST_RESTRICTED) )
  816. // return FALSE;
  817. else if( GetLocalInt(GetModule(), REST_UNRESTRICTED) )
  818. return TRUE;
  819. else
  820. return FALSE;
  821. }
  822.  
  823. int TestRestRequirements()
  824. {
  825. int nTestResults;
  826.  
  827. int nTest = 1;
  828. while(nTest<=LAST_REST_TEST && !(nTestResults & REST_POSTPONE) )
  829. {
  830. nTestResults |= ResterRequirements(nTest);
  831. nTest++;
  832. }
  833.  
  834. SetLocalInt(OBJECT_SELF, REST_TEST_RESULTS, nTestResults);
  835. return nTestResults;
  836. }
  837.  
  838. // REST RESULTS ..............................
  839.  
  840. void RestConsumeItems()
  841. {
  842. int nCount = GetLocalInt(OBJECT_SELF, REST_CONSUME_COUNT);
  843. int nIt = 1;
  844. DeleteLocalInt(OBJECT_SELF, REST_CONSUME_COUNT);
  845.  
  846. object oConsume;
  847. string sConsumableLabel;
  848. for(nIt;nIt<=nCount;nIt++)
  849. {
  850. sConsumableLabel = REST_CONSUME_+IntToString(nIt);
  851. oConsume = GetLocalObject(OBJECT_SELF, sConsumableLabel);
  852. DeleteLocalObject(OBJECT_SELF, sConsumableLabel);
  853. if(ResterConsumes(oConsume))
  854. // destroy the object
  855. DestroyObject(oConsume, 0.1);
  856. }
  857. }
  858.  
  859. void RestPreparation()
  860. {
  861. int nCount = GetLocalInt(OBJECT_SELF, REST_PREPARATION_COUNT);
  862. DeleteLocalInt(OBJECT_SELF, REST_PREPARATION_COUNT);
  863. string sPreparation; int nAction;
  864. int nIt = 1;
  865. for(nIt;nIt<=nCount;nIt++)
  866. {
  867. sPreparation = REST_PREPARATION_+IntToString(nIt);
  868. nAction = GetLocalInt(OBJECT_SELF, sPreparation);
  869. ActionDoCommand( ResterPrepares(nAction) );
  870. DeleteLocalInt(OBJECT_SELF, sPreparation);
  871. }
  872. }
  873.  
  874. void RestComfortable(int bSuccess=TRUE)
  875. {
  876. int nFatigue = ResterGetFatigue();
  877. if(bSuccess)
  878. nFatigue = 0;
  879. else
  880. nFatigue++;
  881.  
  882. ResterSetFatigue(nFatigue);
  883. }
  884.  
  885. void RestLimitSpells()
  886. {
  887. int nMaxAbility = 10+ResterMaxSpellLevelRecovered();
  888. float fDuration = 12.0 + (GetHitDice(OBJECT_SELF)*0.5);
  889.  
  890. // Intelligence Damage
  891. if(REST_SPELL_LIMIT_INT && !GetLocalInt(OBJECT_SELF,REST_NO_SPELL_LIMIT_INT))
  892. {
  893. int nIntDamage = GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE, FALSE) - nMaxAbility;
  894. if(nIntDamage>REST_MAX_DAMAGE_INT)nIntDamage=REST_MAX_DAMAGE_INT;
  895. else if(nIntDamage<REST_MIN_DAMAGE_INT)nIntDamage=REST_MIN_DAMAGE_INT;
  896. effect eFatigue1 = SupernaturalEffect( EffectAbilityDecrease(ABILITY_INTELLIGENCE, nIntDamage) );
  897. ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFatigue1, OBJECT_SELF, fDuration);
  898. }
  899.  
  900. // Wisdom Damage
  901. if(REST_SPELL_LIMIT_WIS && !GetLocalInt(OBJECT_SELF,REST_NO_SPELL_LIMIT_WIS))
  902. {
  903. int nWisDamage = GetAbilityScore(OBJECT_SELF, ABILITY_WISDOM, FALSE) - nMaxAbility;
  904. if(nWisDamage>REST_MAX_DAMAGE_WIS)nWisDamage=REST_MAX_DAMAGE_WIS;
  905. else if(nWisDamage<REST_MIN_DAMAGE_WIS)nWisDamage=REST_MIN_DAMAGE_WIS;
  906. effect eFatigue2 = SupernaturalEffect( EffectAbilityDecrease(ABILITY_WISDOM, nWisDamage) );
  907. ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFatigue2, OBJECT_SELF, fDuration);
  908. }
  909.  
  910. // Charisma Damage
  911. if(REST_SPELL_LIMIT_CHA && !GetLocalInt(OBJECT_SELF,REST_NO_SPELL_LIMIT_CHA))
  912. {
  913. int nChaDamage = GetAbilityScore(OBJECT_SELF, ABILITY_CHARISMA, FALSE) - nMaxAbility;
  914. if(nChaDamage>REST_MAX_DAMAGE_CHA)nChaDamage=REST_MAX_DAMAGE_CHA;
  915. else if(nChaDamage<REST_MIN_DAMAGE_CHA)nChaDamage=REST_MIN_DAMAGE_CHA;
  916. effect eFatigue3 = SupernaturalEffect( EffectAbilityDecrease(ABILITY_CHARISMA, nChaDamage) );
  917. ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFatigue3, OBJECT_SELF, fDuration);
  918. }
  919. }
  920.  
  921. void RestLimitHP()
  922. {
  923. int nDamage = ResterDamageLimitsHPRecovery();
  924.  
  925. if (nDamage > 0) {
  926. SetLocalInt(OBJECT_SELF, "nwnx_tmp_op", 4);
  927. SetLocalInt(OBJECT_SELF, "nwnx_tmp_val", GetCurrentHitPoints(OBJECT_SELF) - nDamage);
  928. ExecuteScript("nwnx_do_op", OBJECT_SELF);
  929. }
  930. }
  931.  
  932. // REST SYSTEM UTILITIES .........................
  933.  
  934. void RestFeedback(int nRestSuccess=TRUE)
  935. {
  936. if(!nRestSuccess)
  937. {
  938. FloatingTextStringOnCreature( ResterFailureText(GetLocalInt(OBJECT_SELF,CAUSE_OF_REST_FAILURE)),
  939. OBJECT_SELF,
  940. FALSE
  941. );
  942. }
  943. else
  944. {
  945. string sDescription = GetLocalString(OBJECT_SELF,DESCRIBE_REST);
  946. if(sDescription!="")
  947. SendMessageToPC( OBJECT_SELF, sDescription );
  948. }
  949. }
  950.  
  951. void RestGarbageCollection()
  952. {
  953. DeleteLocalInt(OBJECT_SELF, REST_TEST_RESULTS);
  954. DeleteLocalInt(OBJECT_SELF, REST_HP);
  955. DeleteLocalInt(OBJECT_SELF, CAUSE_OF_REST_FAILURE);
  956. DeleteLocalString(OBJECT_SELF,DESCRIBE_REST);
  957. DeleteLocalInt(OBJECT_SELF, REST_CONSUME_COUNT);
  958. DeleteLocalInt(OBJECT_SELF, REST_PREPARATION_COUNT);
  959. DeleteLocalInt(OBJECT_SELF,REST_NO_SPELL_LIMIT_INT);
  960. DeleteLocalInt(OBJECT_SELF,REST_NO_SPELL_LIMIT_WIS);
  961. DeleteLocalInt(OBJECT_SELF,REST_NO_SPELL_LIMIT_CHA);
  962. }
  963.  
  964. void ResterAddConsumable(object oConsumable)
  965. {
  966. int nCount = GetLocalInt(OBJECT_SELF, "CONSUMABLE_COUNT")+1;
  967. SetLocalInt(OBJECT_SELF, "CONSUMABLE_COUNT", nCount);
  968. SetLocalObject(OBJECT_SELF, "CONSUMABLE_"+IntToString(nCount), oConsumable);
  969. }
  970.  
  971. void ResterAddPreparatoryAction(int nActionScript)
  972. {
  973. int nCount = GetLocalInt(OBJECT_SELF, REST_PREPARATION_COUNT)+1;
  974. SetLocalInt(OBJECT_SELF, REST_PREPARATION_COUNT, nCount);
  975. SetLocalInt(OBJECT_SELF, REST_PREPARATION_+IntToString(nCount), nActionScript);
  976. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement