SBarInfo Update #16:

- Added: fillzeros flag for drawnumber.  When set the string will always have
  a length of the specified size and zeros will fill in for the missing places.
  If the number is negative the negative sign will take the place of the last
  digit.
- Added: globalarray type to drawnumber which will display the value in a
  global array with the index set to the player's number.  Untested.
- Added: isselected command to SBarInfo.
- Fixed: Bi and Tri colored numbers didn't work.
- Fixed: Crash when using nullimage as the last image in drawswitchableimage.
- Applied Graf suggestion to include the y coord when calulating heights to fix
  most of the gaps caused by round off errors.  At least for now anyways and it
  is only applied for drawimage.
- SBarInfo inventory bars have been converted to use screen->DrawTexture() 

SVN r881 (trunk)
This commit is contained in:
Christoph Oelckers 2008-04-05 07:06:26 +00:00
parent 69002580e6
commit 7b23f6eb8b
4 changed files with 155 additions and 51 deletions

View file

@ -1,3 +1,18 @@
April 5, 2008 (SBarInfo Update #16)
- Added: fillzeros flag for drawnumber. When set the string will always have
a length of the specified size and zeros will fill in for the missing places.
If the number is negative the negative sign will take the place of the last
digit.
- Added: globalarray type to drawnumber which will display the value in a
global array with the index set to the player's number. Untested.
- Added: isselected command to SBarInfo.
- Fixed: Bi and Tri colored numbers didn't work.
- Fixed: Crash when using nullimage as the last image in drawswitchableimage.
- Applied Graf suggestion to include the y coord when calulating heights to fix
most of the gaps caused by round off errors. At least for now anyways and it
is only applied for drawimage.
- SBarInfo inventory bars have been converted to use screen->DrawTexture()
April 4, 2008 (Changes by Graf Zahl) April 4, 2008 (Changes by Graf Zahl)
- Increased limit for demon/melee to 4. - Increased limit for demon/melee to 4.
- Fixed: P_CheckSwitchRange accessed invalid memory when testing a one-sided - Fixed: P_CheckSwitchRange accessed invalid memory when testing a one-sided

View file

@ -183,22 +183,24 @@ enum //drawimage flags
enum //drawnumber flags enum //drawnumber flags
{ {
DRAWNUMBER_HEALTH = 1, DRAWNUMBER_HEALTH = 0x1,
DRAWNUMBER_ARMOR = 2, DRAWNUMBER_ARMOR = 0x2,
DRAWNUMBER_AMMO1 = 4, DRAWNUMBER_AMMO1 = 0x4,
DRAWNUMBER_AMMO2 = 8, DRAWNUMBER_AMMO2 = 0x8,
DRAWNUMBER_AMMO = 16, DRAWNUMBER_AMMO = 0x10,
DRAWNUMBER_AMMOCAPACITY = 32, DRAWNUMBER_AMMOCAPACITY = 0x20,
DRAWNUMBER_FRAGS = 64, DRAWNUMBER_FRAGS = 0x40,
DRAWNUMBER_INVENTORY = 128, DRAWNUMBER_INVENTORY = 0x80,
DRAWNUMBER_KILLS = 256, DRAWNUMBER_KILLS = 0x100,
DRAWNUMBER_MONSTERS = 512, DRAWNUMBER_MONSTERS = 0x200,
DRAWNUMBER_ITEMS = 1024, DRAWNUMBER_ITEMS = 0x400,
DRAWNUMBER_TOTALITEMS = 2048, DRAWNUMBER_TOTALITEMS = 0x800,
DRAWNUMBER_SECRETS = 4096, DRAWNUMBER_SECRETS = 0x1000,
DRAWNUMBER_TOTALSECRETS = 8192, DRAWNUMBER_TOTALSECRETS = 0x2000,
DRAWNUMBER_ARMORCLASS = 16384, DRAWNUMBER_ARMORCLASS = 0x4000,
DRAWNUMBER_GLOBALVAR = 32768, DRAWNUMBER_GLOBALVAR = 0x8000,
DRAWNUMBER_GLOBALARRAY = 0x10000,
DRAWNUMBER_FILLZEROS = 0x20000,
}; };
enum //drawbar flags (will go into special2) enum //drawbar flags (will go into special2)
@ -305,6 +307,7 @@ enum //Bar key words
SBARINFO_GAMEMODE, SBARINFO_GAMEMODE,
SBARINFO_PLAYERCLASS, SBARINFO_PLAYERCLASS,
SBARINFO_ASPECTRATIO, SBARINFO_ASPECTRATIO,
SBARINFO_ISSELECTED,
SBARINFO_WEAPONAMMO, SBARINFO_WEAPONAMMO,
SBARINFO_ININVENTORY, SBARINFO_ININVENTORY,
}; };
@ -338,9 +341,9 @@ public:
void SetMugShotState(const char* stateName, bool waitTillDone=false); void SetMugShotState(const char* stateName, bool waitTillDone=false);
private: private:
void doCommands(SBarInfoBlock &block); void doCommands(SBarInfoBlock &block);
void DrawGraphic(FTexture* texture, int x, int y, int flags); void DrawGraphic(FTexture* texture, int x, int y, int flags=0);
void DrawString(const char* str, int x, int y, EColorRange translation, int spacing=0); void DrawString(const char* str, int x, int y, EColorRange translation, int spacing=0);
void DrawNumber(int num, int len, int x, int y, EColorRange translation, int spacing=0); void DrawNumber(int num, int len, int x, int y, EColorRange translation, int spacing=0, bool fillzeros=false);
void DrawFace(FString &defaultFace, int accuracy, bool xdth, bool animatedgodmode, int x, int y); void DrawFace(FString &defaultFace, int accuracy, bool xdth, bool animatedgodmode, int x, int y);
int updateState(bool xdth, bool animatedgodmode); int updateState(bool xdth, bool animatedgodmode);
void DrawInventoryBar(int type, int num, int x, int y, bool alwaysshow, void DrawInventoryBar(int type, int num, int x, int y, bool alwaysshow,

View file

@ -559,7 +559,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
{ {
DrawGraphic(TexMan[cmd.sprite], cmd.x, cmd.y, cmd.flags); DrawGraphic(TexMan[cmd.sprite], cmd.x, cmd.y, cmd.flags);
} }
else else if(cmd.sprite != -1)
{ {
DrawGraphic(Images[cmd.sprite], cmd.x, cmd.y, cmd.flags); DrawGraphic(Images[cmd.sprite], cmd.x, cmd.y, cmd.flags);
} }
@ -571,7 +571,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
{ {
drawingFont = cmd.font; drawingFont = cmd.font;
} }
if(cmd.flags == DRAWNUMBER_HEALTH) if(cmd.flags & DRAWNUMBER_HEALTH)
{ {
value = health; value = health;
if(SBarInfoScript->lowerHealthCap && cmd.value < 0) //health shouldn't display negatives if(SBarInfoScript->lowerHealthCap && cmd.value < 0) //health shouldn't display negatives
@ -579,11 +579,11 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
value = 0; value = 0;
} }
} }
else if(cmd.flags == DRAWNUMBER_ARMOR) else if(cmd.flags & DRAWNUMBER_ARMOR)
{ {
value = armorAmount; value = armorAmount;
} }
else if(cmd.flags == DRAWNUMBER_AMMO1) else if(cmd.flags & DRAWNUMBER_AMMO1)
{ {
value = ammocount1; value = ammocount1;
if(ammo1 == NULL) //no ammo, do not draw if(ammo1 == NULL) //no ammo, do not draw
@ -591,7 +591,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
continue; continue;
} }
} }
else if(cmd.flags == DRAWNUMBER_AMMO2) else if(cmd.flags & DRAWNUMBER_AMMO2)
{ {
value = ammocount2; value = ammocount2;
if(ammo2 == NULL) //no ammo, do not draw if(ammo2 == NULL) //no ammo, do not draw
@ -599,7 +599,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
continue; continue;
} }
} }
else if(cmd.flags == DRAWNUMBER_AMMO) else if(cmd.flags & DRAWNUMBER_AMMO)
{ {
const PClass* ammo = PClass::FindClass(cmd.string[0]); const PClass* ammo = PClass::FindClass(cmd.string[0]);
AInventory* item = CPlayer->mo->FindInventory(ammo); AInventory* item = CPlayer->mo->FindInventory(ammo);
@ -612,7 +612,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
value = 0; value = 0;
} }
} }
else if(cmd.flags == DRAWNUMBER_AMMOCAPACITY) else if(cmd.flags & DRAWNUMBER_AMMOCAPACITY)
{ {
const PClass* ammo = PClass::FindClass(cmd.string[0]); const PClass* ammo = PClass::FindClass(cmd.string[0]);
AInventory* item = CPlayer->mo->FindInventory(ammo); AInventory* item = CPlayer->mo->FindInventory(ammo);
@ -625,21 +625,21 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
value = ((AInventory *)GetDefaultByType(ammo))->MaxAmount; value = ((AInventory *)GetDefaultByType(ammo))->MaxAmount;
} }
} }
else if(cmd.flags == DRAWNUMBER_FRAGS) else if(cmd.flags & DRAWNUMBER_FRAGS)
value = CPlayer->fragcount; value = CPlayer->fragcount;
else if(cmd.flags == DRAWNUMBER_KILLS) else if(cmd.flags & DRAWNUMBER_KILLS)
value = level.killed_monsters; value = level.killed_monsters;
else if(cmd.flags == DRAWNUMBER_MONSTERS) else if(cmd.flags & DRAWNUMBER_MONSTERS)
value = level.total_monsters; value = level.total_monsters;
else if(cmd.flags == DRAWNUMBER_ITEMS) else if(cmd.flags & DRAWNUMBER_ITEMS)
value = level.found_items; value = level.found_items;
else if(cmd.flags == DRAWNUMBER_TOTALITEMS) else if(cmd.flags & DRAWNUMBER_TOTALITEMS)
value = level.total_items; value = level.total_items;
else if(cmd.flags == DRAWNUMBER_SECRETS) else if(cmd.flags & DRAWNUMBER_SECRETS)
value = level.found_secrets; value = level.found_secrets;
else if(cmd.flags == DRAWNUMBER_TOTALSECRETS) else if(cmd.flags & DRAWNUMBER_TOTALSECRETS)
value = level.total_secrets; value = level.total_secrets;
else if(cmd.flags == DRAWNUMBER_ARMORCLASS) else if(cmd.flags & DRAWNUMBER_ARMORCLASS)
{ {
AHexenArmor *harmor = CPlayer->mo->FindInventory<AHexenArmor>(); AHexenArmor *harmor = CPlayer->mo->FindInventory<AHexenArmor>();
if(harmor != NULL) if(harmor != NULL)
@ -654,9 +654,11 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
} }
value /= (5*FRACUNIT); value /= (5*FRACUNIT);
} }
else if(cmd.flags == DRAWNUMBER_GLOBALVAR) else if(cmd.flags & DRAWNUMBER_GLOBALVAR)
value = ACS_GlobalVars[cmd.value]; value = ACS_GlobalVars[cmd.value];
else if(cmd.flags == DRAWNUMBER_INVENTORY) else if(cmd.flags & DRAWNUMBER_GLOBALARRAY)
value = ACS_GlobalArrays[cmd.value][consoleplayer];
else if(cmd.flags & DRAWNUMBER_INVENTORY)
{ {
AInventory* item = CPlayer->mo->FindInventory(PClass::FindClass(cmd.string[0])); AInventory* item = CPlayer->mo->FindInventory(PClass::FindClass(cmd.string[0]));
if(item != NULL) if(item != NULL)
@ -668,12 +670,13 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
value = 0; value = 0;
} }
} }
if(cmd.special3 != -1 && cmd.value <= cmd.special3) //low bool fillzeros = !!(cmd.flags & DRAWNUMBER_FILLZEROS);
DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation2, cmd.special2); if(cmd.special3 != -1 && value <= cmd.special3) //low
else if(cmd.special4 != -1 && cmd.value >= cmd.special4) //high DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation2, cmd.special2, fillzeros);
DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation3, cmd.special2); else if(cmd.special4 != -1 && value >= cmd.special4) //high
DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation3, cmd.special2, fillzeros);
else else
DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation, cmd.special2); DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation, cmd.special2, fillzeros);
break; break;
} }
case SBARINFO_DRAWMUGSHOT: case SBARINFO_DRAWMUGSHOT:
@ -1079,6 +1082,27 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
doCommands(cmd.subBlock); doCommands(cmd.subBlock);
} }
break; break;
case SBARINFO_ISSELECTED:
if(CPlayer->ReadyWeapon != NULL)
{
const PClass *weapon1 = PClass::FindClass(cmd.string[0]);
const PClass *weapon2 = PClass::FindClass(cmd.string[1]);
if(weapon2 != NULL)
{
if((cmd.flags & SBARINFOEVENT_NOT) && (weapon1 != CPlayer->ReadyWeapon->GetSpecies() && weapon2 != CPlayer->ReadyWeapon->GetSpecies()))
doCommands(cmd.subBlock);
else if(!(cmd.flags & SBARINFOEVENT_NOT) && (weapon1 == CPlayer->ReadyWeapon->GetSpecies() || weapon2 == CPlayer->ReadyWeapon->GetSpecies()))
doCommands(cmd.subBlock);
}
else
{
if(!(cmd.flags & SBARINFOEVENT_NOT) && weapon1 == CPlayer->ReadyWeapon->GetSpecies())
doCommands(cmd.subBlock);
else if((cmd.flags & SBARINFOEVENT_NOT) && weapon1 != CPlayer->ReadyWeapon->GetSpecies())
doCommands(cmd.subBlock);
}
}
break;
case SBARINFO_WEAPONAMMO: case SBARINFO_WEAPONAMMO:
if(CPlayer->ReadyWeapon != NULL) if(CPlayer->ReadyWeapon != NULL)
{ {
@ -1162,8 +1186,9 @@ void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int flags)
x += ST_X; x += ST_X;
y += ST_Y; y += ST_Y;
int w = texture->GetScaledWidth(); int w = texture->GetScaledWidth();
int h = texture->GetScaledHeight(); int h = texture->GetScaledHeight() + y;
screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true); screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true);
h -= y;
if((flags & DRAWIMAGE_TRANSLATABLE)) if((flags & DRAWIMAGE_TRANSLATABLE))
{ {
screen->DrawTexture(texture, x, y, screen->DrawTexture(texture, x, y,
@ -1224,12 +1249,27 @@ void DSBarInfo::DrawString(const char* str, int x, int y, EColorRange translatio
} }
//draws the specified number up to len digits //draws the specified number up to len digits
void DSBarInfo::DrawNumber(int num, int len, int x, int y, EColorRange translation, int spacing) void DSBarInfo::DrawNumber(int num, int len, int x, int y, EColorRange translation, int spacing, bool fillzeros)
{ {
FString value; FString value;
int maxval = (int) ceil(pow(10., len))-1; int maxval = (int) ceil(pow(10., len))-1;
num = clamp(num, -maxval, maxval); if(!fillzeros || len == 1)
num = clamp(num, -maxval, maxval);
else //The community wanted negatives to take the last digit, but we can only do this if there is room
num = clamp(num, (int) -(ceil(pow(10., len-1))-1), maxval);
value.Format("%d", num); value.Format("%d", num);
if(fillzeros)
{
if(num < 0) //We don't want the negative just yet
value.Format("%d", -num);
while(fillzeros && value.Len() < (unsigned int) len)
{
if(num < 0 && value.Len() == (unsigned int) (len-1))
value.Insert(0, "-");
else
value.Insert(0, "0");
}
}
if(SBarInfoScript->spacingCharacter == '\0') if(SBarInfoScript->spacingCharacter == '\0')
x -= int(drawingFont->StringWidth(value)+(spacing * value.Len())); x -= int(drawingFont->StringWidth(value)+(spacing * value.Len()));
else //monospaced so just multiplay the character size else //monospaced so just multiplay the character size
@ -1391,7 +1431,7 @@ void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, bool alwayssho
{ {
if(drawArtiboxes) if(drawArtiboxes)
{ {
DrawImage (Images[invBarOffset + imgARTIBOX], x+i*31, y); DrawGraphic(Images[invBarOffset + imgARTIBOX], x+i*31, y);
} }
DrawDimImage (TexMan(item->Icon), x+i*31, y, item->Amount <= 0); DrawDimImage (TexMan(item->Icon), x+i*31, y, item->Amount <= 0);
if(alwaysshowcounter || item->Amount != 1) if(alwaysshowcounter || item->Amount != 1)
@ -1402,28 +1442,28 @@ void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, bool alwayssho
{ {
if(type == GAME_Heretic) if(type == GAME_Heretic)
{ {
DrawImage(Images[invBarOffset + imgSELECTBOX], x+i*31, y+29); DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y+29);
} }
else else
{ {
DrawImage(Images[invBarOffset + imgSELECTBOX], x+i*31, y); DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y);
} }
} }
} }
for (; i < num && drawArtiboxes; ++i) for (; i < num && drawArtiboxes; ++i)
{ {
DrawImage (Images[invBarOffset + imgARTIBOX], x+i*31, y); DrawGraphic(Images[invBarOffset + imgARTIBOX], x+i*31, y);
} }
// Is there something to the left? // Is there something to the left?
if (!noArrows && CPlayer->mo->FirstInv() != CPlayer->mo->InvFirst) if (!noArrows && CPlayer->mo->FirstInv() != CPlayer->mo->InvFirst)
{ {
DrawImage (Images[!(gametic & 4) ? DrawGraphic(Images[!(gametic & 4) ?
invBarOffset + imgINVLFGEM1 : invBarOffset + imgINVLFGEM2], x-12, y); invBarOffset + imgINVLFGEM1 : invBarOffset + imgINVLFGEM2], x-12, y);
} }
// Is there something to the right? // Is there something to the right?
if (!noArrows && item != NULL) if (!noArrows && item != NULL)
{ {
DrawImage (Images[!(gametic & 4) ? DrawGraphic(Images[!(gametic & 4) ?
invBarOffset + imgINVRTGEM1 : invBarOffset + imgINVRTGEM2], x+num*31+2, y); invBarOffset + imgINVRTGEM1 : invBarOffset + imgINVRTGEM2], x+num*31+2, y);
} }
} }

View file

@ -93,6 +93,7 @@ static const char *SBarInfoRoutineLevel[] =
"gamemode", "gamemode",
"playerclass", "playerclass",
"aspectratio", "aspectratio",
"isselected",
"weaponammo", //event "weaponammo", //event
"ininventory", "ininventory",
NULL NULL
@ -490,6 +491,14 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block)
sc.ScriptError("Global variable number out of range: %d", sc.Number); sc.ScriptError("Global variable number out of range: %d", sc.Number);
cmd.value = sc.Number; cmd.value = sc.Number;
} }
else if(sc.Compare("globalarray")) //acts like variable[playernumber()]
{
cmd.flags += DRAWNUMBER_GLOBALARRAY;
sc.MustGetToken(TK_IntConst);
if(sc.Number < 0 || sc.Number >= NUM_GLOBALVARS)
sc.ScriptError("Global variable number out of range: %d", sc.Number);
cmd.value = sc.Number;
}
else else
{ {
cmd.flags = DRAWNUMBER_INVENTORY; cmd.flags = DRAWNUMBER_INVENTORY;
@ -503,6 +512,18 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block)
} }
sc.MustGetToken(','); sc.MustGetToken(',');
} }
while(sc.CheckToken(TK_Identifier))
{
if(sc.Compare("fillzeros"))
{
cmd.flags += DRAWNUMBER_FILLZEROS;
Printf("%d", cmd.flags);
}
else
sc.ScriptError("Unknown flag '%s'.", sc.String);
if(!sc.CheckToken('|'))
sc.MustGetToken(',');
}
this->getCoordinates(sc, cmd); this->getCoordinates(sc, cmd);
if(sc.CheckToken(',')) if(sc.CheckToken(','))
{ {
@ -948,6 +969,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_ISSELECTED:
if(sc.CheckToken(TK_Identifier))
{
if(sc.Compare("not"))
{
cmd.flags += SBARINFOEVENT_NOT;
}
else
sc.ScriptError("Expected 'not' got '%s' instead.", sc.String);
}
sc.MustGetToken(TK_StringConst);
for(int i = 0;i < 2;i++)
{
cmd.setString(sc, sc.String, i);
const PClass* item = PClass::FindClass(sc.String);
if(item == NULL || !RUNTIME_CLASS(AWeapon)->IsAncestorOf(item))
{
sc.ScriptError("'%s' is not a type of weapon.", sc.String);
}
if(sc.CheckToken(','))
sc.MustGetToken(TK_StringConst);
else
break;
}
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"))
@ -980,7 +1028,6 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block)
this->ParseSBarInfoBlock(sc, cmd.subBlock); this->ParseSBarInfoBlock(sc, cmd.subBlock);
break; break;
case SBARINFO_ININVENTORY: case SBARINFO_ININVENTORY:
{
sc.MustGetToken(TK_Identifier); sc.MustGetToken(TK_Identifier);
if(sc.Compare("not")) if(sc.Compare("not"))
{ {
@ -1011,7 +1058,6 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block)
sc.MustGetToken('{'); sc.MustGetToken('{');
this->ParseSBarInfoBlock(sc, cmd.subBlock); this->ParseSBarInfoBlock(sc, cmd.subBlock);
break; break;
}
} }
block.commands.Push(cmd); block.commands.Push(cmd);
} }