| @@ -6,6 +6,7 @@ | |||||
| <title>Feast</title> | <title>Feast</title> | ||||
| <link rel="stylesheet" href="feast.css"> | <link rel="stylesheet" href="feast.css"> | ||||
| <script src="status.js"></script> | <script src="status.js"></script> | ||||
| <script src="forest.js"></script> | |||||
| <script src="combat.js"></script> | <script src="combat.js"></script> | ||||
| <script src="objects.js"></script> | <script src="objects.js"></script> | ||||
| <script src="dialog.js"></script> | <script src="dialog.js"></script> | ||||
| @@ -115,6 +115,8 @@ function updateExploreCompass() { | |||||
| } | } | ||||
| } | } | ||||
| function updateExploreActions() { | function updateExploreActions() { | ||||
| updateActions(); | |||||
| for (let i = 0; i < actionButtons.length; i++) { | for (let i = 0; i < actionButtons.length; i++) { | ||||
| if (i < actions.length) { | if (i < actions.length) { | ||||
| actionButtons[i].disabled = false; | actionButtons[i].disabled = false; | ||||
| @@ -307,27 +309,32 @@ function move(direction) { | |||||
| moveTo(target,currentRoom.exitDescs[direction]); | moveTo(target,currentRoom.exitDescs[direction]); | ||||
| } | } | ||||
| function updateActions() { | |||||
| actions = []; | |||||
| currentRoom.objects.forEach(function (object) { | |||||
| object.actions.forEach(function (action) { | |||||
| if (action.conditions == undefined || action.conditions.reduce((result, cond) => result && cond(player.prefs), true)) | |||||
| actions.push(action); | |||||
| }); | |||||
| }); | |||||
| } | |||||
| function moveToByName(roomName, desc="You go places lol", loading=false) { | function moveToByName(roomName, desc="You go places lol", loading=false) { | ||||
| moveTo(world[roomName], desc, loading); | moveTo(world[roomName], desc, loading); | ||||
| } | } | ||||
| function moveTo(room,desc="You go places lol", loading=false) { | function moveTo(room,desc="You go places lol", loading=false) { | ||||
| actions = []; | |||||
| currentRoom = room; | currentRoom = room; | ||||
| if (!loading) | if (!loading) | ||||
| advanceTime(30); | advanceTime(30); | ||||
| currentRoom.objects.forEach(function (object) { | |||||
| object.actions.forEach(function (action) { | |||||
| if (action.conditions == undefined || action.conditions.reduce((result, cond) => result && cond(player.prefs), true)) | |||||
| actions.push(action); | |||||
| }); | |||||
| }); | |||||
| update([desc,newline]); | update([desc,newline]); | ||||
| currentRoom.visit(); | currentRoom.visit(); | ||||
| updateDisplay(); | |||||
| } | } | ||||
| window.addEventListener('load', function(event) { | window.addEventListener('load', function(event) { | ||||
| @@ -0,0 +1,148 @@ | |||||
| function ForestExplore() { | |||||
| GameObject.call(this, "Explore the Forest"); | |||||
| this.actions.push({ | |||||
| "name": "Explore", | |||||
| "action": function() { | |||||
| let outcome = Math.random(); | |||||
| advanceTime(60*30 * (Math.random() * 0.2 + 0.9)); | |||||
| if (outcome < 0.25) { | |||||
| currentRoom.flags.exit = true; | |||||
| update(["You find a way back!"]); | |||||
| } else if (outcome < 0.5) { | |||||
| startCombat(new Wolf()); | |||||
| } else if (outcome < 0.6) { | |||||
| startCombat(new AlphaWolf()); | |||||
| } else { | |||||
| update(["You explore the forest for a while, but don't find anything."]); | |||||
| } | |||||
| } | |||||
| }); | |||||
| this.actions.push({ | |||||
| "name": "Leave", | |||||
| "action": function() { | |||||
| moveToByName("East Trail", "You leave the forest"); | |||||
| }, | |||||
| "conditions": [ | |||||
| function(player) { | |||||
| return currentRoom.flags.exit; | |||||
| } | |||||
| ] | |||||
| }); | |||||
| } | |||||
| function Wolf() { | |||||
| Creature.call(this, "Wolf", 10, 15, 15); | |||||
| this.hasName = false; | |||||
| this.description = function() { return "wolf"; }; | |||||
| this.attacks = []; | |||||
| this.attacks.push(wolfBite(this)); | |||||
| //this.attacks.push(wolfSwallow(this)); | |||||
| this.attacks.push(wolfTackle(this)); | |||||
| //this.attacks.push(wolfTackleBite(this)); | |||||
| this.attacks.push(wolfTackleSwallow(this)); | |||||
| this.attacks.push(wolfDigest(this)); | |||||
| this.backupAttack = pass(this); | |||||
| this.flags.stage = "combat"; | |||||
| this.startCombat = function(player) { | |||||
| return ["Oh no a feral wolf"]; | |||||
| }; | |||||
| this.finishCombat = function() { | |||||
| return ["Oops eaten"]; | |||||
| }; | |||||
| this.status = function(player) { | |||||
| return ["It's a wolf"]; | |||||
| }; | |||||
| } | |||||
| function wolfBite(attacker) { | |||||
| return { | |||||
| attackPlayer: function(defender){ | |||||
| let damage = attack(attacker, defender, attacker.str); | |||||
| return ["The wolf jumps at you, biting for " + damage + " damage"]; | |||||
| }, | |||||
| requirements: [ | |||||
| function(attacker, defender) { | |||||
| return attacker.flags.stage == "combat"; | |||||
| }, | |||||
| function(attacker, defender) { | |||||
| return !attacker.flags.grappled && !defender.flags.grappled; | |||||
| } | |||||
| ], | |||||
| priority: 1, | |||||
| weight: function(attacker, defender) { return 1 + defender.health/defender.maxHealth; } | |||||
| }; | |||||
| } | |||||
| function wolfTackle(attacker) { | |||||
| return { | |||||
| attackPlayer: function(defender){ | |||||
| defender.flags.grappled = true; | |||||
| return ["The wolf leaps on top of you, pinning you to the ground!"]; | |||||
| }, | |||||
| requirements: [ | |||||
| function(attacker, defender) { | |||||
| return attacker.flags.stage == "combat"; | |||||
| }, | |||||
| function(attacker, defender) { | |||||
| return !attacker.flags.grappled && !defender.flags.grappled; | |||||
| } | |||||
| ], | |||||
| priority: 1, | |||||
| weight: function(attacker, defender) { return 1.25 - defender.health/defender.maxHealth; } | |||||
| }; | |||||
| } | |||||
| function wolfTackleSwallow(attacker) { | |||||
| return { | |||||
| attackPlayer: function(defender){ | |||||
| attacker.flags.stage = "oral"; | |||||
| return ["You struggle against the wolf, but it's not enough - its greedy jaws envelop your head, then your shoulders. The hungry beast swallows you down in seconds, cramming you into its hot, slimy stomach."]; | |||||
| }, | |||||
| conditions: [ | |||||
| function(attacker, defender) { | |||||
| return defender.prefs.prey && defender.prefs.vore.oral > 0; | |||||
| } | |||||
| ], | |||||
| requirements: [ | |||||
| function(attacker, defender) { | |||||
| return attacker.flags.stage == "combat"; | |||||
| }, | |||||
| function(attacker, defender) { | |||||
| return !attacker.flags.grappled && defender.flags.grappled; | |||||
| } | |||||
| ], | |||||
| priority: 1, | |||||
| weight: function(attacker, defender) { return 1; } | |||||
| }; | |||||
| } | |||||
| function wolfDigest(attacker) { | |||||
| return { | |||||
| attackPlayer: function(defender){ | |||||
| let damage = attack(attacker, defender, 25); | |||||
| return ["The wolf's churning guts wear you down."]; | |||||
| }, | |||||
| requirements: [ | |||||
| function(attacker, defender) { | |||||
| return attacker.flags.stage == "oral"; | |||||
| } | |||||
| ], | |||||
| priority: 1, | |||||
| weight: function(attacker, defender) { return 1; } | |||||
| }; | |||||
| } | |||||
| @@ -46,8 +46,8 @@ function Toilet() { | |||||
| update(lines); | update(lines); | ||||
| }, | }, | ||||
| "conditions": [ | "conditions": [ | ||||
| function(prefs) { | |||||
| return prefs.scat == true; | |||||
| function(player) { | |||||
| return player.prefs.scat == true; | |||||
| } | } | ||||
| ] | ] | ||||
| }); | }); | ||||
| @@ -156,6 +156,11 @@ let locationsSrc = [ | |||||
| "dir": NORTH, | "dir": NORTH, | ||||
| "desc": "You walk north" | "desc": "You walk north" | ||||
| }, | }, | ||||
| { | |||||
| "name": "East Street", | |||||
| "dir": EAST, | |||||
| "desc": "You walk east" | |||||
| }, | |||||
| { | { | ||||
| "name": "South Street", | "name": "South Street", | ||||
| "dir": SOUTH, | "dir": SOUTH, | ||||
| @@ -168,6 +173,58 @@ let locationsSrc = [ | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| { | |||||
| "name": "East Street", | |||||
| "desc": "This street is in the east", | |||||
| "conn": [ | |||||
| { | |||||
| "name": "Crossroads", | |||||
| "dir": WEST, | |||||
| "desc": "You walk to the crossroads" | |||||
| }, | |||||
| { | |||||
| "name": "East Trail", | |||||
| "dir": EAST, | |||||
| "desc": "You head out on the road." | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "name": "East Trail", | |||||
| "desc": "A trail from your hometown to lands beyond", | |||||
| "conn": [ | |||||
| { | |||||
| "name": "East Street", | |||||
| "dir": WEST, | |||||
| "desc": "You walk back into town" | |||||
| }, | |||||
| { | |||||
| "name": "Woods", | |||||
| "dir": NORTH, | |||||
| "desc": "You wander into the woods." | |||||
| }, | |||||
| { | |||||
| "name": "Woods", | |||||
| "dir": SOUTH, | |||||
| "desc": "You wander into the woods." | |||||
| }, | |||||
| ] | |||||
| }, | |||||
| { | |||||
| "name": "Woods", | |||||
| "desc": "A thick forest. It's easy to get lost here, but it's not too dangerous, at least.", | |||||
| "conn": [ | |||||
| ], | |||||
| "objs": [ | |||||
| ForestExplore, | |||||
| ], | |||||
| "hooks": [ | |||||
| function() { | |||||
| currentRoom.flags.exit = false; | |||||
| } | |||||
| ] | |||||
| }, | |||||
| { | { | ||||
| "name": "South Street", | "name": "South Street", | ||||
| "desc": "This street is in the south", | "desc": "This street is in the south", | ||||
| @@ -272,6 +329,7 @@ function Location(name="Nowhere",desc="Nada") { | |||||
| this.objects = []; | this.objects = []; | ||||
| this.hooks = []; | this.hooks = []; | ||||
| this.conditions = []; | this.conditions = []; | ||||
| this.flags = []; | |||||
| this.visit = function() { | this.visit = function() { | ||||
| this.hooks.forEach(function (x) { | this.hooks.forEach(function (x) { | ||||