mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
- 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.
This commit is contained in:
parent
a16f92c508
commit
b4a002a07f
28 changed files with 331 additions and 279 deletions
22
src/actor.h
22
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__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<fixed_t>(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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "d_player.h"
|
||||
|
||||
void AdjustPlayerAngle(AActor *pmo, FTranslatedLineTarget *t);
|
||||
|
||||
class AHolySpirit : public AActor
|
||||
{
|
||||
DECLARE_CLASS (AHolySpirit, AActor)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 (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.)
|
||||
if (origin->X() == target->X() && origin->Y() == target->Y())
|
||||
{
|
||||
ang = pr_kickbackdir.GenRand32();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -37,6 +37,7 @@ struct sector_t;
|
|||
struct msecnode_t;
|
||||
struct secplane_t;
|
||||
struct FCheckPosition;
|
||||
struct FTranslatedLineTarget;
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,40 +4727,28 @@ 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)
|
||||
{
|
||||
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)
|
||||
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)
|
||||
{
|
||||
// Give the NPC a chance to play a brief animation
|
||||
linetarget->ConversationAnimation(0);
|
||||
P_StartConversation(linetarget, player, true, true);
|
||||
t.linetarget->ConversationAnimation(0);
|
||||
P_StartConversation(t.linetarget, player, true, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue