1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 #ifndef _rt_actor_private
21 #define _rt_actor_private
22 
23 #define MAXGIBS            600
24 #define HAAPT              24
25 #define VAAPT              24
26 #define GODHAPT            1024
27 #define GODVAPT            1024
28 #define MAXDELTAYZSHOOT    (((5*FINEANGLES)/360))
29 #define MAXDELTAYZSEE      (((15*FINEANGLES)/360))
30 #define MAXSHOOTOFFSET     (((15*FINEANGLES)/360))
31 #define MAXSHOOTSHIFT      (1)
32 #define MAXDAMAGE          (64)
33 #define MAXYZANGLE         (((30*FINEANGLES)/360))
34 #define SMOKEWALLOFFSET    (0x800)
35 #define MZADJUST           0x30000;
36 #define MAXSTEPHEIGHT      24
37 #define SIGN(x)            ((x)>=0)?(1):(-1)
38 #define MAXRAIN            128
39 #define SG_PSTAT      0x4000
40 #define SG_PSTATE     0x2000
41 #define EXPLOSION_DAMAGE   50
42 #define LOWFALLCLIPZ       (maxheight - 96)
43 #define HIGHFALLCLIPZ      -5
44 #define LOWRISECLIPZ       (nominalheight)
45 #define HIGHRISECLIPZ      64
46 #define NORMALGIBSPEED     0x2f00
47 
48 #define FL_PLEADING        0x400
49 #define FL_EYEBALL         0x400
50 #define FL_UNDEAD          0x8000
51 
52 #define NME_DRUNKTYPE       0x01
53 #define NME_HEATSEEKINGTYPE 0x02
54 
55 #define NUMSTATES 11
56 
57 enum {
58   STAND,
59   PATH,
60   COLLIDE1,
61   COLLIDE2,
62   CHASE,
63   USE,
64   AIM,
65   DIE,
66   FIRE,
67   WAIT,
68   CRUSH
69   };
70 
71 #define SHOTMOM                0x200l
72 #define NEXT                   1
73 #define PREV                   0
74 #define ANGLEMOVE              0x2b000l
75 #define PAINTIME               5l
76 #define LOOKAHEAD              (20 << 16)
77 #define DRAINTIME              70l
78 #define EXPLOSION_IMPULSE      0x2600l
79 #define ZEROMOM                ob->momentumx = ob->momentumy = 0
80 #define NOMOM                  ((!ob->momentumx) && (!ob->momentumy))
81 #define WHICHACTOR             (ob->obclass-lowguardobj)
82 #define SPDPATROL              0x600l
83 //#define ENEMYRUNSPEED          (3*SPDPATROL)
84 #define ENEMYRUNSPEED          (0xc00)
85 #define ENEMYFASTRUNSPEED      (5*SPDPATROL)
86 #define ENEMYINSANESPEED       (7*SPDPATROL)
87 #define MAXMOVE                0x2000l
88 #define PROJECTILESIZE         0x6000l
89 #define DEADFRICTION           0x6000l
90 #define ROLLMOMENTUM           0x920l
91 #define PROJSIZE               0x4000l
92 #define PILLARMOM              0x800l
93 #define HALFGLOBAL1            (TILEGLOBAL/2)
94 #define TOUCHDIST              0xb000l
95 #define STANDDIST              0x5000l
96 #define SNAKERAD               0x4000l
97 #define MINSIGHT               0x18000l
98 #define HBM                    -2
99 #define SNEAKY                 -3
100 #define GIBVALUE               -3
101 #define DISKMOMZ               4
102 
103 //=========================== macros =============================
104 
105 #define M_ISWALL(x)           ((x->which == WALL) || (x->which == PWALL) || (x->which == MWALL))
106 #define M_DISTOK(p1,p2,d)     (abs((p1)-(p2)) <= d)
107 #define M_NONS(x)             ((x->obclass == wallfireobj) || (x->obclass == pillarobj))
108 #define M_CHOOSETIME(x)       ((int)(TILEGLOBAL/((x->speed))))
109 #define M_DIST(x1,x2,y1,y2)   (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
110 #define M_S(x)                (UPDATE_STATES[x][ob->obclass-lowguardobj])
111 #define Fix(a)                (a &= (FINEANGLES - 1))
112 
113 
114 #define STOPACTOR(ob)                   \
115    {                                    \
116    ob->momentumx = ob->momentumy = 0;   \
117    ob->dirchoosetime = 0;               \
118    }
119 
120 
121 #define M_CHECKDIR(ob,tdir)             \
122    {                                    \
123    ob->dir = tdir;                      \
124    ParseMomentum(ob,dirangle8[tdir]);   \
125    ActorMovement(ob);                   \
126    if (ob->momentumx || ob->momentumy)  \
127       return;                           \
128    }                                    \
129 
130 
131 #define M_CHECKTURN(x,ndir)                             \
132    {                                                    \
133    if (ndir == olddir)                                  \
134       ZEROMOM;                                          \
135    ParseMomentum(x,dirangle8[ndir]);                    \
136    ActorMovement(x);                                    \
137    if (!NOMOM)                                          \
138       {                                                 \
139       if (ndir != olddir)                               \
140          {                                              \
141          next = dirorder[olddir][NEXT];                 \
142          prev = dirorder[olddir][PREV];                 \
143          x->temp1 = ndir;                               \
144          if (dirdiff[ndir][next] < dirdiff[ndir][prev]) \
145             NewState(x,&s_kristleft);                   \
146          else                                           \
147             NewState(x,&s_kristright);                  \
148          }                                              \
149       return;                                           \
150       }                                                 \
151    }                                                    \
152 
153 #define M_CheckDoor(ob)                          \
154    {                                             \
155    door = ob->door_to_open;                      \
156    if (door != -1)                               \
157       {                                          \
158       if ((ob->obclass > shurikenobj) &&         \
159           (ob->obclass != collectorobj)          \
160          )                                       \
161          Error("you got it !!!");                \
162       LinkedOpenDoor(door);                      \
163       if (doorobjlist[door]->action != dr_open)  \
164          return;                                 \
165       ob->door_to_open = -1;                     \
166       }                                          \
167    }                                             \
168 
169 #define M_CheckBossSounds(ob)                                 \
170    {                                                          \
171    if ((ob->obclass >= b_darianobj) &&                        \
172        (ob->obclass <= b_darksnakeobj) &&                     \
173        (ob->flags & FL_ATTACKMODE)  &&                        \
174        (ob->obclass != b_robobossobj) &&                      \
175        (!(ob->flags & FL_DYING))                              \
176       )                                                       \
177       {                                                       \
178       if (MISCVARS->SOUNDTIME)                                \
179          MISCVARS->SOUNDTIME --;                              \
180       else                                                    \
181          {                                                    \
182          MISCVARS->SOUNDTIME = 5*VBLCOUNTER;                  \
183          if (GameRandomNumber("boss sound check",0)<160)      \
184             {                                                 \
185             int rand,sound;                                   \
186                                                               \
187             rand = GameRandomNumber("boss sounds",0);         \
188             sound = BAS[ob->obclass].operate;                 \
189             if (rand < 160)                                   \
190                sound ++;                                      \
191             if (rand < 80)                                    \
192                sound ++;                                      \
193                                                               \
194             SD_PlaySoundRTP(sound,ob->x,ob->y);               \
195             }                                                 \
196          }                                                    \
197       if (MISCVARS->REDTIME)                                  \
198          {                                                    \
199          MISCVARS->REDTIME --;                                \
200          MISCVARS->redindex = ((MISCVARS->REDTIME >> 1) & 15);\
201          }                                                    \
202       }                                                       \
203    }
204 
205 
206 
207 
208 #define SET_DEATH_SHAPEOFFSET(ob)                     \
209    {                                                  \
210    ob->flags |= FL_ALTERNATE;                         \
211    ob->shapeoffset += deathshapeoffset[ob->obclass];  \
212    }
213 
214 
215 #define RESET_DEATH_SHAPEOFFSET(ob)                   \
216    {                                                  \
217    ob->flags &= ~FL_ALTERNATE;                        \
218    ob->shapeoffset -= deathshapeoffset[ob->obclass];  \
219    }
220 
221 #define LOW_VIOLENCE_DEATH_SHOULD_BE_SET(ob)          \
222      ((gamestate.violence < vl_high) &&               \
223       (ob->obclass >= lowguardobj) &&                 \
224       (ob->obclass <= triadenforcerobj) &&            \
225       (!(ob->flags & FL_ALTERNATE))                   \
226      )                                                \
227 
228 #define LOW_VIOLENCE_DEATH_IS_SET(ob)   (ob->flags & FL_ALTERNATE)
229 
230 #define LOW_VIOLENCE_PAIN_SHOULD_BE_SET  LOW_VIOLENCE_DEATH_SHOULD_BE_SET
231 
232 #define LOW_VIOLENCE_PAIN_IS_SET  LOW_VIOLENCE_DEATH_IS_SET
233 
234 #define SET_PAIN_SHAPEOFFSET  SET_DEATH_SHAPEOFFSET
235 
236 #define RESET_PAIN_SHAPEOFFSET  RESET_DEATH_SHAPEOFFSET
237 
238 
239 // default = actor
240 
241 typedef struct  sat
242  { int          x,y,z;
243 	unsigned     flags;
244 	int          hitpoints;
245 	int          targetx,targety;
246 	int          angle;
247 	int          yzangle;
248 	int          speed;
249 	int          momentumx,momentumy,momentumz;
250 	int          temp1,temp2,temp3;
251 	int          whateverindex,targetindex;
252 
253 	short        ticcount;
254 	short        shapeoffset;
255 	short        stateindex;
256 	short        dirchoosetime;
257 
258 	byte         areanumber;
259 	byte         obclass;
260 	signed char  door_to_open;
261 	signed char  dir;
262 
263  }saved_actor_type;
264 
265 
266 typedef struct
267  {thingtype which;
268   byte tilex,tiley;
269   fixed x,y,z;
270  }tpoint;
271 
272 
273 //========================== Function Prototypes ==============================
274 
275 void     MissileMovement(objtype*);
276 boolean  MissileTryMove(objtype*,int,int,int);
277 void     T_DarkSnakeChase(objtype*);
278 void     HeatSeek(objtype*);
279 boolean  CheckDoor(objtype *ob,doorobj_t*,int,int);
280 boolean  NextToDoor(objtype*ob);
281 void     MissileHit (objtype *ob,void*);
282 int      Near(objtype*,void*,int);
283 void     FirstSighting(objtype*);
284 void     SelectOrobotChaseDir(objtype*);
285 void     SelectPathDir(objtype*);
286 void     SelectChaseDir(objtype*);
287 void     SelectRoboChaseDir(objtype*);
288 void     SelectDodgeDir(objtype*);
289 void     SelectRollDir (objtype*);
290 void     SelectTouchDir(objtype*);
291 void     SelectMineDir(objtype*);
292 boolean  WallCheck(int,int);
293 boolean  NMEspincheck(objtype*);
294 void     TurnActorIntoSprite(objtype*ob);
295 void     ActivateEnemy(objtype*);
296 #endif
297