123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- 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;
- // }
- // }));
- 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);
- // }
- // 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);
- // (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(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));
|