big steppy
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1793 line
50 KiB

  1. 'use strict';
  2. var things =
  3. {
  4. "Container": {
  5. "Container": Container,
  6. mass: 0,
  7. area: 0,
  8. clusters: 0,
  9. cluster_chances: 0,
  10. contents: [],
  11. descriptor: ["", ""]
  12. },
  13. //Creatures
  14. "Person": {
  15. "Person": Person,
  16. mass: 80,
  17. area: .33,
  18. clusters: 5,
  19. cluster_chances: .8,
  20. contents: [],
  21. descriptor: ["a person", "people"]
  22. },
  23. "Human": {
  24. "Human": Human,
  25. mass: 80,
  26. area: .33,
  27. clusters: 5,
  28. cluster_chances: .8,
  29. contents: [],
  30. descriptor: ["a person", "people"]
  31. },
  32. "Cow": {
  33. "Cow": Cow,
  34. mass: 300,
  35. area: 2,
  36. clusters: 15,
  37. cluster_chances: .5,
  38. contents: [],
  39. descriptor: ["a cow", "cattle"]
  40. },
  41. "Micro": {
  42. "Micro": Micro,
  43. mass: .01,
  44. area: .05,
  45. clusters: 50,
  46. cluster_chances: 1,
  47. contents: [],
  48. descriptor: ["a micro", "micros"]
  49. },
  50. "Macro": {
  51. "Macro": Macro,
  52. mass: 8e4,
  53. area: 100,
  54. clusters: 0,
  55. cluster_chances: 0,
  56. contents: [],
  57. descriptor: ["a smaller macro", "smaller macros"]
  58. },
  59. //Vehicles
  60. "Empty Car": {
  61. "Empty Car": EmptyCar,
  62. mass: 1000,
  63. area: 4,
  64. clusters: 2,
  65. cluster_chances: .3,
  66. contents: [],
  67. descriptor: ["a parked car", "parked cars"]
  68. },
  69. "Car": {
  70. "Car": Car,
  71. mass: 1000,
  72. area: 4,
  73. clusters: 4,
  74. cluster_chances: .5,
  75. contents: [["Person", 1, 4]],
  76. descriptor: ["a car", "cars"]
  77. },
  78. "Bus": {
  79. "Bus": Bus,
  80. mass: 5000,
  81. area: 12,
  82. clusters: 1,
  83. cluster_chances: .25,
  84. contents: [["Person", 2, 30]],
  85. descriptor: ["a bus", "busses"]
  86. },
  87. "Tram": {
  88. "Tram": Tram,
  89. mass: 1e4,
  90. area: 20,
  91. clusters: 1,
  92. cluster_chances: .2,
  93. contents: [["Person", 10, 50]],
  94. descriptor: ["a tram", "trams"]
  95. },
  96. "Train": {
  97. "Train": Train,
  98. mass: 5e4,
  99. area: 40,
  100. clusters: 2,
  101. cluster_chances: .1,
  102. contents: [["Person", 1, 4, "engine"], ["Train Car", 2, 10]],
  103. descriptor: ["a train", "trains"]
  104. },
  105. "Train Car": {
  106. "Train Car": TrainCar,
  107. mass: 7500,
  108. area: 20,
  109. clusters: 1,
  110. cluster_chances: .05,
  111. contents: [["Person", 10, 40]],
  112. descriptor: ["a train car", "train cars"]
  113. },
  114. "Helicopter": {
  115. "Helicopter": Helicopter,
  116. mass: 1500,
  117. area: 12,
  118. clusters: 0,
  119. cluster_chances: 0,
  120. contents: [["Person", 4, 16]],
  121. descriptor: ["a helicopter", "helicopters"]
  122. },
  123. "Empty Helicopter": {
  124. "Empty Helicopter": EmptyHelicopter,
  125. mass: 1500,
  126. area: 12,
  127. clusters: 3,
  128. cluster_chances: 0.05,
  129. contents: [],
  130. descriptor: ["a parked helicopter", "parked helicopters"]
  131. },
  132. "Plane": {
  133. "Plane": Plane,
  134. mass: 6500,
  135. area: 50,
  136. clusters: 1,
  137. cluster_chances: .05,
  138. contents: [],
  139. descriptor: ["a small plane", "small planes"]
  140. },
  141. "Empty Plane": {
  142. "Empty Plane": EmptyPlane,
  143. mass: 6500,
  144. area: 50,
  145. clusters: 1,
  146. cluster_chances: .05,
  147. contents: [["Person", 2, 9]],
  148. descriptor: ["a parked plane", "parked aircraft"]
  149. },
  150. "Airliner": {
  151. "Airliner": Airliner,
  152. mass: 6500,
  153. area: 1250,
  154. clusters: 1,
  155. cluster_chances: .05,
  156. contents: [["Person", 5, 300]],
  157. descriptor: ["an airliner", "airliners"]
  158. },
  159. "Empty Airliner": {
  160. "Empty Airliner": EmptyAirliner,
  161. mass: 6500,
  162. area: 1250,
  163. clusters: 1,
  164. cluster_chances: .05,
  165. contents: [],
  166. descriptor: ["a parked airliner", "parked airliners"]
  167. },
  168. //Buildings
  169. "House": {
  170. "House": House,
  171. mass: 1e4,
  172. area: 150,
  173. clusters: 5,
  174. cluster_chances: .5,
  175. contents: [["Person", 0, 8], ["Empty Car", 0, 2]],
  176. descriptor: ["house", "houses"]
  177. },
  178. "Business": {
  179. "Business": Business,
  180. mass: 5e4,
  181. area: 400,
  182. clusters: 5,
  183. cluster_chances: .25,
  184. contents: [["Person", 0, 30], ["Car", 0, 5], ["Empty Car", 0, 20]],
  185. descriptor: ["a local business", "buildings"]
  186. },
  187. "Barn": {
  188. "Barn": Barn,
  189. mass: 5e3,
  190. area: 300,
  191. clusters: 1,
  192. cluster_chances: .1,
  193. contents: [["Person", 0, 2], ["Cow", 30, 70]],
  194. descriptor: ["a barn", "barns"]
  195. },
  196. "Small Hangar": {
  197. "Small Hangar": SmallHangar,
  198. mass: 5e5,
  199. area: 2500,
  200. clusters: 1,
  201. cluster_chances: .1,
  202. contents: [["Person", 0, 3], ["Plane", 0, 1], ["Empty Plane", 2, 6]],
  203. descriptor: ["a small hangar", "small hangars"]
  204. },
  205. "Helicopter Hangar": {
  206. "Helicopter Hangar": HelicopterHangar,
  207. mass: 5e5,
  208. area: 2000,
  209. clusters: 1,
  210. cluster_chances: .1,
  211. contents: [["Person", 0, 3], ["Helicopter", 0, 1], ["Helicopter", 2, 6]],
  212. descriptor: ["a helicopter hangar", "helicopter hangar"]
  213. },
  214. "Large Hangar": {
  215. "Large Hangar": LargeHangar,
  216. mass: 5e6,
  217. area: 8000,
  218. clusters: 1,
  219. cluster_chances: .1,
  220. contents: [["Person", 0, 5], ["Airliner", 0, 1], ["Empty Airliner", 1, 2]],
  221. descriptor: ["an aircraft hangar", "hangars"]
  222. },
  223. "Small Skyscraper": {
  224. "Small Skyscraper": SmallSkyscraper,
  225. mass: 1e7,
  226. area: 1000,
  227. clusters: 2,
  228. cluster_chances: .25,
  229. contents: [["Person", 150, 750], ["Empty Car", 10, 50]],
  230. descriptor: ["a small skyscraper", "small skyscrapers"]
  231. },
  232. "Large Skyscraper": {
  233. "Large Skyscraper": LargeSkyscraper,
  234. mass: 8e7,
  235. area: 2000,
  236. clusters: 1,
  237. cluster_chances: .25,
  238. contents: [["Person", 500, 1500], ["Empty Car", 20, 100]],
  239. descriptor: ["a large skyscraper", "large skyscrapers"]
  240. },
  241. "Parking Garage": {
  242. "Parking Garage": ParkingGarage,
  243. mass: 1e7,
  244. area: 750,
  245. clusters: 1,
  246. cluster_chances: .1,
  247. contents: [["Person", 10, 200], ["Empty Car", 100, 300], ["Car", 5, 30]],
  248. descriptor: ["a parking garage", "parking garages"]
  249. },
  250. //Places
  251. "Ranch": {
  252. "Ranch": Ranch,
  253. mass: 2e7,
  254. area: 4e4,
  255. clusters: 0,
  256. cluster_chances: 0,
  257. contents: [["Person", 10, 50], ["House", 1, 3], ["Barn", 1, 2]],
  258. descriptor: ["a ranch", "ranchs"]
  259. },
  260. "Airstrip": {
  261. "Airstrip": Airstrip,
  262. mass: 2e7,
  263. area: 9e5,
  264. clusters: 0,
  265. cluster_chances: 0,
  266. contents: [["Person", 10, 50], ["Small Hangar", 1, 3], ["Plane", 0, 2], ["Helicopter", 0, 1], ["Helicopter Hangar", 0, 1], ["Car", 0, 5], ["Empty Car", 0, 20]],
  267. descriptor: ["an airstrip", "airstrips"]
  268. },
  269. "Airport": {
  270. "Airport": Airport,
  271. mass: 1.5e8,
  272. area: 6e6,
  273. clusters: 0,
  274. cluster_chances: 0,
  275. contents: [["Person", 1500, 4000], ["Small Hangar", 4, 12], ["Plane", 2, 5], ["Helicopter", 1, 3], ["Helicopter Hangar", 2, 6], ["Airliner", 1, 3], ["Large Hangar", 2, 6], ["Car", 20, 75], ["Empty Car", 400, 1000]],
  276. descriptor: ["an airport", "airports"]
  277. },
  278. "Town": {
  279. "Town": Town,
  280. mass: 1,
  281. area: 1e7,
  282. clusters: 5,
  283. cluster_chances: .1,
  284. contents: [["Person", 10000, 100000], ["House", 5000, 50000], ["Empty Car", 200, 800], ["Car", 500, 80000], ["Bus", 5, 25], ["Train", 5, 25], ["Business", 500, 5000]],
  285. descriptor: ["a town", "towns"]
  286. },
  287. "City": {
  288. "City": City,
  289. mass: 1,
  290. area: 1e9,
  291. clusters: 0,
  292. cluster_chances: .2,
  293. contents: [["Person", 100000, 1500000], ["House", 20000, 200000], ["Empty Car", 10000, 100000], ["Car", 7500, 125000], ["Bus", 200, 400], ["Train", 10, 50], ["Tram", 25, 100], ["Small Skyscraper", 50, 300], ["Large Skyscraper", 10, 75], ["Parking Garage", 5, 10], ["Business", 2000, 10000]],
  294. descriptor: ["a city", "cities"]
  295. },
  296. "Continent": {
  297. "Continent": Continent,
  298. mass: 1e21,
  299. area: 1.5e13,
  300. clusters: 5,
  301. cluster_chances: .5,
  302. contents: [["Person", 1000000, 15000000], ["House", 2500, 10000], ["Car", 25000, 375000], ["Train", 50, 500], ["Town", 500, 1000], ["City", 50, 250], ["Business", 250, 1000]],
  303. descriptor: ["a continent", "continents"]
  304. },
  305. //Celestial Bodies
  306. "Planet": {
  307. "Planet": Planet,
  308. mass: 5.972e24,
  309. area: 2.5e14,
  310. clusters: 0,
  311. cluster_chances: 1,
  312. contents: [["Continent", 4, 9]],
  313. descriptor: ["a planet", "planets"]
  314. },
  315. "Star": {
  316. "Star": Star,
  317. mass: 1e40,
  318. area: 3e18,
  319. clusters: 1,
  320. cluster_chances: 1,
  321. contents: [],
  322. descriptor: ["a star", "stars"]
  323. },
  324. "Solar System": {
  325. "Solar System": SolarSystem,
  326. mass: 1,
  327. area: 3e21,
  328. clusters: 1,
  329. cluster_chances: 1,
  330. contents: [["Star", 1, 1], ["Planet", 5, 15]],
  331. descriptor: ["a solar system", "solar systems"]
  332. },
  333. "Galaxy": {
  334. "Galaxy": Galaxy,
  335. mass: 1,
  336. area: 2e45,
  337. clusters: 1,
  338. cluster_chances: 1,
  339. contents: [["Star", 1e9, 500e9], ["Solar System", 1e8, 500e8]],
  340. descriptor: ["a galaxy", "galaxies"]
  341. },
  342. "Cluster": {
  343. "Cluster": Cluster,
  344. mass: 1,
  345. area: 2e49,
  346. clusters: 1,
  347. cluster_chances: 1,
  348. contents: [["Galaxy", 200, 5000]],
  349. descriptor: ["a cluster", "clusters"]
  350. },
  351. "Universe": {
  352. "Universe": Universe,
  353. mass: 1,
  354. area: 7e53,
  355. clusters: 1,
  356. cluster_chances: 1,
  357. contents: [["Cluster", 1.5e9, 2.5e9]],
  358. descriptor: ["a universe", "universes"]
  359. },
  360. "Multiverse": {
  361. "Multiverse": Multiverse,
  362. mass: 1,
  363. area: 5e56,
  364. clusters: 1,
  365. cluster_chances: 1,
  366. contents: [["Universe", 100, 1000]],
  367. descriptor: ["a multiverse", "multiverses"]
  368. },
  369. //Military
  370. "Soldier": {
  371. "Soldier": Soldier,
  372. mass: 80,
  373. area: 1,
  374. clusters: 2,
  375. cluster_chances: .2,
  376. contents: [],
  377. descriptor: ["a soldier", "soldiers"]
  378. },
  379. "Tank": {
  380. "Tank": Tank,
  381. mass: 5000,
  382. area: 20,
  383. clusters: 2,
  384. cluster_chances: .25,
  385. contents: [["Soldier", 3, 5]],
  386. descriptor: ["a tank", "tanks"]
  387. },
  388. "Artillery": {
  389. "Artillery": Artillery,
  390. mass: 7000,
  391. area: 25,
  392. clusters: 3,
  393. cluster_chances: .5,
  394. contents: [["Soldier", 4, 6]],
  395. descriptor: ["an artillery tank", "artillery tanks"]
  396. },
  397. "Military Helicopter": {
  398. "Military Helicopter": MilitaryHelicopter,
  399. mass: 1500,
  400. area: 12,
  401. clusters: 0,
  402. cluster_chances: 0,
  403. contents: [["Soldier", 4, 16]],
  404. descriptor: ["a helicopter", "helicopters"]
  405. },
  406. "Squad": {
  407. "Squad": Squad,
  408. mass: 1,
  409. area: 30,
  410. clusters: 20,
  411. cluster_chances: .05,
  412. contents: [["Soldier", 6, 9]],
  413. descriptor: ["a squad", "squads"]
  414. },
  415. "Platoon": {
  416. "Platoon": Platoon,
  417. mass: 100,
  418. area: 150,
  419. clusters: 2,
  420. cluster_chances: .1,
  421. contents: [["Soldier", 16, 44]],
  422. descriptor: ["a military platoon", "platoons"]
  423. },
  424. "Company": {
  425. "Company": Company,
  426. mass: 500,
  427. area: 600,
  428. clusters: 2,
  429. cluster_chances: .1,
  430. contents: [["Soldier", 60, 200]],
  431. descriptor: ["a company of soldiers", "companies"]
  432. },
  433. "Battalion": {
  434. "Battalion": Battalion,
  435. mass: 1000,
  436. area: 3500,
  437. clusters: 2,
  438. cluster_chances: .1,
  439. contents: [["Soldier", 300, 1000]],
  440. descriptor: ["a battalion", "battalions"]
  441. },
  442. "Brigade": {
  443. "Brigade": Brigade,
  444. mass: 1500,
  445. area: 2e4,
  446. clusters: 2,
  447. cluster_chances: .1,
  448. contents: [["Soldier", 1500, 3200]],
  449. descriptor: ["a brigade", "brigades"]
  450. },
  451. "Division": {
  452. "Division": Division,
  453. mass: 2000,
  454. area: 8e4,
  455. clusters: 3,
  456. cluster_chances: .1,
  457. contents: [["Soldier", 10000, 16000]],
  458. descriptor: ["a division", "divisions"]
  459. },
  460. "Tank Division": {
  461. "Tank Division": TankDivision,
  462. mass: 3000,
  463. area: 1e5,
  464. clusters: 1,
  465. cluster_chances: .15,
  466. contents: [["Soldier", 8000, 1200], ["Tank", 250, 500]],
  467. descriptor: ["a tank division", "tank divisions"]
  468. },
  469. "Army": {
  470. "Army": Army,
  471. mass: 5000,
  472. area: 1e6,
  473. clusters: 2,
  474. cluster_chances: .1,
  475. contents: [["Soldier", 40000, 75000]],
  476. descriptor: ["an army", "armies"]
  477. },
  478. };
  479. //Alterante Army Structuring, may be used later
  480. //"Squad": [["Soldier",6,9]],
  481. // "Platoon": [["Squad",3,4]],
  482. //"Company": [["Platoon",3,5],["Squad",0,2]],
  483. //"Battalion": [["Company",4,6]],
  484. //"Brigade": [["Battalion",2,5],["Company",0,3]],
  485. //"Division": [["Brigade",2,4]],
  486. //"Tank Division": [["Brigade",2,4],["Tank",250,500]],
  487. //"Army": [["Division",3,8],["Tank Division",1,5]],
  488. // replace all instances of from with to
  489. function contents_substitute(from, to) {
  490. for (let key in contents) {
  491. if (contents.hasOwnProperty(key)) {
  492. let type = contents[key];
  493. for (let i = 0; i < type.length; i++) {
  494. if (type[i][0] == from) {
  495. type[i][0] = to;
  496. }
  497. }
  498. }
  499. }
  500. }
  501. // remove all instances of thing
  502. function contents_remove(thing) {
  503. for (let key in contents) {
  504. if (contents.hasOwnProperty(key)) {
  505. let type = contents[key];
  506. for (let i = 0; i < type.length; i++) {
  507. if (type[i][0] == thing) {
  508. type.splice(i, 1);
  509. --i;
  510. }
  511. }
  512. }
  513. }
  514. }
  515. // adds thing to parent
  516. function contents_insert(parent, thing, min, max, label) {
  517. let owner = things[parent].contents;
  518. if (label == undefined)
  519. owner.push([thing, min, max]);
  520. else
  521. owner.push([thing, min, max, label]);
  522. }
  523. function initContents(name, count) { //builds the contents for each destrucable(thing) when called
  524. let result = {};
  525. let type = things[name].contents;
  526. for (let i = 0; i < type.length; i++) {
  527. let amount = distribution(type[i][1], type[i][2], count); //arrays of contents look like ["thing name",min,max,"optional name"] so those values have to pulled out
  528. if (amount > 0) {
  529. // if a custom label is supplied, use it!
  530. if (type[i].length == 4) //if has optional name
  531. result[type[i][3]] = new things[type[i][0]][type[i][0]](amount); //creates a "thing name" under the key of "optional name"
  532. else
  533. result[type[i][0]] = new things[type[i][0]][type[i][0]](amount);
  534. }
  535. }
  536. return result;
  537. }
  538. function get_living_prey(sum) {
  539. let total = 0;
  540. for (let key in sum) {
  541. if (sum.hasOwnProperty(key)) {
  542. if (key == "Micro" || key == "Macro" || key == "Person" || key == "Cow" || key == 'Soldier')
  543. total += sum[key];
  544. }
  545. }
  546. return total;
  547. }
  548. // general logic: each step fills in a fraction of the remaining space
  549. function fill_area(area, weights, variance = 0.15) {
  550. area = area + Math.random() * variance * 2 * area - variance * area;
  551. var result = [];
  552. var candidates = [];
  553. for (var key in weights) {
  554. if (weights.hasOwnProperty(key)) {
  555. candidates.push({ "name": key, "area": things[key].area, "weight": weights[key] });
  556. }
  557. }
  558. candidates = candidates.sort(function (x, y) {
  559. return x.area - y.area;
  560. });
  561. while (candidates.length > 0) {
  562. var candidate = candidates.pop();
  563. if (candidate.area > area)
  564. continue;
  565. var max = Math.floor(area / candidate.area);
  566. var limit = Math.min(max, 1000);
  567. var count = 0;
  568. var loopvar = 0;
  569. // for small amounts, actually do the randomness
  570. // the first few ones get a much better shot
  571. // if we have nothing at all, it's even better!
  572. while (loopvar < limit) {
  573. if (loopvar == 0 && result.length == 0) {
  574. ++count;
  575. }
  576. else if (loopvar <= things[candidate.name].clusters) {
  577. if (Math.random() < candidate.weight ? 1 : Math.random() < things[candidate.name].cluster_chances) {
  578. ++count;
  579. }
  580. }
  581. else {
  582. count += Math.random() < candidate.weight ? 1 : 0;
  583. }
  584. ++loopvar;
  585. }
  586. // if we're doing more than the limit, then we just add on the rest, with some variance
  587. if (limit < max) {
  588. const base = (max - limit) * candidate.weight;
  589. count += Math.round(base - base / 10 + base * Math.random() / 5);
  590. }
  591. area -= count * candidate.area;
  592. if (count > 0)
  593. result.push(new things[candidate.name][candidate.name](count));
  594. }
  595. return new Container(result);
  596. }
  597. // maybe make this something that approximates a
  598. // normal distribution; doing this 15,000,000 times is bad...
  599. // solution: only a few are random lul
  600. // improvement: take up to 100 samples, then use that to scale the final result
  601. function distribution(min, max, samples) {
  602. var result = 0;
  603. var limit = Math.min(100, samples);
  604. if (limit < samples) {
  605. let dist = 0;
  606. for (let i = 0; i < limit; i++) {
  607. dist += Math.random();
  608. }
  609. dist /= 100;
  610. return Math.floor(dist * samples * (max - min + 1) + samples * min);
  611. } else {
  612. for (let i = 0; i < limit; i++) {
  613. result += Math.floor(Math.random() * (max - min + 1) + min);
  614. }
  615. }
  616. return result;
  617. }
  618. function defaultMultiply(thing) {
  619. return function (amount) {
  620. thing.count *= amount;
  621. for (var key in thing.contents) {
  622. if (thing.contents.hasOwnProperty(key)) {
  623. thing.contents[key].multiply(amount);
  624. }
  625. }
  626. };
  627. }
  628. function defaultArea(thing) {
  629. return things[thing.name].area;
  630. }
  631. function defaultMass(thing) {
  632. return things[thing.name].mass;
  633. }
  634. function defaultDescribeOne(thing) {
  635. return function (verbose) { //verbose doesn't matter for this case, becasue it handles things with no extra text to use when being verbose
  636. return things[thing.name].descriptor[0];
  637. }
  638. }
  639. function defaultMerge(thing) { //this merges all objects into one containers
  640. return function (container) {
  641. var newCount = this.count + container.count;
  642. var newThing = new things[thing.name][thing.name](newCount);
  643. newThing.contents = {};
  644. for (var key in this.contents) {
  645. if (this.contents.hasOwnProperty(key)) {
  646. newThing.contents[key] = this.contents[key];
  647. }
  648. }
  649. for (key in container.contents) {
  650. if (container.contents.hasOwnProperty(key)) {
  651. if (this.contents.hasOwnProperty(key)) {
  652. newThing.contents[key] = this.contents[key].merge(container.contents[key]);
  653. } else {
  654. newThing.contents[key] = container.contents[key];
  655. }
  656. }
  657. }
  658. return newThing;
  659. };
  660. }
  661. function listSum(sum) {
  662. let result = [];
  663. for (let key in sum) {
  664. if (sum.hasOwnProperty(key)) {
  665. result.push(new things[key][key](sum[key]).describe(false));
  666. }
  667. }
  668. return merge_things(result);
  669. }
  670. // turn a nested object into a container with everything on one level
  671. function flatten(thing) {
  672. let dict = defaultSum(thing)();
  673. let list = [];
  674. Object.entries(dict).forEach(function ([key, val]) {
  675. let obj = new things[key][key](val);
  676. obj.contents = [];
  677. list.push(obj);
  678. });
  679. list.sort(function (x, y) {
  680. if (y.area != x.area) {
  681. return y.area - x.area;
  682. } else {
  683. return x.name.localeCompare(y.name);
  684. }
  685. });
  686. return new Container(list);
  687. }
  688. function defaultSum(thing) {
  689. return function () {
  690. var counts = {};
  691. if (thing.name != "Container")
  692. counts[thing.name] = thing.count;
  693. for (var key in thing.contents) {
  694. if (thing.contents.hasOwnProperty(key)) {
  695. var subcount = thing.contents[key].sum();
  696. for (var subkey in subcount) {
  697. if (!counts.hasOwnProperty(subkey)) {
  698. counts[subkey] = 0;
  699. }
  700. counts[subkey] += subcount[subkey];
  701. }
  702. }
  703. }
  704. return counts;
  705. };
  706. }
  707. function defaultSumProperty(thing) {
  708. return function (prop) {
  709. var total = 0;
  710. total += thing[prop] * thing.count;
  711. for (var key in thing.contents) {
  712. if (thing.contents.hasOwnProperty(key)) {
  713. total += thing.contents[key].sum_property(prop);
  714. }
  715. }
  716. return total;
  717. };
  718. }
  719. function defaultAddContent(thing) {
  720. return function (name, min, max, count) {
  721. if (min == max) {
  722. let object = new things[name](min * count);
  723. thing.contents[object.name] = object;
  724. } else {
  725. let object = new things[name](distribution(min, max, count));
  726. thing.contents[object.name] = object;
  727. }
  728. };
  729. }
  730. function DefaultEntity() {
  731. this.sum = defaultSum;
  732. this.area = defaultArea;
  733. this.mass = defaultMass;
  734. this.sum_property = defaultSumProperty;
  735. this.merge = defaultMerge;
  736. this.multiply = defaultMultiply;
  737. this.describeSimple = defaultDescribeSimple;
  738. this.describeOne = defaultDescribeOne;
  739. return this;
  740. }
  741. // god I love reinventing the wheel
  742. function copy_defaults(self, proto) { //loads the values defined in things into the fuction that calls it
  743. for (var key in proto) { //proto will always be a new DefaultEntity, self is the parent function
  744. if (proto.hasOwnProperty(key)) {
  745. self[key] = proto[key](self);
  746. }
  747. }
  748. }
  749. // combine strings into a list with proper grammar
  750. function merge_things(list, semicolons = false) {
  751. if (list.length == 0) {
  752. return "";
  753. } else if (list.length == 1) {
  754. return list[0];
  755. } else if (list.length == 2) {
  756. return list[0] + " and " + list[1];
  757. } else {
  758. var result = "";
  759. list.slice(0, list.length - 1).forEach(function (term) {
  760. result += term + ", ";
  761. });
  762. result += "and " + list[list.length - 1];
  763. return result;
  764. }
  765. }
  766. // combine the adjectives for something into a single string
  767. function merge_desc(list) {
  768. var result = "";
  769. list.forEach(function (term) {
  770. if (term != "")
  771. result += term + " ";
  772. });
  773. // knock off the last space
  774. if (result.length > 0) {
  775. result = result.substring(0, result.length - 1);
  776. }
  777. let article = "a "
  778. //a/an overwriting terms
  779. let forcedTerms = ["honor", "heir"]; //words that need to start with an but don't start with a,e,i,o,u
  780. let force = false;
  781. for (let i of forcedTerms) {
  782. if (i === result.substring(0, i.length)) { force = true; }
  783. }
  784. let exceptionTerms = ["uniform", "unique"]; //words that need to start with a and start with a,e,i,o,u
  785. let exception = false;
  786. for (let i of exceptionTerms) {
  787. if (i === result.substring(0, i.length)) { exception = true; }
  788. }
  789. //check if the string should start with an
  790. if ((force == true) || (exception == false && ((result.charAt(0) == "a") || (result.charAt(0) == "e") || (result.charAt(0) == "i") || (result.charAt(0) == "o") || (result.charAt(0) == "u")))) {
  791. article = "an ";
  792. }
  793. result = article + result;
  794. return result;
  795. }
  796. // describes everything in the container
  797. function describe_all(contents, verbose = true, except = []) {
  798. var things = [];
  799. for (var key in contents) {
  800. if (contents.hasOwnProperty(key) && !except.includes(key)) {
  801. things.push(contents[key].describe(verbose));
  802. }
  803. }
  804. return merge_things(things);
  805. }
  806. function random_desc(list, odds = 1) { //strings together an array into a series of words
  807. if (Math.random() < odds)
  808. return list[Math.floor(Math.random() * list.length)];
  809. else
  810. return "";
  811. }
  812. function defaultDescribeSimple(thing) {
  813. return function (flat) {
  814. if (flat) {
  815. return flatten(thing).describe(false)
  816. } else {
  817. return thing.describe(false);
  818. }
  819. }
  820. }
  821. function defaultDescribe(verbose = true, parent, descAs) {
  822. let descriptorEnd = " inside";
  823. let descriptorConjunction = " with ";
  824. let groupLessThan3 = false;
  825. switch (descAs) {
  826. case "vehicle":
  827. descriptorEnd = pickString(" inside", " inside", " inside", " inside", " riding inside", " trapped inside", " sitting inside");
  828. break;
  829. case "community":
  830. groupLessThan3 = true;
  831. descriptorEnd = " in " + (parent.count == 1 ? "it" : "them");
  832. break;
  833. case "celestial":
  834. groupLessThan3 = true;
  835. descriptorConjunction = pickString(" made up of ", " consisting of ", " containing ");
  836. descriptorEnd = "";
  837. break;
  838. case "military":
  839. groupLessThan3 = true;
  840. descriptorConjunction = pickString(" of ", " of ", " made up of ", " comprised of ", " containing ");
  841. descriptorEnd = "";
  842. break;
  843. case "generic vehicle":
  844. groupLessThan3 = true;
  845. descriptorEnd = pickString(" inside", " inside", " inside", " inside", " riding inside", " trapped inside", " sitting inside");
  846. break;
  847. } if (verbose) {
  848. if (parent.count = 1) { //singular parent (specifying single to catch cases where groupLessThan3 = true, otherwise it would output "1 towns" instead of "a town"
  849. if (things[parent.name].contents.length > 0) {
  850. return (things[parent.name].descriptor[0] + descriptorConjunction + describe_all(parent.contents, false) + descriptorEnd);
  851. } else {
  852. return parent.describeOne(verbose);
  853. }
  854. }
  855. else if (parent.count <= 3 && groupLessThan3 == false) { // less than 3 parents and an ojbect that has varety when described
  856. var list = [];
  857. for (var i = 0; i < parent.count; i++) {
  858. list.push(parent.describeOne(parent.count <= 2));
  859. }
  860. if (things[parent.name].contents.length > 0) {
  861. return (merge_things(list) + descriptorConjunction + describe_all(parent.contents, false) + descriptorEnd);
  862. } else {
  863. return merge_things(list);
  864. }
  865. } else {//if there are more than 3 of the object
  866. if (things[parent.name].contents.length > 0) {
  867. return (parent.count + " " + things[parent.name].descriptor[1] + descriptorConjunction + describe_all(parent.contents, false) + descriptorEnd);
  868. } else {
  869. return (parent.count + " " + things[parent.name].descriptor[1]);
  870. }
  871. }
  872. } else {//not verbose
  873. return (parent.count > 1 ? (parent.count + " " + things[parent.name].descriptor[1]) : things[parent.name].descriptor[0]);
  874. }
  875. }
  876. function Container(contents = []) {
  877. this.name = "Container";
  878. copy_defaults(this, new DefaultEntity());
  879. if (Number.isInteger(contents))
  880. this.count = contents;
  881. else
  882. this.count = 0;
  883. this.contents = {};
  884. for (var i = 0; i < contents.length; i++) {
  885. this.contents[contents[i].name] = contents[i];
  886. }
  887. for (var key in this.contents) {
  888. if (this.contents.hasOwnProperty(key)) {
  889. this.count += this.contents[key].count;
  890. }
  891. }
  892. this.describe = function (verbose = true) {
  893. return describe_all(this.contents, verbose);
  894. };
  895. return this;
  896. }
  897. function Person(count = 1) {
  898. this.name = "Person";
  899. copy_defaults(this, new DefaultEntity());
  900. this.mass = ((Math.random() - .5) * 20) + this.mass;
  901. this.count = count;
  902. this.contents = initContents(this.name, this.count);
  903. this.describeOne = function (verbose = true) {
  904. var body = random_desc(["skinny", "fat", "tall", "short", "stocky", "spindly", "muscular", "fit", "multi-colored"], (verbose ? 0.6 : 0));
  905. var sex = random_desc(["male", "female"], (verbose ? 0.75 : 0));
  906. var species = "";
  907. species = random_desc(["wolf", "cat", "dog", "squirrel", "horse", "hyena", "fox", "jackal", "crux", "sergal", "coyote", "rabbit", "lizard", "avian"]);
  908. return merge_desc([body, sex, species]);
  909. };
  910. this.describe = function (verbose = true) {
  911. return defaultDescribe(verbose, this);
  912. }
  913. return this;
  914. }
  915. function Human(count = 1) {
  916. this.name = "Person";
  917. copy_defaults(this, new DefaultEntity());
  918. this.mass = ((Math.random() - .5) * 20) + this.mass;
  919. this.count = count;
  920. this.contents = initContents(this.name, this.count);
  921. this.describeOne = function (verbose = true) {
  922. var body = random_desc(["skinny", "fat", "tall", "short", "stocky", "spindly", "muscular", "fit", "tanned"], (verbose ? 0.6 : 0));
  923. var sex = random_desc(["man", "woman"], 1);
  924. return merge_desc([body, sex]);
  925. };
  926. this.describe = function (verbose = true) {
  927. return defaultDescribe(verbose, this);
  928. }
  929. return this;
  930. }
  931. function Cow(count = 1) {
  932. this.name = "Cow";
  933. copy_defaults(this, new DefaultEntity());
  934. this.count = count;
  935. this.contents = initContents(this.name, this.count);
  936. this.describeOne = function (verbose = true) {
  937. var body = random_desc(["skinny", "fat", "tall", "short", "stocky", "spindly", "brown"], (verbose ? 0.6 : 0));
  938. var sex = random_desc(["bull", "steer", "cow", "cow", "cow", "heifer"], (verbose ? 1 : 0));
  939. return merge_desc([body, sex]);
  940. };
  941. this.describe = function (verbose = true) {
  942. return defaultDescribe(verbose, this);
  943. }
  944. return this;
  945. }
  946. function EmptyCar(count = 1) {
  947. this.name = "Empty Car";
  948. copy_defaults(this, new DefaultEntity());
  949. this.count = count;
  950. this.contents = initContents(this.name, this.count);
  951. this.describeOne = function (verbose = true) {
  952. var color = random_desc(["black", "black", "gray", "gray", "blue", "red", "tan", "white", "white"]);
  953. var adjective = random_desc(["rusty", "brand-new", "luxury", "beat-up", "dented", "restored", "classic"], 0.3);
  954. var type = random_desc(["SUV", "coupe", "sedan", "truck", "van", "convertible"]);
  955. return merge_desc(["parked", adjective, color, type]);
  956. };
  957. this.describe = function (verbose = true) {
  958. return defaultDescribe(verbose, this, "vehicle");
  959. }
  960. }
  961. function Car(count = 1) {
  962. this.name = "Car";
  963. copy_defaults(this, new DefaultEntity());
  964. this.count = count;
  965. this.contents = initContents(this.name, this.count);
  966. this.describeOne = function (verbose = true) {
  967. var color = random_desc(["black", "black", "gray", "gray", "blue", "red", "tan", "white", "white"], (verbose ? 1 : 0));
  968. var adjective = random_desc(["rusty", "brand-new", "luxury", "beat-up", "dented", "restored", "classic"], (verbose ? 0.3 : 0));
  969. var type = random_desc(["SUV", "coupe", "sedan", "truck", "van", "convertible"]);
  970. return merge_desc([adjective, color, type]);
  971. };
  972. this.describe = function (verbose = true) {
  973. return defaultDescribe(verbose, this, "vehicle");
  974. }
  975. }
  976. function Bus(count = 1) {
  977. this.name = "Bus";
  978. copy_defaults(this, new DefaultEntity());
  979. this.count = count;
  980. this.contents = initContents(this.name, this.count);
  981. this.describeOne = function (verbose = true) {
  982. var adjective = random_desc(["rusty", "brand-new", "aging", "modern"], (verbose ? 0.3 : 0));
  983. var color = random_desc(["black", "tan", "gray"], (verbose ? 1 : 0));
  984. var type = random_desc(["bus", "double-decker bus", "articulating bus", "open-top bus", "sleeper bus", "intercity bus"]);
  985. return merge_desc([adjective, color, type]);
  986. };
  987. this.describe = function (verbose = true) {
  988. return defaultDescribe(verbose, this, "vehicle");
  989. }
  990. }
  991. function Tram(count = 1) {
  992. this.name = "Tram";
  993. copy_defaults(this, new DefaultEntity());
  994. this.count = count;
  995. this.contents = initContents(this.name, this.count);
  996. this.describeOne = function (verbose = true) {
  997. var adjective = random_desc(["rusty", "weathered", "well-maintained",], (verbose ? 0.3 : 0));
  998. var color = random_desc(["blue", "brown", "gray"], (verbose ? 1 : 0));
  999. var type = random_desc(["tram"]);
  1000. return merge_desc([adjective, color, type]);
  1001. };
  1002. this.describe = function (verbose = true) {
  1003. return defaultDescribe(verbose, this, "vehicle");
  1004. }
  1005. this.anal_vore = function () {
  1006. return "You slide " + this.describe() + " up your tight ass";
  1007. };
  1008. }
  1009. function EmptyHelicopter(count = 1) {
  1010. this.name = "Empty Helicopter";
  1011. copy_defaults(this, new DefaultEntity());
  1012. this.count = count;
  1013. this.contents = initContents(this.name, this.count);
  1014. this.describeOne = function (verbose = true) {
  1015. var color = random_desc(["blue", "white", "white", "red", "black", "gold", "yellow"], (verbose ? 0.6 : 0));
  1016. var type = random_desc(["bubble coptor", "helicopter", "helicopter", "news chopper", "police helicopter", "chopper"]);
  1017. return merge_desc([adjective, color, type]);
  1018. };
  1019. this.describe = function (verbose = true) {
  1020. return defaultDescribe(verbose, this, "vehicle");
  1021. }
  1022. }
  1023. function Helicopter(count = 1) {
  1024. this.name = "Helicopter";
  1025. copy_defaults(this, new DefaultEntity());
  1026. this.count = count;
  1027. this.contents = initContents(this.name, this.count);
  1028. this.describeOne = function (verbose = true) {
  1029. var color = random_desc(["blue", "white", "white", "red", "black", "gold", "yellow"], (verbose ? 0.6 : 0));
  1030. var type = random_desc(["bubble coptor", "helicopter", "helicopter", "news chopper", "police helicopter", "chopper"]);
  1031. return merge_desc([adjective, color, type]);
  1032. };
  1033. this.describe = function (verbose = true) {
  1034. return defaultDescribe(verbose, this, "vehicle");
  1035. }
  1036. }
  1037. function EmptyPlane(count = 1) {
  1038. this.name = "Empty Plane";
  1039. copy_defaults(this, new DefaultEntity());
  1040. this.count = count;
  1041. this.contents = initContents(this.name, this.count);
  1042. this.describeOne = function (verbose = true) {
  1043. var adjective = random_desc(["brand-new", "aging", "modern"], (verbose ? 0.2 : 0));
  1044. var color = random_desc(["blue", "white", "white", "blue and white", "red and white", "black", "gold"], (verbose ? 0.9 : 0));
  1045. var type = random_desc(["luxury jet", "business jet", "single-engine plane", "light aircraft"]);
  1046. return merge_desc([adjective, color, type]);
  1047. };
  1048. this.describe = function (verbose = true) {
  1049. return defaultDescribe(verbose, this, "vehicle");
  1050. }
  1051. }
  1052. function Plane(count = 1) {
  1053. this.name = "Plane";
  1054. copy_defaults(this, new DefaultEntity());
  1055. this.count = count;
  1056. this.contents = initContents(this.name, this.count);
  1057. this.describeOne = function (verbose = true) {
  1058. var adjective = random_desc(["brand-new", "aging", "modern"], (verbose ? 0.2 : 0));
  1059. var color = random_desc(["blue", "white", "white", "blue and white", "red and white", "black", "gold"], (verbose ? 0.9 : 0));
  1060. var type = random_desc(["luxury jet", "business jet", "single-engine plane", "light aircraft"]);
  1061. return merge_desc([adjective, color, type]);
  1062. };
  1063. this.describe = function (verbose = true) {
  1064. return defaultDescribe(verbose, this, "vehicle");
  1065. }
  1066. }
  1067. function EmptyAirliner(count = 1) {
  1068. this.name = "Empty Airliner";
  1069. copy_defaults(this, new DefaultEntity());
  1070. this.count = count;
  1071. this.contents = initContents(this.name, this.count);
  1072. this.describeOne = function (verbose = true) {
  1073. var adjective = random_desc(["brand-new", "aging", "modern"], (verbose ? 0.2 : 0));
  1074. var color = random_desc(["blue", "white", "white", "blue and white"], (verbose ? 0.9 : 0));
  1075. var type = random_desc(["airliner", "twin-engine jet", "trijet", "four engine jet", "double-decker airliner", "widebody airliner", "passenger jet", "airliner"]);
  1076. return merge_desc([adjective, color, type]);
  1077. };
  1078. this.describe = function (verbose = true) {
  1079. return defaultDescribe(verbose, this, "vehicle");
  1080. }
  1081. }
  1082. function Airliner(count = 1) {
  1083. this.name = "Airliner";
  1084. copy_defaults(this, new DefaultEntity());
  1085. this.count = count;
  1086. this.contents = initContents(this.name, this.count);
  1087. this.describeOne = function (verbose = true) {
  1088. var adjective = random_desc(["brand-new", "aging", "modern"], (verbose ? 0.2 : 0));
  1089. var color = random_desc(["blue", "white", "white", "blue and white"], (verbose ? 0.9 : 0));
  1090. var type = random_desc(["airliner", "twin-engine jet", "trijet", "four engine jet", "double-decker airliner", "widebody airliner", "passenger jet", "airliner"]);
  1091. return merge_desc([adjective, color, type]);
  1092. };
  1093. this.describe = function (verbose = true) {
  1094. return defaultDescribe(verbose, this, "vehicle");
  1095. }
  1096. }
  1097. function Train(count = 1) {
  1098. this.name = "Train";
  1099. copy_defaults(this, new DefaultEntity());
  1100. this.count = count;
  1101. this.contents = initContents(this.name, this.count);
  1102. this.describeOne = function (verbose = true) {
  1103. var adjective = random_desc(["rusty", "brand-new", "steam", "freshly-painted"], (verbose ? 0.3 : 0));
  1104. var color = random_desc(["black", "tan", "gray"], (verbose ? 1 : 0));
  1105. var type = random_desc(["train", "passenger train", "freight train"]);
  1106. return merge_desc([adjective, color, type]);
  1107. };
  1108. this.describe = function (verbose = true) {
  1109. if (verbose) {
  1110. if (this.count == 1) {
  1111. var list = [];
  1112. for (var i = 0; i < this.count; i++) {
  1113. list.push(this.describeOne(verbose));
  1114. }
  1115. return merge_things(list) + " with " + this.contents["engine"].describe(false) + " in the engine and " + this.contents["Train Car"].describe() + " attached";
  1116. } else {
  1117. return this.count + " trains with " + this.contents["engine"].describe(false) + " in the engine and " + this.contents["Train Car"].describe() + " attached";
  1118. }
  1119. } else {
  1120. return (this.count > 1 ? this.count + " trains" : "a train");
  1121. }
  1122. };
  1123. this.anal_vore = function () {
  1124. var cars = (this.contents["Train Car"].count == 1 ? this.contents["Train Car"].describe() + " follows it inside" : this.contents["Train Car"].describe() + " are pulled slowly inside");
  1125. return "You snatch up " + this.describeOne() + " and stuff it into your pucker, moaning as " + cars;
  1126. };
  1127. }
  1128. function TrainCar(count = 1) {
  1129. this.name = "Train Car";
  1130. copy_defaults(this, new DefaultEntity());
  1131. this.count = count;
  1132. this.contents = initContents(this.name, this.count);
  1133. this.describeOne = function (verbose = true) {
  1134. var adjective = random_desc(["rusty", "brand-new", "vintage", "graffitied", "well-maintained"], (verbose ? 0.3 : 0));
  1135. var color = random_desc(["black", "tan", "gray", "yellow", "steel", "wooden"], (verbose ? 1 : 0));
  1136. var type = random_desc(["train car", "passenger train car", "freight train car"]);
  1137. return merge_desc([adjective, color, type]);
  1138. };
  1139. this.describe = function (verbose = true) {
  1140. return defaultDescribe(verbose, this, "vehicle");
  1141. }
  1142. }
  1143. function House(count = 1) {
  1144. this.name = "House";
  1145. copy_defaults(this, new DefaultEntity());
  1146. this.count = count;
  1147. this.contents = initContents(this.name, this.count);
  1148. this.describeOne = function (verbose = true) {
  1149. var size = random_desc(["little", "two-story", "large", "well-built", "run-down", "cheap",], (verbose ? 0.5 : 0));
  1150. var color = random_desc(["blue", "white", "gray", "tan", "green", "wooden", "brick"], (verbose ? 0.5 : 0));
  1151. var name = random_desc(["house", "home", "duplex", "house", "house", "trailer"], 1);
  1152. return merge_desc([size, color, name]);
  1153. };
  1154. this.describe = function (verbose = true) {
  1155. return defaultDescribe(verbose, this);
  1156. }
  1157. }
  1158. //might split this into a general business and resutrant categories
  1159. function Business(count = 1) {
  1160. this.name = "Business";
  1161. copy_defaults(this, new DefaultEntity());
  1162. this.count = count;
  1163. this.contents = initContents(this.name, this.count);
  1164. this.describeOne = function (verbose = true) {
  1165. var size = random_desc(["little", "two-story", "large", "well-built", "run-down", "cheap", "aging", "corner"], (verbose ? 0.5 : 0));
  1166. var color = random_desc(["blue", "white", "gray", "tan", "green", "brick", "concrete"], (verbose ? 0.5 : 0));
  1167. var name = random_desc(["mall", "resturant", "bank", "clinic", "shop", "post office", "tire shop", "chain resturant", "grocery store", "barber shop", "pizza resturant", "hardware store", "movie theather", "gas station"], 1);
  1168. return merge_desc([size, color, name]);
  1169. };
  1170. this.describe = function (verbose = true) {
  1171. return defaultDescribe(verbose, this);
  1172. }
  1173. }
  1174. function Barn(count = 1) {
  1175. this.name = "Barn";
  1176. copy_defaults(this, new DefaultEntity());
  1177. this.count = count;
  1178. this.contents = initContents(this.name, this.count);
  1179. this.describeOne = function (verbose = true) {
  1180. var size = random_desc(["little", "big", "large", "weathered", "rotted", "new"], (verbose ? 0.5 : 0));
  1181. var color = random_desc(["blue", "white", "gray", "tan", "green", "red"], (verbose ? 0.5 : 0));
  1182. var name = random_desc(["barn", "barn", "barn", "barn", "barn", "farmhouse"], 1);
  1183. return merge_desc([size, color, name]);
  1184. };
  1185. this.describe = function (verbose = true) {
  1186. return defaultDescribe(verbose, this);
  1187. }
  1188. }
  1189. function SmallHangar(count = 1) {
  1190. this.name = "Small Hangar";
  1191. copy_defaults(this, new DefaultEntity());
  1192. this.count = count;
  1193. this.contents = initContents(this.name, this.count);
  1194. this.describeOne = function (verbose = true) {
  1195. var size = random_desc(["weathered", "aging", "new"], (verbose ? 0.5 : 0));
  1196. var color = random_desc(["blue", "white", "gray", "tan", "green"], (verbose ? 0.5 : 0));
  1197. var name = random_desc(["hangar", "hangar", "hangar", "aircraft hangar"], 1);
  1198. return merge_desc([size, color, name]);
  1199. };
  1200. this.describe = function (verbose = true) {
  1201. return defaultDescribe(verbose, this);
  1202. }
  1203. }
  1204. function HelicopterHangar(count = 1) {
  1205. this.name = "Helicopter Hangar";
  1206. copy_defaults(this, new DefaultEntity());
  1207. this.count = count;
  1208. this.contents = initContents(this.name, this.count);
  1209. this.describeOne = function (verbose = true) {
  1210. var size = random_desc(["weathered", "aging", "new"], (verbose ? 0.5 : 0));
  1211. var color = random_desc(["blue", "white", "gray", "tan", "green"], (verbose ? 0.5 : 0));
  1212. var name = random_desc(["hangar", "hangar", "hangar", "helicopter hangar"], 1);
  1213. return merge_desc([size, color, name]);
  1214. };
  1215. this.describe = function (verbose = true) {
  1216. return defaultDescribe(verbose, this);
  1217. }
  1218. }
  1219. function LargeHangar(count = 1) {
  1220. this.name = "Large Hangar";
  1221. copy_defaults(this, new DefaultEntity());
  1222. this.count = count;
  1223. this.contents = initContents(this.name, this.count);
  1224. this.describeOne = function (verbose = true) {
  1225. var size = random_desc(["weathered", "aging", "new"], (verbose ? 0.5 : 0));
  1226. var color = random_desc(["blue", "white", "gray", "tan", "green"], (verbose ? 0.5 : 0));
  1227. var name = random_desc(["hangar", "hangar", "hangar", "large hangar", "spacious hangar"], 1);
  1228. return merge_desc([size, color, name]);
  1229. };
  1230. this.describe = function (verbose = true) {
  1231. return defaultDescribe(verbose, this);
  1232. }
  1233. }
  1234. function SmallSkyscraper(count = 1) {
  1235. this.name = "Small Skyscraper";
  1236. copy_defaults(this, new DefaultEntity());
  1237. this.count = count;
  1238. this.contents = initContents(this.name, this.count);
  1239. this.describeOne = function (verbose = true) {
  1240. var color = random_desc(["blue", "white", "gray", "tan", "green"], (verbose ? 0.5 : 0));
  1241. var name = random_desc(["skyscraper", "office tower", "office building", "high rise"], 1);
  1242. return merge_desc([color, name]);
  1243. };
  1244. this.describe = function (verbose = true) {
  1245. return defaultDescribe(verbose, this);
  1246. }
  1247. }
  1248. function LargeSkyscraper(count = 1) {
  1249. this.name = "Large Skyscraper";
  1250. copy_defaults(this, new DefaultEntity());
  1251. this.count = count;
  1252. this.contents = initContents(this.name, this.count);
  1253. this.describeOne = function (verbose = true) {
  1254. var color = random_desc(["blue", "white", "gray", "tan", "green", "glass"], (verbose ? 0.5 : 0));
  1255. var name = random_desc(["skyscraper", "office tower", "office building"], 1);
  1256. return merge_desc(["towering", color, name]);
  1257. };
  1258. this.describe = function (verbose = true) {
  1259. return defaultDescribe(verbose, this);
  1260. }
  1261. }
  1262. function ParkingGarage(count = 1) {
  1263. this.name = "Parking Garage";
  1264. copy_defaults(this, new DefaultEntity());
  1265. this.count = count;
  1266. this.contents = initContents(this.name, this.count);
  1267. this.describe = function (verbose = true) {
  1268. return defaultDescribe(verbose, this);
  1269. }
  1270. }
  1271. function Ranch(count = 1) {
  1272. this.name = "Ranch";
  1273. copy_defaults(this, new DefaultEntity());
  1274. this.count = count;
  1275. this.contents = initContents(this.name, this.count);
  1276. this.describeOne = function (verbose = true) {
  1277. var size = random_desc(["little", "large", "prosperous", "run-down"], (verbose ? 0.5 : 0));
  1278. var name = random_desc(["ranch", "farm", "ranch", "dairy farm", "cattle farm", "ranch", "farm"], 1);
  1279. return merge_desc([size, name]);
  1280. };
  1281. this.describe = function (verbose = true) {
  1282. return defaultDescribe(verbose, this);
  1283. }
  1284. }
  1285. function Airstrip(count = 1) {
  1286. this.name = "Airstrip";
  1287. copy_defaults(this, new DefaultEntity());
  1288. this.count = count;
  1289. this.contents = initContents(this.name, this.count);
  1290. this.describe = function (verbose = true) {
  1291. return defaultDescribe(verbose, this, "community");
  1292. }
  1293. }
  1294. function Airport(count = 1) {
  1295. this.name = "Airport";
  1296. copy_defaults(this, new DefaultEntity());
  1297. this.count = count;
  1298. this.contents = initContents(this.name, this.count);
  1299. this.describe = function (verbose = true) {
  1300. return defaultDescribe(verbose, this, "community");
  1301. }
  1302. }
  1303. function Town(count = 1) {
  1304. this.name = "Town";
  1305. copy_defaults(this, new DefaultEntity());
  1306. this.count = count;
  1307. this.contents = initContents(this.name, this.count);
  1308. this.describe = function (verbose = true) {
  1309. return defaultDescribe(verbose, this, "community");
  1310. }
  1311. }
  1312. function City(count = 1) {
  1313. this.name = "City";
  1314. copy_defaults(this, new DefaultEntity());
  1315. this.count = count;
  1316. this.contents = initContents(this.name, this.count);
  1317. this.describe = function (verbose = true) {
  1318. return defaultDescribe(verbose, this, "community");
  1319. }
  1320. }
  1321. function Continent(count = 1) {
  1322. this.name = "Continent";
  1323. copy_defaults(this, new DefaultEntity());
  1324. this.count = count;
  1325. this.contents = initContents(this.name, this.count);
  1326. this.describe = function (verbose = true) {
  1327. return defaultDescribe(verbose, this, "community");
  1328. }
  1329. }
  1330. function Planet(count = 1) {
  1331. this.name = "Planet";
  1332. copy_defaults(this, new DefaultEntity());
  1333. this.count = count;
  1334. this.contents = initContents(this.name, this.count);
  1335. this.describe = function (verbose = true) {
  1336. return defaultDescribe(verbose, this, "community");
  1337. }
  1338. }
  1339. function Star(count = 1) {
  1340. this.name = "Star";
  1341. copy_defaults(this, new DefaultEntity());
  1342. this.count = count;
  1343. this.contents = initContents(this.name, this.count);
  1344. this.describe = function (verbose = true) {
  1345. return (this.count == 1 ? "a star" : this.count + " stars");
  1346. };
  1347. }
  1348. function SolarSystem(count = 1) {
  1349. this.name = "Solar System";
  1350. copy_defaults(this, new DefaultEntity());
  1351. this.count = count;
  1352. this.contents = initContents(this.name, this.count);
  1353. this.describe = function (verbose = true) {
  1354. return defaultDescribe(verbose, this, "celestial");
  1355. }
  1356. }
  1357. function Galaxy(count = 1) {
  1358. this.name = "Galaxy";
  1359. copy_defaults(this, new DefaultEntity());
  1360. this.count = count;
  1361. this.contents = initContents(this.name, this.count);
  1362. this.describe = function (verbose = true) {
  1363. return defaultDescribe(verbose, this, "celestial");
  1364. }
  1365. }
  1366. function Cluster(count = 1) {
  1367. this.name = "Cluster";
  1368. copy_defaults(this, new DefaultEntity());
  1369. this.count = count;
  1370. this.contents = initContents(this.name, this.count);
  1371. this.describe = function (verbose = true) {
  1372. return defaultDescribe(verbose, this, "celestial");
  1373. }
  1374. }
  1375. function Universe(count = 1) {
  1376. this.name = "Universe";
  1377. copy_defaults(this, new DefaultEntity());
  1378. this.count = count;
  1379. this.contents = initContents(this.name, this.count);
  1380. this.describe = function (verbose = true) {
  1381. return defaultDescribe(verbose, this, "celestial");
  1382. }
  1383. }
  1384. function Multiverse(count = 1) {
  1385. this.name = "Multiverse";
  1386. copy_defaults(this, new DefaultEntity());
  1387. this.count = count;
  1388. this.contents = initContents(this.name, this.count);
  1389. this.describe = function (verbose = true) {
  1390. return defaultDescribe(verbose, this, "celestial");
  1391. }
  1392. }
  1393. function Soldier(count = 1) {
  1394. this.name = "Soldier";
  1395. copy_defaults(this, new DefaultEntity());
  1396. this.count = count;
  1397. this.contents = initContents(this.name, this.count);
  1398. this.describe = function (verbose = true) {
  1399. return defaultDescribe(verbose, this, "military");
  1400. }
  1401. }
  1402. function Tank(count = 1) {
  1403. this.name = "Tank";
  1404. copy_defaults(this, new DefaultEntity());
  1405. this.count = count;
  1406. this.contents = initContents(this.name, this.count);
  1407. this.describe = function (verbose = true) {
  1408. return defaultDescribe(verbose, this, "generic vehicle");
  1409. }
  1410. }
  1411. function Artillery(count = 1) {
  1412. this.name = "Artillery";
  1413. copy_defaults(this, new DefaultEntity());
  1414. this.count = count;
  1415. this.contents = initContents(this.name, this.count);
  1416. this.describe = function (verbose = true) {
  1417. return defaultDescribe(verbose, this, "generic vehicle");
  1418. }
  1419. }
  1420. function MilitaryHelicopter(count = 1) {
  1421. this.name = "Military Helicopter";
  1422. copy_defaults(this, new DefaultEntity());
  1423. this.count = count;
  1424. this.contents = initContents(this.name, this.count);
  1425. this.describe = function (verbose = true) {
  1426. return defaultDescribe(verbose, this, "generic vehicle");
  1427. }
  1428. }
  1429. function Micro(count = 1) {
  1430. this.name = "Micro";
  1431. copy_defaults(this, new DefaultEntity());
  1432. this.count = count;
  1433. this.contents = initContents(this.name, this.count);
  1434. this.describe = function (verbose = true) {
  1435. return defaultDescribe(verbose, this);
  1436. }
  1437. }
  1438. function Macro(count = 1) {
  1439. this.name = "Macro";
  1440. copy_defaults(this, new DefaultEntity());
  1441. this.count = count;
  1442. this.contents = initContents(this.name, this.count);
  1443. this.describe = function (verbose = true) {
  1444. return defaultDescribe(verbose, this);
  1445. }
  1446. }
  1447. function Squad(count = 1) {
  1448. this.name = "Squad";
  1449. copy_defaults(this, new DefaultEntity());
  1450. this.count = count;
  1451. this.contents = initContents(this.name, this.count);
  1452. this.describe = function (verbose = true) {
  1453. return defaultDescribe(verbose, this, "military");
  1454. }
  1455. }
  1456. function Platoon(count = 1) {
  1457. this.name = "Platoon";
  1458. copy_defaults(this, new DefaultEntity());
  1459. this.count = count;
  1460. this.contents = initContents(this.name, this.count);
  1461. this.describe = function (verbose = true) {
  1462. return defaultDescribe(verbose, this, "military");
  1463. }
  1464. }
  1465. function Company(count = 1) {
  1466. this.name = "Company";
  1467. copy_defaults(this, new DefaultEntity());
  1468. this.count = count;
  1469. this.contents = initContents(this.name, this.count);
  1470. this.describe = function (verbose = true) {
  1471. return defaultDescribe(verbose, this, "military");
  1472. }
  1473. }
  1474. function Battalion(count = 1) {
  1475. this.name = "Battalion";
  1476. copy_defaults(this, new DefaultEntity());
  1477. this.count = count;
  1478. this.contents = initContents(this.name, this.count);
  1479. this.describe = function (verbose = true) {
  1480. return defaultDescribe(verbose, this, "military");
  1481. }
  1482. }
  1483. function Brigade(count = 1) {
  1484. this.name = "Brigade";
  1485. copy_defaults(this, new DefaultEntity());
  1486. this.count = count;
  1487. this.contents = initContents(this.name, this.count);
  1488. this.describe = function (verbose = true) {
  1489. return defaultDescribe(verbose, this, "military");
  1490. }
  1491. }
  1492. function Division(count = 1) {
  1493. this.name = "Division";
  1494. copy_defaults(this, new DefaultEntity());
  1495. this.count = count;
  1496. this.contents = initContents(this.name, this.count);
  1497. this.describe = function (verbose = true) {
  1498. return defaultDescribe(verbose, this, "military");
  1499. }
  1500. }
  1501. function TankDivision(count = 1) {
  1502. this.name = "Tank Division";
  1503. copy_defaults(this, new DefaultEntity());
  1504. this.count = count;
  1505. this.contents = initContents(this.name, this.count);
  1506. this.describe = function (verbose = true) {
  1507. return defaultDescribe(verbose, this, "military");
  1508. }
  1509. }
  1510. function Army(count = 1) {
  1511. this.name = "Army";
  1512. copy_defaults(this, new DefaultEntity());
  1513. this.count = count;
  1514. this.contents = initContents(this.name, this.count);
  1515. this.describe = function (verbose = true) {
  1516. return defaultDescribe(verbose, this, "military");
  1517. }
  1518. }
  1519. //todo
  1520. //farms
  1521. //factories
  1522. //racetracks
  1523. //more building types
  1524. //cranes and other construction equipment
  1525. //nebula
  1526. //biome magic also set it so that you can't roll your existing biome
  1527. //chemical factory
  1528. //grand army
  1529. //armada