summaryrefslogtreecommitdiff
path: root/src/game-server/mapcomposite.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game-server/mapcomposite.cpp')
-rw-r--r--src/game-server/mapcomposite.cpp207
1 files changed, 180 insertions, 27 deletions
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");
+ }
+ }
+ }
+}