diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 53e82bea6..fa4544ecd 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,13 @@ +June 22, 2008 (Changes by Graf Zahl) +- Added support for ST's QUARTERGRAVITY flag. +- Added a generalized version of Skulltag's A_CheckRailReload function. +- Fixed: DrawImage didn't take 0 as a valid image index. +- Added Gez's RandomSpawner submission with significant changes. +- Added optional blocks for MAPINFO map definitions. ZDoom doesn't use + this feature itself but it allows other ports based on ZDoom + to implement their own sets of options without making such a MAPINFO + unreadable by ZDoom. + June 16, 2008 (Changes by Graf Zahl) - Fixed: The mugshot would not reset on re-spawn. - Fixed: Picking up a weapon would sometimes not activate the grin. diff --git a/src/codepointers.h b/src/codepointers.h index 25270f613..63e18004d 100644 --- a/src/codepointers.h +++ b/src/codepointers.h @@ -110,3 +110,5 @@ ACTOR(LookEx) ACTOR(JumpIfTargetInLOS) ACTOR(DamageMaster) ACTOR(DamageChildren) +ACTOR(CheckForReload) +ACTOR(ResetReloadCounter) diff --git a/src/g_doom/a_bossbrain.cpp b/src/g_doom/a_bossbrain.cpp index 832c872cd..8f96cfb60 100644 --- a/src/g_doom/a_bossbrain.cpp +++ b/src/g_doom/a_bossbrain.cpp @@ -6,6 +6,7 @@ #include "s_sound.h" #include "a_doomglobal.h" #include "statnums.h" +#include "thingdef/thingdef.h" void A_Fire (AActor *); // from m_archvile.cpp @@ -242,12 +243,18 @@ void A_BrainSpit (AActor *self) if (targ != NULL) { + const PClass *spawntype = NULL; + int index = CheckIndex (1, NULL); + if (index >= 0) spawntype = PClass::FindClass ((ENamedName)StateParameters[index]); + if (spawntype == NULL) spawntype = RUNTIME_CLASS(ASpawnShot); + // spawn brain missile - spit = P_SpawnMissile (self, targ, RUNTIME_CLASS(ASpawnShot)); + spit = P_SpawnMissile (self, targ, spawntype); if (spit != NULL) { spit->target = targ; + spit->master = self; // [RH] Do this correctly for any trajectory. Doom would divide by 0 // if the target had the same y coordinate as the spitter. if ((spit->momx | spit->momy) == 0) @@ -265,7 +272,15 @@ void A_BrainSpit (AActor *self) spit->reactiontime /= spit->state->GetTics(); } - S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE); + if (index >= 0) + { + S_Sound(self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NONE); + } + else + { + // compatibility fallback + S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE); + } } } @@ -275,51 +290,109 @@ void A_SpawnFly (AActor *self) AActor *fog; AActor *targ; int r; - const char *type; if (--self->reactiontime) return; // still flying targ = self->target; - // First spawn teleport fire. - fog = Spawn (targ->x, targ->y, targ->z, ALLOW_REPLACE); - S_Sound (fog, CHAN_BODY, "brain/spawn", 1, ATTN_NORM); - // Randomly select monster to spawn. - r = pr_spawnfly (); - - // Probability distribution (kind of :), - // decreasing likelihood. - if (r < 50) type = "DoomImp"; - else if (r < 90) type = "Demon"; - else if (r < 120) type = "Spectre"; - else if (r < 130) type = "PainElemental"; - else if (r < 160) type = "Cacodemon"; - else if (r < 162) type = "Archvile"; - else if (r < 172) type = "Revenant"; - else if (r < 192) type = "Arachnotron"; - else if (r < 222) type = "Fatso"; - else if (r < 246) type = "HellKnight"; - else type = "BaronOfHell"; - - newmobj = Spawn (type, targ->x, targ->y, targ->z, ALLOW_REPLACE); - if (newmobj != NULL) + const PClass *spawntype = NULL; + int index = CheckIndex (1, NULL); + // First spawn teleport fire. + if (index >= 0) { - // Make the new monster hate what the boss eye hates - AActor *eye = self->target; - - if (eye != NULL) + spawntype = PClass::FindClass ((ENamedName)StateParameters[index]); + if (spawntype != NULL) { - newmobj->CopyFriendliness (eye, false); + fog = Spawn (spawntype, targ->x, targ->y, targ->z, ALLOW_REPLACE); + if (fog != NULL) S_Sound (fog, CHAN_BODY, fog->SeeSound, 1, ATTN_NORM); } - if (newmobj->SeeState != NULL && P_LookForPlayers (newmobj, true)) - newmobj->SetState (newmobj->SeeState); + } + else + { + fog = Spawn (targ->x, targ->y, targ->z, ALLOW_REPLACE); + if (fog != NULL) S_Sound (fog, CHAN_BODY, "brain/spawn", 1, ATTN_NORM); + } - if (!(newmobj->ObjectFlags & OF_EuthanizeMe)) + FName SpawnName; + + if (self->master != NULL) + { + FDropItem *di; // di will be our drop item list iterator + FDropItem *drop; // while drop stays as the reference point. + int n=0; + + drop = di = GetDropItems(self->master->GetClass()); + if (di != NULL) { - // telefrag anything in this spot - P_TeleportMove (newmobj, newmobj->x, newmobj->y, newmobj->z, true); + while (di != NULL) + { + if (di->Name != NAME_None) + { + if (di->amount < 0) di->amount = 1; // default value is -1, we need a positive value. + n += di->amount; // this is how we can weight the list. + di = di->Next; + } + } + di = drop; + n = pr_spawnfly(n); + while (n > 0) + { + if (di->Name != NAME_None) + { + n -= di->amount; // logically, none of the -1 values have survived by now. + if (n > -1) di = di->Next; // If we get into the negatives, a spawnfog could be spawned... + // It would mean we've reached the end of the list of monsters. + } + } + + SpawnName = di->Name; + } + } + if (SpawnName == NAME_None) + { + const char *type; + // Randomly select monster to spawn. + r = pr_spawnfly (); + + // Probability distribution (kind of :), + // decreasing likelihood. + if (r < 50) type = "DoomImp"; + else if (r < 90) type = "Demon"; + else if (r < 120) type = "Spectre"; + else if (r < 130) type = "PainElemental"; + else if (r < 160) type = "Cacodemon"; + else if (r < 162) type = "Archvile"; + else if (r < 172) type = "Revenant"; + else if (r < 192) type = "Arachnotron"; + else if (r < 222) type = "Fatso"; + else if (r < 246) type = "HellKnight"; + else type = "BaronOfHell"; + + SpawnName = type; + } + spawntype = PClass::FindClass(SpawnName); + if (spawntype != NULL) + { + newmobj = Spawn (spawntype, targ->x, targ->y, targ->z, ALLOW_REPLACE); + if (newmobj != NULL) + { + // Make the new monster hate what the boss eye hates + AActor *eye = self->target; + + if (eye != NULL) + { + newmobj->CopyFriendliness (eye, false); + } + if (newmobj->SeeState != NULL && P_LookForPlayers (newmobj, true)) + newmobj->SetState (newmobj->SeeState); + + if (!(newmobj->ObjectFlags & OF_EuthanizeMe)) + { + // telefrag anything in this spot + P_TeleportMove (newmobj, newmobj->x, newmobj->y, newmobj->z, true); + } } } @@ -375,3 +448,4 @@ void DBrainState::Serialize (FArchive &arc) arc << SerialTarget; } } + diff --git a/src/g_level.cpp b/src/g_level.cpp index 89c37337f..cb4ecf3c6 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -108,6 +108,48 @@ static void ClearClusterInfoStrings (cluster_info_t *cinfo); static void ParseSkill (FScanner &sc); static void G_VerifySkill(); +struct FOptionalMapinfoParser +{ + const char *keyword; + MIParseFunc parsefunc; +}; + + +static TArray optmapinf(TArray::NoInit); + +void AddOptionalMapinfoParser(const char *keyword, MIParseFunc parsefunc) +{ + FOptionalMapinfoParser mi; + + mi.keyword = keyword; + mi.parsefunc = parsefunc; + optmapinf.Push(mi); +} + +static void ParseOptionalBlock(const char *keyword, FScanner &sc, level_info_t *info) +{ + for(unsigned i=0;i EndSequences; @@ -314,9 +356,6 @@ static const char *MapInfoMapLevel[] = "noinfiniteflightpowerup", "allowrespawn", "teamdamage", - "fogdensity", - "outsidefogdensity", - "skyfog", "teamplayon", "teamplayoff", "checkswitchrange", @@ -466,9 +505,6 @@ MapHandlers[] = { MITYPE_CLRFLAG, LEVEL_INFINITE_FLIGHT, 0 }, { MITYPE_SETFLAG, LEVEL_ALLOWRESPAWN, 0 }, { MITYPE_FLOAT, lioffset(teamdamage), 0 }, - { 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 }, { MITYPE_SETFLAG, LEVEL_CHECKSWITCHRANGE, 0 }, @@ -632,6 +668,19 @@ static FSpecialAction *CopySpecialActions(FSpecialAction *spec) return spec; } +static FOptionalMapinfoData *CopyOptData(FOptionalMapinfoData *opdata) +{ + FOptionalMapinfoData **opt = &opdata; + + while (*opt) + { + FOptionalMapinfoData *newop = (*opt)->Clone(); + *opt = newop; + opt = &newop->Next; + } + return opdata; +} + static void CopyString (char *& string) { if (string != NULL) @@ -663,6 +712,12 @@ static void ClearLevelInfoStrings(level_info_t *linfo) delete spac; spac = next; } + for (FOptionalMapinfoData *spac = linfo->opdata; spac != NULL; ) + { + FOptionalMapinfoData *next = spac->Next; + delete spac; + spac = next; + } } static void ClearClusterInfoStrings(cluster_info_t *cinfo) @@ -743,6 +798,7 @@ static void G_DoParseMapInfo (int lump) CopyString(levelinfo->soundinfo); CopyString(levelinfo->sndseq); levelinfo->specialactions = CopySpecialActions(levelinfo->specialactions); + levelinfo->opdata = CopyOptData(levelinfo->opdata); if (HexenHack) { levelinfo->WallHorizLight = levelinfo->WallVertLight = 0; @@ -867,7 +923,28 @@ static void ParseMapInfoLower (FScanner &sc, sc.UnGet (); break; } - entry = sc.MustMatchString (strings); + entry = sc.MatchString (strings); + + if (entry == -1) + { + FString keyword = sc.String; + sc.MustGetString(); + if (levelinfo != NULL) + { + if (sc.Compare("{")) + { + ParseOptionalBlock(keyword, sc, levelinfo); + continue; + } + else if (!stricmp(keyword, "nobotnodes")) // Ignore this Skulltag option if it appears + { + continue; + } + } + sc.ScriptError("Unknown keyword '%s'", keyword.GetChars()); + } + + handler = handlers + entry; switch (handler->type) { diff --git a/src/g_level.h b/src/g_level.h index 7d6d206b6..2f003c4d9 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -136,6 +136,20 @@ struct FSpecialAction class FCompressedMemFile; class DScroller; +class FScanner; +struct level_info_t; +typedef void (*MIParseFunc)(FScanner &sc, level_info_t *info); + +void AddOptionalMapinfoParser(const char *keyword, MIParseFunc parsefunc); + +struct FOptionalMapinfoData +{ + FOptionalMapinfoData *Next; + FName identifier; + FOptionalMapinfoData() { Next = NULL; identifier = NAME_None; } + virtual FOptionalMapinfoData *Clone() const = 0; +}; + struct level_info_t { char mapname[9]; @@ -187,13 +201,11 @@ struct level_info_t char *sndseq; char bordertexture[9]; - int fogdensity; - int outsidefogdensity; - int skyfog; - FSpecialAction * specialactions; - float teamdamage; + FSpecialAction * specialactions; + FOptionalMapinfoData *opdata; + }; // [RH] These get zeroed every tic and are updated by thinkers. diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index a19b05a50..f9ccbe2a6 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -218,6 +218,7 @@ public: const PClass *AltProjectileType; // Projectile used by alternate attack int SelectionOrder; // Lower-numbered weapons get picked first fixed_t MoveCombatDist; // Used by bots, but do they *really* need it? + int ReloadCounter; // For A_CheckForReload // In-inventory instance variables TObjPtr Ammo1, Ammo2; diff --git a/src/g_shared/a_randomspawner.cpp b/src/g_shared/a_randomspawner.cpp new file mode 100644 index 000000000..f0e646c24 --- /dev/null +++ b/src/g_shared/a_randomspawner.cpp @@ -0,0 +1,86 @@ +#include "actor.h" +#include "info.h" +#include "m_random.h" +#include "p_local.h" +#include "p_enemy.h" +#include "s_sound.h" +#include "a_doomglobal.h" +#include "statnums.h" +#include "gstrings.h" +#include "a_action.h" +#include "thingdef/thingdef.h" + +/* +- in the decorate definition define multiple drop items +- use the function GetDropItems to get the first drop item, then iterate over them and count how many dropitems are defined. +- with M_Random( ) % NUMBEROFDROPITEMS you get a random drop item number (let's call it n) +- use GetDropItems again to get the first drop item, then iterate to the n-th drop item +*/ +static FRandom pr_randomspawn("RandomSpawn"); + +class ARandomSpawner : public AActor +{ + DECLARE_STATELESS_ACTOR (ARandomSpawner, AActor) + + void PostBeginPlay() + { + AActor *newmobj; + FDropItem *di; // di will be our drop item list iterator + FDropItem *drop; // while drop stays as the reference point. + int n=0; + + Super::PostBeginPlay(); + + drop = di = GetDropItems(RUNTIME_TYPE(this)); + // Always make sure it actually exists. + if (di != NULL) + { + // First, we get the size of the array... + while (di != NULL) + { + if (di->Name != NAME_None) + { + if (di->amount < 0) di->amount = 1; // default value is -1, we need a positive value. + n += di->amount; // this is how we can weight the list. + di = di->Next; + } + } + // Then we reset the iterator to the start position... + di = drop; + // Take a random number... + n = pr_randomspawn(n); + // And iterate in the array up to the random number chosen. + while (n > 0) + { + if (di->Name != NAME_None) + { + n -= di->amount; + di = di->Next; + } + } + // So now we can spawn the dropped item. + if (pr_randomspawn() <= di->probability) // prob 255 = always spawn, prob 0 = never spawn. + { + newmobj = Spawn(di->Name, x, y, z, ALLOW_REPLACE); + // copy everything relevant + newmobj->SpawnAngle = newmobj->angle = angle; + newmobj->special = special; + newmobj->args[0] = args[0]; + newmobj->args[1] = args[1]; + newmobj->args[2] = args[2]; + newmobj->args[3] = args[3]; + newmobj->args[4] = args[4]; + newmobj->SpawnFlags = SpawnFlags; + newmobj->HandleSpawnFlags(); + newmobj->momx = momx; + newmobj->momy = momy; + newmobj->momz = momz; + newmobj->CopyFriendliness(this, false); + } + } + } +}; + +IMPLEMENT_STATELESS_ACTOR (ARandomSpawner, Any, -1, 0) +END_DEFAULTS + diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 27742cc9e..1ca3d179e 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -53,7 +53,8 @@ void AWeapon::Serialize (FArchive &arc) << SelectionOrder << MoveCombatDist << Ammo1 << Ammo2 << SisterWeapon << GivenAsMorphWeapon - << bAltFire; + << bAltFire + << ReloadCounter; } //=========================================================================== diff --git a/src/g_shared/sbarinfo_display.cpp b/src/g_shared/sbarinfo_display.cpp index 91ba7e077..8027ca1a3 100644 --- a/src/g_shared/sbarinfo_display.cpp +++ b/src/g_shared/sbarinfo_display.cpp @@ -479,7 +479,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a } else if((cmd.flags & DRAWIMAGE_INVENTORYICON)) texture = TexMan[cmd.sprite_index]; - else if(cmd.image_index > 0) + else if(cmd.image_index >= 0) texture = Images[cmd.image_index]; DrawGraphic(texture, cmd.x, cmd.y, xOffset, yOffset, alpha, !!(cmd.flags & DRAWIMAGE_TRANSLATABLE), false, !!(cmd.flags & DRAWIMAGE_OFFSET_CENTER)); diff --git a/src/g_shared/sbarinfo_parser.cpp b/src/g_shared/sbarinfo_parser.cpp index 0be4682d3..77ad4b6a5 100644 --- a/src/g_shared/sbarinfo_parser.cpp +++ b/src/g_shared/sbarinfo_parser.cpp @@ -447,6 +447,7 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) } else { + //sc.CheckToken(TK_Identifier); cmd.flags |= DRAWIMAGE_INVENTORYICON; const PClass* item = PClass::FindClass(sc.String); if(item == NULL || !PClass::FindClass("Inventory")->IsAncestorOf(item)) //must be a kind of Inventory diff --git a/src/textures/textures.h b/src/textures/textures.h index 369a85edb..073a11e5b 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -21,14 +21,14 @@ class FTextureID friend void R_InitSpriteDefs (); public: - FTextureID() {} + FTextureID() throw() {} bool isNull() const { return texnum == 0; } bool isValid() const { return texnum > 0; } bool Exists() const { return texnum >= 0; } void SetInvalid() { texnum = -1; } bool operator ==(const FTextureID &other) const { return texnum == other.texnum; } bool operator !=(const FTextureID &other) const { return texnum != other.texnum; } - FTextureID operator +(int offset); + FTextureID operator +(int offset) throw(); int GetIndex() const { return texnum; } // Use this only if you absolutely need the index! // The switch list needs these to sort the switches by texture index diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index b446a2d72..d156abbb9 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1416,7 +1416,7 @@ static void InitSpawnedItem(AActor *self, AActor *mo, int flags) (deathmatch && attacker->FriendPlayer!=0 && attacker->FriendPlayer!=mo->FriendPlayer)) { // Target the monster which last attacked the player - mo->target = attacker; + mo->LastHeard = mo->target = attacker; } } } @@ -2261,3 +2261,50 @@ void A_DamageChildren(AActor * self) } // [KS] *** End of my modifications *** + +//=========================================================================== +// +// Modified code pointer from Skulltag +// +//=========================================================================== + +void A_CheckForReload( AActor *self ) +{ + if ( self->player == NULL || self->player->ReadyWeapon == NULL ) + return; + + int index = CheckIndex(2); + if (index<0) return; + + AWeapon *weapon = self->player->ReadyWeapon; + int count = EvalExpressionI (StateParameters[index], self); + + weapon->ReloadCounter = (weapon->ReloadCounter+1) % count; + + // If we have not made our last shot... + if (weapon->ReloadCounter != 0) + { + // Go back to the refire frames, instead of continuing on to the reload frames. + DoJump(self, CallingState, StateParameters[index + 1]); + } + else + { + // We need to reload. However, don't reload if we're out of ammo. + weapon->CheckAmmo( false, false ); + } +} + +//=========================================================================== +// +// Resets the counter for the above function +// +//=========================================================================== + +void A_ResetReloadCounter(AActor *self) +{ + if ( self->player == NULL || self->player->ReadyWeapon == NULL ) + return; + + AWeapon *weapon = self->player->ReadyWeapon; + weapon->ReloadCounter = 0; +} diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index cc4d637d7..d2a581eb3 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -98,7 +98,8 @@ enum DEPF_LOWGRAVITY, DEPF_LONGMELEERANGE, DEPF_SHORTMISSILERANGE, - DEPF_PICKUPFLASH + DEPF_PICKUPFLASH, + DEPF_QUARTERGRAVITY, }; static flagdef ActorFlags[]= @@ -256,7 +257,9 @@ static flagdef ActorFlags[]= DEFINE_DEPRECATED_FLAG(LOWGRAVITY), DEFINE_DEPRECATED_FLAG(SHORTMISSILERANGE), DEFINE_DEPRECATED_FLAG(LONGMELEERANGE), + DEFINE_DEPRECATED_FLAG(QUARTERGRAVITY), DEFINE_DUMMY_FLAG(NONETID), + DEFINE_DUMMY_FLAG(ALLOWCLIENTSPAWN), }; static flagdef InventoryFlags[] = @@ -292,7 +295,6 @@ static flagdef WeaponFlags[] = DEFINE_FLAG(WIF, PRIMARY_USES_BOTH, AWeapon, WeaponFlags), DEFINE_FLAG(WIF, WIMPY_WEAPON, AWeapon, WeaponFlags), DEFINE_FLAG(WIF, POWERED_UP, AWeapon, WeaponFlags), - //DEFINE_FLAG(WIF, EXTREME_DEATH, AWeapon, WeaponFlags), // this should be removed now! DEFINE_FLAG(WIF, STAFF2_KICKBACK, AWeapon, WeaponFlags), DEFINE_FLAG(WIF_BOT, EXPLOSIVE, AWeapon, WeaponFlags), DEFINE_FLAG2(WIF_BOT_MELEE, MELEEWEAPON, AWeapon, WeaponFlags), @@ -424,6 +426,9 @@ static void HandleDeprecatedFlags(AActor *defaults, bool set, int index) case DEPF_LONGMELEERANGE: defaults->meleethreshold = set? 196*FRACUNIT : 0; break; + case DEPF_QUARTERGRAVITY: + defaults->gravity = set? FRACUNIT/4 : FRACUNIT; + break; case DEPF_PICKUPFLASH: if (set) { diff --git a/src/version.h b/src/version.h index f2093bbe9..200f8c812 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 1036 +#define MINSAVEVER 1044 #if SVN_REVISION_NUMBER < MINSAVEVER // Never write a savegame with a version lower than what we need diff --git a/wadsrc/decorate/nativeclasses.txt b/wadsrc/decorate/nativeclasses.txt index 43d3add23..ad3a421f6 100644 --- a/wadsrc/decorate/nativeclasses.txt +++ b/wadsrc/decorate/nativeclasses.txt @@ -50,9 +50,9 @@ class Actor extends Thinker action native A_BrainScream(); action native A_BrainDie(); action native A_BrainAwake(); - action native A_BrainSpit(); + action native A_BrainSpit(optional class spawntype); action native A_SpawnSound(); - action native A_SpawnFly(); + action native A_SpawnFly(optional class spawntype); action native A_BrainExplode(); action native A_Die(optional name damagetype); action native A_Detonate(); @@ -215,5 +215,7 @@ class Inventory extends Actor action native A_CheckReload(); action native A_GunFlash(); action native A_Saw(optional coerce sound fullsound, optional coerce sound hitsound, optional eval int damage, optional class pufftype); + action native A_CheckForReload(eval int counter, state label); + action native A_ResetReloadCounter(); } diff --git a/zdoom.vcproj b/zdoom.vcproj index 8028d5d7b..db9dc0031 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -55,9 +55,11 @@ EnableIntrinsicFunctions="true" FavorSizeOrSpeed="1" OmitFramePointers="true" + WholeProgramOptimization="false" AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;jpeg-6b;snes_spc\snes_spc" PreprocessorDefinitions="NDEBUG,WIN32,_WIN32,_WINDOWS,USEASM,HAVE_STRUPR,HAVE_FILELENGTH" StringPooling="true" + ExceptionHandling="1" RuntimeLibrary="0" EnableFunctionLevelLinking="true" ForceConformanceInForLoopScope="true" @@ -106,6 +108,7 @@ TerminalServerAware="2" OptimizeReferences="2" EnableCOMDATFolding="2" + LinkTimeCodeGeneration="0" SetChecksum="true" /> + +