~widelands-dev/widelands/dynamic_tribe_loading_datadir

« back to all changes in this revision

Viewing changes to src/wui/interactive_base.cc

  • Committer: GunChleoc
  • Date: 2017-11-03 18:46:02 UTC
  • mfrom: (8415.1.57 trunk)
  • Revision ID: fios@foramnagaidhlig.net-20171103184602-15bplqmg1kwf5h1s
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
#include "logic/maphollowregion.h"
44
44
#include "logic/maptriangleregion.h"
45
45
#include "logic/player.h"
 
46
#include "logic/widelands_geometry.h"
46
47
#include "profile/profile.h"
47
48
#include "scripting/lua_interface.h"
48
 
#include "wui/edge_overlay_manager.h"
49
 
#include "wui/field_overlay_manager.h"
50
49
#include "wui/game_chat_menu.h"
51
50
#include "wui/game_debug_ui.h"
52
51
#include "wui/interactive_player.h"
56
55
#include "wui/minimap.h"
57
56
#include "wui/unique_window_handler.h"
58
57
 
59
 
// TODO(tiborb): This constant is temporary and should be replaced by command line switch
60
 
constexpr bool AItrainingMode = false;
 
58
namespace {
61
59
 
62
60
using Widelands::Area;
63
61
using Widelands::CoordPath;
68
66
using Widelands::MapObject;
69
67
using Widelands::TCoords;
70
68
 
71
 
struct InteractiveBaseInternals {
72
 
        MiniMap* mm;
73
 
        MiniMap::Registry minimap;
74
 
        std::unique_ptr<QuickNavigation> quicknavigation;
 
69
int caps_to_buildhelp(const Widelands::NodeCaps caps) {
 
70
        if (caps & Widelands::BUILDCAPS_MINE) {
 
71
                return Widelands::Field::Buildhelp_Mine;
 
72
        }
 
73
        if ((caps & Widelands::BUILDCAPS_SIZEMASK) == Widelands::BUILDCAPS_BIG) {
 
74
                if (caps & Widelands::BUILDCAPS_PORT) {
 
75
                        return Widelands::Field::Buildhelp_Port;
 
76
                }
 
77
                return Widelands::Field::Buildhelp_Big;
 
78
        }
 
79
        if ((caps & Widelands::BUILDCAPS_SIZEMASK) == Widelands::BUILDCAPS_MEDIUM) {
 
80
                return Widelands::Field::Buildhelp_Medium;
 
81
        }
 
82
        if ((caps & Widelands::BUILDCAPS_SIZEMASK) == Widelands::BUILDCAPS_SMALL) {
 
83
                return Widelands::Field::Buildhelp_Small;
 
84
        }
 
85
        if (caps & Widelands::BUILDCAPS_FLAG) {
 
86
                return Widelands::Field::Buildhelp_Flag;
 
87
        }
 
88
        return Widelands::Field::Buildhelp_None;
 
89
}
75
90
 
76
 
        explicit InteractiveBaseInternals(QuickNavigation* qnav) : mm(nullptr), quicknavigation(qnav) {
77
 
        }
78
 
};
 
91
}  // namespace
79
92
 
80
93
InteractiveBase::InteractiveBase(EditorGameBase& the_egbase, Section& global_s)
81
 
   : MapView(nullptr, 0, 0, g_gr->get_xres(), g_gr->get_yres(), *this),
 
94
   : UI::Panel(nullptr, 0, 0, g_gr->get_xres(), g_gr->get_yres()),
 
95
     show_workarea_preview_(global_s.get_bool("workareapreview", true)),
 
96
     buildhelp_(false),
 
97
     map_view_(this, the_egbase.map(), 0, 0, g_gr->get_xres(), g_gr->get_yres()),
82
98
     // Initialize chatoveraly before the toolbar so it is below
83
 
     show_workarea_preview_(global_s.get_bool("workareapreview", true)),
84
99
     chat_overlay_(new ChatOverlay(this, 10, 25, get_w() / 2, get_h() - 25)),
85
100
     toolbar_(this, 0, 0, UI::Box::Horizontal),
86
 
     m(new InteractiveBaseInternals(new QuickNavigation(this))),
87
 
     field_overlay_manager_(new FieldOverlayManager()),
