@@ -335,24 +335,25 @@ local function save_popup()
335335 end
336336end
337337
338- --- @return df.unit[]
339- local function _get_active_units_with_missing_nemesis_records ()
338+ --- @return df.unit.id []
339+ local function _get_active_unit_ids_with_missing_nemesis_records ()
340340 local list = {}
341341 for _ , unit in ipairs (units .active ) do
342342 local ref = dfhack .units .getGeneralRef (unit , df .general_ref_type .IS_NEMESIS )
343343 if ref then
344344 local nrec = ref :getNemesis ()
345345 if nrec == nil then
346- table.insert (list , unit )
346+ table.insert (list , unit . id )
347347 end
348348 end
349349 end
350350 return list
351351end
352352
353- --- @param vector any[] # a df vector or array, or a Lua list (not tested yet).
353+ --- @generic T
354+ --- @param vector ` T ` [] # a df vector or array, or a Lua list (not tested yet).
354355--- @param field string ? # nil, or the field name to sort on.
355- --- @param comparator fun ( a : any , b : any ): integer | nil
356+ --- @param comparator fun ( a : T , b : T ): integer | nil
356357--- # an optional comparator that returns -1,0,1 per utils.compare_* .
357358--- # nil falls back to utils.compare or utils.compare_field.
358359--- # if a comparator is given, the field parameter is ignored.
@@ -381,34 +382,31 @@ end
381382local Cache_nemesis_all = defclass (Cache_nemesis_all , nil ) -- singleton, don't need to instantiate.
382383Cache_nemesis_all .ATTRS {}
383384
385+ function Cache_nemesis_all :invalidate ()
386+ self .ATTRS .cached_on_year = - 1
387+ end
388+
384389--- @param force boolean ? # true to force updating the cached data
385390function Cache_nemesis_all :populate (force )
386- if not force
387- and self .ATTRS .cached_on_year == dfhack .world .ReadCurrentYear ()
388- and (self .ATTRS .cached_on_tick or 0 ) + 600 < dfhack .world .ReadCurrentTick ()
391+ local recheck_after = (self .ATTRS .cached_on_tick or 0 ) + 1200
392+ if force ~= true
393+ and dfhack .world .ReadCurrentYear () == self .ATTRS .cached_on_year
394+ and dfhack .world .ReadCurrentTick () < recheck_after
389395 and self .ATTRS .nemesis_all_length == # df .global .world .nemesis .all
390396 and self .ATTRS .units_active_length == # df .global .world .units .active
391397 then
392398 return
393399 end
394- print (" Cache_nemesis_all:populate" , " \n " ,
395- " force" , force , " \n " ,
396- " year" , self .ATTRS .cached_on_year , dfhack .world .ReadCurrentYear (), " \n " ,
397- " tick" , self .ATTRS .cached_on_tick , dfhack .world .ReadCurrentTick (), " \n " ,
398- " #nemall" , self .ATTRS .nemesis_all_length , # df .global .world .nemesis .all , " \n " ,
399- " #active" , self .ATTRS .units_active_length , # df .global .world .units .active , " \n " ,
400- " " )
401-
402400 self .ATTRS .cached_on_year = dfhack .world .ReadCurrentYear ()
403401 self .ATTRS .cached_on_tick = dfhack .world .ReadCurrentTick ()
404402 self .ATTRS .nemesis_all_length = # df .global .world .nemesis .all
405403 self .ATTRS .units_active_length = # df .global .world .units .active
406404 self .ATTRS .nemesis_all_is_sorted = verify_vector_is_sorted (df .global .world .nemesis .all , ' id' )
407- self .ATTRS .affected_units = _get_active_units_with_missing_nemesis_records ()
405+ self .ATTRS .affected_unit_ids = _get_active_unit_ids_with_missing_nemesis_records ()
408406end
409407
410408function Cache_nemesis_all :init ()
411- self :populate ( true )
409+ self :invalidate ( )
412410end
413411
414412--- @return boolean
@@ -418,9 +416,9 @@ function Cache_nemesis_all:is_sorted()
418416end
419417
420418--- @return df.unit[]
421- function Cache_nemesis_all :get_affected_units ()
419+ function Cache_nemesis_all :get_affected_unit_ids ()
422420 self :populate ()
423- return self .ATTRS .affected_units
421+ return self .ATTRS .affected_unit_ids
424422end
425423
426424-- the order of this list controls the order the notifications will appear in the overlay
@@ -439,7 +437,7 @@ NOTIFICATIONS_BY_IDX = {
439437 local count = df .global .nemesis_next_id - # df .global .world .nemesis .all
440438 if count == 0 then return end
441439 return { {
442- pen = # Cache_nemesis_all :get_affected_units () > 0
440+ pen = # Cache_nemesis_all :get_affected_unit_ids () > 0
443441 and COLOR_LIGHTRED or COLOR_YELLOW ,
444442 text = (' missing %d nemesis record%s' ):format (count , count == 1 and ' ' or ' s' )
445443 } }
@@ -454,7 +452,7 @@ NOTIFICATIONS_BY_IDX = {
454452 dlg .showMessage (' nemesis vector not sorted' , message , COLOR_RED )
455453 return
456454 end
457- local list = Cache_nemesis_all :get_affected_units ()
455+ local list = Cache_nemesis_all :get_affected_unit_ids ()
458456 local message = {
459457 { pen = COLOR_RED , text = ' This save game may be corrupt.' }, NEWLINE ,
460458 NEWLINE ,
@@ -475,8 +473,10 @@ NOTIFICATIONS_BY_IDX = {
475473 table.insert (message , { pen = COLOR_RED ,
476474 text = ' These units on the map are missing their nemesis records:' })
477475 table.insert (message , NEWLINE )
478- for _ , unit in ipairs (list ) do
479- local text = dfhack .units .getReadableName (unit )
476+ for _ , unit_id in ipairs (list ) do
477+ local unit = df .unit .find (unit_id )
478+ local text = unit and dfhack .units .getReadableName (unit )
479+ or " missing unit for unit id " .. unit_id
480480 if # text > 55 then text = dfhack .units .getReadableName (unit , true ); end
481481 table.insert (message , { pen = COLOR_LIGHTRED , text = text })
482482 table.insert (message , NEWLINE )
768768config = get_config ()
769769
770770dfhack .onStateChange [' internal/notify/notifications' ] = function (event )
771- if event == SC_WORLD_LOADED or SC_WORLD_UNLOADED or SC_MAP_LOADED or SC_MAP_UNLOADED then
772- Cache_nemesis_all :populate (true )
771+ if event == SC_WORLD_LOADED or event == SC_WORLD_UNLOADED
772+ or event == SC_MAP_LOADED or event == SC_MAP_UNLOADED
773+ then
774+ Cache_nemesis_all :invalidate ()
773775 end
774776end
0 commit comments