diff --git a/docs/rh-log.txt b/docs/rh-log.txt index ff2e01aa4..80a37824e 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,13 @@ +January 8, 2008 +- Fixed: When starting a teamplay netgame, players who did not specify a team + were not informed about which team they ended up joining. +- Added Skulltag's DF2_SAME_SPAWN_SPOT flags. +- Fixed: DF2_YES_DEGENERATION was pretty much guaranteed to go out of sync + because it used gametic for timing. +- Added DoubleAmmoFactor as a skill property for the DF2_YES_DOUBLEAMMO flag. +- Renumbered the dmflags2 entries to match Skulltag's again. +- Added Karate Chris's infinite ammo patch. + January 7, 2008 - Added support for user-defined crosshairs in the Display Options menu. See xhairs.txt in zdoom.pk3. It's pretty simple. diff --git a/src/d_main.cpp b/src/d_main.cpp index 448a8e623..59f705406 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -387,16 +387,18 @@ CVAR (Flag, sv_nocrouch, dmflags, DF_NO_CROUCH); //========================================================================== CVAR (Int, dmflags2, 0, CVAR_SERVERINFO); -CVAR (Flag, sv_weapondrop, dmflags2, DF2_YES_WEAPONDROP); -CVAR (Flag, sv_noteamswitch, dmflags2, DF2_NO_TEAMSWITCH); -CVAR (Flag, sv_doubleammo, dmflags2, DF2_YES_DOUBLEAMMO); -CVAR (Flag, sv_keepfrags, dmflags2, DF2_YES_KEEPFRAGS); -CVAR (Flag, sv_degeneration, dmflags2, DF2_YES_DEGENERATION); -CVAR (Flag, sv_norespawn, dmflags2, DF2_NO_RESPAWN); -CVAR (Flag, sv_losefrag, dmflags2, DF2_YES_LOSEFRAG); -CVAR (Flag, sv_nobfgaim, dmflags2, DF2_NO_FREEAIMBFG); -CVAR (Flag, sv_respawnprotect, dmflags2, DF2_YES_INVUL); -CVAR (Flag, sv_barrelrespawn, dmflags2, DF2_BARRELS_RESPAWN); +CVAR (Flag, sv_weapondrop, dmflags2, DF2_YES_WEAPONDROP); +CVAR (Flag, sv_noteamswitch, dmflags2, DF2_NO_TEAM_SWITCH); +CVAR (Flag, sv_doubleammo, dmflags2, DF2_YES_DOUBLEAMMO); +CVAR (Flag, sv_degeneration, dmflags2, DF2_YES_DEGENERATION); +CVAR (Flag, sv_nobfgaim, dmflags2, DF2_NO_FREEAIMBFG); +CVAR (Flag, sv_barrelrespawn, dmflags2, DF2_BARRELS_RESPAWN); +CVAR (Flag, sv_keepfrags, dmflags2, DF2_YES_KEEPFRAGS); +CVAR (Flag, sv_norespawn, dmflags2, DF2_NO_RESPAWN); +CVAR (Flag, sv_losefrag, dmflags2, DF2_YES_LOSEFRAG); +CVAR (Flag, sv_respawnprotect, dmflags2, DF2_YES_RESPAWN_INVUL); +CVAR (Flag, sv_samespawnspot, dmflags2, DF2_SAME_SPAWN_SPOT); +CVAR (Flag, sv_infiniteinventory, dmflags2, DF2_INFINITE_INVENTORY) //========================================================================== // diff --git a/src/d_net.cpp b/src/d_net.cpp index 15c937fb6..9fbcb6155 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1346,6 +1346,7 @@ bool DoArbitrate (void *userdata) stream = &netbuffer[9]; } + D_ReadUserInfoStrings (netbuffer[1], &stream, false); if (!nodeingame[node]) { version = (netbuffer[2] << 16) | (netbuffer[3] << 8) | netbuffer[4]; @@ -1356,9 +1357,8 @@ bool DoArbitrate (void *userdata) playeringame[netbuffer[1]] = true; nodeingame[node] = true; - data->playersdetected[0] |= 1 << netbuffer[1]; - D_ReadUserInfoStrings (netbuffer[1], &stream, false); + data->playersdetected[0] |= 1 << netbuffer[1]; StartScreen->NetMessage ("Found %s (node %d, player %d)", players[netbuffer[1]].userinfo.netname, @@ -1422,7 +1422,7 @@ bool DoArbitrate (void *userdata) for (j = 0; j < doomcom.numnodes; ++j) { // Send info about player j to player i? - if (i != j && (data->playersdetected[0] & (1<playersdetected[i] & (1<playersdetected[0] & (1<playersdetected[i] & (1<team)) + if ((dmflags2 & DF2_NO_TEAM_SWITCH) && (alwaysapplydmflags || deathmatch) && TEAMINFO_IsValidTeam (info->team)) { Printf ("Team changing has been disabled!\n"); return; diff --git a/src/doomdef.h b/src/doomdef.h index 8cc9b7fa7..7f0338a3f 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -204,9 +204,9 @@ enum DF_NO_ITEMS = 1 << 1, // Do not spawn powerups (DM) DF_WEAPONS_STAY = 1 << 2, // Leave weapons around after pickup (DM) DF_FORCE_FALLINGZD = 1 << 3, // Falling too far hurts (old ZDoom style) - DF_FORCE_FALLINGHX = 1 << 4, // Falling too far hurts (Hexen style) + DF_FORCE_FALLINGHX = 2 << 3, // Falling too far hurts (Hexen style) DF_FORCE_FALLINGST = 3 << 3, // Falling too far hurts (Strife style) -// DF_INVENTORY_ITEMS = 1 << 5, // Wait for player to use powerups when picked up +// 1 << 5 -- this space left blank -- DF_SAME_LEVEL = 1 << 6, // Stay on the same map when someone exits (DM) DF_SPAWN_FARTHEST = 1 << 7, // Spawn players as far as possible from other players (DM) DF_FORCE_RESPAWN = 1 << 8, // Automatically respawn dead players after respawn_time is up (DM) @@ -237,25 +237,23 @@ enum { // DF2_YES_IMPALING = 1 << 0, // Player gets implaed on MF2_IMPALE items DF2_YES_WEAPONDROP = 1 << 1, // Drop current weapon upon death -//#define DF2_NO_RUNES 4 // Don't spawn runes -//#define DF2_YES_IRETURN 8 // Instantly return skull when player carrying it dies -//#define DF2_YES_RETURN 16 // Return dropped skulls after 30 seconds -//#define DF2_YES_TEAMCOLORS 32 // Don't use player's base color in teamgames - DF2_NO_TEAMSWITCH = 1 << 6, // Player is not allowed to switch teams -//#define DF2_FORCE_RANDOM 128 // Player put on random team -//#define DF2_YES_RUNEDROP 256 // Drop current rune upon death -//#define DF2_YES_200MAX 512 // Don't all max. health/armor items to bring -// // health or armor over 200% - DF2_YES_DOUBLEAMMO = 1 << 10, // Doubles ammo like skill 1 and 5 do - DF2_YES_KEEPFRAGS = 1 << 11, // Don't clear frags after each level - DF2_NO_RESPAWN = 1 << 12, // Player cannot respawn - DF2_YES_DEGENERATION = 1 << 13, // Quake-style degeneration - DF2_YES_LOSEFRAG = 1 << 14, // Lose a frag when killed. More incentive to try to +// DF2_NO_RUNES = 1 << 2, // Don't spawn runes +// DF2_INSTANT_RETURN = 1 << 3, // Instantly return flags and skulls when player carrying it dies (ST/CTF) + DF2_NO_TEAM_SWITCH = 1 << 4, // Do not allow players to switch teams in teamgames +// DF2_NO_TEAM_SELECT = 1 << 5, // Player is automatically placed on a team. + DF2_YES_DOUBLEAMMO = 1 << 6, // Double amount of ammo that items give you like skill 1 and 5 do + DF2_YES_DEGENERATION = 1 << 7, // Player slowly loses health when over 100% (Quake-style) + DF2_NO_FREEAIMBFG = 1 << 8, // Disallow BFG freeaiming. Prevents cheap BFG frags by aiming at floor or ceiling + DF2_BARRELS_RESPAWN = 1 << 9, // Barrels respawn (duh) + DF2_YES_RESPAWN_INVUL = 1 << 10, // Player is temporarily invulnerable when respawned +// DF2_COOP_SHOTGUNSTART = 1 << 11, // All playres start with a shotgun when they respawn + DF2_SAME_SPAWN_SPOT = 1 << 12, // Players respawn in the same place they died (co-op) + + DF2_YES_KEEPFRAGS = 1 << 13, // Don't clear frags after each level + DF2_NO_RESPAWN = 1 << 14, // Player cannot respawn + DF2_YES_LOSEFRAG = 1 << 15, // Lose a frag when killed. More incentive to try to // // not get yerself killed - DF2_NO_FREEAIMBFG = 1 << 15, // Don't allow BFG to be aimed at the ground - // or ceiling. Prevents cheap BFG frags - DF2_BARRELS_RESPAWN = 1 << 16, // Barrels respawn (duh) - DF2_YES_INVUL = 1 << 17, // Player is temporarily invulnerable when respawned + DF2_INFINITE_INVENTORY = 1 << 16, // Infinite inventory. }; // [RH] Compatibility flags. diff --git a/src/g_game.cpp b/src/g_game.cpp index a92d006d7..0b71b7cbf 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1221,7 +1221,7 @@ void G_PlayerReborn (int player) p->isbot = false; // [BC] Handle temporary invulnerability when respawned - if ((dmflags2 & DF2_YES_INVUL) && (deathmatch || alwaysapplydmflags)) + if ((dmflags2 & DF2_YES_RESPAWN_INVUL) && (deathmatch || alwaysapplydmflags)) { APowerup *invul = static_cast(actor->GiveInventoryType (RUNTIME_CLASS(APowerInvulnerable))); invul->EffectTics = 2*TICRATE; diff --git a/src/g_level.cpp b/src/g_level.cpp index e30590d43..551df734a 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -3097,6 +3097,7 @@ static void ParseSkill () FSkillInfo skill; skill.AmmoFactor = FRACUNIT; + skill.DoubleAmmoFactor = 2*FRACUNIT; skill.DamageFactor = FRACUNIT; skill.FastMonsters = false; skill.DisableCheats = false; @@ -3121,6 +3122,11 @@ static void ParseSkill () SC_MustGetFloat (); skill.AmmoFactor = FLOAT2FIXED(sc_Float); } + else if (SC_Compare ("doubleammofactor")) + { + SC_MustGetFloat (); + skill.DoubleAmmoFactor = FLOAT2FIXED(sc_Float); + } else if (SC_Compare ("damagefactor")) { SC_MustGetFloat (); @@ -3227,6 +3233,10 @@ int G_SkillProperty(ESkillProperty prop) switch(prop) { case SKILLP_AmmoFactor: + if (dmflags2 & DF2_YES_DOUBLEAMMO) + { + return AllSkills[gameskill].DoubleAmmoFactor; + } return AllSkills[gameskill].AmmoFactor; case SKILLP_DamageFactor: @@ -3275,6 +3285,7 @@ FSkillInfo &FSkillInfo::operator=(const FSkillInfo &other) { Name = other.Name; AmmoFactor = other.AmmoFactor; + DoubleAmmoFactor = other.DoubleAmmoFactor; DamageFactor = other.DamageFactor; FastMonsters = other.FastMonsters; DisableCheats = other.DisableCheats; diff --git a/src/g_level.h b/src/g_level.h index c055591ae..6ed768383 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -390,7 +390,7 @@ typedef TMap SkillMenuNames; struct FSkillInfo { FName Name; - fixed_t AmmoFactor; + fixed_t AmmoFactor, DoubleAmmoFactor; fixed_t DamageFactor; bool FastMonsters; bool DisableCheats; diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 2e5f990f8..df25ea244 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -76,16 +76,12 @@ bool AAmmo::HandlePickup (AInventory *item) { int receiving = item->Amount; - if (!(item->ItemFlags&IF_IGNORESKILL)) - { - // extra ammo in baby mode and nightmare mode + if (!(item->ItemFlags & IF_IGNORESKILL)) + { // extra ammo in baby mode and nightmare mode receiving = FixedMul(receiving, G_SkillProperty(SKILLP_AmmoFactor)); } int oldamount = Amount; - if (dmflags2 & DF2_YES_DOUBLEAMMO) - receiving *= 2; - Amount += receiving; if (Amount > MaxAmount) { diff --git a/src/m_options.cpp b/src/m_options.cpp index 71f069ced..066c05bdd 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -1006,6 +1006,7 @@ static menuitem_t DMFlagsItems[] = { { bitflag, "Drop weapon", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_WEAPONDROP} }, { bitflag, "Double ammo", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_DOUBLEAMMO} }, { bitflag, "Infinite ammo", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_INFINITE_AMMO} }, + { bitflag, "Infinite inventory", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_INFINITE_INVENTORY} }, { bitflag, "No monsters", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_NO_MONSTERS} }, { bitflag, "Monsters respawn", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_MONSTERS_RESPAWN} }, { bitflag, "No respawn", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_NO_RESPAWN} }, @@ -1029,10 +1030,11 @@ static menuitem_t DMFlagsItems[] = { { bitflag, "Force respawn", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_FORCE_RESPAWN} }, { bitflag, "Allow exit", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_EXIT} }, { bitflag, "Barrels respawn", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_BARRELS_RESPAWN} }, - { bitflag, "Respawn protection", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_INVUL} }, + { bitflag, "Respawn protection", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_RESPAWN_INVUL} }, { bitflag, "Lose frag if fragged", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_LOSEFRAG} }, { bitflag, "Keep frags gained", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_KEEPFRAGS} }, - { bitflag, "No team changing", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_NO_TEAMSWITCH} }, + { bitflag, "No team switching", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_NO_TEAM_SWITCH} }, + { redtext, " ", {NULL}, {0}, {0}, {0}, {NULL} }, { whitetext,"Cooperative Settings", {NULL}, {0}, {0}, {0}, {NULL} }, { bitflag, "Spawn multi. weapons", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_COOP_WEAPON_SPAWN} }, @@ -1043,6 +1045,7 @@ static menuitem_t DMFlagsItems[] = { { bitflag, "Keep powerups", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_COOP_LOSE_POWERUPS} }, { bitflag, "Keep ammo", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_COOP_LOSE_AMMO} }, { bitflag, "Lose half ammo", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_COOP_HALVE_AMMO} }, + { bitflag, "Spawn where died", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_SAME_SPAWN_SPOT} }, }; static menu_t DMFlagsMenu = diff --git a/src/m_random.h b/src/m_random.h index ff0078e61..4c58e6d91 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -73,6 +73,11 @@ public: return operator()(); } + DWORD GetSeed() + { + return Seed; + } + static void StaticClearRandom (); static DWORD StaticSumSeeds (); static void StaticReadRNGState (PNGHandle *png); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 43bd8f980..8bf8b4ae0 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -744,6 +744,10 @@ bool AActor::UseInventory (AInventory *item) { return false; } + + if (dmflags2 & DF2_INFINITE_INVENTORY) + return true; + if (--item->Amount <= 0 && !(item->ItemFlags & IF_KEEPDEPLETED)) { item->Destroy (); @@ -3433,6 +3437,8 @@ void P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer) player_t *p; APlayerPawn *mobj, *oldactor; BYTE state; + fixed_t spawn_x, spawn_y; + angle_t spawn_angle; // [RH] Things 4001-? are also multiplayer starts. Just like 1-4. // To make things simpler, figure out which player is being @@ -3484,8 +3490,25 @@ void P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer) p->cls = PlayerClasses[p->CurrentPlayerClass].Type; } + if (( dmflags2 & DF2_SAME_SPAWN_SPOT ) && + ( p->playerstate == PST_REBORN ) && + ( deathmatch == false ) && + ( gameaction != ga_worlddone ) && + ( p->mo != NULL )) + { + spawn_x = p->mo->x; + spawn_y = p->mo->y; + spawn_angle = p->mo->angle; + } + else + { + spawn_x = mthing->x << FRACBITS; + spawn_y = mthing->y << FRACBITS; + spawn_angle = ANG45 * (mthing->angle/45); + } + mobj = static_cast - (Spawn (p->cls, mthing->x << FRACBITS, mthing->y << FRACBITS, ONFLOORZ, NO_REPLACE)); + (Spawn (p->cls, spawn_x, spawn_y, ONFLOORZ, NO_REPLACE)); mobj->FriendPlayer = playernum + 1; // [RH] players are their own friends oldactor = p->mo; @@ -3513,7 +3536,7 @@ void P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer) // [RH] set color translations for player sprites mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum); - mobj->angle = ANG45 * (mthing->angle/45); + mobj->angle = spawn_angle; mobj->pitch = mobj->roll = 0; mobj->health = p->health; diff --git a/src/p_user.cpp b/src/p_user.cpp index f527441b1..c4d089048 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2199,7 +2199,7 @@ void P_PlayerThink (player_t *player) // Apply degeneration. if (dmflags2 & DF2_YES_DEGENERATION) { - if ((gametic % TICRATE) == 0 && player->health > deh.MaxHealth) + if ((level.time % TICRATE) == 0 && player->health > deh.MaxHealth) { if (player->health - 5 < deh.MaxHealth) player->health = deh.MaxHealth; diff --git a/wadsrc/mapinfo/heretic.txt b/wadsrc/mapinfo/heretic.txt index bd9b14e6a..cf1ce4597 100644 --- a/wadsrc/mapinfo/heretic.txt +++ b/wadsrc/mapinfo/heretic.txt @@ -2,25 +2,30 @@ skill baby AmmoFactor 1.5 + DoubleAmmoFactor 1.5 DamageFactor 0.5 EasyBossBrain SpawnFilter "Easy" Name "MNU_WETNURSE" skill easy + DoubleAmmoFactor 1.5 SpawnFilter "Easy" Name "MNU_YELLOWBELLIES" skill normal + DoubleAmmoFactor 1.5 SpawnFilter "Normal" Name "MNU_BRINGEST" skill hard + DoubleAmmoFactor 1.5 SpawnFilter "Hard" Name "MNU_SMITE" skill nightmare AmmoFactor 1.5 + DoubleAmmoFactor 1.5 FastMonsters DisableCheats SpawnFilter "Hard" diff --git a/wadsrc/mapinfo/hexen.txt b/wadsrc/mapinfo/hexen.txt index 563444d9c..9a6e1f417 100644 --- a/wadsrc/mapinfo/hexen.txt +++ b/wadsrc/mapinfo/hexen.txt @@ -3,6 +3,7 @@ skill baby AmmoFactor 1.5 + DoubleAmmoFactor 1.5 DamageFactor 0.5 EasyBossBrain SpawnFilter "Easy" @@ -13,6 +14,7 @@ skill baby skill easy + DoubleAmmoFactor 1.5 SpawnFilter "Easy" Name "MNU_YELLOWBELLIES" PlayerClassName "fighter" "MNU_KNIGHT" @@ -20,6 +22,7 @@ skill easy PlayerClassName "mage" "MNU_ENCHANTER" skill normal + DoubleAmmoFactor 1.5 SpawnFilter "Normal" Name "MNU_BRINGEST" PlayerClassName "fighter" "MNU_WARRIOR" @@ -27,6 +30,7 @@ skill normal PlayerClassName "mage" "MNU_SORCERER" skill hard + DoubleAmmoFactor 1.5 SpawnFilter "Hard" Name "MNU_SMITE" PlayerClassName "fighter" "MNU_BERSERKER" @@ -35,6 +39,7 @@ skill hard skill nightmare AmmoFactor 1.5 + DoubleAmmoFactor 1.5 FastMonsters DisableCheats SpawnFilter "Hard"