From 030bd8ab571a631f955a3ae19813f6adb078e818 Mon Sep 17 00:00:00 2001 From: jj Date: Sun, 12 Aug 2012 00:24:34 +0200 Subject: [PATCH] fix/loyaltycascade: clear the enemy status cache, dont require a save/reload anymore --- plugins/ruby/ruby-autogen-defs.rb | 1 + scripts/fix/loyaltycascade.rb | 31 +++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/plugins/ruby/ruby-autogen-defs.rb b/plugins/ruby/ruby-autogen-defs.rb index 7165e2448..3507508e1 100644 --- a/plugins/ruby/ruby-autogen-defs.rb +++ b/plugins/ruby/ruby-autogen-defs.rb @@ -361,6 +361,7 @@ module DFHack def empty? ; length == 0 ; end def flatten ; map { |e| e.respond_to?(:flatten) ? e.flatten : e }.flatten ; end def index(e=nil, &b) ; (0...length).find { |i| b ? b[self[i]] : self[i] == e } ; end + def map! ; (0...length).each { |i| self[i] = yield(self[i]) } ; end def first ; self[0] ; end def last ; self[length-1] ; end end diff --git a/scripts/fix/loyaltycascade.rb b/scripts/fix/loyaltycascade.rb index 632f8024e..2f987bd55 100644 --- a/scripts/fix/loyaltycascade.rb +++ b/scripts/fix/loyaltycascade.rb @@ -1,10 +1,11 @@ # script to fix loyalty cascade, when you order your militia to kill friendly units -def fixunit(u) - return if u.race != df.ui.race_id or u.civ_id != df.ui.civ_id - links = u.hist_figure_tg.entity_links +def fixunit(unit) + return if unit.race != df.ui.race_id or unit.civ_id != df.ui.civ_id + links = unit.hist_figure_tg.entity_links fixed = false + # check if the unit is a civ renegade if i1 = links.index { |l| l.kind_of?(DFHack::HistfigEntityLinkFormerMemberst) and l.entity_id == df.ui.civ_id @@ -17,9 +18,10 @@ def fixunit(u) links.delete_at i2 links.delete_at i1 links << DFHack::HistfigEntityLinkMemberst.cpp_new(:entity_id => df.ui.civ_id, :link_strength => 100) - df.add_announcement "fixloyalty: #{u.name} is now a member of #{df.ui.civ_tg.name} again" + df.add_announcement "fixloyalty: #{unit.name} is now a member of #{df.ui.civ_tg.name} again" end + # check if the unit is a group renegade if i1 = links.index { |l| l.kind_of?(DFHack::HistfigEntityLinkFormerMemberst) and l.entity_id == df.ui.group_id @@ -32,20 +34,29 @@ def fixunit(u) links.delete_at i2 links.delete_at i1 links << DFHack::HistfigEntityLinkMemberst.cpp_new(:entity_id => df.ui.group_id, :link_strength => 100) - df.add_announcement "fixloyalty: #{u.name} is now a member of #{df.ui.group_tg.name} again" + df.add_announcement "fixloyalty: #{unit.name} is now a member of #{df.ui.group_tg.name} again" end + # fix the 'is an enemy' cache matrix (mark to be recalculated by the game when needed) + if fixed and unit.unknown8.enemy_status_slot != -1 + i = unit.unknown8.enemy_status_slot + unit.unknown8.enemy_status_slot = -1 + df.world.enemy_status_cache.slot_used[i] = false + df.world.enemy_status_cache.rel_map[i].map! { -1 } + df.world.enemy_status_cache.rel_map.each { |a| a[i] = -1 } + end + + # return true if we actually fixed the unit fixed end -fixed = 0 +count = 0 df.unit_citizens.each { |u| - fixed += 1 if fixunit(u) + count += 1 if fixunit(u) } -if fixed > 0 - df.popup_announcement "Fixed a loyalty cascade, you should save and reload now" - puts "loyalty cascade fixed (#{fixed} dwarves), you should save and reload" +if count > 0 + puts "loyalty cascade fixed (#{count} dwarves)" else puts "no loyalty cascade found" end