21
21
#include " window/building/distribution.h"
22
22
#include " graphics/elements/lang_text.h"
23
23
#include " city/labor.h"
24
+ #include " city/city.h"
24
25
#include " js/js_game.h"
25
26
26
27
building_dock::static_params dock_m;
@@ -32,8 +33,6 @@ void building_dock::static_params::load(archive arch) {
32
33
void building_dock::on_create (int orientation) {
33
34
data.dock .orientation = orientation;
34
35
data.dock .trading_goods .one ();
35
-
36
- city_buildings_add_dock ();
37
36
}
38
37
39
38
void building_dock::on_place (int orientation, int variant) {
@@ -44,7 +43,6 @@ void building_dock::on_place(int orientation, int variant) {
44
43
}
45
44
46
45
void building_dock::on_destroy () {
47
- city_buildings_remove_dock ();
48
46
}
49
47
50
48
bool building_dock::can_play_animation () const {
@@ -57,9 +55,8 @@ bool building_dock::can_play_animation() const {
57
55
}
58
56
59
57
void building_dock::update_count () const {
60
- if (num_workers () > 0 && base.has_open_water_access ) {
61
- city_buildings_add_working_dock (id ());
62
- }
58
+ const bool is_active = num_workers () > 0 && base.has_open_water_access ;
59
+ g_city.buildings .track_building (type (), id (), is_active);
63
60
}
64
61
65
62
void building_dock::update_map_orientation (int orientation) {
@@ -215,147 +212,131 @@ void building_dock::toggle_good_accepted(e_resource r) {
215
212
data.dock .trading_goods .flip (r);
216
213
}
217
214
218
- bool building_dock_accepts_ship (int ship_id, int dock_id) {
219
- building_dock* dock = building_get (dock_id)->dcast_dock ();
220
- if (!dock) {
221
- return false ;
222
- }
223
-
215
+ bool building_dock::accepts_ship (int ship_id) {
224
216
figure* f = figure_get (ship_id);
225
217
226
218
empire_city* city = g_empire.city (f->empire_city_id );
227
219
const resource_list resources = city_resource_get_available ();
228
220
int any_acceptance = 0 ;
229
221
for (auto r: resources) {
230
222
if (city->sells_resource [r.type ] || city->buys_resource [r.type ]) {
231
- any_acceptance += dock-> is_trade_accepted (r.type ) ? 1 : 0 ;
223
+ any_acceptance += is_trade_accepted (r.type ) ? 1 : 0 ;
232
224
}
233
225
}
234
226
235
227
return (any_acceptance > 0 );
236
228
}
237
229
230
+ tile2i building_dock::moor_tile () const {
231
+ vec2i offset;
232
+ switch (data.dock .orientation ) {
233
+ case 0 : offset = { 1 , -1 }; break ;
234
+ case 1 : offset = { 3 , 1 }; break ;
235
+ case 2 : offset = { 1 , 3 }; break ;
236
+ default : offset = { -1 , 1 }; break ;
237
+ }
238
+
239
+ return tile ().shifted (offset.x , offset.y );
240
+ }
241
+
242
+ tile2i building_dock::wait_tile () const {
243
+ vec2i offset;
244
+ switch (data.dock .orientation ) {
245
+ case 0 : offset = { 2 , -2 }; break ;
246
+ case 1 : offset = { 4 , 2 }; break ;
247
+ case 2 : offset = { 2 , 4 }; break ;
248
+ default : offset = { -2 , 2 }; break ;
249
+ }
250
+
251
+ return tile ().shifted (offset.x , offset.y );
252
+ }
253
+
254
+ tile2i building_dock::reid_tile () const {
255
+ vec2i offset;
256
+ switch (data.dock .orientation ) {
257
+ case 0 : offset = { 2 , -3 }; break ;
258
+ case 1 : offset = { 5 , 2 }; break ;
259
+ case 2 : offset = { 2 , 5 }; break ;
260
+ default : offset = { -3 , 2 }; break ;
261
+ }
262
+
263
+ return tile ().shifted (offset.x , offset.y );
264
+ }
265
+
238
266
building_dest map_get_free_destination_dock (int ship_id) {
239
- if (!city_buildings_has_working_dock ())
240
- return {0 , tile2i::invalid};
267
+ if (!g_city.buildings .has_working_dock ()) {
268
+ return { 0 , tile2i::invalid };
269
+ }
241
270
242
- int dock_id = 0 ;
243
- for (int i = 0 ; i < 10 ; i++) {
244
- dock_id = city_buildings_get_working_dock (i);
245
- if (!dock_id) {
271
+ const auto &docks = g_city.buildings .track_buildings (BUILDING_DOCK);
272
+ building_dock* better_dock = nullptr ;
273
+ for (const auto &bid: docks) {
274
+ building_dock *dock = ::building_get (bid)->dcast_dock ();
275
+ if (!dock || !dock->num_workers ()) {
246
276
continue ;
247
277
}
248
278
249
- if (!building_dock_accepts_ship (ship_id, dock_id )) {
250
- dock_id = 0 ;
279
+ if (!dock-> accepts_ship (ship_id)) {
280
+ better_dock = nullptr ;
251
281
continue ;
252
282
}
253
283
254
- building* dock = building_get (dock_id) ;
284
+ better_dock = dock ;
255
285
if (!dock->data .dock .trade_ship_id || dock->data .dock .trade_ship_id == ship_id) {
256
286
break ;
257
287
}
258
288
}
259
289
260
290
// BUG: when 10 docks in city, always takes last one... regardless of whether it is free
261
- if (dock_id <= 0 )
262
- return {0 , tile2i::invalid};
263
-
264
- building* dock = building_get (dock_id);
265
- vec2i offset;
266
- switch (dock->data .dock .orientation ) {
267
- case 0 : offset = {1 , -1 }; break ;
268
- case 1 : offset = {3 , 1 }; break ;
269
- case 2 : offset = {1 , 3 }; break ;
270
- default : offset = {-1 , 1 }; break ;
291
+ if (!better_dock) {
292
+ return { 0 , tile2i::invalid };
271
293
}
272
- tile2i dock_tile = dock->tile .shifted (offset.x , offset.y );
273
- tile2i dest_tile;
274
- map_point_store_result (dock_tile, dest_tile);
275
- dock->data .dock .trade_ship_id = ship_id;
276
- return {dock_id, dest_tile};
294
+
295
+ tile2i moor_tile = better_dock->moor_tile ();
296
+ better_dock->data .dock .trade_ship_id = ship_id;
297
+ return {better_dock->id (), moor_tile };
277
298
}
278
299
279
300
building_dest map_get_queue_destination_dock (int ship_id) {
280
- if (!city_buildings_has_working_dock ())
281
- return {0 , tile2i::invalid};
301
+ if (!g_city.buildings .has_working_dock ()) {
302
+ return { 0 , tile2i::invalid };
303
+ }
282
304
283
305
// first queue position
284
- for (int i = 0 ; i < 10 ; i++) {
285
- int dock_id = city_buildings_get_working_dock (i);
286
- if (!dock_id)
306
+ const auto &docks = g_city.buildings .track_buildings (BUILDING_DOCK);
307
+ for (const auto &bid : docks) {
308
+ building_dock *dock = ::building_get (bid)->dcast_dock ();
309
+ if (!dock) {
287
310
continue ;
311
+ }
288
312
289
- if (!building_dock_accepts_ship (ship_id, dock_id)) {
290
- dock_id = 0 ;
313
+ if (!dock->accepts_ship (ship_id)) {
291
314
continue ;
292
315
}
293
- building* dock = building_get (dock_id);
294
- int dx, dy;
295
- switch (dock->data .dock .orientation ) {
296
- case 0 :
297
- dx = 2 ;
298
- dy = -2 ;
299
- break ;
300
- case 1 :
301
- dx = 4 ;
302
- dy = 2 ;
303
- break ;
304
- case 2 :
305
- dx = 2 ;
306
- dy = 4 ;
307
- break ;
308
- default :
309
- dx = -2 ;
310
- dy = 2 ;
311
- break ;
312
- }
313
- tile2i dock_tile = dock->tile .shifted (dx, dy);
314
- tile2i dest_dock;
315
- map_point_store_result (dock_tile, dest_dock);
316
316
317
- if (!map_has_figure_at (dest_dock)) {
318
- return {dock_id, dest_dock};
317
+ tile2i wait_tile = dock->wait_tile ();
318
+ if (!map_has_figure_at (wait_tile)) {
319
+ return {dock->id (), wait_tile};
319
320
}
320
321
}
321
322
322
323
// second queue position
323
- for (int i = 0 ; i < 10 ; i++) {
324
- int dock_id = city_buildings_get_working_dock (i);
325
- if (!dock_id)
324
+ building_dock *better_dock = nullptr ;
325
+ for (const auto &bid : docks) {
326
+ building_dock *dock = ::building_get (bid)->dcast_dock ();
327
+ if (!dock) {
326
328
continue ;
329
+ }
327
330
328
- if (!building_dock_accepts_ship (ship_id, dock_id)) {
329
- dock_id = 0 ;
331
+ if (!dock->accepts_ship (ship_id)) {
330
332
continue ;
331
333
}
332
- building* dock = building_get (dock_id);
333
- int dx, dy;
334
- switch (dock->data .dock .orientation ) {
335
- case 0 :
336
- dx = 2 ;
337
- dy = -3 ;
338
- break ;
339
- case 1 :
340
- dx = 5 ;
341
- dy = 2 ;
342
- break ;
343
- case 2 :
344
- dx = 2 ;
345
- dy = 5 ;
346
- break ;
347
- default :
348
- dx = -3 ;
349
- dy = 2 ;
350
- break ;
351
- }
352
334
353
- tile2i dock_tile = dock->tile .shifted (dx, dy);
354
- tile2i dest_dock;
355
- map_point_store_result (dock_tile, dest_dock);
356
- if (!map_has_figure_at (dest_dock)) {
357
- return {dock_id, dest_dock};
335
+ tile2i reid_tile = dock->reid_tile ();
336
+ if (!map_has_figure_at (reid_tile)) {
337
+ return {dock->id (), reid_tile};
358
338
}
359
339
}
340
+
360
341
return {0 , tile2i::invalid};
361
342
}
0 commit comments