User File #637806326123243340

Upload All User Files

#637806326123243340 - Rolan's Curse - Enemy & RNG v1.3

Rolan's Curse - Enemy & RNG v1.3.lua
146 downloads
Uploaded 2/16/2022 6:23 PM by ThunderAxe31 (see all 111)
Script that shows various info about enemies: attack, HP left, item drop. It does display an exclamation mark when the drop can happen. Also displays current ATT and HP, of which both temporary and permanent values. Works in 2 players mode, and displays independent lag counts. Works with both Gambatte and GBHawk cores.
--Enemy & RNG watch v1.3 by ThunderAxe31 for GB Rolan's Curse
--1.625 / 13
local addr_scrollx            = 0xFFC6
local addr_scrolly            = 0xFFC5

local addr_temp_att           = 0xFFAA
local addr_perm_att           = 0xFFAB
local addr_left_hp            = 0xFFA9
local addr_temp_hp            = 0xFFA8
local addr_perm_hp            = 0xFFA7

local addr_RNG                = 0xC0A5
local addr_killcount          = 0xC0AD

local addr_x                  = 0xFFD2
local addr_y                  = 0xFFD1
local l_x_pixel_old           = -1
local l_y_pixel_old           = -1
local r_x_pixel_old           = -1
local r_y_pixel_old           = -1
local l_framecount_short      = -1
local r_framecount_short      = -1
local framecount_old          = 0

local addr_enemy_start        = 0xC22B
local addr_enemy_offset_y     = 0x06
local addr_enemy_offset_x     = 0x0A
local addr_enemy_offset_hp    = 0x13
local addr_enemy_offset_att   = 0x15
local addr_enemy_offset_drop  = 0x1A
local addr_enemy_offset_block = 0x20
local enemy_max               = 4

local item = {
	[0x0] = "SWORD",--also used in case of dropless enemy
	[0x1] = "WAND",
	[0x2] = "ARMOR",
	[0x3] = "HAND",
	[0x4] = "HEART",
	[0x5] = "JUG",
	[0x6] = "SHIELD",
	[0x7] = "SPHERE",
	[0x8] = "PICKAX",
	[0x9] = "RING",
	[0xA] = "TRAP",--unused
	[0xB] = "VIAL",
	[0xC] = "CAPE",
	[0xD] = "0xD", --unused
	[0xE] = "0xE", --unused
	[0xF] = "0xF"  --unused
}

