|
ORTS
|
00001 #ifndef PRATERRAIN_H 00002 #define PRATERRAIN_H 00003 00004 // $Id: PRATerrain.H 5279 2007-06-23 02:49:08Z mburo $ 00005 00006 // This is an ORTS file 00007 // (c) Michael Buro, Sami Wagiaalla, David Deutscher 00008 // licensed under the GPL 00009 // Most (if not all) of the code is taken from SimpleTerrain. 00010 // 00011 00012 #include "TerrainBasicImp.H" 00013 #include "TerrainBase.H" 00014 #include <boost/shared_ptr.hpp> 00015 #include "Random.H" 00016 #include "Global.H" 00017 00018 00019 //----------------------------------------------------------------------------- 00020 //----------------------------------------------------------------------------- 00021 00022 // fixme: Transfer this functionality into ST_Task, this is a heritage from before 00023 // the TerrainBase interface. 00024 00025 // struct UnitPath 00026 // { 00027 // const Object *obj; 00028 // Vector<TerrainBase::Loc> path; 00029 // TerrainBase::Loc goal; 00030 // int current_target; // index of current way point in path vector 00031 // bool no_orders_yet; // true 00032 // int collision_step; // this is incremented while solving unexpected stops 00033 // uint4 wakeup; // if SDL_GetTicks() >= wakeup then this UnitPath is not 00034 // // sleeping ie not to be skipped over. 00035 // TerrainBase::Loc spot; // spot of the last unexpected collision 00036 00037 // UnitPath(const Object *obj_, const Vector<TerrainBase::Loc> &path_); 00038 // ~UnitPath() {}; 00039 00040 // void mark_spot(const TerrainBase::Loc &p) { spot = p; }; 00041 // void sleep(int time) { wakeup = SDL_GetTicks() + time; }; 00042 // bool sleeping() const { return wakeup > SDL_GetTicks(); }; 00043 00044 // bool is_intersect(const TerrainBase::Segment &) const; 00045 // }; 00046 00047 00048 /// The internal data complementing Task data: 00049 struct PR_Task { 00050 TerrainBase::Task task; 00051 bool isPending; 00052 bool isFailed; 00053 bool noPathFound; 00054 const Object *obj; 00055 Vector<TerrainBase::Loc> path; 00056 sint4 current_target; 00057 sint4 collision_step; 00058 TerrainBase::Loc motion_vector; 00059 00060 PR_Task(const TerrainBase::Task& task_); 00061 PR_Task(const PR_Task& other) 00062 : task(other.task), isPending(other.isPending), 00063 isFailed(other.isFailed), noPathFound(other.noPathFound), obj(other.obj), 00064 path(other.path), current_target(other.current_target), 00065 collision_step(other.collision_step), motion_vector(other.motion_vector) {}; 00066 void init_path(const Object *obj_, const Vector<TerrainBase::Loc> &path_); 00067 //~ST_Task() { delete path; }; 00068 bool isValid() const { return !isPending && !isFailed && !noPathFound && path.size()>0; }; 00069 private: 00070 PR_Task operator=(const PR_Task& other); 00071 }; 00072 00073 struct Vec_2D{ 00074 sint4 x; 00075 sint4 y; 00076 Vec_2D(sint4 x_, sint4 y_) : x(x_), y(y_){}; 00077 Vec_2D(const Vec_2D &other) : x(other.x), y(other.y){}; 00078 Vec_2D operator+(const Vec_2D &other) const; 00079 Vec_2D operator-(const Vec_2D &other) const; 00080 Vec_2D project_onto(const Vec_2D &other) const; 00081 sint4 dot_prod(const Vec_2D &other) const; 00082 real8 length() const; 00083 }; 00084 00085 00086 //----------------------------------------------------------------------------- 00087 //----------------------------------------------------------------------------- 00088 00089 <<<<<<< PRATerrain.H 00090 /// A Simple implementation of the TerrainBase interface. 00091 /** This TerrainBase implementation is using the PRAstar algorithm. 00092 Limitations: 00093 - Only considers a single Obj per Task (ignoring the second and on obj_ids). 00094 - Does not currently work for IN_AIR units 00095 */ 00096 class PR_Terrain : public TerrainBasicImp<PR_Task> { 00097 typedef TerrainBase::Loc Loc; 00098 typedef TerrainBase::Segment Segment; 00099 typedef TerrainBase::Task Task; 00100 public: 00101 PR_Terrain(){}; 00102 virtual ~PR_Terrain() {}; 00103 00104 /// add command-line options specific to this implementation, using static methods of class Options 00105 static void add_options(void); 00106 00107 //--------------------------------------------------------------------- 00108 /// \name Implementation of relevant parts of the TerrainBase interface 00109 //--------------------------------------------------------------------- 00110 //@{ 00111 virtual void init(sint4 tiles_x_, sint4 tiles_y_, sint4 tile_points_, sint4 me, sint4 neutral); 00112 00113 virtual void add_obj(const Object *obj); 00114 virtual void update_obj(const Object *obj); 00115 virtual void remove_obj(const Object *obj); 00116 virtual void add_segments(const Vector<TerrainBase::Segment> &s); 00117 00118 // virtual void add_task(const Task &task); 00119 virtual void cancel_task(const Object *obj); 00120 virtual void remove_task(TaskId tid); 00121 00122 virtual void execute_tasks(Vector<MoveCmd> &cmds, Vector<StatusMsg> &msgs); 00123 virtual bool plan_tasks(void); 00124 00125 virtual real8 find_path(const Loc &l1, const Loc &l2, sint4 radius, Path &path); 00126 //@} 00127 //--------------------------------------------------------------------- 00128 00129 protected: 00130 bool calculate_vector(const Object *obj, const TerrainBase::Loc &target, TerrainBase::Loc &output); 00131 //void find_obstacles(const Object *obj, Vector<const Object*> &output); 00132 void restrict_vector(const Vec_2D &target_vec, Vec_2D &vec); 00133 void normalize_vector(Loc &vec, const real8 &length); 00134 Loc get_point_repulsion(const Object *moving_obj, const Loc &loc, sint4 radius = 0); 00135 Loc get_line_repulsion(const Object *moving_obj, const Segment &seg); 00136 bool plan_pending_task(void); 00137 bool plan_failed_task(void); 00138 bool is_at_location(const Object *obj, const Loc &target); 00139 bool is_at_goal(const Object *obj, const TerrainBase::Task &task); 00140 bool is_near_waypoint(const Object *obj, const Loc &wp); 00141 bool is_in_range(const Object *moving_obj, const Object *goal_obj); 00142 void invalidate_paths(const Vector<Segment> &segments); 00143 00144 ======= 00145 /// A Simple implementation of the TerrainBase interface. 00146 /** This TerrainBase implementation is using the PRAstar algorithm. 00147 Limitations: 00148 - Only considers a single Obj per Task (ignoring the second and on obj_ids). 00149 - Does not currently work for IN_AIR units 00150 */ 00151 class PR_Terrain : public TerrainBasicImp<ST_Task> 00152 { 00153 public: 00154 PR_Terrain() {}; 00155 virtual ~PR_Terrain() {}; 00156 00157 /// add command-line options specific to this implementation, using static methods of class Options 00158 static void add_options(void); 00159 00160 //--------------------------------------------------------------------- 00161 /// \name Implementation of relevant parts of the TerrainBase interface 00162 //--------------------------------------------------------------------- 00163 //@{ 00164 virtual void init(sint4 tiles_x_, sint4 tiles_y_, sint4 tile_points_); 00165 00166 virtual void add_obj(const Object *obj); 00167 virtual void update_obj(const Object *obj); 00168 virtual void remove_obj(const Object *obj); 00169 virtual void add_segments(const Vector<TerrainBase::Segment> &s); 00170 00171 virtual void cancel_task(const Object *obj); 00172 virtual void remove_task(TaskId tid); 00173 00174 virtual void execute_tasks(Vector<MoveCmd> &cmds, Vector<StatusMsg> &msgs); 00175 virtual bool plan_tasks(sint4 max_time = 0); 00176 00177 virtual real8 find_path(const Loc &l1, const Loc &l2, sint4 radius, Path &path); 00178 //@} 00179 //--------------------------------------------------------------------- 00180 00181 00182 private: 00183 // prevent copying as we currently don't need it. 00184 PR_Terrain(const PR_Terrain& other); 00185 PR_Terrain operator=(const PR_Terrain& other); 00186 00187 /// The mechanics of world representation and PRA* path-finding 00188 class PRAEngine; friend class PR_Terrain::PRAEngine; 00189 00190 //--------------------------------------------------------------------- 00191 /// \name Internal accessories 00192 //--------------------------------------------------------------------- 00193 //@{ 00194 /** Perform PF for a single pending task, and insert results to data structures. 00195 Return true iff did some planning. */ 00196 bool plan_pending_task(void); 00197 /** Perform PF for a single failed task, and insert results to data structures. 00198 Return true iff did some planning. */ 00199 bool plan_failed_task(void); 00200 /// Invalidate existing paths that intersect a given new boundary. 00201 void invalidate_paths(const Vector<Segment> &segments); 00202 /** Test if the object is at the given location, 00203 accounting for a 1-tick look-ahead for moving objects. */ 00204 static bool is_at_location(const Object* obj, const Loc& target); 00205 /** Test if the object is at the goal of the given task, implementing 00206 (some) of the various definitions of 'goal'. */ 00207 static bool is_at_goal(const Object* obj, const Task& task); 00208 /** Test if the object is within firing range */ 00209 static bool is_in_range(const Object* moving_obj, const Object *goal_obj); 00210 >>>>>>> 1.3 00211 00212 void add_move_command(const Object *obj, const Loc &motion_vec, Vector<TerrainBase::MoveCmd> &cmds); 00213 00214 private: 00215 static sint4 round(real8 real); 00216 // prevent copying as we currently don't need it. 00217 PR_Terrain(const PR_Terrain& other); 00218 PR_Terrain operator=(const PR_Terrain& other); 00219 00220 /// The mechanics of world representation and PRA* path-finding 00221 class PRAEngine; friend class PR_Terrain::PRAEngine; 00222 00223 00224 //@} 00225 //--------------------------------------------------------------------- 00226 00227 boost::shared_ptr<PRAEngine> pfEngine; ///< The internal Path Finding engine 00228 std::set<const Object*> objsToStop; 00229 std::map<const Object*, Loc> objects; 00230 Vector<Segment> segments; 00231 static const sint4 FIELD_RANGE_MULTIPLIER = 3; 00232 static const sint4 ATTRACTOR_FORCE = 32; 00233 static const sint4 REPULSOR_BASELINE = 128; 00234 static const sint4 WAYPOINT_PROX = 2; 00235 00236 }; 00237 00238 00239 00240 #endif