SBarInfoCommand::SBarInfoCommand() //sets the default values for more predicable behavior { type = 0; special = 0; special2 = 0; special3 = 0; special4 = 0; flags = 0; x = 0; y = 0; value = 0; image_index = 0; sprite_index.SetInvalid(); translation = CR_UNTRANSLATED; translation2 = CR_UNTRANSLATED; translation3 = CR_UNTRANSLATED; font = V_GetFont("CONFONT"); }
FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font) { if (arc.IsStoring ()) { arc << font->Name; } else { char *name = NULL; arc << name; font = V_GetFont(name); if (font == NULL) { Printf ("Could not load font %s\n", name); font = SmallFont; } delete[] name; } return arc; }
FTextureID FTextureManager::CheckForTexture (const char *name, int usetype, BITFIELD flags) { int i; int firstfound = -1; int firsttype = FTexture::TEX_Null; if (name == NULL || name[0] == '\0') { return FTextureID(-1); } // [RH] Doom counted anything beginning with '-' as "no texture". // Hopefully nobody made use of that and had textures like "-EMPTY", // because -NOFLAT- is a valid graphic for ZDoom. if (name[0] == '-' && name[1] == '\0') { return FTextureID(0); } i = HashFirst[MakeKey (name) % HASH_SIZE]; while (i != HASH_END) { const FTexture *tex = Textures[i].Texture; if (stricmp (tex->Name, name) == 0) { // The name matches, so check the texture type if (usetype == FTexture::TEX_Any) { // All NULL textures should actually return 0 if (tex->UseType == FTexture::TEX_FirstDefined && !(flags & TEXMAN_ReturnFirst)) return 0; return FTextureID(tex->UseType==FTexture::TEX_Null? 0 : i); } else if ((flags & TEXMAN_Overridable) && tex->UseType == FTexture::TEX_Override) { return FTextureID(i); } else if (tex->UseType == usetype) { return FTextureID(i); } else if (tex->UseType == FTexture::TEX_FirstDefined && usetype == FTexture::TEX_Wall) { if (!(flags & TEXMAN_ReturnFirst)) return FTextureID(0); else return FTextureID(i); } else if (tex->UseType == FTexture::TEX_Null && usetype == FTexture::TEX_Wall) { // We found a NULL texture on a wall -> return 0 return FTextureID(0); } else { if (firsttype == FTexture::TEX_Null || (firsttype == FTexture::TEX_MiscPatch && tex->UseType != firsttype && tex->UseType != FTexture::TEX_Null) ) { firstfound = i; firsttype = tex->UseType; } } } i = Textures[i].HashNext; } size_t namelen = strlen(name); if(name[0] == '#' && namelen == 7) { FTexture *solidTex = SolidTexture_TryCreate(name+1); solidTex->UseType = FTexture::TEX_Flat; return AddTexture(solidTex); } // Handle font look ups (FONTNAME:XX) if(namelen > 3 && name[namelen-3] == ':') { FString fontName(name, namelen-3); FFont *font = V_GetFont(fontName); if(font) { return font->GetCharID(ParseHex(name+namelen-2)); } } if ((flags & TEXMAN_TryAny) && usetype != FTexture::TEX_Any) { // Never return the index of NULL textures. if (firstfound != -1) { if (firsttype == FTexture::TEX_Null) return FTextureID(0); if (firsttype == FTexture::TEX_FirstDefined && !(flags & TEXMAN_ReturnFirst)) return FTextureID(0); } return FTextureID(firstfound); } return FTextureID(-1); }
void HUD_InitHud() { switch (gameinfo.gametype) { case GAME_Heretic: case GAME_Hexen: healthpic = TexMan.FindTexture("ARTIPTN2"); HudFont=FFont::FindFont("HUDFONT_RAVEN"); break; case GAME_Strife: healthpic = TexMan.FindTexture("I_MDKT"); HudFont=BigFont; // Strife doesn't have anything nice so use the standard font break; default: healthpic = TexMan.FindTexture("MEDIA0"); berserkpic = TexMan.FindTexture("PSTRA0"); HudFont=FFont::FindFont("HUDFONT_DOOM"); break; } IndexFont = V_GetFont("INDEXFONT"); if (HudFont == NULL) HudFont = BigFont; if (IndexFont == NULL) IndexFont = ConFont; // Emergency fallback invgems[0] = TexMan.FindTexture("INVGEML1"); invgems[1] = TexMan.FindTexture("INVGEML2"); invgems[2] = TexMan.FindTexture("INVGEMR1"); invgems[3] = TexMan.FindTexture("INVGEMR2"); fragpic = TexMan.FindTexture("HU_FRAGS"); // Sadly, I don't have anything usable for this. :( KeyTypes.Clear(); UnassignedKeyTypes.Clear(); statspace = SmallFont->StringWidth("Ac:"); // Now read custom icon overrides int lump, lastlump = 0; while ((lump = Wads.FindLump ("ALTHUDCF", &lastlump)) != -1) { FScanner sc(lump); while (sc.GetString()) { if (sc.Compare("Health")) { sc.MustGetString(); FTextureID tex = TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch); if (tex.isValid()) healthpic = TexMan[tex]; } else if (sc.Compare("Berserk")) { sc.MustGetString(); FTextureID tex = TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch); if (tex.isValid()) berserkpic = TexMan[tex]; } else { PClass *ti = PClass::FindClass(sc.String); if (!ti) { Printf("Unknown item class '%s' in ALTHUDCF\n", sc.String); } else if (!ti->IsDescendantOf(RUNTIME_CLASS(AInventory))) { Printf("Invalid item class '%s' in ALTHUDCF\n", sc.String); ti=NULL; } sc.MustGetString(); FTextureID tex; if (!sc.Compare("0") && !sc.Compare("NULL") && !sc.Compare("")) { tex = TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch); } else tex.SetInvalid(); if (ti) SetHUDIcon(static_cast<PClassInventory*>(ti), tex); } } } }
static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) { sc.MustGetStringName("{"); while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("else")) { SkipSubBlock(sc); } else if (sc.Compare("ifgame")) { if (!CheckSkipGameBlock(sc)) { // recursively parse sub-block ParseListMenuBody(sc, desc); } } else if (sc.Compare("ifoption")) { if (!CheckSkipOptionBlock(sc)) { // recursively parse sub-block ParseListMenuBody(sc, desc); } } else if (sc.Compare("Class")) { sc.MustGetString(); const PClass *cls = PClass::FindClass(sc.String); if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(DListMenu))) { sc.ScriptError("Unknown menu class '%s'", sc.String); } desc->mClass = cls; } else if (sc.Compare("Selector")) { sc.MustGetString(); desc->mSelector = TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch); sc.MustGetStringName(","); sc.MustGetNumber(); desc->mSelectOfsX = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); desc->mSelectOfsY = sc.Number; } else if (sc.Compare("Linespacing")) { sc.MustGetNumber(); desc->mLinespacing = sc.Number; } else if (sc.Compare("Position")) { sc.MustGetNumber(); desc->mXpos = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); desc->mYpos = sc.Number; } else if (sc.Compare("Centermenu")) { desc->mCenter = true; } else if (sc.Compare("MouseWindow")) { sc.MustGetNumber(); desc->mWLeft = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); desc->mWRight = sc.Number; } else if (sc.Compare("StaticPatch") || sc.Compare("StaticPatchCentered")) { bool centered = sc.Compare("StaticPatchCentered"); sc.MustGetNumber(); int x = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); int y = sc.Number; sc.MustGetStringName(","); sc.MustGetString(); FTextureID tex = TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch); FListMenuItem *it = new FListMenuItemStaticPatch(x, y, tex, centered); desc->mItems.Push(it); } else if (sc.Compare("StaticText") || sc.Compare("StaticTextCentered")) { bool centered = sc.Compare("StaticTextCentered"); sc.MustGetNumber(); int x = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); int y = sc.Number; sc.MustGetStringName(","); sc.MustGetString(); FListMenuItem *it = new FListMenuItemStaticText(x, y, sc.String, desc->mFont, desc->mFontColor, centered); desc->mItems.Push(it); } else if (sc.Compare("PatchItem")) { sc.MustGetString(); FTextureID tex = TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch); sc.MustGetStringName(","); sc.MustGetString(); int hotkey = sc.String[0]; sc.MustGetStringName(","); sc.MustGetString(); FName action = sc.String; int param = 0; if (sc.CheckString(",")) { sc.MustGetNumber(); param = sc.Number; } FListMenuItem *it = new FListMenuItemPatch(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, tex, action, param); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; } else if (sc.Compare("TextItem")) { sc.MustGetString(); FString text = sc.String; sc.MustGetStringName(","); sc.MustGetString(); int hotkey = sc.String[0]; sc.MustGetStringName(","); sc.MustGetString(); FName action = sc.String; int param = 0; if (sc.CheckString(",")) { sc.MustGetNumber(); param = sc.Number; } FListMenuItem *it = new FListMenuItemText(desc->mXpos, desc->mYpos, desc->mLinespacing, hotkey, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, param); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; } else if (sc.Compare("Font")) { sc.MustGetString(); FFont *newfont = V_GetFont(sc.String); if (newfont != NULL) desc->mFont = newfont; if (sc.CheckString(",")) { sc.MustGetString(); desc->mFontColor2 = desc->mFontColor = V_FindFontColor((FName)sc.String); if (sc.CheckString(",")) { sc.MustGetString(); desc->mFontColor2 = V_FindFontColor((FName)sc.String); } } else { desc->mFontColor = OptionSettings.mFontColor; desc->mFontColor2 = OptionSettings.mFontColorValue; } } else if (sc.Compare("NetgameMessage")) { sc.MustGetString(); desc->mNetgameMessage = sc.String; } else if (sc.Compare("PlayerDisplay")) { bool noportrait = false; FName action = NAME_None; sc.MustGetNumber(); int x = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); int y = sc.Number; sc.MustGetStringName(","); sc.MustGetString(); PalEntry c1 = V_GetColor(NULL, sc.String); sc.MustGetStringName(","); sc.MustGetString(); PalEntry c2 = V_GetColor(NULL, sc.String); if (sc.CheckString(",")) { sc.MustGetNumber(); noportrait = !!sc.Number; if (sc.CheckString(",")) { sc.MustGetString(); action = sc.String; } } FListMenuItemPlayerDisplay *it = new FListMenuItemPlayerDisplay(desc, x, y, c1, c2, noportrait, action); desc->mItems.Push(it); } else if (sc.Compare("PlayerNameBox")) { sc.MustGetString(); FString text = sc.String; sc.MustGetStringName(","); sc.MustGetNumber(); int ofs = sc.Number; sc.MustGetStringName(","); sc.MustGetString(); FListMenuItem *it = new FPlayerNameBox(desc->mXpos, desc->mYpos, desc->mLinespacing, ofs, text, desc->mFont, desc->mFontColor, sc.String); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; } else if (sc.Compare("ValueText")) { sc.MustGetString(); FString text = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FName action = sc.String; FName values; if (sc.CheckString(",")) { sc.MustGetString(); values = sc.String; } FListMenuItem *it = new FValueTextItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, desc->mFontColor2, action, values); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; } else if (sc.Compare("Slider")) { sc.MustGetString(); FString text = sc.String; sc.MustGetStringName(","); sc.MustGetString(); FString action = sc.String; sc.MustGetStringName(","); sc.MustGetNumber(); int min = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); int max = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); int step = sc.Number; FListMenuItem *it = new FSliderItem(desc->mXpos, desc->mYpos, desc->mLinespacing, text, desc->mFont, desc->mFontColor, action, min, max, step); desc->mItems.Push(it); desc->mYpos += desc->mLinespacing; if (desc->mSelectedItem == -1) desc->mSelectedItem = desc->mItems.Size()-1; } else { sc.ScriptError("Unknown keyword '%s'", sc.String); } } }
void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) { while(sc.CheckToken(TK_Identifier)) { SBarInfoCommand cmd; switch(cmd.type = sc.MustMatchString(SBarInfoRoutineLevel)) { case SBARINFO_DRAWSWITCHABLEIMAGE: sc.MustGetToken(TK_Identifier); if(sc.Compare("weaponslot")) { cmd.flags = DRAWIMAGE_WEAPONSLOT; sc.MustGetToken(TK_IntConst); cmd.value = sc.Number; } else if(sc.Compare("invulnerable")) { cmd.flags = DRAWIMAGE_INVULNERABILITY; } else if(sc.Compare("keyslot")) { cmd.flags = DRAWIMAGE_KEYSLOT; sc.MustGetToken(TK_IntConst); cmd.value = sc.Number; } else { cmd.setString(sc, sc.String, 0); const PClass* item = PClass::FindClass(sc.String); if(item == NULL || !PClass::FindClass("Inventory")->IsAncestorOf(item)) //must be a kind of Inventory { sc.ScriptError("'%s' is not a type of inventory item.", sc.String); } } if(sc.CheckToken(TK_AndAnd)) { cmd.flags |= DRAWIMAGE_SWITCHABLE_AND; if(cmd.flags & DRAWIMAGE_KEYSLOT) { sc.MustGetToken(TK_IntConst); cmd.special4 = sc.Number; } else { sc.MustGetToken(TK_Identifier); cmd.setString(sc, sc.String, 1); const PClass* item = PClass::FindClass(sc.String); if(item == NULL || !PClass::FindClass("Inventory")->IsAncestorOf(item)) //must be a kind of Inventory { sc.ScriptError("'%s' is not a type of inventory item.", sc.String); } } sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); cmd.special = newImage(sc.String); sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); cmd.special2 = newImage(sc.String); sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); cmd.special3 = newImage(sc.String); sc.MustGetToken(','); } else { sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); cmd.special = newImage(sc.String); sc.MustGetToken(','); } case SBARINFO_DRAWIMAGE: { bool getImage = true; if(sc.CheckToken(TK_Identifier)) { getImage = false; if(sc.Compare("playericon")) cmd.flags |= DRAWIMAGE_PLAYERICON; else if(sc.Compare("ammoicon1")) cmd.flags |= DRAWIMAGE_AMMO1; else if(sc.Compare("ammoicon2")) cmd.flags |= DRAWIMAGE_AMMO2; else if(sc.Compare("armoricon")) cmd.flags |= DRAWIMAGE_ARMOR; else if(sc.Compare("weaponicon")) cmd.flags |= DRAWIMAGE_WEAPONICON; else if(sc.Compare("sigil")) cmd.flags |= DRAWIMAGE_SIGIL; else if(sc.Compare("hexenarmor")) { cmd.flags = DRAWIMAGE_HEXENARMOR; sc.MustGetToken(TK_Identifier); if(sc.Compare("armor")) cmd.value = 0; else if(sc.Compare("shield")) cmd.value = 1; else if(sc.Compare("helm")) cmd.value = 2; else if(sc.Compare("amulet")) cmd.value = 3; else sc.ScriptError("Unkown armor type: '%s'", sc.String); sc.MustGetToken(','); getImage = true; } else if(sc.Compare("runeicon")) cmd.flags |= DRAWIMAGE_RUNEICON; else if(sc.Compare("translatable")) { cmd.flags |= DRAWIMAGE_TRANSLATABLE; getImage = true; } else { //sc.CheckToken(TK_Identifier); cmd.flags |= DRAWIMAGE_INVENTORYICON; const PClass* item = PClass::FindClass(sc.String); if(item == NULL || !PClass::FindClass("Inventory")->IsAncestorOf(item)) //must be a kind of Inventory { sc.ScriptError("'%s' is not a type of inventory item.", sc.String); } cmd.sprite_index = ((AInventory *)GetDefaultByType(item))->Icon; cmd.image_index = -1; } } if(getImage) { sc.MustGetToken(TK_StringConst); cmd.image_index = newImage(sc.String); cmd.sprite_index.SetInvalid(); } sc.MustGetToken(','); this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); if(sc.CheckToken(',')) { sc.MustGetToken(TK_Identifier); if(sc.Compare("center")) cmd.flags |= DRAWIMAGE_OFFSET_CENTER; else if(sc.Compare("centerbottom")) cmd.flags |= DRAWIMAGE_OFFSET_CENTERBOTTOM; else sc.ScriptError("'%s' is not a valid alignment.", sc.String); } sc.MustGetToken(';'); break; } case SBARINFO_DRAWNUMBER: cmd.special4 = cmd.special3 = -1; sc.MustGetToken(TK_IntConst); cmd.special = sc.Number; sc.MustGetToken(','); sc.MustGetToken(TK_Identifier); cmd.font = V_GetFont(sc.String); if(cmd.font == NULL) sc.ScriptError("Unknown font '%s'.", sc.String); sc.MustGetToken(','); sc.MustGetToken(TK_Identifier); cmd.translation = this->GetTranslation(sc, sc.String); sc.MustGetToken(','); if(sc.CheckToken(TK_IntConst)) { cmd.value = sc.Number; sc.MustGetToken(','); } else { sc.MustGetToken(TK_Identifier); if(sc.Compare("health")) cmd.flags = DRAWNUMBER_HEALTH; else if(sc.Compare("armor")) cmd.flags = DRAWNUMBER_ARMOR; else if(sc.Compare("ammo1")) cmd.flags = DRAWNUMBER_AMMO1; else if(sc.Compare("ammo2")) cmd.flags = DRAWNUMBER_AMMO2; else if(sc.Compare("ammo")) //request the next string to be an ammo type { sc.MustGetToken(TK_Identifier); cmd.setString(sc, sc.String, 0); cmd.flags = DRAWNUMBER_AMMO; const PClass* ammo = PClass::FindClass(sc.String); if(ammo == NULL || !RUNTIME_CLASS(AAmmo)->IsAncestorOf(ammo)) //must be a kind of ammo { sc.ScriptError("'%s' is not a type of ammo.", sc.String); } } else if(sc.Compare("ammocapacity")) { sc.MustGetToken(TK_Identifier); cmd.setString(sc, sc.String, 0); cmd.flags = DRAWNUMBER_AMMOCAPACITY; const PClass* ammo = PClass::FindClass(sc.String); if(ammo == NULL || !RUNTIME_CLASS(AAmmo)->IsAncestorOf(ammo)) //must be a kind of ammo { sc.ScriptError("'%s' is not a type of ammo.", sc.String); } } else if(sc.Compare("frags")) cmd.flags = DRAWNUMBER_FRAGS; else if(sc.Compare("kills")) cmd.flags |= DRAWNUMBER_KILLS; else if(sc.Compare("monsters")) cmd.flags |= DRAWNUMBER_MONSTERS; else if(sc.Compare("items")) cmd.flags |= DRAWNUMBER_ITEMS; else if(sc.Compare("totalitems")) cmd.flags |= DRAWNUMBER_TOTALITEMS; else if(sc.Compare("secrets")) cmd.flags |= DRAWNUMBER_SECRETS; else if(sc.Compare("totalsecrets")) cmd.flags |= DRAWNUMBER_TOTALSECRETS; else if(sc.Compare("armorclass")) cmd.flags |= DRAWNUMBER_ARMORCLASS; else if(sc.Compare("globalvar")) { cmd.flags |= DRAWNUMBER_GLOBALVAR; 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 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 if(sc.Compare("poweruptime")) { cmd.flags |= DRAWNUMBER_POWERUPTIME; sc.MustGetToken(TK_Identifier); cmd.setString(sc, sc.String, 0); const PClass* item = PClass::FindClass(sc.String); if(item == NULL || !PClass::FindClass("PowerupGiver")->IsAncestorOf(item)) { sc.ScriptError("'%s' is not a type of PowerupGiver.", sc.String); } } else if(sc.Compare("teamscore")) //Takes in a number for team { cmd.flags |= DRAWNUMBER_TEAMSCORE; sc.MustGetToken(TK_StringConst); int t = -1; for(unsigned int i = 0;i < teams.Size();i++) { if(teams[i].Name.CompareNoCase(sc.String) == 0) { t = (int) i; break; } } if(t == -1) sc.ScriptError("'%s' is not a valid team.", sc.String); cmd.value = t; } else { cmd.flags = DRAWNUMBER_INVENTORY; cmd.setString(sc, sc.String, 0); const PClass* item = PClass::FindClass(sc.String); if(item == NULL || !PClass::FindClass("Inventory")->IsAncestorOf(item)) //must be a kind of ammo { sc.ScriptError("'%s' is not a type of inventory item.", sc.String); } } sc.MustGetToken(','); } while(sc.CheckToken(TK_Identifier)) { if(sc.Compare("fillzeros")) cmd.flags |= DRAWNUMBER_FILLZEROS; else if(sc.Compare("whennotzero")) cmd.flags |= DRAWNUMBER_WHENNOTZERO; else if(sc.Compare("drawshadow")) cmd.flags |= DRAWNUMBER_DRAWSHADOW; else sc.ScriptError("Unknown flag '%s'.", sc.String); if(!sc.CheckToken('|')) sc.MustGetToken(','); } this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); if(sc.CheckToken(',')) { bool needsComma = false; if(sc.CheckToken(TK_IntConst)) //font spacing { cmd.special2 = sc.Number; needsComma = true; } if(!needsComma || sc.CheckToken(',')) //2nd coloring for "low-on" value { sc.MustGetToken(TK_Identifier); cmd.translation2 = this->GetTranslation(sc, sc.String); sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); cmd.special3 = sc.Number; if(sc.CheckToken(',')) //3rd coloring for "high-on" value { sc.MustGetToken(TK_Identifier); cmd.translation3 = this->GetTranslation(sc, sc.String); sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); cmd.special4 = sc.Number; } } } sc.MustGetToken(';'); break; case SBARINFO_DRAWMUGSHOT: if(sc.CheckToken(TK_StringConst)) { cmd.setString(sc, sc.String, 0, 3, true); sc.MustGetToken(','); } sc.MustGetToken(TK_IntConst); //accuracy if(sc.Number < 1 || sc.Number > 9) sc.ScriptError("Expected a number between 1 and 9, got %d instead.", sc.Number); cmd.special = sc.Number; sc.MustGetToken(','); while(sc.CheckToken(TK_Identifier)) { if(sc.Compare("xdeathface")) cmd.flags |= DRAWMUGSHOT_XDEATHFACE; else if(sc.Compare("animatedgodmode")) cmd.flags |= DRAWMUGSHOT_ANIMATEDGODMODE; else if(sc.Compare("disablegrin")) cmd.flags |= DRAWMUGSHOT_DISABLEGRIN; else if(sc.Compare("disableouch")) cmd.flags |= DRAWMUGSHOT_DISABLEOUCH; else if(sc.Compare("disablepain")) cmd.flags |= DRAWMUGSHOT_DISABLEPAIN; else if(sc.Compare("disablerampage")) cmd.flags |= DRAWMUGSHOT_DISABLERAMPAGE; else sc.ScriptError("Unknown flag '%s'.", sc.String); if(!sc.CheckToken('|')) sc.MustGetToken(','); } this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); sc.MustGetToken(';'); break; case SBARINFO_DRAWSELECTEDINVENTORY: { bool alternateonempty = false; while(true) //go until we get a font (non-flag) { sc.MustGetToken(TK_Identifier); if(sc.Compare("alternateonempty")) { alternateonempty = true; cmd.flags |= DRAWSELECTEDINVENTORY_ALTERNATEONEMPTY; } else if(sc.Compare("artiflash")) { cmd.flags |= DRAWSELECTEDINVENTORY_ARTIFLASH; } else if(sc.Compare("alwaysshowcounter")) { cmd.flags |= DRAWSELECTEDINVENTORY_ALWAYSSHOWCOUNTER; } else if(sc.Compare("center")) { cmd.flags |= DRAWSELECTEDINVENTORY_CENTER; } else if(sc.Compare("centerbottom")) { cmd.flags |= DRAWSELECTEDINVENTORY_CENTERBOTTOM; } else if(sc.Compare("drawshadow")) { cmd.flags |= DRAWSELECTEDINVENTORY_DRAWSHADOW; } else { cmd.font = V_GetFont(sc.String); if(cmd.font == NULL) sc.ScriptError("Unknown font '%s'.", sc.String); sc.MustGetToken(','); break; } if(!sc.CheckToken('|')) sc.MustGetToken(','); } this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); cmd.special2 = *(cmd.x + 30); cmd.special3 = *(cmd.y + 24); cmd.translation = CR_GOLD; if(sc.CheckToken(',')) //more font information { this->getCoordinates(sc, block.fullScreenOffsets, cmd.special2, cmd.special3); if(sc.CheckToken(',')) { sc.MustGetToken(TK_Identifier); cmd.translation = this->GetTranslation(sc, sc.String); if(sc.CheckToken(',')) { sc.MustGetToken(TK_IntConst); cmd.special4 = sc.Number; } } } if(alternateonempty) { sc.MustGetToken('{'); cmd.subBlock.fullScreenOffsets = block.fullScreenOffsets; this->ParseSBarInfoBlock(sc, cmd.subBlock); } else { sc.MustGetToken(';'); } break; } case SBARINFO_DRAWINVENTORYBAR: sc.MustGetToken(TK_Identifier); if(sc.Compare("Doom")) cmd.special = GAME_Doom; else if(sc.Compare("Heretic")) cmd.special = GAME_Heretic; else if(sc.Compare("Hexen")) cmd.special = GAME_Hexen; else if(sc.Compare("Strife")) cmd.special = GAME_Strife; else sc.ScriptError("Unkown style '%s'.", sc.String); sc.MustGetToken(','); while(sc.CheckToken(TK_Identifier)) { if(sc.Compare("alwaysshow")) { cmd.flags |= DRAWINVENTORYBAR_ALWAYSSHOW; } else if(sc.Compare("noartibox")) { cmd.flags |= DRAWINVENTORYBAR_NOARTIBOX; } else if(sc.Compare("noarrows")) { cmd.flags |= DRAWINVENTORYBAR_NOARROWS; } else if(sc.Compare("alwaysshowcounter")) { cmd.flags |= DRAWINVENTORYBAR_ALWAYSSHOWCOUNTER; } else if(sc.Compare("translucent")) { cmd.flags |= DRAWINVENTORYBAR_TRANSLUCENT; } else { sc.ScriptError("Unknown flag '%s'.", sc.String); } if(!sc.CheckToken('|')) sc.MustGetToken(','); } sc.MustGetToken(TK_IntConst); cmd.value = sc.Number; sc.MustGetToken(','); sc.MustGetToken(TK_Identifier); cmd.font = V_GetFont(sc.String); if(cmd.font == NULL) sc.ScriptError("Unknown font '%s'.", sc.String); sc.MustGetToken(','); this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); cmd.special2 = *(cmd.x + 26); cmd.special3 = *(cmd.y + 22); cmd.translation = CR_GOLD; if(sc.CheckToken(',')) //more font information { this->getCoordinates(sc, block.fullScreenOffsets, cmd.special2, cmd.special3); if(sc.CheckToken(',')) { sc.MustGetToken(TK_Identifier); cmd.translation = this->GetTranslation(sc, sc.String); if(sc.CheckToken(',')) { sc.MustGetToken(TK_IntConst); cmd.special4 = sc.Number; } } } sc.MustGetToken(';'); break; case SBARINFO_DRAWBAR: sc.MustGetToken(TK_StringConst); cmd.image_index = newImage(sc.String); cmd.sprite_index.SetInvalid(); sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); cmd.special = newImage(sc.String); sc.MustGetToken(','); sc.MustGetToken(TK_Identifier); //yeah, this is the same as drawnumber, there might be a better way to copy it... if(sc.Compare("health")) { cmd.flags = DRAWNUMBER_HEALTH; if(sc.CheckToken(TK_Identifier)) //comparing reference { cmd.setString(sc, sc.String, 0); const PClass* item = PClass::FindClass(sc.String); if(item == NULL || !PClass::FindClass("Inventory")->IsAncestorOf(item)) //must be a kind of inventory { sc.ScriptError("'%s' is not a type of inventory item.", sc.String); } } else cmd.special2 = DRAWBAR_COMPAREDEFAULTS; } else if(sc.Compare("armor")) { cmd.flags = DRAWNUMBER_ARMOR; if(sc.CheckToken(TK_Identifier)) { cmd.setString(sc, sc.String, 0); const PClass* item = PClass::FindClass(sc.String); if(item == NULL || !PClass::FindClass("Inventory")->IsAncestorOf(item)) //must be a kind of inventory { sc.ScriptError("'%s' is not a type of inventory item.", sc.String); } } else cmd.special2 = DRAWBAR_COMPAREDEFAULTS; } else if(sc.Compare("ammo1")) cmd.flags = DRAWNUMBER_AMMO1; else if(sc.Compare("ammo2")) cmd.flags = DRAWNUMBER_AMMO2; else if(sc.Compare("ammo")) //request the next string to be an ammo type { sc.MustGetToken(TK_Identifier); cmd.setString(sc, sc.String, 0); cmd.flags = DRAWNUMBER_AMMO; const PClass* ammo = PClass::FindClass(sc.String); if(ammo == NULL || !RUNTIME_CLASS(AAmmo)->IsAncestorOf(ammo)) //must be a kind of ammo { sc.ScriptError("'%s' is not a type of ammo.", sc.String); } } else if(sc.Compare("frags")) cmd.flags = DRAWNUMBER_FRAGS; else if(sc.Compare("kills")) cmd.flags = DRAWNUMBER_KILLS; else if(sc.Compare("items")) cmd.flags = DRAWNUMBER_ITEMS; else if(sc.Compare("secrets")) cmd.flags = DRAWNUMBER_SECRETS; else if(sc.Compare("poweruptime")) { cmd.flags |= DRAWNUMBER_POWERUPTIME; sc.MustGetToken(TK_Identifier); cmd.setString(sc, sc.String, 0); const PClass* item = PClass::FindClass(sc.String); if(item == NULL || !PClass::FindClass("PowerupGiver")->IsAncestorOf(item)) { sc.ScriptError("'%s' is not a type of PowerupGiver.", sc.String); } } else if(sc.Compare("teamscore")) //Takes in a number for team { cmd.flags |= DRAWNUMBER_TEAMSCORE; sc.MustGetToken(TK_StringConst); int t = -1; for(unsigned int i = 0;i < teams.Size();i++) { if(teams[i].Name.CompareNoCase(sc.String) == 0) { t = (int) i; break; } } if(t == -1) sc.ScriptError("'%s' is not a valid team.", sc.String); cmd.value = t; } else { cmd.flags = DRAWNUMBER_INVENTORY; cmd.setString(sc, sc.String, 0); const PClass* item = PClass::FindClass(sc.String); if(item == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(item)) { sc.ScriptError("'%s' is not a type of inventory item.", sc.String); } } sc.MustGetToken(','); sc.MustGetToken(TK_Identifier); if(sc.Compare("horizontal")) cmd.special2 += DRAWBAR_HORIZONTAL; else if(!sc.Compare("vertical")) sc.ScriptError("Unknown direction '%s'.", sc.String); sc.MustGetToken(','); while(sc.CheckToken(TK_Identifier)) { if(sc.Compare("reverse")) cmd.special2 += DRAWBAR_REVERSE; else sc.ScriptError("Unkown flag '%s'.", sc.String); if(!sc.CheckToken('|')) sc.MustGetToken(','); } this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); if(sc.CheckToken(',')) //border { sc.MustGetToken(TK_IntConst); cmd.special3 = sc.Number; } sc.MustGetToken(';'); break; case SBARINFO_DRAWGEM: while(sc.CheckToken(TK_Identifier)) { if(sc.Compare("wiggle")) cmd.flags |= DRAWGEM_WIGGLE; else if(sc.Compare("translatable")) cmd.flags |= DRAWGEM_TRANSLATABLE; else if(sc.Compare("armor")) cmd.flags |= DRAWGEM_ARMOR; else if(sc.Compare("reverse")) cmd.flags |= DRAWGEM_REVERSE; else sc.ScriptError("Unknown drawgem flag '%s'.", sc.String); if(!sc.CheckToken('|')) sc.MustGetToken(','); } sc.MustGetToken(TK_StringConst); //chain cmd.special = newImage(sc.String); sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); //gem cmd.image_index = newImage(sc.String); cmd.sprite_index.SetInvalid(); sc.MustGetToken(','); cmd.special2 = this->getSignedInteger(sc); sc.MustGetToken(','); cmd.special3 = this->getSignedInteger(sc); sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); if(sc.Number < 0) sc.ScriptError("Chain size must be a positive number."); cmd.special4 = sc.Number; sc.MustGetToken(','); this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); sc.MustGetToken(';'); break; case SBARINFO_DRAWSHADER: sc.MustGetToken(TK_IntConst); cmd.special = sc.Number; if(sc.Number < 1) sc.ScriptError("Width must be greater than 1."); sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); cmd.special2 = sc.Number; if(sc.Number < 1) sc.ScriptError("Height must be greater than 1."); sc.MustGetToken(','); sc.MustGetToken(TK_Identifier); if(sc.Compare("vertical")) cmd.flags |= DRAWSHADER_VERTICAL; else if(!sc.Compare("horizontal")) sc.ScriptError("Unknown direction '%s'.", sc.String); sc.MustGetToken(','); if(sc.CheckToken(TK_Identifier)) { if(!sc.Compare("reverse")) { sc.ScriptError("Exspected 'reverse', got '%s' instead.", sc.String); } cmd.flags |= DRAWSHADER_REVERSE; sc.MustGetToken(','); } this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); sc.MustGetToken(';'); break; case SBARINFO_DRAWSTRING: sc.MustGetToken(TK_Identifier); cmd.font = V_GetFont(sc.String); if(cmd.font == NULL) sc.ScriptError("Unknown font '%s'.", sc.String); sc.MustGetToken(','); sc.MustGetToken(TK_Identifier); cmd.translation = this->GetTranslation(sc, sc.String); sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); cmd.setString(sc, sc.String, 0, -1, false); sc.MustGetToken(','); this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); if(sc.CheckToken(',')) //spacing { sc.MustGetToken(TK_IntConst); cmd.special = sc.Number; } sc.MustGetToken(';'); break; case SBARINFO_DRAWKEYBAR: sc.MustGetToken(TK_IntConst); cmd.value = sc.Number; sc.MustGetToken(','); sc.MustGetToken(TK_Identifier); if(sc.Compare("vertical")) cmd.flags |= DRAWKEYBAR_VERTICAL; else if(!sc.Compare("horizontal")) sc.ScriptError("Unknown direction '%s'.", sc.String); sc.MustGetToken(','); while(sc.CheckToken(TK_Identifier)) { if(sc.Compare("reverserows")) cmd.flags |= DRAWKEYBAR_REVERSEROWS; else sc.ScriptError("Unknown flag '%s'.", sc.String); if(!sc.CheckToken('|')) sc.MustGetToken(','); } if(sc.CheckToken(TK_Auto)) cmd.special = -1; else { sc.MustGetToken(TK_IntConst); cmd.special = sc.Number; } sc.MustGetToken(','); this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); if(sc.CheckToken(',')) { //key offset sc.MustGetToken(TK_IntConst); cmd.special2 = sc.Number; if(sc.CheckToken(',')) { //max per row/column sc.MustGetToken(TK_IntConst); cmd.special3 = sc.Number; sc.MustGetToken(','); //row/column spacing (opposite of previous) if(sc.CheckToken(TK_Auto)) cmd.special4 = -1; else { sc.MustGetToken(TK_IntConst); cmd.special4 = sc.Number; } } } sc.MustGetToken(';'); break; case SBARINFO_GAMEMODE: while(sc.CheckToken(TK_Identifier)) { if(sc.Compare("singleplayer")) cmd.flags |= GAMETYPE_SINGLEPLAYER; else if(sc.Compare("cooperative")) cmd.flags |= GAMETYPE_COOPERATIVE; else if(sc.Compare("deathmatch")) cmd.flags |= GAMETYPE_DEATHMATCH; else if(sc.Compare("teamgame")) cmd.flags |= GAMETYPE_TEAMGAME; else if(sc.Compare("ctf")) cmd.flags |= GAMETYPE_CTF; else if(sc.Compare("oneflagctf")) cmd.flags |= GAMETYPE_ONEFLAGCTF; else if(sc.Compare("skulltag")) cmd.flags |= GAMETYPE_SKULLTAG; else if(sc.Compare("invasion")) cmd.flags |= GAMETYPE_INVASION; else if(sc.Compare("possession")) cmd.flags |= GAMETYPE_POSSESSION; else if(sc.Compare("teampossession")) cmd.flags |= GAMETYPE_TEAMPOSSESSION; else if(sc.Compare("lastmanstanding")) cmd.flags |= GAMETYPE_LASTMANSTANDING; else if(sc.Compare("teamlms")) cmd.flags |= GAMETYPE_TEAMLMS; else if(sc.Compare("survival")) cmd.flags |= GAMETYPE_SURVIVAL; else if(sc.Compare("instagib")) cmd.flags |= GAMETYPE_INSTAGIB; else if(sc.Compare("buckshot")) cmd.flags |= GAMETYPE_BUCKSHOT; //else I'm removing this error to allow cross port compatiblity. If it doesn't know what a gamemode is lets just ignore it. // sc.ScriptError("Unknown gamemode: %s", sc.String); if(sc.CheckToken('{')) break; sc.MustGetToken(','); } cmd.subBlock.fullScreenOffsets = block.fullScreenOffsets; this->ParseSBarInfoBlock(sc, cmd.subBlock); break; case SBARINFO_PLAYERCLASS: cmd.special = cmd.special2 = cmd.special3 = -1; for(int i = 0;i < 3 && sc.CheckToken(TK_Identifier);i++) //up to 3 classes { bool foundClass = false; for(unsigned int c = 0;c < PlayerClasses.Size();c++) { if(stricmp(sc.String, PlayerClasses[c].Type->Meta.GetMetaString(APMETA_DisplayName)) == 0) { foundClass = true; if(i == 0) cmd.special = PlayerClasses[c].Type->ClassIndex; else if(i == 1) cmd.special2 = PlayerClasses[c].Type->ClassIndex; else //should be 2 cmd.special3 = PlayerClasses[c].Type->ClassIndex; break; } } if(!foundClass) sc.ScriptError("Unkown PlayerClass '%s'.", sc.String); if(sc.CheckToken('{') || i == 2) goto FinishPlayerClass; sc.MustGetToken(','); } FinishPlayerClass: cmd.subBlock.fullScreenOffsets = block.fullScreenOffsets; this->ParseSBarInfoBlock(sc, cmd.subBlock); break; case SBARINFO_ASPECTRATIO: sc.MustGetToken(TK_StringConst); if(sc.Compare("4:3")) cmd.value = ASPECTRATIO_4_3; else if(sc.Compare("16:9")) cmd.value = ASPECTRATIO_16_9; else if(sc.Compare("16:10")) cmd.value = ASPECTRATIO_16_10; else if(sc.Compare("5:4")) cmd.value = ASPECTRATIO_5_4; else sc.ScriptError("Unkown aspect ratio: %s", sc.String); sc.MustGetToken('{'); cmd.subBlock.fullScreenOffsets = block.fullScreenOffsets; this->ParseSBarInfoBlock(sc, cmd.subBlock); break; case SBARINFO_ISSELECTED: //Using StringConst instead of Identifieres is deperecated! if(sc.CheckToken(TK_Identifier)) { if(sc.Compare("not")) { cmd.flags |= SBARINFOEVENT_NOT; if(!sc.CheckToken(TK_StringConst)) sc.MustGetToken(TK_Identifier); } } else 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(',')) { if(!sc.CheckToken(TK_StringConst)) sc.MustGetToken(TK_Identifier); } else break; } sc.MustGetToken('{'); cmd.subBlock.fullScreenOffsets = block.fullScreenOffsets; this->ParseSBarInfoBlock(sc, cmd.subBlock); break; case SBARINFO_USESSECONDARYAMMO: case SBARINFO_USESAMMO: 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('{'); cmd.subBlock.fullScreenOffsets = block.fullScreenOffsets; 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('{'); cmd.subBlock.fullScreenOffsets = block.fullScreenOffsets; this->ParseSBarInfoBlock(sc, cmd.subBlock); break; } case SBARINFO_INVENTORYBARNOTVISIBLE: sc.MustGetToken('{'); cmd.subBlock.fullScreenOffsets = block.fullScreenOffsets; this->ParseSBarInfoBlock(sc, cmd.subBlock); break; case SBARINFO_WEAPONAMMO: sc.MustGetToken(TK_Identifier); if(sc.Compare("not")) { cmd.flags |= SBARINFOEVENT_NOT; sc.MustGetToken(TK_Identifier); } for(int i = 0;i < 2;i++) { cmd.setString(sc, sc.String, i); const PClass* ammo = PClass::FindClass(sc.String); if(ammo == NULL || !RUNTIME_CLASS(AAmmo)->IsAncestorOf(ammo)) //must be a kind of ammo { sc.ScriptError("'%s' is not a type of ammo.", sc.String); } if(sc.CheckToken(TK_OrOr)) { cmd.flags |= SBARINFOEVENT_OR; sc.MustGetToken(TK_Identifier); } else if(sc.CheckToken(TK_AndAnd)) { cmd.flags |= SBARINFOEVENT_AND; sc.MustGetToken(TK_Identifier); } else break; } sc.MustGetToken('{'); cmd.subBlock.fullScreenOffsets = block.fullScreenOffsets; this->ParseSBarInfoBlock(sc, cmd.subBlock); break; case SBARINFO_ININVENTORY: cmd.special2 = cmd.special3 = 0; sc.MustGetToken(TK_Identifier); if(sc.Compare("not")) { cmd.flags |= SBARINFOEVENT_NOT; sc.MustGetToken(TK_Identifier); } 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(AInventory)->IsAncestorOf(item)) { sc.ScriptError("'%s' is not a type of inventory item.", sc.String); } if (sc.CheckToken(',')) { sc.MustGetNumber(); if (i == 0) cmd.special2 = sc.Number; else cmd.special3 = sc.Number; } if(sc.CheckToken(TK_OrOr)) { cmd.flags |= SBARINFOEVENT_OR; sc.MustGetToken(TK_Identifier); } else if(sc.CheckToken(TK_AndAnd)) { cmd.flags |= SBARINFOEVENT_AND; sc.MustGetToken(TK_Identifier); } else break; } sc.MustGetToken('{'); cmd.subBlock.fullScreenOffsets = block.fullScreenOffsets; this->ParseSBarInfoBlock(sc, cmd.subBlock); break; } block.commands.Push(cmd); } sc.MustGetToken('}'); }