diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 232cff329..4c19865e9 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,11 @@ October 17, 2009 (Changes by Graf Zahl) +- Fixed: The rail sound used the shooter's position for calculating the sound origin + but should use the camera position instead to get the correct position for + the closest point along the trail. +- Fixed: Explosions no longer caused splashes. +- Fixed: Copying translations to lower decals had the shade color check wrong. +- Fixed: Waggling floors did not moved attached geometry. +- Cleaned up p_floor.cpp so that related parts of the code are grouped together. - fixed: The translation addition broke parsing of palette index based translations. October 16, 2009 (Changes by Graf Zahl) diff --git a/src/g_doom/a_fatso.cpp b/src/g_doom/a_fatso.cpp index e9dfa98e3..484df58ca 100644 --- a/src/g_doom/a_fatso.cpp +++ b/src/g_doom/a_fatso.cpp @@ -135,10 +135,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom) if (spawntype == NULL) spawntype = PClass::FindClass("FatShot"); P_RadiusAttack (self, self->target, 128, 128, self->DamageType, true); - if (self->z <= self->floorz + (128<RenderStyle = STYLE_Add; self->alpha = FRACUNIT; P_RadiusAttack (self, self->target, 128, 128, self->DamageType, true); - if (self->z <= self->floorz + (128<LowerDecal) { - int lowercolor = color; + int lowercolor; const FDecalTemplate * tpl_low = tpl->LowerDecal->GetDecal(); // If the default color of the lower decal is the same as the main decal's // apply the custom color as well. - if (tpl->ShadeColor == tpl_low->ShadeColor) lowercolor=0; + if (tpl->ShadeColor != tpl_low->ShadeColor) lowercolor=0; + else lowercolor = color; StaticCreate (tpl_low, x, y, z, wall, ffloor, lowercolor); } DImpactDecal::CheckMax(); diff --git a/src/g_strife/a_thingstoblowup.cpp b/src/g_strife/a_thingstoblowup.cpp index 52cb1d3e5..9727bccd1 100644 --- a/src/g_strife/a_thingstoblowup.cpp +++ b/src/g_strife/a_thingstoblowup.cpp @@ -74,10 +74,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Explode512) { self->target->player->extralight = 5; } - if (self->z <= self->floorz + (512<RenderStyle = STYLE_Add; diff --git a/src/p_effect.cpp b/src/p_effect.cpp index 19b623b38..79de562c1 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -472,17 +472,33 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end } else { + // Only consider sound in 2D (for now, anyway) // [BB] You have to devide by lengthsquared here, not multiply with it. - r = ((start.Y - FIXED2FLOAT(mo->y)) * (-dir.Y) - - (start.X - FIXED2FLOAT(mo->x)) * (dir.X)) / lengthsquared; + + r = ((start.Y - FIXED2FLOAT(viewy)) * (-dir.Y) - (start.X - FIXED2FLOAT(viewx)) * (dir.X)) / lengthsquared; + r = clamp(r, 0., 1.); dirz = dir.Z; dir.Z = 0; point = start + r * dir; dir.Z = dirz; - S_Sound (FLOAT2FIXED(point.X), FLOAT2FIXED(point.Y), mo->z, +#if 0 + Printf("Start = (%1.4f,%1.4f), End = (%1.4f,%1.4f), Dir =(%1.4f,%1.4f), View = (%1.4f,%1.4f), Point = (%1.4f,%1.4f), r=%1.4f\n", + start.X, start.Y, end.X, end.Y, dir.X, dir.Y, FIXED2FLOAT(viewx), FIXED2FLOAT(viewy), + point.X, point.Y, r); + + FVector3 _start = start; + FVector3 _end = end; + FVector3 view(FIXED2FLOAT(viewx), FIXED2FLOAT(viewy), 0); + point.Z = _start.Z = _end.Z = 0; + + Printf("S: %1.4f, E: %1.4f, H: %1.4f P: %1.4f\n", + (_start-view).Length(), (_end-view).Length(), (((_start+_end)/2)-view).Length(), (point-view).Length()); +#endif + + S_Sound (FLOAT2FIXED(point.X), FLOAT2FIXED(point.Y), viewz, CHAN_WEAPON, sound, 1, ATTN_NORM); } } diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index d25ae3de0..300d70a0f 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2986,10 +2986,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Detonate) { int damage = self->GetMissileDamage (0, 1); P_RadiusAttack (self, self->target, damage, damage, self->DamageType, true); - if (self->z <= self->floorz + (damage << FRACBITS)) - { - P_HitFloor (self); - } + P_CheckSplash(self, damage<seqType >= 0) + { + SN_StartSequence (sec, CHAN_FLOOR, sec->seqType, SEQ_PLATFORM, 0); + } + else + { + SN_StartSequence (sec, CHAN_FLOOR, "Floor", 0); + } +} + + +//========================================================================== // // FLOORS // +//========================================================================== IMPLEMENT_CLASS (DFloor) @@ -60,71 +82,12 @@ void DFloor::Serialize (FArchive &arc) << m_Hexencrush; } -IMPLEMENT_POINTY_CLASS (DElevator) - DECLARE_POINTER(m_Interp_Floor) - DECLARE_POINTER(m_Interp_Ceiling) -END_POINTERS - -DElevator::DElevator () -{ -} - -void DElevator::Serialize (FArchive &arc) -{ - Super::Serialize (arc); - arc << m_Type - << m_Direction - << m_FloorDestDist - << m_CeilingDestDist - << m_Speed - << m_Interp_Floor - << m_Interp_Ceiling; -} - -void DElevator::Destroy() -{ - if (m_Interp_Ceiling != NULL) - { - m_Interp_Ceiling->DelRef(); - m_Interp_Ceiling = NULL; - } - if (m_Interp_Floor != NULL) - { - m_Interp_Floor->DelRef(); - m_Interp_Floor = NULL; - } - Super::Destroy(); -} - -IMPLEMENT_POINTY_CLASS (DWaggleBase) - DECLARE_POINTER(m_Interpolation) -END_POINTERS - -IMPLEMENT_CLASS (DFloorWaggle) -IMPLEMENT_CLASS (DCeilingWaggle) - -DWaggleBase::DWaggleBase () -{ -} - -void DWaggleBase::Serialize (FArchive &arc) -{ - Super::Serialize (arc); - arc << m_OriginalDist - << m_Accumulator - << m_AccDelta - << m_TargetScale - << m_Scale - << m_ScaleDelta - << m_Ticker - << m_State - << m_Interpolation; -} - - +//========================================================================== // -// MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN) +// MOVE A FLOOR TO ITS DESTINATION (UP OR DOWN) // +//========================================================================== + void DFloor::Tick () { EResult res; @@ -238,62 +201,11 @@ void DFloor::Tick () } } +//========================================================================== // -// T_MoveElevator() // -// Move an elevator to it's destination (up or down) -// Called once per tick for each moving floor. // -// Passed an elevator_t structure that contains all pertinent info about the -// move. See P_SPEC.H for fields. -// No return. -// -// jff 02/22/98 added to support parallel floor/ceiling motion -// -void DElevator::Tick () -{ - EResult res; - - fixed_t oldfloor, oldceiling; - - oldfloor = m_Sector->floorplane.d; - oldceiling = m_Sector->ceilingplane.d; - - if (m_Direction < 0) // moving down - { - res = MoveFloor (m_Speed, m_FloorDestDist, m_Direction); - if (res == ok || res == pastdest) - { - res = MoveCeiling (m_Speed, m_CeilingDestDist, m_Direction); - if (res == crushed) - { - MoveFloor (m_Speed, oldfloor, -m_Direction); - } - } - } - else // up - { - res = MoveCeiling (m_Speed, m_CeilingDestDist, m_Direction); - if (res == ok || res == pastdest) - { - res = MoveFloor (m_Speed, m_FloorDestDist, m_Direction); - if (res == crushed) - { - MoveCeiling (m_Speed, oldceiling, -m_Direction); - } - } - } - - if (res == pastdest) // if destination height acheived - { - // make floor stop sound - SN_StopSequence (m_Sector); - - m_Sector->floordata = NULL; //jff 2/22/98 - m_Sector->ceilingdata = NULL; //jff 2/22/98 - Destroy (); // remove elevator from actives - } -} +//========================================================================== void DFloor::SetFloorChangeType (sector_t *sec, int change) { @@ -315,37 +227,35 @@ void DFloor::SetFloorChangeType (sector_t *sec, int change) } } -static void StartFloorSound (sector_t *sec) -{ - if (sec->seqType >= 0) - { - SN_StartSequence (sec, CHAN_FLOOR, sec->seqType, SEQ_PLATFORM, 0); - } - else - { - SN_StartSequence (sec, CHAN_FLOOR, "Floor", 0); - } -} +//========================================================================== +// +// +// +//========================================================================== void DFloor::StartFloorSound () { ::StartFloorSound (m_Sector); } -void DElevator::StartFloorSound () -{ - ::StartFloorSound (m_Sector); -} +//========================================================================== +// +// +// +//========================================================================== DFloor::DFloor (sector_t *sec) : DMovingFloor (sec) { } +//========================================================================== // // HANDLE FLOOR TYPES // [RH] Added tag, speed, height, crush, change params. // +//========================================================================== + bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, fixed_t speed, fixed_t height, int crush, int change, bool hexencrush) { @@ -601,10 +511,14 @@ manual_floor: return rtn; } +//========================================================================== +// // [RH] // EV_FloorCrushStop // Stop a floor from crushing! // +//========================================================================== + bool EV_FloorCrushStop (int tag) { int secnum = -1; @@ -624,61 +538,11 @@ bool EV_FloorCrushStop (int tag) return true; } +//========================================================================== // -// EV_DoChange() +// Linear tag search to emulate stair building from Doom.exe // -// Handle pure change types. These change floor texture and sector type -// by trigger or numeric model without moving the floor. -// -// The linedef causing the change and the type of change is passed -// Returns true if any sector changes -// -// jff 3/15/98 added to better support generalized sector types -// [RH] Added tag parameter. -// -bool EV_DoChange (line_t *line, EChange changetype, int tag) -{ - int secnum; - bool rtn; - sector_t *sec; - sector_t *secm; - - secnum = -1; - rtn = false; - // change all sectors with the same tag as the linedef - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) - { - sec = §ors[secnum]; - - rtn = true; - - // handle trigger or numeric change type - FTextureID oldpic = sec->GetTexture(sector_t::floor); - - switch(changetype) - { - case trigChangeOnly: - if (line) - { // [RH] if no line, no change - sec->SetTexture(sector_t::floor, line->frontsector->GetTexture(sector_t::floor)); - sec->special = (sec->special & SECRET_MASK) | (line->frontsector->special & ~SECRET_MASK); - } - break; - case numChangeOnly: - secm = sec->FindModelFloorSector (sec->CenterFloor()); - if (secm) - { // if no model, no change - sec->SetTexture(sector_t::floor, secm->GetTexture(sector_t::floor)); - sec->special = secm->special; - } - break; - default: - break; - } - } - return rtn; -} - +//========================================================================== static int P_FindSectorFromTagLinear (int tag, int start) { @@ -689,6 +553,7 @@ static int P_FindSectorFromTagLinear (int tag, int start) return -1; } +//========================================================================== // // BUILD A STAIRCASE! // [RH] Added stairsize, srcspeed, delay, reset, igntxt, usespecials parameters @@ -696,6 +561,8 @@ static int P_FindSectorFromTagLinear (int tag, int start) // by its special. If usespecials is 2, each sector stays in "sync" with // the others. // +//========================================================================== + bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt, int usespecials) @@ -897,7 +764,12 @@ manual_stair: return rtn; } +//========================================================================== +// // [RH] Added pillarspeed and slimespeed parameters +// +//========================================================================== + bool EV_DoDonut (int tag, fixed_t pillarspeed, fixed_t slimespeed) { sector_t* s1; @@ -966,6 +838,21 @@ bool EV_DoDonut (int tag, fixed_t pillarspeed, fixed_t slimespeed) return rtn; } +//========================================================================== +// +// Elevators +// +//========================================================================== + +IMPLEMENT_POINTY_CLASS (DElevator) + DECLARE_POINTER(m_Interp_Floor) + DECLARE_POINTER(m_Interp_Ceiling) +END_POINTERS + +DElevator::DElevator () +{ +} + DElevator::DElevator (sector_t *sec) : Super (sec) { @@ -975,6 +862,111 @@ DElevator::DElevator (sector_t *sec) m_Interp_Ceiling = sec->SetInterpolation(sector_t::CeilingMove, true); } +void DElevator::Serialize (FArchive &arc) +{ + Super::Serialize (arc); + arc << m_Type + << m_Direction + << m_FloorDestDist + << m_CeilingDestDist + << m_Speed + << m_Interp_Floor + << m_Interp_Ceiling; +} + +//========================================================================== +// +// +// +//========================================================================== + +void DElevator::Destroy() +{ + if (m_Interp_Ceiling != NULL) + { + m_Interp_Ceiling->DelRef(); + m_Interp_Ceiling = NULL; + } + if (m_Interp_Floor != NULL) + { + m_Interp_Floor->DelRef(); + m_Interp_Floor = NULL; + } + Super::Destroy(); +} + +//========================================================================== +// +// T_MoveElevator() +// +// Move an elevator to it's destination (up or down) +// Called once per tick for each moving floor. +// +// Passed an elevator_t structure that contains all pertinent info about the +// move. See P_SPEC.H for fields. +// No return. +// +// jff 02/22/98 added to support parallel floor/ceiling motion +// +//========================================================================== + +void DElevator::Tick () +{ + EResult res; + + fixed_t oldfloor, oldceiling; + + oldfloor = m_Sector->floorplane.d; + oldceiling = m_Sector->ceilingplane.d; + + if (m_Direction < 0) // moving down + { + res = MoveFloor (m_Speed, m_FloorDestDist, m_Direction); + if (res == ok || res == pastdest) + { + res = MoveCeiling (m_Speed, m_CeilingDestDist, m_Direction); + if (res == crushed) + { + MoveFloor (m_Speed, oldfloor, -m_Direction); + } + } + } + else // up + { + res = MoveCeiling (m_Speed, m_CeilingDestDist, m_Direction); + if (res == ok || res == pastdest) + { + res = MoveFloor (m_Speed, m_FloorDestDist, m_Direction); + if (res == crushed) + { + MoveCeiling (m_Speed, oldceiling, -m_Direction); + } + } + } + + if (res == pastdest) // if destination height acheived + { + // make floor stop sound + SN_StopSequence (m_Sector); + + m_Sector->floordata = NULL; //jff 2/22/98 + m_Sector->ceilingdata = NULL; //jff 2/22/98 + Destroy (); // remove elevator from actives + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void DElevator::StartFloorSound () +{ + ::StartFloorSound (m_Sector); +} + +//========================================================================== // // EV_DoElevator // @@ -985,6 +977,8 @@ DElevator::DElevator (sector_t *sec) // jff 2/22/98 new type to move floor and ceiling in parallel // [RH] Added speed, tag, and height parameters and new types. // +//========================================================================== + bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype, fixed_t speed, fixed_t height, int tag) { @@ -1071,6 +1065,96 @@ bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype, } +//========================================================================== +// +// EV_DoChange() +// +// Handle pure change types. These change floor texture and sector type +// by trigger or numeric model without moving the floor. +// +// The linedef causing the change and the type of change is passed +// Returns true if any sector changes +// +// jff 3/15/98 added to better support generalized sector types +// [RH] Added tag parameter. +// +//========================================================================== + +bool EV_DoChange (line_t *line, EChange changetype, int tag) +{ + int secnum; + bool rtn; + sector_t *sec; + sector_t *secm; + + secnum = -1; + rtn = false; + // change all sectors with the same tag as the linedef + while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + { + sec = §ors[secnum]; + + rtn = true; + + // handle trigger or numeric change type + FTextureID oldpic = sec->GetTexture(sector_t::floor); + + switch(changetype) + { + case trigChangeOnly: + if (line) + { // [RH] if no line, no change + sec->SetTexture(sector_t::floor, line->frontsector->GetTexture(sector_t::floor)); + sec->special = (sec->special & SECRET_MASK) | (line->frontsector->special & ~SECRET_MASK); + } + break; + case numChangeOnly: + secm = sec->FindModelFloorSector (sec->CenterFloor()); + if (secm) + { // if no model, no change + sec->SetTexture(sector_t::floor, secm->GetTexture(sector_t::floor)); + sec->special = secm->special; + } + break; + default: + break; + } + } + return rtn; +} + + +//========================================================================== +// +// +// +//========================================================================== + +IMPLEMENT_POINTY_CLASS (DWaggleBase) + DECLARE_POINTER(m_Interpolation) +END_POINTERS + +IMPLEMENT_CLASS (DFloorWaggle) +IMPLEMENT_CLASS (DCeilingWaggle) + +DWaggleBase::DWaggleBase () +{ +} + +void DWaggleBase::Serialize (FArchive &arc) +{ + Super::Serialize (arc); + arc << m_OriginalDist + << m_Accumulator + << m_AccDelta + << m_TargetScale + << m_Scale + << m_ScaleDelta + << m_Ticker + << m_State + << m_Interpolation; +} + //========================================================================== // // WaggleBase @@ -1096,6 +1180,12 @@ void DWaggleBase::Destroy() Super::Destroy(); } +//========================================================================== +// +// +// +//========================================================================== + void DWaggleBase::DoWaggle (bool ceiling) { secplane_t *plane; @@ -1159,7 +1249,12 @@ void DWaggleBase::DoWaggle (bool ceiling) FixedMul (FloatBobOffsets[(m_Accumulator>>FRACBITS)&63], m_Scale)); m_Sector->ChangePlaneTexZ(pos, plane->HeightDiff (dist)); dist = plane->HeightDiff (dist); - P_ChangeSector (m_Sector, true, dist, ceiling, false); + + // Interesting: Hexen passes 'true' for the crunch parameter which really is crushing damage here... + // Also, this does not reset the move if it blocks. + P_Scroll3dMidtex(m_Sector, 1, dist, ceiling); + P_MoveLinkedSectors(m_Sector, 1, dist, ceiling); + P_ChangeSector (m_Sector, 1, dist, ceiling, false); } //========================================================================== @@ -1176,7 +1271,7 @@ DFloorWaggle::DFloorWaggle (sector_t *sec) : Super (sec) { sec->floordata = this; - m_Interpolation = sec->SetInterpolation(sector_t::FloorMove, false); + m_Interpolation = sec->SetInterpolation(sector_t::FloorMove, true); } void DFloorWaggle::Tick () @@ -1198,7 +1293,7 @@ DCeilingWaggle::DCeilingWaggle (sector_t *sec) : Super (sec) { sec->ceilingdata = this; - m_Interpolation = sec->SetInterpolation(sector_t::CeilingMove, false); + m_Interpolation = sec->SetInterpolation(sector_t::CeilingMove, true); } void DCeilingWaggle::Tick () diff --git a/src/p_local.h b/src/p_local.h index 71a662fb7..0be5c11e0 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -403,7 +403,8 @@ void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile ver void P_TraceBleed (int damage, AActor *target); // random direction version void P_RailAttack (AActor *source, int damage, int offset, int color1 = 0, int color2 = 0, float maxdiff = 0, bool silent = false, const PClass *puff = NULL, bool pierce = true); // [RH] Shoot a railgun bool P_HitFloor (AActor *thing); -bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false); +bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false, bool alert = true); +void P_CheckSplash(AActor *self, fixed_t distance); bool P_CheckMissileSpawn (AActor *missile); void P_PlaySpawnSound(AActor *missile, AActor *spawner); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 2285b9f9a..5a00bcc1f 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4618,7 +4618,7 @@ int P_GetThingFloorType (AActor *thing) // Returns true if hit liquid and splashed, false if not. //--------------------------------------------------------------------------- -bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z, bool checkabove) +bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z, bool checkabove, bool alert) { if (thing->flags2 & MF2_FLOATBOB || thing->flags3 & MF3_DONTSPLASH) return false; @@ -4716,7 +4716,7 @@ foundone: { mo = Spawn (splash->SplashBase, x, y, z, ALLOW_REPLACE); } - if (thing->player && !splash->NoAlert) + if (thing->player && !splash->NoAlert && alert) { P_NoiseAlert (thing, thing, true); } @@ -4793,6 +4793,25 @@ bool P_HitFloor (AActor *thing) return P_HitWater (thing, m->m_sector); } +//--------------------------------------------------------------------------- +// +// P_CheckSplash +// +// Checks for splashes caused by explosions +// +//--------------------------------------------------------------------------- + +void P_CheckSplash(AActor *self, fixed_t distance) +{ + if (self->z <= self->floorz + (distance<floorsector == self->Sector) + { + // Explosion splashes never alert monsters. This is because A_Explode has + // a separate parameter for that so this would get in the way of proper + // behavior. + P_HitWater (self, self->Sector, self->x, self->y, self->floorz, false, false); + } +} + //--------------------------------------------------------------------------- // // FUNC P_CheckMissileSpawn diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index cf9e56e8e..481b6e04c 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -609,10 +609,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode) } P_RadiusAttack (self, self->target, damage, distance, self->DamageType, hurtSource, true, fulldmgdistance); - if (self->z <= self->floorz + (distance<target != NULL && self->target->player != NULL) { validcount++; @@ -637,10 +634,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusThrust) if (distance <= 0) distance = force; P_RadiusAttack (self, self->target, force, distance, self->DamageType, affectSource, false); - if (self->z <= self->floorz + (distance<