"use strict";
var cr = {};
cr.plugins = {};
cr.behaviors = {};
(function(){
cr.RGB = function (red, green, blue)
{
return Math.max(Math.min(red, 255), 0)
| (Math.max(Math.min(green, 255), 0) << 8)
| (Math.max(Math.min(blue, 255), 0) << 16);
};
cr.vector2 = function (x, y)
{
this.x = x;
this.y = y;
};
var v2Proto = cr.vector2.prototype;
v2Proto.offset = function (p)
{
this.x += p.x;
this.y += p.y;
return this;
};
v2Proto.neg = function ()
{
return new cr.vector2(-this.x, -this.y);
};
cr.segments_intersect = function(a1, a2, b1, b2)
{
var dpx = b1.x - a1.x + b2.x - a2.x;
var dpy = b1.y - a1.y + b2.y - a2.y;
var qax = a2.x - a1.x;
var qay = a2.y - a1.y;
var qbx = b2.x - b1.x;
var qby = b2.y - b1.y;
var d = Math.abs(qay * qbx - qby * qax);
var la = qbx * dpy - qby * dpx;
var lb = qax * dpy - qay * dpx;
return Math.abs(la) < d && Math.abs(lb) < d;
};
cr.rect = function (left, top, right, bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
};
var rectProto = cr.rect.prototype;
rectProto.width = function ()
{
return this.right - this.left;
};
rectProto.height = function ()
{
return this.bottom - this.top;
};
rectProto.topleft = function ()
{
return new cr.vector2(this.left, this.top);
};
rectProto.topright = function ()
{
return new cr.vector2(this.right, this.top);
};
rectProto.bottomright = function ()
{
return new cr.vector2(this.right, this.bottom);
};
rectProto.bottomleft = function ()
{
return new cr.vector2(this.left, this.bottom);
};
rectProto.offset = function (p)
{
this.left += p.x;
this.top += p.y;
this.right += p.x;
this.bottom += p.y;
return this;
};
rectProto.intersects_rect = function (rc)
{
return !(rc.right < this.left || rc.bottom < this.top || rc.left > this.right || rc.top > this.bottom);
};
rectProto.to_quad = function ()
{
return new cr.quad(this.topleft(), this.topright(), this.bottomright(), this.bottomleft());
};
rectProto.rotate_to_quad = function (a)
{
if (a == 0)
{
return this.to_quad();
}
else
{
var sin_a = Math.sin(a);
var cos_a = Math.cos(a);
var left_sin_a = this.left * sin_a;
var top_sin_a = this.top * sin_a;
var right_sin_a = this.right * sin_a;
var bottom_sin_a = this.bottom * sin_a;
var left_cos_a = this.left * cos_a;
var top_cos_a = this.top * cos_a;
var right_cos_a = this.right * cos_a;
var bottom_cos_a = this.bottom * cos_a;
return new cr.quad(new cr.vector2(left_cos_a - top_sin_a, top_cos_a + left_sin_a),
new cr.vector2(right_cos_a - top_sin_a, top_cos_a + right_sin_a),
new cr.vector2(right_cos_a - bottom_sin_a, bottom_cos_a + right_sin_a),
new cr.vector2(left_cos_a - bottom_sin_a, bottom_cos_a + left_sin_a));
}
};
cr.quad = function (tl, tr, br, bl)
{
this.tl = tl;
this.tr = tr;
this.br = br;
this.bl = bl;
};
var quadProto = cr.quad.prototype;
quadProto.offset = function (p)
{
this.tl.offset(p);
this.tr.offset(p);
this.br.offset(p);
this.bl.offset(p);
return this;
};
quadProto.bounding_box = function ()
{
return new cr.rect(
Math.min(this.tl.x, this.tr.x, this.br.x, this.bl.x),
Math.min(this.tl.y, this.tr.y, this.br.y, this.bl.y),
Math.max(this.tl.x, this.tr.x, this.br.x, this.bl.x),
Math.max(this.tl.y, this.tr.y, this.br.y, this.bl.y));
};
quadProto.contains_pt = function (p)
{
var v0 = this.tl.neg().offset(this.tr);     // tr - tl
var v1 = this.tl.neg().offset(this.br);     // br - tl;
var v2 = this.tl.neg().offset(p);           // p - tl;
var dot00 = cr.dot2(v0, v0);
var dot01 = cr.dot2(v0, v1);
var dot02 = cr.dot2(v0, v2);
var dot11 = cr.dot2(v1, v1);
var dot12 = cr.dot2(v1, v2);
var invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
if ((u > 0.0) && (v > 0.0) && (u + v < 1))
return true;
v0 = this.tl.neg().offset(this.bl);     // bl - tl
dot00 = cr.dot2(v0, v0);
dot01 = cr.dot2(v0, v1);
dot02 = cr.dot2(v0, v2);
invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
u = (dot11 * dot02 - dot01 * dot12) * invDenom;
v = (dot00 * dot12 - dot01 * dot02) * invDenom;
return (u > 0.0) && (v > 0.0) && (u + v < 1);
};
quadProto.at = function (i)
{
i = i % 4;
if (i < 0)
i += 4;
switch (i)
{
case 0: return this.tl;
case 1: return this.tr;
case 2: return this.br;
case 3: return this.bl;
default: return this.tl;
}
};
quadProto.intersects_quad = function (rhs)
{
if (this.contains_pt(rhs.tl))
return true;
if (rhs.contains_pt(this.tl))
return true;
var i, j;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
if (cr.segments_intersect(this.at(i), this.at(i + 1), rhs.at(j), rhs.at(j + 1)))
return true;
}
}
return false;
};
cr.dot2 = function (a, b)
{
return (a.x * b.x) + (a.y * b.y);
};
cr.shallowCopy = function (a, b, allowOverwrite)
{
var attr;
for (attr in b)
{
if (b.hasOwnProperty(attr))
{
;
a[attr] = b[attr];
}
}
};
cr.arrayRemove = function (arr, index)
{
var sliced;
if (index < 1)
arr.shift();
else
{
sliced = arr.slice(index + 1);
arr.length = index;
arr.push.apply(arr, sliced);
}
};
cr.arrayFindRemove = function (arr, item)
{
var index = jQuery.inArray(item, arr);
;
cr.arrayRemove(arr, index);
};
cr.clamp = function(x, a, b)
{
if (x < a)
return a;
else if (x > b)
return b;
else
return x;
};
cr.to_radians = function(x)
{
return x / (180.0 / Math.PI);
};
cr.to_degrees = function(x)
{
return x * (180.0 / Math.PI);
};
cr.clamp_angle_degrees = function (a)
{
var angle = a;
angle %= 360;       // now in (-360, 360) range
if (angle < 0)
angle += 360;   // now in [0, 360) range
return angle;
};
cr.clamp_angle = function (a)
{
var angle = a;
angle %= 2 * Math.PI;       // now in (-2pi, 2pi) range
if (angle < 0)
angle += 2 * Math.PI;   // now in [0, 2pi) range
return angle;
};
cr.to_clamped_degrees = function (x)
{
return cr.clamp_angle_degrees(cr.to_degrees(x));
};
cr.to_clamped_radians = function (x)
{
return cr.clamp_angle(cr.to_radians(x));
};
cr.angleDiff = function (a1, a2)
{
if (a1 === a2)
return 0;
var s1 = Math.sin(a1);
var c1 = Math.cos(a1);
var s2 = Math.sin(a2);
var c2 = Math.cos(a2);
return Math.acos(s1 * s2 + c1 * c2);
};
cr.angleRotate = function (start, end, step)
{
var ss = Math.sin(start);
var cs = Math.cos(start);
var se = Math.sin(end);
var ce = Math.cos(end);
if (Math.acos(ss * se + cs * ce) > step)
{
if (cs * se - ss * ce > 0)
return cr.clamp_angle(start + step);
else
return cr.clamp_angle(start - step);
}
else
return cr.clamp_angle(end);
};
cr.angleClockwise = function (a1, a2)
{
var s1 = Math.sin(a1);
var c1 = Math.cos(a1);
var s2 = Math.sin(a2);
var c2 = Math.cos(a2);
return c1 * s2 - s1 * c2 < 0;
};
cr.xor = function (x, y)
{
return !x != !y;
};
cr.ObjectSet = function ()
{
this.items = {};
this.item_count = 0;
this.values_cache = [];
this.cache_valid = true;
};
var ObjectSetProto = cr.ObjectSet.prototype;
ObjectSetProto.contains = function (x)
{
return this.items.hasOwnProperty(x.toString());
};
ObjectSetProto.add = function (x)
{
if (!this.contains(x))
{
this.items[x.toString()] = x;
this.item_count++;
this.cache_valid = false;
}
return this;
};
ObjectSetProto.remove = function (x)
{
if (this.contains(x))
{
delete this.items[x.toString()];
this.item_count--;
this.cache_valid = false;
}
return this;
};
ObjectSetProto.clear = function ()
{
this.items = {};
this.item_count = 0;
this.values_cache = [];
this.cache_valid = true;
return this;
};
ObjectSetProto.isEmpty = function ()
{
return this.item_count === 0;
};
ObjectSetProto.count = function ()
{
return this.item_count;
};
ObjectSetProto.values = function ()
{
if (!this.cache_valid)
{
this.values_cache = [];
var i;
for (i in this.items)
{
if (this.items.hasOwnProperty(i))
this.values_cache.push(this.items[i]);
}
this.cache_valid = true;
}
return this.values_cache.slice(0);
};
}());
;
(function()
{
cr.runtime = function (canvas)
{
if (!canvas || !canvas.getContext)
return;
this.canvas = canvas; 				// store canvas
this.ctx = canvas.getContext("2d"); // get 2D canvas context
canvas.c2runtime = this;            // back pointer to runtime in canvas
this.width = canvas.width; 			// store canvas size
this.height = canvas.height;
this.redraw = true; 				// canvas needs drawing
this.deathRow = new cr.ObjectSet();
this.dt = 0;
this.last_tick_time = 0;
this.measuring_dt = true;
this.fps = 0;
this.tickcount = 0;
this.framecount = 0;        // for fps
this.objectcount = 0;
this.changelayout = null;   // go to layout sets this to switch layout
this.destroycallbacks = [];
this.event_stack = [];      // for nested loops/recursive calls
this.pushEventStack(null);  // have a default event stack entry for top level events
this.loop_stack = [];       // for nested loops; uses name/index pair
this.next_uid = 0;
this.activeGroups = {};     // group name is a property set to 'true' when active
};
var runtimeProto = cr.runtime.prototype;
runtimeProto.load = function ()
{
if (!this.ctx)
return;
;
cr.shallowCopy(this, cr.projectmodel);
var i, len, j, lenj, idstr;
this.system = new cr.system_object(this);
var plugins_obj = {};   // to replace 'plugins' data array with object
for (i = 0, len = this.plugins.length; i < len; i++)
{
idstr = this.plugins[i].idstr;
;
;
var plugin = new cr.plugins[idstr](this);
cr.shallowCopy(plugin, this.plugins[i]);
cr.add_common_aces(plugin);
if (plugin.onCreate)
plugin.onCreate();  // opportunity to override default ACEs
plugins_obj[idstr] = plugin;
}
this.plugins = plugins_obj;
this.wait_for_textures = [];        // for blocking until textures loaded
this.types_by_index = [];
var types_obj = {};     // to replace 'types' data array with object
this.behaviors = {};    // stores behavior-plugins
this.behaviors_by_index = [];
for (i = 0, len = this.types.length; i < len; i++)
{
;
var plugin_id = this.types[i].plugin_id;
;
var plugin = this.plugins[plugin_id];
;
var type_inst = new plugin.Type(plugin);
;
cr.shallowCopy(type_inst, this.types[i]);
type_inst.index = i;                                // save index in to types array in type
type_inst.instances = [];                           // all instances of this type
type_inst.solstack = [new cr.selection(type_inst)]; // initialise SOL stack with one empty SOL
type_inst.cur_sol = 0;
type_inst.getFirstPicked = cr.type_getFirstPicked;
type_inst.getCurrentSol = cr.type_getCurrentSol;
type_inst.pushCleanSol = cr.type_pushCleanSol;
type_inst.pushCopySol = cr.type_pushCopySol;
type_inst.popSol = cr.type_popSol;
type_inst.getBehaviorByName = cr.type_getBehaviorByName;
type_inst.getBehaviorIndexByName = cr.type_getBehaviorIndexByName;
var behaviors_arr = [];
for (j = 0, lenj = type_inst.behaviors.length; j < lenj; j++)
{
var beh = type_inst.behaviors[j];
idstr = beh.behavior_id;
var behavior_plugin;
if (!this.behaviors[idstr])
{
;
behavior_plugin = new cr.behaviors[idstr](this);
behavior_plugin.my_instances = new cr.ObjectSet(); 	// instances of this behavior
if (behavior_plugin.onCreate)
behavior_plugin.onCreate();
this.behaviors[idstr] = behavior_plugin;
this.behaviors_by_index.push(behavior_plugin);
}
behavior_plugin = this.behaviors[idstr];
var behavior_type = new this.behaviors[beh.behavior_id].Type(behavior_plugin, type_inst);
cr.shallowCopy(behavior_type, beh);
behavior_type.onCreate();
behaviors_arr.push(behavior_type);
}
type_inst.behaviors = behaviors_arr;    // swap model data for created types
type_inst.onCreate();
types_obj[type_inst.name] = type_inst;
this.types_by_index.push(type_inst);
if (plugin.singleglobal)
{
var instance = new plugin.Instance(type_inst);
instance.uid = this.next_uid;
this.next_uid++;
instance.toString = cr.inst_toString;
instance.onCreate();
type_inst.instances.push(instance);
}
}
this.types = types_obj;
var layouts_obj = {};
this.layouts_by_index = [];
for (i = 0, len = this.layouts.length; i < len; i++)
{
var layout = new cr.layout(this);
cr.shallowCopy(layout, this.layouts[i]);
layout.init();
layouts_obj[layout.name] = layout;
this.layouts_by_index.push(layout);
}
this.layouts = layouts_obj;
var eventsheets_obj = {};
this.eventsheets_by_index = [];
this.triggers_to_postinit = [];
for (i = 0, len = this.eventsheets.length; i < len; i++)
{
var sheet = new cr.eventsheet(this);
cr.shallowCopy(sheet, this.eventsheets[i]);
sheet.init();
eventsheets_obj[this.eventsheets[i].name] = sheet;
this.eventsheets_by_index.push(sheet);
}
this.eventsheets = eventsheets_obj;
for (i = 0, len = this.eventsheets_by_index.length; i < len; i++)
this.eventsheets_by_index[i].postInit();
for (i = 0, len = this.triggers_to_postinit.length; i < len; i++)
this.triggers_to_postinit[i].postInit();
delete this.triggers_to_postinit;
this.start_time = new Date().getTime();
};
runtimeProto.areAllTexturesLoaded = function ()
{
var totalsize = 0;
var completedsize = 0;
var ret = true;
var i, len;
for (i = 0, len = this.wait_for_textures.length; i < len; i++)
{
var filesize = this.wait_for_textures[i].cr_filesize;
if (!filesize || filesize <= 0)
filesize = 50000;
totalsize += filesize;
if (this.wait_for_textures[i].complete)
completedsize += filesize;
else
ret = false;    // not all textures loaded
}
if (totalsize == 0)
this.progress = 0;
else
this.progress = (completedsize / totalsize);
return ret;
};
runtimeProto.go = function ()
{
if (!this.ctx)
return;
this.progress = 0;
this.last_progress = -1;
if (this.areAllTexturesLoaded())
this.go_textures_done();
else
{
var ms_elapsed = new Date().getTime() - this.start_time;
if (ms_elapsed >= 500 && this.last_progress != this.progress)   // also don't redraw unless progress has changed
{
this.ctx.clearRect(0, 0, this.width, this.height);
this.ctx.font = "20pt Arial";
this.ctx.textBaseline = "top";
this.ctx.fillStyle = "rgb(0,0,0)";
this.ctx.fillText("Loading (" + Math.round(this.progress * 100) + "%)", 10, 10);
this.last_progress = this.progress;
}
setTimeout((function (self) { return function () { self.go(); }; })(this), 16);
}
};
runtimeProto.go_textures_done = function ()
{
if (this.first_layout)
this.layouts[this.first_layout].startRunning();
else
this.layouts_by_index[0].startRunning();
;
this.start_time = new Date().getTime();
this.last_fps_time = this.start_time;       // for counting framerate
this.tick();
setInterval((function (self) { return function () { self.tick(); }; })(this), 16);
};
runtimeProto.tick = function ()
{
;
this.logic();
if (this.redraw)
{
this.draw();
this.redraw = false;
}
this.tickcount++;
this.framecount++;
};
runtimeProto.logic = function ()
{
var i, leni, j, lenj, k, lenk;
var cur_time = new Date().getTime();
if (cur_time - this.last_fps_time >= 1000)  // every 1 second
{
this.last_fps_time += 1000;
this.fps = this.framecount;
this.framecount = 0;
}
if (this.measuring_dt)
{
if (this.last_tick_time != 0)
{
var ms_diff = cur_time - this.last_tick_time;
if (ms_diff == 0)
{
this.measuring_dt = false;
this.dt = 1.0 / 60.0;            // 60fps assumed (0.01666...)
;
}
else
{
this.dt = ms_diff / 1000.0; // dt measured in seconds
if (this.dt > 0.2)
this.dt = 0.2;
}
}
this.last_tick_time = cur_time;
}
this.ClearDeathRow();
if (this.changelayout)
{
this.running_layout.stopRunning();
this.changelayout.startRunning();
this.changelayout = null;
this.redraw = true;
}
for (i = 0, leni = this.types_by_index.length; i < leni; i++)
{
var type = this.types_by_index[i];
for (j = 0, lenj = type.instances.length; j < lenj; j++)
{
var inst = type.instances[j];
if (!inst.behavior_insts)
continue;
for (k = 0, lenk = inst.behavior_insts.length; k < lenk; k++)
{
inst.behavior_insts[k].tick();
}
}
}
if (this.running_layout.event_sheet)
this.running_layout.event_sheet.run();
};
runtimeProto.draw = function ()
{
this.running_layout.draw(this.ctx);
};
runtimeProto.addDestroyCallback = function (f)
{
if (f)
this.destroycallbacks.push(f);
};
runtimeProto.DestroyInstance = function (inst)
{
this.deathRow.add(inst);
};
runtimeProto.ClearDeathRow = function ()
{
var inst, index, instances;
var i, j, leni, lenj;
var arr = this.deathRow.values();	// get array of items from set
for (i = 0, leni = arr.length; i < leni; i++)
{
inst = arr[i];
instances = inst.type.instances;
for (j = 0, lenj = this.destroycallbacks.length; j < lenj; j++)
this.destroycallbacks[j](inst);
cr.arrayFindRemove(instances, inst);
if (inst.layer)
cr.arrayFindRemove(inst.layer.instances, inst);
if (inst.behavior_insts)
{
for (j = 0, lenj = inst.behavior_insts.length; j < lenj; j++)
{
inst.behavior_insts[j].behavior.my_instances.remove(inst);
}
}
this.objectcount--;
}
if (!this.deathRow.isEmpty())
this.redraw = true;
this.deathRow.clear();
};
runtimeProto.createInstance = function (type, layer)
{
return this.createInstanceFromInit(type.default_instance, layer, false);
};
runtimeProto.createInstanceFromInit = function (initial_inst, layer, is_startup_instance)
{
;
var type = initial_inst.type;
var is_world = initial_inst.type.plugin.is_world;
;
var inst = new type.plugin.Instance(type);
cr.shallowCopy(inst, initial_inst, true);
inst.uid = this.next_uid;
this.next_uid++;
if (initial_inst.instance_vars)
inst.instance_vars = initial_inst.instance_vars.slice(0);
if (is_world && !inst.hasOwnProperty("opacity"))
inst.opacity = 1.0;
this.objectcount++;
type.instances.push(inst);              // add to all instances
if (is_world)
{
inst.set_bbox_changed = cr.set_bbox_changed;
inst.bbox_changed = true;
inst.update_bbox = cr.update_bbox;
inst.visible = true;
inst.layer = layer;
}
inst.toString = cr.inst_toString;
inst.behavior_insts = [];
var i, len;
for (i = 0, len = type.behaviors.length; i < len; i++)
{
var btype = type.behaviors[i];
var binst = new btype.behavior.Instance(btype, inst);
binst.properties = {};
cr.shallowCopy(binst.properties, initial_inst.init_behaviors[i]);
binst.onCreate();
inst.behavior_insts.push(binst);
btype.behavior.my_instances.add(inst);
}
inst.onCreate();
if (layer)
layer.instances.push(inst);
if (is_world)
this.redraw = true;
return inst;
};
runtimeProto.getLayerByName = function (layer_name)
{
var i, len;
for (i = 0, len = this.running_layout.layers.length; i < len; i++)
{
var layer = this.running_layout.layers[i];
if (layer.name === layer_name)
return layer;
}
return null;
};
runtimeProto.getLayerByNumber = function (index)
{
if (index < 0)
index = 0;
if (index >= this.running_layout.layers.length)
index = this.running_layout.layers.length - 1;
return this.running_layout.layers[index];
};
cr.layout = function (runtime)
{
this.runtime = runtime;
};
var layoutProto = cr.layout.prototype;
layoutProto.init = function ()
{
var i, len;
for (i = 0, len = this.layers.length; i < len; i++)
{
var layer = new cr.layer(this);
cr.shallowCopy(layer, this.layers[i]);
layer.init();
this.layers[i] = layer;
}
for (i = 0, len = this.initial_nonworld.length; i < len; i++)
{
var inst = this.initial_nonworld[i];
inst.type = this.runtime.types[inst.type_name];
;
if (!inst.type.default_instance)
{
inst.type.default_instance = inst;
}
}
};
layoutProto.startRunning = function ()
{
if (this.sheetname)
{
this.event_sheet = this.runtime.eventsheets[this.sheetname];
;
}
this.runtime.running_layout = this;
this.scrollX = 0;
this.scrollY = 0;
var i, len;
for (i = 0, len = this.layers.length; i < len; i++)
{
this.layers[i].createInitialInstances();
}
for (i = 0, len = this.initial_nonworld.length; i < len; i++)
{
var type = this.initial_nonworld[i].type;
var plugin = type.plugin;
;
this.runtime.createInstanceFromInit(this.initial_nonworld[i], null, true);
}
this.runtime.trigger("OnLayoutStart", null);
};
layoutProto.stopRunning = function ()
{
;
this.runtime.trigger("OnLayoutEnd", null);
var i, leni, j, lenj, k, lenk;
for (i = 0, leni = this.layers.length; i < leni; i++)
{
this.layers[i].instances.length = 0;
}
var destroycallbacks = this.runtime.destroycallbacks;
for (i = 0, leni = this.runtime.types_by_index.length; i < leni; i++)
{
var type = this.runtime.types_by_index[i];
if (type.plugin.singleglobal)
continue;
this.runtime.objectcount -= type.instances.length;
for (j = 0, lenj = type.instances.length; j < lenj; j++)
{
for (k = 0, lenk = destroycallbacks.length; k < lenk; k++)
destroycallbacks[k](type.instances[j]);
delete type.instances[j];
}
type.instances.length = 0;
}
for (i = 0, leni = this.runtime.behaviors_by_index.length; i < leni; i++)
{
this.runtime.behaviors_by_index[i].my_instances.clear();
}
};
layoutProto.draw = function (ctx)
{
ctx.clearRect(0, 0, this.runtime.width, this.runtime.height);
this.windowRight = this.scrollX + this.runtime.width;
this.windowBottom = this.scrollY + this.runtime.height;
var i, len;
for (i = 0, len = this.layers.length; i < len; i++)
{
if (this.layers[i].visible)
this.layers[i].draw(ctx);
}
};
layoutProto.scrollToX = function (x)
{
var newscrollX = x - (this.runtime.width / 2);
if (newscrollX > this.width - this.runtime.width)
newscrollX = this.width - this.runtime.width;
if (newscrollX < 0)
newscrollX = 0;
if (this.scrollX !== newscrollX)
{
this.scrollX = newscrollX;
this.runtime.redraw = true;
}
};
layoutProto.scrollToY = function (y)
{
var newscrollY = y - (this.runtime.height / 2);
if (newscrollY > this.height - this.runtime.height)
newscrollY = this.height - this.runtime.height;
if (newscrollY < 0)
newscrollY = 0;
if (this.scrollY !== newscrollY)
{
this.scrollY = newscrollY;
this.runtime.redraw = true;
}
};
cr.layer = function (layout)
{
this.layout = layout;
this.runtime = layout.runtime;
this.instances = [];        // running instances
this.visible = true;
};
var layerProto = cr.layer.prototype;
layerProto.init = function ()
{
this.visible = this.initially_visible;
var i, len;
for (i = 0, len = this.initial_instances.length; i < len; i++)
{
var inst = this.initial_instances[i];
inst.type = this.runtime.types[inst.type_name];
;
if (!inst.type.default_instance)
{
inst.type.default_instance = inst;
}
}
};
layerProto.createInitialInstances = function ()
{
var i, len;
for (i = 0, len = this.initial_instances.length; i < len; i++)
{
var type = this.initial_instances[i].type;
var plugin = type.plugin;
;
this.runtime.createInstanceFromInit(this.initial_instances[i], this, true);
}
};
layerProto.draw = function (ctx)
{
var render_offscreen = (this.forceOwnTexture || this.opacity != 1.0);
var layer_canvas = this.runtime.canvas;
var layer_ctx = ctx;
if (render_offscreen)
{
if (!this.runtime.layer_canvas)
{
this.runtime.layer_canvas = document.createElement("canvas");
;
layer_canvas = this.runtime.layer_canvas;
layer_canvas.width = this.runtime.width;
layer_canvas.height = this.runtime.height;
this.runtime.layer_ctx = layer_canvas.getContext("2d");
;
}
layer_canvas = this.runtime.layer_canvas;
layer_ctx = this.runtime.layer_ctx;
if (layer_canvas.width != this.runtime.width)
layer_canvas.width = this.runtime.width;
if (layer_canvas.height != this.runtime.height)
layer_canvas.height = this.runtime.height;
if (this.transparent)
layer_ctx.clearRect(0, 0, this.runtime.width, this.runtime.height);
}
if (!this.transparent)
{
layer_ctx.fillStyle = this.background_color;
layer_ctx.fillRect(0, 0, this.runtime.width, this.runtime.height);
}
layer_ctx.save();
var px = this.layout.scrollX * this.parallaxX;
var py = this.layout.scrollY * this.parallaxY;
layer_ctx.translate(-px, -py);
var wndLeft = px;
var wndTop = py;
var wndRight = px + this.runtime.width;
var wndBottom = py + this.runtime.height;
var i, len;
for (i = 0, len = this.instances.length; i < len; i++)
{
var inst = this.instances[i];
if (!inst.visible)
continue;
inst.update_bbox();
if (inst.bbox.right < wndLeft || inst.bbox.bottom < wndTop || inst.bbox.left > wndRight || inst.bbox.top > wndBottom)
continue;
this.instances[i].draw(layer_ctx);
}
layer_ctx.restore();
if (render_offscreen)
{
ctx.globalAlpha = this.opacity;
ctx.drawImage(layer_canvas, 0, 0);
ctx.globalAlpha = 1.0;
}
};
}());
;
(function()
{
cr.eventsheet = function (runtime)
{
this.runtime = runtime;
this.triggers = {};
};
var eventSheetProto = cr.eventsheet.prototype;
eventSheetProto.init_event = function (evobj, parent, nontriggers)
{
if (evobj.type === "block")
{
var block = new cr.eventblock(this, parent);
cr.shallowCopy(block, evobj);
block.init();
if (block.is_trigger())
this.init_trigger(block);
else
nontriggers.push(block);
}
else if (evobj.type === "variable")
{
var v = new cr.eventvariable(this, parent);
cr.shallowCopy(v, evobj);
v.init();
nontriggers.push(v);
}
else
;
};
eventSheetProto.init = function ()
{
var nontriggers = [];       // triggers won't make it to this array
var i, len;
for (i = 0, len = this.events.length; i < len; i++)
{
this.init_event(this.events[i], null, nontriggers);
}
this.events = nontriggers;
};
eventSheetProto.postInit = function ()
{
var i, len;
for (i = 0, len = this.events.length; i < len; i++)
{
this.events[i].postInit();
}
};
eventSheetProto.run = function ()
{
var i, len;
for (i = 0, len = this.events.length; i < len; i++)
{
var ev = this.events[i];
ev.run();
this.runtime.clearSol(ev.solModifiers);
}
};
cr.selection = function (type)
{
this.type = type;
this.instances = [];        // subset of picked instances
this.select_all = true;
};
var solProto = cr.selection.prototype;
solProto.hasObjects = function ()
{
if (this.select_all)
return this.type.instances.length;
else
return this.instances.length;
};
solProto.getObjects = function ()
{
if (this.select_all)
return this.type.instances;
else
return this.instances;
};
solProto.pick = function (inst)
{
;
if (this.select_all)
{
this.select_all = false;
this.instances = [inst];
}
else
{
if (jQuery.inArray(inst, this.instances) === -1)
this.instances.push(inst);
}
};
var runtimeProto = cr.runtime.prototype;
runtimeProto.clearSol = function (solModifiers)
{
var i, len;
for (i = 0, len = solModifiers.length; i < len; i++)
{
solModifiers[i].getCurrentSol().select_all = true;
}
};
runtimeProto.pushCleanSol = function (solModifiers)
{
var i, len;
for (i = 0, len = solModifiers.length; i < len; i++)
{
solModifiers[i].pushCleanSol();
}
};
runtimeProto.pushCopySol = function (solModifiers)
{
var i, len;
for (i = 0, len = solModifiers.length; i < len; i++)
{
solModifiers[i].pushCopySol();
}
};
runtimeProto.popSol = function (solModifiers)
{
var i, len;
for (i = 0, len = solModifiers.length; i < len; i++)
{
solModifiers[i].popSol();
}
};
cr.eventblock = function (sheet, parent)
{
this.sheet = sheet;
this.parent = parent;
this.runtime = sheet.runtime;
this.solModifiers = [];
};
var eventblockProto = cr.eventblock.prototype;
eventblockProto.init = function ()
{
;
if (this.group)
{
if (this.active_on_start)
this.runtime.activeGroups[this.group_name] = true;
}
var i, len;
for (i = 0, len = this.conditions.length; i < len; i++)
{
var cnd = new cr.condition(this);
cr.shallowCopy(cnd, this.conditions[i]);
cnd.init();
this.conditions[i] = cnd;
this.addSolModifier(cnd.type);
}
for (i = 0, len = this.actions.length; i < len; i++)
{
var act = new cr.action(this);
cr.shallowCopy(act, this.actions[i]);
act.init();
this.actions[i] = act;
}
if (this.subevents)
{
var nontriggers = [];
for (i = 0, len = this.subevents.length; i < len; i++)
{
this.sheet.init_event(this.subevents[i], this, nontriggers);
}
this.subevents = nontriggers;
}
};
eventblockProto.postInit = function ()
{
var i, len;
for (i = 0, len = this.conditions.length; i < len; i++)
this.conditions[i].postInit();
for (i = 0, len = this.actions.length; i < len; i++)
this.actions[i].postInit();
if (this.subevents)
{
for (i = 0, len = this.subevents.length; i < len; i++)
this.subevents[i].postInit();
}
}
eventblockProto.addSolModifier = function (type)
{
if (!type)
return;
if (jQuery.inArray(type, this.solModifiers) === -1)
this.solModifiers.push(type);
};
eventblockProto.is_trigger = function ()
{
if (!this.conditions.length)    // no conditions
return false;
else
return this.conditions[0].trigger;
};
eventblockProto.run = function ()
{
var i, len;
var evinfo = this.runtime.getCurrentEventStack();
evinfo.current_event = this;
for (evinfo.cndindex = 0, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
{
if (!this.conditions[evinfo.cndindex].run())    // condition failed
return false;                               // bail out
}
this.run_actions_and_subevents();
};
eventblockProto.run_actions_and_subevents = function ()
{
var i, len, last, subev, pushpop;
for (i = 0, len = this.actions.length; i < len; i++)
this.actions[i].run();
if (this.subevents)
{
last = this.subevents.length - 1;
for (i = 0, len = this.subevents.length; i < len; i++)
{
subev = this.subevents[i];
pushpop = (!this.group && i < last);
if (pushpop)
this.runtime.pushCopySol(subev.solModifiers);
subev.run();
if (pushpop)
this.runtime.popSol(subev.solModifiers);
else
this.runtime.clearSol(subev.solModifiers);
}
}
};
eventblockProto.run_pretrigger = function ()
{
var i, len;
for (i = 0, len = this.conditions.length; i < len; i++)
{
;
if (!this.conditions[i].run())  // condition failed
return false;               // bail out
}
return true;
};
eventblockProto.retrigger = function ()
{
var prevcndindex = this.runtime.getCurrentEventStack().cndindex;
var len;
var evinfo = this.runtime.pushEventStack(this);
for (evinfo.cndindex = prevcndindex + 1, len = this.conditions.length; evinfo.cndindex < len; evinfo.cndindex++)
{
if (!this.conditions[evinfo.cndindex].run())    // condition failed
{
this.runtime.popEventStack();               // moving up level of recursion
return false;                               // bail out
}
}
this.run_actions_and_subevents();
this.runtime.popEventStack();
};
cr.condition = function (block)
{
this.block = block;
this.sheet = block.sheet;
this.runtime = block.runtime;
};
var conditionProto = cr.condition.prototype;
conditionProto.init = function ()
{
if (this.type == "system")
{
this.type = null;
this.func = this.runtime.system.cnds[this.method];
this.run = this.run_system;
}
else
{
this.type = this.runtime.types[this.type];  // swap type name for type object
if (this.isstatic)
this.run = this.run_static;
else
this.run = this.run_object;
if (this.behaviortype)
{
this.beh_index = this.type.getBehaviorIndexByName(this.behaviortype);
;
this.behaviortype = this.type.getBehaviorByName(this.behaviortype);
this.func = this.behaviortype.behavior.cnds[this.method];
}
else
{
this.func = this.type.plugin.cnds[this.method];
this.beh_index = -1;
}
}
;
if (this.parameters)
{
var i, len;
for (i = 0, len = this.parameters.length; i < len; i++)
{
var param = new cr.parameter(this);
cr.shallowCopy(param, this.parameters[i]);
param.init();
this.parameters[i] = param;
}
this.results = new Array(this.parameters.length);
}
else
this.results = [];
};
conditionProto.postInit = function ()
{
var i, len;
if (this.parameters)
{
for (i = 0, len = this.parameters.length; i < len; i++)
this.parameters[i].postInit();
}
};
conditionProto.run_system = function ()
{
var i, len;
if (this.parameters)
{
for (i = 0, len = this.parameters.length; i < len; i++)
this.results[i] = this.parameters[i].get();
}
return cr.xor(this.func.apply(this.runtime.system, this.results), this.inverted);
};
conditionProto.run_static = function ()
{
var i, len;
if (this.parameters)
{
for (i = 0, len = this.parameters.length; i < len; i++)
this.results[i] = this.parameters[i].get();
}
return this.func.apply(this.runtime, this.results);
};
conditionProto.run_object = function ()
{
var i, j, leni, lenj, ret, inst;
var sol = this.type.getCurrentSol();
if (sol.select_all) {
sol.instances.length = 0;       // clear contents
for (i = 0, leni = this.type.instances.length; i < leni; i++) {
inst = this.type.instances[i];
if (this.parameters) {
for (j = 0, lenj = this.parameters.length; j < lenj; j++)
this.results[j] = this.parameters[j].get(i);        // default SOL index is current object
}
if (this.beh_index > -1)
ret = this.func.apply(inst.behavior_insts[this.beh_index], this.results);
else
ret = this.func.apply(inst, this.results);
if (cr.xor(ret, this.inverted))
sol.instances.push(inst);
}
sol.select_all = false;
}
else {
var k = 0;
for (i = 0, leni = sol.instances.length; i < leni; i++) {
inst = sol.instances[i];
if (this.parameters) {
for (j = 0, lenj = this.parameters.length; j < lenj; j++)
this.results[j] = this.parameters[j].get(i);        // default SOL index is current object
}
if (this.beh_index > -1)
ret = this.func.apply(inst.behavior_insts[this.beh_index], this.results);
else
ret = this.func.apply(inst, this.results);
if (cr.xor(ret, this.inverted)) {
sol.instances[k] = inst;
k++;
}
}
sol.instances.length = k;
}
return sol.hasObjects();
};
cr.action = function (block)
{
this.block = block;
this.sheet = block.sheet;
this.runtime = block.runtime;
};
var actionProto = cr.action.prototype;
actionProto.init = function () {
if (this.type == "system") {
this.type = null;
this.func = this.runtime.system.acts[this.method];
this.run = this.run_system;
}
else {
this.type = this.runtime.types[this.type];
this.run = this.run_object;
if (this.behaviortype) {
this.beh_index = this.type.getBehaviorIndexByName(this.behaviortype);
;
this.behaviortype = this.type.getBehaviorByName(this.behaviortype);
this.func = this.behaviortype.behavior.acts[this.method];
}
else {
this.func = this.type.plugin.acts[this.method];
this.beh_index = -1;
}
}
;
if (this.parameters) {
var i, len;
for (i = 0, len = this.parameters.length; i < len; i++) {
var param = new cr.parameter(this);
cr.shallowCopy(param, this.parameters[i]);
param.init();
this.parameters[i] = param;
}
this.results = new Array(this.parameters.length);
}
else
this.results = [];
};
actionProto.postInit = function ()
{
var i, len;
if (this.parameters)
{
for (i = 0, len = this.parameters.length; i < len; i++)
this.parameters[i].postInit();
}
};
actionProto.run_system = function ()
{
var i, len;
if (this.parameters)
{
for (i = 0, len = this.parameters.length; i < len; i++)
this.results[i] = this.parameters[i].get();
}
this.func.apply(this.runtime.system, this.results);
};
actionProto.run_object = function ()
{
var instances = this.type.getCurrentSol().getObjects();
var i, j, leni, lenj;
for (i = 0, leni = instances.length; i < leni; i++)
{
if (this.parameters)
{
for (j = 0, lenj = this.parameters.length; j < lenj; j++)
this.results[j] = this.parameters[j].get(i);    // pass i to use as default SOL index
}
if (this.beh_index > -1)
this.func.apply(instances[i].behavior_insts[this.beh_index], this.results);
else
this.func.apply(instances[i], this.results);
}
};
cr.parameter = function (owner)
{
this.owner = owner;
this.block = owner.block;
this.sheet = owner.sheet;
this.runtime = owner.runtime;
};
var parameterProto = cr.parameter.prototype;
parameterProto.init = function ()
{
switch (this.type)
{
case "number":
case "string":
case "any":
this.make_exp_node(this.expression);
this.get = this.get_exp;
this.temp = new cr.expvalue();
break;
case "layer":
this.make_exp_node(this.expression);
this.get = this.get_layer;
this.temp = new cr.expvalue();
break;
case "combo":
case "cmp":
this.get = this.get_combosel;
break;
case "layout":
var layoutref = this.runtime.layouts[this.layout];
;
this.layout = layoutref;
this.get = this.get_layout;
break;
case "keyb":
this.get = this.get_key;
break;
case "object":
var object_type = this.runtime.types[this.object];
;
this.object = object_type;
this.get = this.get_object;
this.block.addSolModifier(object_type);
break;
case "instvar":
this.get = this.get_instvar;
break;
case "eventvar":
this.get = this.get_eventvar;
break;
default:
;
}
};
parameterProto.postInit = function ()
{
if (this.type === "eventvar")
{
this.eventvar = this.runtime.getEventVariableByName(this.varname, this.block.parent);
;
}
if (this.expression)
this.expression.postInit();
};
parameterProto.get_exp = function (solindex)
{
this.solindex = solindex || 0;   // default SOL index to use
this.expression.get(this.temp)
return this.temp.data;      // return actual JS value, not expvalue
};
parameterProto.get_object = function ()
{
return this.object;
};
parameterProto.get_combosel = function ()
{
return this.combosel;
};
parameterProto.get_layer = function (solindex)
{
this.solindex = solindex || 0;   // default SOL index to use
this.expression.get(this.temp)
if (this.temp.is_number())
return this.runtime.getLayerByNumber(this.temp.data);
else
return this.runtime.getLayerByName(this.temp.data);
}
parameterProto.get_layout = function ()
{
return this.layout;
};
parameterProto.get_key = function ()
{
return this.key;
};
parameterProto.get_instvar = function ()
{
return this.index;
};
parameterProto.get_eventvar = function ()
{
return this.eventvar;
};
cr.eventvariable = function (sheet, parent)
{
this.sheet = sheet;
this.parent = parent;
this.runtime = sheet.runtime;
this.solModifiers = [];
};
var eventvariableProto = cr.eventvariable.prototype;
eventvariableProto.init = function ()
{
this.data = this.initial;
};
eventvariableProto.postInit = function ()
{
};
eventvariableProto.run = function ()
{
if (this.parent)
this.data = this.initial;
};
runtimeProto.testAndSelectPointOverlap = function (type, pt)
{
var sol = type.getCurrentSol();
var i, j, inst, len;
if (sol.select_all)
{
sol.select_all = false;
sol.instances.length = 0;   // clear contents
for (i = 0, len = type.instances.length; i < len; i++)
{
inst = type.instances[i];
inst.update_bbox();
if (inst.bquad.contains_pt(pt))
sol.instances.push(inst);
}
}
else
{
j = 0;
for (i = 0, len = sol.instances.length; i < len; i++)
{
inst = sol.instances[i];
inst.update_bbox();
if (inst.bquad.contains_pt(pt))
{
sol.instances[j] = sol.instances[i];
j++;
}
}
sol.instances.length = j;
}
return sol.hasObjects();
};
runtimeProto.testOverlap = function (a, b)
{
if (a === b)
return false;
a.update_bbox();
b.update_bbox();
if (!a.bbox.intersects_rect(b.bbox))
return false;
return a.bquad.intersects_quad(b.bquad);
};
runtimeProto.testOverlapSolid = function (inst)
{
var solid = this.behaviors["solid"];
if (!solid)
return;
var i, len, solids = solid.my_instances.values();
for (i = 0, len = solids.length; i < len; ++i) {
if (this.testOverlap(inst, solids[i]))
return true;
}
return false;
};
runtimeProto.pushOutSolid = function (inst, xdir, ydir, dist)
{
var push_dist = dist || 50;
var oldx = inst.x
var oldy = inst.y;
var startx = inst.x;
var starty = inst.y;
if (xdir < 0)
startx = Math.floor(startx);
else if (xdir > 0)
startx = Math.ceil(startx);
if (ydir < 0)
starty = Math.floor(starty);
else if (ydir > 0)
starty = Math.ceil(starty);
var i;
for (i = 0; i < push_dist; i++)
{
inst.x = startx + (xdir * i);
inst.y = starty + (ydir * i);
inst.set_bbox_changed();
if (!this.testOverlapSolid(inst))
return true;
}
inst.x = oldx;
inst.y = oldy;
inst.set_bbox_changed();
return false;
};
eventSheetProto.init_trigger = function (trig)
{
;
this.runtime.triggers_to_postinit.push(trig);
var type_name;
if (trig.conditions[0].type)
type_name = trig.conditions[0].type.name;
else
type_name = "system";
if (!this.triggers[type_name])
this.triggers[type_name] = {};
var obj_entry = this.triggers[type_name];
var method = trig.conditions[0].method;
if (!obj_entry[method])
obj_entry[method] = [];
obj_entry[method].push(trig);
};
runtimeProto.trigger = function (method, inst)
{
var sheet = this.running_layout.event_sheet;
if (!sheet)
return false;     // no event sheet active; nothing to trigger
var type_name;
if (!inst)
type_name = "system";
else
type_name = inst.type.name;
if (!sheet.triggers[type_name])
return false;
var obj_entry = sheet.triggers[type_name];
if (!obj_entry[method])
return false;
var triggers_list = obj_entry[method];
var i, j, leni, lenj, ret = false;
for (i = 0, leni = triggers_list.length; i < leni; i++)
{
var trig = triggers_list[i];
this.pushCleanSol(trig.solModifiers);
if (inst)
{
var sol = inst.type.getCurrentSol();
sol.select_all = false;
sol.instances = [inst];
}
var ok_to_run = true;
if (trig.parent)
{
var parents = [];
var cur_parent = trig.parent;
while (cur_parent)
{
parents.push(cur_parent);
cur_parent = cur_parent.parent;
}
parents.reverse();
for (j = 0, lenj = parents.length; j < lenj; j++)
{
if (!parents[j].run_pretrigger())   // parent event failed
{
ok_to_run = false;
break;
}
}
}
if (ok_to_run)
{
trig.run();
ret = true;     // something got triggered
}
this.popSol(trig.solModifiers);
}
return ret;             // true if anything got triggered
};
runtimeProto.getCurrentCondition = function ()
{
var evinfo = this.getCurrentEventStack();
return evinfo.current_event.conditions[evinfo.cndindex];
};
runtimeProto.pushEventStack = function (cur_event)
{
this.event_stack.push({ current_event: cur_event, cndindex: 0 });
return this.getCurrentEventStack();
};
runtimeProto.popEventStack = function ()
{
;
this.event_stack.pop();
};
runtimeProto.getCurrentEventStack = function ()
{
return this.event_stack[this.event_stack.length - 1];
};
runtimeProto.pushLoopStack = function (name_)
{
this.loop_stack.push({ name: name_, index: 0 });
return this.getCurrentLoop();
};
runtimeProto.popLoopStack = function ()
{
;
this.loop_stack.pop();
};
runtimeProto.getCurrentLoop = function ()
{
;
return this.loop_stack[this.loop_stack.length - 1];
};
runtimeProto.getEventVariableByName = function (name, scope)
{
var i, leni, j, lenj, sheet, e;
while (scope)
{
for (i = 0, leni = scope.subevents.length; i < leni; i++)
{
e = scope.subevents[i];
if (e.type === "variable" && name.toLowerCase() === e.name.toLowerCase())
return e;
}
scope = scope.parent;
}
for (i = 0, leni = this.eventsheets_by_index.length; i < leni; i++)
{
sheet = this.eventsheets_by_index[i];
for (j = 0, lenj = sheet.events.length; j < lenj; j++)
{
e = sheet.events[j];
if (e.type === "variable" && name.toLowerCase() === e.name.toLowerCase())
return e;
}
}
return null;
};
}());
(function()
{
cr.parameter.prototype.make_exp_node = function (en)
{
en.owner = this;
en.postInit = cr.exp_node_postInit;
if (en.type === "system_exp")
{
en.func = this.runtime.system.exps[en.name];
;
if (en.parameters)
{
en.results = new Array(en.parameters.length + 1);
en.temp = new cr.expvalue();    // to recycle when evaluating parameters
}
else
en.results = new Array(1);      // to fit 'ret'
en.runtime = this.runtime;
en.get = cr.exp_eval_system_exp;
}
else if (en.type === "object_exp" || en.type === "behavior_exp")
{
var node_type = en.type;
en.type = this.runtime.types[en.object];
;
if (en.parameters)
en.results = new Array(en.parameters.length + 1);
else
en.results = new Array(1);      // to fit 'ret'
if (en.parameters || en.instance_expr)
en.temp = new cr.expvalue();
en.get = cr.exp_eval_object_behavior_exp;
en.runtime = this.runtime;
if (node_type === "object_exp")
{
en.beh_index = -1;
en.func = en.type.plugin.exps[en.expname]
;
}
else
{
en.beh_index = en.type.getBehaviorIndexByName(en.behavior_type);
;
en.func = en.type.getBehaviorByName(en.behavior_type).behavior.exps[en.expname]
;
}
}
else if (en.type === "instvar_exp")
{
en.type = this.runtime.types[en.object];
;
if (en.instance_expr)
en.temp = new cr.expvalue();
en.runtime = this.runtime;
en.get = cr.exp_eval_instvar_exp;
}
else
{
en.get = cr["exp_eval_" + en.type];
;
}
if (en.first)
this.make_exp_node(en.first);
if (en.second)
this.make_exp_node(en.second);
if (en.third)
this.make_exp_node(en.third);
if (en.instance_expr)
this.make_exp_node(en.instance_expr);
if (en.parameters)
{
var i, len;
for (i = 0, len = en.parameters.length; i < len; i++)
{
this.make_exp_node(en.parameters[i]);
}
}
};
cr.exp_node_postInit = function ()
{
if (this.type === "eventvar_exp")
{
this.eventvar = this.owner.runtime.getEventVariableByName(this.varname, this.owner.block.parent);
;
}
if (this.first)
this.first.postInit();
if (this.second)
this.second.postInit();
if (this.third)
this.third.postInit();
if (this.instance_expr)
this.instance_expr.postInit();
if (this.parameters)
{
var i, len;
for (i = 0, len = this.parameters.length; i < len; i++)
this.parameters[i].postInit();
}
};
cr.exp_eval_system_exp = function (ret)
{
this.results[0] = ret;
if (this.parameters)
{
var i, len;
for (i = 0, len = this.parameters.length; i < len; i++)
{
this.parameters[i].get(this.temp);
this.results[i + 1] = this.temp.data;   // passing actual javascript value as argument instead of expvalue
}
}
this.func.apply(this.runtime.system, this.results);
};
cr.exp_eval_object_behavior_exp = function (ret)
{
var sol = this.type.getCurrentSol();
var instances = sol.getObjects();
if (!instances.length) {
ret.set_int(0);
return;
}
this.results[0] = ret;
if (this.parameters) {
var i, len;
for (i = 0, len = this.parameters.length; i < len; i++) {
this.parameters[i].get(this.temp);
this.results[i + 1] = this.temp.data;   // passing actual javascript value as argument instead of expvalue
}
}
var index = this.owner.solindex;
if (this.instance_expr) {
this.instance_expr.get(this.temp);
if (this.temp.is_number()) {
index = this.temp.data;
instances = this.type.instances;    // pick from all instances, not SOL
}
}
index %= instances.length;      // wraparound
if (index < 0)
index += instances.length;
var returned_val;
if (this.beh_index > -1)
returned_val = this.func.apply(instances[index].behavior_insts[this.beh_index], this.results);
else
returned_val = this.func.apply(instances[index], this.results);
;
};
cr.exp_eval_instvar_exp = function (ret)
{
var sol = this.type.getCurrentSol();
var instances = sol.getObjects();
if (!instances.length)
{
ret.set_int(0);
return;
}
var index = this.owner.solindex;
if (this.instance_expr)
{
this.instance_expr.get(this.temp);
if (this.temp.is_number())
{
index = this.temp.data;
var type_instances = this.type.instances;
index %= type_instances.length;     // wraparound
if (index < 0)                      // offset
index += type_instances.length;
var to_ret = type_instances[index].instance_vars[this.varindex];
if (typeof to_ret === "string")
ret.set_string(to_ret);
else
ret.set_float(to_ret);
return;         // done
}
}
index %= instances.length;      // wraparound
if (index < 0)
index += instances.length;
var to_ret = instances[index].instance_vars[this.varindex];
if (typeof to_ret === "string")
ret.set_string(to_ret);
else
ret.set_float(to_ret);
};
cr.exp_eval_int = function (ret)
{
ret.type = cr.exptype.Integer;
ret.data = this.value;
};
cr.exp_eval_float = function (ret)
{
ret.type = cr.exptype.Float;
ret.data = this.value;
};
cr.exp_eval_string = function (ret)
{
ret.type = cr.exptype.String;
ret.data = this.value;
};
cr.exp_eval_unaryminus = function (ret)
{
this.first.get(ret);                // retrieve operand
if (ret.is_number())
ret.data = -ret.data;
};
cr.exp_eval_add = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
if (ret.is_number() && temp.is_number())
{
ret.data += temp.data;          // both operands numbers: add
if (temp.is_float())
ret.make_float();
}
};
cr.exp_eval_subtract = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
if (ret.is_number() && temp.is_number())
{
ret.data -= temp.data;          // both operands numbers: subtract
if (temp.is_float())
ret.make_float();
}
};
cr.exp_eval_multiply = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
if (ret.is_number() && temp.is_number())
{
ret.data *= temp.data;          // both operands numbers: multiply
if (temp.is_float())
ret.make_float();
}
};
cr.exp_eval_divide = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
if (ret.is_number() && temp.is_number())
{
ret.data /= temp.data;          // both operands numbers: divide
ret.make_float();
}
};
cr.exp_eval_mod = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
if (ret.is_number() && temp.is_number())
{
ret.data %= temp.data;          // both operands numbers: modulo
if (temp.is_float())
ret.make_float();
}
};
cr.exp_eval_power = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
if (ret.is_number() && temp.is_number())
{
ret.data = Math.pow(ret.data, temp.data);   // both operands numbers: raise to power
if (temp.is_float())
ret.make_float();
}
};
cr.exp_eval_and = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
if (ret.is_number())
{
if (temp.is_string())
{
ret.set_string(ret.data.toString() + temp.data);
}
else
{
if (ret.data && temp.data)
ret.set_int(1);
else
ret.set_int(0);
}
}
else if (ret.is_string())
{
ret.data += temp.data.toString();
}
};
cr.exp_eval_or = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
if (ret.is_number() && temp.is_number())
{
if (ret.data || temp.data)
ret.set_int(1);
else
ret.set_int(0);
}
};
cr.exp_eval_conditional = function (ret)
{
this.first.get(ret);                // condition operand
if (ret.data)                       // is true
this.second.get(ret);           // evaluate second operand to ret
else
this.third.get(ret);            // evaluate third operand to ret
};
cr.exp_eval_equal = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
ret.set_int(ret.data === temp.data ? 1 : 0);
};
cr.exp_eval_notequal = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
ret.set_int(ret.data !== temp.data ? 1 : 0);
};
cr.exp_eval_less = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
ret.set_int(ret.data < temp.data ? 1 : 0);
};
cr.exp_eval_lessequal = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
ret.set_int(ret.data <= temp.data ? 1 : 0);
};
cr.exp_eval_greater = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
ret.set_int(ret.data > temp.data ? 1 : 0);
};
cr.exp_eval_greaterequal = function (ret)
{
this.first.get(ret);                // left operand
var temp = new cr.expvalue();       // right operand
this.second.get(temp);
ret.set_int(ret.data >= temp.data ? 1 : 0);
};
cr.exp_eval_eventvar_exp = function (ret)
{
if (typeof this.eventvar.data === "number")
ret.set_float(this.eventvar.data);
else
ret.set_string(this.eventvar.data);
};
cr.expvalue = function (type, data)
{
this.type = type || cr.exptype.Integer;
this.data = data || 0;
;
;
;
if (this.type == cr.exptype.Integer)
this.data = Math.floor(this.data);
};
var expvalueProto = cr.expvalue.prototype;
expvalueProto.is_int = function ()
{
return this.type === cr.exptype.Integer;
};
expvalueProto.is_float = function ()
{
return this.type === cr.exptype.Float;
};
expvalueProto.is_number = function ()
{
return this.type === cr.exptype.Integer || this.type === cr.exptype.Float;
};
expvalueProto.is_string = function ()
{
return this.type === cr.exptype.String;
};
expvalueProto.make_int = function ()
{
if (!this.is_int())
{
if (this.is_float())
this.data = Math.floor(this.data);      // truncate float
else if (this.is_string())
this.data = parseInt(this.data, 10);
this.type = cr.exptype.Integer;
}
};
expvalueProto.make_float = function ()
{
if (!this.is_float())
{
if (this.is_string())
this.data = parseFloat(this.data);
this.type = cr.exptype.Float;
}
};
expvalueProto.make_string = function ()
{
if (!this.is_string())
{
this.data = this.data.toString();
this.type = cr.exptype.String;
}
};
expvalueProto.set_int = function (val)
{
;
this.type = cr.exptype.Integer;
this.data = Math.floor(val);
};
expvalueProto.set_float = function (val)
{
;
this.type = cr.exptype.Float;
this.data = val;
};
expvalueProto.set_string = function (val)
{
;
this.type = cr.exptype.String;
this.data = val;
};
cr.exptype = {
Integer: 0,     // emulated; no native integer support in javascript
Float: 1,
String: 2
};
}());
;
cr.system_object = function (runtime)
{
this.runtime = runtime;
};
cr.system_object.prototype.cnds = {};
cr.system_object.prototype.acts = {};
cr.system_object.prototype.exps = {};
(function ()
{
var syscnds = cr.system_object.prototype.cnds;
syscnds["EveryTick"] = function()
{
return true;
};
syscnds["OnLayoutStart"] = function()
{
return true;
};
syscnds["OnLayoutEnd"] = function()
{
return true;
};
syscnds["Compare"] = function(x, cmp, y)
{
return cr.do_cmp(x, cmp, y);
};
syscnds["CompareTime"] = function (cmp, t)
{
var elapsed = new Date().getTime() - this.runtime.start_time;
if (cmp === 0)
{
var cnd = this.runtime.getCurrentCondition();
if (!cnd.CompareTime_executed)
{
if (elapsed >= t * 1000.0)
{
cnd.CompareTime_executed = true;
return true;
}
}
return false;
}
return cr.do_cmp(elapsed, cmp, t * 1000.0);
};
syscnds["LayerVisible"] = function (layer)
{
if (!layer)
return false;
else
return layer.visible;
};
syscnds["Repeat"] = function (count)
{
var current_event = this.runtime.getCurrentEventStack().current_event;
var current_loop = this.runtime.pushLoopStack();
var i;
for (i = 0; i < count; i++)
{
this.runtime.pushCopySol(current_event.solModifiers);
current_loop.index = i;
current_event.retrigger();
this.runtime.popSol(current_event.solModifiers);
}
this.runtime.popLoopStack();
return false;
};
syscnds["For"] = function (name, start, end)
{
var current_event = this.runtime.getCurrentEventStack().current_event;
var current_loop = this.runtime.pushLoopStack(name);
var i;
for (i = start; i <= end; i++)  // inclusive to end
{
this.runtime.pushCopySol(current_event.solModifiers);
current_loop.index = i;
current_event.retrigger();
this.runtime.popSol(current_event.solModifiers);
}
this.runtime.popLoopStack();
return false;
};
syscnds["ForEach"] = function (obj)
{
var sol = obj.getCurrentSol();
var instances = sol.getObjects().slice(0);
var current_event = this.runtime.getCurrentEventStack().current_event;
var current_loop = this.runtime.pushLoopStack();
var i, len;
for (i = 0, len = instances.length; i < len; i++)
{
this.runtime.pushCopySol(current_event.solModifiers);
sol = obj.getCurrentSol();
sol.select_all = false;
sol.instances = [instances[i]]; // array of current instance
current_loop.index = i;
current_event.retrigger();
this.runtime.popSol(current_event.solModifiers);
}
this.runtime.popLoopStack();
return false;
};
syscnds["TriggerOnce"] = function ()
{
var cnd = this.runtime.getCurrentCondition();
var last_tick = cnd.TriggerOnce_lastTick || 0;
var cur_tick = this.runtime.tickcount;
cnd.TriggerOnce_lastTick = cur_tick;
return !(last_tick === cur_tick - 1);
};
syscnds["Every"] = function (seconds)
{
var cnd = this.runtime.getCurrentCondition();
var last_time = cnd.Every_lastTime || 0;
var cur_time = new Date().getTime();
if (cur_time >= last_time + (seconds * 1000.0))
{
cnd.Every_lastTime = cur_time;
return true;
}
else
return false;
};
syscnds["PickNth"] = function (obj, index)
{
if (!obj)
return false;
var sol = obj.getCurrentSol();
var instances = sol.getObjects();
if (index < 0 || index >= instances.length)
return false;
var inst = instances[index];
sol.select_all = false;
sol.instances = [inst];
return true;
};
syscnds["CompareVar"] = function (v, cmp, val)
{
return cr.do_cmp(v.data, cmp, val);
};
syscnds["IsGroupActive"] = function (group)
{
return this.runtime.activeGroups.hasOwnProperty(group);
};
var sysacts = cr.system_object.prototype.acts;
sysacts["GoToLayout"] = function(to)
{
this.runtime.changelayout = to;
};
sysacts["CreateObject"] = function (obj, layer, x, y)
{
if (!layer || !obj)
return;
var inst = this.runtime.createInstance(obj, layer);
inst.x = x;
inst.y = y;
var sol = inst.type.getCurrentSol();
sol.select_all = false;
sol.instances = [ inst ];
};
sysacts["SetLayerVisible"] = function (layer, visible)
{
if (!layer)
return;
layer.visible = visible;
this.runtime.redraw = true;
};
sysacts["ScrollX"] = function(x)
{
this.runtime.running_layout.scrollToX(x);
};
sysacts["ScrollY"] = function(y)
{
this.runtime.running_layout.scrollToY(y);
};
sysacts["Scroll"] = function(x, y)
{
this.runtime.running_layout.scrollToX(x);
this.runtime.running_layout.scrollToY(y);
};
sysacts["ScrollToObject"] = function(obj)
{
var inst = obj.getFirstPicked();
if (inst)
{
this.runtime.running_layout.scrollToX(inst.x);
this.runtime.running_layout.scrollToY(inst.y);
}
};
sysacts["SetVar"] = function(v, x)
{
if (v.vartype === 0)
{
if (typeof x === "number")
v.data = x;
else
v.data = parseFloat(x);
}
else if (v.vartype === 1)
v.data = x.toString();
};
sysacts["AddVar"] = function(v, x)
{
if (v.vartype === 0)
{
if (typeof x === "number")
v.data += x;
else
v.data += parseFloat(x);
}
else if (v.vartype === 1)
v.data += x.toString();
};
sysacts["SubVar"] = function(v, x)
{
if (v.vartype === 0)
{
if (typeof x === "number")
v.data -= x;
else
v.data -= parseFloat(x);
}
};
sysacts["SetGroupActive"] = function (group, active)
{
if (active)
this.runtime.activeGroups[group] = true;
else if (this.runtime.activeGroups.hasOwnProperty(group))
delete this.runtime.activeGroups[group];
};
var sysexps = cr.system_object.prototype.exps;
sysexps["int"] = function(ret, x)
{
if (typeof x === "string")
{
ret.set_int(parseInt(x, 10));
if (isNaN(ret.data))
ret.data = 0;
}
else
ret.set_int(x);
};
sysexps["float"] = function(ret, x)
{
if (typeof x === "string")
{
ret.set_float(parseFloat(x));
if (isNaN(ret.data))
ret.data = 0;
}
else
ret.set_float(x);
};
sysexps["str"] = function(ret, x)
{
if (typeof x === "string")
ret.set_string(x);
else
ret.set_string(x.toString());
};
sysexps["len"] = function(ret, x)
{
ret.set_int(x.length);
};
sysexps["random"] = function (ret, a, b)
{
if (b === undefined)
{
ret.set_float(Math.random() * a);
}
else
{
ret.set_float(Math.random() * (b - a) + a);
}
};
sysexps["sqrt"] = function(ret, x)
{
ret.set_float(Math.sqrt(x));
};
sysexps["abs"] = function(ret, x)
{
ret.set_float(Math.abs(x));
};
sysexps["round"] = function(ret, x)
{
ret.set_int(Math.round(x));
};
sysexps["floor"] = function(ret, x)
{
ret.set_int(Math.floor(x));
};
sysexps["ceil"] = function(ret, x)
{
ret.set_int(Math.ceil(x));
};
sysexps["sin"] = function(ret, x)
{
ret.set_float(Math.sin(cr.to_radians(x)));
};
sysexps["cos"] = function(ret, x)
{
ret.set_float(Math.cos(cr.to_radians(x)));
};
sysexps["tan"] = function(ret, x)
{
ret.set_float(Math.tan(cr.to_radians(x)));
};
sysexps["asin"] = function(ret, x)
{
ret.set_float(cr.to_degrees(Math.asin(x)));
};
sysexps["acos"] = function(ret, x)
{
ret.set_float(cr.to_degrees(Math.acos(x)));
};
sysexps["atan"] = function(ret, x)
{
ret.set_float(cr.to_degrees(Math.atan(x)));
};
sysexps["exp"] = function(ret, x)
{
ret.set_float(Math.exp(x));
};
sysexps["ln"] = function(ret, x)
{
ret.set_float(Math.log(x));
};
sysexps["log10"] = function(ret, x)
{
ret.set_float(Math.log(x) / Math.LN10);
};
sysexps["max"] = function(ret)
{
var arr = new Array(arguments.length - 1);
var i, len;
for (i = 0, len = arguments.length - 1; i < len; i++)
arr[i] = arguments[i + 1];
ret.set_float(Math.max.apply(null, arr));
};
sysexps["min"] = function(ret)
{
var arr = new Array(arguments.length - 1);
var i, len;
for (i = 0, len = arguments.length - 1; i < len; i++)
arr[i] = arguments[i + 1];
ret.set_float(Math.min.apply(null, arr));
};
sysexps["dt"] = function(ret)
{
ret.set_float(this.runtime.dt);
};
sysexps["timescale"] = function(ret)
{
ret.set_float(1.0);
};
sysexps["time"] = function(ret)
{
ret.set_float((new Date().getTime() - this.runtime.start_time) / 1000.0);
};
sysexps["tickcount"] = function(ret)
{
ret.set_int(this.runtime.tickcount);
};
sysexps["objectcount"] = function(ret)
{
ret.set_int(this.runtime.objectcount);
};
sysexps["fps"] = function(ret)
{
ret.set_int(this.runtime.fps);
};
sysexps["loopindex"] = function(ret, name_)
{
if (!this.runtime.loop_stack.length)
{
ret.set_int(0);
return;
}
if (name_)
{
var i, len;
for (i = 0, len = this.runtime.loop_stack.length; i < len; i++)
{
var loop = this.runtime.loop_stack[i];
if (loop.name === name_)
{
ret.set_int(loop.index);
return;
}
}
ret.set_int(0);
}
else
{
ret.set_int(this.runtime.getCurrentLoop().index);
}
};
sysexps["distance"] = function(ret, x1, y1, x2, y2)
{
var dx = x2 - x1;
var dy = y2 - y1;
ret.set_float(Math.sqrt((dx * dx) + (dy * dy)));
};
sysexps["angle"] = function(ret, x1, y1, x2, y2)
{
var dx = x2 - x1;
var dy = y2 - y1;
ret.set_float(cr.to_degrees(Math.atan2(dy, dx)));
};
sysexps["scrollx"] = function(ret)
{
ret.set_float(this.runtime.running_layout.scrollX + this.runtime.width / 2);
};
sysexps["scrolly"] = function(ret)
{
ret.set_float(this.runtime.running_layout.scrollY + this.runtime.height / 2);
};
sysexps["newline"] = function(ret)
{
ret.set_string("\n");
};
sysexps["lerp"] = function(ret, a, b, x)
{
ret.set_float(a + (b - a) * x);
};
sysexps["windowwidth"] = function(ret)
{
ret.set_int(this.runtime.width);
};
sysexps["windowheight"] = function(ret)
{
ret.set_int(this.runtime.height);
};
}());
;
cr.add_common_aces = function (plugin)
{
if (!plugin.cnds)
plugin.cnds = {};
if (!plugin.acts)
plugin.acts = {};
if (!plugin.exps)
plugin.exps = {};
var cnds = plugin.cnds;
var acts = plugin.acts;
var exps = plugin.exps;
if (plugin.position_aces)
{
cnds["CompareX"] = function (cmp, x)
{
return cr.do_cmp(this.x, cmp, x);
};
cnds["CompareY"] = function (cmp, y)
{
return cr.do_cmp(this.y, cmp, y);
};
cnds["IsOnScreen"] = function ()
{
this.update_bbox();
var bbox = this.bbox;
var layout = this.runtime.running_layout;
return !(bbox.right < layout.scrollX || bbox.bottom < layout.scrollY || bbox.left > layout.windowRight || bbox.top > layout.windowBottom);
};
cnds["IsOutsideLayout"] = function ()
{
this.update_bbox();
var bbox = this.bbox;
var layout = this.runtime.running_layout;
return (bbox.right < 0 || bbox.bottom < 0 || bbox.left > layout.width || bbox.top > layout.height);
};
acts["SetX"] = function (x)
{
if (this.x !== x)
{
this.x = x;
this.set_bbox_changed();
}
};
acts["SetY"] = function (y)
{
if (this.y !== y)
{
this.y = y;
this.set_bbox_changed();
}
};
acts["SetPos"] = function (x, y)
{
if (this.x !== x || this.y !== y)
{
this.x = x;
this.y = y;
this.set_bbox_changed();
}
};
acts["SetPosToObject"] = function (obj, imgpt)
{
var inst = obj.getFirstPicked();
if (inst && (this.x !== inst.x || this.y !== inst.y))
{
this.x = inst.x;
this.y = inst.y;
this.set_bbox_changed();
}
};
acts["MoveForward"] = function (dist)
{
if (dist !== 0)
{
this.x += Math.cos(this.angle) * dist;
this.y += Math.sin(this.angle) * dist;
this.set_bbox_changed();
}
};
exps["X"] = function (ret)
{
ret.set_float(this.x);
};
exps["Y"] = function (ret)
{
ret.set_float(this.y);
};
}
if (plugin.size_aces)
{
cnds["CompareWidth"] = function (cmp, w)
{
return cr.do_cmp(this.width, cmp, w);
};
cnds["CompareHeight"] = function (cmp, h)
{
return cr.do_cmp(this.height, cmp, h);
};
acts["SetWidth"] = function (w)
{
var newwidth = w;
if (newwidth < 0)
newwidth = -newwidth;
if (this.width !== newwidth)
{
this.width = newwidth;
this.set_bbox_changed();
}
};
acts["SetHeight"] = function (h)
{
var newheight = h;
if (newheight < 0)
newheight = -newheight;
if (this.height !== newheight)
{
this.height = newheight;
this.set_bbox_changed();
}
};
acts["SetSize"] = function (w, h)
{
var newwidth = w;
var newheight = h;
if (newwidth < 0)
newwidth = -newwidth;
if (newheight < 0)
newheight = -newheight;
if (this.width !== newwidth || this.height !== newheight)
{
this.width = newwidth;
this.height = newheight;
this.set_bbox_changed();
}
};
exps["Width"] = function (ret)
{
ret.set_float(this.width);
};
exps["Height"] = function (ret)
{
ret.set_float(this.height);
};
}
if (plugin.angle_aces)
{
cnds["AngleWithin"] = function (within, a)
{
return cr.angleDiff(this.angle, cr.to_radians(a)) <= cr.to_radians(within);
};
cnds["IsClockwiseFrom"] = function (a)
{
return cr.angleClockwise(this.angle, cr.to_radians(a));
};
acts["SetAngle"] = function (a)
{
var newangle = cr.to_radians(cr.clamp_angle_degrees(a));
if (isNaN(newangle))
return;
if (this.angle !== newangle)
{
this.angle = newangle;
this.set_bbox_changed();
}
};
acts["RotateClockwise"] = function (a)
{
if (a !== 0 && !isNaN(a))
{
this.angle += cr.to_radians(a);
this.angle = cr.clamp_angle(this.angle);
this.set_bbox_changed();
}
};
acts["RotateCounterclockwise"] = function (a)
{
if (a !== 0 && !isNaN(a))
{
this.angle -= cr.to_radians(a);
this.angle = cr.clamp_angle(this.angle);
this.set_bbox_changed();
}
};
acts["RotateTowardAngle"] = function (amt, target)
{
var newangle = cr.angleRotate(this.angle, cr.to_radians(target), cr.to_radians(amt));
if (isNaN(newangle))
return;
if (this.angle !== newangle)
{
this.angle = newangle;
this.set_bbox_changed();
}
};
acts["RotateTowardPosition"] = function (amt, x, y)
{
var dx = x - this.x;
var dy = y - this.y;
var target = Math.atan2(dy, dx);
var newangle = cr.angleRotate(this.angle, target, cr.to_radians(amt));
if (isNaN(newangle))
return;
if (this.angle !== newangle)
{
this.angle = newangle;
this.set_bbox_changed();
}
};
acts["SetTowardPosition"] = function (x, y)
{
var dx = x - this.x;
var dy = y - this.y;
var newangle = Math.atan2(dy, dx);
if (isNaN(newangle))
return;
if (this.angle !== newangle)
{
this.angle = newangle;
this.set_bbox_changed();
}
};
exps["Angle"] = function (ret)
{
ret.set_float(cr.to_clamped_degrees(this.angle));
};
}
if (!plugin.singleglobal)
{
cnds["CompareInstanceVar"] = function (iv, cmp, val)
{
return cr.do_cmp(this.instance_vars[iv], cmp, val);
};
cnds["IsBoolInstanceVarSet"] = function (iv)
{
return this.instance_vars[iv];
};
acts["SetInstanceVar"] = function (iv, val)
{
if (typeof this.instance_vars[iv] === "number")
{
if (typeof val === "number")
this.instance_vars[iv] = val;
else
this.instance_vars[iv] = parseFloat(val);
}
else if (typeof this.instance_vars[iv] === "string")
{
if (typeof val === "string")
this.instance_vars[iv] = val;
else
this.instance_vars[iv] = val.toString();
}
else
;
};
acts["AddInstanceVar"] = function (iv, val)
{
if (typeof this.instance_vars[iv] === "number")
{
if (typeof val === "number")
this.instance_vars[iv] += val;
else
this.instance_vars[iv] += parseFloat(val);
}
else if (typeof this.instance_vars[iv] === "string")
{
if (typeof val === "string")
this.instance_vars[iv] += val;
else
this.instance_vars[iv] += val.toString();
}
else
;
};
acts["SubInstanceVar"] = function (iv, val)
{
if (typeof this.instance_vars[iv] === "number")
{
if (typeof val === "number")
this.instance_vars[iv] -= val;
else
this.instance_vars[iv] -= parseFloat(val);
}
else
;
};
acts["SetBoolInstanceVar"] = function (iv, val)
{
this.instance_vars[iv] = val;
};
acts["ToggleBoolInstanceVar"] = function (iv)
{
this.instance_vars[iv] = !this.instance_vars[iv];
};
acts["Destroy"] = function ()
{
this.runtime.DestroyInstance(this);
};
exps["Count"] = function (ret)
{
ret.set_int(this.type.instances.length);
};
}
if (plugin.appearance_aces)
{
cnds["IsVisible"] = function ()
{
return this.visible;
};
acts["SetVisible"] = function (v)
{
this.visible = v;
};
cnds["CompareOpacity"] = function (cmp, x)
{
return cr.do_cmp(this.opacity, cmp, x);
};
acts["SetOpacity"] = function (x)
{
var new_opacity = x / 100.0;
if (new_opacity < 0)
new_opacity = 0;
else if (new_opacity > 1)
new_opacity = 1;
if (new_opacity !== this.opacity)
{
this.opacity = new_opacity;
this.runtime.redraw = true;
}
};
exps["Opacity"] = function (ret)
{
ret.set_float(this.opacity * 100.0);
};
}
};
cr.set_bbox_changed = function ()
{
this.bbox_changed = true;       // will recreate next time box requested
this.runtime.redraw = true;     // assume runtime needs to redraw
};
cr.update_bbox = function ()
{
if (!this.bbox_changed)
return;                 // bounding box not changed
var ubox = new cr.rect(this.x, this.y, this.x + this.width, this.y + this.height);
ubox.offset(new cr.vector2(-this.hotspotX * this.width, -this.hotspotY * this.height));
if (!this.angle || this.angle == 0)
{
this.bbox = ubox;                       // bounding box is unrotated
this.bquad = ubox.to_quad();            // make bounding quad from box
}
else
{
ubox.offset(new cr.vector2(-this.x, -this.y));          // translate to origin
this.bquad = ubox.rotate_to_quad(this.angle);           // rotate around origin
this.bquad.offset(new cr.vector2(this.x, this.y));      // translate back to original position
this.bbox = this.bquad.bounding_box();
}
this.bbox_changed = false;  // bounding box up to date
};
cr.inst_toString = function ()
{
return "inst:" + this.type.name + "#" + this.uid;
};
cr.type_getFirstPicked = function ()
{
var instances = this.getCurrentSol().getObjects();
if (instances.length)
return instances[0];
else
return null;
};
cr.type_getCurrentSol = function ()
{
return this.solstack[this.cur_sol];
};
cr.type_pushCleanSol = function ()
{
this.cur_sol++;
if (this.cur_sol === this.solstack.length)
this.solstack.push(new cr.selection(this));
else
this.solstack[this.cur_sol].select_all = true;  // else clear next SOL
};
cr.type_pushCopySol = function ()
{
this.cur_sol++;
if (this.cur_sol === this.solstack.length)
this.solstack.push(new cr.selection(this));
var clonesol = this.solstack[this.cur_sol];
var prevsol = this.solstack[this.cur_sol - 1];
if (prevsol.select_all)
clonesol.select_all = true;
else
{
clonesol.select_all = false;
clonesol.instances = prevsol.instances.slice(0);    // copy elements
}
};
cr.type_popSol = function ()
{
;
this.cur_sol--;
};
cr.type_getBehaviorByName = function (behname) {
var i, len;
for (i = 0, len = this.behaviors.length; i < len; i++) {
if (behname === this.behaviors[i].name)
return this.behaviors[i];
}
};
cr.type_getBehaviorIndexByName = function (behname) {
var i, len;
for (i = 0, len = this.behaviors.length; i < len; i++) {
if (behname === this.behaviors[i].name)
return i;
}
return -1;
};
cr.do_cmp = function (x, cmp, y)
{
switch (cmp)
{
case 0:     // equal
return x === y;
case 1:     // not equal
return x !== y;
case 2:     // less
return x < y;
case 3:     // less/equal
return x <= y;
case 4:     // greater
return x > y;
case 5:     // greater/equal
return x >= y;
default:
;
return false;
}
};
cr.projectmodel = {
"name": "JJH3Game",
"plugins": [
{
"idstr": "Mouse",
"singleglobal": true,
"is_world": false,
"position_aces": false,
"size_aces": false,
"angle_aces": false,
"appearance_aces": false
}
,	{
"idstr": "Sprite",
"singleglobal": false,
"is_world": true,
"position_aces": true,
"size_aces": true,
"angle_aces": true,
"appearance_aces": true
}
,	{
"idstr": "TiledBg",
"singleglobal": false,
"is_world": true,
"position_aces": true,
"size_aces": true,
"angle_aces": true,
"appearance_aces": true
}
],
"types": [
{
"name": "Block",
"plugin_id": "Sprite",
"behaviors": [
{
"name": "Solid",
"behavior_id": "solid"
}
]
,
"texture_file": "block.png",
"texture_filesize": 476
}
,	{
"name": "TiledBackground",
"plugin_id": "TiledBg",
"behaviors": [
]
,
"texture_file": "tiledbackground.png",
"texture_filesize": 1453
}
,	{
"name": "Dude",
"plugin_id": "Sprite",
"behaviors": [
{
"name": "Platform",
"behavior_id": "Platform"
}
]
,
"texture_file": "dude.png",
"texture_filesize": 1010
}
,	{
"name": "JJH3Logo",
"plugin_id": "Sprite",
"behaviors": [
]
,
"texture_file": "jjh3logo.png",
"texture_filesize": 8402
}
,	{
"name": "InstructionImage",
"plugin_id": "Sprite",
"behaviors": [
{
"name": "Fade",
"behavior_id": "Fade"
}
]
,
"texture_file": "instructionimage.png",
"texture_filesize": 1856
}
,	{
"name": "BluePortal",
"plugin_id": "Sprite",
"behaviors": [
{
"name": "Fade",
"behavior_id": "Fade"
}
]
,
"texture_file": "blueportal.png",
"texture_filesize": 1915
}
,	{
"name": "RedPortal",
"plugin_id": "Sprite",
"behaviors": [
{
"name": "Fade",
"behavior_id": "Fade"
}
]
,
"texture_file": "redportal.png",
"texture_filesize": 1961
}
,	{
"name": "Mouse",
"plugin_id": "Mouse",
"behaviors": [
]
}
,	{
"name": "BigBlock",
"plugin_id": "Sprite",
"behaviors": [
{
"name": "Solid",
"behavior_id": "solid"
}
]
,
"texture_file": "bigblock.png",
"texture_filesize": 1233
}
,	{
"name": "DudeShadow",
"plugin_id": "Sprite",
"behaviors": [
{
"name": "Fade",
"behavior_id": "Fade"
}
]
,
"texture_file": "dudeshadow.png",
"texture_filesize": 971
}
],
"layouts": [
{
"name": "Layout 1",
"width": 800,
"height": 600,
"sheetname": "Event sheet 1",
"layers": [
{
"name": "Layer 0",
"index": 0,
"initially_visible": true,
"background_color": "rgb(255, 255, 255)",
"transparent": false,
"parallaxX": 1,
"parallaxY": 1,
"opacity": 1,
"forceOwnTexture": false,
"initial_instances": [
{
"type_name": "TiledBackground",
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 400,
"y": 300,
"z": 0,
"width": 800,
"height": 600,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "DudeShadow",
"init_behaviors": [
{
"Fade in time": 0,
"Wait time": 0,
"Fade out time": 0.5,
"Destroy": "After fade out"
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 55,
"y": 663,
"z": 0,
"width": 20,
"height": 40,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "BluePortal",
"init_behaviors": [
{
"Fade in time": 0.5,
"Wait time": 9999999999999998,
"Fade out time": 1,
"Destroy": "After fade out"
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 359,
"y": 470,
"z": 0,
"width": 20,
"height": 40,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "RedPortal",
"init_behaviors": [
{
"Fade in time": 0.5,
"Wait time": 1000000000000000000,
"Fade out time": 1,
"Destroy": "After fade out"
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 116,
"y": 241,
"z": 0,
"width": 20,
"height": 40,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 10,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 30,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 50,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 70,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 90,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 110,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 130,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 150,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 170,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 190,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 210,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 230,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 250,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 270,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 290,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 310,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 330,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 350,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 370,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 390,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 410,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 430,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 450,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 470,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 490,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 510,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 530,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 550,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 570,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 590,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 610,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 630,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 650,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 670,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 690,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 710,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 730,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 750,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 770,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 790,
"y": 590,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "JJH3Logo",
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 400,
"y": 75,
"z": 0,
"width": 280,
"height": 89,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "InstructionImage",
"init_behaviors": [
{
"Fade in time": 5,
"Wait time": 5,
"Fade out time": 5,
"Destroy": "After fade out"
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 400,
"y": 172,
"z": 0,
"width": 280,
"height": 32,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 58,
"y": 320,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 78,
"y": 320,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 98,
"y": 320,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 118,
"y": 320,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "BigBlock",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 317,
"y": 560,
"z": 0,
"width": 41,
"height": 41,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 138,
"y": 320,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 158,
"y": 320,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 178,
"y": 320,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "BigBlock",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 137,
"y": 290,
"z": 0,
"width": 41,
"height": 41,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "BigBlock",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 358,
"y": 560,
"z": 0,
"width": 41,
"height": 41,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "BigBlock",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 399,
"y": 560,
"z": 0,
"width": 41,
"height": 41,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "BigBlock",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 440,
"y": 560,
"z": 0,
"width": 41,
"height": 41,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "BigBlock",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 379,
"y": 519,
"z": 0,
"width": 41,
"height": 41,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "BigBlock",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 338,
"y": 519,
"z": 0,
"width": 41,
"height": 41,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "BigBlock",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 97,
"y": 290,
"z": 0,
"width": 41,
"height": 41,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "BigBlock",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 614,
"y": 340,
"z": 0,
"width": 41,
"height": 41,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "BigBlock",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 714,
"y": 340,
"z": 0,
"width": 41,
"height": 41,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 644,
"y": 329,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 664,
"y": 329,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
,			{
"type_name": "Block",
"init_behaviors": [
{
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 684,
"y": 329,
"z": 0,
"width": 20,
"height": 20,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
]
}
,		{
"name": "Layer 1",
"index": 1,
"initially_visible": true,
"background_color": "rgb(255, 255, 255)",
"transparent": true,
"parallaxX": 1,
"parallaxY": 1,
"opacity": 1,
"forceOwnTexture": false,
"initial_instances": [
{
"type_name": "Dude",
"init_behaviors": [
{
"Max speed": 200,
"Acceleration": 99999999,
"Deceleration": 1500,
"Jump strength": 500,
"Gravity": 1500,
"Max fall speed": 1000
}
],
"properties": {
"Initial visibility": "Visible",
"Effect": "(none)"
}
,"x": 61,
"y": 542,
"z": 0,
"width": 20,
"height": 40,
"depth": 0,
"angle": 0,
"opacity": 1,
"hotspotX": 0.5,
"hotspotY": 0.5
}
]
}
],
"initial_nonworld": [
]
}
],
"eventsheets": [
{
"name": "Event sheet 1",
"events": [
{
"type": "block",
"conditions": [
{
"type": "Dude",
"method": "IsOutsideLayout",
"trigger": false,
"looping": false,
"inverted": false,
"isstatic": false
}
],
"actions": [
{
"type": "Dude",
"method": "SetPosToObject"
,				"parameters": [
{
"type": "object",
"object": "RedPortal"
}
,				{
"type": "any",
"expression": {
"type": "int",
"value": 0
}
}
]
}
]
}
,		{
"type": "block",
"group": true,
"active_on_start": true,
"group_name": "Portals",
"conditions": [
{
"type": "system",
"method": "IsGroupActive",
"trigger": false,
"looping": false,
"inverted": false,
"isstatic": false
,				"parameters": [
{
"type": "string",
"expression": {
"type": "string",
"value": "Portals"
}
}
]
}
],
"actions": [
]
}
,		{
"type": "block",
"conditions": [
{
"type": "Mouse",
"method": "OnClick",
"trigger": true,
"looping": false,
"inverted": false,
"isstatic": false
,				"parameters": [
{
"type": "combo",
"combosel": 0
}
,				{
"type": "combo",
"combosel": 0
}
]
}
],
"actions": [
{
"type": "BluePortal",
"method": "Destroy"
}
,			{
"type": "system",
"method": "CreateObject"
,				"parameters": [
{
"type": "object",
"object": "BluePortal"
}
,				{
"type": "layer",
"expression": {
"type": "int",
"value": 1
}
}
,				{
"type": "number",
"expression": {
"type": "object_exp",
"object": "Mouse",
"expname": "AbsoluteX"
}
}
,				{
"type": "number",
"expression": {
"type": "object_exp",
"object": "Mouse",
"expname": "AbsoluteY"
}
}
]
}
]
}
,		{
"type": "block",
"conditions": [
{
"type": "Mouse",
"method": "OnClick",
"trigger": true,
"looping": false,
"inverted": false,
"isstatic": false
,				"parameters": [
{
"type": "combo",
"combosel": 2
}
,				{
"type": "combo",
"combosel": 0
}
]
}
],
"actions": [
{
"type": "RedPortal",
"method": "Destroy"
}
,			{
"type": "system",
"method": "CreateObject"
,				"parameters": [
{
"type": "object",
"object": "RedPortal"
}
,				{
"type": "layer",
"expression": {
"type": "int",
"value": 1
}
}
,				{
"type": "number",
"expression": {
"type": "object_exp",
"object": "Mouse",
"expname": "AbsoluteX"
}
}
,				{
"type": "number",
"expression": {
"type": "object_exp",
"object": "Mouse",
"expname": "AbsoluteY"
}
}
]
}
]
}
,		{
"type": "block",
"conditions": [
{
"type": "Dude",
"method": "OnCollision",
"trigger": false,
"looping": false,
"inverted": false,
"isstatic": true
,				"parameters": [
{
"type": "object",
"object": "BluePortal"
}
]
}
],
"actions": [
{
"type": "Dude",
"method": "SetPosToObject"
,				"parameters": [
{
"type": "object",
"object": "RedPortal"
}
,				{
"type": "any",
"expression": {
"type": "int",
"value": 0
}
}
]
}
]
}
,		{
"type": "block",
"conditions": [
{
"type": "Dude",
"method": "OnCollision",
"trigger": false,
"looping": false,
"inverted": false,
"isstatic": true
,				"parameters": [
{
"type": "object",
"object": "Block"
}
]
}
],
"actions": [
]
}
,		{
"type": "block",
"conditions": [
{
"type": "system",
"method": "Every",
"trigger": false,
"looping": false,
"inverted": false,
"isstatic": false
,				"parameters": [
{
"type": "number",
"expression": {
"type": "float",
"value": 0.05
}
}
]
}
],
"actions": [
{
"type": "system",
"method": "CreateObject"
,				"parameters": [
{
"type": "object",
"object": "DudeShadow"
}
,				{
"type": "layer",
"expression": {
"type": "int",
"value": 0
}
}
,				{
"type": "number",
"expression": {
"type": "object_exp",
"object": "Dude",
"expname": "X"
}
}
,				{
"type": "number",
"expression": {
"type": "object_exp",
"object": "Dude",
"expname": "Y"
}
}
]
}
]
}
]
}
]
};
;
;
cr.plugins.Mouse = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins.Mouse.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
this.buttonMap = new Array(4);		// mouse down states
this.mouseXcanvas = 0;				// mouse position relative to canvas
this.mouseYcanvas = 0;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.onCreate = function()
{
jQuery(document).mousemove(
(function (self) {
return function(info) {
self.onMouseMove(info);
};
})(this)
);
jQuery(document).mousedown(
(function (self) {
return function(info) {
self.onMouseDown(info);
};
})(this)
);
jQuery(document).mouseup(
(function (self) {
return function(info) {
self.onMouseUp(info);
};
})(this)
);
jQuery(document).dblclick(
(function (self) {
return function(info) {
self.onDoubleClick(info);
};
})(this)
);
};
instanceProto.onMouseMove = function(info)
{
var offset = jQuery(this.runtime.canvas).offset();
this.mouseXcanvas = info.pageX - offset.left;
this.mouseYcanvas = info.pageY - offset.top;
};
instanceProto.onMouseDown = function(info)
{
this.buttonMap[info.which] = true;
this.runtime.trigger("OnAnyClick", this);
this.triggerButton = info.which - 1;	// 1-based
this.triggerType = 0;					// single click
this.runtime.trigger("OnClick", this);
this.runtime.trigger("OnObjectClicked", this);
};
instanceProto.onMouseUp = function(info)
{
this.buttonMap[info.which] = false;
this.triggerButton = info.which - 1;	// 1-based
this.runtime.trigger("OnRelease", this);
};
instanceProto.onDoubleClick = function(info)
{
this.triggerButton = info.which - 1;	// 1-based
this.triggerType = 1;					// double click
this.runtime.trigger("OnClick", this);
this.runtime.trigger("OnObjectClicked", this);
};
pluginProto.cnds = {};
var cnds = pluginProto.cnds;
cnds["OnClick"] = function (button, type)
{
return button === this.triggerButton && type === this.triggerType;
};
cnds["OnAnyClick"] = function ()
{
return true;
};
cnds["IsButtonDown"] = function (button)
{
return this.buttonMap[button + 1];	// jQuery uses 1-based buttons for some reason
};
cnds["OnRelease"] = function (button)
{
return button === this.triggerButton;
};
cnds["IsOverObject"] = function (obj)
{
var mx = this.mouseXcanvas + this.runtime.running_layout.scrollX;
var my = this.mouseYcanvas + this.runtime.running_layout.scrollY;
return this.runtime.testAndSelectPointOverlap(obj, new cr.vector2(mx, my));
};
cnds["OnObjectClicked"] = function (button, type, obj)
{
if (button !== this.triggerButton || type !== this.triggerType)
return false;	// wrong click type
var mx = this.mouseXcanvas + this.runtime.running_layout.scrollX;
var my = this.mouseYcanvas + this.runtime.running_layout.scrollY;
return this.runtime.testAndSelectPointOverlap(obj, new cr.vector2(mx, my));
};
pluginProto.exps = {};
var exps = pluginProto.exps;
exps["X"] = function (ret)
{
ret.set_float(this.mouseXcanvas + this.runtime.running_layout.scrollX);
};
exps["Y"] = function (ret)
{
ret.set_float(this.mouseYcanvas + this.runtime.running_layout.scrollY);
};
exps["AbsoluteX"] = function (ret)
{
ret.set_float(this.mouseXcanvas);
};
exps["AbsoluteY"] = function (ret)
{
ret.set_float(this.mouseYcanvas);
};
}());
;
;
cr.plugins.Sprite = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins.Sprite.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
this.texture_img = new Image();
this.texture_img.src = this.texture_file;
this.texture_img.cr_filesize = this.texture_filesize;
this.runtime.wait_for_textures.push(this.texture_img);
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.effectToCompositeOp = function(effect)
{
var ret = effect.toLowerCase().replace(" ", "-");		// Destination over -> destination-over
if (ret == "(none)")			// (none) means source-over, the default
ret = "source-over";
else if (ret == "additive")		// additive means 'lighter', for some reason WHATWG renamed additive :-\ 
ret = "lighter";
return ret;
};
instanceProto.onCreate = function()
{
this.visible = (this.properties["Initial visibility"] === "Visible");
this.compositeOp = this.effectToCompositeOp(this.properties["Effect"]);
};
instanceProto.draw = function(ctx)
{
;
if (this.opacity !== 1.0)
ctx.globalAlpha = this.opacity;
if (this.compositeOp != "source-over")
ctx.globalCompositeOperation = this.compositeOp;
if (this.angle == 0)
{
ctx.drawImage(this.type.texture_img,
this.x - (this.hotspotX * this.width),
this.y - (this.hotspotY * this.height),
this.width,
this.height);
}
else
{
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
ctx.drawImage(this.type.texture_img,
0 - (this.hotspotX * this.width),
0 - (this.hotspotY * this.height),
this.width,
this.height);
ctx.restore();
}
if (this.compositeOp != "source-over")
ctx.globalCompositeOperation = "source-over";
if (this.opacity !== 1.0)
ctx.globalAlpha = 1.0;
};
pluginProto.cnds = {};
var cnds = pluginProto.cnds;
function collmemory_add(collmemory, a, b)
{
collmemory.push([a, b]);
};
function collmemory_remove(collmemory, a, b)
{
var i, j = 0, len, entry;
for (i = 0, len = collmemory.length; i < len; i++)
{
entry = collmemory[i];
if (!((entry[0] === a && entry[1] === b) || (entry[0] === b && entry[1] === a)))
{
collmemory[j] = collmemory[i];
j++;
}
}
collmemory.length = j;
};
function collmemory_removeInstance(collmemory, inst)
{
var i, j = 0, len, entry;
for (i = 0, len = collmemory.length; i < len; i++)
{
entry = collmemory[i];
if (entry[0] !== inst && entry[1] !== inst)
{
collmemory[j] = collmemory[i];
j++;
}
}
collmemory.length = j;
};
function collmemory_has(collmemory, a, b)
{
var i, len, entry;
for (i = 0, len = collmemory.length; i < len; i++)
{
entry = collmemory[i];
if ((entry[0] === a && entry[1] === b) || (entry[0] === b && entry[1] === a))
return true;
}
return false;
};
cnds["OnCollision"] = function (rtype)
{	
if (!rtype)
return false;
var cnd = this.getCurrentCondition();
var ltype = cnd.type;
if (!cnd.collmemory)
{
cnd.collmemory = [];
this.addDestroyCallback((function (collmemory) {
return function(inst) {
collmemory_removeInstance(collmemory, inst);
};
})(cnd.collmemory));
}
var lsol = ltype.getCurrentSol();
var rsol = rtype.getCurrentSol();
var linstances = lsol.getObjects();
var rinstances = rsol.getObjects();
var l, lenl, linst, r, lenr, rinst;
lsol.select_all = false;
lsol.instances.length = 1;
rsol.select_all = false;
rsol.instances.length = 1;
var current_event = this.getCurrentEventStack().current_event;
for (l = 0, lenl = linstances.length; l < lenl; l++)
{
linst = linstances[l];
for (r = 0, lenr = rinstances.length; r < lenr; r++)
{
rinst = rinstances[r];
if (this.testOverlap(linst, rinst))
{
if (!collmemory_has(cnd.collmemory, linst, rinst))
{
collmemory_add(cnd.collmemory, linst, rinst);
if (ltype === rtype)
{
lsol.instances.length = 2;	// just use lsol, is same reference as rsol
lsol.instances[0] = linst;
lsol.instances[1] = rinst;
}
else
{
lsol.instances[0] = linst;
rsol.instances[0] = rinst;
}
this.pushCopySol(current_event.solModifiers);
current_event.retrigger();
this.popSol(current_event.solModifiers);
}
}
else
{
collmemory_remove(cnd.collmemory, linst, rinst);
}
}
}
return false;
};
cnds["IsOverlapping"] = function (rtype)
{
if (!rtype)
return false;
var cnd = this.getCurrentCondition();
var ltype = cnd.type;
var lsol = ltype.getCurrentSol();
var rsol = rtype.getCurrentSol();
var linstances = lsol.getObjects();
var rinstances = rsol.getObjects();
var l, lenl, linst, r, lenr, rinst;
var overlapped;
if (cnd.inverted)
{
var ldest = [];
for (l = 0, lenl = linstances.length; l < lenl; l++)
{
linst = linstances[l];
overlapped = false;
for (r = 0, lenr = rinstances.length; r < lenr; r++)
{
rinst = rinstances[r];
if (this.testOverlap(linst, rinst))
{
overlapped = true;
break;
}
}
if (!overlapped)
ldest.push(linst);
}
lsol.select_all = false;
lsol.instances = ldest;
return lsol.instances.length;
}
else
{
lsol.select_all = false;
lsol.instances.length = 1;
rsol.select_all = false;
rsol.instances.length = 1;
var current_event = this.getCurrentEventStack().current_event;
var temp_collmemory = [];
for (l = 0, lenl = linstances.length; l < lenl; l++)
{
linst = linstances[l];
for (r = 0, lenr = rinstances.length; r < lenr; r++)
{
rinst = rinstances[r];
if (this.testOverlap(linst, rinst))
{
if (ltype === rtype)
{
if (collmemory_has(temp_collmemory, linst, rinst))
continue;
else
{
collmemory_add(temp_collmemory, linst, rinst);	// prevent running for second instance
lsol.instances.length = 2;
lsol.instances[0] = linst;
lsol.instances[1] = rinst;
}
}
else
{
lsol.instances[0] = linst;
rsol.instances[0] = rinst;
}
this.pushCopySol(current_event.solModifiers);
current_event.retrigger();
this.popSol(current_event.solModifiers);
}
}
}
return false;
}
};
pluginProto.acts = {};
var acts = pluginProto.acts;
acts["Spawn"] = function (obj, layer, imgpt)
{
if (!obj || !layer)
return;
var inst = this.runtime.createInstance(obj, layer);
inst.x = this.x;
inst.y = this.y;
inst.angle = this.angle;
var sol = obj.getCurrentSol();
sol.select_all = false;
sol.instances = [ inst ];
};
acts["SetEffect"] = function (effect)
{
var fx = ["source-over", "lighter", "xor", "copy", "destination-over", "source-in", "destination-in", "source-out",
"destination-out", "source-atop", "destination-atop"];
this.compositeOp = fx[effect];
this.runtime.redraw = true;
};
}());
;
;
cr.plugins.TiledBg = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var pluginProto = cr.plugins.TiledBg.prototype;
pluginProto.Type = function(plugin)
{
this.plugin = plugin;
this.runtime = plugin.runtime;
};
var typeProto = pluginProto.Type.prototype;
typeProto.onCreate = function()
{
this.texture_img = new Image();
this.texture_img.src = this.texture_file;
this.texture_img.cr_filesize = this.texture_filesize;
this.runtime.wait_for_textures.push(this.texture_img);
};
pluginProto.Instance = function(type)
{
this.type = type;
this.runtime = type.runtime;
};
var instanceProto = pluginProto.Instance.prototype;
instanceProto.effectToCompositeOp = function(effect)
{
var ret = effect.toLowerCase().replace(" ", "-");		// Destination over -> destination-over
if (ret == "(none)")			// (none) means source-over, the default
ret = "source-over";
else if (ret == "additive")		// additive means 'lighter', for some reason WHATWG renamed additive :-\ 
ret = "lighter";
return ret;
};
instanceProto.onCreate = function()
{
this.visible = (this.properties["Initial visibility"] === "Visible");
this.compositeOp = this.effectToCompositeOp(this.properties["Effect"]);
};
instanceProto.draw = function(ctx)
{
;
if (!this.type.pattern)
this.type.pattern = ctx.createPattern(this.type.texture_img, "repeat");
ctx.save();
ctx.globalAlpha = this.opacity;
ctx.globalCompositeOperation = this.compositeOp;
ctx.fillStyle = this.type.pattern;
var drawX = -(this.hotspotX * this.width);
var drawY = -(this.hotspotY * this.height);
var offX = drawX % this.type.texture_img.width;
var offY = drawY % this.type.texture_img.height;
ctx.translate(this.x + offX, this.y + offY);
if (this.angle !== 0)
ctx.rotate(this.angle);
ctx.fillRect(-offX - (this.hotspotX * this.width),
-offY - (this.hotspotY * this.height),
this.width,
this.height);
ctx.restore();
};
pluginProto.acts = {};
var acts = pluginProto.acts;
acts["SetEffect"] = function (effect)
{
var fx = ["source-over", "lighter", "xor", "copy", "destination-over", "source-in", "destination-in", "source-out",
"destination-out", "source-atop", "destination-atop"];
this.compositeOp = fx[effect];
this.runtime.redraw = true;
};
}());
;
;
cr.behaviors.Fade = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.Fade.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst;				// associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.fadeInTime = this.properties["Fade in time"] * 1000.0;		// to ms
this.waitTime = this.properties["Wait time"] * 1000.0;
this.fadeOutTime = this.properties["Fade out time"] * 1000.0;
this.destroy = this.properties["Destroy"];
this.stage = 0;		// 0 = fade in, 1 = wait, 2 = fade out, 3 = done
this.stageTime = new Date().getTime();
if (this.fadeInTime === 0)
{
this.stage = 1;
if (this.waitTime === 0)
this.stage = 2;
}
else
{
this.inst.opacity = 0;
this.runtime.redraw = true;
}
};
behinstProto.tick = function ()
{
var now = new Date().getTime();
var elapsed;
if (this.stage === 0)
{
elapsed = now - this.stageTime;
this.inst.opacity = elapsed / this.fadeInTime;
this.runtime.redraw = true;
if (this.inst.opacity >= 1.0)
{
this.inst.opacity = 1.0;
this.stage = 1;	// wait stage
this.stageTime = now;
}
}
if (this.stage === 1)
{
elapsed = now - this.stageTime;
if (elapsed >= this.waitTime)
{
this.stage = 2;	// fade out stage
this.stageTime = now;
}
}
if (this.stage === 2)
{
elapsed = now - this.stageTime;
this.inst.opacity = 1.0 - (elapsed / this.fadeOutTime);
this.runtime.redraw = true;
if (this.inst.opacity < 0)
{
this.inst.opacity = 0;
this.stage = 3;	// done
this.stageTime = now;
this.runtime.trigger("OnFadeOutEnd", this.inst);
if (this.destroy === "After fade out")
this.runtime.DestroyInstance(this.inst);
}
}
};
behaviorProto.cnds = {};
var cnds = behaviorProto.cnds;
cnds["OnFadeOutEnd"] = function ()
{
return true;
};
}());
;
;
cr.behaviors.Platform = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.Platform.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst;				// associated object instance to modify
this.runtime = type.runtime;
this.leftkey = false;
this.rightkey = false;
this.jumpkey = false;
this.jumped = false;		// prevent bunnyhopping
this.ignoreInput = false;
this.dx = 0;
this.dy = 0;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
this.acc = this.properties["Acceleration"];
this.dec = this.properties["Deceleration"];
this.maxspeed = this.properties["Max speed"];
this.jumpStrength = this.properties["Jump strength"];
this.g = this.properties["Gravity"];
this.maxFall = this.properties["Max fall speed"];
jQuery(document).keydown(
(function (self) {
return function(info) {
self.onKeyDown(info);
};
})(this)
);
jQuery(document).keyup(
(function (self) {
return function(info) {
self.onKeyUp(info);
};
})(this)
);
};
behinstProto.onKeyDown = function (info)
{	
switch (info.which) {
case 16:	// shift
info.preventDefault();
this.jumpkey = true;
break;
case 37:	// left
info.preventDefault();
this.leftkey = true;
break;
case 39:	// right
info.preventDefault();
this.rightkey = true;
break;
}
if (this.ignoreInput)
{
this.leftkey = false;
this.rightkey = false;
this.jumpkey = false;
}
};
behinstProto.onKeyUp = function (info)
{
switch (info.which) {
case 16:	// shift
info.preventDefault();
this.jumpkey = false;
this.jumped = false;
break;
case 37:	// left
info.preventDefault();
this.leftkey = false;
break;
case 39:	// right
info.preventDefault();
this.rightkey = false;
break;
}
};
behinstProto.isOnFloor = function ()
{
var oldy = this.inst.y;
this.inst.y += 1;
this.inst.set_bbox_changed();
var ret = this.runtime.testOverlapSolid(this.inst);
this.inst.y = oldy;
this.inst.set_bbox_changed();
return ret;
};
behinstProto.tick = function ()
{
var dt = this.runtime.dt;
var left = this.leftkey;
var right = this.rightkey;
var jump = this.jumpkey && !this.jumped;
if (this.isOnFloor())
{
if (jump)
{
this.dy = -this.jumpStrength;
this.jumped = true;
}
}
else
{
this.dy += this.g * dt;
if (this.dy > this.maxFall)
this.dy = this.maxFall;
}
if (left == right)	// both up or both down
{
if (this.dx < 0)
{
this.dx += this.dec * dt;
if (this.dx > 0)
this.dx = 0;
}
else if (this.dx > 0)
{
this.dx -= this.dec * dt;
if (this.dx < 0)
this.dx = 0;
}
}
if (left && !right)
{
if (this.dx > 0)
this.dx -= (this.acc + this.dec) * dt;
else
this.dx -= this.acc * dt;
}
if (right && !left)
{
if (this.dx < 0)
this.dx += (this.acc + this.dec) * dt;
else
this.dx += this.acc * dt;
}
if (this.dx > this.maxspeed)
this.dx = this.maxspeed;
else if (this.dx < -this.maxspeed)
this.dx = -this.maxspeed;
if (this.dx != 0)
{		
var oldx = this.inst.x;
this.inst.x += this.dx * dt;
this.inst.set_bbox_changed();
if (this.runtime.testOverlapSolid(this.inst))
{
var push_dist = Math.max(Math.abs(this.dx * dt * 1.5), 10);
if (!this.runtime.pushOutSolid(this.inst, this.dx < 0 ? 1 : -1, 0, push_dist))
{
;
this.inst.x = oldx;
this.inst.set_bbox_changed();
}
else if (Math.abs(this.inst.x - oldx) < 1)
{
this.inst.x = oldx;
this.inst.set_bbox_changed();
}
this.dx = 0;	// stop
}
}
if (this.dy != 0)
{
var oldy = this.inst.y;
this.inst.y += this.dy * dt;
this.inst.set_bbox_changed();
if (this.runtime.testOverlapSolid(this.inst))
{			
var push_dist = Math.max(Math.abs(this.dy * dt * 1.5), 10);
if (!this.runtime.pushOutSolid(this.inst, 0, this.dy < 0 ? 1 : -1, push_dist))
{
;
this.inst.y = oldy;
this.inst.set_bbox_changed();
}
this.dy = 0;	// stop
}
}
};
behaviorProto.cnds = {};
var cnds = behaviorProto.cnds;
cnds["IsMoving"] = function ()
{
return this.dx != 0 || this.dy != 0;
};
cnds["CompareSpeed"] = function (cmp, s)
{
var speed = Math.sqrt(this.dx * this.dx + this.dy * this.dy);
return cr.do_cmp(speed, cmp, s);
};
cnds["IsOnFloor"] = function ()
{
return this.isOnFloor();
};
cnds["IsJumping"] = function ()
{
return this.dy < 0;
};
cnds["IsFalling"] = function ()
{
return this.dy > 0;
};
behaviorProto.acts = {};
var acts = behaviorProto.acts;
acts["SetIgnoreInput"] = function (ignoring)
{
this.ignoreInput = ignoring;
};
acts["SetMaxSpeed"] = function (maxspeed)
{
this.maxspeed = maxspeed;
if (this.maxspeed < 0)
this.maxspeed = 0;
};
acts["SetAcceleration"] = function (acc)
{
this.acc = acc;
if (this.acc < 0)
this.acc = 0;
};
acts["SetDeceleration"] = function (acc)
{
this.acc = acc;
if (this.acc < 0)
this.acc = 0;
};
acts["SetJumpStrength"] = function (js)
{
this.jumpStrength = js;
if (this.jumpStrength < 0)
this.jumpStrength = 0;
};
acts["SetGravity"] = function (grav)
{
this.g = grav;
if (this.g < 0)
this.g = 0;
};
acts["SetMaxFallSpeed"] = function (mfs)
{
this.maxFall = mfc;
if (this.maxFall < 0)
this.maxFall = 0;
};
behaviorProto.exps = {};
var exps = behaviorProto.exps;
exps["Speed"] = function (ret)
{
ret.set_float(Math.sqrt(this.dx * this.dx + this.dy * this.dy));
};
exps["MaxSpeed"] = function (ret)
{
ret.set_float(this.maxspeed);
};
exps["Acceleration"] = function (ret)
{
ret.set_float(this.acc);
};
exps["Deceleration"] = function (ret)
{
ret.set_float(this.dec);
};
exps["JumpStrength"] = function (ret)
{
ret.set_float(this.jumpStrength);
};
exps["Gravity"] = function (ret)
{
ret.set_float(this.g);
};
exps["MaxFallSpeed"] = function (ret)
{
ret.set_float(this.maxFall);
};
exps["MovingAngle"] = function (ret)
{
ret.set_float(cr.to_degrees(Math.atan2(this.dy, this.dx)));
};
exps["VectorX"] = function (ret)
{
ret.set_float(this.dx);
};
exps["VectorY"] = function (ret)
{
ret.set_float(this.dy);
};
}());
;
;
cr.behaviors.solid = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
var behaviorProto = cr.behaviors.solid.prototype;
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst;				// associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
};
behinstProto.tick = function ()
{
};
}());

