summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2011-10-18 00:13:34 +0200
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2011-10-19 22:32:28 +0200
commitc8f2916bdc60f7c5b632655cfe9bddaad3a15bc0 (patch)
treea3a867fae425ca3e53d166748f315a22d6eda28d /src
parent210e33c8b32f3bbc696e5ffd1affef65a7d66b5d (diff)
downloadmanaserv-c8f2916bdc60f7c5b632655cfe9bddaad3a15bc0.tar.gz
manaserv-c8f2916bdc60f7c5b632655cfe9bddaad3a15bc0.tar.bz2
manaserv-c8f2916bdc60f7c5b632655cfe9bddaad3a15bc0.tar.xz
manaserv-c8f2916bdc60f7c5b632655cfe9bddaad3a15bc0.zip
Took interpreting the objects out of the map reader
The map reader is now only concerned with parsing the XML, whereas the MapComposite turns some of the objects into Warps, Spawns and NPCs. Reviewed-by: Yohann Ferreira
Diffstat (limited to 'src')
-rw-r--r--src/game-server/accountconnection.cpp15
-rw-r--r--src/game-server/map.h3
-rw-r--r--src/game-server/mapcomposite.cpp207
-rw-r--r--src/game-server/mapcomposite.h27
-rw-r--r--src/game-server/mapmanager.cpp21
-rw-r--r--src/game-server/mapmanager.h3
-rw-r--r--src/game-server/mapreader.cpp156
-rw-r--r--src/game-server/mapreader.h13
8 files changed, 229 insertions, 216 deletions
diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp
index 927b5c15..a6dc552f 100644
--- a/src/game-server/accountconnection.cpp
+++ b/src/game-server/accountconnection.cpp
@@ -159,7 +159,7 @@ void AccountConnection::processMessage(MessageIn &msg)
case AGMSG_ACTIVE_MAP:
{
int id = msg.readInt16();
- if (MapManager::raiseActive(id))
+ if (MapManager::activateMap(id))
{
// set map variables
MapComposite *m = MapManager::getMap(id);
@@ -260,7 +260,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());
@@ -268,8 +269,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());
@@ -278,8 +280,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/map.h b/src/game-server/map.h
index f1180a77..eca36863 100644
--- a/src/game-server/map.h
+++ b/src/game-server/map.h
@@ -92,6 +92,9 @@ class MapObject
const Rectangle &getBounds() const
{ return mBounds; }
+ int getX() const { return mBounds.x; }
+ int getY() const { return mBounds.y; }
+
private:
Rectangle mBounds;
std::string mName;
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 e82fa10a..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)
{
@@ -163,119 +136,6 @@ Map* MapReader::readMap(xmlNodePtr node, const std::string &path,
}
}
- if (utils::compareStrI(objType, "WARP") == 0)
- {
- std::string destMapName = newObject->getProperty("DEST_MAP");
- int destX = utils::stringToInt(
- newObject->getProperty("DEST_X"));
- int destY = utils::stringToInt(
- newObject->getProperty("DEST_Y"));
-
- if (!destMapName.empty() && destX && destY)
- {
- 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 = utils::stringToInt(
- newObject->getProperty("MAX_BEINGS"));
- int spawnRate = utils::stringToInt(
- newObject->getProperty("SPAWN_RATE"));
- std::string monsterName =
- newObject->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)
- {
- things.push_back(new SpawnArea(composite, monster, rect,
- maxBeings, spawnRate));
- }
- }
- else if (utils::compareStrI(objType, "NPC") == 0)
- {
- Script *s = composite->getScript();
- if (!s)
- {
- // Create a Lua context.
- s = Script::create("lua");
- composite->setScript(s);
- }
-
- int npcId = utils::stringToInt(
- newObject->getProperty("NPC_ID"));
- std::string scriptText = newObject->getProperty("SCRIPT");
-
- if (npcId && !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 =
- newObject->getProperty("FILENAME");
- std::string scriptText = newObject->getProperty("TEXT");
-
- 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.