From 178587fff2ce2fe67c57b3ffcc94cf350500568c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 19 Apr 2010 02:46:50 +0000 Subject: [PATCH] - 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) --- src/actor.h | 3 +- src/d_dehacked.cpp | 4 +- src/g_hexen/a_fog.cpp | 2 +- src/g_hexen/a_spike.cpp | 8 +-- src/g_raven/a_minotaur.cpp | 6 +- src/info.cpp | 4 ++ src/info.h | 28 +++++--- src/p_mobj.cpp | 117 ++++++++----------------------- src/p_pspr.cpp | 43 ++---------- src/p_pspr.h | 3 +- src/p_states.cpp | 19 +++-- src/r_main.cpp | 2 +- src/thingdef/olddecorations.cpp | 2 +- src/thingdef/thingdef_states.cpp | 2 +- wadsrc/static/actors/actor.txt | 2 +- 15 files changed, 85 insertions(+), 160 deletions(-) diff --git a/src/actor.h b/src/actor.h index ad622b3b4..243c57c90 100644 --- a/src/actor.h +++ b/src/actor.h @@ -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(); diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index a1ed9262f..2578f1a60 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -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; diff --git a/src/g_hexen/a_fog.cpp b/src/g_hexen/a_fog.cpp index 34b1537ea..3361deb65 100644 --- a/src/g_hexen/a_fog.cpp +++ b/src/g_hexen/a_fog.cpp @@ -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; } diff --git a/src/g_hexen/a_spike.cpp b/src/g_hexen/a_spike.cpp index ea9d7c3d2..f7269c40c 100644 --- a/src/g_hexen/a_spike.cpp +++ b/src/g_hexen/a_spike.cpp @@ -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); } } diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index 0958edb83..a614d3b41 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -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); } } diff --git a/src/info.cpp b/src/info.cpp index 1006f2b9c..62556b1e9 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -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"); diff --git a/src/info.h b/src/info.h index 034c63196..9480f5f59 100644 --- a/src/info.h +++ b/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) { diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 278fd27a7..2e85dfc68 100644 --- a/src/p_mobj.cpp +++ b/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 diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index e8751c1f0..7606b43a4 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -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()<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()<GetMisc2()) - { - psp->sy = state->GetMisc2()<state->GetNextState(); - } while (!psp->tics); // An initial state of 0 could cycle through. -} - //--------------------------------------------------------------------------- // // PROC P_BringUpWeapon diff --git a/src/p_pspr.h b/src/p_pspr.h index 90a57b555..99eee7883 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -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); diff --git a/src/p_states.cpp b/src/p_states.cpp index f3a99798f..15ff37117 100644 --- a/src/p_states.cpp +++ b/src/p_states.cpp @@ -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]; diff --git a/src/r_main.cpp b/src/r_main.cpp index 68a017986..ebc6720dd 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -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); diff --git a/src/thingdef/olddecorations.cpp b/src/thingdef/olddecorations.cpp index 5948bc55d..795cbc541 100644 --- a/src/thingdef/olddecorations.cpp +++ b/src/thingdef/olddecorations.cpp @@ -684,7 +684,7 @@ static void ParseSpriteFrames (FActorInfo *info, TArray &states, FScanne { sc.ScriptError ("* must come after a frame"); } - state.Frame |= SF_FULLBRIGHT; + state.Fullbright = true; } else if (*token < 'A' || *token > ']') { diff --git a/src/thingdef/thingdef_states.cpp b/src/thingdef/thingdef_states.cpp index c04193718..7e2c11259 100644 --- a/src/thingdef/thingdef_states.cpp +++ b/src/thingdef/thingdef_states.cpp @@ -244,7 +244,7 @@ do_stop: { if (sc.Compare("BRIGHT")) { - state.Frame |= SF_FULLBRIGHT; + state.Fullbright = true; continue; } if (sc.Compare("OFFSET")) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 1b8be9933..5037968e2 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -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: