|
@@ -1,406 +1,466 @@
|
|
|
-var rooma = new RoomRandom("Room A");
|
|
|
-rooma.description = new Say(
|
|
|
- "You are inside a box of metal painted blue. Your head almost touches the ceiling, making the room look smaller than it really is.",
|
|
|
- Say.LINE_BREAK,
|
|
|
- new SayIf(
|
|
|
- () => {
|
|
|
- return Thing.InsideRoomRelation.getLeft(vase) == rooma || Thing.InsideRoomRelation.getLeft(urn) == rooma;
|
|
|
- },
|
|
|
- " Still, there are some things thrown about."
|
|
|
- )
|
|
|
-);
|
|
|
-
|
|
|
-PlayBegins.setStartingRoom(rooma);
|
|
|
-
|
|
|
-let paddedBra = new Clothing({name : "Padded Bra", unique : true});
|
|
|
-paddedBra.breastPadding = 3;
|
|
|
-paddedBra.slots = [Humanoid.SLOT_BREASTS];
|
|
|
-
|
|
|
-let paddedUnderwear = new Clothing({name : "Padded Underwear", unique : true});
|
|
|
-paddedUnderwear.crotchPadding = 15;
|
|
|
-paddedUnderwear.slots = [Humanoid.SLOT_CROTCH_BACK, Humanoid.SLOT_CROTCH_FRONT];
|
|
|
-
|
|
|
-// Thing.WearRelation.setRelation(WorldState.player, paddedBra);
|
|
|
-// Thing.WearRelation.setRelation(WorldState.player, paddedUnderwear);
|
|
|
-
|
|
|
-let player = WorldState.player;
|
|
|
-WorldState.player = player;
|
|
|
-var vase = new Thing({name : "Vase"});
|
|
|
-vase.description = new Say("This is an ornamental vase that'd look very nice on your lap. Why? Who knows.");
|
|
|
-rooma.place(vase);
|
|
|
-
|
|
|
-let mapOfTest = new MapNote({name: "Map of this Region",
|
|
|
-description : "This is a simple map showing all the rooms here.", unique : true});
|
|
|
-rooma.place(mapOfTest);
|
|
|
-
|
|
|
-let urn = new Thing({unique: true, name : "Urn of Dreams", image : "image001"});
|
|
|
-urn.description = new Say("This appears to be a simple, black urn containing the ashes of your dreams.");
|
|
|
-rooma.place(urn);
|
|
|
-
|
|
|
-var roomb = new RoomRandom("Room B");
|
|
|
-
|
|
|
-roomb.place(vase);
|
|
|
-
|
|
|
-
|
|
|
-let frillyPouch = new CoinPouch({
|
|
|
- name : "Frilly Pouch",
|
|
|
- //image : new SayImage("image001"),
|
|
|
- description : new Say("This is a very gay little pink pouch full of little hearts.")
|
|
|
-});
|
|
|
-frillyPouch.addCoins(502);
|
|
|
-rooma.place(frillyPouch);
|
|
|
-
|
|
|
-// ActionTake.check.addRule(new Rule(<RuleOptions<any>> {
|
|
|
-// code : function () {
|
|
|
-// let promise = new Promise(() => {});
|
|
|
-// return promise;
|
|
|
+// var rooma = new RoomRandom("Room A");
|
|
|
+// rooma.description = new Say(
|
|
|
+// "You are inside a box of metal painted blue. Your head almost touches the ceiling, making the room look smaller than it really is.",
|
|
|
+// Say.LINE_BREAK,
|
|
|
+// new SayIf(
|
|
|
+// () => {
|
|
|
+// return Thing.InsideRoomRelation.getLeft(vase) == rooma || Thing.InsideRoomRelation.getLeft(urn) == rooma;
|
|
|
+// },
|
|
|
+// " Still, there are some things thrown about."
|
|
|
+// )
|
|
|
+// );
|
|
|
+//
|
|
|
+// PlayBegins.setStartingRoom(rooma);
|
|
|
+//
|
|
|
+//
|
|
|
+// let paddedBra = new Clothing({name : "Padded Bra", unique : true});
|
|
|
+// paddedBra.breastPadding = 3;
|
|
|
+// paddedBra.slots = [Humanoid.SLOT_BREASTS];
|
|
|
+//
|
|
|
+// let paddedUnderwear = new Clothing({name : "Padded Underwear", unique : true});
|
|
|
+// paddedUnderwear.crotchPadding = 15;
|
|
|
+// paddedUnderwear.slots = [Humanoid.SLOT_CROTCH_BACK, Humanoid.SLOT_CROTCH_FRONT];
|
|
|
+//
|
|
|
+// // Thing.WearRelation.setRelation(WorldState.player, paddedBra);
|
|
|
+// // Thing.WearRelation.setRelation(WorldState.player, paddedUnderwear);
|
|
|
+//
|
|
|
+// let player = WorldState.player;
|
|
|
+// WorldState.player = player;
|
|
|
+// var vase = new Thing({name : "Vase"});
|
|
|
+// vase.description = new Say("This is an ornamental vase that'd look very nice on your lap. Why? Who knows.");
|
|
|
+// rooma.place(vase);
|
|
|
+//
|
|
|
+// let mapOfTest = new MapNote({name: "Map of this Region",
|
|
|
+// description : "This is a simple map showing all the rooms here.", unique : true});
|
|
|
+// rooma.place(mapOfTest);
|
|
|
+//
|
|
|
+// let urn = new Thing({unique: true, name : "Urn of Dreams", image : "image001"});
|
|
|
+// urn.description = new Say("This appears to be a simple, black urn containing the ashes of your dreams.");
|
|
|
+// rooma.place(urn);
|
|
|
+//
|
|
|
+// var roomb = new RoomRandom("Room B");
|
|
|
+// let gates = new Door("Gates of Orkindom", OrcVillage.SouthEntrance, true);
|
|
|
+// rooma.place(gates);
|
|
|
+//
|
|
|
+// roomb.place(vase);
|
|
|
+//
|
|
|
+//
|
|
|
+//
|
|
|
+// let frillyPouch = new CoinPouch({
|
|
|
+// name : "Frilly Pouch",
|
|
|
+// //image : new SayImage("image001"),
|
|
|
+// description : new Say("This is a very gay little pink pouch full of little hearts.")
|
|
|
+// });
|
|
|
+// frillyPouch.addCoins(502);
|
|
|
+// rooma.place(frillyPouch);
|
|
|
+//
|
|
|
+// // ActionTake.check.addRule(new Rule(<RuleOptions<any>> {
|
|
|
+// // code : function () {
|
|
|
+// // let promise = new Promise(() => {});
|
|
|
+// // return promise;
|
|
|
+// // }
|
|
|
+// // }));
|
|
|
+//
|
|
|
+// let bigSack = new CoinPouch({name : "Big Sack"});
|
|
|
+// bigSack.addCoins(100);
|
|
|
+// rooma.place(bigSack);
|
|
|
+//
|
|
|
+// let region = new RegionRandom("Test Region");
|
|
|
+//
|
|
|
+//
|
|
|
+// region.place(rooma, roomb);
|
|
|
+// for (let i = 1; i < 6; i++) {
|
|
|
+// let room = new RoomRandom("Room " + i.toString());
|
|
|
+// // let randomDirection = new Shuffler([Room.NORTH, Room.SOUTH, Room.EAST, Room.WEST])
|
|
|
+// // room.connectableOn = [randomDirection.getOne()];
|
|
|
+// //room.connectableOn = [Room.NORTH, Room.SOUTH, Room.EAST, Room.WEST];
|
|
|
+// region.place(room);
|
|
|
+//
|
|
|
+// if (Math.random() > 0.5) {
|
|
|
+// //mapOfTest.addRoom(room);
|
|
|
+// }
|
|
|
+//
|
|
|
+// }
|
|
|
+//
|
|
|
+// mapOfTest.addRegion(region);
|
|
|
+//
|
|
|
+// let southestRoom = new RoomRandom("Southest Room");
|
|
|
+// //southestRoom.appearChance = 0;
|
|
|
+//
|
|
|
+// region.place(southestRoom);
|
|
|
+//
|
|
|
+// //southestRoom.connectableOn = [Room.NORTH];
|
|
|
+// southestRoom.appearChance = 100;
|
|
|
+// southestRoom.backgroundImage = "bloo";
|
|
|
+//
|
|
|
+// southestRoom.trickyCode = (options : TrickyOptions) => {
|
|
|
+// let myCoordinates = [options.x, options.y];
|
|
|
+// for (let i = 0; i < Room.DIRECTIONS.length; i++) {
|
|
|
+// let direction = Room.DIRECTIONS[i];
|
|
|
+// if (direction != Direction.NORTH) {
|
|
|
+// let coordinates = Room.shift(myCoordinates, direction);
|
|
|
+// if (!options.map.isFree(coordinates[0], coordinates[1])) {
|
|
|
+// return false; // This room can only have rooms on north of it
|
|
|
+// }
|
|
|
+// coordinates = Room.shift(coordinates, direction);
|
|
|
+// if (!options.map.isFree(coordinates[0], coordinates[1])) {
|
|
|
+// return false; // This room can only have rooms on north of it
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// return true;
|
|
|
+// };
|
|
|
+//
|
|
|
+// RegionRandom.rulebookAfterPlaceRoom.addRule(new Rule({
|
|
|
+// name : "After placing the southest room",
|
|
|
+// code : runner => {
|
|
|
+// let options = <RandomizingRoomOptions> runner.noun;
|
|
|
+// let myCoordinates = options.map.getCoordinates(options.room);
|
|
|
+// if (myCoordinates != undefined) {
|
|
|
+// for (let i = 0; i < Room.DIRECTIONS.length; i++) {
|
|
|
+// let direction = Room.DIRECTIONS[i];
|
|
|
+// if (direction != Direction.NORTH) {
|
|
|
+// let coordinates = Room.shift(myCoordinates, direction);
|
|
|
+// options.map.block(coordinates[0], coordinates[1]);
|
|
|
+// coordinates = Room.shift(coordinates, direction);
|
|
|
+// options.map.block(coordinates[0], coordinates[1]);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// },
|
|
|
+// conditions : runner => {
|
|
|
+// return runner.noun.room == southestRoom;
|
|
|
+// }
|
|
|
+// }))
|
|
|
+//
|
|
|
+// Thing.CarryRelation.setRelation(WorldState.player, mapOfTest);
|
|
|
+//
|
|
|
+// // Settings.setDebug(false);
|
|
|
+// PlayBegins.rulebook.addRule(new Rule({
|
|
|
+// name : "randomize region",
|
|
|
+// firstPriority : Rule.PRIORITY_HIGHEST,
|
|
|
+// code : async runner => {
|
|
|
+// //let t0 = performance.now();
|
|
|
+// await region.randomize();
|
|
|
+// //let t1 = performance.now();
|
|
|
// }
|
|
|
// }));
|
|
|
-
|
|
|
-let bigSack = new CoinPouch({name : "Big Sack"});
|
|
|
-bigSack.addCoins(100);
|
|
|
-rooma.place(bigSack);
|
|
|
-
|
|
|
-let region = new RegionRandom("Test Region");
|
|
|
-
|
|
|
-
|
|
|
-region.place(rooma, roomb);
|
|
|
-for (let i = 1; i < 6; i++) {
|
|
|
- let room = new RoomRandom("Room " + i.toString());
|
|
|
- // let randomDirection = new Shuffler([Room.NORTH, Room.SOUTH, Room.EAST, Room.WEST])
|
|
|
- // room.connectableOn = [randomDirection.getOne()];
|
|
|
- //room.connectableOn = [Room.NORTH, Room.SOUTH, Room.EAST, Room.WEST];
|
|
|
- region.place(room);
|
|
|
-
|
|
|
- if (Math.random() > 0.5) {
|
|
|
- //mapOfTest.addRoom(room);
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-mapOfTest.addRegion(region);
|
|
|
-
|
|
|
-let southestRoom = new RoomRandom("Southest Room");
|
|
|
-//southestRoom.appearChance = 0;
|
|
|
-
|
|
|
-region.place(southestRoom);
|
|
|
-
|
|
|
-//southestRoom.connectableOn = [Room.NORTH];
|
|
|
-southestRoom.appearChance = 100;
|
|
|
-southestRoom.backgroundImage = "bloo";
|
|
|
-
|
|
|
-southestRoom.trickyCode = (options : TrickyOptions) => {
|
|
|
- let myCoordinates = [options.x, options.y];
|
|
|
- for (let i = 0; i < Room.DIRECTIONS.length; i++) {
|
|
|
- let direction = Room.DIRECTIONS[i];
|
|
|
- if (direction != Direction.NORTH) {
|
|
|
- let coordinates = Room.shift(myCoordinates, direction);
|
|
|
- if (!options.map.isFree(coordinates[0], coordinates[1])) {
|
|
|
- return false; // This room can only have rooms on north of it
|
|
|
- }
|
|
|
- coordinates = Room.shift(coordinates, direction);
|
|
|
- if (!options.map.isFree(coordinates[0], coordinates[1])) {
|
|
|
- return false; // This room can only have rooms on north of it
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return true;
|
|
|
-};
|
|
|
-
|
|
|
-RegionRandom.rulebookAfterPlaceRoom.addRule(new Rule({
|
|
|
- name : "After placing the southest room",
|
|
|
- code : runner => {
|
|
|
- let options = <RandomizingRoomOptions> runner.noun;
|
|
|
- let myCoordinates = options.map.getCoordinates(options.room);
|
|
|
- if (myCoordinates != undefined) {
|
|
|
- for (let i = 0; i < Room.DIRECTIONS.length; i++) {
|
|
|
- let direction = Room.DIRECTIONS[i];
|
|
|
- if (direction != Direction.NORTH) {
|
|
|
- let coordinates = Room.shift(myCoordinates, direction);
|
|
|
- options.map.block(coordinates[0], coordinates[1]);
|
|
|
- coordinates = Room.shift(coordinates, direction);
|
|
|
- options.map.block(coordinates[0], coordinates[1]);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- conditions : runner => {
|
|
|
- return runner.noun.room == southestRoom;
|
|
|
- }
|
|
|
-}))
|
|
|
-
|
|
|
-Thing.CarryRelation.setRelation(WorldState.player, mapOfTest);
|
|
|
-
|
|
|
-// Settings.setDebug(false);
|
|
|
-PlayBegins.rulebook.addRule(new Rule({
|
|
|
- name : "randomize region",
|
|
|
- firstPriority : Rule.PRIORITY_HIGHEST,
|
|
|
- code : async runner => {
|
|
|
- //let t0 = performance.now();
|
|
|
- await region.randomize();
|
|
|
- //let t1 = performance.now();
|
|
|
- }
|
|
|
-}));
|
|
|
-
|
|
|
-RegionRandom.rulebookRandomizeRegion.addRule(new Rule({
|
|
|
- name : "Add room A and B to region",
|
|
|
- firstPriority : Rule.PRIORITY_HIGHEST,
|
|
|
- code : async runner => {
|
|
|
- await RegionRandom.rulebookPlaceRoom.execute({
|
|
|
- noun : <RandomizingRoomOptions> {
|
|
|
- map : region.map,
|
|
|
- room : rooma,
|
|
|
- region : region
|
|
|
- }
|
|
|
- }).then();
|
|
|
- await RegionRandom.rulebookPlaceRoom.execute({
|
|
|
- noun : <RandomizingRoomOptions> {
|
|
|
- map : region.map,
|
|
|
- room : roomb,
|
|
|
- region : region
|
|
|
- }
|
|
|
- }).then();
|
|
|
- },
|
|
|
- conditions : runner => {
|
|
|
- return runner.noun == region;
|
|
|
- }
|
|
|
-}));
|
|
|
-
|
|
|
-function getPath (rooma : Room, roomb : Room) {
|
|
|
- console.debug("The best path from " + rooma.getPrintedName() + " to " + roomb.getPrintedName() + " is:");
|
|
|
- let t0, dir, t1;
|
|
|
- t0 = performance.now();
|
|
|
- dir = rooma.bestDirectionTo(roomb);
|
|
|
- t1 = performance.now();
|
|
|
- if (dir != undefined) {
|
|
|
- console.debug(DirectionNames[Direction[dir]]);
|
|
|
- } else {
|
|
|
- console.debug("There is no path.");
|
|
|
- }
|
|
|
- console.debug("Call to doSomething took " + (t1 - t0) + " milliseconds.");
|
|
|
-}
|
|
|
-
|
|
|
-// let t0 = performance.now();
|
|
|
-// for (var i = 0; i < 1; i++) {
|
|
|
-// getPath(rooma, roomj);
|
|
|
+//
|
|
|
+// RegionRandom.rulebookRandomizeRegion.addRule(new Rule({
|
|
|
+// name : "Add room A and B to region",
|
|
|
+// firstPriority : Rule.PRIORITY_HIGHEST,
|
|
|
+// code : async runner => {
|
|
|
+// await RegionRandom.rulebookPlaceRoom.execute({
|
|
|
+// noun : <RandomizingRoomOptions> {
|
|
|
+// map : region.map,
|
|
|
+// room : rooma,
|
|
|
+// region : region
|
|
|
+// }
|
|
|
+// }).then();
|
|
|
+// await RegionRandom.rulebookPlaceRoom.execute({
|
|
|
+// noun : <RandomizingRoomOptions> {
|
|
|
+// map : region.map,
|
|
|
+// room : roomb,
|
|
|
+// region : region
|
|
|
+// }
|
|
|
+// }).then();
|
|
|
+// },
|
|
|
+// conditions : runner => {
|
|
|
+// return runner.noun == region;
|
|
|
+// }
|
|
|
+// }));
|
|
|
+//
|
|
|
+// function getPath (rooma : Room, roomb : Room) {
|
|
|
+// console.debug("The best path from " + rooma.getPrintedName() + " to " + roomb.getPrintedName() + " is:");
|
|
|
+// let t0, dir, t1;
|
|
|
+// t0 = performance.now();
|
|
|
+// dir = rooma.bestDirectionTo(roomb);
|
|
|
+// t1 = performance.now();
|
|
|
+// if (dir != undefined) {
|
|
|
+// console.debug(DirectionNames[Direction[dir]]);
|
|
|
+// } else {
|
|
|
+// console.debug("There is no path.");
|
|
|
+// }
|
|
|
+// console.debug("Call to doSomething took " + (t1 - t0) + " milliseconds.");
|
|
|
// }
|
|
|
-// window['roome'] = roome;
|
|
|
-// let t1 = performance.now();
|
|
|
-// console.debug("Total: " + (t1 - t0) + " milliseconds.");
|
|
|
-
|
|
|
-
|
|
|
-let wanderRegion = new RegionRandom("OrcableRegion");
|
|
|
-wanderRegion.place(rooma, roomb);
|
|
|
-region.place(wanderRegion);
|
|
|
-
|
|
|
-// Test done with a thousand orcs searching paths and reading rooms. Total time taken: 200ms.
|
|
|
-// 1000 orcs, no wanderers: 130ms
|
|
|
-// 100 orcs, no wanderer: 13ms (so the same amount of time as not having any orcs)
|
|
|
-// 100 orcs, wanderer: 30ms
|
|
|
-// 100 orcs, no shiny picker, wanderer: 30ms
|
|
|
-// 100 orcs, no wanderer, no shiny picker: 13ms
|
|
|
-// 1000 orcs, no wanderer, no shiny picker: 51ms
|
|
|
-/**
|
|
|
- * Conclusion:
|
|
|
- * 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.
|
|
|
- * Game feels "instant" up to 100ms turns, which was reached at 250 orcs with JUST one PIcks Shiny and Wanderer rules.
|
|
|
- * With 100 EMPTY shiny rules, 250 orcs already take up 500ms per turn!
|
|
|
- * If the orcs fail the conditions for wanderer and shiny rules, then there is just a small overhead to having these rules there.
|
|
|
- * 100 Rules failing the conditions allows for 800 orcs below 100ms.
|
|
|
- * 50 orcs with 150 Shiny Rules which go through all the other orcs while they wander towards a region results in a 250ms wait.
|
|
|
- * 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..
|
|
|
- * Wait is bearable for 100 orcs with 800 disabled rules, so it should be "fine" to have all rules in the same rulebook.
|
|
|
- * 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.
|
|
|
- * 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).
|
|
|
- * Third optimization: reduce number of rules. Last resort.
|
|
|
- */
|
|
|
-let rooms = region.getRooms();
|
|
|
-let shuffler = new Shuffler(rooms);
|
|
|
-for (let i = 0; i < 0; i++) {
|
|
|
- AI.rules.createAndAddRule({
|
|
|
- name : "Pick Shinies",
|
|
|
- firstPriority : AIRules.PRIORITY_ACTING_ON_PLACE,
|
|
|
- conditions : (runner : RulebookRunner<Person>) => {
|
|
|
- let person = runner.noun;
|
|
|
- return person.AI.picksShinies;
|
|
|
- },
|
|
|
- code : (runner : RulebookRunner<Person>) => {
|
|
|
- let person = runner.noun;
|
|
|
- let room = person.getRoom();
|
|
|
- let visibleThings = room.getContainedAndVisibleTo(person);
|
|
|
-
|
|
|
- if (visibleThings.length > 0) {
|
|
|
- for (let i = 0; i < visibleThings.length; i++) {
|
|
|
- if (!visibleThings[i].fixedInPlace && visibleThings[i].getShiny()) {
|
|
|
- return new ActionTake(person, visibleThings[i]);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-}
|
|
|
-let randomOrc;
|
|
|
-let randomOrc2;
|
|
|
-for (let i = 0; i < 8; i++) {
|
|
|
- let orc = new OrcDebugger();
|
|
|
- randomOrc = orc;
|
|
|
- if (randomOrc2 == undefined) {
|
|
|
- randomOrc2 = orc;
|
|
|
- }
|
|
|
- orc.AI.wanderer = true;
|
|
|
- orc.AI.picksShinies = true;
|
|
|
- orc.AI.wandersOn = wanderRegion;
|
|
|
- let room = new Shuffler(region.getRooms()).getOne();
|
|
|
- room.place(orc);
|
|
|
-}
|
|
|
-
|
|
|
-var fTarget = new ContentGroup();
|
|
|
-fTarget.addUnit(
|
|
|
- new FuckingUnit()
|
|
|
- .setFucked(WorldState.player)
|
|
|
- .setFucker(randomOrc)
|
|
|
- .setHole(WorldState.player.getPart(HumanoidVagina))
|
|
|
- .setStick(randomOrc.getPart(HumanoidPenis))
|
|
|
-);
|
|
|
-fTarget.addUnit(
|
|
|
- new FuckingUnit()
|
|
|
- .setFucked(WorldState.player)
|
|
|
- .setFucker(randomOrc2)
|
|
|
- .setHole(WorldState.player.getPart(HumanoidHead))
|
|
|
- .setStick(randomOrc2.getPart(HumanoidPenis))
|
|
|
-);
|
|
|
-
|
|
|
-let spitroast = (new FuckingDescription("Orc spitroast!"));
|
|
|
-spitroast.setDescription(new Say("Orc Spitroast!"))
|
|
|
- .addUnit()
|
|
|
- .setFucker(OrcDebugger)
|
|
|
- .setHole(HumanoidVagina)
|
|
|
- .setStick(HumanoidPenis);
|
|
|
-spitroast.addUnit()
|
|
|
- .setFucker(OrcDebugger)
|
|
|
- .setHole(HumanoidHead)
|
|
|
- .setStick(HumanoidPenis);
|
|
|
-
|
|
|
-(new FuckingDescription("Specific Orc in Vagina"))
|
|
|
- .setDescription(new Say("Specific Orc in Vagina."))
|
|
|
- .addUnit()
|
|
|
- .setFucker(randomOrc)
|
|
|
- .setHole(WorldState.player.getPart(HumanoidVagina))
|
|
|
- .setStick(randomOrc.getPart(HumanoidPenis));
|
|
|
-
|
|
|
-(new FuckingDescription("Specific Orc Starts Cumming in Vagina"))
|
|
|
- .setDescription(new Say("Specific Orc Starts Cumming in Vagina"))
|
|
|
- .addUnit()
|
|
|
- .setFucker(randomOrc)
|
|
|
- .setHole(WorldState.player.getPart(HumanoidVagina))
|
|
|
- .addMarker(FuckingState.CUM_START)
|
|
|
- .setStick(randomOrc.getPart(HumanoidPenis));
|
|
|
-
|
|
|
-(new FuckingDescription("Orc in mouth"))
|
|
|
- .setDescription(new Say("Orc in mouth."))
|
|
|
- .addUnit()
|
|
|
- .setFucker(OrcDebugger)
|
|
|
- .setHole(HumanoidHead)
|
|
|
- .setStick(HumanoidPenis);
|
|
|
-
|
|
|
+//
|
|
|
+// // let t0 = performance.now();
|
|
|
+// // for (var i = 0; i < 1; i++) {
|
|
|
+// // getPath(rooma, roomj);
|
|
|
+// // }
|
|
|
+// // window['roome'] = roome;
|
|
|
+// // let t1 = performance.now();
|
|
|
+// // console.debug("Total: " + (t1 - t0) + " milliseconds.");
|
|
|
+//
|
|
|
+//
|
|
|
+// let wanderRegion = new RegionRandom("OrcableRegion");
|
|
|
+// wanderRegion.place(rooma, roomb);
|
|
|
+// region.place(wanderRegion);
|
|
|
+//
|
|
|
+// // Test done with a thousand orcs searching paths and reading rooms. Total time taken: 200ms.
|
|
|
+// // 1000 orcs, no wanderers: 130ms
|
|
|
+// // 100 orcs, no wanderer: 13ms (so the same amount of time as not having any orcs)
|
|
|
+// // 100 orcs, wanderer: 30ms
|
|
|
+// // 100 orcs, no shiny picker, wanderer: 30ms
|
|
|
+// // 100 orcs, no wanderer, no shiny picker: 13ms
|
|
|
+// // 1000 orcs, no wanderer, no shiny picker: 51ms
|
|
|
+// /**
|
|
|
+// * Conclusion:
|
|
|
+// * 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.
|
|
|
+// * Game feels "instant" up to 100ms turns, which was reached at 250 orcs with JUST one PIcks Shiny and Wanderer rules.
|
|
|
+// * With 100 EMPTY shiny rules, 250 orcs already take up 500ms per turn!
|
|
|
+// * If the orcs fail the conditions for wanderer and shiny rules, then there is just a small overhead to having these rules there.
|
|
|
+// * 100 Rules failing the conditions allows for 800 orcs below 100ms.
|
|
|
+// * 50 orcs with 150 Shiny Rules which go through all the other orcs while they wander towards a region results in a 250ms wait.
|
|
|
+// * 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..
|
|
|
+// * Wait is bearable for 100 orcs with 800 disabled rules, so it should be "fine" to have all rules in the same rulebook.
|
|
|
+// * 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.
|
|
|
+// * 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).
|
|
|
+// * Third optimization: reduce number of rules. Last resort.
|
|
|
+// */
|
|
|
+// let rooms = region.getRooms();
|
|
|
+// let shuffler = new Shuffler(rooms);
|
|
|
+// for (let i = 0; i < 0; i++) {
|
|
|
+// AI.rules.createAndAddRule({
|
|
|
+// name : "Pick Shinies",
|
|
|
+// firstPriority : AIRules.PRIORITY_ACTING_ON_PLACE,
|
|
|
+// conditions : (runner : RulebookRunner<Person>) => {
|
|
|
+// let person = runner.noun;
|
|
|
+// return person.AI.picksShinies;
|
|
|
+// },
|
|
|
+// code : (runner : RulebookRunner<Person>) => {
|
|
|
+// let person = runner.noun;
|
|
|
+// let room = person.getRoom();
|
|
|
+// let visibleThings = room.getContainedAndVisibleTo(person);
|
|
|
+//
|
|
|
+// if (visibleThings.length > 0) {
|
|
|
+// for (let i = 0; i < visibleThings.length; i++) {
|
|
|
+// if (!visibleThings[i].fixedInPlace && visibleThings[i].getShiny()) {
|
|
|
+// return new ActionTake(person, visibleThings[i]);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// });
|
|
|
+// }
|
|
|
+// let randomOrc;
|
|
|
+// let randomOrc2;
|
|
|
+// for (let i = 0; i < 8; i++) {
|
|
|
+// let orc = new OrcDebugger();
|
|
|
+// randomOrc = orc;
|
|
|
+// if (randomOrc2 == undefined) {
|
|
|
+// randomOrc2 = orc;
|
|
|
+// }
|
|
|
+// orc.AI.wanderer = true;
|
|
|
+// orc.AI.picksShinies = true;
|
|
|
+// orc.AI.wandersOn = wanderRegion;
|
|
|
+// let room = new Shuffler(region.getRooms()).getOne();
|
|
|
+// room.place(orc);
|
|
|
+// }
|
|
|
+//
|
|
|
+// var fTarget = new ContentGroup();
|
|
|
+// fTarget.addUnit(
|
|
|
+// new FuckingUnit()
|
|
|
+// .setFucked(WorldState.player)
|
|
|
+// .setFucker(randomOrc)
|
|
|
+// .setHole(WorldState.player.getPart(HumanoidVagina))
|
|
|
+// .setStick(randomOrc.getPart(HumanoidPenis))
|
|
|
+// );
|
|
|
+// fTarget.addUnit(
|
|
|
+// new FuckingUnit()
|
|
|
+// .setFucked(WorldState.player)
|
|
|
+// .setFucker(randomOrc2)
|
|
|
+// .setHole(WorldState.player.getPart(HumanoidHead))
|
|
|
+// .setStick(randomOrc2.getPart(HumanoidPenis))
|
|
|
+// );
|
|
|
+//
|
|
|
|
|
|
-// (new CombatDescription("Poking 2")
|
|
|
-// .setDescription("Oy cheeky kunt stahp that"))
|
|
|
-// .addPokeUnit()
|
|
|
-// .setTarget(Person)
|
|
|
-// .addMarker(CombatPokeResult.ANNOYED);
|
|
|
//
|
|
|
-// (new CombatDescription("Poking 1")
|
|
|
-// .setDescription("Heh whatever"))
|
|
|
-// .addPokeUnit()
|
|
|
-// .setTarget(Person)
|
|
|
-// .addMarker(CombatPokeResult.NOHEAT);
|
|
|
+// (new FuckingDescription("Specific Orc in Vagina"))
|
|
|
+// .setDescription(new Say("Specific Orc in Vagina."))
|
|
|
+// .addUnit()
|
|
|
+// .setFucker(randomOrc)
|
|
|
+// .setHole(WorldState.player.getPart(HumanoidVagina))
|
|
|
+// .setStick(randomOrc.getPart(HumanoidPenis));
|
|
|
+//
|
|
|
+// (new FuckingDescription("Specific Orc Starts Cumming in Vagina"))
|
|
|
+// .setDescription(new Say("Specific Orc Starts Cumming in Vagina"))
|
|
|
+// .addUnit()
|
|
|
+// .setFucker(randomOrc)
|
|
|
+// .setHole(WorldState.player.getPart(HumanoidVagina))
|
|
|
+// .addMarker(FuckingState.CUM_START)
|
|
|
+// .setStick(randomOrc.getPart(HumanoidPenis));
|
|
|
+//
|
|
|
+// (new FuckingDescription("Orc in mouth"))
|
|
|
+// .setDescription(new Say("Orc in mouth."))
|
|
|
+// .addUnit()
|
|
|
+// .setFucker(OrcDebugger)
|
|
|
+// .setHole(HumanoidHead)
|
|
|
+// .setStick(HumanoidPenis);
|
|
|
+//
|
|
|
//
|
|
|
-// (new CombatDescription("Poking 3")
|
|
|
-// .setDescription("A'IGHT YOU GET FUCKED NOW MATE SWAER ON ME MUM"))
|
|
|
-// .addPokeUnit()
|
|
|
+// // (new CombatDescription("Poking 2")
|
|
|
+// // .setDescription("Oy cheeky kunt stahp that"))
|
|
|
+// // .addPokeUnit()
|
|
|
+// // .setTarget(Person)
|
|
|
+// // .addMarker(CombatPokeResult.ANNOYED);
|
|
|
+// //
|
|
|
+// // (new CombatDescription("Poking 1")
|
|
|
+// // .setDescription("Heh whatever"))
|
|
|
+// // .addPokeUnit()
|
|
|
+// // .setTarget(Person)
|
|
|
+// // .addMarker(CombatPokeResult.NOHEAT);
|
|
|
+// //
|
|
|
+// // (new CombatDescription("Poking 3")
|
|
|
+// // .setDescription("A'IGHT YOU GET FUCKED NOW MATE SWAER ON ME MUM"))
|
|
|
+// // .addPokeUnit()
|
|
|
+// // .setTarget(Person)
|
|
|
+// // .addMarker(CombatPokeResult.AGGROED);
|
|
|
+//
|
|
|
+// (new CombatDescription("Allranging Fists"))
|
|
|
+// .setDescriptionFunction((actor, target, weapons, markers) => {
|
|
|
+// let say = new Say(...Say.Mention(actor), " attack", target != WorldState.player ? "s " : " ", ...Say.Mention(target), " with ", ...Say.YourTheir(target) ," fists");
|
|
|
+// if (markers.indexOf(CombatHit.MISS) != -1) {
|
|
|
+// say.add(", but ", ...Say.Mention(actor), " miss");
|
|
|
+// } else if (markers.indexOf(CombatHit.CRITICAL) != -1) {
|
|
|
+// say.add(", it is a strong hit");
|
|
|
+// }
|
|
|
+//
|
|
|
+// if (markers.indexOf(CombatResult.KNOCKED) != -1) {
|
|
|
+// say.add(", the strength of ", ...Say.YourTheir(target) ," attack knocks ", ...Say.Mention(target) , " on the floor.");
|
|
|
+// } else if (markers.indexOf(CombatResult.KNOCKED_OFF) != -1) {
|
|
|
+// say.add(", the strength of ", ...Say.YourTheir(target) ," attack knocks ", ...Say.Mention(target), " unconscious.");
|
|
|
+// } else if (markers.indexOf(CombatResult.KILLED) != -1) {
|
|
|
+// say.add(", ", new SayHeSheIt(target), " dies.");
|
|
|
+// } else {
|
|
|
+// say.add(".");
|
|
|
+// }
|
|
|
+//
|
|
|
+// return say;
|
|
|
+// })
|
|
|
+// .addUnit()
|
|
|
+// .setActor(Person)
|
|
|
// .setTarget(Person)
|
|
|
-// .addMarker(CombatPokeResult.AGGROED);
|
|
|
-
|
|
|
-(new CombatDescription("Allranging Fists"))
|
|
|
- .setDescriptionFunction((actor, target, weapons, markers) => {
|
|
|
- let say = new Say(...Say.Mention(actor), " attack", target != WorldState.player ? "s " : " ", ...Say.Mention(target), " with ", ...Say.YourTheir(target) ," fists");
|
|
|
- if (markers.indexOf(CombatHit.MISS) != -1) {
|
|
|
- say.add(", but ", ...Say.Mention(actor), " miss");
|
|
|
- } else if (markers.indexOf(CombatHit.CRITICAL) != -1) {
|
|
|
- say.add(", it is a strong hit");
|
|
|
- }
|
|
|
-
|
|
|
- if (markers.indexOf(CombatResult.KNOCKED) != -1) {
|
|
|
- say.add(", the strength of ", ...Say.YourTheir(target) ," attack knocks ", ...Say.Mention(target) , " on the floor.");
|
|
|
- } else if (markers.indexOf(CombatResult.KNOCKED_OFF) != -1) {
|
|
|
- say.add(", the strength of ", ...Say.YourTheir(target) ," attack knocks ", ...Say.Mention(target), " unconscious.");
|
|
|
- } else if (markers.indexOf(CombatResult.KILLED) != -1) {
|
|
|
- say.add(", ", new SayHeSheIt(target), " dies.");
|
|
|
- } else {
|
|
|
- say.add(".");
|
|
|
- }
|
|
|
-
|
|
|
- return say;
|
|
|
- })
|
|
|
- .addUnit()
|
|
|
- .setActor(Person)
|
|
|
- .setTarget(Person)
|
|
|
- .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatHit.HIT, CombatHit.CRITICAL, CombatHit.MISS))
|
|
|
- .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatResult.KILLED, CombatResult.KNOCKED, CombatResult.KNOCKED_OFF));
|
|
|
-
|
|
|
-
|
|
|
-(new CombatPokeDescription("Hitting Orc"))
|
|
|
- .setDescriptionFunction((aggressor, target, markers) => {
|
|
|
- let say = new Say(new SayBold(target), ": ");
|
|
|
-
|
|
|
- let action = new SayAction();
|
|
|
- action.add("looks at ");
|
|
|
- if (aggressor != WorldState.player) {
|
|
|
- action.add(new SayThe(), aggressor)
|
|
|
- } else {
|
|
|
- action.add("you");
|
|
|
- }
|
|
|
- say.add(action);
|
|
|
-
|
|
|
- if (markers.includes(AIRules.resultHostile)) {
|
|
|
- say.add("Fucking seriously!? I'm going to rip your head off!");
|
|
|
- return say;
|
|
|
- } else if (AIRules.resultRetaliate) {
|
|
|
- say.add("Fucking STOP that!");
|
|
|
- return say;
|
|
|
- }
|
|
|
-
|
|
|
- if (markers.includes(AIRules.actionMin)) {
|
|
|
- say.add(
|
|
|
- new OneOf(OneOf.PURELY_AT_RANDOM,
|
|
|
- "Stop that.",
|
|
|
- "You better stop that.",
|
|
|
- "Look, I'm not very patient. Stop that."
|
|
|
- )
|
|
|
- );
|
|
|
- } else if (markers.includes(AIRules.actionMed)) {
|
|
|
- say.add(
|
|
|
- new OneOf(OneOf.PURELY_AT_RANDOM,
|
|
|
- "Fucking do that again, see what happens.",
|
|
|
- "Watch it!",
|
|
|
- "I'm THIS close to ripping your head off!"
|
|
|
- )
|
|
|
- );
|
|
|
- } else if (markers.includes(AIRules.actionMax)) {
|
|
|
- say.add(
|
|
|
- new OneOf(OneOf.PURELY_AT_RANDOM,
|
|
|
- "Goddamn it.",
|
|
|
- "Watch it!",
|
|
|
- "I'm THIS close to ripping your head off!"
|
|
|
- )
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- return say;
|
|
|
- })
|
|
|
- .addUnit()
|
|
|
- .setAggressor(Person)
|
|
|
- .setTarget(OrcDebugger)
|
|
|
- .addMarker(AdaptiveDifferential.FULLYADAPTIVE(AIRules.resultRetaliate, AIRules.resultHostile, AIRules.resultNotHostile))
|
|
|
- .addMarker(AdaptiveDifferential.FULLYADAPTIVE(AIRules.actionMin, AIRules.actionMed, AIRules.actionMax));
|
|
|
+// .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatHit.HIT, CombatHit.CRITICAL, CombatHit.MISS))
|
|
|
+// .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatResult.KILLED, CombatResult.KNOCKED, CombatResult.KNOCKED_OFF));
|
|
|
+//
|
|
|
+//
|
|
|
+// (new CombatPokeDescription("Hitting Orc"))
|
|
|
+// .setDescriptionFunction((aggressor, target, markers) => {
|
|
|
+// let say = new Say(new SayBold(target), ": ");
|
|
|
+//
|
|
|
+// let action = new SayAction();
|
|
|
+// action.add("looks at ");
|
|
|
+// if (aggressor != WorldState.player) {
|
|
|
+// action.add(new SayThe(), aggressor)
|
|
|
+// } else {
|
|
|
+// action.add("you");
|
|
|
+// }
|
|
|
+// say.add(action);
|
|
|
+//
|
|
|
+// if (markers.includes(AIRules.resultHostile)) {
|
|
|
+// say.add("Fucking seriously!? I'm going to rip your head off!");
|
|
|
+// return say;
|
|
|
+// } else if (AIRules.resultRetaliate) {
|
|
|
+// say.add("Fucking STOP that!");
|
|
|
+// return say;
|
|
|
+// }
|
|
|
+//
|
|
|
+// if (markers.includes(AIRules.actionMin)) {
|
|
|
+// say.add(
|
|
|
+// new OneOf(OneOf.PURELY_AT_RANDOM,
|
|
|
+// "Stop that.",
|
|
|
+// "You better stop that.",
|
|
|
+// "Look, I'm not very patient. Stop that."
|
|
|
+// )
|
|
|
+// );
|
|
|
+// } else if (markers.includes(AIRules.actionMed)) {
|
|
|
+// say.add(
|
|
|
+// new OneOf(OneOf.PURELY_AT_RANDOM,
|
|
|
+// "Fucking do that again, see what happens.",
|
|
|
+// "Watch it!",
|
|
|
+// "I'm THIS close to ripping your head off!"
|
|
|
+// )
|
|
|
+// );
|
|
|
+// } else if (markers.includes(AIRules.actionMax)) {
|
|
|
+// say.add(
|
|
|
+// new OneOf(OneOf.PURELY_AT_RANDOM,
|
|
|
+// "Goddamn it.",
|
|
|
+// "Watch it!",
|
|
|
+// "I'm THIS close to ripping your head off!"
|
|
|
+// )
|
|
|
+// );
|
|
|
+// }
|
|
|
+//
|
|
|
+// return say;
|
|
|
+// })
|
|
|
+// .addUnit()
|
|
|
+// .setAggressor(Person)
|
|
|
+// .setTarget(OrcDebugger)
|
|
|
+// .addMarker(AdaptiveDifferential.FULLYADAPTIVE(AIRules.resultRetaliate, AIRules.resultHostile, AIRules.resultNotHostile))
|
|
|
+// .addMarker(AdaptiveDifferential.FULLYADAPTIVE(AIRules.actionMin, AIRules.actionMed, AIRules.actionMax));
|
|
|
+
|
|
|
+// (new CombatDescription("test"))
|
|
|
+// .setDescriptionFunction((actor, target, weapons, markers) => {
|
|
|
+// let say = new Say();
|
|
|
+// let verb = "attack";
|
|
|
+// if (!WorldState.isPlayer(actor)) {
|
|
|
+// verb += "s";
|
|
|
+// }
|
|
|
+// say.add(Say.Mention(actor), " " + verb + " ", Say.Mention(target), " with ", Say.Possessive(actor), " fists.");
|
|
|
+//
|
|
|
+// if (markers.includes(CombatHit.MISS)) {
|
|
|
+// say.add(" ", Say.Subject(actor), " " + ("miss" + (WorldState.isPlayer(actor) ? "es." : ".")));
|
|
|
+// } else if (markers.includes(CombatHit.CRITICAL)) {
|
|
|
+// say.add(" It was a very strong hit!");
|
|
|
+// }
|
|
|
+//
|
|
|
+// if (markers.includes(CombatResult.KILLED)) {
|
|
|
+// say.add(" ", Say.Mention(target), " was killed by the force of the attack.");
|
|
|
+// } else if (markers.includes(CombatResult.KNOCKED_OFF)) {
|
|
|
+// say.add(" ", Say.Mention(target), " was incapacitated by the force of the attack.");
|
|
|
+// } else if (markers.includes(CombatResult.KNOCKED)) {
|
|
|
+// say.add(" ", Say.Mention(target), " was thrown to the ground by the force of the attack.");
|
|
|
+// }
|
|
|
+//
|
|
|
+// return say;
|
|
|
+// })
|
|
|
+// .addUnit()
|
|
|
+// .setActor(Person)
|
|
|
+// .setTarget(Person)
|
|
|
+// .setWeapon(HumanoidHands)
|
|
|
+// .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatHit.MISS, CombatHit.HIT, CombatHit.CRITICAL))
|
|
|
+// .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatResult.KNOCKED, CombatResult.KILLED, CombatResult.KNOCKED_OFF))
|
|
|
+// ;
|
|
|
+
|
|
|
+// (new CombatDescription("Minotaur Attacks"))
|
|
|
+// .setDescriptionFunction((actor, target, weapons, markers) => {
|
|
|
+// let say = new Say();
|
|
|
+//
|
|
|
+// if (markers.includes(CombatHit.MISS) {
|
|
|
+// say.add("The minotaur heaves his heavy punches at you, but you narrowly avoid it.");
|
|
|
+// } else if (markers.includes(CombatHit.HIT) {
|
|
|
+// say.add("The minotaur punches you with ease.");
|
|
|
+// } else if (markers.includes(CombatHit.CRITICAL) {
|
|
|
+// say.add("The minotaur punches you in the gut. Ouch, you felt that HARD.");
|
|
|
+// }
|
|
|
+//
|
|
|
+// say.add(" ");
|
|
|
+//
|
|
|
+// if (markers.includes(CombatResult.KILLED) {
|
|
|
+// say.add("YOU ARE DEAD.");
|
|
|
+// } else if (markers.includes(CombatResult.KNOCKED_OFF) {
|
|
|
+// say.add("You lose consciousness.");
|
|
|
+// } else if (markers.includes(CombatResult.KNOCKED) {
|
|
|
+// say.add("You are knocked to the ground!");
|
|
|
+// }
|
|
|
+//
|
|
|
+// return say;
|
|
|
+// })
|
|
|
+// .addUnit()
|
|
|
+// .setActor(MinotaurGuard)
|
|
|
+// .setTarget(WorldState.player)
|
|
|
+// .setWeapon(Thing)
|
|
|
+// .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatHit.MISS, CombatHit.HIT, CombatHit.CRITICAL))
|
|
|
+// .addMarker(AdaptiveDifferential.FULLYADAPTIVE(CombatResult.KNOCKED, CombatResult.KILLED, CombatResult.KNOCKED_OFF))
|
|
|
+// ;
|