void GameHandler::handlePartyInvite(GameClient &client, MessageIn &message)
{
    MapComposite *map = client.character->getMap();
    const int visualRange = Configuration::getValue("game_visualRange", 448);
    std::string invitee = message.readString();

    if (invitee == client.character->getComponent<BeingComponent>()->getName())
        return;

    for (CharacterIterator it(map->getWholeMapIterator()); it; ++it)
    {
        if ((*it)->getComponent<BeingComponent>()->getName() == invitee)
        {
            // calculate if the invitee is within the visual range
            auto *inviterComponent =
                    client.character->getComponent<ActorComponent>();
            auto *inviteeComponent = (*it)->getComponent<ActorComponent>();
            const Point &inviterPosition = inviterComponent->getPosition();
            const Point &inviteePosition = inviteeComponent->getPosition();
            const int dx = std::abs(inviterPosition.x - inviteePosition.x);
            const int dy = std::abs(inviterPosition.y - inviteePosition.y);
            if (visualRange > std::max(dx, dy))
            {
                MessageOut out(GCMSG_PARTY_INVITE);
                out.writeString(client.character
                                ->getComponent<BeingComponent>()->getName());
                out.writeString(invitee);
                accountHandler->send(out);
                return;
            }
            break;
        }
    }

    // Invitee was not found or is too far away
    MessageOut out(GPMSG_PARTY_INVITE_ERROR);
    out.writeString(invitee);
    client.send(out);
}
Example #2
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();
}
Example #3
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();
}