diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index 8ec68982d0..7262ba8be2 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -57,6 +57,7 @@ #include "g_level.h" #include "v_palette.h" #include "p_acs.h" +#include "gstrings.h" #define ADJUST_RELCENTER(x, y, outX, outY) \ if(x.RelCenter()) \ @@ -615,6 +616,13 @@ void SBarInfo::ParseSBarInfo(int lump) sc.MustGetToken(TK_IntConst); popup.speed = sc.Number; } + else if(sc.Compare("pushup")) + { + popup.transition = Popup::TRANSITION_PUSHUP; + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + popup.speed = sc.Number; + } else if(sc.Compare("fade")) { popup.transition = Popup::TRANSITION_FADE; @@ -722,78 +730,79 @@ SBarInfo::~SBarInfo() } //Popup -Popup::Popup() +Popup::Popup() : transition(TRANSITION_NONE), opened(false), moving(false), + height(320), width(200), speed(0), speed2(0), alpha(FRACUNIT), x(320), + y(200), displacementX(0), displacementY(0) { - transition = TRANSITION_NONE; - height = 320; - width = 200; - speed = 0; - x = 320; - y = 200; - alpha = FRACUNIT; - opened = false; - moving = false; } void Popup::init() { x = width; y = height; - if(transition == TRANSITION_SLIDEINBOTTOM) + switch(transition) { - x = 0; - } - else if(transition == TRANSITION_FADE) - { - alpha = 0; - x = 0; - y = 0; + case TRANSITION_SLIDEINBOTTOM: + case TRANSITION_PUSHUP: + x = 0; + break; + case TRANSITION_FADE: + alpha = 0; + x = 0; + y = 0; + break; + default: + break; } } void Popup::tick() { - if(transition == TRANSITION_SLIDEINBOTTOM) + switch(transition) { - if(moving) - { - if(opened) - y -= clamp(height + (y - height), 1, speed); + case TRANSITION_SLIDEINBOTTOM: + case TRANSITION_PUSHUP: + if(moving) + { + int oldY = y; + if(opened) + y -= clamp(height + (y - height), 1, speed); + else + y += clamp(height - y, 1, speed); + if(transition == TRANSITION_PUSHUP) + displacementY += y - oldY; + } + if(y != 0 && y != height) + moving = true; else - y += clamp(height - y, 1, speed); - } - if(y != 0 && y != height) - moving = true; - else - moving = false; - } - else if(transition == TRANSITION_FADE) - { - if(moving) - { - if(opened) - alpha = clamp(alpha + speed, 0, FRACUNIT); + moving = false; + break; + case TRANSITION_FADE: + if(moving) + { + if(opened) + alpha = clamp(alpha + speed, 0, FRACUNIT); + else + alpha = clamp(alpha - speed2, 0, FRACUNIT); + } + if(alpha == 0 || alpha == FRACUNIT) + moving = false; else - alpha = clamp(alpha - speed2, 0, FRACUNIT); - } - if(alpha == 0 || alpha == FRACUNIT) + moving = true; + break; + default: + if(opened) + { + y = 0; + x = 0; + } + else + { + y = height; + x = width; + } moving = false; - else - moving = true; - } - else - { - if(opened) - { - y = 0; - x = 0; - } - else - { - y = height; - x = width; - } - moving = false; + break; } } @@ -819,6 +828,16 @@ int Popup::getAlpha(int maxAlpha) return fixed_t((a * b) * FRACUNIT); } +int Popup::getXDisplacement() +{ + return displacementX; +} + +int Popup::getYDisplacement() +{ + return displacementY; +} + void Popup::open() { opened = true; @@ -914,8 +933,13 @@ public: armor = CPlayer->mo->FindInventory(); if(hud != lastHud) script->huds[hud]->Tick(NULL, this, true); - script->huds[hud]->Draw(NULL, this, 0, 0, FRACUNIT); + + if(currentPopup != POP_None && !script->huds[hud]->FullScreenOffsets()) + script->huds[hud]->Draw(NULL, this, script->popups[currentPopup-1].getXDisplacement(), script->popups[currentPopup-1].getYDisplacement(), FRACUNIT); + else + script->huds[hud]->Draw(NULL, this, 0, 0, FRACUNIT); lastHud = hud; + if(CPlayer->inventorytics > 0 && !(level.flags & LEVEL_NOINVENTORYBAR) && (state == HUD_StatusBar || state == HUD_Fullscreen)) { SBarInfoMainBlock *inventoryBar = state == HUD_StatusBar ? script->huds[STBAR_INVENTORY] : script->huds[STBAR_INVENTORYFULLSCREEN]; diff --git a/src/g_shared/sbarinfo.h b/src/g_shared/sbarinfo.h index 6fd7b1f0c2..03aae3434c 100644 --- a/src/g_shared/sbarinfo.h +++ b/src/g_shared/sbarinfo.h @@ -52,6 +52,7 @@ struct Popup { TRANSITION_NONE, TRANSITION_SLIDEINBOTTOM, + TRANSITION_PUSHUP, TRANSITION_FADE, }; @@ -65,6 +66,8 @@ struct Popup int alpha; int x; int y; + int displacementX; + int displacementY; Popup(); void init(); @@ -75,6 +78,8 @@ struct Popup int getXOffset(); int getYOffset(); int getAlpha(int maxAlpha=FRACUNIT); + int getXDisplacement(); + int getYDisplacement(); }; struct SBarInfo diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index 71444a8118..5123dfaac4 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -515,7 +515,7 @@ class CommandDrawString : public SBarInfoCommand public: CommandDrawString(SBarInfo *script) : SBarInfoCommand(script), shadow(false), spacing(0), font(NULL), translation(CR_UNTRANSLATED), - value(CONSTANT), valueArg(0) + cache(-1), strValue(CONSTANT), valueArgument(0) { } @@ -535,18 +535,50 @@ class CommandDrawString : public SBarInfoCommand if(sc.CheckToken(TK_Identifier)) { if(sc.Compare("levelname")) + strValue = LEVELNAME; + else if(sc.Compare("levellump")) + strValue = LEVELLUMP; + else if(sc.Compare("skillname")) + strValue = SKILLNAME; + else if(sc.Compare("playerclass")) + strValue = PLAYERCLASS; + else if(sc.Compare("playername")) + strValue = PLAYERNAME; + else if(sc.Compare("ammo1tag")) + strValue = AMMO1TAG; + else if(sc.Compare("ammo2tag")) + strValue = AMMO2TAG; + else if(sc.Compare("weapontag")) + strValue = WEAPONTAG; + else if(sc.Compare("inventorytag")) + strValue = INVENTORYTAG; + else if(sc.Compare("globalvar")) { - value = LEVELNAME; - valueArg = -1; + strValue = GLOBALVAR; + sc.MustGetToken(TK_IntConst); + if(sc.Number < 0 || sc.Number >= NUM_GLOBALVARS) + sc.ScriptError("Global variable number out of range: %d", sc.Number); + valueArgument = sc.Number; + } + else if(sc.Compare("globalarray")) + { + strValue = GLOBALARRAY; + sc.MustGetToken(TK_IntConst); + if(sc.Number < 0 || sc.Number >= NUM_GLOBALVARS) + sc.ScriptError("Global variable number out of range: %d", sc.Number); + valueArgument = sc.Number; } else sc.ScriptError("Unknown string '%s'.", sc.String); } else { - value = CONSTANT; + strValue = CONSTANT; sc.MustGetToken(TK_StringConst); - str = sc.String; + if(sc.String[0] == '$') + str = GStrings[sc.String+1]; + else + str = sc.String; } sc.MustGetToken(','); GetCoordinates(sc, fullScreenOffsets, x, y); @@ -562,25 +594,102 @@ class CommandDrawString : public SBarInfoCommand else //monospaced, so just multiplay the character size x -= static_cast ((font->GetCharWidth((int) script->spacingCharacter) + spacing) * str.Len()); } + void Reset() + { + switch(strValue) + { + case PLAYERCLASS: + // userinfo changes before the actual class change. + case SKILLNAME: + // Although it's not possible for the skill level to change + // midlevel, it is possible the level was restarted. + cache = -1; + break; + default: + break; + } + } void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) { - switch(value) + switch(strValue) { case LEVELNAME: - if(level.lumpnum != valueArg) + if(level.lumpnum != cache) { - valueArg = level.lumpnum; + cache = level.lumpnum; str = level.LevelName; } break; + case LEVELLUMP: + if(level.lumpnum != cache) + { + cache = level.lumpnum; + str = level.mapname; + } + break; + case SKILLNAME: + if(level.lumpnum != cache) // Can only change skill between level. + { + cache = level.lumpnum; + str = G_SkillName(); + } + break; + case PLAYERCLASS: + if(statusBar->CPlayer->userinfo.PlayerClass != cache) + { + cache = statusBar->CPlayer->userinfo.PlayerClass; + str = statusBar->CPlayer->cls->Meta.GetMetaString(APMETA_DisplayName); + } + break; + case AMMO1TAG: + SetStringToTag(statusBar->ammo1); + break; + case AMMO2TAG: + SetStringToTag(statusBar->ammo2); + break; + case WEAPONTAG: + SetStringToTag(statusBar->CPlayer->ReadyWeapon); + break; + case INVENTORYTAG: + SetStringToTag(statusBar->CPlayer->mo->InvSel); + break; + case PLAYERNAME: + // Can't think of a good way to detect changes to this, so + // I guess copying it every tick will have to do. + str = statusBar->CPlayer->userinfo.netname; + break; + case GLOBALVAR: + if(ACS_GlobalVars[valueArgument] != cache) + { + cache = ACS_GlobalVars[valueArgument]; + str = FBehavior::StaticLookupString(ACS_GlobalVars[valueArgument]); + } + break; + case GLOBALARRAY: + if(ACS_GlobalArrays[valueArgument][consoleplayer] != cache) + { + cache = ACS_GlobalArrays[valueArgument][consoleplayer]; + str = FBehavior::StaticLookupString(ACS_GlobalArrays[valueArgument][consoleplayer]); + } + break; default: break; } } protected: - enum ValueType + enum StringValueType { LEVELNAME, + LEVELLUMP, + SKILLNAME, + PLAYERCLASS, + PLAYERNAME, + AMMO1TAG, + AMMO2TAG, + WEAPONTAG, + INVENTORYTAG, + GLOBALVAR, + GLOBALARRAY, CONSTANT }; @@ -591,9 +700,28 @@ class CommandDrawString : public SBarInfoCommand EColorRange translation; SBarInfoCoordinate x; SBarInfoCoordinate y; - ValueType value; - int valueArg; + int cache; /// General purpose cache. + StringValueType strValue; + int valueArgument; FString str; + + private: + void SetStringToTag(AActor *actor) + { + if(actor != NULL) + { + if(actor->GetClass()->ClassIndex != cache) + { + cache = actor->GetClass()->ClassIndex; + str = actor->GetTag(); + } + } + else + { + cache = -1; + str = ""; + } + } }; //////////////////////////////////////////////////////////////////////////////// @@ -604,7 +732,7 @@ class CommandDrawNumber : public CommandDrawString CommandDrawNumber(SBarInfo *script) : CommandDrawString(script), fillZeros(false), whenNotZero(false), interpolationSpeed(0), drawValue(0), length(3), lowValue(-1), lowTranslation(CR_UNTRANSLATED), highValue(-1), - highTranslation(CR_UNTRANSLATED), value(CONSTANT), valueArgument(0), + highTranslation(CR_UNTRANSLATED), value(CONSTANT), inventoryItem(NULL) { } @@ -987,7 +1115,6 @@ class CommandDrawNumber : public CommandDrawString EColorRange highTranslation; EColorRange normalTranslation; ValueType value; - int valueArgument; const PClass *inventoryItem; SBarInfoCoordinate startX;