Commit 27efdd9a80c7d068f27db8725c2315fee3e10303

  • avatar
  • Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> (Committer)
  • Thu Jul 08 22:33:31 CEST 2010
  • avatar
  • remoitnane <remoit(DOT)nane(AT)gmail(DOT)com> (Author)
  • Wed Jul 07 12:59:33 CEST 2010
Fix crash in picking up an item that no longer exists

Adds ActorSpriteListener to manage ActorSprite destruction as
recommended by Jaxad0127. This likewise includes the changes made by
Bertram.

Reviewed-by: Jaxad0127, Bertram.

Resolves: Manasource Mantis #160
mana.cbp
(1 / 0)
  
9898 <Unit filename="src\actor.h" />
9999 <Unit filename="src\actorsprite.cpp" />
100100 <Unit filename="src\actorsprite.h" />
101 <Unit filename="src\actorspritelistener.h" />
101102 <Unit filename="src\actorspritemanager.cpp" />
102103 <Unit filename="src\actorspritemanager.h" />
103104 <Unit filename="src\animatedsprite.cpp" />
mana.files
(1 / 0)
  
4242./src/actor.h
4343./src/actorsprite.cpp
4444./src/actorsprite.h
45./src/actorspritelistener.h
4546./src/actorspritemanager.cpp
4647./src/actorspritemanager.h
4748./src/animatedsprite.cpp
  
406406 actor.h
407407 actorsprite.cpp
408408 actorsprite.h
409 actorspritelistener.h
409410 actorspritemanager.cpp
410411 actorspritemanager.h
411412 animatedsprite.cpp
  
305305 actor.h \
306306 actorsprite.cpp \
307307 actorsprite.h \
308 actorspritelistener.h \
308309 actorspritemanager.cpp \
309310 actorspritemanager.h \
310311 animatedsprite.cpp \
  
1919 */
2020
2121#include "actorsprite.h"
22#include "actorspritelistener.h"
2223
2324#include "client.h"
2425#include "effectmanager.h"
6565
6666 if (player_node && player_node->getTarget() == this)
6767 player_node->setTarget(NULL);
68
69 // Notify listeners of the destruction.
70 for (ActorSpriteListenerIterator iter = mActorSpriteListeners.begin(),
71 end = mActorSpriteListeners.end(); iter != end; ++iter)
72 (*iter)->actorSpriteDestroyed(*this);
6873}
6974
7075bool ActorSprite::draw(Graphics *graphics, int offsetX, int offsetY) const
362362
363363 cleanupTargetCursors();
364364 loaded = false;
365}
366
367void ActorSprite::addActorSpriteListener(ActorSpriteListener *listener)
368{
369 mActorSpriteListeners.push_front(listener);
370}
371
372void ActorSprite::removeActorSpriteListener(ActorSpriteListener *listener)
373{
374 mActorSpriteListeners.remove(listener);
365375}
366376
367377static const char *cursorType(int type)
  
2929#include <SDL_types.h>
3030
3131#include <set>
32#include <list>
3233
3334class SimpleAnimation;
3435class StatusEffect;
36class ActorSpriteListener;
3537
3638class ActorSprite : public CompoundSprite, public Actor
3739{
162162
163163 static void unload();
164164
165 /**
166 * Add an ActorSprite listener.
167 */
168 void addActorSpriteListener(ActorSpriteListener *listener);
169
170 /**
171 * Remove an ActorSprite listener.
172 */
173 void removeActorSpriteListener(ActorSpriteListener *listener);
174
165175protected:
166176 /**
167177 * Trigger visual effect, with components
239239
240240 /** Target cursor being used */
241241 SimpleAnimation *mUsedTargetCursor;
242
243 typedef std::list<ActorSpriteListener*> ActorSpriteListeners;
244 typedef ActorSpriteListeners::iterator ActorSpriteListenerIterator;
245 ActorSpriteListeners mActorSpriteListeners;
242246};
243247
244248#endif // ACTORSPRITE_H
  
1/*
2 * The Mana Client
3 * Copyright (C) 2010 The Mana Developers
4 *
5 * This file is part of The Mana Client.
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, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef ACTORSPRITELISTENER_H
22#define ACTORSPRITELISTENER_H
23
24class ActorSprite;
25
26class ActorSpriteListener
27{
28 public:
29 /**
30 * Destructor.
31 */
32 virtual ~ActorSpriteListener() {}
33
34 /**
35 * Called when the ActorSprite has been destroyed. The listener will
36 * have to be registered first.
37 * @param actorSprite the ActorSprite being destroyed.
38 */
39 virtual void actorSpriteDestroyed(const ActorSprite &actorSprite) = 0;
40};
41
42#endif // ACTORSPRITELISTENER_H
  
686686
687687void LocalPlayer::pickUp(FloorItem *item)
688688{
689 if (!item)
690 return;
691
689692 int dx = item->getTileX() - (int) getPosition().x / 32;
690693 int dy = item->getTileY() - (int) getPosition().y / 32;
691694
703703 {
704704 setDestination(item->getPixelX() + 16, item->getPixelY() + 16);
705705 mPickUpTarget = item;
706 mPickUpTarget->addActorSpriteListener(this);
706707 }
707708 else
708709 {
709710 setDestination(item->getTileX(), item->getTileY());
710711 mPickUpTarget = item;
712 mPickUpTarget->addActorSpriteListener(this);
711713 stopAttack();
712714 }
713715 }
716}
717
718void LocalPlayer::actorSpriteDestroyed(const ActorSprite &actorSprite)
719{
720 if (mPickUpTarget == &actorSprite)
721 mPickUpTarget = 0;
714722}
715723
716724Being *LocalPlayer::getTarget() const
  
2323#define LOCALPLAYER_H
2424
2525#include "being.h"
26#include "actorspritelistener.h"
2627
2728#include "gui/userpalette.h"
2829
110110/**
111111 * The local player character.
112112 */
113class LocalPlayer : public Being
113class LocalPlayer : public Being, public ActorSpriteListener
114114{
115115 public:
116116 /**
163163 void setInvItem(int index, int id, int amount);
164164
165165 void pickUp(FloorItem *item);
166
167 /**
168 * Called when an ActorSprite has been destroyed.
169 * @param actorSprite the ActorSprite being destroyed.
170 */
171 void actorSpriteDestroyed(const ActorSprite &actorSprite);
166172
167173 /**
168174 * Sets the attack range.
  
329329
330330void PlayerHandler::pickUp(FloorItem *floorItem)
331331{
332 int id = floorItem->getId();
333 MessageOut msg(PGMSG_PICKUP);
334 msg.writeInt16(id >> 16);
335 msg.writeInt16(id & 0xFFFF);
336 gameServerConnection->send(msg);
332 if (floorItem)
333 {
334 int id = floorItem->getId();
335 MessageOut msg(PGMSG_PICKUP);
336 msg.writeInt16(id >> 16);
337 msg.writeInt16(id & 0xFFFF);
338 gameServerConnection->send(msg);
339 }
337340}
338341
339342void PlayerHandler::setDirection(char direction)
  
582582
583583void PlayerHandler::pickUp(FloorItem *floorItem)
584584{
585 MessageOut outMsg(CMSG_ITEM_PICKUP);
586 outMsg.writeInt32(floorItem->getId());
585 if (floorItem)
586 {
587 MessageOut outMsg(CMSG_ITEM_PICKUP);
588 outMsg.writeInt32(floorItem->getId());
589 }
587590}
588591
589592void PlayerHandler::setDirection(char direction)