- implemented customizable breakable walls and ported all hard coded variants to use this.

This commit is contained in:
Christoph Oelckers 2022-12-05 11:27:25 +01:00
parent 241636a907
commit a63ee8079a
39 changed files with 511 additions and 720 deletions

View file

@ -229,15 +229,12 @@ void FMapInfoParser::ParseMusic(FString &name, int &order)
void FMapInfoParser::ParseSpawnClasses()
{
FString fn;
int res_id = -1;
int numframes = -1;
bool interpolate = false;
int clipdist = -1;
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
// This will need some reworking once we can use real textures.
int clipdist = -1;
int num = -1;
int base = -1;
int basetex = -1;
@ -329,18 +326,18 @@ void FMapInfoParser::ParseSpawnClasses()
void FMapInfoParser::ParseBreakWall()
{
int basetile = -1;
int breaktile = -1;
int flags = 0;
FSoundID sound = NO_SOUND;
VMFunction* handler = nullptr;
FString basename;
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
int basetile = -1;
int breaktile = -1;
int flags = 0;
FSoundID sound = NO_SOUND;
VMFunction* handler = nullptr;
sc.MustGetString();
basename = sc.String; // save for printing error messages.
FString basename = sc.String; // save for printing error messages.
basetile = TileFiles.tileForName(sc.String);
if (basetile < 0)
{
@ -350,7 +347,7 @@ void FMapInfoParser::ParseBreakWall()
ParseAssign();
sc.MustGetString();
breaktile = TileFiles.tileForName(sc.String);
if (breaktile < 0) sc.ScriptMessage("Unknown texture '%s' in breakwall definition", sc.String, breaktile);
if (*sc.String && breaktile < 0) sc.ScriptMessage("Unknown texture '%s' in breakwall definition", sc.String, breaktile);
if (sc.CheckString(","))
{
sc.MustGetString();
@ -377,6 +374,7 @@ void FMapInfoParser::ParseBreakWall()
{
sc.MustGetString();
if (sc.Compare("twosided")) flags |= 1;
else if (sc.Compare("maskedonly")) flags |= 2;
else sc.ScriptMessage("'%s': Unknown breakable flag", sc.String);
}
}

View file

@ -196,6 +196,7 @@ enum ETSprFlags
TSPR_SLOPESPRITE = 8, // render as sloped sprite
TSPR_ROTATE8FRAMES = 16, // do an 8 frame rotation
TSPR_ROTATE12FRAMES = 32, // do an 12 frame rotation
TSPR_NOFLOORPAL = 64, // ignore the floorpal
};

View file

@ -34,6 +34,7 @@ xx(RedneckJaildoorDef)
xx(RedneckJaildoorSound)
xx(RedneckGeometryEffect)
xx(RedneckKeyinfoSetter)
xx(DukeSectorEffector)
xx(spawnstate)
xx(brokenstate)

View file

@ -254,7 +254,7 @@ void hitradius_d(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h
updatesector(w1, &sect);
if (sect && cansee(w1, sect, actor->spr.pos, actor->sector()))
fi.checkhitwall(actor, &wal, DVector3(wal.pos, actor->spr.pos.Z), actor->spr.picnum);
checkhitwall(actor, &wal, DVector3(wal.pos, actor->spr.pos.Z));
}
}
}
@ -1060,7 +1060,7 @@ static void flamethrowerflame(DDukeActor *actor)
else if (coll.type == kHitWall)
{
SetActor(actor, dapos);
fi.checkhitwall(actor, coll.hitWall, actor->spr.pos, actor->spr.picnum);
checkhitwall(actor, coll.hitWall, actor->spr.pos);
}
else if (coll.type == kHitSector)
{

View file

@ -207,7 +207,7 @@ void hitradius_r(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h
updatesector(w1, &sect);
if (sect && cansee(w1, sect, actor->spr.pos, actor->sector()))
fi.checkhitwall(actor, &wal, DVector3(wal.pos, actor->spr.pos.Z), actor->spr.picnum);
checkhitwall(actor, &wal, DVector3(wal.pos, actor->spr.pos.Z));
}
}
}

View file

@ -109,23 +109,20 @@ void animatesprites_d(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi
auto sectp = h->sector();
if (h->GetClass() != RUNTIME_CLASS(DDukeActor))
{
bool res = CallAnimate(h, t);
// some actors have 4, some 6 rotation frames - in true Build fashion there's no pointers what to do here without flagging it.
if (actorflag(h, SFLAG2_ALWAYSROTATE1) || (t->clipdist & TSPR_ROTATE8FRAMES))
applyRotation1(h, t, viewang);
else if (actorflag(h, SFLAG2_ALWAYSROTATE2) || (t->clipdist & TSPR_ROTATE12FRAMES))
applyRotation2(h, t, viewang);
if (sectp->floorpal && !actorflag(h, SFLAG2_NOFLOORPAL))
copyfloorpal(t, sectp);
bool res = CallAnimate(h, t);
// some actors have 4, some 6 rotation frames - in true Build fashion there's no pointers what to do here without flagging it.
if (actorflag(h, SFLAG2_ALWAYSROTATE1) || (t->clipdist & TSPR_ROTATE8FRAMES))
applyRotation1(h, t, viewang);
else if (actorflag(h, SFLAG2_ALWAYSROTATE2) || (t->clipdist & TSPR_ROTATE12FRAMES))
applyRotation2(h, t, viewang);
if (sectp->floorpal && !actorflag(h, SFLAG2_NOFLOORPAL) && !(t->clipdist & TSPR_NOFLOORPAL))
copyfloorpal(t, sectp);
if (res)
{
if (h->dispicnum >= 0)
h->dispicnum = t->picnum;
continue;
}
if (res)
{
if (h->dispicnum >= 0)
h->dispicnum = t->picnum;
continue;
}
t1 = h->temp_data[1];

View file

@ -72,9 +72,8 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi
h = static_cast<DDukeActor*>(t->ownerActor);
auto OwnerAc = h->GetOwner();
switch (h->spr.picnum)
if (iseffector(h))
{
case SECTOREFFECTOR:
if (t->lotag == SE_27_DEMO_CAM && ud.recstat == 1)
{
t->picnum = 11 + ((PlayClock >> 3) & 1);
@ -82,12 +81,9 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi
}
else
t->scale = DVector2(0, 0);
break;
default:
break;
}
if (t->statnum == 99) continue;
if (t->statnum == STAT_TEMP) continue;
auto pp = &ps[h->PlayerIndex()];
if (h->spr.statnum != STAT_ACTOR && h->isPlayer() && pp->newOwner == nullptr && h->GetOwner())
{
@ -106,23 +102,20 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi
auto sectp = h->sector();
if (h->GetClass() != RUNTIME_CLASS(DDukeActor))
{
bool res = CallAnimate(h, t);
// some actors have 4, some 6 rotation frames - in true Build fashion there's no pointers what to do here without flagging it.
if (actorflag(h, SFLAG2_ALWAYSROTATE1) || (t->clipdist & TSPR_ROTATE8FRAMES))
applyRotation1(h, t, viewang);
else if (actorflag(h, SFLAG2_ALWAYSROTATE2) || (t->clipdist & TSPR_ROTATE12FRAMES))
applyRotation2(h, t, viewang);
if (sectp->floorpal && !actorflag(h, SFLAG2_NOFLOORPAL))
copyfloorpal(t, sectp);
bool res = CallAnimate(h, t);
// some actors have 4, some 6 rotation frames - in true Build fashion there's no pointers what to do here without flagging it.
if (actorflag(h, SFLAG2_ALWAYSROTATE1) || (t->clipdist & TSPR_ROTATE8FRAMES))
applyRotation1(h, t, viewang);
else if (actorflag(h, SFLAG2_ALWAYSROTATE2) || (t->clipdist & TSPR_ROTATE12FRAMES))
applyRotation2(h, t, viewang);
if (sectp->floorpal && !actorflag(h, SFLAG2_NOFLOORPAL) && !(t->clipdist & TSPR_NOFLOORPAL))
copyfloorpal(t, sectp);
if (res)
{
if (h->dispicnum >= 0)
h->dispicnum = t->picnum;
continue;
}
if (res)
{
if (h->dispicnum >= 0)
h->dispicnum = t->picnum;
continue;
}
t1 = h->temp_data[1];

View file

@ -43,8 +43,6 @@ bool checkhitswitch_d(int snum, walltype* w, DDukeActor *act);
bool checkhitswitch_r(int snum, walltype* w, DDukeActor* act);
void activatebysector_d(sectortype* sect, DDukeActor* j);
void activatebysector_r(sectortype* sect, DDukeActor* j);
void checkhitwall_d(DDukeActor* spr, walltype* dawall, const DVector3& pos, int atwith);
void checkhitwall_r(DDukeActor* spr, walltype* dawall, const DVector3& pos, int atwith);
bool checkhitceiling_d(sectortype* sn);
bool checkhitceiling_r(sectortype* sn);
void checkhitsprite_d(DDukeActor* i, DDukeActor* sn);
@ -107,7 +105,6 @@ void SetDispatcher()
operateforcefields_d,
checkhitswitch_d,
activatebysector_d,
checkhitwall_d,
checkhitceiling_d,
checkhitsprite_d,
checkhitdefault_d,
@ -145,7 +142,6 @@ void SetDispatcher()
operateforcefields_r,
checkhitswitch_r,
activatebysector_r,
checkhitwall_r,
checkhitceiling_r,
checkhitsprite_r,
checkhitdefault_r,
@ -176,7 +172,6 @@ void SetDispatcher()
}
int TILE_W_FORCEFIELD;
int TILE_APLAYER;
int TILE_DRONE;
int TILE_SCREENBORDER;
@ -198,6 +193,7 @@ int TILE_ACCESSSWITCH;
int TILE_ACCESSSWITCH2;
int TILE_HEN;
int TILE_MIRROR;
int TILE_MIRRORBROKE;
int TILE_LOADSCREEN;
int TILE_CROSSHAIR;
int TILE_EGG;

View file

@ -79,7 +79,6 @@ struct Dispatcher
void (*operateforcefields)(DDukeActor* act, int low);
bool (*checkhitswitch)(int snum, walltype* w, DDukeActor* act);
void (*activatebysector)(sectortype* sect, DDukeActor* j);
void (*checkhitwall)(DDukeActor* spr, walltype* dawall, const DVector3& pos, int atwith);
bool (*checkhitceiling)(sectortype* sn);
void (*checkhitsprite)(DDukeActor* i, DDukeActor* sn);
void (*checkhitdefault)(DDukeActor* i, DDukeActor* sn);

View file

@ -276,7 +276,6 @@ void initactorflags_d()
gs.weaponsandammosprites[14] = DTILE_FREEZEAMMO;
gs.firstdebris = DTILE_SCRAP6;
TILE_W_FORCEFIELD = DTILE_W_FORCEFIELD;
TILE_APLAYER = DTILE_APLAYER;
TILE_DRONE = DTILE_DRONE;
TILE_SCREENBORDER = DTILE_BIGHOLE;
@ -295,6 +294,7 @@ void initactorflags_d()
TILE_ACCESSSWITCH = DTILE_ACCESSSWITCH;
TILE_ACCESSSWITCH2 = DTILE_ACCESSSWITCH2;
TILE_MIRROR = DTILE_MIRROR;
TILE_MIRRORBROKE = DTILE_MIRRORBROKE;
TILE_LOADSCREEN = DTILE_LOADSCREEN;
TILE_CROSSHAIR = DTILE_CROSSHAIR;
TILE_EGG = DTILE_EGG;

View file

@ -276,7 +276,6 @@ void initactorflags_r()
gs.weaponsandammosprites[13] = RTILE_TITSPRITE;
gs.weaponsandammosprites[14] = RTILE_FREEZEAMMO;
TILE_W_FORCEFIELD = RTILE_W_FORCEFIELD;
TILE_APLAYER = RTILE_APLAYER;
TILE_DRONE = RTILE_DRONE;
TILE_SCREENBORDER = isRRRA()? 7629 : RTILE_BIGHOLE;
@ -295,6 +294,7 @@ void initactorflags_r()
TILE_ACCESSSWITCH = RTILE_ACCESSSWITCH;
TILE_ACCESSSWITCH2 = RTILE_ACCESSSWITCH2;
TILE_MIRROR = RTILE_MIRROR;
TILE_MIRRORBROKE = RTILE_MIRRORBROKE;
TILE_HEN = RTILE_HEN;
TILE_LOADSCREEN = RTILE_LOADSCREEN;
TILE_CROSSHAIR = RTILE_CROSSHAIR;

View file

@ -116,7 +116,7 @@ int setpal(player_struct* p);
int madenoise(int playerNum);
int haskey(sectortype* sect, int snum);
void breakwall(int newpn, DDukeActor* spr, walltype* dawallnum);
void checkhitwall(DDukeActor* spr, walltype* wal, const DVector3& pos);
int callsound(sectortype* sectnum,DDukeActor* snum, bool endstate = false);
double hitasprite(DDukeActor* snum,DDukeActor **hitSprite);
int findplayer(const DDukeActor* s, double* dist);
@ -172,7 +172,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
void addspritetodelete(int spnum=0);
void checkavailinven(player_struct* p);
bool initspriteforspawn(DDukeActor* spn);
void spawninitdefault(DDukeActor* actj, DDukeActor* act);
bool spawninitdefault(DDukeActor* actj, DDukeActor* act);
void spawntransporter(DDukeActor* actj, DDukeActor* acti, bool beam);
int spawnbloodpoolpart1(DDukeActor* acti);
void initshell(DDukeActor* actj, DDukeActor* acti, bool isshell);

View file

@ -282,7 +282,6 @@ static void setupbackdrop()
static void initTiles()
{
tileDelete(TILE_MIRROR);
//skiptile = TILE_W_FORCEFIELD + 1;
if (isRR())
tileDelete(0);

View file

@ -2295,7 +2295,7 @@ int ParseState::parse(void)
parseifelse(ud.coop || numplayers > 2);
break;
case concmd_ifonmud:
parseifelse(abs(g_ac->spr.pos.Z - g_ac->sector()->floorz) < 32 && g_ac->sector()->floorpicnum == 3073); // eew, hard coded tile numbers.. :?
parseifelse(abs(g_ac->spr.pos.Z - g_ac->sector()->floorz) < 32 && (tileflags(g_ac->sector()->floorpicnum) & TFLAG_MUDDY) != 0);
break;
case concmd_ifonwater:
parseifelse( abs(g_ac->spr.pos.Z-g_ac->sector()->floorz) < 32 && g_ac->sector()->lotag == ST_1_ABOVE_WATER);

View file

@ -46,7 +46,7 @@ inline int islocator(DDukeActor* actor)
inline int iseffector(DDukeActor* actor)
{
return actor->spr.picnum == SECTOREFFECTOR;
return actor->GetClass()->TypeName == NAME_DukeSectorEffector;
}

View file

@ -130,6 +130,8 @@ x(PANNEL2, 343)
x(WATERTILE, 344)
x(STATIC, 351)
x(W_SCREENBREAK, 357)
x(W_SCREENBREAK2, 358)
x(W_SCREENBREAK3, 359)
x(W_HITTECHWALL3, 360)
x(W_HITTECHWALL4, 361)
x(W_HITTECHWALL2, 362)
@ -205,6 +207,8 @@ x(WATERDRIP, 660)
x(WATERBUBBLE, 661)
x(WATERBUBBLEMAKER, 662)
x(W_FORCEFIELD, 663)
x(W_FORCEFIELD2, 664)
x(W_FORCEFIELD3, 665)
x(VACUUM, 669)
x(FOOTPRINTS2, 672)
x(FOOTPRINTS3, 673)
@ -769,10 +773,15 @@ x(W_TECHWALL12, 4131)
x(W_TECHWALL13, 4132)
x(W_TECHWALL14, 4133)
x(W_TECHWALL5, 4134)
x(W_TECHWALL5B, 4134)
x(W_TECHWALL6, 4136)
x(W_TECHWALL6B, 4137)
x(W_TECHWALL7, 4138)
x(W_TECHWALL7B, 4139)
x(W_TECHWALL8, 4140)
x(W_TECHWALL8B, 4141)
x(W_TECHWALL9, 4142)
x(W_TECHWALL9B, 4143)
x(BPANNEL3, 4100)
x(W_HITTECHWALL16, 4144)
x(W_HITTECHWALL10, 4145)

View file

@ -146,6 +146,8 @@ x(W_TECHWALL15, 191)
x(W_TECHWALL16, 192)
x(STATIC, 195)
x(W_SCREENBREAK, 199)
x(W_SCREENBREAK2, 200)
x(W_SCREENBREAK3, 201)
x(W_HITTECHWALL3, 205)
x(W_HITTECHWALL4, 206)
x(W_HITTECHWALL2, 207)

View file

@ -3,7 +3,6 @@
BEGIN_DUKE_NS
// These are all globally accessed tiles.
extern int TILE_W_FORCEFIELD;
extern int TILE_APLAYER;
extern int TILE_DRONE;
extern int TILE_SCREENBORDER;
@ -23,6 +22,7 @@ extern int TILE_ACCESSSWITCH;
extern int TILE_ACCESSSWITCH2;
extern int TILE_HEN;
extern int TILE_MIRROR;
extern int TILE_MIRRORBROKE;
extern int TILE_LOADSCREEN;
extern int TILE_CROSSHAIR;
extern int TILE_EGG;

View file

@ -283,7 +283,7 @@ static void shootknee(DDukeActor* actor, int p, DVector3 pos, DAngle ang)
if (hit.hitWall->picnum != DTILE_ACCESSSWITCH && hit.hitWall->picnum != DTILE_ACCESSSWITCH2)
{
fi.checkhitwall(knee, hit.hitWall, hit.hitpos, DTILE_KNEE);
checkhitwall(knee, hit.hitWall, hit.hitpos);
if (p >= 0) fi.checkhitswitch(p, hit.hitWall, nullptr);
}
}
@ -519,7 +519,7 @@ static void shootweapon(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int
if (hit.hitpos.Z >= hit.hitWall->nextSector()->floorz)
hit.hitWall = hit.hitWall->nextWall();
fi.checkhitwall(spark, hit.hitWall, hit.hitpos, DTILE_SHOTSPARK1);
checkhitwall(spark, hit.hitWall, hit.hitpos);
}
}
else
@ -537,7 +537,7 @@ static void shootweapon(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int
else spark->spr.scale = DVector2(0, 0);
}
else if (hit.hitWall)
fi.checkhitwall(spark, hit.hitWall, hit.hitpos, DTILE_SHOTSPARK1);
checkhitwall(spark, hit.hitWall, hit.hitpos);
}
}
@ -954,7 +954,7 @@ static void shootgrowspark(DDukeActor* actor, int p, DVector3 pos, DAngle ang)
{
if (hit.hitWall->picnum != DTILE_ACCESSSWITCH && hit.hitWall->picnum != DTILE_ACCESSSWITCH2)
{
fi.checkhitwall(spark, hit.hitWall, hit.hitpos, DTILE_GROWSPARK);
checkhitwall(spark, hit.hitWall, hit.hitpos);
}
}
}

View file

@ -174,7 +174,7 @@ static void shootmelee(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int a
if (hit.hitWall->picnum != RTILE_ACCESSSWITCH && hit.hitWall->picnum != RTILE_ACCESSSWITCH2)
{
fi.checkhitwall(wpn, hit.hitWall, hit.hitpos, atwith);
checkhitwall(wpn, hit.hitWall, hit.hitpos);
if (p >= 0) fi.checkhitswitch(p, hit.hitWall, nullptr);
}
}
@ -414,7 +414,7 @@ static void shootweapon(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int
if (hit.hitpos.Z >= hit.hitWall->nextSector()->floorz)
hit.hitWall = hit.hitWall->nextWall();
fi.checkhitwall(spark, hit.hitWall, hit.hitpos, RTILE_SHOTSPARK1);
checkhitwall(spark, hit.hitWall, hit.hitpos);
}
}
else
@ -431,7 +431,7 @@ static void shootweapon(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int
else spark->spr.scale = DVector2(0, 0);
}
else if (hit.hitWall != nullptr)
fi.checkhitwall(spark, hit.hitWall, hit.hitpos, RTILE_SHOTSPARK1);
checkhitwall(spark, hit.hitWall, hit.hitpos);
}
if ((krand() & 255) < 10)

View file

@ -1255,7 +1255,7 @@ void operateforcefields_common(DDukeActor *effector, int low, const std::initial
{
wal->cstat = 0;
if (effector && iseffector(effector) && effector->spr.lotag == 30)
if (effector && iseffector(effector) && effector->spr.lotag == SE_30_TWO_WAY_TRAIN)
wal->lotag = 0;
}
else
@ -1270,12 +1270,47 @@ void operateforcefields_common(DDukeActor *effector, int low, const std::initial
//
//---------------------------------------------------------------------------
void breakwall(int newpn, DDukeActor* spr, walltype* wal)
void checkhitwall(DDukeActor* spr, walltype* wal, const DVector3& pos)
{
wal->picnum = newpn;
S_PlayActorSound(VENT_BUST, spr);
S_PlayActorSound(GLASS_HEAVYBREAK, spr);
lotsofglass(spr, wal, 10);
if (wal->overpicnum == TILE_MIRROR && actorflag(spr, SFLAG2_BREAKMIRRORS))
{
lotsofglass(spr, wal, 70);
wal->cstat &= ~CSTAT_WALL_MASKED;
wal->overpicnum = TILE_MIRRORBROKE;
wal->portalflags = 0;
S_PlayActorSound(GLASS_HEAVYBREAK, spr);
return;
}
auto handler = [=](const BreakWallRec* data, int16_t* pic)
{
if (!data->handler)
{
*pic = data->brokentex;
S_PlayActorSound(data->breaksound, spr);
}
else
{
VMValue args[7] = { wal, data->brokentex, data->breaksound.index(), spr, pos.X, pos.Y, pos.Z };
VMCall(data->handler, args, 7, nullptr, 0);
}
};
if (wal->twoSided() && wal->nextSector()->floorz > pos.Z && wal->nextSector()->floorz - wal->nextSector()->ceilingz)
{
auto data = breakWallMap.CheckKey(wal->overpicnum);
if (data && (data->flags & 1) && (!(data->flags & 2) || wal->cstat & CSTAT_WALL_MASKED))
{
handler(data, &wal->overpicnum);
}
}
auto data = breakWallMap.CheckKey(wal->picnum);
if (data && !(data->flags & 1))
{
handler(data, &wal->picnum);
}
}
//---------------------------------------------------------------------------

View file

@ -106,8 +106,8 @@ void animatewalls_d(void)
switch (wal->overpicnum)
{
case DTILE_W_FORCEFIELD:
case DTILE_W_FORCEFIELD + 1:
case DTILE_W_FORCEFIELD + 2:
case DTILE_W_FORCEFIELD2:
case DTILE_W_FORCEFIELD3:
t = animwall[p].tag;
@ -128,13 +128,13 @@ void animatewalls_d(void)
{
if (animwall[p].tag & 128)
wal->overpicnum = DTILE_W_FORCEFIELD;
else wal->overpicnum = DTILE_W_FORCEFIELD + 1;
else wal->overpicnum = DTILE_W_FORCEFIELD2;
}
else
{
if ((krand() & 255) < 32)
animwall[p].tag = 128 << (krand() & 3);
else wal->overpicnum = DTILE_W_FORCEFIELD + 1;
else wal->overpicnum = DTILE_W_FORCEFIELD2;
}
}
@ -151,7 +151,7 @@ void animatewalls_d(void)
void operateforcefields_d(DDukeActor* act, int low)
{
operateforcefields_common(act, low, { DTILE_W_FORCEFIELD, DTILE_W_FORCEFIELD + 1, DTILE_W_FORCEFIELD + 2, DTILE_BIGFORCE });
operateforcefields_common(act, low, { DTILE_W_FORCEFIELD, DTILE_W_FORCEFIELD2, DTILE_W_FORCEFIELD3, DTILE_BIGFORCE });
}
//---------------------------------------------------------------------------
@ -557,249 +557,6 @@ void activatebysector_d(sectortype* sect, DDukeActor* activator)
//
//---------------------------------------------------------------------------
void checkhitwall_d(DDukeActor* spr, walltype* wal, const DVector3& pos, int atwith)
{
int j, sn = -1, darkestwall;
if (wal->overpicnum == DTILE_MIRROR && atwith != -1 && gs.actorinfo[atwith].flags2 & SFLAG2_BREAKMIRRORS)
{
lotsofglass(spr, wal, 70);
wal->cstat &= ~CSTAT_WALL_MASKED;
wal->overpicnum = DTILE_MIRRORBROKE;
wal->portalflags = 0;
S_PlayActorSound(GLASS_HEAVYBREAK, spr);
return;
}
if (((wal->cstat & CSTAT_WALL_MASKED) || wal->overpicnum == DTILE_BIGFORCE) && wal->twoSided())
if (wal->nextSector()->floorz> pos.Z)
if (wal->nextSector()->floorz - wal->nextSector()->ceilingz)
switch (wal->overpicnum)
{
case DTILE_W_FORCEFIELD:
case DTILE_W_FORCEFIELD + 1:
case DTILE_W_FORCEFIELD + 2:
wal->extra = 1; // tell the forces to animate
[[fallthrough]];
case DTILE_BIGFORCE:
{
sectortype* sptr = nullptr;
updatesector(pos, &sptr);
if (sptr == nullptr) return;
DDukeActor* spawned;
if (atwith == -1)
spawned = CreateActor(sptr, pos, DTILE_FORCERIPPLE, -127, DVector2(0.125, 0.125), nullAngle, 0., 0., spr, 5);
else
{
if (atwith == DTILE_CHAINGUN)
spawned = CreateActor(sptr, pos, DTILE_FORCERIPPLE, -127, DVector2(0.25, 0.25) + spr->spr.scale, nullAngle, 0., 0., spr, 5);
else spawned = CreateActor(sptr, pos, DTILE_FORCERIPPLE, -127, DVector2(0.5, 0.5), nullAngle, 0., 0., spr, 5);
}
if (spawned)
{
spawned->spr.cstat |= CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_YCENTER;
spawned->spr.Angles.Yaw = wal->delta().Angle() + DAngle90;
S_PlayActorSound(SOMETHINGHITFORCE, spawned);
}
return;
}
case DTILE_FANSPRITE:
wal->overpicnum = DTILE_FANSPRITEBROKE;
wal->cstat &= ~(CSTAT_WALL_BLOCK | CSTAT_WALL_BLOCK_HITSCAN);
if (wal->twoSided())
{
wal->nextWall()->overpicnum = DTILE_FANSPRITEBROKE;
wal->nextWall()->cstat &= ~(CSTAT_WALL_BLOCK | CSTAT_WALL_BLOCK_HITSCAN);
}
S_PlayActorSound(VENT_BUST, spr);
S_PlayActorSound(GLASS_BREAKING, spr);
return;
case DTILE_GLASS:
{
sectortype* sptr = nullptr;
updatesector(pos, &sptr);
if (sptr == nullptr) return;
wal->overpicnum = DTILE_GLASS2;
lotsofglass(spr, wal, 10);
wal->cstat = 0;
if (wal->twoSided())
wal->nextWall()->cstat = 0;
auto spawned = CreateActor(sptr, pos, SECTOREFFECTOR, 0, DVector2(0, 0), ps[0].GetActor()->spr.Angles.Yaw, 0., 0., spr, 3);
if (spawned)
{
spawned->spr.lotag = SE_128_GLASS_BREAKING;
spawned->temp_data[1] = 5;
spawned->temp_walls[0] = wal;
S_PlayActorSound(GLASS_BREAKING, spawned);
}
return;
}
case DTILE_STAINGLASS1:
sectortype* sptr = nullptr;
updatesector(pos, &sptr);
if (sptr == nullptr) return;
lotsofcolourglass(spr, wal, 80);
wal->cstat = 0;
if (wal->twoSided())
wal->nextWall()->cstat = 0;
S_PlayActorSound(VENT_BUST, spr);
S_PlayActorSound(GLASS_BREAKING, spr);
return;
}
switch (wal->picnum)
{
case DTILE_COLAMACHINE:
case DTILE_VENDMACHINE:
breakwall(wal->picnum + 2, spr, wal);
S_PlayActorSound(VENT_BUST, spr);
return;
case DTILE_OJ:
case DTILE_FEMPIC2:
case DTILE_FEMPIC3:
case DTILE_SCREENBREAK6:
case DTILE_SCREENBREAK7:
case DTILE_SCREENBREAK8:
case DTILE_SCREENBREAK1:
case DTILE_SCREENBREAK2:
case DTILE_SCREENBREAK3:
case DTILE_SCREENBREAK4:
case DTILE_SCREENBREAK5:
case DTILE_SCREENBREAK9:
case DTILE_SCREENBREAK10:
case DTILE_SCREENBREAK11:
case DTILE_SCREENBREAK12:
case DTILE_SCREENBREAK13:
case DTILE_SCREENBREAK14:
case DTILE_SCREENBREAK15:
case DTILE_SCREENBREAK16:
case DTILE_SCREENBREAK17:
case DTILE_SCREENBREAK18:
case DTILE_SCREENBREAK19:
case DTILE_BORNTOBEWILDSCREEN:
lotsofglass(spr, wal, 30);
wal->picnum = DTILE_W_SCREENBREAK + (krand() % 3);
S_PlayActorSound(GLASS_HEAVYBREAK, spr);
return;
case DTILE_W_TECHWALL5:
case DTILE_W_TECHWALL6:
case DTILE_W_TECHWALL7:
case DTILE_W_TECHWALL8:
case DTILE_W_TECHWALL9:
breakwall(wal->picnum + 1, spr, wal);
return;
case DTILE_W_MILKSHELF:
breakwall(DTILE_W_MILKSHELFBROKE, spr, wal);
return;
case DTILE_W_TECHWALL10:
breakwall(DTILE_W_HITTECHWALL10, spr, wal);
return;
case DTILE_W_TECHWALL1:
case DTILE_W_TECHWALL11:
case DTILE_W_TECHWALL12:
case DTILE_W_TECHWALL13:
case DTILE_W_TECHWALL14:
breakwall(DTILE_W_HITTECHWALL1, spr, wal);
return;
case DTILE_W_TECHWALL15:
breakwall(DTILE_W_HITTECHWALL15, spr, wal);
return;
case DTILE_W_TECHWALL16:
breakwall(DTILE_W_HITTECHWALL16, spr, wal);
return;
case DTILE_W_TECHWALL2:
breakwall(DTILE_W_HITTECHWALL2, spr, wal);
return;
case DTILE_W_TECHWALL3:
breakwall(DTILE_W_HITTECHWALL3, spr, wal);
return;
case DTILE_W_TECHWALL4:
breakwall(DTILE_W_HITTECHWALL4, spr, wal);
return;
case DTILE_ATM:
wal->picnum = DTILE_ATMBROKE;
fi.lotsofmoney(spr, 1 + (krand() & 7));
S_PlayActorSound(GLASS_HEAVYBREAK, spr);
break;
case DTILE_WALLLIGHT1:
case DTILE_WALLLIGHT2:
case DTILE_WALLLIGHT3:
case DTILE_WALLLIGHT4:
case DTILE_TECHLIGHT2:
case DTILE_TECHLIGHT4:
if (rnd(128))
S_PlayActorSound(GLASS_HEAVYBREAK, spr);
else S_PlayActorSound(GLASS_BREAKING, spr);
lotsofglass(spr, wal, 30);
if (wal->picnum == DTILE_WALLLIGHT1)
wal->picnum = DTILE_WALLLIGHTBUST1;
if (wal->picnum == DTILE_WALLLIGHT2)
wal->picnum = DTILE_WALLLIGHTBUST2;
if (wal->picnum == DTILE_WALLLIGHT3)
wal->picnum = DTILE_WALLLIGHTBUST3;
if (wal->picnum == DTILE_WALLLIGHT4)
wal->picnum = DTILE_WALLLIGHTBUST4;
if (wal->picnum == DTILE_TECHLIGHT2)
wal->picnum = DTILE_TECHLIGHTBUST2;
if (wal->picnum == DTILE_TECHLIGHT4)
wal->picnum = DTILE_TECHLIGHTBUST4;
if (!wal->lotag) return;
if (!wal->twoSided()) return;
darkestwall = 0;
for (auto& wl : wal->nextSector()->walls)
if (wl.shade > darkestwall)
darkestwall = wl.shade;
j = krand() & 1;
DukeStatIterator it(STAT_EFFECTOR);
while (auto effector = it.Next())
{
if (effector->spr.hitag == wal->lotag && effector->spr.lotag == SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT)
{
effector->temp_data[2] = j;
effector->temp_data[3] = darkestwall;
effector->temp_data[4] = 1;
}
}
break;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void checkplayerhurt_d(player_struct* p, const Collision& coll)
{
if (coll.type == kHitSprite)
@ -825,12 +582,12 @@ void checkplayerhurt_d(player_struct* p, const Collision& coll)
p->vel.XY() = -p->GetActor()->spr.Angles.Yaw.ToVector() * 16;
S_PlayActorSound(DUKE_LONGTERM_PAIN, p->GetActor());
fi.checkhitwall(p->GetActor(), wal, p->GetActor()->getPosWithOffsetZ() + p->GetActor()->spr.Angles.Yaw.ToVector() * 2, -1);
checkhitwall(p->GetActor(), wal, p->GetActor()->getPosWithOffsetZ() + p->GetActor()->spr.Angles.Yaw.ToVector() * 2);
break;
case DTILE_BIGFORCE:
p->hurt_delay = 26;
fi.checkhitwall(p->GetActor(), wal, p->GetActor()->getPosWithOffsetZ() + p->GetActor()->spr.Angles.Yaw.ToVector() * 2, -1);
checkhitwall(p->GetActor(), wal, p->GetActor()->getPosWithOffsetZ() + p->GetActor()->spr.Angles.Yaw.ToVector() * 2);
break;
}

View file

@ -46,8 +46,6 @@ BEGIN_DUKE_NS
void animatewalls_r(void)
{
int t;
if (isRRRA() &&ps[screenpeek].sea_sick_stat == 1)
{
for (auto& wal : wall)
@ -101,45 +99,6 @@ void animatewalls_r(void)
continue;
}
if (wal->cstat & CSTAT_WALL_MASKED)
switch (wal->overpicnum)
{
case RTILE_W_FORCEFIELD:
case RTILE_W_FORCEFIELD + 1:
case RTILE_W_FORCEFIELD + 2:
t = animwall[p].tag;
if (wal->cstat & CSTAT_WALL_ANY_EXCEPT_BLOCK)
{
wal->addxpan(-t / 4096.f);
wal->addypan(-t / 4096.f);
if (wal->extra == 1)
{
wal->extra = 0;
animwall[p].tag = 0;
}
else
animwall[p].tag += 128;
if (animwall[p].tag < (128 << 4))
{
if (animwall[p].tag & 128)
wal->overpicnum = RTILE_W_FORCEFIELD;
else wal->overpicnum = RTILE_W_FORCEFIELD + 1;
}
else
{
if ((krand() & 255) < 32)
animwall[p].tag = 128 << (krand() & 3);
else wal->overpicnum = RTILE_W_FORCEFIELD + 1;
}
}
break;
}
}
}
@ -726,325 +685,6 @@ void activatebysector_r(sectortype* sect, DDukeActor* activator)
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void lotsofpopcorn(DDukeActor *actor, walltype* wal, int n)
{
sectortype* sect = nullptr;
if (wal == nullptr)
{
for (int j = n - 1; j >= 0; j--)
{
DAngle a = actor->spr.Angles.Yaw - DAngle45 + DAngle180 + randomAngle(90);
auto vel = krandf(4) + 2;
auto zvel = 4 - krandf(4);
CreateActor(actor->sector(), actor->spr.pos, RTILE_POPCORN, -32, DVector2(0.5625, 0.5625), a, vel, zvel, actor, 5);
}
return;
}
auto pos = wal->pos;
auto delta = wal->delta() / (n + 1);
pos.X -= Sgn(delta.X) * maptoworld;
pos.Y += Sgn(delta.Y) * maptoworld;
for (int j = n; j > 0; j--)
{
pos += delta;
sect = actor->sector();
updatesector(DVector3(pos, sect->floorz), &sect);
if (sect)
{
double z = sect->floorz - krandf(abs(sect->ceilingz - sect->floorz));
if (abs(z) > 32)
z = actor->spr.pos.Z - 32 + krandf(64);
DAngle a = actor->spr.Angles.Yaw - DAngle180;
auto vel = krandf(4) + 2;
auto zvel = -krandf(4);
CreateActor(actor->sector(), DVector3(pos, z), RTILE_POPCORN, -32, DVector2(0.5625, 0.5625), a, vel, zvel, actor, 5);
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void checkhitwall_r(DDukeActor* spr, walltype* wal, const DVector3& pos, int atwith)
{
int j;
int darkestwall;
if (wal->overpicnum == RTILE_MIRROR && atwith != -1 && gs.actorinfo[atwith].flags2 & SFLAG2_BREAKMIRRORS)
{
lotsofglass(spr, wal, 70);
wal->cstat &= ~CSTAT_WALL_MASKED;
wal->overpicnum = RTILE_MIRRORBROKE;
wal->portalflags = 0;
S_PlayActorSound(GLASS_HEAVYBREAK, spr);
return;
}
if (((wal->cstat & CSTAT_WALL_MASKED) || wal->overpicnum == RTILE_BIGFORCE) && wal->twoSided())
if (wal->nextSector()->floorz > pos.Z)
if (wal->nextSector()->floorz - wal->nextSector()->ceilingz)
switch (wal->overpicnum)
{
case RTILE_FANSPRITE:
wal->overpicnum = RTILE_FANSPRITEBROKE;
wal->cstat &= ~(CSTAT_WALL_BLOCK | CSTAT_WALL_BLOCK_HITSCAN);
if (wal->twoSided())
{
wal->nextWall()->overpicnum = RTILE_FANSPRITEBROKE;
wal->nextWall()->cstat &= ~(CSTAT_WALL_BLOCK | CSTAT_WALL_BLOCK_HITSCAN);
}
S_PlayActorSound(VENT_BUST, spr);
S_PlayActorSound(GLASS_BREAKING, spr);
return;
case RTILE_RRTILE1973:
{
sectortype* sptr = nullptr;
updatesector(pos, &sptr);
if (sptr == nullptr) return;
wal->overpicnum = RTILE_GLASS2;
lotsofpopcorn(spr, wal, 64);
wal->cstat = 0;
if (wal->twoSided())
wal->nextWall()->cstat = 0;
auto spawned = CreateActor(sptr, pos, SECTOREFFECTOR, 0, DVector2(0, 0), ps[0].GetActor()->spr.Angles.Yaw, 0., 0., spr, 3);
if (spawned)
{
spawned->spr.lotag = SE_128_GLASS_BREAKING;
spawned->temp_walls[0] = wal;
S_PlayActorSound(GLASS_BREAKING, spawned);
}
return;
}
case RTILE_GLASS:
{
sectortype* sptr = nullptr;
updatesector(pos, &sptr);
if (sptr == nullptr) return;
wal->overpicnum = RTILE_GLASS2;
lotsofglass(spr, wal, 10);
wal->cstat = 0;
if (wal->twoSided())
wal->nextWall()->cstat = 0;
auto spawned = CreateActor(sptr, pos, SECTOREFFECTOR, 0, DVector2(0, 0), ps[0].GetActor()->spr.Angles.Yaw, 0., 0., spr, 3);
if (spawned)
{
spawned->spr.lotag = SE_128_GLASS_BREAKING;
spawned->temp_data[1] = 2;
spawned->temp_walls[0] = wal;
S_PlayActorSound(GLASS_BREAKING, spawned);
}
return;
}
case RTILE_STAINGLASS1:
{
sectortype* sptr = nullptr;
updatesector(pos, &sptr);
if (sptr == nullptr) return;
lotsofcolourglass(spr, wal, 80);
wal->cstat = 0;
if (wal->twoSided())
wal->nextWall()->cstat = 0;
S_PlayActorSound(VENT_BUST, spr);
S_PlayActorSound(GLASS_BREAKING, spr);
return;
}
}
auto data = breakWallMap.CheckKey(wal->picnum);
if (data)
{
if (!data->handler)
{
wal->picnum = data->brokentex;
S_PlayActorSound(data->breaksound, spr);
}
else
{
VMValue args[4] = { wal, data->brokentex, data->breaksound.index(), spr};
VMCall(data->handler, args, 4, nullptr, 0);
}
}
else switch (wal->picnum)
{
case RTILE_IRONWHEELSWITCH:
if (isRRRA()) break;
break;
case RTILE_PICKUPSIDE:
case RTILE_PICKUPFRONT:
case RTILE_PICKUPBACK1:
case RTILE_PICKUPBACK2:
{
auto sect = wal->nextWall()->nextSector();
DukeSectIterator it(sect);
while (auto act = it.Next())
{
if (act->spr.lotag == 6)
{
act->spriteextra++;
if (act->spriteextra == 25)
{
for(auto& wl : act->sector()->walls)
{
if (wl.twoSided()) wl.nextSector()->lotag = 0;
}
act->sector()->lotag = 0;
S_StopSound(act->spr.lotag);
S_PlayActorSound(400, act);
act->Destroy();
}
}
}
return;
}
case RTILE_COLAMACHINE:
case RTILE_VENDMACHINE:
breakwall(wal->picnum + 2, spr, wal);
S_PlayActorSound(GLASS_BREAKING, spr);
return;
case RTILE_OJ:
case RTILE_SCREENBREAK6:
case RTILE_SCREENBREAK7:
case RTILE_SCREENBREAK8:
lotsofglass(spr, wal, 30);
wal->picnum = RTILE_W_SCREENBREAK + (krand() % (isRRRA() ? 2 : 3));
S_PlayActorSound(GLASS_HEAVYBREAK, spr);
return;
case RTILE_ATM:
wal->picnum = RTILE_ATMBROKE;
fi.lotsofmoney(spr, 1 + (krand() & 7));
S_PlayActorSound(GLASS_HEAVYBREAK, spr);
break;
case RTILE_WALLLIGHT1:
case RTILE_WALLLIGHT3:
case RTILE_WALLLIGHT4:
case RTILE_TECHLIGHT2:
case RTILE_TECHLIGHT4:
case RTILE_RRTILE1814:
case RTILE_RRTILE1939:
case RTILE_RRTILE1986:
case RTILE_RRTILE1988:
case RTILE_RRTILE2123:
case RTILE_RRTILE2125:
case RTILE_RRTILE2636:
case RTILE_RRTILE2878:
case RTILE_RRTILE2898:
case RTILE_RRTILE3200:
case RTILE_RRTILE3202:
case RTILE_RRTILE3204:
case RTILE_RRTILE3206:
case RTILE_RRTILE3208:
if (rnd(128))
S_PlayActorSound(GLASS_HEAVYBREAK, spr);
else S_PlayActorSound(GLASS_BREAKING, spr);
lotsofglass(spr, wal, 30);
if (wal->picnum == RTILE_RRTILE1814)
wal->picnum = RTILE_RRTILE1817;
if (wal->picnum == RTILE_RRTILE1986)
wal->picnum = RTILE_RRTILE1987;
if (wal->picnum == RTILE_RRTILE1939)
wal->picnum = RTILE_RRTILE2004;
if (wal->picnum == RTILE_RRTILE1988)
wal->picnum = RTILE_RRTILE2005;
if (wal->picnum == RTILE_RRTILE2898)
wal->picnum = RTILE_RRTILE2899;
if (wal->picnum == RTILE_RRTILE2878)
wal->picnum = RTILE_RRTILE2879;
if (wal->picnum == RTILE_RRTILE2123)
wal->picnum = RTILE_RRTILE2124;
if (wal->picnum == RTILE_RRTILE2125)
wal->picnum = RTILE_RRTILE2126;
if (wal->picnum == RTILE_RRTILE3200)
wal->picnum = RTILE_RRTILE3201;
if (wal->picnum == RTILE_RRTILE3202)
wal->picnum = RTILE_RRTILE3203;
if (wal->picnum == RTILE_RRTILE3204)
wal->picnum = RTILE_RRTILE3205;
if (wal->picnum == RTILE_RRTILE3206)
wal->picnum = RTILE_RRTILE3207;
if (wal->picnum == RTILE_RRTILE3208)
wal->picnum = RTILE_RRTILE3209;
if (wal->picnum == RTILE_RRTILE2636)
wal->picnum = RTILE_RRTILE2637;
if (wal->picnum == RTILE_WALLLIGHT1)
wal->picnum = RTILE_WALLLIGHTBUST1;
if (wal->picnum == RTILE_WALLLIGHT3)
wal->picnum = RTILE_WALLLIGHTBUST3;
if (wal->picnum == RTILE_WALLLIGHT4)
wal->picnum = RTILE_WALLLIGHTBUST4;
if (wal->picnum == RTILE_TECHLIGHT2)
wal->picnum = RTILE_TECHLIGHTBUST2;
if (wal->picnum == RTILE_TECHLIGHT4)
wal->picnum = RTILE_TECHLIGHTBUST4;
if (!wal->lotag) return;
if (!wal->twoSided()) return;
darkestwall = 0;
for (auto& wl : wal->nextSector()->walls)
if (wl.shade > darkestwall)
darkestwall = wl.shade;
j = krand() & 1;
DukeStatIterator it(STAT_EFFECTOR);
while (auto act = it.Next())
{
if (act->spr.hitag == wal->lotag && act->spr.lotag == SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT)
{
act->temp_data[2] = j;
act->temp_data[3] = darkestwall;
act->temp_data[4] = 1;
}
}
break;
}
}
//---------------------------------------------------------------------------
//
//
@ -1068,7 +708,7 @@ void checkplayerhurt_r(player_struct* p, const Collision &coll)
{
case RTILE_BIGFORCE:
p->hurt_delay = 26;
fi.checkhitwall(p->GetActor(), wal, p->GetActor()->getPosWithOffsetZ() + p->GetActor()->spr.Angles.Yaw.ToVector() * 2, -1);
checkhitwall(p->GetActor(), wal, p->GetActor()->getPosWithOffsetZ() + p->GetActor()->spr.Angles.Yaw.ToVector() * 2);
break;
}

View file

@ -119,6 +119,7 @@ DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, PClassActor*
}
s_pn = act->spr.picnum;
memset(act->temp_data, 0, sizeof(act->temp_data));
if (gs.actorinfo[s_pn].scriptaddress)
{
@ -281,7 +282,7 @@ DDukeActor* spawn(DDukeActor* actj, PClassActor * cls)
//
//---------------------------------------------------------------------------
void spawninitdefault(DDukeActor* actj, DDukeActor *act)
bool spawninitdefault(DDukeActor* actj, DDukeActor *act)
{
if (gs.actorinfo[act->spr.picnum].scriptaddress)
{
@ -290,7 +291,7 @@ void spawninitdefault(DDukeActor* actj, DDukeActor *act)
// make it go away...
act->spr.scale = DVector2(0, 0);
ChangeActorStat(act, STAT_MISC);
return;
return false;
}
// Init the size
@ -303,7 +304,7 @@ void spawninitdefault(DDukeActor* actj, DDukeActor *act)
{
act->spr.scale = DVector2(0, 0);
ChangeActorStat(act, STAT_MISC);
return;
return false;
}
makeitfall(act);
@ -335,6 +336,7 @@ void spawninitdefault(DDukeActor* actj, DDukeActor *act)
if (actj)
act->spr.Angles.Yaw = actj->spr.Angles.Yaw;
}
return true;
}
//---------------------------------------------------------------------------

View file

@ -49,9 +49,18 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
act->spr.hitag = -1;
}
if (iseffector(act))
{
// for in-game spawned SE's the init code must not run. The only type ever being spawned that way is SE128 -
// but we cannot check that here as the number has not been set yet.
if (actj == 0) spawneffector(act, actors);
return act;
}
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
{
CallInitialize(act);
if (spawninitdefault(actj, act))
CallInitialize(act);
return act;
}
auto sectp = act->sector();
@ -549,10 +558,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
ChangeActorStat(act, STAT_STANDABLE);
break;
case SECTOREFFECTOR:
spawneffector(act, actors);
break;
case DTILE_RUBBERCAN:
act->spr.extra = 0;
[[fallthrough]];

View file

@ -43,9 +43,16 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
act->spr.hitag = -1;
}
if (iseffector(act))
{
spawneffector(act, actors);
return act;
}
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
{
CallInitialize(act);
if (spawninitdefault(actj, act))
CallInitialize(act);
return act;
}
auto sectp = act->sector();
@ -657,9 +664,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
case RTILE_CEILINGSTEAM:
ChangeActorStat(act, STAT_STANDABLE);
break;
case SECTOREFFECTOR:
spawneffector(act, actors);
break;
case RTILE_RUBBERCAN:
act->spr.extra = 0;

View file

@ -1247,6 +1247,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, SpawnActor, DukeLevel_SpawnActor)
PARAM_FLOAT(zvel);
PARAM_OBJECT(owner, DDukeActor);
PARAM_INT(stat);
ACTION_RETURN_POINTER(DukeLevel_SpawnActor(self, sect, x, y, z, static_cast<PClassActor*>(type), shade, scalex, scaley, angle, vel, zvel, owner, stat));
}
@ -1325,7 +1326,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, ismirror, duke_ismirror)
void duke_checkhitwall(walltype* wal, DDukeActor * actor, double x, double y, double z)
{
fi.checkhitwall(actor, wal, DVector3(x, y, z), actor->spr.picnum);
checkhitwall(actor, wal, DVector3(x, y, z));
}
DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, checkhitwall, duke_checkhitwall)

