void CASW_Simple_Alien::WhatToDoNext(float delta) { if (m_iState == ASW_SIMPLE_ALIEN_ATTACKING) { if (!GetEnemy() || !CanSee(GetEnemy()) || GetEnemy()->GetHealth() <= 0) { LostEnemy(); // clears our enemy and sets us back to idling } else { // head towards enemy SetMoveTarget(GetChaseDestination(GetEnemy())); PerformMovement(delta); } SetNextThink( gpGlobals->curtime + 0.1f ); } else if (m_iState == ASW_SIMPLE_ALIEN_IDLING) { // look for a new enemy? FindNewEnemy(); if (GetEnemy()) SetNextThink( gpGlobals->curtime + 0.1f ); else SetNextThink( gpGlobals->curtime + 0.5f ); } else if (m_iState == ASW_SIMPLE_ALIEN_DEAD) { // don't need to think again } // todo: if in moving to dest state, then move towards that dest, etc. }
void InfectedBunny::ChangeFromInfected(HealthyBunny *hbunny) { assert(hbunny != NULL); m_isActive = true; m_health = 100.0f; SetPosition(hbunny->GetPosition()); SetMoveTarget(hbunny->GetMoveTarget()); m_restingAfterFuckingProgress.SetTicker(GameProps::RestingAfterChangedToInfectedTime); SetState(RestingAfterFucking::GetInstance()); }
void NPC::SetEnemy(edict_t *entity) { if (FNullEnt(entity) || !IsAlive(entity)) { m_enemy = null; m_task &= ~TASK_ENEMY; m_enemyUpdateTime = -1.0f; return; } SetMoveTarget(null); m_enemy = entity; m_task |= TASK_ENEMY; if (m_attackDistance <= 120.0f) m_enemyUpdateTime = gpGlobals->time + 3.0f; else m_enemyUpdateTime = gpGlobals->time + 1.2f; }
void NPC::FindEnemy(void) { if (m_findEnemyMode == -1) { SetEnemy(null); SetMoveTarget(null); return; } int team = GetTeam(GetEntity()); if (m_enemyAPI != null && (FNullEnt(m_enemyAPI) || !IsAlive(m_enemyAPI) || GetTeam(m_enemyAPI) == team)) m_enemyAPI = null; if (!FNullEnt(m_enemy)) { if (!IsAlive(m_enemy) || GetTeam(m_enemy) == team) { SetEnemy(null); LoadEntityWaypointPoint(GetEntity()); m_currentWaypointIndex = -1; FindWaypoint(); } } if (!FNullEnt(m_moveTargetEntity)) { if (!IsAlive(m_moveTargetEntity) || GetTeam(m_moveTargetEntity) == team) SetMoveTarget(null); } edict_t *targetEntity = null; float enemy_distance = 9999.9f; if (!FNullEnt(m_enemy)) targetEntity = m_enemy; else if (!FNullEnt(m_moveTargetEntity)) targetEntity = m_moveTargetEntity; if (!FNullEnt(targetEntity)) { if (m_enemyUpdateTime > gpGlobals->time) return; enemy_distance = GetEntityDistance(targetEntity); } int i, allEnemy = 0; edict_t *entity = null; if (FNullEnt(m_enemyAPI)) { for (i = 0; i < checkEnemyNum; i++) { m_allEnemyId[i] = -1; m_allEnemyDistance[i] = 9999.9f; m_enemyEntityId[i] = -1; m_enemyEntityDistance[i] = 9999.9f; } for (i = 0; i < gpGlobals->maxClients; i++) { entity = INDEXENT(i + 1); if (FNullEnt(entity) || !IsAlive(entity) || GetTeam(entity) == team) continue; m_allEnemyId[allEnemy] = i + 1; m_allEnemyDistance[allEnemy] = GetEntityDistance(entity); allEnemy++; } for (i = 0; i < MAX_NPC; i++) { NPC *npc = g_npcManager->IsSwNPCForNum(i); if (npc == null) continue; entity = npc->GetEntity(); if (FNullEnt(entity) || !IsAlive(entity) || GetTeam(entity) == team) continue; if (entity->v.effects & EF_NODRAW || entity->v.takedamage == DAMAGE_NO) continue; m_allEnemyId[allEnemy] = npc->GetIndex(); m_allEnemyDistance[allEnemy] = GetEntityDistance(entity); allEnemy++; } for (i = 0; i < allEnemy; i++) { for (int y = 0; y < checkEnemyNum; y++) { if (m_allEnemyDistance[i] >= m_enemyEntityDistance[y]) continue; for (int z = allEnemy - 1; z >= y; z--) { if (z == allEnemy - 1 || m_enemyEntityId[z] == -1) continue; m_enemyEntityId[z + 1] = m_enemyEntityId[z]; m_enemyEntityDistance[z + 1] = m_enemyEntityDistance[z]; } m_enemyEntityId[y] = m_allEnemyId[i]; m_enemyEntityDistance[y] = m_allEnemyDistance[i]; break; } } for (i = 0; i < checkEnemyNum; i++) { if (m_enemyEntityId[i] == -1) continue; entity = INDEXENT(m_enemyEntityId[i]); if (IsEnemyViewable(entity)) { enemy_distance = m_enemyEntityDistance[i]; targetEntity = entity; break; } } } else { targetEntity = m_enemyAPI; enemy_distance = GetEntityDistance(m_enemyAPI); } if (!FNullEnt(m_moveTargetEntity) && m_moveTargetEntity != targetEntity) { if (m_currentWaypointIndex != g_waypoint->GetEntityWpIndex(targetEntity)) { float distance = GetEntityDistance(m_moveTargetEntity); if (distance <= enemy_distance + 400.0f) { enemy_distance = distance; targetEntity = null; } } } if (!FNullEnt(targetEntity)) { if (!IsEnemyViewable(targetEntity)) { if (targetEntity == m_enemyAPI) { SetMoveTarget(targetEntity); return; } targetEntity = null; } } if (!FNullEnt(m_enemy) && FNullEnt (targetEntity)) { SetMoveTarget(m_enemy); return; } if (!FNullEnt(targetEntity)) { if (m_attackDistance <= 300.0f) { bool moveTarget = true; int srcIndex = g_waypoint->GetEntityWpIndex(GetEntity()); int destIndex = g_waypoint->GetEntityWpIndex(targetEntity); enemy_distance = GetDistance(pev->origin, GetEntityOrigin (targetEntity)); if (srcIndex == destIndex || m_currentWaypointIndex == destIndex) moveTarget = false; else if (enemy_distance <= m_attackDistance) moveTarget = false; else if (m_attackDistance <= 120.0f) { if (targetEntity == m_moveTargetEntity && &m_navNode[0] != null) { if (m_navNode->index == destIndex) moveTarget = false; } else { int movePoint = 0; while (srcIndex != destIndex && movePoint < 99 && srcIndex >= 0 && destIndex >= 0) { srcIndex = *(g_waypoint->m_pathMatrix + (srcIndex * g_numWaypoints) + destIndex); if (srcIndex < 0) continue; movePoint++; } if ((enemy_distance <= 120.0f && movePoint <= 2) || (targetEntity == m_moveTargetEntity && movePoint <= 1)) moveTarget = false; } } if (!moveTarget) { SetEnemy(targetEntity); return; } SetMoveTarget(targetEntity); } else SetEnemy(targetEntity); } }
// SyPB Pro P.29 - new Look UP Enemy bool Bot::LookupEnemy(void) { m_visibility = 0; m_enemyOrigin = nullvec; if (m_blindTime > engine->GetTime() || sypb_noshots.GetBool()) return false; if (!FNullEnt(m_lastEnemy)) { if (IsNotAttackLab(m_lastEnemy) || !IsAlive(m_lastEnemy) || (GetTeam(m_lastEnemy) == GetTeam(GetEntity()))) { m_lastEnemy = null; m_lastEnemyOrigin = nullvec; } } if (!FNullEnt(m_lastVictim)) { if (!IsAlive(m_lastVictim) || (GetTeam(m_lastVictim) == GetTeam(GetEntity()))) m_lastVictim = null; } m_states &= ~STATE_SUSPECTENEMY; int team = GetTeam(GetEntity()), i; edict_t *entity = null, *targetEntity = null; float enemy_distance = 9999.0f; // SyPB Pro P.30 - AMXX API if (m_blockCheckEnemyTime > engine->GetTime()) { if (!FNullEnt(m_moveTargetEntityAPI)) { if (GetTeam(GetEntity()) != GetTeam(m_moveTargetEntityAPI) && IsAlive(m_moveTargetEntityAPI)) SetMoveTarget(m_moveTargetEntityAPI); else { // SyPB Pro P.32 - API Fixed SetMoveTarget(null); m_moveTargetEntityAPI = null; } } else if (!FNullEnt(m_enemyAPI)) { if (GetTeam(GetEntity()) != GetTeam(m_enemyAPI) && IsAlive(m_enemyAPI)) { m_targetEntity = null; m_enemy = m_enemyAPI; m_lastEnemy = m_enemy; m_lastEnemyOrigin = GetEntityOrigin(m_enemy); m_enemyReachableTimer = 0.0f; m_seeEnemyTime = engine->GetTime(); if (!IsEnemyViewable(m_enemy, 1)) m_enemyOrigin = GetEntityOrigin(m_enemy); return true; } else m_enemyAPI = null; } return false; } m_enemyAPI = null; m_moveTargetEntityAPI = null; if (!FNullEnt(m_enemy)) { if (GetTeam(GetEntity()) == GetTeam(m_enemy) || IsNotAttackLab(m_enemy) || !IsAlive(m_enemy)) return false; if (m_enemyUpdateTime > engine->GetTime() && !(m_states & STATE_SUSPECTENEMY)) { m_aimFlags |= AIM_ENEMY; return true; } if (IsEnemyViewable(m_enemy, 1)) { targetEntity = m_enemy; enemy_distance = GetEntityDistance(m_enemy); } } else if (!FNullEnt(m_moveTargetEntity)) { if (GetTeam(GetEntity()) == GetTeam(m_moveTargetEntity) || !IsAlive(m_moveTargetEntity)) { SetMoveTarget(null); return false; } targetEntity = m_moveTargetEntity; m_moveTargetOrigin = GetEntityOrigin(m_moveTargetEntity); enemy_distance = GetEntityDistance(m_moveTargetEntity); } // SyPB Pro P.34 - Zombie mode if (IsZombieBot(GetEntity())) { if (!FNullEnt(m_moveTargetEntity)) { if (m_enemyUpdateTime > engine->GetTime()) return false; } if (FNullEnt (m_enemy)) m_enemyUpdateTime = engine->GetTime() + 0.15f; } for (i = 1; i <= engine->GetMaxClients(); i++) { entity = INDEXENT(i); if (FNullEnt(entity) || !IsAlive(entity) || GetTeam(entity) == team || entity == GetEntity()) continue; if (IsBehindSmokeClouds(entity) && m_blindRecognizeTime < engine->GetTime()) m_blindRecognizeTime = engine->GetTime() + engine->RandomFloat(2.0, 3.0f); if (m_blindRecognizeTime >= engine->GetTime()) continue; float distance = GetEntityDistance(entity); if (distance >= enemy_distance) continue; if (IsEnemyProtectedByShield(entity)) continue; if (IsEnemyViewable(entity)) { enemy_distance = distance; targetEntity = entity; if ((g_mapType & MAP_AS) && *(INFOKEY_VALUE(GET_INFOKEYBUFFER(entity), "model")) == 'v') break; } } ITERATE_ARRAY(g_entityName, j) { if (g_entityAction[j] != 1 || (GetTeam(GetEntity()) == (g_entityTeam[j] - 1) && g_entityTeam[j] != 0)) continue; while (!FNullEnt(entity = FIND_ENTITY_BY_CLASSNAME(entity, g_entityName[j]))) { if (FNullEnt(entity) || entity == m_enemy) continue; float distance = GetEntityDistance(entity); if (distance >= enemy_distance) continue; if (IsBehindSmokeClouds(entity) && m_blindRecognizeTime < engine->GetTime()) m_blindRecognizeTime = engine->GetTime() + engine->RandomFloat(2.0, 3.0f); // SyPB Pro P.30 - NPC Fixed if (IsEnemyViewable(entity)) { enemy_distance = distance; targetEntity = entity; } } } if (!FNullEnt(targetEntity)) // Last Checking { enemy_distance = GetEntityDistance(targetEntity); if (GetTeam(targetEntity) == team || !IsEnemyViewable(targetEntity, 1)) targetEntity = null; } if (!FNullEnt(m_enemy) && IsZombieBot(GetEntity())) { if (FNullEnt(targetEntity)) // Has not new enemy, and cannot see old enemy { g_botsCanPause = false; // SyPB Pro P.32 - Zombie Ai int botSrcIndex = g_waypoint->FindNearest(pev->origin); int targetSrcIndex = g_waypoint->FindNearest(GetEntityOrigin (m_enemy)); int botStartIndex = *(g_waypoint->m_pathMatrix + (botSrcIndex * g_numWaypoints) + targetSrcIndex); if (!(botStartIndex < 0)) ChangeWptIndex(botStartIndex); RemoveCertainTask(TASK_MOVETOTARGET); SetMoveTarget(m_enemy); return false; } // SyPB Pro P.30 - Zombie Ai else if (targetEntity != m_enemy) { float distance = GetEntityDistance(m_enemy); if (enemy_distance + 50.0f >= distance) { targetEntity = m_enemy; enemy_distance = distance; } } } if (!FNullEnt(targetEntity)) { // SyPB Pro P.34 - Zombie Ai if (IsZombieBot(GetEntity())) { // SyPB Pro P.36 - Zombie Ai float distance = GetEntityDistance(targetEntity); enemy_distance = (GetEntityOrigin (targetEntity) - pev->origin).GetLength(); bool moveTotarget = false; if (enemy_distance >= 150.0f) { moveTotarget = true; if (targetEntity == m_moveTargetEntity) { if (m_navNode == null || (m_navNode != null && m_navNode->next == null)) { moveTotarget = false; // SyPB Pro P.37 - Zombie Ai m_enemyUpdateTime = engine->GetTime() + 4.0f; } } } else if (enemy_distance >= 80.0f && distance >= (enemy_distance * 2)) moveTotarget = true; //else if (m_navNode != null && enemy_distance > 20.0f && distance >= 30.0f)//&& enemy_distance > 40.0f) else if (m_navNode != null && enemy_distance >= 20.0f)// && distance >= 30.0f) { PathNode *navid = &m_navNode[0]; Path *path; while (navid != null) { path = g_waypoint->GetPath(navid->index); navid = navid->next; if (navid != null) { if (path->connectionFlags[navid->index] & PATHFLAG_JUMP) { moveTotarget = true; navid = null; } } } } if (moveTotarget) { // SyPB Pro P.35 - Fixed if (enemy_distance <= 80.0f) //if (moveTotarget <= 80.0f) pev->button |= IN_ATTACK; if (targetEntity != m_moveTargetEntity) { g_botsCanPause = false; // SyPB Pro P.32 - Zombie Ai int botSrcIndex = g_waypoint->FindNearest(pev->origin); int targetSrcIndex = g_waypoint->FindNearest(GetEntityOrigin (targetEntity)); int botStartIndex = *(g_waypoint->m_pathMatrix + (botSrcIndex * g_numWaypoints) + targetSrcIndex); if (!(botStartIndex < 0)) ChangeWptIndex(botStartIndex); SetMoveTarget(targetEntity); } return false; } // SyPB Pro P.37 - Zombie Ai if (m_enemyUpdateTime < engine->GetTime() + 3.0f) m_enemyUpdateTime = engine->GetTime() + 2.5f; } g_botsCanPause = true; m_aimFlags |= AIM_ENEMY; if (targetEntity == m_enemy) { m_seeEnemyTime = engine->GetTime(); m_actualReactionTime = 0.0f; m_lastEnemy = targetEntity; m_lastEnemyOrigin = GetEntityOrigin(targetEntity); return true; } if (m_seeEnemyTime + 3.0f < engine->GetTime() && (pev->weapons & (1 << WEAPON_C4) || HasHostage() || !FNullEnt(m_targetEntity))) RadioMessage(Radio_EnemySpotted); m_targetEntity = null; if (engine->RandomInt(0, 100) < m_skill) m_enemySurpriseTime = engine->GetTime() + (m_actualReactionTime / 3); else m_enemySurpriseTime = engine->GetTime() + m_actualReactionTime; m_actualReactionTime = 0.0f; m_enemy = targetEntity; m_lastEnemy = m_enemy; m_lastEnemyOrigin = GetEntityOrigin(m_enemy); m_enemyReachableTimer = 0.0f; m_seeEnemyTime = engine->GetTime(); if (!IsZombieBot(GetEntity())) m_enemyUpdateTime = engine->GetTime() + 0.6f; //m_enemyUpdateTime = (IsZombieBot(GetEntity()) ? engine->GetTime() + 2.5f : engine->GetTime() + 0.6f); return true; } if ((m_aimFlags <= AIM_PREDICTENEMY && m_seeEnemyTime + 4.0f < engine->GetTime() && !(m_states & (STATE_SEEINGENEMY | STATE_HEARENEMY)) && FNullEnt(m_lastEnemy) && FNullEnt(m_enemy) && GetCurrentTask()->taskID != TASK_DESTROYBREAKABLE && GetCurrentTask()->taskID != TASK_PLANTBOMB && GetCurrentTask()->taskID != TASK_DEFUSEBOMB) || g_roundEnded) { if (!m_reloadState) m_reloadState = RSTATE_PRIMARY; } if ((UsesSniper() || UsesZoomableRifle()) && m_zoomCheckTime + 1.0f < engine->GetTime()) { if (pev->fov < 90) pev->button |= IN_ATTACK2; else m_zoomCheckTime = 0.0f; } return false; }
// we failed to move this interval // returns true if we lay in a new move target bool CASW_Simple_Alien::FailedMove() { m_bMoving = false; m_vecMoveTarget = GetAbsOrigin(); // we've hit something if (m_MoveFailure.trace.m_pEnt) { Vector vecNormal = m_MoveFailure.trace.plane.normal; // todo: if we've hit a marine, hurt him? CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(m_MoveFailure.trace.m_pEnt); if (pMarine) { // it's okay to be stuck on a marine, since that means we're probably clawing him to bits! return false; } // if we've hit another alien, set our normal as though it were a cylinder collision, to get a more accurate avoidance // note: won't work unless the actual movement of the alien is done with a cylinder too //CASW_Simple_Alien *pAlien = dynamic_cast<CASW_Simple_Alien*>(m_MoveFailure.trace.m_pEnt); //if (pAlien) //{ //vecNormal = pAlien->GetAbsOrigin() - GetAbsOrigin(); //vecNormal.NormalizeInPlace(); //} // otherwise, assume we've hit some prop or geometry // if we have no enemy, just randomly move away from the wall if (!GetEnemy()) { SetMoveTarget(PickRandomDestination(32.0f, 16.0f * vecNormal)); return true; } // pick a random distance to move away from the wall float fDist = 56.25f; float fDistPick = random->RandomFloat(); if (fDistPick > 0.8f) fDist = 187.5f; else if (fDistPick > 0.4f) fDist = 112.5f; // find vectors for the two possible directions float wall_yaw = UTIL_VecToYaw(vecNormal); float wall_yaw_left = wall_yaw - 90.0f; float wall_yaw_right = wall_yaw + 90.0f; // which one takes us closer to the enemy? float enemy_yaw = UTIL_VecToYaw(GetEnemy()->GetAbsOrigin() - GetAbsOrigin()); if (fabs(UTIL_AngleDiff(enemy_yaw, wall_yaw_left)) < fabs(UTIL_AngleDiff(enemy_yaw, wall_yaw_right))) { // go left Vector vecLeft; AngleVectors(QAngle(0, wall_yaw_left, 0), &vecLeft); SetMoveTarget(GetAbsOrigin() + vecLeft * fDist); } else { // go right Vector vecRight; AngleVectors(QAngle(0, wall_yaw_right, 0), &vecRight); SetMoveTarget(GetAbsOrigin() + vecRight * fDist); } return true; } return false; }