- 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:
Randy Heit 2010-04-19 02:46:50 +00:00
parent 768bdabbb6
commit 178587fff2
15 changed files with 85 additions and 160 deletions

View file

@ -912,8 +912,7 @@ public:
void SetOrigin (fixed_t x, fixed_t y, fixed_t z); void SetOrigin (fixed_t x, fixed_t y, fixed_t z);
bool InStateSequence(FState * newstate, FState * basestate); bool InStateSequence(FState * newstate, FState * basestate);
int GetTics(FState * newstate); int GetTics(FState * newstate);
bool SetState (FState *newstate); bool SetState (FState *newstate, bool nofunction=false);
bool SetStateNF (FState *newstate);
virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true); virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true);
bool isFast(); bool isFast();
void SetIdle(); void SetIdle();

View file

@ -1354,8 +1354,8 @@ static int PatchFrame (int frameNum)
} }
info->Tics = tics; info->Tics = tics;
info->Misc1 = misc1; info->Misc1 = misc1;
info->Frame = (frame & 0x3f) | info->Frame = frame & 0x3f;
(frame & 0x8000 ? SF_FULLBRIGHT : 0); info->Fullbright = frame & 0x8000 ? true : false;
} }
return result; return result;

View file

@ -73,7 +73,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove)
if (self->args[3]-- <= 0) if (self->args[3]-- <= 0)
{ {
self->SetStateNF (self->FindState(NAME_Death)); self->SetState (self->FindState(NAME_Death), true);
return; return;
} }

View file

@ -107,9 +107,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise)
{ // Reached it's target height { // Reached it's target height
actor->args[0] = 1; actor->args[0] = 1;
if (actor->args[1]) if (actor->args[1])
actor->SetStateNF (actor->FindState ("BloodThrustInit2")); actor->SetState (actor->FindState ("BloodThrustInit2"), true);
else else
actor->SetStateNF (actor->FindState ("ThrustInit2")); actor->SetState (actor->FindState ("ThrustInit2"), true);
} }
// Lose the dirt clump // Lose the dirt clump
@ -131,9 +131,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower)
{ {
self->args[0] = 0; self->args[0] = 0;
if (self->args[1]) if (self->args[1])
self->SetStateNF (self->FindState ("BloodThrustInit1")); self->SetState (self->FindState ("BloodThrustInit1"), true);
else else
self->SetStateNF (self->FindState ("ThrustInit1")); self->SetState (self->FindState ("ThrustInit1"), true);
} }
} }

View file

@ -192,7 +192,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide)
&& pr_minotaurdecide() < 150) && pr_minotaurdecide() < 150)
{ // Charge attack { // Charge attack
// Don't call the state function right away // Don't call the state function right away
self->SetStateNF (self->FindState ("Charge")); self->SetState (self->FindState ("Charge"), true);
self->flags |= MF_SKULLFLY; self->flags |= MF_SKULLFLY;
if (!friendly) if (!friendly)
{ // Heretic's Minotaur is invulnerable during charge attack { // Heretic's Minotaur is invulnerable during charge attack
@ -524,11 +524,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurLook)
if (self->target) if (self->target)
{ {
self->SetStateNF (self->SeeState); self->SetState (self->SeeState, true);
} }
else else
{ {
self->SetStateNF (self->FindState ("Roam")); self->SetState (self->FindState ("Roam"), true);
} }
} }

View file

@ -113,6 +113,10 @@ void FActorInfo::StaticInit ()
// Sprite 1 is always ---- // Sprite 1 is always ----
memcpy (temp.name, "----", 5); memcpy (temp.name, "----", 5);
sprites.Push (temp); sprites.Push (temp);
// Sprite 2 is always ####
memcpy (temp.name, "####", 5);
sprites.Push (temp);
} }
Printf ("LoadActors: Load actor definitions.\n"); Printf ("LoadActors: Load actor definitions.\n");

View file

