//store game variables in an associative array
var storage = [];
function isNumber(value)
{
return (!isNaN(value));
}
function sleep(milliseconds)
{
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
}
class Action
{
constructor()
{
this.arg = [];
this.argCount = 0;
this.weight = 0;
this.idx = -1;
this.bag = [];
this.lastBagIdx = -1;
}
dump(pad)
{
console.log(pad + this.arg[0]);
for(var i = 1; i < this.argCount; i++)
{
console.log(pad + " '" + this.arg[i] + "'");
}
}
}
class Point2I
{
constructor()
{
this.x = 0;
this.y = 0;
}
normalize(len)
{
var factor = len / Math.sqrt(this.x*this.x + this.y*this.y);
this.x *= factor;
this.y *= factor;
}
}
class Overlay
{
constructor()
{
this.origin = new Point2I();
this.pos = new Point2I();
this.w = 0;
this.h = 0;
this.opacity = 100;
this.action = [];
this.actionCount = 0;
this.actionIdx = 0;
this.name = "";
this.parent = ""; //
this.frameParent = ""; //overlay which we get our subframe prefix from
this.subFrame = ""; //name of current subframe
this.scene = "";
this.frameTime = 0;
this.nextFrameTime = 1;
this.clickAction = new Action();
//position tweening
this.posA = new Point2I();
this.posB = new Point2I();
this.posStartTime = 0;
this.posEndTime = 0;
this.posEaseType = "inOutQuad";
this.posEaseDecay = 10.0;
this.posEaseBounce = 5;
//opacity tweening
this.opacA = 0;
this.opacB = 0;
this.opacStartTime = 0;
this.opacEndTime = 0;
this.opacEaseType = "inOutQuad";
//blur tweening
this.blurA = 0;
this.blurB = 0;
this.blurStartTime = 0;
this.blurEndTime = 0;
this.blurEaseType = "inOutQuad";
//stack
this.stack = [];
}
addAction(word)
{
this.action[this.actionCount] = new Action();
for(var i = 0; i < word.length; i++)
{
this.action[this.actionCount].arg[i] = word[i];
this.action[this.actionCount].argCount++;
}
this.action[this.actionCount].idx = this.actionCount;
this.actionCount++;
}
addRandAction(word)
{
this.action[this.actionCount] = new Action();
this.action[this.actionCount].weight = word[0];
for(var i = 1; i < word.length; i++)
{
this.action[this.actionCount].arg[i-1] = word[i];
this.action[this.actionCount].argCount++;
}
this.action[this.actionCount].idx = this.actionCount;
this.actionCount++;
}
dump(pad)
{
console.log(pad + "OVERLAY " + this.pos.x + " " + this.pos.y + " " + this.w + " " + this.h + " " + this.name);
console.log(pad + " frameTime " + this.frameTime);
console.log(pad + " nextFrameTime " + this.nextFrameTime);
if(this.clickAction.argCount > 0)
{
this.clickAction.dump(pad + " CLICK->");
}
for(var i = 0; i < this.actionCount; i++)
{
if(this.actionIdx == i)
this.action[i].dump(pad + " >");
else
this.action[i].dump(pad + " ");
}
}
create()
{
//reset to initial condition
this.pos.x = this.origin.x;
this.pos.y = this.origin.y;
this.opacity = 1.0;
this.posStartTime = 0;
this.posEndTime = 0;
this.opacStartTime = 0;
this.opacEndTime = 0;
this.blur = 0;
this.blurA = 0;
this.blurB = 0;
this.blurStartTime = 0;
this.blurEndTime = 0;
this.blurEaseType = "inOutQuad";
//create an image object on the page
var o = document.createElement("div");
o.id = "overlay-" + this.name;
//console.log("Creating overlay ", o.id);
o.style.height = this.h * gScale;
o.style.width = this.w * gScale;
o.style.left = "0px"; //this.pos.x * gScale;
o.style.top = "0px"; //this.pos.y * gScale;
o.style.transform = "translate(" + (this.pos.x * gScale) + "px," + this.pos.y * gScale + "px)";
o.style.position = "absolute";
o.style.backgroundSize = "100%";
o.onclick = clickHandler;
o.onmousedown = selectionPreventer;
if(this.parent)
{
var p = scene[currSceneIdx].getDivByName(this.parent);
if(p)
{
p.appendChild(o);
}
else
{
console.log("ERROR: cannot find parent '" + this.parent + "'");
playArea.appendChild(o);
}
}
else
{
playArea.appendChild(o);
}
this.div = o;
this.actionIdx = -1;
this.nextFrameTime = gTimeStamp;
//this.doNextAction();
//where we're putting stuff (for relative positioning)
this.cursor = new Point2I();
}
preload()
{
//create a preloader object
//TODO: maximum number of pre-loader objects, cycle out the old ones
//create a preloader object for all frames
for(var i = 0; i < this.actionCount; i++)
{
switch(this.action[i].arg[0])
{
case "FRAME":
addPreloader(this.action[i].arg[1]);
break;
case "OFRAME":
addPreloader(this.action[i].arg[2]);
break;
case "SUBFRAME":
//add variations of preloader for all of the parentFrame's frames
if(!this.frameParent)
console.log("ERROR: preload SUBFRAME without FRAME_PARENT");
this.scene.getOverlayByName(this.frameParent).preloadSubFrame(this.action[i].arg[1]);
break;
case "SOUND":
preloadSound(this.action[i].arg[1]);
setSoundLoop(this.action[i].arg[1], false);
setSoundVolume(this.action[i].arg[1], 1.0);
setSoundChannel(this.action[i].arg[1], -1);
for(var j = 2; j < this.action[i].arg.length; j++)
{
var soundName = this.action[i].arg[1];
if(this.action[i].arg[j] == "LOOP")
{
setSoundLoop(soundName, true);
continue;
}
if(this.action[i].arg[j] == "VOL")
{
j++;
setSoundVolume(soundName, this.action[i].arg[j]);
}
if(this.action[i].arg[j] == "CH")
{
j++;
setSoundChannel(soundName, this.action[i].arg[j]);
}
}
break;
}
}
}
preloadSubFrame(subFrameSuffix)
{
for(var i = 0; i < this.actionCount; i++)
{
switch(this.action[i].arg[0])
{
case "FRAME":
var imgName = this.action[i].arg[1];
imgName = getBaseName(imgName);
imgName += subFrameSuffix;
console.log("Preloading subframe " + imgName);
addPreloader(imgName);
break;
}
}
}
onClick()
{
//console.log(gTimeStamp + " clicked on overlay " + this.name);
if(this.clickAction.argCount > 0)
{
//can't click if we're in a transition
var inTransition = false;
if(this.actionIdx >= 0)
{
if(this.action[this.actionIdx].arg[0] == "WAIT" && this.nextFrameTime != 0)
inTransition = true;
}
if(!inTransition)
{
this.doAction(this.clickAction);
}
}
}
jumpTo(labelName)
{
//varaible lookup
if(labelName.charAt(0) == "$")
labelName = storage[labelName];
if(labelName == "NEXT")
{
this.doNextAction();
return;
}
for(var i = 0; i < this.actionCount; i++)
{
if(this.action[i].arg[0] != "LABEL")
continue;
if(this.action[i].arg[1] != labelName)
continue;
this.actionIdx = i;
this.doNextAction();
return;
}
console.log("ERROR: could not find jump label '" + labelName + "'");
}
doNextAction()
{
if(this.actionCount <= 0)
return;
this.actionIdx++;
this.actionIdx %= this.actionCount;
this.doAction(this.action[this.actionIdx]);
}
updateSubFrame()
{
//get frame prefix from frameParent overlay
var p = this.scene.getDivByName(this.frameParent);
var prefix = p.className.substr("preload-".length, 999);
//assemble subframe name
this.div.className = "preload-" + prefix + getBaseName(this.subFrame);
}
doAction(action)
{
if(typeof action === 'undefined')
return;
/*
if(action.argCount == 1)
console.log(gTimeStamp + " " + this.name + " " + action.arg[0] );
else
console.log(gTimeStamp + " " + this.name + " " + action.arg[0] + " " + action.arg[1] + " " + action.arg[2] + " " + action.arg[3]);
*/
switch(action.arg[0])
{
case "FRAME":
//images are loaded into preloader boxes, just set the class
this.div.className = "preload-" + getBaseName(action.arg[1]);
if(action.argCount == 2)
{
//blank = wait forever
this.nextFrameTime = 0;
}
else if(action.argCount == 3)
{
if(action.arg[2] == "")
{
//blank = wait forever
this.nextFrameTime = 0;
}
else if(action.arg[2] == 0)
{
//0 = advance immediately
}
else
{
//all others treated as a hold time
//this.nextFrameTime = gTimeStamp + parseInt(action.arg[2]);
//this.nextFrameTime += parseInt(action.arg[2]); //this will have more accurate timing, but has problems with OGOTO lines
if(action.arg[2].charAt(0) == "$")
this.nextFrameTime += parseInt(storage[action.arg[2]]);
else
this.nextFrameTime += parseInt(action.arg[2]);
}
}
else
{
console.log("ERROR: FRAME command has unknown argument count");
}
this.scene.updateSubFrames(this.name);
break;
case "OFRAME":
//set the frame on a different overlay
var o = document.getElementById("overlay-" + action.arg[1]);
o.className = "preload-" + getBaseName(action.arg[2]);
if(action.argCount == 3)
{
//blank = wait forever
this.nextFrameTime = 0;
}
else if(action.argCount == 3)
{
if(action.arg[2] == "")
{
//blank = wait forever
this.nextFrameTime = 0;
}
else if(action.arg[2] == 0)
{
//0 = advance immediately
}
else
{
//all others treated as a hold time
//this.nextFrameTime = gTimeStamp + parseInt(action.arg[2]);
//this.nextFrameTime += parseInt(action.arg[2]); //this will have more accurate timing, but has problems with OGOTO lines
if(action.arg[2].charAt(0) == "$")
this.nextFrameTime += parseInt(storage[action.arg[2]]);
else
this.nextFrameTime += parseInt(action.arg[2]);
}
}
//this.doNextAction();
break;
case "SUBFRAME":
if(!this.frameParent)
{
console.log("ERROR: overlay '" + this.name + "' has SUBFRAME op without FRAME_PARENT");
break;
}
//save the subframe suffix name
this.subFrame = action.arg[1];
this.updateSubFrame();
if(action.arg[2] == "")
{
//blank = wait forever
this.nextFrameTime = 0;
}
else if(action.arg[2] == 0)
{
//zero = immediately continue (do multiple actions at once)
//this.doNextAction();
}
else
{
//all others treated as a hold time
this.nextFrameTime += parseInt(action.arg[2]); //this will have more accurate timing, but has problems with OGOTO lines
}
break;
case "NEXT":
//console.log("doing next");
this.nextFrameTime = gTimeStamp;
this.doNextAction();
break;
case "SETSCENE":
this.nextFrameTime = 0;
setScene(action.arg[1]);
break;
case "WAIT":
if(action.argCount == 1)
{
//no arguments, wait forever
this.nextFrameTime = 0;
}
else if(action.argCount == 2)
{
//one argument, want that amount
if(action.arg[1].charAt(0) == "$")
this.nextFrameTime = gTimeStamp + parseInt(storage[action.arg[1]]);
else
this.nextFrameTime = gTimeStamp + parseInt(action.arg[1]);
}
else if(action.argCount == 3)
{
//two arguments, use as random range
var low = action.arg[1];
var high = action.arg[2];
if(low.charAt(0) == "$")
low = storage[low];
if(high.charAt(0) == "$")
high = storage[high];
var time = rand(parseInt(low), parseInt(high));
this.nextFrameTime = gTimeStamp + parseInt(time);
}
else
{
console.log("ERROR: bad agument count (" + action.argCount + ") on WAIT");
}
break;
case "GOTO":
if(action.argCount == 2)
{
//just a label, assume this overlay
this.jumpTo(action.arg[1]);
}
else if(action.argCount == 3)
{
//overlay name and label provided
this.scene.overlayJumpTo(action.arg[1], action.arg[2]);
//this.doNextAction();
}
else
{
console.log("ERROR: bad number of arguments on GOTO");
}
break;
case "CALL":
//like goto except we set the stack pointer
if(action.argCount == 2)
{
//just a label, use this overlay
this.stack.push(this.actionIdx);
this.jumpTo(action.arg[1]);
}
else if(action.argCount == 3)
{
//overlay name and label provided
this.scene.overlayCall(action.arg[1], action.arg[2]);
//this.doNextAction();
}
else
{
console.log("ERROR: bad number of arguments on CALL");
}
break;
case "RETURN":
//jump to the saved stack pointer
this.actionIdx = this.stack.pop();
this.doNextAction();
break;
case "LABEL":
//this.doNextAction();
this.nextFrameTime = gTimeStamp;
break;
case "RANDOM":
/*
//randomly jump to one of the given labels
//add up total odds
var totalOdds = 0;
for(var i = 1; i < action.argCount; i += 2)
{
//console.log("adding " + word[i]);
totalOdds += Math.floor(action.arg[i]); //lol if you don't do math.floor it appends them as strings
}
//pick a random number between 1 and totalodds
var pick = Math.floor(Math.random() * totalOdds) + 1;
//console.log("picked " + pick + " / " + totalOdds);
//walk along until we go past picked value
// then chose label before that
totalOdds = 0;
for(var i = 1; i < action.argCount; i += 2)
{
totalOdds += Math.floor(action.arg[i]);
if(pick <= totalOdds)
{
this.jumpTo(action.arg[i+1]);
break;
}
}
*/
//actions between here and end_random should have weights
var totalOdds = 0;
var walkIdx = action.idx + 1;
var endIdx = 0;
while(1)
{
if(this.action[walkIdx].arg[0] == "END_RANDOM")
{
endIdx = walkIdx;
break;
}
if(this.action[walkIdx].weight <= 0)
{
console.log("ERROR: RANDOM without END_RANDOM?");
break
}
totalOdds += Math.floor(this.action[walkIdx].weight);
walkIdx++;
}
//pick a random number between 1 and totalodds
var pick = Math.floor(Math.random() * totalOdds) + 1;
//console.log("picked " + pick + " / " + totalOdds);
//walk along until we go past picked value
// then chose label before that
totalOdds = 0;
var walkIdx = action.idx + 1;
while(1)
{
if(this.action[walkIdx].weight <= 0)
{
console.log("RAN OFF RANDOM LIST");
this.actionIdx = walkIdx-2;
//this.doNextAction();
break;
}
totalOdds += Math.floor(this.action[walkIdx].weight);
//console.log("WALK " + totalOdds + " " + pick);
if(pick <= totalOdds)
{
this.actionIdx = endIdx;
this.doAction(this.action[walkIdx]);
//this.doNextAction();
return;
}
walkIdx++;
}
break;
case "END_RANDOM":
//this.doNextAction();
break;
case "RANDOM_BAG":
//like random, except no repeats
//actions between here and end_random should have weights
var totalOdds = 0;
var walkIdx = action.idx + 1;
var endIdx = 0;
while(1)
{
if(this.action[walkIdx].arg[0] == "END_RANDOM")
{
endIdx = walkIdx;
break;
}
if(this.action[walkIdx].weight <= 0)
{
console.log("ERROR: RANDOM_BAG without END_RANDOM?");
break;
}
//skip items already picked in this bag, and the last item picked in the previous bag
if(action.bag[walkIdx] !== 1 && walkIdx !== action.lastBagIdx)
totalOdds += Math.floor(this.action[walkIdx].weight);
walkIdx++;
}
if(totalOdds == 0)
{
//bag full, start a new one
action.bag = []; //gabage collected
//add odds again
totalOdds = 0;
walkIdx = action.idx + 1;
endIdx = 0;
while(1)
{
if(this.action[walkIdx].arg[0] == "END_RANDOM")
{
endIdx = walkIdx;
break;
}
if(this.action[walkIdx].weight <= 0)
{
console.log("ERROR: RANDOM_BAG without END_RANDOM?");
break;
}
//skip items already picked in this bag, and the last item picked in the previous bag
if(action.bag[walkIdx] !== 1 && walkIdx !== action.lastBagIdx)
totalOdds += Math.floor(this.action[walkIdx].weight);
walkIdx++;
}
if(totalOdds == 0)
{
console.log("ERROR: Failed to add odds after random_bag reset");
break;
}
}
//pick a random number between 1 and totalodds
var pick = Math.floor(Math.random() * totalOdds) + 1;
//walk along until we go past picked value
// then chose label before that
totalOdds = 0;
var walkIdx = action.idx + 1;
while(1)
{
if(this.action[walkIdx].weight <= 0)
{
console.log("RAN OFF RANDOM LIST");
this.actionIdx = walkIdx-2;
//this.doNextAction();
break;
}
if(action.bag[walkIdx] !== 1 && walkIdx !== action.lastBagItem)
totalOdds += Math.floor(this.action[walkIdx].weight);
//console.log("WALK " + totalOdds + " " + pick);
if(pick <= totalOdds)
{
this.actionIdx = endIdx;
action.lastBagIdx = walkIdx;
action.bag[walkIdx] = 1;
//console.log("Bag item " + walkIdx);
this.doAction(this.action[walkIdx]);
//this.doNextAction();
return;
}
walkIdx++;
}
break;
case "POS":
//update position target
if(action.argCount == 3)
{
//POS, x, y
this.pos.x = parseInt(action.arg[1]);
this.pos.y = parseInt(action.arg[2]);
//cancel position animation
this.posStartTime = 0;
this.posEndTime = 0;
this.resize();
}
else if(action.argCount >= 4)
{
//POS, x, y, time, (easeType)
this.posA.x = this.pos.x;
this.posA.y = this.pos.y;
this.posB.x = parseInt(action.arg[1]);
this.posB.y = parseInt(action.arg[2]);
this.posStartTime = gTimeStamp;
this.posEndTime = gTimeStamp + parseInt(action.arg[3]);
if(action.argCount == 7)
{
this.posEaseType = action.arg[4];
this.posEaseBounce = parseFloat(action.arg[5]);
this.posEaseDecay = parseFloat(action.arg[6]);
}
else if(action.argCount == 5)
{
this.posEaseType = action.arg[4];
this.posEaseDecay = 10.0;
this.posEaseBounce = 5;
}
else
{
this.posEaseType = "inOutQuad";
}
}
//this.doNextAction();
break;
case "POS+":
//update position target
if(action.argCount == 3)
{
//POS+, x, y
this.pos.x = parseInt(this.pos.x) + parseInt(action.arg[1]);
this.pos.y = parseInt(this.pos.y) + parseInt(action.arg[2]);
//cancel position animation
this.posStartTime = 0;
this.posEndTime = 0;
this.resize();
}
else if(action.argCount >= 4)
{
//POS+, x, y, time, (easeType)
if(this.posEndTime > 0)
{
//currently an animation in progress, start at the end of it
this.posA.x = this.posB.x;
this.posA.y = this.posB.y;
}
else
{
this.posA.x = this.pos.x;
this.posA.y = this.pos.y;
}
this.posB.x = parseInt(this.posA.x) + parseInt(action.arg[1]);
this.posB.y = parseInt(this.posA.y) + parseInt(action.arg[2]);
this.posStartTime = gTimeStamp;
this.posEndTime = gTimeStamp + parseInt(action.arg[3]);
if(action.argCount == 7)
{
//console.log("seven args");
this.posEaseType = action.arg[4];
this.posEaseBounce = parseFloat(action.arg[5]);
this.posEaseDecay = parseFloat(action.arg[6]);
}
else if(action.argCount == 5)
{
this.posEaseType = action.arg[4];
this.posEaseDecay = 10.0;
this.posEaseBounce = 5;
}
else
{
this.posEaseType = "inOutQuad";
}
}
//this.doNextAction();
break;
case "OPAC":
//update opacity target
if(action.argCount == 2)
{
//no time given, apply immediately
this.opacity = parseFloat(action.arg[1]);
this.opacStartTime = 0;
this.opacEndTime = 0;
//console.log("setting opacity " + this.name, this.opacity);
}
else if(action.argCount == 3 || action.argCount == 4)
{
//time given, set target
this.opacA = parseFloat(this.opacity);
this.opacB = parseFloat(action.arg[1]);
this.opacStartTime = gTimeStamp;
this.opacEndTime = gTimeStamp + parseInt(action.arg[2]);
if(action.argCount == 4)
this.opacEaseType = action.arg[3];
else
this.opacEaseType = "inOutQuad";
//console.log("setting opacity " + this.name, this.opacB);
}
this.div.style.opacity = parseFloat(this.opacity);
//this.doNextAction();
break;
case "FLIP":
if(action.argCount == 2)
{
if(action.arg[1] == 1)
this.div.style.scale = "1 -1";
else
this.div.style.scale = "1 1";
}
else
{
//scale is magic and if you set it to "1 1", it becomes "1"
// this should just be two variables or a type with .x and .y
// css/javascript is fucking retarded
var xScale = 1;
var yScale = 1;
if(this.div.style.scale != "1" && this.div.style.scale != "")
{
xScale = this.div.style.scale.split(' ')[0];
yScale = this.div.style.scale.split(' ')[1];
}
yScale *= -1;
this.div.style.scale = xScale + " " + yScale;
}
break;
case "SOUND":
//set sound defaults
//setSoundLoop(action.arg[1], false);
//setSoundVolume(action.arg[1], 1.0);
//setSoundChannel(action.arg[1], -1);
for(var i = 2; i < action.arg.length; i++)
{
if(action.arg[i] == "LOOP")
{
setSoundLoop(action.arg[1], true);
continue;
}
if(action.arg[i] == "VOL")
{
i++;
setSoundVolume(action.arg[1], action.arg[i]);
}
if(action.arg[i] == "CH")
{
i++;
setSoundChannel(action.arg[1], action.arg[i]);
}
}
if(action.arg[3] == "LOOP")
setSoundLoop(action.arg[1], true);
else
playSound(action.arg[1]);
//this.doNextAction();
break;
case "BLUR":
if(action.argCount == 2)
{
//instant
this.blur = action.arg[1];
this.div.style.filter = "blur(" + this.blur + "px)";
//this.doNextAction();
}
else if(action.argCount == 3)
{
//time target
this.blurA = this.blur;
this.blurB = action.arg[1];
this.blurStartTime = gTimeStamp;
this.blurEndTime = gTimeStamp + parseInt(action.arg[2]);
this.blurEaseType = "inOutQuad";
}
else if(action.argCount == 4)
{
//time target + ease type
this.blurA = this.blur;
this.blurB = action.arg[1];
this.blurStartTime = gTimeStamp;
this.blurEndTime = gTimeStamp + parseInt(action.arg[2]);
this.blurEaseType = action.arg[3];
}
break;
case "PRELOAD":
this.resize();
if(isPreloadComplete())
{
//this.doNextAction();
//this.div.innerHTML = "Loaded!";
//this.div.className = "loadingText"; //in case of instant preload
this.div.innerHTML = getPreloadString() + "
Click to play";
this.div.className = "loadingText noSelect";
//this.nextFrameTime = 0;
//this.actionIdx--;
this.nextFrameTime = gTimeStamp + 30;
resizePage();
}
else
{
//preload overlay
this.div.innerHTML = getPreloadString();
this.div.className = "loadingText";
//check again in a little bit
this.actionIdx--;
this.nextFrameTime = gTimeStamp + 30;
resizePage();
}
break;
case "FILL":
this.div.style.backgroundColor = action.arg[1];
break;
case "TEXT":
//create text object
//console.log("TEXT " + action.arg[4]);
var d = document.createElement("div");
d.innerHTML = action.arg[4];
d.className = action.arg[1].replaceAll(",", " ") + " " + "noSelect";
d.origin = new Point2I();
//position may be relative to previous text box (makes moving things easier)
var relative = false;
if(action.arg[2].charAt(0) == "+")
relative = true;
if(action.arg[3].charAt(0) == "+")
relative = true;
if(relative)
{
d.origin.x = this.cursor.x + parseInt(action.arg[2]);
d.origin.y = this.cursor.y + parseInt(action.arg[3]);
}
else
{
d.origin.x = parseInt(action.arg[2]);
d.origin.y = parseInt(action.arg[3]);
}
this.cursor.x = d.origin.x;
this.cursor.y = d.origin.y;
d.style.left = (parseFloat(d.origin.x) / parseFloat(imageWidth) * 100.0) + "%";
d.style.top = (parseFloat(d.origin.y) / parseFloat(imageHeight) * 100.0) + "%";
this.div.appendChild(d);
//foo = d;
d.addEventListener("mousedown", onMouseDownText);
d.addEventListener("mousemove", onMouseMoveText);
d.addEventListener("mouseup", onMouseUpText);
d.addEventListener("click", onClickText);
d.overlay = this;
//this.doNextAction();
this.resize();
break;
case "ONCLICKTEXT":
//set a click event for the latest text object
this.div.lastChild.clickAction = new Action();
if(action.arg[1].charAt(0) == "$")
{
//variable assignments start with $
this.div.lastChild.clickAction.arg[0] = "VAR-OP";
this.div.lastChild.clickAction.argCount++;
for(var a = 1; a < action.argCount; a++)
{
this.div.lastChild.clickAction.arg[a] = action.arg[a];
this.div.lastChild.clickAction.argCount++;
}
}
else
{
for(var a = 1; a < action.argCount; a++)
{
this.div.lastChild.clickAction.arg[a-1] = action.arg[a];
this.div.lastChild.clickAction.argCount++;
}
}
break;
case "CLEARTEXT":
//clear all text objects
while (this.div.firstChild)
{
this.div.removeChild(this.div.firstChild);
}
//this.doNextAction();
break;
case "TAIL":
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var polygon = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
svg.appendChild(polygon);
makeTail(polygon, action.arg[1], action.arg[2], action.arg[3], action.arg[4])
svg.style.top = 0;
svg.style.left = 0;
svg.style.position = "absolute";
svg.style.width = "100%";
svg.style.height = "100%";
svg.setAttribute("viewBox", "0 0 " + imageWidth + " " + imageHeight);
polygon.style.stroke = action.arg[5];
polygon.style.fill = action.arg[5];
//svg.onclick = clickHandler;
svg.style.pointerEvents = "none";
this.div.appendChild(svg);
currDebugTail = polygon;
//this.doNextAction();
break;
case "PARENT":
//this.doNextAction();
break;
case "FRAME_PARENT":
//this.doNextAction();
break;
case "TRANSITION":
this.scene.transitionType = action.arg[1]; // fade/scrubLeft/etc
this.scene.transitionDirection = action.arg[2]; // in/out
this.scene.fader.style.backgroundColor = action.arg[3]; // hex color
this.scene.transitionStartTime = gTimeStamp;
var time = action.arg[4];
if(time.charAt(0) == "$")
time = parseInt(storage[time]);
else
time = parseInt(time);
this.scene.transitionEndTime = gTimeStamp + time;
if(action.arg[5])
this.scene.transitionEaseType = action.arg[5];
else
this.scene.transitionEaseType = "inOutQuad";
this.scene.fader.style.opacity = 0.0;
this.scene.fader.style.left = "0px;";
this.scene.fader.style.right = "";
this.scene.fader.style.width = "100%";
this.scene.fader.style.height = "100%";
//this.doNextAction();
break;
case "PLAYALLSOUND":
//hack for iOS, which will only play a sound in response to user input
playAllSound();
//this.doNextAction();
break;
case "STOPALLSOUND":
//hack for iOS, which will only play a sound in response to user input
stopAllSound(action.arg[1]);
//this.doNextAction();
break;
case "CHVOLUME":
//sound channel volume animation
//CHVOLUME