1
0
Fork 0
mirror of https://gitlab.com/Oreolek/salet.git synced 2024-06-01 07:48:20 +03:00

A playable game with most features on

This commit is contained in:
Alexander Yakovlev 2016-02-01 15:51:48 +07:00
parent 5e7f4087aa
commit 5af7d3ad72
6 changed files with 73 additions and 74 deletions

View file

@ -21,7 +21,7 @@ room "plaza", salet,
return "Town plaza" return "Town plaza"
cycle: ["quirky", "distinct", "kooky", "crazy", "quaint"] cycle: ["quirky", "distinct", "kooky", "crazy", "quaint"]
ways: ["shop"] ways: ["shop"]
before: (character, system, from) -> before: (system, from) ->
if from == 'world' if from == 'world'
""" """
You climb up the well and come out to a central plaza of a #{cyclelink("quaint")} little town. You climb up the well and come out to a central plaza of a #{cyclelink("quaint")} little town.
@ -32,11 +32,11 @@ room "plaza", salet,
objects: objects:
policeman: obj "policeman", policeman: obj "policeman",
dsc: "There is a policeman nearby. You could ask him {{for directions.}}" dsc: "There is a policeman nearby. You could ask him {{for directions.}}"
act: (character) -> act: (salet) ->
if character.sandbox.has_mark? if salet.character.has_mark?
return "You already talked to him, no need to bug the man twice." return "You already talked to him, no need to bug the man twice."
character.sandbox.has_mark ?= true salet.character.has_mark ?= true
get_room("lair").destination() salet.getRoom("lair").destination()
""" """
Here, let me mark it on your map. Here, let me mark it on your map.
""" """
@ -65,8 +65,8 @@ room "lair", salet,
bugg: obj "bugg", bugg: obj "bugg",
dsc: "You see a particularly beautiful slimy {{bugg.}}" dsc: "You see a particularly beautiful slimy {{bugg.}}"
takeable: false takeable: false
act: () => act: (salet) =>
here().drop(@name) salet.here().drop(@name)
return "You eat the bugg mass. Delicious and raw. Perhaps it's a good lair to live in." return "You eat the bugg mass. Delicious and raw. Perhaps it's a good lair to live in."
dialogue "Yes", salet, "merchant", "merchant", """ dialogue "Yes", salet, "merchant", "merchant", """
@ -85,8 +85,8 @@ room "shop-inside", salet,
merchant: obj "merchant", merchant: obj "merchant",
dsc: "A {{merchant}} eyes you warily." dsc: "A {{merchant}} eyes you warily."
takeable: false takeable: false
act: (character, system) => act: (system) =>
undum.processClick("merchdialogue") salet.processClick("merchdialogue")
return "" return ""
### ###

View file

@ -8,12 +8,12 @@ cyclelink = (content) ->
cycle = (responses, name, character) -> cycle = (responses, name, character) ->
if typeof responses == "function" if typeof responses == "function"
responses = responses() responses = responses()
character.sandbox.cycle_index ?= [] # initialize with empty array character.cycle_index ?= [] # initialize with empty array
character.sandbox.cycle_index[name] ?= 0 # initialize with 0 character.cycle_index[name] ?= 0 # initialize with 0
response = responses[character.sandbox.cycle_index[name]] response = responses[character.cycle_index[name]]
character.sandbox.cycle_index[name]++ character.cycle_index[name]++
if character.sandbox.cycle_index[name] == responses.length if character.cycle_index[name] == responses.length
character.sandbox.cycle_index[name] = 0 character.cycle_index[name] = 0
return cyclelink(response) return cyclelink(response)
module.exports = cycle module.exports = cycle

View file

