Skip to content

Commit 08bca25

Browse files
author
s.kushnirenko
committed
fort: correct draw ground tiles if blocked
1 parent 13ca0ad commit 08bca25

File tree

7 files changed

+95
-79
lines changed

7 files changed

+95
-79
lines changed

src/building/building_fort.cpp

+29-35
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,23 @@
66
#include "city/finance.h"
77
#include "building/properties.h"
88
#include "graphics/view/view.h"
9+
#include "graphics/view/lookup.h"
910
#include "grid/grid.h"
1011

1112
#include "graphics/animation.h"
1213
#include "js/js_game.h"
1314
#include "city/labor.h"
1415

15-
constexpr int MAX_TILES = 25;
16-
1716
namespace model {
1817

1918
struct fort_t {
2019
static constexpr e_building_type type = BUILDING_COURTHOUSE;
2120
e_labor_category labor_category;
2221
animations_t anim;
2322
struct {
24-
vec2i main_view_offset[4];
25-
vec2i ground_view_offset[4];
23+
std::vector<vec2i> main_view_offset;
24+
std::vector<vec2i> ground_view_offset;
25+
std::vector<vec2i> ground_check_offset;
2626
} ghost;
2727
};
2828

@@ -37,26 +37,21 @@ void config_load_building_fort() {
3737
model::fort.anim.load(arch);
3838

3939
arch.r_section("ghost", [] (archive ghost_arch) {
40-
model::fort.ghost.main_view_offset[0] = ghost_arch.r_vec2i("main_N");
41-
model::fort.ghost.main_view_offset[1] = ghost_arch.r_vec2i("main_W");
42-
model::fort.ghost.main_view_offset[2] = ghost_arch.r_vec2i("main_S");
43-
model::fort.ghost.main_view_offset[3] = ghost_arch.r_vec2i("main_E");
44-
model::fort.ghost.ground_view_offset[0] = ghost_arch.r_vec2i("ground_N");
45-
model::fort.ghost.ground_view_offset[1] = ghost_arch.r_vec2i("ground_W");
46-
model::fort.ghost.ground_view_offset[2] = ghost_arch.r_vec2i("ground_S");
47-
model::fort.ghost.ground_view_offset[3] = ghost_arch.r_vec2i("ground_E");
40+
model::fort.ghost.main_view_offset = ghost_arch.r_array_vec2i("main");
41+
model::fort.ghost.ground_view_offset = ghost_arch.r_array_vec2i("ground");
42+
model::fort.ghost.ground_check_offset = ghost_arch.r_array_vec2i("ground_check");
4843
});
4944
});
5045

5146
city_labor_set_category(model::fort);
5247
}
5348

54-
static const int FORT_GROUND_GRID_OFFSETS_PH[4][4] = {
55-
{GRID_OFFSET(3, -1), GRID_OFFSET(4, -1), GRID_OFFSET(4, 0), GRID_OFFSET(3, 0)},
56-
{GRID_OFFSET(-1, -4), GRID_OFFSET(0, -4), GRID_OFFSET(0, -3), GRID_OFFSET(-1, -3)},
57-
{GRID_OFFSET(-4, 0), GRID_OFFSET(-3, 0), GRID_OFFSET(-3, 1), GRID_OFFSET(-4, 1)},
58-
{GRID_OFFSET(0, 3), GRID_OFFSET(1, 3), GRID_OFFSET(1, 4), GRID_OFFSET(0, 4)}
59-
};
49+
void draw_partially_blocked(painter &ctx, int fully_blocked, const std::vector<blocked_tile> &blocked_tiles) {
50+
for (auto &tile: blocked_tiles) {
51+
vec2i pixel = tile_to_pixel(tile.tile);
52+
draw_flat_tile(ctx, pixel.x, pixel.y, (fully_blocked || tile.blocked) ? COLOR_MASK_RED : COLOR_MASK_GREEN);
53+
}
54+
}
6055