88
 
     edge_overlay_manager_(new EdgeOverlayManager()),
 
101
     quick_navigation_(&map_view_),
89
102
     egbase_(the_egbase),
90
103
#ifndef NDEBUG  //  not in releases
91
104
     display_flags_(dfDebug),
95
108
     lastframe_(SDL_GetTicks()),
96
109
     frametime_(0),
97
110
     avg_usframetime_(0),
98
 
     jobid_(0),
99
 
     road_buildhelp_overlay_jobid_(0),
100
111
     buildroad_(nullptr),
101
112
     road_build_player_(0),
102
113
     unique_window_handler_(new UniqueWindowHandler()),
108
119
                    g_gr->images().get("images/wui/overlays/workarea2.png"),
109
120
                    g_gr->images().get("images/wui/overlays/workarea1.png")} {
110
121
 
 
122
        // Load the buildhelp icons.
 
123
        {
 
124
                BuildhelpOverlay* buildhelp_overlay = buildhelp_overlays_;
 
125
                const char* filenames[] = {
 
126
                   "images/wui/overlays/set_flag.png", "images/wui/overlays/small.png",
 
127
                   "images/wui/overlays/medium.png",   "images/wui/overlays/big.png",
 
128
                   "images/wui/overlays/mine.png",     "images/wui/overlays/port.png"};
 
129
                const char* const* filename = filenames;
 
130
 
 
131
                //  Special case for flag, which has a different formula for hotspot_y.
 
132
                buildhelp_overlay->pic = g_gr->images().get(*filename);
 
133
                buildhelp_overlay->hotspot =
 
134
                   Vector2i(buildhelp_overlay->pic->width() / 2, buildhelp_overlay->pic->height() - 1);
 
135
 
 
136
                const BuildhelpOverlay* const buildhelp_overlays_end =
 
137
                   buildhelp_overlay + Widelands::Field::Buildhelp_None;
 
138
                for (;;) {  // The other buildhelp overlays.
 
139
                        ++buildhelp_overlay;
 
140
                        ++filename;
 
141
                        if (buildhelp_overlay == buildhelp_overlays_end)
 
142
                                break;
 
143
                        buildhelp_overlay->pic = g_gr->images().get(*filename);
 
144
                        buildhelp_overlay->hotspot =
 
145
                           Vector2i(buildhelp_overlay->pic->width() / 2, buildhelp_overlay->pic->height() / 2);
 
146
                }
 
147
        }
 
148
 
111
149
        resize_chat_overlay();
112
150
 
113
151
        graphic_resolution_changed_subscriber_ = Notifications::subscribe<GraphicResolutionChanged>(
114
152
           [this](const GraphicResolutionChanged& message) {
115
153
                   set_size(message.width, message.height);
 
154
                   map_view_.set_size(message.width, message.height);
116
155
                   resize_chat_overlay();
117
156
                   adjust_toolbar_position();
118
157
                });
119
158
        sound_subscriber_ = Notifications::subscribe<NoteSound>([this](const NoteSound& note) {
120
159
                if (note.stereo_position != std::numeric_limits<uint32_t>::max()) {
121
160
                        g_sound_handler.play_fx(note.fx, note.stereo_position, note.priority);
122
 
                } else if (note.coords != Widelands::Coords(-1, -1)) {
 
161
                } else if (note.coords != Widelands::Coords::null()) {
123
162
                        g_sound_handler.play_fx(note.fx, stereo_position(note.coords), note.priority);
124
163
                }
125
164
        });
126
165
 
127
166
        toolbar_.set_layout_toplevel(true);
128
 
        changeview.connect([this] { mainview_move(); });
 
167
        map_view_.changeview.connect([this] { mainview_move(); });
 
168
        map_view()->field_clicked.connect([this](const Widelands::NodeAndTriangle<>& node_and_triangle) {
 
169
                set_sel_pos(node_and_triangle);
 
170
        });
 
171
        map_view_.track_selection.connect([this](const Widelands::NodeAndTriangle<>& node_and_triangle) {
 
172
                if (!sel_.freeze) {
 
173
                        set_sel_pos(node_and_triangle);
 
174
                }
 
175
        });
129
176
 
130
177
        set_border_snap_distance(global_s.get_int("border_snap_distance", 0));
131
178
        set_panel_snap_distance(global_s.get_int("panel_snap_distance", 10));
150
197
        }
