/* <8ea25> ../cstrike/dlls/func_tank.cpp:177 */ void CFuncTank::__MAKE_VHOOK(Spawn)(void) { Precache(); // so it doesn't get pushed by anything pev->movetype = MOVETYPE_PUSH; pev->solid = SOLID_BSP; SET_MODEL(ENT(pev), STRING(pev->model)); m_yawCenter = pev->angles.y; m_pitchCenter = pev->angles.x; if (IsActive()) { pev->nextthink = pev->ltime + 1.0; } // Point at the end of the barrel m_sightOrigin = BarrelPosition(); if (m_fireRate <= 0) m_fireRate = 1; if (m_spread > MAX_FIRING_SPREADS) m_spread = 0; pev->oldorigin = pev->origin; }
void CFuncTank::ControllerPostFrame(void) { ASSERT(m_pController != NULL); if (gpGlobals->time < m_flNextAttack) return; if (m_pController&&m_pController->pev->button & IN_ATTACK) { Vector vecForward; UTIL_MakeVectorsPrivate(pev->angles, vecForward, NULL, NULL); m_fireLast = gpGlobals->time - (1 / m_fireRate) - 0.01; Fire(BarrelPosition(), vecForward, m_pController->pev); if (m_pController && m_pController->IsPlayer()) ((CBasePlayer *)m_pController)->m_iWeaponVolume = LOUD_GUN_VOLUME; m_flNextAttack = gpGlobals->time + (1 / m_fireRate); } }
// Called each frame by the player's ItemPostFrame void CFuncTank::ControllerPostFrame( void ) { ASSERT( m_pController != NULL ); if( gpGlobals->time < m_flNextAttack ) return; if( m_pController->pev->button & IN_ATTACK ) { Vector vecForward; UTIL_MakeVectorsPrivate( pev->angles, vecForward, NULL, NULL ); m_fireLast = gpGlobals->time - ( 1 / m_fireRate ) - 0.01; // to make sure the gun doesn't fire too many bullets Fire( BarrelPosition(), vecForward, m_pController->pev ); // HACKHACK -- make some noise (that the AI can hear) if( m_pController && m_pController->IsPlayer() ) ( ( CBasePlayer * ) m_pController )->m_iWeaponVolume = LOUD_GUN_VOLUME; m_flNextAttack = gpGlobals->time + ( 1 / m_fireRate ); } }
void CFuncTank::Spawn(void) { Precache(); pev->movetype = MOVETYPE_PUSH; pev->solid = SOLID_BSP; SET_MODEL(ENT(pev), STRING(pev->model)); m_yawCenter = pev->angles.y; m_pitchCenter = pev->angles.x; if (IsActive()) pev->nextthink = pev->ltime + 1; m_sightOrigin = BarrelPosition(); if (m_fireRate <= 0) m_fireRate = 1; if (m_spread > (int)(MAX_FIRING_SPREADS)) m_spread = 0; pev->oldorigin = pev->origin; }
/* <8efe4> ../cstrike/dlls/func_tank.cpp:488 */ void CFuncTank::TrackTarget(void) { TraceResult tr; edict_t *pPlayer = FIND_CLIENT_IN_PVS(edict()); BOOL updateTime = FALSE, lineOfSight; Vector angles, direction, targetPosition, barrelEnd; edict_t *pTarget = NULL; // Get a position to aim for if (m_pController != NULL) { // Tanks attempt to mirror the player's angles angles = m_pController->pev->v_angle; angles.x = 0 - angles.x; pev->nextthink = pev->ltime + 0.05; } else { if (IsActive()) pev->nextthink = pev->ltime + 0.1; else return; if (FNullEnt(pPlayer)) { if (IsActive()) { // Wait 2 secs pev->nextthink = pev->ltime + 2; } return; } pTarget = FindTarget(pPlayer); if (!pTarget) { return; } // Calculate angle needed to aim at target barrelEnd = BarrelPosition(); targetPosition = pTarget->v.origin + pTarget->v.view_ofs; float range = (targetPosition - barrelEnd).Length(); if (!InRange(range)) return; UTIL_TraceLine(barrelEnd, targetPosition, dont_ignore_monsters, edict(), &tr); lineOfSight = FALSE; // No line of sight, don't track if (tr.flFraction == 1.0f || tr.pHit == pTarget) { lineOfSight = TRUE; CBaseEntity *pInstance = CBaseEntity::Instance(pTarget); if (InRange(range) && pInstance && pInstance->IsAlive()) { updateTime = TRUE; m_sightOrigin = UpdateTargetPosition(pInstance); } } // Track sight origin // !!! I'm not sure what i changed direction = m_sightOrigin - pev->origin; //direction = m_sightOrigin - barrelEnd; angles = UTIL_VecToAngles(direction); // Calculate the additional rotation to point the end of the barrel at the target (not the gun's center) AdjustAnglesForBarrel(angles, direction.Length()); } angles.x = -angles.x; // Force the angles to be relative to the center position angles.y = m_yawCenter + UTIL_AngleDistance(angles.y, m_yawCenter); angles.x = m_pitchCenter + UTIL_AngleDistance(angles.x, m_pitchCenter); // Limit against range in y if (angles.y > m_yawCenter + m_yawRange) { angles.y = m_yawCenter + m_yawRange; // Don't update if you saw the player, but out of range updateTime = FALSE; } else if (angles.y < (m_yawCenter - m_yawRange)) { angles.y = (m_yawCenter - m_yawRange); // Don't update if you saw the player, but out of range updateTime = FALSE; } if (updateTime) { m_lastSightTime = gpGlobals->time; } // Move toward target at rate or less float_precision distY = UTIL_AngleDistance(angles.y, pev->angles.y); pev->avelocity.y = distY * 10; if (pev->avelocity.y > m_yawRate) { pev->avelocity.y = m_yawRate; } else if (pev->avelocity.y < -m_yawRate) { pev->avelocity.y = -m_yawRate; } // Limit against range in x if (angles.x > m_pitchCenter + m_pitchRange) { angles.x = m_pitchCenter + m_pitchRange; } else if (angles.x < m_pitchCenter - m_pitchRange) { angles.x = m_pitchCenter - m_pitchRange; } // Move toward target at rate or less float_precision distX = UTIL_AngleDistance(angles.x, pev->angles.x); pev->avelocity.x = distX * 10; if (pev->avelocity.x > m_pitchRate) { pev->avelocity.x = m_pitchRate; } else if (pev->avelocity.x < -m_pitchRate) { pev->avelocity.x = -m_pitchRate; } if (m_pController != NULL) { return; } if (CanFire() && ((fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (pev->spawnflags & SF_TANK_LINEOFSIGHT))) { BOOL fire = FALSE; Vector forward; UTIL_MakeVectorsPrivate(pev->angles, forward, NULL, NULL); if (pev->spawnflags & SF_TANK_LINEOFSIGHT) { float length = direction.Length(); UTIL_TraceLine(barrelEnd, barrelEnd + forward * length, dont_ignore_monsters, edict(), &tr); if (tr.pHit == pTarget) { fire = TRUE; } } else fire = TRUE; if (fire) { Fire(BarrelPosition(), forward, pev); } else m_fireLast = 0; } else m_fireLast = 0; }
void CFuncTank::TrackTarget(void) { TraceResult tr; edict_t *pPlayer = FIND_CLIENT_IN_PVS(edict()); BOOL updateTime = FALSE, lineOfSight; Vector angles, direction, targetPosition, barrelEnd; edict_t *pTarget = NULL; if (m_pController) { angles = m_pController->pev->v_angle; angles[0] = 0 - angles[0]; pev->nextthink = pev->ltime + 0.05; } else { if (IsActive()) pev->nextthink = pev->ltime + 0.1; else return; if (FNullEnt(pPlayer)) { if (IsActive()) pev->nextthink = pev->ltime + 2; return; } pTarget = FindTarget(pPlayer); if (!pTarget) return; barrelEnd = BarrelPosition(); targetPosition = pTarget->v.origin + pTarget->v.view_ofs; float range = (targetPosition - barrelEnd).Length(); if (!InRange(range)) return; UTIL_TraceLine(barrelEnd, targetPosition, dont_ignore_monsters, edict(), &tr); lineOfSight = FALSE; if (tr.flFraction == 1 || tr.pHit == pTarget) { lineOfSight = TRUE; CBaseEntity *pInstance = CBaseEntity::Instance(pTarget); if (InRange(range) && pInstance && pInstance->IsAlive()) { updateTime = TRUE; m_sightOrigin = UpdateTargetPosition(pInstance); } } direction = m_sightOrigin - pev->origin; angles = UTIL_VecToAngles(direction); AdjustAnglesForBarrel(angles, direction.Length()); } angles.x = -angles.x; angles.y = m_yawCenter + UTIL_AngleDistance(angles.y, m_yawCenter); angles.x = m_pitchCenter + UTIL_AngleDistance(angles.x, m_pitchCenter); if (angles.y > m_yawCenter + m_yawRange) { angles.y = m_yawCenter + m_yawRange; updateTime = FALSE; } else if (angles.y < (m_yawCenter - m_yawRange)) { angles.y = (m_yawCenter - m_yawRange); updateTime = FALSE; } if (updateTime) m_lastSightTime = gpGlobals->time; float distY = UTIL_AngleDistance(angles.y, pev->angles.y); pev->avelocity.y = distY * 10; if (pev->avelocity.y > m_yawRate) pev->avelocity.y = m_yawRate; else if (pev->avelocity.y < -m_yawRate) pev->avelocity.y = -m_yawRate; if (angles.x > m_pitchCenter + m_pitchRange) angles.x = m_pitchCenter + m_pitchRange; else if (angles.x < m_pitchCenter - m_pitchRange) angles.x = m_pitchCenter - m_pitchRange; float distX = UTIL_AngleDistance(angles.x, pev->angles.x); pev->avelocity.x = distX * 10; if (pev->avelocity.x > m_pitchRate) pev->avelocity.x = m_pitchRate; else if (pev->avelocity.x < -m_pitchRate) pev->avelocity.x = -m_pitchRate; if (m_pController) return; if (CanFire() && ((fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (pev->spawnflags & SF_TANK_LINEOFSIGHT))) { BOOL fire = FALSE; Vector forward; UTIL_MakeVectorsPrivate(pev->angles, forward, NULL, NULL); if (pev->spawnflags & SF_TANK_LINEOFSIGHT) { float length = direction.Length(); UTIL_TraceLine(barrelEnd, barrelEnd + forward * length, dont_ignore_monsters, edict(), &tr); if (tr.pHit == pTarget) fire = TRUE; } else fire = TRUE; if (fire) Fire(BarrelPosition(), forward, pev); else m_fireLast = 0; } else m_fireLast = 0; }