← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/compass into lp:widelands

 

cghislai has proposed merging lp:~widelands-dev/widelands/compass into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #902558 in widelands: "Workers returning to a building being dismantled will attempt to enter it"
  https://bugs.launchpad.net/widelands/+bug/902558
  Bug #923702 in widelands: "soldier "lost" if the building he is returning to has been destroyed"
  https://bugs.launchpad.net/widelands/+bug/923702
  Bug #1144465 in widelands: "Builder gets "lost" after dismantling site"
  https://bugs.launchpad.net/widelands/+bug/1144465

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/compass/+merge/177280

These few fixes help a little bit workers to find their way correctly.
- Builder will correctly return to base flag after dismantling
- Workers will correctly return to baseflag if building is being dismantled
- Soldiers will try to get back to homeland if their building is destroyed. Only then they will become fugitive, but will most probably find a flag. If no land is in sight (2*sight), they will become fugitive and will most likely die.
-- 
https://code.launchpad.net/~widelands-dev/widelands/compass/+merge/177280
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/compass into lp:widelands.
=== modified file 'src/logic/dismantlesite.cc'
--- src/logic/dismantlesite.cc	2013-07-26 20:19:36 +0000
+++ src/logic/dismantlesite.cc	2013-07-28 09:18:26 +0000
@@ -210,7 +210,13 @@
 		schedule_destroy(game);
 
 		worker.pop_task(game);
-		worker.start_task_leavebuilding(game, true);
+		// No more building, so move to the flag
+		worker.start_task_move
+				(game,
+				 WALK_SE,
+				 worker.descr().get_right_walk_anims(false),
+				 true);
+		worker.set_location(nullptr);
 	} else if (not m_working) {
 		m_work_steptime = game.get_gametime() + DISMANTLESITE_STEP_TIME;
 		worker.start_task_idle

=== modified file 'src/logic/findnode.cc'
--- src/logic/findnode.cc	2013-07-27 11:02:05 +0000
+++ src/logic/findnode.cc	2013-07-28 09:18:26 +0000
@@ -131,8 +131,10 @@
 	}
 	for (Direction dir = FIRST_DIRECTION; dir <= LAST_DIRECTION; ++dir) {
 		const FCoords neighb = map.get_neighbour(coord, dir);
-		if (m_resource == neighb.field->get_resources() &&
-			 neighb.field->get_resources_amount() < neighb.field->get_starting_res_amount()) {
+		if 
+			(m_resource == neighb.field->get_resources()
+			 && neighb.field->get_resources_amount() < neighb.field->get_starting_res_amount())
+		{
 			return true;
 		}
 	}

=== modified file 'src/logic/soldier.cc'
--- src/logic/soldier.cc	2013-07-26 20:19:36 +0000
+++ src/logic/soldier.cc	2013-07-28 09:18:26 +0000
@@ -22,6 +22,7 @@
 #include <cstdio>
 #include <list>
 
+#include "economy/economy.h"
 #include "economy/flag.h"
 #include "gamecontroller.h"
 #include "graphic/graphic.h"
@@ -34,6 +35,7 @@
 #include "logic/editor_game_base.h"
 #include "logic/findbob.h"
 #include "logic/findimmovable.h"
+#include "logic/findnode.h"
 #include "logic/game.h"
 #include "logic/game_data_error.h"
 #include "logic/message_queue.h"
@@ -759,6 +761,15 @@
 	return Worker::init_auto_task(game);
 }
 
