Index: src/ai/actions.cpp
===================================================================
--- src/ai/actions.cpp	(revision 53920)
+++ src/ai/actions.cpp	(working copy)
@@ -36,6 +36,10 @@
 #include "actions.hpp"
 #include "manager.hpp"
 
+
+#include "../array.hpp"
+
+
 #include "../actions.hpp"
 #include "../dialogs.hpp"
 #include "../game_end_exceptions.hpp"
@@ -343,9 +347,28 @@
 	, route_()
 	, unit_location_(from)
 	, unreach_is_ok_(unreach_is_ok)
+// --Teugon--	
+	, isGoto_(false)
+// --Teugon--
 {
 }
 
+// --Teugon--
+move_result::move_result( side_number side, const map_location& from,
+			 const map_location& to, bool remove_movement, bool unreach_is_ok,
+			 bool isGoto)
+	: action_result(side)
+	, from_(from)
+	, move_spectator_(*resources::units)
+	, to_(to)
+	, remove_movement_(remove_movement)
+	, route_()
+	, unit_location_(from)
+	, unreach_is_ok_(unreach_is_ok)
+	, isGoto_(isGoto)
+{
+}
+// --Teugon--
 
 const unit *move_result::get_unit()
 {
@@ -460,6 +483,24 @@
 {
 	LOG_AI_ACTIONS << "start of execution of: "<< *this << std::endl;
 	assert(is_success());
+	
+	// --Teugon--
+	// only if constructed as a goto move.
+	if (isGoto_)
+	{
+		// check if location "to" does NOT contains an unit.
+		unit_map::const_iterator unit = resources::units->find(to_);
+		if (unit==resources::units->end()){
+			set_error(E_NO_UNIT_TO_GOTO);
+			return;
+		}
+		// check if the unit is NOT from my side.
+		if (unit->side() != get_side()) {
+			set_error(E_NOT_OWN_UNIT_TO_GOTO);
+			return;
+		}
+	}
+	// --Teugon--
 
 	move_spectator_.set_unit(resources::units->find(from_));
 
@@ -474,8 +515,10 @@
 			/*bool continue_move*/ true, ///@todo 1.9 set to false after implemeting interrupt awareness
 			/*bool should_clear_shroud*/ true,
 			/*bool is_replay*/ false);
-
-		if ( move_spectator_.get_ambusher().valid() || !move_spectator_.get_seen_enemies().empty() || !move_spectator_.get_seen_friends().empty() ) {
+		
+		// something which needs to be prompted to the user happened 
+		if ( move_spectator_.get_ambusher().valid() || !move_spectator_.get_seen_enemies().empty() || !move_spectator_.get_seen_friends().empty() ) 
+		{
 			set_gamestate_changed();
 		} else if (move_spectator_.get_unit().valid()){
 			unit_location_ = move_spectator_.get_unit()->get_location();
@@ -483,10 +526,13 @@
 				set_gamestate_changed();
 			}
 		}
-	} else {
+	}
+	//	( from_ == to_)
+	else {
 		assert(remove_movement_);
 	}
 
+	
 	if (move_spectator_.get_unit().valid()){
 		unit_location_ = move_spectator_.get_unit()->get_location();
 		if (remove_movement_ && move_spectator_.get_unit()->movement_left() > 0 && unit_location_ == to_)
@@ -1046,7 +1092,41 @@
 
 }
 
+	
+move_result_ptr actions::execute_goto_action( side_number side,
+	bool execute,
+	const map_location& from,
+	const map_location& to,
+	bool remove_movement,
+	bool unreach_is_ok)
+{	
+	util::array<map_location,6>	 adjacent_tiles_array;
+ 	get_adjacent_tiles( to, &adjacent_tiles_array[0]);
 
+	/* TODO improve: this is naive: it'll stop on first free tile. Possible improvement are:
+	 *	- evaluate if it's better to stay behind the given unit to be protected or to go ahead to be protecting.
+	 *	- evaluate which tile can give an higher defence value.
+	 *	- avoid (if possible) tiles where it could be easily encircled.
+	 */
+	move_result_ptr best_move;
+	for (int i=0; i<6; i++)
+	{
+		move_result_ptr action(new move_result(side,from, adjacent_tiles_array[i],remove_movement,unreach_is_ok,true));
+		execute ? action->execute() : action->check_before();
+		
+		// if it's the last chance it's up to the caller to check the result.
+		if ( 	(i==5)	  
+			|| 	(action->is_ok()) )
+		{
+			best_move = action;
+			break;
+		}
+	}
+	return best_move;
+	
+}
+
+
 recall_result_ptr actions::execute_recall_action( side_number side,
 	bool execute,
 	const std::string& unit_id,
Index: src/ai/lua/core.cpp
===================================================================
--- src/ai/lua/core.cpp	(revision 53920)
+++ src/ai/lua/core.cpp	(working copy)
@@ -197,6 +197,47 @@
 	return ai_execute_move(L, false);
 }
 
+
+//	adaptation of the code from ai_execute_move
+static int ai_execute_goto(lua_State *L, bool remove_movement)
+{
+	map_location	from, to;
+	bool			unreach_is_ok;
+	int				index, side;
+
+	side 			= get_readonly_context(L).get_side();
+	unreach_is_ok	= false;
+	index			= 1;
+
+	if (	(false == to_map_location(L, index, from))
+		||	(false == to_map_location(L, index, to)) )
+	{
+		return luaL_typerror(L, index, "location (unit/integers)");
+	}
+
+	//only if at give index is a boolean we'll convert the given value.
+	if (lua_isboolean(L, index)) {
+		unreach_is_ok = lua_toboolean(L, index);
+	}
+
+ai::move_result_ptr goto_result = ai::actions::execute_goto_action( side,true,from,to,remove_movement,unreach_is_ok);
+	return transform_ai_action(L,goto_result);
+}
+
+
+static int cfun_ai_execute_goto_full(lua_State *L)
+{
+	return ai_execute_goto(L, true);
+}
+
+
+static int cfun_ai_execute_goto_partial(lua_State *L)
+{
+	return ai_execute_goto(L, false);
+}
+
+
+
 static int cfun_ai_execute_attack(lua_State *L)
 {
 	int index = 1;
@@ -816,6 +857,8 @@
 		// End of validation functions
 		{ "move",             		&cfun_ai_execute_move_partial		},
 		{ "move_full",        		&cfun_ai_execute_move_full        	},
+		{ "goto",					&cfun_ai_execute_goto_partial		},
+		{ "goto_full",				&cfun_ai_execute_goto_full			},
 		{ "recall",          		&cfun_ai_execute_recall           	},
 		{ "recruit",          		&cfun_ai_execute_recruit         	},
 		{ "stopunit_all",     		&cfun_ai_execute_stopunit_all     	},
Index: src/ai/actions.hpp
===================================================================
--- src/ai/actions.hpp	(revision 53920)
+++ src/ai/actions.hpp	(working copy)
@@ -91,7 +91,7 @@
 	/* set error code */
 	void set_error(int error_code, bool log_as_error = true);
 
-	/* is error code equal to 0 (no errors)? */
+	/* true if no error happened */
 	bool is_success() const;
 
 	/* note that the game state has been changed */
@@ -157,7 +157,7 @@
 	double aggression_;
 };
 
