raze/source/games/duke/src/spawn_r.cpp
Christoph Oelckers 4d6920e80b - fixed failiure to initialize the ambient tags array.
Also adding range checks to all places where it gets used. This is from CON code so proper values are never guaranteed.
2022-11-24 09:01:44 +01:00

1278 lines
28 KiB
C++

//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT
Copyright (C) 2020 - Christoph Oelckers
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#include <utility>
#include "ns.h"
#include "global.h"
#include "sounds.h"
#include "names_r.h"
#include "dukeactor.h"
BEGIN_DUKE_NS
DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>* actors)
{
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
{
CallInitialize(act);
return act;
}
auto sectp = act->sector();
switch (act->spr.picnum)
{
default:
default_case:
spawninitdefault(actj, act);
break;
case BOWLINGPINSPOT:
case RRTILE281:
case BOWLINGBALLSPOT:
case RRTILE283:
case RRTILE2025:
case RRTILE2026:
case RRTILE2027:
case RRTILE2028:
act->spr.cstat = 0;
act->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
act->spr.scale = DVector2(0, 0);
act->clipdist = 0;
act->spr.extra = 0;
ChangeActorStat(act, STAT_BOWLING);
break;
case LUMBERBLADE1:
act->spr.extra = 0;
ChangeActorStat(act, STAT_LUMBERMILL);
break;
case RRTILE8450:
if (!isRRRA()) goto default_case;
act->spr.scale = DVector2(1, 1);
act->spr.extra = act->spr.lotag;
act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
ChangeActorStat(act, 116);
break;
case PIG + 11:
if (!isRRRA()) goto default_case;
act->spr.scale = DVector2(0.25, 0.25);
act->clipdist = 0;
act->spr.extra = 0;
act->spr.cstat = 0;
ChangeActorStat(act, 121);
break;
case RRTILE8487:
case RRTILE8489:
if (!isRRRA()) goto default_case;
act->spr.scale = DVector2(0.5, 0.5);
act->spr.extra = 0;
act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
act->spr.hitag = 0;
ChangeActorStat(act, 117);
break;
case RRTILE7936:
if (!isRRRA()) goto default_case;
act->spr.scale = DVector2(0, 0);
fogactive = 1;
break;
case RRTILE6144:
if (!isRRRA()) goto default_case;
act->spr.scale = DVector2(0, 0);
ps[screenpeek].sea_sick_stat = 1;
break;
case RRTILE8448:
if (!isRRRA()) goto default_case;
act->spr.lotag = 1;
act->clipdist = 0;
break;
case RRTILE8099:
if (!isRRRA()) goto default_case;
act->spr.lotag = 5;
act->clipdist = 0;
ChangeActorStat(act, 123);
break;
case RRTILE8704:
if (!isRRRA()) goto default_case;
act->spr.lotag = 1;
act->clipdist = 0;
break;
case RRTILE8192:
if (!isRRRA()) goto default_case;
act->spr.scale = DVector2(0, 0);
ufospawnsminion = 1;
break;
case RRTILE8193:
if (!isRRRA()) goto default_case;
act->spr.scale = DVector2(0, 0);
pistonsound = 1;
break;
case RRTILE8165:
if (!isRRRA()) goto default_case;
act->spr.lotag = 1;
act->clipdist = 0;
act->SetOwner(act);
act->spr.extra = 0;
ChangeActorStat(act, 115);
break;
case RRTILE8593:
if (!isRRRA()) goto default_case;
act->spr.lotag = 1;
act->clipdist = 0;
act->SetOwner(act);
act->spr.extra = 0;
ChangeActorStat(act, 122);
break;
case CHICKENASPAWN:
case CHICKENCSPAWN:
case FEATHERSPAWN:
case CHICKENHEADSPAWN:
case LOAFSPAWN:
case NUGGETSPAWN:
case ROASTSPAWN:
case BONELESSSPAWN:
case JIBSSPAWN:
act->spr.cstat = 0;
act->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
act->spr.scale = DVector2(0, 0);
act->clipdist = 0;
act->spr.lotag = 0;
ChangeActorStat(act, STAT_CHICKENPLANT);
break;
case RRTILE2460:
case RRTILE2465:
case BIKEJIBA:
case BIKEJIBB:
case BIKEJIBC:
case BIKERJIBA:
case BIKERJIBB:
case BIKERJIBC:
case BIKERJIBD:
case CHEERJIBA:
case CHEERJIBB:
case CHEERJIBC:
case CHEERJIBD:
case FBOATJIBA:
case FBOATJIBB:
case RABBITJIBA:
case RABBITJIBB:
case RABBITJIBC:
case MAMAJIBA:
case MAMAJIBB:
// impossible to do with better methods outside of redoing the entire switch/case block
if (isRRRA()) goto rrra_badguy;
else goto default_case;
case WATERSPLASH2:
case MUD:
if (actj)
{
SetActor(act, actj->spr.pos);
double s = 0.125 + (krand() & 7) * REPEAT_SCALE;
act->spr.scale = DVector2(s, s);
}
else
{
double s = 0.25 + (krand() & 15) * REPEAT_SCALE;
act->spr.scale = DVector2(s, s);
}
act->spr.shade = -16;
act->spr.cstat |= CSTAT_SPRITE_YCENTER;
if (actj)
{
if (actj->sector()->lotag == 2)
{
act->spr.pos.Z = getceilzofslopeptr(act->sector(), act->spr.pos) + 16;
act->spr.cstat |= CSTAT_SPRITE_YFLIP;
}
else if (actj->sector()->lotag == 1)
act->spr.pos.Z = getceilzofslopeptr(act->sector(), act->spr.pos);
}
if (sectp->floorpicnum == FLOORSLIME ||
sectp->ceilingpicnum == FLOORSLIME)
act->spr.pal = 7;
[[fallthrough]];
case NEON1:
case NEON2:
case NEON3:
case NEON4:
case NEON5:
case NEON6:
case DOMELITE:
if (act->spr.picnum != WATERSPLASH2)
act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
if (act->spr.picnum == DOMELITE)
act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
[[fallthrough]];
case JIBS1:
case JIBS2:
case JIBS3:
case JIBS4:
case JIBS5:
case JIBS6:
case DUKETORSO:
case DUKEGUN:
case DUKELEG:
case BILLYJIBA:
case BILLYJIBB:
case HULKJIBA:
case HULKJIBB:
case HULKJIBC:
case MINJIBA:
case MINJIBB:
case MINJIBC:
case COOTJIBA:
case COOTJIBB:
case COOTJIBC:
rrra_badguy:
if (act->spr.picnum == JIBS6)
{
act->spr.scale *= 0.5;
}
else if (isRRRA())
{
if (act->spr.picnum == RABBITJIBA)
{
act->spr.scale = DVector2(0.28125, 0.28125);
}
else if (act->spr.picnum == RABBITJIBB)
{
act->spr.scale = DVector2(0.5625, 0.5625);
}
else if (act->spr.picnum == RABBITJIBC)
{
act->spr.scale = DVector2(0.84375, 0.84375);
}
}
ChangeActorStat(act, STAT_MISC);
break;
case TONGUE:
if (actj)
act->spr.angle = actj->spr.angle;
act->spr.pos.Z -= gs.playerheight;
act->vel.Z = 1 - krandf(2);
act->vel.X = 4 - krandf(8);
ChangeActorStat(act, STAT_PROJECTILE);
break;
case TRANSPORTERSTAR:
case TRANSPORTERBEAM:
spawntransporter(actj, act, act->spr.picnum == TRANSPORTERBEAM);
break;
case FRAMEEFFECT1:
if (actj)
{
act->spr.scale = actj->spr.scale;
if (actj->spr.picnum == APLAYER)
act->temp_data[1] = SMALLSMOKE;
else
act->temp_data[1] = actj->spr.picnum;
}
else act->spr.scale = DVector2(0, 0);
ChangeActorStat(act, STAT_MISC);
break;
case FORCESPHERE:
if (!actj)
{
act->spr.cstat = CSTAT_SPRITE_INVISIBLE;
ChangeActorStat(act, STAT_ZOMBIEACTOR);
}
else
{
act->spr.scale = DVector2(REPEAT_SCALE, REPEAT_SCALE);
ChangeActorStat(act, STAT_MISC);
}
break;
case BLOOD:
act->spr.scale = DVector2(0.0625, 0.0625);
act->spr.pos.Z -= 26;
ChangeActorStat(act, STAT_MISC);
break;
case BLOODPOOL:
if (spawnbloodpoolpart1(act)) break;
if (actj)
{
if (actj->spr.pal == 1)
act->spr.pal = 1;
else if (actj->spr.pal != 6 && actj->spr.picnum != NUKEBARREL)
{
act->spr.pal = 2; // Red
}
else act->spr.pal = 0; // green
}
act->spr.cstat |= CSTAT_SPRITE_ALIGNMENT_FLOOR;
[[fallthrough]];
case BLOODSPLAT1:
case BLOODSPLAT2:
case BLOODSPLAT3:
case BLOODSPLAT4:
act->spr.cstat |= CSTAT_SPRITE_ALIGNMENT_WALL;
act->spr.scale.X = (0.109375 + (krand() & 7) * REPEAT_SCALE);
act->spr.scale.Y = (0.109375 + (krand() & 7) * REPEAT_SCALE);
act->spr.pos.Z -= 16;
if (actj && actj->spr.pal == 6)
act->spr.pal = 6;
insertspriteq(act);
ChangeActorStat(act, STAT_MISC);
break;
case HYDRENT:
case SATELITE:
case FUELPOD:
case SOLARPANNEL:
case ANTENNA:
case GRATE1:
case CHAIR1:
case CHAIR2:
case CHAIR3:
case BOTTLE1:
case BOTTLE2:
case BOTTLE3:
case BOTTLE4:
case BOTTLE5:
case BOTTLE6:
case BOTTLE7:
case BOTTLE8:
case BOTTLE10:
case BOTTLE11:
case BOTTLE12:
case BOTTLE13:
case BOTTLE14:
case BOTTLE15:
case BOTTLE16:
case BOTTLE17:
case BOTTLE18:
case BOTTLE19:
case SCALE:
case VACUUM:
case FANSPRITE:
case CAMERALIGHT:
case MOVIECAMERA:
case IVUNIT:
case POT1:
case POT2:
case POT3:
case SUSHIPLATE1:
case SUSHIPLATE2:
case SUSHIPLATE3:
case SUSHIPLATE4:
case SUSHIPLATE5:
case WAITTOBESEATED:
case VASE:
case PIPE1:
case PIPE2:
case PIPE3:
case PIPE4:
case PIPE5:
case PIPE6:
act->clipdist = 8;
act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
ChangeActorStat(act, 0);
break;
case FEMMAG1:
case FEMMAG2:
act->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
ChangeActorStat(act, 0);
break;
case MASKWALL7:
{
auto j = act->spr.cstat & (CSTAT_SPRITE_ALIGNMENT_MASK | CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP);
act->spr.cstat = j | CSTAT_SPRITE_BLOCK;
ChangeActorStat(act, 0);
break;
}
case FOOTPRINTS:
case FOOTPRINTS2:
case FOOTPRINTS3:
case FOOTPRINTS4:
initfootprint(actj, act);
break;
case FEM10:
case NAKED1:
case STATUE:
case TOUGHGAL:
act->spr.yint = act->spr.hitag;
act->spr.hitag = -1;
[[fallthrough]];
case QUEBALL:
case STRIPEBALL:
if (act->spr.picnum == QUEBALL || act->spr.picnum == STRIPEBALL)
{
act->spr.cstat = CSTAT_SPRITE_BLOCK_HITSCAN;
act->clipdist = 2;
}
else
{
act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 8;
}
ChangeActorStat(act, STAT_ZOMBIEACTOR);
break;
case BOWLINGBALL:
act->spr.cstat = CSTAT_SPRITE_BLOCK_HITSCAN;
act->clipdist = 16;
act->spr.scale = DVector2(0.171875, 0.140625);
ChangeActorStat(act, STAT_ZOMBIEACTOR);
break;
case HENSTAND:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 12;
act->spr.scale = DVector2(0.328125, 0.234375);
ChangeActorStat(act, STAT_ZOMBIEACTOR);
break;
case KEGHOLDER:
act->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
ChangeActorStat(act, STAT_LUMBERMILL);
break;
case RRTELEPORT:
case RRTELEPORTDEST:
act->spr.scale = DVector2(1, 1);
act->clipdist = 16;
ChangeActorStat(act, STAT_TELEPORT);
break;
case CHICKENA:
case CHICKENB:
case CHICKENC:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 2;
act->spr.scale = DVector2(0.5, 0.40625);
act->vel.X = 2;
ChangeActorStat(act, STAT_ACTOR);
break;
case CHICKENLOAF:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 2;
act->spr.scale = DVector2(0.1875, 0.15625);
act->vel.X = 2;
ChangeActorStat(act, STAT_ACTOR);
break;
case CHICKENNUGGET:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 0.5;
act->spr.scale = DVector2(0.125, 0.09375);
act->vel.X = 1;
ChangeActorStat(act, STAT_ACTOR);
break;
case ROASTEDCHICKEN:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 2;
act->spr.scale = DVector2(0.203125, 0.203125);
act->vel.X = 1;
ChangeActorStat(act, STAT_ACTOR);
break;
case BONELESSCHICKEN:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 2;
act->spr.scale = DVector2(0.265625, 0.1875);
act->vel.X = 2;
ChangeActorStat(act, STAT_ACTOR);
break;
case CHICKENHEAD:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 2;
act->spr.scale = DVector2(0.203125, 0.15625);
act->vel.X = 0;
ChangeActorStat(act, STAT_ACTOR);
break;
case BOWLINGPIN:
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 12;
act->spr.scale = DVector2(0.359375, 0.359375);
ChangeActorStat(act, STAT_ZOMBIEACTOR);
break;
case DUKELYINGDEAD:
if (actj && actj->spr.picnum == APLAYER)
{
act->spr.scale = actj->spr.scale;
act->spr.shade = actj->spr.shade;
act->spr.pal = ps[actj->PlayerIndex()].palookup;
}
act->spr.cstat = 0;
act->spr.extra = 1;
act->vel.X = 292 / 16.;
act->vel.Z = 360 / 256.;
[[fallthrough]];
case RESPAWNMARKERRED:
if (act->spr.picnum == RESPAWNMARKERRED)
{
act->spr.scale = DVector2(0.125, 0.125);
if (actj) act->spr.pos.Z = actj->floorz;
}
else
{
act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 32;
}
[[fallthrough]];
case MIKE:
if (act->spr.picnum == MIKE)
act->spr.yint = act->spr.hitag;
ChangeActorStat(act, STAT_ACTOR);
break;
case SPOTLITE:
break;
case BULLETHOLE:
act->spr.scale = DVector2(0.046875, 0.046875);
act->spr.cstat = CSTAT_SPRITE_ALIGNMENT_WALL | randomFlip();
insertspriteq(act);
[[fallthrough]];
case MONEY:
if (act->spr.picnum == MONEY)
{
act->temp_data[0] = krand() & 2047;
act->spr.cstat = randomFlip();
act->spr.scale = DVector2(0.125, 0.125);
act->spr.angle = randomAngle();
}
ChangeActorStat(act, STAT_MISC);
break;
case SHELL: //From the player
case SHOTGUNSHELL:
initshell(actj, act, act->spr.picnum == SHELL);
break;
case EXPLOSION2:
case EXPLOSION3:
case BURNING:
case SMALLSMOKE:
if (actj)
{
act->spr.angle = actj->spr.angle;
act->spr.shade = -64;
act->spr.cstat = CSTAT_SPRITE_YCENTER | randomXFlip();
}
if (act->spr.picnum == EXPLOSION2)
{
act->spr.scale = DVector2(0.75, 0.75);
act->spr.shade = -127;
act->spr.cstat |= CSTAT_SPRITE_YCENTER;
}
else if (act->spr.picnum == EXPLOSION3)
{
act->spr.scale = DVector2(2, 2);
act->spr.shade = -127;
act->spr.cstat |= CSTAT_SPRITE_YCENTER;
}
else if (act->spr.picnum == SMALLSMOKE)
{
act->spr.scale = DVector2(0.1875, 0.1875);
}
else if (act->spr.picnum == BURNING)
{
act->spr.scale = DVector2(0.0625, 0.0625);
}
if (actj)
{
double x = getflorzofslopeptr(act->sector(), act->spr.pos);
if (act->spr.pos.Z > x - 12)
act->spr.pos.Z = x - 12;
}
ChangeActorStat(act, STAT_MISC);
break;
case PLAYERONWATER:
if (actj)
{
act->spr.scale = actj->spr.scale;
act->vel.Z = 0.5;
if (act->sector()->lotag != 2)
act->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
}
ChangeActorStat(act, STAT_DUMMYPLAYER);
break;
case APLAYER:
{
act->spr.scale = DVector2(0, 0);
int j = ud.coop;
if (j == 2) j = 0;
if (ud.multimode < 2 || (ud.multimode > 1 && j != act->spr.lotag))
ChangeActorStat(act, STAT_MISC);
else
ChangeActorStat(act, STAT_PLAYER);
break;
}
case WATERBUBBLE:
if (actj && actj->spr.picnum == APLAYER)
act->spr.pos.Z -= 16;
if (act->spr.picnum == WATERBUBBLE)
{
if (actj)
act->spr.angle = actj->spr.angle;
double s = REPEAT_SCALE + (krand() & 7) * REPEAT_SCALE;
act->spr.scale = DVector2(s, s);
}
else
act->spr.scale = DVector2(0.5, 0.5);
ChangeActorStat(act, STAT_MISC);
break;
case PLUG:
act->spr.lotag = 9999;
ChangeActorStat(act, STAT_STANDABLE);
break;
case WATERBUBBLEMAKER:
act->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
ChangeActorStat(act, STAT_STANDABLE);
break;
// this is not really nice...
case BIKERB:
case BIKERBV2:
case BIKER:
case MAKEOUT:
case CHEERB:
case CHEER:
case COOTPLAY:
case BILLYPLAY:
case MINIONBOAT:
case HULKBOAT:
case CHEERBOAT:
case RABBIT:
case ROCK:
case ROCK2:
case MAMACLOUD:
case MAMA:
case UFO1_RRRA:
if (isRRRA()) goto rrra_badguy2;
else goto default_case;
case UFO1_RR:
if (!isRRRA()) goto rrra_badguy2;
else goto default_case;
case SBSWIPE:
case CHEERSTAYPUT:
if (isRRRA()) goto rrra_stayput;
else goto default_case;
case SBMOVE:
if (isRRRA()) goto default_case;
[[fallthrough]];
case BILLYRAYSTAYPUT:
case BRAYSNIPER:
case BUBBASTAND:
case HULKSTAYPUT:
case HENSTAYPUT:
case PIGSTAYPUT:
case MINIONSTAYPUT:
case COOTSTAYPUT:
rrra_stayput:
act->actorstayput = act->sector();
[[fallthrough]];
case BOULDER:
case BOULDER1:
case RAT:
case TORNADO:
case BILLYCOCK:
case BILLYRAY:
case DOGRUN:
case LTH:
case HULK:
case HEN:
case DRONE:
case PIG:
case MINION:
case UFO2:
case UFO3:
case UFO4:
case UFO5:
case COW:
case COOT:
case SHARK:
case VIXEN:
rrra_badguy2:
act->spr.scale = DVector2(0.625, 0.625);
// Note: All inappropriate tiles have already been weeded out by the outer switch block so this does not need game type checks anymore.
switch (act->spr.picnum)
{
case VIXEN:
if (act->spr.pal == 34)
{
act->spr.scale = DVector2(0.34375, 0.328125);
}
else
{
act->spr.scale = DVector2(0.34375, 0.3125);
}
act->setClipDistFromTile();
break;
case HULKHANG:
case HULKHANGDEAD:
case HULKJUMP:
case HULK:
case HULKSTAYPUT:
act->spr.scale = DVector2(0.5, 0.5);
act->setClipDistFromTile();
break;
case COOTPLAY:
case COOT:
case COOTSTAYPUT:
act->spr.scale = DVector2(0.375, 0.28125);
act->setClipDistFromTile();
act->clipdist *= 4;
break;
case DRONE:
act->spr.scale = DVector2(0.21875, 0.109375);
act->clipdist = 32;
break;
case SBSWIPE:
case BILLYPLAY:
case BILLYCOCK:
case BILLYRAY:
case BILLYRAYSTAYPUT:
case BRAYSNIPER:
case BUBBASTAND:
act->spr.scale = DVector2(0.390625, 0.328125);
act->setClipDistFromTile();
break;
case COW:
act->spr.scale = DVector2(0.5, 0.5);
act->setClipDistFromTile();
break;
case HEN:
case HENSTAYPUT:
case HENSTAND:
if (act->spr.pal == 35)
{
act->spr.scale = DVector2(0.65625, 0.46875);
act->setClipDistFromTile();
}
else
{
act->spr.scale = DVector2(0.328125, 0.234375);
act->clipdist = 16;
}
break;
case MINION:
case MINIONSTAYPUT:
act->spr.scale = DVector2(0.25, 0.25);
act->setClipDistFromTile();
if (isRRRA() && ufospawnsminion)
act->spr.pal = 8;
break;
case DOGRUN:
case PIG:
act->spr.scale = DVector2(0.25, 0.25);
act->setClipDistFromTile();
break;
case RABBIT:
act->spr.scale = DVector2(0.28125, 0.28125);
act->setClipDistFromTile();
break;
case MAMACLOUD:
act->spr.scale = DVector2(1, 1);
act->spr.cstat = CSTAT_SPRITE_TRANSLUCENT;
act->spr.cstat |= CSTAT_SPRITE_TRANS_FLIP;
act->spr.pos.X += krandf(128) - 64;
act->spr.pos.Y += krandf(128) - 64;
act->spr.pos.Z += krandf(8) - 4;
break;
case MAMA:
if (actj && isrespawncontroller(actj))
act->spr.pal = actj->spr.pal;
if (act->spr.pal == 30)
{
act->spr.scale = DVector2(0.40625, 0.40625);
act->clipdist = 18.75;
}
else if (act->spr.pal == 31)
{
act->spr.scale = DVector2(0.5625, 0.5625);
act->clipdist = 25;
}
else if (act->spr.pal == 32)
{
act->spr.scale = DVector2(0.78125, 0.78125);
act->clipdist = 25;
}
else
{
act->spr.scale = DVector2(0.78125, 0.78125);
act->clipdist = 25;
}
break;
case BIKERB:
act->spr.scale = DVector2(0.4375, 0.34375);
act->clipdist = 18;
break;
case BIKERBV2:
act->spr.scale = DVector2(0.4375, 0.34375);
act->clipdist = 18;
break;
case BIKER:
act->spr.scale = DVector2(0.4375, 0.34375);
act->setClipDistFromTile();
break;
case CHEERB:
act->spr.scale = DVector2(0.4375, 0.34375);
act->clipdist = 18;
break;
case CHEER:
case CHEERSTAYPUT:
act->spr.scale = DVector2(0.34375, 0.3125);
act->setClipDistFromTile();
break;
case MAKEOUT:
act->spr.scale = DVector2(0.40625, 0.40625);
act->setClipDistFromTile();
break;
case MINIONBOAT:
act->spr.scale = DVector2(0.25, 0.25);
act->setClipDistFromTile();
break;
case HULKBOAT:
act->spr.scale = DVector2(0.75, 0.75);
act->setClipDistFromTile();
break;
case CHEERBOAT:
act->spr.scale = DVector2(0.5, 0.5);
act->setClipDistFromTile();
break;
case TORNADO:
act->spr.scale = DVector2(1, 2);
act->setClipDistFromTile();
act->clipdist *= 0.25;
act->spr.cstat = CSTAT_SPRITE_TRANSLUCENT;
break;
case LTH:
act->spr.scale = DVector2(0.375, 0.34375);
act->setClipDistFromTile();
break;
case ROCK:
case ROCK2:
act->spr.scale = DVector2(1, 1);
act->setClipDistFromTile();
break;
case UFO1_RRRA:
case UFO1_RR:
case UFO2:
case UFO3:
case UFO4:
case UFO5:
act->spr.scale = DVector2(0.5, 0.5);
act->setClipDistFromTile();
act->spr.extra = 50;
break;
case SBMOVE:
act->spr.scale = DVector2(0.75, 0.75);
act->setClipDistFromTile();
break;
default:
break;
}
if (actj) act->spr.lotag = 0;
if ((act->spr.lotag > ud.player_skill) || ud.monsters_off == 1)
{
act->spr.scale = DVector2(0, 0);
ChangeActorStat(act, STAT_MISC);
break;
}
else
{
makeitfall(act);
if (act->spr.picnum == RAT)
{
act->spr.angle = randomAngle();
act->spr.scale = DVector2(0.75, 0.75);
act->spr.cstat = 0;
}
else
{
act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
if (act->spr.picnum != 5501)
if (actorfella(act))
ps[myconnectindex].max_actors_killed++;
}
if (actj)
{
act->timetosleep = 0;
check_fta_sounds_r(act);
ChangeActorStat(act, STAT_ACTOR);
act->spr.shade = actj->spr.shade;
}
else ChangeActorStat(act, STAT_ZOMBIEACTOR);
}
break;
case OOZ:
{
act->spr.shade = -12;
if (actj)
if (actj->spr.picnum == NUKEBARREL)
act->spr.pal = 8;
ChangeActorStat(act, STAT_STANDABLE);
getglobalz(act);
double j = ((act->floorz - act->ceilingz) / 128.);
act->spr.scale = DVector2(max(0., 0.390625 - j * 0.5), j);
if(krand() & 4) act->spr.cstat |= CSTAT_SPRITE_XFLIP;
break;
}
case DYNAMITE:
act->SetOwner(act);
act->spr.scale = DVector2(0.140625, 0.140625);
act->spr.yint = 4;
[[fallthrough]];
case REACTOR2:
case REACTOR:
case RECON:
if (initreactor(actj, act, act->spr.picnum == RECON)) return act;
break;
case RPG2SPRITE:
case MOTOAMMO:
case BOATAMMO:
if (!isRRRA()) goto default_case;
[[fallthrough]];
case ATOMICHEALTH:
case STEROIDS:
case HEATSENSOR:
case SHIELD:
case AIRTANK:
case POWDERKEG:
case COWPIE:
case HOLODUKE:
case FIRSTGUNSPRITE:
case RIFLEGUNSPRITE:
case SHOTGUNSPRITE:
case CROSSBOWSPRITE:
case RIPSAWSPRITE:
case TITSPRITE:
case ALIENBLASTERSPRITE:
case SHOTGUNAMMO:
case FREEZEAMMO:
case HBOMBAMMO:
case CRYSTALAMMO:
case GROWAMMO:
case BATTERYAMMO:
case DEVISTATORAMMO:
case RPGAMMO:
case BOOTS:
case AMMO:
case AMMOLOTS:
case BEER:
case FIRSTAID:
case SIXPAK:
case SAWAMMO:
case BOWLINGBALLSPRITE:
if (actj)
{
act->spr.lotag = 0;
if (act->spr.picnum != BOWLINGBALLSPRITE)
{
act->spr.pos.Z -= 32;
act->vel.Z = -4;
}
else
{
act->vel.Z = 0;
}
ssp(act, CLIPMASK0);
act->spr.cstat = randomXFlip();
}
else
{
act->SetOwner(act);
act->spr.cstat = 0;
}
if ((ud.multimode < 2 && act->spr.pal != 0) || (act->spr.lotag > ud.player_skill))
{
act->spr.scale = DVector2(0, 0);
ChangeActorStat(act, STAT_MISC);
break;
}
act->spr.pal = 0;
[[fallthrough]];
case ACCESSCARD:
if (act->spr.picnum == ATOMICHEALTH)
act->spr.cstat |= CSTAT_SPRITE_YCENTER;
if (ud.multimode > 1 && ud.coop != 1 && act->spr.picnum == ACCESSCARD)
{
act->spr.scale = DVector2(0, 0);
ChangeActorStat(act, STAT_MISC);
break;
}
else
{
if (act->spr.picnum == AMMO)
act->spr.scale = DVector2(0.25, 0.25);
else act->spr.scale = DVector2(0.5, 0.5);
}
act->spr.shade = -17;
if (actj) ChangeActorStat(act, STAT_ACTOR);
else
{
ChangeActorStat(act, STAT_ZOMBIEACTOR);
makeitfall(act);
}
switch (act->spr.picnum)
{
case FIRSTGUNSPRITE:
act->spr.scale = DVector2(0.25, 0.25);
break;
case SHOTGUNAMMO:
act->spr.scale = DVector2(0.28125, 0.265625);
if (isRRRA()) act->spr.cstat = CSTAT_SPRITE_BLOCK_HITSCAN;
break;
case SIXPAK:
act->spr.scale = DVector2(0.203125, 0.140625);
if (isRRRA()) act->spr.cstat = CSTAT_SPRITE_BLOCK_HITSCAN;
break;
case FIRSTAID:
act->spr.scale = DVector2(0.125, 0.125);
break;
case BEER:
act->spr.scale = DVector2(0.078125, 0.0625);
break;
case AMMO:
act->spr.scale = DVector2(0.140625, 0.140625);
break;
case MOTOAMMO:
if (!isRRRA()) goto default_case;
act->spr.scale = DVector2(0.359375, 0.359375);
break;
case BOATAMMO:
if (!isRRRA()) goto default_case;
act->spr.scale = DVector2(0.25, 0.25);
break;
case COWPIE:
act->spr.scale = DVector2(0.125, 0.09375);
break;
case STEROIDS:
act->spr.scale = DVector2(0.203125, 0.140625);
break;
case ACCESSCARD:
act->spr.scale = DVector2(0.171875, 0.1875);
break;
case HEATSENSOR:
act->spr.scale = DVector2(0.09375, 0.0625);
break;
case AIRTANK:
act->spr.scale = DVector2(0.296875, 0.25);
break;
case BATTERYAMMO:
act->spr.scale = DVector2(0.234375, 0.234375);
break;
case BOWLINGBALLSPRITE:
act->spr.scale = DVector2(0.171875, 0.171875);
break;
case POWDERKEG:
act->spr.scale = DVector2(0.171875, 0.171875);
act->spr.yint = 4;
act->vel.X = 2;
break;
case CROSSBOWSPRITE:
act->spr.scale = DVector2(0.25, 0.21875);
break;
case RPG2SPRITE:
if (!isRRRA()) goto default_case;
act->spr.scale = DVector2(0.34375, 0.3125);
break;
case RIPSAWSPRITE:
act->spr.scale = DVector2(0.34375, 0.203125);
break;
case ALIENBLASTERSPRITE:
act->spr.scale = DVector2(0.28125, 0.265625);
break;
case SAWAMMO:
act->spr.scale = DVector2(0.1875, 0.109375);
break;
case GROWSPRITEICON:
act->spr.scale = DVector2(0.15625, 0.140625);
break;
case DEVISTATORAMMO:
act->spr.scale = DVector2(0.15625, 0.140625);
break;
case ATOMICHEALTH:
act->spr.scale = DVector2(0.125, 0.125);
break;
case TITSPRITE:
act->spr.scale = DVector2(0.265625, 0.25);
break;
}
act->spr.shade = act->sector()->floorshade;
break;
case CAMERAPOLE:
act->spr.extra = 1;
if (gs.camerashitable) act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
else act->spr.cstat = 0;
if (ud.multimode < 2 && act->spr.pal != 0)
{
act->spr.scale = DVector2(0, 0);
ChangeActorStat(act, STAT_MISC);
break;
}
else act->spr.pal = 0;
break;
case STEAM:
if (actj)
{
act->spr.angle = actj->spr.angle;
act->spr.cstat = CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_YCENTER | CSTAT_SPRITE_TRANSLUCENT;
act->spr.scale = DVector2(REPEAT_SCALE, REPEAT_SCALE);
act->vel.X = -0.5;
ssp(act, CLIPMASK0);
}
[[fallthrough]];
case CEILINGSTEAM:
ChangeActorStat(act, STAT_STANDABLE);
break;
case SECTOREFFECTOR:
spawneffector(act, actors);
break;
case EMPTYBIKE:
if (!isRRRA()) goto default_case;
if (ud.multimode < 2 && act->spr.pal == 1)
{
act->spr.scale = DVector2(0, 0);
break;
}
act->spr.pal = 0;
act->spr.scale = DVector2(0.28125, 0.28125);
act->setClipDistFromTile();
act->saved_ammo = 100;
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->spr.lotag = 1;
ChangeActorStat(act, STAT_ACTOR);
break;
case EMPTYBOAT:
if (!isRRRA()) goto default_case;
if (ud.multimode < 2 && act->spr.pal == 1)
{
act->spr.scale = DVector2(0, 0);
break;
}
act->spr.pal = 0;
act->spr.scale = DVector2(0.5, 0.5);
act->setClipDistFromTile();
act->saved_ammo = 20;
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->spr.lotag = 1;
ChangeActorStat(act, STAT_ACTOR);
break;
case TOILET:
case STALL:
case RRTILE2121:
case RRTILE2122:
act->spr.lotag = 1;
act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
act->clipdist = 2;
act->SetOwner(act);
break;
case RUBBERCAN:
act->spr.extra = 0;
[[fallthrough]];
case EXPLODINGBARREL:
case HORSEONSIDE:
case FIREBARREL:
case NUKEBARREL:
case FIREVASE:
case NUKEBARRELDENTED:
case NUKEBARRELLEAKED:
case WOODENHORSE:
if (actj)
act->spr.scale = DVector2(0.5, 0.5);
act->clipdist = 18;
makeitfall(act);
if (actj) act->SetOwner(actj);
else act->SetOwner(act);
[[fallthrough]];
case EGG:
if (ud.monsters_off == 1 && act->spr.picnum == EGG)
{
act->spr.scale = DVector2(0, 0);
ChangeActorStat(act, STAT_MISC);
}
else
{
if (act->spr.picnum == EGG)
act->clipdist = 6;
act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL | randomXFlip();
ChangeActorStat(act, STAT_ZOMBIEACTOR);
}
break;
case TOILETWATER:
act->spr.shade = -16;
ChangeActorStat(act, STAT_STANDABLE);
break;
case RRTILE63:
act->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
act->spr.scale = DVector2(REPEAT_SCALE, REPEAT_SCALE);
act->clipdist = 0.25;
ChangeActorStat(act, 100);
break;
}
return act;
}
END_DUKE_NS