From 7b23f6eb8b400909c9aa889bdfe3fce605039eb2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 5 Apr 2008 07:06:26 +0000 Subject: [PATCH] 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) --- docs/rh-log.txt | 15 +++++ src/g_shared/sbarinfo.h | 39 ++++++------ src/g_shared/sbarinfo_display.cpp | 102 +++++++++++++++++++++--------- src/g_shared/sbarinfo_parser.cpp | 50 ++++++++++++++- 4 files changed, 155 insertions(+), 51 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index b1f4bf4d2..da7859cd4 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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) - Increased limit for demon/melee to 4. - Fixed: P_CheckSwitchRange accessed invalid memory when testing a one-sided diff --git a/src/g_shared/sbarinfo.h b/src/g_shared/sbarinfo.h index 217f89dd5..7d38c3249 100644 --- a/src/g_shared/sbarinfo.h +++ b/src/g_shared/sbarinfo.h @@ -183,22 +183,24 @@ enum //drawimage flags enum //drawnumber flags { - DRAWNUMBER_HEALTH = 1, - DRAWNUMBER_ARMOR = 2, - DRAWNUMBER_AMMO1 = 4, - DRAWNUMBER_AMMO2 = 8, - DRAWNUMBER_AMMO = 16, - DRAWNUMBER_AMMOCAPACITY = 32, - DRAWNUMBER_FRAGS = 64, - DRAWNUMBER_INVENTORY = 128, - DRAWNUMBER_KILLS = 256, - DRAWNUMBER_MONSTERS = 512, - DRAWNUMBER_ITEMS = 1024, - DRAWNUMBER_TOTALITEMS = 2048, - DRAWNUMBER_SECRETS = 4096, - DRAWNUMBER_TOTALSECRETS = 8192, - DRAWNUMBER_ARMORCLASS = 16384, - DRAWNUMBER_GLOBALVAR = 32768, + DRAWNUMBER_HEALTH = 0x1, + DRAWNUMBER_ARMOR = 0x2, + DRAWNUMBER_AMMO1 = 0x4, + DRAWNUMBER_AMMO2 = 0x8, + DRAWNUMBER_AMMO = 0x10, + DRAWNUMBER_AMMOCAPACITY = 0x20, + DRAWNUMBER_FRAGS = 0x40, + DRAWNUMBER_INVENTORY = 0x80, + DRAWNUMBER_KILLS = 0x100, + DRAWNUMBER_MONSTERS = 0x200, + DRAWNUMBER_ITEMS = 0x400, + DRAWNUMBER_TOTALITEMS = 0x800, + DRAWNUMBER_SECRETS = 0x1000, + DRAWNUMBER_TOTALSECRETS = 0x2000, + DRAWNUMBER_ARMORCLASS = 0x4000, + DRAWNUMBER_GLOBALVAR = 0x8000, + DRAWNUMBER_GLOBALARRAY = 0x10000, + DRAWNUMBER_FILLZEROS = 0x20000, }; enum //drawbar flags (will go into special2) @@ -305,6 +307,7 @@ enum //Bar key words SBARINFO_GAMEMODE, SBARINFO_PLAYERCLASS, SBARINFO_ASPECTRATIO, + SBARINFO_ISSELECTED, SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, }; @@ -338,9 +341,9 @@ public: void SetMugShotState(const char* stateName, bool waitTillDone=false); private: 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 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); int updateState(bool xdth, bool animatedgodmode); void DrawInventoryBar(int type, int num, int x, int y, bool alwaysshow, diff --git a/src/g_shared/sbarinfo_display.cpp b/src/g_shared/sbarinfo_display.cpp index 5b2fe7c27..949eab836 100644 --- a/src/g_shared/sbarinfo_display.cpp +++ b/src/g_shared/sbarinfo_display.cpp @@ -559,7 +559,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block) { 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); } @@ -571,7 +571,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block) { drawingFont = cmd.font; } - if(cmd.flags == DRAWNUMBER_HEALTH) + if(cmd.flags & DRAWNUMBER_HEALTH) { value = health; if(SBarInfoScript->lowerHealthCap && cmd.value < 0) //health shouldn't display negatives @@ -579,11 +579,11 @@ void DSBarInfo::doCommands(SBarInfoBlock &block) value = 0; } } - else if(cmd.flags == DRAWNUMBER_ARMOR) + else if(cmd.flags & DRAWNUMBER_ARMOR) { value = armorAmount; } - else if(cmd.flags == DRAWNUMBER_AMMO1) + else if(cmd.flags & DRAWNUMBER_AMMO1) { value = ammocount1; if(ammo1 == NULL) //no ammo, do not draw @@ -591,7 +591,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block) continue; } } - else if(cmd.flags == DRAWNUMBER_AMMO2) + else if(cmd.flags & DRAWNUMBER_AMMO2) { value = ammocount2; if(ammo2 == NULL) //no ammo, do not draw @@ -599,7 +599,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block) continue; } } - else if(cmd.flags == DRAWNUMBER_AMMO) + else if(cmd.flags & DRAWNUMBER_AMMO) { const PClass* ammo = PClass::FindClass(cmd.string[0]); AInventory* item = CPlayer->mo->FindInventory(ammo); @@ -612,7 +612,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block) value = 0; } } - else if(cmd.flags == DRAWNUMBER_AMMOCAPACITY) + else if(cmd.flags & DRAWNUMBER_AMMOCAPACITY) { const PClass* ammo = PClass::FindClass(cmd.string[0]); AInventory* item = CPlayer->mo->FindInventory(ammo); @@ -625,21 +625,21 @@ void DSBarInfo::doCommands(SBarInfoBlock &block) value = ((AInventory *)GetDefaultByType(ammo))->MaxAmount; } } - else if(cmd.flags == DRAWNUMBER_FRAGS) + else if(cmd.flags & DRAWNUMBER_FRAGS) value = CPlayer->fragcount; - else if(cmd.flags == DRAWNUMBER_KILLS) + else if(cmd.flags & DRAWNUMBER_KILLS) value = level.killed_monsters; - else if(cmd.flags == DRAWNUMBER_MONSTERS) + else if(cmd.flags & DRAWNUMBER_MONSTERS) value = level.total_monsters; - else if(cmd.flags == DRAWNUMBER_ITEMS) + else if(cmd.flags & DRAWNUMBER_ITEMS) value = level.found_items; - else if(cmd.flags == DRAWNUMBER_TOTALITEMS) + else if(cmd.flags & DRAWNUMBER_TOTALITEMS) value = level.total_items; - else if(cmd.flags == DRAWNUMBER_SECRETS) + else if(cmd.flags & DRAWNUMBER_SECRETS) value = level.found_secrets; - else if(cmd.flags == DRAWNUMBER_TOTALSECRETS) + else if(cmd.flags & DRAWNUMBER_TOTALSECRETS) value = level.total_secrets; - else if(cmd.flags == DRAWNUMBER_ARMORCLASS) + else if(cmd.flags & DRAWNUMBER_ARMORCLASS) { AHexenArmor *harmor = CPlayer->mo->FindInventory(); if(harmor != NULL) @@ -654,9 +654,11 @@ void DSBarInfo::doCommands(SBarInfoBlock &block) } value /= (5*FRACUNIT); } - else if(cmd.flags == DRAWNUMBER_GLOBALVAR) + else if(cmd.flags & DRAWNUMBER_GLOBALVAR) 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])); if(item != NULL) @@ -668,12 +670,13 @@ void DSBarInfo::doCommands(SBarInfoBlock &block) value = 0; } } - if(cmd.special3 != -1 && cmd.value <= cmd.special3) //low - DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation2, cmd.special2); - else if(cmd.special4 != -1 && cmd.value >= cmd.special4) //high - DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation3, cmd.special2); + bool fillzeros = !!(cmd.flags & DRAWNUMBER_FILLZEROS); + if(cmd.special3 != -1 && value <= cmd.special3) //low + DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation2, cmd.special2, fillzeros); + else if(cmd.special4 != -1 && value >= cmd.special4) //high + DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation3, cmd.special2, fillzeros); 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; } case SBARINFO_DRAWMUGSHOT: @@ -1079,6 +1082,27 @@ void DSBarInfo::doCommands(SBarInfoBlock &block) doCommands(cmd.subBlock); } 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: if(CPlayer->ReadyWeapon != NULL) { @@ -1162,8 +1186,9 @@ void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int flags) x += ST_X; y += ST_Y; int w = texture->GetScaledWidth(); - int h = texture->GetScaledHeight(); + int h = texture->GetScaledHeight() + y; screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true); + h -= y; if((flags & DRAWIMAGE_TRANSLATABLE)) { 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 -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; 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); + 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') x -= int(drawingFont->StringWidth(value)+(spacing * value.Len())); 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) { - 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); 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) { - DrawImage(Images[invBarOffset + imgSELECTBOX], x+i*31, y+29); + DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y+29); } else { - DrawImage(Images[invBarOffset + imgSELECTBOX], x+i*31, y); + DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y); } } } 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? if (!noArrows && CPlayer->mo->FirstInv() != CPlayer->mo->InvFirst) { - DrawImage (Images[!(gametic & 4) ? + DrawGraphic(Images[!(gametic & 4) ? invBarOffset + imgINVLFGEM1 : invBarOffset + imgINVLFGEM2], x-12, y); } // Is there something to the right? if (!noArrows && item != NULL) { - DrawImage (Images[!(gametic & 4) ? + DrawGraphic(Images[!(gametic & 4) ? invBarOffset + imgINVRTGEM1 : invBarOffset + imgINVRTGEM2], x+num*31+2, y); } } diff --git a/src/g_shared/sbarinfo_parser.cpp b/src/g_shared/sbarinfo_parser.cpp index 08839b19c..fb87786cb 100644 --- a/src/g_shared/sbarinfo_parser.cpp +++ b/src/g_shared/sbarinfo_parser.cpp @@ -93,6 +93,7 @@ static const char *SBarInfoRoutineLevel[] = "gamemode", "playerclass", "aspectratio", + "isselected", "weaponammo", //event "ininventory", NULL @@ -490,6 +491,14 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) sc.ScriptError("Global variable number out of range: %d", 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 { cmd.flags = DRAWNUMBER_INVENTORY; @@ -503,6 +512,18 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) } 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); if(sc.CheckToken(',')) { @@ -948,6 +969,33 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) sc.MustGetToken('{'); this->ParseSBarInfoBlock(sc, cmd.subBlock); 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: sc.MustGetToken(TK_Identifier); if(sc.Compare("not")) @@ -980,7 +1028,6 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) this->ParseSBarInfoBlock(sc, cmd.subBlock); break; case SBARINFO_ININVENTORY: - { sc.MustGetToken(TK_Identifier); if(sc.Compare("not")) { @@ -1011,7 +1058,6 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) sc.MustGetToken('{'); this->ParseSBarInfoBlock(sc, cmd.subBlock); break; - } } block.commands.Push(cmd); }