summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-01-03 22:34:40 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-01-03 22:34:40 +0000
commit36eb5ac7f856dc83242837738eb18cfd9039352f (patch)
tree89ebfae081d2207e68dc04b52e4558b3a316834f
parent282ca19e33b79f4468ce6402406ddb1397f2d115 (diff)
downloadmanaserv-36eb5ac7f856dc83242837738eb18cfd9039352f.tar.gz
manaserv-36eb5ac7f856dc83242837738eb18cfd9039352f.tar.bz2
manaserv-36eb5ac7f856dc83242837738eb18cfd9039352f.tar.xz
manaserv-36eb5ac7f856dc83242837738eb18cfd9039352f.zip
Added a Xmas cake: the server now supports items on floor.
-rw-r--r--ChangeLog6
-rw-r--r--src/defines.h7
-rw-r--r--src/game-server/item.hpp13
-rw-r--r--src/game-server/itemmanager.cpp8
-rw-r--r--src/game-server/itemmanager.hpp3
-rw-r--r--src/game-server/mapcomposite.cpp35
-rw-r--r--src/game-server/mapcomposite.hpp15
-rw-r--r--src/game-server/state.cpp24
-rw-r--r--src/game-server/testing.cpp10
9 files changed, 109 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 45f40698..9a194e20 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -42,6 +42,12 @@
* src/game-server/being.hpp: Removed counted pointers.
* src/game-server/mapcomposite.hpp, src/game-server/mapcomposite.cpp,
src/game-server/being.cpp: Fixed end of lines.
+ * src/game-server/mapcomposite.hpp, src/game-server/mapcomposite.cpp:
+ Fixed pessimistic bounds on region iterators. Added an iterator for
+ non-moving objects.
+ * src/defines.h, src/game-server/state.cpp: Added code to send data on
+ floor items to clients.
+ * src/game-server/testing.cpp: Added a Xmas cake for testing purpose.
2007-01-02 Guillaume Melquiond <guillaume.melquiond@gmail.com>
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: