mirror of
https://gitlab.com/Oreolek/salet-module.git
synced 2024-06-30 22:05:02 +03:00
Merge branch '2.0-dev'
This commit is contained in:
commit
6509b31955
5
Cakefile
5
Cakefile
|
@ -6,6 +6,7 @@ sources = [
|
|||
'utils.coffee'
|
||||
'view.coffee'
|
||||
'unit.coffee'
|
||||
'container.coffee'
|
||||
'character.coffee'
|
||||
'room.coffee'
|
||||
'localize.coffee'
|
||||
|
@ -17,7 +18,7 @@ for source in sources
|
|||
sourcestring += 'src/'+source+' '
|
||||
|
||||
task 'watch', 'Watch source files and build changes', ->
|
||||
watch = spawn "coffee", ['-c', '-w', '-m', '--no-header', '-j', 'lib/index.js', sourcestring]
|
||||
watch = spawn "node_modules/coffeescript/bin/coffee", ['-c', '-w', '-m', '--no-header', '-j', 'lib/index.js', sourcestring]
|
||||
watch.stdout.on 'data', (data) -> console.log data.toString().trim()
|
||||
|
||||
task 'compile', 'Compile all CoffeeScript files', ->
|
||||
|
@ -27,7 +28,7 @@ task 'compile', 'Compile all CoffeeScript files', ->
|
|||
|
||||
# run coffee-script compile
|
||||
exec "cat #{sourcestring} > lib/index.coffee"
|
||||
exec "coffee --compile --map --no-header lib/index.coffee", (err, stdout, stderr) ->
|
||||
exec "node_modules/coffeescript/bin/coffee --compile --map --no-header lib/index.coffee", (err, stdout, stderr) ->
|
||||
if err
|
||||
util.log err
|
||||
process.exit 1 # abort npm packaging
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2016 Alexander Yakovlev, https://oreolek.ru/
|
||||
Copyright (c) 2016-2017 Alexander Yakovlev, https://oreolek.ru/
|
||||
Raconteur is copyright (c) 2015 Bruno Dias, released under the similar license terms.
|
||||
Undum is copyright (c) 2009-2015 Ian Millington, released under the similar license terms.
|
||||
|
||||
|
|
11
package.json
11
package.json
|
@ -2,7 +2,14 @@
|
|||
"name": "salet",
|
||||
"version": "1.8.6",
|
||||
"description": "A general client-side framework for cybertext interactive fiction games.",
|
||||
"keywords": ["ifiction", "interactive fiction", "games", "coffee-script", "text", "menu"],
|
||||
"keywords": [
|
||||
"ifiction",
|
||||
"interactive fiction",
|
||||
"games",
|
||||
"coffee-script",
|
||||
"text",
|
||||
"menu"
|
||||
],
|
||||
"homepage": "https://salet.su",
|
||||
"bugs": {
|
||||
"url": "https://gitlab.com/oreolek/salet-module/issues"
|
||||
|
@ -16,7 +23,7 @@
|
|||
"url": "https://oreolek.ru"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coffee-script": "*"
|
||||
"coffeescript": "^2.0.0"
|
||||
},
|
||||
"main": "lib/index.min.js",
|
||||
"types": "./typings/salet/index.d.ts",
|
||||
|
|
|
@ -1,32 +1,6 @@
|
|||
class Character
|
||||
class Character extends Container
|
||||
constructor: (spec) ->
|
||||
@inventory = []
|
||||
|
||||
@take = (thing) =>
|
||||
@inventory.push thing
|
||||
|
||||
@drop = (thing) =>
|
||||
for i in @inventory
|
||||
if i.name == thing
|
||||
@inventory.remove(i)
|
||||
return true
|
||||
return false
|
||||
|
||||
@has = (thing) =>
|
||||
for i in @inventory
|
||||
if i.name == thing
|
||||
return true
|
||||
return false
|
||||
|
||||
@listinv = (thing) =>
|
||||
for i in @inventory
|
||||
if i.name == thing
|
||||
return invlink(i.display.fcall(i), i.name)
|
||||
|
||||
@inv = (thing) =>
|
||||
for i in @inventory
|
||||
if i.name == thing
|
||||
return i.inv.fcall(i)
|
||||
super spec
|
||||
|
||||
for index, value of spec
|
||||
this[index] = value
|
||||
|
|
35
src/container.coffee
Normal file
35
src/container.coffee
Normal file
|
@ -0,0 +1,35 @@
|
|||
# A container of elements.
|
||||
class Container
|
||||
constructor: (spec) ->
|
||||
@inventory = []
|
||||
if spec?
|
||||
if spec.inventory?
|
||||
@inventory = spec.inventory
|
||||
if spec.units?
|
||||
@inventory = spec.units
|
||||
|
||||
@take = (thing) =>
|
||||
if @name?
|
||||
thing.location = @name
|
||||
@inventory.push thing
|
||||
|
||||
@drop = (thing) =>
|
||||
for i in @inventory
|
||||
if i.name == thing
|
||||
i.location = null
|
||||
@inventory.remove(i)
|
||||
return true
|
||||
return false
|
||||
|
||||
@has = (thing) =>
|
||||
for i in @inventory
|
||||
if i.name == thing
|
||||
return true
|
||||
return false
|
||||
|
||||
@inv = (thing) =>
|
||||
for i in @inventory
|
||||
if i.name == thing
|
||||
return i.inv.fcall(i)
|
||||
|
||||
return this
|
|
@ -19,6 +19,11 @@ class Localize
|
|||
else
|
||||
@strings[lang] = strings
|
||||
|
||||
# Check if the translation exists.
|
||||
# @return bool
|
||||
exists: (index) ->
|
||||
return @strings[@lang][index]?
|
||||
|
||||
localize: (message, languageCode = @lang) ->
|
||||
if @strings[languageCode]?
|
||||
localized = @strings[languageCode][message]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
class SaletRoom
|
||||
class SaletRoom extends Container
|
||||
constructor: (spec) ->
|
||||
super spec
|
||||
@visited = 0
|
||||
|
||||
# unique room ID, mandatory to edit
|
||||
|
@ -7,7 +8,6 @@ class SaletRoom
|
|||
# room title, used in waypoint generation, see @ways
|
||||
@title = "Room"
|
||||
|
||||
@units = []
|
||||
@canView = true
|
||||
@canChoose = true
|
||||
@priority = 1
|
||||
|
@ -23,24 +23,6 @@ class SaletRoom
|
|||
@dsc = false # room description
|
||||
@extendSection = false
|
||||
@clear = true # clear the screen on entering the room?
|
||||
###
|
||||
I call SaletRoom.exit every time the player exits to another room.
|
||||
Unlike @after this gets called after the section is closed.
|
||||
It's a styling difference.
|
||||
###
|
||||
@exit = (to) =>
|
||||
return true
|
||||
|
||||
###
|
||||
I call SaletRoom.enter every time the player enters this room but before the section is opened.
|
||||
Unlike @before this gets called before the current section is opened.
|
||||
It's a styling difference.
|
||||
|
||||
The upstream Undum version does not allow you to redefine @enter function easily but allows custom @exit one.
|
||||
It was renamed as @entering to achieve API consistency.
|
||||
###
|
||||
@enter = (from) =>
|
||||
return true
|
||||
|
||||
###
|
||||
Salet calls SaletRoom.entering every time a situation is entered, and
|
||||
|
@ -50,6 +32,11 @@ class SaletRoom
|
|||
If f == this.name (we're in the same location) the `before` and `after` callbacks are ignored.
|
||||
###
|
||||
@entering = (f, force = false) =>
|
||||
$(document).trigger("room_transition", {
|
||||
"from": @name
|
||||
"to": f
|
||||
"forced": force
|
||||
})
|
||||
if (
|
||||
f != @name and
|
||||
salet.rooms[f]? and
|
||||
|
@ -64,6 +51,7 @@ class SaletRoom
|
|||
return salet.doTransitionTo(f, true)
|
||||
|
||||
if @clear and f?
|
||||
$(document).trigger("room_#{@name}_clear_content")
|
||||
salet.view.clearContent()
|
||||
|
||||
if salet.rooms[f]? and not @clear
|
||||
|
@ -71,14 +59,29 @@ class SaletRoom
|
|||
salet.view.removeTransient(f)
|
||||
else
|
||||
salet.view.removeTransient()
|
||||
salet.view.clearChoices()
|
||||
|
||||
if f != @name and salet.rooms[f]?
|
||||
$(document).trigger("room_exit", {
|
||||
"from": f
|
||||
"to": @name
|
||||
})
|
||||
$(document).trigger("room_#{f}_exit", {
|
||||
"to": @name
|
||||
})
|
||||
@visited++
|
||||
if salet.rooms[f].exit?
|
||||
salet.rooms[f].exit @name
|
||||
|
||||
if @enter
|
||||
@enter f
|
||||
$(document).trigger("room_enter", {
|
||||
"from": f
|
||||
"to": @name
|
||||
})
|
||||
$(document).trigger("room_#{@name}_enter", {
|
||||
"from": f
|
||||
})
|
||||
if @enter?
|
||||
@enter(f)
|
||||
|
||||
if not @extendSection
|
||||
classes = if @classes then ' ' + @classes.join(' ') else ''
|
||||
|
@ -95,14 +98,18 @@ class SaletRoom
|
|||
if f != @name and @after?
|
||||
salet.view.write markdown(@after.fcall(this, f))
|
||||
|
||||
if @beforeChoices?
|
||||
@beforeChoices.fcall(this, f)
|
||||
$(document).trigger("room_#{@name}_before_choices")
|
||||
if @beforeChoices
|
||||
salet.view.write markdown(@beforeChoices.fcall(this, f))
|
||||
|
||||
if @choices
|
||||
if @choices and @choices != ""
|
||||
salet.view.writeChoices(salet.getSituationIdChoices(@choices, @maxChoices))
|
||||
else
|
||||
salet.view.writeVerbs()
|
||||
|
||||
if @afterChoices?
|
||||
@afterChoices.fcall(this, f)
|
||||
$(document).trigger("room_#{@name}_after_choices")
|
||||
if @afterChoices
|
||||
salet.view.write markdown(@afterChoices.fcall(this, f))
|
||||
|
||||
if salet.autosave and @canSave
|
||||
salet.saveGame()
|
||||
|
@ -124,7 +131,7 @@ class SaletRoom
|
|||
retval += markdown(dsc)
|
||||
|
||||
unitDescriptions = []
|
||||
for thing in @units
|
||||
for thing in @inventory
|
||||
if thing.name and typeof(thing.look) == "function" and thing.look(f)
|
||||
unitDescriptions.push ({
|
||||
order: thing.order,
|
||||
|
@ -140,20 +147,6 @@ class SaletRoom
|
|||
|
||||
return markdown(retval)
|
||||
|
||||
###
|
||||
Places a unit in this room.
|
||||
###
|
||||
@take = (thing) =>
|
||||
thing.location = @name
|
||||
@units.push(thing)
|
||||
|
||||
@drop = (name) =>
|
||||
for thing in @units
|
||||
if thing.name == name
|
||||
@units.splice(@units.indexOf(thing), 1)
|
||||
thing.location = null
|
||||
return @units
|
||||
|
||||
###
|
||||
Unit action. A function or a string which comes when you click on a link in unit description.
|
||||
You could interpret this as an EXAMINE verb or USE one, it's your call.
|
||||
|
@ -162,7 +155,7 @@ class SaletRoom
|
|||
if (link = action.match(/^_(act|cycle|inv)_(.+)$/)) #unit action
|
||||
if link[1] == "inv"
|
||||
return salet.view.write salet.character.inv(link[2])
|
||||
for thing in @units
|
||||
for thing in @inventory
|
||||
if thing.name == link[2]
|
||||
if link[1] == "act"
|
||||
# If it's takeable, the player can take this unit.
|
||||
|
|
145
src/salet.coffee
145
src/salet.coffee
|
@ -24,58 +24,12 @@ class Salet
|
|||
# The unique id of the starting room.
|
||||
@start = "start"
|
||||
|
||||
# Regular expression to catch every link action.
|
||||
# Salet's default is a general URL-safe expression.
|
||||
@linkRe = /^([0-9A-Za-z_-]+|\.)(\/([0-9A-Za-z_-]+))?$/
|
||||
|
||||
###
|
||||
This function is called at the start of the game. It is
|
||||
normally overridden to provide initial character creation
|
||||
(setting initial quality values, setting the
|
||||
character-text. This is optional, however, as set-up
|
||||
processing could also be done by the first room's
|
||||
enter function.
|
||||
# This variable is set to false before triggering "before_action" event.
|
||||
# If any of the user-defined triggers set it to true,
|
||||
# Salet won't execute the action.
|
||||
###
|
||||
@init = () ->
|
||||
|
||||
###
|
||||
This function is called before entering any new
|
||||
room. It is called before the corresponding room
|
||||
has its `enter` method called.
|
||||
###
|
||||
@enter = (oldSituationId, newSituationId) ->
|
||||
|
||||
###
|
||||
Hook for when the room has already been carried out
|
||||
and printed.
|
||||
###
|
||||
@afterEnter = (oldSituationId, newSituationId) ->
|
||||
|
||||
###
|
||||
This function is called before carrying out any action in
|
||||
any room. It is called before the corresponding
|
||||
room has its `act` method called.
|
||||
|
||||
If the function returns true, then it is indicating that it
|
||||
has consumed the action, and the action will not be passed
|
||||
on to the room. Note that this is the only one of
|
||||
these global handlers that can consume the event.
|
||||
###
|
||||
@beforeAction = (roomId, actionId) ->
|
||||
|
||||
###
|
||||
This function is called after carrying out any action in
|
||||
any room. It is called after the corresponding
|
||||
room has its `act` method called.
|
||||
###
|
||||
@afterAction = (roomId, actionId) ->
|
||||
|
||||
###
|
||||
This function is called after leaving any room. It is
|
||||
called after the corresponding room has its `exit`
|
||||
method called.
|
||||
###
|
||||
@exit = (oldSituationId, newSituationId) ->
|
||||
@actionConsumed = false
|
||||
|
||||
###
|
||||
Returns a list of room ids to choose from, given a set of
|
||||
|
@ -243,7 +197,7 @@ class Salet
|
|||
each one, and processLink manages this.
|
||||
###
|
||||
@processOneLink = (code) ->
|
||||
match = code.match(@linkRe)
|
||||
match = code.match(@view.linkRe)
|
||||
if not match
|
||||
console.error "link_not_valid".l()
|
||||
console.error code
|
||||
|
@ -264,17 +218,20 @@ class Salet
|
|||
if (action)
|
||||
room = @getCurrentRoom()
|
||||
if room
|
||||
consumed = false
|
||||
@actionConsumed = false
|
||||
|
||||
if @beforeAction
|
||||
# Try the global act handler
|
||||
consumed = @beforeAction(room, action)
|
||||
$(document).trigger("before_action", {
|
||||
"room": room
|
||||
"action": action
|
||||
})
|
||||
|
||||
if consumed != true
|
||||
if @actionConsumed == false
|
||||
room.act(action)
|
||||
|
||||
if @afterAction
|
||||
@afterAction(room, action)
|
||||
$(document).trigger("after_action", {
|
||||
"room": room
|
||||
"action": action
|
||||
})
|
||||
|
||||
@view.append timerResponse
|
||||
|
||||
|
@ -285,7 +242,7 @@ class Salet
|
|||
|
||||
# don't save any actions in the room we can't save in
|
||||
# and remember that the action of entering the start room is always saved
|
||||
match = code.match(@linkRe)
|
||||
match = code.match(@view.linkRe)
|
||||
room = match[1]
|
||||
if room
|
||||
if room == '.'
|
||||
|
@ -297,11 +254,34 @@ class Salet
|
|||
# don't save
|
||||
return @processLink(code)
|
||||
|
||||
@progress.sequence.push({link:code, when:@time})
|
||||
@progress.sequence.push({
|
||||
link:code,
|
||||
when:@time
|
||||
})
|
||||
if @getRoom(code)? # if it's a room
|
||||
@progress.path.push(code)
|
||||
@processLink(code)
|
||||
|
||||
# This gets called when the user clicks a link to carry out a verb on a unit.
|
||||
@processVerb = (code) ->
|
||||
now = (new Date()).getTime() * 0.001
|
||||
@time = now - @startTime
|
||||
|
||||
# don't save any actions in the room we can't save in
|
||||
# and remember that the action of entering the start room is always saved
|
||||
match = code.match(@view.verbRe)
|
||||
verb = match[1]
|
||||
unit = match[2]
|
||||
room = @getCurrentRoom()
|
||||
assert(room, "unknown_room".l({id:room}))
|
||||
|
||||
if room.canSave
|
||||
@progress.sequence.push({
|
||||
link:code,
|
||||
when:@time
|
||||
})
|
||||
# TODO: find a unit in current room, execute its "verb" method
|
||||
|
||||
# Go back N rooms. It's not an UNDO.
|
||||
# Also, steps = 1 is the current room
|
||||
@goBack = (steps = 2) ->
|
||||
|
@ -320,21 +300,14 @@ class Salet
|
|||
|
||||
assert(newRoom, "unknown_room".l({id:newRoomId}))
|
||||
|
||||
# We might not have an old situation if this is the start of the game.
|
||||
if (oldRoom and @exit)
|
||||
@exit(oldRoomId, newRoomId, force)
|
||||
|
||||
@current = newRoomId
|
||||
|
||||
# A global callback before entering
|
||||
if (@enter)
|
||||
@enter(oldRoomId, newRoomId, force)
|
||||
|
||||
newRoom.entering(oldRoomId, force)
|
||||
|
||||
# additional hook for when the situation text has already been printed
|
||||
if (@afterEnter)
|
||||
@afterEnter(oldRoomId, newRoomId, force)
|
||||
$(document).trigger("room_#{newRoomId}_after_enter", {
|
||||
"from": oldRoomId,
|
||||
"force": force
|
||||
})
|
||||
|
||||
###
|
||||
Erases the character in local storage. This is permanent!
|
||||
|
@ -366,6 +339,11 @@ class Salet
|
|||
now = (new Date()).getTime() * 0.001
|
||||
@progress.saveTime = now - @startTime
|
||||
|
||||
$(document).trigger("saveGame", {
|
||||
"id": @getSaveId()
|
||||
"progress": @progress
|
||||
})
|
||||
|
||||
# Save the game.
|
||||
localStorage.setItem(@getSaveId(), JSON.stringify({
|
||||
progress: @progress
|
||||
|
@ -386,8 +364,12 @@ class Salet
|
|||
|
||||
@rnd = new Random(@progress.seed)
|
||||
|
||||
$(document).trigger("loadGame", {
|
||||
"progress": @progress
|
||||
})
|
||||
|
||||
# Start the game now
|
||||
@init()
|
||||
$(document).trigger("init")
|
||||
|
||||
# Run through all the player's history.
|
||||
@interactive = false
|
||||
|
@ -414,6 +396,7 @@ class Salet
|
|||
return saveFile
|
||||
|
||||
@beginGame = () ->
|
||||
@view.init()
|
||||
@view.fixClicks()
|
||||
|
||||
# Handle storage.
|
||||
|
@ -436,7 +419,7 @@ class Salet
|
|||
|
||||
# Start the game
|
||||
@startTime = new Date().getTime() * 0.001
|
||||
@init()
|
||||
$(document).trigger("init")
|
||||
|
||||
# Do the first state.
|
||||
@doTransitionTo(@start)
|
||||
|
@ -457,17 +440,14 @@ class Salet
|
|||
|
||||
@timers = {}
|
||||
|
||||
# Adds a one-time timer <name> that will fire after <steps> clicks
|
||||
# with <action>.
|
||||
# Adds a timer <name> that will fire after <steps> clicks
|
||||
# @param name string timer ID
|
||||
# @param repeat boolean should it repeat every <step> steps or not
|
||||
# @param action string or function code to call
|
||||
# @param step integer number of steps
|
||||
@addTimer = (name, action, repeatable = false, step = 1) ->
|
||||
@addTimer = (name, repeatable = false, step = 1) ->
|
||||
@timers[name] = {
|
||||
step: step
|
||||
repeatable: repeatable
|
||||
action: action
|
||||
set: @progress.sequence.length
|
||||
}
|
||||
return @timers
|
||||
|
@ -484,15 +464,20 @@ class Salet
|
|||
response = ""
|
||||
for tname, timer of @timers
|
||||
if ((@progress.sequence.length - timer.set) == timer.step)
|
||||
response += "\n\n"+timer.action.fcall(this)
|
||||
$(document).trigger("timer_#{tname}")
|
||||
if !timer.repeatable
|
||||
@dropTimer(tname)
|
||||
return response
|
||||
|
||||
# An object in the format of:
|
||||
# "index": "text",
|
||||
# i.e. "examine": "Examine"
|
||||
# Salet enters verb mode if @choices is empty and @verbs is not.
|
||||
@verbs = {}
|
||||
|
||||
for index, value of spec
|
||||
this[index] = value
|
||||
|
||||
return this
|
||||
|
||||
window.salet = new Salet()
|
||||
salet.view.init()
|
||||
|
|
|
@ -15,9 +15,6 @@ assert = (assertion, msg) -> console.assert assertion, msg
|
|||
way_to = (content, ref) ->
|
||||
return "<a href='#{ref}' class='way' id='waylink-#{ref}'>#{content}</a>"
|
||||
|
||||
invlink = (content, ref) ->
|
||||
return "<a href='./_inv_#{ref}' class='once'>#{content.fcall()}</a>"
|
||||
|
||||
Array::remove = (e) -> @[t..t] = [] if (t = @indexOf(e)) > -1
|
||||
|
||||
addClass = (element, className) ->
|
||||
|
@ -36,3 +33,13 @@ parsedsc = (text, name) ->
|
|||
window.unitname = undefined
|
||||
return unitlink(p1, name)
|
||||
return text
|
||||
|
||||
# Print a link to the thing, if the container has it
|
||||
window.listinv = (thing, container = undefined) =>
|
||||
container ?= salet.character.inventory
|
||||
for i in container
|
||||
if i.name == thing
|
||||
return invlink(i.display.fcall(i), i.name)
|
||||
|
||||
invlink = (content, ref) ->
|
||||
return "<a href='./_inv_#{ref}' class='once'>#{content.fcall()}</a>"
|
||||
|
|
|
@ -15,18 +15,28 @@ There is only one instance of this class, and it's stored as `salet.view`.
|
|||
class SaletView
|
||||
constructor: (spec) ->
|
||||
@init = () ->
|
||||
$(document).trigger("viewinit")
|
||||
$("#page").on("click", "a", (event) ->
|
||||
event.preventDefault()
|
||||
a = $(this)
|
||||
href = a.attr('href')
|
||||
if a.hasClass("once") || href.match(/[?&]once[=&]?/)
|
||||
salet.view.clearLinks(href)
|
||||
if href.match(salet.linkRe)
|
||||
salet.processClick(href)
|
||||
if href.match(salet.view.linkRe) != null
|
||||
event.preventDefault()
|
||||
return salet.processClick(href)
|
||||
else if href.match(salet.view.verbRe) != null
|
||||
event.preventDefault()
|
||||
return salet.processVerb(href)
|
||||
)
|
||||
$("#load").on("click", "a", (event) ->
|
||||
window.location.reload()
|
||||
)
|
||||
$(document).on("click", "#verbs li", () ->
|
||||
verb = $(this).data("verb")
|
||||
for unitname, unit of salet.here().units
|
||||
if unit[verb]?
|
||||
@writeVerbAction(verb, unitname, text)
|
||||
)
|
||||
if (@hasLocalStorage())
|
||||
$(document).on("click", "#erase", (event) ->
|
||||
event.preventDefault()
|
||||
|
@ -36,6 +46,18 @@ class SaletView
|
|||
event.preventDefault()
|
||||
return salet.saveGame()
|
||||
)
|
||||
|
||||
# Regular expression to catch every link action.
|
||||
# Salet's default is a general URL-safe expression.
|
||||
@linkRe = /^([0-9A-Za-z_-]+|\.)(\/([0-9A-Za-z_-]+))?$/
|
||||
|
||||
# Regular expression to catch every verb action.
|
||||
@verbRe = /^verb\_(\w+)\_(\w+)$/
|
||||
|
||||
# Add a verb action to the list of verb actions
|
||||
@writeVerbAction = (verb, unitname, text) ->
|
||||
$("#actions").append("<li><a href='verb_#{verb}_#{unitname}'>#{text}</a></li>")
|
||||
|
||||
@disableSaving = () ->
|
||||
$("#save").addClass('disabled')
|
||||
@enableSaving = () ->
|
||||
|
@ -69,6 +91,7 @@ class SaletView
|
|||
but the element itself remains, ready to be filled again using @write.
|
||||
###
|
||||
@clearContent = (elementSelector = "#content") ->
|
||||
$(document).trigger("clear_content", elementSelector)
|
||||
if (elementSelector == "#content") # empty the intro with the content
|
||||
intro = document.getElementById("intro")
|
||||
if intro?
|
||||
|
@ -140,6 +163,11 @@ class SaletView
|
|||
a.replaceWith($("<span>").addClass("ex_link").html(a.html()))
|
||||
return true
|
||||
|
||||
@clearChoices = () ->
|
||||
choices = document.querySelector("#choices")
|
||||
if choices?
|
||||
choices.innerHTML = ""
|
||||
|
||||
###
|
||||
Given a list of room ids, this outputs a standard option
|
||||
block with the room choices in the given order.
|
||||
|
@ -177,8 +205,17 @@ class SaletView
|
|||
$a.html(optionText)
|
||||
$option.html($a)
|
||||
$options.append($option)
|
||||
# if there is a designated block for this, print choices in the block
|
||||
if ($("#choices").length == 1)
|
||||
@replace($options, "#choices")
|
||||
else
|
||||
@write($options)
|
||||
|
||||
@writeVerbs = () ->
|
||||
$("#verbs").html("")
|
||||
for verb, text of salet.verbs
|
||||
$("#verbs").append("<li data-verb='#{verb}'>#{text}</li>")
|
||||
|
||||
# Marks all links as old. This gets called in a `processLink` function.
|
||||
@mark_all_links_old = () ->
|
||||
$('#page .new').removeClass('new')
|
||||
|
@ -286,6 +323,7 @@ class SaletView
|
|||
@showBlock(".ways #ways_hint")
|
||||
else
|
||||
@hideBlock(".ways #ways_hint", false)
|
||||
|
||||
@cycleLink = (content) ->
|
||||
return "<a href='./_replacer_cyclewriter' class='cycle' id='cyclewriter'>#{content}</a>"
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ $(document).ready(function() {
|
|||
salet.character.take(lamp);
|
||||
assert.equal(salet.character.has("lamp"), true, "The character has the lamp now");
|
||||
assert.equal(salet.character.inv("lamp"), "that's a lamp", "The lamp has an inventory action");
|
||||
assert.ok(salet.character.listinv("lamp").match("lamp description"), "The lamp has a description");
|
||||
assert.ok(listinv("lamp").match("lamp description"), "The lamp has a description");
|
||||
salet.character.drop("lamp");
|
||||
assert.equal(salet.character.has("lamp"), false, "The character has no lamp again");
|
||||
return;
|
||||
|
|
317
yarn.lock
Normal file
317
yarn.lock
Normal file
|
@ -0,0 +1,317 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
ansi-regex@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
|
||||
ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
|
||||
babel-code-frame@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
|
||||
dependencies:
|
||||
chalk "^1.1.3"
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^3.0.2"
|
||||
|
||||
babel-core@^6, babel-core@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8"
|
||||
dependencies:
|
||||
babel-code-frame "^6.26.0"
|
||||
babel-generator "^6.26.0"
|
||||
babel-helpers "^6.24.1"
|
||||
babel-messages "^6.23.0"
|
||||
babel-register "^6.26.0"
|
||||
babel-runtime "^6.26.0"
|
||||
babel-template "^6.26.0"
|
||||
babel-traverse "^6.26.0"
|
||||
babel-types "^6.26.0"
|
||||
babylon "^6.18.0"
|
||||
convert-source-map "^1.5.0"
|
||||
debug "^2.6.8"
|
||||
json5 "^0.5.1"
|
||||
lodash "^4.17.4"
|
||||
minimatch "^3.0.4"
|
||||
path-is-absolute "^1.0.1"
|
||||
private "^0.1.7"
|
||||
slash "^1.0.0"
|
||||
source-map "^0.5.6"
|
||||
|
||||
babel-generator@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5"
|
||||
dependencies:
|
||||
babel-messages "^6.23.0"
|
||||
babel-runtime "^6.26.0"
|
||||
babel-types "^6.26.0"
|
||||
detect-indent "^4.0.0"
|
||||
jsesc "^1.3.0"
|
||||
lodash "^4.17.4"
|
||||
source-map "^0.5.6"
|
||||
trim-right "^1.0.1"
|
||||
|
||||
babel-helpers@^6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
babel-template "^6.24.1"
|
||||
|
||||
babel-messages@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-register@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
|
||||
dependencies:
|
||||
babel-core "^6.26.0"
|
||||
babel-runtime "^6.26.0"
|
||||
core-js "^2.5.0"
|
||||
home-or-tmp "^2.0.0"
|
||||
lodash "^4.17.4"
|
||||
mkdirp "^0.5.1"
|
||||
source-map-support "^0.4.15"
|
||||
|
||||
babel-runtime@^6.22.0, babel-runtime@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
||||
dependencies:
|
||||
core-js "^2.4.0"
|
||||
regenerator-runtime "^0.11.0"
|
||||
|
||||
babel-template@^6.24.1, babel-template@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
babel-traverse "^6.26.0"
|
||||
babel-types "^6.26.0"
|
||||
babylon "^6.18.0"
|
||||
lodash "^4.17.4"
|
||||
|
||||
babel-traverse@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
|
||||
dependencies:
|
||||
babel-code-frame "^6.26.0"
|
||||
babel-messages "^6.23.0"
|
||||
babel-runtime "^6.26.0"
|
||||
babel-types "^6.26.0"
|
||||
babylon "^6.18.0"
|
||||
debug "^2.6.8"
|
||||
globals "^9.18.0"
|
||||
invariant "^2.2.2"
|
||||
lodash "^4.17.4"
|
||||
|
||||
babel-types@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
esutils "^2.0.2"
|
||||
lodash "^4.17.4"
|
||||
to-fast-properties "^1.0.3"
|
||||
|
||||
babylon@^6.18.0:
|
||||
version "6.18.0"
|
||||
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
chalk@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
||||
dependencies:
|
||||
ansi-styles "^2.2.1"
|
||||
escape-string-regexp "^1.0.2"
|
||||
has-ansi "^2.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
coffeescript@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-2.0.0.tgz#61bcc70989cc18a0aab6b3d8be110d2ec7743c9a"
|
||||
optionalDependencies:
|
||||
babel-core "^6"
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
|
||||
convert-source-map@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
|
||||
|
||||
core-js@^2.4.0, core-js@^2.5.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
|
||||
|
||||
debug@^2.6.8:
|
||||
version "2.6.8"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
detect-indent@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
|
||||
dependencies:
|
||||
repeating "^2.0.0"
|
||||
|
||||
escape-string-regexp@^1.0.2:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||
|
||||
globals@^9.18.0:
|
||||
version "9.18.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
home-or-tmp@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
|
||||
dependencies:
|
||||
os-homedir "^1.0.0"
|
||||
os-tmpdir "^1.0.1"
|
||||
|
||||
invariant@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
|
||||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
|
||||
is-finite@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
|
||||
dependencies:
|
||||
number-is-nan "^1.0.0"
|
||||
|
||||
js-tokens@^3.0.0, js-tokens@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
|
||||
|
||||
jsesc@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
|
||||
|
||||
json5@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
||||
|
||||
lodash@^4.17.4:
|
||||
version "4.17.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||
|
||||
loose-envify@^1.0.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||
dependencies:
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||
|
||||
mkdirp@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
dependencies:
|
||||
minimist "0.0.8"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
|
||||
number-is-nan@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
||||
|
||||
os-homedir@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
|
||||
|
||||
os-tmpdir@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
|
||||
path-is-absolute@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
|
||||
private@^0.1.7:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"
|
||||
|
||||
regenerator-runtime@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1"
|
||||
|
||||
repeating@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
|
||||
dependencies:
|
||||
is-finite "^1.0.0"
|
||||
|
||||
slash@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
|
||||
|
||||
source-map-support@^0.4.15:
|
||||
version "0.4.18"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
|
||||
dependencies:
|
||||
source-map "^0.5.6"
|
||||
|
||||
source-map@^0.5.6:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
|
||||
strip-ansi@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
|
||||
to-fast-properties@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
|
||||
|
||||
trim-right@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
|
Loading…
Reference in a new issue