From 54ac35bc5a1484757efeae9b342469b9a00fe2a2 Mon Sep 17 00:00:00 2001 From: Guillaume Melquiond Date: Thu, 18 Oct 2007 19:00:38 +0000 Subject: Removed player looks from generic beings. Prevented client termination on missing sprites. Merged weapon-type and attack-type fields for items. --- src/animatedsprite.cpp | 18 ++++------- src/animatedsprite.h | 4 +-- src/being.cpp | 26 ++-------------- src/being.h | 50 +----------------------------- src/gui/minimap.cpp | 12 +++++--- src/gui/viewport.cpp | 2 +- src/localplayer.cpp | 8 ++--- src/localplayer.h | 3 +- src/monster.cpp | 2 +- src/net/beinghandler.cpp | 15 ++++----- src/net/charserverhandler.cpp | 2 +- src/npc.cpp | 2 +- src/player.cpp | 64 +++++++++++++++++---------------------- src/player.h | 43 ++++++++++++++++++++------ src/resources/itemdb.cpp | 4 +-- src/resources/iteminfo.cpp | 45 +++++++++++++-------------- src/resources/iteminfo.h | 2 +- src/resources/resourcemanager.cpp | 7 +++++ src/resources/spritedef.cpp | 4 +-- 19 files changed, 128 insertions(+), 185 deletions(-) (limited to 'src') diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp index c1e89ff0..466779fd 100644 --- a/src/animatedsprite.cpp +++ b/src/animatedsprite.cpp @@ -54,20 +54,14 @@ AnimatedSprite::AnimatedSprite(SpriteDef *sprite): play(ACTION_STAND); } -AnimatedSprite::AnimatedSprite(const std::string& filename, int variant): - mDirection(DIRECTION_DOWN), - mLastTime(0), - mFrameIndex(0), - mFrameTime(0), - mAnimation(0), - mFrame(0) +AnimatedSprite *AnimatedSprite::load(const std::string& filename, int variant) { ResourceManager *resman = ResourceManager::getInstance(); - mSprite = resman->getSprite(filename, variant); - assert(mSprite); - - // Play the stand animation by default - play(ACTION_STAND); + SpriteDef *s = resman->getSprite(filename, variant); + if (!s) return NULL; + AnimatedSprite *as = new AnimatedSprite(s); + s->decRef(); + return as; } AnimatedSprite::~AnimatedSprite() diff --git a/src/animatedsprite.h b/src/animatedsprite.h index d77d08f5..a1fbe7a0 100644 --- a/src/animatedsprite.h +++ b/src/animatedsprite.h @@ -46,13 +46,13 @@ class AnimatedSprite AnimatedSprite(SpriteDef *sprite); /** - * A convenience constructor, which will request the sprite to animate + * An helper function, which will request the sprite to animate * from the resource manager. * * @param filename the file of the sprite to animate * @param variant the sprite variant */ - AnimatedSprite(const std::string& filename, int variant = 0); + static AnimatedSprite *load(std::string const &filename, int variant = 0); /** * Destructor. diff --git a/src/being.cpp b/src/being.cpp index 81bed667..d5f37371 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -46,26 +46,22 @@ int Being::instances = 0; ImageSet *Being::emotionSet = NULL; -Being::Being(Uint16 id, Uint16 job, Map *map): +Being::Being(int id, int job, Map *map): mJob(job), mX(0), mY(0), mAction(STAND), mWalkTime(0), mEmotion(0), mEmotionTime(0), mAttackSpeed(350), - mEquipment(new Equipment()), mId(id), - mSex(2), mWalkSpeed(150), mSpeedModifier(1024), mSpriteDirection(DIRECTION_DOWN), mDirection(DOWN), mMap(NULL), mEquippedWeapon(NULL), - mHairStyle(0), mHairColor(0), mSpeechTime(0), mPx(0), mPy(0), - mSprites(VECTOREND_SPRITE, NULL), - mEquipmentSpriteIDs(VECTOREND_SPRITE, 0) + mSprites(VECTOREND_SPRITE, NULL) { setMap(map); @@ -272,24 +268,6 @@ Being::setPath(const Path &path, int mod) } } -void -Being::setHairColor(Uint16 color) -{ - mHairColor = (color < NR_HAIR_COLORS) ? color : 0; -} - -void -Being::setHairStyle(Uint16 style) -{ - mHairStyle = (style < NR_HAIR_STYLES) ? style : 0; -} - -void -Being::setVisibleEquipment(Uint8 slot, int id) -{ - mEquipmentSpriteIDs[slot] = id; -} - void Being::setSpeech(const std::string &text, Uint32 time) { diff --git a/src/being.h b/src/being.h index fadf9656..fd17caf5 100644 --- a/src/being.h +++ b/src/being.h @@ -68,7 +68,6 @@ class Being : public Sprite public: enum Type { UNKNOWN, - LOCALPLAYER, PLAYER, NPC, MONSTER @@ -125,7 +124,7 @@ class Being : public Sprite /** * Constructor. */ - Being(Uint16 id, Uint16 job, Map *map); + Being(int id, int job, Map *map); /** * Destructor. @@ -189,48 +188,6 @@ class Being : public Sprite void setName(const std::string &name) { mName = name; } - /** - * Sets the hair color for this being. - */ - virtual void - setHairColor(Uint16 color); - - /** - * Gets the hair color for this being. - */ - Uint16 - getHairColor() const { return mHairColor; } - - /** - * Sets the hair style for this being. - */ - virtual void - setHairStyle(Uint16 style); - - /** - * Gets the hair style for this being. - */ - Uint16 - getHairStyle() const { return mHairStyle; } - - /** - * Sets visible equipments for this being. - */ - virtual void - setVisibleEquipment(Uint8 slot, int id); - - /** - * Sets the sex for this being. - */ - virtual void - setSex(Uint8 sex) { mSex = sex; } - - /** - * Gets the sex for this being. - */ - Uint8 - getSex() const { return mSex; } - /** * Makes this being take the next step of his path. */ @@ -364,8 +321,6 @@ class Being : public Sprite virtual Being::TargetCursorSize getTargetCursorSize() const { return TC_MEDIUM; } - std::auto_ptr mEquipment; - /** * Take control of a particle. */ @@ -378,7 +333,6 @@ class Being : public Sprite void setPath(const Path &path, int mod = 1024); Uint16 mId; /**< Unique being id */ - Uint8 mSex; /**< Character's gender */ Uint16 mWalkSpeed; /**< Walking speed */ Uint16 mSpeedModifier; /**< Modifier to keep course on sync (1024 = normal speed) */ Uint8 mSpriteDirection; /**< Facing direction */ @@ -391,12 +345,10 @@ class Being : public Sprite Path mPath; std::string mSpeech; - Uint16 mHairStyle, mHairColor; Uint32 mSpeechTime; Sint32 mPx, mPy; /**< Pixel coordinates */ std::vector mSprites; - std::vector mEquipmentSpriteIDs; std::list mChildParticleEffects; private: diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index a8e9dafd..f78447cd 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -26,6 +26,7 @@ #include "../being.h" #include "../beingmanager.h" #include "../graphics.h" +#include "../localplayer.h" #include "../resources/image.h" @@ -86,12 +87,13 @@ void Minimap::draw(gcn::Graphics *graphics) int dotSize = 2; switch (being->getType()) { - case Being::LOCALPLAYER: - dotSize = 3; - graphics->setColor(gcn::Color(61, 209, 52)); - break; - case Being::PLAYER: + if (being == player_node) + { + dotSize = 3; + graphics->setColor(gcn::Color(61, 209, 52)); + break; + } graphics->setColor(gcn::Color(61, 52, 209)); break; diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index 915b618d..5c48c355 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -373,7 +373,7 @@ Viewport::mousePressed(gcn::MouseEvent &event) FloorItem *floorItem; if ((being = beingManager->findBeing(tilex, tiley)) && - being->getType() != Being::LOCALPLAYER) + being != player_node) { mPopupMenu->showPopup(event.getX(), event.getY(), being); return; diff --git a/src/localplayer.cpp b/src/localplayer.cpp index f4ad7587..346597a8 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -47,7 +47,8 @@ LocalPlayer *player_node = NULL; LocalPlayer::LocalPlayer(): Player(65535, 0, NULL), mAttackRange(0), - mInventory(new Inventory()), + mInventory(new Inventory), + mEquipment(new Equipment), mAttributeBase(NB_CHARACTER_ATTRIBUTES, 0), mAttributeEffective(NB_CHARACTER_ATTRIBUTES, 0), mAttributeIncreasePoints(0), @@ -94,11 +95,6 @@ void LocalPlayer::nextStep() Player::nextStep(); } -Being::Type LocalPlayer::getType() const -{ - return LOCALPLAYER; -} - void LocalPlayer::clearInventory() { mEquipment->clear(); diff --git a/src/localplayer.h b/src/localplayer.h index ff7bf0b7..6349f7ed 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -141,8 +141,6 @@ class LocalPlayer : public Player virtual void drawName(Graphics *, int, int) {}; - virtual Type getType() const; - void clearInventory(); Item* getInvItem(int index); @@ -305,6 +303,7 @@ class LocalPlayer : public Player float mLastAttackTime; /**< Used to synchronize the charge dialog */ std::auto_ptr mInventory; + std::auto_ptr mEquipment; protected: void walk(unsigned char dir); diff --git a/src/monster.cpp b/src/monster.cpp index fe78c878..bc964b0b 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -35,7 +35,7 @@ Monster::Monster(Uint16 id, Uint16 job, Map *map): Being(id, job, map) { - mSprites[BASE_SPRITE] = new AnimatedSprite( + mSprites[BASE_SPRITE] = AnimatedSprite::load( "graphics/sprites/" + getInfo().getSprite()); } diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp index 020d24af..6bd31c9f 100644 --- a/src/net/beinghandler.cpp +++ b/src/net/beinghandler.cpp @@ -418,7 +418,7 @@ void BeingHandler::handleMessage(MessageIn &msg) } } -static void handleLooks(Being *being, MessageIn &msg) +static void handleLooks(Player *being, MessageIn &msg) { // Order of sent slots. Has to be in sync with the server code. static int const nb_slots = 4; @@ -471,10 +471,11 @@ BeingHandler::handleBeingEnterMessage(MessageIn &msg) being = beingManager->createBeing(id, type, 0); being->setName(name); } - being->setHairStyle(msg.readByte()); - being->setHairColor(msg.readByte()); - being->setSex(msg.readByte()); - handleLooks(being, msg); + Player *p = static_cast< Player * >(being); + p->setHairStyle(msg.readByte()); + p->setHairColor(msg.readByte()); + p->setGender(msg.readByte()); + handleLooks(p, msg); } break; case OBJECT_MONSTER: @@ -591,7 +592,7 @@ void BeingHandler::handleBeingActionChangeMessage(MessageIn &msg) void BeingHandler::handleBeingLooksChangeMessage(MessageIn &msg) { Being *being = beingManager->findBeing(msg.readShort()); - if (!being) return; - handleLooks(being, msg); + if (!being || being->getType() != Being::PLAYER) return; + handleLooks(static_cast< Player * >(being), msg); } diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp index 820aaea4..1cfd815b 100644 --- a/src/net/charserverhandler.cpp +++ b/src/net/charserverhandler.cpp @@ -216,7 +216,7 @@ CharServerHandler::readPlayerData(MessageIn &msg, int &slot) LocalPlayer *tempPlayer = new LocalPlayer; slot = msg.readByte(); // character slot tempPlayer->mName = msg.readString(); - tempPlayer->setSex(msg.readByte()); + tempPlayer->setGender(msg.readByte()); tempPlayer->setHairStyle(msg.readByte()); tempPlayer->setHairColor(msg.readByte()); tempPlayer->setLevel(msg.readByte()); diff --git a/src/npc.cpp b/src/npc.cpp index f65c8d19..980f1c8b 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -35,7 +35,7 @@ NPC *current_npc = 0; NPC::NPC(Uint16 id, Uint16 job, Map *map): Being(id, job, map) { - mSprites[BASE_SPRITE] = new AnimatedSprite("graphics/sprites/npc.xml", + mSprites[BASE_SPRITE] = AnimatedSprite::load("graphics/sprites/npc.xml", job - 100); } diff --git a/src/player.cpp b/src/player.cpp index b63dcd5b..0fe6460c 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -35,8 +35,10 @@ #include "gui/gui.h" -Player::Player(Uint16 id, Uint16 job, Map *map): - Being(id, job, map) +Player::Player(int id, int job, Map *map): + Being(id, job, map), + mEquipmentSpriteIDs(VECTOREND_SPRITE, 0), + mGender(2), mHairStyle(0), mHairColor(0) { } @@ -57,8 +59,7 @@ Player::drawName(Graphics *graphics, int offsetX, int offsetY) graphics->drawText(mName, px + 15, py + 30, gcn::Graphics::CENTER); } -void -Player::setSex(Uint8 sex) +void Player::setGender(int sex) { // Players can only be male or female if (sex > 1) @@ -67,20 +68,20 @@ Player::setSex(Uint8 sex) sex = 0; } - if (sex != mSex) + if (sex != mGender) { - Being::setSex(sex); + mGender = sex; // Reload base sprite AnimatedSprite *newBaseSprite; if (sex == 0) { - newBaseSprite = new AnimatedSprite( + newBaseSprite = AnimatedSprite::load( "graphics/sprites/player_male_base.xml"); } else { - newBaseSprite = new AnimatedSprite( + newBaseSprite = AnimatedSprite::load( "graphics/sprites/player_female_base.xml"); } @@ -92,7 +93,7 @@ Player::setSex(Uint8 sex) { if (i != HAIR_SPRITE && mEquipmentSpriteIDs.at(i) != 0) { - AnimatedSprite *newEqSprite = new AnimatedSprite( + AnimatedSprite *newEqSprite = AnimatedSprite::load( "graphics/sprites/" + ItemDB::get( mEquipmentSpriteIDs.at(i)).getSprite(sex)); delete mSprites[i]; @@ -102,17 +103,17 @@ Player::setSex(Uint8 sex) } } -void -Player::setHairColor(Uint16 color) +void Player::setHairColor(int color) { if (color != mHairColor) { - Being::setHairColor(color); + mHairColor = color < NR_HAIR_COLORS ? color : 0; - AnimatedSprite *newHairSprite = new AnimatedSprite( - "graphics/sprites/hairstyle" + toString(mHairStyle) + ".xml", + AnimatedSprite *newHairSprite = AnimatedSprite::load( + "graphics/sprites/hairstyle" + toString(getHairStyle()) + ".xml", mHairColor); - newHairSprite->setDirection(getSpriteDirection()); + if (newHairSprite) + newHairSprite->setDirection(getSpriteDirection()); delete mSprites[HAIR_SPRITE]; mSprites[HAIR_SPRITE] = newHairSprite; @@ -121,17 +122,17 @@ Player::setHairColor(Uint16 color) } } -void -Player::setHairStyle(Uint16 style) +void Player::setHairStyle(int style) { if (style != mHairStyle) { - Being::setHairStyle(style); + mHairStyle = style < NR_HAIR_STYLES ? style : 0; - AnimatedSprite *newHairSprite = new AnimatedSprite( - "graphics/sprites/hairstyle" + toString(mHairStyle) + ".xml", + AnimatedSprite *newHairSprite = AnimatedSprite::load( + "graphics/sprites/hairstyle" + toString(getHairStyle()) + ".xml", mHairColor); - newHairSprite->setDirection(getSpriteDirection()); + if (newHairSprite) + newHairSprite->setDirection(getSpriteDirection()); delete mSprites[HAIR_SPRITE]; mSprites[HAIR_SPRITE] = newHairSprite; @@ -140,8 +141,7 @@ Player::setHairStyle(Uint16 style) } } -void -Player::setVisibleEquipment(Uint8 slot, int id) +void Player::setVisibleEquipment(int slot, int id) { // id = 0 means unequip if (id == 0) @@ -151,19 +151,11 @@ Player::setVisibleEquipment(Uint8 slot, int id) } else { - AnimatedSprite *equipmentSprite; - - if (mSex == 0) - { - equipmentSprite = new AnimatedSprite( - "graphics/sprites/" + ItemDB::get(id).getSprite(0)); - } - else { - equipmentSprite = new AnimatedSprite( - "graphics/sprites/" + ItemDB::get(id).getSprite(1)); - } + AnimatedSprite *equipmentSprite = AnimatedSprite::load( + "graphics/sprites/" + ItemDB::get(id).getSprite(mGender)); - equipmentSprite->setDirection(getSpriteDirection()); + if (equipmentSprite) + equipmentSprite->setDirection(getSpriteDirection()); delete mSprites[slot]; mSprites[slot] = equipmentSprite; @@ -176,5 +168,5 @@ Player::setVisibleEquipment(Uint8 slot, int id) setAction(mAction); } - Being::setVisibleEquipment(slot, id); + mEquipmentSpriteIDs[slot] = id; } diff --git a/src/player.h b/src/player.h index 2c06bfba..e6d3743a 100644 --- a/src/player.h +++ b/src/player.h @@ -40,7 +40,7 @@ class Player : public Being /** * Constructor. */ - Player(Uint16 id, Uint16 job, Map *map); + Player(int id, int job, Map *map); virtual Type getType() const; @@ -48,17 +48,42 @@ class Player : public Being virtual void drawName(Graphics *graphics, int offsetX, int offsetY); - virtual void - setSex(Uint8 sex); + /** + * Sets the sex for this player. + */ + void setGender(int); - virtual void - setHairColor(Uint16 color); + /** + * Gets the hair color for this player. + */ + int getHairColor() const + { return mHairColor; } - virtual void - setHairStyle(Uint16 style); + /** + * Sets the hair color for this player. + */ + void setHairColor(int color); - virtual void - setVisibleEquipment(Uint8 slot, int id); + /** + * Gets the hair style for this player. + */ + int getHairStyle() const + { return mHairStyle; } + + /** + * Sets the hair style for this player. + */ + void setHairStyle(int style); + + /** + * Sets visible equipments for this player. + */ + void setVisibleEquipment(int slot, int id); + + private: + + std::vector mEquipmentSpriteIDs; + Uint8 mGender, mHairStyle, mHairColor; }; #endif diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index 157e522c..4e978093 100644 --- a/src/resources/itemdb.cpp +++ b/src/resources/itemdb.cpp @@ -107,7 +107,7 @@ void ItemDB::load() std::string image = XML::getProperty(node, "image", ""); std::string description = XML::getProperty(node, "description", ""); std::string effect = XML::getProperty(node, "effect", ""); - std::string attackType = XML::getProperty(node, "attacktype", ""); + int weaponType = XML::getProperty(node, "weapon_type", 0); if (id) { @@ -120,7 +120,7 @@ void ItemDB::load() itemInfo->setView(view); itemInfo->setWeight(weight); itemInfo->setSlot(slot); - itemInfo->setAttackType(attackType); + itemInfo->setWeaponType(weaponType); for_each_xml_child_node(itemChild, node) { diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp index b5b25ac0..6654ccca 100644 --- a/src/resources/iteminfo.cpp +++ b/src/resources/iteminfo.cpp @@ -71,32 +71,29 @@ ItemInfo::getSprite(int gender) const } } -void -ItemInfo::setAttackType(const std::string &attackType) +void ItemInfo::setWeaponType(int type) { - if (attackType == "swing") - { - mAttackType = ACTION_ATTACK_SWING; - } - else if (attackType == "stab") - { - mAttackType = ACTION_ATTACK_STAB; - } - else if (attackType == "bow") - { - mAttackType = ACTION_ATTACK_BOW; - } - else if (attackType == "throw") - { - mAttackType = ACTION_ATTACK_THROW; - } - else if (attackType == "none") - { - mAttackType = ACTION_DEFAULT; - } - else + // See server item.hpp file for type values. + switch (type) { - mAttackType = ACTION_ATTACK; + case 0: // none + mAttackType = ACTION_DEFAULT; + break; + case 1: // knife + case 2: // sword + mAttackType = ACTION_ATTACK_STAB; + break; + case 8: // projectile + mAttackType = ACTION_ATTACK_THROW; + break; + case 10: // bow + mAttackType = ACTION_ATTACK_BOW; + break; + case 11: // sickle + mAttackType = ACTION_ATTACK_SWING; + break; + default: + mAttackType = ACTION_ATTACK; } } diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h index 4fd1638e..4cab66fa 100644 --- a/src/resources/iteminfo.h +++ b/src/resources/iteminfo.h @@ -113,7 +113,7 @@ class ItemInfo const std::string& getSprite(int gender) const; - void setAttackType(const std::string &attackType); + void setWeaponType(int); const SpriteAction getAttackType() const { return mAttackType; } diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index 448e7f80..5e3f3bc7 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -275,6 +275,13 @@ ResourceManager::getSprite(const std::string &path, int variant) return dynamic_cast(resIter->second); } + // FIXME: modify SpriteDef so that it gracefully fails on missing sprite. + if (!exists(path) || isDirectory(path)) + { + logger->log("Failed to load file: %s", path.c_str()); + return NULL; + } + SpriteDef *sprite = new SpriteDef(idPath, path, variant); sprite->incRef(); mResources[idPath] = sprite; diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp index 24156be1..d90d4067 100644 --- a/src/resources/spritedef.cpp +++ b/src/resources/spritedef.cpp @@ -73,13 +73,13 @@ SpriteDef::load(const std::string &animationFile, int variant) if (!doc) { logger->error( - "Animation: Error while parsing animation definition file!"); + "Animation: Error while parsing " + animationFile + " file!"); } xmlNodePtr rootNode = xmlDocGetRootElement(doc); if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "sprite")) { logger->error( - "Animation: this is not a valid animation definition file!"); + "Animation: this is not a valid " + animationFile + " file!"); } // Get the variant -- cgit v1.2.3-70-g09d2