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); } }
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); }
/// \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() ); }
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."); }
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); }
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() ); }
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); }
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; }