1
/*
2
 *  The Mana World
3
 *  Copyright (C) 2004  The Mana World Development Team
4
 *
5
 *  This file is part of The Mana World.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
22
#ifndef BEING_H
23
#define BEING_H
24
25
#include <guichan/color.hpp>
26
27
#include <SDL_types.h>
28
29
#include <set>
30
#include <string>
31
#include <vector>
32
33
#include "configlistener.h"
34
#include "map.h"
35
#include "particlecontainer.h"
36
#include "position.h"
37
#include "sprite.h"
38
#include "vector.h"
39
40
#include "resources/spritedef.h"
41
42
#define FIRST_IGNORE_EMOTE 14
43
#define STATUS_EFFECTS 32
44
45
#define SPEECH_TIME 500
46
#define SPEECH_MAX_TIME 1000
47
48
class AnimatedSprite;
49
class FlashText;
50
class Graphics;
51
class Image;
52
class ItemInfo;
53
class Item;
54
class Particle;
55
class Position;
56
class SimpleAnimation;
57
class SpeechBubble;
58
class Text;
59
60
class StatusEffect;
61
62
class Being : public Sprite, public ConfigListener
63
{
64
    public:
65
        enum Type
66
        {
67
            UNKNOWN,
68
            PLAYER,
69
            NPC,
70
            MONSTER
71
        };
72
73
        /**
74
         * Action the being is currently performing
75
         * WARNING: Has to be in sync with the same enum in the Being class
76
         * of the server!
77
         */
78
        enum Action
79
        {
80
            STAND,
81
            WALK,
82
            ATTACK,
83
            SIT,
84
            DEAD,
85
            HURT
86
        };
87
88
        enum TargetCursorSize
89
        {
90
            TC_SMALL = 0,
91
            TC_MEDIUM,
92
            TC_LARGE,
93
            NUM_TC
94
        };
95
96
        enum Speech
97
        {
98
            NO_SPEECH = 0,
99
            TEXT_OVERHEAD,
100
            NO_NAME_IN_BUBBLE,
101
            NAME_IN_BUBBLE
102
        };
103
104
        enum AttackType
105
        {
106
            HIT = 0x00,
107
            CRITICAL = 0x0a,
108
            MULTI = 0x08,
109
            REFLECT = 0x04,
110
            FLEE = 0x0b
111
        };
112
113
        /**
114
         * Directions, to be used as bitmask values
115
         */
116
        enum { DOWN = 1, LEFT = 2, UP = 4, RIGHT = 8 };
117
118
#ifdef EATHENA_SUPPORT
119
        int mFrame;
120
        int mWalkTime;
121
#endif
122
        int mEmotion;         /**< Currently showing emotion */
123
        int mEmotionTime;     /**< Time until emotion disappears */
124
        int mSpeechTime;
125
126
        int mAttackSpeed;     /**< Attack speed */
127
        Action mAction;       /**< Action the being is performing */
128
        Uint16 mJob;          /**< Job (player job, npc, monster, creature ) */
129
130
        /**
131
         * Constructor.
132
         *
133
         * @param id   a unique being id
134
         * @param job  partly determines the type of the being
135
         * @param map  the map the being is on
136
         */
137
        Being(int id, int job, Map *map);
138
139
        virtual ~Being();
140
141
        /**
142
         * Removes all path nodes from this being.
143
         */
144
        void clearPath();
145
146
        /**
147
         * Sets a new destination for this being to walk to.
148
         */
149
#ifdef EATHENA_SUPPORT
150
        virtual void setDestination(Uint16 destX, Uint16 destY);
151
#else
152
        /**
153
         * Creates a path for the being from current position to ex and ey
154
         */
155
        void setDestination(int ex, int ey);
156
157
        /**
158
         * Returns the destination for this being.
159
         */
160
        const Vector &getDestination() const { return mDest; }
161
#endif
162
163
        /**
164
         * Returns the tile x or y coord
165
         */
166
        int getTileX() const
167
        { return mX; }
168
169
        int getTileY() const
170
        { return mY; }
171
172
        /**
173
         * Sets the tile x or y coord
174
         */
175
        void setTileCoords(int x, int y)
176
        { mX = x; mY = y; }
177
178
        /**
179
         * Puts a "speech balloon" above this being for the specified amount
180
         * of time.
181
         *
182
         * @param text The text that should appear.
183
         * @param time The amount of time the text should stay in milliseconds.
184
         */
185
        void setSpeech(const std::string &text, int time = 500);
186
187
        /**
188
         * Puts a damage bubble above this being.
189
         *
190
         * @param attacker the attacking being
191
         * @param damage the amount of damage recieved (0 means miss)
192
         * @param type the attack type
193
         */
194
        virtual void takeDamage(Being *attacker, int damage, AttackType type);
195
196
        /**
197
         * Handles an attack of another being by this being.
198
         *
199
         * @param victim the victim being
200
         * @param damage the amount of damage dealt (0 means miss)
201
         * @param type the attack type
202
         */
203
        virtual void handleAttack(Being *victim, int damage, AttackType type);
204
205
        /**
206
         * Returns the name of the being.
207
         */
208
        const std::string &getName() const
209
        { return mName; }
210
211
        /**
212
         * Sets the name for the being.
213
         *
214
         * @param name The name that should appear.
215
         */
216
        virtual void setName(const std::string &name);
217
218
        const bool getShowName() const
219
        { return mShowName; }
220
221
        virtual void setShowName(bool doShowName);
222
223
        /**
224
         * Get the number of hairstyles implemented
225
         */
226
        static int getNumOfHairstyles()
227
        { return mNumberOfHairstyles; }
228
229
        /**
230
         * Get the number of layers used to draw the being
231
         */
232
        int getNumberOfLayers() const;
233
234
#ifdef EATHENA_SUPPORT
235
        /**
236
         * Makes this being take the next step of his path.
237
         */
238
        virtual void nextStep();
239
#endif
240
241
        /**
242
         * Performs being logic.
243
         */
244
        virtual void logic();
245
246
        /**
247
         * Draws the speech text above the being.
248
         */
249
        void drawSpeech(int offsetX, int offsetY);
250
251
        /**
252
         * Draws the emotion picture above the being.
253
         */
254
        void drawEmotion(Graphics *graphics, int offsetX, int offsetY);
255
256
        /**
257
         * Returns the type of the being.
258
         */
259
        virtual Type getType() const { return UNKNOWN; }
260
261
        /**
262
         * Sets the walk speed.
263
         * in pixels per second for eAthena,
264
         * in tiles per second for TMWserv.
265
         */
266
        void setWalkSpeed(float speed) { mWalkSpeed = speed; }
267
268
        /**
269
         * Gets the walk speed.
270
         * in pixels per second for eAthena,
271
         * in tiles per second for TMWserv (0.1 precision).
272
         */
273
        float getWalkSpeed() const { return mWalkSpeed; }
274
275
        /**
276
         * Sets the sprite id.
277
         */
278
        void setId(int id) { mId = id; }
279
280
        int getId() const { return mId; }
281
282
        /**
283
         * Sets the map the being is on
284
         */
285
        void setMap(Map *map);
286
287
        /**
288
         * Sets the current action.
289
         */
290
        virtual void setAction(Action action, int attackType = 0);
291
292
        /**
293
         * Returns whether this being is still alive.
294
         */
295
        bool isAlive() const { return mAction != DEAD; }
296
297
        /**
298
         * Returns the current direction.
299
         */
300
        Uint8 getDirection() const { return mDirection; }
301
302
        /**
303
         * Sets the current direction.
304
         */
305
        void setDirection(Uint8 direction);
306
307
#ifdef EATHENA_SUPPORT
308
        /**
309
         * Returns the walk time.
310
         */
311
        int getWalkTime() const { return mWalkTime; }
312
#endif
313
314
        /**
315
         * Returns the direction the being is facing.
316
         */
317
        SpriteDirection getSpriteDirection() const
318
        { return SpriteDirection(mSpriteDirection); }
319
320
        /**
321
         * Draws this being to the given graphics context.
322
         *
323
         * @see Sprite::draw(Graphics, int, int)
324
         */
325
        virtual void draw(Graphics *graphics, int offsetX, int offsetY) const;
326
327
        /**
328
         * Set the alpha opacity used to draw the being.
329
         */
330
        virtual void setAlpha(float alpha)
331
        { mAlpha = alpha; }
332
333
        /**
334
         * Returns the current alpha opacity of the Being.
335
         */
336
        virtual float getAlpha() const
337
        { return mAlpha; }
338
339
        /**
340
         * Returns the X coordinate in pixels.
341
         */
342
        int getPixelX() const
343
        { return mPx; }
344
345
        /**
346
         * Returns the Y coordinate in pixels.
347
         *
348
         * @see Sprite::getPixelY()
349
         */
350
        int getPixelY() const
351
        { return mPy; }
352
353
#ifdef EATHENA_SUPPORT
354
        /**
355
         * Get the current X pixel offset.
356
         */
357
        int getXOffset() const
358
        { return getOffset(LEFT, RIGHT); }
359
360
        /**
361
         * Get the current Y pixel offset.
362
         */
363
        int getYOffset() const
364
        { return getOffset(UP, DOWN); }
365
#endif
366
367
        /**
368
         * Sets the position of this being.
369
         */
370
        void setPosition(const Vector &pos);
371
372
        /**
373
         * Overloaded method provided for convenience.
374
         *
375
         * @see setPosition(const Vector &pos)
376
         */
377
        void setPosition(float x, float y, float z = 0.0f)
378
        {
379
            setPosition(Vector(x, y, z));
380
        }
381
382
        /**
383
         * Returns the position of this being.
384
         */
385
        const Vector &getPosition() const { return mPos; }
386
387
        /**
388
         * Returns the horizontal size of the current base sprite of the being.
389
         */
390
        virtual int getWidth() const;
391
392
        /**
393
         * Returns the vertical size of the current base sprite of the being.
394
         */
395
        virtual int getHeight() const;
396
397
        /**
398
         * Returns the required size of a target cursor for this being.
399
         */
400
        virtual Being::TargetCursorSize getTargetCursorSize() const
401
        { return TC_MEDIUM; }
402
403
        /**
404
         * Take control of a particle.
405
         */
406
        void controlParticle(Particle *particle);
407
408
        /**
409
         * Gets the way the object is blocked by other objects.
410
         */
411
        virtual unsigned char getWalkMask() const
412
        { return 0x00; } //can walk through everything
413
414
        /**
415
         * Returns the path this being is following. An empty path is returned
416
         * when this being isn't following any path currently.
417
         */
418
        const Path &getPath() const { return mPath; }
419
420
        /**
421
         * Sets the target animation for this being.
422
         */
423
        void setTargetAnimation(SimpleAnimation* animation);
424
425
        /**
426
         * Untargets the being
427
         */
428
        void untarget() { mUsedTargetCursor = NULL; }
429
430
        void setEmote(Uint8 emotion, Uint8 emote_time)
431
        {
432
            mEmotion = emotion;
433
            mEmotionTime = emote_time;
434
        }
435
436
        /**
437
         * Sets the being's stun mode.  If zero, the being is `normal',
438
         * otherwise it is `stunned' in some fashion.
439
         */
440
        void setStunMode(int stunMode)
441
        {
442
            if (mStunMode != stunMode)
443
                updateStunMode(mStunMode, stunMode);
444
            mStunMode = stunMode;
445
        };
446
447
        void setStatusEffect(int index, bool active);
448
449
        /**
450
         * A status effect block is a 16 bit mask of status effects.
451
         * We assign each such flag a block ID of offset + bitnr.
452
         *
453
         * These are NOT the same as the status effect indices.
454
         */
455
        void setStatusEffectBlock(int offset, Uint16 flags);
456
457
        /**
458
         * Triggers a visual effect, such as `level up'
459
         *
460
         * Only draws the visual effect, does not play sound effects
461
         *
462
         * \param effectId ID of the effect to trigger
463
         */
464
        virtual void triggerEffect(int effectId)
465
        {
466
            internalTriggerEffect(effectId, false, true);
467
        }
468
469
        virtual AnimatedSprite *getSprite(int index) const
