Switched to Salet because I want procgen
This commit is contained in:
parent
07a644d8a5
commit
edd2373544
|
@ -0,0 +1,4 @@
|
||||||
|
node_modules
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
dist.zip
|
|
@ -0,0 +1,152 @@
|
||||||
|
watchify = require('watchify')
|
||||||
|
browserify = require('browserify')
|
||||||
|
browserSync = require('browser-sync')
|
||||||
|
gulp = require('gulp')
|
||||||
|
source = require('vinyl-source-stream')
|
||||||
|
gutil = require('gulp-util')
|
||||||
|
coffeify = require('coffeeify')
|
||||||
|
coffee = require("gulp-coffee")
|
||||||
|
sass = require('gulp-sass')
|
||||||
|
uglify = require('gulp-uglify')
|
||||||
|
buffer = require('vinyl-buffer')
|
||||||
|
zip = require('gulp-zip')
|
||||||
|
concat = require('gulp-concat')
|
||||||
|
fs = require 'fs'
|
||||||
|
CSON = require 'cson'
|
||||||
|
glob = require 'glob'
|
||||||
|
|
||||||
|
reload = browserSync.reload
|
||||||
|
|
||||||
|
html = (target) ->
|
||||||
|
return () ->
|
||||||
|
return gulp.src(['html/index.html']).pipe(gulp.dest(target))
|
||||||
|
|
||||||
|
# Images
|
||||||
|
img = (target) ->
|
||||||
|
return () ->
|
||||||
|
return gulp.src(['img/*.png', 'img/*.jpeg', 'img/*.jpg']).pipe(gulp.dest(target))
|
||||||
|
|
||||||
|
# Audio assets
|
||||||
|
audio = (target) ->
|
||||||
|
return () ->
|
||||||
|
return gulp.src(['audio/*.mp3']).pipe(gulp.dest(target))
|
||||||
|
|
||||||
|
gulp.task('html', html('./build'))
|
||||||
|
gulp.task('img', img('./build/img'))
|
||||||
|
gulp.task('audio', audio('./build/audio'))
|
||||||
|
|
||||||
|
gulp.task('sass', () ->
|
||||||
|
gulp.src('sass/main.scss')
|
||||||
|
.pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
|
||||||
|
.pipe(gulp.dest('./build/css'))
|
||||||
|
)
|
||||||
|
|
||||||
|
bundler = watchify(browserify({
|
||||||
|
entries: ["./build/game/main.coffee"]
|
||||||
|
debug: true
|
||||||
|
transform: [coffeify]
|
||||||
|
}))
|
||||||
|
|
||||||
|
bundle = () ->
|
||||||
|
return bundler.bundle()
|
||||||
|
.on('error', gutil.log.bind(gutil, 'Browserify Error'))
|
||||||
|
.pipe(source('bundle.js'))
|
||||||
|
.pipe(gulp.dest('./build/game'))
|
||||||
|
|
||||||
|
gulp.task('concatCoffee', () ->
|
||||||
|
files = glob.sync('game/procgen/ru/*.cson')
|
||||||
|
spec = {}
|
||||||
|
for file in files
|
||||||
|
data = CSON.parseCSONFile(file)
|
||||||
|
if not data.groups?
|
||||||
|
data.groups = []
|
||||||
|
if data.phrases?
|
||||||
|
data.groups.push({
|
||||||
|
tags: [],
|
||||||
|
phrases: data.phrases
|
||||||
|
})
|
||||||
|
data.phrases = undefined
|
||||||
|
key = file.substr(0, file.lastIndexOf('.')) || file
|
||||||
|
key = key.replace('game/procgen/ru/', '')
|
||||||
|
spec[key] = data
|
||||||
|
|
||||||
|
json = JSON.stringify(spec) + '\n'
|
||||||
|
fs.writeFileSync("./build/game/procgen/ru.json", json)
|
||||||
|
|
||||||
|
return gulp.src([
|
||||||
|
'./game/begin.coffee',
|
||||||
|
'./game/story.coffee',
|
||||||
|
]).pipe(concat('./main.coffee')).pipe(gulp.dest('./build/game'))
|
||||||
|
)
|
||||||
|
|
||||||
|
gulp.task('coffee', ['concatCoffee'], bundle)
|
||||||
|
|
||||||
|
bundler.on('update', bundle)
|
||||||
|
bundler.on('log', gutil.log)
|
||||||
|
|
||||||
|
gulp.task('build', ['html', 'img', 'sass', 'coffee', 'audio'])
|
||||||
|
|
||||||
|
gulp.task('serve', ['build'], () ->
|
||||||
|
browserSync({
|
||||||
|
server: {
|
||||||
|
baseDir: 'build'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
sassListener = () ->
|
||||||
|
reload('./build/css/main.css')
|
||||||
|
|
||||||
|
gulp.watch(['./html/*.html'], ['html'])
|
||||||
|
gulp.watch(['./sass/*.scss'], ['sass'])
|
||||||
|
gulp.watch(['./img/*.png', './img/*.jpeg', './img/*.jpg'], ['img'])
|
||||||
|
gulp.watch(['./game/*.coffee'], ['coffee']);
|
||||||
|
|
||||||
|
gulp.watch(['./build/css/main.css'], sassListener)
|
||||||
|
gulp.watch(
|
||||||
|
['./build/game/bundle.js', './build/img/*', './build/index.html'],
|
||||||
|
browserSync.reload)
|
||||||
|
)
|
||||||
|
|
||||||
|
gulp.task('html-dist', html('./dist'))
|
||||||
|
gulp.task('img-dist', img('./dist/img'))
|
||||||
|
gulp.task('audio-dist', audio('./dist/audio'))
|
||||||
|
gulp.task('legal-dist', () ->
|
||||||
|
return gulp.src(['LICENSE.txt'])
|
||||||
|
.pipe(gulp.dest("./dist"))
|
||||||
|
)
|
||||||
|
|
||||||
|
gulp.task('sass-dist', () ->
|
||||||
|
return gulp.src('./sass/main.scss')
|
||||||
|
.pipe(sass({outputStyle: 'compressed'}))
|
||||||
|
.pipe(gulp.dest('./dist/css'))
|
||||||
|
)
|
||||||
|
|
||||||
|
distBundler = browserify({
|
||||||
|
debug: false,
|
||||||
|
entries: ['./build/game/main.coffee'],
|
||||||
|
transform: ['coffeeify']
|
||||||
|
})
|
||||||
|
|
||||||
|
gulp.task('coffee-dist', ['concatCoffee'], () ->
|
||||||
|
return distBundler.bundle()
|
||||||
|
.pipe(source('bundle.js'))
|
||||||
|
.pipe(buffer())
|
||||||
|
.pipe(uglify())
|
||||||
|
.on('error', gutil.log)
|
||||||
|
.pipe(gulp.dest('./dist/game'))
|
||||||
|
)
|
||||||
|
|
||||||
|
gulp.task('dist', [
|
||||||
|
'html-dist',
|
||||||
|
'img-dist',
|
||||||
|
'sass-dist',
|
||||||
|
'coffee-dist',
|
||||||
|
'audio-dist',
|
||||||
|
'legal-dist'
|
||||||
|
])
|
||||||
|
|
||||||
|
gulp.task('zip', ['dist'], () ->
|
||||||
|
return gulp.src('dist/**')
|
||||||
|
.pipe(zip('dist.zip'))
|
||||||
|
.pipe(gulp.dest('.'))
|
||||||
|
)
|
|
@ -0,0 +1,22 @@
|
||||||
|
Copyright (c) 2016 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.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
The theme is **One room**.
|
The theme is **One room**.
|
||||||
|
|
||||||
I'm building it for [INSTEAD](http://instead.syscall.ru/download/) interpreter.
|
I'm building it on [Salet](https://salet.su/) engine.
|
||||||
|
|
17
emphasis.lua
17
emphasis.lua
|
@ -1,17 +0,0 @@
|
||||||
require 'format'
|
|
||||||
|
|
||||||
format.filter = function(text)
|
|
||||||
for _, s in ipairs {"%*%*", "%_%_"} do
|
|
||||||
text = text:gsub(s .. "([^%s][^<>]-[^%s][%*%_]?)" .. s, txtb("%1"));
|
|
||||||
end;
|
|
||||||
for _, s in ipairs {"%*"} do
|
|
||||||
text = text:gsub(s .. "([^%s_][^<>_]-[^%s_])" .. s, txtem("%1"));
|
|
||||||
end;
|
|
||||||
for _, s in ipairs {"%_"} do
|
|
||||||
text = text:gsub(s .. "([^%s_][^<>_]-[^%s_])" .. s, txtu("%1"));
|
|
||||||
end;
|
|
||||||
for _, s in ipairs {"%-"} do
|
|
||||||
text = text:gsub(s .. " ([^%s_][^<>_]-[^%s_]) " .. s, txtst("%1"));
|
|
||||||
end;
|
|
||||||
return text;
|
|
||||||
end
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
dialogue = require('../../lib/dialogue.coffee')
|
||||||
|
phrase = require('../../lib/phrase.coffee')
|
||||||
|
#oneOf = require('../../lib/oneOf.coffee')
|
||||||
|
require('salet')
|
||||||
|
ImprovEngine = require('improv')
|
||||||
|
Improv = {}
|
||||||
|
|
||||||
|
salet.game_id = "0ee0825d-0c71-4a08-bfe5-730e575df26d"
|
||||||
|
salet.game_version = "1.0"
|
||||||
|
|
||||||
|
$.getJSON('game/procgen/ru.json', (data) ->
|
||||||
|
Improv = new ImprovEngine(data, {
|
||||||
|
filters: [
|
||||||
|
ImprovEngine.filters.mismatchFilter()
|
||||||
|
]
|
||||||
|
reincorporate: false
|
||||||
|
})
|
||||||
|
|
||||||
|
$.holdReady( false )
|
||||||
|
)
|
||||||
|
|
||||||
|
$(document).ready(() ->
|
||||||
|
window.addEventListener('popstate', (event) ->
|
||||||
|
salet.goBack()
|
||||||
|
)
|
||||||
|
$("#night").on("click", () ->
|
||||||
|
if (window.night)
|
||||||
|
styles = {
|
||||||
|
"-webkit-filter": ""
|
||||||
|
"filter": ""
|
||||||
|
"background-color": ""
|
||||||
|
}
|
||||||
|
$("body").css(styles)
|
||||||
|
$("#night").removeClass("active")
|
||||||
|
window.night = false
|
||||||
|
else
|
||||||
|
styles = {
|
||||||
|
"-webkit-filter": "invert(1)hue-rotate(180deg)"
|
||||||
|
"filter": "invert(1)hue-rotate(180deg)"
|
||||||
|
"background-color": "#000"
|
||||||
|
}
|
||||||
|
$("body").css(styles)
|
||||||
|
$("#night").addClass("active")
|
||||||
|
window.night = true
|
||||||
|
)
|
||||||
|
|
||||||
|
salet.beginGame()
|
||||||
|
)
|
||||||
|
|
||||||
|
###
|
||||||
|
Element helpers. There is no real need to build monsters like a().id("hello")
|
||||||
|
because you won't use them as is. It does not make sense in context, the
|
||||||
|
author has Markdown and all utilities to *forget* about the markup.
|
||||||
|
###
|
||||||
|
way_to = (content, ref) ->
|
||||||
|
return "<a href='#{ref}' class='way'>#{content}</a>"
|
||||||
|
textlink = (content, ref) ->
|
||||||
|
return "<a href='./_writer_#{ref}' class='once'>#{content}</a>"
|
||||||
|
actlink = (content, ref) ->
|
||||||
|
return "<a href='./#{ref}' class='once'>#{content}</a>"
|
||||||
|
|
||||||
|
class ImprovModel
|
||||||
|
constructor: () ->
|
||||||
|
@tags = []
|
|
@ -0,0 +1,5 @@
|
||||||
|
phrases: [
|
||||||
|
"обнимает гитару."
|
||||||
|
"насвистывает свою партию в песне про солнце."
|
||||||
|
"задумчиво смотрит в одну точку."
|
||||||
|
]
|
|
@ -0,0 +1,3 @@
|
||||||
|
phrases: [
|
||||||
|
"выжимает из машины всё, что дозволено правилами."
|
||||||
|
]
|
|
@ -0,0 +1,3 @@
|
||||||
|
phrases: [
|
||||||
|
"напевает про себя весёлый мотивчик."
|
||||||
|
]
|
|
@ -0,0 +1,50 @@
|
||||||
|
room "start",
|
||||||
|
choices: ["vstart"]
|
||||||
|
before: (from) ->
|
||||||
|
if (!from)
|
||||||
|
"""
|
||||||
|
-- Только что звонили из клуба.
|
||||||
|
Приехали какие-то чмыри из администрации, нас отменяют.
|
||||||
|
"""
|
||||||
|
dsc: () -> """
|
||||||
|
### В машине
|
||||||
|
|
||||||
|
Рядом с вами сидит [Лёша](alexey) и #{Improv.gen("alexey")}
|
||||||
|
На переднем сидении [Марго](margo) #{Improv.gen("margo")}
|
||||||
|
Вы сидите на заднем сидении, за спиной водителя. [Катя](katie) #{Improv.gen("katie")}
|
||||||
|
|
||||||
|
Вы положили в карман дверцы [мобильный телефон.](phone)
|
||||||
|
За [окном машины](./_writer_window) проносится трасса.
|
||||||
|
|
||||||
|
*Вы сжимаете родную флейту. Только бы не опоздать.*
|
||||||
|
"""
|
||||||
|
writers:
|
||||||
|
window:
|
||||||
|
"Россия."
|
||||||
|
|
||||||
|
room "phone",
|
||||||
|
choices: "#call",
|
||||||
|
dsc: "Вы открываете список контактов. Кому бы позвонить…"
|
||||||
|
|
||||||
|
room "director",
|
||||||
|
tags: ["call"],
|
||||||
|
choices: "#director"
|
||||||
|
optionText: "Директор музыкального клуба"
|
||||||
|
dsc: """
|
||||||
|
— Алло? Анна Борисовна?
|
||||||
|
"""
|
||||||
|
|
||||||
|
dialogue "Попрощаться", "director", "call", """
|
||||||
|
— Спасибо. Созвонимся.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Virtual room to go around limitations
|
||||||
|
room "vstart",
|
||||||
|
tags: ["call"]
|
||||||
|
optionText: (from) ->
|
||||||
|
switch from
|
||||||
|
when "start" then "Осмотреться ещё раз"
|
||||||
|
when "phone" then "Отложить телефон"
|
||||||
|
else "Передумать"
|
||||||
|
enter: () ->
|
||||||
|
salet.goTo("start")
|
|
@ -0,0 +1,61 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Salet showcase</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=PT+Sans:400,400italic|PT+Sans+Caption' rel='stylesheet' type='text/css'>
|
||||||
|
<link rel="stylesheet" href="css/main.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="page">
|
||||||
|
<div class="fixed container">
|
||||||
|
<div id="tools_wrapper" class="row">
|
||||||
|
<div class='ways'>
|
||||||
|
<small class="text-muted" id="ways_hint">Click these links to explore other rooms</small>
|
||||||
|
<ul class="nav nav-pills" id="ways">
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<button id="night" class="btn btn-outline-primary">Night mode</button>
|
||||||
|
<button id="erase" class="btn btn-outline-danger">Restart</button>
|
||||||
|
</div>
|
||||||
|
</div> <!-- End of div.tools_wrapper -->
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div id="title" class="title">
|
||||||
|
<div class="label">
|
||||||
|
<h1>One room</h1>
|
||||||
|
<h2>A Ludum Dare effort</h2>
|
||||||
|
<noscript>
|
||||||
|
<p class="noscript_message">This game requires Javascript.</p>
|
||||||
|
</noscript>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="content_wrapper" class="row">
|
||||||
|
<div id="content" class="content">
|
||||||
|
<noscript>You need to turn on Javascript to play this game.</noscript>
|
||||||
|
</div>
|
||||||
|
<a name="end_of_content"></a>
|
||||||
|
</div>
|
||||||
|
<div id="legal" class="row">
|
||||||
|
<div id="footleft">
|
||||||
|
<p>
|
||||||
|
<a href="https://git.oreolek.ru/oreolek/ludumdare37" target="_blank">See the source code</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="footright">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> <!-- End of div.page -->
|
||||||
|
|
||||||
|
<!-- CDN JS Libraries -->
|
||||||
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.min.js" integrity="sha384-QXBtGc4014gU26HdCwzgy8TVO+FHSSE4+EvPPiSTpdE9w0KyJy1ocfiIbBl1HLq7" crossorigin="anonymous"></script>
|
||||||
|
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.1.min.js" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="game/bundle.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
13
init.lua
13
init.lua
|
@ -1,13 +0,0 @@
|
||||||
require 'para'
|
|
||||||
require 'dash'
|
|
||||||
require 'quotes'
|
|
||||||
require 'dbg'
|
|
||||||
require 'emphasis';
|
|
||||||
|
|
||||||
game.forcedsc = false;
|
|
||||||
game._action = nil;
|
|
||||||
game.actions = {}
|
|
||||||
|
|
||||||
rndstr = function(strings)
|
|
||||||
return strings[rnd(stead.table.maxn(strings))];
|
|
||||||
end
|
|
BIN
italic.ttf
BIN
italic.ttf
Binary file not shown.
|
@ -0,0 +1,2 @@
|
||||||
|
These functions are not used by Salet core.
|
||||||
|
But you can `require` them in your game and use thusly.
|
|
@ -0,0 +1,25 @@
|
||||||
|
###
|
||||||
|
A dialogue shortcut.
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
dialogue "Point out a thing in her purse (mildly)", "start", "mild", """
|
||||||
|
Point out a thing in her purse (mildly)
|
||||||
|
""", "character.mild = true"
|
||||||
|
###
|
||||||
|
dialogue = (title, startTag, endTag, text, effect) ->
|
||||||
|
retval = room("dialogue_"+Object.keys(salet.rooms).length, {
|
||||||
|
optionText: title
|
||||||
|
dsc: text
|
||||||
|
clear: false # backlog is useful in dialogues
|
||||||
|
choices: "#"+endTag
|
||||||
|
})
|
||||||
|
if typeof(startTag) == "string"
|
||||||
|
retval.tags = [startTag]
|
||||||
|
else if typeof(startTag) == "object"
|
||||||
|
retval.tags = startTag
|
||||||
|
if effect?
|
||||||
|
retval.before = (character, system) ->
|
||||||
|
eval(effect)
|
||||||
|
return retval
|
||||||
|
|
||||||
|
module.exports = dialogue
|
|
@ -0,0 +1,169 @@
|
||||||
|
###
|
||||||
|
oneOf.js
|
||||||
|
|
||||||
|
Copyright (c) 2015 Bruno Dias
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
###
|
||||||
|
|
||||||
|
###
|
||||||
|
Undularity Tools
|
||||||
|
|
||||||
|
Those functions are not a core part of Undularity, but provide some
|
||||||
|
general functionality that relates to adaptive text generation.
|
||||||
|
|
||||||
|
This is provided partly as a helper to less technical users, and as
|
||||||
|
a convenience for authors.
|
||||||
|
###
|
||||||
|
|
||||||
|
# Monkey patching
|
||||||
|
|
||||||
|
###
|
||||||
|
Shuffles an array. It can use Undum's random number generator implementation,
|
||||||
|
so it expects a System.rnd object to be passed into it. If one isn't
|
||||||
|
supplied, it will use Math.Random instead.
|
||||||
|
|
||||||
|
This is an implementation of the Fischer-Yates (Knuth) shuffle.
|
||||||
|
|
||||||
|
Returns the shuffled array.
|
||||||
|
###
|
||||||
|
|
||||||
|
Array.prototype.shuffle = () ->
|
||||||
|
# slice() clones the array. Object members are copied by reference, beware.
|
||||||
|
newArr = this.slice()
|
||||||
|
m = newArr.length
|
||||||
|
|
||||||
|
while (m)
|
||||||
|
i = Math.floor(salet.rnd.randf() * m--)
|
||||||
|
t = newArr[m]
|
||||||
|
newArr[m] = newArr[i]
|
||||||
|
newArr[i] = t
|
||||||
|
|
||||||
|
return newArr
|
||||||
|
|
||||||
|
###
|
||||||
|
oneOf()
|
||||||
|
|
||||||
|
Takes an array and returns an object with several methods. Each method
|
||||||
|
returns an iterator which iterates over the array in a specific way:
|
||||||
|
|
||||||
|
inOrder()
|
||||||
|
Returns the array items in order.
|
||||||
|
|
||||||
|
cycling()
|
||||||
|
Returns the array items in order, cycling back to the first item when
|
||||||
|
it runs out.
|
||||||
|
|
||||||
|
stopping()
|
||||||
|
Returns the array items in order, then repeats the last item when it
|
||||||
|
runs out.
|
||||||
|
|
||||||
|
randomly()
|
||||||
|
Returns the array items at random. Takes a system object, for consistent
|
||||||
|
randomness. Will never return the same item twice in a row.
|
||||||
|
|
||||||
|
trulyAtRandom()
|
||||||
|
Returns the array items purely at random. Takes a system object, for
|
||||||
|
consistent randomness.
|
||||||
|
|
||||||
|
inRandomOrder()
|
||||||
|
Returns the array items in a random order. Takes a system object, for
|
||||||
|
consistent randomness.
|
||||||
|
###
|
||||||
|
|
||||||
|
###
|
||||||
|
Takes a function and gives it a toString() property that calls itself and
|
||||||
|
returns its value, allowing for ambiguous use of the closure object
|
||||||
|
as a text snippet.
|
||||||
|
|
||||||
|
Returns the modified function.
|
||||||
|
###
|
||||||
|
stringish = (callback) ->
|
||||||
|
callback.toString = () ->
|
||||||
|
return '' + this.call()
|
||||||
|
return callback
|
||||||
|
|
||||||
|
oneOf = (ary...) ->
|
||||||
|
if ary.length == 0
|
||||||
|
throw new Error(
|
||||||
|
"tried to create a oneOf iterator with a 0-length array");
|
||||||
|
|
||||||
|
return {
|
||||||
|
inOrder: () ->
|
||||||
|
i = 0
|
||||||
|
return stringish(() ->
|
||||||
|
if i >= ary.length
|
||||||
|
return null
|
||||||
|
return ary[i++]
|
||||||
|
)
|
||||||
|
|
||||||
|
cycling: () ->
|
||||||
|
i = 0
|
||||||
|
return stringish(() ->
|
||||||
|
if (i >= ary.length)
|
||||||
|
i = 0
|
||||||
|
return ary[i++]
|
||||||
|
)
|
||||||
|
|
||||||
|
stopping: () ->
|
||||||
|
i = 0
|
||||||
|
return stringish(() ->
|
||||||
|
if (i >= ary.length)
|
||||||
|
i = ary.length - 1
|
||||||
|
return ary[i++]
|
||||||
|
)
|
||||||
|
|
||||||
|
randomly: (system) ->
|
||||||
|
last = null
|
||||||
|
|
||||||
|
if (ary.length<2)
|
||||||
|
throw new Error("attempted to make randomly() iterator with a 1-length array")
|
||||||
|
return stringish( () ->
|
||||||
|
i = null
|
||||||
|
offset = null
|
||||||
|
if not last?
|
||||||
|
i = Math.floor(salet.rnd.randf() * ary.length)
|
||||||
|
else
|
||||||
|
###
|
||||||
|
Let offset be a random number between 1 and the length of the
|
||||||
|
array, minus one. We jump offset items ahead on the array,
|
||||||
|
wrapping around to the beginning. This gives us a random item
|
||||||
|
other than the one we just chose.
|
||||||
|
###
|
||||||
|
|
||||||
|
offset = Math.floor(salet.rnd.randf() * (ary.length -1) + 1)
|
||||||
|
i = (last + offset) % ary.length
|
||||||
|
|
||||||
|
last = i
|
||||||
|
return ary[i]
|
||||||
|
)
|
||||||
|
|
||||||
|
trulyAtRandom: (system) ->
|
||||||
|
return stringish(() ->
|
||||||
|
return ary[Math.floor(salet.rnd.randf() * ary.length)];
|
||||||
|
)
|
||||||
|
|
||||||
|
inRandomOrder: (system) ->
|
||||||
|
shuffled = ary.shuffle(system)
|
||||||
|
i = 0
|
||||||
|
return stringish(() ->
|
||||||
|
if (i >= ary.length)
|
||||||
|
i = 0
|
||||||
|
return shuffled[i++]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.prototype.oneOf = () ->
|
||||||
|
oneOf.apply(null, this)
|
||||||
|
String.prototype.oneOf = () ->
|
||||||
|
return this
|
||||||
|
|
||||||
|
module.exports = oneOf
|
|
@ -0,0 +1,28 @@
|
||||||
|
###
|
||||||
|
A phrase shortcut.
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
phrase "Point out a thing in her purse (mildly)", "start", """
|
||||||
|
Point out a thing in her purse (mildly)
|
||||||
|
""", "character.sandbox.mild = true"
|
||||||
|
|
||||||
|
@param title phrase Phrase (question)
|
||||||
|
@param salet Salet core
|
||||||
|
@param string tag tag marking viewing condition
|
||||||
|
@param string text Response
|
||||||
|
@param string effect an optional parameter, eval'd code
|
||||||
|
###
|
||||||
|
phrase = (title, tag, text, effect) ->
|
||||||
|
retval = room("phrase_"+salet.rooms.length, {
|
||||||
|
optionText: title
|
||||||
|
dsc: text
|
||||||
|
clear: false # backlog is useful in dialogues
|
||||||
|
choices: "#"+tag
|
||||||
|
tags: [tag]
|
||||||
|
})
|
||||||
|
if effect?
|
||||||
|
retval.before = (character, system) ->
|
||||||
|
eval(effect)
|
||||||
|
return retval
|
||||||
|
|
||||||
|
module.exports = phrase
|
15
main.lua
15
main.lua
|
@ -1,15 +0,0 @@
|
||||||
-- $Name: Ludum Dare 37$
|
|
||||||
instead_version "1.9.1";
|
|
||||||
dofile("init.lua");
|
|
||||||
|
|
||||||
main = room{
|
|
||||||
nam = "Дело о ",
|
|
||||||
dsc = [[
|
|
||||||
-- Я никого не выпущу, пока мы не решим, что делать с колонией, — сказал директор, закрывая
|
|
||||||
входную дверь на ключ.
|
|
||||||
]],
|
|
||||||
obj = {},
|
|
||||||
};
|
|
||||||
|
|
||||||
-- Outside the window is The World Out There; it's buzzing with life. In a cruel twist of the fate… you guessed it - it's 100% decoration.
|
|
||||||
--
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"cson": "^4.0.0",
|
||||||
|
"glob": "^7.1.1",
|
||||||
|
"improv": "^0.8.0",
|
||||||
|
"salet": "^1.5.4"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"devDependencies": {
|
||||||
|
"bootstrap": "^4.0.0-alpha.2",
|
||||||
|
"browser-sync": "^2.18.2",
|
||||||
|
"browserify": "^13.1.1",
|
||||||
|
"browserify-shim": "^3.8.8",
|
||||||
|
"coffee-script": "^1.12.0",
|
||||||
|
"coffeeify": "^2.1.0",
|
||||||
|
"gulp": "^3.8.11",
|
||||||
|
"gulp-coffee": "^2.3.3",
|
||||||
|
"gulp-concat": "^2.6.1",
|
||||||
|
"gulp-sass": "^2.1.1",
|
||||||
|
"gulp-uglify": "^2.0.0",
|
||||||
|
"gulp-util": "^3.0.4",
|
||||||
|
"gulp-zip": "^3.0.2",
|
||||||
|
"vinyl-buffer": "^1.0.0",
|
||||||
|
"vinyl-source-stream": "^1.1.0",
|
||||||
|
"watchify": "^3.1.0"
|
||||||
|
}
|
||||||
|
}
|
BIN
regular.ttf
BIN
regular.ttf
Binary file not shown.
|
@ -0,0 +1,16 @@
|
||||||
|
@mixin halfcolumn() {
|
||||||
|
@media (min-width: breakpoint-min(sm)) {
|
||||||
|
@include make-col(6);
|
||||||
|
}
|
||||||
|
@media (max-width: breakpoint-max(xs)) {
|
||||||
|
@include make-col(12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin col($sm-width, $xs-width) {
|
||||||
|
@media (min-width: breakpoint-min(sm)) {
|
||||||
|
@include make-col($sm-width);
|
||||||
|
}
|
||||||
|
@media (max-width: breakpoint-max(xs)) {
|
||||||
|
@include make-col($xs-width);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
$font-family-sans-serif: 'PT Sans','Open Sans',"Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
$headings-font-family: "PT Sans Caption",$font-family-sans-serif;
|
||||||
|
$font-family-base: $font-family-sans-serif;
|
||||||
|
|
||||||
|
$body-bg: #fff;
|
||||||
|
$body-color: #000;
|
||||||
|
$link-color: blue;
|
||||||
|
$btn-bg: grey;
|
||||||
|
$btn-color: lighten($btn-bg, 50%);
|
||||||
|
$secondary-bg: #F1EED9;
|
||||||
|
|
||||||
|
$brand-primary: lighten($body-color, 20%);
|
||||||
|
$brand-danger: darken($body-bg, 30%);
|
||||||
|
|
||||||
|
$waycolor: $link-color;
|
||||||
|
$text_background: $body-bg; // can be btn-bg
|
||||||
|
$animation_duration: 2s;
|
|
@ -0,0 +1,203 @@
|
||||||
|
@import "../node_modules/bootstrap/scss/mixins/grid";
|
||||||
|
@import "mixins";
|
||||||
|
@import "variables";
|
||||||
|
// Bootstrap v4 stripped core
|
||||||
|
@import "../node_modules/bootstrap/scss/variables";
|
||||||
|
@import "../node_modules/bootstrap/scss/mixins";
|
||||||
|
@import "../node_modules/bootstrap/scss/normalize";
|
||||||
|
@import "../node_modules/bootstrap/scss/print";
|
||||||
|
@import "../node_modules/bootstrap/scss/reboot";
|
||||||
|
@import "../node_modules/bootstrap/scss/type";
|
||||||
|
// @import "../node_modules/bootstrap/scss/images";
|
||||||
|
@import "../node_modules/bootstrap/scss/grid";
|
||||||
|
@import "../node_modules/bootstrap/scss/buttons";
|
||||||
|
|
||||||
|
@import "../node_modules/bootstrap/scss/nav";
|
||||||
|
@import "../node_modules/bootstrap/scss/responsive-embed";
|
||||||
|
@import "../node_modules/bootstrap/scss/utilities";
|
||||||
|
|
||||||
|
body {
|
||||||
|
overflow-y: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
background: $body-bg;
|
||||||
|
}
|
||||||
|
// The title block
|
||||||
|
.title {
|
||||||
|
margin-top: 3.5em;
|
||||||
|
@include col(10,12);
|
||||||
|
@media (min-width: breakpoint-min(sm)) {
|
||||||
|
@include make-col-offset(1);
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
margin: 1.5em auto;
|
||||||
|
@media (min-width: breakpoint-min(sm)) {
|
||||||
|
@include make-col-offset(2);
|
||||||
|
@include make-col(8);
|
||||||
|
}
|
||||||
|
@media (max-width: breakpoint-min(sm)) {
|
||||||
|
@include make-col(12);
|
||||||
|
}
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.subtitle {
|
||||||
|
font-size: smaller;
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
.warnings {
|
||||||
|
font-size: small;
|
||||||
|
font-style: italic;
|
||||||
|
p {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.noscript_message {
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
position: absolute;
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-style: italic;
|
||||||
|
text-align: center;
|
||||||
|
color: #943;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#choices {
|
||||||
|
@include make-col(12);
|
||||||
|
}
|
||||||
|
.fixed {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#tools_wrapper {
|
||||||
|
background: $body-bg;
|
||||||
|
.ways {
|
||||||
|
padding: 0.5em;
|
||||||
|
@include make-col(6);
|
||||||
|
}
|
||||||
|
.buttons {
|
||||||
|
@include make-col(6);
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#content_wrapper {
|
||||||
|
background: $text_background;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
@include col(10, 12);
|
||||||
|
@media (min-width: breakpoint-min(sm)) {
|
||||||
|
@include make-col-offset(1);
|
||||||
|
}
|
||||||
|
.pic {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
hyphens: auto;
|
||||||
|
}
|
||||||
|
padding: 1em;
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
ul.options {
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 0.7em;
|
||||||
|
list-style-type: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
li {
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
li:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
li:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
section {
|
||||||
|
border-top: 1px dashed #bbb;
|
||||||
|
}
|
||||||
|
.situation-start {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
img.right {
|
||||||
|
float: right;
|
||||||
|
margin: 1.1em 0 1.1em 1.1em;
|
||||||
|
}
|
||||||
|
img.left {
|
||||||
|
float: left;
|
||||||
|
margin: 1.1em 1.1em 1.1em 0;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#legal {
|
||||||
|
margin-top: 1em;
|
||||||
|
color: darken($body-color, 10%);
|
||||||
|
font-size: smaller;
|
||||||
|
#footleft {
|
||||||
|
@media (min-width: breakpoint-min(sm)) {
|
||||||
|
@include make-col-offset(2);
|
||||||
|
@include make-col(5);
|
||||||
|
}
|
||||||
|
@media (max-width: breakpoint-max(xs)) {
|
||||||
|
@include make-col(12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#footright {
|
||||||
|
text-align: right;
|
||||||
|
@media (min-width: breakpoint-min(sm)) {
|
||||||
|
@include make-col(3);
|
||||||
|
@include make-col-offset(2);
|
||||||
|
}
|
||||||
|
@media (max-width: breakpoint-max(xs)) {
|
||||||
|
@include make-col(12);
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.way {
|
||||||
|
color: $waycolor;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
.cycle {
|
||||||
|
color: darkgreen;
|
||||||
|
border-bottom: darkgreen dashed 1px;
|
||||||
|
}
|
||||||
|
ul.options {
|
||||||
|
border: 1px solid #876;
|
||||||
|
li {
|
||||||
|
border-bottom: 1px solid #876;
|
||||||
|
}
|
||||||
|
li:hover {
|
||||||
|
background-color: rgba(153,136,119,0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#legal {
|
||||||
|
.muted {
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
width: 50%;
|
||||||
|
border-color: $body-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
14
theme.ini
14
theme.ini
|
@ -1,14 +0,0 @@
|
||||||
; $Name: Baskerville-beige$
|
|
||||||
include = garamond
|
|
||||||
|
|
||||||
win.fnt.name = {regular,,italic,}.ttf
|
|
||||||
win.fnt.size = 18
|
|
||||||
win.fnt.height = 1.4
|
|
||||||
|
|
||||||
inv.fnt.name = {regular,,italic,}.ttf
|
|
||||||
inv.fnt.size = 18
|
|
||||||
inv.fnt.height = 1.4
|
|
||||||
|
|
||||||
menu.fnt.name = {regular,,italic,}.ttf
|
|
||||||
menu.fnt.size = 15
|
|
||||||
menu.fnt.height = 1.4
|
|
Loading…
Reference in New Issue