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

Proper variables and putting things

This commit is contained in:
Alexander Yakovlev 2016-02-10 20:35:44 +07:00
parent 43c66af5a6
commit 2b0f714ac0
7 changed files with 388 additions and 366 deletions

View file

@ -4,10 +4,10 @@ dialogue = require('../../lib/dialogue.coffee')
oneOf = require('../../lib/oneOf.coffee') oneOf = require('../../lib/oneOf.coffee')
Salet = require('../../lib/salet.coffee') Salet = require('../../lib/salet.coffee')
salet = new Salet salet = Salet({
salet.view.init(salet) game_id: "your-game-id-here"
salet.game_id = "your-game-id-here" game_version: "1.0"
salet.game_version = "1.0" })
$(document).ready(() -> $(document).ready(() ->
salet.beginGame() salet.beginGame()
) )

View file

@ -86,10 +86,10 @@ room "shop-inside", salet,
The insides are painted pastel white, honouring The Great Milk Spill of 1985. The insides are painted pastel white, honouring The Great Milk Spill of 1985.
""" """
objects: [ objects: [
merchant: obj "merchant", obj "merchant",
dsc: "A {{merchant}} eyes you warily." dsc: "A {{merchant}} eyes you warily."
takeable: false takeable: false
act: (system) => act: (salet) =>
salet.processClick("merchdialogue") salet.processClick("merchdialogue")
return "" return ""
] ]
@ -100,7 +100,7 @@ The chain of calls is very weird and this puts an object IN EVERY ROOM for God's
I need someone smarter than me to fix this. I need someone smarter than me to fix this.
### ###
lamp = obj "lamp", salet, lamp = obj "lamp",
takeable: true takeable: true
lamp.put(salet, "shop-inside") lamp.put(salet, "shop-inside")

21
lib/character.coffee Normal file
View file

@ -0,0 +1,21 @@
class Character
constructor: (spec) ->
@inventory = []
@take = (thing) =>
@inventory.push thing
@drop = (thing) =>
for i in @inventory
if i.name == thing
index = @objects.indexOf(thing)
@inventory.splice(index, 1)
for index, value of spec
this[index] = value
return this
character = (spec) ->
spec ?= {}
return( new Character(spec) )
module.exports = character

View file

@ -40,6 +40,8 @@ class SaletObj
if salet.rooms[location]? if salet.rooms[location]?
@location = location @location = location
salet.rooms[location].take(this) salet.rooms[location].take(this)
else
console.log("Could not find location #{location} for an object #{@name}")
@delete = (salet, location = false) => @delete = (salet, location = false) =>
if location == false if location == false
location = @location location = @location

View file

@ -144,7 +144,7 @@ class SaletRoom
Puts an object in this room. Puts an object in this room.
### ###
@take = (thing) => @take = (thing) =>
@objects[thing.name] = thing @objects.push(thing)
@drop = (name) => @drop = (name) =>
for thing in @objects for thing in @objects
@ -164,7 +164,8 @@ 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
system.character.inventory.push thing console.log system
system.character.take(thing)
@drop name @drop name
system.view.clearContent() system.view.clearContent()
@entering.fcall(this, system, @name) @entering.fcall(this, system, @name)

View file

