File: object.h

package info (click to toggle)
freespace2 24.0.2%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: trixie
  • size: 43,188 kB
  • sloc: cpp: 583,107; ansic: 21,729; python: 1,174; sh: 464; makefile: 248; xml: 181
file content (390 lines) | stat: -rw-r--r-- 13,509 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
/*
 * Copyright (C) Volition, Inc. 1999.  All rights reserved.
 *
 * All source code herein is the property of Volition, Inc. You may not sell 
 * or otherwise commercially exploit the source or things you created based on the 
 * source.
 *
*/ 



#ifndef _OBJECT_H
#define _OBJECT_H

#include "globalincs/globals.h"
#include "globalincs/pstypes.h"
#include "math/vecmat.h"
#include "object/object.h"
#include "object/object_flags.h"
#include "physics/physics.h"
#include "utils/event.h"
#include "network/multi_interpolate.h"

#include <functional>

/*
 *		CONSTANTS
 */

#define DEFAULT_SHIELD_SECTIONS	4	//	Number of sections in standard shields.

#ifndef NDEBUG
#define OBJECT_CHECK 
#endif

//Object types
#define OBJ_NONE				0		//unused object
#define OBJ_SHIP				1		//a ship
#define OBJ_WEAPON			2		//a laser, missile, etc
#define OBJ_FIREBALL			3		//an explosion
#define OBJ_START				4		//a starting point marker (player start, etc)
#define OBJ_WAYPOINT			5		//a waypoint object, maybe only ever used by Fred
#define OBJ_DEBRIS			6		//a flying piece of ship debris
//#define OBJ_CMEASURE			7		//a countermeasure, such as chaff
#define OBJ_GHOST				8		//so far, just a placeholder for when a player dies.
#define OBJ_POINT				9		//generic object type to display a point in Fred.
#define OBJ_SHOCKWAVE		10		// a shockwave
#define OBJ_WING				11		// not really a type used anywhere, but I need it for Fred.
#define OBJ_OBSERVER       12    // used for multiplayer observers (possibly single player later)
#define OBJ_ASTEROID			13		//	An asteroid, you know, a big rock, like debris, sort of.
#define OBJ_JUMP_NODE		14		// A jump node object, used only in Fred.
#define OBJ_BEAM				15		// beam weapons. we have to roll them into the object system to get the benefits of the collision pairs

//Make sure to change Object_type_names in Object.c when adding another type!
#define MAX_OBJECT_TYPES	16

#define UNUSED_OBJNUM		(-MAX_OBJECTS*2)	//	Newer systems use this instead of -1 for invalid object.

extern const char	*Object_type_names[MAX_OBJECT_TYPES];

// each object type should have these functions:  (I will use weapon as example)
//
// int weapon_create( weapon specific parameters )
// {
//    ...
//		objnum = obj_create();
//		... Do some check to correctly handle obj_create returning  which
//        means that that object couldn't be created
//    ... Initialize the weapon-specific info in Objects[objnum]
//    return objnum;
// }
//
// void weapon_delete( object * obj )
// {
//    {Put a call to this in OBJECT.C, function obj_delete_all_that_should_be_dead }
//    WARNING: To kill an object, set it's OF_SHOULD_BE_DEAD flag.  Then,
//    this function will get called when it's time to clean up the data.
//    Assert( obj->flags[Object::Object_Flags::Should_be_dead] );
//    ...
//    ... Free up all weapon-specfic data
//    obj_delete(objnum);
// }
// 
// void weapon_move( object * obj )
// {
//    {Put a call to this in ??? }
//    ... Do whatever needs to be done each frame.  Usually this amounts
//        to setting the thrust, seeing if we've died, etc.
// }
//
// int weapon_check_collision( object * obj, object * other_obj, vec3d * hitpos )
// {
//    this should check if a vector from 
//		other_obj->last_pos to other_obj->pos with a radius of other_obj->radius
//    collides with object obj.   If it does, then fill in hitpos with the point
//    of impact and return non-zero, otherwise return 0 if no impact.   Note that
//    this shouldn't take any action... that happens in weapon_hit.
// }

// 
// void weapon_hit( object * obj, object * other_obj, vec3d * hitpos )
// {
//    {Put a call to this in COLLIDE.C}
//    ... Do what needs to be done when this object gets hit
//    ... Reducing shields, etc
// }

typedef struct obj_flag_name {
	Object::Object_Flags flag;
	char flag_name[TOKEN_LENGTH];
} obj_flag_name;

typedef struct obj_flag_description {
	Object::Object_Flags flag;
	SCP_string flag_desc;
} obj_flag_description;

extern obj_flag_name Object_flag_names[];
extern obj_flag_description Object_flag_descriptions[];
extern const int Num_object_flag_names;

struct dock_instance;
class model_draw_list;

class object
{
public:
	class object	*next, *prev;	// for linked lists of objects
	int				signature;		// Every object ever has a unique signature...
	char			type;			// what type of object this is... ship, weapon, debris, asteroid, fireball, see OBJ_* defines above
	int				parent;			// This object's parent.
	int				parent_sig;		// This object's parent's signature
	int				instance;		// index into the corresponding type array, i.e. if type == OBJ_SHIP then instance indexes the Ships array
	flagset<Object::Object_Flags> flags;			// misc flags.  Call obj_set_flags to change this.
	vec3d			pos;				// absolute x,y,z coordinate of center of object
	matrix			orient;			// orientation of object in world
	float			radius;			// 3d size of object - for collision detection
	vec3d			last_pos;		// where object was last frame
	matrix			last_orient;	// how the object was oriented last frame
	physics_info	phys_info;		// a physics object
	int				n_quadrants;	// how many shield quadrants the ship has
	SCP_vector<float>	shield_quadrant;	//	Shield is broken into components, quadrants by default.
	float			hull_strength;	//	Remaining hull strength.
	float			sim_hull_strength;	// Simulated hull strength - used with training weapons.
	SCP_vector<int> objsnd_num;		// Index of persistant sound struct.
	ushort			net_signature;
	int				num_pairs;		// How many object pairs this is associated with.  When 0 then there are no more.

	dock_instance	*dock_list;			// Goober5000 - objects this object is docked to
	dock_instance	*dead_dock_list;	// Goober5000 - objects this object was docked to when destroyed; replaces dock_objnum_when_dead

	int				collision_group_id; // This is a bitfield. Collision checks will be skipped if A->collision_group_id & B->collision_group_id returns nonzero

	util::event<void, object*> pre_move_event;
	util::event<void, object*> post_move_event;

	interpolation_manager interp_info;

	object();
	~object();
	void clear();

private:
	// An object should never be copied; there are allocated pointers, and linked list shenanigans.
	object(const object& other); // no implementation
	object& operator= (const object & other); // no implementation
};

struct lua_State;
namespace scripting {
	class ade_table_entry;
}
namespace luacpp {
	class LuaValue;
}

extern int Num_objects;
extern object Objects[];

struct object_h {
	object *objp;
	int sig;

	bool IsValid() const {return (objp != nullptr && objp->signature == sig && sig > 0); }
	object_h(object *in) {objp = in; sig = (in == nullptr) ? -1 : in->signature; }
	object_h() { objp = nullptr; sig = -1; }

	object_h(int objnum)
	{
		if (objnum >= 0 && objnum < MAX_OBJECTS)
		{
			objp = &Objects[objnum];
			sig = objp->signature;
		}
		else
		{
			objp = nullptr;
			sig = -1;
		}
	}

	static void serialize(lua_State* L, const scripting::ade_table_entry& tableEntry, const luacpp::LuaValue& value, ubyte* data, int& packet_size);
	static void deserialize(lua_State* L, const scripting::ade_table_entry& tableEntry, char* data_ptr, ubyte* data, int& offset);
};

// object backup struct used by Fred.
typedef struct object_orient_pos {
	vec3d pos;
	matrix orient;
} object_orient_pos;

#ifdef OBJECT_CHECK
class checkobject
{
public:
	int	type;
	int	signature;
	flagset<Object::Object_Flags>	flags;
	int	parent_sig;

    checkobject();
};
#endif

/*
 *		VARIABLES
 */

extern int Object_inited;
extern int Show_waypoints;

extern int Object_next_signature;		// The next signature for the next newly created object. Zero is bogus
extern int Highest_object_index;		//highest objnum
extern int Highest_ever_object_index;

extern object obj_free_list;
extern object obj_used_list;
extern object obj_create_list;

extern int render_total;
extern int render_order[MAX_OBJECTS];

extern object *Viewer_obj;	// Which object is the viewer. Can be NULL.
extern object *Player_obj;	// Which object is the player. Has to be valid.

// Use this instead of "objp - Objects" to get an object number
// given it's pointer.  This way, we can replace it with a macro
// to check that the pointer is valid for debugging.
// This code will break in 64 bit builds when we have more than 2^31 objects but that will probably never happen
#define OBJ_INDEX(objp) static_cast<int>(objp-Objects)

/*
 *		FUNCTIONS
 */

//do whatever setup needs to be done
void obj_init();

void obj_shutdown();

