diff --git a/game_engine.coffee b/game_engine.coffee index 8afafe4..0e07952 100644 --- a/game_engine.coffee +++ b/game_engine.coffee @@ -26,6 +26,9 @@ class Inventory @items[item.name] = item @length += 1 + all: -> + return (item for name, item of @items) + describe: (options={})-> options.simple ?= false result = [] @@ -55,8 +58,16 @@ class Inventory class Item - constructor: (@name)-> + constructor: (@name, options={})-> + options.fixed ?= false + @description = "non-descript item" + @fixed = options.fixed + + # Public Methods ############################################################################### + + attemptTake: -> + return true describe: -> return @description @@ -104,7 +115,6 @@ class Location return undefined - removeItem: (item)-> @items.remove(item) return this @@ -258,12 +268,39 @@ class Player constructor: (@story)-> @inventory = new Inventory() + @onChange = (->) @verbs = {} + @_score = 0 + + # Properties ################################################################################### + + Object.defineProperties @prototype, + score: + get: -> + return @_score + set: (value)-> + @_score = value + @onChange(this) + + # Public Methods ############################################################################### + addVerb: (verb, onVerb)-> @verbs[verb] = onVerb @story.parser.addVerb(verb) + drop: (items...)-> + if items.length is 0 + items = @inventory.all() + + for item in items + if @inventory.has(item) + @inventory.remove(item) + @story.currentLocation.inventory.add(item) + @story.log.writeln("Dropped #{item.name}.") + else + @story.log.writeln("You're not holding a #{item.name}.") + enact: (sentence)-> onVerb = @verbs[sentence.verb] if onVerb @@ -283,16 +320,25 @@ class Player take: (item)-> localItems = @story.currentLocation.inventory if not item - localItems.eachItem (item)=> @take(item) + tookSomething = false + localItems.eachItem (item)=> + if not item.fixed + @take(item) + tookSomething = true + + if not tookSomething then @story.log.writeln("There's nothing here you can take.") else if localItems.has(item) - localItems.remove(item) - @inventory.add(item) - @story.log.writeln("Taken.") + console.log(item) + if not item.fixed + localItems.remove(item) + @inventory.add(item) + @story.log.writeln("Took the #{item.name}.") + else + @story.log.writeln("You can't take the #{item.name}.") else throw new ParseError("You can't take #{item} because there isn't one here.") - ######################################################################################################################## class Sentence @@ -339,15 +385,28 @@ class Story @items = [] @locations = [] @log = new GameLog() + @onChange = (->) @parser = new Parser(this) @player = new Player(this) + @_turns = 0 + @_configure() + # Properties ################################################################################### + + Object.defineProperties @prototype, + "turns": + get: -> + return @_turns + set: (value)-> + @_turns = value + @onChange(this) + # Configuration Methods ###########3############################################################ - addItem: (name)-> - item = new Item(name) + addItem: (name, options={})-> + item = new Item(name, options) @items.push(item) return item @@ -375,6 +434,7 @@ class Story interpret: (userInput)-> try @log.echoInput(userInput) + @turns += 1 sentence = @parser.interpret(userInput) @player.enact(sentence) catch e @@ -415,6 +475,13 @@ class Story "w": "west", }) + @player.addVerb "drop", (sentence)=> + if sentence.has(item: 0) + @player.drop() + else + for itemToken in sentence.tokens.item + @player.drop(itemToken.referant) + @player.addVerb "go", (sentence)=> if sentence.has(location: 1) @player.move(sentence.location) diff --git a/index.html b/index.html index 1a77aed..617b53d 100644 --- a/index.html +++ b/index.html @@ -2,6 +2,10 @@ +
+   +   +

diff --git a/run_game.coffee b/run_game.coffee index 35f345a..33a4a94 100644 --- a/run_game.coffee +++ b/run_game.coffee @@ -6,18 +6,32 @@ RETURN_KEY = 13 # Global Data ########################################################################################################## $(document).ready -> + # configure player input box $input = $("input.entry") $input.on "keydown", -> if event.which isnt RETURN_KEY then return STORY.interpret($input.val()) $input.val("") + # configure the story log display $log = $(".log") $logText = $("p.log-text") - STORY.log.onChange = (log)-> $logText.html(log.content) $log.scrollTop($log[0].scrollHeight) + # configure the score display + $score = $(".score") + STORY.player.onChange = (player)-> + $score.text("score: #{player.score}") + STORY.player.onChange(STORY.player) + + # configure the turns display + $turns = $(".turns") + STORY.onChange = (story)-> + $turns.text("turns: #{story.turns}") + STORY.onChange(STORY) + + # start the story STORY.begin() $input.focus() diff --git a/story.coffee b/story.coffee index 8765c46..51a9dca 100644 --- a/story.coffee +++ b/story.coffee @@ -2,7 +2,7 @@ window.STORY = s = new Story("A Walk Through My House") # Items ################################################################################################################ -boxOfTile = s.addItem("box of tiles") +boxOfTile = s.addItem("box of tiles", fixed: true) boxOfTile.description = "This appears to be a box of flooring tiles. The tiles appear to be a very light color of natural stone. It is quite heavy." diff --git a/styles.css b/styles.css index b1aff92..d803f7a 100644 --- a/styles.css +++ b/styles.css @@ -11,16 +11,7 @@ body { justify-content: center; } -div.log { - background: black; - color: green; - height: 600px; - overflow-y: scroll; - padding: 0.25em 1em; - width: 800px; -} - -input.entry { +.entry { background: black; border: none; border-top: 1px solid gray; @@ -33,10 +24,33 @@ input.entry { width: 800px; } -p.log-text { +.log { + background: black; + color: green; + height: 600px; + overflow-y: auto; + padding: 0.25em 1em; + width: 800px; } -p.placeholder { - color: gray; +.status { + background: black; + border: none; + border-bottom: 1px solid gray; + color: green; + display: flex; + font-family: monospace; + font-size: 16px; + margin: 0; + padding: 0.5em 1em; + width: 800px; } +.score { + flex: 1 1 50%; + text-align: right; +} + +.turns { + flex: 1 1 50%; +}