From bcbcc3d1e756d1009cbaab6e830e9f67cdaebd20 Mon Sep 17 00:00:00 2001 From: LOIRELAB <66545056+LoireLab@users.noreply.github.com> Date: Sat, 19 Jul 2025 20:34:50 +0200 Subject: [PATCH 1/2] Track artifacts and invasions --- chronicle.lua | 33 ++++++++++++++++++++++++++++++++- docs/chronicle.rst | 5 ++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/chronicle.lua b/chronicle.lua index 446b3fd6c..8f3efccca 100644 --- a/chronicle.lua +++ b/chronicle.lua @@ -1,4 +1,4 @@ --- Chronicles fortress events (currently only unit deaths) +-- Chronicles fortress events: unit deaths, artifact creation, and invasions --@module = true --@enable = true @@ -40,6 +40,29 @@ local function on_unit_death(unit_id) local date = format_date(df.global.cur_year, df.global.cur_year_tick) add_entry(string.format('Death of %s on %s', name, date)) end + +local function on_item_created(item_id) + local item = df.item.find(item_id) + if not item or not item.flags.artifact then return end + + local gref = dfhack.items.getGeneralRef(item, df.general_ref_type.IS_ARTIFACT) + local rec = gref and df.artifact_record.find(gref.artifact_id) or nil + if not rec then return end + + local name = dfhack.translation.translateName(rec.name) + local date = format_date(rec.year, rec.season_tick or 0) + if rec.id > state.last_artifact_id then + state.last_artifact_id = rec.id + end + add_entry(string.format('Artifact "%s" created on %s', name, date)) +end + +local function on_invasion(invasion_id) + if state.known_invasions[invasion_id] then return end + state.known_invasions[invasion_id] = true + local date = format_date(df.global.cur_year, df.global.cur_year_tick) + add_entry(string.format('Invasion started on %s', date)) +end local function check_artifacts() local last_id = state.last_artifact_id for _, rec in ipairs(df.global.world.artifacts.all) do @@ -73,7 +96,11 @@ end local function do_enable() state.enabled = true + eventful.enableEvent(eventful.eventType.ITEM_CREATED, 1) + eventful.enableEvent(eventful.eventType.INVASION, 1) eventful.onUnitDeath[GLOBAL_KEY] = on_unit_death + eventful.onItemCreated[GLOBAL_KEY] = on_item_created + eventful.onInvasion[GLOBAL_KEY] = on_invasion persist_state() event_loop() @@ -82,6 +109,8 @@ end local function do_disable() state.enabled = false eventful.onUnitDeath[GLOBAL_KEY] = nil + eventful.onItemCreated[GLOBAL_KEY] = nil + eventful.onInvasion[GLOBAL_KEY] = nil persist_state() end @@ -95,6 +124,8 @@ end dfhack.onStateChange[GLOBAL_KEY] = function(sc) if sc == SC_MAP_UNLOADED then eventful.onUnitDeath[GLOBAL_KEY] = nil + eventful.onItemCreated[GLOBAL_KEY] = nil + eventful.onInvasion[GLOBAL_KEY] = nil state.enabled = false return end diff --git a/docs/chronicle.rst b/docs/chronicle.rst index 7943ee30a..e573d967b 100644 --- a/docs/chronicle.rst +++ b/docs/chronicle.rst @@ -2,12 +2,11 @@ chronicle ========= .. dfhack-tool:: - :summary: Record fortress events like deaths. Artifact and invasion tracking disabled. + :summary: Record fortress events like deaths, artifacts, and invasions. :tags: fort gameplay This tool automatically records notable events in a chronicle that is stored -with your save. Currently only unit deaths are recorded since artifact and -invasion tracking has been disabled due to performance issues. +with your save. Unit deaths, artifact creation, and invasions are recorded. Usage ----- From c623822944a29856ec5b24e548027ef1e7a0bf30 Mon Sep 17 00:00:00 2001 From: LOIRELAB <66545056+LoireLab@users.noreply.github.com> Date: Sat, 19 Jul 2025 20:39:20 +0200 Subject: [PATCH 2/2] Remove legacy scanning in chronicle --- chronicle.lua | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/chronicle.lua b/chronicle.lua index 8f3efccca..c247180ed 100644 --- a/chronicle.lua +++ b/chronicle.lua @@ -63,36 +63,8 @@ local function on_invasion(invasion_id) local date = format_date(df.global.cur_year, df.global.cur_year_tick) add_entry(string.format('Invasion started on %s', date)) end -local function check_artifacts() - local last_id = state.last_artifact_id - for _, rec in ipairs(df.global.world.artifacts.all) do - if rec.id > last_id then - local name = dfhack.translation.translateName(rec.name) - -- artifact_record stores the creation tick in `season_tick` - local date = format_date(rec.year, rec.season_tick or 0) - add_entry(string.format('Artifact "%s" created on %s', name, date)) - last_id = rec.id - end - end - state.last_artifact_id = last_id -end - -local function check_invasions() - for _, inv in ipairs(df.global.plotinfo.invasions.list) do - if inv.flags.active and not state.known_invasions[inv.id] then - state.known_invasions[inv.id] = true - local date = format_date(df.global.cur_year, df.global.cur_year_tick) - add_entry(string.format('Invasion started on %s', date)) - end - end -end - --- main loop; artifact and invasion tracking disabled to avoid scanning large --- data structures, which was causing hangs on some forts -local function event_loop() - if not state.enabled then return end - dfhack.timeout(1200, 'ticks', event_loop) -end +-- legacy scanning functions for artifacts and invasions have been removed in +-- favor of event-based tracking. the main loop is no longer needed. local function do_enable() state.enabled = true @@ -102,8 +74,6 @@ local function do_enable() eventful.onItemCreated[GLOBAL_KEY] = on_item_created eventful.onInvasion[GLOBAL_KEY] = on_invasion persist_state() - - event_loop() end local function do_disable()