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