1960 lines
70 KiB
C++
1960 lines
70 KiB
C++
|
||
#include <cstdio>
|
||
#include <sstream>
|
||
#include <cstring>
|
||
#include "scen.global.hpp"
|
||
#include "scenario/scenario.hpp"
|
||
#include "gfx/gfxsheets.hpp"
|
||
#include "gfx/render_image.hpp"
|
||
#include "gfx/render_shapes.hpp"
|
||
#include "gfx/render_text.hpp"
|
||
#include "gfx/tiling.hpp" // for bg
|
||
#include "scen.graphics.hpp"
|
||
#include <cmath>
|
||
#include "scen.keydlgs.hpp"
|
||
#include "sounds.hpp"
|
||
#include "mathutil.hpp"
|
||
#include "tools/drawable_manager.hpp"
|
||
#include "tools/cursors.hpp"
|
||
#include "tools/winutil.hpp"
|
||
#include <boost/variant.hpp>
|
||
#include <boost/algorithm/string.hpp>
|
||
#include "dialogxml/widgets/field.hpp"
|
||
|
||
#include "dialogxml/dialogs/dialog.hpp"
|
||
|
||
#include "scen.core.hpp"
|
||
#include "scen.menus.hpp"
|
||
#include "scen.townout.hpp"
|
||
#include "dialogxml/widgets/scrollbar.hpp"
|
||
#include "fileio/resmgr/res_image.hpp"
|
||
|
||
#include "scen.btnmg.hpp"
|
||
|
||
void load_terrain_template();
|
||
short terrain_in_index();
|
||
void put_terrain_in_template();
|
||
void undo_clip();
|
||
|
||
short find_index_spot();
|
||
bool is_s_d();
|
||
void sort_specials();
|
||
|
||
extern cOutdoors* current_terrain;
|
||
extern sf::View mainView;
|
||
extern cDrawableManager drawable_mgr;
|
||
extern cTown* current_town;
|
||
extern short cen_x, cen_y,current_terrain_type,cur_town;
|
||
extern cTown* town;
|
||
extern short cur_viewing_mode;
|
||
extern eScenMode overall_mode;
|
||
eDrawMode draw_mode = DRAW_TERRAIN;
|
||
extern short available_dlog_buttons[NUM_DLOG_B];
|
||
extern bool editing_town;
|
||
extern cScenario scenario;
|
||
extern sf::Texture bg_gworld;
|
||
extern rectangle right_buttons[NRSONPAGE];
|
||
extern rectangle right_scrollbar_rect;
|
||
extern std::shared_ptr<cScrollbar> right_sbar, pal_sbar;
|
||
extern std::shared_ptr<cTextField> palette_search_field;
|
||
extern rectangle search_field_text_rect;
|
||
extern boost::variant<boost::none_t, std::pair<long,bool>, cTownperson, cTown::cItem, vector2d<ter_num_t>> clipboard;
|
||
|
||
extern bool left_buttons_active,right_buttons_active;
|
||
extern std::array<lb_t,NLS> left_button_status;
|
||
extern std::vector<rb_t> right_button_status;
|
||
short mini_map_scales[3] = {12, 6, 4};
|
||
// TODO: What is this for?
|
||
//extern btn_t buttons[];
|
||
extern location cur_out, mouse_spot;
|
||
extern ter_num_t current_ground;
|
||
extern short right_button_hovered;
|
||
|
||
short num_ir[3] = {12,10,4};
|
||
|
||
cCustomGraphics spec_scen_g;
|
||
const sf::Color hilite_colour = {0xff, 0x00, 0x80, 0x40};
|
||
|
||
// begin new stuff
|
||
rectangle blue_button_from = {120,235,134,251};
|
||
rectangle start_button_from = {120,70,127,91};
|
||
rectangle base_small_button_from = {120,0,127,7};
|
||
extern rectangle palette_buttons[10][6];
|
||
extern ePalBtn town_buttons[6][10], out_buttons[6][10];
|
||
rectangle palette_button_base = {0,0,18,26};
|
||
rectangle terrain_buttons_rect = {0,0,410,294};
|
||
rectangle terrain_buttons_rect_editing = {0,0,610,294};
|
||
extern rectangle left_buttons[NLS][2]; // 0 - whole, 1 - blue button
|
||
rectangle left_button_base = {5,5,21,280};
|
||
rectangle right_button_base = {RIGHT_AREA_UL_Y,RIGHT_AREA_UL_X,17,RIGHT_AREA_UL_Y};
|
||
rectangle terrain_rect = {0,0,340,272};
|
||
std::string current_string[2];
|
||
extern rectangle terrain_rects[16*TYPE_ROWS_EDITING];
|
||
|
||
unsigned char small_what_drawn[64][64];
|
||
extern bool small_any_drawn;
|
||
|
||
// These are at the bottom of edbuttons.png:
|
||
static short get_small_icon(ter_num_t ter){
|
||
short icon = -1;
|
||
switch(scenario.ter_types[ter].special){
|
||
case eTerSpec::NONE:
|
||
icon = scenario.ter_types[ter].flag1;
|
||
break;
|
||
case eTerSpec::CHANGE_WHEN_STEP_ON:
|
||
icon = 87;
|
||
break;
|
||
case eTerSpec::DAMAGING:
|
||
switch(eDamageType(scenario.ter_types[ter].flag3)) {
|
||
case eDamageType::WEAPON:
|
||
icon = 16;
|
||
break;
|
||
case eDamageType::FIRE:
|
||
icon = 18;
|
||
break;
|
||
case eDamageType::POISON:
|
||
icon = 17;
|
||
break;
|
||
case eDamageType::ACID:
|
||
icon = 24; // green with black spots, doesn't seem to be used elsewhere
|
||
break;
|
||
case eDamageType::MAGIC:
|
||
icon = 20;
|
||
break;
|
||
case eDamageType::SPECIAL:
|
||
icon = 22;
|
||
break;
|
||
case eDamageType::UNBLOCKABLE:
|
||
icon = 21;
|
||
break;
|
||
case eDamageType::COLD:
|
||
icon = 19;
|
||
break;
|
||
case eDamageType::UNDEAD:
|
||
icon = 25;
|
||
break;
|
||
case eDamageType::DEMON:
|
||
icon = 23;
|
||
break;
|
||
case eDamageType::MARKED: // Invalid
|
||
break;
|
||
}
|
||
break;
|
||
case eTerSpec::BRIDGE:
|
||
icon = 82;
|
||
break;
|
||
case eTerSpec::BED:
|
||
icon = -1;
|
||
break;
|
||
case eTerSpec::DANGEROUS:
|
||
icon = 12;
|
||
switch((eStatus)scenario.ter_types[ter].flag3){
|
||
case eStatus::POISONED_WEAPON: // TODO: Do something here
|
||
break;
|
||
case eStatus::BLESS_CURSE:
|
||
icon = scenario.ter_types[ter].flag1 > 0 ? 4 : 5;
|
||
break;
|
||
case eStatus::POISON:
|
||
if(scenario.ter_types[ter].flag1 > 0)
|
||
icon = 1;
|
||
break;
|
||
case eStatus::HASTE_SLOW:
|
||
icon = scenario.ter_types[ter].flag1 > 0 ? 6 : 7;
|
||
break;
|
||
case eStatus::INVULNERABLE: // TODO: Do something here
|
||
break;
|
||
case eStatus::MAGIC_RESISTANCE: // TODO: Do something here
|
||
break;
|
||
case eStatus::WEBS:
|
||
if(scenario.ter_types[ter].flag1 > 0)
|
||
icon = 52;
|
||
break;
|
||
case eStatus::DISEASE:
|
||
if(scenario.ter_types[ter].flag1 > 0)
|
||
icon = 0;
|
||
break;
|
||
case eStatus::INVISIBLE: // TODO: Do something here
|
||
break;
|
||
case eStatus::DUMB:
|
||
icon = scenario.ter_types[ter].flag1 > 0 ? 8 : 9;
|
||
break;
|
||
case eStatus::MARTYRS_SHIELD: // TODO: Do something here
|
||
break;
|
||
case eStatus::ASLEEP:
|
||
if(scenario.ter_types[ter].flag1 > 0)
|
||
icon = 3;
|
||
break;
|
||
case eStatus::PARALYZED: // TODO: Do something here
|
||
break;
|
||
case eStatus::ACID:
|
||
if(scenario.ter_types[ter].flag1 > 0)
|
||
icon = 2;
|
||
break;
|
||
case eStatus::FORCECAGE:
|
||
if(scenario.ter_types[ter].flag1 > 0)
|
||
icon = 43;
|
||
break;
|
||
case eStatus::MAIN: case eStatus::CHARM:
|
||
icon = -1;
|
||
break; // Nothing to do here; these values are "magic" and should not be used
|
||
}
|
||
break;
|
||
case eTerSpec::CRUMBLING:
|
||
icon = 98;
|
||
break;
|
||
case eTerSpec::LOCKABLE:
|
||
icon = 94;
|
||
break;
|
||
case eTerSpec::UNLOCKABLE:
|
||
if(scenario.ter_types[ter].flag2 >= 5)
|
||
icon = (scenario.ter_types[ter].flag2 == 10) ? 96 : 95;
|
||
else icon = 94;
|
||
break;
|
||
case eTerSpec::IS_A_SIGN:
|
||
icon = 92;
|
||
break;
|
||
case eTerSpec::CALL_SPECIAL:
|
||
case eTerSpec::CALL_SPECIAL_WHEN_USED:
|
||
icon = scenario.ter_types[ter].flag3;
|
||
break;
|
||
case eTerSpec::IS_A_CONTAINER:
|
||
icon = 93;
|
||
break;
|
||
case eTerSpec::WATERFALL_CAVE:
|
||
case eTerSpec::WATERFALL_SURFACE:
|
||
icon = 91;
|
||
break;
|
||
case eTerSpec::CONVEYOR:
|
||
switch(scenario.ter_types[ter].flag1){
|
||
case DIR_N:
|
||
icon = 78;
|
||
break;
|
||
case DIR_NE:
|
||
icon = 79;
|
||
break;
|
||
case DIR_NW:
|
||
icon = 77;
|
||
break;
|
||
case DIR_E:
|
||
icon = 80;
|
||
break;
|
||
case DIR_S:
|
||
icon = 74;
|
||
break;
|
||
case DIR_SE:
|
||
icon = 81;
|
||
break;
|
||
case DIR_SW:
|
||
icon = 75;
|
||
break;
|
||
case DIR_W:
|
||
icon = 76;
|
||
break;
|
||
}
|
||
break;
|
||
case eTerSpec::BLOCKED_TO_MONSTERS:
|
||
icon = 28;
|
||
break;
|
||
case eTerSpec::TOWN_ENTRANCE:
|
||
icon = 84;
|
||
break;
|
||
case eTerSpec::CHANGE_WHEN_USED:
|
||
icon = 97;
|
||
break;
|
||
case eTerSpec::WILDERNESS_CAVE:
|
||
case eTerSpec::WILDERNESS_SURFACE:
|
||
icon = 90;
|
||
break;
|
||
default:
|
||
icon = -1;
|
||
}
|
||
if(icon == 255) icon = -1;
|
||
return icon;
|
||
}
|
||
|
||
static std::vector<short> get_small_icons(location at, ter_num_t t_to_draw) {
|
||
std::vector<short> icons;
|
||
// draw start icon, if starting point
|
||
if(editing_town && cur_town == scenario.which_town_start && scenario.where_start == at) {
|
||
icons.push_back(-1);
|
||
}
|
||
if(!editing_town && scenario.out_sec_start == cur_out && scenario.out_start == at) {
|
||
icons.push_back(-1);
|
||
}
|
||
short ter_small_i = get_small_icon(t_to_draw);
|
||
// Special case for towns
|
||
if(ter_small_i == 84 && !editing_town) {
|
||
bool have_town = false;
|
||
for(size_t i = 0; i < current_terrain->city_locs.size(); i++) {
|
||
if(current_terrain->city_locs[i] == at)
|
||
have_town = true;
|
||
}
|
||
if(!have_town) ter_small_i++;
|
||
}
|
||
if(ter_small_i >= 0)
|
||
icons.push_back(ter_small_i);
|
||
|
||
if(is_special(at.x, at.y)) {
|
||
std::vector<spec_loc_t>& spec_list = get_current_area()->special_locs;
|
||
int num_spec = std::count_if(spec_list.begin(), spec_list.end(), [at](spec_loc_t which) {
|
||
return which.spec >= 0 && which.x == at.x && which.y == at.y;
|
||
});
|
||
if(num_spec > 1)
|
||
icons.push_back(89);
|
||
else icons.push_back(88);
|
||
}
|
||
if(editing_town) {
|
||
if(scenario.ter_types[t_to_draw].light_radius > 0)
|
||
icons.push_back(83);
|
||
for(size_t i = 0; i < town->start_locs.size(); i++)
|
||
if(at == town->start_locs[i]) {
|
||
icons.push_back(70 + i);
|
||
}
|
||
for(size_t i = 0; i < town->wandering_locs.size(); i++)
|
||
if(at == town->wandering_locs[i]) {
|
||
icons.push_back(86);
|
||
}
|
||
if(is_field_type(at.x, at.y, BARRIER_FIRE)) {
|
||
icons.push_back(33);
|
||
}
|
||
if(is_field_type(at.x, at.y, BARRIER_FORCE)) {
|
||
icons.push_back(34);
|
||
}
|
||
} else {
|
||
for(size_t i = 0; i < current_terrain->wandering_locs.size(); i++)
|
||
if(at == current_terrain->wandering_locs[i]) {
|
||
icons.push_back(86);
|
||
}
|
||
}
|
||
return icons;
|
||
}
|
||
|
||
void Set_up_win() {
|
||
terrain_rect.offset(TER_RECT_UL_X, TER_RECT_UL_Y);
|
||
terrain_buttons_rect.offset(RIGHT_AREA_UL_X, RIGHT_AREA_UL_Y);
|
||
terrain_buttons_rect_editing.offset(RIGHT_AREA_UL_X, RIGHT_AREA_UL_Y);
|
||
palette_button_base.offset(RIGHT_AREA_UL_X, RIGHT_AREA_UL_Y);
|
||
|
||
for(short i = 0; i < 10; i++)
|
||
for(short j = 0; j < 6; j++) {
|
||
palette_buttons[i][j] = palette_button_base;
|
||
palette_buttons[i][j].offset(i * 25, j * 17);
|
||
}
|
||
for(short i = 0; i < 10; i++)
|
||
for(short j = /*2*/0; j < 6; j++)
|
||
palette_buttons[i][j].offset(0, 3);
|
||
for(short i = 0; i < 10; i++)
|
||
for(short j = /*3*/0; j < 6; j++)
|
||
palette_buttons[i][j].offset(0, 3);
|
||
for(short i = 0; i < 10; i++)
|
||
for(short j = /*4*/0; j < 6; j++)
|
||
palette_buttons[i][j].offset(0, 3);
|
||
|
||
for(short i = 0; i < NLS; i++) {
|
||
left_buttons[i][0] = left_button_base;
|
||
left_buttons[i][0].offset(0,i * 16);
|
||
left_buttons[i][1] = left_buttons[i][0];
|
||
left_buttons[i][1].top += 1;
|
||
left_buttons[i][1].bottom -= 1;
|
||
left_buttons[i][1].left += 0;
|
||
left_buttons[i][1].right = left_buttons[i][1].left + 16;
|
||
}
|
||
right_button_base.left = RIGHT_AREA_UL_X + 1;
|
||
right_button_base.top = RIGHT_AREA_UL_Y + 1;
|
||
right_button_base.bottom = right_button_base.top + 12;
|
||
right_button_base.right = right_button_base.left + RIGHT_AREA_WIDTH - 20;
|
||
for(short i = 0; i < NRSONPAGE; i++) {
|
||
right_buttons[i] = right_button_base;
|
||
right_buttons[i].offset(0,i * 12);
|
||
}
|
||
}
|
||
|
||
void run_startup_g() {
|
||
sf::Event event;
|
||
sf::Texture& pict_to_draw = *ResMgr::graphics.get("edsplash", true);
|
||
rectangle dest_rect = rectangle(pict_to_draw);
|
||
|
||
play_sound(-95);
|
||
sf::Time delay = time_in_ticks(120);
|
||
sf::Clock timer;
|
||
while(sound_going(95) || timer.getElapsedTime() < delay) {
|
||
draw_splash(pict_to_draw, mainPtr(), dest_rect);
|
||
if(!pollEvent(mainPtr(), event)) continue;
|
||
if(event.type == sf::Event::GainedFocus || event.type == sf::Event::MouseMoved)
|
||
set_cursor(watch_curs);
|
||
if(event.type == sf::Event::KeyPressed || event.type == sf::Event::MouseButtonPressed)
|
||
break;
|
||
}
|
||
|
||
// It's never needed again, so don't keep it in GPU memory
|
||
ResMgr::graphics.free("edsplash");
|
||
}
|
||
|
||
void load_graphics(){
|
||
// Preload the main editor interface graphics
|
||
ResMgr::graphics.get("edbuttons");
|
||
ResMgr::graphics.get("teranim");
|
||
ResMgr::graphics.get("fields");
|
||
ResMgr::graphics.get("objects");
|
||
ResMgr::graphics.get("tinyobj");
|
||
ResMgr::graphics.get("termap");
|
||
}
|
||
|
||
void redraw_screen() {
|
||
rectangle windRect(mainPtr());
|
||
|
||
// Switch back to the default view while drawing the background tiles
|
||
// so that they are not upscaled
|
||
mainPtr().setView(mainPtr().getDefaultView());
|
||
tileImage(mainPtr(),windRect,bg[20]);
|
||
mainPtr().setView(mainView);
|
||
|
||
draw_main_screen();
|
||
|
||
if(overall_mode < MODE_MAIN_SCREEN)
|
||
draw_terrain();
|
||
|
||
// DIRTY FIX to a problem that exist somewhere else. But where?
|
||
undo_clip(mainPtr());
|
||
|
||
drawable_mgr.draw_all();
|
||
|
||
mainPtr().display();
|
||
}
|
||
|
||
extern size_t num_strs(short mode); // defined in scen.keydlgs.cpp
|
||
|
||
void apply_mode_buttons() {
|
||
right_button_status.clear();
|
||
int num_options;
|
||
switch(overall_mode){
|
||
case MODE_EDIT_SPECIAL_ITEMS:
|
||
num_options = scenario.special_items.size() + 1;
|
||
for(int i = 0; i < num_options; i++) {
|
||
std::string title;
|
||
if(i == scenario.special_items.size())
|
||
title = "Create New Special Item";
|
||
else title = scenario.special_items[i].name;
|
||
title = std::to_string(i) + " - " + title;
|
||
set_rb(i,RB_SPEC_ITEM, i, title);
|
||
}
|
||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||
break;
|
||
case MODE_EDIT_QUESTS:
|
||
num_options = scenario.quests.size() + 1;
|
||
for(int i = 0; i < num_options; i++) {
|
||
std::string title;
|
||
if(i == scenario.quests.size())
|
||
title = "Create New Quest";
|
||
else title = scenario.quests[i].name;
|
||
title = std::to_string(i) + " - " + title;
|
||
set_rb(i, RB_QUEST, i, title);
|
||
}
|
||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||
break;
|
||
case MODE_EDIT_SHOPS:
|
||
num_options = scenario.shops.size() + 1;
|
||
for(int i = 0; i < num_options; i++) {
|
||
std::string title;
|
||
if(i == scenario.shops.size())
|
||
title = "Create New Shop";
|
||
else title = scenario.shops[i].getName();
|
||
title = std::to_string(i) + " - " + title;
|
||
set_rb(i, RB_SHOP, i, title);
|
||
}
|
||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||
break;
|
||
case MODE_EDIT_STRINGS:{
|
||
eStrMode mode = static_cast<eStrMode>(scenario.editor_state.string_editing_mode);
|
||
size_t num_strs = ::num_strs(mode);
|
||
|
||
for(size_t i = 0; i < num_strs; i++) {
|
||
std::ostringstream str;
|
||
switch(mode) {
|
||
case 0:
|
||
str << i << " - " << scenario.spec_strs[i];
|
||
set_rb(i,RB_SCEN_STR, i,str.str());
|
||
break;
|
||
case 1:
|
||
str << i << " - " << current_terrain->spec_strs[i];
|
||
set_rb(i,RB_OUT_STR, i,str.str());
|
||
break;
|
||
case 2:
|
||
str << i << " - " << town->spec_strs[i];
|
||
set_rb(i,RB_TOWN_STR, i,str.str());
|
||
break;
|
||
case 3:
|
||
str << i << " - " << scenario.journal_strs[i];
|
||
set_rb(i,RB_JOURNAL, i,str.str());
|
||
break;
|
||
case 4:
|
||
str << i << " - " << current_terrain->sign_locs[i];
|
||
set_rb(i,RB_OUT_SIGN, i,str.str());
|
||
break;
|
||
case 5:
|
||
str << i << " - " << town->sign_locs[i].text;
|
||
set_rb(i,RB_TOWN_SIGN, i,str.str());
|
||
break;
|
||
case 6:
|
||
str << i << " - " << current_terrain->area_desc[i];
|
||
set_rb(i,RB_OUT_RECT, i,str.str());
|
||
break;
|
||
case 7:
|
||
str << i << " - " << town->area_desc[i].descr;
|
||
set_rb(i,RB_TOWN_RECT, i,str.str());
|
||
break;
|
||
}
|
||
}
|
||
if(mode <= STRS_JOURNAL) {
|
||
// Signs and area rects don't get a Create New option – you create a new one on the map.
|
||
std::string make_new = std::to_string(num_strs) + " - Create New String";
|
||
switch(mode) {
|
||
case 0: set_rb(num_strs, RB_SCEN_STR, num_strs, make_new); break;
|
||
case 1: set_rb(num_strs, RB_OUT_STR, num_strs, make_new); break;
|
||
case 2: set_rb(num_strs, RB_TOWN_STR, num_strs, make_new); break;
|
||
case 3: set_rb(num_strs, RB_JOURNAL, num_strs, make_new); break;
|
||
case 4: set_rb(num_strs, RB_OUT_SIGN, num_strs, make_new); break;
|
||
case 5: set_rb(num_strs, RB_TOWN_SIGN, num_strs, make_new); break;
|
||
case 6: set_rb(num_strs, RB_OUT_RECT, num_strs, make_new); break;
|
||
case 7: set_rb(num_strs, RB_TOWN_RECT, num_strs, make_new); break;
|
||
}
|
||
}
|
||
|
||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||
}break;
|
||
case MODE_EDIT_SPECIALS:{
|
||
size_t num_specs;
|
||
short mode = scenario.editor_state.special_editing_mode;
|
||
switch(mode) {
|
||
case 0: num_specs = scenario.scen_specials.size(); break;
|
||
case 1: num_specs = current_terrain->specials.size(); break;
|
||
case 2: num_specs = town->specials.size(); break;
|
||
}
|
||
|
||
for(size_t i = 0; i < num_specs; i++) {
|
||
std::ostringstream strb;
|
||
switch(mode) {
|
||
case 0:
|
||
strb << i << " - " << (*scenario.scen_specials[i].type).name();
|
||
set_rb(i,RB_SCEN_SPEC, i, strb.str());
|
||
break;
|
||
case 1:
|
||
strb << i << " - " << (*current_terrain->specials[i].type).name();
|
||
set_rb(i,RB_OUT_SPEC, i, strb.str());
|
||
break;
|
||
case 2:
|
||
strb << i << " - " << (*town->specials[i].type).name();
|
||
set_rb(i,RB_TOWN_SPEC, i, strb.str());
|
||
break;
|
||
}
|
||
}
|
||
std::string make_new = std::to_string(num_specs) + " - Create New Special";
|
||
switch(mode) {
|
||
case 0: set_rb(num_specs, RB_SCEN_SPEC, num_specs, make_new); break;
|
||
case 1: set_rb(num_specs, RB_OUT_SPEC, num_specs, make_new); break;
|
||
case 2: set_rb(num_specs, RB_TOWN_SPEC, num_specs, make_new); break;
|
||
}
|
||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click to delete",true);
|
||
}break;
|
||
case MODE_EDIT_DIALOGUE:{
|
||
// TODO use stringstream and give more readable info
|
||
char s[15] = " , ";
|
||
for(short i = 0; i < 10; i++) {
|
||
std::ostringstream strb;
|
||
strb << "Personality " << (i + cur_town * 10) << " - " << town->talking.people[i].title;
|
||
set_rb(i,RB_PERSONALITY, i, strb.str());
|
||
}
|
||
size_t n_nodes = town->talking.talk_nodes.size();
|
||
for(short i = 0; i < n_nodes; i++) {
|
||
for(short j = 0; j < 4; j++) {
|
||
s[j] = town->talking.talk_nodes[i].link1[j];
|
||
s[j + 6] = town->talking.talk_nodes[i].link2[j];
|
||
}
|
||
std::ostringstream strb;
|
||
strb << "Node " << i << " - Per. " << town->talking.talk_nodes[i].personality << ", " << s;
|
||
set_rb(10 + i,RB_DIALOGUE, i, strb.str());
|
||
}
|
||
set_rb(10 + n_nodes, RB_DIALOGUE, n_nodes, "Create New Node");
|
||
right_sbar->setMaximum((11 + n_nodes) - NRSONPAGE);
|
||
set_lb(NLS - 3,LB_TEXT,LB_NO_ACTION,"Alt-click node to delete",true);
|
||
}break;
|
||
default: break;
|
||
}
|
||
}
|
||
|
||
void draw_main_screen() {
|
||
rectangle draw_rect;
|
||
|
||
apply_mode_buttons();
|
||
|
||
draw_lb();
|
||
|
||
// draw right buttons (only when not editing terrain)
|
||
if(overall_mode >= MODE_MAIN_SCREEN) {
|
||
draw_rect.left = RIGHT_AREA_UL_X;
|
||
draw_rect.top = RIGHT_AREA_UL_Y;
|
||
draw_rect.right = RIGHT_AREA_UL_X + RIGHT_AREA_WIDTH - 16;
|
||
draw_rect.bottom = RIGHT_AREA_UL_Y + RIGHT_AREA_HEIGHT;
|
||
|
||
frame_rect(mainPtr(), draw_rect, sf::Color::Black);
|
||
draw_rect.inset(1,1);
|
||
tileImage(mainPtr(),draw_rect,bg[17]);
|
||
|
||
draw_rb();
|
||
}
|
||
|
||
// draw terrain palette
|
||
if((overall_mode < MODE_MAIN_SCREEN) || (overall_mode == MODE_EDIT_TYPES)) {
|
||
place_location();
|
||
set_up_type_buttons(false);
|
||
TextStyle style;
|
||
win_draw_string(mainPtr(), search_field_text_rect, "Search:", eTextMode::WRAP, style);
|
||
palette_search_field->show();
|
||
}else{
|
||
palette_search_field->hide();
|
||
}
|
||
|
||
|
||
}
|
||
|
||
void draw_lb() {
|
||
for(short i = 0; i < NLS; i++)
|
||
draw_lb_slot(i,0);
|
||
}
|
||
|
||
const int LEFT_BUTTON_SPACE = 2;
|
||
|
||
// mode 0 normal 1 click
|
||
void draw_lb_slot (short which,short mode) {
|
||
rectangle text_rect,from_rect;
|
||
|
||
tileImage(mainPtr(),left_buttons[which][0],bg[20]);
|
||
if(left_button_status[which].mode == LB_CLEAR)
|
||
return;
|
||
|
||
int button_width = blue_button_from.width();
|
||
|
||
text_rect = left_buttons[which][0];
|
||
if(left_button_status[which].action != LB_NO_ACTION) {
|
||
text_rect.left += button_width + LEFT_BUTTON_SPACE;
|
||
from_rect = blue_button_from;
|
||
if(mode > 0)
|
||
from_rect.offset(0,from_rect.height());
|
||
rect_draw_some_item(*ResMgr::graphics.get("edbuttons"),from_rect,mainPtr(),left_buttons[which][1]);
|
||
}
|
||
if(left_button_status[which].mode == LB_INDENT)
|
||
text_rect.left += 16;
|
||
TextStyle style;
|
||
if(left_button_status[which].mode == LB_TITLE) {
|
||
style.pointSize = 14;
|
||
}
|
||
else text_rect.offset(0,2);
|
||
if(mode > 0)
|
||
style.colour = Colours::BLUE;
|
||
style.lineHeight = 12;
|
||
|
||
// Arbitrary extra space on the right prevents labels from being forced to line wrap
|
||
text_rect.right += 10;
|
||
|
||
// Measure the button's clickable width including the label
|
||
left_buttons[which][0].width() = button_width + LEFT_BUTTON_SPACE + string_length(left_button_status[which].label, style);
|
||
|
||
win_draw_string(mainPtr(),text_rect,left_button_status[which].label,eTextMode::WRAP,style);
|
||
}
|
||
|
||
void draw_rb() {
|
||
long pos = right_sbar->getPosition();
|
||
for(long i = pos; i < pos + NRSONPAGE && i < NRS; i++)
|
||
draw_rb_slot(i,0);
|
||
}
|
||
|
||
// mode 0 normal 1 pressed
|
||
void draw_rb_slot (short which,short mode) {
|
||
rectangle text_rect;
|
||
long pos;
|
||
|
||
pos = right_sbar->getPosition();
|
||
if(which < pos || which >= pos + NRSONPAGE || which >= NRS)
|
||
return;
|
||
|
||
tileImage(mainPtr(),right_buttons[which - pos],bg[17]);
|
||
if(right_button_status[which].action == RB_CLEAR)
|
||
return;
|
||
text_rect = right_buttons[which - pos];
|
||
|
||
TextStyle style;
|
||
if(mode > 0)
|
||
style.colour = Colours::RED;
|
||
else if(right_button_hovered == which - pos)
|
||
style.colour = Colours::GREEN;
|
||
|
||
style.lineHeight = 12;
|
||
win_draw_string(mainPtr(),text_rect,right_button_status[which].label,eTextMode::LEFT_TOP,style);
|
||
}
|
||
|
||
void set_up_type_buttons(bool reset) {
|
||
short pic,small_i;
|
||
rectangle ter_from,ter_from_base = {0,0,36,28}, ter_plus_from = {148,235,164,251};
|
||
rectangle tiny_from,tiny_to;
|
||
|
||
rectangle palette_from,palette_to = palette_button_base;
|
||
int max;
|
||
int rows = TYPE_ROWS_DRAWING;
|
||
switch(draw_mode) {
|
||
case DRAW_TERRAIN: max = scenario.ter_types.size(); break;
|
||
case DRAW_ITEM: max = scenario.scen_items.size(); break;
|
||
case DRAW_MONST: max = scenario.scen_monsters.size(); max--; break; // I think this is because monsters have no number 0
|
||
default: return;
|
||
}
|
||
if(overall_mode == MODE_EDIT_TYPES){
|
||
max++; // The plus button
|
||
rows = TYPE_ROWS_EDITING;
|
||
}
|
||
|
||
if(reset) pal_sbar->setPosition(0);
|
||
|
||
int rows_overflow = ceil(max / 16.0) - rows;
|
||
pal_sbar->setMaximum(rows_overflow);
|
||
|
||
int first = pal_sbar->getPosition() * 16;
|
||
if(draw_mode == DRAW_MONST) first++, max++; // Monsters have no number 0
|
||
int end = min(first + 16 * rows, max);
|
||
|
||
std::string search_query = palette_search_field->getText();
|
||
boost::algorithm::to_lower(search_query);
|
||
boost::algorithm::trim(search_query);
|
||
|
||
// How transparent to make non-matching elements in the palette
|
||
static const sf::Uint8 FILTER_ALPHA = 255 / 8;
|
||
|
||
// first make terrain buttons
|
||
sf::Texture& editor_mixed = *ResMgr::graphics.get("edbuttons");
|
||
for(short i = first; i < end; i++) {
|
||
sf::Color colour = Colours::WHITE;
|
||
sf::Color frame_colour = Colours::BLACK;
|
||
rectangle draw_rect = terrain_rects[i - first];
|
||
draw_rect.offset(RIGHT_AREA_UL_X, RIGHT_AREA_UL_Y);
|
||
switch(draw_mode){
|
||
case DRAW_TERRAIN:{
|
||
// Plus button
|
||
if(i == scenario.ter_types.size()) {
|
||
rect_draw_some_item(editor_mixed, ter_plus_from, mainPtr(), draw_rect);
|
||
break;
|
||
}
|
||
const cTerrain& ter = scenario.ter_types[i];
|
||
|
||
std::string name = ter.name;
|
||
boost::algorithm::to_lower(name);
|
||
if(!search_query.empty() && name.find(search_query) == std::string::npos) colour.a = FILTER_ALPHA;
|
||
|
||
ter_from = ter_from_base;
|
||
pic = ter.picture;
|
||
if(pic >= 1000) {
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic % 1000);
|
||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), draw_rect, sf::BlendAlpha, colour);
|
||
}
|
||
else if(pic < 960) {
|
||
pic = pic % 50;
|
||
ter_from.offset(28 * (pic % 10), 36 * (pic / 10));
|
||
int which_sheet = ter.picture / 50;
|
||
rect_draw_some_item(*ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet)),
|
||
ter_from, mainPtr(), draw_rect, sf::BlendAlpha, colour);
|
||
}
|
||
else {
|
||
pic = (pic - 560) % 50;
|
||
ter_from.left = 112 * (pic / 5);
|
||
ter_from.right = ter_from.left + 28;
|
||
ter_from.top = 36 * (pic % 5);
|
||
ter_from.bottom = ter_from.top + 36;
|
||
rect_draw_some_item(*ResMgr::graphics.get("teranim"), ter_from, mainPtr(), draw_rect, sf::BlendAlpha, colour);
|
||
|
||
}
|
||
small_i = get_small_icon(i);
|
||
tiny_from = base_small_button_from;
|
||
tiny_from.offset(7 * (small_i % 30),7 * (small_i / 30));
|
||
tiny_to = draw_rect;
|
||
tiny_to.top = tiny_to.bottom - 7;
|
||
tiny_to.left = tiny_to.right - 7;
|
||
if(small_i >= 0 && small_i < 255)
|
||
rect_draw_some_item(editor_mixed, tiny_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
}break;
|
||
case DRAW_MONST:{
|
||
// Plus button
|
||
if(i == scenario.scen_monsters.size()) {
|
||
rect_draw_some_item(editor_mixed, ter_plus_from, mainPtr(), draw_rect);
|
||
break;
|
||
}
|
||
const cMonster& monst = scenario.scen_monsters[i];
|
||
|
||
std::string name = monst.m_name;
|
||
boost::algorithm::to_lower(name);
|
||
if(!search_query.empty() && name.find(search_query) == std::string::npos){
|
||
colour.a = frame_colour.a = FILTER_ALPHA;
|
||
}
|
||
|
||
pic = monst.picture_num;
|
||
tiny_to = draw_rect;
|
||
frame_rect(mainPtr(), tiny_to, frame_colour);
|
||
if(pic >= 4000) {
|
||
pic %= 1000;
|
||
tiny_to.width() = tiny_to.width() / 2;
|
||
tiny_to.height() = tiny_to.height() / 2;
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
pic++;
|
||
tiny_to.offset(tiny_to.width(), 0);
|
||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
pic++;
|
||
tiny_to.offset(-tiny_to.width(), tiny_to.height());
|
||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
pic++;
|
||
tiny_to.offset(tiny_to.width(), 0);
|
||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
} else if(pic >= 3000) {
|
||
pic %= 1000;
|
||
tiny_to.width() = tiny_to.width() / 2;
|
||
tiny_to.height() = tiny_to.height() / 2;
|
||
tiny_to.offset(tiny_to.width() / 2, 0);
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
pic++;
|
||
tiny_to.offset(0, tiny_to.height());
|
||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
} else if(pic >= 2000) {
|
||
pic %= 1000;
|
||
tiny_to.width() = tiny_to.width() / 2;
|
||
tiny_to.height() = tiny_to.height() / 2;
|
||
tiny_to.offset(0, tiny_to.height() / 2);
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
pic++;
|
||
tiny_to.offset(tiny_to.width(), 0);
|
||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
} else if(pic >= 1000) {
|
||
pic %= 1000;
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic);
|
||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
} else {
|
||
auto pic_info = m_pic_index[pic];
|
||
pic = pic_info.i;
|
||
auto monst_gworld = [](pic_num_t sheet_num) {
|
||
return *ResMgr::graphics.get("monst" + std::to_string(1 + sheet_num));
|
||
};
|
||
if(pic_info.x == 2 && pic_info.y == 2) {
|
||
tiny_to.width() = tiny_to.width() / 2;
|
||
tiny_to.height() = tiny_to.height() / 2;
|
||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
pic++;
|
||
tiny_to.offset(tiny_to.width(), 0);
|
||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
pic++;
|
||
tiny_to.offset(-tiny_to.width(), tiny_to.height());
|
||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
pic++;
|
||
tiny_to.offset(tiny_to.width(), 0);
|
||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
} else if(pic_info.y == 2) {
|
||
tiny_to.width() = tiny_to.width() / 2;
|
||
tiny_to.height() = tiny_to.height() / 2;
|
||
tiny_to.offset(tiny_to.width() / 2, 0);
|
||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
pic++;
|
||
tiny_to.offset(0, tiny_to.height());
|
||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
} else if(pic_info.x == 2) {
|
||
tiny_to.width() = tiny_to.width() / 2;
|
||
tiny_to.height() = tiny_to.height() / 2;
|
||
tiny_to.offset(0, tiny_to.height() / 2);
|
||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
pic++;
|
||
tiny_to.offset(tiny_to.width(), 0);
|
||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
} else {
|
||
ter_from = calc_rect(2 * ((pic % 20) / 10), (pic % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(pic / 20), ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
}
|
||
}
|
||
}break;
|
||
case DRAW_ITEM:{
|
||
// Plus button
|
||
if(i == scenario.scen_items.size()) {
|
||
rect_draw_some_item(editor_mixed, ter_plus_from, mainPtr(), draw_rect);
|
||
break;
|
||
}
|
||
const cItem& item = scenario.scen_items[i];
|
||
pic = item.graphic_num;
|
||
|
||
std::string fname = item.full_name;
|
||
boost::algorithm::to_lower(fname);
|
||
// Maybe a designer will want to search for the unidentified name of a cursed item?
|
||
std::string name = item.name;
|
||
boost::algorithm::to_lower(name);
|
||
|
||
if(!search_query.empty() && fname.find(search_query) == std::string::npos && name.find(search_query) == std::string::npos){
|
||
colour.a = frame_colour.a = FILTER_ALPHA;
|
||
}
|
||
|
||
tiny_to = draw_rect;
|
||
frame_rect(mainPtr(), tiny_to, frame_colour);
|
||
if(pic >= 1000) {
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, ter_from) = spec_scen_g.find_graphic(pic % 1000);
|
||
rect_draw_some_item(*source_gworld, ter_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
} else {
|
||
tiny_from = {0,0,18,18};
|
||
tiny_from.offset((pic % 10) * 18,(pic / 10) * 18);
|
||
rect_draw_some_item(*ResMgr::graphics.get("tinyobj"), tiny_from, mainPtr(), tiny_to, sf::BlendAlpha, colour);
|
||
}
|
||
}break;
|
||
}
|
||
}
|
||
|
||
if(overall_mode < MODE_MAIN_SCREEN) {
|
||
palette_to.offset(5,terrain_rects[255].bottom + 14);
|
||
for(short i = 0; i < 10; i++){
|
||
for(short j = 0; j < 6; j++){
|
||
auto cur_palette_buttons = editing_town ? town_buttons : out_buttons;
|
||
if(cur_palette_buttons[j][i] != PAL_BLANK) {
|
||
palette_from = palette_button_base;
|
||
palette_from.offset(-RIGHT_AREA_UL_X, -RIGHT_AREA_UL_Y);
|
||
int n = cur_palette_buttons[j][i];
|
||
palette_from.offset((n%10) * 25, (n/10) * 17);
|
||
rect_draw_some_item(editor_mixed, palette_from, mainPtr(), palette_to, sf::BlendAlpha);
|
||
}
|
||
palette_to.offset(0,17);
|
||
}
|
||
palette_to.offset(25,-6*17);
|
||
}
|
||
}
|
||
}
|
||
|
||
rectangle visible_bounds() {
|
||
if(cur_viewing_mode == 0){
|
||
return {cen_y - 4, cen_x - 4, cen_y + 4, cen_x + 4};
|
||
}else{
|
||
// Width available: 64 4x4 tiles, 42 6x6 tiles, or 21 12x12 tiles -- 256 pixels
|
||
// Height available: 81 4x4 tiles, 54 6x6 tiles, or 27 12x12 tiles -- 324 pixels
|
||
short size = mini_map_scales[cur_viewing_mode - 1];
|
||
int max_dim = get_current_area()->max_dim;
|
||
int xMin = 0, yMin = 0, xMax = max_dim, yMax = max_dim;
|
||
if(!editing_town){
|
||
--xMin;
|
||
--yMin;
|
||
++xMax;
|
||
++yMax;
|
||
}
|
||
if(cen_x + 5 > 256 / size) {
|
||
xMin = cen_x + 5 - (256 / size);
|
||
xMax = cen_x + 5;
|
||
} else xMax = std::min(xMax, 256 / size);
|
||
if(cen_y + 5 > 324 / size) {
|
||
yMin = cen_y + 5 - (324 / size);
|
||
yMax = cen_y + 5;
|
||
} else yMax = std::min(yMax, 324 / size);
|
||
return {yMin, xMin, yMax, xMax};
|
||
}
|
||
}
|
||
|
||
static ter_num_t ter_at(int q, int r) {
|
||
ter_num_t t_to_draw;
|
||
rectangle bounds = visible_bounds();
|
||
if(editing_town) {
|
||
t_to_draw = town->terrain(bounds.left + q, bounds.top + r);
|
||
}
|
||
else {
|
||
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)
|
||
t_to_draw = scenario.outdoors[cur_out.x - 1][cur_out.y - 1]->terrain[47][47];
|
||
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];
|
||
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];
|
||
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];
|
||
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];
|
||
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];
|
||
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];
|
||
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];
|
||
else if(ter_x == -1 || ter_x == 48 || ter_y == -1 || ter_y == 48)
|
||
t_to_draw = 90;
|
||
else t_to_draw = current_terrain->terrain[ter_x][ter_y];
|
||
}
|
||
return t_to_draw;
|
||
}
|
||
|
||
void draw_terrain(){
|
||
location which_pt,where_draw;
|
||
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 boat_rect = {0,0,36,28};
|
||
tiny_to_base.offset(TER_RECT_UL_X,TER_RECT_UL_Y);
|
||
clipping_rect.offset(TER_RECT_UL_X,TER_RECT_UL_Y);
|
||
|
||
if(overall_mode >= MODE_MAIN_SCREEN)
|
||
return;
|
||
|
||
if(cur_viewing_mode == 0) {
|
||
tileImage(mainPtr(),terrain_rect,bg[17]);
|
||
frame_rect(mainPtr(), terrain_rect, sf::Color::Black);
|
||
for(short q = 0; q < 9; q++)
|
||
for(short r = 0; r < 9; r++) {
|
||
where_draw.x = q;
|
||
where_draw.y = r;
|
||
t_to_draw = ter_at(q, r);
|
||
draw_one_terrain_spot(q,r,t_to_draw);
|
||
|
||
rectangle destrec;
|
||
|
||
destrec.left = 8 + BITMAP_WIDTH * where_draw.x;
|
||
destrec.right = destrec.left + BITMAP_WIDTH;
|
||
destrec.top = 8 + BITMAP_HEIGHT * where_draw.y;
|
||
destrec.bottom = destrec.top + BITMAP_HEIGHT;
|
||
destrec.offset(TER_RECT_UL_X,TER_RECT_UL_Y);
|
||
|
||
sf::Texture& fields_gworld = *ResMgr::graphics.get("fields");
|
||
sf::Texture& vehicle_gworld = *ResMgr::graphics.get("vehicle");
|
||
|
||
// TODO this doesn't work for the 1 row/column of adjacent outdoor sections drawn
|
||
if(is_road(cen_x + q - 4,cen_y + r - 4))
|
||
rect_draw_some_item(fields_gworld, calc_rect(0, 2), mainPtr(), destrec, sf::BlendAlpha);
|
||
if(is_spot(cen_x + q - 4,cen_y + r - 4))
|
||
rect_draw_some_item(fields_gworld, calc_rect(4, 0), mainPtr(), destrec, sf::BlendAlpha);
|
||
|
||
which_pt.x = cen_x + q - 4;
|
||
which_pt.y =cen_y + r - 4;
|
||
|
||
for(short i = 0; i < scenario.boats.size(); i++) {
|
||
if(editing_town && scenario.boats[i].which_town == cur_town &&
|
||
scenario.boats[i].loc == which_pt)
|
||
rect_draw_some_item(vehicle_gworld,boat_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
if(!editing_town && scenario.boats[i].which_town == 200 &&
|
||
scenario.boats[i].sector == cur_out &&
|
||
scenario.boats[i].loc == which_pt)
|
||
rect_draw_some_item(vehicle_gworld,boat_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
|
||
}
|
||
for(short i = 0; i < scenario.horses.size(); i++) {
|
||
source_rect = boat_rect;
|
||
source_rect.offset(0,36);
|
||
if(editing_town && scenario.horses[i].which_town == cur_town &&
|
||
scenario.horses[i].loc == which_pt)
|
||
rect_draw_some_item(vehicle_gworld,source_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
if(!editing_town && scenario.horses[i].which_town == 200 &&
|
||
scenario.horses[i].sector == cur_out &&
|
||
scenario.horses[i].loc == which_pt)
|
||
rect_draw_some_item(vehicle_gworld,source_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
|
||
}
|
||
|
||
if(editing_town) {
|
||
if(is_field_type(cen_x + q - 4,cen_y + r - 4, FIELD_WEB)) {
|
||
from_rect = calc_rect(5,0);
|
||
rect_draw_some_item(fields_gworld,from_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
}
|
||
if(is_field_type(cen_x + q - 4,cen_y + r - 4, OBJECT_CRATE)) {
|
||
from_rect = calc_rect(6,0);
|
||
rect_draw_some_item(fields_gworld,from_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
}
|
||
if(is_field_type(cen_x + q - 4,cen_y + r - 4, OBJECT_BARREL)) {
|
||
from_rect = calc_rect(7,0);
|
||
rect_draw_some_item(fields_gworld,from_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
}
|
||
if(is_field_type(cen_x + q - 4,cen_y + r - 4, BARRIER_FIRE)) {
|
||
from_rect = calc_rect(8,4);
|
||
rect_draw_some_item(*ResMgr::graphics.get("teranim"),from_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
}
|
||
if(is_field_type(cen_x + q - 4,cen_y + r - 4, FIELD_QUICKFIRE)) {
|
||
from_rect = calc_rect(7,1);
|
||
rect_draw_some_item(fields_gworld,from_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
}
|
||
if(is_field_type(cen_x + q - 4,cen_y + r - 4, BARRIER_FORCE)) {
|
||
from_rect = calc_rect(10,4);
|
||
rect_draw_some_item(*ResMgr::graphics.get("teranim"),from_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
}
|
||
if(is_field_type(cen_x + q - 4,cen_y + r - 4, OBJECT_BLOCK)) {
|
||
from_rect = calc_rect(3,0);
|
||
rect_draw_some_item(fields_gworld,from_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
}
|
||
if(is_field_type(cen_x + q - 4,cen_y + r - 4, BARRIER_CAGE)) {
|
||
from_rect = calc_rect(0,0);
|
||
rect_draw_some_item(fields_gworld,from_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
}
|
||
for(short i = 0; i < 8; i++) {
|
||
eFieldType sfx = eFieldType(SFX_SMALL_BLOOD + i);
|
||
if(is_field_type(cen_x + q - 4,cen_y + r - 4,sfx)) {
|
||
from_rect = calc_rect(i,3);
|
||
rect_draw_some_item(fields_gworld,from_rect,mainPtr(),destrec,sf::BlendAlpha);
|
||
}
|
||
}
|
||
}
|
||
|
||
tiny_to = tiny_to_base;
|
||
tiny_to.offset(28 * q, 36 * r);
|
||
|
||
// Tiny icons
|
||
std::vector<short> icons = get_small_icons(loc(cen_x + q - 4, cen_y + r - 4), t_to_draw);
|
||
|
||
if(!icons.empty()) {
|
||
bool has_start = icons[0] == -1;
|
||
rectangle tiny_from_base = {120, 0, 127, 7};
|
||
sf::Texture& editor_mixed = *ResMgr::graphics.get("edbuttons");
|
||
for(short icon : icons) {
|
||
rectangle tiny_from = tiny_from_base;
|
||
if(icon == -1) {
|
||
tiny_from.offset(30 * 7, 0);
|
||
tiny_from.right += 14;
|
||
tiny_to.left -= 14;
|
||
} else {
|
||
tiny_from.offset((icon % 30) * 7, (icon / 30) * 7);
|
||
}
|
||
rect_draw_some_item(editor_mixed, tiny_from, mainPtr(), tiny_to);
|
||
if(icon == -1) tiny_to.left += 14;
|
||
tiny_to.offset(0, -7);
|
||
// Now check to see if it's overflowing our space
|
||
if(tiny_to.top < destrec.top) {
|
||
tiny_to.offset(-7, 7 * (has_start ? 4 : 5));
|
||
}
|
||
}
|
||
}
|
||
|
||
if(mouse_spot.x >= 0 && mouse_spot.y >= 0) {
|
||
bool need_hilite = false, large_hilite = false;
|
||
int d = dist(where_draw, mouse_spot);
|
||
if(overall_mode == MODE_SMALL_PAINTBRUSH && d <= 1) {
|
||
need_hilite = true;
|
||
large_hilite = true;
|
||
} else if((overall_mode == MODE_ERASER || overall_mode == MODE_SMALL_SPRAYCAN) && d <= 2) {
|
||
need_hilite = true;
|
||
large_hilite = true;
|
||
} else if((overall_mode == MODE_LARGE_PAINTBRUSH || overall_mode == MODE_LARGE_SPRAYCAN) && d <= 4) {
|
||
need_hilite = true;
|
||
large_hilite = true;
|
||
} else if(where_draw == mouse_spot)
|
||
need_hilite = true;
|
||
else if(overall_mode == MODE_PLACE_CREATURE) {
|
||
extern short mode_count;
|
||
cMonster& monst = scenario.scen_monsters[mode_count];
|
||
for(int x = 0; x < monst.x_width; x++) {
|
||
for(int y = 0; y < monst.y_width; y++) {
|
||
location this_spot = {where_draw.x - x, where_draw.y - y};
|
||
if(this_spot == mouse_spot)
|
||
need_hilite = true;
|
||
}
|
||
}
|
||
} else if(overall_mode == MODE_DRAWING) {
|
||
cTerrain& ter = scenario.ter_types[current_terrain_type];
|
||
if(ter.obj_num > 0) {
|
||
// TODO: Don't do this if auto-completion of large terrain objects is disabled
|
||
for(int x = 0; x < ter.obj_size.x; x++) {
|
||
for(int y = 0; y < ter.obj_size.y; y++) {
|
||
location this_spot = {where_draw.x - x + ter.obj_pos.x, where_draw.y - y + ter.obj_pos.y};
|
||
if(this_spot == mouse_spot)
|
||
need_hilite = true;
|
||
}
|
||
}
|
||
}
|
||
} else if(overall_mode == MODE_PASTE) {
|
||
if(auto who = boost::get<cTownperson>(&clipboard)) {
|
||
cMonster& monst = scenario.scen_monsters[who->number];
|
||
for(int x = 0; x < monst.x_width; x++) {
|
||
for(int y = 0; y < monst.y_width; y++) {
|
||
location this_spot = {where_draw.x - x, where_draw.y - y};
|
||
if(this_spot == mouse_spot)
|
||
need_hilite = true;
|
||
}
|
||
}
|
||
} else if(auto ter = boost::get<vector2d<ter_num_t>>(&clipboard)) {
|
||
for(int x = 0; x < ter->width(); x++) {
|
||
for(int y = 0; y < ter->height(); y++) {
|
||
location this_spot = {where_draw.x - x, where_draw.y - y};
|
||
if(this_spot == mouse_spot)
|
||
need_hilite = true;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
if(need_hilite) {
|
||
fill_rect(mainPtr(), destrec, hilite_colour);
|
||
if(large_hilite && where_draw == mouse_spot)
|
||
fill_rect(mainPtr(), destrec, hilite_colour);
|
||
}
|
||
}
|
||
}
|
||
if(editing_town) {
|
||
draw_monsts();
|
||
draw_items();
|
||
}
|
||
|
||
clip_rect(mainPtr(),clipping_rect);
|
||
|
||
// draw info rects
|
||
for(auto& area_desc : get_current_area()->area_desc)
|
||
if(area_desc.left > 0) {
|
||
draw_rect.left = 22 + 28 * (area_desc.left - cen_x + 4);
|
||
draw_rect.right = 22 + 28 * (area_desc.right - cen_x + 4);
|
||
draw_rect.top = 24 + 36 * (area_desc.top - cen_y + 4);
|
||
draw_rect.bottom = 24 + 36 * (area_desc.bottom - cen_y + 4);
|
||
draw_rect.inset(-10, -13);
|
||
draw_rect.offset(TER_RECT_UL_X, TER_RECT_UL_Y);
|
||
frame_rect(mainPtr(), draw_rect, Colours::RED);
|
||
}
|
||
if(editing_town) {
|
||
// draw border rect
|
||
draw_rect.left = 21 + 28 * (town->in_town_rect.left - cen_x + 4);
|
||
draw_rect.right = 21 + 28 * (town->in_town_rect.right - cen_x + 4);
|
||
draw_rect.top = 25 + 36 * (town->in_town_rect.top - cen_y + 4);
|
||
draw_rect.bottom = 25 + 36 * (town->in_town_rect.bottom - cen_y + 4);
|
||
draw_rect.inset(10, 13);
|
||
draw_rect.offset(TER_RECT_UL_X, TER_RECT_UL_Y);
|
||
frame_rect(mainPtr(), draw_rect, sf::Color::White);
|
||
// draw stored item rect
|
||
auto iter = scenario.store_item_rects.find(cur_town);
|
||
if(iter != scenario.store_item_rects.end()) {
|
||
draw_rect.left = 22 + 28 * (iter->second.left - cen_x + 4);
|
||
draw_rect.right = 22 + 28 * (iter->second.right - cen_x + 4);
|
||
draw_rect.top = 24 + 36 * (iter->second.top - cen_y + 4);
|
||
draw_rect.bottom = 24 + 36 * (iter->second.bottom - cen_y + 4);
|
||
draw_rect.inset(-8, -11);
|
||
draw_rect.offset(TER_RECT_UL_X, TER_RECT_UL_Y);
|
||
frame_rect(mainPtr(), draw_rect, sf::Color::Cyan);
|
||
}
|
||
}
|
||
clip_rect(mainPtr(), terrain_rect);
|
||
|
||
small_any_drawn = false;
|
||
//if(cur_viewing_mode == 0)
|
||
// draw_frames();
|
||
}
|
||
|
||
else {
|
||
tileImage(mainPtr(), terrain_rect,bg[17]);
|
||
frame_rect(mainPtr(), terrain_rect, sf::Color::Black);
|
||
|
||
short size = mini_map_scales[cur_viewing_mode - 1];
|
||
int max = get_current_area()->max_dim;
|
||
int min = 0;
|
||
if(!editing_town){
|
||
--min;
|
||
++max;
|
||
}
|
||
rectangle bounds = visible_bounds();
|
||
// std::cout << "Drawing map for " << bounds << std::endl;
|
||
for(short q = 0; q < bounds.width(); q++)
|
||
for(short r = 0; r < bounds.height(); r++) {
|
||
if(q + bounds.left > max) continue;
|
||
if(r + bounds.top > max) continue;
|
||
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));
|
||
small_what_drawn[q][r] = t_to_draw;
|
||
}
|
||
small_any_drawn = true;
|
||
}
|
||
}
|
||
|
||
void draw_monsts() {
|
||
short width,height,m_start_pic;
|
||
std::shared_ptr<const sf::Texture> from_gworld = nullptr;
|
||
rectangle source_rect;
|
||
location where_draw,store_loc;
|
||
|
||
for(short i = 0; i < town->creatures.size(); i++)
|
||
if(town->creatures[i].number != 0) {
|
||
where_draw.x = town->creatures[i].start_loc.x - cen_x + 4;
|
||
where_draw.y = town->creatures[i].start_loc.y - cen_y + 4;
|
||
width = scenario.scen_monsters[town->creatures[i].number].x_width;
|
||
height = scenario.scen_monsters[town->creatures[i].number].y_width;
|
||
|
||
for(short k = 0; k < width * height; k++) {
|
||
store_loc = where_draw;
|
||
if((where_draw.x == minmax(0,8,where_draw.x)) &&
|
||
(where_draw.y == minmax(0,8,where_draw.y)) &&
|
||
(scenario.scen_monsters[town->creatures[i].number].picture_num >= 1000)) {
|
||
graf_pos_ref(from_gworld, source_rect) = spec_scen_g.find_graphic((scenario.scen_monsters[town->creatures[i].number].picture_num + k) % 1000);
|
||
store_loc.x += k % width;
|
||
store_loc.y += k / width;
|
||
}
|
||
else if(scenario.scen_monsters[town->creatures[i].number].picture_num < 1000) {
|
||
m_start_pic = m_pic_index[scenario.scen_monsters[town->creatures[i].number].picture_num].i + k;
|
||
int which_sheet = m_start_pic / 20;
|
||
from_gworld = &ResMgr::graphics.get("monst" + std::to_string(1 + which_sheet));
|
||
m_start_pic = m_start_pic % 20;
|
||
source_rect = calc_rect(2 * (m_start_pic / 10), m_start_pic % 10);
|
||
store_loc.x += k % width;
|
||
store_loc.y += k / width;
|
||
}
|
||
|
||
if(store_loc.x < 0 || store_loc.x > 8 || store_loc.y < 0 || store_loc.y > 8)
|
||
continue;
|
||
|
||
rectangle destrec;
|
||
destrec.left = 8 + BITMAP_WIDTH * store_loc.x;
|
||
destrec.right = destrec.left + BITMAP_WIDTH;
|
||
destrec.top = 8 + BITMAP_HEIGHT * store_loc.y;
|
||
destrec.bottom = destrec.top + BITMAP_HEIGHT;
|
||
|
||
destrec.left = destrec.right - (source_rect.right - source_rect.left);
|
||
destrec.top = destrec.bottom - (source_rect.bottom - source_rect.top);
|
||
destrec.offset(TER_RECT_UL_X,TER_RECT_UL_Y);
|
||
|
||
rect_draw_some_item(*from_gworld, source_rect, mainPtr(), destrec, sf::BlendAlpha);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Returns rect for drawing an item, if num < 25, rect is in big item template,
|
||
// otherwise in small item template
|
||
static rectangle get_item_template_rect (short type_wanted) {
|
||
rectangle store_rect;
|
||
|
||
if(type_wanted < 55) {
|
||
store_rect.top = (type_wanted / 5) * BITMAP_HEIGHT;
|
||
store_rect.bottom = store_rect.top + BITMAP_HEIGHT;
|
||
store_rect.left = (type_wanted % 5) * BITMAP_WIDTH;
|
||
store_rect.right = store_rect.left + BITMAP_WIDTH;
|
||
}
|
||
else {
|
||
store_rect.top = (type_wanted / 10) * 18;
|
||
store_rect.bottom = store_rect.top + 18;
|
||
store_rect.left = (type_wanted % 10) * 18;
|
||
store_rect.right = store_rect.left + 18;
|
||
}
|
||
|
||
return store_rect;
|
||
}
|
||
|
||
void draw_items() {
|
||
rectangle source_rect,dest_rect;
|
||
location where_draw;
|
||
short pic_num;
|
||
|
||
for(short i = 0; i < town->preset_items.size(); i++) {
|
||
if(town->preset_items[i].code >= 0) {
|
||
where_draw.x = town->preset_items[i].loc.x - cen_x + 4;
|
||
where_draw.y = town->preset_items[i].loc.y - cen_y + 4;
|
||
pic_num = scenario.scen_items[town->preset_items[i].code].graphic_num;
|
||
if((where_draw.x >= 0) && (where_draw.x <= 8) &&
|
||
(where_draw.y >= 0) && (where_draw.y <= 8)) {
|
||
|
||
if(pic_num >= 1000) {
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(pic_num - 1000);
|
||
dest_rect = calc_rect(where_draw.x,where_draw.y);
|
||
dest_rect.offset(8+TER_RECT_UL_X,8+TER_RECT_UL_Y);
|
||
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), dest_rect, sf::BlendAlpha);
|
||
}
|
||
else {
|
||
source_rect = get_item_template_rect(pic_num);
|
||
dest_rect = calc_rect(where_draw.x,where_draw.y);
|
||
dest_rect.offset(8+TER_RECT_UL_X,8+TER_RECT_UL_Y);
|
||
if(pic_num >= 45) {
|
||
dest_rect.top += 9;
|
||
dest_rect.bottom -= 9;
|
||
dest_rect.left += 5;
|
||
dest_rect.right -= 5;
|
||
}
|
||
rect_draw_some_item(*ResMgr::graphics.get((pic_num < 55) ? "objects" : "tinyobj"),
|
||
source_rect, mainPtr(), dest_rect,sf::BlendAlpha);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void force_tiny_redraw() {
|
||
// for(short q = 0; q < 8; q++)
|
||
// for(short r = 0; r < 64; r++)
|
||
// ter_changed[q][r] = 255;
|
||
|
||
}
|
||
|
||
void draw_one_terrain_spot (short i,short j,ter_num_t terrain_to_draw) {
|
||
location where_draw;
|
||
rectangle source_rect;
|
||
short picture_wanted;
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
|
||
if(i < 0 || i > 8 || j < 0 || j > 8)
|
||
return;
|
||
|
||
picture_wanted = scenario.ter_types[terrain_to_draw].picture;
|
||
|
||
where_draw.x = (char) i;
|
||
where_draw.y = (char) j;
|
||
|
||
if(picture_wanted >= 1000 && spec_scen_g) {
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000);
|
||
}
|
||
else if(picture_wanted >= 960) {
|
||
source_gworld = &ResMgr::graphics.get("teranim");
|
||
picture_wanted -= 960;
|
||
source_rect.left = 112 * (picture_wanted / 5);
|
||
source_rect.right = source_rect.left + 28;
|
||
source_rect.top = 36 * (picture_wanted % 5);
|
||
source_rect.bottom = source_rect.top + 36;
|
||
}
|
||
else {
|
||
source_rect = get_template_rect(terrain_to_draw);
|
||
int which_sheet = picture_wanted / 50;
|
||
source_gworld = &ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet));
|
||
}
|
||
|
||
rectangle destrec;
|
||
destrec.left = 8 + BITMAP_WIDTH * where_draw.x;
|
||
destrec.right = destrec.left + BITMAP_WIDTH;
|
||
destrec.top = 8 + BITMAP_HEIGHT * where_draw.y;
|
||
destrec.bottom = destrec.top + BITMAP_HEIGHT;
|
||
destrec.offset(TER_RECT_UL_X,TER_RECT_UL_Y);
|
||
|
||
sf::Color colour = Colours::WHITE;
|
||
// We render one row/column from the neighboring outdoor section.
|
||
// Make it slightly transparent because you can't edit it.
|
||
int x = cen_x + i - 4;
|
||
int y = cen_y + j - 4;
|
||
if(!editing_town && (x == -1 || x == 48 || y == -1 || y == 48)){
|
||
colour.a = 128;
|
||
}
|
||
|
||
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), destrec, sf::BlendAlpha, colour);
|
||
}
|
||
|
||
void draw_one_tiny_terrain_spot (short i,short j,ter_num_t terrain_to_draw,short size,bool road) {
|
||
rectangle dest_rect = {0,0,size,size},from_rect = {0,0,12,12};
|
||
short picture_wanted;
|
||
bool drawLargeIcon = false;
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
|
||
picture_wanted = scenario.ter_types[terrain_to_draw].map_pic;
|
||
if(picture_wanted == NO_PIC) {
|
||
drawLargeIcon = true;
|
||
picture_wanted = scenario.ter_types[terrain_to_draw].picture;
|
||
}
|
||
|
||
dest_rect.offset(8 + TER_RECT_UL_X + size * i, 8 + TER_RECT_UL_Y + size * j);
|
||
if(drawLargeIcon) {
|
||
if(picture_wanted >= 1000) {
|
||
graf_pos_ref(source_gworld, from_rect) = spec_scen_g.find_graphic(picture_wanted % 1000);
|
||
} else if(picture_wanted >= 960) {
|
||
source_gworld = &ResMgr::graphics.get("teranim");
|
||
from_rect = calc_rect(4 * ((picture_wanted - 960) / 5),(picture_wanted - 960) % 5);
|
||
} else {
|
||
int which_sheet = picture_wanted / 50;
|
||
source_gworld = &ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet));
|
||
picture_wanted %= 50;
|
||
from_rect = calc_rect(picture_wanted % 10, picture_wanted / 10);
|
||
}
|
||
rect_draw_some_item(*source_gworld, from_rect, mainPtr(), dest_rect);
|
||
} else {
|
||
if(picture_wanted >= 1000) {
|
||
std::shared_ptr<const sf::Texture> from_gw;
|
||
graf_pos_ref(from_gw, from_rect) = spec_scen_g.find_graphic(picture_wanted % 1000);
|
||
from_rect.right = from_rect.left + 12;
|
||
from_rect.bottom = from_rect.top + 12;
|
||
picture_wanted /= 1000; picture_wanted--;
|
||
from_rect.offset((picture_wanted / 3) * 12, (picture_wanted % 3) * 12);
|
||
rect_draw_some_item(*from_gw, from_rect, mainPtr(), dest_rect);
|
||
} else {
|
||
sf::Texture& small_ter_gworld = *ResMgr::graphics.get("termap");
|
||
if(picture_wanted >= 960) {
|
||
picture_wanted -= 960;
|
||
from_rect.offset(12 * 20, (picture_wanted - 960) * 12);
|
||
rect_draw_some_item(small_ter_gworld, from_rect, mainPtr(), dest_rect);
|
||
} else {
|
||
from_rect.offset((picture_wanted % 20) * 12,(picture_wanted / 20) * 12);
|
||
rect_draw_some_item(small_ter_gworld, from_rect, mainPtr(), dest_rect);
|
||
}
|
||
}
|
||
}
|
||
if(road) {
|
||
rectangle road_rect = dest_rect;
|
||
int border = (size - 4) / 2;
|
||
road_rect.inset(border,border);
|
||
rect_draw_some_item(*ResMgr::graphics.get("edbuttons"), {120, 231, 124, 235}, mainPtr(), road_rect);
|
||
}
|
||
if(mouse_spot.x >= 0 && mouse_spot.y >= 0) {
|
||
location where_draw(i,j);
|
||
bool need_hilite = false, large_hilite = false;
|
||
int d = dist(where_draw, mouse_spot);
|
||
if(overall_mode == MODE_SMALL_PAINTBRUSH && d <= 1) {
|
||
need_hilite = true;
|
||
large_hilite = true;
|
||
} else if((overall_mode == MODE_ERASER || overall_mode == MODE_SMALL_SPRAYCAN) && d <= 2) {
|
||
need_hilite = true;
|
||
large_hilite = true;
|
||
} else if((overall_mode == MODE_LARGE_PAINTBRUSH || overall_mode == MODE_LARGE_SPRAYCAN) && d <= 4) {
|
||
need_hilite = true;
|
||
large_hilite = true;
|
||
} else if(where_draw == mouse_spot)
|
||
need_hilite = true;
|
||
if(need_hilite) {
|
||
fill_rect(mainPtr(), dest_rect, hilite_colour);
|
||
if(large_hilite && where_draw == mouse_spot)
|
||
fill_rect(mainPtr(), dest_rect, hilite_colour);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Input terrain currently trying to draw. Get back rectangle in terrain template containing
|
||
desired pixmap, or rectangle to darkness if desired map not present */
|
||
rectangle get_template_rect (unsigned short type_wanted) {
|
||
rectangle store_rect;
|
||
short picture_wanted;
|
||
|
||
picture_wanted = scenario.ter_types[type_wanted].picture;
|
||
if(picture_wanted >= 1000)
|
||
picture_wanted = 0;
|
||
picture_wanted = picture_wanted % 50;
|
||
store_rect.top = 0 + (picture_wanted / 10) * BITMAP_HEIGHT;
|
||
store_rect.bottom = store_rect.top + BITMAP_HEIGHT;
|
||
store_rect.left = 0 + (picture_wanted % 10) * BITMAP_WIDTH;
|
||
store_rect.right = store_rect.left + BITMAP_WIDTH;
|
||
|
||
return store_rect;
|
||
}
|
||
|
||
void draw_frames() {
|
||
location which_pt;
|
||
rectangle draw_rect;
|
||
|
||
for(short q = 0; q < 9; q++) {
|
||
for(short r = 0; r < 9; r++) {
|
||
which_pt.x = cen_x + q - 4;
|
||
which_pt.y = cen_y + r - 4;
|
||
draw_rect.top = 23 + r * 36;
|
||
draw_rect.bottom = 58 + r * 36;
|
||
draw_rect.left = 23 + q * 28;
|
||
draw_rect.right = 50 + q * 28;
|
||
draw_rect.offset(TER_RECT_UL_X,TER_RECT_UL_Y);
|
||
for(short i = 0; i < town->wandering_locs.size(); i++)
|
||
if((which_pt.x == town->wandering_locs[i].x) &&
|
||
(which_pt.y == town->wandering_locs[i].y)) {
|
||
|
||
frame_rect(mainPtr(), draw_rect, Colours::RED);
|
||
}
|
||
for(short i = 0; i < town->start_locs.size(); i++)
|
||
if((which_pt.x == town->start_locs[i].x) &&
|
||
(which_pt.y == town->start_locs[i].y)) {
|
||
frame_rect(mainPtr(), draw_rect, Colours::PINK);
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
static void place_selected_terrain(ter_num_t ter, rectangle draw_rect) {
|
||
pic_num_t picture_wanted = scenario.ter_types[ter].picture;
|
||
rectangle source_rect;
|
||
if(picture_wanted >= 1000) {
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000);
|
||
rect_draw_some_item(*source_gworld, source_rect,mainPtr(),draw_rect);
|
||
}
|
||
else if(picture_wanted >= 960) {
|
||
picture_wanted -= 960;
|
||
source_rect.left = 112 * (picture_wanted / 5);
|
||
source_rect.right = source_rect.left + 28;
|
||
source_rect.top = 36 * (picture_wanted % 5);
|
||
source_rect.bottom = source_rect.top + 36;
|
||
rect_draw_some_item(*ResMgr::graphics.get("teranim"),source_rect,mainPtr(),draw_rect);
|
||
}
|
||
else {
|
||
source_rect = get_template_rect(ter);
|
||
int which_sheet = picture_wanted / 50;
|
||
sf::Texture& terrain_gworld = *ResMgr::graphics.get("ter" + std::to_string(1 + which_sheet));
|
||
rect_draw_some_item(terrain_gworld,source_rect,
|
||
mainPtr(),draw_rect);
|
||
}
|
||
short small_i = get_small_icon(ter);
|
||
rectangle tiny_to = draw_rect;
|
||
tiny_to.top = tiny_to.bottom - 7;
|
||
tiny_to.left = tiny_to.right - 7;
|
||
rectangle tiny_from = base_small_button_from;
|
||
tiny_from.offset(7 * (small_i % 30),7 * (small_i / 30));
|
||
if(small_i >= 0 && small_i < 255)
|
||
rect_draw_some_item(*ResMgr::graphics.get("edbuttons"),tiny_from,mainPtr(),tiny_to);
|
||
}
|
||
|
||
extern std::vector<std::string> attitude_disp_strs;
|
||
|
||
void place_location() {
|
||
std::ostringstream sout;
|
||
rectangle draw_rect,source_rect;
|
||
rectangle text_rect = {0,0,12,100};
|
||
text_rect.offset(RIGHT_AREA_UL_X,RIGHT_AREA_UL_Y);
|
||
short picture_wanted;
|
||
tileImage(mainPtr(), terrain_buttons_rect, bg[17]);
|
||
frame_rect(mainPtr(), terrain_buttons_rect, sf::Color::Black);
|
||
location mouse = translate_mouse_coordinates(sf::Mouse::getPosition(mainPtr()));
|
||
|
||
location moveTo(5, terrain_rects[16 * TYPE_ROWS_DRAWING - 1].top + 18);
|
||
if(overall_mode == MODE_EDIT_TYPES) moveTo.y = terrain_rects[16 * TYPE_ROWS_EDITING -1].top + 18;
|
||
draw_rect = text_rect;
|
||
draw_rect.offset(moveTo);
|
||
// Drawing modes and type editing mode, show tooltips for the type buttons
|
||
if(overall_mode < MODE_MAIN_SCREEN || overall_mode == MODE_EDIT_TYPES) {
|
||
rectangle buttons_rect = terrain_buttons_rect;
|
||
int rows = TYPE_ROWS_DRAWING;
|
||
if(overall_mode == MODE_EDIT_TYPES){
|
||
buttons_rect = terrain_buttons_rect_editing;
|
||
rows = TYPE_ROWS_EDITING;
|
||
}
|
||
if(mouse.in(buttons_rect)) {
|
||
location rel_mouse = mouse;
|
||
rel_mouse.x -= RIGHT_AREA_UL_X;
|
||
rel_mouse.y -= RIGHT_AREA_UL_Y;
|
||
for(int i = 0; i < 16 * rows; i++) {
|
||
if(rel_mouse.in(terrain_rects[i])) {
|
||
int first = pal_sbar->getPosition() * 16;
|
||
switch(draw_mode) {
|
||
case DRAW_TERRAIN:
|
||
if(first + i < scenario.ter_types.size())
|
||
sout << "Terrain: " << scenario.ter_types[first + i].name;
|
||
break;
|
||
case DRAW_ITEM:
|
||
if(first + i < scenario.scen_items.size())
|
||
sout << "Item: " << scenario.scen_items[first + i].full_name;
|
||
break;
|
||
case DRAW_MONST:
|
||
if(first + i + 1 < scenario.scen_monsters.size()){
|
||
sout << "Creature: " << scenario.scen_monsters[first + i + 1].m_name;
|
||
sout << " (" << attitude_disp_strs[(int)scenario.scen_monsters[first + i + 1].default_attitude] << ")";
|
||
}
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// Edit types, when none are hovered
|
||
if(sout.str().empty() && overall_mode == MODE_EDIT_TYPES){
|
||
moveTo.y += 13;
|
||
std::string type = "terrain";
|
||
if(draw_mode == DRAW_MONST) type = "monster";
|
||
else if(draw_mode == DRAW_ITEM) type = "item";
|
||
sout << "Click " << type << " to edit.";
|
||
}
|
||
// Modes showing the terrain map, show the highlighted spot coords or screen center coords
|
||
if(sout.str().empty() && mouse.in(terrain_rect) && mouse_spot.x >= 0)
|
||
sout << "Under mouse: x = " << (cen_x - 4 + mouse_spot.x)
|
||
<< ", y = " << (cen_y - 4 + mouse_spot.y);
|
||
if(sout.str().empty())
|
||
sout << "Center: x = " << cen_x << ", y = " << cen_y;
|
||
TextStyle style;
|
||
style.lineHeight = 12;
|
||
win_draw_string(mainPtr(), draw_rect, sout.str(), eTextMode::LEFT_TOP, style);
|
||
clear_sstr(sout);
|
||
|
||
if(overall_mode != MODE_EDIT_TYPES){
|
||
moveTo = location(260, terrain_rects[255].top + 18);
|
||
draw_rect = text_rect;
|
||
draw_rect.offset(moveTo);
|
||
sout << current_terrain_type;
|
||
win_draw_string(mainPtr(), draw_rect, sout.str(), eTextMode::LEFT_TOP, style);
|
||
clear_sstr(sout);
|
||
}
|
||
|
||
if(overall_mode < MODE_MAIN_SCREEN) {
|
||
moveTo = location(5,terrain_rects[255].bottom + 121);
|
||
draw_rect = text_rect;
|
||
draw_rect.offset(moveTo);
|
||
win_draw_string(mainPtr(), draw_rect, current_string[0], eTextMode::LEFT_TOP, style);
|
||
moveTo = location(RIGHT_AREA_WIDTH / 2,terrain_rects[255].bottom + 121);
|
||
draw_rect = text_rect;
|
||
draw_rect.offset(moveTo);
|
||
win_draw_string(mainPtr(), draw_rect, current_string[1], eTextMode::LEFT_TOP, style);
|
||
}
|
||
|
||
draw_rect.top = palette_buttons[0][0].top + terrain_rects[255].bottom + 5;
|
||
draw_rect.left = palette_buttons[9][0].right + 10; // + 17;
|
||
draw_rect.bottom = draw_rect.top + 36;
|
||
draw_rect.right = draw_rect.left + 28;
|
||
|
||
if(overall_mode < MODE_MAIN_SCREEN) {
|
||
place_selected_terrain(current_terrain_type, draw_rect);
|
||
extern short mode_count;
|
||
bool draw_field = false;
|
||
if(overall_mode == MODE_PLACE_CREATURE || (overall_mode == MODE_PASTE && boost::get<cTownperson>(&clipboard))) {
|
||
rectangle to_rect = draw_rect;
|
||
mon_num_t m_num = overall_mode == MODE_PLACE_CREATURE ? mode_count : boost::get<cTownperson>(&clipboard)->number;
|
||
picture_wanted = scenario.scen_monsters[m_num].picture_num;
|
||
if(picture_wanted >= 4000) {
|
||
picture_wanted %= 1000;
|
||
to_rect.width() = to_rect.width() / 2;
|
||
to_rect.height() = to_rect.height() / 2;
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted);
|
||
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
picture_wanted++;
|
||
to_rect.offset(to_rect.width(), 0);
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted);
|
||
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
picture_wanted++;
|
||
to_rect.offset(-to_rect.width(), to_rect.height());
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted);
|
||
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
picture_wanted++;
|
||
to_rect.offset(to_rect.width(), 0);
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted);
|
||
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
} else if(picture_wanted >= 3000) {
|
||
picture_wanted %= 1000;
|
||
to_rect.width() = to_rect.width() / 2;
|
||
to_rect.height() = to_rect.height() / 2;
|
||
to_rect.offset(to_rect.width() / 2, 0);
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted);
|
||
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
picture_wanted++;
|
||
to_rect.offset(0, to_rect.height());
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted);
|
||
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
} else if(picture_wanted >= 2000) {
|
||
picture_wanted %= 1000;
|
||
to_rect.width() = to_rect.width() / 2;
|
||
to_rect.height() = to_rect.height() / 2;
|
||
to_rect.offset(0, to_rect.height() / 2);
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted);
|
||
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
picture_wanted++;
|
||
to_rect.offset(to_rect.width(), 0);
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted);
|
||
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
} else if(picture_wanted >= 1000) {
|
||
picture_wanted %= 1000;
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted);
|
||
rect_draw_some_item(*source_gworld, source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
} else {
|
||
auto pic_info = m_pic_index[picture_wanted];
|
||
picture_wanted = pic_info.i;
|
||
auto monst_gworld = [](pic_num_t sheet_num) {
|
||
return *ResMgr::graphics.get("monst" + std::to_string(1 + sheet_num));
|
||
};
|
||
if(pic_info.x == 2 && pic_info.y == 2) {
|
||
to_rect.width() = to_rect.width() / 2;
|
||
to_rect.height() = to_rect.height() / 2;
|
||
source_rect = calc_rect(2 * ((picture_wanted % 20) / 10), (picture_wanted % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(picture_wanted / 20), source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
picture_wanted++;
|
||
to_rect.offset(to_rect.width(), 0);
|
||
source_rect = calc_rect(2 * ((picture_wanted % 20) / 10), (picture_wanted % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(picture_wanted / 20), source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
picture_wanted++;
|
||
to_rect.offset(-to_rect.width(), to_rect.height());
|
||
source_rect = calc_rect(2 * ((picture_wanted % 20) / 10), (picture_wanted % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(picture_wanted / 20), source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
picture_wanted++;
|
||
to_rect.offset(to_rect.width(), 0);
|
||
source_rect = calc_rect(2 * ((picture_wanted % 20) / 10), (picture_wanted % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(picture_wanted / 20), source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
} else if(pic_info.y == 2) {
|
||
to_rect.width() = to_rect.width() / 2;
|
||
to_rect.height() = to_rect.height() / 2;
|
||
to_rect.offset(to_rect.width() / 2, 0);
|
||
source_rect = calc_rect(2 * ((picture_wanted % 20) / 10), (picture_wanted % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(picture_wanted / 20), source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
picture_wanted++;
|
||
to_rect.offset(0, to_rect.height());
|
||
source_rect = calc_rect(2 * ((picture_wanted % 20) / 10), (picture_wanted % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(picture_wanted / 20), source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
} else if(pic_info.x == 2) {
|
||
to_rect.width() = to_rect.width() / 2;
|
||
to_rect.height() = to_rect.height() / 2;
|
||
to_rect.offset(0, to_rect.height() / 2);
|
||
source_rect = calc_rect(2 * ((picture_wanted % 20) / 10), (picture_wanted % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(picture_wanted / 20), source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
picture_wanted++;
|
||
to_rect.offset(to_rect.width(), 0);
|
||
source_rect = calc_rect(2 * ((picture_wanted % 20) / 10), (picture_wanted % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(picture_wanted / 20), source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
} else {
|
||
source_rect = calc_rect(2 * ((picture_wanted % 20) / 10), (picture_wanted % 20) % 10);
|
||
rect_draw_some_item(monst_gworld(picture_wanted / 20), source_rect, mainPtr(), to_rect, sf::BlendAlpha);
|
||
}
|
||
}
|
||
} else if(overall_mode == MODE_PLACE_ITEM || (overall_mode == MODE_PASTE && boost::get<cTown::cItem>(&clipboard))) {
|
||
item_num_t i_num = overall_mode == MODE_PLACE_ITEM ? mode_count : boost::get<cTown::cItem>(&clipboard)->code;
|
||
picture_wanted = scenario.scen_items[i_num].graphic_num;
|
||
if(picture_wanted >= 1000) {
|
||
std::shared_ptr<const sf::Texture> source_gworld;
|
||
graf_pos_ref(source_gworld, source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000);
|
||
rect_draw_some_item(*source_gworld,source_rect,mainPtr(),draw_rect,sf::BlendAlpha);
|
||
} else if(picture_wanted < 55) {
|
||
source_rect = calc_rect(picture_wanted % 5,picture_wanted / 5);
|
||
rect_draw_some_item(*ResMgr::graphics.get("objects"),source_rect,mainPtr(),draw_rect,sf::BlendAlpha);
|
||
} else {
|
||
draw_rect.inset(5, 9);
|
||
rectangle tiny_from = {0,0,18,18};
|
||
tiny_from.offset((picture_wanted % 10) * 18,(picture_wanted / 10) * 18);
|
||
rect_draw_some_item(*ResMgr::graphics.get("tinyobj"),tiny_from,mainPtr(),draw_rect,sf::BlendAlpha);
|
||
draw_rect.inset(-5, -9);
|
||
}
|
||
} else if(overall_mode == MODE_TOGGLE_SPECIAL_DOT) {
|
||
draw_field = true;
|
||
source_rect = calc_rect(4, 0);
|
||
} else if(overall_mode == MODE_PLACE_FORCECAGE) {
|
||
draw_field = true;
|
||
source_rect = calc_rect(0, 0);
|
||
} else if(overall_mode == MODE_PLACE_WEB) {
|
||
draw_field = true;
|
||
source_rect = calc_rect(5, 0);
|
||
} else if(overall_mode == MODE_PLACE_CRATE) {
|
||
draw_field = true;
|
||
source_rect = calc_rect(6, 0);
|
||
} else if(overall_mode == MODE_PLACE_BARREL) {
|
||
draw_field = true;
|
||
source_rect = calc_rect(7, 0);
|
||
} else if(overall_mode == MODE_PLACE_FIRE_BARRIER) {
|
||
source_rect = calc_rect(8, 4);
|
||
rect_draw_some_item(*ResMgr::graphics.get("teranim"),source_rect,mainPtr(),draw_rect,sf::BlendAlpha);
|
||
} else if(overall_mode == MODE_PLACE_FORCE_BARRIER) {
|
||
source_rect = calc_rect(8, 4);
|
||
rect_draw_some_item(*ResMgr::graphics.get("teranim"),source_rect,mainPtr(),draw_rect,sf::BlendAlpha);
|
||
} else if(overall_mode == MODE_PLACE_QUICKFIRE) {
|
||
draw_field = true;
|
||
source_rect = calc_rect(7, 1);
|
||
} else if(overall_mode == MODE_PLACE_STONE_BLOCK) {
|
||
draw_field = true;
|
||
source_rect = calc_rect(3, 0);
|
||
} else if(overall_mode == MODE_PLACE_SFX) {
|
||
draw_field = true;
|
||
source_rect = calc_rect(mode_count, 3);
|
||
} else if(overall_mode == MODE_TOGGLE_ROAD) {
|
||
draw_field = true;
|
||
source_rect = calc_rect(0, 2);
|
||
}
|
||
if(draw_field) {
|
||
const sf::Texture& fields_gworld = *ResMgr::graphics.get("fields");
|
||
rect_draw_some_item(fields_gworld,source_rect,mainPtr(),draw_rect,sf::BlendAlpha);
|
||
}
|
||
draw_rect.offset(0,40);
|
||
place_selected_terrain(current_ground, draw_rect);
|
||
}
|
||
}
|
||
|
||
void set_string(std::string string,std::string string2) {
|
||
current_string[0] = string;
|
||
current_string[1] = string2;
|
||
}
|
||
|
||
bool is_special(short i,short j) {
|
||
location check(i,j);
|
||
|
||
for(auto loc : get_current_area()->special_locs)
|
||
if(loc == check && loc.spec >= 0)
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
void sort_specials() {
|
||
}
|
||
|
||
bool is_spot(short i,short j){
|
||
if(editing_town)
|
||
return is_field_type(i,j,SPECIAL_SPOT);
|
||
else if(i >= 0 && i < 48 && j >= 0 && j < 48)
|
||
return current_terrain->special_spot[i][j];
|
||
return false;
|
||
}
|
||
|
||
bool is_road(short i,short j){
|
||
if(editing_town)
|
||
return is_field_type(i,j,SPECIAL_ROAD);
|
||
else if(i >= 0 && i < 48 && j >= 0 && j < 48)
|
||
return current_terrain->roads[i][j];
|
||
return false;
|
||
}
|
||
|
||
bool is_field_type(short i,short j,eFieldType field_type) {
|
||
for(short k = 0; k < town->preset_fields.size(); k++)
|
||
if((town->preset_fields[k].type == field_type) &&
|
||
(town->preset_fields[k].loc.x == i) &&
|
||
(town->preset_fields[k].loc.y == j))
|
||
return true;
|
||
return false;
|
||
}
|
||
|
||
void make_field_type(short i,short j,eFieldType field_type,field_stroke_t& stroke) {
|
||
if(is_field_type(i,j,field_type))
|
||
return;
|
||
stroke.insert(loc(i,j));
|
||
|
||
for(short k = 0; k < town->preset_fields.size(); k++)
|
||
if(town->preset_fields[k].type == 0) {
|
||
town->preset_fields[k].loc.x = i;
|
||
town->preset_fields[k].loc.y = j;
|
||
town->preset_fields[k].type = field_type;
|
||
return;
|
||
}
|
||
cTown::cField the_field;
|
||
the_field.loc.x = i;
|
||
the_field.loc.y = j;
|
||
the_field.type = field_type;
|
||
town->preset_fields.push_back(the_field);
|
||
}
|
||
|
||
|
||
void take_field_type(short i,short j,eFieldType field_type,clear_field_stroke_t& stroke) {
|
||
for(short k = 0; k < town->preset_fields.size(); k++)
|
||
if((town->preset_fields[k].type == field_type) &&
|
||
(town->preset_fields[k].loc.x == i) &&
|
||
(town->preset_fields[k].loc.y == j)) {
|
||
town->preset_fields[k].type = FIELD_DISPEL;
|
||
stroke[loc(i,j)].push_back(field_type);
|
||
return;
|
||
}
|
||
}
|
||
|
||
bool container_there(location l) {
|
||
if(!editing_town)
|
||
return false;
|
||
if(scenario.ter_types[town->terrain(l.x,l.y)].special == eTerSpec::IS_A_CONTAINER)
|
||
return true;
|
||
if(is_field_type(l.x,l.y, OBJECT_BARREL))
|
||
return true;
|
||
if(is_field_type(l.x,l.y, OBJECT_CRATE))
|
||
return true;
|
||
return 0;
|
||
}
|
||
|
||
void record_display_strings(){}
|
||
|
||
// Translate mouse event coordinates based on the global view and viewport
|
||
sf::Vector2f translate_mouse_coordinates(sf::Vector2i const point) {
|
||
return mainPtr().mapPixelToCoords(point, mainView);
|
||
}
|
||
|
||
sf::RenderWindow& mainPtr() {
|
||
static sf::RenderWindow instance;
|
||
return instance;
|
||
}
|