|
ORTS
|
00001 #ifndef GameObj_H 00002 #define GameObj_H 00003 00004 /** @file GameObj.H 00005 The objects that populate the world. 00006 $Id: GameObj.H 6869 2008-04-07 05:32:39Z furtak $ 00007 $Source$ 00008 */ 00009 00010 // This is an ORTS file (c) Michael Buro, licensed under the GPL 00011 00012 #include "Global.H" 00013 #include "ScriptObj.H" 00014 #include "Object.H" 00015 #include "Action.H" 00016 00017 class GameObjBlueprint; 00018 class PlayerInfo; 00019 00020 //=================================================================== 00021 00022 /** Objects that interact with the world. */ 00023 00024 class GameObj : public ScriptObj, public Object { 00025 00026 public: 00027 class BasePtr; 00028 class WPtr; 00029 class Ptr; 00030 00031 ServerObjData sod; ///< Pointers to certain often-accessed variables. Avoids string lookup. 00032 00033 ServerMotionData smd; ///< Properties used for object motion/collision. 00034 Action cur_action; ///< The current action about to be taken and parameters. 00035 sint4 enable_count; ///< 1 - # of disabled parent objects. 00036 00037 uint4 dir_dmg; ///< Bit vector for whether damage was taken from each direction range. 00038 uint4 dir_dmg2; ///< Same as dir_dmg, but for damage from the air. 00039 Vector<uint4> dir_damage; ///< [GameConst::DAMAGE_N+1] Amount of damage received from each dir. 00040 uint2 dir_max_damage; ///< The direction (1...DAMAGE_N) that the most damage came from. 00041 00042 typedef std::map<std::string, SimpleActions::saction*> CommandMap; 00043 CommandMap last_command_map; ///< pending actions 00044 typedef Vector<SimpleActions::saction**> Command; 00045 Command last_command; ///< Points to the pointer in last_command_map. Includes component actions. 00046 00047 GameObj(GameObjBlueprint &bp, GameObj *parent = 0); 00048 GameObj(const GameObj &gob) : ScriptObj(gob), Object(gob) { ERR("foo"); } 00049 virtual ~GameObj(); 00050 00051 void update_sod(); 00052 void update_points() const; 00053 00054 // If enable_count <= 0 then the client can't send actions for the object. 00055 virtual void enable(); 00056 virtual void disable(); 00057 virtual sint4 get_refs() const; 00058 virtual bool is_enabled() { return enable_count > 0; } 00059 00060 void print(std::ostream &os = std::cout) const; 00061 void notify_attack(GameObj *targ, sint4 damage); 00062 00063 virtual std::string bp_name() const; 00064 virtual uint4 code() const; 00065 virtual void attr_names(Vector<std::string> &) const; 00066 virtual bool attr_changed(const std::string &a) const; 00067 00068 virtual stype get_val_prev(const std::string &a) const; 00069 virtual stype* get_val_ptr(const std::string &a); 00070 virtual const stype* get_val_ptr(const std::string &a) const; 00071 virtual void set_val(const std::string &a, stype v, bool warn=true); 00072 00073 virtual void gen_diff(bool first, bool allied, std::string &s, PlayerInfo *pi) const; 00074 virtual void gen_comp_diff(bool first, bool allied, std::string &s, PlayerInfo *pi) const; 00075 virtual bool apply_diff(ByteStream &s, PlayerInfo *pi); 00076 virtual bool apply_comp_diff(bool allied, ByteStream &s, bool first, PlayerInfo *pi); 00077 virtual void copy_to_prev(); 00078 virtual void reset_frame_data(); // reset_attr_vals 00079 00080 virtual void action_names(Vector<std::string> &names) const; 00081 00082 virtual void queue_action(sint4 frame_sent); // don't call in client user code 00083 virtual std::string write_action(ObjId my_id) const; 00084 00085 virtual ObjAction* action(const std::string &name) const; 00086 virtual ObjAction* action(sint4 id) const; 00087 virtual sint4 action_id(const std::string &name) const; 00088 virtual bool action_enabled(sint4 id) const; 00089 virtual bool action_enabled(const std::string &name) const; 00090 virtual bool action_hidden(sint4 id) const; 00091 virtual bool action_hidden(const std::string &name) const; 00092 00093 virtual void component_names(Vector<std::string> &names) const; 00094 virtual ScriptObj* component(const std::string &name) const; 00095 virtual ScriptObj* action_component(sint4 id) const { return action2component[id]; } 00096 00097 virtual void construct(); 00098 virtual void destruct(); 00099 00100 virtual GameObj* get_GameObj() { return this; } 00101 00102 friend class GameObjFactory; 00103 friend class ScriptParser; 00104 00105 00106 // Client data/functions 00107 00108 // 0 if error, client_action_id > 0 if OK 00109 virtual uint4 set_action(const std::string &name, const Vector<sint4> ¶ms, sint4 priority=1); 00110 virtual uint4 set_action(sint4 id, const Vector<sint4> ¶ms, sint4 priority=1); 00111 virtual uint4 set_action(const std::string &name, const Vector<stype> ¶ms, sint4 priority=1); 00112 virtual uint4 set_action(sint4 id, const Vector<stype> ¶ms, sint4 priority=1); 00113 00114 virtual bool action_already_set() const; 00115 virtual void clear_action(); 00116 00117 struct ActInfo 00118 { 00119 sint4 frame_sent; // view_frame action was sent to server 00120 GameObj *obj; // actor 00121 uint4 client_action_id; // for easy action identification in client 00122 uint4 error_code; // 0:OK, >0:ERROR, fixme: to be sent from server 00123 00124 ActInfo(sint4 frame_sent_=0, uint4 client_action_id_=0, GameObj *obj_=0, uint4 error_code_=0) 00125 : frame_sent(frame_sent_), 00126 obj(obj_), 00127 client_action_id(client_action_id_), 00128 error_code(error_code_) 00129 { } 00130 }; 00131 00132 // Pending actions 00133 // 00134 // Updated in GameStateModule (send_actions, recv_view). So, 00135 // technically shouldn't be here because Game doesn't do anything 00136 // with it. But: having it here avoids maintaining a gameobj->queue map. 00137 std::list<ActInfo> pending_actions; ///< Actions that have been sent to the server and are awaiting response. 00138 00139 // Object virtual functions 00140 00141 Object::Shape get_shape() const; 00142 sint4 get_max_speed() const; 00143 sint4 get_radius() const; 00144 Object::ZCat get_zcat(ZCat *prev) const; 00145 sint4 get_speed(sint4 *prev) const; 00146 bool get_moving(bool *prev) const ; 00147 void get_center(sint4 &x, sint4 &y, sint4 *px=0, sint4 *py=0) const; 00148 void get_p1(sint4 &x, sint4 &y, sint4 *px=0, sint4 *py=0) const; // upper left corner 00149 void get_p2(sint4 &x, sint4 &y, sint4 *px=0, sint4 *py=0) const; // lower right corner 00150 bool is_pending_action(void) const; 00151 real8 distance_to(const Object &other) const; 00152 00153 // Auxiliary "shortcut" methods 00154 const GameObjBlueprint* get_bp() const { 00155 return blueprint; 00156 } 00157 const stype* get_val_ptr(sint4 index) const { 00158 return &attr_vals[index]; 00159 } 00160 sint4 component_index(const std::string &name) const { 00161 FIND (name2comp, it, name); 00162 if (it != name2comp.end()) return it->second; 00163 return -1; 00164 } 00165 const ScriptObj* component(sint4 index) const { 00166 return components[index]; 00167 } 00168 00169 protected: 00170 00171 GameObj() { blueprint = 0; } 00172 00173 void init_sod(); 00174 void delete_sod(); 00175 00176 sint4 num_const, num_stable, num_variable; 00177 Vector<stype> attr_vals; 00178 Vector<stype> prev_attr_vals; 00179 GameObjBlueprint *blueprint; 00180 Vector<GameObj*> action2component; ///< The sub-object that each action belongs to. 00181 /// Pointers to enable_count for the component that owns each action (used by the root). 00182 00183 Vector<sint4*> action_enabled_list; 00184 typedef std::map<std::string, sint4> Name2CompInd; 00185 Name2CompInd name2comp; ///< Maps component name to component index. 00186 Vector<ScriptObj*> components; ///< Sub-objects. 00187 void inc_enable_count(); 00188 void dec_enable_count(); 00189 00190 // helpers 00191 00192 private: 00193 00194 static uint4 next_client_action_id(); 00195 }; 00196 00197 //------------------------------------------------------------------- 00198 00199 /** A 'weak' pointer. 00200 Not strong enough to prevent its target from being deleted. 00201 */ 00202 00203 class GameObj::WPtr : public ScriptObj::WPtr 00204 { 00205 public: 00206 inline GameObj* operator->() const { return (GameObj*)p; } 00207 inline GameObj& operator*() const { if (!p) { std::cout << "DANGER" << std::endl; } return *(GameObj*)p; } 00208 inline operator GameObj* () const { return (GameObj*)p; } 00209 00210 WPtr() {} 00211 WPtr(GameObj *s); 00212 WPtr(const WPtr &ptr); 00213 // ~WPtr() {} 00214 }; 00215 00216 //------------------------------------------------------------------- 00217 00218 /** A 'strong' pointer. 00219 The object is maintained as long as at least one strong pointer 00220 is referencing it. 00221 */ 00222 00223 class GameObj::Ptr : public ScriptObj::Ptr 00224 { 00225 public: 00226 inline GameObj* operator->() const { return (GameObj*)p; } 00227 inline GameObj& operator*() const { if (!p) { std::cout << "DANGER" << std::endl; } return *(GameObj*)p; } 00228 inline operator GameObj* () const { return (GameObj*)p; } 00229 00230 Ptr() {} 00231 Ptr(GameObj *g); 00232 Ptr(const Ptr &ptr); 00233 // ~Ptr() {} 00234 00235 inline operator GameObj::WPtr () const { return GameObj::WPtr((GameObj*)p); } 00236 }; 00237 00238 //=================================================================== 00239 00240 REGISTER_TYPEOF(56, std::set<GameObj*>::iterator); 00241 REGISTER_TYPEOF(57, std::set<GameObj*>::const_iterator); 00242 REGISTER_TYPEOF(58, Vector<GameObj*>::iterator); 00243 REGISTER_TYPEOF(59, Vector<GameObj*>::const_iterator); 00244 REGISTER_TYPEOF(60, GameObj::CommandMap::iterator); 00245 REGISTER_TYPEOF(61, GameObj::CommandMap::const_iterator); 00246 REGISTER_TYPEOF(108, std::list<GameObj::ActInfo>::iterator); 00247 REGISTER_TYPEOF(109, std::list<GameObj::ActInfo>::const_iterator); 00248 00249 //=================================================================== 00250 00251 #endif 00252