0
0
Fork 0
mirror of https://gitlab.com/Oreolek/salet-module.git synced 2024-07-05 08:14:23 +03:00

More untested conversions WIP

This commit is contained in:
Alexander Yakovlev 2016-01-23 18:31:03 +07:00
parent e54585cdbc
commit c48c1ff11e

View file

@ -20,7 +20,7 @@ parseFn = (str) ->
#{str} #{str}
#}) #})
""" """
return eval(fstr); return eval(fstr)
# Scrolls the top of the screen to the specified point # Scrolls the top of the screen to the specified point
scrollTopTo = (value) -> scrollTopTo = (value) ->
@ -63,143 +63,6 @@ augmentLinks = (content) ->
) )
return output return output
/* Erases the character in local storage. This is permanent!
/* To restart the game afterwards, we perform a simple page refresh.
/* This guarantees authors don't have to care about "tainting" the
/* game state across save/erase cycles, meaning that character.sandbox
/* no longer has to be the end-all be-all repository of game state. */
var doErase = function(force) {
var saveId = getSaveId();
if (localStorage.getItem(saveId)) {
if (force || confirm("erase_message".l())) {
localStorage.removeItem(saveId);
window.location.reload();
}
}
};
/* Find and return a list of ids for all situations with the given tag. */
var getSituationIdsWithTag = function(tag) {
var result = [];
for (var situationId in game.situations) {
var situation = game.situations[situationId];
for (var i = 0; i < situation.tags.length; ++i) {
if (situation.tags[i] == tag) {
result.push(situationId);
break;
}
}
}
return result;
};
/* Clear the current game output and start again. */
var startGame = function() {
progress.seed = new Date().toString();
character = new Character();
system.rnd = new Random(progress.seed);
progress.sequence = [{link:game.start, when:0}];
// Empty the display
$("#content").empty();
// Start the game
startTime = new Date().getTime() * 0.001;
system.time = 0;
if (game.init) game.init(character, system);
// Do the first state.
doTransitionTo(game.start);
};
/* Saves the character to local storage. */
var saveGame = function() {
// Store when we're saving the game, to avoid exploits where a
// player loads their file to gain extra time.
var now = (new Date()).getTime() * 0.001;
progress.saveTime = now - startTime;
// Save the game.
localStorage.setItem(getSaveId(), JSON.stringify(progress));
// Switch the button highlights.
$("#erase").removeClass('disabled');
$("#load").removeClass('disabled');
$("#save").addClass('disabled');
};
/* Loads the game from the given data */
var loadGame = function(characterData) {
progress = characterData;
character = new Character();
system.rnd = new Random(progress.seed);
// Empty the display
$("#content").empty();
$("#intro").empty();
// Now play through the actions so far:
if (game.init) game.init(character, system);
// Run through all the player's history.
interactive = false;
for (var i = 0; i < progress.sequence.length; i++) {
var step = progress.sequence[i];
// The action must be done at the recorded time.
system.time = step.when;
processLink(step.link);
}
interactive = true;
// Reverse engineer the start time.
var now = new Date().getTime() * 0.001;
startTime = now - progress.saveTime;
};
// -----------------------------------------------------------------------
// Setup
// -----------------------------------------------------------------------
var begin = function () {
/* Set up the game when everything is loaded. */
// Handle storage.
if (hasLocalStorage()) {
var erase = $("#erase").click(function() {
doErase();
});
var save = $("#save").click(saveGame);
var storedCharacter = localStorage.getItem(getSaveId());
if (storedCharacter) {
try {
loadGame(JSON.parse(storedCharacter));
save.addClass('disabled')
erase.removeClass('disabled')
} catch(err) {
doErase(true);
}
} else {
startGame();
}
} else {
startGame();
}
// Any point that an option list appears, its options are its
// first links.
$("body").on('click', "ul.options li, #menu li", function(event) {
// Make option clicks pass through to their first link.
var link = $("a", this);
if (link.length > 0) {
$(link.get(0)).click();
}
});
};
### ###
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).
@ -587,116 +450,215 @@ Salet = {
@enableSaving() @enableSaving()
disableSaving: () -> disableSaving: () ->
$("#save").addClass('disabled');
enableSaving: () -> enableSaving: () ->
$("#save").removeClass('disabled'); $("#save").removeClass('disabled');
/* This gets called to actually do the work of processing a code. ###
* When one doLink is called (or a link is clicked), this may set call This gets called to actually do the work of processing a code.
* code that further calls doLink, and so on. This method processes When one doLink is called (or a link is clicked), this may set call
* each one, and processLink manages this. code that further calls doLink, and so on. This method processes
*/ each one, and processLink manages this.
var processOneLink = function(code) { ###
var match = code.match(linkRe); processOneLink: = (code) ->
assert(match, "link_not_valid".l({link:code})); match = code.match(linkRe)
assert(match, "link_not_valid".l({link:code}))
var situation = match[1]; situation = match[1]
var action = match[3]; action = match[3]
// Change the situation # Change the situation
if (situation !== '.') { if (situation !== '.')
if (situation !== current) { if (situation !== current)
doTransitionTo(situation); doTransitionTo(situation)
} else
} else { # We should have an action if we have no situation change.
// We should have an action if we have no situation change. assert(action, "link_no_action".l())
assert(action, "link_no_action".l());
}
// Carry out the action # Carry out the action
if (action) { if (action)
situation = getCurrentSituation(); situation = getCurrentSituation()
if (situation) { if (situation)
if (game.beforeAction) { if (game.beforeAction)
// Try the global act handler, and see if we need # Try the global act handler, and see if we need
// to notify the situation. # to notify the situation.
var consumed = game.beforeAction( consumed = game.beforeAction(
character, system, current, action character, system, current, action
); )
if (consumed !== true) { if (consumed != true)
situation.act(character, system, action); situation.act(character, system, action)
} else
} else { # We have no global act handler, always notify the situation.
// We have no global act handler, always notify situation.act(character, system, action)
// the situation.
situation.act(character, system, action);
}
if (game.afterAction) {
game.afterAction(character, system, current, action);
}
}
}
};
/* This gets called when the user clicks a link to carry out an if (game.afterAction)
* action. */ game.afterAction(character, system, current, action)
var processClick = function(code) {
var now = (new Date()).getTime() * 0.001;
system.time = now - startTime;
progress.sequence.push({link:code, when:system.time});
processLink(code);
};
/* Transitions between situations. */ # This gets called when the user clicks a link to carry out an action.
var doTransitionTo = function(newSituationId) { processClick: (code) ->
var oldSituationId = current; now = (new Date()).getTime() * 0.001
var oldSituation = getCurrentSituation(); system.time = now - startTime
var newSituation = game.situations[newSituationId]; progress.sequence.push({link:code, when:system.time})
processLink(code)
assert(newSituation, "unknown_situation".l({id:newSituationId})); # Transitions between situations.
doTransitionTo: (newSituationId) ->
oldSituationId = current
oldSituation = getCurrentSituation()
newSituation = game.situations[newSituationId]
// We might not have an old situation if this is the start of assert(newSituation, "unknown_situation".l({id:newSituationId}))
// the game.
if (oldSituation) {
if (game.exit) {
game.exit(character, system, oldSituationId, newSituationId);
}
// Remove links and transient sections. # We might not have an old situation if this is the start of the game.
$('#content a').each(function(index, element) { if (oldSituation)
var a = $(element); if (game.exit)
if (a.hasClass('sticky') || a.attr("href").match(/[?&]sticky[=&]?/)) game.exit(character, system, oldSituationId, newSituationId);
return;
a.replaceWith($("<span>").addClass("ex_link").html(a.html()));
});
var contentToHide = $('#content .transient, #content ul.options');
contentToHide.add($("#content a").filter(function(){
return $(this).attr("href").match(/[?&]transient[=&]?/);
}));
if (interactive) {
contentToHide.
animate({opacity: 0}, 350).
slideUp(500, function() {
$(this).remove();
});
} else {
contentToHide.remove();
}
}
// Move the character. # Remove links and transient sections.
current = newSituationId; $('#content a').each((index, element) ->
a = $(element);
if (a.hasClass('sticky') || a.attr("href").match(/[?&]sticky[=&]?/))
return;
a.replaceWith($("<span>").addClass("ex_link").html(a.html()))
)
contentToHide = $('#content .transient, #content ul.options')
contentToHide.add($("#content a").filter(() ->
return $(this).attr("href").match(/[?&]transient[=&]?/)
))
if (interactive)
contentToHide.animate({opacity: 0}, 350).
slideUp(500, () ->
$(this).remove()
)
else
contentToHide.remove()
// Notify the incoming situation. # Move the character.
if (game.enter) { current = newSituationId
game.enter(character, system, oldSituationId, newSituationId);
}
newSituation.entering(character, system, oldSituationId);
// additional hook for when the situation text has already been printed # Notify the incoming situation.
if (game.afterEnter) { if (game.enter)
game.afterEnter(character, system, oldSituationId, newSituationId); game.enter(character, system, oldSituationId, newSituationId)
} newSituation.entering(character, system, oldSituationId)
};
# additional hook for when the situation text has already been printed
if (game.afterEnter)
game.afterEnter(character, system, oldSituationId, newSituationId)
###
Erases the character in local storage. This is permanent!
To restart the game afterwards, we perform a simple page refresh.
This guarantees authors don't have to care about "tainting" the
game state across save/erase cycles, meaning that character.sandbox
no longer has to be the end-all be-all repository of game state. */
###
erase_save: (force = false) =>
save_id = @getSaveId() # save slot
if (localStorage.getItem(saveId) and (force or confirm("erase_message".l())))
localStorage.removeItem(saveId)
window.location.reload()
# Find and return a list of ids for all situations with the given tag.
getSituationIdsWithTag: (tag) =>
result = []
for (situationId, situation of @situations)
for (i = 0; i < situation.tags.length; ++i)
if (situation.tags[i] == tag)
result.push(situationId)
break
return result
# Saves the character to local storage.
saveGame: () ->
# Store when we're saving the game, to avoid exploits where a
# player loads their file to gain extra time.
now = (new Date()).getTime() * 0.001
progress.saveTime = now - startTime
# Save the game.
localStorage.setItem(getSaveId(), JSON.stringify(progress))
# Switch the button highlights.
$("#erase").removeClass('disabled')
$("#load").removeClass('disabled')
@disableSaving()
# Loads the game from the given data
loadGame = (characterData) ->
progress = characterData
character = new Character()
system.rnd = new Random(progress.seed)
# Empty the display
$("#content").empty()
$("#intro").empty()
# Now play through the actions so far:
if (game.init)
game.init(character, system)
# Run through all the player's history.
interactive = false
for (i = 0; i < progress.sequence.length; i++)
step = progress.sequence[i]
# The action must be done at the recorded time.
system.time = step.when
processLink(step.link)
interactive = true
# Reverse engineer the start time.
now = new Date().getTime() * 0.001
startTime = now - progress.saveTime
game_begin: () ->
# Handle storage.
storedCharacter = false
if (@hasLocalStorage())
storedCharacter = localStorage.getItem(@getSaveId())
if (storedCharacter)
try
@loadGame(JSON.parse(storedCharacter))
@disableSaving()
$("#erase").removeClass('disabled')
catch(err)
@erase_save(true)
else
progress.seed = new Date().toString()
character = new Character()
system.rnd = new Random(progress.seed)
progress.sequence = [{link:game.start, when:0}]
# Empty the display
$("#content").empty()
# Start the game
startTime = new Date().getTime() * 0.001
system.time = 0
if (game.init)
game.init(character, system)
# Do the first state.
doTransitionTo(game.start);
# Any point that an option list appears, its options are its first links.
$("body").on('click', "ul.options li, #menu li", (event) ->
# Make option clicks pass through to their first link.
link = $("a", this)
if (link.length > 0)
$(link.get(0)).click()
);
} }
# Set up the game when everything is loaded.
$(document).ready(() ->
salet = new Salet
if (salet.hasLocalStorage())
$("#erase").click(salet.erase_save) # is Salet defined here?
$("#save").click(salet.saveGame)
salet.game_begin()
)