示例#1
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);
    }
}
示例#2
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);
}
示例#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);

}
void CelestialNavigationDialog::OnDuplicate(wxCommandEvent &event)
{
    long selected_index = m_lSights->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
    if (selected_index < 0) return;

    Sight *psight = (Sight*)wxUIntToPtr(m_lSights->GetItemData(selected_index));
    Sight *ns = new Sight(*psight);
    ns->RebuildPolygons();
    InsertSight(ns);
    RequestRefresh( GetParent() );
}
void ClockCorrectionDialog::OnUpdate( wxSpinEvent& event )
{
    CelestialNavigationDialog *parent((CelestialNavigationDialog*)GetParent());
    wxListCtrl *lSights = parent->m_lSights;
    for(int i = 0; i<lSights->GetItemCount(); i++) {
        Sight *s = (Sight*)wxUIntToPtr(lSights->GetItemData(i));
        s->Recompute(m_sClockCorrection->GetValue());
    }

    parent->UpdateSights();
    RequestRefresh( parent->GetParent() );
}
示例#6
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.");
}
示例#7
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);
}
示例#8
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);
}
void CelestialNavigationDialog::OnNew(wxCommandEvent &event)
{
    wxDateTime now = wxDateTime::Now().ToUTC();

    Sight s(Sight::ALTITUDE, _("Sun"), Sight::LOWER, now, 0, 0, 10);
    SightDialog dialog(GetParent(), s, m_ClockCorrectionDialog.m_sClockCorrection->GetValue());
      
    if( dialog.ShowModal() == wxID_OK ) {
        Sight *ns = new Sight(s);

        dialog.Recompute();
        ns->RebuildPolygons();
        InsertSight(ns);
        RequestRefresh( GetParent() );
    }
}
void CelestialNavigationDialog::OnDRShift( wxCommandEvent& event )
{
    #if 0
    DRShiftDialog dialog;
    if(dialog.ShowModel() == wxID_OK) {
        double shiftnm, shiftbearing;
        dialog.m_tShiftNm->GetValue().ToDouble(&shiftnm);
        dialog.m_tShiftBearing->GetValue().ToDouble(&shiftbearing);
        bool MagneticShiftBearing = dialog.m_cbMagneticShiftBearing->GetValue();

        for (std::list<Sight*>::iterator it = m_SightList.begin(); it != m_SightList.end(); it++) {
            Sight *s = *it;
            if(!s->IsVisible())
                continue;

            if(s->m_bMagneticShiftBearing != MagneticShiftBearing
        }
    }
void CelestialNavigationDialog::OnEdit( )
{
    // Manipulate selected_index sight/track
    long selected_index = m_lSights->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
    if (selected_index < 0) return;

    Sight *psight = (Sight*)wxUIntToPtr(m_lSights->GetItemData(selected_index));
    Sight originalsight = *psight; /* in case of cancel */
    
    SightDialog dialog(GetParent(), *psight, m_ClockCorrectionDialog.m_sClockCorrection->GetValue());
    
    if( dialog.ShowModal() == wxID_OK ) {
        dialog.Recompute();
        psight->RebuildPolygons();
        UpdateSight(selected_index);
    } else
        *psight = originalsight;

    RequestRefresh( GetParent() );
}
示例#12
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);
    }
}
void CelestialNavigationDialog::UpdateFix()
{
    std::list<std::vector<double> > J;
    std::list<double> R;

    double X[3]; /* result */

    double initiallat = m_sInitialLatitude->GetValue(), initiallon = m_sInitialLongitude->GetValue();
    X[0] = cos(deg2rad(initiallat))*cos(deg2rad(initiallon));
    X[1] = cos(deg2rad(initiallat))*sin(deg2rad(initiallon));
    X[2] = sin(deg2rad(initiallat));

    int iterations = 0;
again:

    for (SightList::iterator it = m_SightList.begin(); it != m_SightList.end(); it++) {
        Sight *s = *it;
        if(!s->IsVisible() || s->m_Type != Sight::ALTITUDE)
            continue;
    
        if(s->m_ShiftNm) {
            static bool seenwarning = false;
            if(!seenwarning) {
                wxMessageDialog mdlg(this, _("Shifted sights are not used to compute a fix, \
determine fix visually instead.\n"), wxString(_("Fix Position"), wxID_OK | wxICON_WARNING));
                mdlg.ShowModal();
                seenwarning = true;
            }
            continue;
        }

        double lat, lon;
        s->BodyLocation(s->m_DateTime, &lat, &lon, 0, 0);

        /* take vector from body location of length equal to
           normalized measurement (so the plane this vector
           describes intersects the unit sphere along the positions
           the sight is valid) */
        std::vector<double> v;
        double x = cos(deg2rad(lat))*cos(deg2rad(lon));
        double y = cos(deg2rad(lat))*sin(deg2rad(lon));
        double z = sin(deg2rad(lat));

        double sm = sin(deg2rad(s->m_CorrectedAltitude));
        double cm = cos(deg2rad(s->m_CorrectedAltitude));

        double d;

        switch(m_cbFixAlgorithm->GetSelection()) {
        case 0: /* plane */
        plane:
            /* plane */
            v.push_back(x);
            v.push_back(y);
            v.push_back(z);
            d = sm - (X[0]*x + X[1]*y + X[2]*z);
            break;
        case 1: /* sphere */
        {
            double xc = X[0] - x, yc = X[1] - y, zc = X[2] - z;
            v.push_back(2*xc);
            v.push_back(2*yc);
            v.push_back(2*zc);
            d = cm*cm + (1-sm)*(1-sm) - xc*xc - yc*yc - zc*zc;
        } break;
        case 2: /* cone */
        {
            double t2 = X[0]*X[0] + X[1]*X[1] + X[2]*X[2], t = sqrt(t2);
            if(t < .1) goto plane;
            v.push_back(x);
            v.push_back(y);
            v.push_back(z);
            d = sm - (X[0]*x + X[1]*y + X[2]*z)/t;
        } break;
        case 3: /* cone 2 */
        {
            double t2 = X[0]*X[0] + X[1]*X[1] + X[2]*X[2], t = sqrt(t2);
            if(t < .1) goto plane;
            v.push_back(x/t - x*X[0]*X[0]/(t*t2));
            v.push_back(y/t - y*X[1]*X[1]/(t*t2));
            v.push_back(z/t - z*X[2]*X[2]/(t*t2));
            d = sm - (X[0]*x + X[1]*y + X[2]*z)/t;
        } break;
        }

        J.push_back(v);
        R.push_back(d);
    }
示例#14
0
void Commander::dispatch(const RootOperation& op)
{
    Appearance appear = smart_dynamic_cast<Appearance>(op);
    if (appear.isValid()) {
        assert(op->hasAttr("for"));
        Agent* ag = m_server->findAgentForEntity(op->getAttr("for").asString());
        if (ag) {
            ag->setEntityVisible(op->getTo(), true);
        } else {
            // doesn't exist yet, mark as visible if / when the agent is created
            Agent::setEntityVisibleForFutureAgent(op->getTo(), op->getAttr("for").asString());
        }
    }
    
    Disappearance disap = smart_dynamic_cast<Disappearance>(op);
    if (disap.isValid()) {
        assert(op->hasAttr("for"));
        Agent* ag = m_server->findAgentForEntity(op->getAttr("for").asString());
        if (ag) ag->setEntityVisible(op->getTo(), false);
    }
    
    Create cr = smart_dynamic_cast<Create>(op);
    if (cr.isValid()) {
        std::vector<Root> args(op->getArgs());
        assert(!args.empty());
        RootEntity ent = smart_dynamic_cast<RootEntity>(args.front());
        assert(ent.isValid());
        
        static int idCounter = 900;
        char buf[32];
        snprintf(buf, 32, "_created_%d", ++idCounter);
        std::string id(buf);
        
        ent->setId(id);
        std::string loc = ent->getLoc();
        assert(m_server->m_world.count(loc));
        
        StringList children(m_server->m_world[loc]->getContains());
        children.push_back(id);
        m_server->m_world[loc]->setContains(children);

        m_server->m_world[id] = ent;
        
        Create bcr(cr);
        bcr->setArgs1(ent);
        Agent::broadcastSight(bcr);
    }
    
    Delete del = smart_dynamic_cast<Delete>(op);
    if (del.isValid()) {
        std::vector<Root> args(op->getArgs());
        assert(!args.empty());
        
        std::string id = args.front()->getId();
        assert(m_server->m_world.count(id));
        m_server->m_world.erase(id);
        
        Agent::broadcastSight(op);
    }
    
    Move mv = smart_dynamic_cast<Move>(op);
    if (mv.isValid()) {
        RootEntity ent = m_server->getEntity(op->getTo());
        
        std::vector<Root> args(op->getArgs());
        
        if (args.front()->hasAttr("loc")) {
            std::string newLocId = args.front()->getAttr("loc").asString();
            
            RootEntity oldLoc = m_server->getEntity(ent->getLoc()),
                newLoc = m_server->getEntity(newLocId);
            
            ent->setLoc(newLocId);
            // modify stamps?
            oldLoc->modifyContains().remove(ent->getId());
            newLoc->modifyContains().push_back(ent->getId());
        }
        
        if (args.front()->hasAttr("pos"))
            ent->setPosAsList(args.front()->getAttr("pos").asList());
            
        // handle velocity changes
        Agent::broadcastSight(op);
        return;
    }
    
    Sound snd = smart_dynamic_cast<Sound>(op);
    if (snd.isValid()) {
        
        std::vector<Root> args(op->getArgs());
        assert(!args.empty());
        
        if (snd->hasAttr("broadcast")) {
            Agent::broadcastSound(smart_dynamic_cast<RootOperation>(args.front()));
        }
    }
    
    Sight st = smart_dynamic_cast<Sight>(op);
    if (st.isValid()) {
        if (st->hasAttr("broadcast")) {
            std::vector<Root> args(op->getArgs());
            assert(!args.empty());
            Agent::broadcastSight(smart_dynamic_cast<RootOperation>(args.front()));
        }
    }
    
    Set s = smart_dynamic_cast<Set>(op);
    if (s.isValid()) {
        
        std::vector<Root> args(op->getArgs());
        for (unsigned int A=0; A < args.size(); ++A) {
            std::string eid = args[A]->getId();
        
            RootEntity entity = m_server->getEntity(eid);
            Root::const_iterator I = args[A]->begin();
            
            for (; I != args[A]->end(); ++I) {
                if ((I->first == "id") || (I->first == "parents") || (I->first == "objtype")) {
                    continue;
                }
                
                assert(I->first != "loc");
                entity->setAttr(I->first, I->second);
            }
        }

        Agent::broadcastSight(s);
    }
    
    Action act = smart_dynamic_cast<Action>(op);
    if (act.isValid()) {
        std::vector<Root> args(op->getArgs());
        
        if (act->getParents().front() == "command") {
            std::string cid = args[0]->getAttr("cid").asString();
            
            if (cid == "socket-shutdown") {
                std::string acc = args[0]->getAttr("acc").asString();
                ClientConnection* cc = m_server->getConnectionForAccount(acc);
                assert(cc);
                cc->shutdown();
            } else if (cid == "add-many-objects") {
                m_server->addManyObjects(args[0]->getAttr("acc").asString());
            } else if (cid == "set-world-time") {
                /* double t = */ args[0]->getAttr("seconds").asFloat();
                
            } else {
                std::cerr << "unknown command " << cid << std::endl;
            }
        } // of command action case
    } // of action case
}
bool CelestialNavigationDialog::OpenXML(wxString filename, bool reportfailure)
{
    TiXmlDocument doc;
    wxString error;

    wxFileName fn(filename);

    if(!doc.LoadFile(filename.mb_str()))
        FAIL(_("Failed to load file: ") + filename);
    else {
        TiXmlHandle root(doc.RootElement());

        if(strcmp(root.Element()->Value(), "OpenCPNCelestialNavigation"))
            FAIL(_("Invalid xml file"));

        m_lSights->DeleteAllItems();

        for(TiXmlElement* e = root.FirstChild().Element(); e; e = e->NextSiblingElement()) {
            if(!strcmp(e->Value(), "ClockError")) {
                m_ClockCorrectionDialog.m_sClockCorrection->SetValue(AttributeInt(e, "Seconds", 0));
            } else if(!strcmp(e->Value(), "Sight")) {
                Sight s;

                s.m_bVisible = AttributeBool(e, "Visible", true);
                s.m_Type = (Sight::Type)AttributeInt(e, "Type", 0);
                s.m_Body = wxString::FromUTF8(e->Attribute("Body"));
                s.m_BodyLimb = (Sight::BodyLimb)AttributeInt(e, "BodyLimb", 0);

                s.m_DateTime.ParseISODate(wxString::FromUTF8(e->Attribute("Date")));

                wxDateTime time;
                time.ParseISOTime(wxString::FromUTF8(e->Attribute("Time")));

                if(s.m_DateTime.IsValid() && time.IsValid()) {
                    s.m_DateTime.SetHour(time.GetHour());
                    s.m_DateTime.SetMinute(time.GetMinute());
                    s.m_DateTime.SetSecond(time.GetSecond());
                } else
                    continue; /* skip if invalid */
            
                s.m_TimeCertainty = AttributeDouble(e, "TimeCertainty", 0);

                s.m_Measurement = AttributeDouble(e, "Measurement", 0);
                s.m_MeasurementCertainty = AttributeDouble(e, "MeasurementCertainty", .25);

                s.m_EyeHeight = AttributeDouble(e, "EyeHeight", 2);
                s.m_Temperature = AttributeDouble(e, "Temperature", 10);
                s.m_Pressure = AttributeDouble(e, "Pressure", 1010);
                s.m_IndexError = AttributeDouble(e, "IndexError", 0);

                s.m_ShiftNm = AttributeDouble(e, "ShiftNm", 0);
                s.m_ShiftBearing = AttributeDouble(e, "ShiftBearing", 0);
                s.m_bMagneticShiftBearing = AttributeBool(e, "MagneticShiftBearing", 0);

                s.m_ColourName = wxString::FromUTF8(e->Attribute("ColourName"));
                s.m_Colour = wxColour(wxString::FromUTF8(e->Attribute("Colour")));
                s.m_Colour.Set(s.m_Colour.Red(), s.m_Colour.Green(), s.m_Colour.Blue(),
                               AttributeInt(e, "Transparency", 150));

                Sight *ns = new Sight(s);

                ns->Recompute(m_ClockCorrectionDialog.m_sClockCorrection->GetValue());
                ns->RebuildPolygons();
                InsertSight(ns, false);
            } else
                FAIL(_("Unrecognized xml node"));
        }
    }

    RequestRefresh( GetParent() );
    return true;
failed:

    if(reportfailure) {
        wxMessageDialog mdlg(this, error, _("Celestial Navigation"), wxOK | wxICON_ERROR);
        mdlg.ShowModal();
    }
    return false;
}