1 //
2 // This is a temporary copy of the player functions as originally
3 // defined in the editor (as opposed to the stand-alone player).
4 // These have been extracted to make the stand-alone player shared
5 // between the editor and the exported games.
6 //
7 // THIS CAN BE DELETED WHEN THAT REFACTORING IS COMPLETE!
8 //
9
10
11 function play_obj(obj){
12 is_stopped = false;
13 rendered_paragraphs = [];
14 if("*Always Before" in objs){
15 render_obj(objs['*Always Before'], true);
16 }
17 render_obj(obj, false);
18 if("*Always After" in objs){
19 render_obj(objs['*Always After'], true);
20 }
21 }
22
23 function render_obj(obj){
24 // Refactoring this from a strictly functional style
25 // to rendering into a global array because it's actually
26 // way cleaner this way. (!)
27 var p = ['p'];
28
29 // Logic Stack for if/else/endif instruction rules:
30 // * if pushes true or false on the logic stack
31 // * else inverts the last item on the stack
32 // * endif pops the last item on the stack
33 // Current statement is only "true" if entire stack is true.
34 var logic_stack = [];
35
36 function ls_true(){
37 if(ls_empty()) return true;
38 return logic_stack.every(function(s){ return s; });
39 }
40 function ls_empty(){
41 return (logic_stack.length < 1);
42 }
43 function ls_invert_last(){
44 var last = logic_stack.length-1;
45 logic_stack[last] = !logic_stack[last];
46 }
47
48 obj.forEach(function(c){
49 if(is_stopped) return;
50
51 if(c[TYPE] === 'if'){
52 v = getval(c[KEY]);
53 logic_stack.push(v == c[VAL]);
54 return;
55 }
56 if(c[TYPE] === 'else'){
57 if(ls_empty()){
58 logic_stack.push(false);
59 return;
60 }
61 ls_invert_last();
62 return;
63 }
64 if(c[TYPE] === 'endif'){
65 if(!ls_empty()){
66 logic_stack.pop();
67 }
68 return;
69 }
70
71 // if logic stack has a "falsy" value, skip!
72 if(!ls_true()){
73 return;
74 }
75
76 // NEWSTUFF GOES HERE 3
77
78 if(c[TYPE] === 'stop'){ is_stopped = true; return; }
79
80 // insert...here
81 if(c[TYPE] === 'insert'){
82 rendered_paragraphs.push(p); // add last one
83 p = ['p']; // start a new one
84
85 // limit inserts (prevent crash from infinite recursion)
86 inserts++;
87 if(inserts > insert_limit){
88 p.push("...");
89 return;
90 }
91 if(objs[c[FRIEND]]){
92 render_obj(objs[c[FRIEND]], true);
93 }
94 else{
95 p.push(['button', {onclick:create_script(c[FRIEND])},
96 'Create "'+c[FRIEND]+'"']);
97 }
98 return;
99 }
100 if(c[TYPE] === 'deco'){
101 p.push(['.deco', ['i', c[TXT]], ['b']]);
102 return;
103 }
104 if(c[TYPE] === 'txt'){
105 // Only add space where there isn't punctuation.
106 var before = c[TXT].match(/^\W/) ? "" : " ";
107 var after = c[TXT].match(/\W$/) ? "" : " ";
108 p.push(before + c[TXT] + after);
109 return;
110 }
111 if(c[TYPE] === 'link'){
112 if(objs[c[TO]]){
113 p.push(['a', {onclick:link(c[TO])}, c[TXT]]);
114 }
115 else{
116 p.push(['button', {onclick:create_script(c[TO])},
117 'Create "'+c[TO]+'"']);
118 }
119 return;
120 }
121
122 // paragraph/line break
123 if(c[TYPE] === 'break'){
124 if(p.length < 2){
125 // Keep empty paragraph open...
126 return;
127 }
128 rendered_paragraphs.push(p); // add last one
129 p = ['p']; // start a new one
130 return;
131 }
132
133 // var/inc/dec
134 if(c[TYPE] === 'var'){
135 vars[c[KEY]] = c[VAL];
136 return;
137 }
138 if(c[TYPE] === 'inc'){
139 v = getval(c[KEY]);
140 if(isNaN(v)){
141 txt_size(c[KEY], +1);
142 }
143 else{
144 vars[c[KEY]] = Number(v)+1;
145 }
146 return;
147 }
148 if(c[TYPE] === 'dec'){
149 v = getval(c[KEY]);
150 if(isNaN(v)){
151 txt_size(c[KEY], -1);
152 }
153 else{
154 vars[c[KEY]] = Number(v)-1;
155 }
156 return;
157 }
158 if(c[TYPE] === 'print'){
159 sz=txt_size(c[KEY],0);
160 txt=getval(c[KEY]);
161 if(sz!=1)
162 p.push(['span',{'class':'sz'+sz},txt]);
163 else
164 p.push(txt);
165 return;
166 }
167 });
168 if(p.length > 1){
169 // We put something in that last one.
170 rendered_paragraphs.push(p);
171 }
172 }
173
174 function txt_size(key, amt){
175 var sz;var_txt_size[key]
176 if(!(key in var_txt_size)){
177 sz = 1;
178 }
179 else{
180 sz = var_txt_size[key];
181 }
182 sz+=amt;
183 // min and max
184 sz = Math.min(5, Math.max(-4, sz));
185 // var_txt_size[key] = sz;
186 return var_txt_size[key] = sz;
187 }
188
189 function getval(key){
190 if(!(key in vars)){
191 vars[key] = 'EMPTY';
192 }
193 return vars[key];
194 }
195
196 function link(to){
197 return function(){
198 rename_msg = null;
199 delete_prompt = false;
200 editing_name = false;
201 adding_script = false;
202 current_name = to;
203 current_obj = objs[to];
204 display_script = obj_to_script(current_obj);
205 highlight_script = script_to_highlights(display_script);
206 draw();
207 };
208 }