2006-03-20 17:12:09 +00:00
/*
2014-06-01 17:55:23 +00:00
* Portions of this file are copyright Rebirth contributors and licensed as
* described in COPYING . txt .
* Portions of this file are copyright Parallax Software and licensed
* according to the Parallax license below .
* See COPYING . txt for license details .
2006-03-20 17:12:09 +00:00
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ( " PARALLAX " ) . PARALLAX , IN DISTRIBUTING THE CODE TO
END - USERS , AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN , GRANTS A
ROYALTY - FREE , PERPETUAL LICENSE TO SUCH END - USERS FOR USE BY SUCH END - USERS
IN USING , DISPLAYING , AND CREATING DERIVATIVE WORKS THEREOF , SO LONG AS
SUCH USE , DISPLAY OR CREATION IS FOR NON - COMMERCIAL , ROYALTY OR REVENUE
FREE PURPOSES . IN NO EVENT SHALL THE END - USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE - BEARING PURPOSES . THE END - USER UNDERSTANDS
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE .
COPYRIGHT 1993 - 1999 PARALLAX SOFTWARE CORPORATION . ALL RIGHTS RESERVED .
*/
/*
*
* object system definitions
*
*/
2014-11-23 04:36:58 +00:00
# pragma once
2006-03-20 17:12:09 +00:00
2015-04-19 04:18:52 +00:00
# if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
# include "pstypes.h"
# include "vecmat.h"
# include "aistruct.h"
2013-03-24 20:32:01 +00:00
# include "polyobj.h"
2013-10-08 03:20:09 +00:00
# include "laser.h"
2006-03-20 17:12:09 +00:00
2012-11-11 22:12:51 +00:00
# ifdef __cplusplus
2014-07-20 01:09:55 +00:00
# include <cassert>
2013-12-26 22:21:16 +00:00
# include <cstdint>
2013-12-12 21:48:34 +00:00
# include "dxxsconf.h"
2013-12-21 05:12:38 +00:00
# include "compiler-array.h"
2013-12-24 04:53:59 +00:00
# include "valptridx.h"
2013-12-29 04:28:07 +00:00
# include "objnum.h"
# include "segnum.h"
2013-12-25 23:47:30 +00:00
# include <vector>
2013-12-26 03:10:16 +00:00
# include <stdexcept>
2014-07-05 22:21:47 +00:00
# include "compiler-type_traits.h"
2014-11-23 04:36:58 +00:00
# include "fwdobject.h"
2006-03-20 17:12:09 +00:00
// Object types
2014-11-23 04:36:58 +00:00
enum object_type_t : int
2012-09-01 22:24:42 +00:00
{
OBJ_NONE = 255 , // unused object
OBJ_WALL = 0 , // A wall... not really an object, but used for collisions
OBJ_FIREBALL = 1 , // a fireball, part of an explosion
OBJ_ROBOT = 2 , // an evil enemy
OBJ_HOSTAGE = 3 , // a hostage you need to rescue
OBJ_PLAYER = 4 , // the player on the console
OBJ_WEAPON = 5 , // a laser, missile, etc
OBJ_CAMERA = 6 , // a camera to slew around with
OBJ_POWERUP = 7 , // a powerup you can pick up
OBJ_DEBRIS = 8 , // a piece of robot
OBJ_CNTRLCEN = 9 , // the control center
OBJ_CLUTTER = 11 , // misc objects
OBJ_GHOST = 12 , // what the player turns into when dead
OBJ_LIGHT = 13 , // a light source, & not much else
OBJ_COOP = 14 , // a cooperative player object.
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2012-09-01 22:24:42 +00:00
OBJ_MARKER = 15 , // a map marker
2013-03-03 01:03:33 +00:00
# endif
2012-09-01 22:24:42 +00:00
} ;
2006-03-20 17:12:09 +00:00
/*
* STRUCTURES
*/
2013-03-23 19:09:44 +00:00
struct reactor_static {
/* Location of the gun on the reactor object */
2015-04-02 02:36:52 +00:00
array < vms_vector , MAX_CONTROLCEN_GUNS > gun_pos ,
2013-03-23 19:09:44 +00:00
/* Orientation of the gun on the reactor object */
2015-04-02 02:36:52 +00:00
gun_dir ;
2013-03-23 19:09:44 +00:00
} ;
2007-12-29 14:18:49 +00:00
// A compressed form for sending crucial data
2013-12-22 22:03:07 +00:00
struct shortpos
{
2006-03-20 17:12:09 +00:00
sbyte bytemat [ 9 ] ;
short xo , yo , zo ;
short segment ;
short velx , vely , velz ;
2013-12-22 22:03:07 +00:00
} __pack__ ;
2006-03-20 17:12:09 +00:00
2012-05-21 15:06:50 +00:00
// Another compressed form for object position, velocity, orientation and rotvel using quaternion
2013-12-22 22:03:07 +00:00
struct quaternionpos
{
2012-05-21 15:06:50 +00:00
vms_quaternion orient ;
vms_vector pos ;
2013-12-09 13:00:23 +00:00
short segment ;
2012-05-21 15:06:50 +00:00
vms_vector vel ;
vms_vector rotvel ;
2013-12-22 22:03:07 +00:00
} __pack__ ;
2012-05-21 15:06:50 +00:00
2006-03-20 17:12:09 +00:00
// information for physics sim for an object
2014-11-23 04:36:58 +00:00
struct physics_info : prohibit_void_ptr < physics_info >
2013-12-22 22:03:07 +00:00
{
2006-03-20 17:12:09 +00:00
vms_vector velocity ; // velocity vector of this object
vms_vector thrust ; // constant force applied to this object
fix mass ; // the mass of this object
fix drag ; // how fast this slows down
vms_vector rotvel ; // rotational velecity (angles)
vms_vector rotthrust ; // rotational acceleration
fixang turnroll ; // rotation caused by turn banking
ushort flags ; // misc physics flags
2013-12-22 23:11:35 +00:00
} ;
struct physics_info_rw
{
vms_vector velocity ; // velocity vector of this object
vms_vector thrust ; // constant force applied to this object
fix mass ; // the mass of this object
fix drag ; // how fast this slows down
fix obsolete_brakes ; // how much brakes applied
vms_vector rotvel ; // rotational velecity (angles)
vms_vector rotthrust ; // rotational acceleration
fixang turnroll ; // rotation caused by turn banking
ushort flags ; // misc physics flags
2013-12-22 22:03:07 +00:00
} __pack__ ;
2006-03-20 17:12:09 +00:00
// stuctures for different kinds of simulation
2015-04-19 04:18:52 +00:00
struct laser_parent
{
short parent_type ; // The type of the parent of this object
objnum_t parent_num ; // The object's parent's number
object_signature_t parent_signature ; // The object's parent's signature...
} ;
struct laser_info : prohibit_void_ptr < laser_info > , laser_parent
2013-12-22 22:03:07 +00:00
{
2014-06-21 23:55:24 +00:00
struct hitobj_list_t : public prohibit_void_ptr < hitobj_list_t >
2013-12-26 03:10:16 +00:00
{
template < typename T >
struct tproxy
{
T * addr ;
uint8_t mask ;
tproxy ( T * a , uint8_t m ) :
addr ( a ) , mask ( m )
{
assert ( m ) ;
assert ( ! ( m & ( m - 1 ) ) ) ;
}
dxx_explicit_operator_bool operator bool ( ) const
{
return * addr & mask ;
}
} ;
typedef tproxy < const uint8_t > cproxy ;
struct proxy : public tproxy < uint8_t >
{
proxy ( uint8_t * a , uint8_t m ) :
tproxy < uint8_t > ( a , m )
{
}
proxy & operator = ( bool b )
{
if ( b )
* addr | = mask ;
else
* addr & = ~ mask ;
return * this ;
}
template < typename T >
void operator = ( T ) DXX_CXX11_EXPLICIT_DELETE ;
} ;
array < uint8_t , ( MAX_OBJECTS + 7 ) / 8 > mask ;
proxy operator [ ] ( objnum_t i )
{
return make_proxy < proxy > ( mask , i ) ;
}
cproxy operator [ ] ( objnum_t i ) const
{
return make_proxy < cproxy > ( mask , i ) ;
}
void clear ( )
{
mask . fill ( 0 ) ;
}
template < typename T1 , typename T2 >
static T1 make_proxy ( T2 & mask , objnum_t i )
{
typename T2 : : size_type index = i / 8 , bitshift = i % 8 ;
if ( ! ( index < mask . size ( ) ) )
throw std : : out_of_range ( " index exceeds object range " ) ;
return T1 ( & mask [ index ] , 1 < < bitshift ) ;
}
} ;
2010-12-22 00:17:59 +00:00
fix64 creation_time ; // Absolute time of creation.
2013-12-26 03:10:16 +00:00
hitobj_list_t hitobj_list ; // list of all objects persistent weapon has already damaged (useful in case it's in contact with two objects at the same time)
2013-12-29 04:28:07 +00:00
objnum_t last_hitobj ; // For persistent weapons (survive object collision), object it most recently hit.
objnum_t track_goal ; // Object this object is tracking.
2006-03-20 17:12:09 +00:00
fix multiplier ; // Power if this is a fusion bolt (or other super weapon to be added).
2013-08-07 22:29:56 +00:00
fix track_turn_time ;
2013-08-24 22:09:58 +00:00
# if defined(DXX_BUILD_DESCENT_II)
fix64 last_afterburner_time ; // Time at which this object last created afterburner blobs.
# endif
2014-01-11 21:51:29 +00:00
} ;
2006-03-20 17:12:09 +00:00
2010-12-22 00:17:59 +00:00
// Same as above but structure Savegames/Multiplayer objects expect
2013-12-22 22:03:07 +00:00
struct laser_info_rw
{
2010-12-22 00:17:59 +00:00
short parent_type ; // The type of the parent of this object
short parent_num ; // The object's parent's number
int parent_signature ; // The object's parent's signature...
fix creation_time ; // Absolute time of creation.
2010-12-22 09:41:25 +00:00
short last_hitobj ; // For persistent weapons (survive object collision), object it most recently hit.
2010-12-22 00:17:59 +00:00
short track_goal ; // Object this object is tracking.
fix multiplier ; // Power if this is a fusion bolt (or other super weapon to be added).
2013-12-22 22:03:07 +00:00
} __pack__ ;
2010-12-22 00:17:59 +00:00
2014-11-23 04:36:58 +00:00
struct explosion_info : prohibit_void_ptr < explosion_info >
2013-12-22 23:11:35 +00:00
{
fix spawn_time ; // when lifeleft is < this, spawn another
fix delete_time ; // when to delete object
2013-12-29 04:28:07 +00:00
objnum_t delete_objnum ; // and what object to delete
objnum_t attach_parent ; // explosion is attached to this object
objnum_t prev_attach ; // previous explosion in attach list
objnum_t next_attach ; // next explosion in attach list
2013-12-22 23:11:35 +00:00
} ;
struct explosion_info_rw
2013-12-22 22:03:07 +00:00
{
2006-03-20 17:12:09 +00:00
fix spawn_time ; // when lifeleft is < this, spawn another
fix delete_time ; // when to delete object
short delete_objnum ; // and what object to delete
short attach_parent ; // explosion is attached to this object
short prev_attach ; // previous explosion in attach list
short next_attach ; // next explosion in attach list
2013-12-22 22:03:07 +00:00
} __pack__ ;
2006-03-20 17:12:09 +00:00
2014-11-23 04:36:58 +00:00
struct light_info : prohibit_void_ptr < light_info >
2013-12-22 23:11:35 +00:00
{
fix intensity ; // how bright the light is
} ;
struct light_info_rw
2013-12-22 22:03:07 +00:00
{
2006-03-20 17:12:09 +00:00
fix intensity ; // how bright the light is
2013-12-22 22:03:07 +00:00
} __pack__ ;
2006-03-20 17:12:09 +00:00
2014-11-23 04:36:58 +00:00
struct powerup_info : prohibit_void_ptr < powerup_info >
2013-12-22 22:03:07 +00:00
{
2006-03-20 17:12:09 +00:00
int count ; // how many/much we pick up (vulcan cannon only?)
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
int flags ; // spat by player?
2013-12-12 23:12:55 +00:00
fix64 creation_time ; // Absolute time of creation.
2013-03-03 01:03:33 +00:00
# endif
2014-06-21 23:55:24 +00:00
} ;
2006-03-20 17:12:09 +00:00
2013-12-22 22:03:07 +00:00
struct powerup_info_rw
{
2010-12-22 00:17:59 +00:00
int count ; // how many/much we pick up (vulcan cannon only?)
2013-12-22 22:03:07 +00:00
# if defined(DXX_BUILD_DESCENT_II)
// Same as above but structure Savegames/Multiplayer objects expect
2010-12-22 00:17:59 +00:00
fix creation_time ; // Absolute time of creation.
int flags ; // spat by player?
2013-03-03 01:03:33 +00:00
# endif
2013-12-22 22:03:07 +00:00
} __pack__ ;
2010-12-22 00:17:59 +00:00
2014-11-23 04:36:58 +00:00
struct vclip_info : prohibit_void_ptr < vclip_info >
2013-12-22 23:11:35 +00:00
{
int vclip_num ;
fix frametime ;
sbyte framenum ;
} ;
struct vclip_info_rw
2013-12-22 22:03:07 +00:00
{
2006-03-20 17:12:09 +00:00
int vclip_num ;
fix frametime ;
sbyte framenum ;
2013-12-22 22:03:07 +00:00
} __pack__ ;
2006-03-20 17:12:09 +00:00
// structures for different kinds of rendering
2014-11-23 04:36:58 +00:00
struct polyobj_info : prohibit_void_ptr < polyobj_info >
2013-12-22 23:11:35 +00:00
{
int model_num ; // which polygon model
2015-02-14 22:48:28 +00:00
array < vms_angvec , MAX_SUBMODELS > anim_angles ; // angles for each subobject
2013-12-22 23:11:35 +00:00
int subobj_flags ; // specify which subobjs to draw
int tmap_override ; // if this is not -1, map all face to this
int alt_textures ; // if not -1, use these textures instead
} ;
struct polyobj_info_rw
2013-12-22 22:03:07 +00:00
{
2006-03-20 17:12:09 +00:00
int model_num ; // which polygon model
vms_angvec anim_angles [ MAX_SUBMODELS ] ; // angles for each subobject
int subobj_flags ; // specify which subobjs to draw
int tmap_override ; // if this is not -1, map all face to this
int alt_textures ; // if not -1, use these textures instead
2013-12-22 22:03:07 +00:00
} __pack__ ;
2006-03-20 17:12:09 +00:00
2013-03-24 20:32:01 +00:00
struct object {
2015-03-22 18:49:21 +00:00
object_signature_t signature ;
2006-03-20 17:12:09 +00:00
ubyte type ; // what type of object this is... robot, weapon, hostage, powerup, fireball
ubyte id ; // which form of object...which powerup, robot, etc.
2013-12-29 04:28:07 +00:00
objnum_t next , prev ; // id of next and previous connected object in Objects, -1 = no connection
2006-03-20 17:12:09 +00:00
ubyte control_type ; // how this object is controlled
ubyte movement_type ; // how this object moves
ubyte render_type ; // how this object renders
ubyte flags ; // misc flags
2013-12-29 04:28:07 +00:00
segnum_t segnum ; // segment number containing object
objnum_t attached_obj ; // number of attached fireball object
2006-03-20 17:12:09 +00:00
vms_vector pos ; // absolute x,y,z coordinate of center of object
vms_matrix orient ; // orientation of object in world
fix size ; // 3d size of object - for collision detection
fix shields ; // Starts at maximum, when <0, object dies..
vms_vector last_pos ; // where object was last frame
sbyte contains_type ; // Type of object this object contains (eg, spider contains powerup)
sbyte contains_id ; // ID of object this object contains (eg, id = blue type = key)
sbyte contains_count ; // number of objects of type:id this object contains
sbyte matcen_creator ; // Materialization center that created this object, high bit set if matcen-created
fix lifeleft ; // how long until goes away, or 7fff if immortal
// -- Removed, MK, 10/16/95, using lifeleft instead: int lightlevel;
// movement info, determined by MOVEMENT_TYPE
union {
physics_info phys_info ; // a physics object
vms_vector spin_rate ; // for spinning objects
2013-12-22 23:11:35 +00:00
} mtype ;
2006-03-20 17:12:09 +00:00
2013-12-26 02:53:14 +00:00
// render info, determined by RENDER_TYPE
union {
struct polyobj_info pobj_info ; // polygon model
struct vclip_info vclip_info ; // vclip
} rtype ;
2006-03-20 17:12:09 +00:00
// control info, determined by CONTROL_TYPE
union {
2012-11-02 17:13:04 +00:00
struct laser_info laser_info ;
struct explosion_info expl_info ; // NOTE: debris uses this also
struct light_info light_info ; // why put this here? Didn't know what else to do with it.
struct powerup_info powerup_info ;
2013-03-24 20:32:01 +00:00
struct ai_static ai_info ;
2013-03-23 19:09:44 +00:00
struct reactor_static reactor_info ;
2013-12-22 23:11:35 +00:00
} ctype ;
2013-03-24 20:32:01 +00:00
} ;
2006-03-20 17:12:09 +00:00
2010-12-22 00:17:59 +00:00
// Same as above but structure Savegames/Multiplayer objects expect
2013-12-22 22:03:07 +00:00
struct object_rw
{
2010-12-22 00:17:59 +00:00
int signature ; // Every object ever has a unique signature...
ubyte type ; // what type of object this is... robot, weapon, hostage, powerup, fireball
ubyte id ; // which form of object...which powerup, robot, etc.
short next , prev ; // id of next and previous connected object in Objects, -1 = no connection
ubyte control_type ; // how this object is controlled
ubyte movement_type ; // how this object moves
ubyte render_type ; // how this object renders
ubyte flags ; // misc flags
short segnum ; // segment number containing object
short attached_obj ; // number of attached fireball object
vms_vector pos ; // absolute x,y,z coordinate of center of object
vms_matrix orient ; // orientation of object in world
fix size ; // 3d size of object - for collision detection
fix shields ; // Starts at maximum, when <0, object dies..
vms_vector last_pos ; // where object was last frame
sbyte contains_type ; // Type of object this object contains (eg, spider contains powerup)
sbyte contains_id ; // ID of object this object contains (eg, id = blue type = key)
sbyte contains_count ; // number of objects of type:id this object contains
sbyte matcen_creator ; // Materialization center that created this object, high bit set if matcen-created
fix lifeleft ; // how long until goes away, or 7fff if immortal
// -- Removed, MK, 10/16/95, using lifeleft instead: int lightlevel;
// movement info, determined by MOVEMENT_TYPE
union {
2013-12-22 23:11:35 +00:00
physics_info_rw phys_info ; // a physics object
2010-12-22 00:17:59 +00:00
vms_vector spin_rate ; // for spinning objects
} __pack__ mtype ;
// control info, determined by CONTROL_TYPE
union {
laser_info_rw laser_info ;
2013-12-22 23:11:35 +00:00
explosion_info_rw expl_info ; // NOTE: debris uses this also
2010-12-22 00:17:59 +00:00
ai_static_rw ai_info ;
2013-12-22 23:11:35 +00:00
light_info_rw light_info ; // why put this here? Didn't know what else to do with it.
2010-12-22 00:17:59 +00:00
powerup_info_rw powerup_info ;
} __pack__ ctype ;
// render info, determined by RENDER_TYPE
union {
2013-12-22 23:11:35 +00:00
polyobj_info_rw pobj_info ; // polygon model
vclip_info_rw vclip_info ; // vclip
2012-04-17 09:15:09 +00:00
} __pack__ rtype ;
2013-12-22 22:03:07 +00:00
} __pack__ ;
2010-12-22 00:17:59 +00:00
2013-12-22 22:03:07 +00:00
struct obj_position
{
2006-03-20 17:12:09 +00:00
vms_vector pos ; // absolute x,y,z coordinate of center of object
vms_matrix orient ; // orientation of object in world
2013-12-29 04:28:07 +00:00
segnum_t segnum ; // segment number containing object
2013-12-22 22:03:07 +00:00
} ;
2006-03-20 17:12:09 +00:00
2014-11-23 04:36:58 +00:00
struct object_array_t : array < object , MAX_OBJECTS >
2014-07-05 22:21:47 +00:00
{
2014-07-06 00:55:03 +00:00
int highest ;
# define Highest_object_index Objects.highest
2014-07-05 22:21:47 +00:00
typedef array < object , MAX_OBJECTS > array_t ;
template < typename T >
typename tt : : enable_if < tt : : is_integral < T > : : value , reference > : : type operator [ ] ( T n )
{
return array_t : : operator [ ] ( n ) ;
}
2014-07-11 03:14:50 +00:00
template < typename T >
typename tt : : enable_if < tt : : is_integral < T > : : value , const_reference > : : type operator [ ] ( T n ) const
{
return array_t : : operator [ ] ( n ) ;
}
2014-07-05 22:21:47 +00:00
template < typename T >
typename tt : : enable_if < ! tt : : is_integral < T > : : value , reference > : : type operator [ ] ( T ) const DXX_CXX11_EXPLICIT_DELETE ;
2015-01-28 03:42:52 +00:00
object_array_t ( ) ;
2014-07-11 03:14:50 +00:00
object_array_t ( const object_array_t & ) = delete ;
object_array_t & operator = ( const object_array_t & ) = delete ;
2014-07-05 22:21:47 +00:00
} ;
2013-12-12 21:48:34 +00:00
2014-10-02 03:02:34 +00:00
DEFINE_VALPTRIDX_SUBTYPE ( obj , object , objnum_t , Objects ) ;
2014-10-05 19:47:30 +00:00
2014-10-02 03:02:34 +00:00
static inline ubyte get_hostage_id ( const vcobjptr_t o )
2014-10-05 19:47:30 +00:00
{
return o - > id ;
}
2014-10-02 03:02:34 +00:00
static inline ubyte get_player_id ( const vcobjptr_t o )
2014-10-05 19:47:30 +00:00
{
return o - > id ;
}
2014-10-02 03:02:34 +00:00
static inline ubyte get_powerup_id ( const vcobjptr_t o )
2014-10-05 19:47:30 +00:00
{
return o - > id ;
}
2014-10-02 03:02:34 +00:00
static inline ubyte get_reactor_id ( const vcobjptr_t o )
2014-10-05 19:47:30 +00:00
{
return o - > id ;
}
2014-10-02 03:02:34 +00:00
static inline ubyte get_robot_id ( const vcobjptr_t o )
2014-10-05 19:47:30 +00:00
{
return o - > id ;
}
2014-10-02 03:02:34 +00:00
static inline weapon_type_t get_weapon_id ( const vcobjptr_t o )
2014-10-05 19:47:30 +00:00
{
return static_cast < weapon_type_t > ( o - > id ) ;
}
2014-10-02 03:02:34 +00:00
static inline void set_hostage_id ( const vobjptr_t o , ubyte id )
2014-10-05 19:47:30 +00:00
{
o - > id = id ;
}
2014-10-02 03:02:34 +00:00
static inline void set_player_id ( const vobjptr_t o , ubyte id )
2014-10-05 19:47:30 +00:00
{
o - > id = id ;
}
2015-03-28 17:18:02 +00:00
void set_powerup_id ( vobjptr_t o , uint8_t id ) ;
2014-10-05 19:47:30 +00:00
2014-10-02 03:02:34 +00:00
static inline void set_robot_id ( const vobjptr_t o , ubyte id )
2014-10-05 19:47:30 +00:00
{
o - > id = id ;
}
2014-10-02 03:02:34 +00:00
static inline void set_weapon_id ( const vobjptr_t o , weapon_type_t id )
2014-10-05 19:47:30 +00:00
{
o - > id = id ;
}
2013-03-24 20:32:01 +00:00
# endif
2006-03-20 17:12:09 +00:00
# endif