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.
 
 
 

1640 lines
44 KiB

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