Post subject: Battle Kid 2: Mountain of Torment
caitsith2
He/Him
Player (47)
Joined: 3/26/2004
Posts: 194
Now that there is a demo out, we can start some work on at least some TAS planning. The demo is available at http://sivak.nintendoage.com/BK2.html I have already taken liberty of doing a hitbox script for the game, most of which originally was from the original Battle Kid lua script.
-- Battle Kid 2: Mountain of Torment 
-- Written by CaitSith2
-- Oct 8, 2013
-- Displays Hitboxes, Enemy HP, and various stats on screen

enable_info = 1
current_run_direction = 0

local function line(x1,y1,x2,y2,color)
		if (enable_info == 1) then
			gui.drawline(x1,y1+8,x2,y2+8,color)
		end
end
local function box(x1,y1,x2,y2,color)
	line(x1,y1,x1,y2,color)
	line(x1,y1,x2,y1,color)
	line(x2,y1,x2,y2,color)
	line(x1,y2,x2,y2,color)
end
local function selectivebox(x1,y1,x2,y2,color,left,right,top,bottom)
	if (left == 1) then
		line(x1,y1,x1,y2,color)
	end
	if (top == 1) then
		line(x1,y1,x2,y1,color)
	end
	if (right == 1) then
		line(x2,y1,x2,y2,color)
	end
	if (bottom == 1) then
		line(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
		if (enable_info == 1) then
			gui.text(x,y+8,str)
		end
	end
end
local function pixel(x,y,color)
	if (x > 0 and x < 255 and y > 0 and y < 240) then
		if (enable_info == 1) then
			gui.drawpixel(x,y+8,color)
		end
	end
end

enable_tas_info = 0
infinite_loop = 1
end_avi = 197000

function battlekidloop()
	local roomcollision = 0x0300

	framecounter = emu.framecount()
	local enable_extended_info = 1
	local enable_hud_info = 1
	local enable_debug_code = 0
	--local force_wall_grip	-- obsoleted by 3 line game genie code, YATVXN + ELYTUY + ELTVVY
	
	local info_frames = 300
	local info_1 = 1200
	local info_1_string = "Unfair 100%"
	local info_1_author = "CaitSith2"
	local info_2 = 1800
	local frame_rate = 60.098769685745869044
	local frames_per_minute = frame_rate * 60
	text(1,1,"")

	local stuff = 0x0400;
	local timmy = 0x0054;
	local timmyshots = 0x0598

	x1 = memory.readbyte(timmy)
	x2 = memory.readbyte(timmy+1)
	y1 = memory.readbyte(timmy+2) + 24
	y2 = memory.readbyte(timmy+3) + 24
	hp = memory.readbyte(0x82)
	maxhp = memory.readbyte(0x83)
        alive = memory.readbyte(0x6d)
	
	if((memory.readbyte(0x20) == 0) and (memory.readbyte(0x21) == 0)) then
		gameaction = 0
	else
		gameaction = 1
	end
	
	if ((enable_extended_info == 1) and (gameaction == 1)) then

		--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 = { 		0x0D, 0x02, 0x09, 0x0D, 0x0D,	0x0D, 0x0C, 0x01, 0x00, 0x0D, 
						0x0C, 0x02, 0x02, 0x09, 0x00,	0x00, 0x00, 0x00, 0x00, 0x00, 
						0x00, 0x00, 0x0E, 0x00, 0x0D,	0x00, 0x09, 0x0D, 0x02, 0x00,
						0x00, 0x00, 0x03, 0x00, 0x00,	0x0D, 0x00, 0x00, 0x00, 0x02,
						0x00, 0x00, 0x00, 0x09, 0x09,	0x09, 0x00, 0x00, 0x00, 0x00,

						0x03, 0x00, 0x00, 0x00, 0x00,	0x00, 0x00, 0x00, 0x00, 0x00,
						0x00, 0x00, 0x00, 0x07, 0x09,	0x00, 0x00, 0x00, 0x0D, 0x00,
						0x00, 0x00, 0x00, 0x00, 0x00,	0x00, 0x00, 0x00, 0x00, 0x0D,
						0x00, 0x00, 0x00, 0x00, 0x00,	0x00, 0x00, 0x00, 0x00, 0x00,
						0x00, 0x00, 0x09, 0x09, 0x00,	0x00, 0x00, 0x00, 0x00, 0x00,
		}

		--draw room collision zones

		for i=0,12 do
			toprow = 24
			bottomrow = 39
			if (i == 0) then
				toprow = 36
			end
			if (i == 12) then
				bottomrow = 31
			end
			for j=0,15 do
				top = 1
				bottom = 1
				left = 1
				right = 1
				blocktype = memory.readbyte(roomcollision + (i*16) + j)
				if(i ~= 0) then
					if (blocktype == memory.readbyte(roomcollision + ((i-1)*16) + j)) then
						top = 0
					end
				end
				if(i ~= 12) then
					if (blocktype == memory.readbyte(roomcollision + ((i+1)*16) + j)) then
						bottom = 0
					end
				end
				if(j ~= 0) then
					if (blocktype == memory.readbyte(roomcollision + (i*16) + (j-1))) then
						left = 0
					end
				end
				if(j ~= 15) then
					if (blocktype == memory.readbyte(roomcollision + (i*16) + (j+1))) then
						right = 0
					end
				end

				if(blocktype == 0x03) then		--Instant Kill Object
					selectivebox(j*16,toprow+(i*16),15+(j*16),bottomrow+(i*16),"red",left,right,top,bottom)
					line(j*16,toprow+(i*16),15+(j*16),bottomrow+(i*16),"red")
					line(15+(j*16),toprow+(i*16),j*16,bottomrow+(i*16),"red")
				end
				
				if(blocktype >= 0x10) then		--Solid Object
					selectivebox(j*16,toprow+(i*16),15+(j*16),bottomrow+(i*16),"cyan",left,right,top,bottom)
					if(blocktype == 0x11) then	--Ice
						line(j*16,toprow+(i*16),(j*16)+8,(toprow+(i*16))+8,"cyan")
						line((j*16)+8,toprow+(i*16),(j*16)+15,(toprow+(i*16))+8,"cyan")
					elseif(blocktype == 0x12) then	--conveyer belt <<<
						line(j*16,toprow+8+(i*16),15+(j*16),bottomrow+(i*16),"cyan")
						line(15+(j*16),toprow+(i*16),j*16,bottomrow-8+(i*16),"cyan")
					elseif(blocktype == 0x13) then	--conveyer belt >>>
						line(j*16,toprow+(i*16),15+(j*16),bottomrow-8+(i*16),"cyan")
						line(15+(j*16),toprow+8+(i*16),j*16,bottomrow+(i*16),"cyan")
					elseif(blocktype == 0x14) then	--Wallgrip objects
						line(j*16,toprow+(i*16),15+(j*16),bottomrow+(i*16),"cyan")
						line(15+(j*16),toprow+(i*16),j*16,bottomrow+(i*16),"cyan")
					elseif(blocktype == 0x15) then	--Rune spectre destroyable blocks
						line((j*16)+8,toprow+(i*16),(j*16)+8,bottomrow+(i*16),"cyan")
						line(j*16,toprow+(i*16)+8,(j*16)+15,toprow+(i*16)+8,"cyan")
						line((j*16)+8,toprow+(i*16),(j*16)+15,(toprow+(i*16))+8,"cyan")
						line((j*16)+8,bottomrow+(i*16),(j*16)+15,(toprow+(i*16))+8,"cyan")
						line((j*16)+8,toprow+(i*16),j*16,(toprow+(i*16))+8,"cyan")
						line((j*16)+8,bottomrow+(i*16),j*16,(toprow+(i*16))+8,"cyan")
					end
				end
			end
		end

		--text(x1+3,y1+3,hp)
		--text(x1,y1-8,string.format("%03d,%03d",x1,y1))
		if (hp > 0) then
			if (alive == 0) then
				box(x1,y1,x2,y2,"green")
			else
				box(x1,y1,x2,y2,"red")
				line(x1,y1,x2,y2,"red")
				line(x1,y2,x2,y1,"red")
			end
		else
			box(x1,y1,x2,y2,"red")
			if (alive ~= 0) then
				line(x1,y1,x2,y2,"red")
				line(x1,y2,x2,y1,"red")
			end
		end
		for i=0,2 do
			timmyshotexists = memory.readbyte(timmyshots+7+(i*8))
			if(timmyshotexists ~= 0xF8) then
				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
				box(x1,y1,x2,y2,"green")
			end
		end
		for i=0,15 do
			stype = memory.readbyte(stuff+(i*16)) / 2
			if(spritetype[stype+1] == nil) then
				break	--Invalid sprite type.  Game has very likely crashed
				--As such, there is no point in running the rest of this script section.
			end
			spritedisplay = bit.band(spritetype[stype+1],3)
			spritebox = bit.band(spritetype[stype+1],12)
			spriteflags = bit.band(spritetype[stype+1],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

------------------------------ COMMON VARIABLES ---------------------------------------------------
			phase = memory.readbyte(stuff+1+(i*16))
			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

			
------------------------------ BOSS HANDLERS ------------------------------------------------------
			if (stype == 18) then	--Boss/minigame/locked door spawner
				spawntype = memory.readbyte(stuff+11+(i*16))
				if(spawntype == 0x42) then
					timer = memory.readbyte(stuff+13+(i*16))
					text(x1,y1+8,timer)
					break;
				end
			end

			if (stype == 55) then	--Handle Night Mission Boss
				if(i == 1) then
					spritedisplay = 0
					ZeddState = memory.readbyte(stuff+11+(i*16))
					if ((ZeddState == 0) or (ZeddState <= 6)) then
						text(90,32,"Tossing Electric Sparks")
					elseif ((ZeddState >= 8) and (ZeddState <= 10)) then
						text(90,32,"Last Spark")
					elseif ((ZeddState >= 12) and (ZeddState <= 14)) then
						text(90,32,"Charging up")
					elseif ((ZeddState >= 16) and (ZeddState <= 20)) then
						text(90,32,"Dashing Across Room")
					elseif ((ZeddState >= 22) and (ZeddState <= 26)) then
						text(90,32,"Staying in one spot")
					end
				end
				spritebox = 12
				box(x1,y1,x2,y2,"red")
				
			end

			if ((stype == 42) or (stype == 83)) then	--Hantairei'mos
				spritebox = 12
				box(x1,y1,x2,y2,"red")
				if(i==0) then
					spritedisplay = 3
				end
			end
			
			if ((stype == 53) or (stype == 85)) then	--Misha
				spritebox = 12
				box(x1,y1,x2,y2,"red")
				--if(i==0) then
				--	spritedisplay = 3
				--end
			end

			if ((stype == 54) or (stype == 86)) then	--Helga Kraftie, Power station version
				spritebox = 12
				box(x1,y1,x2,y2,"red")
			end

			if ((stype == 56) or (stype == 87)) then	--Doppleganger either being constructed or dying
				if (i == 0) then	--Doppleganger constructor phase
					hp = memory.readbyte(stuff+6+(i*16))
					if ((hp == 13) or (hp == 12)) then
						text(24,72,"One doppleganger clone, no abilities")
					elseif (hp == 11) then
						text(24,72,"Two doppleganger clones, no abilities")
					elseif (hp == 10) then
						text(24,72,"Three doppleganger clones, Jump")
					elseif (hp == 9) then
						text(24,72,"Five doppleganger clones, Jump")
					elseif (hp == 8) then
						text(24,72,"Six doppleganger clones, Jump")
					elseif (hp == 7) then
						text(24,72,"Five doppleganger clones, Jump, Feather")
					elseif (hp == 6) then
						text(24,72,"Six doppleganger clones, Jump, Feather")
					elseif (hp == 5) then
						text(24,72,"Three doppleganger clones, Jump lust")
					elseif (hp == 4) then
						text(24,72,"Six doppleganger clones, Jump lust")
					elseif (hp == 3) then
						text(24,72,"Three doppleganger clones, Double Jump")
					elseif (hp == 2) then
						text(24,72,"Two doppleganger clones, Double Jump, 5HP")
					elseif (hp == 1) then
						text(24,72,"Two doppleganger clones, Attack shots, 5HP")
					elseif (hp == 0) then
						text(24,64,"One doppleganger clone")
						text(24,72,"Attack Shots, 5HP, Jump")
					else
						text(24,72,"The TIMMY :)")
					end
				end
				spritebox = 12
				spritedisplay = 3
				if (phase < 12) then
					box(x1,y1,x2,y2,"yellow")
				elseif (phase == 12) then
					box(x1,y1,x2,y2,"red")
				elseif (phase == 34) then
					box(x1,y1,x2,y2,"red")
					spritedisplay = 1
				else
					spritedisplay = 1
				end
			end;
			
			if (stype == 57) then	--Doppleganger in action
				spritebox = 0
				spritedisplay = 2
			end;

			if (stype == 58) then	--The Timmy :)
				spritebox = 12
				if (i ~= 1) then
					spritedisplay = 1
				end
				box(x1,y1,x2,y2,"red")
			end;

			if (stype == 69) then	--Doppleganger exploding
				spritebox = 12
				spritedisplay = 1
			end

			if (stype == 68) then
				spritebox = 12
				if (i==0) then
					stype = memory.readbyte(stuff+0+16)/2
					ZeddState = memory.readbyte(stuff+11+(16))
					if ((stype == 19) or (stype == 80)) then	--Handle Golem Boss
						spritedisplay = 0
						if ((ZeddState == 18) or (ZeddState <= 2)) then
							text(90,32,"Manipulate Luck Now")
						elseif ((ZeddState >= 4) and (ZeddState <= 6)) then
							text(90,32,"Group of 3 Balls")
						elseif ((ZeddState >= 8) and (ZeddState <= 10)) then
							text(90,32,"Targeting Blue Balls")
						elseif (ZeddState == 12) then
							text(90,32,"End of Blue Balls")
						elseif ((ZeddState >= 14) and (ZeddState <= 16)) then
							text(90,32,"Yellow Goop")
						end
						spritebox = 12
						box(x1,y1,x2,y2,"red")
					end
					if ((stype == 31) or (stype == 81)) then		--Verdigrime
						
						if (ZeddState == 0) then
							text(90,32,"Waiting phase - Open fire")
						elseif (ZeddState == 2) then
							text(90,32,"End of Waiting phase")
							text(90,40,"Manipulate Luck during Attacks")
						elseif ((ZeddState >= 4) and (ZeddState <= 8)) then
							text(90,32,"Targeted Eye Slime Attack")
						elseif ((ZeddState >= 10) and (ZeddState <= 16)) then
							text(90,32,"Mouth Slime spray attack")
						elseif ((ZeddState >= 18) and (ZeddState <= 22)) then
							text(90,32,"Ceiling Slime Attack")
						end
						box(x1,y1,x2,0x8F+24,"red")
					end
					if ((stype == 34) or (stype == 82)) then	--Ivan 2
						if (ZeddState <= 4) then
							text(90,32,"Making Ice column")
						elseif ((ZeddState >= 6) and (ZeddState <= 14)) then
							text(90,32,"Shooting Ice Ghost")
						elseif((ZeddState >= 16) and (ZeddState <= 30)) then
							text(90,32,"Shooting Icicles")
						elseif((ZeddState >= 32) and (ZeddState <= 44)) then
							text(90,32,"Shooting Ice bullet spread")
						end
						box(x1,y1,x2,0xAF+24,"red")
					end
				else
					box(x1,y1,x2,y2,"red")
				end
			end

			if (stype == 84) then	--Lobstor bot
				spritebox = 12
				box(x1,y1,x2,y2,"red")
				for j=0,15 do
					stype = memory.readbyte(stuff+(j*16))
					if (stype == 68) then
						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
						box(x1,y1,x2,y2,"red")
					end
				end
			end

			if (stype == 70) then	--Muckswimmer
				spritebox = 12
				if(phase ~= 4) then
					spritedisplay = 1
				else
					box(x1,y1,x2,y2,"red")
				end
			end

			if (stype == 96) then	--Pinkface
				dirchange = memory.readbyte(0x6BC) 
				current_suit = memory.readbyte(0x6E5)
				spritebox = 12
				box(x1,y1,x2,y2,"red")
				if(current_suit == 0) then
					text(16,32,"Current suit is Hearts")
				elseif (current_suit == 1) then
					text(16,32,"Current suit is Diamonds")
				elseif (current_suit == 2) then
					text(16,32,"Current suit is Spades")
				else
					text(16,32,"Current suit is Clubs")
				end
				text(16,40,string.format("Direction change in %d suit changes",dirchange))

				for j=0,15 do
					stype = memory.readbyte(stuff+(j*16))
					if (stype == 68) then
						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
						timer1 = memory.readbyte(stuff+13+(j*16))
						timer2 = memory.readbyte(stuff+14+(j*16))
						if(current_suit == 0) then
							if(timer2 > 0) then
								box(x1,y1,x2,y2,"yellow")
								text(x1,y1+8,timer2)
							else
								box(x1,y1,x2,y2,"red")
								text(x1,y1+8,timer1)
							end
						elseif (current_suit == 3) then
							box(x1,y1,x2,y2,"red")
							line(0,y1,255,y1,"yellow")
							line(0,y2,255,y2,"yellow")
						end
					end
				end
			end


------------------------------ END OF BOSS HANDLERS -----------------------------------------------


------------------------------ SPRITE HANDLERS ----------------------------------------------------
			if (stype == 3) then	--Dying sprite
				spritebox = 12
				spritedisplay = 1
			end

			if (stype == 4) then	--Shot Cannons
				timeleft = memory.readbyte(stuff+14+(i*16))
				for j=0,7 do
					stype2 = memory.readbyte(stuff+0+(j*16)) / 2
					x2 = memory.readbyte(stuff+2+(j*16))
					y2 = memory.readbyte(stuff+4+(j*16)) + 24
					timeleft2 = memory.readbyte(stuff+14+(j*16))
					if((x1 == x2) and (y1 == y2) and (timeleft2 < timeleft) and (stype2 == 4)) then
						if(j < i) then
							break
						end
						timeleft = timeleft2
					end
					if (j==7) then
						text(x1,y1+8,timeleft)
						box(x1,y1,x1+7,y1+7,"yellow")
					end
				end
			end

			if ((stype == 5) or  (stype == 6) or (stype == 9)) then	--shots
				if ((x2 ~=0) or ((y2-24) ~= 0)) then
					box(x1,y1,x2,y2,"red")
				end;
			end

			if (stype == 12) then	--Eye Sniper
				timeleft = memory.readbyte(stuff+14+(i*16))
				text(x1,y1+8,timeleft)
			end

			if (stype == 14) then	--Lock Blocks
				spritebox = 12
				spritedisplay = 1
				keyrequired = memory.readbyte(stuff+6+(i*16))
				keys = memory.readbyte(0x89)
				if(bit.band(keys,keyrequired) == keyrequired) then
					box(x1,y1,x2,y2,"red")
				end
			end

			if (stype == 15) then	--Pickaxe Chuck
				spritedisplay = 2
				timer = memory.readbyte(stuff+13+(i*16))
				if(phase == 2) then
					text(x1,y1+8,timer+30)
				elseif (phase == 4) then
					text(x1,y1+8,timer)
				elseif (phase == 6) then
					text(x1,y1+8,timer+86)
				elseif (phase == 8) then
					text(x1,y1+8,timer+70)
				end
			end

			if (stype == 16) then	--Boss Door
				spritedisplay = 1
			end

			if (stype == 21) then	--Sqlungy
				spritedisplay = 2
				updown = memory.readbyte(stuff+1+(i*16))
				if (updown < 8) then
					line(x1+6,y1,x1+6,0,"yellow")
					--line(x1+7,y1,x1+7,0,"yellow")
					--line(x1+8,y1,x1+8,0,"yellow")
					line(x1+9,y1,x1+9,0,"yellow")
				else
					line(x2-6,y2,x2-6,240,"yellow")
					--line(x2-7,y2,x2-7,240,"yellow")
					--line(x2-8,y2,x2-8,240,"yellow")
					line(x2-9,y2,x2-9,240,"yellow")
				end
			end

			if (stype == 22) then	--shots
				if (i<8) then
					timeleft = memory.readbyte(stuff+13+(i*16))
					for j=0,7 do
						stype2 = memory.readbyte(stuff+0+(j*16))/2
						timeleft2 = memory.readbyte(stuff+13+(j*16))
						x3 = memory.readbyte(stuff+2+(j*16))
						y3 = memory.readbyte(stuff+4+(j*16)) + 24
						if((x1 == x3) and (y1 == y3) and (timeleft2 < timeleft) and (stype2 == 22)) then
							if(j<i) then
								break
							end
							timeleft = timeleft2
						end
						if(j==7) then
							box(x1,y1,x1+15,y1+15,"yellow")
							text(x1,y1+8,timeleft)
						end
					end
				else
					box(x1,y1,x2,y2,"red")
				end
			end

			if (stype == 24) then	--Turbine
				type = memory.readbyte(stuff+1+(i*16))
				if (type < 9) then
					box(x1,y1,x2,y2,"red")
					line(x1,y1,x2,y2,"red")
					line(x1,y2,x2,y1,"red")
					timeleft = memory.readbyte(stuff+13+(i*16))
					if (type == 8) then
						text(x1,y1+8,timeleft+90)
					elseif (type == 2) then
						text(x1,y1+8,timeleft+30)
					else
						text(x1,y1+8,timeleft)
					end
				end
			end
			if (stype == 25) then	--megaman style disappearing blocks
				spritedisplay = 1
				spritebox = 12
				type = memory.readbyte(stuff+12+(i*16))
				timer = memory.readbyte(stuff+13+(i*16))
				if(phase < 8) then
					box(x1,y1,x2,y2,"yellow")
					if(type == 17) then	--Ice
						line(x1,y1,x1+8,y1+8,"yellow")
						line(x1+8,y1,x2,y1+8,"yellow")
					elseif(type == 18) then	--conveyer belt
						line(x2,y1,x1,y1+8,"yellow")
						line(x2,y2,x1,y1+8,"yellow")
					elseif(type == 19) then	--conveyer belt
						line(x1,y1,x2,y1+8,"yellow")
						line(x1,y2,x2,y1+8,"yellow")
					elseif(type == 20) then	--Wallgrip objects
						line(x1,y1,x2,y2,"yellow")
						line(x1,y2,x2,y1,"yellow")
					end
				end
				text(x1,y2,timer)
			end

			if (stype == 26) then	--Timmy's breath bubbles.
				spritebox = 12
			end

			if (stype == 27) then	--Immortal Jelly
				hp = memory.readbyte(stuff+6+(i*16))
				timer = memory.readbyte(stuff+13+(i*16))
				if(phase <= 8) then
					box(x1,y1,x2,y2,"red")
					text(x1,y1,hp)
				elseif(phase == 10) then
					text(x1,y1+8,timer+147)
				elseif(phase == 12) then
					text(x1,y1+8,timer+27)
				elseif(phase == 14) then
					text(x1,y1+8,((hp-1)*3)+timer)
				end
				
			end

			if (stype == 28) then		--Squeex
				direction = memory.readbyte(stuff+11+(i*16))
				timer = memory.readbyte(stuff+13+(i*16))
				shots = memory.readbyte(stuff+14+(i*16))
				if(phase == 4) then
					text(x1,y1+8,39)
				elseif(phase >= 6) then
					if(shots == 3) then
						timer = timer + 7 + 7 + 21
					end
					if(shots == 2) then
						timer = timer + 7 + 21
					end
					if (shots == 1) then
						timer = timer + 21
					end
					text(x1,y1+8,timer)
				end
				if(direction == 1) then
					line(x1,y1+7,255,y1+7,"yellow")
					line(x1,y2-1,255,y2-1,"yellow")
				else
					line(0,y1+7,x2,y1+7,"yellow")
					line(0,y2-1,x2,y2-1,"yellow")
				end
			end

			if(stype == 29) then	--spirit conjurer/stalking spirit
				spritedisplay = 1
				hp = memory.readbyte(stuff+6+(i*16))
				timer1 = memory.readbyte(stuff+13+(i*16))
				timer2 = memory.readbyte(stuff+14+(i*16))
				if(phase == 2) then
					text(x1,y1+8,timer1+36)
				elseif(phase == 4) then
					text(x1,y1+8,((timer1-1)+((timer2-1)*6))+1)
				end
				if(phase <= 6) then
					text(x1,y1,hp)
				end
			end

			if(stype == 30) then	--Orbit Drone
				spritedisplay = 1
			end

			if(stype == 32) then	--Bone spears
				spritebox = 12
				spritedisplay = 1
				timer = memory.readbyte(stuff+13+(i*16))
				if(phase < 16) then
					text(x1,y2,timer)
				else
					text(x1,y1-8,timer)
				end
				if((phase == 2) or (phase == 16)) then
					box(x1,y1,x2,y2,"yellow")
				else
					box(x1,y1,x2,y2,"red")
				end
			end;	

			if (stype == 35) then	--Eletric Barriers
				count1 = memory.readbyte(stuff+11+(i*16))
				count2 = memory.readbyte(stuff+13+(i*16))
				if(count1 > 0) then
					text(x1,y1+8,((count1-1)*10)+count2)
				else
					box(x1,y1,x2,y2,"red")
				end
			end

			if (stype == 37) then	--Voltsphere
				spritebox = 12
				spritedisplay = 2
				box(x1,y1,x2,y2,"red")
				timer1 = memory.readbyte(stuff+13+(i*16))
				timer2 = memory.readbyte(stuff+11+(i*16))
				timer3 = 3 - ((phase / 2) - 1)
				if(phase <= 8) then
					text(x1,y1+8,((timer2-1)*4)+timer3+21)
				elseif (phase == 10) then
					text(x1,y1+8,timer1)
				elseif (phase == 12) then
					text(x1,y1+8,timer1+30+48+21)
				elseif (phase == 14) then
					text(x1,y1+8,timer1+48+21)
				elseif (phase == 16) then
					text(x1,y1+8,timer1+48+21)
				end
			end

			if (stype == 38) then	--To'skuuth
				spritebox = 12
				spritedisplay = 2
				count = memory.readbyte(stuff+13+(i*16))
				if((phase >= 8) and (phase <= 14)) then
					box(x1,y1,x2,y2,"red")
				else
					box(x1,y1,x2,y2,"yellow")
				end; 
				local countoffset = { 28, count, count - 1, 36, 21, 1, 0, count + 70, count + 69, 70, 69 }
				text(x1,y1+8,count+countoffset[phase/2])
			end

			if (stype == 39) then	--Rune Spectre
				count1 = memory.readbyte(stuff+15+(i*16))
				count2 = memory.readbyte(stuff+13+(i*16))
				x2 = memory.readbyte(timmy)
				y2 = memory.readbyte(timmy+2) + 24
				if (phase == 10) then
					line(x1+8,y1,x2+7,y2+7,"green")
				elseif ((phase == 12) or (phase == 14)) then
					line(x1+8,y1,x2+7,y2+7,"red")
				else
					line(x1+8,y1,x2+7,y2+7,"yellow")
				end
				if(phase <= 8) then
					if((phase == 2) or (phase == 6)) then
						offset = 1
					else
						offset = 0
					end
					text(x1,y1+8,((count1-1)*4)+count2+offset)
				elseif (phase == 10) then
					text(x1,y1+8,count2)
				end
			end

			if (stype == 41) then	--Timed Sprite spawner
				spritebox = 12
				timer1 = memory.readbyte(stuff+12+(i*16))
				timer2 = memory.readbyte(stuff+13+(i*16))
				if(phase < 6) then
					x1 = memory.readbyte(stuff+2+((i+1)*16))
					y1 = memory.readbyte(stuff+4+((i+1)*16)) + 24
					box(x1,y1,x1+15,y1+15,"yellow")
					text(x1,y1,((timer1-1)*60)+timer2)
				end
			end
			
			if (stype == 47) then	--Yeti
				spritebox = 12
				box(x1,y1,x2,y2,"red")
				if(phase == 14) then
					spritedisplay = 2
				end
			end

			if (stype == 50) then	--Spiked Crusher
				spritebox = 12
				type = memory.readbyte(stuff+15+(i*16))
				x3 = memory.readbyte(stuff+11+(i*16))
				y3 = memory.readbyte(stuff+12+(i*16)) + 24
				line(x3,y3,x3+15,y3+15,"yellow")
				line(x3+15,y3,x3,y3+15,"yellow")
				if ((type == 2) or (type == 6)) then
					line(x3,36,x3,y3,"yellow")
					line(x3,y3+15,x3,240,"yellow")
					line(x3+15,36,x3+15,y3,"yellow")
					line(x3+15,y3+15,x3+15,240,"yellow")
				end
				if ((type == 4) or (type == 6)) then
					line(0,y3,x3,y3,"yellow")
					line(x3+15,y3,256,y3,"yellow")
					line(0,y3+15,x3,y3+15,"yellow")
					line(x3+15,y3+15,256,y3+15,"yellow")
				end
				box(x1,y1,x2,y2,"red")
			end

			if (stype == 51) then	--Binary Zap minigame
				spritebox = 12
				if(i > 0) then
					local bdigits = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }
					if(bit.band(memory.readbyte(stuff+12),bdigits[i]) == bdigits[i]) then
						box(x1,0x50+24,x2,0xA0+24,"yellow")
						for j=0,4 do
							line(x1,0x50+24+(j*16),x2,0x60+24+(j*16),"yellow")
							line(x2,0x50+24+(j*16),x1,0x60+24+(j*16),"yellow")
						end
					end
					box(x1,y1,x2,y2,"red")
				end
			end

			if (stype == 64) then	--Portals
				spritebox = 12
				dx = memory.readbyte(stuff+11+(i*16))
				dy = memory.readbyte(stuff+12+(i*16))
				if((dx == 0x19) and (dy == 0)) then
					box(x1,y1,x2,y2,"red");	--This is the land of pointy things, at 25,00. don't want to go here :)
				else
					box(x1,y1,x2,y2,"green")
				end
			end

			if (stype == 65) then	--Simon says minigame
				spritebox = 12
				spritedisplay = 1
				if(i>=3) then
					correct_corner_offset = memory.readbyte(stuff+12+(2*16))
					corner = memory.readbyte(stuff+11+(i*16))
					if(corner == memory.readbyte(0x708 + correct_corner_offset)) then
						box(x1,y1,x2,y2,"green")
					else
						box(x1,y1,x2,y2,"red")
					end
				end
			end

			if (stype == 72) then	--Icicle
				spritedisplay = 1
				spritebox = 12
				box(x1,y1,x2,y2,"red")
				direction = memory.readbyte(stuff+12+(i*16))
				if(bit.band(direction,0xC0) == 0x00) then
					line(x1,y2,x1,240,"yellow")
					line(x2,y2,x2,240,"yellow")
				elseif(bit.band(direction,0xC0) == 0x40) then
					line(x2,y1,256,y1,"yellow")
					line(x2,y2,256,y2,"yellow")
				elseif(bit.band(direction,0xC0) == 0x80) then
					line(x1,y1,x1,40,"yellow")
					line(x2,y1,x2,40,"yellow")
				elseif(bit.band(direction,0xC0) == 0xC0) then
					line(x1,y1,0,y1,"yellow")
					line(x2,y2,0,y2,"yellow")
				end
			end

			if (stype == 98) then	-- This is only present in the Demo version.  In the full version, this sprite type
						-- does absolutely nothing, as it never leaves phase 0.
				if(phase > 0) then
					text(8,200,"Next room to the left will end this demo")
				end
			end

------------------------------ END OF SPRITE HANDLERS ----------------------------------------------------

			if((spriteexists < 248) or (i < 8)) then
				if ((spriteexists == 248) and (i < 8)) 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 ~= 15) and (stype ~= 40) and (stype ~= 41)) 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
						if (stype>0) then
							text(1,8+(i*8),stype);	--Debug info on sprite identifier.
							text(26, 8+(i*8),spritedisplay)
							text(34, 8+(i*8),spritebox)
						end
					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
						timer = memory.readbyte(stuff+13+(i*16))
						if(timer > 0) then
							text(x1,y1+8,timer)
						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
					--if((enable_debug_code == 1) and (spritebox == 12)) then
					--	box(x1,y1,x2,y2,"red")
					--	box(x1+1,y1+1,x2-1,y2-1,"green")
					--end
				end
			end
		end
	end

	if ((enable_hud_info == 1) and (gameaction == 1)) then
		xloc = memory.readbyte(0x31)
		yloc = memory.readbyte(0x30) / 2
		text(210,0,string.format(" %02d,%02d ",xloc,yloc))

		jumpsleft = memory.readbyte(0x78)
		jumpstotal = memory.readbyte(0x77)
		
		shotsleft=3
		for i=0,2 do
			timmyshotexists = memory.readbyte(timmyshots+7+(i*8))
			if (timmyshotexists ~= 0xF8) then
				shotsleft = shotsleft - 1
			end
		end
			
		text(52,0,string.format("Shots:%d/3",shotsleft))
		text(32,8,string.format("/%X Jumps:%d/%d",maxhp,jumpsleft,jumpstotal))

		acceleration = memory.readbyte(0x59)
		runspeed = memory.readbyte(0x58)
		if(acceleration > 127) then
			acceleration = bit.band(bit.bnot(acceleration),0xFF) + 1
			text(80,24,string.format("Fall Rate = -%d pixels/frame",acceleration))
		else
			text(80,24,string.format("Fall Rate = %d pixels/frame",acceleration))
		end
		if((runspeed > 0) and (runspeed <= 127)) then
			current_run_direction = 0
		elseif (runspeed > 127) then
			runspeed = bit.band(bit.bnot(runspeed),0xFF) + 1
			current_run_direction = 1
		end
		if(current_run_direction == 1) then
			text(80,32,string.format("Run left = %d pixels/frame",runspeed))
		else
			text(80,32,string.format("Run right = %d pixels/frame",runspeed))
		end

		timer_msec = memory.readbyte(0xC2)
		timer_sec = memory.readbyte(0xC3)
		timer_min = memory.readbyte(0xC4)
		timer_hour = memory.readbyte(0xC5)

		local msec_timer = { 0,1,3,5,6,8,
				   10,11,13,15,16,18,
				   20,21,23,25,26,28,
				   30,31,33,35,36,38,
				   40,41,43,45,46,48,
				   50,51,53,55,56,58,
				   60,61,63,65,66,68,
				   70,71,73,75,76,78,
				   80,81,83,85,86,88,
				   90,91,93,95,96,98,
				   99,}

		
		if (enable_tas_info ~= 1) then	--No point in showing this in a TAS, as we won't be dying. :)
			deaths = memory.readbyte(0x72) + (memory.readbyte(0x73) * 256)
			text(108,0,string.format("DEATHS: %d",deaths))
		end
		if ((timer_msec + timer_sec + timer_min + timer_hour) > 0) then
			text(108,8,string.format("%.2d:%.2d:%.2d:%.2d",timer_hour,59-timer_min,59-timer_sec,msec_timer[60-timer_msec+1]))
		end
	end

	if ((enable_tas_info == 1) and (movie.active())) then
		if(framecounter >= end_avi) then
			FCEU.pause()
		end
		if((framecounter >= info_1) and (framecounter <= (info_1+info_frames))) then
			text(32,32,"Battle Kid 2: Mountain of Torment")
			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)

