示例#1
0
void Thing::DeleteOperation(const Operation & op, OpVector & res)
{
    if (m_location.m_loc == 0) {
        log(ERROR, String::compose("Deleting %1(%2) when it is not "
                                   "in the world.", getType(), getId()));
        assert(m_location.m_loc != 0);
        return;
    }
    // The actual destruction and removal of this entity will be handled
    // by the WorldRouter

    if (isPerceptive()) {
        //We need to send a sight operation directly to the entity.
        //The reason is that else the entity will be deleted before it can receive the broadcast Sight
        //of the Delete op, which will leave any external clients hanging.
        Sight sToEntity;
        sToEntity->setArgs1(op);
        sToEntity->setTo(getId());
        operation(sToEntity, res);
    }

    Sight s;
    s->setArgs1(op);
    res.push_back(s);

    Entity::DeleteOperation(op, res);
}
示例#2
0
void World::LookOperation(const Operation & op, OpVector & res)
{
    // We must be the top level entity
    assert(m_location.m_parent == nullptr);
    // We must contains something, or where the hell did the look come from?
    assert(m_contains != nullptr);

    //The top level entity is a little special, since its properties can be inspected by all entities, although it's children can not.
    //First check if there's a movement domain. If so we'll handle Look ops just like usually. However, if not we'll send the properties sans the "contains" property.
    auto from = BaseWorld::instance().getEntity(op->getFrom());
    if (!from) {
        log(ERROR, String::compose("Look op has invalid from %1. %2", op->getFrom(), describeEntity()));
        return;
    }

    Domain* domain = nullptr;
    if (m_location.m_parent) {
        domain = m_location.m_parent->getDomain();
    }
    if (domain) {
        generateSightOp(*from, op, res);
    } else {
        Sight s;

        Anonymous sarg;
        addToEntity(sarg);
        //Hide all contents of the root entity.
        sarg->removeAttr("contains");
        s->setArgs1(sarg);
        s->setTo(op->getFrom());
        res.push_back(s);
    }
}
示例#3
0
/// \brief Handle a relay operation
void Entity::RelayOperation(const Operation & op, OpVector & res)
{
    if (op->getArgs().empty()) {
        log(ERROR, "Entity::RelayOperation no args.");
        return;
    }
    Operation relayedOp = Atlas::Objects::smart_dynamic_cast<Operation>(
            op->getArgs().front());

    if (!relayedOp.isValid()) {
        log(ERROR,
                "Entity::RelayOperation first arg is not an operation.");
        return;
    }

    if (op->isDefaultSerialno()) {
        log(ERROR, "Entity::RelayOperation no serial number.");
        return;
    }

    //Add a sight of the operation
    Sight sight;
    sight->setArgs1(relayedOp);

    Atlas::Objects::Operation::Generic responseOp;
    responseOp->setType("relay", Atlas::Objects::Operation::RELAY_NO);
    responseOp->setArgs1(sight);
    responseOp->setTo(op->getFrom());
    res.push_back(responseOp);

    //Make sure that the contained op is addressed to the entity
    relayedOp->setTo(getId());
    operation(relayedOp, res);

}
示例#4
0
void World::clearWorld(OpVector & res) {
    log(INFO, "Clearing world; deleting all entities.");

    OpVector ignoredRes;
    auto& baseWorld = BaseWorld::instance();
    if (m_contains) {
        while (!m_contains->empty()) {

            auto& entity = *m_contains->begin();

            if (entity->isPerceptive()) {
                //Send a sight of a delete op to the entity so that it knows it has been deleted.
                Delete delOp;
                delOp->setTo(entity->getId());

                Anonymous delArg;
                delArg->setId(entity->getId());
                delOp->setArgs1(delArg);

                Sight sToEntity;
                sToEntity->setArgs1(delOp);
                sToEntity->setTo(entity->getId());
                entity->operation(sToEntity, ignoredRes);
            }
            baseWorld.delEntity(entity.get());
        }
    }

    //Remove all properties except for "id"
    auto propIter = m_properties.begin();
    while(propIter != m_properties.end())
    {
        if (propIter->first != "id") {
            auto prop = propIter->second;
            prop->remove(this, propIter->first);
            delete prop;
            m_properties.erase(propIter++);
        } else {
            ++propIter;
        }
    }

    CalendarProperty* calProp = new CalendarProperty();
    calProp->install(this, "calendar");
    m_properties["calendar"] = calProp;

    delete m_contains;
    m_contains = nullptr;

    log(INFO, "World cleared of all entities.");
}
示例#5
0
void Thing::DeleteOperation(const Operation & op, OpVector & res)
{
    if (m_location.m_loc == 0) {
        log(ERROR, String::compose("Deleting %1(%2) when it is not "
                                   "in the world.", getType(), getId()));
        assert(m_location.m_loc != 0);
        return;
    }
    // The actual destruction and removal of this entity will be handled
    // by the WorldRouter
    Sight s;
    s->setArgs1(op);
    res.push_back(s);
}
示例#6
0
void ClientConnection::processOOGLook(const Look& lk)
{
    const std::vector<Root>& args = lk->getArgs();
    std::string lookTarget;
                
    if (args.empty()) {
        lookTarget = "_lobby";
    } else {
        lookTarget = args.front()->getId();
    }
    
    RootEntity thing;
    if (m_server->m_accounts.count(lookTarget))
    {
        thing = m_server->m_accounts[lookTarget];
        if (lookTarget != lk->getFrom())
        {
            // prune
            thing->removeAttr("characters");
            thing->removeAttr("password");
        }
    }
    else if (m_server->m_world.count(lookTarget))
    {
        // ensure it's owned by the account, i.e in characters
        if (!entityIsCharacter(lookTarget))
        {
            sendError("not allowed to look at that entity", lk);
            return;
        }
        
        thing = m_server->m_world[lookTarget];
    }
    else if (m_server->m_rooms.count(lookTarget))
    {
        // should check room view permissions?
        thing = m_server->m_rooms[lookTarget];
    } else {
        // didn't find any entity with the id
        sendError("processed OOG look for unknown entity " + lookTarget, lk);
        return;
    }
    
    Sight st;
    st->setArgs1(thing);
    st->setFrom(lookTarget);
    st->setTo(lk->getFrom());
    st->setRefno(lk->getSerialno());
    send(st);
}
示例#7
0
void Statistics::increment(const std::string & name, OpVector & res)
{
    float oldval, newval;

    // Check if we have this skill already
    SkillDict::iterator I = m_skills.find(name);
    if (I == m_skills.end()) {
        // We dont have this skill yet
        oldval = 0.f;
        newval = 0.01f;
        m_skills.insert(std::make_pair(name, newval));
    } else {
        // We have this skill, increment in a curve which tends towards 1
        oldval = I->second;
        // FIXME Need to replace with a more flexible function which
        // gives the right curve
        newval = oldval + ((1.f - std::min(oldval, 1.f)) / 1000.f);
        I->second = newval;
    }

    // If value has changed by more than 0.001 then report to character.
    if ((int)(newval * 1000) != (int)(oldval * 1000)) {
        Set set;
        Anonymous set_arg;
        MapType skills;
        skills[name] = newval;
        set_arg->setAttr("skills", skills);
        set_arg->setId(m_character.getId());
        set->setTo(m_character.getId());
        set->setFrom(m_character.getId());
        set->setArgs1(set_arg);
        Sight sight;
        sight->setArgs1(set);
        sight->setTo(m_character.getId());
        res.push_back(sight);
    }
}