diff --git a/library/lua/memscan.lua b/library/lua/memscan.lua index 4bd01c8f7..65b02194c 100644 --- a/library/lua/memscan.lua +++ b/library/lua/memscan.lua @@ -168,7 +168,7 @@ function MemoryArea:__tostring() return string.format('', self.start_addr, self.end_addr) end function MemoryArea:contains_range(start,size) - return start >= self.start_addr and (start+size) <= self.end_addr + return size >= 0 and start >= self.start_addr and (start+size) <= self.end_addr end function MemoryArea:contains_obj(obj,count) local size, base = df.sizeof(obj) diff --git a/scripts/devel/find-offsets.lua b/scripts/devel/find-offsets.lua index ef9c98299..391390f14 100644 --- a/scripts/devel/find-offsets.lua +++ b/scripts/devel/find-offsets.lua @@ -24,7 +24,10 @@ PERMANENT SAVE CORRUPTION. Finding the first few globals requires this script to be started immediately after loading the game, WITHOUT -first loading a world. +first loading a world. The rest expect a loaded save, +not a fresh embark. Finding current_weather requires +a special save previously processed with devel/prepare-save +on a DF version with working dfhack. The script expects vanilla game configuration, without any custom tilesets or init file changes. Never unpause @@ -387,6 +390,43 @@ number, so when it shows "Min (5000df", it means 50000:]], addr, df.ui_build_selector, 'plate_info', 'unit_min') end +-- +-- current_weather +-- + +local function find_current_weather() + print('\nPlease load the save previously processed with prepare-save.') + if not utils.prompt_yes_no('Proceed?', true) then + return + end + + local zone + if os_type == 'windows' then + zone = zoomed_searcher('crime_next_id', 512) + elseif os_type == 'darwin' then + zone = zoomed_searcher('cursor', -64) + elseif os_type == 'linux' then + zone = zoomed_searcher('ui_building_assign_type', -512) + end + zone = zone or searcher + + local wbytes = { + 2, 1, 0, 2, 0, + 1, 2, 1, 0, 0, + 2, 0, 2, 1, 2, + 1, 2, 0, 1, 1, + 2, 0, 1, 0, 2 + } + + local idx, addr = zone.area.int8_t:find_one(wbytes) + if idx then + ms.found_offset('current_weather', addr) + return + end + + dfhack.printerr('Could not find current_weather - must be a wrong save.') +end + -- -- ui_menu_width -- @@ -669,7 +709,7 @@ end local function get_process_zone() if os_type == 'windows' then return zoomed_searcher('ui_workshop_job_cursor', 'ui_building_in_resize') - else + elseif os_type == 'linux' or os_type == 'darwin' then return zoomed_searcher('cur_year', 'cur_year_tick') end end @@ -710,10 +750,10 @@ end local function find_pause_state() local zone - if os_type == 'linux' then + if os_type == 'linux' or os_type == 'darwin' then zone = zoomed_searcher('ui_look_cursor', 32) elseif os_type == 'windows' then - zone = zoomed_searcher('ui_workshop_job_cursor', 64) + zone = zoomed_searcher('ui_workshop_job_cursor', 80) end zone = zone or searcher @@ -747,6 +787,7 @@ exec_finder(find_ui_build_selector, 'ui_build_selector') print('\nPrimitive globals:\n') +exec_finder(find_current_weather, 'current_weather') exec_finder(find_ui_menu_width, { 'ui_menu_width', 'ui_area_map_width' }) exec_finder(find_ui_selected_unit, 'ui_selected_unit') exec_finder(find_ui_unit_view_mode, 'ui_unit_view_mode') diff --git a/scripts/devel/prepare-save.lua b/scripts/devel/prepare-save.lua new file mode 100644 index 000000000..781e3b892 --- /dev/null +++ b/scripts/devel/prepare-save.lua @@ -0,0 +1,71 @@ +-- Prepare the current save for use with devel/find-offsets. + +df.global.pause_state = true + +--[[print('Placing anchor...') + +do + local wp = df.global.ui.waypoints + + for _,pt in ipairs(wp.points) do + if pt.name == 'dfhack_anchor' then + print('Already placed.') + goto found + end + end + + local x,y,z = pos2xyz(df.global.cursor) + + if not x then + error("Place cursor at your preferred anchor point.") + end + + local id = wp.next_point_id + wp.next_point_id = id + 1 + + wp.points:insert('#',{ + new = true, id = id, name = 'dfhack_anchor', + comment=(x..','..y..','..z), + tile = string.byte('!'), fg_color = COLOR_LIGHTRED, bg_color = COLOR_BLUE, + pos = xyz2pos(x,y,z) + }) + +::found:: +end]] + +print('Nicknaming units...') + +for i,unit in ipairs(df.global.world.units.active) do + dfhack.units.setNickname(unit, i..':'..unit.id) +end + +print('Setting weather...') + +local wbytes = { + 2, 1, 0, 2, 0, + 1, 2, 1, 0, 0, + 2, 0, 2, 1, 2, + 1, 2, 0, 1, 1, + 2, 0, 1, 0, 2 +} + +for i=0,4 do + for j = 0,4 do + df.global.current_weather[i][j] = (wbytes[i*5+j+1] or 2) + end +end + +local yearstr = df.global.cur_year..','..df.global.cur_year_tick + +print('Cur year and tick: '..yearstr) + +dfhack.persistent.save{ + key='prepare-save/cur_year', + value=yearstr, + ints={df.global.cur_year, df.global.cur_year_tick} +} + +-- Save + +dfhack.run_script('quicksave') +