431 lines
7.5 KiB
HTML
431 lines
7.5 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
|
<title>Art lost in time</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<style>
|
|
* {
|
|
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
|
|
-moz-box-sizing: border-box; /* Firefox, other Gecko */
|
|
box-sizing: border-box; /* Opera/IE 8+ */
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
body {
|
|
background-color: darkgrey;
|
|
font-family: "Lucida console", monospaced;
|
|
font-weight: bold;
|
|
font-size: 16px;
|
|
}
|
|
|
|
#all {
|
|
width: 1282px;
|
|
height: 480px;
|
|
margin: auto;
|
|
background-color: #fff;
|
|
border: 1px solid #000;
|
|
}
|
|
|
|
#img {
|
|
float: left;
|
|
}
|
|
|
|
#all:after {
|
|
content: "";
|
|
display: table;
|
|
clear: both;
|
|
}
|
|
|
|
#texty {
|
|
float: left;
|
|
width: 400px;
|
|
padding: 5px;
|
|
border: 1px solid black;
|
|
overflow: auto;
|
|
height: 480px;
|
|
}
|
|
|
|
#texty .error {
|
|
color: red;
|
|
}
|
|
|
|
#menu {
|
|
float: left;
|
|
width: 240px;
|
|
}
|
|
|
|
#menu a {
|
|
display: block;
|
|
color: #000;
|
|
text-decoration: none;
|
|
padding: 5px;
|
|
}
|
|
</style>
|
|
<script src="fengari-web.js" type="text/javascript"></script>
|
|
</head>
|
|
<body>
|
|
|
|
<div id="all">
|
|
<img src="art/titulka.png" id="img">
|
|
<div id="texty">
|
|
<p>Art lost in time</p>
|
|
<p>If the game does not start, please report it back to Severák. Please include info which browser (and version) did you used.</p>
|
|
</div>
|
|
<div id="menu">
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
var el_texty = document.getElementById("texty");
|
|
var el_menu = document.getElementById("menu");
|
|
|
|
function ui_p(txt)
|
|
{
|
|
|
|
el_texty.innerHTML += ("<p>" + txt + "</p>");
|
|
el_texty.scrollTop = el_texty.scrollHeight;
|
|
}
|
|
|
|
function ui_cls(txt)
|
|
{
|
|
|
|
el_texty.innerHTML = "";
|
|
}
|
|
|
|
function ui_add_menu(code, txt)
|
|
{
|
|
|
|
el_menu.innerHTML += ("<a href=\"#\" data-code=\""+code+"\">" + txt + "</p>");
|
|
}
|
|
|
|
function ui_cls_menu()
|
|
{
|
|
|
|
el_menu.innerHTML = "";
|
|
}
|
|
|
|
function ui_errormsg(txt)
|
|
{
|
|
|
|
el_texty.innerHTML += ("<p class=\"error\">" + txt.replace("\n", "<br/>") + "</p>");
|
|
el_texty.scrollTop = el_texty.scrollHeight;
|
|
}
|
|
|
|
function ui_img(src)
|
|
{
|
|
document.getElementById('img').src = 'art/' + src;
|
|
}
|
|
|
|
</script>
|
|
|
|
<script type="application/lua">
|
|
local js = require "js"
|
|
local window = js.global
|
|
|
|
gamefile = "art.lua"
|
|
|
|
-- Hagen game engine
|
|
-- (c) Severák 2019-2021
|
|
|
|
-- kód nedoporučuju nikomu číst, protože zárodek vzniknul během jednoho odpoledne
|
|
|
|
-- inspirace
|
|
-- - hra Gateway od Legend entrertaiment
|
|
-- - textovky od Petra Kaina
|
|
-- - textovkový engine INSTEAD
|
|
|
|
-- globals
|
|
|
|
paramsNo = 0
|
|
params = {}
|
|
currVerb = nil
|
|
|
|
verb_ord = {}
|
|
room_ord = {}
|
|
item_ord = {}
|
|
|
|
menu2codes = {}
|
|
|
|
issued_command = {}
|
|
|
|
-- API
|
|
|
|
function verb(def)
|
|
def.is_verb = true
|
|
def.params = def.params or {}
|
|
verb_ord[#verb_ord+1] = def
|
|
return def
|
|
end
|
|
|
|
function room(def)
|
|
def.is_room = true
|
|
room_ord[#room_ord+1] = def
|
|
return def
|
|
end
|
|
|
|
function item(def)
|
|
def.is_item = true
|
|
item_ord[#item_ord+1] = def
|
|
return def
|
|
end
|
|
|
|
function cls()
|
|
window:ui_cls()
|
|
end
|
|
|
|
function img(src)
|
|
window:ui_img(src)
|
|
end
|
|
|
|
local function split_lines(str)
|
|
local result = {}
|
|
for line in str:gmatch '[^\n]+' do
|
|
table.insert(result, line)
|
|
end
|
|
return result
|
|
end
|
|
|
|
function p(par)
|
|
par = par or ""
|
|
for line in par:gmatch '[^\n]+' do
|
|
window:ui_p(line)
|
|
end
|
|
end
|
|
|
|
function here()
|
|
return game[game.me.w]
|
|
end
|
|
|
|
function move(what, where)
|
|
game[what].w = where
|
|
end
|
|
|
|
function walk(where, nocls)
|
|
assert(game[where], "room " .. where .. " does not exist")
|
|
if game[where].img then
|
|
img(game[where].img)
|
|
end
|
|
move("me", where)
|
|
if not nocls then
|
|
cls()
|
|
end
|
|
p(game[where].n)
|
|
p(game[where].d)
|
|
for i,item in ipairs(item_ord) do
|
|
if item.d and item.w==here().ref then
|
|
p(item.d)
|
|
end
|
|
end
|
|
show_verbs()
|
|
end
|
|
|
|
function has(what)
|
|
return game[what].w=="me"
|
|
end
|
|
|
|
function location_of(what)
|
|
return game[what].w
|
|
end
|
|
|
|
function is_here(what)
|
|
return game[what].w==game.me.w
|
|
end
|
|
|
|
|
|
-- end of API
|
|
|
|
-- TODO - checkovat všechny parametry
|
|
function _has_subj_of(verb)
|
|
local parCode = verb.params[#params+1]
|
|
for i,item in ipairs(item_ord) do
|
|
if item[parCode] and (verb.global_reach or item.w==here().ref or item.w=="me") then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function show_verbs()
|
|
paramsNo = 0
|
|
currVerb = ""
|
|
params = {}
|
|
local here = game[game.me.w]
|
|
window:ui_cls_menu();
|
|
menu2codes={}
|
|
for i,verb in ipairs(verb_ord) do
|
|
if verb.always or here[verb.ref] or _has_subj_of(verb) then
|
|
local idx=#menu2codes+1
|
|
window:ui_add_menu(idx, verb.n);
|
|
menu2codes[idx] = verb.ref
|
|
end
|
|
end
|
|
end
|
|
|
|
function show_items()
|
|
local verb = game[currVerb]
|
|
local parCode = verb.params[#params+1]
|
|
-- print("parCode="..parCode)
|
|
window:ui_cls_menu();
|
|
menu2codes={}
|
|
for i,item in ipairs(item_ord) do
|
|
if item[parCode] and (verb.global_reach or item.w==here().ref or item.w=="me") then
|
|
local idx=#menu2codes+1
|
|
window:ui_add_menu(idx, item.n);
|
|
menu2codes[idx] = item.ref
|
|
end
|
|
end
|
|
if #menu2codes=="0" then
|
|
show_verbs() -- situace kdy není možné zobrazit další krok v menu
|
|
-- TODO - vyřešit nějak líp
|
|
end
|
|
end
|
|
|
|
function process_param(param)
|
|
if paramsNo == 0 then
|
|
currVerb = param
|
|
paramsNo = #game[currVerb].params
|
|
else
|
|
params[#params+1]=param
|
|
end
|
|
|
|
-- debug:
|
|
|
|
--[[
|
|
print("param="..param)
|
|
print("params="..table.concat(params," "))
|
|
print("currVerb="..currVerb)
|
|
print("paramsNo="..paramsNo)
|
|
print("#params="..#params)
|
|
print "---"
|
|
]]
|
|
|
|
if #params==paramsNo then
|
|
p ""
|
|
p("> " .. table.concat(issued_command, " "))
|
|
issued_command = {}
|
|
game[currVerb].act(table.unpack(params))
|
|
if game.round then
|
|
game.round()
|
|
end
|
|
show_verbs()
|
|
else
|
|
show_items()
|
|
end
|
|
|
|
end
|
|
|
|
-- game defaults
|
|
|
|
game = {
|
|
title = "Emty game",
|
|
me = item{
|
|
w="intro"
|
|
},
|
|
intro = room{
|
|
n="void",
|
|
d="YOU ARE IN A MAZE OF TWISTY LITTLE PASSAGES, ALL ALIKE.",
|
|
ref = "intro"
|
|
},
|
|
void = room{
|
|
n="void",
|
|
d="YOU ARE IN A MAZE OF TWISTY LITTLE PASSAGES, ALL ALIKE.",
|
|
ref = "void"
|
|
},
|
|
vars = {}
|
|
}
|
|
|
|
-- utils
|
|
|
|
function read_config(filename)
|
|
filename = filename or ''
|
|
assert(type(filename) == 'string')
|
|
local ans,u,k,v,temp = {}, '_'
|
|
local f = io.open(filename)
|
|
if f then
|
|
f:close()
|
|
for line in io.lines(filename) do
|
|
temp = line:match('^%[(.+)%]$')
|
|
if temp ~= nil and u ~= temp then u = temp end
|
|
k,v = line:match('^([^=]+)=(.+)$')
|
|
if u ~= nil then
|
|
ans[u] = ans[u] or {}
|
|
if k ~= nil then
|
|
ans[u][k] = v
|
|
end
|
|
end
|
|
end
|
|
return ans
|
|
else
|
|
return {}
|
|
end
|
|
end
|
|
|
|
-- GUI
|
|
|
|
-- loads game
|
|
load_game, err = loadfile(gamefile, "t", setmetatable(game, {__index=_G}))
|
|
|
|
if err then
|
|
window:ui_errormsg(err)
|
|
-- os.exit(1)
|
|
end
|
|
|
|
load_game()
|
|
|
|
local refcnt = 0
|
|
-- add refs
|
|
for ref,obj in pairs(game) do
|
|
if type(obj)=='table' and (obj.is_verb or obj.is_room or obj.is_item) then
|
|
obj.ref = ref
|
|
refcnt = refcnt + 1
|
|
end
|
|
end
|
|
|
|
-- stupid cyber arm glitching again!
|
|
for i,obj in ipairs(verb_ord) do
|
|
print("verb " .. obj.ref)
|
|
end
|
|
for i,obj in ipairs(room_ord) do
|
|
print("room " .. obj.ref)
|
|
end
|
|
for i,obj in ipairs(item_ord) do
|
|
print("item " .. obj.ref)
|
|
end
|
|
|
|
print("refcnt = " .. refcnt)
|
|
print("#verb_ord = " .. #verb_ord)
|
|
print("#room_ord = " .. #room_ord)
|
|
print("#item_ord = " .. #item_ord)
|
|
print("#sum_ord = " .. #verb_ord + #room_ord + #item_ord)
|
|
|
|
local ok, err = pcall(walk, "intro")
|
|
if not ok then
|
|
window:ui_errormsg(err)
|
|
end
|
|
|
|
window.document:getElementById("menu"):addEventListener("click", function(eL, ev)
|
|
local target = ev.target;
|
|
local code = target:getAttribute("data-code")
|
|
|
|
local text = target.innerText
|
|
local i = tonumber(code)
|
|
|
|
issued_command[#issued_command+1] = text
|
|
|
|
local ok, err = pcall(process_param, menu2codes[i])
|
|
if not ok then
|
|
window:ui_errormsg(err)
|
|
show_verbs()
|
|
end
|
|
|
|
ev:stopPropagation();
|
|
ev:preventDefault();
|
|
end)
|
|
|
|
</script>
|
|
|
|
|
|
</body>
|
|
</html>
|