Rev 5021 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5 | Plagman | 1 | //------------------------------------------------------------------------- |
2 | /* |
||
1652 | terminx | 3 | Copyright (C) 2010 EDuke32 developers and contributors |
5 | Plagman | 4 | |
1652 | terminx | 5 | This file is part of EDuke32. |
5 | Plagman | 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 |
||
4541 | hendricks2 | 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
5 | Plagman | 20 | */ |
21 | //------------------------------------------------------------------------- |
||
1652 | terminx | 22 | |
5 | Plagman | 23 | #include "duke3d.h" |
1677 | terminx | 24 | #include "actors.h" |
610 | terminx | 25 | #include "gamedef.h" |
1677 | terminx | 26 | #include "gameexec.h" |
5 | Plagman | 27 | |
1595 | helixhorne | 28 | #if KRANDDEBUG |
29 | # define ACTOR_STATIC |
||
30 | #else |
||
31 | # define ACTOR_STATIC static |
||
32 | #endif |
||
33 | |||
2608 | helixhorne | 34 | #define KILLIT(KX) do { A_DeleteSprite(KX); goto BOLT; } while (0) |
1595 | helixhorne | 35 | |
1205 | terminx | 36 | extern int32_t g_numEnvSoundsPlaying; |
37 | extern int32_t g_noEnemies; |
||
1143 | terminx | 38 | |
3678 | helixhorne | 39 | int32_t otherp; |
40 | |||
5067 | terminx | 41 | int32_t G_SetInterpolation(int32_t * const posptr) |
5 | Plagman | 42 | { |
3486 | helixhorne | 43 | if (g_numInterpolations >= MAXINTERPOLATIONS) |
44 | return 1; |
||
45 | |||
5067 | terminx | 46 | for (int i = 0; i < g_numInterpolations; ++i) |
3486 | helixhorne | 47 | if (curipos[i] == posptr) |
48 | return 0; |
||
49 | |||
1143 | terminx | 50 | curipos[g_numInterpolations] = posptr; |
51 | oldipos[g_numInterpolations] = *posptr; |
||
52 | g_numInterpolations++; |
||
3486 | helixhorne | 53 | return 0; |
5 | Plagman | 54 | } |
55 | |||
5067 | terminx | 56 | void G_StopInterpolation(int32_t * const posptr) |
5 | Plagman | 57 | { |
5067 | terminx | 58 | for (int i = startofdynamicinterpolations; i < g_numInterpolations; ++i) |
5 | Plagman | 59 | if (curipos[i] == posptr) |
60 | { |
||
1143 | terminx | 61 | g_numInterpolations--; |
62 | oldipos[i] = oldipos[g_numInterpolations]; |
||
63 | bakipos[i] = bakipos[g_numInterpolations]; |
||
64 | curipos[i] = curipos[g_numInterpolations]; |
||
5 | Plagman | 65 | } |
66 | } |
||
67 | |||
1205 | terminx | 68 | void G_DoInterpolations(int32_t smoothratio) //Stick at beginning of drawscreen |
5 | Plagman | 69 | { |
1531 | plagman | 70 | if (g_interpolationLock++) |
71 | return; |
||
72 | |||
5067 | terminx | 73 | int32_t odelta, ndelta = 0; |
74 | |||
75 | for (int i = 0, j = 0; i < g_numInterpolations; ++i) |
||
5 | Plagman | 76 | { |
5067 | terminx | 77 | odelta = ndelta; |
5 | Plagman | 78 | bakipos[i] = *curipos[i]; |
5067 | terminx | 79 | ndelta = (*curipos[i]) - oldipos[i]; |
80 | if (odelta != ndelta) |
||
81 | j = mulscale16(ndelta, smoothratio); |
||
82 | *curipos[i] = oldipos[i] + j; |
||
5 | Plagman | 83 | } |
84 | } |
||
85 | |||
2853 | helixhorne | 86 | void G_ClearCameraView(DukePlayer_t *ps) |
87 | { |
||
88 | int32_t k; |
||
89 | |||
90 | ps->newowner = -1; |
||
5067 | terminx | 91 | ps->pos = ps->opos; |
2853 | helixhorne | 92 | ps->ang = ps->oang; |
93 | |||
94 | updatesector(ps->pos.x, ps->pos.y, &ps->cursectnum); |
||
95 | P_UpdateScreenPal(ps); |
||
96 | |||
3679 | helixhorne | 97 | for (SPRITES_OF(STAT_ACTOR, k)) |
2853 | helixhorne | 98 | if (sprite[k].picnum==CAMERA1) |
99 | sprite[k].yvel = 0; |
||
100 | } |
||
101 | |||
4204 | helixhorne | 102 | // Manhattan distance between wall-point and sprite. |
4981 | terminx | 103 | static inline int32_t G_WallSpriteDist(const twalltype *wal, const spritetype *spr) |
4204 | helixhorne | 104 | { |
105 | return klabs(wal->x - spr->x) + klabs(wal->y - spr->y); |
||
106 | } |
||
107 | |||
3679 | helixhorne | 108 | void A_RadiusDamage(int32_t i, int32_t r, int32_t hp1, int32_t hp2, int32_t hp3, int32_t hp4) |
5 | Plagman | 109 | { |
3679 | helixhorne | 110 | int32_t d, q, stati; |
111 | const spritetype *const s = &sprite[i]; |
||
112 | |||
3678 | helixhorne | 113 | static const int32_t statlist[] = { |
3679 | helixhorne | 114 | STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE, |
115 | STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC |
||
3353 | helixhorne | 116 | }; |
5 | Plagman | 117 | |
4199 | helixhorne | 118 | // XXX: accesses to 'sectorlist' potentially unaligned |
119 | int16_t *const sectorlist = (int16_t *)tempbuf; |
||
120 | const int32_t maxsects = sizeof(tempbuf)/sizeof(int16_t); |
||
3353 | helixhorne | 121 | |
3679 | helixhorne | 122 | if (s->picnum == RPG && s->xrepeat < 11) |
123 | goto SKIPWALLCHECK; |
||
5 | Plagman | 124 | |
331 | terminx | 125 | if (s->picnum != SHRINKSPARK) |
5 | Plagman | 126 | { |
3679 | helixhorne | 127 | int32_t sectcnt = 0; |
128 | int32_t sectend = 1; |
||
129 | |||
4199 | helixhorne | 130 | sectorlist[0] = s->sectnum; |
5 | Plagman | 131 | |
132 | do |
||
133 | { |
||
4981 | terminx | 134 | const twalltype *wal; |
4199 | helixhorne | 135 | const int32_t dasect = sectorlist[sectcnt++]; |
3679 | helixhorne | 136 | const int32_t startwall = sector[dasect].wallptr; |
137 | const int32_t endwall = startwall+sector[dasect].wallnum; |
||
4205 | helixhorne | 138 | |
3679 | helixhorne | 139 | int32_t w; |
4205 | helixhorne | 140 | const int32_t w2 = wall[startwall].point2; |
3679 | helixhorne | 141 | |
4205 | helixhorne | 142 | // Check if "hit" 1st or 3rd wall-point. This mainly makes sense |
143 | // for rectangular "ceiling light"-style sectors. |
||
4981 | terminx | 144 | if (G_WallSpriteDist((twalltype *)&wall[startwall], s) < r || |
145 | G_WallSpriteDist((twalltype *)&wall[wall[w2].point2], s) < r) |
||
5 | Plagman | 146 | { |
4205 | helixhorne | 147 | if (((sector[dasect].ceilingz-s->z)>>8) < r) |
148 | Sect_DamageCeilingOrFloor(0, dasect); |
||
149 | if (((s->z-sector[dasect].floorz)>>8) < r) |
||
150 | Sect_DamageCeilingOrFloor(1, dasect); |
||
5 | Plagman | 151 | } |
152 | |||
4981 | terminx | 153 | for (w=startwall,wal=(twalltype *)&wall[startwall]; w<endwall; w++,wal++) |
4204 | helixhorne | 154 | if (G_WallSpriteDist(wal, s) < r) |
5 | Plagman | 155 | { |
3678 | helixhorne | 156 | int16_t sect = -1; |
3679 | helixhorne | 157 | const int32_t nextsect = wal->nextsector; |
158 | int32_t x1, y1; |
||
159 | |||
5 | Plagman | 160 | if (nextsect >= 0) |
161 | { |
||
3679 | helixhorne | 162 | int32_t dasect2; |
163 | for (dasect2=sectend-1; dasect2>=0; dasect2--) |
||
4199 | helixhorne | 164 | if (sectorlist[dasect2] == nextsect) |
3679 | helixhorne | 165 | break; |
166 | |||
167 | if (dasect2 < 0) |
||
4199 | helixhorne | 168 | { |
169 | if (sectend == maxsects) |
||
170 | goto SKIPWALLCHECK; // prevent oob access of 'sectorlist' |
||
171 | sectorlist[sectend++] = nextsect; |
||
172 | } |
||
5 | Plagman | 173 | } |
3679 | helixhorne | 174 | |
5 | Plagman | 175 | x1 = (((wal->x+wall[wal->point2].x)>>1)+s->x)>>1; |
176 | y1 = (((wal->y+wall[wal->point2].y)>>1)+s->y)>>1; |
||
3679 | helixhorne | 177 | |
5 | Plagman | 178 | updatesector(x1,y1,§); |
3679 | helixhorne | 179 | |
333 | terminx | 180 | if (sect >= 0 && cansee(x1,y1,s->z,sect,s->x,s->y,s->z,s->sectnum)) |
1207 | terminx | 181 | { |
3679 | helixhorne | 182 | vec3_t tmpvect = { wal->x, wal->y, s->z }; |
183 | A_DamageWall(i, w, &tmpvect, s->picnum); |
||
1207 | terminx | 184 | } |
5 | Plagman | 185 | } |
186 | } |
||
187 | while (sectcnt < sectend); |
||
188 | } |
||
189 | |||
190 | SKIPWALLCHECK: |
||
191 | |||
3679 | helixhorne | 192 | q = -(16<<8) + (krand()&((32<<8)-1)); |
5 | Plagman | 193 | |
4199 | helixhorne | 194 | for (stati=0; stati < ARRAY_SSIZE(statlist); stati++) |
5 | Plagman | 195 | { |
3679 | helixhorne | 196 | int32_t j = headspritestat[statlist[stati]]; |
197 | |||
331 | terminx | 198 | while (j >= 0) |
5 | Plagman | 199 | { |
3679 | helixhorne | 200 | const int32_t nextj = nextspritestat[j]; |
3353 | helixhorne | 201 | spritetype *const sj = &sprite[j]; |
5 | Plagman | 202 | |
3679 | helixhorne | 203 | // DEFAULT, ZOMBIEACTOR, MISC |
204 | if (stati == 0 || stati >= 5 || AFLAMABLE(sj->picnum)) |
||
5 | Plagman | 205 | { |
333 | terminx | 206 | if (s->picnum != SHRINKSPARK || (sj->cstat&257)) |
207 | if (dist(s, sj) < r) |
||
5 | Plagman | 208 | { |
1143 | terminx | 209 | if (A_CheckEnemySprite(sj) && !cansee(sj->x, sj->y,sj->z+q, sj->sectnum, s->x, s->y, s->z+q, s->sectnum)) |
5 | Plagman | 210 | goto BOLT; |
1143 | terminx | 211 | A_DamageObject(j, i); |
5 | Plagman | 212 | } |
213 | } |
||
1143 | terminx | 214 | else if (sj->extra >= 0 && sj != s && (sj->picnum == TRIPBOMB || A_CheckEnemySprite(sj) || sj->picnum == QUEBALL || sj->picnum == STRIPEBALL || (sj->cstat&257) || sj->picnum == DUKELYINGDEAD)) |
5 | Plagman | 215 | { |
333 | terminx | 216 | if (s->picnum == SHRINKSPARK && sj->picnum != SHARK && (j == s->owner || sj->xrepeat < 24)) |
5 | Plagman | 217 | { |
218 | j = nextj; |
||
219 | continue; |
||
220 | } |
||
333 | terminx | 221 | if (s->picnum == MORTER && j == s->owner) |
5 | Plagman | 222 | { |
223 | j = nextj; |
||
224 | continue; |
||
225 | } |
||
226 | |||
331 | terminx | 227 | if (sj->picnum == APLAYER) sj->z -= PHEIGHT; |
333 | terminx | 228 | d = dist(s, sj); |
331 | terminx | 229 | if (sj->picnum == APLAYER) sj->z += PHEIGHT; |
5 | Plagman | 230 | |
333 | terminx | 231 | if (d < r && cansee(sj->x, sj->y, sj->z-(8<<8), sj->sectnum, s->x, s->y, s->z-(12<<8), s->sectnum)) |
5 | Plagman | 232 | { |
1625 | terminx | 233 | actor[j].ang = getangle(sj->x-s->x,sj->y-s->y); |
5 | Plagman | 234 | |
333 | terminx | 235 | if (s->picnum == RPG && sj->extra > 0) |
1625 | terminx | 236 | actor[j].picnum = RPG; |
4351 | helixhorne | 237 | else if (A_CheckSpriteFlags(i,SFLAG_PROJECTILE) && SpriteProjectile[i].workslike & PROJECTILE_RADIUS_PICNUM && sj->extra > 0) |
1625 | terminx | 238 | actor[j].picnum = s->picnum; |
5 | Plagman | 239 | else |
240 | { |
||
333 | terminx | 241 | if (s->picnum == SHRINKSPARK) |
1625 | terminx | 242 | actor[j].picnum = SHRINKSPARK; |
243 | else actor[j].picnum = RADIUSEXPLOSION; |
||
5 | Plagman | 244 | } |
245 | |||
331 | terminx | 246 | if (s->picnum != SHRINKSPARK) |
5 | Plagman | 247 | { |
3679 | helixhorne | 248 | const int32_t k = r/3; |
249 | |||
949 | terminx | 250 | if (d < k) |
5 | Plagman | 251 | { |
331 | terminx | 252 | if (hp4 == hp3) hp4++; |
1625 | terminx | 253 | actor[j].extra = hp3 + (krand()%(hp4-hp3)); |
5 | Plagman | 254 | } |
3679 | helixhorne | 255 | else if (d < k*2) |
5 | Plagman | 256 | { |
331 | terminx | 257 | if (hp3 == hp2) hp3++; |
1625 | terminx | 258 | actor[j].extra = hp2 + (krand()%(hp3-hp2)); |
5 | Plagman | 259 | } |
333 | terminx | 260 | else if (d < r) |
5 | Plagman | 261 | { |
331 | terminx | 262 | if (hp2 == hp1) hp2++; |
1625 | terminx | 263 | actor[j].extra = hp1 + (krand()%(hp2-hp1)); |
5 | Plagman | 264 | } |
265 | |||
4863 | helixhorne | 266 | if (!A_CheckSpriteFlags(j, SFLAG_NODAMAGEPUSH)) |
5 | Plagman | 267 | { |
331 | terminx | 268 | if (sj->xvel < 0) sj->xvel = 0; |
5 | Plagman | 269 | sj->xvel += (s->extra<<2); |
270 | } |
||
271 | |||
333 | terminx | 272 | if (sj->picnum == PODFEM1 || sj->picnum == FEM1 || |
5 | Plagman | 273 | sj->picnum == FEM2 || sj->picnum == FEM3 || |
274 | sj->picnum == FEM4 || sj->picnum == FEM5 || |
||
275 | sj->picnum == FEM6 || sj->picnum == FEM7 || |
||
276 | sj->picnum == FEM8 || sj->picnum == FEM9 || |
||
277 | sj->picnum == FEM10 || sj->picnum == STATUE || |
||
278 | sj->picnum == STATUEFLASH || sj->picnum == SPACEMARINE || sj->picnum == QUEBALL || sj->picnum == STRIPEBALL) |
||
1143 | terminx | 279 | A_DamageObject(j, i); |
5 | Plagman | 280 | } |
1625 | terminx | 281 | else if (s->extra == 0) actor[j].extra = 0; |
5 | Plagman | 282 | |
333 | terminx | 283 | if (sj->picnum != RADIUSEXPLOSION && |
284 | s->owner >= 0 && sprite[s->owner].statnum < MAXSTATUS) |
||
5 | Plagman | 285 | { |
331 | terminx | 286 | if (sj->picnum == APLAYER) |
5 | Plagman | 287 | { |
4226 | helixhorne | 288 | DukePlayer_t *ps = g_player[P_GetP(sj)].ps; |
5 | Plagman | 289 | |
2853 | helixhorne | 290 | if (ps->newowner >= 0) |
291 | G_ClearCameraView(ps); |
||
5 | Plagman | 292 | } |
2853 | helixhorne | 293 | |
1625 | terminx | 294 | actor[j].owner = s->owner; |
5 | Plagman | 295 | } |
296 | } |
||
297 | } |
||
298 | BOLT: |
||
299 | j = nextj; |
||
300 | } |
||
301 | } |
||
302 | } |
||
303 | |||
3678 | helixhorne | 304 | // Maybe do a projectile transport via an SE7. |
305 | // <spritenum>: the projectile |
||
306 | // <i>: the SE7 |
||
307 | // <fromunderp>: below->above change? |
||
5067 | terminx | 308 | static int32_t Proj_MaybeDoTransport(int32_t spritenum, const tspritetype * const effector, int32_t fromunderp, int32_t daz) |
3678 | helixhorne | 309 | { |
5067 | terminx | 310 | if (totalclock <= actor[spritenum].lasttransport) |
311 | return 0; |
||
3678 | helixhorne | 312 | |
5067 | terminx | 313 | spritetype *const spr = &sprite[spritenum]; |
314 | const tspritetype *const otherse = (tspritetype *)&sprite[effector->owner]; |
||
3678 | helixhorne | 315 | |
5067 | terminx | 316 | actor[spritenum].lasttransport = totalclock + (TICSPERFRAME<<2); |
3678 | helixhorne | 317 | |
5067 | terminx | 318 | spr->x += (otherse->x - effector->x); |
319 | spr->y += (otherse->y - effector->y); |
||
3682 | helixhorne | 320 | |
5067 | terminx | 321 | // above->below |
322 | spr->z = (!fromunderp) ? sector[otherse->sectnum].ceilingz - daz + sector[effector->sectnum].floorz : |
||
323 | sector[otherse->sectnum].floorz - daz + sector[effector->sectnum].ceilingz; |
||
324 | // below->above |
||
3682 | helixhorne | 325 | |
5067 | terminx | 326 | actor[spritenum].bpos = *(vec3_t *)&sprite[spritenum]; |
327 | changespritesect(spritenum, otherse->sectnum); |
||
328 | |||
329 | return 1; |
||
3678 | helixhorne | 330 | } |
331 | |||
332 | // Check whether sprite <s> is on/in a non-SE7 water sector. |
||
333 | // <othersectptr>: if not NULL, the sector on the other side. |
||
334 | static int32_t A_CheckNoSE7Water(const spritetype *s, int32_t sectnum, int32_t slotag, int32_t *othersectptr) |
||
335 | { |
||
336 | if (slotag==ST_1_ABOVE_WATER || slotag==ST_2_UNDERWATER) |
||
337 | { |
||
338 | int32_t othersect = yax_getneighborsect( |
||
339 | s->x, s->y, sectnum, slotag==ST_1_ABOVE_WATER ? YAX_FLOOR : YAX_CEILING); |
||
340 | |||
341 | int32_t othertag = (slotag==ST_1_ABOVE_WATER) ? |
||
342 | ST_2_UNDERWATER : ST_1_ABOVE_WATER; |
||
343 | |||
344 | // If submerging, the lower sector MUST have lotag 2. |
||
345 | // If emerging, the upper sector MUST have lotag 1. |
||
346 | // This way, the x/y coordinates where above/below water |
||
347 | // changes can happen are the same. |
||
348 | if (othersect >= 0 && sector[othersect].lotag==othertag) |
||
349 | { |
||
350 | if (othersectptr) |
||
351 | *othersectptr = othersect; |
||
352 | return 1; |
||
353 | } |
||
354 | } |
||
355 | |||
356 | return 0; |
||
357 | } |
||
358 | |||
359 | // Check whether to do a z position update of sprite <spritenum>. |
||
360 | // Returns: |
||
361 | // 0 if no. |
||
362 | // 1 if yes, but stayed inside [actor[].ceilingz+1, actor[].floorz]. |
||
3683 | helixhorne | 363 | // <0 if yes, but passed a TROR no-SE7 water boundary. -returnvalue-1 is the |
364 | // other-side sector number. |
||
3678 | helixhorne | 365 | static int32_t A_CheckNeedZUpdate(int32_t spritenum, int32_t changez, int32_t *dazptr) |
366 | { |
||
367 | const spritetype *spr = &sprite[spritenum]; |
||
3925 | helixhorne | 368 | const int32_t daz = spr->z + (changez>>1); |
3678 | helixhorne | 369 | |
370 | *dazptr = daz; |
||
371 | |||
372 | if (changez == 0) |
||
373 | return 0; |
||
374 | |||
375 | if (daz > actor[spritenum].ceilingz && daz <= actor[spritenum].floorz) |
||
376 | return 1; |
||
377 | |||
378 | #ifdef YAX_ENABLE |
||
379 | { |
||
380 | const int32_t psect=spr->sectnum, slotag=sector[psect].lotag; |
||
3683 | helixhorne | 381 | int32_t othersect; |
3678 | helixhorne | 382 | |
383 | // Non-SE7 water. |
||
3682 | helixhorne | 384 | // PROJECTILE_CHSECT |
3678 | helixhorne | 385 | if ((changez < 0 && slotag==ST_2_UNDERWATER) || (changez > 0 && slotag==ST_1_ABOVE_WATER)) |
3683 | helixhorne | 386 | if (A_CheckNoSE7Water(spr, sprite[spritenum].sectnum, slotag, &othersect)) |
3678 | helixhorne | 387 | { |
3683 | helixhorne | 388 | A_Spawn(spritenum, WATERSPLASH2); |
389 | // NOTE: Don't tweak its z position afterwards like with |
||
390 | // SE7-induced projectile teleportation. It doesn't look good |
||
391 | // with TROR water. |
||
392 | |||
4351 | helixhorne | 393 | actor[spritenum].flags |= SFLAG_DIDNOSE7WATER; |
3683 | helixhorne | 394 | return -othersect-1; |
3678 | helixhorne | 395 | } |
396 | } |
||
397 | #endif |
||
398 | |||
399 | return 0; |
||
400 | } |
||
401 | |||
4590 | helixhorne | 402 | int32_t A_MoveSpriteClipdist(int32_t spritenum, const vec3_t *change, uint32_t cliptype, int32_t clipdist) |
5 | Plagman | 403 | { |
3075 | helixhorne | 404 | spritetype *const spr = &sprite[spritenum]; |
4974 | helixhorne | 405 | const int32_t badguy = A_CheckEnemySprite(spr); |
3075 | helixhorne | 406 | const int32_t oldx = spr->x, oldy = spr->y; |
5 | Plagman | 407 | |
4974 | helixhorne | 408 | if (spr->statnum == STAT_MISC || (badguy && spr->xrepeat < 4)) |
5 | Plagman | 409 | { |
3925 | helixhorne | 410 | spr->x += change->x; |
411 | spr->y += change->y; |
||
412 | spr->z += change->z; |
||
3075 | helixhorne | 413 | |
4974 | helixhorne | 414 | if (badguy) |
3075 | helixhorne | 415 | setsprite(spritenum, (vec3_t *)spr); |
416 | |||
5 | Plagman | 417 | return 0; |
418 | } |
||
419 | |||
4974 | helixhorne | 420 | if (clipdist >= 0) |
5 | Plagman | 421 | { |
4974 | helixhorne | 422 | // use that value |
423 | } |
||
424 | else if (badguy) |
||
425 | { |
||
426 | if (spr->xrepeat > 60) |
||
427 | clipdist = 1024; |
||
428 | else if (spr->picnum == LIZMAN) |
||
429 | clipdist = 292; |
||
430 | else if (A_CheckSpriteTileFlags(spr->picnum, SFLAG_BADGUY)) |
||
431 | clipdist = spr->clipdist<<2; |
||
5 | Plagman | 432 | else |
4974 | helixhorne | 433 | clipdist = 192; |
3075 | helixhorne | 434 | } |
4974 | helixhorne | 435 | else |
436 | { |
||
437 | if (spr->statnum == STAT_PROJECTILE && (SpriteProjectile[spritenum].workslike & PROJECTILE_REALCLIPDIST) == 0) |
||
438 | clipdist = 8; |
||
439 | else |
||
440 | clipdist = spr->clipdist<<2; |
||
441 | } |
||
3075 | helixhorne | 442 | |
5021 | helixhorne | 443 | int16_t dasectnum = spr->sectnum; |
444 | const int16_t osectnum = dasectnum; |
||
445 | int32_t daz = spr->z - 2*tilesiz[spr->picnum].y*spr->yrepeat; |
||
446 | const int32_t oldz = spr->z; |
||
447 | |||
4974 | helixhorne | 448 | // Handle horizontal movement first. |
449 | spr->z = daz; |
||
450 | int32_t retval = clipmove((vec3_t *)spr, &dasectnum, |
||
451 | change->x<<13, change->y<<13, |
||
452 | clipdist, 4<<8, 4<<8, cliptype); |
||
453 | spr->z = oldz; |
||
454 | |||
455 | if (badguy) |
||
3075 | helixhorne | 456 | { |
4974 | helixhorne | 457 | // Handle potential stayput condition (map-provided or hard-coded). |
3075 | helixhorne | 458 | if (dasectnum < 0 || |
459 | ((actor[spritenum].actorstayput >= 0 && actor[spritenum].actorstayput != dasectnum) || |
||
460 | (spr->picnum == BOSS2 && spr->pal == 0 && sector[dasectnum].lotag != ST_3) || |
||
461 | ((spr->picnum == BOSS1 || spr->picnum == BOSS2) && sector[dasectnum].lotag == ST_1_ABOVE_WATER) |
||
5021 | helixhorne | 462 | || (sector[osectnum].lotag != ST_1_ABOVE_WATER && sector[dasectnum].lotag == ST_1_ABOVE_WATER && |
463 | (spr->picnum == LIZMAN || (spr->picnum == LIZTROOP && spr->zvel == 0))) |
||
3075 | helixhorne | 464 | ) |
465 | ) |
||
5 | Plagman | 466 | { |
1490 | terminx | 467 | spr->x = oldx; |
468 | spr->y = oldy; |
||
4974 | helixhorne | 469 | |
470 | // NOTE: in Duke3D, LIZMAN on water takes on random angle here. |
||
471 | |||
3075 | helixhorne | 472 | setsprite(spritenum, (vec3_t *)spr); |
473 | |||
474 | if (dasectnum < 0) |
||
475 | dasectnum = 0; |
||
476 | |||
3678 | helixhorne | 477 | return 16384+dasectnum; |
5 | Plagman | 478 | } |
1210 | terminx | 479 | |
3075 | helixhorne | 480 | if ((retval&49152) >= 32768 && actor[spritenum].cgg==0) |
481 | spr->ang += 768; |
||
1490 | terminx | 482 | } |
1210 | terminx | 483 | |
1490 | terminx | 484 | if (dasectnum == -1) |
485 | { |
||
486 | dasectnum = spr->sectnum; |
||
1736 | helixhorne | 487 | // OSD_Printf("%s:%d wtf\n",__FILE__,__LINE__); |
5 | Plagman | 488 | } |
3075 | helixhorne | 489 | else if (dasectnum != spr->sectnum) |
1490 | terminx | 490 | { |
3075 | helixhorne | 491 | changespritesect(spritenum, dasectnum); |
3094 | terminx | 492 | // A_GetZLimits(spritenum); |
1490 | terminx | 493 | } |
494 | |||
3075 | helixhorne | 495 | Bassert(dasectnum == spr->sectnum); |
496 | |||
4974 | helixhorne | 497 | int dozupdate = A_CheckNeedZUpdate(spritenum, change->z, &daz); |
1490 | terminx | 498 | |
3678 | helixhorne | 499 | // Update sprite's z positions and (for TROR) maybe the sector number. |
500 | if (dozupdate) |
||
1877 | helixhorne | 501 | { |
1490 | terminx | 502 | spr->z = daz; |
1877 | helixhorne | 503 | #ifdef YAX_ENABLE |
3683 | helixhorne | 504 | if (dozupdate < 0) |
3678 | helixhorne | 505 | { |
506 | // If we passed a TROR no-SE7 water boundary, signal to the outside |
||
507 | // that the ceiling/floor was not hit. However, this is not enough: |
||
508 | // later, code checks for (retval&49152)!=49152 |
||
509 | // [i.e. not "was ceiling or floor hit", but "was no sprite hit"] |
||
510 | // and calls G_WeaponHitCeilingOrFloor() then, so we need to set |
||
4351 | helixhorne | 511 | // actor[].flags |= SFLAG_DIDNOSE7WATER in A_CheckNeedZUpdate() |
3678 | helixhorne | 512 | // previously. |
513 | // XXX: Why is this contrived data flow necessary? (If at all.) |
||
3683 | helixhorne | 514 | changespritesect(spritenum, -dozupdate-1); |
515 | return 0; |
||
3678 | helixhorne | 516 | } |
3683 | helixhorne | 517 | |
518 | if (yax_getbunch(dasectnum, (change->z>0))>=0 |
||
519 | && (SECTORFLD(dasectnum,stat, (change->z>0))&yax_waltosecmask(cliptype))==0) |
||
520 | { |
||
521 | setspritez(spritenum, (vec3_t *)spr); |
||
522 | } |
||
1877 | helixhorne | 523 | #endif |
524 | } |
||
3686 | helixhorne | 525 | else if (change->z != 0 && retval == 0) |
3075 | helixhorne | 526 | retval = 16384+dasectnum; |
5 | Plagman | 527 | |
3678 | helixhorne | 528 | if (retval == 16384+dasectnum) |
1490 | terminx | 529 | if (spr->statnum == STAT_PROJECTILE) |
1450 | terminx | 530 | { |
3678 | helixhorne | 531 | int32_t i; |
1450 | terminx | 532 | |
3682 | helixhorne | 533 | // Projectile sector changes due to transport SEs (SE7_PROJECTILE). |
534 | // PROJECTILE_CHSECT |
||
3678 | helixhorne | 535 | for (SPRITES_OF(STAT_TRANSPORT, i)) |
2379 | helixhorne | 536 | if (sprite[i].sectnum == dasectnum) |
1450 | terminx | 537 | { |
3682 | helixhorne | 538 | const int32_t lotag = sector[dasectnum].lotag; |
539 | |||
540 | if (lotag == ST_1_ABOVE_WATER) |
||
2379 | helixhorne | 541 | if (daz >= actor[spritenum].floorz) |
5067 | terminx | 542 | if (Proj_MaybeDoTransport(spritenum, (tspritetype *)&sprite[i], 0, daz)) |
3682 | helixhorne | 543 | return 0; |
3678 | helixhorne | 544 | |
3682 | helixhorne | 545 | if (lotag == ST_2_UNDERWATER) |
2379 | helixhorne | 546 | if (daz <= actor[spritenum].ceilingz) |
5067 | terminx | 547 | if (Proj_MaybeDoTransport(spritenum, (tspritetype *)&sprite[i], 1, daz)) |
3682 | helixhorne | 548 | return 0; |
1450 | terminx | 549 | } |
550 | } |
||
551 | |||
3678 | helixhorne | 552 | return retval; |
5 | Plagman | 553 | } |
554 | |||
1205 | terminx | 555 | int32_t block_deletesprite = 0; |
1138 | terminx | 556 | |
2006 | helixhorne | 557 | #ifdef POLYMER |
3053 | terminx | 558 | static void A_DeleteLight(int32_t s) |
2006 | helixhorne | 559 | { |
2169 | helixhorne | 560 | if (actor[s].lightId >= 0) |
561 | polymer_deletelight(actor[s].lightId); |
||
2006 | helixhorne | 562 | actor[s].lightId = -1; |
563 | actor[s].lightptr = NULL; |
||
564 | } |
||
565 | |||
566 | void G_Polymer_UnInit(void) |
||
567 | { |
||
568 | int32_t i; |
||
569 | |||
570 | for (i=0; i<MAXSPRITES; i++) |
||
3053 | terminx | 571 | A_DeleteLight(i); |
2006 | helixhorne | 572 | } |
573 | #endif |
||
574 | |||
2452 | helixhorne | 575 | // deletesprite() game wrapper |
1205 | terminx | 576 | void A_DeleteSprite(int32_t s) |
587 | terminx | 577 | { |
4699 | terminx | 578 | if (EDUKE32_PREDICT_FALSE(block_deletesprite)) |
1138 | terminx | 579 | { |
4745 | terminx | 580 | OSD_Printf(OSD_ERROR "A_DeleteSprite(): tried to remove sprite %d in EVENT_EGS\n", s); |
1138 | terminx | 581 | return; |
582 | } |
||
1399 | terminx | 583 | |
4680 | terminx | 584 | if (VM_HaveEvent(EVENT_KILLIT)) |
610 | terminx | 585 | { |
4745 | terminx | 586 | int32_t p, pl = A_FindPlayer(&sprite[s], &p); |
1198 | terminx | 587 | |
4745 | terminx | 588 | if (VM_OnEventWithDist_(EVENT_KILLIT, s, pl, p)) |
610 | terminx | 589 | return; |
590 | } |
||
1399 | terminx | 591 | |
592 | #ifdef POLYMER |
||
4745 | terminx | 593 | if (actor[s].lightptr != NULL && getrendermode() == REND_POLYMER) |
3053 | terminx | 594 | A_DeleteLight(s); |
1399 | terminx | 595 | #endif |
596 | |||
4745 | terminx | 597 | // AMBIENT_SFX_PLAYING |
598 | if (sprite[s].picnum == MUSICANDSFX && actor[s].t_data[0] == 1) |
||
3822 | helixhorne | 599 | S_StopEnvSound(sprite[s].lotag, s); |
600 | |||
3270 | terminx | 601 | // NetAlloc |
602 | if (Net_IsRelevantSprite(s)) |
||
603 | { |
||
604 | Net_DeleteSprite(s); |
||
4745 | terminx | 605 | return; |
3270 | terminx | 606 | } |
4745 | terminx | 607 | |
608 | deletesprite(s); |
||
587 | terminx | 609 | } |
610 | |||
1205 | terminx | 611 | void A_AddToDeleteQueue(int32_t i) |
5 | Plagman | 612 | { |
3095 | terminx | 613 | if (g_spriteDeleteQueueSize == 0) |
5 | Plagman | 614 | { |
2452 | helixhorne | 615 | A_DeleteSprite(i); |
612 | terminx | 616 | return; |
5 | Plagman | 617 | } |
618 | |||
1143 | terminx | 619 | if (SpriteDeletionQueue[g_spriteDeleteQueuePos] >= 0) |
620 | sprite[SpriteDeletionQueue[g_spriteDeleteQueuePos]].xrepeat = 0; |
||
621 | SpriteDeletionQueue[g_spriteDeleteQueuePos] = i; |
||
622 | g_spriteDeleteQueuePos = (g_spriteDeleteQueuePos+1)%g_spriteDeleteQueueSize; |
||
5 | Plagman | 623 | } |
624 | |||
1205 | terminx | 625 | void A_SpawnMultiple(int32_t sp, int32_t pic, int32_t n) |
5 | Plagman | 626 | { |
1205 | terminx | 627 | int32_t j; |
511 | terminx | 628 | spritetype *s = &sprite[sp]; |
522 | terminx | 629 | |
1229 | terminx | 630 | for (; n>0; n--) |
5 | Plagman | 631 | { |
1143 | terminx | 632 | j = A_InsertSprite(s->sectnum,s->x,s->y,s->z-(krand()%(47<<8)),pic,-32,8,8,krand()&2047,0,0,sp,5); |
633 | A_Spawn(-1, j); |
||
634 | sprite[j].cstat = krand()&12; |
||
5 | Plagman | 635 | } |
636 | } |
||
637 | |||
1205 | terminx | 638 | void A_DoGuts(int32_t sp, int32_t gtype, int32_t n) |
5 | Plagman | 639 | { |
1205 | terminx | 640 | int32_t gutz,floorz; |
641 | int32_t i,a,j,sx = 32,sy = 32; |
||
5 | Plagman | 642 | |
3679 | helixhorne | 643 | const spritetype *const s = &sprite[sp]; |
644 | |||
1143 | terminx | 645 | if (A_CheckEnemySprite(s) && s->xrepeat < 16) |
5 | Plagman | 646 | sx = sy = 8; |
647 | |||
648 | gutz = s->z-(8<<8); |
||
649 | floorz = getflorzofslope(s->sectnum,s->x,s->y); |
||
650 | |||
333 | terminx | 651 | if (gutz > (floorz-(8<<8))) |
5 | Plagman | 652 | gutz = floorz-(8<<8); |
653 | |||
331 | terminx | 654 | if (s->picnum == COMMANDER) |
5 | Plagman | 655 | gutz -= (24<<8); |
656 | |||
1229 | terminx | 657 | for (j=n; j>0; j--) |
5 | Plagman | 658 | { |
1143 | terminx | 659 | a = krand()&2047; |
660 | i = A_InsertSprite(s->sectnum,s->x+(krand()&255)-128,s->y+(krand()&255)-128,gutz-(krand()&8191),gtype,-32,sx,sy,a,48+(krand()&31),-512-(krand()&2047),sp,5); |
||
331 | terminx | 661 | if (PN == JIBS2) |
5 | Plagman | 662 | { |
663 | sprite[i].xrepeat >>= 2; |
||
664 | sprite[i].yrepeat >>= 2; |
||
665 | } |
||
3679 | helixhorne | 666 | |
935 | terminx | 667 | sprite[i].pal = s->pal; |
5 | Plagman | 668 | } |
669 | } |
||
670 | |||
1205 | terminx | 671 | void A_DoGutsDir(int32_t sp, int32_t gtype, int32_t n) |
5 | Plagman | 672 | { |
1205 | terminx | 673 | int32_t gutz,floorz; |
674 | int32_t i,a,j,sx = 32,sy = 32; |
||
3679 | helixhorne | 675 | const spritetype *const s = &sprite[sp]; |
522 | terminx | 676 | |
1143 | terminx | 677 | if (A_CheckEnemySprite(s) && s->xrepeat < 16) |
5 | Plagman | 678 | sx = sy = 8; |
679 | |||
680 | gutz = s->z-(8<<8); |
||
681 | floorz = getflorzofslope(s->sectnum,s->x,s->y); |
||
682 | |||
333 | terminx | 683 | if (gutz > (floorz-(8<<8))) |
5 | Plagman | 684 | gutz = floorz-(8<<8); |
685 | |||
331 | terminx | 686 | if (s->picnum == COMMANDER) |
5 | Plagman | 687 | gutz -= (24<<8); |
688 | |||
1229 | terminx | 689 | for (j=n; j>0; j--) |
5 | Plagman | 690 | { |
1143 | terminx | 691 | a = krand()&2047; |
692 | i = A_InsertSprite(s->sectnum,s->x,s->y,gutz,gtype,-32,sx,sy,a,256+(krand()&127),-512-(krand()&2047),sp,5); |
||
935 | terminx | 693 | sprite[i].pal = s->pal; |
5 | Plagman | 694 | } |
695 | } |
||
696 | |||
3645 | helixhorne | 697 | LUNATIC_EXTERN int32_t G_ToggleWallInterpolation(int32_t w, int32_t doset) |
5 | Plagman | 698 | { |
3486 | helixhorne | 699 | if (doset) |
5 | Plagman | 700 | { |
3486 | helixhorne | 701 | return G_SetInterpolation(&wall[w].x) |
702 | || G_SetInterpolation(&wall[w].y); |
||
5 | Plagman | 703 | } |
3486 | helixhorne | 704 | else |
705 | { |
||
706 | G_StopInterpolation(&wall[w].x); |
||
707 | G_StopInterpolation(&wall[w].y); |
||
708 | return 0; |
||
709 | } |
||
5 | Plagman | 710 | } |
711 | |||
4745 | terminx | 712 | void Sect_ToggleInterpolation(int sectnum, int doset) |
5 | Plagman | 713 | { |
4745 | terminx | 714 | int k, j = sector[sectnum].wallptr; |
715 | const int endwall = sector[sectnum].wallptr + sector[sectnum].wallnum; |
||
511 | terminx | 716 | |
1229 | terminx | 717 | for (; j<endwall; j++) |
5 | Plagman | 718 | { |
3486 | helixhorne | 719 | G_ToggleWallInterpolation(j, doset); |
720 | |||
1708 | helixhorne | 721 | k = wall[j].nextwall; |
722 | if (k >= 0) |
||
5 | Plagman | 723 | { |
3486 | helixhorne | 724 | G_ToggleWallInterpolation(k, doset); |
725 | G_ToggleWallInterpolation(wall[k].point2, doset); |
||
5 | Plagman | 726 | } |
727 | } |
||
728 | } |
||
729 | |||
3316 | helixhorne | 730 | static int32_t move_rotfixed_sprite(int32_t j, int32_t pivotspr, int32_t daang) |
1913 | helixhorne | 731 | { |
3316 | helixhorne | 732 | if ((ROTFIXSPR_STATNUMP(sprite[j].statnum) || |
4745 | terminx | 733 | ((sprite[j].statnum == STAT_ACTOR || sprite[j].statnum == STAT_ZOMBIEACTOR) && |
734 | A_CheckSpriteTileFlags(sprite[j].picnum, SFLAG_ROTFIXED))) && |
||
735 | actor[j].t_data[7] == (ROTFIXSPR_MAGIC | pivotspr)) |
||
1913 | helixhorne | 736 | { |
4745 | terminx | 737 | rotatepoint(0, 0, actor[j].t_data[8], actor[j].t_data[9], daang & 2047, &sprite[j].x, &sprite[j].y); |
1913 | helixhorne | 738 | sprite[j].x += sprite[pivotspr].x; |
739 | sprite[j].y += sprite[pivotspr].y; |
||
740 | return 0; |
||
741 | } |
||
742 | |||
743 | return 1; |
||
744 | } |
||
745 | |||
4745 | terminx | 746 | static void A_MoveSector(int i) |
5 | Plagman | 747 | { |
4745 | terminx | 748 | // T1,T2 and T3 are used for all the sector moving stuff!!! |
749 | spritetype * const s = &sprite[i]; |
||
750 | int j = T2, k = T3; |
||
751 | int32_t tx, ty; |
||
5 | Plagman | 752 | |
4745 | terminx | 753 | s->x += (s->xvel * (sintable[(s->ang + 512) & 2047])) >> 14; |
754 | s->y += (s->xvel * (sintable[s->ang & 2047])) >> 14; |
||
5 | Plagman | 755 | |
4745 | terminx | 756 | const int endwall = sector[s->sectnum].wallptr + sector[s->sectnum].wallnum; |
5 | Plagman | 757 | |
4745 | terminx | 758 | for (i = sector[s->sectnum].wallptr; i < endwall; i++) |
5 | Plagman | 759 | { |
4745 | terminx | 760 | rotatepoint(0, 0, msx[j], msy[j], k & 2047, &tx, &ty); |
761 | dragpoint(i, s->x + tx, s->y + ty, 0); |
||
511 | terminx | 762 | |
4745 | terminx | 763 | j++; |
5 | Plagman | 764 | } |
765 | } |
||
766 | |||
3680 | helixhorne | 767 | #if !defined LUNATIC |
3920 | helixhorne | 768 | // NOTE: T5 is AC_ACTION_ID |
4745 | terminx | 769 | # define LIGHTRAD_PICOFS (T5 ? *(script + T5) + (*(script + T5 + 2)) * AC_CURFRAME(actor[i].t_data) : 0) |
2669 | helixhorne | 770 | #else |
2864 | helixhorne | 771 | // startframe + viewtype*[cyclic counter] |
4745 | terminx | 772 | # define LIGHTRAD_PICOFS (actor[i].ac.startframe + actor[i].ac.viewtype * AC_CURFRAME(actor[i].t_data)) |
2669 | helixhorne | 773 | #endif |
2185 | helixhorne | 774 | |
1409 | terminx | 775 | // this is the same crap as in game.c's tspr manipulation. puke. |
3920 | helixhorne | 776 | // XXX: may access tilesizy out-of-bounds by bad user code. |
4623 | terminx | 777 | #define LIGHTRAD (s->yrepeat * tilesiz[s->picnum + LIGHTRAD_PICOFS].y) |
4745 | terminx | 778 | #define LIGHTRAD2 (((s->yrepeat) + (rand() % (s->yrepeat >> 2))) * tilesiz[s->picnum + LIGHTRAD_PICOFS].y) |
1409 | terminx | 779 | |
1677 | terminx | 780 | void G_AddGameLight(int32_t radius, int32_t srcsprite, int32_t zoffset, int32_t range, int32_t color, int32_t priority) |
1402 | terminx | 781 | { |
782 | #ifdef POLYMER |
||
1423 | terminx | 783 | spritetype *s = &sprite[srcsprite]; |
784 | |||
3346 | terminx | 785 | if (getrendermode() != REND_POLYMER) |
1414 | plagman | 786 | return; |
787 | |||
1625 | terminx | 788 | if (actor[srcsprite].lightptr == NULL) |
1402 | terminx | 789 | { |
4745 | terminx | 790 | #pragma pack(push, 1) |
1402 | terminx | 791 | _prlight mylight; |
1457 | terminx | 792 | #pragma pack(pop) |
1941 | helixhorne | 793 | Bmemset(&mylight, 0, sizeof(mylight)); |
1402 | terminx | 794 | |
795 | mylight.sector = s->sectnum; |
||
796 | mylight.x = s->x; |
||
797 | mylight.y = s->y; |
||
4745 | terminx | 798 | mylight.z = s->z - zoffset; |
799 | mylight.color[0] = color & 255; |
||
800 | mylight.color[1] = (color >> 8) & 255; |
||
801 | mylight.color[2] = (color >> 16) & 255; |
||
1402 | terminx | 802 | mylight.radius = radius; |
1625 | terminx | 803 | actor[srcsprite].lightmaxrange = mylight.range = range; |
1402 | terminx | 804 | |
805 | mylight.priority = priority; |
||
1524 | plagman | 806 | mylight.tilenum = 0; |
1402 | terminx | 807 | |
3092 | Plagman | 808 | mylight.publicflags.emitshadow = 1; |
809 | mylight.publicflags.negative = 0; |
||
810 | |||
1625 | terminx | 811 | actor[srcsprite].lightId = polymer_addlight(&mylight); |
812 | if (actor[srcsprite].lightId >= 0) |
||
813 | actor[srcsprite].lightptr = &prlights[actor[srcsprite].lightId]; |
||
1402 | terminx | 814 | return; |
815 | } |
||
816 | |||
817 | s->z -= zoffset; |
||
1425 | terminx | 818 | |
4745 | terminx | 819 | if (range<actor[srcsprite].lightmaxrange>> 1) |
1625 | terminx | 820 | actor[srcsprite].lightmaxrange = 0; |
1430 | terminx | 821 | |
4745 | terminx | 822 | if (range > actor[srcsprite].lightmaxrange || priority != actor[srcsprite].lightptr->priority || |
823 | Bmemcmp(&sprite[srcsprite], actor[srcsprite].lightptr, sizeof(int32_t) * 3)) |
||
1402 | terminx | 824 | { |
1625 | terminx | 825 | if (range > actor[srcsprite].lightmaxrange) |
826 | actor[srcsprite].lightmaxrange = range; |
||
1410 | terminx | 827 | |
1625 | terminx | 828 | Bmemcpy(actor[srcsprite].lightptr, &sprite[srcsprite], sizeof(int32_t) * 3); |
829 | actor[srcsprite].lightptr->sector = s->sectnum; |
||
830 | actor[srcsprite].lightptr->flags.invalidate = 1; |
||
1402 | terminx | 831 | } |
1409 | terminx | 832 | |
1625 | terminx | 833 | actor[srcsprite].lightptr->priority = priority; |
834 | actor[srcsprite].lightptr->range = range; |
||
4745 | terminx | 835 | actor[srcsprite].lightptr->color[0] = color & 255; |
836 | actor[srcsprite].lightptr->color[1] = (color >> 8) & 255; |
||
837 | actor[srcsprite].lightptr->color[2] = (color >> 16) & 255; |
||
1409 | terminx | 838 | |
1402 | terminx | 839 | s->z += zoffset; |
840 | |||
841 | #else |
||
842 | UNREFERENCED_PARAMETER(radius); |
||
1488 | terminx | 843 | UNREFERENCED_PARAMETER(srcsprite); |
844 | UNREFERENCED_PARAMETER(zoffset); |
||
1402 | terminx | 845 | UNREFERENCED_PARAMETER(range); |
846 | UNREFERENCED_PARAMETER(color); |
||
847 | UNREFERENCED_PARAMETER(priority); |
||
848 | #endif |
||
849 | } |
||
850 | |||
1143 | terminx | 851 | // sleeping monsters, etc |
1595 | helixhorne | 852 | ACTOR_STATIC void G_MoveZombieActors(void) |
5 | Plagman | 853 | { |
3679 | helixhorne | 854 | int32_t i = headspritestat[STAT_ZOMBIEACTOR], j; |
5 | Plagman | 855 | |
331 | terminx | 856 | while (i >= 0) |
5 | Plagman | 857 | { |
3679 | helixhorne | 858 | const int32_t nexti = nextspritestat[i]; |
5 | Plagman | 859 | |
3679 | helixhorne | 860 | int32_t x; |
861 | spritetype *const s = &sprite[i]; |
||
862 | const int32_t p = A_FindPlayer(s,&x); |
||
5 | Plagman | 863 | |
3679 | helixhorne | 864 | int16_t ssect = s->sectnum; |
865 | int16_t psect = s->sectnum; |
||
5 | Plagman | 866 | |
564 | terminx | 867 | if (sprite[g_player[p].ps->i].extra > 0) |
5 | Plagman | 868 | { |
333 | terminx | 869 | if (x < 30000) |
5 | Plagman | 870 | { |
1625 | terminx | 871 | actor[i].timetosleep++; |
872 | if (actor[i].timetosleep >= (x>>8)) |
||
5 | Plagman | 873 | { |
1143 | terminx | 874 | if (A_CheckEnemySprite(s)) |
5 | Plagman | 875 | { |
3679 | helixhorne | 876 | const int32_t px = g_player[p].ps->opos.x+64-(krand()&127); |
877 | const int32_t py = g_player[p].ps->opos.y+64-(krand()&127); |
||
878 | int32_t sx, sy; |
||
879 | |||
376 | terminx | 880 | updatesector(px,py,&psect); |
331 | terminx | 881 | if (psect == -1) |
5 | Plagman | 882 | { |
883 | i = nexti; |
||
884 | continue; |
||
885 | } |
||
3679 | helixhorne | 886 | |
1143 | terminx | 887 | sx = s->x+64-(krand()&127); |
888 | sy = s->y+64-(krand()&127); |
||
376 | terminx | 889 | updatesector(px,py,&ssect); |
331 | terminx | 890 | if (ssect == -1) |
5 | Plagman | 891 | { |
892 | i = nexti; |
||
893 | continue; |
||
894 | } |
||
3679 | helixhorne | 895 | |
896 | j = cansee(sx,sy,s->z-(krand()%(52<<8)),s->sectnum, px,py, |
||
897 | g_player[p].ps->opos.z-(krand()%(32<<8)),g_player[p].ps->cursectnum); |
||
5 | Plagman | 898 | } |
899 | else |
||
3679 | helixhorne | 900 | j = cansee(s->x,s->y,s->z-((krand()&31)<<8),s->sectnum, g_player[p].ps->opos.x,g_player[p].ps->opos.y, |
901 | g_player[p].ps->opos.z-((krand()&31)<<8), g_player[p].ps->cursectnum); |
||
5 | Plagman | 902 | |
2652 | terminx | 903 | if (j) |
904 | { |
||
2653 | terminx | 905 | switch (DYNAMICTILEMAP(s->picnum)) |
5 | Plagman | 906 | { |
337 | terminx | 907 | case RUBBERCAN__STATIC: |
908 | case EXPLODINGBARREL__STATIC: |
||
909 | case WOODENHORSE__STATIC: |
||
910 | case HORSEONSIDE__STATIC: |
||
911 | case CANWITHSOMETHING__STATIC: |
||
912 | case CANWITHSOMETHING2__STATIC: |
||
913 | case CANWITHSOMETHING3__STATIC: |
||
914 | case CANWITHSOMETHING4__STATIC: |
||
915 | case FIREBARREL__STATIC: |
||
916 | case FIREVASE__STATIC: |
||
917 | case NUKEBARREL__STATIC: |
||
918 | case NUKEBARRELDENTED__STATIC: |
||
919 | case NUKEBARRELLEAKED__STATIC: |
||
920 | case TRIPBOMB__STATIC: |
||
4477 | helixhorne | 921 | if (sector[s->sectnum].ceilingstat&1 && A_CheckSpriteFlags(i,SFLAG_NOSHADE) == 0) |
337 | terminx | 922 | s->shade = sector[s->sectnum].ceilingshade; |
923 | else s->shade = sector[s->sectnum].floorshade; |
||
5 | Plagman | 924 | |
1625 | terminx | 925 | actor[i].timetosleep = 0; |
2642 | helixhorne | 926 | changespritestat(i, STAT_STANDABLE); |
337 | terminx | 927 | break; |
3679 | helixhorne | 928 | |
1336 | terminx | 929 | case RECON__STATIC: |
930 | CS |= 257; |
||
3679 | helixhorne | 931 | // fall-through |
337 | terminx | 932 | default: |
4351 | helixhorne | 933 | if (A_CheckSpriteFlags(i, SFLAG_USEACTIVATOR) && sector[sprite[i].sectnum].lotag & 16384) |
1457 | terminx | 934 | break; |
1625 | terminx | 935 | actor[i].timetosleep = 0; |
1143 | terminx | 936 | A_PlayAlertSound(i); |
1344 | terminx | 937 | changespritestat(i, STAT_ACTOR); |
337 | terminx | 938 | break; |
5 | Plagman | 939 | } |
2652 | terminx | 940 | } |
1625 | terminx | 941 | else actor[i].timetosleep = 0; |
5 | Plagman | 942 | } |
943 | } |
||
3679 | helixhorne | 944 | |
4351 | helixhorne | 945 | if (A_CheckEnemySprite(s) && A_CheckSpriteFlags(i,SFLAG_NOSHADE) == 0) |
5 | Plagman | 946 | { |
947 | if (sector[s->sectnum].ceilingstat&1) |
||
948 | s->shade = sector[s->sectnum].ceilingshade; |
||
949 | else s->shade = sector[s->sectnum].floorshade; |
||
950 | } |
||
951 | } |
||
3679 | helixhorne | 952 | |
5 | Plagman | 953 | i = nexti; |
954 | } |
||
955 | } |
||
956 | |||
2993 | terminx | 957 | // stupid name, but it's what the function does. |
4745 | terminx | 958 | FORCE_INLINE int G_FindExplosionInSector(int sectnum) |
5 | Plagman | 959 | { |
4745 | terminx | 960 | for (int SPRITES_OF(STAT_MISC, i)) |
333 | terminx | 961 | if (PN == EXPLOSION2 && sectnum == SECT) |
5 | Plagman | 962 | return i; |
3679 | helixhorne | 963 | |
5 | Plagman | 964 | return -1; |
965 | } |
||
966 | |||
4745 | terminx | 967 | FORCE_INLINE void P_Nudge(int p, int sn, int shl) |
2874 | helixhorne | 968 | { |
4745 | terminx | 969 | g_player[p].ps->vel.x += actor[sn].extra * (sintable[(actor[sn].ang + 512) & 2047]) << shl; |
970 | g_player[p].ps->vel.y += actor[sn].extra * (sintable[actor[sn].ang & 2047]) << shl; |
||
2874 | helixhorne | 971 | } |
972 | |||
1205 | terminx | 973 | int32_t A_IncurDamage(int32_t sn) |
5 | Plagman | 974 | { |
3053 | terminx | 975 | spritetype *const targ = &sprite[sn]; |
976 | actor_t *const dmg = &actor[sn]; |
||
5 | Plagman | 977 | |
3626 | helixhorne | 978 | // dmg->picnum check: safety, since it might have been set to <0 from CON. |
979 | if (dmg->extra < 0 || targ->extra < 0 || dmg->picnum < 0) |
||
5 | Plagman | 980 | { |
3053 | terminx | 981 | dmg->extra = -1; |
982 | return -1; |
||
983 | } |
||
5 | Plagman | 984 | |
3053 | terminx | 985 | if (targ->picnum == APLAYER) |
986 | { |
||
4745 | terminx | 987 | const int p = P_GetP(targ); |
5 | Plagman | 988 | |
4745 | terminx | 989 | if (ud.god && dmg->picnum != SHRINKSPARK) |
990 | return -1; |
||
5 | Plagman | 991 | |
3053 | terminx | 992 | if (dmg->owner >= 0 && ud.ffire == 0 && sprite[dmg->owner].picnum == APLAYER && |
993 | (GametypeFlags[ud.coop] & GAMETYPE_PLAYERSFRIENDLY || |
||
4226 | helixhorne | 994 | (GametypeFlags[ud.coop] & GAMETYPE_TDM && g_player[p].ps->team == g_player[P_Get(dmg->owner)].ps->team))) |
3053 | terminx | 995 | return -1; |
5 | Plagman | 996 | |
3053 | terminx | 997 | targ->extra -= dmg->extra; |
268 | terminx | 998 | |
3053 | terminx | 999 | if (dmg->owner >= 0 && targ->extra <= 0 && dmg->picnum != FREEZEBLAST) |
1000 | { |
||
4226 | helixhorne | 1001 | const int32_t ow = dmg->owner; |
1002 | |||
3053 | terminx | 1003 | targ->extra = 0; |
5 | Plagman | 1004 | |
4226 | helixhorne | 1005 | g_player[p].ps->wackedbyactor = ow; |
5 | Plagman | 1006 | |
4226 | helixhorne | 1007 | if (sprite[ow].picnum == APLAYER && p != P_Get(ow)) |
1008 | g_player[p].ps->frag_ps = P_Get(ow); |
||
5 | Plagman | 1009 | |
3053 | terminx | 1010 | dmg->owner = g_player[p].ps->i; |
1011 | } |
||
5 | Plagman | 1012 | |
3053 | terminx | 1013 | switch (DYNAMICTILEMAP(dmg->picnum)) |
1014 | { |
||
4745 | terminx | 1015 | case RADIUSEXPLOSION__STATIC: |
1016 | case RPG__STATIC: |
||
1017 | case HYDRENT__STATIC: |
||
1018 | case HEAVYHBOMB__STATIC: |
||
1019 | case SEENINE__STATIC: |
||
1020 | case OOZFILTER__STATIC: |
||
1021 | case EXPLODINGBARREL__STATIC: |
||
1022 | P_Nudge(p, sn, 2); |
||
1023 | break; |
||
3679 | helixhorne | 1024 | |
4745 | terminx | 1025 | default: |
1026 | if (A_CheckSpriteTileFlags(dmg->picnum, SFLAG_PROJECTILE) && |
||
1027 | (SpriteProjectile[sn].workslike & PROJECTILE_RPG)) |
||
1028 | P_Nudge(p, sn, 2); |
||
1029 | else |
||
1030 | P_Nudge(p, sn, 1); |
||
1031 | break; |
||
3053 | terminx | 1032 | } |
5 | Plagman | 1033 | |
3053 | terminx | 1034 | dmg->extra = -1; |
1035 | return dmg->picnum; |
||
1036 | } |
||
5 | Plagman | 1037 | |
4745 | terminx | 1038 | if (dmg->extra == 0 && dmg->picnum == SHRINKSPARK && targ->xrepeat < 24) |
1039 | return -1; |
||
5 | Plagman | 1040 | |
3053 | terminx | 1041 | targ->extra -= dmg->extra; |
5 | Plagman | 1042 | |
3053 | terminx | 1043 | if (targ->picnum != RECON && targ->owner >= 0 && sprite[targ->owner].statnum < MAXSTATUS) |
1044 | targ->owner = dmg->owner; |
||
5 | Plagman | 1045 | |
3053 | terminx | 1046 | dmg->extra = -1; |
4745 | terminx | 1047 | |
3053 | terminx | 1048 | return dmg->picnum; |
5 | Plagman | 1049 | } |
1050 | |||
1143 | terminx | 1051 | void A_MoveCyclers(void) |
5 | Plagman | 1052 | { |
3053 | terminx | 1053 | int32_t i; |
5 | Plagman | 1054 | |
3053 | terminx | 1055 | for (i=g_numCyclers-1; i>=0; i--) |
5 | Plagman | 1056 | { |
3679 | helixhorne | 1057 | int16_t *const c = cyclers[i]; |
1058 | const int32_t sect = c[0]; |
||
1059 | const int32_t t = c[3]; |
||
1060 | int32_t j = t + (sintable[c[1]&2047]>>10); |
||
3053 | terminx | 1061 | int32_t cshade = c[2]; |
5 | Plagman | 1062 | |
3679 | helixhorne | 1063 | if (j < cshade) |
1064 | j = cshade; |
||
1065 | else if (j > t) |
||
1066 | j = t; |
||
5 | Plagman | 1067 | |
3053 | terminx | 1068 | c[1] += sector[sect].extra; |
1069 | |||
331 | terminx | 1070 | if (c[5]) |
5 | Plagman | 1071 | { |
3053 | terminx | 1072 | walltype *wal = &wall[sector[sect].wallptr]; |
1073 | int32_t x; |
||
1074 | |||
1075 | for (x = sector[sect].wallnum; x>0; x--,wal++) |
||
1076 | { |
||
333 | terminx | 1077 | if (wal->hitag != 1) |
5 | Plagman | 1078 | { |
1079 | wal->shade = j; |
||
1080 | |||
333 | terminx | 1081 | if ((wal->cstat&2) && wal->nextwall >= 0) |
5 | Plagman | 1082 | wall[wal->nextwall].shade = j; |
3053 | terminx | 1083 | } |
1084 | } |
||
5 | Plagman | 1085 | |
3053 | terminx | 1086 | sector[sect].floorshade = sector[sect].ceilingshade = j; |
5 | Plagman | 1087 | } |
1088 | } |
||
1089 | } |
||
1090 | |||
1143 | terminx | 1091 | void A_MoveDummyPlayers(void) |
5 | Plagman | 1092 | { |
3679 | helixhorne | 1093 | int32_t i = headspritestat[STAT_DUMMYPLAYER]; |
5 | Plagman | 1094 | |
331 | terminx | 1095 | while (i >= 0) |
5 | Plagman | 1096 | { |
4226 | helixhorne | 1097 | const int32_t p = P_Get(OW); |
2876 | helixhorne | 1098 | DukePlayer_t *const ps = g_player[p].ps; |
2342 | helixhorne | 1099 | |
3679 | helixhorne | 1100 | const int32_t nexti = nextspritestat[i]; |
1101 | const int32_t psectnum = ps->cursectnum; |
||
5 | Plagman | 1102 | |
3073 | helixhorne | 1103 | if (ps->on_crane >= 0 || (psectnum >= 0 && sector[psectnum].lotag != ST_1_ABOVE_WATER) || sprite[ps->i].extra <= 0) |
5 | Plagman | 1104 | { |
2876 | helixhorne | 1105 | ps->dummyplayersprite = -1; |
5 | Plagman | 1106 | KILLIT(i); |
1107 | } |
||
1108 | else |
||
1109 | { |
||
3073 | helixhorne | 1110 | if (ps->on_ground && ps->on_warping_sector == 1 && psectnum >= 0 && sector[psectnum].lotag == ST_1_ABOVE_WATER) |
5 | Plagman | 1111 | { |
1112 | CS = 257; |
||
1113 | SZ = sector[SECT].ceilingz+(27<<8); |
||
2876 | helixhorne | 1114 | SA = ps->ang; |
331 | terminx | 1115 | if (T1 == 8) |
5 | Plagman | 1116 | T1 = 0; |
1117 | else T1++; |
||
1118 | } |
||
1119 | else |
||
1120 | { |
||
3073 | helixhorne | 1121 | if (sector[SECT].lotag != ST_2_UNDERWATER) SZ = sector[SECT].floorz; |
3211 | helixhorne | 1122 | CS = 32768; |
5 | Plagman | 1123 | } |
1124 | } |
||
1125 | |||
2876 | helixhorne | 1126 | SX += (ps->pos.x-ps->opos.x); |
1127 | SY += (ps->pos.y-ps->opos.y); |
||
3075 | helixhorne | 1128 | setsprite(i, (vec3_t *)&sprite[i]); |
5 | Plagman | 1129 | |
1130 | BOLT: |
||
1131 | i = nexti; |
||
1132 | } |
||
1133 | } |
||
1134 | |||
3072 | helixhorne | 1135 | |
1136 | static int32_t P_Submerge(int32_t j, int32_t p, DukePlayer_t *ps, int32_t sect, int32_t othersect); |
||
1137 | static int32_t P_Emerge(int32_t j, int32_t p, DukePlayer_t *ps, int32_t sect, int32_t othersect); |
||
1138 | static void P_FinishWaterChange(int32_t j, DukePlayer_t *ps, int32_t sectlotag, int32_t ow, int32_t newsectnum); |
||
1139 | |||
1595 | helixhorne | 1140 | ACTOR_STATIC void G_MovePlayers(void) |
5 | Plagman | 1141 | { |
2876 | helixhorne | 1142 | int32_t i = headspritestat[STAT_PLAYER]; |
5 | Plagman | 1143 | |
331 | terminx | 1144 | while (i >= 0) |
5 | Plagman | 1145 | { |
2876 | helixhorne | 1146 | const int32_t nexti = nextspritestat[i]; |
5 | Plagman | 1147 | |
3073 | helixhorne | 1148 | spritetype *const s = &sprite[i]; |
4226 | helixhorne | 1149 | DukePlayer_t *const p = g_player[P_GetP(s)].ps; |
2876 | helixhorne | 1150 | |
331 | terminx | 1151 | if (s->owner >= 0) |
5 | Plagman | 1152 | { |
333 | terminx | 1153 | if (p->newowner >= 0) //Looking thru the camera |
5 | Plagman | 1154 | { |
1625 | terminx | 1155 | s->x = p->opos.x; |
1156 | s->y = p->opos.y; |
||
3314 | helixhorne | 1157 | actor[i].bpos.z = s->z = p->opos.z+PHEIGHT; |
5 | Plagman | 1158 | s->ang = p->oang; |
1208 | terminx | 1159 | setsprite(i,(vec3_t *)s); |
5 | Plagman | 1160 | } |
1161 | else |
||
1162 | { |
||
3072 | helixhorne | 1163 | int32_t otherx; |
1164 | #ifdef YAX_ENABLE |
||
1165 | // TROR water submerge/emerge |
||
1166 | const int32_t psect=s->sectnum, slotag=sector[psect].lotag; |
||
3678 | helixhorne | 1167 | int32_t othersect; |
3072 | helixhorne | 1168 | |
3678 | helixhorne | 1169 | if (A_CheckNoSE7Water(s, psect, slotag, &othersect)) |
3072 | helixhorne | 1170 | { |
3678 | helixhorne | 1171 | int32_t k = 0; |
3072 | helixhorne | 1172 | |
3678 | helixhorne | 1173 | // NOTE: Compare with G_MoveTransports(). |
1174 | p->on_warping_sector = 1; |
||
3677 | helixhorne | 1175 | |
3678 | helixhorne | 1176 | if (slotag==ST_1_ABOVE_WATER) |
4226 | helixhorne | 1177 | k = P_Submerge(i, P_GetP(s), p, psect, othersect); |
3678 | helixhorne | 1178 | else |
4226 | helixhorne | 1179 | k = P_Emerge(i, P_GetP(s), p, psect, othersect); |
3072 | helixhorne | 1180 | |
3678 | helixhorne | 1181 | if (k == 1) |
1182 | P_FinishWaterChange(i, p, slotag, -1, othersect); |
||
3072 | helixhorne | 1183 | } |
1184 | #endif |
||
2925 | helixhorne | 1185 | if (g_netServer || ud.multimode > 1) |
4226 | helixhorne | 1186 | otherp = P_FindOtherPlayer(P_GetP(s), &otherx); |
5 | Plagman | 1187 | else |
1188 | { |
||
4226 | helixhorne | 1189 | otherp = P_GetP(s); |
5 | Plagman | 1190 | otherx = 0; |
1191 | } |
||
1192 | |||
3344 | helixhorne | 1193 | if (G_HaveActor(sprite[i].picnum)) |
4226 | helixhorne | 1194 | A_Execute(i, P_GetP(s), otherx); |
5 | Plagman | 1195 | |
2925 | helixhorne | 1196 | if (g_netServer || ud.multimode > 1) |
564 | terminx | 1197 | if (sprite[g_player[otherp].ps->i].extra > 0) |
5 | Plagman | 1198 | { |
564 | terminx | 1199 | if (s->yrepeat > 32 && sprite[g_player[otherp].ps->i].yrepeat < 32) |
5 | Plagman | 1200 | { |
333 | terminx | 1201 | if (otherx < 1400 && p->knee_incs == 0) |
5 | Plagman | 1202 | { |
1203 | p->knee_incs = 1; |
||
1204 | p->weapon_pos = -1; |
||
564 | terminx | 1205 | p->actorsqu = g_player[otherp].ps->i; |
5 | Plagman | 1206 | } |
1207 | } |
||
1208 | } |
||
3053 | terminx | 1209 | |
331 | terminx | 1210 | if (ud.god) |
5 | Plagman | 1211 | { |
566 | terminx | 1212 | s->extra = p->max_player_health; |
5 | Plagman | 1213 | s->cstat = 257; |
1572 | terminx | 1214 | p->inv_amount[GET_JETPACK] = 1599; |
5 | Plagman | 1215 | } |
1216 | |||
333 | terminx | 1217 | if (s->extra > 0) |
5 | Plagman | 1218 | { |
1625 | terminx | 1219 | actor[i].owner = i; |
5 | Plagman | 1220 | |
331 | terminx | 1221 | if (ud.god == 0) |
1143 | terminx | 1222 | if (G_CheckForSpaceCeiling(s->sectnum) || G_CheckForSpaceFloor(s->sectnum)) |
1223 | P_QuickKill(p); |
||
5 | Plagman | 1224 | } |
1225 | else |
||
1226 | { |
||
1625 | terminx | 1227 | p->pos.x = s->x; |
1228 | p->pos.y = s->y; |
||
1229 | p->pos.z = s->z-(20<<8); |
||
5 | Plagman | 1230 | |
1231 | p->newowner = -1; |
||
1232 | |||
333 | terminx | 1233 | if (p->wackedbyactor >= 0 && sprite[p->wackedbyactor].statnum < MAXSTATUS) |
5 | Plagman | 1234 | { |
1625 | terminx | 1235 | p->ang += G_GetAngleDelta(p->ang,getangle(sprite[p->wackedbyactor].x-p->pos.x,sprite[p->wackedbyactor].y-p->pos.y))>>1; |
5 | Plagman | 1236 | p->ang &= 2047; |
1237 | } |
||
3053 | terminx | 1238 | } |
5 | Plagman | 1239 | |
1240 | s->ang = p->ang; |
||
1241 | } |
||
1242 | } |
||
1243 | else |
||
1244 | { |
||
331 | terminx | 1245 | if (p->holoduke_on == -1) |
5 | Plagman | 1246 | KILLIT(i); |
1247 | |||
4132 | helixhorne | 1248 | Bmemcpy(&actor[i].bpos, s, sizeof(vec3_t)); |
5 | Plagman | 1249 | s->cstat = 0; |
1250 | |||
331 | terminx | 1251 | if (s->xrepeat < 42) |
5 | Plagman | 1252 | { |
1253 | s->xrepeat += 4; |
||
1254 | s->cstat |= 2; |
||
1255 | } |
||
1256 | else s->xrepeat = 42; |
||
3053 | terminx | 1257 | |
331 | terminx | 1258 | if (s->yrepeat < 36) |
5 | Plagman | 1259 | s->yrepeat += 4; |
1260 | else |
||
1261 | { |
||
1262 | s->yrepeat = 36; |
||
3073 | helixhorne | 1263 | if (sector[s->sectnum].lotag != ST_2_UNDERWATER) |
1143 | terminx | 1264 | A_Fall(i); |
3073 | helixhorne | 1265 | if (s->zvel == 0 && sector[s->sectnum].lotag == ST_1_ABOVE_WATER) |
5 | Plagman | 1266 | s->z += (32<<8); |
1267 | } |
||
1268 | |||
331 | terminx | 1269 | if (s->extra < 8) |
5 | Plagman | 1270 | { |
1271 | s->xvel = 128; |
||
1272 | s->ang = p->ang; |
||
1273 | s->extra++; |
||
1143 | terminx | 1274 | A_SetSprite(i,CLIPMASK0); |
5 | Plagman | 1275 | } |
1276 | else |
||
1277 | { |
||
1278 | s->ang = 2047-p->ang; |
||
1208 | terminx | 1279 | setsprite(i,(vec3_t *)s); |
5 | Plagman | 1280 | } |
1281 | } |
||
1282 | |||
1283 | if (sector[s->sectnum].ceilingstat&1) |
||
4392 | helixhorne | 1284 | s->shade = logapproach(s->shade, sector[s->sectnum].ceilingshade); |
5 | Plagman | 1285 | else |
4392 | helixhorne | 1286 | s->shade = logapproach(s->shade, sector[s->sectnum].floorshade); |
5 | Plagman | 1287 | |
1288 | BOLT: |
||
1289 | i = nexti; |
||
1290 | } |
||
1291 | } |
||
1292 | |||
1595 | helixhorne | 1293 | ACTOR_STATIC void G_MoveFX(void) |
5 | Plagman | 1294 | { |
2887 | helixhorne | 1295 | int32_t i = headspritestat[STAT_FX]; |
5 | Plagman | 1296 | |
331 | terminx | 1297 | while (i >= 0) |
5 | Plagman | 1298 | { |
2887 | helixhorne | 1299 | spritetype *const s = &sprite[i]; |
1300 | const int32_t nexti = nextspritestat[i]; |
||
5 | Plagman | 1301 | |
2297 | helixhorne | 1302 | switch (DYNAMICTILEMAP(s->picnum)) |
5 | Plagman | 1303 | { |
337 | terminx | 1304 | case RESPAWN__STATIC: |
1305 | if (sprite[i].extra == 66) |
||
1306 | { |
||
2887 | helixhorne | 1307 | /*int32_t j =*/ A_Spawn(i,SHT); |
337 | terminx | 1308 | // sprite[j].pal = sprite[i].pal; |
1309 | KILLIT(i); |
||
1310 | } |
||
1311 | else if (sprite[i].extra > (66-13)) |
||
1312 | sprite[i].extra++; |
||
1313 | break; |
||
5 | Plagman | 1314 | |
337 | terminx | 1315 | case MUSICANDSFX__STATIC: |
2885 | helixhorne | 1316 | { |
1317 | const int32_t ht = s->hitag; |
||
2887 | helixhorne | 1318 | DukePlayer_t *const peekps = g_player[screenpeek].ps; |
5 | Plagman | 1319 | |
563 | terminx | 1320 | if (T2 != ud.config.SoundToggle) |
337 | terminx | 1321 | { |
3822 | helixhorne | 1322 | // If sound playback was toggled, restart. |
563 | terminx | 1323 | T2 = ud.config.SoundToggle; |
337 | terminx | 1324 | T1 = 0; |
1325 | } |
||
1326 | |||
1327 | if (s->lotag >= 1000 && s->lotag < 2000) |
||
1328 | { |
||
2887 | helixhorne | 1329 | int32_t x = ldist(&sprite[peekps->i],s); |
2885 | helixhorne | 1330 | |
4249 | hendricks2 | 1331 | #ifdef SPLITSCREEN_MOD_HACKS |
2957 | helixhorne | 1332 | if (g_fakeMultiMode==2) |
2885 | helixhorne | 1333 | { |
1334 | // HACK for splitscreen mod |
||
1335 | int32_t otherdist = ldist(&sprite[g_player[1].ps->i],s); |
||
1336 | x = min(x, otherdist); |
||
1337 | } |
||
4249 | hendricks2 | 1338 | #endif |
2885 | helixhorne | 1339 | |
337 | terminx | 1340 | if (x < ht && T1 == 0) |
5 | Plagman | 1341 | { |
337 | terminx | 1342 | FX_SetReverb(s->lotag - 1000); |
1343 | T1 = 1; |
||
5 | Plagman | 1344 | } |
337 | terminx | 1345 | if (x >= ht && T1 == 1) |
5 | Plagman | 1346 | { |
337 | terminx | 1347 | FX_SetReverb(0); |
1348 | FX_SetReverbDelay(0); |
||
1349 | T1 = 0; |
||
5 | Plagman | 1350 | } |
337 | terminx | 1351 | } |
3008 | helixhorne | 1352 | else if (s->lotag < 999 && (unsigned)sector[s->sectnum].lotag < 9 && // ST_9_SLIDING_ST_DOOR |
2887 | helixhorne | 1353 | ud.config.AmbienceToggle && sector[SECT].floorz != sector[SECT].ceilingz) |
337 | terminx | 1354 | { |
4055 | helixhorne | 1355 | if (g_sounds[s->lotag].m & SF_MSFX) |
5 | Plagman | 1356 | { |
2887 | helixhorne | 1357 | int32_t x = dist(&sprite[peekps->i],s); |
2885 | helixhorne | 1358 | |
4249 | hendricks2 | 1359 | #ifdef SPLITSCREEN_MOD_HACKS |
2957 | helixhorne | 1360 | if (g_fakeMultiMode==2) |
2885 | helixhorne | 1361 | { |
1362 | // HACK for splitscreen mod |
||
1363 | int32_t otherdist = dist(&sprite[g_player[1].ps->i],s); |
||
1364 | x = min(x, otherdist); |
||
1365 | } |
||
4249 | hendricks2 | 1366 | #endif |
2885 | helixhorne | 1367 | |
580 | terminx | 1368 | if (x < ht && T1 == 0 && FX_VoiceAvailable(g_sounds[s->lotag].pr-1)) |
5 | Plagman | 1369 | { |
3822 | helixhorne | 1370 | // Start playing an ambience sound. |
1371 | |||
3336 | hendricks2 | 1372 | char om = g_sounds[s->lotag].m; |
1143 | terminx | 1373 | if (g_numEnvSoundsPlaying == ud.config.NumVoices) |
5 | Plagman | 1374 | { |
2887 | helixhorne | 1375 | int32_t j; |
1376 | |||
1377 | for (SPRITES_OF(STAT_FX, j)) |
||
3680 | helixhorne | 1378 | if (j != i && S_IsAmbientSFX(j) && actor[j].t_data[0] == 1 && |
2887 | helixhorne | 1379 | dist(&sprite[j], &sprite[peekps->i]) > x) |
5 | Plagman | 1380 | { |
1143 | terminx | 1381 | S_StopEnvSound(sprite[j].lotag,j); |
337 | terminx | 1382 | break; |
5 | Plagman | 1383 | } |
2887 | helixhorne | 1384 | |
1385 | if (j == -1) |
||
1386 | goto BOLT; |
||
5 | Plagman | 1387 | } |
2887 | helixhorne | 1388 | |
4055 | helixhorne | 1389 | g_sounds[s->lotag].m |= SF_LOOP; |
1143 | terminx | 1390 | A_PlaySound(s->lotag,i); |
3336 | hendricks2 | 1391 | g_sounds[s->lotag].m = om; |
4352 | helixhorne | 1392 | T1 = 1; // AMBIENT_SFX_PLAYING |
5 | Plagman | 1393 | } |
2887 | helixhorne | 1394 | else if (x >= ht && T1 == 1) |
5 | Plagman | 1395 | { |
3822 | helixhorne | 1396 | // Stop playing ambience sound because we're out of its range. |
1397 | |||
4352 | helixhorne | 1398 | // T1 will be reset in sounds.c: CLEAR_SOUND_T0 |
1599 | terminx | 1399 | // T1 = 0; |
1143 | terminx | 1400 | S_StopEnvSound(s->lotag,i); |
5 | Plagman | 1401 | } |
1402 | } |
||
2887 | helixhorne | 1403 | |
4055 | helixhorne | 1404 | if (g_sounds[s->lotag].m & SF_GLOBAL) |
337 | terminx | 1405 | { |
2887 | helixhorne | 1406 | // Randomly playing global sounds (flyby of planes, screams, ...) |
1407 | |||
1408 | if (T5 > 0) |
||
1409 | T5--; |
||
1143 | terminx | 1410 | else |
2876 | helixhorne | 1411 | { |
1412 | int32_t p; |
||
2379 | helixhorne | 1413 | for (TRAVERSE_CONNECT(p)) |
1414 | if (p == myconnectindex && g_player[p].ps->cursectnum == s->sectnum) |
||
1415 | { |
||
3679 | helixhorne | 1416 | S_PlaySound(s->lotag + (unsigned)g_globalRandom % (s->hitag+1)); |
1417 | T5 = GAMETICSPERSEC*40 + g_globalRandom%(GAMETICSPERSEC*40); |
||
2379 | helixhorne | 1418 | } |
2876 | helixhorne | 1419 | } |
337 | terminx | 1420 | } |
1421 | } |
||
1422 | break; |
||
5 | Plagman | 1423 | } |
2885 | helixhorne | 1424 | } |
5 | Plagman | 1425 | BOLT: |
1426 | i = nexti; |
||
1427 | } |
||
1428 | } |
||
1429 | |||
1595 | helixhorne | 1430 | ACTOR_STATIC void G_MoveFallers(void) |
5 | Plagman | 1431 | { |
3679 | helixhorne | 1432 | int32_t i = headspritestat[STAT_FALLER]; |
5 | Plagman | 1433 | |
331 | terminx | 1434 | while (i >= 0) |
5 | Plagman | 1435 | { |
3679 | helixhorne | 1436 | const int32_t nexti = nextspritestat[i]; |
1437 | spritetype *const s = &sprite[i]; |
||
5 | Plagman | 1438 | |
3679 | helixhorne | 1439 | const int32_t sect = s->sectnum; |
5 | Plagman | 1440 | |
333 | terminx | 1441 | if (T1 == 0) |
5 | Plagman | 1442 | { |
3679 | helixhorne | 1443 | int32_t j; |
1444 | const int32_t oextra = s->extra; |
||
1445 | |||
5 | Plagman | 1446 | s->z -= (16<<8); |
1447 | T2 = s->ang; |
||
1802 | terminx | 1448 | if ((j = A_IncurDamage(i)) >= 0) |
5 | Plagman | 1449 | { |
333 | terminx | 1450 | if (j == FIREEXT || j == RPG || j == RADIUSEXPLOSION || j == SEENINE || j == OOZFILTER) |
559 | terminx | 1451 | { |
1452 | if (s->extra <= 0) |
||
5 | Plagman | 1453 | { |
1454 | T1 = 1; |
||
3679 | helixhorne | 1455 | |
1456 | for (SPRITES_OF(STAT_FALLER, j)) |
||
5 | Plagman | 1457 | { |
331 | terminx | 1458 | if (sprite[j].hitag == SHT) |
5 | Plagman | 1459 | { |
1625 | terminx | 1460 | actor[j].t_data[0] = 1; |
5 | Plagman | 1461 | sprite[j].cstat &= (65535-64); |
331 | terminx | 1462 | if (sprite[j].picnum == CEILINGSTEAM || sprite[j].picnum == STEAM) |
5 | Plagman | 1463 | sprite[j].cstat |= 32768; |
1464 | } |
||
1465 | } |
||
1466 | } |
||
1467 | } |
||
1468 | else |
||
1469 | { |
||
1625 | terminx | 1470 | actor[i].extra = 0; |
3679 | helixhorne | 1471 | s->extra = oextra; |
5 | Plagman | 1472 | } |
1473 | } |
||
1474 | s->ang = T2; |
||
1475 | s->z += (16<<8); |
||
1476 | } |
||
331 | terminx | 1477 | else if (T1 == 1) |
5 | Plagman | 1478 | { |
3210 | helixhorne | 1479 | if ((int16_t)s->lotag > 0) |
5 | Plagman | 1480 | { |
1481 | s->lotag-=3; |
||
3210 | helixhorne | 1482 | if ((int16_t)s->lotag <= 0) |
5 | Plagman | 1483 | { |
1143 | terminx | 1484 | s->xvel = (32+(krand()&63)); |
1485 | s->zvel = -(1024+(krand()&1023)); |
||
5 | Plagman | 1486 | } |
1487 | } |
||
1488 | else |
||
1489 | { |
||
3679 | helixhorne | 1490 | int32_t x; |
1491 | |||
333 | terminx | 1492 | if (s->xvel > 0) |
5 | Plagman | 1493 | { |
1494 | s->xvel -= 8; |
||
1143 | terminx | 1495 | A_SetSprite(i,CLIPMASK0); |
5 | Plagman | 1496 | } |
1497 | |||
4699 | terminx | 1498 | if (EDUKE32_PREDICT_FALSE(G_CheckForSpaceFloor(s->sectnum))) |
1150 | terminx | 1499 | x = 0; |
5 | Plagman | 1500 | else |
1501 | { |
||
4699 | terminx | 1502 | if (EDUKE32_PREDICT_FALSE(G_CheckForSpaceCeiling(s->sectnum))) |
1150 | terminx | 1503 | x = g_spriteGravity/6; |
5 | Plagman | 1504 | else |
1150 | terminx | 1505 | x = g_spriteGravity; |
5 | Plagman | 1506 | } |
1507 | |||
1677 | terminx | 1508 | if (s->z < (sector[sect].floorz-ZOFFSET)) |
5 | Plagman | 1509 | { |
1510 | s->zvel += x; |
||
331 | terminx | 1511 | if (s->zvel > 6144) |
5 | Plagman | 1512 | s->zvel = 6144; |
1513 | s->z += s->zvel; |
||
1514 | } |
||
333 | terminx | 1515 | if ((sector[sect].floorz-s->z) < (16<<8)) |
5 | Plagman | 1516 | { |
3679 | helixhorne | 1517 | int32_t j = 1+(krand()&7); |
1229 | terminx | 1518 | for (x=0; x<j; x++) RANDOMSCRAP; |
5 | Plagman | 1519 | KILLIT(i); |
1520 | } |
||
1521 | } |
||
1522 | } |
||
1523 | |||
1524 | BOLT: |
||
1525 | i = nexti; |
||
1526 | } |
||
1527 | } |
||
1528 | |||
1595 | helixhorne | 1529 | ACTOR_STATIC void G_MoveStandables(void) |
5 | Plagman | 1530 | { |
3679 | helixhorne | 1531 | int32_t i = headspritestat[STAT_STANDABLE], j, switchpicnum; |
1205 | terminx | 1532 | int32_t l=0, x; |
2451 | helixhorne | 1533 | |
331 | terminx | 1534 | while (i >= 0) |
5 | Plagman | 1535 | { |
3679 | helixhorne | 1536 | const int32_t nexti = nextspritestat[i]; |
5 | Plagman | 1537 | |
3679 | helixhorne | 1538 | int32_t *const t = &actor[i].t_data[0]; |
1539 | spritetype *const s = &sprite[i]; |
||
1540 | const int32_t sect = s->sectnum; |
||
5 | Plagman | 1541 | |
2609 | helixhorne | 1542 | if (sect < 0) |
1543 | KILLIT(i); |
||
5 | Plagman | 1544 | |
3682 | helixhorne | 1545 | // Rotation-fixed sprites in rotating sectors already have bpos* updated. |
3316 | helixhorne | 1546 | if ((t[7]&(0xffff0000))!=ROTFIXSPR_MAGIC) |
4132 | helixhorne | 1547 | Bmemcpy(&actor[i].bpos, s, sizeof(vec3_t)); |
5 | Plagman | 1548 | |
3647 | helixhorne | 1549 | if (PN >= CRANE && PN <= CRANE+3) |
5 | Plagman | 1550 | { |
3679 | helixhorne | 1551 | int32_t nextj; |
1552 | |||
5 | Plagman | 1553 | //t[0] = state |
1554 | //t[1] = checking sector number |
||
1555 | |||
1143 | terminx | 1556 | if (s->xvel) A_GetZLimits(i); |
5 | Plagman | 1557 | |
333 | terminx | 1558 | if (t[0] == 0) //Waiting to check the sector |
5 | Plagman | 1559 | { |
3679 | helixhorne | 1560 | for (SPRITES_OF_SECT_SAFE(t[1], j, nextj)) |
5 | Plagman | 1561 | { |
333 | terminx | 1562 | switch (sprite[j].statnum) |
5 | Plagman | 1563 | { |
1487 | terminx | 1564 | case STAT_ACTOR: |
1565 | case STAT_ZOMBIEACTOR: |
||
1566 | case STAT_STANDABLE: |
||
1567 | case STAT_PLAYER: |
||
3679 | helixhorne | 1568 | { |
1569 | vec3_t vect = { msx[t[4]+1], msy[t[4]+1], sprite[j].z }; |
||
1208 | terminx | 1570 | |
3679 | helixhorne | 1571 | s->ang = getangle(vect.x-s->x, vect.y-s->y); |
1572 | setsprite(j, &vect); |
||
1573 | t[0]++; |
||
1574 | goto BOLT; |
||
5 | Plagman | 1575 | } |
3679 | helixhorne | 1576 | } |
5 | Plagman | 1577 | } |
1578 | } |
||
1579 | |||
331 | terminx | 1580 | else if (t[0]==1) |
5 | Plagman | 1581 | { |
333 | terminx | 1582 | if (s->xvel < 184) |
5 | Plagman | 1583 | { |
1584 | s->picnum = CRANE+1; |
||
1585 | s->xvel += 8; |
||
1586 | } |
||
1143 | terminx | 1587 | A_SetSprite(i,CLIPMASK0); |
331 | terminx | 1588 | if (sect == t[1]) |
5 | Plagman | 1589 | t[0]++; |
1590 | } |
||
331 | terminx | 1591 | else if (t[0]==2 || t[0]==7) |
5 | Plagman | 1592 | { |
1593 | s->z += (1024+512); |
||
1594 | |||
331 | terminx | 1595 | if (t[0]==2) |
5 | Plagman | 1596 | { |
3679 | helixhorne | 1597 | if (sector[sect].floorz - s->z < (64<<8)) |
331 | terminx | 1598 | if (s->picnum > CRANE) s->picnum--; |
5 | Plagman | 1599 | |
3679 | helixhorne | 1600 | if (sector[sect].floorz - s->z < 4096+1024) |
5 | Plagman | 1601 | t[0]++; |
1602 | } |
||
3679 | helixhorne | 1603 | |
331 | terminx | 1604 | if (t[0]==7) |
5 | Plagman | 1605 | { |
3679 | helixhorne | 1606 | if (sector[sect].floorz - s->z < (64<<8)) |
5 | Plagman | 1607 | { |
331 | terminx | 1608 | if (s->picnum > CRANE) s->picnum--; |
5 | Plagman | 1609 | else |
1610 | { |
||
331 | terminx | 1611 | if (s->owner==-2) |
5 | Plagman | 1612 | { |
3680 | helixhorne | 1613 | int32_t p = A_FindPlayer(s, NULL); |
1143 | terminx | 1614 | A_PlaySound(DUKE_GRUNT,g_player[p].ps->i); |
564 | terminx | 1615 | if (g_player[p].ps->on_crane == i) |
1616 | g_player[p].ps->on_crane = -1; |
||
5 | Plagman | 1617 | } |
3679 | helixhorne | 1618 | |
5 | Plagman | 1619 | t[0]++; |
1620 | s->owner = -1; |
||
1621 | } |
||
1622 | } |
||
1623 | } |
||
1624 | } |
||
331 | terminx | 1625 | else if (t[0]==3) |
5 | Plagman | 1626 | { |
1627 | s->picnum++; |
||
3679 | helixhorne | 1628 | if (s->picnum == CRANE+2) |
5 | Plagman | 1629 | { |
2876 | helixhorne | 1630 | int32_t p = G_CheckPlayerInSector(t[1]); |
3679 | helixhorne | 1631 | |
564 | terminx | 1632 | if (p >= 0 && g_player[p].ps->on_ground) |
5 | Plagman | 1633 | { |
1634 | s->owner = -2; |
||
564 | terminx | 1635 | g_player[p].ps->on_crane = i; |
1143 | terminx | 1636 | A_PlaySound(DUKE_GRUNT,g_player[p].ps->i); |
564 | terminx | 1637 | g_player[p].ps->ang = s->ang+1024; |
5 | Plagman | 1638 | } |
1639 | else |
||
1640 | { |
||
3679 | helixhorne | 1641 | for (SPRITES_OF_SECT(t[1], j)) |
5 | Plagman | 1642 | { |
333 | terminx | 1643 | switch (sprite[j].statnum) |
5 | Plagman | 1644 | { |
1487 | terminx | 1645 | case STAT_ACTOR: |
1646 | case STAT_STANDABLE: |
||
337 | terminx | 1647 | s->owner = j; |
1648 | break; |
||
5 | Plagman | 1649 | } |
1650 | } |
||
1651 | } |
||
1652 | |||
1653 | t[0]++;//Grabbed the sprite |
||
1654 | t[2]=0; |
||
1655 | goto BOLT; |
||
1656 | } |
||
1657 | } |
||
331 | terminx | 1658 | else if (t[0]==4) //Delay before going up |
5 | Plagman | 1659 | { |
1660 | t[2]++; |
||
331 | terminx | 1661 | if (t[2] > 10) |
5 | Plagman | 1662 | t[0]++; |
1663 | } |
||
331 | terminx | 1664 | else if (t[0]==5 || t[0] == 8) |
5 | Plagman | 1665 | { |
331 | terminx | 1666 | if (t[0]==8 && s->picnum < (CRANE+2)) |
333 | terminx | 1667 | if ((sector[sect].floorz-s->z) > 8192) |
5 | Plagman | 1668 | s->picnum++; |
1669 | |||
331 | terminx | 1670 | if (s->z < msx[t[4]+2]) |
5 | Plagman | 1671 | { |
1672 | t[0]++; |
||
1673 | s->xvel = 0; |
||
1674 | } |
||
1675 | else |
||
1676 | s->z -= (1024+512); |
||
1677 | } |
||
331 | terminx | 1678 | else if (t[0]==6) |
5 | Plagman | 1679 | { |
333 | terminx | 1680 | if (s->xvel < 192) |
5 | Plagman | 1681 | s->xvel += 8; |
1682 | s->ang = getangle(msx[t[4]]-s->x,msy[t[4]]-s->y); |
||
1143 | terminx | 1683 | A_SetSprite(i,CLIPMASK0); |
333 | terminx | 1684 | if (((s->x-msx[t[4]])*(s->x-msx[t[4]])+(s->y-msy[t[4]])*(s->y-msy[t[4]])) < (128*128)) |
5 | Plagman | 1685 | t[0]++; |
1686 | } |
||
1687 | |||
331 | terminx | 1688 | else if (t[0]==9) |
5 | Plagman | 1689 | t[0] = 0; |
1690 | |||
1208 | terminx | 1691 | { |
1692 | vec3_t vect; |
||
1693 | Bmemcpy(&vect,s,sizeof(vec3_t)); |
||
1694 | vect.z -= (34<<8); |
||
1695 | setsprite(msy[t[4]+2],&vect); |
||
1696 | } |
||
5 | Plagman | 1697 | |
1208 | terminx | 1698 | |
331 | terminx | 1699 | if (s->owner != -1) |
5 | Plagman | 1700 | { |
3680 | helixhorne | 1701 | int32_t p = A_FindPlayer(s, NULL); |
5 | Plagman | 1702 | |
3680 | helixhorne | 1703 | if (A_IncurDamage(i) >= 0) |
5 | Plagman | 1704 | { |
331 | terminx | 1705 | if (s->owner == -2) |
564 | terminx | 1706 | if (g_player[p].ps->on_crane == i) |
1707 | g_player[p].ps->on_crane = -1; |
||
559 | terminx | 1708 | s->owner = -1; |
1709 | s->picnum = CRANE; |
||
1710 | goto BOLT; |
||
1711 | } |
||
5 | Plagman | 1712 | |
559 | terminx | 1713 | if (s->owner >= 0) |
1714 | { |
||
1208 | terminx | 1715 | setsprite(s->owner,(vec3_t *)s); |
5 | Plagman | 1716 | |
4132 | helixhorne | 1717 | Bmemcpy(&actor[s->owner].bpos, s, sizeof(vec3_t)); |
5 | Plagman | 1718 | |
559 | terminx | 1719 | s->zvel = 0; |
1720 | } |
||
1721 | else if (s->owner == -2) |
||
1722 | { |
||
2875 | helixhorne | 1723 | DukePlayer_t *const ps = g_player[p].ps; |
1208 | terminx | 1724 | |
2875 | helixhorne | 1725 | ps->opos.x = ps->pos.x = s->x-(sintable[(ps->ang+512)&2047]>>6); |
1726 | ps->opos.y = ps->pos.y = s->y-(sintable[ps->ang&2047]>>6); |
||
1727 | ps->opos.z = ps->pos.z = s->z+(2<<8); |
||
1728 | |||
1729 | setsprite(ps->i, (vec3_t *)ps); |
||
1730 | ps->cursectnum = sprite[ps->i].sectnum; |
||
559 | terminx | 1731 | } |
5 | Plagman | 1732 | } |
1733 | |||
1734 | goto BOLT; |
||
1735 | } |
||
1736 | |||
3647 | helixhorne | 1737 | if (PN >= WATERFOUNTAIN && PN <= WATERFOUNTAIN+3) |
5 | Plagman | 1738 | { |
331 | terminx | 1739 | if (t[0] > 0) |
5 | Plagman | 1740 | { |
333 | terminx | 1741 | if (t[0] < 20) |
5 | Plagman | 1742 | { |
1743 | t[0]++; |
||
1744 | |||
1745 | s->picnum++; |
||
1746 | |||
333 | terminx | 1747 | if (s->picnum == (WATERFOUNTAIN+3)) |
5 | Plagman | 1748 | s->picnum = WATERFOUNTAIN+1; |
1749 | } |
||
1750 | else |
||
1751 | { |
||
2876 | helixhorne | 1752 | A_FindPlayer(s,&x); |
5 | Plagman | 1753 | |
331 | terminx | 1754 | if (x > 512) |
5 | Plagman | 1755 | { |
1756 | t[0] = 0; |
||
1757 | s->picnum = WATERFOUNTAIN; |
||
1758 | } |
||
1759 | else t[0] = 1; |
||
1760 | } |
||
1761 | } |
||
1762 | goto BOLT; |
||
1763 | } |
||
1764 | |||
333 | terminx | 1765 | if (AFLAMABLE(s->picnum)) |
5 | Plagman | 1766 | { |
331 | terminx | 1767 | if (T1 == 1) |
5 | Plagman | 1768 | { |
1769 | T2++; |
||
333 | terminx | 1770 | if ((T2&3) > 0) goto BOLT; |
5 | Plagman | 1771 | |
333 | terminx | 1772 | if (s->picnum == TIRE && T2 == 32) |
5 | Plagman | 1773 | { |
1774 | s->cstat = 0; |
||
1143 | terminx | 1775 | j = A_Spawn(i,BLOODPOOL); |
5 | Plagman | 1776 | sprite[j].shade = 127; |
1777 | } |
||
1778 | else |
||
1779 | { |
||
331 | terminx | 1780 | if (s->shade < 64) s->shade++; |
5 | Plagman | 1781 | else KILLIT(i); |
1782 | } |
||
1783 | |||
1143 | terminx | 1784 | j = s->xrepeat-(krand()&7); |
331 | terminx | 1785 | if (j < 10) |
5 | Plagman | 1786 | KILLIT(i); |
1787 | |||
1788 | s->xrepeat = j; |
||
1789 | |||
1143 | terminx | 1790 | j = s->yrepeat-(krand()&7); |
335 | terminx | 1791 | if (j < 4) |
1792 | KILLIT(i); |
||
2609 | helixhorne | 1793 | |
5 | Plagman | 1794 | s->yrepeat = j; |
1795 | } |
||
331 | terminx | 1796 | if (s->picnum == BOX) |
5 | Plagman | 1797 | { |
1143 | terminx | 1798 | A_Fall(i); |
1625 | terminx | 1799 | actor[i].ceilingz = sector[s->sectnum].ceilingz; |
5 | Plagman | 1800 | } |
1801 | goto BOLT; |
||
1802 | } |
||
1803 | |||
331 | terminx | 1804 | if (s->picnum == TRIPBOMB) |
5 | Plagman | 1805 | { |
4256 | helixhorne | 1806 | // TIMER_CONTROL |
1625 | terminx | 1807 | if (actor[i].t_data[6] == 1) |
5 | Plagman | 1808 | { |
1809 | |||
1625 | terminx | 1810 | if (actor[i].t_data[7] >= 1) |
5 | Plagman | 1811 | { |
1625 | terminx | 1812 | actor[i].t_data[7]--; |
5 | Plagman | 1813 | } |
1814 | |||
1625 | terminx | 1815 | if (actor[i].t_data[7] <= 0) |
5 | Plagman | 1816 | { |
1817 | T3=16; |
||
1625 | terminx | 1818 | actor[i].t_data[6]=3; |
1143 | terminx | 1819 | A_PlaySound(LASERTRIP_ARMING,i); |
5 | Plagman | 1820 | } |
1821 | // we're on a timer.... |
||
1822 | } |
||
1625 | terminx | 1823 | if (T3 > 0 && actor[i].t_data[6] == 3) |
5 | Plagman | 1824 | { |
1825 | T3--; |
||
1625 | terminx | 1826 | |
331 | terminx | 1827 | if (T3 == 8) |
5 | Plagman | 1828 | { |
1229 | terminx | 1829 | for (j=0; j<5; j++) RANDOMSCRAP; |
5 | Plagman | 1830 | x = s->extra; |
1143 | terminx | 1831 | A_RadiusDamage(i, g_tripbombBlastRadius, x>>2,x>>1,x-(x>>2),x); |
5 | Plagman | 1832 | |
1143 | terminx | 1833 | j = A_Spawn(i,EXPLOSION2); |
1665 | terminx | 1834 | A_PlaySound(LASERTRIP_EXPLODE,j); |
5 | Plagman | 1835 | sprite[j].ang = s->ang; |
1836 | sprite[j].xvel = 348; |
||
1143 | terminx | 1837 | A_SetSprite(j,CLIPMASK0); |
5 | Plagman | 1838 | |
3679 | helixhorne | 1839 | for (SPRITES_OF(STAT_MISC, j)) |
5 | Plagman | 1840 | { |
331 | terminx | 1841 | if (sprite[j].picnum == LASERLINE && s->hitag == sprite[j].hitag) |
5 | Plagman | 1842 | sprite[j].xrepeat = sprite[j].yrepeat = 0; |
1843 | } |
||
2609 | helixhorne | 1844 | |
5 | Plagman | 1845 | KILLIT(i); |
1846 | } |
||
1847 | goto BOLT; |
||
1848 | } |
||
1849 | else |
||
1850 | { |
||
3679 | helixhorne | 1851 | const int32_t oextra = s->extra; |
5 | Plagman | 1852 | s->extra = 1; |
1853 | l = s->ang; |
||
3679 | helixhorne | 1854 | if (A_IncurDamage(i) >= 0) |
1855 | { |
||
1856 | actor[i].t_data[6] = 3; |
||
1857 | T3 = 16; |
||
1858 | } |
||
1859 | s->extra = oextra; |
||
5 | Plagman | 1860 | s->ang = l; |
1861 | } |
||
1862 | |||
1677 | terminx | 1863 | switch (T1) |
5 | Plagman | 1864 | { |
1625 | terminx | 1865 | default: |
2876 | helixhorne | 1866 | A_FindPlayer(s,&x); |
1625 | terminx | 1867 | if (x > 768 || T1 > 16) T1++; |
1868 | break; |
||
1869 | |||
1870 | case 32: |
||
3680 | helixhorne | 1871 | { |
1872 | int16_t m; |
||
1873 | |||
5 | Plagman | 1874 | l = s->ang; |
1875 | s->ang = T6; |
||
1876 | |||
335 | terminx | 1877 | T4 = s->x; |
1878 | T5 = s->y; |
||
1625 | terminx | 1879 | |
5 | Plagman | 1880 | s->x += sintable[(T6+512)&2047]>>9; |
1881 | s->y += sintable[(T6)&2047]>>9; |
||
1882 | s->z -= (3<<8); |
||
1625 | terminx | 1883 | |
1208 | terminx | 1884 | setsprite(i,(vec3_t *)s); |
5 | Plagman | 1885 | |
3680 | helixhorne | 1886 | x = A_CheckHitSprite(i, &m); |
5 | Plagman | 1887 | |
1625 | terminx | 1888 | actor[i].lastvx = x; |
5 | Plagman | 1889 | |
1890 | s->ang = l; |
||
1891 | |||
1892 | // if(lTripBombControl & TRIPBOMB_TRIPWIRE) |
||
1625 | terminx | 1893 | if (actor[i].t_data[6] != 1) |
5 | Plagman | 1894 | { |
1895 | // we're on a trip wire |
||
2072 | hendricks2 | 1896 | int16_t cursectnum; |
5 | Plagman | 1897 | |
331 | terminx | 1898 | while (x > 0) |
5 | Plagman | 1899 | { |
1143 | terminx | 1900 | j = A_Spawn(i,LASERLINE); |
1208 | terminx | 1901 | setsprite(j,(vec3_t *)&sprite[j]); |
5 | Plagman | 1902 | sprite[j].hitag = s->hitag; |
1625 | terminx | 1903 | actor[j].t_data[1] = sprite[j].z; |
5 | Plagman | 1904 | |
1905 | s->x += sintable[(T6+512)&2047]>>4; |
||
1906 | s->y += sintable[(T6)&2047]>>4; |
||
1907 | |||
333 | terminx | 1908 | if (x < 1024) |
5 | Plagman | 1909 | { |
1910 | sprite[j].xrepeat = x>>5; |
||
1911 | break; |
||
1912 | } |
||
1913 | x -= 1024; |
||
2072 | hendricks2 | 1914 | |
1915 | cursectnum = s->sectnum; |
||
1916 | updatesector(s->x, s->y, &cursectnum); |
||
1917 | if (cursectnum < 0) |
||
1918 | break; |
||
5 | Plagman | 1919 | } |
1920 | } |
||
1625 | terminx | 1921 | |
5 | Plagman | 1922 | T1++; |
1625 | terminx | 1923 | |
335 | terminx | 1924 | s->x = T4; |
1925 | s->y = T5; |
||
5 | Plagman | 1926 | s->z += (3<<8); |
1625 | terminx | 1927 | |
1208 | terminx | 1928 | setsprite(i,(vec3_t *)s); |
1625 | terminx | 1929 | T4 = T3 = 0; |
1930 | |||
1931 | if (m >= 0 && actor[i].t_data[6] != 1) |
||
5 | Plagman | 1932 | { |
1625 | terminx | 1933 | actor[i].t_data[6] = 3; |
5 | Plagman | 1934 | T3 = 13; |
1143 | terminx | 1935 | A_PlaySound(LASERTRIP_ARMING,i); |
5 | Plagman | 1936 | } |
1625 | terminx | 1937 | break; |
3680 | helixhorne | 1938 | } |
1625 | terminx | 1939 | |
1940 | case 33: |
||
5 | Plagman | 1941 | T2++; |
1942 | |||
335 | terminx | 1943 | T4 = s->x; |
1944 | T5 = s->y; |
||
1625 | terminx | 1945 | |
5 | Plagman | 1946 | s->x += sintable[(T6+512)&2047]>>9; |
1947 | s->y += sintable[(T6)&2047]>>9; |
||
1948 | s->z -= (3<<8); |
||
1625 | terminx | 1949 | |
1208 | terminx | 1950 | setsprite(i,(vec3_t *)s); |
5 | Plagman | 1951 | |
3680 | helixhorne | 1952 | x = A_CheckHitSprite(i, NULL); |
5 | Plagman | 1953 | |
335 | terminx | 1954 | s->x = T4; |
1955 | s->y = T5; |
||
5 | Plagman | 1956 | s->z += (3<<8); |
1208 | terminx | 1957 | setsprite(i,(vec3_t *)s); |
5 | Plagman | 1958 | |
3679 | helixhorne | 1959 | // if( Actor[i].lastvx != x && lTripBombControl & TRIPBOMB_TRIPWIRE) |
1625 | terminx | 1960 | if (actor[i].lastvx != x && actor[i].t_data[6] != 1) |
5 | Plagman | 1961 | { |
1625 | terminx | 1962 | actor[i].t_data[6] = 3; |
5 | Plagman | 1963 | T3 = 13; |
1143 | terminx | 1964 | A_PlaySound(LASERTRIP_ARMING,i); |
5 | Plagman | 1965 | } |
1625 | terminx | 1966 | break; |
5 | Plagman | 1967 | } |
1625 | terminx | 1968 | |
5 | Plagman | 1969 | goto BOLT; |
1970 | } |
||
1971 | |||
333 | terminx | 1972 | if (s->picnum >= CRACK1 && s->picnum <= CRACK4) |
5 | Plagman | 1973 | { |
331 | terminx | 1974 | if (s->hitag > 0) |
5 | Plagman | 1975 | { |
3681 | helixhorne | 1976 | int32_t k; |
1977 | |||
5 | Plagman | 1978 | t[0] = s->cstat; |
1979 | t[1] = s->ang; |
||
3053 | terminx | 1980 | |
3681 | helixhorne | 1981 | k = A_IncurDamage(i); |
3743 | helixhorne | 1982 | if (k < 0) |
1983 | goto crack_default; |
||
3681 | helixhorne | 1984 | |
3743 | helixhorne | 1985 | switch (DYNAMICTILEMAP(k)) |
1986 | { |
||
1987 | case FIREEXT__STATIC: |
||
1988 | case RPG__STATIC: |
||
1989 | case RADIUSEXPLOSION__STATIC: |
||
1990 | case SEENINE__STATIC: |
||
1991 | case OOZFILTER__STATIC: |
||
1992 | for (SPRITES_OF(STAT_STANDABLE, j)) |
||
5 | Plagman | 1993 | { |
3743 | helixhorne | 1994 | if (s->hitag == sprite[j].hitag && (sprite[j].picnum == OOZFILTER || sprite[j].picnum == SEENINE)) |
1995 | if (sprite[j].shade != -32) |
||
1996 | sprite[j].shade = -32; |
||
1997 | } |
||
5 | Plagman | 1998 | |
3743 | helixhorne | 1999 | goto DETONATE; |
3053 | terminx | 2000 | |
3743 | helixhorne | 2001 | crack_default: |
2002 | default: |
||
2003 | s->cstat = t[0]; |
||
2004 | s->ang = t[1]; |
||
2005 | s->extra = 0; |
||
3681 | helixhorne | 2006 | |
3743 | helixhorne | 2007 | goto BOLT; |
2008 | } |
||
5 | Plagman | 2009 | } |
2010 | goto BOLT; |
||
2011 | } |
||
2012 | |||
333 | terminx | 2013 | if (s->picnum == FIREEXT) |
5 | Plagman | 2014 | { |
3679 | helixhorne | 2015 | int32_t k; |
2016 | |||
3626 | helixhorne | 2017 | if (A_IncurDamage(i) < 0) |
3053 | terminx | 2018 | goto BOLT; |
5 | Plagman | 2019 | |
1229 | terminx | 2020 | for (k=0; k<16; k++) |
5 | Plagman | 2021 | { |
1143 | terminx | 2022 | j = A_InsertSprite(SECT,SX,SY,SZ-(krand()%(48<<8)),SCRAP3+(krand()&3),-8,48,48,krand()&2047,(krand()&63)+64,-(krand()&4095)-(sprite[i].zvel>>2),i,5); |
5 | Plagman | 2023 | sprite[j].pal = 2; |
2024 | } |
||
2025 | |||
1665 | terminx | 2026 | j = A_Spawn(i,EXPLOSION2); |
2027 | A_PlaySound(PIPEBOMB_EXPLODE,j); |
||
2028 | A_PlaySound(GLASS_HEAVYBREAK,j); |
||
5 | Plagman | 2029 | |
3210 | helixhorne | 2030 | if ((int16_t)s->hitag > 0) |
5 | Plagman | 2031 | { |
3679 | helixhorne | 2032 | for (SPRITES_OF(STAT_STANDABLE, j)) |
5 | Plagman | 2033 | { |
3679 | helixhorne | 2034 | // XXX: This block seems to be CODEDUP'd a lot of times. |
333 | terminx | 2035 | if (s->hitag == sprite[j].hitag && (sprite[j].picnum == OOZFILTER || sprite[j].picnum == SEENINE)) |
331 | terminx | 2036 | if (sprite[j].shade != -32) |
5 | Plagman | 2037 | sprite[j].shade = -32; |
2038 | } |
||
2039 | |||
2040 | x = s->extra; |
||
1143 | terminx | 2041 | A_RadiusDamage(i, g_pipebombBlastRadius,x>>2, x-(x>>1),x-(x>>2), x); |
1665 | terminx | 2042 | j = A_Spawn(i,EXPLOSION2); |
2043 | A_PlaySound(PIPEBOMB_EXPLODE,j); |
||
5 | Plagman | 2044 | |
2045 | goto DETONATE; |
||
2046 | } |
||
2047 | else |
||
2048 | { |
||
1143 | terminx | 2049 | A_RadiusDamage(i,g_seenineBlastRadius,10,15,20,25); |
5 | Plagman | 2050 | KILLIT(i); |
2051 | } |
||
2052 | goto BOLT; |
||
2053 | } |
||
2054 | |||
3679 | helixhorne | 2055 | if (s->picnum == OOZFILTER || s->picnum == SEENINE || s->picnum == SEENINEDEAD || s->picnum == SEENINEDEAD+1) |
5 | Plagman | 2056 | { |
331 | terminx | 2057 | if (s->shade != -32 && s->shade != -33) |
5 | Plagman | 2058 | { |
331 | terminx | 2059 | if (s->xrepeat) |
1143 | terminx | 2060 | j = (A_IncurDamage(i) >= 0); |
5 | Plagman | 2061 | else |
2062 | j = 0; |
||
2063 | |||
333 | terminx | 2064 | if (j || s->shade == -31) |
5 | Plagman | 2065 | { |
331 | terminx | 2066 | if (j) s->lotag = 0; |
5 | Plagman | 2067 | |
2068 | t[3] = 1; |
||
2069 | |||
3679 | helixhorne | 2070 | for (SPRITES_OF(STAT_STANDABLE, j)) |
5 | Plagman | 2071 | { |
333 | terminx | 2072 | if (s->hitag == sprite[j].hitag && (sprite[j].picnum == SEENINE || sprite[j].picnum == OOZFILTER)) |
5 | Plagman | 2073 | sprite[j].shade = -32; |
2074 | } |
||
2075 | } |
||
2076 | } |
||
2077 | else |
||
2078 | { |
||
331 | terminx | 2079 | if (s->shade == -32) |
5 | Plagman | 2080 | { |
3210 | helixhorne | 2081 | if ((int16_t)s->lotag > 0) |
5 | Plagman | 2082 | { |
3679 | helixhorne | 2083 | s->lotag -= 3; |
3210 | helixhorne | 2084 | if ((int16_t)s->lotag <= 0) |
2085 | s->lotag = (uint16_t)(-99); |
||
5 | Plagman | 2086 | } |
2087 | else |
||
2088 | s->shade = -33; |
||
2089 | } |
||
2090 | else |
||
2091 | { |
||
333 | terminx | 2092 | if (s->xrepeat > 0) |
5 | Plagman | 2093 | { |
2094 | T3++; |
||
331 | terminx | 2095 | if (T3 == 3) |
5 | Plagman | 2096 | { |
333 | terminx | 2097 | if (s->picnum == OOZFILTER) |
5 | Plagman | 2098 | { |
2099 | T3 = 0; |
||
2100 | goto DETONATE; |
||
2101 | } |
||
3679 | helixhorne | 2102 | |
333 | terminx | 2103 | if (s->picnum != (SEENINEDEAD+1)) |
5 | Plagman | 2104 | { |
2105 | T3 = 0; |
||
2106 | |||
3679 | helixhorne | 2107 | if (s->picnum == SEENINEDEAD) |
2108 | s->picnum++; |
||
331 | terminx | 2109 | else if (s->picnum == SEENINE) |
5 | Plagman | 2110 | s->picnum = SEENINEDEAD; |
2111 | } |
||
2112 | else goto DETONATE; |
||
2113 | } |
||
2114 | goto BOLT; |
||
2115 | } |
||
2116 | |||
2117 | DETONATE: |
||
1143 | terminx | 2118 | g_earthquakeTime = 16; |
5 | Plagman | 2119 | |
3679 | helixhorne | 2120 | for (SPRITES_OF(STAT_EFFECTOR, j)) |
5 | Plagman | 2121 | { |
333 | terminx | 2122 | if (s->hitag == sprite[j].hitag) |
5 | Plagman | 2123 | { |
3008 | helixhorne | 2124 | if (sprite[j].lotag == SE_13_EXPLOSIVE) |
5 | Plagman | 2125 | { |
1625 | terminx | 2126 | if (actor[j].t_data[2] == 0) |
2127 | actor[j].t_data[2] = 1; |
||
5 | Plagman | 2128 | } |
3008 | helixhorne | 2129 | else if (sprite[j].lotag == SE_8_UP_OPEN_DOOR_LIGHTS) |
1625 | terminx | 2130 | actor[j].t_data[4] = 1; |
3008 | helixhorne | 2131 | else if (sprite[j].lotag == SE_18_INCREMENTAL_SECTOR_RISE_FALL) |
5 | Plagman | 2132 | { |
1625 | terminx | 2133 | if (actor[j].t_data[0] == 0) |
2134 | actor[j].t_data[0] = 1; |
||
5 | Plagman | 2135 | } |
2970 | helixhorne | 2136 | else if (sprite[j].lotag == SE_21_DROP_FLOOR) |
1625 | terminx | 2137 | actor[j].t_data[0] = 1; |
5 | Plagman | 2138 | } |
2139 | } |
||
2140 | |||
2141 | s->z -= (32<<8); |
||
2142 | |||
1665 | terminx | 2143 | if (s->xrepeat) |
2144 | for (x=0; x<8 |