missiles and some reworking
This commit is contained in:
parent
61ce6d6331
commit
a3c65f3a7e
|
@ -68,6 +68,7 @@ SET(SOURCES
|
||||||
src/otclient/core/thing.cpp
|
src/otclient/core/thing.cpp
|
||||||
src/otclient/core/creature.cpp
|
src/otclient/core/creature.cpp
|
||||||
src/otclient/core/effect.cpp
|
src/otclient/core/effect.cpp
|
||||||
|
src/otclient/core/missile.cpp
|
||||||
src/otclient/core/localplayer.cpp
|
src/otclient/core/localplayer.cpp
|
||||||
|
|
||||||
# otclient ui
|
# otclient ui
|
||||||
|
|
|
@ -34,27 +34,32 @@ template<class T>
|
||||||
class TPoint
|
class TPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TPoint() : x(0), y(0) {};
|
TPoint() : x(0), y(0) {}
|
||||||
TPoint(T x, T y) : x(x), y(y) { };
|
TPoint(T x, T y) : x(x), y(y) { }
|
||||||
TPoint(const TPoint<T>& other) : x(other.x), y(other.y) { };
|
TPoint(const TPoint<T>& other) : x(other.x), y(other.y) { }
|
||||||
|
|
||||||
bool isNull() const { return x==0 && y==0; }
|
bool isNull() const { return x==0 && y==0; }
|
||||||
TSize<T> toSize() const { return TSize<T>(x, y); }
|
TSize<T> toSize() const { return TSize<T>(x, y); }
|
||||||
|
|
||||||
TPoint<T> operator-() const { return TPoint<T>(-x, -y); }
|
TPoint<T> operator-() const { return TPoint<T>(-x, -y); }
|
||||||
TPoint<T> operator+(const TPoint<T>& other) const { return TPoint<T>(x + other.x, y + other.y); }
|
TPoint<T> operator+(const TPoint<T>& other) const { return TPoint<T>(x + other.x, y + other.y); }
|
||||||
TPoint<T>& operator+=(const TPoint<T>& other) { x+=other.x; y+=other.y; return *this; }
|
TPoint<T>& operator+=(const TPoint<T>& other) { x+=other.x; y+=other.y; return *this; }
|
||||||
TPoint<T> operator-(const TPoint<T>& other) const { return TPoint<T>(x - other.x, y - other.y); }
|
TPoint<T> operator-(const TPoint<T>& other) const { return TPoint<T>(x - other.x, y - other.y); }
|
||||||
TPoint<T>& operator-=(const TPoint<T>& other) { x-=other.x; y-=other.y; return *this; }
|
TPoint<T>& operator-=(const TPoint<T>& other) { x-=other.x; y-=other.y; return *this; }
|
||||||
TPoint<T> operator*(const TPoint<T>& other) const { return TPoint<T>(x * other.x, y * other.y); }
|
TPoint<T> operator*(const TPoint<T>& other) const { return TPoint<T>(x * other.x, y * other.y); }
|
||||||
TPoint<T>& operator*=(const TPoint<T>& other) { x*=other.x; y*=other.y; return *this; }
|
TPoint<T>& operator*=(const TPoint<T>& other) { x*=other.x; y*=other.y; return *this; }
|
||||||
TPoint<T> operator*(const T v) const { return TPoint<T>(x * v, y * v); }
|
TPoint<T> operator*(const T v) const { return TPoint<T>(x * v, y * v); }
|
||||||
TPoint<T>& operator*=(const T v) { x*=v; y*=v; return *this; }
|
TPoint<T>& operator*=(const T v) { x*=v; y*=v; return *this; }
|
||||||
TPoint<T> operator/(const TPoint<T>& other) const { return TPoint<T>(x/other.x, y/other.y); }
|
TPoint<T> operator/(const TPoint<T>& other) const { return TPoint<T>(x/other.x, y/other.y); }
|
||||||
TPoint<T>& operator/=(const TPoint<T>& other) { x/=other.x; y/=other.y; return *this; }
|
TPoint<T>& operator/=(const TPoint<T>& other) { x/=other.x; y/=other.y; return *this; }
|
||||||
TPoint<T> operator/(const T v) const { return TPoint<T>(x/v, y/v); }
|
TPoint<T> operator/(const T v) const { return TPoint<T>(x/v, y/v); }
|
||||||
TPoint<T>& operator/=(const T v) { x/=v; y/=v; return *this; }
|
TPoint<T>& operator/=(const T v) { x/=v; y/=v; return *this; }
|
||||||
|
|
||||||
|
TPoint<T> operator+(T other) const { return TPoint<T>(x + other, y + other); }
|
||||||
|
TPoint<T>& operator+=(T other) { x+=other; y+=other; return *this; }
|
||||||
|
TPoint<T> operator-(T other) const { return TPoint<T>(x - other, y - other); }
|
||||||
|
TPoint<T>& operator-=(T other) { x-=other; y-=other; return *this; }
|
||||||
|
|
||||||
bool operator<=(const TPoint<T>&other) const { return x<=other.x && y<=other.y; }
|
bool operator<=(const TPoint<T>&other) const { return x<=other.x && y<=other.y; }
|
||||||
bool operator>=(const TPoint<T>&other) const { return x>=other.x && y>=other.y; }
|
bool operator>=(const TPoint<T>&other) const { return x>=other.x && y>=other.y; }
|
||||||
bool operator<(const TPoint<T>&other) const { return x<other.x && y<other.y; }
|
bool operator<(const TPoint<T>&other) const { return x<other.x && y<other.y; }
|
||||||
|
|
|
@ -38,19 +38,12 @@ Creature::Creature() : Thing()
|
||||||
m_direction = Otc::South;
|
m_direction = Otc::South;
|
||||||
|
|
||||||
m_walking = false;
|
m_walking = false;
|
||||||
m_walkOffsetX = 0;
|
|
||||||
m_walkOffsetY = 0;
|
|
||||||
|
|
||||||
m_informationFont = g_fonts.getFont("verdana-11px-rounded");
|
m_informationFont = g_fonts.getFont("verdana-11px-rounded");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Creature::draw(int x, int y)
|
void Creature::draw(const Point& p)
|
||||||
{
|
{
|
||||||
if(m_walking) {
|
|
||||||
x += m_walkOffsetX;
|
|
||||||
y += m_walkOffsetY;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ThingType& type = getType();
|
const ThingType& type = getType();
|
||||||
|
|
||||||
// Render creature
|
// Render creature
|
||||||
|
@ -61,7 +54,7 @@ void Creature::draw(int x, int y)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// draw white item
|
// draw white item
|
||||||
internalDraw(x, y, 0);
|
internalDraw(p + m_walkOffset, 0);
|
||||||
|
|
||||||
// draw mask if exists
|
// draw mask if exists
|
||||||
if(type.layers > 1) {
|
if(type.layers > 1) {
|
||||||
|
@ -70,19 +63,19 @@ void Creature::draw(int x, int y)
|
||||||
|
|
||||||
// head
|
// head
|
||||||
g_graphics.bindColor(Otc::OutfitColors[m_outfit.head]);
|
g_graphics.bindColor(Otc::OutfitColors[m_outfit.head]);
|
||||||
internalDraw(x, y, 1, Otc::SpriteYellowMask);
|
internalDraw(p + m_walkOffset, 1, Otc::SpriteYellowMask);
|
||||||
|
|
||||||
// body
|
// body
|
||||||
g_graphics.bindColor(Otc::OutfitColors[m_outfit.body]);
|
g_graphics.bindColor(Otc::OutfitColors[m_outfit.body]);
|
||||||
internalDraw(x, y, 1, Otc::SpriteRedMask);
|
internalDraw(p + m_walkOffset, 1, Otc::SpriteRedMask);
|
||||||
|
|
||||||
// legs
|
// legs
|
||||||
g_graphics.bindColor(Otc::OutfitColors[m_outfit.legs]);
|
g_graphics.bindColor(Otc::OutfitColors[m_outfit.legs]);
|
||||||
internalDraw(x, y, 1, Otc::SpriteGreenMask);
|
internalDraw(p + m_walkOffset, 1, Otc::SpriteGreenMask);
|
||||||
|
|
||||||
// feet
|
// feet
|
||||||
g_graphics.bindColor(Otc::OutfitColors[m_outfit.feet]);
|
g_graphics.bindColor(Otc::OutfitColors[m_outfit.feet]);
|
||||||
internalDraw(x, y, 1, Otc::SpriteBlueMask);
|
internalDraw(p + m_walkOffset, 1, Otc::SpriteBlueMask);
|
||||||
|
|
||||||
// restore default blend func
|
// restore default blend func
|
||||||
g_graphics.bindBlendFunc(Fw::BlendDefault);
|
g_graphics.bindBlendFunc(Fw::BlendDefault);
|
||||||
|
@ -137,55 +130,55 @@ void Creature::walk(const Position& position, bool inverse)
|
||||||
// set new direction
|
// set new direction
|
||||||
if(m_position + Position(0, -1, 0) == position) {
|
if(m_position + Position(0, -1, 0) == position) {
|
||||||
setDirection(Otc::North);
|
setDirection(Otc::North);
|
||||||
m_walkOffsetY = 32;
|
m_walkOffset.y = 32;
|
||||||
}
|
}
|
||||||
else if(m_position + Position(1, 0, 0) == position) {
|
else if(m_position + Position(1, 0, 0) == position) {
|
||||||
setDirection(Otc::East);
|
setDirection(Otc::East);
|
||||||
m_walkOffsetX = -32;
|
m_walkOffset.x = -32;
|
||||||
}
|
}
|
||||||
else if(m_position + Position(0, 1, 0) == position) {
|
else if(m_position + Position(0, 1, 0) == position) {
|
||||||
setDirection(Otc::South);
|
setDirection(Otc::South);
|
||||||
m_walkOffsetY = -32;
|
m_walkOffset.y = -32;
|
||||||
}
|
}
|
||||||
else if(m_position + Position(-1, 0, 0) == position) {
|
else if(m_position + Position(-1, 0, 0) == position) {
|
||||||
setDirection(Otc::West);
|
setDirection(Otc::West);
|
||||||
m_walkOffsetX = 32;
|
m_walkOffset.x = 32;
|
||||||
}
|
}
|
||||||
else if(m_position + Position(1, -1, 0) == position) {
|
else if(m_position + Position(1, -1, 0) == position) {
|
||||||
setDirection(Otc::NorthEast);
|
setDirection(Otc::NorthEast);
|
||||||
m_walkOffsetX = -32;
|
m_walkOffset.x = -32;
|
||||||
m_walkOffsetY = 32;
|
m_walkOffset.y = 32;
|
||||||
walkTimeFactor = 2;
|
walkTimeFactor = 2;
|
||||||
}
|
}
|
||||||
else if(m_position + Position(1, 1, 0) == position) {
|
else if(m_position + Position(1, 1, 0) == position) {
|
||||||
setDirection(Otc::SouthEast);
|
setDirection(Otc::SouthEast);
|
||||||
m_walkOffsetX = -32;
|
m_walkOffset.x = -32;
|
||||||
m_walkOffsetY = -32;
|
m_walkOffset.y = -32;
|
||||||
walkTimeFactor = 2;
|
walkTimeFactor = 2;
|
||||||
}
|
}
|
||||||
else if(m_position + Position(-1, 1, 0) == position) {
|
else if(m_position + Position(-1, 1, 0) == position) {
|
||||||
setDirection(Otc::SouthWest);
|
setDirection(Otc::SouthWest);
|
||||||
m_walkOffsetX = 32;
|
m_walkOffset.x = 32;
|
||||||
m_walkOffsetY = -32;
|
m_walkOffset.y = -32;
|
||||||
walkTimeFactor = 2;
|
walkTimeFactor = 2;
|
||||||
}
|
}
|
||||||
else if(m_position + Position(-1, -1, 0) == position) {
|
else if(m_position + Position(-1, -1, 0) == position) {
|
||||||
setDirection(Otc::NorthWest);
|
setDirection(Otc::NorthWest);
|
||||||
m_walkOffsetX = 32;
|
m_walkOffset.x = 32;
|
||||||
m_walkOffsetY = 32;
|
m_walkOffset.y = 32;
|
||||||
walkTimeFactor = 2;
|
walkTimeFactor = 2;
|
||||||
}
|
}
|
||||||
else { // Teleport
|
else { // Teleport
|
||||||
// we teleported, dont walk or change direction
|
// we teleported, dont walk or change direction
|
||||||
m_walking = false;
|
m_walking = false;
|
||||||
m_walkOffsetX = 0;
|
m_walkOffset.x = 0;
|
||||||
m_walkOffsetY = 0;
|
m_walkOffset.y = 0;
|
||||||
m_animation = 0;
|
m_animation = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!m_inverseWalking) {
|
if(!m_inverseWalking) {
|
||||||
m_walkOffsetX = 0;
|
m_walkOffset.x = 0;
|
||||||
m_walkOffsetY = 0;
|
m_walkOffset.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_walking) {
|
if(m_walking) {
|
||||||
|
@ -215,28 +208,28 @@ void Creature::updateWalk()
|
||||||
|
|
||||||
if(m_inverseWalking) {
|
if(m_inverseWalking) {
|
||||||
if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest)
|
if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest)
|
||||||
m_walkOffsetY = 32 - totalPixelsWalked;
|
m_walkOffset.y = 32 - totalPixelsWalked;
|
||||||
else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest)
|
else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest)
|
||||||
m_walkOffsetY = totalPixelsWalked - 32;
|
m_walkOffset.y = totalPixelsWalked - 32;
|
||||||
|
|
||||||
if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast)
|
if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast)
|
||||||
m_walkOffsetX = totalPixelsWalked - 32;
|
m_walkOffset.x = totalPixelsWalked - 32;
|
||||||
else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest)
|
else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest)
|
||||||
m_walkOffsetX = 32 - totalPixelsWalked;
|
m_walkOffset.x = 32 - totalPixelsWalked;
|
||||||
|
|
||||||
if(m_walkOffsetX == 0 && m_walkOffsetY == 0)
|
if(m_walkOffset.x == 0 && m_walkOffset.y == 0)
|
||||||
cancelWalk(m_direction);
|
cancelWalk(m_direction);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest)
|
if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest)
|
||||||
m_walkOffsetY = -totalPixelsWalked;
|
m_walkOffset.y = -totalPixelsWalked;
|
||||||
else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest)
|
else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest)
|
||||||
m_walkOffsetY = totalPixelsWalked;
|
m_walkOffset.y = totalPixelsWalked;
|
||||||
|
|
||||||
if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast)
|
if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast)
|
||||||
m_walkOffsetX = totalPixelsWalked;
|
m_walkOffset.x = totalPixelsWalked;
|
||||||
else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest)
|
else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest)
|
||||||
m_walkOffsetX = -totalPixelsWalked;
|
m_walkOffset.x = -totalPixelsWalked;
|
||||||
}
|
}
|
||||||
|
|
||||||
int totalWalkTileTicks = (int)m_walkTimePerPixel*32 * 0.5;
|
int totalWalkTileTicks = (int)m_walkTimePerPixel*32 * 0.5;
|
||||||
|
@ -252,8 +245,8 @@ void Creature::cancelWalk(Otc::Direction direction)
|
||||||
{
|
{
|
||||||
m_walking = false;
|
m_walking = false;
|
||||||
m_walkStartTicks = 0;
|
m_walkStartTicks = 0;
|
||||||
m_walkOffsetX = 0;
|
m_walkOffset.x = 0;
|
||||||
m_walkOffsetY = 0;
|
m_walkOffset.y = 0;
|
||||||
m_direction = direction;
|
m_direction = direction;
|
||||||
|
|
||||||
auto self = asCreature();
|
auto self = asCreature();
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
Creature();
|
Creature();
|
||||||
virtual ~Creature() { }
|
virtual ~Creature() { }
|
||||||
|
|
||||||
virtual void draw(int x, int y);
|
virtual void draw(const Point& p);
|
||||||
void drawInformation(int x, int y, bool useGray, const Rect& rect);
|
void drawInformation(int x, int y, bool useGray, const Rect& rect);
|
||||||
|
|
||||||
void setName(const std::string& name) { m_name = name; }
|
void setName(const std::string& name) { m_name = name; }
|
||||||
|
@ -73,8 +73,7 @@ public:
|
||||||
|
|
||||||
virtual void walk(const Position& position, bool inverse = true);
|
virtual void walk(const Position& position, bool inverse = true);
|
||||||
virtual void cancelWalk(Otc::Direction direction);
|
virtual void cancelWalk(Otc::Direction direction);
|
||||||
int getWalkOffsetX() { return m_walkOffsetX; }
|
Point getWalkOffset() { return m_walkOffset; }
|
||||||
int getWalkOffsetY() { return m_walkOffsetY; }
|
|
||||||
|
|
||||||
bool isWalking() { return m_walking; }
|
bool isWalking() { return m_walking; }
|
||||||
|
|
||||||
|
@ -101,7 +100,7 @@ protected:
|
||||||
bool m_walking, m_inverseWalking;
|
bool m_walking, m_inverseWalking;
|
||||||
float m_walkTimePerPixel;
|
float m_walkTimePerPixel;
|
||||||
Position m_walkingFromPosition;
|
Position m_walkingFromPosition;
|
||||||
int m_walkOffsetX, m_walkOffsetY;
|
Point m_walkOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,6 +30,7 @@ class Thing;
|
||||||
class Item;
|
class Item;
|
||||||
class Creature;
|
class Creature;
|
||||||
class Effect;
|
class Effect;
|
||||||
|
class Missile;
|
||||||
class Player;
|
class Player;
|
||||||
class LocalPlayer;
|
class LocalPlayer;
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ typedef std::shared_ptr<Thing> ThingPtr;
|
||||||
typedef std::shared_ptr<Item> ItemPtr;
|
typedef std::shared_ptr<Item> ItemPtr;
|
||||||
typedef std::shared_ptr<Creature> CreaturePtr;
|
typedef std::shared_ptr<Creature> CreaturePtr;
|
||||||
typedef std::shared_ptr<Effect> EffectPtr;
|
typedef std::shared_ptr<Effect> EffectPtr;
|
||||||
|
typedef std::shared_ptr<Missile> MissilePtr;
|
||||||
typedef std::shared_ptr<Player> PlayerPtr;
|
typedef std::shared_ptr<Player> PlayerPtr;
|
||||||
typedef std::shared_ptr<LocalPlayer> LocalPlayerPtr;
|
typedef std::shared_ptr<LocalPlayer> LocalPlayerPtr;
|
||||||
|
|
||||||
|
|
|
@ -32,13 +32,13 @@ Effect::Effect() : Thing()
|
||||||
m_animationStartTicks = 0;
|
m_animationStartTicks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::draw(int x, int y)
|
void Effect::draw(const Point& p)
|
||||||
{
|
{
|
||||||
int animationPhase = (g_platform.getTicks() - m_animationStartTicks) / TICKS_PER_FRAME;
|
int animationPhase = (g_platform.getTicks() - m_animationStartTicks) / TICKS_PER_FRAME;
|
||||||
|
|
||||||
if(animationPhase < getAnimationPhases()) {
|
if(animationPhase < getAnimationPhases()) {
|
||||||
m_animation = animationPhase;
|
m_animation = animationPhase;
|
||||||
internalDraw(x, y, 0);
|
internalDraw(p, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ class Effect : public Thing
|
||||||
public:
|
public:
|
||||||
Effect();
|
Effect();
|
||||||
|
|
||||||
void draw(int x, int y);
|
void draw(const Point& p);
|
||||||
|
|
||||||
void startAnimation();
|
void startAnimation();
|
||||||
void updateAnimation();
|
void updateAnimation();
|
||||||
|
|
|
@ -28,31 +28,26 @@
|
||||||
|
|
||||||
Item::Item() : Thing()
|
Item::Item() : Thing()
|
||||||
{
|
{
|
||||||
m_count = 0;
|
m_data = 0;
|
||||||
m_lastTicks = g_platform.getTicks();
|
m_lastTicks = g_platform.getTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Item::draw(int x, int y)
|
void Item::draw(const Point& p)
|
||||||
{
|
{
|
||||||
const ThingType& type = g_thingsType.getItemType(m_id);
|
const ThingType& type = g_thingsType.getItemType(m_id);
|
||||||
|
|
||||||
if(type.animationPhases > 1)
|
if(type.animationPhases > 1)
|
||||||
m_animation = (g_platform.getTicks() % (TICKS_PER_FRAME * type.animationPhases)) / TICKS_PER_FRAME;
|
m_animation = (g_platform.getTicks() % (TICKS_PER_FRAME * type.animationPhases)) / TICKS_PER_FRAME;
|
||||||
|
|
||||||
/*if(type.group == Otc::ThingSplashGroup || type.group == Otc::ThingFluidGroup) {
|
|
||||||
//xPattern = m_count % type.xPattern;
|
|
||||||
//yPattern = m_count / type.yPattern;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
for(int b = 0; b < type.layers; b++)
|
for(int b = 0; b < type.layers; b++)
|
||||||
internalDraw(x, y, b);
|
internalDraw(p, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Item::setCount(int count)
|
void Item::setData(int count)
|
||||||
{
|
{
|
||||||
int oldCount = m_count;
|
int oldData = m_data;
|
||||||
m_count = count;
|
m_data = count;
|
||||||
onCountChange(oldCount);
|
onDataChange(oldData);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ThingType& Item::getType()
|
const ThingType& Item::getType()
|
||||||
|
@ -71,30 +66,104 @@ void Item::onPositionChange(const Position&)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Item::onCountChange(int)
|
void Item::onDataChange(int)
|
||||||
{
|
{
|
||||||
const ThingType& type = g_thingsType.getItemType(m_id);
|
const ThingType& type = g_thingsType.getItemType(m_id);
|
||||||
|
|
||||||
if(type.isStackable && type.xPattern == 4 && type.yPattern == 2) {
|
if(type.isStackable && type.xPattern == 4 && type.yPattern == 2) {
|
||||||
if(m_count < 5) {
|
if(m_data < 5) {
|
||||||
m_xPattern = m_count-1;
|
m_xPattern = m_data-1;
|
||||||
m_yPattern = 0;
|
m_yPattern = 0;
|
||||||
}
|
}
|
||||||
else if(m_count < 10) {
|
else if(m_data < 10) {
|
||||||
m_xPattern = 0;
|
m_xPattern = 0;
|
||||||
m_yPattern = 1;
|
m_yPattern = 1;
|
||||||
}
|
}
|
||||||
else if(m_count < 25) {
|
else if(m_data < 25) {
|
||||||
m_xPattern = 1;
|
m_xPattern = 1;
|
||||||
m_yPattern = 1;
|
m_yPattern = 1;
|
||||||
}
|
}
|
||||||
else if(m_count < 50) {
|
else if(m_data < 50) {
|
||||||
m_xPattern = 2;
|
m_xPattern = 2;
|
||||||
m_yPattern = 1;
|
m_yPattern = 1;
|
||||||
}
|
}
|
||||||
else if(m_count <= 100) {
|
else if(m_data <= 100) {
|
||||||
m_xPattern = 3;
|
m_xPattern = 3;
|
||||||
m_yPattern = 1;
|
m_yPattern = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(type.isHangable) {
|
||||||
|
if(type.isHookSouth) {
|
||||||
|
m_xPattern = type.xPattern >= 2 ? 1 : 0;
|
||||||
|
}
|
||||||
|
else if(type.isHookEast) {
|
||||||
|
m_xPattern = type.xPattern >= 3 ? 2 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(type.isSplash || type.isFluidContainer) {
|
||||||
|
int var = 0;
|
||||||
|
// TODO: find out what the heck does it mean
|
||||||
|
switch(m_data) {
|
||||||
|
case 0:
|
||||||
|
var = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
var = 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
var = 7;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
var = 3;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
var = 3;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
var = 2;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
var = 4;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
var = 3;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
var = 5;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
var = 6;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
var = 7;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
var = 2;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
var = 5;
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
var = 3;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
var = 5;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
var = 6;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
var = 3;
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
var = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
var = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_xPattern = (var & 3) % type.xPattern;
|
||||||
|
m_yPattern = (var >> 2) % type.yPattern;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,20 +35,20 @@ public:
|
||||||
TICKS_PER_FRAME = 500
|
TICKS_PER_FRAME = 500
|
||||||
};
|
};
|
||||||
|
|
||||||
void draw(int x, int y);
|
void draw(const Point& p);
|
||||||
|
|
||||||
void setCount(int count);
|
void setData(int count);
|
||||||
|
|
||||||
int getCount() { return m_count; }
|
int getData() { return m_data; }
|
||||||
const ThingType& getType();
|
const ThingType& getType();
|
||||||
|
|
||||||
void onPositionChange(const Position&);
|
void onPositionChange(const Position&);
|
||||||
void onCountChange(int);
|
void onDataChange(int);
|
||||||
|
|
||||||
ItemPtr asItem() { return std::static_pointer_cast<Item>(shared_from_this()); }
|
ItemPtr asItem() { return std::static_pointer_cast<Item>(shared_from_this()); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_count;
|
int m_data;
|
||||||
int m_lastTicks;
|
int m_lastTicks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,18 +43,17 @@ void LocalPlayer::walk(const Position& position, bool inverse)
|
||||||
{
|
{
|
||||||
if(m_clientWalking) {
|
if(m_clientWalking) {
|
||||||
Position pos = Position::getPositionFromDirection(m_direction);
|
Position pos = Position::getPositionFromDirection(m_direction);
|
||||||
int walkOffsetX = m_walkOffsetX - pos.x * 32;
|
Point walkOffset = Point(m_walkOffset.x - pos.x * 32,
|
||||||
int walkOffsetY = m_walkOffsetY - pos.y * 32;
|
m_walkOffset.y - pos.y * 32);
|
||||||
|
|
||||||
Creature::walk(position, inverse);
|
Creature::walk(position, inverse);
|
||||||
|
|
||||||
m_walkOffsetX = walkOffsetX;
|
m_walkOffset = walkOffset;
|
||||||
m_walkOffsetY = walkOffsetY;
|
|
||||||
m_clientWalking = false;
|
m_clientWalking = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_walkOffsetX = 0;
|
m_walkOffset.x = 0;
|
||||||
m_walkOffsetY = 0;
|
m_walkOffset.y = 0;
|
||||||
Creature::walk(position, inverse);
|
Creature::walk(position, inverse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "localplayer.h"
|
#include "localplayer.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
#include "missile.h"
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
#include <framework/graphics/framebuffer.h>
|
#include <framework/graphics/framebuffer.h>
|
||||||
|
|
||||||
|
@ -40,8 +41,7 @@ void Map::draw(const Rect& rect)
|
||||||
|
|
||||||
// draw offsets
|
// draw offsets
|
||||||
LocalPlayerPtr localPlayer = g_game.getLocalPlayer();
|
LocalPlayerPtr localPlayer = g_game.getLocalPlayer();
|
||||||
int walkOffsetX = localPlayer->getWalkOffsetX();
|
Point walkOffset = localPlayer->getWalkOffset();
|
||||||
int walkOffsetY = localPlayer->getWalkOffsetY();
|
|
||||||
|
|
||||||
//TODO: cache first/last visible floor
|
//TODO: cache first/last visible floor
|
||||||
// draw from bottom floors to top floors
|
// draw from bottom floors to top floors
|
||||||
|
@ -62,10 +62,16 @@ void Map::draw(const Rect& rect)
|
||||||
// skip tiles that are behind another tile
|
// skip tiles that are behind another tile
|
||||||
//if(isCompletlyCovered(tilePos, firstFloor))
|
//if(isCompletlyCovered(tilePos, firstFloor))
|
||||||
// continue;
|
// continue;
|
||||||
tile->draw(tilePos.to2D(m_centralPosition) - Point(walkOffsetX, walkOffsetY));
|
tile->draw(tilePos.to2D(m_centralPosition) - walkOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// after drawing all tiles, draw shots
|
||||||
|
for(const MissilePtr& shot : m_missilesAtFloor[iz]) {
|
||||||
|
Position missilePos = shot->getPosition();
|
||||||
|
shot->draw(missilePos.to2D(m_centralPosition) - walkOffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_framebuffer->unbind();
|
m_framebuffer->unbind();
|
||||||
|
@ -89,15 +95,14 @@ void Map::draw(const Rect& rect)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(const CreaturePtr& creature : creatures) {
|
for(const CreaturePtr& creature : creatures) {
|
||||||
int x = (7 + (tilePos.x - m_centralPosition.x))*NUM_TILE_PIXELS + 10 - tile->getDrawElevation();
|
Point p((7 + (tilePos.x - m_centralPosition.x))*NUM_TILE_PIXELS + 10 - tile->getDrawElevation(),
|
||||||
int y = (5 + (tilePos.y - m_centralPosition.y))*NUM_TILE_PIXELS - 10 - tile->getDrawElevation();
|
(5 + (tilePos.y - m_centralPosition.y))*NUM_TILE_PIXELS - 10 - tile->getDrawElevation());
|
||||||
|
|
||||||
if(creature != localPlayer) {
|
if(creature != localPlayer) {
|
||||||
x += creature->getWalkOffsetX() - walkOffsetX;
|
p += creature->getWalkOffset() - walkOffset;
|
||||||
y += creature->getWalkOffsetY() - walkOffsetY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
creature->drawInformation(rect.x() + x*horizontalStretchFactor, rect.y() + y*verticalStretchFactor, isCovered(tilePos, firstFloor), rect);
|
creature->drawInformation(rect.x() + p.x*horizontalStretchFactor, rect.y() + p.y*verticalStretchFactor, isCovered(tilePos, firstFloor), rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,6 +201,11 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
|
||||||
if(!thing)
|
if(!thing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(MissilePtr shot = thing->asMissile()) {
|
||||||
|
m_missilesAtFloor[shot->getPosition().z].push_back(shot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TilePtr tile = getTile(pos);
|
TilePtr tile = getTile(pos);
|
||||||
tile->addThing(thing, stackPos);
|
tile->addThing(thing, stackPos);
|
||||||
|
|
||||||
|
@ -221,6 +231,17 @@ void Map::removeThing(const ThingPtr& thing)
|
||||||
if(!thing)
|
if(!thing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(MissilePtr shot = thing->asMissile()) {
|
||||||
|
m_missilesAtFloor[shot->getPosition().z];
|
||||||
|
for(auto it = m_missilesAtFloor[shot->getPosition().z].begin(), end = m_missilesAtFloor[shot->getPosition().z].end(); it != end; ++it) {
|
||||||
|
if(shot == *it) {
|
||||||
|
m_missilesAtFloor[shot->getPosition().z].erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(TilePtr& tile = m_tiles[thing->getPosition()])
|
if(TilePtr& tile = m_tiles[thing->getPosition()])
|
||||||
tile->removeThing(thing);
|
tile->removeThing(thing);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
private:
|
private:
|
||||||
std::unordered_map<Position, TilePtr, PositionHasher> m_tiles;
|
std::unordered_map<Position, TilePtr, PositionHasher> m_tiles;
|
||||||
std::map<uint32, CreaturePtr> m_creatures;
|
std::map<uint32, CreaturePtr> m_creatures;
|
||||||
|
std::map<int, std::vector<MissilePtr> > m_missilesAtFloor;
|
||||||
|
|
||||||
Light m_light;
|
Light m_light;
|
||||||
Position m_centralPosition;
|
Position m_centralPosition;
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "missile.h"
|
||||||
|
#include "thingstype.h"
|
||||||
|
#include "map.h"
|
||||||
|
#include "tile.h"
|
||||||
|
#include <framework/platform/platform.h>
|
||||||
|
#include <framework/core/eventdispatcher.h>
|
||||||
|
|
||||||
|
Missile::Missile() : Thing()
|
||||||
|
{
|
||||||
|
m_startTicks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Missile::draw(const Point& p)
|
||||||
|
{
|
||||||
|
float time = (g_platform.getTicks() - m_startTicks) / m_duration;
|
||||||
|
internalDraw(p + Point(m_positionDelta.x * time, m_positionDelta.y * time), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Missile::setPath(const Position& fromPosition, const Position& toPosition)
|
||||||
|
{
|
||||||
|
m_position = fromPosition;
|
||||||
|
m_positionDelta = toPosition - fromPosition;
|
||||||
|
|
||||||
|
if(m_positionDelta.x == 0 && m_positionDelta.y == 0) {
|
||||||
|
m_xPattern = 1;
|
||||||
|
m_yPattern = 1;
|
||||||
|
}
|
||||||
|
else if(m_positionDelta.x == 0) {
|
||||||
|
m_xPattern = 1;
|
||||||
|
if(m_positionDelta.y < 0) {
|
||||||
|
m_yPattern = 0;
|
||||||
|
}
|
||||||
|
else if(m_positionDelta.y > 0) {
|
||||||
|
m_yPattern = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(m_positionDelta.y == 0) {
|
||||||
|
m_yPattern = 1;
|
||||||
|
if(m_positionDelta.x < 0) {
|
||||||
|
m_xPattern = 0;
|
||||||
|
}
|
||||||
|
else if(m_positionDelta.x > 0) {
|
||||||
|
m_xPattern = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float angle = std::atan2(m_positionDelta.y * -1, m_positionDelta.x) * 180.0 / 3.141592;
|
||||||
|
if(angle < 0)
|
||||||
|
angle += 360;
|
||||||
|
|
||||||
|
if(angle >= 360 - 22.5 || angle < 0 + 22.5) {
|
||||||
|
m_xPattern = 2;
|
||||||
|
m_yPattern = 1;
|
||||||
|
}
|
||||||
|
else if(angle >= 45 - 22.5 && angle < 45 + 22.5) {
|
||||||
|
m_xPattern = 2;
|
||||||
|
m_yPattern = 0;
|
||||||
|
}
|
||||||
|
else if(angle >= 90 - 22.5 && angle < 90 + 22.5) {
|
||||||
|
m_xPattern = 1;
|
||||||
|
m_yPattern = 0;
|
||||||
|
}
|
||||||
|
else if(angle >= 135 - 22.5 && angle < 135 + 22.5) {
|
||||||
|
m_xPattern = 0;
|
||||||
|
m_yPattern = 0;
|
||||||
|
}
|
||||||
|
else if(angle >= 180 - 22.5 && angle < 180 + 22.5) {
|
||||||
|
m_xPattern = 0;
|
||||||
|
m_yPattern = 1;
|
||||||
|
}
|
||||||
|
else if(angle >= 225 - 22.5 && angle < 225 + 22.5) {
|
||||||
|
m_xPattern = 0;
|
||||||
|
m_yPattern = 2;
|
||||||
|
}
|
||||||
|
else if(angle >= 270 - 22.5 && angle < 270 + 22.5) {
|
||||||
|
m_xPattern = 1;
|
||||||
|
m_yPattern = 2;
|
||||||
|
}
|
||||||
|
else if(angle >= 315 - 22.5 && angle < 315 + 22.5) {
|
||||||
|
m_xPattern = 2;
|
||||||
|
m_yPattern = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_duration = 150 * std::sqrt(Point(m_positionDelta.x, m_positionDelta.y).length());
|
||||||
|
m_positionDelta.x *= 32;
|
||||||
|
m_positionDelta.y *= 32;
|
||||||
|
|
||||||
|
m_startTicks = g_platform.getTicks();
|
||||||
|
|
||||||
|
// schedule removal
|
||||||
|
auto self = asMissile();
|
||||||
|
g_dispatcher.scheduleEvent([self]() {
|
||||||
|
g_map.removeThing(self);
|
||||||
|
}, m_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ThingType& Missile::getType()
|
||||||
|
{
|
||||||
|
return g_thingsType.getShotType(m_id);
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHOT_H
|
||||||
|
#define SHOT_H
|
||||||
|
|
||||||
|
#include <framework/global.h>
|
||||||
|
#include "thing.h"
|
||||||
|
|
||||||
|
class Missile : public Thing
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
TICKS_PER_FRAME = 75
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Missile();
|
||||||
|
|
||||||
|
void draw(const Point& p);
|
||||||
|
|
||||||
|
void updateAnimation();
|
||||||
|
|
||||||
|
void setPath(const Position& fromPosition, const Position& toPosition);
|
||||||
|
|
||||||
|
const ThingType& getType();
|
||||||
|
|
||||||
|
MissilePtr asMissile() { return std::static_pointer_cast<Missile>(shared_from_this()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_startTicks;
|
||||||
|
Position m_positionDelta;
|
||||||
|
float m_duration;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -48,7 +48,7 @@ void Thing::setPosition(const Position& position)
|
||||||
onPositionChange(oldPosition);
|
onPositionChange(oldPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thing::internalDraw(int x, int y, int layers, Otc::SpriteMask mask)
|
void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask)
|
||||||
{
|
{
|
||||||
const ThingType& type = getType();
|
const ThingType& type = getType();
|
||||||
|
|
||||||
|
@ -68,8 +68,8 @@ void Thing::internalDraw(int x, int y, int layers, Otc::SpriteMask mask)
|
||||||
|
|
||||||
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId, mask);
|
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId, mask);
|
||||||
|
|
||||||
Rect drawRect((x - xi*32) - type.xDisplacement,
|
Rect drawRect((p.x - xi*32) - type.xDisplacement,
|
||||||
(y - yi*32) - type.yDisplacement,
|
(p.y - yi*32) - type.yDisplacement,
|
||||||
32, 32);
|
32, 32);
|
||||||
g_graphics.drawTexturedRect(drawRect, spriteTex);
|
g_graphics.drawTexturedRect(drawRect, spriteTex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
Thing();
|
Thing();
|
||||||
virtual ~Thing() { }
|
virtual ~Thing() { }
|
||||||
|
|
||||||
virtual void draw(int x, int y) = 0;
|
virtual void draw(const Point& p) = 0;
|
||||||
|
|
||||||
void setId(uint32 id);
|
void setId(uint32 id);
|
||||||
void setPosition(const Position& position);
|
void setPosition(const Position& position);
|
||||||
|
@ -57,11 +57,12 @@ public:
|
||||||
virtual ItemPtr asItem() { return nullptr; }
|
virtual ItemPtr asItem() { return nullptr; }
|
||||||
virtual CreaturePtr asCreature() { return nullptr; }
|
virtual CreaturePtr asCreature() { return nullptr; }
|
||||||
virtual EffectPtr asEffect() { return nullptr; }
|
virtual EffectPtr asEffect() { return nullptr; }
|
||||||
|
virtual MissilePtr asMissile() { return nullptr; }
|
||||||
virtual PlayerPtr asPlayer() { return nullptr; }
|
virtual PlayerPtr asPlayer() { return nullptr; }
|
||||||
virtual LocalPlayerPtr asLocalPlayer() { return nullptr; }
|
virtual LocalPlayerPtr asLocalPlayer() { return nullptr; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void internalDraw(int x, int y, int layers, Otc::SpriteMask mask = Otc::SpriteNoMask);
|
void internalDraw(const Point& p, int layers, Otc::SpriteMask mask = Otc::SpriteNoMask);
|
||||||
|
|
||||||
uint32 m_id;
|
uint32 m_id;
|
||||||
Position m_position;
|
Position m_position;
|
||||||
|
|
|
@ -44,7 +44,7 @@ void Tile::draw(const Point& p)
|
||||||
const ThingType& type = thing->getType();
|
const ThingType& type = thing->getType();
|
||||||
if(!type.isGround && !type.isGroundClip && !type.isOnBottom)
|
if(!type.isGround && !type.isGroundClip && !type.isOnBottom)
|
||||||
break;
|
break;
|
||||||
thing->draw(p.x - m_drawElevation, p.y - m_drawElevation);
|
thing->draw(p - m_drawElevation);
|
||||||
m_drawElevation += type.elevation;
|
m_drawElevation += type.elevation;
|
||||||
if(m_drawElevation > MAX_DRAW_ELEVATION)
|
if(m_drawElevation > MAX_DRAW_ELEVATION)
|
||||||
m_drawElevation = MAX_DRAW_ELEVATION;
|
m_drawElevation = MAX_DRAW_ELEVATION;
|
||||||
|
@ -56,7 +56,7 @@ void Tile::draw(const Point& p)
|
||||||
const ThingType& type = thing->getType();
|
const ThingType& type = thing->getType();
|
||||||
if(thing->asCreature() || type.isOnTop || type.isOnBottom || type.isGroundClip || type.isGround)
|
if(thing->asCreature() || type.isOnTop || type.isOnBottom || type.isGroundClip || type.isGround)
|
||||||
break;
|
break;
|
||||||
thing->draw(p.x - m_drawElevation, p.y - m_drawElevation);
|
thing->draw(p - m_drawElevation);
|
||||||
m_drawElevation += type.elevation;
|
m_drawElevation += type.elevation;
|
||||||
if(m_drawElevation > MAX_DRAW_ELEVATION)
|
if(m_drawElevation > MAX_DRAW_ELEVATION)
|
||||||
m_drawElevation = MAX_DRAW_ELEVATION;
|
m_drawElevation = MAX_DRAW_ELEVATION;
|
||||||
|
@ -68,12 +68,12 @@ void Tile::draw(const Point& p)
|
||||||
for(int yi = -1; yi <= 1; ++yi) {
|
for(int yi = -1; yi <= 1; ++yi) {
|
||||||
for(CreaturePtr creature : g_map.getTile(m_position + Position(xi, yi, 0))->getCreatures()) {
|
for(CreaturePtr creature : g_map.getTile(m_position + Position(xi, yi, 0))->getCreatures()) {
|
||||||
auto& type = creature->getType();
|
auto& type = creature->getType();
|
||||||
Rect creatureRect(p.x + xi*32 + creature->getWalkOffsetX() - type.xDisplacement, p.y + yi*32 + creature->getWalkOffsetY() - type.yDisplacement, 32, 32);
|
Rect creatureRect(p.x + xi*32 + creature->getWalkOffset().x - type.xDisplacement, p.y + yi*32 + creature->getWalkOffset().y - type.yDisplacement, 32, 32);
|
||||||
Rect thisTileRect(p.x, p.y, 32, 32);
|
Rect thisTileRect(p.x, p.y, 32, 32);
|
||||||
|
|
||||||
// only render creatures where bottom right is inside our rect
|
// only render creatures where bottom right is inside our rect
|
||||||
if(thisTileRect.contains(creatureRect.bottomRight())) {
|
if(thisTileRect.contains(creatureRect.bottomRight())) {
|
||||||
creature->draw(p.x + xi*32 - m_drawElevation, p.y + yi*32 - m_drawElevation);
|
creature->draw(Point(p.x + xi*32 - m_drawElevation, p.y + yi*32 - m_drawElevation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,13 +81,13 @@ void Tile::draw(const Point& p)
|
||||||
|
|
||||||
// effects
|
// effects
|
||||||
for(const EffectPtr& effect : m_effects)
|
for(const EffectPtr& effect : m_effects)
|
||||||
effect->draw(p.x - m_drawElevation, p.y - m_drawElevation);
|
effect->draw(p - m_drawElevation);
|
||||||
|
|
||||||
// top items
|
// top items
|
||||||
for(const ThingPtr& thing : m_things) {
|
for(const ThingPtr& thing : m_things) {
|
||||||
const ThingType& type = thing->getType();
|
const ThingType& type = thing->getType();
|
||||||
if(type.isOnTop)
|
if(type.isOnTop)
|
||||||
thing->draw(p.x, p.y);
|
thing->draw(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <otclient/core/map.h>
|
#include <otclient/core/map.h>
|
||||||
#include <otclient/core/item.h>
|
#include <otclient/core/item.h>
|
||||||
#include <otclient/core/effect.h>
|
#include <otclient/core/effect.h>
|
||||||
|
#include <otclient/core/missile.h>
|
||||||
#include <otclient/core/tile.h>
|
#include <otclient/core/tile.h>
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
|
|
||||||
|
@ -531,9 +532,14 @@ void ProtocolGame::parseAnimatedText(InputMessage& msg)
|
||||||
|
|
||||||
void ProtocolGame::parseDistanceShot(InputMessage& msg)
|
void ProtocolGame::parseDistanceShot(InputMessage& msg)
|
||||||
{
|
{
|
||||||
parsePosition(msg); // fromPos
|
Position fromPos = parsePosition(msg);
|
||||||
parsePosition(msg); // toPos
|
Position toPos = parsePosition(msg);
|
||||||
msg.getU8(); // effect
|
int shotId = msg.getU8();
|
||||||
|
|
||||||
|
MissilePtr shot = MissilePtr(new Missile());
|
||||||
|
shot->setId(shotId);
|
||||||
|
shot->setPath(fromPos, toPos);
|
||||||
|
g_map.addThing(shot, fromPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseCreatureSquare(InputMessage& msg)
|
void ProtocolGame::parseCreatureSquare(InputMessage& msg)
|
||||||
|
@ -1052,7 +1058,7 @@ ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, uint16 id)
|
||||||
|
|
||||||
const ThingType& itemType = g_thingsType.getItemType(id);
|
const ThingType& itemType = g_thingsType.getItemType(id);
|
||||||
if(itemType.isStackable || itemType.isFluidContainer || itemType.isSplash)
|
if(itemType.isStackable || itemType.isFluidContainer || itemType.isSplash)
|
||||||
item->setCount(msg.getU8());
|
item->setData(msg.getU8());
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
|
|
||||||
Position operator+(const Position& other) const { return Position(x + other.x, y + other.y, z + other.z); }
|
Position operator+(const Position& other) const { return Position(x + other.x, y + other.y, z + other.z); }
|
||||||
Position& operator+=(const Position& other) { x+=other.x; y+=other.y; z +=other.z; return *this; }
|
Position& operator+=(const Position& other) { x+=other.x; y+=other.y; z +=other.z; return *this; }
|
||||||
Position operator-(const Position& other) const { return Position(x - other.x, y - other.y, z + other.z); }
|
Position operator-(const Position& other) const { return Position(x - other.x, y - other.y, z - other.z); }
|
||||||
Position& operator-=(const Position& other) { x-=other.x; y-=other.y; z-=other.z; return *this; }
|
Position& operator-=(const Position& other) { x-=other.x; y-=other.y; z-=other.z; return *this; }
|
||||||
|
|
||||||
Position& operator=(const Position& other) { x = other.x; y = other.y; z = other.z; return *this; }
|
Position& operator=(const Position& other) { x = other.x; y = other.y; z = other.z; return *this; }
|
||||||
|
|
Loading…
Reference in New Issue