View file

@ -689,8 +689,6 @@ void AddFlow(sectortype* pSector, int nSpeed, int b, DAngle nAngle)
int nFlow = nFlowCount;
nFlowCount++;
int nPic = pSector->floorpicnum;
sFlowInfo[nFlow].angcos = float(-nAngle.Cos() * nSpeed);
sFlowInfo[nFlow].angsin = float(nAngle.Sin() * nSpeed);
sFlowInfo[nFlow].pSector = pSector;

View file

@ -0,0 +1,60 @@
breakwalls
{
BIGFORCE = "", "SOMETHINGHITFORCE", "DukeBreakwalls.ForcefieldHit", twosided
W_FORCEFIELD = "", "SOMETHINGHITFORCE", "DukeBreakwalls.ForcefieldHitAnim", twosided, maskedonly
W_FORCEFIELD2 = "", "SOMETHINGHITFORCE", "DukeBreakwalls.ForcefieldHitAnim", twosided, maskedonly
W_FORCEFIELD3 = "", "SOMETHINGHITFORCE", "DukeBreakwalls.ForcefieldHitAnim", twosided, maskedonly
FANSPRITE = FANSPRITEBROKE, "VENT_BUST", "DukeBreakwalls.FanSpriteHit", twosided, maskedonly // also RR
GLASS = GLASS2, "GLASS_BREAKING", "DukeBreakwalls.GlassHit", twosided, maskedonly // also RR
STAINGLASS1 = "", "GLASS_BREAKING", "DukeBreakwalls.StainGlassHit", twosided, maskedonly // also RR
COLAMACHINE = COLAMACHINEBROKE, "GLASS_BREAKING", "DukeBreakWalls.TechStuffBreak"
VENDMACHINE = VENDMACHINEBROKE, "VENT_BUST", "DukeBreakWalls.TechStuffBreak"
OJ = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
FEMPIC2 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
FEMPIC3 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK6 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK7 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK8 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK1 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK2 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK3 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK4 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK5 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK9 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK10 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK11 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK12 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK13 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK14 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK15 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK16 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK17 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK18 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK19 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
BORNTOBEWILDSCREEN = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
W_TECHWALL5 = W_TECHWALL5B, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL6 = W_TECHWALL6B, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL7 = W_TECHWALL7B, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL8 = W_TECHWALL8B, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL9 = W_TECHWALL9B, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL9 = W_TECHWALL9B, "", "DukeBreakWalls.TechStuffBreak"
W_MILKSHELF = W_MILKSHELFBROKE, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL10 = W_HITTECHWALL10, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL1 = W_HITTECHWALL1, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL11 = W_HITTECHWALL1, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL12 = W_HITTECHWALL1, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL13 = W_HITTECHWALL1, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL14 = W_HITTECHWALL1, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL2 = W_HITTECHWALL2, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL3 = W_HITTECHWALL3, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL4 = W_HITTECHWALL4, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL15 = W_HITTECHWALL15, "", "DukeBreakWalls.TechStuffBreak"
W_TECHWALL16 = W_HITTECHWALL16, "", "DukeBreakWalls.TechStuffBreak"
WALLLIGHT1 = WALLLIGHTBUST1, "", "DukeBreakWalls.LightBreak"
WALLLIGHT2 = WALLLIGHTBUST2, "", "DukeBreakWalls.LightBreak"
WALLLIGHT3 = WALLLIGHTBUST3, "", "DukeBreakWalls.LightBreak"
WALLLIGHT4 = WALLLIGHTBUST4, "", "DukeBreakWalls.LightBreak"
TECHLIGHT2 = TECHLIGHTBUST2, "", "DukeBreakWalls.LightBreak"
TECHLIGHT4 = TECHLIGHTBUST4, "", "DukeBreakWalls.LightBreak"
ATM = ATMBROKE, "GLASS_HEAVYBREAK", "DukeBreakWalls.ATMBreak"
}