6156
void draw_fort_ghost(painter &ctx, e_building_type build_type, tile2i &tile, vec2i pixel) {
6257
bool fully_blocked = false;
@@ -66,38 +61,37 @@ void draw_fort_ghost(painter &ctx, e_building_type build_type, tile2i &tile, vec
6661
blocked = true;
6762
}
6863

69-
int num_tiles_fort = building_properties_for_type(BUILDING_FORT_ARCHERS)->size;
70-
num_tiles_fort *= num_tiles_fort;
71-
int num_tiles_ground = building_properties_for_type(BUILDING_FORT_GROUND)->size;
72-
num_tiles_ground *= num_tiles_ground;
64+
int fort_size = building_properties_for_type(BUILDING_FORT_ARCHERS)->size;
65+
int ground_size = building_properties_for_type(BUILDING_FORT_GROUND)->size;
7366

7467
// int grid_offset_fort = tile->grid_offset;
7568
int global_rotation = building_rotation_global_rotation();
76-
int grid_offset_ground = tile.grid_offset() + FORT_GROUND_GRID_OFFSETS_PH[global_rotation][city_view_orientation() / 2];
69+
vec2i tile_ground_offset = model::fort.ghost.ground_check_offset[global_rotation * 4 + (city_view_orientation() / 2)];
70+
tile2i tile_ground = tile.shifted(tile_ground_offset.x, tile_ground_offset.y);
7771

78-
int blocked_tiles_fort[MAX_TILES];
79-
int blocked_tiles_ground[MAX_TILES];
72+
std::vector<blocked_tile> blocked_tiles_fort;
73+
std::vector<blocked_tile> blocked_tiles_ground;
8074

81-
blocked += is_blocked_for_building(tile.grid_offset(), num_tiles_fort, blocked_tiles_fort);
82-
blocked += is_blocked_for_building(grid_offset_ground, num_tiles_ground, blocked_tiles_ground);
75+
blocked += is_blocked_for_building(tile, fort_size, blocked_tiles_fort);
76+
blocked += is_blocked_for_building(tile_ground, ground_size, blocked_tiles_ground);
8377

8478
int orientation_index = building_rotation_get_storage_fort_orientation(global_rotation) / 2;
85-
vec2i main = pixel + model::fort.ghost.main_view_offset[orientation_index];
86-
vec2i ground = pixel + model::fort.ghost.ground_view_offset[orientation_index];
79+
vec2i main_pixel = pixel + model::fort.ghost.main_view_offset[orientation_index];
80+
vec2i ground_pixel = pixel + model::fort.ghost.ground_view_offset[orientation_index];
8781

8882
if (blocked) {
89-
draw_partially_blocked(ctx, pixel, fully_blocked, num_tiles_fort, blocked_tiles_fort);
90-
draw_partially_blocked(ctx, ground, fully_blocked, num_tiles_ground, blocked_tiles_ground);
83+
draw_partially_blocked(ctx, fully_blocked, blocked_tiles_fort);
84+
draw_partially_blocked(ctx, fully_blocked, blocked_tiles_ground);
9185
} else {
9286
int image_id = image_id_from_group(GROUP_BUILDING_FORT);
9387
if (orientation_index == 0 || orientation_index == 3) {
9488
// draw fort first, then ground
95-
draw_building_ghost(ctx, image_id, main);
96-
draw_building_ghost(ctx, image_id + 1, ground);
89+
draw_building_ghost(ctx, image_id, main_pixel);
90+
draw_building_ghost(ctx, image_id + 1, ground_pixel);
9791
} else {
9892
// draw ground first, then fort
99-
draw_building_ghost(ctx, image_id + 1, ground);
100-
draw_building_ghost(ctx, image_id, main);
93+
draw_building_ghost(ctx, image_id + 1, ground_pixel);
94+
draw_building_ghost(ctx, image_id, main_pixel);
10195
}
10296
}
10397
}

src/core/archive.cpp

+27-2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,24 @@ std::vector<std::string> archive::r_array_str(pcstr name) {
9494
return result;
9595
}
9696

