1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
-- This file can be used inside a debug build of widelands or be included in a scenario. It will dump the
-- economy of one player as a campaign data file (.wcd) which can be used in scenarios. The
-- state will be as complete as possible given the limitations of the current
-- state of the Lua engine.
--
-- Usage:
-- Press CTRL + SHIFT + Space to open the debug console (need a debug build for that).
-- dofile("utils/dump_economy.lua")
-- dump_eco(plrnumber, mapname)
-- arg:mapname
-- is a string for the folder in .widelands/campaigns/ where the file will be stored
-- it should be chosen according the map/scenario
-- the name of the file will be e.g. ecodump_player1_tribename.wcd
--
-- Note that constructionsites will be completely ignored.
--
-- The HQ flag of a player will be the base for the graph traversal used. Therefore if he has more
-- than one economy, this script will only dump one of it.
include "scripting/set.lua"
local game = wl.Game()
local map = game.map
local rv
function traverse_economy(plr, flag)
rv = {
details = {},
flags = {},
roads = {},
buildings = {}
}
rv.details[1] = {playerno = plr.number, tribe = plr.tribe_name}
local roads_done = Set:new{}
local flags_done = Set:new{}
local buildings_done = Set:new{}
local flags_to_check = Set:new{flag}
local _find_directions = function(r)
local lf = nil
local f = r.start_flag.fields[1]
local steps = {}
local _step = function (d)
steps[#steps+1] = ("[[%s]]"):format(d)
f, lf = f[d..'n'], f
end
local flag_found = false
while not flag_found do
for idx,nn in ipairs{"r", "br", "bl", "l", "tl", "tr"} do
local n = f[nn .. "n"]
if n.immovable == r and lf ~= n then
_step(nn)
break
elseif n.immovable == r.end_flag then
_step(nn)
flag_found = true
break
end
end
end
return steps
end
local _handle_flag = function (f)
if flags_done:contains(f) then return end
rv.flags[#rv.flags + 1] = {x = f.fields[1].x, y = f.fields[1].y, wares = f:get_wares("all")}
flags_to_check:add(f)
end
local _discover_road = function (r)
if roads_done:contains(r) then return end
rv.roads[#rv.roads + 1] = {x = r.start_flag.fields[1].x, y = r.start_flag.fields[1].y,
dirs = table.concat(_find_directions(r), ','), workers = r:get_workers("all"),
road_type = r.road_type}
roads_done:add(r)
end
local _discover_building = function (b)
if buildings_done:contains(b.fields[1]) then return end
local _inputs = {}
local _wares = {}
local _soldiers = {}
local _workers = {}
if b.get_inputs then
_inputs = b:get_inputs("all")
end
if b.get_wares then
_wares = b:get_wares("all")
end
if b.get_workers then
_workers = b:get_workers("all")
end
if b.get_soldiers then
for descr,n in pairs(b:get_soldiers("all")) do
_soldiers[descr[1] .. descr[2] .. descr[3].. descr[4]] = n
end
end
rv.buildings[#rv.buildings + 1] = {name = b.descr.name, x = b.fields[1].x, y = b.fields[1].y, wares = _wares, inputs = _inputs, workers = _workers, soldiers = _soldiers}
buildings_done:add(b.fields[1])
end
while flags_to_check.size > 0 do
local flag = flags_to_check:pop_at(1)
local f = flag.fields[1]
flags_done:add(flag)
for idx,n in ipairs{f.rn, f.brn, f.bln, f.ln, f.tln, f.trn} do
if n.immovable and n.immovable.owner == plr then
if n.immovable.descr.type_name == "road" or n.immovable.descr.type_name == "waterway" then
local r = n.immovable
if r.start_flag == flag then
_handle_flag(r.end_flag)
_discover_road(r)
elseif r.end_flag == flag then
_handle_flag(r.start_flag)
_discover_road(r)
end
elseif n.immovable.descr.type_name == "constructionsite" or n.immovable.descr.type_name == "dismantlesite" then
print(("IGNORING constructionsite/dismantlesite at %s"):format(tostring(n)))
elseif n.immovable.descr.type_name:sub(-4) == "site" or n.immovable.descr.type_name == "warehouse" then
_discover_building(n.immovable)
else
print("IGNORING immovable type: ", n.immovable.descr.type_name)
end
end
end
end
end
function dump_eco(plrno, mapname)
local plr = game.players[plrno]
local start_flag = map.player_slots[plrno].starting_field.brn.immovable
assert(start_flag.descr.type_name == "flag")
traverse_economy(plr, start_flag)
local folder = mapname
local file = ("ecodump_player"..plrno.."-"..plr.tribe_name)
game:save_campaign_data(folder, file, rv)
end
|