diff --git a/Source/automap.cpp b/Source/automap.cpp index cd9fb1b27..d2a25bca1 100644 --- a/Source/automap.cpp +++ b/Source/automap.cpp @@ -402,7 +402,7 @@ void DrawAutomapPlr(const Surface &out, const Displacement &myPlayerOffset, int int px = tile.x - 2 * AutomapOffset.deltaX - ViewPosition.x; int py = tile.y - 2 * AutomapOffset.deltaY - ViewPosition.y; - Displacement playerOffset = player.position.offset; + Displacement playerOffset = {}; if (player.IsWalking()) playerOffset = GetOffsetForWalking(player.AnimInfo, player._pdir); diff --git a/Source/cursor.cpp b/Source/cursor.cpp index 95d79c859..bd64f8d18 100644 --- a/Source/cursor.cpp +++ b/Source/cursor.cpp @@ -289,18 +289,20 @@ void CheckCursMove() int yo = 0; CalcTileOffset(&xo, &yo); const Player &myPlayer = *MyPlayer; - Displacement offset = {}; - if (myPlayer.IsWalking()) - offset = GetOffsetForWalking(myPlayer.AnimInfo, myPlayer._pdir, true); - sx -= offset.deltaX - xo; - sy -= offset.deltaY - yo; - - // Predict the next frame when walking to avoid input jitter - int fx = myPlayer.position.offset2.deltaX / 256; - int fy = myPlayer.position.offset2.deltaY / 256; - fx -= (myPlayer.position.offset2.deltaX + myPlayer.position.velocity.deltaX) / 256; - fy -= (myPlayer.position.offset2.deltaY + myPlayer.position.velocity.deltaY) / 256; + if (myPlayer.IsWalking()) { + Displacement offset = GetOffsetForWalking(myPlayer.AnimInfo, myPlayer._pdir, true); + sx -= offset.deltaX - xo; + sy -= offset.deltaY - yo; + + // Predict the next frame when walking to avoid input jitter + DisplacementOf offset2 = myPlayer.position.CalculateWalkingOffsetShifted8(myPlayer._pdir, myPlayer.AnimInfo); + DisplacementOf velocity = myPlayer.position.GetWalkingVelocityShifted8(myPlayer._pdir, myPlayer.AnimInfo); + int fx = offset2.deltaX / 256; + int fy = offset2.deltaY / 256; + fx -= (offset2.deltaX + velocity.deltaX) / 256; + fy -= (offset2.deltaY + velocity.deltaY) / 256; + sx -= fx; sy -= fy; } diff --git a/Source/engine/actor_position.hpp b/Source/engine/actor_position.hpp index a8874a2c6..1dce0aaa0 100644 --- a/Source/engine/actor_position.hpp +++ b/Source/engine/actor_position.hpp @@ -16,12 +16,6 @@ struct ActorPosition { WorldTilePosition old; /** Used for referring to position of player when finishing moving one tile (also used to define target coordinates for spells and ranged attacks) */ WorldTilePosition temp; - /** Pixel offset from tile. */ - DisplacementOf offset; - /** Same as offset but contains the value in a higher range */ - DisplacementOf offset2; - /** Pixel velocity while walking. Indirectly applied to offset via _pvar6/7 */ - DisplacementOf velocity; /** @brief Calculates the offset for the walking animation. */ DisplacementOf CalculateWalkingOffset(Direction dir, const AnimationInfo &animInfo, bool pendingProcessAnimation = false) const; diff --git a/Source/engine/render/scrollrt.cpp b/Source/engine/render/scrollrt.cpp index 74c5fa4ac..b132652fe 100644 --- a/Source/engine/render/scrollrt.cpp +++ b/Source/engine/render/scrollrt.cpp @@ -533,7 +533,7 @@ void DrawDeadPlayer(const Surface &out, Point tilePosition, Point targetBufferPo for (Player &player : Players) { if (player.plractive && player._pHitPoints == 0 && player.isOnActiveLevel() && player.position.tile == tilePosition) { dFlags[tilePosition.x][tilePosition.y] |= DungeonFlag::DeadPlayer; - const Point playerRenderPosition { targetBufferPosition + player.position.offset }; + const Point playerRenderPosition { targetBufferPosition }; DrawPlayer(out, player, tilePosition, playerRenderPosition); } } @@ -705,7 +705,7 @@ void DrawMonsterHelper(const Surface &out, Point tilePosition, Point targetBuffe const ClxSprite sprite = monster.animInfo.currentSprite(); - Displacement offset = monster.position.offset; + Displacement offset = {}; if (monster.isWalking()) { bool isSideWalkingToLeft = monster.mode == MonsterMode::MoveSideways && monster.direction == Direction::West; if (isNegativeMonster && !isSideWalkingToLeft) @@ -735,7 +735,7 @@ void DrawMonsterHelper(const Surface &out, Point tilePosition, Point targetBuffe */ void DrawPlayerHelper(const Surface &out, const Player &player, Point tilePosition, Point targetBufferPosition) { - Displacement offset = player.position.offset; + Displacement offset = {}; if (player.IsWalking()) { offset = GetOffsetForWalking(player.AnimInfo, player._pdir); } diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index 02f174f02..332c36baf 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -342,10 +342,7 @@ void LoadPlayer(LoadHelper &file, Player &player) player.position.last.y = file.NextLE(); player.position.old.x = file.NextLE(); player.position.old.y = file.NextLE(); - player.position.offset.deltaX = file.NextLE(); - player.position.offset.deltaY = file.NextLE(); - player.position.velocity.deltaX = file.NextLE(); - player.position.velocity.deltaY = file.NextLE(); + file.Skip(4); // Skip offset and velocity player._pdir = static_cast(file.NextLE()); file.Skip(4); // Unused player._pgfxnum = file.NextLE(); @@ -446,8 +443,7 @@ void LoadPlayer(LoadHelper &file, Player &player) player.tempDirection = static_cast(file.NextLE()); player.queuedSpell.spellLevel = file.NextLE(); file.Skip(); // skip _pVar5, was used for storing position of a tile which should have its HorizontalMovingPlayer flag removed after walking - player.position.offset2.deltaX = file.NextLE(); - player.position.offset2.deltaY = file.NextLE(); + file.Skip(2); // skip offset2; file.Skip(); // Skip actionFrame for (uint8_t i = 0; i < giNumberOfLevels; i++) @@ -590,10 +586,7 @@ void LoadMonster(LoadHelper *file, Monster &monster) monster.position.future.y = file->NextLE(); monster.position.old.x = file->NextLE(); monster.position.old.y = file->NextLE(); - monster.position.offset.deltaX = file->NextLE(); - monster.position.offset.deltaY = file->NextLE(); - monster.position.velocity.deltaX = file->NextLE(); - monster.position.velocity.deltaY = file->NextLE(); + file->Skip(4); // Skip offset and velocity monster.direction = static_cast(file->NextLE()); monster.enemy = file->NextLE(); monster.enemyPosition.x = file->NextLE(); @@ -614,9 +607,8 @@ void LoadMonster(LoadHelper *file, Monster &monster) monster.var3 = file->NextLENarrow(); monster.position.temp.x = file->NextLENarrow(); monster.position.temp.y = file->NextLENarrow(); - monster.position.offset2.deltaX = file->NextLE(); - monster.position.offset2.deltaY = file->NextLE(); - file->Skip(4); // Skip actionFrame + file->Skip(2); // skip offset2; + file->Skip(4); // Skip actionFrame monster.maxHitPoints = file->NextLE(); monster.hitPoints = file->NextLE(); @@ -1109,10 +1101,18 @@ void SavePlayer(SaveHelper &file, const Player &player) file.WriteLE(player.position.last.y); file.WriteLE(player.position.old.x); file.WriteLE(player.position.old.y); - file.WriteLE(player.position.offset.deltaX); - file.WriteLE(player.position.offset.deltaY); - file.WriteLE(player.position.velocity.deltaX); - file.WriteLE(player.position.velocity.deltaY); + DisplacementOf offset = {}; + DisplacementOf offset2 = {}; + DisplacementOf velocity = {}; + if (player.IsWalking()) { + offset = player.position.CalculateWalkingOffset(player._pdir, player.AnimInfo); + offset2 = player.position.CalculateWalkingOffsetShifted8(player._pdir, player.AnimInfo); + velocity = player.position.GetWalkingVelocityShifted8(player._pdir, player.AnimInfo); + } + file.WriteLE(offset.deltaX); + file.WriteLE(offset.deltaY); + file.WriteLE(velocity.deltaX); + file.WriteLE(velocity.deltaY); file.WriteLE(static_cast(player._pdir)); file.Skip(4); // Unused file.WriteLE(player._pgfxnum); @@ -1218,8 +1218,8 @@ void SavePlayer(SaveHelper &file, const Player &player) file.WriteLE(static_cast(player.tempDirection)); file.WriteLE(player.queuedSpell.spellLevel); file.Skip(); // skip _pVar5, was used for storing position of a tile which should have its HorizontalMovingPlayer flag removed after walking - file.WriteLE(player.position.offset2.deltaX); - file.WriteLE(player.position.offset2.deltaY); + file.WriteLE(offset2.deltaX); + file.WriteLE(offset2.deltaY); file.Skip(); // Skip _pVar8 for (uint8_t i = 0; i < giNumberOfLevels; i++) file.WriteLE(player._pLvlVisited[i] ? 1 : 0); @@ -1342,10 +1342,18 @@ void SaveMonster(SaveHelper *file, Monster &monster) file->WriteLE(monster.position.future.y); file->WriteLE(monster.position.old.x); file->WriteLE(monster.position.old.y); - file->WriteLE(monster.position.offset.deltaX); - file->WriteLE(monster.position.offset.deltaY); - file->WriteLE(monster.position.velocity.deltaX); - file->WriteLE(monster.position.velocity.deltaY); + DisplacementOf offset = {}; + DisplacementOf offset2 = {}; + DisplacementOf velocity = {}; + if (monster.isWalking()) { + offset = monster.position.CalculateWalkingOffset(monster.direction, monster.animInfo); + offset2 = monster.position.CalculateWalkingOffsetShifted4(monster.direction, monster.animInfo); + velocity = monster.position.GetWalkingVelocityShifted4(monster.direction, monster.animInfo); + } + file->WriteLE(offset.deltaX); + file->WriteLE(offset.deltaY); + file->WriteLE(velocity.deltaX); + file->WriteLE(velocity.deltaY); file->WriteLE(static_cast(monster.direction)); file->WriteLE(monster.enemy); file->WriteLE(monster.enemyPosition.x); @@ -1364,8 +1372,8 @@ void SaveMonster(SaveHelper *file, Monster &monster) file->WriteLE(monster.var3); file->WriteLE(monster.position.temp.x); file->WriteLE(monster.position.temp.y); - file->WriteLE(monster.position.offset2.deltaX); - file->WriteLE(monster.position.offset2.deltaY); + file->WriteLE(offset2.deltaX); + file->WriteLE(offset2.deltaY); file->Skip(); // Skip _mVar8 file->WriteLE(monster.maxHitPoints); file->WriteLE(monster.hitPoints); diff --git a/Source/monster.cpp b/Source/monster.cpp index 8bee04e12..757938a0a 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -86,70 +86,6 @@ constexpr const std::array<_monster_id, 12> SkeletonTypes { MT_XSKELSD, }; -// BUGFIX: MWVel velocity values are not rounded consistently. The correct -// formula for monster walk velocity is calculated as follows (for 16, 32 and 64 -// pixel distances, respectively): -// -// vel16 = (16 << monsterWalkShift) / nframes -// vel32 = (32 << monsterWalkShift) / nframes -// vel64 = (64 << monsterWalkShift) / nframes -// -// The correct monster walk velocity table is as follows: -// -// int MWVel[24][3] = { -// { 256, 512, 1024 }, -// { 128, 256, 512 }, -// { 85, 171, 341 }, -// { 64, 128, 256 }, -// { 51, 102, 205 }, -// { 43, 85, 171 }, -// { 37, 73, 146 }, -// { 32, 64, 128 }, -// { 28, 57, 114 }, -// { 26, 51, 102 }, -// { 23, 47, 93 }, -// { 21, 43, 85 }, -// { 20, 39, 79 }, -// { 18, 37, 73 }, -// { 17, 34, 68 }, -// { 16, 32, 64 }, -// { 15, 30, 60 }, -// { 14, 28, 57 }, -// { 13, 27, 54 }, -// { 13, 26, 51 }, -// { 12, 24, 49 }, -// { 12, 23, 47 }, -// { 11, 22, 45 }, -// { 11, 21, 43 } -// }; - -/** Maps from monster walk animation frame num to monster velocity. */ -constexpr int MWVel[24][3] = { - { 256, 512, 1024 }, - { 128, 256, 512 }, - { 85, 170, 341 }, - { 64, 128, 256 }, - { 51, 102, 204 }, - { 42, 85, 170 }, - { 36, 73, 146 }, - { 32, 64, 128 }, - { 28, 56, 113 }, - { 26, 51, 102 }, - { 23, 46, 93 }, - { 21, 42, 85 }, - { 19, 39, 78 }, - { 18, 36, 73 }, - { 17, 34, 68 }, - { 16, 32, 64 }, - { 15, 30, 60 }, - { 14, 28, 57 }, - { 13, 26, 54 }, - { 12, 25, 51 }, - { 12, 24, 48 }, - { 11, 23, 46 }, - { 11, 22, 44 }, - { 10, 21, 42 } -}; /** Maps from monster action to monster animation letter. */ constexpr char Animletter[7] = "nwahds"; @@ -500,7 +436,6 @@ void ClearMVars(Monster &monster) monster.var2 = 0; monster.var3 = 0; monster.position.temp = { 0, 0 }; - monster.position.offset2 = { 0, 0 }; } void ClrAllMonsters() @@ -515,7 +450,6 @@ void ClrAllMonsters() monster.position.future = { 0, 0 }; monster.position.old = { 0, 0 }; monster.direction = static_cast(GenerateRnd(8)); - monster.position.velocity = { 0, 0 }; monster.animInfo = {}; monster.flags = 0; monster.isInvalid = false; @@ -671,7 +605,6 @@ void StartMonsterGotHit(Monster &monster) NewMonsterAnim(monster, MonsterGraphic::GotHit, monster.direction, animationFlags, numSkippedFrames); monster.mode = MonsterMode::HitRecovery; } - monster.position.offset = { 0, 0 }; monster.position.tile = monster.position.old; monster.position.future = monster.position.old; M_ClearSquares(monster); @@ -784,12 +717,11 @@ void StartSpecialStand(Monster &monster, Direction md) { NewMonsterAnim(monster, MonsterGraphic::Special, md); monster.mode = MonsterMode::SpecialStand; - monster.position.offset = { 0, 0 }; monster.position.future = monster.position.tile; monster.position.old = monster.position.tile; } -void WalkNorthwards(Monster &monster, int xvel, int yvel, int xadd, int yadd, Direction endDir) +void WalkNorthwards(Monster &monster, int xadd, int yadd, Direction endDir) { const auto fx = static_cast(xadd + monster.position.tile.x); const auto fy = static_cast(yadd + monster.position.tile.y); @@ -798,15 +730,13 @@ void WalkNorthwards(Monster &monster, int xvel, int yvel, int xadd, int yadd, Di monster.mode = MonsterMode::MoveNorthwards; monster.position.old = monster.position.tile; monster.position.future = { fx, fy }; - monster.position.velocity = DisplacementOf { static_cast(xvel), static_cast(yvel) }; monster.var1 = xadd; monster.var2 = yadd; monster.var3 = static_cast(endDir); NewMonsterAnim(monster, MonsterGraphic::Walk, endDir, AnimationDistributionFlags::ProcessAnimationPending, -1); - monster.position.offset2 = { 0, 0 }; } -void WalkSouthwards(Monster &monster, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, Direction endDir) +void WalkSouthwards(Monster &monster, int xoff, int yoff, int xadd, int yadd, Direction endDir) { const auto fx = static_cast(xadd + monster.position.tile.x); const auto fy = static_cast(yadd + monster.position.tile.y); @@ -820,15 +750,12 @@ void WalkSouthwards(Monster &monster, int xvel, int yvel, int xoff, int yoff, in dMonster[fx][fy] = monster.getId() + 1; if (monster.lightId != NO_LIGHT) ChangeLightXY(monster.lightId, monster.position.tile); - monster.position.offset = DisplacementOf { static_cast(xoff), static_cast(yoff) }; monster.mode = MonsterMode::MoveSouthwards; - monster.position.velocity = DisplacementOf { static_cast(xvel), static_cast(yvel) }; monster.var3 = static_cast(endDir); NewMonsterAnim(monster, MonsterGraphic::Walk, endDir, AnimationDistributionFlags::ProcessAnimationPending, -1); - monster.position.offset2 = DisplacementOf { static_cast(16 * xoff), static_cast(16 * yoff) }; } -void WalkSideways(Monster &monster, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, Direction endDir) +void WalkSideways(Monster &monster, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, Direction endDir) { const auto fx = static_cast(xadd + monster.position.tile.x); const auto fy = static_cast(yadd + monster.position.tile.y); @@ -843,14 +770,11 @@ void WalkSideways(Monster &monster, int xvel, int yvel, int xoff, int yoff, int monster.position.temp = { x, y }; monster.position.old = monster.position.tile; monster.position.future = { fx, fy }; - monster.position.offset = DisplacementOf { static_cast(xoff), static_cast(yoff) }; monster.mode = MonsterMode::MoveSideways; - monster.position.velocity = DisplacementOf { static_cast(xvel), static_cast(yvel) }; monster.var1 = fx; monster.var2 = fy; monster.var3 = static_cast(endDir); NewMonsterAnim(monster, MonsterGraphic::Walk, endDir, AnimationDistributionFlags::ProcessAnimationPending, -1); - monster.position.offset2 = DisplacementOf { static_cast(16 * xoff), static_cast(16 * yoff) }; } void StartAttack(Monster &monster) @@ -858,7 +782,6 @@ void StartAttack(Monster &monster) Direction md = GetMonsterDirection(monster); NewMonsterAnim(monster, MonsterGraphic::Attack, md, AnimationDistributionFlags::ProcessAnimationPending); monster.mode = MonsterMode::MeleeAttack; - monster.position.offset = { 0, 0 }; monster.position.future = monster.position.tile; monster.position.old = monster.position.tile; } @@ -870,7 +793,6 @@ void StartRangedAttack(Monster &monster, missile_id missileType, int dam) monster.mode = MonsterMode::RangedAttack; monster.var1 = missileType; monster.var2 = dam; - monster.position.offset = { 0, 0 }; monster.position.future = monster.position.tile; monster.position.old = monster.position.tile; } @@ -886,7 +808,6 @@ void StartRangedSpecialAttack(Monster &monster, missile_id missileType, int dam) monster.var1 = missileType; monster.var2 = 0; monster.var3 = dam; - monster.position.offset = { 0, 0 }; monster.position.future = monster.position.tile; monster.position.old = monster.position.tile; } @@ -896,7 +817,6 @@ void StartSpecialAttack(Monster &monster) Direction md = GetMonsterDirection(monster); NewMonsterAnim(monster, MonsterGraphic::Special, md); monster.mode = MonsterMode::SpecialMeleeAttack; - monster.position.offset = { 0, 0 }; monster.position.future = monster.position.tile; monster.position.old = monster.position.tile; } @@ -905,7 +825,6 @@ void StartEating(Monster &monster) { NewMonsterAnim(monster, MonsterGraphic::Special, monster.direction); monster.mode = MonsterMode::SpecialMeleeAttack; - monster.position.offset = { 0, 0 }; monster.position.future = monster.position.tile; monster.position.old = monster.position.tile; } @@ -927,7 +846,6 @@ void DiabloDeath(Monster &diablo, bool sendmsg) NewMonsterAnim(monster, MonsterGraphic::Death, monster.direction); monster.mode = MonsterMode::Death; - monster.position.offset = { 0, 0 }; monster.var1 = 0; monster.position.tile = monster.position.old; monster.position.future = monster.position.tile; @@ -942,7 +860,6 @@ void DiabloDeath(Monster &diablo, bool sendmsg) diablo.var3 = ViewPosition.x << 16; diablo.position.temp.x = ViewPosition.y << 16; diablo.position.temp.y = (int)((diablo.var3 - (diablo.position.tile.x << 16)) / (double)dist); - diablo.position.offset2.deltaX = (int)((diablo.position.temp.x - (diablo.position.tile.y << 16)) / (double)dist); } void SpawnLoot(Monster &monster, bool sendmsg) @@ -1045,7 +962,6 @@ void StartFadein(Monster &monster, Direction md, bool backwards) { NewMonsterAnim(monster, MonsterGraphic::Special, md); monster.mode = MonsterMode::FadeIn; - monster.position.offset = { 0, 0 }; monster.position.future = monster.position.tile; monster.position.old = monster.position.tile; monster.flags &= ~MFLAG_HIDDEN; @@ -1059,7 +975,6 @@ void StartFadeout(Monster &monster, Direction md, bool backwards) { NewMonsterAnim(monster, MonsterGraphic::Special, md); monster.mode = MonsterMode::FadeOut; - monster.position.offset = { 0, 0 }; monster.position.future = monster.position.tile; monster.position.old = monster.position.tile; if (backwards) { @@ -1088,7 +1003,8 @@ void StartHeal(Monster &monster) void SyncLightPosition(Monster &monster) { - ChangeLightOffset(monster.lightId, monster.position.offset.screenToLight()); + Displacement offset = monster.position.CalculateWalkingOffset(monster.direction, monster.animInfo); + ChangeLightOffset(monster.lightId, offset.screenToLight()); } void MonsterIdle(Monster &monster) @@ -1138,16 +1054,9 @@ bool MonsterWalk(Monster &monster, MonsterMode variant) if (monster.animInfo.tickCounterOfCurrentFrame == 0) { if (monster.animInfo.currentFrame == 0 && monster.type().type == MT_FLESTHNG) PlayEffect(monster, MonsterSound::Special); - monster.position.offset2 += monster.position.velocity; - monster.position.offset.deltaX = monster.position.offset2.deltaX >> 4; - monster.position.offset.deltaY = monster.position.offset2.deltaY >> 4; } } - assert(!monster.isWalking() || monster.position.velocity == monster.position.GetWalkingVelocityShifted4(monster.direction, monster.animInfo)); - assert(!monster.isWalking() || monster.position.offset == monster.position.CalculateWalkingOffset(monster.direction, monster.animInfo, true)); - assert(!monster.isWalking() || monster.position.offset2 == monster.position.CalculateWalkingOffsetShifted4(monster.direction, monster.animInfo, true)); - if (monster.lightId != NO_LIGHT) // BUGFIX: change uniqtype check to lightId check like it is in all other places (fixed) SyncLightPosition(monster); @@ -3693,7 +3602,6 @@ void M_StartStand(Monster &monster, Direction md) monster.var1 = static_cast(monster.mode); monster.var2 = 0; monster.mode = MonsterMode::Stand; - monster.position.offset = { 0, 0 }; monster.position.future = monster.position.tile; monster.position.old = monster.position.tile; UpdateEnemy(monster); @@ -3777,7 +3685,6 @@ void MonsterDeath(Monster &monster, Direction md, bool sendmsg) } monster.goal = MonsterGoal::None; monster.var1 = 0; - monster.position.offset = { 0, 0 }; monster.position.tile = monster.position.old; monster.position.future = monster.position.old; M_ClearSquares(monster); @@ -3911,28 +3818,28 @@ bool Walk(Monster &monster, Direction md) int mwi = monster.type().getAnimData(MonsterGraphic::Walk).frames - 1; switch (md) { case Direction::North: - WalkNorthwards(monster, 0, -MWVel[mwi][1], -1, -1, Direction::North); + WalkNorthwards(monster, -1, -1, Direction::North); break; case Direction::NorthEast: - WalkNorthwards(monster, MWVel[mwi][1], -MWVel[mwi][0], 0, -1, Direction::NorthEast); + WalkNorthwards(monster, 0, -1, Direction::NorthEast); break; case Direction::East: - WalkSideways(monster, MWVel[mwi][2], 0, -32, -16, 1, -1, 1, 0, Direction::East); + WalkSideways(monster, -32, -16, 1, -1, 1, 0, Direction::East); break; case Direction::SouthEast: - WalkSouthwards(monster, MWVel[mwi][1], MWVel[mwi][0], -32, -16, 1, 0, Direction::SouthEast); + WalkSouthwards(monster, -32, -16, 1, 0, Direction::SouthEast); break; case Direction::South: - WalkSouthwards(monster, 0, MWVel[mwi][1], 0, -32, 1, 1, Direction::South); + WalkSouthwards(monster, 0, -32, 1, 1, Direction::South); break; case Direction::SouthWest: - WalkSouthwards(monster, -MWVel[mwi][1], MWVel[mwi][0], 32, -16, 0, 1, Direction::SouthWest); + WalkSouthwards(monster, 32, -16, 0, 1, Direction::SouthWest); break; case Direction::West: - WalkSideways(monster, -MWVel[mwi][2], 0, 32, -16, -1, 1, 0, 1, Direction::West); + WalkSideways(monster, 32, -16, -1, 1, 0, 1, Direction::West); break; case Direction::NorthWest: - WalkNorthwards(monster, -MWVel[mwi][1], -MWVel[mwi][0], -1, 0, Direction::NorthWest); + WalkNorthwards(monster, -1, 0, Direction::NorthWest); break; } return true; @@ -4088,9 +3995,6 @@ void ProcessMonsters() if (monster.mode != MonsterMode::Petrified && (monster.flags & MFLAG_ALLOW_SPECIAL) == 0) { monster.animInfo.processAnimation((monster.flags & MFLAG_LOCK_ANIMATION) != 0); } - assert(!monster.isWalking() || monster.position.velocity == monster.position.GetWalkingVelocityShifted4(monster.direction, monster.animInfo)); - assert(!monster.isWalking() || monster.position.offset == monster.position.CalculateWalkingOffset(monster.direction, monster.animInfo)); - assert(!monster.isWalking() || monster.position.offset2 == monster.position.CalculateWalkingOffsetShifted4(monster.direction, monster.animInfo)); } DeleteMonsterList(); diff --git a/Source/player.cpp b/Source/player.cpp index ce4fdfd9a..914edcbd6 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -166,7 +166,6 @@ namespace { struct DirectionSettings { Direction dir; DisplacementOf tileAdd; - DisplacementOf offset; DisplacementOf map; PLR_MODE walkMode; void (*walkModeHandler)(Player &, const DirectionSettings &); @@ -181,15 +180,7 @@ constexpr int8_t PlrGFXAnimLens[enum_size::value][11] = { { 8, 18, 8, 4, 20, 16, 7, 20, 8, 10, 12 }, { 10, 16, 8, 2, 20, 20, 6, 20, 8, 9, 14 }, }; -/** Maps from player class to player velocity. */ -constexpr int PWVel[enum_size::value][3] = { - { 2048, 1024, 512 }, - { 2048, 1024, 512 }, - { 2048, 1024, 512 }, - { 2048, 1024, 512 }, - { 2048, 1024, 512 }, - { 2048, 1024, 512 }, -}; + const char *const ClassPathTbl[] = { "Warrior", "Rogue", @@ -201,15 +192,11 @@ const char *const ClassPathTbl[] = { void PmChangeLightOff(Player &player) { - assert(!player.IsWalking() || leveltype == DTYPE_TOWN || player.position.velocity == player.position.GetWalkingVelocityShifted8(player._pdir, player.AnimInfo)); - assert(!player.IsWalking() || leveltype == DTYPE_TOWN || player.position.offset == player.position.CalculateWalkingOffset(player._pdir, player.AnimInfo, true)); - assert(!player.IsWalking() || leveltype == DTYPE_TOWN || player.position.offset2 == player.position.CalculateWalkingOffsetShifted8(player._pdir, player.AnimInfo, true)); - if (player._plid == NO_LIGHT) return; const Light *l = &Lights[player._plid]; - WorldTileDisplacement offset = player.position.offset; + WorldTileDisplacement offset = player.position.CalculateWalkingOffset(player._pdir, player.AnimInfo); int x = 2 * offset.deltaY + offset.deltaX; int y = 2 * offset.deltaY - offset.deltaX; @@ -273,14 +260,14 @@ constexpr _sfx_id herosounds[enum_size::value][enum_size: constexpr std::array WalkSettings { { // clang-format off - { Direction::South, { 1, 1 }, { 0, -32 }, { 0, 0 }, PM_WALK_SOUTHWARDS, WalkSouthwards }, - { Direction::SouthWest, { 0, 1 }, { 32, -16 }, { 0, 0 }, PM_WALK_SOUTHWARDS, WalkSouthwards }, - { Direction::West, { -1, 1 }, { 32, -16 }, { 0, 1 }, PM_WALK_SIDEWAYS, WalkSideways }, - { Direction::NorthWest, { -1, 0 }, { 0, 0 }, { 0, 0 }, PM_WALK_NORTHWARDS, WalkNorthwards }, - { Direction::North, { -1, -1 }, { 0, 0 }, { 0, 0 }, PM_WALK_NORTHWARDS, WalkNorthwards }, - { Direction::NorthEast, { 0, -1 }, { 0, 0 }, { 0, 0 }, PM_WALK_NORTHWARDS, WalkNorthwards }, - { Direction::East, { 1, -1 }, { -32, -16 }, { 1, 0 }, PM_WALK_SIDEWAYS, WalkSideways }, - { Direction::SouthEast, { 1, 0 }, { -32, -16 }, { 0, 0 }, PM_WALK_SOUTHWARDS, WalkSouthwards } + { Direction::South, { 1, 1 }, { 0, 0 }, PM_WALK_SOUTHWARDS, WalkSouthwards }, + { Direction::SouthWest, { 0, 1 }, { 0, 0 }, PM_WALK_SOUTHWARDS, WalkSouthwards }, + { Direction::West, { -1, 1 }, { 0, 1 }, PM_WALK_SIDEWAYS, WalkSideways }, + { Direction::NorthWest, { -1, 0 }, { 0, 0 }, PM_WALK_NORTHWARDS, WalkNorthwards }, + { Direction::North, { -1, -1 }, { 0, 0 }, PM_WALK_NORTHWARDS, WalkNorthwards }, + { Direction::NorthEast, { 0, -1 }, { 0, 0 }, PM_WALK_NORTHWARDS, WalkNorthwards }, + { Direction::East, { 1, -1 }, { 1, 0 }, PM_WALK_SIDEWAYS, WalkSideways }, + { Direction::SouthEast, { 1, 0 }, { 0, 0 }, PM_WALK_SOUTHWARDS, WalkSouthwards } // clang-format on } }; @@ -303,7 +290,7 @@ bool PlrDirOK(const Player &player, Direction dir) return true; } -void HandleWalkMode(Player &player, Displacement vel, Direction dir) +void HandleWalkMode(Player &player, Direction dir) { const auto &dirModeParams = WalkSettings[static_cast(dir)]; SetPlayerOld(player); @@ -311,16 +298,13 @@ void HandleWalkMode(Player &player, Displacement vel, Direction dir) return; } - player.position.offset = dirModeParams.offset; // Offset player sprite to align with their previous tile position // The player's tile position after finishing this movement action player.position.future = player.position.tile + dirModeParams.tileAdd; dirModeParams.walkModeHandler(player, dirModeParams); - player.position.velocity = vel; player.tempDirection = dirModeParams.dir; player._pmode = dirModeParams.walkMode; - player.position.offset2 = dirModeParams.offset * 256; player._pdir = dir; } @@ -338,14 +322,14 @@ void StartWalkAnimation(Player &player, Direction dir, bool pmWillBeCalled) /** * @brief Start moving a player to a new tile */ -void StartWalk(Player &player, Displacement vel, Direction dir, bool pmWillBeCalled) +void StartWalk(Player &player, Direction dir, bool pmWillBeCalled) { if (player._pInvincible && player._pHitPoints == 0 && &player == MyPlayer) { SyncPlrKill(player, -1); return; } - HandleWalkMode(player, vel, dir); + HandleWalkMode(player, dir); StartWalkAnimation(player, dir, pmWillBeCalled); } @@ -354,14 +338,12 @@ void ClearStateVariables(Player &player) player.position.temp = { 0, 0 }; player.tempDirection = Direction::South; player.queuedSpell.spellLevel = 0; - player.position.offset2 = { 0, 0 }; } void StartWalkStand(Player &player) { player._pmode = PM_STAND; player.position.future = player.position.tile; - player.position.offset = { 0, 0 }; if (&player == MyPlayer) { ViewPosition = player.position.tile; @@ -370,23 +352,6 @@ void StartWalkStand(Player &player) void ChangeOffset(Player &player) { - int px = player.position.offset2.deltaX / 256; - int py = player.position.offset2.deltaY / 256; - - player.position.offset2 += player.position.velocity; - - if (leveltype == DTYPE_TOWN && sgGameInitInfo.bRunInTown != 0) { - player.position.offset2 += player.position.velocity; - } - - player.position.offset = DisplacementOf { - static_cast(player.position.offset2.deltaX >> 8), - static_cast(player.position.offset2.deltaY >> 8) - }; - - px -= player.position.offset2.deltaX >> 8; - py -= player.position.offset2.deltaY >> 8; - PmChangeLightOff(player); } @@ -1402,39 +1367,30 @@ void CheckNewPath(Player &player, bool pmWillBeCalled) } } - int xvel3 = 2048; - int xvel = 1024; - int yvel = 512; - if (leveltype != DTYPE_TOWN) { - xvel3 = PWVel[static_cast(player._pClass)][0]; - xvel = PWVel[static_cast(player._pClass)][1]; - yvel = PWVel[static_cast(player._pClass)][2]; - } - switch (player.walkpath[0]) { case WALK_N: - StartWalk(player, { 0, -xvel }, Direction::North, pmWillBeCalled); + StartWalk(player, Direction::North, pmWillBeCalled); break; case WALK_NE: - StartWalk(player, { xvel, -yvel }, Direction::NorthEast, pmWillBeCalled); + StartWalk(player, Direction::NorthEast, pmWillBeCalled); break; case WALK_E: - StartWalk(player, { xvel3, 0 }, Direction::East, pmWillBeCalled); + StartWalk(player, Direction::East, pmWillBeCalled); break; case WALK_SE: - StartWalk(player, { xvel, yvel }, Direction::SouthEast, pmWillBeCalled); + StartWalk(player, Direction::SouthEast, pmWillBeCalled); break; case WALK_S: - StartWalk(player, { 0, xvel }, Direction::South, pmWillBeCalled); + StartWalk(player, Direction::South, pmWillBeCalled); break; case WALK_SW: - StartWalk(player, { -xvel, yvel }, Direction::SouthWest, pmWillBeCalled); + StartWalk(player, Direction::SouthWest, pmWillBeCalled); break; case WALK_W: - StartWalk(player, { -xvel3, 0 }, Direction::West, pmWillBeCalled); + StartWalk(player, Direction::West, pmWillBeCalled); break; case WALK_NW: - StartWalk(player, { -xvel, -yvel }, Direction::NorthWest, pmWillBeCalled); + StartWalk(player, Direction::NorthWest, pmWillBeCalled); break; } @@ -2729,9 +2685,6 @@ void InitPlayer(Player &player, bool firstTime) SetPlrAnims(player); - player.position.offset = { 0, 0 }; - player.position.velocity = { 0, 0 }; - ClearStateVariables(player); if (player._pHitPoints >> 6 > 0) { @@ -2833,7 +2786,6 @@ void SetPlayerOld(Player &player) void FixPlayerLocation(Player &player, Direction bDir) { player.position.future = player.position.tile; - player.position.offset = { 0, 0 }; player._pdir = bDir; if (&player == MyPlayer) { ViewPosition = player.position.tile; @@ -3307,10 +3259,6 @@ void ProcessPlayers() player.previewCelSprite = std::nullopt; if (player._pmode != PM_DEATH || player.AnimInfo.tickCounterOfCurrentFrame != 40) player.AnimInfo.processAnimation(); - - assert(!player.IsWalking() || leveltype == DTYPE_TOWN || player.position.velocity == player.position.GetWalkingVelocityShifted8(player._pdir, player.AnimInfo)); - assert(!player.IsWalking() || leveltype == DTYPE_TOWN || player.position.offset == player.position.CalculateWalkingOffset(player._pdir, player.AnimInfo)); - assert(!player.IsWalking() || leveltype == DTYPE_TOWN || player.position.offset2 == player.position.CalculateWalkingOffsetShifted8(player._pdir, player.AnimInfo)); } } } diff --git a/test/fixtures/timedemo/WarriorLevel1to2/demo_0_reference_spawn_0.sv b/test/fixtures/timedemo/WarriorLevel1to2/demo_0_reference_spawn_0.sv index e7a9c186c..40f3cb745 100644 Binary files a/test/fixtures/timedemo/WarriorLevel1to2/demo_0_reference_spawn_0.sv and b/test/fixtures/timedemo/WarriorLevel1to2/demo_0_reference_spawn_0.sv differ