Advertisement
Guest User

Untitled

a guest
Apr 15th, 2025
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.16 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>TI4 Unit Calculator</title>
  5. <style>
  6. body {
  7. font-family: Arial, sans-serif;
  8. max-width: 800px;
  9. margin: 0 auto;
  10. padding: 20px;
  11. background-color: #f5f5f5;
  12. }
  13.  
  14. h1 {
  15. color: #2c3e50;
  16. text-align: center;
  17. }
  18.  
  19. .container {
  20. background-color: white;
  21. padding: 20px;
  22. border-radius: 10px;
  23. box-shadow: 0 0 10px rgba(0,0,0,0.1);
  24. margin-bottom: 20px;
  25. }
  26.  
  27. .unit-section {
  28. display: grid;
  29. grid-template-columns: 3fr 1fr 1fr 1fr;
  30. align-items: center;
  31. margin-bottom: 10px;
  32. }
  33.  
  34. .unit-name {
  35. font-size: 18px;
  36. }
  37.  
  38. .button {
  39. background-color: #3498db;
  40. color: white;
  41. border: none;
  42. border-radius: 5px;
  43. padding: 8px 12px;
  44. cursor: pointer;
  45. font-size: 16px;
  46. transition: background-color 0.2s;
  47. }
  48.  
  49. .button:hover {
  50. background-color: #2980b9;
  51. }
  52.  
  53. .button:active {
  54. transform: translateY(2px);
  55. }
  56.  
  57. input[type="text"] {
  58. padding: 8px;
  59. font-size: 16px;
  60. border: 1px solid #ccc;
  61. border-radius: 5px;
  62. text-align: center;
  63. width: 60px;
  64. margin: 0 auto;
  65. display: block;
  66. }
  67.  
  68. .faction-container {
  69. display: flex;
  70. justify-content: space-between;
  71. margin-bottom: 20px;
  72. }
  73.  
  74. select {
  75. padding: 8px;
  76. font-size: 16px;
  77. border: 1px solid #ccc;
  78. border-radius: 5px;
  79. }
  80.  
  81. .checkbox-container {
  82. display: flex;
  83. align-items: center;
  84. }
  85.  
  86. input[type="checkbox"] {
  87. margin-right: 5px;
  88. width: 16px;
  89. height: 16px;
  90. }
  91.  
  92. .result-container {
  93. display: grid;
  94. grid-template-columns: 1fr 1fr 1fr;
  95. gap: 10px;
  96. margin-top: 20px;
  97. }
  98.  
  99. .result-item {
  100. background-color: #ecf0f1;
  101. padding: 15px;
  102. border-radius: 5px;
  103. text-align: center;
  104. }
  105.  
  106. .result-value {
  107. font-size: 24px;
  108. font-weight: bold;
  109. margin-top: 5px;
  110. }
  111.  
  112. .caption {
  113. font-size: 14px;
  114. color: #7f8c8d;
  115. margin-top: 5px;
  116. }
  117.  
  118. #buildStatus {
  119. text-align: center;
  120. font-size: 20px;
  121. font-weight: bold;
  122. padding: 10px;
  123. margin-top: 20px;
  124. border-radius: 5px;
  125. }
  126.  
  127. .valid {
  128. background-color: #2ecc71;
  129. color: white;
  130. }
  131.  
  132. .invalid {
  133. background-color: #e74c3c;
  134. color: white;
  135. }
  136.  
  137. .notes {
  138. margin-top: 20px;
  139. font-size: 14px;
  140. color: #7f8c8d;
  141. }
  142. </style>
  143. </head>
  144.  
  145. <body>
  146. <h1>TI4 Unit Calculator</h1>
  147.  
  148. <div class="container">
  149. <div class="faction-container">
  150. <div>
  151. <label for="faction">Faction:</label>
  152. <select name="faction" id="faction" onchange="updateUnitData()">
  153. <option value="Other">Other</option>
  154. <option value="Arborec">Arborec</option>
  155. <option value="Barony">Barony of Letnev</option>
  156. <option value="Embers">Embers of Muaat</option>
  157. <option value="L1Z1X">L1Z1X Mindnet</option>
  158. <option value="Naalu">Naalu Collective</option>
  159. <option value="Saar">Clan of Saar</option>
  160. <option value="Sol">Federation of Sol</option>
  161. </select>
  162. </div>
  163. <div class="checkbox-container">
  164. <input type="checkbox" id="sarween" onchange="calculateAll()">
  165. <label for="sarween">Sarween Tools</label>
  166. </div>
  167. </div>
  168. </div>
  169.  
  170. <div class="container">
  171. <h2>Units to Build</h2>
  172.  
  173. <div class="unit-section">
  174. <div class="unit-name">Infantry (0.5 Resources each)</div>
  175. <button class="button" onclick="alter('newInfantry',-1)">-</button>
  176. <input size="1" type="text" id="newInfantry" value="0" onchange="calculateTotals()">
  177. <button class="button" onclick="alter('newInfantry',1)">+</button>
  178. </div>
  179.  
  180. <div class="unit-section">
  181. <div class="unit-name">Mechs (2 Resources each)</div>
  182. <button class="button" onclick="alter('newMechs',-1)">-</button>
  183. <input size="1" type="text" id="newMechs" value="0" onchange="calculateTotals()">
  184. <button class="button" onclick="alter('newMechs',1)">+</button>
  185. </div>
  186.  
  187. <div class="unit-section">
  188. <div class="unit-name">Fighters (0.5 Resources each)</div>
  189. <button class="button" onclick="alter('newFighters',-1)">-</button>
  190. <input size="1" type="text" id="newFighters" value="0" onchange="calculateTotals()">
  191. <button class="button" onclick="alter('newFighters',1)">+</button>
  192. <div class="checkbox-container" style="margin-top: 10px;">
  193. <input type="checkbox" id="Fi2" onchange="calculateTotals()">
  194. <label for="Fi2">Fighter II (can count as ships)</label>
  195. </div>
  196. </div>
  197.  
  198. <div class="unit-section">
  199. <div class="unit-name">Carriers (3 Resources)</div>
  200. <button class="button" onclick="alter('newCarriers',-1)">-</button>
  201. <input size="1" type="text" id="newCarriers" value="0" onchange="calculateAll()">
  202. <button class="button" onclick="alter('newCarriers',1)">+</button>
  203. </div>
  204.  
  205. <div class="unit-section">
  206. <div class="unit-name">Destroyers (1 Resource)</div>
  207. <button class="button" onclick="alter('newDestroyers',-1)">-</button>
  208. <input size="1" type="text" id="newDestroyers" value="0" onchange="calculateAll()">
  209. <button class="button" onclick="alter('newDestroyers',1)">+</button>
  210. </div>
  211.  
  212. <div class="unit-section">
  213. <div class="unit-name">Cruisers (2 Resources)</div>
  214. <button class="button" onclick="alter('newCruisers',-1)">-</button>
  215. <input size="1" type="text" id="newCruisers" value="0" onchange="calculateAll()">
  216. <button class="button" onclick="alter('newCruisers',1)">+</button>
  217. </div>
  218.  
  219. <div class="unit-section">
  220. <div class="unit-name">Dreadnoughts (4 Resources)</div>
  221. <button class="button" onclick="alter('newDreadnoughts',-1)">-</button>
  222. <input size="1" type="text" id="newDreadnoughts" value="0" onchange="calculateAll()">
  223. <button class="button" onclick="alter('newDreadnoughts',1)">+</button>
  224. </div>
  225.  
  226. <div class="unit-section">
  227. <div class="unit-name">War Suns (12 Resources)</div>
  228. <button class="button" onclick="alter('newWarSuns',-1)">-</button>
  229. <input size="1" type="text" id="newWarSuns" value="0" onchange="calculateAll()">
  230. <button class="button" onclick="alter('newWarSuns',1)">+</button>
  231. <div class="checkbox-container" style="margin-top: 10px;">
  232. <input type="checkbox" id="Wa2" checked onchange="calculateAll()">
  233. <label for="Wa2">War Sun Upgrade</label>
  234. </div>
  235. </div>
  236.  
  237. <div class="unit-section">
  238. <div class="unit-name">Flagship (8 Resources)</div>
  239. <button class="button" onclick="alter('newFlagships',-1)">-</button>
  240. <input size="1" type="text" id="newFlagships" value="0" onchange="calculateAll()">
  241. <button class="button" onclick="alter('newFlagships',1)">+</button>
  242. </div>
  243. </div>
  244.  
  245. <div class="container">
  246. <div class="result-container">
  247. <div class="result-item">
  248. <div>Total Resource Cost</div>
  249. <div id="totalCost" class="result-value">0</div>
  250. </div>
  251. <div class="result-item">
  252. <div>Minimum Fleet Supply Needed</div>
  253. <div id="totalFleetNeeded" class="result-value">0</div>
  254. </div>
  255. <div class="result-item">
  256. <div>Production Needed</div>
  257. <div id="totalProduction" class="result-value">0</div>
  258. </div>
  259. <div class="result-item">
  260. <div>Total Capacity Needed</div>
  261. <div id="totalCapacity" class="result-value">0</div>
  262. <div class="caption">(Fighters + Infantry + Mechs)</div>
  263. </div>
  264. <div class="result-item">
  265. <div>Capacity for Fighters Only</div>
  266. <div id="capacityWithoutGround" class="result-value">0</div>
  267. <div class="caption">(Ground troops can be on planets)</div>
  268. </div>
  269. </div>
  270.  
  271. <div id="buildStatus">Enter units above</div>
  272.  
  273. <div class="notes">
  274. <p>Note: This calculator shows the minimum requirements to produce these units. Remember to check:</p>
  275. <ul>
  276. <li>Production capacity of the system you're building in (must be ≥ Production Needed)</li>
  277. <li>Units already present in the system (for fleet supply limits)</li>
  278. <li>Available capacity for fighters and ground troops</li>
  279. <li>Available resources and trade goods</li>
  280. </ul>
  281. <p><strong>Production Rule:</strong> Each unit counts as 1 production, regardless of cost (exception: Mechs count as 2 production each). Your Space Dock's production value must be equal to or greater than your total Production Needed.</p>
  282. <p><strong>Capacity Note:</strong> Infantry and Mechs can be on planets and don't require capacity if they stay grounded. Fighters always need capacity.</p>
  283. </div>
  284. </div>
  285.  
  286. <script>
  287. // Cost data for units [cost, counts as ship for fleet supply]
  288. let unitData = {
  289. Infantry: [0.5, false],
  290. Mechs: [2, false],
  291. Fighters: [0.5, false], // normally false, but can be true with Fighter II
  292. Carriers: [3, true],
  293. Destroyers: [1, true],
  294. Cruisers: [2, true],
  295. Dreadnoughts: [4, true],
  296. WarSuns: [12, true], // Cost can change with tech
  297. Flagship: [8, true]
  298. };
  299.  
  300. // Add event listeners for all form elements
  301. document.addEventListener('DOMContentLoaded', function() {
  302. // Attach change listeners to all inputs
  303. document.querySelectorAll('input[type="text"]').forEach(input => {
  304. input.addEventListener('change', function() {
  305. calculateTotals();
  306. });
  307. });
  308.  
  309. document.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
  310. checkbox.addEventListener('change', function() {
  311. // Update unit data without making recursive calls
  312. if (this.id === "Fi2") {
  313. unitData.Fighters[1] = this.checked;
  314. } else if (this.id === "Wa2" && document.getElementById("faction").value === 'Embers') {
  315. unitData.WarSuns[0] = this.checked ? 10 : 12;
  316. }
  317. calculateTotals();
  318. });
  319. });
  320.  
  321. document.getElementById('faction').addEventListener('change', function() {
  322. // Reset to default values
  323. unitData = {
  324. Infantry: [0.5, false],
  325. Fighters: [0.5, false],
  326. Carriers: [3, true],
  327. Destroyers: [1, true],
  328. Cruisers: [2, true],
  329. Dreadnoughts: [4, true],
  330. WarSuns: [12, true],
  331. Flagship: [8, true]
  332. };
  333.  
  334. // Apply faction-specific changes
  335. if (this.value === 'Embers') {
  336. if (document.getElementById("Wa2").checked) {
  337. unitData.WarSuns[0] = 10; // Embers with War Sun upgrade
  338. } else {
  339. unitData.WarSuns[0] = 12; // Embers standard War Sun
  340. }
  341. }
  342.  
  343. // Update Fighter II status
  344. unitData.Fighters[1] = document.getElementById("Fi2").checked;
  345.  
  346. calculateTotals();
  347. });
  348.  
  349. // Initial calculation
  350. calculateTotals();
  351. });
  352.  
  353. // Update unit data based on faction selection
  354. function updateUnitData() {
  355. // Reset to default values
  356. unitData = {
  357. Infantry: [0.5, false],
  358. Fighters: [0.5, false],
  359. Carriers: [3, true],
  360. Destroyers: [1, true],
  361. Cruisers: [2, true],
  362. Dreadnoughts: [4, true],
  363. WarSuns: [12, true],
  364. Flagship: [8, true]
  365. };
  366.  
  367. // Apply faction-specific changes
  368. const faction = document.getElementById("faction").value;
  369.  
  370. if (faction === 'Embers') {
  371. if (document.getElementById("Wa2").checked) {
  372. unitData.WarSuns = [10, true]; // Embers with War Sun upgrade
  373. } else {
  374. unitData.WarSuns = [12, true]; // Embers standard War Sun
  375. }
  376. }
  377.  
  378. // Update Fighter II status
  379. unitData.Fighters[1] = document.getElementById("Fi2").checked;
  380.  
  381. // Calculate totals without recursive calls
  382. calculateTotals();
  383. }
  384.  
  385. function alter(id, amount) {
  386. let currentValue = parseInt(document.getElementById(id).value);
  387.  
  388. // Prevent negative values
  389. if (amount < 0 && currentValue === 0) {
  390. return;
  391. }
  392.  
  393. // Apply unit-specific maximums
  394. const unitMaximums = {
  395. 'newFlagships': 1,
  396. 'newWarSuns': 2,
  397. 'newDreadnoughts': 5,
  398. 'newCruisers': 8,
  399. 'newDestroyers': 8,
  400. 'newCarriers': 4,
  401. 'newMechs': 4 // Adding limit for mechs
  402. };
  403.  
  404. if (amount > 0 && unitMaximums[id] && currentValue >= unitMaximums[id]) {
  405. return;
  406. }
  407.  
  408. document.getElementById(id).value = currentValue + amount;
  409. calculateTotals();
  410. }
  411.  
  412. function calculateAll() {
  413. // Update unit data without recursive calls
  414. updateUnitData();
  415. }
  416.  
  417. function calculateTotals() {
  418. // Calculate total cost
  419. let totalCost = 0;
  420. let totalShips = 0;
  421. let totalProduction = 0;
  422. let totalCapacityNeeded = 0;
  423. let capacityNeededWithoutGround = 0;
  424.  
  425. // Infantry (0.5 resource per unit)
  426. let infantryCount = parseInt(document.getElementById("newInfantry").value) || 0;
  427. totalCost += Math.ceil(infantryCount * 0.5);
  428. totalProduction += infantryCount;
  429. totalCapacityNeeded += infantryCount;
  430.  
  431. // Mechs (2 resource per unit)
  432. let mechCount = parseInt(document.getElementById("newMechs").value) || 0;
  433. totalCost += mechCount * 2;
  434. totalProduction += mechCount;
  435. totalCapacityNeeded += mechCount;
  436.  
  437. // Fighters (0.5 resource per unit)
  438. let fighterCount = parseInt(document.getElementById("newFighters").value) || 0;
  439. totalCost += Math.ceil(fighterCount * 0.5);
  440. totalProduction += fighterCount;
  441. totalCapacityNeeded += fighterCount;
  442. capacityNeededWithoutGround += fighterCount;
  443.  
  444. // If Fighter II is checked, fighters count toward fleet supply
  445. if (unitData.Fighters[1]) {
  446. totalShips += fighterCount;
  447. }
  448.  
  449. // Other ships
  450. let carriers = parseInt(document.getElementById("newCarriers").value) || 0;
  451. totalCost += carriers * unitData.Carriers[0];
  452. totalShips += carriers;
  453. totalProduction += carriers;
  454.  
  455. let destroyers = parseInt(document.getElementById("newDestroyers").value) || 0;
  456. totalCost += destroyers * unitData.Destroyers[0];
  457. totalShips += destroyers;
  458. totalProduction += destroyers;
  459.  
  460. let cruisers = parseInt(document.getElementById("newCruisers").value) || 0;
  461. totalCost += cruisers * unitData.Cruisers[0];
  462. totalShips += cruisers;
  463. totalProduction += cruisers;
  464.  
  465. let dreadnoughts = parseInt(document.getElementById("newDreadnoughts").value) || 0;
  466. totalCost += dreadnoughts * unitData.Dreadnoughts[0];
  467. totalShips += dreadnoughts;
  468. totalProduction += dreadnoughts;
  469.  
  470. let warSuns = parseInt(document.getElementById("newWarSuns").value) || 0;
  471. // War Sun cost depends on tech and faction
  472. if (document.getElementById("Wa2").checked) {
  473. if (document.getElementById("faction").value === 'Embers') {
  474. totalCost += warSuns * 10; // Embers with war sun upgrade
  475. } else {
  476. totalCost += warSuns * 12; // Others with war sun upgrade
  477. }
  478. } else {
  479. totalCost += warSuns * 12; // No upgrade (rare)
  480. }
  481. totalShips += warSuns;
  482. totalProduction += warSuns;
  483.  
  484. let flagships = parseInt(document.getElementById("newFlagships").value) || 0;
  485. totalCost += flagships * unitData.Flagship[0];
  486. totalShips += flagships;
  487. totalProduction += flagships;
  488.  
  489. // Apply Sarween Tools discount if checked
  490. if (document.getElementById("sarween").checked) {
  491. totalCost = Math.max(0, totalCost - 1);
  492. }
  493.  
  494. // Update UI
  495. document.getElementById("totalCost").textContent = totalCost;
  496. document.getElementById("totalFleetNeeded").textContent = totalShips;
  497. document.getElementById("totalProduction").textContent = totalProduction;
  498. document.getElementById("totalCapacity").textContent = totalCapacityNeeded;
  499. document.getElementById("capacityWithoutGround").textContent = capacityNeededWithoutGround;
  500.  
  501. // Check if there's anything to build
  502. let buildStatus = document.getElementById("buildStatus");
  503.  
  504. if (infantryCount + mechCount + fighterCount + carriers + destroyers + cruisers + dreadnoughts + warSuns + flagships > 0) {
  505. buildStatus.textContent = "Build Requirements Calculated";
  506. buildStatus.className = "valid";
  507. } else {
  508. buildStatus.textContent = "Select units to build";
  509. buildStatus.className = "";
  510. }
  511. }
  512.  
  513. // Initialize
  514. calculateAll();
  515. </script>
  516. </body>
  517. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement