caitsith2
He/Him
Player (46)
Joined: 3/26/2004
Posts: 194
That was pretty much exactly what I was going to do with the lotus guardian. It seems that he only has 45 hitpoints in the full version, unlike 55 in the demo. Also, don't visit portal 2 immediately after beating the lotus guardian. We have another less out of the way opportunity to visit portal 2, before we need to use it. Given that there shouldn't be any randomness up to your current point, we should be able to edit out the portal 2 visit. Some of the savings you improved upon, caused me to drop my jaw a few times.
caitsith2
He/Him
Player (46)
Joined: 3/26/2004
Posts: 194
I think I may have optimized SGCLEVEL as much as I could now, with a 44 frame improvement. encode
Expert player (3555)
Joined: 11/9/2007
Posts: 375
Location: Varberg, Sweden
Made some adjustments here and there. Up to where the WIP ends I saved 19 frames besides the time gained from skipping that portal. http://dehacked.2y.net/microstorage.php/info/410381908/Battle%20Kid%20-%20Fortress%20of%20Peril_WIP.fm2 caitsith2, I see that you've put down quite a lot of effort on this game. Except what's shown in this thread I recently found the map at VGmaps and saw it was also made by you. Did you plan to finish a run to submit at this site? Since if you intended to do this yourself I of course won't steal it away from you.
feos wrote:
Only Aglar can improve this now.
caitsith2
He/Him
Player (46)
Joined: 3/26/2004
Posts: 194
For the time being, I will deal with the side bonuses, like the boss rush, petuniax, etc... I don't mind if you work on the main game itself.
caitsith2
He/Him
Player (46)
Joined: 3/26/2004
Posts: 194
Boss Rush optimized. fm2, encode
Active player (421)
Joined: 9/27/2004
Posts: 650
Location: Canada
Something seems a bit off to me about the hydra fight. I'm guessing there are invulerability periods to worry about but for some reason it still strikes me as some shots aren't being taken as soon as they could be.
caitsith2
He/Him
Player (46)
Joined: 3/26/2004
Posts: 194
Yeah, the bsoss is invulnerable while its mouth is closed. The other issue, is the bubble projectiles. If it was not for the timing of that third bubble on second phase, I could have finished the boss sooner. I may give it another shot later. As for Zedd, his first attack needs to be manipulated from timing his room is entered, due to there being absolutely 0 manipulation frames, once the lag frames are finished playing, and finally for the last boss, Much faster to fight from that upper platform. The one plus side to handling the boss rush, is that many of the boss strategies can be applied to the main game. Oh yeah, I look forward to Battle Kid 2 coming out, so that it can be TASed as well.
Expert player (3555)
Joined: 11/9/2007
Posts: 375
Location: Varberg, Sweden
I've been working on the main game the last couple of days and found quite some new strategies and micro optimization tricks. The boss battles I've done are also faster than in the posted boss rush run. I can give it away via PM if anyone's interested, since I think I might have a submitable run ready in just some days depending on how easy the last bosses turns out to be, so there won't be much waiting time for you anyway.
feos wrote:
Only Aglar can improve this now.
Skilled player (1305)
Joined: 9/7/2007
Posts: 1354
Location: U.S.
Looking foward to it. But I havent played the game yet so its best if I dont look at it. :( btw, What are you going to do next? Wizards & Warriors 2?
Expert player (3555)
Joined: 11/9/2007
Posts: 375
Location: Varberg, Sweden
Sonikkustar wrote:
btw, What are you going to do next? Wizards & Warriors 2?
Breakfast:) Actually I have no more TAS plans as of now. My TASes are often very impulsively chosen, like this one.
feos wrote:
Only Aglar can improve this now.
caitsith2
He/Him
Player (46)
Joined: 3/26/2004
Posts: 194
New revision of the lua hitbox displaying script. Now displays extended hud info, as well as where instant death zones are, among some other things.
-- Battle Kid: Fortress of Peril 
-- Written by CaitSith2
-- May 1, 2011
-- Displays Hitboxes, Enemy HP, and various stats on screen
-- Now possible to turn display of some info on/off.
-- Finally fixed hitbox drawing of sprite type 48, which is only noticeable in one room.
-- Added collision zones for Solid objects and instant death zones.
-- Marked where the blinking spikes will appear.
-- Sprite type 48 now displays a timer, for when the enemy will spawn, and a box to show where it will spawn.
-- Amethyst Angel Death hit boxes added
-- OwlBot Death hit boxes added
-- Converted from while(true) loop to register.gui
-- Fixed displaying of Lotus Gaurdian Hitbox
-- Fixed displaying of Cleo hit box.
-- Added Trigger lines for Lethal Lemons, Life Stealin' Lime, Homing Drones, Spike Traps, Sniper Snails.
-- Added Battle Information for Zedd and TY-52414ET.
-- Now differentiate between game action and cutscenes, no info displayed during cutscenes.

--(framecounter <= 125589)

local function line(x1,y1,x2,y2,color)
		gui.drawline(x1,y1,x2,y2,color);
end;
local function box(x1,y1,x2,y2,color)
	-- gui.text(50,50,x1..","..y1.." "..x2..","..y2);
	-- if (x1 > 0 and x1 < 255 and x2 > 0 and x2 < 255 and y1 > 0 and y1 < 241 and y2 > 0 and y2 < 241) then
		-- gui.drawbox(x1,y1,x2,y2,color);
		gui.drawline(x1,y1,x1,y2,color);
		gui.drawline(x1,y1,x2,y1,color);
		gui.drawline(x2,y1,x2,y2,color);
		gui.drawline(x1,y2,x2,y2,color);
	-- end;
end;
local function text(x,y,str)
	if (x >= 0 and x < 255 and y >= 0 and y < 240) then
		gui.text(x,y,str);
	end;
end;
local function pixel(x,y,color)
	if (x > 0 and x < 255 and y > 0 and y < 240) then
		gui.drawpixel(x,y,color);
	end;
end;

enable_tas_info = 1
infinite_loop = 1
end_avi = 141000

function battlekidloop()
	framecounter = emu.framecount();
	local enable_extended_info = 1
	local enable_hud_info = 1
	local enable_debug_code = 0

	
	local info_frames = 300
	local info_1 = 1200
	local info_1_string = "PETUNIAX"
	local info_1_author = "CaitSith2"
	local info_2 = 1800
	local frame_rate = 60.098769685745869044
	local frames_per_minute = frame_rate * 60
	local gameaction = memory.readbyte(0);
	local gameactiontwo = memory.readbyte(1);
	text(1,1,"");

	if ((enable_hud_info == 1) and (gameaction == 136) and (gameactiontwo <= 10)) then
		xloc = memory.readbyte(0x1E)
		yloc = memory.readbyte(0x1D) / 2
		text(210,0,string.format(" %02d,%02d ",xloc,yloc));

		portals = memory.readbyte(0x8A)
		if (bit.band(portals,0x01) == 0x01) then
			PortalA = 0x31
		else
			PortalA = 0x5F
		end;
		if (bit.band(portals,0x02) == 0x02) then
			PortalB = 0x32
		else
			PortalB = 0x5F
		end;
		if (bit.band(portals,0x04) == 0x04) then
			PortalC = 0x33
		else
			PortalC = 0x5F
		end;
		if (bit.band(portals,0x08) == 0x08) then
			PortalD = 0x34
		else
			PortalD = 0x5F
		end;
		if (bit.band(portals,0x10) == 0x10) then
			PortalE = 0x35
		else
			PortalE = 0x5F
		end;
		jumpsleft = memory.readbyte(0x4D)
		jumpstotal = memory.readbyte(0x4E)
		text(8,0,string.format("TP:%c%c%c%c%c  %d/%d",PortalA,PortalB,PortalC,PortalD,PortalE,jumpsleft,jumpstotal))
	end;

	if ((enable_extended_info == 1) and (gameaction == 136) and (gameactiontwo <= 10)) then
		
		local stuff = 0x0300; -- start of tile data, 4 bytes each, y, ?, ?, x. every tile appears to be 10x10px
		local timmy = 0x0031;		--V1.1
		local timmyshots = 0x0290;
		--local timmy = 0x0030;		--Demo and V1.0
		if(memory.readbyte(0x22) == 1) then
			timmy = 0x30;
		else
			timmy = 0x31;
		end;


		--spritetype is structured bitwise as follows, ffffbbdd
		--ffff = flags. 0001 = box backs off one color on sprites 3-15.
		--		    0010 = 
		--bb = box color. 00 = red, 01 = yellow, 10 = green, 11 = no box.
		--dd = display info. 00 = All info, 01 = no info, 10 = HP, 11 = Phase
	      local spritetype = { 	0x00,0x00,0x00,0x00,0x00, 0x00,0x08,0x00,0x02,0x00, 
						0x09,0x00,0x04,0x00,0x01, 0x00,0x0A,0x00,0x08,0x00, 
						0x00,0x00,0x00,0x00,0x02, 0x00,0x08,0x00,0x00,0x00, 
						0x41,0x00,0x05,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x04,0x00, 

						0x14,0x00,0x08,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 
						0x00,0x00,0x02,0x00,0x00, 0x00,0x0D,0x00,0x02,0x00, 
						0x41,0x00,0x01,0x00,0x00, 0x00,0x20,0x00,0x03,0x00, 
						0x40,0x00,0x42,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 
						0x08,0x00,0x41,0x00,0x00, 0x00,0x41,0x00,0x08,0x00, 

						0x01,0x00,0x09,0x00,0x00, 0x00,0x41,0x00,0x00,0x00, 
						0x00,0x00,0x08,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 
						0x08,0x00,0x01,0x00,0x01, 0x00,0x05,0x00,0x00,0x00, 
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 

						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00, 
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,
	 
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,
						0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,

						0x00,0x00,0x00,0x00,0x00, 0x00,
		};
		-- print boxes for all the tiles
		-- invalid tiles are automatically hidden because their x/y coords are out of range, i guess
		x1 = memory.readbyte(timmy);
		x2 = memory.readbyte(timmy+1);
		y1 = memory.readbyte(timmy+2) + 24;
		y2 = memory.readbyte(timmy+3) + 24;
		hp = memory.readbyte(0x20);

		--draw room collision zones
		i=0
		for j=0,15 do
			blocktype = memory.readbyte(0x500 + (i*16) + j)
			if(blocktype == 1) then		--Solid Object
				box(j*16,36+(i*16),16+(j*16),40+(i*16),"cyan")
			end;
			if(blocktype == 2) then		--Instant Kill Object
				box(j*16,36+(i*16),16+(j*16),40+(i*16),"red")
			end;
			
		end;

		for i=1,13 do
			for j=0,15 do
				blocktype = memory.readbyte(0x500 + (i*16) + j)
				if(blocktype == 1) then		--Solid Object
					box(j*16,24+(i*16),15+(j*16),39+(i*16),"cyan")
				end;
				if(blocktype == 2) then		--Instant Kill Object
					box(j*16,24+(i*16),15+(j*16),39+(i*16),"red")
				end;
				if(blocktype == 102) then	--Blinking spike in its Off state
					box(j*16,24+(i*16),15+(j*16),39+(i*16),"yellow")
					gui.drawline(j*16,24+(i*16),15+(j*16),39+(i*16),"yellow");
					gui.drawline(15+(j*16),24+(i*16),j*16,39+(i*16),"yellow");
				end;
			end;
		end;

		--text(x1+3,y1+3,hp);
		if (hp == 0) then
			box(x1,y1,x2,y2,"green");
		else
			box(x1,y1,x2,y2,"red");
		end;
		for i=0,2 do
			timmyshotexists = memory.readbyte(timmyshots+7+(i*8))
			x1 = memory.readbyte(timmyshots+1+(i*8));
			x2 = memory.readbyte(timmyshots+2+(i*8));
			y1 = memory.readbyte(timmyshots+3+(i*8)) + 24;
			y2 = memory.readbyte(timmyshots+4+(i*8)) + 24;
			if(timmyshotexists ~= 0xF8) then
				box(x1,y1,x2,y2,"green");
			end;
		end;
		for i=0,15 do
			stype = memory.readbyte(stuff+(i*16)) + 1;
			spritedisplay = bit.band(spritetype[stype],3);
			spritebox = bit.band(spritetype[stype],12)
			spriteflags = bit.band(spritetype[stype],240);
			spriteexists = memory.readbyte(stuff+8+(i*16));
			if (bit.band(spriteflags,0x10) == 0x10) then
				if (i >= 3) then
					spritebox = spritebox - 4;
					if (spritebox < 0) then
						spritebox = 12;
					end;
				end;
			end;
			if (bit.band(spriteflags,0x20) == 0x20) then
				if (i >= 3) then
					spritedisplay = 1;
				end;
			end;
			if ((stype == (36+1)) or (stype == (110+1)) or (stype == (138+1))) then	--Handle Lotus Gaurdian	(and Petunia of pain)
				if ((i==0) or (i==2)) then
					spritebox = 12
					x1 = memory.readbyte(stuff+2+(i*16));
					x2 = memory.readbyte(stuff+3+(i*16));
					y1 = memory.readbyte(stuff+4+(i*16)) + 24;
					y2 = memory.readbyte(stuff+5+(i*16)) + 24;
					box(x1,y1,x2,y2,"red");
				end;
			end;
			if ((stype == (114 + 1)) or (stype == (70 + 1))) then	--Handle OwlBot
				if ((i == 4) or (i == 0)) then
					spritedisplay = 0;
				end;
				if (i == 4) then
					x1 = memory.readbyte(stuff+2+(i*16));
					x2 = memory.readbyte(stuff+3+(i*16));
					y2 = memory.readbyte(stuff+5+(i*16)) + 24;
					line(x2+1,y2,x2+1,224,"yellow");
					line(x2,y2,x2,224,"yellow");
				end;
				if (i == 1) then
					spritedisplay = 0;
					spritebox = 12;
					box(0,40,88,200,"red")
				end;
			end;
			if ((stype == (116 + 1)) or (stype == (76 + 1))) then	--Handle Cleo
				if (i==0) then
					spritebox = 12
					x1 = memory.readbyte(stuff+2+(i*16));
					x2 = memory.readbyte(stuff+3+(i*16));
					y1 = memory.readbyte(stuff+4+(i*16)) + 24;
					y2 = memory.readbyte(stuff+5+(i*16)) + 24;
					box(x1,y1,x2,y2,"red");
				end;
				cleo = memory.readbyte(stuff + 15);
				if(cleo == 0) then
					text(128,8,"Red")
				end;
				if(cleo == 1) then
					text(128,8,"Blue")
				end;
				if(cleo == 2) then
					text(128,8,"Purple")
				end;
				if(cleo == 3) then
					text(128,8,"Pink")
				end;
				if(cleo == 4) then
					text(128,8,"Yellow")
				end;
				if(cleo == 5) then
					text(128,8,"Green")
				end;
			end;
			if (stype == (80+1)) then	--Handle nagaconda displaying specifically.
				nagaconda = memory.readbyte(stuff+10+(i*16))
				if (i == 1) then
					spritebox = 12;
				end;
				if((i >= 2)) then
					spritedisplay = 1;
				end;
				if (i == 5) then
					spritedisplay = 3;
				end;
				if (i == 12) then
					if (nagaconda == 3) then
						spritedisplay = 2;
					end;
				end;
			end;
			if (stype == (92+1)) then	--Handle Seahorse Turret.
				seahorsenext = {2,3,1,0,0}
				seahorsefire = memory.readbyte(stuff+13)
				seahorsetimer = memory.readbyte(stuff+12)
				seahorsebullets = memory.readbyte(stuff+14)
				j = 0;
				if(seahorsebullets == 0) then
					seahorsefire = 3;
				end;
				while((j < 4) and (seahorsefire < 4)) do
					hp = memory.readbyte(stuff+5+((seahorsenext[seahorsefire+1]+1)*16))
					--text(128,24+(8*seahorsefire),hp);
					if (memory.readbyte(stuff+5+((seahorsenext[seahorsefire+1]+1)*16))==0) then
						seahorsefire = seahorsefire - 1;
						if(seahorsefire < 0) then
							seahorsefire = 3;
						end;
					else
						break;
					end;
					j = j + 1;
				end;
				if(seahorsefire < 4) then	--Check that there is at least one seahorse turret still alive.
					spritezero = memory.readbyte(stuff)
					if (spritezero == 92) then
						text(128,8,seahorsebullets/4);
					end;
					--text(128,8,seahorsefire);
					--text(128,16,seahorsenext[seahorsefire+1]);
					if ((i >= 1) and (i <= 5)) then
						spritedisplay = 2;
					end;
					if ((i-1) == (seahorsenext[seahorsefire+1])) then
						spritebox = 4;
						x1 = memory.readbyte(stuff+2+(i*16));
						y1 = memory.readbyte(stuff+4+(i*16)) + 24;
						text(x1,y1+10,seahorsetimer);
					else
						spritebox = 0;
					end;
				end;
			end;
			if (stype == (96 + 1)) then	--Handle Amethyst Angel
				if(i == 0) then
					spritedisplay = 0
				end;
				if(i == 1) then
					spritebox = 12;
				end;
				if(i == 2) then
					x1 = memory.readbyte(stuff+2+(i*16));
					x2 = memory.readbyte(stuff+3+(i*16));
					y1 = memory.readbyte(stuff+4+(i*16)) + 24;
					y2 = memory.readbyte(stuff+5+(i*16)) + 24;
					box(x1,y1,x2,y2,"red");
					corner = memory.readbyte(stuff+12+(i*16));
					x1 = 0
					y1 = 0
					x2 = 60
					y2 = 17
					if (corner == 0) then
						box(x1+15,y1+84,x2+15,y2+84,"red");
					end;
					if (corner == 4) then
						box(x1+180,y1+84,x2+180,y2+84,"red");
					end;
					if (corner == 8) then
						box(x1+15,y1+148,x2+15,y2+148,"red");
					end;
					if (corner == 12) then
						box(x1+180,y1+148,x2+180,y2+148,"red");
						--box((11*16)+4,(8*16)+24-4,15*16,(9*16)+24-2,"red");
					end;
				end;
			end;
			if ((stype == (100 + 1)) or (stype == (126 + 1))) then	--Handle Zedd
				if(i == 0) then
					spritedisplay = 0
					ZeddState = memory.readbyte(stuff+7+(i*16));
					if ((ZeddState >= 32) and (ZeddState <= 50)) then
						--Freeze attack in middle of room
						text(90,0,"Freeze Attack");
						text(90,8,"Middle of Room");
						box(112,32,143,169,"green")
					end;
					if ((ZeddState >= 88) and (ZeddState <= 102)) then
						--Side to Side hopping
						text(90,0,"Side to Side");
						text(90,8,"hopping");
						box(0,70+24,255,121+24,"green")
					end;
					if ((ZeddState >= 2) and (ZeddState <= 20)) then
						--Teleporting
						spriteone = memory.readbyte(stuff+8+(14*16))
						spritetwo = memory.readbyte(stuff+8+(15*16))
						if ((spriteone == 248) and (spritetwo == 248)) then
							text(90,0,"Teleporting");
						else
							text(90,0,"Teleport Attack");
						end;
					end;
					if ((ZeddState >= 56) and (ZeddState <= 84)) then
						--Freeze Attack at end of room
						text(90,0,"Freeze Attack");
						text(90,8,"Side of Room");
						x1 = memory.readbyte(stuff+2+(14*16));
						x2 = memory.readbyte(stuff+3+(14*16));
						y1 = memory.readbyte(stuff+4+(14*16)) + 24;
						y2 = memory.readbyte(stuff+5+(14*16)) + 24;
						x3 = memory.readbyte(stuff+2+(15*16));
						x4 = memory.readbyte(stuff+3+(15*16));
						y3 = memory.readbyte(stuff+4+(15*16)) + 24;
						y4 = memory.readbyte(stuff+5+(15*16)) + 24;
						spriteone = memory.readbyte(stuff+8+(14*16))
						spritetwo = memory.readbyte(stuff+8+(15*16))
						if ( (y2-y3) < 32 ) then
							if ((spriteone < 248) and (spritetwo < 248)) then
								box(1,32,255,y3-1,"green");
							end;
						else
							box(1,y4+1,255,y1-1,"green");
						end;
					end;
					if (ZeddState == 22) then
						text(90,0,"Thinking");
					end;
				end;
				spritebox = 12
				x1 = memory.readbyte(stuff+2+(i*16));
				x2 = memory.readbyte(stuff+3+(i*16));
				y1 = memory.readbyte(stuff+4+(i*16)) + 24;
				y2 = memory.readbyte(stuff+5+(i*16)) + 24;
				box(x1,y1,x2,y2,"red");
				
			end;
			if ((stype == (106 + 1)) or (stype == (128 + 1))) then	--Handle TY-524A4ET
				if(i == 0) then
					tyrantalive = memory.readbyte(stuff+8+(1*16))
					spritedisplay = 0
					if (tyrantalive < 248) then
						TyrantState = memory.readbyte(stuff+7+(i*16));
						pauseemu = true
						if ((TyrantState >= 38) and (TyrantState <= 44)) then
							pauseemu = false
							missiles = memory.readbyte(stuff+13+(i*16)) + 1
							if(missiles == 256) then
								missiles = 0;
							end;
							text(90,0,"Missile Attack");
							text(90,8,string.format("Missiles Left:%d",missiles));
						end;
						if ((TyrantState >= 0) and (TyrantState <= 4)) then
							pauseemu = false
							text(90,0,"Thinking - Manipulate");
							text(90,8,"Luck Now");
						end;
						if ((TyrantState >= 6) and (TyrantState <= 18)) then
							pauseemu = false
							text(90,0,"Mass Laser");
							text(90,8,"Flood Attack");
						end;
						if ((TyrantState >= 30) and (TyrantState <= 36)) then
							pauseemu = false
							text(90,0,"Bullet Attack");
							bullets = memory.readbyte(stuff+13+(i*16));
							text(90,8,string.format("Bullets Left: %d",bullets));
						end;
						if ((TyrantState >= 46) and (TyrantState <= 54)) then
							pauseemu = false
							text(90,0,"Fireball Attack");
							if (TyrantState < 50) then
								bullets = memory.readbyte(stuff+13+(i*16));
								text(90,8,string.format("FireBalls Left: %d",bullets));
							else
								bullets = memory.readbyte(stuff+14+(i*16));
								text(90,8,string.format("FireBalls Left: %d",bullets));
							end;
						end;
						if ((TyrantState >= 20) and (TyrantState <= 28)) then
							pauseemu = false
							text(90,0,"Electric Spark Attack");
							bullets = memory.readbyte(stuff+13+(i*16));
							text(90,8,string.format("Sparks Left: %d",bullets));
							for j=12,15 do
								sparkexists = memory.readbyte(stuff+8+(j*16))
								if (sparkexists < 248) then
									sparktype = memory.readbyte(stuff+1+(j*16))
									x1 = memory.readbyte(stuff+2+(j*16));
									x2 = memory.readbyte(stuff+3+(j*16));
									y1 = memory.readbyte(stuff+4+(j*16)) + 24;
									y2 = memory.readbyte(stuff+5+(j*16)) + 24;
									if ((sparktype == 24)) then
										if (x1 == 202) then
											line(1,y2,255,y2,"yellow");
										else
											line(x2-2,32,x2-2,223,"yellow");
										end;
									end;
									if ((sparktype == 26) or (sparktype == 28))then
										line(x2-2,32,x2-2,223,"yellow");
									end;
									if ((sparktype == 30) or (sparktype == 32)) then
										line(1,y2,255,y2,"yellow");
									end;
								end;
							end;
						end;
						if (pauseemu) then
							FCEU.pause();
						end;
					end;
				end;
			end;
--End of Bosses


			if (stype == (4+1)) then	--Lethal Lemons and Life Stealin Limes
				if (i<3) then
					x1 = memory.readbyte(stuff+2+(i*16));
					x2 = memory.readbyte(stuff+3+(i*16));
					y1 = memory.readbyte(stuff+4+(i*16)) + 24;
					y2 = memory.readbyte(stuff+5+(i*16)) + 24;
					subtype = memory.readbyte(stuff+1+(i*16));
					if (subtype < 8) then
						line(x1+3,y1,x1+3,248,"yellow");
						line(x2+3,y1,x2+3,248,"yellow");
					else
						line(x1+3,y2,x1+3,40,"yellow");
						line(x2+3,y2,x2+3,40,"yellow");
					end;
				end;
			end;
			if (stype == (38+1)) then	--Sniper Snail
				x1 = memory.readbyte(stuff+2+(i*16));
				x2 = memory.readbyte(stuff+3+(i*16));
				y1 = memory.readbyte(stuff+4+(i*16)) + 24;
				y2 = memory.readbyte(stuff+5+(i*16)) + 24;
				line(1,y2,255,y2,"yellow");
				line(1,y1+1,255,y1+1,"yellow");
			end;
			if (stype == (60+1)) then	--Homing Drone
				x1 = memory.readbyte(stuff+2+(i*16));
				x2 = memory.readbyte(stuff+3+(i*16));
				y1 = memory.readbyte(stuff+4+(i*16)) + 24;
				y2 = memory.readbyte(stuff+5+(i*16)) + 24;
				sstate = memory.readbyte(stuff+1+(i*16));
				if (sstate == 2) then
					line(x2,y2,x2-(224-y2)/2,224,"yellow");
					line(x1,y2,x1+(224-y2)/2,224,"yellow");
					line(x2,y1,x2-((y1-32)/2),32,"yellow");
					line(x1,y1,x1+((y1-32)/2),32,"yellow");
				else
					line(1,y2,255,y2,"yellow");
				end;
			end;
			if (stype == (48+1)) then	--Handle the spawn points.
				spritebox = 12
				x1 = memory.readbyte(stuff+2+(i*16));
				x2 = memory.readbyte(stuff+3+(i*16));
				y1 = memory.readbyte(stuff+4+(i*16)) + 24;
				y2 = memory.readbyte(stuff+5+(i*16)) + 24;
				for j=3,15 do
					x3 = memory.readbyte(stuff+2+(j*16));
					x4 = memory.readbyte(stuff+3+(j*16));
					y3 = memory.readbyte(stuff+4+(j*16)) + 24;
					y4 = memory.readbyte(stuff+5+(j*16)) + 24;
					if ((x1 == x3) and (x2 == x4) and (y1 == y3) and (y2 == y4)) then
						timer = memory.readbyte(stuff+12+(j*16));
						text(x1+4,y1+4,timer);
						box(x1,y1,x1+16,y1+16,"yellow");
					end;
				end;
			end;	
			if (stype == (78+1)) then	-- spike traps (todo, get official name)
				x1 = memory.readbyte(stuff+2+(i*16));
				x2 = memory.readbyte(stuff+3+(i*16));
				y1 = memory.readbyte(stuff+4+(i*16)) + 24;
				y2 = memory.readbyte(stuff+5+(i*16)) + 24;
				subtype = memory.readbyte(stuff+11+(i*16));
				if (subtype == 0) then	--Horizontal
					line(1,y1,255,y1,"yellow");
					line(1,y2,255,y2,"yellow");
				else	--Vertical
					line(x1,32,x1,224,"yellow");
					line(x2,32,x2,224,"yellow");
				end;
			end;


			if((spriteexists < 248) or (i < 3)) then
				if ((spriteexists == 248) and (i < 3)) then
					spriteexists = memory.readbyte(stuff+7+(i*16));
				end;
				if((spriteexists < 248)) then
					x1 = memory.readbyte(stuff+2+(i*16));
					x2 = memory.readbyte(stuff+3+(i*16));
					y1 = memory.readbyte(stuff+4+(i*16)) + 24;
					y2 = memory.readbyte(stuff+5+(i*16)) + 24;
					-- if((stype ~= (30+1)) and (stype ~= (80+1)) and (stype ~= (82+1))) then
					if(bit.band(spriteflags,0x40) ~= 0x40) then
						if (x2 <= x1) then
							x2 = x1 + 15;
						end;
						if (y2 <= x1) then
							y2 = y1 + 15;
						end;
					end;
					
					if (enable_debug_code == 1) then
						text(1,8+(i*8),stype-1);	--Debug info on sprite identifier.
						text(26, 8+(i*8),spritedisplay)
						text(34, 8+(i*8),spritebox)
					end;
					
					if (stype == (22+1)) then --Blinking spike room, display the phase counters in a visible spot.
						phase = memory.readbyte(stuff+12+(i*16));
						text(128,8,phase);
						phase = memory.readbyte(stuff+13+(i*16));
						text(128,16,phase);
					end;
					
					
					if ((spritedisplay == 0) or (spritedisplay == 2)) then
						hp = memory.readbyte(stuff+6+(i*16));
						if (hp > 0) then
							text(x1+1,y1+1,hp);
						end;
					end;
					if ((spritedisplay == 0) or (spritedisplay == 3)) then
						if(stype == (74+1)) then	--Colormancers use 14/12 for their attack counters.
							phase = memory.readbyte(stuff+14+(i*16))
						else 
							phase = memory.readbyte(stuff+12+(i*16));
						end;
						if(phase > 0) then
							text(x1,y1+8,phase);
						end;
						if(phase == 0) then
							if(stype == (74+1)) then
								phase = memory.readbyte(stuff+12+(i*16))
							else 
								phase = memory.readbyte(stuff+13+(i*16));
							end;
							if(phase > 0) then
								text(x1,y1+8,phase);
							end;
						end;
					end;
					if(spritebox == 0) then
						box(x1,y1,x2,y2,"red");
					end;
					if(spritebox == 4) then
						box(x1,y1,x2,y2,"yellow");
					end;
					if(spritebox == 8) then
						box(x1,y1,x2,y2,"green");
					end;
				end;
			end;
		end;
	end;
	if ((enable_tas_info == 1) and (movie.active())) then
		if ((gameaction == 136) and (gameactiontwo == 28)) then
			if (memory.readbyte(10) == 78) then
				if (memory.readbyte(11) == 169) then
					if (memory.readbyte(12) == 160) then
						if (memory.readbyte(222) == 1) then
							FCEU.pause()
						end;
					end;
				end;
			end;
		end;
		if ((gameaction == 138) and (gameactiontwo == 16) and (framecounter > movie.length())) then
			FCEU.pause()
		end;
		if((framecounter >= info_1) and (framecounter <= (info_1+info_frames))) then
			text(32,32,"Battle Kid: Fortress of Peril");
			movie_frames = (movie.length() % frame_rate)
			movie_seconds = ((movie.length() % frames_per_minute) - movie_frames) / frame_rate
			movie_minutes = (movie.length() - (movie.length() % frames_per_minute)) / frames_per_minute
			text(32,40,string.format("%s in %02d:%02d.%02d by %s",info_1_string,movie_minutes,movie_seconds,(movie_frames*100)/60,info_1_author));
			text(32,48,string.format("%d Rerecords",movie.rerecordcount()));
		end;

		if((framecounter >= info_2) and (framecounter <= (info_2+info_frames))) then
			text(32,32,"This is a Tool Assisted Recording.");
			text(32,40,"For more Info, Go to TASVideos.org");
		end;
		if((framecounter >= movie.length()) and (framecounter <= (movie.length() + info_frames))) then
			text(8,200,"Movie Finished Playing");
		end;
	end;
end;

gui.register(battlekidloop)

while (true) do
	FCEU.frameadvance();
end;
Edit: Script now converted to gui.register form, shows more info about bosses, and draws trigger lines for certain enemies.
caitsith2
He/Him
Player (46)
Joined: 3/26/2004
Posts: 194
Revised my PETUNIAX run, saving 209 frames, using some tricks that I learned from Aglar's run. fm2
Site Admin, Skilled player (1234)
Joined: 4/17/2010
Posts: 11251
Location: RU
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Expert player (3555)
Joined: 11/9/2007
Posts: 375
Location: Varberg, Sweden
Sorry that I haven't posted this earlier but I initially had plans to improve it (I got lazy at the boss). However since the level doesn't have an ingame timer like the SGC level, nor is this anything to submit at this site I don't think I'll try to make it perfect. Feel free to try to improve it if you like (the boss can definitely be much better). http://dehacked.2y.net/microstorage.php/info/997492229/Battle%20Kid%20-%20Fortress%20of%20Perilpetuniax.fm2 Also, here's my take on the SGC level: http://www.youtube.com/watch?v=oOF9Deh5MnM
feos wrote:
Only Aglar can improve this now.
caitsith2
He/Him
Player (46)
Joined: 3/26/2004
Posts: 194
I know I am replying to this quite late, but that PETUNIAX run caused me to have to pick my jaw up off the floor a few times. Even the password entry was more optimal than my own.
Fortranm
He/Him
Editor, Experienced player (773)
Joined: 10/19/2013
Posts: 1108
I have combined the lua scripts for both games by caitsith2 and ported it to Bizhawk. http://tasvideos.org/userfiles/info/59827345600595517 It fully (hopefully) supports all 7 releases before Battle Kid v2.0: Battle Kid demo Battle Kid demo 2 Battle Kid v1.0 Battle Kid v1.1 Battle Kid 2 demo Battle Kid 2 new demo Battle Kid 2 v1.0 I have added partial support for Battle Kid v2.0 to the script. Most functions other than enemy information and player shot detection seem to work. I will really appreciate it if anyone can figure that part out. Edit:caitsith2 has added sprite display for BK v2.0: http://tasvideos.org/userfiles/info/60045844721779290