Merge lp:~widelands-dev/widelands/expedition_portspace_indicator into lp:widelands

Proposed by Benedikt Straub
Status: Merged
Merged at revision: 9093
Proposed branch: lp:~widelands-dev/widelands/expedition_portspace_indicator
Merge into: lp:widelands
Diff against target: 171 lines (+61/-6)
4 files modified
src/game_io/game_interactive_player_packet.cc (+24/-4)
src/wui/interactive_base.cc (+25/-0)
src/wui/interactive_base.h (+8/-0)
src/wui/interactive_player.cc (+4/-2)
To merge this branch: bzr merge lp:~widelands-dev/widelands/expedition_portspace_indicator
Reviewer Review Type Date Requested Status
GunChleoc Approve
Benedikt Straub Needs Resubmitting
Review via email: mp+366640@code.launchpad.net

Commit message

Show a port icon on the field where an expedition ship can build a port

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

Continuous integration builds have changed state:

Travis build 4835. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/525916562.
Appveyor build 4616. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_expedition_portspace_indicator-4616.

Revision history for this message
GunChleoc (gunchleoc) wrote :

We are trying to get rid of references to InteractiveBase from the logic library.

Would you like to try your hand at adding new actions to NoteShip and subscribing to those in InteractivePlayer?

After placing a port construction site, a big building plot icon is shown on top of the construction site.

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

OK, now InteractiveBase receives a notification instead when a portspace is found. Since there are fairly many reasons why a port space can become unavailable again (ship sails on, port is constructed, ship is sunk…), the IBase takes care of cleaning up the set itself now when think()ing. This fixes the bug that the indicator won´t go away on portconstruction.
Also added saving support for the indicators so they are also shown for ships that already are in PortSpaceFound state when the game is loaded.

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

I am still wondering if we can get more performance out of this thing.

* Ship sails on and ship is sunk could be taken care of by the ShipNote
* Port being built can be taken care of by buildcaps, just like we do for the building spaces overlays in general

Any other reasons?

+1 for the saving support :)

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

> Port being built can be taken care of by buildcaps
IMHO we should remove the portspaces either only in response to Notes or only autonomously. Mixing both feels messy.
To use notes, we´d need subscriptions (in addition to what we already have) to
– NoteExpeditionCanceled
– FieldPossession (another possible reason why a portspace might become unavailable is that some other player conquers that land, which is not even necessarily reflected in the buildcaps)
– FieldTerrainChanged (if the port space is removed by a terrain-changing script)
– A tree grows over the port space (or is this forbidden somehow?) → is there a notification for that?
– A script unsets a port space directly → is there a notification for that?

That´s quite a lot for a pretty small feature IMHO; and I don´t think the autonomous cleanup of displayed portspaces is performance-critical – I can´t imagine a player will have so many expeditions at a time that it really matters.

Revision history for this message
GunChleoc (gunchleoc) wrote :

You have convinced me.

I have done more testing - all working now :)

