diff options
author | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-10-19 23:55:30 +0200 |
---|---|---|
committer | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-10-19 23:55:30 +0200 |
commit | 8629addec23239b667295c68ee3061ebc4ca918d (patch) | |
tree | 067f2969ea12053e5636dbb6035def59c32b01a2 /src | |
parent | 77ea3d90114a7d6503d19e89ffaf2e548f63e420 (diff) | |
parent | 03ff7c110e536de1f8b239817e50cb07c492da6f (diff) | |
download | manaserv-8629addec23239b667295c68ee3061ebc4ca918d.tar.gz manaserv-8629addec23239b667295c68ee3061ebc4ca918d.tar.bz2 manaserv-8629addec23239b667295c68ee3061ebc4ca918d.tar.xz manaserv-8629addec23239b667295c68ee3061ebc4ca918d.zip |
Merge branch 'master' of github.com:mana/manaserv
Conflicts:
src/game-server/accountconnection.cpp
Diffstat (limited to 'src')
-rw-r--r-- | src/account-server/main-account.cpp | 19 | ||||
-rw-r--r-- | src/chat-server/chathandler.cpp | 8 | ||||
-rw-r--r-- | src/game-server/accountconnection.cpp | 15 | ||||
-rw-r--r-- | src/game-server/being.cpp | 12 | ||||
-rw-r--r-- | src/game-server/main-game.cpp | 19 | ||||
-rw-r--r-- | src/game-server/map.cpp | 10 | ||||
-rw-r--r-- | src/game-server/map.h | 63 | ||||
-rw-r--r-- | src/game-server/mapcomposite.cpp | 207 | ||||
-rw-r--r-- | src/game-server/mapcomposite.h | 27 | ||||
-rw-r--r-- | src/game-server/mapmanager.cpp | 21 | ||||
-rw-r--r-- | src/game-server/mapmanager.h | 3 | ||||
-rw-r--r-- | src/game-server/mapreader.cpp | 276 | ||||
-rw-r--r-- | src/game-server/mapreader.h | 13 | ||||
-rw-r--r-- | src/scripting/lua.cpp | 150 | ||||
-rw-r--r-- | src/scripting/luautil.cpp | 5 | ||||
-rw-r--r-- | src/scripting/luautil.h | 5 | ||||
-rw-r--r-- | src/utils/logger.cpp | 17 | ||||
-rw-r--r-- | src/utils/logger.h | 4 |
18 files changed, 493 insertions, 381 deletions
diff --git a/src/account-server/main-account.cpp b/src/account-server/main-account.cpp index 6d46ec49..0adf1285 100644 --- a/src/account-server/main-account.cpp +++ b/src/account-server/main-account.cpp @@ -141,14 +141,7 @@ static void initialize() // Initialize PhysicsFS PHYSFS_init(""); - // Initialize the logger. - Logger::setLogFile(logFile, true); - - // Write the messages to both the screen and the log file. - Logger::setTeeMode( - Configuration::getBoolValue("log_accountToStandardOutput", - true)); - LOG_INFO("Using log file: " << logFile); + Logger::initialize(logFile); // Indicate in which file the statistics are put. statisticsFile = Configuration::getValue("log_statisticsFile", @@ -156,16 +149,6 @@ static void initialize() LOG_INFO("Using statistics file: " << statisticsFile); - // Set up the options related to log rotation. - Logger::enableLogRotation(Configuration::getBoolValue("log_enableRotation", - false)); - - Logger::setMaxLogfileSize(Configuration::getValue("log_maxFileSize", - 1024)); - - Logger::setSwitchLogEachDay(Configuration::getBoolValue("log_perDay", - false)); - ResourceManager::initialize(); // Open database diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp index 3f11d71d..e7ef11d2 100644 --- a/src/chat-server/chathandler.cpp +++ b/src/chat-server/chathandler.cpp @@ -350,14 +350,6 @@ void ChatHandler::handlePrivMsgMessage(ChatClient &client, MessageIn &msg) // We seek the player to whom the message is told and send it to her/him. sayToPlayer(client, user, text); - - // log transaction - Transaction trans; - trans.mCharacterId = client.characterId; - trans.mAction = TRANS_MSG_PRIVATE; - trans.mMessage = "User said " + text; - trans.mMessage.append(" to " + user); - storage->addTransaction(trans); } void ChatHandler::handleWhoMessage(ChatClient &client) diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp index 874bf3e4..36f30f33 100644 --- a/src/game-server/accountconnection.cpp +++ b/src/game-server/accountconnection.cpp @@ -160,7 +160,7 @@ void AccountConnection::processMessage(MessageIn &msg) case AGMSG_ACTIVE_MAP: { int mapId = msg.readInt16(); - if (MapManager::raiseActive(mapId)) + if (MapManager::activateMap(mapId)) { // Set map variables MapComposite *m = MapManager::getMap(mapId); @@ -288,7 +288,8 @@ void AccountConnection::playerReconnectAccount(int id, send(msg); } -void AccountConnection::requestCharacterVar(Character *ch, const std::string &name) +void AccountConnection::requestCharacterVar(Character *ch, + const std::string &name) { MessageOut msg(GAMSG_GET_VAR_CHR); msg.writeInt32(ch->getDatabaseID()); @@ -296,8 +297,9 @@ void AccountConnection::requestCharacterVar(Character *ch, const std::string &na send(msg); } -void AccountConnection::updateCharacterVar(Character *ch, const std::string &name, - const std::string &value) +void AccountConnection::updateCharacterVar(Character *ch, + const std::string &name, + const std::string &value) { MessageOut msg(GAMSG_SET_VAR_CHR); msg.writeInt32(ch->getDatabaseID()); @@ -306,8 +308,9 @@ void AccountConnection::updateCharacterVar(Character *ch, const std::string &nam send(msg); } -void AccountConnection::updateMapVar(MapComposite *map, const std::string &name, - const std::string &value) +void AccountConnection::updateMapVar(MapComposite *map, + const std::string &name, + const std::string &value) { MessageOut msg(GAMSG_SET_VAR_MAP); msg.writeInt32(map->getID()); diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index 4058a4ad..fd9f8fe4 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -192,11 +192,11 @@ void Being::setDestination(const Point &dst) Path Being::findPath() { - mOld = getPosition(); Map *map = getMap()->getMap(); int tileWidth = map->getTileWidth(); int tileHeight = map->getTileHeight(); - int startX = mOld.x / tileWidth, startY = mOld.y / tileHeight; + int startX = getPosition().x / tileWidth; + int startY = getPosition().y / tileHeight; int destX = mDst.x / tileWidth, destY = mDst.y / tileHeight; return map->findPath(startX, startY, destX, destY, getWalkMask()); @@ -307,8 +307,10 @@ void Being::move() Map *map = getMap()->getMap(); int tileWidth = map->getTileWidth(); int tileHeight = map->getTileHeight(); - int tileSX = mOld.x / tileWidth, tileSY = mOld.y / tileHeight; - int tileDX = mDst.x / tileWidth, tileDY = mDst.y / tileHeight; + int tileSX = getPosition().x / tileWidth; + int tileSY = getPosition().y / tileHeight; + int tileDX = mDst.x / tileWidth; + int tileDY = mDst.y / tileHeight; if (tileSX == tileDX && tileSY == tileDY) { @@ -316,7 +318,7 @@ void Being::move() setAction(STAND); // Moving while staying on the same tile is free // We only update the direction in that case. - updateDirection(mOld, mDst); + updateDirection(getPosition(), mDst); setPosition(mDst); mMoveTime = 0; return; diff --git a/src/game-server/main-game.cpp b/src/game-server/main-game.cpp index 9d96a6ab..a9a6652a 100644 --- a/src/game-server/main-game.cpp +++ b/src/game-server/main-game.cpp @@ -164,24 +164,7 @@ static void initializeServer() // Initialize PhysicsFS PHYSFS_init(""); - // Initialize the logger. - Logger::setLogFile(logFile, true); - - // Write the messages to both the screen and the log file. - Logger::setTeeMode(Configuration::getBoolValue("log_gameToStandardOutput", - true)); - - LOG_INFO("Using log file: " << logFile); - - // Set up the options related to log rotation. - Logger::enableLogRotation(Configuration::getBoolValue("log_enableRotation", - false)); - - Logger::setMaxLogfileSize(Configuration::getValue("log_maxFileSize", - 1024)); - - Logger::setSwitchLogEachDay(Configuration::getBoolValue("log_perDay", - false)); + Logger::initialize(logFile); // --- Initialize the managers // Initialize the slang's and double quotes filter. diff --git a/src/game-server/map.cpp b/src/game-server/map.cpp index b824aaac..e372f03d 100644 --- a/src/game-server/map.cpp +++ b/src/game-server/map.cpp @@ -96,7 +96,6 @@ class Location int Fcost; /**< Estimation of total path cost */ }; - Map::Map(int width, int height, int tileWidth, int tileHeight): mWidth(width), mHeight(height), mTileWidth(tileWidth), mTileHeight(tileHeight), @@ -104,6 +103,15 @@ Map::Map(int width, int height, int tileWidth, int tileHeight): { } +Map::~Map() +{ + for (std::vector<MapObject*>::iterator it = mMapObjects.begin(); + it != mMapObjects.end(); ++it) + { + delete *it; + } +} + void Map::setSize(int width, int height) { mWidth = width; diff --git a/src/game-server/map.h b/src/game-server/map.h index 7c58d005..eca36863 100644 --- a/src/game-server/map.h +++ b/src/game-server/map.h @@ -26,11 +26,12 @@ #include <string> #include <vector> +#include "utils/logger.h" #include "utils/point.h" +#include "utils/string.h" typedef std::list<Point> Path; typedef Path::iterator PathIterator; - enum BlockType { BLOCKTYPE_NONE = -1, @@ -59,6 +60,49 @@ class MetaTile char blockmask; /**< walkability bitfield */ }; +class MapObject +{ + public: + MapObject(const Rectangle &bounds, + const std::string &name, + const std::string &type) + : mBounds(bounds), + mName(name), + mType(type) + { } + + void addProperty(const std::string &key, const std::string &value) + { + if (mProperties.contains(key)) + LOG_WARN("Duplicate property " << key << + " of object " << mName); + else + mProperties.insert(key, value); + } + + std::string getProperty(const std::string &key) const + { return mProperties.find(key); } + + const std::string &getName() const + { return mName; } + + const std::string &getType() const + { return mType; } + + const Rectangle &getBounds() const + { return mBounds; } + + int getX() const { return mBounds.x; } + int getY() const { return mBounds.y; } + + private: + Rectangle mBounds; + std::string mName; + std::string mType; + utils::NameMap<std::string> mProperties; +}; + + /** * A tile map. */ @@ -71,6 +115,8 @@ class Map Map(int width, int height, int tileWidth, int tileHeight); + ~Map(); + /** * Sets the size of the map. This will destroy any existing map data. */ @@ -129,9 +175,21 @@ class Map /** * Sets a map property */ - void setProperty(const std::string& key, const std::string& val) + void setProperty(const std::string &key, const std::string &val) { mProperties[key] = val; } + /** + * Adds an object. + */ + void addObject(MapObject *object) + { mMapObjects.push_back(object); } + + /** + * Returns the objects of the map. + */ + const std::vector<MapObject*> &getObjects() const + { return mMapObjects; } + /** * Find a path from one location to the next. */ @@ -154,6 +212,7 @@ class Map std::map<std::string, std::string> mProperties; std::vector<MetaTile> mMetaTiles; + std::vector<MapObject*> mMapObjects; }; #endif diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index d3475f7a..ecd39569 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -1,6 +1,7 @@ /* * The Mana Server * Copyright (C) 2006-2010 The Mana World Development Team + * Copyright (C) 2010-2011 The Mana Development Team * * This file is part of The Mana Server. * @@ -21,11 +22,17 @@ #include <algorithm> #include <cassert> -#include "common/configuration.h" #include "accountconnection.h" -#include "game-server/map.h" -#include "game-server/mapcomposite.h" +#include "common/configuration.h" +#include "common/resourcemanager.h" #include "game-server/character.h" +#include "game-server/mapcomposite.h" +#include "game-server/map.h" +#include "game-server/mapmanager.h" +#include "game-server/mapreader.h" +#include "game-server/monstermanager.h" +#include "game-server/spawnarea.h" +#include "game-server/trigger.h" #include "scripting/script.h" #include "utils/logger.h" #include "utils/point.h" @@ -261,6 +268,11 @@ void ActorIterator::operator++() } } + +/****************************************************************************** + * ObjectBucket + *****************************************************************************/ + ObjectBucket::ObjectBucket() : free(256), next_object(0) { @@ -326,6 +338,11 @@ void ObjectBucket::deallocate(int i) ++free; } + +/****************************************************************************** + * MapContent + *****************************************************************************/ + MapContent::MapContent(Map *map) : last_bucket(0), zones(NULL) { @@ -433,6 +450,11 @@ MapZone& MapContent::getZone(const Point &pos) const return zones[(pos.x / zoneDiam) + (pos.y / zoneDiam) * mapWidth]; } + +/****************************************************************************** + * MapComposite + *****************************************************************************/ + MapComposite::MapComposite(int id, const std::string &name): mMap(NULL), mContent(NULL), @@ -449,6 +471,39 @@ MapComposite::~MapComposite() delete mScript; } +bool MapComposite::activate() +{ + assert(!isActive()); + + std::string file = "maps/" + mName + ".tmx"; + if (!ResourceManager::exists(file)) + file += ".gz"; + + mMap = MapReader::readMap(file); + if (!mMap) + return false; + + initializeContent(); + + std::string sPvP = mMap->getProperty("pvp"); + if (sPvP.empty()) + sPvP = Configuration::getValue("game_defaultPvp", std::string()); + + if (sPvP == "free") + mPvPRules = PVP_FREE; + else + mPvPRules = PVP_NONE; + + if (Script *s = getScript()) + { + s->setMap(this); + s->prepare("initialize"); + s->execute(); + } + + return true; +} + ZoneIterator MapComposite::getAroundPointIterator(const Point &p, int radius) const { MapRegion r; @@ -544,22 +599,6 @@ void MapComposite::remove(Thing *ptr) } } -void MapComposite::setMap(Map *m) -{ - assert(!mMap && m); - mMap = m; - mContent = new MapContent(m); - - std::string sPvP = m->getProperty("pvp"); - if (sPvP.empty()) - sPvP = Configuration::getValue("game_defaultPvp", std::string()); - - if (sPvP == "free") - mPvPRules = PVP_FREE; - else - mPvPRules = PVP_NONE; -} - void MapComposite::update() { for (int i = 0; i < mContent->mapHeight * mContent->mapWidth; ++i) @@ -596,12 +635,11 @@ const std::vector< Thing * > &MapComposite::getEverything() const } -std::string MapComposite::getVariable(const std::string &key) +std::string MapComposite::getVariable(const std::string &key) const { - std::map<std::string, std::string>::iterator iValue = - mScriptVariables.find(key); - if (iValue != mScriptVariables.end()) - return iValue->second; + std::map<std::string, std::string>::const_iterator i = mScriptVariables.find(key); + if (i != mScriptVariables.end()) + return i->second; else return std::string(); } @@ -609,9 +647,8 @@ std::string MapComposite::getVariable(const std::string &key) void MapComposite::setVariable(const std::string &key, const std::string &value) { // check if the value actually changed - std::map<std::string, std::string>::iterator iOldValue = - mScriptVariables.find(key); - if (iOldValue == mScriptVariables.end() || iOldValue->second != value) + std::map<std::string, std::string>::iterator i = mScriptVariables.find(key); + if (i == mScriptVariables.end() || i->second != value) { // changed value or unknown variable mScriptVariables[key] = value; @@ -619,3 +656,119 @@ void MapComposite::setVariable(const std::string &key, const std::string &value) accountHandler->updateMapVar(this, key, value); } } + +/** + * Initializes the map content. This creates the warps, spawn areas, npcs and + * other scripts. + */ +void MapComposite::initializeContent() +{ + mContent = new MapContent(mMap); + + const std::vector<MapObject*> &objects = mMap->getObjects(); + + for (size_t i = 0; i < objects.size(); ++i) + { + const MapObject *object = objects.at(i); + const std::string &type = object->getType(); + + if (utils::compareStrI(type, "WARP") == 0) + { + std::string destMapName = object->getProperty("DEST_MAP"); + int destX = utils::stringToInt(object->getProperty("DEST_X")); + int destY = utils::stringToInt(object->getProperty("DEST_Y")); + + if (!destMapName.empty() && destX && destY) + { + if (MapComposite *destMap = MapManager::getMap(destMapName)) + { + WarpAction *action = new WarpAction(destMap, destX, destY); + insert(new TriggerArea(this, object->getBounds(), + action, false)); + } + } + else + { + LOG_WARN("Unrecognized warp format"); + } + } + else if (utils::compareStrI(type, "SPAWN") == 0) + { + MonsterClass *monster = 0; + int maxBeings = utils::stringToInt(object->getProperty("MAX_BEINGS")); + int spawnRate = utils::stringToInt(object->getProperty("SPAWN_RATE")); + std::string monsterName = object->getProperty("MONSTER_ID"); + int monsterId = utils::stringToInt(monsterName); + + if (monsterId) + { + monster = monsterManager->getMonster(monsterId); + if (!monster) + { + LOG_WARN("Couldn't find monster ID " << monsterId << + " for spawn area"); + } + } + else + { + monster = monsterManager->getMonsterByName(monsterName); + if (!monster) + { + LOG_WARN("Couldn't find monster " << monsterName << + " for spawn area"); + } + } + + if (monster && maxBeings && spawnRate) + { + insert(new SpawnArea(this, monster, object->getBounds(), + maxBeings, spawnRate)); + } + } + else if (utils::compareStrI(type, "NPC") == 0) + { + if (!mScript) + { + mScript = Script::create("lua"); + } + + int npcId = utils::stringToInt(object->getProperty("NPC_ID")); + std::string scriptText = object->getProperty("SCRIPT"); + + if (npcId && !scriptText.empty()) + { + mScript->loadNPC(object->getName(), npcId, + object->getX(), object->getY(), + scriptText.c_str()); + } + else + { + LOG_WARN("Unrecognized format for npc"); + } + } + else if (utils::compareStrI(type, "SCRIPT") == 0) + { + if (!mScript) + { + mScript = Script::create("lua"); + } + + std::string scriptFilename = object->getProperty("FILENAME"); + std::string scriptText = object->getProperty("TEXT"); + + if (!scriptFilename.empty()) + { + mScript->loadFile(scriptFilename); + } + else if (!scriptText.empty()) + { + std::string name = "'" + object->getName() + "'' in " + mName; + mScript->load(scriptText.c_str(), name.c_str()); + } + else + { + LOG_WARN("Unrecognized format for script"); + } + } + } +} diff --git a/src/game-server/mapcomposite.h b/src/game-server/mapcomposite.h index f34ad24a..988b0ed8 100644 --- a/src/game-server/mapcomposite.h +++ b/src/game-server/mapcomposite.h @@ -1,6 +1,7 @@ /* * The Mana Server * Copyright (C) 2006-2010 The Mana World Development Team + * Copyright (C) 2010-2011 The Mana Development Team * * This file is part of The Mana Server. * @@ -233,10 +234,13 @@ class MapComposite ~MapComposite(); /** - * Sets the underlying pathfinding map. - * Can be done only once. + * Loads the map and initializes the map content. Should only be called + * once! + * + * @return <code>true</code> when succesful, <code>false</code> when + * an error occurred. */ - void setMap(Map *); + bool activate(); /** * Gets the underlying pathfinding map. @@ -245,13 +249,8 @@ class MapComposite { return mMap; } /** - * Sets the associated script. - */ - void setScript(Script *s) - { mScript = s; } - - /** - * Gets the associated script. + * Gets the associated script. Returns 0 when no scripts or inline + * NPCs are used on this map! */ Script *getScript() const { return mScript; } @@ -329,13 +328,13 @@ class MapComposite /** * Gets the cached value of a map-bound script variable */ - std::string getVariable(const std::string &key); + std::string getVariable(const std::string &key) const; /** * Changes a script variable and notifies the database server * about the change */ - void setVariable (const std::string &key, const std::string &value); + void setVariable(const std::string &key, const std::string &value); /** * Changes a script variable without notifying the database server @@ -348,13 +347,15 @@ class MapComposite private: MapComposite(const MapComposite &); + void initializeContent(); + Map *mMap; /**< Actual map. */ MapContent *mContent; /**< Entities on the map. */ Script *mScript; /**< Script associated to this map. */ std::string mName; /**< Name of the map. */ unsigned short mID; /**< ID of the map. */ /** Cached persistent variables */ - std::map< std::string, std::string > mScriptVariables; + std::map<std::string, std::string> mScriptVariables; PvPRules mPvPRules; }; diff --git a/src/game-server/mapmanager.cpp b/src/game-server/mapmanager.cpp index 094af923..4d7b25b4 100644 --- a/src/game-server/mapmanager.cpp +++ b/src/game-server/mapmanager.cpp @@ -1,6 +1,7 @@ /* * The Mana Server * Copyright (C) 2004-2010 The Mana World Development Team + * Copyright (C) 2010-2011 The Mana Development Team * * This file is part of The Mana Server. * @@ -23,7 +24,6 @@ #include "common/resourcemanager.h" #include "game-server/map.h" #include "game-server/mapcomposite.h" -#include "game-server/mapreader.h" #include "utils/logger.h" #include "utils/xml.h" @@ -127,30 +127,25 @@ MapComposite *MapManager::getMap(const std::string &mapName) return NULL; } -bool MapManager::raiseActive(int mapId) +bool MapManager::activateMap(int mapId) { Maps::iterator i = maps.find(mapId); assert(i != maps.end()); MapComposite *composite = i->second; + if (composite->isActive()) - { return true; - } - std::string file = "maps/" + composite->getName() + ".tmx"; - if (!ResourceManager::exists(file)) - { - file += ".gz"; - } - if (MapReader::readMap(file, composite)) + if (composite->activate()) { - LOG_INFO("Activated map \"" << file << "\" (id " << mapId << ")"); + LOG_INFO("Activated map \"" << composite->getName() + << "\" (id " << mapId << ")"); return true; } else { - LOG_WARN("Couldn't activate invalid map \"" << file << "\" (id " << - mapId << ")"); + LOG_WARN("Couldn't activate invalid map \"" << composite->getName() + << "\" (id " << mapId << ")"); return false; } } diff --git a/src/game-server/mapmanager.h b/src/game-server/mapmanager.h index d21bd419..6b518819 100644 --- a/src/game-server/mapmanager.h +++ b/src/game-server/mapmanager.h @@ -1,6 +1,7 @@ /* * The Mana Server * Copyright (C) 2004-2010 The Mana World Development Team + * Copyright (C) 2010-2011 The Mana Development Team * * This file is part of The Mana Server. * @@ -62,7 +63,7 @@ namespace MapManager * Sets the activity status of the map. * @return true if the activation was successful. */ - bool raiseActive(int mapId); + bool activateMap(int mapId); } #endif // MAPMANAGER_H diff --git a/src/game-server/mapreader.cpp b/src/game-server/mapreader.cpp index 8438c82c..87101a65 100644 --- a/src/game-server/mapreader.cpp +++ b/src/game-server/mapreader.cpp @@ -1,6 +1,7 @@ /* * The Mana Server * Copyright (C) 2004-2010 The Mana World Development Team + * Copyright (C) 2010-2011 The Mana Development Team * * This file is part of The Mana Server. * @@ -20,13 +21,8 @@ #include "game-server/mapreader.h" +#include "common/defines.h" #include "game-server/map.h" -#include "game-server/mapcomposite.h" -#include "game-server/mapmanager.h" -#include "game-server/monstermanager.h" -#include "game-server/spawnarea.h" -#include "game-server/trigger.h" -#include "scripting/script.h" #include "utils/base64.h" #include "utils/logger.h" #include "utils/xml.h" @@ -37,7 +33,7 @@ static std::vector< int > tilesetFirstGids; -bool MapReader::readMap(const std::string &filename, MapComposite *composite) +Map *MapReader::readMap(const std::string &filename) { XML::Document doc(filename); xmlNodePtr rootNode = doc.rootNode(); @@ -49,39 +45,16 @@ bool MapReader::readMap(const std::string &filename, MapComposite *composite) return false; } - std::vector<Thing *> things; - Map *map = readMap(rootNode, filename, composite, things); - - if (map) - { - composite->setMap(map); - - for (std::vector< Thing * >::const_iterator i = things.begin(), - i_end = things.end(); i != i_end; ++i) - { - composite->insert(*i); - } - - if (Script *s = composite->getScript()) - { - s->setMap(composite); - s->prepare("initialize"); - s->execute(); - } - } - return true; + return readMap(rootNode); } -Map* MapReader::readMap(xmlNodePtr node, const std::string &path, - MapComposite *composite, std::vector<Thing *> &things) +Map *MapReader::readMap(xmlNodePtr node) { - // Take the filename off the path - std::string pathDir = path.substr(0, path.rfind("/") + 1); int w = XML::getProperty(node, "width", 0); int h = XML::getProperty(node, "height", 0); - int tilew = XML::getProperty(node, "tilewidth", DEFAULT_TILE_LENGTH); - int tileh = XML::getProperty(node, "tileheight", DEFAULT_TILE_LENGTH); - Map* map = new Map(w, h, tilew, tileh); + int tileW = XML::getProperty(node, "tilewidth", DEFAULT_TILE_LENGTH); + int tileH = XML::getProperty(node, "tileheight", DEFAULT_TILE_LENGTH); + Map *map = new Map(w, h, tileW, tileH); for (node = node->xmlChildrenNode; node != NULL; node = node->next) { @@ -141,236 +114,29 @@ Map* MapReader::readMap(xmlNodePtr node, const std::string &path, int objH = XML::getProperty(objectNode, "height", 0); Rectangle rect = { objX, objY, objW, objH }; + MapObject *newObject = new MapObject(rect, objName, objType); - if (utils::compareStrI(objType, "WARP") == 0) - { - std::string destMapName = std::string(); - int destX = -1; - int destY = -1; - - for_each_xml_child_node(propertiesNode, objectNode) - { - if (!xmlStrEqual(propertiesNode->name, BAD_CAST "properties")) - { - continue; - } - - for_each_xml_child_node(propertyNode, propertiesNode) - { - if (xmlStrEqual(propertyNode->name, - BAD_CAST "property")) - { - std::string value = XML::getProperty( - propertyNode, "name", std::string()); - value = utils::toUpper(value); - if (utils::compareStrI(value, "DEST_MAP") == 0) - { - destMapName = getObjectProperty(propertyNode, - std::string()); - } - else if (utils::compareStrI(value, "DEST_X") == 0) - { - destX = getObjectProperty(propertyNode, -1); - } - else if (utils::compareStrI(value, "DEST_Y") == 0) - { - destY = getObjectProperty(propertyNode, -1); - } - } - } - } - - if (!destMapName.empty() && destX != -1 && destY != -1) - { - MapComposite *destMap = MapManager::getMap(destMapName); - if (destMap) - { - things.push_back(new TriggerArea( - composite, rect, - new WarpAction(destMap, destX, destY), - false)); - } - } - else - { - LOG_WARN("Unrecognized warp format"); - } - } - else if (utils::compareStrI(objType, "SPAWN") == 0) - { - MonsterClass *monster = 0; - int maxBeings = 10; // Default value - int spawnRate = 10; // Default value - - for_each_xml_child_node(propertiesNode, objectNode) - { - if (!xmlStrEqual(propertiesNode->name, BAD_CAST "properties")) - { - continue; - } - - for_each_xml_child_node(propertyNode, propertiesNode) - { - if (xmlStrEqual(propertyNode->name, BAD_CAST "property")) - { - std::string value = XML::getProperty( - propertyNode, - "name", - std::string()); - value = utils::toUpper(value); - if (utils::compareStrI(value, "MONSTER_ID") == 0) - { - std::string monsterName = - getObjectProperty(propertyNode, - std::string()); - int monsterId = utils::stringToInt(monsterName); - if (monsterId) - { - monster = monsterManager->getMonster( - monsterId); - if (!monster) - { - LOG_WARN("Couldn't find monster ID " - << monsterId << - " for spawn area"); - } - } - else - { - monster = monsterManager-> - getMonsterByName(monsterName); - if (!monster) - { - LOG_WARN("Couldn't find monster " - << monsterName << - " for spawn area"); - } - } - } - else if (utils::compareStrI(value, - "MAX_BEINGS") == 0) - { - maxBeings = getObjectProperty(propertyNode, - maxBeings); - } - else if (utils::compareStrI(value, - "SPAWN_RATE") == 0) - { - spawnRate = getObjectProperty(propertyNode, - spawnRate); - } - } - } - } - - if (monster) - { - things.push_back(new SpawnArea(composite, monster, rect, - maxBeings, spawnRate)); - } - } - else if (utils::compareStrI(objType, "NPC") == 0) + for_each_xml_child_node(propertiesNode, objectNode) { - Script *s = composite->getScript(); - if (!s) + if (!xmlStrEqual(propertiesNode->name, BAD_CAST "properties")) { - // Create a Lua context. - s = Script::create("lua"); - composite->setScript(s); + continue; } - - int npcId = -1; - std::string scriptText; - - for_each_xml_child_node(propertiesNode, objectNode) + + for_each_xml_child_node(propertyNode, propertiesNode) { - if (!xmlStrEqual(propertiesNode->name, BAD_CAST "properties")) - { - continue; - } - - for_each_xml_child_node(propertyNode, propertiesNode) + if (xmlStrEqual(propertyNode->name, BAD_CAST "property")) { - if (xmlStrEqual(propertyNode->name, BAD_CAST "property")) - { - std::string value = XML::getProperty(propertyNode, "name", std::string()); - value = utils::toUpper(value); - if (utils::compareStrI(value, "NPC_ID") == 0) - { - npcId = getObjectProperty(propertyNode, npcId); - } - else if (utils::compareStrI(value, "SCRIPT") == 0) - { - scriptText = getObjectProperty(propertyNode, std::string()); - } - } + std::string key = XML::getProperty( + propertyNode, "name", std::string()); + std::string value = getObjectProperty(propertyNode, + std::string()); + newObject->addProperty(key, value); } } - - if (npcId != -1 && !scriptText.empty()) - { - s->loadNPC(objName, npcId, objX, objY, scriptText.c_str()); - } - else - { - LOG_WARN("Unrecognized format for npc"); - } } - else if (utils::compareStrI(objType, "SCRIPT") == 0) - { - Script *s = composite->getScript(); - if (!s) - { - // Create a Lua context. - s = Script::create("lua"); - composite->setScript(s); - } - - std::string scriptFilename; - std::string scriptText; - for_each_xml_child_node(propertiesNode, objectNode) - { - if (!xmlStrEqual(propertiesNode->name, BAD_CAST "properties")) - { - continue; - } - - for_each_xml_child_node(propertyNode, propertiesNode) - { - if (xmlStrEqual(propertyNode->name, BAD_CAST "property")) - { - std::string value = XML::getProperty(propertyNode, "name", - std::string()); - value = utils::toUpper(value); - if (utils::compareStrI(value, "FILENAME") == 0) - { - scriptFilename = getObjectProperty(propertyNode, - std::string()); - utils::trim(scriptFilename); - } - else if (utils::compareStrI(value, "TEXT") == 0) - { - scriptText = getObjectProperty(propertyNode, ""); - } - } - } - } - - if (!scriptFilename.empty()) - { - s->loadFile(scriptFilename); - } - else if (!scriptText.empty()) - { - const std::string name = "'" + objName + "'' in " + path; - s->load(scriptText.c_str(), name.c_str()); - } - else - { - LOG_WARN("Unrecognized format for script"); - } - } + map->addObject(newObject); } } } diff --git a/src/game-server/mapreader.h b/src/game-server/mapreader.h index f4a0e5f8..725737f2 100644 --- a/src/game-server/mapreader.h +++ b/src/game-server/mapreader.h @@ -1,6 +1,7 @@ /* * The Mana Server * Copyright (C) 2004-2010 The Mana World Development Team + * Copyright (C) 2010-2011 The Mana Development Team * * This file is part of The Mana Server. * @@ -38,19 +39,15 @@ class MapReader public: /** * Read an XML map from a file. - * @return true if it was successful. + * @return the map when successful, 0 otherwise. */ - static bool readMap(const std::string &filename, - MapComposite *composite); + static Map *readMap(const std::string &filename); private: /** - * Read an XML map from a parsed XML tree, and populate things with - * objects in that map. + * Read an XML map from a parsed XML tree. */ - static Map *readMap(xmlNodePtr node, const std::string &path, - MapComposite *composite, - std::vector<Thing *> &things); + static Map *readMap(xmlNodePtr node); /** * Reads a map layer and adds it to the given map. diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 4d5d3371..03d08771 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1432,14 +1432,27 @@ static int chat_message(lua_State *s) /** * mana.get_beings_in_circle(int x, int y, int radius): table of Being* + * mana.get_beings_in_circle(handle centerBeing, int radius): table of Being* * Gets a LUA table with the Being* pointers of all beings * inside of a circular area of the current map. */ static int get_beings_in_circle(lua_State *s) { - const int x = luaL_checkint(s, 1); - const int y = luaL_checkint(s, 2); - const int r = luaL_checkint(s, 3); + int x, y, r; + if (lua_islightuserdata(s, 1)) + { + Being *b = getBeing(s, 1); + const Point &pos = b->getPosition(); + x = pos.x; + y = pos.y; + r = luaL_checkint(s, 2); + } + else + { + x = luaL_checkint(s, 1); + y = luaL_checkint(s, 2); + r = luaL_checkint(s, 3); + } lua_pushlightuserdata(s, (void *)®istryKey); lua_gettable(s, LUA_REGISTRYINDEX); @@ -2139,6 +2152,132 @@ static int get_distance(lua_State *s) return 1; } +/** + * mana.map_get_objects(): table of all objects + * mana.map_get_objects(string type): table of all objects of type + * Gets the objects of a map. + */ +static int map_get_objects(lua_State *s) +{ + const bool filtered = (lua_gettop(s) == 1); + std::string filter; + if (filtered) + filter = luaL_checkstring(s, 1); + + lua_pushlightuserdata(s, (void *)®istryKey); + lua_gettable(s, LUA_REGISTRYINDEX); + Script *t = static_cast<Script *>(lua_touserdata(s, -1)); + const std::vector<MapObject*> &objects = t->getMap()->getMap()->getObjects(); + + if (!filtered) + pushSTLContainer<MapObject*>(s, objects); + else + { + std::vector<MapObject*> filteredObjects; + for (std::vector<MapObject*>::const_iterator it = objects.begin(); + it != objects.end(); ++it) + { + if (utils::compareStrI((*it)->getType(), filter) == 0) + { + filteredObjects.push_back(*it); + } + } + pushSTLContainer<MapObject*>(s, filteredObjects); + } + return 1; +} + +/** + * mana.map_object_get_property(handle object, string key) + * Returns the value of the object property 'key'. + */ +static int map_object_get_property(lua_State *s) +{ + std::string key = luaL_checkstring(s, 2); + if (!lua_islightuserdata(s, 1)) + { + raiseScriptError(s, "map_object_get_property called with invalid" + "object handle"); + return 0; + } + MapObject *obj = static_cast<MapObject *>(lua_touserdata(s, 1)); + if (obj) + { + std::string property = obj->getProperty(key); + if (!property.empty()) + { + lua_pushstring(s, property.c_str()); + return 1; + } + else + { + // scripts can check for nil + return 0; + } + } + else + { + raiseScriptError(s, "map_object_get_property called with invalid" + "object handle"); + return 0; + } +} + +/** + * mana.map_object_get_bounds(object) + * Returns 4 int: x/y/width/height of object. + */ +static int map_object_get_bounds(lua_State *s) +{ + if (!lua_islightuserdata(s, 1)) + { + raiseScriptError(s, "map_object_get_bounds called with invalid" + "object handle"); + return 0; + } + MapObject *obj = static_cast<MapObject *>(lua_touserdata(s, 1)); + const Rectangle &bounds = obj->getBounds(); + lua_pushinteger(s, bounds.x); + lua_pushinteger(s, bounds.y); + lua_pushinteger(s, bounds.w); + lua_pushinteger(s, bounds.h); + return 4; +} + +/** + * mana.map_object_get_name(object) + * Returns the name of the object. + */ +static int map_object_get_name(lua_State *s) +{ + if (!lua_islightuserdata(s, 1)) + { + raiseScriptError(s, "map_object_get_name called with invalid" + "object handle"); + return 0; + } + MapObject *obj = static_cast<MapObject *>(lua_touserdata(s, 1)); + lua_pushstring(s, obj->getName().c_str()); + return 1; +} + +/** + * mana.map_object_get_type(object) + * Returns the type of the object. + */ +static int map_object_get_type(lua_State *s) +{ + if (!lua_islightuserdata(s, 1)) + { + raiseScriptError(s, "map_object_get_type called with invalid" + "object handle"); + return 0; + } + MapObject *obj = static_cast<MapObject *>(lua_touserdata(s, 1)); + lua_pushstring(s, obj->getType().c_str()); + return 1; +} + static int require_loader(lua_State *s) { // Add .lua extension (maybe only do this when it doesn't have it already) @@ -2248,6 +2387,11 @@ LuaScript::LuaScript(): { "npc_ask_string", &npc_ask_string }, { "log", &log }, { "get_distance", &get_distance }, + { "map_get_objects", &map_get_objects }, + { "map_object_get_property", &map_object_get_property }, + { "map_object_get_bounds", &map_object_get_bounds }, + { "map_object_get_name", &map_object_get_name }, + { "map_object_get_type", &map_object_get_type }, { NULL, NULL } }; luaL_register(mState, "mana", callbacks); diff --git a/src/scripting/luautil.cpp b/src/scripting/luautil.cpp index b7680c6b..a7521426 100644 --- a/src/scripting/luautil.cpp +++ b/src/scripting/luautil.cpp @@ -116,3 +116,8 @@ void push(lua_State *s, double val) { lua_pushnumber(s, val); } + +void push(lua_State *s, MapObject *val) +{ + lua_pushlightuserdata(s, val); +} diff --git a/src/scripting/luautil.h b/src/scripting/luautil.h index c55b04b7..82bb78cf 100644 --- a/src/scripting/luautil.h +++ b/src/scripting/luautil.h @@ -31,6 +31,8 @@ extern "C" { #include <set> #include <vector> +#include "game-server/map.h" + class Being; class NPC; class Character; @@ -52,8 +54,9 @@ Being *getBeing(lua_State *s, int p); Useful for templates.*/ void push(lua_State *s, int val); void push(lua_State *s, const std::string &val); -void push(lua_State *s, Thing* val); +void push(lua_State *s, Thing *val); void push(lua_State *s, double val); +void push(lua_State *s, MapObject *val); /* Pushes an STL LIST */ diff --git a/src/utils/logger.cpp b/src/utils/logger.cpp index e5ceb9bc..8a070570 100644 --- a/src/utils/logger.cpp +++ b/src/utils/logger.cpp @@ -20,6 +20,7 @@ */ #include "logger.h" +#include "common/configuration.h" #include "common/resourcemanager.h" #include "utils/string.h" #include "utils/time.h" @@ -63,7 +64,7 @@ static std::string mOldDate; * * @return whether the day has changed. */ -bool getDayChanged() +static bool getDayChanged() { std::string dayDate = getCurrentDate(); @@ -78,6 +79,20 @@ bool getDayChanged() return false; } +void Logger::initialize(const std::string &logFile) +{ + setLogFile(logFile, true); + + // Write the messages to both the screen and the log file. + setTeeMode(Configuration::getBoolValue("log_toStandardOutput", true)); + LOG_INFO("Using log file: " << logFile); + + // Set up the options related to log rotation. + setLogRotation(Configuration::getBoolValue("log_enableRotation", false)); + setMaxLogfileSize(Configuration::getValue("log_maxFileSize", 1024)); + setSwitchLogEachDay(Configuration::getBoolValue("log_perDay", false)); +} + void Logger::output(std::ostream &os, const std::string &msg, const char *prefix) { if (mHasTimestamp) diff --git a/src/utils/logger.h b/src/utils/logger.h index ba64b10b..65846be5 100644 --- a/src/utils/logger.h +++ b/src/utils/logger.h @@ -82,6 +82,8 @@ class Logger Debug }; + static void initialize(const std::string &logFile); + /** * Sets the log file. * @@ -127,7 +129,7 @@ class Logger * * @param enable Set to true to enable logrotation. */ - static void enableLogRotation(bool enable = true) + static void setLogRotation(bool enable) { mLogRotation = enable; } /** |