1 /*
2  *  The ManaPlus Client
3  *  Copyright (C) 2010  The Mana Developers
4  *  Copyright (C) 2011-2019  The ManaPlus Developers
5  *  Copyright (C) 2019-2021  Andrei Karas
6  *
7  *  This file is part of The ManaPlus Client.
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef BEING_ACTORSPRITE_H
24 #define BEING_ACTORSPRITE_H
25 
26 #include "being/actor.h"
27 #include "being/compoundsprite.h"
28 
29 #include "const/resources/map/map.h"
30 
31 #include "enums/being/actortype.h"
32 #include "enums/being/targetcursorsize.h"
33 #include "enums/being/targetcursortype.h"
34 
35 #include "enums/simpletypes/beingid.h"
36 #include "enums/simpletypes/enable.h"
37 #include "enums/simpletypes/forcedisplay.h"
38 #include "enums/simpletypes/isstart.h"
39 
40 #include "enums/resources/displaytype.h"
41 
42 #include "enums/resources/map/blocktype.h"
43 
44 #include "particle/particlelist.h"
45 #include "particle/particlevector.h"
46 
47 #include "localconsts.h"
48 
49 class AnimatedSprite;
50 class StatusEffect;
51 class ActorSpriteListener;
52 
53 struct SpriteDisplay;
54 
55 class ActorSprite notfinal : public CompoundSprite, public Actor
56 {
57     public:
58         explicit ActorSprite(const BeingId id);
59 
60         A_DELETE_COPY(ActorSprite)
61 
62         ~ActorSprite() override;
63 
getId()64         BeingId getId() const noexcept2 A_WARN_UNUSED
65         { return mId; }
66 
setId(const BeingId id)67         void setId(const BeingId id) noexcept2
68         { mId = id; }
69 
70         /**
71          * Returns the type of the ActorSprite.
72          */
getType()73         virtual ActorTypeT getType() const noexcept2 A_WARN_UNUSED
74         { return ActorType::Unknown; }
75 
76         virtual void logic();
77 
78         void setMap(Map *const map) override;
79 
80         /**
81          * Gets the way the object blocks pathfinding for other objects
82          */
getBlockType()83         virtual BlockTypeT getBlockType() const A_WARN_UNUSED
84         { return BlockType::NONE; }
85 
86         /**
87          * Take control of a particle. Particle can be auto deleted.
88          */
89         void controlAutoParticle(Particle *const particle);
90 
91         /**
92          * Take control of a particle. Owner must remove particle by self.
93          */
94         void controlCustomParticle(Particle *const particle);
95 
96         /**
97          * Returns the required size of a target cursor for this being.
98          */
getTargetCursorSize()99         virtual TargetCursorSizeT getTargetCursorSize() const A_WARN_UNUSED
100         { return TargetCursorSize::MEDIUM; }
101 
getTargetOffsetX()102         virtual int getTargetOffsetX() const A_WARN_UNUSED
103         { return 0; }
104 
getTargetOffsetY()105         virtual int getTargetOffsetY() const A_WARN_UNUSED
106         { return 0; }
107 
108         /**
109          * Sets the target animation for this actor.
110          */
111         void setTargetType(const TargetCursorTypeT type);
112 
113         /**
114          * Untargets the actor.
115          */
untarget()116         void untarget()
117         { mUsedTargetCursor = nullptr; }
118 
119         void setStatusEffect(const int32_t index,
120                              const Enable active,
121                              const IsStart start);
122 
123         void setStatusEffectOpitons(const uint32_t option,
124                                     const uint32_t opt1,
125                                     const uint32_t opt2,
126                                     const uint32_t opt3);
127 
128         void setStatusEffectOpitons(const uint32_t option,
129                                     const uint32_t opt1,
130                                     const uint32_t opt2);
131 
132         void setStatusEffectOpiton0(const uint32_t option);
133 
setAlpha(const float alpha)134         void setAlpha(const float alpha) override final
135         { CompoundSprite::setAlpha(alpha); }
136 
getAlpha()137         float getAlpha() const override final A_WARN_UNUSED
138         { return CompoundSprite::getAlpha(); }
139 
getWidth()140         int getWidth() const override A_WARN_UNUSED
141         { return CompoundSprite::getWidth(); }
142 
getHeight()143         int getHeight() const override A_WARN_UNUSED
144         { return CompoundSprite::getHeight(); }
145 
146         static void load();
147 
148         static void unload();
149 
150         /**
151          * Add an ActorSprite listener.
152          */
153         void addActorSpriteListener(ActorSpriteListener *const listener);
154 
155         /**
156          * Remove an ActorSprite listener.
157          */
158         void removeActorSpriteListener(ActorSpriteListener *const listener);
159 
getActorX()160         int getActorX() const A_WARN_UNUSED
161         { return getPixelX() - mapTileSize / 2; }
162 
getActorY()163         int getActorY() const A_WARN_UNUSED
164         { return getPixelY() - mapTileSize; }
165 
setPoison(const bool b)166         void setPoison(const bool b)
167         { mPoison = b; }
168 
getPoison()169         bool getPoison() const A_WARN_UNUSED
170         { return mPoison; }
171 
setHaveCart(const bool b)172         void setHaveCart(const bool b)
173         { mHaveCart = b; }
174 
getHaveCart()175         bool getHaveCart() const A_WARN_UNUSED
176         { return mHaveCart; }
177 
setRiding(const bool b)178         virtual void setRiding(const bool b)
179         { mHorseId = b ? 1 : 0; }
180 
setTrickDead(const bool b)181         virtual void setTrickDead(const bool b)
182         { mTrickDead = b; }
183 
isTrickDead()184         bool isTrickDead() const A_WARN_UNUSED
185         { return mTrickDead; }
186 
getStatusEffects()187         const std::set<int32_t> &getStatusEffects() const A_WARN_UNUSED
188         { return mStatusEffects; }
189 
190         std::string getStatusEffectsString() const;
191 
stopCast(const bool b A_UNUSED)192         virtual void stopCast(const bool b A_UNUSED)
193         { }
194 
getParticlesCount()195         size_t getParticlesCount() const
196         {
197             return mStatusParticleEffects.usedSize() +
198                 mChildParticleEffects.size();
199         }
200 
201         void controlParticleDeleted(const Particle *const particle);
202 
203     protected:
204         /**
205          * Notify self that a status effect has flipped.
206          * The new flag is passed.
207          */
208         virtual void updateStatusEffect(const int32_t index,
209                                         const Enable newStatus,
210                                         const IsStart start);
211 
212         /**
213          * Handle an update to a status or stun effect
214          *
215          * \param The StatusEffect to effect
216          * \param effectId -1 for stun, otherwise the effect index
217          */
218         virtual void handleStatusEffect(const StatusEffect *const effect,
219                                         const int32_t effectId,
220                                         const Enable newStatus,
221                                         const IsStart start);
222 
223         void setupSpriteDisplay(const SpriteDisplay &display,
224                                 const ForceDisplay forceDisplay,
225                                 const DisplayTypeT displayType,
226                                 const std::string &color);
227 
228         /** Load the target cursors into memory */
229         static void initTargetCursor();
230 
231         /** Remove the target cursors from memory */
232         static void cleanupTargetCursors();
233 
234         /** Animated target cursors. */
235         static AnimatedSprite *targetCursor
236             [CAST_SIZE(TargetCursorType::NUM_TCT)]
237             [CAST_SIZE(TargetCursorSize::NUM_TC)];
238 
239         static bool loaded;
240 
241         /**< set of active status effects */
242         std::set<int32_t> mStatusEffects;
243 
244         ParticleVector mStatusParticleEffects;
245         ParticleList mChildParticleEffects;
246         int mHorseId;
247         BeingId mId;
248 
249         /** Target cursor being used */
250         AnimatedSprite *mUsedTargetCursor;
251 
252         typedef std::list<ActorSpriteListener*> ActorSpriteListeners;
253         typedef ActorSpriteListeners::iterator ActorSpriteListenerIterator;
254         ActorSpriteListeners mActorSpriteListeners;
255 
256         int mCursorPaddingX;
257         int mCursorPaddingY;
258 
259         /** Reset particle status effects on next redraw? */
260         bool mMustResetParticles;
261         bool mPoison;
262         bool mHaveCart;
263         bool mTrickDead;
264 };
265 
266 #endif  // BEING_ACTORSPRITE_H
267