- Added support for THRU flags on bullets and rails.

- ALLOWTHRUFLAGS must be used on the puffs, added for the sake of compatibility with older mods. This applies to the following:
-- Bullets: THRUACTORS, THRUSPECIES
-- Rails: Same as bullets, but includes THRUGHOST.
This commit is contained in:
MajorCooke 2016-04-23 10:16:37 -05:00 committed by Christoph Oelckers
parent 262f3575ae
commit 660aff562d
3 changed files with 79 additions and 21 deletions

View file

@ -380,6 +380,7 @@ enum ActorFlag7
MF7_FORCEDECAL = 0x00080000, // [ZK] Forces puff's decal to override the weapon's.
MF7_LAXTELEFRAGDMG = 0x00100000, // [MC] Telefrag damage can be reduced.
MF7_ICESHATTER = 0x00200000, // [MC] Shatters ice corpses regardless of damagetype.
MF7_ALLOWTHRUFLAGS = 0x00400000, // [MC] Allow THRUACTORS and the likes on puffs to prevent mod breakage.
};
// --- mobj.renderflags ---

View file

@ -4023,8 +4023,11 @@ DAngle P_AimLineAttack(AActor *t1, DAngle angle, double distance, FTranslatedLin
struct Origin
{
AActor *Caller;
FNameNoInit PuffSpecies;
bool hitGhosts;
bool hitSameSpecies;
bool MThruSpecies;
bool ThruSpecies;
bool ThruActors;
};
static ETraceStatus CheckForActor(FTraceResults &res, void *userdata)
@ -4036,17 +4039,16 @@ static ETraceStatus CheckForActor(FTraceResults &res, void *userdata)
Origin *data = (Origin *)userdata;
// check for physical attacks on spectrals
if (res.Actor->flags4 & MF4_SPECTRAL)
{
return TRACE_Skip;
}
// Skip actors if the puff has:
// 1. THRUACTORS or SPECTRAL
// 2. MTHRUSPECIES on puff and the shooter has same species as the hit actor
// 3. THRUSPECIES on puff and the puff has same species as the hit actor
// 4. THRUGHOST on puff and the GHOST flag on the hit actor
if (data->hitSameSpecies && res.Actor->GetSpecies() == data->Caller->GetSpecies())
{
return TRACE_Skip;
}
if (data->hitGhosts && res.Actor->flags3 & MF3_GHOST)
if ((data->ThruActors) || (res.Actor->flags4 & MF4_SPECTRAL) ||
(data->MThruSpecies && res.Actor->GetSpecies() == data->Caller->GetSpecies()) ||
(data->ThruSpecies && res.Actor->GetSpecies() == data->PuffSpecies) ||
(data->hitGhosts && res.Actor->flags3 & MF3_GHOST))
{
return TRACE_Skip;
}
@ -4108,14 +4110,41 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
// We need to check the defaults of the replacement here
AActor *puffDefaults = GetDefaultByType(pufftype->GetReplacement());
TData.hitGhosts = (t1->player != NULL &&
t1->player->ReadyWeapon != NULL &&
(t1->player->ReadyWeapon->flags2 & MF2_THRUGHOST)) ||
(puffDefaults && (puffDefaults->flags2 & MF2_THRUGHOST));
TData.hitSameSpecies = (puffDefaults && (puffDefaults->flags6 & MF6_MTHRUSPECIES));
TData.MThruSpecies = (puffDefaults && (puffDefaults->flags6 & MF6_MTHRUSPECIES));
TData.PuffSpecies = NAME_None;
// [MC] To prevent possible mod breakage, this flag is pretty much necessary.
// Somewhere, someone is relying on these to spawn on actors and move through them.
if ((puffDefaults->flags7 & MF7_ALLOWTHRUFLAGS))
{
TData.ThruSpecies = (puffDefaults && (puffDefaults->flags6 & MF6_THRUSPECIES));
TData.ThruActors = (puffDefaults && (puffDefaults->flags2 & MF2_THRUACTORS));
// [MC] Because this is a one-hit trace event, we need to spawn the puff, get the species
// and destroy it. Assume there is no species unless tempuff isn't NULL. We cannot get
// a proper species the same way as puffDefaults flags it appears...
AActor *tempuff = NULL;
if (pufftype != NULL)
tempuff = Spawn(pufftype, t1->Pos(), ALLOW_REPLACE);
if (tempuff != NULL)
{
TData.PuffSpecies = tempuff->GetSpecies();
tempuff->Destroy();
}
}
else
{
TData.ThruSpecies = false;
TData.ThruActors = false;
}
// if the puff uses a non-standard damage type, this will override default, hitscan and melee damage type.
// All other explicitly passed damage types (currenty only MDK) will be preserved.
if ((damageType == NAME_None || damageType == NAME_Melee || damageType == NAME_Hitscan) &&
@ -4543,9 +4572,13 @@ struct RailData
AActor *Caller;
TArray<SRailHit> RailHits;
TArray<SPortalHit> PortalHits;
FNameNoInit PuffSpecies;
bool StopAtOne;
bool StopAtInvul;
bool ThruGhosts;
bool ThruSpecies;
bool MThruSpecies;
bool ThruActors;
};
static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata)
@ -4572,8 +4605,16 @@ static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata)
return TRACE_Stop;
}
// Skip actors with the same species if the puff has MTHRUSPECIES.
if (data->ThruSpecies && res.Actor->GetSpecies() == data->Caller->GetSpecies())
// Skip actors if the puff has:
// 1. THRUACTORS (This one did NOT include a check for spectral)
// 2. MTHRUSPECIES on puff and the shooter has same species as the hit actor
// 3. THRUSPECIES on puff and the puff has same species as the hit actor
// 4. THRUGHOST on puff and the GHOST flag on the hit actor
if ((data->ThruActors) ||
(data->MThruSpecies && res.Actor->GetSpecies() == data->Caller->GetSpecies()) ||
(data->ThruSpecies && res.Actor->GetSpecies() == data->PuffSpecies) ||
(data->ThruGhosts && res.Actor->flags3 & MF3_GHOST))
{
return TRACE_Skip;
}
@ -4648,7 +4689,27 @@ void P_RailAttack(FRailParams *p)
// disabled because not complete yet.
flags = (puffDefaults->flags6 & MF6_NOTRIGGER) ? TRACE_ReportPortals : TRACE_PCross | TRACE_Impact | TRACE_ReportPortals;
rail_data.StopAtInvul = (puffDefaults->flags3 & MF3_FOILINVUL) ? false : true;
rail_data.ThruSpecies = (puffDefaults->flags6 & MF6_MTHRUSPECIES) ? true : false;
rail_data.MThruSpecies = ((puffDefaults->flags6 & MF6_MTHRUSPECIES)) ? true : false;
// Prevent mod breakage as somewhere, someone is relying on these to spawn on an actor
// and move through them...
if ((puffDefaults->flags7 & MF7_ALLOWTHRUFLAGS))
{
rail_data.ThruGhosts = !!(puffDefaults->flags2 & MF2_THRUGHOST);
rail_data.ThruSpecies = !!(puffDefaults->flags6 & MF6_THRUSPECIES);
rail_data.ThruActors = !!(puffDefaults->flags2 & MF2_THRUACTORS);
}
else
{
rail_data.ThruGhosts = false;
rail_data.MThruSpecies = false;
rail_data.ThruActors = false;
}
// used as damage inflictor
AActor *thepuff = NULL;
if (puffclass != NULL) thepuff = Spawn(puffclass, source->Pos(), ALLOW_REPLACE);
rail_data.PuffSpecies = (thepuff != NULL) ? thepuff->GetSpecies() : NAME_None;
Trace(start, source->Sector, vec, p->distance, MF_SHOOTABLE, ML_BLOCKEVERYTHING, source, trace, flags, ProcessRailHit, &rail_data);
@ -4656,11 +4717,6 @@ void P_RailAttack(FRailParams *p)
unsigned int i;
FName damagetype = (puffDefaults == NULL || puffDefaults->DamageType == NAME_None) ? FName(NAME_Railgun) : puffDefaults->DamageType;
// used as damage inflictor
AActor *thepuff = NULL;
if (puffclass != NULL) thepuff = Spawn(puffclass, source->Pos(), ALLOW_REPLACE);
for (i = 0; i < rail_data.RailHits.Size(); i++)
{
bool spawnpuff;

View file

@ -256,6 +256,7 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(MF7, FORCEDECAL, AActor, flags7),
DEFINE_FLAG(MF7, LAXTELEFRAGDMG, AActor, flags7),
DEFINE_FLAG(MF7, ICESHATTER, AActor, flags7),
DEFINE_FLAG(MF7, ALLOWTHRUFLAGS, AActor, flags7),
// Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),