mirror of
https://github.com/edubart/otclient.git
synced 2025-10-14 03:24:55 +02:00
Implement new cool features
* Implement walk booster (dash) as an option in settings menu * Dash is smarter (can pre-animate) * Implement smart walking (walk in diagonal when holding two arrow keys) * Implement ping meter for all protocols * Ping meter uses uses real ping packet for 9.6 and walk for others
This commit is contained in:
@@ -339,6 +339,7 @@ namespace Otc
|
||||
GamePurseSlot = 21,
|
||||
GameFormatCreatureName = 22,
|
||||
GameSpellList = 23,
|
||||
GameClientPing = 24,
|
||||
// 23-50 unused yet
|
||||
// 51-100 reserved to be defined in lua
|
||||
LastGameFeature = 101
|
||||
|
@@ -55,6 +55,7 @@ void Game::resetGameStates()
|
||||
m_dead = false;
|
||||
m_serverBeat = 50;
|
||||
m_seq = 0;
|
||||
m_ping = -1;
|
||||
m_canReportBugs = false;
|
||||
m_fightMode = Otc::FightBalanced;
|
||||
m_chaseMode = Otc::DontChase;
|
||||
@@ -68,6 +69,12 @@ void Game::resetGameStates()
|
||||
if(container)
|
||||
container->onClose();
|
||||
}
|
||||
|
||||
if(m_pingEvent) {
|
||||
m_pingEvent->cancel();
|
||||
m_pingEvent = nullptr;
|
||||
}
|
||||
|
||||
m_containers.clear();
|
||||
m_vips.clear();
|
||||
m_gmActions.clear();
|
||||
@@ -122,6 +129,16 @@ void Game::processGameStart()
|
||||
enableBotCall();
|
||||
g_lua.callGlobalField("g_game", "onGameStart");
|
||||
disableBotCall();
|
||||
|
||||
if(g_game.getFeature(Otc::GameClientPing)) {
|
||||
m_pingEvent = g_dispatcher.cycleEvent([this] {
|
||||
if(m_protocolGame && m_protocolGame->isConnected()) {
|
||||
enableBotCall();
|
||||
m_protocolGame->sendPing();
|
||||
disableBotCall();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
void Game::processGameEnd()
|
||||
@@ -159,6 +176,7 @@ void Game::processPing()
|
||||
|
||||
void Game::processPingBack(int elapsed)
|
||||
{
|
||||
m_ping = elapsed;
|
||||
g_lua.callGlobalField("g_game", "onPingBack", elapsed);
|
||||
}
|
||||
|
||||
@@ -1175,8 +1193,9 @@ void Game::setClientVersion(int version)
|
||||
enableFeature(Otc::GamePlayerMarket);
|
||||
}
|
||||
|
||||
if(version >= 954) {
|
||||
if(version >= 953) {
|
||||
enableFeature(Otc::GamePurseSlot);
|
||||
enableFeature(Otc::GameClientPing);
|
||||
}
|
||||
|
||||
if(version >= 960) {
|
||||
|
@@ -252,6 +252,7 @@ public:
|
||||
bool isAttacking() { return !!m_attackingCreature; }
|
||||
bool isFollowing() { return !!m_followingCreature; }
|
||||
|
||||
int getPing() { return m_ping; }
|
||||
ContainerPtr getContainer(int index) { return m_containers[index]; }
|
||||
std::map<int, ContainerPtr> getContainers() { return m_containers; }
|
||||
std::map<int, Vip> getVips() { return m_vips; }
|
||||
@@ -289,6 +290,7 @@ private:
|
||||
bool m_denyBotCall;
|
||||
bool m_dead;
|
||||
int m_serverBeat;
|
||||
int m_ping;
|
||||
uint m_seq;
|
||||
Otc::FightModes m_fightMode;
|
||||
Otc::ChaseModes m_chaseMode;
|
||||
@@ -298,6 +300,7 @@ private:
|
||||
std::string m_characterName;
|
||||
std::string m_worldName;
|
||||
std::bitset<Otc::LastGameFeature> m_features;
|
||||
ScheduledEventPtr m_pingEvent;
|
||||
int m_clientVersion;
|
||||
};
|
||||
|
||||
|
@@ -37,6 +37,7 @@ LocalPlayer::LocalPlayer()
|
||||
m_states = 0;
|
||||
m_vocation = 0;
|
||||
m_walkLockExpiration = 0;
|
||||
m_lastWalkPing = -1;
|
||||
|
||||
m_skillsLevel.fill(-1);
|
||||
m_skillsBaseLevel.fill(-1);
|
||||
@@ -99,11 +100,8 @@ void LocalPlayer::walk(const Position& oldPos, const Position& newPos)
|
||||
// a prewalk was going on
|
||||
if(m_preWalking) {
|
||||
if(m_waitingWalkPong) {
|
||||
if(newPos == m_lastPrewalkDestionation) {
|
||||
m_lastWalkPings.push_back(m_walkPingTimer.ticksElapsed());
|
||||
if(m_lastWalkPings.size() > 10)
|
||||
m_lastWalkPings.pop_front();
|
||||
}
|
||||
if(newPos == m_lastPrewalkDestionation)
|
||||
m_lastWalkPing = m_walkPingTimer.ticksElapsed();
|
||||
|
||||
m_waitingWalkPong = false;
|
||||
}
|
||||
@@ -120,6 +118,7 @@ void LocalPlayer::walk(const Position& oldPos, const Position& newPos)
|
||||
}
|
||||
// no prewalk was going on, this must be an server side automated walk
|
||||
else {
|
||||
m_walkPingTimer.restart();
|
||||
m_autoWalking = true;
|
||||
if(m_autoWalkEndEvent)
|
||||
m_autoWalkEndEvent->cancel();
|
||||
@@ -136,6 +135,12 @@ void LocalPlayer::preWalk(Otc::Direction direction)
|
||||
if(m_preWalking && m_lastPrewalkDestionation == newPos)
|
||||
return;
|
||||
|
||||
m_waitingWalkPong = false;
|
||||
if(m_walkPingTimer.ticksElapsed() > getStepDuration() && m_idleTimer.ticksElapsed() > getStepDuration()*2) {
|
||||
m_waitingWalkPong = true;
|
||||
m_walkPingTimer.restart();
|
||||
}
|
||||
|
||||
m_preWalking = true;
|
||||
|
||||
if(m_autoWalkEndEvent)
|
||||
@@ -155,6 +160,8 @@ void LocalPlayer::cancelWalk(Otc::Direction direction)
|
||||
|
||||
m_lastPrewalkDone = true;
|
||||
m_waitingWalkPong = false;
|
||||
m_walkPingTimer.restart();
|
||||
m_idleTimer.restart();
|
||||
|
||||
// turn to the cancel direction
|
||||
if(direction != Otc::InvalidDirection)
|
||||
@@ -206,6 +213,7 @@ void LocalPlayer::terminateWalk()
|
||||
{
|
||||
Creature::terminateWalk();
|
||||
m_preWalking = false;
|
||||
m_idleTimer.restart();
|
||||
|
||||
auto self = asLocalPlayer();
|
||||
|
||||
@@ -458,17 +466,6 @@ void LocalPlayer::setSpells(const std::vector<int>& spells)
|
||||
}
|
||||
}
|
||||
|
||||
double LocalPlayer::getWalkPing()
|
||||
{
|
||||
if(m_lastWalkPings.empty())
|
||||
return 9999;
|
||||
|
||||
double sum = 0;
|
||||
for(int p : m_lastWalkPings)
|
||||
sum += p;
|
||||
return sum / (double)m_lastWalkPings.size();
|
||||
}
|
||||
|
||||
bool LocalPlayer::hasSight(const Position& pos)
|
||||
{
|
||||
return m_position.isInRange(pos, (Otc::VISIBLE_X_TILES - 1)/2, (Otc::VISIBLE_Y_TILES - 1)/2);
|
||||
|
@@ -66,7 +66,7 @@ public:
|
||||
int getSkillBaseLevel(Otc::Skill skill) { return m_skillsBaseLevel[skill]; }
|
||||
int getSkillLevelPercent(Otc::Skill skill) { return m_skillsLevelPercent[skill]; }
|
||||
int getVocation() { return m_vocation; }
|
||||
double getWalkPing();
|
||||
int getWalkPing() { return m_lastWalkPing; }
|
||||
double getHealth() { return m_health; }
|
||||
double getMaxHealth() { return m_maxHealth; }
|
||||
double getFreeCapacity() { return m_freeCapacity; }
|
||||
@@ -122,7 +122,8 @@ private:
|
||||
ScheduledEventPtr m_autoWalkEndEvent;
|
||||
stdext::boolean<false> m_waitingWalkPong;
|
||||
Timer m_walkPingTimer;
|
||||
std::deque<int> m_lastWalkPings;
|
||||
Timer m_idleTimer;
|
||||
int m_lastWalkPing;
|
||||
|
||||
std::array<int, Otc::LastSkill> m_skillsLevel;
|
||||
std::array<int, Otc::LastSkill> m_skillsBaseLevel;
|
||||
|
@@ -199,6 +199,7 @@ void OTClient::registerLuaFunctions()
|
||||
g_lua.bindSingletonFunction("g_game", "isDead", &Game::isDead, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isAttacking", &Game::isAttacking, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isFollowing", &Game::isFollowing, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getPing", &Game::getPing, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getContainer", &Game::getContainer, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getContainers", &Game::getContainers, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getVips", &Game::getVips, &g_game);
|
||||
@@ -412,6 +413,7 @@ void OTClient::registerLuaFunctions()
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getTotalCapacity", &LocalPlayer::getTotalCapacity);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getInventoryItem", &LocalPlayer::getInventoryItem);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getVocation", &LocalPlayer::getVocation);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getWalkPing", &LocalPlayer::getWalkPing);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isPremium", &LocalPlayer::isPremium);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isKnown", &LocalPlayer::isKnown);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isPreWalking", &LocalPlayer::isPreWalking);
|
||||
|
@@ -73,8 +73,8 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
|
||||
break;
|
||||
case Proto::GameServerPing:
|
||||
case Proto::GameServerPingBack:
|
||||
if((opcode == Proto::GameServerPing && g_game.getClientVersion() >= 953) ||
|
||||
(opcode == Proto::GameServerPingBack && g_game.getClientVersion() < 953))
|
||||
if((opcode == Proto::GameServerPing && g_game.getFeature(Otc::GameClientPing)) ||
|
||||
(opcode == Proto::GameServerPingBack && !g_game.getFeature(Otc::GameClientPing)))
|
||||
parsePingBack(msg);
|
||||
else
|
||||
parsePing(msg);
|
||||
|
Reference in New Issue
Block a user