From e748c49dd0c672829d23ab31358e6671ebf5b215 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 17:29:42 -0500 Subject: [PATCH 1/9] - Fixed: m_specialpaths.cpp did not compile under Linux. --- src/m_specialpaths.cpp | 31 +++++++++++++++++++------------ src/version.h | 6 ++---- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/m_specialpaths.cpp b/src/m_specialpaths.cpp index 1f17f90c2..b4fcba3c3 100644 --- a/src/m_specialpaths.cpp +++ b/src/m_specialpaths.cpp @@ -12,9 +12,16 @@ #include "cmdlib.h" #include "m_misc.h" -#if defined(_WIN32) +#if !defined(__APPLE__) && !defined(_WIN32) +#include +#include +#include "i_system.h" +#endif #include "version.h" // for GAMENAME + +#if defined(_WIN32) + typedef HRESULT (WINAPI *GKFP)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *); //=========================================================================== @@ -195,7 +202,7 @@ FString M_GetConfigPath(bool for_reading) // Construct a user-specific config name if (UseKnownFolders() && GetKnownFolder(CSIDL_APPDATA, FOLDERID_RoamingAppData, true, path)) { - path << '/' << GAME_DIR; + path += "/" GAME_DIR; CreatePath(path); path += "/zdoom.ini"; } @@ -534,7 +541,7 @@ FString M_GetCachePath(bool create) FString path = NicePath("~/.config/zdoom/cache"); if (create) { - CreatePath(create); + CreatePath(path); } return path; } @@ -564,16 +571,16 @@ FString M_GetCajunPath(const char *botfilename) { FString path; - // Check first in ~/.config/zdoom./botfilename. - path = GetUserFile(BOTFILENAME); - if (!FileExists(tmp)) + // Check first in ~/.config/zdoom/botfilename. + path = GetUserFile(botfilename); + if (!FileExists(path)) { - // Then check in SHARE_DIR/botfilename. (Some allowance for Macs - // should probably be made here.) - path = SHARE_DIR BOTFILENAME; + // Then check in SHARE_DIR/botfilename. + path = SHARE_DIR; + path << botfilename; if (!FileExists(path)) { - path =""; + path = ""; } } return path; @@ -604,7 +611,7 @@ FString M_GetConfigPath(bool for_reading) FString M_GetScreenshotsPath() { - return "~/" GAME_DIR "/screenshots/"; + return NicePath("~/" GAME_DIR "/screenshots/"); } //=========================================================================== @@ -617,7 +624,7 @@ FString M_GetScreenshotsPath() FString M_GetSavegamesPath() { - return = "~/" GAME_DIR; + return NicePath("~/" GAME_DIR); } #endif diff --git a/src/version.h b/src/version.h index b0717fbf8..66e2f8938 100644 --- a/src/version.h +++ b/src/version.h @@ -91,12 +91,10 @@ const char *GetVersionString(); #define FORUM_URL "http://forum.zdoom.org" #define BUGS_FORUM_URL "http://forum.zdoom.org/index.php?c=3" -#ifdef __unix__ -#define GAME_DIR ".config/zdoom" -#elif defined(__APPLE__) +#if defined(__APPLE__) || defined(_WIN32) #define GAME_DIR GAMENAME #else -#define GAME_DIR "zdoom" +#define GAME_DIR ".config/zdoom" #endif From 285be8db926d3fc7ebc7af992f00171d3dbd7336 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 20:45:39 -0500 Subject: [PATCH 2/9] Fixed: wi_noautostartmap was not sync safe - Make wi_noautostartmap a userinfo cvar. This allows it to be communicated across the network and saved in demos. If any player has it set, then the intermission screen will not automatically advance to the next level. --- src/d_player.h | 4 ++++ src/namedef.h | 1 + src/wi_stuff.cpp | 25 +++++++++++++++++++++---- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 75ed533d9..69487070e 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -325,6 +325,10 @@ struct userinfo_t : TMap { return *static_cast(*CheckKey(NAME_Gender)); } + bool GetNoAutostartMap() const + { + return *static_cast(*CheckKey(NAME_Wi_NoAutostartMap)); + } void Reset(); int TeamChanged(int team); diff --git a/src/namedef.h b/src/namedef.h index f7607400e..644d0deb4 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -568,3 +568,4 @@ xx(NeverSwitchOnPickup) xx(MoveBob) xx(StillBob) xx(PlayerClass) +xx(Wi_NoAutostartMap) \ No newline at end of file diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 6ae9148af..7aef939b1 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -62,7 +62,7 @@ typedef enum CVAR (Bool, wi_percents, true, CVAR_ARCHIVE) CVAR (Bool, wi_showtotaltime, true, CVAR_ARCHIVE) -CVAR (Bool, wi_noautostartmap, false, CVAR_ARCHIVE) +CVAR (Bool, wi_noautostartmap, false, CVAR_USERINFO|CVAR_ARCHIVE) void WI_loadData (); @@ -1098,11 +1098,28 @@ void WI_updateNoState () { WI_updateAnimatedBack(); + if (acceleratestage) + { + cnt = 0; + } + else + { + bool noauto = noautostartmap; - if (!wi_noautostartmap && !noautostartmap) cnt--; - if (acceleratestage) cnt=0; + for (int i = 0; !noauto && i < MAXPLAYERS; ++i) + { + if (playeringame[i]) + { + noauto |= players[i].userinfo.GetNoAutostartMap(); + } + } + if (!noauto) + { + cnt--; + } + } - if (cnt==0) + if (cnt == 0) { WI_End(); G_WorldDone(); From 0cf68af7d26978b3c3623855ece6633d0ce56946 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:14:44 -0500 Subject: [PATCH 3/9] Overload operator = for player_t - This fixes crashes when quitting multiplayer games because the default byte-for-byte copy caused PredictionPlayerBackup and the console player to point to the exact same userinfo data and to both try and free it when they are deleted. --- src/d_netinfo.cpp | 1 + src/d_player.h | 1 + src/p_user.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 6832a047e..12fb187ae 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -1058,4 +1058,5 @@ userinfo_t::~userinfo_t() { delete pair->Value; } + this->Clear(); } diff --git a/src/d_player.h b/src/d_player.h index 69487070e..f6f7674d7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -352,6 +352,7 @@ class player_t { public: player_t(); + player_t &operator= (const player_t &p); void Serialize (FArchive &arc); size_t FixPointers (const DObject *obj, DObject *replacement); diff --git a/src/p_user.cpp b/src/p_user.cpp index e2c8b80c9..901f6cfaa 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -314,6 +314,115 @@ player_t::player_t() memset (&skill, 0, sizeof(skill)); } +player_t &player_t::operator=(const player_t &p) +{ + mo = p.mo; + playerstate = p.playerstate; + cmd = p.cmd; + original_cmd = p.original_cmd; + original_oldbuttons = p.original_oldbuttons; + // Intentionally not copying userinfo! + cls = p.cls; + DesiredFOV = p.DesiredFOV; + FOV = p.FOV; + viewz = p.viewz; + viewheight = p.viewheight; + deltaviewheight = p.deltaviewheight; + bob = p.bob; + velx = p.velx; + vely = p.vely; + centering = p.centering; + turnticks = p.turnticks; + attackdown = p.attackdown; + usedown = p.usedown; + oldbuttons = p.oldbuttons; + health = p.health; + inventorytics = p.inventorytics; + CurrentPlayerClass = p.CurrentPlayerClass; + backpack = p.backpack; + memcpy(frags, &p.frags, sizeof(frags)); + fragcount = p.fragcount; + lastkilltime = p.lastkilltime; + multicount = p.multicount; + spreecount = p.spreecount; + WeaponState = p.WeaponState; + ReadyWeapon = p.ReadyWeapon; + PendingWeapon = p.PendingWeapon; + cheats = p.cheats; + timefreezer = p.timefreezer; + refire = p.refire; + inconsistant = p.inconsistant; + waiting = p.waiting; + killcount = p.killcount; + itemcount = p.itemcount; + secretcount = p.secretcount; + damagecount = p.damagecount; + bonuscount = p.bonuscount; + hazardcount = p.hazardcount; + poisoncount = p.poisoncount; + poisontype = p.poisontype; + poisonpaintype = p.poisonpaintype; + poisoner = p.poisoner; + attacker = p.attacker; + extralight = p.extralight; + fixedcolormap = p.fixedcolormap; + fixedlightlevel = p.fixedlightlevel; + memcpy(psprites, &p.psprites, sizeof(psprites)); + morphTics = p.morphTics; + MorphedPlayerClass = p.MorphedPlayerClass; + MorphStyle = p.MorphStyle; + MorphExitFlash = p.MorphExitFlash; + PremorphWeapon = p.PremorphWeapon; + chickenPeck = p.chickenPeck; + jumpTics = p.jumpTics; + respawn_time = p.respawn_time; + camera = p.camera; + air_finished = p.air_finished; + LastDamageType = p.LastDamageType; + savedyaw = p.savedyaw; + savedpitch = p.savedpitch; + angle = p.angle; + dest = p.dest; + prev = p.prev; + enemy = p.enemy; + missile = p.missile; + mate = p.mate; + last_mate = p.last_mate; + settings_controller = p.settings_controller; + skill = p.skill; + t_active = p.t_active; + t_respawn = p.t_respawn; + t_strafe = p.t_strafe; + t_react = p.t_react; + t_fight = p.t_fight; + t_roam = p.t_roam; + t_rocket = p.t_rocket; + isbot = p.isbot; + first_shot = p.first_shot; + sleft = p.sleft; + allround = p.allround; + oldx = p.oldx; + oldy = p.oldy; + BlendR = p.BlendR; + BlendG = p.BlendG; + BlendB = p.BlendB; + BlendA = p.BlendA; + LogText = p.LogText; + MinPitch = p.MinPitch; + MaxPitch = p.MaxPitch; + crouching = p.crouching; + crouchdir = p.crouchdir; + crouchfactor = p.crouchfactor; + crouchoffset = p.crouchoffset; + crouchviewdelta = p.crouchviewdelta; + weapons = p.weapons; + ConversationNPC = p.ConversationNPC; + ConversationPC = p.ConversationPC; + ConversationNPCAngle = p.ConversationNPCAngle; + ConversationFaceTalker = p.ConversationFaceTalker; + return *this; +} + // This function supplements the pointer cleanup in dobject.cpp, because // player_t is not derived from DObject. (I tried it, and DestroyScan was // unable to properly determine the player object's type--possibly From d05cdb79ef9b25ad8aac0d66012209c20b9d89bc Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:22:21 -0500 Subject: [PATCH 4/9] Switch true to LAF_ISMELEEATTACK inside A_Punch's call to P_LineAttack() --- src/g_doom/a_doomweaps.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 9dd055711..368d7ce8b 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -53,7 +53,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch) angle += pr_punch.Random2() << 18; pitch = P_AimLineAttack (self, angle, MELEERANGE, &linetarget); - P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true, &linetarget); + P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, LAF_ISMELEEATTACK, &linetarget); // turn to face target if (linetarget) From a7a7d5d6b3dc5075ea5c82b7b50ac2c12dbadfa4 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:25:00 -0500 Subject: [PATCH 5/9] Add missing prantheses for A_CustomPunch's puffFlags calculation - Fixed: Need parentheses for precedence when setting puffFlags in A_CustomPunch. Otherwise, it's completely broken. --- src/thingdef/thingdef_codeptr.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index f5ef45f45..c97aee39c 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1404,7 +1404,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) } if (!PuffType) PuffType = PClass::FindClass(NAME_BulletPuff); - int puffFlags = LAF_ISMELEEATTACK | (flags & CPF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0; + int puffFlags = LAF_ISMELEEATTACK | ((flags & CPF_NORANDOMPUFFZ) ? LAF_NORANDOMPUFFZ : 0); P_LineAttack (self, angle, Range, pitch, Damage, NAME_Melee, PuffType, puffFlags, &linetarget, &actualdamage); @@ -1426,7 +1426,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) if (flags & CPF_PULLIN) self->flags |= MF_JUSTATTACKED; if (flags & CPF_DAGGER) P_DaggerAlert (self, linetarget); - } } From e3741c809752f67d07a9004df823849ae5b55d0e Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:29:19 -0500 Subject: [PATCH 6/9] GetSelectedSize() needs to check for a valid selection. - With mouse navigation, there's no guarantee that there even is a selected item. --- src/menu/videomenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp index 8a6e6720d..f26b90704 100644 --- a/src/menu/videomenu.cpp +++ b/src/menu/videomenu.cpp @@ -348,7 +348,7 @@ void M_InitVideoModesMenu () static bool GetSelectedSize (int *width, int *height) { FOptionMenuDescriptor *opt = GetVideoModeMenu(); - if (opt != NULL) + if (opt != NULL && (unsigned)opt->mSelectedItem < opt->mItems.Size()) { int line = opt->mSelectedItem; int hsel; From 75535fba727d0aa9c733c4ee4cf9d32d1d75ab93 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:32:46 -0500 Subject: [PATCH 7/9] Do not enter testing mode if a valid mode is not selected. - It doesn't make much sense to "test" the current mode if a non-video mode is selected in the menu, so don't. --- src/menu/videomenu.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp index f26b90704..1d1d02383 100644 --- a/src/menu/videomenu.cpp +++ b/src/menu/videomenu.cpp @@ -166,15 +166,18 @@ public: NewWidth = SCREENWIDTH; NewHeight = SCREENHEIGHT; } - OldWidth = SCREENWIDTH; - OldHeight = SCREENHEIGHT; - OldBits = DisplayBits; - NewBits = BitTranslate[DummyDepthCvar]; - setmodeneeded = true; - testingmode = I_GetTime(false) + 5 * TICRATE; - S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); - SetModesMenu (NewWidth, NewHeight, NewBits); - return true; + else + { + OldWidth = SCREENWIDTH; + OldHeight = SCREENHEIGHT; + OldBits = DisplayBits; + NewBits = BitTranslate[DummyDepthCvar]; + setmodeneeded = true; + testingmode = I_GetTime(false) + 5 * TICRATE; + S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); + SetModesMenu (NewWidth, NewHeight, NewBits); + return true; + } } return Super::Responder(ev); } From ad7aefff20b4047b5bac744a13743dcba24cc775 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 21:37:51 -0500 Subject: [PATCH 8/9] - Fixed: Do not apply AVOIDMELEE logic when moving toward a goal --- src/p_enemy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 81a58ac15..359b49f9c 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -915,7 +915,7 @@ void P_NewChaseDir(AActor * actor) // MBF's monster_backing option. Made an actor flag instead. Also cleaned the code up to make it readable. // Todo: implement the movement logic AActor *target = actor->target; - if (target->health > 0 && !actor->IsFriend(target)) + if (target->health > 0 && !actor->IsFriend(target) && target != actor->goal) { // Live enemy target if (actor->flags3 & MF3_AVOIDMELEE) From 5850279090bc29f3f76811baaf719eb319bdf1bc Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 18 Sep 2013 22:03:59 -0500 Subject: [PATCH 9/9] - Fixed: Thing_SetGoal could put an actor's target and goal out of sync. If an actor is already targeting a goal, and Thing_SetGoal is used on it, it would still be left targeting the old goal instead of the new one. This messed up checks in A_Chase for walking towards a goal vs a real target. --- src/p_lnspec.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 869fd5169..12c877116 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -1562,9 +1562,21 @@ FUNC(LS_Thing_SetGoal) ok = true; if (self->flags & MF_SHOOTABLE) { + if (self->target == self->goal) + { // Targeting a goal already? -> don't target it anymore. + // A_Look will set it to the goal, presuming no real targets + // come into view by then. + self->target = NULL; + } self->goal = goal; - if (arg3 == 0) self->flags5 &=~ MF5_CHASEGOAL; - else self->flags5 |= MF5_CHASEGOAL; + if (arg3 == 0) + { + self->flags5 &= ~MF5_CHASEGOAL; + } + else + { + self->flags5 |= MF5_CHASEGOAL; + } if (self->target == NULL) { self->reactiontime = arg2 * TICRATE;