- scriptified OozFilter + Seenine

Also fixing the default handling for onHit.
This commit is contained in:
Christoph Oelckers 2022-01-20 08:31:08 +01:00
parent 26ba1f601e
commit b106fb693a
27 changed files with 347 additions and 324 deletions

View file

@ -492,7 +492,7 @@ DEFINE_PROPERTY(owner, I, CoreActor)
//==========================================================================
DEFINE_PROPERTY(spriteset, Sssssssssssssssssssssssssssssss, CoreActor)
{
info->ActorInfo()->SpriteSet.Clear();
info->ActorInfo()->SpriteSetNames.Clear();
for (int i = 0; i < PROP_PARM_COUNT; ++i)
{
PROP_STRING_PARM(n, i);

View file

@ -884,83 +884,6 @@ void movetouchplate(DDukeActor* actor, int plate)
//
//---------------------------------------------------------------------------
void moveooz(DDukeActor* actor, int seenine, int seeninedead, int ooz, int explosion)
{
int j;
if (actor->spr.shade != -32 && actor->spr.shade != -33)
{
if (actor->spr.scale.X != 0)
j = (fi.ifhitbyweapon(actor) >= 0);
else
j = 0;
if (j || actor->spr.shade == -31)
{
if (j) actor->spr.lotag = 0;
actor->temp_data[3] = 1;
DukeStatIterator it(STAT_STANDABLE);
while (auto act2 = it.Next())
{
if (actor->spr.hitag == act2->spr.hitag && actorflag(act2, SFLAG2_BRIGHTEXPLODE))
act2->spr.shade = -32;
}
}
}
else
{
if (actor->spr.shade == -32)
{
if (actor->spr.lotag > 0)
{
actor->spr.lotag -= 3;
if (actor->spr.lotag <= 0) actor->spr.lotag = -99;
}
else
actor->spr.shade = -33;
}
else
{
if (actor->spr.scale.X > 0)
{
actor->temp_data[2]++;
if (actor->temp_data[2] == 3)
{
if (actor->spr.picnum == ooz)
{
actor->temp_data[2] = 0;
detonate(actor, explosion);
return;
}
if (actor->spr.picnum != (seeninedead + 1))
{
actor->temp_data[2] = 0;
if (actor->spr.picnum == seeninedead) actor->spr.picnum++;
else if (actor->spr.picnum == seenine)
actor->spr.picnum = seeninedead;
}
else
{
detonate(actor, explosion);
return;
}
}
return;
}
detonate(actor, explosion);
return;
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void movecanwithsomething(DDukeActor* actor)
{
makeitfall(actor);

View file

@ -945,11 +945,6 @@ void movestandables_d(void)
continue;
}
else if (picnum == OOZFILTER || picnum == SEENINE || picnum == SEENINEDEAD || picnum == (SEENINEDEAD + 1))
{
moveooz(act, SEENINE, SEENINEDEAD, OOZFILTER, EXPLOSION2);
}
else if (picnum == MASTERSWITCH)
{
movemasterswitch(act);

View file

@ -793,11 +793,6 @@ void movestandables_r(void)
continue;
}
else if (picnum == OOZFILTER || picnum == SEENINE || picnum == SEENINEDEAD || picnum == (SEENINEDEAD + 1))
{
moveooz(act, SEENINE, SEENINEDEAD, OOZFILTER, EXPLOSION2);
}
else if (picnum == MASTERSWITCH)
{
movemasterswitch(act);

View file

@ -359,6 +359,7 @@ enum sflags2_t
SFLAG2_CAMERA = 0x00000100,
SFLAG2_DONTANIMATE = 0x00000200,
SFLAG2_INTERPOLATEANGLE = 0x00000400,
SFLAG2_GREENBLOOD = 0x00000800,
};
using EDukeFlags2 = TFlags<sflags2_t, uint32_t>;

View file

@ -53,6 +53,8 @@ bool checkhitceiling_d(sectortype* sn);
bool checkhitceiling_r(sectortype* sn);
void checkhitsprite_d(DDukeActor* i, DDukeActor* sn);
void checkhitsprite_r(DDukeActor* i, DDukeActor* sn);
void checkhitdefault_d(DDukeActor* i, DDukeActor* sn);
void checkhitdefault_r(DDukeActor* i, DDukeActor* sn);
void checksectors_d(int snum);
void checksectors_r(int snum);
@ -119,6 +121,7 @@ void SetDispatcher()
checkhitwall_d,
checkhitceiling_d,
checkhitsprite_d,
checkhitdefault_d,
checksectors_d,
spawninit_d,
@ -161,6 +164,7 @@ void SetDispatcher()
checkhitwall_r,
checkhitceiling_r,
checkhitsprite_r,
checkhitdefault_r,
checksectors_r,
spawninit_r,

View file

@ -79,6 +79,7 @@ struct Dispatcher
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);
void (*checksectors)(int low);
DDukeActor* (*spawninit)(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>* actors);

View file

@ -224,6 +224,7 @@ void initactorflags_d()
setflag(SFLAG2_CAMERA, { CAMERA1 });
setflag(SFLAG2_DONTANIMATE, { TRIPBOMB, LASERLINE });
setflag(SFLAG2_INTERPOLATEANGLE, { BEARINGPLATE });
setflag(SFLAG2_GREENBLOOD, { OOZFILTER, NEWBEAST });
if (isWorldTour())
{

View file

@ -251,6 +251,7 @@ void initactorflags_r()
setflag(SFLAG2_BREAKMIRRORS, { RADIUSEXPLOSION, RPG, HYDRENT, DYNAMITE, SEENINE, OOZFILTER, EXPLODINGBARREL, POWDERKEG });
if (isRRRA()) setflag(SFLAG2_BREAKMIRRORS, { RPG2 });
setflag(SFLAG2_CAMERA, { CAMERA1 });
setflag(SFLAG2_GREENBLOOD, { OOZFILTER });
// Animals were not supposed to have this, but due to a coding bug the logic was unconditional for everything in the game.
for (auto& ainf : gs.actorinfo)

View file

@ -31,7 +31,6 @@ void movefta();
void clearcameras(int i, player_struct* p);
void RANDOMSCRAP(DDukeActor* i);
void movecrane(DDukeActor* i, int crane);
void detonate(DDukeActor* i, int explosion);
void movemasterswitch(DDukeActor* i);
void movetrash(DDukeActor* i);
@ -42,7 +41,6 @@ void movecanwithsomething(DDukeActor* i);
void bounce(DDukeActor* i);
void movetongue(DDukeActor* i, int tongue, int jaw);
void rpgexplode(DDukeActor* i, int j, const DVector3& pos, int EXPLOSION2, int EXPLOSIONBOT2, int newextra, int playsound);
void moveooz(DDukeActor* i, int seenine, int seeninedead, int ooz, int explosion);
void lotsofstuff(DDukeActor* s, int n, int spawntype);
bool respawnmarker(DDukeActor* i, int yellow, int green);
bool rat(DDukeActor* i, bool makesound);
@ -133,7 +131,7 @@ void quickkill(player_struct* p);
int setpal(player_struct* p);
int madenoise(int playerNum);
int haskey(sectortype* sect, int snum);
void shootbloodsplat(DDukeActor* i, int p, const DVector3& pos, DAngle ang, int atwith, int BIGFORCE, int OOZFILTER, int NEWBEAST);
void shootbloodsplat(DDukeActor* i, int p, const DVector3& pos, DAngle ang, int atwith, int BIGFORCE);
void breakwall(int newpn, DDukeActor* spr, walltype* dawallnum);
int callsound(sectortype* sectnum,DDukeActor* snum, bool endstate = false);

View file

@ -345,6 +345,7 @@ x(EXPLODINGBARREL2, 1239)
x(FIREBARREL, 1240)
x(SEENINE, 1247)
x(SEENINEDEAD, 1248)
x(SEENINEDEAD1, 1249)
x(STEAM, 1250)
x(CEILINGSTEAM, 1255)
x(PIPE6B, 1260)

View file

@ -411,6 +411,7 @@ x(EXPLODINGBARREL2, 1316)
x(FIREBARREL, 1317)
x(SEENINE, 1324)
x(SEENINEDEAD, 1325)
x(SEENINEDEAD1, 1326)
x(STEAM, 1327)
x(CEILINGSTEAM, 1332)
x(PIPE6B, 1337)

View file

@ -1008,7 +1008,7 @@ int haskey(sectortype* sectp, int snum)
//
//---------------------------------------------------------------------------
void shootbloodsplat(DDukeActor* actor, int p, const DVector3& pos, DAngle ang, int atwith, int BIGFORCE, int OOZFILTER, int NEWBEAST)
void shootbloodsplat(DDukeActor* actor, int p, const DVector3& pos, DAngle ang, int atwith, int BIGFORCE)
{
auto sectp = actor->sector();
double zvel;
@ -1059,7 +1059,7 @@ void shootbloodsplat(DDukeActor* actor, int p, const DVector3& pos, DAngle ang,
spawned->spr.cstat |= randomXFlip();
ssp(spawned, CLIPMASK0);
SetActor(spawned, spawned->spr.pos);
if (actor->spr.picnum == OOZFILTER || actor->spr.picnum == NEWBEAST)
if (actorflag(actor, SFLAG2_GREENBLOOD))
spawned->spr.pal = 6;
}
}

View file

@ -1126,7 +1126,7 @@ void shoot_d(DDukeActor* actor, int atwith)
case BLOODSPLAT2:
case BLOODSPLAT3:
case BLOODSPLAT4:
shootbloodsplat(actor, p, spos, sang, atwith, BIGFORCE, OOZFILTER, NEWBEAST);
shootbloodsplat(actor, p, spos, sang, atwith, BIGFORCE);
break;
case KNEE:

View file

@ -853,7 +853,7 @@ void shoot_r(DDukeActor* actor, int atwith)
case BLOODSPLAT2:
case BLOODSPLAT3:
case BLOODSPLAT4:
shootbloodsplat(actor, p, spos, sang, atwith, BIGFORCE, OOZFILTER, -1);
shootbloodsplat(actor, p, spos, sang, atwith, BIGFORCE);
return;
case SLINGBLADE:

View file

@ -155,8 +155,6 @@ static void cachespritenum(DDukeActor* actor)
maxc = 10;
break;
case EXPLODINGBARREL:
case SEENINE:
case OOZFILTER:
maxc = 3;
break;
case NUKEBARREL:

View file

@ -263,8 +263,6 @@ static void cachespritenum(DDukeActor* actor)
maxc = 6;
break;
case EXPLODINGBARREL:
case SEENINE:
case OOZFILTER:
maxc = 3;
break;
case NUKEBARREL:

View file

@ -999,9 +999,124 @@ bool checkhitceiling_d(sectortype* sectp)
//
//---------------------------------------------------------------------------
void checkhitdefault_d(DDukeActor* targ, DDukeActor* proj)
{
if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_WALL) && targ->spr.hitag == 0 && targ->spr.lotag == 0 && targ->spr.statnum == 0)
return;
if ((proj->spr.picnum == FREEZEBLAST || proj->GetOwner() != targ) && targ->spr.statnum != 4)
{
if (badguy(targ) == 1)
{
if (isWorldTour() && targ->spr.picnum == FIREFLY && targ->spr.scale.X < 0.75)
return;
if (proj->spr.picnum == RPG) proj->spr.extra <<= 1;
if ((targ->spr.picnum != DRONE) && (targ->spr.picnum != ROTATEGUN) && (targ->spr.picnum != COMMANDER) && (targ->spr.picnum < GREENSLIME || targ->spr.picnum > GREENSLIME + 7))
if (proj->spr.picnum != FREEZEBLAST)
//if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL. Cannot be done right with EDuke mess backing the engine.
{
auto spawned = spawn(proj, JIBS6);
if (spawned)
{
if (proj->spr.pal == 6)
spawned->spr.pal = 6;
spawned->spr.pos.Z += 4;
spawned->vel.X = 1;
spawned->spr.scale = DVector2(0.375, 0.375);
spawned->spr.angle = DAngle22_5 / 4 - randomAngle(22.5 / 2);
}
}
auto Owner = proj->GetOwner();
if (Owner && Owner->spr.picnum == APLAYER && targ->spr.picnum != ROTATEGUN && targ->spr.picnum != DRONE)
if (ps[Owner->PlayerIndex()].curr_weapon == SHOTGUN_WEAPON)
{
fi.shoot(targ, BLOODSPLAT3);
fi.shoot(targ, BLOODSPLAT1);
fi.shoot(targ, BLOODSPLAT2);
fi.shoot(targ, BLOODSPLAT4);
}
if (targ->spr.picnum != TANK && !bossguy(targ) && targ->spr.picnum != RECON && targ->spr.picnum != ROTATEGUN)
{
if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == 0)
targ->spr.angle = proj->spr.angle + DAngle180;
targ->vel.X = -proj->spr.extra * 0.25;
auto sp = targ->sector();
pushmove(targ->spr.pos, &sp, 8, 4, 4, CLIPMASK0);
if (sp != targ->sector() && sp != nullptr)
ChangeActorSect(targ, sp);
}
if (targ->spr.statnum == 2)
{
ChangeActorStat(targ, 1);
targ->timetosleep = SLEEPTIME;
}
if ((targ->spr.scale.X < 0.375 || targ->spr.picnum == SHARK) && proj->spr.picnum == SHRINKSPARK) return;
}
if (targ->spr.statnum != 2)
{
if (proj->spr.picnum == FREEZEBLAST && ((targ->spr.picnum == APLAYER && targ->spr.pal == 1) || (gs.freezerhurtowner == 0 && proj->GetOwner() == targ)))
return;
int hitpic = proj->spr.picnum;
auto Owner = proj->GetOwner();
if (Owner && Owner->spr.picnum == APLAYER)
{
if (targ->spr.picnum == APLAYER && ud.coop != 0 && ud.ffire == 0)
return;
auto tOwner = targ->GetOwner();
if (isWorldTour() && hitpic == FIREBALL && tOwner && tOwner->spr.picnum != FIREBALL)
hitpic = FLAMETHROWERFLAME;
}
targ->attackertype = hitpic;
targ->hitextra += proj->spr.extra;
targ->hitang = proj->spr.angle;
targ->SetHitOwner(Owner);
}
if (targ->spr.statnum == 10)
{
auto p = targ->spr.yint;
if (ps[p].newOwner != nullptr)
{
ps[p].newOwner = nullptr;
ps[p].restorexyz();
ps[p].angle.restore();
updatesector(ps[p].pos, &ps[p].cursector);
DukeStatIterator it(STAT_ACTOR);
while (auto itActor = it.Next())
{
if (actorflag(itActor, SFLAG2_CAMERA)) itActor->spr.yint = 0;
}
}
if (targ->spr.scale.X < 0.375 && proj->spr.picnum == SHRINKSPARK)
return;
auto hitowner = targ->GetHitOwner();
if (!hitowner || hitowner->spr.picnum != APLAYER)
if (ud.player_skill >= 3)
proj->spr.extra += (proj->spr.extra >> 1);
}
}
}
void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj)
{
int j, k, p;
int j, k;
if (targ->GetClass() != RUNTIME_CLASS(DDukeActor))
{
@ -1312,117 +1427,7 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj)
if (!targ) break;
[[fallthrough]];
default:
if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_WALL) && targ->spr.hitag == 0 && targ->spr.lotag == 0 && targ->spr.statnum == 0)
break;
if ((proj->spr.picnum == FREEZEBLAST || proj->GetOwner() != targ) && targ->spr.statnum != 4)
{
if (badguy(targ) == 1)
{
if (isWorldTour() && targ->spr.picnum == FIREFLY && targ->spr.scale.X < 0.75)
break;
if (proj->spr.picnum == RPG) proj->spr.extra <<= 1;
if ((targ->spr.picnum != DRONE) && (targ->spr.picnum != ROTATEGUN) && (targ->spr.picnum != COMMANDER) && (targ->spr.picnum < GREENSLIME || targ->spr.picnum > GREENSLIME + 7))
if (proj->spr.picnum != FREEZEBLAST)
//if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL. Cannot be done right with EDuke mess backing the engine.
{
auto spawned = spawn(proj, JIBS6);
if (spawned)
{
if (proj->spr.pal == 6)
spawned->spr.pal = 6;
spawned->spr.pos.Z += 4;
spawned->vel.X = 1;
spawned->spr.scale = DVector2(0.375, 0.375);
spawned->spr.angle = DAngle22_5 / 4 - randomAngle(22.5 / 2);
}
}
auto Owner = proj->GetOwner();
if (Owner && Owner->spr.picnum == APLAYER && targ->spr.picnum != ROTATEGUN && targ->spr.picnum != DRONE)
if (ps[Owner->PlayerIndex()].curr_weapon == SHOTGUN_WEAPON)
{
fi.shoot(targ, BLOODSPLAT3);
fi.shoot(targ, BLOODSPLAT1);
fi.shoot(targ, BLOODSPLAT2);
fi.shoot(targ, BLOODSPLAT4);
}
if (targ->spr.picnum != TANK && !bossguy(targ) && targ->spr.picnum != RECON && targ->spr.picnum != ROTATEGUN)
{
if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == 0)
targ->spr.angle = proj->spr.angle + DAngle180;
targ->vel.X = -proj->spr.extra * 0.25;
auto sp = targ->sector();
pushmove(targ->spr.pos, &sp, 8, 4, 4, CLIPMASK0);
if (sp != targ->sector() && sp != nullptr)
ChangeActorSect(targ, sp);
}
if (targ->spr.statnum == 2)
{
ChangeActorStat(targ, 1);
targ->timetosleep = SLEEPTIME;
}
if ((targ->spr.scale.X < 0.375 || targ->spr.picnum == SHARK) && proj->spr.picnum == SHRINKSPARK) return;
}
if (targ->spr.statnum != 2)
{
if (proj->spr.picnum == FREEZEBLAST && ((targ->spr.picnum == APLAYER && targ->spr.pal == 1) || (gs.freezerhurtowner == 0 && proj->GetOwner() == targ)))
return;
int hitpic = proj->spr.picnum;
auto Owner = proj->GetOwner();
if (Owner && Owner->spr.picnum == APLAYER)
{
if (targ->spr.picnum == APLAYER && ud.coop != 0 && ud.ffire == 0)
return;
auto tOwner = targ->GetOwner();
if (isWorldTour() && hitpic == FIREBALL && tOwner && tOwner->spr.picnum != FIREBALL)
hitpic = FLAMETHROWERFLAME;
}
targ->attackertype = hitpic;
targ->hitextra += proj->spr.extra;
targ->hitang = proj->spr.angle;
targ->SetHitOwner(Owner);
}
if (targ->spr.statnum == 10)
{
p = targ->spr.yint;
if (ps[p].newOwner != nullptr)
{
ps[p].newOwner = nullptr;
ps[p].restorexyz();
ps[p].angle.restore();
updatesector(ps[p].pos, &ps[p].cursector);
DukeStatIterator it(STAT_ACTOR);
while (auto itActor = it.Next())
{
if (actorflag(itActor, SFLAG2_CAMERA)) itActor->spr.yint = 0;
}
}
if (targ->spr.scale.X < 0.375 && proj->spr.picnum == SHRINKSPARK)
return;
auto hitowner = targ->GetHitOwner();
if (!hitowner || hitowner->spr.picnum != APLAYER)
if (ud.player_skill >= 3)
proj->spr.extra += (proj->spr.extra >> 1);
}
}
checkhitdefault_d(targ, proj);
break;
}
}

View file

@ -1513,9 +1513,92 @@ bool checkhitceiling_r(sectortype* sectp)
//
//---------------------------------------------------------------------------
void checkhitdefault_r(DDukeActor* targ, DDukeActor* proj)
{
if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_WALL) && targ->spr.hitag == 0 && targ->spr.lotag == 0 && targ->spr.statnum == 0)
return;
if ((proj->spr.picnum == SHRINKSPARK || proj->spr.picnum == FREEZEBLAST || proj->GetOwner() != targ) && targ->spr.statnum != 4)
{
if (badguy(targ) == 1)
{
if (proj->spr.picnum == RPG) proj->spr.extra <<= 1;
else if (isRRRA() && proj->spr.picnum == RPG2) proj->spr.extra <<= 1;
if ((targ->spr.picnum != DRONE))
if (proj->spr.picnum != FREEZEBLAST)
//if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL. Cannot be done right with EDuke mess backing the engine.
{
auto spawned = spawn(proj, JIBS6);
if (spawned)
{
if (proj->spr.pal == 6)
spawned->spr.pal = 6;
spawned->spr.pos.Z += 4;
spawned->vel.X = 1;
spawned->spr.scale = DVector2(0.375, 0.375);
spawned->spr.angle = DAngle22_5 / 4 - randomAngle(22.5 / 2);
}
}
auto Owner = proj->GetOwner();
if (Owner && Owner->spr.picnum == APLAYER && targ->spr.picnum != DRONE)
if (ps[Owner->PlayerIndex()].curr_weapon == SHOTGUN_WEAPON)
{
fi.shoot(targ, BLOODSPLAT3);
fi.shoot(targ, BLOODSPLAT1);
fi.shoot(targ, BLOODSPLAT2);
fi.shoot(targ, BLOODSPLAT4);
}
if (targ->spr.statnum == 2)
{
ChangeActorStat(targ, 1);
targ->timetosleep = SLEEPTIME;
}
}
if (targ->spr.statnum != 2)
{
if (proj->spr.picnum == FREEZEBLAST && ((targ->spr.picnum == APLAYER && targ->spr.pal == 1) || (gs.freezerhurtowner == 0 && proj->GetOwner() == targ)))
return;
targ->attackertype = proj->spr.picnum;
targ->hitextra += proj->spr.extra;
if (targ->spr.picnum != COW)
targ->hitang = proj->spr.angle;
targ->SetHitOwner(proj->GetOwner());
}
if (targ->spr.statnum == 10)
{
auto p = targ->PlayerIndex();
if (ps[p].newOwner != nullptr)
{
ps[p].newOwner = nullptr;
ps[p].restorexyz();
updatesector(ps[p].pos, &ps[p].cursector);
DukeStatIterator it(STAT_EFFECTOR);
while (auto act = it.Next())
{
if (actorflag(act, SFLAG2_CAMERA)) act->spr.yint = 0;
}
}
auto Owner = targ->GetHitOwner();
if (!Owner || Owner->spr.picnum != APLAYER)
if (ud.player_skill >= 3)
proj->spr.extra += (proj->spr.extra >> 1);
}
}
}
void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj)
{
int j, k, p;
int j, k;
if (targ->GetClass() != RUNTIME_CLASS(DDukeActor))
{
@ -2278,85 +2361,7 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj)
if (!targ) break;
[[fallthrough]];
default:
if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_WALL) && targ->spr.hitag == 0 && targ->spr.lotag == 0 && targ->spr.statnum == 0)
break;
if ((proj->spr.picnum == SHRINKSPARK || proj->spr.picnum == FREEZEBLAST || proj->GetOwner() != targ) && targ->spr.statnum != 4)
{
if (badguy(targ) == 1)
{
if (proj->spr.picnum == RPG) proj->spr.extra <<= 1;
else if (isRRRA() && proj->spr.picnum == RPG2) proj->spr.extra <<= 1;
if ((targ->spr.picnum != DRONE))
if (proj->spr.picnum != FREEZEBLAST)
//if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL. Cannot be done right with EDuke mess backing the engine.
{
auto spawned = spawn(proj, JIBS6);
if (spawned)
{
if (proj->spr.pal == 6)
spawned->spr.pal = 6;
spawned->spr.pos.Z += 4;
spawned->vel.X = 1;
spawned->spr.scale = DVector2(0.375, 0.375);
spawned->spr.angle = DAngle22_5/4 - randomAngle(22.5/2);
}
}
auto Owner = proj->GetOwner();
if (Owner && Owner->spr.picnum == APLAYER && targ->spr.picnum != DRONE)
if (ps[Owner->PlayerIndex()].curr_weapon == SHOTGUN_WEAPON)
{
fi.shoot(targ, BLOODSPLAT3);
fi.shoot(targ, BLOODSPLAT1);
fi.shoot(targ, BLOODSPLAT2);
fi.shoot(targ, BLOODSPLAT4);
}
if (targ->spr.statnum == 2)
{
ChangeActorStat(targ, 1);
targ->timetosleep = SLEEPTIME;
}
}
if (targ->spr.statnum != 2)
{
if (proj->spr.picnum == FREEZEBLAST && ((targ->spr.picnum == APLAYER && targ->spr.pal == 1) || (gs.freezerhurtowner == 0 && proj->GetOwner() == targ)))
return;
targ->attackertype = proj->spr.picnum;
targ->hitextra += proj->spr.extra;
if (targ->spr.picnum != COW)
targ->hitang = proj->spr.angle;
targ->SetHitOwner(proj->GetOwner());
}
if (targ->spr.statnum == 10)
{
p = targ->PlayerIndex();
if (ps[p].newOwner != nullptr)
{
ps[p].newOwner = nullptr;
ps[p].restorexyz();
updatesector(ps[p].pos, &ps[p].cursector);
DukeStatIterator it(STAT_EFFECTOR);
while (auto act = it.Next())
{
if (actorflag(act, SFLAG2_CAMERA)) act->spr.yint = 0;
}
}
auto Owner = targ->GetHitOwner();
if (!Owner || Owner->spr.picnum != APLAYER)
if (ud.player_skill >= 3)
proj->spr.extra += (proj->spr.extra >> 1);
}
}
checkhitdefault_r(targ, proj);
break;
}
}

View file

@ -1041,23 +1041,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
case SECTOREFFECTOR:
spawneffector(act, actors);
break;
case SEENINE:
case OOZFILTER:
act->spr.shade = -16;
if (act->spr.scale.X <= 0.125)
{
act->spr.cstat = CSTAT_SPRITE_INVISIBLE;
act->spr.scale = DVector2(0, 0);
}
else act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->spr.extra = gs.impact_damage << 2;
act->SetOwner(act);
ChangeActorStat(act, STAT_STANDABLE);
break;
case TOILET:

View file

@ -1271,21 +1271,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
spawneffector(act, actors);
break;
case SEENINE:
case OOZFILTER:
act->spr.shade = -16;
if (act->spr.scale.X <= 0.125)
{
act->spr.cstat = CSTAT_SPRITE_INVISIBLE;
act->spr.scale = DVector2(0, 0);
}
else act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
act->spr.extra = gs.impact_damage << 2;
act->SetOwner(act);
ChangeActorStat(act, STAT_STANDABLE);
break;
case EMPTYBIKE:
if (!isRRRA()) goto default_case;
if (ud.multimode < 2 && act->spr.pal == 1)

View file

@ -138,6 +138,18 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, SetSpritesetImage, setSpritesetImage)
return 0;
}
static int getSpritesetSize(DDukeActor* self)
{
auto& spriteset = static_cast<PClassActor*>(self->GetClass())->ActorInfo()->SpriteSet;
return spriteset.Size();
}
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, GetSpritesetSize, getSpritesetSize)
{
PARAM_SELF_PROLOGUE(DDukeActor);
ACTION_RETURN_INT(getSpritesetSize(self));
}
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, getglobalz, getglobalz)
{
PARAM_SELF_PROLOGUE(DDukeActor);
@ -332,6 +344,18 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, detonate, DukeActor_detonate)
return 0;
}
void DukeActor_checkhitdefault(DDukeActor* origin, DDukeActor* proj)
{
fi.checkhitdefault(origin, proj);
}
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, checkhitdefault, DukeActor_checkhitdefault)
{
PARAM_SELF_PROLOGUE(DDukeActor);
PARAM_OBJECT(proj, DDukeActor);
DukeActor_checkhitdefault(self, proj);
return 0;
}
// temporary helpers to hide the fact that these flags are not part of the actor yet.
DEFINE_ACTION_FUNCTION(DDukeActor, actorflag1)

View file

@ -21,4 +21,7 @@ spawnclasses
548 = DukeCrack3
549 = DukeCrack4
916 = DukeFireext
1079 = DukeOozFilter
1247 = DukeSeenine
}

View file

@ -17,5 +17,7 @@ spawnclasses
1076 = DukeCrack2
1077 = DukeCrack3
1078 = DukeCrack4
1273 = DukeOozFilter
1324 = DukeSeenine
}

View file

@ -58,6 +58,7 @@ version "4.10"
#include "zscript/games/duke/actors/tripbomb.zs"
#include "zscript/games/duke/actors/crack.zs"
#include "zscript/games/duke/actors/fireext.zs"
#include "zscript/games/duke/actors/oozfilter.zs"
#include "zscript/games/blood/bloodgame.zs"
#include "zscript/games/blood/ui/menu.zs"

View file

@ -0,0 +1,96 @@
class DukeOozFilter : DukeActor
{
default
{
statnum STAT_STANDABLE;
spriteset "OOZFILTER";
}
override void Initialize()
{
self.shade = -16;
if (self.scale.X <= 0.125)
{
self.cstat = CSTAT_SPRITE_INVISIBLE;
self.scale = (0, 0);
}
else self.cstat = CSTAT_SPRITE_BLOCK_ALL;
self.extra = gs.impact_damage << 2;
self.ownerActor = self;
}
override void Tick()
{
int j;
if (self.shade != -32 && self.shade != -33)
{
if (self.scale.X != 0)
j = self.ifhitbyweapon();
else
j = -1;
if (j >= 0 || self.shade == -31)
{
if (j >= 0) self.lotag = 0;
self.temp_data[3] = 1;
DukeStatIterator it;
for(let act2 = it.first(STAT_STANDABLE); act2; act2 = it.Next())
{
if (self.hitag == act2.hitag && act2.actorflag2(SFLAG2_BRIGHTEXPLODE))
act2.shade = -32;
}
}
}
else
{
if (self.shade == -32)
{
if (self.lotag > 0)
{
self.lotag -= 3;
if (self.lotag <= 0) self.lotag = -99;
}
else
{
self.shade = -33;
}
}
else
{
if (self.scale.X > 0)
{
self.temp_data[2]++;
if (self.temp_data[2] == 3)
{
if (self.spritesetindex < self.getSpriteSetSize() - 1)
{
self.temp_data[2] = 0;
self.setSpriteSetImage(self.spritesetindex + 1);
}
else
{
self.detonate('DukeExplosion2');
}
}
return;
}
self.detonate('DukeExplosion2');
}
}
}
}
class DukeSeenine : DukeOozFilter
{
default
{
spriteset "SEENINE", "SEENINEDEAD", "SEENINEDEAD1";
}
}

View file

@ -24,6 +24,7 @@ class DukeActor : CoreActor native
};
native void SetSpritesetImage(int index);
native int GetSpritesetSize();
native DukeActor ownerActor, hitOwnerActor;
native uint8 cgg;
@ -76,11 +77,12 @@ class DukeActor : CoreActor native
native void lotsofglass(int count);
native void makeitfall();
native void detonate(name type);
native void checkhitdefault(DukeActor proj);
virtual void BeginPlay() {}
virtual void Initialize() {}
virtual void Tick() {}
virtual void onHit(DukeActor hitter) {}
virtual void onHit(DukeActor hitter) { checkhitdefault(hitter); }
virtual void onHurt(DukePlayer p) {}
virtual void onUse(DukePlayer user) {}
virtual bool animate(tspritetype tspr) { return false; }