diff --git a/src/compatibility.cpp b/src/compatibility.cpp index d60677f64..498fefb2a 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -145,6 +145,7 @@ static FCompatOption Options[] = { "badangles", COMPATF2_BADANGLES, SLOT_COMPAT2 }, { "floormove", COMPATF2_FLOORMOVE, SLOT_COMPAT2 }, { "soundcutoff", COMPATF2_SOUNDCUTOFF, SLOT_COMPAT2 }, + { "pointonline", COMPATF2_POINTONLINE, SLOT_COMPAT2 }, { NULL, 0, 0 } }; diff --git a/src/d_main.cpp b/src/d_main.cpp index 98be13e33..3b3cce1f4 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -561,7 +561,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN| COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF|COMPATF_CORPSEGIBS|COMPATF_HITSCAN| COMPATF_WALLRUN|COMPATF_NOTOSSDROPS|COMPATF_LIGHT|COMPATF_MASKEDMIDTEX; - w = COMPATF2_BADANGLES|COMPATF2_FLOORMOVE; + w = COMPATF2_BADANGLES|COMPATF2_FLOORMOVE|COMPATF2_POINTONLINE; break; case 3: // Boom compat mode @@ -580,6 +580,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) case 6: // Boom with some added settings to reenable some 'broken' behavior v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP|COMPATF_NO_PASSMOBJ| COMPATF_INVISIBILITY|COMPATF_CORPSEGIBS|COMPATF_HITSCAN|COMPATF_WALLRUN|COMPATF_NOTOSSDROPS; + w = COMPATF2_POINTONLINE; break; } @@ -622,6 +623,7 @@ CVAR (Flag, compat_maskedmidtex, compatflags, COMPATF_MASKEDMIDTEX); CVAR (Flag, compat_badangles, compatflags2, COMPATF2_BADANGLES); CVAR (Flag, compat_floormove, compatflags2, COMPATF2_FLOORMOVE); CVAR (Flag, compat_soundcutoff, compatflags2, COMPATF2_SOUNDCUTOFF); +CVAR (Flag, compat_pointonline, compatflags2, COMPATF2_POINTONLINE); //========================================================================== // diff --git a/src/d_player.h b/src/d_player.h index e27bf1087..2ac2ad0d5 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -427,6 +427,7 @@ public: short fixedcolormap; // can be set to REDCOLORMAP, etc. short fixedlightlevel; pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc) + TObjPtr pspinterp[NUMPSPRITES]; // view sprite interpolations int morphTics; // player is a chicken/pig if > 0 const PClass *MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed int MorphStyle; // which effects to apply for this player instance when morphed diff --git a/src/doomdef.h b/src/doomdef.h index c8aa66c17..802591386 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -340,6 +340,7 @@ enum COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW. COMPATF2_FLOORMOVE = 1 << 1, // Use the same floor motion behavior as Doom. COMPATF2_SOUNDCUTOFF = 1 << 2, // Cut off sounds when an actor vanishes instead of making it owner-less + COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSide() }; // Emulate old bugs for select maps. These are not exposed by a cvar diff --git a/src/g_doomedmap.cpp b/src/g_doomedmap.cpp index 45224329d..08d5aa2e2 100644 --- a/src/g_doomedmap.cpp +++ b/src/g_doomedmap.cpp @@ -135,7 +135,7 @@ CCMD (dumpmapthings) } else { - Printf("%6d none", infos[i]->Key); + Printf("%6d none\n", infos[i]->Key); } } diff --git a/src/g_game.cpp b/src/g_game.cpp index 8101ca23d..f77949687 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1726,6 +1726,15 @@ void G_DoPlayerPop(int playernum) players[playernum].mo = NULL; players[playernum].camera = NULL; } + // Now's the ideal time to remove his psprite interpolations. + for (int ii = 0; ii < NUMPSPRITES; ii++) + { + if (players[playernum].psprites[ii].interpolation != NULL) + { + players[playernum].psprites[ii].StopInterpolation(); + players[playernum].pspinterp[ii] = NULL; + } + } // [RH] Let the scripts know the player left FBehavior::StaticStartTypedScripts(SCRIPT_Disconnect, NULL, true, playernum); } diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 49493667e..ac938797d 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1333,6 +1333,7 @@ MapFlagHandlers[] = { "compat_badangles", MITYPE_COMPATFLAG, 0, COMPATF2_BADANGLES }, { "compat_floormove", MITYPE_COMPATFLAG, 0, COMPATF2_FLOORMOVE }, { "compat_soundcutoff", MITYPE_COMPATFLAG, 0, COMPATF2_SOUNDCUTOFF }, + { "compat_pointonline", MITYPE_COMPATFLAG, 0, COMPATF2_POINTONLINE }, { "cd_start_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end1_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end2_track", MITYPE_EATNEXT, 0, 0 }, diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 54f9fa658..63ab71717 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -75,6 +75,7 @@ #include "actorptrselect.h" #include "farchive.h" #include "decallib.h" +#include "version.h" #include "g_shared/a_pickups.h" @@ -1417,7 +1418,7 @@ FBehavior *FBehavior::StaticLoadModule (int lumpnum, FileReader *fr, int len) else { delete behavior; - Printf(TEXTCOLOR_RED "%s: invalid ACS module", Wads.GetLumpFullName(lumpnum)); + Printf(TEXTCOLOR_RED "%s: invalid ACS module\n", Wads.GetLumpFullName(lumpnum)); return NULL; } } @@ -6032,6 +6033,7 @@ int DLevelScript::RunScript () int sp = 0; int *pc = this->pc; ACSFormat fmt = activeBehavior->GetFormat(); + FBehavior* const savedActiveBehavior = activeBehavior; unsigned int runaway = 0; // used to prevent infinite loops int pcd; FString work; @@ -6065,6 +6067,7 @@ int DLevelScript::RunScript () { default: Printf ("Unknown P-Code %d in %s\n", pcd, ScriptPresentation(script).GetChars()); + activeBehavior = savedActiveBehavior; // fall through case PCD_TERMINATE: DPrintf ("%s finished\n", ScriptPresentation(script).GetChars()); @@ -9355,6 +9358,10 @@ scriptwait: } break; + case PCD_CONSOLECOMMAND: + Printf (TEXTCOLOR_RED GAMENAME " doesn't support execution of console commands from scripts\n"); + sp -= 3; + break; } } diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index a0b1ddbc1..603535b7c 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -184,7 +184,6 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf const char *message; const char *messagename; char gendermessage[1024]; - bool friendly; int gender; // No obituaries for non-players, voodoo dolls or when not wanted @@ -197,8 +196,6 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf if (inflictor && inflictor->player && inflictor->player->mo != inflictor) MeansOfDeath = NAME_None; - friendly = (self->player != attacker->player && self->IsTeammate(attacker)); - mod = MeansOfDeath; message = NULL; messagename = NULL; @@ -266,7 +263,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf if (message == NULL && attacker != NULL && attacker->player != NULL) { - if (friendly) + if (self->player != attacker->player && self->IsTeammate(attacker)) { self = attacker; gender = self->player->userinfo.GetGender(); diff --git a/src/p_local.h b/src/p_local.h index a2fa00c71..95d7541a8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -153,7 +153,7 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PCl AActor *P_SpawnPlayerMissile (AActor* source, const PClass *type); AActor *P_SpawnPlayerMissile (AActor *source, const PClass *type, angle_t angle); AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, const PClass *type, angle_t angle, - AActor **pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false); + AActor **pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false, bool noautoaim = false); void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheight=false); @@ -240,7 +240,11 @@ fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) { - return DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; + extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line); + + return i_compatflags2 & COMPATF2_POINTONLINE + ? P_VanillaPointOnLineSide(x, y, line) + : DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; } //========================================================================== @@ -254,7 +258,11 @@ inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line) { - return DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0; + extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line); + + return (i_compatflags2 & COMPATF2_POINTONLINE) + ? P_VanillaPointOnDivlineSide(x, y, line) + : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0); } //========================================================================== diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 3a4a4c6a0..0a39460e7 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -1523,3 +1523,92 @@ static AActor *RoughBlockCheck (AActor *mo, int index, void *param) } return NULL; } + +//=========================================================================== +// +// P_VanillaPointOnLineSide +// P_PointOnLineSide() from the initial Doom source code release +// +//=========================================================================== + +int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line) +{ + fixed_t dx; + fixed_t dy; + fixed_t left; + fixed_t right; + + if (!line->dx) + { + if (x <= line->v1->x) + return line->dy > 0; + + return line->dy < 0; + } + if (!line->dy) + { + if (y <= line->v1->y) + return line->dx < 0; + + return line->dx > 0; + } + + dx = (x - line->v1->x); + dy = (y - line->v1->y); + + left = FixedMul ( line->dy>>FRACBITS , dx ); + right = FixedMul ( dy , line->dx>>FRACBITS ); + + if (right < left) + return 0; // front side + return 1; // back side +} + +//=========================================================================== +// +// P_VanillaPointOnDivlineSide +// P_PointOnDivlineSide() from the initial Doom source code release +// +//=========================================================================== + +int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line) +{ + fixed_t dx; + fixed_t dy; + fixed_t left; + fixed_t right; + + if (!line->dx) + { + if (x <= line->x) + return line->dy > 0; + + return line->dy < 0; + } + if (!line->dy) + { + if (y <= line->y) + return line->dx < 0; + + return line->dx > 0; + } + + dx = (x - line->x); + dy = (y - line->y); + + // try to quickly decide by looking at sign bits + if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 ) + { + if ( (line->dy ^ dx) & 0x80000000 ) + return 1; // (left is negative) + return 0; + } + + left = FixedMul ( line->dy>>8, dx>>8 ); + right = FixedMul ( dy>>8 , line->dx>>8 ); + + if (right < left) + return 0; // front side + return 1; // back side +} + diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 267e71bb9..901372eef 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5923,7 +5923,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, const PClass *type, angle_t angle) AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, const PClass *type, angle_t angle, AActor **pLineTarget, AActor **pMissileActor, - bool nofreeaim) + bool nofreeaim, bool noautoaim) { static const int angdiff[3] = { -1<<26, 1<<26, 0 }; angle_t an = angle; @@ -5936,7 +5936,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, { return NULL; } - if (source->player && source->player->ReadyWeapon && (source->player->ReadyWeapon->WeaponFlags & WIF_NOAUTOAIM)) + if (source->player && source->player->ReadyWeapon && ((source->player->ReadyWeapon->WeaponFlags & WIF_NOAUTOAIM) || noautoaim)) { // Keep exactly the same angle and pitch as the player's own aim an = angle; diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 63f3bc648..d2bf8cc87 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -1104,11 +1104,32 @@ void P_MovePsprites (player_t *player) P_CheckWeaponZoom (player); } } + + psp = &player->psprites[0]; + for (i = 0; i < NUMPSPRITES; i++, psp++) + { + if (psp->state == NULL) + { + if (psp->interpolation != NULL) + { + player->pspinterp[i] = NULL; + psp->StopInterpolation(); + } + } + else if (psp->interpolation == NULL) + { + player->pspinterp[i] = psp->SetInterpolation(player - players, i); + } + } } FArchive &operator<< (FArchive &arc, pspdef_t &def) { arc << def.state << def.tics << def.sx << def.sy << def.sprite << def.frame; + + if (SaveVersion >= 4525) + arc << def.interpolation; + return arc; } diff --git a/src/p_pspr.h b/src/p_pspr.h index ca9b45ee8..62c2a6fe4 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -26,6 +26,7 @@ // Basic data types. // Needs fixed point, and BAM angles. #include "tables.h" +#include "r_data/r_interpolate.h" #include "thingdef/thingdef.h" #define WEAPONBOTTOM 128*FRACUNIT @@ -71,6 +72,11 @@ struct pspdef_t int sprite; int frame; bool processPending; // true: waiting for periodic processing on this tick + + TObjPtr interpolation; + DInterpolation *SetInterpolation(int player, int position); + void UpdateInterpolation(int player); + void StopInterpolation(); }; class FArchive; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 480494320..f16bdb0f9 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -297,6 +297,11 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name) { dst->mo->player = dst; } + // Fix the psprite interpolation pointers too. + for (int i = 0; i < NUMPSPRITES; i++) + { + dst->psprites[i].UpdateInterpolation(dst - players); + } // These 2 variables may not be overwritten. dst->attackdown = attackdown; dst->usedown = usedown; diff --git a/src/p_user.cpp b/src/p_user.cpp index 0d5cdce20..ced6732a3 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -316,6 +316,7 @@ player_t::player_t() memset (&cmd, 0, sizeof(cmd)); memset (frags, 0, sizeof(frags)); memset (psprites, 0, sizeof(psprites)); + memset (pspinterp, 0, sizeof(pspinterp)); } player_t &player_t::operator=(const player_t &p) @@ -371,6 +372,7 @@ player_t &player_t::operator=(const player_t &p) fixedcolormap = p.fixedcolormap; fixedlightlevel = p.fixedlightlevel; memcpy(psprites, &p.psprites, sizeof(psprites)); + memcpy(pspinterp, &p.pspinterp, sizeof(pspinterp)); morphTics = p.morphTics; MorphedPlayerClass = p.MorphedPlayerClass; MorphStyle = p.MorphStyle; @@ -435,6 +437,10 @@ size_t player_t::FixPointers (const DObject *old, DObject *rep) if (*&ConversationNPC == old) ConversationNPC = replacement, changed++; if (*&ConversationPC == old) ConversationPC = replacement, changed++; if (*&MUSINFOactor == old) MUSINFOactor = replacement, changed++; + + for (int i = 0; i < NUMPSPRITES; i++) + if (*&pspinterp[i] == old) pspinterp[i] = static_cast(rep), changed++; + return changed; } @@ -454,6 +460,11 @@ size_t player_t::PropagateMark() { GC::Mark(PendingWeapon); } + for (int i = 0; i < NUMPSPRITES; i++) + { + GC::Mark(pspinterp[i]); + } + return sizeof(*this); } @@ -3052,7 +3063,11 @@ void player_t::Serialize (FArchive &arc) for (i = 0; i < MAXPLAYERS; i++) arc << frags[i]; for (i = 0; i < NUMPSPRITES; i++) + { arc << psprites[i]; + if (SaveVersion >= 4525) + arc << pspinterp[i]; + } arc << CurrentPlayerClass; diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index 3ca3b557c..6c2221520 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -151,6 +151,35 @@ public: }; +//========================================================================== +// +// +// +//========================================================================== + +class DPSpriteInterpolation : public DInterpolation +{ + DECLARE_CLASS(DPSpriteInterpolation, DInterpolation) + + pspdef_t *psp; + int player, position; + fixed_t oldx, oldy; + fixed_t bakx, baky; + fixed_t ofsx, ofsy; + fixed_t nfsx, nfsy; + +public: + + DPSpriteInterpolation() {} + DPSpriteInterpolation(pspdef_t *psp, int player, int position); + void UpdatePointer(int player); + void Destroy(); + void UpdateInterpolation(); + void Restore(); + void Interpolate(fixed_t smoothratio); + void Serialize(FArchive &arc); +}; + //========================================================================== // // @@ -162,6 +191,7 @@ IMPLEMENT_CLASS(DSectorPlaneInterpolation) IMPLEMENT_CLASS(DSectorScrollInterpolation) IMPLEMENT_CLASS(DWallScrollInterpolation) IMPLEMENT_CLASS(DPolyobjInterpolation) +IMPLEMENT_CLASS(DPSpriteInterpolation) //========================================================================== // @@ -628,7 +658,6 @@ void DSectorScrollInterpolation::Serialize(FArchive &arc) arc << sector << ceiling << oldx << oldy; } - //========================================================================== // // @@ -824,6 +853,113 @@ void DPolyobjInterpolation::Serialize(FArchive &arc) if (arc.IsLoading()) bakverts.Resize(oldverts.Size()); } +//========================================================================== +// +// +// +//========================================================================== + +//========================================================================== +// +// +// +//========================================================================== + +DPSpriteInterpolation::DPSpriteInterpolation(pspdef_t *_psp, int _player, int _position) +: psp(_psp), player(_player), position(_position), + ofsx(0), ofsy(0), nfsx(0), nfsy(0) +{ + UpdateInterpolation (); + interpolator.AddInterpolation(this); +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::UpdatePointer(int _player) +{ + player = _player; + psp = &players[player].psprites[position]; +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::Destroy() +{ + psp->interpolation = NULL; + Super::Destroy(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::UpdateInterpolation() +{ + if ( position == ps_weapon ) + P_BobWeapon( &players[player], psp, &ofsx, &ofsy ); + + oldx = psp->sx + ofsx; + oldy = psp->sy + ofsy; +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::Restore() +{ + psp->sx = bakx - nfsx; + psp->sy = baky - nfsy; +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::Interpolate(fixed_t smoothratio) +{ + if ( position == ps_weapon ) + P_BobWeapon( &players[player], psp, &nfsx, &nfsy ); + + bakx = psp->sx + nfsx; + baky = psp->sy + nfsy; + + psp->sx = oldx + FixedMul(bakx - oldx, smoothratio) - nfsx; + psp->sy = oldy + FixedMul(baky - oldy, smoothratio) - nfsy; +} + +//========================================================================== +// +// +// +//========================================================================== + +void DPSpriteInterpolation::Serialize(FArchive &arc) +{ + Super::Serialize(arc); + arc << player << position << oldx << oldy << ofsx << ofsy; + UpdatePointer(player); +} + +//========================================================================== +// +// +// +//========================================================================== //========================================================================== // @@ -944,6 +1080,62 @@ void FPolyObj::StopInterpolation() } } +//========================================================================== +// +// +// +//========================================================================== + +DInterpolation *pspdef_t::SetInterpolation(int player, int position) +{ + if (interpolation == NULL) + { + interpolation = new DPSpriteInterpolation(this, player, position); + } + interpolation->AddRef(); + GC::WriteBarrier(interpolation); + return interpolation; +} + +//========================================================================== +// +// +// +//========================================================================== + +void pspdef_t::UpdateInterpolation(int player) +{ + if (interpolation != NULL) + { + barrier_cast(interpolation)->UpdatePointer(player); + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void pspdef_t::StopInterpolation() +{ + if (interpolation != NULL) + { + interpolation->DelRef(); + } +} + +//========================================================================== +// +// +// +//========================================================================== + +//========================================================================== +// +// +// +//========================================================================== ADD_STAT (interpolations) { @@ -951,5 +1143,3 @@ ADD_STAT (interpolations) out.Format ("%d interpolations", interpolator.CountInterpolations ()); return out; } - - diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 8433b301b..33ca0495d 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -771,7 +771,7 @@ bool FMODSoundRenderer::Init() } #endif -#ifndef _WIN32 +#if !defined _WIN32 && !defined __APPLE__ // Try to load SDL output plugin result = Sys->setPluginPath(progdir); // Should we really look for it in the program directory? result = Sys->loadPlugin("liboutput_sdl.so", &OutputPlugin); diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 54b816ebb..dab68867b 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1320,6 +1320,7 @@ enum FP_Flags { FPF_AIMATANGLE = 1, FPF_TRANSFERTRANSLATION = 2, + FPF_NOAUTOAIM = 4, }; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) { @@ -1358,7 +1359,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) // Temporarily adjusts the pitch fixed_t SavedPlayerPitch = self->pitch; self->pitch -= pitch; - AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &linetarget); + AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &linetarget, NULL, false, (Flags & FPF_NOAUTOAIM) != 0); self->pitch = SavedPlayerPitch; // automatic handling of seeker missiles @@ -5071,7 +5072,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropItem) // A_SetSpeed // //========================================================================== - DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) { ACTION_PARAM_START(2); @@ -5089,6 +5089,28 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) ref->Speed = speed; } +//========================================================================== +// +// A_SetFloatSpeed +// +//========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetFloatSpeed) +{ + ACTION_PARAM_START(2); + ACTION_PARAM_FIXED(speed, 0); + ACTION_PARAM_INT(ptr, 1); + + AActor *ref = COPY_AAPTR(self, ptr); + + if (!ref) + { + ACTION_SET_RESULT(false); + return; + } + + ref->FloatSpeed = speed; +} + //=========================================================================== // // Common A_Damage handler @@ -5823,3 +5845,4 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRipMax) ACTION_PARAM_INT(max, 0); self->RipLevelMax = max; } + diff --git a/src/version.h b/src/version.h index 913c9bd18..168cb7519 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 4524 +#define SAVEVER 4525 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index f231348d3..5877192ce 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -304,6 +304,7 @@ ACTOR Actor native //: Thinker action native A_SetDamageType(name damagetype); action native A_DropItem(class item, int dropamount = -1, int chance = 256); action native A_SetSpeed(float speed, int ptr = AAPTR_DEFAULT); + action native A_SetFloatSpeed(float speed, int ptr = AAPTR_DEFAULT); action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 04ed6f1fc..b5a8b8cd4 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -188,6 +188,7 @@ const int CPF_STEALARMOR = 32; // Flags for A_CustomMissile const int FPF_AIMATANGLE = 1; const int FPF_TRANSFERTRANSLATION = 2; +const int FPF_NOAUTOAIM = 4; // Flags for A_Teleport enum diff --git a/wadsrc/static/actors/heretic/hereticweaps.txt b/wadsrc/static/actors/heretic/hereticweaps.txt index 711c3fd29..f0db7caf2 100644 --- a/wadsrc/static/actors/heretic/hereticweaps.txt +++ b/wadsrc/static/actors/heretic/hereticweaps.txt @@ -802,6 +802,7 @@ ACTOR BlasterPuff +NOGRAVITY +PUFFONACTORS RenderStyle Add + SeeSound "weapons/blasterhit" States { Crash: diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 541dd37ac..13ae00936 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -10,7 +10,7 @@ ACTOR Inventory native action native A_JumpIfNoAmmo(state label); action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class armorbonustype = "ArmorBonus"); action native A_FireBullets(float spread_xy, float spread_z, int numbullets, int damageperbullet, class pufftype = "BulletPuff", int flags = 1, float range = 0); - action native A_FireCustomMissile(class missiletype, float angle = 0, bool useammo = true, int spawnofs_xy = 0, float spawnheight = 0, bool aimatangle = false, float pitch = 0); + action native A_FireCustomMissile(class missiletype, float angle = 0, bool useammo = true, int spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0); action native A_RailAttack(int damage, int spawnofs_xy = 0, int useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class pufftype = "BulletPuff", float spread_xy = 0, float spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270); action native A_Light(int extralight); action native A_Light0(); diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 6cbe36af4..1bd031ed8 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -55,6 +55,8 @@ A80E7EE40E0D0C76A6FBD242BE29FE27 // map15 { stairs maskedmidtex + corpsegibs + vileghosts } 10E1E2B36302D31AC4AE68C84B5DC457 // Eternal Doom MAP28 @@ -125,7 +127,6 @@ BA530202AF0BA0C6CBAE6A0C7076FB72 // Requiem map04 CBDFEFAC579A62DE8F1B48CA4A09D381 // gather2.wad map05 and darkside.wad map01 C7A2FAFB0AFB2632C50AD625CDB50E51 // Reverie map18 9E5724BC6135AA6F86EE54FD4D91F1E2 // Project X map14 -6DA6FCBA8089161BDEC6A1D3F6C8D60F // Eternal Doom map25 01899825FFEAE016D39C02A7DA4B218F // Archie map01 1D9F3AFDC2517C2E450491ED13896712 // Seej map01 0AE745A3AB86D15FB2FB74489962C421 // 6pack2 map02 @@ -320,8 +321,7 @@ F481922F4881F74760F3C0437FD5EDD0 // map03 7C1913DEE396BA26CFF22A0E9369B7D2 // Nuke Mine, e1m2 { - clearlinespecial 1107 - clearlinespecial 1108 + pointonline } 5B862477519B21B30059A466F2FF6460 // Khorus, map08 @@ -401,3 +401,8 @@ D0139194F7817BF06F3988DFC47DB38D // Whispers of Satan map29 { nopassover } + +D7F6E9F08C39A17026349A04F8C0B0BE // Return to Hadron, e1m9 +{ + pointonline +} diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index f15f91dff..b1ca44de7 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1303,6 +1303,7 @@ OptionMenu "CompatibilityOptions" Option "Find shortest textures like Doom", "compat_SHORTTEX", "YesNo" Option "Use buggier stair building", "compat_stairs", "YesNo" Option "Use Doom's floor motion behavior", "compat_floormove", "YesNo" + Option "Use Doom's point-on-line algorithm", "compat_pointonline", "YesNo" StaticText " " StaticText "Physics Behavior",1