1 /*
2
3 This is the 'runtime' for Hoot. It's the code that makes a Hoot game playable.
4 A minified copy of this entire script is in examplegame.html to make it run.
5
6 NOTE: examplegame.html copy minified with UglifyJS (at jscompress.com)
7
8
9
10 TODO: runtime needs for the "location" var to mean the current location
11 so that the engine can always display a clickable with the location name
12 as a clickable title in the game display
13
14 ALSO: allow location to be set to something invalid (like NOWHERE) which
15 will not display the location at all
16
17 ALSO: might want to do something similar for an inventory (game author
18 would be responsible for creating inventory interface)
19
20 */
21
22
23
24 function rungame(tree, outputarea){
25 var gamevars = [];
26 var upper = false;
27
28 // the first element in the tree will be array of the rest of the tree
29 tree = tree[0];
30
31 outputarea.empty();
32 runfunc('start');
33
34 function runfunc(funcname){
35 thefunc = findfunc(funcname);
36 if(!thefunc){ alert("Sorry, can't continue because I couldn't find a thing named \""+funcname+"\"."); return; }
37 // console.log("running function "+thefunc[1][1]);
38 expressions(thefunc, 2);
39 }
40
41 function findfunc(funcname){
42 for(s in tree){
43 if(tree[s][1] && tree[s][1][1] && tree[s][1][1].toLowerCase() == funcname.toLowerCase()){
44 return tree[s];
45 }
46 }
47 return null;
48 }
49
50 function expression(expr){
51 switch(expr[0]){
52 case 'assign':
53 // console.log("assigning "+expr[1][1]+" to "+expr[2][1]);
54 gamevars[expr[1][1].toLowerCase()] = expr[2][1];
55
56 break;
57 case 'print': print(expr); break;
58 case 'ifseq': ifsequence(expr); break;
59 case 'runme': runfunc(expr[1][1]); break;
60 case 'decr': gamevars[expr[1][1].toLowerCase()]--; break;
61 case 'incr': gamevars[expr[1][1].toLowerCase()]++; break;
62 case 'elseseq': break; // do nothing, this will run if needed
63 default: alert("Sorry, I wasn't expecting a '"+expr[0]+"' in the script. :-(");
64 }
65 }
66
67 function expressions(list, startpos){
68 // run multiple expressions from a list, starting from startpos
69 for(var e=startpos; e<list.length; e++){
70 expression(list[e]);
71 }
72 }
73
74 function ifsequence(tree){
75 var val1 = tree[1][1];
76 var test_opr = tree[2][1];
77 var val2 = tree[3][1];
78
79 // console.log("Test: "+val1+" "+test_opr+" "+val2);
80
81 if(tree[1][0] == "name"){ val1=gamevars[val1.toLowerCase()]; }
82 if(tree[3][0] == "name"){ val2=gamevars[val2.toLowerCase()]; }
83
84 // console.log("translates to: "+val1+" "+test_opr+" "+val2);
85
86
87 if( (test_opr == "equals" && val1 == val2) ||
88 (test_opr == "less than" && val1 < val2) ||
89 (test_opr == "greater than" && val1 > val2) ||
90 (test_opr == "doesn't equal" && val1 != val2) ){
91 // console.log("true");
92 expressions(tree,4);
93 }
94 else{
95 // console.log("false");
96 // see if there's an else to run
97 for(e in tree){
98 if(tree[e][0] == "elseseq"){
99 expressions(tree[e],1);
100 }
101 }
102 }
103 }
104
105 function print(printables){
106 for(var p = 1; p<printables.length; p++){
107 type = printables[p][0]; // the type of printable item
108 body = printables[p][1]; // the body of the printable
109 // console.log("printing "+type+": "+body);
110 switch(type){
111 case 'string' : printstr(body); break;
112 case 'strname' : printname(body); break;
113 case 'upname' : upper = true; printname(body); break;
114 case 'link' : printlink(body); break;
115 case 'break' : printbreak(); break;
116 default: alert("Sorry, I don't know how to display a '"+type+"'. :-(");
117 }
118 }
119 }
120
121 function printname(name){
122 name = name.toLowerCase();
123 if(name in gamevars){
124 printstr(gamevars[name]);
125 return;
126 }
127 if(findfunc(name)){
128 runfunc(name);
129 return;
130 }
131 alert("Sorry, couldn't find anything called '"+name+"' to display.");
132 }
133
134 function printstr(str){
135 str = String(str);
136 str = str.replace(/\\\//g,'/');
137 if(upper){
138 upper = false; // we've done it, don't do it again until requested
139 printstr(str.charAt(0).toUpperCase()+str.slice(1));
140 return;
141 }
142 outputarea.append("<span>"+str+"</span>");
143 }
144
145 function printlink(funcname){
146 outputarea.append($("<a href=\"#\">"+body+"</a>").click(function(){
147 outputarea.empty();
148 runfunc(funcname);
149 return false;
150 }));
151 }
152
153 function printbreak(){
154 outputarea.append("<hr>");
155 }
156 }