예제 #1
0
/**
 * 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)
        {
            const std::string destMapName = object->getProperty("DEST_MAP");
            const Rectangle &sourceBounds = object->getBounds();
            MapComposite *destMap = MapManager::getMap(destMapName);

            // check destination map
            if (!destMap)
            {
                if (destMapName.empty())
                {
                    // this must be a one way warp target
                    continue;
                }

                LOG_ERROR("Warp \"" << object->getName() << "\" targets missing map \""
                          << destMapName << "\" in " << getName());
                continue;
            }


            TriggerAction* action;
            if (object->hasProperty("DEST_NAME"))
            {
                // warp to an object
                // get destination object name
                const std::string destMapObjectName = object->getProperty("DEST_NAME");
                // get target object and validate it
                const MapObject *destination = destMap->findMapObject(destMapObjectName, "WARP");
                if (!destination)
                {
                    LOG_ERROR("Warp \"" << object->getName() << "\" from map " << getName()
                              << " targets missing warp \"" << destMapObjectName << "\" "
                              << " on map " << destMap->getName());
                    continue;
                }

                const Rectangle &destinationBounds = destination->getBounds();

                const std::string &exit = destination->getProperty("EXIT_DIRECTION");

                if (exit.empty()) {
                    // old style WARP, warp to center of that object
                    int destX = destinationBounds.x + destinationBounds.w / 2;
                    int destY = destinationBounds.y + destinationBounds.h / 2;
                    action = new WarpAction(destMap, Point(destX, destY));
                }
                else
                {
                    // newer and cooler warp

                    AutowarpAction::ExitDirection exitDir;

                    // find the exit direction
                    if (utils::compareStrI(exit, "NORTH") == 0)
                    {
                        exitDir = AutowarpAction::ExitNorth;
                    }
                    else if (utils::compareStrI(exit, "EAST") == 0)
                    {
                        exitDir = AutowarpAction::ExitEast;
                    }
                    else if (utils::compareStrI(exit, "SOUTH") == 0)
                    {
                        exitDir = AutowarpAction::ExitSouth;
                    }
                    else if (utils::compareStrI(exit, "WEST") == 0)
                    {
                        exitDir = AutowarpAction::ExitWest;
                    }
                    else
                    {
                        // invalid or missing exit direction
                        if (exit.empty())
                        {
                            LOG_ERROR("Warp target \"" << destMapObjectName << "\" on map "
                                    << destMap->getName()
                                    << " is missing exit direction!");
                        }
                        else
                        {
                            LOG_ERROR("Warp target \"" << destMapObjectName << "\" on map "
                                    << destMap->getName()
                                    << " has an invalid exit direction \""
                                    << exit
                                    << "\"!");
                        }
                        continue;
                    }

                    action = new AutowarpAction(destMap, sourceBounds,
                                                destinationBounds, exitDir);
                }
            }
            else if (object->hasProperty("DEST_X") && object->hasProperty("DEST_Y"))
            {
                // warp to absolute position
                int destX = utils::stringToInt(object->getProperty("DEST_X"));
                int destY = utils::stringToInt(object->getProperty("DEST_Y"));

                action = new WarpAction(destMap, Point(destX, destY));
            }
            else
            {
                LOG_ERROR("Warp \"" << object->getName() << "\" on map "
                          << getName()
                          << " is invalid!");
                continue;
            }

            // add this trigger to the map
            Entity *entity = new Entity(OBJECT_OTHER, this);
            entity->addComponent(
                        new TriggerAreaComponent(
                            sourceBounds,
                            action,
                            false
                        )
                     );
            insert(entity);
        }
        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)
            {
                Entity *entity = new Entity(OBJECT_OTHER, this);
                SpawnAreaComponent *spawnArea =
                        new SpawnAreaComponent(monster, object->getBounds(),
                                               maxBeings, spawnRate);

                entity->addComponent(spawnArea);
                insert(entity);
            }
        }
        else if (utils::compareStrI(type, "NPC") == 0)
        {
            int npcId = utils::stringToInt(object->getProperty("NPC_ID"));
            std::string gender = object->getProperty("GENDER");
            std::string scriptText = object->getProperty("SCRIPT");

            if (npcId && !scriptText.empty())
            {
                Script *script = ScriptManager::currentState();
                script->loadNPC(object->getName(), npcId,
                                ManaServ::getGender(gender),
                                object->getX(), object->getY(),
                                scriptText.c_str(), this);
            }
            else
            {
                LOG_WARN("Unrecognized format for npc");
            }
        }
        else if (utils::compareStrI(type, "SCRIPT") == 0)
        {
            std::string scriptFilename = object->getProperty("FILENAME");
            std::string scriptText = object->getProperty("TEXT");

            Script *script = ScriptManager::currentState();
            Script::Context context;
            context.map = this;

            if (!scriptFilename.empty())
            {
                script->loadFile(scriptFilename, context);
            }
            else if (!scriptText.empty())
            {
                std::string name = "'" + object->getName() + "'' in " + mName;
                script->load(scriptText.c_str(), name.c_str(), context);
            }
            else
            {
                LOG_WARN("Unrecognized format for script");
            }
        }
    }
}
예제 #2
0
/**
 * 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");
            std::string destMapObjectName = object->getProperty("DEST_NAME");

            MapComposite *destMap = MapManager::getMap(destMapName);
            int destX = 0;
            int destY = 0;

            if (destMap && !destMapObjectName.empty())
            {
                const MapObject *obj =
                        destMap->findMapObject(destMapObjectName, "WARP");
                if (obj)
                {
                    const Rectangle &rect = obj->getBounds();
                    destX = rect.x + rect.w / 2;
                    destY = rect.y + rect.h / 2;
                }
                else
                {
                    LOG_ERROR("Warp target \"" << destMapObjectName << "\" "
                              << "was not found on the map "
                              << destMap->getName());
                }
            }
            else
            {
                destX = utils::stringToInt(object->getProperty("DEST_X"));
                destY = utils::stringToInt(object->getProperty("DEST_Y"));
            }


            if (destMap && destX && destY)
            {
                Entity *entity = new Entity(OBJECT_OTHER, this);
                WarpAction *action = new WarpAction(destMap, destX, destY);
                entity->addComponent(
                            new TriggerAreaComponent(object->getBounds(),
                                                     action, false));
                insert(entity);
            }
            else
            {
                LOG_WARN("Unrecognized warp format on map " << mName);
            }
        }
        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)
            {
                Entity *entity = new Entity(OBJECT_OTHER, this);
                SpawnAreaComponent *spawnArea =
                        new SpawnAreaComponent(monster, object->getBounds(),
                                               maxBeings, spawnRate);

                entity->addComponent(spawnArea);
                insert(entity);
            }
        }
        else if (utils::compareStrI(type, "NPC") == 0)
        {
            int npcId = utils::stringToInt(object->getProperty("NPC_ID"));
            std::string gender = object->getProperty("GENDER");
            std::string scriptText = object->getProperty("SCRIPT");

            if (npcId && !scriptText.empty())
            {
                Script *script = ScriptManager::currentState();
                script->loadNPC(object->getName(), npcId,
                                ManaServ::getGender(gender),
                                object->getX(), object->getY(),
                                scriptText.c_str(), this);
            }
            else
            {
                LOG_WARN("Unrecognized format for npc");
            }
        }
        else if (utils::compareStrI(type, "SCRIPT") == 0)
        {
            std::string scriptFilename = object->getProperty("FILENAME");
            std::string scriptText = object->getProperty("TEXT");

            Script *script = ScriptManager::currentState();
            Script::Context context;
            context.map = this;

            if (!scriptFilename.empty())
            {
                script->loadFile(scriptFilename, context);
            }
            else if (!scriptText.empty())
            {
                std::string name = "'" + object->getName() + "'' in " + mName;
                script->load(scriptText.c_str(), name.c_str(), context);
            }
            else
            {
                LOG_WARN("Unrecognized format for script");
            }
        }
    }
}