mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- Merged SetState and SetStateNF into a single function.
- Added new sprite #### and frame character # to specify the behavior of sprite ---- on a per-sprite and per-frame basis respectively. SVN r2291 (trunk)
This commit is contained in:
parent
768bdabbb6
commit
178587fff2
15 changed files with 85 additions and 160 deletions
|
@ -912,8 +912,7 @@ public:
|
|||
void SetOrigin (fixed_t x, fixed_t y, fixed_t z);
|
||||
bool InStateSequence(FState * newstate, FState * basestate);
|
||||
int GetTics(FState * newstate);
|
||||
bool SetState (FState *newstate);
|
||||
bool SetStateNF (FState *newstate);
|
||||
bool SetState (FState *newstate, bool nofunction=false);
|
||||
virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true);
|
||||
bool isFast();
|
||||
void SetIdle();
|
||||
|
|
|
@ -1354,8 +1354,8 @@ static int PatchFrame (int frameNum)
|
|||
}
|
||||
info->Tics = tics;
|
||||
info->Misc1 = misc1;
|
||||
info->Frame = (frame & 0x3f) |
|
||||
(frame & 0x8000 ? SF_FULLBRIGHT : 0);
|
||||
info->Frame = frame & 0x3f;
|
||||
info->Fullbright = frame & 0x8000 ? true : false;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -73,7 +73,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove)
|
|||
|
||||
if (self->args[3]-- <= 0)
|
||||
{
|
||||
self->SetStateNF (self->FindState(NAME_Death));
|
||||
self->SetState (self->FindState(NAME_Death), true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -107,9 +107,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise)
|
|||
{ // Reached it's target height
|
||||
actor->args[0] = 1;
|
||||
if (actor->args[1])
|
||||
actor->SetStateNF (actor->FindState ("BloodThrustInit2"));
|
||||
actor->SetState (actor->FindState ("BloodThrustInit2"), true);
|
||||
else
|
||||
actor->SetStateNF (actor->FindState ("ThrustInit2"));
|
||||
actor->SetState (actor->FindState ("ThrustInit2"), true);
|
||||
}
|
||||
|
||||
// Lose the dirt clump
|
||||
|
@ -131,9 +131,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower)
|
|||
{
|
||||
self->args[0] = 0;
|
||||
if (self->args[1])
|
||||
self->SetStateNF (self->FindState ("BloodThrustInit1"));
|
||||
self->SetState (self->FindState ("BloodThrustInit1"), true);
|
||||
else
|
||||
self->SetStateNF (self->FindState ("ThrustInit1"));
|
||||
self->SetState (self->FindState ("ThrustInit1"), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -192,7 +192,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide)
|
|||
&& pr_minotaurdecide() < 150)
|
||||
{ // Charge attack
|
||||
// Don't call the state function right away
|
||||
self->SetStateNF (self->FindState ("Charge"));
|
||||
self->SetState (self->FindState ("Charge"), true);
|
||||
self->flags |= MF_SKULLFLY;
|
||||
if (!friendly)
|
||||
{ // Heretic's Minotaur is invulnerable during charge attack
|
||||
|
@ -524,11 +524,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook)
|
|||
|
||||
if (self->target)
|
||||
{
|
||||
self->SetStateNF (self->SeeState);
|
||||
self->SetState (self->SeeState, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->SetStateNF (self->FindState ("Roam"));
|
||||
self->SetState (self->FindState ("Roam"), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,10 @@ void FActorInfo::StaticInit ()
|
|||
// Sprite 1 is always ----
|
||||
memcpy (temp.name, "----", 5);
|
||||
sprites.Push (temp);
|
||||
|
||||
// Sprite 2 is always ####
|
||||
memcpy (temp.name, "####", 5);
|
||||
sprites.Push (temp);
|
||||
}
|
||||
|
||||
Printf ("LoadActors: Load actor definitions.\n");
|
||||
|
|
28
src/info.h
28
src/info.h
|
@ -44,20 +44,28 @@
|
|||
#include "dobject.h"
|
||||
#include "doomdef.h"
|
||||
|
||||
const BYTE SF_FULLBRIGHT = 0x40;
|
||||
|
||||
struct Baggage;
|
||||
class FScanner;
|
||||
struct FActorInfo;
|
||||
class FArchive;
|
||||
|
||||
// Sprites that are fixed in position because they can have special meanings.
|
||||
enum
|
||||
{
|
||||
SPR_TNT1, // The empty sprite
|
||||
SPR_FIXED, // Do not change sprite or frame
|
||||
SPR_NOCHANGE, // Do not change sprite (frame change is okay)
|
||||
};
|
||||
|
||||
struct FState
|
||||
{
|
||||
WORD sprite;
|
||||
SWORD Tics;
|
||||
long Misc1; // Was changed to SBYTE, reverted to long for MBF compat
|
||||
long Misc2; // Was changed to BYTE, reverted to long for MBF compat
|
||||
BYTE Frame;
|
||||
int Misc1; // Was changed to SBYTE, reverted to long for MBF compat
|
||||
int Misc2; // Was changed to BYTE, reverted to long for MBF compat
|
||||
BYTE Frame:6;
|
||||
BYTE Fullbright:1; // State is fullbright
|
||||
BYTE SameFrame:1; // Ignore Frame (except when spawning actor)
|
||||
BYTE DefineFlags; // Unused byte so let's use it during state creation.
|
||||
short Light;
|
||||
FState *NextState;
|
||||
|
@ -66,11 +74,15 @@ struct FState
|
|||
|
||||
inline int GetFrame() const
|
||||
{
|
||||
return Frame & ~(SF_FULLBRIGHT);
|
||||
return Frame;
|
||||
}
|
||||
inline bool GetSameFrame() const
|
||||
{
|
||||
return SameFrame;
|
||||
}
|
||||
inline int GetFullbright() const
|
||||
{
|
||||
return Frame & SF_FULLBRIGHT ? 0x10 /*RF_FULLBRIGHT*/ : 0;
|
||||
return Fullbright ? 0x10 /*RF_FULLBRIGHT*/ : 0;
|
||||
}
|
||||
inline int GetTics() const
|
||||
{
|
||||
|
@ -90,7 +102,7 @@ struct FState
|
|||
}
|
||||
inline void SetFrame(BYTE frame)
|
||||
{
|
||||
Frame = (Frame & SF_FULLBRIGHT) | (frame-'A');
|
||||
Frame = frame - 'A';
|
||||
}
|
||||
void SetAction(PSymbolActionFunction *func, bool setdefaultparams = true)
|
||||
{
|
||||
|
|
117
src/p_mobj.cpp
117
src/p_mobj.cpp
|
@ -528,7 +528,7 @@ int AActor::GetTics(FState * newstate)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool AActor::SetState (FState *newstate)
|
||||
bool AActor::SetState (FState *newstate, bool nofunction)
|
||||
{
|
||||
if (debugfile && player && (player->cheats & CF_PREDICTING))
|
||||
fprintf (debugfile, "for pl %td: SetState while predicting!\n", player-players);
|
||||
|
@ -554,37 +554,41 @@ bool AActor::SetState (FState *newstate)
|
|||
tics = GetTics(newstate);
|
||||
renderflags = (renderflags & ~RF_FULLBRIGHT) | newstate->GetFullbright();
|
||||
newsprite = newstate->sprite;
|
||||
if (newsprite != 1)
|
||||
{
|
||||
// Sprite 1 is ----, which means "do not change the sprite"
|
||||
frame = newstate->GetFrame();
|
||||
|
||||
if (!(flags4 & MF4_NOSKIN) && newsprite == SpawnState->sprite)
|
||||
{ // [RH] If the new sprite is the same as the original sprite, and
|
||||
// this actor is attached to a player, use the player's skin's
|
||||
// sprite. If a player is not attached, do not change the sprite
|
||||
// unless it is different from the previous state's sprite; a
|
||||
// player may have been attached, died, and respawned elsewhere,
|
||||
// and we do not want to lose the skin on the body. If it wasn't
|
||||
// for Dehacked, I would move sprite changing out of the states
|
||||
// altogether, since actors rarely change their sprites after
|
||||
// spawning.
|
||||
if (player != NULL)
|
||||
{
|
||||
sprite = skins[player->userinfo.skin].sprite;
|
||||
if (newsprite != SPR_FIXED)
|
||||
{ // okay to change sprite and/or frame
|
||||
if (!newstate->GetSameFrame())
|
||||
{ // okay to change frame
|
||||
frame = newstate->GetFrame();
|
||||
}
|
||||
if (newsprite != SPR_NOCHANGE)
|
||||
{ // okay to change sprite
|
||||
if (!(flags4 & MF4_NOSKIN) && newsprite == SpawnState->sprite)
|
||||
{ // [RH] If the new sprite is the same as the original sprite, and
|
||||
// this actor is attached to a player, use the player's skin's
|
||||
// sprite. If a player is not attached, do not change the sprite
|
||||
// unless it is different from the previous state's sprite; a
|
||||
// player may have been attached, died, and respawned elsewhere,
|
||||
// and we do not want to lose the skin on the body. If it wasn't
|
||||
// for Dehacked, I would move sprite changing out of the states
|
||||
// altogether, since actors rarely change their sprites after
|
||||
// spawning.
|
||||
if (player != NULL)
|
||||
{
|
||||
sprite = skins[player->userinfo.skin].sprite;
|
||||
}
|
||||
else if (newsprite != prevsprite)
|
||||
{
|
||||
sprite = newsprite;
|
||||
}
|
||||
}
|
||||
else if (newsprite != prevsprite)
|
||||
else
|
||||
{
|
||||
sprite = newsprite;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite = newsprite;
|
||||
}
|
||||
}
|
||||
|
||||
if (newstate->CallAction(this, this))
|
||||
if (!nofunction && newstate->CallAction(this, this))
|
||||
{
|
||||
// Check whether the called action function resulted in destroying the actor
|
||||
if (ObjectFlags & OF_EuthanizeMe)
|
||||
|
@ -600,69 +604,6 @@ bool AActor::SetState (FState *newstate)
|
|||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// FUNC AActor::SetStateNF
|
||||
//
|
||||
// Same as SetState, but does not call the state function.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool AActor::SetStateNF (FState *newstate)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (newstate == NULL)
|
||||
{
|
||||
state = NULL;
|
||||
Destroy ();
|
||||
return false;
|
||||
}
|
||||
int prevsprite, newsprite;
|
||||
|
||||
if (state != NULL)
|
||||
{
|
||||
prevsprite = state->sprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevsprite = -1;
|
||||
}
|
||||
state = newstate;
|
||||
tics = GetTics(newstate);
|
||||
renderflags = (renderflags & ~RF_FULLBRIGHT) | newstate->GetFullbright();
|
||||
newsprite = newstate->sprite;
|
||||
if (newsprite != 1)
|
||||
{
|
||||
// Sprite 1 is ----, which means "do not change the sprite"
|
||||
|
||||
frame = newstate->GetFrame();
|
||||
if (!(flags4 & MF4_NOSKIN) && newsprite == SpawnState->sprite)
|
||||
{
|
||||
if (player != NULL && gameinfo.gametype != GAME_Hexen)
|
||||
{
|
||||
sprite = skins[player->userinfo.skin].sprite;
|
||||
}
|
||||
else if (newsprite != prevsprite)
|
||||
{
|
||||
sprite = newsprite;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite = newsprite;
|
||||
}
|
||||
}
|
||||
newstate = newstate->GetNextState();
|
||||
} while (tics == 0);
|
||||
|
||||
if (screen != NULL)
|
||||
{
|
||||
screen->StateChanged(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// AActor :: AddInventory
|
||||
|
|
|
@ -61,13 +61,12 @@ static FRandom pr_gunshot ("GunShot");
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void P_SetPsprite (player_t *player, int position, FState *state)
|
||||
void P_SetPsprite (player_t *player, int position, FState *state, bool nofunction)
|
||||
{
|
||||
pspdef_t *psp;
|
||||
|
||||
if (position == ps_weapon)
|
||||
{
|
||||
// A_WeaponReady will re-set these as needed
|
||||
if (position == ps_weapon && !nofunction)
|
||||
{ // A_WeaponReady will re-set these as needed
|
||||
player->cheats &= ~(CF_WEAPONREADY | CF_WEAPONREADYALT | CF_WEAPONBOBBING | CF_WEAPONSWITCHOK);
|
||||
}
|
||||
|
||||
|
@ -97,7 +96,7 @@ void P_SetPsprite (player_t *player, int position, FState *state)
|
|||
psp->sy = state->GetMisc2()<<FRACBITS;
|
||||
}
|
||||
|
||||
if (player->mo != NULL)
|
||||
if (!nofunction && player->mo != NULL)
|
||||
{
|
||||
if (state->CallAction(player->mo, player->ReadyWeapon))
|
||||
{
|
||||
|
@ -112,40 +111,6 @@ void P_SetPsprite (player_t *player, int position, FState *state)
|
|||
} while (!psp->tics); // An initial state of 0 could cycle through.
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_SetPspriteNF
|
||||
//
|
||||
// Identical to P_SetPsprite, without calling the action function
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void P_SetPspriteNF (player_t *player, int position, FState *state)
|
||||
{
|
||||
pspdef_t *psp;
|
||||
|
||||
psp = &player->psprites[position];
|
||||
do
|
||||
{
|
||||
if (state == NULL)
|
||||
{ // Object removed itself.
|
||||
psp->state = NULL;
|
||||
break;
|
||||
}
|
||||
psp->state = state;
|
||||
psp->tics = state->GetTics(); // could be 0
|
||||
|
||||
if (state->GetMisc1())
|
||||
{ // Set coordinates.
|
||||
psp->sx = state->GetMisc1()<<FRACBITS;
|
||||
}
|
||||
if (state->GetMisc2())
|
||||
{
|
||||
psp->sy = state->GetMisc2()<<FRACBITS;
|
||||
}
|
||||
state = psp->state->GetNextState();
|
||||
} while (!psp->tics); // An initial state of 0 could cycle through.
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_BringUpWeapon
|
||||
|
|
|
@ -79,8 +79,7 @@ class player_t;
|
|||
class AActor;
|
||||
struct FState;
|
||||
|
||||
void P_SetPsprite (player_t *player, int position, FState *state);
|
||||
void P_SetPspriteNF (player_t *player, int position, FState *state);
|
||||
void P_SetPsprite (player_t *player, int position, FState *state, bool nofunction=false);
|
||||
void P_CalcSwing (player_t *player);
|
||||
void P_BringUpWeapon (player_t *player);
|
||||
void P_FireWeapon (player_t *player);
|
||||
|
|
|
@ -824,23 +824,28 @@ bool FStateDefinitions::SetLoop()
|
|||
bool FStateDefinitions::AddStates(FState *state, const char *framechars)
|
||||
{
|
||||
bool error = false;
|
||||
int frame = 0;
|
||||
|
||||
while (*framechars)
|
||||
{
|
||||
int frame;
|
||||
|
||||
if (*framechars == '^')
|
||||
frame = '\\'-'A';
|
||||
bool noframe = false;
|
||||
|
||||
if (*framechars == '#')
|
||||
noframe = true;
|
||||
else if (*framechars == '^')
|
||||
frame = '\\' - 'A';
|
||||
else
|
||||
frame = ((*framechars)&223)-'A';
|
||||
frame = (*framechars & 223) - 'A';
|
||||
|
||||
framechars++;
|
||||
if (frame<0 || frame>28)
|
||||
if (frame < 0 || frame > 28)
|
||||
{
|
||||
frame = 0;
|
||||
error = true;
|
||||
}
|
||||
|
||||
state->Frame=(state->Frame&(SF_FULLBRIGHT))|frame;
|
||||
state->Frame = frame;
|
||||
state->SameFrame = noframe;
|
||||
StateArray.Push(*state);
|
||||
}
|
||||
laststate = &StateArray[StateArray.Size() - 1];
|
||||
|
|
|
@ -1054,7 +1054,7 @@ void R_SetupFrame (AActor *actor)
|
|||
((player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) &&
|
||||
(camera->RenderStyle.BlendOp != STYLEOP_None) &&
|
||||
!(camera->renderflags & RF_INVISIBLE) &&
|
||||
camera->sprite != 0) // Sprite 0 is always TNT1
|
||||
camera->sprite != SPR_TNT1)
|
||||
{
|
||||
// [RH] Use chasecam view
|
||||
P_AimCamera (camera, iview->nviewx, iview->nviewy, iview->nviewz, viewsector);
|
||||
|
|
|
@ -684,7 +684,7 @@ static void ParseSpriteFrames (FActorInfo *info, TArray<FState> &states, FScanne
|
|||
{
|
||||
sc.ScriptError ("* must come after a frame");
|
||||
}
|
||||
state.Frame |= SF_FULLBRIGHT;
|
||||
state.Fullbright = true;
|
||||
}
|
||||
else if (*token < 'A' || *token > ']')
|
||||
{
|
||||
|
|
|
@ -244,7 +244,7 @@ do_stop:
|
|||
{
|
||||
if (sc.Compare("BRIGHT"))
|
||||
{
|
||||
state.Frame |= SF_FULLBRIGHT;
|
||||
state.Fullbright = true;
|
||||
continue;
|
||||
}
|
||||
if (sc.Compare("OFFSET"))
|
||||
|
|
|
@ -282,7 +282,7 @@ ACTOR Actor native //: Thinker
|
|||
Stop
|
||||
GenericFreezeDeath:
|
||||
// Generic freeze death frames. Woo!
|
||||
"----" A 5 A_GenericFreezeDeath
|
||||
"####" "#" 5 A_GenericFreezeDeath
|
||||
"----" A 1 A_FreezeDeathChunks
|
||||
Wait
|
||||
GenericCrush:
|
||||
|
|
Loading…
Reference in a new issue