//initialize a new object.  adds to the list for the given segment.
//returns the object number.  The object will be a non-rendering, non-physics
//object.  Returns 0 if failed, otherwise object index.
//You can pass 0 for parent if you don't care about that.
//You can pass null for orient and/or pos if you don't care.
int obj_create(ubyte type, int parent_obj, int instance, const matrix *orient, const vec3d *pos, float radius, const flagset<Object::Object_Flags> &flags, bool essential = true);

void obj_render(object* obj);

void obj_queue_render(object* obj, model_draw_list* scene);

//Sorts and renders all the ojbects
void obj_render_all(const std::function<void(object*)>& render_function, bool* render_viewer_last );

//move all objects for the current frame
void obj_move_all(float frametime);		// moves all objects

// function to delete an object -- should probably only be called directly from editor code
void obj_delete(int objnum);

void obj_delete_all();

void obj_delete_all_that_should_be_dead();

// should only be used by the editor!
void obj_merge_created_list(void);

// recalculate object pairs for an object
#define OBJ_RECALC_PAIRS(obj_to_reset)		do {	obj_set_flags(obj_to_reset, obj_to_reset->flags - Object::Object_Flags::Collides); obj_set_flags(obj_to_reset, obj_to_reset->flags + Object::Object_Flags::Collides); } while(false);

//	Returns true if objects A and B are expected to collide in next duration seconds.
//	For purposes of this check, the first object moves from current location to predicted
//	location.  The second object is assumed to be where it will be at time duration, NOT
//	where it currently is.
//	radius_scale: 0.0f means use polygon models, else scale sphere size by radius_scale
//	radius_scale == 1.0f means Descent style collisions.
int objects_will_collide(object *A, object *B, float duration, float radius_scale);

// Used for pausing.  Seems hacked.  Was in PHYSICS, but that broke the TestCode program,
// so I moved it into the object lib.  -John
void obj_init_all_ships_physics();

// Goober5000
float get_hull_pct(object *objp);
float get_sim_hull_pct(object *objp);
float get_shield_pct(object *objp);

// returns the average 3-space position of all ships.  useful to find "center" of battle (sort of)
void obj_get_average_ship_pos(vec3d *pos);

// function to deal with firing player things like lasers, missiles, etc.
// separated out because of multiplayer issues.
void obj_player_fire_stuff( object *objp, control_info ci );

// Call this if you want to change an object flag so that the
// object code knows what's going on.  For instance if you turn
// off OF_COLLIDES, the object code needs to know this in order to
// actually turn the object collision detection off.  By calling
// this you shouldn't get Int3's in the checkobject code.  If you
// do, then put code in here to correctly handle the case.
void obj_set_flags(object *obj, const flagset<Object::Object_Flags>& new_flags);

// get the team for any object
int obj_team(object *objp);

void obj_move_all_pre(object *objp, float frametime);
void obj_move_all_post(object *objp, float frametime);

void obj_move_call_physics(object *objp, float frametime);

// multiplayer object update stuff begins -------------------------------------------

// move an observer object in multiplayer
void obj_observer_move(float frame_time);

/**
 * @brief Checks if the given object is docked with anyone.
 *
 * @returns Nonzero if docked, or
 * @returns 0 if not docked
 *
 * @author Goober5000
 */
int object_is_docked(object *objp);

/**
 * @brief Checks if the given object is dead-docked with anyone.
 *
 * @returns Nonzero if docked, or
 * @returns 0 if not docked
 *
 * @details An object is "dead-docked" when it is dying and still has objects docked to it. The dead_dock list is
 *   populated when the object dies, and is used later on to jettison and maybe damage the docked objects.
 *
 * @author Goober5000
 */
int object_is_dead_docked(object *objp);

/**
 * @brief Moves a docked object to keep up with the parent object as it moves
 *
 * @param[in,out] objp The docked object
 * @param[in]     parent_objp The object that it's docked to
 *
 * @author Goober5000
 */
void obj_move_one_docked_object(object *objp, object *parent_objp);

//WMC
void object_set_gliding(object *objp, bool enable=true, bool force = false);
bool object_get_gliding(object *objp);
bool object_glide_forced(object* objp);
int obj_get_by_signature(int sig);
int object_get_model(const object *objp);
int object_get_model_instance(const object *objp);

void obj_render_queue_all();

/**
 * @brief Compares two object pointers and determines if they refer to the same object
 *
 * @note Two @c nullptr parameters are considered equal
 *
 * @param left The first object pointer, may be @c nullptr
 * @param right The second object pointer, may be @c nullptr
 * @return @c true if the two pointers refer to the same object
 */
bool obj_compare(object *left, object *right);

#endif