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.

SVN r980 (trunk)
This commit is contained in:
Christoph Oelckers 2008-05-18 15:48:03 +00:00
parent b8c21495d5
commit 35ea94c014
10 changed files with 342 additions and 333 deletions

View file

@ -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) May 17, 2008 (Changes by Graf Zahl)
- Fixed: When FTextureManager::CheckForTexture finds a matching NULL texture - Fixed: When FTextureManager::CheckForTexture finds a matching NULL texture
it should always return 0, not the actual texture's index. it should always return 0, not the actual texture's index.

View file

@ -14,6 +14,7 @@
#include "templates.h" #include "templates.h"
#include "i_system.h" #include "i_system.h"
#include "r_translate.h" #include "r_translate.h"
#include "sbarinfo.h"
#define ST_EVILGRINCOUNT (2*TICRATE) #define ST_EVILGRINCOUNT (2*TICRATE)
@ -26,7 +27,6 @@
EXTERN_CVAR (Bool, vid_fps) EXTERN_CVAR (Bool, vid_fps)
class DDoomStatusBar : public DBaseStatusBar class DDoomStatusBar : public DBaseStatusBar
{ {
DECLARE_CLASS(DDoomStatusBar, DBaseStatusBar) DECLARE_CLASS(DDoomStatusBar, DBaseStatusBar)
@ -51,7 +51,12 @@ public:
BigHeight = tex->GetHeight(); BigHeight = tex->GetHeight();
DoCommonInit (); DoCommonInit ();
bEvilGrin = false; bEvilGrin = false;
bDamageFaceActive = false;
CurrentState = NULL;
RampageTimer = 0;
LastDamageAngle = 1;
} }
~DDoomStatusBar () ~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) void AddFaceToImageCollection (void *skn, FImageCollection *images)
{ {
AddFaceToImageCollectionActual (skn, images, true); AddFaceToImageCollectionActual (skn, images, true);
@ -161,7 +109,26 @@ public:
{ {
DBaseStatusBar::Tick (); DBaseStatusBar::Tick ();
RandomNumber = M_Random (); 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) void Draw (EHudState state)
@ -183,7 +150,6 @@ public:
OldKeys = -1; OldKeys = -1;
memset (OldAmmo, 255, sizeof(OldAmmo)); memset (OldAmmo, 255, sizeof(OldAmmo));
memset (OldMaxAmmo, 255, sizeof(OldMaxAmmo)); memset (OldMaxAmmo, 255, sizeof(OldMaxAmmo));
OldFaceIndex = -1;
OldHealth = -1; OldHealth = -1;
OldArmor = -1; OldArmor = -1;
OldActiveAmmo = -1; OldActiveAmmo = -1;
@ -199,6 +165,20 @@ 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: private:
struct FDoomStatusBarTexture : public FTexture struct FDoomStatusBarTexture : public FTexture
{ {
@ -255,8 +235,6 @@ private:
StatusBarTex.Unload (); StatusBarTex.Unload ();
SB_state = screen->GetPageCount (); SB_state = screen->GetPageCount ();
FaceLastAttackDown = -1;
FacePriority = 0;
} }
void DrawMainBar () 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 () void DrawKeys ()
{ {
AInventory *item; AInventory *item;
@ -796,73 +742,34 @@ private:
bEvilGrin = true; bEvilGrin = true;
} }
// int UpdateState ()
// 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 i; int i;
angle_t badguyangle; angle_t badguyangle;
angle_t diffang; angle_t diffang;
if(CPlayer->health > 0)
if (FacePriority < 10)
{ {
// dead
if (CPlayer->health <= 0)
{
FacePriority = 9;
FaceIndex = ST_DEADFACE;
FaceCount = 1;
}
}
if (FacePriority < 9)
{
if (CPlayer->bonuscount)
{
// picking up bonus
if(bEvilGrin) if(bEvilGrin)
{ {
// evil grin if just picked up weapon if(CurrentState == NULL)
bEvilGrin = false; bEvilGrin = false;
FacePriority = 8; else if(CPlayer->bonuscount)
FaceCount = ST_EVILGRINCOUNT;
FaceIndex = CalcPainOffset() + ST_EVILGRINOFFSET;
}
}
else
{ {
// This happens when a weapon is added to the inventory SetMugShotState("grin", false);
// by other means than being picked up. return 0;
bEvilGrin = false;
} }
} }
if (FacePriority < 8) if (CPlayer->damagecount)
{ {
if (CPlayer->damagecount int damageAngle = 1;
&& CPlayer->attacker if(CPlayer->attacker && CPlayer->attacker != CPlayer->mo)
&& CPlayer->attacker != CPlayer->mo)
{ {
// being attacked if(CPlayer->mo != NULL)
FacePriority = 7;
if (FaceHealth != -9999 && FaceHealth - CPlayer->health > ST_MUCHPAIN)
{ {
FaceCount = ST_TURNCOUNT; //The next 12 lines is from the Doom statusbar code.
FaceIndex = CalcPainOffset() + ST_OUCHOFFSET; badguyangle = R_PointToAngle2(CPlayer->mo->x, CPlayer->mo->y, CPlayer->attacker->x, CPlayer->attacker->y);
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) if(badguyangle > CPlayer->mo->angle)
{ {
// whether right or left // whether right or left
@ -875,95 +782,108 @@ private:
diffang = CPlayer->mo->angle - badguyangle; diffang = CPlayer->mo->angle - badguyangle;
i = diffang <= ANG180; i = diffang <= ANG180;
} // confusing, aint it? } // confusing, aint it?
if(i && diffang >= ANG45)
FaceCount = ST_TURNCOUNT;
FaceIndex = CalcPainOffset();
if (diffang < ANG45)
{ {
// head-on damageAngle = 0;
FaceIndex += ST_RAMPAGEOFFSET;
} }
else if (i) else if(!i && diffang >= ANG45)
{ {
// turn face right damageAngle = 2;
FaceIndex += ST_TURNOFFSET;
} }
}
}
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 else
{ {
// turn face left const char* stateName = new char[5];
FaceIndex += ST_TURNOFFSET+1; if (FaceHealth != -1 && CPlayer->health - FaceHealth > 20)
} stateName = "ouch";
}
}
}
if (FacePriority < 7)
{
// getting hurt because of your own damn stupidity
if (CPlayer->damagecount)
{
if (OldHealth != -1 && CPlayer->health - OldHealth > ST_MUCHPAIN)
{
FacePriority = 7;
FaceCount = ST_TURNCOUNT;
FaceIndex = CalcPainOffset() + ST_OUCHOFFSET;
}
else else
{ stateName = "pain";
FacePriority = 6; char* fullStateName = new char[sizeof(stateName)+sizeof((const char*) CPlayer->LastDamageType) + 1];
FaceCount = ST_TURNCOUNT; sprintf(fullStateName, "%s.%s", stateName, (const char*) CPlayer->LastDamageType);
FaceIndex = CalcPainOffset() + ST_RAMPAGEOFFSET; if(FindMugShotState(fullStateName) != NULL)
SetMugShotState(fullStateName);
else
SetMugShotState(stateName);
return LastDamageAngle;
}
} }
if(RampageTimer == ST_RAMPAGEDELAY)
{
SetMugShotState("rampage", true);
return 0;
} }
} if(!bEvilGrin)
if (FacePriority < 6)
{ {
// rapid firing if((CPlayer->cheats & CF_GODMODE) || (CPlayer->mo != NULL && CPlayer->mo->flags2 & MF2_INVULNERABLE))
if ((CPlayer->cmd.ucmd.buttons & (BT_ATTACK|BT_ALTATTACK)) && !(CPlayer->cheats & (CF_FROZEN | CF_TOTALLYFROZEN))) SetMugShotState("god");
{ else
if (FaceLastAttackDown == -1) SetMugShotState("normal");
FaceLastAttackDown = ST_RAMPAGEDELAY;
else if (!--FaceLastAttackDown)
{
FacePriority = 5;
FaceIndex = CalcPainOffset() + ST_RAMPAGEOFFSET;
FaceCount = 1;
FaceLastAttackDown = 1;
} }
} }
else else
{ {
FaceLastAttackDown = -1; 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;
} }
if (FacePriority < 5) void DrawFace ()
{ {
// invulnerability if (CPlayer->mo->InvSel == NULL || (level.flags & LEVEL_NOINVENTORYBAR))
if ((CPlayer->cheats & CF_GODMODE)
|| (CPlayer->mo != NULL && CPlayer->mo->flags2 & MF2_INVULNERABLE))
{ {
FacePriority = 4; int angle = UpdateState();
FaceIndex = ST_GODFACE; int level = 0;
FaceCount = 1; for(level = 0;CPlayer->health < (4-level)*(CPlayer->mo->GetMaxHealth()/5);level++);
if(CurrentState != NULL)
{
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);
} }
} }
// look left or look right if the facecount has timed out
if (!FaceCount)
{
FaceIndex = CalcPainOffset() + (RandomNumber % 3);
FaceCount = ST_STRAIGHTFACECOUNT;
FacePriority = 0;
} }
else
FaceCount--; {
FaceHealth = CPlayer->health; 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);
}
}
} }
enum enum
@ -995,15 +915,11 @@ private:
}; };
FImageCollection Images; FImageCollection Images;
FImageCollection Faces;
int BigWidth; int BigWidth;
int BigHeight; int BigHeight;
int FaceIndex;
int FaceCount;
int RandomNumber; int RandomNumber;
int OldFaceIndex;
BYTE OldArms[6]; BYTE OldArms[6];
int OldKeys; int OldKeys;
int OldAmmo[4]; int OldAmmo[4];
@ -1012,9 +928,6 @@ private:
int OldArmor; int OldArmor;
int OldActiveAmmo; int OldActiveAmmo;
int OldFrags; int OldFrags;
int FaceHealth;
int FaceLastAttackDown;
int FacePriority;
char HealthRefresh; char HealthRefresh;
char ArmorRefresh; char ArmorRefresh;
@ -1026,7 +939,13 @@ private:
char FaceRefresh; char FaceRefresh;
char KeysRefresh; char KeysRefresh;
//Mugshot
MugShotState *CurrentState;
int RampageTimer;
int LastDamageAngle;
int FaceHealth;
bool bEvilGrin; bool bEvilGrin;
bool bDamageFaceActive;
}; };
IMPLEMENT_CLASS(DDoomStatusBar) IMPLEMENT_CLASS(DDoomStatusBar)

