GLB Player Builder

simulate a player's build

目前为 2014-07-19 提交的版本。查看 最新版本

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