diff options
Diffstat (limited to 'src/game-server')
-rw-r--r-- | src/game-server/accountconnection.cpp | 64 | ||||
-rw-r--r-- | src/game-server/accountconnection.h | 15 | ||||
-rw-r--r-- | src/game-server/gamehandler.cpp | 29 |
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; |