/* * The Mana Server * Copyright (C) 2004-2010 The Mana World Development Team * * This file is part of The Mana Server. * * The Mana Server 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. * * The Mana Server 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 The Mana Server. If not, see . */ #ifndef MONSTER_H #define MONSTER_H #include "game-server/abilitymanager.h" #include "game-server/being.h" #include "common/defines.h" #include "scripting/script.h" #include "utils/string.h" #include #include #include #include #include class CharacterComponent; class ItemClass; class Script; /** * Structure containing an item class and its probability to be dropped * (unit: 1/10000). */ struct MonsterDrop { ItemClass *item; int probability; }; typedef std::vector< MonsterDrop > MonsterDrops; typedef std::map Vulnerabilities; /** * Class describing the characteristics of a generic monster. */ class MonsterClass { public: MonsterClass(int id): mId(id), mName("unnamed"), mGender(GENDER_UNSPECIFIED), mSpeed(1), mSize(16), mExp(-1), mMutation(0), mOptimalLevel(0) {} /** * Returns monster type. This is the Id of the monster class. */ int getId() const { return mId; } /** * Returns the name of the monster type */ const std::string &getName() const { return mName; } /** * Sets the name of the monster type */ void setName(const std::string &name) { mName = name; } void setGender(BeingGender gender) { mGender = gender; } BeingGender getGender() const { return mGender; } /** * Sets monster drops. These are the items the monster drops when it * dies. */ void setDrops(const MonsterDrops &v) { mDrops = v; } /** * Sets a being base attribute. */ void setAttribute(int attribute, double value) { mAttributes[attribute] = value; } /** * Returns a being base attribute. */ double getAttribute(int attribute) const { return mAttributes.at(attribute); } /** * Returns whether the monster has got the attribute. */ bool hasAttribute(int attribute) const { return (mAttributes.find(attribute) != mAttributes.end()); } const std::map &getAttributes() const { return mAttributes; } /** Sets collision circle radius. */ void setSize(int size) { mSize = size; } /** Returns collision circle radius. */ int getSize() const { return mSize; } /** Sets experience reward for killing the monster. */ void setExp(int exp) { mExp = exp; } /** Returns experience reward for killing the monster. */ int getExp() const { return mExp; } /** Gets maximum skill level after which exp reward is reduced */ void setOptimalLevel(int level) { mOptimalLevel = level; } /** Sets maximum skill level after which exp reward is reduced. */ int getOptimalLevel() const { return mOptimalLevel; } /** Sets mutation factor in percent. */ void setMutation(unsigned factor) { mMutation = factor; } /** Returns mutation factor in percent. */ unsigned getMutation() const { return mMutation; } void addAbility(AbilityManager::AbilityInfo *info); const std::set &getAbilities() const; void setUpdateCallback(Script *script) { script->assignCallback(mUpdateCallback); } Script::Ref getUpdateCallback() const { return mUpdateCallback; } private: unsigned short mId; std::string mName; BeingGender mGender; MonsterDrops mDrops; std::map mAttributes; /**< Base attributes of the monster. */ std::set mAbilities; float mSpeed; /**< The monster class speed in tiles per second */ int mSize; int mExp; int mMutation; int mOptimalLevel; /** * A reference to the script function that is called each update. */ Script::Ref mUpdateCallback; friend class MonsterManager; friend class MonsterComponent; }; /** * The component for a fightable monster with its own AI */ class MonsterComponent : public Component { public: static const ComponentType type = CT_Monster; MonsterComponent(Entity &entity, MonsterClass *); /** * Returns monster specy. */ MonsterClass *getSpecy() const { return mSpecy; } /** * Performs one step of controller logic. */ void update(Entity &entity); /** * Signal handler */ void monsterDied(Entity *monster); private: static const int DECAY_TIME = 50; MonsterClass *mSpecy; /** Time until dead monster is removed */ Timeout mDecayTimeout; }; inline void MonsterClass::addAbility(AbilityManager::AbilityInfo *info) { mAbilities.insert(info); } inline const std::set &MonsterClass::getAbilities() const { return mAbilities; } #endif // MONSTER_H