From 478e55e65834fd88ec1e3559b6d759ad718a924d Mon Sep 17 00:00:00 2001 From: Henrique Santiago Date: Wed, 4 Jan 2012 11:02:35 -0200 Subject: [PATCH] thing menu improvements --- modules/game/thing.lua | 42 +++++++++------- modules/game_inventory/inventory.lua | 2 +- src/otclient/core/game.cpp | 74 +++++++++++++++++----------- src/otclient/core/game.h | 4 ++ src/otclient/core/map.cpp | 3 ++ src/otclient/core/thing.cpp | 30 +++++++++++ src/otclient/core/thing.h | 6 +++ src/otclient/core/tile.cpp | 54 +++++++++++++++++--- src/otclient/core/tile.h | 6 ++- src/otclient/luafunctions.cpp | 3 ++ src/otclient/ui/uimap.cpp | 8 ++- 11 files changed, 172 insertions(+), 60 deletions(-) diff --git a/modules/game/thing.lua b/modules/game/thing.lua index 072c2425..9f8c6162 100644 --- a/modules/game/thing.lua +++ b/modules/game/thing.lua @@ -1,47 +1,51 @@ -- public functions -function Thing:createMenu(menuPosition) +function Game.createThingMenu(menuPosition, lookThing, useThing, creatureThing) local menu = createWidget('PopupMenu') - menu:addOption('Look', function() Game.look(self) end) + + if lookThing then + menu:addOption('Look', function() Game.look(lookThing) end) + end -- Open or Use, depending if thing is a container - if not self:asCreature() then - if self:isContainer() then + if useThing then + if useThing:isContainer() then menu:addOption('Open', function() print('open') end) else - if self:isMultiUse() then + if useThing:isMultiUse() then menu:addOption('Use with ...', function() print('use with...') end) else - menu:addOption('Use', function() Game.use(self) end) + menu:addOption('Use', function() Game.use(useThing) end) end end - - if self:isRotateable() then - menu:addOption('Rotate', function() print('rotate') end) + + if useThing:isRotateable() then + menu:addOption('Rotate', function() Game.rotate(useThing) end) end - + menu:addSeparator() - - if not self:isNotMoveable() and self:isPickupable() then + + if not useThing:isNotMoveable() and useThing:isPickupable() then menu:addOption('Trade with ...', function() print('trade with') end) end + end - else + if creatureThing then menu:addSeparator() - if self:asLocalPlayer() then + if creatureThing:asLocalPlayer() then menu:addOption('Set Outfit', function() Game.openOutfitWindow() end) else -- todo: check for stop attack/follow - menu:addOption('Attack', function() print('attack') end) - menu:addOption('Follow', function() print('follow') end) + menu:addOption('Attack', function() Game.attack(creatureThing) end) + menu:addOption('Follow', function() Game.follow(creatureThing)end) - if self:asPlayer() then + if creatureThing:asPlayer() then menu:addSeparator() - menu:addOption('Message to ' .. self:asCreature():getName(), function() print('message') end) + menu:addOption('Message to ' .. creatureThing:getName(), function() print('message') end) menu:addOption('Add to VIP list', function() print('vip') end) - menu:addOption('Ignore ' .. self:asCreature():getName(), function() print('ignore') end) + menu:addOption('Ignore ' .. creatureThing:getName(), function() print('ignore') end) menu:addOption('Invite to Party', function() print('invite to party') end) end diff --git a/modules/game_inventory/inventory.lua b/modules/game_inventory/inventory.lua index a78601bf..c94d14ad 100644 --- a/modules/game_inventory/inventory.lua +++ b/modules/game_inventory/inventory.lua @@ -35,7 +35,7 @@ function Inventory.onInventoryItemMousePress(itemWidget, mousePos, mouseButton) local item = itemWidget:getItem() if not item then return end - item:createMenu(mousePos) + Game.createThingMenu(mousePos, item, item, nil) end connect(Game, { onLogin = Inventory.create, diff --git a/src/otclient/core/game.cpp b/src/otclient/core/game.cpp index b8db523d..333ebc5f 100644 --- a/src/otclient/core/game.cpp +++ b/src/otclient/core/game.cpp @@ -161,42 +161,60 @@ void Game::turn(Otc::Direction direction) void Game::look(const ThingPtr& thing) { - // thing is at map - if(thing->getPos().x != 65535) { - Position tilePos = thing->getPos(); - TilePtr tile = nullptr; - int stackpos = -1; - - while(true) { - tile = g_map.getTile(tilePos); - stackpos = tile->getLookStackpos(); - if(stackpos != -1 || tilePos.z >= Map::MAX_Z) - break; - - tilePos.coveredDown(); - } - - ThingPtr lookThing = tile->getThing(stackpos); - if(lookThing) - m_protocolGame->sendLookAt(tilePos, lookThing->getId(), stackpos); - } - // thing is at inventory - else - m_protocolGame->sendLookAt(thing->getPos(), thing->getId(), 0); + if(!m_online || !thing) + return; + + int stackpos = getThingStackpos(thing); + if(stackpos != -1) + m_protocolGame->sendLookAt(thing->getPos(), thing->getId(), stackpos); } void Game::use(const ThingPtr& thing) +{ + if(!m_online || !thing) + return; + + int stackpos = getThingStackpos(thing); + if(stackpos != -1) + m_protocolGame->sendUseItem(thing->getPos(), thing->getId(), stackpos, 0);// last 0 has something to do with container +} + +void Game::attack(const CreaturePtr& creature) +{ + if(!m_online || !creature) + return; + + m_protocolGame->sendAttack(creature->getId()); +} + +void Game::follow(const CreaturePtr& creature) +{ + if(!m_online || !creature) + return; + + m_protocolGame->sendFollow(creature->getId()); +} + +void Game::rotate(const ThingPtr& thing) +{ + if(!m_online || !thing) + return; + + int stackpos = getThingStackpos(thing); + if(stackpos != -1) + m_protocolGame->sendRotateItem(thing->getPos(), thing->getId(), stackpos); +} + +int Game::getThingStackpos(const ThingPtr& thing) { // thing is at map if(thing->getPos().x != 65535) { TilePtr tile = g_map.getTile(thing->getPos()); - int stackpos = tile->getThingStackpos(thing); - if(stackpos != -1) - m_protocolGame->sendUseItem(thing->getPos(), thing->getId(), stackpos, 0); + return tile->getThingStackpos(thing); } - // thing is at inventory - else - m_protocolGame->sendUseItem(thing->getPos(), thing->getId(), 0, 0); // last 0 has something to do with container + + // thing is at container or inventory + return 0; } void Game::talkChannel(int channelType, int channelId, const std::string& message) diff --git a/src/otclient/core/game.h b/src/otclient/core/game.h index 7ef5a408..4e241c8a 100644 --- a/src/otclient/core/game.h +++ b/src/otclient/core/game.h @@ -50,10 +50,14 @@ public: void turn(Otc::Direction direction); void look(const ThingPtr& thing); void use(const ThingPtr& thing); + void attack(const CreaturePtr& creature); + void follow(const CreaturePtr& creature); + 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); void openOutfitWindow(); void setOutfit(const Outfit& outfit); + int getThingStackpos(const ThingPtr& thing); bool isOnline() { return m_online; } diff --git a/src/otclient/core/map.cpp b/src/otclient/core/map.cpp index 45fb55ba..daa2233f 100644 --- a/src/otclient/core/map.cpp +++ b/src/otclient/core/map.cpp @@ -323,6 +323,9 @@ void Map::removeThing(const ThingPtr& thing) TilePtr Map::getTile(const Position& pos) { + if(!pos.isValid()) + return nullptr; + TilePtr& tile = m_tiles[pos]; if(!tile) tile = TilePtr(new Tile(pos)); diff --git a/src/otclient/core/thing.cpp b/src/otclient/core/thing.cpp index c141e10f..daf8e5fd 100644 --- a/src/otclient/core/thing.cpp +++ b/src/otclient/core/thing.cpp @@ -78,11 +78,36 @@ ThingType *Thing::getType() return g_thingsType.getEmptyThingType(); } +bool Thing::isGround() +{ + return m_type->properties[ThingType::IsGround]; +} + +bool Thing::isGroundBorder() +{ + return m_type->properties[ThingType::IsGroundBorder]; +} + +bool Thing::isOnBottom() +{ + return m_type->properties[ThingType::IsOnBottom]; +} + +bool Thing::isOnTop() +{ + return m_type->properties[ThingType::IsOnTop]; +} + bool Thing::isContainer() { return m_type->properties[ThingType::IsContainer]; } +bool Thing::isForceUse() +{ + return m_type->properties[ThingType::IsForceUse]; +} + bool Thing::isMultiUse() { return m_type->properties[ThingType::IsMultiUse]; @@ -102,3 +127,8 @@ bool Thing::isPickupable() { return m_type->properties[ThingType::IsPickupable]; } + +bool Thing::ignoreLook() +{ + return m_type->properties[ThingType::IgnoreLook]; +} diff --git a/src/otclient/core/thing.h b/src/otclient/core/thing.h index d1213a58..55bf3c68 100644 --- a/src/otclient/core/thing.h +++ b/src/otclient/core/thing.h @@ -66,11 +66,17 @@ public: virtual AnimatedTextPtr asAnimatedText() { return nullptr; } virtual StaticTextPtr asStaticText() { return nullptr; } + bool isGround(); + bool isGroundBorder(); + bool isOnBottom(); + bool isOnTop(); bool isContainer(); + bool isForceUse(); bool isMultiUse(); bool isRotateable(); bool isNotMoveable(); bool isPickupable(); + bool ignoreLook(); protected: void internalDraw(const Point& p, int layer); diff --git a/src/otclient/core/tile.cpp b/src/otclient/core/tile.cpp index 6965f656..b3bffe15 100644 --- a/src/otclient/core/tile.cpp +++ b/src/otclient/core/tile.cpp @@ -197,15 +197,57 @@ ItemPtr Tile::getGround() return nullptr; } -int Tile::getLookStackpos() +ThingPtr Tile::getTopLookThing() { + ThingPtr retThing; + // check if there is any lookable object in this tile for(int i = m_things.size() - 1; i >= 0; --i) { - ThingType *type = m_things[i]->getType(); - if(!type->properties[ThingType::IgnoreLook] && - (type->properties[ThingType::IsGround] || type->properties[ThingType::IsGroundBorder] || type->properties[ThingType::IsOnBottom] || type->properties[ThingType::IsOnTop])) - return i; + ThingPtr thing = m_things[i]; + if(!thing->ignoreLook() && (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop())) + return thing; + else if(!thing->ignoreLook()) + retThing = thing; } - return -1; + + // return this, it it is lookable. + if(retThing) + return retThing; + + // if not, check on under tile + Position tilePos = m_position; + tilePos.coveredDown(); + TilePtr tile = g_map.getTile(tilePos); + if(tile) + return tile->getTopLookThing(); + + return nullptr; +} + +ThingPtr Tile::getTopUseThing() +{ + if(isEmpty()) + return nullptr; + + for(int i = m_things.size() - 1; i >= 0; --i) { + ThingPtr thing = m_things[i]; + if(thing->isForceUse() || (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop())) + return thing; + } + + return m_things[0]; +} + +CreaturePtr Tile::getTopCreature() +{ + CreaturePtr creature; + for(int i = m_things.size() - 1; i >= 0; --i) { + ThingPtr thing = m_things[i]; + if(thing->asLocalPlayer()) // return local player if there aint no other creature. + creature = thing->asCreature(); + else if(thing->asCreature() && !thing->asLocalPlayer()) + return thing->asCreature(); + } + return creature; } bool Tile::isWalkable() diff --git a/src/otclient/core/tile.h b/src/otclient/core/tile.h index 5cc94615..f1c5d430 100644 --- a/src/otclient/core/tile.h +++ b/src/otclient/core/tile.h @@ -44,11 +44,15 @@ public: ThingPtr removeThing(int stackPos); ThingPtr removeThing(const ThingPtr& thing); + + ThingPtr getTopLookThing(); + ThingPtr getTopUseThing(); + CreaturePtr getTopCreature(); + const Position& getPos() { return m_position; } int getDrawElevation() { return m_drawElevation; } std::vector getCreatures(); ItemPtr getGround(); - int getLookStackpos(); bool isWalkable(); bool isFullGround(); bool isFullyOpaque(); diff --git a/src/otclient/luafunctions.cpp b/src/otclient/luafunctions.cpp index eff74e19..8aa3df15 100644 --- a/src/otclient/luafunctions.cpp +++ b/src/otclient/luafunctions.cpp @@ -66,6 +66,9 @@ void OTClient::registerLuaFunctions() g_lua.bindClassStaticFunction("setOutfit", std::bind(&Game::setOutfit, &g_game, _1)); 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("follow", std::bind(&Game::follow, &g_game, _1)); + g_lua.bindClassStaticFunction("rotate", std::bind(&Game::rotate, &g_game, _1)); g_lua.registerClass(); g_lua.bindClassStaticFunction("create", &UIItem::create); diff --git a/src/otclient/ui/uimap.cpp b/src/otclient/ui/uimap.cpp index bca0541f..2074eafa 100644 --- a/src/otclient/ui/uimap.cpp +++ b/src/otclient/ui/uimap.cpp @@ -79,7 +79,7 @@ bool UIMap::onMousePress(const Point& mousePos, Fw::MouseButton button) tilePos.perspectiveUp(tilePos.z - firstFloor); for(int i = firstFloor; i <= Map::MAX_Z; i++) { tile = g_map.getTile(tilePos); - if(!tile->isEmpty()) + if(!tile || !tile->isEmpty()) break; tilePos.coveredDown(); } @@ -87,14 +87,12 @@ bool UIMap::onMousePress(const Point& mousePos, Fw::MouseButton button) if(!tile || tile->isEmpty()) return true; - //tile->useItem(); - if(button == Fw::MouseLeftButton) { - g_game.look(tile->getThing(0)); + g_game.look(tile->getTopLookThing()); } else if(button == Fw::MouseRightButton) { - g_lua.callGlobalField("Thing","createMenu", tile->getTopThing(), mousePos); + g_lua.callGlobalField("Game","createThingMenu", mousePos, tile->getTopLookThing(), tile->getTopUseThing(), tile->getTopCreature()); } return true;