@ -23,17 +23,17 @@ class SaletObj
for key, value of spec for key, value of spec
this[key] = value this[key] = value
level: 0 level: 0
look: (character, system, f) => look: (system, f) =>
if @dsc if @dsc
text = markdown(@dsc.fcall(this, character, system, f)) text = markdown(@dsc.fcall(this, system, f).toString())
text = "<span class='look lvl#{@level}'>" + text + "</span>" text = "<span class='look lvl#{@level}'>" + text + "</span>"
# replace braces {{}} with link to _act_ # replace braces {{}} with link to _act_
return parsedsc(text, @name) return parsedsc(text, @name)
takeable: false takeable: false
take: (character, system) => "You take the #{@name}." # taking to inventory take: (system) => "You take the #{@name}." # taking to inventory
act: (character, system) => "You don't find anything extraordinary about the #{@name}." # object action act: (system) => "You don't find anything extraordinary about the #{@name}." # object action
dsc: (character, system) => "You see a {{#{@name}}} here." # object description dsc: (system) => "You see a {{#{@name}}} here." # object description
inv: (character, system) => "It's a {{#{@name}.}}" # inventory description inv: (system) => "It's a {{#{@name}.}}" # inventory description
location: "" location: ""
put: (location) => put: (location) =>
@level = 0 # this is scenery @level = 0 # this is scenery

View file

@ -5,20 +5,19 @@ obj = require('./obj.coffee')
markdown = require('./markdown.coffee') markdown = require('./markdown.coffee')
cycle = require('./cycle.coffee') cycle = require('./cycle.coffee')
# Assertion
assert = (msg, assertion) -> console.assert assertion, msg assert = (msg, assertion) -> console.assert assertion, msg
Function.prototype.fcall = Function.prototype.call;
Boolean.prototype.fcall = () ->
return this
String.prototype.fcall = () ->
return this
way_to = (content, ref) -> way_to = (content, ref) ->
return "<a href='#{ref}' class='way' id='waylink-#{ref}'>#{content}</a>" return "<a href='#{ref}' class='way' id='waylink-#{ref}'>#{content}</a>"
Array::remove = (e) -> @[t..t] = [] if (t = @indexOf(e)) > -1 Array::remove = (e) -> @[t..t] = [] if (t = @indexOf(e)) > -1
addClass = (element, className) ->
if (element.classList)
element.classList.add(className)
else
element.className += ' ' + className
class SaletRoom class SaletRoom
constructor: (spec) -> constructor: (spec) ->
for index, value of spec for index, value of spec
@ -126,7 +125,8 @@ class SaletRoom
# Print the room description # Print the room description
if @dsc if @dsc
retval += markdown(@dsc.fcall(this, system, f)) dsc = @dsc.fcall(this, system, f).toString()
retval += markdown(dsc)
for name, thing of @objects for name, thing of @objects
retval += thing.look() retval += thing.look()
@ -157,13 +157,13 @@ class SaletRoom
# If it's takeable, the player can take this object. # If it's takeable, the player can take this object.
# If not, we check the "act" function. # If not, we check the "act" function.
if thing.takeable if thing.takeable
character.sandbox.inventory.push thing system.character.inventory.push thing
@drop name @drop name
cls(system) system.view.clearContent()
@entering.fcall(this, character, system, @name) @entering.fcall(this, system, @name)
return print(thing.take.fcall(thing, character, system)) return system.view.write(thing.take.fcall(thing, system).toString())
if thing.act if thing.act
return print(thing.act.fcall(thing, character, system)) return system.view.write(thing.act.fcall(thing, system).toString())
elseif link[1] == "cycle" elseif link[1] == "cycle"
# TODO object cyclewriter # TODO object cyclewriter
# the loop is done but no return came - match not found # the loop is done but no return came - match not found
@ -177,15 +177,15 @@ class SaletRoom
writer: (ref) -> writer: (ref) ->
content = that.writers[ref].fcall(that, system, action) content = that.writers[ref].fcall(that, system, action)
output = markdown(content) output = markdown(content)
system.writeInto(output, '#current-room') system.view.write(output)
replacer: (ref) -> replacer: (ref) ->
content = that.writers[ref].fcall(that, system, action) content = that.writers[ref].fcall(that, system, action)
output = "<span>"+content+"</span>" # <p> tags are usually bad for replacers output = "<span>"+content+"</span>" # <p> tags are usually bad for replacers
system.replaceWith(output, '#'+ref) system.view.replace(output, '#'+ref)
inserter: (ref) -> inserter: (ref) ->
content = that.writers[ref].fcall(that, system, action) content = that.writers[ref].fcall(that, system, action)
output = markdown(content) output = markdown(content)
system.writeInto(output, '#'+ref) system.view.write(output, '#'+ref)
} }
if (actionClass) if (actionClass)
@ -221,8 +221,8 @@ class SaletRoom
return this return this
writers: writers:
cyclewriter: (character) -> cyclewriter: (salet) ->
cycle(this.cycle, this.name, character) cycle(this.cycle, this.name, salet.character)
room = (name, salet, spec) -> room = (name, salet, spec) ->
spec ?= {} spec ?= {}

