Pardus Building Class

Building class used by Pardus Trader Autopilot

目前为 2023-06-10 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/468016/1202858/Pardus%20Building%20Class.js

  1. // ==UserScript==
  2. // @name Pardus Building Class
  3. // @namespace fear.math@gmail.com
  4. // @version 2.3.0
  5. // @description Building class used by Pardus Trader Autopilot
  6. // @author Math (Orion)
  7. // ==/UserScript==
  8.  
  9. class Building {
  10. static defaultLevel = 8;
  11. static maxTicks = 12;
  12. static resourceNames = {
  13. '1': 'food', '2': 'energy', '3': 'water', '4': 'embryos', '5': 'ore', '6': 'metal', '7': 'electronics',
  14. '8': 'bots', '9': 'plastics', '10': 'hws', '11': 'medics', '12': 'gas', '13': 'chems', '14': 'gems',
  15. '15': 'liquor', '16': 'fuel', '17': 'ematter', '18': 'optics', '19': 'cells', '20': 'droids', '21': 'biowaste',
  16. '22': 'leech', '23': 'clod', '27': 'bwps', '28': 'tissue', '29': 'stims', '50': 'slaves', '51': 'drugs',
  17. };
  18.  
  19. // Credit to Taised (tiziano.m@infinito.it) who hosts the original version of this data at
  20. // 'http://www.fantamondi.it/pardus/common/building_data.js
  21. static buildingData = [
  22. { type: "Energy Well", tier: 0, resources: { "food": -1, "water": -1, "energy": 6 } },
  23. { type: "Nebula Plant", tier: 0, resources: { "food": -2, "water": -2, "ematter": -3, "energy": 35, "gas": 4 } },
  24. { type: "Space Farm", tier: 0, resources: { "energy": -4, "embryos": -5, "food": 8, "water": 2, "biowaste": 1 } },
  25.  
  26. { type: "Asteroid Mine", tier: 1, resources: { "food": -1, "energy": -1, "water": -1, "ore": 9, "gems": 2 } },
  27. { type: "Chemical Laboratory", tier: 1, resources: { "food": -1, "energy": -3, "water": -1, "chems": 9 } },
  28. { type: "Gas Collector", tier: 1, resources: { "food": -2, "energy": -2, "water": -2, "gas": 20 } },
  29. { type: "Radiation Collector", tier: 1, resources: { "food": -1, "energy": -3, "water": -1, "cells": 6 } },
  30.  
  31. { type: "Alliance Command Station", tier: 2, resources: { "energy": -6, "cells": -2 } },
  32. { type: "Brewery", tier: 2, resources: { "food": -2, "energy": -2, "water": -2, "chems": -4, "liquor": 4 } },
  33. { type: "Clod Generator", tier: 2, resources: { "biowaste": -18, "energy": -4, "chems": -4, "clod": 5 } },
  34. { type: "Fuel Collector", tier: 2, resources: { "energy": -4, "chems": -1, "fuel": 30 } },
  35. { type: "Medical Laboratory", tier: 2, resources: { "food": -2, "energy": -2, "water": -2, "gas": -7, "medics": 4 } },
  36. { type: "Military Outpost", tier: 2, resources: { "energy": -5, "fuel": -5 } },
  37. { type: "Optics Research Center", tier: 2, resources: { "food": -1, "energy": -3, "water": -1, "gems": -2, "optics": 10 } },
  38. { type: "Plastics Facility", tier: 2, resources: { "food": -2, "energy": -2, "water": -2, "chems": -3, "gas": -3, "plastics": 6 } },
  39. { type: "Recyclotron", tier: 2, resources: { "biowaste": -5, "energy": -3, "chems": -1, "food": 7, "water": 5 } },
  40. { type: "Smelting Facility", tier: 2, resources: { "food": -2, "energy": -2, "water": -2, "ore": -6, "metal": 12 } },
  41.  
  42. { type: "Electronics Facility", tier: 3, resources: { "food": -1, "energy": -4, "water": -1, "plastics": -2, "metal": -3, "electronics": 6 } },
  43. { type: "Leech Nursery", tier: 3, resources: { "food": -2, "energy": -6, "water": -10, "cells": -6, "clod": -40, "leech": 1, "biowaste": 3 } },
  44. { type: "Neural Laboratory", tier: 3, resources: { "food": -2, "water": -2, "energy": -2, "embryos": -12, "medics": -2, "tissue": 16 } },
  45. { type: "Slave Camp", tier: 3, resources: { "food": -3, "energy": -1, "water": -3, "liquor": -2, "medics": -2, "slaves": 3 } },
  46.  
  47. { type: "Battleweapons Factory", tier: 4, resources: { "food": -1, "energy": -2, "water": -1, "metal": -3, "optics": -4, "electronics": -3, "bwps": 2 } },
  48. { type: "Dark Dome", tier: 4, resources: { "slaves": -3, "energy": -1, "bodyparts": 12, "biowaste": 4 } },
  49. // { type: "Dark Dome (TSS)", tier: 4, resources: { "slaves": -2, "energy": -1, "bodyparts": 12, "biowaste": 4 } },
  50. { type: "Drug Station", tier: 4, resources: { "food": -3, "energy": -1, "water": -3, "slaves": -4, "ematter": -3, "drugs": 1 } },
  51. // { type: "Drug Station (TSS)", tier: 4, resources: { "food": -3, "energy": -1, "water": -3, "slaves": -3, "ematter": -3, "drugs": 1 } },
  52. { type: "Handweapons Factory", tier: 4, resources: { "food": -1, "energy": -2, "water": -1, "plastics": -3, "optics": -3, "electronics": -3, "hws": 2 } },
  53. { type: "Robots Factory", tier: 4, resources: { "food": -2, "energy": -2, "water": -2, "metal": -1, "optics": -2, "electronics": -4, "bots": 3 } },
  54. { type: "Stim Chip Mill", tier: 4, resources: { "food": -3, "water": -3, "ematter": -2, "tissue": -44, "electronics": -2, "stims": 2 } },
  55.  
  56. { type: "Droid Assembly Complex", tier: 5, resources: {"food": -1, "energy": -3, "water": -1, "cells": -3, "bots": -2, "droids": 1} }
  57. ];
  58.  
  59. constructor(type, sector, x, y, level = Building.defaultLevel, lastStock = {}, lastViewed = null, balance = null) {
  60. this.type = type;
  61. this.sector = sector;
  62. this.x = x;
  63. this.y = y;
  64. this.level = level;
  65. this._balance = balance;
  66. this.lastStock = lastStock;
  67. this.lastViewed = lastViewed;
  68. }
  69.  
  70. get coords() {
  71. return `[${this.x},${this.y}]`;
  72. }
  73.  
  74. // If we know the balance, return it, otherwise guess the production
  75. get balance() {
  76. return this._balance || this.calculateProduction();
  77. }
  78.  
  79. // Calculate the guessed current stock based on lastViewed time and building characteristics
  80. get stock() {
  81. const ticksPassed = this.calculateTicksPassed();
  82. const production = this.balance;
  83. const stock = this.lastStock;
  84.  
  85. // Calculate the guessed stock for each commodity
  86. for (const commodity in production) {
  87. if (production.hasOwnProperty(commodity)) {
  88. const lastStock = stock[commodity] || 0;
  89. const change = production[commodity] * ticksPassed;
  90. stock[commodity] = lastStock + change;
  91. }
  92. }
  93.  
  94. return stock;
  95. }
  96.  
  97. // Setter for level
  98. setLevel(level) {
  99. this.level = level;
  100. }
  101.  
  102. // Called on the building trade screen. Updates balance, lastStock, and lastViewed
  103. update() {
  104. this.updateBalance();
  105. this.updateLastStock();
  106. this.updateLastViewed();
  107. }
  108.  
  109. updateBalance() {
  110. const balanceValues = Building.extractBalanceValues();
  111.  
  112. const balance = {};
  113.  
  114. // Add res_production to the balance
  115. for (const key in amount) {
  116. const resourceName = Building.resourceNames[key];
  117. balance[resourceName] = balanceValues.shift();
  118. }
  119.  
  120. this._balance = balance;
  121. }
  122.  
  123. updateLastStock() {
  124. const stock = {};
  125.  
  126. for (const key in amount) {
  127. const resourceName = Building.resourceNames[key];
  128. const balance = this.balance[resourceName];
  129.  
  130. // Production's stock level is the amount above the min
  131. if (balance > 0) {
  132. stock[resourceName] = amount[key] - amount_min[key];
  133. }
  134.  
  135. // Upkeep's stock level is the amount below the max
  136. if (balance < 0) {
  137. stock[resourceName] = amount_max[key] - amount[key];
  138. }
  139. }
  140.  
  141. this.lastStock = stock;
  142. }
  143.  
  144. updateLastViewed() {
  145. this.lastViewed = Date.now();
  146. }
  147.  
  148. // Calculate the number of building ticks that have passed since lastViewed
  149. calculateTicksPassed() {
  150. const millisecondsPerTick = 6 * 60 * 60 * 1000; // Milliseconds per tick
  151.  
  152. const now = new Date();
  153. const lastViewed = new Date(this.lastViewed);
  154.  
  155. // Adjust the last viewed time forward to the nearest tick time (1:25 GMT and every 6 hours)
  156. lastViewed.setUTCMinutes(Math.round(Math.ceil((lastViewed.getUTCMinutes() - 25) / 60) * 60 + 25));
  157. lastViewed.setUTCHours(Math.round(Math.ceil((lastViewed.getUTCHours() - 1) / 6) * 6 + 1));
  158.  
  159. // Calculate the time difference in milliseconds
  160. const timeDiff = now - lastViewed;
  161.  
  162. // Calculate the number of ticks passed
  163. const ticksPassed = Math.ceil(timeDiff / millisecondsPerTick);
  164.  
  165. return Math.min(ticksPassed, Building.maxTicks);
  166. }
  167.  
  168. // Calculate the production and consumption rates based on the building type and level
  169. calculateProduction() {
  170. const buildingData = Building.buildingData.find(building => building.type === this.type);
  171.  
  172. if (!buildingData) {
  173. console.log(`Building data not found for building type: ${this.type}`);
  174. return;
  175. }
  176.  
  177. const { resources } = buildingData;
  178. const production = {};
  179.  
  180. for (const resource in resources) {
  181. const value = resources[resource];
  182.  
  183. if (value > 0) {
  184. production[resource] = Math.round(value * (1 + 0.5 * (this.level - 1)));
  185. } else if (value < 0) {
  186. production[resource] = Math.round(value * (1 + 0.4 * (this.level - 1)));
  187. }
  188. }
  189.  
  190. return production;
  191. }
  192.  
  193. // Custom serialization method
  194. toJSON() {
  195. return {
  196. type: this.type,
  197. sector: this.sector,
  198. x: this.x,
  199. y: this.y,
  200. level: this.level,
  201. lastStock: this.lastStock,
  202. lastViewed: this.lastViewed,
  203. _balance: this._balance,
  204. };
  205. }
  206.  
  207. // Custom deserialization method
  208. static fromJSON(json) {
  209. const { type, sector, x, y, level, lastStock, lastViewed, _balance } = json;
  210. const building = new Building(type, sector, x, y, level, lastStock, lastViewed, _balance);
  211. return building;
  212. }
  213.  
  214. static extractBalanceValues() {
  215. var balanceValues = [];
  216. var tableRows = document.querySelectorAll('#building_trade tr[id^="baserow"]');
  217.  
  218. tableRows.forEach(function(row) {
  219. var balanceCell = row.querySelector('td:nth-child(4)');
  220. var balanceValue = balanceCell.textContent.trim();
  221. balanceValues.push(balanceValue);
  222. });
  223.  
  224. return balanceValues.map(Number);
  225. }
  226. }