+struct FindNodeOwned {
+	FindNodeOwned(Player_Number owner) : m_owner(owner)
+	{};
+	bool accept(const Map & map, const FCoords & coords) const {
+		return (coords.field->get_owned_by() == m_owner);
+	}
+private:
+	Player_Number m_owner;
+};
 
 /**
  * Leave our home building and single-mindedly try to attack
@@ -784,6 +795,7 @@
 	State & state  = top_state();
 	state.objvar1  = &building;
 	state.coords   = building.get_position();
+	state.ivar2    = 0; // Thre return state 1=go home 2=go back in known land
 
 	if (retreat) {
 		assert(retreat < 101);
@@ -818,6 +830,12 @@
 				molog("[attack] unexpected fail\n");
 				return pop_task(game);
 			}
+		} else if (signal == "location") {
+			molog("[attack] Location destroyed\n");
+			signal_handled();
+			if (state.ivar2 == 0) {
+				state.ivar2 = 1;
+			}
 		} else {
 			molog
 				("[attack] cancelled by unexpected signal '%s'\n", signal.c_str());
@@ -834,14 +852,101 @@
 	upcast(Building, location, get_location(game));
 	upcast(Building, enemy, state.objvar1.get(game));
 
-	if (location && get_position() == location->get_position()) {
-		if (!enemy) {
-			molog("[attack] returned home\n");
-			return pop_task(game);
-		}
-		return start_task_leavebuilding(game, false);
+	// Handle returns
+	if (state.ivar2 > 0) {
+		if (state.ivar2 == 1) {
+			// Return home
+			if (!location || !is_a(MilitarySite, location)) {
+				molog("[attack] No more site to go back to\n");
+				state.ivar2 = 2;
+				return schedule_act(game, 10);
+			}
+			Flag & baseflag = location->base_flag();
+			if (get_position() == baseflag.get_position()) {
+				// At flag, enter building
+				return
+					start_task_move
+						(game,
+							WALK_NW,
+							descr().get_right_walk_anims(does_carry_ware()),
+							true);
+			}
+			if (get_position() == location->get_position()) {
+				// At building, check if attack is required
+				if (!enemy) {
+					molog("[attack] returned home\n");
+					return pop_task(game);
+				}
+				state.ivar2 = 0;
+				return start_task_leavebuilding(game, false);
+			}
+			// Head to home
+			if
+				(start_task_movepath
+					(game,
+						baseflag.get_position(),
+						4, // use larger persist when returning home
+						descr().get_right_walk_anims(does_carry_ware())))
+				return;
+			else {
+				molog("[attack] failed to return home\n");
+				return pop_task(game);
+			}
+		}
+		if (state.ivar2 == 2) {
+			// No more home, so return to homeland
+			upcast(Flag, flag, game.map().get_immovable(get_position()));
+			if (flag && flag->get_owner() == get_owner()) {
+				// At a flag
+				molog("[attack] Returned to own flag\n");
+				return pop_task(game);
+			}
+			Coords target;
+			if (get_location(game)) {
+				// We still have a location, head for the flag
+				target = get_location(game)->base_flag().get_position();
+				molog("[attack] Going back to our flag\n");
+			} else {
+				// No location
+				if (get_position().field->get_owned_by() == get_owner()->player_number()) {
+					// We are in our land, become fugitive
+					molog("[attack] Back to our land\n");
+					return pop_task(game);
+				}
+				// Try to find our land
+				Map* map = game.get_map();
+				std::vector<Coords> coords;
+				uint32_t maxdist = vision_range() * 2;
+				Area<FCoords> area(map->get_fcoords(get_position()), maxdist);
+				if
+					(map->find_reachable_fields
+						(area, &coords, CheckStepDefault(descr().movecaps()),
+						 FindNodeOwned(get_owner()->player_number())))
+				{
+					// Found home land
+					target = coords.front();
+					molog("[attack] Going back to our land\n");
+				} else {
+					// Become fugitive
+					molog("[attack] No land in sight\n");
+					return pop_task(game);
+				}
+			}
+			if
+				(start_task_movepath
+					(game,
+						target,
+						4, // use larger persist when returning home
+						descr().get_right_walk_anims(does_carry_ware())))
+				return;
+			else {
+				molog("[attack] failed to return to own land\n");
+				return pop_task(game);
+			}
+		}
 	}
 
+
 	if (m_battle)
 		return start_task_battle(game);
 
@@ -853,11 +958,6 @@
 		return start_task_idle(game, get_animation("idle"), 5000);
 	}
 
-	if (!location) {
-		molog("[attack] our location disappeared during a battle\n");
-		return pop_task(game);
-	}
-
 	// Count remaining defenders
 	if (enemy) {
 		if (upcast(MilitarySite, ms, enemy)) {
@@ -913,26 +1013,9 @@
 				}
 			}
 		}
-		Flag & baseflag = location->base_flag();
-		if (get_position() == baseflag.get_position())
-			return
-				start_task_move
-					(game,
-					 WALK_NW,
-					 descr().get_right_walk_anims(does_carry_ware()),
-					 true);
-
-		if
-			(start_task_movepath
-			 	(game,
-			 	 baseflag.get_position(),
-			 	 4, // use larger persist when returning home
-			 	 descr().get_right_walk_anims(does_carry_ware())))
-			return;
-		else {
-			molog("[attack] failed to return home\n");
-			return pop_task(game);
-		}
+		// Return home
+		state.ivar2 = 1;
+		return schedule_act(game, 10);
 	}
 
 	// At this point, we know that the enemy building still stands,
@@ -951,6 +1034,7 @@
 				 "and return home!\n");
 			state.coords = Coords::Null();
 			state.objvar1 = 0;
+			state.ivar2 = 1;
 			return schedule_act(game, 10);
 		}
 	}

=== modified file 'src/logic/worker.cc'
--- src/logic/worker.cc	2013-07-27 11:02:05 +0000
+++ src/logic/worker.cc	2013-07-28 09:18:26 +0000
@@ -31,6 +31,7 @@
 #include "logic/checkstep.h"
 #include "logic/cmd_incorporate.h"
 #include "logic/critter_bob.h"
+#include "logic/dismantlesite.h"
 #include "logic/findbob.h"
 #include "logic/findimmovable.h"
 #include "logic/findnode.h"
@@ -1824,19 +1825,28 @@
 		if (upcast(Flag, flag, pos)) {
 			// Is this "our" flag?
 			if (flag->get_building() == location) {
-				if (state.ivar1 && flag->has_capacity())
+				if (state.ivar1 && flag->has_capacity()) {
 					if (WareInstance * const item = fetch_carried_item(game)) {
 						flag->add_item(game, *item);
 						set_animation(game, descr().get_animation("idle"));
 						return schedule_act(game, 20); //  rest a while
 					}
+				}
 
-				return
-					start_task_move
-						(game,
-						 WALK_NW,
-						 descr().get_right_walk_anims(does_carry_ware()),
-						 true);
+				// Don't try to enter building if it is a dismantle site
+				// It is no problem for builders since they won't return before
+				// dismantling is complete.
+				if (is_a(DismantleSite, location)) {
+					set_location(0);
+					return pop_task(game);
+				} else {
+					return
+						start_task_move
+							(game,
+							WALK_NW,
+							descr().get_right_walk_anims(does_carry_ware()),
+							true);
+				}
 			}
 		}
 	}
@@ -2401,8 +2411,9 @@
 		return pop_task(game);
 
 	upcast(Building, building, get_location(game));
-	if (!building)
+	if (!building) {
 		return pop_task(game);
+	}
 
 	Flag & baseflag = building->base_flag();
 


Follow ups