From 5faa903e18805a6724c9a01b17fa74c651180de2 Mon Sep 17 00:00:00 2001 From: Henrique Santiago Date: Wed, 28 Dec 2011 09:00:09 -0200 Subject: [PATCH] creatures walk and outift fixes --- src/framework/const.h | 1 + src/otclient/core/creature.cpp | 217 +++++++++++-------------- src/otclient/core/creature.h | 4 +- src/otclient/net/protocolgameparse.cpp | 14 +- src/otclient/util/position.h | 2 +- 5 files changed, 110 insertions(+), 128 deletions(-) diff --git a/src/framework/const.h b/src/framework/const.h index 61deb95e..4f6a275e 100644 --- a/src/framework/const.h +++ b/src/framework/const.h @@ -26,6 +26,7 @@ #include "util/types.h" #define DEG_TO_RAD (acos(-1)/180.0) +#define RAD_TO_DEC (180.0/acos(-1)) namespace Fw { diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index e6acb52d..ee3beb04 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -90,38 +90,24 @@ void Creature::draw(const Point& p) outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor()); outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor()); - for(int yi = 0; yi < m_type->dimensions[ThingType::Height]; yi++) { - for(int xi = 0; xi < m_type->dimensions[ThingType::Width]; xi++) { - int sprIndex = ((((((m_animation % m_type->dimensions[ThingType::AnimationPhases]) - * m_type->dimensions[ThingType::PatternZ] + m_zPattern) - * m_type->dimensions[ThingType::PatternY] + m_yPattern) - * m_type->dimensions[ThingType::PatternX] + m_xPattern) - * m_type->dimensions[ThingType::Layers] + 0) - * m_type->dimensions[ThingType::Height] + yi) - * m_type->dimensions[ThingType::Width] + xi; + for(int h = 0; h < m_type->dimensions[ThingType::Height]; h++) { + for(int w = 0; w < m_type->dimensions[ThingType::Width]; w++) { if(m_type->dimensions[ThingType::Layers] > 1) { - int maskIndex = ((((((m_animation % m_type->dimensions[ThingType::AnimationPhases]) - * m_type->dimensions[ThingType::PatternZ] + m_zPattern) - * m_type->dimensions[ThingType::PatternY] + m_yPattern) - * m_type->dimensions[ThingType::PatternX] + m_xPattern) - * m_type->dimensions[ThingType::Layers] + 1) - * m_type->dimensions[ThingType::Height] + yi) - * m_type->dimensions[ThingType::Width] + xi; - int spriteId = m_type->sprites[maskIndex]; - if(!spriteId) + int maskId = m_type->getSpriteId(w, h, 1, m_xPattern, m_yPattern, m_zPattern, m_animation); + if(!maskId) continue; - TexturePtr maskTex = g_sprites.getSpriteTexture(spriteId); + TexturePtr maskTex = g_sprites.getSpriteTexture(maskId); outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1); } - int spriteId = m_type->sprites[sprIndex]; + int spriteId = m_type->getSpriteId(w, h, 0, m_xPattern, m_yPattern, m_zPattern, m_animation); if(!spriteId) continue; TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId); - Rect drawRect(((p + m_walkOffset).x - xi*32) - m_type->parameters[ThingType::DisplacementX], - ((p + m_walkOffset).y - yi*32) - m_type->parameters[ThingType::DisplacementY], + Rect drawRect(((p + m_walkOffset).x - w*32) - m_type->parameters[ThingType::DisplacementX], + ((p + m_walkOffset).y - h*32) - m_type->parameters[ThingType::DisplacementY], 32, 32); g_painter.drawTexturedRect(drawRect, spriteTex); } @@ -162,127 +148,104 @@ void Creature::drawInformation(int x, int y, bool useGray, const Rect& rect) g_painter.setColor(fillColor); g_painter.drawFilledRect(healthRect); - m_informationFont->renderText(m_name, textRect, Fw::AlignTopCenter, fillColor); + if(m_informationFont) + m_informationFont->renderText(m_name, textRect, Fw::AlignTopCenter, fillColor); } void Creature::walk(const Position& position, bool inverse) { - // set walking state - bool sameWalk = m_walking && !m_inverseWalking && inverse; - m_walking = true; - m_inverseWalking = inverse; - int walkTimeFactor = 1; - - // set new direction + // We're walking if(m_position.isInRange(position, 1, 1, 0)) { Otc::Direction direction = m_position.getDirectionFromPosition(position); setDirection(direction); - if(direction == Otc::NorthWest) { - m_walkOffset.x = 32; - m_walkOffset.y = 32; - walkTimeFactor = 2; - } - else if(direction == Otc::North) { - m_walkOffset.y = 32; - } - else if(direction == Otc::NorthEast) { - m_walkOffset.x = -32; - m_walkOffset.y = 32; - walkTimeFactor = 2; - } - else if(direction == Otc::East) { - m_walkOffset.x = -32; - } - else if(direction == Otc::SouthEast) { - m_walkOffset.x = -32; - m_walkOffset.y = -32; - walkTimeFactor = 2; - } - else if(direction == Otc::South) { - m_walkOffset.y = -32; + if(inverse) { + Position positionDelta = m_position - position; + m_walkOffset = Point(positionDelta.x * 32, positionDelta.y * 32); } - else if(direction == Otc::SouthWest) { - m_walkOffset.x = 32; - m_walkOffset.y = -32; - walkTimeFactor = 2; - } - else if(direction == Otc::West) { - m_walkOffset.x = 32; - } - } - else { // Teleport - // we teleported, dont walk or change direction - m_walking = false; - m_walkOffset.x = 0; - m_walkOffset.y = 0; - m_animation = 0; - } + else + m_walkOffset = Point(0, 0); - if(!m_inverseWalking) { - m_walkOffset.x = 0; - m_walkOffset.y = 0; - } + // Diagonal walking lasts 3 times more. + int walkTimeFactor = 1; + if(direction == Otc::NorthWest || direction == Otc::NorthEast || direction == Otc::SouthWest || direction == Otc::SouthEast) + walkTimeFactor = 3; - if(m_walking) { - // get walk speed + // Get walking speed int groundSpeed = 100; - - ItemPtr ground = g_map.getTile(position)->getGround(); - if(ground) + if(ItemPtr ground = g_map.getTile(position)->getGround()) groundSpeed = ground->getType()->parameters[ThingType::GroundSpeed]; - float walkTime = walkTimeFactor * 1000.0 * (float)groundSpeed / m_speed; + float walkTime = 1000.0 * (float)groundSpeed / m_speed; walkTime = (walkTime == 0) ? 1000 : walkTime; + bool sameWalk = m_walking && !m_inverseWalking && inverse; + m_inverseWalking = inverse; + m_walking = true; + m_walkTimePerPixel = walkTime / 32.0; - if(!sameWalk) - m_walkStartTicks = g_clock.ticks(); + m_walkStart = sameWalk ? m_walkStart : g_clock.ticks(); + m_walkEnd = m_walkStart + walkTime * walkTimeFactor; + + m_turnDirection = m_direction; updateWalk(); } + // Teleport + else { + m_walking = false; + m_walkOffset = Point(0, 0); + m_animation = 0; + } } -void Creature::updateWalk() +void Creature::turn(Otc::Direction direction) { - if(m_walking) { - int elapsedTicks = g_clock.ticksElapsed(m_walkStartTicks); - int totalPixelsWalked = std::min((int)round(elapsedTicks / m_walkTimePerPixel), 32); - - if(m_inverseWalking) { - if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest) - m_walkOffset.y = 32 - totalPixelsWalked; - else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest) - m_walkOffset.y = totalPixelsWalked - 32; - - if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast) - m_walkOffset.x = totalPixelsWalked - 32; - else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest) - m_walkOffset.x = 32 - totalPixelsWalked; - } - else { - if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest) - m_walkOffset.y = -totalPixelsWalked; - else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest) - m_walkOffset.y = totalPixelsWalked; - - if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast) - m_walkOffset.x = totalPixelsWalked; - else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest) - m_walkOffset.x = -totalPixelsWalked; - } + if(!m_walking) + setDirection(direction); + else + m_turnDirection = direction; +} - int totalWalkTileTicks = (int)m_walkTimePerPixel*32 * 0.5; - if(m_type->dimensions[ThingType::AnimationPhases] > 0) - m_animation = (g_clock.ticks() % totalWalkTileTicks) / (totalWalkTileTicks / (m_type->dimensions[ThingType::AnimationPhases] - 1)) + 1; - else - m_animation = 0; +void Creature::updateWalk() +{ + if(!m_walking) + return; + + int elapsedTicks = g_clock.ticksElapsed(m_walkStart); + int totalPixelsWalked = std::min((int)round(elapsedTicks / m_walkTimePerPixel), 32); + + if(m_inverseWalking) { + if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest) + m_walkOffset.y = 32 - totalPixelsWalked; + else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest) + m_walkOffset.y = totalPixelsWalked - 32; + + if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast) + m_walkOffset.x = totalPixelsWalked - 32; + else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest) + m_walkOffset.x = 32 - totalPixelsWalked; + } + else { + if(m_direction == Otc::North || m_direction == Otc::NorthEast || m_direction == Otc::NorthWest) + m_walkOffset.y = -totalPixelsWalked; + else if(m_direction == Otc::South || m_direction == Otc::SouthEast || m_direction == Otc::SouthWest) + m_walkOffset.y = totalPixelsWalked; + + if(m_direction == Otc::East || m_direction == Otc::NorthEast || m_direction == Otc::SouthEast) + m_walkOffset.x = totalPixelsWalked; + else if(m_direction == Otc::West || m_direction == Otc::NorthWest || m_direction == Otc::SouthWest) + m_walkOffset.x = -totalPixelsWalked; + } + if(totalPixelsWalked == 32 || m_type->dimensions[ThingType::AnimationPhases] == 0) + m_animation = 0; + else if(m_type->dimensions[ThingType::AnimationPhases] > 0) + m_animation = 1 + totalPixelsWalked * 4 / Map::NUM_TILE_PIXELS % (m_type->dimensions[ThingType::AnimationPhases] - 1); - if(totalPixelsWalked == 32) - cancelWalk(m_direction); - else - g_dispatcher.scheduleEvent(std::bind(&Creature::updateWalk, asCreature()), m_walkTimePerPixel); - } + if(g_clock.ticks() > m_walkEnd) + cancelWalk(m_turnDirection); + else + g_dispatcher.scheduleEvent(std::bind(&Creature::updateWalk, asCreature()), m_walkTimePerPixel); } void Creature::cancelWalk(Otc::Direction direction) @@ -296,15 +259,15 @@ void Creature::cancelWalk(Otc::Direction direction) } m_walking = false; - m_walkStartTicks = 0; - m_walkOffset.x = 0; - m_walkOffset.y = 0; - m_direction = direction; + m_walkStart = 0; + m_walkOffset = Point(0, 0); + setDirection(direction); } void Creature::setName(const std::string& name) { - m_nameSize = m_informationFont->calculateTextRectSize(name); + if(m_informationFont) + m_nameSize = m_informationFont->calculateTextRectSize(name); m_name = name; } @@ -355,6 +318,14 @@ void Creature::setOutfit(const Outfit& outfit) { m_outfit = outfit; m_type = getType(); + + // Do not apply any mask color. + if(m_type->dimensions[ThingType::Layers] == 1) { + m_outfit.setHead(0); + m_outfit.setBody(0); + m_outfit.setLegs(0); + m_outfit.setFeet(0); + } } ThingType *Creature::getType() diff --git a/src/otclient/core/creature.h b/src/otclient/core/creature.h index fae32534..f754ccb5 100644 --- a/src/otclient/core/creature.h +++ b/src/otclient/core/creature.h @@ -61,6 +61,7 @@ public: ThingType *getType(); virtual void walk(const Position& position, bool inverse = true); + void turn(Otc::Direction direction); virtual void cancelWalk(Otc::Direction direction); Point getWalkOffset() { return m_walkOffset; } @@ -88,10 +89,11 @@ protected: FontPtr m_informationFont; Color m_informationColor; - ticks_t m_walkStartTicks; + ticks_t m_walkStart, m_walkEnd; bool m_walking, m_inverseWalking; float m_walkTimePerPixel; Point m_walkOffset; + Otc::Direction m_turnDirection; }; #endif diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index f86e10b1..01adce57 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -408,9 +408,17 @@ void ProtocolGame::parseCreatureMove(InputMessage& msg) Position newPos = parsePosition(msg); ThingPtr thing = g_map.getTile(oldPos)->getThing(oldStackpos); - assert(thing); + if(!thing) { + logError("could not get thing"); + return; + } + CreaturePtr creature = thing->asCreature(); - assert(creature); + if(!creature) { + logError("thing is not a creature"); + return; + } + creature->walk(newPos); // update map tiles @@ -642,7 +650,7 @@ void ProtocolGame::parseCreatureTurn(InputMessage& msg) CreaturePtr creature = g_map.getCreatureById(id); if(creature) - creature->setDirection(direction); + creature->turn(direction); } void ProtocolGame::parseItemTextWindow(InputMessage& msg) diff --git a/src/otclient/util/position.h b/src/otclient/util/position.h index 7969cae9..ec2ecaef 100644 --- a/src/otclient/util/position.h +++ b/src/otclient/util/position.h @@ -74,7 +74,7 @@ public: return Otc::East; } else { - float angle = std::atan2(positionDelta.y * -1, positionDelta.x) * DEG_TO_RAD; + float angle = std::atan2(positionDelta.y * -1, positionDelta.x) * RAD_TO_DEC; if(angle < 0) angle += 360;