View file

@ -1,5 +1,6 @@
spawnclasses
{
1 = DukeSectorEffector
2 = DukeActivator
3 = DukeTouchplate
4 = DukeActivatorLocked
@ -10,6 +11,7 @@ spawnclasses
9 = DukeRespawnController
10 = DukeGPSpeed
4890 = DukeNaturalLightning
2536 = DukeChaingun
1221 = DukeCranePole
1222 = DukeCrane
@ -231,4 +233,7 @@ spawnclasses
774 = DukeGenericDestructible, "SUSHIPLATE3", "", "GLASS_HEAVYBREAK", 8, blocking, spawnglass2
779 = DukeGenericDestructible, "SUSHIPLATE4", "", "GLASS_HEAVYBREAK", 8, blocking, spawnglass2
792 = DukeGenericDestructible, "SUSHIPLATE5", "", "GLASS_HEAVYBREAK", 8, blocking, spawnglass2
// the following actors use CON.
1671 = DukeForceRipple
}

View file

@ -162,5 +162,5 @@ tileflag TFLAG_BLOCKDOOR {
RRTILE3837
}
tileflag TFLAG_MUDDY { MUDDY MUDDYPATH }
tileflag TFLAG_MUDDY { MUDDY }

View file

@ -0,0 +1,39 @@
breakwalls
{
FANSPRITE = FANSPRITEBROKE, "VENT_BUST", "DukeBreakwalls.FanSpriteHit", twosided, maskedonly
GLASS = GLASS2, "GLASS_BREAKING", "DukeBreakwalls.GlassHit", twosided, maskedonly
STAINGLASS1 = "", "GLASS_BREAKING", "DukeBreakwalls.StainGlassHit", twosided, maskedonly
COLAMACHINE = COLAMACHINEBROKE, "GLASS_BREAKING", "DukeBreakWalls.TechStuffBreak"
VENDMACHINE = VENDMACHINEBROKE, "VENT_BUST", "DukeBreakWalls.TechStuffBreak"
OJ = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK6 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK7 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
SCREENBREAK8 = "", "GLASS_HEAVYBREAK", "DukeBreakWalls.ScreenBreak"
ATM = ATMBROKE, "GLASS_HEAVYBREAK", "DukeBreakWalls.ATMBreak"
WALLLIGHT1 = WALLLIGHTBUST1, "", "DukeBreakWalls.LightBreak"
WALLLIGHT3 = WALLLIGHTBUST3, "", "DukeBreakWalls.LightBreak"
WALLLIGHT4 = WALLLIGHTBUST4, "", "DukeBreakWalls.LightBreak"
TECHLIGHT2 = TECHLIGHTBUST2, "", "DukeBreakWalls.LightBreak"
TECHLIGHT4 = TECHLIGHTBUST4, "", "DukeBreakWalls.LightBreak"
RRTILE1814 = RRTILE1817, "", "DukeBreakWalls.LightBreak"
RRTILE1986 = RRTILE1987, "", "DukeBreakWalls.LightBreak"
RRTILE1939 = RRTILE2004, "", "DukeBreakWalls.LightBreak"
RRTILE1988 = RRTILE2005, "", "DukeBreakWalls.LightBreak"
RRTILE2898 = RRTILE2899, "", "DukeBreakWalls.LightBreak"
RRTILE2878 = RRTILE2879, "", "DukeBreakWalls.LightBreak"
RRTILE2123 = RRTILE2124, "", "DukeBreakWalls.LightBreak"
RRTILE2125 = RRTILE2126, "", "DukeBreakWalls.LightBreak"
RRTILE3200 = RRTILE3201, "", "DukeBreakWalls.LightBreak"
RRTILE3202 = RRTILE3203, "", "DukeBreakWalls.LightBreak"
RRTILE3204 = RRTILE3205, "", "DukeBreakWalls.LightBreak"
RRTILE3206 = RRTILE3207, "", "DukeBreakWalls.LightBreak"
RRTILE3208 = RRTILE3209, "", "DukeBreakWalls.LightBreak"
RRTILE2636 = RRTILE2637, "", "DukeBreakWalls.LightBreak"
RRTILE1973 = GLASS2, "GLASS_BREAKING", "RedneckBreakwalls.PopcornHit", twosided, maskedonly
PICKUPSIDE = "", "TRUKDIE", "RedneckBreakwalls.PickupHit"
PICKUPFRONT = "", "TRUKDIE", "RedneckBreakwalls.PickupHit"
PICKUPBACK1 = "", "TRUKDIE", "RedneckBreakwalls.PickupHit"
PICKUPBACK2 = "", "TRUKDIE", "RedneckBreakwalls.PickupHit"
}

