Subversion Repositories eduke32

Rev

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