151
198
}
152
199
 
 
200
const InteractiveBase::BuildhelpOverlay*
 
201
InteractiveBase::get_buildhelp_overlay(const Widelands::NodeCaps caps) const {
 
202
        const int buildhelp_overlay_index = caps_to_buildhelp(caps);
 
203
        if (buildhelp_overlay_index < Widelands::Field::Buildhelp_None) {
 
204
                return &buildhelp_overlays_[buildhelp_overlay_index];
 
205
        }
 
206
        return nullptr;
 
207
}
 
208
 
153
209
UniqueWindowHandler& InteractiveBase::unique_windows() {
154
210
        return *unique_window_handler_;
155
211
}
156
212
 
157
213
void InteractiveBase::set_sel_pos(Widelands::NodeAndTriangle<> const center) {
158
 
        Map& map = egbase().map();
159
 
 
160
 
        // Remove old sel pointer
161
 
        if (sel_.jobid)
162
 
                field_overlay_manager_->remove_overlay(sel_.jobid);
163
 
        const FieldOverlayManager::OverlayId jobid = sel_.jobid =
164
 
           field_overlay_manager_->next_overlay_id();
165
 
 
 
214
        const Map& map = egbase().map();
166
215
        sel_.pos = center;
167
216
 
168
 
        //  register sel overlay position
169
 
        if (sel_.triangles) {
170
 
                assert(center.triangle.t == TCoords<>::D || center.triangle.t == TCoords<>::R);
171
 
                Widelands::MapTriangleRegion<> mr(map, Area<TCoords<>>(center.triangle, sel_.radius));
172
 
                do
173
 
                        field_overlay_manager_->register_overlay(
174
 
                           mr.location(), sel_.pic, 7, Vector2i::invalid(), jobid);
175
 
                while (mr.advance(map));
176
 
        } else {
177
 
                Widelands::MapRegion<> mr(map, Area<>(center.node, sel_.radius));
178
 
                do
179
 
                        field_overlay_manager_->register_overlay(
180
 
                           mr.location(), sel_.pic, 7, Vector2i::invalid(), jobid);
181
 
                while (mr.advance(map));
182
 
                if (upcast(InteractiveGameBase const, igbase, this))
183
 
                        if (upcast(Widelands::ProductionSite, productionsite, map[center.node].get_immovable())) {
184
 
                                if (upcast(InteractivePlayer const, iplayer, igbase)) {
185
 
                                        const Widelands::Player& player = iplayer->player();
186
 
                                        if (!player.see_all() &&
187
 
                                            (1 >= player.vision(Widelands::Map::get_index(center.node, map.get_width())) ||
188
 
                                             player.is_hostile(*productionsite->get_owner())))
189
 
                                                return set_tooltip("");
190
 
                                }
191
 
                                set_tooltip(
192
 
                                   productionsite->info_string(Widelands::Building::InfoStringFormat::kTooltip));
193
 
                                return;
 
217
        if (upcast(InteractiveGameBase const, igbase, this))
 
218
                if (upcast(Widelands::ProductionSite, productionsite, map[center.node].get_immovable())) {
 
219
                        if (upcast(InteractivePlayer const, iplayer, igbase)) {
 
220
                                const Widelands::Player& player = iplayer->player();
 
221
                                if (!player.see_all() &&
 
222
                                    (1 >= player.vision(Widelands::Map::get_index(center.node, map.get_width())) ||
 
223
                                     player.is_hostile(*productionsite->get_owner())))
 
224
                                        return set_tooltip("");
194
225
                        }
195
 
        }
 
226
                        set_tooltip(productionsite->info_string(Widelands::Building::InfoStringFormat::kTooltip));
 
227
                        return;
 
228
                }
196
229
        set_tooltip("");
197
230
}
198
231
 
213
246
        sel_.pic = image;
214
247
        set_sel_pos(get_sel_pos());  //  redraw
215
248
}
 
249
 
 
250
TextToDraw InteractiveBase::get_text_to_draw() const {
 
251
        TextToDraw text_to_draw = TextToDraw::kNone;
 
252
        auto display_flags = get_display_flags();
 
253
        if (display_flags & InteractiveBase::dfShowCensus) {
 
254
                text_to_draw = text_to_draw | TextToDraw::kCensus;
 
255
        }
 
256
        if (display_flags & InteractiveBase::dfShowStatistics) {
 
257
                text_to_draw = text_to_draw | TextToDraw::kStatistics;
 
258
        }
 
259
        return text_to_draw;
 
260
}
 
