From 4e62d647f759b252371879416cdf4c844d746bd6 Mon Sep 17 00:00:00 2001 From: Joris <Joris.dauphin@gmail.com> Date: Sat, 5 Feb 2011 22:50:44 +0100 Subject: [PATCH] Fix casting range. Fix missile by introducing PixelPos (instead of Vec2i). --- src/action/action_spellcast.cpp | 5 +-- src/action/command.cpp | 1 - src/include/actions.h | 6 +++- src/include/editor.h | 6 ++-- src/include/missile.h | 32 +++++++++---------- src/include/unit.h | 17 ++++++++++ src/include/vec2i.h | 55 ++++++++++++++++++++------------ src/stratagus/missile.cpp | 45 +++++++++++++------------- src/stratagus/script_missile.cpp | 6 ++-- src/unit/unit.cpp | 14 ++++++++ 10 files changed, 117 insertions(+), 70 deletions(-) diff --git a/src/action/action_spellcast.cpp b/src/action/action_spellcast.cpp index 92e8c4eb7..ed43de9c6 100644 --- a/src/action/action_spellcast.cpp +++ b/src/action/action_spellcast.cpp @@ -110,7 +110,6 @@ static void SpellMoveToTarget(CUnit &unit) goal = order->GetGoal(); if (goal && unit.MapDistanceTo(*goal) <= order->Range) { - // there is goal and it is in range unit.State = 0; UnitHeadingFromDeltaXY(unit, goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos); @@ -118,9 +117,7 @@ static void SpellMoveToTarget(CUnit &unit) return; } else if (!goal && unit.MapDistanceTo(order->goalPos.x, order->goalPos.y) <= order->Range) { // there is no goal and target spot is in range - const Vec2i diag = {order->Arg1.Spell->Range, order->Arg1.Spell->Range}; - - UnitHeadingFromDeltaXY(unit, order->goalPos + diag - unit.tilePos); + UnitHeadingFromDeltaXY(unit, order->goalPos - unit.tilePos); unit.SubAction++; // cast the spell return; } else if (err == PF_UNREACHABLE) { diff --git a/src/action/command.cpp b/src/action/command.cpp index ef70c97d5..a7f88f119 100644 --- a/src/action/command.cpp +++ b/src/action/command.cpp @@ -1078,7 +1078,6 @@ void CommandSpellCast(CUnit &unit, const Vec2i &pos, CUnit *dest, SpellType *spe order->SetGoal(dest); } } else { - order->Range = 1; order->goalPos = pos; } order->Arg1.Spell = spell; diff --git a/src/include/actions.h b/src/include/actions.h index b1332f442..100e63215 100644 --- a/src/include/actions.h +++ b/src/include/actions.h @@ -36,6 +36,10 @@ #include "unit_cache.h" #endif +#ifndef __VEC2I_H__ +#include "vec2i.h" +#endif + //#include "vec2i.h" /*---------------------------------------------------------------------------- @@ -54,7 +58,7 @@ class CUnitType; class CUpgrade; class SpellType; class CAnimation; -class Vec2i; + /*---------------------------------------------------------------------------- -- Variables diff --git a/src/include/editor.h b/src/include/editor.h index d859381cc..4db142339 100644 --- a/src/include/editor.h +++ b/src/include/editor.h @@ -37,13 +37,15 @@ #include <string> #include "player.h" #include "icons.h" - +#ifndef __VEC2I_H__ +#include "vec2i.h" +#endif /*---------------------------------------------------------------------------- -- Declarations ----------------------------------------------------------------------------*/ class CUnitType; -class Vec2i; + enum EditorRunningType { EditorNotRunning = 0, /// Not Running diff --git a/src/include/missile.h b/src/include/missile.h index d089225fe..13d4a938f 100644 --- a/src/include/missile.h +++ b/src/include/missile.h @@ -383,10 +383,10 @@ public: /// load the graphics for a missile type void LoadMissileSprite(); - void Init(void); - void DrawMissileType(int frame, const Vec2i &pos) const; + void Init(); + void DrawMissileType(int frame, const PixelPos &pos) const; void DrawMissileType(int frame, int x, int y) const { - Vec2i pos = {x, y}; + PixelPos pos = {x, y}; DrawMissileType(frame, pos); } @@ -396,7 +396,7 @@ public: std::string Ident; /// missile name int Transparency; /// missile transparency - Vec2i size; /// missile size in pixels + PixelSize size; /// missile size in pixels int DrawLevel; /// Level to draw missile at int SpriteFrames; /// number of sprite frames in graphic int NumDirections; /// number of directions missile can face @@ -439,10 +439,10 @@ protected: public: virtual ~Missile() {}; - static Missile *Init(MissileType *mtype, const Vec2i &startPos, const Vec2i &destPos); + static Missile *Init(MissileType *mtype, const PixelPos &startPos, const PixelPos &destPos); static Missile *Init(MissileType *mtype, int sx, int sy, int dx, int dy) { - Vec2i startPos = {sx, sy}; - Vec2i destPos = {dx, dy}; + PixelPos startPos = {sx, sy}; + PixelPos destPos = {dx, dy}; return Init(mtype, startPos, destPos); } @@ -452,9 +452,9 @@ public: void DrawMissile(const CViewport *vp) const; void SaveMissile(CFile *file) const; - Vec2i source; /// Missile source position - Vec2i position; /// missile pixel position - Vec2i destination; /// missile pixel destination + PixelPos source; /// Missile source position + PixelPos position; /// missile pixel position + PixelPos destination; /// missile pixel destination MissileType *Type; /// missile-type pointer int SpriteFrame; /// sprite frame counter int State; /// state @@ -585,18 +585,18 @@ extern MissileType *NewMissileTypeSlot(const std::string& ident); /// Get missile-type by ident extern MissileType *MissileTypeByIdent(const std::string& ident); /// create a missile -extern Missile *MakeMissile(MissileType *mtype, const Vec2i &startPos, const Vec2i &destPos); +extern Missile *MakeMissile(MissileType *mtype, const PixelPos &startPos, const PixelPos &destPos); inline Missile *MakeMissile(MissileType *mtype, int sx, int sy, int dx, int dy) { - const Vec2i startPos = {sx, sy}; - const Vec2i destPos = {dx, dy}; + const PixelPos startPos = {sx, sy}; + const PixelPos destPos = {dx, dy}; return MakeMissile(mtype, startPos, destPos); } /// create a local missile -extern Missile *MakeLocalMissile(MissileType *mtype, const Vec2i &startPos, const Vec2i &destPos); +extern Missile *MakeLocalMissile(MissileType *mtype, const PixelPos &startPos, const PixelPos &destPos); inline Missile *MakeLocalMissile(MissileType *mtype, int sx, int sy, int dx, int dy) { - const Vec2i startPos = {sx, sy}; - const Vec2i destPos = {dx, dy}; + const PixelPos startPos = {sx, sy}; + const PixelPos destPos = {dx, dy}; return MakeLocalMissile(mtype, startPos, destPos); } diff --git a/src/include/unit.h b/src/include/unit.h index 3108b6335..cdb3fe182 100644 --- a/src/include/unit.h +++ b/src/include/unit.h @@ -409,6 +409,21 @@ static inline int MapDistance(const Vec2i& pos1, const Vec2i &pos2) return isqrt(diff.x * diff.x + diff.y * diff.y); } +/** +** Returns the map distance between two points. +** +** @param pos1 map pixel position. +** @param pos2 map pixel position. +** +** @return The distance between in pixels. +*/ +static inline int MapDistance(const PixelPos& pos1, const PixelPos &pos2) +{ + const PixelDiff diff = pos2 - pos1; + + return isqrt(diff.x * diff.x + diff.y * diff.y); +} + /// Returns the map distance between two points with unit-type extern int MapDistanceToType(const Vec2i &pos1, const CUnitType &type, const Vec2i &pos2); @@ -1279,6 +1294,8 @@ extern void RescueUnits(); /// Convert direction (dx,dy) to heading (0-255) extern int DirectionToHeading(const Vec2i &dir); + /// Convert direction (dx,dy) to heading (0-255) +extern int DirectionToHeading(const PixelDiff &dir); /// Update frame from heading extern void UnitUpdateHeading(CUnit &unit); diff --git a/src/include/vec2i.h b/src/include/vec2i.h index 9eee5e451..4376e1ba8 100644 --- a/src/include/vec2i.h +++ b/src/include/vec2i.h @@ -33,93 +33,108 @@ //@{ -class Vec2i +template <typename T> +class Vec2T { public: - short int x; - short int y; + T x; + T y; }; -inline bool operator == (const Vec2i &lhs, const Vec2i & rhs) +template <typename T> +inline bool operator == (const Vec2T<T> &lhs, const Vec2T<T> &rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; } -inline bool operator != (const Vec2i &lhs, const Vec2i & rhs) +template <typename T> +inline bool operator != (const Vec2T<T> &lhs, const Vec2T<T> &rhs) { return !(lhs == rhs); } -inline const Vec2i& operator += (Vec2i &lhs, const Vec2i& rhs) +template <typename T> +inline const Vec2T<T>& operator += (Vec2T<T> &lhs, const Vec2T<T>& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } -inline const Vec2i& operator -= (Vec2i &lhs, const Vec2i& rhs) +template <typename T> +inline const Vec2T<T>& operator -= (Vec2T<T> &lhs, const Vec2T<T> &rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } -inline const Vec2i& operator *= (Vec2i &lhs, int rhs) +template <typename T> +inline const Vec2T<T>& operator *= (Vec2T<T> &lhs, int rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } -inline const Vec2i& operator /= (Vec2i &lhs, int rhs) +template <typename T> +inline const Vec2T<T>& operator /= (Vec2T<T> &lhs, int rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } -inline Vec2i operator + (const Vec2i &lhs, const Vec2i& rhs) +template <typename T> +inline Vec2T<T> operator + (const Vec2T<T> &lhs, const Vec2T<T>& rhs) { - Vec2i res(lhs); + Vec2T<T> res(lhs); res += rhs; return res; } -inline Vec2i operator - (const Vec2i &lhs, const Vec2i& rhs) +template <typename T> +inline Vec2T<T> operator - (const Vec2T<T> &lhs, const Vec2T<T>& rhs) { - Vec2i res(lhs); + Vec2T<T> res(lhs); res -= rhs; return res; } -inline Vec2i operator * (const Vec2i &lhs, int rhs) +template <typename T> +inline Vec2T<T> operator * (const Vec2T<T> &lhs, int rhs) { - Vec2i res(lhs); + Vec2T<T> res(lhs); res *= rhs; return res; } -inline Vec2i operator * (int lhs, const Vec2i &rhs) +template <typename T> +inline Vec2T<T> operator * (int lhs, const Vec2T<T> &rhs) { - Vec2i res(rhs); + Vec2T<T> res(rhs); res *= lhs; return res; } - -inline Vec2i operator / (const Vec2i &lhs, int rhs) +template <typename T> +inline Vec2T<T> operator / (const Vec2T<T> &lhs, int rhs) { - Vec2i res(lhs); + Vec2T<T> res(lhs); res /= rhs; return res; } +typedef Vec2T<short int> Vec2i; +typedef Vec2T<int> PixelPos; +typedef Vec2T<int> PixelDiff; +typedef Vec2T<int> PixelSize; //@} diff --git a/src/stratagus/missile.cpp b/src/stratagus/missile.cpp index 3c8e695e5..085d00dd1 100644 --- a/src/stratagus/missile.cpp +++ b/src/stratagus/missile.cpp @@ -170,7 +170,7 @@ Missile::Missile() : ** ** @return created missile. */ -Missile *Missile::Init(MissileType *mtype, const Vec2i &startPos, const Vec2i &destPos) +Missile *Missile::Init(MissileType *mtype, const PixelPos &startPos, const PixelPos &destPos) { Missile *missile = NULL; @@ -218,7 +218,7 @@ Missile *Missile::Init(MissileType *mtype, const Vec2i &startPos, const Vec2i &d missile = new MissileDeathCoil; break; } - const Vec2i halfSize = mtype->size / 2; + const PixelPos halfSize = mtype->size / 2; missile->position = startPos - halfSize; missile->destination = destPos - halfSize; missile->source = missile->position; @@ -238,7 +238,7 @@ Missile *Missile::Init(MissileType *mtype, const Vec2i &startPos, const Vec2i &d ** ** @return created missile. */ -Missile *MakeMissile(MissileType *mtype, const Vec2i &startPos, const Vec2i &destPos) +Missile *MakeMissile(MissileType *mtype, const PixelPos &startPos, const PixelPos &destPos) { Missile *missile = Missile::Init(mtype, startPos, destPos); @@ -255,7 +255,7 @@ Missile *MakeMissile(MissileType *mtype, const Vec2i &startPos, const Vec2i &des ** ** @return created missile. */ -Missile *MakeLocalMissile(MissileType *mtype, const Vec2i &startPos, const Vec2i &destPos) +Missile *MakeLocalMissile(MissileType *mtype, const PixelPos &startPos, const PixelPos &destPos) { Missile *missile = Missile::Init(mtype, startPos, destPos); @@ -513,7 +513,7 @@ static int MissileVisibleInViewport(const CViewport *vp, const Missile *missile) ** @param frame Animation frame ** @param pos Screen pixel position */ -void MissileType::DrawMissileType(int frame, const Vec2i &pos) const +void MissileType::DrawMissileType(int frame, const PixelPos &pos) const { #ifdef DYNAMIC_LOAD if (!this->G->IsLoaded()) { @@ -683,7 +683,7 @@ int FindAndSortMissiles(const CViewport *vp, ** ** @internal We have : SpriteFrame / (2 * (Numdirection - 1)) == DirectionToHeading / 256. */ -static void MissileNewHeadingFromXY(Missile &missile, const Vec2i &delta) +static void MissileNewHeadingFromXY(Missile &missile, const PixelPos &delta) { int neg; @@ -720,7 +720,7 @@ static void MissileNewHeadingFromXY(Missile &missile, const Vec2i &delta) */ static int MissileInitMove(Missile &missile) { - const Vec2i heading = missile.destination - missile.position; + const PixelPos heading = missile.destination - missile.position; MissileNewHeadingFromXY(missile, heading); if (!(missile.State & 1)) { @@ -759,11 +759,11 @@ static int PointToPointMissile(Missile &missile) Assert(missile.Type != NULL); Assert(missile.TotalStep != 0); - const Vec2i diff = (missile.destination - missile.source); + const PixelPos diff = (missile.destination - missile.source); missile.position = missile.source + diff * missile.CurrentStep / missile.TotalStep; if (missile.Type->SmokeMissile && missile.CurrentStep) { - const Vec2i position = missile.position + missile.Type->size / 2; + const PixelPos position = missile.position + missile.Type->size / 2; MakeMissile(missile.Type->SmokeMissile, position, position); } return 0; @@ -792,10 +792,10 @@ static int ParabolicMissile(Missile &missile) return 1; } Assert(missile.Type != NULL); - const Vec2i orig_pos = missile.position; + const PixelPos orig_pos = missile.position; Assert(missile.TotalStep != 0); - const Vec2i step = (missile.destination - missile.source) * 1000 / missile.TotalStep; - missile.position = missile.source + step * missile.CurrentStep / 1000; + const PixelPos diff = (missile.destination - missile.source); + missile.position = missile.source + diff * missile.CurrentStep / missile.TotalStep; Assert(k != 0); z = missile.CurrentStep * (missile.TotalStep - missile.CurrentStep) / k; @@ -804,7 +804,7 @@ static int ParabolicMissile(Missile &missile) missile.position.y += z * zprojToY / 64; MissileNewHeadingFromXY(missile, missile.position - orig_pos); if (missile.Type->SmokeMissile && missile.CurrentStep) { - const Vec2i position = missile.position + missile.Type->size / 2; + const PixelPos position = missile.position + missile.Type->size / 2; MakeMissile(missile.Type->SmokeMissile, position, position); } return 0; @@ -875,18 +875,18 @@ void MissileHit(Missile *missile) if (missile->Type->ImpactSound.Sound) { PlayMissileSound(missile, missile->Type->ImpactSound.Sound); } - Vec2i pos = missile->position + missile->Type->size / 2; + const PixelPos pixelPos = missile->position + missile->Type->size / 2; // // The impact generates a new missile. // if (missile->Type->ImpactMissile) { - MakeMissile(missile->Type->ImpactMissile, pos.x, pos.y, pos.x, pos.y); + MakeMissile(missile->Type->ImpactMissile, pixelPos, pixelPos); } if (missile->Type->ImpactParticle) { missile->Type->ImpactParticle->pushPreamble(); - missile->Type->ImpactParticle->pushInteger(pos.x); - missile->Type->ImpactParticle->pushInteger(pos.y); + missile->Type->ImpactParticle->pushInteger(pixelPos.x); + missile->Type->ImpactParticle->pushInteger(pixelPos.y); missile->Type->ImpactParticle->run(); } @@ -894,8 +894,7 @@ void MissileHit(Missile *missile) return; } - pos.x /= TileSizeX; - pos.y /= TileSizeY; + const Vec2i pos = {pixelPos.x / TileSizeX, pixelPos.y / TileSizeY}; if (!Map.Info.IsPointOnMap(pos)) { // FIXME: this should handled by caller? @@ -1126,7 +1125,7 @@ void MissileActions() */ int ViewPointDistanceToMissile(const Missile *missile) { - const Vec2i pixelPos = missile->position + missile->Type->size / 2; + const PixelPos pixelPos = missile->position + missile->Type->size / 2; const Vec2i tilePos = { pixelPos.x / TileSizeX, pixelPos.y / TileSizeY }; return ViewPointDistance(tilePos); @@ -1400,9 +1399,9 @@ void MissilePointToPointBounce::Action() this->Wait = this->Type->Sleep; if (PointToPointMissile(*this)) { if (this->State < 2 * this->Type->NumBounces - 1 && this->TotalStep) { - const Vec2i step = (this->destination - this->source) * 1024 / this->TotalStep; + const PixelPos step = (this->destination - this->source); - this->destination += step * ((TileSizeX + TileSizeY) * 3) / 4 / 1024; + this->destination += step * ((TileSizeX + TileSizeY) * 3) / 4 / this->TotalStep; this->State++; // !(State & 1) to initialise this->source = this->position; PointToPointMissile(*this); @@ -1625,7 +1624,7 @@ void MissileWhirlwind::Action() // // Center of the tornado // - Vec2i center = this->position + this->Type->size / 2; + PixelPos center = this->position + this->Type->size / 2; center.x = (center.x + TileSizeX / 2) / TileSizeX; center.y = (center.y + TileSizeY) / TileSizeY; diff --git a/src/stratagus/script_missile.cpp b/src/stratagus/script_missile.cpp index 823a881ba..1d82c4316 100644 --- a/src/stratagus/script_missile.cpp +++ b/src/stratagus/script_missile.cpp @@ -197,9 +197,9 @@ static int CclDefineMissileType(lua_State *l) static int CclMissile(lua_State *l) { MissileType *type = NULL; - Vec2i position = {-1, -1}; - Vec2i destination = {-1, -1}; - Vec2i source = {-1, -1}; + PixelPos position = {-1, -1}; + PixelPos destination = {-1, -1}; + PixelPos source = {-1, -1}; Missile *missile = NULL; DebugPrint("FIXME: not finished\n"); diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index 28d94a49e..c90ad7edf 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -1744,6 +1744,20 @@ int DirectionToHeading(const Vec2i& delta) return 0; } +/** +** Convert direction to heading. +** +** @param delta Delta. +** +** @return Angle (0..255) +*/ +int DirectionToHeading(const PixelDiff& delta) +{ + // code is identic for Vec2i and PixelDiff + Vec2i delta2 = {delta.x, delta.y}; + return DirectionToHeading(delta2); +} + /** ** Update sprite frame for new heading. */