local function draw(rightside)
	local draw_offset = 0
	if rightside then draw_offset = 160 end
	
	local scrollx = memory.read_u8(addr_scrollx)
	local scrolly = memory.read_u8(addr_scrolly)
	local killcount = memory.read_u8(addr_killcount)
	local killcycle = bit.band(killcount, 0x0F)
	
	for i = 0, enemy_max-1 do
		local addr_enemy = addr_enemy_start +i*0x20
		if memory.read_u8(addr_enemy) ~= 0 then
			local enemy_x    = memory.read_u8(addr_enemy + addr_enemy_offset_x) -scrollx
			local enemy_y    = memory.read_u8(addr_enemy + addr_enemy_offset_y) -scrolly -14
			local enemy_hp   = memory.read_u16_le(addr_enemy + addr_enemy_offset_hp)
			local enemy_att  = memory.read_u8(addr_enemy + addr_enemy_offset_att)
			
			local enemy_drop = memory.read_u8(addr_enemy + addr_enemy_offset_drop)
			local enemy_drop_item = bit.band(enemy_drop, 0x0F)
			local enemy_drop_rate = math.floor((bit.rshift(enemy_drop, 4) /15) *100)
			
			local dropping = " "
			if enemy_drop >= 240 then
				dropping = "!"
			elseif bit.band(enemy_drop, 0xF0) > bit.bxor(memory.read_u8(addr_RNG + killcycle), 0xFF) then
				dropping = "!"
			end
			
			if enemy_x < 0 then enemy_x = 0 end
			if enemy_y < 0 then enemy_y = 0 end
			if enemy_x > 120 then enemy_x = 115 end
			if enemy_y > 121 then enemy_y = 114 end
			gui.pixelText(enemy_x + draw_offset, enemy_y, "ATT:" .. enemy_att .. " HP:" .. enemy_hp .. "\n" .. item[enemy_drop_item] .. " " .. enemy_drop_rate .. "%" .. dropping)
		end
	end
	
	local rand1 = string.format("%X", memory.read_u32_be(addr_RNG) )
	local rand2 = string.format("%X", memory.read_u32_be(addr_RNG+4) )
	killcount = string.format("%X", killcount)
	
	if string.len(rand1) < 8 then rand1 = "0" .. rand1 end
	if string.len(rand1) < 8 then rand1 = "0" .. rand1 end
	if string.len(rand2) < 8 then rand2 = "0" .. rand2 end
	if string.len(rand2) < 8 then rand2 = "0" .. rand2 end
	if string.len(killcount) < 2 then killcount = "0" .. killcount end
	if string.len(killcount) < 2 then killcount = "0" .. killcount end
	
	gui.pixelText(86 + draw_offset, 136, rand1 .. rand2 .. killcount, 0xFFFFFFFF, 0xFF000000)
	gui.drawRectangle(86 + draw_offset +8*killcycle, 135, 8, 8, "red")
	
	local temp_att = memory.read_u8(addr_temp_att)+1
	local perm_att = memory.read_u8(addr_perm_att)+1
	local temp_hp  = memory.read_u8(addr_temp_hp)
	local perm_hp  = memory.read_u8(addr_perm_hp)
	local left_hp  = memory.read_u8(addr_left_hp)
	
	gui.pixelText(36 +draw_offset, 129, "ATT:  " .. temp_att .. "(" .. perm_att .. ")" .. "\nHP: " .. left_hp .. "/" .. temp_hp .. "(" .. perm_hp .. ")", 0xFFFFFFFF, 0xFF000000)
	
	--the following code block handles the movement speed thing
	local x_pixel = memory.read_u8(addr_x)
	local y_pixel = memory.read_u8(addr_y)
	
	local x_pixel_old      = -1
	local y_pixel_old      = -1
	local framecount_short = -1
	
	if rightside then
		x_pixel_old = r_x_pixel_old
		y_pixel_old = r_y_pixel_old
		framecount_short = r_framecount_short
	else
		x_pixel_old = l_x_pixel_old
		y_pixel_old = l_y_pixel_old
		framecount_short = l_framecount_short
	end
	
	if framecount_short >= 0 then
		framecount_short = framecount_short +1
		if (framecount_short > 2) and (x_pixel %8 == 0) and (y_pixel %8 == 0) then
			local text_color = 0xFFFFFFFF
			if framecount_short > 13 then
				text_color = 0xFFFF0000
			elseif framecount_short < 13 then
				text_color = 0xFF00FF00
			end
			gui.pixelText(1 +draw_offset, 129, framecount_short, text_color, 0xFF000000)
			framecount_short = -1
		end
	end
	
	if (((x_pixel_old == 7) or (x_pixel_old == 9) or (x_pixel_old == 15) or (x_pixel_old == 1)) and (x_pixel %8 == 0)) or (((y_pixel_old == 7) or (y_pixel_old == 9) or (y_pixel_old == 15) or (y_pixel_old == 1)) and (y_pixel %8 == 0)) then
		framecount_short = 0
	end
	
	x_pixel_old = x_pixel
	y_pixel_old = y_pixel
	
	if rightside then
		r_x_pixel_old = x_pixel_old
		r_y_pixel_old = y_pixel_old
		r_framecount_short = framecount_short
	else
		l_x_pixel_old = x_pixel_old
		l_y_pixel_old = y_pixel_old
		l_framecount_short = framecount_short
	end
end

if (memory.getmemorydomainlist()[0] == "WRAM") or (memory.getmemorydomainlist()[0] == "Main RAM") then
	if memory.usememorydomain("System Bus") then
		while true do
			local framecount = emu.framecount()
			if framecount_old ~= (framecount-1) then --if a state has been loaded, reset values
				l_x_pixel_old      = -1
				l_y_pixel_old      = -1
				l_framecount_short = -1
			end
			framecount_old = framecount
			
			draw(false)
			emu.frameadvance()
		end
	else
		console.log("Fatal error: unable to set System Bus memory domain for single GB")
	end
else
	local memdom_l = ""
	local memdom_r = ""
	if memory.getmemorydomainlist()[0] == "L WRAM" then
		memdom_l = "L System Bus"
		memdom_r = "R System Bus"
	elseif memory.getmemorydomainlist()[0] == "Main RAM L" then
		memdom_l = "System Bus L"
		memdom_r = "System Bus R"
	else
		console.log("Fatal error: unable to set System Bus memory domain for dual GB")
		return
	end
	while true do
		local framecount = emu.framecount()
		if framecount_old ~= (framecount-1) then --if a state has been loaded, reset values
			l_x_pixel_old      = -1
			l_y_pixel_old      = -1
			r_x_pixel_old      = -1
			r_y_pixel_old      = -1
			l_framecount_short = -1
			r_framecount_short = -1
		end
		framecount_old = framecount
		
		memory.usememorydomain(memdom_l)
		draw(false)
		
		memory.usememorydomain(memdom_r)
		draw(true)
		
		emu.frameadvance()
	end
end