summaryrefslogtreecommitdiff
path: root/src/game-server/monster.hpp
blob: f5c7c18fbaae7c8fde18869c9fa0e8f37f239b63 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*
 *  The Mana World Server
 *  Copyright 2004 The Mana World Development Team
 *
 *  This file is part of The Mana World.
 *
 *  The Mana World  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  World 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  World; if not, write to the  Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 *  $Id$
 */

#ifndef _TMWSERV_MONSTER_H_
#define _TMWSERV_MONSTER_H_

#include <map>
#include <vector>

#include "game-server/being.hpp"
#include "game-server/eventlistener.hpp"

class ItemClass;
class MapComposite;

/**
 * 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;

/**
 * Class describing the characteristics of a generic monster.
 */
class MonsterClass
{
    public:
        MonsterClass(int id): mID(id), mAttributes(BASE_ATTR_NB, 0), mExp(-1) {}

        /**
         * Gets monster type.
         */
        int getType() const
        { return mID; }

        /**
         * Sets monster drops.
         */
        void setDrops(MonsterDrops const &v)
        { mDrops = v; }

        /**
         * Sets a being attribute
         */
        void setAttribute(size_t attribute, int value)
        { mAttributes.at(attribute) = value ; }

        /**
         * Gets a being attribute
         */
        int getAttribute(size_t attribute) const
        { return mAttributes.at(attribute); }

        /**
         * Sets exp reward for killing the monster
         */
        void setExp(int exp)
        { mExp = exp; }

        /**
         * Gets exp reward for killing the monster
         */
        int getExp() const
        { return mExp; }

        /**
         * Randomly selects a monster drop (may return NULL).
         * TODO: pass some luck modifier as an argument.
         */
        ItemClass *getRandomDrop() const;

    private:
        unsigned short mID; /**< ID of the monster class. */
        MonsterDrops mDrops; /**< Items the monster drops when dying. */
        std::vector<int> mAttributes; /**< Base attributes of the monster*/
        int mExp; /**< Exp reward for killing the monster */
};

/**
 * Structure holding possible positions relative to the target from which
 * the monster can attack
 */
struct AttackPosition
{
    AttackPosition(int posX, int posY, Direction dir):
        x(posX),
        y(posY),
        direction(dir)
    {};

    int x;
    int y;
    Direction direction;
};

/**
 * The class for a fightable monster with its own AI
 */
class Monster : public Being
{
    public:

        static const int KILLSTEAL_PROTECTION_TIME = 100; /**< Time in game ticks until ownership of a monster can change */

        /**
         * Constructor.
         */
        Monster(MonsterClass *);

        /**
         * Destructor.
         */
        ~Monster();

        /**
         * Gets monster specy.
         */
        MonsterClass *getSpecy()
        { return mSpecy; }

        /**
         * Performs one step of controller logic.
         */
        void update();

        /**
         * Performs an attack, if needed.
         */
        void perform();

        /**
         * Kills the being.
         */
        void died();

        /**
         * Calls the damage function in Being and updates the aggro list
         */
        virtual int damage(Object *source, Damage const &damage);

        /**
         * Removes a being from the anger list.
         */
        void forgetTarget(Thing *being);

    private:
        int calculatePositionPriority(Point position, int targetPriority);

        MonsterClass *mSpecy; /**< Monster specy. */
        int mCountDown; /**< Count down till next random movement (temporary). */
        std::map<Being *, int> mAnger;   /**< Aggression towards other beings */
        EventListener mTargetListener; /**< Listener for updating the anger list. */

        Character* mOwner; /**< Character who currently owns this monster (killsteal protection) */
        int mOwnerTimer; /**< Time until someone else can claim this monster (killsteal protection) */
        std::map<Character *, std::set <size_t> > mExpReceivers; /**< List of characters and their skills that attacked this monster*/
        std::set<Character *> mLegalExpReceivers; /**< List of characters who are entitled to receive exp (killsteal protection)*/

        int mAttackTime;                       /**< Delay until monster can attack */
        // TODO: the following vars should all be the same for all monsters of
        // the same type. So they should be stored in mSpecy to save memory
        int mAttackPreDelay;        /**< time between decision to make an attack and performing the attack */
        int mAttackAftDelay;        /**< time it takes to perform an attack */
        int mAttackRange;           /**< range of the monsters attacks in pixel */
        int mAttackAngle;           /**< angle of the monsters attacks in degree */
        bool mAgressive;            /**< Does the monster attack without being provoked? */
        unsigned mAgressionRange;   /**< Distance the monster tracks enemies in */
        std::list<AttackPosition> mAttackPositions; /**< set positions relative to target from which the monster can attack */

        friend struct MonsterTargetEventDispatch;
};

#endif // _TMWSERV_MONSTER_H_