View file

@ -18,19 +18,7 @@ String.prototype.fcall = () ->
assert = (msg, assertion) -> console.assert assertion, msg assert = (msg, assertion) -> console.assert assertion, msg
class Character class Character
inventory: []
# Utility functions
parseFn = (str) ->
unless str?
return str
fstr = """
(function(character, situation) {
#{str}
#})
"""
return eval(fstr)
# Regular expression to catch every link action. # Regular expression to catch every link action.
# Salet's default is a general URL-safe expression. # Salet's default is a general URL-safe expression.
@ -257,8 +245,8 @@ class Salet
# Handle each link in turn. # Handle each link in turn.
@processOneLink(code); @processOneLink(code);
while (@linkStack.length > 0) while (@linkStack.length > 0)
code = linkStack.shift() code = @linkStack.shift()
processOneLink(code) @processOneLink(code)
# We're done, so remove the stack to prevent future pushes. # We're done, so remove the stack to prevent future pushes.
@linkStack = null; @linkStack = null;
@ -291,22 +279,15 @@ class Salet
# Carry out the action # Carry out the action
if (action) if (action)
situation = @getCurrentRoom() room = @getCurrentRoom()
if (situation) if (room and @beforeAction)
if (@beforeAction) # Try the global act handler
# Try the global act handler, and see if we need consumed = @beforeAction(room, action)
# to notify the situation. if (consumed != true)
consumed = @beforeAction( room.act(this, action)
character, current, action
)
if (consumed != true)
situation.act(character, action)
else
# We have no global act handler, always notify the situation.
situation.act(character, action)
if (@afterAction) if (@afterAction)
@afterAction(character, current, action) @afterAction(this, room, action)
# This gets called when the user clicks a link to carry out an action. # This gets called when the user clicks a link to carry out an action.
processClick: (code) -> processClick: (code) ->

View file

@ -16,6 +16,12 @@ assert = (msg, assertion) -> console.assert assertion, msg
way_to = (content, ref) -> way_to = (content, ref) ->
return "<a href='#{ref}' class='way'>#{content}</a>" return "<a href='#{ref}' class='way'>#{content}</a>"
addClass = (element, className) ->
if (element.classList)
element.classList.add(className)
else
element.className += ' ' + className
class SaletView class SaletView
init: (salet) -> init: (salet) ->
$("#content, #ways").on("click", "a", (event) -> $("#content, #ways").on("click", "a", (event) ->
@ -70,15 +76,19 @@ class SaletView
document.getElementById("intro").innerHTML = "" document.getElementById("intro").innerHTML = ""
document.querySelector(elementSelector).innerHTML = "" document.querySelector(elementSelector).innerHTML = ""
# Write content to current room prepareContent: (content) ->
write: (content) ->
if content == ""
return
if typeof content == "function" if typeof content == "function"
content = content() content = content()
if content instanceof jQuery if content instanceof jQuery
content = content[0].outerHTML content = content[0].outerHTML
block = document.getElementById("current-room") return content.toString()
# Write content to current room
write: (content, elementSelector = "#current-room") ->
if content == ""
return
content = @prepareContent(content)
block = document.querySelector(elementSelector)
if block if block
block.innerHTML = block.innerHTML + markdown(content) block.innerHTML = block.innerHTML + markdown(content)
else else
@ -86,6 +96,14 @@ class SaletView
block = document.getElementById("content") block = document.getElementById("content")
block.innerHTML = content block.innerHTML = content
# Replaces the text in the given block with the given text.
# !! Does not call markdown on the provided text. !!
replace: (content, elementSelector) ->
if content == ""
return
content = @prepareContent(content)
block = document.querySelector(elementSelector)
block.innerHTML = content
### ###
Turns any links that target the given href into plain Turns any links that target the given href into plain
text. This can be used to remove action options when an action text. This can be used to remove action options when an action