470
        { return mSprites[index]; }
471
472
        static void load();
473
474
        virtual void optionChanged(const std::string &value) {}
475
476
        void flashName(int time);
477
478
    protected:
479
        /**
480
         * Sets the new path for this being.
481
         */
482
        void setPath(const Path &path);
483
484
        /**
485
         * Updates name's location.
486
         */
487
        virtual void updateCoords();
488
489
        /**
490
         * Gets the way the object blocks pathfinding for other objects
491
         */
492
        virtual Map::BlockType getBlockType() const
493
        { return Map::BLOCKTYPE_NONE; }
494
495
        /**
496
         * Trigger visual effect, with components
497
         *
498
         * \param effectId ID of the effect to trigger
499
         * \param sfx Whether to trigger sound effects
500
         * \param gfx Whether to trigger graphical effects
501
         */
502
        void internalTriggerEffect(int effectId, bool sfx, bool gfx);
503
504
        /**
505
         * Notify self that the stun mode has been updated. Invoked by
506
         * setStunMode if something changed.
507
         */
508
        virtual void updateStunMode(int oldMode, int newMode);
509
510
        /**
511
         * Notify self that a status effect has flipped.
512
         * The new flag is passed.
513
         */
514
        virtual void updateStatusEffect(int index, bool newStatus);
515
516
        /**
517
         * Handle an update to a status or stun effect
518
         *
519
         * \param The StatusEffect to effect
520
         * \param effectId -1 for stun, otherwise the effect index
521
         */
522
        virtual void handleStatusEffect(StatusEffect *effect, int effectId);
523
524
        virtual void showName();
525
526
        int mId;                        /**< Unique sprite id */
527
        Uint8 mDirection;               /**< Facing direction */
528
        Uint8 mSpriteDirection;         /**< Facing direction */
529
        Map *mMap;                      /**< Map on which this being resides */
530
        std::string mName;              /**< Name of character */
531
        MapSprite mMapSprite;
532
        bool mParticleEffects;          /**< Whether to display particles or not */
533
534
        /**
535
         * Holds a text object when the being displays it's name, 0 otherwise
536
         */
537
        FlashText *mDispName;
538
        const gcn::Color *mNameColor;
539
        bool mShowName;
540
541
        /** Engine-related infos about weapon. */
542
        const ItemInfo *mEquippedWeapon;
543
544
        static int mNumberOfHairstyles;          /** Number of hair styles in use */
545
546
        Path mPath;
547
        std::string mSpeech;
548
        Text *mText;
549
        const gcn::Color *mTextColor;
550
        Uint16 mStunMode;               /**< Stun mode; zero if not stunned */
551
        std::set<int> mStatusEffects;   /**< set of active status effects */
552
553
        typedef std::vector<AnimatedSprite*> Sprites;
554
        typedef Sprites::iterator SpriteIterator;
555
        typedef Sprites::const_iterator SpriteConstIterator;
556
        Sprites mSprites;
557
        float mAlpha;                   /**< Alpha opacity to draw the sprite */
558
559
        ParticleList mStunParticleEffects;
560
        ParticleVector mStatusParticleEffects;
561
        ParticleList mChildParticleEffects;
562
563
    private:
564
#ifdef EATHENA_SUPPORT
565
        /**
566
         * Calculates the offset in the given directions.
567
         * If walking in direction 'neg' the value is negated.
568
         */
569
        int getOffset(char pos, char neg) const;
570
#endif
571
572
        /** Reset particle status effects on next redraw? */
573
        bool mMustResetParticles;
574
575
        /** Speech Bubble components */
576
        SpeechBubble *mSpeechBubble;
577
578
        /**
579
         * Walk speed.
580
         * In pixels per second for eAthena,
581
         * In tiles per second (0.1 precision) for TMWserv.
582
         */
583
        float mWalkSpeed;
584
585
        Vector mPos;
586
        Vector mDest;
587
        int mPx, mPy;                   /**< Position in pixels */
588
        int mX, mY;                     /**< Position on tile */
589
590
        /** Target cursor being used */
591
        SimpleAnimation* mUsedTargetCursor;
592
};
593
594
#endif