1 /* 2 * Copyright (C) Volition, Inc. 1999. All rights reserved. 3 * 4 * All source code herein is the property of Volition, Inc. You may not sell 5 * or otherwise commercially exploit the source or things you created based on the 6 * source. 7 * 8 */ 9 10 11 12 #ifndef _OBJECT_H 13 #define _OBJECT_H 14 15 #include "globalincs/pstypes.h" 16 #include "globalincs/globals.h" 17 #include "math/vecmat.h" 18 #include "physics/physics.h" 19 20 /* 21 * CONSTANTS 22 */ 23 24 #define DEFAULT_SHIELD_SECTIONS 4 // Number of sections in standard shields. 25 26 #ifndef NDEBUG 27 #define OBJECT_CHECK 28 #endif 29 30 //Object types 31 #define OBJ_NONE 0 //unused object 32 #define OBJ_SHIP 1 //a ship 33 #define OBJ_WEAPON 2 //a laser, missile, etc 34 #define OBJ_FIREBALL 3 //an explosion 35 #define OBJ_START 4 //a starting point marker (player start, etc) 36 #define OBJ_WAYPOINT 5 //a waypoint object, maybe only ever used by Fred 37 #define OBJ_DEBRIS 6 //a flying piece of ship debris 38 //#define OBJ_CMEASURE 7 //a countermeasure, such as chaff 39 #define OBJ_GHOST 8 //so far, just a placeholder for when a player dies. 40 #define OBJ_POINT 9 //generic object type to display a point in Fred. 41 #define OBJ_SHOCKWAVE 10 // a shockwave 42 #define OBJ_WING 11 // not really a type used anywhere, but I need it for Fred. 43 #define OBJ_OBSERVER 12 // used for multiplayer observers (possibly single player later) 44 #define OBJ_ASTEROID 13 // An asteroid, you know, a big rock, like debris, sort of. 45 #define OBJ_JUMP_NODE 14 // A jump node object, used only in Fred. 46 #define OBJ_BEAM 15 // beam weapons. we have to roll them into the object system to get the benefits of the collision pairs 47 48 //Make sure to change Object_type_names in Object.c when adding another type! 49 #define MAX_OBJECT_TYPES 16 50 51 #define UNUSED_OBJNUM (-MAX_OBJECTS*2) // Newer systems use this instead of -1 for invalid object. 52 53 extern char *Object_type_names[MAX_OBJECT_TYPES]; 54 55 // each object type should have these functions: (I will use weapon as example) 56 // 57 // int weapon_create( weapon specific parameters ) 58 // { 59 // ... 60 // objnum = obj_create(); 61 // ... Do some check to correctly handle obj_create returning which 62 // means that that object couldn't be created 63 // ... Initialize the weapon-specific info in Objects[objnum] 64 // return objnum; 65 // } 66 // 67 // void weapon_delete( object * obj ) 68 // { 69 // {Put a call to this in OBJECT.C, function obj_delete_all_that_should_be_dead } 70 // WARNING: To kill an object, set it's OF_SHOULD_BE_DEAD flag. Then, 71 // this function will get called when it's time to clean up the data. 72 // Assert( obj->flags & OF_SHOULD_BE_DEAD ); 73 // ... 74 // ... Free up all weapon-specfic data 75 // obj_delete(objnum); 76 // } 77 // 78 // void weapon_move( object * obj ) 79 // { 80 // {Put a call to this in ??? } 81 // ... Do whatever needs to be done each frame. Usually this amounts 82 // to setting the thrust, seeing if we've died, etc. 83 // } 84 // 85 // int weapon_check_collision( object * obj, object * other_obj, vec3d * hitpos ) 86 // { 87 // this should check if a vector from 88 // other_obj->last_pos to other_obj->pos with a radius of other_obj->radius 89 // collides with object obj. If it does, then fill in hitpos with the point 90 // of impact and return non-zero, otherwise return 0 if no impact. Note that 91 // this shouldn't take any action... that happens in weapon_hit. 92 // } 93 94 // 95 // void weapon_hit( object * obj, object * other_obj, vec3d * hitpos ) 96 // { 97 // {Put a call to this in COLLIDE.C} 98 // ... Do what needs to be done when this object gets hit 99 // ... Reducing shields, etc 100 // } 101 102 //Misc object flags 103 #define OF_RENDERS (1<<0) // It renders as something ( objtype_render gets called) 104 #define OF_COLLIDES (1<<1) // It collides with stuff (objtype_check_impact & objtype_hit gets called) 105 #define OF_PHYSICS (1<<2) // It moves with standard physics. 106 #define OF_SHOULD_BE_DEAD (1<<3) // this object should be dead, so next time we can, we should delete this object. 107 #define OF_INVULNERABLE (1<<4) // invulnerable 108 #define OF_PROTECTED (1<<5) // Don't kill this object, probably mission-critical. 109 #define OF_PLAYER_SHIP (1<<6) // this object under control of some player -- don't do ai stuff on it!!! 110 #define OF_NO_SHIELDS (1<<7) // object has no shield generator system (i.e. no shields) 111 #define OF_JUST_UPDATED (1<<8) // for multiplayer -- indicates that we received object update this frame 112 #define OF_COULD_BE_PLAYER (1<<9) // for multiplayer -- indicates that it is selectable ingame joiners as their ship 113 #define OF_WAS_RENDERED (1<<10) // Set if this object was rendered this frame. Only gets set if OF_RENDERS set. Gets cleared or set in obj_render_all(). 114 #define OF_NOT_IN_COLL (1<<11) // object has not been added to collision list 115 #define OF_BEAM_PROTECTED (1<<12) // don't fire beam weapons at this type of object, probably mission critical. 116 #define OF_SPECIAL_WARPIN (1<<13) // Object has special warp-in enabled. 117 #define OF_DOCKED_ALREADY_HANDLED (1<<14) // Goober5000 - a docked object that we already moved 118 #define OF_TARGETABLE_AS_BOMB (1<<15) 119 #define OF_FLAK_PROTECTED (1<<16) // Goober5000 - protected from flak turrets 120 #define OF_LASER_PROTECTED (1<<17) // Goober5000 - protected from laser turrets 121 #define OF_MISSILE_PROTECTED (1<<18) // Goober5000 - protected from missile turrets 122 #define OF_IMMOBILE (1<<19) // Goober5000 - doesn't move, no matter what 123 124 // Flags used by Fred 125 #define OF_MARKED (1<<29) // Object is marked (Fred). Can be reused in FreeSpace for anything that won't be used by Fred. 126 #define OF_TEMP_MARKED (1<<30) // Temporarily marked (Fred). 127 #define OF_HIDDEN (1<<31) // Object is hidden (not shown) and can't be manipulated 128 129 typedef struct obj_flag_name { 130 int flag; 131 char flag_name[TOKEN_LENGTH]; 132 int flag_list; 133 } obj_flag_name; 134 135 #define MAX_OBJECT_FLAG_NAMES 9 136 extern obj_flag_name Object_flag_names[]; 137 138 struct dock_instance; 139 140 class object 141 { 142 public: 143 class object *next, *prev; // for linked lists of objects 144 int signature; // Every object ever has a unique signature... 145 char type; // what type of object this is... robot, weapon, hostage, powerup, fireball 146 int parent; // This object's parent. 147 int parent_sig; // This object's parent's signature 148 char parent_type; // This object's parent's type 149 int instance; // which instance. ie.. if type is Robot, then this indexes into the Robots array 150 uint flags; // misc flags. Call obj_set_flags to change this. 151 vec3d pos; // absolute x,y,z coordinate of center of object 152 matrix orient; // orientation of object in world 153 float radius; // 3d size of object - for collision detection 154 vec3d last_pos; // where object was last frame 155 matrix last_orient; // how the object was oriented last frame 156 physics_info phys_info; // a physics object 157 int n_quadrants; // how many shield quadrants the ship has 158 SCP_vector<float> shield_quadrant; // Shield is broken into components, quadrants by default. 159 float hull_strength; // Remaining hull strength. 160 float sim_hull_strength; // Simulated hull strength - used with training weapons. 161 SCP_vector<int> objsnd_num; // Index of persistant sound struct. 162 ushort net_signature; 163 int num_pairs; // How many object pairs this is associated with. When 0 then there are no more. 164 165 dock_instance *dock_list; // Goober5000 - objects this object is docked to 166 dock_instance *dead_dock_list; // Goober5000 - objects this object was docked to when destroyed; replaces dock_objnum_when_dead 167 168 int collision_group_id; // This is a bitfield. Collision checks will be skipped if A->collision_group_id & B->collision_group_id returns nonzero 169 170 object(); 171 ~object(); 172 void clear(); 173 }; 174 175 struct object_h { 176 object *objp; 177 int sig; 178 IsValidobject_h179 bool IsValid(){return (this != NULL && objp != NULL && objp->signature == sig);} object_hobject_h180 object_h(object *in){objp=in; if(objp!=NULL){sig=in->signature;}} object_hobject_h181 object_h(){objp=NULL;sig=-1;} 182 }; 183 184 // object backup struct used by Fred. 185 typedef struct object_orient_pos { 186 vec3d pos; 187 matrix orient; 188 } object_orient_pos; 189 190 #ifdef OBJECT_CHECK 191 typedef struct checkobject 192 { 193 int type; 194 int signature; 195 uint flags; 196 int parent_sig; 197 int parent_type; 198 } checkobject; 199 #endif 200 201 /* 202 * VARIABLES 203 */ 204 205 extern int Object_inited; 206 extern int Show_waypoints; 207 208 // The next signature for the next newly created object. Zero is bogus 209 extern int Object_next_signature; 210 extern int Num_objects; 211 212 extern object Objects[]; 213 extern int Highest_object_index; //highest objnum 214 extern int Highest_ever_object_index; 215 extern object obj_free_list; 216 extern object obj_used_list; 217 extern object obj_create_list; 218 219 extern int render_total; 220 extern int render_order[MAX_OBJECTS]; 221 222 extern object *Viewer_obj; // Which object is the viewer. Can be NULL. 223 extern object *Player_obj; // Which object is the player. Has to be valid. 224 225 // Use this instead of "objp - Objects" to get an object number 226 // given it's pointer. This way, we can replace it with a macro 227 // to check that the pointer is valid for debugging. 228 #define OBJ_INDEX(objp) (objp-Objects) 229 230 /* 231 * FUNCTIONS 232 */ 233 234 //do whatever setup needs to be done 235 void obj_init(); 236 237 //initialize a new object. adds to the list for the given segment. 238 //returns the object number. The object will be a non-rendering, non-physics 239 //object. Returns 0 if failed, otherwise object index. 240 //You can pass 0 for parent if you don't care about that. 241 //You can pass null for orient and/or pos if you don't care. 242 int obj_create(ubyte type,int parent_obj, int instance, matrix * orient, vec3d * pos, float radius, uint flags ); 243 244 //Render an object. Calls one of several routines based on type 245 void obj_render(object *obj); 246 247 //Sorts and renders all the ojbects 248 void obj_render_all(void (*render_function)(object *objp), bool* render_viewer_last ); 249 250 //move all objects for the current frame 251 void obj_move_all(float frametime); // moves all objects 252 253 //move an object for the current frame 254 void obj_move_one(object * obj, float frametime); 255 256 // function to delete an object -- should probably only be called directly from editor code 257 void obj_delete(int objnum); 258 259 // should only be used by the editor! 260 void obj_merge_created_list(void); 261 262 // recalculate object pairs for an object 263 #define OBJ_RECALC_PAIRS(obj_to_reset) do { obj_set_flags(obj_to_reset, obj_to_reset->flags & ~(OF_COLLIDES)); obj_set_flags(obj_to_reset, obj_to_reset->flags | OF_COLLIDES); } while(0); 264 265 // Removes any occurances of object 'a' from the pairs list. 266 void obj_remove_pairs( object * a ); 267 268 // add an object to the pairs list 269 void obj_add_pairs(int objnum); 270 271 // Returns true if objects A and B are expected to collide in next duration seconds. 272 // For purposes of this check, the first object moves from current location to predicted 273 // location. The second object is assumed to be where it will be at time duration, NOT 274 // where it currently is. 275 // radius_scale: 0.0f means use polygon models, else scale sphere size by radius_scale 276 // radius_scale == 1.0f means Descent style collisions. 277 int objects_will_collide(object *A, object *B, float duration, float radius_scale); 278 279 // Used for pausing. Seems hacked. Was in PHYSICS, but that broke the TestCode program, 280 // so I moved it into the object lib. -John 281 void obj_init_all_ships_physics(); 282 283 // Goober5000 284 float get_hull_pct(object *objp); 285 float get_sim_hull_pct(object *objp); 286 float get_shield_pct(object *objp); 287 float get_max_shield_quad(object *objp); 288 289 // returns the average 3-space position of all ships. useful to find "center" of battle (sort of) 290 void obj_get_average_ship_pos(vec3d *pos); 291 292 // function to deal with firing player things like lasers, missiles, etc. 293 // separated out because of multiplayer issues. 294 void obj_player_fire_stuff( object *objp, control_info ci ); 295 296 // Call this if you want to change an object flag so that the 297 // object code knows what's going on. For instance if you turn 298 // off OF_COLLIDES, the object code needs to know this in order to 299 // actually turn the object collision detection off. By calling 300 // this you shouldn't get Int3's in the checkobject code. If you 301 // do, then put code in here to correctly handle the case. 302 void obj_set_flags(object *obj, uint new_flags); 303 304 // get the Ship_info flags for a given ship (if you have the object) 305 int obj_get_SIF(object *objp); 306 int obj_get_SIF(int obj); 307 308 // get the team for any object 309 int obj_team(object *objp); 310 311 void obj_move_all_pre(object *objp, float frametime); 312 void obj_move_all_post(object *objp, float frametime); 313 314 void obj_move_call_physics(object *objp, float frametime); 315 316 // multiplayer object update stuff begins ------------------------------------------- 317 318 // do client-side pre-interpolation object movement 319 void obj_client_pre_interpolate(); 320 321 // do client-side post-interpolation object movement 322 void obj_client_post_interpolate(); 323 324 // move an observer object in multiplayer 325 void obj_observer_move(float frame_time); 326 327 // Goober5000 328 int object_is_docked(object *objp); 329 int object_is_dead_docked(object *objp); 330 void obj_move_one_docked_object(object *objp, object *parent_objp); 331 332 //WMC 333 void object_set_gliding(object *objp, bool enable=true, bool force = false); 334 bool object_get_gliding(object *objp); 335 bool object_glide_forced(object* objp); 336 int obj_get_by_signature(int sig); 337 int object_get_model(object *objp); 338 339 #endif 340