mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-14 16:40:52 +00:00
- implemented customizable breakable walls and ported all hard coded variants to use this.
This commit is contained in:
parent
241636a907
commit
a63ee8079a
39 changed files with 511 additions and 720 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ xx(RedneckJaildoorDef)
|
|||
xx(RedneckJaildoorSound)
|
||||
xx(RedneckGeometryEffect)
|
||||
xx(RedneckKeyinfoSetter)
|
||||
xx(DukeSectorEffector)
|
||||
|
||||
xx(spawnstate)
|
||||
xx(brokenstate)
|
||||
|
|
|
@ -254,7 +254,7 @@ void hitradius_d(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h
|
|||
updatesector(w1, §);
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -207,7 +207,7 @@ void hitradius_r(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h
|
|||
updatesector(w1, §);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -282,7 +282,6 @@ static void setupbackdrop()
|
|||
static void initTiles()
|
||||
{
|
||||
tileDelete(TILE_MIRROR);
|
||||
//skiptile = TILE_W_FORCEFIELD + 1;
|
||||
|
||||
if (isRR())
|
||||
tileDelete(0);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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), §);
|
||||
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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -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]];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
60
wadsrc/static/filter/dukelike/rmapinfo.breakables
Normal file
60
wadsrc/static/filter/dukelike/rmapinfo.breakables
Normal 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"
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -162,5 +162,5 @@ tileflag TFLAG_BLOCKDOOR {
|
|||
RRTILE3837
|
||||
}
|
||||
|
||||
tileflag TFLAG_MUDDY { MUDDY MUDDYPATH }
|
||||
tileflag TFLAG_MUDDY { MUDDY }
|
||||
|
||||
|
|
39
wadsrc/static/filter/redneck/rmapinfo.breakables
Normal file
39
wadsrc/static/filter/redneck/rmapinfo.breakables
Normal 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"
|
||||
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
26
wadsrc/static/zscript/games/duke/actors/_placeholders.zs
Normal file
26
wadsrc/static/zscript/games/duke/actors/_placeholders.zs
Normal 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";
|
||||
}
|
||||
}
|
|
@ -62,3 +62,11 @@ class RedneckJoe9000 : DukeActor
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class RedneckPopcorn : DukeActor
|
||||
{
|
||||
default
|
||||
{
|
||||
pic "POPCORN";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
134
wadsrc/static/zscript/games/duke/world/dukebreak.zs
Normal file
134
wadsrc/static/zscript/games/duke/world/dukebreak.zs
Normal 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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue