Fix casting range.
Fix missile by introducing PixelPos (instead of Vec2i).
This commit is contained in:
parent
027a95a816
commit
4e62d647f7
10 changed files with 117 additions and 70 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
//@}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue