From a246c08cef5e4d598fc07a681eb971bfbcf01519 Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Fri, 7 Oct 2005 00:12:32 +0000 Subject: Modified finding NPC as by timonator's suggestion in order to allow NPCs to be clicked on their heads too. Also made start to tile engine improvement by adding the Sprite class that is now used by the floor items for being displayed on the map. Finally added documentation to Item class and splitted out Properties class from Map. --- src/Makefile.am | 4 +- src/being.cpp | 13 ++- src/engine.cpp | 15 +--- src/engine.h | 2 +- src/floor_item.cpp | 72 ++++++++++++--- src/floor_item.h | 39 ++++---- src/game.cpp | 2 +- src/gui/gui.cpp | 19 ++-- src/item.cpp | 16 ---- src/item.h | 185 ++++++++++++++++++++------------------ src/map.cpp | 49 ++++++---- src/map.h | 31 ++++--- src/properties.h | 84 +++++++++++++++++ src/resources/itemmanager.cpp | 10 ++- src/resources/resourcemanager.cpp | 2 - src/sprite.h | 76 ++++++++++++++++ 16 files changed, 425 insertions(+), 194 deletions(-) create mode 100644 src/properties.h create mode 100644 src/sprite.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 0cf92c0f..25f60cf7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -172,9 +172,11 @@ tmw_SOURCES = graphic/spriteset.cpp \ openglgraphics.cpp\ openglgraphics.h \ playerinfo.h \ + properties.h \ serverinfo.h \ sound.cpp \ - sound.h + sound.h \ + sprite.h # set the include path found by configure INCLUDES = \ diff --git a/src/being.cpp b/src/being.cpp index 4301b0a9..5cdd8c01 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -118,7 +118,11 @@ Being *findNode(Uint16 x, Uint16 y) for (i = beings.begin(); i != beings.end(); i++) { Being *being = (*i); // Return being if found and it is not a dead monster - if (being->x == x && being->y == y && being->action != Being::MONSTER_DEAD) { + if (being->x == x && + (being->y == y || + (being->getType() == Being::NPC && being->y == y + 1)) && + being->action != Being::MONSTER_DEAD) + { return being; } } @@ -131,8 +135,11 @@ Being* findNode(Uint16 x, Uint16 y, Being::Type type) for (i = beings.begin(); i != beings.end(); i++) { Being *being = (*i); // Check if is a NPC (only low job ids) - if (being->x == x && being->y == y && - being->getType() == type && being->action != Being::MONSTER_DEAD) + if (being->x == x && + (being->y == y || + (being->getType() == Being::NPC && being->y == y + 1)) && + being->getType() == type && + being->action != Being::MONSTER_DEAD) { return being; } diff --git a/src/engine.cpp b/src/engine.cpp index 1dd7c752..4d934504 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -65,6 +65,7 @@ gcn::Label *debugInfo; std::map monsterset; ItemManager *itemDb; /**< Item database object */ +Spriteset *itemset; char hairtable[16][4][2] = { // S(x,y) W(x,y) N(x,y) E(x,y) @@ -294,20 +295,6 @@ void Engine::draw() mCurrentMap->draw(graphics, map_x, map_y, 1); } - // Draw items - for (std::list::iterator i = floorItems.begin(); i != floorItems.end(); i++) - { - FloorItem *floorItem = (*i); - if (itemDb->getItemInfo(floorItem->getItemId())->getImage() > 0) { - Image *image = itemset->spriteset[itemDb->getItemInfo( - floorItem->getItemId())->getImage() - 1]; - - graphics->drawImage(image, - floorItem->getX() * 32 - map_x, - floorItem->getY() * 32 - map_y); - } - } - // Draw nodes for (std::list::iterator i = beings.begin(); i != beings.end(); i++) { diff --git a/src/engine.h b/src/engine.h index 03b33b5e..49a307f5 100644 --- a/src/engine.h +++ b/src/engine.h @@ -69,7 +69,7 @@ class Engine void draw(); private: - Spriteset *emotionset, *npcset, *weaponset, *itemset; + Spriteset *emotionset, *npcset, *weaponset; Map *mCurrentMap; Image *attackTarget; }; diff --git a/src/floor_item.cpp b/src/floor_item.cpp index 691c5acd..a1b83a75 100755 --- a/src/floor_item.cpp +++ b/src/floor_item.cpp @@ -22,14 +22,52 @@ */ #include "floor_item.h" +#include "sprite.h" +#include "graphic/spriteset.h" +#include "resources/itemmanager.h" +#include "resources/iteminfo.h" #include -std::list floorItems; +extern Spriteset *itemset; + +typedef std::list FloorItems; +FloorItems floorItems; + +FloorItem::FloorItem(unsigned int id, + unsigned int itemId, + unsigned short x, + unsigned short y, + Map *map): + mId(id), + mItemId(itemId), + mX(x), + mY(y), + mMap(map) +{ + // Retrieve item image using a global itemset and itemDb (alternative?) + Image *image = itemset->spriteset[ + itemDb->getItemInfo(itemId)->getImage() - 1]; + + // Create the sprite representing this floor item + mSprite = new Sprite(mX * map->getTileWidth(), + mY * map->getTileHeight(), + image); + + // Add the representative sprite to the map + mSpriteIterator = mMap->addSprite(mSprite); +} + +FloorItem::~FloorItem() +{ + // Remove and delete the representative sprite + mMap->removeSprite(mSpriteIterator); + delete mSprite; +} void empty_floor_items() { - std::list::iterator i; + FloorItems::iterator i; for (i = floorItems.begin(); i != floorItems.end(); i++) { delete (*i); } @@ -41,11 +79,14 @@ void add_floor_item(FloorItem *floorItem) floorItems.push_back(floorItem); } -void remove_floor_item(unsigned int int_id) +void remove_floor_item(unsigned int id) { - std::list::iterator i; - for (i = floorItems.begin(); i != floorItems.end(); i++) { - if ((*i)->getId() == int_id) { + FloorItems::iterator i; + + for (i = floorItems.begin(); i != floorItems.end(); i++) + { + if ((*i)->getId() == id) + { delete (*i); floorItems.erase(i); return; @@ -55,25 +96,34 @@ void remove_floor_item(unsigned int int_id) unsigned int find_floor_item_by_cor(unsigned short x, unsigned short y) { - std::list::iterator i; - for (i = floorItems.begin(); i != floorItems.end(); i++) { + FloorItems::iterator i; + + for (i = floorItems.begin(); i != floorItems.end(); i++) + { FloorItem *floorItem = (*i); + if (floorItem->getX() == x && floorItem->getY() == y) { return floorItem->getId(); } } + return 0; } FloorItem *find_floor_item_by_id(unsigned int int_id) { - std::list::iterator i; - for (i = floorItems.begin(); i != floorItems.end(); i++) { + FloorItems::iterator i; + + for (i = floorItems.begin(); i != floorItems.end(); i++) + { FloorItem *floorItem = (*i); - if (floorItem->getId() == int_id) { + + if (floorItem->getId() == int_id) + { return floorItem; } } + return NULL; } diff --git a/src/floor_item.h b/src/floor_item.h index cd3293b4..5563da24 100755 --- a/src/floor_item.h +++ b/src/floor_item.h @@ -21,8 +21,12 @@ * $Id$ */ -#ifndef _TMW_FLOORITEM_H -#define _TMW_FLOORITEM_H +#ifndef _TMW_FLOORITEM_H_ +#define _TMW_FLOORITEM_H_ + +class Map; + +#include "map.h" /** * An item lying on the floor. @@ -36,38 +40,41 @@ class FloorItem FloorItem(unsigned int id, unsigned int itemId, unsigned short x, - unsigned short y): - id(itemId), - int_id(id), - x(x), - y(y) - { - } + unsigned short y, + Map *map); + + /** + * Destructor. + */ + ~FloorItem(); /** * Returns instance id of this item. */ - unsigned int getId() { return int_id; } + unsigned int getId() { return mId; } /** * Returns the item id. */ - unsigned int getItemId() { return id; } + unsigned int getItemId() { return mItemId; } /** * Returns the x coordinate. */ - unsigned short getX() { return x; } + unsigned short getX() { return mX; } /** * Returns the y coordinate. */ - unsigned short getY() { return y; } + unsigned short getY() { return mY; } private: - unsigned int id; - unsigned int int_id; - unsigned short x, y; + unsigned int mId; + unsigned int mItemId; + unsigned short mX, mY; + Sprite *mSprite; + Sprites::iterator mSpriteIterator; + Map *mMap; }; /** Removes all items from the list */ diff --git a/src/game.cpp b/src/game.cpp index 5c220155..51848441 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1859,7 +1859,7 @@ void do_parse() Uint16 y = msg.readShort(); msg.skip(4); // amount,subX,subY / subX,subY,amount - add_floor_item(new FloorItem(id, itemId, x, y)); + add_floor_item(new FloorItem(id, itemId, x, y, tiledMap)); } break; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 48cbd522..365d8eba 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -192,7 +192,8 @@ Gui::~Gui() delete guiInput; } -void Gui::logic() +void +Gui::logic() { gcn::Gui::logic(); @@ -201,7 +202,8 @@ void Gui::logic() mFocusHandler->applyChanges(); } -void Gui::draw() +void +Gui::draw() { mGraphics->pushClipArea(mTop->getDimension()); mTop->draw(mGraphics); @@ -212,19 +214,24 @@ void Gui::draw() if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS || button & SDL_BUTTON(1)) && mCustomCursor) { - dynamic_cast(mGraphics)->drawImage(mMouseCursor, mouseX - 5, mouseY - 2); + dynamic_cast(mGraphics)->drawImage(mMouseCursor, + mouseX - 5, + mouseY - 2); } mGraphics->popClipArea(); } -void Gui::mousePress(int mx, int my, int button) +void +Gui::mousePress(int mx, int my, int button) { // Mouse pressed on window container (basically, the map) // When conditions for walking are met, set new player destination - if (player_node && player_node->action != Being::DEAD && current_npc == 0 && - button == gcn::MouseInput::LEFT) + if (player_node && + player_node->action != Being::DEAD && + current_npc == 0 && + button == gcn::MouseInput::LEFT) { Map *tiledMap = engine->getCurrentMap(); int tilex = mx / 32 + camera_x; diff --git a/src/item.cpp b/src/item.cpp index e49de630..3cea30e5 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -21,19 +21,3 @@ * $Id$ */ -#include "item.h" -#include "resources/itemmanager.h" - -Item::Item(int id, int quantity, bool equipment, bool equipped): - id(id), quantity(quantity), equipment(equipment), equipped(equipped) -{ -} - -Item::~Item() -{ -} - -ItemInfo* Item::getInfo() -{ - return itemDb->getItemInfo(id); -} diff --git a/src/item.h b/src/item.h index 0a5fc31e..c4b53ad1 100644 --- a/src/item.h +++ b/src/item.h @@ -21,99 +21,112 @@ * $Id$ */ -#ifndef _ITEM_H -#define _ITEM_H +#ifndef _ITEM_H_ +#define _ITEM_H_ -class ItemInfo; +#include "resources/itemmanager.h" +/** + * Represents one or more instances of a certain item type. + */ class Item { public: - Item(int id=-1, int quantity=0, - bool equipment=false, bool equipped=false); - - ~Item(); - - void setId(int id); - int getId(); - - void setQuantity(int quantity); - void increaseQuantity(int amount); - int getQuantity(); - - void setEquipment(bool equipment); - bool isEquipment(); - - void setEquipped(bool equipped); - bool isEquipped(); - - int getInvIndex(); - void setInvIndex(int index); - - ItemInfo* getInfo(); + /** + * Constructor. + */ + Item(int id = -1, int quantity = 0, + bool equipment = false, bool equipped = false): + mId(id), + mQuantity(quantity), + mEquipment(equipment), + mEquipped(equipped) + { + } + + /** + * Destructor. + */ + ~Item() {} + + /** + * Sets the item id, identifying the item type. + */ + void + setId(int id) { mId = id; } + + /** + * Returns the item id. + */ + int + getId() const { return mId; } + + /** + * Sets the number of items. + */ + void + setQuantity(int quantity) { mQuantity = quantity; } + + /** + * Increases the number of items by the given amount. + */ + void + increaseQuantity(int amount) { mQuantity += amount; } + + /** + * Returns the number of items. + */ + int + getQuantity() const { return mQuantity; } + + /** + * Sets wether this item is considered equipment. + */ + void + setEquipment(bool equipment) { mEquipment = equipment; } + + /** + * Returns wether this item is considered equipment. + */ + bool + isEquipment() const { return mEquipment; } + + /** + * Sets wether this item is equipped. + */ + void + setEquipped(bool equipped) { mEquipped = equipped; } + + /** + * Returns wether this item is equipped. + */ + bool + isEquipped() const { return mEquipped; } + + /** + * Sets the inventory index of this item. + */ + void + setInvIndex(int index) { mInvIndex = index; } + + /** + * Returns the inventory index of this item. + */ + int + getInvIndex() const { return mInvIndex; } + + /** + * Returns information about this item type. + */ + ItemInfo* + getInfo() const { return itemDb->getItemInfo(mId); } protected: - int id; - int quantity; - bool equipment; - bool equipped; - - int invIndex; + int mId; /**< Item type id. */ + int mQuantity; /**< Number of items. */ + bool mEquipment; /**< Item is equipment. */ + bool mEquipped; /**< Item is equipped. */ + int mInvIndex; /**< Inventory index. */ }; -inline void Item::setId(int id) -{ - this->id = id; -} - -inline int Item::getId() -{ - return id; -} - -inline void Item::setQuantity(int quantity) -{ - this->quantity = quantity; -} - -inline void Item::increaseQuantity(int amount) -{ - this->quantity += amount; -} - -inline int Item::getQuantity() -{ - return quantity; -} - -inline void Item::setEquipment(bool equipment) -{ - this->equipment = equipment; -} - -inline bool Item::isEquipment() -{ - return equipment; -} - -inline void Item::setEquipped(bool equipped) -{ - this->equipped = equipped; -} - -inline bool Item::isEquipped() -{ - return equipped; -} - -inline int Item::getInvIndex() -{ - return invIndex; -} - -inline void Item::setInvIndex(int index) -{ - this->invIndex = index; -} - #endif diff --git a/src/map.cpp b/src/map.cpp index 583a01be..3237b54a 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -26,6 +26,7 @@ #include "being.h" #include "graphics.h" #include "resources/image.h" +#include "sprite.h" #include @@ -85,9 +86,22 @@ Map::addTileset(Tileset *tileset) tilesets.push_back(tileset); } +bool spriteCompare(const Sprite *a, const Sprite *b) +{ + return a->getY() < b->getY(); +} + void Map::draw(Graphics *graphics, int scrollX, int scrollY, int layer) { + // If drawing the fringe layer, make sure sprites are sorted + Sprites::iterator si; + if (layer == 1) + { + mSprites.sort(spriteCompare); + si = mSprites.begin(); + } + int startX = scrollX / 32; int startY = scrollY / 32; int endX = (graphics->getWidth() + scrollX + 31) / 32; @@ -100,6 +114,17 @@ Map::draw(Graphics *graphics, int scrollX, int scrollY, int layer) for (int y = startY; y < endY; y++) { + // If drawing the fringe layer, make sure all sprites above this row of + // tiles have been drawn + if (layer == 1) + { + while (si != mSprites.end() && (*si)->getY() < y * 32) + { + (*si)->draw(graphics, -scrollX, -scrollY); + si++; + } + } + for (int x = startX; x < endX; x++) { Image *img = getTile(x, y, layer); @@ -220,29 +245,17 @@ Map::getMetaTile(int x, int y) return &metaTiles[x + y * mWidth]; } -std::string -Map::getProperty(const std::string &name) -{ - std::map::iterator i = properties.find(name); - - if (i != properties.end()) - { - return (*i).second; - } - - return ""; -} - -bool -Map::hasProperty(const std::string &name) +Sprites::iterator +Map::addSprite(Sprite *sprite) { - return (properties.find(name) != properties.end()); + mSprites.push_front(sprite); + return mSprites.begin(); } void -Map::setProperty(const std::string &name, const std::string &value) +Map::removeSprite(Sprites::iterator iterator) { - properties[name] = value; + mSprites.erase(iterator); } std::list diff --git a/src/map.h b/src/map.h index 7e0389d9..18278c20 100644 --- a/src/map.h +++ b/src/map.h @@ -21,20 +21,25 @@ * $Id$ */ -#ifndef _TMW_MAP_H -#define _TMW_MAP_H +#ifndef _TMW_MAP_H_ +#define _TMW_MAP_H_ #include #include #include +#include "properties.h" class Being; class Graphics; class Image; class Tileset; +class Sprite; struct PATH_NODE; +typedef std::vector Tilesets; +typedef std::list Sprites; + /** * A meta tile stores additional information about a location on a tile map. * This is information that doesn't need to be repeated for each tile in each @@ -81,7 +86,7 @@ class Location /** * A tile map. */ -class Map +class Map : public Properties { public: /** @@ -178,22 +183,16 @@ class Map findPath(int startX, int startY, int destX, int destY); /** - * Get a map property. - * - * @return the value of the given property or an empty string when it - * doesn't exist. + * Adds a sprite to the map. */ - std::string getProperty(const std::string &name); + Sprites::iterator + addSprite(Sprite *sprite); /** - * Returns whether a certain property is available. + * Removes a sprite from the map. */ - bool hasProperty(const std::string &name); - - /** - * Set a map property. - */ - void setProperty(const std::string &name, const std::string &value); + void + removeSprite(Sprites::iterator iterator); private: /** @@ -215,8 +214,8 @@ class Map Image **tiles; std::map properties; - typedef std::vector Tilesets; Tilesets tilesets; + Sprites mSprites; // Pathfinding members int onClosedList, onOpenList; diff --git a/src/properties.h b/src/properties.h new file mode 100644 index 00000000..ccf8cd00 --- /dev/null +++ b/src/properties.h @@ -0,0 +1,84 @@ +/* + * The Mana World + * 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 _TMW_PROPERTIES_H_ +#define _TMW_PROPERTIES_H_ + +#include +#include + +/** + * A class holding a set of properties. + */ +class Properties +{ + public: + virtual + ~Properties() {} + + /** + * Get a map property. + * + * @return the value of the given property or an empty string when it + * doesn't exist. + */ + const std::string& + getProperty(const std::string &name) + { + const static std::string undefined = ""; + std::map::const_iterator i = + properties.find(name); + + if (i != properties.end()) + { + return (*i).second; + } + else + { + return undefined; + } + } + + /** + * Returns whether a certain property is available. + */ + bool + hasProperty(const std::string &name) + { + return (properties.find(name) != properties.end()); + } + + /** + * Set a map property. + */ + void + setProperty(const std::string &name, const std::string &value) + { + properties[name] = value; + } + + private: + std::map properties; +}; + +#endif diff --git a/src/resources/itemmanager.cpp b/src/resources/itemmanager.cpp index caa26f5b..6fac63fd 100644 --- a/src/resources/itemmanager.cpp +++ b/src/resources/itemmanager.cpp @@ -20,7 +20,7 @@ * * $Id$ */ - + #include #include "iteminfo.h" @@ -126,11 +126,15 @@ ItemManager::~ItemManager() delete unknown; } -ItemInfo *ItemManager::getItemInfo(int id) +ItemInfo* +ItemManager::getItemInfo(int id) { if (db.find(id) != db.end()) + { return db[id]; + } else + { return unknown; + } } - diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index 4a8a010a..e9595093 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -31,7 +31,6 @@ #include "soundeffect.h" #include "../log.h" -#include "../gui/button.h" ResourceManager *ResourceManager::instance = NULL; @@ -50,7 +49,6 @@ ResourceManager::~ResourceManager() { Resource *res = resources.begin()->second; std::string id = res->getIdPath(); - int references = 0; do { diff --git a/src/sprite.h b/src/sprite.h new file mode 100644 index 00000000..97851138 --- /dev/null +++ b/src/sprite.h @@ -0,0 +1,76 @@ +/* + * The Mana World + * 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 _TMW_SPRITE_H_ +#define _TMW_SPRITE_H_ + +#include "graphics.h" + +/** + * A sprite is some visible object on a map. + */ +class Sprite +{ + public: + /** + * Constructor. + */ + Sprite(int x = 0, int y = 0, Image *image = NULL): + mX(x), + mY(y), + mImage(image) + { + } + + /** + * Draws the sprite to the given graphics context. + * + * Note: this function could be simplified if the graphics context + * would support setting a translation offset. It already does this + * partly with the clipping rectangle support. + */ + void + draw(Graphics *graphics, int offsetX, int offsetY) + { + graphics->drawImage(mImage, mX + offsetX, mY + offsetY); + } + + /** + * Returns the X coordinate of the sprite. + */ + int + getY() const { return mY; } + + /** + * Returns the Y coordinate of the sprite. + */ + int + getX() const { return mX; } + + private: + int mX; /**< X coordinate in pixels. */ + int mY; /**< Y coordinate in pixels. */ + Image *mImage; /**< The image currently representing this sprite. */ +}; + +#endif -- cgit v1.2.3-70-g09d2