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 }