mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-16 09:31:14 +00:00
Explode bouncing projectiles if hit damageable geometry
This commit is contained in:
parent
b581648d6f
commit
89bdd1adf0
4 changed files with 76 additions and 19 deletions
|
@ -569,24 +569,27 @@ void P_GeometryRadiusAttack(AActor* bombspot, AActor* bombsource, int bombdamage
|
||||||
}
|
}
|
||||||
|
|
||||||
// check 3d floors
|
// check 3d floors
|
||||||
for (auto f : othersector->e->XFloor.ffloors)
|
if (othersector)
|
||||||
{
|
{
|
||||||
if (!(f->flags & FF_EXISTS)) continue;
|
for (auto f : othersector->e->XFloor.ffloors)
|
||||||
if (!(f->flags & FF_SOLID)) continue;
|
{
|
||||||
|
if (!(f->flags & FF_EXISTS)) continue;
|
||||||
|
if (!(f->flags & FF_SOLID)) continue;
|
||||||
|
|
||||||
if (!f->model || !f->model->health3d) continue;
|
if (!f->model || !f->model->health3d) continue;
|
||||||
|
|
||||||
// 3d floors over real ceiling, or under real floor, are ignored
|
// 3d floors over real ceiling, or under real floor, are ignored
|
||||||
double z_ff_top = clamp(f->top.plane->ZatPoint(to2d), z_bottom2, z_top2);
|
double z_ff_top = clamp(f->top.plane->ZatPoint(to2d), z_bottom2, z_top2);
|
||||||
double z_ff_bottom = clamp(f->bottom.plane->ZatPoint(to2d), z_bottom2, z_top2);
|
double z_ff_bottom = clamp(f->bottom.plane->ZatPoint(to2d), z_bottom2, z_top2);
|
||||||
if (z_ff_top < z_ff_bottom)
|
if (z_ff_top < z_ff_bottom)
|
||||||
continue; // also ignore eldritch geometry
|
continue; // also ignore eldritch geometry
|
||||||
|
|
||||||
DVector3 to3d_ffloor(to2d.X, to2d.Y, clamp(bombspot->Z(), z_ff_bottom, z_ff_top));
|
DVector3 to3d_ffloor(to2d.X, to2d.Y, clamp(bombspot->Z(), z_ff_bottom, z_ff_top));
|
||||||
int grp = f->model->health3dgroup;
|
int grp = f->model->health3dgroup;
|
||||||
if (grp <= 0)
|
if (grp <= 0)
|
||||||
grp = 0x20000000 | (f->model->sectornum & 0x0FFFFFFF);
|
grp = 0x20000000 | (f->model->sectornum & 0x0FFFFFFF);
|
||||||
PGRA_InsertIfCloser(damageGroupPos, grp, to3d_ffloor, bombspot->Pos(), srcsector, f->model, nullptr, SECPART_3D);
|
PGRA_InsertIfCloser(damageGroupPos, grp, to3d_ffloor, bombspot->Pos(), srcsector, f->model, nullptr, SECPART_3D);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -646,13 +649,17 @@ void P_GeometryRadiusAttack(AActor* bombspot, AActor* bombsource, int bombdamage
|
||||||
// Called if P_ExplodeMissile was called against a wall.
|
// Called if P_ExplodeMissile was called against a wall.
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void P_ProjectileHitLinedef(AActor* mo, line_t* line)
|
bool P_ProjectileHitLinedef(AActor* mo, line_t* line)
|
||||||
{
|
{
|
||||||
|
bool washit = false;
|
||||||
// detect 3d floor hit
|
// detect 3d floor hit
|
||||||
if (mo->Blocking3DFloor)
|
if (mo->Blocking3DFloor)
|
||||||
{
|
{
|
||||||
if (mo->Blocking3DFloor->health3d > 0)
|
if (mo->Blocking3DFloor->health3d > 0)
|
||||||
|
{
|
||||||
P_DamageSector(mo->Blocking3DFloor, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_3D, mo->Pos());
|
P_DamageSector(mo->Blocking3DFloor, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_3D, mo->Pos());
|
||||||
|
washit = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int wside = P_PointOnLineSide(mo->Pos(), line);
|
int wside = P_PointOnLineSide(mo->Pos(), line);
|
||||||
|
@ -676,33 +683,59 @@ void P_ProjectileHitLinedef(AActor* mo, line_t* line)
|
||||||
if (zbottom < (otherfloorz + EQUAL_EPSILON) && othersector->healthfloor > 0 && P_CheckLinedefVulnerable(line, wside, SECPART_Floor))
|
if (zbottom < (otherfloorz + EQUAL_EPSILON) && othersector->healthfloor > 0 && P_CheckLinedefVulnerable(line, wside, SECPART_Floor))
|
||||||
{
|
{
|
||||||
P_DamageSector(othersector, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_Floor, mo->Pos());
|
P_DamageSector(othersector, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_Floor, mo->Pos());
|
||||||
|
washit = true;
|
||||||
}
|
}
|
||||||
if (ztop > (otherceilingz - EQUAL_EPSILON) && othersector->healthceiling > 0 && P_CheckLinedefVulnerable(line, wside, SECPART_Ceiling))
|
if (ztop > (otherceilingz - EQUAL_EPSILON) && othersector->healthceiling > 0 && P_CheckLinedefVulnerable(line, wside, SECPART_Ceiling))
|
||||||
{
|
{
|
||||||
P_DamageSector(othersector, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_Ceiling, mo->Pos());
|
P_DamageSector(othersector, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_Ceiling, mo->Pos());
|
||||||
|
washit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line->health > 0 && P_CheckLinedefVulnerable(line, wside))
|
if (line->health > 0 && P_CheckLinedefVulnerable(line, wside))
|
||||||
{
|
{
|
||||||
P_DamageLinedef(line, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, wside, mo->Pos());
|
P_DamageLinedef(line, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, wside, mo->Pos());
|
||||||
|
washit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return washit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_ProjectileHitPlane(AActor* mo, int part)
|
// part = -1 means "detect from blocking"
|
||||||
|
bool P_ProjectileHitPlane(AActor* mo, int part)
|
||||||
{
|
{
|
||||||
|
if (part < 0)
|
||||||
|
{
|
||||||
|
if (mo->BlockingCeiling)
|
||||||
|
part = SECPART_Ceiling;
|
||||||
|
else if (mo->BlockingFloor)
|
||||||
|
part = SECPART_Floor;
|
||||||
|
}
|
||||||
|
|
||||||
// detect 3d floor hit
|
// detect 3d floor hit
|
||||||
if (mo->Blocking3DFloor)
|
if (mo->Blocking3DFloor)
|
||||||
{
|
{
|
||||||
if (mo->Blocking3DFloor->health3d > 0)
|
if (mo->Blocking3DFloor->health3d > 0)
|
||||||
|
{
|
||||||
P_DamageSector(mo->Blocking3DFloor, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_3D, mo->Pos());
|
P_DamageSector(mo->Blocking3DFloor, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_3D, mo->Pos());
|
||||||
return;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (part == SECPART_Floor && mo->Sector->healthfloor > 0 && P_CheckSectorVulnerable(mo->Sector, SECPART_Floor))
|
if (part == SECPART_Floor && mo->Sector->healthfloor > 0 && P_CheckSectorVulnerable(mo->Sector, SECPART_Floor))
|
||||||
|
{
|
||||||
P_DamageSector(mo->Sector, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_Floor, mo->Pos());
|
P_DamageSector(mo->Sector, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_Floor, mo->Pos());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (part == SECPART_Ceiling && mo->Sector->healthceiling > 0 && P_CheckSectorVulnerable(mo->Sector, SECPART_Ceiling))
|
else if (part == SECPART_Ceiling && mo->Sector->healthceiling > 0 && P_CheckSectorVulnerable(mo->Sector, SECPART_Ceiling))
|
||||||
|
{
|
||||||
P_DamageSector(mo->Sector, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_Ceiling, mo->Pos());
|
P_DamageSector(mo->Sector, mo, mo->GetMissileDamage((mo->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1), mo->DamageType, SECPART_Ceiling, mo->Pos());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -33,8 +33,8 @@ void P_DamageLinedef(line_t* line, AActor* source, int damage, FName damagetype,
|
||||||
|
|
||||||
void P_GeometryLineAttack(FTraceResults& trace, AActor* thing, int damage, FName damageType);
|
void P_GeometryLineAttack(FTraceResults& trace, AActor* thing, int damage, FName damageType);
|
||||||
void P_GeometryRadiusAttack(AActor* bombspot, AActor* bombsource, int bombdamage, int bombdistance, FName damagetype, int fulldamagedistance);
|
void P_GeometryRadiusAttack(AActor* bombspot, AActor* bombsource, int bombdamage, int bombdistance, FName damagetype, int fulldamagedistance);
|
||||||
void P_ProjectileHitLinedef(AActor* projectile, line_t* line);
|
bool P_ProjectileHitLinedef(AActor* projectile, line_t* line);
|
||||||
void P_ProjectileHitPlane(AActor* projectile, int part);
|
bool P_ProjectileHitPlane(AActor* projectile, int part);
|
||||||
|
|
||||||
bool P_CheckLinedefVulnerable(line_t* line, int side, int part = -1);
|
bool P_CheckLinedefVulnerable(line_t* line, int side, int part = -1);
|
||||||
bool P_CheckSectorVulnerable(sector_t* sector, int part);
|
bool P_CheckSectorVulnerable(sector_t* sector, int part);
|
||||||
|
|
|
@ -3561,6 +3561,18 @@ bool FSlide::BounceWall(AActor *mo)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [ZZ] if bouncing missile hits a damageable linedef, it dies
|
||||||
|
if (P_ProjectileHitLinedef(mo, line) && mo->bouncecount > 0)
|
||||||
|
{
|
||||||
|
mo->Vel.Zero();
|
||||||
|
mo->Speed = 0;
|
||||||
|
mo->bouncecount = 0;
|
||||||
|
if (mo->flags & MF_MISSILE)
|
||||||
|
P_ExplodeMissile(mo, line, nullptr);
|
||||||
|
else mo->CallDie(nullptr, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// The amount of bounces is limited
|
// The amount of bounces is limited
|
||||||
if (mo->bouncecount>0 && --mo->bouncecount == 0)
|
if (mo->bouncecount>0 && --mo->bouncecount == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2141,6 +2141,18 @@ void AActor::PlayBounceSound(bool onfloor)
|
||||||
|
|
||||||
bool AActor::FloorBounceMissile (secplane_t &plane)
|
bool AActor::FloorBounceMissile (secplane_t &plane)
|
||||||
{
|
{
|
||||||
|
// [ZZ] if bouncing missile hits a damageable sector(plane), it dies
|
||||||
|
if (P_ProjectileHitPlane(this, -1) && bouncecount > 0)
|
||||||
|
{
|
||||||
|
Vel.Zero();
|
||||||
|
Speed = 0;
|
||||||
|
bouncecount = 0;
|
||||||
|
if (flags & MF_MISSILE)
|
||||||
|
P_ExplodeMissile(this, nullptr, nullptr);
|
||||||
|
else CallDie(nullptr, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (Z() <= floorz && P_HitFloor (this))
|
if (Z() <= floorz && P_HitFloor (this))
|
||||||
{
|
{
|
||||||
// Landed in some sort of liquid
|
// Landed in some sort of liquid
|
||||||
|
|
Loading…
Reference in a new issue