Ejemplo n.º 1
0
bool MapManager::raiseActive(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))
    {
        LOG_INFO("Activated map \"" << file << "\" (id " << mapId << ")");
        return true;
    }
    else
    {
        LOG_WARN("Couldn't activate invalid map \"" << file << "\" (id " <<
                 mapId << ")");
        return false;
    }
}
Ejemplo n.º 2
0
void AccountConnection::sendStatistics()
{
    MessageOut msg(GAMSG_STATISTICS);
    const MapManager::Maps &maps = MapManager::getMaps();
    for (MapManager::Maps::const_iterator i = maps.begin(),
         i_end = maps.end(); i != i_end; ++i)
    {
        MapComposite *m = i->second;
        if (!m->isActive()) continue;
        msg.writeInt16(i->first);
        int nbEntities = 0, nbMonsters = 0;
        typedef std::vector< Entity * > Entities;
        const Entities &things = m->getEverything();
        std::vector< int > players;
        for (Entities::const_iterator j = things.begin(),
             j_end = things.end(); j != j_end; ++j)
        {
            Entity *t = *j;
            switch (t->getType())
            {
                case OBJECT_CHARACTER:
                    players.push_back
                        (static_cast< Character * >(t)->getDatabaseID());
                    break;
                case OBJECT_MONSTER:
                    ++nbMonsters;
                    break;
                default:
                    ++nbEntities;
            }
        }
        msg.writeInt16(nbEntities);
        msg.writeInt16(nbMonsters);
        msg.writeInt16(players.size());
        for (std::vector< int >::const_iterator j = players.begin(),
             j_end = players.end(); j != j_end; ++j)
        {
            msg.writeInt32(*j);
        }
    }
    send(msg);
}
Ejemplo n.º 3
0
bool GameState::insert(Entity *ptr)
{
    assert(!dbgLockObjects);
    MapComposite *map = ptr->getMap();
    assert(map && map->isActive());

    /* Non-visible objects have neither position nor public ID, so their
       insertion cannot fail. Take care of them first. */
    if (!ptr->isVisible())
    {
        map->insert(ptr);
        ptr->signal_inserted.emit(ptr);
        return true;
    }

    // Check that coordinates are actually valid.
    Actor *obj = static_cast< Actor * >(ptr);
    Map *mp = map->getMap();
    Point pos = obj->getPosition();
    if ((int)pos.x / mp->getTileWidth() >= mp->getWidth() ||
        (int)pos.y / mp->getTileHeight() >= mp->getHeight())
    {
        LOG_ERROR("Tried to insert an actor at position " << pos.x << ','
                  << pos.y << " outside map " << map->getID() << '.');
        // Set an arbitrary small position.
        pos = Point(100, 100);
        obj->setPosition(pos);
    }

    if (!map->insert(obj))
    {
        // The map is overloaded, no room to add a new actor
        LOG_ERROR("Too many actors on map " << map->getID() << '.');
        return false;
    }

    obj->signal_inserted.emit(obj);

    // DEBUG INFO
    switch (obj->getType())
    {
        case OBJECT_ITEM:
            LOG_DEBUG("Item inserted: "
                   << obj->getComponent<ItemComponent>()->getItemClass()->getDatabaseID());
            break;

        case OBJECT_NPC:
            LOG_DEBUG("NPC inserted: " << obj->getComponent<NpcComponent>()->getNpcId());
            break;

        case OBJECT_CHARACTER:
            LOG_DEBUG("Player inserted: "
                      << static_cast<Being*>(obj)->getName());
            break;

        case OBJECT_EFFECT:
            LOG_DEBUG("Effect inserted: "
                      << obj->getComponent<EffectComponent>()->getEffectId());
            break;

        case OBJECT_MONSTER:
            LOG_DEBUG("Monster inserted: "
                      << static_cast<Monster*>(obj)->getSpecy()->getId());
            break;

        case OBJECT_ACTOR:
        case OBJECT_OTHER:
        default:
            LOG_DEBUG("Entity inserted: " << obj->getType());
            break;
    }

    obj->raiseUpdateFlags(UPDATEFLAG_NEW_ON_MAP);
    if (obj->getType() != OBJECT_CHARACTER)
        return true;

    /* Since the player does not know yet where in the world its character is,
       we send a map-change message, even if it is the first time it
       connects to this server. */
    MessageOut mapChangeMessage(GPMSG_PLAYER_MAP_CHANGE);
    mapChangeMessage.writeString(map->getName());
    mapChangeMessage.writeInt16(pos.x);
    mapChangeMessage.writeInt16(pos.y);
    gameHandler->sendTo(static_cast< Character * >(obj), mapChangeMessage);

    // update the online state of the character
    accountHandler->updateOnlineStatus(
        static_cast< Character * >(obj)->getDatabaseID(), true);

    return true;
}
Ejemplo n.º 4
0
void GameState::update(int tick)
{
    currentTick = tick;

#ifndef NDEBUG
    dbgLockObjects = true;
#endif

    ScriptManager::currentState()->update();

    // Update game state (update AI, etc.)
    const MapManager::Maps &maps = MapManager::getMaps();
    for (MapManager::Maps::const_iterator m = maps.begin(),
         m_end = maps.end(); m != m_end; ++m)
    {
        MapComposite *map = m->second;
        if (!map->isActive())
            continue;

        map->update();

        for (CharacterIterator p(map->getWholeMapIterator()); p; ++p)
        {
            informPlayer(map, *p);
        }

        for (ActorIterator it(map->getWholeMapIterator()); it; ++it)
        {
            Actor *a = *it;
            a->clearUpdateFlags();
            if (a->canFight())
            {
                static_cast< Being * >(a)->clearHitsTaken();
            }
        }
    }

#   ifndef NDEBUG
    dbgLockObjects = false;
#   endif

    // Take care of events that were delayed because of their side effects.
    for (DelayedEvents::iterator it = delayedEvents.begin(),
         it_end = delayedEvents.end(); it != it_end; ++it)
    {
        const DelayedEvent &e = it->second;
        Actor *o = it->first;
        switch (e.type)
        {
            case EVENT_REMOVE:
                remove(o);
                if (o->getType() == OBJECT_CHARACTER)
                {
                    Character *ch = static_cast< Character * >(o);
                    ch->disconnected();
                    gameHandler->kill(ch);
                }
                delete o;
                break;

            case EVENT_INSERT:
                insertOrDelete(o);
                break;

            case EVENT_WARP:
                assert(o->getType() == OBJECT_CHARACTER);
                warp(static_cast< Character * >(o), e.map, e.x, e.y);
                break;
        }
    }
    delayedEvents.clear();
}
Ejemplo n.º 5
0
void GameState::update(int worldTime)
{
#   ifndef NDEBUG
    dbgLockObjects = true;
#   endif

    // Update game state (update AI, etc.)
    const MapManager::Maps &maps = MapManager::getMaps();
    for (MapManager::Maps::const_iterator m = maps.begin(), m_end = maps.end(); m != m_end; ++m)
    {
        MapComposite *map = m->second;
        if (!map->isActive())
        {
            continue;
        }

        updateMap(map);

        for (CharacterIterator p(map->getWholeMapIterator()); p; ++p)
        {
            informPlayer(map, *p);
            /*
             sending the whole character is overhead for the database, it should
             be replaced by a syncbuffer. see: game-server/accountconnection:
             AccountConnection::syncChanges()

            if (worldTime % 2000 == 0)
            {
                accountHandler->sendCharacterData(*p);
            }
            */
        }

        for (ActorIterator i(map->getWholeMapIterator()); i; ++i)
        {
            Actor *a = *i;
            a->clearUpdateFlags();
            if (a->canFight())
            {
                static_cast< Being * >(a)->clearHitsTaken();
            }
        }
    }

#   ifndef NDEBUG
    dbgLockObjects = false;
#   endif

    // Take care of events that were delayed because of their side effects.
    for (DelayedEvents::iterator i = delayedEvents.begin(),
            i_end = delayedEvents.end(); i != i_end; ++i)
    {
        const DelayedEvent &e = i->second;
        Actor *o = i->first;
        switch (e.type)
        {
        case EVENT_REMOVE:
            remove(o);
            if (o->getType() == OBJECT_CHARACTER)
            {
                Character *ch = static_cast< Character * >(o);
                ch->disconnected();
                gameHandler->kill(ch);
            }
            delete o;
            break;

        case EVENT_INSERT:
            insertSafe(o);
            break;

        case EVENT_WARP:
            assert(o->getType() == OBJECT_CHARACTER);
            warp(static_cast< Character * >(o), e.map, e.x, e.y);
            break;
        }
    }
    delayedEvents.clear();
}