Added SpriteAngle and SpriteRotation properties.

- Includes four functions, A_SetSprite(Angle/Rotation) and GetSprite(Angle/Rotation).
- SpriteRotation offsets the angle of the sprite, allowing for actors to move backwards or sideways for example.
- SpriteAngle requires +SPRITEANGLE and sets the actor's sprite to the absolute rotation found at that angle. Overrides SpriteRotation once the flag is on.
This commit is contained in:
Major Cooke 2016-07-28 15:52:20 -05:00 committed by Christoph Oelckers
parent 6ada8aa644
commit dfed6ac1fb
8 changed files with 154 additions and 5 deletions

View file

@ -382,6 +382,7 @@ enum ActorFlag7
MF7_ALLOWTHRUFLAGS = 0x00400000, // [MC] Allow THRUACTORS and the likes on puffs to prevent mod breakage.
MF7_USEKILLSCRIPTS = 0x00800000, // [JM] Use "KILL" Script on death if not forced by GameInfo.
MF7_NOKILLSCRIPTS = 0x01000000, // [JM] No "KILL" Script on death whatsoever, even if forced by GameInfo.
MF7_SPRITEANGLE = 0x02000000, // [MC] Utilize the SpriteAngle property and lock the rotation to the degrees specified.
};
// --- mobj.renderflags ---
@ -978,6 +979,8 @@ public:
DVector3 __Pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions.
DVector3 OldRenderPos;
DAngle SpriteAngle;
DAngle SpriteRotation;
DRotator Angles;
DVector3 Vel;
double Speed;

View file

@ -383,6 +383,11 @@ void AActor::Serialize(FArchive &arc)
<< RipLevelMin
<< RipLevelMax;
arc << DefThreshold;
if (SaveVersion >= 4549)
{
arc << SpriteAngle;
arc << SpriteRotation;
}
{
FString tagstr;

View file

@ -809,11 +809,17 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
angle_t rot;
if (sprframe->Texture[0] == sprframe->Texture[1])
{
rot = (ang - thing->Angles.Yaw + 45.0/2*9).BAMs() >> 28;
if (thing->flags7 & MF7_SPRITEANGLE)
rot = (thing->SpriteAngle + 45.0 / 2 * 9).BAMs() >> 28;
else
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + 45.0 / 2 * 9).BAMs() >> 28;
}
else
{
rot = (ang - thing->Angles.Yaw + (45.0/2*9-180.0/16)).BAMs() >> 28;
if (thing->flags7 & MF7_SPRITEANGLE)
rot = (thing->SpriteAngle + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
else
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
}
picnum = sprframe->Texture[rot];
if (sprframe->Flip & (1 << rot))
@ -848,11 +854,17 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
angle_t rot;
if (sprframe->Texture[0] == sprframe->Texture[1])
{
rot = (ang - thing->Angles.Yaw + 45.0 / 2 * 9).BAMs() >> 28;
if (thing->flags7 & MF7_SPRITEANGLE)
rot = (thing->SpriteAngle + 45.0 / 2 * 9).BAMs() >> 28;
else
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + 45.0 / 2 * 9).BAMs() >> 28;
}
else
{
rot = (ang - thing->Angles.Yaw + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
if (thing->flags7 & MF7_SPRITEANGLE)
rot = (thing->SpriteAngle + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
else
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
}
picnum = sprframe->Texture[rot];
if (sprframe->Flip & (1 << rot))

View file

@ -395,6 +395,64 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetGibHealth)
return 0;
}
//==========================================================================
//
// GetSpriteAngle
//
// NON-ACTION function returns the sprite angle of a pointer.
//==========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetSpriteAngle)
{
if (numret > 0)
{
assert(ret != NULL);
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
AActor *target = COPY_AAPTR(self, ptr);
if (target == nullptr)
{
ret->SetFloat(0.0);
}
else
{
const double ang = target->SpriteAngle.Degrees;
ret->SetFloat(ang);
}
return 1;
}
return 0;
}
//==========================================================================
//
// GetSpriteRotation
//
// NON-ACTION function returns the sprite rotation of a pointer.
//==========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetSpriteRotation)
{
if (numret > 0)
{
assert(ret != NULL);
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
AActor *target = COPY_AAPTR(self, ptr);
if (target == nullptr)
{
ret->SetFloat(0.0);
}
else
{
const double ang = target->SpriteRotation.Degrees;
ret->SetFloat(ang);
}
return 1;
}
return 0;
}
//==========================================================================
//
// GetZAt
@ -7219,3 +7277,49 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CopySpriteFrame)
if (!(flags & CPSF_NOFRAME)) copyto->frame = copyfrom->frame;
ACTION_RETURN_BOOL(true);
}
//==========================================================================
//
// A_SetSpriteAngle(angle, ptr)
//
// Specifies which angle the actor must always draw its sprite from.
//==========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpriteAngle)
{
PARAM_ACTION_PROLOGUE;
PARAM_FLOAT_OPT(angle) { angle = 0.; }
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
AActor *mobj = COPY_AAPTR(self, ptr);
if (mobj == nullptr)
{
ACTION_RETURN_BOOL(false);
}
mobj->SpriteAngle = angle;
ACTION_RETURN_BOOL(true);
}
//==========================================================================
//
// A_SetSpriteRotation(angle, ptr)
//
// Specifies how much to fake a sprite rotation.
//==========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpriteRotation)
{
PARAM_ACTION_PROLOGUE;
PARAM_ANGLE_OPT(angle) { angle = 0.; }
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
AActor *mobj = COPY_AAPTR(self, ptr);
if (mobj == nullptr)
{
ACTION_RETURN_BOOL(false);
}
mobj->SpriteRotation = angle;
ACTION_RETURN_BOOL(true);
}

View file

@ -259,6 +259,7 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(MF7, ALLOWTHRUFLAGS, AActor, flags7),
DEFINE_FLAG(MF7, USEKILLSCRIPTS, AActor, flags7),
DEFINE_FLAG(MF7, NOKILLSCRIPTS, AActor, flags7),
DEFINE_FLAG(MF7, SPRITEANGLE, AActor, flags7),
// Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),

View file

@ -1345,6 +1345,24 @@ DEFINE_PROPERTY(gravity, F, Actor)
defaults->Gravity = i;
}
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(spriteangle, F, Actor)
{
PROP_DOUBLE_PARM(i, 0);
defaults->SpriteAngle = i;
}
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(spriterotation, F, Actor)
{
PROP_DOUBLE_PARM(i, 0);
defaults->SpriteRotation = i;
}
//==========================================================================
//
//==========================================================================

View file

@ -76,7 +76,7 @@ const char *GetVersionString();
// Use 4500 as the base git save version, since it's higher than the
// SVN revision ever got.
#define SAVEVER 4548
#define SAVEVER 4549
#define SAVEVERSTRINGIFY2(x) #x
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)

View file

@ -35,6 +35,8 @@ ACTOR Actor native //: Thinker
BloodType "Blood", "BloodSplatter", "AxeBlood"
ExplosionDamage 128
MissileHeight 32
SpriteAngle 0
SpriteRotation 0
// Functions
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
@ -48,6 +50,8 @@ ACTOR Actor native //: Thinker
native float GetCrouchFactor(int ptr = AAPTR_PLAYER1);
native float GetCVar(string cvar);
native int GetPlayerInput(int inputnum, int ptr = AAPTR_DEFAULT);
native float GetSpriteAngle(int ptr = AAPTR_DEFAULT);
native float GetSpriteRotation(int ptr = AAPTR_DEFAULT);
// Action functions
// Meh, MBF redundant functions. Only for DeHackEd support.
@ -331,6 +335,8 @@ ACTOR Actor native //: Thinker
action native bool A_FaceMovementDirection(float offset = 0, float anglelimit = 0, float pitchlimit = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
action native int A_ClearOverlays(int sstart = 0, int sstop = 0, bool safety = true);
action native bool A_CopySpriteFrame(int from, int to, int flags = 0);
action native bool A_SetSpriteAngle(float angle = 0, int ptr = AAPTR_DEFAULT);
action native bool A_SetSpriteRotation(float angle = 0, int ptr = AAPTR_DEFAULT);
native void A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0);
native void A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0);