Browse Source

ActorPosition: Remove offset, offset2 and velocity

pull/5169/head
obligaron 4 years ago committed by Anders Jenbo
parent
commit
2493f06116
  1. 2
      Source/automap.cpp
  2. 24
      Source/cursor.cpp
  3. 6
      Source/engine/actor_position.hpp
  4. 6
      Source/engine/render/scrollrt.cpp
  5. 58
      Source/loadsave.cpp
  6. 122
      Source/monster.cpp
  7. 94
      Source/player.cpp
  8. BIN
      test/fixtures/timedemo/WarriorLevel1to2/demo_0_reference_spawn_0.sv

2
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);

24
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<int16_t> offset2 = myPlayer.position.CalculateWalkingOffsetShifted8(myPlayer._pdir, myPlayer.AnimInfo);
DisplacementOf<int16_t> 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;
}

6
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<int8_t> offset;
/** Same as offset but contains the value in a higher range */
DisplacementOf<int16_t> offset2;
/** Pixel velocity while walking. Indirectly applied to offset via _pvar6/7 */
DisplacementOf<int16_t> velocity;
/** @brief Calculates the offset for the walking animation. */
DisplacementOf<int8_t> CalculateWalkingOffset(Direction dir, const AnimationInfo &animInfo, bool pendingProcessAnimation = false) const;

6
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);
}

58
Source/loadsave.cpp

@ -342,10 +342,7 @@ void LoadPlayer(LoadHelper &file, Player &player)
player.position.last.y = file.NextLE<int32_t>();
player.position.old.x = file.NextLE<int32_t>();
player.position.old.y = file.NextLE<int32_t>();
player.position.offset.deltaX = file.NextLE<int32_t>();
player.position.offset.deltaY = file.NextLE<int32_t>();
player.position.velocity.deltaX = file.NextLE<int32_t>();
player.position.velocity.deltaY = file.NextLE<int32_t>();
file.Skip<int32_t>(4); // Skip offset and velocity
player._pdir = static_cast<Direction>(file.NextLE<int32_t>());
file.Skip(4); // Unused
player._pgfxnum = file.NextLE<int32_t>();
@ -446,8 +443,7 @@ void LoadPlayer(LoadHelper &file, Player &player)
player.tempDirection = static_cast<Direction>(file.NextLE<int32_t>());
player.queuedSpell.spellLevel = file.NextLE<int32_t>();
file.Skip<uint32_t>(); // 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<int32_t>();
player.position.offset2.deltaY = file.NextLE<int32_t>();
file.Skip<int32_t>(2); // skip offset2;
file.Skip<uint32_t>(); // 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<int32_t>();
monster.position.old.x = file->NextLE<int32_t>();
monster.position.old.y = file->NextLE<int32_t>();
monster.position.offset.deltaX = file->NextLE<int32_t>();
monster.position.offset.deltaY = file->NextLE<int32_t>();
monster.position.velocity.deltaX = file->NextLE<int32_t>();
monster.position.velocity.deltaY = file->NextLE<int32_t>();
file->Skip<int32_t>(4); // Skip offset and velocity
monster.direction = static_cast<Direction>(file->NextLE<int32_t>());
monster.enemy = file->NextLE<int32_t>();
monster.enemyPosition.x = file->NextLE<uint8_t>();
@ -614,9 +607,8 @@ void LoadMonster(LoadHelper *file, Monster &monster)
monster.var3 = file->NextLENarrow<int32_t, int8_t>();
monster.position.temp.x = file->NextLENarrow<int32_t, WorldTileCoord>();
monster.position.temp.y = file->NextLENarrow<int32_t, WorldTileCoord>();
monster.position.offset2.deltaX = file->NextLE<int32_t>();
monster.position.offset2.deltaY = file->NextLE<int32_t>();
file->Skip(4); // Skip actionFrame
file->Skip<int32_t>(2); // skip offset2;
file->Skip(4); // Skip actionFrame
monster.maxHitPoints = file->NextLE<int32_t>();
monster.hitPoints = file->NextLE<int32_t>();
@ -1109,10 +1101,18 @@ void SavePlayer(SaveHelper &file, const Player &player)
file.WriteLE<int32_t>(player.position.last.y);
file.WriteLE<int32_t>(player.position.old.x);
file.WriteLE<int32_t>(player.position.old.y);
file.WriteLE<int32_t>(player.position.offset.deltaX);
file.WriteLE<int32_t>(player.position.offset.deltaY);
file.WriteLE<int32_t>(player.position.velocity.deltaX);
file.WriteLE<int32_t>(player.position.velocity.deltaY);
DisplacementOf<int16_t> offset = {};
DisplacementOf<int16_t> offset2 = {};
DisplacementOf<int16_t> 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<int32_t>(offset.deltaX);
file.WriteLE<int32_t>(offset.deltaY);
file.WriteLE<int32_t>(velocity.deltaX);
file.WriteLE<int32_t>(velocity.deltaY);
file.WriteLE<int32_t>(static_cast<int32_t>(player._pdir));
file.Skip(4); // Unused
file.WriteLE<int32_t>(player._pgfxnum);
@ -1218,8 +1218,8 @@ void SavePlayer(SaveHelper &file, const Player &player)
file.WriteLE<int32_t>(static_cast<int32_t>(player.tempDirection));
file.WriteLE<int32_t>(player.queuedSpell.spellLevel);
file.Skip<int32_t>(); // skip _pVar5, was used for storing position of a tile which should have its HorizontalMovingPlayer flag removed after walking
file.WriteLE<int32_t>(player.position.offset2.deltaX);
file.WriteLE<int32_t>(player.position.offset2.deltaY);
file.WriteLE<int32_t>(offset2.deltaX);
file.WriteLE<int32_t>(offset2.deltaY);
file.Skip<int32_t>(); // Skip _pVar8
for (uint8_t i = 0; i < giNumberOfLevels; i++)
file.WriteLE<uint8_t>(player._pLvlVisited[i] ? 1 : 0);
@ -1342,10 +1342,18 @@ void SaveMonster(SaveHelper *file, Monster &monster)
file->WriteLE<int32_t>(monster.position.future.y);
file->WriteLE<int32_t>(monster.position.old.x);
file->WriteLE<int32_t>(monster.position.old.y);
file->WriteLE<int32_t>(monster.position.offset.deltaX);
file->WriteLE<int32_t>(monster.position.offset.deltaY);
file->WriteLE<int32_t>(monster.position.velocity.deltaX);
file->WriteLE<int32_t>(monster.position.velocity.deltaY);
DisplacementOf<int16_t> offset = {};
DisplacementOf<int16_t> offset2 = {};
DisplacementOf<int16_t> 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<int32_t>(offset.deltaX);
file->WriteLE<int32_t>(offset.deltaY);
file->WriteLE<int32_t>(velocity.deltaX);
file->WriteLE<int32_t>(velocity.deltaY);
file->WriteLE<int32_t>(static_cast<int32_t>(monster.direction));
file->WriteLE<int32_t>(monster.enemy);
file->WriteLE<uint8_t>(monster.enemyPosition.x);
@ -1364,8 +1372,8 @@ void SaveMonster(SaveHelper *file, Monster &monster)
file->WriteLE<int32_t>(monster.var3);
file->WriteLE<int32_t>(monster.position.temp.x);
file->WriteLE<int32_t>(monster.position.temp.y);
file->WriteLE<int32_t>(monster.position.offset2.deltaX);
file->WriteLE<int32_t>(monster.position.offset2.deltaY);
file->WriteLE<int32_t>(offset2.deltaX);
file->WriteLE<int32_t>(offset2.deltaY);
file->Skip<int32_t>(); // Skip _mVar8
file->WriteLE<int32_t>(monster.maxHitPoints);
file->WriteLE<int32_t>(monster.hitPoints);

