diff --git a/src/am_map.cpp b/src/am_map.cpp index 8f6871f9..28739c85 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1850,7 +1850,7 @@ void AM_drawPlayers () { float h, s, v, r, g, b; - D_GetPlayerColor (i, &h, &s, &v); + D_GetPlayerColor (i, &h, &s, &v, NULL); HSVtoRGB (&r, &g, &b, h, s, v); color.FromRGB(clamp (int(r*255.f),0,255), clamp (int(g*255.f),0,255), clamp (int(b*255.f),0,255)); diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index c90eabe9..62c5090e 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2138,20 +2138,7 @@ static int PatchText (int oldSize) if (!good) { - // search cluster text background flats (only if no user-defined MAPINFO is used!) - if (strlen(newStr) <= 8 && Wads.CheckNumForName("MAPINFO") >= 0) - { - for (unsigned int i = 0; i < wadclusterinfos.Size(); i++) - { - if (!strcmp(wadclusterinfos[i].finaleflat, oldStr)) - { - strcpy(wadclusterinfos[i].finaleflat, newStr); - good = true; - } - } - } - - if (!good) DPrintf (" (Unmatched)\n"); + DPrintf (" (Unmatched)\n"); } } diff --git a/src/d_netinf.h b/src/d_netinf.h index c2d49630..728bad32 100644 --- a/src/d_netinf.h +++ b/src/d_netinf.h @@ -54,7 +54,8 @@ void D_DoServerInfoChange (BYTE **stream, bool singlebit); void D_WriteUserInfoStrings (int player, BYTE **stream, bool compact=false); void D_ReadUserInfoStrings (int player, BYTE **stream, bool update); -void D_GetPlayerColor (int player, float *h, float *s, float *v); +struct FPlayerColorSet; +void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet **colorset); void D_PickRandomTeam (int player); int D_PickRandomTeam (); class player_t; diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index e31354a6..c415ebe4 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -65,6 +65,7 @@ EXTERN_CVAR (Bool, teamplay) CVAR (Float, autoaim, 5000.f, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Color, color, 0x40cf00, CVAR_USERINFO | CVAR_ARCHIVE); +CVAR (Int, colorset, 0, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, skin, "base", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Int, team, TEAM_NONE, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, gender, "male", CVAR_USERINFO | CVAR_ARCHIVE); @@ -85,6 +86,7 @@ enum INFO_MoveBob, INFO_StillBob, INFO_PlayerClass, + INFO_ColorSet, }; const char *GenderNames[3] = { "male", "female", "other" }; @@ -101,6 +103,7 @@ static const char *UserInfoStrings[] = "movebob", "stillbob", "playerclass", + "colorset", NULL }; @@ -184,10 +187,24 @@ int D_PlayerClassToInt (const char *classname) } } -void D_GetPlayerColor (int player, float *h, float *s, float *v) +void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet **set) { userinfo_t *info = &players[player].userinfo; - int color = info->color; + FPlayerColorSet *colorset = NULL; + int color; + + if (players[player].mo != NULL) + { + colorset = P_GetPlayerColorSet(players[player].mo->GetClass()->TypeName, info->colorset); + } + if (colorset != NULL) + { + color = GPalette.BaseColors[GPalette.Remap[colorset->RepresentativeColor]]; + } + else + { + color = info->color; + } RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f, h, s, v); @@ -206,6 +223,10 @@ void D_GetPlayerColor (int player, float *h, float *s, float *v) *s = clamp(ts + *s * 0.15f - 0.075f, 0.f, 1.f); *v = clamp(tv + *v * 0.5f - 0.25f, 0.f, 1.f); } + if (set != NULL) + { + *set = colorset; + } } // Find out which teams are present. If there is only one, @@ -379,6 +400,7 @@ void D_SetupUserInfo () coninfo->aimdist = abs ((int)(autoaim * (float)ANGLE_1)); } coninfo->color = color; + coninfo->colorset = colorset; coninfo->skin = R_FindSkin (skin, 0); coninfo->gender = D_GenderToInt (gender); coninfo->neverswitch = neverswitchonpickup; @@ -564,6 +586,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) "\\name\\%s" "\\autoaim\\%g" "\\color\\%x %x %x" + "\\colorset\\%d" "\\skin\\%s" "\\team\\%d" "\\gender\\%s" @@ -574,6 +597,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) , D_EscapeUserInfo(info->netname).GetChars(), (double)info->aimdist / (float)ANGLE_1, + info->colorset, RPART(info->color), GPART(info->color), BPART(info->color), D_EscapeUserInfo(skins[info->skin].name).GetChars(), info->team, @@ -600,6 +624,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) "\\%g" // movebob "\\%g" // stillbob "\\%s" // playerclass + "\\%d" // colorset , D_EscapeUserInfo(info->netname).GetChars(), (double)info->aimdist / (float)ANGLE_1, @@ -612,7 +637,8 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) (float)(info->MoveBob) / 65536.f, (float)(info->StillBob) / 65536.f, info->PlayerClass == -1 ? "Random" : - D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars() + D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars(), + info->colorset ); } } @@ -716,7 +742,15 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update) break; case INFO_Color: - info->color = V_GetColorFromString (NULL, value); + case INFO_ColorSet: + if (infotype == INFO_Color) + { + info->color = V_GetColorFromString (NULL, value); + } + else + { + info->colorset = atoi(value); + } R_BuildPlayerTranslation (i); if (StatusBar != NULL && i == StatusBar->GetPlayer()) { @@ -806,6 +840,10 @@ FArchive &operator<< (FArchive &arc, userinfo_t &info) arc.Read (&info.netname, sizeof(info.netname)); } arc << info.team << info.aimdist << info.color << info.skin << info.gender << info.neverswitch; + if (SaveVersion >= 2193) + { + arc << info.colorset; + } return arc; } @@ -831,6 +869,7 @@ CCMD (playerinfo) Printf ("Team: %s (%d)\n", ui->team == TEAM_NONE ? "None" : Teams[ui->team].GetName (), ui->team); Printf ("Aimdist: %d\n", ui->aimdist); Printf ("Color: %06x\n", ui->color); + Printf ("ColorSet: %d\n", ui->colorset); Printf ("Skin: %s (%d)\n", skins[ui->skin].name, ui->skin); Printf ("Gender: %s (%d)\n", GenderNames[ui->gender], ui->gender); Printf ("NeverSwitch: %d\n", ui->neverswitch); diff --git a/src/d_player.h b/src/d_player.h index 3c9ad954..64d90132 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -71,6 +71,21 @@ enum APMETA_Slot9, }; +// Standard pre-defined skin colors +struct FPlayerColorSet +{ + FName Name; // Name of this color + + int Lump; // Lump to read the translation from, otherwise use next 2 fields + BYTE FirstColor, LastColor; // Describes the range of colors to use for the translation + + BYTE RepresentativeColor; // A palette entry representative of this translation, + // for map arrows and status bar backgrounds and such +}; +void P_AddPlayerColorSet(FName classname, int setnum, const FPlayerColorSet *colorset); +FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum); +void P_EnumPlayerColorSets(FName classname, TArray *out); + class player_t; class APlayerPawn : public AActor @@ -223,6 +238,7 @@ struct userinfo_t BYTE team; int aimdist; int color; + int colorset; int skin; int gender; bool neverswitch; diff --git a/src/f_finale.cpp b/src/f_finale.cpp index e08f249e..2b9fc877 100644 --- a/src/f_finale.cpp +++ b/src/f_finale.cpp @@ -117,6 +117,10 @@ void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int } FinaleFlat = (flat != NULL && *flat != 0) ? flat : gameinfo.finaleFlat; + if (FinaleFlat != NULL && FinaleFlat[0] == '$') + { + FinaleFlat = GStrings(FinaleFlat + 1); + } if (textInLump) { @@ -758,7 +762,7 @@ void F_CastDrawer (void) FTexture* pic; // erase the entire screen to a background - screen->DrawTexture (TexMan["BOSSBACK"], 0, 0, + screen->DrawTexture (TexMan[GStrings("bgcastcall")], 0, 0, DTA_DestWidth, screen->GetWidth(), DTA_DestHeight, screen->GetHeight(), TAG_DONE); diff --git a/src/g_level.cpp b/src/g_level.cpp index 1b0bd113..cc304294 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1039,7 +1039,7 @@ void G_WorldDone (void) { F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder, thiscluster->cdtrack, thiscluster->cdid, - thiscluster->finaleflat, thiscluster->ExitText, + thiscluster->FinaleFlat, thiscluster->ExitText, thiscluster->flags & CLUSTER_EXITTEXTINLUMP, thiscluster->flags & CLUSTER_FINALEPIC, thiscluster->flags & CLUSTER_LOOKUPEXITTEXT, @@ -1057,7 +1057,7 @@ void G_WorldDone (void) { F_StartFinale (nextcluster->MessageMusic, nextcluster->musicorder, nextcluster->cdtrack, nextcluster->cdid, - nextcluster->finaleflat, nextcluster->EnterText, + nextcluster->FinaleFlat, nextcluster->EnterText, nextcluster->flags & CLUSTER_ENTERTEXTINLUMP, nextcluster->flags & CLUSTER_FINALEPIC, nextcluster->flags & CLUSTER_LOOKUPENTERTEXT, @@ -1067,7 +1067,7 @@ void G_WorldDone (void) { F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder, thiscluster->cdtrack, nextcluster->cdid, - thiscluster->finaleflat, thiscluster->ExitText, + thiscluster->FinaleFlat, thiscluster->ExitText, thiscluster->flags & CLUSTER_EXITTEXTINLUMP, thiscluster->flags & CLUSTER_FINALEPIC, thiscluster->flags & CLUSTER_LOOKUPEXITTEXT, diff --git a/src/g_level.h b/src/g_level.h index 3b085163..7ea2e314 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -77,6 +77,7 @@ struct FMapInfoParser bool ParseLookupName(FString &dest); void ParseMusic(FString &name, int &order); void ParseLumpOrTextureName(char *name); + void ParseLumpOrTextureName(FString &name); void ParseCluster(); void ParseNextMap(char *mapname); @@ -439,7 +440,7 @@ extern TArray EndSequences; struct cluster_info_t { int cluster; - char finaleflat[9]; + FString FinaleFlat; FString ExitText; FString EnterText; FString MessageMusic; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index f85b0896..f9fe5e82 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -389,7 +389,7 @@ bool level_info_t::isValid() void cluster_info_t::Reset() { cluster = 0; - finaleflat[0] = 0; + FinaleFlat = ""; ExitText = ""; EnterText = ""; MessageMusic = ""; @@ -615,6 +615,12 @@ void FMapInfoParser::ParseLumpOrTextureName(char *name) name[8]=0; } +void FMapInfoParser::ParseLumpOrTextureName(FString &name) +{ + sc.MustGetString(); + name = sc.String; +} + //========================================================================== // @@ -691,12 +697,12 @@ void FMapInfoParser::ParseCluster() else if (sc.Compare("flat")) { ParseAssign(); - ParseLumpOrTextureName(clusterinfo->finaleflat); + ParseLumpOrTextureName(clusterinfo->FinaleFlat); } else if (sc.Compare("pic")) { ParseAssign(); - ParseLumpOrTextureName(clusterinfo->finaleflat); + ParseLumpOrTextureName(clusterinfo->FinaleFlat); clusterinfo->flags |= CLUSTER_FINALEPIC; } else if (sc.Compare("hub")) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 3b4f639d..c56ce1d6 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -308,7 +308,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms) if (!parms.alphaChannel) { int translation = 0; - if (parms.remap != NULL) + if (parms.remap != NULL && !parms.remap->Inactive) { GLTranslationPalette * pal = static_cast(parms.remap->GetNative()); if (pal) translation = -pal->GetIndex(); diff --git a/src/gl/textures/gl_translate.cpp b/src/gl/textures/gl_translate.cpp index 3eaac3aa..9865f127 100644 --- a/src/gl/textures/gl_translate.cpp +++ b/src/gl/textures/gl_translate.cpp @@ -79,7 +79,7 @@ int GLTranslationPalette::GetInternalTranslation(int trans) if (trans <= 0) return 0; FRemapTable *remap = TranslationToTable(trans); - if (remap == NULL) return 0; + if (remap == NULL || remap->Inactive) return 0; GLTranslationPalette *tpal = static_cast(remap->GetNative()); if (tpal == NULL) return 0; diff --git a/src/gl/textures/gl_translate.h b/src/gl/textures/gl_translate.h index 064a7bc6..1bdc92e5 100644 --- a/src/gl/textures/gl_translate.h +++ b/src/gl/textures/gl_translate.h @@ -37,21 +37,6 @@ public: } bool Update(); int GetIndex() const { return Index; } - - static int GetIndex(FRemapTable *remap) - { - GLTranslationPalette * pal = static_cast(remap->GetNative()); - if (pal) return pal->GetIndex(); - else return 0; - } - - static int GetIndex(unsigned int translation_code) - { - if (translation_code == 0) return 0; - else if (translation_code == TRANSLATION(TRANSLATION_Standard, 7)) return TRANSLATION_ICE; - else if (translation_code == TRANSLATION(TRANSLATION_Standard, 8)) return TRANSLATION_INTENSITY; - else return GetInternalTranslation(translation_code); - } }; diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index 456652bc..1d881bd3 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -418,7 +418,7 @@ void HU_DrawColorBar(int x, int y, int height, int playernum) { float h, s, v, r, g, b; - D_GetPlayerColor (playernum, &h, &s, &v); + D_GetPlayerColor (playernum, &h, &s, &v, NULL); HSVtoRGB (&r, &g, &b, h, s, v); screen->Clear (x, y, x + 24*CleanXfac, y + height, -1, diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 23383a6f..2b87900b 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -46,8 +46,6 @@ #include "d_dehacked.h" #include "gi.h" -EXTERN_CVAR(Bool, r_forceplayertranslation) - // [RH] Actually handle the cheat. The cheat code in st_stuff.c now just // writes some bytes to the network data stream, and the network code // later calls us. @@ -321,8 +319,10 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->special1 = 0; // required for the Hexen fighter's fist attack. // This gets set by AActor::Die as flag for the wimpy death and must be reset here. player->mo->SetState (player->mo->SpawnState); - if (multiplayer || r_forceplayertranslation) + if (!(player->mo->flags2 & MF2_DONTTRANSLATE)) + { player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); + } player->mo->DamageType = NAME_None; // player->mo->GiveDefaultInventory(); if (player->ReadyWeapon != NULL) diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 88eac1ed..7628b336 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -118,7 +118,7 @@ protected: // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- -void R_GetPlayerTranslation (int color, FPlayerSkin *skin, FRemapTable *table); +void R_GetPlayerTranslation (int color, const FPlayerColorSet *colorset, FPlayerSkin *skin, FRemapTable *table); // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -188,6 +188,7 @@ static void M_EditPlayerName (int choice); static void M_ChangePlayerTeam (int choice); static void M_PlayerNameChanged (FSaveGameNode *dummy); static void M_PlayerNameNotChanged (); +static void M_ChangeColorSet (int choice); static void M_SlidePlayerRed (int choice); static void M_SlidePlayerGreen (int choice); static void M_SlidePlayerBlue (int choice); @@ -269,6 +270,7 @@ static int PlayerSkin; static FState *PlayerState; static int PlayerTics; static int PlayerRotation; +static TArray PlayerColorSets; static FTexture *SavePic; static FBrokenLines *SaveComment; @@ -536,10 +538,11 @@ static oldmenuitem_t PlayerSetupMenu[] = { { 1,0,'n',NULL,M_EditPlayerName, CR_UNTRANSLATED}, { 2,0,'t',NULL,M_ChangePlayerTeam, CR_UNTRANSLATED}, + { 2,0,'c',NULL,M_ChangeColorSet, CR_UNTRANSLATED}, { 2,0,'r',NULL,M_SlidePlayerRed, CR_UNTRANSLATED}, { 2,0,'g',NULL,M_SlidePlayerGreen, CR_UNTRANSLATED}, { 2,0,'b',NULL,M_SlidePlayerBlue, CR_UNTRANSLATED}, - { 2,0,'c',NULL,M_ChangeClass, CR_UNTRANSLATED}, + { 2,0,'t',NULL,M_ChangeClass, CR_UNTRANSLATED}, { 2,0,'s',NULL,M_ChangeSkin, CR_UNTRANSLATED}, { 2,0,'e',NULL,M_ChangeGender, CR_UNTRANSLATED}, { 2,0,'a',NULL,M_ChangeAutoAim, CR_UNTRANSLATED} @@ -2088,13 +2091,16 @@ void M_PlayerSetup (void) PlayerClass = &PlayerClasses[players[consoleplayer].CurrentPlayerClass]; } PlayerSkin = players[consoleplayer].userinfo.skin; - R_GetPlayerTranslation (players[consoleplayer].userinfo.color, &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); + R_GetPlayerTranslation (players[consoleplayer].userinfo.color, + P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset), + &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); PlayerState = GetDefaultByType (PlayerClass->Type)->SeeState; PlayerTics = PlayerState->GetTics(); if (FireTexture == NULL) { FireTexture = new FBackdropTexture; } + P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets); } static void M_PlayerSetupTicker (void) @@ -2112,6 +2118,7 @@ static void M_PlayerSetupTicker (void) item = (MenuTime>>2) % (ClassMenuDef.numitems-1); PlayerClass = &PlayerClasses[D_PlayerClassToInt (ClassMenuItems[item].name)]; + P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets); } else { @@ -2125,6 +2132,7 @@ static void M_PlayerSetupTicker (void) PlayerSkin = R_FindSkin (skins[PlayerSkin].name, int(PlayerClass - &PlayerClasses[0])); R_GetPlayerTranslation (players[consoleplayer].userinfo.color, + P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset), &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); } @@ -2280,19 +2288,27 @@ static void M_PlayerSetupDrawer () DTA_Clean, true, TAG_DONE); } - // Draw player color sliders - //V_DrawTextCleanMove (CR_GREY, PSetupDef.x, PSetupDef.y + LINEHEIGHT, "Color"); + // Draw player color selection and sliders + FPlayerColorSet *colorset = P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset); + x = SmallFont->StringWidth("Color") + 8 + PSetupDef.x; + screen->DrawText(SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*2+yo, "Color", DTA_Clean, true, TAG_DONE); + screen->DrawText(SmallFont, value, x, PSetupDef.y + LINEHEIGHT*2+yo, + colorset != NULL ? colorset->Name.GetChars() : "Custom", DTA_Clean, true, TAG_DONE); - screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*2+yo, "Red", DTA_Clean, true, TAG_DONE); - screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*3+yo, "Green", DTA_Clean, true, TAG_DONE); - screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*4+yo, "Blue", DTA_Clean, true, TAG_DONE); + // Only show the sliders for a custom color set. + if (colorset == NULL) + { + screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*2.875)+yo, "Red", DTA_Clean, true, TAG_DONE); + screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*3.5)+yo, "Green", DTA_Clean, true, TAG_DONE); + screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*4.125)+yo, "Blue", DTA_Clean, true, TAG_DONE); - x = SmallFont->StringWidth ("Green") + 8 + PSetupDef.x; - color = players[consoleplayer].userinfo.color; + x = SmallFont->StringWidth ("Green") + 8 + PSetupDef.x; + color = players[consoleplayer].userinfo.color; - M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*2+yo, RPART(color)); - M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*3+yo, GPART(color)); - M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*4+yo, BPART(color)); + M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*2.875)+yo, RPART(color)); + M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*3.5)+yo, GPART(color)); + M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*4.125)+yo, BPART(color)); + } // [GRB] Draw class setting int pclass = players[consoleplayer].userinfo.PlayerClass; @@ -2587,7 +2603,9 @@ static void M_ChangeSkin (int choice) PlayerSkin = (PlayerSkin < (int)numskins - 1) ? PlayerSkin + 1 : 0; } while (!PlayerClass->CheckSkin (PlayerSkin)); - R_GetPlayerTranslation (players[consoleplayer].userinfo.color, &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); + R_GetPlayerTranslation (players[consoleplayer].userinfo.color, + P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset), + &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); cvar_set ("skin", skins[PlayerSkin].name); } @@ -2708,13 +2726,50 @@ static void M_ChangePlayerTeam (int choice) } } +static void M_ChangeColorSet (int choice) +{ + int curpos = (int)PlayerColorSets.Size(); + int mycolorset = players[consoleplayer].userinfo.colorset; + while (--curpos >= 0) + { + if (PlayerColorSets[curpos] == mycolorset) + break; + } + if (choice == 0) + { + curpos--; + } + else + { + curpos++; + } + if (curpos < -1) + { + curpos = (int)PlayerColorSets.Size() - 1; + } + else if (curpos >= (int)PlayerColorSets.Size()) + { + curpos = -1; + } + mycolorset = (curpos >= 0) ? PlayerColorSets[curpos] : -1; + + char command[24]; + mysnprintf(command, countof(command), "colorset %d", mycolorset); + C_DoCommand(command); + R_GetPlayerTranslation(players[consoleplayer].userinfo.color, + P_GetPlayerColorSet(PlayerClass->Type->TypeName, mycolorset), + &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); +} + static void SendNewColor (int red, int green, int blue) { char command[24]; mysnprintf (command, countof(command), "color \"%02x %02x %02x\"", red, green, blue); C_DoCommand (command); - R_GetPlayerTranslation (MAKERGB (red, green, blue), &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); + R_GetPlayerTranslation(MAKERGB (red, green, blue), + P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset), + &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); } static void M_SlidePlayerRed (int choice) @@ -3646,8 +3701,31 @@ void M_Drawer () // [RH] Use options menu cursor for the player setup menu. if (skullAnimCounter < 6) { + double item; + // The green slider is halfway between lines, and the red and + // blue ones are offset slightly to make room for it. + if (itemOn < 3) + { + item = itemOn; + } + else if (itemOn > 5) + { + item = itemOn - 1; + } + else if (itemOn == 3) + { + item = 2.875; + } + else if (itemOn == 4) + { + item = 3.5; + } + else + { + item = 4.125; + } screen->DrawText (ConFont, CR_RED, x - 16, - currentMenu->y + itemOn*PLAYERSETUP_LINEHEIGHT + + currentMenu->y + int(item*PLAYERSETUP_LINEHEIGHT) + (!(gameinfo.gametype & (GAME_DoomStrifeChex)) ? 6 : -1), "\xd", DTA_Clean, true, TAG_DONE); } @@ -4037,4 +4115,5 @@ static void PickPlayerClass () } PlayerClass = &PlayerClasses[pclass]; + P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets); } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index c899c584..846b699e 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3284,8 +3284,8 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) case ACSF_CheckActorClass: { - AActor *a = args[0] == 0 ? (AActor *)activator : SingleActorFromTID(args[0], NULL); - return a->GetClass()->TypeName == FName(FBehavior::StaticLookupString(args[1])); + AActor *a = args[0] == 0 ? (AActor *)activator : SingleActorFromTID(args[0], NULL); + return a == NULL ? false : a->GetClass()->TypeName == FName(FBehavior::StaticLookupString(args[1])); } case ACSF_SoundSequenceOnActor: diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index bf858a16..f581312f 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -114,14 +114,6 @@ CUSTOM_CVAR (Float, sv_gravity, 800.f, CVAR_SERVERINFO|CVAR_NOSAVE) level.gravity = self; } -CUSTOM_CVAR(Bool, r_forceplayertranslation, false, CVAR_ARCHIVE|CVAR_NOINITCALL) -{ - if (!multiplayer && players[0].mo != NULL) - { - players[0].mo->Translation = self? TRANSLATION(TRANSLATION_Players, 0) : 0; - } -} - CVAR (Bool, cl_missiledecals, true, CVAR_ARCHIVE) CVAR (Bool, addrocketexplosion, false, CVAR_ARCHIVE) @@ -3988,14 +3980,15 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer) p->userinfo.skin = R_FindSkin (skins[p->userinfo.skin].name, p->CurrentPlayerClass); StatusBar->SetFace (&skins[p->userinfo.skin]); - // [RH] Be sure the player has the right translation - R_BuildPlayerTranslation (playernum); - // [RH] set color translations for player sprites - if (multiplayer || r_forceplayertranslation) + if (!(mobj->flags2 & MF2_DONTTRANSLATE)) + { + // [RH] Be sure the player has the right translation + R_BuildPlayerTranslation (playernum); + + // [RH] set color translations for player sprites mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum); - else - mobj->Translation = 0; + } mobj->angle = spawn_angle; mobj->pitch = mobj->roll = 0; diff --git a/src/p_user.cpp b/src/p_user.cpp index ff1a80da..78e6eeb2 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -55,6 +55,9 @@ static FRandom pr_skullpop ("SkullPop"); +// Color set class name -> mapping table +typedef TMap FPlayerColorSetMap; +TMap PlayerToColorsMap; // [RH] # of ticks to complete a turn180 #define TURN180_TICKS ((TICRATE / 4) + 1) @@ -2631,3 +2634,66 @@ void player_t::Serialize (FArchive &arc) } } + +static FPlayerColorSetMap *GetPlayerColors(FName classname, bool create) +{ + FPlayerColorSetMap *map, **value; + + value = PlayerToColorsMap.CheckKey(classname); + if (value == NULL) + { + if (create) + { + map = new FPlayerColorSetMap; + PlayerToColorsMap.Insert(classname, map); + } + else + { + map = NULL; + } + } + else + { + map = *value; + } + return map; +} + +void P_AddPlayerColorSet(FName classname, int setnum, const FPlayerColorSet *colorset) +{ + FPlayerColorSetMap *map = GetPlayerColors(classname, true); + (*map)[setnum] = *colorset; +} + +FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum) +{ + FPlayerColorSetMap *map = GetPlayerColors(classname, false); + if (map == NULL) + { + return NULL; + } + return map->CheckKey(setnum); +} + +static int STACK_ARGS intcmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +void P_EnumPlayerColorSets(FName classname, TArray *out) +{ + out->Clear(); + FPlayerColorSetMap *map = GetPlayerColors(classname, false); + if (map != NULL) + { + FPlayerColorSetMap::Iterator it(*map); + FPlayerColorSetMap::Pair *pair; + + while (it.NextPair(pair)) + { + out->Push(pair->Key); + } + qsort(&(*out)[0], out->Size(), sizeof(int), intcmp); + } +} + diff --git a/src/r_draw.cpp b/src/r_draw.cpp index 12cf3c51..ce836f83 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -2181,7 +2181,7 @@ ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, if (translation != 0) { FRemapTable *table = TranslationToTable(translation); - if (table != NULL) + if (table != NULL && !table->Inactive) { dc_translation = table->Remap; } diff --git a/src/r_translate.cpp b/src/r_translate.cpp index 8e74f444..045dc3f4 100644 --- a/src/r_translate.cpp +++ b/src/r_translate.cpp @@ -46,6 +46,7 @@ #include "sc_man.h" #include "doomerrors.h" #include "i_system.h" +#include "w_wad.h" #include "gi.h" #include "stats.h" @@ -78,7 +79,7 @@ const BYTE IcePalette[16][3] = FRemapTable::FRemapTable(int count) { assert(count <= 256); - + Inactive = false; Alloc(count); // Note that the tables are left uninitialized. It is assumed that @@ -163,6 +164,7 @@ FRemapTable &FRemapTable::operator=(const FRemapTable &o) { Alloc(o.NumEntries); } + Inactive = o.Inactive; memcpy(Remap, o.Remap, NumEntries*sizeof(*Remap) + NumEntries*sizeof(*Palette)); return *this; } @@ -892,7 +894,8 @@ static void SetRemap(FRemapTable *table, int i, float r, float g, float b) // //---------------------------------------------------------------------------- -static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable) +static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerColorSet *colorset, + FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable) { int i; BYTE start = skin->range0start; @@ -927,6 +930,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s // [GRB] Don't translate skins with color range 0-0 (APlayerPawn default) if (start == 0 && end == 0) { + table->Inactive = true; table->UpdateNative(); return; } @@ -936,7 +940,46 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s bases = s; basev = v; - if (gameinfo.gametype & GAME_DoomStrifeChex) + if (colorset != NULL && colorset->Lump >= 0 && Wads.LumpLength(colorset->Lump) < 256) + { // Bad table length. Ignore it. + colorset = NULL; + } + + if (colorset != NULL) + { + // Use the pre-defined range instead of a custom one. + if (colorset->Lump < 0) + { + int first = colorset->FirstColor; + if (start == end) + { + table->Remap[i] = (first + colorset->LastColor) / 2; + } + else + { + int palrange = colorset->LastColor - first; + for (i = start; i <= end; ++i) + { + table->Remap[i] = GPalette.Remap[first + palrange * (i - start) / (end - start)]; + } + } + } + else + { + FMemLump translump = Wads.ReadLump(colorset->Lump); + const BYTE *trans = (const BYTE *)translump.GetMem(); + for (i = start; i <= end; ++i) + { + table->Remap[i] = GPalette.Remap[trans[i]]; + } + } + for (i = start; i <= end; ++i) + { + table->Palette[i] = GPalette.BaseColors[table->Remap[i]]; + table->Palette[i].a = 255; + } + } + else if (gameinfo.gametype & GAME_DoomStrifeChex) { // Build player sprite translation s -= 0.23f; @@ -1014,9 +1057,19 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s SetRemap(table, i, r, g, b); } } - - // Build lifegem translation - if (alttable) + } + if (gameinfo.gametype == GAME_Hexen && alttable != NULL) + { + // Build Hexen's lifegem translation. + + // Is the player's translation range the same as the gem's and we are using a + // predefined translation? If so, then use the same one for the gem. Otherwise, + // build one as per usual. + if (colorset != NULL && start == 164 && end == 185) + { + *alttable = *table; + } + else { for (i = 164; i <= 185; ++i) { @@ -1027,9 +1080,10 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s HSVtoRGB (&r, &g, &b, h, s*bases, v*basev); SetRemap(alttable, i, r, g, b); } - alttable->UpdateNative(); } + alttable->UpdateNative(); } + table->Inactive = false; table->UpdateNative(); } @@ -1042,10 +1096,11 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s void R_BuildPlayerTranslation (int player) { float h, s, v; + FPlayerColorSet *colorset; - D_GetPlayerColor (player, &h, &s, &v); + D_GetPlayerColor (player, &h, &s, &v, &colorset); - R_CreatePlayerTranslation (h, s, v, + R_CreatePlayerTranslation (h, s, v, colorset, &skins[players[player].userinfo.skin], translationtables[TRANSLATION_Players][player], translationtables[TRANSLATION_PlayersExtra][player]); @@ -1057,13 +1112,17 @@ void R_BuildPlayerTranslation (int player) // //---------------------------------------------------------------------------- -void R_GetPlayerTranslation (int color, FPlayerSkin *skin, FRemapTable *table) +void R_GetPlayerTranslation (int color, const FPlayerColorSet *colorset, FPlayerSkin *skin, FRemapTable *table) { float h, s, v; + if (colorset != NULL) + { + color = colorset->RepresentativeColor; + } RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f, &h, &s, &v); - R_CreatePlayerTranslation (h, s, v, skin, table, NULL); + R_CreatePlayerTranslation (h, s, v, colorset, skin, table, NULL); } diff --git a/src/r_translate.h b/src/r_translate.h index 730dac54..21488155 100644 --- a/src/r_translate.h +++ b/src/r_translate.h @@ -46,6 +46,7 @@ struct FRemapTable PalEntry *Palette; // The ideal palette this maps to FNativePalette *Native; // The Palette stored in a HW texture int NumEntries; // # of elements in this table (usually 256) + bool Inactive; // This table is inactive and should be treated as if it was passed as NULL private: void Free(); diff --git a/src/s_playlist.cpp b/src/s_playlist.cpp index 1ab294dc..e92a5cee 100644 --- a/src/s_playlist.cpp +++ b/src/s_playlist.cpp @@ -198,7 +198,7 @@ int FPlayList::Advance () int FPlayList::Backup () { - if (--Position < 0) + if (Position-- == 0) { Position = Songs.Size() - 1; } diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index 83c75410..38e820c8 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -112,7 +112,10 @@ CUSTOM_CVAR (Float, snd_musicvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) else { // Set general music volume. - GSnd->SetMusicVolume(clamp(self * relative_volume, 0, 1)); + if (GSnd != NULL) + { + GSnd->SetMusicVolume(clamp(self * relative_volume, 0, 1)); + } // For music not implemented through the digital sound system, // let them know about the change. if (currSong != NULL) diff --git a/src/svnrevision.h b/src/svnrevision.h index 1121a6c6..9f05693f 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "2187" -#define ZD_SVN_REVISION_NUMBER 2187 +#define ZD_SVN_REVISION_STRING "2198" +#define ZD_SVN_REVISION_NUMBER 2198 diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 884e596e..5a8bfe0f 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1860,6 +1860,57 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorrange, I_I, PlayerPawn) info->Class->Meta.SetMetaInt (APMETA_ColorRange, (start & 255) | ((end & 255) << 8)); } +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(player, colorset, ISIII, PlayerPawn) +{ + PROP_INT_PARM(setnum, 0); + PROP_STRING_PARM(setname, 1); + PROP_INT_PARM(rangestart, 2); + PROP_INT_PARM(rangeend, 3); + PROP_INT_PARM(representative_color, 4); + + FPlayerColorSet color; + color.Name = setname; + color.Lump = -1; + color.FirstColor = rangestart; + color.LastColor = rangeend; + color.RepresentativeColor = representative_color; + + if (setnum < 0) + { + bag.ScriptPosition.Message(MSG_WARNING, "Color set number must not be negative.\n"); + } + else + { + P_AddPlayerColorSet(info->Class->TypeName, setnum, &color); + } +} + +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(player, colorsetfile, ISSI, PlayerPawn) +{ + PROP_INT_PARM(setnum, 0); + PROP_STRING_PARM(setname, 1); + PROP_STRING_PARM(rangefile, 2); + PROP_INT_PARM(representative_color, 3); + + FPlayerColorSet color; + color.Name = setname; + color.Lump = Wads.CheckNumForName(rangefile); + color.RepresentativeColor = representative_color; + if (setnum < 0) + { + bag.ScriptPosition.Message(MSG_WARNING, "Color set number must not be negative.\n"); + } + else if (color.Lump >= 0) + { + P_AddPlayerColorSet(info->Class->TypeName, setnum, &color); + } +} //========================================================================== // //========================================================================== diff --git a/src/v_draw.cpp b/src/v_draw.cpp index e46a99d1..42b0b514 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -527,6 +527,10 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag case DTA_Translation: parms->remap = va_arg(tags, FRemapTable *); + if (parms->remap != NULL && parms->remap->Inactive) + { // If it's inactive, pretend we were passed NULL instead. + parms->remap = NULL; + } break; case DTA_ColorOverlay: diff --git a/src/v_font.cpp b/src/v_font.cpp index 56a7ad81..ea6feb14 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -1352,8 +1352,8 @@ FSinglePicFont::FSinglePicFont(const char *picname) FTexture *pic = TexMan[picnum]; Name = copystring(picname); - FontHeight = pic->GetHeight(); - SpaceWidth = pic->GetWidth(); + FontHeight = pic->GetScaledHeight(); + SpaceWidth = pic->GetScaledWidth(); GlobalKerning = 0; FirstChar = LastChar = 'A'; ActiveColors = 0; diff --git a/src/v_text.cpp b/src/v_text.cpp index be386e99..715e0609 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -276,7 +276,7 @@ int FFont::StringWidth (const BYTE *string) const ++string; } } - else if (*string != '\0') + if (*string != '\0') { ++string; } @@ -324,7 +324,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string) i = w = 0; - while ( (c = *string++) && i < 128 ) + while ( (c = *string++) && i < countof(lines) ) { if (c == TEXTCOLOR_ESCAPE) { @@ -400,7 +400,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string) } // String here is pointing one character after the '\0' - if (i < 128 && --string - start >= 1) + if (i < countof(lines) && --string - start >= 1) { const BYTE *s = start; diff --git a/wadsrc/static/actors/chex/chexplayer.txt b/wadsrc/static/actors/chex/chexplayer.txt index 5003ea80..210a6847 100644 --- a/wadsrc/static/actors/chex/chexplayer.txt +++ b/wadsrc/static/actors/chex/chexplayer.txt @@ -16,4 +16,14 @@ actor ChexPlayer : DoomPlayer player.WeaponSlot 5, ZorchPropulsor player.WeaponSlot 6, PhasingZorcher player.WeaponSlot 7, LAZDevice + + Player.Colorset 0, "Light Blue", 0xC0, 0xCF, 0xC2 + Player.Colorset 1, "Green", 0x70, 0x7F, 0x72 + Player.Colorset 2, "Gray", 0x60, 0x6F, 0x62 + Player.Colorset 3, "Brown", 0x40, 0x4F, 0x42 + Player.Colorset 4, "Red", 0x20, 0x2F, 0x22 + Player.Colorset 5, "Light Gray", 0x58, 0x67, 0x5A + Player.Colorset 6, "Light Brown", 0x38, 0x47, 0x3A + Player.Colorset 7, "Light Red", 0xB0, 0xBF, 0xB2 + } diff --git a/wadsrc/static/actors/doom/doomplayer.txt b/wadsrc/static/actors/doom/doomplayer.txt index 9138fc64..3f81eaac 100644 --- a/wadsrc/static/actors/doom/doomplayer.txt +++ b/wadsrc/static/actors/doom/doomplayer.txt @@ -11,7 +11,6 @@ ACTOR DoomPlayer : PlayerPawn Height 56 Mass 100 PainChance 255 - Player.ColorRange 112, 127 Player.DisplayName "Marine" Player.CrouchSprite "PLYC" Player.StartItem "Pistol" @@ -24,6 +23,17 @@ ACTOR DoomPlayer : PlayerPawn Player.WeaponSlot 5, RocketLauncher Player.WeaponSlot 6, PlasmaRifle Player.WeaponSlot 7, BFG9000 + + Player.ColorRange 112, 127 + Player.Colorset 0, "Green", 0x70, 0x7F, 0x72 + Player.Colorset 1, "Gray", 0x60, 0x6F, 0x62 + Player.Colorset 2, "Brown", 0x40, 0x4F, 0x42 + Player.Colorset 3, "Red", 0x20, 0x2F, 0x22 + // Doom Legacy additions + Player.Colorset 4, "Light Gray", 0x58, 0x67, 0x5A + Player.Colorset 5, "Light Brown", 0x38, 0x47, 0x3A + Player.Colorset 6, "Light Red", 0xB0, 0xBF, 0xB2 + Player.Colorset 7, "Light Blue", 0xC0, 0xCF, 0xC2 States { diff --git a/wadsrc/static/actors/heretic/hereticplayer.txt b/wadsrc/static/actors/heretic/hereticplayer.txt index 9e36f8d7..77ec994d 100644 --- a/wadsrc/static/actors/heretic/hereticplayer.txt +++ b/wadsrc/static/actors/heretic/hereticplayer.txt @@ -6,7 +6,6 @@ ACTOR HereticPlayer : PlayerPawn Mass 100 Painchance 255 Speed 1 - Player.ColorRange 225, 240 Player.DisplayName "Corvus" Player.StartItem "GoldWand" Player.StartItem "Staff" @@ -18,7 +17,20 @@ ACTOR HereticPlayer : PlayerPawn Player.WeaponSlot 5, SkullRod Player.WeaponSlot 6, PhoenixRod Player.WeaponSlot 7, Mace - + + Player.ColorRange 225, 240 + Player.Colorset 0, "Green", 225, 240, 238 + Player.Colorset 1, "Yellow", 114, 129, 127 + Player.Colorset 2, "Red", 145, 160, 158 + Player.Colorset 3, "Blue", 190, 205, 203 + // Doom Legacy additions + Player.Colorset 4, "Brown", 67, 82, 80 + Player.Colorset 5, "Light Gray", 9, 24, 22 + Player.Colorset 6, "Light Brown", 74, 89, 87 + Player.Colorset 7, "Light Red", 150, 165, 163 + Player.Colorset 8, "Light Blue", 192, 207, 205 + Player.Colorset 9, "Beige", 95, 110, 108 + States { Spawn: diff --git a/wadsrc/static/actors/hexen/clericplayer.txt b/wadsrc/static/actors/hexen/clericplayer.txt index 493faffd..4fe6629e 100644 --- a/wadsrc/static/actors/hexen/clericplayer.txt +++ b/wadsrc/static/actors/hexen/clericplayer.txt @@ -15,7 +15,6 @@ ACTOR ClericPlayer : PlayerPawn RadiusDamageFactor 0.25 Player.JumpZ 9 Player.Viewheight 48 - Player.ColorRange 146, 163 Player.SpawnClass "Cleric" Player.DisplayName "Cleric" Player.SoundClass "cleric" @@ -29,6 +28,16 @@ ACTOR ClericPlayer : PlayerPawn Player.WeaponSlot 3, CWeapFlame Player.WeaponSlot 4, CWeapWraithverge + Player.ColorRange 146, 163 + Player.Colorset 0, "Blue", 146, 163, 161 + Player.ColorsetFile 1, "Red", "TRANTBL7", 0xB3 + Player.ColorsetFile 2, "Gold", "TRANTBL8", 0x8C + Player.ColorsetFile 3, "Dull Green", "TRANTBL9", 0x41 + Player.ColorsetFile 4, "Green", "TRANTBLA", 0xC9 + Player.ColorsetFile 5, "Gray", "TRANTBLB", 0x30 + Player.ColorsetFile 6, "Brown", "TRANTBLC", 0x72 + Player.ColorsetFile 7, "Purple", "TRANTBLD", 0xEE + States { Spawn: diff --git a/wadsrc/static/actors/hexen/fighterplayer.txt b/wadsrc/static/actors/hexen/fighterplayer.txt index 5c307bd6..277a2986 100644 --- a/wadsrc/static/actors/hexen/fighterplayer.txt +++ b/wadsrc/static/actors/hexen/fighterplayer.txt @@ -14,7 +14,6 @@ ACTOR FighterPlayer : PlayerPawn RadiusDamageFactor 0.25 Player.JumpZ 9 Player.Viewheight 48 - Player.ColorRange 246, 254 Player.SpawnClass "Fighter" Player.DisplayName "Fighter" Player.SoundClass "fighter" @@ -29,6 +28,16 @@ ACTOR FighterPlayer : PlayerPawn Player.WeaponSlot 3, FWeapHammer Player.WeaponSlot 4, FWeapQuietus + Player.ColorRange 246, 254 + Player.Colorset 0, "Gold", 246, 254, 253 + Player.ColorsetFile 1, "Red", "TRANTBL0", 0xAC + Player.ColorsetFile 2, "Blue", "TRANTBL1", 0x9D + Player.ColorsetFile 3, "Dull Green", "TRANTBL2", 0x3E + Player.ColorsetFile 4, "Green", "TRANTBL3", 0xC8 + Player.ColorsetFile 5, "Gray", "TRANTBL4", 0x2D + Player.ColorsetFile 6, "Brown", "TRANTBL5", 0x6F + Player.ColorsetFile 7, "Purple", "TRANTBL6", 0xEE + States { Spawn: diff --git a/wadsrc/static/actors/hexen/mageplayer.txt b/wadsrc/static/actors/hexen/mageplayer.txt index 2f67d35b..a3469836 100644 --- a/wadsrc/static/actors/hexen/mageplayer.txt +++ b/wadsrc/static/actors/hexen/mageplayer.txt @@ -15,7 +15,6 @@ ACTOR MagePlayer : PlayerPawn RadiusDamageFactor 0.25 Player.JumpZ 9 Player.Viewheight 48 - Player.ColorRange 146, 163 Player.SpawnClass "Mage" Player.DisplayName "Mage" Player.SoundClass "mage" @@ -31,6 +30,16 @@ ACTOR MagePlayer : PlayerPawn Player.WeaponSlot 3, MWeapLightning Player.WeaponSlot 4, MWeapBloodscourge + Player.ColorRange 146, 163 + Player.Colorset 0, "Blue", 146, 163, 161 + Player.ColorsetFile 1, "Red", "TRANTBL7", 0xB3 + Player.ColorsetFile 2, "Gold", "TRANTBL8", 0x8C + Player.ColorsetFile 3, "Dull Green", "TRANTBL9", 0x41 + Player.ColorsetFile 4, "Green", "TRANTBLA", 0xC9 + Player.ColorsetFile 5, "Gray", "TRANTBLB", 0x30 + Player.ColorsetFile 6, "Brown", "TRANTBLC", 0x72 + Player.ColorsetFile 7, "Purple", "TRANTBLD", 0xEE + States { Spawn: diff --git a/wadsrc/static/actors/strife/strifeplayer.txt b/wadsrc/static/actors/strife/strifeplayer.txt index d42dc1ba..1dabeff4 100644 --- a/wadsrc/static/actors/strife/strifeplayer.txt +++ b/wadsrc/static/actors/strife/strifeplayer.txt @@ -9,7 +9,6 @@ ACTOR StrifePlayer : PlayerPawn PainChance 255 Speed 1 MaxStepHeight 16 - Player.ColorRange 128, 143 Player.DisplayName "Rebel" Player.StartItem "PunchDagger" Player.RunHealth 15 @@ -22,6 +21,16 @@ ACTOR StrifePlayer : PlayerPawn Player.WeaponSlot 7, Mauler2, Mauler Player.WeaponSlot 8, Sigil + Player.ColorRange 128, 143 + Player.Colorset 0, "Brown", 0x80, 0x8F, 0x82 + Player.Colorset 1, "Red", 0x40, 0x4F, 0x42 + Player.Colorset 2, "Rust", 0xB0, 0xBF, 0xB2 + Player.Colorset 3, "Gray", 0x10, 0x1F, 0x12 + Player.Colorset 4, "Dark Green", 0x30, 0x3F, 0x32 + Player.Colorset 5, "Gold", 0x50, 0x5F, 0x52 + Player.Colorset 6, "Bright Green", 0x60, 0x6F, 0x62 + Player.Colorset 7, "Blue", 0x90, 0x9F, 0x92 + action native A_ItBurnsItBurns(); action native A_CrispyPlayer(); action native A_HandLower(); diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index a4fd9065..685fda08 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -24,6 +24,11 @@ A80E7EE40E0D0C76A6FBD242BE29FE27 // map15 resetplayerspeed } +6DA6FCBA8089161BDEC6A1D3F6C8D60F // Eternal Doom MAP25 +{ + stairs +} + 10E1E2B36302D31AC4AE68C84B5DC457 // Eternal Doom MAP28 { // What's really sad is that I got a separate bug report for this map diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 4cb444d0..53d74a48 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -570,6 +570,19 @@ PD_ALL6 = "You need all six keys to open this door"; PD_ALL6O = "You need all six keys to activate this object"; PD_ALLKEYS = "You need all the keys"; +// MBF (BOOM?) narration backgrounds +bgflatE1 = "FLOOR4_8"; +bgflatE2 = "SFLR6_1"; +bgflatE3 = "MFLR8_4"; +bgflatE4 = "MFLR8_3"; +bgflat06 = "SLIME16"; +bgflat11 = "RROCK14"; +bgflat20 = "RROCK07"; +bgflat30 = "RROCK17"; +bgflat15 = "RROCK13"; +bgflat31 = "RROCK19"; +bgcastcall = "BOSSBACK"; + // Gameflow messages TXT_FRAGLIMIT = "Fraglimit hit."; TXT_TIMELIMIT = "Timelimit hit.";