1 Commits

11 changed files with 83 additions and 38 deletions

View File

@@ -17,11 +17,11 @@
22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22 22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22
22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22 22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22
22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22 22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22
22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22 22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,36%8,36%12,36%12,36%4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22
22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22 22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,36%10,36,36,35%5,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22
22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22 22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,36%8,36%12,36%12,36%12,36%14,36,36,36%5,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22
22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22 22,22,22,22,26,40,2,2,2,2,2,2,2,2,36%8,36%6,36%3,36%3,36%3,36%3,36%3,36%3,3%1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22
22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,121!0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22 22,22,22,22,26,40,2,2,2,2,2,2,2,2,36%2,36%1,2,2,2,2,2,2,2,121!0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22
22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,234@0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22 22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,234@0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22
22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22 22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22
22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22 22,22,22,22,26,40,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,44,30,22,22,22,22

BIN
rsrc/graphics/tertrans.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -134,6 +134,7 @@
<xs:element name="arena" type="xs:integer"/> <xs:element name="arena" type="xs:integer"/>
<xs:element name="ground" minOccurs="0" type="xs:integer"/> <xs:element name="ground" minOccurs="0" type="xs:integer"/>
<xs:element name="trim-for" minOccurs="0" type="xs:integer"/> <xs:element name="trim-for" minOccurs="0" type="xs:integer"/>
<xs:element name="tile-with" minOccurs="0" type="xs:integer"/>
<xs:element name="editor" type="editorData" minOccurs="0"/> <xs:element name="editor" type="editorData" minOccurs="0"/>
</xs:all> </xs:all>
<xs:attribute name="id" type="xs:integer" use="required"/> <xs:attribute name="id" type="xs:integer" use="required"/>

View File

@@ -1204,6 +1204,9 @@ void readTerrainFromXml(ticpp::Document&& data, cScenario& scenario) {
ter->GetText(&the_ter.ground_type); ter->GetText(&the_ter.ground_type);
} else if(type == "arena") { } else if(type == "arena") {
ter->GetText(&the_ter.combat_arena); ter->GetText(&the_ter.combat_arena);
} else if(type == "tile-with") {
the_ter.tile_with.emplace_back();
ter->GetText(&the_ter.tile_with.back());
} else if(type == "editor") { } else if(type == "editor") {
Iterator<Element> edit; Iterator<Element> edit;
for(edit = edit.begin(ter.Get()); edit != edit.end(); edit++) { for(edit = edit.begin(ter.Get()); edit != edit.end(); edit++) {
@@ -2133,6 +2136,9 @@ void loadOutMapData(map_data&& data, location which, cScenario& scen) {
break; break;
out.wandering_locs[feat.second] = loc(x,y); out.wandering_locs[feat.second] = loc(x,y);
break; break;
case eMapFeature::VARIANT:
out.variants[x][y] = feat.second;
break;
} }
} }
} }
@@ -2202,6 +2208,9 @@ void loadTownMapData(map_data&& data, int which, cScenario& scen) {
break; break;
town.creatures[feat.second].start_loc = loc(x,y); town.creatures[feat.second].start_loc = loc(x,y);
break; break;
case eMapFeature::VARIANT:
town.variants[x][y] = feat.second;
break;
} }
} }
} }

View File

@@ -75,6 +75,8 @@ map_data load_map(std::istream& fin, bool isTown, std::string name) {
curFeature = eMapFeature::FIELD; curFeature = eMapFeature::FIELD;
} else if(c == '$') { } else if(c == '$') {
curFeature = eMapFeature::CREATURE; curFeature = eMapFeature::CREATURE;
} else if(c == '%') {
curFeature = eMapFeature::VARIANT;
} else if(c == 'h') { } else if(c == 'h') {
vehicle_owned = true; vehicle_owned = true;
curFeature = eMapFeature::HORSE; curFeature = eMapFeature::HORSE;
@@ -165,6 +167,7 @@ void map_data::writeTo(std::ostream& out) {
case eMapFeature::ENTRANCE_WEST: out << '<'; break; case eMapFeature::ENTRANCE_WEST: out << '<'; break;
case eMapFeature::BOAT: out << (feat.second > 0 ? 'b' : 'B') << abs(feat.second); break; case eMapFeature::BOAT: out << (feat.second > 0 ? 'b' : 'B') << abs(feat.second); break;
case eMapFeature::HORSE: out << (feat.second > 0 ? 'h' : 'H') << abs(feat.second); break; case eMapFeature::HORSE: out << (feat.second > 0 ? 'h' : 'H') << abs(feat.second); break;
case eMapFeature::VARIANT: out << '%' << feat.second; break;
} }
} }
} }

View File

