"use strict";

DATA_SDS_SCRIPTED_EVENTS["Ending"] = {};
var evt = DATA_SDS_SCRIPTED_EVENTS["Ending"];
var t=0;
evt[t] = {
			customPre : function(cacheVars){
				cacheVars.meli = cacheVars.objMgr.getNamedObject("Meli");
				cacheVars.malfose = cacheVars.objMgr.getNamedObject("Malfose");
				if (cacheVars.meli){
					// this is a multi-dialog event; we want to lock down movement between them
					cacheVars.controls = cacheVars.meli.controls;
					cacheVars.meli.controls = new Controls();
				}
				if (cacheVars.malfose){
					// jic and for debugging
					cacheVars.malfose.control_state=cacheVars.malfose.CONTROL_STATES.postfight;
				}
				GLOBAL_DIARY.note(5,"MALFOSE_DEAD");
				SDS.meters.visible = false;
				Logging_Save_Score();
				if (DATA_SDS_DIALOGUE["Ending_common_1"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_common_1",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_common_2"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_common_2",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_common_3"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_common_3",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Malfose":{A:true}
			},
			customPost : noop
		};
evt[t+=30] = {
			customPre : function(cacheVars){
				GLOBAL_SCRATCHPAD.note("fade",true);
				GLOBAL_SCRATCHPAD.persist("fade");
			},
			controls : {
			},
			customPost : noop
		};
evt[t+=16] = {
			customPre : function(cacheVars){
				var room = cacheVars.meli.sprite.map_room;
				var getDestName = function(room){
					return function(){
						return "backyard";
					};
				}(room);
				// full-room autoport trigger
				var port = new GO_Passage(room.pixel_width,room.pixel_height,getDestName,noop);
				port.sprite.x = 0;
				port.sprite.y = 0;

				room.addSprite(port.sprite);
				cacheVars.objMgr.add(port);
			},
			controls : {
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				cacheVars.meli.overrideFrame=30; // empty/hidden frame; don't trust visibility=false to not be overridden
				// screen center
				//cacheVars.meli.sprite.x = 66<<4;
				//cacheVars.meli.sprite.y = 9<<4;
				// but no, since we splash back into the water
				// and suppressing that would be a pain,
				// place meli where malfose is about to bust out
				// so the splash can be handwaved as part of that
				cacheVars.meli.sprite.x = 65<<4;
				cacheVars.meli.sprite.y = 14<<4;
			},
			controls : {
			},
			customPost : noop
		};
evt[t+=16] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_common_4"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_common_4",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
				// spawn hellmaw, so it has min priority in the draw
				// spawn Malfose, controls to A
				// spawn trident at correct position & dir to intersect
				// spawn Rinda
				// this is all ideally staged so it just goes on independently
				// of user confirming dialog, meaning we don't get any more
				// event steps for setup until after common_4 closes

				// purely decorative, but don't want to
				// make a dynamic deco system just for this
				cacheVars.hole = new GO_HellMaw();
				cacheVars.hole.sprite.x = (67<<4);
				cacheVars.hole.sprite.y = (15<<4);
				cacheVars.hole.addToRoom(cacheVars.meli.sprite.map_room);
				cacheVars.objMgr.add(cacheVars.hole);

				// spawn Malfose; this also conveniently releases our old cache val
				cacheVars.malfose = new GO_Malfose();
				cacheVars.malfose.sprite.x = (67<<4);
				cacheVars.malfose.sprite.y = (18<<4);
				cacheVars.malfose.direction = 1;
				cacheVars.malfose.addToRoom(cacheVars.meli.sprite.map_room);
				cacheVars.objMgr.add(cacheVars.malfose);
				cacheVars.malfose.control_state=cacheVars.malfose.CONTROL_STATES.settled;
				cacheVars.malfose.hp=0;
				cacheVars.malfose.interactions = 
					DEFINE_GAMEOBJECT_INTERACTIONS.CONTROL |
					DEFINE_GAMEOBJECT_INTERACTIONS.DAMAGE;
				cacheVars.malfose.controls.press(cacheVars.malfose.controls,"A");
				// malfose moves -4 px/sec on y (up)
				// trident moves -6 px/sec on needed axis
				// so if 2 trains leave in opposite directions at noon on Thursday,
				// malfose needs to cover 8.5 blocks (to half a block past y row 10) = 136px
				// which will take 34 frames
				// so trident needs to either be added later, which would be ugly,
				// or disregard terrain & wrapping and be added
				// 34 frames below row 10 or 34 frames right of column 68
				cacheVars.trident = new GO_BattleTrident();
				cacheVars.trident.sprite.x = (68<<4);
				cacheVars.trident.sprite.y = (10<<4);
				cacheVars.trident.addToRoom(cacheVars.meli.sprite.map_room);
				cacheVars.objMgr.add(cacheVars.trident);
				if (!GLOBAL_DIARY.check(1,"TRIDENT") || GLOBAL_DIARY.check(1,"NOTRIDENT")){
					cacheVars.trident.vertical = false;
					cacheVars.trident.sprite.x += 34*6;
				}
				else{
					cacheVars.trident.vertical = true;
					cacheVars.trident.sprite.y += 34*6 + 32; // malfose has a big butt
					cacheVars.trident.sprite.constraints.y = DEFINE_SPRITE_MOVE_CONSTRAINT.NONE;
				}

				// aaand o right we need a rinda for the trident to home to
				cacheVars.rinda = new GO_Rinda();
				cacheVars.rinda.sprite.x = (76<<4);
				cacheVars.rinda.sprite.y = (10<<4);
				cacheVars.rinda.direction = -1;
				cacheVars.rinda.addToRoom(cacheVars.meli.sprite.map_room);
				cacheVars.objMgr.add(cacheVars.rinda);

				cacheVars.trident.target_name = "Malfose";
				cacheVars.trident.owner_name="Rinda";

				// but thank you past-me for all those lovely solid stone blocks :P
				// Trident DOES get hung up on them because it must collide with sprites.
				// May need to find them and hack them to not be solid...

				// and, sure, why not put charis in to keep spawn logic consolidated
				cacheVars.charis = new GO_Charis();
				cacheVars.charis.sprite.x = (51<<4);
				cacheVars.charis.sprite.y = (3<<4);
				cacheVars.charis.direction = 1;
				cacheVars.charis.addToRoom(cacheVars.meli.sprite.map_room);
				cacheVars.objMgr.add(cacheVars.charis);
			},
			controls : {
				//"Malfose":{A:true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				//SDS.switchBgm("Forged in Steel",true); // TODO after prequel: patch in Rinda's actual hero theme here (spoilers: Shadows of the Past but with fewer shadows)
				SDS.switchBgm("Hero of the Past",true);
				SDS.queueBgm("Fly, Legendary SkyDragon",true);
			},
			controls : {
				"Rinda":{left:true}
			},
			customPost : noop
		};
evt[t+=56] = {
			customPre : noop,
			controls : {
				"Rinda":{left:false}
			},
			customPost : noop
		};

evt[++t] = DlgEvent("Ending_common_5");

evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{right:true}
			},
			customPost : noop
		};
evt[t+=30] = {
			customPre : noop,
			controls : {
				"Rinda":{right:false}
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{left:true}
			},
			customPost : noop
		};
evt[t+=30] = {
			customPre : noop,
			controls : {
				"Rinda":{left:false}
			},
			customPost : noop
		};

evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_common_6"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_common_6",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Charis":{right:true}
			},
			customPost : noop
		};
evt[t+=32] = {
			customPre : noop,
			controls : {
				"Charis":{down:true}
			},
			customPost : noop
		};
evt[t+=32] = {
			customPre : noop,
			controls : {
				"Charis":{right:false, left:true}
			},
			customPost : noop
		};
evt[t+=24] = {
			customPre : noop,
			controls : {
				"Charis":{right:true, left:false}
			},
			customPost : noop
		};
evt[t+=24] = {
			customPre : noop,
			controls : {
				"Charis":{down:false}
			},
			customPost : noop
		};
evt[t+=24] = {
			customPre : noop,
			controls : {
				"Charis":{up:true}
			},
			customPost : noop
		};
evt[t+=16] = {
			customPre : noop,
			controls : {
				"Charis":{right:false, up:false}
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_common_7"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_common_7",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				
			},
			customPost : noop
		};

for (var l=8; l<=14; ++l){
	evt[++t] = DlgEvent("Ending_common_"+l);
}

evt[++t] = {
			customPre : function(cacheVars){
				GLOBAL_SCRATCHPAD.note("fade",true);
				GLOBAL_SCRATCHPAD.persist("fade");
			},
			controls : {
				"Rinda":{left:true, down: true},
				"Charis":{right:true, down: true},
			},
			customPost : noop
		};

evt[t+=16] = {
			customPre : function(cacheVars){
				var room = cacheVars.meli.sprite.map_room;
				var getDestName = function(room){
					return function(){
						return "underdark_arena_flooded";
					};
				}(room);
				// full-room autoport trigger
				var port = new GO_Passage(room.pixel_width,room.pixel_height,getDestName,noop);
				port.sprite.x = 0;
				port.sprite.y = 0;

				room.addSprite(port.sprite);
				cacheVars.objMgr.add(port);
			},
			controls : {
			},
			customPost : noop
		};




