From b4a002a07fa6d6c95d7cb5201f46e5665edbc450 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 1 Mar 2016 16:38:45 +0100 Subject: [PATCH] - preparations for allowing hitscans through portals. To allow processing the hit through an arbitrary portal without reference to the portal group table, P_AimLineAttack and P_LineAttack need to pass some more info than just the linetarget. We need the relative positions of shooter and target within the visual reference of the other to calculate proper angles and we need to know if such a portal was crossed at all, because a few things, e.g. seeker missiles won't work with them. - fixed setup of target acquisition for the Mage Staff. The pre-acquired seeker target was never passed to the spawned projectiles. --- src/actor.h | 22 +++++++ src/actorptrselect.cpp | 18 +++--- src/c_cmds.cpp | 26 ++++---- src/g_doom/a_doomweaps.cpp | 38 ++++++------ src/g_doom/a_scriptedmarine.cpp | 21 +++---- src/g_heretic/a_chicken.cpp | 20 +++--- src/g_heretic/a_hereticweaps.cpp | 48 +++++++-------- src/g_hexen/a_clericholy.cpp | 8 +-- src/g_hexen/a_clericmace.cpp | 16 +++-- src/g_hexen/a_clericstaff.cpp | 16 ++--- src/g_hexen/a_fighteraxe.cpp | 20 +++--- src/g_hexen/a_fighterhammer.cpp | 34 +++++------ src/g_hexen/a_fighterplayer.cpp | 25 ++++---- src/g_hexen/a_hexenglobal.h | 2 + src/g_hexen/a_hexenspecialdecs.cpp | 2 +- src/g_hexen/a_magecone.cpp | 8 +-- src/g_hexen/a_magestaff.cpp | 25 ++++---- src/g_hexen/a_pig.cpp | 12 ++-- src/g_strife/a_strifeweapons.cpp | 34 +++++------ src/p_acs.cpp | 4 +- src/p_enemy.cpp | 14 ++--- src/p_interaction.cpp | 14 +++-- src/p_local.h | 14 +++-- src/p_map.cpp | 97 +++++++++++++++++++----------- src/p_mobj.cpp | 16 ++--- src/p_pspr.cpp | 14 ++--- src/p_pspr.h | 2 +- src/thingdef/thingdef_codeptr.cpp | 40 ++++++------ 28 files changed, 331 insertions(+), 279 deletions(-) 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)) {