if(movie.active() and (enable_tas_info == 1)) then
	movie.playbeginning()
end

while (true) do
	FCEU.frameadvance()
end;
--- Edit: Updated the script, to reflect the full version of the game.
caitsith2
He/Him
Player (47)
Joined: 3/26/2004
Posts: 194
Did a TAS of the demo. Can't wait to get my hands on the full game.
Expert player (3645)
Joined: 11/9/2007
Posts: 375
Location: Varberg, Sweden
You beat me to it! We apparently made these TASes at the same time, I just went for lunch before posting it here: http://dehacked.2y.net/microstorage.php/info/669574632/BattleKid2-demo.fm2 You're clearly improving as a TASer. I'm not as much ahead of you as the input file shows, because I didn't take the portals and also ended the input earlier.
feos wrote:
Only Aglar can improve this now.
Editor, Skilled player (1441)
Joined: 3/31/2010
Posts: 2113
Woo, I'm really excited for this. Great WIPs by the two of you so far, I'm really looking forward to the full game and its eventual TAS. Please, do keep it up
caitsith2
He/Him
Player (47)
Joined: 3/26/2004
Posts: 194
Because of the Engine demo, I was able to test out Feather physics again. Completely identical to Battle Kid 1, except that becauase the controls respond even quicker, you can slow your fall even more, from 2/3 pixel/frame, down to 1/2 pixel/frame, with the pattern of up/release/up/release. (formally, up/release/up/release was basically up/up/up/up in Battle Kid 1.) Also, Water/Sludge Fall speeds are completely identical, feather/no feather.
caitsith2
He/Him
Player (47)
Joined: 3/26/2004
Posts: 194
TASed the Engine Demo mode of this game, effectively abusing the underwater feather physics again, and bypassing a wall jump that most players would actually have to use, in the feather room. The only thing left, is to do an Easy mode TAS, in which you CAN take damage to save time.
caitsith2
He/Him
Player (47)
Joined: 3/26/2004
Posts: 194
New version of the battle kid 2 demo up, and it goes even farther than the original demo, and as such, needs to be TASed. Heck, because of the way it was coded, it can even be directly transitioned into the full game, when it comes out, and its rom dump made.
Site Admin, Skilled player (1255)
Joined: 4/17/2010
Posts: 11495
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
JMan is streaming a full game from the console (Sivak appears in chat for the second part): http://twitch.tv/megaultrajman/b/354093162 http://twitch.tv/megaultrajman/b/354381599 EDIT: Finished watching it myself. Sivak even calls JMan vie Skype and they talk after the 7 hour mark of the 2nd vid. Sivak now is in Japan. Their talk is pretty long :)
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.
Joined: 1/17/2013
Posts: 1
Hi That is great, That is awesome information, i was also looking for this. how can i get the New version of the battle kid 2 demo Regards
Michaeljee
caitsith2
He/Him
Player (47)
Joined: 3/26/2004
Posts: 194
The new demo is available here. Played through it. WIP Once a rom dump is made, I am likely to continue the TAS from there, assuming no desyncs.
caitsith2
He/Him
Player (47)
Joined: 3/26/2004
Posts: 194
TAS successfully resumed and completed. It is available here. I own a Limited Edition cart, which I made a personal rom dump of. I will NOT provide this rom to anybody, so don't bother asking. The unlimited retail version is exactly the same, except for what it says near the bottom of the title screen. Some route optimizations I can make, for my next run through. Don't get Portal B, or the Cave Orrexium at first possible opportunity. Portal B will be used later to go to Portal E, and the Cave Orrexium will be collected on the way to the Aquatic base. Also, gotta figure out how to luck manipulate Verdigrime, to not do its slime from mouth attack, as that significantly slows down the fight. For those that do dump their own rom, Line 132 of datalatch.cpp will need to be modified, to setprg16(0x8000, latche & 0x1f);, as this game uses a 512K UNROM board. The existing mask only supports a <= 256K UNROM board.
Fortranm
He/Him
Editor, Experienced player (879)
Joined: 10/19/2013
Posts: 1122
The full rom is dumped in October, I think.
Post subject: A movie of Battle Kid 2, Unfair 100%
Player (156)
Joined: 11/7/2013
Posts: 12
Location: China
Playing time:47:20.80 Rerecord count:85120 frames:170729 Rom:Battle Kid 2 - Mountain of Torment (U) Emulator:FCEUX 2.1.6 This is my first time making jump game's movie,Unable to avoid inadequacies,so I will improve my movie later I can't upload AVI file to youtube(Although I can enter) Hope someone can help me upload it.......link to video:http://v.youku.com/v_show/id_XNjY5NDM4ODI0.html AVI file download:http://pan.baidu.com/s/1hqKEP6G
Zarmakuizz
He/Him
Joined: 10/12/2013
Posts: 279
Location: France
The link to the AVI file takes forever to load.
Spikestuff
They/Them
Editor, Publisher, Expert player (2656)
Joined: 10/12/2011
Posts: 6449
Location: The land down under.
Zarmakuizz wrote:
The link to the AVI file takes forever to load.
nEilfox noticing that you're Chinese use: youku or Nico. For you, preferably youku. Edit: Just notcied the youku link. Here you go much simpler: Link to video Edit 2: We need a merge... To here please.
WebNations/Sabih wrote:
+fsvgm777 never censoring anything.
Disables Comments and Ratings for the YouTube account. Something better for yourself and also others.
Player (156)
Joined: 11/7/2013
Posts: 12
Location: China
When I upload video to youtube,it show 10kb/s,after N years it would be complete ,I have to upload to it.
Post subject: Battle Kid 2 movie,Should I continue to make it?
Player (156)
Joined: 11/7/2013
Posts: 12
Location: China
Movie File Download:http://www.multiupload.nl/3WQ1OAFS9G I'd like to improve my movie BUT, I think my movie is not enough entertainment. Or the game doesn't suit to make a TAS. How to do next?
Post subject: Re: Battle Kid 2 movie,Should I continue to make it?
Editor, Expert player (2080)
Joined: 6/15/2005
Posts: 3284
nEilfox wrote:
I'd like to improve my movie BUT, I think my movie is not enough entertainment. Or the game doesn't suit to make a TAS. How to do next?
I think the game is quite entertaining. If it is not too hard, you can try to improve it. Edit: I think you should get the XY coordinate item at 1:37, since it is a 100% run.
caitsith2
He/Him
Player (47)
Joined: 3/26/2004
Posts: 194
You made the same mistake I did, and went and collected the cave orrexium shard at the first opportunity, when you could have collected it on your way to the aquatic base. In fact, watch my unfair run TAS, and merge in any improvements you see. I can see a major one in the aquatic base regarding the fans and spikes. And yes, XY item is part of the 100%. One more optimization, do not get Portal B at first opportunity. You will get that when you are coming from the aquatic base, to head to the ice caves. Your route from Portal D to the 7th Orrexium shard is faster than my route from Portal A to the 7th Orrexium shard, by about 400 frames.
caitsith2
He/Him
Player (47)
Joined: 3/26/2004
Posts: 194
youtube encodes of nEilfox's runs uploaded. Standard or With Hitbox / Extended HUD
Player (156)
Joined: 11/7/2013
Posts: 12
Location: China
The video with extended hud is good. In fact, I am very lazy that I only check and improve my movie for little time, quality is low,My movie needs a lot of improve,The improvement point that caitsith2 talk is all true, For another example when i am ice mountain,In the memory game,Just because of my bad skill,After the third round I can not let each point locked in an orrexium through control luck.And it's going to need a lot of details processing in my movie,I'll contine to make it,and try to make it perfect.I aslo going to collected XY item to correct the mistakes.
caitsith2
He/Him
Player (47)
Joined: 3/26/2004
Posts: 194
My lua script as contained in the first post is what provides the hitbox and extended hud. Definitely make sure to watch my run too. There are things from it that are faster.
Site Admin, Skilled player (1255)
Joined: 4/17/2010
Posts: 11495
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
Is it known how randomness works in this game?
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.
caitsith2
He/Him
Player (47)
Joined: 3/26/2004
Posts: 194
Several random number generation routines. One of them uses controller input, and the something from the music engine. However, not all of the things that use randomization use that routine. It would have to be looked at on a case by case basis.
Site Admin, Skilled player (1255)
Joined: 4/17/2010
Posts: 11495
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
I mean, is it known how to manipulate bosses patterns, or orexium letters, or flashing crystal sequences?
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.