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
*
*/
# ifndef _OBJECT_H
# define _OBJECT_H
# include "pstypes.h"
# include "vecmat.h"
2013-03-24 20:32:01 +00:00
# if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
# include "aistruct.h"
2013-03-24 20:32:01 +00:00
# endif
# 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
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-25 23:47:30 +00:00
# include <vector>
2013-12-26 03:10:16 +00:00
# include <stdexcept>
2012-11-11 22:12:51 +00:00
2013-12-26 04:18:28 +00:00
struct segment ;
2006-03-20 17:12:09 +00:00
/*
* CONSTANTS
*/
# define MAX_OBJECTS 350 // increased on 01/24/95 for multiplayer. --MK; total number of objects in world
2009-02-17 11:34:16 +00:00
# define MAX_USED_OBJECTS (MAX_OBJECTS-20)
2006-03-20 17:12:09 +00:00
// Object types
2012-09-01 22:24:42 +00:00
enum object_type_t
{
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_FLARE = 10 , // a flare
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
// WARNING!! If you add a type here, add its name to Object_type_names
// in object.c
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
# define MAX_OBJECT_TYPES 15
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
# define MAX_OBJECT_TYPES 16
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
// Result types
# define RESULT_NOTHING 0 // Ignore this collision
# define RESULT_CHECK 1 // Check for this collision
// Control types - what tells this object what do do
# define CT_NONE 0 // doesn't move (or change movement)
# define CT_AI 1 // driven by AI
# define CT_EXPLOSION 2 // explosion sequencer
# define CT_FLYING 4 // the player is flying
# define CT_SLEW 5 // slewing
# define CT_FLYTHROUGH 6 // the flythrough system
# define CT_WEAPON 9 // laser, etc.
# define CT_REPAIRCEN 10 // under the control of the repair center
# define CT_MORPH 11 // this object is being morphed
# define CT_DEBRIS 12 // this is a piece of debris
# define CT_POWERUP 13 // animating powerup blob
# define CT_LIGHT 14 // doesn't actually do anything
# define CT_REMOTE 15 // controlled by another net player
# define CT_CNTRLCEN 16 // the control center/main reactor
// Movement types
# define MT_NONE 0 // doesn't move
# define MT_PHYSICS 1 // moves by physics
# define MT_SPINNING 3 // this object doesn't move, just sits and spins
// Render types
# define RT_NONE 0 // does not render
# define RT_POLYOBJ 1 // a polygon model
# define RT_FIREBALL 2 // a fireball
# define RT_LASER 3 // a laser
# define RT_HOSTAGE 4 // a hostage
# define RT_POWERUP 5 // a powerup
# define RT_MORPH 6 // a robot being morphed
# define RT_WEAPON_VCLIP 7 // a weapon that renders as a vclip
// misc object flags
# define OF_EXPLODING 1 // this object is exploding
# define OF_SHOULD_BE_DEAD 2 // this object should be dead, so next time we can, we should delete this object.
# define OF_DESTROYED 4 // this has been killed, and is showing the dead version
# define OF_SILENT 8 // this makes no sound when it hits a wall. Added by MK for weapons, if you extend it to other types, do it completely!
# define OF_ATTACHED 16 // this object is a fireball attached to another object
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
# define OF_PLAYER_DROPPED 64 // this object was dropped by the player...
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
// Different Weapon ID types...
# define WEAPON_ID_LASER 0
# define WEAPON_ID_MISSLE 1
# define WEAPON_ID_CANNONBALL 2
// Object Initial shields...
# define OBJECT_INITIAL_SHIELDS F1_0 / 2
// physics flags
# define PF_TURNROLL 0x01 // roll when turning
# define PF_LEVELLING 0x02 // level object with closest side
# define PF_BOUNCE 0x04 // bounce (not slide) when hit will
# define PF_WIGGLE 0x08 // wiggle while flying
# define PF_STICK 0x10 // object sticks (stops moving) when hits wall
# define PF_PERSISTENT 0x20 // object keeps going even after it hits another object (eg, fusion cannon)
# define PF_USES_THRUST 0x40 // this object uses its thrust
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
# define PF_BOUNCED_ONCE 0x80 // Weapon has bounced once.
# define PF_FREE_SPINNING 0x100 // Drag does not apply to rotation of this object
# define PF_BOUNCES_TWICE 0x200 // This weapon bounces twice, then dies
2013-03-03 01:03:33 +00:00
# define PF_SPAT_BY_PLAYER 1 //this powerup was spat by the player
# endif
2006-03-20 17:12:09 +00:00
# define IMMORTAL_TIME 0x3fffffff // Time assigned to immortal objects, about 32768 seconds, or about 9 hours.
2013-12-26 22:21:16 +00:00
template < int16_t I >
struct object_magic_constant_t
{
operator int16_t ( ) const { return I ; }
} ;
static const object_magic_constant_t < - 2 > object_guidebot_cannot_reach = { } ;
static const object_magic_constant_t < - 1 > object_none = { } ;
static const object_magic_constant_t < 0 > object_first = { } ;
2006-03-20 17:12:09 +00:00
/*
* STRUCTURES
*/
2013-03-24 20:32:01 +00:00
# if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
2013-11-28 00:23:24 +00:00
extern const char Object_type_names [ MAX_OBJECT_TYPES ] [ 9 ] ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
# define MAX_CONTROLCEN_GUNS 4
# define MAX_RENDERED_WINDOWS 1
# elif defined(DXX_BUILD_DESCENT_II)
2013-03-23 19:09:44 +00:00
# define MAX_CONTROLCEN_GUNS 8
2013-03-03 01:03:33 +00:00
# define MAX_RENDERED_WINDOWS 3
# endif
2013-03-23 19:09:44 +00:00
struct reactor_static {
/* Location of the gun on the reactor object */
vms_vector gun_pos [ MAX_CONTROLCEN_GUNS ] ;
/* Orientation of the gun on the reactor object */
vms_vector gun_dir [ MAX_CONTROLCEN_GUNS ] ;
} ;
2013-03-24 20:32:01 +00:00
# endif
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
// This is specific to the shortpos extraction routines in gameseg.c.
# define RELPOS_PRECISION 10
# define MATRIX_PRECISION 9
# define MATRIX_MAX 0x7f // This is based on MATRIX_PRECISION, 9 => 0x7f
// information for physics sim for an object
2013-12-22 22:03:07 +00:00
struct physics_info
{
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
2013-12-22 22:03:07 +00:00
struct laser_info
{
2013-12-26 03:10:16 +00:00
struct hitobj_list_t
{
typedef unsigned objnum_t ;
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 ) ;
}
} ;
2006-03-20 17:12:09 +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...
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)
2010-12-22 09:41:25 +00:00
short last_hitobj ; // For persistent weapons (survive object collision), object it most recently hit.
2006-03-20 17:12:09 +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-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
2013-12-22 22:03:07 +00:00
struct 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
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
} ;
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
2013-12-22 22:03:07 +00:00
struct 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
2013-12-22 22:03:07 +00:00
struct powerup_info
{
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
2013-12-22 22:03:07 +00:00
} __pack__ ;
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
2013-12-22 22:03:07 +00:00
struct 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
2013-12-22 22:03:07 +00:00
struct polyobj_info
2013-12-22 23:11:35 +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
} ;
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 ;
struct object_rw ;
# if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
struct object {
2006-03-20 17:12:09 +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.
# ifdef WORDS_NEED_ALIGNMENT
short pad ;
# endif
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 {
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 ;
2006-03-20 17:12:09 +00:00
# ifdef WORDS_NEED_ALIGNMENT
short pad2 ;
# endif
2013-03-24 20:32:01 +00:00
} ;
2006-03-20 17:12:09 +00:00
2013-10-07 23:52:33 +00:00
static inline ubyte get_hostage_id ( const struct object * o )
{
return o - > id ;
}
static inline ubyte get_player_id ( const struct object * o )
{
return o - > id ;
}
static inline ubyte get_powerup_id ( const struct object * o )
{
return o - > id ;
}
static inline ubyte get_reactor_id ( const struct object * o )
{
return o - > id ;
}
static inline ubyte get_robot_id ( const struct object * o )
{
return o - > id ;
}
static inline enum weapon_type_t get_weapon_id ( const struct object * o )
{
return ( enum weapon_type_t ) o - > id ;
}
static inline void set_hostage_id ( struct object * o , ubyte id )
{
o - > id = id ;
}
static inline void set_player_id ( struct object * o , ubyte id )
{
o - > id = id ;
}
static inline void set_powerup_id ( struct object * o , ubyte id )
{
o - > id = id ;
}
static inline void set_robot_id ( struct object * o , ubyte id )
{
o - > id = id ;
}
static inline void set_weapon_id ( struct object * o , enum weapon_type_t id )
{
o - > id = id ;
}
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.
# ifdef WORDS_NEED_ALIGNMENT
short pad ;
# endif
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 ;
2010-12-22 00:17:59 +00:00
# ifdef WORDS_NEED_ALIGNMENT
short pad2 ;
# endif
2013-12-22 22:03:07 +00:00
} __pack__ ;
2013-03-24 20:32:01 +00:00
# endif
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
short segnum ; // segment number containing object
2013-12-22 22:03:07 +00:00
} ;
2006-03-20 17:12:09 +00:00
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
2013-12-22 22:03:07 +00:00
struct window_rendered_data
{
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2012-05-14 17:06:28 +00:00
fix64 time ;
2006-03-20 17:12:09 +00:00
object * viewer ;
int rear_view ;
2013-03-03 01:03:33 +00:00
# endif
2013-12-25 23:47:30 +00:00
std : : vector < short > rendered_robots ;
2013-12-22 22:03:07 +00:00
} ;
2006-03-20 17:12:09 +00:00
extern window_rendered_data Window_rendered_data [ MAX_RENDERED_WINDOWS ] ;
2013-03-24 20:32:01 +00:00
extern ubyte CollisionResult [ MAX_OBJECT_TYPES ] [ MAX_OBJECT_TYPES ] ;
// ie CollisionResult[a][b]== what happens to a when it collides with b
2013-12-24 02:11:27 +00:00
struct object_array_t : public array < object , MAX_OBJECTS > { } ;
extern object_array_t Objects ;
2013-12-12 21:48:34 +00:00
2013-12-24 04:53:59 +00:00
DEFINE_VALPTRIDX_SUBTYPE ( objptridx , object , int16_t , Objects ) ;
static inline objptridx_t operator - ( object * o , array < object , MAX_OBJECTS > & O )
2013-12-12 21:48:34 +00:00
{
2013-12-24 04:53:59 +00:00
return objptridx_t ( o , o - ( & * O . begin ( ) ) ) ;
2013-12-12 21:48:34 +00:00
}
2014-01-11 22:50:07 +00:00
objptridx_t operator - ( objptridx_t , array < object , MAX_OBJECTS > & ) DXX_CXX11_EXPLICIT_DELETE ;
2013-03-24 20:32:01 +00:00
# endif
2006-03-20 17:12:09 +00:00
/*
* VARIABLES
*/
extern int Object_next_signature ; // The next signature for the next newly created object
extern int Highest_object_index ; // highest objnum
2009-02-17 11:34:16 +00:00
extern int num_objects ;
2006-03-20 17:12:09 +00:00
extern int Num_robot_types ;
extern object * ConsoleObject ; // pointer to the object that is the player
extern object * Viewer ; // which object we are seeing from
extern object * Dead_player_camera ;
extern int Player_is_dead ; // !0 means player is dead!
extern int Player_exploded ;
2011-01-14 14:13:29 +00:00
extern int Player_eggs_dropped ;
2006-03-20 17:12:09 +00:00
extern int Death_sequence_aborted ;
2013-12-26 22:21:16 +00:00
extern short Player_fired_laser_this_frame ;
2012-11-11 00:14:30 +00:00
extern int Drop_afterburner_blob_flag ; //ugly hack
2006-03-20 17:12:09 +00:00
/*
* FUNCTIONS
*/
// do whatever setup needs to be done
void init_objects ( ) ;
// returns segment number object is in. Searches out from object's current
// seg, so this shouldn't be called if the object has "jumped" to a new seg
int obj_get_new_seg ( object * obj ) ;
// when an object has moved into a new segment, this function unlinks it
// from its old segment, and links it into the new segment
2013-12-24 04:53:59 +00:00
void obj_relink ( objptridx_t objnum , int newsegnum ) ;
2006-03-20 17:12:09 +00:00
2012-04-17 09:15:09 +00:00
// for getting out of messed up linking situations (i.e. caused by demo playback)
void obj_relink_all ( void ) ;
2006-03-20 17:12:09 +00:00
// move an object from one segment to another. unlinks & relinks
void obj_set_new_seg ( int objnum , int newsegnum ) ;
// links an object into a segment's list of objects.
// takes object number and segment number
2013-12-24 04:53:59 +00:00
void obj_link ( objptridx_t objnum , int segnum ) ;
2006-03-20 17:12:09 +00:00
// unlinks an object from a segment's list of objects
2013-12-24 04:53:59 +00:00
void obj_unlink ( objptridx_t objnum ) ;
2006-03-20 17:12:09 +00:00
// initialize a new object. adds to the list for the given segment
// returns the object number
2014-01-05 05:17:34 +00:00
objptridx_t obj_create ( enum object_type_t type , ubyte id , int segnum , const vms_vector * pos ,
2013-06-08 22:24:17 +00:00
const vms_matrix * orient , fix size ,
2006-03-20 17:12:09 +00:00
ubyte ctype , ubyte mtype , ubyte rtype ) ;
// make a copy of an object. returs num of new object
2014-01-12 19:14:16 +00:00
objptridx_t obj_create_copy ( int objnum , vms_vector * new_pos , int newsegnum ) ;
2006-03-20 17:12:09 +00:00
// remove object from the world
2014-01-11 17:14:20 +00:00
void obj_delete ( objptridx_t objnum ) ;
2006-03-20 17:12:09 +00:00
// called after load. Takes number of objects, and objects should be
// compressed
void reset_objects ( int n_objs ) ;
// make object array non-sparse
void compress_objects ( void ) ;
// Render an object. Calls one of several routines based on type
2014-01-11 23:06:33 +00:00
void render_object ( objptridx_t obj ) ;
2006-03-20 17:12:09 +00:00
// Draw a blob-type object, like a fireball
void draw_object_blob ( object * obj , bitmap_index bitmap ) ;
// draw an object that is a texture-mapped rod
void draw_object_tmap_rod ( object * obj , bitmap_index bitmap , int lighted ) ;
// Deletes all objects that have been marked for death.
void obj_delete_all_that_should_be_dead ( ) ;
// Toggles whether or not lock-boxes draw.
void object_toggle_lock_targets ( ) ;
// move all objects for the current frame
void object_move_all ( ) ; // moves all objects
// set viewer object to next object in array
void object_goto_next_viewer ( ) ;
// draw target boxes for nearby robots
void object_render_targets ( void ) ;
// move an object for the current frame
2014-01-11 17:14:20 +00:00
void object_move_one ( objptridx_t obj ) ;
2006-03-20 17:12:09 +00:00
// make object0 the player, setting all relevant fields
void init_player_object ( ) ;
// check if object is in object->segnum. if not, check the adjacent
// segs. if not any of these, returns false, else sets obj->segnum &
// returns true callers should really use find_vector_intersection()
// Note: this function is in gameseg.c
2013-12-24 04:53:59 +00:00
int update_object_seg ( objptridx_t obj ) ;
2006-03-20 17:12:09 +00:00
// Finds what segment *obj is in, returns segment number. If not in
// any segment, returns -1. Note: This function is defined in
// gameseg.h, but object.h depends on gameseg.h, and object.h is where
// object is defined...get it?
extern int find_object_seg ( object * obj ) ;
// go through all objects and make sure they have the correct segment
// numbers used when debugging is on
void fix_object_segs ( ) ;
// Drops objects contained in objp.
int object_create_egg ( object * objp ) ;
// Interface to object_create_egg, puts count objects of type type, id
// = id in objp and then drops them.
int call_object_create_egg ( object * objp , int count , int type , int id ) ;
extern void dead_player_end ( void ) ;
// Extract information from an object (objp->orient, objp->pos,
// objp->segnum), stuff in a shortpos structure. See typedef
// shortpos.
extern void create_shortpos ( shortpos * spp , object * objp , int swap_bytes ) ;
// Extract information from a shortpos, stuff in objp->orient
// (matrix), objp->pos, objp->segnum
2013-12-24 04:53:59 +00:00
void extract_shortpos ( objptridx_t objp , shortpos * spp , int swap_bytes ) ;
2006-03-20 17:12:09 +00:00
2012-05-21 15:06:50 +00:00
// create and extract quaternion structure from object data which greatly saves bytes by using quaternion instead or orientation matrix
void create_quaternionpos ( quaternionpos * qpp , object * objp , int swap_bytes ) ;
2013-12-24 04:53:59 +00:00
void extract_quaternionpos ( objptridx_t objp , quaternionpos * qpp , int swap_bytes ) ;
2012-05-21 15:06:50 +00:00
2006-03-20 17:12:09 +00:00
// delete objects, such as weapons & explosions, that shouldn't stay
// between levels if clear_all is set, clear even proximity bombs
void clear_transient_objects ( int clear_all ) ;
2010-01-28 15:26:27 +00:00
// Returns a new, unique signature for a new object
int obj_get_signature ( ) ;
2006-03-20 17:12:09 +00:00
// returns the number of a free object, updating Highest_object_index.
// Generally, obj_create() should be called to get an object, since it
// fills in important fields and does the linking. returns -1 if no
// free objects
2014-01-12 19:14:16 +00:00
objptridx_t obj_allocate ( ) ;
2006-03-20 17:12:09 +00:00
// frees up an object. Generally, obj_delete() should be called to
// get rid of an object. This function deallocates the object entry
// after the object has been unlinked
void obj_free ( int objnum ) ;
// after calling init_object(), the network code has grabbed specific
// object slots without allocating them. Go though the objects &
// build the free list, then set the apporpriate globals Don't call
// this function if you don't know what you're doing.
void special_reset_objects ( void ) ;
// attaches an object, such as a fireball, to another object, such as
// a robot
2013-12-24 04:53:59 +00:00
void obj_attach ( objptridx_t parent , objptridx_t sub ) ;
2006-03-20 17:12:09 +00:00
2014-01-11 17:14:20 +00:00
void create_small_fireball_on_object ( objptridx_t objp , fix size_scale , int sound_flag ) ;
2012-11-11 00:14:30 +00:00
void dead_player_frame ( void ) ;
2006-03-20 17:12:09 +00:00
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
// returns object number
int drop_marker_object ( vms_vector * pos , int segnum , vms_matrix * orient , int marker_num ) ;
2013-12-24 04:53:59 +00:00
extern void wake_up_rendered_objects ( objptridx_t gmissp , int window_num ) ;
2006-03-20 17:12:09 +00:00
2012-11-11 00:14:30 +00:00
void fuelcen_check_for_goal ( segment * ) ;
2013-03-03 01:03:33 +00:00
# endif
2012-11-11 00:14:30 +00:00
struct object * obj_find_first_of_type ( int ) ;
2006-03-20 17:12:09 +00:00
2013-03-24 20:32:01 +00:00
extern void object_rw_swap ( struct object_rw * obj_rw , int swap ) ;
2012-11-11 00:14:30 +00:00
void reset_player_object ( void ) ;
2009-10-05 02:51:37 +00:00
2012-11-11 22:12:51 +00:00
# endif
2006-03-20 17:12:09 +00:00
# endif