GLB Player Builder

simulate a player's build

  1. // ==UserScript==
  2. // @name GLB Player Builder
  3. // @namespace nikkoum
  4. // @description simulate a player's build
  5. // @include https://goallineblitz.com/game/skill_points.pl?player_id=*
  6. // @include https://glb.warriorgeneral.com/game/skill_points.pl?player_id=*
  7. // @version 16.09.22-nikkoum
  8. // @grant GM_addStyle
  9. // ==/UserScript==
  10. // Original script written by monsterkill. Accelerated Player Development changes made by AirMcMVP.
  11. // Training gains at high attribute values, including hardcoding, fixed by mandyross ...
  12. // see https://sites.google.com/site/glbmandyross/training_hotspots
  13. // pabst fixed something 3/4/2012 and fixed multitraining 7/18/2013 and other stuff later
  14. // I added very few things to make it run under modern iterations of script extensions, notably Tampermonkey
  15.  
  16.  
  17. var autoTrain = true;
  18.  
  19. var offseasonLength = 8;
  20. var preseasonLength = 8;
  21. var automaticSeasonChange = true;
  22. var sitout_first_season = false;
  23. var game_xp_factor = 1.0;
  24. var daily_xp_factor = 1.0;
  25. var va_xp_factor = 1.0;
  26. var training_points_per_day = 2;
  27. var sp_increase = 0 ;
  28. var boost_count = 0 ;
  29. var max_boosts_per_season = 3;
  30. var plateau_age = 280;
  31. var extended_plateau_age = 281;
  32. var desiredBT = 0;
  33. var disableSerialization = false;
  34. var enableDesiredBTCheck = true;//enable to set a desired BT amount for age 280 and training will check for when you need to start light training
  35. var logTrainingCalcs = false;// send text to the console log to trace the bonuses applied during training
  36. var commonHeaders = {
  37. "User-agent": "Mozilla/5.0 (compatible) Greasemonkey"
  38. ,
  39. "Accept": "text/html,application/xml,text/xml"
  40. };
  41.  
  42. /* start constants */
  43. var TRAININGTYPE = {
  44. LIGHT: 0,
  45. NORMAL: 1,
  46. INTENSE: 2,
  47. MULTI: 3
  48. }
  49. var trainingTypes = {
  50. 'light' : TRAININGTYPE.LIGHT,
  51. 'normal' : TRAININGTYPE.NORMAL,
  52. 'intense' : TRAININGTYPE.INTENSE,
  53. 'multi' : TRAININGTYPE.MULTI
  54. };
  55. var attributeTrainingOptions = [ 'strength',
  56. 'speed',
  57. 'agility',
  58. 'jumping',
  59. 'stamina',
  60. 'vision',
  61. 'confidence',
  62. 'blocking',
  63. 'throwing',
  64. 'catching',
  65. 'carrying',
  66. 'tackling',
  67. 'kicking',
  68. 'punting'
  69. ];
  70. /* end constants */
  71.  
  72.  
  73.  
  74. var containerDiv = document.createElement('div');
  75. // change this if you want the controls somewhere else
  76. document.getElementById("special_abilities").appendChild(containerDiv);
  77.  
  78. var startBuilderButton = addElement('input', 'startBuilderButton', containerDiv, {
  79. type: "button",
  80. value: "Start Builder"
  81. });
  82. startBuilderButton.addEventListener("click", startBuilder, true);
  83.  
  84.  
  85. var topTableRow = addElement('tr', 'topTableRow', addElement('table', 'topTable', containerDiv));
  86. GM_addStyle("#topTable {width: 100%}");
  87. var previousDayTD = addElement('td', 'previousDayTD', topTableRow);
  88. var previousDayButton = addElement('input', 'previousDayButton', previousDayTD, {
  89. type: "button",
  90. value: "Previous Day"
  91. });
  92. previousDayButton.addEventListener("click", restoreBuild, true);
  93. GM_addStyle("#previousDayButton {display: none}");
  94. GM_addStyle("#previousDayTD {width: 50%}");
  95.  
  96. var nextDayTD = addElement('td', 'nextDayTD', topTableRow);
  97. var nextDayButton = addElement('input', 'nextDayButton', addElement('td', null, nextDayTD), {
  98. type: "button",
  99. value: "Next Day"
  100. });
  101. nextDayButton.addEventListener("click", incrementDay, true);
  102. GM_addStyle("#nextDayButton {display: none}");
  103. GM_addStyle("#nextDayTD {width: 50%}");
  104.  
  105. var loadSavedBuildButton = document.createElement('input');
  106. loadSavedBuildButton.id = "loadSavedBuildButton";
  107. loadSavedBuildButton.type = "button";
  108. loadSavedBuildButton.value = "Load a Saved Build";
  109. loadSavedBuildButton.addEventListener("click", loadSavedBuild, true);
  110. containerDiv.appendChild(loadSavedBuildButton);
  111. if (disableSerialization) {
  112. GM_addStyle("#loadSavedBuildButton {display: none}");
  113. }
  114.  
  115. /*
  116. var convertBuildButton = document.createElement('input');
  117. convertBuildButton.id = "convertBuildButton";
  118. convertBuildButton.type = "button";
  119. convertBuildButton.value = "Convert a Saved Build";
  120. convertBuildButton.addEventListener("click", convertSavedBuild, true);
  121. containerDiv.appendChild(convertBuildButton);
  122. if (disableSerialization) {
  123. GM_addStyle("#convertBuildButton {display: none}");
  124. }
  125. */
  126.  
  127. var startSeasonButton = document.createElement('input');
  128. startSeasonButton.id = "startSeasonButton";
  129. startSeasonButton.type = "button";
  130. startSeasonButton.value = "Start Season";
  131. startSeasonButton.addEventListener("click", startSeason, true);
  132. containerDiv.appendChild(startSeasonButton);
  133. GM_addStyle("#startSeasonButton {display: none}");
  134.  
  135. var boostButton = document.createElement('input');
  136. boostButton.id = "boostButton";
  137. boostButton.type = "button";
  138. boostButton.value = "Boost";
  139. boostButton.addEventListener("click", boost, true);
  140. containerDiv.appendChild(boostButton);
  141. GM_addStyle("#boostButton {display: none}");
  142.  
  143. var currentSeasonDiv = document.createElement('div');
  144. currentSeasonDiv.id = "currentSeasonDiv";
  145. containerDiv.appendChild(currentSeasonDiv);
  146. var currentDayDiv = document.createElement('div');
  147. currentDayDiv.id = "currentDayDiv";
  148. containerDiv.appendChild(currentDayDiv);
  149. var currentAgeDiv = document.createElement('div');
  150. currentAgeDiv.id = "currentAgeDiv";
  151. containerDiv.appendChild(currentAgeDiv);
  152.  
  153. var availableBoostsDiv = document.createElement('div');
  154. availableBoostsDiv.id = "availableBoostsDiv";
  155. containerDiv.appendChild(availableBoostsDiv);
  156.  
  157. var boostCountDiv = document.createElement('div');
  158. boostCountDiv.id = "boostCountDiv";
  159. containerDiv.appendChild(boostCountDiv);
  160.  
  161. // level and experience
  162. var currentLevelDiv = document.createElement('div');
  163. currentLevelDiv.id = "currentLevelDiv";
  164. containerDiv.appendChild(currentLevelDiv);
  165. var currentXPDiv = document.createElement('div');
  166. currentXPDiv.id = "currentXPDiv";
  167. containerDiv.appendChild(currentXPDiv);
  168.  
  169. // stop game xp button
  170. var stopGameXPButton = addElement('input','stopGameXPButton', containerDiv, {
  171. type: "button",
  172. value: "Turn Off Game XP"
  173. });
  174. stopGameXPButton.addEventListener("click", turnOffGameXP, true);
  175. GM_addStyle("#stopGameXPButton {display: none}");
  176. // start game xp button
  177. var startGameXPButton = document.createElement('input');
  178. startGameXPButton.id = "startGameXPButton";
  179. startGameXPButton.type = "button";
  180. startGameXPButton.value = "Turn On Game XP";
  181. startGameXPButton.addEventListener("click", turnOnGameXP, true);
  182. containerDiv.appendChild(startGameXPButton);
  183. GM_addStyle("#startGameXPButton {display: none}");
  184.  
  185. // even game day button
  186. var gameDayEvenButton = addElement('input','gameDayEvenButton', containerDiv, {
  187. type: "button",
  188. value: "Run games on even days"
  189. });
  190. gameDayEvenButton.addEventListener("click", enableEvenDayGames, true);
  191. GM_addStyle("#gameDayEvenButton {display: none}");
  192.  
  193. // odd game day button
  194. var gameDayOddButton = addElement('input','gameDayOddButton', containerDiv, {
  195. type: "button",
  196. value: "Run games on odd days"
  197. });
  198. gameDayOddButton.addEventListener("click", enableOddDayGames, true);
  199. GM_addStyle("#gameDayOddButton {display: none}");
  200.  
  201. // veteran xp and points
  202. var currentVAXPDiv = document.createElement('div');
  203. currentVAXPDiv.id = "currentVAXPDiv";
  204. containerDiv.appendChild(currentVAXPDiv);
  205. var currentVADiv = document.createElement('div');
  206. currentVADiv.id = "currentVADiv";
  207. containerDiv.appendChild(currentVADiv);
  208.  
  209. // bonus tokens
  210. var currentBTDiv = document.createElement('span');
  211. currentBTDiv.id = "currentBTDiv";
  212. containerDiv.appendChild(currentBTDiv);
  213. var spendBTButton = document.createElement('input');
  214. spendBTButton.id = "spendBTButton";
  215. spendBTButton.type = "button";
  216. spendBTButton.value = "Spend 15 BT for 1 SP";
  217. spendBTButton.addEventListener("click", spendBT, true);
  218. containerDiv.appendChild(spendBTButton);
  219. GM_addStyle("#spendBTButton {display: none}");
  220.  
  221. if (enableDesiredBTCheck) {
  222. var btWarningDiv = addElement('div', 'btWarningDiv', containerDiv);
  223. var btWarningButton = addElement('input', "btWarningButton", btWarningDiv, {
  224. type: "button",
  225. value: "Set Desired BT for Day 280"
  226. });
  227. btWarningButton.addEventListener("click", promptForDesiredBT, true);
  228. }
  229. GM_addStyle("#btWarningDiv {display: none}");
  230. addElement('hr', null, containerDiv);
  231.  
  232. // training
  233. var currentTPDiv = addElement('div', 'currentTPDiv', containerDiv);
  234.  
  235. var trainingDiv = addElement('div', 'trainingDiv', containerDiv, {innerHTML : '<select id="trainingSelect"></select>'});
  236. GM_addStyle("#trainingDiv {display: none}");
  237.  
  238. // populate training options
  239. var trainingSelect = document.getElementById('trainingSelect');
  240. for (k in trainingTypes) {
  241. addElement('option', 'trainingTypeOption'+trainingTypes[k], trainingSelect, {
  242. value: trainingTypes[k],
  243. innerHTML: k
  244. });
  245. }
  246. trainingSelect.addEventListener("change", trainingTypeChanged, true);
  247. function trainingTypeChanged(val) {
  248. var trainingType = document.getElementById('trainingSelect').selectedIndex;
  249. if (trainingType==TRAININGTYPE.LIGHT) {
  250. GM_addStyle("#singleTrainDiv {display: block}");
  251. GM_addStyle("#multiTrainDiv {display: none}");
  252. } else if (trainingType==TRAININGTYPE.NORMAL) {
  253. GM_addStyle("#singleTrainDiv {display: block}");
  254. GM_addStyle("#multiTrainDiv {display: none}");
  255. } else if (trainingType==TRAININGTYPE.INTENSE) {
  256. GM_addStyle("#singleTrainDiv {display: block}");
  257. GM_addStyle("#multiTrainDiv {display: none}");
  258. } else if (trainingType==TRAININGTYPE.MULTI) {
  259. GM_addStyle("#singleTrainDiv {display: none}");
  260. GM_addStyle("#multiTrainDiv {display: block}");
  261. }
  262. updateTrainingPrediction();
  263. }
  264. // container for the single training drop down
  265. var singleTrainDiv = addElement('div', 'singleTrainDiv', trainingDiv);
  266. var singleTrainSelect = addElement('select', 'singleTrainSelect', singleTrainDiv);
  267. fillAttributeDropdown(singleTrainSelect);
  268. singleTrainSelect.addEventListener("change", updateTrainingPrediction, true);
  269.  
  270. // container for the multi training drop downs
  271. var multiTrainDiv = addElement('div', 'multiTrainDiv', trainingDiv);
  272. GM_addStyle("#multiTrainDiv {display: none}");
  273.  
  274. var multiTrainSelect1 = addElement('select', 'multiTrainSelect1', multiTrainDiv);
  275. addElement('option', null, multiTrainSelect1, {value: null, innerHTML: 'None'});
  276. fillAttributeDropdown(multiTrainSelect1, 'mt1');
  277. multiTrainSelect1.value = "";
  278. multiTrainSelect1.addEventListener("change", multiTrainSelectChanged, true);
  279.  
  280. var multiTrainSelect2 = addElement('select', 'multiTrainSelect2', multiTrainDiv);
  281. addElement('option', null, multiTrainSelect2, {value: null, innerHTML: 'None'});
  282. multiTrainSelect2.addEventListener("change", multiTrainSelectChanged, true);
  283.  
  284. var multiTrainSelect3 = addElement('select', 'multiTrainSelect3', multiTrainDiv);
  285. addElement('option', null, multiTrainSelect3, {value: null, innerHTML: 'None'});
  286. multiTrainSelect3.addEventListener("change", multiTrainSelectChanged, true);
  287.  
  288. var multiTrainSelect4 = addElement('select', 'multiTrainSelect4', multiTrainDiv);
  289. addElement('option', null, multiTrainSelect4, {value: null, innerHTML: 'None'});
  290. multiTrainSelect4.addEventListener("change", multiTrainSelectChanged, true);
  291. var trainButton = addElement('input', 'trainButton', trainingDiv, {
  292. type : "button",
  293. value : "Train"
  294. });
  295. trainButton.addEventListener("click", train, true);
  296. GM_addStyle("#trainButton {display: block}");
  297.  
  298. // training prediction text
  299. var trainPredictionSpan = addElement('span', 'trainPredictionSpan', trainingDiv);
  300. trainPredictionSpan.innerHTML="Training Prediction";
  301.  
  302. var enhanceTrainingButton = addElement('input', 'enhanceTrainingButton', trainingDiv, {
  303. type : "button",
  304. value : "Buy Training Enhancements"
  305. });
  306. enhanceTrainingButton.addEventListener("click", enhanceTraining, true);
  307. GM_addStyle("#enhanceTrainingButton {display: block}");
  308. var multiTrainingButton = addElement('input', 'multiTrainingButton', trainingDiv, {
  309. type : "button",
  310. value : "Buy Multi Training"
  311. });
  312. multiTrainingButton.addEventListener("click", multiTraining, true);
  313. GM_addStyle("#multiTrainingButton {display: block}");
  314.  
  315. var span = document.createElement('span');
  316. span.id="autoTrainSpan";
  317. span.innerHTML = "Auto Train when points are available : ";
  318. trainingDiv.appendChild(span);
  319. var autoTrainBox = document.createElement('input');
  320. autoTrainBox.id = "autoTrainBox";
  321. autoTrainBox.type = "checkbox";
  322. autoTrainBox.addEventListener("click", function() {
  323. autoTrain = document.getElementById("autoTrainBox").checked;
  324. }, true);
  325. trainingDiv.appendChild(autoTrainBox);
  326. autoTrainBox.checked = autoTrain;
  327. GM_addStyle("#trainingDiv {display: none}");
  328.  
  329. addElement('hr', null, containerDiv);
  330.  
  331. var serializeButton = addElement('input', "serializeButton", containerDiv, {
  332. type: "button",
  333. value: "Generate a key for this build"
  334. });
  335. serializeButton.addEventListener("click", getSerializedBuild, true);
  336. GM_addStyle("#serializeButton {display: none}");
  337.  
  338. var printFriendlyButton = addElement('input', "printFriendlyButton", containerDiv, {
  339. type: "button",
  340. value: "Create Print Friendly text"
  341. });
  342. printFriendlyButton.addEventListener("click", getPrintFriendlyText, true);
  343. GM_addStyle("#printFriendlyButton {display: none}");
  344.  
  345.  
  346. var position;
  347. var season = 0;
  348. var level = -1;
  349. var xp = 0;
  350. var day = 1;
  351. var tp = 0;
  352. var availableBoosts = 0;
  353. var buildFromScratch = true;
  354. var vaxp = 0;
  355. var va = 0;
  356. var age = 0;
  357. var playerId = parsePlayerId();
  358.  
  359. /*
  360.  
  361. weightOptions: the number of increments on each side of the weight slider not including 0.
  362. EX: weightOptions = 4 means there's 9 possible weights for the position.
  363. */
  364. var positionData = {
  365. qb_pocket_passer: {
  366. majors: ["confidence","throwing","vision"],
  367. minors: ["agility","stamina","strength", "carrying"],
  368. weightOptions: 18,
  369. heightOptions: 3
  370. },
  371. qb_deep_passer: {
  372. majors: ["strength","throwing","vision"],
  373. minors: ["agility","stamina","confidence", "carrying"],
  374. weightOptions: 18,
  375. heightOptions: 3
  376. },
  377. qb_scrambler: {
  378. majors: ["agility","throwing","vision"],
  379. minors: ["confidence","speed","strength", "carrying"],
  380. weightOptions: 18,
  381. heightOptions: 3
  382. },
  383. hb_power_back: {
  384. majors: ["agility","carrying","confidence", "strength"],
  385. minors: ["jumping","speed","stamina","vision"],
  386. weightOptions: 22,
  387. heightOptions: 2
  388. },
  389. hb_elusive_back: {
  390. majors: ["agility","carrying","speed", "vision"],
  391. minors: ["catching","confidence","stamina","strength"],
  392. weightOptions: 22,
  393. heightOptions: 2
  394. },
  395. hb_scat_back: {
  396. majors: ["agility","catching","speed", "carrying"],
  397. minors: ["vision","confidence","stamina","jumping"],
  398. weightOptions: 22,
  399. heightOptions: 2
  400. },
  401. hb_combo_back: {
  402. majors: ["carrying","confidence","speed", "strength", "vision"],
  403. minors: ["agility","catching","stamina","jumping"],
  404. weightOptions: 22,
  405. heightOptions: 2
  406. },
  407. hb_returner: {
  408. majors: ["carrying","stamina","speed", "agility", "vision"],
  409. minors: ["confidence","strength","jumping"],
  410. weightOptions: 22,
  411. heightOptions: 2
  412. },
  413. hb_special_teamer: {
  414. majors: ["blocking","stamina","speed", "agility", "tackling"],
  415. minors: ["confidence","strength","vision"],
  416. weightOptions: 22,
  417. heightOptions: 2
  418. },
  419. fb_rusher: {
  420. majors: ["agility","carrying","confidence", "strength"],
  421. minors: ["blocking","speed","stamina","vision"],
  422. weightOptions: 22,
  423. heightOptions: 2
  424. },
  425. fb_blocker: {
  426. majors: ["agility","blocking","strength", "vision"],
  427. minors: ["carrying","confidence","stamina","speed"],
  428. weightOptions: 22,
  429. heightOptions: 2
  430. },
  431. fb_combo_back: {
  432. majors: ["agility","carrying","blocking", "strength", "vision"],
  433. minors: ["catching","confidence","speed","jumping"],
  434. weightOptions: 22,
  435. heightOptions: 2
  436. },
  437. fb_scat_back: {
  438. majors: ["agility","catching","speed", "vision"],
  439. minors: ["blocking","confidence","carrying","jumping"],
  440. weightOptions: 22,
  441. heightOptions: 2
  442. },
  443. fb_special_teamer: {
  444. majors: ["agility","stamina","speed", "blocking", "tackling"],
  445. minors: ["strength","confidence","vision"],
  446. weightOptions: 22,
  447. heightOptions: 2
  448. },
  449. wr_speedster: {
  450. majors: ["agility","catching","speed", "vision", "confidence"],
  451. minors: ["carrying","jumping","stamina"],
  452. weightOptions: 9,
  453. heightOptions: 3
  454. },
  455. wr_possession_receiver: {
  456. majors: ["agility","catching","jumping", "vision", "carrying"],
  457. minors: ["confidence","speed","stamina"],
  458. weightOptions: 9,
  459. heightOptions: 3
  460. },
  461. wr_power_receiver: {
  462. majors: ["agility","catching","carrying", "strength", "vision"],
  463. minors: ["confidence","speed","stamina"],
  464. weightOptions: 9,
  465. heightOptions: 3
  466. },
  467. wr_returner: {
  468. majors: ["agility","carrying","speed", "stamina", "vision"],
  469. minors: ["confidence","jumping","strength"],
  470. weightOptions: 9,
  471. heightOptions: 3
  472. },
  473. wr_special_teamer: {
  474. majors: ["agility","blocking","speed", "stamina", "tackling"],
  475. minors: ["strength","confidence","vision"],
  476. weightOptions: 9,
  477. heightOptions: 3
  478. },
  479. te_blocker: {
  480. majors: ["agility","blocking","vision", "strength","confidence"],
  481. minors: ["catching","speed","stamina"],
  482. weightOptions: 9,
  483. heightOptions: 3
  484. },
  485. te_receiver: {
  486. majors: ["agility","speed","catching","vision","carrying"],
  487. minors: ["strength","blocking","stamina"],
  488. weightOptions: 9,
  489. heightOptions: 3
  490. },
  491. te_power_receiver : {
  492. majors: ["agility","strength","catching","confidence","carrying"],
  493. minors: ["speed","blocking","stamina"],
  494. weightOptions: 9,
  495. heightOptions: 3
  496. },
  497. te_dual_threat: {
  498. majors: ["agility","blocking","catching", "strength", "vision"],
  499. minors: ["jumping","confidence","speed"],
  500. weightOptions: 9,
  501. heightOptions: 3
  502. },
  503. te_special_teamer: {
  504. majors: ["agility","blocking","speed", "stamina", "tackling"],
  505. minors: ["strength","confidence","vision"],
  506. weightOptions: 9,
  507. heightOptions: 3
  508. },
  509. c_run_blocker: {
  510. majors: ["strength","blocking","confidence", "vision"],
  511. minors: ["agility", "stamina","speed"],
  512. weightOptions: 9,
  513. heightOptions: 3
  514. },
  515. c_pass_blocker: {
  516. majors: ["agility","blocking","confidence", "vision"],
  517. minors: ["strength", "speed","stamina"],
  518. weightOptions: 9,
  519. heightOptions: 3
  520. },
  521. c_special_teamer: {
  522. majors: ["agility","blocking","speed","stamina","tackling"],
  523. minors: ["confidence","strength","vision"],
  524. weightOptions: 9,
  525. heightOptions: 3
  526. },
  527. g_run_blocker: {
  528. majors: ["strength","blocking","confidence", "vision"],
  529. minors: ["agility", "stamina","speed"],
  530. weightOptions: 9,
  531. heightOptions: 3
  532. },
  533. g_pass_blocker: {
  534. majors: ["agility","blocking","confidence", "vision"],
  535. minors: ["strength", "speed","stamina"],
  536. weightOptions: 9,
  537. heightOptions: 3
  538. },
  539. g_special_teamer: {
  540. majors: ["agility","blocking","speed","stamina","tackling"],
  541. minors: ["confidence","strength","vision"],
  542. weightOptions: 9,
  543. heightOptions: 3
  544. },
  545. ot_run_blocker: {
  546. majors: ["strength","blocking","confidence", "vision"],
  547. minors: ["agility", "stamina","speed"],
  548. weightOptions: 9,
  549. heightOptions: 3
  550. },
  551. ot_pass_blocker: {
  552. majors: ["agility","blocking","confidence", "vision"],
  553. minors: ["strength", "speed","stamina"],
  554. weightOptions: 9,
  555. heightOptions: 3
  556. },
  557. ot_special_teamer: {
  558. majors: ["agility","blocking","speed","stamina","tackling"],
  559. minors: ["confidence","strength","vision"],
  560. weightOptions: 9,
  561. heightOptions: 3
  562. },
  563. dt_run_stuffer: {
  564. majors: ["agility","strength","tackling", "vision"],
  565. minors: ["confidence","stamina","speed"],
  566. weightOptions: 18,
  567. heightOptions: 3
  568. },
  569. dt_pass_rusher: {
  570. majors: ["agility","speed","vision", "tackling"],
  571. minors: ["confidence","stamina","strength"],
  572. weightOptions: 18,
  573. heightOptions: 3
  574. },
  575. dt_combo_tackle: {
  576. majors: ["speed","strength","vision", "tackling"],
  577. minors: ["agility","stamina","confidence"],
  578. weightOptions: 18,
  579. heightOptions: 3
  580. },
  581. dt_special_teamer: {
  582. majors: ["agility","blocking","speed","stamina","tackling"],
  583. minors: ["strength","vision","confidence"],
  584. weightOptions: 18,
  585. heightOptions: 3
  586. },
  587. de_run_stuffer: {
  588. majors: ["agility","strength","tackling","vision"],
  589. minors: ["confidence","stamina","speed"],
  590. weightOptions: 18,
  591. heightOptions: 3
  592. },
  593. de_pass_rusher: {
  594. majors: ["agility","speed","vision","tackling"],
  595. minors: ["confidence","stamina","strength"],
  596. weightOptions: 18,
  597. heightOptions: 3
  598. },
  599. de_combo_end: {
  600. majors: ["speed","strength","vision","tackling"],
  601. minors: ["agility","stamina","confidence"],
  602. weightOptions: 18,
  603. heightOptions: 3
  604. },
  605. de_special_teamer: {
  606. majors: ["agility","blocking","speed","stamina","tackling"],
  607. minors: ["strength","vision","confidence"],
  608. weightOptions: 18,
  609. heightOptions: 3
  610. },
  611. cb_man_specialist: {
  612. majors: ["agility","jumping","speed","vision"],
  613. minors: ["catching","confidence","stamina","tackling"],
  614. weightOptions: 18,
  615. heightOptions: 3
  616. },
  617. cb_zone_specialist: {
  618. majors: ["agility","speed","tackling","vision"],
  619. minors: ["catching","confidence","jumping","stamina"],
  620. weightOptions: 18,
  621. heightOptions: 3
  622. },
  623. cb_hard_hitter: {
  624. majors: ["speed","strength","tackling","vision"],
  625. minors: ["confidence","jumping","agility","stamina"],
  626. weightOptions: 18,
  627. heightOptions: 3
  628. },
  629. cb_combo_corner: {
  630. majors: ["agility","speed","strength","tackling"],
  631. minors: ["confidence","jumping","stamina","vision"],
  632. weightOptions: 18,
  633. heightOptions: 3
  634. },
  635. cb_returner: {
  636. majors: ["agility","carrying","speed","stamina","vision"],
  637. minors: ["confidence","jumping","strength"],
  638. weightOptions: 18,
  639. heightOptions: 3
  640. },
  641. cb_special_teamer: {
  642. majors: ["agility","blocking","speed","stamina","tackling"],
  643. minors: ["confidence","strength","vision"],
  644. weightOptions: 18,
  645. heightOptions: 3
  646. },
  647. ss_man_specialist: {
  648. majors: ["agility","jumping","speed","vision"],
  649. minors: ["catching","confidence","stamina","tackling"],
  650. weightOptions: 18,
  651. heightOptions: 3
  652. },
  653. ss_zone_specialist: {
  654. majors: ["agility","speed","tackling","vision"],
  655. minors: ["catching","confidence","jumping","stamina"],
  656. weightOptions: 18,
  657. heightOptions: 3
  658. },
  659. ss_hard_hitter: {
  660. majors: ["speed","strength","tackling","vision"],
  661. minors: ["confidence","jumping","agility","stamina"],
  662. weightOptions: 18,
  663. heightOptions: 3
  664. },
  665. ss_combo_safety: {
  666. majors: ["agility","speed","strength","tackling"],
  667. minors: ["confidence","jumping","stamina","vision"],
  668. weightOptions: 18,
  669. heightOptions: 3
  670. },
  671. ss_special_teamer: {
  672. majors: ["agility","blocking","speed","stamina","tackling"],
  673. minors: ["confidence","strength","vision"],
  674. weightOptions: 18,
  675. heightOptions: 3
  676. },
  677. fs_man_specialist: {
  678. majors: ["agility","jumping","speed","vision"],
  679. minors: ["catching","confidence","stamina","tackling"],
  680. weightOptions: 18,
  681. heightOptions: 3
  682. },
  683. fs_zone_specialist: {
  684. majors: ["agility","speed","tackling","vision"],
  685. minors: ["catching","confidence","jumping","stamina"],
  686. weightOptions: 18,
  687. heightOptions: 3
  688. },
  689. fs_hard_hitter: {
  690. majors: ["speed","strength","tackling","vision"],
  691. minors: ["confidence","jumping","agility","stamina"],
  692. weightOptions: 18,
  693. heightOptions: 3
  694. },
  695. fs_combo_safety: {
  696. majors: ["agility","speed","strength","tackling"],
  697. minors: ["confidence","jumping","stamina","vision"],
  698. weightOptions: 18,
  699. heightOptions: 3
  700. },
  701. fs_special_teamer: {
  702. majors: ["agility","blocking","speed","stamina","tackling"],
  703. minors: ["confidence","strength","vision"],
  704. weightOptions: 18,
  705. heightOptions: 3
  706. },
  707. lb_coverage_linebacker: {
  708. majors: ["agility","jumping","speed","vision"],
  709. minors: ["confidence","stamina","strength","tackling"],
  710. weightOptions: 18,
  711. heightOptions: 3
  712. },
  713. lb_blitzer: {
  714. majors: ["agility","jumping","speed","tackling"],
  715. minors: ["confidence","stamina","strength","vision"],
  716. weightOptions: 18,
  717. heightOptions: 3
  718. },
  719. lb_hard_hitter: {
  720. majors: ["agility","strength","tackling","vision"],
  721. minors: ["confidence","jumping","speed","stamina"],
  722. weightOptions: 18,
  723. heightOptions: 3
  724. },
  725. lb_combo_linebacker: {
  726. majors: ["agility","speed","tackling","vision", "confidence"],
  727. minors: ["jumping","stamina","strength"],
  728. weightOptions: 18,
  729. heightOptions: 3
  730. },
  731. lb_special_teamer: {
  732. majors: ["agility","blocking","speed","stamina", "tackling"],
  733. minors: ["confidence","strength","vision"],
  734. weightOptions: 18,
  735. heightOptions: 3
  736. },
  737. k_boomer: {
  738. majors: ["confidence","kicking","strength"],
  739. minors: ["jumping","agility","vision"],
  740. weightOptions: 18,
  741. heightOptions: 3
  742. },
  743. k_technician: {
  744. majors: ["confidence","kicking","vision"],
  745. minors: ["jumping","agility","strength"],
  746. weightOptions: 18,
  747. heightOptions: 3
  748. },
  749. p_boomer: {
  750. majors: ["confidence","punting","strength"],
  751. minors: ["jumping","agility","vision"],
  752. weightOptions: 18,
  753. heightOptions: 3
  754. },
  755. p_technician: {
  756. majors: ["confidence","punting","vision"],
  757. minors: ["jumping","agility","strength"],
  758. weightOptions: 18,
  759. heightOptions: 3
  760. },
  761. de_none: {
  762. majors: ["strength","tackling","agility","speed"],
  763. minors: ["blocking","jumping","stamina","vision","confidence"],
  764. weightOptions: 18,
  765. heightOptions: 3
  766. },
  767. dt_none: {
  768. majors: ["strength","tackling","agility"],
  769. minors: ["blocking", "speed", "vision", "stamina", "confidence"],
  770. weightOptions: 33,
  771. heightOptions: 3
  772. },
  773. c_none: {
  774. majors: ["strength","blocking"],
  775. minors: ["tackling", "agility", "stamina", "vision", "confidence"],
  776. weightOptions: 22,
  777. heightOptions: 2
  778. },
  779. g_none: {
  780. majors: ["strength","blocking","confidence"],
  781. minors: ["tackling","agility","stamina","vision"],
  782. weightOptions: 22,
  783. heightOptions: 2
  784. },
  785. ot_none: {
  786. majors: ["strength","blocking","confidence","vision","agility"],
  787. minors: ["tackling","stamina"],
  788. weightOptions: 25,
  789. heightOptions: 3
  790. },
  791. hb_none: {
  792. majors: ["strength","speed","agility","carrying","vision","confidence"],
  793. minors: ["jumping","stamina","blocking","throwing","catching"],
  794. weightOptions: 20,
  795. heightOptions: 2
  796. },
  797. wr_none: {
  798. majors: ["speed","agility","jumping","vision","stamina","catching"],
  799. minors: ["confidence","carrying"],
  800. weightOptions: 11,
  801. heightOptions: 2
  802. },
  803. qb_none: {
  804. majors: ["strength","throwing","stamina","vision","confidence"],
  805. minors: ["speed","agility","jumping","catching","carrying"],
  806. weightOptions: 9,
  807. heightOptions: 3
  808. },
  809. te_none: {
  810. majors: ["strength","blocking","catching","vision"],
  811. minors: ["speed","tackling","agility","stamina","carrying","confidence"],
  812. weightOptions: 22,
  813. heightOptions: 3
  814. },
  815. fb_none: {
  816. majors: ["strength","blocking","agility","carrying"],
  817. minors: ["confidence","vision","stamina","catching","tackling"],
  818. weightOptions: 15,
  819. heightOptions: 3
  820. },
  821. lb_none: {
  822. majors: ["strength","tackling","agility","stamina","vision","confidence"],
  823. minors: ["blocking","speed","jumping","catching"],
  824. weightOptions: 9,
  825. heightOptions: 3
  826. },
  827. cb_none: {
  828. majors: ["speed","agility","jumping","stamina","vision","catching"],
  829. minors: ["strength","tackling","carrying","confidence"],
  830. weightOptions: 11,
  831. heightOptions: 3
  832. },
  833. ss_none: {
  834. majors: ["strength","speed","tackling","stamina","vision"],
  835. minors: ["blocking","agility","jumping","catching","carrying","confidence"],
  836. weightOptions: 13,
  837. heightOptions: 2
  838. },
  839. fs_none: {
  840. majors: ["speed","tackling","catching","stamina","vision"],
  841. minors: ["strength","blocking","agility","jumping","confidence","carrying"],
  842. weightOptions: 13,
  843. heightOptions: 2
  844. },
  845. k_none: {
  846. majors: ["kicking","confidence"],
  847. minors: ["strength","speed","agility","throwing","jumping","vision"],
  848. weightOptions: 22,
  849. heightOptions: 2
  850. },
  851. p_none: {
  852. majors: ["punting","confidence"],
  853. minors: ["strength","speed","agility","throwing","jumping","vision"],
  854. weightOptions: 22,
  855. heightOptions: 2
  856. }
  857. };
  858.  
  859. // dont rearrange these as this order is used for de-serializing saved builds
  860. var minimums = {
  861. qb_pocket_passer:{strength:"10", speed:"8", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"10", catching:"8", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  862. qb_scrambler:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"8", vision:"10", confidence:"10", blocking:"8", throwing:"10", catching:"8", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  863. qb_deep_passer:{strength:"10", speed:"8", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"10", catching:"8", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  864. hb_power_back:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  865. hb_scat_back:{strength:"8", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  866. hb_combo_back:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  867. hb_returner:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  868. hb_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  869. fb_rusher:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  870. fb_blocker:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  871. fb_combo_back:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"8", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"10", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  872. fb_scat_back:{strength:"8", speed:"10", agility:"10", jumping:"10", stamina:"8", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"10", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  873. fb_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  874. te_blocker:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"10", carrying:"8", tackling:"8", kicking:"8", punting:"8"},
  875. te_receiver:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"8", blocking:"10", throwing:"8", catching:"10", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  876. te_power_receiver:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"8", confidence:"10", blocking:"10", throwing:"8", catching:"10", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  877. te_dual_threat:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"8", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"10", carrying:"8", tackling:"8", kicking:"8", punting:"8"},
  878. te_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  879. wr_speedster:{strength:"8", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  880. wr_possession_receiver:{strength:"8", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  881. wr_power_receiver:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  882. wr_returner:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  883. wr_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  884. hb_elusive_back:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  885. dt_run_stuffer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  886. dt_pass_rusher:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  887. dt_combo_tackle:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  888. dt_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  889. de_run_stuffer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  890. de_pass_rusher:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  891. de_combo_end:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  892. de_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  893. cb_man_specialist:{strength:"8", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  894. cb_zone_specialist:{strength:"8", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  895. cb_hard_hitter:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  896. cb_combo_corner:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  897. cb_returner:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"10", tackling:"8", kicking:"8", punting:"8"},
  898. cb_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  899. ss_man_specialist:{strength:"8", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  900. ss_zone_specialist:{strength:"8", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  901. ss_hard_hitter:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  902. ss_combo_safety:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  903. ss_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  904. fs_man_specialist:{strength:"8", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  905. fs_zone_specialist:{strength:"8", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"10", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  906. fs_hard_hitter:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  907. fs_combo_safety:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  908. fs_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  909. lb_coverage_linebacker:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  910. lb_blitzer:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  911. lb_hard_hitter:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  912. lb_combo_linebacker:{strength:"10", speed:"10", agility:"10", jumping:"10", stamina:"10", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  913. lb_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  914. k_boomer:{strength:"10", speed:"8", agility:"10", jumping:"10", stamina:"8", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"8", kicking:"10", punting:"8"},
  915. k_technician:{strength:"10", speed:"8", agility:"10", jumping:"10", stamina:"8", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"8", kicking:"10", punting:"8"},
  916. p_boomer:{strength:"10", speed:"8", agility:"10", jumping:"10", stamina:"8", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"8", kicking:"8", punting:"10"},
  917. p_technician:{strength:"10", speed:"8", agility:"10", jumping:"10", stamina:"8", vision:"10", confidence:"10", blocking:"8", throwing:"8", catching:"8", carrying:"8", tackling:"8", kicking:"8", punting:"10"},
  918. c_pass_blocker:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"8", kicking:"8", punting:"8"},
  919. c_run_blocker:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"8", kicking:"8", punting:"8"},
  920. c_special_teamerr:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  921. c_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  922. g_pass_blocker:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"8", kicking:"8", punting:"8"},
  923. g_run_blocker:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"8", kicking:"8", punting:"8"},
  924. g_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  925. ot_run_blocker:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"8", kicking:"8", punting:"8"},
  926. ot_pass_blocker:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"8", kicking:"8", punting:"8"},
  927. ot_special_teamer:{strength:"10", speed:"10", agility:"10", jumping:"8", stamina:"10", vision:"10", confidence:"10", blocking:"10", throwing:"8", catching:"8", carrying:"8", tackling:"10", kicking:"8", punting:"8"},
  928. de_none:{strength : 10, blocking : 10, speed : 10, tackling : 10, agility : 10, throwing : 8, jumping : 10, catching : 8, stamina : 10, carrying : 8, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  929. dt_none:{strength : 10, blocking : 10, speed : 10, tackling : 10, agility : 10, throwing : 8, jumping : 8, catching : 8, stamina : 10, carrying : 8, vision : 10, kicking : 8, confidence : 10, "punting": 8},
  930. c_none:{strength : 10, blocking : 10, speed : 8, tackling : 10, agility : 10, throwing : 8, jumping : 8, catching : 8, stamina : 10, carrying : 8, vision : 10, kicking : 8, confidence : 10, "punting": 8},
  931. g_none:{strength : 10, blocking : 10, speed : 8, tackling : 10, agility : 10, throwing : 8, jumping : 8, catching : 8, stamina : 10, carrying : 8, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  932. ot_none:{strength : 10, blocking : 10, speed : 8, tackling : 10, agility : 10, throwing : 8, jumping : 8, catching : 8, stamina : 10, carrying : 8, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  933. hb_none:{strength : 10, blocking : 10, speed : 10, tackling : 10, agility : 10, throwing : 8, jumping : 10, catching : 10, stamina : 10, carrying : 10, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  934. wr_none:{strength : 8, blocking : 8, speed : 10, tackling : 8, agility : 10, throwing : 8, jumping : 10, catching : 10, stamina : 10, carrying : 10, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  935. te_none:{strength : 10, blocking : 10, speed : 10, tackling : 10, agility : 10, throwing : 8, jumping : 8, catching : 10, stamina : 10, carrying : 10, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  936. fb_none:{strength : 10, blocking : 10, speed : 8, tackling : 10, agility : 10, throwing : 8, jumping : 8, catching : 10, stamina : 10, carrying : 10, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  937. qb_none:{strength : 10, blocking : 8, speed : 10, tackling : 8, agility : 10, throwing : 10, jumping : 10, catching : 10, stamina : 10, carrying : 10, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  938. lb_none:{strength : 10, blocking : 10, speed : 10, tackling : 10, agility : 10, throwing : 8, jumping : 10, catching : 10, stamina : 10, carrying : 8, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  939. cb_none:{strength : 10, blocking : 8, speed : 10, tackling : 10, agility : 10, throwing : 8, jumping : 10, catching : 10, stamina : 10, carrying : 10, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  940. ss_none:{strength : 10, blocking : 10, speed : 10, tackling : 10, agility : 10, throwing : 8, jumping : 10, catching : 10, stamina : 10, carrying : 10, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  941. fs_none:{strength : 10, blocking : 10, speed : 10, tackling : 10, agility : 10, throwing : 8, jumping : 10, catching : 10, stamina : 10, carrying : 10, vision : 10, kicking : 8, confidence : 10, "punting" : 8},
  942. p_none:{strength : 10, blocking : 8, speed : 10, tackling : 8, agility : 10, throwing : 10, jumping : 10, catching : 8, stamina : 8, carrying : 8, vision : 10, kicking : 8, confidence : 10, "punting" : 10},
  943. k_none:{strength : 10, blocking : 8, speed : 10, tackling : 8, agility : 10, throwing : 10, jumping : 10, catching : 8, stamina : 8, carrying : 8, vision : 10, kicking : 10, confidence : 10, "punting" : 8}
  944. }
  945.  
  946. var trainingStatus = {};
  947. var trainingUpgrades = {};
  948.  
  949.  
  950. function reset() {
  951. // remove the submit button to prevent any real SP spending
  952. var s = document.getElementById('submit');
  953. s.innerHTML = "Submit button removed by the GLB Player Builder Script. Refresh the page to get it back.";
  954.  
  955. //remove the current player's name to be less confusing
  956. document.getElementById("player_vitals").childNodes[1].innerHTML = "Simulated Player | Position: "+getPosition();
  957.  
  958. if (getIsBuildFromScratch()) {
  959. //var tmpSP = 157;
  960. var tmpSP = 157-8;
  961. for (k in minimums[getPosition()]) {
  962. setAtt(k, minimums[getPosition()][k]);
  963. tmpSP -= minimums[getPosition()][k];
  964.  
  965. //reset the training status to 0%
  966. setTrainingStatus(k, 0);
  967. }
  968. setTP(8);
  969. setXP(0);
  970. setDay(1);
  971. setAge(0);
  972. setLevel(-1);
  973. setVA(0);
  974. setVAXP(0);
  975. setSP(tmpSP);
  976. setBoosts(0);
  977. setBonusTokens(12);
  978. resetSAs();
  979. resetTrainingUpgrades();
  980. setBoostCount(0);
  981. }
  982. if (getAge() < plateau_age) {
  983. // no need to show button for plateau players
  984. turnOnGameXP();
  985. }
  986. enableOddDayGames();
  987. setDesiredBT(0);
  988. setSeason(0);
  989. //loadBoostCount(); // Need a routine to pull number of boosts from build
  990. if (getLevel() == -1 || !automaticSeasonChange) {
  991. GM_addStyle("#startSeasonButton {display: block}");
  992. }
  993. }
  994.  
  995. function resetTrainingUpgrades() {
  996. trainingUpgrades = {};
  997. for (var t=0; t<attributeTrainingOptions.length; t++) {
  998. trainingUpgrades[attributeTrainingOptions[t]] = {enhance: 0, multi: false};
  999. }
  1000. disableMultiTraining();
  1001. }
  1002.  
  1003. function startBuilder() {
  1004. var resetBuild = confirm("Do you want to start the build from scratch or start with this player's level, position, and attributes?\n\nHit OK to reset everything\nHit Cancel to use this player's existing build.");
  1005. setIsBuildFromScratch(resetBuild);
  1006. if (getIsBuildFromScratch()) {
  1007. //log("Creating a player from scratch is not implemented yet.", true);
  1008. //return;
  1009. p = requestPosition();
  1010. if (p) {
  1011. GM_addStyle(".playerhead {color: white}");
  1012. GM_addStyle("#startBuilderButton {display: none}");
  1013. GM_addStyle("#trainingDiv {display: block}");
  1014. if (!disableSerialization) {
  1015. GM_addStyle("#serializeButton {display: block}");
  1016. }
  1017. setPosition(p);
  1018. reset();
  1019. showIntialPointsPrompt();
  1020. startSeasonButton.value = "Pick Height and Weight";
  1021. }
  1022. } else {
  1023. var playerId = parsePlayerId();
  1024. getInetPage("/game/player.pl?player_id="+playerId, parsePlayerPage);
  1025. }
  1026. }
  1027.  
  1028. function showIntialPointsPrompt() {
  1029. alert('Spend your initial skill points first.\n\nThis represents your player\'s initial roll.\n\nAll attributes are already set to '+getPosition()+' minimums.');
  1030. }
  1031.  
  1032. function parsePlayerId() {
  1033. var pid = window.location.search;
  1034. pid = pid.slice(pid.indexOf('player_id=')+'player_id='.length);
  1035. if (pid.indexOf('&') > -1) {
  1036. pid = pid.slice(0,pid.indexOf('&'));
  1037. } else {
  1038. pid = pid.slice(0);
  1039. }
  1040. return pid;
  1041. }
  1042.  
  1043. function dump(txt) {
  1044. if (console.clear) {
  1045. console.clear();
  1046. }
  1047. log(txt);
  1048. }
  1049.  
  1050. /*
  1051. * get their position, level, current xp
  1052. */
  1053. function parsePlayerPage(address, page) {
  1054. var txt = page.responseText;
  1055. if (txt.indexOf('<span>Vet Pts:</span>') >-1) {
  1056. var vasplit = txt.split('<span>Vet Pts:</span>');
  1057. va = vasplit[1].substring(vasplit[1].indexOf('>')+1,vasplit[1].indexOf('</a>'));
  1058. }
  1059. else {
  1060. va=0;
  1061. }
  1062.  
  1063. // get player position from the page
  1064. var positionRegex = /\/archetypes\/(\w+).png/gi;
  1065. var result = positionRegex.exec(txt);
  1066. if (result != null && result.length > 1) {
  1067. var p = result[1];
  1068. if (positionData[p]!=null && minimums[p]) {
  1069. setPosition(p);
  1070. }
  1071. else {
  1072. log("This player's archetype ["+p+"] is not implemented.", true);
  1073. return;
  1074. }
  1075. } else {
  1076. log("Unable to load the player's archetype", true);
  1077. dump(txt);
  1078. return;
  1079. }
  1080. GM_addStyle(".playerhead {color: white}");
  1081. GM_addStyle("#startBuilderButton {display: none}");
  1082. GM_addStyle("#nextDayButton {display: inline}");
  1083. GM_addStyle("#startSeasonButton {display: none}");
  1084. GM_addStyle("#trainingDiv {display: block}");
  1085. if (!disableSerialization) {
  1086. GM_addStyle("#serializeButton {display: block}");
  1087. }
  1088. GM_addStyle("#printFriendlyButton {display: block}");
  1089. GM_addStyle("#btWarningDiv {display: block}");
  1090.  
  1091. // get the training statii (sp?)
  1092. for (k in minimums[getPosition()]) {
  1093. //fix from Bogleg
  1094. var re = new RegExp(k + ' training progress: (\\d+)%', 'i');
  1095. var results = re.exec(txt);
  1096. if (results != null && results.length > 0 && !isNaN(parseInt(results[1]))) {
  1097. setTrainingStatus(k, parseInt(results[1]));
  1098. } else {
  1099. log('Failed to parse the training status of '+k, true);
  1100. return;
  1101. }
  1102. }
  1103.  
  1104. // get player creation day
  1105. var creationDayResult = /Season\s+\d+,\s+day\s+(\d+)/gi.exec(txt);
  1106. setCreatedDay(creationDayResult[1]);
  1107.  
  1108. var ageRegExResult = /(\d+)d old/gi.exec(txt);
  1109. setAge(parseInt(ageRegExResult[1]));
  1110.  
  1111. var regexResult = /player_points_value\D*?(\d+)\D*?(\d+)\D*?(\d+)\D*?(\d+)\D*?(?:.|\n)*?Next Level.*?(\d+)\/1000\D+Vet Pts\D+\d+\D+(\d+)/gi.exec(txt);
  1112. if (regexResult == null) {
  1113. // player is too low level to have VAs
  1114. regexResult = /player_points_value\D*?(\d+)\D*?(\d+)\D*?(\d+)\D*?(\d+)\D*?(?:.|\n)*?Next Level.*?(\d+)\/1000\D+/gi.exec(txt);
  1115. }
  1116. if (regexResult == null) {
  1117. // player is too old, that last regex fails for plateau players that don't have 'Next Level'
  1118. regexResult = /player_points_value\D*(\d+)\D*(\d+)\D*?(\d+)\D*?(\d+)\D*?(?:.|\n)*?Remaining XP/gi.exec(txt);
  1119. }
  1120. setLevel(parseInt(regexResult[1]));
  1121. setSP(parseInt(regexResult[2]));
  1122. setTP(parseInt(regexResult[3]));
  1123. setBonusTokens(parseInt(regexResult[4]));
  1124. if (regexResult[5] != null) {
  1125. setXP(parseInt(regexResult[5]));
  1126. } else {
  1127. setXP(0);
  1128. }
  1129. if (regexResult[6] != null) {
  1130. setVA(parseInt(regexResult[6]));
  1131. } else {
  1132. setVA(0);
  1133. }
  1134.  
  1135. // get the current day and reset the rest
  1136. getInetPage("/game/home.pl", parseCurrentDay);
  1137. }
  1138.  
  1139. /*
  1140. parses the day and player xp from the agent's homepage
  1141. */
  1142. function parseCurrentDay(address, page) {
  1143. var txt = page.responseText;
  1144.  
  1145. // first just get to the player section
  1146. var playersplit = txt.split('<div id="players">')[1];
  1147. // now look for players, assuming the grid style
  1148. var stopTryingGridStyle = false;
  1149. vasplit = playersplit.split('\/game\/player\.pl\?player\_id\='+playerId+'"')[1];
  1150. vasplit = vasplit.split('<div class="player_xp">')[2];
  1151. if (vasplit != null) {
  1152. vasplit = vasplit.substring(0, vasplit.indexOf('</div>'));
  1153. vaxp = vasplit.substring(0,vasplit.indexOf('/'));
  1154. } else {
  1155. // the homepage must be using the list style, try parsing like that
  1156. // split off anything before the player's row in the list
  1157. vasplit = playersplit.split('\/game\/player\.pl\?player\_id\='+playerId+'"')[1];
  1158. vasplit = vasplit.split('\<td class\=\"list_vxp"\>')[1];
  1159. vasplit = vasplit.substring(0, vasplit.indexOf('</td>'));
  1160. if (vasplit != null) {
  1161. vaxp = vasplit;
  1162. } else {
  1163. alert('failed to retrieve VA XP from the agent\'s homepage');
  1164. }
  1165. }
  1166. setVAXP(parseInt(vaxp));
  1167.  
  1168. txt = txt.slice(txt.indexOf(', Day ')+5);
  1169. var d = txt.substring(0,txt.indexOf('</div>'));
  1170. setDay(parseInt(d));
  1171. getInetPage("/game/bonus_tokens.pl?player_id="+playerId, loadTrainingUpgrades);
  1172. }
  1173.  
  1174. function loadTrainingUpgrades(address, page) {
  1175. resetTrainingUpgrades();
  1176. var txt = page.responseText;
  1177. var enhanceRegex = /<img.*stars_level_(\d+).*enhanced_(\w+)_level.*>/gi;
  1178. var done = false;
  1179. while (!done) {
  1180. result = enhanceRegex.exec(txt);
  1181. if (result==null) {
  1182. done = true;
  1183. } else {
  1184. trainingUpgrades[result[2]].enhance = parseInt(result[1])*10;
  1185. }
  1186. }
  1187. // get attributes available for multi training
  1188. var multiRegex = /<img.*secondary_(\w+)_level.*star_full.*>/gi;
  1189. done = false;
  1190. while (!done) {
  1191. result = multiRegex.exec(txt);
  1192. if (result==null) {
  1193. done = true;
  1194. } else {
  1195. // add the new attribute option to the 3 drop downs and
  1196. // enable the multi training type if this is the first one enabled
  1197. enableMultiTrainAttribute(result[1]);
  1198. }
  1199. }
  1200. // attributes not available for training
  1201. var notMultiRegex = /<img.*secondary_(\w+)_level.*star_empty.*>/gi;
  1202. done = false;
  1203. while (!done) {
  1204. result = notMultiRegex.exec(txt);
  1205. if (result==null) {
  1206. done = true;
  1207. } else {
  1208. trainingUpgrades[result[1]].multi = false;
  1209. }
  1210. }
  1211. getInetPage("/game/boost_player.pl?player_id="+playerId, loadAvailableBoosts);
  1212. getInetPage("/game/xp_history.pl?player_id="+playerId, loadBoostCount);
  1213. }
  1214.  
  1215. /*
  1216. *
  1217. */
  1218. function loadAvailableBoosts(address, page) {
  1219. var txt = page.responseText;
  1220. var availableBoostsRegex = /Available Level Ups\D+(\d+)/gi;
  1221. var result = availableBoostsRegex.exec(txt);
  1222. if (result!=null && result.length>1) {
  1223. log('available boosts = '+result[1]);
  1224. setBoosts(result[1]);
  1225. } else {
  1226. log("Failed to load the player's remaining boosts for this season. Defaulting to use the maximum.", true);
  1227. setBoosts(max_boosts_per_season);
  1228. }
  1229. reset();
  1230. }
  1231.  
  1232. function loadBoostCount(address, page) {
  1233. var txt2 = page.responseText;
  1234. var boostCountRegex = /[0-9] Boosts x 1000 =\D+(\d+)/gi;
  1235. var result2 = boostCountRegex.exec(txt2);
  1236. if (result2!=null && result2.length>1) {
  1237. log('boost count = '+(result2[1]/1000));
  1238. setBoostCount(parseInt((result2[1]/1000)));
  1239. } else {
  1240. log(result2 + " Failed to load the player's current boost count. Defaulting to 0.", true);
  1241. setBoostCount(0);
  1242. }
  1243. reset();
  1244. }
  1245.  
  1246. function promptForHeight() {
  1247. var h = 100;
  1248. var max = positionData[getPosition()].heightOptions;
  1249. // keep trying until they hit cancel or get in range
  1250. while (h!=null && (h > max || h < (-1 * max))) {
  1251. h = prompt("Enter the player's relative height.\n\nMust be a number ranging from -"+max+" to "+max+".\n\n-"+max+" = shortest possible height for your position\n"+max+" = tallest possible height for your position.");
  1252. }
  1253. h = Math.round(h / max * 2 * 100) / 100;
  1254. return h;
  1255. }
  1256.  
  1257. function promptForWeight() {
  1258. var w = 100;
  1259. var max = positionData[getPosition()].weightOptions;
  1260. // keep trying until they hit cancel or get in range
  1261. while (w != null && (w > max || w < (-1 * max))) {
  1262. w = prompt("Enter the player's relative weight.\n\nMust be a number ranging from -"+max+" to "+max+".\n\n-"+max+" = lightest possible weight for your position\n"+max+" = heaviest possible weight for your position.");
  1263. }
  1264. w = Math.round(w / max * 2 * 100)/100;
  1265. return w;
  1266. }
  1267.  
  1268. /*
  1269. return true if all the attributes are below 26. duh.
  1270. */
  1271. function allAttributesUnder26() {
  1272. for (k in minimums[getPosition()]) {
  1273. if (getAtt(k) > 25) {
  1274. alert("Can't start with an attribute above 25. \n\nLower your "+k+" to continue.");
  1275. return false;
  1276. }
  1277. }
  1278. return true;
  1279. }
  1280.  
  1281. function isDefender() {
  1282. var result = /(\w+)\_/gi.exec(getPosition());
  1283. if (result != null && result.length>0 && result[1]!=null) {
  1284. var defenders = ['wr','qb','fb','hb','te','c','g','ot','p'];
  1285. for (var i=0; i < defenders.length; i++) {
  1286. if (result[i]==defenders[i]) {
  1287. return true;
  1288. }
  1289. }
  1290. } else {
  1291. log('bug: can\'t tell if this position is a defender: '+getPosition()+' assuming not a defender so blocking will be effected by weight, not tackling.', true);
  1292. }
  1293. return false;
  1294. }
  1295.  
  1296. function startSeason() {
  1297. if (getLevel() < 0 && getSP() > 0) {
  1298. showIntialPointsPrompt();
  1299. return;
  1300. }
  1301. if (getLevel() < 0 && getSP()==0) {
  1302. if (!allAttributesUnder26()) {
  1303. return;
  1304. }
  1305. var height = promptForHeight();
  1306. if (height == null) {
  1307. return;
  1308. }
  1309. var weight = promptForWeight();
  1310. if (weight == null) {
  1311. return;
  1312. }
  1313. // height adjustments
  1314. setAtt("jumping", getAtt("jumping") + height);
  1315. setAtt("vision", getAtt("vision") + height);
  1316. setAtt("agility", getAtt("agility") - height);
  1317. setAtt("stamina", getAtt("stamina") - height);
  1318. // weight adjustments
  1319. setAtt("strength", getAtt("strength") + weight);
  1320. if (isDefender()) {
  1321. setAtt("tackling", getAtt("tackling") + weight);
  1322. } else {
  1323. setAtt("blocking", getAtt("blocking") + weight);
  1324. }
  1325. setAtt("speed", getAtt("speed") - weight);
  1326. setAtt("stamina", getAtt("stamina") - weight);
  1327. startSeasonButton.value = "Start Season";
  1328. // using level as a 'state' until the intializing is done and it goes above 0
  1329. // -1 means it still needs to assign the starting SP and then pick Height/Weight
  1330. // 0 means the height and weight have been picked, and they need to pick a start day for the season
  1331. commitSPSpending();
  1332. setLevel(0);
  1333. }
  1334. if (getLevel() > 0 && getDay() < 41) {
  1335. alert('You havent finished this season yet.\n\nWait until day 41 to start a new season');
  1336. return;
  1337. }
  1338. // find out how many days of training before games start
  1339. // skip this if using automatic season change and it's not a new player
  1340. // for automatic season change, it will default to the preseason length
  1341. var startDay = (0-preseasonLength);
  1342. if (getLevel()==0 || !automaticSeasonChange) {
  1343. startDay = prompt("Enter a day to start on.\n\nDay 0 will ensure you get the first daily experience of the season and the first game xp.\nAll games are run on odd days.\n\nDay 31 would start you after the last game of the season has been run.\nThe transition from day 39 to 40 is the last daily experience of the season.\n\nEnter negative days to accrue training points before games start.");
  1344. startDay = parseInt(startDay);
  1345. }
  1346. if (isNaN(startDay)) {
  1347. alert('Invalid start day');
  1348. } else if (startDay == null) {
  1349. return;
  1350. } else {
  1351. commitSPSpending();
  1352. setBoosts(max_boosts_per_season);
  1353. setDay(startDay);
  1354. setSeason(season+1);
  1355. startSeasonButton.value = "Next Season";
  1356. if (getLevel() == 0) {
  1357. setSP(getSP() + 15);
  1358. setLevel(1);
  1359. setXP(0);
  1360. }
  1361. GM_addStyle("#nextDayButton {display: inline}");
  1362. GM_addStyle("#printFriendlyButton {display: block}");
  1363. GM_addStyle("#btWarningDiv {display: block}");
  1364. GM_addStyle("#startSeasonButton {display: none}");
  1365. }
  1366. }
  1367.  
  1368. function requestPosition() {
  1369. var msg = "Valid positions: \n";
  1370. for (k in positionData) {
  1371. msg += k+" | ";
  1372. }
  1373. var p = prompt("Enter a Position\n\n"+msg);
  1374. if (p == null || (positionData[p] != null && minimums[p] != null)) {
  1375. return p;
  1376. }
  1377. alert('Invalid position entered: '+p+'\n\n'+msg);
  1378. return requestPosition();
  1379. }
  1380.  
  1381. var dailyXP = {
  1382. 1 : [50,625],
  1383. 2 : [50,625],
  1384. 3 : [50,625],
  1385. 4 : [50,625],
  1386. 5 : [50,625],
  1387. 6 : [50,625],
  1388. 7 : [50,625],
  1389. 8 : [50,625],
  1390. 9 : [50,625],
  1391. 10 : [50,625],
  1392. 11 : [50,625],
  1393. 12 : [50,625],
  1394. 13 : [50,625],
  1395. 14 : [50,625],
  1396. 15 : [50,625],
  1397. 16 : [50,500],
  1398. 17 : [50,500],
  1399. 18 : [50,500],
  1400. 19 : [50,500],
  1401. 20 : [50,500],
  1402. 21 : [50,500],
  1403. 22 : [50,500],
  1404. 23 : [50,500],
  1405. 24 : [50,500],
  1406. 25 : [50,500],
  1407. 26 : [50,500],
  1408. 27 : [50,500],
  1409. 28 : [50,500],
  1410. 29 : [50,500],
  1411. 30 : [50,500],
  1412. 31 : [50,500],
  1413. 32 : [50,375],
  1414. 33 : [50,375],
  1415. 34 : [50,375],
  1416. 35 : [50,375],
  1417. 36 : [50,375],
  1418. 37 : [50,375],
  1419. 38 : [50,375],
  1420. 39 : [50,375],
  1421. 40 : [50,375],
  1422. 41 : [25,375],
  1423. 42 : [25,375],
  1424. 43 : [25,375],
  1425. 44 : [25,375],
  1426. 45 : [25,375],
  1427. 46 : [25,375],
  1428. 47 : [25,375],
  1429. 48 : [25,375],
  1430. 49 : [25,375],
  1431. 50 : [25,375],
  1432. 51 : [25,375],
  1433. 52 : [25,375],
  1434. 53 : [25,250],
  1435. 54 : [25,250],
  1436. 55 : [25,250],
  1437. 56 : [25,250],
  1438. 57 : [25,250],
  1439. 58 : [25,250],
  1440. 59 : [25,250],
  1441. 60 : [25,250],
  1442. 61 : [25,250],
  1443. 62 : [25,250],
  1444. 63 : [25,250],
  1445. 64 : [25,250],
  1446. 65 : [25,250],
  1447. 66 : [25,250],
  1448. 67 : [25,250],
  1449. 68 : [25,250],
  1450. 69 : [25,125]
  1451. }
  1452. var dailyvaxp = {
  1453. 25 : 150,
  1454. 26 : 150,
  1455. 27 : 150,
  1456. 28 : 150,
  1457. 29 : 150,
  1458. 30 : 250,
  1459. 31 : 250,
  1460. 32 : 250,
  1461. 33 : 250,
  1462. 34 : 250,
  1463. 35 : 300,
  1464. 36 : 300,
  1465. 37 : 300,
  1466. 38 : 300,
  1467. 39 : 300,
  1468. 40 : 325
  1469. }
  1470.  
  1471. var maxLevelPerBoost = {
  1472. 79 : 30,
  1473. 78 : 29,
  1474. 77 : 28,
  1475. 76 : 27,
  1476. 75 : 26,
  1477. 74 : 25,
  1478. 73 : 24,
  1479. 72 : 23,
  1480. 71 : 22,
  1481. 70 : 21,
  1482. 69 : 20,
  1483. 68 : 19,
  1484. 67 : 18,
  1485. 66 : 17,
  1486. 65 : 16,
  1487. 64 : 15,
  1488. 63 : 14,
  1489. 62 : 13,
  1490. 61 : 12,
  1491. 60 : 11,
  1492. 60 : 10,
  1493. 60 : 9,
  1494. 60 : 8,
  1495. 60 : 7,
  1496. 60 : 6,
  1497. 60 : 5,
  1498. 60 : 4,
  1499. 60 : 3,
  1500. 60 : 2,
  1501. 60 : 1,
  1502. 60 : 0,
  1503. }
  1504.  
  1505. function incrementDay() {
  1506. var requiredBoosts = maxLevelPerBoost[getLevel()]
  1507.  
  1508. nextDayButton.disabled=true;
  1509. if (getLevel() == 0 && getSP() > 0) {
  1510. showIntialPointsPrompt();
  1511. nextDayButton.disabled=false;
  1512. return;
  1513. }
  1514. if (getAge() >= extended_plateau_age) {
  1515. if ((getLevel()+getBoosts()) < 79) {
  1516. // plateau players can boost to 79
  1517. var addedBoosts = Math.min(79-getBoosts()-getLevel(), 6);
  1518. setBoosts(getBoosts()+ addedBoosts);
  1519. }
  1520. log("You've hit the extended plateau, no point in incrementing the days any further.", true);
  1521. nextDayButton.disabled=false;
  1522. return;
  1523. }
  1524. // save this build incase it needs to be restored
  1525. backupBuild();
  1526. if (automaticSeasonChange && (getDay() >= (offseasonLength+40))) {
  1527. startSeason();
  1528. } else {
  1529. setDay(getDay()+1);
  1530. }
  1531.  
  1532. // move this to after the age has incremented, to use an if command incase the number of days is equal to 281
  1533. // setTP(getTP()+training_points_per_day);
  1534.  
  1535. // daily xp if not in offseason
  1536. if (getDay() > 0 && getDay() < 41) {
  1537. if (getLevel()>39) {
  1538. increaseVAXP(va_xp_factor * 325);
  1539. }
  1540. else if (getLevel()>24 && getLevel() < 40) {
  1541. increaseVAXP(va_xp_factor * dailyvaxp[getLevel()]);
  1542. }
  1543. if (getAge()<plateau_age) {
  1544. if (boost_count <= maxLevelPerBoost[getLevel()]) {
  1545. increaseXP(0)
  1546. } else if (getLevel()<41) {
  1547. increaseXP(daily_xp_factor * dailyXP[getLevel()][0]);
  1548. } else {
  1549. increaseXP(daily_xp_factor * 25);
  1550. }
  1551. }
  1552.  
  1553. // in season, the day counts towards the player's age
  1554. // small oddity, for new players(before their first season)
  1555. // if they were created before day 41 and after day 0, the rollover from day0->1 will age them one day
  1556. // if they were created after day 40, in the offseason, they will not age on that rollover from day 0->1
  1557. if (getAge()!=0 || getDay()!=1 || getCreatedDay()>=41 || getCreatedDay()<=0) {
  1558. setAge(getAge()+1);
  1559. }
  1560. }
  1561.  
  1562. // this conditional should give 2 training points per day, apart from when the player ages 280-281
  1563. if (getAge()<extended_plateau_age) {
  1564. setTP(getTP()+training_points_per_day);
  1565. }
  1566.  
  1567. // game xp, every other day for days 1-31 games
  1568. if (boost_count <= maxLevelPerBoost[getLevel()]) {
  1569. increaseXP(0)
  1570. }
  1571. else if (getDay() > 0 && getDay() <= 32) {
  1572. if ((getDay()%2 == 1 && getGamesOnOddDays()) || (getDay()%2 == 0 && !getGamesOnOddDays())) {
  1573. if (getAge()<plateau_age) {
  1574. if (getLevel()<70) {
  1575. increaseXP(game_xp_factor * dailyXP[getLevel()][1]);
  1576. } else {
  1577. increaseXP(game_xp_factor * 125);
  1578. }
  1579. }
  1580. }
  1581. }
  1582.  
  1583. if (autoTrain) {
  1584. train();
  1585. }
  1586.  
  1587. if (getDay() > 39 && !automaticSeasonChange) {
  1588. GM_addStyle("#startSeasonButton {display: block}");
  1589. }
  1590.  
  1591. commitSPSpending();
  1592.  
  1593. nextDayButton.disabled=false;
  1594. }
  1595.  
  1596. var backupBuildStack = new Array();
  1597. function clearBackups() {
  1598. while (backupBuildStack.length>0) {
  1599. backupBuildStack.pop();
  1600. }
  1601. GM_addStyle("#previousDayButton {display: none}");
  1602. }
  1603.  
  1604. function backupBuild() {
  1605. var b = serializeBuild();
  1606. backupBuildStack.push(b);
  1607. GM_addStyle("#previousDayButton {display: inline}");
  1608. }
  1609.  
  1610. function restoreBuild() {
  1611. GM_addStyle("#previousDayButton {display: none}");
  1612. var tmp = backupBuildStack.pop();
  1613. if (tmp != null) {
  1614. loadBuild(tmp);
  1615. } else {
  1616. log('Can\'t back up anymore', true);
  1617. }
  1618. if (backupBuildStack.length > 0) {
  1619. GM_addStyle("#previousDayButton {display: inline}");
  1620. }
  1621. }
  1622.  
  1623. /*
  1624. * click handler for the button to buy training enhancements
  1625. */
  1626. function enhanceTraining() {
  1627. var promptMsg = 'Enter an attribute to enhance.';
  1628. for (var a=0; a<attributeTrainingOptions.length; a++) {
  1629. var att = attributeTrainingOptions[a];
  1630. var current = trainingUpgrades[att].enhance;
  1631. var btcost = 0;
  1632. if (current == 0) {
  1633. btcost = 6;
  1634. }
  1635. else if (current == 10) {
  1636. btcost = 12;
  1637. }
  1638. else if (current == 20) {
  1639. btcost = 18;
  1640. }
  1641. else if (current == 30) {
  1642. btcost = 24;
  1643. }
  1644. else if (current == 40) {
  1645. btcost = 30;
  1646. }
  1647. if (current<50) {
  1648. //promptMsg += '\n'+att+"\t"+(att!="confidence"?"\t":"")+current+"% > "+(current+10)+"%\tCost:"+ (current+10)/2 +" BT";
  1649. promptMsg += '\n'+att+"\t"+(att!="confidence"?"\t":"")+current+"% > "+(current+10)+"%\tCost:"+ btcost +" BT";
  1650. } else {
  1651. promptMsg += '\n'+att+"\t\tMAXED OUT at "+current+"%";
  1652. }
  1653. }
  1654. var found = false;
  1655. var chosenAttribute = null;
  1656. while (!found) {
  1657. var chosenAttribute = prompt(promptMsg);
  1658. if (chosenAttribute == null) {
  1659. // they hit cancel
  1660. return;
  1661. }
  1662. chosenAttribute = chosenAttribute.toLowerCase();
  1663. var found = false;
  1664. for (var a=0; a<attributeTrainingOptions.length; a++) {
  1665. if (attributeTrainingOptions[a]==chosenAttribute) {
  1666. found = true;
  1667. }
  1668. }
  1669. if (!found) {
  1670. log('['+chosenAttribute+'] is not a valid attribute option', true);
  1671. } else if (trainingUpgrades[chosenAttribute].enhance >= 50) {
  1672. // that attribute is already maxed out
  1673. log('Can not enhance ['+chosenAttribute+'] past 50%', true);
  1674. found = false;
  1675. }
  1676. }
  1677. // CHECK THIS SECTION TO ENSURE BTs ARE REMOVED CORRECTLY!
  1678. //var cost = (trainingUpgrades[chosenAttribute].enhance+10)/2;
  1679. //var b=0; a<attributeTrainingOptions.length;
  1680. //var att1 = attributeTrainingOptions[b];
  1681. var current1 = trainingUpgrades[chosenAttribute].enhance;
  1682. var cost = 0;
  1683. if (current1 == 0) {
  1684. cost = 6;
  1685. }
  1686. else if (current1 == 10) {
  1687. cost = 12;
  1688. }
  1689. else if (current1 == 20) {
  1690. cost = 18;
  1691. }
  1692. else if (current1 == 30) {
  1693. cost = 24;
  1694. }
  1695. else if (current1 == 40) {
  1696. cost = 30;
  1697. }
  1698. if (cost <= getBonusTokens()) {
  1699. setBonusTokens(getBonusTokens()-cost);
  1700. trainingUpgrades[chosenAttribute].enhance = trainingUpgrades[chosenAttribute].enhance+10;
  1701. log("Enhanced "+chosenAttribute+" to "+trainingUpgrades[chosenAttribute].enhance+"%");
  1702. } else {
  1703. log("You don't have enough bonus tokens to enhance "+chosenAttribute+" further. You need "+cost+".", true);
  1704. }
  1705. }
  1706.  
  1707. /**
  1708. * click handler for the button to add buy multi train attributes
  1709. */
  1710. function multiTraining() {
  1711. var promptMsg = 'Enter an attribute to allow in multi-training.';
  1712. var nonMultis = getListOfNonMultiTrainAttributes();
  1713. if (nonMultis.length == 0) {
  1714. log('No attributes left to allow for multi training', true);
  1715. return;
  1716. }
  1717. for (var a=0; a<nonMultis.length; a++) {
  1718. var att = nonMultis[a];
  1719. promptMsg += '\n'+att;
  1720. }
  1721.  
  1722. //var cost = 5 + getListOfMultiTrainAttributes().length*5;
  1723. var cost = (getListOfMultiTrainAttributes().length + 1) * 6;
  1724. promptMsg += '\n\n Cost: '+cost+' Bonus Tokens';
  1725.  
  1726. var chosenAttribute = prompt(promptMsg);
  1727. if (chosenAttribute == null) {
  1728. // they hit cancel
  1729. return;
  1730. }
  1731. chosenAttribute = chosenAttribute.toLowerCase();
  1732. var found = false;
  1733. for (var a=0; a<nonMultis.length; a++) {
  1734. if (nonMultis[a]==chosenAttribute) {
  1735. found = true;
  1736. }
  1737. }
  1738. if (!found) {
  1739. log('['+chosenAttribute+'] is not a valid attribute option', true);
  1740. } else if (cost>getBonusTokens()) {
  1741. log('You don\'t have enough bonus tokens. Need '+cost, true);
  1742. } else {
  1743. setBonusTokens(getBonusTokens()-cost);
  1744. enableMultiTrainAttribute(chosenAttribute);
  1745. }
  1746. }
  1747.  
  1748. /*
  1749. prevents accidentally lowering the SP spent too much
  1750. */
  1751. function commitSPSpending() {
  1752. for (k in minimums["qb_pocket_passer"]) {
  1753. document.getElementById('modifier_' + k).innerHTML = 0;
  1754. document.getElementById('hidden_' + k).value = 0;
  1755. }
  1756. // update the next cap tooltips
  1757. installCapTips();
  1758. }
  1759. /*
  1760. * return map of valid training types
  1761. *
  1762. */
  1763.  
  1764. // TODO - Figure out the calculations in the multi-train section
  1765. function getValidTrainingTypes() {
  1766. // calc max gain not including the next training
  1767. var maxPossible = calcMaxPossibleBTGain();
  1768.  
  1769. var validTrainingTypes = {
  1770. intense : false,
  1771. normal : false,
  1772. light : false,
  1773. multi4 : false,
  1774. multi3 : false,
  1775. multi2 : false
  1776. };
  1777. var neededFromNextTrain = getDesiredBT() - (maxPossible+getBonusTokens());
  1778. if (neededFromNextTrain > 6) {
  1779. // can't make the goal
  1780. return validTrainingTypes;
  1781. } else if (neededFromNextTrain == 6) {
  1782. validTrainingTypes.light = true;
  1783. } else if (neededFromNextTrain == 4) {
  1784. validTrainingTypes.light = true;
  1785. validTrainingTypes.normal = true;
  1786. } else if (neededFromNextTrain == 2) {
  1787. validTrainingTypes.light = true;
  1788. validTrainingTypes.normal = true;
  1789. validTrainingTypes.intense = true;
  1790. } else if (neededFromNextTrain <= 0) {
  1791. validTrainingTypes.light = true;
  1792. validTrainingTypes.normal = true;
  1793. validTrainingTypes.intense = true;
  1794. }
  1795. // see if any multi training can be done
  1796. var maxBTGain_multi4 = maxPossible - 12;
  1797. var neededFromNext4Trains = getDesiredBT() - (maxBTGain_multi4+getBonusTokens());
  1798. if (neededFromNext4Trains <= 12) {
  1799. validTrainingTypes.multi4 = true;
  1800. }
  1801. var maxBTGain_multi3 = maxPossible - 9;
  1802. var neededFromNext3Trains = getDesiredBT() - (maxBTGain_multi3+getBonusTokens());
  1803. if (neededFromNext3Trains <= 8) {
  1804. validTrainingTypes.multi3 = true;
  1805. }
  1806. var maxBTGain_multi2 = maxPossible - 6;
  1807. var neededFromNext2Trains = getDesiredBT() - (maxBTGain_multi2+getBonusTokens());
  1808. if (neededFromNext2Trains <= 4) {
  1809. validTrainingTypes.multi2 = true;
  1810. }
  1811. return validTrainingTypes;
  1812. }
  1813.  
  1814. /*
  1815. * find out how many BTs you can gain if you train on light for the rest of your career
  1816. */
  1817. function calcMaxPossibleBTGain() {
  1818. var a = getAge();
  1819. var d = getDay();
  1820. var trainingDaysLeft = getTP()/2;
  1821. while (a <= plateau_age) {
  1822. // use constants for the length of the offseason and preseason
  1823. d++;
  1824. if (d>(40+offseasonLength)) {
  1825. d = (0-preseasonLength);
  1826. }
  1827. if (d>0 && d<41) {
  1828. a++;//seasonal day, add age
  1829. }
  1830. trainingDaysLeft++;
  1831. }
  1832. return (trainingDaysLeft-1)*6;
  1833. }
  1834.  
  1835. function calcMaxPossiblenormalBTGain() {
  1836. var a = getAge();
  1837. var d = getDay();
  1838. var trainingDaysLeft = getTP()/2;
  1839. while (a <= plateau_age) {
  1840. // use constants for the length of the offseason and preseason
  1841. d++;
  1842. if (d>(40+offseasonLength)) {
  1843. d = (0-preseasonLength);
  1844. }
  1845. if (d>0 && d<41) {
  1846. a++;//seasonal day, add age
  1847. }
  1848. trainingDaysLeft++;
  1849. }
  1850. return (trainingDaysLeft-1)*4;
  1851. }
  1852.  
  1853. function calcMaxPossibleintenseBTGain() {
  1854. var a = getAge();
  1855. var d = getDay();
  1856. var trainingDaysLeft = getTP()/2;
  1857. while (a <= plateau_age) {
  1858. // use constants for the length of the offseason and preseason
  1859. d++;
  1860. if (d>(40+offseasonLength)) {
  1861. d = (0-preseasonLength);
  1862. }
  1863. if (d>0 && d<41) {
  1864. a++;//seasonal day, add age
  1865. }
  1866. trainingDaysLeft++;
  1867. }
  1868. return (trainingDaysLeft-1)*2;
  1869. }
  1870.  
  1871. function calcMaxPossiblemulti4BTGain() {
  1872. var a = getAge();
  1873. var d = getDay();
  1874. var trainingDaysLeft = getTP()/2;
  1875. while (a <= plateau_age) {
  1876. // use constants for the length of the offseason and preseason
  1877. d++;
  1878. if (d>(40+offseasonLength)) {
  1879. d = (0-preseasonLength);
  1880. }
  1881. if (d>0 && d<41) {
  1882. a++;//seasonal day, add age
  1883. }
  1884. trainingDaysLeft++;
  1885. }
  1886. return Math.floor((trainingDaysLeft-1)/4)*12;
  1887. }
  1888.  
  1889. /*
  1890. * start here for doing training, it decides if it needs to do multi or single training,
  1891. * and also checks to see if the BT goal can be reached with the current training selections
  1892. */
  1893. function train() {
  1894. // don't allow training for new player yet
  1895. if (getLevel() == 0 && getSP() > 0) {
  1896. showIntialPointsPrompt();
  1897. return;
  1898. }
  1899. var trainingType = document.getElementById('trainingSelect').value;
  1900. var validTrainings = getValidTrainingTypes();
  1901. if (trainingType==TRAININGTYPE.MULTI) {
  1902. if (!enableDesiredBTCheck || ((getMultiTrainCount()==2 && validTrainings.multi2) ||
  1903. (getMultiTrainCount()==3 && validTrainings.multi3) ||
  1904. (getMultiTrainCount()==4 && validTrainings.multi4))) {
  1905. multiTrain();
  1906. } else {
  1907. log("Training skipped. You can not multi train "+getMultiTrainCount()+" attributes and still reach your BT goal", true);
  1908. return;
  1909. }
  1910. } else {
  1911. if (singleTrainSelect.value == "") {
  1912. log("Need to select an attribute to train", !autoTrain);
  1913. return;
  1914. }
  1915. if (!enableDesiredBTCheck || (trainingType==TRAININGTYPE.INTENSE && validTrainings.intense ||
  1916. trainingType==TRAININGTYPE.NORMAL && validTrainings.normal ||
  1917. trainingType==TRAININGTYPE.LIGHT && validTrainings.light)) {
  1918. singleTrain();
  1919. } else {
  1920. log("Training skipped. You can not do the selected training and still reach your BT goal.", true);
  1921. return;
  1922. }
  1923. }
  1924. updateTrainingPrediction();
  1925. }
  1926. /**
  1927. * Gives an alert with the training gains that would occur in the next training
  1928. */
  1929. function updateTrainingPrediction() {
  1930. var trainingType = document.getElementById('trainingSelect').value;
  1931. if (trainingType==TRAININGTYPE.MULTI) {
  1932. var attsToTrain = []
  1933. if (attributeTrainingOptions.indexOf(multiTrainSelect1.value) != -1) {
  1934. attsToTrain.push(multiTrainSelect1.value);
  1935. }
  1936. if (attributeTrainingOptions.indexOf(multiTrainSelect2.value) != -1) {
  1937. attsToTrain.push(multiTrainSelect2.value);
  1938. }
  1939. if (attributeTrainingOptions.indexOf(multiTrainSelect3.value) != -1) {
  1940. attsToTrain.push(multiTrainSelect3.value);
  1941. }
  1942. if (attributeTrainingOptions.indexOf(multiTrainSelect4.value) != -1) {
  1943. attsToTrain.push(multiTrainSelect4.value);
  1944. }
  1945. if (attsToTrain.length < 2) {
  1946. trainPredictionSpan.innerHTML = "Need to choose at least 2 attributes to multi train";
  1947. return;
  1948. }
  1949. var multiplier = 0;
  1950. if (attsToTrain.length==2) {
  1951. multiplier = 1.05;
  1952. }
  1953. else if (attsToTrain.length==3) {
  1954. multiplier = 1.2;
  1955. }
  1956. else {
  1957. multiplier = 1.3;
  1958. }
  1959. var logMsg = '<b>Multi Train Prediction</b><br/>';
  1960. for (var a=0; a<attsToTrain.length; a++) {
  1961. var gain = calculateTrainingGain(attsToTrain[a], TRAININGTYPE.MULTI, multiplier);
  1962. logMsg += attsToTrain[a]+' : '+gain+'%';
  1963. logMsg += getTrainingWarningMsg(attsToTrain[a], gain);
  1964. }
  1965. trainPredictionSpan.innerHTML = logMsg;
  1966. } else {
  1967. var light = calculateTrainingGain(singleTrainSelect.value, TRAININGTYPE.LIGHT);
  1968. var normal = calculateTrainingGain(singleTrainSelect.value, TRAININGTYPE.NORMAL);
  1969. var intense = calculateTrainingGain(singleTrainSelect.value, TRAININGTYPE.INTENSE);
  1970. var logMsg = '<b>Single Training Prediction</b><br/>'+singleTrainSelect.value+'<br/>';
  1971. logMsg += 'Intense\t: '+intense+'% ';
  1972. logMsg += getTrainingWarningMsg(singleTrainSelect.value, intense);
  1973. logMsg += 'Normal\t: '+normal+'% ';
  1974. logMsg += getTrainingWarningMsg(singleTrainSelect.value, normal);
  1975. logMsg += 'Light\t\t: '+light+'% ';
  1976. logMsg += getTrainingWarningMsg(singleTrainSelect.value, light);
  1977. trainPredictionSpan.innerHTML = logMsg;
  1978. }
  1979. }
  1980. /**
  1981. * returns text to append to training predictions
  1982. */
  1983. function getTrainingWarningMsg(attName, gain) {
  1984. var ret = '';
  1985. if (getTrainingStatus(attName)+gain < 100) {
  1986. if (getTrainingStatus(attName)+(Math.round(gain*1.1)) >= 100) {
  1987. //ret += ' *** Warning : A training breakthrough could cause rollover.<br/>';
  1988. ret += '<br/>';
  1989. } else {
  1990. ret += '<br/>';
  1991. }
  1992. } else {
  1993. ret += ' *** Training will cause rollover.<br/>';
  1994. }
  1995. return ret;
  1996. }
  1997.  
  1998. /**
  1999. * Handles all the rounding involved
  2000. * mandyross is in here, destroying the script
  2001. *
  2002. * attName : attribute name
  2003. *
  2004. * trainingType : TRAININGTYPE.LIGHT, TRAININGTYPE.NORMAL, TRAININGTYPE.INTENSE, TRAININGTYPE.MULTI
  2005. *
  2006. * multiTrainingMultiplier : 1.05, 1.2, 1.3
  2007. */
  2008. function calculateTrainingGain(attName, trainingType, multiTrainingMultiplier) {
  2009. var attVal = (getAtt(attName));
  2010. var oldNormalGain = Math.round(1.6 * 75 * Math.exp(-0.038 * (attVal - 1)))
  2011.  
  2012. var trainingTypeMultiplier = null;
  2013. if (trainingType==TRAININGTYPE.LIGHT) {
  2014. trainingTypeMultiplier = 0.4;
  2015. } else if (trainingType==TRAININGTYPE.NORMAL) {
  2016. trainingTypeMultiplier = 0.85;
  2017. } else if (trainingType==TRAININGTYPE.INTENSE || trainingType==TRAININGTYPE.MULTI) {
  2018. trainingTypeMultiplier = 1.2;
  2019. } else {
  2020. alert('something went wrong, calculateTrainingGain() had an invalid training type: ['+trainingType+']');
  2021. return 0;
  2022. };
  2023.  
  2024. if (attVal >= 100) {
  2025. oldNormalGain = 1;
  2026. }
  2027.  
  2028. var ret = Math.round(oldNormalGain * trainingTypeMultiplier);
  2029. ret = Math.round(ret * getEnhancement(attName));
  2030.  
  2031. if (ret == 0) {
  2032. ret = 1;
  2033. }
  2034.  
  2035. if (trainingType==TRAININGTYPE.MULTI) {
  2036. ret = Math.round(oldNormalGain * 1.2) * getEnhancement(attName);
  2037. ret = Math.round(ret * multiTrainingMultiplier);
  2038. if (ret == 0) {
  2039. ret = 1;
  2040. }
  2041. }
  2042. return ret;
  2043. }
  2044. /*
  2045. * get number of attributes being multi trained
  2046. */
  2047. function getMultiTrainCount() {
  2048. var count = 0;
  2049. if (attributeTrainingOptions.indexOf(multiTrainSelect1.value) != -1) {
  2050. count ++;
  2051. }
  2052. if (attributeTrainingOptions.indexOf(multiTrainSelect2.value) != -1) {
  2053. count ++;
  2054. }
  2055. if (attributeTrainingOptions.indexOf(multiTrainSelect3.value) != -1) {
  2056. count ++;
  2057. }
  2058. if (attributeTrainingOptions.indexOf(multiTrainSelect4.value) != -1) {
  2059. count ++;
  2060. }
  2061. return count;
  2062. }
  2063. /**
  2064. * applies training gain to the selected attribute
  2065. *
  2066. * subtracts the TP cost
  2067. *
  2068. * adds BT gain
  2069. *
  2070. * attempts to train again if TP remains
  2071. */
  2072. function singleTrain() {
  2073. var tpCost = 2;
  2074. if (tpCost > getTP()) {
  2075. if (!autoTrain) {
  2076. log('Not enough training points. Need '+tpCost, true);
  2077. }
  2078. } else {
  2079. var trainingType = document.getElementById('trainingSelect').value;
  2080. var btGain = 0;
  2081. if (trainingType==TRAININGTYPE.LIGHT) {
  2082. btGain = 6;
  2083. }
  2084. else if (trainingType==TRAININGTYPE.NORMAL) {
  2085. btGain = 4;
  2086. }
  2087. else if (trainingType==TRAININGTYPE.INTENSE) {
  2088. btGain = 2;
  2089. }
  2090. var increase = calculateTrainingGain(singleTrainSelect.value, trainingType);
  2091.  
  2092. if (trainAttribute(singleTrainSelect.value, increase)) {
  2093. setTP(getTP()-tpCost);
  2094. setBonusTokens(getBonusTokens()+btGain);
  2095. // keep training if there's left over TP
  2096. if (autoTrain) {
  2097. train();
  2098. }
  2099. }
  2100. }
  2101. }
  2102. /**
  2103. * returns the current enhancement bonus for a given attribute name
  2104. *
  2105. * ranges from 1.0-1.5
  2106. */
  2107. function getEnhancement(attributeName) {
  2108. return (1+(trainingUpgrades[attributeName].enhance / 100 )).toFixed(2);
  2109. }
  2110. /**
  2111. * applies training gains to the multi trained atributes
  2112. *
  2113. * subtracts TP cost
  2114. *
  2115. * adds bonus tokens
  2116. *
  2117. * loops back to train more if training points remain
  2118. */
  2119. function multiTrain() {
  2120. var attsToTrain = [];
  2121. if (attributeTrainingOptions.indexOf(multiTrainSelect1.value) != -1) {
  2122. attsToTrain.push(multiTrainSelect1.value);
  2123. }
  2124. if (attributeTrainingOptions.indexOf(multiTrainSelect2.value) != -1) {
  2125. attsToTrain.push(multiTrainSelect2.value);
  2126. }
  2127. if (attributeTrainingOptions.indexOf(multiTrainSelect3.value) != -1) {
  2128. attsToTrain.push(multiTrainSelect3.value);
  2129. }
  2130. if (attributeTrainingOptions.indexOf(multiTrainSelect4.value) != -1) {
  2131. attsToTrain.push(multiTrainSelect4.value);
  2132. }
  2133. if (attsToTrain.length < 2) {
  2134. log("Need to choose at least 2 attributes to multi train", true);
  2135. return;
  2136. }
  2137. var cost = 2*attsToTrain.length;
  2138.  
  2139. if (cost > getTP()) {
  2140. if (!autoTrain) {
  2141. log('Not enough training points. Need '+cost, true);
  2142. }
  2143. } else {
  2144. var multiplier = 0;
  2145. if (attsToTrain.length==2) {
  2146. multiplier = 1.05;
  2147. }
  2148. else if (attsToTrain.length==3) {
  2149. multiplier = 1.2;
  2150. }
  2151. else {
  2152. multiplier = 1.3;
  2153. }
  2154.  
  2155. // single train each one with the increased multiplier
  2156. for (var a=0; a<attsToTrain.length; a++) {
  2157. var increase = calculateTrainingGain(attsToTrain[a], TRAININGTYPE.MULTI, multiplier);
  2158. increase = Math.round(increase * 10) / 10;
  2159. trainAttribute(attsToTrain[a], increase);
  2160. }
  2161. // subtract tp
  2162. setTP(getTP() - cost);
  2163. // add bonus tokens
  2164. //setBonusTokens(getBonusTokens()+((attsToTrain.length-1)*2));
  2165. setBonusTokens(getBonusTokens()+((attsToTrain.length-1)*4));
  2166.  
  2167. // keep training if there's left over TP
  2168. if (autoTrain) {
  2169. train();
  2170. }
  2171. }
  2172. }
  2173.  
  2174. /**
  2175. * increases the attribute's trained amount
  2176. */
  2177. function trainAttribute(attribute, increase) {
  2178. if (isNaN(increase)) {
  2179. alert('Pick a different attribute to train.\n\nThis script hasnt defined a training percentage for an attribute that high');
  2180. return false;
  2181. }
  2182. var new_status = increase + getTrainingStatus(attribute);
  2183. new_status = Math.round(new_status * 10) / 10;
  2184. if (new_status >= 200) {
  2185. new_status -= 200;
  2186. new_status = Math.round(new_status * 10) / 10; // this should round the training percent to one decimal place...I am unsure of how formatting will work
  2187. setAtt(attribute, getAtt(attribute)+2);
  2188. } else if (new_status >= 100) {
  2189. new_status -= 100;
  2190. new_status = Math.round(new_status * 10) / 10; // this should round the training percent to one decimal place...I am unsure of how formatting will work
  2191. setAtt(attribute, getAtt(attribute)+1);
  2192. }
  2193. if (logTrainingCalcs) {
  2194. log("increased "+attribute+" by "+increase+"%");
  2195. }
  2196. setTrainingStatus(attribute, new_status);
  2197. return true;
  2198. }
  2199.  
  2200. function increaseXP(addedXP) {
  2201. setXP(xp+addedXP);
  2202.  
  2203. if (addedXP == 1000 && boost_count == 25) sp_increase = 26;
  2204. else if (addedXP == 1000) sp_increase = 6;
  2205. else sp_increase = 5;
  2206.  
  2207. // level up
  2208. if (xp >= 1000) {
  2209. setXP(xp-1000);
  2210. setLevel(getLevel()+1);
  2211. // add 5 SP
  2212. setSP(getSP() + sp_increase);
  2213. // add VA points if hitting level 25
  2214. if (getLevel()==25) {
  2215. setVA(2);
  2216. }
  2217. // add auto gains
  2218. var major;
  2219. var minor;
  2220. if (getLevel()<22) {
  2221. major=2;
  2222. minor=1;
  2223. } else if (getLevel()<30) {
  2224. major = 1.5;
  2225. minor = 0.75;
  2226. } else if (getLevel()<38) {
  2227. major = 1.125;
  2228. minor = 0.5625;
  2229. } else {
  2230. major = 0.84375;
  2231. minor = 0.421875;
  2232. }
  2233. var perMajorAtt = Math.round(major / positionData[position].majors.length * 100)/100;
  2234. var perMinorAtt = Math.round(minor / positionData[position].minors.length * 100)/100;
  2235.  
  2236. for (var k=0; k<positionData[position].majors.length; k++) {
  2237. var new_value = parseFloat(document.getElementById(positionData[position].majors[k]).innerHTML);
  2238. new_value += perMajorAtt;
  2239. try {
  2240. new_value = new_value.toFixed(2);
  2241. }
  2242. catch(err) {}
  2243. document.getElementById(positionData[position].majors[k]).innerHTML = new_value;
  2244. }
  2245. for (var k=0; k<positionData[position].minors.length; k++) {
  2246. var new_value = parseFloat(document.getElementById(positionData[position].minors[k]).innerHTML);
  2247. new_value += perMinorAtt;
  2248. try {
  2249. new_value = new_value.toFixed(2);
  2250. }
  2251. catch(err) {}
  2252. document.getElementById(positionData[position].minors[k]).innerHTML = new_value;
  2253. }
  2254. commitSPSpending();
  2255. }
  2256. }
  2257.  
  2258. function increaseVAXP(addedXP) {
  2259. setVAXP(vaxp+addedXP);
  2260.  
  2261. // level up
  2262. if (vaxp >= 1000) {
  2263. setVAXP(vaxp-1000);
  2264. setVA(va+1);
  2265. }
  2266. }
  2267.  
  2268. function boost() {
  2269. if (getBoosts() > 0) {
  2270. setBoostCount(boost_count + 1) ;
  2271. setBoosts(getBoosts()-1);
  2272. increaseXP(1000);
  2273.  
  2274. }
  2275. updateTrainingPrediction();
  2276. }
  2277.  
  2278. function spendBT() {
  2279. if (getBonusTokens() > 14) {
  2280. setBonusTokens(getBonusTokens()-15);
  2281. setSP(getSP()+1);
  2282. } else {
  2283. alert('You need 15 Bonus tokens to exchange for 1 SP');
  2284. }
  2285. }
  2286.  
  2287. function resetSAs() {
  2288. var skilltree = unsafeWindow.skills;
  2289. for (s in skilltree) {
  2290. document.getElementById('skill_level_' + s).innerHTML = 0;
  2291. }
  2292. }
  2293. function getSerializedBuild() {
  2294. var b = serializeBuild();
  2295. prompt('Save this key and when you want to return to this build, click the \'Load a Saved Build\' button and copy in this key', b);
  2296. }
  2297. // COMPLETE TO HERE
  2298. function serializeBuild() {
  2299. var b = "";
  2300. //TODO this will need to be changed if archetype names go longer than 22
  2301. b += format(getPosition(), 22);
  2302. b += format(season, 2);
  2303. b += format(getDay(), 3);
  2304. b += format(availableBoosts, 1);
  2305. b += format(boost_count, 2);
  2306. b += format(getLevel(), 2);
  2307. b += format(xp, 3);
  2308. b += format(vaxp, 3);
  2309. b += format(va, 3);
  2310. b += format(getBonusTokens(), 4);
  2311. b += format(getTP(), 3);
  2312. b += format(getSP(), 3);
  2313. b += format(getDesiredBT(), 5);
  2314. // training status for all 14 atts
  2315. for (att in minimums[getPosition()]) {
  2316. b += format(getTrainingStatus(att), 2);
  2317. }
  2318. // all attributes
  2319. for (att in minimums[getPosition()]) {
  2320. b += format(getAtt(att), 6);
  2321. }
  2322. // SA levels for all 10 SAs
  2323. var skilltree = unsafeWindow.skills;
  2324. for (s in skilltree) {
  2325. b += format(document.getElementById('skill_level_' + s).innerHTML, 2);
  2326. }
  2327. b += format(getAge(), 3);
  2328. // save enhanced training
  2329. for (att in minimums[getPosition()]) {
  2330. b += format(trainingUpgrades[att].enhance, 2);
  2331. }
  2332. // save multi training
  2333. for (att in minimums[getPosition()]) {
  2334. b += format(trainingUpgrades[att].multi, 1);
  2335. }
  2336. // save current training type
  2337. b += format(trainingSelect.selectedIndex, 1);
  2338.  
  2339. // save current training attribute(s)
  2340. b += format(singleTrainSelect.selectedIndex, 2);
  2341. b += format(multiTrainSelect1.selectedIndex, 2);
  2342. b += format(multiTrainSelect2.selectedIndex, 2);
  2343. b += format(multiTrainSelect3.selectedIndex, 2);
  2344. b += format(multiTrainSelect4.selectedIndex, 2);
  2345.  
  2346. return b;
  2347. }
  2348.  
  2349. function getPrintFriendlyText() {
  2350. var b = serializeBuild();
  2351. var pf = "Player Build";
  2352. var index=0;
  2353. pf += "\nPosition:\t"+ getString(b, index, 22);
  2354. index += 22;
  2355. pf += "\nSeason:\t"+getInt(b, index, 2);
  2356. index += 2;
  2357. pf += "\nDay:\t\t"+getInt(b, index, 3);
  2358. index += 3;
  2359. index += 1;
  2360. pf += "\nBoosts:\t"+getInt(b, index, 2);
  2361. index += 2;
  2362. pf += "\nLevel:\t"+getInt(b, index, 2);
  2363. index += 2;
  2364. pf += "\nXP:\t\t"+getInt(b, index, 3);
  2365. index += 3;
  2366. pf += "\nVA XP:\t"+getInt(b, index, 3);
  2367. index += 3;
  2368. pf += "\nVA:\t\t"+getInt(b, index, 3);
  2369. index += 3;
  2370. pf += "\nBonus Tokens:\t"+getInt(b, index, 4);
  2371. index += 4;
  2372. pf += "\nTraining Points:\t"+getInt(b, index, 3);
  2373. index += 3;
  2374. pf += "\nSP:\t\t"+getInt(b, index, 3);
  2375. index += 3;
  2376. index += 5; // correct???
  2377. pf += "\n\nTraining Status:";
  2378. // training status for all 14 atts
  2379. for (att in minimums[getPosition()]) {
  2380. pf += "\n"+att+" : "+getInt(b, index, 2)+"%";
  2381. index += 2;
  2382. }
  2383. // all attributes
  2384. pf += "\n\nAttributes:";
  2385. for (att in minimums[getPosition()]) {
  2386. pf += "\n"+att+" : "+getFloat(b, index, 6);
  2387. index += 6;
  2388. }
  2389. // SA levels for all 10 SAs
  2390. pf += "\n\nTop SA Tree:\t\t| ";
  2391. for (var i=0; i<5; i++) {
  2392. pf += getInt(b, index, 2) + ' | ';
  2393. index += 2;
  2394. }
  2395. pf += "\nBottom SA Tree:\t| ";
  2396. for (var i=0; i<5; i++) {
  2397. pf += getInt(b, index, 2) + ' | ';
  2398. index += 2;
  2399. }
  2400. pf += "\nAdditional SA Tree:\t| ";
  2401. for (var i=0; i<5; i++) {
  2402. if (index<b.length) {
  2403. pf += getInt(b, index, 2) + ' | ';
  2404. index += 2;
  2405. }
  2406. }
  2407. log(pf, true);
  2408. }
  2409.  
  2410. // pad with leading zeros to get the correct length
  2411. function format(value, length) {
  2412. var ret = "";
  2413. // pad with zeros if it's too short
  2414. while ((ret+value).length < length) {
  2415. ret += "0";
  2416. }
  2417. // chop off trailing characters if it's too long
  2418. while ((ret+value).length > length) {
  2419. value = (""+value).substr(0,(""+value).length-1);
  2420. }
  2421. return ret+value;
  2422. }
  2423.  
  2424. function getString(b, start, length) {
  2425. return b.substring(start, start+length).replace(/^0*/g,"");
  2426. }
  2427. function getInt(b, start, length) {
  2428. var stripped = b.substring(start, start+length).replace(/^0*/g,"");
  2429. return (stripped == "") ? 0 : parseInt(stripped);
  2430. }
  2431. function getFloat(b, start, length) {
  2432. var stripped = b.substring(start, start+length).replace(/^0*/g,"")
  2433. return (stripped == "") ? 0.0 : parseFloat(stripped);
  2434. }
  2435.  
  2436. function loadBuild(b) {
  2437. var index=0;
  2438. //TODO this will need to be changed if archetype names go longer than 22
  2439. setPosition(getString(b, index, 22));
  2440. index += 22;
  2441. reset();
  2442. setSeason(getInt(b, index, 2));
  2443. index += 2;
  2444. setDay(getInt(b, index, 3));
  2445. if (automaticSeasonChange || getDay() < 41) {
  2446. GM_addStyle("#startSeasonButton {display: none}");
  2447. }
  2448. index += 3;
  2449. setBoosts(getInt(b, index, 1));
  2450. index += 1;
  2451. setBoostCount(getInt(b, index, 2));
  2452. index += 2;
  2453. setLevel(getInt(b, index, 2));
  2454. index += 2;
  2455. setXP(getInt(b, index, 3));
  2456. index += 3;
  2457. setVAXP(getInt(b, index, 3));
  2458. index += 3;
  2459. setVA(getInt(b, index, 3));
  2460. index += 3;
  2461. setBonusTokens(getInt(b, index, 4));
  2462. index += 4;
  2463. setTP(getInt(b, index, 3));
  2464. index += 3;
  2465. setSP(getInt(b, index, 3));
  2466. index += 3;
  2467. setDesiredBT(getInt(b, index, 5));
  2468. index +=5;
  2469. // training status for all 14 atts
  2470. for (att in minimums[getPosition()]) {
  2471. setTrainingStatus(att, getInt(b, index, 2));
  2472. index += 2;
  2473. }
  2474. // all attributes
  2475. for (att in minimums[getPosition()]) {
  2476. setAtt(att, getFloat(b, index, 6));
  2477. index += 6;
  2478. }
  2479. // SA levels for all 10 SAs
  2480. var skilltree = unsafeWindow.skills;
  2481. for (s in skilltree) {
  2482. document.getElementById('skill_level_' + s).innerHTML = getInt(b, index, 2);
  2483. index += 2;
  2484. }
  2485. setAge(getInt(b, index, 3));
  2486. index += 3;
  2487.  
  2488. resetTrainingUpgrades();
  2489. // load enhanced training
  2490. for (att in minimums[getPosition()]) {
  2491. trainingUpgrades[att].enhance = getInt(b, index, 2);
  2492. index += 2;
  2493. }
  2494. // load multi training attributes
  2495. for (att in minimums[getPosition()]) {
  2496. if (getString(b, index, 1) == 't') {
  2497. enableMultiTrainAttribute(att);
  2498. }
  2499. index += 1;
  2500. }
  2501. // load current training type
  2502. trainingSelect.selectedIndex = getString(b, index, 1);
  2503. trainingTypeChanged(trainingSelect.selectedIndex);
  2504. index += 1;
  2505.  
  2506. // load current training attribute(s)
  2507. singleTrainSelect.selectedIndex = getInt(b, index, 2);
  2508. index += 2;
  2509. multiTrainSelect1.selectedIndex = getInt(b, index, 2);
  2510. index += 2;
  2511. multiTrainSelect2.selectedIndex = getInt(b, index, 2);
  2512. index += 2;
  2513. multiTrainSelect3.selectedIndex = getInt(b, index, 2);
  2514. index += 2;
  2515. multiTrainSelect4.selectedIndex = getInt(b, index, 2);
  2516. index += 2;
  2517. multiTrainSelectChanged();
  2518. updateTrainingPrediction();
  2519.  
  2520. // TODO something needs to be done to load additional SAs
  2521. GM_addStyle("#nextDayButton {display: inline}");
  2522. GM_addStyle(".playerhead {color: white}");
  2523. GM_addStyle("#startBuilderButton {display: none}");
  2524. GM_addStyle("#trainingDiv {display: block}");
  2525. if (!disableSerialization) {
  2526. GM_addStyle("#serializeButton {display: block}");
  2527. }
  2528. GM_addStyle("#printFriendlyButton {display: block}");
  2529. GM_addStyle("#btWarningDiv {display: block}");
  2530. }
  2531.  
  2532. function convertBuild(b) {
  2533. var index=183;
  2534.  
  2535. var boostsMsg = 'Enter number of boosts from XP History Page';
  2536.  
  2537. var boostsEntered = prompt(boostsMsg);
  2538. if (boostsEntered == null) {
  2539. // they hit cancel
  2540. return;
  2541. }
  2542. boostsEntered = boostsEntered;
  2543.  
  2544. var newAge = getInt(b, index, 3);
  2545.  
  2546. var ageConversionFactor = 0
  2547.  
  2548. if (newAge < 19) {
  2549. ageConversionFactor = .9;
  2550. }
  2551. else if (newAge < 29) {
  2552. ageConversionFactor = .8;
  2553. }
  2554. else if (newAge < 39) {
  2555. ageConversionFactor = .7;
  2556. }
  2557. else if (newAge < 79) {
  2558. ageConversionFactor = .65;
  2559. }
  2560. else if (newAge < 119) {
  2561. ageConversionFactor = .6;
  2562. }
  2563. else if (newAge < 159) {
  2564. ageConversionFactor = .54;
  2565. }
  2566. else if (newAge < 199) {
  2567. ageConversionFactor = .56;
  2568. }
  2569. else if (newAge < 239) {
  2570. ageConversionFactor = .56;
  2571. }
  2572. else if (newAge < 399) {
  2573. ageConversionFactor = .57;
  2574. }
  2575. else if (newAge < 400) {
  2576. ageConversionFactor = .6;
  2577. }
  2578.  
  2579. if (newAge > 440) {
  2580. newAge = newAge - 160;
  2581. }
  2582. else {
  2583. newAge = Math.ceil(newAge * ageConversionFactor);
  2584. }
  2585.  
  2586. index = 39;
  2587.  
  2588. var newBT = Math.round(getInt(b, index, 4) * 1.25);
  2589.  
  2590. index = 43;
  2591.  
  2592. var newTP = Math.ceil(getInt(b, index, 3) / 1.6);
  2593.  
  2594. if (newTP % 2 != 0) {
  2595. newTP = newTP + 1;
  2596. }
  2597.  
  2598. index = 46;
  2599.  
  2600. var newSP = getInt(b, index, 3);
  2601.  
  2602. if (boostsEntered > 25) newSP += 20;
  2603.  
  2604. newSP += parseInt(boostsEntered);
  2605.  
  2606. index = 0;
  2607.  
  2608. //TODO this will need to be changed if archetype names go longer than 22
  2609. setPosition(getString(b, index, 22));
  2610. index += 22;
  2611. reset();
  2612. setSeason(getInt(b, index, 2));
  2613. index += 2;
  2614. setDay(getInt(b, index, 3));
  2615. if (automaticSeasonChange || getDay() < 41) {
  2616. GM_addStyle("#startSeasonButton {display: none}");
  2617. }
  2618. index += 3;
  2619. setBoosts(getInt(b, index, 1));
  2620. setBoostCount(boostsEntered);
  2621. index += 1;
  2622. setLevel(getInt(b, index, 2));
  2623. index += 2;
  2624. setXP(getInt(b, index, 3));
  2625. index += 3;
  2626. setVAXP(getInt(b, index, 3));
  2627. index += 3;
  2628. setVA(getInt(b, index, 3));
  2629. index += 3;
  2630. setBonusTokens(newBT);
  2631. index += 4;
  2632. setTP(newTP);
  2633. index += 3;
  2634. setSP(newSP);
  2635. index += 3;
  2636. //setDesiredBT(getInt(b, 0, 5));
  2637. // training status for all 14 atts
  2638. for (att in minimums[getPosition()]) {
  2639. setTrainingStatus(att, getInt(b, index, 2));
  2640. index += 2;
  2641. }
  2642. // all attributes
  2643. for (att in minimums[getPosition()]) {
  2644. setAtt(att, getFloat(b, index, 6));
  2645. index += 6;
  2646. }
  2647. // SA levels for all 10 SAs
  2648. var skilltree = unsafeWindow.skills;
  2649. for (s in skilltree) {
  2650. document.getElementById('skill_level_' + s).innerHTML = getInt(b, index, 2);
  2651. index += 2;
  2652. }
  2653. setAge(newAge);
  2654. index += 3;
  2655.  
  2656. resetTrainingUpgrades();
  2657. // load enhanced training
  2658. for (att in minimums[getPosition()]) {
  2659. trainingUpgrades[att].enhance = getInt(b, index, 2);
  2660. index += 2;
  2661. }
  2662. // load multi training attributes
  2663. for (att in minimums[getPosition()]) {
  2664. if (getString(b, index, 1) == 't') {
  2665. enableMultiTrainAttribute(att);
  2666. }
  2667. index += 1;
  2668. }
  2669. // load current training type
  2670. trainingSelect.selectedIndex = getString(b, index, 1);
  2671. trainingTypeChanged(trainingSelect.selectedIndex);
  2672. index += 1;
  2673.  
  2674. // load current training attribute(s)
  2675. singleTrainSelect.selectedIndex = getInt(b, index, 2);
  2676. index += 2;
  2677. multiTrainSelect1.selectedIndex = getInt(b, index, 2);
  2678. index += 2;
  2679. multiTrainSelect2.selectedIndex = getInt(b, index, 2);
  2680. index += 2;
  2681. multiTrainSelect3.selectedIndex = getInt(b, index, 2);
  2682. index += 2;
  2683. multiTrainSelect4.selectedIndex = getInt(b, index, 2);
  2684. index += 2;
  2685. multiTrainSelectChanged();
  2686. updateTrainingPrediction();
  2687.  
  2688. // TODO something needs to be done to load additional SAs
  2689. GM_addStyle("#nextDayButton {display: inline}");
  2690. GM_addStyle(".playerhead {color: white}");
  2691. GM_addStyle("#startBuilderButton {display: none}");
  2692. GM_addStyle("#trainingDiv {display: block}");
  2693. if (!disableSerialization) {
  2694. GM_addStyle("#serializeButton {display: block}");
  2695. }
  2696. GM_addStyle("#printFriendlyButton {display: block}");
  2697. GM_addStyle("#btWarningDiv {display: block}");
  2698. }
  2699.  
  2700. function loadSavedBuild() {
  2701. var b = prompt('Enter the build here');
  2702. if (b) {
  2703. var expectedLength = 246;
  2704. if (b.length==expectedLength) {
  2705. loadBuild(b);
  2706. clearBackups();
  2707. } else {
  2708. alert('Invalid build\nIt\'s missing '+(expectedLength-b.length)+' characters.\n\nMake sure the key was generated using the same version of the script.');
  2709. }
  2710. }
  2711. }
  2712.  
  2713. function convertSavedBuild() {
  2714. var b = prompt('Enter the build here');
  2715. if (b) {
  2716. var expectedLength = 239;
  2717. if (b.length==expectedLength) {
  2718. convertBuild(b);
  2719. clearBackups();
  2720. } else {
  2721. alert('Invalid build\nIt\'s missing '+(expectedLength-b.length)+' characters.\n\nMake sure the key was generated using the same version of the script.');
  2722. }
  2723. }
  2724. }
  2725.  
  2726. function promptForDesiredBT() {
  2727. var maxPossible = calcMaxPossibleBTGain()+getBonusTokens();
  2728. var maxPossiblenormal = calcMaxPossiblenormalBTGain()+getBonusTokens();
  2729. var maxPossibleintense = calcMaxPossibleintenseBTGain()+getBonusTokens();
  2730. var maxPossiblemulti4 = calcMaxPossiblemulti4BTGain()+getBonusTokens();
  2731. var val = prompt('Enter the number of BT you want available on day 280 of your build.\n\nThis will allow you to do multi/normal/intense training up until the point where you absolutely have to switch to light training in order to reach your BT goal.\n\nNote: this calculation tries to figure out how many training days you have left by assuming a '+offseasonLength+' day offseason and '+preseasonLength+' day preseason. So if you\'re going to stick to this calculation, I\'d recommend setting the BT goal slightly higher than you really need so you have some buffer in place in case the offseason length changes.\nCurrently, if you spend the rest of your career and all of your current TP in light training, you\'ll end up with: '+(maxPossible)+' BT\n(Normal training ... you\'ll end up with: '+(maxPossiblenormal)+' BT)\n(Intense training ... you\'ll end up with: '+(maxPossibleintense)+' BT)\n(4-way multi training ... you\'ll end up with: '+(maxPossiblemulti4)+' BT)\n\nEnter zero if you don\'t want this to block your training.\n\nHit cancel to leave the number unchanged.', getDesiredBT());
  2732. if (val == null || val =='' || isNaN(val)) {
  2733. return;
  2734. }
  2735. setDesiredBT(val);
  2736. if (val > maxPossible) {
  2737. log("You can not reach that BT goal even if you only do light training for the rest of your career.\nSet a value lower than "+(maxPossible+1), true);
  2738. setDesiredBT(maxPossible);
  2739. promptForDesiredBT();
  2740. }
  2741. }
  2742. function enableOddDayGames() {
  2743. setGamesOnOddDays(true);
  2744. GM_addStyle("#gameDayOddButton {display: none}");
  2745. GM_addStyle("#gameDayEvenButton {display: block}");
  2746. }
  2747. function enableEvenDayGames() {
  2748. setGamesOnOddDays(false);
  2749. GM_addStyle("#gameDayOddButton {display: block}");
  2750. GM_addStyle("#gameDayEvenButton {display: none}");
  2751. }
  2752. /* start multi training stuff */
  2753. function enableMultiTrainAttribute(attribute) {
  2754. if (getListOfMultiTrainAttributes().length==0) {
  2755. enableMultiTraining();
  2756. }
  2757. trainingUpgrades[attribute].multi = true;
  2758. addElement('option', 'mt2'+attribute, multiTrainSelect2, {
  2759. value: attribute,
  2760. innerHTML: attribute,
  2761. disabled: (multiTrainSelect1.value == attribute) ? true : null
  2762. });
  2763. addElement('option', 'mt3'+attribute, multiTrainSelect3, {
  2764. value: attribute,
  2765. innerHTML: attribute,
  2766. disabled: (multiTrainSelect1.value == attribute) ? true : null
  2767. });
  2768. addElement('option', 'mt4'+attribute, multiTrainSelect4, {
  2769. value: attribute,
  2770. innerHTML: attribute,
  2771. disabled: (multiTrainSelect1.value == attribute) ? true : null
  2772. });
  2773. }
  2774. function enableMultiTraining() {
  2775. var opt = document.getElementById('trainingTypeOption'+TRAININGTYPE.MULTI);
  2776. opt.disabled = false;
  2777. }
  2778.  
  2779. /*
  2780. cleanup involved with disabling multitraining
  2781. */
  2782. function disableMultiTraining() {
  2783. var opt = document.getElementById('trainingTypeOption'+TRAININGTYPE.MULTI);
  2784. opt.disabled = true;
  2785. opt.selected=0;
  2786.  
  2787. // remove the attribute options from the dropdowns but re-add the 'None' options
  2788. multiTrainSelect2.innerHTML='';
  2789. addElement('option', null, multiTrainSelect2, {value: null, innerHTML: 'None'});
  2790. multiTrainSelect2.selectedIndex=0;
  2791.  
  2792. multiTrainSelect3.innerHTML='';
  2793. addElement('option', null, multiTrainSelect3, {value: null, innerHTML: 'None'});
  2794. multiTrainSelect3.selectedIndex=0;
  2795.  
  2796. multiTrainSelect4.innerHTML='';
  2797. addElement('option', null, multiTrainSelect4, {value: null, innerHTML: 'None'});
  2798. multiTrainSelect4.selectedIndex=0;
  2799.  
  2800. // if any of the multi trains were selected, the first multi train dropdown might still have some options disabled
  2801. //TODO enable them here
  2802. for (var i=0; i<multiTrainSelect1.options.length; i++) {
  2803. multiTrainSelect1.options[i].disabled = false;
  2804. }
  2805.  
  2806. trainingTypeChanged(0);
  2807. }
  2808.  
  2809. function multiTrainSelectChanged() {
  2810. var one = multiTrainSelect1.value;
  2811. var two = multiTrainSelect2.value;
  2812. var three = multiTrainSelect3.value;
  2813. var four = multiTrainSelect4.value;
  2814. // disable the newly selected attribute in the other drop downs
  2815. var multiAtts = getListOfMultiTrainAttributes();
  2816. for (var a=0; a<multiAtts.length; a++) {
  2817. if (multiAtts[a]==one) {
  2818. document.getElementById('mt1'+multiAtts[a]).disabled = null;
  2819. document.getElementById('mt2'+multiAtts[a]).disabled = true;
  2820. document.getElementById('mt3'+multiAtts[a]).disabled = true;
  2821. document.getElementById('mt4'+multiAtts[a]).disabled = true;
  2822. } else if (multiAtts[a]==two) {
  2823. document.getElementById('mt1'+two).disabled = true;
  2824. document.getElementById('mt2'+two).disabled = null;
  2825. document.getElementById('mt3'+two).disabled = true;
  2826. document.getElementById('mt4'+two).disabled = true;
  2827. } else if (multiAtts[a]==three) {
  2828. document.getElementById('mt1'+three).disabled = true;
  2829. document.getElementById('mt2'+three).disabled = true;
  2830. document.getElementById('mt3'+three).disabled = null;
  2831. document.getElementById('mt4'+three).disabled = true;
  2832. } else if (multiAtts[a]==four) {
  2833. document.getElementById('mt1'+four).disabled = true;
  2834. document.getElementById('mt2'+four).disabled = true;
  2835. document.getElementById('mt3'+four).disabled = true;
  2836. document.getElementById('mt4'+four).disabled = null;
  2837. } else {
  2838. document.getElementById('mt1'+multiAtts[a]).disabled = null;
  2839. document.getElementById('mt2'+multiAtts[a]).disabled = null;
  2840. document.getElementById('mt3'+multiAtts[a]).disabled = null;
  2841. document.getElementById('mt4'+multiAtts[a]).disabled = null;
  2842. }
  2843. }
  2844. updateTrainingPrediction();
  2845. }
  2846. function getListOfMultiTrainAttributes() {
  2847. var result = [];
  2848. for (var att in trainingUpgrades) {
  2849. if (trainingUpgrades[att].multi) {
  2850. result.push(att);
  2851. }
  2852. }
  2853. return result;
  2854. }
  2855. function getListOfNonMultiTrainAttributes() {
  2856. var result = [];
  2857. for (var att in trainingUpgrades) {
  2858. if (trainingUpgrades[att].multi==null || trainingUpgrades[att].multi != true) {
  2859. result.push(att);
  2860. }
  2861. }
  2862. return result;
  2863. }
  2864. /* end multi training stuff */
  2865.  
  2866. /* getters and setters */
  2867. var gameXpOnOddDays = true;
  2868. function getGamesOnOddDays() {
  2869. return gameXpOnOddDays;
  2870. }
  2871. function setGamesOnOddDays(newVal) {
  2872. gameXpOnOddDays = newVal;
  2873. }
  2874. var createdDay = 0;
  2875. function getCreatedDay() {
  2876. return createdDay;
  2877. }
  2878. function setCreatedDay(newVal) {
  2879. createdDay = parseInt(newVal);
  2880. }
  2881. //var desiredBT = 0;
  2882. function setDesiredBT(newVal) {
  2883. desiredBT = parseInt(newVal);
  2884. }
  2885. function getDesiredBT() {
  2886. return parseInt(desiredBT);
  2887. }
  2888. function getPosition() {
  2889. return position;
  2890. }
  2891. function setPosition(newValue) {
  2892. position = newValue;
  2893. }
  2894. function getBoosts() {
  2895. return parseInt(availableBoosts);
  2896. }
  2897. function setBoosts(newValue) {
  2898. availableBoosts = newValue;
  2899. if (availableBoosts > 6) {
  2900. availableBoosts = 6
  2901. }
  2902. availableBoostsDiv.innerHTML = "Available Boosts: "+availableBoosts
  2903. if (getBoosts() == 0) {
  2904. GM_addStyle("#boostButton {display: none}");
  2905. } else {
  2906. GM_addStyle("#boostButton {display: block}");
  2907. GM_addStyle("#boostButton {display: block}");
  2908. }
  2909. }
  2910. function setBoostCount(newValue) {
  2911. boost_count = newValue;
  2912. boostCountDiv.innerHTML = "Boost Count: "+boost_count ;
  2913. }
  2914. function getSP() {
  2915. return parseInt(document.getElementById('skill_points').innerHTML);
  2916. }
  2917. function setSP(newSP) {
  2918. contentEval("skillPoints="+newSP);
  2919. document.getElementById('skill_points').innerHTML = newSP;
  2920. }
  2921. function getTP() {
  2922. return parseInt(tp);
  2923. }
  2924. function setTP(newTP) {
  2925. tp = parseInt(newTP);
  2926. currentTPDiv.innerHTML = "TP: "+getTP();
  2927. }
  2928. function getDay() {
  2929. return parseInt(day);
  2930. }
  2931. function setDay(newDay) {
  2932. day = parseInt(newDay);
  2933. currentDayDiv.innerHTML = "Day: "+day;
  2934. }
  2935. function setLevel(newLevel) {
  2936. level = newLevel;
  2937. currentLevelDiv.innerHTML = "Level: "+level;
  2938. }
  2939. function getLevel() {
  2940. return parseInt(level);
  2941. }
  2942. function setVAXP(newVAXP) {
  2943. vaxp = newVAXP;
  2944. currentVAXPDiv.innerHTML = "VA XP: "+vaxp+" / 1000";
  2945. }
  2946. function setVA(newVA) {
  2947. va = newVA;
  2948. currentVADiv.innerHTML = "Vet Points: "+va;
  2949. }
  2950. function setXP(newXP) {
  2951. xp = newXP;
  2952. currentXPDiv.innerHTML = "XP: "+xp+" / 1000";
  2953. }
  2954. function setAtt(attribute, newValue) {
  2955. document.getElementById(attribute).innerHTML = newValue;
  2956. installCapTips();
  2957. }
  2958. function getAtt(attribute) {
  2959. return parseFloat(document.getElementById(attribute).innerHTML);
  2960. }
  2961. function getTrainingStatus(attribute) {
  2962. return trainingStatus[attribute];
  2963. }
  2964. function setTrainingStatus(attribute, newValue) {
  2965. //TODO this needs to change for creating players from scratch as the current player's
  2966. // major/minor 'stars' probably need to be dropped
  2967. trainingStatus[attribute] = newValue;
  2968.  
  2969. // display the new value
  2970. var txt = attribute.substring(0,1).toUpperCase() + attribute.substring(1, attribute.length);
  2971. var txt = txt + " "+newValue+"%";
  2972. //document.getElementById(attribute).parentNode.childNodes[1].innerHTML = txt;
  2973.  
  2974. var attributeContainer = document.getElementById(attribute).parentNode;
  2975. for (var i=0; i<attributeContainer.childNodes.length; i++) {
  2976. var current = attributeContainer.childNodes[i];
  2977.  
  2978. if (current.className == 'attribute_name') {
  2979. var indexToEdit = (current.childNodes.length>1) ? 1 : 0;
  2980. current.childNodes[indexToEdit].childNodes[0].innerHTML = txt;
  2981. }
  2982. }
  2983. }
  2984. // need these style changes so the training percentages will fit inside
  2985. // the attribute lines without pushing buttons around
  2986. GM_addStyle("div.attribute_name { width: 112px; }");// +12 width
  2987. GM_addStyle("div.attribute_value { width: 40px; }");// -6 width
  2988. GM_addStyle("div.attribute_name div a { font-size: 11px; }");
  2989. GM_addStyle("div.attribute_modifier { width: 28px; }"); // -6 width
  2990.  
  2991. function setSeason(newValue) {
  2992. season = newValue;
  2993. currentSeasonDiv.innerHTML = "Season: "+season;
  2994. }
  2995. function getIsBuildFromScratch() {
  2996. return buildFromScratch;
  2997. }
  2998. function setIsBuildFromScratch(newValue) {
  2999. buildFromScratch = newValue;
  3000. }
  3001. var bonusTokens = 0;
  3002. function setBonusTokens(newValue) {
  3003. bonusTokens = newValue;
  3004. currentBTDiv.innerHTML = "Bonus Tokens: "+getBonusTokens();
  3005. if (bonusTokens>14) {
  3006. GM_addStyle("#spendBTButton {display: inline}");
  3007. } else {
  3008. GM_addStyle("#spendBTButton {display: none}");
  3009. }
  3010. }
  3011. function getBonusTokens() {
  3012. return parseInt(bonusTokens);
  3013. }
  3014. function setAge(newValue) {
  3015. age = newValue;
  3016. currentAgeDiv.innerHTML = "Player Age (Days): "+age;
  3017. if (age >= plateau_age) {
  3018. GM_addStyle("#startGameXPButton {display: none}");
  3019. GM_addStyle("#stopGameXPButton {display: none}");
  3020. }
  3021. }
  3022. function getAge() {
  3023. return age;
  3024. }
  3025. function turnOffGameXP() {
  3026. game_xp_factor = 0.0;
  3027. GM_addStyle("#startGameXPButton {display: block}");
  3028. GM_addStyle("#stopGameXPButton {display: none}");
  3029. }
  3030. function turnOnGameXP() {
  3031. game_xp_factor = 1.0;
  3032. GM_addStyle("#startGameXPButton {display: none}");
  3033. GM_addStyle("#stopGameXPButton {display: block}");
  3034. }
  3035. //
  3036. // next 2 functions were copied from GLB skill points enhancements
  3037. // http://userscripts.org/scripts/show/47648
  3038. //
  3039. function figureNextCaps(curVal) {
  3040. var out = '';
  3041. var cur = curVal;
  3042. var origCost = 0;
  3043. var caps = 4;
  3044. var needed = 0;
  3045. while (caps > 0) {
  3046. cost = parseInt(Math.exp(0.0003 * Math.pow(cur, 2)));
  3047. if (cost > origCost) {
  3048. if (origCost > 0) {
  3049. if (out.length) {
  3050. out += '<br />';
  3051. }
  3052. out += '<b>' + cur + '</b>&nbsp;(' + origCost + '-cap)&nbsp;cost:&nbsp;' + needed + '&nbsp;Skill&nbsp;Point' + ((needed == 1) ? '' : 's');
  3053. --caps;
  3054. }
  3055. origCost = cost;
  3056. }
  3057. needed += cost;
  3058. cur = Math.round((cur + 1) * 100) / 100;
  3059. }
  3060. return out;
  3061. }
  3062.  
  3063. function installCapTips() {
  3064. var divs = document.getElementById('attribute_list').getElementsByTagName('div');
  3065. for (var div=0; div<divs.length; div++) {
  3066. if (divs[div].className == 'attribute_value') {
  3067. var tip = figureNextCaps(parseFloat(divs[div].innerHTML));
  3068. divs[div].setAttribute('onmouseover', "set_tip('" + tip + "', 0, 1, 1, 1)");
  3069. divs[div].setAttribute('onmouseout', "unset_tip()");
  3070. }
  3071. }
  3072. }
  3073. //////////////////////////////////////
  3074. function log(msg, doAlert) {
  3075. if (doAlert) {
  3076. alert(msg);
  3077. }
  3078. console.log(msg);
  3079. }
  3080. /*
  3081. * type, id, parentNode, attributes, innerHTML
  3082. */
  3083. function addElement(type, id, parentNode, attributes, innerHTML) {
  3084. var e = document.createElement(type);
  3085. e.id = id;
  3086. parentNode.appendChild(e);
  3087. if (attributes!=null) {
  3088. for (var attName in attributes) {
  3089. e[attName] = attributes[attName];
  3090. }
  3091. }
  3092. if (innerHTML!=null) {
  3093. e.innerHTML = innerHTML;
  3094. }
  3095. return e;
  3096. }
  3097. /*
  3098. * populate the given dropdown with an option for each attribute
  3099. *
  3100. * use idPrefix to add a prefix to the id, followed by the attribute name. Ex: idPrefixstrength
  3101. */
  3102. function fillAttributeDropdown(selectElement, idPrefix) {
  3103. for (var a=0; a<attributeTrainingOptions.length; a++) {
  3104. var id = null;
  3105. if (idPrefix!=null) {
  3106. id = idPrefix+attributeTrainingOptions[a];
  3107. }
  3108. addElement('option', id, selectElement, {
  3109. value : attributeTrainingOptions[a],
  3110. innerHTML: attributeTrainingOptions[a]
  3111. });
  3112. }
  3113. }
  3114.  
  3115. /*
  3116. * needed this to access the skillPoints variable on the page
  3117. * firefox would have been ok but this is needed for chrome
  3118. *
  3119. * from https://wiki.greasespot.net/Content_Script_Injection
  3120. */
  3121. function contentEval(source) {
  3122. // Check for function input.
  3123. if ('function' == typeof source) {
  3124. // Execute this function with no arguments, by adding parentheses.
  3125. // One set around the function, required for valid syntax, and a
  3126. // second empty set calls the surrounded function.
  3127. source = '(' + source + ')();'
  3128. }
  3129.  
  3130. // Create a script node holding this source code.
  3131. var script = document.createElement('script');
  3132. script.setAttribute("type", "application/javascript");
  3133. script.textContent = source;
  3134.  
  3135. // Insert the script node into the page, so it will run, and immediately
  3136. // remove it to clean up.
  3137. document.body.appendChild(script);
  3138. document.body.removeChild(script);
  3139. }
  3140.  
  3141. function getInetPage(address, func) {
  3142. var req = new XMLHttpRequest();
  3143. req.open( 'GET', address, true);
  3144. req.onload = function() {
  3145. if (this.status != 200) {
  3146. alert("gm script: Error "+this.status+" loading "+address);
  3147. }
  3148. else {
  3149. func(address,this);
  3150. }
  3151. };
  3152.  
  3153. req.send(null);
  3154. return req;
  3155. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址