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.
 
 
 

2382 lines
55 KiB

  1. "use strict";
  2. var things = {
  3. Container: {
  4. Container: Container,
  5. mass: 0,
  6. area: 0,
  7. clusters: 0,
  8. cluster_chances: 0,
  9. contents: [],
  10. descriptor: ["", ""],
  11. },
  12. //Creatures
  13. Person: {
  14. Person: Person,
  15. mass: 80,
  16. area: 0.33,
  17. clusters: 5,
  18. cluster_chances: 0.8,
  19. contents: [],
  20. descriptor: ["a person", "people"],
  21. },
  22. Human: {
  23. Human: Human,
  24. mass: 80,
  25. area: 0.33,
  26. clusters: 5,
  27. cluster_chances: 0.8,
  28. contents: [],
  29. descriptor: ["a person", "people"],
  30. },
  31. Cow: {
  32. Cow: Cow,
  33. mass: 300,
  34. area: 2,
  35. clusters: 15,
  36. cluster_chances: 0.5,
  37. contents: [],
  38. descriptor: ["a cow", "cattle"],
  39. },
  40. Micro: {
  41. Micro: Micro,
  42. mass: 0.01,
  43. area: 0.05,
  44. clusters: 50,
  45. cluster_chances: 1,
  46. contents: [],
  47. descriptor: ["a micro", "micros"],
  48. },
  49. Macro: {
  50. Macro: Macro,
  51. mass: 8e4,
  52. area: 100,
  53. clusters: 0,
  54. cluster_chances: 0,
  55. contents: [],
  56. descriptor: ["a smaller macro", "smaller macros"],
  57. },
  58. //Vehicles
  59. "Empty Car": {
  60. "Empty Car": EmptyCar,
  61. mass: 1000,
  62. area: 4,
  63. clusters: 2,
  64. cluster_chances: 0.3,
  65. contents: [],
  66. descriptor: ["a parked car", "parked cars"],
  67. },
  68. Car: {
  69. Car: Car,
  70. mass: 1000,
  71. area: 4,
  72. clusters: 4,
  73. cluster_chances: 0.5,
  74. contents: [["Person", 1, 4]],
  75. descriptor: ["a car", "cars"],
  76. },
  77. Bus: {
  78. Bus: Bus,
  79. mass: 5000,
  80. area: 12,
  81. clusters: 1,
  82. cluster_chances: 0.25,
  83. contents: [["Person", 2, 30]],
  84. descriptor: ["a bus", "busses"],
  85. },
  86. Tram: {
  87. Tram: Tram,
  88. mass: 1e4,
  89. area: 20,
  90. clusters: 1,
  91. cluster_chances: 0.2,
  92. contents: [["Person", 10, 50]],
  93. descriptor: ["a tram", "trams"],
  94. },
  95. Train: {
  96. Train: Train,
  97. mass: 5e4,
  98. area: 40,
  99. clusters: 2,
  100. cluster_chances: 0.1,
  101. contents: [
  102. ["Person", 1, 4, "engine"],
  103. ["Train Car", 2, 10],
  104. ],
  105. descriptor: ["a train", "trains"],
  106. },
  107. "Train Car": {
  108. "Train Car": TrainCar,
  109. mass: 7500,
  110. area: 20,
  111. clusters: 1,
  112. cluster_chances: 0.05,
  113. contents: [["Person", 10, 40]],
  114. descriptor: ["a train car", "train cars"],
  115. },
  116. Helicopter: {
  117. Helicopter: Helicopter,
  118. mass: 1500,
  119. area: 12,
  120. clusters: 0,
  121. cluster_chances: 0,
  122. contents: [["Person", 4, 16]],
  123. descriptor: ["a helicopter", "helicopters"],
  124. },
  125. "Empty Helicopter": {
  126. "Empty Helicopter": EmptyHelicopter,
  127. mass: 1500,
  128. area: 12,
  129. clusters: 3,
  130. cluster_chances: 0.05,
  131. contents: [],
  132. descriptor: ["a parked helicopter", "parked helicopters"],
  133. },
  134. Plane: {
  135. Plane: Plane,
  136. mass: 6500,
  137. area: 50,
  138. clusters: 1,
  139. cluster_chances: 0.05,
  140. contents: [],
  141. descriptor: ["a small plane", "small planes"],
  142. },
  143. "Empty Plane": {
  144. "Empty Plane": EmptyPlane,
  145. mass: 6500,
  146. area: 50,
  147. clusters: 1,
  148. cluster_chances: 0.05,
  149. contents: [["Person", 2, 9]],
  150. descriptor: ["a parked plane", "parked aircraft"],
  151. },
  152. Airliner: {
  153. Airliner: Airliner,
  154. mass: 6500,
  155. area: 1250,
  156. clusters: 1,
  157. cluster_chances: 0.05,
  158. contents: [["Person", 5, 300]],
  159. descriptor: ["an airliner", "airliners"],
  160. },
  161. "Empty Airliner": {
  162. "Empty Airliner": EmptyAirliner,
  163. mass: 6500,
  164. area: 1250,
  165. clusters: 1,
  166. cluster_chances: 0.05,
  167. contents: [],
  168. descriptor: ["a parked airliner", "parked airliners"],
  169. },
  170. //Buildings
  171. House: {
  172. House: House,
  173. mass: 1e4,
  174. area: 150,
  175. clusters: 5,
  176. cluster_chances: 0.5,
  177. contents: [
  178. ["Person", 0, 8],
  179. ["Empty Car", 0, 2],
  180. ],
  181. descriptor: ["a house", "houses"],
  182. },
  183. Business: {
  184. Business: Business,
  185. mass: 5e4,
  186. area: 400,
  187. clusters: 5,
  188. cluster_chances: 0.25,
  189. contents: [
  190. ["Person", 0, 30],
  191. ["Car", 0, 5],
  192. ["Empty Car", 0, 20],
  193. ],
  194. descriptor: ["a local business", "buildings"],
  195. },
  196. Barn: {
  197. Barn: Barn,
  198. mass: 5e3,
  199. area: 300,
  200. clusters: 1,
  201. cluster_chances: 0.1,
  202. contents: [
  203. ["Person", 0, 2],
  204. ["Cow", 30, 70],
  205. ],
  206. descriptor: ["a barn", "barns"],
  207. },
  208. "Small Hangar": {
  209. "Small Hangar": SmallHangar,
  210. mass: 5e5,
  211. area: 2500,
  212. clusters: 1,
  213. cluster_chances: 0.1,
  214. contents: [
  215. ["Person", 0, 3],
  216. ["Plane", 0, 1],
  217. ["Empty Plane", 2, 6],
  218. ],
  219. descriptor: ["a small hangar", "small hangars"],
  220. },
  221. "Helicopter Hangar": {
  222. "Helicopter Hangar": HelicopterHangar,
  223. mass: 5e5,
  224. area: 2000,
  225. clusters: 1,
  226. cluster_chances: 0.1,
  227. contents: [
  228. ["Person", 0, 3],
  229. ["Helicopter", 0, 1],
  230. ["Helicopter", 2, 6],
  231. ],
  232. descriptor: ["a helicopter hangar", "helicopter hangar"],
  233. },
  234. "Large Hangar": {
  235. "Large Hangar": LargeHangar,
  236. mass: 5e6,
  237. area: 8000,
  238. clusters: 1,
  239. cluster_chances: 0.1,
  240. contents: [
  241. ["Person", 0, 5],
  242. ["Airliner", 0, 1],
  243. ["Empty Airliner", 1, 2],
  244. ],
  245. descriptor: ["an aircraft hangar", "hangars"],
  246. },
  247. "Small Skyscraper": {
  248. "Small Skyscraper": SmallSkyscraper,
  249. mass: 1e7,
  250. area: 1000,
  251. clusters: 2,
  252. cluster_chances: 0.25,
  253. contents: [
  254. ["Person", 150, 750],
  255. ["Empty Car", 10, 50],
  256. ],
  257. descriptor: ["a small skyscraper", "small skyscrapers"],
  258. },
  259. "Large Skyscraper": {
  260. "Large Skyscraper": LargeSkyscraper,
  261. mass: 8e7,
  262. area: 2000,
  263. clusters: 1,
  264. cluster_chances: 0.25,
  265. contents: [
  266. ["Person", 500, 1500],
  267. ["Empty Car", 20, 100],
  268. ],
  269. descriptor: ["a large skyscraper", "large skyscrapers"],
  270. },
  271. "Parking Garage": {
  272. "Parking Garage": ParkingGarage,
  273. mass: 1e7,
  274. area: 750,
  275. clusters: 1,
  276. cluster_chances: 0.1,
  277. contents: [
  278. ["Person", 10, 200],
  279. ["Empty Car", 100, 300],
  280. ["Car", 5, 30],
  281. ],
  282. descriptor: ["a parking garage", "parking garages"],
  283. },
  284. //Places
  285. Ranch: {
  286. Ranch: Ranch,
  287. mass: 2e7,
  288. area: 4e4,
  289. clusters: 0,
  290. cluster_chances: 0,
  291. contents: [
  292. ["Person", 10, 50],
  293. ["House", 1, 3],
  294. ["Barn", 1, 2],
  295. ],
  296. descriptor: ["a ranch", "ranchs"],
  297. },
  298. Airstrip: {
  299. Airstrip: Airstrip,
  300. mass: 2e7,
  301. area: 9e5,
  302. clusters: 0,
  303. cluster_chances: 0,
  304. contents: [
  305. ["Person", 10, 50],
  306. ["Small Hangar", 1, 3],
  307. ["Plane", 0, 2],
  308. ["Helicopter", 0, 1],
  309. ["Helicopter Hangar", 0, 1],
  310. ["Car", 0, 5],
  311. ["Empty Car", 0, 20],
  312. ],
  313. descriptor: ["an airstrip", "airstrips"],
  314. },
  315. Airport: {
  316. Airport: Airport,
  317. mass: 1.5e8,
  318. area: 6e6,
  319. clusters: 0,
  320. cluster_chances: 0,
  321. contents: [
  322. ["Person", 1500, 4000],
  323. ["Small Hangar", 4, 12],
  324. ["Plane", 2, 5],
  325. ["Helicopter", 1, 3],
  326. ["Helicopter Hangar", 2, 6],
  327. ["Airliner", 1, 3],
  328. ["Large Hangar", 2, 6],
  329. ["Car", 20, 75],
  330. ["Empty Car", 400, 1000],
  331. ],
  332. descriptor: ["an airport", "airports"],
  333. },
  334. Town: {
  335. Town: Town,
  336. mass: 1,
  337. area: 1e7,
  338. clusters: 5,
  339. cluster_chances: 0.1,
  340. contents: [
  341. ["Person", 10000, 100000],
  342. ["House", 5000, 50000],
  343. ["Empty Car", 200, 800],
  344. ["Car", 500, 80000],
  345. ["Bus", 5, 25],
  346. ["Train", 5, 25],
  347. ["Business", 500, 5000],
  348. ],
  349. descriptor: ["a town", "towns"],
  350. },
  351. City: {
  352. City: City,
  353. mass: 1,
  354. area: 1e9,
  355. clusters: 0,
  356. cluster_chances: 0.2,
  357. contents: [
  358. ["Person", 100000, 1500000],
  359. ["House", 20000, 200000],
  360. ["Empty Car", 10000, 100000],
  361. ["Car", 7500, 125000],
  362. ["Bus", 200, 400],
  363. ["Train", 10, 50],
  364. ["Tram", 25, 100],
  365. ["Small Skyscraper", 50, 300],
  366. ["Large Skyscraper", 10, 75],
  367. ["Parking Garage", 5, 10],
  368. ["Business", 2000, 10000],
  369. ],
  370. descriptor: ["a city", "cities"],
  371. },
  372. Continent: {
  373. Continent: Continent,
  374. mass: 1e21,
  375. area: 1.5e13,
  376. clusters: 5,
  377. cluster_chances: 0.5,
  378. contents: [
  379. ["Person", 1000000, 15000000],
  380. ["House", 2500, 10000],
  381. ["Car", 25000, 375000],
  382. ["Train", 50, 500],
  383. ["Town", 500, 1000],
  384. ["City", 50, 250],
  385. ["Business", 250, 1000],
  386. ],
  387. descriptor: ["a continent", "continents"],
  388. },
  389. //Celestial Bodies
  390. Planet: {
  391. Planet: Planet,
  392. mass: 5.972e24,
  393. area: 2.5e14,
  394. clusters: 0,
  395. cluster_chances: 1,
  396. contents: [["Continent", 4, 9]],
  397. descriptor: ["a planet", "planets"],
  398. },
  399. Star: {
  400. Star: Star,
  401. mass: 1e40,
  402. area: 3e18,
  403. clusters: 1,
  404. cluster_chances: 1,
  405. contents: [],
  406. descriptor: ["a star", "stars"],
  407. },
  408. "Solar System": {
  409. "Solar System": SolarSystem,
  410. mass: 1,
  411. area: 3e21,
  412. clusters: 1,
  413. cluster_chances: 1,
  414. contents: [
  415. ["Star", 1, 1],
  416. ["Planet", 5, 15],
  417. ],
  418. descriptor: ["a solar system", "solar systems"],
  419. },
  420. Galaxy: {
  421. Galaxy: Galaxy,
  422. mass: 1,
  423. area: 2e45,
  424. clusters: 1,
  425. cluster_chances: 1,
  426. contents: [
  427. ["Star", 1e9, 500e9],
  428. ["Solar System", 1e8, 500e8],
  429. ],
  430. descriptor: ["a galaxy", "galaxies"],
  431. },
  432. Cluster: {
  433. Cluster: Cluster,
  434. mass: 1,
  435. area: 2e49,
  436. clusters: 1,
  437. cluster_chances: 1,
  438. contents: [["Galaxy", 200, 5000]],
  439. descriptor: ["a cluster", "clusters"],
  440. },
  441. Universe: {
  442. Universe: Universe,
  443. mass: 1,
  444. area: 7e53,
  445. clusters: 1,
  446. cluster_chances: 1,
  447. contents: [["Cluster", 1.5e9, 2.5e9]],
  448. descriptor: ["a universe", "universes"],
  449. },
  450. Multiverse: {
  451. Multiverse: Multiverse,
  452. mass: 1,
  453. area: 5e56,
  454. clusters: 1,
  455. cluster_chances: 1,
  456. contents: [["Universe", 100, 1000]],
  457. descriptor: ["a multiverse", "multiverses"],
  458. },
  459. Timeline: {
  460. Timeline: Timeline,
  461. mass: 1,
  462. area: 5e75,
  463. clusters: 1,
  464. cluster_chances: 1,
  465. contents: [["Multiverse", 1e50, 1e53]],
  466. descriptor: ["an entire timeline", "entire timelines"],
  467. },
  468. Pantheon: {
  469. Pantheon: Pantheon,
  470. mass: 1,
  471. area: 1e100,
  472. clusters: 1,
  473. cluster_chances: 1,
  474. contents: [
  475. ["Timeline", 1e30, 1e35],
  476. ["Deity", 10, 30],
  477. ],
  478. descriptor: ["a pantheon", "pantheons"],
  479. },
  480. Deity: {
  481. Deity: Deity,
  482. mass: 1e100,
  483. area: 1e100,
  484. clusters: 1,
  485. cluster_chances: 1,
  486. contents: [],
  487. descriptor: ["a deity", "deities"],
  488. },
  489. Reality: {
  490. Reality: Reality,
  491. mass: 1,
  492. area: 1e120,
  493. clusters: 1,
  494. cluster_changes: 1,
  495. contents: [["Pantheon", 1e30, 1e35]],
  496. descriptor: ["a reality", "realities"],
  497. },
  498. //Military
  499. Soldier: {
  500. Soldier: Soldier,
  501. mass: 80,
  502. area: 1,
  503. clusters: 2,
  504. cluster_chances: 0.2,
  505. contents: [],
  506. descriptor: ["a soldier", "soldiers"],
  507. },
  508. Tank: {
  509. Tank: Tank,
  510. mass: 5000,
  511. area: 20,
  512. clusters: 2,
  513. cluster_chances: 0.25,
  514. contents: [["Soldier", 3, 5]],
  515. descriptor: ["a tank", "tanks"],
  516. },
  517. Artillery: {
  518. Artillery: Artillery,
  519. mass: 7000,
  520. area: 25,
  521. clusters: 3,
  522. cluster_chances: 0.5,
  523. contents: [["Soldier", 4, 6]],
  524. descriptor: ["an artillery tank", "artillery tanks"],
  525. },
  526. "Military Helicopter": {
  527. "Military Helicopter": MilitaryHelicopter,
  528. mass: 1500,
  529. area: 12,
  530. clusters: 0,
  531. cluster_chances: 0,
  532. contents: [["Soldier", 4, 16]],
  533. descriptor: ["a helicopter", "helicopters"],
  534. },
  535. Squad: {
  536. Squad: Squad,
  537. mass: 1,
  538. area: 30,
  539. clusters: 20,
  540. cluster_chances: 0.05,
  541. contents: [["Soldier", 6, 9]],
  542. descriptor: ["a squad", "squads"],
  543. },
  544. Platoon: {
  545. Platoon: Platoon,
  546. mass: 100,
  547. area: 150,
  548. clusters: 2,
  549. cluster_chances: 0.1,
  550. contents: [["Soldier", 16, 44]],
  551. descriptor: ["a military platoon", "platoons"],
  552. },
  553. Company: {
  554. Company: Company,
  555. mass: 500,
  556. area: 600,
  557. clusters: 2,
  558. cluster_chances: 0.1,
  559. contents: [["Soldier", 60, 200]],
  560. descriptor: ["a company of soldiers", "companies"],
  561. },
  562. Battalion: {
  563. Battalion: Battalion,
  564. mass: 1000,
  565. area: 3500,
  566. clusters: 2,
  567. cluster_chances: 0.1,
  568. contents: [["Soldier", 300, 1000]],
  569. descriptor: ["a battalion", "battalions"],
  570. },
  571. Brigade: {
  572. Brigade: Brigade,
  573. mass: 1500,
  574. area: 2e4,
  575. clusters: 2,
  576. cluster_chances: 0.1,
  577. contents: [["Soldier", 1500, 3200]],
  578. descriptor: ["a brigade", "brigades"],
  579. },
  580. Division: {
  581. Division: Division,
  582. mass: 2000,
  583. area: 8e4,
  584. clusters: 3,
  585. cluster_chances: 0.1,
  586. contents: [["Soldier", 10000, 16000]],
  587. descriptor: ["a division", "divisions"],
  588. },
  589. "Tank Division": {
  590. "Tank Division": TankDivision,
  591. mass: 3000,
  592. area: 1e5,
  593. clusters: 1,
  594. cluster_chances: 0.15,
  595. contents: [
  596. ["Soldier", 8000, 1200],
  597. ["Tank", 250, 500],
  598. ],
  599. descriptor: ["a tank division", "tank divisions"],
  600. },
  601. Army: {
  602. Army: Army,
  603. mass: 5000,
  604. area: 1e6,
  605. clusters: 2,
  606. cluster_chances: 0.1,
  607. contents: [["Soldier", 40000, 75000]],
  608. descriptor: ["an army", "armies"],
  609. },
  610. };
  611. //Alterante Army Structuring, may be used later
  612. //"Squad": [["Soldier",6,9]],
  613. // "Platoon": [["Squad",3,4]],
  614. //"Company": [["Platoon",3,5],["Squad",0,2]],
  615. //"Battalion": [["Company",4,6]],
  616. //"Brigade": [["Battalion",2,5],["Company",0,3]],
  617. //"Division": [["Brigade",2,4]],
  618. //"Tank Division": [["Brigade",2,4],["Tank",250,500]],
  619. //"Army": [["Division",3,8],["Tank Division",1,5]],
  620. // replace all instances of from with to
  621. function contents_substitute(from, to) {
  622. for (let key in contents) {
  623. if (contents.hasOwnProperty(key)) {
  624. let type = contents[key];
  625. for (let i = 0; i < type.length; i++) {
  626. if (type[i][0] == from) {
  627. type[i][0] = to;
  628. }
  629. }
  630. }
  631. }
  632. }
  633. // remove all instances of thing
  634. function contents_remove(thing) {
  635. for (let key in contents) {
  636. if (contents.hasOwnProperty(key)) {
  637. let type = contents[key];
  638. for (let i = 0; i < type.length; i++) {
  639. if (type[i][0] == thing) {
  640. type.splice(i, 1);
  641. --i;
  642. }
  643. }
  644. }
  645. }
  646. }
  647. // adds thing to parent
  648. function contents_insert(parent, thing, min, max, label) {
  649. let owner = things[parent].contents;
  650. if (label == undefined) owner.push([thing, min, max]);
  651. else owner.push([thing, min, max, label]);
  652. }
  653. function initContents(name, count) {
  654. //builds the contents for each destrucable(thing) when called
  655. let result = {};
  656. let type = things[name].contents;
  657. for (let i = 0; i < type.length; i++) {
  658. 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
  659. if (amount > 0) {
  660. // if a custom label is supplied, use it!
  661. if (type[i].length == 4)
  662. //if has optional name
  663. result[type[i][3]] = new things[type[i][0]][type[i][0]](
  664. amount
  665. ); //creates a "thing name" under the key of "optional name"
  666. else result[type[i][0]] = new things[type[i][0]][type[i][0]](amount);
  667. }
  668. }
  669. return result;
  670. }
  671. function get_living_prey(sum) {
  672. let total = 0;
  673. for (let key in sum) {
  674. if (sum.hasOwnProperty(key)) {
  675. if (
  676. key == "Micro" ||
  677. key == "Macro" ||
  678. key == "Person" ||
  679. key == "Cow" ||
  680. key == "Soldier"
  681. )
  682. total += sum[key];
  683. }
  684. }
  685. return total;
  686. }
  687. // general logic: each step fills in a fraction of the remaining space
  688. function fill_area(area, weights, variance = 0.15) {
  689. area = area + Math.random() * variance * 2 * area - variance * area;
  690. var result = [];
  691. var candidates = [];
  692. for (var key in weights) {
  693. if (weights.hasOwnProperty(key)) {
  694. candidates.push({
  695. name: key,
  696. area: things[key].area,
  697. weight: weights[key],
  698. });
  699. }
  700. }
  701. candidates = candidates.sort(function (x, y) {
  702. return x.area - y.area;
  703. });
  704. while (candidates.length > 0) {
  705. var candidate = candidates.pop();
  706. if (candidate.area > area) continue;
  707. var max = Math.floor(area / candidate.area);
  708. var limit = Math.min(max, 1000);
  709. var count = 0;
  710. var loopvar = 0;
  711. // for small amounts, actually do the randomness
  712. // the first few ones get a much better shot
  713. // if we have nothing at all, it's even better!
  714. while (loopvar < limit) {
  715. if (loopvar == 0 && result.length == 0) {
  716. ++count;
  717. } else if (loopvar <= things[candidate.name].clusters) {
  718. if (
  719. Math.random() < candidate.weight
  720. ? 1
  721. : Math.random() < things[candidate.name].cluster_chances
  722. ) {
  723. ++count;
  724. }
  725. } else {
  726. count += Math.random() < candidate.weight ? 1 : 0;
  727. }
  728. ++loopvar;
  729. }
  730. // if we're doing more than the limit, then we just add on the rest, with some variance
  731. if (limit < max) {
  732. const base = (max - limit) * candidate.weight;
  733. count += Math.round(base - base / 10 + (base * Math.random()) / 5);
  734. }
  735. area -= count * candidate.area;
  736. if (count > 0)
  737. result.push(new things[candidate.name][candidate.name](count));
  738. }
  739. return new Container(result);
  740. }
  741. // maybe make this something that approximates a
  742. // normal distribution; doing this 15,000,000 times is bad...
  743. // solution: only a few are random lul
  744. // improvement: take up to 100 samples, then use that to scale the final result
  745. function distribution(min, max, samples) {
  746. var result = 0;
  747. var limit = Math.min(100, samples);
  748. if (limit < samples) {
  749. let dist = 0;
  750. for (let i = 0; i < limit; i++) {
  751. dist += Math.random();
  752. }
  753. dist /= 100;
  754. return Math.floor(dist * samples * (max - min + 1) + samples * min);
  755. } else {
  756. for (let i = 0; i < limit; i++) {
  757. result += Math.floor(Math.random() * (max - min + 1) + min);
  758. }
  759. }
  760. return result;
  761. }
  762. function defaultMultiply(thing) {
  763. return function (amount) {
  764. thing.count *= amount;
  765. for (var key in thing.contents) {
  766. if (thing.contents.hasOwnProperty(key)) {
  767. thing.contents[key].multiply(amount);
  768. }
  769. }
  770. };
  771. }
  772. function defaultArea(thing) {
  773. return things[thing.name].area;
  774. }
  775. function defaultMass(thing) {
  776. return things[thing.name].mass;
  777. }
  778. function defaultDescribeOne(thing) {
  779. return function (verbose) {
  780. //verbose doesn't matter for this case, becasue it handles things with no extra text to use when being verbose
  781. return things[thing.name].descriptor[0];
  782. };
  783. }
  784. function defaultMerge(thing) {
  785. //this merges all objects into one containers
  786. return function (container) {
  787. var newCount = this.count + container.count;
  788. var newThing = new things[thing.name][thing.name](newCount);
  789. newThing.contents = {};
  790. for (var key in this.contents) {
  791. if (this.contents.hasOwnProperty(key)) {
  792. newThing.contents[key] = this.contents[key];
  793. }
  794. }
  795. for (key in container.contents) {
  796. if (container.contents.hasOwnProperty(key)) {
  797. if (this.contents.hasOwnProperty(key)) {
  798. newThing.contents[key] = this.contents[key].merge(
  799. container.contents[key]
  800. );
  801. } else {
  802. newThing.contents[key] = container.contents[key];
  803. }
  804. }
  805. }
  806. return newThing;
  807. };
  808. }
  809. function listSum(sum) {
  810. let result = [];
  811. for (let key in sum) {
  812. if (sum.hasOwnProperty(key)) {
  813. result.push(new things[key][key](sum[key]).describe(false));
  814. }
  815. }
  816. return merge_things(result);
  817. }
  818. // turn a nested object into a container with everything on one level
  819. function flatten(thing) {
  820. let dict = defaultSum(thing)();
  821. let list = [];
  822. Object.entries(dict).forEach(function ([key, val]) {
  823. let obj = new things[key][key](val);
  824. obj.contents = [];
  825. list.push(obj);
  826. });
  827. list.sort(function (x, y) {
  828. if (y.area != x.area) {
  829. return y.area - x.area;
  830. } else {
  831. return x.name.localeCompare(y.name);
  832. }
  833. });
  834. return new Container(list);
  835. }
  836. function defaultSum(thing) {
  837. return function () {
  838. var counts = {};
  839. if (thing.name != "Container") counts[thing.name] = thing.count;
  840. for (var key in thing.contents) {
  841. if (thing.contents.hasOwnProperty(key)) {
  842. var subcount = thing.contents[key].sum();
  843. for (var subkey in subcount) {
  844. if (!counts.hasOwnProperty(subkey)) {
  845. counts[subkey] = 0;
  846. }
  847. counts[subkey] += subcount[subkey];
  848. }
  849. }
  850. }
  851. return counts;
  852. };
  853. }
  854. function defaultSumProperty(thing) {
  855. return function (prop) {
  856. var total = 0;
  857. total += thing[prop] * thing.count;
  858. for (var key in thing.contents) {
  859. if (thing.contents.hasOwnProperty(key)) {
  860. total += thing.contents[key].sum_property(prop);
  861. }
  862. }
  863. return total;
  864. };
  865. }
  866. function defaultModProperty(thing) {
  867. return function (prop, func) {
  868. thing[prop] = func(thing[prop]);
  869. for (var key in thing.contents) {
  870. if (thing.contents.hasOwnProperty(key)) {
  871. thing.contents[key].mod_property(prop, func);
  872. }
  873. }
  874. };
  875. }
  876. function defaultAddContent(thing) {
  877. return function (name, min, max, count) {
  878. if (min == max) {
  879. let object = new things[name](min * count);
  880. thing.contents[object.name] = object;
  881. } else {
  882. let object = new things[name](distribution(min, max, count));
  883. thing.contents[object.name] = object;
  884. }
  885. };
  886. }
  887. function DefaultEntity() {
  888. this.sum = defaultSum;
  889. this.area = defaultArea;
  890. this.mass = defaultMass;
  891. this.sum_property = defaultSumProperty;
  892. this.mod_property = defaultModProperty;
  893. this.merge = defaultMerge;
  894. this.multiply = defaultMultiply;
  895. this.describeSimple = defaultDescribeSimple;
  896. this.describeOne = defaultDescribeOne;
  897. return this;
  898. }
  899. // god I love reinventing the wheel
  900. function copy_defaults(self, proto) {
  901. //loads the values defined in things into the fuction that calls it
  902. for (var key in proto) {
  903. //proto will always be a new DefaultEntity, self is the parent function
  904. if (proto.hasOwnProperty(key)) {
  905. self[key] = proto[key](self);
  906. }
  907. }
  908. }
  909. // combine strings into a list with proper grammar
  910. function merge_things(list, semicolons = false) {
  911. if (list.length == 0) {
  912. return "";
  913. } else if (list.length == 1) {
  914. return list[0];
  915. } else if (list.length == 2) {
  916. return list[0] + " and " + list[1];
  917. } else {
  918. var result = "";
  919. list.slice(0, list.length - 1).forEach(function (term) {
  920. result += term + ", ";
  921. });
  922. result += "and " + list[list.length - 1];
  923. return result;
  924. }
  925. }
  926. // combine the adjectives for something into a single string
  927. function merge_desc(list) {
  928. var result = "";
  929. list.forEach(function (term) {
  930. if (term != "") result += term + " ";
  931. });
  932. // knock off the last space
  933. if (result.length > 0) {
  934. result = result.substring(0, result.length - 1);
  935. }
  936. let article = "a ";
  937. //a/an overwriting terms
  938. let forcedTerms = ["honor", "heir"]; //words that need to start with an but don't start with a,e,i,o,u
  939. let force = false;
  940. for (let i of forcedTerms) {
  941. if (i === result.substring(0, i.length)) {
  942. force = true;
  943. }
  944. }
  945. let exceptionTerms = ["uniform", "unique"]; //words that need to start with a and start with a,e,i,o,u
  946. let exception = false;
  947. for (let i of exceptionTerms) {
  948. if (i === result.substring(0, i.length)) {
  949. exception = true;
  950. }
  951. }
  952. //check if the string should start with an
  953. if (
  954. force == true ||
  955. (exception == false &&
  956. (result.charAt(0) == "a" ||
  957. result.charAt(0) == "e" ||
  958. result.charAt(0) == "i" ||
  959. result.charAt(0) == "o" ||
  960. result.charAt(0) == "u"))
  961. ) {
  962. article = "an ";
  963. }
  964. result = article + result;
  965. return result;
  966. }
  967. // describes everything in the container
  968. function describe_all(contents, verbose = true, except = []) {
  969. var things = [];
  970. for (var key in contents) {
  971. if (contents.hasOwnProperty(key) && !except.includes(key)) {
  972. things.push(contents[key].describe(verbose));
  973. }
  974. }
  975. return merge_things(things);
  976. }
  977. function random_desc(list, odds = 1) {
  978. //strings together an array into a series of words
  979. if (Math.random() < odds)
  980. return list[Math.floor(Math.random() * list.length)];
  981. else return "";
  982. }
  983. function defaultDescribeSimple(thing) {
  984. return function (flat) {
  985. if (flat) {
  986. return flatten(thing).describe(false);
  987. } else {
  988. return thing.describe(false);
  989. }
  990. };
  991. }
  992. function defaultDescribe(verbose = true, parent, descAs) {
  993. let descriptorEnd = " inside";
  994. let descriptorConjunction = " with ";
  995. let groupLessThan3 = false;
  996. switch (descAs) {
  997. case "vehicle":
  998. descriptorEnd = pickString(
  999. " inside",
  1000. " inside",
  1001. " inside",
  1002. " inside",
  1003. " riding inside",
  1004. " trapped inside",
  1005. " sitting inside"
  1006. );
  1007. break;
  1008. case "community":
  1009. groupLessThan3 = true;
  1010. descriptorEnd = " in " + (parent.count == 1 ? "it" : "them");
  1011. break;
  1012. case "celestial":
  1013. groupLessThan3 = true;
  1014. descriptorConjunction = pickString(
  1015. " made up of ",
  1016. " consisting of ",
  1017. " containing "
  1018. );
  1019. descriptorEnd = "";
  1020. break;
  1021. case "military":
  1022. groupLessThan3 = true;
  1023. descriptorConjunction = pickString(
  1024. " of ",
  1025. " of ",
  1026. " made up of ",
  1027. " comprised of ",
  1028. " containing "
  1029. );
  1030. descriptorEnd = "";
  1031. break;
  1032. case "generic vehicle":
  1033. groupLessThan3 = true;
  1034. descriptorEnd = pickString(
  1035. " inside",
  1036. " inside",
  1037. " inside",
  1038. " inside",
  1039. " riding inside",
  1040. " trapped inside",
  1041. " sitting inside"
  1042. );
  1043. break;
  1044. }
  1045. if (verbose) {
  1046. if (parent.count == 1) {
  1047. //singular parent (specifying single to catch cases where groupLessThan3 = true, otherwise it would output "1 towns" instead of "a town"
  1048. if (things[parent.name].contents.length > 0) {
  1049. return (
  1050. things[parent.name].descriptor[0] +
  1051. descriptorConjunction +
  1052. describe_all(parent.contents, false) +
  1053. descriptorEnd
  1054. );
  1055. } else {
  1056. return parent.describeOne(verbose);
  1057. }
  1058. } else if (parent.count <= 3 && groupLessThan3 == false) {
  1059. // less than 3 parents and an ojbect that has varety when described
  1060. var list = [];
  1061. for (var i = 0; i < parent.count; i++) {
  1062. list.push(parent.describeOne(parent.count <= 2));
  1063. }
  1064. if (things[parent.name].contents.length > 0) {
  1065. return (
  1066. merge_things(list) +
  1067. descriptorConjunction +
  1068. describe_all(parent.contents, false) +
  1069. descriptorEnd
  1070. );
  1071. } else {
  1072. return merge_things(list);
  1073. }
  1074. } else {
  1075. //if there are more than 3 of the object
  1076. if (things[parent.name].contents.length > 0) {
  1077. return (
  1078. parent.count +
  1079. " " +
  1080. things[parent.name].descriptor[1] +
  1081. descriptorConjunction +
  1082. describe_all(parent.contents, false) +
  1083. descriptorEnd
  1084. );
  1085. } else {
  1086. return parent.count + " " + things[parent.name].descriptor[1];
  1087. }
  1088. }
  1089. } else {
  1090. //not verbose
  1091. return parent.count > 1
  1092. ? parent.count + " " + things[parent.name].descriptor[1]
  1093. : things[parent.name].descriptor[0];
  1094. }
  1095. }
  1096. function Container(contents = []) {
  1097. this.name = "Container";
  1098. copy_defaults(this, new DefaultEntity());
  1099. if (Number.isInteger(contents)) this.count = contents;
  1100. else this.count = 0;
  1101. this.contents = {};
  1102. for (var i = 0; i < contents.length; i++) {
  1103. this.contents[contents[i].name] = contents[i];
  1104. }
  1105. for (var key in this.contents) {
  1106. if (this.contents.hasOwnProperty(key)) {
  1107. this.count += this.contents[key].count;
  1108. }
  1109. }
  1110. this.describe = function (verbose = true) {
  1111. return describe_all(this.contents, verbose);
  1112. };
  1113. return this;
  1114. }
  1115. function Person(count = 1) {
  1116. this.name = "Person";
  1117. copy_defaults(this, new DefaultEntity());
  1118. this.mass = (Math.random() - 0.5) * 20 + this.mass;
  1119. this.count = count;
  1120. this.contents = initContents(this.name, this.count);
  1121. this.describeOne = function (verbose = true) {
  1122. var body = random_desc(
  1123. [
  1124. "skinny",
  1125. "fat",
  1126. "tall",
  1127. "short",
  1128. "stocky",
  1129. "spindly",
  1130. "muscular",
  1131. "fit",
  1132. "multi-colored",
  1133. ],
  1134. verbose ? 0.6 : 0
  1135. );
  1136. var sex = random_desc(["male", "female"], verbose ? 0.75 : 0);
  1137. var species = "";
  1138. species = random_desc([
  1139. "wolf",
  1140. "cat",
  1141. "dog",
  1142. "squirrel",
  1143. "horse",
  1144. "hyena",
  1145. "fox",
  1146. "jackal",
  1147. "crux",
  1148. "sergal",
  1149. "coyote",
  1150. "rabbit",
  1151. "lizard",
  1152. "avian",
  1153. ]);
  1154. return merge_desc([body, sex, species]);
  1155. };
  1156. this.describe = function (verbose = true) {
  1157. return defaultDescribe(verbose, this);
  1158. };
  1159. return this;
  1160. }
  1161. function Human(count = 1) {
  1162. this.name = "Person";
  1163. copy_defaults(this, new DefaultEntity());
  1164. this.mass = (Math.random() - 0.5) * 20 + this.mass;
  1165. this.count = count;
  1166. this.contents = initContents(this.name, this.count);
  1167. this.describeOne = function (verbose = true) {
  1168. var body = random_desc(
  1169. [
  1170. "skinny",
  1171. "fat",
  1172. "tall",
  1173. "short",
  1174. "stocky",
  1175. "spindly",
  1176. "muscular",
  1177. "fit",
  1178. "tanned",
  1179. ],
  1180. verbose ? 0.6 : 0
  1181. );
  1182. var sex = random_desc(["man", "woman"], 1);
  1183. return merge_desc([body, sex]);
  1184. };
  1185. this.describe = function (verbose = true) {
  1186. return defaultDescribe(verbose, this);
  1187. };
  1188. return this;
  1189. }
  1190. function Cow(count = 1) {
  1191. this.name = "Cow";
  1192. copy_defaults(this, new DefaultEntity());
  1193. this.count = count;
  1194. this.contents = initContents(this.name, this.count);
  1195. this.describeOne = function (verbose = true) {
  1196. var body = random_desc(
  1197. ["skinny", "fat", "tall", "short", "stocky", "spindly", "brown"],
  1198. verbose ? 0.6 : 0
  1199. );
  1200. var sex = random_desc(
  1201. ["bull", "steer", "cow", "cow", "cow", "heifer"],
  1202. verbose ? 1 : 0
  1203. );
  1204. return merge_desc([body, sex]);
  1205. };
  1206. this.describe = function (verbose = true) {
  1207. return defaultDescribe(verbose, this);
  1208. };
  1209. return this;
  1210. }
  1211. function EmptyCar(count = 1) {
  1212. this.name = "Empty Car";
  1213. copy_defaults(this, new DefaultEntity());
  1214. this.count = count;
  1215. this.contents = initContents(this.name, this.count);
  1216. this.describeOne = function (verbose = true) {
  1217. var color = random_desc([
  1218. "black",
  1219. "black",
  1220. "gray",
  1221. "gray",
  1222. "blue",
  1223. "red",
  1224. "tan",
  1225. "white",
  1226. "white",
  1227. ]);
  1228. var adjective = random_desc(
  1229. [
  1230. "rusty",
  1231. "brand-new",
  1232. "luxury",
  1233. "beat-up",
  1234. "dented",
  1235. "restored",
  1236. "classic",
  1237. ],
  1238. 0.3
  1239. );
  1240. var type = random_desc([
  1241. "SUV",
  1242. "coupe",
  1243. "sedan",
  1244. "truck",
  1245. "van",
  1246. "convertible",
  1247. ]);
  1248. return merge_desc(["parked", adjective, color, type]);
  1249. };
  1250. this.describe = function (verbose = true) {
  1251. return defaultDescribe(verbose, this, "vehicle");
  1252. };
  1253. }
  1254. function Car(count = 1) {
  1255. this.name = "Car";
  1256. copy_defaults(this, new DefaultEntity());
  1257. this.count = count;
  1258. this.contents = initContents(this.name, this.count);
  1259. this.describeOne = function (verbose = true) {
  1260. var color = random_desc(
  1261. [
  1262. "black",
  1263. "black",
  1264. "gray",
  1265. "gray",
  1266. "blue",
  1267. "red",
  1268. "tan",
  1269. "white",
  1270. "white",
  1271. ],
  1272. verbose ? 1 : 0
  1273. );
  1274. var adjective = random_desc(
  1275. [
  1276. "rusty",
  1277. "brand-new",
  1278. "luxury",
  1279. "beat-up",
  1280. "dented",
  1281. "restored",
  1282. "classic",
  1283. ],
  1284. verbose ? 0.3 : 0
  1285. );
  1286. var type = random_desc([
  1287. "SUV",
  1288. "coupe",
  1289. "sedan",
  1290. "truck",
  1291. "van",
  1292. "convertible",
  1293. ]);
  1294. return merge_desc([adjective, color, type]);
  1295. };
  1296. this.describe = function (verbose = true) {
  1297. return defaultDescribe(verbose, this, "vehicle");
  1298. };
  1299. }
  1300. function Bus(count = 1) {
  1301. this.name = "Bus";
  1302. copy_defaults(this, new DefaultEntity());
  1303. this.count = count;
  1304. this.contents = initContents(this.name, this.count);
  1305. this.describeOne = function (verbose = true) {
  1306. var adjective = random_desc(
  1307. ["rusty", "brand-new", "aging", "modern"],
  1308. verbose ? 0.3 : 0
  1309. );
  1310. var color = random_desc(["black", "tan", "gray"], verbose ? 1 : 0);
  1311. var type = random_desc([
  1312. "bus",
  1313. "double-decker bus",
  1314. "articulating bus",
  1315. "open-top bus",
  1316. "sleeper bus",
  1317. "intercity bus",
  1318. ]);
  1319. return merge_desc([adjective, color, type]);
  1320. };
  1321. this.describe = function (verbose = true) {
  1322. return defaultDescribe(verbose, this, "vehicle");
  1323. };
  1324. }
  1325. function Tram(count = 1) {
  1326. this.name = "Tram";
  1327. copy_defaults(this, new DefaultEntity());
  1328. this.count = count;
  1329. this.contents = initContents(this.name, this.count);
  1330. this.describeOne = function (verbose = true) {
  1331. var adjective = random_desc(
  1332. ["rusty", "weathered", "well-maintained"],
  1333. verbose ? 0.3 : 0
  1334. );
  1335. var color = random_desc(["blue", "brown", "gray"], verbose ? 1 : 0);
  1336. var type = random_desc(["tram"]);
  1337. return merge_desc([adjective, color, type]);
  1338. };
  1339. this.describe = function (verbose = true) {
  1340. return defaultDescribe(verbose, this, "vehicle");
  1341. };
  1342. this.anal_vore = function () {
  1343. return "You slide " + this.describe() + " up your tight ass";
  1344. };
  1345. }
  1346. function EmptyHelicopter(count = 1) {
  1347. this.name = "Empty Helicopter";
  1348. copy_defaults(this, new DefaultEntity());
  1349. this.count = count;
  1350. this.contents = initContents(this.name, this.count);
  1351. this.describeOne = function (verbose = true) {
  1352. var color = random_desc(
  1353. ["blue", "white", "white", "red", "black", "gold", "yellow"],
  1354. verbose ? 0.6 : 0
  1355. );
  1356. var type = random_desc([
  1357. "bubble coptor",
  1358. "helicopter",
  1359. "helicopter",
  1360. "news chopper",
  1361. "police helicopter",
  1362. "chopper",
  1363. ]);
  1364. return merge_desc([adjective, color, type]);
  1365. };
  1366. this.describe = function (verbose = true) {
  1367. return defaultDescribe(verbose, this, "vehicle");
  1368. };
  1369. }
  1370. function Helicopter(count = 1) {
  1371. this.name = "Helicopter";
  1372. copy_defaults(this, new DefaultEntity());
  1373. this.count = count;
  1374. this.contents = initContents(this.name, this.count);
  1375. this.describeOne = function (verbose = true) {
  1376. var color = random_desc(
  1377. ["blue", "white", "white", "red", "black", "gold", "yellow"],
  1378. verbose ? 0.6 : 0
  1379. );
  1380. var type = random_desc([
  1381. "bubble coptor",
  1382. "helicopter",
  1383. "helicopter",
  1384. "news chopper",
  1385. "police helicopter",
  1386. "chopper",
  1387. ]);
  1388. return merge_desc([adjective, color, type]);
  1389. };
  1390. this.describe = function (verbose = true) {
  1391. return defaultDescribe(verbose, this, "vehicle");
  1392. };
  1393. }
  1394. function EmptyPlane(count = 1) {
  1395. this.name = "Empty Plane";
  1396. copy_defaults(this, new DefaultEntity());
  1397. this.count = count;
  1398. this.contents = initContents(this.name, this.count);
  1399. this.describeOne = function (verbose = true) {
  1400. var adjective = random_desc(
  1401. ["brand-new", "aging", "modern"],
  1402. verbose ? 0.2 : 0
  1403. );
  1404. var color = random_desc(
  1405. [
  1406. "blue",
  1407. "white",
  1408. "white",
  1409. "blue and white",
  1410. "red and white",
  1411. "black",
  1412. "gold",
  1413. ],
  1414. verbose ? 0.9 : 0
  1415. );
  1416. var type = random_desc([
  1417. "luxury jet",
  1418. "business jet",
  1419. "single-engine plane",
  1420. "light aircraft",
  1421. ]);
  1422. return merge_desc([adjective, color, type]);
  1423. };
  1424. this.describe = function (verbose = true) {
  1425. return defaultDescribe(verbose, this, "vehicle");
  1426. };
  1427. }
  1428. function Plane(count = 1) {
  1429. this.name = "Plane";
  1430. copy_defaults(this, new DefaultEntity());
  1431. this.count = count;
  1432. this.contents = initContents(this.name, this.count);
  1433. this.describeOne = function (verbose = true) {
  1434. var adjective = random_desc(
  1435. ["brand-new", "aging", "modern"],
  1436. verbose ? 0.2 : 0
  1437. );
  1438. var color = random_desc(
  1439. [
  1440. "blue",
  1441. "white",
  1442. "white",
  1443. "blue and white",
  1444. "red and white",
  1445. "black",
  1446. "gold",
  1447. ],
  1448. verbose ? 0.9 : 0
  1449. );
  1450. var type = random_desc([
  1451. "luxury jet",
  1452. "business jet",
  1453. "single-engine plane",
  1454. "light aircraft",
  1455. ]);
  1456. return merge_desc([adjective, color, type]);
  1457. };
  1458. this.describe = function (verbose = true) {
  1459. return defaultDescribe(verbose, this, "vehicle");
  1460. };
  1461. }
  1462. function EmptyAirliner(count = 1) {
  1463. this.name = "Empty Airliner";
  1464. copy_defaults(this, new DefaultEntity());
  1465. this.count = count;
  1466. this.contents = initContents(this.name, this.count);
  1467. this.describeOne = function (verbose = true) {
  1468. var adjective = random_desc(
  1469. ["brand-new", "aging", "modern"],
  1470. verbose ? 0.2 : 0
  1471. );
  1472. var color = random_desc(
  1473. ["blue", "white", "white", "blue and white"],
  1474. verbose ? 0.9 : 0
  1475. );
  1476. var type = random_desc([
  1477. "airliner",
  1478. "twin-engine jet",
  1479. "trijet",
  1480. "four engine jet",
  1481. "double-decker airliner",
  1482. "widebody airliner",
  1483. "passenger jet",
  1484. "airliner",
  1485. ]);
  1486. return merge_desc([adjective, color, type]);
  1487. };
  1488. this.describe = function (verbose = true) {
  1489. return defaultDescribe(verbose, this, "vehicle");
  1490. };
  1491. }
  1492. function Airliner(count = 1) {
  1493. this.name = "Airliner";
  1494. copy_defaults(this, new DefaultEntity());
  1495. this.count = count;
  1496. this.contents = initContents(this.name, this.count);
  1497. this.describeOne = function (verbose = true) {
  1498. var adjective = random_desc(
  1499. ["brand-new", "aging", "modern"],
  1500. verbose ? 0.2 : 0
  1501. );
  1502. var color = random_desc(
  1503. ["blue", "white", "white", "blue and white"],
  1504. verbose ? 0.9 : 0
  1505. );
  1506. var type = random_desc([
  1507. "airliner",
  1508. "twin-engine jet",
  1509. "trijet",
  1510. "four engine jet",
  1511. "double-decker airliner",
  1512. "widebody airliner",
  1513. "passenger jet",
  1514. "airliner",
  1515. ]);
  1516. return merge_desc([adjective, color, type]);
  1517. };
  1518. this.describe = function (verbose = true) {
  1519. return defaultDescribe(verbose, this, "vehicle");
  1520. };
  1521. }
  1522. function Train(count = 1) {
  1523. this.name = "Train";
  1524. copy_defaults(this, new DefaultEntity());
  1525. this.count = count;
  1526. this.contents = initContents(this.name, this.count);
  1527. this.describeOne = function (verbose = true) {
  1528. var adjective = random_desc(
  1529. ["rusty", "brand-new", "steam", "freshly-painted"],
  1530. verbose ? 0.3 : 0
  1531. );
  1532. var color = random_desc(["black", "tan", "gray"], verbose ? 1 : 0);
  1533. var type = random_desc(["train", "passenger train", "freight train"]);
  1534. return merge_desc([adjective, color, type]);
  1535. };
  1536. this.describe = function (verbose = true) {
  1537. if (verbose) {
  1538. if (this.count == 1) {
  1539. var list = [];
  1540. for (var i = 0; i < this.count; i++) {
  1541. list.push(this.describeOne(verbose));
  1542. }
  1543. return (
  1544. merge_things(list) +
  1545. " with " +
  1546. this.contents["engine"].describe(false) +
  1547. " in the engine and " +
  1548. this.contents["Train Car"].describe() +
  1549. " attached"
  1550. );
  1551. } else {
  1552. return (
  1553. this.count +
  1554. " trains with " +
  1555. this.contents["engine"].describe(false) +
  1556. " in the engine and " +
  1557. this.contents["Train Car"].describe() +
  1558. " attached"
  1559. );
  1560. }
  1561. } else {
  1562. return this.count > 1 ? this.count + " trains" : "a train";
  1563. }
  1564. };
  1565. this.anal_vore = function () {
  1566. var cars =
  1567. this.contents["Train Car"].count == 1
  1568. ? this.contents["Train Car"].describe() + " follows it inside"
  1569. : this.contents["Train Car"].describe() + " are pulled slowly inside";
  1570. return (
  1571. "You snatch up " +
  1572. this.describeOne() +
  1573. " and stuff it into your pucker, moaning as " +
  1574. cars
  1575. );
  1576. };
  1577. }
  1578. function TrainCar(count = 1) {
  1579. this.name = "Train Car";
  1580. copy_defaults(this, new DefaultEntity());
  1581. this.count = count;
  1582. this.contents = initContents(this.name, this.count);
  1583. this.describeOne = function (verbose = true) {
  1584. var adjective = random_desc(
  1585. ["rusty", "brand-new", "vintage", "graffitied", "well-maintained"],
  1586. verbose ? 0.3 : 0
  1587. );
  1588. var color = random_desc(
  1589. ["black", "tan", "gray", "yellow", "steel", "wooden"],
  1590. verbose ? 1 : 0
  1591. );
  1592. var type = random_desc([
  1593. "train car",
  1594. "passenger train car",
  1595. "freight train car",
  1596. ]);
  1597. return merge_desc([adjective, color, type]);
  1598. };
  1599. this.describe = function (verbose = true) {
  1600. return defaultDescribe(verbose, this, "vehicle");
  1601. };
  1602. }
  1603. function House(count = 1) {
  1604. this.name = "House";
  1605. copy_defaults(this, new DefaultEntity());
  1606. this.count = count;
  1607. this.contents = initContents(this.name, this.count);
  1608. this.describeOne = function (verbose = true) {
  1609. var size = random_desc(
  1610. ["little", "two-story", "large", "well-built", "run-down", "cheap"],
  1611. verbose ? 0.5 : 0
  1612. );
  1613. var color = random_desc(
  1614. ["blue", "white", "gray", "tan", "green", "wooden", "brick"],
  1615. verbose ? 0.5 : 0
  1616. );
  1617. var name = random_desc(
  1618. ["house", "home", "duplex", "house", "house", "trailer"],
  1619. 1
  1620. );
  1621. return merge_desc([size, color, name]);
  1622. };
  1623. this.describe = function (verbose = true) {
  1624. return defaultDescribe(verbose, this);
  1625. };
  1626. }
  1627. //might split this into a general business and resutrant categories
  1628. function Business(count = 1) {
  1629. this.name = "Business";
  1630. copy_defaults(this, new DefaultEntity());
  1631. this.count = count;
  1632. this.contents = initContents(this.name, this.count);
  1633. this.describeOne = function (verbose = true) {
  1634. var size = random_desc(
  1635. [
  1636. "little",
  1637. "two-story",
  1638. "large",
  1639. "well-built",
  1640. "run-down",
  1641. "cheap",
  1642. "aging",
  1643. "corner",
  1644. ],
  1645. verbose ? 0.5 : 0
  1646. );
  1647. var color = random_desc(
  1648. ["blue", "white", "gray", "tan", "green", "brick", "concrete"],
  1649. verbose ? 0.5 : 0
  1650. );
  1651. var name = random_desc(
  1652. [
  1653. "mall",
  1654. "resturant",
  1655. "bank",
  1656. "clinic",
  1657. "shop",
  1658. "post office",
  1659. "tire shop",
  1660. "chain resturant",
  1661. "grocery store",
  1662. "barber shop",
  1663. "pizza resturant",
  1664. "hardware store",
  1665. "movie theather",
  1666. "gas station",
  1667. ],
  1668. 1
  1669. );
  1670. return merge_desc([size, color, name]);
  1671. };
  1672. this.describe = function (verbose = true) {
  1673. return defaultDescribe(verbose, this);
  1674. };
  1675. }
  1676. function Barn(count = 1) {
  1677. this.name = "Barn";
  1678. copy_defaults(this, new DefaultEntity());
  1679. this.count = count;
  1680. this.contents = initContents(this.name, this.count);
  1681. this.describeOne = function (verbose = true) {
  1682. var size = random_desc(
  1683. ["little", "big", "large", "weathered", "rotted", "new"],
  1684. verbose ? 0.5 : 0
  1685. );
  1686. var color = random_desc(
  1687. ["blue", "white", "gray", "tan", "green", "red"],
  1688. verbose ? 0.5 : 0
  1689. );
  1690. var name = random_desc(
  1691. ["barn", "barn", "barn", "barn", "barn", "farmhouse"],
  1692. 1
  1693. );
  1694. return merge_desc([size, color, name]);
  1695. };
  1696. this.describe = function (verbose = true) {
  1697. return defaultDescribe(verbose, this);
  1698. };
  1699. }
  1700. function SmallHangar(count = 1) {
  1701. this.name = "Small Hangar";
  1702. copy_defaults(this, new DefaultEntity());
  1703. this.count = count;
  1704. this.contents = initContents(this.name, this.count);
  1705. this.describeOne = function (verbose = true) {
  1706. var size = random_desc(["weathered", "aging", "new"], verbose ? 0.5 : 0);
  1707. var color = random_desc(
  1708. ["blue", "white", "gray", "tan", "green"],
  1709. verbose ? 0.5 : 0
  1710. );
  1711. var name = random_desc(
  1712. ["hangar", "hangar", "hangar", "aircraft hangar"],
  1713. 1
  1714. );
  1715. return merge_desc([size, color, name]);
  1716. };
  1717. this.describe = function (verbose = true) {
  1718. return defaultDescribe(verbose, this);
  1719. };
  1720. }
  1721. function HelicopterHangar(count = 1) {
  1722. this.name = "Helicopter Hangar";
  1723. copy_defaults(this, new DefaultEntity());
  1724. this.count = count;
  1725. this.contents = initContents(this.name, this.count);
  1726. this.describeOne = function (verbose = true) {
  1727. var size = random_desc(["weathered", "aging", "new"], verbose ? 0.5 : 0);
  1728. var color = random_desc(
  1729. ["blue", "white", "gray", "tan", "green"],
  1730. verbose ? 0.5 : 0
  1731. );
  1732. var name = random_desc(
  1733. ["hangar", "hangar", "hangar", "helicopter hangar"],
  1734. 1
  1735. );
  1736. return merge_desc([size, color, name]);
  1737. };
  1738. this.describe = function (verbose = true) {
  1739. return defaultDescribe(verbose, this);
  1740. };
  1741. }
  1742. function LargeHangar(count = 1) {
  1743. this.name = "Large Hangar";
  1744. copy_defaults(this, new DefaultEntity());
  1745. this.count = count;
  1746. this.contents = initContents(this.name, this.count);
  1747. this.describeOne = function (verbose = true) {
  1748. var size = random_desc(["weathered", "aging", "new"], verbose ? 0.5 : 0);
  1749. var color = random_desc(
  1750. ["blue", "white", "gray", "tan", "green"],
  1751. verbose ? 0.5 : 0
  1752. );
  1753. var name = random_desc(
  1754. ["hangar", "hangar", "hangar", "large hangar", "spacious hangar"],
  1755. 1
  1756. );
  1757. return merge_desc([size, color, name]);
  1758. };
  1759. this.describe = function (verbose = true) {
  1760. return defaultDescribe(verbose, this);
  1761. };
  1762. }
  1763. function SmallSkyscraper(count = 1) {
  1764. this.name = "Small Skyscraper";
  1765. copy_defaults(this, new DefaultEntity());
  1766. this.count = count;
  1767. this.contents = initContents(this.name, this.count);
  1768. this.describeOne = function (verbose = true) {
  1769. var color = random_desc(
  1770. ["blue", "white", "gray", "tan", "green"],
  1771. verbose ? 0.5 : 0
  1772. );
  1773. var name = random_desc(
  1774. ["skyscraper", "office tower", "office building", "high rise"],
  1775. 1
  1776. );
  1777. return merge_desc([color, name]);
  1778. };
  1779. this.describe = function (verbose = true) {
  1780. return defaultDescribe(verbose, this);
  1781. };
  1782. }
  1783. function LargeSkyscraper(count = 1) {
  1784. this.name = "Large Skyscraper";
  1785. copy_defaults(this, new DefaultEntity());
  1786. this.count = count;
  1787. this.contents = initContents(this.name, this.count);
  1788. this.describeOne = function (verbose = true) {
  1789. var color = random_desc(
  1790. ["blue", "white", "gray", "tan", "green", "glass"],
  1791. verbose ? 0.5 : 0
  1792. );
  1793. var name = random_desc(
  1794. ["skyscraper", "office tower", "office building"],
  1795. 1
  1796. );
  1797. return merge_desc(["towering", color, name]);
  1798. };
  1799. this.describe = function (verbose = true) {
  1800. return defaultDescribe(verbose, this);
  1801. };
  1802. }
  1803. function ParkingGarage(count = 1) {
  1804. this.name = "Parking Garage";
  1805. copy_defaults(this, new DefaultEntity());
  1806. this.count = count;
  1807. this.contents = initContents(this.name, this.count);
  1808. this.describe = function (verbose = true) {
  1809. return defaultDescribe(verbose, this);
  1810. };
  1811. }
  1812. function Ranch(count = 1) {
  1813. this.name = "Ranch";
  1814. copy_defaults(this, new DefaultEntity());
  1815. this.count = count;
  1816. this.contents = initContents(this.name, this.count);
  1817. this.describeOne = function (verbose = true) {
  1818. var size = random_desc(
  1819. ["little", "large", "prosperous", "run-down"],
  1820. verbose ? 0.5 : 0
  1821. );
  1822. var name = random_desc(
  1823. ["ranch", "farm", "ranch", "dairy farm", "cattle farm", "ranch", "farm"],
  1824. 1
  1825. );
  1826. return merge_desc([size, name]);
  1827. };
  1828. this.describe = function (verbose = true) {
  1829. return defaultDescribe(verbose, this);
  1830. };
  1831. }
  1832. function Airstrip(count = 1) {
  1833. this.name = "Airstrip";
  1834. copy_defaults(this, new DefaultEntity());
  1835. this.count = count;
  1836. this.contents = initContents(this.name, this.count);
  1837. this.describe = function (verbose = true) {
  1838. return defaultDescribe(verbose, this, "community");
  1839. };
  1840. }
  1841. function Airport(count = 1) {
  1842. this.name = "Airport";
  1843. copy_defaults(this, new DefaultEntity());
  1844. this.count = count;
  1845. this.contents = initContents(this.name, this.count);
  1846. this.describe = function (verbose = true) {
  1847. return defaultDescribe(verbose, this, "community");
  1848. };
  1849. }
  1850. function Town(count = 1) {
  1851. this.name = "Town";
  1852. copy_defaults(this, new DefaultEntity());
  1853. this.count = count;
  1854. this.contents = initContents(this.name, this.count);
  1855. this.describe = function (verbose = true) {
  1856. return defaultDescribe(verbose, this, "community");
  1857. };
  1858. }
  1859. function City(count = 1) {
  1860. this.name = "City";
  1861. copy_defaults(this, new DefaultEntity());
  1862. this.count = count;
  1863. this.contents = initContents(this.name, this.count);
  1864. this.describe = function (verbose = true) {
  1865. return defaultDescribe(verbose, this, "community");
  1866. };
  1867. }
  1868. function Continent(count = 1) {
  1869. this.name = "Continent";
  1870. copy_defaults(this, new DefaultEntity());
  1871. this.count = count;
  1872. this.contents = initContents(this.name, this.count);
  1873. this.describe = function (verbose = true) {
  1874. return defaultDescribe(verbose, this, "community");
  1875. };
  1876. }
  1877. function Planet(count = 1) {
  1878. this.name = "Planet";
  1879. copy_defaults(this, new DefaultEntity());
  1880. this.count = count;
  1881. this.contents = initContents(this.name, this.count);
  1882. this.describe = function (verbose = true) {
  1883. return defaultDescribe(verbose, this, "community");
  1884. };
  1885. }
  1886. function Star(count = 1) {
  1887. this.name = "Star";
  1888. copy_defaults(this, new DefaultEntity());
  1889. this.count = count;
  1890. this.contents = initContents(this.name, this.count);
  1891. this.describe = function (verbose = true) {
  1892. return this.count == 1 ? "a star" : this.count + " stars";
  1893. };
  1894. }
  1895. function SolarSystem(count = 1) {
  1896. this.name = "Solar System";
  1897. copy_defaults(this, new DefaultEntity());
  1898. this.count = count;
  1899. this.contents = initContents(this.name, this.count);
  1900. this.describe = function (verbose = true) {
  1901. return defaultDescribe(verbose, this, "celestial");
  1902. };
  1903. }
  1904. function Galaxy(count = 1) {
  1905. this.name = "Galaxy";
  1906. copy_defaults(this, new DefaultEntity());
  1907. this.count = count;
  1908. this.contents = initContents(this.name, this.count);
  1909. this.describe = function (verbose = true) {
  1910. return defaultDescribe(verbose, this, "celestial");
  1911. };
  1912. }
  1913. function Cluster(count = 1) {
  1914. this.name = "Cluster";
  1915. copy_defaults(this, new DefaultEntity());
  1916. this.count = count;
  1917. this.contents = initContents(this.name, this.count);
  1918. this.describe = function (verbose = true) {
  1919. return defaultDescribe(verbose, this, "celestial");
  1920. };
  1921. }
  1922. function Universe(count = 1) {
  1923. this.name = "Universe";
  1924. copy_defaults(this, new DefaultEntity());
  1925. this.count = count;
  1926. this.contents = initContents(this.name, this.count);
  1927. this.describe = function (verbose = true) {
  1928. return defaultDescribe(verbose, this, "celestial");
  1929. };
  1930. }
  1931. function Multiverse(count = 1) {
  1932. this.name = "Multiverse";
  1933. copy_defaults(this, new DefaultEntity());
  1934. this.count = count;
  1935. this.contents = initContents(this.name, this.count);
  1936. this.describe = function (verbose = true) {
  1937. return defaultDescribe(verbose, this, "celestial");
  1938. };
  1939. }
  1940. function Timeline(count = 1) {
  1941. this.name = "Timeline";
  1942. copy_defaults(this, new DefaultEntity());
  1943. this.count = count;
  1944. this.contents = initContents(this.name, this.count);
  1945. this.describe = function (verbose = true) {
  1946. return defaultDescribe(verbose, this, "celestial");
  1947. };
  1948. }
  1949. function Pantheon(count = 1) {
  1950. this.name = "Pantheon";
  1951. copy_defaults(this, new DefaultEntity());
  1952. this.count = count;
  1953. this.contents = initContents(this.name, this.count);
  1954. this.describe = function (verbose = true) {
  1955. return defaultDescribe(verbose, this, "celestial");
  1956. };
  1957. }
  1958. function Deity(count = 1) {
  1959. this.name = "Deity";
  1960. copy_defaults(this, new DefaultEntity());
  1961. this.count = count;
  1962. this.contents = initContents(this.name, this.count);
  1963. this.describe = function (verbose = true) {
  1964. return defaultDescribe(verbose, this, "celestial");
  1965. };
  1966. }
  1967. function Reality(count = 1) {
  1968. this.name = "Reality";
  1969. copy_defaults(this, new DefaultEntity());
  1970. this.count = count;
  1971. this.contents = initContents(this.name, this.count);
  1972. this.describe = function (verbose = true) {
  1973. return defaultDescribe(verbose, this, "celestial");
  1974. };
  1975. }
  1976. function Soldier(count = 1) {
  1977. this.name = "Soldier";
  1978. copy_defaults(this, new DefaultEntity());
  1979. this.count = count;
  1980. this.contents = initContents(this.name, this.count);
  1981. this.describe = function (verbose = true) {
  1982. return defaultDescribe(verbose, this, "military");
  1983. };
  1984. }
  1985. function Tank(count = 1) {
  1986. this.name = "Tank";
  1987. copy_defaults(this, new DefaultEntity());
  1988. this.count = count;
  1989. this.contents = initContents(this.name, this.count);
  1990. this.describe = function (verbose = true) {
  1991. return defaultDescribe(verbose, this, "generic vehicle");
  1992. };
  1993. }
  1994. function Artillery(count = 1) {
  1995. this.name = "Artillery";
  1996. copy_defaults(this, new DefaultEntity());
  1997. this.count = count;
  1998. this.contents = initContents(this.name, this.count);
  1999. this.describe = function (verbose = true) {
  2000. return defaultDescribe(verbose, this, "generic vehicle");
  2001. };
  2002. }
  2003. function MilitaryHelicopter(count = 1) {
  2004. this.name = "Military Helicopter";
  2005. copy_defaults(this, new DefaultEntity());
  2006. this.count = count;
  2007. this.contents = initContents(this.name, this.count);
  2008. this.describe = function (verbose = true) {
  2009. return defaultDescribe(verbose, this, "generic vehicle");
  2010. };
  2011. }
  2012. function Micro(count = 1) {
  2013. this.name = "Micro";
  2014. copy_defaults(this, new DefaultEntity());
  2015. this.count = count;
  2016. this.contents = initContents(this.name, this.count);
  2017. this.describe = function (verbose = true) {
  2018. return defaultDescribe(verbose, this);
  2019. };
  2020. }
  2021. function Macro(count = 1) {
  2022. this.name = "Macro";
  2023. copy_defaults(this, new DefaultEntity());
  2024. this.count = count;
  2025. this.contents = initContents(this.name, this.count);
  2026. this.describe = function (verbose = true) {
  2027. return defaultDescribe(verbose, this);
  2028. };
  2029. }
  2030. function Squad(count = 1) {
  2031. this.name = "Squad";
  2032. copy_defaults(this, new DefaultEntity());
  2033. this.count = count;
  2034. this.contents = initContents(this.name, this.count);
  2035. this.describe = function (verbose = true) {
  2036. return defaultDescribe(verbose, this, "military");
  2037. };
  2038. }
  2039. function Platoon(count = 1) {
  2040. this.name = "Platoon";
  2041. copy_defaults(this, new DefaultEntity());
  2042. this.count = count;
  2043. this.contents = initContents(this.name, this.count);
  2044. this.describe = function (verbose = true) {
  2045. return defaultDescribe(verbose, this, "military");
  2046. };
  2047. }
  2048. function Company(count = 1) {
  2049. this.name = "Company";
  2050. copy_defaults(this, new DefaultEntity());
  2051. this.count = count;
  2052. this.contents = initContents(this.name, this.count);
  2053. this.describe = function (verbose = true) {
  2054. return defaultDescribe(verbose, this, "military");
  2055. };
  2056. }
  2057. function Battalion(count = 1) {
  2058. this.name = "Battalion";
  2059. copy_defaults(this, new DefaultEntity());
  2060. this.count = count;
  2061. this.contents = initContents(this.name, this.count);
  2062. this.describe = function (verbose = true) {
  2063. return defaultDescribe(verbose, this, "military");
  2064. };
  2065. }
  2066. function Brigade(count = 1) {
  2067. this.name = "Brigade";
  2068. copy_defaults(this, new DefaultEntity());
  2069. this.count = count;
  2070. this.contents = initContents(this.name, this.count);
  2071. this.describe = function (verbose = true) {
  2072. return defaultDescribe(verbose, this, "military");
  2073. };
  2074. }
  2075. function Division(count = 1) {
  2076. this.name = "Division";
  2077. copy_defaults(this, new DefaultEntity());
  2078. this.count = count;
  2079. this.contents = initContents(this.name, this.count);
  2080. this.describe = function (verbose = true) {
  2081. return defaultDescribe(verbose, this, "military");
  2082. };
  2083. }
  2084. function TankDivision(count = 1) {
  2085. this.name = "Tank Division";
  2086. copy_defaults(this, new DefaultEntity());
  2087. this.count = count;
  2088. this.contents = initContents(this.name, this.count);
  2089. this.describe = function (verbose = true) {
  2090. return defaultDescribe(verbose, this, "military");
  2091. };
  2092. }
  2093. function Army(count = 1) {
  2094. this.name = "Army";
  2095. copy_defaults(this, new DefaultEntity());
  2096. this.count = count;
  2097. this.contents = initContents(this.name, this.count);
  2098. this.describe = function (verbose = true) {
  2099. return defaultDescribe(verbose, this, "military");
  2100. };
  2101. }
  2102. //todo
  2103. //farms
  2104. //factories
  2105. //racetracks
  2106. //more building types
  2107. //cranes and other construction equipment
  2108. //nebula
  2109. //biome magic also set it so that you can't roll your existing biome
  2110. //chemical factory
  2111. //grand army
  2112. //armada