Merge lp:~widelands-dev/widelands/editor-resize-map into lp:widelands

Proposed by Benedikt Straub
Status: Merged
Merged at revision: 9072
Proposed branch: lp:~widelands-dev/widelands/editor-resize-map
Merge into: lp:widelands
Diff against target: 1162 lines (+649/-119)
16 files modified
src/editor/CMakeLists.txt (+4/-0)
src/editor/editorinteractive.cc (+2/-2)
src/editor/editorinteractive.h (+6/-2)
src/editor/tools/action_args.h (+12/-0)
src/editor/tools/history.cc (+1/-0)
src/editor/tools/resize_tool.cc (+99/-0)
src/editor/tools/resize_tool.h (+76/-0)
src/editor/ui_menus/main_menu_new_map.cc (+23/-37)
src/editor/ui_menus/main_menu_new_map.h (+3/-3)
src/editor/ui_menus/main_menu_random_map.cc (+40/-47)
src/editor/ui_menus/main_menu_random_map.h (+3/-5)
src/editor/ui_menus/tool_menu.cc (+23/-10)
src/editor/ui_menus/tool_resize_options_menu.cc (+108/-0)
src/editor/ui_menus/tool_resize_options_menu.h (+48/-0)
src/logic/map.cc (+169/-5)
src/logic/map.h (+32/-8)
To merge this branch: bzr merge lp:~widelands-dev/widelands/editor-resize-map
Reviewer Review Type Date Requested Status
GunChleoc Approve
Review via email: mp+365638@code.launchpad.net

Commit message

Add an editor tool to change the map size

Description of the change

This is for b21.

Usage:
· Tool Menu → Resize
· Set the new map size
· Click on the map field where to split the map
New rows/columns will be inserted at the clicked spot. The field itself will then be located on the southeastern corner of the inserted rectangle of new fields. When making the map smaller, rows/columns south and east of the clicked field will be deleted.

To post a comment you must log in.
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4685. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/516924316.
Appveyor build 4471. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_editor_resize_map-4471.

Revision history for this message
GunChleoc (gunchleoc) wrote :

First round of code review done. Not tested yet.

Revision history for this message
Benedikt Straub (nordfriese) wrote :

Thanks for the review, implemented your suggestions

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4695. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/517211510.
Appveyor build 4481. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_editor_resize_map-4481.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Changes LGTM :)

Not tested yet.

review: Approve
Revision history for this message
GunChleoc (gunchleoc) wrote :

I have given this a very quick spin.

I don't think that it is obvious to the user that they need to click on the map after selecting the values. Best add a Multilinetextarea with a hint.

I think it would also be good to have dropdown menus for the map size rather than spin boxes - selecting them will be much faster that way. You could put this into a separate class and use it everywhere in the editor where map sized are being set.

Revision history for this message
Benedikt Straub (nordfriese) wrote :

OK, added the hint and replaced spinners with dropdowns in the Resize Tool options and the New Map and Random Map menus. The large code blocks for setting the initial values are now shorter and more intuitive, I don´t think we would gain much by making a new class for it.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4708. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/518246751.
Appveyor build 4494. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_editor_resize_map-4494.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Changes look good. I have done some testing with a few random maps - no issues :)

review: Approve
Revision history for this message
GunChleoc (gunchleoc) wrote :

Transient failure on Travis

@bunnybot merge force

Revision history for this message
bunnybot (widelandsofficial) wrote :

Error merging this proposal:

Output:
stdout:

stderr:
+N data/images/wui/editor/editor_menu_tool_resize.png
+N data/images/wui/editor/fsel_editor_resize.png
+N src/editor/tools/resize_tool.cc
+N src/editor/tools/resize_tool.h
+N src/editor/ui_menus/tool_resize_options_menu.cc
+N src/editor/ui_menus/tool_resize_options_menu.h
 M src/editor/CMakeLists.txt
 M src/editor/editorinteractive.cc
 M src/editor/editorinteractive.h
 M src/editor/tools/action_args.h
 M src/editor/tools/history.cc
 M src/editor/ui_menus/main_menu_new_map.cc
 M src/editor/ui_menus/main_menu_new_map.h
 M src/editor/ui_menus/main_menu_random_map.cc
 M src/editor/ui_menus/main_menu_random_map.h
 M src/editor/ui_menus/tool_menu.cc
 M src/logic/map.cc
 M src/logic/map.h
Text conflict in src/editor/ui_menus/tool_menu.cc
1 conflicts encountered.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4766. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/523536087.
Appveyor build 4550. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_editor_resize_map-4550.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Transient failure on Travis

@bunnybot merge

Revision history for this message
GunChleoc (gunchleoc) wrote :

@bunnybot merge force

Revision history for this message
bunnybot (widelandsofficial) wrote :

Refusing to merge, since Travis is not green. Use @bunnybot merge force for merging anyways.

Travis build 4766. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/523536087.

Revision history for this message
GunChleoc (gunchleoc) wrote :

@bunnybot merge force

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'data/images/wui/editor/editor_menu_tool_resize.png'
0Binary files data/images/wui/editor/editor_menu_tool_resize.png 1970-01-01 00:00:00 +0000 and data/images/wui/editor/editor_menu_tool_resize.png 2019-04-23 14:01:41 +0000 differ0Binary files data/images/wui/editor/editor_menu_tool_resize.png 1970-01-01 00:00:00 +0000 and data/images/wui/editor/editor_menu_tool_resize.png 2019-04-23 14:01:41 +0000 differ
=== added file 'data/images/wui/editor/fsel_editor_resize.png'
1Binary files data/images/wui/editor/fsel_editor_resize.png 1970-01-01 00:00:00 +0000 and data/images/wui/editor/fsel_editor_resize.png 2019-04-23 14:01:41 +0000 differ1Binary files data/images/wui/editor/fsel_editor_resize.png 1970-01-01 00:00:00 +0000 and data/images/wui/editor/fsel_editor_resize.png 2019-04-23 14:01:41 +0000 differ
=== modified file 'src/editor/CMakeLists.txt'
--- src/editor/CMakeLists.txt 2018-11-04 17:56:37 +0000
+++ src/editor/CMakeLists.txt 2019-04-23 14:01:41 +0000
@@ -30,6 +30,8 @@
30 tools/place_critter_tool.h30 tools/place_critter_tool.h
31 tools/place_immovable_tool.cc31 tools/place_immovable_tool.cc
32 tools/place_immovable_tool.h32 tools/place_immovable_tool.h
33 tools/resize_tool.cc
34 tools/resize_tool.h
33 tools/set_height_tool.cc35 tools/set_height_tool.cc
34 tools/set_height_tool.h36 tools/set_height_tool.h
35 tools/set_origin_tool.cc37 tools/set_origin_tool.cc
@@ -79,6 +81,8 @@
79 ui_menus/tool_place_critter_options_menu.h81 ui_menus/tool_place_critter_options_menu.h
80 ui_menus/tool_place_immovable_options_menu.cc82 ui_menus/tool_place_immovable_options_menu.cc
81 ui_menus/tool_place_immovable_options_menu.h83 ui_menus/tool_place_immovable_options_menu.h
84 ui_menus/tool_resize_options_menu.cc
85 ui_menus/tool_resize_options_menu.h
82 ui_menus/tool_set_terrain_options_menu.cc86 ui_menus/tool_set_terrain_options_menu.cc
83 ui_menus/tool_set_terrain_options_menu.h87 ui_menus/tool_set_terrain_options_menu.h
84 ui_menus/toolsize_menu.cc88 ui_menus/toolsize_menu.cc
8589
=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc 2019-02-27 17:19:00 +0000
+++ src/editor/editorinteractive.cc 2019-04-23 14:01:41 +0000
@@ -72,7 +72,7 @@
72 is_painting_(false),72 is_painting_(false),
73 undo_(nullptr),73 undo_(nullptr),
74 redo_(nullptr),74 redo_(nullptr),
75 tools_(new Tools()),75 tools_(new Tools(e.map())),
76 history_(nullptr) // history needs the undo/redo buttons76 history_(nullptr) // history needs the undo/redo buttons
77{77{
78 add_toolbar_button("wui/menus/menu_toggle_menu", "menu", _("Main menu"), &mainmenu_, true);78 add_toolbar_button("wui/menus/menu_toggle_menu", "menu", _("Main menu"), &mainmenu_, true);
@@ -652,7 +652,7 @@
652 undo_->set_enabled(false);652 undo_->set_enabled(false);
653 redo_->set_enabled(false);653 redo_->set_enabled(false);
654654
655 tools_.reset(new Tools());655 tools_.reset(new Tools(egbase().map()));
656 select_tool(tools_->info, EditorTool::First);656 select_tool(tools_->info, EditorTool::First);
657 set_sel_radius(0);657 set_sel_radius(0);
658658
659659
=== modified file 'src/editor/editorinteractive.h'
--- src/editor/editorinteractive.h 2019-02-23 11:00:49 +0000
+++ src/editor/editorinteractive.h 2019-04-23 14:01:41 +0000
@@ -29,6 +29,7 @@
29#include "editor/tools/noise_height_tool.h"29#include "editor/tools/noise_height_tool.h"
30#include "editor/tools/place_critter_tool.h"30#include "editor/tools/place_critter_tool.h"
31#include "editor/tools/place_immovable_tool.h"31#include "editor/tools/place_immovable_tool.h"
32#include "editor/tools/resize_tool.h"
32#include "editor/tools/set_origin_tool.h"33#include "editor/tools/set_origin_tool.h"
33#include "editor/tools/set_port_space_tool.h"34#include "editor/tools/set_port_space_tool.h"
34#include "editor/tools/set_starting_pos_tool.h"35#include "editor/tools/set_starting_pos_tool.h"
@@ -49,7 +50,7 @@
49class EditorInteractive : public InteractiveBase {50class EditorInteractive : public InteractiveBase {
50public:51public:
51 struct Tools {52 struct Tools {
52 Tools()53 Tools(const Widelands::Map& map)
53 : current_pointer(&info),54 : current_pointer(&info),
54 use_tool(EditorTool::First),55 use_tool(EditorTool::First),
55 increase_height(decrease_height, set_height),56 increase_height(decrease_height, set_height),
@@ -58,7 +59,8 @@
58 place_critter(delete_critter),59 place_critter(delete_critter),
59 increase_resources(decrease_resources, set_resources),60 increase_resources(decrease_resources, set_resources),
60 set_port_space(unset_port_space),61 set_port_space(unset_port_space),
61 set_origin() {62 set_origin(),
63 resize(map.get_width(), map.get_height()) {
62 }64 }
63 EditorTool& current() const {65 EditorTool& current() const {
64 return *current_pointer;66 return *current_pointer;
@@ -83,6 +85,7 @@
83 EditorSetPortSpaceTool set_port_space;85 EditorSetPortSpaceTool set_port_space;
84 EditorUnsetPortSpaceTool unset_port_space;86 EditorUnsetPortSpaceTool unset_port_space;
85 EditorSetOriginTool set_origin;87 EditorSetOriginTool set_origin;
88 EditorResizeTool resize;
86 };89 };
87 explicit EditorInteractive(Widelands::EditorGameBase&);90 explicit EditorInteractive(Widelands::EditorGameBase&);
8891
@@ -162,6 +165,7 @@
162 UI::UniqueWindow::Registry immovablemenu_;165 UI::UniqueWindow::Registry immovablemenu_;
163 UI::UniqueWindow::Registry crittermenu_;166 UI::UniqueWindow::Registry crittermenu_;
164 UI::UniqueWindow::Registry resourcesmenu_;167 UI::UniqueWindow::Registry resourcesmenu_;
168 UI::UniqueWindow::Registry resizemenu_;
165 UI::UniqueWindow::Registry helpmenu_;169 UI::UniqueWindow::Registry helpmenu_;
166170
167 UI::Button* toggle_buildhelp_;171 UI::Button* toggle_buildhelp_;
168172
=== modified file 'src/editor/tools/action_args.h'
--- src/editor/tools/action_args.h 2019-02-23 11:00:49 +0000
+++ src/editor/tools/action_args.h 2019-04-23 14:01:41 +0000
@@ -21,9 +21,13 @@
21#define WL_EDITOR_TOOLS_ACTION_ARGS_H21#define WL_EDITOR_TOOLS_ACTION_ARGS_H
2222
23#include <list>23#include <list>
24#include <map>
25#include <set>
24#include <string>26#include <string>
27#include <vector>
2528
26#include "logic/field.h"29#include "logic/field.h"
30#include "logic/map.h"
27#include "logic/widelands_geometry.h"31#include "logic/widelands_geometry.h"
2832
29namespace Widelands {33namespace Widelands {
@@ -52,12 +56,19 @@
52 std::list<Widelands::Field::Height> original_heights; // change height tool56 std::list<Widelands::Field::Height> original_heights; // change height tool
53 Widelands::DescriptionIndex current_resource; // resources change tools57 Widelands::DescriptionIndex current_resource; // resources change tools
54 Widelands::ResourceAmount set_to; // resources change tools58 Widelands::ResourceAmount set_to; // resources change tools
59 Widelands::Extent new_map_size; // resize tool
5560
56 struct ResourceState {61 struct ResourceState {
57 Widelands::FCoords location;62 Widelands::FCoords location;
58 Widelands::DescriptionIndex idx;63 Widelands::DescriptionIndex idx;
59 Widelands::ResourceAmount amount;64 Widelands::ResourceAmount amount;
60 };65 };
66 struct ResizeHistory {
67 Widelands::Extent old_map_size = Widelands::Extent(0, 0);
68 std::map<Widelands::Coords, Widelands::FieldData> deleted_fields;
69 std::set<Widelands::Coords> port_spaces;
70 std::vector<Widelands::Coords> starting_positions;
71 };
6172
62 std::list<ResourceState> original_resource; // resources set tool73 std::list<ResourceState> original_resource; // resources set tool
63 std::list<const Widelands::BobDescr*> old_bob_type, new_bob_type; // bob change tools74 std::list<const Widelands::BobDescr*> old_bob_type, new_bob_type; // bob change tools
@@ -65,6 +76,7 @@
65 std::list<Widelands::DescriptionIndex> new_immovable_types; // immovable change tools76 std::list<Widelands::DescriptionIndex> new_immovable_types; // immovable change tools
66 Widelands::HeightInterval interval; // noise height tool77 Widelands::HeightInterval interval; // noise height tool
67 std::list<Widelands::DescriptionIndex> terrain_type, original_terrain_type; // set terrain tool78 std::list<Widelands::DescriptionIndex> terrain_type, original_terrain_type; // set terrain tool
79 ResizeHistory resized; // resize tool
6880
69 std::list<EditorToolAction*> draw_actions; // draw tool81 std::list<EditorToolAction*> draw_actions; // draw tool
7082
7183
=== modified file 'src/editor/tools/history.cc'
--- src/editor/tools/history.cc 2019-03-10 06:34:41 +0000
+++ src/editor/tools/history.cc 2019-04-23 14:01:41 +0000
@@ -35,6 +35,7 @@
35 change_by(0),35 change_by(0),
36 current_resource(0),36 current_resource(0),
37 set_to(0),37 set_to(0),
38 new_map_size(0, 0),
38 interval(0, 0),39 interval(0, 0),
39 refcount(0) {40 refcount(0) {
40}41}
4142
=== added file 'src/editor/tools/resize_tool.cc'
--- src/editor/tools/resize_tool.cc 1970-01-01 00:00:00 +0000
+++ src/editor/tools/resize_tool.cc 2019-04-23 14:01:41 +0000
@@ -0,0 +1,99 @@
1/*
2 * Copyright (C) 2002-2019 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#include "editor/tools/resize_tool.h"
21
22#include "editor/editorinteractive.h"
23#include "logic/field.h"
24#include "logic/widelands_geometry.h"
25
26int32_t EditorResizeTool::handle_click_impl(const Widelands::World& world,
27 const Widelands::NodeAndTriangle<>& center,
28 EditorInteractive& parent,
29 EditorActionArgs* args,
30 Widelands::Map* map) {
31 Widelands::EditorGameBase& egbase = parent.egbase();
32
33 args->resized.old_map_size = map->extent();
34 args->resized.port_spaces.clear();
35 args->resized.starting_positions.clear();
36 for (const Widelands::Coords& ps : map->get_port_spaces()) {
37 args->resized.port_spaces.insert(Widelands::Coords(ps));
38 }
39 for (uint8_t i = 1; i <= map->get_nrplayers(); ++i) {
40 args->resized.starting_positions.push_back(map->get_starting_pos(i));
41 }
42
43 args->resized.deleted_fields = map->resize(egbase, center.node, args->new_map_size.w, args->new_map_size.h);
44
45 map->recalc_whole_map(world);
46 return 0;
47}
48
49int32_t EditorResizeTool::handle_undo_impl(
50 const Widelands::World& world,
51 const Widelands::NodeAndTriangle<Widelands::Coords>& center,
52 EditorInteractive& parent,
53 EditorActionArgs* args,
54 Widelands::Map* map) {
55 Widelands::EditorGameBase& egbase = parent.egbase();
56
57 map->resize(egbase, center.node, args->resized.old_map_size.w, args->resized.old_map_size.h);
58
59 for (const auto& it : args->resized.deleted_fields) {
60 const Widelands::FCoords f = map->get_fcoords(it.first);
61 const Widelands::FieldData data = it.second;
62
63 if (Widelands::BaseImmovable* imm = f.field->get_immovable()) {
64 imm->remove(egbase);
65 }
66 for (Widelands::Bob* bob = f.field->get_first_bob(); bob; bob = bob->get_next_bob()) {
67 bob->remove(egbase);
68 }
69
70 f.field->set_height(data.height);
71 f.field->set_terrains(data.terrains);
72 map->initialize_resources(f, data.resources, data.resource_amount);
73
74 if (!data.immovable.empty()) {
75 egbase.create_immovable_with_name(f, data.immovable,
76 Widelands::MapObjectDescr::OwnerType::kWorld, nullptr, nullptr);
77 }
78 for (const std::string& bob : data.bobs) {
79 egbase.create_critter(f, bob);
80 }
81 }
82
83 for (const Widelands::Coords& c : args->resized.port_spaces) {
84 map->set_port_space(world, c, true, true);
85 }
86 for (uint8_t i = 1; i <= map->get_nrplayers(); ++i) {
87 map->set_starting_pos(i, args->resized.starting_positions[i - 1]);
88 }
89
90 map->recalc_whole_map(world);
91 return 0;
92}
93
94EditorActionArgs EditorResizeTool::format_args_impl(EditorInteractive& parent) {
95 EditorActionArgs a(parent);
96 a.new_map_size = Widelands::Extent(width_, height_);
97 return a;
98}
99
0100
=== added file 'src/editor/tools/resize_tool.h'
--- src/editor/tools/resize_tool.h 1970-01-01 00:00:00 +0000
+++ src/editor/tools/resize_tool.h 2019-04-23 14:01:41 +0000
@@ -0,0 +1,76 @@
1/*
2 * Copyright (C) 2002-2019 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#ifndef WL_EDITOR_TOOLS_RESIZE_TOOL_H
21#define WL_EDITOR_TOOLS_RESIZE_TOOL_H
22
23#include "editor/tools/tool.h"
24
25/// Resize the map
26struct EditorResizeTool : public EditorTool {
27 EditorResizeTool(int16_t width, int16_t height) : EditorTool(*this, *this), width_(width), height_(height) {
28 }
29
30 /**
31 * Change the map size
32 */
33 int32_t handle_click_impl(const Widelands::World& world,
34 const Widelands::NodeAndTriangle<>& center,
35 EditorInteractive& parent,
36 EditorActionArgs* args,
37 Widelands::Map* map) override;
38
39 int32_t handle_undo_impl(const Widelands::World& world,
40 const Widelands::NodeAndTriangle<>& center,
41 EditorInteractive& parent,
42 EditorActionArgs* args,
43 Widelands::Map* map) override;
44
45 EditorActionArgs format_args_impl(EditorInteractive& parent) override;
46
47 const Image* get_sel_impl() const override {
48 return g_gr->images().get("images/wui/editor/fsel_editor_resize.png");
49 }
50
51 bool has_size_one() const override {
52 return true;
53 }
54
55 void set_width(uint32_t w) {
56 width_ = w;
57 }
58
59 uint32_t get_width() {
60 return width_;
61 }
62
63 void set_height(uint32_t h) {
64 height_ = h;
65 }
66
67 uint32_t get_height() {
68 return height_;
69 }
70
71private:
72 uint32_t width_;
73 uint32_t height_;
74};
75
76#endif // end of include guard: WL_EDITOR_TOOLS_RESIZE_TOOL_H
077
=== modified file 'src/editor/ui_menus/main_menu_new_map.cc'
--- src/editor/ui_menus/main_menu_new_map.cc 2019-02-23 11:00:49 +0000
+++ src/editor/ui_menus/main_menu_new_map.cc 2019-04-23 14:01:41 +0000
@@ -51,25 +51,19 @@
51 0,51 0,
52 box_width_,52 box_width_,
53 box_width_ / 3,53 box_width_ / 3,
54 0,54 24,
55 0,55 _("Width"),
56 0,56 UI::DropdownType::kTextual,
57 UI::PanelStyle::kWui,57 UI::PanelStyle::kWui),
58 _("Width:"),
59 UI::SpinBox::Units::kNone,
60 UI::SpinBox::Type::kValueList),
61 height_(&box_,58 height_(&box_,
62 0,59 0,
63 0,60 0,
64 box_width_,61 box_width_,
65 box_width_ / 3,62 box_width_ / 3,
66 0,63 24,
67 0,64 _("Height"),
68 0,65 UI::DropdownType::kTextual,
69 UI::PanelStyle::kWui,66 UI::PanelStyle::kWui),
70 _("Height:"),
71 UI::SpinBox::Units::kNone,
72 UI::SpinBox::Type::kValueList),
73 list_(&box_, 0, 0, box_width_, 330, UI::PanelStyle::kWui),67 list_(&box_, 0, 0, box_width_, 330, UI::PanelStyle::kWui),
74 // Buttons68 // Buttons
75 button_box_(&box_, 0, 0, UI::Box::Horizontal, 0, 0, margin_),69 button_box_(&box_, 0, 0, UI::Box::Horizontal, 0, 0, margin_),
@@ -89,25 +83,17 @@
89 0,83 0,
90 UI::ButtonStyle::kWuiSecondary,84 UI::ButtonStyle::kWuiSecondary,
91 _("Cancel")) {85 _("Cancel")) {
92 width_.set_value_list(Widelands::kMapDimensions);86
93 height_.set_value_list(Widelands::kMapDimensions);87 for (const int32_t& i : Widelands::kMapDimensions) {
9488 width_.add(std::to_string(i), i);
95 {89 height_.add(std::to_string(i), i);
96 size_t width_index, height_index;
97 Widelands::Extent const map_extent = parent.egbase().map().extent();
98 for (width_index = 0; width_index < Widelands::kMapDimensions.size() &&
99 Widelands::kMapDimensions[width_index] < map_extent.w;
100 ++width_index) {
101 }
102 width_.set_value(width_index);
103
104 for (height_index = 0; height_index < Widelands::kMapDimensions.size() &&
105 Widelands::kMapDimensions[height_index] < map_extent.h;
106 ++height_index) {
107 }
108 height_.set_value(height_index);
109 }90 }
91 width_.select(parent.egbase().map().get_width());
92 height_.select(parent.egbase().map().get_height());
93 width_.set_max_items(12);
94 height_.set_max_items(12);
11095
96 box_.set_size(100, 20); // Prevent assert failures
111 box_.add(&width_);97 box_.add(&width_);
112 box_.add(&height_);98 box_.add(&height_);
113 box_.add_space(margin_);99 box_.add_space(margin_);
@@ -145,8 +131,8 @@
145 parent.cleanup_for_load();131 parent.cleanup_for_load();
146132
147 map->create_empty_map(133 map->create_empty_map(
148 egbase.world(), width_.get_value() > 0 ? width_.get_value() : Widelands::kMapDimensions[0],134 egbase.world(), width_.get_selected() > 0 ? width_.get_selected() : Widelands::kMapDimensions[0],
149 height_.get_value() > 0 ? height_.get_value() : Widelands::kMapDimensions[0],135 height_.get_selected() > 0 ? height_.get_selected() : Widelands::kMapDimensions[0],
150 list_.get_selected(), _("No Name"),136 list_.get_selected(), _("No Name"),
151 g_options.pull_section("global").get_string("realname", pgettext("author_name", "Unknown")));137 g_options.pull_section("global").get_string("realname", pgettext("author_name", "Unknown")));
152138
153139
=== modified file 'src/editor/ui_menus/main_menu_new_map.h'
--- src/editor/ui_menus/main_menu_new_map.h 2019-02-23 11:00:49 +0000
+++ src/editor/ui_menus/main_menu_new_map.h 2019-04-23 14:01:41 +0000
@@ -23,8 +23,8 @@
23#include "logic/description_maintainer.h"23#include "logic/description_maintainer.h"
24#include "ui_basic/box.h"24#include "ui_basic/box.h"
25#include "ui_basic/button.h"25#include "ui_basic/button.h"
26#include "ui_basic/dropdown.h"
26#include "ui_basic/listselect.h"27#include "ui_basic/listselect.h"
27#include "ui_basic/spinbox.h"
28#include "ui_basic/window.h"28#include "ui_basic/window.h"
2929
30class EditorInteractive;30class EditorInteractive;
@@ -46,8 +46,8 @@
46 int32_t margin_;46 int32_t margin_;
47 int32_t box_width_;47 int32_t box_width_;
48 UI::Box box_;48 UI::Box box_;
49 UI::SpinBox width_;49 UI::Dropdown<int32_t> width_;
50 UI::SpinBox height_;50 UI::Dropdown<int32_t> height_;
5151
52 // Terrains list52 // Terrains list
53 UI::Listselect<Widelands::DescriptionIndex> list_;53 UI::Listselect<Widelands::DescriptionIndex> list_;
5454
=== modified file 'src/editor/ui_menus/main_menu_random_map.cc'
--- src/editor/ui_menus/main_menu_random_map.cc 2019-02-23 11:00:49 +0000
+++ src/editor/ui_menus/main_menu_random_map.cc 2019-04-23 14:01:41 +0000
@@ -59,25 +59,19 @@
59 0,59 0,
60 box_width_,60 box_width_,
61 box_width_ / 3,61 box_width_ / 3,
62 0,62 24,
63 0,63 _("Width"),
64 0,64 UI::DropdownType::kTextual,
65 UI::PanelStyle::kWui,65 UI::PanelStyle::kWui),
66 _("Width:"),
67 UI::SpinBox::Units::kNone,
68 UI::SpinBox::Type::kValueList),
69 height_(&box_,66 height_(&box_,
70 0,67 0,
71 0,68 0,
72 box_width_,69 box_width_,
73 box_width_ / 3,70 box_width_ / 3,
74 0,71 24,
75 0,72 _("Height"),
76 0,73 UI::DropdownType::kTextual,
77 UI::PanelStyle::kWui,74 UI::PanelStyle::kWui),
78 _("Height:"),
79 UI::SpinBox::Units::kNone,
80 UI::SpinBox::Type::kValueList),
81 max_players_(2),75 max_players_(2),
82 players_(&box_,76 players_(&box_,
83 0,77 0,
@@ -227,23 +221,21 @@
227221
228 // ---------- Width + Height ----------222 // ---------- Width + Height ----------
229223
230 width_.set_value_list(Widelands::kMapDimensions);224 for (const int32_t& i : Widelands::kMapDimensions) {
231 height_.set_value_list(Widelands::kMapDimensions);225 width_.add(std::to_string(i), i);
232 {226 height_.add(std::to_string(i), i);
233 Widelands::Extent const map_extent = parent.egbase().map().extent();
234 width_.set_value(find_dimension_index(map_extent.w));
235 height_.set_value(find_dimension_index(map_extent.h));
236 }227 }
237228 width_.select(parent.egbase().map().get_width());
238 width_.get_buttons()[0]->sigclicked.connect(229 height_.select(parent.egbase().map().get_height());
239 boost::bind(&MainMenuNewRandomMap::button_clicked, this, ButtonId::kMapSize));230 width_.set_max_items(12);
240 width_.get_buttons()[1]->sigclicked.connect(231 height_.set_max_items(12);
241 boost::bind(&MainMenuNewRandomMap::button_clicked, this, ButtonId::kMapSize));232
242 height_.get_buttons()[0]->sigclicked.connect(233 width_.selected.connect(
243 boost::bind(&MainMenuNewRandomMap::button_clicked, this, ButtonId::kMapSize));234 boost::bind(&MainMenuNewRandomMap::button_clicked, this, ButtonId::kMapSize));
244 height_.get_buttons()[1]->sigclicked.connect(235 height_.selected.connect(
245 boost::bind(&MainMenuNewRandomMap::button_clicked, this, ButtonId::kMapSize));236 boost::bind(&MainMenuNewRandomMap::button_clicked, this, ButtonId::kMapSize));
246237
238 box_.set_size(100, 20); // Prevent assert failures
247 box_.add(&width_);239 box_.add(&width_);
248 box_.add(&height_);240 box_.add(&height_);
249 box_height += margin_ + width_.get_h();241 box_height += margin_ + width_.get_h();
@@ -397,6 +389,14 @@
397 center_to_parent();389 center_to_parent();
398}390}
399391
392// Helper function for setting the highest number of allowed players dependent on the map size
393static size_t find_dimension_index(int32_t value) {
394 size_t result = 0;
395 for (; result < Widelands::kMapDimensions.size() && Widelands::kMapDimensions[result] < value;
396 ++result) {
397 }
398 return result;
399}
400/**400/**
401 * Called, when button get clicked401 * Called, when button get clicked
402 */402 */
@@ -407,7 +407,7 @@
407 // Restrict maximum players according to map size, but allow at least 2 players.407 // Restrict maximum players according to map size, but allow at least 2 players.
408 max_players_ = std::min(408 max_players_ = std::min(
409 static_cast<size_t>(kMaxMapgenPlayers),409 static_cast<size_t>(kMaxMapgenPlayers),
410 (find_dimension_index(width_.get_value()) + find_dimension_index(height_.get_value())) /410 (find_dimension_index(width_.get_selected()) + find_dimension_index(height_.get_selected())) /
411 2 +411 2 +
412 2);412 2);
413 players_.set_interval(1, max_players_);413 players_.set_interval(1, max_players_);
@@ -443,7 +443,7 @@
443 // Make sure that all conditions are met443 // Make sure that all conditions are met
444 max_players_ = std::min(444 max_players_ = std::min(
445 static_cast<size_t>(kMaxMapgenPlayers),445 static_cast<size_t>(kMaxMapgenPlayers),
446 (find_dimension_index(width_.get_value()) + find_dimension_index(height_.get_value())) /446 (find_dimension_index(width_.get_selected()) + find_dimension_index(height_.get_selected())) /
447 2 +447 2 +
448 2);448 2);
449 players_.set_interval(1, max_players_);449 players_.set_interval(1, max_players_);
@@ -604,8 +604,8 @@
604 sstrm << map_info.mapNumber;604 sstrm << map_info.mapNumber;
605 map_number_edit_.set_text(sstrm.str());605 map_number_edit_.set_text(sstrm.str());
606606
607 width_.set_value(find_dimension_index(map_info.w));607 width_.select(map_info.w);
608 height_.set_value(find_dimension_index(map_info.h));608 height_.select(map_info.h);
609609
610 players_.set_interval(1, map_info.numPlayers); // hack to make sure we can set the value610 players_.set_interval(1, map_info.numPlayers); // hack to make sure we can set the value
611 players_.set_value(map_info.numPlayers);611 players_.set_value(map_info.numPlayers);
@@ -658,8 +658,8 @@
658}658}
659659
660void MainMenuNewRandomMap::set_map_info(Widelands::UniqueRandomMapInfo& map_info) const {660void MainMenuNewRandomMap::set_map_info(Widelands::UniqueRandomMapInfo& map_info) const {
661 map_info.w = width_.get_value() > 0 ? width_.get_value() : Widelands::kMapDimensions[0];661 map_info.w = width_.get_selected() > 0 ? width_.get_selected() : Widelands::kMapDimensions[0];
662 map_info.h = height_.get_value() > 0 ? height_.get_value() : Widelands::kMapDimensions[0];662 map_info.h = height_.get_selected() > 0 ? height_.get_selected() : Widelands::kMapDimensions[0];
663 map_info.waterRatio = static_cast<double>(waterval_) / 100.0;663 map_info.waterRatio = static_cast<double>(waterval_) / 100.0;
664 map_info.landRatio = static_cast<double>(landval_) / 100.0;664 map_info.landRatio = static_cast<double>(landval_) / 100.0;
665 map_info.wastelandRatio = static_cast<double>(wastelandval_) / 100.0;665 map_info.wastelandRatio = static_cast<double>(wastelandval_) / 100.0;
@@ -671,10 +671,3 @@
671 map_info.world_name = world_descriptions_[current_world_].name;671 map_info.world_name = world_descriptions_[current_world_].name;
672}672}
673673
674size_t MainMenuNewRandomMap::find_dimension_index(int32_t value) {
675 size_t result = 0;
676 for (; result < Widelands::kMapDimensions.size() && Widelands::kMapDimensions[result] < value;
677 ++result) {
678 }
679 return result;
680}
681674
=== modified file 'src/editor/ui_menus/main_menu_random_map.h'
--- src/editor/ui_menus/main_menu_random_map.h 2019-02-23 11:00:49 +0000
+++ src/editor/ui_menus/main_menu_random_map.h 2019-04-23 14:01:41 +0000
@@ -25,6 +25,7 @@
25#include "base/macros.h"25#include "base/macros.h"
26#include "ui_basic/box.h"26#include "ui_basic/box.h"
27#include "ui_basic/checkbox.h"27#include "ui_basic/checkbox.h"
28#include "ui_basic/dropdown.h"
28#include "ui_basic/editbox.h"29#include "ui_basic/editbox.h"
29#include "ui_basic/spinbox.h"30#include "ui_basic/spinbox.h"
30#include "ui_basic/textarea.h"31#include "ui_basic/textarea.h"
@@ -81,9 +82,6 @@
8182
82 void set_map_info(Widelands::UniqueRandomMapInfo& map_info) const;83 void set_map_info(Widelands::UniqueRandomMapInfo& map_info) const;
8384
84 // Helper function to find a map dimension in the global list of available dimensions.
85 size_t find_dimension_index(int32_t value);
86
87 // UI elements85 // UI elements
88 int32_t margin_;86 int32_t margin_;
89 int32_t box_width_;87 int32_t box_width_;
@@ -91,8 +89,8 @@
91 UI::Box box_;89 UI::Box box_;
9290
93 // Size91 // Size
94 UI::SpinBox width_;92 UI::Dropdown<int32_t> width_;
95 UI::SpinBox height_;93 UI::Dropdown<int32_t> height_;
9694
97 uint8_t max_players_;95 uint8_t max_players_;
98 UI::SpinBox players_;96 UI::SpinBox players_;
9997
=== modified file 'src/editor/ui_menus/tool_menu.cc'
--- src/editor/ui_menus/tool_menu.cc 2019-04-09 16:43:49 +0000
+++ src/editor/ui_menus/tool_menu.cc 2019-04-23 14:01:41 +0000
@@ -36,6 +36,7 @@
36#include "editor/ui_menus/tool_noise_height_options_menu.h"36#include "editor/ui_menus/tool_noise_height_options_menu.h"
37#include "editor/ui_menus/tool_place_critter_options_menu.h"37#include "editor/ui_menus/tool_place_critter_options_menu.h"
38#include "editor/ui_menus/tool_place_immovable_options_menu.h"38#include "editor/ui_menus/tool_place_immovable_options_menu.h"
39#include "editor/ui_menus/tool_resize_options_menu.h"
39#include "editor/ui_menus/tool_set_terrain_options_menu.h"40#include "editor/ui_menus/tool_set_terrain_options_menu.h"
40#include "graphic/graphic.h"41#include "graphic/graphic.h"
41#include "ui_basic/radiobutton.h"42#include "ui_basic/radiobutton.h"
@@ -50,7 +51,7 @@
50 int32_t const width = 34;51 int32_t const width = 34;
51 int32_t const height = 34;52 int32_t const height = 34;
5253
53 int32_t const num_tools = 8;54 int32_t const num_tools = 9;
54#define ADD_BUTTON(pic, tooltip) \55#define ADD_BUTTON(pic, tooltip) \
55 radioselect_.add_button( \56 radioselect_.add_button( \
56 this, pos, g_gr->images().get("images/wui/editor/editor_menu_tool_" pic ".png"), tooltip); \57 this, pos, g_gr->images().get("images/wui/editor/editor_menu_tool_" pic ".png"), tooltip); \
@@ -64,25 +65,29 @@
64 ADD_BUTTON("change_resources", _("Resources"))65 ADD_BUTTON("change_resources", _("Resources"))
65 ADD_BUTTON("set_port_space", _("Set port space"))66 ADD_BUTTON("set_port_space", _("Set port space"))
66 ADD_BUTTON("set_origin", _("Set the position that will have the coordinates (0, 0). This will "67 ADD_BUTTON("set_origin", _("Set the position that will have the coordinates (0, 0). This will "
67 "be the top-left corner of a generated minimap."))68 "be the top-left corner of a generated minimap."));
69 ADD_BUTTON("resize", _("Change the map’s size"));
6870
69 set_inner_size(offs.x + (width + spacing) * num_tools, offs.y + (height + spacing));71 set_inner_size(offs.x + (width + spacing) * num_tools, offs.y + (height + spacing));
7072
71 {73 {
72 const EditorTool& current = parent.tools()->current();74 const EditorTool* current = &parent.tools()->current();
73 radioselect_.set_state(&current == &parent.tools()->noise_height ?75 radioselect_.set_state(current == &parent.tools()->noise_height ?
74 1 :76 1 :
75 &current == &parent.tools()->set_terrain ?77 current == &parent.tools()->set_terrain ?
76 2 :78 2 :
77 &current == &parent.tools()->place_immovable ?79 current == &parent.tools()->place_immovable ?
78 3 :80 3 :
79 &current == &parent.tools()->place_critter ?81 current == &parent.tools()->place_critter ?
80 4 :82 4 :
81 &current == &parent.tools()->increase_resources ?83 current == &parent.tools()->increase_resources ?
82 5 :84 5 :
83 &current == &parent.tools()->set_port_space ?85 current == &parent.tools()->set_port_space ?
84 6 :86 6 :
85 &current == &parent.tools()->set_origin ? 7 : 0);87 current == &parent.tools()->set_origin ?
88 7 :
89 current == &parent.tools()->resize ?
90 8 : 0);
86 }91 }
8792
88 radioselect_.changed.connect(boost::bind(&EditorToolMenu::changed_to, this));93 radioselect_.changed.connect(boost::bind(&EditorToolMenu::changed_to, this));
@@ -135,6 +140,10 @@
135 current_tool_pointer = &parent.tools()->set_origin;140 current_tool_pointer = &parent.tools()->set_origin;
136 current_registry_pointer = nullptr; // no need for a window141 current_registry_pointer = nullptr; // no need for a window
137 break;142 break;
143 case 8:
144 current_tool_pointer = &parent.tools()->resize;
145 current_registry_pointer = &parent.resizemenu_;
146 break;
138 default:147 default:
139 NEVER_HERE();148 NEVER_HERE();
140 }149 }
@@ -174,6 +183,10 @@
174 new EditorToolChangeResourcesOptionsMenu(183 new EditorToolChangeResourcesOptionsMenu(
175 parent, parent.tools()->increase_resources, *current_registry_pointer);184 parent, parent.tools()->increase_resources, *current_registry_pointer);
176 break;185 break;
186 case 8:
187 new EditorToolResizeOptionsMenu(
188 parent, parent.tools()->resize, *current_registry_pointer);
189 break;
177 default:190 default:
178 NEVER_HERE();191 NEVER_HERE();
179 }192 }
180193
=== added file 'src/editor/ui_menus/tool_resize_options_menu.cc'
--- src/editor/ui_menus/tool_resize_options_menu.cc 1970-01-01 00:00:00 +0000
+++ src/editor/ui_menus/tool_resize_options_menu.cc 2019-04-23 14:01:41 +0000
@@ -0,0 +1,108 @@
1/*
2 * Copyright (C) 2002-2019 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#include "editor/ui_menus/tool_resize_options_menu.h"
21
22#include <cstdio>
23#include <string>
24
25#include "base/i18n.h"
26#include "base/wexception.h"
27#include "editor/editorinteractive.h"
28#include "editor/tools/resize_tool.h"
29#include "graphic/graphic.h"
30#include "logic/map.h"
31
32inline EditorInteractive& EditorToolResizeOptionsMenu::eia() {
33 return dynamic_cast<EditorInteractive&>(*get_parent());
34}
35
36EditorToolResizeOptionsMenu::EditorToolResizeOptionsMenu(
37 EditorInteractive& parent,
38 EditorResizeTool& resize_tool,
39 UI::UniqueWindow::Registry& registry)
40 : EditorToolOptionsMenu(parent, registry, 260, 200, _("Resize")),
41 resize_tool_(resize_tool),
42 box_(this, hmargin(), vmargin(), UI::Box::Vertical, 0, 0, vspacing()),
43 new_width_(&box_,
44 0,
45 0,
46 get_inner_w() - 2 * hmargin(),
47 200,
48 24,
49 _("New width"),
50 UI::DropdownType::kTextual,
51 UI::PanelStyle::kWui),
52 new_height_(&box_,
53 0,
54 0,
55 get_inner_w() - 2 * hmargin(),
56 200,
57 24,
58 _("New height"),
59 UI::DropdownType::kTextual,
60 UI::PanelStyle::kWui),
61 text_area_(&box_,
62 0,
63 0,
64 get_inner_w() - 2 * hmargin(),
65 48,
66 UI::PanelStyle::kWui,
67 _("Select the new map size, then click the map to split it at the desired location."),
68 UI::Align::kCenter,
69 UI::MultilineTextarea::ScrollMode::kNoScrolling) {
70
71 for (const int32_t& i : Widelands::kMapDimensions) {
72 new_width_.add(std::to_string(i), i);
73 new_height_.add(std::to_string(i), i);
74 }
75 new_width_.select(parent.egbase().map().get_width());
76 new_height_.select(parent.egbase().map().get_height());
77 new_width_.set_max_items(8);
78 new_height_.set_max_items(8);
79
80 new_width_.selected.connect(
81 boost::bind(&EditorToolResizeOptionsMenu::update_width, boost::ref(*this)));
82 new_height_.selected.connect(
83 boost::bind(&EditorToolResizeOptionsMenu::update_height, boost::ref(*this)));
84
85 box_.add(&text_area_);
86 box_.set_size(100, 20); // Prevent assert failures
87 box_.add(&new_width_, UI::Box::Resizing::kFullSize);
88 box_.add(&new_height_, UI::Box::Resizing::kFullSize);
89
90 box_.set_size(get_inner_w() - 2 * hmargin(),
91 new_width_.get_h() + new_height_.get_h() + text_area_.get_h() + 2 * vspacing());
92 set_inner_size(get_inner_w(), box_.get_h() + 1 * vmargin());
93}
94
95void EditorToolResizeOptionsMenu::update_width() {
96 int32_t w = new_width_.get_selected();
97 assert(w > 0);
98 resize_tool_.set_width(w);
99 select_correct_tool();
100}
101
102void EditorToolResizeOptionsMenu::update_height() {
103 int32_t h = new_height_.get_selected();
104 assert(h > 0);
105 resize_tool_.set_height(h);
106 select_correct_tool();
107}
108
0109
=== added file 'src/editor/ui_menus/tool_resize_options_menu.h'
--- src/editor/ui_menus/tool_resize_options_menu.h 1970-01-01 00:00:00 +0000
+++ src/editor/ui_menus/tool_resize_options_menu.h 2019-04-23 14:01:41 +0000
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2002-2019 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#ifndef WL_EDITOR_UI_MENUS_TOOL_RESIZE_OPTIONS_MENU_H
21#define WL_EDITOR_UI_MENUS_TOOL_RESIZE_OPTIONS_MENU_H
22
23#include "editor/ui_menus/tool_options_menu.h"
24#include "ui_basic/box.h"
25#include "ui_basic/dropdown.h"
26#include "ui_basic/multilinetextarea.h"
27
28class EditorInteractive;
29struct EditorResizeTool;
30
31struct EditorToolResizeOptionsMenu : public EditorToolOptionsMenu {
32 EditorToolResizeOptionsMenu(EditorInteractive&,
33 EditorResizeTool&,
34 UI::UniqueWindow::Registry&);
35
36private:
37 EditorInteractive& eia();
38 void update_width();
39 void update_height();
40
41 EditorResizeTool& resize_tool_;
42 UI::Box box_;
43 UI::Dropdown<int32_t> new_width_;
44 UI::Dropdown<int32_t> new_height_;
45 UI::MultilineTextarea text_area_;
46};
47
48#endif // end of include guard: WL_EDITOR_UI_MENUS_TOOL_RESIZE_OPTIONS_MENU_H
049
=== modified file 'src/logic/map.cc'
--- src/logic/map.cc 2019-03-24 13:16:11 +0000
+++ src/logic/map.cc 2019-04-23 14:01:41 +0000
@@ -54,6 +54,21 @@
5454
55namespace Widelands {55namespace Widelands {
5656
57FieldData::FieldData(const Field& field)
58 : height(field.get_height()),
59 resources(field.get_resources()),
60 resource_amount(field.get_initial_res_amount()),
61 terrains(field.get_terrains()) {
62 if (const BaseImmovable* imm = field.get_immovable()) {
63 immovable = imm->descr().name();
64 } else {
65 immovable = "";
66 }
67 for (Bob* bob = field.get_first_bob(); bob; bob = bob->get_next_bob()) {
68 bobs.push_back(bob->descr().name());
69 }
70}
71
57/*72/*
58==============================================================================73==============================================================================
5974
@@ -456,6 +471,11 @@
456 filesystem_.reset(nullptr);471 filesystem_.reset(nullptr);
457}472}
458473
474// Made this a separate function to reduce compiler warnings
475template <typename T = Field> static inline void clear_array(std::unique_ptr<T[]>* array, uint32_t size) {
476 memset(array->get(), 0, sizeof(T) * size);
477}
478
459void Map::set_origin(const Coords& new_origin) {479void Map::set_origin(const Coords& new_origin) {
460 assert(0 <= new_origin.x);480 assert(0 <= new_origin.x);
461 assert(new_origin.x < width_);481 assert(new_origin.x < width_);
@@ -469,7 +489,7 @@
469 }489 }
470490
471 std::unique_ptr<Field[]> new_field_order(new Field[field_size]);491 std::unique_ptr<Field[]> new_field_order(new Field[field_size]);
472 memset(new_field_order.get(), 0, sizeof(Field) * field_size);492 clear_array<>(&new_field_order, field_size);
473493
474 // Rearrange The fields494 // Rearrange The fields
475 // NOTE because of the triangle design, we have to take special care of cases495 // NOTE because of the triangle design, we have to take special care of cases
@@ -524,6 +544,148 @@
524 log("Map origin was shifted by (%d, %d)\n", new_origin.x, new_origin.y);544 log("Map origin was shifted by (%d, %d)\n", new_origin.x, new_origin.y);
525}545}
526546
547/* Helper function for resize():
548 * Calculates the coords of 'c' after resizing the map from the given old size to the given new size at 'split'.
549 */
550static Coords transform_coords(const Coords& c, const Coords& split,
551 int16_t w_new, int16_t h_new, int16_t w_old, int16_t h_old) {
552 const int16_t delta_w = w_new - w_old;
553 const int16_t delta_h = h_new - h_old;
554 if (c.x < split.x && c.y < split.y) {
555 // Nothing to shift
556 Coords result(c);
557 Map::normalize_coords(result, w_new, h_new);
558 return result;
559 } else if ((w_new < w_old && c.x >= split.x && c.x < split.x - delta_w) ||
560 (h_new < h_old && c.y >= split.y && c.y < split.y - delta_h)) {
561 // Field removed
562 return Coords::null();
563 }
564 Coords result(c.x, c.y);
565 if (c.x >= split.x) {
566 result.x += delta_w;
567 }
568 if (c.y >= split.y) {
569 result.y += delta_h;
570 }
571 Map::normalize_coords(result, w_new, h_new);
572 return result;
573}
574
575/* Change the size of the (already initialized) map to 'w'×'h' by inserting/deleting fields south and east of 'split'.
576 * Returns the data of fields that were deleted during resizing.
577 * This function will notify all players of the change in map size, but not of anything else. This is because
578 * the editor may want to do some post-resize cleanup first, and this function is intended to be used only
579 * by the editor anyway.
580 * You should call recalc_whole_map() afterwards to resolve height differences etc.
581 */
582std::map<Coords, FieldData> Map::resize(EditorGameBase& egbase, const Coords split, const int32_t w, const int32_t h) {
583 assert(w > 0);
584 assert(h > 0);
585
586 std::map<Coords, FieldData> deleted;
587 if (w == width_ && h == height_) {
588 return deleted;
589 }
590
591 const uint32_t field_size = w * h;
592 const uint32_t old_field_size = width_ * height_;
593
594 std::unique_ptr<Field[]> new_fields(new Field[field_size]);
595 clear_array<>(&new_fields, field_size);
596
597 // Take care of starting positions and port spaces
598 for (uint8_t i = get_nrplayers(); i > 0; --i) {
599 if (starting_pos_[i - 1]) {
600 starting_pos_[i - 1] = transform_coords(starting_pos_[i - 1], split, w, h, width_, height_);
601 }
602 }
603
604 PortSpacesSet new_port_spaces;
605 for (Coords it : port_spaces_) {
606 if (Coords c = transform_coords(it, split, w, h, width_, height_)) {
607 new_port_spaces.insert(c);
608 }
609 }
610 port_spaces_ = new_port_spaces;
611
612 Field::Terrains default_terrains;
613 default_terrains.r = 0;
614 default_terrains.d = 0;
615
616 std::unique_ptr<bool[]> preserved_coords(new bool[old_field_size]);
617 clear_array<bool>(&preserved_coords, old_field_size);
618
619 const int16_t w_max = w > width_ ? w : width_;
620 const int16_t h_max = h > height_ ? h : height_;
621 for (int16_t x = 0; x < w_max; ++x) {
622 for (int16_t y = 0; y < h_max; ++y) {
623 Coords c_new = Coords(x, y);
624 if (x < width_ && y < height_ && !preserved_coords[get_index(c_new, width_)]) {
625 // Save the data of fields that will be deleted
626 Field& field = operator[](c_new);
627 deleted.insert(std::make_pair(c_new, FieldData(field)));
628 // ...and now we delete stuff that needs removing when the field is destroyed
629 if (BaseImmovable* imm = field.get_immovable()) {
630 imm->remove(egbase);
631 }
632 while (Bob* bob = field.get_first_bob()) {
633 bob->remove(egbase);
634 }
635 }
636 if (x < w && y < h) {
637 if (Coords c_old = transform_coords(c_new, split, width_, height_, w, h)) {
638 bool& entry = preserved_coords[get_index(c_old, width_)];
639 if (!entry) {
640 // Copy existing field
641 entry = true;
642 new_fields[get_index(c_new, w)] = operator[](c_old);
643 continue;
644 }
645 }
646 // Init new field
647 Field& field = new_fields[get_index(c_new, w)];
648 field.set_height(10);
649 field.set_terrains(default_terrains);
650 }
651 }
652 }
653
654 // Replace all fields
655 fields_.reset(new Field[field_size]);
656 clear_array<>(&fields_, field_size);
657 for (size_t ind = 0; ind < field_size; ++ind) {
658 fields_[ind] = new_fields[ind];
659 }
660 log("Resized map from (%d, %d) to (%u, %u) at (%d, %d)\n", width_, height_, w, h, split.x, split.y);
661 width_ = w;
662 height_ = h;
663
664 // Inform immovables and bobs about their new position
665 for (MapIndex idx = 0; idx < field_size; ++idx) {
666 Field& f = operator[](idx);
667 if (upcast(Immovable, immovable, f.get_immovable())) {
668 immovable->position_ = get_fcoords(f);
669 }
670 // Ensuring that all bob iterators are changed correctly is a bit hacky, but the more obvious
671 // solution of doing it like in set_origin() is highly problematic here, or so ASan tells me
672 std::vector<Bob*> bobs;
673 for (Bob* bob = f.get_first_bob(); bob; bob = bob->get_next_bob()) {
674 bobs.push_back(bob);
675 }
676 f.bobs = nullptr;
677 for (Bob* bob : bobs) {
678 bob->position_.field = nullptr;
679 bob->linknext_ = nullptr;
680 bob->linkpprev_ = nullptr;
681 bob->set_position(egbase, get_fcoords(f));
682 }
683 }
684
685 egbase.allocate_player_maps();
686 return deleted;
687}
688
527/*689/*
528===============690===============
529Set the size of the map. This should only happen once during initial load.691Set the size of the map. This should only happen once during initial load.
@@ -535,10 +697,12 @@
535 width_ = w;697 width_ = w;
536 height_ = h;698 height_ = h;
537699
538 fields_.reset(new Field[w * h]);700 const uint32_t field_size = w * h;
539 memset(fields_.get(), 0, sizeof(Field) * w * h);701
540702 fields_.reset(new Field[field_size]);
541 pathfieldmgr_->set_size(w * h);703 clear_array<>(&fields_, field_size);
704
705 pathfieldmgr_->set_size(field_size);
542}706}
543707
544/*708/*
545709
=== modified file 'src/logic/map.h'
--- src/logic/map.h 2019-03-24 13:16:11 +0000
+++ src/logic/map.h 2019-04-23 14:01:41 +0000
@@ -104,6 +104,18 @@
104 } // make gcc shut up104 } // make gcc shut up
105};105};
106106
107// Helper struct to save certain elemental data of a field without an actual instance of Field
108struct FieldData {
109 FieldData(const Field& f);
110
111 std::string immovable;
112 std::list<std::string> bobs;
113 uint8_t height;
114 DescriptionIndex resources;
115 uint8_t resource_amount;
116 Field::Terrains terrains;
117};
118
107/** class Map119/** class Map
108 *120 *
109 * This really identifies a map like it is in the game121 * This really identifies a map like it is in the game
@@ -327,6 +339,7 @@
327 Field& operator[](MapIndex) const;339 Field& operator[](MapIndex) const;
328 Field& operator[](const Coords&) const;340 Field& operator[](const Coords&) const;
329 FCoords get_fcoords(const Coords&) const;341 FCoords get_fcoords(const Coords&) const;
342 static void normalize_coords(Coords&, int16_t, int16_t);
330 void normalize_coords(Coords&) const;343 void normalize_coords(Coords&) const;
331 FCoords get_fcoords(Field&) const;344 FCoords get_fcoords(Field&) const;
332 void get_coords(Field& f, Coords& c) const;345 void get_coords(Field& f, Coords& c) const;
@@ -498,6 +511,9 @@
498 // Visible for testing.511 // Visible for testing.
499 void set_size(uint32_t w, uint32_t h);512 void set_size(uint32_t w, uint32_t h);
500513
514 // Change the map size
515 std::map<Coords, FieldData> resize(EditorGameBase& egbase, const Coords coords, int32_t w, int32_t h);
516
501private:517private:
502 void recalc_border(const FCoords&);518 void recalc_border(const FCoords&);
503 void recalc_brightness(const FCoords&);519 void recalc_brightness(const FCoords&);
@@ -588,14 +604,22 @@
588}604}
589605
590inline void Map::normalize_coords(Coords& c) const {606inline void Map::normalize_coords(Coords& c) const {
591 while (c.x < 0)607 normalize_coords(c, width_, height_);
592 c.x += width_;608}
593 while (c.x >= width_)609
594 c.x -= width_;610inline void Map::normalize_coords(Coords& c, int16_t w, int16_t h) {
595 while (c.y < 0)611 while (c.x < 0) {
596 c.y += height_;612 c.x += w;
597 while (c.y >= height_)613 }
598 c.y -= height_;614 while (c.x >= w) {
615 c.x -= w;
616 }
617 while (c.y < 0) {
618 c.y += h;
619 }
620 while (c.y >= h) {
621 c.y -= h;
622 }
599}623}
600624
601/**625/**

Subscribers

People subscribed via source and target branches

to status/vote changes: