diff --git a/src/core/Ghost.lua b/src/core/Ghost.lua index c9a6f29..753375f 100644 --- a/src/core/Ghost.lua +++ b/src/core/Ghost.lua @@ -4,7 +4,9 @@ -- SPDX-License-Identifier: GPL-2.0-or-later -- -Ghost = {} +Ghost = { + object_address = 0 +} ---@class GhostFrame ---@field global_timer integer @@ -24,8 +26,14 @@ local frame = 0 local recording_base_frame = nil local last_global_timer = nil +local OBJECT_EXTRA_MAGIC = 0x4F424A54 +local non_mario_graphics = nil +local animation_switches = { } +local last_recorded_animation = nil + local OBJ_POSITION_OFFSET = 0x20 -local OBJ_ANIMATION_OFFSET = 0x38 +local OBJ_ANIMATION_ID_OFFSET = 0x38 +local OBJ_ANIMATION_OFFSET = 0x3C local OBJ_ANIMATION_TIMER_OFFSET = 0x40 local OBJ_PITCH_OFFSET = 0x1A local OBJ_YAW_OFFSET = 0x1C @@ -82,6 +90,18 @@ local function flush() writebytes32(file, value.roll) end + if non_mario_graphics then + writebytes32(file, OBJECT_EXTRA_MAGIC) + writebytes32(file, non_mario_graphics) + local count = 0 + for _ in pairs(animation_switches) do count = count + 1 end + writebytes32(file, count) + for k, v in pairs(animation_switches) do + writebytes32(file, k) + writebytes32(file, v) + end + end + file:close() return true @@ -99,7 +119,7 @@ function Ghost.update() end local address_source = Addresses[Settings.address_source_index] - local mario_obj = memory.readdword(address_source.mario_object_pointer) + local mario_obj = Ghost.object_address or memory.readdword(address_source.mario_object_pointer) local global_timer = memory.readdword(address_source.global_timer) if recording_base_frame == nil then @@ -116,9 +136,15 @@ function Ghost.update() x = memory.readdword(mario_obj + OBJ_POSITION_OFFSET), y = memory.readdword(mario_obj + OBJ_POSITION_OFFSET + 4), z = memory.readdword(mario_obj + OBJ_POSITION_OFFSET + 8), - animation_index = memory.readword(mario_obj + OBJ_ANIMATION_OFFSET), + animation_index = memory.readword(mario_obj + OBJ_ANIMATION_ID_OFFSET), animation_timer = memory.readword(mario_obj + OBJ_ANIMATION_TIMER_OFFSET) - 1, } + + local animation = memory.readdword(mario_obj + OBJ_ANIMATION_OFFSET) + if animation ~= last_recorded_animation then + last_recorded_animation = animation + animation_switches[#frames - 1] = animation + end end end @@ -153,6 +179,8 @@ function Ghost.start_recording() end is_recording = true + non_mario_graphics = Ghost.object_address and memory.readdword(Ghost.object_address + 0x14) or 0 + last_recorded_animation = nil return true end diff --git a/src/core/Locales.lua b/src/core/Locales.lua index 5ca974e..705496f 100644 --- a/src/core/Locales.lua +++ b/src/core/Locales.lua @@ -141,6 +141,7 @@ Locales = {} ---@field public TOOLS_RNG_USE_INDEX string ---@field public TOOLS_DUMPING string ---@field public TOOLS_GHOST string +---@field public TOOLS_GHOST_OBJECT_ADDRESS_TOOL_TIP string ---@field public TOOLS_GHOST_START string ---@field public TOOLS_GHOST_STOP string ---@field public TOOLS_GHOST_START_RECORDING_FAILED string diff --git a/src/res/lang/en_US.lua b/src/res/lang/en_US.lua index 1af699f..407d917 100644 --- a/src/res/lang/en_US.lua +++ b/src/res/lang/en_US.lua @@ -179,6 +179,7 @@ This action cannot be undone. TOOLS_RNG_USE_INDEX = 'Use Index', TOOLS_DUMPING = 'Dumping', TOOLS_GHOST = 'Ghost', + TOOLS_GHOST_OBJECT_ADDRESS_TOOL_TIP = 'Address of the object to record (e.g. 8033FF48). If 0, Mario is recorded.', TOOLS_GHOST_START = 'Start Recording', TOOLS_GHOST_STOP = 'Stop Recording', TOOLS_GHOST_START_RECORDING_FAILED = 'Failed to start ghost recording.', diff --git a/src/res/lang/fr_FR.lua b/src/res/lang/fr_FR.lua index 9ae834a..508d49d 100644 --- a/src/res/lang/fr_FR.lua +++ b/src/res/lang/fr_FR.lua @@ -178,6 +178,7 @@ Cette action est irréversible. TOOLS_DUMPING = 'Export', TOOLS_EXPERIMENTS = 'Expériences', TOOLS_GHOST = 'Fantôme', + TOOLS_GHOST_OBJECT_ADDRESS_TOOL_TIP = 'Adresse de l’objet à enregistrer (par exemple 8033FF48). Si 0, Mario est enregistré.', TOOLS_GHOST_START = 'Démarrer rec.', TOOLS_GHOST_STOP = 'Arrêter rec.', TOOLS_GHOST_START_RECORDING_FAILED = 'Échec du démarrage de l\'enregistrement fantôme.', diff --git a/src/views/Tools.lua b/src/views/Tools.lua index 2af60cc..81ec464 100644 --- a/src/views/Tools.lua +++ b/src/views/Tools.lua @@ -17,6 +17,7 @@ local UID = UIDProvider.allocate_once('Tools', function(enum_next) RngUse = enum_next(), RngValue = enum_next(4), Dump = enum_next(), + GhostObjectAddress = enum_next(), RecordGhost = enum_next(), WorldVisualizer = enum_next(), AutoFirsties = enum_next(), @@ -114,6 +115,13 @@ return { align_y = BreitbandGraphics.alignment.center, }) + Ghost.object_address = tonumber(ugui.textbox({ + uid = UID.GhostObjectAddress, + rectangle = grid_rect(4, GHOST_ROW, 4, 1), + text = string.format("%x", Ghost.object_address or 0), + tooltip = Locales.str('TOOLS_GHOST_OBJECT_ADDRESS_TOOL_TIP') + }):gsub("[^%x]", ""), 16) + if ugui.button({ uid = UID.RecordGhost, rectangle = grid_rect(0, GHOST_ROW, 4, 1),