1 /* 2 * The ManaPlus Client 3 * Copyright (C) 2004-2009 The Mana World Development Team 4 * Copyright (C) 2009-2010 The Mana Developers 5 * Copyright (C) 2011-2019 The ManaPlus Developers 6 * Copyright (C) 2019-2021 Andrei Karas 7 * 8 * This file is part of The ManaPlus Client. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #ifndef BEING_LOCALPLAYER_H 25 #define BEING_LOCALPLAYER_H 26 27 #include "being/being.h" 28 29 #include "enums/being/pickup.h" 30 #include "enums/being/visiblename.h" 31 32 #include "enums/simpletypes/allowsort.h" 33 #include "enums/simpletypes/keep.h" 34 35 #include "listeners/actorspritelistener.h" 36 #include "listeners/attributelistener.h" 37 #include "listeners/playerdeathlistener.h" 38 39 #include "localconsts.h" 40 41 class AwayListener; 42 class ChatTab; 43 class FloorItem; 44 class Map; 45 class OkDialog; 46 47 /** 48 * The local player character. 49 */ 50 class LocalPlayer final : public Being, 51 public ActorSpriteListener, 52 public AttributeListener, 53 public PlayerDeathListener 54 { 55 public: 56 /** 57 * Constructor. 58 */ 59 LocalPlayer(const BeingId id, 60 const BeingTypeId subType); 61 62 A_DELETE_COPY(LocalPlayer) 63 64 /** 65 * Destructor. 66 */ 67 ~LocalPlayer() override final; 68 69 void logic() override final; 70 71 void slowLogic(); 72 73 void setAction(const BeingActionT &action, 74 const int attackId) override final; 75 76 /** 77 * Compute the next pathnode location when walking using keyboard. 78 * used by nextTile(). 79 */ 80 Position getNextWalkPosition(const unsigned char dir) 81 const A_WARN_UNUSED; 82 83 /** 84 * Adds a new tile to the path when walking. 85 * @note Eathena 86 * Also, when specified, it picks up an item at the end of a path 87 * or attack target. 88 */ 89 void nextTile() override final; 90 91 bool pickUp(FloorItem *const item); 92 93 /** 94 * Called when an ActorSprite has been destroyed. 95 * @param actorSprite the ActorSprite being destroyed. 96 */ 97 void actorSpriteDestroyed(const ActorSprite &actorSprite) 98 override final; 99 100 /** 101 * Gets the attack range. 102 */ 103 int getAttackRange() const A_WARN_UNUSED; 104 105 int getAttackRange2() const A_WARN_UNUSED; 106 107 void attack(Being *const target, 108 const bool keep, 109 const bool dontChangeEquipment); 110 111 void attack2(Being *const target, 112 const bool keep, 113 const bool dontChangeEquipment); 114 115 void setGroupId(const int id) override final; 116 117 void stopAttack(const bool keepAttack); 118 119 void untarget(); 120 121 /** 122 * Returns the current target of the player. Returns 0 if no being is 123 * currently targeted. 124 */ 125 Being *getTarget() const A_WARN_UNUSED; 126 127 /** 128 * Sets the target being of the player. 129 */ 130 void setTarget(Being *const target); 131 132 Being *setNewTarget(const ActorTypeT type, 133 const AllowSort allowSort); 134 135 /** 136 * Sets a new destination for this being to walk to. 137 */ 138 void setDestination(const int x, const int y); 139 140 /** 141 * Sets a new direction to keep walking in. 142 */ 143 void setWalkingDir(const unsigned char dir); 144 145 /** 146 * Gets the walking direction 147 */ getWalkingDir()148 unsigned char getWalkingDir() const noexcept2 A_WARN_UNUSED 149 { return mWalkingDir; } 150 151 /** 152 * Sets going to being to attack 153 */ 154 void setGotoTarget(Being *const target); 155 156 /** 157 * Returns whether the target is in range to attack 158 */ 159 bool withinAttackRange(const Being *const target, 160 const bool fixDistance, 161 const int addRange) const A_WARN_UNUSED; 162 163 /** 164 * Stops the player dead in his tracks 165 */ 166 void stopWalking(const bool sendToServer); 167 168 bool toggleSit() const; 169 170 bool updateSit() const; 171 172 static bool emote(const uint8_t emotion); 173 174 /** 175 * Shows item pickup notifications. 176 */ 177 void pickedUp(const ItemInfo &itemInfo, 178 const int amount, 179 const ItemColor color, 180 const BeingId floorItemId, 181 const PickupT fail); 182 183 int getLevel() const override final A_WARN_UNUSED; 184 185 /** Tells that the path has been set by mouse. */ pathSetByMouse()186 void pathSetByMouse() 187 { mPathSetByMouse = true; } 188 189 /** Tells if the path has been set by mouse. */ isPathSetByMouse()190 bool isPathSetByMouse() const noexcept2 A_WARN_UNUSED 191 { return mPathSetByMouse; } 192 getMoveState()193 unsigned int getMoveState() const noexcept2 A_WARN_UNUSED 194 { return mMoveState; } 195 setMoveState(const unsigned int n)196 void setMoveState(const unsigned int n) noexcept2 197 { mMoveState = n; } 198 199 std::string getPingTime() const A_WARN_UNUSED; 200 201 void tryPingRequest(); 202 203 #ifdef TMWA_SUPPORT 204 void magicAttack() const; 205 #endif // TMWA_SUPPORT 206 207 void specialMove(const unsigned char direction); 208 209 void moveByDirection(const unsigned char dir); 210 211 bool pickUpItems(int pickUpType); 212 213 void move(const int dX, const int dY); 214 215 void moveToTarget(int dist); 216 217 void moveToHome(); 218 219 bool isReachable(Being *const being, 220 const int maxCost) A_WARN_UNUSED; 221 222 bool isReachable(const int x, 223 const int y, 224 const bool allowCollision) const A_WARN_UNUSED; 225 226 void setHome(); 227 228 void pingRequest(); 229 230 void pingResponse(); 231 232 void setAway(const std::string &message) const; 233 234 static void setPseudoAway(const std::string &message); 235 setHalfAway(const bool n)236 void setHalfAway(const bool n) 237 { mInactive = n; } 238 getHalfAway()239 bool getHalfAway() const noexcept2 A_WARN_UNUSED 240 { return mInactive; } 241 242 void afkRespond(ChatTab *const tab, const std::string &nick); 243 244 static void setAfkMessage(std::string message); 245 246 bool navigateTo(const int x, const int y); 247 248 void navigateClean(); 249 250 void imitateEmote(const Being *const being, 251 const unsigned char action) const; 252 253 void imitateAction(const Being *const being, 254 const BeingActionT &action); 255 256 void imitateDirection(const Being *const being, 257 const unsigned char dir); 258 259 void imitateOutfit(const Being *const player, 260 const int sprite) const; 261 262 void followMoveTo(const Being *const being, 263 const int x, 264 const int y); 265 266 void followMoveTo(const Being *const being, 267 const int x1, 268 const int y1, 269 const int x2, 270 const int y2); 271 272 bool allowAction() A_WARN_UNUSED; 273 274 void setRealPos(const int x, const int y); 275 isServerBuggy()276 bool isServerBuggy() const noexcept2 A_WARN_UNUSED 277 { return mIsServerBuggy; } 278 279 void fixPos(); 280 281 void setTileCoords(const int x, 282 const int y) restrict2 override final; 283 284 /** 285 * Sets the map the being is on 286 */ 287 void setMap(Map *const map) override final; 288 289 void addMessageToQueue(const std::string &message, 290 const UserColorIdT color); 291 292 /** 293 * Called when a option (set with config.addListener()) is changed 294 */ 295 void optionChanged(const std::string &value) override final; 296 297 void playerDeath() override final; 298 299 /** 300 * set a following player. 301 */ 302 void setFollow(const std::string &player); 303 304 /** 305 * set an imitation player. 306 */ 307 void setImitate(const std::string &player); 308 309 /** 310 * setting the next destination of the following, in case of warp 311 */ 312 void setNextDest(const int x, const int y); 313 getNextDestX()314 int getNextDestX() const noexcept2 A_WARN_UNUSED 315 { return mNextDestX; } 316 getNextDestY()317 int getNextDestY() const noexcept2 A_WARN_UNUSED 318 { return mNextDestY; } 319 320 void respawn(); 321 getPickUpTarget()322 const FloorItem *getPickUpTarget() const noexcept2 A_WARN_UNUSED 323 { return mPickUpTarget; } 324 unSetPickUpTarget()325 void unSetPickUpTarget() 326 { mPickUpTarget = nullptr; } 327 328 /** 329 * Stop following a player. 330 */ 331 void cancelFollow(); 332 333 /** 334 * Get the playername followed by the current player. 335 */ getFollow()336 const std::string &getFollow() const noexcept2 A_WARN_UNUSED 337 { return mPlayerFollowed; } 338 339 /** 340 * Get the playername imitated by the current player. 341 */ getImitate()342 const std::string &getImitate() const noexcept2 A_WARN_UNUSED 343 { return mPlayerImitated; } 344 345 /** 346 * Tells the engine whether to check 347 * if the Player Name is to be displayed. 348 */ setCheckNameSetting(const bool checked)349 void setCheckNameSetting(const bool checked) 350 { mUpdateName = checked; } 351 352 /** 353 * Gets if the engine has to check 354 * if the Player Name is to be displayed. 355 */ getCheckNameSetting()356 bool getCheckNameSetting() const noexcept2 A_WARN_UNUSED 357 { return mUpdateName; } 358 359 void fixAttackTarget(); 360 361 void updateNavigateList(); 362 363 int getPathLength(const Being *const being) const A_WARN_UNUSED; 364 365 void targetMoved() const; 366 setLastHitFrom(const std::string & n)367 void setLastHitFrom(const std::string &n) 368 { mLastHitFrom = n; } 369 370 void waitFor(const std::string &nick); 371 372 void checkNewName(Being *const being); 373 374 unsigned char getBlockWalkMask() const override final 375 A_CONST A_WARN_UNUSED; 376 377 void saveHomes(); 378 379 void removeHome(); 380 381 void stopAdvert(); 382 383 void addXpMessage(const int64_t change); 384 385 void addHomunXpMessage(const int change); 386 387 void addJobMessage(const int64_t change); 388 389 void addHpMessage(const int change); 390 391 void addSpMessage(const int change); 392 393 static bool checAttackPermissions(const Being *const target) 394 A_WARN_UNUSED; 395 396 void updateStatus() const; 397 398 void setTestParticle(const std::string &fileName, 399 const bool updateHash); 400 getLastAttackX()401 int getLastAttackX() const override final 402 { return mTarget != nullptr ? mTarget->mX : mLastAttackX; } 403 getLastAttackY()404 int getLastAttackY() const override final 405 { return mTarget != nullptr ? mTarget->mY : mLastAttackY; } 406 407 void attributeChanged(const AttributesT id, 408 const int64_t oldVal, 409 const int64_t newVal) override final; 410 411 void updateMusic() const; 412 setAfkTime(const int v)413 void setAfkTime(const int v) noexcept2 414 { mAfkTime = v; } 415 setAwayDialog(OkDialog * const dialog)416 void setAwayDialog(OkDialog *const dialog) 417 { mAwayDialog = dialog; } 418 getAwayListener()419 AwayListener *getAwayListener() const noexcept2 A_WARN_UNUSED 420 { return mAwayListener; } 421 setRename(const bool r)422 void setRename(const bool r) noexcept2 423 { mAllowRename = r; } 424 getRename()425 bool getRename() const noexcept2 426 { return mAllowRename; } 427 428 bool canMove() const; 429 430 void freezeMoving(const int timeWaitTicks); 431 432 void failMove(const int x, 433 const int y); 434 435 protected: 436 void updateCoords() override final; 437 438 void handleStatusEffect(const StatusEffect *const effect, 439 const int32_t effectId, 440 const Enable newStatus, 441 const IsStart start) override final; 442 443 void startWalking(const unsigned char dir); 444 445 void changeEquipmentBeforeAttack(const Being *const target) const; 446 447 #ifdef TMWA_SUPPORT 448 static void tryMagic(const std::string &spell, 449 const int baseMagic, 450 const int schoolMagic, 451 const int mana); 452 #endif // TMWA_SUPPORT 453 454 void loadHomes(); 455 456 // move state. used if mMoveType == 2 457 unsigned int mMoveState; 458 459 int mLastTargetX; 460 int mLastTargetY; 461 462 std::map<std::string, Vector> mHomes; 463 464 Being *mTarget; 465 466 /** Follow system **/ 467 std::string mPlayerFollowed; 468 std::string mPlayerImitated; 469 int mNextDestX; 470 int mNextDestY; 471 472 FloorItem *mPickUpTarget; 473 474 int mLastAction; // Time stamp of the last action, -1 if none. 475 476 STD_VECTOR<int32_t> mStatusEffectIcons; 477 478 typedef std::pair<std::string, UserColorIdT> MessagePair; 479 /** Queued messages*/ 480 std::list<MessagePair> mMessages; 481 int mMessageTime; 482 AwayListener *mAwayListener; 483 OkDialog *mAwayDialog; 484 485 int mPingSendTick; 486 time_t mPingTime; 487 time_t mAfkTime; 488 time_t mActivityTime; 489 int mNavigateX; 490 int mNavigateY; 491 BeingId mNavigateId; 492 int mCrossX; 493 int mCrossY; 494 int mOldX; 495 int mOldY; 496 int mOldTileX; 497 int mOldTileY; 498 Path mNavigatePath; 499 500 std::string mLastHitFrom; 501 std::string mWaitFor; 502 time_t mAdvertTime; 503 Particle *mTestParticle; 504 std::string mTestParticleName; 505 time_t mTestParticleTime; 506 unsigned long mTestParticleHash; 507 int mSyncPlayerMoveDistance; 508 int mUnfreezeTime; 509 unsigned char mWalkingDir; // The direction the player is walking in. 510 /** Whether or not the name settings have changed */ 511 bool mUpdateName; 512 bool mBlockAdvert; 513 bool mTargetDeadPlayers; 514 Keep mServerAttack; 515 VisibleName::Type mVisibleNames; 516 bool mEnableAdvert; 517 bool mTradebot; 518 bool mTargetOnlyReachable; 519 bool mIsServerBuggy; 520 bool mSyncPlayerMove; 521 bool mDrawPath; 522 bool mAttackMoving; 523 bool mAttackNext; 524 bool mShowJobExp; 525 bool mShowServerPos; 526 bool mNextStep; 527 // temporary disable crazy moves in moves 528 bool mGoingToTarget; 529 // Whether or not to continue to attack 530 bool mKeepAttacking; 531 // Tells if the path was set using mouse 532 bool mPathSetByMouse; 533 bool mWaitPing; 534 bool mShowNavigePath; 535 bool mAllowRename; 536 bool mFreezed; 537 }; 538 539 extern LocalPlayer *localPlayer; 540 541 #endif // BEING_LOCALPLAYER_H 542