User File #56303559949576175

Upload All User Files

#56303559949576175 - Rolan's Curse - Enemy & RNG v1.2

Rolan's Curse - Enemy & RNG v1.2.lua
566 downloads
Uploaded 7/2/2019 3:06 PM by ThunderAxe31 (see all 109)
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.2 by ThunderAxe31 for GB Rolan's Curse

local addr_scrollx            = 0xFFC6
local addr_scrolly            = 0xFFC5

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

local addr_RNG                = 0xC0A5
local addr_killcount          = 0xC0AD
local addr_timer              = 0xFFB8
local lagcount_l              = 0
local lagcount_r              = 0
local timer_old_l             = -1
local timer_old_r             = -1
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
	
	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)
	
	--gui.pixelText(87 + draw_offset, 137, rand1 .. rand2 .. killcount)
	gui.pixelText(87 + draw_offset, 130, "ATT:" .. temp_att .. "(" .. perm_att .. ")" .. "  HP:" .. temp_hp .. "(" .. perm_hp .. ")\n" .. rand1 .. rand2 .. killcount, 0xFFFFFFFF, 0xFF000000)
	gui.drawRectangle(87 + draw_offset +8*killcycle, 137, 8, 6, "red")
end

if (memory.getmemorydomainlist()[0] == "WRAM") or (memory.getmemorydomainlist()[0] == "Main RAM") then
	if memory.usememorydomain("System Bus") then
		while true do
			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
			lagcount_l              = 0
			lagcount_r              = 0
			timer_old_l             = -1
			timer_old_r             = -1
		end
		framecount_old = framecount
		
		memory.usememorydomain(memdom_l)
		draw(false)
		
		local timer_l = memory.read_u8(addr_timer)
		if timer_l == timer_old_l then
			lagcount_l = lagcount_l +1
		end
		timer_old_l = timer_l
		gui.pixelText(0, 128, lagcount_l, 0xFFFF0000, 0xFF000000)
	
		memory.usememorydomain(memdom_r)
		draw(true)
		
		local timer_r = memory.read_u8(addr_timer)
		if timer_r == timer_old_r then
			lagcount_r = lagcount_r +1
		end
		timer_old_r = timer_r
		gui.pixelText(160, 128, lagcount_r, 0xFFFF0000, 0xFF000000)
		
		emu.frameadvance()
	end
end