evt[++t] = {
			customPre : function(cacheVars){
				cacheVars.meli.overrideFrame=27; // TODO?: actual death frame
				cacheVars.meli.sprite.x = 17<<4;
				cacheVars.meli.sprite.y = 22<<4;

				cacheVars.rinda = new GO_Rinda();
				cacheVars.rinda.sprite.x = ((19+10)<<4);
				cacheVars.rinda.sprite.y = ((22-10)<<4);
				cacheVars.rinda.direction = -1;
				cacheVars.rinda.addToRoom(cacheVars.meli.sprite.map_room);
				cacheVars.objMgr.add(cacheVars.rinda);
				cacheVars.uncacheObjects.push("Rinda"); // new room new instance

				cacheVars.charis = new GO_Charis();
				cacheVars.charis.sprite.x = ((19+11)<<4)+8;
				cacheVars.charis.sprite.y = ((21-11)<<4);
				cacheVars.charis.direction = 1;
				cacheVars.charis.addToRoom(cacheVars.meli.sprite.map_room);
				cacheVars.objMgr.add(cacheVars.charis);
				cacheVars.uncacheObjects.push("Charis"); // new room new instance
			},
			controls : {
				
			},
			customPost : noop
		};
evt[t+=16] = {
			customPre : function(cacheVars){
				// event-skipping this while allowing the fade delay in both cases
				// would require more juggling than I'm in the mood for.
				// So condition the dialogue and allow the dead frame if nope
				if (!GLOBAL_DIARY.check(5,"RAVI_KILL") && DATA_SDS_DIALOGUE["Ending_common_15"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_common_15",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				
			},
			customPost : noop
		};

evt[++t] = {
			customPre : noop,
			controls : {
				"Raviene":{down:true},
				"Rinda":{down:true,left:true},
				"Charis":{down:true,left:true},
			},
			customPost : noop
		};
evt[t+=80] = {
			customPre : noop,
			controls : {
				"Rinda":{down:false,left:false},
			},
			customPost : noop
		};
evt[t+=8] = {
			customPre : noop,
			controls : {
				"Charis":{down:false,left:false},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (!GLOBAL_DIARY.check(5,"RAVI_KILL") && DATA_SDS_DIALOGUE["Ending_common_16"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_common_16",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				
			},
			customPost : noop
		};

for (var l=17; l<=21; ++l){
	evt[++t] = DlgEvent("Ending_common_"+l);
}
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_common_22"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_common_22",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Charis":{B:true},
			},
			customPost : noop
		};

// spawn goddess
evt[++t] = {
			customPre : function(cacheVars){
				cacheVars.goddess = new GO_Goddess();
				cacheVars.goddess.sprite.x = (12<<4)+8;
				cacheVars.goddess.sprite.y = (19<<4);
				cacheVars.goddess.direction = 1;
				cacheVars.goddess.addToRoom(cacheVars.meli.sprite.map_room);
				cacheVars.objMgr.add(cacheVars.goddess);

				cacheVars.goddess.FadeIn();
				SDS.queueBgm("Divine Pity", true);
			},
			controls : {
				
			},
			customPost : noop
		};

evt[++t] = {
			customPre : noop,
			controls : {
				"Goddess":{A:true},
				"Charis":{B:false},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_common_23"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_common_23",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}

				if (GLOBAL_DIARY.check(5,"RAVI_KILL")) cacheVars.frameCounter+=5;
			},
			controls : {
				//"Goddess":{A:true}, // frameCounter override causes current frame controls to be skipped
				//"Charis":{B:false},
			},
			customPost : noop
		};

evt[++t] = {
			customPre : noop,
			controls : {
				"Goddess":{A:false},
				"Raviene":{left:true, down:false},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Raviene":{left:false, down:true},
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_common_24");
evt[++t] = {
			customPre : noop,
			controls : {
				"Goddess":{A:true},
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_common_25");

evt[++t] = {
			customPre : noop,
			controls : {
				"Goddess":{A:false},
				"Rinda":{up:true, left:true},
			},
			customPost : noop
		};
evt[t+=10] = {
			customPre : noop,
			controls : {
				"Rinda":{up:false},
			},
			customPost : noop
		};
evt[t+=8] = {
			customPre : noop,
			controls : {
				"Rinda":{left:false},
			},
			customPost : noop
		};

evt[++t] = DlgEvent("Ending_common_26");
evt[++t] = {
			customPre : noop,
			controls : {
				"Goddess":{A:true},
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_common_27");

evt[++t] = {
			customPre : noop,
			controls : {
				"Goddess":{A:false},
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_common_28");
evt[t+=24] = {
			customPre : noop,
			controls : {
				"Goddess":{B:true},
			},
			customPost : noop
		};
evt[t+=24] = {
			customPre : noop,
			controls : {
				"Goddess":{down:true,left:true},
			},
			customPost : noop
		};
evt[t+=4] = {
			customPre : noop,
			controls : {
				"Goddess":{down:false,left:false},
			},
			customPost : noop
		};
evt[t+=16] = DlgEvent("Ending_common_29");

evt[++t] = {
			customPre : function(cacheVars){
				cacheVars.rinda.sprite.x += 2;
				cacheVars.charis.sprite.x += 2;
			},
			controls : {
				"Raviene":{down:false},
			},
			customPost : noop
		};

evt[t+=30] = {
			customPre : noop,
			controls : {
				"Rinda":{left:true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Rinda":{left:false},
			},
			customPost : noop
		};

evt[t+=45] = {
			customPre : noop,
			controls : {
				"Rinda":{left:true},
			},
			customPost : noop
		};
evt[t+=5] = {
			customPre : noop,
			controls : {
				"Rinda":{left:false},
			},
			customPost : noop
		};
evt[t+=15] = DlgEvent("Ending_common_30");

evt[++t] = {
			customPre : noop,
			controls : {
				"Goddess":{right:true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Goddess":{right:false},
			},
			customPost : function(cacheVars){
				// manhandle meli's event trigger slots
				// since that's the least-ugly option
				// I can think of compared with grabbing
				// for globals or making all ending branches
				// line-GOTO indices of the same event
				if (cacheVars.meli){
					cacheVars.meli.triggering = {
						triggerEvent: function(sourceGO){
							var all = true;
							var none = true;
							for (var s in DEFINE_DIARY_EVENTS.SOULS){
								if (!GLOBAL_DIARY.hasSoul(s)){
									all=false;
									if (s==='RAVIENE') none=false;
								}
								else if (s!=='MELI' && s!='RAVIENE') none=false;
							}
							if (none) return "Ending_Low_Souls";
							if (all) return "Ending_All_Souls";
							return "Ending_Normal";
						},
					};
				}
			}
		};


DATA_SDS_SCRIPTED_EVENTS["Ending_Normal"] = {};
var evt = DATA_SDS_SCRIPTED_EVENTS["Ending_Normal"];
var t=0;
evt[t] = {
			customPre : function(cacheVars){
				cacheVars.meli = cacheVars.objMgr.getNamedObject("Meli");
				if (DATA_SDS_DIALOGUE["Ending_normal_1"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_normal_1",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}

				if (GLOBAL_DIARY.check(5,"RAVI_KILL")) cacheVars.frameCounter+=1;
			},
			controls : {
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_normal_2"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_normal_2",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Raviene":{down:true}
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_normal_3"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_normal_3",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Raviene":{down:false}
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
			},
			customPost : function(cacheVars){
				// manhandle meli's event trigger slots
				// since that's the least-ugly option
				// I can think of compared with grabbing
				// for globals or making all ending branches
				// line-GOTO indices of the same event
				if (cacheVars.meli){
					cacheVars.meli.triggering = {
						triggerEvent: function(sourceGO){
							return "Finish_Ending_Normal";
						},
					};
				}
			}
		};

DATA_SDS_SCRIPTED_EVENTS["Finish_Ending_Normal"] = {};
var evt = DATA_SDS_SCRIPTED_EVENTS["Finish_Ending_Normal"];
var t=0;
evt[t] = {
			customPre : function(cacheVars){
				cacheVars.meli = cacheVars.objMgr.getNamedObject("Meli");
				GLOBAL_SCRATCHPAD.note("fade",true);
				GLOBAL_SCRATCHPAD.persist("fade");
			},
			controls : {
			},
			customPost : noop
		};
evt[t+=16] = {
			customPre : function(cacheVars){
				var all = true;
				for (var t in DEFINE_DIARY_EVENTS.TEARS){
					if (!GLOBAL_DIARY.hasTear(t)){
						all=false;
					}
				}
				if (all){
					cacheVars.tidx = 0;
					cacheVars.tcount = Object.keys(DEFINE_DIARY_EVENTS.TEARS).length;
					cacheVars.tsprite = [];
					cacheVars.frameCounter+=1;
				}
			},
			controls : {
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_normal_close"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_normal_close",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
							
							// END GAME
							SDS.switchBgm("Self; Pity",true);
							SDS.ending = "Finally Over";
							var diaryel = document.getElementById("diary");
							diaryel.value=GLOBAL_DIARY.record("DIED");
							diaryel.scrollTop = diaryel.scrollHeight;
							cacheVars.frameCounter+=1000; // skip to should-be-very-done
						}
					});
				}
			},
			controls : {
			},
			customPost : noop
		};

evt[++t] = {
			customPre : function(cacheVars){
				var room = cacheVars.meli.sprite.map_room;
				var getDestName = function(room){
					return function(){
						return "the_void";
					};
				}(room);
				// full-room autoport trigger
				var port = new GO_Passage(room.pixel_width,room.pixel_height,getDestName,noop);
				port.sprite.x = 0;
				port.sprite.y = 0;

				room.addSprite(port.sprite);
				cacheVars.objMgr.add(port);
			},
			controls : {
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				var room = cacheVars.meli.sprite.map_room;
				cacheVars.meli.sprite.x = (room.pixel_width>>1)-8;
				cacheVars.meli.sprite.y = (room.pixel_height>>1)-8;
			},
			controls : {
			},
			customPost : noop
		};
for (var collected in DEFINE_DIARY_EVENTS.TEARS){
	evt[t+=20] = {
			customPre : function(cacheVars){
				var room = cacheVars.meli.sprite.map_room;
				var tear = new GO_Tear(collected);
				tear.addToRoom(room);
				cacheVars.objMgr.add(tear);
				tear.sprite.y = cacheVars.meli.sprite.y - 24;
				tear.sprite.x = cacheVars.meli.sprite.x + cacheVars.meli.sprite.center.x - (cacheVars.tcount<<3) + (cacheVars.tidx<<4);
				tear.interactions = 0; // purely decorative now
				cacheVars.tsprite.push(tear.sprite);
				++cacheVars.tidx;
			},
			controls : {
			},
			customPost : noop
		};
}
t+=20;
for (var i=0; i<60; ++i){
	evt[++t] = {
			customPre : function(cacheVars){
				var mx = cacheVars.meli.sprite.x;
				var my = cacheVars.meli.sprite.y;
				// so hard to not fall into more modern let & forEach syntax...
				for (var j=0; j<cacheVars.tsprite.length; ++j){
					var dx = cacheVars.tsprite[j].x - mx;
					var dy = cacheVars.tsprite[j].y - my;

					var sx = dx<0?-1:1;
					var sy = dy<0?-1:1;

					dx = sx*(Math.abs(dx*15)>>4);
					dy = sy*(Math.abs(dy*15)>>4);

					cacheVars.tsprite[j].x = mx + dx;
					cacheVars.tsprite[j].y = my + dy;
				}
			},
			controls : {
			},
			customPost : noop
		};
}
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_normal_close_all_tears"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_normal_close_all_tears",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
							
							// END GAME
							SDS.switchBgm("Divine Pity",true);
							SDS.ending = "Somewhere Out There";
							var diaryel = document.getElementById("diary");
							diaryel.value=GLOBAL_DIARY.record("DIED");
							diaryel.scrollTop = diaryel.scrollHeight;
						}
					});
				}
			},
			controls : {
			},
			customPost : noop
		};

DATA_SDS_SCRIPTED_EVENTS["Ending_Low_Souls"] = {};
var evt = DATA_SDS_SCRIPTED_EVENTS["Ending_Low_Souls"];
var t=0;
evt[t] = DlgEvent("Ending_low_1");
evt[++t] = {
			customPre : function(cacheVars){
				cacheVars.meli = cacheVars.objMgr.getNamedObject("Meli");
				if (DATA_SDS_DIALOGUE["Ending_low_2"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_low_2",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Raviene":{down:true}
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_low_3"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_low_3",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Raviene":{down:false}
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Goddess":{A:true, B:true},
			},
			customPost : noop
		};

//for (var i=1;i<8;++i){
//	evt[++t] = DlgEvent("Ending_choice_"+i);
//}
evt[++t] = DlgEvent("Ending_choice_1");
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{down:true, right:true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_choice_2"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_choice_2",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Rinda":{down:false, right:false},
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_choice_3");
evt[++t] = {
			customPre : noop,
			controls : {
				"Charis":{down:true, left: true},
			},
			customPost : noop
		};
evt[t+=4] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_choice_4"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_choice_4",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Charis":{down:false, left: false},
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_choice_5");
evt[++t] = {
			customPre : noop,
			controls : {
				"Raviene":{left:true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Raviene":{left:false, right: true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_choice_6"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_choice_6",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Raviene":{right: false},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Raviene":{left:true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_choice_7"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_choice_7",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Raviene":{left: false, down:true},
			},
			customPost : noop
		};

evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_choice_8"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_choice_8",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
							
							if (retval==1) cacheVars.frameCounter+=1;
							// else 
						}
					});
				}
			},
			controls : {
			},
			customPost : noop
		};
// choose to die: literally invoke normal ending path & jump to end
evt[++t] = {
			customPre : noop,
			controls : {
			},
			customPost : function(cacheVars){
				cacheVars.frameCounter+=1000; // skip to should-be-very-done
				// manhandle meli's event trigger slots
				// since that's the least-ugly option
				// I can think of compared with grabbing
				// for globals or making all ending branches
				// line-GOTO indices of the same event
				if (cacheVars.meli){
					cacheVars.meli.triggering = {
						triggerEvent: function(sourceGO){
							return "Finish_Ending_Normal";
						},
					};
				}
			}
		};
// choose to live: new sequence, with similar branch
evt[++t] = {
			customPre : function(cacheVars){
				cacheVars.meli.overrideFrame = null;
				for (var dx=-8; dx<=8; dx+=8){
					for (var dy=-8; dy<=8; dy+=8){
						var sparkle = new GO_Sparkle(
							30,
							dx*(dy==0?3:2),
							dy*(dx==0?3:2),
							);
						sparkle.spawnOnSprite(cacheVars.meli.sprite,cacheVars.objMgr);

					}
				}
			},
			controls : {
				"Goddess":{A:false, B:false},
			},
			customPost : noop
		};
evt[t+=30] = {
			customPre : noop,
			controls : {
				"Meli":{left:true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Meli":{left:false},
			},
			customPost : noop
		};
evt[t+=30] = {
			customPre : noop,
			controls : {
				"Meli":{right:true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Meli":{right:false},
			},
			customPost : noop
		};
evt[t+=30] = {
			customPre : noop,
			controls : {
				"Meli":{left:true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{up:true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{left:false},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{right:true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{up:false},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{down:true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{right:false},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{left: true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{left:false,down:false},
			},
			customPost : noop
		};

evt[t+=16] = {
			customPre : function(cacheVars){
				var all = true;
				for (var t in DEFINE_DIARY_EVENTS.TEARS){
					if (!GLOBAL_DIARY.hasTear(t)){
						all=false;
					}
				}
				if (all){
					cacheVars.tidx = 0;
					cacheVars.tcount = Object.keys(DEFINE_DIARY_EVENTS.TEARS).length;
					cacheVars.tsprite = [];
					cacheVars.frameCounter+=1;
				}
			},
			controls : {
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_low_close"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_low_close",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
							
							// END GAME
							SDS.switchBgm("It Is a Good Day",true);
							SDS.ending = "Second Chance";
							var diaryel = document.getElementById("diary");
							diaryel.value=GLOBAL_DIARY.record("LIVED");
							diaryel.scrollTop = diaryel.scrollHeight;
							cacheVars.frameCounter+=1000; // skip to should-be-very-done
						}
					});
				}
			},
			controls : {
			},
			customPost : noop
		};


for (var collected in DEFINE_DIARY_EVENTS.TEARS){
	evt[t+=20] = {
			customPre : function(cacheVars){
				var room = cacheVars.meli.sprite.map_room;
				var tear = new GO_Tear(collected);
				tear.addToRoom(room);
				cacheVars.objMgr.add(tear);
				tear.sprite.y = cacheVars.meli.sprite.y + 24;
				tear.sprite.x = cacheVars.meli.sprite.x + cacheVars.meli.sprite.center.x - (cacheVars.tcount<<3) + (cacheVars.tidx<<4);
				tear.interactions = 0; // purely decorative now
				cacheVars.tsprite.push(tear.sprite);
				++cacheVars.tidx;
			},
			controls : {
			},
			customPost : noop
		};
}
t+=20;
for (var i=0; i<60; ++i){
	evt[++t] = {
			customPre : function(cacheVars){
				var mx = cacheVars.meli.sprite.x;
				var my = cacheVars.meli.sprite.y;
				// so hard to not fall into more modern let & forEach syntax...
				for (var j=0; j<cacheVars.tsprite.length; ++j){
					var dx = cacheVars.tsprite[j].x - mx;
					var dy = cacheVars.tsprite[j].y - my;

					var sx = dx<0?-1:1;
					var sy = dy<0?-1:1;

					dx = sx*(Math.abs(dx*15)>>4);
					dy = sy*(Math.abs(dy*15)>>4);

					cacheVars.tsprite[j].x = mx + dx;
					cacheVars.tsprite[j].y = my + dy;
				}
			},
			controls : {
			},
			customPost : noop
		};
}
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_low_close_all_tears"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_low_close_all_tears",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
							
							// END GAME
							SDS.switchBgm("Teamwork",true);
							SDS.ending = "Fresh Start";
							var diaryel = document.getElementById("diary");
							diaryel.value=GLOBAL_DIARY.record("LIVED");
							diaryel.scrollTop = diaryel.scrollHeight;
						}
					});
				}
			},
			controls : {
			},
			customPost : noop
		};


DATA_SDS_SCRIPTED_EVENTS["Ending_All_Souls"] = {};
var evt = DATA_SDS_SCRIPTED_EVENTS["Ending_All_Souls"];
var t=0;
evt[t] = DlgEvent("Ending_high_1");
evt[++t] = {
			customPre : function(cacheVars){
				cacheVars.meli = cacheVars.objMgr.getNamedObject("Meli");
				if (DATA_SDS_DIALOGUE["Ending_high_2"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_high_2",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Raviene":{down:true}
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_high_3"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_high_3",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Raviene":{down:false}
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_high_4");
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{down:true, left:true},
			},
			customPost : noop
		};
evt[t+=8] = {
			customPre : noop,
			controls : {
				"Rinda":{left:false, right: true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_high_5"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_high_5",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Rinda":{down:false, right: false}
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_high_6");
evt[++t] = DlgEvent("Ending_high_7");
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{up:true, left: true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{left: false},
			},
			customPost : noop
		};
evt[t+=12] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_high_8"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_high_8",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Rinda":{up:false}
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_high_9");
evt[++t] = DlgEvent("Ending_high_10");
evt[++t] = DlgEvent("Ending_high_11");
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{up:true, left: true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{left: false, right: true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{up: false, down: true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{right: false, left: true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{down: false},
			},
			customPost : noop
		};
evt[t+=5] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_high_12"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_high_12",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Rinda":{left: false}
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Charis":{left: true, up: true},
			},
			customPost : noop
		};
evt[t+=5] = {
			customPre : noop,
			controls : {
				"Charis":{left: false, up: false},
				"Rinda":{right: true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_high_13"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_high_13",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Rinda":{right: false},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{left: true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_high_14"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_high_14",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Rinda":{left: false},
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_high_15");
evt[++t] = DlgEvent("Ending_high_16");
evt[++t] = DlgEvent("Ending_high_17");


evt[++t] = {
			customPre : noop,
			controls : {
				"Goddess":{A:true, B:true},
			},
			customPost : noop
		};

//for (var i=1;i<8;++i){
//	evt[++t] = DlgEvent("Ending_choice_"+i);
//}
evt[++t] = DlgEvent("Ending_choice_1");
evt[++t] = {
			customPre : noop,
			controls : {
				"Rinda":{down:true, right:true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_choice_2"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_choice_2",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Rinda":{down:false, right:false},
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_choice_3");
evt[++t] = {
			customPre : noop,
			controls : {
				"Charis":{down:true, left: true},
			},
			customPost : noop
		};
evt[t+=4] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_choice_4"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_choice_4",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Charis":{down:false, left: false},
			},
			customPost : noop
		};
evt[++t] = DlgEvent("Ending_choice_5");
evt[++t] = {
			customPre : noop,
			controls : {
				"Raviene":{left:true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Raviene":{left:false, right: true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_choice_6"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_choice_6",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Raviene":{right: false},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Raviene":{left:true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_choice_7"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_choice_7",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
						}
					});
				}
			},
			controls : {
				"Raviene":{left: false, down:true},
			},
			customPost : noop
		};

evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_choice_8"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_choice_8",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
							
							if (retval==1) cacheVars.frameCounter+=1;
							// else 
						}
					});
				}
			},
			controls : {
			},
			customPost : noop
		};
// choose to die: literally invoke normal ending path & jump to end
evt[++t] = {
			customPre : noop,
			controls : {
			},
			customPost : function(cacheVars){
				cacheVars.frameCounter+=1000; // skip to should-be-very-done
				// manhandle meli's event trigger slots
				// since that's the least-ugly option
				// I can think of compared with grabbing
				// for globals or making all ending branches
				// line-GOTO indices of the same event
				if (cacheVars.meli){
					cacheVars.meli.triggering = {
						triggerEvent: function(sourceGO){
							return "Finish_Ending_Normal";
						},
					};
				}
			}
		};
// choose to live: new sequence, with similar branch
evt[++t] = {
			customPre : function(cacheVars){
				cacheVars.meli.overrideFrame = null;
				for (var dx=-8; dx<=8; dx+=8){
					for (var dy=-8; dy<=8; dy+=8){
						var sparkle = new GO_Sparkle(
							30,
							dx*(dy==0?3:2),
							dy*(dx==0?3:2),
							);
						sparkle.spawnOnSprite(cacheVars.meli.sprite,cacheVars.objMgr);

					}
				}
			},
			controls : {
				"Goddess":{A:false, B:false},
				"Raviene":{right:true, down:false},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Raviene":{right:false},
			},
			customPost : noop
		};
evt[t+=30] = {
			customPre : noop,
			controls : {
				"Meli":{left:true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Meli":{left:false},
			},
			customPost : noop
		};
evt[t+=30] = {
			customPre : noop,
			controls : {
				"Meli":{right:true},
			},
			customPost : noop
		};
evt[++t] = {
			customPre : noop,
			controls : {
				"Meli":{right:false},
			},
			customPost : noop
		};
evt[t+=30] = {
			customPre : noop,
			controls : {
				"Meli":{left:true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{up:true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{left:false},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{right:true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{up:false},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{down:true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{right:false},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{left: true},
			},
			customPost : noop
		};
evt[t+=2] = {
			customPre : noop,
			controls : {
				"Meli":{left:false,down:false},
			},
			customPost : noop
		};

evt[t+=16] = {
			customPre : function(cacheVars){
				var all = true;
				for (var t in DEFINE_DIARY_EVENTS.TEARS){
					if (!GLOBAL_DIARY.hasTear(t)){
						all=false;
					}
				}
				if (all){
					cacheVars.tidx = 0;
					cacheVars.tcount = Object.keys(DEFINE_DIARY_EVENTS.TEARS).length;
					cacheVars.tsprite = [];
					cacheVars.frameCounter+=1;
				}
			},
			controls : {
			},
			customPost : noop
		};
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_high_close"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_high_close",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
							
							// END GAME
							SDS.switchBgm("Fly, Legendary SkyDragon",true);
							SDS.ending = "A New Soul";
							var diaryel = document.getElementById("diary");
							diaryel.value=GLOBAL_DIARY.record("LIVED");
							diaryel.scrollTop = diaryel.scrollHeight;
							cacheVars.frameCounter+=1000; // skip to should-be-very-done
						}
					});
				}
			},
			controls : {
			},
			customPost : noop
		};


for (var collected in DEFINE_DIARY_EVENTS.TEARS){
	evt[t+=20] = {
			customPre : function(cacheVars){
				var room = cacheVars.meli.sprite.map_room;
				var tear = new GO_Tear(collected);
				tear.addToRoom(room);
				cacheVars.objMgr.add(tear);
				tear.sprite.y = cacheVars.meli.sprite.y + 24;
				tear.sprite.x = cacheVars.meli.sprite.x + cacheVars.meli.sprite.center.x - (cacheVars.tcount<<3) + (cacheVars.tidx<<4);
				tear.interactions = 0; // purely decorative now
				cacheVars.tsprite.push(tear.sprite);
				++cacheVars.tidx;
			},
			controls : {
			},
			customPost : noop
		};
}
t+=20;
for (var i=0; i<60; ++i){
	evt[++t] = {
			customPre : function(cacheVars){
				var mx = cacheVars.meli.sprite.x;
				var my = cacheVars.meli.sprite.y;
				// so hard to not fall into more modern let & forEach syntax...
				for (var j=0; j<cacheVars.tsprite.length; ++j){
					var dx = cacheVars.tsprite[j].x - mx;
					var dy = cacheVars.tsprite[j].y - my;

					var sx = dx<0?-1:1;
					var sy = dy<0?-1:1;

					dx = sx*(Math.abs(dx*15)>>4);
					dy = sy*(Math.abs(dy*15)>>4);

					cacheVars.tsprite[j].x = mx + dx;
					cacheVars.tsprite[j].y = my + dy;
				}
			},
			controls : {
			},
			customPost : noop
		};
}
evt[++t] = {
			customPre : function(cacheVars){
				if (DATA_SDS_DIALOGUE["Ending_high_close_all_tears"]){
					cacheVars.wait=true;
					cacheVars.dlgMgr.open("Ending_high_close_all_tears",function(index,retval){
						if (retval!=null){
							cacheVars.wait=false; // yay js scoping
							
							// END GAME
							SDS.switchBgm("Forged in Steel",true);
							SDS.ending = "A New Goddess";
							var diaryel = document.getElementById("diary");
							diaryel.value=GLOBAL_DIARY.record("LIVED");
							diaryel.scrollTop = diaryel.scrollHeight;
						}
					});
				}
			},
			controls : {
			},
			customPost : noop
		};