Finalizing auto walk enhancements, closes #63, also other fixes:
* Can now auto walk up to 1000 steps! * Re-added sexy topmenu buttons :) * Tooltip for logout/edit will now change * Changed xxStackpos to xxStackPos
This commit is contained in:
parent
c28596292f
commit
8c6d5a0f5c
Binary file not shown.
Before Width: | Height: | Size: 426 B After Width: | Height: | Size: 223 B |
|
@ -209,7 +209,7 @@ function addCreature(creature)
|
|||
battleButton:setup(creature)
|
||||
|
||||
battleButton.onHoverChange = onBattleButtonHoverChange
|
||||
battleButton.onMouseRelease = onMouseRelease
|
||||
battleButton.onMouseRelease = onBattleButtonMouseRelease
|
||||
|
||||
battleButtonsByCreaturesList[creatureId] = battleButton
|
||||
|
||||
|
@ -225,7 +225,27 @@ function addCreature(creature)
|
|||
end
|
||||
end
|
||||
|
||||
function onMouseRelease(self, mousePosition, mouseButton)
|
||||
function removeAllCreatures()
|
||||
for i, v in pairs(battleButtonsByCreaturesList) do
|
||||
removeCreature(v.creature)
|
||||
end
|
||||
end
|
||||
|
||||
function removeCreature(creature)
|
||||
if hasCreature(creature) then
|
||||
local creatureId = creature:getId()
|
||||
|
||||
if lastBattleButtonSwitched == battleButtonsByCreaturesList[creatureId] then
|
||||
lastBattleButtonSwitched = nil
|
||||
end
|
||||
|
||||
battleButtonsByCreaturesList[creatureId].creature:hideStaticSquare()
|
||||
battleButtonsByCreaturesList[creatureId]:destroy()
|
||||
battleButtonsByCreaturesList[creatureId] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function onBattleButtonMouseRelease(self, mousePosition, mouseButton)
|
||||
if mouseWidget.cancelNextRelease then
|
||||
mouseWidget.cancelNextRelease = false
|
||||
return false
|
||||
|
@ -249,26 +269,6 @@ function onMouseRelease(self, mousePosition, mouseButton)
|
|||
return false
|
||||
end
|
||||
|
||||
function removeAllCreatures()
|
||||
for i, v in pairs(battleButtonsByCreaturesList) do
|
||||
removeCreature(v.creature)
|
||||
end
|
||||
end
|
||||
|
||||
function removeCreature(creature)
|
||||
if hasCreature(creature) then
|
||||
local creatureId = creature:getId()
|
||||
|
||||
if lastBattleButtonSwitched == battleButtonsByCreaturesList[creatureId] then
|
||||
lastBattleButtonSwitched = nil
|
||||
end
|
||||
|
||||
battleButtonsByCreaturesList[creatureId].creature:hideStaticSquare()
|
||||
battleButtonsByCreaturesList[creatureId]:destroy()
|
||||
battleButtonsByCreaturesList[creatureId] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function onBattleButtonHoverChange(widget, hovered)
|
||||
if widget.isBattleButton then
|
||||
widget.isHovered = hovered
|
||||
|
|
|
@ -49,7 +49,7 @@ function init()
|
|||
gameBottomPanel = gameRootPanel:getChildById('gameBottomPanel')
|
||||
connect(gameLeftPanel, { onVisibilityChange = onLeftPanelVisibilityChange })
|
||||
|
||||
logoutButton = modules.client_topmenu.addLeftButton('logoutButton', 'Logout', '/images/topbuttons/logout', tryLogout, true)
|
||||
logoutButton = modules.client_topmenu.addLeftButton('logoutButton', 'Exit', '/images/topbuttons/logout', tryLogout, true)
|
||||
|
||||
bindKeys()
|
||||
|
||||
|
@ -111,6 +111,7 @@ function terminate()
|
|||
end
|
||||
|
||||
function onGameStart()
|
||||
logoutButton:setTooltip('Logout')
|
||||
show()
|
||||
|
||||
-- open tibia has delay in auto walking
|
||||
|
@ -120,6 +121,7 @@ function onGameStart()
|
|||
end
|
||||
|
||||
function onGameEnd()
|
||||
logoutButton:setTooltip('Exit')
|
||||
hide()
|
||||
end
|
||||
|
||||
|
|
|
@ -40,7 +40,8 @@ namespace Otc
|
|||
STATIC_DURATION_PER_CHARACTER = 60,
|
||||
MIN_STATIC_TEXT_DURATION = 3000,
|
||||
MAX_STATIC_TEXT_WIDTH = 200,
|
||||
MAX_AUTOWALK_STEPS_RETRY = 10
|
||||
MAX_AUTOWALK_STEPS_RETRY = 10,
|
||||
MAX_AUTOWALK_DIST = 127
|
||||
};
|
||||
|
||||
enum DrawFlags {
|
||||
|
|
|
@ -717,7 +717,7 @@ void Game::look(const ThingPtr& thing)
|
|||
if(thing->isCreature() && m_protocolVersion >= 961)
|
||||
m_protocolGame->sendLookCreature(thing->getId());
|
||||
else
|
||||
m_protocolGame->sendLook(thing->getPosition(), thing->getId(), thing->getStackpos());
|
||||
m_protocolGame->sendLook(thing->getPosition(), thing->getId(), thing->getStackPos());
|
||||
}
|
||||
|
||||
void Game::move(const ThingPtr& thing, const Position& toPos, int count)
|
||||
|
@ -734,7 +734,7 @@ void Game::move(const ThingPtr& thing, const Position& toPos, int count)
|
|||
id = Proto::Creature;
|
||||
}
|
||||
|
||||
m_protocolGame->sendMove(thing->getPosition(), id, thing->getStackpos(), toPos, count);
|
||||
m_protocolGame->sendMove(thing->getPosition(), id, thing->getStackPos(), toPos, count);
|
||||
}
|
||||
|
||||
void Game::moveToParentContainer(const ThingPtr& thing, int count)
|
||||
|
@ -751,7 +751,7 @@ void Game::rotate(const ThingPtr& thing)
|
|||
if(!canPerformGameAction() || !thing)
|
||||
return;
|
||||
|
||||
m_protocolGame->sendRotateItem(thing->getPosition(), thing->getId(), thing->getStackpos());
|
||||
m_protocolGame->sendRotateItem(thing->getPosition(), thing->getId(), thing->getStackPos());
|
||||
}
|
||||
|
||||
void Game::use(const ThingPtr& thing)
|
||||
|
@ -765,7 +765,7 @@ void Game::use(const ThingPtr& thing)
|
|||
|
||||
// some itens, e.g. parcel, are not set as containers but they are.
|
||||
// always try to use these items in free container slots.
|
||||
m_protocolGame->sendUseItem(pos, thing->getId(), thing->getStackpos(), findEmptyContainerId());
|
||||
m_protocolGame->sendUseItem(pos, thing->getId(), thing->getStackPos(), findEmptyContainerId());
|
||||
}
|
||||
|
||||
void Game::useInventoryItem(int itemId)
|
||||
|
@ -788,9 +788,9 @@ void Game::useWith(const ItemPtr& item, const ThingPtr& toThing)
|
|||
pos = Position(0xFFFF, 0, 0); // means that is a item in inventory
|
||||
|
||||
if(toThing->isCreature())
|
||||
m_protocolGame->sendUseOnCreature(pos, item->getId(), item->getStackpos(), toThing->getId());
|
||||
m_protocolGame->sendUseOnCreature(pos, item->getId(), item->getStackPos(), toThing->getId());
|
||||
else
|
||||
m_protocolGame->sendUseItemWith(pos, item->getId(), item->getStackpos(), toThing->getPosition(), toThing->getId(), toThing->getStackpos());
|
||||
m_protocolGame->sendUseItemWith(pos, item->getId(), item->getStackPos(), toThing->getPosition(), toThing->getId(), toThing->getStackPos());
|
||||
}
|
||||
|
||||
void Game::useInventoryItemWith(int itemId, const ThingPtr& toThing)
|
||||
|
@ -803,7 +803,7 @@ void Game::useInventoryItemWith(int itemId, const ThingPtr& toThing)
|
|||
if(toThing->isCreature())
|
||||
m_protocolGame->sendUseOnCreature(pos, itemId, 0, toThing->getId());
|
||||
else
|
||||
m_protocolGame->sendUseItemWith(pos, itemId, 0, toThing->getPosition(), toThing->getId(), toThing->getStackpos());
|
||||
m_protocolGame->sendUseItemWith(pos, itemId, 0, toThing->getPosition(), toThing->getId(), toThing->getStackPos());
|
||||
}
|
||||
|
||||
int Game::open(const ItemPtr& item, const ContainerPtr& previousContainer)
|
||||
|
@ -817,7 +817,7 @@ int Game::open(const ItemPtr& item, const ContainerPtr& previousContainer)
|
|||
else
|
||||
id = previousContainer->getId();
|
||||
|
||||
m_protocolGame->sendUseItem(item->getPosition(), item->getId(), item->getStackpos(), id);
|
||||
m_protocolGame->sendUseItem(item->getPosition(), item->getId(), item->getStackPos(), id);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -1121,7 +1121,7 @@ void Game::requestTrade(const ItemPtr& item, const CreaturePtr& creature)
|
|||
{
|
||||
if(!canPerformGameAction() || !item || !creature)
|
||||
return;
|
||||
m_protocolGame->sendRequestTrade(item->getPosition(), item->getId(), item->getStackpos(), creature->getId());
|
||||
m_protocolGame->sendRequestTrade(item->getPosition(), item->getId(), item->getStackPos(), creature->getId());
|
||||
}
|
||||
|
||||
void Game::inspectTrade(bool counterOffer, int index)
|
||||
|
|
|
@ -184,33 +184,41 @@ void LocalPlayer::cancelWalk(Otc::Direction direction)
|
|||
|
||||
void LocalPlayer::updateAutoWalkSteps(bool walkFailed)
|
||||
{
|
||||
if(!m_autoWalking) {
|
||||
m_autoWalkSteps.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!m_lastAutoWalkDestination.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// for now this cannot be done from lua, due to bot protection
|
||||
m_autoWalkSteps.push_back(m_lastAutoWalkDestination);
|
||||
if(m_autoWalkSteps.size() >= Otc::MAX_AUTOWALK_STEPS_RETRY || walkFailed) {
|
||||
m_autoWalkSteps.push_back(m_position);
|
||||
if(m_lastAutoWalkDestination != m_position && (m_autoWalkSteps.size() >= Otc::MAX_AUTOWALK_STEPS_RETRY || walkFailed)) {
|
||||
autoWalk(m_lastAutoWalkDestination);
|
||||
}
|
||||
else if(m_position == m_lastAutoWalkDestination && !m_autoWalkQueue.empty()) {
|
||||
m_autoWalkQueue.pop_back();
|
||||
|
||||
// task the next destination
|
||||
if(!m_autoWalkQueue.empty()) {
|
||||
std::vector<Position> destinations = m_position.translatedToDirections(m_autoWalkQueue.back());
|
||||
autoWalk(destinations.back());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LocalPlayer::autoWalk(const Position& destination)
|
||||
{
|
||||
m_autoWalkSteps.clear();
|
||||
|
||||
m_lastAutoWalkDestination = destination;
|
||||
std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> result = g_map.findPath(m_position, destination, 127, Otc::PathFindAllowNullTiles);
|
||||
|
||||
std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> result = g_map.findPath(m_position, destination, 1000, Otc::PathFindAllowNullTiles);
|
||||
|
||||
std::vector<Otc::Direction> dirs = std::get<0>(result);
|
||||
if(dirs.size() == 0)
|
||||
return false;
|
||||
|
||||
if(dirs.size() > Otc::MAX_AUTOWALK_DIST) {
|
||||
dirs = calculateAutoWalk(dirs);
|
||||
m_lastAutoWalkDestination = m_position.translatedToDirections(dirs).back();
|
||||
}
|
||||
|
||||
g_game.autoWalk(dirs);
|
||||
return true;
|
||||
}
|
||||
|
@ -219,6 +227,7 @@ void LocalPlayer::stopAutoWalkUpdate()
|
|||
{
|
||||
m_lastAutoWalkDestination = Position();
|
||||
m_autoWalkSteps.clear();
|
||||
m_autoWalkQueue.clear();
|
||||
}
|
||||
|
||||
void LocalPlayer::stopWalk()
|
||||
|
@ -229,6 +238,29 @@ void LocalPlayer::stopWalk()
|
|||
m_lastPrewalkDestionation = Position();
|
||||
}
|
||||
|
||||
std::vector<Otc::Direction> LocalPlayer::calculateAutoWalk(std::vector<Otc::Direction>& dirs)
|
||||
{
|
||||
if(dirs.size() > Otc::MAX_AUTOWALK_DIST) {
|
||||
// populate auto walk queue
|
||||
m_autoWalkQueue.clear();
|
||||
size_t blocks = std::ceil((float)dirs.size() / Otc::MAX_AUTOWALK_DIST);
|
||||
|
||||
size_t size = Otc::MAX_AUTOWALK_DIST;
|
||||
for(size_t i = 0, offset=0 ; i < blocks ; ++i) {
|
||||
std::vector<Otc::Direction>::iterator next = dirs.begin() + offset;
|
||||
if((offset + size) < dirs.size())
|
||||
m_autoWalkQueue.push_back(std::vector<Otc::Direction>(next, next + size));
|
||||
else
|
||||
m_autoWalkQueue.push_back(std::vector<Otc::Direction>(next, dirs.end()));
|
||||
offset += size;
|
||||
}
|
||||
std::reverse(m_autoWalkQueue.begin(), m_autoWalkQueue.end());
|
||||
|
||||
return m_autoWalkQueue.back();
|
||||
}
|
||||
return dirs;
|
||||
}
|
||||
|
||||
void LocalPlayer::updateWalkOffset(int totalPixelsWalked)
|
||||
{
|
||||
// pre walks offsets are calculated in the oposite direction
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
void updateAutoWalkSteps(bool walkFailed = false);
|
||||
bool autoWalk(const Position& destination);
|
||||
bool canWalk(Otc::Direction direction);
|
||||
std::vector<Otc::Direction> calculateAutoWalk(std::vector<Otc::Direction>& dirs);
|
||||
|
||||
void setStates(int states);
|
||||
void setSkill(Otc::Skill skill, int level, int levelPercent);
|
||||
|
@ -145,6 +146,7 @@ private:
|
|||
std::array<int, Otc::LastSkill> m_skillsLevelPercent;
|
||||
std::vector<int> m_spells;
|
||||
std::vector<Position> m_autoWalkSteps;
|
||||
std::vector<std::vector<Otc::Direction> > m_autoWalkQueue;
|
||||
|
||||
int m_states;
|
||||
int m_vocation;
|
||||
|
|
|
@ -285,6 +285,7 @@ void Client::registerLuaFunctions()
|
|||
g_lua.bindClassMemberFunction<Thing>("getId", &Thing::getId);
|
||||
g_lua.bindClassMemberFunction<Thing>("getPosition", &Thing::getPosition);
|
||||
g_lua.bindClassMemberFunction<Thing>("getStackPriority", &Thing::getStackPriority);
|
||||
g_lua.bindClassMemberFunction<Thing>("getStackPos", &Thing::getStackPos);
|
||||
g_lua.bindClassMemberFunction<Thing>("getAnimationPhases", &Thing::getAnimationPhases);
|
||||
g_lua.bindClassMemberFunction<Thing>("getTile", &Thing::getTile);
|
||||
g_lua.bindClassMemberFunction<Thing>("isItem", &Thing::isItem);
|
||||
|
@ -486,7 +487,7 @@ void Client::registerLuaFunctions()
|
|||
g_lua.bindClassMemberFunction<Tile>("getThing", &Tile::getThing);
|
||||
g_lua.bindClassMemberFunction<Tile>("getThings", &Tile::getThings);
|
||||
g_lua.bindClassMemberFunction<Tile>("getItems", &Tile::getItems);
|
||||
g_lua.bindClassMemberFunction<Tile>("getThingStackpos", &Tile::getThingStackpos);
|
||||
g_lua.bindClassMemberFunction<Tile>("getThingStackPos", &Tile::getThingStackPos);
|
||||
g_lua.bindClassMemberFunction<Tile>("getThingCount", &Tile::getThingCount);
|
||||
g_lua.bindClassMemberFunction<Tile>("getTopThing", &Tile::getTopThing);
|
||||
g_lua.bindClassMemberFunction<Tile>("removeThing", &Tile::removeThing);
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <framework/const.h>
|
||||
#include <framework/util/point.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Position
|
||||
{
|
||||
public:
|
||||
|
@ -122,6 +124,22 @@ public:
|
|||
return angle;
|
||||
}
|
||||
|
||||
std::vector<Position> translatedToDirections(const std::vector<Otc::Direction>& dirs) const {
|
||||
Position lastPos = *this;
|
||||
std::vector<Position> positions;
|
||||
|
||||
positions.push_back(lastPos);
|
||||
|
||||
for(auto dir : dirs) {
|
||||
if(lastPos.isValid()) {
|
||||
positions.push_back(lastPos);
|
||||
}
|
||||
lastPos = lastPos.translatedToDirection(dir);
|
||||
}
|
||||
|
||||
return positions;
|
||||
}
|
||||
|
||||
Otc::Direction getDirectionFromPosition(const Position& position) const {
|
||||
int dx = position.x - x;
|
||||
int dy = position.y - y;
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
void sendAcceptTrade();
|
||||
void sendRejectTrade();
|
||||
void sendUseItem(const Position& position, int itemId, int stackpos, int index);
|
||||
void sendUseItemWith(const Position& fromPos, int itemId, int fromStackpos, const Position& toPos, int toThingId, int toStackpos);
|
||||
void sendUseItemWith(const Position& fromPos, int itemId, int fromStackPos, const Position& toPos, int toThingId, int toStackPos);
|
||||
void sendUseOnCreature(const Position& pos, int thingId, int stackpos, uint creatureId);
|
||||
void sendRotateItem(const Position& pos, int thingId, int stackpos);
|
||||
void sendCloseContainer(int containerId);
|
||||
|
|
|
@ -553,7 +553,7 @@ void ProtocolGame::parseTileTransformThing(const InputMessagePtr& msg)
|
|||
}
|
||||
|
||||
Position pos = thing->getPosition();
|
||||
int stackpos = thing->getStackpos();
|
||||
int stackpos = thing->getStackPos();
|
||||
|
||||
if(!g_map.removeThing(thing)) {
|
||||
g_logger.traceError("unable to remove thing");
|
||||
|
|
|
@ -390,16 +390,16 @@ void ProtocolGame::sendUseItem(const Position& position, int itemId, int stackpo
|
|||
send(msg);
|
||||
}
|
||||
|
||||
void ProtocolGame::sendUseItemWith(const Position& fromPos, int itemId, int fromStackpos, const Position& toPos, int toThingId, int toStackpos)
|
||||
void ProtocolGame::sendUseItemWith(const Position& fromPos, int itemId, int fromStackPos, const Position& toPos, int toThingId, int toStackPos)
|
||||
{
|
||||
OutputMessagePtr msg(new OutputMessage);
|
||||
msg->addU8(Proto::ClientUseItemWith);
|
||||
addPosition(msg, fromPos);
|
||||
msg->addU16(itemId);
|
||||
msg->addU8(fromStackpos);
|
||||
msg->addU8(fromStackPos);
|
||||
addPosition(msg, toPos);
|
||||
msg->addU16(toThingId);
|
||||
msg->addU8(toStackpos);
|
||||
msg->addU8(toStackPos);
|
||||
send(msg);
|
||||
}
|
||||
|
||||
|
|
|
@ -73,12 +73,12 @@ ContainerPtr Thing::getParentContainer()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
int Thing::getStackpos()
|
||||
int Thing::getStackPos()
|
||||
{
|
||||
if(m_position.x == 65535 && isItem()) // is inside a container
|
||||
return m_position.z;
|
||||
else if(const TilePtr& tile = getTile())
|
||||
return tile->getThingStackpos(static_self_cast<Thing>());
|
||||
return tile->getThingStackPos(static_self_cast<Thing>());
|
||||
else {
|
||||
g_logger.traceError("got a thing with invalid stackpos");
|
||||
return -1;
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
int getStackPriority();
|
||||
const TilePtr& getTile();
|
||||
ContainerPtr getParentContainer();
|
||||
int getStackpos();
|
||||
int getStackPos();
|
||||
|
||||
virtual bool isItem() { return false; }
|
||||
virtual bool isEffect() { return false; }
|
||||
|
|
|
@ -276,7 +276,7 @@ bool Tile::hasThing(const ThingPtr& thing)
|
|||
return std::find(m_things.begin(), m_things.end(), thing) != m_things.end();
|
||||
}
|
||||
|
||||
int Tile::getThingStackpos(const ThingPtr& thing)
|
||||
int Tile::getThingStackPos(const ThingPtr& thing)
|
||||
{
|
||||
for(uint stackpos = 0; stackpos < m_things.size(); ++stackpos)
|
||||
if(thing == m_things[stackpos])
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
ThingPtr getThing(int stackPos);
|
||||
EffectPtr getEffect(uint16 id);
|
||||
bool hasThing(const ThingPtr& thing);
|
||||
int getThingStackpos(const ThingPtr& thing);
|
||||
int getThingStackPos(const ThingPtr& thing);
|
||||
ThingPtr getTopThing();
|
||||
|
||||
ThingPtr getTopLookThing();
|
||||
|
|
Loading…
Reference in New Issue