1 #pragma once
2 
3 //********************************************************************************************
4 //*
5 //*    This file is part of Egoboo.
6 //*
7 //*    Egoboo is free software: you can redistribute it and/or modify it
8 //*    under the terms of the GNU General Public License as published by
9 //*    the Free Software Foundation, either version 3 of the License, or
10 //*    (at your option) any later version.
11 //*
12 //*    Egoboo is distributed in the hope that it will be useful, but
13 //*    WITHOUT ANY WARRANTY; without even the implied warranty of
14 //*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //*    General Public License for more details.
16 //*
17 //*    You should have received a copy of the GNU General Public License
18 //*    along with Egoboo.  If not, see <http://www.gnu.org/licenses/>.
19 //*
20 //********************************************************************************************
21 
22 #include "egoboo_object.h"
23 
24 #include "pip_file.h"
25 #include "graphic_prt.h"
26 #include "physics.h"
27 #include "bsp.h"
28 
29 //--------------------------------------------------------------------------------------------
30 //--------------------------------------------------------------------------------------------
31 
32 struct s_mesh_wall_data;
33 
34 //--------------------------------------------------------------------------------------------
35 //--------------------------------------------------------------------------------------------
36 // Particles
37 
38 #define MAXPARTICLEIMAGE                256         ///< Number of particle images ( frames )
39 
40 #define SPAWNNOCHARACTER                255         ///< For particles that spawn characters...
41 
42 #define STOPBOUNCINGPART                5.0f         ///< To make particles stop bouncing
43 
44 DECLARE_STACK_EXTERN( pip_t, PipStack, MAX_PIP );
45 
46 #define VALID_PIP_RANGE( IPIP ) ( ((IPIP) >= 0) && ((IPIP) < MAX_PIP) )
47 #define LOADED_PIP( IPIP )       ( VALID_PIP_RANGE( IPIP ) && PipStack.lst[IPIP].loaded )
48 
49 //--------------------------------------------------------------------------------------------
50 
51 /// Everything that is necessary to compute the character's interaction with the environment
52 struct s_prt_environment
53 {
54     // floor stuff
55     Uint8  twist;
56     float  floor_level;           ///< Height of tile
57     float  level;                 ///< Height of a tile or a platform
58     float  zlerp;
59 
60     float adj_level;              ///< The level for the particle to sit on the floor or a platform
61     float adj_floor;              ///< The level for the particle to sit on the floor or a platform
62 
63     // friction stuff
64     bool_t is_slipping;
65     bool_t is_slippy,    is_watery;
66     float  air_friction, ice_friction;
67     float  fluid_friction_hrz, fluid_friction_vrt;
68     float  friction_hrz;
69     float  traction;
70 
71     // misc states
72     bool_t   inwater;
73     fvec3_t  acc;
74 };
75 typedef struct s_prt_environment prt_environment_t;
76 
77 //--------------------------------------------------------------------------------------------
78 struct s_prt_spawn_data
79 {
80     fvec3_t  pos;
81     FACING_T facing;
82     PRO_REF  iprofile;
83     PIP_REF  ipip;
84 
85     CHR_REF  chr_attach;
86     Uint16   vrt_offset;
87     TEAM_REF team;
88 
89     CHR_REF  chr_origin;
90     PRT_REF  prt_origin;
91     int      multispawn;
92     CHR_REF  oldtarget;
93 };
94 
95 typedef struct s_prt_spawn_data prt_spawn_data_t;
96 
97 //--------------------------------------------------------------------------------------------
98 // Particle variables
99 //--------------------------------------------------------------------------------------------
100 
101 /// The definition of the particle object
102 /// This "inherits" for obj_data_t
103 struct s_prt
104 {
105     obj_data_t obj_base;              ///< the "inheritance" from obj_data_t
106     bool_t     is_ghost;              ///< the particla has been killed, but is hanging around a while...
107 
108     prt_spawn_data_t  spawn_data;
109 
110     // profiles
111     PIP_REF pip_ref;                         ///< The part template
112     PRO_REF profile_ref;                     ///< the profile related to the spawned particle
113 
114     // links
115     CHR_REF attachedto_ref;                  ///< For torch flame
116     CHR_REF owner_ref;                       ///< The character that is attacking
117     CHR_REF target_ref;                      ///< Who it's chasing
118     PRT_REF parent_ref;                      ///< Did a another particle spawn this one?
119     Uint32  parent_guid;                     ///< Just in case, the parent particle was despawned and a differnt particle now has the parent_ref
120 
121     Uint16   attachedto_vrt_off;              ///< It's vertex offset
122     Uint8    type;                            ///< Transparency mode, 0-2
123     FACING_T facing;                          ///< Direction of the part
124     TEAM_REF team;                            ///< Team
125 
126     fvec3_t pos, pos_old, pos_stt;           ///< Position
127     fvec3_t vel, vel_old, vel_stt;           ///< Velocity
128     fvec3_t offset;                          ///< The initial offset when spawning the particle
129 
130     Uint32  onwhichgrid;                      ///< Where the part is
131     Uint32  onwhichblock;                    ///< The particle's collision block
132     bool_t  is_hidden;                       ///< Is the particle related to a hidden character?
133 
134     // platforms
135     float   targetplatform_level;             ///< What is the height of the target platform?
136     CHR_REF targetplatform_ref;               ///< Am I trying to attach to a platform?
137     CHR_REF onwhichplatform_ref;              ///< Is the particle on a platform?
138     Uint32  onwhichplatform_update;           ///< When was the last platform attachment made?
139 
140     FACING_T rotate;                          ///< Rotation direction
141     Sint16   rotate_add;                      ///< Rotation rate
142 
143     UFP8_T  size_stt;                        ///< The initial size of particle (8.8-bit fixed point)
144     UFP8_T  size;                            ///< Size of particle (8.8-bit fixed point)
145     SFP8_T  size_add;                        ///< Change in size
146 
147     //bool_t  inview;                          ///< Render this one? (same as inst.indolist)
148     UFP8_T  image;                           ///< Which image (8.8-bit fixed point)
149     Uint16  image_add;                       ///< Animation rate
150     Uint16  image_max;                       ///< End of image loop
151     Uint16  image_stt;                       ///< Start of image loop
152 
153     bool_t  is_eternal;                      ///< Does the particle ever time-out?
154     size_t  lifetime;                        ///< Total particle lifetime in updates
155     size_t  lifetime_remaining;              ///< How many updates does the particle have left?
156     size_t  frames_remaining;                ///< How many frames does the particle have left?
157     int     contspawn_timer;                 ///< Time until spawn
158 
159     Uint32            bump_size_stt;         ///< the starting size of the particle (8.8-bit fixed point)
160     bumper_t          bump_real;             ///< Actual size of the particle
161     bumper_t          bump_padded;           ///< The size of the particle with the additional bumpers added in
162     oct_bb_t          prt_min_cv;            ///< Collision volume for chr-prt interactions
163     oct_bb_t          prt_max_cv;            ///< Collision volume for chr-prt interactions
164 
165     IPair             damage;                ///< For strength
166     Uint8             damagetype;            ///< Damage type
167     Uint16            lifedrain;
168     Uint16            manadrain;
169 
170     bool_t            is_bumpspawn;          ///< this particle is like a flame, burning something
171     bool_t            inwater;
172 
173     int               spawncharacterstate;   ///< if != SPAWNNOCHARACTER, then a character is spawned on end
174 
175     bool_t            is_homing;                 ///< Is the particle in control of its motion?
176 
177     // some data that needs to be copied from the particle profile
178     Uint8             endspawn_amount;        ///< The number of particles to be spawned at the end
179     Uint16            endspawn_facingadd;     ///< The angular spacing for the end spawn
180     int               endspawn_lpip;          ///< The actual local pip that will be spawned at the end
181 
182     dynalight_info_t  dynalight;              ///< Dynamic lighting...
183     prt_instance_t    inst;                   ///< Everything needed for rendering
184     prt_environment_t enviro;                 ///< the particle's environment
185     phys_data_t       phys;                   ///< the particle's physics data
186 
187     bool_t         safe_valid;                ///< is the last "safe" position valid?
188     fvec3_t        safe_pos;                  ///< the last "safe" position
189     Uint32         safe_time;                 ///< the last "safe" time
190     Uint32         safe_grid;                 ///< the last "safe" grid
191 
192     float          buoyancy;                  ///< an estimate of the particle bouyancy in air
193     float          air_resistance;            ///< an estimate of the particle's extra resistance to air motion
194 
195     BSP_leaf_t        bsp_leaf;
196 };
197 typedef struct s_prt prt_t;
198 
199 // counters for debugging wall collisions
200 extern int prt_stoppedby_tests;
201 extern int prt_pressure_tests;
202 
203 //--------------------------------------------------------------------------------------------
204 struct s_prt_bundle
205 {
206     PRT_REF   prt_ref;
207     prt_t   * prt_ptr;
208 
209     PIP_REF   pip_ref;
210     pip_t   * pip_ptr;
211 };
212 typedef struct s_prt_bundle prt_bundle_t;
213 
214 //--------------------------------------------------------------------------------------------
215 // function prototypes
216 
217 void particle_system_begin();
218 void particle_system_end();
219 
220 prt_t * prt_ctor( prt_t * pprt );
221 prt_t * prt_dtor( prt_t * pprt );
222 
223 void   init_all_pip();
224 void   release_all_pip();
225 bool_t release_one_pip( const PIP_REF ipip );
226 
227 const PRT_REF end_one_particle_now( const PRT_REF particle );
228 const PRT_REF end_one_particle_in_game( const PRT_REF particle );
229 
230 void update_all_particles( void );
231 void move_all_particles( void );
232 void cleanup_all_particles( void );
233 void bump_all_particles_update_counters( void );
234 
235 void play_particle_sound( const PRT_REF particle, Sint8 sound );
236 
237 PRT_REF spawn_one_particle( fvec3_t pos, FACING_T facing, const PRO_REF iprofile, int pip_index,
238                             const CHR_REF chr_attach, Uint16 vrt_offset, const TEAM_REF team,
239                             const CHR_REF chr_origin, const PRT_REF prt_origin, int multispawn, const CHR_REF oldtarget );
240 
241 #define spawn_one_particle_global( pos, facing, gpip_index, multispawn ) spawn_one_particle( pos, facing, (PRO_REF)MAX_PROFILE, gpip_index, (CHR_REF)MAX_CHR, GRIP_LAST, (TEAM_REF)TEAM_NULL, (CHR_REF)MAX_CHR, (PRT_REF)MAX_PRT, multispawn, (CHR_REF)MAX_CHR );
242 
243 int     prt_count_free();
244 
245 PIP_REF load_one_particle_profile_vfs( const char *szLoadName, const PIP_REF pip_override );
246 void    reset_particles();
247 
248 BIT_FIELD prt_hit_wall( prt_t * pprt, const float test_pos[], float nrm[], float * pressure, struct s_mesh_wall_data * pdata );
249 BIT_FIELD prt_test_wall( prt_t * pprt, const float test_pos[], struct s_mesh_wall_data * pdata );
250 
251 bool_t prt_is_over_water( const PRT_REF particle );
252 
253 bool_t release_one_pip( const PIP_REF ipip );
254 
255 bool_t prt_request_terminate( const PRT_REF iprt );
256 
257 void prt_set_level( prt_t * pprt, float level );
258 
259 prt_t * prt_run_config( prt_t * pprt );
260 prt_t * prt_config_construct( prt_t * pprt, int max_iterations );
261 prt_t * prt_config_initialize( prt_t * pprt, int max_iterations );
262 prt_t * prt_config_activate( prt_t * pprt, int max_iterations );
263 prt_t * prt_config_deinitialize( prt_t * pprt, int max_iterations );
264 prt_t * prt_config_deconstruct( prt_t * pprt, int max_iterations );
265 
266 bool_t prt_set_pos( prt_t * pprt, fvec3_base_t pos );
267 
268 prt_bundle_t * move_one_particle_get_environment( prt_bundle_t * pbdl_prt );
269