1
1

main.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. // var rooma = new RoomRandom("Room A");
  2. // rooma.description = new Say(
  3. // "You are inside a box of metal painted blue. Your head almost touches the ceiling, making the room look smaller than it really is.",
  4. // Say.LINE_BREAK,
  5. // new SayIf(
  6. // () => {
  7. // return Thing.InsideRoomRelation.getLeft(vase) == rooma || Thing.InsideRoomRelation.getLeft(urn) == rooma;
  8. // },
  9. // " Still, there are some things thrown about."
  10. // )
  11. // );
  12. //
  13. // PlayBegins.setStartingRoom(rooma);
  14. //
  15. //
  16. // let paddedBra = new Clothing({name : "Padded Bra", unique : true});
  17. // paddedBra.breastPadding = 3;
  18. // paddedBra.slots = [Humanoid.SLOT_BREASTS];
  19. //
  20. // let paddedUnderwear = new Clothing({name : "Padded Underwear", unique : true});
  21. // paddedUnderwear.crotchPadding = 15;
  22. // paddedUnderwear.slots = [Humanoid.SLOT_CROTCH_BACK, Humanoid.SLOT_CROTCH_FRONT];
  23. //
  24. // // Thing.WearRelation.setRelation(WorldState.player, paddedBra);
  25. // // Thing.WearRelation.setRelation(WorldState.player, paddedUnderwear);
  26. //
  27. // let player = WorldState.player;
  28. // WorldState.player = player;
  29. // var vase = new Thing({name : "Vase"});
  30. // vase.description = new Say("This is an ornamental vase that'd look very nice on your lap. Why? Who knows.");
  31. // rooma.place(vase);
  32. //
  33. // let mapOfTest = new MapNote({name: "Map of this Region",
  34. // description : "This is a simple map showing all the rooms here.", unique : true});
  35. // rooma.place(mapOfTest);
  36. //
  37. // let urn = new Thing({unique: true, name : "Urn of Dreams", image : "image001"});
  38. // urn.description = new Say("This appears to be a simple, black urn containing the ashes of your dreams.");
  39. // rooma.place(urn);
  40. //
  41. // var roomb = new RoomRandom("Room B");
  42. // let gates = new Door("Gates of Orkindom", OrcVillage.SouthEntrance, true);
  43. // rooma.place(gates);
  44. //
  45. // roomb.place(vase);
  46. //
  47. //
  48. //
  49. // let frillyPouch = new CoinPouch({
  50. // name : "Frilly Pouch",
  51. // //image : new SayImage("image001"),
  52. // description : new Say("This is a very gay little pink pouch full of little hearts.")
  53. // });
  54. // frillyPouch.addCoins(502);
  55. // rooma.place(frillyPouch);
  56. //
  57. // // ActionTake.check.addRule(new Rule(<RuleOptions<any>> {
  58. // // code : function () {
  59. // // let promise = new Promise(() => {});
  60. // // return promise;
  61. // // }
  62. // // }));
  63. //
  64. // let bigSack = new CoinPouch({name : "Big Sack"});
  65. // bigSack.addCoins(100);
  66. // rooma.place(bigSack);
  67. //
  68. // let region = new RegionRandom("Test Region");
  69. //
  70. //
  71. // region.place(rooma, roomb);
  72. // for (let i = 1; i < 6; i++) {
  73. // let room = new RoomRandom("Room " + i.toString());
  74. // // let randomDirection = new Shuffler([Room.NORTH, Room.SOUTH, Room.EAST, Room.WEST])
  75. // // room.connectableOn = [randomDirection.getOne()];
  76. // //room.connectableOn = [Room.NORTH, Room.SOUTH, Room.EAST, Room.WEST];
  77. // region.place(room);
  78. //
  79. // if (Math.random() > 0.5) {
  80. // //mapOfTest.addRoom(room);
  81. // }
  82. //
  83. // }
  84. //
  85. // mapOfTest.addRegion(region);
  86. //
  87. // let southestRoom = new RoomRandom("Southest Room");
  88. // //southestRoom.appearChance = 0;
  89. //
  90. // region.place(southestRoom);
  91. //
  92. // //southestRoom.connectableOn = [Room.NORTH];
  93. // southestRoom.appearChance = 100;
  94. // southestRoom.backgroundImage = "bloo";
  95. //
  96. // southestRoom.trickyCode = (options : TrickyOptions) => {
  97. // let myCoordinates = [options.x, options.y];
  98. // for (let i = 0; i < Room.DIRECTIONS.length; i++) {
  99. // let direction = Room.DIRECTIONS[i];
  100. // if (direction != Direction.NORTH) {
  101. // let coordinates = Room.shift(myCoordinates, direction);
  102. // if (!options.map.isFree(coordinates[0], coordinates[1])) {
  103. // return false; // This room can only have rooms on north of it
  104. // }
  105. // coordinates = Room.shift(coordinates, direction);
  106. // if (!options.map.isFree(coordinates[0], coordinates[1])) {
  107. // return false; // This room can only have rooms on north of it
  108. // }
  109. // }
  110. // }
  111. // return true;
  112. // };
  113. //
  114. // RegionRandom.rulebookAfterPlaceRoom.addRule(new Rule({
  115. // name : "After placing the southest room",
  116. // code : runner => {
  117. // let options = <RandomizingRoomOptions> runner.noun;
  118. // let myCoordinates = options.map.getCoordinates(options.room);
  119. // if (myCoordinates != undefined) {
  120. // for (let i = 0; i < Room.DIRECTIONS.length; i++) {
  121. // let direction = Room.DIRECTIONS[i];
  122. // if (direction != Direction.NORTH) {
  123. // let coordinates = Room.shift(myCoordinates, direction);
  124. // options.map.block(coordinates[0], coordinates[1]);
  125. // coordinates = Room.shift(coordinates, direction);
  126. // options.map.block(coordinates[0], coordinates[1]);
  127. // }
  128. // }
  129. // }
  130. // },
  131. // conditions : runner => {
  132. // return runner.noun.room == southestRoom;
  133. // }
  134. // }))
  135. //
  136. // Thing.CarryRelation.setRelation(WorldState.player, mapOfTest);
  137. //
  138. // // Settings.setDebug(false);
  139. // PlayBegins.rulebook.addRule(new Rule({
  140. // name : "randomize region",
  141. // firstPriority : Rule.PRIORITY_HIGHEST,
  142. // code : async runner => {
  143. // //let t0 = performance.now();
  144. // await region.randomize();
  145. // //let t1 = performance.now();
  146. // }
  147. // }));
  148. //
  149. // RegionRandom.rulebookRandomizeRegion.addRule(new Rule({
  150. // name : "Add room A and B to region",
  151. // firstPriority : Rule.PRIORITY_HIGHEST,
  152. // code : async runner => {
  153. // await RegionRandom.rulebookPlaceRoom.execute({
  154. // noun : <RandomizingRoomOptions> {
  155. // map : region.map,
  156. // room : rooma,
  157. // region : region
  158. // }
  159. // }).then();
  160. // await RegionRandom.rulebookPlaceRoom.execute({
  161. // noun : <RandomizingRoomOptions> {
  162. // map : region.map,
  163. // room : roomb,
  164. // region : region
  165. // }
  166. // }).then();
  167. // },
  168. // conditions : runner => {
  169. // return runner.noun == region;
  170. // }
  171. // }));
  172. //
  173. // function getPath (rooma : Room, roomb : Room) {
  174. // console.debug("The best path from " + rooma.getPrintedName() + " to " + roomb.getPrintedName() + " is:");
  175. // let t0, dir, t1;
  176. // t0 = performance.now();
  177. // dir = rooma.bestDirectionTo(roomb);
  178. // t1 = performance.now();
  179. // if (dir != undefined) {
  180. // console.debug(DirectionNames[Direction[dir]]);
  181. // } else {
  182. // console.debug("There is no path.");
  183. // }
  184. // console.debug("Call to doSomething took " + (t1 - t0) + " milliseconds.");
  185. // }
  186. //
  187. // // let t0 = performance.now();
  188. // // for (var i = 0; i < 1; i++) {
  189. // // getPath(rooma, roomj);
  190. // // }
  191. // // window['roome'] = roome;
  192. // // let t1 = performance.now();
  193. // // console.debug("Total: " + (t1 - t0) + " milliseconds.");
  194. //
  195. //
  196. // let wanderRegion = new RegionRandom("OrcableRegion");
  197. // wanderRegion.place(rooma, roomb);
  198. // region.place(wanderRegion);
  199. //
  200. // // Test done with a thousand orcs searching paths and reading rooms. Total time taken: 200ms.
  201. // // 1000 orcs, no wanderers: 130ms
  202. // // 100 orcs, no wanderer: 13ms (so the same amount of time as not having any orcs)
  203. // // 100 orcs, wanderer: 30ms
  204. // // 100 orcs, no shiny picker, wanderer: 30ms
  205. // // 100 orcs, no wanderer, no shiny picker: 13ms
  206. // // 1000 orcs, no wanderer, no shiny picker: 51ms
  207. // /**
  208. // * Conclusion:
  209. // * The test had all orcs placed in the same room, so every time ShinyPicker AI runs, all the orcs were looking at all the other orcs.
  210. // * Game feels "instant" up to 100ms turns, which was reached at 250 orcs with JUST one PIcks Shiny and Wanderer rules.
  211. // * With 100 EMPTY shiny rules, 250 orcs already take up 500ms per turn!
  212. // * If the orcs fail the conditions for wanderer and shiny rules, then there is just a small overhead to having these rules there.
  213. // * 100 Rules failing the conditions allows for 800 orcs below 100ms.
  214. // * 50 orcs with 150 Shiny Rules which go through all the other orcs while they wander towards a region results in a 250ms wait.
  215. // * That's not good since those numbers are similar to what end game should have, however real rules might not be as expensive as Pick Shinies with a room full of orcs..
  216. // * Wait is bearable for 100 orcs with 800 disabled rules, so it should be "fine" to have all rules in the same rulebook.
  217. // * First possible optimization: make AI rules have a static "check" and bake them into each NPC's rulebook so that they don't have to be checked every turn.
  218. // * Second possible optimization: use maximum distance from player to decide which NPCs have their AIs executed (even better: only run AI for the current region).
  219. // * Third optimization: reduce number of rules. Last resort.
  220. // */
  221. // let rooms = region.getRooms();
  222. // let shuffler = new Shuffler(rooms);
  223. // for (let i = 0; i < 0; i++) {
  224. // AI.rules.createAndAddRule({
  225. // name : "Pick Shinies",
  226. // firstPriority : AIRules.PRIORITY_ACTING_ON_PLACE,
  227. // conditions : (runner : RulebookRunner<Person>) => {
  228. // let person = runner.noun;
  229. // return person.AI.picksShinies;
  230. // },
  231. // code : (runner : RulebookRunner<Person>) => {
  232. // let person = runner.noun;
  233. // let room = person.getRoom();
  234. // let visibleThings = room.getContainedAndVisibleTo(person);
  235. //
  236. // if (visibleThings.length > 0) {
  237. // for (let i = 0; i < visibleThings.length; i++) {
  238. // if (!visibleThings[i].fixedInPlace && visibleThings[i].getShiny()) {
  239. // return new ActionTake(person, visibleThings[i]);
  240. // }
  241. // }
  242. // }
  243. // }
  244. // });
  245. // }
  246. // let randomOrc;
  247. // let randomOrc2;
  248. // for (let i = 0; i < 8; i++) {
  249. // let orc = new OrcDebugger();
  250. // randomOrc = orc;
  251. // if (randomOrc2 == undefined) {
  252. // randomOrc2 = orc;
  253. // }
  254. // orc.AI.wanderer = true;
  255. // orc.AI.picksShinies = true;
  256. // orc.AI.wandersOn = wanderRegion;
  257. // let room = new Shuffler(region.getRooms()).getOne();
  258. // room.place(orc);
  259. // }
  260. //
  261. // var fTarget = new ContentGroup();
  262. // fTarget.addUnit(
  263. // new FuckingUnit()
  264. // .setFucked(WorldState.player)
  265. // .setFucker(randomOrc)
  266. // .setHole(WorldState.player.getPart(HumanoidVagina))
  267. // .setStick(randomOrc.getPart(HumanoidPenis))
  268. // );
  269. // fTarget.addUnit(
  270. // new FuckingUnit()
  271. // .setFucked(WorldState.player)
  272. // .setFucker(randomOrc2)
  273. // .setHole(WorldState.player.getPart(HumanoidHead))
  274. // .setStick(randomOrc2.getPart(HumanoidPenis))
  275. // );
  276. //
  277. //
  278. // (new FuckingDescription("Specific Orc in Vagina"))
  279. // .setDescription(new Say("Specific Orc in Vagina."))
  280. // .addUnit()
  281. // .setFucker(randomOrc)
  282. // .setHole(WorldState.player.getPart(HumanoidVagina))
  283. // .setStick(randomOrc.getPart(HumanoidPenis));
  284. //
  285. // (new FuckingDescription("Specific Orc Starts Cumming in Vagina"))
  286. // .setDescription(new Say("Specific Orc Starts Cumming in Vagina"))
  287. // .addUnit()
  288. // .setFucker(randomOrc)
  289. // .setHole(WorldState.player.getPart(HumanoidVagina))
  290. // .addMarker(FuckingState.CUM_START)
  291. // .setStick(randomOrc.getPart(HumanoidPenis));
  292. //
  293. // (new FuckingDescription("Orc in mouth"))
  294. // .setDescription(new Say("Orc in mouth."))
  295. // .addUnit()
  296. // .setFucker(OrcDebugger)
  297. // .setHole(HumanoidHead)
  298. // .setStick(HumanoidPenis);
  299. //
  300. //
  301. // // (new CombatDescription("Poking 2")
  302. // // .setDescription("Oy cheeky kunt stahp that"))
  303. // // .addPokeUnit()
  304. // // .setTarget(Person)
  305. // // .addMarker(CombatPokeResult.ANNOYED);
  306. // //
  307. // // (new CombatDescription("Poking 1")
  308. // // .setDescription("Heh whatever"))
  309. // // .addPokeUnit()
  310. // // .setTarget(Person)
  311. // // .addMarker(CombatPokeResult.NOHEAT);
  312. // //
  313. // // (new CombatDescription("Poking 3")
  314. // // .setDescription("A'IGHT YOU GET FUCKED NOW MATE SWAER ON ME MUM"))
  315. // // .addPokeUnit()
  316. // // .setTarget(Person)
  317. // // .addMarker(CombatPokeResult.AGGROED);
  318. //
  319. // (new CombatDescription("Allranging Fists"))
  320. // .setDescriptionFunction((actor, target, weapons, markers) => {
  321. // let say = new Say(...Say.Mention(actor), " attack", target != WorldState.player ? "s " : " ", ...Say.Mention(target), " with ", ...Say.YourTheir(target) ," fists");
  322. // if (markers.indexOf(CombatHit.MISS) != -1) {
  323. // say.add(", but ", ...Say.Mention(actor), " miss");
  324. // } else if (markers.indexOf(CombatHit.CRITICAL) != -1) {
  325. // say.add(", it is a strong hit");
  326. // }
  327. //
  328. // if (markers.indexOf(CombatResult.KNOCKED) != -1) {
  329. // say.add(", the strength of ", ...Say.YourTheir(target) ," attack knocks ", ...Say.Mention(target) , " on the floor.");
  330. // } else if (markers.indexOf(CombatResult.KNOCKED_OFF) != -1) {
  331. // say.add(", the strength of ", ...Say.YourTheir(target) ," attack knocks ", ...Say.Mention(target), " unconscious.");
  332. // } else if (markers.indexOf(CombatResult.KILLED) != -1) {
  333. // say.add(", ", new SayHeSheIt(target), " dies.");
  334. // } else {
  335. // say.add(".");
  336. // }
  337. //
  338. // return say;
  339. // })
  340. // .addUnit()
  341. // .setActor(Person)
  342. // .setTarget(Person)
  343. // .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatHit.HIT, CombatHit.CRITICAL, CombatHit.MISS))
  344. // .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatResult.KILLED, CombatResult.KNOCKED, CombatResult.KNOCKED_OFF));
  345. //
  346. //
  347. // (new CombatPokeDescription("Hitting Orc"))
  348. // .setDescriptionFunction((aggressor, target, markers) => {
  349. // let say = new Say(new SayBold(target), ": ");
  350. //
  351. // let action = new SayAction();
  352. // action.add("looks at ");
  353. // if (aggressor != WorldState.player) {
  354. // action.add(new SayThe(), aggressor)
  355. // } else {
  356. // action.add("you");
  357. // }
  358. // say.add(action);
  359. //
  360. // if (markers.includes(AIRules.resultHostile)) {
  361. // say.add("Fucking seriously!? I'm going to rip your head off!");
  362. // return say;
  363. // } else if (AIRules.resultRetaliate) {
  364. // say.add("Fucking STOP that!");
  365. // return say;
  366. // }
  367. //
  368. // if (markers.includes(AIRules.actionMin)) {
  369. // say.add(
  370. // new OneOf(OneOf.PURELY_AT_RANDOM,
  371. // "Stop that.",
  372. // "You better stop that.",
  373. // "Look, I'm not very patient. Stop that."
  374. // )
  375. // );
  376. // } else if (markers.includes(AIRules.actionMed)) {
  377. // say.add(
  378. // new OneOf(OneOf.PURELY_AT_RANDOM,
  379. // "Fucking do that again, see what happens.",
  380. // "Watch it!",
  381. // "I'm THIS close to ripping your head off!"
  382. // )
  383. // );
  384. // } else if (markers.includes(AIRules.actionMax)) {
  385. // say.add(
  386. // new OneOf(OneOf.PURELY_AT_RANDOM,
  387. // "Goddamn it.",
  388. // "Watch it!",
  389. // "I'm THIS close to ripping your head off!"
  390. // )
  391. // );
  392. // }
  393. //
  394. // return say;
  395. // })
  396. // .addUnit()
  397. // .setAggressor(Person)
  398. // .setTarget(OrcDebugger)
  399. // .addMarker(AdaptiveDifferential.FULLYADAPTIVE(AIRules.resultRetaliate, AIRules.resultHostile, AIRules.resultNotHostile))
  400. // .addMarker(AdaptiveDifferential.FULLYADAPTIVE(AIRules.actionMin, AIRules.actionMed, AIRules.actionMax));
  401. // (new CombatDescription("test"))
  402. // .setDescriptionFunction((actor, target, weapons, markers) => {
  403. // let say = new Say();
  404. // let verb = "attack";
  405. // if (!WorldState.isPlayer(actor)) {
  406. // verb += "s";
  407. // }
  408. // say.add(Say.Mention(actor), " " + verb + " ", Say.Mention(target), " with ", Say.Possessive(actor), " fists.");
  409. //
  410. // if (markers.includes(CombatHit.MISS)) {
  411. // say.add(" ", Say.Subject(actor), " " + ("miss" + (WorldState.isPlayer(actor) ? "es." : ".")));
  412. // } else if (markers.includes(CombatHit.CRITICAL)) {
  413. // say.add(" It was a very strong hit!");
  414. // }
  415. //
  416. // if (markers.includes(CombatResult.KILLED)) {
  417. // say.add(" ", Say.Mention(target), " was killed by the force of the attack.");
  418. // } else if (markers.includes(CombatResult.KNOCKED_OFF)) {
  419. // say.add(" ", Say.Mention(target), " was incapacitated by the force of the attack.");
  420. // } else if (markers.includes(CombatResult.KNOCKED)) {
  421. // say.add(" ", Say.Mention(target), " was thrown to the ground by the force of the attack.");
  422. // }
  423. //
  424. // return say;
  425. // })
  426. // .addUnit()
  427. // .setActor(Person)
  428. // .setTarget(Person)
  429. // .setWeapon(HumanoidHands)
  430. // .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatHit.MISS, CombatHit.HIT, CombatHit.CRITICAL))
  431. // .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatResult.KNOCKED, CombatResult.KILLED, CombatResult.KNOCKED_OFF))
  432. // ;
  433. // (new CombatDescription("Minotaur Attacks"))
  434. // .setDescriptionFunction((actor, target, weapons, markers) => {
  435. // let say = new Say();
  436. //
  437. // if (markers.includes(CombatHit.MISS) {
  438. // say.add("The minotaur heaves his heavy punches at you, but you narrowly avoid it.");
  439. // } else if (markers.includes(CombatHit.HIT) {
  440. // say.add("The minotaur punches you with ease.");
  441. // } else if (markers.includes(CombatHit.CRITICAL) {
  442. // say.add("The minotaur punches you in the gut. Ouch, you felt that HARD.");
  443. // }
  444. //
  445. // say.add(" ");
  446. //
  447. // if (markers.includes(CombatResult.KILLED) {
  448. // say.add("YOU ARE DEAD.");
  449. // } else if (markers.includes(CombatResult.KNOCKED_OFF) {
  450. // say.add("You lose consciousness.");
  451. // } else if (markers.includes(CombatResult.KNOCKED) {
  452. // say.add("You are knocked to the ground!");
  453. // }
  454. //
  455. // return say;
  456. // })
  457. // .addUnit()
  458. // .setActor(MinotaurGuard)
  459. // .setTarget(WorldState.player)
  460. // .setWeapon(Thing)
  461. // .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatHit.MISS, CombatHit.HIT, CombatHit.CRITICAL))
  462. // .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatResult.KNOCKED, CombatResult.KILLED, CombatResult.KNOCKED_OFF))
  463. // ;