Advertisement
TheKeeper81

Untitled

Dec 29th, 2021
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 54.75 KB | None | 0 0
  1. // Myriad_Lite_To_D6_Module_Character_Sheet.lsl
  2. // This script was adapted to the Open D6 System by KeeperS Karu (Keeper S. Karu).
  3. // The adapted script uses the dual-license established by Allen Kerensky.
  4. //
  5. // The Open D6 System was developed by West End Games.
  6. // The Open D6 System is licensed under:
  7. // OPEN GAME LICENSE Version 1.0a
  8. // http://www.opengamingfoundation.org/ogl.html
  9. //
  10. // Myriad_Lite_Module_Character_Sheet-v0.0.6-20120827.lsl
  11. // Copyright (c) 2012 by Allen Kerensky (OSG/SL) All Rights Reserved.
  12. // This work is dual-licensed under
  13. // Creative Commons Attribution (CC BY) 3.0 Unported
  14. // http://creativecommons.org/licenses/by/3.0/
  15. // - or -
  16. // Modified BSD License (3-clause)
  17. // Redistribution and use in source and binary forms, with or without
  18. // modification, are permitted provided that the following conditions are met:
  19. // * Redistributions of source code must retain the above copyright notice,
  20. // this list of conditions and the following disclaimer.
  21. // * Redistributions in binary form must reproduce the above copyright notice,
  22. // this list of conditions and the following disclaimer in the documentation
  23. // and/or other materials provided with the distribution.
  24. // * Neither the name of Myriad Lite nor the names of its contributors may be
  25. // used to endorse or promote products derived from this software without
  26. // specific prior written permission.
  27. //
  28. // THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
  29. // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
  31. // NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  32. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  33. // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  34. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  35. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  37. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. //
  39. // The Myriad RPG System was designed, written, and illustrated by Ashok Desai
  40. // Myriad RPG System licensed under:
  41. // Creative Commons Attribution (CC BY) 2.0 UK: England and Wales
  42. // http://creativecommons.org/licenses/by/2.0/uk/
  43.  
  44. //================
  45. // VERSION CONTROL
  46. //================
  47. string VERSION = "0.0.6"; // Allen Kerensky's script version
  48. string VERSIONDATE = "20120827"; // Allen Kerensky's script yyyymmdd
  49. string D6VERSION = "1"; //Keeper's version of the D6-adapted script
  50. string D6VERSIONDATE = "20130521"; // Keeper's D6-adapted script yyyymmdd
  51.  
  52. //========================
  53. // CHARACTER SHEET STORAGE
  54. //========================
  55.  
  56. // Cardversion
  57. string CARDVERSION = "0.0.5"; // what card format version do we expect
  58. string D6CARDVERSION = "1.0.0"; // Myriad Lite to D6 card format version to expect
  59.  
  60. // Special Points
  61. list CHARACTERPOINTS = []; // character points [integer TotalCharPoints, integer StartCharacterPoints]
  62. list FATEPOINTS = []; // fate points [integer TotalFatePoints, integer StartFatePoints]
  63.  
  64. // Character Personal Info
  65. string PLAYERNAME = ""; // player's avatar name
  66. string CHARACTERNAME = ""; // character name
  67. string CHARACTERALIASES = ""; // character aliases
  68. string OCCUPATION = ""; // occupation template
  69. string SPECIES = ""; // species template used for character
  70. string GENDER = ""; // Your character's gender
  71. string AGE = ""; // Your character's age
  72. string HEIGHT = ""; // Your character's height
  73. string WEIGHT = ""; // Your character's weight
  74. string PHYSICALDESCRIPTION = ""; // Your character's additional physical description
  75. string PERSONALITY = ""; // Your character's personality
  76. string OBJECTIVES = ""; // Your character's objectives
  77. string NATIVELANGUAGE = ""; // Your character's native languages
  78. string OTHERINFORMATION = ""; // otherinformation template
  79.  
  80. // Character Attributes
  81. list ATTRIBUTES = []; // attributes [string AttributeName, integer TotalATTRank, integer BaseATTRank, integer StartATTRank]
  82. list SKILLS = []; // skills [ string SkillName, integer TotalSkillRank, integer BaseSkillRank, integer StartSkillRank ]
  83. list SKILL_SPECIALIZATIONS = []; // specialization [ string SpecName,integer TotalSpecRank, integer BaseSpecRank, integer StartSpecRank] ; SpecName = Specialization/MainSkill
  84. list EXTRANORMAL_PSIONICS = []; // psionics [ string PsiSkillName, integer TotalPsiRank, integer BasePsiRank, integer StartPsiRank]
  85. list EXTRANORMAL_MAGIC = []; // magic [ string MagicSkillName, integer TotalMagicRank, integer BaseMagicRank, integer StartMagicRank]
  86. list EXTRANORMAL_POWERS = []; // powers [ string PowerSkillName, integer TotalPowerRank, integer BasePowerRank, integer StartPowerRank]
  87. list ADVAN = []; // advantages [ string ADVANName, integer TotalADVANRank, integer StartingADVANRank ]
  88. list DISAD = []; // disad [ string DISADName, integer TotalDISADRank, integer StartingDISADRank ]
  89. list SPECIAL_ABILITIES = []; // special ability [string SpecName, integer BaseRank, integer StartRank] TotalRank not needed as there are no modifiers to character options
  90. list ENHANCEMENTS = []; // enhancement [string EnhanceName, integer BaseRank, integer StartRank]
  91. list LIMITATIONS = []; // limits [string LimitName, integer BaseRank, integer StartRank]
  92.  
  93. // Derived Statistics
  94. list BODYPOINTS = []; // bodypoints [integer TotalBodypoints, StartingBodypoints]
  95. list CURRENTBODYPOINTS = []; // currentbodypoints [integer tempbody, integer actualbody]
  96. list MOVEMENT = []; // movement [integer TotalModifiedMovement, BaseMovement]
  97.  
  98. // Personal Resources
  99. list FUNDS = []; // FUNDS [integer TotalFunds, integer StartingFunds]
  100. list EQUIPMENT = []; // Equipment [ string ItemName, integer NumberCarried, integer ItemDieCode ]
  101.  
  102. // Level-Based Progress
  103. integer XP = 0; // 0-2320
  104. integer XPLEVEL = 1; // 1-30
  105. integer ATTPOOL = 0; // attributes die pool
  106. integer SKILLPOOL = 0; // skill die pool
  107. integer FUNDSPOOL = 0; // resource die pool
  108.  
  109. // Gradual Progress
  110. integer XPLEFT = 0; // unspent XP
  111.  
  112. // Random Progress
  113. integer SKILL_INCREASES; // how many times have we increased skills, when 5 skills, get new skill
  114. list SKILLS_INCREASED = []; // [ SkillName, TimesFailed ] if TimesFailed = 5, increase skill and reset
  115. integer NEW_SKILLS; // number of new skills earned through RANDOM skill increases since last reset
  116. list ATTS_INCREASED = []; // [ AttName, Times Advanced ] if TimesAdvanced = 5, increase att and reset
  117.  
  118. //=================
  119. // MYRIAD CONSTANTS
  120. //=================
  121. integer MINXP = 0; // min experience points
  122. integer MAXXP = 2320; // max experience points
  123. integer MIN_XPLEVEL = 1; // min XP level
  124. integer MAX_XPLEVEL = 30; // max XP level
  125. list XP_BY_LEVEL = [ 0,0,10,25,45,70,100,135,175,220,270,325,385,450,520,595,675,760,850,945,1045,1150,1260,1375,1495,1620,1750,1885,2025,2170,2320 ];
  126. integer MINATT = 1; // min value for attributes
  127. integer MAXATT = 6; // max human value for an attribute
  128. integer MAXSTARTATT = 6; // max value for an attribute at character creation
  129. integer MINBODYPOINTS = 21; // min value for bodypoints at character creation
  130. integer MAXBODYPOINTS = 75; // max value for bodypoints at character creation
  131. integer MINADVAN = 1; // min value for advan rank
  132. integer MAXADVAN = 100; // max value for advan rank at character creation
  133. integer MINDISAD = 1; // min value for disad rank
  134. integer MAXDISAD = 100; // max value for disad rank at character creation
  135. integer MINSKILL = 1; // min value for skill rank
  136. integer MAXSKILL = 3; // max value for skill rank at character creation
  137. integer MINSPEC = 1; // min value for specialization rank
  138. integer MAXSPEC = 2; // max value for specialization rank at character creation
  139. integer MINEXTRASKILL = 1; // min value for extranormal skills
  140. integer MAXEXTRASKILL = 100; // max value for extranormal skills
  141. integer MINEQUIPPED = 1; // min number of items player can carry
  142. integer MAXEQUIPPED = 100; // max number of items player can carry TODO: what about bullets?
  143. //integer MINDAMAGE = 1; // min attack dice for weapon
  144. //integer MAXDAMAGE = 5; // max attack dice for weapon
  145.  
  146. //=====================================
  147. // MODULE TO MODULE MESSAGING CONSTANTS
  148. //=====================================
  149. //integer MODULE_HUD = -1;
  150. integer MODULE_CHARSHEET = -2;
  151. //integer MODULE_ARMOR = -3;
  152. //integer MODULE_BAM = -4;
  153. //integer MODULE_RUMORS = -5;
  154. // integer MODULE_CLOSE = -6;
  155. // integer MODULE_RANGED = -7;
  156. // integer MODULE_RESILIENCE = -8;
  157. // integer MODULE_PROGRESS = -9;
  158. // integer MODULE_WELL = -10;
  159. // integer MODULE_METER = -11;
  160. integer LM_SENDTOATTACHMENT = 0x80000000;
  161.  
  162. //=========
  163. // Runtimes
  164. //=========
  165. integer FLAG_DEBUG;
  166. key PLAYERID;
  167. string DIV="|";
  168. string ESTATE; // what estate does this region belong to - loaded from region server
  169. string PROGRESSION; // Progression Method: LEVEL, GRADUAL, or RANDOM
  170. integer CHANMYRIAD = -999;
  171. integer CHANOBJECT;
  172. integer HANDOBJECT;
  173.  
  174. //==============
  175. // Menu Handling
  176. //==============
  177. integer MENU_TIMER;
  178. integer MENU_TIMEOUT = 30;
  179. integer MENU_CHANNEL;
  180. integer MENU_HANDLE;
  181. list MENU;
  182.  
  183. //==================
  184. // NOTECARD HANDLING
  185. //==================
  186. list CHARACTERS;
  187. string CARD;
  188. string DEFAULT = "Myriad_Lite_To_D6_Character_Sheet_v1.txt"; // character sheet notecard
  189. integer LINE = 0; // reading line number
  190. key QUERY = NULL_KEY; // track notecard queries
  191.  
  192. //=======================
  193. // USER-DEFINED FUNCTIONS
  194. //=======================
  195.  
  196. // ADD_XP - Add a point of XP
  197. ADD_XP(key granterid)
  198. {
  199. key objectowner = llList2Key(llGetObjectDetails(granterid,[OBJECT_OWNER]),0);
  200. key regionowner = llList2Key(llGetParcelDetails(<0,0,0>,[PARCEL_DETAILS_OWNER]),0);
  201. if ( objectowner!= regionowner )
  202. {
  203. ERROR("ADD_XP called by object or player who is not region owner. ["+(string)objectowner+"]["+(string)regionowner+"]");
  204. return;
  205. }
  206. DEBUG("Progression="+PROGRESSION+" XP="+(string)XP+" XPLEVEL="+(string)XPLEVEL);
  207. if ( PROGRESSION == "RANDOM" )
  208. {
  209. ERROR("Unable to add XP in region using Random Progression");
  210. return;
  211. }
  212. if ( XP < MAXXP )
  213. {
  214. XP++; // add one to total XP
  215. if ( PROGRESSION == "LEVEL-BASED" )
  216. {
  217. integer currentlevel = XPLEVEL;
  218. integer templevel = GET_LEVEL_BY_XP(XP);
  219. if ( templevel > currentlevel )
  220. {
  221. XPLEVEL = templevel;
  222. llOwnerSay("LEVEL UP! Congratulations, you are now XP Level "+(string)XPLEVEL);
  223. RPEVENT("LEVEL UP! Congratulations, "+llKey2Name(llGetOwner())+" is now XP Level "+(string)XPLEVEL);
  224. LEVELUP(XPLEVEL);
  225. }
  226. return;
  227. }
  228. if ( PROGRESSION == "GRADUAL" )
  229. {
  230. XPLEFT++; // add one to XP you can spend in gradual progress mode
  231. return;
  232. }
  233. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"XP_CHANGED|XP="+(string)XP,llGetOwner());
  234. DEBUG("Progression="+PROGRESSION+" XP="+(string)XP+" XPLEVEL="+(string)XPLEVEL);
  235. }
  236. else
  237. {
  238. ERROR("XP already maxed.");
  239. }
  240. }
  241.  
  242. CALCULATE_LEVEL_BY_XP()
  243. {
  244. integer i;
  245. for ( i=1; i < llGetListLength(XP_BY_LEVEL); i++ )
  246. {
  247. integer basexp = llList2Integer(XP_BY_LEVEL,i);
  248. if ( XP >= basexp )
  249. {
  250. SET_XPLEVEL(i);
  251. }
  252. }
  253. }
  254.  
  255. CHECK_D6CARDVERSION(string ncversion)
  256. {
  257. if ( ncversion!= D6CARDVERSION )
  258. {
  259. ERROR("Character sheet format "+ncversion+" found. Format version "+D6CARDVERSION+" expected. Please update character sheets to newer versions.");
  260. }
  261. }
  262.  
  263. DEBUG(string debugmsg)
  264. {
  265. if ( FLAG_DEBUG == TRUE ) // are we debugging?
  266. {
  267. llSay(DEBUG_CHANNEL,"("+llKey2Name(PLAYERID)+") MOD CHARSHEET DEBUG: "+debugmsg);
  268. }
  269. }
  270.  
  271. DEL_PROGRESS(key id)
  272. {
  273. key objectowner = llList2Key(llGetObjectDetails(id,[OBJECT_OWNER]),0);
  274. key regionowner = llList2Key(llGetParcelDetails(<0,0,0>,[PARCEL_DETAILS_OWNER]),0);
  275. if ( objectowner!= regionowner )
  276. {
  277. ERROR("DEL_PROGRESS called by object or player who is not region owner. ["+(string)objectowner+"]["+(string)regionowner+"]");
  278. return;
  279. }
  280. if ( PROGRESSION == "LEVEL-BASED" )
  281. {
  282. ATTPOOL = 0;
  283. SKILLPOOL = 0;
  284. FUNDSPOOL = 0;
  285. return;
  286. }
  287. if ( PROGRESSION == "GRADUAL" )
  288. {
  289. XPLEFT = 0;
  290. return;
  291. }
  292. if ( PROGRESSION == "RANDOM" )
  293. {
  294. SKILL_INCREASES = 0;
  295. NEW_SKILLS = 0;
  296. SKILLS_INCREASED = [];
  297. ATTS_INCREASED = [];
  298. return;
  299. }
  300. }
  301.  
  302. DUMP_SHEET(key id) // dump current character sheet
  303. {
  304. key objectowner = llList2Key(llGetObjectDetails(id,[OBJECT_OWNER]),0);
  305. key regionowner = llList2Key(llGetParcelDetails(<0,0,0>,[PARCEL_DETAILS_OWNER]),0);
  306. if ( objectowner!= regionowner )
  307. {
  308. ERROR("DUMP_SHEET called by object or player who is not region owner. ["+(string)objectowner+"]["+(string)regionowner+"]");
  309. return;
  310. }
  311. DEBUG("Dumping character sheet to "+llKey2Name(id)+" ("+(string)id+")");
  312. integer chan = (integer)("0x"+llGetSubString((string)id,0,6));
  313. string tempname = llGetObjectName();
  314. llSetObjectName("");
  315. llSay(chan,"D6VERSION|D6VERSION="+D6VERSION);
  316. llSay(chan,"CHARACTERNAME|CHARACTERNAME="+CHARACTERNAME);
  317. // Characteraliases
  318. llSay(chan,"CHARACTERALIASES|CHARACTERALIASES="+CHARACTERALIASES);
  319. // Occupations
  320. llSay(chan,"OCCUPATION|OCCUPATION="+OCCUPATION);
  321. // Species
  322. llSay(chan,"SPECIES|SPECIES="+SPECIES);
  323. // Gender
  324. llSay(chan,"GENDER|GENDER="+GENDER);
  325. // Age
  326. llSay(chan,"AGE|AGE="+AGE);
  327. // Height
  328. llSay(chan,"HEIGHT|HEIGHT="+HEIGHT);
  329. // Weight
  330. llSay(chan,"WEIGHT|WEIGHT="+WEIGHT);
  331. // Physicaldescription
  332. llSay(chan,"PHYSICALDESCRIPTION|PHYSICALDESCRIPTION="+PHYSICALDESCRIPTION);
  333. // Personality
  334. llSay(chan,"PERSONALITY|PERSONALITY="+PERSONALITY);
  335. // Objectives
  336. llSay(chan,"OBJECTIVES|OBJECTIVES="+OBJECTIVES);
  337. // Nativelanguage
  338. llSay(chan,"NATIVELANGUAGE|NATIVELANGUAGE="+NATIVELANGUAGE);
  339. // Otherinformation
  340. llSay(chan,"OTHERINFORMATION|OTHERINFORMATION="+OTHERINFORMATION);
  341. //llSay(chan,"XP="+(string)XP);
  342. //llSay(chan,"XPLEVEL="+(string)XPLEVEL);
  343. // Attributes
  344. integer numstats = llGetListLength(ATTRIBUTES);
  345. integer count;
  346. for ( count = 0; count < numstats; count += 4 )
  347. {
  348. string name = llList2String(ATTRIBUTES,count);
  349. integer totalrank = llList2Integer(ATTRIBUTES,count + 1);
  350. integer baserank = llList2Integer(ATTRIBUTES,count + 2);
  351. integer startrank = llList2Integer(ATTRIBUTES,count + 3);
  352. if ( totalrank > 0 ) llSay(chan,"ATTRIBUTE|"+name+"="+(string)totalrank+(string)baserank+(string)startrank);
  353. }
  354. // Skills
  355. numstats = llGetListLength(SKILLS);
  356. for ( count = 0; count < numstats; count += 4 )
  357. {
  358. string name = llList2String(SKILLS,count);
  359. integer totalrank = llList2Integer(SKILLS,count +1);
  360. integer baserank = llList2Integer(SKILLS,count +2);
  361. integer startrank = llList2Integer(SKILLS,count +3);
  362. if ( totalrank > 0 ) llSay(chan,"SKILL|"+name+"="+(string)totalrank+(string)baserank+(string)startrank);
  363. }
  364. // Skill_Specializations
  365. numstats = llGetListLength(SKILL_SPECIALIZATIONS);
  366. for ( count = 0; count < numstats; count += 4 )
  367. {
  368. string name = llList2String(SKILL_SPECIALIZATIONS,count);
  369. integer totalrank = llList2Integer(SKILL_SPECIALIZATIONS,count +1);
  370. integer baserank = llList2Integer(SKILL_SPECIALIZATIONS,count +2);
  371. integer startrank = llList2Integer(SKILL_SPECIALIZATIONS,count +3);
  372. if ( totalrank > 0 ) llSay(chan,"SKILL_SPECIALIZATIONS|"+name+"="+(string)totalrank+(string)baserank+(string)startrank);
  373. }
  374. // Extranormal_Psionics
  375. numstats = llGetListLength(EXTRANORMAL_PSIONICS);
  376. for ( count = 0; count < numstats; count += 4 )
  377. {
  378. string name = llList2String(EXTRANORMAL_PSIONICS,count);
  379. integer totalrank = llList2Integer(EXTRANORMAL_PSIONICS,count +1);
  380. integer baserank = llList2Integer(EXTRANORMAL_PSIONICS,count +2);
  381. integer startrank = llList2Integer(EXTRANORMAL_PSIONICS,count +3);
  382. if ( totalrank > 0 ) llSay(chan,"EXTRANORMAL_PSIONICS|"+name+"="+(string)totalrank+(string)baserank+(string)startrank);
  383. }
  384. // Extranormal_Magic
  385. numstats = llGetListLength(EXTRANORMAL_MAGIC);
  386. for ( count = 0; count < numstats; count += 4 )
  387. {
  388. string name = llList2String(EXTRANORMAL_MAGIC,count);
  389. integer totalrank = llList2Integer(EXTRANORMAL_MAGIC,count +1);
  390. integer baserank = llList2Integer(EXTRANORMAL_MAGIC,count +2);
  391. integer startrank = llList2Integer(EXTRANORMAL_MAGIC,count +3);
  392. if ( totalrank > 0 ) llSay(chan,"EXTRANORMAL_MAGIC|"+name+"="+(string)totalrank+(string)baserank+(string)startrank);
  393. }
  394. // Extranormal_Powers
  395. numstats = llGetListLength(EXTRANORMAL_POWERS);
  396. for ( count = 0; count < numstats; count += 4 )
  397. {
  398. string name = llList2String(EXTRANORMAL_POWERS,count);
  399. integer totalrank = llList2Integer(EXTRANORMAL_POWERS,count +1);
  400. integer baserank = llList2Integer(EXTRANORMAL_POWERS,count +2);
  401. integer startrank = llList2Integer(EXTRANORMAL_POWERS,count +3);
  402. if ( totalrank > 0 ) llSay(chan,"EXTRANORMAL_POWERS|"+name+"="+(string)totalrank+(string)baserank+(string)startrank);
  403. }
  404. // Advantages
  405. numstats = llGetListLength(ADVAN);
  406. for ( count = 0; count < numstats; count +=3)
  407. {
  408. string name = llList2String(ADVAN,count);
  409. integer totalrank = llList2Integer(ADVAN,count +1);
  410. integer startrank = llList2Integer(ADVAN,count +2);
  411. if ( totalrank > 0 ) llSay(chan,"ADVAN|"+name+"="+(string)totalrank+(string)startrank);
  412. }
  413. // Disadvantages
  414. numstats = llGetListLength(DISAD);
  415. for ( count = 0; count < numstats; count +=3)
  416. {
  417. string name = llList2String(DISAD,count);
  418. integer totalrank = llList2Integer(DISAD,count +1);
  419. integer startrank = llList2Integer(DISAD,count +2);
  420. if ( totalrank > 0 ) llSay(chan,"DISAD|"+name+"="+(string)totalrank+(string)startrank);
  421. }
  422. // Special_Abilities
  423. numstats = llGetListLength(SPECIAL_ABILITIES);
  424. for ( count = 0; count < numstats; count +=3)
  425. {
  426. string name = llList2String(SPECIAL_ABILITIES,count);
  427. integer totalrank = llList2Integer(SPECIAL_ABILITIES,count +1);
  428. integer startrank = llList2Integer(SPECIAL_ABILITIES,count +2);
  429. if ( totalrank > 0 ) llSay(chan,"SPECIAL_ABILITIES|"+name+"="+(string)totalrank+(string)startrank);
  430. }
  431. // Enhancements
  432. numstats = llGetListLength(ENHANCEMENTS);
  433. for ( count = 0; count < numstats; count +=3)
  434. {
  435. string name = llList2String(ENHANCEMENTS,count);
  436. integer totalrank = llList2Integer(ENHANCEMENTS,count +1);
  437. integer startrank = llList2Integer(ENHANCEMENTS,count +2);
  438. if ( totalrank > 0 ) llSay(chan,"ENHANCEMENTS|"+name+"="+(string)totalrank+(string)startrank);
  439. }
  440. // Limitations
  441. numstats = llGetListLength(LIMITATIONS);
  442. for ( count = 0; count < numstats; count +=3)
  443. {
  444. string name = llList2String(LIMITATIONS,count);
  445. integer totalrank = llList2Integer(LIMITATIONS,count +1);
  446. integer startrank = llList2Integer(LIMITATIONS,count +2);
  447. if ( totalrank > 0 ) llSay(chan,"LIMITATIONS|"+name+"="+(string)totalrank+(string)startrank);
  448. }
  449. // Bodypoints
  450. string totalamount = llList2Integer(BODYPOINTS,0);
  451. integer startingamount = llList2Integer(BODYPOINTS,1);
  452. llSay(chan,"BODYPOINTS|="+(string)(totalamount)+(string)startingamount);
  453. // CurrentBodypoints
  454. string tempamount = llList2Integer(CURRENTBODYPOINTS,0);
  455. string actualamount = llList2Integer (CURRENTBODYPOINTS,1);
  456. llSay(chan,"CURRENTBODYPOINTS|="+(string)tempamount+(string)(actualamount));
  457. // Movement
  458. string totalmovement = llList2Integer(MOVEMENT,0);
  459. integer startingmovement = llList2Integer(MOVEMENT,1);
  460. llSay(chan,"MOVEMENT|="+(string)(totalmovement)+(string)startingmovement);
  461. // Character Points
  462. integer TotalPoints = llList2Integer(CHARACTERPOINTS,0);
  463. integer StartingPoints = llList2Integer(CHARACTERPOINTS,1);
  464. llSay(chan,"CHARACTERPOINTS|="+(string)TotalPoints+(string)StartingPoints);
  465. //Fatepoints
  466. integer TotalFatePoints = llList2Integer(FATEPOINTS,0);
  467. integer StartingFatePoints = llList2Integer(FATEPOINTS,1);
  468. llSay(chan,"FATEPOINTS|="+(string)TotalFatePoints+(string)StartingFatePoints);
  469. // Funds
  470. integer TotalFunds = llList2Integer(FUNDS,0);
  471. integer StartingFunds = llList2Integer(FUNDS,1);
  472. llSay(chan,"FUNDS|="+(string)TotalFunds+(string)StartingFunds);
  473. // Equipment
  474. numstats = llGetListLength(EQUIPMENT);
  475. for ( count = 0; count < numstats; count +=3)
  476. {
  477. string name = llList2String(EQUIPMENT,count);
  478. integer numcarried = llList2Integer(EQUIPMENT,count +1);
  479. integer diecode = llList2Integer(EQUIPMENT,count +2);
  480. if ( numcarried > 0 ) llSay(chan,"EQUIPMENT|"+name+"="+(string)numcarried+(string)diecode);
  481. }
  482. llSay(chan,"CHARACTER_LOADED");
  483. llSetObjectName(tempname);
  484. }
  485.  
  486. DUMP_PROGRESS(key id)
  487. { // id to dump progress back to
  488. key objectowner = llList2Key(llGetObjectDetails(id,[OBJECT_OWNER]),0);
  489. key regionowner = llList2Key(llGetParcelDetails(<0,0,0>,[PARCEL_DETAILS_OWNER]),0);
  490. if ( objectowner!= regionowner )
  491. {
  492. ERROR("DUMP_PROGRESS called by object or player who is not region owner. ["+(string)objectowner+"]["+(string)regionowner+"]");
  493. return;
  494. }
  495. integer chan = (integer)("0x"+llGetSubString((key)id,0,6));
  496. if ( PROGRESSION == "LEVEL-BASED" )
  497. {
  498. llSay(chan,"PROGRESS|XP="+(string)XP);
  499. llSay(chan,"PROGRESS|XPLEVEL="+(string)XPLEVEL);
  500. llSay(chan,"PROGRESS|ATTPOOL="+(string)ATTPOOL);
  501. llSay(chan,"PROGRESS|SKILLPOOL="+(string)SKILLPOOL);
  502. llSay(chan,"PROGRESS|FUNDSPOOL="+(string)FUNDSPOOL);
  503. return;
  504. }
  505. if ( PROGRESSION == "GRADUAL" )
  506. {
  507. llSay(chan,"PROGRESS|XP="+(string)XP);
  508. llSay(chan,"PROGRESS|XPLEFT="+(string)XPLEFT);
  509. return;
  510. }
  511. if ( PROGRESSION == "RANDOM" )
  512. {
  513. llSay(chan,"PROGRESS|SKILL_INCREASES="+(string)SKILL_INCREASES);
  514. llSay(chan,"PROGRESS|NEW_SKILLS="+(string)NEW_SKILLS);
  515. integer count = llGetListLength(SKILLS_INCREASED);
  516. integer i;
  517. for ( i=0; i< count; i++)
  518. {
  519. llSay(chan,"PROGRESS|SKILL="+llList2String(SKILLS_INCREASED,i)+"|TIMESFAILED="+llList2String(SKILLS_INCREASED,i + 1));
  520. }
  521. count = llGetListLength(ATTS_INCREASED);
  522. for ( i=0; i< count; i++)
  523. {
  524. llSay(chan,"PROGRESS|ATT="+llList2String(ATTS_INCREASED,i)+"|TIMESADVANCERD="+llList2String(ATTS_INCREASED,i + 1));
  525. }
  526. return;
  527. }
  528. }
  529.  
  530. ERROR(string errmsg)
  531. {
  532. llSay(DEBUG_CHANNEL,"("+llKey2Name(PLAYERID)+") MOD CHARSHEET ERROR: "+errmsg);
  533. }
  534.  
  535. FIND_NOTECARD()
  536. {
  537. CHARACTERS = [];
  538. MENU = ["Default"];
  539. //string regionname = llGetRegionName();
  540. integer count = llGetInventoryNumber(INVENTORY_NOTECARD);
  541. while (count--)
  542. {
  543. string currentcard = llGetInventoryName(INVENTORY_NOTECARD,count);
  544. list tokens = llParseString2List(currentcard,["@"],[]);
  545. string cardname = llList2String(tokens,0);
  546. string cardestate = llList2String(tokens,1);
  547. if ( cardname!= DEFAULT && cardestate == ESTATE )
  548. {
  549. CHARACTERS = [cardname,currentcard] + CHARACTERS;
  550. MENU = [cardname] + MENU;
  551. DEBUG("Found estate-specific character sheet "+cardname+"@"+cardestate);
  552. }
  553. }
  554. MENU_CHANNEL = (integer)llFrand(9999.0) * -1;
  555. MENU_HANDLE = llListen(MENU_CHANNEL,"",llGetOwner(),"");
  556. llDialog(llGetOwner(),"Choose your character",MENU,MENU_CHANNEL);
  557. MENU_TIMER = MENU_TIMEOUT;
  558. llSetTimerEvent(1.0);
  559. }
  560.  
  561. integer GET_ATT(string gattname, integer gtotattrank, integer gbaseattrank, integer gstartattrank) // gattname = get attribute name
  562. {
  563. integer pos = llListFindList(ATTRIBUTES,[gattname]);
  564. if ( pos >= 0 )
  565. {
  566. integer gtotattrank = llList2Integer(ATTRIBUTES,pos + 1);
  567. integer gbaseattrank = llList2Integer(ATTRIBUTES,pos + 2);
  568. integer gstartattrank = llList2Integer(ATTRIBUTES,pos +3);
  569. return;
  570. }
  571. return 0;
  572. }
  573.  
  574. integer GET_CURRENTBODYPOINTS(integer gcurbodytemp, integer gcurbodyactual)
  575. {
  576. integer gcurbodytemp = llList2Integer(CURRENTBODYPOINTS,0);
  577. integer gcurbodyactual = llList2Integer(CURRENTBODYPOINTS,1);
  578. return CURRENTBODYPOINTS;
  579. }
  580.  
  581. integer GET_LEVEL_BY_XP(integer amount)
  582. {
  583. integer count = 0;
  584. integer outlevel = 0;
  585. for (count = 0; count < MAX_XPLEVEL; count++ )
  586. {
  587. if ( amount > llList2Integer(XP_BY_LEVEL,count) ) outlevel = count;
  588. }
  589. DEBUG("GET_LEVEL_BY_XP("+(string)amount+") returning "+(string)outlevel);
  590. return outlevel;
  591. }
  592.  
  593. integer GET_BODYPOINTS(integer gtotmaxbody, integer gstartbody)
  594. {
  595. integer gtotalmaxbody = llList2Integer(BODYPOINTS,0);
  596. integer gstartmaxbody = llList2Integer(BODYPOINTS,1);
  597. return BODYPOINTS;
  598. }
  599.  
  600. GETVERSION()
  601. {
  602. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"VERSION_INFO"+DIV+"NAME="+llGetScriptName()+DIV+"D6VERSION="+D6VERSION+DIV+"D6VERSIONDATE="+D6VERSIONDATE,llGetOwner());
  603. }
  604.  
  605. integer GET_XP()
  606. {
  607. if ( XP >= MINXP && XP <= MAXXP)
  608. {
  609. // inform all other modules that might need to track XPLEVEL
  610. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"GET_XP|XP="+(string)XP,llGetOwner());
  611. return XP;
  612. } else
  613. {
  614. ERROR("GET_XP("+(string)XP+") AMOUNT OUT OF RANGE "+(string)MINXP+"-"+(string)MAXXP+"! RESETTING");
  615. }
  616. RESET();
  617. return 0;
  618. }
  619.  
  620. integer GET_XPLEVEL()
  621. {
  622. if ( XPLEVEL >= MIN_XPLEVEL && XPLEVEL <= MAX_XPLEVEL)
  623. {
  624. // inform all other modules that might need to track XPLEVEL
  625. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"GET_XPLEVEL|XPLEVEL="+(string)XPLEVEL,llGetOwner());
  626. return XPLEVEL;
  627. } else
  628. {
  629. ERROR("GET_XPLEVEL ["+(string)XPLEVEL+"] AMOUNT OUT OF RANGE "+(string)MIN_XPLEVEL+"-"+(string)MAX_XPLEVEL+"! RESETTING");
  630. }
  631. RESET();
  632. return 0;
  633. }
  634.  
  635. INCREASE_ATT(string iattname) // iattname = increase attribute name
  636. {
  637. integer pos = llListFindList(ATTRIBUTES,[iattname]);
  638. if ( pos >= 0 ) // found skill in list
  639. {
  640. integer totcurval = llList2Integer(ATTRIBUTES,pos +1);
  641. integer curval = llList2Integer(ATTRIBUTES,pos + 2);
  642. if ( curval < MAXATT )
  643. {
  644. ATTRIBUTES = llListReplaceList(ATTRIBUTES,[totcurval++,curval++],pos +1, pos +2);
  645. RPEVENT("increased their "+iattname+" attribute by one.");
  646. }
  647. } else
  648. {
  649. ERROR("Requested att increase for nonexistent att "+iattname);
  650. }
  651. }
  652.  
  653. INCREASE_SKILL(string isname) // isname = increase skill name
  654. {
  655. integer pos = llListFindList(SKILLS,[isname]);
  656. if ( pos >= 0 ) // found skill in list
  657. {
  658. integer totcurval = llList2Integer(SKILLS,pos +1);
  659. integer curval = llList2Integer(SKILLS,pos + 2);
  660. SKILLS = llListReplaceList(SKILLS,[totcurval++,curval++],pos + 1,pos + 2);
  661. RPEVENT("increased their "+isname+" skill by one.");
  662. llRegionSay(CHANMYRIAD,"GET_SKILL|"+isname);
  663. } else
  664. {
  665. ERROR("Requested Skill increase for nonexistent skill "+isname);
  666. }
  667. }
  668.  
  669. INCREASE_SKILL_SPECIALIZATIONS(string issname) // isname = increase skill specialization name
  670. {
  671. integer pos = llListFindList(SKILL_SPECIALIZATIONS,[issname]);
  672. if ( pos >= 0 ) // found skill in list
  673. {
  674. integer totcurval = llList2Integer(SKILL_SPECIALIZATIONS,pos +1)
  675. integer curval = llList2Integer(SKILL_SPECIALIZATIONS,pos + 2);
  676. SKILL_SPECIALIZATIONS = llListReplaceList(SKILL_SPECIALIZATIONS,[totcurvall++,curval++],pos + 1,pos + 2);
  677. RPEVENT("increased their "+issname+" skill by one.");
  678. llRegionSay(CHANMYRIAD,"GET_SKILL|"+issname);
  679. } else
  680. {
  681. ERROR("Requested Skill increase for nonexistent skill "+issname);
  682. }
  683. }
  684. // LEVEL UP - Calculate bonuses related to new level
  685. LEVELUP(integer newlevel)
  686. {
  687. // In the Myriad system, each time a character gains a new level he is given two skill points, each of which can be used to purchase a new skill at level 1 or improve an existing skill by one level. Keeping this method as an alternate means of character improvement for Open D6, with the addition that 1 skill point can increase a specialization skill by 2 ranks.
  688. SKILLPOOL += 2; // add two skill points per level
  689. // Finally, the character earns one quarter of a attribute point to improve any one attribute with.
  690. if ( ( newlevel% 4 ) == 0 ) // every 4th level
  691. {
  692. ATTPOOL++; // add a new att point
  693. }
  694. }
  695.  
  696. RESET()
  697. {
  698. // do any final work, then reset
  699. llResetScript();
  700. }
  701.  
  702. RPEVENT(string text)
  703. {
  704. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,text,llGetOwner());
  705. }
  706.  
  707. SET_ADVAN(string advanname,integer advantotrank, integer advanstartrank) // TODO how to verify advan names are valid?
  708. {
  709. if ( advanstartrank >= MINADVAN && advanstartrank <= MAXADVAN ) // rank valid?
  710. {
  711. ADVAN = [advanname,advantotrank,advanstartrank] + ADVAN; // add advan to list
  712. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_ADVAN|"+advanname+"="+(string)advantotrank+(string)advanstartrank,llGetOwner());
  713. } else // invalid, report it
  714. {
  715. ERROR("ADVAN "+advanname+" rank "+(string)advanstartrank+" value out of allowed range: "+(string)MINADVAN+"-"+(string)MAXADVAN);
  716. }
  717. }
  718.  
  719. SET_ATT(string attname,integer atttotrank,integer attbaserank,integer attstartrank) // TODO how to verify att names are valid?
  720. {
  721. if ( attbaserank >= MINATT && attbaserank <= MAXATT && attstartrank <= MAXSTARTATT ) // rank valid?
  722. {
  723. integer attpos = llListFindList(ATTRIBUTES,[attname]);
  724. if ( attpos < 0 )
  725. {
  726. ATTRIBUTES = [attname,atttotrank,attbaserank,attstartrank] + ATTRIBUTES; // add attribute to list
  727. }
  728. else
  729. {
  730. ATTRIBUTES = llListReplaceList(ATTRIBUTES,[atttotrank,attbaserank,attstartrank],attpos + 1,attpos + 3);
  731. }
  732. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_ATTRIBUTE|"+attname+"="+(string)atttotrank+(string)attbaserank+(string)attstartrank,llGetOwner());
  733.  
  734. }
  735. else // invalid, report it
  736. {
  737. ERROR("ATTRIBUTE "+attname+" base rank "+(string)attbaserank+" or starting rank"+(string)attstartrank+" value out of allowed range: "+(string)MINATT+"-"+(string)MAXATT+" for base rank,"+(string)MAXSTARTATT+" for maximum starting rank.");
  738. }
  739. }
  740.  
  741. SET_ATTPOOL(integer attamt)
  742. {
  743. if ( attamt >= 0 )
  744. {
  745. ATTPOOL = attamt;
  746. }
  747. else
  748. {
  749. ERROR("SET_ATTPOOL("+(string)attamt+") REQUESTED AMOUNT OUT OF RANGE: LESS THAN ZERO");
  750. }
  751. }
  752.  
  753. // Set Bodypoints and Current Bodypoints
  754. // SET_BODYPOINTS updates the total number and starting number of bodypoints from the character sheet, replacing the old list with the new information. In addition, this sets the current bodypoints' actual bodypoint total, using the total number of bodypoints as a reference. Until I've managed to find a way to work in temporary current bodypoints from special abilities, the temporary current bodypoints will remain at a constant of 0.
  755. SET_BODYPOINTS(integer totbody,integer startbody)
  756. {
  757. if ( startbody >= MINBODYPOINTS && startbody <= MAXBODYPOINTS ) // rank valid?
  758. {
  759. BODYPOINTS = llListReplaceList(BODYPOINTS,[totbody,startbody],0,1); // replace the BODYPOINTS list with the values in the notecard
  760. CURRENTBODYPOINTS = llListReplaceList(CURRENTBODYPOINTS,[totbody,startbody],0,1); // replace the CURRENTBODYPOINTS list with the values from the notecard
  761. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_CURRENTBODYPOINTS|"+(string)totbody+(string)startbody,llGetOwner());
  762. }
  763. else // invalid, report it
  764. {
  765. ERROR("BODYPOINTS start rank "+(string)startbody+" value out of allowed range: "+(string)MINBODYPOINTS+"-"+(string)MAXBODYPOINTS);
  766. }
  767. }
  768.  
  769. SET_CURRENTBODYPOINTS(integer newtempbody,integer newcurbody)
  770. {
  771. CURRENTBODYPOINTS = llListReplaceList(CURRENTBODYPOINTS,[newtempbody,newcurbody],0,1);
  772. // Idea on keeping track of temporary body points: the Resilience Module recieves the temp and current body points from the character sheet module. From there, if the character is struck, have the Resilience Module FIRST check to see if there are any temporary body points. If so, the code first removes the temporary points. If there are still points past the temporary point count, the Res Module THEN removes the actual current bodypoints. If there are no temporary bodypoints, then it reduces the actual current bodypoints by the amount of damage caused.
  773.  
  774. // Keeping track of temporary skill and attribute boosts is a bit tricky, however. I'm considering the idea of creating a Buff/Debuff Module that sends and receives data on the total attribute and skill points. If a particular buff/debuff mode is active, it sends out information concerning how to modify stats to the main and/or character sheet module. When they are inactive, it changes the stats back to the default stats. Basically, the Buff/Debuff module will be a list of buffs/debuffs that note if they are active, sending this information out. If they are active, it starts a timer based on whatever conditions that particular debuff/buff requires. When the timer reaches 0, it deactivates the buff/debuff, and it sends this information out. Meanwhile, the main and/or character module notes that the buff/debuff is active, takes the information on much much to raise the stat by, then when the buff/debuff is inactive, returns the stat to its default state.
  775. }
  776.  
  777. SET_CHARACTERNAME(string aname)
  778. {
  779. CHARACTERNAME = aname;
  780. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_CHARACTERNAME|CHARACTERNAME="+CHARACTERNAME,llGetOwner());
  781. }
  782.  
  783. SET_DISAD(string disadname,integer disadtotrank,integer disadstartrank) // TODO how to verify disad names are valid?
  784. {
  785. if ( disadstartrank >= MINDISAD && disadstartrank <= MAXDISAD ) // rank valid?
  786. {
  787. DISAD = [disadname,disadtotrank,disadstartrank] + DISAD; // add disad to list
  788. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_DISAD|"+disadname+"="+(string)disadtotrank+(string)disadstartrank,llGetOwner());
  789. }
  790. else // invalid, report it
  791. {
  792. ERROR("DISAD "+disadname+" starting rank "+(string)disadstartrank+" value out of allowed range: "+(string)MINDISAD+"-"+(string)MAXDISAD);
  793. }
  794. }
  795.  
  796. SET_EQUIPMENT(string equipmentname,integer equipmentamount,integer equipmentdiecode) // TODO how to verify the equipment name is valid?
  797. {
  798. if ( equipmentamount >= MINEQUIPPED && equipmentamount <= MAXEQUIPPED ) // amount valid?
  799. {
  800. EQUIPMENT = [equipmentname,equipmentamount,equipmentdiecode] + EQUIPMENT; // add equipment to list
  801. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_EQUIPMENT|"+equipmentname+"="+(string)equipmentamount+(string)equipmentdiecode,llGetOwner());
  802. }
  803. else // invalid, report it
  804. {
  805. ERROR("EQUIPMENT "+equipmentname+" amount "+(string)equipmentamount+" value out of allowed range: "+(string)MINEQUIPPED+"-"+(string)MAXEQUIPPED);
  806. }
  807. }
  808.  
  809. SET_ESTATE(string anestate)
  810. {
  811. ESTATE = anestate;
  812. DEBUG("Estate: ["+ESTATE+"]");
  813. }
  814.  
  815. SET_EXTRANORMAL_MAGIC(string magname,integer magtotrank,integer magbaserank,integer magstartrank)
  816. {
  817. // TODO how to verify effect name?
  818. if ( magbaserank >= MINEXTRASKILL && magbaserank <= MAXEXTRASKILL ) // effect rank valid?
  819. {
  820. EXTRANORMAL_MAGIC = [magname,magtotrank,magbaserank,magstartrank] + EXTRANORMAL_MAGIC; // add effect to list
  821. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_EXTRANORMAL_MAGIC|"+magname+"="+(string)magtotrank+(string)magbaserank+(string)magstartrank,llGetOwner());
  822. }
  823. else // invalid, report it
  824. {
  825. ERROR("EXTRANORMAL MAGIC "+magname+" base rank "+(string)magbaserank+" value out of allowed range: "+(string)MINEXTRASKILL+"-"+(string)MAXEXTRASKILL);
  826. }
  827. }
  828.  
  829. SET_EXTRANORMAL_POWERS(string powername,integer powertotrank,integer powerbaserank,integer powerstartrank)
  830. {
  831. // TODO how to verify effect name?
  832. if ( powerbaserank >= MINEXTRASKILL && powerbaserank <= MAXEXTRASKILL ) // effect rank valid?
  833. {
  834. EXTRANORMAL_POWERS = [powername,powertotrank,powerbaserank,powerstartrank] + EXTRANORMAL_POWERS; // add effect to list
  835. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_EXTRANORMAL_POWERS|"+powername+"="+(string)powertotrank+(string)powerbaserank+(string)powerstartrank,llGetOwner());
  836. }
  837. else // invalid, report it
  838. {
  839. ERROR("EXTRANORMAL POWER "+powername+" base rank "+(string)powerbaserank+" value out of allowed range: "+(string)MINEXTRASKILL+"-"+(string)MAXEXTRASKILL);
  840. }
  841. }
  842.  
  843. SET_EXTRANORMAL_PSIONICS(string psiname,integer psitotrank,integer psibaserank,integer psistartrank) // TODO how to verify effect name?
  844. {
  845.  
  846. if ( psitotrank >= MINEXTRASKILL && psitotrank <= MAXEXTRASKILL ) // effect rank valid?
  847. {
  848. EXTRANORMAL_PSIONICS = [psiname,psitotrank,psibaserank,psistartrank] + EXTRANORMAL_PSIONICS; // add effect to list
  849. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_EXTRANORMAL_PSIONICS|"+psiname+"="+(string)psitotrank+(string)psibaserank+(string)psistartrank,llGetOwner());
  850. }
  851. else // invalid, report it
  852. {
  853. ERROR("EXTRANORMAL PSIONICS "+psiname+" rank "+(string)psibaserank+" value out of allowed range: "+(string)MINEXTRASKILL+"-"+(string)MAXEXTRASKILL);
  854. }
  855. }
  856.  
  857. SET_FUNDS(integer fundstotal,integer fundsstart) // TODO how to verify funds?
  858. {
  859. FUNDS = [fundstotal,fundsstart] + FUNDS; // add funds to list
  860. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_FUNDS|FUNDS="+(string)fundstotal+(string)fundsstart,llGetOwner());
  861. }
  862.  
  863. SET_FUNDSPOOL(integer fundsamt)
  864. {
  865. if ( fundsamt >= 0 )
  866. {
  867. FUNDSPOOL = fundsamt;
  868. } else
  869. {
  870. ERROR("SET_FUNDSPOOL("+(string)fundsamt+") REQUESTED AMOUNT OUT OF RANGE: LESS THAN ZERO");
  871. }
  872. }
  873.  
  874. SET_OTHERINFORMATION(string someinfo)
  875. {
  876. OTHERINFORMATION = someinfo;
  877. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_OTHERINFORMATION|OTHERINFORMATION="+OTHERINFORMATION,llGetOwner());
  878. }
  879.  
  880. SET_OCCUPATION(string anoccupation)
  881. {
  882. OCCUPATION = anoccupation;
  883. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_OCCUPATION|OCCUPATION="+OCCUPATION,llGetOwner());
  884. }
  885.  
  886. SET_PROGRESSION(string method)
  887. {
  888. method = llToUpper(method);
  889. if ( method == "LEVEL-BASED" || method == "GRADUAL" || method == "RANDOM" )
  890. {
  891. PROGRESSION = method;
  892. DEBUG("Character progression method set to: "+method);
  893. }
  894. else
  895. {
  896. ERROR("Unknown progression method: "+method+"! Roleplay progress will not be counted.");
  897. }
  898. }
  899.  
  900. SET_SPECIAL_ABILITIES(string abilityname,integer abilitytotrank, integer abilitystartrank) // TODO how to verify effect name?
  901. {
  902. if ( abilitystartrank >= MINEXTRASKILL && abilitystartrank <= MAXEXTRASKILL ) // effect rank valid?
  903. {
  904. SPECIAL_ABILITIES = [abilityname,abilitytotrank,abilitystartrank] + SPECIAL_ABILITIES; // add effect to list
  905. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_SPECIAL_ABILITIES|"+abilityname+"="+(string)abilitytotrank+(string)abilitystartrank,llGetOwner());
  906. }
  907. else // invalid, report it
  908. {
  909. ERROR("VEHICLE EFFECT "+abilityname+" starting rank "+(string)abilitystartrank+" value out of allowed range: "+(string)MINEXTRASKILL+"-"+(string)MAXEXTRASKILL);
  910. }
  911. }
  912.  
  913. SET_SPECIES(string aspecies)
  914. {
  915. SPECIES = aspecies;
  916. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_SPECIES|SPECIES="+SPECIES,llGetOwner());
  917. }
  918.  
  919. SET_SKILL(string skillname,integer skilltotrank,integer skillbaserank,integer skillstartrank) // TODO how to verify skill names are valid?
  920. {
  921. if ( skillstartrank >= MINSKILL && skillstartrank <= MAXSKILL ) // skill rank valid?
  922. {
  923. SKILLS = [skillname,skilltotrank,skillbaserank,skillstartrank] + SKILLS; // add skill to list
  924. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_SKILL|"+skillname+"="+(string)skilltotrank+(string)skillbaserank+(string)skillstartrank,llGetOwner());
  925. }
  926. else // invalid, report it
  927. {
  928. ERROR("SKILL "+skillname+" starting rank "+(string)skillstartrank+" value out of allowed range: "+(string)MINSKILL+"-"+(string)MAXSKILL);
  929. }
  930. }
  931.  
  932. SET_SKILLPOOL(integer skillamt)
  933. {
  934. if ( skillamt >= 0 )
  935. {
  936. SKILLPOOL = skillamt;
  937. }
  938. else
  939. {
  940. ERROR("SET_SKILLPOOL("+(string)skillamt+") REQUESTED AMOUNT OUT OF RANGE: LESS THAN ZERO");
  941. }
  942. }
  943.  
  944. SET_SKILL_SPECIALIALIZATION(string specname,integer spectot,integer specbase,integer specstart) // TODO how to verify specialization?
  945. {
  946. if ( specstart >= MINSPEC && specstart <= MAXSPEC) // skill rank valid?
  947. {
  948. SKILL_SPECIALIALIZATION = [specname,spectot,specbase,specstart] + SKILL_SPECIALIALIZATION; // add skill to list
  949. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SKILL_SPECIALIALIZATION|"+specname+"="+(string)spectot+(string)specbase+(string)specstart,llGetOwner());
  950. }
  951. else // invalid, report it
  952. {
  953. ERROR("SKILL_SPECIALIALIZATION "+specname+" starting rank "+(string)specstart+" value out of allowed range: "+(string)MINSPEC+"-"+(string)MAXSPEC);
  954. }
  955. }
  956.  
  957. SET_XP(integer xpamt)
  958. {
  959. if ( xpamt >= MINXP && xpamt <= MAXXP )
  960. {
  961. XP = xpamt;
  962. CALCULATE_LEVEL_BY_XP();
  963. // inform all other modules that might need to track XP
  964. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_XP|XP="+(string)XP,llGetOwner());
  965. }
  966. else
  967. {
  968. ERROR("SET_XP("+(string)xpamt+") REQUESTED AMOUNT OF RANGE: "+(string)MINXP+"-"+(string)MAXXP);
  969. }
  970. }
  971.  
  972. SET_XPLEVEL(integer xplevelamt)
  973. {
  974. if ( xplevelamt >= MIN_XPLEVEL && xplevelamt <= MAX_XPLEVEL )
  975. {
  976. XPLEVEL = xplevelamt; // save local state
  977. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"SET_XPLEVEL|XPLEVEL="+(string)XPLEVEL,llGetOwner());
  978. }
  979. else
  980. {
  981. ERROR("SET_XPLEVEL("+(string)xplevelamt+") REQUESTED AMOUNT OUT OF RANGE: "+(string)MIN_XPLEVEL+"-"+(string)MAX_XPLEVEL);
  982. }
  983. }
  984.  
  985. SETUP()
  986. {
  987. FLAG_DEBUG = FALSE;
  988. PLAYERID = llGetOwner();
  989. CHANOBJECT = (integer)("0x"+llGetSubString(llGetKey(),0,6));
  990. if ( HANDOBJECT!= 0 ) llListenRemove(HANDOBJECT);
  991. HANDOBJECT = llListen(CHANOBJECT,"",NULL_KEY,"");
  992. llRegionSay(CHANMYRIAD,"GET_REGION_SETTING|PROGRESSION"); // ask for this first, asking for estate triggers find_notecard function
  993. llRegionSay(CHANMYRIAD,"GET_REGION_SETTING|ESTATE");
  994. MENU_TIMER = MENU_TIMEOUT;
  995. llSetTimerEvent(1.0);
  996. }
  997.  
  998. SKILL_FAILED(string sname)
  999. {
  1000. if ( PROGRESSION!= "RANDOM" ) return; // tracking skill failure only applies to random progression - ignore message
  1001. integer pos = llListFindList(SKILLS_INCREASED,[sname]);
  1002. if ( pos >= 0 ) // skill already in increase list
  1003. {
  1004. integer current = llList2Integer(SKILLS_INCREASED,pos + 1);
  1005. if ( current < 4 ) // not yet, just note it
  1006. {
  1007. }
  1008. else // has hit 5, increase skill and att
  1009. {
  1010. INCREASE_SKILL(sname); // increase skill
  1011. SKILLS_INCREASED = llListReplaceList(SKILLS_INCREASED,[0],pos + 1,pos + 1);
  1012. }
  1013. }
  1014. else // skill not in increase list
  1015. {
  1016. SKILLS_INCREASED = [sname,1] + SKILLS_INCREASED; // add the skill to the increased list
  1017. }
  1018. SKILL_INCREASES++;
  1019. // now - 5 skill increases = new skill earned
  1020. if ( SKILL_INCREASES == 5 )
  1021. {
  1022. SKILL_INCREASES = 0;
  1023. NEW_SKILLS++;
  1024. RPEVENT("earned a new skill!");
  1025. }
  1026. }
  1027.  
  1028. PARSE(string message,key id)
  1029. {
  1030. //DEBUG("Parse: message=["+message+"] id=["+(string)id+"]");
  1031.  
  1032. // First - handle type 1 messages that do not require breaking down
  1033. string msg = llToLower(message);
  1034. if ( msg == "debugoff" ) { FLAG_DEBUG=FALSE; } // turn off debugging on request
  1035. if ( msg == "debugon" ) { FLAG_DEBUG=TRUE; } // turn on debugging on request
  1036. if ( msg == "reset" ) { RESET(); } // reset on request
  1037. if ( msg == "version") { GETVERSION(); } // respond with version info when requested
  1038. if ( msg == "get_xp" ) { GET_XP(); return; }
  1039. if ( msg == "get_xplevel" ) { GET_XPLEVEL(); return; }
  1040. if ( msg == "dump_sheet" ) { DUMP_SHEET(id); return; } // id is UUID of character builder, sent over from HUD script
  1041. if ( msg == "dump_progress" ) { DUMP_PROGRESS(id); return; } // id is UUID of character builder, sent over from HUD script
  1042. if ( msg == "del_progress" ) { DEL_PROGRESS(id); return; } // id is UUID of item that requested del progress
  1043. if ( msg == "add_xp" ) { ADD_XP(id); return; } // add a point of total and spendable XP
  1044.  
  1045. // Set up variables to process type 2 and type 3 messages
  1046. list tokens; // The parts of the message
  1047. string cmd; // command (example: set attribute)
  1048. string data; // just data, like the character's physical description, or the character's aliases
  1049. list subtokens; // statistic category; (Example: POWERS)
  1050. string statname; // statistic name; (Example: Telepathy)
  1051. integer idata; // integer data; (Example: Telepathy Total Rank)
  1052. integer i2data; // integer data 2 (Example: Telepathy Base Rank)
  1053. integer i3data; // integer data 3 (Example: Telepathy Starting Rank)
  1054. string sdata; // string data (Used for getting the list of skills/attributes that fail to advance, when levelling)
  1055.  
  1056. // process type 2 bus messages COMMAND|DATA=...|DATA=...
  1057. if ( llSubStringIndex(message,DIV) >=0 )
  1058. {
  1059. tokens = llParseString2List(message,[DIV],[]);
  1060. cmd = llToLower(llStringTrim(llList2String(tokens,0),STRING_TRIM));
  1061. data = llList2String(tokens,1);
  1062. subtokens = llParseString2List(data,["="],[]);
  1063. statname = llList2String(subtokens,0);
  1064. idata = llList2Integer(subtokens,1);
  1065. i2data = llList2Integer(subtokens,2);
  1066. i3data = llList2Integer(subtokens,3);
  1067. sdata = llList2String(subtokens,1);
  1068. //if ( command == "SET_ESTATE" ) { SET_ESTATE(svalue); return;}
  1069. if ( cmd == "set_xp" ) { SET_XP(idata); return; }
  1070. if ( cmd == "set_xplevel" ) { SET_XPLEVEL(idata); return; }
  1071. if ( cmd == "get_att" ) { GET_ATT(statname,idata,i2data,i3data); return; }
  1072. if ( cmd == "get_bodypoints" ) { GET_BODYPOINTS(idata,i2data); return; }
  1073. if ( cmd == "get_currentbodypoints" ) { GET_CURRENTBODYPOINTS(idata,i2data); return; }
  1074. if ( cmd == "set_currentbodypoints" ) { SET_CURRENTBODYPOINTS(idata,i2data); return; }
  1075. // Progress
  1076. if ( cmd == "skill_failed" ) { SKILL_FAILED(sdata); return; } // SKILL_FAILED|SKILL=name
  1077. if ( cmd == "progress" )
  1078. {
  1079. if ( llToLower(statname) == "xp" )
  1080. {
  1081. XP = idata;
  1082. if ( XP > MAXXP ) XP = MAXXP;
  1083. llSay(PUBLIC_CHANNEL,"Progress XP: "+(string)XP);
  1084. return;
  1085. }
  1086. if ( llToLower(statname) == "xplevel" )
  1087. {
  1088. XPLEVEL = idata;
  1089. if ( XPLEVEL > MAX_XPLEVEL ) XPLEVEL = MAX_XPLEVEL;
  1090. llSay(PUBLIC_CHANNEL,"Progress XP Level: "+(string)XPLEVEL);
  1091. return;
  1092. }
  1093. if ( llToLower(statname) == "attpool" )
  1094. {
  1095. ATTPOOL=idata;
  1096. llSay(PUBLIC_CHANNEL,"Progress Attributes Pool: "+(string)ATTPOOL);
  1097. return;
  1098. }
  1099. if ( llToLower(statname) == "skillpool" )
  1100. {
  1101. SKILLPOOL=idata;
  1102. llSay(PUBLIC_CHANNEL,"Progress Skill Pool: "+(string)SKILLPOOL);
  1103. return;
  1104. }
  1105. return;
  1106. }
  1107. // done processing commands with DIV
  1108. return;
  1109. }
  1110.  
  1111. // Process type 3 messages CATEGORY=ATTRIBUTE,VALUE
  1112. tokens = llParseString2List(message,["="],[]);
  1113. cmd = llToLower(llStringTrim(llList2String(tokens,0),STRING_TRIM));
  1114. data = llList2String(tokens,1);
  1115. subtokens = llCSV2List(data);
  1116. statname = llList2String(subtokens,0);
  1117. idata = llList2Integer(subtokens,1);
  1118. i2data = llList2Integer(subtokens,2);
  1119. i3data = llList2Integer(subtokens,3);
  1120. sdata = llList2String(subtokens,1);
  1121. if ( cmd == "version" ) { CHECK_D6CARDVERSION(data); return;}
  1122. if ( cmd == "charactername" ) { SET_CHARACTERNAME(data); return; }
  1123. if ( cmd == "species" ) { SET_SPECIES(data); return;}
  1124. if ( cmd == "otherinformation" ) { SET_OTHERINFORMATION(data); return; }
  1125. if ( cmd == "occupation" ) { SET_OCCUPATION(data); return; }
  1126. if ( cmd == "attribute" ) { SET_ATT(statname,idata,i2data,i3data); return; }
  1127. if ( cmd == "advan" ) { SET_ADVAN(statname,idata,i2data); return;}
  1128. if ( cmd == "disad" ) { SET_DISAD(statname,idata,i2data); return;}
  1129. if ( cmd == "skill" ) { SET_SKILL(statname,idata,i2data,i3data); return;}
  1130. if ( cmd == "extranormal_psionics" ) { SET_EXTRANORMAL_PSIONICS(statname,idata,i2data,i3data); return;}
  1131. if ( cmd == "extranormal_magic" ) { SET_EXTRANORMAL_MAGIC(statname,idata,i2data,i3data); return;}
  1132. if ( cmd == "extranormal_powers" ) { SET_EXTRANORMAL_POWERS(statname,idata,i2data,i3data); return;}
  1133. if ( cmd == "special_abilities" ) { SET_SPECIAL_ABILITIES(statname,idata,i2data,i3data); return;}
  1134. if ( cmd == "skill_specializations" ) { SET_SKILL_SPECIALIZATIONS(statname,idata,i2data,i3data); return;}
  1135. if ( cmd == "bodypoints" ) { SET_BODYPOINTS(idata,i2data); return;}
  1136. if ( cmd == "funds" ) { SET_FUNDS(idata,i2data); return;}
  1137. if ( cmd == "equipment" ) { SET_EQUIPMENT(statname,idata,i2data,i3data); return;}
  1138. if ( cmd == "xp" ) { SET_XP(idata); return; }
  1139. if ( cmd == "xplevel" ) { SET_XPLEVEL(idata); return; }
  1140. if ( cmd == "attpool" ) { SET_ATTPOOL(idata); return; }
  1141. if ( cmd == "skillpool" ) { SET_SKILLPOOL(idata); return; }
  1142. if ( cmd == "fundspool" ) { SET_FUNDSPOOL(idata); return; }
  1143. if ( cmd == "character_loaded" )
  1144. {
  1145. llSay(PUBLIC_CHANNEL,llKey2Name(PLAYERID)+"'s character loaded.");
  1146. }
  1147. }
  1148.  
  1149. //=======
  1150. //DEFAULT
  1151. //=======
  1152. default
  1153. {
  1154.  
  1155. // dataserver called for each line of notecard requested - process character sheet
  1156. dataserver(key queryid,string data)
  1157. {
  1158. if ( queryid == QUERY ) // ataserver gave us line we asked for?
  1159. {
  1160. if ( data!= EOF ) // we're not at end of notecard file?
  1161. {
  1162. if ( llGetSubString(data,0,0) == "#" ) // does this line start with comment mark?
  1163. {
  1164. QUERY = llGetNotecardLine(CARD,LINE++); // ignore comment and ask for the next line
  1165. return;
  1166. }
  1167. PARSE(data,llGetOwner()); // parse incoming notecard line
  1168. QUERY = llGetNotecardLine(CARD,LINE++); // finished with known keywords, get next line
  1169. }
  1170. else // end of notecard
  1171. {
  1172. // TODO how to verify entire character sheet was completed and loaded?
  1173. llMessageLinked(LINK_THIS,MODULE_CHARSHEET,"CHARACTER_LOADED",llGetOwner()); // done loading
  1174. DEBUG("Character Sheet Loaded.");
  1175. } // end if data not equal eof
  1176. } // end if query id equal
  1177. } // end if data server event
  1178.  
  1179. link_message(integer sender_num,integer num,string str,key id)
  1180. {
  1181. if ( num == MODULE_CHARSHEET || num == LM_SENDTOATTACHMENT ) return; // ignore link messages not sent to us specifically
  1182. DEBUG("EVENT: link_message("+(string)sender_num+","+(string)num+","+str+","+(string)id+")");
  1183. PARSE(str,id); // parse incoming message
  1184. }
  1185.  
  1186. listen(integer channel,string name,key id, string msg)
  1187. {
  1188. name = ""; // LSLint
  1189. id = NULL_KEY; // LSLint
  1190. if ( channel == CHANOBJECT )
  1191. {
  1192. list tokens = llParseString2List(msg,[DIV],[]);
  1193. string command = llToLower(llStringTrim(llList2String(tokens,0),STRING_TRIM));
  1194. if ( command == "region_setting" )
  1195. {
  1196. list sublist = llParseString2List(llList2String(tokens,1),["="],[]);
  1197. if ( llToLower(llStringTrim(llList2String(sublist,0),STRING_TRIM)) == "progression" )
  1198. {
  1199. SET_PROGRESSION(llToUpper(llList2String(sublist,1)));
  1200. return;
  1201. }
  1202. if ( llToLower(llStringTrim(llList2String(sublist,0),STRING_TRIM)) == "estate" )
  1203. {
  1204. SET_ESTATE(llList2String(sublist,1));
  1205. FIND_NOTECARD();
  1206. return;
  1207. }
  1208. return;
  1209. }
  1210. if ( command == "skill" )
  1211. {
  1212. integer t = llGetListLength(tokens);
  1213. integer c;
  1214. for ( c = 0; c < t; c++)
  1215. {
  1216. list sublist = llParseString2List(llList2String(tokens,c),["="],[]);
  1217. string statname = llToLower(llList2String(sublist,0));
  1218. if ( statname == "basestat" )
  1219. {
  1220. string value = llList2String(sublist,1);
  1221. INCREASE_STAT(value);
  1222. }
  1223. }
  1224. }
  1225. PARSE(msg,id); // parse incoming chat message not REGION_SETTING or SKILL data
  1226. return;
  1227. }
  1228. if ( channel == MENU_CHANNEL )
  1229. {
  1230. if ( msg == "Default" )
  1231. {
  1232. CARD = DEFAULT;
  1233. }
  1234. else
  1235. {
  1236. integer listpos = llListFindList(CHARACTERS,[msg]);
  1237. if ( listpos >= 0 )
  1238. {
  1239. CARD = llList2String(CHARACTERS,listpos + 1);
  1240. }
  1241. }
  1242. DEBUG("Loading character sheet: "+CARD);
  1243. llSetTimerEvent(0.0);
  1244. MENU_TIMER = 0;
  1245. llListenRemove(MENU_HANDLE);
  1246. QUERY = llGetNotecardLine(CARD,LINE++); // ask for line from notecard and advance to next line
  1247. return;
  1248. }
  1249. }
  1250.  
  1251. state_entry()
  1252. {
  1253. SETUP();
  1254. }
  1255.  
  1256. timer()
  1257. {
  1258. MENU_TIMER--; // timer still running, decrement
  1259. if ( MENU_TIMER <= 0 ) // timed out
  1260. {
  1261. DEBUG("Character Sheet Menu timed out. Using default character sheet."); // tell the owner
  1262. llListenRemove(MENU_HANDLE); // remove the listener
  1263. MENU_TIMER = 0;
  1264. llSetTimerEvent(0.0); // stop the timer
  1265. CARD = DEFAULT;
  1266. QUERY = llGetNotecardLine(CARD,LINE++);
  1267. }
  1268. }
  1269. }
  1270. // END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement