diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b1e6da2a72..138fcf5a2c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -778,6 +778,7 @@ set( NOT_COMPILED_SOURCE_FILES g_hexen/a_fighterquietus.cpp g_hexen/a_firedemon.cpp g_hexen/a_flechette.cpp + g_hexen/a_flies.cpp g_hexen/a_fog.cpp g_hexen/a_healingradius.cpp g_hexen/a_heresiarch.cpp diff --git a/src/actor.h b/src/actor.h index bf84ce37c7..50247c0bbd 100644 --- a/src/actor.h +++ b/src/actor.h @@ -1035,7 +1035,7 @@ public: virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true); bool isFast(); bool isSlow(); - void SetIdle(); + void SetIdle(bool nofunction=false); void ClearCounters(); FState *GetRaiseState(); void Revive(); diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 778f25be1d..74968404d4 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -641,6 +641,23 @@ CCMD (error_fatal) } } +//========================================================================== +// +// CCMD crashout +// +// Debugging routine for testing the crash logger. +// Useless in a win32 debug build, because that doesn't enable the crash logger. +// +//========================================================================== + +#if !defined(_WIN32) || !defined(_DEBUG) +CCMD (crashout) +{ + *(volatile int *)0 = 0; +} +#endif + + CCMD (dir) { FString dir, path; diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 393ca11cc4..4bb53e3fed 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -47,6 +47,7 @@ #include "v_video.h" #include "gameconfigfile.h" #include "resourcefiles/resourcefile.h" +#include "version.h" CVAR (Bool, queryiwad, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); @@ -504,19 +505,19 @@ int FIWadManager::IdentifyVersion (TArray &wadfiles, const char *iwad, if (numwads == 0) { I_FatalError ("Cannot find a game IWAD (doom.wad, doom2.wad, heretic.wad, etc.).\n" - "Did you install ZDoom properly? You can do either of the following:\n" + "Did you install " GAMENAME " properly? You can do either of the following:\n" "\n" #if defined(_WIN32) - "1. Place one or more of these wads in the same directory as ZDoom.\n" - "2. Edit your zdoom-username.ini and add the directories of your iwads\n" + "1. Place one or more of these wads in the same directory as " GAMENAME ".\n" + "2. Edit your " GAMENAMELOWERCASE "-username.ini and add the directories of your iwads\n" "to the list beneath [IWADSearch.Directories]"); #elif defined(__APPLE__) - "1. Place one or more of these wads in ~/Library/Application Support/zdoom/\n" - "2. Edit your ~/Library/Preferences/zdoom.ini and add the directories\n" + "1. Place one or more of these wads in ~/Library/Application Support/" GAMENAMELOWERCASE "/\n" + "2. Edit your ~/Library/Preferences/" GAMENAMELOWERCASE ".ini and add the directories\n" "of your iwads to the list beneath [IWADSearch.Directories]"); #else - "1. Place one or more of these wads in ~/.config/zdoom/.\n" - "2. Edit your ~/.config/zdoom/zdoom.ini and add the directories of your\n" + "1. Place one or more of these wads in ~/.config/" GAMENAMELOWERCASE "/.\n" + "2. Edit your ~/.config/" GAMENAMELOWERCASE "/" GAMENAMELOWERCASE ".ini and add the directories of your\n" "iwads to the list beneath [IWADSearch.Directories]"); #endif } diff --git a/src/g_hexen/a_flies.cpp b/src/g_hexen/a_flies.cpp new file mode 100644 index 0000000000..3c677d5cb3 --- /dev/null +++ b/src/g_hexen/a_flies.cpp @@ -0,0 +1,106 @@ +static FRandom pr_fly("GetOffMeFly"); + +//=========================================================================== +// +// FindCorpse +// +// Finds a corpse to buzz around. We can't use a blockmap check because +// corpses generally aren't linked into the blockmap. +// +//=========================================================================== + +static AActor *FindCorpse(AActor *fly, sector_t *sec, int recurselimit) +{ + AActor *fallback = NULL; + sec->validcount = validcount; + + // Search the current sector + for (AActor *check = sec->thinglist; check != NULL; check = check->snext) + { + if (check == fly) + continue; + if (!(check->flags & MF_CORPSE)) + continue; + if (!P_CheckSight(fly, check)) + continue; + fallback = check; + if (pr_fly(2)) // 50% chance to try to pick a different corpse + continue; + return check; + } + if (--recurselimit <= 0 || (fallback != NULL && pr_fly(2))) + { + return fallback; + } + // Try neighboring sectors + for (int i = 0; i < sec->linecount; ++i) + { + line_t *line = sec->lines[i]; + sector_t *sec2 = (line->frontsector == sec) ? line->backsector : line->frontsector; + if (sec2 != NULL && sec2->validcount != validcount) + { + AActor *neighbor = FindCorpse(fly, sec2, recurselimit); + if (neighbor != NULL) + { + return neighbor; + } + } + } + return fallback; +} + +DEFINE_ACTION_FUNCTION(AActor, A_FlySearch) +{ + // The version from the retail beta is not so great for general use: + // 1. Pick one of the first fifty thinkers at random. + // 2. Starting from that thinker, find one that is an actor, not itself, + // and within sight. Give up after 100 sequential thinkers. + // It's effectively useless if there are more than 150 thinkers on a map. + // + // So search the sectors instead. We can't potentially find something all + // the way on the other side of the map and we can't find invisible corpses, + // but at least we aren't crippled on maps with lots of stuff going on. + validcount++; + AActor *other = FindCorpse(self, self->Sector, 5); + if (other != NULL) + { + self->target = other; + self->SetState(self->FindState("Buzz")); + } +} + +DEFINE_ACTION_FUNCTION(AActor, A_FlyBuzz) +{ + AActor *targ = self->target; + + if (targ == NULL || !(targ->flags & MF_CORPSE) || pr_fly() < 5) + { + self->SetIdle(); + return; + } + + angle_t ang = R_PointToAngle2(self->x, self->y, targ->x, targ->y); + self->angle = ang; + self->args[0]++; + ang >>= ANGLETOFINESHIFT; + if (!P_TryMove(self, self->x + 6 * finecosine[ang], self->y + 6 * finesine[ang], true)) + { + self->SetIdle(true); + return; + } + if (self->args[0] & 2) + { + self->velx += (pr_fly() - 128) << BOBTOFINESHIFT; + self->vely += (pr_fly() - 128) << BOBTOFINESHIFT; + } + int zrand = pr_fly(); + if (targ->z + 5*FRACUNIT < self->z && zrand > 150) + { + zrand = -zrand; + } + self->velz = zrand << BOBTOFINESHIFT; + if (pr_fly() < 40) + { + S_Sound(self, CHAN_VOICE, self->ActiveSound, 0.5f, ATTN_STATIC); + } +} diff --git a/src/g_hexen/a_hexenmisc.cpp b/src/g_hexen/a_hexenmisc.cpp index fa07a67599..1141f381f9 100644 --- a/src/g_hexen/a_hexenmisc.cpp +++ b/src/g_hexen/a_hexenmisc.cpp @@ -38,6 +38,7 @@ #include "a_fighterquietus.cpp" #include "a_firedemon.cpp" #include "a_flechette.cpp" +#include "a_flies.cpp" #include "a_fog.cpp" #include "a_healingradius.cpp" #include "a_heresiarch.cpp" diff --git a/src/m_specialpaths.cpp b/src/m_specialpaths.cpp index e6f74eda61..a45c23dc79 100644 --- a/src/m_specialpaths.cpp +++ b/src/m_specialpaths.cpp @@ -204,7 +204,7 @@ FString M_GetConfigPath(bool for_reading) { path += "/" GAME_DIR; CreatePath(path); - path += "/zdoom.ini"; + path += "/" GAMENAMELOWERCASE ".ini"; } else { // construct "$PROGDIR/zdoom-$USER.ini" @@ -224,11 +224,11 @@ FString M_GetConfigPath(bool for_reading) *probe = '_'; ++probe; } - path << "zdoom-" << uname << ".ini"; + path << GAMENAMELOWERCASE "-" << uname << ".ini"; } else { // Couldn't get user name, so just use zdoom.ini - path += "zdoom.ini"; + path += GAMENAMELOWERCASE ".ini"; } } @@ -239,7 +239,7 @@ FString M_GetConfigPath(bool for_reading) if (!FileExists(path)) { path = progdir; - path << "zdoom.ini"; + path << GAMENAMELOWERCASE ".ini"; } } @@ -411,11 +411,11 @@ FString M_GetConfigPath(bool for_reading) noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX)) { FString path; - path << cpath << "/zdoom.ini"; + path << cpath << "/" GAMENAMELOWERCASE ".ini"; return path; } // Ungh. - return "zdoom.ini"; + return GAMENAMELOWERCASE ".ini"; } //=========================================================================== @@ -497,12 +497,12 @@ FString GetUserFile (const char *file) // This can be removed after a release or two // Transfer the old zdoom directory to the new location bool moved = false; - FString oldpath = NicePath("~/.zdoom/"); + FString oldpath = NicePath("~/." GAMENAMELOWERCASE "/"); if (stat (oldpath, &extrainfo) != -1) { if (rename(oldpath, path) == -1) { - I_Error ("Failed to move old zdoom directory (%s) to new location (%s).", + I_Error ("Failed to move old " GAMENAMELOWERCASE " directory (%s) to new location (%s).", oldpath.GetChars(), path.GetChars()); } else @@ -598,7 +598,7 @@ FString M_GetCajunPath(const char *botfilename) FString M_GetConfigPath(bool for_reading) { - return GetUserFile("zdoom.ini"); + return GetUserFile(GAMENAMELOWERCASE ".ini"); } //=========================================================================== diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 74bfc56f4d..1e9dbf9b6e 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1033,6 +1033,8 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, { target->velx = target->vely = target->velz = 0; } + + player = target->player; if (!(flags & DMG_FORCED)) // DMG_FORCED skips all special damage checks, TELEFRAG_DAMAGE may not be reduced at all { if (target->flags2 & MF2_DORMANT) @@ -1043,7 +1045,6 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, if (damage < TELEFRAG_DAMAGE) // TELEFRAG_DAMAGE may not be reduced at all or it may not guarantee its effect. { - player = target->player; if (player && damage > 1) { // Take half damage in trainer mode @@ -1119,10 +1120,10 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, return -1; } } - if (target->flags5 & MF5_NODAMAGE) - { - damage = 0; - } + } + if (target->flags5 & MF5_NODAMAGE) + { + damage = 0; } } if (damage < 0) @@ -1331,7 +1332,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, // but telefragging should still do enough damage to kill the player) // Ignore players that are already dead. // [MC]Buddha2 absorbs telefrag damage, and anything else thrown their way. - if (((player->cheats & CF_BUDDHA2) || (((player->cheats & CF_BUDDHA) || (player->mo->flags7 & MF7_BUDDHA)) && (damage < TELEFRAG_DAMAGE))) && (player->playerstate != PST_DEAD)) + if (!(flags & DMG_FORCED) && (((player->cheats & CF_BUDDHA2) || (((player->cheats & CF_BUDDHA) || (player->mo->flags7 & MF7_BUDDHA)) && (damage < TELEFRAG_DAMAGE))) && (player->playerstate != PST_DEAD))) { // If this is a voodoo doll we need to handle the real player as well. player->mo->health = target->health = player->health = 1; @@ -1396,7 +1397,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, if (target->health <= 0) { //[MC]Buddha flag for monsters. - if ((target->flags7 & MF7_BUDDHA) && (damage < TELEFRAG_DAMAGE) && ((inflictor == NULL || !(inflictor->flags7 & MF7_FOILBUDDHA)) && !(flags & DMG_FOILBUDDHA))) + if (!(flags & DMG_FORCED) && ((target->flags7 & MF7_BUDDHA) && (damage < TELEFRAG_DAMAGE) && ((inflictor == NULL || !(inflictor->flags7 & MF7_FOILBUDDHA)) && !(flags & DMG_FOILBUDDHA)))) { //FOILBUDDHA or Telefrag damage must kill it. target->health = 1; } diff --git a/src/p_map.cpp b/src/p_map.cpp index 2362fbd124..1ad1728ce8 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1034,7 +1034,7 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm) // Both things overlap in x or y direction bool unblocking = false; - if (tm.FromPMove) + if (tm.FromPMove || tm.thing->player != NULL) { // Both actors already overlap. To prevent them from remaining stuck allow the move if it // takes them further apart or the move does not change the position (when called from P_ChangeSector.) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index c12bd53db5..9dd9f1ddcc 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6236,11 +6236,11 @@ void AActor::Crash() } } -void AActor::SetIdle() +void AActor::SetIdle(bool nofunction) { FState *idle = FindState (NAME_Idle); if (idle == NULL) idle = SpawnState; - SetState(idle); + SetState(idle, nofunction); } int AActor::SpawnHealth() diff --git a/src/posix/sdl/crashcatcher.c b/src/posix/sdl/crashcatcher.c index 4754a369a4..f85713e312 100644 --- a/src/posix/sdl/crashcatcher.c +++ b/src/posix/sdl/crashcatcher.c @@ -37,7 +37,7 @@ static struct { pid_t pid; int has_siginfo; siginfo_t siginfo; - char buf[1024]; + char buf[4096]; } crash_info; diff --git a/src/posix/sdl/i_main.cpp b/src/posix/sdl/i_main.cpp index d60494d1a5..7c08dacdbb 100644 --- a/src/posix/sdl/i_main.cpp +++ b/src/posix/sdl/i_main.cpp @@ -240,7 +240,7 @@ int main (int argc, char **argv) #if !defined (__APPLE__) { int s[4] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS }; - cc_install_handlers(argc, argv, 4, s, "zdoom-crash.log", DoomSpecificInfo); + cc_install_handlers(argc, argv, 4, s, GAMENAMELOWERCASE "-crash.log", DoomSpecificInfo); } #endif // !__APPLE__ diff --git a/src/version.h b/src/version.h index 84035b8e8e..2caf2fc95a 100644 --- a/src/version.h +++ b/src/version.h @@ -90,13 +90,14 @@ const char *GetVersionString(); // More stuff that needs to be different for derivatives. #define GAMENAME "GZDoom" +#define GAMENAMELOWERCASE "gzdoom" #define FORUM_URL "http://forum.drdteam.org" #define BUGS_FORUM_URL "http://forum.drdteam.org/viewforum.php?f=24" #if defined(__APPLE__) || defined(_WIN32) #define GAME_DIR GAMENAME #else -#define GAME_DIR ".config/gzdoom" +#define GAME_DIR ".config/" GAMENAMELOWERCASE #endif diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index f2a4fab4d1..c63e7bc1c2 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -1288,20 +1288,3 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n MainThread = INVALID_HANDLE_VALUE; return 0; } - -//========================================================================== -// -// CCMD crashout -// -// Debugging routine for testing the crash logger. -// Useless in a debug build, because that doesn't enable the crash logger. -// -//========================================================================== - -#ifndef _DEBUG -#include "c_dispatch.h" -CCMD (crashout) -{ - *(int *)0 = 0; -} -#endif diff --git a/wadsrc/static/actors/hexen/flies.txt b/wadsrc/static/actors/hexen/flies.txt new file mode 100644 index 0000000000..6be4a749f7 --- /dev/null +++ b/wadsrc/static/actors/hexen/flies.txt @@ -0,0 +1,28 @@ + +// Buzzy fly ---------------------------------------------------------------- + +ACTOR LittleFly 112 +{ + Game Hexen + +NOBLOCKMAP +NOGRAVITY + +CANPASS + + Speed 6 + Radius 5 + Height 5 + Mass 2 + ActiveSound "FlyBuzz" + + action native A_FlySearch(); + action native A_FlyBuzz(); + + States + { + Spawn: + TNT1 A 20 A_FlySearch // [RH] Invisible when not flying + Loop + Buzz: + AFLY ABCD 3 A_FlyBuzz + Loop + } +} diff --git a/wadsrc/static/decorate.txt b/wadsrc/static/decorate.txt index ae4b6f8517..46f1854b99 100644 --- a/wadsrc/static/decorate.txt +++ b/wadsrc/static/decorate.txt @@ -93,6 +93,7 @@ #include "actors/hexen/mageplayer.txt" #include "actors/hexen/pig.txt" #include "actors/hexen/flame.txt" +#include "actors/hexen/flies.txt" #include "actors/hexen/hexenarmor.txt" #include "actors/hexen/hexendecorations.txt" #include "actors/hexen/hexenkeys.txt" diff --git a/wadsrc/static/sprites/AFLYA0.png b/wadsrc/static/sprites/AFLYA0.png new file mode 100644 index 0000000000..d12ca16c6e Binary files /dev/null and b/wadsrc/static/sprites/AFLYA0.png differ diff --git a/wadsrc/static/sprites/AFLYB0.png b/wadsrc/static/sprites/AFLYB0.png new file mode 100644 index 0000000000..6f39e47d44 Binary files /dev/null and b/wadsrc/static/sprites/AFLYB0.png differ diff --git a/wadsrc/static/sprites/AFLYC0.png b/wadsrc/static/sprites/AFLYC0.png new file mode 100644 index 0000000000..bc2a9a3716 Binary files /dev/null and b/wadsrc/static/sprites/AFLYC0.png differ diff --git a/wadsrc/static/sprites/AFLYD0.png b/wadsrc/static/sprites/AFLYD0.png new file mode 100644 index 0000000000..8509a127da Binary files /dev/null and b/wadsrc/static/sprites/AFLYD0.png differ diff --git a/zdoom.vcproj b/zdoom.vcproj index a6a94cafe4..9c3367ff20 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -5228,6 +5228,42 @@ /> + + + + + + + + + + + + + +