261
 
216
262
void InteractiveBase::unset_sel_picture() {
217
263
        set_sel_picture(g_gr->images().get("images/ui_basic/fsel.png"));
218
264
}
219
265
 
220
266
bool InteractiveBase::buildhelp() const {
221
 
        return field_overlay_manager_->buildhelp();
 
267
        return buildhelp_;
222
268
}
223
269
 
224
270
void InteractiveBase::show_buildhelp(bool t) {
225
 
        field_overlay_manager_->show_buildhelp(t);
 
271
        buildhelp_ = t;
226
272
        on_buildhelp_changed(t);
227
273
}
228
274
 
229
275
void InteractiveBase::toggle_buildhelp() {
230
 
        show_buildhelp(!field_overlay_manager_->buildhelp());
 
276
        show_buildhelp(!buildhelp());
231
277
}
232
278
 
233
279
UI::Button* InteractiveBase::add_toolbar_button(const std::string& image_basename,
254
300
}
255
301
 
256
302
// Show the given workareas at the given coords and returns the overlay job id associated
257
 
FieldOverlayManager::OverlayId InteractiveBase::show_work_area(const WorkareaInfo& workarea_info,
258
 
                                                               Widelands::Coords coords) {
259
 
        const uint8_t workareas_nrs = workarea_info.size();
260
 
        WorkareaInfo::size_type wa_index;
261
 
        switch (workareas_nrs) {
262
 
        case 0:
263
 
                return 0;  // no workarea
264
 
        case 1:
265
 
                wa_index = 5;
266
 
                break;
267
 
        case 2:
268
 
                wa_index = 3;
269
 
                break;
270
 
        case 3:
271
 
                wa_index = 0;
272
 
                break;
273
 
        default:
274
 
                throw wexception("Encountered unexpected WorkareaInfo size %i", workareas_nrs);
275
 
        }
276
 
        Widelands::Map& map = egbase_.map();
277
 
        FieldOverlayManager::OverlayId overlay_id = field_overlay_manager_->next_overlay_id();
278
 
 
279
 
        Widelands::HollowArea<> hollow_area(Widelands::Area<>(coords, 0), 0);
280
 
 
281
 
        // Iterate through the work areas, from building to its enhancement
282
 
        WorkareaInfo::const_iterator it = workarea_info.begin();
283
 
        for (; it != workarea_info.end(); ++it) {
284
 
                hollow_area.radius = it->first;
285
 
                Widelands::MapHollowRegion<> mr(map, hollow_area);
286
 
                do
287
 
                        field_overlay_manager_->register_overlay(
288
 
                           mr.location(), workarea_pics_[wa_index], 0, Vector2i::invalid(), overlay_id);
289
 
                while (mr.advance(map));
290
 
                wa_index++;
291
 
                hollow_area.hole_radius = hollow_area.radius;
292
 
        }
293
 
        return overlay_id;
294
 
}
295
 
 
296
 
