diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index 78e6f1a2..9d7d99c5 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -1,5 +1,8 @@ #include "creature.h" #include "datmanager.h" +#include "localplayer.h" +#include "map.h" +#include #include #include @@ -7,13 +10,95 @@ Creature::Creature() : Thing(THING_CREATURE) { m_healthPercent = 0; m_direction = DIRECTION_SOUTH; + m_animation = 0; + + m_walking = false; + m_walkOffsetX = 0; + m_walkOffsetY = 0; + m_lastTicks = g_platform.getTicks(); } void Creature::draw(int x, int y) { - int anim = 0; + //dump << (int)m_speed; + + // gspeed = 100 + // pspeed = 234 + // (recorded) 400 - 866 = 466 + // (calc by ot eq) 1000 * 100 / 234 = 427 + + // gspeed = 150 + // pspeed = 234 + // (recorded) 934 - 1597 = 663 + // (calc by ot eq) 1000 * 150 / 234 = 641 + + // gspeed = 100 + // pspeed = 110 + // (recorded) 900 - 1833 = 933 + // (calc by ot eq) 1000 * 100 / 110 = 909 + + // 1000 * groundSpeed / playerSpeed + + // TODO 1: ADD 2 NEW RENDER STEPS, CREATURE AND TOP 3 + // TODO 2: CONSIDER STRETCH FACTOR ON drawInformation + // TODO 3: FIX MAP BUGGY TILES ?? const ThingAttributes& attributes = getAttributes(); + + // we must walk 32 pixels in m_speed miliseconds + if(m_walking && attributes.animcount > 1) { + + + int groundSpeed = 0; + + ThingPtr ground = g_map.getThing(m_walkingPosition, 0); + if(ground) + groundSpeed = ground->getAttributes().speed; + + float walkTime = 1000.0 * (float)groundSpeed / m_speed; + + //dump << walkTime << (g_platform.getTicks() - m_lastTicks+1); + + if(m_direction == DIRECTION_NORTH) + m_walkOffsetY -= (32.0 / walkTime) * (g_platform.getTicks() - m_lastTicks+1); + else if(m_direction == DIRECTION_EAST) + m_walkOffsetX += (32.0 / walkTime) * (g_platform.getTicks() - m_lastTicks+1); + else if(m_direction == DIRECTION_SOUTH) + m_walkOffsetY += (32.0 / walkTime) * (g_platform.getTicks() - m_lastTicks+1); + else if(m_direction == DIRECTION_WEST) + m_walkOffsetX -= (32.0 / walkTime) * (g_platform.getTicks() - m_lastTicks+1); + + /*if(g_platform.getTicks() - m_lastTicks > m_speed / 4) { + if(m_animation+1 == attributes.animcount) + m_animation = 1; + else + m_animation++; + + m_lastTicks = g_platform.getTicks(); + }*/ + + dump << m_walkOffsetY; + + if(fabs(m_walkOffsetY) >= 32) { + g_map.removeThingByPtr(asThing()); + + // calc newpos + m_position = m_walkingPosition; + + g_map.addThing(asThing()); + m_walking = false; + m_walkOffsetY = 0; + } + + //m_lastTicks = g_platform.getTicks(); + } + + m_lastTicks = g_platform.getTicks(); + + x += m_walkOffsetX; + y += m_walkOffsetY; + + for(int ydiv = 0; ydiv < attributes.ydiv; ydiv++) { // continue if we dont have this addon. @@ -21,7 +106,7 @@ void Creature::draw(int x, int y) continue; // draw white item - internalDraw(x, y, 0, m_direction, ydiv, 0, anim); + internalDraw(x, y, 0, m_direction, ydiv, 0, m_animation); // draw mask if exists if(attributes.blendframes > 1) { @@ -40,7 +125,7 @@ void Creature::draw(int x, int y) outfitColorId = m_outfit.feet; g_graphics.bindColor(OutfitColors[outfitColorId]); - internalDraw(x, y, 1, m_direction, ydiv, 0, anim, (SpriteMask)mask); + internalDraw(x, y, 1, m_direction, ydiv, 0, m_animation, (SpriteMask)mask); } g_graphics.bindBlendFunc(BLEND_NORMAL); @@ -51,23 +136,36 @@ void Creature::draw(int x, int y) void Creature::drawInformation(int x, int y, bool useGray) { + x += m_walkOffsetX; + y += m_walkOffsetY; + Color fillColor = Color(96, 96, 96); if(!useGray) { - // health bar + // health bar according to yatc fillColor = Color::black; - if(m_healthPercent > 60 && m_healthPercent <= 100) { - fillColor.setRed(0.0f); - fillColor.setGreen(0.75f); - } else if(m_healthPercent > 30 && m_healthPercent <= 60) { - fillColor.setRed(0.75f); - fillColor.setGreen(0.75f); - } else if(m_healthPercent > 10 && m_healthPercent <= 30) { - fillColor.setRed(0.75f); - fillColor.setGreen(0.00f); - } else if(m_healthPercent > 0 && m_healthPercent <= 10) { - fillColor.setRed(0.25f); - fillColor.setGreen(0.00f); + if(m_healthPercent > 92) { + fillColor.setGreen(188); + } + else if(m_healthPercent > 60) { + fillColor.setRed(80); + fillColor.setGreen(161); + fillColor.setBlue(80); + } + else if(m_healthPercent > 30) { + fillColor.setRed(161); + fillColor.setGreen(161); + } + else if(m_healthPercent > 8) { + fillColor.setRed(160); + fillColor.setGreen(39); + fillColor.setBlue(39); + } + else if(m_healthPercent > 3) { + fillColor.setRed(160); + } + else { + fillColor.setRed(79); } } @@ -89,6 +187,30 @@ void Creature::drawInformation(int x, int y, bool useGray) font->renderText(m_name, Rect(x-100, y-15, 200, 15), AlignTopCenter, fillColor); } +void Creature::walk(const Position& position) +{ + m_walking = true; + m_walkOffsetX = 0; + m_walkOffsetY = 0; + m_walkingPosition = position; + + if(m_position + Position(0, -1, 0) == m_walkingPosition) + m_direction = DIRECTION_NORTH; + else if(m_position + Position(1, 0, 0) == m_walkingPosition) + m_direction = DIRECTION_EAST; + else if(m_position + Position(0, 1, 0) == m_walkingPosition) + m_direction = DIRECTION_SOUTH; + else if(m_position + Position(-1, 0, 0) == m_walkingPosition) + m_direction = DIRECTION_WEST; + else { // Teleport + g_map.removeThingByPtr(asThing()); + m_position = m_walkingPosition; + g_map.addThing(asThing()); + + m_walking = false; + } +} + const ThingAttributes& Creature::getAttributes() { return g_dat.getCreatureAttributes(m_outfit.type); diff --git a/src/otclient/core/creature.h b/src/otclient/core/creature.h index 6872a032..45c8ab35 100644 --- a/src/otclient/core/creature.h +++ b/src/otclient/core/creature.h @@ -43,6 +43,8 @@ public: uint8 getEmblem() { return m_emblem; } bool getImpassable() { return m_impassable; } + void walk(const Position& position); + const ThingAttributes& getAttributes(); CreaturePtr asCreature() { return std::static_pointer_cast(shared_from_this()); } @@ -58,6 +60,12 @@ private: uint8 m_shield; uint8 m_emblem; bool m_impassable; + + int m_lastTicks; + bool m_walking; + Position m_walkingPosition; + float m_walkOffsetX, m_walkOffsetY; + int m_animation; }; #endif diff --git a/src/otclient/core/datmanager.cpp b/src/otclient/core/datmanager.cpp index caac3cd6..3d759aab 100644 --- a/src/otclient/core/datmanager.cpp +++ b/src/otclient/core/datmanager.cpp @@ -17,9 +17,14 @@ bool DatManager::load(const std::string& file) int numShots = fw::getu16(fin); m_itemsAttributes.resize(numItems); - for(int id = 100; id < numItems; ++id) + for(int id = 100; id < numItems; ++id) { parseThingAttributes(fin, m_itemsAttributes[id - 100]); + if(id == 436 || id == 870 || id == 4522) { + dump << id << (int)m_itemsAttributes[id-100].speed; + } + } + m_creaturesAttributes.resize(numItems); for(int id = 0; id < numCreatures; ++id) parseThingAttributes(fin, m_creaturesAttributes[id]); diff --git a/src/otclient/core/tile.cpp b/src/otclient/core/tile.cpp index a5ec7651..9b843c01 100644 --- a/src/otclient/core/tile.cpp +++ b/src/otclient/core/tile.cpp @@ -78,11 +78,13 @@ void Tile::addThing(ThingPtr thing, int stackpos) if(!thing) return; - if(thing->getPosition() == g_game.getLocalPlayer()->getPosition() + Position(-1, 0, 0) && thing->getAttributes().alwaysOnTop) { + const ThingAttributes& thingAttributes = thing->getAttributes(); + + if(thing->getPosition() == g_game.getLocalPlayer()->getPosition() + Position(-1, 0, 0) && thingAttributes.group == THING_GROUP_GROUND) { logDebug((int)thing->getId()); } - const ThingAttributes& thingAttributes = thing->getAttributes(); + if(thing->asItem()) { if(thingAttributes.group == THING_GROUP_GROUND) diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index 0d4a91ef..633611d5 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -382,21 +382,9 @@ void ProtocolGame::parseCreatureMove(InputMessage& msg) ThingPtr thing = g_map.getThing(oldPos, oldStackpos); if(thing) { - g_map.removeThing(oldPos, oldStackpos); - thing->setPosition(newPos); - g_map.addThing(thing); - } - - CreaturePtr creature = thing->asCreature(); - if(creature) { - if(oldPos + Position(0, -1, 0) == newPos) - creature->setDirection(DIRECTION_NORTH); - else if(oldPos + Position(1, 0, 0) == newPos) - creature->setDirection(DIRECTION_EAST); - else if(oldPos + Position(0, 1, 0) == newPos) - creature->setDirection(DIRECTION_SOUTH); - else if(oldPos + Position(-1, 0, 0) == newPos) - creature->setDirection(DIRECTION_WEST); + CreaturePtr creature = thing->asCreature(); + if(creature) + creature->walk(newPos); } }