From 62e9aa0448b4217caa42e48f072367ce56b4f117 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Mon, 14 Aug 2023 08:57:24 +0900 Subject: [PATCH] `MissilePosition`: Use `WorldTilePosition` Reduces struct size and makes the types of coordinates more obvious. --- Source/debug.cpp | 6 ++--- Source/engine/displacement.hpp | 2 +- Source/engine/render/scrollrt.cpp | 15 +++-------- Source/missiles.cpp | 42 +++++++++++++++---------------- Source/missiles.h | 16 ++++++------ Source/monster.cpp | 2 +- Source/player.cpp | 6 ++--- Source/spells.cpp | 7 +++--- Source/spells.h | 3 ++- 9 files changed, 45 insertions(+), 54 deletions(-) diff --git a/Source/debug.cpp b/Source/debug.cpp index c752ec3ec..28b7a8386 100644 --- a/Source/debug.cpp +++ b/Source/debug.cpp @@ -395,10 +395,8 @@ std::string DebugCmdVisitTowner(const std::string_view parameter) CastSpell( MyPlayerId, SpellID::Teleport, - myPlayer.position.tile.x, - myPlayer.position.tile.y, - towner.position.x, - towner.position.y, + myPlayer.position.tile, + towner.position, 1); return StrCat("Say hello to ", parameter, " from me."); diff --git a/Source/engine/displacement.hpp b/Source/engine/displacement.hpp index d9535db30..2c3bde90b 100644 --- a/Source/engine/displacement.hpp +++ b/Source/engine/displacement.hpp @@ -341,7 +341,7 @@ constexpr DisplacementOf operator>>(DisplacementOf constexpr DisplacementOf abs(DisplacementOf a) { - return { std::abs(a.deltaX), std::abs(a.deltaY) }; + return DisplacementOf(std::abs(a.deltaX), std::abs(a.deltaY)); } template diff --git a/Source/engine/render/scrollrt.cpp b/Source/engine/render/scrollrt.cpp index ae866b9fb..10ab6c042 100644 --- a/Source/engine/render/scrollrt.cpp +++ b/Source/engine/render/scrollrt.cpp @@ -20,6 +20,7 @@ #include "engine/render/dun_render.hpp" #include "engine/render/text_render.hpp" #include "engine/trn.hpp" +#include "engine/world_tile.hpp" #include "error.h" #include "gmenu.h" #include "help.h" @@ -75,20 +76,10 @@ bool frameflag; namespace { -/** - * @brief Hash algorithm for point - */ -struct PointHash { - std::size_t operator()(Point const &s) const noexcept - { - return s.x ^ (s.y << 1); - } -}; - /** * @brief Contains all Missile at rendering position */ -std::unordered_multimap MissilesAtRenderingTile; +std::unordered_multimap MissilesAtRenderingTile; /** * @brief Could the missile (at the next game tick) collide? This method is a simplified version of CheckMissileCol (for example without random). @@ -295,7 +286,7 @@ void DrawMissilePrivate(const Surface &out, const Missile &missile, Point target * @param targetBufferPosition Output buffer coordinates * @param pre Is the sprite in the background */ -void DrawMissile(const Surface &out, Point tilePosition, Point targetBufferPosition, bool pre) +void DrawMissile(const Surface &out, WorldTilePosition tilePosition, Point targetBufferPosition, bool pre) { const auto [begin, end] = MissilesAtRenderingTile.equal_range(tilePosition); for (auto it = begin; it != end; ++it) { diff --git a/Source/missiles.cpp b/Source/missiles.cpp index b99177349..7ad2d3cf5 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -104,7 +104,7 @@ constexpr Direction16 Direction16Flip(Direction16 x, Direction16 pivot) return static_cast(ret); } -void UpdateMissileVelocity(Missile &missile, Point destination, int velocityInPixels) +void UpdateMissileVelocity(Missile &missile, WorldTilePosition destination, int velocityInPixels) { missile.position.velocity = { 0, 0 }; @@ -112,7 +112,7 @@ void UpdateMissileVelocity(Missile &missile, Point destination, int velocityInPi return; // Get the normalized vector in isometric projection - Displacement fixed16NormalVector = (missile.position.tile - destination).worldToNormalScreen(); + Displacement fixed16NormalVector = (Point { missile.position.tile } - Point { destination }).worldToNormalScreen(); // Multiplying by the target velocity gives us a scaled velocity vector. missile.position.velocity = fixed16NormalVector * velocityInPixels; @@ -1153,8 +1153,8 @@ void InitMissiles() void AddOpenNest(Missile &missile, AddMissileParameter ¶meter) { - for (int x : { 80, 81 }) { - for (int y : { 62, 63 }) { + for (WorldTileCoord x : { 80, 81 }) { + for (WorldTileCoord y : { 62, 63 }) { AddMissile({ x, y }, { 80, 62 }, parameter.midir, MissileID::BigExplosion, missile._micaster, missile._misource, missile._midam, 0); } } @@ -1534,7 +1534,7 @@ void AddBigExplosion(Missile &missile, AddMissileParameter & /*parameter*/) void AddImmolation(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; if (missile.position.start == parameter.dst) { dst += parameter.midir; } @@ -1550,7 +1550,7 @@ void AddImmolation(Missile &missile, AddMissileParameter ¶meter) void AddLightningBow(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; if (missile.position.start == parameter.dst) { dst += parameter.midir; } @@ -1634,7 +1634,7 @@ void AddSearch(Missile &missile, AddMissileParameter & /*parameter*/) void AddChargedBoltBow(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; missile._mirnd = GenerateRnd(15) + 1; if (missile._micaster != TARGET_MONSTERS) { missile._midam = 15; @@ -1653,7 +1653,7 @@ void AddChargedBoltBow(Missile &missile, AddMissileParameter ¶meter) void AddElementalArrow(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; if (missile.position.start == dst) { dst += parameter.midir; } @@ -1690,7 +1690,7 @@ void AddElementalArrow(Missile &missile, AddMissileParameter ¶meter) void AddArrow(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; if (missile.position.start == dst) { dst += parameter.midir; } @@ -1730,7 +1730,7 @@ void UpdateVileMissPos(Missile &missile, Point dst) for (int i = -k; i <= k; i++) { int xx = i + dst.x; if (PosOkPlayer(*MyPlayer, { xx, yy })) { - missile.position.tile = { xx, yy }; + missile.position.tile = WorldTilePosition(xx, yy); return; } } @@ -1778,7 +1778,7 @@ void AddPhasing(Missile &missile, AddMissileParameter ¶meter) void AddFirebolt(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; if (missile.position.start == dst) { dst += parameter.midir; } @@ -1865,7 +1865,7 @@ void AddNovaBall(Missile &missile, AddMissileParameter ¶meter) UpdateMissileVelocity(missile, parameter.dst, 16); missile._miAnimFrame = GenerateRnd(8) + 1; missile._mirange = 255; - const Point position { missile._misource < 0 ? missile.position.start : Point(Players[missile._misource].position.tile) }; + const WorldTilePosition position = missile._misource < 0 ? missile.position.start : Players[missile._misource].position.tile; missile.var1 = position.x; missile.var2 = position.y; } @@ -1888,7 +1888,7 @@ void AddFireWall(Missile &missile, AddMissileParameter ¶meter) void AddFireball(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; if (missile.position.start == dst) { dst += parameter.midir; } @@ -2194,7 +2194,7 @@ void AddRhino(Missile &missile, AddMissileParameter ¶meter) void AddGenericMagicMissile(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; if (missile.position.start == dst) { dst += parameter.midir; } @@ -2394,7 +2394,7 @@ void AddHealOther(Missile &missile, AddMissileParameter & /*parameter*/) void AddElemental(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; if (missile.position.start == dst) { dst += parameter.midir; } @@ -2592,7 +2592,7 @@ void AddInferno(Missile &missile, AddMissileParameter ¶meter) void AddInfernoControl(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; if (missile.position.start == parameter.dst) { dst += parameter.midir; } @@ -2604,7 +2604,7 @@ void AddInfernoControl(Missile &missile, AddMissileParameter ¶meter) void AddChargedBolt(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; missile._mirnd = GenerateRnd(15) + 1; missile._midam = (missile._micaster == TARGET_MONSTERS) ? (GenerateRnd(Players[missile._misource]._pMagic / 4) + 1) : 15; @@ -2622,7 +2622,7 @@ void AddChargedBolt(Missile &missile, AddMissileParameter ¶meter) void AddHolyBolt(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; if (missile.position.start == dst) { dst += parameter.midir; } @@ -2672,7 +2672,7 @@ void AddTelekinesis(Missile &missile, AddMissileParameter & /*parameter*/) void AddBoneSpirit(Missile &missile, AddMissileParameter ¶meter) { - Point dst = parameter.dst; + WorldTilePosition dst = parameter.dst; if (missile.position.start == dst) { dst += parameter.midir; } @@ -2706,7 +2706,7 @@ void AddDiabloApocalypse(Missile &missile, AddMissileParameter & /*parameter*/) missile._miDelFlag = true; } -Missile *AddMissile(Point src, Point dst, Direction midir, MissileID mitype, +Missile *AddMissile(WorldTilePosition src, WorldTilePosition dst, Direction midir, MissileID mitype, mienemy_type micaster, int id, int midam, int spllvl, Missile *parent, std::optional<_sfx_id> lSFX) { @@ -3789,7 +3789,7 @@ void ProcessApocalypse(Missile &missile) continue; int id = missile._misource; - AddMissile({ k, j }, { k, j }, Players[id]._pdir, MissileID::ApocalypseBoom, TARGET_MONSTERS, id, missile._midam, 0); + AddMissile(WorldTilePosition(k, j), WorldTilePosition(k, j), Players[id]._pdir, MissileID::ApocalypseBoom, TARGET_MONSTERS, id, missile._midam, 0); missile.var2 = j; missile.var4 = k + 1; return; diff --git a/Source/missiles.h b/Source/missiles.h index 1ef1fe8fe..69d5ed85e 100644 --- a/Source/missiles.h +++ b/Source/missiles.h @@ -11,6 +11,7 @@ #include "engine.h" #include "engine/point.hpp" +#include "engine/world_tile.hpp" #include "misdat.h" #include "monster.h" #include "player.h" @@ -21,20 +22,21 @@ namespace devilution { constexpr WorldTilePosition GolemHoldingCell = Point { 1, 0 }; struct MissilePosition { - Point tile; /** Sprite's pixel offset from tile. */ Displacement offset; /** Pixel velocity while moving */ Displacement velocity; - /** Start position */ - Point start; - /** Start position */ + /** Pixels traveled as a numerator of 65,536. */ Displacement traveled; + WorldTilePosition tile; + /** Start position */ + WorldTilePosition start; + /** * @brief Specifies the location (tile) while rendering */ - Point tileForRendering; + WorldTilePosition tileForRendering; /** * @brief Specifies the location (offset) while rendering */ @@ -240,7 +242,7 @@ inline void SetMissDir(Missile &missile, Direction16 dir) void InitMissiles(); struct AddMissileParameter { - Point dst; + WorldTilePosition dst; Direction midir; Missile *pParent; bool spellFizzled; @@ -390,7 +392,7 @@ void AddTelekinesis(Missile &missile, AddMissileParameter ¶meter); void AddBoneSpirit(Missile &missile, AddMissileParameter ¶meter); void AddRedPortal(Missile &missile, AddMissileParameter ¶meter); void AddDiabloApocalypse(Missile &missile, AddMissileParameter ¶meter); -Missile *AddMissile(Point src, Point dst, Direction midir, MissileID mitype, +Missile *AddMissile(WorldTilePosition src, WorldTilePosition dst, Direction midir, MissileID mitype, mienemy_type micaster, int id, int midam, int spllvl, Missile *parent = nullptr, std::optional<_sfx_id> lSFX = std::nullopt); void ProcessElementalArrow(Missile &missile); diff --git a/Source/monster.cpp b/Source/monster.cpp index 08999f6c0..acf83841d 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -2366,7 +2366,7 @@ void BatAi(Monster &monster) monster.goal = MonsterGoal::Retreat; monster.goalVar1 = 0; if (monster.type().type == MT_FAMILIAR) { - AddMissile(monster.enemyPosition, { monster.enemyPosition.x + 1, 0 }, Direction::South, MissileID::Lightning, TARGET_PLAYERS, monster.getId(), GenerateRnd(10) + 1, 0); + AddMissile(monster.enemyPosition, monster.enemyPosition + Direction::SouthEast, Direction::South, MissileID::Lightning, TARGET_PLAYERS, monster.getId(), GenerateRnd(10) + 1, 0); } } diff --git a/Source/player.cpp b/Source/player.cpp index 859253416..a71164741 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -1058,10 +1058,8 @@ bool DoSpell(Player &player) CastSpell( player.getId(), player.executedSpell.spellId, - player.position.tile.x, - player.position.tile.y, - player.position.temp.x, - player.position.temp.y, + player.position.tile, + player.position.temp, player.executedSpell.spellLevel); if (IsAnyOf(player.executedSpell.spellType, SpellType::Scroll, SpellType::Charges)) { diff --git a/Source/spells.cpp b/Source/spells.cpp index d76846ef1..ec73f1bd3 100644 --- a/Source/spells.cpp +++ b/Source/spells.cpp @@ -13,6 +13,7 @@ #include "engine/backbuffer_state.hpp" #include "engine/point.hpp" #include "engine/random.hpp" +#include "engine/world_tile.hpp" #include "gamemenu.h" #include "inv.h" #include "missiles.h" @@ -208,7 +209,7 @@ SpellCheckResult CheckSpell(const Player &player, SpellID sn, SpellType st, bool return SpellCheckResult::Success; } -void CastSpell(int id, SpellID spl, int sx, int sy, int dx, int dy, int spllvl) +void CastSpell(int id, SpellID spl, WorldTilePosition src, WorldTilePosition dst, int spllvl) { Player &player = Players[id]; Direction dir = player._pdir; @@ -219,12 +220,12 @@ void CastSpell(int id, SpellID spl, int sx, int sy, int dx, int dy, int spllvl) bool fizzled = false; const SpellData &spellData = GetSpellData(spl); for (size_t i = 0; i < sizeof(spellData.sMissiles) / sizeof(spellData.sMissiles[0]) && spellData.sMissiles[i] != MissileID::Null; i++) { - Missile *missile = AddMissile({ sx, sy }, { dx, dy }, dir, spellData.sMissiles[i], TARGET_MONSTERS, id, 0, spllvl); + Missile *missile = AddMissile(src, dst, dir, spellData.sMissiles[i], TARGET_MONSTERS, id, 0, spllvl); fizzled |= (missile == nullptr); } if (spl == SpellID::ChargedBolt) { for (int i = (spllvl / 2) + 3; i > 0; i--) { - Missile *missile = AddMissile({ sx, sy }, { dx, dy }, dir, MissileID::ChargedBolt, TARGET_MONSTERS, id, 0, spllvl); + Missile *missile = AddMissile(src, dst, dir, MissileID::ChargedBolt, TARGET_MONSTERS, id, 0, spllvl); fizzled |= (missile == nullptr); } } diff --git a/Source/spells.h b/Source/spells.h index 671410046..925231861 100644 --- a/Source/spells.h +++ b/Source/spells.h @@ -7,6 +7,7 @@ #include +#include "engine/world_tile.hpp" #include "player.h" namespace devilution { @@ -34,7 +35,7 @@ SpellCheckResult CheckSpell(const Player &player, SpellID sn, SpellType st, bool * @param player The player whose readied spell is to be checked. */ void EnsureValidReadiedSpell(Player &player); -void CastSpell(int id, SpellID spl, int sx, int sy, int dx, int dy, int spllvl); +void CastSpell(int id, SpellID spl, WorldTilePosition src, WorldTilePosition dst, int spllvl); /** * @param pnum player index