From 660aff562d2fbcc9c9e2a1ecaaa8f15c42e9cf22 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sat, 23 Apr 2016 10:16:37 -0500 Subject: [PATCH] - 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. --- src/actor.h | 1 + src/p_map.cpp | 98 ++++++++++++++++++++++++++-------- src/thingdef/thingdef_data.cpp | 1 + 3 files changed, 79 insertions(+), 21 deletions(-) diff --git a/src/actor.h b/src/actor.h index 10bbd119a3..37815ba3c6 100644 --- a/src/actor.h +++ b/src/actor.h @@ -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 --- diff --git a/src/p_map.cpp b/src/p_map.cpp index 0938fe3b08..959412a132 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -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 RailHits; TArray 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; diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 55f20df034..efb7be0c25 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -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),