diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 61b7103e28..a204a67a55 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,13 @@ +May 18, 2008 (SBarInfo Update #20) +- Added: hasweaponpiece command to check for custom weapon pieces. +- Added: usessecondaryammo command to check if the current weapon has a second + ammo type. +- Most of SBarInfo's mugshot scripting can be used with the default Doom status + bar. +- Fixed: By default drawmugshot would never come out of normal god mode state. + In addition the state change to and from god mode was not quite as responsive + as the original code. + May 17, 2008 (Changes by Graf Zahl) - Fixed: When FTextureManager::CheckForTexture finds a matching NULL texture it should always return 0, not the actual texture's index. diff --git a/src/g_doom/doom_sbar.cpp b/src/g_doom/doom_sbar.cpp index a0e9e380a8..355367add2 100644 --- a/src/g_doom/doom_sbar.cpp +++ b/src/g_doom/doom_sbar.cpp @@ -14,6 +14,7 @@ #include "templates.h" #include "i_system.h" #include "r_translate.h" +#include "sbarinfo.h" #define ST_EVILGRINCOUNT (2*TICRATE) @@ -26,7 +27,6 @@ EXTERN_CVAR (Bool, vid_fps) - class DDoomStatusBar : public DBaseStatusBar { DECLARE_CLASS(DDoomStatusBar, DBaseStatusBar) @@ -51,7 +51,12 @@ public: BigHeight = tex->GetHeight(); DoCommonInit (); + bEvilGrin = false; + bDamageFaceActive = false; + CurrentState = NULL; + RampageTimer = 0; + LastDamageAngle = 1; } ~DDoomStatusBar () @@ -68,63 +73,6 @@ public: } } - void SetFace (void *skn) - { - const char *nameptrs[ST_NUMFACES]; - char names[ST_NUMFACES][9]; - char prefix[4]; - int i, j; - int namespc; - int facenum; - FPlayerSkin *skin = (FPlayerSkin *)skn; - - for (i = 0; i < ST_NUMFACES; i++) - { - nameptrs[i] = names[i]; - } - - if (skin->face[0] != 0) - { - prefix[0] = skin->face[0]; - prefix[1] = skin->face[1]; - prefix[2] = skin->face[2]; - prefix[3] = 0; - namespc = skin->namespc; - } - else - { - prefix[0] = 'S'; - prefix[1] = 'T'; - prefix[2] = 'F'; - prefix[3] = 0; - namespc = ns_global; - } - - facenum = 0; - - for (i = 0; i < ST_NUMPAINFACES; i++) - { - for (j = 0; j < ST_NUMSTRAIGHTFACES; j++) - { - sprintf (names[facenum++], "%sST%d%d", prefix, i, j); - } - sprintf (names[facenum++], "%sTR%d0", prefix, i); // turn right - sprintf (names[facenum++], "%sTL%d0", prefix, i); // turn left - sprintf (names[facenum++], "%sOUCH%d", prefix, i); // ouch! - sprintf (names[facenum++], "%sEVL%d", prefix, i); // evil grin ;) - sprintf (names[facenum++], "%sKILL%d", prefix, i); // pissed off - } - sprintf (names[facenum++], "%sGOD0", prefix); - sprintf (names[facenum++], "%sDEAD0", prefix); - - Faces.Uninit (); - Faces.Init (nameptrs, ST_NUMFACES, namespc); - - FaceIndex = 0; - FaceCount = 0; - OldFaceIndex = -1; - } - void AddFaceToImageCollection (void *skn, FImageCollection *images) { AddFaceToImageCollectionActual (skn, images, true); @@ -161,7 +109,26 @@ public: { DBaseStatusBar::Tick (); RandomNumber = M_Random (); - UpdateFace (); + + //Do some stuff related to the mug shot that has to be done at 35fps + if(CurrentState != NULL) + { + CurrentState->tick(); + if(CurrentState->finished) + CurrentState = NULL; + } + if((CPlayer->cmd.ucmd.buttons & (BT_ATTACK|BT_ALTATTACK)) && !(CPlayer->cheats & (CF_FROZEN | CF_TOTALLYFROZEN))) + { + if(RampageTimer != ST_RAMPAGEDELAY) + { + RampageTimer++; + } + } + else + { + RampageTimer = 0; + } + FaceHealth = CPlayer->health; } void Draw (EHudState state) @@ -183,7 +150,6 @@ public: OldKeys = -1; memset (OldAmmo, 255, sizeof(OldAmmo)); memset (OldMaxAmmo, 255, sizeof(OldMaxAmmo)); - OldFaceIndex = -1; OldHealth = -1; OldArmor = -1; OldActiveAmmo = -1; @@ -199,32 +165,46 @@ public: } } + //See sbarinfo_display.cpp + void SetMugShotState (const char* stateName, bool waitTillDone=false) + { + MugShotState *state = (MugShotState *) FindMugShotState(stateName); + if(state != CurrentState) + { + if(!waitTillDone || CurrentState == NULL || CurrentState->finished) + { + CurrentState = state; + state->reset(); + } + } + } + private: struct FDoomStatusBarTexture : public FTexture { void DrawToBar (const char *name, int x, int y, const BYTE *colormap_in = NULL); - public: - FDoomStatusBarTexture (); - const BYTE *GetColumn (unsigned int column, const Span **spans_out); - const BYTE *GetPixels (); - void Unload (); - ~FDoomStatusBarTexture (); - void SetPlayerRemap(FRemapTable *remap); - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); + public: + FDoomStatusBarTexture (); + const BYTE *GetColumn (unsigned int column, const Span **spans_out); + const BYTE *GetPixels (); + void Unload (); + ~FDoomStatusBarTexture (); + void SetPlayerRemap(FRemapTable *remap); + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); - FTextureFormat GetFormat() - { - return TEX_RGB; - } + FTextureFormat GetFormat() + { + return TEX_RGB; + } - protected: - void MakeTexture (); + protected: + void MakeTexture (); - FTexture *BaseTexture; - BYTE *Pixels; - FRemapTable *STFBRemap; + FTexture *BaseTexture; + BYTE *Pixels; + FRemapTable *STFBRemap; } StatusBarTex; @@ -255,8 +235,6 @@ private: StatusBarTex.Unload (); SB_state = screen->GetPageCount (); - FaceLastAttackDown = -1; - FacePriority = 0; } void DrawMainBar () @@ -463,38 +441,6 @@ private: } } - void DrawFace () - { - // If a player has an inventory item selected, it takes the place of the - // face, for lack of a better place to put it. - if (OldFaceIndex != FaceIndex) - { - FaceRefresh = screen->GetPageCount (); - OldFaceIndex = FaceIndex; - } - if (FaceRefresh || (CPlayer->mo->InvSel != NULL && !(level.flags & LEVEL_NOINVENTORYBAR))) - { - if (FaceRefresh) - { - FaceRefresh--; - } - DrawPartialImage (&StatusBarTex, 142, 37); - if (CPlayer->mo->InvSel == NULL || (level.flags & LEVEL_NOINVENTORYBAR)) - { - DrawImage (Faces[FaceIndex], 143, 0); - } - else - { - DrawDimImage (TexMan(CPlayer->mo->InvSel->Icon), 144, 0, CPlayer->mo->InvSel->Amount <= 0); - if (CPlayer->mo->InvSel->Amount != 1) - { - DrSmallNumber (CPlayer->mo->InvSel->Amount, 165, 24); - } - OldFaceIndex = -1; - } - } - } - void DrawKeys () { AInventory *item; @@ -780,7 +726,7 @@ private: int health; static int lastcalc; static int oldhealth = -1; - + health = CPlayer->health > 100 ? 100 : CPlayer->health; if (health != oldhealth) @@ -796,174 +742,148 @@ private: bEvilGrin = true; } - // - // This is a not-very-pretty routine which handles the face states - // and their timing. The precedence of expressions is: - // dead > evil grin > turned head > straight ahead - // - void UpdateFace () + int UpdateState () { int i; angle_t badguyangle; angle_t diffang; - - if (FacePriority < 10) + if(CPlayer->health > 0) { - // dead - if (CPlayer->health <= 0) + if(bEvilGrin) { - FacePriority = 9; - FaceIndex = ST_DEADFACE; - FaceCount = 1; - } - } - - if (FacePriority < 9) - { - if (CPlayer->bonuscount) - { - // picking up bonus - if (bEvilGrin) - { - // evil grin if just picked up weapon + if(CurrentState == NULL) bEvilGrin = false; - FacePriority = 8; - FaceCount = ST_EVILGRINCOUNT; - FaceIndex = CalcPainOffset() + ST_EVILGRINOFFSET; + else if(CPlayer->bonuscount) + { + SetMugShotState("grin", false); + return 0; } } - else - { - // This happens when a weapon is added to the inventory - // by other means than being picked up. - bEvilGrin = false; - } - } - - if (FacePriority < 8) - { - if (CPlayer->damagecount - && CPlayer->attacker - && CPlayer->attacker != CPlayer->mo) - { - // being attacked - FacePriority = 7; - - if (FaceHealth != -9999 && FaceHealth - CPlayer->health > ST_MUCHPAIN) - { - FaceCount = ST_TURNCOUNT; - FaceIndex = CalcPainOffset() + ST_OUCHOFFSET; - FacePriority = 8; - } - else if (CPlayer->mo != NULL) - { - badguyangle = R_PointToAngle2(CPlayer->mo->x, - CPlayer->mo->y, - CPlayer->attacker->x, - CPlayer->attacker->y); - - if (badguyangle > CPlayer->mo->angle) - { - // whether right or left - diffang = badguyangle - CPlayer->mo->angle; - i = diffang > ANG180; - } - else - { - // whether left or right - diffang = CPlayer->mo->angle - badguyangle; - i = diffang <= ANG180; - } // confusing, aint it? - - FaceCount = ST_TURNCOUNT; - FaceIndex = CalcPainOffset(); - - if (diffang < ANG45) - { - // head-on - FaceIndex += ST_RAMPAGEOFFSET; - } - else if (i) - { - // turn face right - FaceIndex += ST_TURNOFFSET; - } - else - { - // turn face left - FaceIndex += ST_TURNOFFSET+1; - } - } - } - } - - if (FacePriority < 7) - { - // getting hurt because of your own damn stupidity if (CPlayer->damagecount) { - if (OldHealth != -1 && CPlayer->health - OldHealth > ST_MUCHPAIN) + int damageAngle = 1; + if(CPlayer->attacker && CPlayer->attacker != CPlayer->mo) { - FacePriority = 7; - FaceCount = ST_TURNCOUNT; - FaceIndex = CalcPainOffset() + ST_OUCHOFFSET; + if(CPlayer->mo != NULL) + { + //The next 12 lines is from the Doom statusbar code. + badguyangle = R_PointToAngle2(CPlayer->mo->x, CPlayer->mo->y, CPlayer->attacker->x, CPlayer->attacker->y); + if(badguyangle > CPlayer->mo->angle) + { + // whether right or left + diffang = badguyangle - CPlayer->mo->angle; + i = diffang > ANG180; + } + else + { + // whether left or right + diffang = CPlayer->mo->angle - badguyangle; + i = diffang <= ANG180; + } // confusing, aint it? + if(i && diffang >= ANG45) + { + damageAngle = 0; + } + else if(!i && diffang >= ANG45) + { + damageAngle = 2; + } + } } + const char* stateName = new char[5]; + if (FaceHealth != -1 && CPlayer->health - FaceHealth > 20) + stateName = "ouch"; + else + stateName = "pain"; + char* fullStateName = new char[sizeof(stateName)+sizeof((const char*) CPlayer->LastDamageType) + 1]; + sprintf(fullStateName, "%s.%s", stateName, (const char*) CPlayer->LastDamageType); + if(FindMugShotState(fullStateName) != NULL) + SetMugShotState(fullStateName); + else + SetMugShotState(stateName); + bDamageFaceActive = !(CurrentState == NULL); + LastDamageAngle = damageAngle; + return damageAngle; + } + if(bDamageFaceActive) + { + if(CurrentState == NULL) + bDamageFaceActive = false; else { - FacePriority = 6; - FaceCount = ST_TURNCOUNT; - FaceIndex = CalcPainOffset() + ST_RAMPAGEOFFSET; + const char* stateName = new char[5]; + if (FaceHealth != -1 && CPlayer->health - FaceHealth > 20) + stateName = "ouch"; + else + stateName = "pain"; + char* fullStateName = new char[sizeof(stateName)+sizeof((const char*) CPlayer->LastDamageType) + 1]; + sprintf(fullStateName, "%s.%s", stateName, (const char*) CPlayer->LastDamageType); + if(FindMugShotState(fullStateName) != NULL) + SetMugShotState(fullStateName); + else + SetMugShotState(stateName); + return LastDamageAngle; } - } - } - - if (FacePriority < 6) - { - // rapid firing - if ((CPlayer->cmd.ucmd.buttons & (BT_ATTACK|BT_ALTATTACK)) && !(CPlayer->cheats & (CF_FROZEN | CF_TOTALLYFROZEN))) + if(RampageTimer == ST_RAMPAGEDELAY) { - if (FaceLastAttackDown == -1) - FaceLastAttackDown = ST_RAMPAGEDELAY; - else if (!--FaceLastAttackDown) - { - FacePriority = 5; - FaceIndex = CalcPainOffset() + ST_RAMPAGEOFFSET; - FaceCount = 1; - FaceLastAttackDown = 1; - } + SetMugShotState("rampage", true); + return 0; } + + if(!bEvilGrin) + { + if((CPlayer->cheats & CF_GODMODE) || (CPlayer->mo != NULL && CPlayer->mo->flags2 & MF2_INVULNERABLE)) + SetMugShotState("god"); + else + SetMugShotState("normal"); + } + } + else + { + const char* stateName = new char[7]; + stateName = "death"; + //new string the size of stateName and the damage type put together + char* fullStateName = new char[sizeof(stateName)+sizeof((const char*) CPlayer->LastDamageType) + 1]; + sprintf(fullStateName, "%s.%s", stateName, (const char*) CPlayer->LastDamageType); + if(FindMugShotState(fullStateName) != NULL) + SetMugShotState(fullStateName); else + SetMugShotState(stateName); + } + return 0; + } + + void DrawFace () + { + if (CPlayer->mo->InvSel == NULL || (level.flags & LEVEL_NOINVENTORYBAR)) + { + int angle = UpdateState(); + int level = 0; + for(level = 0;CPlayer->health < (4-level)*(CPlayer->mo->GetMaxHealth()/5);level++); + if(CurrentState != NULL) { - FaceLastAttackDown = -1; + FString defaultFace = "STF"; + FPlayerSkin *skin = &skins[CPlayer->morphTics ? CPlayer->MorphedPlayerClass : CPlayer->userinfo.skin]; + FTexture *face = CurrentState->getCurrentFrameTexture(defaultFace, skin, level, angle); + if (face != NULL) + { + DrawPartialImage (&StatusBarTex, 142, 37); + DrawImage (face, 143, 0); + } } } - - if (FacePriority < 5) + else { - // invulnerability - if ((CPlayer->cheats & CF_GODMODE) - || (CPlayer->mo != NULL && CPlayer->mo->flags2 & MF2_INVULNERABLE)) + DrawDimImage (TexMan(CPlayer->mo->InvSel->Icon), 144, 0, CPlayer->mo->InvSel->Amount <= 0); + if (CPlayer->mo->InvSel->Amount != 1) { - FacePriority = 4; - FaceIndex = ST_GODFACE; - FaceCount = 1; + DrSmallNumber (CPlayer->mo->InvSel->Amount, 165, 24); } } - - // look left or look right if the facecount has timed out - if (!FaceCount) - { - FaceIndex = CalcPainOffset() + (RandomNumber % 3); - FaceCount = ST_STRAIGHTFACECOUNT; - FacePriority = 0; - } - - FaceCount--; - FaceHealth = CPlayer->health; } enum @@ -995,15 +915,11 @@ private: }; FImageCollection Images; - FImageCollection Faces; int BigWidth; int BigHeight; - int FaceIndex; - int FaceCount; int RandomNumber; - int OldFaceIndex; BYTE OldArms[6]; int OldKeys; int OldAmmo[4]; @@ -1012,9 +928,6 @@ private: int OldArmor; int OldActiveAmmo; int OldFrags; - int FaceHealth; - int FaceLastAttackDown; - int FacePriority; char HealthRefresh; char ArmorRefresh; @@ -1026,7 +939,13 @@ private: char FaceRefresh; char KeysRefresh; + //Mugshot + MugShotState *CurrentState; + int RampageTimer; + int LastDamageAngle; + int FaceHealth; bool bEvilGrin; + bool bDamageFaceActive; }; IMPLEMENT_CLASS(DDoomStatusBar) @@ -1075,7 +994,7 @@ void DDoomStatusBar::FDoomStatusBarTexture::Unload () Pixels = NULL; } } - + DDoomStatusBar::FDoomStatusBarTexture::~FDoomStatusBarTexture () { Unload (); diff --git a/src/g_shared/a_weaponpiece.cpp b/src/g_shared/a_weaponpiece.cpp index aa47874e63..7bde37bb18 100644 --- a/src/g_shared/a_weaponpiece.cpp +++ b/src/g_shared/a_weaponpiece.cpp @@ -2,26 +2,6 @@ #include "a_weaponpiece.h" #include "doomstat.h" - - -// an internal class to hold the information for player class independent weapon piece handling -class AWeaponHolder : public AInventory -{ - DECLARE_ACTOR(AWeaponHolder, AInventory) - -public: - int PieceMask; - const PClass * PieceWeapon; - - void Serialize (FArchive &arc) - { - Super::Serialize(arc); - arc << PieceMask << PieceWeapon; - } -}; - - - IMPLEMENT_STATELESS_ACTOR (AWeaponHolder, Any, -1, 0) PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR) PROP_Inventory_FlagsSet (IF_UNDROPPABLE) diff --git a/src/g_shared/a_weaponpiece.h b/src/g_shared/a_weaponpiece.h index d6df4a71a4..ccb18093b1 100644 --- a/src/g_shared/a_weaponpiece.h +++ b/src/g_shared/a_weaponpiece.h @@ -16,3 +16,20 @@ public: const PClass * WeaponClass; TObjPtr FullWeapon; }; + +// an internal class to hold the information for player class independent weapon piece handling +// [BL] Needs to be available for SBarInfo to check weaponpieces +class AWeaponHolder : public AInventory +{ + DECLARE_ACTOR(AWeaponHolder, AInventory) + +public: + int PieceMask; + const PClass * PieceWeapon; + + void Serialize (FArchive &arc) + { + Super::Serialize(arc); + arc << PieceMask << PieceWeapon; + } +}; diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index 58d18189ea..26f9c28676 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -218,6 +218,7 @@ public: virtual void ShowPop (int popnum); virtual void ReceivedWeapon (AWeapon *weapon); virtual bool MustDrawLog(EHudState state); + virtual void SetMugShotState (const char* stateName, bool waitTillDone=false) {} void DrawLog(); protected: diff --git a/src/g_shared/sbarinfo.h b/src/g_shared/sbarinfo.h index 2e1b582947..bb00088de7 100644 --- a/src/g_shared/sbarinfo.h +++ b/src/g_shared/sbarinfo.h @@ -346,6 +346,8 @@ enum //Bar key words SBARINFO_PLAYERCLASS, SBARINFO_ASPECTRATIO, SBARINFO_ISSELECTED, + SBARINFO_USESSECONDARYAMMO, + SBARINFO_HASWEAPONPIECE, SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, }; @@ -384,9 +386,9 @@ private: void DrawNumber(int num, int len, int x, int y, int xOffset, int yOffset, int alpha, EColorRange translation, int spacing=0, bool fillzeros=false); void DrawFace(FString &defaultFace, int accuracy, bool xdth, bool animatedgodmode, int x, int y, int xOffset, int yOffset, int alpha); int updateState(bool xdth, bool animatedgodmode); - void DrawInventoryBar(int type, int num, int x, int y, int xOffset, int yOffset, int alpha, bool alwaysshow, + void DrawInventoryBar(int type, int num, int x, int y, int xOffset, int yOffset, int alpha, bool alwaysshow, int counterx, int countery, EColorRange translation, bool drawArtiboxes, bool noArrows, bool alwaysshowcounter); - void DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y, int xOffset, int yOffset, int alpha, int padleft, int padright, int chainsize, + void DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y, int xOffset, int yOffset, int alpha, int padleft, int padright, int chainsize, bool wiggle, bool translate); FRemapTable* getTranslation(); diff --git a/src/g_shared/sbarinfo_display.cpp b/src/g_shared/sbarinfo_display.cpp index ecf11f2d95..a4a2666b3e 100644 --- a/src/g_shared/sbarinfo_display.cpp +++ b/src/g_shared/sbarinfo_display.cpp @@ -52,6 +52,7 @@ #include "gi.h" #include "r_translate.h" #include "r_main.h" +#include "a_weaponpiece.h" static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic. @@ -670,7 +671,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a AHexenArmor *harmor = CPlayer->mo->FindInventory(); if(harmor != NULL) { - value = harmor->Slots[0] + harmor->Slots[1] + + value = harmor->Slots[0] + harmor->Slots[1] + harmor->Slots[2] + harmor->Slots[3] + harmor->Slots[4]; } //Hexen counts basic armor also so we should too. @@ -1134,6 +1135,33 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a } } break; + case SBARINFO_USESSECONDARYAMMO: + if((CPlayer->ReadyWeapon->AmmoType2 != NULL && !(cmd.flags & SBARINFOEVENT_NOT)) || + (CPlayer->ReadyWeapon->AmmoType2 == NULL && cmd.flags & SBARINFOEVENT_NOT)) + { + doCommands(cmd.subBlock, xOffset, yOffset, alpha); + } + break; + case SBARINFO_HASWEAPONPIECE: + { + AInventory *inv; + AWeaponHolder *hold; + const PClass *weapon = PClass::FindClass(cmd.string[0]); + for(inv = CPlayer->mo->Inventory;inv != NULL;inv=inv->Inventory) + { + if(inv->IsKindOf(RUNTIME_CLASS(AWeaponHolder))) + { + hold = static_cast(inv); + if(hold->PieceWeapon == weapon) + { + if(hold->PieceMask & (1 << (cmd.value-1))) + doCommands(cmd.subBlock, xOffset, yOffset, alpha); + break; + } + } + } + break; + } case SBARINFO_WEAPONAMMO: if(CPlayer->ReadyWeapon != NULL) { @@ -1146,7 +1174,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a bool usesammo2 = (AmmoType2 != NULL); if(!(cmd.flags & SBARINFOEVENT_NOT) && !usesammo1 && !usesammo2) //if the weapon doesn't use ammo don't go though the trouble. { - doCommands(cmd.subBlock, xOffset, yOffset); + doCommands(cmd.subBlock, xOffset, yOffset, alpha); break; } //Or means only 1 ammo type needs to match and means both need to match. @@ -1207,7 +1235,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a } //draws an image with the specified flags -void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int xOffset, int yOffset, int alpha, +void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int xOffset, int yOffset, int alpha, bool translate, bool dim, bool center) //flags { if (texture == NULL) @@ -1333,7 +1361,8 @@ int DSBarInfo::updateState(bool xdth, bool animatedgodmode) { if(weaponGrin) { - weaponGrin = false; + if(currentState == NULL) + weaponGrin = false; if(CPlayer->bonuscount) { SetMugShotState("grin", false); @@ -1354,13 +1383,13 @@ int DSBarInfo::updateState(bool xdth, bool animatedgodmode) { // whether right or left diffang = badguyangle - CPlayer->mo->angle; - i = diffang > ANG180; + i = diffang > ANG180; } else { // whether left or right diffang = CPlayer->mo->angle - badguyangle; - i = diffang <= ANG180; + i = diffang <= ANG180; } // confusing, aint it? if(i && diffang >= ANG45) { @@ -1377,7 +1406,7 @@ int DSBarInfo::updateState(bool xdth, bool animatedgodmode) stateName = "ouch"; else stateName = "pain"; - char* fullStateName = new char[sizeof(stateName)+sizeof((const char*) CPlayer->LastDamageType) + 1]; + char* fullStateName = new char[sizeof(stateName)+sizeof((const char*) CPlayer->LastDamageType) + 1]; sprintf(fullStateName, "%s.%s", stateName, (const char*) CPlayer->LastDamageType); if(FindMugShotState(fullStateName) != NULL) SetMugShotState(fullStateName); @@ -1398,7 +1427,7 @@ int DSBarInfo::updateState(bool xdth, bool animatedgodmode) stateName = "ouch"; else stateName = "pain"; - char* fullStateName = new char[sizeof(stateName)+sizeof((const char*) CPlayer->LastDamageType) + 1]; + char* fullStateName = new char[sizeof(stateName)+sizeof((const char*) CPlayer->LastDamageType) + 1]; sprintf(fullStateName, "%s.%s", stateName, (const char*) CPlayer->LastDamageType); if(FindMugShotState(fullStateName) != NULL) SetMugShotState(fullStateName); @@ -1414,15 +1443,18 @@ int DSBarInfo::updateState(bool xdth, bool animatedgodmode) return 0; } - if((CPlayer->cheats & CF_GODMODE) || (CPlayer->mo != NULL && CPlayer->mo->flags2 & MF2_INVULNERABLE)) + if(!weaponGrin) { - if(animatedgodmode) - SetMugShotState("godanimated", true); + if((CPlayer->cheats & CF_GODMODE) || (CPlayer->mo != NULL && CPlayer->mo->flags2 & MF2_INVULNERABLE)) + { + if(animatedgodmode) + SetMugShotState("godanimated"); + else + SetMugShotState("god"); + } else - SetMugShotState("god", true); + SetMugShotState("normal"); } - else - SetMugShotState("normal", true); } else { @@ -1432,7 +1464,7 @@ int DSBarInfo::updateState(bool xdth, bool animatedgodmode) else stateName = "xdeath"; //new string the size of stateName and the damage type put together - char* fullStateName = new char[sizeof(stateName)+sizeof((const char*) CPlayer->LastDamageType) + 1]; + char* fullStateName = new char[sizeof(stateName)+sizeof((const char*) CPlayer->LastDamageType) + 1]; sprintf(fullStateName, "%s.%s", stateName, (const char*) CPlayer->LastDamageType); if(FindMugShotState(fullStateName) != NULL) SetMugShotState(fullStateName); @@ -1442,7 +1474,7 @@ int DSBarInfo::updateState(bool xdth, bool animatedgodmode) return 0; } -void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, int xOffset, int yOffset, int alpha, bool alwaysshow, +void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, int xOffset, int yOffset, int alpha, bool alwaysshow, int counterx, int countery, EColorRange translation, bool drawArtiboxes, bool noArrows, bool alwaysshowcounter) { //yes, there is some Copy & Paste here too AInventory *item; @@ -1469,6 +1501,10 @@ void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, int xOffset, i { DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y+29, xOffset, yOffset, alpha); } + else if(type == GAME_Hexen) + { + DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y-1, xOffset, yOffset, alpha); + } else { DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y, xOffset, yOffset, alpha); @@ -1495,7 +1531,7 @@ void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, int xOffset, i } //draws heretic/hexen style life gems -void DSBarInfo::DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y, int xOffset, int yOffset, int alpha, int padleft, int padright, int chainsize, +void DSBarInfo::DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y, int xOffset, int yOffset, int alpha, int padleft, int padright, int chainsize, bool wiggle, bool translate) { if(chain == NULL) diff --git a/src/g_shared/sbarinfo_parser.cpp b/src/g_shared/sbarinfo_parser.cpp index 9a7b86b3a3..4459a96a8b 100644 --- a/src/g_shared/sbarinfo_parser.cpp +++ b/src/g_shared/sbarinfo_parser.cpp @@ -95,6 +95,8 @@ static const char *SBarInfoRoutineLevel[] = "playerclass", "aspectratio", "isselected", + "usessecondaryammo", + "hasweaponpiece", "weaponammo", //event "ininventory", NULL @@ -140,7 +142,7 @@ void SBarInfo::ParseSBarInfo(int lump) { sc.MustGetToken(TK_StringConst); int lump = Wads.CheckNumForFullName(sc.String, true); - if (lump == -1) + if (lump == -1) sc.ScriptError("Lump '%s' not found", sc.String); ParseSBarInfo(lump); continue; @@ -229,7 +231,7 @@ void SBarInfo::ParseSBarInfo(int lump) spacingCharacter = '\0'; sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); //Don't tell anyone we're just ignoring this ;) - } + } sc.MustGetToken(';'); break; case SBARINFO_LOWERHEALTHCAP: @@ -705,7 +707,11 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) { cmd.special = GAME_Heretic; } - if(sc.Compare("Doom") || sc.Compare("Heretic")) + else if(sc.Compare("Hexen")) + { + cmd.special = GAME_Hexen; + } + if(sc.Compare("Doom") || sc.Compare("Heretic") || sc.Compare("Hexen")) { sc.MustGetToken(','); while(sc.CheckToken(TK_Identifier)) @@ -1053,6 +1059,33 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) sc.MustGetToken('{'); this->ParseSBarInfoBlock(sc, cmd.subBlock); break; + case SBARINFO_USESSECONDARYAMMO: + if(sc.CheckToken(TK_Identifier)) + { + if(sc.Compare("not")) + cmd.flags += SBARINFOEVENT_NOT; + else + sc.ScriptError("Exspected 'not' got '%s' instead.", sc.String); + } + sc.MustGetToken('{'); + this->ParseSBarInfoBlock(sc, cmd.subBlock); + break; + case SBARINFO_HASWEAPONPIECE: + { + sc.MustGetToken(TK_Identifier); + const PClass* weapon = PClass::FindClass(sc.String); + if(weapon == NULL || !RUNTIME_CLASS(AWeapon)->IsAncestorOf(weapon)) //must be a weapon + sc.ScriptError("%s is not a kind of weapon.", sc.String); + cmd.setString(sc, sc.String, 0); + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + if(sc.Number < 1) + sc.ScriptError("Weapon piece number can not be less than 1."); + cmd.value = sc.Number; + sc.MustGetToken('{'); + this->ParseSBarInfoBlock(sc, cmd.subBlock); + break; + } case SBARINFO_WEAPONAMMO: sc.MustGetToken(TK_Identifier); if(sc.Compare("not")) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 14633e7986..6ef9873a36 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -81,7 +81,7 @@ FRandom pr_acs ("ACS"); #define CLAMPCOLOR(c) (EColorRange)((unsigned)(c) >= NUM_TEXT_COLORS ? CR_UNTRANSLATED : (c)) #define HUDMSG_LOG (0x80000000) #define HUDMSG_COLORSTRING (0x40000000) -#define LANGREGIONMASK MAKE_ID(0,0,0xff,0xff) +#define LANGREGIONMASK MAKE_ID(0,0,0xff,0xff) // Flags for ReplaceTextures #define NOT_BOTTOM 1 @@ -143,7 +143,7 @@ static void DoClearInv (AActor *actor) AAmmo *ammo = static_cast(inv); ammo->Amount = 0; } - else + else inv->Destroy (); } else if (inv->GetClass() == RUNTIME_CLASS(AHexenArmor)) @@ -203,7 +203,7 @@ static void DoGiveInv (AActor *actor, const PClass *info, int amount) AInventory *item = static_cast(Spawn (info, 0,0,0, NO_REPLACE)); // This shouldn't count for the item statistics! - if (item->flags & MF_COUNTITEM) + if (item->flags & MF_COUNTITEM) { level.total_items--; item->flags &= ~MF_COUNTITEM; @@ -298,9 +298,9 @@ static void DoTakeInv (AActor *actor, const PClass *info, int amount) item->Amount -= amount; if (item->Amount <= 0) { - // If it's not ammo or an internal armor, destroy it. - // Ammo needs to stick around, even when it's zero for the benefit - // of the weapons that use it and to maintain the maximum ammo + // If it's not ammo or an internal armor, destroy it. + // Ammo needs to stick around, even when it's zero for the benefit + // of the weapons that use it and to maintain the maximum ammo // amounts a backpack might have given. // Armor shouldn't be removed because they only work properly when // they are the last items in the inventory. @@ -520,7 +520,7 @@ void DPlaneWatcher::Tick () } fixed_t newd; - + if (bCeiling) { newd = Sector->ceilingplane.d; @@ -825,7 +825,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) Data = object; DataSize = len; - + if (Format == ACS_Old) { DWORD dirofs = LittleLong(((DWORD *)object)[1]); @@ -1227,7 +1227,7 @@ void FBehavior::LoadScriptsDirectory () } } break; - + default: break; } @@ -1818,11 +1818,11 @@ int DLevelScript::ThingCount (int type, int stringid, int tid, int tag) const char *type_name = FBehavior::StaticLookupString (stringid); if (type_name == NULL) return 0; - + kind = PClass::FindClass (type_name); if (kind == NULL || kind->ActorInfo == NULL) return 0; - + } else { @@ -1918,7 +1918,7 @@ int DLevelScript::CountPlayers () for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) count++; - + return count; } @@ -2248,7 +2248,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) case APROP_RenderStyle: for(int i=0; LegacyRenderStyleIndices[i] >= 0; i++) { - if (LegacyRenderStyleIndices[i] == value) + if (LegacyRenderStyleIndices[i] == value) { actor->RenderStyle = ERenderStyle(i); break; @@ -2282,14 +2282,14 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) else actor->flags4 &= ~MF4_FRIGHTENED; break; - + case APROP_Friendly: if (value) actor->flags |= MF_FRIENDLY; else actor->flags &= ~MF_FRIENDLY; break; - + case APROP_SpawnHealth: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) @@ -2297,7 +2297,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) static_cast(actor)->MaxHealth = value; } break; - + case APROP_Gravity: actor->gravity = value; break; @@ -2311,7 +2311,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) break; case APROP_PainSound: - actor->PainSound = S_FindSound (FBehavior::StaticLookupString (value)); + actor->PainSound = S_FindSound (FBehavior::StaticLookupString (value)); break; case APROP_DeathSound: @@ -2374,7 +2374,7 @@ int DLevelScript::GetActorProperty (int tid, int property) { return actor->GetDefault()->health; } - + case APROP_JumpZ: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) { return static_cast(actor)->JumpZ; // [GRB] @@ -2425,7 +2425,7 @@ int DLevelScript::RunScript () while ((secnum = P_FindSectorFromTag (statedata, secnum)) >= 0) if (sectors[secnum].floordata || sectors[secnum].ceilingdata) return resultValue; - + // If we got here, none of the tagged sectors were busy state = SCRIPT_Running; } @@ -3571,7 +3571,7 @@ int DLevelScript::RunScript () STACK(2) = Random (STACK(2), STACK(1)); sp--; break; - + case PCD_RANDOMDIRECT: PushToStack (Random (pc[0], pc[1])); pc += 2; @@ -4273,7 +4273,7 @@ int DLevelScript::RunScript () { FActorIterator iterator (STACK(7)); AActor *actor; - + while ( (actor = iterator.Next ()) ) { actor->special = STACK(6); @@ -4457,7 +4457,7 @@ int DLevelScript::RunScript () break; case PCD_CHECKACTORINVENTORY: - STACK(2) = CheckInventory (SingleActorFromTID(STACK(2), NULL), + STACK(2) = CheckInventory (SingleActorFromTID(STACK(2), NULL), FBehavior::StaticLookupString (STACK(1))); sp--; break; @@ -4877,7 +4877,7 @@ int DLevelScript::RunScript () } } break; - + case PCD_SETMARINEWEAPON: if (STACK(2) != 0) { @@ -5150,7 +5150,7 @@ int DLevelScript::RunScript () FState *state; MakeStateNameList(statename, &statelist); - + if (STACK(3) == 0) { state = activator->GetClass()->ActorInfo->FindState (statelist.Size(), &statelist[0], !!STACK(1)); @@ -5223,7 +5223,7 @@ int DLevelScript::RunScript () case PCD_CHANGELEVEL: { int flags = STACK(2); - G_ChangeLevel(FBehavior::StaticLookupString(STACK(4)), STACK(3), + G_ChangeLevel(FBehavior::StaticLookupString(STACK(4)), STACK(3), !!(flags & CHANGELEVEL_KEEPFACING), STACK(1), !!(flags & CHANGELEVEL_NOINTERMISSION), !!(flags & CHANGELEVEL_RESETINVENTORY), @@ -5243,7 +5243,7 @@ int DLevelScript::RunScript () sp -= 5; int secnum = -1; - + while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { AActor *actor, *next; @@ -5334,25 +5334,22 @@ int DLevelScript::RunScript () } case PCD_SETMUGSHOTSTATE: - if(StatusBar != NULL && StatusBar->IsKindOf(RUNTIME_CLASS(DSBarInfo))) - { - static_cast(StatusBar)->SetMugShotState(FBehavior::StaticLookupString(STACK(1))); - } + StatusBar->SetMugShotState(FBehavior::StaticLookupString(STACK(1))); break; case PCD_CHECKPLAYERCAMERA: { int playernum = STACK(1); - + if (playernum < 0 || playernum >= MAXPLAYERS || !playeringame[playernum] || players[playernum].camera == NULL) { STACK(1) = -1; } - else + else { STACK(1) = players[playernum].camera->tid; } - } + } break; } } diff --git a/wadsrc/fontdefs.txt b/wadsrc/fontdefs.txt index 1e5f21108c..7e3aae0684 100644 --- a/wadsrc/fontdefs.txt +++ b/wadsrc/fontdefs.txt @@ -31,3 +31,17 @@ HUDFONT_RAVEN 8 IN8 9 IN9 } + +INDEXFONT_RAVEN +{ + 0 SMALLIN0 + 1 SMALLIN1 + 2 SMALLIN2 + 3 SMALLIN3 + 4 SMALLIN4 + 5 SMALLIN5 + 6 SMALLIN6 + 7 SMALLIN7 + 8 SMALLIN8 + 9 SMALLIN9 +}