From 7e7050929d573a334515bdc51208c2cbe4749798 Mon Sep 17 00:00:00 2001 From: Henrique Santiago Date: Thu, 5 Jan 2012 12:24:38 -0200 Subject: [PATCH] attack and follow --- modules/game/thing.lua | 14 +++++++-- src/otclient/core/creature.cpp | 28 ++++++++++++++---- src/otclient/core/creature.h | 15 ++++++++-- src/otclient/core/game.cpp | 40 ++++++++++++++++++++++++++ src/otclient/core/game.h | 8 ++++++ src/otclient/luafunctions.cpp | 4 +++ src/otclient/net/protocolgameparse.cpp | 5 ++-- 7 files changed, 101 insertions(+), 13 deletions(-) diff --git a/modules/game/thing.lua b/modules/game/thing.lua index 4d12bb33..e39bff16 100644 --- a/modules/game/thing.lua +++ b/modules/game/thing.lua @@ -37,10 +37,18 @@ function Game.createThingMenu(menuPosition, lookThing, useThing, creatureThing) if creatureThing:asLocalPlayer() then menu:addOption('Set Outfit', function() Game.openOutfitWindow() end) else - -- todo: check for stop attack/follow - menu:addOption('Attack', function() Game.attack(creatureThing) end) - menu:addOption('Follow', function() Game.follow(creatureThing)end) + if Game.getAttackingCreature() ~= creatureThing then + menu:addOption('Attack', function() Game.attack(creatureThing) end) + else + menu:addOption('Stop Attack', function() Game.cancelAttack() end) + end + if Game.getFollowingCreature() ~= creatureThing then + menu:addOption('Follow', function() Game.follow(creatureThing) end) + else + menu:addOption('Stop Follow', function() Game.cancelFollow() end) + end + if creatureThing:asPlayer() then menu:addSeparator() menu:addOption('Message to ' .. creatureThing:getName(), function() print('message') end) diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index d70eb496..e0d324b5 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -39,7 +39,8 @@ Creature::Creature() : Thing() { m_healthPercent = 0; - m_showSquareColor = false; + m_showVolatileSquare = false; + m_showStaticSquare = false; m_direction = Otc::South; m_walkTimePerPixel = 1000.0/32.0; @@ -58,12 +59,17 @@ int MASK_TEXTURE_UNIFORM = 14; void Creature::draw(const Point& p) { - // TODO: activate on attack, follow, discover how 'attacked' works - if(m_showSquareColor) { - g_painter.setColor(Outfit::getColor(m_squareColor)); - g_painter.drawBoundingRect(Rect(p + m_walkOffset - 8, Size(32, 32)), 2); + if(m_showVolatileSquare) { + g_painter.setColor(m_volatileSquareColor); + g_painter.drawBoundingRect(Rect(p + m_walkOffset - Point(m_type->parameters[ThingType::DisplacementX], m_type->parameters[ThingType::DisplacementY]) + 3, Size(28, 28)), 2); } + if(m_showStaticSquare) { + g_painter.setColor(m_staticSquareColor); + g_painter.drawBoundingRect(Rect(p + m_walkOffset - Point(m_type->parameters[ThingType::DisplacementX], m_type->parameters[ThingType::DisplacementY]) + 1, Size(32, 32)), 2); + } + + g_painter.setColor(Fw::white); if(!outfitProgram) { outfitProgram = PainterShaderProgramPtr(new PainterShaderProgram); outfitProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader); @@ -319,6 +325,18 @@ void Creature::setOutfit(const Outfit& outfit) m_outfit.resetClothes(); } +void Creature::addVolatileSquare(uint8 color) +{ + m_showVolatileSquare = true; + m_volatileSquareColor = Color::from8bit(color); + + // schedule removal + auto self = asCreature(); + g_dispatcher.scheduleEvent([self]() { + self->removeVolatileSquare(); + }, VOLATILE_SQUARE_DURATION); +} + ThingType *Creature::getType() { return g_thingsType.getThingType(m_outfit.getType(), ThingsType::Creature); diff --git a/src/otclient/core/creature.h b/src/otclient/core/creature.h index 7e3c7c61..9f0752ba 100644 --- a/src/otclient/core/creature.h +++ b/src/otclient/core/creature.h @@ -30,6 +30,10 @@ class Creature : public Thing { public: + enum { + VOLATILE_SQUARE_DURATION = 1000 + }; + Creature(); virtual ~Creature() { } @@ -46,7 +50,12 @@ public: void setShield(uint8 shield) { m_shield = shield; } void setEmblem(uint8 emblem) { m_emblem = emblem; } void setPassable(bool passable) { m_passable = passable; } - void setSquareColor(uint8 squareColor) { m_squareColor = squareColor; } + + void addVolatileSquare(uint8 color); + void removeVolatileSquare() { m_showVolatileSquare = false; } + + void activateStaticSquare(const Color& color) { m_showStaticSquare = true; m_staticSquareColor = color; } + void deactivateStaticSquare() { m_showStaticSquare = false; } std::string getName() { return m_name; } uint8 getHealthPercent() { return m_healthPercent; } @@ -83,8 +92,8 @@ protected: uint8 m_shield; uint8 m_emblem; bool m_passable; - uint8 m_squareColor; - bool m_showSquareColor; + Color m_volatileSquareColor, m_staticSquareColor; + bool m_showVolatileSquare, m_showStaticSquare; FontPtr m_informationFont; Color m_informationColor; diff --git a/src/otclient/core/game.cpp b/src/otclient/core/game.cpp index 585e04f1..74750464 100644 --- a/src/otclient/core/game.cpp +++ b/src/otclient/core/game.cpp @@ -109,6 +109,8 @@ void Game::walk(Otc::Direction direction) if(!m_online || !m_localPlayer->canWalk(direction) || !g_ui.isOnInputEvent()) return; + cancelFollow(); + m_localPlayer->clientWalk(direction); switch(direction) { @@ -185,17 +187,55 @@ void Game::attack(const CreaturePtr& creature) if(!m_online || !creature || !g_ui.isOnInputEvent()) return; + if(m_attackingCreature) + m_attackingCreature->deactivateStaticSquare(); + + creature->activateStaticSquare(Fw::red); + m_attackingCreature = creature; + m_protocolGame->sendAttack(creature->getId()); } +void Game::cancelAttack() +{ + if(m_attackingCreature) { + m_protocolGame->sendAttack(0); + m_attackingCreature->deactivateStaticSquare(); + m_attackingCreature = nullptr; + } +} + +void Game::onAttackCancelled() +{ + if(m_attackingCreature) { + m_attackingCreature->deactivateStaticSquare(); + m_attackingCreature = nullptr; + } +} + void Game::follow(const CreaturePtr& creature) { if(!m_online || !creature || !g_ui.isOnInputEvent()) return; + if(m_followingCreature) + m_followingCreature->deactivateStaticSquare(); + + creature->activateStaticSquare(Fw::green); + m_followingCreature = creature; + m_protocolGame->sendFollow(creature->getId()); } +void Game::cancelFollow() +{ + if(m_followingCreature) { + m_protocolGame->sendFollow(0); + m_followingCreature->deactivateStaticSquare(); + m_followingCreature = nullptr; + } +} + void Game::rotate(const ThingPtr& thing) { if(!m_online || !thing || !g_ui.isOnInputEvent()) diff --git a/src/otclient/core/game.h b/src/otclient/core/game.h index 709c9e0f..67bc07f1 100644 --- a/src/otclient/core/game.h +++ b/src/otclient/core/game.h @@ -51,7 +51,9 @@ public: void look(const ThingPtr& thing); void use(const ThingPtr& thing); void attack(const CreaturePtr& creature); + void cancelAttack(); void follow(const CreaturePtr& creature); + void cancelFollow(); void rotate(const ThingPtr& thing); void talkChannel(int channelType, int channelId, const std::string& message); void talkPrivate(int channelType, const std::string& receiver, const std::string& message); @@ -61,6 +63,10 @@ public: void addVip(const std::string& name); void removeVip(int playerId); int getThingStackpos(const ThingPtr& thing); + void onAttackCancelled(); + + CreaturePtr getAttackingCreature() { return m_attackingCreature; } + CreaturePtr getFollowingCreature() { return m_followingCreature; } bool isOnline() { return m_online; } @@ -75,6 +81,8 @@ private: ProtocolGamePtr m_protocolGame; bool m_online; int m_serverBeat; + + CreaturePtr m_attackingCreature, m_followingCreature; }; extern Game g_game; diff --git a/src/otclient/luafunctions.cpp b/src/otclient/luafunctions.cpp index 6cdbfbe7..b6b11a58 100644 --- a/src/otclient/luafunctions.cpp +++ b/src/otclient/luafunctions.cpp @@ -73,11 +73,15 @@ void OTClient::registerLuaFunctions() g_lua.bindClassStaticFunction("look", std::bind(&Game::look, &g_game, _1)); g_lua.bindClassStaticFunction("use", std::bind(&Game::use, &g_game, _1)); g_lua.bindClassStaticFunction("attack", std::bind(&Game::attack, &g_game, _1)); + g_lua.bindClassStaticFunction("cancelAttack", std::bind(&Game::cancelAttack, &g_game)); g_lua.bindClassStaticFunction("follow", std::bind(&Game::follow, &g_game, _1)); + g_lua.bindClassStaticFunction("cancelFollow", std::bind(&Game::cancelFollow, &g_game)); g_lua.bindClassStaticFunction("rotate", std::bind(&Game::rotate, &g_game, _1)); g_lua.bindClassStaticFunction("inviteToParty", std::bind(&Game::inviteToParty, &g_game, _1)); g_lua.bindClassStaticFunction("addVip", std::bind(&Game::addVip, &g_game, _1)); g_lua.bindClassStaticFunction("removeVip", std::bind(&Game::removeVip, &g_game, _1)); + g_lua.bindClassStaticFunction("getAttackingCreature", std::bind(&Game::getAttackingCreature, &g_game)); + g_lua.bindClassStaticFunction("getFollowingCreature", std::bind(&Game::getFollowingCreature, &g_game)); g_lua.registerClass(); g_lua.bindClassStaticFunction("create", &UIItem::create); diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index 3421d53c..5c8c000d 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -573,7 +573,7 @@ void ProtocolGame::parseCreatureSquare(InputMessage& msg) CreaturePtr creature = g_map.getCreatureById(id); if(creature) - creature->setSquareColor(color); + creature->addVolatileSquare(color); } void ProtocolGame::parseCreatureHealth(InputMessage& msg) @@ -735,7 +735,8 @@ void ProtocolGame::parsePlayerIcons(InputMessage& msg) void ProtocolGame::parsePlayerCancelAttack(InputMessage& msg) { - msg.getU32(); + msg.getU32(); // unknown + g_game.onAttackCancelled(); } void ProtocolGame::parseCreatureSpeak(InputMessage& msg)