View file

@ -1,5 +1,6 @@
spawnclasses
{
1 = DukeSectorEffector
2 = DukeActivator
3 = DukeTouchplate
4 = DukeActivatorLocked
@ -23,6 +24,7 @@ spawnclasses
38 = RedneckJaildoorSound
19 = RedneckGeometryEffect
34 = RedneckKeyinfoSetter
3380 = DukeChaingun
1298 = DukeCranePole
1299 = DukeCrane
@ -176,6 +178,7 @@ spawnclasses
2137 = RedneckFlamingo
2151 = RedneckMarbleStatue
2152 = RedneckMarbleStatue2
2021 = RedneckPopcorn
3114 = DukeGenericDestructible, "RRTILE3114", "RRTILE3117", "GLASS_BREAKING", spawnglass
2876 = DukeGenericDestructible, "RRTILE2876", "RRTILE2990", "GLASS_BREAKING", spawnglass

View file

@ -61,6 +61,7 @@ version "4.10"
#include "zscript/games/duke/actors/frameeffect.zs"
#include "zscript/games/duke/actors/naturallightning.zs"
#include "zscript/games/duke/actors/_placeholders.zs"
#include "zscript/games/duke/actors/dukemisc.zs"
#include "zscript/games/duke/actors/projectiles.zs"
#include "zscript/games/duke/actors/mortar.zs"
@ -116,6 +117,7 @@ version "4.10"
#include "zscript/games/duke/actors/airplane.zs"
#include "zscript/games/duke/actors/piano.zs"
#include "zscript/games/duke/world/dukebreak.zs"
#include "zscript/games/duke/world/redneckbreak.zs"
#include "zscript/games/blood/bloodgame.zs"

View file

@ -0,0 +1,26 @@
// dummy items representing certain weapons
class DukeChaingun : DukeActor
{
default
{
pic "CHAINGUN";
}
}
class DukeSectorEffector : DukeActor
{
//This never gets ticked, the handler goes directly to the native implementations.
}
// placeholders for CON scripted actors where we need the class.
class DukeForceRipple : DukeActor
{
default
{
pic "FORCERIPPLE";
}
}

View file

@ -62,3 +62,11 @@ class RedneckJoe9000 : DukeActor
return true;
}
}
class RedneckPopcorn : DukeActor
{
default
{
pic "POPCORN";
}
}

View file

@ -82,8 +82,8 @@ class DukeSoundController : DukeActor
override void OnDestroy()
{
Super.OnDestroy();
if (self.temp_data[0] == 1)
self.StopSound(self.lotag);
self.StopSound(-1);
Super.OnDestroy();
}
}

View file

@ -0,0 +1,134 @@
class DukeBreakWalls
{
static void breakwall(TextureID newpn, DukeActor spr, walltype wal)
{
wal.SetTexture(walltype.main, newpn);
spr.PlayActorSound("VENT_BUST");
spr.PlayActorSound("GLASS_HEAVYBREAK");
spr.lotsofglass(10, wal);
}
static void ForcefieldHit(walltype wal, TextureID newtex, Sound snd, DukeActor spr, Vector3 pos)
{
sectortype sptr = Raze.updatesector(pos.XY, spr.sector);
if (sptr == nullptr) return;
double scale = spr.isPlayer()? 0.125 : spr is 'DukeChaingun'? 0.25 : 0.5;
let spawned = dlevel.SpawnActor(sptr, pos, 'DukeForceRipple', -127, (scale, scale), 0, 0., 0., spr, DukeActor.STAT_MISC);
if (spawned)
{
spawned.cstat |= CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_YCENTER;
spawned.angle = wal.delta().Angle() + 90;
spawned.PlayActorSound(snd);
}
}
static void ForcefieldHitAnim(walltype wal, TextureID newtex, Sound snd, DukeActor spr, Vector3 pos)
{
wal.extra = 1;
ForcefieldHit(wal, newtex, snd, spr, pos);
}
static void FanSpriteHit(walltype wal, TextureID newtex, Sound snd, DukeActor spr, Vector3 pos)
{
wal.SetTexture(walltype.over, newtex);
wal.cstat &= ~(CSTAT_WALL_BLOCK | CSTAT_WALL_BLOCK_HITSCAN);
let nwal = wal.nextwallp();
if (nwal)
{
nwal.SetTexture(walltype.over, newtex);
nwal.cstat &= ~(CSTAT_WALL_BLOCK | CSTAT_WALL_BLOCK_HITSCAN);
}
spr.PlayActorSound(snd);
spr.PlayActorSound("GLASS_BREAKING");
}
static void GlassHit(walltype wal, TextureID newtex, Sound snd, DukeActor spr, Vector3 pos)
{
let sptr = Raze.updatesector(pos.XY, spr.sector);
if (sptr == nullptr) return;
wal.setTexture(walltype.over, newtex);
spr.lotsofglass(10, wal);
wal.cstat = 0;
let nwal = wal.nextwallp();
if (nwal) nwal.cstat = 0;
let spawned = dlevel.SpawnActor(sptr, pos, "DukeSectorEffector", 0, (0, 0), spr.Angle, 0., 0., spr, DukeActor.STAT_EFFECTOR);
if (spawned)
{
spawned.lotag = SE_128_GLASS_BREAKING;
spawned.temp_data[1] = 5;
spawned.temp_walls[0] = wal;
spawned.PlayActorSound(snd);
}
}
static void StainGlassHit(walltype wal, TextureID newtex, Sound snd, DukeActor spr, Vector3 pos)
{
let sptr = Raze.updatesector(pos.XY, spr.sector);
if (sptr == nullptr) return;
wal.setTexture(walltype.over, newtex);
spr.lotsofcolourglass(10, wal);
wal.cstat = 0;
let nwal = wal.nextwallp();
if (nwal) nwal.cstat = 0;
spr.PlayActorSound("VENT_BUST");
spr.PlayActorSound(snd);
}
static void TechStuffBreak(walltype wal, TextureID newtex, Sound snd, DukeActor spr, Vector3 pos)
{
breakwall(newtex, spr, wal);
spr.PlayActorSound(snd);
}
static void ScreenBreak(walltype wal, TextureID newtex, Sound snd, DukeActor spr, Vector3 pos)
{
static const String randbreak[] = { "W_SCREENBREAK", "W_SCREENBREAK2", "W_SCREENBREAK3" };
spr.lotsofglass(30, wal);
wal.SetTextureName(walltype.main, randbreak[random(0, 2)]);
spr.PlayActorSound(snd);
}
static void LightBreak(walltype wal, TextureID newtex, Sound snd, DukeActor spr, Vector3 pos)
{
if (Duke.rnd(128))
spr.PlayActorSound("GLASS_HEAVYBREAK");
else spr.PlayActorSound("GLASS_BREAKING");
spr.lotsofglass(30, wal);
wal.setTexture(walltype.main, newtex);
if (!wal.lotag) return;
if (!wal.twoSided()) return;
int darkestwall = 0;
let nextsect = wal.nextsectorp();
foreach (wl : nextsect.walls)
if (wl.shade > darkestwall)
darkestwall = wl.shade;
int j = random(0, 1);
DukeStatIterator it;
for(let effector = it.First(DukeActor.STAT_EFFECTOR); effector; effector = it.Next())
{
if (effector.hitag == wal.lotag && effector.lotag == SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT)
{
effector.temp_data[2] = j;
effector.temp_data[3] = darkestwall;
effector.temp_data[4] = 1;
}
}
}
static void ATMBreak(walltype wal, TextureID newtex, Sound snd, DukeActor spr, Vector3 pos)
{
wal.setTexture(walltype.main, newtex);
spr.PlayActorSound(snd);
spr.lotsofstuff('DukeMoney', random(1, 8));
}
}

