Esempio n. 1
0
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();
	}
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
void fireCollisionCb(Body* self, Body* other, Contact* contact, ContactResponse* response)
{
	response->mBounceThem = true;
	response->mBounceMe = true;

	doDamage(self, other, Fire, 10.0f);
}
Esempio n. 4
0
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);
    }
}
Esempio n. 5
0
void BunkerBlock::onCollision(const Entity* entity)
{
	//auto bullet = static_cast<const Bullet*>(entity);

	Message::BulletHitMessage msg(entity->getId(), this->getId());

	notifyCollision(msg);

	doDamage(1);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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);
					}
				}
			}
		}
	}
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
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);
	}
}
Esempio n. 15
0
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);
}
Esempio n. 16
0
    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);
	}
Esempio n. 17
0
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();

}
Esempio n. 18
0
void LamakiWarrior::fire()
{
	doDamage(Target);
}
Esempio n. 19
0
//Collide with another object
void Spaceship::collide(SceneNode * other)
{
    if(dynamic_cast<Projectile*>(other) && ((Entity*)other)->getTeam() != getTeam())
        doDamage(((Projectile*)other)->getDamage());
}
Esempio n. 20
0
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);
	}
}