void Monster::onThink(uint32_t interval)
{
	Creature::onThink(interval);

	if(despawn()){
		g_game.removeCreature(this, true);
		setIdle(true);
	}
	else{
		updateIdleStatus();
		if(!isIdle && !semiIdle){
			addEventWalk();

			if(isSummon()){
				if(!attackedCreature){
					if(getMaster() && getMaster()->getAttackedCreature()){
						///This happens if the monster is summoned during combat
						selectTarget(getMaster()->getAttackedCreature());
					}
					else if(getMaster() != followCreature){
						//Our master has not ordered us to attack anything, lets follow him around instead.
						setFollowCreature(getMaster());
					}
				}
				else if(attackedCreature == this){
					setFollowCreature(NULL);
				}
				else if(followCreature != attackedCreature){
					//This happens just after a master orders an attack, so lets follow it aswell.
					setFollowCreature(attackedCreature);
				}
			}
			else if(!targetList.empty()){
				if(!followCreature || !hasFollowPath){
					searchTarget();
				}
				else if(isFleeing()){
					if(attackedCreature && !canUseAttack(getPosition(), attackedCreature)){
						searchTarget(TARGETSEARCH_ATTACKRANGE);
					}
				}
			}

			onThinkTarget(interval);
			onThinkYell(interval);
			onThinkDefense(interval);
		}
	}
}
Пример #2
0
void DefendBehavior::doMove()
{
    vector<otank_t> otherTanks;
    connection->get_othertanks(&otherTanks);
    
    

    vector<tank_t> myTanks;
    connection->get_mytanks(&myTanks);
    tank_t me = myTanks[tankNumber];
    // Check if the currentTarget needs to be changed

    selectTarget(&otherTanks, me);
    
    if(currentTarget == NULL)
    {
        return;
    }
    
    // Aim and fire
    
    Point targetLocation = currentTarget->getCurrentPoint();
    double distanceToEnemy = SearchTools::distance(me.pos[0], me.pos[1], targetLocation.x, targetLocation.y);
    double timeForShotToHit = distanceToEnemy / SHOTSPEED;
    Point futureLocation = currentTarget->getTargetPoint(timeForShotToHit);
    double targetAngle = atan2((futureLocation.y - me.pos[1]) , (futureLocation.x - me.pos[0]));
    double angularVelocity = pdController.calculateAngularVelocity(me.angle, targetAngle);
    
    connection->speed(tankNumber, 0);
    connection->angvel(tankNumber, angularVelocity * 4);// / abs(angularVelocity));
    
    bool safeToFire = true;
    for(int i = 0; i < myTanks.size();i++) 
    {
        if (i == tankNumber)
            continue;

        double friendAngle = atan2((myTanks[i].pos[1] - me.pos[1]), (myTanks[i].pos[0] - me.pos[0]));
        if (abs(differenceBetweenTwoAngles(me.angle, friendAngle)) < .01 &&
            SearchTools::distance(myTanks[i].pos[0], myTanks[i].pos[1], me.pos[0], me.pos[1]) < 400) 
        {
            safeToFire = false;
        }
    }
    if(abs(differenceBetweenTwoAngles(me.angle, targetAngle)) < .01 && safeToFire)
    {
        connection->shoot(tankNumber);
    }
}
Пример #3
0
bool Monster::challengeCreature(Creature* creature)
{
	if(isSummon())
		return false;
	else
	{
		bool result = selectTarget(creature);
		if(result)
		{
			targetChangeCooldown = 8000;
			targetChangeTicks = 0;
		}

		return result;
	}
	return false;
}
Пример #4
0
bool Actor::challengeCreature(Creature* creature)
{
  if(isPlayerSummon()){
    return false;
  }
  else{
    bool result = selectTarget(creature);
    if(result){
      targetChangeCooldown = 8000;
      targetChangeTicks = 0;
    }

    return result;
  }

  return false;
}
Пример #5
0
void UnitFiring::autoFire() {
	mTargetAquired = selectTarget();
	if (!mTargetAquired) mAimReset = true;

	if (mTargetAquired) {
		mTargetPosition = predictTargetPosition( const_cast<Unit*>(mTargetUnit));
		aim();
		if (isAimed()) {
			fire();
		}
	} else if (mAimReset) {
		resetAim();
	} else {
		freezeAim();
	}

	theApp->displayUnitReload(this, getRemainingReloadTime());
}
Пример #6
0
void Piece::markPosition(int diagId, int diagonal, map<int,int>* values, 
		vector<Object*> board){
	if (diagId < 0 || diagId >= BOARD_SIZE) return;

	if (board[diagId] != NULL) {

		if (diagId % (int)sqrt(BOARD_SIZE) == 0 ||
				diagId % (int)sqrt(BOARD_SIZE) == (int)sqrt(BOARD_SIZE) - 1)
			return;
		
		if (diagId / (int)sqrt(BOARD_SIZE) == 0 ||
				diagId / (int)sqrt(BOARD_SIZE) == (int)sqrt(BOARD_SIZE) - 1)
			return;
		selectTarget(diagId,diagonal,values,board);
	}
	else
		values->insert(pair<int,int>(diagId,-1));
}
Пример #7
0
void ComponentAIBomber::deleteObject(GameObject* targetObject)
{

	if(targetObject->getTag() == GameObject::MAIN_PLAYER)
	{
		std::list<GameObject*>::iterator it;
		if(!players.empty())
		{
			for (it=players.begin(); it!=players.end(); ++it)
			{	
				if( *it == targetObject)
				{
					players.erase(it);

					break;
				}
			}
		}
	}
	else
	{
		std::list<GameObject*>::iterator it;
		for (it=onVisionList.begin(); it!=onVisionList.end(); ++it)
		{	
			if( *it == targetObject)
			{
				//Es el primero
				if(*it == onVisionList.front() && shooting)
				{
					messageStopAIM();
					shooting = false;
				}
				onVisionList.erase(it);
				target = NULL;
				watching = false;
				selectTarget();
			
				break;
			}
		}
	}
}
Пример #8
0
bool GameScreen::select(sf::Vector2i s)
{
	if(m_selectedPiece != NULL_SQUARE) //if a piece is selected
	{
		if(m_selectedTarget != NULL_SQUARE) //if an enemy piece is selected
		{
			if(!m_highlighter.isHighlighted(s)) //square isn't selectable
				unselect();
			else //square is selectable
			{
				bool res = m_game.displace(toSquare(m_selectedPiece), toSquare(s), toSquare(m_selectedTarget), false);
				unselect();
				return res;
			}
		}
		else //no enemy piece selected
		{
			if(!m_highlighter.isHighlighted(s)) //square isn't selectable
				unselect();
			else //square is selectable
			{
				PiecePtr p = m_game[toSquare(s)];
				if (p == nullptr) //no piece here
				{
					bool res = m_game.move(toSquare(m_selectedPiece), toSquare(s), false);
					unselect();
					return res;
				}
				else
					selectTarget(s);
			}
		}
	}
	else //no piece is selected
	{
		PiecePtr p = m_game[toSquare(s)];
		if (p != nullptr && p->getColor() == m_game.getActivePlayer())  //there is a piece and it can be selected
			selectPiece(s);
	}
	return false;
}
Пример #9
0
void ComponentAIBomber::addObject(GameObject* gameObject)
{


	if(gameObject->getTag() != GameObject::MAIN_PLAYER)
	{
		onVisionList.push_back(gameObject);
		if(onVisionList.size() > 1)
		{
			onVisionList.sort(GameObject::selectPrefEnemy);
		}

		if(onVisionList.front() == gameObject)
		{
			selectTarget();
		}
	}
	else
	{
		players.push_back(gameObject);
	}
}
Пример #10
0
void Monster::onCreatureMove(const Creature* creature, const Tile* newTile, const Position& newPos,
	const Tile* oldTile, const Position& oldPos, bool teleport)
{
	Creature::onCreatureMove(creature, newTile, newPos, oldTile, oldPos, teleport);

	if(creature == this)
	{
		if(isSummon())
			isMasterInRange = canSee(getMaster()->getPosition());

		updateTargetList();
		updateIdleStatus();
	}
	else
	{
		bool canSeeNewPos = canSee(newPos);
		bool canSeeOldPos = canSee(oldPos);

		if(canSeeNewPos && !canSeeOldPos)
			onCreatureEnter(const_cast<Creature*>(creature));
		else if(!canSeeNewPos && canSeeOldPos)
			onCreatureLeave(const_cast<Creature*>(creature));

		if(canSeeNewPos && isSummon() && getMaster() == creature)
			isMasterInRange = true;	//Turn the summon on again

		updateIdleStatus();

		if(!followCreature && !isSummon())
		{
			//we have no target lets try pick this one
			if(isOpponent(creature))
				selectTarget(const_cast<Creature*>(creature));
		}
	}
}
Пример #11
0
TextureOgl::TextureOgl( const Description &description ) :
    _description( description ),
    _texelDescription( selectTexelDescription(description.format) ),
    _target( selectTarget(description.layout) )
{
    validateDescription();

    ScopeTextureBinding scopeTextureBinding( _target, _texture );

    const unsigned int levelsMaximum = getMipLevelsMaximum( _description );
    const unsigned int levels = _description.mipLevels == CompleteMipMap ?
        levelsMaximum : _description.mipLevels;
    storm_assert( levels <= levelsMaximum );

    if( _description.mipLevels == CompleteMipMap )
        _description.mipLevels = levels;

    switch( _description.layout ) {
    case Layout::Separate1d:
        ::glTexStorage1D(
            _target, levels, _texelDescription.internalFormat,
            description.width );
        checkResult( "::glTexStorage1D" );
        break;
    case Layout::Separate2d:
    case Layout::CubeMap:
        ::glTexStorage2D(
            _target, levels, _texelDescription.internalFormat,
            description.width,
            description.height );
        checkResult( "::glTexStorage2D" );
        break;
    case Layout::Separate3d:
        ::glTexStorage3D(
            _target, levels, _texelDescription.internalFormat,
            description.width,
            description.height,
            description.depth );
        checkResult( "::glTexStorage3D" );
        break;
    case Layout::Layered1d:
        ::glTexStorage2D(
            _target, levels, _texelDescription.internalFormat,
            description.width,
            description.layers );
        checkResult( "::glTexStorage2D" );
        break;
    case Layout::Layered2d:
        ::glTexStorage3D(
            _target, levels, _texelDescription.internalFormat,
            description.width,
            description.height,
            description.layers );
        checkResult( "::glTexStorage3D" );
        break;
    case Layout::Separate2dMsaa:
        ::glTexStorage2DMultisample(
            _target, description.texelSamples,
            _texelDescription.internalFormat,
            description.width,
            description.height,
            GL_TRUE );
        checkResult( "::glTexStorage2DMultisample" );
        break;
    case Layout::Layered2dMsaa:
        ::glTexStorage3DMultisample(
            _target, description.texelSamples,
            _texelDescription.internalFormat,
            description.width,
            description.height,
            description.layers,
            GL_TRUE );
        checkResult( "::glTexStorage3DMultisample" );
        break;
    default:
        throwNotImplemented();
    }
}
Пример #12
0
void doPlayer(void)
{
	self = player;
	
	rechargeBoostECM();
	
	if (game.currentMission->challengeData.isChallenge)
	{
		applyRestrictions();
	}
	
	if (player->alive == ALIVE_ALIVE && player->systemPower > 0)
	{
		handleKeyboard();

		handleMouse();
		
		handleSuspicionLevel();

		if (!player->target || player->target->health <= 0 || player->target->systemPower <= 0 || targetOutOfRange())
		{
			selectTarget();
		}
	}

	player->angle = ((int)player->angle) % 360;

	if (player->health <= 0 && battle.status == MS_IN_PROGRESS)
	{
		if (game.currentMission->challengeData.isChallenge)
		{
			if (!game.currentMission->challengeData.allowPlayerDeath)
			{
				updateDeathStats();
				
				failMission();
			}
		}
		else if (!battle.isEpic)
		{
			updateDeathStats();
			
			failMission();
		}
		else if (player->health == -FPS)
		{
			updateDeathStats();
			
			updateCondition("PLAYER", TT_DESTROY);
			
			if (battle.status == MS_IN_PROGRESS)
			{
				initPlayerSelect();
			}
		}
	}

	if (battle.status == MS_IN_PROGRESS)
	{
		selectMissionTarget();
	}

	if (dev.playerUnlimitedMissiles)
	{
		player->missiles = 999;
	}
	
	/* really only used in challenge mode */
	if (player->systemPower <= 0 && battle.status == MS_IN_PROGRESS)
	{
		if (game.currentMission->challengeData.isChallenge)
		{
			addHudMessage(colors.red, _("Challenge Failed!"));
			failMission();
		}
	}

	if (battle.boostTimer == (int)BOOST_FINISHED_TIME)
	{
		deactivateBoost();
	}
}
Пример #13
0
static void handleKeyboard(void)
{
	if (battle.status == MS_IN_PROGRESS)
	{
		if (isControl(CONTROL_BOOST) && player->speed > 0)
		{
			if (battle.boostTimer == BOOST_RECHARGE_TIME)
			{
				playSound(SND_BOOST);

				activateBoost();
			}
			else
			{
				playSound(SND_GUI_DENIED);
			}

			clearControl(CONTROL_BOOST);
		}

		if (isControl(CONTROL_TARGET))
		{
			selectTarget();

			clearControl(CONTROL_TARGET);
		}

		if (isControl(CONTROL_ECM))
		{
			if (battle.ecmTimer == ECM_RECHARGE_TIME)
			{
				playSound(SND_ECM);

				activateECM();
			}
			else
			{
				playSound(SND_GUI_DENIED);
			}

			clearControl(CONTROL_ECM);
		}

		if (isControl(CONTROL_BRAKE))
		{
			applyFighterBrakes();
		}

		if (isControl(CONTROL_GUNS))
		{
			switchGuns();

			clearControl(CONTROL_GUNS);
		}

		if (isControl(CONTROL_RADAR))
		{
			cycleRadarZoom();

			clearControl(CONTROL_RADAR);
		}

		if (isControl(CONTROL_MISSILE))
		{
			preFireMissile();

			clearControl(CONTROL_MISSILE);
		}
	}
	else
	{
		applyFighterBrakes();
	}
}
Пример #14
0
bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAULT*/)
{
#ifdef __DEBUG__
	std::clog << "Searching target... " << std::endl;
#endif

	std::list<Creature*> resultList;
	const Position& myPos = getPosition();
	for(CreatureList::iterator it = targetList.begin(); it != targetList.end(); ++it)
	{
		if(followCreature != (*it) && isTarget(*it) && (searchType == TARGETSEARCH_RANDOM
			|| canUseAttack(myPos, *it)))
			resultList.push_back(*it);
	}

	switch(searchType)
	{
		case TARGETSEARCH_NEAREST:
		{
			Creature* target = NULL;
			int32_t range = -1;
			for(CreatureList::iterator it = resultList.begin(); it != resultList.end(); ++it)
			{
				int32_t tmp = std::max(std::abs(myPos.x - (*it)->getPosition().x),
					std::abs(myPos.y - (*it)->getPosition().y));
				if(range >= 0 && tmp >= range)
					continue;

				target = *it;
				range = tmp;
			}

			if(target && selectTarget(target))
				return target;

			break;
		}
		default:
		{
			if(!resultList.empty())
			{
				CreatureList::iterator it = resultList.begin();
				std::advance(it, random_range(0, resultList.size() - 1));
#ifdef __DEBUG__

				std::clog << "Selecting target " << (*it)->getName() << std::endl;
#endif
				return selectTarget(*it);
			}

			if(searchType == TARGETSEARCH_ATTACKRANGE)
				return false;

			break;
		}
	}


	//lets just pick the first target in the list
	for(CreatureList::iterator it = targetList.begin(); it != targetList.end(); ++it)
	{
		if(followCreature == (*it) || !selectTarget(*it))
			continue;

#ifdef __DEBUG__
		std::clog << "Selecting target " << (*it)->getName() << std::endl;
#endif
		return true;
	}

	return false;
}
Пример #15
0
void Monster::onCreatureMove(Creature* creature, const Tile* newTile, const Position& newPos,
                             const Tile* oldTile, const Position& oldPos, bool teleport)
{
	Creature::onCreatureMove(creature, newTile, newPos, oldTile, oldPos, teleport);

	if (mType->info.creatureMoveEvent != -1) {
		// onCreatureMove(self, creature, oldPosition, newPosition)
		LuaScriptInterface* scriptInterface = mType->info.scriptInterface;
		if (!scriptInterface->reserveScriptEnv()) {
			std::cout << "[Error - Monster::onCreatureMove] Call stack overflow" << std::endl;
			return;
		}

		ScriptEnvironment* env = scriptInterface->getScriptEnv();
		env->setScriptId(mType->info.creatureMoveEvent, scriptInterface);

		lua_State* L = scriptInterface->getLuaState();
		scriptInterface->pushFunction(mType->info.creatureMoveEvent);

		LuaScriptInterface::pushUserdata<Monster>(L, this);
		LuaScriptInterface::setMetatable(L, -1, "Monster");

		LuaScriptInterface::pushUserdata<Creature>(L, creature);
		LuaScriptInterface::setCreatureMetatable(L, -1, creature);

		LuaScriptInterface::pushPosition(L, oldPos);
		LuaScriptInterface::pushPosition(L, newPos);

		if (scriptInterface->callFunction(4)) {
			return;
		}
	}

	if (creature == this) {
		if (isSummon()) {
			isMasterInRange = canSee(getMaster()->getPosition());
		}

		updateTargetList();
		updateIdleStatus();
	} else {
		bool canSeeNewPos = canSee(newPos);
		bool canSeeOldPos = canSee(oldPos);

		if (canSeeNewPos && !canSeeOldPos) {
			onCreatureEnter(creature);
		} else if (!canSeeNewPos && canSeeOldPos) {
			onCreatureLeave(creature);
		}

		if (canSeeNewPos && isSummon() && getMaster() == creature) {
			isMasterInRange = true;    //Follow master again
		}

		updateIdleStatus();

		if (!isSummon()) {
			if (followCreature) {
				const Position& followPosition = followCreature->getPosition();
				const Position& position = getPosition();

				int32_t offset_x = Position::getDistanceX(followPosition, position);
				int32_t offset_y = Position::getDistanceY(followPosition, position);
				if ((offset_x > 1 || offset_y > 1) && mType->info.changeTargetChance > 0) {
					Direction dir = getDirectionTo(position, followPosition);
					const Position& checkPosition = getNextPosition(dir, position);

					Tile* tile = g_game.map.getTile(checkPosition);
					if (tile) {
						Creature* topCreature = tile->getTopCreature();
						if (topCreature && followCreature != topCreature && isOpponent(topCreature)) {
							selectTarget(topCreature);
						}
					}
				}
			} else if (isOpponent(creature)) {
				//we have no target lets try pick this one
				selectTarget(creature);
			}
		}
	}
}
Пример #16
0
void Robot::planAction(void) {
	ownTime_ms_delta_t hurryUp = 1000*60*11; // If it's time to abandon everything else and get current targets to the goal 
	static ownTime_ms_delta_t explRollStartTime = 0;
	static ownTime_ms_delta_t hidasprkl = 0;
	if (!manual.enabled) {
		if(statistics.taskStartTime == 0)
			statistics.taskStartTime = ownTime_get_ms();
		SLAM::RobotLocation p = slam.getCurrentMapData().getRobotLocation();
		std::cout << "PLANNER: ROBOT LOCATION " << p.x << " " << p.y << " " << p.theta << std::endl;
		switch (taskState) {
			case START: // roll around to discover empty areas
				if (!motionControl.rollStart(p))
					taskState = EXPLORE;
				break;
			case EXPLORE: // seek unexplored areas until targets visible
				if (ownTime_get_ms_since(hidasprkl) >= 5000) {
					hidasprkl = ownTime_get_ms();
					updateTargets();
				}
				if (targets.size()) {
					if (motionControl.running())
						motionControl.stop();
					taskState = GO_TO_TARGET;
					selectTarget();
					navigateTarget();
				} else {
					if (!motionControl.iterate(p) && explRollStartTime == 0) {
						explRollStartTime = ownTime_get_ms();
						motionControl.setCtrl(0, 1.0 / 10 * M_PI);
					} else if (explRollStartTime != 0 && ownTime_get_ms_since(explRollStartTime) > 3000) {
						motionControl.setCtrl(0, 0);
						SLAM::Location to(navigation.farthest());
						explRollStartTime = 0;
						std::cout << "PLANNER: explore to farthest " << to.x << " " << to.y << std::endl;
						navigation.solveTo(to);
						navigate();
						//explore();
					}
				}
				break;
			case GO_TO_TARGET: // Move near the nearest target to open the hatch
				if (motionControl.routeLeft() < HATCH_OPEN_DISTANCE) {
					if (approachStarted < 1) {
						approachStarted = ownTime_get_ms();
						break;
					}
					camera.rotateNear();
					if(ownTime_get_ms_since(approachStarted) < 1000) {
						if (motionControl.running()) {
							motionControl.stop();
						}
						break;
					}
					servoControl.setHatch(false);
					navigateTarget();
					approachStarted = 0;
					taskState = APPROACH_PICK_UP;
				}
				motionControl.iterate(p);
				break;
			case APPROACH_PICK_UP: // Move on close to target
				if (!motionControl.iterate(p)) {
					float clear = navigation.wallClearance(p);
					float walk = clear < PICKUPWALK ? clear : PICKUPWALK;
					navigation.solveTo(SLAM::Location(p.x + cos(p.theta) * walk, p.y + sin(p.theta) * walk));
					navigate();
					taskState = PICK_UP;
				}
				break;
			case GO_RETURN_TO_GOAL: // Try to find a route to the goal -- if cannot, explore more
				ownSleep_ms(1000);
				updateTargets();
				if (navigation.solveTo(SLAM::Location(0, 0))) {
					navigate();
					taskState = RETURN_TO_GOAL;
				} else {
					taskState = EXPLORE;
				}
				break;
			case RETURN_TO_GOAL: // Going to goal
				if (!motionControl.iterate(p)) {
					float clear = navigation.wallClearance(p);
					float walk = clear < GOALWALK ? clear : GOALWALK;
					navigation.solveTo(SLAM::Location(p.x + cos(p.theta) * walk, p.y + sin(p.theta) * walk));
					navigate();
					camera.rotateFar();
					taskState = GOAL_WALKHAX;
				}
				break;
			case GOAL_WALKHAX: // in goal, drive a bit forwards to be able to drop targets correctly
				if (!motionControl.iterate(p)) {
					taskState = RELEASE_TARGETS;
					servoControl.setHatch(false);
				}
				break;
			case PICK_UP: // when target is near, drive a bit forwards to be sure
				if (!motionControl.iterate(p)) {
					servoControl.setHatch(true);
					camera.rotateFar();
					numberOfPickUps++;
					speak("Pallo " + lexical_cast(numberOfPickUps));
					if(numberOfPickUps >= 10) {
						taskState = GO_RETURN_TO_GOAL;
					} else {
						if (targets.empty()) {
							taskState = EXPLORE;
						} else {
							selectTarget();
							navigateTarget();
							taskState = GO_TO_TARGET;
						}
						taskState = EXPLORE;
					}
				}
				break;
			case RELEASE_TARGETS: // eggs hatching, get back
				servoControl.setHatch(false);
				if (!motionControl.backFromGoal(p)) {
					taskState = RETURN_TO_GOAL_AGAIN;
					navigation.solveTo(SLAM::Location(0, 0));
					navigate();
				}
				break;
			case RETURN_TO_GOAL_AGAIN: // Going to goal another time to get last balls rolling
				if (!motionControl.iterate(p)) {
					float clear = navigation.wallClearance(p);
					float walk = clear < GOALWALK_AGAIN ? clear : GOALWALK_AGAIN;
					navigation.solveTo(SLAM::Location(p.x + cos(p.theta) * walk, p.y + sin(p.theta) * walk));
					navigate();
					camera.rotateFar();
					taskState = GOAL_WALKHAX_AGAIN;
				}
				break;
			case GOAL_WALKHAX_AGAIN: // in goal, drive a bit forwards to be able to drop targets correctly
				if (!motionControl.iterate(p)) {
					taskState = RELEASE_TARGETS_AGAIN;
				}
				break;
			case RELEASE_TARGETS_AGAIN: // they see me rollin', they hatin'
				if (!motionControl.backFromGoal(p)) {
					taskState = END_STATE;
				}
				break;
			case END_STATE: // world domination succeeded
				camera.rotateNear();
				speak("Hurraa");
				manual.enabled = true;
				break;
			case BACK_OFF: // bumpers hit. exit to exploring when bumpers not hitting anymore
				std::cout << "PLANNER: DYNDYNDYY" << std::endl;
				motionControl.backOff();
				break;
			default: throw std::runtime_error("Bad task state number"); break;
		}
		float timeSince = ownTime_get_ms_since(statistics.taskStartTime);
		if (timeSince >= hurryUp && (
				taskState == START
				|| taskState == EXPLORE
				|| taskState == GO_TO_TARGET
				|| taskState == APPROACH_PICK_UP
				|| taskState == PICK_UP
		   )) {
			taskState = GO_RETURN_TO_GOAL;
			speak("Hop hop hop");
		}
		std::cout << "PLANNER: CURRENT TASK: " << taskdescr[taskState] << ", time elapsed " << (timeSince / 1000) << std::endl;
	}
}
Пример #17
0
bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAULT*/)
{
#ifdef __DEBUG__
	std::cout << "Searching target... " << std::endl;
#endif

	std::list<Creature*> resultList;
	const Position& myPos = getPosition();
	for(CreatureList::iterator it = targetList.begin(); it != targetList.end(); ++it)
	{
		if(followCreature != (*it) && isTarget(*it))
		{
			if(searchType == TARGETSEARCH_RANDOM || canUseAttack(myPos, *it))
				resultList.push_back(*it);
		}
	}

	switch(searchType)
	{
		case TARGETSEARCH_NEAREAST:
		{
			Creature* target = NULL;
			int32_t minRange = -1;
			for(std::list<Creature*>::iterator it = resultList.begin(); it != resultList.end(); ++it)
			{
				const Position& pos = (*it)->getPosition();
				if(minRange == -1 || std::max(std::abs(myPos.x - pos.x), std::abs(myPos.y - pos.y)) < minRange)
				{
					target = *it;
					minRange = std::max(std::abs(myPos.x - pos.x), std::abs(myPos.y - pos.y));
				}
			}

			if(target && selectTarget(target))
				return true;

			break;
		}

		case TARGETSEARCH_DEFAULT:
		case TARGETSEARCH_ATTACKRANGE:
		case TARGETSEARCH_RANDOM:
		default:
		{
			if(!resultList.empty())
			{
				uint32_t index = random_range(0, resultList.size() - 1);
				CreatureList::iterator it = resultList.begin();
				std::advance(it, index);
#ifdef __DEBUG__
				std::cout << "Selecting target " << (*it)->getName() << std::endl;
#endif
				return selectTarget(*it);
			}

			if(searchType == TARGETSEARCH_ATTACKRANGE)
				return false;

			break;
		}
	}

	//lets just pick the first target in the list
	for(CreatureList::iterator it = targetList.begin(); it != targetList.end(); ++it)
	{
		if(followCreature != (*it) && selectTarget(*it))
		{
#ifdef __DEBUG__
			std::cout << "Selecting target " << (*it)->getName() << std::endl;
#endif
			return true;
		}
	}
	return false;
}
Пример #18
0
bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAULT*/)
{
	std::list<Creature*> resultList;
	const Position& myPos = getPosition();

	for (Creature* creature : targetList) {
		if (followCreature != creature && isTarget(creature)) {
			if (searchType == TARGETSEARCH_RANDOM || canUseAttack(myPos, creature)) {
				resultList.push_back(creature);
			}
		}
	}

	switch (searchType) {
		case TARGETSEARCH_NEAREST: {
			Creature* target = nullptr;
			if (!resultList.empty()) {
				auto it = resultList.begin();
				target = *it;

				if (++it != resultList.end()) {
					const Position& targetPosition = target->getPosition();
					int32_t minRange = Position::getDistanceX(myPos, targetPosition) + Position::getDistanceY(myPos, targetPosition);
					do {
						const Position& pos = (*it)->getPosition();

						int32_t distance = Position::getDistanceX(myPos, pos) + Position::getDistanceY(myPos, pos);
						if (distance < minRange) {
							target = *it;
							minRange = distance;
						}
					} while (++it != resultList.end());
				}
			} else {
				int32_t minRange = std::numeric_limits<int32_t>::max();
				for (Creature* creature : targetList) {
					if (!isTarget(creature)) {
						continue;
					}

					const Position& pos = creature->getPosition();
					int32_t distance = Position::getDistanceX(myPos, pos) + Position::getDistanceY(myPos, pos);
					if (distance < minRange) {
						target = creature;
						minRange = distance;
					}
				}
			}

			if (target && selectTarget(target)) {
				return true;
			}
			break;
		}

		case TARGETSEARCH_DEFAULT:
		case TARGETSEARCH_ATTACKRANGE:
		case TARGETSEARCH_RANDOM:
		default: {
			if (!resultList.empty()) {
				auto it = resultList.begin();
				std::advance(it, uniform_random(0, resultList.size() - 1));
				return selectTarget(*it);
			}

			if (searchType == TARGETSEARCH_ATTACKRANGE) {
				return false;
			}

			break;
		}
	}

	//lets just pick the first target in the list
	for (Creature* target : targetList) {
		if (followCreature != target && selectTarget(target)) {
			return true;
		}
	}
	return false;
}
Пример #19
0
void Monster::onThink(uint32_t interval)
{
	Creature::onThink(interval);

	if (mType->info.thinkEvent != -1) {
		// onThink(self, interval)
		LuaScriptInterface* scriptInterface = mType->info.scriptInterface;
		if (!scriptInterface->reserveScriptEnv()) {
			std::cout << "[Error - Monster::onThink] Call stack overflow" << std::endl;
			return;
		}

		ScriptEnvironment* env = scriptInterface->getScriptEnv();
		env->setScriptId(mType->info.thinkEvent, scriptInterface);

		lua_State* L = scriptInterface->getLuaState();
		scriptInterface->pushFunction(mType->info.thinkEvent);

		LuaScriptInterface::pushUserdata<Monster>(L, this);
		LuaScriptInterface::setMetatable(L, -1, "Monster");

		lua_pushnumber(L, interval);

		if (scriptInterface->callFunction(2)) {
			return;
		}
	}

	if (!isInSpawnRange(position)) {
		g_game.internalTeleport(this, masterPos);
		setIdle(true);
	} else {
		updateIdleStatus();

		if (!isIdle) {
			addEventWalk();

			if (isSummon()) {
				if (!attackedCreature) {
					if (getMaster() && getMaster()->getAttackedCreature()) {
						//This happens if the monster is summoned during combat
						selectTarget(getMaster()->getAttackedCreature());
					} else if (getMaster() != followCreature) {
						//Our master has not ordered us to attack anything, lets follow him around instead.
						setFollowCreature(getMaster());
					}
				} else if (attackedCreature == this) {
					setFollowCreature(nullptr);
				} else if (followCreature != attackedCreature) {
					//This happens just after a master orders an attack, so lets follow it aswell.
					setFollowCreature(attackedCreature);
				}
			} else if (!targetList.empty()) {
				if (!followCreature || !hasFollowPath) {
					searchTarget();
				} else if (isFleeing()) {
					if (attackedCreature && !canUseAttack(getPosition(), attackedCreature)) {
						searchTarget(TARGETSEARCH_ATTACKRANGE);
					}
				}
			}

			onThinkTarget(interval);
			onThinkYell(interval);
			onThinkDefense(interval);
		}
	}
}
Пример #20
0
void Monster::doAttacking(uint32_t interval)
{
	if(!attackedCreature || (isSummon() && attackedCreature == this))
		return; // aqui

    const Position& myPos = getPosition();
    const Position& targetPos = attackedCreature->getPosition();
	
    FindPathParams fpp;
    
    	fpp.fullPathSearch = true;
    	fpp.maxSearchDist = -1;
    	fpp.minTargetDist = 0;
    	fpp.maxTargetDist = 1;
    	
	    std::string valueString;
    	std::list<Direction> dirList;
    	if(attackedCreature->getPlayer()){
           if(Creature* summon = attackedCreature->pushBackSummonOne())
                  selectTarget(summon);
        }
    	
    /*	
    	if(!g_game.getPathToEx(this, targetPos, dirList, fpp) && attackedCreature->isSummon()){
            selectTarget(attackedCreature->getMaster());
            
            std::string strValue; int32_t value;
				if(getStorage(8085, strValue))
				{
				   value = atoi(strValue.c_str());
				}
				if(value == 0) 
				  g_game.addAnimatedText(getPosition(), 215, "GRRR!");
				  
            setStorage(8085, "2");
        }
            
        if(attackedCreature->getPlayer()){
           if(Creature* summon = attackedCreature->pushBackSummonOne()){
               if(g_game.getPathToEx(this, summon->getPosition(), dirList, fpp)){
                  selectTarget(summon);
                  std::string strValue, playerStor; int32_t value, value2;
    				if(getStorage(8085, strValue))
    				{
    				   value = atoi(strValue.c_str());
    				}
        				if(value == 2) 
        				   g_game.addAnimatedText(getPosition(), 215, "Hmpf");
        				   
        				  
                  setStorage(8085, "0");
               }
           }else
                  setStorage(8085, "1");
        } 
        */

	bool updateLook = true, outOfRange = true;
	resetTicks = interval;
	attackTicks += interval;

	
	for(SpellList::iterator it = mType->spellAttackList.begin(); it != mType->spellAttackList.end(); ++it)
	{
		if(it->isMelee && isFleeing())
			continue;

		bool inRange = false;
		if(canUseSpell(myPos, targetPos, *it, interval, inRange))
		{
			if(it->chance >= (uint32_t)random_range(1, 100))
			{
				if(updateLook)
				{
					updateLookDirection();
					updateLook = false;
				}

				double multiplier;
				if(maxCombatValue > 0) //defense
					multiplier = g_config.getDouble(ConfigManager::RATE_MONSTER_DEFENSE);
				else //attack
					multiplier = g_config.getDouble(ConfigManager::RATE_MONSTER_ATTACK);

				minCombatValue = (int32_t)(it->minCombatValue * multiplier);
				maxCombatValue = (int32_t)(it->maxCombatValue * multiplier);

				it->spell->castSpell(this, attackedCreature);
				if(it->isMelee)
					extraMeleeAttack = false;
#ifdef __DEBUG__
				static uint64_t prevTicks = OTSYS_TIME();
				std::cout << "doAttacking ticks: " << OTSYS_TIME() - prevTicks << std::endl;
				prevTicks = OTSYS_TIME();
#endif
			}
		}

		if(inRange)
			outOfRange = false;
		else if(it->isMelee) //melee swing out of reach
			extraMeleeAttack = true;
	}

	if(updateLook)
		updateLookDirection();

	if(resetTicks)
		attackTicks = 0;
}