From cef8ae56325dd3ffddf8c755c0d59d9a652b062c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 27 Dec 2014 19:19:15 +0100 Subject: [PATCH 1/4] - fixed: The A_BossDeath code in P_MorphedDeath was missing a NULL pointer check. --- src/g_shared/a_morph.cpp | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 6014d6feee..e3433f12ef 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -529,24 +529,26 @@ bool P_MorphedDeath(AActor *actor, AActor **morphed, int *morphedstyle, int *mor { AMorphedMonster *fakeme = static_cast(actor); AActor *realme = fakeme->UnmorphedMe; - if ((fakeme->UnmorphTime) && - (fakeme->MorphStyle & MORPH_UNDOBYDEATH) && - (realme)) + if (realme != NULL) { - int realstyle = fakeme->MorphStyle; - int realhealth = fakeme->health; - if (P_UndoMonsterMorph(fakeme, !!(fakeme->MorphStyle & MORPH_UNDOBYDEATHFORCED))) + if ((fakeme->UnmorphTime) && + (fakeme->MorphStyle & MORPH_UNDOBYDEATH)) { - *morphed = realme; - *morphedstyle = realstyle; - *morphedhealth = realhealth; - return true; + int realstyle = fakeme->MorphStyle; + int realhealth = fakeme->health; + if (P_UndoMonsterMorph(fakeme, !!(fakeme->MorphStyle & MORPH_UNDOBYDEATHFORCED))) + { + *morphed = realme; + *morphedstyle = realstyle; + *morphedhealth = realhealth; + return true; + } + } + if (realme->flags4 & MF4_BOSSDEATH) + { + realme->health = 0; // make sure that A_BossDeath considers it dead. + CALL_ACTION(A_BossDeath, realme); } - } - if (realme->flags4 & MF4_BOSSDEATH) - { - realme->health = 0; // make sure that A_BossDeath considers it dead. - CALL_ACTION(A_BossDeath, realme); } fakeme->flags3 |= MF3_STAYMORPHED; // moved here from AMorphedMonster::Die() return false; From fdf2d6c493ea898e13e1b92b145566949f1ac38b Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sat, 27 Dec 2014 12:47:48 -0600 Subject: [PATCH 2/4] - Cleaned up some of the reflective code. - Added null checks to AIMREFLECT. - The missile being reflected now corrects the z velocity to perfectly reflect towards the actor's middle. --- src/p_mobj.cpp | 79 ++++++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 8c76d793e8..a88ec65159 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1961,48 +1961,50 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) // Don't change the angle if there's THRUREFLECT on the monster. if (!(BlockingMobj->flags7 & MF7_THRUREFLECT)) { - int dir; - angle_t delta; - - if (BlockingMobj->flags7 & MF7_MIRRORREFLECT) - angle = mo->angle + ANG180; - else - angle = R_PointToAngle2(BlockingMobj->x, BlockingMobj->y, mo->x, mo->y); - + //int dir; + //angle_t delta; + bool dontReflect = (mo->AdjustReflectionAngle(BlockingMobj, angle)); // Change angle for deflection/reflection - // AIMREFLECT calls precedence so make sure not to bother with adjusting here if declared. - if (!(BlockingMobj->flags7 & MF7_AIMREFLECT) && (mo->AdjustReflectionAngle(BlockingMobj, angle))) - { - goto explode; - } - // Reflect the missile along angle - if (BlockingMobj->flags7 & MF7_AIMREFLECT) + if (!dontReflect) { - dir = P_FaceMobj(mo, mo->target, &delta); - if (dir) - { // Turn clockwise - mo->angle += delta; + bool tg = (mo->target != NULL); + bool blockingtg = (BlockingMobj->target != NULL); + if (BlockingMobj->flags7 & MF7_AIMREFLECT && (tg || blockingtg)) + { + AActor *origin; + if (tg) + origin = mo->target; + else if (blockingtg) + origin = BlockingMobj->target; + + float speed = (float)(mo->Speed); + //dest->x - source->x + FVector3 velocity(origin->x - mo->x, origin->y - mo->y, (origin->z + (origin->height/2)) - mo->z); + velocity.Resize(speed); + angle = mo->angle >> ANGLETOFINESHIFT; + mo->velx = (fixed_t)(velocity.X); + mo->vely = (fixed_t)(velocity.Y); + mo->velz = (fixed_t)(velocity.Z); + /* + mo->velx = FixedMul(mo->Speed, finecosine[angle]); + mo->vely = FixedMul(mo->Speed, finesine[angle]); + mo->velz = -mo->velz; + */ } else - { // Turn counter clockwise - mo->angle -= delta; + { + mo->angle = angle; + angle >>= ANGLETOFINESHIFT; + mo->velx = FixedMul(mo->Speed >> 1, finecosine[angle]); + mo->vely = FixedMul(mo->Speed >> 1, finesine[angle]); + mo->velz = -mo->velz / 2; } - angle = mo->angle >> ANGLETOFINESHIFT; - mo->velx = FixedMul(mo->Speed, finecosine[angle]); - mo->vely = FixedMul(mo->Speed, finesine[angle]); - mo->velz = -mo->velz; } else { - mo->angle = angle; - angle >>= ANGLETOFINESHIFT; - mo->velx = FixedMul(mo->Speed >> 1, finecosine[angle]); - mo->vely = FixedMul(mo->Speed >> 1, finesine[angle]); - mo->velz = -mo->velz / 2; - } - - + goto explode; + } } if (mo->flags2 & MF2_SEEKERMISSILE) { @@ -2928,8 +2930,10 @@ bool AActor::AdjustReflectionAngle (AActor *thing, angle_t &angle) if (flags2 & MF2_DONTREFLECT) return true; if (thing->flags7 & MF7_THRUREFLECT) return false; + if (thing->flags7 & MF7_MIRRORREFLECT) + angle += ANGLE_180; // Change angle for reflection - if (thing->flags4&MF4_SHIELDREFLECT) + else if (thing->flags4&MF4_SHIELDREFLECT) { // Shield reflection (from the Centaur if (abs (angle - thing->angle)>>24 > 45) @@ -2952,6 +2956,13 @@ bool AActor::AdjustReflectionAngle (AActor *thing, angle_t &angle) else angle -= ANG45; } + else if (thing->flags7 & MF7_AIMREFLECT) + { + if (this->target != NULL) + A_Face(this, this->target); + else if (thing->target != NULL) + A_Face(this, thing->target); + } else angle += ANGLE_1 * ((pr_reflect()%16)-8); return false; From 519ff8b7d114b6d38ba0813b8d7f509ef6e6329c Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sat, 27 Dec 2014 14:15:14 -0600 Subject: [PATCH 3/4] - HITTARGET/MASTER/TRACER now set the puff's pointer(s) within P_SpawnPuff. - PUFFGETSOWNER, for the sake of compatibility, maintains override for target. --- src/p_local.h | 2 +- src/p_map.cpp | 18 +++--------------- src/p_mobj.cpp | 10 +++++++++- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index c0a754e25b..fe7958807b 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -133,7 +133,7 @@ enum EPuffFlags PF_NORANDOMZ = 16 }; -AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0); +AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0, AActor *vict = NULL); void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator); void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator); void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator); diff --git a/src/p_map.cpp b/src/p_map.cpp index 456db2d0f7..aecead6eda 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3761,14 +3761,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, puffFlags |= PF_HITTHINGBLEED; // We must pass the unreplaced puff type here - puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING); - } - - if (puffDefaults != NULL && trace.Actor != NULL && puff != NULL) - { - if (puffDefaults->flags7 && MF7_HITTARGET) puff->target = trace.Actor; - if (puffDefaults->flags7 && MF7_HITMASTER) puff->master = trace.Actor; - if (puffDefaults->flags7 && MF7_HITTRACER) puff->tracer = trace.Actor; + puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING, trace.Actor); } // Allow puffs to inflict poison damage, so that hitscans can poison, too. @@ -4211,14 +4204,9 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i } if (spawnpuff) { - P_SpawnPuff(source, puffclass, x, y, z, (source->angle + angleoffset) - ANG90, 1, puffflags); - } - if (hitactor != NULL && puffDefaults != NULL && thepuff != NULL) - { - if (puffDefaults->flags7 & MF7_HITTARGET) thepuff->target = hitactor; - if (puffDefaults->flags7 & MF7_HITMASTER) thepuff->master = hitactor; - if (puffDefaults->flags7 & MF7_HITTRACER) thepuff->tracer = hitactor; + P_SpawnPuff(source, puffclass, x, y, z, (source->angle + angleoffset) - ANG90, 1, puffflags, hitactor); } + if (puffDefaults && puffDefaults->PoisonDamage > 0 && puffDefaults->PoisonDuration != INT_MIN) { P_PoisonMobj(hitactor, thepuff ? thepuff : source, source, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod, puffDefaults->PoisonDamageType); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index a88ec65159..dbce9e2ff0 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4930,7 +4930,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) // P_SpawnPuff // -AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags) +AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags, AActor *vict) { AActor *puff; @@ -4940,9 +4940,17 @@ AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t puff = Spawn (pufftype, x, y, z, ALLOW_REPLACE); if (puff == NULL) return NULL; + //Moved puff creation and target/master/tracer setting to here. + if (puff && vict) + { + if (puff->flags7 & MF7_HITTARGET) puff->target = vict; + if (puff->flags7 & MF7_HITMASTER) puff->master = vict; + if (puff->flags7 & MF7_HITTRACER) puff->tracer = vict; + } // [BB] If the puff came from a player, set the target of the puff to this player. if ( puff && (puff->flags5 & MF5_PUFFGETSOWNER)) puff->target = source; + if (source != NULL) puff->angle = R_PointToAngle2(x, y, source->x, source->y); From b5d0c5c357e3d74c1b90b9492cf176f14b1c7f72 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 28 Dec 2014 22:15:12 +0100 Subject: [PATCH 4/4] - fixed: When a player drops his inventory, the dropped weapons must be checked for their class to ensure that they are not DehackedPickups which cannot be modified as intended. --- src/p_user.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index bf656d2b9e..e91766cf0f 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1365,7 +1365,7 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor, int dmgflags) weap->SpawnState != ::GetDefault()->SpawnState) { item = P_DropItem (this, weap->GetClass(), -1, 256); - if (item != NULL) + if (item != NULL && item->IsKindOf(RUNTIME_CLASS(AWeapon))) { if (weap->AmmoGive1 && weap->Ammo1) {