Browse Source

`MissilePosition`: Use `WorldTilePosition`

Reduces struct size and makes the types of coordinates more obvious.
pull/6529/head
Gleb Mazovetskiy 3 years ago
parent
commit
62e9aa0448
  1. 6
      Source/debug.cpp
  2. 2
      Source/engine/displacement.hpp
  3. 15
      Source/engine/render/scrollrt.cpp
  4. 42
      Source/missiles.cpp
  5. 16
      Source/missiles.h
  6. 2
      Source/monster.cpp
  7. 6
      Source/player.cpp
  8. 7
      Source/spells.cpp
  9. 3
      Source/spells.h

6
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.");

2
Source/engine/displacement.hpp

@ -341,7 +341,7 @@ constexpr DisplacementOf<DisplacementDeltaT> operator>>(DisplacementOf<Displacem
template <typename DisplacementDeltaT>
constexpr DisplacementOf<DisplacementDeltaT> abs(DisplacementOf<DisplacementDeltaT> a)
{
return { std::abs(a.deltaX), std::abs(a.deltaY) };
return DisplacementOf<DisplacementDeltaT>(std::abs(a.deltaX), std::abs(a.deltaY));
}
template <typename DeltaT>

15
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<Point, Missile *, PointHash> MissilesAtRenderingTile;
std::unordered_multimap<WorldTilePosition, Missile *> 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) {

42
Source/missiles.cpp

@ -104,7 +104,7 @@ constexpr Direction16 Direction16Flip(Direction16 x, Direction16 pivot)
return static_cast<Direction16>(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 &parameter)
{
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 &parameter)
{
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 &parameter)
void AddLightningBow(Missile &missile, AddMissileParameter &parameter)
{
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 &parameter)
{
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 &parameter)
void AddElementalArrow(Missile &missile, AddMissileParameter &parameter)
{
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 &parameter)
void AddArrow(Missile &missile, AddMissileParameter &parameter)
{
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 &parameter)
void AddFirebolt(Missile &missile, AddMissileParameter &parameter)
{
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 &parameter)
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 &parameter)
void AddFireball(Missile &missile, AddMissileParameter &parameter)
{
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 &parameter)
void AddGenericMagicMissile(Missile &missile, AddMissileParameter &parameter)
{
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 &parameter)
{
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 &parameter)
void AddInfernoControl(Missile &missile, AddMissileParameter &parameter)
{
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 &parameter)
void AddChargedBolt(Missile &missile, AddMissileParameter &parameter)
{
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 &parameter)
void AddHolyBolt(Missile &missile, AddMissileParameter &parameter)
{
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 &parameter)
{
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;

16
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 &parameter);
void AddBoneSpirit(Missile &missile, AddMissileParameter &parameter);
void AddRedPortal(Missile &missile, AddMissileParameter &parameter);
void AddDiabloApocalypse(Missile &missile, AddMissileParameter &parameter);
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);

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

6
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)) {

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

3
Source/spells.h

@ -7,6 +7,7 @@
#include <cstdint>
#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

Loading…
Cancel
Save