SabrehavenServer/src/monster.h
2019-09-16 20:38:16 +03:00

275 lines
7.8 KiB
C++

/**
* Tibia GIMUD Server - a free and open-source MMORPG server emulator
* Copyright (C) 2019 Sabrehaven and Mark Samman <mark.samman@gmail.com>
*
* 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
* (at your option) 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef FS_MONSTER_H_9F5EEFE64314418CA7DA41D1B9409DD0
#define FS_MONSTER_H_9F5EEFE64314418CA7DA41D1B9409DD0
#include "tile.h"
#include "monsters.h"
class Creature;
class Game;
class Spawn;
class Combat;
typedef std::unordered_set<Creature*> CreatureHashSet;
typedef std::list<Creature*> CreatureList;
enum TargetSearchType_t {
TARGETSEARCH_ANY,
TARGETSEARCH_RANDOM,
TARGETSEARCH_NEAREST,
TARGETSEARCH_WEAKEST,
TARGETSEARCH_MOSTDAMAGE,
};
class Monster final : public Creature
{
public:
static Monster* createMonster(const std::string& name);
static int32_t despawnRange;
static int32_t despawnRadius;
explicit Monster(MonsterType* mtype);
~Monster();
// non-copyable
Monster(const Monster&) = delete;
Monster& operator=(const Monster&) = delete;
Monster* getMonster() final {
return this;
}
const Monster* getMonster() const final {
return this;
}
void setID() final {
if (id == 0) {
id = monsterAutoID++;
}
}
void removeList() final;
void addList() final;
const std::string& getName() const final {
return mType->name;
}
const std::string& getNameDescription() const final {
return mType->nameDescription;
}
std::string getDescription(int32_t) const final {
return strDescription + '.';
}
const Position& getMasterPos() const {
return masterPos;
}
void setMasterPos(Position pos) {
masterPos = pos;
}
RaceType_t getRace() const final {
return mType->info.race;
}
int32_t getArmor() const final {
int32_t armor = mType->info.armor;
if (armor > 1) {
return rand() % (mType->info.armor >> 1) + (mType->info.armor >> 1);
}
return armor;
}
int32_t getDefense() final;
bool isPushable() const final {
return mType->info.pushable && baseSpeed != 0;
}
bool isAttackable() const final {
return mType->info.isAttackable;
}
bool canPushItems() const {
return mType->info.canPushItems;
}
bool canPushCreatures() const {
return mType->info.canPushCreatures;
}
bool isHostile() const {
return mType->info.isHostile;
}
bool canSee(const Position& pos) const final;
bool canSeeInvisibility() const final {
return isImmune(CONDITION_INVISIBLE);
}
uint32_t getManaCost() const {
return mType->info.manaCost;
}
void setSpawn(Spawn* spawn) {
this->spawn = spawn;
}
void onAttackedCreature(Creature* creature) final;
void onCreatureAppear(Creature* creature, bool isLogin) final;
void onRemoveCreature(Creature* creature, bool isLogout) final;
void onCreatureMove(Creature* creature, const Tile* newTile, const Position& newPos, const Tile* oldTile, const Position& oldPos, bool teleport) final;
void onCreatureSay(Creature* creature, SpeakClasses type, const std::string& text) final;
void drainHealth(Creature* attacker, int32_t damage) final;
void changeHealth(int32_t healthChange, bool sendHealthChange = true) final;
void onWalk() final;
bool getNextStep(Direction& direction, uint32_t& flags) final;
void onFollowCreatureComplete(const Creature* creature) final;
void onThink(uint32_t interval) final;
bool challengeCreature(Creature* creature) final;
bool convinceCreature(Creature* creature) final;
void setNormalCreatureLight() final;
bool getCombatValues(int32_t& min, int32_t& max) final;
void doAttacking(uint32_t interval) final;
bool searchTarget(TargetSearchType_t searchType);
bool selectTarget(Creature* creature);
const CreatureList& getTargetList() const {
return targetList;
}
const CreatureHashSet& getFriendList() const {
return friendList;
}
bool isTarget(const Creature* creature) const;
bool isFleeing() const {
return !isSummon() && getHealth() <= mType->info.runAwayHealth;
}
bool getDistanceStep(const Position& targetPos, Direction& direction, bool flee = false);
bool isTargetNearby() const {
return stepDuration >= 1;
}
BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
bool checkDefense = false, bool checkArmor = false, bool field = false);
static uint32_t monsterAutoID;
private:
CreatureHashSet friendList;
CreatureList targetList;
std::string strDescription;
MonsterType* mType;
Spawn* spawn = nullptr;
int64_t lifetime = 0;
int64_t nextDanceStepRound = 0;
int64_t earliestAttackTime = 0;
int64_t earliestWakeUpTime = 0;
int64_t earliestDanceTime = 0;
uint32_t targetChangeTicks = 0;
int32_t minCombatValue = 0;
int32_t maxCombatValue = 0;
int32_t targetChangeCooldown = 0;
int32_t stepDuration = 0;
Position masterPos;
bool isIdle = true;
bool isMasterInRange = false;
bool egibleToDance = true;
void onCreatureEnter(Creature* creature);
void onCreatureLeave(Creature* creature);
void onCreatureFound(Creature* creature, bool pushFront = false);
void updateLookDirection();
void addFriend(Creature* creature);
void removeFriend(Creature* creature);
void addTarget(Creature* creature, bool pushFront = false);
void removeTarget(Creature* creature);
void updateTargetList();
void clearTargetList();
void clearFriendList();
void death(Creature* lastHitCreature) final;
Item* getCorpse(Creature* lastHitCreature, Creature* mostDamageCreature) final;
void setIdle(bool idle);
void updateIdleStatus();
bool getIdleStatus() const {
return isIdle;
}
void onAddCondition(ConditionType_t type) final;
void onEndCondition(ConditionType_t type) final;
void onCreatureConvinced(const Creature* convincer, const Creature* creature) final;
bool canUseAttack(const Position& pos, const Creature* target) const;
bool getRandomStep(const Position& creaturePos, Direction& direction) const;
bool getDanceStep(const Position& creaturePos, Direction& direction,
bool keepAttack = true, bool keepDistance = true);
bool isInSpawnRange(const Position& pos) const;
bool canWalkTo(Position pos, Direction direction) const;
static bool pushItem(Item* item);
static void pushItems(Tile* tile);
static bool pushCreature(Creature* creature);
static void pushCreatures(Tile* tile);
void onThinkTarget(uint32_t interval);
void onThinkYell(uint32_t interval);
void onThinkDefense(uint32_t interval);
bool isFriend(const Creature* creature) const;
bool isOpponent(const Creature* creature) const;
uint64_t getLostExperience() const final {
return skillLoss ? mType->info.experience : 0;
}
uint16_t getLookCorpse() const final {
return mType->info.lookcorpse;
}
void dropLoot(Container* corpse, Creature* lastHitCreature) final;
uint32_t getDamageImmunities() const final {
return mType->info.damageImmunities;
}
uint32_t getConditionImmunities() const final {
return mType->info.conditionImmunities;
}
void getPathSearchParams(const Creature* creature, FindPathParams& fpp) const final;
bool useCacheMap() const final {
return true;
}
friend class LuaScriptInterface;
friend class AreaSpawnEvent;
friend class Combat;
friend class Creature;
};
#endif