-class move_result : public action_result {
+class  move_result : public action_result {
 public:
 	move_result( side_number side,
 		const map_location& from,
@@ -165,6 +165,13 @@
 		bool remove_movement,
 		bool unreach_is_ok);
 
+	move_result( side_number side,
+		const map_location& from,
+		const map_location& to,
+		bool remove_movement,
+		bool unreach_is_ok,
+		bool isGoto);
+
 	enum tresult {
 		E_EMPTY_MOVE = 2001,
 		E_NO_UNIT = 2002,
@@ -173,26 +180,31 @@
 		E_AMBUSHED = 2005,
 		E_FAILED_TELEPORT = 2006,
 		E_NOT_REACHED_DESTINATION = 2007,
-		E_NO_ROUTE = 2008
+		E_NO_ROUTE = 2008,
+		E_NO_UNIT_TO_GOTO = 2009,
+		E_NOT_OWN_UNIT_TO_GOTO = 2010
 	};
 
-	virtual std::string do_describe() const;
-	virtual const map_location& get_unit_location() const;
+	virtual std::string 					do_describe() const;
+	virtual const map_location& 			get_unit_location() const;
 protected:
-	virtual void do_check_before();
-	virtual void do_check_after();
-	virtual void do_execute();
-	virtual void do_init_for_execution();
+	virtual void 							do_check_before();
+	virtual void 							do_check_after();
+	virtual void 							do_execute();
+	virtual void 							do_init_for_execution();
 private:
-	const unit *get_unit();
-	bool test_route(const unit &un);
-	const map_location from_;
-	move_unit_spectator move_spectator_;
-	const map_location to_;
-	bool remove_movement_;
+	//	functions
+	const unit 								 *get_unit();
+	bool 									 test_route(const unit &un);
+	//	attributes
+	const map_location 						 from_;
+	move_unit_spectator 					 move_spectator_;
+	const map_location 					 	 to_;
+	bool 									 remove_movement_;
 	boost::shared_ptr<pathfind::plain_route> route_;
-	map_location unit_location_;
-	bool unreach_is_ok_;
+	map_location							 unit_location_;
+	bool									 unreach_is_ok_;
+	bool									 isGoto_;
 };
 
 
@@ -297,6 +309,7 @@
 };
 
 
+
 class actions {
 
 public:
@@ -346,7 +359,29 @@
 	bool unreach_is_ok = false);
 
 
+// --Teugon--
+/**
+ * Ask the game to move our unit from location 'from' in one of the six nearest hex in location 'to', optionally - doing a partial move.
+ * @param side the side which tries to execute the move
+ * @param execute should move be actually executed or not
+ * @param from location of our unit	
+ * @param to where to get closer
+ * @param remove_movement set unit movement to 0 in case of successful move
+ * @retval possible result: ok
+ * @retval possible result: NULL (location to contains no unit, or contains one of yours)
+ * @retval possible result: something wrong
+ * @retval possible result: move is interrupted
+ * @retval possible result: move is impossible
+ */
+static move_result_ptr execute_goto_action( side_number side,
+	bool execute,
+	const map_location& from,
+	const map_location& to,
+	bool remove_movement,
+	bool unreach_is_ok = false);
+// --Teugon--
 
+
 /**
  * Ask the game to recall a unit for us on specified location
  * @param side the side which tries to execute the move
Index: src/ai/contexts.cpp
===================================================================
--- src/ai/contexts.cpp	(revision 53920)
+++ src/ai/contexts.cpp	(working copy)
@@ -106,6 +106,11 @@
 }
 
 
+move_result_ptr readwrite_context_impl::execute_goto_action(const map_location& from, const map_location& to, bool remove_movement){
+	return actions::execute_goto_action(get_side(),true,from,to,remove_movement);
+}
+
+
 move_result_ptr readonly_context_impl::check_move_action(const map_location& from, const map_location& to, bool remove_movement){
 	return actions::execute_move_action(get_side(),false,from,to,remove_movement);
 }
Index: src/ai/contexts.hpp
===================================================================
--- src/ai/contexts.hpp	(revision 53920)
+++ src/ai/contexts.hpp	(working copy)
@@ -64,7 +64,6 @@
 		}
 	}
 
-
 	/**
 	 * Get the current value of the recursion counter
 	 */
@@ -73,11 +72,9 @@
 		return counter_;
 	}
 
-
 	//max recursion depth
 	static const int MAX_COUNTER_VALUE = 100;
 
-
 	/**
 	 * Check if more recursion is allowed
 	 */
@@ -410,7 +407,9 @@
 
 	virtual move_result_ptr execute_move_action(const map_location& from, const map_location& to, bool remove_movement=true) = 0;
 
+	virtual move_result_ptr execute_goto_action(const map_location& from, const map_location& to, bool remove_movement=true) = 0;
 
+
 	virtual recall_result_ptr execute_recall_action(const std::string& id, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location) = 0;
 
 
@@ -938,13 +937,11 @@
 		return target_->suitable_keep(leader_location, leader_paths);
 	}
 
-
 	virtual config to_readonly_context_config() const
 	{
 		return target_->to_readonly_context_config();
 	}
 
-
 	virtual std::map<std::pair<map_location,const unit_type *>,
 		std::pair<battle_context_unit_stats,battle_context_unit_stats> >& unit_stats_cache() const
 	{
@@ -989,7 +986,12 @@
 		return target_->execute_move_action(from, to, remove_movement);
 	}
 
+	virtual move_result_ptr execute_goto_action(const map_location& from, const map_location& to, bool remove_movement=true)
+	{
+		return target_->execute_goto_action(from, to, remove_movement);
+	}
 
+
 	virtual recall_result_ptr execute_recall_action(const std::string& id, const map_location &where = map_location::null_location, const map_location &from = map_location::null_location)
 	{
 		return target_->execute_recall_action(id,where,from);
@@ -1517,7 +1519,24 @@
 	virtual move_result_ptr execute_move_action(const map_location& from, const map_location& to, bool remove_movement=true);
 
 
+
 	/**
+	 * Ask the game to move our unit from location 'from' to nearest hex in location 'to', optionally - doing a partial move
+	 * @param side the side which tries to execute the move
+	 * @param execute should move be actually executed or not
+	 * @param from location of our unit
+	 * @param to where to get as close as possible.
+	 * @param remove_movement set unit movement to 0 in case of successful move
+	 * @retval possible result: ok
+	 * @retval possible result: something wrong
+	 * @retval possible result: move is interrupted
+	 * @retval possible result: move is impossible
+	 */
+	virtual move_result_ptr execute_goto_action(const map_location& from, const map_location& to, bool remove_movement=true);
+
+	
+
+	/**
 	 * Ask the game to recall a unit for us on specified location
 	 * @param id the id of the unit to be recalled.
 	 * @param where location where the unit is to be recalled.
Index: data/core/about.cfg
===================================================================
--- data/core/about.cfg	(revision 53920)
+++ data/core/about.cfg	(working copy)
@@ -1107,6 +1107,11 @@
         email = "asqueados_AT_gmail.com"
     [/entry]
     [entry]
+        name = "Paolo De Luca (teugon)"
+        wikiuser = "teugon"
+        email = "teugon@gmail.com"
+    [/entry]
+    [entry]
         name = "Patryk Obara (dreamer_)"
     [/entry]
     [entry]
Index: changelog
===================================================================
--- changelog	(revision 53920)
+++ changelog	(working copy)
@@ -79,6 +79,7 @@
    * Upgraded Lua from 5.1.4 to 5.2.0
    * new: field wesnoth.game_config.mp_debug
    * new: setter for wesnoth.sides[i].color
+   * new: wrapper functions for actions::execute_goto_action
    * Deprecated the following functions from the wesnoth table,
      all of which have better replacements:
      get_side, get_side_count, get_unit_type_ids, get_unit_type,
@@ -209,6 +210,7 @@
    * Restart is no longer required to toggle desktop notifications
    * Display the savegame version when warning the user about unsupported or
      mismatched versions (bug #7243)
+   * Implemented feature for set goto on a own unit. (see easyCoding adding AI function)
    * Implemented feature request for difficulty changing during campaigns.
      (see bug #10978)
    * The saved games cache file is now save_index instead of save_index.gz, and