View file

@ -2,26 +2,6 @@
#include "a_weaponpiece.h" #include "a_weaponpiece.h"
#include "doomstat.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) IMPLEMENT_STATELESS_ACTOR (AWeaponHolder, Any, -1, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR) PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR)
PROP_Inventory_FlagsSet (IF_UNDROPPABLE) PROP_Inventory_FlagsSet (IF_UNDROPPABLE)

View file

@ -16,3 +16,20 @@ public:
const PClass * WeaponClass; const PClass * WeaponClass;
TObjPtr<AWeapon> FullWeapon; TObjPtr<AWeapon> 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;
}
};

View file

@ -218,6 +218,7 @@ public:
virtual void ShowPop (int popnum); virtual void ShowPop (int popnum);
virtual void ReceivedWeapon (AWeapon *weapon); virtual void ReceivedWeapon (AWeapon *weapon);
virtual bool MustDrawLog(EHudState state); virtual bool MustDrawLog(EHudState state);
virtual void SetMugShotState (const char* stateName, bool waitTillDone=false) {}
void DrawLog(); void DrawLog();
protected: protected:

View file

@ -346,6 +346,8 @@ enum //Bar key words
SBARINFO_PLAYERCLASS, SBARINFO_PLAYERCLASS,
SBARINFO_ASPECTRATIO, SBARINFO_ASPECTRATIO,
SBARINFO_ISSELECTED, SBARINFO_ISSELECTED,
SBARINFO_USESSECONDARYAMMO,
SBARINFO_HASWEAPONPIECE,
SBARINFO_WEAPONAMMO, SBARINFO_WEAPONAMMO,
SBARINFO_ININVENTORY, SBARINFO_ININVENTORY,
}; };

View file

@ -52,6 +52,7 @@
#include "gi.h" #include "gi.h"
#include "r_translate.h" #include "r_translate.h"
#include "r_main.h" #include "r_main.h"
#include "a_weaponpiece.h"
static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic. static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic.
@ -1134,6 +1135,33 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a
} }
} }
break; 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<AWeaponHolder*>(inv);
if(hold->PieceWeapon == weapon)
{
if(hold->PieceMask & (1 << (cmd.value-1)))
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
break;
}
}
}
break;
}
case SBARINFO_WEAPONAMMO: case SBARINFO_WEAPONAMMO:
if(CPlayer->ReadyWeapon != NULL) if(CPlayer->ReadyWeapon != NULL)
{ {
@ -1146,7 +1174,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a
bool usesammo2 = (AmmoType2 != NULL); bool usesammo2 = (AmmoType2 != NULL);
if(!(cmd.flags & SBARINFOEVENT_NOT) && !usesammo1 && !usesammo2) //if the weapon doesn't use ammo don't go though the trouble. 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; break;
} }
//Or means only 1 ammo type needs to match and means both need to match. //Or means only 1 ammo type needs to match and means both need to match.
@ -1333,6 +1361,7 @@ int DSBarInfo::updateState(bool xdth, bool animatedgodmode)
{ {
if(weaponGrin) if(weaponGrin)
{ {
if(currentState == NULL)
weaponGrin = false; weaponGrin = false;
if(CPlayer->bonuscount) if(CPlayer->bonuscount)
{ {
@ -1414,15 +1443,18 @@ int DSBarInfo::updateState(bool xdth, bool animatedgodmode)
return 0; return 0;
} }
if(!weaponGrin)
{
if((CPlayer->cheats & CF_GODMODE) || (CPlayer->mo != NULL && CPlayer->mo->flags2 & MF2_INVULNERABLE)) if((CPlayer->cheats & CF_GODMODE) || (CPlayer->mo != NULL && CPlayer->mo->flags2 & MF2_INVULNERABLE))
{ {
if(animatedgodmode) if(animatedgodmode)
SetMugShotState("godanimated", true); SetMugShotState("godanimated");
else else
SetMugShotState("god", true); SetMugShotState("god");
} }
else else
SetMugShotState("normal", true); SetMugShotState("normal");
}
} }
else else
{ {
@ -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); 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 else
{ {
DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y, xOffset, yOffset, alpha); DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y, xOffset, yOffset, alpha);

View file

@ -95,6 +95,8 @@ static const char *SBarInfoRoutineLevel[] =
"playerclass", "playerclass",
"aspectratio", "aspectratio",
"isselected", "isselected",
"usessecondaryammo",
"hasweaponpiece",
"weaponammo", //event "weaponammo", //event
"ininventory", "ininventory",
NULL NULL
@ -705,7 +707,11 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block)
{ {
cmd.special = GAME_Heretic; 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(','); sc.MustGetToken(',');
while(sc.CheckToken(TK_Identifier)) while(sc.CheckToken(TK_Identifier))
@ -1053,6 +1059,33 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block)
sc.MustGetToken('{'); sc.MustGetToken('{');
this->ParseSBarInfoBlock(sc, cmd.subBlock); this->ParseSBarInfoBlock(sc, cmd.subBlock);
break; 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: case SBARINFO_WEAPONAMMO:
sc.MustGetToken(TK_Identifier); sc.MustGetToken(TK_Identifier);
if(sc.Compare("not")) if(sc.Compare("not"))

View file

@ -5334,10 +5334,7 @@ int DLevelScript::RunScript ()
} }
case PCD_SETMUGSHOTSTATE: case PCD_SETMUGSHOTSTATE:
if(StatusBar != NULL && StatusBar->IsKindOf(RUNTIME_CLASS(DSBarInfo))) StatusBar->SetMugShotState(FBehavior::StaticLookupString(STACK(1)));
{
static_cast<DSBarInfo*>(StatusBar)->SetMugShotState(FBehavior::StaticLookupString(STACK(1)));
}
break; break;
case PCD_CHECKPLAYERCAMERA: case PCD_CHECKPLAYERCAMERA:

View file

@ -31,3 +31,17 @@ HUDFONT_RAVEN
8 IN8 8 IN8
9 IN9 9 IN9
} }
INDEXFONT_RAVEN
{
0 SMALLIN0
1 SMALLIN1
2 SMALLIN2
3 SMALLIN3
4 SMALLIN4
5 SMALLIN5
6 SMALLIN6
7 SMALLIN7
8 SMALLIN8
9 SMALLIN9
}