- merged both hitradius variants, now that all the critical differences are properly handled by actor flags.

This commit is contained in:
Christoph Oelckers 2022-12-29 16:59:07 +01:00
parent 927d014cea
commit 542083af30
8 changed files with 131 additions and 225 deletions

View file

@ -763,7 +763,7 @@ void detonate(DDukeActor *actor, PClassActor* explosion)
{
int x = actor->spr.extra;
spawn(actor, explosion);
fi.hitradius(actor, gs.seenineblastradius, x >> 2, x - (x >> 1), x - (x >> 2), x);
hitradius(actor, gs.seenineblastradius, x >> 2, x - (x >> 1), x - (x >> 2), x);
S_PlayActorSound(PIPEBOMB_EXPLODE, actor);
}
@ -852,6 +852,132 @@ void blastceiling(DDukeActor* actor, double radius)
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void hitradius(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int hp4)
{
double radius = r * inttoworld;
static const uint8_t statlist[] = { STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE, STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC };
if (!(actor->flags3 & SFLAG3_NOCEILINGBLAST))
{
blastceiling(actor, radius);
}
double q = zrand(32) - (isRR() ? 24 : 16);
auto Owner = actor->GetOwner();
for (int x = 0; x < 7; x++)
{
DukeStatIterator itj(statlist[x]);
while (auto act2 = itj.Next())
{
if (Owner)
{
if (Owner->isPlayer() && act2->isPlayer() && ud.coop != 0 && ud.ffire == 0 && Owner != act2 /* && (dmflags & NOFRIENDLYRADIUSDMG)*/)
{
continue;
}
if (actor->flags3 & SFLAG3_HITRADIUS_DONTHURTSPECIES && !Owner->isPlayer() && Owner->GetClass() == act2->GetClass())
{
continue;
}
}
if (x == 0 || x >= 5 || (act2->flags1 & SFLAG_HITRADIUS_CHECKHITONLY))
{
if (!(actor->flags3 & SFLAG3_HITRADIUS_NODAMAGE) || (act2->spr.cstat & CSTAT_SPRITE_BLOCK_ALL))
if ((actor->spr.pos - act2->spr.pos).Length() < radius)
{
if (badguy(act2) && !cansee(act2->spr.pos.plusZ(q), act2->sector(), actor->spr.pos.plusZ(q), actor->sector()))
continue;
checkhitsprite(act2, actor);
}
}
else if (act2->spr.extra >= 0 && act2 != actor && ((act2->flags1 & SFLAG_HITRADIUS_FORCEEFFECT) || badguy(act2) || (act2->spr.cstat & CSTAT_SPRITE_BLOCK_ALL)))
{
// this is a damage type check, not a projectile type check.
// It's also quite broken because it doesn't check for being shrunk but tries to guess it from the size.
// Unfortunately, with CON there is no way to retrieve proper shrunk state in any way.
if (actor->GetClass() == DukeShrinkSparkClass && (act2->spr.scale.X < 0.375))
{
continue;
}
if (actor->flags3 & SFLAG3_HITRADIUS_DONTHURTSHOOTER && act2 == Owner)
{
continue;
}
if (actor->flags3 & SFLAG3_HITRADIUS_NOEFFECT)
{
continue;
}
double dist = (act2->getPosWithOffsetZ() - actor->spr.pos).Length();
if (dist < radius && cansee(act2->spr.pos.plusZ(-8), act2->sector(), actor->spr.pos.plusZ(-12), actor->sector()))
{
act2->hitang = (act2->spr.pos - actor->spr.pos).Angle();
act2->attackertype = CallGetRadiusDamageType(actor, act2->spr.extra);
if (!(actor->flags3 & SFLAG3_HITRADIUS_NODAMAGE))
{
if (dist < radius / 3)
{
if (hp4 == hp3) hp4++;
act2->hitextra = hp3 + (krand() % (hp4 - hp3));
}
else if (dist < 2 * radius / 3)
{
if (hp3 == hp2) hp3++;
act2->hitextra = hp2 + (krand() % (hp3 - hp2));
}
else if (dist < radius)
{
if (hp2 == hp1) hp2++;
act2->hitextra = hp1 + (krand() % (hp2 - hp1));
}
if (!(act2->flags2 & SFLAG2_NORADIUSPUSH) && !bossguy(act2))
{
if (act2->vel.X < 0) act2->vel.X = 0;
act2->vel.X += ((actor->spr.extra / 4.));
}
if ((act2->flags1 & SFLAG_HITRADIUSCHECK))
checkhitsprite(act2, actor);
}
else if (actor->spr.extra == 0) act2->hitextra = 0;
if (act2->GetClass() != DukeRadiusExplosionClass && Owner && Owner->spr.statnum < MAXSTATUS)
{
if (act2->isPlayer())
{
int p = act2->PlayerIndex();
if (act2->attackertype == DukeFlamethrowerFlameClass && Owner->isPlayer())
{
ps[p].numloogs = -1 - actor->spr.yint;
}
if (ps[p].newOwner != nullptr)
{
clearcamera(&ps[p]);
}
}
act2->SetHitOwner(actor->GetOwner());
}
}
}
}
}
}
//---------------------------------------------------------------------------
//
// Rotating sector

View file

@ -147,120 +147,6 @@ int ifsquished(DDukeActor* actor, int p)
//
//---------------------------------------------------------------------------
void hitradius_d(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int hp4)
{
double radius = r * inttoworld;
static const uint8_t statlist[] = { STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE, STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC };
if(!(actor->flags3 & SFLAG3_NOCEILINGBLAST))
{
blastceiling(actor, radius);
}
double q = zrand(32) - 16;
auto Owner = actor->GetOwner();
for (int x = 0; x < 7; x++)
{
DukeStatIterator itj(statlist[x]);
while (auto act2 = itj.Next())
{
if (Owner)
{
if (Owner->isPlayer() && act2->isPlayer() && ud.coop != 0 && ud.ffire == 0 && Owner != act2 /* && (dmflags & NOFRIENDLYRADIUSDMG)*/)
{
continue;
}
if (actor->flags3 & SFLAG3_HITRADIUS_DONTHURTSPECIES && !Owner->isPlayer() && Owner->GetClass() == act2->GetClass())
{
continue;
}
}
if (x == 0 || x >= 5 || (act2->flags1 & SFLAG_HITRADIUS_CHECKHITONLY))
{
if (!(actor->flags3 & SFLAG3_HITRADIUS_NODAMAGE) || (act2->spr.cstat & CSTAT_SPRITE_BLOCK_ALL))
if ((actor->spr.pos - act2->spr.pos).Length() < radius)
{
if (badguy(act2) && !cansee(act2->spr.pos.plusZ(q), act2->sector(), actor->spr.pos.plusZ(q), actor->sector()))
continue;
checkhitsprite(act2, actor);
}
}
else if (act2->spr.extra >= 0 && act2 != actor && ((act2->flags1 & SFLAG_HITRADIUS_FORCEEFFECT) || badguy(act2) || (act2->spr.cstat & CSTAT_SPRITE_BLOCK_ALL)))
{
if (actor->flags3 & SFLAG3_HITRADIUS_DONTHURTSHOOTER && act2 == Owner)
{
continue;
}
double dist = (act2->getPosWithOffsetZ() - actor->spr.pos).Length();
if (dist < radius && cansee(act2->spr.pos.plusZ(-8), act2->sector(), actor->spr.pos.plusZ(-12), actor->sector()))
{
act2->hitang = (act2->spr.pos - actor->spr.pos).Angle();
act2->attackertype = CallGetRadiusDamageType(actor, act2->spr.extra);
if (!(actor->flags3 & SFLAG3_HITRADIUS_NODAMAGE))
{
if (dist < radius / 3)
{
if (hp4 == hp3) hp4++;
act2->hitextra = hp3 + (krand() % (hp4 - hp3));
}
else if (dist < 2 * radius / 3)
{
if (hp3 == hp2) hp3++;
act2->hitextra = hp2 + (krand() % (hp3 - hp2));
}
else if (dist < radius)
{
if (hp2 == hp1) hp2++;
act2->hitextra = hp1 + (krand() % (hp2 - hp1));
}
if (!(act2->flags2 & SFLAG2_NORADIUSPUSH) && !bossguy(act2))
{
if (act2->vel.X < 0) act2->vel.X = 0;
act2->vel.X += ( (actor->spr.extra / 4.));
}
if ((act2->flags1 & SFLAG_HITRADIUSCHECK))
checkhitsprite(act2, actor);
}
else if (actor->spr.extra == 0) act2->hitextra = 0;
if (act2->GetClass() != DukeRadiusExplosionClass && Owner && Owner->spr.statnum < MAXSTATUS)
{
if (act2->isPlayer())
{
int p = act2->PlayerIndex();
if (act2->attackertype == DukeFlamethrowerFlameClass && Owner->isPlayer())
{
ps[p].numloogs = -1 - actor->spr.yint;
}
if (ps[p].newOwner != nullptr)
{
clearcamera(&ps[p]);
}
}
act2->SetHitOwner(actor->GetOwner());
}
}
}
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int movesprite_ex_d(DDukeActor* actor, const DVector3& change, unsigned int cliptype, Collision &result)
{

View file

@ -146,102 +146,6 @@ void addweapon_r(player_struct* p, int weapon, bool wswitch)
//
//---------------------------------------------------------------------------
void hitradius_r(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int hp4)
{
double radius = r * inttoworld;
static const uint8_t statlist[] = { STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE, STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC };
if (!(actor->flags3 & SFLAG3_NOCEILINGBLAST))
{
blastceiling(actor, radius);
}
double q = zrand(32) - 24;
auto Owner = actor->GetOwner();
for (int x = 0; x < 7; x++)
{
DukeStatIterator it1(statlist[x]);
while (auto act2 = it1.Next())
{
if (x == 0 || x >= 5 || (act2->flags1 & SFLAG_HITRADIUS_CHECKHITONLY))
{
if ((actor->spr.pos - act2->spr.pos).Length() < radius)
{
if (badguy(act2) && !cansee(act2->spr.pos.plusZ(q), act2->sector(), actor->spr.pos.plusZ(q), actor->sector()))
continue;
checkhitsprite(act2, actor);
}
}
else if (act2->spr.extra >= 0 && act2 != actor && ((act2->flags1 & SFLAG_HITRADIUS_FORCEEFFECT) || badguy(act2) || (act2->spr.cstat & CSTAT_SPRITE_BLOCK_ALL)))
{
if (actor->flags3 & SFLAG3_HITRADIUS_DONTHURTSHOOTER && act2 == Owner)
{
continue;
}
if (actor->flags3 & SFLAG3_HITRADIUS_NOEFFECT)
{
continue;
}
double dist = (act2->getPosWithOffsetZ() - actor->spr.pos).Length();
if (dist < radius && cansee(act2->spr.pos.plusZ(-8), act2->sector(), actor->spr.pos.plusZ(-12), actor->sector()))
{
act2->hitang = (act2->spr.pos - actor->spr.pos).Angle();
act2->attackertype = CallGetRadiusDamageType(actor, act2->spr.extra);
if (dist < radius / 3)
{
if (hp4 == hp3) hp4++;
act2->hitextra = hp3 + (krand() % (hp4 - hp3));
}
else if (dist < 2 * radius / 3)
{
if (hp3 == hp2) hp3++;
act2->hitextra = hp2 + (krand() % (hp3 - hp2));
}
else if (dist < radius)
{
if (hp2 == hp1) hp2++;
act2->hitextra = hp1 + (krand() % (hp2 - hp1));
}
if (!(act2->flags2 & SFLAG2_NORADIUSPUSH) && !bossguy(act2))
{
if (act2->vel.X < 0) act2->vel.X = 0;
act2->vel.X += ((actor->spr.extra / 4.));
}
if ((act2->flags1 & SFLAG_HITRADIUSCHECK))
checkhitsprite(act2, actor);
if (act2->GetClass() != DukeRadiusExplosionClass && Owner && Owner->spr.statnum < MAXSTATUS)
{
if (act2->isPlayer())
{
int p = act2->PlayerIndex();
if (ps[p].newOwner != nullptr)
{
clearcamera(&ps[p]);
}
}
act2->SetHitOwner(actor->GetOwner());
}
}
}
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int movesprite_ex_r(DDukeActor* actor, const DVector3& change, unsigned int cliptype, Collision &result)
{
int bg = badguy(actor);

View file

@ -46,8 +46,6 @@ void checksectors_r(int snum);
void addweapon_d(player_struct* p, int weapon, bool wswitch);
void addweapon_r(player_struct* p, int weapon, bool wswitch);
void hitradius_d(DDukeActor* i, int r, int hp1, int hp2, int hp3, int hp4);
void hitradius_r(DDukeActor* i, int r, int hp1, int hp2, int hp3, int hp4);
void lotsofmoney_d(DDukeActor* s, int n);
void lotsofmail_d(DDukeActor* s, int n);
void lotsofpaper_d(DDukeActor* s, int n);
@ -97,7 +95,6 @@ void SetDispatcher()
checksectors_d,
addweapon_d,
hitradius_d,
lotsofmoney_d,
lotsofmail_d,
lotsofpaper_d,
@ -128,7 +125,6 @@ void SetDispatcher()
checksectors_r,
addweapon_r,
hitradius_r,
lotsoffeathers_r,
lotsoffeathers_r,
lotsoffeathers_r,

View file

@ -81,7 +81,6 @@ struct Dispatcher
void (*checksectors)(int low);
void (*addweapon)(player_struct *p, int weapon, bool wswitch);
void (*hitradius)(DDukeActor* i, int r, int hp1, int hp2, int hp3, int hp4);
void (*lotsofmoney)(DDukeActor *s, int n);
void (*lotsofmail)(DDukeActor *s, int n);
void (*lotsofpaper)(DDukeActor *s, int n);

View file

@ -40,7 +40,7 @@ void movefta();
void clearcameras(player_struct* p);
void RANDOMSCRAP(DDukeActor* i);
void detonate(DDukeActor* i, PClassActor* explosion);
void blastceiling(DDukeActor* actor, double radius);
void hitradius(DDukeActor* i, int r, int hp1, int hp2, int hp3, int hp4);
void lotsofstuff(DDukeActor* s, int n, PClassActor* spawntype);
void watersplash2(DDukeActor* i);
bool money(DDukeActor* i, int BLOODPOOL);

View file

@ -2017,7 +2017,7 @@ int ParseState::parse(void)
insptr += 2;
break;
case concmd_hitradius:
fi.hitradius(g_ac, *(insptr + 1), *(insptr + 2), *(insptr + 3), *(insptr + 4), *(insptr + 5));
hitradius(g_ac, *(insptr + 1), *(insptr + 2), *(insptr + 3), *(insptr + 4), *(insptr + 5));
insptr+=6;
break;
case concmd_ifp:

View file

@ -549,12 +549,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, RandomScrap, RANDOMSCRAP)
return 0;
}
void DukeActor_hitradius(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int hp4)
{
fi.hitradius(actor, r, hp1, hp2, hp3, hp4);
}
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, hitradius, DukeActor_hitradius)
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, hitradius, hitradius)
{
PARAM_SELF_PROLOGUE(DDukeActor);
PARAM_INT(r);
@ -562,7 +557,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, hitradius, DukeActor_hitradius)
PARAM_INT(h2);
PARAM_INT(h3);
PARAM_INT(h4);
DukeActor_hitradius(self, r, h1, h2, h3, h4);
hitradius(self, r, h1, h2, h3, h4);
return 0;
}