Update to ZDoom r2198:

- let players check MF2_NOTRANSLATE so that mods can create player classes which are not subject to
  default player color handling.
- fixed: The ChexPlayer was missing default colorset definitions.
- Final Doom needs its finale flats changed, too.
- It's "BGCASTCALL", not "BOSSBACK".
- Added BOOM/MBF BEX-style narrative background text substitution. There are two changes because
  of this:
  * A cluster's flat definition can now be preceded by a $ to do a string table lookup.
  * Since the standard flat names are now in the LANGUAGE lump, the normal Dehacked substitution
    for these is no longer handled specially and so will not be automatically disabled merely
    by providing your own MAPINFO.
- Setting a Player.ColorRange now completely disables the translation rather than just
  making it an identity map.
- Added support for the original games' player translations, including Hexen's table-based ones.
- Fixed: CheckActorClass needed a NULL check.
- Fixed: FFont::StringWidth() counted the ']' character of a named color escape sequence in
  its width calculation.
- Fixed: FSinglePicFont should set the character size by the scaled size of the texture.
- Fixed: snd_musicvolume needs to check GSnd for NULL, since somebody might have set an
  atexit for it, which gets executed after the sound system shuts down.
- Fixed: FPlayList::Backup() failed to wrap around below entry 0 because Position is
  unsigned now.

git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@744 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
Christoph Oelckers 2010-03-06 11:03:55 +00:00
parent 3a83e3ed57
commit 30c977090c
37 changed files with 490 additions and 109 deletions

View file

@ -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));

View file

@ -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");
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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<int> *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;

View file

@ -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);

View file

@ -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,

View file

@ -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<EndSequence> EndSequences;
struct cluster_info_t
{
int cluster;
char finaleflat[9];
FString FinaleFlat;
FString ExitText;
FString EnterText;
FString MessageMusic;

View file

@ -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"))

View file

@ -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<GLTranslationPalette*>(parms.remap->GetNative());
if (pal) translation = -pal->GetIndex();

View file

@ -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<GLTranslationPalette*>(remap->GetNative());
if (tpal == NULL) return 0;

View file

@ -37,21 +37,6 @@ public:
}
bool Update();
int GetIndex() const { return Index; }
static int GetIndex(FRemapTable *remap)
{
GLTranslationPalette * pal = static_cast<GLTranslationPalette*>(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);
}
};

View file

@ -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,

View file

@ -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)

View file

@ -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<int> 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);
}

View file

@ -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:

View file

@ -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;

View file

@ -55,6 +55,9 @@
static FRandom pr_skullpop ("SkullPop");
// Color set class name -> mapping table
typedef TMap<int, FPlayerColorSet> FPlayerColorSetMap;
TMap<FName, FPlayerColorSetMap *> 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<int> *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);
}
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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();

View file

@ -198,7 +198,7 @@ int FPlayList::Advance ()
int FPlayList::Backup ()
{
if (--Position < 0)
if (Position-- == 0)
{
Position = Songs.Size() - 1;
}

View file

@ -112,7 +112,10 @@ CUSTOM_CVAR (Float, snd_musicvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
else
{
// Set general music volume.
GSnd->SetMusicVolume(clamp<float>(self * relative_volume, 0, 1));
if (GSnd != NULL)
{
GSnd->SetMusicVolume(clamp<float>(self * relative_volume, 0, 1));
}
// For music not implemented through the digital sound system,
// let them know about the change.
if (currSong != NULL)

View file

@ -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

View file

@ -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);
}
}
//==========================================================================
//
//==========================================================================

View file

@ -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:

View file

@ -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;

View file

@ -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;

View file

@ -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
}

View file

@ -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
{

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

@ -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();

View file

@ -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

View file

@ -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.";