diff --git a/src/actor.h b/src/actor.h index d30da8922..7dc4bf1ee 100644 --- a/src/actor.h +++ b/src/actor.h @@ -1397,6 +1397,28 @@ inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle) void PrintMiscActorInfo(AActor * query); AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask); +// If we want to make P_AimLineAttack capable of handling arbitrary portals, it needs to pass a lot more info than just the linetarget actor. +struct FTranslatedLineTarget +{ + AActor *linetarget; + angle_t hitangle; + fixedvec3 targetPosFromSrc; + angle_t targetAngleFromSrc; + fixedvec3 sourcePosFromTarget; + angle_t sourceAngleFromTarget; + bool unlinked; // found by a trace that went through an unlinked portal. + + angle_t SourceAngleToTarget() const + { + return R_PointToAngle2(sourcePosFromTarget.x, sourcePosFromTarget.y, linetarget->X(), linetarget->Y()); + } + angle_t TargetAngleToSource() const + { + return R_PointToAngle2(linetarget->X(), linetarget->Y(), sourcePosFromTarget.x, sourcePosFromTarget.y); + } +}; + + #define S_FREETARGMOBJ 1 #endif // __P_MOBJ_H__ diff --git a/src/actorptrselect.cpp b/src/actorptrselect.cpp index 54c41e6ba..a93ecd6a1 100644 --- a/src/actorptrselect.cpp +++ b/src/actorptrselect.cpp @@ -2,6 +2,7 @@ #include "actor.h" #include "d_player.h" #include "p_pspr.h" +#include "p_local.h" //========================================================================== // @@ -34,6 +35,8 @@ AActor *COPY_AAPTR(AActor *origin, int selector) { if (selector == AAPTR_DEFAULT) return origin; + FTranslatedLineTarget t; + if (origin) { if (origin->player) @@ -41,11 +44,9 @@ AActor *COPY_AAPTR(AActor *origin, int selector) switch (selector & AAPTR_PLAYER_SELECTORS) { case AAPTR_PLAYER_GETTARGET: - { - AActor *gettarget = NULL; - P_BulletSlope(origin, &gettarget); - return gettarget; - } + P_BulletSlope(origin, &t, ALF_PORTALRESTRICT); + return t.linetarget; + case AAPTR_PLAYER_GETCONVERSATION: return origin->player->ConversationNPC; } @@ -60,11 +61,8 @@ AActor *COPY_AAPTR(AActor *origin, int selector) return origin->FriendPlayer ? AAPTR_RESOLVE_PLAYERNUM(origin->FriendPlayer - 1) : NULL; case AAPTR_GET_LINETARGET: - { - AActor *gettarget = NULL; - P_BulletSlope(origin, &gettarget); - return gettarget; - } + P_BulletSlope(origin, &t, ALF_PORTALRESTRICT); + return t.linetarget; } } diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 70f36bea9..1e4516b27 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -872,16 +872,16 @@ CCMD (wdir) //----------------------------------------------------------------------------- CCMD(linetarget) { - AActor *linetarget; + FTranslatedLineTarget t; if (CheckCheatmode () || players[consoleplayer].mo == NULL) return; - P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE, &linetarget, 0); - if (linetarget) + P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE, &t, 0); + if (t.linetarget) { Printf("Target=%s, Health=%d, Spawnhealth=%d\n", - linetarget->GetClass()->TypeName.GetChars(), - linetarget->health, - linetarget->SpawnHealth()); + t.linetarget->GetClass()->TypeName.GetChars(), + t.linetarget->health, + t.linetarget->SpawnHealth()); } else Printf("No target found\n"); } @@ -889,18 +889,18 @@ CCMD(linetarget) // As linetarget, but also give info about non-shootable actors CCMD(info) { - AActor *linetarget; + FTranslatedLineTarget t; if (CheckCheatmode () || players[consoleplayer].mo == NULL) return; P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE, - &linetarget, 0, ALF_CHECKNONSHOOTABLE|ALF_FORCENOSMART); - if (linetarget) + &t, 0, ALF_CHECKNONSHOOTABLE|ALF_FORCENOSMART); + if (t.linetarget) { Printf("Target=%s, Health=%d, Spawnhealth=%d\n", - linetarget->GetClass()->TypeName.GetChars(), - linetarget->health, - linetarget->SpawnHealth()); - PrintMiscActorInfo(linetarget); + t.linetarget->GetClass()->TypeName.GetChars(), + t.linetarget->health, + t.linetarget->SpawnHealth()); + PrintMiscActorInfo(t.linetarget); } else Printf("No target found. Info cannot find actors that have " "the NOBLOCKMAP flag or have height/radius of 0.\n"); diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 73fda96b3..08eb018f9 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -33,7 +33,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch) angle_t angle; int damage; int pitch; - AActor *linetarget; + FTranslatedLineTarget t; if (self->player != NULL) { @@ -53,15 +53,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch) angle = self->angle; angle += pr_punch.Random2() << 18; - pitch = P_AimLineAttack (self, angle, MELEERANGE, &linetarget); + pitch = P_AimLineAttack (self, angle, MELEERANGE); - P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, LAF_ISMELEEATTACK, &linetarget); + P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, LAF_ISMELEEATTACK, &t); // turn to face target - if (linetarget) + if (t.linetarget) { S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM); - self->angle = self->AngleTo(linetarget); + self->angle = t.SourceAngleToTarget(); } return 0; } @@ -133,7 +133,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) angle_t angle; angle_t slope; player_t *player; - AActor *linetarget; + FTranslatedLineTarget t; int actualdamage; if (NULL == (player = self->player)) @@ -159,18 +159,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) } angle = self->angle + (pr_saw.Random2() * (spread_xy / 255)); - slope = P_AimLineAttack (self, angle, range, &linetarget) + (pr_saw.Random2() * (spread_z / 255)); + slope = P_AimLineAttack (self, angle, range, &t) + (pr_saw.Random2() * (spread_z / 255)); AWeapon *weapon = self->player->ReadyWeapon; - if ((weapon != NULL) && !(flags & SF_NOUSEAMMO) && !(!linetarget && (flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON()) + if ((weapon != NULL) && !(flags & SF_NOUSEAMMO) && !(!t.linetarget && (flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON()) { if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - P_LineAttack (self, angle, range, slope, damage, NAME_Melee, pufftype, false, &linetarget, &actualdamage); + P_LineAttack (self, angle, range, slope, damage, NAME_Melee, pufftype, false, &t, &actualdamage); - if (!linetarget) + if (!t.linetarget) { if ((flags & SF_RANDOMLIGHTMISS) && (pr_saw() > 64)) { @@ -197,7 +197,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) } } - if (lifesteal && !(linetarget->flags5 & MF5_DONTDRAIN)) + if (lifesteal && !(t.linetarget->flags5 & MF5_DONTDRAIN)) { if (flags & SF_STEALARMOR) { @@ -232,7 +232,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) // turn to face target if (!(flags & SF_NOTURN)) { - angle = self->AngleTo(linetarget); + angle = t.SourceAngleToTarget(); if (angle - self->angle > ANG180) { if (angle - self->angle < (angle_t)(-ANG90 / 20)) @@ -643,7 +643,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) int j; int damage; angle_t an; - AActor *linetarget; + FTranslatedLineTarget t; if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra"); if (numrays <= 0) numrays = 40; @@ -662,18 +662,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) an = self->angle - angle / 2 + angle / numrays*i; // self->target is the originator (player) of the missile - P_AimLineAttack(self->target, an, distance, &linetarget, vrange); + P_AimLineAttack(self->target, an, distance, &t, vrange); - if (linetarget != NULL) + if (t.linetarget != NULL) { - AActor *spray = Spawn(spraytype, linetarget->PosPlusZ(linetarget->height >> 2), ALLOW_REPLACE); + AActor *spray = Spawn(spraytype, t.linetarget->PosPlusZ(t.linetarget->height >> 2), ALLOW_REPLACE); int dmgFlags = 0; FName dmgType = NAME_BFGSplash; if (spray != NULL) { - if (spray->flags6 & MF6_MTHRUSPECIES && self->target->GetSpecies() == linetarget->GetSpecies()) + if (spray->flags6 & MF6_MTHRUSPECIES && self->target->GetSpecies() == t.linetarget->GetSpecies()) { spray->Destroy(); // [MC] Remove it because technically, the spray isn't trying to "hit" them. continue; @@ -696,8 +696,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) damage = defdamage; } - int newdam = P_DamageMobj(linetarget, self->target, self->target, damage, dmgType, dmgFlags); - P_TraceBleed(newdam > 0 ? newdam : damage, linetarget, self->target); + int newdam = P_DamageMobj(t.linetarget, self->target, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.SourceAngleToTarget()); + P_TraceBleed(newdam > 0 ? newdam : damage, &t, self); } } return 0; diff --git a/src/g_doom/a_scriptedmarine.cpp b/src/g_doom/a_scriptedmarine.cpp index 43eec76e1..5051a4b94 100644 --- a/src/g_doom/a_scriptedmarine.cpp +++ b/src/g_doom/a_scriptedmarine.cpp @@ -276,16 +276,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw) if (self->CheckMeleeRange ()) { angle_t angle; - AActor *linetarget; + FTranslatedLineTarget t; damage *= (pr_m_saw()%10+1); angle = self->angle + (pr_m_saw.Random2() << 18); P_LineAttack (self, angle, MELEERANGE+1, - P_AimLineAttack (self, angle, MELEERANGE+1, &linetarget), damage, - NAME_Melee, pufftype, false, &linetarget); + P_AimLineAttack (self, angle, MELEERANGE+1), damage, + NAME_Melee, pufftype, false, &t); - if (!linetarget) + if (!t.linetarget) { S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM); return 0; @@ -293,7 +293,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw) S_Sound (self, CHAN_WEAPON, hitsound, 1, ATTN_NORM); // turn to face target - angle = self->AngleTo(linetarget); + angle = t.SourceAngleToTarget(); if (angle - self->angle > ANG180) { if (angle - self->angle < (angle_t)(-ANG90/20)) @@ -328,7 +328,7 @@ static void MarinePunch(AActor *self, int damagemul) angle_t angle; int damage; int pitch; - AActor *linetarget; + FTranslatedLineTarget t; if (self->target == NULL) return; @@ -337,15 +337,14 @@ static void MarinePunch(AActor *self, int damagemul) A_FaceTarget (self); angle = self->angle + (pr_m_punch.Random2() << 18); - pitch = P_AimLineAttack (self, angle, MELEERANGE, &linetarget); - P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true, &linetarget); + pitch = P_AimLineAttack (self, angle, MELEERANGE); + P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true, &t); // turn to face target - if (linetarget) + if (t.linetarget) { S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM); - self->angle = self->AngleTo(linetarget); - + self->angle = t.SourceAngleToTarget(); } } diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index dcc3e1774..9ebdaf169 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -176,7 +176,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1) int damage; int slope; player_t *player; - AActor *linetarget; + FTranslatedLineTarget t; if (NULL == (player = self->player)) { @@ -185,11 +185,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1) damage = 1 + (pr_beakatkpl1()&3); angle = player->mo->angle; - slope = P_AimLineAttack (player->mo, angle, MELEERANGE, &linetarget); - P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &linetarget); - if (linetarget) + slope = P_AimLineAttack (player->mo, angle, MELEERANGE); + P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t); + if (t.linetarget) { - player->mo->angle = player->mo->AngleTo(linetarget); + player->mo->angle = t.SourceAngleToTarget(); } P_PlayPeck (player->mo); player->chickenPeck = 12; @@ -211,7 +211,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2) int damage; int slope; player_t *player; - AActor *linetarget; + FTranslatedLineTarget t; if (NULL == (player = self->player)) { @@ -220,11 +220,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2) damage = pr_beakatkpl2.HitDice (4); angle = player->mo->angle; - slope = P_AimLineAttack (player->mo, angle, MELEERANGE, &linetarget); - P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &linetarget); - if (linetarget) + slope = P_AimLineAttack (player->mo, angle, MELEERANGE); + P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t); + if (t.linetarget) { - player->mo->angle = player->mo->AngleTo(linetarget); + player->mo->angle = t.SourceAngleToTarget(); } P_PlayPeck (player->mo); player->chickenPeck = 12; diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index f51de13e1..4ff89d9d2 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -66,7 +66,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack) angle_t angle; int slope; player_t *player; - AActor *linetarget; + FTranslatedLineTarget t; if (NULL == (player = self->player)) { @@ -88,13 +88,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack) } angle = self->angle; angle += pr_sap.Random2() << 18; - slope = P_AimLineAttack (self, angle, MELEERANGE, &linetarget); - P_LineAttack (self, angle, MELEERANGE, slope, damage, NAME_Melee, puff, true, &linetarget); - if (linetarget) + slope = P_AimLineAttack (self, angle, MELEERANGE); + P_LineAttack (self, angle, MELEERANGE, slope, damage, NAME_Melee, puff, true, &t); + if (t.linetarget) { //S_StartSound(player->mo, sfx_stfhit); // turn to face target - self->angle = self->AngleTo(linetarget); + self->angle = t.SourceAngleToTarget(); } return 0; } @@ -257,7 +257,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) fixed_t dist; player_t *player; PClassActor *pufftype; - AActor *linetarget; + FTranslatedLineTarget t; int actualdamage = 0; if (NULL == (player = self->player)) @@ -290,9 +290,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) angle += pr_gatk.Random2() << 18; pufftype = PClass::FindActor("GauntletPuff1"); } - slope = P_AimLineAttack (self, angle, dist, &linetarget); - P_LineAttack (self, angle, dist, slope, damage, NAME_Melee, pufftype, false, &linetarget, &actualdamage); - if (!linetarget) + slope = P_AimLineAttack (self, angle, dist); + P_LineAttack (self, angle, dist, slope, damage, NAME_Melee, pufftype, false, &t, &actualdamage); + if (!t.linetarget) { if (pr_gatk() > 64) { @@ -316,7 +316,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) } if (power) { - if (!(linetarget->flags5 & MF5_DONTDRAIN)) P_GiveBody (self, actualdamage>>1); + if (!(t.linetarget->flags5 & MF5_DONTDRAIN)) P_GiveBody (self, actualdamage>>1); S_Sound (self, CHAN_AUTO, "weapons/gauntletspowhit", 1, ATTN_NORM); } else @@ -324,7 +324,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) S_Sound (self, CHAN_AUTO, "weapons/gauntletshit", 1, ATTN_NORM); } // turn to face target - angle = self->AngleTo(linetarget); + angle = t.SourceAngleToTarget(); if (angle-self->angle > ANG180) { if ((int)(angle-self->angle) < -ANG90/20) @@ -594,7 +594,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL2) AActor *mo; player_t *player; - AActor *linetarget; + FTranslatedLineTarget t; if (NULL == (player = self->player)) { @@ -607,16 +607,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL2) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - mo = P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AMaceFX4), self->angle, &linetarget); + mo = P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AMaceFX4), self->angle, &t); if (mo) { mo->velx += self->velx; mo->vely += self->vely; mo->velz = 2*FRACUNIT+ clamp(finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)], -5*FRACUNIT, 5*FRACUNIT); - if (linetarget) + if (t.linetarget && !t.unlinked) { - mo->tracer = linetarget; + mo->tracer = t.linetarget; } } S_Sound (self, CHAN_WEAPON, "weapons/maceshoot", 1, ATTN_NORM); @@ -637,7 +637,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) AActor *target; angle_t angle = 0; bool newAngle; - AActor *linetarget; + FTranslatedLineTarget t; if ((self->Z() <= self->floorz) && P_HitFloor (self)) { // Landed in some sort of liquid @@ -671,11 +671,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) angle = 0; for (i = 0; i < 16; i++) { - P_AimLineAttack (self, angle, 10*64*FRACUNIT, &linetarget, 0, ALF_NOFRIENDS, NULL, self->target); - if (linetarget && self->target != linetarget) + P_AimLineAttack (self, angle, 10*64*FRACUNIT, &t, 0, ALF_NOFRIENDS|ALF_PORTALRESTRICT, NULL, self->target); + if (t.linetarget && self->target != t.linetarget) { - self->tracer = linetarget; - angle = self->AngleTo(linetarget); + self->tracer = t.linetarget; + angle = t.SourceAngleToTarget(); newAngle = true; break; } @@ -943,7 +943,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL2) player_t *player; AActor *MissileActor; - AActor *linetarget; + FTranslatedLineTarget t; if (NULL == (player = self->player)) { @@ -955,16 +955,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL2) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AHornRodFX2), self->angle, &linetarget, &MissileActor); + P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AHornRodFX2), self->angle, &t, &MissileActor); // Use MissileActor instead of the return value from // P_SpawnPlayerMissile because we need to give info to the mobj // even if it exploded immediately. if (MissileActor != NULL) { MissileActor->special2 = (int)(player - players); - if (linetarget) + if (t.linetarget && !t.unlinked) { - MissileActor->tracer = linetarget; + MissileActor->tracer = t.linetarget; } S_Sound (MissileActor, CHAN_WEAPON, "weapons/hornrodpowshoot", 1, ATTN_NORM); } diff --git a/src/g_hexen/a_clericholy.cpp b/src/g_hexen/a_clericholy.cpp index 466c0f7c8..f87c2dd7d 100644 --- a/src/g_hexen/a_clericholy.cpp +++ b/src/g_hexen/a_clericholy.cpp @@ -213,7 +213,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack) PARAM_ACTION_PROLOGUE; player_t *player; - AActor *linetarget; + FTranslatedLineTarget t; if (NULL == (player = self->player)) { @@ -225,10 +225,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - AActor *missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("HolyMissile"), self->angle, &linetarget); - if (missile != NULL) + AActor *missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("HolyMissile"), self->angle, &t); + if (missile != NULL && !t.unlinked) { - missile->tracer = linetarget; + missile->tracer = t.linetarget; } weapon->CHolyCount = 3; diff --git a/src/g_hexen/a_clericmace.cpp b/src/g_hexen/a_clericmace.cpp index c9b2e4f8d..05698c086 100644 --- a/src/g_hexen/a_clericmace.cpp +++ b/src/g_hexen/a_clericmace.cpp @@ -5,8 +5,6 @@ #include "thingdef/thingdef.h" */ -extern void AdjustPlayerAngle (AActor *pmo, AActor *linetarget); - static FRandom pr_maceatk ("CMaceAttack"); //=========================================================================== @@ -24,7 +22,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack) int slope; int i; player_t *player; - AActor *linetarget; + FTranslatedLineTarget t; if (NULL == (player = self->player)) { @@ -39,13 +37,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack) for (int j = 1; j >= -1; j -= 2) { angle = player->mo->angle + j*i*(ANG45 / 16); - slope = P_AimLineAttack(player->mo, angle, 2 * MELEERANGE, &linetarget); - if (linetarget) + slope = P_AimLineAttack(player->mo, angle, 2 * MELEERANGE, &t); + if (t.linetarget) { - P_LineAttack(player->mo, angle, 2 * MELEERANGE, slope, damage, NAME_Melee, hammertime, true, &linetarget); - if (linetarget != NULL) + P_LineAttack(player->mo, angle, 2 * MELEERANGE, slope, damage, NAME_Melee, hammertime, true, &t); + if (t.linetarget != NULL) { - AdjustPlayerAngle(player->mo, linetarget); + AdjustPlayerAngle(player->mo, &t); goto macedone; } } @@ -55,7 +53,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack) player->mo->weaponspecial = 0; angle = player->mo->angle; - slope = P_AimLineAttack (player->mo, angle, MELEERANGE, &linetarget); + slope = P_AimLineAttack (player->mo, angle, MELEERANGE); P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, hammertime); macedone: return 0; diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index 457a54738..2644b29b0 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -55,7 +55,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) int slope; int i; player_t *player; - AActor *linetarget; + FTranslatedLineTarget t; PClassActor *puff; if (NULL == (player = self->player)) @@ -73,15 +73,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) for (int j = 1; j >= -1; j -= 2) { angle = pmo->angle + j*i*(ANG45 / 16); - slope = P_AimLineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D); - if (linetarget) + slope = P_AimLineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), &t, 0, ALF_CHECK3D); + if (t.linetarget) { - P_LineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &linetarget); - if (linetarget != NULL) + P_LineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &t); + if (t.linetarget != NULL) { - pmo->angle = pmo->AngleTo(linetarget); - if (((linetarget->player && (!linetarget->IsTeammate(pmo) || level.teamdamage != 0)) || linetarget->flags3&MF3_ISMONSTER) - && (!(linetarget->flags2&(MF2_DORMANT | MF2_INVULNERABLE)))) + pmo->angle = t.SourceAngleToTarget(); + if (((t.linetarget->player && (!t.linetarget->IsTeammate(pmo) || level.teamdamage != 0)) || t.linetarget->flags3&MF3_ISMONSTER) + && (!(t.linetarget->flags2&(MF2_DORMANT | MF2_INVULNERABLE)))) { newLife = player->health + (damage >> 3); newLife = newLife > max ? max : newLife; diff --git a/src/g_hexen/a_fighteraxe.cpp b/src/g_hexen/a_fighteraxe.cpp index 047c02fc8..1681efe9f 100644 --- a/src/g_hexen/a_fighteraxe.cpp +++ b/src/g_hexen/a_fighteraxe.cpp @@ -24,8 +24,6 @@ void A_FAxeCheckReadyG (AActor *actor); void A_FAxeCheckUpG (AActor *actor); void A_FAxeAttack (AActor *actor); -extern void AdjustPlayerAngle (AActor *pmo, AActor *linetarget); - // The Fighter's Axe -------------------------------------------------------- class AFWeapAxe : public AFighterWeapon @@ -210,7 +208,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) player_t *player; AWeapon *weapon; PClassActor *pufftype; - AActor *linetarget; + FTranslatedLineTarget t; if (NULL == (player = self->player)) { @@ -239,17 +237,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) for (int j = 1; j >= -1; j -= 2) { angle = pmo->angle + j*i*(ANG45 / 16); - slope = P_AimLineAttack(pmo, angle, AXERANGE, &linetarget); - if (linetarget) + slope = P_AimLineAttack(pmo, angle, AXERANGE, &t); + if (t.linetarget) { - P_LineAttack(pmo, angle, AXERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget); - if (linetarget != NULL) + P_LineAttack(pmo, angle, AXERANGE, slope, damage, NAME_Melee, pufftype, true, &t); + if (t.linetarget != NULL) { - if (linetarget->flags3&MF3_ISMONSTER || linetarget->player) + if (t.linetarget->flags3&MF3_ISMONSTER || t.linetarget->player) { - P_ThrustMobj(linetarget, angle, power); + P_ThrustMobj(t.linetarget, t.hitangle, power); } - AdjustPlayerAngle(pmo, linetarget); + AdjustPlayerAngle(pmo, &t); useMana++; goto axedone; } @@ -260,7 +258,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) pmo->weaponspecial = 0; angle = pmo->angle; - slope = P_AimLineAttack (pmo, angle, MELEERANGE, &linetarget); + slope = P_AimLineAttack (pmo, angle, MELEERANGE); P_LineAttack (pmo, angle, MELEERANGE, slope, damage, NAME_Melee, pufftype, true); axedone: diff --git a/src/g_hexen/a_fighterhammer.cpp b/src/g_hexen/a_fighterhammer.cpp index 2980dec7a..836f6e4b7 100644 --- a/src/g_hexen/a_fighterhammer.cpp +++ b/src/g_hexen/a_fighterhammer.cpp @@ -17,8 +17,6 @@ const fixed_t HAMMER_RANGE = MELEERANGE+MELEERANGE/2; static FRandom pr_hammeratk ("FHammerAtk"); -extern void AdjustPlayerAngle (AActor *pmo, AActor *linetarget); - //============================================================================ // // A_FHammerAttack @@ -35,7 +33,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack) int slope; int i; player_t *player; - AActor *linetarget; + FTranslatedLineTarget t; PClassActor *hammertime; if (NULL == (player = self->player)) @@ -50,32 +48,32 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack) for (i = 0; i < 16; i++) { angle = pmo->angle + i*(ANG45/32); - slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D); - if (linetarget != NULL) + slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &t, 0, ALF_CHECK3D); + if (t.linetarget != NULL) { - P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &linetarget); - if (linetarget != NULL) + P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &t); + if (t.linetarget != NULL) { - AdjustPlayerAngle(pmo, linetarget); - if (linetarget->flags3 & MF3_ISMONSTER || linetarget->player) + AdjustPlayerAngle(pmo, &t); + if (t.linetarget->flags3 & MF3_ISMONSTER || t.linetarget->player) { - P_ThrustMobj(linetarget, angle, power); + P_ThrustMobj(t.linetarget, t.hitangle, power); } pmo->weaponspecial = false; // Don't throw a hammer goto hammerdone; } } angle = pmo->angle-i*(ANG45/32); - slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D); - if (linetarget != NULL) + slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &t, 0, ALF_CHECK3D); + if (t.linetarget != NULL) { - P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &linetarget); - if (linetarget != NULL) + P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &t); + if (t.linetarget != NULL) { - AdjustPlayerAngle(pmo, linetarget); - if (linetarget->flags3 & MF3_ISMONSTER || linetarget->player) + AdjustPlayerAngle(pmo, &t); + if (t.linetarget->flags3 & MF3_ISMONSTER || t.linetarget->player) { - P_ThrustMobj(linetarget, angle, power); + P_ThrustMobj(t.linetarget, t.hitangle, power); } pmo->weaponspecial = false; // Don't throw a hammer goto hammerdone; @@ -84,7 +82,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack) } // didn't find any targets in meleerange, so set to throw out a hammer angle = pmo->angle; - slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D); + slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, NULL, 0, ALF_CHECK3D); if (P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true) != NULL) { pmo->weaponspecial = false; diff --git a/src/g_hexen/a_fighterplayer.cpp b/src/g_hexen/a_fighterplayer.cpp index 944a4aa45..dfbc43be2 100644 --- a/src/g_hexen/a_fighterplayer.cpp +++ b/src/g_hexen/a_fighterplayer.cpp @@ -25,12 +25,12 @@ static FRandom pr_fpatk ("FPunchAttack"); #define MAX_ANGLE_ADJUST (5*ANGLE_1) -void AdjustPlayerAngle (AActor *pmo, AActor *linetarget) +void AdjustPlayerAngle (AActor *pmo, FTranslatedLineTarget *t) { angle_t angle; int difference; - angle = pmo->AngleTo(linetarget); + angle = t->SourceAngleToTarget(); difference = (int)angle - (int)pmo->angle; if (abs(difference) > MAX_ANGLE_ADJUST) { @@ -60,11 +60,11 @@ void AdjustPlayerAngle (AActor *pmo, AActor *linetarget) static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power) { PClassActor *pufftype; - AActor *linetarget; + FTranslatedLineTarget t; int slope; - slope = P_AimLineAttack (pmo, angle, 2*MELEERANGE, &linetarget); - if (linetarget != NULL) + slope = P_AimLineAttack (pmo, angle, 2*MELEERANGE, &t); + if (t.linetarget != NULL) { if (++pmo->weaponspecial >= 3) { @@ -76,15 +76,15 @@ static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power) { pufftype = PClass::FindActor("PunchPuff"); } - P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, pufftype, true, &linetarget); - if (linetarget != NULL) + P_LineAttack (pmo, angle, 2*MELEERANGE, slope, damage, NAME_Melee, pufftype, true, &t); + if (t.linetarget != NULL) { - if (linetarget->player != NULL || - (linetarget->Mass != INT_MAX && (linetarget->flags3 & MF3_ISMONSTER))) + if (t.linetarget->player != NULL || + (t.linetarget->Mass != INT_MAX && (t.linetarget->flags3 & MF3_ISMONSTER))) { - P_ThrustMobj (linetarget, angle, power); + P_ThrustMobj (t.linetarget, t.hitangle, power); } - AdjustPlayerAngle (pmo, linetarget); + AdjustPlayerAngle (pmo, &t); return true; } } @@ -131,8 +131,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) // didn't find any creatures, so try to strike any walls pmo->weaponspecial = 0; - AActor *linetarget; - int slope = P_AimLineAttack (pmo, pmo->angle, MELEERANGE, &linetarget); + int slope = P_AimLineAttack (pmo, pmo->angle, MELEERANGE); P_LineAttack (pmo, pmo->angle, MELEERANGE, slope, damage, NAME_Melee, PClass::FindActor("PunchPuff"), true); return 0; } diff --git a/src/g_hexen/a_hexenglobal.h b/src/g_hexen/a_hexenglobal.h index ba68a9988..94b03d45d 100644 --- a/src/g_hexen/a_hexenglobal.h +++ b/src/g_hexen/a_hexenglobal.h @@ -3,6 +3,8 @@ #include "d_player.h" +void AdjustPlayerAngle(AActor *pmo, FTranslatedLineTarget *t); + class AHolySpirit : public AActor { DECLARE_CLASS (AHolySpirit, AActor) diff --git a/src/g_hexen/a_hexenspecialdecs.cpp b/src/g_hexen/a_hexenspecialdecs.cpp index 86addb2cb..302048998 100644 --- a/src/g_hexen/a_hexenspecialdecs.cpp +++ b/src/g_hexen/a_hexenspecialdecs.cpp @@ -350,7 +350,7 @@ void AZBell::Activate (AActor *activator) { if (health > 0) { - P_DamageMobj (this, activator, activator, 10, NAME_Melee); // 'ring' the bell + P_DamageMobj (this, activator, activator, 10, NAME_Melee, DMG_THRUSTLESS); // 'ring' the bell } } diff --git a/src/g_hexen/a_magecone.cpp b/src/g_hexen/a_magecone.cpp index 154c76524..c157c02c0 100644 --- a/src/g_hexen/a_magecone.cpp +++ b/src/g_hexen/a_magecone.cpp @@ -60,7 +60,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1) AActor *mo; bool conedone=false; player_t *player; - AActor *linetarget; + FTranslatedLineTarget t; if (NULL == (player = self->player)) { @@ -79,10 +79,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1) for (i = 0; i < 16; i++) { angle = self->angle+i*(ANG45/16); - slope = P_AimLineAttack (self, angle, MELEERANGE, &linetarget, 0, ALF_CHECK3D); - if (linetarget) + slope = P_AimLineAttack (self, angle, MELEERANGE, &t, 0, ALF_CHECK3D); + if (t.linetarget) { - P_DamageMobj (linetarget, self, self, damage, NAME_Ice); + P_DamageMobj (t.linetarget, self, self, damage, NAME_Ice, DMG_USEANGLE, t.SourceAngleToTarget()); conedone = true; break; } diff --git a/src/g_hexen/a_magestaff.cpp b/src/g_hexen/a_magestaff.cpp index d1ca7e75c..832ae96d1 100644 --- a/src/g_hexen/a_magestaff.cpp +++ b/src/g_hexen/a_magestaff.cpp @@ -97,17 +97,20 @@ bool AMageStaffFX2::SpecialBlastHandling (AActor *source, fixed_t strength) // //============================================================================ -void MStaffSpawn (AActor *pmo, angle_t angle) +void MStaffSpawn (AActor *pmo, angle_t angle, AActor *alttarget) { AActor *mo; - AActor *linetarget; + FTranslatedLineTarget t; mo = P_SpawnPlayerMissile (pmo, 0, 0, 8*FRACUNIT, - RUNTIME_CLASS(AMageStaffFX2), angle, &linetarget); + RUNTIME_CLASS(AMageStaffFX2), angle, &t); if (mo) { mo->target = pmo; - mo->tracer = linetarget; + if (t.linetarget && !t.unlinked) + mo->tracer = t.linetarget; + else + mo->tracer = alttarget; } } @@ -123,7 +126,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack) angle_t angle; player_t *player; - AActor *linetarget; + FTranslatedLineTarget t; if (NULL == (player = self->player)) { @@ -139,18 +142,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack) angle = self->angle; // [RH] Let's try and actually track what the player aimed at - P_AimLineAttack (self, angle, PLAYERMISSILERANGE, &linetarget, ANGLE_1*32); - if (linetarget == NULL) + P_AimLineAttack (self, angle, PLAYERMISSILERANGE, &t, ANGLE_1*32); + if (t.linetarget == NULL) { BlockCheckLine.x = self->X(); BlockCheckLine.y = self->Y(); BlockCheckLine.dx = -finesine[angle >> ANGLETOFINESHIFT]; BlockCheckLine.dy = -finecosine[angle >> ANGLETOFINESHIFT]; - linetarget = P_BlockmapSearch (self, 10, FrontBlockCheck); + t.linetarget = P_BlockmapSearch (self, 10, FrontBlockCheck); } - MStaffSpawn (self, angle); - MStaffSpawn (self, angle-ANGLE_1*5); - MStaffSpawn (self, angle+ANGLE_1*5); + MStaffSpawn (self, angle, t.linetarget); + MStaffSpawn (self, angle-ANGLE_1*5, t.linetarget); + MStaffSpawn (self, angle+ANGLE_1*5, t.linetarget); S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM); weapon->MStaffCount = 3; return 0; diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index 8ce394a28..b07bfc4a0 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -18,8 +18,6 @@ static FRandom pr_snoutattack ("SnoutAttack"); static FRandom pr_pigattack ("PigAttack"); static FRandom pr_pigplayerthink ("PigPlayerThink"); -extern void AdjustPlayerAngle (AActor *, AActor *); - // Pig player --------------------------------------------------------------- class APigPlayer : public APlayerPawn @@ -67,7 +65,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack) int slope; player_t *player; AActor *puff; - AActor *linetarget; + FTranslatedLineTarget t; if (NULL == (player = self->player)) { @@ -76,12 +74,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack) damage = 3+(pr_snoutattack()&3); angle = player->mo->angle; - slope = P_AimLineAttack(player->mo, angle, MELEERANGE, &linetarget); - puff = P_LineAttack(player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "SnoutPuff", true, &linetarget); + slope = P_AimLineAttack(player->mo, angle, MELEERANGE); + puff = P_LineAttack(player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "SnoutPuff", true, &t); S_Sound(player->mo, CHAN_VOICE, "PigActive", 1, ATTN_NORM); - if(linetarget) + if(t.linetarget) { - AdjustPlayerAngle(player->mo, linetarget); + AdjustPlayerAngle(player->mo, &t); if(puff != NULL) { // Bit something S_Sound(player->mo, CHAN_VOICE, "PigAttack", 1, ATTN_NORM); diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 561f52746..60e86a34b 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -100,7 +100,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_JabDagger) int damage; int pitch; int power; - AActor *linetarget; + FTranslatedLineTarget t; power = MIN(10, self->player->mo->stamina / 10); damage = (pr_jabdagger() % (power + 8)) * (power + 2); @@ -111,18 +111,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_JabDagger) } angle = self->angle + (pr_jabdagger.Random2() << 18); - pitch = P_AimLineAttack (self, angle, 80*FRACUNIT, &linetarget); - P_LineAttack (self, angle, 80*FRACUNIT, pitch, damage, NAME_Melee, "StrifeSpark", true, &linetarget); + pitch = P_AimLineAttack (self, angle, 80*FRACUNIT); + P_LineAttack (self, angle, 80*FRACUNIT, pitch, damage, NAME_Melee, "StrifeSpark", true, &t); // turn to face target - if (linetarget) + if (t.linetarget) { S_Sound (self, CHAN_WEAPON, - linetarget->flags & MF_NOBLOOD ? "misc/metalhit" : "misc/meathit", + t.linetarget->flags & MF_NOBLOOD ? "misc/metalhit" : "misc/meathit", 1, ATTN_NORM); - self->angle = self->AngleTo(linetarget); + self->angle = t.SourceAngleToTarget(); self->flags |= MF_JUSTATTACKED; - P_DaggerAlert (self, linetarget); + P_DaggerAlert (self, t.linetarget); } else { @@ -978,7 +978,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil1) AActor *spot; player_t *player = self->player; - AActor *linetarget; + FTranslatedLineTarget t; if (player == NULL || player->ReadyWeapon == NULL) return 0; @@ -986,13 +986,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil1) P_DamageMobj (self, self, NULL, 1*4, 0, DMG_NO_ARMOR); S_Sound (self, CHAN_WEAPON, "weapons/sigilcharge", 1, ATTN_NORM); - P_BulletSlope (self, &linetarget); - if (linetarget != NULL) + P_BulletSlope (self, &t, ALF_PORTALRESTRICT); + if (t.linetarget != NULL) { - spot = Spawn("SpectralLightningSpot", linetarget->X(), linetarget->Y(), linetarget->floorz, ALLOW_REPLACE); + spot = Spawn("SpectralLightningSpot", t.linetarget->X(), t.linetarget->Y(), t.linetarget->floorz, ALLOW_REPLACE); if (spot != NULL) { - spot->tracer = linetarget; + spot->tracer = t.linetarget; } } else @@ -1080,7 +1080,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil4) AActor *spot; player_t *player = self->player; - AActor *linetarget; + FTranslatedLineTarget t; if (player == NULL || player->ReadyWeapon == NULL) return 0; @@ -1088,13 +1088,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil4) P_DamageMobj (self, self, NULL, 4*4, 0, DMG_NO_ARMOR); S_Sound (self, CHAN_WEAPON, "weapons/sigilcharge", 1, ATTN_NORM); - P_BulletSlope (self, &linetarget); - if (linetarget != NULL) + P_BulletSlope (self, &t, ALF_PORTALRESTRICT); + if (t.linetarget != NULL) { - spot = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("SpectralLightningBigV1"), self->angle, &linetarget); + spot = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("SpectralLightningBigV1"), self->angle, &t, NULL, false, false, ALF_PORTALRESTRICT); if (spot != NULL) { - spot->tracer = linetarget; + spot->tracer = t.linetarget; } } else diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 52e11ee8b..b6a718f65 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4939,7 +4939,9 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) { if (actor->player != NULL && actor->player->playerstate == PST_LIVE) { - P_BulletSlope(actor, &actor); + FTranslatedLineTarget t; + P_BulletSlope(actor, &t, ALF_PORTALRESTRICT); + actor = t.linetarget; } else { diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 0e8c7d6ff..af4a9042d 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -425,16 +425,16 @@ bool AActor::SuggestMissileAttack (fixed_t dist) bool P_HitFriend(AActor * self) { - AActor *linetarget; + FTranslatedLineTarget t; if (self->flags&MF_FRIENDLY && self->target != NULL) { angle_t angle = self->AngleTo(self->target); fixed_t dist = self->AproxDistance (self->target); - P_AimLineAttack (self, angle, dist, &linetarget, 0, true); - if (linetarget != NULL && linetarget != self->target) + P_AimLineAttack (self, angle, dist, &t, 0, true); + if (t.linetarget != NULL && t.linetarget != self->target) { - return self->IsFriend (linetarget); + return self->IsFriend (t.linetarget); } } return false; @@ -2990,7 +2990,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail) return 0; fixed_t saved_pitch = self->pitch; - AActor *linetarget; + FTranslatedLineTarget t; // [RH] Andy Baker's stealth monsters if (self->flags & MF_STEALTH) @@ -3002,8 +3002,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail) self->angle = self->AngleTo(self->target); - self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &linetarget, ANGLE_1*60, 0, self->target); - if (linetarget == NULL) + self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &t, ANGLE_1*60, 0, self->target); + if (t.linetarget == NULL) { // We probably won't hit the target, but aim at it anyway so we don't look stupid. fixedvec2 pos = self->Vec2To(self->target); diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 98d08832e..313531425 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -927,7 +927,7 @@ static inline bool isFakePain(AActor *target, AActor *inflictor, int damage) // Returns the amount of damage actually inflicted upon the target, or -1 if // the damage was cancelled. -int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags) +int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, angle_t angle) { unsigned ang; player_t *player = NULL; @@ -1151,11 +1151,15 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, { AActor *origin = (source && (flags & DMG_INFLICTOR_IS_PUFF))? source : inflictor; - // If the origin and target are in exactly the same spot, choose a random direction. - // (Most likely cause is from telefragging somebody during spawning because they - // haven't moved from their spawn spot at all.) - if (origin->X() == target->X() && origin->Y() == target->Y()) + if (flags & DMG_USEANGLE) { + ang = angle; + } + else if (origin->X() == target->X() && origin->Y() == target->Y()) + { + // If the origin and target are in exactly the same spot, choose a random direction. + // (Most likely cause is from telefragging somebody during spawning because they + // haven't moved from their spawn spot at all.) ang = pr_kickbackdir.GenRand32(); } else diff --git a/src/p_local.h b/src/p_local.h index 7e11010c5..75ee1e695 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -37,6 +37,7 @@ struct sector_t; struct msecnode_t; struct secplane_t; struct FCheckPosition; +struct FTranslatedLineTarget; #include @@ -173,7 +174,7 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassAct AActor *P_SpawnPlayerMissile (AActor* source, PClassActor *type); AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, angle_t angle); AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, PClassActor *type, angle_t angle, - AActor **pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false, bool noautoaim = false); + FTranslatedLineTarget *pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false, bool noautoaim = false, int aimflags = 0); void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheight=false); @@ -304,7 +305,7 @@ void P_FindFloorCeiling (AActor *actor, int flags=0); bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset); -fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget = NULL, fixed_t vrange=0, int flags = 0, AActor *target=NULL, AActor *friender=NULL); +fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, FTranslatedLineTarget *pLineTarget = NULL, fixed_t vrange=0, int flags = 0, AActor *target=NULL, AActor *friender=NULL); enum // P_AimLineAttack flags { @@ -313,6 +314,7 @@ enum // P_AimLineAttack flags ALF_CHECKNONSHOOTABLE = 4, ALF_CHECKCONVERSATION = 8, ALF_NOFRIENDS = 16, + ALF_PORTALRESTRICT = 32, // only work through portals with a global offset (to be used for stuff that cannot remember the calculated FTranslatedLineTarget info) }; enum // P_LineAttack flags @@ -322,11 +324,12 @@ enum // P_LineAttack flags LAF_NOIMPACTDECAL = 4 }; -AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL); -AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL); +AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); +AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch); void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch); void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version +void P_TraceBleed(int damage, FTranslatedLineTarget *t, AActor *puff); // hitscan version void P_TraceBleed (int damage, AActor *target); // random direction version bool P_HitFloor (AActor *thing); bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false, bool alert = true, bool force = false); @@ -382,7 +385,7 @@ extern BYTE* rejectmatrix; // for fast sight rejection // P_INTER // void P_TouchSpecialThing (AActor *special, AActor *toucher); -int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0); +int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0, angle_t angle = 0); void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period, FName type); bool P_GiveBody (AActor *actor, int num, int max=0); bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poison); @@ -399,6 +402,7 @@ enum EDmgFlags DMG_FOILINVUL = 64, DMG_FOILBUDDHA = 128, DMG_NO_PROTECT = 256, + DMG_USEANGLE = 512, }; diff --git a/src/p_map.cpp b/src/p_map.cpp index 1a4a18d74..150348fc3 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3787,7 +3787,7 @@ void aim_t::AimTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t en // //============================================================================ -fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget, fixed_t vrange, +fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslatedLineTarget *pLineTarget, fixed_t vrange, int flags, AActor *target, AActor *friender) { fixed_t x2; @@ -3881,7 +3881,18 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, AActor **pL } if (pLineTarget) { - *pLineTarget = aim.linetarget; + if (aim.linetarget) + { + pLineTarget->linetarget = aim.linetarget; + pLineTarget->hitangle = angle; + pLineTarget->targetPosFromSrc = aim.linetarget->Pos(); + pLineTarget->targetAngleFromSrc = aim.linetarget->angle; + pLineTarget->sourcePosFromTarget = t1->Pos(); + pLineTarget->sourceAngleFromTarget = t1->angle; + pLineTarget->unlinked = false; + } + else + memset(pLineTarget, 0, sizeof(*pLineTarget)); } return aim.linetarget ? aim.aimpitch : t1->pitch; } @@ -3936,7 +3947,7 @@ static ETraceStatus CheckForActor(FTraceResults &res, void *userdata) //========================================================================== AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, - int pitch, int damage, FName damageType, PClassActor *pufftype, int flags, AActor **victim, int *actualdamage) + int pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage) { fixed_t vx, vy, vz, shootz; FTraceResults trace; @@ -3953,7 +3964,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, if (victim != NULL) { - *victim = NULL; + memset(victim, 0, sizeof(*victim)); } if (actualdamage != NULL) { @@ -4136,6 +4147,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING | PF_TEMPORARY); killPuff = true; } +#pragma message("damage angle") newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags); if (actualdamage != NULL) { @@ -4175,7 +4187,13 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, } if (victim != NULL) { - *victim = trace.Actor; + victim->linetarget = trace.Actor; + victim->hitangle = angle; + victim->targetPosFromSrc = trace.Actor->Pos(); + victim->targetAngleFromSrc = trace.Actor->angle; + victim->sourcePosFromTarget = t1->Pos(); + victim->sourceAngleFromTarget = t1->angle; + victim->unlinked = false; } } if (trace.Crossed3DWater || trace.CrossedWater) @@ -4198,22 +4216,22 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, } AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, - int pitch, int damage, FName damageType, FName pufftype, int flags, AActor **victim, int *actualdamage) + int pitch, int damage, FName damageType, FName pufftype, int flags, FTranslatedLineTarget *victim, int *actualdamage) { PClassActor *type = PClass::FindActor(pufftype); - if (victim != NULL) - { - *victim = NULL; - } if (type == NULL) { + if (victim != NULL) + { + memset(victim, 0, sizeof(*victim)); + } Printf("Attempt to spawn unknown actor type '%s'\n", pufftype.GetChars()); + return NULL; } else { return P_LineAttack(t1, angle, distance, pitch, damage, damageType, type, flags, victim, actualdamage); } - return NULL; } //========================================================================== @@ -4395,6 +4413,24 @@ void P_TraceBleed(int damage, AActor *target, AActor *missile) // //========================================================================== +void P_TraceBleed(int damage, FTranslatedLineTarget *t, AActor *puff) +{ + if (t->linetarget == NULL || puff->flags3 & MF3_BLOODLESSIMPACT) + { + return; + } + + fixed_t randpitch = (pr_tracebleed() - 128) << 16; + P_TraceBleed(damage, t->linetarget->X(), t->linetarget->Y(), t->linetarget->Z() + t->linetarget->height / 2, + t->linetarget, t->SourceAngleToTarget(), 0); +} + +//========================================================================== +// +// +// +//========================================================================== + void P_TraceBleed(int damage, AActor *target) { if (target != NULL) @@ -4573,6 +4609,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i if (puffDefaults->flags3 & MF3_FOILINVUL) dmgFlagPass |= DMG_FOILINVUL; if (puffDefaults->flags7 & MF7_FOILBUDDHA) dmgFlagPass |= DMG_FOILBUDDHA; } +#pragma message("damage angle") int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, dmgFlagPass); if (bleed) @@ -4690,38 +4727,26 @@ void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &Camera bool P_TalkFacing(AActor *player) { - AActor *linetarget; + static const int angleofs[] = { 0, ANGLE_90 >> 4, - ANGLE_90 >> 4 }; + FTranslatedLineTarget t; - P_AimLineAttack(player, player->angle, TALKRANGE, &linetarget, ANGLE_1 * 35, ALF_FORCENOSMART | ALF_CHECKCONVERSATION); - if (linetarget == NULL) + for (int angle : angleofs) { - P_AimLineAttack(player, player->angle + (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1 * 35, ALF_FORCENOSMART | ALF_CHECKCONVERSATION); - if (linetarget == NULL) + P_AimLineAttack(player, player->angle + angle, TALKRANGE, &t, ANGLE_1 * 35, ALF_FORCENOSMART | ALF_CHECKCONVERSATION | ALF_PORTALRESTRICT); + if (t.linetarget != NULL) { - P_AimLineAttack(player, player->angle - (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1 * 35, ALF_FORCENOSMART | ALF_CHECKCONVERSATION); - if (linetarget == NULL) + if (t.linetarget->health > 0 && // Dead things can't talk. + t.linetarget->flags4 & MF4_INCOMBAT && // Fighting things don't talk either. + t.linetarget->Conversation != NULL) { - return false; + // Give the NPC a chance to play a brief animation + t.linetarget->ConversationAnimation(0); + P_StartConversation(t.linetarget, player, true, true); + return true; } + return false; } } - // Dead things can't talk. - if (linetarget->health <= 0) - { - return false; - } - // Fighting things don't talk either. - if (linetarget->flags4 & MF4_INCOMBAT) - { - return false; - } - if (linetarget->Conversation != NULL) - { - // Give the NPC a chance to play a brief animation - linetarget->ConversationAnimation(0); - P_StartConversation(linetarget, player, true, true); - return true; - } return false; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index f03362ab5..fbceb5d3f 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6164,13 +6164,13 @@ AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, angle_t angle) } AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, - PClassActor *type, angle_t angle, AActor **pLineTarget, AActor **pMissileActor, - bool nofreeaim, bool noautoaim) + PClassActor *type, angle_t angle, FTranslatedLineTarget *pLineTarget, AActor **pMissileActor, + bool nofreeaim, bool noautoaim, int aimflags) { static const int angdiff[3] = { -(1<<26), 1<<26, 0 }; angle_t an = angle; angle_t pitch; - AActor *linetarget; + FTranslatedLineTarget scratch; AActor *defaultobject = GetDefaultByType(type); int vrange = nofreeaim ? ANGLE_1*35 : 0; @@ -6178,12 +6178,13 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, { return NULL; } + if (!pLineTarget) pLineTarget = &scratch; if (source->player && source->player->ReadyWeapon && ((source->player->ReadyWeapon->WeaponFlags & WIF_NOAUTOAIM) || noautoaim)) { // Keep exactly the same angle and pitch as the player's own aim an = angle; pitch = source->pitch; - linetarget = NULL; + pLineTarget->linetarget = NULL; } else // see which target is to be aimed at { @@ -6196,7 +6197,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, do { an = angle + angdiff[i]; - pitch = P_AimLineAttack (source, an, linetargetrange, &linetarget, vrange); + pitch = P_AimLineAttack (source, an, linetargetrange, pLineTarget, vrange, aimflags); if (source->player != NULL && !nofreeaim && @@ -6205,9 +6206,9 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, { break; } - } while (linetarget == NULL && --i >= 0); + } while (pLineTarget->linetarget == NULL && --i >= 0); - if (linetarget == NULL) + if (pLineTarget->linetarget == NULL) { an = angle; if (nofreeaim || !level.IsFreelookAllowed()) @@ -6216,7 +6217,6 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, } } } - if (pLineTarget) *pLineTarget = linetarget; if (z != ONFLOORZ && z != ONCEILINGZ) { diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index ec6c38f77..2f2af36c3 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -919,20 +919,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_GunFlash) // the height of the intended target // -angle_t P_BulletSlope (AActor *mo, AActor **pLineTarget) +angle_t P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget, int aimflags) { static const int angdiff[3] = { -(1<<26), 1<<26, 0 }; int i; angle_t an; angle_t pitch; - AActor *linetarget; + FTranslatedLineTarget scratch; + if (pLineTarget == NULL) pLineTarget = &scratch; // see which target is to be aimed at i = 2; do { an = mo->angle + angdiff[i]; - pitch = P_AimLineAttack (mo, an, 16*64*FRACUNIT, &linetarget); + pitch = P_AimLineAttack (mo, an, 16*64*FRACUNIT, pLineTarget, 0, aimflags); if (mo->player != NULL && level.IsFreelookAllowed() && @@ -940,11 +941,8 @@ angle_t P_BulletSlope (AActor *mo, AActor **pLineTarget) { break; } - } while (linetarget == NULL && --i >= 0); - if (pLineTarget != NULL) - { - *pLineTarget = linetarget; - } + } while (pLineTarget->linetarget == NULL && --i >= 0); + return pitch; } diff --git a/src/p_pspr.h b/src/p_pspr.h index a9eec48b6..8fb6d455b 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -88,7 +88,7 @@ void P_BringUpWeapon (player_t *player); void P_FireWeapon (player_t *player); void P_DropWeapon (player_t *player); void P_BobWeapon (player_t *player, pspdef_t *psp, fixed_t *x, fixed_t *y); -angle_t P_BulletSlope (AActor *mo, AActor **pLineTarget = NULL); +angle_t P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget = NULL, int aimflags = 0); void P_GunShot (AActor *mo, bool accurate, PClassActor *pufftype, angle_t pitch); void DoReadyWeapon(AActor *self); diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 19c34cd4f..c1724c2c5 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -960,7 +960,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfCloser) else { // Does the player aim at something that can be shot? - P_BulletSlope(self, &target); + FTranslatedLineTarget t; + P_BulletSlope(self, &t, ALF_PORTALRESTRICT); + target = t.linetarget; } return DoJumpIfCloser(target, VM_ARGS_NAMES); } @@ -1637,7 +1639,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) player_t *player = self->player; AWeapon *weapon = player->ReadyWeapon; - AActor *linetarget; + FTranslatedLineTarget t; // Only use ammo if called from a weapon if (useammo && ACTION_CALL_FROM_WEAPON() && weapon) @@ -1659,7 +1661,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) // Temporarily adjusts the pitch fixed_t saved_player_pitch = self->pitch; self->pitch -= pitch; - AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &linetarget, NULL, false, (flags & FPF_NOAUTOAIM) != 0); + AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &t, NULL, false, (flags & FPF_NOAUTOAIM) != 0); self->pitch = saved_player_pitch; // automatic handling of seeker missiles @@ -1667,8 +1669,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) { if (flags & FPF_TRANSFERTRANSLATION) misl->Translation = self->Translation; - if (linetarget && (misl->flags2 & MF2_SEEKERMISSILE)) - misl->tracer = linetarget; + if (t.linetarget && !t.unlinked && (misl->flags2 & MF2_SEEKERMISSILE)) + misl->tracer = t.linetarget; if (!(flags & FPF_AIMATANGLE)) { // This original implementation is to aim straight ahead and then offset @@ -1727,7 +1729,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) angle_t angle; int pitch; - AActor * linetarget; + FTranslatedLineTarget t; int actualdamage; if (!norandom) @@ -1736,10 +1738,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) angle = self->angle + (pr_cwpunch.Random2() << 18); if (range == 0) range = MELEERANGE; - pitch = P_AimLineAttack (self, angle, range, &linetarget); + pitch = P_AimLineAttack (self, angle, range, &t); // only use ammo when actually hitting something! - if ((flags & CPF_USEAMMO) && linetarget && weapon && ACTION_CALL_FROM_WEAPON()) + if ((flags & CPF_USEAMMO) && t.linetarget && weapon && ACTION_CALL_FROM_WEAPON()) { if (!weapon->DepleteAmmo(weapon->bAltFire, true)) return 0; // out of ammo @@ -1749,15 +1751,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) pufftype = PClass::FindActor(NAME_BulletPuff); int puffFlags = LAF_ISMELEEATTACK | ((flags & CPF_NORANDOMPUFFZ) ? LAF_NORANDOMPUFFZ : 0); - P_LineAttack (self, angle, range, pitch, damage, NAME_Melee, pufftype, puffFlags, &linetarget, &actualdamage); + P_LineAttack (self, angle, range, pitch, damage, NAME_Melee, pufftype, puffFlags, &t, &actualdamage); - if (!linetarget) + if (!t.linetarget) { if (MissSound) S_Sound(self, CHAN_WEAPON, MissSound, 1, ATTN_NORM); } else { - if (lifesteal && !(linetarget->flags5 & MF5_DONTDRAIN)) + if (lifesteal && !(t.linetarget->flags5 & MF5_DONTDRAIN)) { if (flags & CPF_STEALARMOR) { @@ -1794,11 +1796,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) if (!(flags & CPF_NOTURN)) { // turn to face target - self->angle = self->AngleTo(linetarget); + self->angle = t.SourceAngleToTarget(); } if (flags & CPF_PULLIN) self->flags |= MF_JUSTATTACKED; - if (flags & CPF_DAGGER) P_DaggerAlert (self, linetarget); + if (flags & CPF_DAGGER) P_DaggerAlert (self, t.linetarget); } return 0; } @@ -1900,7 +1902,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) if (range == 0) range = 8192*FRACUNIT; if (sparsity == 0) sparsity = 1; - AActor *linetarget; + FTranslatedLineTarget t; fixedvec3 savedpos = self->Pos(); angle_t saved_angle = self->angle; @@ -1923,8 +1925,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) { self->angle = self->AngleTo(self->target); } - self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &linetarget, ANGLE_1*60, 0, aim ? self->target : NULL); - if (linetarget == NULL && aim) + self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &t, ANGLE_1*60, 0, aim ? self->target : NULL); + if (t.linetarget == NULL && aim) { // We probably won't hit the target, but aim at it anyway so we don't look stupid. fixedvec2 pos = self->Vec2To(self->target); @@ -3929,6 +3931,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) angle_t an; AActor *target, *viewport; + FTranslatedLineTarget t; bool doCheckSight; @@ -3964,12 +3967,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) else { // Does the player aim at something that can be shot? - P_AimLineAttack(self, self->angle, MISSILERANGE, &target, (flags & JLOSF_NOAUTOAIM) ? ANGLE_1/2 : 0); + P_AimLineAttack(self, self->angle, MISSILERANGE, &t, (flags & JLOSF_NOAUTOAIM) ? ANGLE_1/2 : 0, ALF_PORTALRESTRICT); - if (!target) + if (!t.linetarget) { ACTION_RETURN_STATE(NULL); } + target = t.linetarget; switch (flags & (JLOSF_TARGETLOS|JLOSF_FLIPFOV)) {