void CASW_Sentry_Top::AnimThink( void )
{	
	float deltatime = gpGlobals->curtime - m_fLastThinkTime;
	m_fLastThinkTime = gpGlobals->curtime;
	SetNextThink( gpGlobals->curtime + 0.01f );
		
	m_iEnemySkip++;
	if (m_iEnemySkip >= 5)
	{
		m_iEnemySkip = 0;
		FindEnemy();
	}
	UpdateGoal();
	TurnToGoal(deltatime);
	CheckFiring();
	StudioFrameAdvance();
}
Exemple #2
0
void NPC::NPCAi(void)
{
	m_frameInterval = gpGlobals->time - m_lastThinkTime;
	m_lastThinkTime = gpGlobals->time;

	m_nextThinkTime = gpGlobals->time + 0.1f;

	g_npcAS = ASC_IDLE;
	m_moveSpeed = 0.0f;
	m_destOrigin = nullvec;
		
	FindWaypoint();

	FindEnemy();
	if (m_task & TASK_ENEMY)
		TaskEnemy();
	else if (m_task & TASK_MOVETOTARGET)
		TaskMoveTarget();
	else
		TaskBase();

	if (m_destOrigin == nullvec && m_currentWaypointIndex != -1)
	{
		m_destOrigin = m_waypointOrigin;
		m_lookAt = m_destOrigin;
		m_moveSpeed = pev->maxspeed;
	}

	if (m_iDamage)
	{
		m_changeActionTime = -1.0f;
		g_npcAS |= ASC_DAMAGE;
		m_iDamage = false;
	}

	FacePosition();
	MoveAction();

	ChangeAnim();
	pev->nextthink = m_nextThinkTime;
}
Exemple #3
0
void AIPlayer::Update(float dt)
{
	if (m_Squads.size() == 0)
		return;

	//Return fire
	CheckBeingAttacked();

	m_Brain.LastUpdateWorldView += dt;

	//Update view of life
	if (m_Brain.LastUpdateWorldView > m_Brain.DelayUpdateWorldView)
	{
		UpdateWorldView();
		m_Brain.LastUpdateWorldView = 0;
	}

	m_Perceptions[PERCEPTION_KNOWN_FARM] = static_cast<float>(m_Brain.FoodLocations.size());

	m_Perceptions[PERCEPTION_OWNED_CONTROL_POINTS] = static_cast<float>(g_SSControlPoint.GetOwnedControlPointsCount(m_Team));

	rVector<bool> currentDecisions = m_Decisions;

	if (m_Perceptions[PERCEPTION_UNDER_ATTACK])
	{
		m_Brain.TimeSinceAttacked += dt;
		if (m_Brain.TimeSinceAttacked > m_Genes.IsUnderAttackReset)
		{
			m_Brain.TimeSinceAttacked = 0;
			m_Perceptions[PERCEPTION_UNDER_ATTACK] = 0;
			m_Brain.SquadIDUnderAttack = -1;
		}
	}

	m_Brain.TimeSinceDecision += dt;

	Terrain::EnemyZone zone = Terrain::GetInstance()->GetClosestEnemy(Terrain::GetInstance()->GetTile(0,0), 1000, m_Team, 0);

	for (int squad = 0; squad < m_Squads.size();squad++)
	{
		if (!m_Squads[squad]->HasMission() || m_Brain.TimeSinceDecision > m_Brain.DecisionCoolDown || zone.Amount != m_Brain.LastKnownEnemySize || m_Brain.TimeSinceAttacked == dt)
		{
			m_Brain.TimeSinceDecision = 0;

			m_Perceptions[PERCEPTION_SIZE_SELF] = static_cast<float>(m_Squads[squad]->GetSize());

			m_Perceptions[PERCEPTION_UPGRADE_VALUE] = static_cast<float>(g_SSUpgrades.GetUnitValue(m_Squads[squad]->GetLeader()->GetEntityID())) - UNIT_DEFAULT_VALUE;

			m_Perceptions[PERCEPTION_AVAILABLE_UPGRADES] = 0;

			UPGRADE_NAME chosenUpg = UPGRADE_NAME::EMPTY;

			int indexStart = m_Brain.CurrentUpgradeLoopIndex - 1;

			if (indexStart < 0)
				indexStart = 0;

			bool tryTwoLoops = false;

			if (indexStart != 0)
				tryTwoLoops = true;

			for (int i = indexStart; i < m_Genes.PreferredUpgrade.size(); i++)
			{
				if (g_SSResearch.GetPlayerResearchDone(m_Team, static_cast<UPGRADE_NAME>(m_Genes.PreferredUpgrade[i])))
				{
					if (!g_SSUpgrades.SquadHasUpgrade(m_Team, m_Squads[squad]->GetID(), m_Genes.PreferredUpgrade[i]))
					{
						UpgradeData data = g_SSUpgrades.GetUpgrade(m_Genes.PreferredUpgrade[i]);

						//no overwrite cheating
						if (!g_SSUpgrades.SquadSlotFree(m_Team, m_Squads[squad]->GetID(), data.Slot))
						{
							continue;
						}

						m_Perceptions[PERCEPTION_AVAILABLE_UPGRADES]++;
					}
				}

				if (i == m_Genes.PreferredUpgrade.size() - 1 && tryTwoLoops)
				{
					i = 0;
					tryTwoLoops = false;
				}
			}

// 			int slotsTaken = 0;
// 			ParentComponent* parentComponent = GetDenseComponent<ParentComponent>(m_Squads[squad]->GetLeader()->GetEntityID());
// 			for (Entity slot : parentComponent->Children)
// 			{
// 				if (slot != ENTITY_INVALID)
// 				{
// 					slotsTaken++;
// 				}
// 			}
// 
// 			if (slotsTaken == 4)
// 				m_Perceptions[PERCEPTION_AVAILABLE_UPGRADES] = 0;
// 			else
// 			{
// 				if (m_AllResearchFinished)
// 				{
// 					m_Perceptions[PERCEPTION_AVAILABLE_UPGRADES] = static_cast<float>(m_Genes.PreferredUpgrade.size());
// 				}
// 				else
// 				{
// 					for (int i = 0; i < m_Genes.PreferredUpgrade.size(); i++)
// 					{
// 						if (g_SSResearch.GetPlayerResearchDone(m_Team, static_cast<UPGRADE_NAME>(m_Genes.PreferredUpgrade[i])) && g_SSUpgrades.SquadSlotFree(m_Team, m_Squads[squad]->GetID(), g_SSUpgrades.GetUpgradeSlot(static_cast<UPGRADE_NAME>(m_Genes.PreferredUpgrade[i]))))
// 							m_Perceptions[PERCEPTION_AVAILABLE_UPGRADES]++;
// 					}
// 				}
// 			}

			FindEnemy(m_Squads[squad]->GetLeader()->GetTile());

			//Train
			if (m_IsNeuralNetAI)
			{
				GetNetOutput();

				if (AI_TRAIN_NEURAL_NETS)
				{
					SoftTraining(squad);
				}
			}
			else
				HardTrainingData();

// 				if (PRINT_AI_PLAYER)
// 					printf("team: %d squad %d | At: %d, F: %d, Sc: %d, Rt: %d, Sp: %d, Up: %d\n", m_Team,squad->GetID(), m_Decisions[DECISION_ATTACK] ? 1 : -1, m_Decisions[DECISION_FARM] ? 1 : -1, m_Decisions[DECISION_SCOUT] ? 1 : -1, m_Decisions[DECISION_RETREAT] ? 1 : -1, m_Decisions[DECISION_SPLIT] ? 1 : -1, m_Decisions[DECISION_UPGRADE] ? 1 : -1);


			if (!m_IsNeuralNetAI)
			{
				for (int i = 0; i < m_Decisions.size(); i++)
				{
					m_Decisions[i] = (m_WantedOutputs[i] == 1);
				}
			}

			if (m_Perceptions[PERCEPTION_SIZE_SELF] >= SQUAD_MAXIMUM_UNIT_COUNT && m_Squads.size() < SQUAD_MAXIMUM_SQUAD_COUNT)
				DecideToSplit(m_Squads[squad]);

			if (m_Decisions[DECISION_UPGRADE])
				DecideToUpgrade(m_Squads[squad]);
			else if (m_Decisions[DECISION_RETREAT])
				DecideToRetreat(m_Squads[squad]);
			else if (m_Decisions[DECISION_ATTACK])
				DecideToAttack(m_Squads[squad]);
			else if (m_Decisions[DECISION_FARM])
				DecideToFarm(m_Squads[squad]);
			else if (m_Decisions[DECISION_SCOUT])
				DecideToScout(m_Squads[squad]);

			m_SavedPerceptions[squad].push_back(m_Perceptions);
			m_SavedDecisions[squad].push_back(m_Decisions);

			for (int i = 0; i < m_TrainingVector.size(); i++)
			{
				m_TrainingVector[i] = 0.0f;
			}
		}
	}
	
	m_Brain.LastKnownEnemySize = zone.Amount;

#if AI_DRAW_NEURAL_NETS == 1
	if (m_IsNeuralNetAI)
	{
		rString decision = "None";
		if (m_Decisions[DECISION_ATTACK])
			decision = "Attack";
		else if (m_Decisions[DECISION_FARM])
			decision = "Farm";
		else if (m_Decisions[DECISION_SCOUT])
			decision = "Scout";
		else if (m_Decisions[DECISION_RETREAT])
			decision = "Retreat";
// 		else if (m_Decisions[DECISION_SPLIT])
// 			decision = "Split";
		else if (m_Decisions[DECISION_UPGRADE])
			decision = "Upgrade";

		rString text = 
			"Player: " + rToString(m_Team) + 
			"\nDecision: " + decision + 
			"\nFitness: " + rToString(m_Genes.Fitness) + 
			"\nError: " + rToString(m_Net->GetError());
		m_Net->SetText(text);
	}
#endif
}
qboolean
Pet_FindTarget(edict_t * self)
{
	edict_t * enemy = 0;
	edict_t * PetOwner = self->monsterinfo.PetOwner;
	int radius = 500;
//	int bCammed = false;

	// follow mode means ignore combat
	if (self->monsterinfo.PetState & PET_FOLLOW)
	{
		self->enemy = 0;
		self->goalentity = PetOwner;
		return true;
	}

// optional bonus for a pet actively being cammed
//	if (PetOwner->client->petcam == self)
//	{
//		bCammed = true;
//		radius = 1000;
//	}

	// help master if appropriate
	if (!(self->monsterinfo.PetState & PET_FREETARGET)
		&& PetOwner->enemy)
	{
		vec3_t dir;
		double distance;
		VectorSubtract(self->s.origin,PetOwner->s.origin, dir);
		distance = VectorLength(dir);
		if ( distance < 400)
			enemy = PetOwner->enemy;
	}

	if (!enemy)
		enemy = FindEnemy(self, radius);

	if (enemy)
	{
		self->enemy = enemy;
		FoundTarget (self);

		if (!(self->monsterinfo.aiflags & AI_SOUND_TARGET) && (self->monsterinfo.sight))
			self->monsterinfo.sight (self, self->enemy);
		return true;
	}

	// no enemy, what about following owner ?
	self->enemy = 0; // 2000/05/27
	self->goalentity = 0;
	if (!(self->monsterinfo.PetState & PET_FREE)
			&& visible(self, PetOwner))
	{
		if (DistanceTo(self, PetOwner) > 100)
		{
			self->goalentity = PetOwner;
			self->monsterinfo.pausetime = level.time;
		}
		else
		{
			self->monsterinfo.stand (self);
			self->monsterinfo.pausetime = level.time + 30;
		}
	}
	return false;
}