97+
std::vector<vec2i> archive::r_array_vec2i(pcstr name) {
98+
auto vm = (js_State *)state;
99+
js_getproperty(vm, -1, name);
100+
std::vector<vec2i> result;
101+
if (js_isarray(vm, -1)) {
102+
int length = js_getlength(vm, -1);
103+
104+
for (int i = 0; i < length; ++i) {
105+
js_getindex(vm, -1, i);
106+
vec2i v = r_vec2i_impl("x", "y");
107+
result.push_back(v);
108+
js_pop(vm, 1);
109+
}
110+
js_pop(vm, 1);
111+
}
112+
return result;
113+
}
114+
97115
int archive::r_int(pcstr name, int def) {
98116
auto vm = (js_State *)state;
99117
js_getproperty(vm, -1, name);
@@ -126,10 +144,9 @@ vec2i archive::r_size2i(pcstr name, pcstr w, pcstr h) {
126144
return r_vec2i(name, w, h);
127145
}
128146

129-
vec2i archive::r_vec2i(pcstr name, pcstr x, pcstr y) {
147+
vec2i archive::r_vec2i_impl(pcstr x, pcstr y) {
130148
auto vm = (js_State *)state;
131149
vec2i result(0, 0);
132-
js_getproperty(vm, -1, name);
133150
if (js_isobject(vm, -1)) {
134151
if (js_isarray(vm, -1)) {
135152
int length = js_getlength(vm, -1);
@@ -144,6 +161,14 @@ vec2i archive::r_vec2i(pcstr name, pcstr x, pcstr y) {
144161
js_getproperty(vm, -1, y); result.y = !js_isundefined(vm, -1) ? js_tointeger(vm, -1) : 0; js_pop(vm, 1);
145162
}
146163
}
164+
165+
return result;
166+
}
167+
168+
vec2i archive::r_vec2i(pcstr name, pcstr x, pcstr y) {
169+
auto vm = (js_State *)state;
170+
js_getproperty(vm, -1, name);
171+
vec2i result = r_vec2i_impl(x, y);
147172
js_pop(vm, 1);
148173

149174
return result;

src/core/archive.h

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ struct archive {
2222
vec2i r_size2i(pcstr name, pcstr w = "w", pcstr h = "h");
2323
vec2i r_vec2i(pcstr name, pcstr x = "x", pcstr y = "y");
2424

25+
std::vector<vec2i> r_array_vec2i(pcstr name);
26+
2527
template<class T>
2628
inline T r_type(pcstr name) { return (T)r_int(name); }
2729

@@ -59,6 +61,8 @@ struct archive {
5961
pop(1);
6062
}
6163

64+
vec2i r_vec2i_impl(pcstr x, pcstr y);
65+
6266
template<typename T>
6367
inline void r_objects(pcstr name, T read_func) {
6468
this->r_section(name, [this, &read_func] (archive s_arch) {

src/scripts/building_info.js

+6-8
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,12 @@ building_big_statue = {
5555

5656
building_fort = {
5757
ghost : {
58-
main_N : [-55, -35],
59-
main_W : [-55, -35],
60-
main_S : [-55, -35],
61-
main_E : [-60, -40],
62-
ground_N : [35, 35],
63-
ground_W : [5, -70],
64-
ground_S : [-200, -55],
65-
ground_E : [-180, 46],
58+
main : [[-55, -35], [-55, -35], [-55, -35], [-60, -40]],
59+
ground : [[35, 35], [5, -70], [-200, -55], [-180, 46]],
60+
ground_check : [[3, -1], [4, -1], [4, 0], [3, 0],
61+
[-1,-4], [0, -4], [0,-3], [-1,-3],
62+
[-4, 0], [-3, 0], [-3,1], [-4, 1],
63+
[0, 3], [1, 3], [1, 4], [0, 4]],
6664
},
6765
labor_category : LABOR_CATEGORY_MILITARY,
6866
}

src/widget/city/building_ghost.cpp

+12-26
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
#define MAX_TILES 25
2929

30-
const vec2i VIEW_OFFSETS[MAX_TILES] = { {0, 0},
30+
const vec2i VIEW_OFFSETS[] = { {0, 0},
3131
{-30,15}, {30, 15}, {0,30},
3232
{-60,30}, {60, 30}, {-30,45}, {30, 45}, {0, 60},
3333
{-90, 45}, {90, 45}, {-60,60}, {60, 60}, {-30,75}, {30, 75}, {0, 90},
@@ -134,42 +134,28 @@ static void get_building_base_xy(int map_x, int map_y, int building_size, int* x
134134
}
135135
}
136136

137-
int is_blocked_for_building(int grid_offset, int num_tiles, int* blocked_tiles) {
137+
int is_blocked_for_building(tile2i tile, int size, std::vector<blocked_tile> &blocked_tiles) {
138138
int orientation_index = city_view_orientation() / 2;
139139
int blocked = 0;
140+
int num_tiles = pow(size, 2);
140141
for (int i = 0; i < num_tiles; i++) {
141-
int tile_offset = grid_offset; // + TILE_GRID_OFFSETS[orientation_index][i];
142-
tile_offset += TILE_GRID_OFFSETS_PH[orientation_index][i];
143-
bool tile_blocked = false;
144-
if (map_terrain_is(tile_offset, TERRAIN_NOT_CLEAR))
145-
tile_blocked = true;
146-
if (map_terrain_count_directly_adjacent_with_type(grid_offset, TERRAIN_FLOODPLAIN) > 0
147-
|| map_terrain_count_diagonally_adjacent_with_type(grid_offset, TERRAIN_FLOODPLAIN) > 0)
148-
tile_blocked = true;
149-
150-
if (map_has_figure_at(tile_offset))
151-
tile_blocked = true;
152-
153-
blocked_tiles[i] = tile_blocked;
142+
int offset = TILE_GRID_OFFSETS_PH[orientation_index][i];
143+
tile2i check_tile = tile.shifted(offset);
144+
bool tile_blocked = map_terrain_is(check_tile, TERRAIN_NOT_CLEAR)
145+
|| (map_terrain_count_directly_adjacent_with_type(check_tile.grid_offset(), TERRAIN_FLOODPLAIN) > 0)
146+
|| (map_terrain_count_diagonally_adjacent_with_type(check_tile.grid_offset(), TERRAIN_FLOODPLAIN) > 0)
147+
|| map_has_figure_at(check_tile);
148+
149+
blocked_tiles.push_back({check_tile, tile_blocked});
154150
blocked += (tile_blocked ? 1 : 0);
155151
}
156152
return blocked;
157153
}
158154

159-
static void draw_flat_tile(painter &ctx, int x, int y, color color_mask) {
155+
void draw_flat_tile(painter &ctx, int x, int y, color color_mask) {
160156
ImageDraw::img_generic(ctx, image_id_from_group(GROUP_TERRAIN_OVERLAY_COLORED), x, y, color_mask);
161157
}
162158

163-
void draw_partially_blocked(painter &ctx, vec2i tile, int fully_blocked, int num_tiles, int* blocked_tiles) {
164-
for (int i = 0; i < num_tiles; i++) {
165-
vec2i offset = tile + VIEW_OFFSETS[i];
166-
if (fully_blocked || blocked_tiles[i])
167-
draw_flat_tile(ctx, offset.x, offset.y, COLOR_MASK_RED);
168-
else
169-
draw_flat_tile(ctx, offset.x, offset.y, COLOR_MASK_GREEN);
170-
}
171-
}
172-
173159
void draw_building_ghost(painter &ctx, e_image_id image_id, vec2i tile, color color_mask) {
174160
int img = image_group(image_id);
175161
ImageDraw::isometric(ctx, img, tile, color_mask);

src/widget/city/building_ghost.h

+11-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@
55
#include "grid/point.h"
66
#include "core/vec2i.h"
77

8+
#include <vector>
9+
810
struct painter;
911

12+
struct blocked_tile {
13+
tile2i tile;
14+
bool blocked;
15+
};
16+
1017
void draw_building_ghost(painter &ctx, e_image_id image_id, vec2i tile, color color_mask = COLOR_MASK_GREEN);
1118
void draw_building_ghost(painter &ctx, int image_id, vec2i tile, color color_mask = COLOR_MASK_GREEN);
12-
int is_blocked_for_building(int grid_offset, int num_tiles, int *blocked_tiles);
13-
void draw_partially_blocked(painter &ctx, vec2i tile, int fully_blocked, int num_tiles, int *blocked_tiles);
19+
int is_blocked_for_building(tile2i tile, int size, std::vector<blocked_tile> &blocked_tiles);
20+
void draw_flat_tile(painter &ctx, int x, int y, color color_mask);
1421
bool city_building_ghost_mark_deleting(tile2i tile);
22+
23+
extern const vec2i VIEW_OFFSETS[];

src/widget/map_editor_tool.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ static void offset_to_view_offset(int dx, int dy, int* view_dx, int* view_dy) {
2222
*view_dy = (dx + dy) * 15;
2323
}
2424

25-
static void draw_flat_tile(vec2i pos, color color_mask) {
25+
static void draw_flat_tile_editor(vec2i pos, color color_mask) {
2626
painter ctx = game.painter();
2727
if (color_mask == COLOR_MASK_GREEN && scenario_property_climate() != CLIMATE_DESERT)
2828
ImageDraw::img_generic(ctx, image_id_from_group(GROUP_TERRAIN_OVERLAY_COLORED), pos, ALPHA_MASK_SEMI_TRANSPARENT & color_mask);
@@ -36,9 +36,9 @@ static void draw_partially_blocked_editor(int x, int y, int num_tiles, int* bloc
3636
int x_offset = x + X_VIEW_OFFSETS[i];
3737
int y_offset = y + Y_VIEW_OFFSETS[i];
3838
if (blocked_tiles[i])
39-
draw_flat_tile(vec2i{x_offset, y_offset}, COLOR_MASK_RED);
39+
draw_flat_tile_editor(vec2i{x_offset, y_offset}, COLOR_MASK_RED);
4040
else {
41-
draw_flat_tile(vec2i{x_offset, y_offset}, COLOR_MASK_GREEN);
41+
draw_flat_tile_editor(vec2i{x_offset, y_offset}, COLOR_MASK_GREEN);
4242
}
4343
}
4444
}
@@ -92,7 +92,7 @@ static void draw_road(painter &ctx, tile2i tile, int x, int y) {
9292
}
9393
}
9494
if (blocked)
95-
draw_flat_tile(vec2i{x, y}, COLOR_MASK_RED);
95+
draw_flat_tile_editor(vec2i{x, y}, COLOR_MASK_RED);
9696
else {
9797
draw_building_image(image_id, x, y);
9898
}
@@ -102,7 +102,7 @@ static void draw_brush_tile(const void* data, int dx, int dy) {
102102
screen_tile* view = (screen_tile*)data;
103103
int view_dx, view_dy;
104104
offset_to_view_offset(dx, dy, &view_dx, &view_dy);
105-
draw_flat_tile(vec2i{view->x + view_dx, view->y + view_dy}, COLOR_MASK_GREEN);
105+
draw_flat_tile_editor(vec2i{view->x + view_dx, view->y + view_dy}, COLOR_MASK_GREEN);
106106
}
107107

108108
static void draw_brush(painter &ctx, tile2i tile, int x, int y) {
@@ -122,7 +122,7 @@ static void draw_access_ramp(tile2i tile, int x, int y) {
122122
}
123123

124124
static void draw_map_flag(int x, int y, int is_ok) {
125-
draw_flat_tile(vec2i{x, y}, is_ok ? COLOR_MASK_GREEN : COLOR_MASK_RED);
125+
draw_flat_tile_editor(vec2i{x, y}, is_ok ? COLOR_MASK_GREEN : COLOR_MASK_RED);
126126
}
127127

128128
void map_editor_tool_draw(painter &ctx, tile2i tile) {

0 commit comments

Comments
 (0)