diff --git a/src/am_map.cpp b/src/am_map.cpp index 44b6da619..bb0215242 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1158,7 +1158,10 @@ void AM_NewResolution() CCMD (togglemap) { - gameaction = ga_togglemap; + if (gameaction == ga_nothing) + { + gameaction = ga_togglemap; + } } //============================================================================= diff --git a/src/d_player.h b/src/d_player.h index 9bdcfadf6..40b0d2ecd 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -174,6 +174,7 @@ class APlayerChunk : public APlayerPawn enum { PPF_NOTHRUSTWHENINVUL = 1, // Attacks do not thrust the player if they are invulnerable. + PPF_CANSUPERMORPH = 2, // Being remorphed into this class can give you a Tome of Power }; // diff --git a/src/g_hexen/a_bats.cpp b/src/g_hexen/a_bats.cpp index d00422837..2c09bb919 100644 --- a/src/g_hexen/a_bats.cpp +++ b/src/g_hexen/a_bats.cpp @@ -92,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove) } // Handle Z movement - self->z = self->target->z + 2*FloatBobOffsets[self->args[0]]; + self->z = self->target->z + 16*finesine[self->args[0] << BOBTOFINESHIFT]; self->args[0] = (self->args[0]+3)&63; return 0; } diff --git a/src/g_hexen/a_bishop.cpp b/src/g_hexen/a_bishop.cpp index e1d6e1d76..76a8dfd99 100644 --- a/src/g_hexen/a_bishop.cpp +++ b/src/g_hexen/a_bishop.cpp @@ -175,9 +175,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopChase) { PARAM_ACTION_PROLOGUE; - self->z -= FloatBobOffsets[self->special2] >> 1; + self->z -= finesine[self->special2 << BOBTOFINESHIFT] * 4; self->special2 = (self->special2 + 4) & 63; - self->z += FloatBobOffsets[self->special2] >> 1; + self->z += finesine[self->special2 << BOBTOFINESHIFT] * 4; return 0; } diff --git a/src/g_hexen/a_clericholy.cpp b/src/g_hexen/a_clericholy.cpp index 5f0a18cfc..849890ce9 100644 --- a/src/g_hexen/a_clericholy.cpp +++ b/src/g_hexen/a_clericholy.cpp @@ -146,17 +146,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack2) switch (j) { // float bob index case 0: - mo->special2 = pr_holyatk2()&7; // upper-left + mo->special2 = pr_holyatk2(8 << BOBTOFINESHIFT); // upper-left break; case 1: - mo->special2 = 32+(pr_holyatk2()&7); // upper-right + mo->special2 = FINEANGLES/2 + pr_holyatk2(8 << BOBTOFINESHIFT); // upper-right break; case 2: - mo->special2 = (32+(pr_holyatk2()&7))<<16; // lower-left + mo->special2 = (FINEANGLES/2 + pr_holyatk2(8 << BOBTOFINESHIFT)) << 16; // lower-left break; case 3: - i = pr_holyatk2(); - mo->special2 = ((32+(i&7))<<16)+32+(pr_holyatk2()&7); + i = pr_holyatk2(8 << BOBTOFINESHIFT); + mo->special2 = ((FINEANGLES/2 + i) << 16) + FINEANGLES/2 + pr_holyatk2(8 << BOBTOFINESHIFT); break; } mo->z = self->z; @@ -463,23 +463,19 @@ void CHolyWeave (AActor *actor, FRandom &pr_random) int weaveXY, weaveZ; int angle; - weaveXY = actor->special2>>16; - weaveZ = actor->special2&0xFFFF; - angle = (actor->angle+ANG90)>>ANGLETOFINESHIFT; - newX = actor->x-FixedMul(finecosine[angle], - FloatBobOffsets[weaveXY]<<2); - newY = actor->y-FixedMul(finesine[angle], - FloatBobOffsets[weaveXY]<<2); - weaveXY = (weaveXY+(pr_random()%5))&63; - newX += FixedMul(finecosine[angle], - FloatBobOffsets[weaveXY]<<2); - newY += FixedMul(finesine[angle], - FloatBobOffsets[weaveXY]<<2); + weaveXY = actor->special2 >> 16; + weaveZ = actor->special2 & FINEMASK; + angle = (actor->angle + ANG90) >> ANGLETOFINESHIFT; + newX = actor->x - FixedMul(finecosine[angle], finesine[weaveXY] * 32); + newY = actor->y - FixedMul(finesine[angle], finesine[weaveXY] * 32); + weaveXY = (weaveXY + pr_random(5 << BOBTOFINESHIFT)) & FINEMASK; + newX += FixedMul(finecosine[angle], finesine[weaveXY] * 32); + newY += FixedMul(finesine[angle], finesine[weaveXY] * 32); P_TryMove(actor, newX, newY, true); - actor->z -= FloatBobOffsets[weaveZ]<<1; - weaveZ = (weaveZ+(pr_random()%5))&63; - actor->z += FloatBobOffsets[weaveZ]<<1; - actor->special2 = weaveZ+(weaveXY<<16); + actor->z -= finesine[weaveZ] * 16; + weaveZ = (weaveZ + pr_random(5 << BOBTOFINESHIFT)) & FINEMASK; + actor->z += finesine[weaveZ] * 16; + actor->special2 = weaveZ + (weaveXY << 16); } //============================================================================ diff --git a/src/g_hexen/a_firedemon.cpp b/src/g_hexen/a_firedemon.cpp index ae93715e3..714ece7b3 100644 --- a/src/g_hexen/a_firedemon.cpp +++ b/src/g_hexen/a_firedemon.cpp @@ -145,8 +145,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase) if (self->threshold) self->threshold--; // Float up and down - self->z += FloatBobOffsets[weaveindex]; - self->special1 = (weaveindex+2)&63; + self->z += finesine[weaveindex << BOBTOFINESHIFT] * 8; + self->special1 = (weaveindex + 2) & 63; // Ensure it stays above certain height if (self->z < self->floorz + (64*FRACUNIT)) diff --git a/src/g_hexen/a_flechette.cpp b/src/g_hexen/a_flechette.cpp index 4ff127944..0b907031a 100644 --- a/src/g_hexen/a_flechette.cpp +++ b/src/g_hexen/a_flechette.cpp @@ -420,8 +420,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage) P_RadiusAttack (self, self->target, 4, 40, self->DamageType, true); bobIndex = self->special2; - self->z += FloatBobOffsets[bobIndex]>>4; - self->special2 = (bobIndex+1)&63; + self->z += finesine[bobIndex << BOBTOFINESHIFT] >> 1; + self->special2 = (bobIndex + 1) & 63; return 0; } diff --git a/src/g_hexen/a_fog.cpp b/src/g_hexen/a_fog.cpp index 2b01761a6..e360bdb3f 100644 --- a/src/g_hexen/a_fog.cpp +++ b/src/g_hexen/a_fog.cpp @@ -90,8 +90,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove) if ((self->args[3] % 4) == 0) { weaveindex = self->special2; - self->z += FloatBobOffsets[weaveindex]>>1; - self->special2 = (weaveindex+1)&63; + self->z += finesine[weaveindex << BOBTOFINESHIFT] * 4; + self->special2 = (weaveindex + 1) & 63; } angle = self->angle>>ANGLETOFINESHIFT; diff --git a/src/g_hexen/a_korax.cpp b/src/g_hexen/a_korax.cpp index bdf1254e7..e859d88cc 100644 --- a/src/g_hexen/a_korax.cpp +++ b/src/g_hexen/a_korax.cpp @@ -186,7 +186,7 @@ void KSpiritInit (AActor *spirit, AActor *korax) spirit->health = KORAX_SPIRIT_LIFETIME; spirit->tracer = korax; // Swarm around korax - spirit->special2 = 32+(pr_kspiritinit()&7); // Float bob index + spirit->special2 = FINEANGLES/2 + pr_kspiritinit(8 << BOBTOFINESHIFT); // Float bob index spirit->args[0] = 10; // initial turn value spirit->args[1] = 0; // initial look angle diff --git a/src/g_hexen/a_wraith.cpp b/src/g_hexen/a_wraith.cpp index 9ed3fd3df..b714a57a4 100644 --- a/src/g_hexen/a_wraith.cpp +++ b/src/g_hexen/a_wraith.cpp @@ -246,8 +246,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithChase) PARAM_ACTION_PROLOGUE; int weaveindex = self->special1; - self->z += FloatBobOffsets[weaveindex]; - self->special1 = (weaveindex+2)&63; + self->z += finesine[weaveindex << BOBTOFINESHIFT] * 8; + self->special1 = (weaveindex + 2) & 63; // if (self->floorclip > 0) // { // P_SetMobjState(self, S_WRAITH_RAISE2); diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 52a3cc0f7..c0cfd82e4 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -47,6 +47,13 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp } if (p->morphTics) { // Player is already a beast + if ((p->mo->GetClass() == spawntype) + && (p->mo->PlayerFlags & PPF_CANSUPERMORPH) + && (p->morphTics < (((duration) ? duration : MORPHTICS) - TICRATE)) + && (p->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true) == NULL)) + { // Make a super chicken + p->mo->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2)); + } return false; } if (p->health <= 0) diff --git a/src/menu/playerdisplay.cpp b/src/menu/playerdisplay.cpp index 09132186e..cb6f69ab6 100644 --- a/src/menu/playerdisplay.cpp +++ b/src/menu/playerdisplay.cpp @@ -385,7 +385,11 @@ void FListMenuItemPlayerDisplay::UpdateRandomClass() if (++mRandomClass >= (int)PlayerClasses.Size ()) mRandomClass = 0; mPlayerClass = &PlayerClasses[mRandomClass]; mPlayerState = GetDefaultByType (mPlayerClass->Type)->SeeState; - mPlayerTics = mPlayerState->GetTics(); + if (mPlayerState == NULL) + { // No see state, so try spawn state. + mPlayerState = GetDefaultByType (mPlayerClass->Type)->SpawnState; + } + mPlayerTics = mPlayerState != NULL ? mPlayerState->GetTics() : -1; mRandomTimer = 6; // Since the newly displayed class may used a different translation @@ -435,7 +439,11 @@ void FListMenuItemPlayerDisplay::SetPlayerClass(int classnum, bool force) { mPlayerClass = &PlayerClasses[classnum]; mPlayerState = GetDefaultByType (mPlayerClass->Type)->SeeState; - mPlayerTics = mPlayerState->GetTics(); + if (mPlayerState == NULL) + { // No see state, so try spawn state. + mPlayerState = GetDefaultByType (mPlayerClass->Type)->SpawnState; + } + mPlayerTics = mPlayerState != NULL ? mPlayerState->GetTics() : -1; mClassNum = classnum; } } @@ -557,17 +565,20 @@ void FListMenuItemPlayerDisplay::Drawer(bool selected) spriteframe_t *sprframe; fixed_t scaleX, scaleY; - if (mSkin == 0) + if (mPlayerState != NULL) { - sprframe = &SpriteFrames[sprites[mPlayerState->sprite].spriteframes + mPlayerState->GetFrame()]; - scaleX = GetDefaultByType(mPlayerClass->Type)->scaleX; - scaleY = GetDefaultByType(mPlayerClass->Type)->scaleY; - } - else - { - sprframe = &SpriteFrames[sprites[skins[mSkin].sprite].spriteframes + mPlayerState->GetFrame()]; - scaleX = skins[mSkin].ScaleX; - scaleY = skins[mSkin].ScaleY; + if (mSkin == 0) + { + sprframe = &SpriteFrames[sprites[mPlayerState->sprite].spriteframes + mPlayerState->GetFrame()]; + scaleX = GetDefaultByType(mPlayerClass->Type)->scaleX; + scaleY = GetDefaultByType(mPlayerClass->Type)->scaleY; + } + else + { + sprframe = &SpriteFrames[sprites[skins[mSkin].sprite].spriteframes + mPlayerState->GetFrame()]; + scaleX = skins[mSkin].ScaleX; + scaleY = skins[mSkin].ScaleY; + } } if (sprframe != NULL) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index e4130b11c..0fcdfaea5 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3362,6 +3362,10 @@ enum EACSFunctions ACSF_ACS_NamedLockedExecuteDoor, ACSF_ACS_NamedExecuteWithResult, ACSF_ACS_NamedExecuteAlways, + + // ZDaemon + ACSF_GetTeamScore = 19620, + ACSF_SetTeamScore, }; int DLevelScript::SideFromID(int id, int side) @@ -5292,20 +5296,24 @@ int DLevelScript::RunScript () case PCD_SCRIPTWAIT: statedata = STACK(1); + sp--; +scriptwait: if (controller->RunningScripts.CheckKey(statedata) != NULL) state = SCRIPT_ScriptWait; else state = SCRIPT_ScriptWaitPre; - sp--; PutLast (); break; case PCD_SCRIPTWAITDIRECT: - state = SCRIPT_ScriptWait; statedata = uallong(pc[0]); pc++; - PutLast (); - break; + goto scriptwait; + + case PCD_SCRIPTWAITNAMED: + statedata = -FName(FBehavior::StaticLookupString(STACK(1))); + sp--; + goto scriptwait; case PCD_CLEARLINESPECIAL: if (activationline != NULL) diff --git a/src/p_acs.h b/src/p_acs.h index da363958b..7a432815b 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -598,8 +598,9 @@ public: PCD_STRCPYTOMAPCHRANGE, // [FDARI] input range (copy string to all/part of array) PCD_STRCPYTOWORLDCHRANGE, PCD_STRCPYTOGLOBALCHRANGE, - PCD_PUSHFUNCTION, -/*360*/ PCD_CALLSTACK, + PCD_PUSHFUNCTION, // from Eternity +/*360*/ PCD_CALLSTACK, // from Eternity + PCD_SCRIPTWAITNAMED, /*361*/ PCODE_COMMAND_COUNT }; diff --git a/src/p_local.h b/src/p_local.h index 032ba8e22..073320b9d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -114,8 +114,6 @@ void P_UnPredictPlayer (); #define ONCEILINGZ FIXED_MAX #define FLOATRANDZ (FIXED_MAX-1) -extern fixed_t FloatBobOffsets[64]; - APlayerPawn *P_SpawnPlayer (struct FPlayerStart *mthing, int playernum, bool tempplayer=false); void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 8d919a61b..1eceee563 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -119,47 +119,6 @@ CUSTOM_CVAR (Float, sv_gravity, 800.f, CVAR_SERVERINFO|CVAR_NOSAVE) CVAR (Bool, cl_missiledecals, true, CVAR_ARCHIVE) CVAR (Bool, addrocketexplosion, false, CVAR_ARCHIVE) - -fixed_t FloatBobOffsets[64] = -{ - 0, 51389, 102283, 152192, - 200636, 247147, 291278, 332604, - 370727, 405280, 435929, 462380, - 484378, 501712, 514213, 521763, - 524287, 521763, 514213, 501712, - 484378, 462380, 435929, 405280, - 370727, 332604, 291278, 247147, - 200636, 152192, 102283, 51389, - -1, -51390, -102284, -152193, - -200637, -247148, -291279, -332605, - -370728, -405281, -435930, -462381, - -484380, -501713, -514215, -521764, - -524288, -521764, -514214, -501713, - -484379, -462381, -435930, -405280, - -370728, -332605, -291279, -247148, - -200637, -152193, -102284, -51389 -}; - -fixed_t FloatBobDiffs[64] = -{ - 51389, 51389, 50894, 49909, 48444, - 46511, 44131, 41326, 38123, - 34553, 30649, 26451, 21998, - 17334, 12501, 7550, 2524, - -2524, -7550, -12501, -17334, - -21998, -26451, -30649, -34553, - -38123, -41326, -44131, -46511, - -48444, -49909, -50894, -51390, - -51389, -50894, -49909, -48444, - -46511, -44131, -41326, -38123, - -34553, -30649, -26451, -21999, - -17333, -12502, -7549, -2524, - 2524, 7550, 12501, 17334, - 21998, 26451, 30650, 34552, - 38123, 41326, 44131, 46511, - 48444, 49909, 50895 -}; - CVAR (Int, cl_pufftype, 0, CVAR_ARCHIVE); CVAR (Int, cl_bloodtype, 0, CVAR_ARCHIVE); diff --git a/src/tables.h b/src/tables.h index 929fabf80..04a66376e 100644 --- a/src/tables.h +++ b/src/tables.h @@ -44,14 +44,15 @@ #endif - +#define FINEANGLEBITS 13 #define FINEANGLES 8192 #define FINEMASK (FINEANGLES-1) - // 0x100000000 to 0x2000 #define ANGLETOFINESHIFT 19 +#define BOBTOFINESHIFT (FINEANGLEBITS - 6) + // Effective size is 10240. extern fixed_t finesine[5*FINEANGLES/4]; diff --git a/src/thingdef/thingdef.h b/src/thingdef/thingdef.h index aa1624620..29fd98e81 100644 --- a/src/thingdef/thingdef.h +++ b/src/thingdef/thingdef.h @@ -355,7 +355,6 @@ int MatchString (const char *in, const char **strings); struct StateCallData { FState *State; - AActor *Item; bool Result; }; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 77536f62e..89847f7c0 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -100,7 +100,6 @@ bool ACustomInventory::CallStateChain (AActor *actor, FState * State) bool result = false; int counter = 0; - StateCall.Item = this; while (State != NULL) { // Assume success. The code pointer will set this to false if necessary @@ -2790,6 +2789,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckFloor) // A_CheckCeiling // [GZ] Totally copied from A_CheckFloor, jumps if actor touches ceiling // + //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckCeiling) { @@ -2878,7 +2878,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn) } else { - oktorespawn = P_CheckPosition(self, self->x, self->z, true); + oktorespawn = P_CheckPosition(self, self->x, self->y, true); } if (oktorespawn) @@ -4078,11 +4078,11 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdis if (xydist != 0 && xyspeed != 0) { - dist = FixedMul(FloatBobOffsets[weaveXY], xydist); + dist = MulScale13(finesine[weaveXY << BOBTOFINESHIFT], xydist); newX = self->x - FixedMul (finecosine[angle], dist); newY = self->y - FixedMul (finesine[angle], dist); weaveXY = (weaveXY + xyspeed) & 63; - dist = FixedMul(FloatBobOffsets[weaveXY], xydist); + dist = MulScale13(finesine[weaveXY << BOBTOFINESHIFT], xydist); newX += FixedMul (finecosine[angle], dist); newY += FixedMul (finesine[angle], dist); if (!(self->flags5 & MF5_NOINTERACTION)) @@ -4099,12 +4099,11 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdis } self->WeaveIndexXY = weaveXY; } - if (zdist != 0 && zspeed != 0) { - self->z -= FixedMul(FloatBobOffsets[weaveZ], zdist); + self->z -= MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist); weaveZ = (weaveZ + zspeed) & 63; - self->z += FixedMul(FloatBobOffsets[weaveZ], zdist); + self->z += MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist); self->WeaveIndexZ = weaveZ; } } @@ -4441,6 +4440,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) //========================================================================== // // ACS_Named* stuff + // // These are exactly like their un-named line special equivalents, except // they take strings instead of integers to indicate which script to run. diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index b9cff9a9f..114c8a0b1 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -333,6 +333,7 @@ static FFlagDef PlayerPawnFlags[] = { // PlayerPawn flags DEFINE_FLAG(PPF, NOTHRUSTWHENINVUL, APlayerPawn, PlayerFlags), + DEFINE_FLAG(PPF, CANSUPERMORPH, APlayerPawn, PlayerFlags), }; static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int NumDefs; } FlagLists[] = diff --git a/wadsrc/static/actors/heretic/chicken.txt b/wadsrc/static/actors/heretic/chicken.txt index 2bed5248c..029dca014 100644 --- a/wadsrc/static/actors/heretic/chicken.txt +++ b/wadsrc/static/actors/heretic/chicken.txt @@ -68,6 +68,7 @@ ACTOR ChickenPlayer : PlayerPawn native Speed 1 Gravity 0.125 +NOSKIN + +CANSUPERMORPH PainSound "chicken/pain" DeathSound "chicken/death" Player.JumpZ 1 diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 531e89a4d..261b91574 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -66,6 +66,7 @@ F84AB4557464A383E93F37CD3A82AC48 // MM2 map03 71C2E6D9CFA3D8750C6A9599FB2453BD // Hacx map03: There are some switches behind 96368EB950E33AF62EA6423434E3CEF7 // HacX map17: shootable covers in these levels +BA530202AF0BA0C6CBAE6A0C7076FB72 // Requiem map04 { useblocking } @@ -176,3 +177,10 @@ E2B5D1400279335811C1C1C0B437D9C8 // Deathknights of the Dark Citadel, map54 { floormove } + +// There is a special at the beginning of the level which relies on the Pain Elemental's lost soul limit. +811A0C97777A198BC9B2BB558CB46E6A // Hell Revealed map19 +{ + limitpain +} +