--[[nef_20230424 CITY_STEAL The function stolen can be used to keep track of cities that have had tech stolen by a diplomat. Arguments: 1. City. a. nil (default). List cities that have had a tech stolen (and by whom). b. boolean false. Delete all current 'stolen' records(with 2b.). (Dubious use.) c. userdata or a featured text string defining a City. 2. Action to be taken: a. nil (default). Show current state of the City. b. Boolean false. Mark the City as having had no tech stolen . (Not recommended.) c. Anything else. Mark the City as having had tech stolen. (Not recommended.) To delete the list both arguments need to be boolean false. The module should be loaded into an autoscript to start recording without any delays. Requires FEATURED_TEXT, PARSER, and SUPPORT_continuity. ]] if signal then -- CITY_STEAL -- SOH local featured = setmetatable({},{ -- FEATURED_TEXT __index = function(t,k) local ft = assert(log.featured, 'Featured text not loaded') return assert(ft[k], 'Featured '..k..' not loaded.' ) end;}) local function link (...) link = featured.link; return link (...) end local function bbcode(...) bbcode = featured.bbcode; return bbcode (...) end local SP = setmetatable({},{ -- SUPPORT_basic __index = function(t,k) local SP = assert(game.SP, 'Support package not loaded') return assert(SP[k], 'Support '..k..' not loaded.') end;}) local function user (...) user = SP.user; return user (...) end local function colored_link(...) colored_link = SP.colored_link; return colored_link(...) end -- SUPPORT_extended local function get_link_bb(...) get_link_bb = SP.get_link_bb; return get_link_bb (...) end -- SUPPORT_continuity local function tables(...) tables = SP.tables; return tables(...) end local MTs = setmetatable({}, {__newindex = function(t,k,v) rawset(t,k,v); v._fc_keep = true end}) local get = setmetatable({}, { __index = function(t,k) t[k] = tables(k, MTs) return t[k] end; __call = function(t,k) t[k] = tables(k) return t[k] end; }) -- STX local reporter = function(tile,msg,...) notify.event(user(),tile,msg,...) end local report = function(tile,...) reporter(tile,E.BROADCAST_REPORT,...) end MTs.stolen = {__call = function (t,k) return t[k] and '' or 'NOT ' end;} function stolen (object, option); object = get_link_bb(object) local stolen = get.stolen if false then elseif tolua.type(object) == 'City' then if option ~= nil then watch(stolen, object, option and user() or nil) end report(object.tile,'Tech %s stolen from %s',stolen(object),colored_link(object)) elseif object == nil then local r_player = type (option) == 'number' and find.player(option) local function p_report(...); p_report = report p_report(nil, bbcode ("b","Tech stolen cities.").. ((' %s'):format (r_player or ''))); p_report(...) end for object, player in pairs (stolen) do if object:exists() and not r_player or r_player == player then p_report(object.tile, colored_link(object).. (' %s'):format (not r_player and player or '')) end end; if p_report ~= report then report(nil, "No tech stolen cities") end elseif object == false and option == false then get 'stolen' else report(nil, 'Argument not a city reference') end end do_signals = function (signals, active) local signal = signal [active and 'replace' or 'remove'] for Signal, callback in pairs(signals) do signal(Signal, callback) end return active end local CBs = setmetatable({ city_destroyed = '.tech_steal_dies'; -- 10 action_started_unit_city = '.tech_steal_action'; -- 20 },{ __call = do_signals}) local CB_research = setmetatable({ tech_researched = '.tech_steal_city'; -- 9 },{ __call = do_signals}) local CB_unit_steal = setmetatable({ unit_lost = '.tech_steal_unit'; -- 14 },{ __call = do_signals}) do -- startup CBs(true) end do -- callbacks local tech_unit, tech_city -- 10 city_destroyed (City, Player (loser), Player (destroyer)) _ENV[CBs.city_destroyed] = function (city); get.stolen[city] = nil; end -- 20 action_started_unit_city (string (Action rule_name), Unit (actor), City (target)) _ENV[CBs.action_started_unit_city] = function (action, unit, city) if CB_research(action:rule_name()=='Steal Tech') then tech_unit, tech_city = unit, city; end end -- 9 tech_researched (Tech_Type, Player, string) _ENV[CB_research.tech_researched] = function (Tech_Type, winner, reason) CB_research(false) CB_unit_steal(reason == "stolen" and tech_unit.owner == winner) end; -- 14 unit_lost (Unit, Player (loser), string) _ENV[CB_unit_steal.unit_lost] = function (unit, loser, reason) CB_unit_steal(false) if reason == "used" and tech_unit == unit then get.stolen[tech_city] = loser -- notify.embassies (tech_city.owner, tech_city.tile, E.BROADCAST_REPORT, -- '%s %s %s %s' .. -- ' %s %s', -- colored_link(tech_city), reason, game.turn(), unit.owner, -- tech_unit, unit, -- nil) end end end --ETX end -------- end CITY_STEAL