View file

@ -3,16 +3,7 @@
class RedneckBreakWalls
{
static void breakwall(TextureID newpn, DukeActor spr, walltype wal)
{
wal.SetTexture(walltype.main, newpn);
spr.PlayActorSound("VENT_BUST");
spr.PlayActorSound("GLASS_HEAVYBREAK");
spr.lotsofglass(10, wal);
}
static void SinglePlayerBreak(walltype wal, TextureID newtex, Sound snd, DukeActor hitter)
static void SinglePlayerBreak(walltype wal, TextureID newtex, Sound snd, DukeActor hitter, Vector3 pos)
{
if (ud.multimode < 2)
{
@ -20,5 +11,91 @@ class RedneckBreakWalls
hitter.PlayActorSound(snd);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
private static int sgn(double v)
{
return (v > 0) - (v < 0);
}
}
static void lotsofpopcorn(DukeActor actor, walltype wal, int n)
{
let pos = wal.pos;
let delta = wal.delta() / (n + 1);
pos.X -= Sgn(delta.X) * maptoworld;
pos.Y += Sgn(delta.Y) * maptoworld;
for (int j = n; j > 0; j--)
{
pos += delta;
let sect = Raze.updatesector(pos, actor.sector);
if (sect)
{
double z = sect.floorz - frandom(0, abs(sect.ceilingz - sect.floorz));
if (abs(z) > 32)
z = actor.pos.Z - 32 + frandom(0, 64);
let a = actor.Angle - 180;
let vel = frandom(2, 6);
let zvel = -frandom(0, 4);
dlevel.SpawnActor(actor.sector, (pos, z), 'RedneckPopcorn', -32, (0.5625, 0.5625), a, vel, zvel, actor, DukeActor.STAT_MISC);
}
}
}
static void PopcornHit(walltype wal, TextureID newtex, Sound snd, DukeActor spr, Vector3 pos)
{
let sptr = Raze.updatesector(pos.XY, spr.sector);
if (sptr == nullptr) return;
wal.setTexture(walltype.over, newtex);
lotsofpopcorn(spr, wal, 64);
wal.cstat = 0;
let nwal = wal.nextwallp();
if (nwal) nwal.cstat = 0;
let spawned = dlevel.SpawnActor(sptr, pos, "DukeSectorEffector", 0, (0, 0), spr.Angle, 0., 0., spr, DukeActor.STAT_EFFECTOR);
if (spawned)
{
spawned.lotag = SE_128_GLASS_BREAKING;
//spawned.temp_data[1] = 5;
spawned.temp_walls[0] = wal;
spawned.PlayActorSound(snd);
}
}
static void PickupHit(walltype wal, TextureID newtex, Sound snd, DukeActor spr, Vector3 pos)
{
let sect = wal.sectorp();
DukeSectIterator it;
for(let act = it.First(sect); act; act = it.Next())
{
if (act.lotag == 6)
{
act.spriteextra++;
if (act.spriteextra == 25)
{
foreach(wl : sect.walls)
{
let nsec = wl.nextSectorp();
if (nsec) nsec.lotag = 0;
}
sect.lotag = 0;
act.StopSound(-1);
act.PlayActorSound(snd);
act.ChangeStat(DukeActor.STAT_REMOVED);
act.cstat2 |= CSTAT2_SPRITE_NOFIND;
act.lotag = 0;
}
}
}
}
}