void InteractiveBase::hide_work_area(FieldOverlayManager::OverlayId overlay_id) {
297
 
        field_overlay_manager_->remove_overlay(overlay_id);
 
303
void InteractiveBase::show_work_area(const WorkareaInfo& workarea_info, Widelands::Coords coords) {
 
304
        work_area_previews_[coords] = &workarea_info;
 
305
}
 
306
 
 
307
std::map<Coords, const Image*>
 
308
InteractiveBase::get_work_area_overlays(const Widelands::Map& map) const {
 
309
        std::map<Coords, const Image*> result;
 
310
        for (const auto& pair : work_area_previews_) {
 
311
                const Coords& coords = pair.first;
 
312
                const WorkareaInfo* workarea_info = pair.second;
 
313
                WorkareaInfo::size_type wa_index;
 
314
                switch (workarea_info->size()) {
 
315
                case 0:
 
316
                        continue;  // no workarea
 
317
                case 1:
 
318
                        wa_index = 5;
 
319
                        break;
 
320
                case 2:
 
321
                        wa_index = 3;
 
322
                        break;
 
323
                case 3:
 
324
                        wa_index = 0;
 
325
                        break;
 
326
                default:
 
327
                        throw wexception(
 
328
                           "Encountered unexpected WorkareaInfo size %i", static_cast<int>(workarea_info->size()));
 
329
                }
 
330
 
 
331
                Widelands::HollowArea<> hollow_area(Widelands::Area<>(coords, 0), 0);
 
332
 
 
333
                // Iterate through the work areas, from building to its enhancement
 
334
                WorkareaInfo::const_iterator it = workarea_info->begin();
 
335
                for (; it != workarea_info->end(); ++it) {
 
336
                        hollow_area.radius = it->first;
 
337
                        Widelands::MapHollowRegion<> mr(map, hollow_area);
 
338
                        do {
 
339
                                result[mr.location()] = workarea_pics_[wa_index];
 
340
                        } while (mr.advance(map));
 
341
                        wa_index++;
 
342
                        hollow_area.hole_radius = hollow_area.radius;
 
343
                }
 
344
        }
 
345
        return result;
 
346
}
 
347
 
 
348
void InteractiveBase::hide_work_area(const Widelands::Coords& coords) {
 
349
        work_area_previews_.erase(coords);
298
350
}
299
351
 
300
352
/**
318
370
        if (keyboard_free() && Panel::allow_user_input()) {
319
371
                if (get_key_state(SDL_SCANCODE_UP) ||
320
372
                    (get_key_state(SDL_SCANCODE_KP_8) && (SDL_GetModState() ^ KMOD_NUM))) {
321
 
                        pan_by(Vector2i(0, -scrollval));
 
373
                        map_view_.pan_by(Vector2i(0, -scrollval));
322
374
                }
323
375
                if (get_key_state(SDL_SCANCODE_DOWN) ||
324
376
                    (get_key_state(SDL_SCANCODE_KP_2) && (SDL_GetModState() ^ KMOD_NUM))) {
325
 
                        pan_by(Vector2i(0, scrollval));
 
377
                        map_view_.pan_by(Vector2i(0, scrollval));
326
378
                }
327
379
                if (get_key_state(SDL_SCANCODE_LEFT) ||
328
380
                    (get_key_state(SDL_SCANCODE_KP_4) && (SDL_GetModState() ^ KMOD_NUM))) {
329
 
                        pan_by(Vector2i(-scrollval, 0));
 
381
                        map_view_.pan_by(Vector2i(-scrollval, 0));
330
382
                }
331
383
                if (get_key_state(SDL_SCANCODE_RIGHT) ||
332
384
                    (get_key_state(SDL_SCANCODE_KP_6) && (SDL_GetModState() ^ KMOD_NUM))) {
333
 
                        pan_by(Vector2i(scrollval, 0));
 
385
                        map_view_.pan_by(Vector2i(scrollval, 0));
334
386
                }
335
387
        }
336
388
        egbase().think();  // Call game logic here. The game advances.
351
403
        avg_usframetime_ = ((avg_usframetime_ * 15) + (frametime_ * 1000)) / 16;
352
404
        lastframe_ = curframe;
353
405
 
 
406
        Game* game = dynamic_cast<Game*>(&egbase());
 
407
 
354
408
        // This portion of code keeps the speed of game so that FPS are kept within
355
409
        // range 13 - 15, this is used for training of AI
356
 
        if (AItrainingMode) {
357
 
                if (upcast(Game, game, &egbase())) {
 
410
        if (game != nullptr) {
 
411
                if (game->is_auto_speed()) {
358
412
                        uint32_t cur_fps = 1000000 / avg_usframetime_;
359
413
                        int32_t speed_diff = 0;
360
414
                        if (cur_fps < 13) {
364
418
                                speed_diff = +100;
365
419
                        }
366
420
                        if (speed_diff != 0) {
367
 
 
368
421
                                if (GameController* const ctrl = game->game_controller()) {
369
422
                                        if ((ctrl->desired_speed() > 950 && ctrl->desired_speed() < 30000) ||
370
423
                                            (ctrl->desired_speed() < 1000 && speed_diff > 0) ||
376
429
                }
377
430
        }
378
431
 
379
 
        const Map& map = egbase().map();
380
 
        const bool is_game = dynamic_cast<const Game*>(&egbase());
381
 
 
382
432
        // Blit node information when in debug mode.
383
 
        if (get_display_flag(dfDebug) || !is_game) {
 
433
        if (get_display_flag(dfDebug) || game == nullptr) {
384
434
                std::string node_text;
385
 
                if (is_game) {
 
435
                if (game != nullptr) {
386
436
                        const std::string gametime(gametimestring(egbase().get_gametime(), true));
387
437
                        std::shared_ptr<const UI::RenderedText> rendered_text =
388
438
                           UI::g_fh1->render(as_condensed(gametime));
392
442
                        node_text = as_condensed((node_format % sel_.pos.node.x % sel_.pos.node.y).str());
393
443
                } else {  // This is an editor
394
444
                        static boost::format node_format("(%i, %i, %i)");
395
 
                        const int32_t height = map[sel_.pos.node].get_height();
 
445
                        const int32_t height = egbase().map()[sel_.pos.node].get_height();
396
446
                        node_text = as_condensed((node_format % sel_.pos.node.x % sel_.pos.node.y % height).str());
397
447
                }
398
448
                std::shared_ptr<const UI::RenderedText> rendered_text = UI::g_fh1->render(node_text);
401
451
        }
402
452
 
403
453
        // Blit FPS when playing a game in debug mode.
404
 
        if (get_display_flag(dfDebug) && is_game) {
 
454
        if (get_display_flag(dfDebug) && game != nullptr) {
405
455
                static boost::format fps_format("%5.1f fps (avg: %5.1f fps)");
406
456
                std::shared_ptr<const UI::RenderedText> rendered_text = UI::g_fh1->render(as_condensed(
407
457
                   (fps_format % (1000.0 / frametime_) % (1000.0 / (avg_usframetime_ / 1000))).str()));
410
460
}
411
461
 
412
462
void InteractiveBase::mainview_move() {
413
 
        if (m->minimap.window) {
414
 
                m->mm->set_view(view_area().rect());
 
463
        if (minimap_registry_.window) {
 
464
                minimap_->set_view(map_view_.view_area().rect());
415
465
        }
416
466
}
417
467
 
418
468
// Open the minimap or close it if it's open
419
469
void InteractiveBase::toggle_minimap() {
420
 
        if (m->minimap.window) {
421
 
                delete m->minimap.window;
 
470
        if (minimap_registry_.window) {
 
471
                delete minimap_registry_.window;
422
472
        } else {
423
 
                m->mm = new MiniMap(*this, &m->minimap);
424
 
                m->mm->warpview.connect(
425
 
                   [this](const Vector2f& map_pixel) { scroll_to_map_pixel(map_pixel, Transition::Smooth); });
 
473
                minimap_ = new MiniMap(*this, &minimap_registry_);
 
474
                minimap_->warpview.connect([this](const Vector2f& map_pixel) {
 
475
                        map_view_.scroll_to_map_pixel(map_pixel, MapView::Transition::Smooth);
 
476
                });
426
477
                mainview_move();
427
478
        }
428
479
}
429
480
 
430
481
const std::vector<QuickNavigation::Landmark>& InteractiveBase::landmarks() {
431
 
        return m->quicknavigation->landmarks();
 
482
        return quick_navigation_.landmarks();
432
483
}
433
484
 
434
485
void InteractiveBase::set_landmark(size_t key, const MapView::View& landmark_view) {
435
 
        m->quicknavigation->set_landmark(key, landmark_view);
 
486
        quick_navigation_.set_landmark(key, landmark_view);
436
487
}
437
488
 
438
489
/**
439
490
 * Hide the minimap if it is currently shown; otherwise, do nothing.
440
491
 */
441
492
void InteractiveBase::hide_minimap() {
442
 
        m->minimap.destroy();
 
493
        minimap_registry_.destroy();
443
494
}
444
495
 
445
496
/**
450
501
===========
451
502
*/
452
503
MiniMap::Registry& InteractiveBase::minimap_registry() {
453
 
        return m->minimap;
 
504
        return minimap_registry_;
454
505
}
455
506
 
456
507
/*
580
631
bool InteractiveBase::append_build_road(Coords const field) {
581
632
        assert(buildroad_);
582
633
 
583
 
        Map& map = egbase().map();
 
634
        const Map& map = egbase().map();
584
635
        const Widelands::Player& player = egbase().player(road_build_player_);
585
636
 
586
637
        {  //  find a path to the clicked-on node
658
709
 
659
710
        // Viewpoint is the point of the map in pixel which is shown in the upper
660
711
        // left corner of window or fullscreen
661
 
        const MapView::ViewArea area = view_area();
 
712
        const MapView::ViewArea area = map_view_.view_area();
662
713
        if (!area.contains(position_map)) {
663
714
                return -1;
664
715
        }
680
731
*/
681
732
void InteractiveBase::roadb_add_overlay() {
682
733
        assert(buildroad_);
 
734
        assert(road_building_overlays_.road_previews.empty());
 
735
        assert(road_building_overlays_.steepness_indicators.empty());
683
736
 
684
 
        Map& map = egbase().map();
 
737
        const Map& map = egbase().map();
685
738
 
686
739
        // preview of the road
687
 
        assert(!jobid_);
688
 
        jobid_ = field_overlay_manager_->next_overlay_id();
689
740
        const CoordPath::StepVector::size_type nr_steps = buildroad_->get_nsteps();
690
741
        for (CoordPath::StepVector::size_type idx = 0; idx < nr_steps; ++idx) {
691
742
                Widelands::Direction dir = (*buildroad_)[idx];
695
746
                        map.get_neighbour(c, dir, &c);
696
747
                        dir = Widelands::get_reverse_dir(dir);
697
748
                }
698
 
 
699
749
                int32_t const shift = 2 * (dir - Widelands::WALK_E);
700
 
 
701
 
                uint8_t set_to = edge_overlay_manager_->get_overlay(c);
702
 
                set_to |= Widelands::RoadType::kNormal << shift;
703
 
                edge_overlay_manager_->register_overlay(c, set_to, jobid_);
 
750
                road_building_overlays_.road_previews[c] |= (Widelands::RoadType::kNormal << shift);
704
751
        }
705
752
 
706
753
        // build hints
707
754
        Widelands::FCoords endpos = map.get_fcoords(buildroad_->get_end());
708
755
 
709
 
        assert(!road_buildhelp_overlay_jobid_);
710
 
        road_buildhelp_overlay_jobid_ = field_overlay_manager_->next_overlay_id();
711
756
        for (int32_t dir = 1; dir <= 6; ++dir) {
712
757
                Widelands::FCoords neighb;
713
758
                int32_t caps;
748
793
                        name = "images/wui/overlays/roadb_yellow.png";
749
794
                else
750
795
                        name = "images/wui/overlays/roadb_red.png";
751
 
 
752
 
                field_overlay_manager_->register_overlay(
753
 
                   neighb, g_gr->images().get(name), 7, Vector2i::invalid(), road_buildhelp_overlay_jobid_);
 
796
                road_building_overlays_.steepness_indicators[neighb] = g_gr->images().get(name);
754
797
        }
755
798
}
756
799
 
761
804
*/
762
805
void InteractiveBase::roadb_remove_overlay() {
763
806
        assert(buildroad_);
764
 
 
765
 
        //  preview of the road
766
 
        if (jobid_) {
767
 
                edge_overlay_manager_->remove_overlay(jobid_);
768
 
        }
769
 
        jobid_ = 0;
770
 
 
771
 
        // build hints
772
 
        if (road_buildhelp_overlay_jobid_) {
773
 
                field_overlay_manager_->remove_overlay(road_buildhelp_overlay_jobid_);
774
 
        }
775
 
        road_buildhelp_overlay_jobid_ = 0;
 
807
        road_building_overlays_.road_previews.clear();
 
808
        road_building_overlays_.steepness_indicators.clear();
776
809
}
777
810
 
778
811
bool InteractiveBase::handle_key(bool const down, SDL_Keysym const code) {
779
 
        if (m->quicknavigation->handle_key(down, code))
 
812
        if (quick_navigation_.handle_key(down, code))
780
813
                return true;
781
814
 
782
815
        if (down) {
826
859
                }
827
860
        }
828
861
 
829
 
        return MapView::handle_key(down, code);
 
862
        return map_view_.handle_key(down, code);
830
863
}
831
864
 
832
865
void InteractiveBase::cmd_lua(const std::vector<std::string>& args) {