diff --git a/src/actor.h b/src/actor.h index 289213450..89047cc8c 100644 --- a/src/actor.h +++ b/src/actor.h @@ -355,6 +355,7 @@ enum MF7_HITTARGET = 0x00004000, // The actor the projectile dies on is set to target, provided it's targetable anyway. MF7_HITMASTER = 0x00008000, // Same as HITTARGET, except it's master instead of target. MF7_HITTRACER = 0x00010000, // Same as HITTARGET, but for tracer. + MF7_FLYCHEAT = 0x00020000, // must be part of the actor so that it can be tracked properly diff --git a/src/am_map.cpp b/src/am_map.cpp index 29cd60793..0133a2493 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1234,7 +1234,7 @@ void AM_initVariables () for (pnum=0;pnum= 0 && pnum < MAXPLAYERS); m_x = (players[pnum].camera->x >> FRACTOMAPBITS) - m_w/2; m_y = (players[pnum].camera->y >> FRACTOMAPBITS) - m_h/2; AM_changeWindowLoc(); diff --git a/src/b_func.cpp b/src/b_func.cpp index 7165d2cc1..1c29c2cf6 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -513,7 +513,7 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) bglobal.SetBodyAt (enemy->x + FixedMul(enemy->velx, (m+2*FRACUNIT)), enemy->y + FixedMul(enemy->vely, (m+2*FRACUNIT)), ONFLOORZ, 1); - dist = P_AproxDistance(actor->x-bglobal.body1->x, actor->y-bglobal.body1->y); + //try the predicted location if (P_CheckSight (actor, bglobal.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile { diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 63950a1f5..2ae975605 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -1026,8 +1026,7 @@ CCMD(nextsecret) TEXTCOLOR_NORMAL " is for single-player only.\n"); return; } - char *next = NULL; - + if (level.NextSecretMap.Len() > 0 && level.NextSecretMap.Compare("enDSeQ", 6)) { G_DeferedInitNew(level.NextSecretMap); diff --git a/src/c_console.cpp b/src/c_console.cpp index e3e3d98fe..3be72d953 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -856,11 +856,10 @@ void C_DrawConsole (bool hw2d) } else if (ConBottom) { - int visheight, realheight; + int visheight; FTexture *conpic = TexMan[conback]; visheight = ConBottom; - realheight = (visheight * conpic->GetHeight()) / SCREENHEIGHT; screen->DrawTexture (conpic, 0, visheight - screen->GetHeight(), DTA_DestWidth, screen->GetWidth(), diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index c770bcbcf..2c6510219 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -475,39 +475,32 @@ UCVarValue FBaseCVar::FromString (const char *value, ECVarType type) // 0 1 2 3 ret.pGUID = NULL; - for (i = 0; i < 38; ++i) + if (value == NULL) + { + break; + } + for (i = 0; value[i] != 0 && i < 38; i++) { - if (value[i] == 0) - { - break; - } - bool goodv = true; switch (i) { case 0: if (value[i] != '{') - goodv = false; - break; + break; case 9: case 14: case 19: case 24: if (value[i] != '-') - goodv = false; - break; + break; case 37: if (value[i] != '}') - goodv = false; - break; + break; default: if (value[i] < '0' || (value[i] > '9' && value[i] < 'A') || (value[i] > 'F' && value[i] < 'a') || value[i] > 'f') - { - goodv = false; - } - break; + break; } } if (i == 38 && value[i] == 0) @@ -1673,9 +1666,6 @@ void FBaseCVar::ListVars (const char *filter, bool plain) if (CheckWildcards (filter, var->GetName())) { DWORD flags = var->GetFlags(); - UCVarValue val; - - val = var->GetGenericRep (CVAR_String); if (plain) { // plain formatting does not include user-defined cvars if (!(flags & CVAR_UNSETTABLE)) @@ -1698,7 +1688,7 @@ void FBaseCVar::ListVars (const char *filter, bool plain) flags & CVAR_MOD ? 'M' : ' ', flags & CVAR_IGNORE ? 'X' : ' ', var->GetName(), - var->GetGenericRep (CVAR_String).String); + var->GetGenericRep(CVAR_String).String); } } var = var->m_Next; diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 06bcf6b58..6a526a661 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -1336,7 +1336,7 @@ CCMD (alias) } else { - alias = new FConsoleAlias (argv[1], argv[2], ParsingKeyConf); + new FConsoleAlias (argv[1], argv[2], ParsingKeyConf); } } } diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 8a4341b76..da4ab4945 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -109,6 +109,7 @@ static FCompatOption Options[] = { "rebuildnodes", BCOMPATF_REBUILDNODES, SLOT_BCOMPAT }, { "linkfrozenprops", BCOMPATF_LINKFROZENPROPS, SLOT_BCOMPAT }, { "disablepushwindowcheck", BCOMPATF_NOWINDOWCHECK, SLOT_BCOMPAT }, + { "floatbob", BCOMPATF_FLOATBOB, SLOT_BCOMPAT }, // list copied from g_mapinfo.cpp { "shorttex", COMPATF_SHORTTEX, SLOT_COMPAT }, @@ -434,6 +435,11 @@ void CheckCompatibility(MapData *map) // Reset i_compatflags compatflags.Callback(); compatflags2.Callback(); + // Set floatbob compatibility for all maps with an original Hexen MAPINFO. + if (level.flags2 & LEVEL2_HEXENHACK) + { + ib_compatflags |= BCOMPATF_FLOATBOB; + } } //========================================================================== @@ -448,7 +454,7 @@ void SetCompatibilityParams() { unsigned i = ii_compatparams; - while (CompatParams[i] != CP_END && i < CompatParams.Size()) + while (i < CompatParams.Size() && CompatParams[i] != CP_END) { switch (CompatParams[i]) { diff --git a/src/configfile.cpp b/src/configfile.cpp index b8e37d91c..177c019fb 100644 --- a/src/configfile.cpp +++ b/src/configfile.cpp @@ -836,7 +836,7 @@ const char *FConfigFile::GenerateEndTag(const char *value) for (int i = 0; i < 5; ++i) { - DWORD three_bytes = (rand_bytes[i*3] << 16) | (rand_bytes[i*3+1] << 8) | (rand_bytes[i*3+2]); + //DWORD three_bytes = (rand_bytes[i*3] << 16) | (rand_bytes[i*3+1] << 8) | (rand_bytes[i*3+2]); // ??? EndTag[4+i*4 ] = Base64Table[rand_bytes[i*3] >> 2]; EndTag[4+i*4+1] = Base64Table[((rand_bytes[i*3] & 3) << 4) | (rand_bytes[i*3+1] >> 4)]; EndTag[4+i*4+2] = Base64Table[((rand_bytes[i*3+1] & 15) << 2) | (rand_bytes[i*3+2] >> 6)]; diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 9c7ca796a..9d7bcd6b5 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2244,24 +2244,25 @@ static int PatchText (int oldSize) } } - if (!good) - { - // Search through most other texts - const char *str; - str = EnglishStrings->MatchString (oldStr); + // Search through most other texts + const char *str; + do + { + str = EnglishStrings->MatchString(oldStr); if (str != NULL) { - GStrings.SetString (str, newStr); + GStrings.SetString(str, newStr); + EnglishStrings->SetString(str, "~~"); // set to something invalid so that it won't get found again by the next iteration or by another replacement later good = true; } + } + while (str != NULL); // repeat search until the text can no longer be found - if (!good) - { - DPrintf (" (Unmatched)\n"); - } + if (!good) + { + DPrintf (" (Unmatched)\n"); } - donewithtext: if (newStr) delete[] newStr; diff --git a/src/d_net.cpp b/src/d_net.cpp index 71d99a966..6445e5b93 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -107,7 +107,7 @@ int resendcount[MAXNETNODES]; unsigned int lastrecvtime[MAXPLAYERS]; // [RH] Used for pings unsigned int currrecvtime[MAXPLAYERS]; -unsigned int lastglobalrecvtime; // Identify the last time a packet was recieved. +unsigned int lastglobalrecvtime; // Identify the last time a packet was received. bool hadlate; int netdelay[MAXNETNODES][BACKUPTICS]; // Used for storing network delay times. int lastaverage; @@ -1861,7 +1861,7 @@ void TryRunTics (void) if (counts == 0 && !doWait) { // Check possible stall conditions - Net_CheckLastRecieved(counts); + Net_CheckLastReceived(counts); if (realtics >= 1) { C_Ticker(); @@ -1897,7 +1897,7 @@ void TryRunTics (void) I_Error ("TryRunTics: lowtic < gametic"); // Check possible stall conditions - Net_CheckLastRecieved (counts); + Net_CheckLastReceived (counts); // don't stay in here forever -- give the menu a chance to work if (I_GetTime (false) - entertic >= 1) @@ -1945,9 +1945,9 @@ void TryRunTics (void) } } -void Net_CheckLastRecieved (int counts) +void Net_CheckLastReceived (int counts) { - // [Ed850] Check to see the last time a packet was recieved. + // [Ed850] Check to see the last time a packet was received. // If it's longer then 3 seconds, a node has likely stalled. if (I_GetTime(false) - lastglobalrecvtime >= TICRATE * 3) { @@ -1974,11 +1974,11 @@ void Net_CheckLastRecieved (int counts) } else { //Send a resend request to the Arbitrator, as it's obvious we are stuck here. - if (debugfile && !players[playerfornode[Net_Arbitrator]].waiting) + if (debugfile && !players[Net_Arbitrator].waiting) fprintf(debugfile, "Arbitrator is slow (%i to %i)\n", - nettics[Net_Arbitrator], gametic + counts); + nettics[nodeforplayer[Net_Arbitrator]], gametic + counts); //Send resend request to the Arbitrator. Also mark the Arbitrator as waiting to display it in the hud. - remoteresend[Net_Arbitrator] = players[playerfornode[Net_Arbitrator]].waiting = hadlate = true; + remoteresend[nodeforplayer[Net_Arbitrator]] = players[Net_Arbitrator].waiting = hadlate = true; } } } @@ -2048,14 +2048,14 @@ void FDynamicBuffer::SetData (const BYTE *data, int len) m_BufferLen = (len + 255) & ~255; m_Data = (BYTE *)M_Realloc (m_Data, m_BufferLen); } - if (data) + if (data != NULL) { m_Len = len; memcpy (m_Data, data, len); } - else + else { - len = 0; + m_Len = 0; } } @@ -2668,7 +2668,9 @@ void Net_SkipCommand (int type, BYTE **stream) case DEM_SUMMONFOE2: skip = strlen ((char *)(*stream)) + 26; break; - + case DEM_CHANGEMAP2: + skip = strlen((char *)(*stream + 1)) + 2; + break; case DEM_MUSICCHANGE: case DEM_PRINT: case DEM_CENTERPRINT: diff --git a/src/d_net.h b/src/d_net.h index 07921a301..f9c4f6106 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -115,7 +115,7 @@ void D_QuitNetGame (void); void TryRunTics (void); //Use for checking to see if the netgame has stalled -void Net_CheckLastRecieved(int); +void Net_CheckLastReceived(int); // [RH] Functions for making and using special "ticcmds" void Net_NewMakeTic (); diff --git a/src/d_protocol.cpp b/src/d_protocol.cpp index 11e682cda..3613f84db 100644 --- a/src/d_protocol.cpp +++ b/src/d_protocol.cpp @@ -500,5 +500,5 @@ void SkipChunk (BYTE **stream) int len; len = ReadLong (stream); - stream += len + (len & 1); + *stream += len + (len & 1); } diff --git a/src/decallib.cpp b/src/decallib.cpp index 1bfe5142c..454f54ea5 100644 --- a/src/decallib.cpp +++ b/src/decallib.cpp @@ -443,7 +443,6 @@ void FDecalLib::ParseDecal (FScanner &sc) FString decalName; WORD decalNum; FDecalTemplate newdecal; - int code; FTextureID picnum; int lumpnum; @@ -467,7 +466,7 @@ void FDecalLib::ParseDecal (FScanner &sc) AddDecal (decalName, decalNum, newdecal); break; } - switch ((code = sc.MustMatchString (DecalKeywords))) + switch (sc.MustMatchString (DecalKeywords)) { case DECAL_XSCALE: newdecal.ScaleX = ReadScale (sc); @@ -763,8 +762,7 @@ void FDecalLib::ParseSlider (FScanner &sc) } else if (sc.Compare ("DistX")) { - sc.MustGetFloat (); - distX = (fixed_t)(sc.Float * FRACUNIT); + sc.MustGetFloat (); // must remain to avoid breaking definitions that accidentally used DistX Printf ("DistX in slider decal %s is unsupported\n", sliderName.GetChars()); } else if (sc.Compare ("DistY")) diff --git a/src/doomdef.h b/src/doomdef.h index 767f97661..c8aa66c17 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -354,6 +354,7 @@ enum BCOMPATF_REBUILDNODES = 1 << 5, // Force node rebuild BCOMPATF_LINKFROZENPROPS = 1 << 6, // Clearing PROP_TOTALLYFROZEN or PROP_FROZEN also clears the other BCOMPATF_NOWINDOWCHECK = 1 << 7, // Disable the window check in CheckForPushSpecial() + BCOMPATF_FLOATBOB = 1 << 8, // Use Hexen's original method of preventing floatbobbing items from falling down }; // phares 3/20/98: diff --git a/src/files.cpp b/src/files.cpp index d7dad642e..52aa891c9 100644 --- a/src/files.cpp +++ b/src/files.cpp @@ -53,7 +53,7 @@ //========================================================================== FileReader::FileReader () -: File(NULL), Length(0), StartPos(0), CloseOnDestruct(false) +: File(NULL), Length(0), StartPos(0), FilePos(0), CloseOnDestruct(false) { } diff --git a/src/g_game.cpp b/src/g_game.cpp index d704d9873..68f9fff87 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2592,6 +2592,12 @@ bool G_ProcessIFFDemo (FString &mapname) demo_p = nextchunk; } + if (!headerHit) + { + Printf ("Demo has no header!\n"); + return true; + } + if (!numPlayers) { Printf ("Demo has no players!\n"); diff --git a/src/g_heretic/a_hereticartifacts.cpp b/src/g_heretic/a_hereticartifacts.cpp index f9886b689..17d7f65ef 100644 --- a/src/g_heretic/a_hereticartifacts.cpp +++ b/src/g_heretic/a_hereticartifacts.cpp @@ -50,6 +50,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_TimeBomb) PARAM_ACTION_PROLOGUE; self->z += 32*FRACUNIT; + self->PrevZ = self->z; // no interpolation! self->RenderStyle = STYLE_Add; self->alpha = FRACUNIT; P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE); diff --git a/src/g_level.cpp b/src/g_level.cpp index 713847b05..2d44bfc27 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -367,7 +367,6 @@ static void InitPlayerClasses () void G_InitNew (const char *mapname, bool bTitleLevel) { - EGameSpeed oldSpeed; bool wantFast; int i; @@ -454,7 +453,6 @@ void G_InitNew (const char *mapname, bool bTitleLevel) I_Error ("Could not find map %s\n", mapname); } - oldSpeed = GameSpeed; wantFast = !!G_SkillProperty(SKILLP_FastMonsters); GameSpeed = wantFast ? SPEED_Fast : SPEED_Normal; @@ -1237,15 +1235,6 @@ void G_FinishTravel () pawn->AddToHash (); pawn->SetState(pawn->SpawnState); pawn->player->SendPitchLimits(); - // Sync the FLY flags. - if (pawn->flags2 & MF2_FLY) - { - pawn->player->cheats |= CF_FLY; - } - else - { - pawn->player->cheats &= ~CF_FLY; - } for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory) { diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 783e51a99..554c7be18 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -705,8 +705,6 @@ void FMapInfoParser::ParseCluster() } else if (sc.Compare("music")) { - int order = 0; - ParseAssign(); ParseMusic(clusterinfo->MessageMusic, clusterinfo->musicorder); } diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 4fe0c7086..2a398e750 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -997,7 +997,8 @@ void APowerFlight::EndEffect () { return; } - if (!(Owner->player->cheats & CF_FLY)) + + if (!(Owner->flags7 & MF7_FLYCHEAT)) { if (Owner->z != Owner->floorz) { diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index c3a227b36..5cce4c371 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -33,8 +33,8 @@ DEarthquake::DEarthquake() // //========================================================================== -DEarthquake::DEarthquake (AActor *center, int intensity, int duration, - int damrad, int tremrad, FSoundID quakesound) +DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int intensityZ, int duration, + int damrad, int tremrad, FSoundID quakesound, int flags) : DThinker(STAT_EARTHQUAKE) { m_QuakeSFX = quakesound; @@ -42,8 +42,12 @@ DEarthquake::DEarthquake (AActor *center, int intensity, int duration, // Radii are specified in tile units (64 pixels) m_DamageRadius = damrad << (FRACBITS); m_TremorRadius = tremrad << (FRACBITS); - m_Intensity = intensity; + m_IntensityX = intensityX; + m_IntensityY = intensityY; + m_IntensityZ = intensityZ; + m_CountdownStart = (double)duration; m_Countdown = duration; + m_Flags = flags; } //========================================================================== @@ -55,9 +59,27 @@ DEarthquake::DEarthquake (AActor *center, int intensity, int duration, void DEarthquake::Serialize (FArchive &arc) { Super::Serialize (arc); - arc << m_Spot << m_Intensity << m_Countdown + arc << m_Spot << m_IntensityX << m_Countdown << m_TremorRadius << m_DamageRadius << m_QuakeSFX; + if (SaveVersion < 4519) + { + m_IntensityY = m_IntensityX; + m_IntensityZ = 0; + m_Flags = 0; + } + else + { + arc << m_IntensityY << m_IntensityZ << m_Flags; + } + if (SaveVersion < 4520) + { + m_CountdownStart = 0; + } + else + { + arc << m_CountdownStart; + } } //========================================================================== @@ -78,7 +100,7 @@ void DEarthquake::Tick () Destroy (); return; } - + if (!S_IsActorPlayingSomething (m_Spot, CHAN_BODY, m_QuakeSFX)) { S_Sound (m_Spot, CHAN_BODY | CHAN_LOOP, m_QuakeSFX, 1, ATTN_NORM); @@ -102,11 +124,23 @@ void DEarthquake::Tick () } // Thrust player around angle_t an = victim->angle + ANGLE_1*pr_quake(); - P_ThrustMobj (victim, an, m_Intensity << (FRACBITS-1)); + if (m_IntensityX == m_IntensityY) + { // Thrust in a circle + P_ThrustMobj (victim, an, m_IntensityX << (FRACBITS-1)); + } + else + { // Thrust in an ellipse + an >>= ANGLETOFINESHIFT; + // So this is actually completely wrong, but it ought to be good + // enough. Otherwise, I'd have to use tangents and square roots. + victim->velx += FixedMul(m_IntensityX << (FRACBITS-1), finecosine[an]); + victim->vely += FixedMul(m_IntensityY << (FRACBITS-1), finesine[an]); + } } } } } + if (--m_Countdown == 0) { if (S_IsActorPlayingSomething(m_Spot, CHAN_BODY, m_QuakeSFX)) @@ -126,16 +160,18 @@ void DEarthquake::Tick () // //========================================================================== -int DEarthquake::StaticGetQuakeIntensity (AActor *victim) +int DEarthquake::StaticGetQuakeIntensities(AActor *victim, quakeInfo &qprop) { - int intensity = 0; - TThinkerIterator iterator (STAT_EARTHQUAKE); - DEarthquake *quake; - if (victim->player != NULL && (victim->player->cheats & CF_NOCLIP)) { return 0; } + qprop.isScalingDown = qprop.isScalingUp = qprop.preferMaximum = qprop.fullIntensity = false; + qprop.intensityX = qprop.intensityY = qprop.intensityZ = qprop.relIntensityX = qprop.relIntensityY = qprop.relIntensityZ = 0; + + TThinkerIterator iterator(STAT_EARTHQUAKE); + DEarthquake *quake; + int count = 0; while ( (quake = iterator.Next()) != NULL) { @@ -145,12 +181,36 @@ int DEarthquake::StaticGetQuakeIntensity (AActor *victim) victim->y - quake->m_Spot->y); if (dist < quake->m_TremorRadius) { - if (intensity < quake->m_Intensity) - intensity = quake->m_Intensity; + ++count; + if (quake->m_Flags & QF_RELATIVE) + { + qprop.relIntensityX = MAX(qprop.relIntensityX, quake->m_IntensityX); + qprop.relIntensityY = MAX(qprop.relIntensityY, quake->m_IntensityY); + qprop.relIntensityZ = MAX(qprop.relIntensityZ, quake->m_IntensityZ); + } + else + { + qprop.intensityX = MAX(qprop.intensityX, quake->m_IntensityX); + qprop.intensityY = MAX(qprop.intensityY, quake->m_IntensityY); + qprop.intensityZ = MAX(qprop.intensityZ, quake->m_IntensityZ); + } + if (quake->m_Flags) + { + qprop.scaleDownStart = quake->m_CountdownStart; + qprop.scaleDown = quake->m_Countdown; + qprop.isScalingDown = (quake->m_Flags & QF_SCALEDOWN) ? true : false; + qprop.isScalingUp = (quake->m_Flags & QF_SCALEUP) ? true : false; + qprop.preferMaximum = (quake->m_Flags & QF_MAX) ? true : false; + qprop.fullIntensity = (quake->m_Flags & QF_FULLINTENSITY) ? true : false; + } + else + { + qprop.scaleDownStart = qprop.scaleDown = 0.0; + } } } } - return intensity; + return count; } //========================================================================== @@ -159,18 +219,20 @@ int DEarthquake::StaticGetQuakeIntensity (AActor *victim) // //========================================================================== -bool P_StartQuake (AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx) +bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags) { AActor *center; bool res = false; - intensity = clamp (intensity, 1, 9); + if (intensityX) intensityX = clamp(intensityX, 1, 9); + if (intensityY) intensityY = clamp(intensityY, 1, 9); + if (intensityZ) intensityZ = clamp(intensityZ, 1, 9); if (tid == 0) { if (activator != NULL) { - new DEarthquake(activator, intensity, duration, damrad, tremrad, quakesfx); + new DEarthquake(activator, intensityX, intensityY, intensityZ, duration, damrad, tremrad, quakesfx, flags); return true; } } @@ -180,9 +242,14 @@ bool P_StartQuake (AActor *activator, int tid, int intensity, int duration, int while ( (center = iterator.Next ()) ) { res = true; - new DEarthquake (center, intensity, duration, damrad, tremrad, quakesfx); + new DEarthquake(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad, quakesfx, flags); } } return res; } + +bool P_StartQuake(AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx) +{ //Maintains original behavior by passing 0 to intensityZ, and flags. + return P_StartQuakeXYZ(activator, tid, intensity, intensity, 0, duration, damrad, tremrad, quakesfx, 0); +} diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 1fe70c4b4..649fcfa93 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -131,23 +131,40 @@ protected: DFlashFader (); }; +enum +{ + QF_RELATIVE = 1, + QF_SCALEDOWN = 1 << 1, + QF_SCALEUP = 1 << 2, + QF_MAX = 1 << 3, + QF_FULLINTENSITY = 1 << 4, +}; + +struct quakeInfo +{ + int intensityX, intensityY, intensityZ, relIntensityX, relIntensityY, relIntensityZ; + double scaleDown, scaleDownStart; + bool isScalingDown, isScalingUp, preferMaximum, fullIntensity; +}; + class DEarthquake : public DThinker { DECLARE_CLASS (DEarthquake, DThinker) HAS_OBJECT_POINTERS public: - DEarthquake (AActor *center, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx); + DEarthquake(AActor *center, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags); void Serialize (FArchive &arc); void Tick (); - TObjPtr m_Spot; fixed_t m_TremorRadius, m_DamageRadius; - int m_Intensity; int m_Countdown; + double m_CountdownStart; FSoundID m_QuakeSFX; + int m_Flags; + int m_IntensityX, m_IntensityY, m_IntensityZ; - static int StaticGetQuakeIntensity (AActor *viewer); + static int StaticGetQuakeIntensities(AActor *viewer, quakeInfo &qprop); private: DEarthquake (); diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 5e96ab130..6f3c44612 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -73,6 +73,7 @@ CVAR (Bool, hud_showitems, false,CVAR_ARCHIVE); // Show item stats on HUD CVAR (Bool, hud_showstats, false, CVAR_ARCHIVE); // for stamina and accuracy. CVAR (Bool, hud_showscore, false, CVAR_ARCHIVE); // for user maintained score CVAR (Bool, hud_showweapons, true, CVAR_ARCHIVE); // Show weapons collected +CVAR (Int , hud_showammo, 2, CVAR_ARCHIVE); // Show ammo collected CVAR (Int , hud_showtime, 0, CVAR_ARCHIVE); // Show time on HUD CVAR (Int , hud_timecolor, CR_GOLD,CVAR_ARCHIVE); // Color of in-game time on HUD CVAR (Int , hud_showlag, 0, CVAR_ARCHIVE); // Show input latency (maketic - gametic difference) @@ -546,23 +547,37 @@ static int DrawAmmo(player_t *CPlayer, int x, int y) orderedammos.Clear(); - // Order ammo by use of weapons in the weapon slots - // Do not check for actual presence in the inventory! - // We want to show all ammo types that can be used by - // the weapons in the weapon slots. - for (k = 0; k < NUM_WEAPON_SLOTS; k++) for(j = 0; j < CPlayer->weapons.Slots[k].Size(); j++) + if (0 == hud_showammo) { - const PClass *weap = CPlayer->weapons.Slots[k].GetWeapon(j); - - if (weap) AddAmmoToList((AWeapon*)GetDefaultByType(weap)); + // Show ammo for current weapon if any + if (wi) AddAmmoToList(wi); } - - // Now check for the remaining weapons that are in the inventory but not in the weapon slots - for(inv=CPlayer->mo->Inventory;inv;inv=inv->Inventory) + else { - if (inv->IsKindOf(RUNTIME_CLASS(AWeapon))) + // Order ammo by use of weapons in the weapon slots + for (k = 0; k < NUM_WEAPON_SLOTS; k++) for(j = 0; j < CPlayer->weapons.Slots[k].Size(); j++) { - AddAmmoToList((AWeapon*)inv); + PClassActor *weap = CPlayer->weapons.Slots[k].GetWeapon(j); + + if (weap) + { + // Show ammo for available weapons if hud_showammo CVAR is 1 + // or show ammo for all weapons if hud_showammo is greater than 1 + + if (hud_showammo > 1 || CPlayer->mo->FindInventory(weap)) + { + AddAmmoToList((AWeapon*)GetDefaultByType(weap)); + } + } + } + + // Now check for the remaining weapons that are in the inventory but not in the weapon slots + for(inv=CPlayer->mo->Inventory;inv;inv=inv->Inventory) + { + if (inv->IsKindOf(RUNTIME_CLASS(AWeapon))) + { + AddAmmoToList((AWeapon*)inv); + } } } diff --git a/src/i_net.cpp b/src/i_net.cpp index 188d2871e..d3958e1e1 100644 --- a/src/i_net.cpp +++ b/src/i_net.cpp @@ -800,7 +800,6 @@ bool Guest_WaitForOthers (void *userdata) { int node; - packet.NumNodes = packet.NumNodes; doomcom.numnodes = packet.NumNodes + 2; sendplayer[0] = packet.ConsoleNum; // My player number doomcom.consoleplayer = packet.ConsoleNum; diff --git a/src/info.cpp b/src/info.cpp index 33461bb77..a02e5a3ec 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -350,7 +350,6 @@ void PClassActor::InitializeNativeDefaults() void PClassActor::RegisterIDs() { PClassActor *cls = PClass::FindActor(TypeName); - bool set = false; if (cls == NULL) { @@ -723,17 +722,17 @@ CCMD (summonfoe) TMap GlobalDamageDefinitions; -void DamageTypeDefinition::Apply(FName const type) +void DamageTypeDefinition::Apply(FName type) { GlobalDamageDefinitions[type] = *this; } -DamageTypeDefinition *DamageTypeDefinition::Get(FName const type) +DamageTypeDefinition *DamageTypeDefinition::Get(FName type) { return GlobalDamageDefinitions.CheckKey(type); } -bool DamageTypeDefinition::IgnoreArmor(FName const type) +bool DamageTypeDefinition::IgnoreArmor(FName type) { DamageTypeDefinition *dtd = Get(type); if (dtd) return dtd->NoArmor; @@ -755,7 +754,7 @@ bool DamageTypeDefinition::IgnoreArmor(FName const type) // //========================================================================== -int DamageTypeDefinition::ApplyMobjDamageFactor(int damage, FName const type, DmgFactors const * const factors) +int DamageTypeDefinition::ApplyMobjDamageFactor(int damage, FName type, DmgFactors const * const factors) { if (factors) { diff --git a/src/info.h b/src/info.h index 4b63bd475..c211b936b 100644 --- a/src/info.h +++ b/src/info.h @@ -171,7 +171,7 @@ public: bool ReplaceFactor; bool NoArmor; - void Apply(FName const type); + void Apply(FName type); void Clear() { DefaultFactor = FRACUNIT; @@ -179,9 +179,9 @@ public: NoArmor = false; } - static DamageTypeDefinition *Get(FName const type); - static bool IgnoreArmor(FName const type); - static int ApplyMobjDamageFactor(int damage, FName const type, DmgFactors const * const factors); + static DamageTypeDefinition *Get(FName type); + static bool IgnoreArmor(FName type); + static int ApplyMobjDamageFactor(int damage, FName type, DmgFactors const * const factors); }; class DDropItem; diff --git a/src/m_argv.cpp b/src/m_argv.cpp index 816a2d54c..004f7857d 100644 --- a/src/m_argv.cpp +++ b/src/m_argv.cpp @@ -56,9 +56,8 @@ DArgs::DArgs() //=========================================================================== DArgs::DArgs(const DArgs &other) -: DObject() +: DObject(), Argv(other.Argv) { - Argv = other.Argv; } //=========================================================================== @@ -263,7 +262,6 @@ void DArgs::RemoveArgs(const char *check) const char *DArgs::GetArg(int arg) const { return ((unsigned)arg < Argv.Size()) ? Argv[arg].GetChars() : NULL; - return Argv[arg]; } //=========================================================================== @@ -351,7 +349,6 @@ void DArgs::RemoveArg(int argindex) void DArgs::CollectFiles(const char *param, const char *extension) { TArray work; - DArgs *out = new DArgs; unsigned int i; size_t extlen = extension == NULL ? 0 : strlen(extension); diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 762e5299e..60436719c 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -149,8 +149,7 @@ void cht_DoCheat (player_t *player, int cheat) case CHT_FLY: if (player->mo != NULL) { - player->cheats ^= CF_FLY; - if (player->cheats & CF_FLY) + if ((player->mo->flags7 ^= MF7_FLYCHEAT) != 0) { player->mo->flags |= MF_NOGRAVITY; player->mo->flags2 |= MF2_FLY; diff --git a/src/m_png.cpp b/src/m_png.cpp index 2bec48103..0c8b6ab18 100644 --- a/src/m_png.cpp +++ b/src/m_png.cpp @@ -1023,7 +1023,6 @@ bool M_SaveBitmap(const BYTE *from, ESSType color_type, int width, int height, i } } - y = sizeof(buffer) - stream.avail_out; deflateEnd (&stream); if (err != Z_STREAM_END) diff --git a/src/oplsynth/nukedopl3.cpp b/src/oplsynth/nukedopl3.cpp index a520f68e1..4d143f4a5 100644 --- a/src/oplsynth/nukedopl3.cpp +++ b/src/oplsynth/nukedopl3.cpp @@ -98,8 +98,7 @@ Bit16s envelope_calcsin0(Bit16u phase, Bit16u envelope) { phase &= 0x3ff; Bit16u out = 0; Bit16u neg = 0; - if (phase & 0x200 && (phase & 0x1ff)) { - phase--; + if (phase & 0x200) { neg = ~0; } if (phase & 0x100) { @@ -154,8 +153,7 @@ Bit16s envelope_calcsin4(Bit16u phase, Bit16u envelope) { phase &= 0x3ff; Bit16u out = 0; Bit16u neg = 0; - if ((phase & 0x300) == 0x100 && (phase & 0xff)) { - phase--; + if ((phase & 0x300) == 0x100) { neg = ~0; } if (phase & 0x200) { @@ -188,8 +186,7 @@ Bit16s envelope_calcsin5(Bit16u phase, Bit16u envelope) { Bit16s envelope_calcsin6(Bit16u phase, Bit16u envelope) { phase &= 0x3ff; Bit16u neg = 0; - if (phase & 0x200 && (phase & 0x1ff)) { - phase--; + if (phase & 0x200) { neg = ~0; } return envelope_calcexp(envelope << 3) ^ neg; @@ -199,8 +196,7 @@ Bit16s envelope_calcsin7(Bit16u phase, Bit16u envelope) { phase &= 0x3ff; Bit16u out = 0; Bit16u neg = 0; - if (phase & 0x200 && (phase & 0x1ff)) { - phase--; + if (phase & 0x200) { neg = ~0; phase = (phase & 0x1ff) ^ 0x1ff; } @@ -976,4 +972,4 @@ NukedOPL3::NukedOPL3(bool stereo) { OPLEmul *NukedOPL3Create(bool stereo) { return new NukedOPL3(stereo); -} \ No newline at end of file +} diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index fc35409dc..58c2dbde7 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -488,7 +488,7 @@ void P_Recalculate3DFloors(sector_t * sector) // by the clipping code below. ffloors.Push(pick); } - else if (pick->flags&(FF_SWIMMABLE|FF_TRANSLUCENT) && pick->flags&FF_EXISTS) + else if ((pick->flags&(FF_SWIMMABLE|FF_TRANSLUCENT) || (!(pick->flags&(FF_ALLSIDES|FF_BOTHPLANES)))) && pick->flags&FF_EXISTS) { // We must check if this nonsolid segment gets clipped from the top by another 3D floor if (solid != NULL && solid_bottom < height) diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp index ac6d7aca7..7f934e2f5 100644 --- a/src/p_3dmidtex.cpp +++ b/src/p_3dmidtex.cpp @@ -223,11 +223,12 @@ bool P_GetMidTexturePosition(const line_t *line, int sideno, fixed_t *ptextop, f FTexture * tex= TexMan(texnum); if (!tex) return false; + fixed_t totalscale = FixedMul(side->GetTextureYScale(side_t::mid), tex->yScale); fixed_t y_offset = side->GetTextureYOffset(side_t::mid); - fixed_t textureheight = tex->GetScaledHeight() << FRACBITS; - if (tex->yScale != FRACUNIT && !tex->bWorldPanning) + fixed_t textureheight = tex->GetScaledHeight(totalscale) << FRACBITS; + if (totalscale != FRACUNIT && !tex->bWorldPanning) { - y_offset = FixedDiv(y_offset, tex->yScale); + y_offset = FixedDiv(y_offset, totalscale); } if(line->flags & ML_DONTPEGBOTTOM) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 28a536adb..d2b31609b 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -217,7 +217,7 @@ FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS]; // // When the string table needs to grow to hold more strings, a garbage // collection is first attempted to see if more room can be made to store -// strings without growing. A string is concidered in use if any value +// strings without growing. A string is considered in use if any value // in any of these variable blocks contains a valid ID in the global string // table: // * The active area of the ACS stack @@ -226,7 +226,7 @@ FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS]; // * All world variables // * All global variables // It's not important whether or not they are really used as strings, only -// that they might be. A string is also concidered in use if its lock count +// that they might be. A string is also considered in use if its lock count // is non-zero, even if none of the above variable blocks referenced it. // // To keep track of local and map variables for nonresident maps in a hub, @@ -1066,14 +1066,7 @@ static void DoGiveInv (AActor *actor, PClassActor *info, int amount) item->ClearCounters(); if (info->IsDescendantOf (RUNTIME_CLASS(ABasicArmorPickup))) { - if (static_cast(item)->SaveAmount != 0) - { - static_cast(item)->SaveAmount *= amount; - } - else - { - static_cast(item)->SaveAmount *= amount; - } + static_cast(item)->SaveAmount *= amount; } else if (info->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus))) { @@ -2052,7 +2045,6 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) } } } - i += 4+ArrayStore[arraynum].ArraySize; } } @@ -5838,13 +5830,13 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) } FActorIterator iterator(args[0]); - bool canraiseall = false; + bool canraiseall = true; while ((actor = iterator.Next())) { - canraiseall = !P_Thing_CanRaise(actor) | canraiseall; + canraiseall = P_Thing_CanRaise(actor) & canraiseall; } - return !canraiseall; + return canraiseall; } break; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 920ff4330..13a66458d 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -670,33 +670,39 @@ bool P_TryWalk (AActor *actor) void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay) { - dirtype_t d[3]; + dirtype_t d[2]; int tdir; dirtype_t olddir, turnaround; + bool attempts[NUMDIRS-1]; // We don't need to attempt DI_NODIR. + memset(&attempts, false, sizeof(attempts)); olddir = (dirtype_t)actor->movedir; turnaround = opposite[olddir]; if (deltax>10*FRACUNIT) - d[1]= DI_EAST; + d[0]= DI_EAST; else if (deltax<-10*FRACUNIT) - d[1]= DI_WEST; + d[0]= DI_WEST; + else + d[0]=DI_NODIR; + + if (deltay<-10*FRACUNIT) + d[1]= DI_SOUTH; + else if (deltay>10*FRACUNIT) + d[1]= DI_NORTH; else d[1]=DI_NODIR; - if (deltay<-10*FRACUNIT) - d[2]= DI_SOUTH; - else if (deltay>10*FRACUNIT) - d[2]= DI_NORTH; - else - d[2]=DI_NODIR; - // try direct route - if (d[1] != DI_NODIR && d[2] != DI_NODIR) + if (d[0] != DI_NODIR && d[1] != DI_NODIR) { actor->movedir = diags[((deltay<0)<<1) + (deltax>0)]; - if (actor->movedir != turnaround && P_TryWalk(actor)) - return; + if (actor->movedir != turnaround) + { + attempts[actor->movedir] = true; + if (P_TryWalk(actor)) + return; + } } // try other directions @@ -704,18 +710,19 @@ void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay) { if ((pr_newchasedir() > 200 || abs(deltay) > abs(deltax))) { - swapvalues (d[1], d[2]); + swapvalues (d[0], d[1]); } + if (d[0] == turnaround) + d[0] = DI_NODIR; if (d[1] == turnaround) d[1] = DI_NODIR; - if (d[2] == turnaround) - d[2] = DI_NODIR; } - if (d[1] != DI_NODIR) + if (d[0] != DI_NODIR && attempts[d[0]] == false) { - actor->movedir = d[1]; + actor->movedir = d[0]; + attempts[d[0]] = true; if (P_TryWalk (actor)) { // either moved forward or attacked @@ -723,9 +730,10 @@ void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay) } } - if (d[2] != DI_NODIR) + if (d[1] != DI_NODIR && attempts[d[1]] == false) { - actor->movedir = d[2]; + actor->movedir = d[1]; + attempts[d[1]] = true; if (P_TryWalk (actor)) return; } @@ -733,9 +741,10 @@ void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay) if (!(actor->flags5 & MF5_AVOIDINGDROPOFF)) { // there is no direct path to the player, so pick another direction. - if (olddir != DI_NODIR) + if (olddir != DI_NODIR && attempts[olddir] == false) { actor->movedir = olddir; + attempts[olddir] = true; if (P_TryWalk (actor)) return; } @@ -746,9 +755,10 @@ void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay) { for (tdir = DI_EAST; tdir <= DI_SOUTHEAST; tdir++) { - if (tdir != turnaround) + if (tdir != turnaround && attempts[tdir] == false) { actor->movedir = tdir; + attempts[tdir] = true; if ( P_TryWalk(actor) ) return; } @@ -758,16 +768,17 @@ void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay) { for (tdir = DI_SOUTHEAST; tdir != (DI_EAST-1); tdir--) { - if (tdir != turnaround) + if (tdir != turnaround && attempts[tdir] == false) { actor->movedir = tdir; + attempts[tdir] = true; if ( P_TryWalk(actor) ) return; } } } - if (turnaround != DI_NODIR) + if (turnaround != DI_NODIR && attempts[turnaround] == false) { actor->movedir =turnaround; if ( P_TryWalk(actor) ) @@ -2545,8 +2556,6 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) // use the current actor's radius instead of the Arch Vile's default. fixed_t maxdist = corpsehit->GetDefault()->radius + self->radius; - maxdist = corpsehit->GetDefault()->radius + self->radius; - if (abs(corpsehit->x - viletryx) > maxdist || abs(corpsehit->y - viletryy) > maxdist) continue; // not actually touching @@ -2824,7 +2833,7 @@ void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch, a target_z = other->z + (other->height / 2) + other->GetBobOffset(); if (flags & FAF_TOP) target_z = other->z + (other->height) + other->GetBobOffset(); - if (!flags & FAF_NODISTFACTOR) + if (!(flags & FAF_NODISTFACTOR)) target_z += pitch_offset; double dist_z = target_z - source_z; diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 1a2e20b52..839e593c5 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -361,7 +361,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) if (debugfile && this->player) { - static int dieticks[MAXPLAYERS]; + static int dieticks[MAXPLAYERS]; // [ZzZombo] not used? Except if for peeking in debugger... int pnum = int(this->player-players); dieticks[pnum] = gametic; fprintf (debugfile, "died (%d) on tic %d (%s)\n", pnum, gametic, @@ -1711,14 +1711,12 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPainSound) { AActor *target; - AActor *inflictor; if (player == NULL) { return; } target = player->mo; - inflictor = source; if (target->health <= 0) { return; diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 6b865878f..54ab60337 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2800,7 +2800,7 @@ FUNC(LS_SetPlayerProperty) mask = CF_INSTANTWEAPSWITCH; break; case PROP_FLY: - mask = CF_FLY; + //mask = CF_FLY; break; case PROP_TOTALLYFROZEN: mask = CF_TOTALLYFROZEN; @@ -2814,6 +2814,7 @@ FUNC(LS_SetPlayerProperty) it->player->cheats |= mask; if (arg2 == PROP_FLY) { + it->flags7 |= MF7_FLYCHEAT; it->flags2 |= MF2_FLY; it->flags |= MF_NOGRAVITY; } @@ -2823,6 +2824,7 @@ FUNC(LS_SetPlayerProperty) it->player->cheats &= ~mask; if (arg2 == PROP_FLY) { + it->flags7 &= ~MF7_FLYCHEAT; it->flags2 &= ~MF2_FLY; it->flags &= ~MF_NOGRAVITY; } diff --git a/src/p_map.cpp b/src/p_map.cpp index 7357a63ac..7b640ea95 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -755,12 +755,14 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm) if (!(tm.thing->flags & MF_DROPOFF) && !(tm.thing->flags & (MF_NOGRAVITY | MF_NOCLIP))) { - secplane_t frontplane = ld->frontsector->floorplane; - secplane_t backplane = ld->backsector->floorplane; + secplane_t frontplane, backplane; #ifdef _3DFLOORS // Check 3D floors as well frontplane = P_FindFloorPlane(ld->frontsector, tm.thing->x, tm.thing->y, tm.thing->floorz); backplane = P_FindFloorPlane(ld->backsector, tm.thing->x, tm.thing->y, tm.thing->floorz); +#else + frontplane = ld->frontsector->floorplane; + backplane = ld->backsector->floorplane; #endif if (frontplane.c < STEEPSLOPE || backplane.c < STEEPSLOPE) { @@ -2964,7 +2966,6 @@ bool FSlide::BounceWall(AActor *mo) deltaangle = (2 * lineangle) - moveangle; mo->angle = deltaangle; - lineangle >>= ANGLETOFINESHIFT; deltaangle >>= ANGLETOFINESHIFT; movelen = fixed_t(sqrt(double(mo->velx)*mo->velx + double(mo->vely)*mo->vely)); @@ -3151,9 +3152,6 @@ bool aim_t::AimTraverse3DFloors(const divline_t &trace, intercept_t * in) fixed_t trY = trace.y + FixedMul(trace.dy, in->frac); fixed_t dist = FixedMul(attackrange, in->frac); - - int dir = aimpitch < 0 ? 1 : aimpitch > 0 ? -1 : 0; - frontflag = P_PointOnLineSide(shootthing->x, shootthing->y, li); // 3D floor check. This is not 100% accurate but normally sufficient when diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index d9323537f..24d4d009d 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2072,13 +2072,9 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { bool tg = (mo->target != NULL); bool blockingtg = (BlockingMobj->target != NULL); - if (BlockingMobj->flags7 & MF7_AIMREFLECT && (tg || blockingtg)) + if ((BlockingMobj->flags7 & MF7_AIMREFLECT) && (tg | blockingtg)) { - AActor *origin; - if (tg) - origin = mo->target; - else if (blockingtg) - origin = BlockingMobj->target; + AActor *origin = tg ? mo->target : BlockingMobj->target; float speed = (float)(mo->Speed); //dest->x - source->x @@ -2090,7 +2086,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) } else { - if (BlockingMobj->flags7 & MF7_MIRRORREFLECT && (tg || blockingtg)) + if ((BlockingMobj->flags7 & MF7_MIRRORREFLECT) && (tg | blockingtg)) { mo->angle += ANGLE_180; mo->velx = -mo->velx / 2; @@ -2413,6 +2409,16 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) } } + // Hexen compatibility handling for floatbobbing. Ugh... + // Hexen yanked all items to the floor, except those being spawned at map start in the air. + // Those were kept at their original height. + // Do this only if the item was actually spawned by the map above ground to avoid problems. + if (mo->special1 > 0 && (mo->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB)) + { + mo->z = mo->floorz + mo->special1; + } + + // // adjust height // @@ -2715,8 +2721,6 @@ void P_NightmareRespawn (AActor *mobj) z = ONCEILINGZ; else if (info->flags2 & MF2_SPAWNFLOAT) z = FLOATRANDZ; - else if (info->flags2 & MF2_FLOATBOB) - z = mobj->SpawnPoint[2]; else z = ONFLOORZ; @@ -3604,11 +3608,13 @@ void AActor::Tick () velz <= 0 && floorz == z) { - secplane_t floorplane = floorsector->floorplane; + secplane_t floorplane; #ifdef _3DFLOORS // Check 3D floors as well floorplane = P_FindFloorPlane(floorsector, x, y, floorz); +#else + floorplane = floorsector->floorplane; #endif if (floorplane.c < STEEPSLOPE && @@ -4587,7 +4593,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) p->mo->ResetAirSupply(false); p->Uncrouch(); p->MinPitch = p->MaxPitch = 0; // will be filled in by PostBeginPlay()/netcode - p->cheats &= ~CF_FLY; + p->velx = p->vely = 0; // killough 10/98: initialize bobbing to 0. @@ -4981,7 +4987,13 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj = AActor::StaticSpawn (i, x, y, z, NO_REPLACE, true); if (z == ONFLOORZ) + { mobj->z += mthing->z; + if ((mobj->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB)) + { + mobj->special1 = mthing->z; + } + } else if (z == ONCEILINGZ) mobj->z -= mthing->z; @@ -4994,7 +5006,11 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) else if (mthing->gravity > 0) mobj->gravity = FixedMul(mobj->gravity, mthing->gravity); else mobj->flags &= ~MF_NOGRAVITY; - P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); + // For Hexen floatbob 'compatibility' we do not really want to alter the floorz. + if (mobj->special1 == 0 || !(mobj->flags2 & MF2_FLOATBOB) || !(ib_compatflags & BCOMPATF_FLOATBOB)) + { + P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); + } if (!(mobj->flags2 & MF2_ARGSDEFINED)) { @@ -5743,18 +5759,31 @@ static fixed_t GetDefaultSpeed(PClassActor *type) AActor *P_SpawnMissile (AActor *source, AActor *dest, PClassActor *type, AActor *owner) { + if (source == NULL) + { + return NULL; + } return P_SpawnMissileXYZ (source->x, source->y, source->z + 32*FRACUNIT + source->GetBobOffset(), source, dest, type, true, owner); } AActor *P_SpawnMissileZ (AActor *source, fixed_t z, AActor *dest, PClassActor *type) { + if (source == NULL) + { + return NULL; + } return P_SpawnMissileXYZ (source->x, source->y, z, source, dest, type); } AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, AActor *source, AActor *dest, PClassActor *type, bool checkspawn, AActor *owner) { + if (source == NULL) + { + return NULL; + } + if (dest == NULL) { Printf ("P_SpawnMissilyXYZ: Tried to shoot %s from %s with no dest\n", @@ -5824,6 +5853,10 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, AActor *P_OldSpawnMissile(AActor *source, AActor *owner, AActor *dest, PClassActor *type) { + if (source == NULL) + { + return NULL; + } angle_t an; fixed_t dist; AActor *th = Spawn (type, source->x, source->y, source->z + 4*8*FRACUNIT, ALLOW_REPLACE); @@ -5865,6 +5898,10 @@ AActor *P_OldSpawnMissile(AActor *source, AActor *owner, AActor *dest, PClassAct AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, angle_t angle, fixed_t velz) { + if (source == NULL) + { + return NULL; + } return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT + source->GetBobOffset(), type, angle, velz, GetDefaultSpeed (type)); } @@ -5878,6 +5915,10 @@ AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z, AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassActor *type) { + if (source == NULL) + { + return NULL; + } angle_t an; fixed_t dist; fixed_t speed; @@ -5908,6 +5949,10 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassAct AActor *P_SpawnMissileAngleSpeed (AActor *source, PClassActor *type, angle_t angle, fixed_t velz, fixed_t speed) { + if (source == NULL) + { + return NULL; + } return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT + source->GetBobOffset(), type, angle, velz, speed); } @@ -5915,9 +5960,13 @@ AActor *P_SpawnMissileAngleSpeed (AActor *source, PClassActor *type, AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, PClassActor *type, angle_t angle, fixed_t velz, fixed_t speed, AActor *owner, bool checkspawn) { + if (source == NULL) + { + return NULL; + } AActor *mo; - if (z != ONFLOORZ && z != ONCEILINGZ && source != NULL) + if (z != ONFLOORZ && z != ONCEILINGZ) { z -= source->floorclip; } @@ -5952,6 +6001,10 @@ AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type) { + if (source == NULL) + { + return NULL; + } return P_SpawnPlayerMissile (source, 0, 0, 0, type, source->angle); } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index ec7bf7d98..9bd2b8cf7 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1362,7 +1362,7 @@ void P_LoadSegs (MapData * map) } } } - catch (badseg bad) + catch (const badseg &bad) // the preferred way is to catch by (const) reference. { switch (bad.badtype) { @@ -1467,7 +1467,6 @@ void P_LoadSubsectors (MapData * map) void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) { - char fname[9]; int i; char *msp; mapsector_t *ms; @@ -1486,7 +1485,6 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) defSeqType = -1; fogMap = normMap = NULL; - fname[8] = 0; msp = new char[lumplen]; map->Read(ML_SECTORS, msp); @@ -3041,15 +3039,12 @@ void P_LoadBlockMap (MapData * map) blockmap = blockmaplump+4; } - - // // P_GroupLines // Builds sector line lists and subsector sector numbers. // Finds block bounding boxes for sectors. // [RH] Handles extra lights // -struct linf { short tag; WORD count; }; line_t** linebuffer; static void P_GroupLines (bool buildmap) @@ -3059,7 +3054,6 @@ static void P_GroupLines (bool buildmap) int i; int j; int total; - int totallights; line_t* li; sector_t* sector; FBoundingBox bbox; @@ -3092,7 +3086,6 @@ static void P_GroupLines (bool buildmap) // count number of lines in each sector times[1].Clock(); total = 0; - totallights = 0; for (i = 0, li = lines; i < numlines; i++, li++) { if (li->frontsector == NULL) diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index af0ad7a20..2cce53a92 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -529,11 +529,9 @@ static void P_AlignPlane (sector_t *sec, line_t *line, int which) FVector3 p, v1, v2, cross; - const secplane_t *refplane; secplane_t *srcplane; fixed_t srcheight, destheight; - refplane = (which == 0) ? &refsec->floorplane : &refsec->ceilingplane; srcplane = (which == 0) ? &sec->floorplane : &sec->ceilingplane; srcheight = (which == 0) ? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); destheight = (which == 0) ? refsec->GetPlaneTexZ(sector_t::floor) : refsec->GetPlaneTexZ(sector_t::ceiling); diff --git a/src/p_spec.h b/src/p_spec.h index 7e717029a..544c7fa0a 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -929,6 +929,7 @@ void P_DoDeferedScripts (void); // // [RH] p_quake.c // -bool P_StartQuake (AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx); +bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags); +bool P_StartQuake(AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx); #endif diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 6493459ac..59265b198 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -187,8 +187,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, // Spawn teleport fog at source and destination if (sourceFog && !predicting) { - fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT; - P_SpawnTeleportFog(thing, oldx, oldy, oldz, true, true); //Passes the actor through which then pulls the TeleFog metadate types based on properties. + P_SpawnTeleportFog(thing, oldx, oldy, oldz, true, true); //Passes the actor through which then pulls the TeleFog metadata types based on properties. } if (useFog) { diff --git a/src/p_usdf.cpp b/src/p_usdf.cpp index 279f9b8c4..7bc6a90fa 100644 --- a/src/p_usdf.cpp +++ b/src/p_usdf.cpp @@ -131,7 +131,6 @@ class USDFParser : public UDMFParserBase while (!sc.CheckToken('}')) { bool block = false; - int costs = 0; FName key = ParseKey(true, &block); if (!block) { diff --git a/src/p_user.cpp b/src/p_user.cpp index 41924beb4..500787905 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1095,7 +1095,7 @@ void APlayerPawn::FilterCoopRespawnInventory (APlayerPawn *oldplayer) else if ((dmflags & DF_COOP_LOSE_ARMOR) && item->IsKindOf(RUNTIME_CLASS(AArmor))) { - if (defitem != NULL) + if (defitem == NULL) { item->Destroy(); } diff --git a/src/po_man.cpp b/src/po_man.cpp index bb9b3ca46..4a3345d5b 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -679,10 +679,6 @@ void DPolyDoor::Tick () if (m_Dist <= 0 || poly->RotatePolyobj (m_Speed)) { absSpeed = abs (m_Speed); - if (m_Dist == -1) - { // perpetual polyobj - return; - } m_Dist -= absSpeed; if (m_Dist <= 0) { diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 6572c1f0b..8c01a1c3e 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -438,7 +438,6 @@ void R_MapTiltedPlane (int y, int x1) } startu = endu; startv = endv; - startz = endz; width -= SPANSIZE; } if (width > 0) diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 17e1dffe2..2d41a1389 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -764,6 +764,52 @@ bool R_GetViewInterpolationStatus() return NoInterpolateView; } +//========================================================================== +// +// QuakePower +// +//========================================================================== + +static fixed_t QuakePower(double factor, int intensity, quakeInfo quake) +{ + double scaleDownStart = quake.scaleDownStart; + double scaleDown = quake.scaleDown; + if (intensity == 0) + { + return 0; + } + else + { + double ss = (double)((pr_torchflicker() % (intensity << 2)) - (intensity << 1)); + double mtp = (quake.fullIntensity) ? 2.0 : 1.0; + if (quake.isScalingDown || quake.isScalingUp) + { + fixed_t result; + if (scaleDownStart == 0) scaleDownStart = 1; + + if (quake.isScalingDown && quake.isScalingUp) + { + if (quake.preferMaximum) + result = FLOAT2FIXED((factor * ss) * MAX(((scaleDown*mtp) / scaleDownStart), ((scaleDownStart - scaleDown)*mtp) / scaleDownStart)); + else + result = FLOAT2FIXED((factor * ss) * MIN(((scaleDown*mtp) / scaleDownStart), ((scaleDownStart - scaleDown)*mtp) / scaleDownStart)); + } + else if (quake.isScalingDown) + result = FLOAT2FIXED((factor * ss) * (scaleDown / scaleDownStart)); + else if (quake.isScalingUp) + result = FLOAT2FIXED((factor * ss) * ((scaleDownStart - scaleDown) / scaleDownStart)); + else + result = FLOAT2FIXED(factor * ss); + + return result; + } + else + { + return FLOAT2FIXED(factor * ss); + } + } + +} //========================================================================== // @@ -875,13 +921,39 @@ void R_SetupFrame (AActor *actor) if (!paused) { - int intensity = DEarthquake::StaticGetQuakeIntensity (camera); - if (intensity != 0) + quakeInfo quake; + if (DEarthquake::StaticGetQuakeIntensities(camera, quake) > 0) { - fixed_t quakefactor = FLOAT2FIXED(r_quakeintensity); + double quakefactor = r_quakeintensity; - viewx += quakefactor * ((pr_torchflicker() % (intensity<<2)) - (intensity<<1)); - viewy += quakefactor * ((pr_torchflicker() % (intensity<<2)) - (intensity<<1)); + if (quake.relIntensityX != 0) + { + int ang = (camera->angle) >> ANGLETOFINESHIFT; + fixed_t power = QuakePower(quakefactor, quake.relIntensityX, quake); + viewx += FixedMul(finecosine[ang], power); + viewy += FixedMul(finesine[ang], power); + } + if (quake.relIntensityY != 0) + { + int ang = (camera->angle + ANG90) >> ANGLETOFINESHIFT; + fixed_t power = QuakePower(quakefactor, quake.relIntensityY, quake); + viewx += FixedMul(finecosine[ang], power); + viewy += FixedMul(finesine[ang], power); + } + if (quake.intensityX != 0) + { + viewx += QuakePower(quakefactor, quake.intensityX, quake); + } + if (quake.intensityY != 0) + { + viewy += QuakePower(quakefactor, quake.intensityY, quake); + } + // FIXME: Relative Z is not relative + quake.intensityZ = MAX(quake.intensityZ, quake.relIntensityZ); + if (quake.intensityZ != 0) + { + viewz += QuakePower(quakefactor, quake.intensityZ, quake); + } } } diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 483502692..f78e753d8 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -2993,3 +2993,23 @@ CCMD (cachesound) } } } + + +CCMD(listsoundchannels) +{ + FSoundChan *chan; + int count = 0; + for (chan = Channels; chan != NULL; chan = chan->NextChan) + { + if (!(chan->ChanFlags & CHAN_EVICTED)) + { + FVector3 chanorigin; + + CalcPosVel(chan, &chanorigin, NULL); + + Printf("%s at (%1.5f, %1.5f, %1.5f)\n", (const char*)chan->SoundID, chanorigin.X, chanorigin.Y, chanorigin.Z); + count++; + } + } + Printf("%d sounds playing\n", count); +} diff --git a/src/textures/textures.h b/src/textures/textures.h index 16fa4ef07..b5a999978 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -233,6 +233,7 @@ public: int GetScaledWidth () { int foo = (Width << 17) / xScale; return (foo >> 1) + (foo & 1); } int GetScaledHeight () { int foo = (Height << 17) / yScale; return (foo >> 1) + (foo & 1); } + int GetScaledHeight(fixed_t scale) { int foo = (Height << 17) / scale; return (foo >> 1) + (foo & 1); } double GetScaledWidthDouble () { return (Width * 65536.) / xScale; } double GetScaledHeightDouble () { return (Height * 65536.) / yScale; } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index c2d3c8505..59cd115dd 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2090,30 +2090,32 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_TakeFromSiblings) enum SIX_Flags { - SIXF_TRANSFERTRANSLATION = 1 << 0, - SIXF_ABSOLUTEPOSITION = 1 << 1, - SIXF_ABSOLUTEANGLE = 1 << 2, - SIXF_ABSOLUTEVELOCITY = 1 << 3, - SIXF_SETMASTER = 1 << 4, - SIXF_NOCHECKPOSITION = 1 << 5, - SIXF_TELEFRAG = 1 << 6, - SIXF_CLIENTSIDE = 1 << 7, // only used by Skulldronum - SIXF_TRANSFERAMBUSHFLAG = 1 << 8, - SIXF_TRANSFERPITCH = 1 << 9, - SIXF_TRANSFERPOINTERS = 1 << 10, - SIXF_USEBLOODCOLOR = 1 << 11, - SIXF_CLEARCALLERTID = 1 << 12, - SIXF_MULTIPLYSPEED = 1 << 13, - SIXF_TRANSFERSCALE = 1 << 14, - SIXF_TRANSFERSPECIAL = 1 << 15, - SIXF_CLEARCALLERSPECIAL = 1 << 16, - SIXF_TRANSFERSTENCILCOL = 1 << 17, - SIXF_TRANSFERALPHA = 1 << 18, - SIXF_TRANSFERRENDERSTYLE = 1 << 19, - SIXF_SETTARGET = 1 << 20, - SIXF_SETTRACER = 1 << 21, - SIXF_NOPOINTERS = 1 << 22, - SIXF_ORIGINATOR = 1 << 23, + SIXF_TRANSFERTRANSLATION = 0x00000001, + SIXF_ABSOLUTEPOSITION = 0x00000002, + SIXF_ABSOLUTEANGLE = 0x00000004, + SIXF_ABSOLUTEVELOCITY = 0x00000008, + SIXF_SETMASTER = 0x00000010, + SIXF_NOCHECKPOSITION = 0x00000020, + SIXF_TELEFRAG = 0x00000040, + SIXF_CLIENTSIDE = 0x00000080, // only used by Skulldronum + SIXF_TRANSFERAMBUSHFLAG = 0x00000100, + SIXF_TRANSFERPITCH = 0x00000200, + SIXF_TRANSFERPOINTERS = 0x00000400, + SIXF_USEBLOODCOLOR = 0x00000800, + SIXF_CLEARCALLERTID = 0x00001000, + SIXF_MULTIPLYSPEED = 0x00002000, + SIXF_TRANSFERSCALE = 0x00004000, + SIXF_TRANSFERSPECIAL = 0x00008000, + SIXF_CLEARCALLERSPECIAL = 0x00010000, + SIXF_TRANSFERSTENCILCOL = 0x00020000, + SIXF_TRANSFERALPHA = 0x00040000, + SIXF_TRANSFERRENDERSTYLE = 0x00080000, + SIXF_SETTARGET = 0x00100000, + SIXF_SETTRACER = 0x00200000, + SIXF_NOPOINTERS = 0x00400000, + SIXF_ORIGINATOR = 0x00800000, + SIXF_TRANSFERSPRITEFRAME = 0x01000000, + SIXF_TRANSFERROLL = 0x02000000, }; static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) @@ -2259,6 +2261,17 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) { mo->RenderStyle = self->RenderStyle; } + + if (flags & SIXF_TRANSFERSPRITEFRAME) + { + mo->sprite = self->sprite; + mo->frame = self->frame; + } + + if (flags & SIXF_TRANSFERROLL) + { + mo->roll = self->roll; + } return true; } @@ -4745,6 +4758,29 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Quake) return 0; } +//=========================================================================== +// +// A_QuakeEx +// +// Extended version of A_Quake. Takes individual axis into account and can +// take a flag. +//=========================================================================== + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_QuakeEx) +{ + PARAM_ACTION_PROLOGUE; + PARAM_INT(intensityX); + PARAM_INT(intensityY); + PARAM_INT(intensityZ); + PARAM_INT(duration); + PARAM_INT(damrad); + PARAM_INT(tremrad); + PARAM_SOUND_OPT (sound) { sound = "world/quake"; } + PARAM_INT_OPT(flags) { flags = 0; } + P_StartQuakeXYZ(self, 0, intensityX, intensityY, intensityZ, duration, damrad, tremrad, sound, flags); + return 0; +} + //=========================================================================== // // A_Weave diff --git a/src/thingdef/thingdef_exp.h b/src/thingdef/thingdef_exp.h index 1aac01c29..7277d48bb 100644 --- a/src/thingdef/thingdef_exp.h +++ b/src/thingdef/thingdef_exp.h @@ -191,6 +191,7 @@ class FxExpression { protected: FxExpression(const FScriptPosition &pos) + : ScriptPosition(pos) { isresolved = false; ScriptPosition = pos; diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 1061a1991..e8e3c2b67 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -1918,6 +1918,7 @@ FxExpression *FxAbs::Resolve(FCompileContext &ctx) case VAL_Float: value.Float = fabs(value.Float); + break; default: // shouldn't happen diff --git a/src/version.h b/src/version.h index 09b830438..794bdcec8 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4518 +#define SAVEVER 4520 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 61ce5e27a..2d2be4bbf 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -267,6 +267,7 @@ ACTOR Actor native //: Thinker action native A_SetUserArray(name varname, int index, int value); action native A_SetSpecial(int spec, int arg0 = 0, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0); action native A_Quake(int intensity, int duration, int damrad, int tremrad, sound sfx = "world/quake"); + action native A_QuakeEx(int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, sound sfx = "world/quake", int flags = 0); action native A_SetTics(int tics); action native A_SetDamageType(name damagetype); action native A_DropItem(class item, int dropamount = -1, int chance = 256); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 89a547617..27e461f3d 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -72,6 +72,8 @@ const int SXF_SETTARGET = 1 << 20; const int SXF_SETTRACER = 1 << 21; const int SXF_NOPOINTERS = 1 << 22; const int SXF_ORIGINATOR = 1 << 23; +const int SXF_TRANSFERSPRITEFRAME = 1 << 24; +const int SXF_TRANSFERROLL = 1 << 25; // Flags for A_Chase const int CHF_FASTCHASE = 1; @@ -456,3 +458,13 @@ enum FAF_NODISTFACTOR = 8, }; +// Flags for A_QuakeEx +enum +{ + QF_RELATIVE = 1, + QF_SCALEDOWN = 1 << 1, + QF_SCALEUP = 1 << 2, + QF_MAX = 1 << 3, + QF_FULLINTENSITY = 1 << 4, +}; + diff --git a/wadsrc/static/actors/heretic/hereticammo.txt b/wadsrc/static/actors/heretic/hereticammo.txt index 8f02cce0a..96a20352b 100644 --- a/wadsrc/static/actors/heretic/hereticammo.txt +++ b/wadsrc/static/actors/heretic/hereticammo.txt @@ -221,7 +221,6 @@ ACTOR BagOfHolding : BackpackItem 8 Inventory.PickupMessage "$TXT_ITEMBAGOFHOLDING" +COUNTITEM +FLOATBOB - +NOGRAVITY States { Spawn: diff --git a/wadsrc/static/actors/heretic/hereticarmor.txt b/wadsrc/static/actors/heretic/hereticarmor.txt index 40ca671da..e027f4f47 100644 --- a/wadsrc/static/actors/heretic/hereticarmor.txt +++ b/wadsrc/static/actors/heretic/hereticarmor.txt @@ -6,7 +6,6 @@ Actor SilverShield : BasicArmorPickup 85 Game Heretic SpawnID 68 +FLOATBOB - +NOGRAVITY Inventory.Pickupmessage "$TXT_ITEMSHIELD1" Inventory.Icon "SHLDA0" Armor.Savepercent 50 @@ -26,7 +25,6 @@ Actor EnchantedShield : BasicArmorPickup 31 Game Heretic SpawnID 69 +FLOATBOB - +NOGRAVITY Inventory.Pickupmessage "$TXT_ITEMSHIELD2" Inventory.Icon "SHD2A0" Armor.Savepercent 75 diff --git a/wadsrc/static/actors/heretic/hereticartifacts.txt b/wadsrc/static/actors/heretic/hereticartifacts.txt index 404e5ba39..67d3946b9 100644 --- a/wadsrc/static/actors/heretic/hereticartifacts.txt +++ b/wadsrc/static/actors/heretic/hereticartifacts.txt @@ -7,7 +7,6 @@ ACTOR SuperMap : MapRevealer 35 +COUNTITEM +INVENTORY.ALWAYSPICKUP +FLOATBOB - +NOGRAVITY Inventory.MaxAmount 0 Inventory.PickupMessage "$TXT_ITEMSUPERMAP" States @@ -27,7 +26,6 @@ ACTOR ArtiInvisibility : PowerupGiver 75 SpawnID 135 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.PICKUPFLASH RenderStyle Translucent Alpha 0.4 @@ -53,7 +51,6 @@ ACTOR ArtiTomeOfPower : PowerupGiver 86 native SpawnID 134 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.PICKUPFLASH Inventory.Icon "ARTIPWBK" Powerup.Type Weaponlevel2 @@ -97,7 +94,6 @@ ACTOR ArtiTimeBomb : Inventory 34 native SpawnID 72 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.PICKUPFLASH +INVENTORY.INVBAR +INVENTORY.FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/hexen/blastradius.txt b/wadsrc/static/actors/hexen/blastradius.txt index 28af3e698..ad98d7ecc 100644 --- a/wadsrc/static/actors/hexen/blastradius.txt +++ b/wadsrc/static/actors/hexen/blastradius.txt @@ -4,7 +4,6 @@ ACTOR ArtiBlastRadius : CustomInventory 10110 Game Hexen SpawnID 74 +FLOATBOB - +NOGRAVITY Inventory.DefMaxAmount Inventory.PickupFlash "PickupFlash" +INVBAR +FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/hexen/boostarmor.txt b/wadsrc/static/actors/hexen/boostarmor.txt index 8aa6b6eeb..607c8d66a 100644 --- a/wadsrc/static/actors/hexen/boostarmor.txt +++ b/wadsrc/static/actors/hexen/boostarmor.txt @@ -7,7 +7,6 @@ ACTOR ArtiBoostArmor : Inventory 8041 native SpawnID 22 +COUNTITEM +FLOATBOB - +NOGRAVITY Inventory.DefMaxAmount Inventory.PickupFlash "PickupFlash" +INVBAR +FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/hexen/clericholy.txt b/wadsrc/static/actors/hexen/clericholy.txt index cebc44610..e97be8b17 100644 --- a/wadsrc/static/actors/hexen/clericholy.txt +++ b/wadsrc/static/actors/hexen/clericholy.txt @@ -8,7 +8,6 @@ ACTOR ClericWeaponPiece : WeaponPiece Inventory.ForbiddenTo FighterPlayer, MagePlayer WeaponPiece.Weapon CWeapWraithverge +FLOATBOB - +NOGRAVITY } // Cleric Weapon Piece 1 ---------------------------------------------------- diff --git a/wadsrc/static/actors/hexen/fighterquietus.txt b/wadsrc/static/actors/hexen/fighterquietus.txt index b5ecd22e4..a77e851d8 100644 --- a/wadsrc/static/actors/hexen/fighterquietus.txt +++ b/wadsrc/static/actors/hexen/fighterquietus.txt @@ -8,7 +8,6 @@ ACTOR FighterWeaponPiece : WeaponPiece Inventory.ForbiddenTo ClericPlayer, MagePlayer WeaponPiece.Weapon FWeapQuietus +FLOATBOB - +NOGRAVITY } // Fighter Weapon Piece 1 --------------------------------------------------- diff --git a/wadsrc/static/actors/hexen/flechette.txt b/wadsrc/static/actors/hexen/flechette.txt index 74c7a0a6a..6e12bff53 100644 --- a/wadsrc/static/actors/hexen/flechette.txt +++ b/wadsrc/static/actors/hexen/flechette.txt @@ -99,7 +99,6 @@ ACTOR ArtiPoisonBag : Inventory 8000 native Game Hexen SpawnID 72 +FLOATBOB - +NOGRAVITY Inventory.DefMaxAmount Inventory.PickupFlash "PickupFlash" +INVBAR +FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/hexen/healingradius.txt b/wadsrc/static/actors/hexen/healingradius.txt index 97efc0449..e0556915b 100644 --- a/wadsrc/static/actors/hexen/healingradius.txt +++ b/wadsrc/static/actors/hexen/healingradius.txt @@ -6,7 +6,6 @@ ACTOR ArtiHealingRadius : Inventory 10120 native Game Hexen +COUNTITEM +FLOATBOB - +NOGRAVITY Inventory.DefMaxAmount +INVENTORY.INVBAR +INVENTORY.PICKUPFLASH diff --git a/wadsrc/static/actors/hexen/magestaff.txt b/wadsrc/static/actors/hexen/magestaff.txt index a8584aae7..aa75ed446 100644 --- a/wadsrc/static/actors/hexen/magestaff.txt +++ b/wadsrc/static/actors/hexen/magestaff.txt @@ -8,7 +8,6 @@ ACTOR MageWeaponPiece : WeaponPiece Inventory.ForbiddenTo FighterPlayer, ClericPlayer WeaponPiece.Weapon MWeapBloodscourge +FLOATBOB - +NOGRAVITY } // Mage Weapon Piece 1 ------------------------------------------------------ diff --git a/wadsrc/static/actors/hexen/mana.txt b/wadsrc/static/actors/hexen/mana.txt index 97bc419c8..a2e6ee4bc 100644 --- a/wadsrc/static/actors/hexen/mana.txt +++ b/wadsrc/static/actors/hexen/mana.txt @@ -11,7 +11,6 @@ ACTOR Mana1 : Ammo 122 Radius 8 Height 8 +FLOATBOB - +NOGRAVITY Inventory.Icon "MAN1I0" Inventory.PickupMessage "$TXT_MANA_1" States @@ -35,7 +34,6 @@ ACTOR Mana2 : Ammo 124 Radius 8 Height 8 +FLOATBOB - +NOGRAVITY Inventory.Icon "MAN2G0" Inventory.PickupMessage "$TXT_MANA_2" States @@ -55,7 +53,6 @@ ACTOR Mana3 : CustomInventory 8004 Radius 8 Height 8 +FLOATBOB - +NOGRAVITY Inventory.PickupMessage "$TXT_MANA_BOTH" States { diff --git a/wadsrc/static/actors/hexen/speedboots.txt b/wadsrc/static/actors/hexen/speedboots.txt index c22699b62..5fd6703b8 100644 --- a/wadsrc/static/actors/hexen/speedboots.txt +++ b/wadsrc/static/actors/hexen/speedboots.txt @@ -5,7 +5,6 @@ ACTOR ArtiSpeedBoots : PowerupGiver 8002 Game Hexen SpawnID 13 +FLOATBOB - +NOGRAVITY +COUNTITEM +INVENTORY.PICKUPFLASH Inventory.Icon ARTISPED diff --git a/wadsrc/static/actors/hexen/summon.txt b/wadsrc/static/actors/hexen/summon.txt index 28c3c3267..a4b3b8584 100644 --- a/wadsrc/static/actors/hexen/summon.txt +++ b/wadsrc/static/actors/hexen/summon.txt @@ -7,7 +7,6 @@ ACTOR ArtiDarkServant : Inventory 86 native SpawnID 16 +COUNTITEM +FLOATBOB - +NOGRAVITY Inventory.RespawnTics 4230 Inventory.DefMaxAmount Inventory.PickupFlash "PickupFlash" diff --git a/wadsrc/static/actors/hexen/teleportother.txt b/wadsrc/static/actors/hexen/teleportother.txt index 49b20a0bd..77a05f6af 100644 --- a/wadsrc/static/actors/hexen/teleportother.txt +++ b/wadsrc/static/actors/hexen/teleportother.txt @@ -7,7 +7,6 @@ ACTOR ArtiTeleportOther : Inventory 10040 native SpawnID 17 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.INVBAR +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/raven/artiegg.txt b/wadsrc/static/actors/raven/artiegg.txt index 2a9c6867e..d94f00151 100644 --- a/wadsrc/static/actors/raven/artiegg.txt +++ b/wadsrc/static/actors/raven/artiegg.txt @@ -31,7 +31,6 @@ ACTOR ArtiEgg : CustomInventory 30 SpawnID 14 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.INVBAR +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND @@ -86,7 +85,6 @@ ACTOR ArtiPork : CustomInventory 30 SpawnID 14 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.INVBAR +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/raven/artitele.txt b/wadsrc/static/actors/raven/artitele.txt index b0eedf1cd..79811fd53 100644 --- a/wadsrc/static/actors/raven/artitele.txt +++ b/wadsrc/static/actors/raven/artitele.txt @@ -7,7 +7,6 @@ ACTOR ArtiTeleport : Inventory 36 native SpawnID 18 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.INVBAR +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND diff --git a/wadsrc/static/actors/raven/ravenartifacts.txt b/wadsrc/static/actors/raven/ravenartifacts.txt index 4f31ad5fb..c02c19c3b 100644 --- a/wadsrc/static/actors/raven/ravenartifacts.txt +++ b/wadsrc/static/actors/raven/ravenartifacts.txt @@ -8,7 +8,6 @@ ACTOR ArtiHealth : HealthPickup 82 Health 25 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND Inventory.Icon ARTIPTN2 @@ -33,7 +32,6 @@ ACTOR ArtiSuperHealth : HealthPickup 32 Health 100 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.PICKUPFLASH +INVENTORY.FANCYPICKUPSOUND Inventory.Icon ARTISPHL @@ -57,7 +55,6 @@ ACTOR ArtiFly : PowerupGiver 83 SpawnID 15 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.PICKUPFLASH +INVENTORY.INTERHUBSTRIP Inventory.RespawnTics 4230 @@ -81,7 +78,6 @@ ACTOR ArtiInvulnerability : PowerupGiver 84 SpawnID 133 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.PICKUPFLASH Inventory.RespawnTics 4230 Inventory.Icon ARTIINVU @@ -105,7 +101,6 @@ ACTOR ArtiInvulnerability2 : PowerupGiver 84 SpawnID 133 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.PICKUPFLASH Inventory.RespawnTics 4230 Inventory.Icon ARTIDEFN @@ -128,7 +123,6 @@ ACTOR ArtiTorch : PowerupGiver 33 SpawnID 73 +COUNTITEM +FLOATBOB - +NOGRAVITY +INVENTORY.PICKUPFLASH Inventory.Icon ARTITRCH Inventory.PickupMessage "$TXT_ARTITORCH" diff --git a/wadsrc/static/actors/raven/ravenhealth.txt b/wadsrc/static/actors/raven/ravenhealth.txt index 45cbe59b9..af951be1b 100644 --- a/wadsrc/static/actors/raven/ravenhealth.txt +++ b/wadsrc/static/actors/raven/ravenhealth.txt @@ -3,7 +3,6 @@ ACTOR CrystalVial : Health 81 Game Raven SpawnID 23 +FLOATBOB - +NOGRAVITY Inventory.Amount 10 Inventory.PickupMessage "$TXT_ITEMHEALTH" States diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index d2bb85fd2..bd90342f2 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -198,14 +198,6 @@ E2B5D1400279335811C1C1C0B437D9C8 // Deathknights of the Dark Citadel, map54 clearlineflags 1069 0x200 } -CBDE77E3ACB4B166D53C1812E5C72F54 // Hexen IWAD map04 -{ - setthingz 49 0 - setthingz 50 0 - setthingz 51 0 - setthingz 52 0 -} - 3F249EDD62A3A08F53A6C53CB4C7ABE5 // Artica 3 map01 { clearlinespecial 66 diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 978480e4d..f84c3ceff 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -795,6 +795,13 @@ OptionValue "AltHUDScale" 2, "Pixel double" } +OptionValue "AltHUDAmmo" +{ + 0, "Current weapon" + 1, "Available weapons" + 2, "All weapons" +} + OptionValue "AltHUDTime" { 0, "Off" @@ -828,6 +835,7 @@ OptionMenu "AltHUDOptions" Option "Show stamina and accuracy", "hud_showstats", "OnOff" Option "Show berserk", "hud_berserk_health", "OnOff" Option "Show weapons", "hud_showweapons", "OnOff" + Option "Show ammo for", "hud_showammo", "AltHUDAmmo" Option "Show time", "hud_showtime", "AltHUDTime" Option "Time color", "hud_timecolor", "TextColors" Option "Show network latency", "hud_showlag", "AltHUDLag" @@ -1268,42 +1276,60 @@ OptionMenu "CompatibilityOptions" { Title "COMPATIBILITY OPTIONS" Option "Compatibility mode", "compatmode", "CompatModes", "", 1 + StaticText " " + StaticText "Actor Behavior",1 + Option "Crushed monsters can be resurrected", "compat_CORPSEGIBS", "YesNo" + Option "Friendly monsters aren't blocked", "compat_NOBLOCKFRIENDS", "YesNo" + Option "Limit Pain Elementals' Lost Souls", "compat_LIMITPAIN", "YesNo" + Option "Monster movement is affected by effects", "compat_MBFMONSTERMOVE", "YesNo" + Option "Monsters cannot cross dropoffs", "compat_CROSSDROPOFF", "YesNo" + Option "Monsters get stuck over dropoffs", "compat_DROPOFF", "YesNo" + Option "Monsters see invisible players", "compat_INVISIBILITY", "YesNo" + Option "No Minotaur floor flames in water", "compat_MINOTAUR", "YesNo" + Option "Spawn item drops on the floor", "compat_NOTOSSDROPS", "YesNo" + + StaticText " " + StaticText "DehackEd Behavior",1 + Option "DEH health settings like Doom2.exe", "compat_DEHHEALTH", "YesNo" + Option "Original A_Mushroom speed in DEH mods", "compat_MUSHROOM", "YesNo" + + StaticText " " + StaticText "Map/Action Behavior",1 + Option "All special lines can block ", "compat_USEBLOCKING", "YesNo" + Option "Allow any bossdeath for level special", "compat_ANYBOSSDEATH", "YesNo" + Option "Disable BOOM door light effect", "compat_NODOORLIGHT", "YesNo" + Option "Find neighboring light like Doom", "compat_LIGHT", "YesNo" Option "Find shortest textures like Doom", "compat_SHORTTEX", "YesNo" Option "Use buggier stair building", "compat_stairs", "YesNo" - Option "Find neighboring light like Doom", "compat_LIGHT", "YesNo" - Option "Limit Pain Elementals' Lost Souls", "compat_LIMITPAIN", "YesNo" - Option "Don't let others hear your pickups", "compat_SILENTPICKUP", "YesNo" + Option "Use Doom's floor motion behavior", "compat_floormove", "YesNo" + + StaticText " " + StaticText "Physics Behavior",1 Option "Actors are infinitely tall", "compat_nopassover", "YesNo" - Option "Enable wall running", "compat_WALLRUN", "YesNo" - Option "Spawn item drops on the floor", "compat_NOTOSSDROPS", "YesNo" - Option "All special lines can block ", "compat_USEBLOCKING", "YesNo" - Option "Disable BOOM door light effect", "compat_NODOORLIGHT", "YesNo" - Option "Raven scrollers use original speed", "compat_RAVENSCROLL", "YesNo" - Option "Use original sound target handling", "compat_SOUNDTARGET", "YesNo" - Option "DEH health settings like Doom2.exe", "compat_DEHHEALTH", "YesNo" - Option "Self ref. sectors don't block shots", "compat_TRACE", "YesNo" - Option "Monsters get stuck over dropoffs", "compat_DROPOFF", "YesNo" - Option "Monsters cannot cross dropoffs", "compat_CROSSDROPOFF", "YesNo" - Option "Monsters see invisible players", "compat_INVISIBILITY", "YesNo" Option "Boom scrollers are additive", "compat_BOOMSCROLL", "YesNo" - Option "Inst. moving floors are not silent", "compat_silentinstantfloors", "YesNo" - Option "Sector sounds use center as source", "compat_SECTORSOUNDS", "YesNo" - Option "Use Doom heights for missile clipping", "compat_MISSILECLIP", "YesNo" - Option "Allow any bossdeath for level special", "compat_ANYBOSSDEATH", "YesNo" - Option "No Minotaur floor flames in water", "compat_MINOTAUR", "YesNo" - Option "Original A_Mushroom speed in DEH mods", "compat_MUSHROOM", "YesNo" - Option "Monster movement is affected by effects", "compat_MBFMONSTERMOVE", "YesNo" - Option "Crushed monsters can be resurrected", "compat_CORPSEGIBS", "YesNo" - Option "Friendly monsters aren't blocked", "compat_NOBLOCKFRIENDS", "YesNo" - Option "Invert sprite sorting", "compat_SPRITESORT", "YesNo" + Option "Cannot travel straight NSEW", "compat_badangles", "YesNo" + Option "Enable wall running", "compat_WALLRUN", "YesNo" + Option "Raven scrollers use original speed", "compat_RAVENSCROLL", "YesNo" + Option "Self ref. sectors don't block shots", "compat_TRACE", "YesNo" Option "Use Doom code for hitscan checks", "compat_HITSCAN", "YesNo" - Option "Cripple sound for silent BFG trick", "compat_soundslots", "YesNo" + Option "Use Doom heights for missile clipping", "compat_MISSILECLIP", "YesNo" + + + StaticText " " + StaticText "Rendering Behavior",1 Option "Draw polyobjects like Hexen", "compat_POLYOBJ", "YesNo" Option "Ignore Y offsets on masked midtextures", "compat_MASKEDMIDTEX", "YesNo" - Option "Cannot travel straight NSEW", "compat_badangles", "YesNo" - Option "Use Doom's floor motion behavior", "compat_floormove", "YesNo" + Option "Invert sprite sorting", "compat_SPRITESORT", "YesNo" + + StaticText " " + StaticText "Sound Behavior",1 + Option "Cripple sound for silent BFG trick", "compat_soundslots", "YesNo" + Option "Don't let others hear your pickups", "compat_SILENTPICKUP", "YesNo" + Option "Inst. moving floors are not silent", "compat_silentinstantfloors", "YesNo" + Option "Sector sounds use center as source", "compat_SECTORSOUNDS", "YesNo" Option "Sounds stop when actor vanishes", "compat_soundcutoff", "YesNo" + Option "Use original sound target handling", "compat_SOUNDTARGET", "YesNo" Class "CompatibilityMenu" }