1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 2010 EDuke32 developers and contributors
4
5 This file is part of EDuke32.
6
7 EDuke32 is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License version 2
9 as published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
15 See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 //-------------------------------------------------------------------------
22
23 #ifndef actors_h_
24 #define actors_h_
25
26 #include "player.h"
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 #define MAXSLEEPDIST 16384
33 #define SLEEPTIME 1536
34 #define ACTOR_FLOOR_OFFSET (1<<8)
35 #define ZOFFSET2 (16<<8)
36 #define ZOFFSET3 (8<<8)
37 #define ZOFFSET4 (12<<8)
38 #define ZOFFSET5 (32<<8)
39 #define ZOFFSET6 (4<<8)
40
41 #define ACTOR_MAXFALLINGZVEL 6144
42 #define ACTOR_ONWATER_ADDZ (24<<8)
43
44 #define STAT_DEFAULT 0
45 #define STAT_ACTOR 1
46 #define STAT_ZOMBIEACTOR 2
47 #define STAT_EFFECTOR 3
48 #define STAT_PROJECTILE 4
49 #define STAT_MISC 5
50 #define STAT_STANDABLE 6
51 #define STAT_LOCATOR 7
52 #define STAT_ACTIVATOR 8
53 #define STAT_TRANSPORT 9
54 #define STAT_PLAYER 10
55 #define STAT_FX 11
56 #define STAT_FALLER 12
57 #define STAT_DUMMYPLAYER 13
58 #define STAT_LIGHT 14
59 #define STAT_NETALLOC (MAXSTATUS-1)
60
61
62 // Defines the motion characteristics of an actor
63 enum amoveflags_t
64 {
65 face_player = 1,
66 geth = 2,
67 getv = 4,
68 random_angle = 8,
69 face_player_slow = 16,
70 spin = 32,
71 face_player_smart = 64,
72 fleeenemy = 128,
73 jumptoplayer_only = 256,
74 jumptoplayer_bits = 257, // NOTE: two bits set!
75 seekplayer = 512,
76 furthestdir = 1024,
77 dodgebullet = 4096
78 };
79
80 // Defines for 'useractor' keyword
81 enum uactortypes_t
82 {
83 notenemy,
84 enemy,
85 enemystayput
86 };
87
88 // These macros are there to give names to the t_data[]/T*/vm.g_t[] indices
89 // when used with actors. Greppability of source code is certainly a virtue.
90 #define AC_COUNT(t) ((t)[0]) /* the actor's count */
91 /* The ID of the actor's current move. In C-CON, the bytecode offset to the
92 * move composite: */
93 #define AC_MOVE_ID(t) ((t)[1])
94 #define AC_ACTION_COUNT(t) ((t)[2]) /* the actor's action count */
95 #define AC_CURFRAME(t) ((t)[3]) /* the actor's current frame offset */
96 /* The ID of the actor's current action. In C-CON, the bytecode offset to the
97 * action composite: */
98 #define AC_ACTION_ID(t) ((t)[4])
99 #define AC_AI_ID(t) ((t)[5]) /* the ID of the actor's current ai */
100
101 enum actionparams
102 {
103 ACTION_STARTFRAME = 0,
104 ACTION_NUMFRAMES,
105 ACTION_VIEWTYPE,
106 ACTION_INCVAL,
107 ACTION_DELAY,
108 ACTION_FLAGS,
109 ACTION_PARAM_COUNT,
110 };
111
112 enum actionflags
113 {
114 AF_VIEWPOINT = 1u<<0u,
115 };
116
117 // <spr>: sprite pointer
118 // <a>: actor_t pointer
119 #define AC_ACTIONTICS(spr, a) ((spr)->lotag)
120 #define AC_MOVFLAGS(spr, a) ((spr)->hitag)
121
122 // (+ 40 16 16 4 8 6 8 6 4 20)
123 #pragma pack(push, 1)
124 typedef struct
125 {
126 int32_t t_data[10]; // 40b sometimes used to hold offsets to con code
127
128 uint32_t flags; // 4b
129 vec3_t bpos; // 12b
130 int32_t floorz, ceilingz; // 8b
131 vec2_t lastv; // 8b
132 int16_t picnum, ang; // 4b
133 int16_t extra, owner; // 4b
134 int16_t movflag, tempang; // 4b
135 int16_t timetosleep, stayput; // 4b
136 uint16_t florhit, lzsum; // 4b
137 int16_t dispicnum; // 2b NOTE: updated every frame, not in sync with game tics!
138 uint8_t cgg, lasttransport; // 2b
139 } actor_t;
140
141 EDUKE32_STATIC_ASSERT(sizeof(actor_t) == 96);
142
143 #ifdef POLYMER
144 typedef struct
145 {
146 _prlight *lightptr; // 4b/8b aligned on 96 bytes
147 int16_t lightId, lightmaxrange; // 4b
148 uint8_t lightcount, filler[3]; // 4b
149 } practor_t;
150 #endif
151
152 // note: fields in this struct DO NOT have to be in this order,
153 // however if you add something to this struct, please make sure
154 // a field gets added to ActorFields[], otherwise the field
155 // won't get synced over the network!
156 //
157 // I don't think the ActorFields array needs to be in the same order,
158 // need to verify this...
159 typedef struct netactor_s
160 {
161 // actor fields
162 //--------------------------------------------
163 int32_t
164 t_data_0,
165 t_data_1,
166 t_data_2,
167 t_data_3,
168 t_data_4,
169 t_data_5,
170 t_data_6,
171 t_data_7,
172 t_data_8,
173 t_data_9;
174
175 int32_t
176 flags;
177
178
179 int32_t
180 bpos_x,
181 bpos_y,
182 bpos_z;
183
184 int32_t
185 floorz,
186 ceilingz,
187 lastvx,
188 lastvy,
189
190 lasttransport,
191
192 picnum,
193 ang,
194 extra,
195 owner,
196
197 movflag,
198 tempang,
199 timetosleep,
200
201 stayput,
202 dispicnum;
203
204 // note: lightId, lightcount, lightmaxrange are not synchronized between client and server
205
206 int32_t
207 cgg;
208
209
210 // sprite fields
211 //-----------------------------
212
213 int32_t
214 spr_x,
215 spr_y,
216 spr_z,
217
218 spr_cstat,
219
220 spr_picnum,
221
222 spr_shade,
223
224 spr_pal,
225 spr_clipdist,
226 spr_blend,
227
228 spr_xrepeat,
229 spr_yrepeat,
230
231 spr_xoffset,
232 spr_yoffset,
233
234 spr_sectnum,
235 spr_statnum,
236
237 spr_ang,
238 spr_owner,
239 spr_xvel,
240 spr_yvel,
241 spr_zvel,
242
243 spr_lotag,
244 spr_hitag,
245
246 spr_extra;
247
248 //---------------------------------------------
249 //spriteext fields
250
251 int32_t
252 ext_mdanimtims,
253
254 ext_mdanimcur,
255 ext_angoff,
256 ext_pitch,
257 ext_roll,
258
259 ext_pivot_offset_x,
260 ext_pivot_offset_y,
261 ext_pivot_offset_z,
262
263 ext_position_offset_x,
264 ext_position_offset_y,
265 ext_position_offset_z,
266
267 ext_flags,
268 ext_xpanning,
269 ext_ypanning;
270
271 float ext_alpha;
272
273 // DON'T send tsprites over the internet
274
275 //--------------------------------------------
276 //spritesmooth fields
277
278 float sm_smoothduration;
279
280 int32_t
281 sm_mdcurframe,
282 sm_mdoldframe,
283
284 sm_mdsmooth;
285
286 //--------------------------------------------
287 // SpriteProjectile fields
288
289 // may want to put projectile fields here
290 int32_t netIndex;
291
292 } netactor_t;
293 #pragma pack(pop)
294
295 typedef struct
296 {
297 intptr_t *execPtr; // pointer to CON script for this tile, formerly actorscrptr
298 intptr_t *loadPtr; // pointer to load time CON script, formerly actorLoadEventScrPtr or something
299 projectile_t *proj;
300 projectile_t *defproj;
301 uint32_t flags; // formerly SpriteFlags, ActorType
302 int32_t cacherange; // formerly SpriteCache
303 } tiledata_t;
304
305
306 enum sflags_t : unsigned int
307 {
308 SFLAG_SHADOW = 0x00000001,
309 SFLAG_NVG = 0x00000002,
310 SFLAG_NOSHADE = 0x00000004,
311 SFLAG_PROJECTILE = 0x00000008,
312 SFLAG_DECAL = 0x00000010,
313 SFLAG_BADGUY = 0x00000020,
314 SFLAG_NOPAL = 0x00000040,
315 SFLAG_NOEVENTCODE = 0x00000080,
316 SFLAG_NOLIGHT = 0x00000100,
317 SFLAG_USEACTIVATOR = 0x00000200,
318 SFLAG_NULL = 0x00000400, // null sprite in multiplayer
319 SFLAG_NOCLIP = 0x00000800, // clipmove it with cliptype 0
320 SFLAG_NOFLOORSHADOW = 0x00001000, // for temp. internal use, per-tile flag not checked
321 SFLAG_SMOOTHMOVE = 0x00002000,
322 SFLAG_NOTELEPORT = 0x00004000,
323 SFLAG_BADGUYSTAYPUT = 0x00008000,
324 SFLAG_CACHE = 0x00010000,
325 // rotation-fixed wrt a pivot point to prevent position diverging due to
326 // roundoff error accumulation:
327 SFLAG_ROTFIXED = 0x00020000,
328 SFLAG_HARDCODED_BADGUY = 0x00040000,
329 SFLAG_DIDNOSE7WATER = 0x00080000, // used temporarily
330 SFLAG_NODAMAGEPUSH = 0x00100000,
331 SFLAG_NOWATERDIP = 0x00200000,
332 SFLAG_HURTSPAWNBLOOD = 0x00400000,
333 SFLAG_GREENSLIMEFOOD = 0x00800000,
334 SFLAG_REALCLIPDIST = 0x01000000,
335 SFLAG_WAKEUPBADGUYS = 0x02000000,
336 SFLAG_DAMAGEEVENT = 0x04000000,
337 SFLAG_NOWATERSECTOR = 0x08000000,
338 SFLAG_QUEUEDFORDELETE = 0x10000000,
339 SFLAG_RESERVED = 0x20000000,
340 SFLAG_RESERVED2 = 0x40000000,
341 SFLAG_RESERVED3 = 0x80000000,
342 };
343
344 // Custom projectiles "workslike" flags.
345 // XXX: Currently not predefined from CON.
346 enum pflags_t : unsigned int
347 {
348 PROJECTILE_HITSCAN = 0x00000001,
349 PROJECTILE_RPG = 0x00000002,
350 PROJECTILE_BOUNCESOFFWALLS = 0x00000004,
351 PROJECTILE_BOUNCESOFFMIRRORS = 0x00000008,
352 PROJECTILE_KNEE = 0x00000010,
353 PROJECTILE_WATERBUBBLES = 0x00000020,
354 PROJECTILE_TIMED = 0x00000040,
355 PROJECTILE_BOUNCESOFFSPRITES = 0x00000080,
356 PROJECTILE_SPIT = 0x00000100,
357 PROJECTILE_COOLEXPLOSION1 = 0x00000200,
358 PROJECTILE_BLOOD = 0x00000400,
359 PROJECTILE_LOSESVELOCITY = 0x00000800,
360 PROJECTILE_NOAIM = 0x00001000,
361 PROJECTILE_RANDDECALSIZE = 0x00002000,
362 PROJECTILE_EXPLODEONTIMER = 0x00004000,
363 PROJECTILE_RPG_IMPACT = 0x00008000,
364 PROJECTILE_RADIUS_PICNUM = 0x00010000,
365 PROJECTILE_ACCURATE_AUTOAIM = 0x00020000,
366 PROJECTILE_FORCEIMPACT = 0x00040000,
367 PROJECTILE_REALCLIPDIST = 0x00080000,
368 PROJECTILE_ACCURATE = 0x00100000,
369 PROJECTILE_NOSETOWNERSHADE = 0x00200000,
370 PROJECTILE_RPG_IMPACT_DAMAGE = 0x00400000,
371 PROJECTILE_MOVED = 0x80000000, // internal flag, do not document
372 PROJECTILE_TYPE_MASK = PROJECTILE_HITSCAN | PROJECTILE_RPG | PROJECTILE_KNEE | PROJECTILE_BLOOD,
373 };
374
375 extern tiledata_t g_tile[MAXTILES];
376 extern actor_t actor[MAXSPRITES];
377 #ifdef POLYMER
378 extern practor_t practor[MAXSPRITES];
379 #endif
380 extern int32_t block_deletesprite;
381 extern int32_t g_noEnemies;
382 extern int32_t otherp;
383 extern int32_t ticrandomseed;
384 extern projectile_t SpriteProjectile[MAXSPRITES];
385 extern uint8_t g_radiusDmgStatnums[(MAXSTATUS+7)>>3];
386
387 int A_CheckNoSE7Water(uspriteptr_t pSprite, int sectNum, int sectLotag, int32_t *pOther);
388 int A_CheckSwitchTile(int spriteNum);
389 int A_IncurDamage(int spriteNum);
390 void A_AddToDeleteQueue(int spriteNum);
391 void A_DeleteSprite(int spriteNum);
392 void A_DoGuts(int spriteNum, int tileNum, int spawnCnt);
393 void A_DoGutsDir(int spriteNum, int tileNum, int spawnCnt);
394 int A_GetClipdist(int spriteNum, int clipDist);
395 void A_MoveCyclers(void);
396 void A_MoveDummyPlayers(void);
397 void A_MoveSector(int spriteNum);
398 void A_PlayAlertSound(int spriteNum);
399 void A_RadiusDamage(int spriteNum, int blastRadius, int dmg1, int dmg2, int dmg3, int dmg4);
400 void A_SpawnMultiple(int spriteNum, int tileNum, int spawnCnt);
401
402 int G_SetInterpolation(int32_t *posptr);
403 void G_AddGameLight(int lightRadius, int spriteNum, int zOffset, int lightRange, int lightColor, int lightPrio);
404 void G_ClearCameraView(DukePlayer_t *ps);
405 void G_DoInterpolations(int smoothRatio);
406 void G_MoveWorld(void);
407 void G_RefreshLights(void);
408 void G_StopInterpolation(const int32_t *posptr);
409
410 // PK 20110701: changed input argument: int32_t i (== sprite, whose sectnum...) --> sectnum directly
411 void Sect_ToggleInterpolation(int sectnum, int setInterpolation);
Sect_ClearInterpolation(int sectnum)412 static FORCE_INLINE void Sect_ClearInterpolation(int sectnum) { Sect_ToggleInterpolation(sectnum, 0); }
Sect_SetInterpolation(int sectnum)413 static FORCE_INLINE void Sect_SetInterpolation(int sectnum) { Sect_ToggleInterpolation(sectnum, 1); }
414
415 #if KRANDDEBUG
416 # define ACTOR_INLINE __fastcall
417 # define ACTOR_INLINE_HEADER extern __fastcall
418 #else
419 # define ACTOR_INLINE EXTERN_INLINE
420 # define ACTOR_INLINE_HEADER EXTERN_INLINE_HEADER
421 #endif
422
423 extern int32_t A_MoveSpriteClipdist(int32_t spritenum, vec3_t const * change, uint32_t cliptype, int32_t clipdist);
424 ACTOR_INLINE_HEADER int A_CheckEnemyTile(int tileNum);
425 ACTOR_INLINE_HEADER int A_SetSprite(int spriteNum, uint32_t cliptype);
426 ACTOR_INLINE_HEADER int32_t A_MoveSprite(int spriteNum, vec3_t const * change, uint32_t cliptype);
427
428 EXTERN_INLINE_HEADER int G_CheckForSpaceCeiling(int sectnum);
429 EXTERN_INLINE_HEADER int G_CheckForSpaceFloor(int sectnum);
430
431 EXTERN_INLINE_HEADER int A_CheckEnemySprite(void const * s);
432
433 #ifdef __cplusplus
434 }
435 #endif
436
437 #if defined actors_c_ || !defined DISABLE_INLINING
438
439 # if !KRANDDEBUG || (KRANDDEBUG && defined actors_c_)
440
A_CheckEnemyTile(int const tileNum)441 ACTOR_INLINE int A_CheckEnemyTile(int const tileNum)
442 {
443 return ((g_tile[tileNum].flags & (SFLAG_HARDCODED_BADGUY | SFLAG_BADGUY)) != 0);
444 }
445
A_SetSprite(int const spriteNum,uint32_t cliptype)446 ACTOR_INLINE int A_SetSprite(int const spriteNum, uint32_t cliptype)
447 {
448 vec3_t const davect = { (sprite[spriteNum].xvel * (sintable[(sprite[spriteNum].ang + 512) & 2047])) >> 14,
449 (sprite[spriteNum].xvel * (sintable[sprite[spriteNum].ang & 2047])) >> 14, sprite[spriteNum].zvel };
450 return (A_MoveSprite(spriteNum, &davect, cliptype) == 0);
451 }
452
A_SetSpriteNoZ(int const spriteNum,uint32_t cliptype)453 ACTOR_INLINE int A_SetSpriteNoZ(int const spriteNum, uint32_t cliptype)
454 {
455 vec3_t const davect = { (sprite[spriteNum].xvel * (sintable[(sprite[spriteNum].ang + 512) & 2047])) >> 14,
456 (sprite[spriteNum].xvel * (sintable[sprite[spriteNum].ang & 2047])) >> 14, 0 };
457 return (A_MoveSprite(spriteNum, &davect, cliptype) == 0);
458 }
459
A_MoveSprite(int const spriteNum,vec3_t const * const change,uint32_t cliptype)460 ACTOR_INLINE int32_t A_MoveSprite(int const spriteNum, vec3_t const * const change, uint32_t cliptype)
461 {
462 return A_MoveSpriteClipdist(spriteNum, change, cliptype, -1);
463 }
464
465 # endif
466
467 # include "namesdyn.h"
468
G_CheckForSpaceCeiling(int const sectnum)469 EXTERN_INLINE int G_CheckForSpaceCeiling(int const sectnum)
470 {
471 return ((sector[sectnum].ceilingstat&1) && sector[sectnum].ceilingpal == 0 &&
472 (sector[sectnum].ceilingpicnum==MOONSKY1 || sector[sectnum].ceilingpicnum==BIGORBIT1));
473 }
474
G_CheckForSpaceFloor(int const sectnum)475 EXTERN_INLINE int G_CheckForSpaceFloor(int const sectnum)
476 {
477 return ((sector[sectnum].floorstat&1) && sector[sectnum].ceilingpal == 0 &&
478 (sector[sectnum].floorpicnum==MOONSKY1 || sector[sectnum].floorpicnum==BIGORBIT1));
479 }
480
A_CheckEnemySprite(void const * const pSprite)481 EXTERN_INLINE int A_CheckEnemySprite(void const * const pSprite)
482 {
483 return A_CheckEnemyTile(((uspriteptr_t) pSprite)->picnum);
484 }
485
486 #endif
487
488 #endif
489