static void fight(char_t *c) { // Always hit the enemy first int damage = getDamage(getPlayer(), c); char buf[50]; if(!doDamage(c, damage)){ getPlayer()->stats.xp += c->stats.xp; removeCharMap(&map, c); sprintf(buf, "You killed \"%s\"", getNameFromChar(c)); popupText(buf); checkLevelUp(); return; }else{ sprintf(buf, "You deal %d damage", damage); popupText(buf); } damage = getDamage(c, getPlayer()); sprintf(buf, "You take %d damage", damage); popupText(buf); if(!doDamage(getPlayer(), damage)){ getPlayer()->stats.health = 0; die(); } }
bool ConditionDamage::executeCondition(Creature* creature, const int32_t& interval) { if (periodDamage != 0) { periodDamageTick += interval; if (periodDamageTick >= tickInterval) { periodDamageTick = 0; doDamage(creature, periodDamage); } } else if (!damageList.empty()) { IntervalInfo& damageInfo = damageList.front(); bool bRemove = (getTicks() != -1); creature->onTickCondition(getType(), interval, bRemove); damageInfo.timeLeft -= interval; if (damageInfo.timeLeft <= 0) { int32_t damage = damageInfo.value; if (bRemove) { damageList.pop_front(); } else { //restore timeLeft damageInfo.timeLeft = damageInfo.interval; } doDamage(creature, damage); } if (!bRemove) { if (getTicks() > 0) { endTime = endTime + interval; } return Condition::executeCondition(creature, 0); } } return Condition::executeCondition(creature, interval); }
void fireCollisionCb(Body* self, Body* other, Contact* contact, ContactResponse* response) { response->mBounceThem = true; response->mBounceMe = true; doDamage(self, other, Fire, 10.0f); }
void Shit::onMove(const CardMoveStruct &move) const{ ServerPlayer *from = (ServerPlayer*)move.from; if(from && move.from_place == Player::PlaceHand && from->getRoom()->getCurrent() == move.from && (move.to_place == Player::DiscardPile || move.to_place == Player::TopDrawPile || move.to_place == Player::DealingArea) && move.to == NULL){ doDamage((ServerPlayer*)move.from); } }
void BunkerBlock::onCollision(const Entity* entity) { //auto bullet = static_cast<const Bullet*>(entity); Message::BulletHitMessage msg(entity->getId(), this->getId()); notifyCollision(msg); doDamage(1); }
bool ConditionDamage::startCondition(Creature* creature) { if(!Condition::startCondition(creature) || !init()) return false; if(delayed) return true; int32_t damage = 0; return !getNextDamage(damage) || doDamage(creature, damage); }
void enemyWeaponHeatSeakerCollisionCb(Body* self, Body* other, Contact* contact, ContactResponse* response) { response->mBounceThem = true; response->mBounceMe = false; Particle* p = (Particle*)self->mUserArg; HeatSeakerParticleData* data = (HeatSeakerParticleData*)p->mData; doDamage(self, other, HeatSeakerMissle, data->mWeaponData->mDamage); gWorld->getParticleSystem()->removeParticle(p); gWorld->getParticleSystem()->initExplosionParticle(self->mCenter); }
bool ConditionDamage::executeCondition(Creature* creature, int32_t interval) { if(periodDamage) { periodDamageTick += interval; if(periodDamageTick >= tickInterval) { periodDamageTick = 0; doDamage(creature, periodDamage); } } else if(!damageList.empty()) { bool remove = getTicks() != -1; creature->onTickCondition(getType(), interval, remove); IntervalInfo& damageInfo = damageList.front(); damageInfo.timeLeft -= interval; if(damageInfo.timeLeft <= 0) { int32_t damage = damageInfo.value; if(remove) damageList.pop_front(); else damageInfo.timeLeft = damageInfo.interval; doDamage(creature, damage); } if(!remove) { if(getTicks() > 0) endTime += interval; interval = 0; } } return Condition::executeCondition(creature, interval); }
void MobV2SAO::punch(ServerActiveObject *puncher, float time_from_last_punch) { if(!puncher) return; v3f dir = (getBasePosition() - puncher->getBasePosition()).normalize(); // A quick hack; SAO description is player name for player std::string playername = puncher->getDescription(); Map *map = &m_env->getMap(); actionstream<<playername<<" punches mob id="<<m_id <<" at "<<PP(m_base_position/BS)<<std::endl; m_disturb_timer = 0; m_disturbing_player = playername; m_next_pos_exists = false; // Cancel moving immediately m_yaw = wrapDegrees_180(180./PI*atan2(dir.Z, dir.X) + 180.); v3f new_base_position = m_base_position + dir * BS; { v3s16 pos_i = floatToInt(new_base_position, BS); v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5); v3s16 pos_size_off(0,0,0); if(m_size.X >= 2.5){ pos_size_off.X = -1; pos_size_off.Y = -1; } bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks); if(free) m_base_position = new_base_position; } sendPosition(); // "Material" properties of the MobV2 MaterialProperties mp; mp.diggability = DIGGABLE_NORMAL; mp.crackiness = -1.0; mp.cuttability = 1.0; ToolDiggingProperties tp; puncher->getWieldDiggingProperties(&tp); HittingProperties hitprop = getHittingProperties(&mp, &tp, time_from_last_punch); doDamage(hitprop.hp); puncher->damageWieldedItem(hitprop.wear); }
void ConditionDamage::addCondition(Creature* creature, const Condition* addCondition) { if (addCondition->getType() == conditionType) { const ConditionDamage& conditionDamage = static_cast<const ConditionDamage&>(*addCondition); if (updateCondition(&conditionDamage)) { setTicks(addCondition->getTicks()); owner = conditionDamage.owner; maxDamage = conditionDamage.maxDamage; minDamage = conditionDamage.minDamage; startDamage = conditionDamage.startDamage; tickInterval = conditionDamage.tickInterval; periodDamage = conditionDamage.periodDamage; int32_t nextTimeLeft = tickInterval; if (!damageList.empty()) { //save previous timeLeft IntervalInfo& damageInfo = damageList.front(); nextTimeLeft = damageInfo.timeLeft; damageList.clear(); } damageList = conditionDamage.damageList; if (init()) { if (!damageList.empty()) { //restore last timeLeft IntervalInfo& damageInfo = damageList.front(); damageInfo.timeLeft = nextTimeLeft; } if (!delayed) { int32_t damage = 0; if (getNextDamage(damage)) { doDamage(creature, damage); } } } } } }
void lightningBulletCollisionCallback(Body* self, Body* other, Contact* contact, ContactResponse* response) { response->mBounceMe = true; response->mBounceThem = true; gWorld->getParticleSystem()->initSmokeParticle(contact->mContactPoint, 0.0f, Vector2(0,0), 5); doDamage(self, other, Lightning , 20.0f); // Stop in place and fade to dark. Particle* me = (Particle*)self->mUserArg; gWorld->getPhysics()->removeBody(me->mBody); me->mBody = 0; me->mCallback = lightningBulletFadeParticleCallback; }
void Bullet::onCollision(const Entity* entity) { if(entity->getType() == Model::LASERCANNON && type == FRIENDLY) { return; } if(entity->getType() == Model::ALIEN && type == ENEMY) { return; } auto msg = Message::BulletHitMessage(getId(), entity->getId()); notifyCollision(msg); doDamage(1); }
bool ConditionDamage::startCondition(Creature* creature) { if(!Condition::startCondition(creature)) return false; if(!init()) return false; if(!delayed) { int32_t damage = 0; if(getNextDamage(damage)) return doDamage(creature, damage); } return true; }
void BaseBullet::update(float time) { if (!Target) { _deleted = true; return; } float dist = Target->massCenterPosition().distance(position()); if (dist > (0.5f * Target->LocalGameData.GameData->GeometryRadius)) { Vector3 dir = (Target->massCenterPosition() - position()) / dist; setPosition(position() + dir * min(dist, time * 0.01f)); } else { _deleted = true; doDamage(Target); } }
void Oerkki1SAO::punch(ServerActiveObject *puncher, float time_from_last_punch) { if(!puncher) return; v3f dir = (getBasePosition() - puncher->getBasePosition()).normalize(); m_speed_f += dir*12*BS; // "Material" properties of an oerkki MaterialProperties mp; mp.diggability = DIGGABLE_NORMAL; mp.crackiness = -1.0; mp.cuttability = 1.0; ToolDiggingProperties tp; puncher->getWieldDiggingProperties(&tp); HittingProperties hitprop = getHittingProperties(&mp, &tp, time_from_last_punch); doDamage(hitprop.hp); puncher->damageWieldedItem(hitprop.wear); }
void Combat::doAttacke(JobSet* jobSetAnims, JobSet* jobSetDamage, Combatant* actor, Combatant* target) { bool damageSp = false; GameEventLog::getSingleton().logEvent( actor->getName() + " attackiert " + target->getName(), GET_COMBAT); DamageStrength rollDamage = DMG_NONE; // Make an attack roll. int aresult = actor->rollAttacke(); if (aresult >= RESULT_ERFOLG) { if (aresult >= RESULT_GLUECKLICH) { rollDamage = DMG_DOUBLE; } else { rollDamage = DMG_NORMAL; } // Ok, succeeded // Has target registered a reaction? CombatantReactionsMap::iterator it = mCombatantReactions.find(target); if (it != mCombatantReactions.end()) { // Yes, there is a reaction if (it->second == PARADE) { int presult = target->rollParade(aresult >= RESULT_GLUECKLICH); if (presult >= RESULT_ERFOLG) { GameEventLog::getSingleton().logEvent("Erfolg, aber pariert.", GET_COMBAT); if (target->getActiveWeapon()->isNatural() && !actor->getActiveWeapon()->isNatural()) { rollDamage = DMG_HALF; } else if (!target->getActiveWeapon()->isNatural() && actor->getActiveWeapon()->isNatural()) { doDamage(jobSetAnims, DMG_HALF, target, actor); rollDamage = DMG_NONE; } else { rollDamage = DMG_NONE; } damageSp = target->getActiveWeapon()->isAvoidingArmor(); } else { GameEventLog::getSingleton().logEvent("Erfolg, nicht pariert, Treffer!", GET_COMBAT); } target->doParade(jobSetAnims, actor, presult); actor->doAttacke(jobSetAnims, target, aresult, true, presult); } else if (it->second == AUSWEICHEN) { // Faellt aus wegen is nich. } } else { GameEventLog::getSingleton().logEvent("Treffer!", GET_COMBAT); actor->doAttacke(jobSetAnims, target, aresult, false); } } else { GameEventLog::getSingleton().logEvent("Verfehlt!", GET_COMBAT); actor->doAttacke(jobSetAnims, target, aresult, false); target->doGetroffen(jobSetAnims); } doDamage(jobSetAnims, rollDamage, actor, target); }
void RSPCombat::doCombat(std::map<uint32_t, IdSet> sides) { Game* game = Game::getGame(); PlayerManager::Ptr playermanager = game->getPlayerManager(); ObjectManager* objectmanager = game->getObjectManager(); DesignStore::Ptr ds = game->getDesignStore(); const char * const rsp[] = {"rock", "scissors", "paper"}; IdSet listallobids; IdSet listallplayerids; std::map<uint32_t, std::vector<Combatant*> > fleetcache; battlelogger.reset(new BattleXML::BattleLogger()); msgstrings.clear(); for(std::map<uint32_t, IdSet>::iterator itmap = sides.begin(); itmap != sides.end(); ++itmap) { std::vector<Combatant*> pcombatant; Player::Ptr player = playermanager->getPlayer(itmap->first); battlelogger->startSide(player->getName()); IdSet theset = itmap->second; for(IdSet::iterator itset = theset.begin(); itset != theset.end(); ++itset) { listallobids.insert(*itset); IGObject::Ptr obj = objectmanager->getObject (*itset); objectcache[*itset] = obj; if(obj->getType() == obT_Fleet) { Fleet* f2 = (Fleet*)(obj->getObjectBehaviour()); IdMap shiplist = f2->getShips(); uint32_t damage = f2->getDamage(); for(IdMap::reverse_iterator itship = shiplist.rbegin(); itship != shiplist.rend(); ++itship) { for(uint32_t i = 0; i < itship->second; i++) { Combatant* f1 = new Combatant(); f1->setOwner(itmap->first); f1->setObject(obj->getID()); f1->setShipType(itship->first); uint32_t mydamage = damage / std::max(1U, (unsigned int)(shiplist.size() - i)); f1->setDamage(mydamage); damage -= mydamage; std::string type = ds->getDesign(itship->first)->getName(); f1->setBattleXmlType(type); f1->setBattleXmlId(str(boost::format("%1%-%2%-%3%") % type % obj->getID() % i)); f1->setBattleXmlName(str(boost::format("%1%'s %2%, %3% %4%") % player->getName() % obj->getName() % type % i)); battlelogger->addCombatant(f1); pcombatant.push_back(f1); } } } else { int shipcount = 2; int homeplanetid = game->getResourceManager()->getResourceDescription("Home Planet")->getResourceType(); if(((Planet*)(obj->getObjectBehaviour()))->getResource(homeplanetid) == 1) { //three more for home planets shipcount += 3; } for(int i = 0; i < shipcount; i++) { Combatant* f1 = new Combatant(); f1->setOwner(itmap->first); f1->setObject(obj->getID()); f1->setShipType(0); f1->setBattleXmlType("planet"); f1->setBattleXmlId(str(boost::format("planet-%1%-%2%") % obj->getID() % i)); f1->setBattleXmlName(str(boost::format("%1%'s colony on %2%, Defense battery %3%") % player->getName() % obj->getName() % i)); battlelogger->addCombatant(f1); pcombatant.push_back(f1); } } } listallplayerids.insert(itmap->first); battlelogger->endSide(); //sort combatant list by ship type, descending sort(pcombatant.begin(), pcombatant.end(), CombatantSorter()); fleetcache[itmap->first] = pcombatant; } for(std::set<uint32_t>::iterator itplayer = listallplayerids.begin(); itplayer != listallplayerids.end(); ++itplayer) { msgstrings[*itplayer] = ""; } Random* random = Game::getGame()->getRandom(); Logger::getLogger()->debug("Combat start"); while(fleetcache.size() >= 2) { battlelogger->startRound(); uint32_t pos1, pos2; if(fleetcache.size() == 2) { pos1 = 0; pos2 = 1; } else { pos1 = pos2 = random->getInRange(0U, ((uint32_t)(fleetcache.size() - 1))); while(pos2 == pos1) { pos2 = random->getInRange(0U, ((uint32_t)(fleetcache.size() - 1))); } } std::map<uint32_t, std::vector<Combatant*> >::iterator itpa = fleetcache.begin(); advance(itpa, pos1); std::map<uint32_t, std::vector<Combatant*> >::iterator itpb = fleetcache.begin(); advance(itpb, pos2); std::vector<Combatant*> f1 = itpa->second; std::vector<Combatant*> f2 = itpb->second; uint32_t ownerid1 = f1[0]->getOwner(); uint32_t ownerid2 = f2[0]->getOwner(); std::string p1name = playermanager->getPlayer(ownerid1)->getName(); std::string p2name = playermanager->getPlayer(ownerid2)->getName(); int32_t r1 = random->getInRange((int32_t)0, (int32_t)2); int32_t r2 = random->getInRange((int32_t)0, (int32_t)2); std::map<Combatant*, uint32_t> d1, d2; battlelogger->log(str(boost::format("%1%'s fleet chooses %2%.") % p1name % rsp[r2])); battlelogger->log(str(boost::format("%1%'s fleet chooses %2%.") % p2name % rsp[(r2 + r1) % 3])); if(r1 == 0) { //draw battlelogger->log("It's a draw"); d1 = buildShotList(f1, true); d2 = buildShotList(f2, true); if(d1.size() != 0) doDamage(d1, f2); if(d2.size() != 0) doDamage(d2, f1); } else { if(r1 == 1) { //pa win battlelogger->log(str(boost::format("%1% wins.") % p1name)); d1 = buildShotList(f1); if(d1.size() == 0) { battlelogger->log(str(boost::format("%1%'s forces escape") % p1name)); msgstrings[ownerid1] += "Your Fleet escaped. "; for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid1) continue; msgit->second += str(boost::format("%1%'s fleet of escaped. ") % p1name); } resolveCombatantsToObjects(f1); for(std::vector<Combatant*>::iterator itcombatant = f1.begin(); itcombatant != f1.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpa); battlelogger->endRound(); continue; } doDamage(d1, f2); } else { //pb win battlelogger->log(str(boost::format("%1% wins.") % p2name)); d2 = buildShotList(f2); if(d2.size() == 0) { battlelogger->log(str(boost::format("%1%'s forces escape") % p2name)); msgstrings[ownerid2] += "Your Fleet escaped. "; for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid2) continue; msgit->second += str(boost::format("%1%'s fleet of escaped. ") % p2name); } resolveCombatantsToObjects(f2); for(std::vector<Combatant*>::iterator itcombatant = f2.begin(); itcombatant != f2.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpb); battlelogger->endRound(); continue; } doDamage(d2, f1); } } if(isAllDead(f1)) { msgstrings[ownerid1] += str(boost::format("Your fleet was destroyed by %1%'s fleet. ") % p2name); msgstrings[ownerid2] += str(boost::format("You destroyed %1%'s fleet. ") % p1name); std::string deathmsg = str(boost::format("%1%'s fleet destroyed %2%'s fleet. ") % p1name % p2name); for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid1 || msgit->first == ownerid2) continue; msgit->second += deathmsg; } resolveCombatantsToObjects(f1); for(std::vector<Combatant*>::iterator itcombatant = f1.begin(); itcombatant != f1.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpa); } if(isAllDead(f2)) { msgstrings[ownerid2] += str(boost::format("Your fleet was destroyed by %1%'s fleet. ") % p1name); msgstrings[ownerid1] += str(boost::format("You destroyed %1%'s fleet. ") % p2name); std::string deathmsg = str(boost::format("%1%'s fleet destroyed %2%'s fleet. ") % p2name % p1name); for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { if(msgit->first == ownerid1 || msgit->first == ownerid2) continue; msgit->second += deathmsg; } resolveCombatantsToObjects(f2); for(std::vector<Combatant*>::iterator itcombatant = f2.begin(); itcombatant != f2.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(itpb); } battlelogger->endRound(); } std::string file = battlelogger->save(); if(!fleetcache.empty()) { std::vector<Combatant*> flast = fleetcache.begin()->second; resolveCombatantsToObjects(flast); msgstrings[flast[0]->getOwner()] += "Your Fleet survived combat."; for(std::vector<Combatant*>::iterator itcombatant = flast.begin(); itcombatant != flast.end(); ++itcombatant) { delete *itcombatant; } fleetcache.erase(fleetcache.begin()); if(!fleetcache.empty()) { Logger::getLogger()->warning("fleetcache not empty at end of combat"); } } for(std::map<uint32_t, std::string>::iterator msgit = msgstrings.begin(); msgit != msgstrings.end(); ++msgit) { Message::Ptr msg( new Message() ); msg->setSubject("Combat"); for(std::set<uint32_t>::iterator itob = listallobids.begin(); itob != listallobids.end(); ++itob) { msg->addReference(rst_Object, *itob); } for(std::set<uint32_t>::iterator itpl = listallplayerids.begin(); itpl != listallplayerids.end(); ++itpl) { msg->addReference(rst_Player, *itpl); } msg->setBody(msgit->second); Game::getGame()->getPlayerManager()->getPlayer(msgit->first)->postToBoard(msg); } for(std::map<uint32_t, IGObject::Ptr>::iterator itob = objectcache.begin(); itob != objectcache.end(); ++itob) { Game::getGame()->getObjectManager()->doneWithObject(itob->first); } objectcache.clear(); }
void LamakiWarrior::fire() { doDamage(Target); }
//Collide with another object void Spaceship::collide(SceneNode * other) { if(dynamic_cast<Projectile*>(other) && ((Entity*)other)->getTeam() != getTeam()) doDamage(((Projectile*)other)->getDamage()); }
void Oerkki1SAO::step(float dtime, bool send_recommended) { ScopeProfiler sp2(g_profiler, "Oerkki1SAO::step avg", SPT_AVG); assert(m_env); if(m_is_active == false) { if(m_inactive_interval.step(dtime, 0.5)==false) return; } /* The AI */ m_age += dtime; if(m_age > 120) { // Die m_removed = true; return; } m_after_jump_timer -= dtime; v3f old_speed = m_speed_f; // Apply gravity m_speed_f.Y -= dtime*9.81*BS; /* Move around if some player is close */ bool player_is_close = false; bool player_is_too_close = false; v3f near_player_pos; // Check connected players core::list<Player*> players = m_env->getPlayers(true); core::list<Player*>::Iterator i; for(i = players.begin(); i != players.end(); i++) { Player *player = *i; v3f playerpos = player->getPosition(); f32 dist = m_base_position.getDistanceFrom(playerpos); if(dist < BS*0.6) { m_removed = true; return; player_is_too_close = true; near_player_pos = playerpos; } else if(dist < BS*15.0 && !player_is_too_close) { player_is_close = true; near_player_pos = playerpos; } } m_is_active = player_is_close; v3f target_speed = m_speed_f; if(!player_is_close) { target_speed = v3f(0,0,0); } else { // Move around v3f ndir = near_player_pos - m_base_position; ndir.Y = 0; ndir.normalize(); f32 nyaw = 180./PI*atan2(ndir.Z,ndir.X); if(nyaw < m_yaw - 180) nyaw += 360; else if(nyaw > m_yaw + 180) nyaw -= 360; m_yaw = 0.95*m_yaw + 0.05*nyaw; m_yaw = wrapDegrees(m_yaw); f32 speed = 2*BS; if((m_touching_ground || m_after_jump_timer > 0.0) && !player_is_too_close) { v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI)); target_speed.X = speed * dir.X; target_speed.Z = speed * dir.Z; } if(m_touching_ground && (m_oldpos - m_base_position).getLength() < dtime*speed/2) { m_counter1 -= dtime; if(m_counter1 < 0.0) { m_counter1 += 0.2; // Jump target_speed.Y = 5.0*BS; m_after_jump_timer = 1.0; } } { m_counter2 -= dtime; if(m_counter2 < 0.0) { m_counter2 += (float)(myrand()%100)/100*3.0; //m_yaw += ((float)(myrand()%200)-100)/100*180; m_yaw += ((float)(myrand()%200)-100)/100*90; m_yaw = wrapDegrees(m_yaw); } } } if((m_speed_f - target_speed).getLength() > BS*4 || player_is_too_close) accelerate_xz(m_speed_f, target_speed, dtime*BS*8); else accelerate_xz(m_speed_f, target_speed, dtime*BS*4); m_oldpos = m_base_position; /* Move it, with collision detection */ core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*5./3.,BS/3.); collisionMoveResult moveresult; // Maximum movement without glitches f32 pos_max_d = BS*0.25; /*// Limit speed if(m_speed_f.getLength()*dtime > pos_max_d) m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);*/ v3f pos_f = getBasePosition(); v3f pos_f_old = pos_f; IGameDef *gamedef = m_env->getGameDef(); moveresult = collisionMovePrecise(&m_env->getMap(), gamedef, pos_max_d, box, dtime, pos_f, m_speed_f); m_touching_ground = moveresult.touching_ground; // Do collision damage float tolerance = BS*30; float factor = BS*0.5; v3f speed_diff = old_speed - m_speed_f; // Increase effect in X and Z speed_diff.X *= 2; speed_diff.Z *= 2; float vel = speed_diff.getLength(); if(vel > tolerance) { f32 damage_f = (vel - tolerance)/BS*factor; u16 damage = (u16)(damage_f+0.5); doDamage(damage); } setBasePosition(pos_f); if(send_recommended == false && m_speed_f.getLength() < 3.0*BS) return; if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS) { m_last_sent_position = pos_f; std::ostringstream os(std::ios::binary); // command (0 = update position) writeU8(os, 0); // pos writeV3F1000(os, m_base_position); // yaw writeF1000(os, m_yaw); // create message and add to list ActiveObjectMessage aom(getId(), false, os.str()); m_messages_out.push_back(aom); } }