@ -1,6 +1,7 @@
markdown = require('./markdown.coffee') markdown = require('./markdown.coffee')
SaletView = require('./view.coffee') SaletView = require('./view.coffee')
Random = require('./random.js') Random = require('./random.js')
character = require('./character.coffee')
languages = require('./localize.coffee') languages = require('./localize.coffee')
### ###
@ -17,9 +18,6 @@ String.prototype.fcall = () ->
assert = (msg, assertion) -> console.assert assertion, msg assert = (msg, assertion) -> console.assert assertion, msg
class Character
inventory: []
### ###
This is the control structure, it has minimal amount of data and This is the control structure, it has minimal amount of data and
this data is volatile anyway (as in, it won't get saved). this data is volatile anyway (as in, it won't get saved).
@ -27,25 +25,26 @@ this data is volatile anyway (as in, it won't get saved).
There is only one instance of this class. There is only one instance of this class.
### ###
class Salet class Salet
# REDEFINE THIS IN YOUR GAME constructor: (spec) ->
game_id: null @character = character()
game_version: "1.0"
autosave: true
rnd: null # REDEFINE THIS IN YOUR GAME
time: 0 @game_id = null
@game_version = "1.0"
@autosave = true
@rnd = null
@time = 0
# Corresponding room names to room objects. # Corresponding room names to room objects.
rooms: {} @rooms = {}
# The unique id of the starting room. # The unique id of the starting room.
start: "start" @start = "start"
# 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.
linkRe: /^([0-9A-Za-z_-]+|\.)(\/([0-9A-Za-z_-]+))?$/ @linkRe = /^([0-9A-Za-z_-]+|\.)(\/([0-9A-Za-z_-]+))?$/
character: new Character
### ###
This function is called at the start of the game. It is This function is called at the start of the game. It is
@ -55,20 +54,20 @@ class Salet
processing could also be done by the first situation's processing could also be done by the first situation's
enter function. enter function.
### ###
init: () -> @init = () ->
### ###
This function is called before entering any new This function is called before entering any new
situation. It is called before the corresponding situation situation. It is called before the corresponding situation
has its `enter` method called. has its `enter` method called.
### ###
enter: (oldSituationId, newSituationId) -> @enter = (oldSituationId, newSituationId) ->
### ###
Hook for when the situation has already been carried out Hook for when the situation has already been carried out
and printed. and printed.
### ###
afterEnter: (oldSituationId, newSituationId) -> @afterEnter = (oldSituationId, newSituationId) ->
### ###
This function is called before carrying out any action in This function is called before carrying out any action in
@ -80,21 +79,21 @@ class Salet
on to the situation. Note that this is the only one of on to the situation. Note that this is the only one of
these global handlers that can consume the event. these global handlers that can consume the event.
### ###
beforeAction: (situationId, actionId) -> @beforeAction = (situationId, actionId) ->
### ###
This function is called after carrying out any action in This function is called after carrying out any action in
any situation. It is called after the corresponding any situation. It is called after the corresponding
situation has its `act` method called. situation has its `act` method called.
### ###
afterAction: (situationId, actionId) -> @afterAction = (situationId, actionId) ->
### ###
This function is called after leaving any situation. It is This function is called after leaving any situation. It is
called after the corresponding situation has its `exit` called after the corresponding situation has its `exit`
method called. method called.
### ###
exit: (oldSituationId, newSituationId) -> @exit = (oldSituationId, newSituationId) ->
### ###
Returns a list of situation ids to choose from, given a set of Returns a list of situation ids to choose from, given a set of
@ -124,23 +123,12 @@ class Salet
more than this number of results possible, then the highest more than this number of results possible, then the highest
priority resuls will be guaranteed to be returned, but the priority resuls will be guaranteed to be returned, but the
lowest priority group will have to fight it out for the lowest priority group will have to fight it out for the
remaining places. In this case, a random sample is chosen, remaining places.
taking into account the frequency of each situation. So a
situation with a frequency of 100 will be chosen 100 times more
often than a situation with a frequency of 1, if there is one
space available. Often these frequencies have to be taken as a
guideline, and the actual probabilities will only be
approximate. Consider three situations with frequencies of 1,
1, 100, competing for two spaces. The 100-frequency situation
will be chosen almost every time, but for the other space, one
of the 1-frequency situations must be chosen. So the actual
probabilities will be roughly 50%, 50%, 100%. When selecting
more than one result, frequencies can only be a guide.
Before this function returns its result, it sorts the Before this function returns its result, it sorts the
situations in increasing order of their displayOrder values. situations in increasing order of their displayOrder values.
### ###
getSituationIdChoices: (listOfOrOneIdsOrTags, maxChoices) => @getSituationIdChoices = (listOfOrOneIdsOrTags, maxChoices) =>
datum = null datum = null
i = 0 i = 0
@ -202,7 +190,7 @@ class Salet
return result return result
# This is the data on the player's progress that gets saved. # This is the data on the player's progress that gets saved.
progress: { @progress = {
# A random seed string, used internally to make random # A random seed string, used internally to make random
# sequences predictable. # sequences predictable.
seed: null seed: null
@ -212,30 +200,30 @@ class Salet
saveTime: null saveTime: null
} }
# The Id of the current situation the player is in. # The Id of the current room the player is in.
current: null; @current = null
# Tracks whether we're in interactive mode or batch mode. # Tracks whether we're in interactive mode or batch mode.
interactive: true @interactive = true
# The system time when the game was initialized. # The system time when the game was initialized.
startTime: null @startTime = null
# The stack of links, resulting from the last action, still be to resolved. # The stack of links, resulting from the last action, still be to resolved.
linkStack: null @linkStack = null
getCurrentRoom: () => @getCurrentRoom = () =>
if (@current) if (@current)
return @rooms[@current] return @rooms[@current]
return null return null
# Gets the unique id used to identify saved games. # Gets the unique id used to identify saved games.
getSaveId: (slot = "") => @getSaveId = (slot = "") =>
return 'salet_'+@game_id+'_'+@game_version#+'_'+slot return 'salet_'+@game_id+'_'+@game_version#+'_'+slot
# This gets called when a link needs to be followed, regardless # This gets called when a link needs to be followed, regardless
# of whether it was user action that initiated it. # of whether it was user action that initiated it.
processLink: (code) => @processLink = (code) =>
# Check if we should do this now, or if processing is already underway. # Check if we should do this now, or if processing is already underway.
if @linkStack != null if @linkStack != null
@linkStack.push(code) @linkStack.push(code)
@ -261,7 +249,7 @@ class Salet
# We're able to save, if we weren't already. # We're able to save, if we weren't already.
@view.enableSaving() @view.enableSaving()
goTo: (roomId) => @goTo = (roomId) =>
return @processLink(roomId) return @processLink(roomId)
### ###
@ -270,7 +258,7 @@ class Salet
code that further calls doLink, and so on. This method processes code that further calls doLink, and so on. This method processes
each one, and processLink manages this. each one, and processLink manages this.
### ###
processOneLink: (code) => @processOneLink = (code) =>
match = code.match(@linkRe) match = code.match(@linkRe)
assert(match, "link_not_valid".l({link:code})) assert(match, "link_not_valid".l({link:code}))
@ -297,14 +285,14 @@ class Salet
@afterAction(this, room, 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) =>
now = (new Date()).getTime() * 0.001 now = (new Date()).getTime() * 0.001
@time = now - @startTime @time = now - @startTime
@progress.sequence.push({link:code, when:@time}) @progress.sequence.push({link:code, when:@time})
@processLink(code) @processLink(code)
# Transitions between situations. # Transition between rooms.
doTransitionTo: (newRoomId) => @doTransitionTo = (newRoomId) =>
oldRoomId = @current oldRoomId = @current
oldRoom = @getCurrentRoom() oldRoom = @getCurrentRoom()
newRoom = @rooms[newRoomId] newRoom = @rooms[newRoomId]
@ -336,14 +324,14 @@ class Salet
game state across save/erase cycles, meaning that character.sandbox game state across save/erase cycles, meaning that character.sandbox
no longer has to be the end-all be-all repository of game state. no longer has to be the end-all be-all repository of game state.
### ###
eraseSave: (force = false) => @eraseSave = (force = false) =>
saveId = @getSaveId() # save slot saveId = @getSaveId() # save slot
if (localStorage.getItem(saveId) and (force or confirm("erase_message".l()))) if (localStorage.getItem(saveId) and (force or confirm("erase_message".l())))
localStorage.removeItem(saveId) localStorage.removeItem(saveId)
window.location.reload() window.location.reload()
# Find and return a list of ids for all situations with the given tag. # Find and return a list of ids for all situations with the given tag.
getRoomsTagged: (tag) => @getRoomsTagged = (tag) =>
result = [] result = []
for id, room of @rooms for id, room of @rooms
for i in room.tags for i in room.tags
@ -353,7 +341,7 @@ class Salet
return result return result
# Saves the character and the walking history to local storage. # Saves the character and the walking history to local storage.
saveGame: () => @saveGame = () =>
# Store when we're saving the game, to avoid exploits where a # Store when we're saving the game, to avoid exploits where a
# player loads their file to gain extra time. # player loads their file to gain extra time.
now = (new Date()).getTime() * 0.001 now = (new Date()).getTime() * 0.001
@ -371,7 +359,7 @@ class Salet
@view.enableLoading() @view.enableLoading()
# Loads the game from the given data # Loads the game from the given data
loadGame: (saveFile) => @loadGame = (saveFile) =>
@progress = saveFile.progress @progress = saveFile.progress
@character = saveFile.character @character = saveFile.character
@ -398,9 +386,9 @@ class Salet
now = new Date().getTime() * 0.001 now = new Date().getTime() * 0.001
startTime = now - @progress.saveTime startTime = now - @progress.saveTime
view: new SaletView @view = new SaletView
beginGame: () => @beginGame = () =>
@view.fixClicks() @view.fixClicks()
# Handle storage. # Handle storage.
@ -432,16 +420,25 @@ class Salet
# Do the first state. # Do the first state.
@doTransitionTo(@start) @doTransitionTo(@start)
getRoom: (name) => @getRoom = (name) => @rooms[name]
return @rooms[name]
# Just an alias for getCurrentRoom # Just an alias for getCurrentRoom
here: () => @getCurrentRoom() @here = () => @getCurrentRoom()
isVisited: (name) => @isVisited = (name) =>
place = @getRoom(name) place = @getRoom(name)
if place if place
return Boolean place.visited return Boolean place.visited
return 0 return 0
module.exports = Salet for index, value of spec
this[index] = value
return this
salet = (spec) ->
spec ?= {}
retval = new Salet(spec)
retval.view.init(retval)
return retval
module.exports = salet

View file

@ -271,6 +271,7 @@ class SaletView
key: way key: way
distance: salet.rooms[way].distance distance: salet.rooms[way].distance
}) })
document.querySelector(".ways h2").style.display = "block"
else else
document.querySelector(".ways h2").style.display = "none" document.querySelector(".ways h2").style.display = "none"
document.getElementById("ways").innerHTML = content document.getElementById("ways").innerHTML = content