@bunnybot merge

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/game_io/game_interactive_player_packet.cc'
--- src/game_io/game_interactive_player_packet.cc 2019-02-23 11:00:49 +0000
+++ src/game_io/game_interactive_player_packet.cc 2019-05-03 09:15:36 +0000
@@ -25,6 +25,8 @@
25#include "logic/game_data_error.h"25#include "logic/game_data_error.h"
26#include "logic/map_objects/tribes/tribe_descr.h"26#include "logic/map_objects/tribes/tribe_descr.h"
27#include "logic/player.h"27#include "logic/player.h"
28#include "map_io/map_object_loader.h"
29#include "map_io/map_object_saver.h"
28#include "wui/interactive_player.h"30#include "wui/interactive_player.h"
29#include "wui/mapview.h"31#include "wui/mapview.h"
3032
@@ -32,16 +34,16 @@
3234
33namespace {35namespace {
3436
35constexpr uint16_t kCurrentPacketVersion = 4;37constexpr uint16_t kCurrentPacketVersion = 5;
3638
37} // namespace39} // namespace
3840
39void GameInteractivePlayerPacket::read(FileSystem& fs, Game& game, MapObjectLoader*) {41void GameInteractivePlayerPacket::read(FileSystem& fs, Game& game, MapObjectLoader* mol) {
40 try {42 try {
41 FileRead fr;43 FileRead fr;
42 fr.open(fs, "binary/interactive_player");44 fr.open(fs, "binary/interactive_player");
43 uint16_t const packet_version = fr.unsigned_16();45 uint16_t const packet_version = fr.unsigned_16();
44 if (packet_version == kCurrentPacketVersion) {46 if (packet_version <= kCurrentPacketVersion && packet_version >= 4) {
45 PlayerNumber player_number = fr.unsigned_8();47 PlayerNumber player_number = fr.unsigned_8();
46 if (!(0 < player_number && player_number <= game.map().get_nrplayers())) {48 if (!(0 < player_number && player_number <= game.map().get_nrplayers())) {
47 throw GameDataError("Invalid player number: %i.", player_number);49 throw GameDataError("Invalid player number: %i.", player_number);
@@ -92,6 +94,17 @@
92 ibase->set_landmark(i, view);94 ibase->set_landmark(i, view);
93 }95 }
94 }96 }
97
98 if (packet_version == kCurrentPacketVersion) {
99 size_t nr_port_spaces = fr.unsigned_32();
100 for (size_t i = 0; i < nr_port_spaces; ++i) {
101 uint32_t serial = fr.unsigned_32();
102 int16_t x = fr.signed_16();
103 int16_t y = fr.signed_16();
104 ibase->get_expedition_port_spaces().emplace(&mol->get<Widelands::Ship>(serial),
105 Widelands::Coords(x, y));
106 }
107 }
95 }108 }
96 } else {109 } else {
97 throw UnhandledVersionError(110 throw UnhandledVersionError(
@@ -105,7 +118,7 @@
105/*118/*
106 * Write Function119 * Write Function
107 */120 */
108void GameInteractivePlayerPacket::write(FileSystem& fs, Game& game, MapObjectSaver* const) {121void GameInteractivePlayerPacket::write(FileSystem& fs, Game& game, MapObjectSaver* const mos) {
109 FileWrite fw;122 FileWrite fw;
110123
111 fw.unsigned_16(kCurrentPacketVersion);124 fw.unsigned_16(kCurrentPacketVersion);
@@ -138,6 +151,13 @@
138 fw.float_32(landmark.view.viewpoint.y);151 fw.float_32(landmark.view.viewpoint.y);
139 fw.float_32(landmark.view.zoom);152 fw.float_32(landmark.view.zoom);
140 }153 }
154
155 fw.unsigned_32(ibase->get_expedition_port_spaces().size());
156 for (const auto& pair : ibase->get_expedition_port_spaces()) {
157 fw.unsigned_32(mos->get_object_file_index(*pair.first));
158 fw.signed_16(pair.second.x);
159 fw.signed_16(pair.second.y);
160 }
141 }161 }
142162
143 fw.write(fs, "binary/interactive_player");163 fw.write(fs, "binary/interactive_player");
144164
=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc 2019-04-25 06:31:33 +0000
+++ src/wui/interactive_base.cc 2019-05-03 09:15:36 +0000
@@ -152,6 +152,12 @@
152 });152 });
153 sound_subscriber_ = Notifications::subscribe<NoteSound>(153 sound_subscriber_ = Notifications::subscribe<NoteSound>(
154 [this](const NoteSound& note) { play_sound_effect(note); });154 [this](const NoteSound& note) { play_sound_effect(note); });
155 shipnotes_subscriber_ = Notifications::subscribe<Widelands::NoteShip>([this](const Widelands::NoteShip& note) {
156 if (note.action == Widelands::NoteShip::Action::kWaitingForCommand &&
157 note.ship->get_ship_state() == Widelands::Ship::ShipStates::kExpeditionPortspaceFound) {
158 expedition_port_spaces_.emplace(note.ship, note.ship->exp_port_spaces().front());
159 }
160 });
155161
156 toolbar_.set_layout_toplevel(true);162 toolbar_.set_layout_toplevel(true);
157 map_view_.changeview.connect([this] { mainview_move(); });163 map_view_.changeview.connect([this] { mainview_move(); });
@@ -304,6 +310,15 @@
304void InteractiveBase::on_buildhelp_changed(bool /* value */) {310void InteractiveBase::on_buildhelp_changed(bool /* value */) {
305}311}
306312
313bool InteractiveBase::has_expedition_port_space(const Widelands::Coords& coords) const {
314 for (const auto& pair : expedition_port_spaces_) {
315 if (pair.second == coords) {
316 return true;
317 }
318 }
319 return false;
320}
321
307// Show the given workareas at the given coords and returns the overlay job id associated322// Show the given workareas at the given coords and returns the overlay job id associated
308void InteractiveBase::show_workarea(const WorkareaInfo& workarea_info, Widelands::Coords coords) {323void InteractiveBase::show_workarea(const WorkareaInfo& workarea_info, Widelands::Coords coords) {
309 workarea_previews_[coords] = &workarea_info;324 workarea_previews_[coords] = &workarea_info;
@@ -457,6 +472,16 @@
457 }472 }
458 egbase().think(); // Call game logic here. The game advances.473 egbase().think(); // Call game logic here. The game advances.
459474
475 // Cleanup found port spaces if the ship sailed on or was destroyed
476 for (auto it = expedition_port_spaces_.begin(); it != expedition_port_spaces_.end(); ++it) {
477 if (!egbase().objects().object_still_available(it->first) ||
478 it->first->get_ship_state() != Widelands::Ship::ShipStates::kExpeditionPortspaceFound) {
479 expedition_port_spaces_.erase(it);
480 // If another port space also needs removing, we'll take care of it in the next frame
481 return;
482 }
483 }
484
460 UI::Panel::think();485 UI::Panel::think();
461}486}
462487
463488
=== modified file 'src/wui/interactive_base.h'
--- src/wui/interactive_base.h 2019-04-25 06:31:33 +0000
+++ src/wui/interactive_base.h 2019-05-03 09:15:36 +0000
@@ -86,6 +86,11 @@
86 void show_workarea(const WorkareaInfo& workarea_info, Widelands::Coords coords);86 void show_workarea(const WorkareaInfo& workarea_info, Widelands::Coords coords);
87 void hide_workarea(const Widelands::Coords& coords);87 void hide_workarea(const Widelands::Coords& coords);
8888
89 bool has_expedition_port_space(const Widelands::Coords&) const;
90 std::map<Widelands::Ship*, Widelands::Coords>& get_expedition_port_spaces() {
91 return expedition_port_spaces_;
92 }
93
89 // point of view for drawing94 // point of view for drawing
90 virtual Widelands::Player* get_player() const = 0;95 virtual Widelands::Player* get_player() const = 0;
9196
@@ -291,11 +296,14 @@
291 // coordinate that the building that shows the work area is positioned.296 // coordinate that the building that shows the work area is positioned.
292 std::map<Widelands::Coords, const WorkareaInfo*> workarea_previews_;297 std::map<Widelands::Coords, const WorkareaInfo*> workarea_previews_;
293298
299 std::map<Widelands::Ship*, Widelands::Coords> expedition_port_spaces_;
300
294 RoadBuildingOverlays road_building_overlays_;301 RoadBuildingOverlays road_building_overlays_;
295302
296 std::unique_ptr<Notifications::Subscriber<GraphicResolutionChanged>>303 std::unique_ptr<Notifications::Subscriber<GraphicResolutionChanged>>
297 graphic_resolution_changed_subscriber_;304 graphic_resolution_changed_subscriber_;
298 std::unique_ptr<Notifications::Subscriber<NoteSound>> sound_subscriber_;305 std::unique_ptr<Notifications::Subscriber<NoteSound>> sound_subscriber_;
306 std::unique_ptr<Notifications::Subscriber<Widelands::NoteShip>> shipnotes_subscriber_;
299 Widelands::EditorGameBase& egbase_;307 Widelands::EditorGameBase& egbase_;
300 uint32_t display_flags_;308 uint32_t display_flags_;
301 uint32_t lastframe_; // system time (milliseconds)309 uint32_t lastframe_; // system time (milliseconds)
302310
=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc 2019-04-25 06:31:33 +0000
+++ src/wui/interactive_player.cc 2019-05-03 09:15:36 +0000
@@ -339,8 +339,10 @@
339339
340 if (f->vision > 0) {340 if (f->vision > 0) {
341 // Draw build help.341 // Draw build help.
342 if (buildhelp()) {342 bool show_port_space = has_expedition_port_space(f->fcoords);
343 const auto* overlay = get_buildhelp_overlay(plr.get_buildcaps(f->fcoords));343 if (show_port_space || buildhelp()) {
344 const auto* overlay = get_buildhelp_overlay(show_port_space ?
345 f->fcoords.field->maxcaps() : plr.get_buildcaps(f->fcoords));
344 if (overlay != nullptr) {346 if (overlay != nullptr) {
345 blit_field_overlay(dst, *f, overlay->pic, overlay->hotspot, scale);347 blit_field_overlay(dst, *f, overlay->pic, overlay->hotspot, scale);
346 }348 }

Subscribers

People subscribed via source and target branches

to status/vote changes: