diff --git a/docs/rh-log.txt b/docs/rh-log.txt index d92290e278..74d6023c97 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,9 @@ January 26, 2008 (Changes by Graf Zahl) +- Added Karate Chris's patch for teamplay MAPINFO option. +- Added Karate Chris's patch for custom damage color per player class. +- Added Karate Chris's patch for respawnlimit skill property. +- Added Karate Chris's patch for Strife quit messages. +- Fixed: P_RailAttack ignored the puff's damage type. - Fixed: ACS used incompatible values for APROP_RenderStyle. It needs to use the exact same values as previous ZDoom versions - Added a DECORATE 'stencilcolor' property so that the stencil render style diff --git a/src/actor.h b/src/actor.h index 8054c12e4c..99a642a6d2 100644 --- a/src/actor.h +++ b/src/actor.h @@ -657,6 +657,7 @@ public: } LastLook; WORD SpawnPoint[3]; // For nightmare respawn WORD SpawnAngle; + int skillrespawncount; AActor *tracer; // Thing being chased/attacked for tracers AActor *master; // Thing which spawned this one (prevents mutual attacks) fixed_t floorclip; // value to use for floor clipping diff --git a/src/d_player.h b/src/d_player.h index 951f508643..72be0e890b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -118,6 +118,12 @@ public: FNameNoInit MorphWeapon; fixed_t AttackZOffset; // attack height, relative to player center + // [CW] Fades for when you are being damaged. + bool HasDamageFade; + float RedDamageFade; + float GreenDamageFade; + float BlueDamageFade; + bool UpdateWaterLevel (fixed_t oldz, bool splash); bool ResetAirSupply (); diff --git a/src/g_level.cpp b/src/g_level.cpp index 4c40c400e2..6fdd5d1008 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -305,6 +305,8 @@ static const char *MapInfoMapLevel[] = "fogdensity", "outsidefogdensity", "skyfog", + "teamplayon", + "teamplayoff", NULL }; @@ -450,6 +452,8 @@ MapHandlers[] = { MITYPE_INT, lioffset(fogdensity), 0 }, { MITYPE_INT, lioffset(outsidefogdensity), 0 }, { MITYPE_INT, lioffset(skyfog), 0 }, + { MITYPE_SCFLAGS, LEVEL_FORCETEAMPLAYON, ~LEVEL_FORCETEAMPLAYOFF }, + { MITYPE_SCFLAGS, LEVEL_FORCETEAMPLAYOFF, ~LEVEL_FORCETEAMPLAYON }, }; static const char *MapInfoClusterLevel[] = @@ -1978,6 +1982,14 @@ void G_DoLoadLevel (int position, bool autosave) G_InitLevelLocals (); StatusBar->DetachAllMessages (); + // Force 'teamplay' to 'true' if need be. + if (level.flags & LEVEL_FORCETEAMPLAYON) + teamplay = true; + + // Force 'teamplay' to 'false' if need be. + if (level.flags & LEVEL_FORCETEAMPLAYOFF) + teamplay = false; + Printf ( "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36" "\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n" @@ -3136,6 +3148,7 @@ static void ParseSkill (FScanner &sc) skill.EasyBossBrain = false; skill.AutoUseHealth = false; skill.RespawnCounter = 0; + skill.RespawnLimit = 0; skill.Aggressiveness = FRACUNIT; skill.SpawnFilter = 0; skill.ACSReturn = AllSkills.Size(); @@ -3185,6 +3198,11 @@ static void ParseSkill (FScanner &sc) sc.MustGetFloat (); skill.RespawnCounter = int(sc.Float*TICRATE); } + else if (sc.Compare("respawnlimit")) + { + sc.MustGetNumber (); + skill.RespawnLimit = sc.Number; + } else if (sc.Compare("Aggressiveness")) { sc.MustGetFloat (); @@ -3282,6 +3300,9 @@ int G_SkillProperty(ESkillProperty prop) return TICRATE * (gameinfo.gametype != GAME_Strife ? 12 : 16); return AllSkills[gameskill].RespawnCounter; + case SKILLP_RespawnLimit: + return AllSkills[gameskill].RespawnLimit; + case SKILLP_Aggressiveness: return AllSkills[gameskill].Aggressiveness; @@ -3324,6 +3345,7 @@ FSkillInfo &FSkillInfo::operator=(const FSkillInfo &other) AutoUseHealth = other.AutoUseHealth; EasyBossBrain = other.EasyBossBrain; RespawnCounter= other.RespawnCounter; + RespawnLimit= other.RespawnLimit; Aggressiveness= other.Aggressiveness; SpawnFilter = other.SpawnFilter; ACSReturn = other.ACSReturn; diff --git a/src/g_level.h b/src/g_level.h index 6ed7683834..9e401bcb2d 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -115,6 +115,9 @@ #define LEVEL_ALLOWRESPAWN UCONST64(0x4000000000000) +#define LEVEL_FORCETEAMPLAYON UCONST64(0x8000000000000) +#define LEVEL_FORCETEAMPLAYOFF UCONST64(0x10000000000000) + struct acsdefered_s; struct FSpecialAction @@ -376,6 +379,7 @@ enum ESkillProperty SKILLP_DamageFactor, SKILLP_FastMonsters, SKILLP_Respawn, + SKILLP_RespawnLimit, SKILLP_Aggressiveness, SKILLP_DisableCheats, SKILLP_AutoUseHealth, @@ -397,6 +401,7 @@ struct FSkillInfo bool AutoUseHealth; bool EasyBossBrain; int RespawnCounter; + int RespawnLimit; fixed_t Aggressiveness; int SpawnFilter; int ACSReturn; diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 826be70eb0..52d5299fca 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -1437,7 +1437,18 @@ void FBaseStatusBar::BlendView (float blend[4]) if (cnt > 228) cnt = 228; - AddBlend (1.f, 0.f, 0.f, cnt / 255.f, blend); + APlayerPawn *mo = players[consoleplayer].mo; + + // [CW] If no damage fade is specified, assume defaults. + if (!mo->HasDamageFade) + { + mo->HasDamageFade = true; + mo->RedDamageFade = 255; + mo->GreenDamageFade = 0; + mo->BlueDamageFade = 0; + } + + AddBlend (mo->RedDamageFade / 255, mo->GreenDamageFade / 255, mo->BlueDamageFade / 255, cnt / 255.f, blend); } // Unlike Doom, I did not have any utility source to look at to find the diff --git a/src/gstrings.h b/src/gstrings.h index 99366bcf32..4267adc177 100644 --- a/src/gstrings.h +++ b/src/gstrings.h @@ -42,8 +42,9 @@ extern FStringTable GStrings; -// QuitDOOM messages -#define NUM_QUITMESSAGES 15 +// QuitGame messages +#define NUM_QUITDOOMMESSAGES 15 +#define NUM_QUITSTRIFEMESSAGES 8 extern const char *endmsg[]; diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 3b58cdb9dd..756d3f78ff 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -126,7 +126,7 @@ static void M_Options (int choice); static void M_EndGame (int choice); static void M_ReadThis (int choice); static void M_ReadThisMore (int choice); -static void M_QuitDOOM (int choice); +static void M_QuitGame (int choice); static void M_GameFiles (int choice); static void M_ClearSaveStuff (); @@ -275,7 +275,7 @@ static oldmenuitem_t MainMenu[]= {1,0,'s',"M_SAVEG",M_SaveGame, CR_UNTRANSLATED}, {1,0,'o',"M_OPTION",M_Options, CR_UNTRANSLATED}, // [RH] Moved {1,0,'r',"M_RDTHIS",M_ReadThis, CR_UNTRANSLATED}, // Another hickup with Special edition. - {1,0,'q',"M_QUITG",M_QuitDOOM, CR_UNTRANSLATED} + {1,0,'q',"M_QUITG",M_QuitGame, CR_UNTRANSLATED} }; static oldmenu_t MainDef = @@ -296,7 +296,7 @@ static oldmenuitem_t HereticMainMenu[] = {1,1,'o',"MNU_OPTIONS",M_Options, CR_UNTRANSLATED}, {1,1,'f',"MNU_GAMEFILES",M_GameFiles, CR_UNTRANSLATED}, {1,1,'i',"MNU_INFO",M_ReadThis, CR_UNTRANSLATED}, - {1,1,'q',"MNU_QUITGAME",M_QuitDOOM, CR_UNTRANSLATED} + {1,1,'q',"MNU_QUITGAME",M_QuitGame, CR_UNTRANSLATED} }; static oldmenu_t HereticMainDef = @@ -625,7 +625,7 @@ CCMD (menu_quit) { // F10 //M_StartControlPanel (true); S_Sound (CHAN_VOICE, "menu/activate", 1, ATTN_NONE); - M_QuitDOOM(0); + M_QuitGame(0); } CCMD (menu_game) @@ -1942,7 +1942,7 @@ void M_FinishReadThis (int choice) } // -// M_QuitDOOM +// M_QuitGame // void M_QuitResponse(int ch) @@ -1960,16 +1960,16 @@ void M_QuitResponse(int ch) ST_Endoom(); } -void M_QuitDOOM (int choice) +void M_QuitGame (int choice) { // We pick index 0 which is language sensitive, // or one at random, between 1 and maximum number. - if (gameinfo.gametype == GAME_Doom) + if (gameinfo.gametype & (GAME_Doom|GAME_Strife)) { - int quitmsg = gametic % NUM_QUITMESSAGES; + int quitmsg = gametic % (gameinfo.gametype == GAME_Doom ? NUM_QUITDOOMMESSAGES : NUM_QUITSTRIFEMESSAGES); if (quitmsg != 0) { - EndString.Format("QUITMSG%d", quitmsg); + EndString.Format("QUITMSG%d", quitmsg + (gameinfo.gametype == GAME_Doom ? 0 : NUM_QUITDOOMMESSAGES)); EndString.Format("%s\n\n%s", GStrings(EndString), GStrings("DOSY")); } else diff --git a/src/p_map.cpp b/src/p_map.cpp index 0b921923aa..767b22e013 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3202,6 +3202,9 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color // Now hurt anything the trace hit unsigned int i; + const PClass *puffclass = PClass::FindClass(puff); + AActor *puffDefaults = puffclass == NULL? NULL : GetDefaultByType (puffclass); + FName damagetype = puffDefaults != NULL && puffDefaults->DamageType == NAME_None? FName(NAME_Railgun) : puffDefaults->DamageType; for (i = 0; i < RailHits.Size (); i++) { @@ -3214,14 +3217,13 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color if ((RailHits[i].HitActor->flags & MF_NOBLOOD) || (RailHits[i].HitActor->flags2 & (MF2_DORMANT|MF2_INVULNERABLE))) { - const PClass *puffclass = PClass::FindClass(puff); if (puffclass != NULL) P_SpawnPuff (puffclass, x, y, z, source->angle - ANG180, 1, true); } else { P_SpawnBlood (x, y, z, source->angle - ANG180, damage, RailHits[i].HitActor); } - P_DamageMobj (RailHits[i].HitActor, source, source, damage, NAME_Railgun); + P_DamageMobj (RailHits[i].HitActor, source, source, damage, damagetype); P_TraceBleed (damage, x, y, z, RailHits[i].HitActor, angle, pitch); } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 197b3566f9..4cd94cb77a 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -281,6 +281,7 @@ void AActor::Serialize (FArchive &arc) << player << SpawnPoint[0] << SpawnPoint[1] << SpawnPoint[2] << SpawnAngle + << skillrespawncount << tracer << floorclip << tid @@ -2182,6 +2183,8 @@ void P_NightmareRespawn (AActor *mobj) AActor *mo; AActor *info = mobj->GetDefault(); + mobj->skillrespawncount++; + // spawn the new monster (assume the spawn will be good) if (info->flags & MF_SPAWNCEILING) z = ONCEILINGZ; @@ -2226,6 +2229,8 @@ void P_NightmareRespawn (AActor *mobj) mo->CopyFriendliness (mobj, false); mo->Translation = mobj->Translation; + mo->skillrespawncount = mobj->skillrespawncount; + // spawn a teleport fog at old spot because of removal of the body? mo = Spawn ("TeleportFog", mobj->x, mobj->y, mobj->z, ALLOW_REPLACE); if (mo != NULL) @@ -2970,6 +2975,9 @@ void AActor::Tick () if (pr_nightmarerespawn() > 4) return; + if (G_SkillProperty (SKILLP_RespawnLimit) && (this)->skillrespawncount >= G_SkillProperty (SKILLP_RespawnLimit)) + return; + P_NightmareRespawn (this); } } diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index a654594708..ed8c886b38 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -2304,6 +2304,34 @@ static void PlayerCrouchSprite (FScanner &sc, APlayerPawn *defaults, Baggage &ba defaults->crouchsprite = GetSpriteIndex (sc.String); } +//========================================================================== +// +//========================================================================== +static void PlayerDmgScreenColor (FScanner &sc, APlayerPawn *defaults, Baggage &bag) +{ + defaults->HasDamageFade = true; + + if (sc.CheckNumber ()) + { + sc.MustGetNumber (); + defaults->RedDamageFade = clamp (sc.Number, 0, 255); + sc.CheckString (","); + sc.MustGetNumber (); + defaults->GreenDamageFade = clamp (sc.Number, 0, 255); + sc.CheckString (","); + sc.MustGetNumber (); + defaults->BlueDamageFade = clamp (sc.Number, 0, 255); + } + else + { + sc.MustGetString (); + int c = V_GetColor (NULL, sc.String); + defaults->RedDamageFade = RPART (c); + defaults->GreenDamageFade = GPART (c); + defaults->BlueDamageFade = BPART (c); + } +} + //========================================================================== // // [GRB] Store start items in drop item list @@ -2495,6 +2523,7 @@ static const ActorProps props[] = { "player.attackzoffset", (apf)PlayerAttackZOffset, RUNTIME_CLASS(APlayerPawn) }, { "player.colorrange", (apf)PlayerColorRange, RUNTIME_CLASS(APlayerPawn) }, { "player.crouchsprite", (apf)PlayerCrouchSprite, RUNTIME_CLASS(APlayerPawn) }, + { "player.damagescreencolor", (apf)PlayerDmgScreenColor, RUNTIME_CLASS(APlayerPawn) }, { "player.displayname", (apf)PlayerDisplayName, RUNTIME_CLASS(APlayerPawn) }, { "player.forwardmove", (apf)PlayerForwardMove, RUNTIME_CLASS(APlayerPawn) }, { "player.healradiustype", (apf)PlayerHealRadius, RUNTIME_CLASS(APlayerPawn) }, diff --git a/src/version.h b/src/version.h index 726fcf7c6b..53778d4125 100644 --- a/src/version.h +++ b/src/version.h @@ -75,7 +75,7 @@ // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 667 +#define MINSAVEVER 714 #if SVN_REVISION_NUMBER == 0 // This can happen if svnrevision is not updated properly (e.g. compiling while offline) diff --git a/wadsrc/languages/english-us.txt b/wadsrc/languages/english-us.txt index 45006ca2a3..e839e278af 100644 --- a/wadsrc/languages/english-us.txt +++ b/wadsrc/languages/english-us.txt @@ -9,7 +9,7 @@ PRESSYN = "press y or n."; QUITMSG = "are you sure you want to\nquit this great game?"; -// QuitDoom1 messages +// Quit Doom 1 messages QUITMSG1 = "please don't leave, there's more\ndemons to toast!"; QUITMSG2 = "let's beat it -- this is turning\ninto a bloodbath!"; QUITMSG3 = "i wouldn't leave if i were you.\ndos is much worse."; @@ -18,7 +18,7 @@ QUITMSG5 = "don't leave yet -- there's a\ndemon around that corner!"; QUITMSG6 = "ya know, next time you come in here\ni'm gonna toast ya."; QUITMSG7 = "go ahead and leave. see if i care."; -// QuitDOOM II messages +// Quit Doom II messages QUITMSG8 = "you want to quit?\nthen, thou hast lost an eighth!"; QUITMSG9 = "don't go now, there's a \ndimensional shambler waiting\nat the dos prompt!"; QUITMSG10 = "get outta here and go back\nto your boring programs."; @@ -27,6 +27,16 @@ QUITMSG12 = "look, bud. you leave now\nand you forfeit your body count!"; QUITMSG13 = "just leave. when you come\nback, i'll be waiting with a bat."; QUITMSG14 = "you're lucky i don't smack\nyou for thinking about leaving."; +// Quit Strife messages +QUITMSG15 = "where are you going?! what about the rebellion?"; +QUITMSG16 = "carnage interrupted... what a tease!"; +QUITMSG17 = "but you're the hope -- my only chance!!"; +QUITMSG18 = "nobody walks out on blackbird."; +QUITMSG19 = "i thought you were different..."; +QUITMSG20 = "fine! just kill and run!"; +QUITMSG21 = "you can quit...but you can't hide..."; +QUITMSG22 = "whaaa, what's the matter? mommy says dinnertime?"; + LOADNET = "you can't do load while in a net game!\n\npress a key."; QLOADNET = "you can't quickload during a netgame!\n\npress a key."; QSAVESPOT = "you haven't picked a quicksave slot yet!\n\npress a key.";