From 2ae807c202489e0126733c29095947662ad527b1 Mon Sep 17 00:00:00 2001
From: Stijn Buys <ingar@osirion.org>
Date: Sun, 10 Nov 2013 20:44:07 +0000
Subject: Ignore server-side entities when using 'goto' and added a safety
 distance and a nudge check.

---
 src/core/zone.cc      | 19 +++++++++++--------
 src/game/base/game.cc | 22 +++++++++++++++-------
 2 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/src/core/zone.cc b/src/core/zone.cc
index 2ea04fb..659e62f 100644
--- a/src/core/zone.cc
+++ b/src/core/zone.cc
@@ -274,14 +274,17 @@ Entity *Zone::search_entity(const std::string & searchname)
 	for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) {
 		Entity *entity = (*it);
 
-		label.assign(entity->label());
-		if (label.size() && (label.find(strsearchkey) != std::string::npos)) {
-			return entity;
-		}
-
-		name.assign(aux::lowercase(entity->name()));
-		if (name.size() && (name.find(strsearchkey) != std::string::npos)) {
-			return entity;
+		if (!entity->serverside()) 
+		{
+			label.assign(entity->label());
+			if (label.size() && (label.find(strsearchkey) != std::string::npos)) {
+				return entity;
+			}
+
+			name.assign(aux::lowercase(entity->name()));
+			if (name.size() && (name.find(strsearchkey) != std::string::npos)) {
+				return entity;
+			}
 		}
 	}
 
diff --git a/src/game/base/game.cc b/src/game/base/game.cc
index fa3e81a..54c59b7 100644
--- a/src/game/base/game.cc
+++ b/src/game/base/game.cc
@@ -1563,9 +1563,19 @@ void Game::func_goto(core::Player *player, const std::string &args)
 	}
 
 	core::Entity *dock = player->control()->zone()->search_entity(args);
-	Ship *ship = static_cast<Ship *>(player->control());
-
+	
+	// if target is docked,goto the dock instead
+	if (dock->moduletype() == ship_enttype) {
+		Ship *ship = static_cast<Ship *>(dock);
+		
+		if ((ship->state() == core::Entity::Docked) && (ship->dock())) {
+			player->send(ship->name() + " docked at " + ship->dock()->name());
+			dock = ship->dock();
+		}
+	}	
 	if (dock) {
+		Ship *ship = static_cast<Ship *>(player->control());
+		
 		if (dock->type() == core::Entity::Globe) {
 			// target is a planet: keep a safe distance
 			ship->get_location().assign(dock->location() + (dock->axis().forward() * (PLANET_SAFE_DISTANCE + ship->radius() + dock->radius())));
@@ -1574,19 +1584,17 @@ void Game::func_goto(core::Player *player, const std::string &args)
 
 		} else if (dock->type() == core::Entity::Controlable) {
 			// target is a controlable: appear above it
-			
-			// FIxME target might be docked -> requires ship docked_at awareness
-			// we might want to match the target's state() and speed()
-			ship->get_location().assign(dock->location() + (dock->axis().up() * (ship->radius() + dock->radius())));
+			ship->get_location().assign(dock->location() + (dock->axis().up() * (0.25f + ship->radius() + dock->radius())));
 			ship->get_axis().assign(dock->axis());
 			
 		} else {
 			// targe is something else, appear in front of it
-			ship->get_location().assign(dock->location() + (dock->axis().forward() * (ship->radius() + dock->radius())));
+			ship->get_location().assign(dock->location() + (dock->axis().forward() * (0.25f + ship->radius() + dock->radius())));
 			ship->get_axis().assign(dock->axis());
 			ship->get_axis().change_direction(180.0f);
 		}
 		ship->set_state(core::Entity::Normal);
+		ship->nudge();
 		ship->reset();
 
 		player->set_view(0);
-- 
cgit v1.2.3