big steppy
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

1200 行
32 KiB

  1. 'use strict';
  2. var things =
  3. {
  4. "Container": Container,
  5. "Person": Person,
  6. "Human": Human,
  7. "Cow": Cow,
  8. "Empty Car": EmptyCar,
  9. "Car": Car,
  10. "Bus": Bus,
  11. "Tram": Tram,
  12. "House": House,
  13. "Barn": Barn,
  14. "Small Skyscraper": SmallSkyscraper,
  15. "Large Skyscraper": LargeSkyscraper,
  16. "Train": Train,
  17. "Train Car": TrainCar,
  18. "Parking Garage": ParkingGarage,
  19. "Town": Town,
  20. "City": City,
  21. "Continent": Continent,
  22. "Planet": Planet,
  23. "Star": Star,
  24. "Solar System": SolarSystem,
  25. "Galaxy": Galaxy,
  26. "Cluster": Cluster,
  27. "Universe": Universe,
  28. "Multiverse": Multiverse,
  29. "Soldier": Soldier,
  30. "Tank": Tank,
  31. "Artillery": Artillery,
  32. "Helicopter": Helicopter,
  33. "Micro": Micro,
  34. "Macro": Macro,
  35. };
  36. var areas =
  37. {
  38. "Container": 0,
  39. "Person": 0.33,
  40. "Human": 0.33,
  41. "Cow": 2,
  42. "Car": 4,
  43. "Bus": 12,
  44. "Tram": 20,
  45. "House": 150,
  46. "Barn": 300,
  47. "Small Skyscraper": 1000,
  48. "Large Skyscraper": 2000,
  49. "Train": 40,
  50. "TrainCar": 20,
  51. "Parking Garage": 750,
  52. "Town": 1e7,
  53. "City": 1e9,
  54. "Continent": 1.5e13,
  55. "Planet": 2.5e14,
  56. "Star": 3e18,
  57. "Solar System": 3e21,
  58. "Galaxy": 2e45,
  59. "Cluster": 2e49,
  60. "Universe": 7e53,
  61. "Multiverse": 5e56,
  62. "Soldier": 1,
  63. "Tank": 10,
  64. "Artillery": 12,
  65. "Helicopter": 8,
  66. "Micro": 0.05,
  67. "Macro": 100,
  68. };
  69. var masses =
  70. {
  71. "Container": 0,
  72. "Person": 80,
  73. "Human": 80,
  74. "Cow": 300,
  75. "Car": 1000,
  76. "Bus": 5000,
  77. "Tram": 10000,
  78. "House": 10000,
  79. "Barn": 5000,
  80. "Small Skyscraper": 10000000,
  81. "Large Skyscraper": 80000000,
  82. "Train": 50000,
  83. "Train Car": 7500,
  84. "Parking Garage": 10000000,
  85. "Town": 1,
  86. "City": 1,
  87. "Continent": 1e21,
  88. "Planet": 5.972e24,
  89. "Star": 1e40,
  90. "Solar System": 1,
  91. "Galaxy": 1,
  92. "Cluster": 1,
  93. "Universe": 1,
  94. "Multiverse": 1,
  95. "Soldier": 80,
  96. "Tank": 5000,
  97. "Artillery": 7000,
  98. "Helicopter": 1500,
  99. "Micro": 0.01,
  100. "Macro": 80000,
  101. };
  102. var clusters =
  103. {
  104. "Container": 0,
  105. "Person": 5,
  106. "Human": 5,
  107. "Cow": 15,
  108. "Car": 3,
  109. "Bus": 1,
  110. "Tram": 1,
  111. "House": 5,
  112. "Barn": 1,
  113. "Small Skyscraper": 2,
  114. "Large Skyscraper": 1,
  115. "Train": 2,
  116. "Train Car": 1,
  117. "Parking Garage": 1,
  118. "Town": 5,
  119. "City": 1,
  120. "Continent": 5,
  121. "Planet": 1,
  122. "Star": 1,
  123. "Solar System": 1,
  124. "Galaxy": 1,
  125. "Cluster": 1,
  126. "Universe": 1,
  127. "Multiverse": 1,
  128. "Soldier": 0,
  129. "Tank": 0,
  130. "Artillery": 0,
  131. "Helicopter": 0,
  132. "Micro": 10,
  133. "Macro": 0,
  134. };
  135. var contents =
  136. {
  137. "Container": [],
  138. "Person": [],
  139. "Human": [],
  140. "Cow": [],
  141. "Car": [["Person",1,4]],
  142. "Bus": [["Person",2,30]],
  143. "Tram": [["Person",10,50]],
  144. "Train": [["Person",1,4,"engine"],["Train Car",2,10]],
  145. "Train Car": [["Person",10,40]],
  146. "House": [["Person",0,8],["Empty Car",0,2]],
  147. "Barn": [["Person",0,2],["Cow",30,70]],
  148. "Small Skyscraper": [["Person",150,750],["Empty Car",10,50]],
  149. "Large Skyscraper": [["Person",500,1500],["Empty Car",20,100]],
  150. "Parking Garage": [["Person",10,200],["Empty Car",100,300],["Car",5,30]],
  151. "Town": [["Person",10000,100000],["House",5000,50000],["Empty Car",200,800],["Car",500,80000],["Bus",5,25],["Train",5,25]],
  152. "City": [["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]],
  153. "Continent": [["Person",1000000,15000000],["House",2500,10000],["Car",25000,375000],["Train",50,500],["Town",500,1000],["City",50,250]],
  154. "Planet": [["Continent",4,9]],
  155. "Star": [],
  156. "Solar System": [["Star",1,1],["Planet",5,15]],
  157. "Galaxy": [["Star",1e9,500e9],["Solar System",1e8,500e8]],
  158. "Cluster": [["Galaxy",200,5000]],
  159. "Universe": [["Cluster",1.5e9,2.5e9]],
  160. "Multiverse": [["Universe",100,1000]],
  161. "Soldier": [],
  162. "Tank": [["Soldier",3,5]],
  163. "Artillery": [["Soldier",4,6]],
  164. "Helicopter": [["Soldier",4,16]],
  165. "Micro": [[]],
  166. "Macro": [[]]
  167. };
  168. // replace all instances of from with to
  169. function contents_substitute(from,to) {
  170. for (let key in contents) {
  171. if (contents.hasOwnProperty(key)) {
  172. let type = contents[key];
  173. for (let i=0; i<type.length; i++) {
  174. if (type[i][0] == from) {
  175. type[i][0] = to;
  176. }
  177. }
  178. }
  179. }
  180. }
  181. // remove all instances of thing
  182. function contents_remove(thing) {
  183. for (let key in contents) {
  184. if (contents.hasOwnProperty(key)) {
  185. let type = contents[key];
  186. for (let i=0; i<type.length; i++) {
  187. if (type[i][0] == thing) {
  188. type.splice(i,1);
  189. --i;
  190. }
  191. }
  192. }
  193. }
  194. }
  195. // adds thing to parent
  196. function contents_insert(parent,thing,min,max,label) {
  197. let owner = contents[parent];
  198. if (label == undefined)
  199. owner.push([thing,min,max]);
  200. else
  201. owner.push([thing,min,max,label]);
  202. }
  203. function initContents(name,count) {
  204. let result = {};
  205. let type = contents[name];
  206. for (let i=0; i<type.length; i++) {
  207. let amount = distribution(type[i][1],type[i][2],count);
  208. if (amount > 0) {
  209. // if a custom label is supplied, use it!
  210. if (type[i].length == 4)
  211. result[type[i][3]] = new things[type[i][0]](amount);
  212. else
  213. result[type[i][0]] = new things[type[i][0]](amount);
  214. }
  215. }
  216. return result;
  217. }
  218. function get_living_prey(sum) {
  219. let total = 0;
  220. for (let key in sum) {
  221. if (sum.hasOwnProperty(key)) {
  222. if (key == "Micro" || key == "Macro" || key == "Person" || key == "Cow" || key == 'Soldier')
  223. total += sum[key];
  224. }
  225. }
  226. return total;
  227. }
  228. // general logic: each step fills in a fraction of the remaining space
  229. function fill_area(area, weights, variance=0.15)
  230. {
  231. area = area + Math.random() * variance * 2 * area - variance * area;
  232. var result = [];
  233. var candidates = [];
  234. for (var key in weights) {
  235. if (weights.hasOwnProperty(key)) {
  236. candidates.push({"name": key, "area": areas[key], "weight": weights[key]});
  237. }
  238. }
  239. candidates = candidates.sort(function (x,y) {
  240. return x.area - y.area;
  241. });
  242. while(candidates.length > 0) {
  243. var candidate = candidates.pop();
  244. if (candidate.area > area)
  245. continue;
  246. var max = Math.floor(area / candidate.area);
  247. var limit = Math.min(max, 100);
  248. var count = 0;
  249. var loopvar = limit;
  250. // for small amounts, actually do the randomness
  251. // the first few ones get a much better shot
  252. while (loopvar > 0) {
  253. if (loopvar <= clusters[candidate.name] && loopvar == 1)
  254. count += 1;
  255. else if (loopvar <= clusters[candidate.name]) {
  256. if (Math.random() < candidate.weight ? 1 : 0 || Math.random() < 0.75) {
  257. count += 1;
  258. }
  259. }
  260. else
  261. count += Math.random() < candidate.weight ? 1 : 0;
  262. --loopvar;
  263. }
  264. if (limit < max) {
  265. count += Math.round((max-limit) * candidate.weight);
  266. }
  267. area -= count * candidate.area;
  268. if (count > 0)
  269. result.push(new things[candidate.name](count));
  270. }
  271. return new Container(result);
  272. }
  273. // describes everything in the container
  274. function describe_all(contents,verbose=true,except=[]) {
  275. var things = [];
  276. for (var key in contents) {
  277. if (contents.hasOwnProperty(key) && !except.includes(key)) {
  278. things.push(contents[key].describe(verbose));
  279. }
  280. }
  281. return merge_things(things);
  282. }
  283. function random_desc(list, odds=1) {
  284. if (Math.random() < odds)
  285. return list[Math.floor(Math.random() * list.length)];
  286. else
  287. return "";
  288. }
  289. // combine strings into a list with proper grammar
  290. function merge_things(list,semicolons=false) {
  291. if (list.length == 0) {
  292. return "";
  293. } else if (list.length == 1) {
  294. return list[0];
  295. } else if (list.length == 2) {
  296. return list[0] + " and " + list[1];
  297. } else {
  298. var result = "";
  299. list.slice(0,list.length-1).forEach(function(term) {
  300. result += term + ", ";
  301. });
  302. result += "and " + list[list.length-1];
  303. return result;
  304. }
  305. }
  306. // combine the adjectives for something into a single string
  307. function merge_desc(list) {
  308. var result = "";
  309. list.forEach(function(term) {
  310. if (term != "")
  311. result += term + " ";
  312. });
  313. // knock off the last space
  314. if (result.length > 0) {
  315. result = result.substring(0, result.length - 1);
  316. }
  317. return result;
  318. }
  319. // maybe make this something that approximates a
  320. // normal distribution; doing this 15,000,000 times is bad...
  321. // solution: only a few are random lul
  322. // improvement: take up to 100 samples, then use that to scale the final result
  323. function distribution(min, max, samples) {
  324. var result = 0;
  325. var limit = Math.min(100,samples);
  326. if (limit < samples) {
  327. let dist = 0;
  328. for (let i = 0; i < limit; i++) {
  329. dist += Math.random();
  330. }
  331. dist /= 100;
  332. return Math.floor(dist * samples * (max - min + 1) + samples * min);
  333. } else {
  334. for (let i = 0; i < limit; i++) {
  335. result += Math.floor(Math.random() * (max - min + 1) + min);
  336. }
  337. }
  338. return result;
  339. }
  340. function defaultArea(thing) {
  341. return areas[thing.name];
  342. }
  343. function defaultMass(thing) {
  344. return masses[thing.name];
  345. }
  346. function defaultMerge(thing) {
  347. return function(container) {
  348. var newCount = this.count + container.count;
  349. var newThing = new things[thing.name](newCount);
  350. newThing.contents = {};
  351. for (var key in this.contents) {
  352. if (this.contents.hasOwnProperty(key)) {
  353. newThing.contents[key] = this.contents[key];
  354. }
  355. }
  356. for (key in container.contents) {
  357. if (container.contents.hasOwnProperty(key)) {
  358. if (this.contents.hasOwnProperty(key)) {
  359. newThing.contents[key] = this.contents[key].merge(container.contents[key]);
  360. } else {
  361. newThing.contents[key] = container.contents[key];
  362. }
  363. }
  364. }
  365. return newThing;
  366. };
  367. }
  368. function listSum(sum) {
  369. let result = [];
  370. for (let key in sum) {
  371. if (sum.hasOwnProperty(key)) {
  372. result.push(new things[key](sum[key]).describe(false));
  373. }
  374. }
  375. return merge_things(result);
  376. }
  377. function defaultSum(thing) {
  378. return function() {
  379. var counts = {};
  380. if (thing.name != "Container")
  381. counts[thing.name] = thing.count;
  382. for (var key in thing.contents) {
  383. if (thing.contents.hasOwnProperty(key)) {
  384. var subcount = thing.contents[key].sum();
  385. for (var subkey in subcount) {
  386. if (!counts.hasOwnProperty(subkey)) {
  387. counts[subkey] = 0;
  388. }
  389. counts[subkey] += subcount[subkey];
  390. }
  391. }
  392. }
  393. return counts;
  394. };
  395. }
  396. function defaultSumProperty(thing) {
  397. return function(prop) {
  398. var total = 0;
  399. total += thing[prop] * thing.count;
  400. for (var key in thing.contents) {
  401. if (thing.contents.hasOwnProperty(key)) {
  402. total += thing.contents[key].sum_property(prop);
  403. }
  404. }
  405. return total;
  406. };
  407. }
  408. function defaultAddContent(thing) {
  409. return function(name, min, max, count) {
  410. if (min == max) {
  411. let object = new things[name](min*count);
  412. thing.contents[object.name] = object;
  413. } else {
  414. let object = new things[name](distribution(min, max, count));
  415. thing.contents[object.name] = object;
  416. }
  417. };
  418. }
  419. function DefaultEntity() {
  420. this.sum = defaultSum;
  421. this.area = defaultArea;
  422. this.mass = defaultMass;
  423. this.sum_property = defaultSumProperty;
  424. this.merge = defaultMerge;
  425. return this;
  426. }
  427. // god I love reinventing the wheel
  428. function copy_defaults(self,proto) {
  429. for (var key in proto) {
  430. if (proto.hasOwnProperty(key)) {
  431. self[key] = proto[key](self);
  432. }
  433. }
  434. }
  435. function Container(contents = []) {
  436. this.name = "Container";
  437. copy_defaults(this,new DefaultEntity());
  438. if (Number.isInteger(contents))
  439. this.count = contents;
  440. else
  441. this.count = 0;
  442. this.contents = {};
  443. for (var i=0; i < contents.length; i++) {
  444. this.contents[contents[i].name] = contents[i];
  445. }
  446. for (var key in this.contents) {
  447. if (this.contents.hasOwnProperty(key)) {
  448. this.count += this.contents[key].count;
  449. }
  450. }
  451. this.describe = function(verbose = true) {
  452. return describe_all(this.contents,verbose);
  453. };
  454. return this;
  455. }
  456. function Person(count = 1) {
  457. this.name = "Person";
  458. copy_defaults(this,new DefaultEntity());
  459. this.count = count;
  460. this.contents = initContents(this.name,this.count);
  461. this.describeOne = function (verbose=true) {
  462. var body = random_desc(["skinny","fat","tall","short","stocky","spindly"], (verbose ? 0.6 : 0));
  463. var sex = random_desc(["male", "female"], (verbose ? 1 : 0));
  464. var species = "";
  465. species = random_desc(["wolf","cat","dog","squirrel","horse","hyena","fox","jackal","crux","sergal"]);
  466. return "a " + merge_desc([body,sex,species]);
  467. };
  468. this.describe = function(verbose=true) {
  469. if (verbose) {
  470. if (count <= 3) {
  471. var list = [];
  472. for (var i = 0; i < count; i++) {
  473. list.push(this.describeOne(this.count <= 2));
  474. }
  475. return merge_things(list);
  476. } else {
  477. return this.count + " people";
  478. }
  479. } else {
  480. return (this.count > 1 ? this.count + " people" : "a person");
  481. }
  482. };
  483. return this;
  484. }
  485. function Human(count = 1) {
  486. this.name = "Person";
  487. copy_defaults(this,new DefaultEntity());
  488. this.count = count;
  489. this.contents = initContents(this.name,this.count);
  490. this.describeOne = function (verbose=true) {
  491. var body = random_desc(["skinny","fat","tall","short","stocky","spindly"], (verbose ? 0.6 : 0));
  492. var sex = random_desc(["man", "woman"], 1);
  493. return "a " + merge_desc([body,sex]);
  494. };
  495. this.describe = function(verbose=true) {
  496. if (verbose) {
  497. if (count <= 3) {
  498. var list = [];
  499. for (var i = 0; i < count; i++) {
  500. list.push(this.describeOne(this.count <= 2));
  501. }
  502. return merge_things(list);
  503. } else {
  504. return this.count + " people";
  505. }
  506. } else {
  507. return (this.count > 1 ? this.count + " people" : "a person");
  508. }
  509. };
  510. return this;
  511. }
  512. function Cow(count = 1) {
  513. this.name = "Cow";
  514. copy_defaults(this,new DefaultEntity());
  515. this.count = count;
  516. this.contents = initContents(this.name,this.count);
  517. this.describeOne = function (verbose=true) {
  518. var body = random_desc(["skinny","fat","tall","short","stocky","spindly"], (verbose ? 0.6 : 0));
  519. var sex = random_desc(["male", "female"], (verbose ? 1 : 0));
  520. return "a " + merge_desc([body,sex,"cow"]);
  521. };
  522. this.describe = function(verbose=true) {
  523. if (verbose) {
  524. if (count <= 3) {
  525. var list = [];
  526. for (var i = 0; i < count; i++) {
  527. list.push(this.describeOne(this.count <= 2));
  528. }
  529. return merge_things(list);
  530. } else {
  531. return this.count + " cattle";
  532. }
  533. } else {
  534. return (this.count > 1 ? this.count + " cattle" : "a cow");
  535. }
  536. };
  537. return this;
  538. }
  539. function EmptyCar(count = 1) {
  540. this.name = "Car";
  541. copy_defaults(this,new DefaultEntity());
  542. this.count = count;
  543. this.contents = initContents(this.name,this.count);
  544. this.describeOne = function(verbose=true) {
  545. var color = random_desc(["black","black","gray","gray","blue","red","tan","white","white"]);
  546. var adjective = random_desc(["rusty","brand-new"],0.3);
  547. var type = random_desc(["SUV","coupe","sedan","truck","van","convertible"]);
  548. return "a parked " + merge_desc([adjective,color,type]);
  549. };
  550. this.describe = function(verbose = true) {
  551. if (verbose) {
  552. if (this.count <= 3) {
  553. var list = [];
  554. for (var i = 0; i < this.count; i++) {
  555. list.push(this.describeOne());
  556. }
  557. return merge_things(list);
  558. } else {
  559. return this.count + " parked cars";
  560. }
  561. } else {
  562. return (this.count > 1 ? this.count + " parked cars" : "a parked car");
  563. }
  564. };
  565. }
  566. function Car(count = 1) {
  567. this.name = "Car";
  568. copy_defaults(this,new DefaultEntity());
  569. this.count = count;
  570. this.contents = initContents(this.name,this.count);
  571. this.describeOne = function(verbose=true) {
  572. var color = random_desc(["black","black","gray","gray","blue","red","tan","white","white"], (verbose ? 1 : 0));
  573. var adjective = random_desc(["rusty","brand-new"], (verbose ? 0.3 : 0));
  574. var type = random_desc(["SUV","coupe","sedan","truck","van","convertible"]);
  575. return "a " + merge_desc([adjective,color,type]);
  576. };
  577. this.describe = function(verbose = true) {
  578. if (verbose) {
  579. if (this.count <= 3) {
  580. var list = [];
  581. for (var i = 0; i < this.count; i++) {
  582. list.push(this.describeOne(this.count < 2));
  583. }
  584. return merge_things(list) + " with " + describe_all(this.contents,verbose) + " inside";
  585. } else {
  586. return this.count + " cars with " + describe_all(this.contents,verbose) + " inside";
  587. }
  588. } else {
  589. return (this.count > 1 ? this.count + " cars" : "a car");
  590. }
  591. };
  592. }
  593. function Bus(count = 1) {
  594. this.name = "Bus";
  595. copy_defaults(this,new DefaultEntity());
  596. this.count = count;
  597. this.contents = initContents(this.name,this.count);
  598. this.describeOne = function(verbose=true) {
  599. var adjective = random_desc(["rusty","brand-new"], (verbose ? 0.3 : 0));
  600. var color = random_desc(["black","tan","gray"], (verbose ? 1 : 0));
  601. var type = random_desc(["bus","double-decker bus","articulating bus"]);
  602. return "a " + merge_desc([adjective,color,type]);
  603. };
  604. this.describe = function(verbose = true) {
  605. if (verbose) {
  606. if (this.count <= 3) {
  607. var list = [];
  608. for (var i = 0; i < this.count; i++) {
  609. list.push(this.describeOne(this.count < 2));
  610. }
  611. return merge_things(list) + " with " + describe_all(this.contents,verbose) + " inside";
  612. } else {
  613. return this.count + " buses with " + describe_all(this.contents,verbose) + " inside";
  614. }
  615. } else {
  616. return (this.count > 1 ? this.count + " buses" : "a bus");
  617. }
  618. };
  619. }
  620. function Tram(count = 1) {
  621. this.name = "Tram";
  622. copy_defaults(this,new DefaultEntity());
  623. this.count = count;
  624. this.contents = initContents(this.name,this.count);
  625. this.describeOne = function(verbose=true) {
  626. var adjective = random_desc(["rusty","weathered"], (verbose ? 0.3 : 0));
  627. var color = random_desc(["blue","brown","gray"], (verbose ? 1 : 0));
  628. var type = random_desc(["tram"]);
  629. return "a " + merge_desc([adjective,color,type]);
  630. };
  631. this.describe = function(verbose = true) {
  632. if (verbose) {
  633. if (this.count == 1) {
  634. var list = [];
  635. for (var i = 0; i < this.count; i++) {
  636. list.push(this.describeOne(verbose));
  637. }
  638. return merge_things(list) + " with " + describe_all(this.contents,verbose) + " inside";
  639. } else {
  640. return this.count + " trams with " + describe_all(this.contents,verbose) + " inside";
  641. }
  642. } else {
  643. return (this.count > 1 ? this.count + " trams" : "a tram");
  644. }
  645. };
  646. this.anal_vore = function() {
  647. return "You slide " + this.describe() + " up your tight ass";
  648. };
  649. }
  650. function Train(count = 1) {
  651. this.name = "Train";
  652. copy_defaults(this,new DefaultEntity());
  653. this.count = count;
  654. this.contents = initContents(this.name,this.count);
  655. this.describeOne = function(verbose=true) {
  656. var adjective = random_desc(["rusty","brand-new"], (verbose ? 0.3 : 0));
  657. var color = random_desc(["black","tan","gray"], (verbose ? 1 : 0));
  658. var type = random_desc(["train","passenger train","freight train"]);
  659. return "a " + merge_desc([adjective,color,type]);
  660. };
  661. this.describe = function(verbose = true) {
  662. if (verbose) {
  663. if (this.count == 1) {
  664. var list = [];
  665. for (var i = 0; i < this.count; i++) {
  666. list.push(this.describeOne(verbose));
  667. }
  668. return merge_things(list) + " with " + this.contents["engine"].describe(false) + " in the engine and " + this.contents["Train Car"].describe() + " attached";
  669. } else {
  670. return this.count + " trains with " + this.contents["engine"].describe(false) + " in the engine and " + this.contents["Train Car"].describe() + " attached";
  671. }
  672. } else {
  673. return (this.count > 1 ? this.count + " trains" : "a train");
  674. }
  675. };
  676. this.anal_vore = function() {
  677. 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");
  678. return "You snatch up " + this.describeOne() + " and stuff it into your pucker, moaning as " + cars;
  679. };
  680. }
  681. function TrainCar(count = 1) {
  682. this.name = "Train Car";
  683. copy_defaults(this,new DefaultEntity());
  684. this.count = count;
  685. this.contents = initContents(this.name,this.count);
  686. this.describeOne = function(verbose=true) {
  687. var adjective = random_desc(["rusty","brand-new"], (verbose ? 0.3 : 0));
  688. var color = random_desc(["black","tan","gray"], (verbose ? 1 : 0));
  689. var type = random_desc(["train car","passenger train car","freight train car"]);
  690. return "a " + merge_desc([adjective,color,type]);
  691. };
  692. this.describe = function(verbose = true) {
  693. if (verbose) {
  694. return (this.count > 1 ? this.count + " train cars" : "a train car") + " with " + describe_all(this.contents) + " inside";
  695. } else {
  696. return (this.count > 1 ? this.count + " train cars" : "a train car");
  697. }
  698. };
  699. }
  700. function House(count = 1) {
  701. this.name = "House";
  702. copy_defaults(this,new DefaultEntity());
  703. this.count = count;
  704. this.contents = initContents(this.name,this.count);
  705. this.describeOne = function(verbose=true) {
  706. var size = random_desc(["little","two-story","large"], (verbose ? 0.5 : 0));
  707. var color = random_desc(["blue","white","gray","tan","green"], (verbose ? 0.5 : 0));
  708. var name = random_desc(["house","house","house","house","house","trailer"], 1);
  709. return "a " + merge_desc([size,color,name]);
  710. };
  711. this.describe = function(verbose = true) {
  712. if (verbose) {
  713. if (this.count <= 3) {
  714. var list = [];
  715. for (var i = 0; i < this.count; i++) {
  716. list.push(this.describeOne(this.count < 2));
  717. }
  718. return merge_things(list) + " with " + describe_all(this.contents,verbose) + " inside";
  719. } else {
  720. return this.count + " homes with " + describe_all(this.contents,verbose) + " inside";
  721. }
  722. } else {
  723. return (this.count > 1 ? this.count + " houses" : "a house");
  724. }
  725. };
  726. }
  727. function Barn(count = 1) {
  728. this.name = "Barn";
  729. copy_defaults(this,new DefaultEntity());
  730. this.count = count;
  731. this.contents = initContents(this.name,this.count);
  732. this.describeOne = function(verbose=true) {
  733. var size = random_desc(["little","big","large"], (verbose ? 0.5 : 0));
  734. var color = random_desc(["blue","white","gray","tan","green"], (verbose ? 0.5 : 0));
  735. var name = random_desc(["barn","barn","barn","barn","barn","farmhouse"], 1);
  736. return "a " + merge_desc([size,color,name]);
  737. };
  738. this.describe = function(verbose = true) {
  739. if (verbose) {
  740. if (this.count <= 3) {
  741. var list = [];
  742. for (var i = 0; i < this.count; i++) {
  743. list.push(this.describeOne(this.count < 2));
  744. }
  745. return merge_things(list) + " with " + describe_all(this.contents,verbose) + " inside";
  746. } else {
  747. return this.count + " barns with " + describe_all(this.contents,verbose) + " inside";
  748. }
  749. } else {
  750. return (this.count > 1 ? this.count + " barns" : "a barn");
  751. }
  752. };
  753. }
  754. function SmallSkyscraper(count = 1) {
  755. this.name = "Small Skyscraper";
  756. copy_defaults(this,new DefaultEntity());
  757. this.count = count;
  758. this.contents = initContents(this.name,this.count);
  759. this.describeOne = function(verbose=true) {
  760. var color = random_desc(["blue","white","gray","tan","green"], (verbose ? 0.5 : 0));
  761. var name = random_desc(["skyscraper","office tower","office building"], 1);
  762. return "a " + merge_desc([color,name]);
  763. };
  764. this.describe = function(verbose = true) {
  765. if (verbose) {
  766. if (this.count <= 3) {
  767. var list = [];
  768. for (var i = 0; i < this.count; i++) {
  769. list.push(this.describeOne(this.count < 2));
  770. }
  771. return merge_things(list) + " with " + describe_all(this.contents,verbose) + " inside";
  772. } else {
  773. return this.count + " small skyscrapers with " + describe_all(this.contents,verbose) + " inside";
  774. }
  775. } else {
  776. return (this.count > 1 ? this.count + " small skyscrapers" : "a small skyscraper");
  777. }
  778. };
  779. }
  780. function LargeSkyscraper(count = 1) {
  781. this.name = "Large Skyscraper";
  782. copy_defaults(this,new DefaultEntity());
  783. this.count = count;
  784. this.contents = initContents(this.name,this.count);
  785. this.describeOne = function(verbose=true) {
  786. var color = random_desc(["blue","white","gray","tan","green"], (verbose ? 0.5 : 0));
  787. var name = random_desc(["skyscraper","office tower","office building"], 1);
  788. return "a " + merge_desc(["towering",color,name]);
  789. };
  790. this.describe = function(verbose = true) {
  791. if (verbose) {
  792. if (this.count <= 3) {
  793. var list = [];
  794. for (var i = 0; i < this.count; i++) {
  795. list.push(this.describeOne(this.count < 2));
  796. }
  797. return merge_things(list) + " with " + describe_all(this.contents,verbose) + " inside";
  798. } else {
  799. return this.count + " large skyscrapers with " + describe_all(this.contents,verbose) + " inside";
  800. }
  801. } else {
  802. return (this.count > 1 ? this.count + " large skyscrapers" : "a large skyscraper");
  803. }
  804. };
  805. }
  806. function ParkingGarage(count = 1) {
  807. this.name = "Parking Garage";
  808. copy_defaults(this,new DefaultEntity());
  809. this.count = count;
  810. this.contents = initContents(this.name,this.count);
  811. this.describeOne = function(verbose=true) {
  812. return "a parking garage";
  813. };
  814. this.describe = function(verbose = true) {
  815. if (verbose) {
  816. return (this.count == 1 ? "a parking garage" : this.count + " parking garages") + " with " + describe_all(this.contents, verbose) + " inside";
  817. } else {
  818. return (this.count == 1 ? "a parking garage" : this.count + " parking garages");
  819. }
  820. };
  821. }
  822. function Town(count = 1) {
  823. this.name = "Town";
  824. copy_defaults(this,new DefaultEntity());
  825. this.count = count;
  826. this.contents = initContents(this.name,this.count);
  827. this.describe = function(verbose = true) {
  828. if (verbose) {
  829. return (this.count == 1 ? "a town" : this.count + " towns") + " with " + describe_all(this.contents, verbose) + " in " + (this.count == 1 ? "it" : "them");
  830. } else {
  831. return (this.count == 1 ? "a town" : this.count + " towns");
  832. }
  833. };
  834. }
  835. function City(count = 1) {
  836. this.name = "City";
  837. copy_defaults(this,new DefaultEntity());
  838. this.count = count;
  839. this.contents = initContents(this.name,this.count);
  840. this.describe = function(verbose = true) {
  841. if (verbose) {
  842. return (this.count == 1 ? "a city" : this.count + " cities") + " with " + describe_all(this.contents, verbose) + " in " + (this.count == 1 ? "it" : "them");
  843. } else {
  844. return (this.count == 1 ? "a city" : this.count + " cities");
  845. }
  846. };
  847. }
  848. function Continent(count = 1) {
  849. this.name = "Continent";
  850. copy_defaults(this,new DefaultEntity());
  851. this.count = count;
  852. this.contents = initContents(this.name,this.count);
  853. this.describe = function(verbose = true) {
  854. if (verbose) {
  855. return (this.count == 1 ? "a continent" : this.count + " continents") + " with " + describe_all(this.contents, verbose) + " on " + (this.count == 1 ? "it" : "them");
  856. } else {
  857. return (this.count == 1 ? "a continent" : this.count + " continents");
  858. }
  859. };
  860. }
  861. function Planet(count = 1) {
  862. this.name = "Planet";
  863. copy_defaults(this,new DefaultEntity());
  864. this.count = count;
  865. this.contents = initContents(this.name,this.count);
  866. this.describe = function(verbose = true) {
  867. if (verbose) {
  868. return (this.count == 1 ? "a planet" : this.count + " planets") + " with " + describe_all(this.contents, verbose) + " on " + (this.count == 1 ? "it" : "them");
  869. } else {
  870. return (this.count == 1 ? "a planet" : this.count + " planets");
  871. }
  872. };
  873. }
  874. function Star(count = 1) {
  875. this.name = "Star";
  876. copy_defaults(this,new DefaultEntity());
  877. this.count = count;
  878. this.contents = initContents(this.name,this.count);
  879. this.describe = function(verbose = true) {
  880. return (this.count == 1 ? "a star" : this.count + " stars");
  881. };
  882. }
  883. function SolarSystem(count = 1) {
  884. this.name = "Solar System";
  885. copy_defaults(this,new DefaultEntity());
  886. this.count = count;
  887. this.contents = initContents(this.name,this.count);
  888. this.describe = function(verbose = true) {
  889. if (verbose) {
  890. return (this.count == 1 ? "a solar system" : this.count + " solar systems") + " made up of " + describe_all(this.contents, verbose);
  891. } else {
  892. return (this.count == 1 ? "a solar system" : this.count + " solar systems");
  893. }
  894. };
  895. }
  896. function Galaxy(count = 1) {
  897. this.name = "Galaxy";
  898. copy_defaults(this,new DefaultEntity());
  899. this.count = count;
  900. this.contents = initContents(this.name,this.count);
  901. this.describe = function(verbose = true) {
  902. if (verbose) {
  903. return (this.count == 1 ? "a galaxy" : this.count + " galaxies") + " made up of " + describe_all(this.contents, verbose);
  904. } else {
  905. return (this.count == 1 ? "a galaxy" : this.count + " galaxies");
  906. }
  907. };
  908. }
  909. function Cluster(count = 1) {
  910. this.name = "Cluster";
  911. copy_defaults(this,new DefaultEntity());
  912. this.count = count;
  913. this.contents = initContents(this.name,this.count);
  914. this.describe = function(verbose = true) {
  915. if (verbose) {
  916. return (this.count == 1 ? "a cluster" : this.count + " clusters") + " made up of " + describe_all(this.contents, verbose);
  917. } else {
  918. return (this.count == 1 ? "a cluster" : this.count + " clusters");
  919. }
  920. };
  921. }
  922. function Universe(count = 1) {
  923. this.name = "Universe";
  924. copy_defaults(this,new DefaultEntity());
  925. this.count = count;
  926. this.contents = initContents(this.name,this.count);
  927. this.describe = function(verbose = true) {
  928. if (verbose) {
  929. return (this.count == 1 ? "a universe" : this.count + " universes") + " made up of " + describe_all(this.contents, verbose);
  930. } else {
  931. return (this.count == 1 ? "a universe" : this.count + " universes");
  932. }
  933. };
  934. }
  935. function Multiverse(count = 1) {
  936. this.name = "Multiverse";
  937. copy_defaults(this,new DefaultEntity());
  938. this.count = count;
  939. this.contents = initContents(this.name,this.count);
  940. this.describe = function(verbose = true) {
  941. if (verbose) {
  942. return (this.count == 1 ? "a multiverse" : this.count + " multiverses") + " made up of " + describe_all(this.contents, verbose);
  943. } else {
  944. return (this.count == 1 ? "a multiverse" : this.count + " multiverses");
  945. }
  946. };
  947. }
  948. function Soldier(count = 1) {
  949. this.name = "Soldier";
  950. copy_defaults(this,new DefaultEntity());
  951. this.count = count;
  952. this.contents = initContents(this.name,this.count);
  953. this.describe = function(verbose = true) {
  954. return (this.count == 1 ? "a soldier" : this.count + " soldiers");
  955. };
  956. }
  957. function Tank(count = 1) {
  958. this.name = "Tank";
  959. copy_defaults(this,new DefaultEntity());
  960. this.count = count;
  961. this.contents = initContents(this.name,this.count);
  962. this.describe = function(verbose = true) {
  963. if (verbose) {
  964. return (this.count == 1 ? "a tank" : this.count + " tanks") + " with " + describe_all(this.contents, verbose) + " trapped inside.";
  965. } else {
  966. return (this.count == 1 ? "a tank" : this.count + " tanks");
  967. }
  968. };
  969. }
  970. function Artillery(count = 1) {
  971. this.name = "Artillery";
  972. copy_defaults(this,new DefaultEntity());
  973. this.count = count;
  974. this.contents = initContents(this.name,this.count);
  975. this.describe = function(verbose = true) {
  976. if (verbose) {
  977. return (this.count == 1 ? "an artillery unit" : this.count + " artillery units") + " with " + describe_all(this.contents, verbose) + " trapped inside.";
  978. } else {
  979. return (this.count == 1 ? "an artillery unit" : this.count + " artillery units");
  980. }
  981. };
  982. }
  983. function Helicopter(count = 1) {
  984. this.name = "Helicopter";
  985. copy_defaults(this,new DefaultEntity());
  986. this.count = count;
  987. this.contents = initContents(this.name,this.count);
  988. this.describe = function(verbose = true) {
  989. if (verbose) {
  990. return (this.count == 1 ? "a helicopter" : this.count + " helicopters") + " with " + describe_all(this.contents, verbose) + " riding inside.";
  991. } else {
  992. return (this.count == 1 ? "a helicopter" : this.count + " helicopters");
  993. }
  994. };
  995. }
  996. function Micro(count = 1) {
  997. this.name = "Micro";
  998. copy_defaults(this,new DefaultEntity());
  999. this.count = count;
  1000. this.contents = initContents(this.name,this.count);
  1001. this.describe = function(verbose = true) {
  1002. return (this.count == 1 ? "a micro" : this.count + " micros");
  1003. };
  1004. }
  1005. function Macro(count = 1) {
  1006. this.name = "Macro";
  1007. copy_defaults(this,new DefaultEntity());
  1008. this.count = count;
  1009. this.contents = initContents(this.name,this.count);
  1010. this.describe = function(verbose = true) {
  1011. return (this.count == 1 ? "a smaller macro" : this.count + " smaller macros");
  1012. };
  1013. }