0
0
Fork 0
mirror of https://gitlab.com/Oreolek/salet-module.git synced 2024-07-01 06:15:04 +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}
#})
"""
return eval(fstr);
return eval(fstr)
# Scrolls the top of the screen to the specified point
scrollTopTo = (value) ->
@ -63,143 +63,6 @@ augmentLinks = (content) ->
)
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 data is volatile anyway (as in, it won't get saved).
@ -587,116 +450,215 @@ Salet = {
@enableSaving()
disableSaving: () ->
$("#save").addClass('disabled');
enableSaving: () ->
$("#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
* 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);
assert(match, "link_not_valid".l({link:code}));
###
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
code that further calls doLink, and so on. This method processes
each one, and processLink manages this.
###
processOneLink: = (code) ->
match = code.match(linkRe)
assert(match, "link_not_valid".l({link:code}))
var situation = match[1];
var action = match[3];
situation = match[1]
action = match[3]
// Change the situation
if (situation !== '.') {
if (situation !== current) {
doTransitionTo(situation);
}
} else {
// We should have an action if we have no situation change.
assert(action, "link_no_action".l());
}
# Change the situation
if (situation !== '.')
if (situation !== current)
doTransitionTo(situation)
else
# We should have an action if we have no situation change.
assert(action, "link_no_action".l())
// Carry out the action
if (action) {
situation = getCurrentSituation();
if (situation) {
if (game.beforeAction) {
// Try the global act handler, and see if we need
// to notify the situation.
var consumed = game.beforeAction(
character, system, current, action
);
if (consumed !== true) {
situation.act(character, system, action);
}
} else {
// We have no global act handler, always notify
// the situation.
situation.act(character, system, action);
}
if (game.afterAction) {
game.afterAction(character, system, current, action);
}
}
}
};
# Carry out the action
if (action)
situation = getCurrentSituation()
if (situation)
if (game.beforeAction)
# Try the global act handler, and see if we need
# to notify the situation.
consumed = game.beforeAction(
character, system, current, action
)
if (consumed != true)
situation.act(character, system, action)
else
# We have no global act handler, always notify 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
* 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);
};
# This gets called when the user clicks a link to carry out an action.
processClick: (code) ->
now = (new Date()).getTime() * 0.001
system.time = now - startTime
progress.sequence.push({link:code, when:system.time})
processLink(code)
/* Transitions between situations. */
var doTransitionTo = function(newSituationId) {
var oldSituationId = current;
var oldSituation = getCurrentSituation();
var newSituation = game.situations[newSituationId];
# Transitions between situations.
doTransitionTo: (newSituationId) ->
oldSituationId = current
oldSituation = getCurrentSituation()
newSituation = game.situations[newSituationId]
assert(newSituation, "unknown_situation".l({id:newSituationId}));
assert(newSituation, "unknown_situation".l({id:newSituationId}))
// We might not have an old situation if this is the start of
// the game.
if (oldSituation) {
if (game.exit) {
game.exit(character, system, oldSituationId, newSituationId);
}
# We might not have an old situation if this is the start of the game.
if (oldSituation)
if (game.exit)
game.exit(character, system, oldSituationId, newSituationId);
// Remove links and transient sections.
$('#content a').each(function(index, element) {
var a = $(element);
if (a.hasClass('sticky') || a.attr("href").match(/[?&]sticky[=&]?/))
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();
}
}
# Remove links and transient sections.
$('#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()
// Move the character.
current = newSituationId;
# Move the character.
current = newSituationId
// Notify the incoming situation.
if (game.enter) {
game.enter(character, system, oldSituationId, newSituationId);
}
newSituation.entering(character, system, oldSituationId);
# Notify the incoming situation.
if (game.enter)
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);
}
};
# 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()
)