mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- Added ang_offset and pitch_offset to A_Face, along with 4 new flags:
- ang_offset: the extra angle to apply to the actor after calculating the maximum turn. - pitch_offset: Just like ang_offset, with pitch instead. - FAF_BOTTOM: Aim straight for the actor's z coordinate, not with +32 units. - FAF_MIDDLE: Aims for the direct middle of the actor. - FAF_TOP: Aims for the very top of the actor. - FAF_NODISTFACTOR: Use the raw pitch offset without calculating it into the distance of the aimed actor.
This commit is contained in:
parent
b69edbbec1
commit
53fd57d6b7
4 changed files with 69 additions and 27 deletions
|
@ -2721,7 +2721,14 @@ void A_Chase(AActor *self)
|
||||||
// A_FaceTracer
|
// A_FaceTracer
|
||||||
//
|
//
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch)
|
enum FAF_Flags
|
||||||
|
{
|
||||||
|
FAF_BOTTOM = 1,
|
||||||
|
FAF_MIDDLE = 2,
|
||||||
|
FAF_TOP = 4,
|
||||||
|
FAF_NODISTFACTOR = 8,
|
||||||
|
};
|
||||||
|
void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch, angle_t ang_offset, angle_t pitch_offset, int flags)
|
||||||
{
|
{
|
||||||
if (!other)
|
if (!other)
|
||||||
return;
|
return;
|
||||||
|
@ -2744,28 +2751,28 @@ void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch)
|
||||||
{
|
{
|
||||||
if (self->angle - other_angle < ANGLE_180)
|
if (self->angle - other_angle < ANGLE_180)
|
||||||
{
|
{
|
||||||
self->angle -= max_turn;
|
self->angle -= max_turn + ang_offset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self->angle += max_turn;
|
self->angle += max_turn + ang_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (other_angle - self->angle < ANGLE_180)
|
if (other_angle - self->angle < ANGLE_180)
|
||||||
{
|
{
|
||||||
self->angle += max_turn;
|
self->angle += max_turn + ang_offset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self->angle -= max_turn;
|
self->angle -= max_turn + ang_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self->angle = other_angle;
|
self->angle = other_angle + ang_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [DH] Now set pitch. In order to maintain compatibility, this can be
|
// [DH] Now set pitch. In order to maintain compatibility, this can be
|
||||||
|
@ -2776,20 +2783,33 @@ void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch)
|
||||||
// result is only used in a ratio.
|
// result is only used in a ratio.
|
||||||
double dist_x = other->x - self->x;
|
double dist_x = other->x - self->x;
|
||||||
double dist_y = other->y - self->y;
|
double dist_y = other->y - self->y;
|
||||||
|
|
||||||
// Positioning ala missile spawning, 32 units above foot level
|
// Positioning ala missile spawning, 32 units above foot level
|
||||||
fixed_t source_z = self->z + 32*FRACUNIT + self->GetBobOffset();
|
fixed_t source_z = self->z + 32*FRACUNIT + self->GetBobOffset();
|
||||||
fixed_t target_z = other->z + 32*FRACUNIT + other->GetBobOffset();
|
fixed_t target_z = other->z + 32*FRACUNIT + other->GetBobOffset();
|
||||||
|
|
||||||
// If the target z is above the target's head, reposition to the middle of
|
// If the target z is above the target's head, reposition to the middle of
|
||||||
// its body.
|
// its body.
|
||||||
if (target_z >= other->z + other->height)
|
if (target_z >= other->z + other->height)
|
||||||
{
|
{
|
||||||
target_z = other->z + other->height / 2;
|
target_z = other->z + (other->height / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Note there is no +32*FRACUNIT on purpose. This is for customization sake.
|
||||||
|
//If one doesn't want this behavior, just don't use FAF_BOTTOM.
|
||||||
|
if (flags & FAF_BOTTOM)
|
||||||
|
target_z = other->z + other->GetBobOffset();
|
||||||
|
if (flags & FAF_MIDDLE)
|
||||||
|
target_z = other->z + (other->height / 2) + other->GetBobOffset();
|
||||||
|
if (flags & FAF_TOP)
|
||||||
|
target_z = other->z + (other->height) + other->GetBobOffset();
|
||||||
|
if (!flags & FAF_NODISTFACTOR)
|
||||||
|
target_z += pitch_offset;
|
||||||
|
|
||||||
double dist_z = target_z - source_z;
|
double dist_z = target_z - source_z;
|
||||||
double dist = sqrt(dist_x*dist_x + dist_y*dist_y + dist_z*dist_z);
|
double dist = sqrt(dist_x*dist_x + dist_y*dist_y + dist_z*dist_z);
|
||||||
|
|
||||||
int other_pitch = (int)rad2bam(asin(dist_z / dist));
|
int other_pitch = (int)rad2bam(asin(dist_z / dist));
|
||||||
|
|
||||||
if (max_pitch != 0)
|
if (max_pitch != 0)
|
||||||
{
|
{
|
||||||
if (self->pitch > other_pitch)
|
if (self->pitch > other_pitch)
|
||||||
|
@ -2807,7 +2827,11 @@ void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch)
|
||||||
{
|
{
|
||||||
self->pitch = other_pitch;
|
self->pitch = other_pitch;
|
||||||
}
|
}
|
||||||
|
if (flags & FAF_NODISTFACTOR)
|
||||||
|
self->pitch += pitch_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This will never work well if the turn angle is limited.
|
// This will never work well if the turn angle is limited.
|
||||||
if (max_turn == 0 && (self->angle == other_angle) && other->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE) )
|
if (max_turn == 0 && (self->angle == other_angle) && other->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE) )
|
||||||
|
@ -2816,46 +2840,55 @@ void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void A_FaceTarget (AActor *self, angle_t max_turn, angle_t max_pitch)
|
void A_FaceTarget(AActor *self, angle_t max_turn, angle_t max_pitch, angle_t ang_offset, angle_t pitch_offset, int flags)
|
||||||
{
|
{
|
||||||
A_Face(self, self->target, max_turn, max_pitch);
|
A_Face(self, self->target, max_turn, max_pitch, ang_offset, pitch_offset, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void A_FaceMaster (AActor *self, angle_t max_turn, angle_t max_pitch)
|
void A_FaceMaster(AActor *self, angle_t max_turn, angle_t max_pitch, angle_t ang_offset, angle_t pitch_offset, int flags)
|
||||||
{
|
{
|
||||||
A_Face(self, self->master, max_turn, max_pitch);
|
A_Face(self, self->master, max_turn, max_pitch, ang_offset, pitch_offset, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void A_FaceTracer (AActor *self, angle_t max_turn, angle_t max_pitch)
|
void A_FaceTracer(AActor *self, angle_t max_turn, angle_t max_pitch, angle_t ang_offset, angle_t pitch_offset, int flags)
|
||||||
{
|
{
|
||||||
A_Face(self, self->tracer, max_turn, max_pitch);
|
A_Face(self, self->tracer, max_turn, max_pitch, ang_offset, pitch_offset, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTarget)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTarget)
|
||||||
{
|
{
|
||||||
ACTION_PARAM_START(2);
|
ACTION_PARAM_START(5);
|
||||||
ACTION_PARAM_ANGLE(max_turn, 0);
|
ACTION_PARAM_ANGLE(max_turn, 0);
|
||||||
ACTION_PARAM_ANGLE(max_pitch, 1);
|
ACTION_PARAM_ANGLE(max_pitch, 1);
|
||||||
|
ACTION_PARAM_ANGLE(ang_offset, 2);
|
||||||
|
ACTION_PARAM_ANGLE(pitch_offset, 3);
|
||||||
|
ACTION_PARAM_INT(flags, 4);
|
||||||
|
|
||||||
A_FaceTarget(self, max_turn, max_pitch);
|
A_FaceTarget(self, max_turn, max_pitch, ang_offset, pitch_offset, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMaster)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMaster)
|
||||||
{
|
{
|
||||||
ACTION_PARAM_START(2);
|
ACTION_PARAM_START(5);
|
||||||
ACTION_PARAM_ANGLE(max_turn, 0);
|
ACTION_PARAM_ANGLE(max_turn, 0);
|
||||||
ACTION_PARAM_ANGLE(max_pitch, 1);
|
ACTION_PARAM_ANGLE(max_pitch, 1);
|
||||||
|
ACTION_PARAM_ANGLE(ang_offset, 2);
|
||||||
|
ACTION_PARAM_ANGLE(pitch_offset, 3);
|
||||||
|
ACTION_PARAM_INT(flags, 4);
|
||||||
|
|
||||||
A_FaceMaster(self, max_turn, max_pitch);
|
A_FaceMaster(self, max_turn, max_pitch, ang_offset, pitch_offset, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTracer)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTracer)
|
||||||
{
|
{
|
||||||
ACTION_PARAM_START(2);
|
ACTION_PARAM_START(5);
|
||||||
ACTION_PARAM_ANGLE(max_turn, 0);
|
ACTION_PARAM_ANGLE(max_turn, 0);
|
||||||
ACTION_PARAM_ANGLE(max_pitch, 1);
|
ACTION_PARAM_ANGLE(max_pitch, 1);
|
||||||
|
ACTION_PARAM_ANGLE(ang_offset, 2);
|
||||||
|
ACTION_PARAM_ANGLE(pitch_offset, 3);
|
||||||
|
ACTION_PARAM_INT(flags, 4);
|
||||||
|
|
||||||
A_FaceTracer(self, max_turn, max_pitch);
|
A_FaceTracer(self, max_turn, max_pitch, ang_offset, pitch_offset, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -72,8 +72,8 @@ DECLARE_ACTION(A_FreezeDeathChunks)
|
||||||
DECLARE_ACTION(A_BossDeath)
|
DECLARE_ACTION(A_BossDeath)
|
||||||
|
|
||||||
void A_Chase(AActor *self);
|
void A_Chase(AActor *self);
|
||||||
void A_FaceTarget(AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270);
|
void A_FaceTarget(AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0);
|
||||||
void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270);
|
void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0);
|
||||||
|
|
||||||
bool A_RaiseMobj (AActor *, fixed_t speed);
|
bool A_RaiseMobj (AActor *, fixed_t speed);
|
||||||
bool A_SinkMobj (AActor *, fixed_t speed);
|
bool A_SinkMobj (AActor *, fixed_t speed);
|
||||||
|
|
|
@ -82,9 +82,9 @@ ACTOR Actor native //: Thinker
|
||||||
action native A_XScream();
|
action native A_XScream();
|
||||||
action native A_Look();
|
action native A_Look();
|
||||||
action native A_Chase(state melee = "*", state missile = "none", int flags = 0);
|
action native A_Chase(state melee = "*", state missile = "none", int flags = 0);
|
||||||
action native A_FaceTarget(float max_turn = 0, float max_pitch = 270);
|
action native A_FaceTarget(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0);
|
||||||
action native A_FaceTracer(float max_turn = 0, float max_pitch = 270);
|
action native A_FaceTracer(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0);
|
||||||
action native A_FaceMaster(float max_turn = 0, float max_pitch = 270);
|
action native A_FaceMaster(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0);
|
||||||
action native A_PosAttack();
|
action native A_PosAttack();
|
||||||
action native A_Scream();
|
action native A_Scream();
|
||||||
action native A_SPosAttack();
|
action native A_SPosAttack();
|
||||||
|
|
|
@ -447,6 +447,15 @@ enum
|
||||||
FTF_CLAMP = 1 << 1,
|
FTF_CLAMP = 1 << 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Flags for A_Face*
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FAF_BOTTOM = 1,
|
||||||
|
FAF_MIDDLE = 2,
|
||||||
|
FAF_TOP = 4,
|
||||||
|
FAF_NODISTFACTOR = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// This is only here to provide one global variable for testing.
|
// This is only here to provide one global variable for testing.
|
||||||
native int testglobalvar;
|
native int testglobalvar;
|
||||||
|
|
Loading…
Reference in a new issue