diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/defines.h | 7 | ||||
-rw-r--r-- | src/game-server/item.hpp | 13 | ||||
-rw-r--r-- | src/game-server/itemmanager.cpp | 8 | ||||
-rw-r--r-- | src/game-server/itemmanager.hpp | 3 | ||||
-rw-r--r-- | src/game-server/mapcomposite.cpp | 35 | ||||
-rw-r--r-- | src/game-server/mapcomposite.hpp | 15 | ||||
-rw-r--r-- | src/game-server/state.cpp | 24 | ||||
-rw-r--r-- | src/game-server/testing.cpp | 10 |
8 files changed, 103 insertions, 12 deletions
diff --git a/src/defines.h b/src/defines.h index ba2ba4af..b6479d2c 100644 --- a/src/defines.h +++ b/src/defines.h @@ -144,15 +144,16 @@ enum { GPMSG_BEING_LEAVE = 0x0201, // W being id PGMSG_WALK = 0x0260, // W*2 destination GPMSG_BEINGS_MOVE = 0x0280, // { W being id, B flags [, C position] [, W*2 destination] }* - PGMSG_SAY = 0x02A0, // S text - GPMSG_SAY = 0x02A1, // W being id, S text + GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }* PGMSG_ATTACK = 0x0290, // B direction GPMSG_BEING_ATTACK = 0x0291, // W being id + PGMSG_SAY = 0x02A0, // S text + GPMSG_SAY = 0x02A1, // W being id, S text PGMSG_USE_ITEM = 0x0300, // L item id GPMSG_USE_RESPONSE = 0x0301, // B error PGMSG_EQUIP = 0x0302, // L item id, B slot GPMSG_EQUIP_RESPONSE = 0x0303, // B error - GPMSG_BEINGS_DAMAGE = 0x0310, // { W being id, W ammount }* + GPMSG_BEINGS_DAMAGE = 0x0310, // { W being id, W amount }* // Chat CPMSG_ERROR = 0x0401, // B error diff --git a/src/game-server/item.hpp b/src/game-server/item.hpp index 283e685c..9d2ebb72 100644 --- a/src/game-server/item.hpp +++ b/src/game-server/item.hpp @@ -129,8 +129,8 @@ struct Modifiers class ItemClass { public: - ItemClass(int type) - : mType(type) + ItemClass(int id, int type) + : mDatabaseID(id), mType(type) {} /** @@ -199,6 +199,12 @@ class ItemClass void setScriptName(std::string const &name) { mScriptName = name; } + /** + * Gets database ID. + */ + int getDatabaseID() + { return mDatabaseID; } + private: /** @@ -207,6 +213,7 @@ class ItemClass bool runScript(Being *itemUser); // Item reference information + unsigned short mDatabaseID; unsigned char mType; /**< Type: usable, equipment. */ unsigned short mWeight; /**< Weight of the item. */ unsigned short mCost; /**< Unit cost the item. */ @@ -225,6 +232,8 @@ class Item: public Object ItemClass *getItemClass() const { return mType; } + virtual void update() {} + private: ItemClass *mType; }; diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp index f4a5b751..08adb9de 100644 --- a/src/game-server/itemmanager.cpp +++ b/src/game-server/itemmanager.cpp @@ -101,7 +101,7 @@ ItemManager::ItemManager(std::string const &itemReferenceFile) modifiers.weaponType = XML::getProperty(node, "weapon_type", 0); modifiers.beingStateEffect = XML::getProperty(node, "status_effect", 0); - ItemClass *item = new ItemClass(itemType); + ItemClass *item = new ItemClass(id, itemType); item->setWeight(weight); item->setCost(value); item->setMaxPerSlot(maxPerSlot); @@ -157,3 +157,9 @@ ItemManager::ItemManager(std::string const &itemReferenceFile) xmlFreeDoc(doc); } + +ItemClass *ItemManager::getItem(int itemId) const +{ + std::map< int, ItemClass * >::const_iterator i = mItemReference.find(itemId); + return i != mItemReference.end() ? i->second : NULL; +} diff --git a/src/game-server/itemmanager.hpp b/src/game-server/itemmanager.hpp index 64bf5ae2..a144fa87 100644 --- a/src/game-server/itemmanager.hpp +++ b/src/game-server/itemmanager.hpp @@ -43,8 +43,7 @@ class ItemManager /** * Gives an Item having the demanded information. */ - ItemClass *getItem(int itemId) - { return mItemReference[itemId]; }; + ItemClass *getItem(int itemId) const; private: std::map< int, ItemClass * > mItemReference; /**< Item reference */ diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index 21648bc1..2ccee600 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -210,6 +210,33 @@ void MovingObjectIterator::operator++() } } +FixedObjectIterator::FixedObjectIterator(ZoneIterator const &it) + : iterator(it), pos(0) +{ + while (iterator && (*iterator)->nbMovingObjects == (*iterator)->objects.size()) ++iterator; + if (iterator) + { + pos = (*iterator)->nbMovingObjects; + current = (*iterator)->objects[pos]; + } +} + +void FixedObjectIterator::operator++() +{ + if (++pos == (*iterator)->objects.size()) + { + do ++iterator; while (iterator && (*iterator)->nbMovingObjects == (*iterator)->objects.size()); + if (iterator) + { + pos = (*iterator)->nbMovingObjects; + } + } + if (iterator) + { + current = (*iterator)->objects[pos]; + } +} + ObjectIterator::ObjectIterator(ZoneIterator const &it) : iterator(it), pos(0) { @@ -355,8 +382,8 @@ void MapComposite::fillRegion(MapRegion &r, Point const &p, int radius) const { int ax = p.x > radius ? (p.x - radius) / zoneDiam : 0, ay = p.y > radius ? (p.y - radius) / zoneDiam : 0, - bx = std::max((p.x + radius) / zoneDiam, mapWidth - 1), - by = std::max((p.y + radius) / zoneDiam, mapHeight - 1); + bx = std::min((p.x + radius) / zoneDiam, mapWidth - 1), + by = std::min((p.y + radius) / zoneDiam, mapHeight - 1); for (int y = ay; y <= by; ++y) { for (int x = ax; x <= bx; ++x) @@ -370,8 +397,8 @@ void MapComposite::fillRegion(MapRegion &r, Rectangle const &p) const { int ax = p.x / zoneDiam, ay = p.y / zoneDiam, - bx = std::max((p.x + p.w) / zoneDiam, mapWidth - 1), - by = std::max((p.y + p.h) / zoneDiam, mapHeight - 1); + bx = std::min((p.x + p.w) / zoneDiam, mapWidth - 1), + by = std::min((p.y + p.h) / zoneDiam, mapHeight - 1); for (int y = ay; y <= by; ++y) { for (int x = ax; x <= bx; ++x) diff --git a/src/game-server/mapcomposite.hpp b/src/game-server/mapcomposite.hpp index 1996950e..0eae7d91 100644 --- a/src/game-server/mapcomposite.hpp +++ b/src/game-server/mapcomposite.hpp @@ -112,6 +112,21 @@ struct MovingObjectIterator }; /** + * Iterates through the non-moving Objects of a region. + */ +struct FixedObjectIterator +{ + ZoneIterator iterator; + unsigned short pos; + Object *current; + + FixedObjectIterator(ZoneIterator const &); + void operator++(); + Object *operator*() const { return current; } + operator bool() const { return iterator; } +}; + +/** * Iterates through the Objects of a region. */ struct ObjectIterator diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index 4fe48b9b..90243742 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -29,6 +29,7 @@ #include "point.h" #include "game-server/accountconnection.hpp" #include "game-server/gamehandler.hpp" +#include "game-server/item.hpp" #include "game-server/map.hpp" #include "game-server/mapcomposite.hpp" #include "game-server/mapmanager.hpp" @@ -201,6 +202,29 @@ void State::informPlayer(MapComposite *map, Player *p) if (damageMsg.getLength() > 2) gameHandler->sendTo(p, damageMsg); + + MessageOut itemMsg(GPMSG_ITEMS); + for (FixedObjectIterator i(map->getAroundPlayerIterator(p, AROUND_AREA)); i; ++i) + { + assert((*i)->getType() == OBJECT_ITEM); + Item *o = static_cast< Item * >(*i); + Point opos = o->getPosition(); + int oflags = o->getUpdateFlags(); + bool willBeInRange = ppos.inRangeOf(opos, AROUND_AREA); + bool wereInRange = pold.inRangeOf(opos, AROUND_AREA) && + !((pflags | oflags) & NEW_ON_MAP); + + if (willBeInRange ^ wereInRange) + { + itemMsg.writeShort(willBeInRange ? o->getItemClass()->getDatabaseID() : 0); + itemMsg.writeShort(opos.x); + itemMsg.writeShort(opos.y); + } + } + + // Do not send a packet if nothing happened in p's range. + if (itemMsg.getLength() > 2) + gameHandler->sendTo(p, itemMsg); } void State::update() diff --git a/src/game-server/testing.cpp b/src/game-server/testing.cpp index e580694d..2565f3ec 100644 --- a/src/game-server/testing.cpp +++ b/src/game-server/testing.cpp @@ -2,7 +2,10 @@ to the game. It should be removed once all the related managers have been implemented. There are no headers for this file on purpose. */ +#include <cassert> + #include "controller.h" +#include "game-server/itemmanager.hpp" #include "game-server/state.hpp" #include "game-server/trigger.hpp" @@ -27,6 +30,13 @@ void testingMap(int id) being->setPosition(pos); gameState->insert(being); } + ItemClass *ic = itemManager->getItem(508); + assert(ic); + Item *i = new Item(ic); + i->setMapId(1); + Point pos = { 58 * 32 + 16, 20 * 32 + 16 }; + i->setPosition(pos); + gameState->insert(i); } break; case 3: |