summaryrefslogtreecommitdiff
path: root/src/being/localplayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/being/localplayer.cpp')
-rw-r--r--src/being/localplayer.cpp2816
1 files changed, 0 insertions, 2816 deletions
diff --git a/src/being/localplayer.cpp b/src/being/localplayer.cpp
deleted file mode 100644
index 1a12a3808..000000000
--- a/src/being/localplayer.cpp
+++ /dev/null
@@ -1,2816 +0,0 @@
-/*
- * The ManaPlus Client
- * Copyright (C) 2004-2009 The Mana World Development Team
- * Copyright (C) 2009-2010 The Mana Developers
- * Copyright (C) 2011-2017 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 "being/localplayer.h"
-
-#include "actormanager.h"
-#include "configuration.h"
-#include "gamemodifiers.h"
-#include "guild.h"
-#include "party.h"
-#include "settings.h"
-#include "soundmanager.h"
-#include "statuseffect.h"
-
-#include "being/beingflag.h"
-#include "being/crazymoves.h"
-#include "being/playerinfo.h"
-#include "being/playerrelations.h"
-
-#include "const/sound.h"
-
-#include "enums/equipslot.h"
-
-#include "enums/being/beingdirection.h"
-
-#include "enums/resources/map/blockmask.h"
-#include "enums/resources/map/mapitemtype.h"
-
-#include "particle/particleengine.h"
-
-#include "input/keyboardconfig.h"
-
-#include "gui/gui.h"
-#include "gui/userpalette.h"
-#include "gui/popupmanager.h"
-
-#include "gui/windows/chatwindow.h"
-#include "gui/windows/ministatuswindow.h"
-#include "gui/windows/okdialog.h"
-#include "gui/windows/outfitwindow.h"
-#include "gui/windows/shopwindow.h"
-#include "gui/windows/socialwindow.h"
-#include "gui/windows/statuswindow.h"
-#include "gui/windows/updaterwindow.h"
-
-#include "gui/widgets/tabs/chat/whispertab.h"
-
-#include "listeners/awaylistener.h"
-
-#include "net/beinghandler.h"
-#include "net/chathandler.h"
-#include "net/inventoryhandler.h"
-#include "net/net.h"
-#include "net/packetlimiter.h"
-#include "net/playerhandler.h"
-#include "net/serverfeatures.h"
-
-#include "resources/iteminfo.h"
-
-#include "resources/db/weaponsdb.h"
-
-#include "resources/item/item.h"
-
-#include "resources/map/map.h"
-#include "resources/map/mapitem.h"
-#include "resources/map/speciallayer.h"
-#include "resources/map/walklayer.h"
-
-#include "resources/sprite/animatedsprite.h"
-
-#include "utils/delete2.h"
-#include "utils/foreach.h"
-#include "utils/gettext.h"
-#include "utils/timer.h"
-
-#ifdef USE_MUMBLE
-#include "mumblemanager.h"
-#endif // USE_MUMBLE
-
-#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 *localPlayer = nullptr;
-
-extern OkDialog *weightNotice;
-extern time_t weightNoticeTime;
-
-LocalPlayer::LocalPlayer(const BeingId id,
- const BeingTypeId subType) :
- Being(id, ActorType::Player),
- ActorSpriteListener(),
- AttributeListener(),
- PlayerDeathListener(),
- mMoveState(0),
- mLastTargetX(0),
- mLastTargetY(0),
- mHomes(),
- mTarget(nullptr),
- mPlayerFollowed(),
- mPlayerImitated(),
- mNextDestX(0),
- mNextDestY(0),
- mPickUpTarget(nullptr),
- mLastAction(-1),
- mStatusEffectIcons(),
- mMessages(),
- mMessageTime(0),
- mAwayListener(new AwayListener),
- mAwayDialog(nullptr),
- mPingSendTick(0),
- mPingTime(0),
- mAfkTime(0),
- mActivityTime(0),
- mNavigateX(0),
- mNavigateY(0),
- mNavigateId(BeingId_zero),
- mCrossX(0),
- mCrossY(0),
- mOldX(0),
- mOldY(0),
- mOldTileX(0),
- mOldTileY(0),
- mNavigatePath(),
- mLastHitFrom(),
- mWaitFor(),
- mAdvertTime(0),
- mTestParticle(nullptr),
- mTestParticleName(),
- mTestParticleTime(0),
- mTestParticleHash(0L),
- mSyncPlayerMoveDistance(config.getIntValue("syncPlayerMoveDistance")),
- mUnfreezeTime(0),
- mWalkingDir(0),
- mUpdateName(true),
- mBlockAdvert(false),
- mTargetDeadPlayers(config.getBoolValue("targetDeadPlayers")),
- mServerAttack(fromBool(config.getBoolValue("serverAttack"), Keep)),
- mVisibleNames(static_cast<VisibleName::Type>(
- config.getIntValue("visiblenames"))),
- mEnableAdvert(config.getBoolValue("enableAdvert")),
- mTradebot(config.getBoolValue("tradebot")),
- mTargetOnlyReachable(config.getBoolValue("targetOnlyReachable")),
- 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")),
- mShowServerPos(config.getBoolValue("showserverpos")),
- mNextStep(false),
- mGoingToTarget(false),
- mKeepAttacking(false),
- mPathSetByMouse(false),
- mWaitPing(false),
- mShowNavigePath(false),
- mAllowRename(false),
- mFreezed(false)
-{
- logger->log1("LocalPlayer::LocalPlayer");
-
- postInit(subType, nullptr);
- mAttackRange = 0;
- mLevel = 1;
- mAdvanced = true;
- mTextColor = &theme->getColor(ThemeColorId::PLAYER, 255);
- if (userPalette != nullptr)
- mNameColor = &userPalette->getColor(UserColorId::SELF);
- else
- mNameColor = nullptr;
-
- PlayerInfo::setStatBase(Attributes::PLAYER_WALK_SPEED,
- getWalkSpeed());
- PlayerInfo::setStatMod(Attributes::PLAYER_WALK_SPEED, 0);
-
- loadHomes();
-
- config.addListener("showownname", this);
- config.addListener("targetDeadPlayers", this);
- serverConfig.addListener("enableBuggyServers", this);
- config.addListener("syncPlayerMove", this);
- config.addListener("syncPlayerMoveDistance", 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);
- config.addListener("showserverpos", this);
- config.addListener("visiblenames", this);
- setShowName(config.getBoolValue("showownname"));
-}
-
-LocalPlayer::~LocalPlayer()
-{
- logger->log1("LocalPlayer::~LocalPlayer");
-
- config.removeListeners(this);
- serverConfig.removeListener("enableBuggyServers", this);
-
- navigateClean();
- mCrossX = 0;
- mCrossY = 0;
-
- updateNavigateList();
-
- if (mAwayDialog != nullptr)
- {
- soundManager.volumeRestore();
- delete2(mAwayDialog)
- }
- delete2(mAwayListener);
-}
-
-void LocalPlayer::logic()
-{
- BLOCK_START("LocalPlayer::logic")
-#ifdef USE_MUMBLE
- if (mumbleManager)
- mumbleManager->setPos(mX, mY, mDirection);
-#endif // USE_MUMBLE
-
- // Actions are allowed once per second
- if (get_elapsed_time(mLastAction) >= 1000)
- mLastAction = -1;
-
- if (mActivityTime == 0 || mLastAction != -1)
- mActivityTime = cur_time;
-
- if (mUnfreezeTime > 0 &&
- mUnfreezeTime <= tick_time)
- {
- mUnfreezeTime = 0;
- mFreezed = false;
- }
-
- if ((mAction != BeingAction::MOVE || mNextStep) && !mNavigatePath.empty())
- {
- mNextStep = false;
- int dist = 5;
- if (!mSyncPlayerMove)
- dist = 20;
-
- if (((mNavigateX != 0) || (mNavigateY != 0)) &&
- ((mCrossX + dist >= mX && mCrossX <= mX + dist
- && mCrossY + dist >= mY && mCrossY <= mY + dist)
- || ((mCrossX == 0) && (mCrossY == 0))))
- {
- const Path::const_iterator i = mNavigatePath.begin();
- if ((*i).x == mX && (*i).y == mY)
- mNavigatePath.pop_front();
- else
- setDestination((*i).x, (*i).y);
- }
- }
-
- // Show XP messages
- if (!mMessages.empty())
- {
- if (mMessageTime == 0)
- {
- const MessagePair info = mMessages.front();
-
- if ((particleEngine != nullptr) && (gui != nullptr))
- {
- particleEngine->addTextRiseFadeOutEffect(
- info.first,
- mPixelX,
- mPixelY - 48,
- &userPalette->getColor(info.second),
- gui->getInfoParticleFont(),
- true);
- }
-
- mMessages.pop_front();
- mMessageTime = 30;
- }
- mMessageTime--;
- }
-
- if (mTarget != nullptr)
- {
- if (mTarget->getType() == ActorType::Npc)
- {
- // NPCs are always in range
- mTarget->setTargetType(TargetCursorType::IN_RANGE);
- }
- else
- {
- // Find whether target is in range
- const int rangeX = CAST_S32(
- abs(mTarget->mX - mX));
- const int rangeY = CAST_S32(
- abs(mTarget->mY - mY));
- const int attackRange = getAttackRange();
- const TargetCursorTypeT targetType
- = rangeX > attackRange || rangeY > attackRange
- ? TargetCursorType::NORMAL : TargetCursorType::IN_RANGE;
- mTarget->setTargetType(targetType);
-
- if (!mTarget->isAlive() && (!mTargetDeadPlayers
- || mTarget->getType() != ActorType::Player))
- {
- stopAttack(true);
- }
-
- if (mKeepAttacking && (mTarget != nullptr))
- attack(mTarget, true);
- }
- }
-
- Being::logic();
- BLOCK_END("LocalPlayer::logic")
-}
-
-void LocalPlayer::slowLogic()
-{
- BLOCK_START("LocalPlayer::slowLogic")
- const time_t time = cur_time;
- if ((weightNotice != nullptr) && weightNoticeTime < time)
- {
- weightNotice->scheduleDelete();
- weightNotice = nullptr;
- weightNoticeTime = 0;
- }
-
- if ((serverFeatures != nullptr) &&
- !serverFeatures->havePlayerStatusUpdate() &&
- mEnableAdvert &&
- !mBlockAdvert &&
- mAdvertTime < cur_time)
- {
- uint8_t smile = BeingFlag::SPECIAL;
- if (mTradebot &&
- shopWindow != nullptr &&
- !shopWindow->isShopEmpty())
- {
- smile |= BeingFlag::SHOP;
- }
-
- if (settings.awayMode || settings.pseudoAwayMode)
- smile |= BeingFlag::AWAY;
-
- if (mInactive)
- smile |= BeingFlag::INACTIVE;
-
- if (emote(smile))
- mAdvertTime = time + 60;
- else
- mAdvertTime = time + 30;
- }
-
- if (mTestParticleTime != time && !mTestParticleName.empty())
- {
- const unsigned long hash = UpdaterWindow::getFileHash(
- mTestParticleName);
- if (hash != mTestParticleHash)
- {
- setTestParticle(mTestParticleName, false);
- mTestParticleHash = hash;
- }
- mTestParticleTime = time;
- }
-
- BLOCK_END("LocalPlayer::slowLogic")
-}
-
-void LocalPlayer::setAction(const BeingActionT &action,
- const int attackId)
-{
- if (action == BeingAction::DEAD)
- {
- if (!mLastHitFrom.empty() &&
- !serverFeatures->haveKillerId())
- {
- // TRANSLATORS: chat message after death
- debugMsg(strprintf(_("You were killed by %s."),
- mLastHitFrom.c_str()));
- mLastHitFrom.clear();
- }
- setTarget(nullptr);
- }
-
- Being::setAction(action,
- attackId);
-#ifdef USE_MUMBLE
- if (mumbleManager)
- mumbleManager->setAction(CAST_S32(action));
-#endif // USE_MUMBLE
-}
-
-void LocalPlayer::setGroupId(const int id)
-{
- Being::setGroupId(id);
-
- if (id > 0)
- {
- setGM(true);
- if (chatWindow != nullptr)
- {
- chatWindow->loadGMCommands();
- chatWindow->showGMTab();
- }
- }
- else
- {
- setGM(false);
- }
- if (statusWindow != nullptr)
- statusWindow->updateLevelLabel();
-}
-
-void LocalPlayer::nextTile(unsigned char dir A_UNUSED = 0)
-{
- const Party *const party = Party::getParty(1);
- if (party != nullptr)
- {
- PartyMember *const pm = party->getMember(mName);
- if (pm != nullptr)
- {
- pm->setX(mX);
- pm->setY(mY);
- }
- }
-
- if (mPath.empty())
- {
- if (mPickUpTarget != nullptr)
- pickUp(mPickUpTarget);
-
- if (mWalkingDir != 0u)
- startWalking(mWalkingDir);
- }
- else if (mPath.size() == 1)
- {
- if (mPickUpTarget != nullptr)
- pickUp(mPickUpTarget);
- }
-
- if (mGoingToTarget && (mTarget != nullptr) && withinAttackRange(mTarget))
- {
- mAction = BeingAction::STAND;
- attack(mTarget, true);
- mGoingToTarget = false;
- mPath.clear();
- return;
- }
- else if (mGoingToTarget && (mTarget == nullptr))
- {
- mGoingToTarget = false;
- mPath.clear();
- }
-
- if (mPath.empty())
- {
- if (mNavigatePath.empty() || mAction != BeingAction::MOVE)
- setAction(BeingAction::STAND, 0);
- else
- mNextStep = true;
- }
- else
- {
- Being::nextTile();
- }
-}
-
-bool LocalPlayer::pickUp(FloorItem *const item)
-{
- if (item == nullptr)
- return false;
-
- if (!PacketLimiter::limitPackets(PacketType::PACKET_PICKUP))
- return false;
-
- const int dx = item->getTileX() - mX;
- const int dy = item->getTileY() - mY;
- int dist = 6;
-
- const unsigned int pickUpType = settings.pickUpType;
- if (pickUpType >= 4 && pickUpType <= 6)
- dist = 4;
-
- if (dx * dx + dy * dy < dist)
- {
- if ((actorManager != nullptr) && actorManager->checkForPickup(item))
- {
- PlayerInfo::pickUpItem(item, Sfx_true);
- mPickUpTarget = nullptr;
- }
- }
- else if (pickUpType >= 4 && pickUpType <= 6)
- {
- const Path debugPath = mMap->findPath(
- (mPixelX - mapTileSize / 2) / mapTileSize,
- (mPixelY - mapTileSize) / mapTileSize,
- item->getTileX(),
- item->getTileY(),
- getBlockWalkMask(),
- 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 != nullptr))
- return;
-
- if (target == mTarget)
- return;
-
- Being *oldTarget = nullptr;
- if (mTarget != nullptr)
- {
- mTarget->untarget();
- oldTarget = mTarget;
- }
-
- if (mTarget != nullptr)
- {
- if (mTarget->getType() == ActorType::Monster)
- mTarget->setShowName(false);
- }
-
- mTarget = target;
-
- if (oldTarget != nullptr)
- oldTarget->updateName();
-
- if (target != nullptr)
- {
- mLastTargetX = target->mX;
- mLastTargetY = target->mY;
- target->updateName();
- if (mVisibleNames == VisibleName::ShowOnSelection)
- target->setShowName(true);
- }
- if (oldTarget != nullptr && mVisibleNames == VisibleName::ShowOnSelection)
- oldTarget->setShowName(false);
- if (target != nullptr && target->getType() == ActorType::Monster)
- target->setShowName(true);
-}
-
-Being *LocalPlayer::setNewTarget(const ActorTypeT type,
- const AllowSort allowSort)
-{
- if (actorManager != nullptr)
- {
- Being *const target = actorManager->findNearestLivingBeing(
- localPlayer, 20, type, allowSort);
-
- if ((target != nullptr) && target != mTarget)
- setTarget(target);
-
- return target;
- }
- return nullptr;
-}
-
-void LocalPlayer::setDestination(const int x, const int y)
-{
- mActivityTime = cur_time;
-
- if (settings.attackType == 0 || !mAttackMoving)
- mKeepAttacking = false;
-
- // Only send a new message to the server when destination changes
- if (x != mDest.x || y != mDest.y)
- {
- if (settings.moveType != 1)
- {
- playerHandler->setDestination(x, y, mDirection);
- Being::setDestination(x, y);
- }
- else
- {
- uint8_t newDir = 0;
- if ((mDirection & BeingDirection::UP) != 0)
- newDir |= BeingDirection::DOWN;
- if ((mDirection & BeingDirection::LEFT) != 0)
- newDir |= BeingDirection::RIGHT;
- if ((mDirection & BeingDirection::DOWN) != 0)
- newDir |= BeingDirection::UP;
- if ((mDirection & BeingDirection::RIGHT) != 0)
- newDir |= BeingDirection::LEFT;
-
- playerHandler->setDestination(x, y, newDir);
-
-// if (PacketLimiter::limitPackets(PacketType::PACKET_DIRECTION))
- {
- setDirection(newDir);
- playerHandler->setDirection(newDir);
- }
-
- Being::setDestination(x, y);
- playerHandler->setDestination(x, y, mDirection);
- }
- }
-}
-
-void LocalPlayer::setWalkingDir(const unsigned char dir)
-{
- // This function is called by Game::handleInput()
- mWalkingDir = dir;
-
- // If we're not already walking, start walking.
- if (mAction != BeingAction::MOVE && (dir != 0u))
- startWalking(dir);
-}
-
-void LocalPlayer::startWalking(const unsigned char dir)
-{
- // This function is called by setWalkingDir(),
- // but also by nextTile() for TMW-Athena...
- if ((mMap == nullptr) || (dir == 0u))
- return;
-
- mPickUpTarget = nullptr;
- if (mAction == BeingAction::MOVE && !mPath.empty())
- {
- // Just finish the current action, otherwise we get out of sync
- Being::setDestination(mX, mY);
- return;
- }
-
- int dx = 0, dy = 0;
- if ((dir & BeingDirection::UP) != 0)
- dy--;
- if ((dir & BeingDirection::DOWN) != 0)
- dy++;
- if ((dir & BeingDirection::LEFT) != 0)
- dx--;
- if ((dir & BeingDirection::RIGHT) != 0)
- dx++;
-
- const unsigned char blockWalkMask = getBlockWalkMask();
- // Prevent skipping corners over colliding tiles
- if ((dx != 0) && !mMap->getWalk(mX + dx, mY, blockWalkMask))
- dx = 0;
- if ((dy != 0) && !mMap->getWalk(mX, mY + dy, blockWalkMask))
- dy = 0;
-
- // Choose a straight direction when diagonal target is blocked
- if (dx != 0 && dy != 0 && !mMap->getWalk(mX + dx, mY + dy, blockWalkMask))
- dx = 0;
-
- // Walk to where the player can actually go
- if ((dx != 0 || dy != 0) && mMap->getWalk(mX + dx, mY + dy, blockWalkMask))
- {
- setDestination(mX + dx, mY + dy);
- }
- else if (dir != mDirection)
- {
- // If the being can't move, just change direction
-
-// if (PacketLimiter::limitPackets(PacketType::PACKET_DIRECTION))
- {
- playerHandler->setDirection(dir);
- setDirection(dir);
- }
- }
-}
-
-void LocalPlayer::stopWalking(const bool sendToServer)
-{
- if (mAction == BeingAction::MOVE && (mWalkingDir != 0u))
- {
- mWalkingDir = 0;
- mPickUpTarget = nullptr;
- setDestination(mPixelX,
- mPixelY);
- if (sendToServer)
- {
- playerHandler->setDestination(
- mPixelX,
- mPixelY,
- -1);
- }
- setAction(BeingAction::STAND, 0);
- }
-
- // No path set anymore, so we reset the path by mouse flag
- mPathSetByMouse = false;
-
- clearPath();
- navigateClean();
-}
-
-bool LocalPlayer::toggleSit() const
-{
- if (!PacketLimiter::limitPackets(PacketType::PACKET_SIT))
- return false;
-
- BeingActionT newAction;
- switch (mAction)
- {
- case BeingAction::STAND:
- case BeingAction::PRESTAND:
- case BeingAction::SPAWN:
- newAction = BeingAction::SIT;
- break;
- case BeingAction::SIT:
- newAction = BeingAction::STAND;
- break;
- case BeingAction::MOVE:
- case BeingAction::ATTACK:
- case BeingAction::DEAD:
- case BeingAction::HURT:
- case BeingAction::CAST:
- default:
- return true;
- }
-
- playerHandler->changeAction(newAction);
- return true;
-}
-
-bool LocalPlayer::updateSit() const
-{
- if (!PacketLimiter::limitPackets(PacketType::PACKET_SIT))
- return false;
-
- playerHandler->changeAction(mAction);
- return true;
-}
-
-bool LocalPlayer::emote(const uint8_t emotion)
-{
- if (!PacketLimiter::limitPackets(PacketType::PACKET_EMOTE))
- return false;
-
- playerHandler->emote(emotion);
- return true;
-}
-
-void LocalPlayer::attack(Being *const target, const bool keep,
- const bool dontChangeEquipment)
-{
- mKeepAttacking = keep;
-
- if ((target == nullptr) || target->getType() == ActorType::Npc)
- return;
-
- if (mTarget != target)
- setTarget(target);
-
- // Must be standing or sitting or casting to attack
- if (mAction != BeingAction::STAND &&
- mAction != BeingAction::SIT &&
- mAction != BeingAction::CAST)
- {
- return;
- }
-
-#ifdef TMWA_SUPPORT
- const int dist_x = target->mX - mX;
- const int dist_y = target->mY - mY;
-
- if (Net::getNetworkType() == ServerType::TMWATHENA)
- {
- if (abs(dist_y) >= abs(dist_x))
- {
- if (dist_y > 0)
- setDirection(BeingDirection::DOWN);
- else
- setDirection(BeingDirection::UP);
- }
- else
- {
- if (dist_x > 0)
- setDirection(BeingDirection::RIGHT);
- else
- setDirection(BeingDirection::LEFT);
- }
- }
-#endif // TMWA_SUPPORT
-
- mActionTime = tick_time;
-
- if (target->getType() != ActorType::Player
- || checAttackPermissions(target))
- {
- setAction(BeingAction::ATTACK, 0);
-
- if (!PacketLimiter::limitPackets(PacketType::PACKET_ATTACK))
- return;
-
- if (!dontChangeEquipment)
- changeEquipmentBeforeAttack(target);
-
- const BeingId targetId = target->getId();
- playerHandler->attack(targetId, mServerAttack);
- PlayerInfo::updateAttackAi(targetId, mServerAttack);
- }
-
- if (!keep)
- stopAttack();
-}
-
-void LocalPlayer::stopAttack(const bool keepAttack)
-{
- if (!PacketLimiter::limitPackets(PacketType::PACKET_STOPATTACK))
- return;
-
- if (mServerAttack == Keep_true && mAction == BeingAction::ATTACK)
- playerHandler->stopAttack();
-
- untarget();
- if (!keepAttack || !mAttackNext)
- mKeepAttacking = false;
-}
-
-void LocalPlayer::untarget()
-{
- if (mAction == BeingAction::ATTACK)
- setAction(BeingAction::STAND, 0);
-
- if (mTarget != nullptr)
- setTarget(nullptr);
-}
-
-void LocalPlayer::pickedUp(const ItemInfo &itemInfo,
- const int amount,
- const ItemColor color,
- const BeingId floorItemId,
- const PickupT fail)
-{
- if (fail != Pickup::OKAY)
- {
- if ((actorManager != nullptr) && floorItemId != BeingId_zero)
- {
- FloorItem *const item = actorManager->findItem(floorItemId);
- if (item != nullptr)
- {
- if (!item->getShowMsg())
- return;
- item->setShowMsg(false);
- }
- }
- const char* msg = nullptr;
- 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;
- case Pickup::MAX_AMOUNT:
- // TRANSLATORS: pickup error message
- msg = N_("You can't pickup this amount of items.");
- break;
- case Pickup::STACK_AMOUNT:
- // TRANSLATORS: pickup error message
- msg = N_("Your item stack has max amount.");
- break;
- case Pickup::OKAY:
- break;
- default:
- case Pickup::UNKNOWN:
- // TRANSLATORS: pickup error message
- msg = N_("Unknown problem picking up item.");
- break;
- }
- if ((localChatTab != nullptr) && config.getBoolValue("showpickupchat"))
- localChatTab->chatLog(gettext(msg), ChatMsgType::BY_SERVER);
-
- if ((mMap != nullptr) && config.getBoolValue("showpickupparticle"))
- {
- // Show pickup notification
- addMessageToQueue(gettext(msg), UserColorId::PICKUP_INFO);
- }
- }
- else
- {
- std::string str;
-#ifdef TMWA_SUPPORT
- if (Net::getNetworkType() == ServerType::TMWATHENA)
- {
- str = itemInfo.getName();
- }
- else
-#endif // TMWA_SUPPORT
- {
- str = itemInfo.getName(color);
- }
-
- if (config.getBoolValue("showpickupchat") && (localChatTab != nullptr))
- {
- // 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()),
- ChatMsgType::BY_SERVER);
- }
-
- if ((mMap != nullptr) && config.getBoolValue("showpickupparticle"))
- {
- // Show pickup notification
- if (amount > 1)
- {
- addMessageToQueue(strprintf("%d x %s", amount,
- str.c_str()), UserColorId::PICKUP_INFO);
- }
- else
- {
- addMessageToQueue(str, UserColorId::PICKUP_INFO);
- }
- }
- }
-}
-
-int LocalPlayer::getAttackRange() const
-{
- if (mAttackRange > -1)
- {
- return mAttackRange;
- }
-
- const Item *const weapon = PlayerInfo::getEquipment(
- EquipSlot::FIGHT1_SLOT);
- if (weapon != nullptr)
- {
- 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 == nullptr)
- return false;
-
- int range = getAttackRange() + addRange;
- int dx;
- int dy;
-
- if (fixDistance && range == 1)
- range = 2;
-
- dx = CAST_S32(abs(target->mX - mX));
- dy = CAST_S32(abs(target->mY - mY));
- return !(dx > range || dy > range);
-}
-
-void LocalPlayer::setGotoTarget(Being *const target)
-{
- if (target == nullptr)
- return;
-
- mPickUpTarget = nullptr;
- setTarget(target);
- mGoingToTarget = true;
- navigateTo(target->mX,
- target->mY);
-}
-
-void LocalPlayer::handleStatusEffect(const StatusEffect *const effect,
- const int32_t effectId,
- const Enable newStatus,
- const IsStart start)
-{
- Being::handleStatusEffect(effect,
- effectId,
- newStatus,
- start);
-
- if (effect != nullptr)
- {
- effect->deliverMessage();
- effect->playSFX();
-
- AnimatedSprite *const sprite = effect->getIcon();
-
- if (sprite == nullptr)
- {
- // delete sprite, if necessary
- for (size_t i = 0; i < mStatusEffectIcons.size(); )
- {
- if (mStatusEffectIcons[i] == effectId)
- {
- mStatusEffectIcons.erase(mStatusEffectIcons.begin() + i);
- if (miniStatusWindow != nullptr)
- miniStatusWindow->eraseIcon(CAST_S32(i));
- }
- else
- {
- i++;
- }
- }
- }
- else
- {
- // replace sprite or append
- bool found = false;
- const size_t sz = mStatusEffectIcons.size();
- for (size_t i = 0; i < sz; i++)
- {
- if (mStatusEffectIcons[i] == effectId)
- {
- if (miniStatusWindow != nullptr)
- miniStatusWindow->setIcon(CAST_S32(i), sprite);
- found = true;
- break;
- }
- }
-
- if (!found)
- { // add new
- const int offset = CAST_S32(mStatusEffectIcons.size());
- if (miniStatusWindow != nullptr)
- miniStatusWindow->setIcon(offset, sprite);
- mStatusEffectIcons.push_back(effectId);
- }
- }
- }
-}
-
-void LocalPlayer::addMessageToQueue(const std::string &message,
- const UserColorIdT 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 == "syncPlayerMoveDistance")
- {
- mSyncPlayerMoveDistance = config.getIntValue("syncPlayerMoveDistance");
- }
- else if (value == "drawPath")
- {
- mDrawPath = config.getBoolValue("drawPath");
- }
- else if (value == "serverAttack")
- {
- mServerAttack = fromBool(config.getBoolValue("serverAttack"), Keep);
- }
- 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");
- }
- else if (value == "showserverpos")
- {
- mShowServerPos = config.getBoolValue("showserverpos");
- }
- else if (value == "visiblenames")
- {
- mVisibleNames = static_cast<VisibleName::Type>(
- config.getIntValue("visiblenames"));
- }
-}
-
-void LocalPlayer::addJobMessage(const int change)
-{
- 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"))) ==
- // TRANSLATORS: this is normal experience
- 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::addXpMessage(const int change)
-{
- if (change != 0 && mMessages.size() < 20)
- {
- // TRANSLATORS: get xp message
- addMessageToQueue(strprintf("%d %s", change, _("xp")));
- }
-}
-
-void LocalPlayer::addHomunXpMessage(const int change)
-{
- if (change != 0 && mMessages.size() < 20)
- {
- addMessageToQueue(strprintf("%s %d %s",
- // TRANSLATORS: get homunculus xp message
- _("Homun"),
- change,
- // TRANSLATORS: get xp message
- _("xp")));
- }
-}
-
-void LocalPlayer::addHpMessage(const int change)
-{
- if (change != 0 && mMessages.size() < 20)
- {
- // TRANSLATORS: get hp message
- addMessageToQueue(strprintf("%d %s", change, _("hp")));
- }
-}
-
-void LocalPlayer::addSpMessage(const int change)
-{
- if (change != 0 && mMessages.size() < 20)
- {
- // TRANSLATORS: get hp message
- addMessageToQueue(strprintf("%d %s", change, _("mana")));
- }
-}
-
-void LocalPlayer::attributeChanged(const AttributesT id,
- const int64_t oldVal,
- const int64_t newVal)
-{
- PRAGMA45(GCC diagnostic push)
- PRAGMA45(GCC diagnostic ignored "-Wswitch-enum")
- switch (id)
- {
- case Attributes::PLAYER_EXP:
- {
- if (Net::getNetworkType() != ServerType::TMWATHENA)
- break;
- if (oldVal > newVal)
- break;
-
- const int change = CAST_S32(newVal - oldVal);
- addXpMessage(change);
- break;
- }
- case Attributes::PLAYER_BASE_LEVEL:
- mLevel = CAST_S32(newVal);
- break;
- case Attributes::PLAYER_HP:
- if (oldVal != 0 && newVal == 0)
- PlayerDeathListener::distributeEvent();
- break;
- case Attributes::PLAYER_JOB_EXP:
- {
- if (!mShowJobExp ||
- Net::getNetworkType() != ServerType::TMWATHENA)
- {
- return;
- }
- if (oldVal > newVal ||
- PlayerInfo::getAttribute(
- Attributes::PLAYER_JOB_EXP_NEEDED) == 0)
- {
- return;
- }
- const int32_t change = CAST_S32(newVal - oldVal);
- addJobMessage(change);
- break;
- }
- default:
- break;
- }
- PRAGMA45(GCC diagnostic pop)
-}
-
-void LocalPlayer::move(const int dX, const int dY)
-{
- mPickUpTarget = nullptr;
- setDestination(mX + dX, mY + dY);
-}
-
-void LocalPlayer::moveToTarget(int dist)
-{
- bool gotPos(false);
- Path debugPath;
-
- size_t limit(0);
-
- if (dist == -1)
- {
- dist = settings.moveToTargetType;
- if (dist != 0)
- {
- const bool broken = (Net::getNetworkType() ==
- ServerType::TMWATHENA);
- switch (dist)
- {
- case 10:
- dist = mAttackRange;
- if (dist == 1 && broken)
- dist = 2;
- break;
- case 11:
- dist = mAttackRange - 1;
- if (dist < 1)
- dist = 1;
- if (dist == 1 && broken)
- dist = 2;
- break;
- default:
- break;
- }
- }
- }
-
- if (mTarget != nullptr)
- {
- if (mMap != nullptr)
- {
- debugPath = mMap->findPath(
- (mPixelX - mapTileSize / 2) / mapTileSize,
- (mPixelY - mapTileSize) / mapTileSize,
- mTarget->mX,
- mTarget->mY,
- getBlockWalkMask(),
- 0);
- }
-
- const size_t sz = debugPath.size();
- if (sz < CAST_SIZE(dist))
- return;
- limit = CAST_S32(sz) - dist;
- gotPos = true;
- }
- else if ((mNavigateX != 0) || (mNavigateY != 0))
- {
- debugPath = mNavigatePath;
- limit = dist;
- gotPos = true;
- }
-
- if (gotPos)
- {
- if (dist == 0)
- {
- if (mTarget != nullptr)
- navigateTo(mTarget->mX, mTarget->mY);
- }
- else
- {
- Position pos(0, 0);
- size_t f = 0;
-
- for (Path::const_iterator i = debugPath.begin(),
- i_fend = debugPath.end();
- i != i_fend && f < limit; ++i, f++)
- {
- pos = (*i);
- }
- navigateTo(pos.x, pos.y);
- }
- }
- else if ((mLastTargetX != 0) || (mLastTargetY != 0))
- {
- navigateTo(mLastTargetX, mLastTargetY);
- }
-}
-
-void LocalPlayer::moveToHome()
-{
- mPickUpTarget = nullptr;
- if ((mX != mCrossX || mY != mCrossY) && (mCrossX != 0) && (mCrossY != 0))
- {
- setDestination(mCrossX, mCrossY);
- }
- else if (mMap != nullptr)
- {
- 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)
- {
- playerHandler->setDestination(
- CAST_S32(pos.x),
- CAST_S32(pos.y),
- CAST_S32(mDirection));
- }
- else
- {
- navigateTo(CAST_S32(pos.x), CAST_S32(pos.y));
- }
- }
- }
-}
-
-void LocalPlayer::changeEquipmentBeforeAttack(const Being *const target) const
-{
- if (settings.attackWeaponType == 1
- || (target == nullptr)
- || (PlayerInfo::getInventory() == nullptr))
- {
- return;
- }
-
- bool allowSword = false;
- const int dx = target->mX - mX;
- const int dy = target->mY - 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 == nullptr)
- return;
-
- // if attack distance for sword
- if (allowSword)
- {
- // searching swords
- const WeaponsInfos &swords = WeaponsDB::getSwords();
- FOR_EACH (WeaponsInfosIter, it, swords)
- {
- item = inv->findItem(*it, ItemColor_zero);
- if (item != nullptr)
- break;
- }
-
- // no swords
- if (item == nullptr)
- return;
-
- // if sword not equiped
- if (item->isEquipped() == Equipped_false)
- PlayerInfo::equipItem(item, Sfx_true);
-
- // if need equip shield too
- if (settings.attackWeaponType == 3)
- {
- // searching shield
- const WeaponsInfos &shields = WeaponsDB::getShields();
- FOR_EACH (WeaponsInfosIter, it, shields)
- {
- item = inv->findItem(*it, ItemColor_zero);
- if (item != nullptr)
- break;
- }
- if ((item != nullptr) && item->isEquipped() == Equipped_false)
- PlayerInfo::equipItem(item, Sfx_true);
- }
- }
- // big distance. allowed only bow
- else
- {
- // searching bow
- const WeaponsInfos &bows = WeaponsDB::getBows();
- FOR_EACH (WeaponsInfosIter, it, bows)
- {
- item = inv->findItem(*it, ItemColor_zero);
- if (item != nullptr)
- break;
- }
-
- // no bow
- if (item == nullptr)
- return;
-
- if (item->isEquipped() == Equipped_false)
- PlayerInfo::equipItem(item, Sfx_true);
- }
-}
-
-bool LocalPlayer::isReachable(Being *const being,
- const int maxCost)
-{
- if ((being == nullptr) || (mMap == nullptr))
- return false;
-
- if (being->getReachable() == Reachable::REACH_NO)
- return false;
-
- if (being->mX == mX &&
- being->mY == mY)
- {
- being->setDistance(0);
- being->setReachable(Reachable::REACH_YES);
- return true;
- }
- else if (being->mX - 1 <= mX &&
- being->mX + 1 >= mX &&
- being->mY - 1 <= mY &&
- being->mY + 1 >= mY)
- {
- being->setDistance(1);
- being->setReachable(Reachable::REACH_YES);
- return true;
- }
-
- const Path debugPath = mMap->findPath(
- (mPixelX - mapTileSize / 2) / mapTileSize,
- (mPixelY - mapTileSize) / mapTileSize,
- being->mX,
- being->mY,
- getBlockWalkMask(),
- maxCost);
-
- being->setDistance(CAST_S32(debugPath.size()));
- if (!debugPath.empty())
- {
- being->setReachable(Reachable::REACH_YES);
- return true;
- }
- being->setReachable(Reachable::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 == nullptr)
- 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 (actorManager == nullptr)
- return false;
-
- bool status = false;
- int x = mX;
- int y = mY;
-
- // first pick up item on player position
- FloorItem *item =
- actorManager->findItem(x, y);
- if (item != nullptr)
- status = pickUp(item);
-
- if (pickUpType == 0)
- pickUpType = settings.pickUpType;
-
- if (pickUpType == 0)
- return status;
-
- int x1, y1, x2, y2;
- switch (pickUpType)
- {
- case 1:
- switch (mDirection)
- {
- case BeingDirection::UP : --y; break;
- case BeingDirection::DOWN : ++y; break;
- case BeingDirection::LEFT : --x; break;
- case BeingDirection::RIGHT: ++x; break;
- default: break;
- }
- item = actorManager->findItem(x, y);
- if (item != nullptr)
- status = pickUp(item);
- break;
- case 2:
- switch (mDirection)
- {
- case BeingDirection::UP:
- x1 = x - 1; y1 = y - 1; x2 = x + 1; y2 = y; break;
- case BeingDirection::DOWN:
- x1 = x - 1; y1 = y; x2 = x + 1; y2 = y + 1; break;
- case BeingDirection::LEFT:
- x1 = x - 1; y1 = y - 1; x2 = x; y2 = y + 1; break;
- case BeingDirection::RIGHT:
- x1 = x; y1 = y - 1; x2 = x + 1; y2 = y + 1; break;
- default:
- x1 = x; x2 = x; y1 = y; y2 = y; break;
- }
- if (actorManager->pickUpAll(x1, y1, x2, y2))
- status = true;
- break;
- case 3:
- if (actorManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
- status = true;
- break;
-
- case 4:
- if (!actorManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
- {
- if (actorManager->pickUpNearest(x, y, 4))
- status = true;
- }
- else
- {
- status = true;
- }
- break;
-
- case 5:
- if (!actorManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
- {
- if (actorManager->pickUpNearest(x, y, 8))
- status = true;
- }
- else
- {
- status = true;
- }
- break;
-
- case 6:
- if (!actorManager->pickUpAll(x - 1, y - 1, x + 1, y + 1))
- {
- if (actorManager->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;
- if ((dir & BeingDirection::UP) != 0)
- dy--;
- if ((dir & BeingDirection::DOWN) != 0)
- dy++;
- if ((dir & BeingDirection::LEFT) != 0)
- dx--;
- if ((dir & BeingDirection::RIGHT) != 0)
- dx++;
- move(dx, dy);
-}
-
-void LocalPlayer::specialMove(const unsigned char direction)
-{
- if ((direction != 0u) && ((mNavigateX != 0) || (mNavigateY != 0)))
- navigateClean();
-
- if ((direction != 0u) && (settings.moveType >= 2
- && settings.moveType <= 4))
- {
- if (mAction == BeingAction::MOVE)
- return;
-
- unsigned int max;
-
- if (settings.moveType == 2)
- max = 5;
- else if (settings.moveType == 4)
- max = 1;
- else
- max = 3;
-
- if (getMoveState() < max)
- {
- moveByDirection(direction);
- mMoveState ++;
- }
- else
- {
- mMoveState = 0;
- crazyMoves->crazyMove();
- }
- }
- else
- {
- setWalkingDir(direction);
- }
-}
-
-#ifdef TMWA_SUPPORT
-void LocalPlayer::magicAttack() const
-{
- if (Net::getNetworkType() != ServerType::TMWATHENA)
- return;
- if (chatWindow == nullptr ||
- !isAlive() ||
- !playerHandler->canUseMagic())
- {
- return;
- }
-
- switch (settings.magicAttackType)
- {
- // 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 == nullptr)
- return;
-
- if (PlayerInfo::getSkillLevel(340) >= baseMagic
- && PlayerInfo::getSkillLevel(342) >= schoolMagic)
- {
- if (PlayerInfo::getAttribute(Attributes::PLAYER_MP) >= mana)
- {
- if (!PacketLimiter::limitPackets(PacketType::PACKET_CHAT))
- return;
-
- chatWindow->localChatInput(spell);
- }
- }
-}
-#endif // TMWA_SUPPORT
-
-void LocalPlayer::loadHomes()
-{
- std::string buf;
- std::stringstream ss(serverConfig.getValue("playerHomes", ""));
-
- while (ss >> buf)
- {
- Vector pos;
- ss >> pos.x;
- ss >> pos.y;
- mHomes[buf] = pos;
- }
-}
-
-void LocalPlayer::setMap(Map *const map)
-{
- BLOCK_START("LocalPlayer::setMap")
- if (map != nullptr)
- {
- if (socialWindow != nullptr)
- socialWindow->updateActiveList();
- }
- navigateClean();
- mCrossX = 0;
- mCrossY = 0;
-
- Being::setMap(map);
- updateNavigateList();
- BLOCK_END("LocalPlayer::setMap")
-}
-
-void LocalPlayer::setHome()
-{
- if ((mMap == nullptr) || (socialWindow == nullptr))
- return;
-
- SpecialLayer *const specialLayer = mMap->getSpecialLayer();
-
- if (specialLayer == nullptr)
- return;
-
- const std::string key = mMap->getProperty("_realfilename");
- Vector pos = mHomes[key];
-
- if (mAction == BeingAction::SIT)
- {
- const std::map<std::string, Vector>::const_iterator
- iter = mHomes.find(key);
-
- if (iter != mHomes.end())
- {
- socialWindow->removePortal(CAST_S32(pos.x),
- CAST_S32(pos.y));
- }
-
- if (iter != mHomes.end() && mX == CAST_S32(pos.x)
- && mY == CAST_S32(pos.y))
- {
- mMap->updatePortalTile("", MapItemType::EMPTY,
- CAST_S32(pos.x), CAST_S32(pos.y));
-
- mHomes.erase(key);
- socialWindow->removePortal(CAST_S32(pos.x),
- CAST_S32(pos.y));
- }
- else
- {
- if (iter != mHomes.end())
- {
- specialLayer->setTile(CAST_S32(pos.x),
- CAST_S32(pos.y), MapItemType::EMPTY);
- specialLayer->updateCache();
- }
-
- pos.x = static_cast<float>(mX);
- pos.y = static_cast<float>(mY);
- mHomes[key] = pos;
- mMap->updatePortalTile("home", MapItemType::HOME,
- mX, mY);
- socialWindow->addPortal(mX, mY);
- }
- MapItem *const mapItem = specialLayer->getTile(mX, mY);
- if (mapItem != nullptr)
- {
- const int idx = socialWindow->getPortalIndex(mX, mY);
- mapItem->setName(KeyboardConfig::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 == nullptr) || mapItem->getType() == MapItemType::EMPTY)
- {
- if ((mDirection & BeingDirection::UP) != 0)
- type = MapItemType::ARROW_UP;
- else if ((mDirection & BeingDirection::LEFT) != 0)
- type = MapItemType::ARROW_LEFT;
- else if ((mDirection & BeingDirection::DOWN) != 0)
- type = MapItemType::ARROW_DOWN;
- else if ((mDirection & BeingDirection::RIGHT) != 0)
- type = MapItemType::ARROW_RIGHT;
- }
- else
- {
- type = MapItemType::EMPTY;
- }
- mMap->updatePortalTile("", type, mX, mY);
-
- if (type != MapItemType::EMPTY)
- {
- socialWindow->addPortal(mX, mY);
- mapItem = specialLayer->getTile(mX, mY);
- if (mapItem != nullptr)
- {
- const int idx = socialWindow->getPortalIndex(mX, mY);
- mapItem->setName(KeyboardConfig::getKeyShortString(
- OutfitWindow::keyName(idx)));
- }
- }
- else
- {
- specialLayer->setTile(mX, mY, MapItemType::EMPTY);
- specialLayer->updateCache();
- socialWindow->removePortal(mX, mY);
- }
- }
-}
-
-void LocalPlayer::saveHomes()
-{
- std::stringstream ss;
-
- for (std::map<std::string, Vector>::const_iterator iter = mHomes.begin(),
- iter_fend = mHomes.end();
- iter != iter_fend;
- ++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;
- beingHandler->requestNameById(getId());
-}
-
-std::string LocalPlayer::getPingTime() const
-{
- std::string str;
- if (!mWaitPing)
- {
- if (mPingTime == 0)
- str = "?";
- else
- str = toString(CAST_S32(mPingTime));
- }
- else
- {
- time_t 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)", CAST_S32(mPingTime), CAST_S32(time));
- else
- str = toString(CAST_S32(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) const
-{
- setAfkMessage(message);
- GameModifiers::changeAwayMode(true);
- updateStatus();
-}
-
-void LocalPlayer::setAfkMessage(std::string message)
-{
- if (!message.empty())
- {
- if (message.size() > 4 && message.substr(0, 4) == "/me ")
- {
- message = message.substr(4);
- config.setValue("afkFormat", 1);
- }
- else
- {
- config.setValue("afkFormat", 0);
- }
- serverConfig.setValue("afkMessage", message);
- }
-}
-
-void LocalPlayer::setPseudoAway(const std::string &message)
-{
- setAfkMessage(message);
- settings.pseudoAwayMode = !settings.pseudoAwayMode;
-}
-
-void LocalPlayer::afkRespond(ChatTab *const tab, const std::string &nick)
-{
- if (settings.awayMode)
- {
- const time_t time = cur_time;
- if (mAfkTime == 0 || time < mAfkTime
- || time - mAfkTime > awayLimitTimer)
- {
- std::string str(serverConfig.getValue("afkMessage",
- "I am away from keyboard."));
- if (str.find("'NAME'") != std::string::npos)
- replaceAll(str, "'NAME'", nick);
-
- std::string msg("*AFK*: " + str);
-
- if (config.getIntValue("afkFormat") == 1)
- msg = "*" + msg + "*";
-
- if (tab == nullptr)
- {
- chatHandler->privateMessage(nick, msg);
- if (localChatTab != nullptr)
- {
- localChatTab->chatLog(std::string(mName).append(
- " : ").append(msg),
- ChatMsgType::ACT_WHISPER,
- IgnoreRecord_false);
- }
- }
- else
- {
- if (tab->getNoAway())
- return;
- chatHandler->privateMessage(nick, msg);
- tab->chatLog(mName, msg);
- }
- mAfkTime = time;
- }
- }
-}
-
-bool LocalPlayer::navigateTo(const int x, const int y)
-{
- if (mMap == nullptr)
- return false;
-
- SpecialLayer *const tmpLayer = mMap->getTempLayer();
- if (tmpLayer == nullptr)
- return false;
-
- mShowNavigePath = true;
- mOldX = mPixelX;
- mOldY = mPixelY;
- mOldTileX = mX;
- mOldTileY = mY;
- mNavigateX = x;
- mNavigateY = y;
- mNavigateId = BeingId_zero;
-
- mNavigatePath = mMap->findPath(
- (mPixelX - mapTileSize / 2) / mapTileSize,
- (mPixelY - mapTileSize) / mapTileSize,
- x,
- y,
- getBlockWalkMask(),
- 0);
-
- if (mDrawPath)
- tmpLayer->addRoad(mNavigatePath);
- return !mNavigatePath.empty();
-}
-
-void LocalPlayer::navigateClean()
-{
- if (mMap == nullptr)
- return;
-
- mShowNavigePath = false;
- mOldX = 0;
- mOldY = 0;
- mOldTileX = 0;
- mOldTileY = 0;
- mNavigateX = 0;
- mNavigateY = 0;
- mNavigateId = BeingId_zero;
-
- mNavigatePath.clear();
-
- SpecialLayer *const tmpLayer = mMap->getTempLayer();
- if (tmpLayer == nullptr)
- return;
-
- tmpLayer->clean();
-}
-
-void LocalPlayer::updateMusic() const
-{
- if (mMap != nullptr)
- {
- std::string str = mMap->getObjectData(mX, mY, MapItemType::MUSIC);
- if (str.empty())
- str = mMap->getMusicFile();
- if (str != soundManager.getCurrentMusicFile())
- {
- if (str.empty())
- soundManager.fadeOutMusic();
- else
- soundManager.fadeOutAndPlayMusic(str);
- }
- }
-}
-
-void LocalPlayer::updateCoords()
-{
- Being::updateCoords();
-
- // probably map not loaded.
- if ((mPixelX == 0) || (mPixelY == 0))
- return;
-
- if (mX != mOldTileX || mY != mOldTileY)
- {
- if (socialWindow != nullptr)
- socialWindow->updatePortals();
- PopupManager::hideBeingPopup();
- updateMusic();
- }
-
- if ((mMap != nullptr) && (mX != mOldTileX || mY != mOldTileY))
- {
- SpecialLayer *const tmpLayer = mMap->getTempLayer();
- if (tmpLayer == nullptr)
- return;
-
- const int x = (mPixelX - mapTileSize / 2) / mapTileSize;
- const int y = (mPixelY - mapTileSize) / mapTileSize;
- if (mNavigateId != BeingId_zero)
- {
- if (actorManager == nullptr)
- {
- navigateClean();
- return;
- }
-
- const Being *const being = actorManager
- ->findBeing(mNavigateId);
- if (being == nullptr)
- {
- navigateClean();
- return;
- }
- mNavigateX = being->mX;
- mNavigateY = being->mY;
- }
-
- if (mNavigateX == x && mNavigateY == y)
- {
- navigateClean();
- return;
- }
- for (Path::const_iterator i = mNavigatePath.begin(),
- i_fend = mNavigatePath.end();
- i != i_fend;
- ++i)
- {
- if ((*i).x == mX && (*i).y == mY)
- {
- mNavigatePath.pop_front();
- fixPos();
- break;
- }
- }
- if (mDrawPath && mShowNavigePath)
- {
- tmpLayer->clean();
- tmpLayer->addRoad(mNavigatePath);
- }
- }
- mOldX = mPixelX;
- mOldY = mPixelY;
- mOldTileX = mX;
- mOldTileY = mY;
-}
-
-void LocalPlayer::targetMoved() const
-{
-/*
- if (mKeepAttacking)
- {
- if (mTarget && mServerAttack == Keep_true)
- {
- logger->log("LocalPlayer::targetMoved0");
- if (!PacketLimiter::limitPackets(PacketType::PACKET_ATTACK))
- return;
- logger->log("LocalPlayer::targetMoved");
- playerHandler->attack(mTarget->getId(), mServerAttack);
- }
- }
-*/
-}
-
-int LocalPlayer::getPathLength(const Being *const being) const
-{
- if ((mMap == nullptr) || (being == nullptr))
- return 0;
-
- 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(
- (mPixelX - mapTileSize / 2) / mapTileSize,
- (mPixelY - mapTileSize) / mapTileSize,
- being->mX,
- being->mY,
- getBlockWalkMask(),
- 0);
- return CAST_S32(debugPath.size());
- }
-
- const int dx = CAST_S32(abs(being->mX - mX));
- const int dy = CAST_S32(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 != nullptr))
- changeEquipmentBeforeAttack(target);
-
- const bool broken = (Net::getNetworkType() == ServerType::TMWATHENA);
-
- // probably need cache getPathLength(target)
- if ((target == nullptr ||
- settings.attackType == 0 ||
- settings.attackType == 3) ||
- (withinAttackRange(target, broken, broken ? 1 : 0) &&
- getPathLength(target) <= getAttackRange2()))
- {
- attack(target, keep);
- if (settings.attackType == 2)
- {
- if (target == nullptr)
- {
- if (pickUpItems())
- return;
- }
- else
- {
- pickUpItems(3);
- }
- }
- }
- else if (mPickUpTarget == nullptr)
- {
- if (settings.attackType == 2)
- {
- if (pickUpItems())
- return;
- }
- setTarget(target);
- if (target->getType() != ActorType::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 == nullptr)
- return;
-
- std::string player_imitated = getImitate();
- if (!player_imitated.empty() && being->mName == player_imitated)
- emote(action);
-}
-
-void LocalPlayer::imitateAction(const Being *const being,
- const BeingActionT &action)
-{
- if (being == nullptr)
- return;
-
- if (!mPlayerImitated.empty() && being->mName == mPlayerImitated)
- {
- setAction(action, 0);
- playerHandler->changeAction(action);
- }
-}
-
-void LocalPlayer::imitateDirection(const Being *const being,
- const unsigned char dir)
-{
- if (being == nullptr)
- return;
-
- if (!mPlayerImitated.empty() && being->mName == mPlayerImitated)
- {
- if (!PacketLimiter::limitPackets(PacketType::PACKET_DIRECTION))
- return;
-
- if (settings.followMode == 2)
- {
- uint8_t dir2 = 0;
- if ((dir & BeingDirection::LEFT) != 0)
- dir2 |= BeingDirection::RIGHT;
- else if ((dir & BeingDirection::RIGHT) != 0)
- dir2 |= BeingDirection::LEFT;
- if ((dir & BeingDirection::UP) != 0)
- dir2 |= BeingDirection::DOWN;
- else if ((dir & BeingDirection::DOWN) != 0)
- dir2 |= BeingDirection::UP;
-
- setDirection(dir2);
- playerHandler->setDirection(dir2);
- }
- else
- {
- setDirection(dir);
- playerHandler->setDirection(dir);
- }
- }
-}
-
-void LocalPlayer::imitateOutfit(const Being *const player,
- const int sprite) const
-{
- if (player == nullptr)
- return;
-
- if (settings.imitationMode == 1 &&
- !mPlayerImitated.empty() &&
- player->mName == mPlayerImitated)
- {
- if (sprite < 0 || sprite >= player->getNumberOfLayers())
- return;
-
- const AnimatedSprite *const equipmentSprite
- = dynamic_cast<const AnimatedSprite *>(
- player->mSprites[sprite]);
-
- if (equipmentSprite != nullptr)
- {
-// logger->log("have equipmentSprite");
- const Inventory *const inv = PlayerInfo::getInventory();
- if (inv == nullptr)
- 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 != nullptr) && item->isEquipped() == Equipped_false)
- PlayerInfo::equipItem(item, Sfx_false);
- }
- else
- {
-// logger->log("have unequip %d", sprite);
- const int equipmentSlot = inventoryHandler
- ->convertFromServerSlot(sprite);
-// logger->log("equipmentSlot: " + toString(equipmentSlot));
- if (equipmentSlot == inventoryHandler->getProjectileSlot())
- return;
-
- const Item *const item = PlayerInfo::getEquipment(equipmentSlot);
- if (item != nullptr)
- {
-// logger->log("unequiping");
- PlayerInfo::unequipItem(item, Sfx_false);
- }
- }
- }
-}
-
-void LocalPlayer::followMoveTo(const Being *const being,
- const int x, const int y)
-{
- if ((being != nullptr) &&
- !mPlayerFollowed.empty() &&
- being->mName == mPlayerFollowed)
- {
- mPickUpTarget = nullptr;
- navigateTo(x, y);
- }
-}
-
-void LocalPlayer::followMoveTo(const Being *const being,
- const int x1, const int y1,
- const int x2, const int y2)
-{
- if (being == nullptr)
- return;
-
- mPickUpTarget = nullptr;
- if (!mPlayerFollowed.empty() &&
- being->mName == mPlayerFollowed)
- {
- switch (settings.followMode)
- {
- case 0:
- navigateTo(x1, y1);
- setNextDest(x2, y2);
- break;
- case 1:
- if (x1 != x2 || y1 != y2)
- {
- navigateTo(mX + x2 - x1, mY + y2 - y1);
- setNextDest(mX + x2 - x1, mY + y2 - y1);
- }
- break;
- case 2:
- if (x1 != x2 || y1 != y2)
- {
- navigateTo(mX + x1 - x2, mY + y1 - y2);
- setNextDest(mX + x1 - x2, mY + y1 - y2);
- }
- break;
- case 3:
- if (mTarget == nullptr ||
- mTarget->mName != mPlayerFollowed)
- {
- if (actorManager != nullptr)
- {
- Being *const b = actorManager->findBeingByName(
- mPlayerFollowed, ActorType::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;
-}
-
-void LocalPlayer::fixPos()
-{
- if ((mCrossX == 0) && (mCrossY == 0))
- return;
-
- const int dx = abs(mX - mCrossX);
- const int dy = abs(mY - mCrossY);
- const int dist = dx > dy ? dx : dy;
- const time_t time = cur_time;
- const int maxDist = mSyncPlayerMove ? mSyncPlayerMoveDistance : 7;
-
- if (dist > maxDist)
- {
- mActivityTime = time;
- setTileCoords(mCrossX, mCrossY);
-// alternative way to fix, move to real position
-// setDestination(mCrossX, mCrossY);
- }
-}
-
-void LocalPlayer::setRealPos(const int x, const int y)
-{
- if (mMap == nullptr)
- return;
-
- SpecialLayer *const layer = mMap->getTempLayer();
- if (layer != nullptr)
- {
- bool cacheUpdated(false);
- if (((mCrossX != 0) || (mCrossY != 0)) &&
- (layer->getTile(mCrossX, mCrossY) != nullptr) &&
- layer->getTile(mCrossX, mCrossY)->getType() == MapItemType::CROSS)
- {
- layer->setTile(mCrossX, mCrossY, MapItemType::EMPTY);
- layer->updateCache();
- cacheUpdated = true;
- }
-
- if (mShowServerPos)
- {
- const MapItem *const mapItem = layer->getTile(x, y);
-
- if (mapItem == nullptr ||
- mapItem->getType() == MapItemType::EMPTY)
- {
- if (mX != x && mY != y)
- {
- layer->setTile(x, y, MapItemType::CROSS);
- if (cacheUpdated == false)
- layer->updateCache();
- }
- }
- }
-
- if (mCrossX != x || mCrossY != y)
- {
- mCrossX = x;
- mCrossY = y;
- }
- }
- if (mMap->isCustom())
- mMap->setWalk(x, y);
-}
-void LocalPlayer::fixAttackTarget()
-{
- if ((mMap == nullptr) || (mTarget == nullptr))
- return;
-
- if (settings.moveToTargetType == 11 || (settings.attackType == 0u)
- || !config.getBoolValue("autofixPos"))
- {
- return;
- }
-
- const Path debugPath = mMap->findPath(
- (mPixelX - mapTileSize / 2) / mapTileSize,
- (mPixelY - mapTileSize) / mapTileSize,
- mTarget->mX,
- mTarget->mY,
- getBlockWalkMask(),
- 0);
-
- if (!debugPath.empty())
- {
- const Path::const_iterator i = debugPath.begin();
- setDestination((*i).x, (*i).y);
- }
-}
-
-void LocalPlayer::respawn()
-{
- navigateClean();
-}
-
-int LocalPlayer::getLevel() const
-{
- return PlayerInfo::getAttribute(Attributes::PLAYER_BASE_LEVEL);
-}
-
-void LocalPlayer::updateNavigateList()
-{
- if (mMap != nullptr)
- {
- 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 != 0.0f) && (pos.y != 0.0f))
- {
- mMap->addPortalTile("home", MapItemType::HOME,
- CAST_S32(pos.x), CAST_S32(pos.y));
- }
- }
- }
-}
-
-void LocalPlayer::failMove(const int x A_UNUSED,
- const int y A_UNUSED)
-{
-}
-
-void LocalPlayer::waitFor(const std::string &nick)
-{
- mWaitFor = nick;
-}
-
-void LocalPlayer::checkNewName(Being *const being)
-{
- if (being == nullptr)
- return;
-
- const std::string &nick = being->mName;
- if (being->getType() == ActorType::Player)
- {
- const Guild *const guild = getGuild();
- if (guild != nullptr)
- {
- const GuildMember *const gm = guild->getMember(nick);
- if (gm != nullptr)
- {
- const int level = gm->getLevel();
- if (level > 1 && being->getLevel() != level)
- {
- being->setLevel(level);
- being->updateName();
- }
- }
- }
- if (chatWindow != nullptr)
- {
- WhisperTab *const tab = chatWindow->getWhisperTab(nick);
- if (tab != nullptr)
- 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();
- }
-}
-
-unsigned char LocalPlayer::getBlockWalkMask() const
-{
- // for now blocking all types of collisions
- return BlockMask::WALL |
- BlockMask::AIR |
- BlockMask::WATER |
- BlockMask::PLAYERWALL;
-}
-
-void LocalPlayer::removeHome()
-{
- if (mMap == nullptr)
- 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)
-{
- if (target == nullptr)
- return false;
-
- switch (settings.pvpAttackType)
- {
- case 0:
- return true;
- case 1:
- return !(playerRelations.getRelation(target->mName)
- == Relation::FRIEND);
- case 2:
- return playerRelations.checkBadRelation(target->mName);
- default:
- case 3:
- return false;
- }
-}
-
-void LocalPlayer::updateStatus() const
-{
- if (serverFeatures->havePlayerStatusUpdate() && mEnableAdvert)
- {
- uint8_t status = 0;
- if (Net::getNetworkType() == ServerType::TMWATHENA)
- {
- if (mTradebot &&
- shopWindow != nullptr &&
- !shopWindow->isShopEmpty())
- {
- status |= BeingFlag::SHOP;
- }
- }
- if (settings.awayMode || settings.pseudoAwayMode)
- status |= BeingFlag::AWAY;
-
- if (mInactive)
- status |= BeingFlag::INACTIVE;
-
- playerHandler->updateStatus(status);
- }
-}
-
-void LocalPlayer::setTestParticle(const std::string &fileName,
- const bool updateHash)
-{
- mTestParticleName = fileName;
- mTestParticleTime = cur_time;
- if (mTestParticle != nullptr)
- {
- mChildParticleEffects.removeLocally(mTestParticle);
- mTestParticle = nullptr;
- }
- if (!fileName.empty())
- {
- mTestParticle = particleEngine->addEffect(fileName, 0, 0, 0);
- controlCustomParticle(mTestParticle);
- if (updateHash)
- mTestParticleHash = UpdaterWindow::getFileHash(mTestParticleName);
- }
-}
-
-void LocalPlayer::playerDeath()
-{
- if (mAction != BeingAction::DEAD)
- {
- setAction(BeingAction::DEAD, 0);
- recalcSpritesOrder();
- }
-}
-
-bool LocalPlayer::canMove() const
-{
- return !mFreezed &&
- mAction != BeingAction::DEAD &&
- (serverFeatures->haveMoveWhileSit() ||
- mAction != BeingAction::SIT);
-}
-
-void LocalPlayer::freezeMoving(const int timeWaitTicks)
-{
- if (timeWaitTicks <= 0)
- return;
- const int nextTime = tick_time + timeWaitTicks;
- if (mUnfreezeTime < nextTime)
- mUnfreezeTime = nextTime;
- if (mUnfreezeTime > 0)
- mFreezed = true;
-}