Exemplo n.º 1
0
void WifiStateMachine::triggerState(int state)
{
  char buf[20];
  char command[64];
  snprintf(buf, sizeof(buf), "Entering state %d", state);
  Serial.println(buf);

  switch (state) {
    case WIFI_OFF:
      digitalWrite(resetPin, LOW);
      waitState(WIFI_RST_HIGH, 15 * MILLIS_PER_MINUTE);
      break;
    case WIFI_RST_HIGH:
      digitalWrite(resetPin, HIGH);
      waitState(WIFI_CIPSTART, 10 * MILLIS_PER_SECOND);
      break;
    case WIFI_CIPSTART:
      snprintf(command, sizeof(command), "AT+CIPSTART=\"UDP\",\"%s\",%d,%d,0", server, port, port);
      swSerial->println(command);
      waitState(WIFI_CIPSEND, 100);
      break;
    case WIFI_CIPSEND:
      payload = payloadCB();
      snprintf(command, sizeof(command), "AT+CIPSEND=%d", strlen(payload) + 1);
      swSerial->println(command);
      waitState(WIFI_SEND_PAYLOAD, 100);
      break;
    case WIFI_SEND_PAYLOAD:
      swSerial->println(payload);
      waitState(WIFI_OFF, 10 * MILLIS_PER_SECOND);
      break;
  }
}
Exemplo n.º 2
0
void Timer::triggerState(int state) {
  switch (state) {
    case TIMER_STATE_IDLE:
      waitState(TIMER_STATE_FIRE, interval);
      break;
    case TIMER_STATE_FIRE:
      fire();
      waitState(TIMER_STATE_IDLE, 0);
      break;
  }
}
Exemplo n.º 3
0
bool PathSitTask::Perform( Subsystem &subsystem ) {
	DM_LOG( LC_AI, LT_INFO )LOGSTRING( "PathSitTask performing.\r" );
	idAI *owner = _owner.GetEntity();
	// This task may not be performed with an empty owner pointer
	assert( owner != NULL );
	// grayman #3670 - wait for the sitting down (and possibly turning
	// after) to finish, in case there's a target that needs to be activated
	idStr waitState( owner->WaitState() ); // grayman #3670
	if( !_sittingAnimDone && ( ( waitState == "sit_down" ) || ( owner->AI_SIT_DOWN_ANGLE != owner->GetCurrentYaw() ) ) ) {
		return false;
	}
	if( !_sittingAnimDone ) {
		_sittingAnimDone = true;
		idPathCorner *path = _path.GetEntity(); // grayman #3670
		// This task may not be performed with an empty path pointer
		assert( path != NULL );
		path->ActivateTargets( owner );
	}
	if( _waitEndTime >= 0 ) {
		if( gameLocal.time >= _waitEndTime ) {
			// Exit when the waitstate is not "get up" anymore
			//idStr waitState(owner->WaitState());
			if( waitState != "get_up" ) {
				if( owner->GetMoveType() == MOVETYPE_SIT ) {
					owner->GetUp();
				} else {
					return true;
				}
			}
		}
	} else {
		return true;
	}
	return false;
}
Exemplo n.º 4
0
bool PlayAnimationTask::Perform(Subsystem& subsystem)
{
	DM_LOG(LC_AI, LT_INFO)LOGSTRING("PlayAnimationTask performing.\r");

	idAI* owner = _owner.GetEntity();

	// This task may not be performed with an empty owner pointer
	assert(owner != NULL);

	// Exit when the waitstate is not "customAnim" anymore
	idStr waitState(owner->WaitState());

	if (waitState != "customAnim")
	{
		// We're finished, what now?
		if (_playCycle)
		{
			// Starte the anim cycle again
			StartAnim(owner);
		}
		else
		{
			return true;
		}
	}

	return false;
}
Exemplo n.º 5
0
Timer::Timer(unsigned long _interval, TimerCallback cb, void *ctx) {
  callback = cb;
  callbackContext = ctx;
  interval = _interval;

  waitState(TIMER_STATE_IDLE, 0);
}
Exemplo n.º 6
0
FUNCTION int Q4LI(obj user, obj usedon, int Q5NM)
{
  int Q5NC = 0x00;
  if(Q50G(usedon))
  {
    if(!getMobFlag(usedon, 0x02))
    {
      int Q4NC;
      loc Q4VS = loc( getLocation(user) );
      loc there = loc( getLocation(usedon) );
      faceHere(user, getDirectionInternal(Q4VS, there));
      if(hasObjVar(this, "magicItemModifier"))
      {
        Q4NC = 0x02 * (getObjVar(this, "magicItemModifier")) + 0x05;
      }
      else
      {
        Q4NC = (getSkillLevel(user, 0x19) / 0x0A + 0x01) * 0x02 + 0x05;
      }
      if(Q4CN(NULL(), usedon, 0x05))
      {
        Q4NC = Q4NC / 0x02;
      }
      doMobAnimation(usedon, 0x376A, 0x06, Q4NC, 0x00, 0x00);
      sfx(there, 0x0204, 0x00);
      setWaitState(usedon, Q4NC);
      int Q67T = waitState(usedon);
      setMobFlag(usedon, 0x02, 0x01);
      scriptTrig(usedon, 0x01, user);
      if(isValid(usedon))
      {
        Q422(user, usedon, 0x00, Q5NM);
        if(isValid(usedon))
        {
          Q5UK(user, usedon, 0x02, Q5NM);
          if(isValid(usedon))
          {
            attachScript(usedon, "rempara");
            callback(usedon, Q4NC, 0x0D);
          }
        }
      }
    }
  }
  Q5UQ(this);
  return(Q5NC);
}
Exemplo n.º 7
0
void CGameEngine::initGame()
{
	try{
		boost::property_tree::ptree levelRoot;
		read_info("data\\test_level.info", levelRoot);

		CLevelLoader::load(levelRoot, m_level,m_resourceEngine);
	}
	catch(boost::property_tree::ptree_error &e){
		CLog::error(e.what());
	}
	m_level->setSpeed(100.0f);

	boost::shared_ptr<CPlayGameState> gameState(new CPlayGameState());
	pushState(gameState);

	boost::shared_ptr<CWaitState> waitState(new CWaitState());
	pushState(waitState);

	m_isRunning=true;
}
Exemplo n.º 8
0
bool PathSitTask::Perform(Subsystem& subsystem)
{
	DM_LOG(LC_AI, LT_INFO)LOGSTRING("PathSitTask performing.\r");

	idAI* owner = _owner.GetEntity();

	// This task may not be performed with an empty owner pointer
	assert(owner != NULL);


	if (_waitEndTime >= 0)
	{
		if(gameLocal.time >= _waitEndTime)
		{
			// Exit when the waitstate is not "get up" anymore
			idStr waitState(owner->WaitState());
			if (waitState != "get_up")
			{
				if (owner->GetMoveType() == MOVETYPE_SIT)
				{
					owner->GetUp();
				}
				else
				{
					return true;
				}
			}
		}
	}
	else
	{
		return true;
	}

	return false;
}
Exemplo n.º 9
0
void WifiStateMachine::reset()
{
  waitState(WIFI_OFF, 0);
}
Exemplo n.º 10
0
// Gets called each time the mind is thinking
void UnreachableTargetState::Think(idAI* owner)
{
	Memory& memory = owner->GetMemory();

	idActor* enemy = _enemy.GetEntity();
	if (enemy == NULL)
	{
		DM_LOG(LC_AI, LT_ERROR)LOGSTRING("No enemy!\r");
		owner->GetMind()->SwitchState(STATE_LOST_TRACK_OF_ENEMY);
		return;
	}

	// grayman #3492 - if you kill the enemy with a rock, behave the same
	// way you would had you killed him with a weapon

	if (enemy->AI_DEAD)
	{
		owner->SetLastKilled(enemy);
		owner->ClearEnemy();
		owner->StopMove(MOVE_STATUS_DONE);
		owner->SetAlertLevel(owner->thresh_2 + (owner->thresh_3 - owner->thresh_2) * 0.5);
		
		// grayman #3473 - stop looking at the spot you were looking at when you killed the enemy
		owner->SetFocusTime(gameLocal.time);

		// bark about death

		idStr bark = "";
		idStr enemyAiUse = enemy->spawnArgs.GetString("AIUse");
		if ( ( enemyAiUse == AIUSE_MONSTER ) || ( enemyAiUse == AIUSE_UNDEAD ) )
		{
			bark = "snd_killed_monster";
		}
		else
		{
			bark = "snd_killed_enemy";
		}
		owner->PostEventMS(&AI_Bark,ENEMY_DEAD_BARK_DELAY,bark);

		owner->GetMind()->EndState();
		return;
	}

	// Check the distance to the enemy, the other subsystem tasks need it.
	memory.canHitEnemy = owner->CanHitEntity(enemy);

	if (!owner->AI_ENEMY_VISIBLE)
	{
		// The enemy is not visible, let's keep track of him for a small amount of time
		if (gameLocal.time - memory.lastTimeEnemySeen < MAX_BLIND_CHASE_TIME)
		{
			// Cheat a bit and take the last reachable position as "visible & reachable"
			owner->lastVisibleReachableEnemyPos = owner->lastReachableEnemyPos;
		}
		else
		{
			// BLIND_CHASE_TIME has expired, we have lost the enemy!
			owner->GetMind()->SwitchState(STATE_LOST_TRACK_OF_ENEMY);
			return;
		}
	}

	owner->TurnToward(enemy->GetPhysics()->GetOrigin());
	
	if (owner->spawnArgs.GetBool("outofreach_projectile_enabled", "0") &&
			_moveRequired && (owner->AI_MOVE_DONE || owner->AI_DEST_UNREACHABLE))
	{
		// We are finished moving closer
		// Start throwing now
		_moveRequired = false;

		// greebo: Sheathe weapon before starting to throw // FIXME: put weapon to left hand?
		owner->SheathWeapon();

		owner->FaceEnemy();
		owner->actionSubsystem->PushTask(ThrowObjectTask::CreateInstance());
		_takeCoverTime = gameLocal.time + 3000;
	}

	// This checks if the enemy is reachable again so we can go into combat state
	if (owner->enemyReachable || owner->TestMelee() || memory.canHitEnemy)
	{
		if (owner->GetMind()->PerformCombatCheck())
		{
			owner->GetMind()->EndState();
			return;
		}
	}

	// This checks for a reachable position within combat range
	idVec3 enemyDirection = owner->GetPhysics()->GetOrigin() - enemy->GetPhysics()->GetOrigin();
	enemyDirection.z = 0;
	enemyDirection.NormalizeFast();
	float angle = (_reachEnemyCheck * 90) % 360;
	float sinAngle = idMath::Sin(angle);
	float cosAngle = idMath::Cos(angle);
	idVec3 targetDirection = enemyDirection;
	targetDirection.x = enemyDirection.x * cosAngle + enemyDirection.y * sinAngle;
	targetDirection.y = enemyDirection.y * cosAngle + enemyDirection.x * sinAngle;

	idVec3 targetPoint = enemy->GetPhysics()->GetOrigin() 
				+ (targetDirection * owner->melee_range);
	idVec3 bottomPoint = targetPoint;
	bottomPoint.z -= 70;
	
	trace_t result;
	if (gameLocal.clip.TracePoint(result, targetPoint, bottomPoint, MASK_OPAQUE, NULL))
	{
		targetPoint.z = result.endpos.z + 1;
		int areaNum = owner->PointReachableAreaNum(owner->GetPhysics()->GetOrigin(), 1.0f);
		idVec3 forward = owner->viewAxis.ToAngles().ToForward();
		int targetAreaNum = owner->PointReachableAreaNum(targetPoint, 1.0f, -10*forward);
		aasPath_t path;

		if (owner->PathToGoal(path, areaNum, owner->GetPhysics()->GetOrigin(), targetAreaNum, targetPoint, owner))
		{
			owner->GetMind()->EndState();
			return;
		}
		else
		{
			_reachEnemyCheck++;
		}
	}
	else
	{
		_reachEnemyCheck++;
	}

	_reachEnemyCheck %= 4;
	
	// Wait at least for 3 seconds (_takeCoverTime) after starting to throw before taking cover
	// If a ranged threat from the player is detected (bow is out)
	// take cover if possible after throwing animation is finished
	idStr waitState(owner->WaitState());

	if ( _takingCoverPossible &&
		 ( waitState != "throw" ) &&
		 ( _takeCoverTime > 0 ) &&
		 ( gameLocal.time > _takeCoverTime ) &&
		 ( enemy->RangedThreatTo(owner) || !owner->spawnArgs.GetBool("taking_cover_only_from_archers","0") ))
	{
		owner->GetMind()->SwitchState(STATE_TAKE_COVER);
	}
}
Exemplo n.º 11
0
void MeleeCombatTask::PerformParry(idAI* owner)
{
	CMeleeStatus& ownerStatus = owner->m_MeleeStatus;
	CMeleeStatus& enemyStatus = _enemy.GetEntity()->m_MeleeStatus;
	EMeleeActPhase phase = ownerStatus.m_ActionPhase;
	
	if ( phase == MELEEPHASE_PREPARING )
	{
		if( cv_melee_state_debug.GetBool() )
		{
			idStr debugText = "MeleeAction: Parry, Phase: Preparing";
			gameRenderWorld->DrawText( debugText, (owner->GetEyePosition() - owner->GetPhysics()->GetGravityNormal()*-25), 0.20f, colorMagenta, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec );
		}

		// wait until done with initial delay, then start the animation
		if ( _bInPreParryDelayState && ((gameLocal.time - _ParryDelayTimer) > _PreParryDelay) )
		{
			// Set the waitstate, this gets cleared by script when the anim is done
			owner->SetWaitState("melee_action");

			const char *suffix = idActor::MeleeTypeNames[ownerStatus.m_ActionType];
			// script state plays the animation and clears wait state when done
			// TODO: Why did we have 5 blend frames here?
			owner->SetAnimState(ANIMCHANNEL_TORSO, va("Torso_Parry_%s",suffix), 5);

			_bInPreParryDelayState = false;
		}

		// don't do anything, animation will update status when it reaches hold point
		return;
	}

	if ( phase == MELEEPHASE_HOLDING )
	{
		if( cv_melee_state_debug.GetBool() )
		{
			idStr debugText = "MeleeAction: Parry, Phase: Holding";
			gameRenderWorld->DrawText( debugText, (owner->GetEyePosition() - owner->GetPhysics()->GetGravityNormal()*-25), 0.20f, colorMagenta, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec );
		}

		// Decide whether to keep holding the parry or to release
		bool bRelease = false;

		// If our enemy is no longer attacking, release
		if( enemyStatus.m_ActionState != MELEEACTION_ATTACK
			|| enemyStatus.m_ActionPhase == MELEEPHASE_RECOVERING )
			bRelease = true;
		// If our enemy switches attacks, stop this parry to prepare the next
		else if( ownerStatus.m_ActionType != MELEETYPE_BLOCKALL && ownerStatus.m_ActionType != enemyStatus.m_ActionType )
			bRelease = true;
		// or if enemy is holding for over some time
		else if( enemyStatus.m_ActionPhase == MELEEPHASE_HOLDING
				 && ((gameLocal.time - enemyStatus.m_PhaseChangeTime) > owner->m_MeleeCurrentParryHold) )
		{
			// also force an attack next, so we don't just go back into parry - this creates an opening
			_bForceAttack = true;
			bRelease = true;
		}
		// TODO: Check if enemy is dead or beyond some max range, then stop parrying?
		else
		{
			// debug display the countdown to release
			if( cv_melee_state_debug.GetBool() )
			{
				idStr debugText = va("Parry Waiting for: %d [ms]", (gameLocal.time - enemyStatus.m_PhaseChangeTime) );
				gameRenderWorld->DrawText( debugText, (owner->GetEyePosition() - owner->GetPhysics()->GetGravityNormal()*-40), 0.20f, colorMagenta, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec );
			}
			// otherwise, keep holding the parry
			bRelease = false;
		}

		if( bRelease )
		{
			// owner->Event_PauseAnim( ANIMCHANNEL_TORSO, false );
			_bInPostParryDelayState = true;
			_ParryDelayTimer = gameLocal.time;
			owner->Event_MeleeActionReleased();
		}
	}
	// MELEEPHASE_RECOVERING
	else
	{
		// recovery has two phases: 1. Wait for post-parry delay reaction time
		// and 2. wait for recovery animation to finish


		// If just finishing up the initial delay, start the animation
		if( _bInPostParryDelayState && ((gameLocal.time - _ParryDelayTimer) > _PostParryDelay) )
		{
			owner->Event_PauseAnim( ANIMCHANNEL_TORSO, false );
			_bInPostParryDelayState = false;
		}
		// post parry delay has already finished, wait for animation
		else if( !_bInPostParryDelayState )
		{
			// check if animation is finished (script will set this when it is)
			idStr waitState( owner->WaitState() );
			if( waitState != "melee_action" )
			{
				// if nothing happened with our parry, it was aborted
				if( ownerStatus.m_ActionResult == MELEERESULT_IN_PROGRESS )
					ownerStatus.m_ActionResult = MELEERESULT_PAR_ABORTED;

				owner->Event_MeleeActionFinished();
			}
		}
		// otherwise we wait for the post parry delay

		if( cv_melee_state_debug.GetBool() )
		{
			idStr debugText = "MeleeAction: Parry, Phase: Recovering";
			gameRenderWorld->DrawText( debugText, (owner->GetEyePosition() - owner->GetPhysics()->GetGravityNormal()*-25), 0.20f, colorMagenta, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec );
		}
	}
}
Exemplo n.º 12
0
void MeleeCombatTask::PerformAttack(idAI* owner)
{
	CMeleeStatus& ownerStatus = owner->m_MeleeStatus;
	EMeleeActPhase phase = ownerStatus.m_ActionPhase;
	
	Memory& memory = owner->GetMemory();
	
	if( phase == MELEEPHASE_PREPARING )
	{
		if( cv_melee_state_debug.GetBool() )
		{
			idStr debugText = "MeleeAction: Attack, Phase: Preparing";
			gameRenderWorld->DrawText( debugText, (owner->GetEyePosition() - owner->GetPhysics()->GetGravityNormal()*-25), 0.20f, colorMagenta, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec );
		}
		// don't do anything, animation will update melee status to holding when it reaches the hold point
		// FIX: Some animations don't have a hold point and just go straight through
		idStr waitState( owner->WaitState() );
		if( waitState != "melee_action" )
		{
			// Hack: animation is done, advance the state where it will be handled properly in the next frame
			owner->Event_MeleeActionReleased();
		}
		return;
	}
	else if( phase == MELEEPHASE_HOLDING )
	{
		// TODO: Decide whether to keep holding the attack or release
		// if player is out of range but close, maybe hold the swing and charge at them for a little while?

		if( cv_melee_state_debug.GetBool() )
		{
			idStr debugText = "MeleeAction: Attack, Phase: Holding";
			gameRenderWorld->DrawText( debugText, (owner->GetEyePosition() - owner->GetPhysics()->GetGravityNormal()*-25), 0.20f, colorMagenta, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec );
		}
		
		// wait some finite time before releasing (for difficulty tweaking)
		if( (gameLocal.time - ownerStatus.m_PhaseChangeTime) > owner->m_MeleeCurrentHoldTime )
		{
			owner->Event_PauseAnim( ANIMCHANNEL_TORSO, false );
			owner->Event_MeleeActionReleased();
		}
	}
	// MELEEPHASE_EXECUTING OR MELEEPHASE_RECOVERING
	else
	{
		if( cv_melee_state_debug.GetBool() )
		{
			idStr debugText = "MeleeAction: Attack, Phase: Executing/Recovering";
			gameRenderWorld->DrawText( debugText, (owner->GetEyePosition() - owner->GetPhysics()->GetGravityNormal()*-25), 0.20f, colorMagenta, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, gameLocal.msec );
		}

		// check if animation is finished (script will set this when it is)
		idStr waitState( owner->WaitState() );
		if( waitState != "melee_action" )
		{
			// if attack hasn't hit anything, switch to missed at this point
			if (ownerStatus.m_ActionResult == MELEERESULT_IN_PROGRESS)
			{
				ownerStatus.m_ActionResult = MELEERESULT_AT_MISSED;
			}
			else if (ownerStatus.m_ActionResult == MELEERESULT_AT_PARRIED)
			{
				// Emit our frustration bark with a certain probability (1 out of 3)
				if (gameLocal.random.RandomFloat() > 0.7f)
				{
					EmitCombatBark(owner, "snd_combat_blocked_by_player");
				}
			}
			else if (ownerStatus.m_ActionResult == MELEERESULT_AT_HIT)
			{
				// Emit our success bark with a certain probability (1 out of 3)
				if (gameLocal.random.RandomFloat() > 0.7f)
				{
					bool hasCompany = (MS2SEC(gameLocal.time - memory.lastTimeFriendlyAISeen) <= MAX_FRIEND_SIGHTING_SECONDS_FOR_ACCOMPANIED_ALERT_BARK);

					EmitCombatBark(owner, hasCompany ? "snd_combat_hit_player_company" : "snd_combat_hit_player");
				}
			}

			owner->Event_MeleeActionFinished();
		}
	}
}