denki_guy 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1151 @@
1
+ // ---
2
+ // Copyright (c) 2010 Francesco Cottone, http://www.kesiev.com/
3
+ // ---
4
+
5
+ var toys={
6
+
7
+ // CONSTANTS
8
+ NOOP:function(){},
9
+ PUSH_NONE:0,
10
+ PUSH_LEFT:1,
11
+ PUSH_RIGHT:2,
12
+ PUSH_UP:3,
13
+ PUSH_DOWN:4,
14
+
15
+ FACES:["up","right","down","left"],
16
+ FACES_ANGLE:[trigo.ANGLE_UP,trigo.ANGLE_RIGHT,trigo.ANGLE_DOWN,trigo.ANGLE_LEFT],
17
+ FACE_UP:0,
18
+ FACE_RIGHT:1,
19
+ FACE_DOWN:2,
20
+ FACE_LEFT:3,
21
+
22
+ // Top-view (Zelda-alike) specifics
23
+
24
+ topview:{
25
+ collides:function(fr,to,t) { // Special collision. Counts also the Z
26
+ if (Math.abs(fr.z,to.z)<5) return gbox.collides({x:fr.x+fr.colx,y:fr.y+fr.coly,h:fr.colh,w:fr.colw},{x:to.x+to.colx,y:to.y+to.coly,h:to.colh,w:to.colw},t); else return false;
27
+ },
28
+ pixelcollides:function(fr,to,t) { // Special collision. Counts also the Z
29
+ return gbox.pixelcollides(fr,{x:to.x+to.colx,y:to.y+to.coly,h:to.colh,w:to.colw},t);
30
+ },
31
+ initialize:function(th,data) {
32
+ help.mergeWithModel(
33
+ th,
34
+ help.mergeWithModel(
35
+ data,
36
+ {
37
+ x:0, y:0,
38
+ z:0,
39
+ accx:0, accy:0, accz:0,
40
+ frames:{},
41
+ shadow:null,
42
+ maxacc:4, controlmaxacc:4,
43
+ responsive:0, // Responsiveness
44
+ weapon:0, // Weapon
45
+ camera:true,
46
+ flipv:false, fliph:false,
47
+ facing:player_faces(),
48
+ flipside:true,
49
+ haspushing:false,
50
+ frame:0,
51
+ colh:gbox.getTiles(th.tileset).tilehh,
52
+ colw:gbox.getTiles(th.tileset).tilew,
53
+ colx:0,
54
+ staticspeed:0,
55
+ nodiagonals:false,
56
+ noreset:false
57
+ }
58
+ )
59
+ );
60
+ if (th.coly==null) th.coly=gbox.getTiles(th.tileset).tileh-th.colh;
61
+ th.colhh=Math.floor(th.colh/2);
62
+ th.colhw=Math.floor(th.colw/2);
63
+
64
+ toys.topview.spawn(th);
65
+ },
66
+ spawn:function(th,data) {
67
+ th.xpushing=toys.PUSH_NONE; // user is moving side
68
+ th.vpushing=toys.PUSH_NONE; // user is moving side
69
+ th.zpushing=toys.PUSH_NONE; // user is moving side
70
+ th.counter=0; // self counter
71
+ th.hittimer=0;
72
+ th.killed=false;
73
+ help.copyModel(th,data);
74
+ gbox.setZindex(th,th.y+th.h); // these object follows the z-index and uses ZINDEX_LAYER
75
+ },
76
+ controlKeys:function(th,keys) {
77
+ var cancelx=false;
78
+ var cancely=false;
79
+ var idlex=false;
80
+ var idley=false;
81
+
82
+ if (gbox.keyIsPressed(keys.left)||keys.pressleft) {
83
+ th.xpushing=toys.PUSH_LEFT;
84
+ th.facing=toys.FACE_LEFT;
85
+ if (th.accx>th.responsive) th.accx=th.responsive;
86
+ if (th.staticspeed) th.accx=-th.staticspeed; else th.accx=help.limit(th.accx-1,-th.controlmaxacc,th.controlmaxacc);
87
+ if (th.nodiagonals) { cancely=true; idley=true }
88
+ } else if (gbox.keyIsPressed(keys.right)||keys.pressright) {
89
+ th.xpushing=toys.PUSH_RIGHT;
90
+ th.facing=toys.FACE_RIGHT;
91
+ if (th.accx<-th.responsive) th.accx=-th.responsive;
92
+ if (th.staticspeed) th.accx=th.staticspeed; else th.accx=help.limit(th.accx+1,-th.controlmaxacc,th.controlmaxacc);
93
+ if (th.nodiagonals) { cancely=true; idley=true }
94
+ } else idlex=true;
95
+
96
+ if (!cancely&&(gbox.keyIsPressed(keys.up)||keys.pressup)) {
97
+ th.ypushing=toys.PUSH_UP;
98
+ th.facing=toys.FACE_UP;
99
+ if (th.accy>th.responsive) th.accy=th.responsive;
100
+ if (th.staticspeed) th.accy=-th.staticspeed; else th.accy=help.limit(th.accy-1,-th.controlmaxacc,th.controlmaxacc);
101
+ if (th.nodiagonals) { cancelx=true; idlex=true; }
102
+ } else if (!cancely&&(gbox.keyIsPressed(keys.down)||keys.pressdown)) {
103
+ th.ypushing=toys.PUSH_DOWN;
104
+ th.facing=toys.FACE_DOWN;
105
+ if (th.accy<-th.responsive) th.accy=-th.responsive;
106
+ if (th.staticspeed) th.accy=th.staticspeed; else th.accy=help.limit(th.accy+1,-th.controlmaxacc,th.controlmaxacc);
107
+ if (th.nodiagonals) { cancelx=true; idlex=true; }
108
+ } else idley=true;
109
+
110
+
111
+
112
+ if (idlex) {
113
+ if (cancelx) th.accx=0;
114
+ if (cancelx||!th.noreset) th.xpushing=toys.PUSH_NONE;
115
+ }
116
+ if (idley) {
117
+ if (cancely) th.accy=0;
118
+ if (cancely||!th.noreset) th.ypushing=toys.PUSH_NONE;
119
+ }
120
+ },
121
+ getNextX:function(th) { return th.x+help.limit(th.accx,-th.maxacc,th.maxacc); },
122
+ getNextY:function(th) { return th.y+help.limit(th.accy,-th.maxacc,th.maxacc); },
123
+ getNextZ:function(th) { return th.z+help.limit(th.accz,-th.maxacc,th.maxacc); },
124
+ applyForces:function(th) {
125
+ th.x=toys.topview.getNextX(th);
126
+ th.y=toys.topview.getNextY(th);
127
+ },
128
+ applyGravity:function(th) {
129
+ th.z=toys.topview.getNextZ(th);
130
+ },
131
+ handleAccellerations:function(th) {
132
+ if (!th.xpushing) th.accx=help.goToZero(th.accx);
133
+ if (!th.ypushing) th.accy=help.goToZero(th.accy);
134
+
135
+ },
136
+ handleGravity:function(th) {
137
+ th.accz++;
138
+ },
139
+ setFrame:function(th) {
140
+ var pref="stand";
141
+ if (th.xpushing||th.ypushing)
142
+ if (th.haspushing&&(th.toucheddown||th.touchedup||th.touchedleft||th.touchedright)) pref="pushing"; else pref="moving";
143
+ if (th.flipside)
144
+ th.fliph=(th.facing==toys.FACE_RIGHT);
145
+ th.frame=help.decideFrame(th.counter,th.frames[pref+toys.FACES[th.facing]]);
146
+ },
147
+ tileCollision:function(th,map,tilemap,defaulttile,data) {
148
+
149
+ th.touchedup=false;
150
+ th.toucheddown=false;
151
+ th.touchedleft=false;
152
+ th.touchedright=false;
153
+
154
+ var tollerance=(data&&(data.tollerance!=null)?data.tollerance:6);
155
+ var approximation=(data&&(data.approximation!=null)?data.approximation:10);
156
+ var t=tollerance-approximation;
157
+ do {
158
+ t+=approximation;
159
+ if (t>th.colw-tollerance-1) t=th.colw-tollerance-1;
160
+ var bottom=help.getTileInMap(th.x+th.colx+t,th.y+th.coly+th.colh-1,map,defaulttile,tilemap);
161
+ var top=help.getTileInMap(th.x+th.colx+t,th.y+th.coly,map,defaulttile,tilemap);
162
+ if (map.tileIsSolid(th,top)) th.touchedup=true;
163
+ if (map.tileIsSolid(th,bottom)) th.toucheddown=true;
164
+ } while (t!=th.colw-tollerance-1);
165
+
166
+ t=tollerance-approximation;
167
+ do {
168
+ t+=approximation;
169
+ if (t>th.colh-tollerance-1) t=th.colh-tollerance-1;
170
+ var left=help.getTileInMap(th.x+th.colx,th.y+th.coly+t,map,defaulttile,tilemap);
171
+ var right=help.getTileInMap(th.x+th.colx+th.colw-1,th.y+th.coly+t,map,defaulttile,tilemap);
172
+ if (map.tileIsSolid(th,left)) th.touchedleft=true;
173
+ if (map.tileIsSolid(th,right)) th.touchedright=true;
174
+ } while (t!=th.colh-tollerance-1);
175
+
176
+ if (th.touchedup) {
177
+ th.accy=0;
178
+ th.y=help.yPixelToTile(map,th.y+th.coly,1)-th.coly;
179
+ }
180
+ if (th.toucheddown) {
181
+ th.accy=0;
182
+ th.y=help.yPixelToTile(map,th.y+th.coly+th.colh-1)-th.coly-th.colh;
183
+ }
184
+ if (th.touchedleft) {
185
+ th.accx=0;
186
+ th.x=help.xPixelToTile(map,th.x+th.colx,1)-th.colx;
187
+ }
188
+ if (th.touchedright) {
189
+ th.accx=0;
190
+ th.x=help.xPixelToTile(map,th.x+th.colx+th.colw-1)-th.colx-th.colw;
191
+ }
192
+
193
+ },
194
+ spritewallCollision:function(th,data) {
195
+ var wl;
196
+ for (var i in gbox._objects[data.group])
197
+ if ((!gbox._objects[data.group][i].initialize)&&toys.topview.collides(th,gbox._objects[data.group][i])) {
198
+ wl=gbox._objects[data.group][i];
199
+ if (toys.topview.pixelcollides({x:th.x+th.colx,y:th.y+th.coly+th.colhh},wl)) {
200
+ th.touchedleft=true;
201
+ th.accx=0;
202
+ th.x=wl.x+wl.colx+wl.colw-th.colx+1;
203
+ } else if (toys.topview.pixelcollides({x:th.x+th.colx+th.colw,y:th.y+th.coly+th.colhh},wl)) {
204
+ th.touchedright=true;
205
+ th.accx=0;
206
+ th.x=wl.x+wl.colx-th.colw-th.colx-1;
207
+ }
208
+ if (toys.topview.pixelcollides({x:th.x+th.colx+th.colhw,y:th.y+th.coly+th.colh},wl)) {
209
+ th.toucheddown=true;
210
+ th.accy=0;
211
+ th.y=wl.y+wl.coly-th.colh-th.coly;
212
+ } else if (toys.topview.pixelcollides({x:th.x+th.colx+th.colhw,y:th.y+th.coly},wl)) {
213
+ th.touchedup=true;
214
+ th.accy=0;
215
+ th.y=wl.y+wl.coly+wl.colh-th.coly;
216
+ }
217
+ }
218
+
219
+ },
220
+ floorCollision:function(th,data) {
221
+ th.touchedfloor=false;
222
+ if (th.z>0) {
223
+ th.accz=(data==null?0:-Math.floor(th.accz/data.bounce));
224
+ th.z=0;
225
+ th.touchedfloor=true;
226
+ }
227
+ },
228
+ adjustZindex:function(th) {
229
+ gbox.setZindex(th,th.y+th.h);
230
+ },
231
+ // Helper: returns the ahead pixel (i.e. destination use action)
232
+ getAheadPixel:function(th,data) {
233
+ switch (th.facing) {
234
+ case toys.FACE_RIGHT:{
235
+ return {x:th.x+th.colx+th.colw+data.distance,y:th.y+th.coly+th.colhh};
236
+ break;
237
+ }
238
+ case toys.FACE_LEFT:{
239
+ return {x:th.x+th.colx-data.distance,y:th.y+th.coly+th.colhh};
240
+ break;
241
+ }
242
+ case toys.FACE_UP:{
243
+ return {x:th.x+th.colx+th.colhw,y:th.y+th.coly-data.distance};
244
+ break;
245
+ }
246
+ case toys.FACE_DOWN:{
247
+ return {x:th.x+th.colx+th.colhw,y:th.y+th.coly+th.colh+data.distance};
248
+ break;
249
+ }
250
+ }
251
+ },
252
+ // Helper: trigger a method in colliding objects (i.e. "use action")
253
+ callInColliding:function(th,data) {
254
+ for (var i in gbox._objects[data.group])
255
+ if ((!gbox._objects[data.group][i].initialize)&&toys.topview.pixelcollides(data,gbox._objects[data.group][i]))
256
+ if (gbox._objects[data.group][i][data.call]) {
257
+ gbox._objects[data.group][i][data.call](th);
258
+ return i;
259
+ }
260
+ return false;
261
+ },
262
+ // Enemy methods
263
+ wander:function(th,map,tilemap,defaulttile,data) {
264
+ if ((!th.wandercounter)||(th.toucheddown||th.touchedup||th.touchedleft||th.touchedright)) {
265
+ th.wandercounter=help.random(data.minstep,data.steprange);
266
+ th.wanderdirection=help.random(0,4);
267
+ } else th.wandercounter--;
268
+ switch (th.wanderdirection) {
269
+ case toys.FACE_LEFT: {
270
+ th.xpushing=toys.PUSH_LEFT;
271
+ th.ypushing=toys.PUSH_NONE;
272
+ th.facing=toys.FACE_LEFT;
273
+ th.accx=-data.speed;
274
+ th.accy=0;
275
+ break;
276
+ }
277
+ case toys.FACE_RIGHT: {
278
+ th.xpushing=toys.PUSH_RIGHT;
279
+ th.ypushing=toys.PUSH_NONE;
280
+ th.facing=toys.FACE_RIGHT;
281
+ th.accx=data.speed;
282
+ th.accy=0;
283
+ break;
284
+ }
285
+ case toys.FACE_UP: {
286
+ th.ypushing=toys.PUSH_UP;
287
+ th.xpushing=toys.PUSH_NONE;
288
+ th.facing=toys.FACE_UP;
289
+ th.accy=-data.speed;
290
+ th.accx=0;
291
+ break;
292
+ }
293
+ case toys.FACE_DOWN: {
294
+ th.ypushing=toys.PUSH_DOWN;
295
+ th.xpushing=toys.PUSH_NONE;
296
+ th.facing=toys.FACE_DOWN;
297
+ th.accy=data.speed;
298
+ th.accx=0;
299
+ break;
300
+ }
301
+ }
302
+ },
303
+ // generators (firebullet specific for topdown - more complex than SHMUP one)
304
+ fireBullet:function(gr,id,data) {
305
+
306
+ var ts=gbox.getTiles(data.tileset);
307
+
308
+
309
+ var obj=gbox.addObject(
310
+ help.mergeWithModel(
311
+ data,{
312
+ _bullet:true,
313
+ zindex:0,
314
+ fliph:false, flipv:false,
315
+ id:id,
316
+ group:gr,
317
+ cnt:0,
318
+ tileset:"",
319
+ frames:{},
320
+ acc:0,
321
+ angle:0,
322
+ camera:data.from.camera,
323
+ accx:(data.accx==null?Math.floor(trigo.translateX(0,data.angle,data.acc)):0),
324
+ accy:(data.accy==null?Math.floor(trigo.translateY(0,data.angle,data.acc)):0),
325
+ accz:0,
326
+ x:(data.sidex==toys.FACE_LEFT?data.from.x-ts.tilehw:(data.sidex==toys.FACE_RIGHT?data.from.x+data.from.w-ts.tilehw:data.from.x+data.from.hw-ts.tilehw))+(data.gapx?data.gapx:0),
327
+ y:(data.sidey==toys.FACE_UP?data.from.y-ts.tilehh:(data.sidey==toys.FACE_DOWN?data.from.y+data.from.h-ts.tilehh:data.from.y+data.from.hh-ts.tilehh))+(data.gapy?data.gapy:0),
328
+ z:(data.from.z==null?0:data.from.z),
329
+ collidegroup:"",
330
+ spark:toys.NOOP,
331
+ power:1,
332
+ lifetime:null,
333
+ tilemap:null,
334
+ defaulttile:0,
335
+ applyzgravity:false,
336
+ map:null,
337
+ defaulttile:0,
338
+ mapindex:"",
339
+ spritewalls:null,
340
+ colx:(data.fullhit?0:null),
341
+ coly:(data.fullhit?0:null),
342
+ colh:(data.fullhit?ts.tileh:null),
343
+ colw:(data.fullhit?ts.tilew:null),
344
+ duration:null,
345
+ onWallHit:function() {
346
+ this.spark(this);
347
+ gbox.trashObject(this);
348
+ },
349
+ bulletIsAlive:function() {
350
+ return gbox.objectIsVisible(this);
351
+ }
352
+ }
353
+ )
354
+ );
355
+
356
+ obj.initialize=function() {
357
+ toys.topview.initialize(this);
358
+ };
359
+
360
+ obj[(data.logicon==null?"first":data.logicon)]=function() {
361
+ this.cnt=(this.cnt+1)%10;
362
+
363
+ if (this.applyzgravity) toys.topview.handleGravity(this); // z-gravity
364
+ toys.topview.applyForces(this); // Apply forces
365
+ if (this.applyzgravity) toys.topview.applyGravity(this); // z-gravity
366
+ if (this.map!=null) toys.topview.tileCollision(this,this.map,this.mapindex,this.defaulttile); // tile collisions
367
+ if (this.spritewalls!=null) toys.topview.spritewallCollision(this,{group:this.spritewalls}); // walls collisions
368
+ if (this.applyzgravity) toys.topview.floorCollision(this); // Collision with the floor (for z-gravity)
369
+ toys.topview.adjustZindex(this);
370
+ if (this.duration!=null) {
371
+ this.duration--;
372
+ if (this.duration==0) gbox.trashObject(this);
373
+ }
374
+ if (!this.bulletIsAlive()) gbox.trashObject(this);
375
+ else if (this.toucheddown||this.touchedup||this.touchedleft||this.touchedright) this.onWallHit();
376
+ else if (this.collidegroup!=null)
377
+ for (var i in gbox._objects[this.collidegroup])
378
+ if ((!gbox._objects[this.collidegroup][i].initialize)&&toys.topview.collides(this,gbox._objects[this.collidegroup][i],gbox._objects[this.collidegroup][i].tollerance)) {
379
+ if (gbox._objects[this.collidegroup][i]["hitByBullet"]!=null)
380
+ if (!gbox._objects[this.collidegroup][i].hitByBullet(this)) {
381
+ this.spark(this);
382
+ gbox.trashObject(this);
383
+ }
384
+ }
385
+ }
386
+
387
+ obj[(data.bliton==null?"blit":data.bliton)]=function() {
388
+ if (!gbox.objectIsTrash(this))
389
+ gbox.blitTile(gbox.getBufferContext(),{tileset:this.tileset,tile:help.decideFrame(this.cnt,this.frames),dx:this.x,dy:this.y+this.z,camera:this.camera,fliph:this.fliph,flipv:this.flipv});
390
+ }
391
+
392
+ gbox.setZindex(obj,obj.y+obj.h);
393
+
394
+ return obj;
395
+
396
+ },
397
+ makedoor:function(gr,id,map,data) {
398
+
399
+ var mts=gbox.getTiles(map.tileset);
400
+ var ts=gbox.getTiles(data.tileset);
401
+
402
+ var obj=gbox.addObject(
403
+ help.mergeWithModel(
404
+ data,{
405
+ zindex:0,
406
+ fliph:false, flipv:false,
407
+ id:id,
408
+ group:gr,
409
+ cnt:0,
410
+ tileset:"",
411
+ frames:{},
412
+ camera:true,
413
+ x:data.tilex*mts.tilew,
414
+ y:data.tiley*mts.tileh,
415
+ z:0,
416
+ tilemap:null,
417
+ defaulttile:0,
418
+ map:map,
419
+ colx:(data.fullhit?0:null),
420
+ coly:(data.fullhit?0:null),
421
+ colh:(data.fullhit?ts.tileh:null),
422
+ colw:(data.fullhit?ts.tilew:null),
423
+ opening:false,
424
+ doorheight:ts.tileh,
425
+ opencounter:0,
426
+ opening:false,
427
+ closing:false,
428
+ doOpen:function() {
429
+ this.opening=true;
430
+ },
431
+ whenClosed:toys.NOOP,
432
+ whenOpened:toys.NOOP,
433
+ whileMoving:toys.NOOP,
434
+ hitByBullet:function(by) {
435
+
436
+ }
437
+ }
438
+ )
439
+ );
440
+
441
+ // Closing animation
442
+ if (obj.closing) obj.opencounter=obj.doorheight;
443
+
444
+ obj.initialize=function() {
445
+ toys.topview.initialize(this);
446
+ };
447
+
448
+ obj[(data.logicon==null?"first":data.logicon)]=function() {
449
+ if (this.closing) {
450
+ this.whileMoving();
451
+ this.opencounter--;
452
+ if (this.opencounter<0) {
453
+ this.opencounter=0;
454
+ this.closing=false;
455
+ this.whenClosed();
456
+ }
457
+ }
458
+ if (this.opening) {
459
+ this.whileMoving();
460
+ this.opencounter++;
461
+ if (this.opencounter>=this.doorheight) {
462
+ if (!this.whenOpened()) gbox.trashObject(this);
463
+ }
464
+ }
465
+ }
466
+
467
+ obj[(data.bliton==null?"blit":data.bliton)]=function() {
468
+ if (!gbox.objectIsTrash(this))
469
+ gbox.blitTile(gbox.getBufferContext(),{tileset:this.tileset,tile:help.decideFrame(this.cnt,this.frames),dx:this.x,dy:this.y+this.z+this.opencounter,h:this.h-this.opencounter,camera:this.camera,fliph:this.fliph,flipv:this.flipv});
470
+ }
471
+
472
+ gbox.setZindex(obj,obj.y+obj.h);
473
+
474
+ return obj;
475
+ },
476
+ // Set the object speed making sure that the X and Y coords are multiple of the speed. Useful on maze-based games.
477
+ setStaticSpeed:function(th,speed) {
478
+ th.staticspeed=speed;
479
+ th.x=Math.round(th.x/speed)*speed;
480
+ th.y=Math.round(th.y/speed)*speed;
481
+ }
482
+ },
483
+
484
+
485
+
486
+ // State-based toys
487
+ // CONSTANTS
488
+ TOY_BUSY:0,
489
+ TOY_DONE:1,
490
+ TOY_IDLE:2,
491
+
492
+ // PRIVATE
493
+
494
+ // Generical toys method
495
+ resetToy:function(th,id) { if (th.toys) delete th.toys[id] },
496
+ getToyValue:function(th,id,v,def) { return ((th.toys==null)||(th.toys[id]==null)?def:th.toys[id][v]) },
497
+ getToyStatus:function(th,id) { return ((th.toys==null)||(th.toys[id]==null)?toys.TOY_BUSY:th.toys[id].__status) },
498
+
499
+ _toydone:function(th,id) {
500
+ if (th.toys[id].__status<toys.TOY_IDLE) th.toys[id].__status++;
501
+ return th.toys[id].__status;
502
+ },
503
+ _toybusy:function(th,id) {
504
+ th.toys[id].__status=toys.TOY_BUSY;
505
+ return th.toys[id].__status;
506
+ },
507
+ _toyfrombool:function(th,id,b) { return (b?toys._toydone(th,id):toys._toybusy(th,id)) },
508
+ _maketoy:function(th,id){
509
+ if (!th.toys) th.toys={};
510
+ if (!th.toys[id]) {
511
+ th.toys[id]={__status:toys.TOY_BUSY};
512
+ return true;
513
+ } else return false;
514
+ },
515
+ // Pure timers
516
+ timer:{
517
+ randomly:function(th,id,data) {
518
+ if (toys._maketoy(th,id)) {
519
+ th.toys[id].time=help.random(data.base,data.range);
520
+ }
521
+ if (th.toys[id].time) {
522
+ th.toys[id].time--;
523
+ return toys._toybusy(th,id);
524
+ } else {
525
+ th.toys[id].time=help.random(data.base,data.range);
526
+ return toys._toydone(th,id);
527
+ }
528
+ },
529
+ real:function(th,id,data) {
530
+ if (toys._maketoy(th,id)) {
531
+ th.toys[id].subtimer=gbox.getFps();
532
+ th.toys[id].done=false;
533
+ if (data.countdown)
534
+ th.toys[id].time=data.countdown;
535
+ else
536
+ th.toys[id].time=0;
537
+ }
538
+ th.toys[id].subtimer--;
539
+ if (!th.toys[id].subtimer) {
540
+ th.toys[id].subtimer=gbox.getFps();
541
+ if (data.countdown) {
542
+ if (th.toys[id].time) th.toys[id].time--; else th.toys[id].done=true;
543
+ } else
544
+ th.toys[id].time++;
545
+ }
546
+ return toys._toyfrombool(th,id,th.toys[id].done);
547
+
548
+ },
549
+ every:function(th,id,frames){
550
+ if (toys._maketoy(th,id)) th.toys[id].timer=0;
551
+ th.toys[id].timer++;
552
+ if (th.toys[id].timer==frames) {
553
+ th.toys[id].timer=0;
554
+ return toys._toydone(th,id);
555
+ } else return toys._toybusy(th,id)
556
+ },
557
+ after:function(th,id,frames) {
558
+ if (toys._maketoy(th,id)) th.toys[id].timer=0;
559
+ if (th.toys[id].timer==frames) return toys._toydone(th,id); else {
560
+ th.toys[id].timer++;
561
+ return toys._toybusy(th,id);
562
+ }
563
+ }
564
+ },
565
+ // Logical helpers
566
+ logic: {
567
+ once:function(th,id,cond){
568
+ if (toys._maketoy(th,id)) th.toys[id].done=false;
569
+ if (th.toys[id].done) return false; else if (cond) th.toys[id].done=true;
570
+ return cond;
571
+ }
572
+ },
573
+ // UI
574
+ ui:{
575
+ menu:function(th,id,opt) {
576
+ if (toys._maketoy(th,id)||opt.resetmenu) {
577
+ var fd=gbox._fonts[opt.font];
578
+ th.toys[id].selected=(opt.selected?opt.selected:0);
579
+ th.toys[id].ok=0;
580
+ var w=0;
581
+ for (var i=0;i<opt.items.length;i++)
582
+ if (opt.items[i].length>w) w=opt.items[i].length;
583
+ gbox.createCanvas("menu-"+id,{w:w*fd.tilew,h:opt.items.length*fd.tileh});
584
+ for (var i=0;i<opt.items.length;i++)
585
+ gbox.blitText(gbox.getCanvasContext("menu-"+id),{font:opt.font,text:opt.items[i],dx:0,dy:fd.tileh*i});
586
+ th.toys[id].fh=fd.tileh;
587
+ th.toys[id].fw=fd.tilew;
588
+ }
589
+ if (!th.toys[id].ok) {
590
+ if (gbox.keyIsHit(opt.keys.up)&&(th.toys[id].selected>0)) th.toys[id].selected--; else
591
+ if (gbox.keyIsHit(opt.keys.down)&&(th.toys[id].selected<opt.items.length-1)) th.toys[id].selected++; else
592
+ if (gbox.keyIsHit(opt.keys.ok)) th.toys[id].ok=1; else
593
+ if (gbox.keyIsHit(opt.keys.cancel)) th.toys[id].ok=-1;
594
+ }
595
+ gbox.blitAll(gbox.getBufferContext(),gbox.getCanvas("menu-"+id),{dx:opt.x+th.toys[id].fw,dy:opt.y,camera:opt.camera});
596
+ if (!(th.toys[id].ok%2)) gbox.blitText(gbox.getBufferContext(),{font:opt.font,text:opt.selector,dx:opt.x,dy:opt.y+th.toys[id].selected*th.toys[id].fh,camera:opt.camera});
597
+ if (th.toys[id].ok) {
598
+ if (th.toys[id].ok>0)
599
+ if (th.toys[id].ok<10) {
600
+ th.toys[id].ok++;
601
+ toys._toybusy(th,id);
602
+ } else return toys._toydone(th,id); // selected > 0
603
+ else return toys._toydone(th,id); // selected == -1
604
+ } else return toys._toybusy(th,id);
605
+ },
606
+
607
+ // Returns a full customizable object for optimized huds
608
+ hud:function(id) {
609
+ gbox.createCanvas(id);
610
+ return {
611
+ w:{},
612
+ surfaceid:id,
613
+
614
+ updateWidget:function(i){
615
+ if (!this.w[i].__hidden) {
616
+ if (this.w[i].widget=="label") {
617
+ if (this.w[i].prepad!=null) this.w[i].text=help.prepad(this.w[i].value,this.w[i].prepad,this.w[i].padwith); else
618
+ if (this.w[i].postpad!=null) this.w[i].text=help.postpad(this.w[i].value,this.w[i].postpad,this.w[i].padwith); else
619
+ this.w[i].text=this.w[i].value+"";
620
+ gbox.blitText(gbox.getCanvasContext(this.surfaceid),this.w[i]);
621
+ }
622
+ if (this.w[i].widget=="symbols") {
623
+ var ts=gbox.getTiles(this.w[i].tileset);
624
+ gbox.blitClear(gbox.getCanvasContext(this.surfaceid),{x:this.w[i].dx,y:this.w[i].dy,w:((this.w[i].maxshown-1)*this.w[i].gapx)+ts.tilew,h:((this.w[i].maxshown-1)*this.w[i].gapy)+ts.tileh});
625
+ var cnt=this.w[i].value;
626
+ for (var x=0;x<this.w[i].maxshown;x++) {
627
+ if (cnt>0) {
628
+ gbox.blitTile(gbox.getCanvasContext(this.surfaceid),{tileset:this.w[i].tileset,tile:this.w[i].tiles[(cnt>this.w[i].tiles.length?this.w[i].tiles.length-1:cnt-1)],dx:this.w[i].dx+(x*this.w[i].gapx),dy:this.w[i].dy+(x*this.w[i].gapy),fliph:this.w[i].fliph,flipv:this.w[i].flipv});
629
+ } else
630
+ if (this.w[i].emptytile!=null)
631
+ gbox.blitTile(gbox.getCanvasContext(this.surfaceid),{tileset:this.w[i].tileset,tile:this.w[i].emptytile,dx:this.w[i].dx+(x*this.w[i].gapx),dy:this.w[i].dy+(x*this.w[i].gapy),fliph:this.w[i].fliph,flipv:this.w[i].flipv});
632
+ cnt-=this.w[i].tiles.length;
633
+ }
634
+
635
+ }
636
+ if (this.w[i].widget=="stack") {
637
+ var ts=gbox.getTiles(this.w[i].tileset);
638
+ var bw=((this.w[i].maxshown-1)*this.w[i].gapx)+ts.tilew;
639
+ gbox.blitClear(gbox.getCanvasContext(this.surfaceid),{x:this.w[i].dx-(this.w[i].rightalign?bw:0),y:this.w[i].dy,w:bw,h:((this.w[i].maxshown-1)*this.w[i].gapy)+ts.tileh});
640
+ for (var x=0;x<this.w[i].maxshown;x++)
641
+ if (x<this.w[i].value.length)
642
+ gbox.blitTile(gbox.getCanvasContext(this.surfaceid),{tileset:this.w[i].tileset,tile:this.w[i].value[x],dx:(this.w[i].rightalign?this.w[i].dx-ts.tileh-(this.w[i].gapx*x):this.w[i].dx+(x*this.w[i].gapx)),dy:this.w[i].dy+(x*this.w[i].gapy),fliph:this.w[i].fliph,flipv:this.w[i].flipv});
643
+ }
644
+ if (this.w[i].widget=="radio") {
645
+ var ts=gbox.getTiles(this.w[i].tileset);
646
+ gbox.blitClear(gbox.getCanvasContext(this.surfaceid),{x:this.w[i].dx,y:this.w[i].dy,w:ts.tilew,h:ts.tileh});
647
+ gbox.blitTile(gbox.getCanvasContext(this.surfaceid),{tileset:this.w[i].tileset,tile:this.w[i].frames[this.w[i].value],dx:this.w[i].dx,dy:this.w[i].dy,fliph:this.w[i].fliph,flipv:this.w[i].flipv});
648
+
649
+ }
650
+ if (this.w[i].widget=="blit") {
651
+ var ts=gbox.getTiles(this.w[i].tileset);
652
+ gbox.blitClear(gbox.getCanvasContext(this.surfaceid),{x:this.w[i].dx,y:this.w[i].dy,w:ts.tilew,h:ts.tileh});
653
+ gbox.blitTile(gbox.getCanvasContext(this.surfaceid),{tileset:this.w[i].tileset,tile:this.w[i].value,dx:this.w[i].dx,dy:this.w[i].dy,fliph:this.w[i].fliph,flipv:this.w[i].flipv});
654
+
655
+ }
656
+ if (this.w[i].widget=="bool") {
657
+ var ts=gbox.getTiles(this.w[i].tileset);
658
+ gbox.blitClear(gbox.getCanvasContext(this.surfaceid),{x:this.w[i].dx,y:this.w[i].dy,w:ts.tilew,h:ts.tileh});
659
+ if (this.w[i].value)
660
+ gbox.blitTile(gbox.getCanvasContext(this.surfaceid),{tileset:this.w[i].tileset,tile:this.w[i].frame,dx:this.w[i].dx,dy:this.w[i].dy,fliph:this.w[i].fliph,flipv:this.w[i].flipv});
661
+ }
662
+ }
663
+ },
664
+
665
+ hideWidgets:function(l) {
666
+ for (var i=0;i<l.length;i++) this.w[l[i]].__hidden=true;
667
+ this.redraw();
668
+ },
669
+
670
+ showWidgets:function(l) {
671
+ for (var i=0;i<l.length;i++) this.w[l[i]].__hidden=false;
672
+ this.redraw();
673
+ },
674
+
675
+ getValue:function(w,k) {
676
+ return this.w[w][k];
677
+ },
678
+
679
+ setValue:function(w,k,v) {
680
+ if (this.w[w][k]!=v) {
681
+ if (k=="value") {
682
+ if ((this.w[w].maxvalue!=null)&&(v>this.w[w].maxvalue)) v=this.w[w].maxvalue;
683
+ if ((this.w[w].minvalue!=null)&&(v<this.w[w].minvalue)) v=this.w[w].minvalue;
684
+ if (this.w[w].widget=="radio") v=(v%this.w[w].frames.length);
685
+ }
686
+ this.w[w][k]=v;
687
+ this.updateWidget(w);
688
+ }
689
+ },
690
+
691
+ pushValue:function(w,k,v) {
692
+ this.w[w][k].push(v);
693
+ this.updateWidget(w);
694
+ },
695
+
696
+ addValue:function(w,k,v) {
697
+ if (v) this.setValue(w,k,this.w[w][k]+v);
698
+ },
699
+
700
+ setWidget:function(id,w) {
701
+ this.w[id]=w;
702
+ this.updateWidget(id);
703
+ },
704
+
705
+ redraw:function() {
706
+ gbox.blitClear(gbox.getCanvasContext(this.surfaceid));
707
+ for (var i in this.w) this.updateWidget(i);
708
+ },
709
+
710
+ blit:function() {
711
+ gbox.blitAll(gbox.getBufferContext(),gbox.getCanvas(this.surfaceid),{dx:0,dy:0});
712
+ }
713
+
714
+ }
715
+ }
716
+ },
717
+ fullscreen:{
718
+ fadeout:function(th,id,tox,data) {
719
+ if (toys._maketoy(th,id)||data.resetfade) th.toys[id].fade=0;
720
+ th.toys[id].fade+=data.fadespeed;
721
+ if (th.toys[id].fade>1) th.toys[id].fade=1;
722
+ data.alpha=th.toys[id].fade;
723
+ gbox.blitFade(tox,data);
724
+ return toys._toyfrombool(th,id,th.toys[id].fade==1)
725
+ },
726
+ fadein:function(th,id,tox,data) {
727
+ if (toys._maketoy(th,id)||data.resetfade) th.toys[id].fade=1;
728
+ th.toys[id].fade-=data.fadespeed;
729
+ if (th.toys[id].fade<0) th.toys[id].fade=0;
730
+ if (th.toys[id].fade) {
731
+ data.alpha=th.toys[id].fade;
732
+ gbox.blitFade(tox,data);
733
+ }
734
+ return toys._toyfrombool(th,id,th.toys[id].fade==0);
735
+ }
736
+ },
737
+ text:{
738
+ blink:function(th,id,tox,data) {
739
+ if (toys._maketoy(th,id)) {
740
+ th.toys[id].texttimer=0;
741
+ th.toys[id].visible=false;
742
+ th.toys[id].times=0;
743
+ }
744
+ if (th.toys[id].texttimer>=data.blinkspeed) {
745
+ th.toys[id].texttimer=0;
746
+ th.toys[id].visible=!th.toys[id].visible;
747
+ if (data.times) th.toys[id].times++;
748
+ } else th.toys[id].texttimer++;
749
+ if (th.toys[id].visible)
750
+ gbox.blitText(tox,data);
751
+ return toys._toyfrombool(th,id,(data.times?data.times<th.toys[id].times:false));
752
+ },
753
+ fixed:function(th,id,tox,data) {
754
+ if (toys._maketoy(th,id))
755
+ th.toys[id].texttimer=0;
756
+ else
757
+ th.toys[id].texttimer++;
758
+ gbox.blitText(tox,data);
759
+ return toys._toyfrombool(th,id,data.time<th.toys[id].texttimer);
760
+ }
761
+ },
762
+ logos:{
763
+ linear:function(th,id,data) {
764
+ if (toys._maketoy(th,id)) {
765
+ th.toys[id].x=data.sx;
766
+ th.toys[id].y=data.sy;
767
+ }
768
+ if ((data.x!=th.toys[id].x)||(data.y!=th.toys[id].y))
769
+ if ((Math.abs(data.x-th.toys[id].x)<=data.speed)&&(Math.abs(data.y-th.toys[id].y)<=data.speed)) {
770
+ th.toys[id].x=data.x;
771
+ th.toys[id].y=data.y;
772
+ } else
773
+ trigo.translate(th.toys[id],trigo.getAngle(th.toys[id],data),data.speed);
774
+ gbox.blitAll(gbox.getBufferContext(),gbox.getImage(data.image),{dx:th.toys[id].x,dy:th.toys[id].y});
775
+ return toys._toyfrombool(th,id,(data.x==th.toys[id].x)&&(data.y==th.toys[id].y));
776
+ },
777
+ crossed:function(th,id,data) {
778
+ if (toys._maketoy(th,id)) {
779
+ th.toys[id].gapx=data.gapx;
780
+ th.toys[id].lw=gbox.getImage(data.image).height;
781
+ th.toys[id].done=false;
782
+ }
783
+ if (th.toys[id].gapx) {
784
+ th.toys[id].gapx-=data.speed;
785
+ if (th.toys[id].gapx<0) th.toys[id].gapx=0;
786
+ gbox.blitAll(gbox.getBufferContext(),gbox.getImage(data.image),{dx:data.x-th.toys[id].gapx,dy:data.y,alpha:data.alpha});
787
+ gbox.blitAll(gbox.getBufferContext(),gbox.getImage(data.image),{dx:data.x+th.toys[id].gapx,dy:data.y,alpha:data.alpha});
788
+ return toys._toybusy(th,id);
789
+ } else {
790
+ gbox.blitAll(gbox.getBufferContext(),gbox.getImage(data.image),{dx:data.x,dy:data.y});
791
+ return toys._toydone(th,id);
792
+ }
793
+ },
794
+ zoomout:function(th,id,data) {
795
+ if (toys._maketoy(th,id)) {
796
+ th.toys[id].zoom=data.zoom;
797
+ th.toys[id].done=false;
798
+ th.toys[id].img=gbox.getImage(data.image);
799
+ }
800
+ if (th.toys[id].zoom!=1) {
801
+ th.toys[id].zoom-=data.speed;
802
+ if (th.toys[id].zoom<1) th.toys[id].zoom=1;
803
+ gbox.blit(gbox.getBufferContext(),gbox.getImage(data.image),{h:th.toys[id].img.height,w:th.toys[id].img.width,dx:data.x-Math.floor(th.toys[id].img.width*(th.toys[id].zoom-1)/2),dy:data.y-Math.floor(th.toys[id].img.height*(th.toys[id].zoom-1)/2),dh:Math.floor(th.toys[id].img.height*th.toys[id].zoom),dw:Math.floor(th.toys[id].img.width*th.toys[id].zoom),alpha:1/th.toys[id].zoom});
804
+ return toys._toybusy(th,id);
805
+ } else {
806
+ gbox.blitAll(gbox.getBufferContext(),gbox.getImage(data.image),{dx:data.x,dy:data.y});
807
+ return toys._toydone(th,id);
808
+ }
809
+ },
810
+ rising:function(th,id,data) {
811
+ if (toys._maketoy(th,id)) {
812
+ th.toys[id].cnt=0;
813
+ th.toys[id].lh=gbox.getImage(data.image).height;
814
+ th.toys[id].lw=gbox.getImage(data.image).width;
815
+ th.toys[id].done=false;
816
+ }
817
+ if (th.toys[id].cnt<th.toys[id].lh) {
818
+ th.toys[id].cnt+=data.speed;
819
+ if (th.toys[id].cnt>th.toys[id].lh) th.toys[id].gapx=th.toys[id].lh;
820
+ gbox.blit(gbox.getBufferContext(),gbox.getImage(data.image),{dh:th.toys[id].cnt,dw:th.toys[id].lw,dx:data.x,dy:data.y+th.toys[id].lh-th.toys[id].cnt,alpha:data.alpha});
821
+ if (data.reflex) gbox.blit(gbox.getBufferContext(),gbox.getImage(data.image),{dh:th.toys[id].cnt,dw:th.toys[id].lw,dx:data.x,dy:data.y+th.toys[id].lh,alpha:data.reflex,flipv:true});
822
+
823
+ return toys._toybusy(th,id);
824
+ } else {
825
+ gbox.blitAll(gbox.getBufferContext(),gbox.getImage(data.image),{dx:data.x,dy:data.y});
826
+ if (data.reflex) gbox.blitAll(gbox.getBufferContext(),gbox.getImage(data.image),{dx:data.x,dy:data.y+th.toys[id].lh,alpha:data.reflex,flipv:true});
827
+
828
+ return toys._toydone(th,id);
829
+ }
830
+ },
831
+ bounce:function(th,id,data) {
832
+ if (toys._maketoy(th,id)) {
833
+ th.toys[id].accy=data.accy;
834
+ th.toys[id].y=data.y;
835
+ th.toys[id].h=gbox.getImage(data.image).height;
836
+ th.toys[id].done=false;
837
+ }
838
+ if (!th.toys[id].done) {
839
+ if (th.toys[id].y+th.toys[id].h>=data.floory) {
840
+ th.toys[id].y=data.floory-th.toys[id].h;
841
+ th.toys[id].accy=-Math.ceil(th.toys[id].accy/(data.heavy?data.heavy:2));
842
+ th.toys[id].done=(th.toys[id].accy==0);
843
+ } else th.toys[id].accy--;
844
+ th.toys[id].y-=th.toys[id].accy;
845
+ }
846
+ gbox.blitAll(gbox.getBufferContext(),gbox.getImage(data.image),{dx:data.x,dy:th.toys[id].y});
847
+
848
+ return toys._toyfrombool(th,id,th.toys[id].done);
849
+ }
850
+ },
851
+ dialogue: {
852
+ render:function(th,id,data){
853
+ if (toys._maketoy(th,id)) {
854
+ th.toys[id].newscene=true;
855
+ th.toys[id].sceneid=-1;
856
+ th.toys[id].ended=false;
857
+ th.toys[id].timer=0;
858
+ th.toys[id].counter=0;
859
+ th.toys[id].anim=0;
860
+ gbox.createCanvas("dialogue-"+id);
861
+ }
862
+ if (!data.hideonend||(data.hideonend&&!th.toys[id].ended)) {
863
+ if (th.toys[id].newscene&&!th.toys[id].ended) {
864
+ th.toys[id].anim=0;
865
+ th.toys[id].timer=0;
866
+ th.toys[id].newscene=false;
867
+ th.toys[id].sceneid++;
868
+ th.toys[id].ended=(th.toys[id].sceneid==data.scenes.length);
869
+ if (!th.toys[id].ended) {
870
+ th.toys[id].letter=0;
871
+ th.toys[id].wait=false;
872
+ th.toys[id].scene=data.scenes[th.toys[id].sceneid];
873
+ th.toys[id].fd=gbox.getFont((th.toys[id].scene.font?th.toys[id].scene.font:data.font));
874
+ th.toys[id].sceneH=(th.toys[id].scene.dh?th.toys[id].scene.dh:gbox.getScreenH());
875
+ th.toys[id].sceneW=(th.toys[id].scene.dw?th.toys[id].scene.dw:gbox.getScreenW());
876
+ th.toys[id].sceneX=(th.toys[id].scene.dx?th.toys[id].scene.dx:0);
877
+ th.toys[id].sceneY=(th.toys[id].scene.dy?th.toys[id].scene.dy:0);
878
+ gbox.blitClear(gbox.getCanvasContext("dialogue-"+id));
879
+ if (th.toys[id].scene.slide) {
880
+ gbox.blitAll(gbox.getCanvasContext("dialogue-"+id),gbox.getImage(th.toys[id].scene.slide.image),{dx:th.toys[id].scene.slide.x,dy:th.toys[id].scene.slide.y});
881
+ }
882
+ if (th.toys[id].scene.scroller) {
883
+ gbox.createCanvas("scroller-"+id,{w:th.toys[id].sceneW,h:(th.toys[id].scene.scroller.length)*(th.toys[id].fd.tileh+th.toys[id].scene.spacing)});
884
+ for (var i=0;i<th.toys[id].scene.scroller.length;i++)
885
+ gbox.blitText(gbox.getCanvasContext("scroller-"+id),{
886
+ font:th.toys[id].fd.id,
887
+ dx:0,
888
+ dy:i*(th.toys[id].fd.tileh+th.toys[id].scene.spacing),
889
+ dw:th.toys[id].sceneW,
890
+ halign:gbox.ALIGN_CENTER,
891
+ text:th.toys[id].scene.scroller[i]
892
+ });
893
+ }
894
+ if (th.toys[id].scene.bonus) {
895
+ gbox.createCanvas("bonus-"+id,{w:th.toys[id].sceneW,h:(th.toys[id].scene.bonus.length)*(th.toys[id].fd.tileh+th.toys[id].scene.spacing)});
896
+ }
897
+ }
898
+ }
899
+ if (!th.toys[id].ended) {
900
+ if (th.toys[id].wait) {
901
+ if (gbox.keyIsHit(data.esckey)) th.toys[id].ended=true; else
902
+ if (gbox.keyIsHit(data.skipkey)) th.toys[id].newscene=true;
903
+ } else {
904
+
905
+ // SKIP KEYS
906
+
907
+ if (gbox.keyIsHit(data.esckey)) th.toys[id].ended=true; else
908
+ if (gbox.keyIsHold(data.skipkey)) th.toys[id].counter=th.toys[id].scene.speed;
909
+ else th.toys[id].counter++;
910
+
911
+ // MOVING
912
+
913
+ if (th.toys[id].scene.talk) { // DIALOGUES
914
+
915
+
916
+ if (th.toys[id].counter==th.toys[id].scene.speed) {
917
+ th.toys[id].letter++;
918
+ th.toys[id].counter=0;
919
+ var tmp=th.toys[id].letter;
920
+ var row=0;
921
+ while (tmp>th.toys[id].scene.talk[row].length) {
922
+ tmp-=th.toys[id].scene.talk[row].length;
923
+ row++;
924
+ if (row==th.toys[id].scene.talk.length) {
925
+ row=-1;
926
+ break;
927
+ }
928
+ }
929
+ if (row>=0) {
930
+ gbox.blitText(gbox.getCanvasContext("dialogue-"+id),{
931
+ font:data.font,
932
+ dx:data.who[th.toys[id].scene.who].x,
933
+ dy:(data.who[th.toys[id].scene.who].y)+(row*th.toys[id].fd.tileh),
934
+ text:th.toys[id].scene.talk[row].substr(0,tmp)
935
+ });
936
+ } else
937
+ th.toys[id].wait=true;
938
+ }
939
+
940
+ } else if (th.toys[id].scene.scroller) { // SCROLLER (i.e. credits)
941
+
942
+ if (th.toys[id].counter==th.toys[id].scene.speed) {
943
+ th.toys[id].letter++;
944
+ th.toys[id].counter=0;
945
+ if (th.toys[id].letter==(gbox.getCanvas("scroller-"+id).height+th.toys[id].scene.push))
946
+ th.toys[id].wait=true;
947
+ }
948
+
949
+ } else if (th.toys[id].scene.bonus) { // BONUS (classic bonus award screen)
950
+ for (var row=0;row<=th.toys[id].letter;row++) {
951
+ if (th.toys[id].scene.bonus[row].text)
952
+ gbox.blitText(gbox.getCanvasContext("bonus-"+id),{
953
+ font:data.font,
954
+ dx:0,
955
+ dy:(row*(th.toys[id].fd.tileh+th.toys[id].scene.spacing)),
956
+ text:th.toys[id].scene.bonus[row].text
957
+ });
958
+ else if (th.toys[id].scene.bonus[row].mul) {
959
+ // Mask is %VAL%e%MUL%=%TOT%
960
+ th.toys[id].scene.bonus[row].tmptext=th.toys[id].scene.bonus[row].mask.replace(/%VAL%/,th.toys[id].timer).replace(/%MUL%/,th.toys[id].scene.bonus[row].mul).replace(/%TOT%/,(th.toys[id].timer*th.toys[id].scene.bonus[row].mul));
961
+ gbox.blitText(gbox.getCanvasContext("bonus-"+id),{
962
+ clear:true,
963
+ font:data.font,
964
+ dx:0,
965
+ dy:(row*(th.toys[id].fd.tileh+th.toys[id].scene.spacing)),
966
+ text:th.toys[id].scene.bonus[row].tmptext
967
+ });
968
+ }
969
+ }
970
+
971
+ if (!th.toys[id].wait) {
972
+ var next=false;
973
+ if (th.toys[id].scene.bonus[th.toys[id].letter].mul&&!th.toys[id].scene.bonus[th.toys[id].letter].text) {
974
+ if (th.toys[id].counter>=th.toys[id].scene.bonus[th.toys[id].letter].speed) {
975
+ th.toys[id].counter=0;
976
+ th.toys[id].timer++;
977
+ if (th.toys[id].timer>th.toys[id].scene.bonus[th.toys[id].letter].mulvalue) {
978
+ th.toys[id].scene.bonus[th.toys[id].letter].text=th.toys[id].scene.bonus[th.toys[id].letter].tmptext;
979
+ next=true;
980
+ } else {
981
+ if (th.toys[id].scene.bonus[th.toys[id].letter].callback)
982
+ th.toys[id].scene.bonus[th.toys[id].letter].callback(th.toys[id].scene.bonus[th.toys[id].letter],th.toys[id].scene.bonus[th.toys[id].letter].arg);
983
+ }
984
+ }
985
+
986
+ } else if (th.toys[id].counter>=th.toys[id].scene.speed) next=true;
987
+ if (next) {
988
+ if (th.toys[id].letter==th.toys[id].scene.bonus.length-1)
989
+ th.toys[id].wait=true;
990
+ else {
991
+ th.toys[id].letter++;
992
+ if (th.toys[id].scene.bonus[th.toys[id].letter].mul) {
993
+ th.toys[id].scene.bonus[th.toys[id].letter].text=null;
994
+ th.toys[id].scene.bonus[th.toys[id].letter].tmptext=null;
995
+ th.toys[id].timer=0;
996
+ }
997
+ th.toys[id].counter=0;
998
+ }
999
+ }
1000
+ }
1001
+ }
1002
+
1003
+ }
1004
+
1005
+ }
1006
+
1007
+ // RENDERING
1008
+
1009
+
1010
+ if (th.toys[id].scene.talk) { // DIALOGUES
1011
+ if (data.who[th.toys[id].scene.who].box)
1012
+ gbox.blitRect(gbox.getBufferContext(),data.who[th.toys[id].scene.who].box);
1013
+ if (data.who[th.toys[id].scene.who].tileset) {
1014
+ th.toys[id].anim=(th.toys[id].anim+1)%20;
1015
+ gbox.blitTile(gbox.getBufferContext(),{tileset:data.who[th.toys[id].scene.who].tileset,tile:help.decideFrame(th.toys[id].anim,data.who[th.toys[id].scene.who].frames),dx:data.who[th.toys[id].scene.who].portraitx,dy:data.who[th.toys[id].scene.who].portraity,camera:false,fliph:data.who[th.toys[id].scene.who].fliph,flipv:data.who[th.toys[id].scene.who].flipv});
1016
+ }
1017
+ gbox.blitAll(gbox.getBufferContext(),gbox.getCanvas("dialogue-"+id),{dx:0,dy:0});
1018
+ } else if (th.toys[id].scene.scroller) // SCROLLER (i.e. credits)
1019
+ gbox.blit(gbox.getBufferContext(),gbox.getCanvas("scroller-"+id),{dx:th.toys[id].sceneX,dy:th.toys[id].sceneY+(th.toys[id].letter<th.toys[id].sceneH?th.toys[id].sceneH-th.toys[id].letter:0),dw:th.toys[id].sceneW,y:(th.toys[id].letter<th.toys[id].sceneH?0:th.toys[id].letter-th.toys[id].sceneH),dh:(th.toys[id].letter<th.toys[id].sceneH?th.toys[id].letter:th.toys[id].sceneH)});
1020
+ else if (th.toys[id].scene.bonus) // BONUS (i.e. credits)
1021
+ gbox.blitAll(gbox.getBufferContext(),gbox.getCanvas("bonus-"+id),{dx:th.toys[id].sceneX,dy:th.toys[id].sceneY});
1022
+ }
1023
+ return toys._toyfrombool(th,id,th.toys[id].ended);
1024
+ }
1025
+ },
1026
+
1027
+ // GENERATORS
1028
+
1029
+ generate: {
1030
+ sparks:{
1031
+ simple:function(th,group,id,data) {
1032
+ var ts=gbox.getTiles(data.tileset);
1033
+ if (data.frames==null) {
1034
+ data.frames={ speed:(data.animspeed==null?1:data.animspeed), frames:[]};
1035
+ for (var i=0;i<ts.tilerow;i++) data.frames.frames[i]=i;
1036
+ }
1037
+
1038
+ var obj=gbox.addObject(
1039
+ help.mergeWithModel(
1040
+ data,{
1041
+ id:id,
1042
+ group:group,
1043
+ x:th.x+th.hw-ts.tilehw+(data.gapx==null?0:data.gapx),
1044
+ y:(data.valign=="top"?th.y:th.y+th.hh-ts.tilehh+(data.gapy==null?0:data.gapy)),
1045
+ tileset:data.tileset,
1046
+ alpha:null,
1047
+ accx:0, accy:0,
1048
+ frame:0,
1049
+ timer:(data.delay?-data.delay:-1),
1050
+ frames:data.frames,
1051
+ toptimer:((data.frames.frames.length)*data.frames.speed)-1,
1052
+ camera:th.camera,
1053
+ gravity:false,
1054
+ trashoffscreen:true,
1055
+ fliph:(data.fliph==null?th.fliph:data.fliph), flipv:(data.flipv==null?th.flipv:data.flipv)
1056
+ }
1057
+ )
1058
+ );
1059
+
1060
+ obj[(data.logicon==null?"first":data.logicon)]=function() {
1061
+ this.timer++;
1062
+ if (this.timer>=0) {
1063
+ this.x+=this.accx;
1064
+ this.y+=this.accy;
1065
+ if (this.gravity) this.accy++;
1066
+ if ((this.timer==this.toptimer)||(this.trashoffscreen&&(!gbox.objectIsVisible(this)))) gbox.trashObject(this);
1067
+ }
1068
+ }
1069
+
1070
+ obj[(data.bliton==null?"blit":data.bliton)]=function() {
1071
+ if (this.timer>=0)
1072
+ gbox.blitTile(gbox.getBufferContext(),{tileset:this.tileset,tile:help.decideFrame(this.timer,this.frames),dx:this.x,dy:this.y,camera:this.camera,fliph:this.fliph,flipv:this.flipv,alpha:this.alpha});
1073
+ }
1074
+
1075
+ return obj;
1076
+ },
1077
+ popupText:function(th,group,id,data) {
1078
+ data.text+="";
1079
+ var fd=gbox.getFont(data.font);
1080
+
1081
+ var obj=gbox.addObject(
1082
+ help.mergeWithModel(
1083
+ data,{
1084
+ id:id,
1085
+ group:group,
1086
+ x:Math.floor(th.x+th.hw-(fd.tilehw*data.text.length)),
1087
+ y:th.y-fd.tilehh,
1088
+ vaccy:-data.jump,
1089
+ font:"small",
1090
+ keep:0,
1091
+ text:data.text,
1092
+ cnt:0,
1093
+ camera:th.camera
1094
+ }
1095
+ )
1096
+ );
1097
+
1098
+ obj[(data.logicon==null?"first":data.logicon)]=function() {
1099
+ if (gbox.objectIsVisible(this)) {
1100
+ if (this.vaccy)
1101
+ this.vaccy++;
1102
+ else
1103
+ this.cnt++;
1104
+ this.y+=this.vaccy;
1105
+ if (this.cnt>=this.keep) gbox.trashObject(this);
1106
+ } else gbox.trashObject(this);
1107
+ }
1108
+
1109
+ obj[(data.bliton==null?"blit":data.bliton)]=function() {
1110
+ gbox.blitText(gbox.getBufferContext(),{font:this.font,text:this.text,dx:this.x,dy:this.y,camera:this.camera});
1111
+ }
1112
+
1113
+ return obj;
1114
+ },
1115
+ bounceDie:function(th,group,id,data){
1116
+ var obj=gbox.addObject(
1117
+ help.mergeWithModel(
1118
+ data,{
1119
+ id:id,
1120
+ group:group,
1121
+ tileset:th.tileset,
1122
+ frame:th.frame,
1123
+ side:th.side,
1124
+ frames:th.frames.die,
1125
+ x:th.x,
1126
+ y:th.y,
1127
+ vaccy:-data.jump,
1128
+ flipv:data.flipv,
1129
+ cnt:0,
1130
+ camera:th.camera
1131
+ }
1132
+ )
1133
+ );
1134
+
1135
+ obj[(data.logicon==null?"first":data.logicon)]=function() {
1136
+ if (gbox.objectIsVisible(this)) {
1137
+ this.vaccy++;
1138
+ this.y+=this.vaccy;
1139
+ this.cnt=(this.cnt+1)%10;
1140
+ } else gbox.trashObject(this);
1141
+ }
1142
+
1143
+ obj[(data.bliton==null?"blit":data.bliton)]=function() {
1144
+ gbox.blitTile(gbox.getBufferContext(),{tileset:this.tileset,tile:help.decideFrame(this.cnt,this.frames),dx:this.x,dy:this.y,camera:this.camera,fliph:this.side,flipv:this.flipv});
1145
+ }
1146
+
1147
+ return obj;
1148
+ }
1149
+ }
1150
+ }
1151
+ }