diff --git a/modules/client_entergame/characterlist.lua b/modules/client_entergame/characterlist.lua index 63023926..1c8fbd66 100644 --- a/modules/client_entergame/characterlist.lua +++ b/modules/client_entergame/characterlist.lua @@ -231,17 +231,13 @@ function CharacterList.create(characters, account, otui) end function CharacterList.destroy() - charactersWindow:hide() + CharacterList.hide(true) if charactersWindow then characterList = nil charactersWindow:destroy() charactersWindow = nil end - - if EnterGame and not g_game.isOnline() then - EnterGame.show() - end end function CharacterList.show() @@ -252,8 +248,13 @@ function CharacterList.show() end end -function CharacterList.hide() +function CharacterList.hide(showLogin) + showLogin = showLogin or false charactersWindow:hide() + + if showLogin and EnterGame and not g_game.isOnline() then + EnterGame.show() + end end function CharacterList.showAgain() diff --git a/modules/client_entergame/characterlist.otui b/modules/client_entergame/characterlist.otui index 7e0d011f..09eb3e85 100644 --- a/modules/client_entergame/characterlist.otui +++ b/modules/client_entergame/characterlist.otui @@ -46,7 +46,7 @@ MainWindow size: 250 248 visible: false @onEnter: CharacterList.doLogin() - @onEscape: CharacterList.hide() + @onEscape: CharacterList.hide(true) @onSetup: | g_keyboard.bindKeyPress('Up', function() self:getChildById('characters'):focusPreviousChild(KeyboardFocusReason) end, self) g_keyboard.bindKeyPress('Down', function() self:getChildById('characters'):focusNextChild(KeyboardFocusReason) end, self) @@ -113,4 +113,4 @@ MainWindow width: 64 anchors.right: parent.right anchors.bottom: parent.bottom - @onClick: CharacterList.destroy() + @onClick: CharacterList.hide(true) diff --git a/modules/corelib/keyboard.lua b/modules/corelib/keyboard.lua index d195cabe..5b365b7a 100644 --- a/modules/corelib/keyboard.lua +++ b/modules/corelib/keyboard.lua @@ -196,9 +196,9 @@ function g_keyboard.isKeySetPressed(keys, all) local result = {} for k,v in pairs(keys) do if type(v) == 'string' then - key = getKeyCode(v) + v = getKeyCode(v) end - if g_window.isKeyPressed(key) then + if g_window.isKeyPressed(v) then if not all then return true end diff --git a/modules/game_interface/gameinterface.lua b/modules/game_interface/gameinterface.lua index 65688daa..1bdb0e31 100644 --- a/modules/game_interface/gameinterface.lua +++ b/modules/game_interface/gameinterface.lua @@ -1,4 +1,4 @@ -WALK_AUTO_REPEAT_DELAY = 80 +WALK_AUTO_REPEAT_DELAY = 150 gameRootPanel = nil gameMapPanel = nil @@ -14,7 +14,7 @@ bottomSplitter = nil lastWalkDir = nil arrowKeys = { - [North] = "Up", + [North] = 'Up', [South] = 'Down', [East] = 'Right', [West] = 'Left', @@ -182,7 +182,6 @@ function tryLogout() end function smartWalk(defaultDir) - --[[ TODO: Add walk event stack ]] local rebindKey = false local lastKey = arrowKeys[lastWalkDir] @@ -229,11 +228,7 @@ function smartWalk(defaultDir) g_game.forceWalk(dir) end else - --if g_game.getLocalPlayer():canWalk(dir) then - g_game.walk(dir) - --else - - --end + g_game.walk(dir) end if rebindKey then @@ -284,7 +279,7 @@ function onUseWith(clickedWidget, mousePosition) if clickedWidget:getClassName() == 'UIMap' then local tile = clickedWidget:getTile(mousePosition) if tile then - g_game.useWith(selectedThing, tile:getTopMultiUseThing()) + g_game.useWith(selectedThing, tile:getTopMultiUseThing(false)) end elseif clickedWidget:getClassName() == 'UIItem' and not clickedWidget:isVirtual() then g_game.useWith(selectedThing, clickedWidget:getItem()) diff --git a/src/otclient/creature.h b/src/otclient/creature.h index 015eb631..b187a490 100644 --- a/src/otclient/creature.h +++ b/src/otclient/creature.h @@ -89,6 +89,8 @@ public: Position getLastStepFromPosition() { return m_lastStepFromPosition; } Position getLastStepToPosition() { return m_lastStepToPosition; } float getStepProgress() { return m_walkTimer.ticksElapsed() / getStepDuration(); } + float getStepTicksLeft() { return getStepDuration() - m_walkTimer.ticksElapsed(); } + ticks_t getWalkTicksElapsed() { return m_walkTimer.ticksElapsed(); } double getSpeedFormula(Otc::SpeedFormula formula) { return m_speedFormula[formula]; } bool hasSpeedFormula(); std::array getSpeedFormulaArray() { return m_speedFormula; } diff --git a/src/otclient/game.cpp b/src/otclient/game.cpp index ecc37150..f4139c30 100644 --- a/src/otclient/game.cpp +++ b/src/otclient/game.cpp @@ -76,6 +76,11 @@ void Game::resetGameStates() m_pingEvent = nullptr; } + if(m_walkEvent) { + m_walkEvent->cancel(); + m_walkEvent = nullptr; + } + m_containers.clear(); m_vips.clear(); m_gmActions.clear(); @@ -501,8 +506,21 @@ bool Game::walk(Otc::Direction direction) return false; } - if(!m_localPlayer->canWalk(direction)) + // must add a new walk event + if(!m_localPlayer->canWalk(direction)) { + if(m_lastWalkDir != direction) { + float ticks = m_localPlayer->getStepTicksLeft(); + if(ticks < 0) + ticks = 0; + + if(m_walkEvent) { + m_walkEvent->cancel(); + m_walkEvent = nullptr; + } + m_walkEvent = g_dispatcher.scheduleEvent([=] { walk(direction); }, ticks); + } return false; + } Position toPos = m_localPlayer->getPosition().translatedToDirection(direction); TilePtr toTile = g_map.getTile(toPos); @@ -546,6 +564,7 @@ bool Game::walk(Otc::Direction direction) g_lua.callGlobalField("g_game", "onWalk", direction); forceWalk(direction); + m_lastWalkDir = direction; return true; } diff --git a/src/otclient/game.h b/src/otclient/game.h index 428ad66e..00c4dddb 100644 --- a/src/otclient/game.h +++ b/src/otclient/game.h @@ -307,6 +307,7 @@ private: uint m_seq; Otc::FightModes m_fightMode; Otc::ChaseModes m_chaseMode; + Otc::Direction m_lastWalkDir; bool m_safeFight; bool m_canReportBugs; std::vector m_gmActions; @@ -314,6 +315,7 @@ private: std::string m_worldName; std::bitset m_features; ScheduledEventPtr m_pingEvent; + ScheduledEventPtr m_walkEvent; int m_protocolVersion; int m_clientVersion; }; diff --git a/src/otclient/luafunctions.cpp b/src/otclient/luafunctions.cpp index 43193eea..bacd6ded 100644 --- a/src/otclient/luafunctions.cpp +++ b/src/otclient/luafunctions.cpp @@ -364,6 +364,10 @@ void OTClient::registerLuaFunctions() g_lua.bindClassMemberFunction("setOutfit", &Creature::setOutfit); g_lua.bindClassMemberFunction("getOutfit", &Creature::getOutfit); g_lua.bindClassMemberFunction("getDirection", &Creature::getDirection); + g_lua.bindClassMemberFunction("getStepDuration", &Creature::getStepDuration); + g_lua.bindClassMemberFunction("getStepProgress", &Creature::getStepProgress); + g_lua.bindClassMemberFunction("getWalkTicksElapsed", &Creature::getWalkTicksElapsed); + g_lua.bindClassMemberFunction("getStepTicksLeft", &Creature::getStepTicksLeft); g_lua.bindClassMemberFunction("setDirection", &Creature::setDirection); g_lua.bindClassMemberFunction("setSkullTexture", &Creature::setSkullTexture); g_lua.bindClassMemberFunction("setShieldTexture", &Creature::setShieldTexture); diff --git a/src/otclient/tile.cpp b/src/otclient/tile.cpp index 502d0ada..b9277ecf 100644 --- a/src/otclient/tile.cpp +++ b/src/otclient/tile.cpp @@ -433,15 +433,17 @@ ThingPtr Tile::getTopMoveThing() return m_things[0]; } -ThingPtr Tile::getTopMultiUseThing() +ThingPtr Tile::getTopMultiUseThing(bool ignoreCreature) { - // this is related to classic controls, getting top item, forceuse or creature + // this is related to classic controls, getting top item, forceuse for creature if(isEmpty()) return nullptr; for(uint i = 0; i < m_things.size(); ++i) { ThingPtr thing = m_things[i]; - if(thing->isForceUse() || (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature())) { + if(thing->isForceUse() || (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop())) { + if(thing->isCreature() && ignoreCreature) + continue; if(i > 0 && thing->isSplash()) return m_things[i-1]; return thing; @@ -450,8 +452,11 @@ ThingPtr Tile::getTopMultiUseThing() for(uint i = 0; i < m_things.size(); ++i) { ThingPtr thing = m_things[i]; - if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnTop() && !thing->isCreature()) + if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnTop()) { + if(thing->isCreature() && ignoreCreature) + continue; return thing; + } } return m_things[0]; diff --git a/src/otclient/tile.h b/src/otclient/tile.h index 3d21f89a..ebed86f3 100644 --- a/src/otclient/tile.h +++ b/src/otclient/tile.h @@ -81,7 +81,7 @@ public: ThingPtr getTopUseThing(); CreaturePtr getTopCreature(); ThingPtr getTopMoveThing(); - ThingPtr getTopMultiUseThing(); + ThingPtr getTopMultiUseThing(bool ignoreCreature = true); const Position& getPosition() { return m_position; } int getDrawElevation() { return m_drawElevation; }