diff --git a/src/d_player.h b/src/d_player.h index 96fb1399..3467328f 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -426,6 +426,11 @@ public: crouching = 0; crouchviewdelta = 0; } + + bool CanCrouch() const + { + return morphTics == 0 || mo->PlayerFlags & PPF_CROUCHABLEMORPH; + } int GetSpawnClass(); }; diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index ff39bf67..0f9d9cd5 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -558,7 +558,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurChase) if (!self1->target || (self1->target->health <= 0) || !(self1->target->flags&MF_SHOOTABLE)) { // look for a new target - self1->SetState (self1->FindState ("Spawn")); + self1->SetIdle(); return; } diff --git a/src/p_map.cpp b/src/p_map.cpp index 803276d1..657b90d8 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3886,6 +3886,7 @@ struct RailData { TArray RailHits; bool StopAtOne; + bool StopAtInvul; }; static ETraceStatus ProcessRailHit (FTraceResults &res, void *userdata) @@ -3897,7 +3898,7 @@ static ETraceStatus ProcessRailHit (FTraceResults &res, void *userdata) } // Invulnerable things completely block the shot - if (res.Actor->flags2 & MF2_INVULNERABLE) + if (data->StopAtInvul && res.Actor->flags2 & MF2_INVULNERABLE) { return TRACE_Stop; } @@ -3964,10 +3965,11 @@ void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z, int flags; - AActor *puffDefaults = puffclass == NULL ? NULL : GetDefaultByType (puffclass->GetReplacement()); + assert(puffclass != NULL); // Because we set it to a default above + AActor *puffDefaults = GetDefaultByType (puffclass->GetReplacement()); - if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) flags = 0; - else flags = TRACE_PCross|TRACE_Impact; + flags = (puffDefaults->flags6 & MF6_NOTRIGGER) ? 0 : TRACE_PCross|TRACE_Impact; + rail_data.StopAtInvul = (puffDefaults->flags3 & MF3_FOILINVUL) ? false : true; Trace (x1, y1, shootz, source->Sector, vx, vy, vz, distance, MF_SHOOTABLE, ML_BLOCKEVERYTHING, source, trace, diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 9895d7a5..9b697863 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3498,22 +3498,29 @@ void AActor::Tick () // cycle through states, calling action functions at transitions if (tics != -1) { - tics--; - // you can cycle through multiple states in a tic - // [RH] Use <= 0 instead of == 0 so that spawnstates - // of 0 tics work as expected. - if (tics <= 0) + // [BL] If we reach here with a 0 duration state, we + // have created an extra tic, so account for it. + int newtics; + do { - assert (state != NULL); - if (state == NULL) + newtics = --tics; + + // [RH] Use tics <= 0 instead of == 0 so that spawnstates + // of 0 tics work as expected. + if (tics <= 0) { - Destroy(); - return; + assert (state != NULL); + if (state == NULL) + { + Destroy(); + return; + } + if (!SetState (state->GetNextState())) + return; // freed itself } - if (!SetState (state->GetNextState())) - return; // freed itself } + while (newtics < 0); } else { diff --git a/src/p_user.cpp b/src/p_user.cpp index 42031d29..0816d753 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -539,7 +539,7 @@ void APlayerPawn::BeginPlay () void APlayerPawn::Tick() { - if (player != NULL && player->mo == this && player->morphTics == 0 && player->playerstate != PST_DEAD) + if (player != NULL && player->mo == this && player->CanCrouch() && player->playerstate != PST_DEAD) { height = FixedMul(GetDefault()->height, player->crouchfactor); } @@ -1788,7 +1788,7 @@ void P_MovePlayer (player_t *player) sm = FixedMul (sm, player->mo->Speed); // When crouching, speed and bobbing have to be reduced - if (player->morphTics == 0 && player->crouchfactor != FRACUNIT) + if (player->CanCrouch() && player->crouchfactor != FRACUNIT) { fm = FixedMul(fm, player->crouchfactor); sm = FixedMul(sm, player->crouchfactor); @@ -2204,8 +2204,7 @@ void P_PlayerThink (player_t *player) { player->cmd.ucmd.buttons &= ~BT_CROUCH; } - if ((player->morphTics == 0 || player->mo->PlayerFlags & PPF_CROUCHABLEMORPH) - && player->health > 0 && level.IsCrouchingAllowed()) + if (player->CanCrouch() && player->health > 0 && level.IsCrouchingAllowed()) { if (!totallyfrozen) { diff --git a/src/r_things.cpp b/src/r_things.cpp index 276cbd8b..9bdba99f 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -139,6 +139,7 @@ vissprite_t **firstvissprite; vissprite_t **vissprite_p; vissprite_t **lastvissprite; int newvissprite; +bool DrewAVoxel; static vissprite_t **spritesorter; static int spritesortersize = 0; @@ -186,6 +187,7 @@ void R_DeinitSprites() void R_ClearSprites (void) { vissprite_p = firstvissprite; + DrewAVoxel = false; } @@ -782,6 +784,8 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->gz = fz; vis->gzb = gzb; // [RH] use gzb, not thing->z vis->gzt = gzt; // killough 3/27/98 + vis->deltax = fx - viewx; + vis->deltay = fy - viewy; vis->renderflags = thing->renderflags; if(thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D vis->Style.RenderStyle = thing->RenderStyle; @@ -798,6 +802,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor { vis->voxel = voxel->Voxel; vis->bIsVoxel = true; + DrewAVoxel = true; } else { @@ -1330,11 +1335,22 @@ void R_DrawRemainingPlayerSprites() // gain compared to the old function. // // Sort vissprites by depth, far to near + +// This is the standard version, which does a simple test based on depth. static bool sv_compare(vissprite_t *a, vissprite_t *b) { return a->idepth > b->idepth; } +// This is an alternate version, for when one or more voxel is in view. +// It does a 2D distance test based on whichever one is furthest from +// the viewpoint. +static bool sv_compare2d(vissprite_t *a, vissprite_t *b) +{ + return TVector2(a->deltax, a->deltay).LengthSquared() < + TVector2(b->deltax, b->deltay).LengthSquared(); +} + #if 0 static drawseg_t **drawsegsorter; static int drawsegsortersize = 0; @@ -1965,7 +1981,7 @@ void R_DrawHeightPlanes(fixed_t height); // kg3D - fake planes void R_DrawMasked (void) { - R_SortVisSprites (sv_compare, firstvissprite - vissprites); + R_SortVisSprites (DrewAVoxel ? sv_compare2d : sv_compare, firstvissprite - vissprites); if (height_top == NULL) { // kg3D - no visible 3D floors, normal rendering diff --git a/src/r_things.h b/src/r_things.h index 14ed8afc..2219eee2 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -38,6 +38,7 @@ struct vissprite_t fixed_t xscale, yscale; fixed_t depth; fixed_t idepth; // 1/z + fixed_t deltax, deltay; DWORD FillColor; fixed_t floorclip; union diff --git a/src/svnrevision.h b/src/svnrevision.h index afbc5336..1d16ec00 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -3,5 +3,5 @@ // This file was automatically generated by the // updaterevision tool. Do not edit by hand. -#define ZD_SVN_REVISION_STRING "4225" -#define ZD_SVN_REVISION_NUMBER 4225 +#define ZD_SVN_REVISION_STRING "4231" +#define ZD_SVN_REVISION_NUMBER 4231 diff --git a/wadsrc/static/actors/hexen/demons.txt b/wadsrc/static/actors/hexen/demons.txt index cb1428ee..80926d7a 100644 --- a/wadsrc/static/actors/hexen/demons.txt +++ b/wadsrc/static/actors/hexen/demons.txt @@ -20,7 +20,7 @@ ACTOR Demon1 31 DeathSound "DemonDeath" ActiveSound "DemonActive" Obituary "$OB_DEMON1" - const int ChunkFlags = SXF_TRANSFERTRANSLATION|SXF_ABSOLUTEVELOCITY; + const int ChunkFlags = SXF_TRANSFERTRANSLATION | SXF_ABSOLUTEVELOCITY; States { Spawn: @@ -53,11 +53,11 @@ ACTOR Demon1 31 Stop XDeath: DEMN H 6 - DEMN I 0 A_SpawnItemEx("Demon1Chunk1", 0,0,45, 1+(random[DemonChunks](0,255)*0.015625), 1+(random[DemonChunks](0,255)*0.015625), ChunkFlags, 90) - DEMN I 0 A_SpawnItemEx("Demon1Chunk2", 0,0,45, 1+(random[DemonChunks](0,255)*0.015625), 1+(random[DemonChunks](0,255)*0.015625), ChunkFlags, 270) - DEMN I 0 A_SpawnItemEx("Demon1Chunk3", 0,0,45, 1+(random[DemonChunks](0,255)*0.015625), 1+(random[DemonChunks](0,255)*0.015625), ChunkFlags, 270) - DEMN I 0 A_SpawnItemEx("Demon1Chunk4", 0,0,45, 1+(random[DemonChunks](0,255)*0.015625), 1+(random[DemonChunks](0,255)*0.015625), ChunkFlags, 270) - DEMN I 6 A_SpawnItemEx("Demon1Chunk5", 0,0,45, 1+(random[DemonChunks](0,255)*0.015625), 1+(random[DemonChunks](0,255)*0.015625), ChunkFlags, 270) + DEMN I 0 A_SpawnItemEx("Demon1Chunk1", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle+90), frandom[DemonChunks](1,4.984375)*sin(Angle+90), 8, 90, ChunkFlags) + DEMN I 0 A_SpawnItemEx("Demon1Chunk2", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 270, ChunkFlags) + DEMN I 0 A_SpawnItemEx("Demon1Chunk3", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 270, ChunkFlags) + DEMN I 0 A_SpawnItemEx("Demon1Chunk4", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 270, ChunkFlags) + DEMN I 6 A_SpawnItemEx("Demon1Chunk5", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 270, ChunkFlags) Goto Death+2 Ice: DEMN Q 5 A_FreezeDeath @@ -249,11 +249,11 @@ ACTOR Demon2 : Demon1 8080 Stop XDeath: DEM2 H 6 - DEM2 I 0 A_SpawnItemEx("Demon2Chunk1", 0,0,45, 1+(random[DemonChunks](0,255)*0.015625), 1+(random[DemonChunks](0,255)*0.015625), ChunkFlags, 90) - DEM2 I 0 A_SpawnItemEx("Demon2Chunk2", 0,0,45, 1+(random[DemonChunks](0,255)*0.015625), 1+(random[DemonChunks](0,255)*0.015625), ChunkFlags, 270) - DEM2 I 0 A_SpawnItemEx("Demon2Chunk3", 0,0,45, 1+(random[DemonChunks](0,255)*0.015625), 1+(random[DemonChunks](0,255)*0.015625), ChunkFlags, 270) - DEM2 I 0 A_SpawnItemEx("Demon2Chunk4", 0,0,45, 1+(random[DemonChunks](0,255)*0.015625), 1+(random[DemonChunks](0,255)*0.015625), ChunkFlags, 270) - DEM2 I 6 A_SpawnItemEx("Demon2Chunk5", 0,0,45, 1+(random[DemonChunks](0,255)*0.015625), 1+(random[DemonChunks](0,255)*0.015625), ChunkFlags, 270) + DEM2 I 0 A_SpawnItemEx("Demon2Chunk1", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle+90), frandom[DemonChunks](1,4.984375)*sin(Angle+90), 8, 90, ChunkFlags) + DEM2 I 0 A_SpawnItemEx("Demon2Chunk2", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 90, ChunkFlags) + DEM2 I 0 A_SpawnItemEx("Demon2Chunk3", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 90, ChunkFlags) + DEM2 I 0 A_SpawnItemEx("Demon2Chunk4", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 90, ChunkFlags) + DEM2 I 6 A_SpawnItemEx("Demon2Chunk5", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 90, ChunkFlags) Goto Death+2 } }