@@ -29,6 +29,7 @@ enum class eMapFeature {
ITEM, ITEM,
CREATURE, CREATURE,
FIELD, FIELD,
VARIANT,
}; };
class map_data { class map_data {

View File

@@ -29,7 +29,7 @@ enum {
class cArea { class cArea {
public: public:
const size_t max_dim; const size_t max_dim;
vector2d<ter_num_t> terrain; vector2d<ter_num_t> terrain, variants;
std::vector<spec_loc_t> special_locs; std::vector<spec_loc_t> special_locs;
std::vector<sign_loc_t> sign_locs; std::vector<sign_loc_t> sign_locs;
std::vector<info_rect_t> area_desc; std::vector<info_rect_t> area_desc;
@@ -41,6 +41,7 @@ public:
explicit cArea(size_t dim) explicit cArea(size_t dim)
: max_dim(dim) : max_dim(dim)
, terrain(dim, dim) , terrain(dim, dim)
, variants(dim, dim)
, maps(dim, boost::dynamic_bitset<>(dim)) , maps(dim, boost::dynamic_bitset<>(dim))
{} {}

View File

@@ -44,10 +44,10 @@ public:
location obj_size; // editor use only location obj_size; // editor use only
pic_num_t map_pic = -1; pic_num_t map_pic = -1;
unsigned short i; // for temporary use in porting unsigned short i; // for temporary use in porting
std::vector<ter_num_t> tile_with;
bool blocksMove() const; bool blocksMove() const;
void import_legacy(legacy::terrain_type_type& old); void import_legacy(legacy::terrain_type_type& old);
void writeTo(std::ostream& file) const;
}; };
#endif #endif

View File

@@ -744,41 +744,48 @@ rectangle visible_bounds() {
} }
} }
static ter_num_t ter_at(int q, int r) { struct ter_pos_t {
ter_num_t t_to_draw; cArea* area;
int x, y;
ter_num_t get() const {
return area ? 90 : area->terrain(x,y);
}
};
static ter_pos_t ter_at(int q, int r) {
rectangle bounds = visible_bounds(); rectangle bounds = visible_bounds();
if(editing_town) { if(editing_town) {
t_to_draw = town->terrain(bounds.left + q, bounds.top + r); return {town, bounds.left + q, bounds.top + r};
} }
else { else {
short ter_x = bounds.left + q, ter_y = bounds.top + r; short ter_x = bounds.left + q, ter_y = bounds.top + r;
if(ter_x == -1 && ter_y == -1 && cur_out.x > 0 && cur_out.y > 0) if(ter_x == -1 && ter_y == -1 && cur_out.x > 0 && cur_out.y > 0)
t_to_draw = scenario.outdoors[cur_out.x - 1][cur_out.y - 1]->terrain[47][47]; return {scenario.outdoors[cur_out.x - 1][cur_out.y - 1], 47, 47};
else if(ter_x == -1 && ter_y == 48 && cur_out.x > 0 && cur_out.y < scenario.outdoors.height() - 1) else if(ter_x == -1 && ter_y == 48 && cur_out.x > 0 && cur_out.y < scenario.outdoors.height() - 1)
t_to_draw = scenario.outdoors[cur_out.x - 1][cur_out.y + 1]->terrain[47][0]; return {scenario.outdoors[cur_out.x - 1][cur_out.y + 1], 47, 0};
else if(ter_x == 48 && ter_y == -1 && cur_out.x < scenario.outdoors.width() - 1 && cur_out.y > 0) else if(ter_x == 48 && ter_y == -1 && cur_out.x < scenario.outdoors.width() - 1 && cur_out.y > 0)
t_to_draw = scenario.outdoors[cur_out.x + 1][cur_out.y - 1]->terrain[0][47]; return {scenario.outdoors[cur_out.x + 1][cur_out.y - 1], 0, 47};
else if(ter_x == 48 && ter_y == 48 && cur_out.x < scenario.outdoors.width() - 1 && cur_out.y < scenario.outdoors.height() - 1) else if(ter_x == 48 && ter_y == 48 && cur_out.x < scenario.outdoors.width() - 1 && cur_out.y < scenario.outdoors.height() - 1)
t_to_draw = scenario.outdoors[cur_out.x + 1][cur_out.y + 1]->terrain[0][0]; return {scenario.outdoors[cur_out.x + 1][cur_out.y + 1], 0, 0};
else if(ter_x == -1 && ter_y >= 0 && ter_y < 48 && cur_out.x > 0) else if(ter_x == -1 && ter_y >= 0 && ter_y < 48 && cur_out.x > 0)
t_to_draw = scenario.outdoors[cur_out.x - 1][cur_out.y]->terrain[47][ter_y]; return {scenario.outdoors[cur_out.x - 1][cur_out.y], 47, ter_y};
else if(ter_y == -1 && ter_x >= 0 && ter_x < 48 && cur_out.y > 0) else if(ter_y == -1 && ter_x >= 0 && ter_x < 48 && cur_out.y > 0)
t_to_draw = scenario.outdoors[cur_out.x][cur_out.y - 1]->terrain[ter_x][47]; return {scenario.outdoors[cur_out.x][cur_out.y - 1], ter_x, 47};
else if(ter_x == 48 && ter_y >= 0 && ter_y < 48 && cur_out.x < scenario.outdoors.width() - 1) else if(ter_x == 48 && ter_y >= 0 && ter_y < 48 && cur_out.x < scenario.outdoors.width() - 1)
t_to_draw = scenario.outdoors[cur_out.x + 1][cur_out.y]->terrain[0][ter_y]; return {scenario.outdoors[cur_out.x + 1][cur_out.y], 0, ter_y};
else if(ter_y == 48 && ter_x >= 0 && ter_x < 48 && cur_out.y < scenario.outdoors.height() - 1) else if(ter_y == 48 && ter_x >= 0 && ter_x < 48 && cur_out.y < scenario.outdoors.height() - 1)
t_to_draw = scenario.outdoors[cur_out.x][cur_out.y + 1]->terrain[ter_x][0]; return {scenario.outdoors[cur_out.x][cur_out.y + 1], ter_x, 0};
else if(ter_x == -1 || ter_x == 48 || ter_y == -1 || ter_y == 48) else if(ter_x == -1 || ter_x == 48 || ter_y == -1 || ter_y == 48)
t_to_draw = 90; return {nullptr};
else t_to_draw = current_terrain->terrain[ter_x][ter_y]; else return {current_terrain, ter_x, ter_y};
} }
return t_to_draw;
} }
static void draw_one_terrain_spot (short i,short j,ter_pos_t terrain_to_draw);
static void draw_one_tiny_terrain_spot (short i,short j,ter_pos_t terrain_to_draw,short size,bool road);
void draw_terrain(){ void draw_terrain(){
location which_pt,where_draw; location which_pt,where_draw;
rectangle draw_rect,clipping_rect = {8,8,332,260}; rectangle draw_rect,clipping_rect = {8,8,332,260};
ter_num_t t_to_draw;
rectangle source_rect,tiny_to,tiny_to_base = {37,29,44,36},from_rect,to_rect; rectangle source_rect,tiny_to,tiny_to_base = {37,29,44,36},from_rect,to_rect;
rectangle boat_rect = {0,0,36,28}; rectangle boat_rect = {0,0,36,28};
tiny_to_base.offset(TER_RECT_UL_X,TER_RECT_UL_Y); tiny_to_base.offset(TER_RECT_UL_X,TER_RECT_UL_Y);
@@ -794,7 +801,7 @@ void draw_terrain(){
for(short r = 0; r < 9; r++) { for(short r = 0; r < 9; r++) {
where_draw.x = q; where_draw.x = q;
where_draw.y = r; where_draw.y = r;
t_to_draw = ter_at(q, r); auto t_to_draw = ter_at(q, r);
draw_one_terrain_spot(q,r,t_to_draw); draw_one_terrain_spot(q,r,t_to_draw);
rectangle destrec; rectangle destrec;
@@ -885,7 +892,7 @@ void draw_terrain(){
tiny_to.offset(28 * q, 36 * r); tiny_to.offset(28 * q, 36 * r);
// Tiny icons // Tiny icons
std::vector<short> icons = get_small_icons(loc(cen_x + q - 4, cen_y + r - 4), t_to_draw); std::vector<short> icons = get_small_icons(loc(cen_x + q - 4, cen_y + r - 4), t_to_draw.get());
if(!icons.empty()) { if(!icons.empty()) {
bool has_start = icons[0] == -1; bool has_start = icons[0] == -1;
@@ -1037,9 +1044,9 @@ void draw_terrain(){
for(short r = 0; r < bounds.height(); r++) { for(short r = 0; r < bounds.height(); r++) {
if(q + bounds.left > max) continue; if(q + bounds.left > max) continue;
if(r + bounds.top > max) continue; if(r + bounds.top > max) continue;
t_to_draw = ter_at(q, r); auto t_to_draw = ter_at(q, r);
draw_one_tiny_terrain_spot(q,r,t_to_draw,size,is_road(q+bounds.left,r+bounds.top)); draw_one_tiny_terrain_spot(q,r,t_to_draw,size,is_road(q+bounds.left,r+bounds.top));
small_what_drawn[q][r] = t_to_draw; small_what_drawn[q][r] = t_to_draw.get();
} }
small_any_drawn = true; small_any_drawn = true;
} }
@@ -1162,24 +1169,47 @@ void force_tiny_redraw() {
} }
void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw) { static void draw_one_terrain_spot (short i,short j,ter_pos_t terrain_to_draw) {
location where_draw; location where_draw;
rectangle source_rect; rectangle source_rect;
short picture_wanted; short picture_wanted = -1;
ter_num_t t_type;
std::shared_ptr<const sf::Texture> source_gworld; std::shared_ptr<const sf::Texture> source_gworld;
if(i < 0 || i > 8 || j < 0 || j > 8) if(i < 0 || i > 8 || j < 0 || j > 8)
return; return;
picture_wanted = scenario.ter_types[terrain_to_draw].picture; bool is_transition = false;
if(terrain_to_draw.area == nullptr) {
t_type = 90;
picture_wanted = 74;
} else {
int x = terrain_to_draw.x, y = terrain_to_draw.y;
t_type = terrain_to_draw.area->terrain[x][y];
int variation = terrain_to_draw.area->variants[x][y];
if(variation == 0) {
picture_wanted = scenario.ter_types[t_type].picture;
} else {
is_transition = true;
if(picture_wanted >= 1000) {
source_gworld = &ResMgr::graphics.get("sheet" + std::to_string(picture_wanted));
} else {
source_gworld = &ResMgr::graphics.get("tertrans");
}
source_rect.left = 28 * (variation - 1);
source_rect.right = 28 * variation;
source_rect.top = 0;
source_rect.bottom = 36;
}
}
where_draw.x = (char) i; where_draw.x = (char) i;
where_draw.y = (char) j; where_draw.y = (char) j;
if(picture_wanted >= 1000 && spec_scen_g) { if(!is_transition && picture_wanted >= 1000 && spec_scen_g) {
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000); graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000);
} }
else if(picture_wanted >= 960) { else if(!is_transition && picture_wanted >= 960) {
source_gworld = &ResMgr::graphics.get("teranim"); source_gworld = &ResMgr::graphics.get("teranim");
picture_wanted -= 960; picture_wanted -= 960;
source_rect.left = 112 * (picture_wanted / 5); source_rect.left = 112 * (picture_wanted / 5);
@@ -1187,8 +1217,8 @@ void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw) {
source_rect.top = 36 * (picture_wanted % 5); source_rect.top = 36 * (picture_wanted % 5);
source_rect.bottom = source_rect.top + 36; source_rect.bottom = source_rect.top + 36;
} }
else { else if(!is_transition && picture_wanted >= 0) {
source_rect = get_template_rect(terrain_to_draw); source_rect = get_template_rect(t_type);
int which_sheet = picture_wanted / 50; int which_sheet = picture_wanted / 50;
source_gworld = &ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)); source_gworld = &ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet));
} }
@@ -1203,16 +1233,16 @@ void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw) {
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), destrec); rect_draw_some_item(*source_gworld, source_rect, mainPtr(), destrec);
} }
void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw,short size,bool road) { void draw_one_tiny_terrain_spot (short i,short j,ter_pos_t terrain_to_draw,short size,bool road) {
rectangle dest_rect = {0,0,size,size},from_rect = {0,0,12,12}; rectangle dest_rect = {0,0,size,size},from_rect = {0,0,12,12};
short picture_wanted; short picture_wanted;
bool drawLargeIcon = false; bool drawLargeIcon = false;
std::shared_ptr<const sf::Texture> source_gworld; std::shared_ptr<const sf::Texture> source_gworld;
picture_wanted = scenario.ter_types[terrain_to_draw].map_pic; picture_wanted = scenario.ter_types[terrain_to_draw.get()].map_pic;
if(picture_wanted == NO_PIC) { if(picture_wanted == NO_PIC) {
drawLargeIcon = true; drawLargeIcon = true;
picture_wanted = scenario.ter_types[terrain_to_draw].picture; picture_wanted = scenario.ter_types[terrain_to_draw.get()].picture;
} }
dest_rect.offset(8 + TER_RECT_UL_X + size * i, 8 + TER_RECT_UL_Y + size * j); dest_rect.offset(8 + TER_RECT_UL_X + size * i, 8 + TER_RECT_UL_Y + size * j);

View File

@@ -18,7 +18,7 @@ void draw_terrain();
void draw_monsts(); void draw_monsts();
void draw_items(); void draw_items();
void force_tiny_redraw(); void force_tiny_redraw();
void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw); //void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw);
void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw,short size,bool road); void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw,short size,bool road);
rectangle get_template_rect (unsigned short type_wanted); rectangle get_template_rect (unsigned short type_wanted);
void draw_frames(); void draw_frames();

View File

@@ -1555,7 +1555,7 @@ void set_current_town(int to, bool first_restore) {
store_current_terrain_state(); store_current_terrain_state();
} }
if(to < 0 || to >= scenario.towns.size()) return; if(to < 0 || to >= scenario.towns.size()) to = 0;
cur_town = to; cur_town = to;
town = scenario.towns[cur_town]; town = scenario.towns[cur_town];
scenario.editor_state.last_town_edited = cur_town; scenario.editor_state.last_town_edited = cur_town;