122
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<Direction>(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<WorldTileCoord>(xadd + monster.position.tile.x);
const auto fy = static_cast<WorldTileCoord>(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<int16_t> { static_cast<int16_t>(xvel), static_cast<int16_t>(yvel) };
monster.var1 = xadd;
monster.var2 = yadd;
monster.var3 = static_cast<int>(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<WorldTileCoord>(xadd + monster.position.tile.x);
const auto fy = static_cast<WorldTileCoord>(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<int16_t> { static_cast<int16_t>(xoff), static_cast<int16_t>(yoff) };
monster.mode = MonsterMode::MoveSouthwards;
monster.position.velocity = DisplacementOf<int16_t> { static_cast<int16_t>(xvel), static_cast<int16_t>(yvel) };
monster.var3 = static_cast<int>(endDir);
NewMonsterAnim(monster, MonsterGraphic::Walk, endDir, AnimationDistributionFlags::ProcessAnimationPending, -1);
monster.position.offset2 = DisplacementOf<int16_t> { static_cast<int16_t>(16 * xoff), static_cast<int16_t>(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<WorldTileCoord>(xadd + monster.position.tile.x);
const auto fy = static_cast<WorldTileCoord>(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<int16_t> { static_cast<int16_t>(xoff), static_cast<int16_t>(yoff) };
monster.mode = MonsterMode::MoveSideways;
monster.position.velocity = DisplacementOf<int16_t> { static_cast<int16_t>(xvel), static_cast<int16_t>(yvel) };
monster.var1 = fx;
monster.var2 = fy;
monster.var3 = static_cast<int>(endDir);
NewMonsterAnim(monster, MonsterGraphic::Walk, endDir, AnimationDistributionFlags::ProcessAnimationPending, -1);
monster.position.offset2 = DisplacementOf<int16_t> { static_cast<int16_t>(16 * xoff), static_cast<int16_t>(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<int>(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();

94
Source/player.cpp

@ -166,7 +166,6 @@ namespace {
struct DirectionSettings {
Direction dir;
DisplacementOf<int8_t> tileAdd;
DisplacementOf<int16_t> offset;
DisplacementOf<int8_t> map;
PLR_MODE walkMode;
void (*walkModeHandler)(Player &, const DirectionSettings &);
@ -181,15 +180,7 @@ constexpr int8_t PlrGFXAnimLens[enum_size<HeroClass>::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<HeroClass>::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<HeroClass>::value][enum_size<HeroSpeech>:
constexpr std::array<const DirectionSettings, 8> 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<size_t>(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<int8_t> {
static_cast<int8_t>(player.position.offset2.deltaX >> 8),
static_cast<int8_t>(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<std::size_t>(player._pClass)][0];
xvel = PWVel[static_cast<std::size_t>(player._pClass)][1];
yvel = PWVel[static_cast<std::size_t>(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));
}
}
}

BIN
test/fixtures/timedemo/WarriorLevel1to2/demo_0_reference_spawn_0.sv vendored

Binary file not shown.
Loading…
Cancel
Save