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); }
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 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 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); } }