@ -44,20 +44,28 @@
#include "dobject.h" #include "dobject.h"
#include "doomdef.h" #include "doomdef.h"
const BYTE SF_FULLBRIGHT = 0x40;
struct Baggage; struct Baggage;
class FScanner; class FScanner;
struct FActorInfo; struct FActorInfo;
class FArchive; 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 struct FState
{ {
WORD sprite; WORD sprite;
SWORD Tics; SWORD Tics;
long Misc1; // Was changed to SBYTE, reverted to long for MBF compat int Misc1; // Was changed to SBYTE, reverted to long for MBF compat
long Misc2; // Was changed to BYTE, reverted to long for MBF compat int Misc2; // Was changed to BYTE, reverted to long for MBF compat
BYTE Frame; 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. BYTE DefineFlags; // Unused byte so let's use it during state creation.
short Light; short Light;
FState *NextState; FState *NextState;
@ -66,11 +74,15 @@ struct FState
inline int GetFrame() const inline int GetFrame() const
{ {
return Frame & ~(SF_FULLBRIGHT); return Frame;
}
inline bool GetSameFrame() const
{
return SameFrame;
} }
inline int GetFullbright() const inline int GetFullbright() const
{ {
return Frame & SF_FULLBRIGHT ? 0x10 /*RF_FULLBRIGHT*/ : 0; return Fullbright ? 0x10 /*RF_FULLBRIGHT*/ : 0;
} }
inline int GetTics() const inline int GetTics() const
{ {
@ -90,7 +102,7 @@ struct FState
} }
inline void SetFrame(BYTE frame) inline void SetFrame(BYTE frame)
{ {
Frame = (Frame & SF_FULLBRIGHT) | (frame-'A'); Frame = frame - 'A';
} }
void SetAction(PSymbolActionFunction *func, bool setdefaultparams = true) void SetAction(PSymbolActionFunction *func, bool setdefaultparams = true)
{ {

View file

@ -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)) if (debugfile && player && (player->cheats & CF_PREDICTING))
fprintf (debugfile, "for pl %td: SetState while predicting!\n", player-players); fprintf (debugfile, "for pl %td: SetState while predicting!\n", player-players);
@ -554,37 +554,41 @@ bool AActor::SetState (FState *newstate)
tics = GetTics(newstate); tics = GetTics(newstate);
renderflags = (renderflags & ~RF_FULLBRIGHT) | newstate->GetFullbright(); renderflags = (renderflags & ~RF_FULLBRIGHT) | newstate->GetFullbright();
newsprite = newstate->sprite; newsprite = newstate->sprite;
if (newsprite != 1) if (newsprite != SPR_FIXED)
{ { // okay to change sprite and/or frame
// Sprite 1 is ----, which means "do not change the sprite" if (!newstate->GetSameFrame())
frame = newstate->GetFrame(); { // okay to change frame
frame = newstate->GetFrame();
if (!(flags4 & MF4_NOSKIN) && newsprite == SpawnState->sprite) }
{ // [RH] If the new sprite is the same as the original sprite, and if (newsprite != SPR_NOCHANGE)
// this actor is attached to a player, use the player's skin's { // okay to change sprite
// sprite. If a player is not attached, do not change the sprite if (!(flags4 & MF4_NOSKIN) && newsprite == SpawnState->sprite)
// unless it is different from the previous state's sprite; a { // [RH] If the new sprite is the same as the original sprite, and
// player may have been attached, died, and respawned elsewhere, // this actor is attached to a player, use the player's skin's
// and we do not want to lose the skin on the body. If it wasn't // sprite. If a player is not attached, do not change the sprite
// for Dehacked, I would move sprite changing out of the states // unless it is different from the previous state's sprite; a
// altogether, since actors rarely change their sprites after // player may have been attached, died, and respawned elsewhere,
// spawning. // and we do not want to lose the skin on the body. If it wasn't
if (player != NULL) // for Dehacked, I would move sprite changing out of the states
{ // altogether, since actors rarely change their sprites after
sprite = skins[player->userinfo.skin].sprite; // spawning.
if (player != NULL)
{
sprite = skins[player->userinfo.skin].sprite;
}
else if (newsprite != prevsprite)
{
sprite = newsprite;
}
} }
else if (newsprite != prevsprite) else
{ {
sprite = newsprite; 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 // Check whether the called action function resulted in destroying the actor
if (ObjectFlags & OF_EuthanizeMe) if (ObjectFlags & OF_EuthanizeMe)
@ -600,69 +604,6 @@ bool AActor::SetState (FState *newstate)
return true; 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 // AActor :: AddInventory

View file

@ -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; pspdef_t *psp;
if (position == ps_weapon) if (position == ps_weapon && !nofunction)
{ { // A_WeaponReady will re-set these as needed
// A_WeaponReady will re-set these as needed
player->cheats &= ~(CF_WEAPONREADY | CF_WEAPONREADYALT | CF_WEAPONBOBBING | CF_WEAPONSWITCHOK); 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; psp->sy = state->GetMisc2()<<FRACBITS;
} }
if (player->mo != NULL) if (!nofunction && player->mo != NULL)
{ {
if (state->CallAction(player->mo, player->ReadyWeapon)) 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. } 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 // PROC P_BringUpWeapon

View file

@ -79,8 +79,7 @@ class player_t;
class AActor; class AActor;
struct FState; struct FState;
void P_SetPsprite (player_t *player, int position, FState *state); void P_SetPsprite (player_t *player, int position, FState *state, bool nofunction=false);
void P_SetPspriteNF (player_t *player, int position, FState *state);
void P_CalcSwing (player_t *player); void P_CalcSwing (player_t *player);
void P_BringUpWeapon (player_t *player); void P_BringUpWeapon (player_t *player);
void P_FireWeapon (player_t *player); void P_FireWeapon (player_t *player);

View file

@ -824,23 +824,28 @@ bool FStateDefinitions::SetLoop()
bool FStateDefinitions::AddStates(FState *state, const char *framechars) bool FStateDefinitions::AddStates(FState *state, const char *framechars)
{ {
bool error = false; bool error = false;
int frame = 0;
while (*framechars) while (*framechars)
{ {
int frame; bool noframe = false;
if (*framechars == '^') if (*framechars == '#')
frame = '\\'-'A'; noframe = true;
else if (*framechars == '^')
frame = '\\' - 'A';
else else
frame = ((*framechars)&223)-'A'; frame = (*framechars & 223) - 'A';
framechars++; framechars++;
if (frame<0 || frame>28) if (frame < 0 || frame > 28)
{ {
frame = 0; frame = 0;
error = true; error = true;
} }
state->Frame=(state->Frame&(SF_FULLBRIGHT))|frame; state->Frame = frame;
state->SameFrame = noframe;
StateArray.Push(*state); StateArray.Push(*state);
} }
laststate = &StateArray[StateArray.Size() - 1]; laststate = &StateArray[StateArray.Size() - 1];

View file

@ -1054,7 +1054,7 @@ void R_SetupFrame (AActor *actor)
((player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) && ((player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) &&
(camera->RenderStyle.BlendOp != STYLEOP_None) && (camera->RenderStyle.BlendOp != STYLEOP_None) &&
!(camera->renderflags & RF_INVISIBLE) && !(camera->renderflags & RF_INVISIBLE) &&
camera->sprite != 0) // Sprite 0 is always TNT1 camera->sprite != SPR_TNT1)
{ {
// [RH] Use chasecam view // [RH] Use chasecam view
P_AimCamera (camera, iview->nviewx, iview->nviewy, iview->nviewz, viewsector); P_AimCamera (camera, iview->nviewx, iview->nviewy, iview->nviewz, viewsector);

View file

@ -684,7 +684,7 @@ static void ParseSpriteFrames (FActorInfo *info, TArray<FState> &states, FScanne
{ {
sc.ScriptError ("* must come after a frame"); sc.ScriptError ("* must come after a frame");
} }
state.Frame |= SF_FULLBRIGHT; state.Fullbright = true;
} }
else if (*token < 'A' || *token > ']') else if (*token < 'A' || *token > ']')
{ {

View file

@ -244,7 +244,7 @@ do_stop:
{ {
if (sc.Compare("BRIGHT")) if (sc.Compare("BRIGHT"))
{ {
state.Frame |= SF_FULLBRIGHT; state.Fullbright = true;
continue; continue;
} }
if (sc.Compare("OFFSET")) if (sc.Compare("OFFSET"))

View file

@ -282,7 +282,7 @@ ACTOR Actor native //: Thinker
Stop Stop
GenericFreezeDeath: GenericFreezeDeath:
// Generic freeze death frames. Woo! // Generic freeze death frames. Woo!
"----" A 5 A_GenericFreezeDeath "####" "#" 5 A_GenericFreezeDeath
"----" A 1 A_FreezeDeathChunks "----" A 1 A_FreezeDeathChunks
Wait Wait
GenericCrush: GenericCrush: