summaryrefslogtreecommitdiff
path: root/src/game-server
diff options
context:
space:
mode:
Diffstat (limited to 'src/game-server')
-rw-r--r--src/game-server/accountconnection.cpp64
-rw-r--r--src/game-server/accountconnection.h15
-rw-r--r--src/game-server/gamehandler.cpp29
3 files changed, 99 insertions, 9 deletions
diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp
index 927b5c15..874bf3e4 100644
--- a/src/game-server/accountconnection.cpp
+++ b/src/game-server/accountconnection.cpp
@@ -26,6 +26,7 @@
#include "game-server/map.h"
#include "game-server/mapcomposite.h"
#include "game-server/mapmanager.h"
+#include "game-server/item.h"
#include "game-server/itemmanager.h"
#include "game-server/postman.h"
#include "game-server/quest.h"
@@ -158,18 +159,45 @@ void AccountConnection::processMessage(MessageIn &msg)
case AGMSG_ACTIVE_MAP:
{
- int id = msg.readInt16();
- if (MapManager::raiseActive(id))
+ int mapId = msg.readInt16();
+ if (MapManager::raiseActive(mapId))
{
- // set map variables
- MapComposite *m = MapManager::getMap(id);
- while (msg.getUnreadLength())
+ // Set map variables
+ MapComposite *m = MapManager::getMap(mapId);
+ int mapVarsNumber = msg.readInt16();
+ for(int i = 0; i < mapVarsNumber; ++i)
{
std::string key = msg.readString();
std::string value = msg.readString();
if (!key.empty() && !value.empty())
- {
m->setVariableFromDbserver(key, value);
+ }
+
+ // Recreate potential persistent floor items
+ LOG_DEBUG("Recreate persistant items on map " << mapId);
+ int floorItemsNumber = msg.readInt16();
+
+ for(int i = 0; i < floorItemsNumber; i += 4)
+ {
+ int itemId = msg.readInt32();
+ int amount = msg.readInt16();
+ int posX = msg.readInt16();
+ int posY = msg.readInt16();
+
+ if (ItemClass *ic = itemManager->getItem(itemId))
+ {
+ Item *item = new Item(ic, amount);
+ item->setMap(m);
+ Point dst(posX, posY);
+ item->setPosition(dst);
+
+ if (!GameState::insertOrDelete(item))
+ {
+ // The map is full.
+ LOG_WARN("Couldn't add floor item(s) " << itemId
+ << " into map " << mapId);
+ return;
+ }
}
}
}
@@ -466,3 +494,27 @@ void AccountConnection::sendTransaction(int id, int action, const std::string &m
msg.writeString(message);
send(msg);
}
+
+void AccountConnection::createFloorItems(int mapId, int itemId, int amount,
+ int posX, int posY)
+{
+ MessageOut msg(GAMSG_CREATE_ITEM_ON_MAP);
+ msg.writeInt32(mapId);
+ msg.writeInt32(itemId);
+ msg.writeInt16(amount);
+ msg.writeInt16(posX);
+ msg.writeInt16(posY);
+ send(msg);
+}
+
+void AccountConnection::removeFloorItems(int mapId, int itemId, int amount,
+ int posX, int posY)
+{
+ MessageOut msg(GAMSG_REMOVE_ITEM_ON_MAP);
+ msg.writeInt32(mapId);
+ msg.writeInt32(itemId);
+ msg.writeInt16(amount);
+ msg.writeInt16(posX);
+ msg.writeInt16(posY);
+ send(msg);
+}
diff --git a/src/game-server/accountconnection.h b/src/game-server/accountconnection.h
index 4e763158..a144a1d1 100644
--- a/src/game-server/accountconnection.h
+++ b/src/game-server/accountconnection.h
@@ -160,6 +160,21 @@ class AccountConnection : public Connection
void updateOnlineStatus(int charId, bool online);
/**
+ * Adds floor items info on database.
+ *
+ * This is used to make them potentially persistent between two server
+ * restart.
+ */
+ void createFloorItems(int mapId, int itemId, int amount,
+ int posX, int posY);
+
+ /**
+ * Remove floor items from the database
+ */
+ void removeFloorItems(int mapId, int itemId, int amount,
+ int posX, int posY);
+
+ /**
* Send transaction to account server
*/
void sendTransaction(int id, int action, const std::string &message);
diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp
index 92971903..e6c4737f 100644
--- a/src/game-server/gamehandler.cpp
+++ b/src/game-server/gamehandler.cpp
@@ -472,11 +472,22 @@ void GameHandler::handlePickup(GameClient &client, MessageIn &message)
{
Item *item = static_cast< Item * >(o);
ItemClass *ic = item->getItemClass();
+ int amount = item->getAmount();
if (!Inventory(client.character).insert(ic->getDatabaseID(),
- item->getAmount()))
+ amount))
{
-
GameState::remove(item);
+
+ // We only do this when items are to be kept in memory
+ // between two server restart.
+ if (!Configuration::getValue("game_floorItemDecayTime", 0))
+ {
+ // Remove the floor item from map
+ accountHandler->removeFloorItems(map->getID(),
+ ic->getDatabaseID(),
+ amount, x, y);
+ }
+
// log transaction
std::stringstream str;
str << "User picked up item " << ic->getDatabaseID()
@@ -531,8 +542,20 @@ void GameHandler::handleDrop(GameClient &client, MessageIn &message)
delete item;
return;
}
- // log transaction
+
Point pt = client.character->getPosition();
+
+ // We store the item in database only when the floor items are meant
+ // to be persistent between two server restarts.
+ if (!Configuration::getValue("game_floorItemDecayTime", 0))
+ {
+ // Create the floor item on map
+ accountHandler->createFloorItems(client.character->getMap()->getID(),
+ ic->getDatabaseID(),
+ amount, pt.x, pt.y);
+ }
+
+ // log transaction
std::stringstream str;
str << "User dropped item " << ic->getDatabaseID()
<< " at " << pt.x << "x" << pt.y;