User File #638492465665812103

Upload All User Files

#638492465665812103 - NES Crown of Kings lua script

COK-distance-calculator-v3.lua
System: Nintendo Entertainment System
47 downloads
Uploaded 4/20/2024 9:49 PM by Winslinator (see all 25)
For a given input sequence, the script can check what cave layout occurs for every possible delay you could wait between each input of a specified input sequence.
--start specifies the frame on which the first input in the series is to be executed
--maxenter specifies the latest acceptable frame the mountain can be entered
start = 3264
maxenter = 3315

--this script checks a series of up to 8 inputs. To execute only 7 inputs, start by setting delay1int to 0 and comment out the joypad command under the "emu.framecount() == start" if statement. To execute 6 inputs, set delay2int to 0 and comment out the joypad command under the "emu.framecount() == start + delay1" if statement.
delay1int = 0
delay2int = 8
delay3int = 8
delay4int = 8
delay5int = 8
delay6int = 8
delay7int = 8
delay1 = delay1int
delay2 = delay2int
delay3 = delay3int
delay4 = delay4int
delay5 = delay5int
delay6 = delay6int
delay7 = delay7int

mincount = 0

while true do

	if emu.framecount() == start - 1
	then
		savestate.saveslot(1)
	end
	
	--for the series of if statements below, uncomment each joypad command you wish for the game to execute
	
	if emu.framecount() == start
	then
		-- joypad.set({Up=true}, 1)
		--joypad.set({Up=true, Right=true}, 1)
		--joypad.set({Right=true}, 1)
		--joypad.set({Down=true, Right=true}, 1)
		-- joypad.set({Down=true}, 1)
		-- joypad.set({Down=true, Left=true}, 1)
		-- joypad.set({Left=true}, 1)
		-- joypad.set({Up=true, Left=true}, 1)
	end
	
	if emu.framecount() == start + delay1
	then
		-- joypad.set({Up=true}, 1)
		--joypad.set({Up=true, Right=true}, 1)
		--joypad.set({Right=true}, 1)
		joypad.set({Down=true, Right=true}, 1)
		-- joypad.set({Down=true}, 1)
		-- joypad.set({Down=true, Left=true}, 1)
		-- joypad.set({Left=true}, 1)
		-- joypad.set({Up=true, Left=true}, 1)
	end
	
	if emu.framecount() == start + delay1 + delay2
	then
		-- joypad.set({Up=true}, 1)
		joypad.set({Up=true, Right=true}, 1)
		--joypad.set({Right=true}, 1)
		--joypad.set({Down=true, Right=true}, 1)
		-- joypad.set({Down=true}, 1)
		-- joypad.set({Down=true, Left=true}, 1)
		-- joypad.set({Left=true}, 1)
		--joypad.set({Up=true, Left=true}, 1)
	end
	
	if emu.framecount() == start + delay1 + delay2 + delay3
	then
		--joypad.set({Up=true}, 1)
		--joypad.set({Up=true, Right=true}, 1)
		joypad.set({Right=true}, 1)
		--joypad.set({Down=true, Right=true}, 1)
		-- joypad.set({Down=true}, 1)
		-- joypad.set({Down=true, Left=true}, 1)
		-- joypad.set({Left=true}, 1)
		--joypad.set({Up=true, Left=true}, 1)
	end
	
	if emu.framecount() == start + delay1 + delay2 + delay3 + delay4
	then
		-- joypad.set({Up=true}, 1)
		joypad.set({Up=true, Right=true}, 1)
		--joypad.set({Right=true}, 1)
		--joypad.set({Down=true, Right=true}, 1)
		--joypad.set({Down=true}, 1)
		-- joypad.set({Down=true, Left=true}, 1)
		--joypad.set({Left=true}, 1)
		--joypad.set({Up=true, Left=true}, 1)
	end
	
	if emu.framecount() == start + delay1 + delay2 + delay3 + delay4 + delay5
	then
		--joypad.set({Up=true}, 1)
		--joypad.set({Up=true, Right=true}, 1)
		--joypad.set({Right=true}, 1)
		joypad.set({Down=true, Right=true}, 1)
		--joypad.set({Down=true}, 1)
		--joypad.set({Down=true, Left=true}, 1)
		--joypad.set({Left=true}, 1)
		-- joypad.set({Up=true, Left=true}, 1)
	end
	
	if emu.framecount() == start + delay1 + delay2 + delay3 + delay4 + delay5 + delay6
	then
		--joypad.set({Up=true}, 1)
		--joypad.set({Up=true, Right=true}, 1)
		--joypad.set({Right=true}, 1)
		joypad.set({Down=true, Right=true}, 1)
		--joypad.set({Down=true}, 1)
		--joypad.set({Down=true, Left=true}, 1)
		--joypad.set({Left=true}, 1)
		--joypad.set({Up=true, Left=true}, 1)
	end
	
	if emu.framecount() == start + delay1 + delay2 + delay3 + delay4 + delay5 + delay6 + delay7
	then
		-- joypad.set({Up=true}, 1)
		--joypad.set({Up=true, Right=true}, 1)
		--joypad.set({Right=true}, 1)
		joypad.set({Down=true, Right=true}, 1)
		-- joypad.set({Down=true}, 1)
		--joypad.set({Down=true, Left=true}, 1)
		-- joypad.set({Left=true}, 1)
		-- joypad.set({Up=true, Left=true}, 1)
	end
	
	enterframe = start + delay1 + delay2 + delay3 + delay4 + delay5 + delay6 + delay7
	
	if emu.framecount() == enterframe + 108
	then
		--read a bunch of position variables from RAM
		x = mainmemory.read_u8(0x0085)
		y = mainmemory.read_u8(0x0086)
		toolx = mainmemory.read_u8(0x00DE)
		tooly = mainmemory.read_u8(0x00DF)
		ladderx = mainmemory.read_u8(0x0301)
		laddery = mainmemory.read_u8(0x0302)
		crown1x = mainmemory.read_u8(0x0305)
		crown1y = mainmemory.read_u8(0x0306)
		crown2x = mainmemory.read_u8(0x0307)
		crown2y = mainmemory.read_u8(0x0308)
		
		--calculates each rectilinear distances between the player's start point and the tool, the tool and the ladder, and the player's start point and the ladder
		if crown1x == 128 and crown1y == 128 and crown2x == 128 and crown2y == 128
		then
			dist1 = math.min((toolx - x) % 48, (x - toolx) % 48) + math.min((tooly - y) % 45, (y - tooly) % 45)
			dist2 = math.min((ladderx - toolx) % 48, (toolx - ladderx) % 48) + math.min((laddery - tooly) % 45, (tooly - laddery) % 45)
			dist3 = math.min((ladderx - x) % 48, (x - ladderx) % 48) + math.min((laddery - y) % 45, (y - laddery) % 45)
			totdist = dist1 + math.min(dist2,dist3)
		--calculates each rectilinear distances between the player's start point and each crown half, and the distances between the crown halves
		elseif toolx == 128 and tooly == 128 and ladderx == 128 and laddery == 128
		then	
			dist1 = math.min((crown2x - x) % 48, (x - crown2x) % 48) + math.min((crown2y - y) % 45, (y - crown2y) % 45)
			dist2 = math.min((crown2x - crown1x) % 48, (crown1x - crown2x) % 48) + math.min((crown2y - crown1y) % 45, (crown1y - crown2y) % 45)
			dist3 = math.min((crown1x - x) % 48, (x - crown1x) % 48) + math.min((crown1y - y) % 45, (y - crown1y) % 45)
			shortdist = math.min(dist1,dist2)
			if shortdist == dist1
			then
				totdist = dist1 + math.min(dist2,dist3)
			elseif shortdist == dist2
			then
				totdist = dist2 + math.min(dist1,dist3)
			end
		end
		
		--how many of the best cave layouts have been found so far?
		if dist1 == 11 and dist2 == 17 and dist3 == 16
		then
			mincount = mincount + 1
		end
		
		--output some important numbers
		console.log(start,delay1,delay2,delay3,delay4,delay5,delay6,delay7,totdist,mincount,enterframe)
		
		--the rest controls iterating the through each scenario
		delay7 = delay7 + 1
		if start + delay1 + delay2 + delay3 + delay4 + delay5 + delay6 + delay7 > maxenter
		then
			delay6 = delay6 + 1
			if start + delay1 + delay2 + delay3 + delay4 + delay5 + delay6 > maxenter - delay7int
			then
				delay5 = delay5 + 1
				if start + delay1 + delay2 + delay3 + delay4 + delay5 > maxenter - delay7int - delay6int
				then
					delay4 = delay4 + 1
					if start + delay1 + delay2 + delay3 + delay4 > maxenter - delay7int - delay6int - delay5int
					then
						delay3 = delay3 + 1
						if start + delay1 + delay2 + delay3 > maxenter - delay7int - delay6int - delay5int - delay4int
						then
							delay2 = delay2 + 1
							if start + delay1 + delay2 > maxenter - delay7int - delay6int - delay5int - delay4int - delay3int
							then
								delay1 = delay1 + 1
								if start + delay1 > maxenter - delay7int - delay6int - delay5int - delay4int - delay3int - delay2int
								then
									start = start + 1
									delay1 = delay1int
								end
								delay2 = delay2int
							end
							delay3 = delay3int
						end
						delay4 = delay4int
					end
					delay5 = delay5int
				end
				delay6 = delay6int
			end
			delay7 = delay7int
		end
		savestate.loadslot(1)
	end
	
	if delay6int == 0 and delay5int == 0 and delay4int == 0 and delay3int == 0 and delay2int == 0 and delay1int == 0 then stop = delay6
	elseif delay6int ~= 0 and delay5int == 0 and delay4int == 0 and delay3int == 0 and delay2int == 0 and delay1int == 0 then stop = delay5
	elseif delay6int ~= 0 and delay5int ~= 0 and delay4int == 0 and delay3int == 0 and delay2int == 0 and delay1int == 0 then stop = delay4
	elseif delay6int ~= 0 and delay5int ~= 0 and delay4int ~= 0 and delay3int == 0 and delay2int == 0 and delay1int == 0 then stop = delay3
	elseif delay6int ~= 0 and delay5int ~= 0 and delay4int ~= 0 and delay3int ~= 0 and delay2int == 0 and delay1int == 0 then stop = delay2
	elseif delay6int ~= 0 and delay5int ~= 0 and delay4int ~= 0 and delay3int ~= 0 and delay2int ~= 0 and delay1int == 0 then stop = delay1
	else stop = start + delay1 + delay2 + delay3 + delay4 + delay5 + delay6 + delay7 - maxenter
	end
	
	if stop > 0
	then
		start = start + 1
		delay1 = delay1int
		delay2 = delay2int
		delay3 = delay3int
		delay4 = delay4int
		delay5 = delay5int
		delay6 = delay6int
		delay7 = delay7int
	end
	
	--pause the emulator if there are no more scenarios to check
	if enterframe > maxenter
	then
		client.pause()
	end
	
	emu.frameadvance()
end