void NPC::TaskBase(void) { if (m_goalWaypointAPI != -1) { if (m_goalWaypointAPI != m_goalWaypoint) { DeleteSearchNodes(); m_goalWaypoint = m_goalWaypointAPI; } } if (DoWaypointNav()) { m_goalWaypoint = -1; if (m_goalWaypointAPI != -1 && m_goalWaypointAPI == m_currentWaypointIndex) m_goalWaypointAPI = -1; } if (!GoalIsValid()) { if (m_goalWaypoint == -1) m_goalWaypoint = RANDOM_LONG(0, g_numWaypoints - 1); FindWaypoint(); DeleteSearchNodes(); FindShortestPath(m_currentWaypointIndex, m_goalWaypoint); } }
void NPC::TaskMoveTarget(void) { if (FNullEnt(m_moveTargetEntity)) return; if (DoWaypointNav()) DeleteSearchNodes(); int destIndex = g_waypoint->GetEntityWpIndex(m_moveTargetEntity); if (destIndex >= 0 && destIndex < g_numWaypoints) { bool moveToTarget = false; if (&m_navNode[0] != null) { PathNode *node = m_navNode; while (node->next != null) node = node->next; if (node->index == destIndex) moveToTarget = true; } if (!GoalIsValid() || (m_goalWaypoint != destIndex && !moveToTarget)) { int srcIndex = m_currentWaypointIndex; if (m_currentWaypointIndex != g_waypoint->GetEntityWpIndex(GetEntity())) { if (*(g_waypoint->m_distMatrix + (m_currentWaypointIndex * g_numWaypoints) + destIndex) <= *(g_waypoint->m_distMatrix + (g_waypoint->GetEntityWpIndex(GetEntity()) * g_numWaypoints) + destIndex)) srcIndex = m_currentWaypointIndex; else srcIndex = g_waypoint->GetEntityWpIndex(GetEntity()); } DeleteSearchNodes(); m_currentWaypointIndex = srcIndex; m_navTime = gpGlobals->time + 5.0f; SetWaypointOrigin(); m_goalWaypoint = destIndex; FindShortestPath(m_currentWaypointIndex, m_goalWaypoint); } if (m_currentWaypointIndex == m_goalWaypoint) SetEnemy(m_moveTargetEntity); } }
void NPC::ResetNPC(void) { m_enemy = null; m_enemyUpdateTime = -1.0f; m_moveTargetEntity = null; m_lookAt = nullvec; m_moveSpeed = 0.0f; //m_strafeSpeed = 0.0f; m_jumpAction = false; m_destOrigin = nullvec; m_deadActionTime = -1.0f; m_changeActionTime = -1.0f; m_currentWaypointIndex = -1; m_navTime = gpGlobals->time; m_goalWaypoint = -1; m_asTime = 0.0f; m_attackTime = 0.0f; m_checkStuckTime = -1.0f; m_prevOrigin = nullvec; g_npcAS = ASC_IDLE; m_task = TASK_BASE; m_iDamage = false; m_goalWaypointAPI = -1; m_enemyAPI = null; DeleteSearchNodes(); }
void NPC::FindShortestPath(int srcIndex, int destIndex) { DeleteSearchNodes(); PathNode *node = new PathNode; node->index = srcIndex; node->next = null; m_navNodeStart = node; m_navNode = m_navNodeStart; while (srcIndex != destIndex) { srcIndex = *(g_waypoint->m_pathMatrix + (srcIndex * g_numWaypoints) + destIndex); if (srcIndex < 0) { m_goalWaypoint = -1; return; } node->next = new PathNode (); node = node->next; node->index = srcIndex; node->next = null; } }
NPC::~NPC(void) { DeleteSearchNodes(); m_pmodel = null; pev = null; pvData = null; g_npcManager->UpdateNPCNum(); }
void NPC::TaskEnemy(void) { if (FNullEnt(m_enemy)) return; m_destOrigin = GetEntityOrigin (m_enemy); m_lookAt = m_destOrigin; DeleteSearchNodes(); m_goalWaypoint = -1; m_moveSpeed = pev->maxspeed; AttackAction(m_enemy); }
Bot::~Bot (void) { // this is bot destructor // SwitchChatterIcon (false); // crash on CTRL+C'ing win32 console hlds DeleteSearchNodes (); ResetTasks (); // free used botname ITERATE_ARRAY (g_botNames, j) { if (strcmp (g_botNames[j].name, STRING (pev->netname)) == 0) { g_botNames[j].isUsed = false; break; } } }
bool NPC::FindWaypoint(void) { bool needFindWaypont = false; if (m_currentWaypointIndex < 0 || m_currentWaypointIndex >= g_numWaypoints) needFindWaypont = true; else if (m_navTime <= gpGlobals->time) needFindWaypont = true; if (needFindWaypont) { DeleteSearchNodes(); m_currentWaypointIndex = g_waypoint->GetEntityWpIndex(GetEntity()); m_navTime = gpGlobals->time + 5.0f; SetWaypointOrigin(); } return needFindWaypont; }
void Bot::NewRound (void) { // this function initializes a bot after creation & at the start of each round int i = 0; // delete all allocated path nodes DeleteSearchNodes (); m_waypointOrigin = nullvec; m_destOrigin = nullvec; m_currentWaypointIndex = -1; m_currentTravelFlags = 0; m_desiredVelocity = nullvec; m_prevGoalIndex = -1; m_chosenGoalIndex = -1; m_loosedBombWptIndex = -1; m_moveToC4 = false; m_duckDefuse = false; m_duckDefuseCheckTime = 0.0f; m_prevWptIndex[0] = -1; m_prevWptIndex[1] = -1; m_prevWptIndex[2] = -1; m_prevWptIndex[3] = -1; m_prevWptIndex[4] = -1; m_navTimeset = engine->GetTime (); switch (m_personality) { case PERSONALITY_NORMAL: m_pathType = engine->RandomInt (0, 100) > 50 ? 0 : 1; break; case PERSONALITY_RUSHER: m_pathType = 0; break; case PERSONALITY_CAREFUL: m_pathType = 1; break; } // clear all states & tasks m_states = 0; ResetTasks (); m_isVIP = false; m_isLeader = false; m_hasProgressBar = false; m_canChooseAimDirection = true; m_timeTeamOrder = 0.0f; m_askCheckTime = 0.0f; m_minSpeed = 260.0f; m_prevSpeed = 0.0f; m_prevOrigin = Vector (9999.0, 9999.0, 9999.0f); m_prevTime = engine->GetTime (); m_blindRecognizeTime = engine->GetTime (); m_viewDistance = 4096.0f; m_maxViewDistance = 4096.0f; m_pickupItem = null; m_itemIgnore = null; m_itemCheckTime = 0.0f; m_breakableEntity = null; m_breakable = nullvec; m_timeDoorOpen = 0.0f; ResetCollideState (); ResetDoubleJumpState (); m_enemy = null; m_lastVictim = null; m_lastEnemy = null; m_lastEnemyOrigin = nullvec; m_trackingEdict = null; m_timeNextTracking = 0.0f; m_buttonPushTime = 0.0f; m_enemyUpdateTime = 0.0f; m_seeEnemyTime = 0.0f; m_shootAtDeadTime = 0.0f; m_oldCombatDesire = 0.0f; m_avoidGrenade = null; m_needAvoidGrenade = 0; m_lastDamageType = -1; m_voteKickIndex = 0; m_lastVoteKick = 0; m_voteMap = 0; m_doorOpenAttempt = 0; m_aimFlags = 0; m_burstShotsFired = 0; m_position = nullvec; m_idealReactionTime = g_skillTab[m_skill / 20].minSurpriseTime; m_actualReactionTime = g_skillTab[m_skill / 20].minSurpriseTime; m_targetEntity = null; m_followWaitTime = 0.0f; for (i = 0; i < Const_MaxHostages; i++) m_hostages[i] = null; for (i = 0; i < Chatter_Total; i++) m_voiceTimers[i] = -1.0f; m_isReloading = false; m_reloadState = RSTATE_NONE; m_reloadCheckTime = 0.0f; m_shootTime = engine->GetTime (); m_playerTargetTime = engine->GetTime (); m_firePause = 0.0f; m_timeLastFired = 0.0f; m_grenadeCheckTime = 0.0f; m_isUsingGrenade = false; m_skillOffset = (100 - m_skill) / 100.0f; m_blindButton = 0; m_blindTime = 0.0f; m_jumpTime = 0.0f; m_jumpFinished = false; m_isStuck = false; m_sayTextBuffer.timeNextChat = engine->GetTime (); m_sayTextBuffer.entityIndex = -1; m_sayTextBuffer.sayText[0] = 0x0; m_buyState = 0; if (!m_notKilled) // if bot died, clear all weapon stuff and force buying again { memset (&m_ammoInClip, 0, sizeof (m_ammoInClip)); memset (&m_ammo, 0, sizeof (m_ammo)); m_currentWeapon = 0; } m_knifeAttackTime = engine->GetTime () + engine->RandomFloat (1.3f, 2.6f); m_nextBuyTime = engine->GetTime () + engine->RandomFloat (0.6f, 1.2f); m_buyPending = false; m_inBombZone = false; m_shieldCheckTime = 0.0f; m_zoomCheckTime = 0.0f; m_strafeSetTime = 0.0f; m_combatStrafeDir = 0; m_fightStyle = 0; m_lastFightStyleCheck = 0.0f; m_checkWeaponSwitch = true; m_checkKnifeSwitch = true; m_buyingFinished = false; m_radioEntity = null; m_radioOrder = 0; m_defendedBomb = false; m_timeLogoSpray = engine->GetTime () + engine->RandomFloat (0.5, 2.0f); m_spawnTime = engine->GetTime (); m_lastChatTime = engine->GetTime (); pev->v_angle.y = pev->ideal_yaw; m_timeCamping = 0; m_campDirection = 0; m_nextCampDirTime = 0; m_campButtons = 0; m_soundUpdateTime = 0.0f; m_heardSoundTime = engine->GetTime (); // clear its message queue for (i = 0; i < 32; i++) m_messageQueue[i] = CMENU_IDLE; m_actMessageIndex = 0; m_pushMessageIndex = 0; // and put buying into its message queue PushMessageQueue (CMENU_BUY); PushTask (TASK_NORMAL, TASKPRI_NORMAL, -1, 0.0, true); }
void NPC::CheckStuck(float oldSpeed) { if (!IsOnFloor(GetEntity()) || IsOnLadder (GetEntity ())) return; if (WalkMove()) return; if (m_checkStuckTime > gpGlobals->time) return; m_checkStuckTime = gpGlobals->time + 0.5f; bool isStuck = false; float moveDistance = GetDistance(pev->origin, m_prevOrigin); if (oldSpeed >= 10.0f && pev->speed >= 10.0f) { if (moveDistance <= 2.0f) isStuck = true; } if (isStuck) { MakeVectors(pev->angles); TraceResult tr; Vector dest = pev->origin; dest.z += 32; Vector src = pev->origin + gpGlobals->v_forward * 32; UTIL_TraceHull(dest, src, dont_ignore_monsters, head_hull, GetEntity(), &tr); if (tr.flFraction > 0.0f && tr.flFraction != 1.0f) { float newOriginZ = pev->origin.z + (tr.vecEndPos.z - GetBottomOrigin(GetEntity ()).z) - 32; if (newOriginZ > pev->origin.z && (newOriginZ - pev->origin.z) <= 32) { pev->velocity.z = (270.0f * pev->gravity) + 32.0f; m_jumpAction = false; goto end; } } for (int i = 0; i <= 18; i++) { UTIL_TraceHull(pev->origin, pev->origin, dont_ignore_monsters, human_hull, GetEntity(), &tr); if (!tr.fStartSolid && !tr.fAllSolid && tr.fInOpen) break; if (i == 17) { int block = MF_ExecuteForward(g_callStuck_Pre, (cell)ENTINDEX(GetEntity())); if (!block) { LogToFile("The NPC is stuck, remove now"); m_needRemove = true; } break; } pev->origin.z += 1; } m_goalWaypoint = -1; m_currentWaypointIndex = -1; DeleteSearchNodes(); } end: m_prevOrigin = pev->origin; }