summaryrefslogtreecommitdiff
path: root/src/localplayer.cpp
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2013-08-31 22:42:10 +0300
committerAndrei Karas <akaras@inbox.ru>2013-08-31 22:42:10 +0300
commit00cda69b883d6354f093be6ee39a7936cb798979 (patch)
treef1daa290abfb53180bd8420a45fe6dff1c7a2ab3 /src/localplayer.cpp
parent5919cdc663d5f60a8c5cc7e50ad0c43a18cf9829 (diff)
downloadmv-00cda69b883d6354f093be6ee39a7936cb798979.tar.gz
mv-00cda69b883d6354f093be6ee39a7936cb798979.tar.bz2
mv-00cda69b883d6354f093be6ee39a7936cb798979.tar.xz
mv-00cda69b883d6354f093be6ee39a7936cb798979.zip
move being related files into being dir.
Diffstat (limited to 'src/localplayer.cpp')
-rw-r--r--src/localplayer.cpp4354
1 files changed, 0 insertions, 4354 deletions
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
deleted file mode 100644
index 02c1d6ed9..000000000
--- a/src/localplayer.cpp
+++ /dev/null
@@ -1,4354 +0,0 @@
-/*
- * The ManaPlus Client
- * Copyright (C) 2004-2009 The Mana World Development Team
- * Copyright (C) 2009-2010 The Mana Developers
- * Copyright (C) 2011-2013 The ManaPlus Developers
- *
- * This file is part of The ManaPlus Client.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "localplayer.h"
-
-#include "actorspritemanager.h"
-#include "client.h"
-#include "configuration.h"
-#include "dropshortcut.h"
-#include "effectmanager.h"
-#include "guild.h"
-#include "item.h"
-#include "maplayer.h"
-#include "party.h"
-#include "playerinfo.h"
-#include "playerrelations.h"
-#include "simpleanimation.h"
-#include "soundconsts.h"
-#include "soundmanager.h"
-#include "statuseffect.h"
-#include "walklayer.h"
-
-#include "particle/particle.h"
-
-#include "input/keyboardconfig.h"
-
-#include "gui/chatwindow.h"
-#include "gui/gui.h"
-#include "gui/ministatuswindow.h"
-#include "gui/okdialog.h"
-#include "gui/outfitwindow.h"
-#include "gui/shopwindow.h"
-#include "gui/sdlfont.h"
-#include "gui/skilldialog.h"
-#include "gui/socialwindow.h"
-#include "gui/updaterwindow.h"
-#include "gui/viewport.h"
-
-#include "gui/widgets/gmtab.h"
-#include "gui/widgets/whispertab.h"
-
-#include "render/graphics.h"
-
-#include "net/beinghandler.h"
-#include "net/chathandler.h"
-#include "net/guildhandler.h"
-#include "net/inventoryhandler.h"
-#include "net/net.h"
-#include "net/partyhandler.h"
-#include "net/playerhandler.h"
-#include "net/skillhandler.h"
-#include "net/tradehandler.h"
-
-#include "resources/imageset.h"
-#include "resources/iteminfo.h"
-#include "resources/resourcemanager.h"
-
-#include "utils/gettext.h"
-
-#include "mumblemanager.h"
-
-#include <climits>
-
-#include "debug.h"
-
-static const int16_t awayLimitTimer = 60;
-static const int MAX_TICK_VALUE = INT_MAX / 2;
-
-typedef std::map<int, Guild*>::const_iterator GuildMapCIter;
-
-LocalPlayer *player_node = nullptr;
-
-extern std::list<BeingCacheEntry*> beingInfoCache;
-extern OkDialog *weightNotice;
-extern int weightNoticeTime;
-extern MiniStatusWindow *miniStatusWindow;
-extern SkillDialog *skillDialog;
-
-LocalPlayer::LocalPlayer(const int id, const int subtype) :
- Being(id, PLAYER, subtype, nullptr),
- mGMLevel(0),
- mInvertDirection(0),
- mCrazyMoveType(config.getIntValue("crazyMoveType")),
- mCrazyMoveState(0),
- mAttackWeaponType(config.getIntValue("attackWeaponType")),
- mQuickDropCounter(config.getIntValue("quickDropCounter")),
- mMoveState(0),
- mPickUpType(config.getIntValue("pickUpType")),
- mMagicAttackType(config.getIntValue("magicAttackType")),
- mPvpAttackType(config.getIntValue("pvpAttackType")),
- mMoveToTargetType(config.getIntValue("moveToTargetType")),
- mAttackType(config.getIntValue("attackType")),
- mFollowMode(config.getIntValue("followMode")),
- mImitationMode(config.getIntValue("imitationMode")),
- mLastTargetX(0),
- mLastTargetY(0),
- mHomes(),
- mTarget(nullptr),
- mPlayerFollowed(),
- mPlayerImitated(),
- mNextDestX(0),
- mNextDestY(0),
- mPickUpTarget(nullptr),
- mLastAction(-1),
- mStatusEffectIcons(),
- mLocalWalkTime(-1),
- mMessages(),
- mMessageTime(0),
- mAwayListener(new AwayListener),
- mAwayDialog(nullptr),
- mPingSendTick(0),
- mPingTime(0),
- mAfkTime(0),
- mActivityTime(0),
- mNavigateX(0),
- mNavigateY(0),
- mNavigateId(0),
- mCrossX(0),
- mCrossY(0),
- mOldX(0),
- mOldY(0),
- mOldTileX(0),
- mOldTileY(0),
- mNavigatePath(),
- mLastHitFrom(),
- mWaitFor(),
- mAdvertTime(0),
- mTestParticle(nullptr),
- mTestParticleName(),
- mTestParticleTime(0),
- mTestParticleHash(0l),
- mWalkingDir(0),
- mUpdateName(true),
- mBlockAdvert(false),
- mTargetDeadPlayers(config.getBoolValue("targetDeadPlayers")),
- mServerAttack(config.getBoolValue("serverAttack")),
- mEnableAdvert(config.getBoolValue("enableAdvert")),
- mTradebot(config.getBoolValue("tradebot")),
- mTargetOnlyReachable(config.getBoolValue("targetOnlyReachable")),
- mDisableGameModifiers(config.getBoolValue("disableGameModifiers")),
- mIsServerBuggy(serverConfig.getValueBool("enableBuggyServers", true)),
- mSyncPlayerMove(config.getBoolValue("syncPlayerMove")),
- mDrawPath(config.getBoolValue("drawPath")),
- mAttackMoving(config.getBoolValue("attackMoving")),
- mAttackNext(config.getBoolValue("attackNext")),
- mShowJobExp(config.getBoolValue("showJobExp")),
- mNextStep(false),
- mDisableCrazyMove(false),
- mGoingToTarget(false),
- mKeepAttacking(false),
- mPathSetByMouse(false),
- mWaitPing(false),
- mAwayMode(false),
- mPseudoAwayMode(false),
- mShowNavigePath(false)
-{
- logger->log1("LocalPlayer::LocalPlayer");
-
- listen(CHANNEL_ATTRIBUTES);
-
- mAttackRange = 0;
- mLevel = 1;
- mAdvanced = true;
- mTextColor = &Theme::getThemeColor(Theme::PLAYER);
- if (userPalette)
- mNameColor = &userPalette->getColor(UserPalette::SELF);
- else
- mNameColor = nullptr;
-
- PlayerInfo::setStatBase(PlayerInfo::WALK_SPEED,
- static_cast<int>(getWalkSpeed().x));
- PlayerInfo::setStatMod(PlayerInfo::WALK_SPEED, 0);
-
- loadHomes();
-
- config.addListener("showownname", this);
- config.addListener("targetDeadPlayers", this);
- serverConfig.addListener("enableBuggyServers", this);
- config.addListener("syncPlayerMove", this);
- config.addListener("drawPath", this);
- config.addListener("serverAttack", this);
- config.addListener("attackMoving", this);
- config.addListener("attackNext", this);
- config.addListener("showJobExp", this);
- config.addListener("enableAdvert", this);
- config.addListener("tradebot", this);
- config.addListener("targetOnlyReachable", this);
- setShowName(config.getBoolValue("showownname"));
-}
-
-LocalPlayer::~LocalPlayer()
-{
- logger->log1("LocalPlayer::~LocalPlayer");
-
- config.removeListeners(this);
- serverConfig.removeListener("enableBuggyServers", this);
-
- if (mAwayDialog)
- {
- soundManager.volumeRestore();
- delete mAwayDialog;
- mAwayDialog = nullptr;
- }
- delete mAwayListener;
- mAwayListener = nullptr;
-}
-
-void LocalPlayer::logic()
-{
- BLOCK_START("LocalPlayer::logic")
-#ifdef USE_MUMBLE
- if (mumbleManager)
- mumbleManager->setPos(mX, mY, mDirection);
-#endif
-
- // Actions are allowed once per second
- if (get_elapsed_time(mLastAction) >= 1000)
- mLastAction = -1;
-
- if (mActivityTime == 0 || mLastAction != -1)
- mActivityTime = cur_time;
-
- if ((mAction != MOVE || mNextStep) && !mNavigatePath.empty())
- {
- mNextStep = false;
- int dist = 5;
- if (!mSyncPlayerMove)
- dist = 20;
-
- if ((mNavigateX || mNavigateY) &&
- ((mCrossX + dist >= mX && mCrossX <= mX + dist
- && mCrossY + dist >= mY && mCrossY <= mY + dist)
- || (!mCrossX && !mCrossY)))
- {
- const Path::const_iterator i = mNavigatePath.begin();
- if ((*i).x == mX && (*i).y == mY)
- mNavigatePath.pop_front();
- else
- moveTo((*i).x, (*i).y);
- }
- }
-
- // Show XP messages
- if (!mMessages.empty())
- {
- if (mMessageTime == 0)
- {
- MessagePair info = mMessages.front();
-
- if (particleEngine)
- {
- particleEngine->addTextRiseFadeOutEffect(
- info.first,
- getPixelX(),
- getPixelY() - 48,
- &userPalette->getColor(info.second),
- gui->getInfoParticleFont(), true);
- }
-
- mMessages.pop_front();
- mMessageTime = 30;
- }
- mMessageTime--;
- }
-
-#ifdef MANASERV_SUPPORT
- PlayerInfo::logic();
-#endif
-
- if (mTarget)
- {
- if (mTarget->getType() == ActorSprite::NPC)
- {
- // NPCs are always in range
- mTarget->setTargetType(TCT_IN_RANGE);
- }
- else
- {
- // Find whether target is in range
-#ifdef MANASERV_SUPPORT
- const int rangeX =
- (Net::getNetworkType() == ServerInfo::MANASERV) ?
- static_cast<int>(abs(static_cast<int>(mTarget->getPosition().x
- - getPosition().x))) :
- static_cast<int>(abs(mTarget->getTileX() - getTileX()));
- const int rangeY =
- (Net::getNetworkType() == ServerInfo::MANASERV) ?
- static_cast<int>(abs(static_cast<int>(mTarget->getPosition().y
- - getPosition().y))) :
- static_cast<int>(abs(mTarget->getTileY() - getTileY()));
-#else
- const int rangeX = static_cast<int>(
- abs(mTarget->getTileX() - getTileX()));
- const int rangeY = static_cast<int>(
- abs(mTarget->getTileY() - getTileY()));
-#endif
- const int attackRange = getAttackRange();
- const TargetCursorType targetType = rangeX > attackRange ||
- rangeY > attackRange ?
- TCT_NORMAL : TCT_IN_RANGE;
- mTarget->setTargetType(targetType);
-
- if (!mTarget->isAlive() && (!mTargetDeadPlayers
- || mTarget->getType() != Being::PLAYER))
- {
- stopAttack(true);
- }
-
- if (mKeepAttacking && mTarget)
- attack(mTarget, true);
- }
- }
-
- Being::logic();
- BLOCK_END("LocalPlayer::logic")
-}
-
-void LocalPlayer::slowLogic()
-{
- BLOCK_START("LocalPlayer::slowLogic")
- const int time = cur_time;
- if (weightNotice && weightNoticeTime < time)
- {
- weightNotice->scheduleDelete();
- weightNotice = nullptr;
- weightNoticeTime = 0;
- }
-
- if (serverVersion < 4 && mEnableAdvert && !mBlockAdvert
- && mAdvertTime < cur_time)
- {
- uint8_t smile = FLAG_SPECIAL;
- if (mTradebot && shopWindow && !shopWindow->isShopEmpty())
- smile |= FLAG_SHOP;
-
- if (mAwayMode || mPseudoAwayMode)
- smile |= FLAG_AWAY;
-
- if (mInactive)
- smile |= FLAG_INACTIVE;
-
- if (emote(smile))
- mAdvertTime = time + 60;
- else
- mAdvertTime = time + 30;
- }
-
- if (mTestParticleTime != time && !mTestParticleName.empty())
- {
- unsigned long hash = UpdaterWindow::getFileHash(mTestParticleName);
- if (hash != mTestParticleHash)
- {
- setTestParticle(mTestParticleName, false);
- mTestParticleHash = hash;
- }
- mTestParticleTime = time;
- }
-
- BLOCK_END("LocalPlayer::slowLogic")
-}
-
-void LocalPlayer::setAction(const Action &action, const int attackType)
-{
- if (action == DEAD)
- {
- if (!mLastHitFrom.empty())
- {
- // TRANSLATORS: chat message after death
- debugMsg(strprintf(_("You were killed by %s"),
- mLastHitFrom.c_str()));
- mLastHitFrom.clear();
- }
- setTarget(nullptr);
- }
-
- Being::setAction(action, attackType);
-#ifdef USE_MUMBLE
- if (mumbleManager)
- mumbleManager->setAction(static_cast<int>(action));
-#endif
-}
-
-void LocalPlayer::setGMLevel(const int level)
-{
- mGMLevel = level;
-
- if (level > 0)
- {
- setGM(true);
- if (chatWindow)
- {
- chatWindow->loadGMCommands();
- if (!gmChatTab && config.getBoolValue("enableGmTab"))
- gmChatTab = new GmTab(chatWindow);
- }
- }
-}
-
-#ifdef MANASERV_SUPPORT
-Position LocalPlayer::getNextWalkPosition(const unsigned char dir) const
-{
- // Compute where the next tile will be set.
- int dx = 0, dy = 0;
- if (dir & Being::UP)
- dy--;
- if (dir & Being::DOWN)
- dy++;
- if (dir & Being::LEFT)
- dx--;
- if (dir & Being::RIGHT)
- dx++;
-
- const Vector &pos = getPosition();
-
- // If no map or no direction is given, give back the current player position
- if (!mMap || (!dx && !dy))
- return Position(static_cast<int>(pos.x), static_cast<int>(pos.y));
-
- const int posX = static_cast<int>(pos.x);
- const int posY = static_cast<int>(pos.y);
- // Get the current tile pos and its offset
- const int tileX = posX / mMap->getTileWidth();
- const int tileY = posY / mMap->getTileHeight();
- const int offsetX = posX % mMap->getTileWidth();
- const int offsetY = posY % mMap->getTileHeight();
- const unsigned char walkMask = getWalkMask();
- const int radius = getCollisionRadius();
-
- // Get the walkability of every surrounding tiles.
- bool wTopLeft = mMap->getWalk(tileX - 1, tileY - 1, walkMask);
- const bool wTop = mMap->getWalk(tileX, tileY - 1, walkMask);
- bool wTopRight = mMap->getWalk(tileX + 1, tileY - 1, walkMask);
- const bool wLeft = mMap->getWalk(tileX - 1, tileY, walkMask);
- const bool wRight = mMap->getWalk(tileX + 1, tileY, walkMask);
- bool wBottomLeft = mMap->getWalk(tileX - 1, tileY + 1, walkMask);
- const bool wBottom = mMap->getWalk(tileX, tileY + 1, walkMask);
- bool wBottomRight = mMap->getWalk(tileX + 1, tileY + 1, walkMask);
-
- // Make diagonals unwalkable when both straight directions are blocking
- if (!wTop)
- {
- if (!wRight)
- wTopRight = false;
- if (!wLeft)
- wTopLeft = false;
- }
- if (!wBottom)
- {
- if (!wRight)
- wBottomRight = false;
- if (!wLeft)
- wBottomLeft = false;
- }
-
- // We'll make tests for each desired direction
-
- // Handle diagonal cases by setting the way back to a straight direction
- // when necessary.
- if (dx && dy)
- {
- // Going top-right
- if (dx > 0 && dy < 0)
- {
- if (!wTopRight)
- {
- // Choose a straight direction when diagonal target is blocked
- if (!wTop && wRight)
- {
- dy = 0;
- }
- else if (wTop && !wRight)
- {
- dx = 0;
- }
- else if (!wTop && !wRight)
- {
- return Position(tileX * 32 + 32 - radius,
- tileY * 32 + getCollisionRadius());
- }
- else // Both straight direction are walkable
- {
- // Go right when below the corner
- if (offsetY >= (offsetX / mMap->getTileHeight()
- - (offsetX / mMap->getTileWidth()
- * mMap->getTileHeight()) ))
- {
- dy = 0;
- }
- else // Go up otherwise
- {
- dx = 0;
- }
- }
- }
- else // The diagonal is walkable
- {
- return mMap->checkNodeOffsets(radius,
- walkMask, Position(posX + 32, posY - 32));
- }
- }
-
- // Going top-left
- if (dx < 0 && dy < 0)
- {
- if (!wTopLeft)
- {
- // Choose a straight direction when diagonal target is blocked
- if (!wTop && wLeft)
- {
- dy = 0;
- }
- else if (wTop && !wLeft)
- {
- dx = 0;
- }
- else if (!wTop && !wLeft)
- {
- return Position(tileX * 32 + radius,
- tileY * 32 + radius);
- }
- else // Both straight direction are walkable
- {
- // Go left when below the corner
- if (offsetY >= (offsetX / mMap->getTileWidth()
- * mMap->getTileHeight()))
- {
- dy = 0;
- }
- else // Go up otherwise
- {
- dx = 0;
- }
- }
- }
- else // The diagonal is walkable
- {
- return mMap->checkNodeOffsets(radius,
- walkMask, Position(posX - 32, posY - 32));
- }
- }
-
- // Going bottom-left
- if (dx < 0 && dy > 0)
- {
- if (!wBottomLeft)
- {
- // Choose a straight direction when diagonal target is blocked
- if (!wBottom && wLeft)
- {
- dy = 0;
- }
- else if (wBottom && !wLeft)
- {
- dx = 0;
- }
- else if (!wBottom && !wLeft)
- {
- return Position(tileX * 32 + radius,
- tileY * 32 + 32 - radius);
- }
- else // Both straight direction are walkable
- {
- // Go down when below the corner
- if (offsetY >= (offsetX / mMap->getTileHeight()
- - (offsetX / mMap->getTileWidth()
- * mMap->getTileHeight())))
- {
- dx = 0;
- }
- else // Go left otherwise
- {
- dy = 0;
- }
- }
- }
- else // The diagonal is walkable
- {
- return mMap->checkNodeOffsets(radius,
- walkMask, Position(posX - 32, posY + 32));
- }
- }
-
- // Going bottom-right
- if (dx > 0 && dy > 0)
- {
- if (!wBottomRight)
- {
- // Choose a straight direction when diagonal target is blocked
- if (!wBottom && wRight)
- {
- dy = 0;
- }
- else if (wBottom && !wRight)
- {
- dx = 0;
- }
- else if (!wBottom && !wRight)
- {
- return Position(tileX * 32 + 32 - radius,
- tileY * 32 + 32 - radius);
- }
- else // Both straight direction are walkable
- {
- // Go down when below the corner
- if (offsetY >= (offsetX / mMap->getTileWidth()
- * mMap->getTileHeight()))
- {
- dx = 0;
- }
- else // Go right otherwise
- {
- dy = 0;
- }
- }
- }
- else // The diagonal is walkable
- {
- return mMap->checkNodeOffsets(radius,
- walkMask, Position(posX + 32, posY + 32));
- }
- }
- } // End of diagonal cases
-
- // Straight directions
- // Right direction
- if (dx > 0 && !dy)
- {
- // If the straight destination is blocked,
- // Make the player go the closest possible.
- if (!wRight)
- {
- return Position(tileX * 32 + 32 - radius, posY);
- }
- else
- {
- if (!wTopRight)
- {
- // If we're going to collide with the top-right corner
- if (offsetY - radius < 0)
- {
- // We make the player corrects its offset
- // before going further
- return Position(tileX * 32 + 32 - radius,
- tileY * 32 + radius);
- }
- }
-
- if (!wBottomRight)
- {
- // If we're going to collide with the bottom-right corner
- if (offsetY + radius > 32)
- {
- // We make the player corrects its offset
- // before going further
- return Position(tileX * 32 + 32 - radius,
- tileY * 32 + 32 - radius);
- }
- }
- // If the way is clear, step up one checked tile ahead.
- return mMap->checkNodeOffsets(radius,
- walkMask, Position(posX + 32, posY));
- }
- }
-
- // Left direction
- if (dx < 0 && !dy)
- {
- // If the straight destination is blocked,
- // Make the player go the closest possible.
- if (!wLeft)
- {
- return Position(tileX * 32 + radius, posY);
- }
- else
- {
- if (!wTopLeft)
- {
- // If we're going to collide with the top-left corner
- if (offsetY - radius < 0)
- {
- // We make the player corrects its offset
- // before going further
- return Position(tileX * 32 + radius,
- tileY * 32 + radius);
- }
- }
-
- if (!wBottomLeft)
- {
- // If we're going to collide with the bottom-left corner
- if (offsetY + radius > 32)
- {
- // We make the player corrects its offset
- // before going further
- return Position(tileX * 32 + radius,
- tileY * 32 + 32 - radius);
- }
- }
- // If the way is clear, step up one checked tile ahead.
- return mMap->checkNodeOffsets(radius,
- walkMask, Position(posX - 32, posY));
- }
- }
-
- // Up direction
- if (!dx && dy < 0)
- {
- // If the straight destination is blocked,
- // Make the player go the closest possible.
- if (!wTop)
- {
- return Position(posX, tileY * 32 + radius);
- }
- else
- {
- if (!wTopLeft)
- {
- // If we're going to collide with the top-left corner
- if (offsetX - radius < 0)
- {
- // We make the player corrects its offset
- // before going further
- return Position(tileX * 32 + radius,
- tileY * 32 + radius);
- }
- }
-
- if (!wTopRight)
- {
- // If we're going to collide with the top-right corner
- if (offsetX + radius > 32)
- {
- // We make the player corrects its offset
- // before going further
- return Position(tileX * 32 + 32 - radius,
- tileY * 32 + radius);
- }
- }
- // If the way is clear, step up one checked tile ahead.
- return mMap->checkNodeOffsets(radius,
- walkMask, Position(posX, posY - 32));
- }
- }
-
- // Down direction
- if (!dx && dy > 0)
- {
- // If the straight destination is blocked,
- // Make the player go the closest possible.
- if (!wBottom)
- {
- return Position(posX, tileY * 32 + 32 - radius);
- }
- else
- {
- if (!wBottomLeft)
- {
- // If we're going to collide with the bottom-left corner
- if (offsetX - radius < 0)
- {
- // We make the player corrects its offset
- // before going further
- return Position(tileX * 32 + radius,
- tileY * 32 + 32 - radius);
- }
- }
-
- if (!wBottomRight)
- {
- // If we're going to collide with the bottom-right corner
- if (offsetX + radius > 32)
- {
- // We make the player corrects its offset
- // before going further
- return Position(tileX * 32 + 32 - radius,
- tileY * 32 + 32 - radius);
- }
- }
- // If the way is clear, step up one checked tile ahead.
- return mMap->checkNodeOffsets(radius,
- walkMask, Position(posX, posY + 32));
- }
- }
-
- // Return the current position if everything else has failed.
- return Position(posX, posY);
-}
-#endif
-
-void LocalPlayer::nextTile(unsigned char dir A_UNUSED = 0)
-{
-#ifdef MANASERV_SUPPORT
- if (Net::getNetworkType() != ServerInfo::MANASERV)
-#endif
- {
- Party *const party = Party::getParty(1);
- if (party)
- {
- PartyMember *const pm = party->getMember(getName());
- if (pm)
- {
- pm->setX(mX);
- pm->setY(mY);
- }
- }
-
- if (mPath.empty())
- {
- if (mPickUpTarget)
- pickUp(mPickUpTarget);
-
- if (mWalkingDir)
- startWalking(mWalkingDir);
- }
- else if (mPath.size() == 1)
- {
- if (mPickUpTarget)
- pickUp(mPickUpTarget);
- }
-
- if (mGoingToTarget && mTarget && withinAttackRange(mTarget))
- {
- mAction = Being::STAND;
- attack(mTarget, true);
- mGoingToTarget = false;
- mPath.clear();
- return;
- }
- else if (mGoingToTarget && !mTarget)
- {
- mGoingToTarget = false;
- mPath.clear();
- }
-
- if (mPath.empty())
- {
- if (mNavigatePath.empty() || mAction != MOVE)
- setAction(STAND);
- else
- mNextStep = true;
- }
- else
- {
- Being::nextTile();
- }
- }
-#ifdef MANASERV_SUPPORT
- else
- {
- if (!mMap || !dir)
- return;
-
- const Vector &pos = getPosition();
- const Position destination = getNextWalkPosition(dir);
-
- if (static_cast<int>(pos.x) != destination.x
- || static_cast<int>(pos.y) != destination.y)
- {
- setDestination(destination.x, destination.y);
- }
- else if (dir != mDirection)
- {
- Net::getPlayerHandler()->setDirection(dir);
- setDirection(dir);
- }
- }
-#endif
-}
-
-bool LocalPlayer::pickUp(FloorItem *const item)
-{
- if (!item)
- return false;
-
- if (!client->limitPackets(PACKET_PICKUP))
- return false;
-
- const int dx = item->getTileX() - mX;
- const int dy = item->getTileY() - mY;
- int dist = 6;
-
- if (mPickUpType >= 4 && mPickUpType <= 6)
- dist = 4;
-
- if (dx * dx + dy * dy < dist)
- {
- if (actorSpriteManager && actorSpriteManager->checkForPickup(item))
- {
- Net::getPlayerHandler()->pickUp(item);
- mPickUpTarget = nullptr;
- }
- }
- else if (mPickUpType >= 4 && mPickUpType <= 6)
- {
-#ifdef MANASERV_SUPPORT
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- setDestination(item->getPixelX() + 16, item->getPixelY() + 16);
- mPickUpTarget = item;
- mPickUpTarget->addActorSpriteListener(this);
- }
- else
-#endif
- {
- const Vector &playerPos = getPosition();
- const Path debugPath = mMap->findPath(
- static_cast<int>(playerPos.x - 16) / 32,
- static_cast<int>(playerPos.y - 32) / 32,
- item->getTileX(), item->getTileY(), getWalkMask(), 0);
- if (!debugPath.empty())
- navigateTo(item->getTileX(), item->getTileY());
- else
- setDestination(item->getTileX(), item->getTileY());
-
- mPickUpTarget = item;
- mPickUpTarget->addActorSpriteListener(this);
- }
- }
- return true;
-}
-
-void LocalPlayer::actorSpriteDestroyed(const ActorSprite &actorSprite)
-{
- if (mPickUpTarget == &actorSprite)
- mPickUpTarget = nullptr;
-}
-
-Being *LocalPlayer::getTarget() const
-{
- return mTarget;
-}
-
-void LocalPlayer::setTarget(Being *const target)
-{
- if (target == this && target)
- return;
-
- if (target == mTarget)
- return;
-
- Being *oldTarget = nullptr;
- if (mTarget)
- {
- mTarget->untarget();
- oldTarget = mTarget;
- }
-
- if (mTarget && mTarget->getType() == ActorSprite::MONSTER)
- mTarget->setShowName(false);
-
- mTarget = target;
-
- if (oldTarget)
- oldTarget->updateName();
-
- if (mTarget)
- {
- mLastTargetX = mTarget->getTileX();
- mLastTargetY = mTarget->getTileY();
- mTarget->updateName();
- }
-
- if (target && target->getType() == ActorSprite::MONSTER)
- target->setShowName(true);
-}
-
-void LocalPlayer::setDestination(const int x, const int y)
-{
- mActivityTime = cur_time;
-
- if (getAttackType() == 0 || !mAttackMoving)
- mKeepAttacking = false;
-
- // Only send a new message to the server when destination changes
- if (x != mDest.x || y != mDest.y)
- {
- if (mInvertDirection != 1)
- {
- Net::getPlayerHandler()->setDestination(x, y, mDirection);
- Being::setDestination(x, y);
- }
- else if (mInvertDirection == 1)
- {
- uint8_t newDir = 0;
- if (mDirection & UP)
- newDir |= DOWN;
- if (mDirection & LEFT)
- newDir |= RIGHT;
- if (mDirection & DOWN)
- newDir |= UP;
- if (mDirection & RIGHT)
- newDir |= LEFT;
-
- Net::getPlayerHandler()->setDestination(x, y, newDir);
-
-// if (client->limitPackets(PACKET_DIRECTION))
- {
- setDirection(newDir);
- Net::getPlayerHandler()->setDirection(newDir);
- }
-
- Being::setDestination(x, y);
- }
- else
- {
-#ifdef MANASERV_SUPPORT
- // Manaserv:
- // If the destination given to being class is accepted,
- // we inform the Server.
- if ((x == mDest.x && y == mDest.y)
- || Net::getNetworkType() != ServerInfo::MANASERV)
-#endif
- {
- Net::getPlayerHandler()->setDestination(x, y, mDirection);
- }
- }
- }
-}
-
-void LocalPlayer::setWalkingDir(const unsigned char dir)
-{
- // This function is called by Game::handleInput()
-
-#ifdef MANASERV_SUPPORT
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- // First if player is pressing key for the direction he is already
- // going, do nothing more...
-
- // Else if he is pressing a key, and its different from what he has
- // been pressing, stop (do not send this stop to the server) and
- // start in the new direction
- if (dir && (dir != getWalkingDir()))
- stopWalking(false);
-
- // Else, he is not pressing a key,
- // and the current path hasn't been sent by mouse,
- // then, stop (sending to server).
- else if (!dir)
- {
- if (!mPathSetByMouse)
- stopWalking(true);
- return;
- }
-
- // If the delay to send another walk message to the server hasn't
- // expired, don't do anything or we could get disconnected for
- // spamming the server
- if (get_elapsed_time(mLocalWalkTime) < walkingKeyboardDelay)
- return;
- }
-#endif
-
- mWalkingDir = dir;
-
- // If we're not already walking, start walking.
- if (mAction != MOVE && dir)
- {
- startWalking(dir);
- }
-#ifdef MANASERV_SUPPORT
- else if (mAction == MOVE && (Net::getNetworkType()
- == ServerInfo::MANASERV))
- {
- nextTile(dir);
- }
-#endif
-}
-
-void LocalPlayer::startWalking(const unsigned char dir)
-{
- // This function is called by setWalkingDir(),
- // but also by nextTile() for TMW-Athena...
- if (!mMap || !dir)
- return;
-
- mPickUpTarget = nullptr;
- if (mAction == MOVE && !mPath.empty())
- {
- // Just finish the current action, otherwise we get out of sync
-#ifdef MANASERV_SUPPORT
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- const Vector &pos = getPosition();
- Being::setDestination(static_cast<int>(pos.x),
- static_cast<int>(pos.y));
- }
- else
-#endif
- {
- Being::setDestination(mX, mY);
- }
- return;
- }
-
- int dx = 0, dy = 0;
- if (dir & UP)
- dy--;
- if (dir & DOWN)
- dy++;
- if (dir & LEFT)
- dx--;
- if (dir & RIGHT)
- dx++;
-
-#ifdef MANASERV_SUPPORT
- if (Net::getNetworkType() != ServerInfo::MANASERV)
-#endif
- {
- const unsigned char walkMask = getWalkMask();
- // Prevent skipping corners over colliding tiles
- if (dx && !mMap->getWalk(mX + dx, mY, walkMask))
- dx = 0;
- if (dy && !mMap->getWalk(mX, mY + dy, walkMask))
- dy = 0;
-
- // Choose a straight direction when diagonal target is blocked
- if (dx && dy && !mMap->getWalk(mX + dx, mY + dy, walkMask))
- dx = 0;
-
- // Walk to where the player can actually go
- if ((dx || dy) && mMap->getWalk(mX + dx, mY + dy, walkMask))
- {
- setDestination(mX + dx, mY + dy);
- }
- else if (dir != mDirection)
- {
- // If the being can't move, just change direction
-
-// if (client->limitPackets(PACKET_DIRECTION))
- {
- Net::getPlayerHandler()->setDirection(dir);
- setDirection(dir);
- }
- }
- }
-#ifdef MANASERV_SUPPORT
- else
- {
- nextTile(dir);
- }
-#endif
-}
-
-void LocalPlayer::stopWalking(const bool sendToServer)
-{
- if (mAction == MOVE && mWalkingDir)
- {
- mWalkingDir = 0;
- mLocalWalkTime = 0;
- mPickUpTarget = nullptr;
-
- setDestination(static_cast<int>(getPosition().x),
- static_cast<int>(getPosition().y));
- if (sendToServer)
- {
- Net::getPlayerHandler()->setDestination(
- static_cast<int>(getPosition().x),
- static_cast<int>(getPosition().y), -1);
- }
- setAction(STAND);
- }
-
- // No path set anymore, so we reset the path by mouse flag
- mPathSetByMouse = false;
-
- clearPath();
- navigateClean();
-}
-
-bool LocalPlayer::toggleSit() const
-{
- if (!client->limitPackets(PACKET_SIT))
- return false;
-
- Being::Action newAction;
- switch (mAction)
- {
- case STAND:
- case SPAWN:
- newAction = SIT;
- break;
- case SIT:
- newAction = STAND;
- break;
- case MOVE:
- case ATTACK:
- case DEAD:
- case HURT:
- default:
- return true;
- }
-
- Net::getPlayerHandler()->changeAction(newAction);
- return true;
-}
-
-bool LocalPlayer::updateSit() const
-{
- if (!client->limitPackets(PACKET_SIT))
- return false;
-
- Net::getPlayerHandler()->changeAction(mAction);
- return true;
-}
-
-bool LocalPlayer::emote(const uint8_t emotion)
-{
- if (!client->limitPackets(PACKET_EMOTE))
- return false;
-
- Net::getPlayerHandler()->emote(emotion);
- return true;
-}
-
-void LocalPlayer::attack(Being *const target, const bool keep,
- const bool dontChangeEquipment)
-{
-#ifdef MANASERV_SUPPORT
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- if (mLastAction != -1)
- return;
-
- // Can only attack when standing still
- if (mAction != STAND && mAction != ATTACK)
- return;
- }
-#endif
-
- mKeepAttacking = keep;
-
- if (!target || target->getType() == ActorSprite::NPC)
- return;
-
- if (mTarget != target || !mTarget)
- setTarget(target);
-
-#ifdef MANASERV_SUPPORT
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- const Vector &plaPos = this->getPosition();
- const Vector &tarPos = mTarget->getPosition();
- const int dist_x = static_cast<int>(plaPos.x - tarPos.x);
- const int dist_y = static_cast<int>(plaPos.y - tarPos.y);
-
- if (abs(dist_y) >= abs(dist_x))
- {
- if (dist_y < 0)
- setDirection(DOWN);
- else
- setDirection(UP);
- }
- else
- {
- if (dist_x < 0)
- setDirection(RIGHT);
- else
- setDirection(LEFT);
- }
-
- mLastAction = tick_time;
- }
- else
-#endif
- {
- const int dist_x = target->getTileX() - mX;
- const int dist_y = target->getTileY() - mY;
-
- // Must be standing or sitting to attack
- if (mAction != STAND && mAction != SIT)
- return;
-
- if (abs(dist_y) >= abs(dist_x))
- {
- if (dist_y > 0)
- setDirection(DOWN);
- else
- setDirection(UP);
- }
- else
- {
- if (dist_x > 0)
- setDirection(RIGHT);
- else
- setDirection(LEFT);
- }
-
- mActionTime = tick_time;
- }
-
- if (target->getType() != Being::PLAYER || checAttackPermissions(target))
- {
- setAction(ATTACK);
-
- if (!client->limitPackets(PACKET_ATTACK))
- return;
-
- if (!dontChangeEquipment)
- changeEquipmentBeforeAttack(target);
-
- Net::getPlayerHandler()->attack(target->getId(), mServerAttack);
- }
-
-#ifdef MANASERV_SUPPORT
- if ((Net::getNetworkType() != ServerInfo::MANASERV) && !keep)
-#else
- if (!keep)
-#endif
- stopAttack();
-}
-
-void LocalPlayer::stopAttack(const bool keepAttack)
-{
- if (!client->limitPackets(PACKET_STOPATTACK))
- return;
-
- if (mServerAttack && mAction == ATTACK)
- Net::getPlayerHandler()->stopAttack();
-
- untarget();
- if (!keepAttack || !mAttackNext)
- mKeepAttacking = false;
-}
-
-void LocalPlayer::untarget()
-{
- if (mAction == ATTACK)
- setAction(STAND);
-
- if (mTarget)
- setTarget(nullptr);
-}
-
-void LocalPlayer::pickedUp(const ItemInfo &itemInfo, const int amount,
- const unsigned char color, const int floorItemId,
- const unsigned char fail)
-{
- if (fail)
- {
- if (actorSpriteManager && floorItemId)
- {
- FloorItem *const item = actorSpriteManager->findItem(floorItemId);
- if (item)
- {
- if (!item->getShowMsg())
- return;
- item->setShowMsg(false);
- }
- }
- const char* msg;
- switch (fail)
- {
- case PICKUP_BAD_ITEM:
- // TRANSLATORS: pickup error message
- msg = N_("Tried to pick up nonexistent item.");
- break;
- case PICKUP_TOO_HEAVY:
- // TRANSLATORS: pickup error message
- msg = N_("Item is too heavy.");
- break;
- case PICKUP_TOO_FAR:
- // TRANSLATORS: pickup error message
- msg = N_("Item is too far away.");
- break;
- case PICKUP_INV_FULL:
- // TRANSLATORS: pickup error message
- msg = N_("Inventory is full.");
- break;
- case PICKUP_STACK_FULL:
- // TRANSLATORS: pickup error message
- msg = N_("Stack is too big.");
- break;
- case PICKUP_DROP_STEAL:
- // TRANSLATORS: pickup error message
- msg = N_("Item belongs to someone else.");
- break;
- default:
- // TRANSLATORS: pickup error message
- msg = N_("Unknown problem picking up item.");
- break;
- }
- if (localChatTab && config.getBoolValue("showpickupchat"))
- localChatTab->chatLog(gettext(msg), BY_SERVER);
-
- if (mMap && config.getBoolValue("showpickupparticle"))
- {
- // Show pickup notification
- addMessageToQueue(gettext(msg), UserPalette::PICKUP_INFO);
- }
- }
- else
- {
- std::string str;
- if (serverVersion > 0)
- str = itemInfo.getName(color);
- else
- str = itemInfo.getName();
-
- if (config.getBoolValue("showpickupchat") && localChatTab)
- {
- // TRANSLATORS: %d is number,
- // [@@%d|%s@@] - here player can see link to item
- localChatTab->chatLog(strprintf(ngettext("You picked up %d "
- "[@@%d|%s@@].", "You picked up %d [@@%d|%s@@].", amount),
- amount, itemInfo.getId(), str.c_str()), BY_SERVER);
- }
-
- if (mMap && config.getBoolValue("showpickupparticle"))
- {
- // Show pickup notification
- if (amount > 1)
- {
- addMessageToQueue(strprintf("%d x %s", amount,
- str.c_str()), UserPalette::PICKUP_INFO);
- }
- else
- {
- addMessageToQueue(str, UserPalette::PICKUP_INFO);
- }
- }
- }
-}
-
-int LocalPlayer::getAttackRange() const
-{
- if (mAttackRange > -1)
- {
- return mAttackRange;
- }
- else
- {
- const Item *const weapon = PlayerInfo::getEquipment(EQUIP_FIGHT1_SLOT);
- if (weapon)
- {
- const ItemInfo &info = weapon->getInfo();
- return info.getAttackRange();
- }
- return 48; // unarmed range
- }
-}
-
-bool LocalPlayer::withinAttackRange(const Being *const target,
- const bool fixDistance,
- const int addRange) const
-{
- if (!target)
- return false;
-
- int range = getAttackRange() + addRange;
- int dx;
- int dy;
-
- if (fixDistance && range == 1)
- range = 2;
-
-#ifdef MANASERV_SUPPORT
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- const Vector &targetPos = target->getPosition();
- const Vector &pos = getPosition();
- dx = static_cast<int>(abs(static_cast<int>(targetPos.x - pos.x)));
- dy = static_cast<int>(abs(static_cast<int>(targetPos.y - pos.y)));
- }
- else
-#endif
- {
- dx = static_cast<int>(abs(target->getTileX() - mX));
- dy = static_cast<int>(abs(target->getTileY() - mY));
- }
- return !(dx > range || dy > range);
-}
-
-void LocalPlayer::setGotoTarget(Being *const target)
-{
- if (!target)
- return;
-
- mPickUpTarget = nullptr;
-#ifdef MANASERV_SUPPORT
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- mTarget = target;
- mGoingToTarget = true;
- const Vector &targetPos = target->getPosition();
- setDestination(static_cast<int>(targetPos.x),
- static_cast<int>(targetPos.y));
- }
- else
-#endif
- {
- setTarget(target);
- mGoingToTarget = true;
- setDestination(target->getTileX(), target->getTileY());
- }
-}
-
-void LocalPlayer::handleStatusEffect(StatusEffect *const effect,
- const int effectId)
-{
- Being::handleStatusEffect(effect, effectId);
-
- if (effect)
- {
- effect->deliverMessage();
- effect->playSFX();
-
- AnimatedSprite *const sprite = effect->getIcon();
-
- if (!sprite)
- {
- // delete sprite, if necessary
- for (unsigned int i = 0; i < mStatusEffectIcons.size(); )
- {
- if (mStatusEffectIcons[i] == effectId)
- {
- mStatusEffectIcons.erase(mStatusEffectIcons.begin() + i);
- if (miniStatusWindow)
- miniStatusWindow->eraseIcon(i);
- }
- else
- {
- i++;
- }
- }
- }
- else
- {
- // replace sprite or append
- bool found = false;
- const unsigned int sz = mStatusEffectIcons.size();
- for (unsigned int i = 0; i < sz; i++)
- {
- if (mStatusEffectIcons[i] == effectId)
- {
- if (miniStatusWindow)
- miniStatusWindow->setIcon(i, sprite);
- found = true;
- break;
- }
- }
-
- if (!found)
- { // add new
- const int offset = static_cast<int>(mStatusEffectIcons.size());
- if (miniStatusWindow)
- miniStatusWindow->setIcon(offset, sprite);
- mStatusEffectIcons.push_back(effectId);
- }
- }
- }
-}
-
-void LocalPlayer::addMessageToQueue(const std::string &message,
- const int color)
-{
- if (mMessages.size() < 20)
- mMessages.push_back(MessagePair(message, color));
-}
-
-void LocalPlayer::optionChanged(const std::string &value)
-{
- if (value == "showownname")
- setShowName(config.getBoolValue("showownname"));
- else if (value == "targetDeadPlayers")
- mTargetDeadPlayers = config.getBoolValue("targetDeadPlayers");
- else if (value == "enableBuggyServers")
- mIsServerBuggy = serverConfig.getBoolValue("enableBuggyServers");
- else if (value == "syncPlayerMove")
- mSyncPlayerMove = config.getBoolValue("syncPlayerMove");
- else if (value == "drawPath")
- mDrawPath = config.getBoolValue("drawPath");
- else if (value == "serverAttack")
- mServerAttack = config.getBoolValue("serverAttack");
- else if (value == "attackMoving")
- mAttackMoving = config.getBoolValue("attackMoving");
- else if (value == "attackNext")
- mAttackNext = config.getBoolValue("attackNext");
- else if (value == "showJobExp")
- mShowJobExp = config.getBoolValue("showJobExp");
- else if (value == "enableAdvert")
- mEnableAdvert = config.getBoolValue("enableAdvert");
- else if (value == "tradebot")
- mTradebot = config.getBoolValue("tradebot");
- else if (value == "targetOnlyReachable")
- mTargetOnlyReachable = config.getBoolValue("targetOnlyReachable");
-}
-
-void LocalPlayer::processEvent(Channels channel,
- const DepricatedEvent &event)
-{
- if (channel == CHANNEL_ATTRIBUTES)
- {
- if (event.getName() == EVENT_UPDATEATTRIBUTE)
- {
- switch (event.getInt("id"))
- {
- case PlayerInfo::EXP:
- {
- if (event.getInt("oldValue") > event.getInt("newValue"))
- break;
-
- const int change = event.getInt("newValue")
- - event.getInt("oldValue");
-
- if (change != 0)
- {
- // TRANSLATORS: get xp message
- addMessageToQueue(strprintf("%d %s", change, _("xp")));
- }
- break;
- }
- case PlayerInfo::LEVEL:
- mLevel = event.getInt("newValue");
- break;
- default:
- break;
- };
- }
- else if (event.getName() == EVENT_UPDATESTAT)
- {
- if (!mShowJobExp)
- return;
-
- const int id = event.getInt("id");
- if (id == Net::getPlayerHandler()->getJobLocation())
- {
- const std::pair<int, int> exp
- = PlayerInfo::getStatExperience(id);
- if (event.getInt("oldValue1") > exp.first
- || !event.getInt("oldValue2"))
- {
- return;
- }
-
- const int change = exp.first - event.getInt("oldValue1");
- if (change != 0 && mMessages.size() < 20)
- {
- if (!mMessages.empty())
- {
- MessagePair pair = mMessages.back();
- // TRANSLATORS: this is normal experience
- if (pair.first.find(strprintf(" %s",
- _("xp"))) == pair.first.size()
- - strlen(_("xp")) - 1)
- {
- mMessages.pop_back();
- // TRANSLATORS: this is job experience
- pair.first.append(strprintf(", %d %s",
- change, _("job")));
- mMessages.push_back(pair);
- }
- else
- {
- // TRANSLATORS: this is job experience
- addMessageToQueue(strprintf("%d %s",
- change, _("job")));
- }
- }
- else
- {
- // TRANSLATORS: this is job experience
- addMessageToQueue(strprintf(
- "%d %s", change, _("job")));
- }
- }
- }
- }
- }
-}
-
-void LocalPlayer::moveTo(const int x, const int y)
-{
- setDestination(x, y);
-}
-
-void LocalPlayer::move(const int dX, const int dY)
-{
- mPickUpTarget = nullptr;
- moveTo(mX + dX, mY + dY);
-}
-
-void LocalPlayer::moveToTarget(int dist)
-{
- bool gotPos(false);
- Path debugPath;
-
- const Vector &playerPos = getPosition();
- unsigned int limit(0);
-
- if (dist == -1)
- {
- dist = mMoveToTargetType;
- if (mMoveToTargetType == 0)
- {
- dist = 0;
- }
- else
- {
- switch (mMoveToTargetType)
- {
- case 1:
- dist = 1;
- break;
- case 2:
- dist = 2;
- break;
- case 3:
- dist = 3;
- break;
- case 4:
- dist = 5;
- break;
- case 5:
- dist = 7;
- break;
- case 6:
- case 7:
- dist = mAttackRange;
- if (dist == 1 && serverVersion < 1)
- dist = 2;
- break;
- case 8:
- dist = mAttackRange - 1;
- if (dist < 1)
- dist = 1;
- if (dist == 1 && serverVersion < 1)
- dist = 2;
- break;
- default:
- break;
- }
- }
- }
-
- if (mTarget)
- {
- if (mMap)
- {
- debugPath = mMap->findPath(static_cast<int>(playerPos.x - 16) / 32,
- static_cast<int>(playerPos.y - 32) / 32,
- mTarget->getTileX(), mTarget->getTileY(), getWalkMask(), 0);
- }
-
- const unsigned int sz = debugPath.size();
- if (sz < static_cast<unsigned int>(dist))
- return;
- limit = static_cast<int>(sz) - dist;
- gotPos = true;
- }
- else if (mNavigateX || mNavigateY)
- {
- debugPath = mNavigatePath;
- limit = dist;
- gotPos = true;
- }
-
- if (gotPos)
- {
- if (dist == 0)
- {
- if (mTarget)
- navigateTo(mTarget);
- }
- else
- {
- Position pos(0, 0);
- unsigned int f = 0;
-
- for (Path::const_iterator i = debugPath.begin(),
- i_end = debugPath.end();
- i != i_end && f < limit; ++i, f++)
- {
- pos = (*i);
- }
- navigateTo(pos.x, pos.y);
- }
- }
- else if (mLastTargetX || mLastTargetY)
- {
- navigateTo(mLastTargetX, mLastTargetY);
- }
-}
-
-void LocalPlayer::moveToHome()
-{
- mPickUpTarget = nullptr;
- if ((mX != mCrossX || mY != mCrossY) && mCrossX && mCrossY)
- {
- moveTo(mCrossX, mCrossY);
- }
- else if (mMap)
- {
- const std::map<std::string, Vector>::const_iterator iter =
- mHomes.find(mMap->getProperty("_realfilename"));
-
- if (iter != mHomes.end())
- {
- const Vector pos = mHomes[(*iter).first];
- if (mX == pos.x && mY == pos.y)
- {
- Net::getPlayerHandler()->setDestination(
- static_cast<int>(pos.x),
- static_cast<int>(pos.y),
- static_cast<int>(mDirection));
- }
- else
- {
- navigateTo(static_cast<int>(pos.x), static_cast<int>(pos.y));
- }
- }
- }
-}
-
-static const unsigned invertDirectionSize = 5;
-
-void LocalPlayer::changeMode(unsigned *const var, const unsigned limit,
- const char *const conf,
- std::string (LocalPlayer::*const func)(),
- const unsigned def,
- const bool save)
-{
- if (!var)
- return;
-
- (*var) ++;
- if (*var >= limit)
- *var = def;
- if (save)
- config.setValue(conf, *var);
- if (miniStatusWindow)
- miniStatusWindow->updateStatus();
- const std::string str = (this->*func)();
- if (str.size() > 4)
- debugMsg(str.substr(4));
-}
-
-void LocalPlayer::invertDirection()
-{
- mMoveState = 0;
- changeMode(&mInvertDirection, invertDirectionSize, "invertMoveDirection",
- &LocalPlayer::getInvertDirectionString, 0, false);
-}
-
-static const char *const invertDirectionStrings[] =
-{
- // TRANSLATORS: move type in status bar
- N_("(D) default moves"),
- // TRANSLATORS: move type in status bar
- N_("(I) invert moves"),
- // TRANSLATORS: move type in status bar
- N_("(c) moves with some crazy moves"),
- // TRANSLATORS: move type in status bar
- N_("(C) moves with crazy moves"),
- // TRANSLATORS: move type in status bar
- N_("(d) double normal + crazy"),
- // TRANSLATORS: move type in status bar
- N_("(?) unknown move")
-};
-
-std::string LocalPlayer::getInvertDirectionString()
-{
- return gettext(getVarItem(&invertDirectionStrings[0],
- mInvertDirection, invertDirectionSize));
-}
-
-static const unsigned crazyMoveTypeSize = 11;
-
-void LocalPlayer::changeCrazyMoveType()
-{
- mCrazyMoveState = 0;
- changeMode(&mCrazyMoveType, crazyMoveTypeSize, "crazyMoveType",
- &LocalPlayer::getCrazyMoveTypeString, 1);
-}
-
-std::string LocalPlayer::getCrazyMoveTypeString()
-{
- if (mCrazyMoveType < crazyMoveTypeSize - 1)
- {
- // TRANSLATORS: crazy move type in status bar
- return strprintf(_("(%u) crazy move number %u"),
- mCrazyMoveType, mCrazyMoveType);
- }
- else if (mCrazyMoveType == crazyMoveTypeSize - 1)
- {
- // TRANSLATORS: crazy move type in status bar
- return _("(a) custom crazy move");
- }
- else
- {
- // TRANSLATORS: crazy move type in status bar
- return _("(?) crazy move");
- }
-}
-
-static const unsigned moveToTargetTypeSize = 9;
-
-void LocalPlayer::changeMoveToTargetType()
-{
- changeMode(&mMoveToTargetType, moveToTargetTypeSize, "moveToTargetType",
- &LocalPlayer::getMoveToTargetTypeString);
-}
-
-static const char *const moveToTargetTypeStrings[] =
-{
- // TRANSLATORS: move to target type in status bar
- N_("(0) default moves to target"),
- // TRANSLATORS: move to target type in status bar
- N_("(1) moves to target in distance 1"),
- // TRANSLATORS: move to target type in status bar
- N_("(2) moves to target in distance 2"),
- // TRANSLATORS: move to target type in status bar
- N_("(3) moves to target in distance 3"),
- // TRANSLATORS: move to target type in status bar
- N_("(5) moves to target in distance 5"),
- // TRANSLATORS: move to target type in status bar
- N_("(7) moves to target in distance 7"),
- // TRANSLATORS: move to target type in status bar
- N_("(A) moves to target in attack range"),
- // TRANSLATORS: move to target type in status bar
- N_("(a) archer attack range"),
- // TRANSLATORS: move to target type in status bar
- N_("(B) moves to target in attack range - 1"),
- // TRANSLATORS: move to target type in status bar
- N_("(?) move to target")
-};
-
-std::string LocalPlayer::getMoveToTargetTypeString()
-{
- return gettext(getVarItem(&moveToTargetTypeStrings[0],
- mMoveToTargetType, moveToTargetTypeSize));
-}
-
-static const unsigned followModeSize = 4;
-
-void LocalPlayer::changeFollowMode()
-{
- changeMode(&mFollowMode, followModeSize, "followMode",
- &LocalPlayer::getFollowModeString);
-}
-
-static const char *const followModeStrings[] =
-{
- // TRANSLATORS: folow mode in status bar
- N_("(D) default follow"),
- // TRANSLATORS: folow mode in status bar
- N_("(R) relative follow"),
- // TRANSLATORS: folow mode in status bar
- N_("(M) mirror follow"),
- // TRANSLATORS: folow mode in status bar
- N_("(P) pet follow"),
- // TRANSLATORS: folow mode in status bar
- N_("(?) unknown follow")
-};
-
-std::string LocalPlayer::getFollowModeString()
-{
- return gettext(getVarItem(&followModeStrings[0],
- mFollowMode, followModeSize));
-}
-
-const unsigned attackWeaponTypeSize = 4;
-
-void LocalPlayer::changeAttackWeaponType()
-{
- changeMode(&mAttackWeaponType, attackWeaponTypeSize, "attackWeaponType",
- &LocalPlayer::getAttackWeaponTypeString, 1);
-}
-
-static const char *attackWeaponTypeStrings[] =
-{
- // TRANSLATORS: switch attack type in status bar
- N_("(?) attack"),
- // TRANSLATORS: switch attack type in status bar
- N_("(D) default attack"),
- // TRANSLATORS: switch attack type in status bar
- N_("(s) switch attack without shield"),
- // TRANSLATORS: switch attack type in status bar
- N_("(S) switch attack with shield"),
- // TRANSLATORS: switch attack type in status bar
- N_("(?) attack")
-};
-
-std::string LocalPlayer::getAttackWeaponTypeString()
-{
- return gettext(getVarItem(&attackWeaponTypeStrings[0],
- mAttackWeaponType, attackWeaponTypeSize));
-}
-
-const unsigned attackTypeSize = 4;
-
-void LocalPlayer::changeAttackType()
-{
- changeMode(&mAttackType, attackTypeSize, "attackType",
- &LocalPlayer::getAttackTypeString);
-}
-
-static const char *const attackTypeStrings[] =
-{
- // TRANSLATORS: attack type in status bar
- N_("(D) default attack"),
- // TRANSLATORS: attack type in status bar
- N_("(G) go and attack"),
- // TRANSLATORS: attack type in status bar
- N_("(A) go, attack, pickup"),
- // TRANSLATORS: attack type in status bar
- N_("(d) without auto attack"),
- // TRANSLATORS: attack type in status bar
- N_("(?) attack")
-};
-
-std::string LocalPlayer::getAttackTypeString()
-{
- return gettext(getVarItem(&attackTypeStrings[0],
- mAttackType, attackTypeSize));
-}
-
-const unsigned quickDropCounterSize = 31;
-
-void LocalPlayer::changeQuickDropCounter()
-{
- changeMode(&mQuickDropCounter, quickDropCounterSize, "quickDropCounter",
- &LocalPlayer::getQuickDropCounterString, 1);
-}
-
-std::string LocalPlayer::getQuickDropCounterString()
-{
- if (mQuickDropCounter > 9)
- {
- return strprintf("(%c) drop counter %u", static_cast<signed char>(
- 'a' + mQuickDropCounter - 10), mQuickDropCounter);
- }
- else
- {
- return strprintf("(%u) drop counter %u",
- mQuickDropCounter, mQuickDropCounter);
- }
-}
-
-void LocalPlayer::setQuickDropCounter(const int n)
-{
- if (n < 1 || n >= static_cast<signed>(quickDropCounterSize))
- return;
- mQuickDropCounter = n;
- config.setValue("quickDropCounter", mQuickDropCounter);
- if (miniStatusWindow)
- miniStatusWindow->updateStatus();
-}
-
-const unsigned pickUpTypeSize = 7;
-
-void LocalPlayer::changePickUpType()
-{
- changeMode(&mPickUpType, pickUpTypeSize, "pickUpType",
- &LocalPlayer::getPickUpTypeString);
-}
-
-static const char *const pickUpTypeStrings[] =
-{
- // TRANSLATORS: pickup size in status bar
- N_("(S) small pick up 1x1 cells"),
- // TRANSLATORS: pickup size in status bar
- N_("(D) default pick up 2x1 cells"),
- // TRANSLATORS: pickup size in status bar
- N_("(F) forward pick up 2x3 cells"),
- // TRANSLATORS: pickup size in status bar
- N_("(3) pick up 3x3 cells"),
- // TRANSLATORS: pickup size in status bar
- N_("(g) go and pick up in distance 4"),
- // TRANSLATORS: pickup size in status bar
- N_("(G) go and pick up in distance 8"),
- // TRANSLATORS: pickup size in status bar
- N_("(A) go and pick up in max distance"),
- // TRANSLATORS: pickup size in status bar
- N_("(?) pick up")
-};
-
-std::string LocalPlayer::getPickUpTypeString()
-{
- return gettext(getVarItem(&pickUpTypeStrings[0],
- mPickUpType, pickUpTypeSize));
-}
-
-const unsigned debugPathSize = 5;
-
-static const char *const debugPathStrings[] =
-{
- // TRANSLATORS: map view type in status bar
- N_("(N) normal map view"),
- // TRANSLATORS: map view type in status bar
- N_("(D) debug map view"),
- // TRANSLATORS: map view type in status bar
- N_("(u) ultra map view"),
- // TRANSLATORS: map view type in status bar
- N_("(U) ultra map view 2"),
- // TRANSLATORS: map view type in status bar
- N_("(e) empty map view"),
- // TRANSLATORS: map view type in status bar
- N_("(b) black & white map view")
-};
-
-std::string LocalPlayer::getDebugPathString() const
-{
- return gettext(getVarItem(&debugPathStrings[0],
- viewport->getDebugPath(), debugPathSize));
-}
-
-const unsigned magicAttackSize = 5;
-
-void LocalPlayer::switchMagicAttack()
-{
- changeMode(&mMagicAttackType, magicAttackSize, "magicAttackType",
- &LocalPlayer::getMagicAttackString);
-}
-
-static const char *const magicAttackStrings[] =
-{
- // TRANSLATORS: magic attack in status bar
- N_("(f) use #flar for magic attack"),
- // TRANSLATORS: magic attack in status bar
- N_("(c) use #chiza for magic attack"),
- // TRANSLATORS: magic attack in status bar
- N_("(I) use #ingrav for magic attack"),
- // TRANSLATORS: magic attack in status bar
- N_("(F) use #frillyar for magic attack"),
- // TRANSLATORS: magic attack in status bar
- N_("(U) use #upmarmu for magic attack"),
- // TRANSLATORS: magic attack in status bar
- N_("(?) magic attack")
-};
-
-std::string LocalPlayer::getMagicAttackString()
-{
- return gettext(getVarItem(&magicAttackStrings[0],
- mMagicAttackType, magicAttackSize));
-}
-
-const unsigned pvpAttackSize = 4;
-
-void LocalPlayer::switchPvpAttack()
-{
- changeMode(&mPvpAttackType, pvpAttackSize, "pvpAttackType",
- &LocalPlayer::getPvpAttackString);
-}
-
-static const char *const pvpAttackStrings[] =
-{
- // TRANSLATORS: player attack type in status bar
- N_("(a) attack all players"),
- // TRANSLATORS: player attack type in status bar
- N_("(f) attack all except friends"),
- // TRANSLATORS: player attack type in status bar
- N_("(b) attack bad relations"),
- // TRANSLATORS: player attack type in status bar
- N_("(d) don't attack players"),
- // TRANSLATORS: player attack type in status bar
- N_("(?) pvp attack")
-};
-
-std::string LocalPlayer::getPvpAttackString()
-{
- return gettext(getVarItem(&pvpAttackStrings[0],
- mPvpAttackType, pvpAttackSize));
-}
-
-const unsigned imitationModeSize = 2;
-
-void LocalPlayer::changeImitationMode()
-{
- changeMode(&mImitationMode, imitationModeSize, "imitationMode",
- &LocalPlayer::getImitationModeString);
-}
-
-static const char *const imitationModeStrings[] =
-{
- // TRANSLATORS: imitation type in status bar
- N_("(D) default imitation"),
- // TRANSLATORS: imitation type in status bar
- N_("(O) outfits imitation"),
- // TRANSLATORS: imitation type in status bar
- N_("(?) imitation")
-};
-
-std::string LocalPlayer::getImitationModeString()
-{
- return gettext(getVarItem(&imitationModeStrings[0],
- mImitationMode, imitationModeSize));
-}
-
-const unsigned awayModeSize = 2;
-
-void LocalPlayer::changeAwayMode()
-{
- mAwayMode = !mAwayMode;
- mAfkTime = 0;
- mInactive = false;
- updateName();
- if (miniStatusWindow)
- miniStatusWindow->updateStatus();
- if (mAwayMode)
- {
- if (chatWindow)
- chatWindow->clearAwayLog();
-
- cancelFollow();
- navigateClean();
- if (outfitWindow)
- outfitWindow->wearAwayOutfit();
- // TRANSLATORS: away message box header
- mAwayDialog = new OkDialog(_("Away"),
- config.getStringValue("afkMessage"),
- DIALOG_SILENCE, true, false);
- mAwayDialog->addActionListener(mAwayListener);
- soundManager.volumeOff();
- addAfkEffect();
- }
- else
- {
- mAwayDialog = nullptr;
- soundManager.volumeRestore();
- if (chatWindow)
- {
- chatWindow->displayAwayLog();
- chatWindow->clearAwayLog();
- }
- removeAfkEffect();
- }
-}
-
-static const char *awayModeStrings[] =
-{
- // TRANSLATORS: away type in status bar
- N_("(O) on keyboard"),
- // TRANSLATORS: away type in status bar
- N_("(A) away"),
- // TRANSLATORS: away type in status bar
- N_("(?) away")
-};
-
-std::string LocalPlayer::getAwayModeString()
-{
- return gettext(getVarItem(&awayModeStrings[0],
- mAwayMode, awayModeSize));
-}
-
-const unsigned cameraModeSize = 2;
-
-static const char *cameraModeStrings[] =
-{
- // TRANSLATORS: camera mode in status bar
- N_("(G) game camera mode"),
- // TRANSLATORS: camera mode in status bar
- N_("(F) free camera mode"),
- // TRANSLATORS: camera mode in status bar
- N_("(?) away")
-};
-
-std::string LocalPlayer::getCameraModeString() const
-{
- return gettext(getVarItem(&cameraModeStrings[0],
- viewport->getCameraMode(), cameraModeSize));
-}
-
-const unsigned gameModifiersSize = 2;
-
-void LocalPlayer::switchGameModifiers()
-{
- mDisableGameModifiers = !mDisableGameModifiers;
- config.setValue("disableGameModifiers", mDisableGameModifiers);
- miniStatusWindow->updateStatus();
-
- const std::string str = getGameModifiersString();
- if (str.size() > 4)
- debugMsg(str.substr(4));
-}
-
-static const char *const gameModifiersStrings[] =
-{
- // TRANSLATORS: game modifiers state in status bar
- N_("Game modifiers are enabled"),
- // TRANSLATORS: game modifiers state in status bar
- N_("Game modifiers are disabled"),
- // TRANSLATORS: game modifiers state in status bar
- N_("Game modifiers are unknown")
-};
-
-std::string LocalPlayer::getGameModifiersString()
-{
- return gettext(getVarItem(&gameModifiersStrings[0],
- mDisableGameModifiers, gameModifiersSize));
-}
-
-
-void LocalPlayer::changeEquipmentBeforeAttack(const Being *const target) const
-{
- if (mAttackWeaponType == 1 || !target || !PlayerInfo::getInventory())
- return;
-
- bool allowSword = false;
- const int dx = target->getTileX() - mX;
- const int dy = target->getTileY() - mY;
- const Item *item = nullptr;
-
- if (dx * dx + dy * dy > 80)
- return;
-
- if (dx * dx + dy * dy < 8)
- allowSword = true;
-
- const Inventory *const inv = PlayerInfo::getInventory();
- if (!inv)
- return;
-
- // if attack distance for sword
- if (allowSword)
- {
- // finding sword
- item = inv->findItem(571, 0);
-
- if (!item)
- item = inv->findItem(570, 0);
-
- if (!item)
- item = inv->findItem(579, 0);
-
- if (!item)
- item = inv->findItem(867, 0);
-
- if (!item)
- item = inv->findItem(536, 0);
-
- if (!item)
- item = inv->findItem(758, 0);
-
- // no swords
- if (!item)
- return;
-
- // if sword not equiped
- if (!item->isEquipped())
- Net::getInventoryHandler()->equipItem(item);
-
- // if need equip shield too
- if (mAttackWeaponType == 3)
- {
- // finding shield
- item = inv->findItem(601, 0);
- if (!item)
- item = inv->findItem(602, 0);
- if (item && !item->isEquipped())
- Net::getInventoryHandler()->equipItem(item);
- }
- }
- // big distance. allowed only bow
- else
- {
- // finding bow
- item = inv->findItem(545, 0);
-
- if (!item)
- item = inv->findItem(530, 0);
-
- // no bow
- if (!item)
- return;
-
- if (!item->isEquipped())
- Net::getInventoryHandler()->equipItem(item);
- }
-}
-
-void LocalPlayer::crazyMove()
-{
- const bool oldDisableCrazyMove = mDisableCrazyMove;
- mDisableCrazyMove = true;
- switch (mCrazyMoveType)
- {
- case 1:
- crazyMove1();
- break;
- case 2:
- crazyMove2();
- break;
- case 3:
- crazyMove3();
- break;
- case 4:
- crazyMove4();
- break;
- case 5:
- crazyMove5();
- break;
- case 6:
- crazyMove6();
- break;
- case 7:
- crazyMove7();
- break;
- case 8:
- crazyMove8();
- break;
- case 9:
- crazyMove9();
- break;
- case 10:
- crazyMoveA();
- break;
- default:
- break;
- }
- mDisableCrazyMove = oldDisableCrazyMove;
-}
-
-void LocalPlayer::crazyMove1()
-{
- if (mAction == MOVE)
- return;
-
-// if (!client->limitPackets(PACKET_DIRECTION))
-// return;
-
- if (mDirection == Being::UP)
- {
- setWalkingDir(Being::UP);
- setDirection(Being::LEFT);
- Net::getPlayerHandler()->setDirection(Being::LEFT);
- }
- else if (mDirection == Being::LEFT)
- {
- setWalkingDir(Being::LEFT);
- setDirection(Being::DOWN);
- Net::getPlayerHandler()->setDirection(Being::DOWN);
- }
- else if (mDirection == Being::DOWN)
- {
- setWalkingDir(Being::DOWN);
- setDirection(Being::RIGHT);
- Net::getPlayerHandler()->setDirection(Being::RIGHT);
- }
- else if (mDirection == Being::RIGHT)
- {
- setWalkingDir(Being::RIGHT);
- setDirection(Being::UP);
- Net::getPlayerHandler()->setDirection(Being::UP);
- }
-}
-
-void LocalPlayer::crazyMove2()
-{
- if (mAction == MOVE)
- return;
-
-// if (!client->limitPackets(PACKET_DIRECTION))
-// return;
-
- if (mDirection == Being::UP)
- {
- setWalkingDir(Being::UP | Being::LEFT);
- setDirection(Being::RIGHT);
- Net::getPlayerHandler()->setDirection(Being::DOWN | Being::RIGHT);
- }
- else if (mDirection == Being::RIGHT)
- {
- setWalkingDir(Being::UP | Being::RIGHT);
- setDirection(Being::DOWN);
- Net::getPlayerHandler()->setDirection(Being::DOWN | Being::LEFT);
- }
- else if (mDirection == Being::DOWN)
- {
- setWalkingDir(Being::DOWN | Being::RIGHT);
- setDirection(Being::LEFT);
- Net::getPlayerHandler()->setDirection(Being::UP | Being::LEFT);
- }
- else if (mDirection == Being::LEFT)
- {
- setWalkingDir(Being::DOWN | Being::LEFT);
- setDirection(Being::UP);
- Net::getPlayerHandler()->setDirection(Being::UP | Being::RIGHT);
- }
-}
-
-void LocalPlayer::crazyMove3()
-{
- if (mAction == MOVE)
- return;
-
- switch (mCrazyMoveState)
- {
- case 0:
- move(1, 1);
- mCrazyMoveState = 1;
- break;
- case 1:
- move(1, -1);
- mCrazyMoveState = 2;
- break;
- case 2:
- move(-1, -1);
- mCrazyMoveState = 3;
- break;
- case 3:
- move(-1, 1);
- mCrazyMoveState = 0;
- break;
- default:
- break;
- }
-
-// if (!client->limitPackets(PACKET_DIRECTION))
-// return;
-
- setDirection(Being::DOWN);
- Net::getPlayerHandler()->setDirection(Being::DOWN);
-}
-
-void LocalPlayer::crazyMove4()
-{
- if (mAction == MOVE)
- return;
-
- switch (mCrazyMoveState)
- {
- case 0:
- move(7, 0);
- mCrazyMoveState = 1;
- break;
- case 1:
- move(-7, 0);
- mCrazyMoveState = 0;
- break;
- default:
- break;
- }
-}
-
-void LocalPlayer::crazyMove5()
-{
- if (mAction == MOVE)
- return;
-
- switch (mCrazyMoveState)
- {
- case 0:
- move(0, 7);
- mCrazyMoveState = 1;
- break;
- case 1:
- move(0, -7);
- mCrazyMoveState = 0;
- break;
- default:
- break;
- }
-}
-
-void LocalPlayer::crazyMove6()
-{
- if (mAction == MOVE)
- return;
-
- switch (mCrazyMoveState)
- {
- case 0:
- move(3, 0);
- mCrazyMoveState = 1;
- break;
- case 1:
- move(2, -2);
- mCrazyMoveState = 2;
- break;
- case 2:
- move(0, -3);
- mCrazyMoveState = 3;
- break;
- case 3:
- move(-2, -2);
- mCrazyMoveState = 4;
- break;
- case 4:
- move(-3, 0);
- mCrazyMoveState = 5;
- break;
- case 5:
- move(-2, 2);
- mCrazyMoveState = 6;
- break;
- case 6:
- move(0, 3);
- mCrazyMoveState = 7;
- break;
- case 7:
- move(2, 2);
- mCrazyMoveState = 0;
- break;
- default:
- break;
- }
-}
-
-void LocalPlayer::crazyMove7()
-{
- if (mAction == MOVE)
- return;
-
- switch (mCrazyMoveState)
- {
- case 0:
- move(1, 1);
- mCrazyMoveState = 1;
- break;
- case 1:
- move(-1, 1);
- mCrazyMoveState = 2;
- break;
- case 2:
- move(-1, -1);
- mCrazyMoveState = 3;
- break;
- case 3:
- move(1, -1);
- mCrazyMoveState = 0;
- break;
- default:
- break;
- }
-}
-
-void LocalPlayer::crazyMove8()
-{
- if (mAction == MOVE || !mMap)
- return;
- int idx = 0;
- const int dist = 1;
-
-// look
-// up, ri,do,le
- static const int movesX[][4] =
- {
- {-1, 0, 1, 0}, // move left
- { 0, 1, 0, -1}, // move up
- { 1, 0, -1, 0}, // move right
- { 0, -1, 0, 1} // move down
- };
-
-// look
-// up, ri,do,le
- static const int movesY[][4] =
- {
- { 0, -1, 0, 1}, // move left
- {-1, 0, 1, 0}, // move up
- { 0, 1, 0, -1}, // move right
- { 1, 0, -1, 0} // move down
- };
-
- if (mDirection == Being::UP)
- idx = 0;
- else if (mDirection == Being::RIGHT)
- idx = 1;
- else if (mDirection == Being::DOWN)
- idx = 2;
- else if (mDirection == Being::LEFT)
- idx = 3;
-
-
- int mult = 1;
- const unsigned char walkMask = getWalkMask();
- if (mMap->getWalk(mX + movesX[idx][0],
- mY + movesY[idx][0], walkMask))
- {
- while (mMap->getWalk(mX + movesX[idx][0] * mult,
- mY + movesY[idx][0] * mult,
- getWalkMask()) && mult <= dist)
- {
- mult ++;
- }
- move(movesX[idx][0] * (mult - 1), movesY[idx][0] * (mult - 1));
- }
- else if (mMap->getWalk(mX + movesX[idx][1],
- mY + movesY[idx][1], walkMask))
- {
- while (mMap->getWalk(mX + movesX[idx][1] * mult,
- mY + movesY[idx][1] * mult,
- getWalkMask()) && mult <= dist)
- {
- mult ++;
- }
- move(movesX[idx][1] * (mult - 1), movesY[idx][1] * (mult - 1));
- }
- else if (mMap->getWalk(mX + movesX[idx][2],
- mY + movesY[idx][2], walkMask))
- {
- while (mMap->getWalk(mX + movesX[idx][2] * mult,
- mY + movesY[idx][2] * mult,
- getWalkMask()) && mult <= dist)
- {
- mult ++;
- }
- move(movesX[idx][2] * (mult - 1), movesY[idx][2] * (mult - 1));
- }
- else if (mMap->getWalk(mX + movesX[idx][3],
- mY + movesY[idx][3], walkMask))
- {
- while (mMap->getWalk(mX + movesX[idx][3] * mult,
- mY + movesY[idx][3] * mult,
- getWalkMask()) && mult <= dist)
- {
- mult ++;
- }
- move(movesX[idx][3] * (mult - 1), movesY[idx][3] * (mult - 1));
- }
-}
-
-void LocalPlayer::crazyMove9()
-{
- int dx = 0;
- int dy = 0;
-
- if (mAction == MOVE)
- return;
-
- switch (mCrazyMoveState)
- {
- case 0:
- switch (mDirection)
- {
- case UP : dy = -1; break;
- case DOWN : dy = 1; break;
- case LEFT : dx = -1; break;
- case RIGHT: dx = 1; break;
- default: break;
- }
- move(dx, dy);
- mCrazyMoveState = 1;
- break;
- case 1:
- mCrazyMoveState = 2;
- if (!allowAction())
- return;
- Net::getPlayerHandler()->changeAction(SIT);
- break;
- case 2:
- mCrazyMoveState = 3;
- break;
- case 3:
- mCrazyMoveState = 0;
- break;
- default:
- break;
- }
-}
-
-void LocalPlayer::crazyMoveA()
-{
- const std::string mMoveProgram(config.getStringValue("crazyMoveProgram"));
-
- if (mAction == MOVE)
- return;
-
- if (mMoveProgram.empty())
- return;
-
- if (mCrazyMoveState >= mMoveProgram.length())
- mCrazyMoveState = 0;
-
- // move command
- if (mMoveProgram[mCrazyMoveState] == 'm')
- {
- mCrazyMoveState ++;
- if (mCrazyMoveState < mMoveProgram.length())
- {
- int dx = 0;
- int dy = 0;
-
- signed char param = mMoveProgram[mCrazyMoveState++];
- if (param == '?')
- {
- const char cmd[] = {'l', 'r', 'u', 'd'};
- srand(tick_time);
- param = cmd[rand() % 4];
- }
- switch (param)
- {
- case 'd':
- move(0, 1);
- break;
- case 'u':
- move(0, -1);
- break;
- case 'l':
- move(-1, 0);
- break;
- case 'r':
- move(1, 0);
- break;
- case 'f':
- switch (mDirection)
- {
- case UP : dy = -1; break;
- case DOWN : dy = 1; break;
- case LEFT : dx = -1; break;
- case RIGHT: dx = 1; break;
- default: break;
- }
- move(dx, dy);
- break;
- case 'b':
- switch (mDirection)
- {
- case UP : dy = 1; break;
- case DOWN : dy = -1; break;
- case LEFT : dx = 1; break;
- case RIGHT: dx = -1; break;
- default: break;
- }
- move(dx, dy);
- break;
- default:
- break;
- }
- }
- }
- // direction command
- else if (mMoveProgram[mCrazyMoveState] == 'd')
- {
- mCrazyMoveState ++;
-
- if (mCrazyMoveState < mMoveProgram.length())
- {
- signed char param = mMoveProgram[mCrazyMoveState++];
- if (param == '?')
- {
- const char cmd[] = {'l', 'r', 'u', 'd'};
- srand(tick_time);
- param = cmd[rand() % 4];
- }
- switch (param)
- {
- case 'd':
-
-// if (client->limitPackets(PACKET_DIRECTION))
- {
- setDirection(Being::DOWN);
- Net::getPlayerHandler()->setDirection(Being::DOWN);
- }
- break;
- case 'u':
-// if (client->limitPackets(PACKET_DIRECTION))
- {
- setDirection(Being::UP);
- Net::getPlayerHandler()->setDirection(Being::UP);
- }
- break;
- case 'l':
-// if (client->limitPackets(PACKET_DIRECTION))
- {
- setDirection(Being::LEFT);
- Net::getPlayerHandler()->setDirection(Being::LEFT);
- }
- break;
- case 'r':
-// if (client->limitPackets(PACKET_DIRECTION))
- {
- setDirection(Being::RIGHT);
- Net::getPlayerHandler()->setDirection(Being::RIGHT);
- }
- break;
- case 'L':
-// if (client->limitPackets(PACKET_DIRECTION))
- {
- uint8_t dir = 0;
- switch (mDirection)
- {
- case UP : dir = Being::LEFT; break;
- case DOWN : dir = Being::RIGHT; break;
- case LEFT : dir = Being::DOWN; break;
- case RIGHT : dir = Being::UP; break;
- default: break;
- }
- setDirection(dir);
- Net::getPlayerHandler()->setDirection(dir);
- }
- break;
- case 'R':
-// if (client->limitPackets(PACKET_DIRECTION))
- {
- uint8_t dir = 0;
- switch (mDirection)
- {
- case UP : dir = Being::RIGHT; break;
- case DOWN : dir = Being::LEFT; break;
- case LEFT : dir = Being::UP; break;
- case RIGHT : dir = Being::DOWN; break;
- default: break;
- }
- setDirection(dir);
- Net::getPlayerHandler()->setDirection(dir);
- }
- break;
- case 'b':
-// if (client->limitPackets(PACKET_DIRECTION))
- {
- uint8_t dir = 0;
- switch (mDirection)
- {
- case UP : dir = Being::DOWN; break;
- case DOWN : dir = Being::UP; break;
- case LEFT : dir = Being::RIGHT; break;
- case RIGHT : dir = Being::LEFT; break;
- default: break;
- }
- setDirection(dir);
- Net::getPlayerHandler()->setDirection(dir);
- }
- break;
- case '0':
- dropShortcut->dropFirst();
- break;
- case 'a':
- dropShortcut->dropItems();
- break;
- default:
- break;
- }
- }
- }
- // sit command
- else if (mMoveProgram[mCrazyMoveState] == 's')
- {
- mCrazyMoveState ++;
- if (toggleSit())
- mCrazyMoveState ++;
- }
- // wear outfits
- else if (mMoveProgram[mCrazyMoveState] == 'o')
- {
- mCrazyMoveState ++;
- if (mCrazyMoveState < mMoveProgram.length())
- {
- // wear next outfit
- if (mMoveProgram[mCrazyMoveState] == 'n')
- {
- mCrazyMoveState ++;
- outfitWindow->wearNextOutfit();
- }
- // wear previous outfit
- else if (mMoveProgram[mCrazyMoveState] == 'p')
- {
- mCrazyMoveState ++;
- outfitWindow->wearPreviousOutfit();
- }
- }
- }
- // pause
- else if (mMoveProgram[mCrazyMoveState] == 'w')
- {
- mCrazyMoveState ++;
- }
- // pick up
- else if (mMoveProgram[mCrazyMoveState] == 'p')
- {
- mCrazyMoveState ++;
- pickUpItems();
- }
- // emote
- else if (mMoveProgram[mCrazyMoveState] == 'e')
- {
- mCrazyMoveState ++;
- const signed char emo = mMoveProgram[mCrazyMoveState];
- if (emo == '?')
- {
- srand(tick_time);
- emote(static_cast<unsigned char>(1 + (rand() % 13)));
- }
- else
- {
- if (emo >= '0' && emo <= '9')
- emote(static_cast<unsigned char>(emo - '0' + 1));
- else if (emo >= 'a' && emo <= 'd')
- emote(static_cast<unsigned char>(emo - 'a' + 11));
- }
-
- mCrazyMoveState ++;
- }
- else
- {
- mCrazyMoveState ++;
- }
-
- if (mCrazyMoveState >= mMoveProgram.length())
- mCrazyMoveState = 0;
-}
-
-bool LocalPlayer::isReachable(Being *const being,
- const int maxCost)
-{
- if (!being || !mMap)
- return false;
-
- if (being->isReachable() == Being::REACH_NO)
- return false;
-
- if (being->getTileX() == mX
- && being->getTileY() == mY)
- {
- being->setDistance(0);
- being->setIsReachable(Being::REACH_YES);
- return true;
- }
- else if (being->getTileX() - 1 <= mX
- && being->getTileX() + 1 >= mX
- && being->getTileY() - 1 <= mY
- && being->getTileY() + 1 >= mY)
- {
- being->setDistance(1);
- being->setIsReachable(Being::REACH_YES);
- return true;
- }
-
- const Vector &playerPos = getPosition();
-
- const Path debugPath = mMap->findPath(
- static_cast<int>(playerPos.x - 16) / 32,
- static_cast<int>(playerPos.y - 32) / 32,
- being->getTileX(), being->getTileY(), getWalkMask(), maxCost);
-
- being->setDistance(static_cast<int>(debugPath.size()));
- if (!debugPath.empty())
- {
- being->setIsReachable(Being::REACH_YES);
- return true;
- }
- else
- {
- being->setIsReachable(Being::REACH_NO);
- return false;
- }
-}
-
-bool LocalPlayer::isReachable(const int x, const int y,
- const bool allowCollision) const
-{
- const WalkLayer *const walk = mMap->getWalkLayer();
- if (!walk)
- return false;
- int num = walk->getDataAt(x, y);
- if (allowCollision && num < 0)
- num = -num;
-
- return walk->getDataAt(mX, mY) == num;
-}
-
-bool LocalPlayer::pickUpItems(int pickUpType)
-{
- if (!actorSpriteManager)
- return false;
-
- bool status = false;
- int x = mX;
- int y = mY;
-
- // first pick up item on player position
- FloorItem *item =
- actorSpriteManager->findItem(x, y);
- if (item)
- status = pickUp(item);
-
- if (pickUpType == 0)
- pickUpType = mPickUpType;
-
- if (pickUpType == 0)
- return status;
-
- int x1, y1, x2, y2;
- switch (pickUpType)
- {
- case 1:
- switch (mDirection)
- {
- case UP : --y; break;
- case DOWN : ++y; break;
- case LEFT : --x; break;
- case RIGHT: ++x; break;
- default: break;
- }
- item = actorSpriteManager->findItem(x, y);
- if (item)
- status = pickUp(item);
- break;
- case 2:
- switch (mDirection)
- {
- case UP : x1 = x - 1; y1 = y - 1; x2 = x + 1; y2 = y; break;
- case DOWN : x1 = x - 1; y1 = y; x2 = x + 1; y2 = y + 1; break;
- case LEFT : x1 = x - 1; y1 = y - 1; x2 = x; y2 = y + 1; break;
- case RIGHT: x1 = x; y1 = y - 1; x2 = x + 1; y2 = y + 1; break;
- default: x1 = x; x2 = x; y1 = y; y2 = y; break;
- }
- if (actorSpriteManager->pickUpAll(x1, y1, x2, y2))
- status = true;
- break;
- case 3:
- if (actorSpriteManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
- status = true;
- break;
-
- case 4:
- if (!actorSpriteManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
- {
- if (actorSpriteManager->pickUpNearest(x, y, 4))
- status = true;
- }
- else
- {
- status = true;
- }
- break;
-
- case 5:
- if (!actorSpriteManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
- {
- if (actorSpriteManager->pickUpNearest(x, y, 8))
- status = true;
- }
- else
- {
- status = true;
- }
- break;
-
- case 6:
- if (!actorSpriteManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
- {
- if (actorSpriteManager->pickUpNearest(x, y, 90))
- status = true;
- }
- else
- {
- status = true;
- }
- break;
-
- default:
- break;
- }
- return status;
-}
-
-
-void LocalPlayer::moveByDirection(const unsigned char dir)
-{
- int dx = 0, dy = 0;
-#ifdef MANASERV_SUPPORT
- if (dir & UP)
- dy -= 32;
- if (dir & DOWN)
- dy += 32;
- if (dir & LEFT)
- dx -= 32;
- if (dir & RIGHT)
- dx += 32;
-#else
- if (dir & UP)
- dy--;
- if (dir & DOWN)
- dy++;
- if (dir & LEFT)
- dx--;
- if (dir & RIGHT)
- dx++;
-#endif
-
- move(dx, dy);
-}
-
-void LocalPlayer::specialMove(const unsigned char direction)
-{
- if (direction && (mNavigateX || mNavigateY))
- navigateClean();
-
- if (direction && (mInvertDirection >= 2
- && mInvertDirection <= 4)
- && !mIsServerBuggy)
- {
- if (mAction == MOVE)
- return;
-
- int max;
-
- if (mInvertDirection == 2)
- max = 5;
- else if (mInvertDirection == 4)
- max = 1;
- else
- max = 3;
-
- if (getMoveState() < max)
- {
- moveByDirection(direction);
- mMoveState ++;
- }
- else
- {
- mMoveState = 0;
- crazyMove();
- }
- }
- else
- {
- setWalkingDir(direction);
- }
-}
-
-void LocalPlayer::debugMsg(const std::string &str) const
-{
- if (debugChatTab)
- debugChatTab->chatLog(str);
-}
-
-void LocalPlayer::magicAttack() const
-{
- if (!chatWindow || !isAlive()
- || !Net::getPlayerHandler()->canUseMagic())
- {
- return;
- }
-
- switch (mMagicAttackType)
- {
- // flar W00
- case 0:
- tryMagic("#flar", 1, 0, 10);
- break;
- // chiza W01
- case 1:
- tryMagic("#chiza", 1, 0, 9);
- break;
- // ingrav W10
- case 2:
- tryMagic("#ingrav", 2, 2, 20);
- break;
- // frillyar W11
- case 3:
- tryMagic("#frillyar", 2, 2, 25);
- break;
- // upmarmu W12
- case 4:
- tryMagic("#upmarmu", 2, 2, 20);
- break;
- default:
- break;
- }
-}
-
-void LocalPlayer::tryMagic(const std::string &spell, const int baseMagic,
- const int schoolMagic, const int mana)
-{
- if (!chatWindow)
- return;
-
- if (PlayerInfo::getSkillLevel(340) >= baseMagic
- && PlayerInfo::getSkillLevel(342) >= schoolMagic)
- {
- if (PlayerInfo::getAttribute(PlayerInfo::MP) >= mana)
- {
- if (!client->limitPackets(PACKET_CHAT))
- return;
-
- chatWindow->localChatInput(spell);
- }
- }
-}
-
-void LocalPlayer::loadHomes()
-{
- if (serverVersion > 0)
- return;
- std::string buf;
- std::stringstream ss(serverConfig.getValue("playerHomes",
- "maps/018-1.tmx 71 76 maps/013-3.tmx 71 24"));
-
- while (ss >> buf)
- {
- Vector pos;
- ss >> pos.x;
- ss >> pos.y;
- mHomes[buf] = pos;
- }
-}
-
-void LocalPlayer::setMap(Map *const map)
-{
- if (map)
- {
- if (socialWindow)
- socialWindow->updateActiveList();
- }
- navigateClean();
- mCrossX = 0;
- mCrossY = 0;
-
- Being::setMap(map);
- updateNavigateList();
-}
-
-void LocalPlayer::setHome()
-{
- if (!mMap || !socialWindow)
- return;
-
- SpecialLayer *const specialLayer = mMap->getSpecialLayer();
-
- if (!specialLayer)
- return;
-
- const std::string key = mMap->getProperty("_realfilename");
- Vector pos = mHomes[key];
-
- if (mAction == SIT)
- {
- const std::map<std::string, Vector>::const_iterator
- iter = mHomes.find(key);
-
- if (iter != mHomes.end())
- {
- socialWindow->removePortal(static_cast<int>(pos.x),
- static_cast<int>(pos.y));
- }
-
- if (iter != mHomes.end() && mX == static_cast<int>(pos.x)
- && mY == static_cast<int>(pos.y))
- {
- mMap->updatePortalTile("", MapItem::EMPTY,
- static_cast<int>(pos.x), static_cast<int>(pos.y));
-
- mHomes.erase(key);
- socialWindow->removePortal(static_cast<int>(pos.x),
- static_cast<int>(pos.y));
- }
- else
- {
- if (specialLayer && iter != mHomes.end())
- {
- specialLayer->setTile(static_cast<int>(pos.x),
- static_cast<int>(pos.y), MapItem::EMPTY);
- }
-
- pos.x = static_cast<float>(mX);
- pos.y = static_cast<float>(mY);
- mHomes[key] = pos;
- mMap->updatePortalTile("home", MapItem::HOME,
- mX, mY);
- socialWindow->addPortal(mX, mY);
- }
- MapItem *const mapItem = specialLayer->getTile(mX, mY);
- if (mapItem)
- {
- const int idx = socialWindow->getPortalIndex(mX, mY);
- mapItem->setName(keyboard.getKeyShortString(
- outfitWindow->keyName(idx)));
- }
- saveHomes();
- }
- else
- {
- MapItem *mapItem = specialLayer->getTile(mX, mY);
- int type = 0;
-
- const std::map<std::string, Vector>::iterator iter = mHomes.find(key);
- if (iter != mHomes.end() && mX == pos.x && mY == pos.y)
- {
- mHomes.erase(key);
- saveHomes();
- }
-
- if (!mapItem || mapItem->getType() == MapItem::EMPTY)
- {
- if (mDirection & UP)
- type = MapItem::ARROW_UP;
- else if (mDirection & LEFT)
- type = MapItem::ARROW_LEFT;
- else if (mDirection & DOWN)
- type = MapItem::ARROW_DOWN;
- else if (mDirection & RIGHT)
- type = MapItem::ARROW_RIGHT;
- }
- else
- {
- type = MapItem::EMPTY;
- }
- mMap->updatePortalTile("", type, mX, mY);
-
- if (type != MapItem::EMPTY)
- {
- socialWindow->addPortal(mX, mY);
- mapItem = specialLayer->getTile(mX, mY);
- if (mapItem)
- {
- const int idx = socialWindow->getPortalIndex(mX, mY);
- mapItem->setName(keyboard.getKeyShortString(
- outfitWindow->keyName(idx)));
- }
- }
- else
- {
- specialLayer->setTile(mX, mY, MapItem::EMPTY);
- socialWindow->removePortal(mX, mY);
- }
- }
-}
-
-void LocalPlayer::saveHomes()
-{
- std::stringstream ss;
-
- for (std::map<std::string, Vector>::const_iterator iter = mHomes.begin(),
- iter_end = mHomes.end(); iter != iter_end; ++iter )
- {
- const Vector &pos = (*iter).second;
-
- if (iter != mHomes.begin())
- ss << " ";
- ss << (*iter).first << " " << pos.x << " " << pos.y;
- }
-
- serverConfig.setValue("playerHomes", ss.str());
-}
-
-void LocalPlayer::pingRequest()
-{
- const int time = tick_time;
- if (mWaitPing == true && mPingSendTick != 0)
- {
- if (time >= mPingSendTick && (time - mPingSendTick) > 1000)
- return;
- }
-
- mPingSendTick = time;
- mWaitPing = true;
- Net::getBeingHandler()->requestNameById(getId());
-}
-
-std::string LocalPlayer::getPingTime() const
-{
- std::string str;
- if (!mWaitPing)
- {
- if (!mPingTime)
- str = "?";
- else
- str = toString(mPingTime);
- }
- else
- {
- int time = tick_time;
- if (time > mPingSendTick)
- time -= mPingSendTick;
- else
- time += MAX_TICK_VALUE - mPingSendTick;
- if (time <= mPingTime)
- time = mPingTime;
- if (mPingTime != time)
- str = strprintf("%d (%d)", mPingTime, time);
- else
- str = toString(time);
- }
- return str;
-}
-
-void LocalPlayer::pingResponse()
-{
- if (mWaitPing == true && mPingSendTick > 0)
- {
- mWaitPing = false;
- const int time = tick_time;
- if (time < mPingSendTick)
- {
- mPingSendTick = 0;
- mPingTime = 0;
- }
- else
- {
- mPingTime = (time - mPingSendTick) * 10;
- }
- }
-}
-
-void LocalPlayer::tryPingRequest()
-{
- if (mPingSendTick == 0 || tick_time < mPingSendTick
- || (tick_time - mPingSendTick) > 200)
- {
- pingRequest();
- }
-}
-
-
-void LocalPlayer::setAway(const std::string &message)
-{
- if (!message.empty())
- config.setValue("afkMessage", message);
- changeAwayMode();
- updateStatus();
-}
-
-void LocalPlayer::setPseudoAway(const std::string &message)
-{
- if (!message.empty())
- config.setValue("afkMessage", message);
- mPseudoAwayMode = !mPseudoAwayMode;
-}
-
-void LocalPlayer::afkRespond(ChatTab *const tab, const std::string &nick)
-{
- if (mAwayMode)
- {
- const int time = cur_time;
- if (mAfkTime == 0 || time < mAfkTime
- || time - mAfkTime > awayLimitTimer)
- {
- const std::string msg = "*AFK*: "
- + config.getStringValue("afkMessage");
-
- if (!tab)
- {
- Net::getChatHandler()->privateMessage(nick, msg);
- if (localChatTab)
- {
- localChatTab->chatLog(std::string(getName()).append(
- " : ").append(msg), ACT_WHISPER, false);
- }
- }
- else
- {
- if (tab->getNoAway())
- return;
- Net::getChatHandler()->privateMessage(nick, msg);
- tab->chatLog(getName(), msg);
- }
- mAfkTime = time;
- }
- }
-}
-
-bool LocalPlayer::navigateTo(const int x, const int y)
-{
- if (!mMap)
- return false;
-
- SpecialLayer *const tmpLayer = mMap->getTempLayer();
- if (!tmpLayer)
- return false;
-
- const Vector &playerPos = getPosition();
- mShowNavigePath = true;
- mOldX = static_cast<int>(playerPos.x);
- mOldY = static_cast<int>(playerPos.y);
- mOldTileX = mX;
- mOldTileY = mY;
- mNavigateX = x;
- mNavigateY = y;
- mNavigateId = 0;
-
- mNavigatePath = mMap->findPath(
- static_cast<int>(playerPos.x - 16) / 32,
- static_cast<int>(playerPos.y - 32) / 32,
- x, y, getWalkMask(), 0);
-
- if (mDrawPath)
- tmpLayer->addRoad(mNavigatePath);
- return !mNavigatePath.empty();
-}
-
-void LocalPlayer::navigateTo(const Being *const being)
-{
- if (!mMap || !being)
- return;
-
- SpecialLayer *const tmpLayer = mMap->getTempLayer();
- if (!tmpLayer)
- return;
-
- const Vector &playerPos = getPosition();
- mShowNavigePath = true;
- mOldX = static_cast<int>(playerPos.x);
- mOldY = static_cast<int>(playerPos.y);
- mOldTileX = mX;
- mOldTileY = mY;
- mNavigateX = being->getTileX();
- mNavigateY = being->getTileY();
-
- mNavigatePath = mMap->findPath(
- static_cast<int>(playerPos.x - 16) / 32,
- static_cast<int>(playerPos.y - 32) / 32,
- being->getTileX(), being->getTileY(),
- getWalkMask(), 0);
-
- if (mDrawPath)
- tmpLayer->addRoad(mNavigatePath);
-}
-
-void LocalPlayer::navigateClean()
-{
- if (!mMap)
- return;
-
- mShowNavigePath = false;
- mOldX = 0;
- mOldY = 0;
- mOldTileX = 0;
- mOldTileY = 0;
- mNavigateX = 0;
- mNavigateY = 0;
- mNavigateId = 0;
-
- mNavigatePath.clear();
-
- const SpecialLayer *const tmpLayer = mMap->getTempLayer();
- if (!tmpLayer)
- return;
-
- tmpLayer->clean();
-}
-
-void LocalPlayer::updateCoords()
-{
- Being::updateCoords();
-
- const Vector &playerPos = getPosition();
- // probably map not loaded.
- if (!playerPos.x || !playerPos.y)
- return;
-
- if (mX != mOldTileX || mY != mOldTileY)
- {
- if (socialWindow)
- socialWindow->updatePortals();
- if (viewport)
- viewport->hideBeingPopup();
- if (mMap)
- {
- std::string str = mMap->getObjectData(mX, mY,
- MapItem::MUSIC);
- if (str.empty())
- str = mMap->getMusicFile();
- if (str != soundManager.getCurrentMusicFile())
- {
- if (str.empty())
- soundManager.fadeOutMusic();
- else
- soundManager.fadeOutAndPlayMusic(str);
- }
- }
- }
-
- if (mShowNavigePath)
- {
- if (mMap && (mX != mOldTileX || mY != mOldTileY))
- {
- SpecialLayer *const tmpLayer = mMap->getTempLayer();
- if (!tmpLayer)
- return;
-
- const int x = static_cast<int>(playerPos.x - 16) / 32;
- const int y = static_cast<int>(playerPos.y - 32) / 32;
- if (mNavigateId)
- {
- if (!actorSpriteManager)
- {
- navigateClean();
- return;
- }
-
- const Being *const being = actorSpriteManager
- ->findBeing(mNavigateId);
- if (!being)
- {
- navigateClean();
- return;
- }
- mNavigateX = being->getTileX();
- mNavigateY = being->getTileY();
- }
-
- if (mNavigateX == x && mNavigateY == y)
- {
- navigateClean();
- return;
- }
- else
- {
- for (Path::const_iterator i = mNavigatePath.begin(),
- i_end = mNavigatePath.end(); i != i_end; ++ i)
- {
- if ((*i).x == mX && (*i).y == mY)
- {
- mNavigatePath.pop_front();
- break;
- }
- }
-
- if (mDrawPath)
- {
- tmpLayer->clean();
- tmpLayer->addRoad(mNavigatePath);
- }
- }
- }
- }
- mOldX = static_cast<int>(playerPos.x);
- mOldY = static_cast<int>(playerPos.y);
- mOldTileX = mX;
- mOldTileY = mY;
-}
-
-void LocalPlayer::targetMoved() const
-{
-/*
- if (mKeepAttacking)
- {
- if (mTarget && mServerAttack)
- {
- logger->log("LocalPlayer::targetMoved0");
- if (!client->limitPackets(PACKET_ATTACK))
- return;
- logger->log("LocalPlayer::targetMoved");
- Net::getPlayerHandler()->attack(mTarget->getId(), mServerAttack);
- }
- }
-*/
-}
-
-int LocalPlayer::getPathLength(const Being *const being) const
-{
- if (!mMap || !being)
- return 0;
-
- const Vector &playerPos = getPosition();
-
- if (being->mX == mX && being->mY == mY)
- return 0;
-
- if (being->mX - 1 <= mX && being->mX + 1 >= mX
- && being->mY - 1 <= mY && being->mY + 1 >= mY)
- {
- return 1;
- }
-
- if (mTargetOnlyReachable)
- {
- const Path debugPath = mMap->findPath(
- static_cast<int>(playerPos.x - 16) / 32,
- static_cast<int>(playerPos.y - 32) / 32,
- being->getTileX(), being->getTileY(),
- getWalkMask(), 0);
- return static_cast<int>(debugPath.size());
- }
- else
- {
- const int dx = static_cast<int>(abs(being->mX - mX));
- const int dy = static_cast<int>(abs(being->mY - mY));
- if (dx > dy)
- return dx;
- return dy;
- }
-}
-
-int LocalPlayer::getAttackRange2() const
-{
- int range = getAttackRange();
- if (range == 1)
- range = 2;
- return range;
-}
-
-void LocalPlayer::attack2(Being *const target, const bool keep,
- const bool dontChangeEquipment)
-{
- if (!dontChangeEquipment && target)
- changeEquipmentBeforeAttack(target);
-
- // probably need cache getPathLength(target)
- if ((!target || mAttackType == 0 || mAttackType == 3)
- || (withinAttackRange(target, serverVersion < 1,
- serverVersion < 1 ? 1 : 0)
- && getPathLength(target) <= getAttackRange2()))
- {
- attack(target, keep);
- if (mAttackType == 2)
- {
- if (!target)
- {
- if (pickUpItems())
- return;
- }
- else
- {
- pickUpItems(3);
- }
- }
- }
- else if (!mPickUpTarget)
- {
- if (mAttackType == 2)
- {
- if (pickUpItems())
- return;
- }
- setTarget(target);
- if (target && target->getType() != Being::NPC)
- {
- mKeepAttacking = true;
- moveToTarget();
- }
- }
-}
-
-void LocalPlayer::setFollow(const std::string &player)
-{
- mPlayerFollowed = player;
- if (!mPlayerFollowed.empty())
- {
- // TRANSLATORS: follow command message
- std::string msg = strprintf(_("Follow: %s"), player.c_str());
- debugMsg(msg);
- }
- else
- {
- // TRANSLATORS: follow command message
- debugMsg(_("Follow canceled"));
- }
-}
-
-void LocalPlayer::setImitate(const std::string &player)
-{
- mPlayerImitated = player;
- if (!mPlayerImitated.empty())
- {
- // TRANSLATORS: imitate command message
- std::string msg = strprintf(_("Imitation: %s"), player.c_str());
- debugMsg(msg);
- }
- else
- {
- // TRANSLATORS: imitate command message
- debugMsg(_("Imitation canceled"));
- }
-}
-
-void LocalPlayer::cancelFollow()
-{
- if (!mPlayerFollowed.empty())
- {
- // TRANSLATORS: cancel follow message
- debugMsg(_("Follow canceled"));
- }
- if (!mPlayerImitated.empty())
- {
- // TRANSLATORS: cancel follow message
- debugMsg(_("Imitation canceled"));
- }
- mPlayerFollowed.clear();
- mPlayerImitated.clear();
-}
-
-void LocalPlayer::imitateEmote(const Being *const being,
- const unsigned char action) const
-{
- if (!being)
- return;
-
- std::string player_imitated = getImitate();
- if (!player_imitated.empty() && being->getName() == player_imitated)
- emote(action);
-}
-
-void LocalPlayer::imitateAction(const Being *const being,
- const Being::Action &action)
-{
- if (!being)
- return;
-
- if (!mPlayerImitated.empty() && being->getName() == mPlayerImitated)
- {
- setAction(action);
- Net::getPlayerHandler()->changeAction(action);
- }
-}
-
-void LocalPlayer::imitateDirection(const Being *const being,
- const unsigned char dir)
-{
- if (!being)
- return;
-
- if (!mPlayerImitated.empty() && being->getName() == mPlayerImitated)
- {
- if (!client->limitPackets(PACKET_DIRECTION))
- return;
-
- if (mFollowMode == 2)
- {
- uint8_t dir2 = 0;
- if (dir & Being::LEFT)
- dir2 |= Being::RIGHT;
- else if (dir & Being::RIGHT)
- dir2 |= Being::LEFT;
- if (dir & Being::UP)
- dir2 |= Being::DOWN;
- else if (dir & Being::DOWN)
- dir2 |= Being::UP;
-
- setDirection(dir2);
- Net::getPlayerHandler()->setDirection(dir2);
- }
- else
- {
- setDirection(dir);
- Net::getPlayerHandler()->setDirection(dir);
- }
- }
-}
-
-void LocalPlayer::imitateOutfit(Being *const player, const int sprite) const
-{
- if (!player)
- return;
-
- if (mImitationMode == 1 && !mPlayerImitated.empty()
- && player->getName() == mPlayerImitated)
- {
- if (sprite < 0 || sprite >= player->getNumberOfLayers())
- return;
-
- const AnimatedSprite *const equipmentSprite
- = dynamic_cast<const AnimatedSprite *const>(
- player->getSprite(sprite));
-
- if (equipmentSprite)
- {
-// logger->log("have equipmentSprite");
- const Inventory *const inv = PlayerInfo::getInventory();
- if (!inv)
- return;
-
- const std::string &path = equipmentSprite->getIdPath();
- if (path.empty())
- return;
-
-// logger->log("idPath: " + path);
- const Item *const item = inv->findItemBySprite(path,
- player->getGender(), player->getSubType());
- if (item && !item->isEquipped())
- Net::getInventoryHandler()->equipItem(item);
- }
- else
- {
-// logger->log("have unequip %d", sprite);
- const int equipmentSlot = Net::getInventoryHandler()
- ->convertFromServerSlot(sprite);
-// logger->log("equipmentSlot: " + toString(equipmentSlot));
- if (equipmentSlot == EQUIP_PROJECTILE_SLOT)
- return;
-
- const Item *const item = PlayerInfo::getEquipment(equipmentSlot);
- if (item)
- {
-// logger->log("unequiping");
- Net::getInventoryHandler()->unequipItem(item);
- }
- }
- }
-}
-
-void LocalPlayer::followMoveTo(const Being *const being,
- const int x, const int y)
-{
- if (being && !mPlayerFollowed.empty()
- && being->getName() == mPlayerFollowed)
- {
- mPickUpTarget = nullptr;
- setDestination(x, y);
- }
-}
-
-void LocalPlayer::followMoveTo(const Being *const being,
- const int x1, const int y1,
- const int x2, const int y2)
-{
- if (!being)
- return;
-
- mPickUpTarget = nullptr;
- if (!mPlayerFollowed.empty() && being->getName() == mPlayerFollowed)
- {
- switch (mFollowMode)
- {
- case 0:
- setDestination(x1, y1);
- setNextDest(x2, y2);
- break;
- case 1:
- if (x1 != x2 || y1 != y2)
- {
- setDestination(mX + x2 - x1, mY + y2 - y1);
- setNextDest(mX + x2 - x1, mY + y2 - y1);
- }
- break;
- case 2:
- if (x1 != x2 || y1 != y2)
- {
- setDestination(mX + x1 - x2, mY + y1 - y2);
- setNextDest(mX + x1 - x2, mY + y1 - y2);
- }
- break;
- case 3:
- if (!mTarget || mTarget->getName() != mPlayerFollowed)
- {
- if (actorSpriteManager)
- {
- Being *const b = actorSpriteManager->findBeingByName(
- mPlayerFollowed, Being::PLAYER);
- setTarget(b);
- }
- }
- moveToTarget();
- setNextDest(x2, y2);
- break;
- default:
- break;
- }
- }
-}
-
-void LocalPlayer::setNextDest(const int x, const int y)
-{
- mNextDestX = x;
- mNextDestY = y;
-}
-
-bool LocalPlayer::allowAction()
-{
- if (mIsServerBuggy)
- {
- if (mLastAction != -1)
- return false;
- mLastAction = tick_time;
- }
- return true;
-}
-
-/*
-bool LocalPlayer::allowMove() const
-{
- if (mIsServerBuggy)
- {
- if (mAction == MOVE)
- return false;
- }
- return true;
-}
-*/
-
-void LocalPlayer::fixPos(const int maxDist)
-{
- if (!mCrossX && !mCrossY)
- return;
-
- const int dx = abs(mX - mCrossX);
- const int dy = abs(mY - mCrossY);
- const int dest = (dx * dx) + (dy * dy);
- const int time = cur_time;
-
- if (dest > maxDist && mActivityTime
- && (time < mActivityTime || time - mActivityTime > 2))
- {
- mActivityTime = time;
- moveTo(mCrossX, mCrossY);
- }
-}
-
-void LocalPlayer::setRealPos(const int x, const int y)
-{
- if (!mMap)
- return;
-
- SpecialLayer *const layer = mMap->getTempLayer();
- if (layer)
- {
- fixPos(1);
-
- if ((mCrossX || mCrossY) && layer->getTile(mCrossX, mCrossY)
- && layer->getTile(mCrossX, mCrossY)->getType() == MapItem::CROSS)
- {
- layer->setTile(mCrossX, mCrossY, MapItem::EMPTY);
- }
-
- if (!layer->getTile(x, y)
- || layer->getTile(x, y)->getType() == MapItem::EMPTY)
- {
- if (getTileX() != x && getTileY() != y)
- layer->setTile(x, y, MapItem::CROSS);
- }
-
- mCrossX = x;
- mCrossY = y;
- }
- if (mMap->isCustom())
- mMap->setWalk(x, y, true);
-}
-void LocalPlayer::fixAttackTarget()
-{
- if (!mMap || !mTarget)
- return;
-
- if (mMoveToTargetType == 7 || !mAttackType
- || !config.getBoolValue("autofixPos"))
- {
- return;
- }
-
- const Vector &playerPos = getPosition();
- const Path debugPath = mMap->findPath(
- static_cast<int>(playerPos.x - 16) / 32,
- static_cast<int>(playerPos.y - 32) / 32,
- mTarget->getTileX(), mTarget->getTileY(),
- getWalkMask(), 0);
-
- if (!debugPath.empty())
- {
- const Path::const_iterator i = debugPath.begin();
- moveTo((*i).x, (*i).y);
- }
-}
-
-void LocalPlayer::respawn()
-{
- navigateClean();
-}
-
-int LocalPlayer::getLevel() const
-{
- return PlayerInfo::getAttribute(PlayerInfo::LEVEL);
-}
-
-void LocalPlayer::updateNavigateList()
-{
- if (mMap)
- {
- const std::map<std::string, Vector>::const_iterator iter =
- mHomes.find(mMap->getProperty("_realfilename"));
-
- if (iter != mHomes.end())
- {
- const Vector &pos = mHomes[(*iter).first];
- if (pos.x && pos.y)
- {
- mMap->addPortalTile("home", MapItem::HOME,
- static_cast<int>(pos.x), static_cast<int>(pos.y));
- }
- }
- }
-}
-
-void LocalPlayer::waitFor(const std::string &nick)
-{
- mWaitFor = nick;
-}
-
-void LocalPlayer::checkNewName(Being *const being)
-{
- if (!being)
- return;
-
- const std::string nick = being->getName();
- if (being->getType() == ActorSprite::PLAYER)
- {
- const Guild *const guild = getGuild();
- if (guild)
- {
- const GuildMember *const gm = guild->getMember(nick);
- if (gm)
- {
- const int level = gm->getLevel();
- if (level > 1 && being->getLevel() != level)
- {
- being->setLevel(level);
- being->updateName();
- }
- }
- }
- if (chatWindow)
- {
- WhisperTab *const tab = chatWindow->getWhisperTab(nick);
- if (tab)
- tab->setWhisperTabColors();
- }
- }
-
- if (!mWaitFor.empty() && mWaitFor == nick)
- {
- // TRANSLATORS: wait player/monster message
- debugMsg(strprintf(_("You see %s"), mWaitFor.c_str()));
- soundManager.playGuiSound(SOUND_INFO);
- mWaitFor.clear();
- }
-}
-
-void LocalPlayer::resetYellowBar()
-{
- mInvertDirection = 0;
- mCrazyMoveType = config.resetIntValue("crazyMoveType");
- mMoveToTargetType = config.resetIntValue("moveToTargetType");
- mFollowMode = config.resetIntValue("followMode");
- mAttackWeaponType = config.resetIntValue("attackWeaponType");
- mAttackType = config.resetIntValue("attackType");
- mMagicAttackType = config.resetIntValue("magicAttackType");
- mPvpAttackType = config.resetIntValue("pvpAttackType");
- mQuickDropCounter = config.resetIntValue("quickDropCounter");
- mPickUpType = config.resetIntValue("pickUpType");
- if (viewport)
- {
- viewport->setDebugPath(0);
- if (viewport->getCameraMode())
- viewport->toggleCameraMode();
- }
- if (mMap)
- mMap->setDebugFlags(0);
- mImitationMode = config.resetIntValue("imitationMode");
- mDisableGameModifiers = config.resetBoolValue("disableGameModifiers");
-
- if (miniStatusWindow)
- miniStatusWindow->updateStatus();
-}
-
-unsigned char LocalPlayer::getWalkMask() const
-{
- // for now blocking all types of collisions
- return Map::BLOCKMASK_WALL | Map::BLOCKMASK_AIR | Map::BLOCKMASK_WATER;
-}
-
-void LocalPlayer::removeHome()
-{
- if (!mMap)
- return;
-
- const std::string key = mMap->getProperty("_realfilename");
- const std::map<std::string, Vector>::iterator iter = mHomes.find(key);
-
- if (iter != mHomes.end())
- mHomes.erase(key);
-}
-
-void LocalPlayer::stopAdvert()
-{
- mBlockAdvert = true;
-}
-
-bool LocalPlayer::checAttackPermissions(const Being *const target) const
-{
- if (!target)
- return false;
-
- switch (mPvpAttackType)
- {
- case 0:
- return true;
- case 1:
- return !(player_relations.getRelation(target->getName())
- == PlayerRelation::FRIEND);
- case 2:
- return player_relations.checkBadRelation(target->getName());
- default:
- case 3:
- return false;
- }
-}
-
-
-const char *LocalPlayer::getVarItem(const char *const *const arr,
- const unsigned index,
- const unsigned sz) const
-{
- if (index < sz)
- return arr[index];
- return arr[sz];
-}
-
-void LocalPlayer::updateStatus() const
-{
- if (serverVersion >= 4 && mEnableAdvert)
- {
- uint8_t status = 0;
- if (mTradebot && shopWindow && !shopWindow->isShopEmpty())
- status |= FLAG_SHOP;
-
- if (mAwayMode || mPseudoAwayMode)
- status |= FLAG_AWAY;
-
- if (mInactive)
- status |= FLAG_INACTIVE;
-
- Net::getPlayerHandler()->updateStatus(status);
- }
-}
-
-void LocalPlayer::setTestParticle(const std::string &fileName, bool updateHash)
-{
- mTestParticleName = fileName;
- mTestParticleTime = cur_time;
- if (mTestParticle)
- {
- mChildParticleEffects.removeLocally(mTestParticle);
- mTestParticle = nullptr;
- }
- if (!fileName.empty())
- {
- mTestParticle = particleEngine->addEffect(fileName, 0, 0, false);
- controlParticle(mTestParticle);
- if (updateHash)
- mTestParticleHash = UpdaterWindow::getFileHash(mTestParticleName);
- }
-}
-
-void AwayListener::action(const gcn::ActionEvent &event)
-{
- if (event.getId() == "ok" && player_node && player_node->getAway())
- {
- player_node->changeAwayMode();
- player_node->updateStatus();
- if (outfitWindow)
- outfitWindow->unwearAwayOutfit();
- if (miniStatusWindow)
- miniStatusWindow->updateStatus();
- }
-}