override public void Fire() { if (m_bCanFire) { // Target position is the player's position Vector3 vTargetPos = m_goPlayer.transform.position; Vector3 vTargetFuture = Vector3.zero; Vector2 vTrajAdd = Vector3.zero; if (!m_bIsAngry) { // Plus where they'll be 15-20 frames from now (which is scarily accurate at these scales, btw :D) vTargetFuture = (m_gcGameInstance.GetPlayerTrajectory() * Random.Range(0.1f, 1f)) * (m_gcGameInstance.GetPlayerState().GetPlayerMovementSpeed() * Random.Range(0.1f, 1.0f)) * (Random.Range(0f, 15f) * TimerManager.fGameDeltaTime); if (Random.Range(1f, 100f) > 80f) { vTrajAdd = m_gcGameInstance.GetPlayerTrajectory(); } } else { vTargetFuture = m_gcGameInstance.GetPlayerTrajectory() * (20.0f * TimerManager.fGameDeltaTime); } // Add these together for some variance... vTargetPos += vTargetFuture; // * Random.Range(0.25f, 1.0f); // We have to call this ourselves as there's no behaviour on top of us constantly aiming... UpdateFireDirection(vTargetPos - transform.position); // Bullet spawn position is gun's position, plus a definable distance, offset in the direction of fire... Vector3 vSpawnPos = (transform.position + m_vGunPositionOffset) + (new Vector3(m_vFireDirection.x, m_vFireDirection.y, 0.0f) * m_fBulletSpawnOffset); // Bullet's speed needs to be inversely proportional to our distance from the player { Vector3 vDist = m_goPlayer.transform.position - transform.position; m_fThisBulletSpeed = Mathf.Clamp(Mathf.Abs(vDist.magnitude / Types.s_fEUGE_PlayerDistanceDivisor) * m_fMinBulletSpeed, m_fMinBulletSpeed, m_fBulletSpeed); } // Spawn the Spark // Note, because enforcers will be killed so quickly and sparks slide along the environment // we're not pooling these bullets. Player is very likely to kill the Enforcer before the bullet // gets going... { GameObject go = Instantiate(m_BulletPrefab, vSpawnPos, Quaternion.identity); BulletMovementSpark gc = go.GetComponent <BulletMovementSpark>(); if (!m_bIsAngry) { gc.SparkInitBullet(m_vFireDirection, vTrajAdd, m_fThisBulletSpeed, Random.Range(0.1f, m_fBulletSpeed / 2.0f)); } else { gc.SparkInitBullet(m_vFireDirection, vTrajAdd, m_fBulletSpeed, m_fBulletSpeed / 2.0f); } } // Set a timer for the next shot... (Assuming we're healthy) if (m_gcHealth.GetHitPointsRemaining() > 0) { m_iTimerHandle = TimerManager.AddTimer(m_fFiringPauseSeconds + Random.Range(-m_fFiringPauseSeconds, m_fFiringPauseSeconds), Fire); } else { m_iTimerHandle = 0; } } }
// Pay audio / effects, and return to the pool // virtual public void OnCollisionEnter2D(Collision2D collision) { if (m_bIsAlive) { // Now do some checks to see what we hit. { // Env always killed the bullet, no matter where it comes from if (collision.gameObject.CompareTag(Types.s_sTAG_Environment) || collision.gameObject.CompareTag(Types.s_sTAG_Doorway)) { m_iDamageRemaining = 0; } // Enemy Bullets always subtract from Damage Remaining else if (collision.gameObject.CompareTag(Types.s_sTag_EnemyBullets)) { m_iDamageRemaining = (int)MathUtil.Clamp(m_iDamageRemaining - 1, 0, Types.s_iPLAYER_MaxDamage); } // Enemies and destructible items should subtract their hitpoints else if (collision.gameObject.CompareTag(Types.s_sTag_Enemy) || collision.gameObject.CompareTag(Types.s_sTag_Destructible)) { // But... if we're a player bullet we also need to tell the Enemy how much damage we're doing! // Enemy bullets should just die on impact... if (!gameObject.CompareTag(Types.s_sTag_PlayerBullets)) { m_iDamageRemaining = 0; } else { TrackHitPoints gc = collision.gameObject.GetComponent <TrackHitPoints>(); if (null != gc) { int iHitPoints = gc.GetHitPointsRemaining(); int iDamageAfter = (int)MathUtil.Clamp(m_iDamageRemaining - iHitPoints, 0, Types.s_iPLAYER_MaxDamage); gc.DoOnImpactFromPlayer((uint)m_iDamageRemaining); m_iDamageRemaining = iDamageAfter; } // If an enemy doesn't have TrackHitPoints it's invulnerable, so kill this bullet else { m_iDamageRemaining = 0; } } } // Anything remaining is untagged, so kill the bullet just in case... else { m_iDamageRemaining = 0; } } // Die if we need to... if (m_iDamageRemaining == 0) { Vector3 vPos = new Vector3(collision.contacts[0].point.x, collision.contacts[0].point.y, Types.s_fPOS_FrontLayerZ); vPos += new Vector3(collision.contacts[0].normal.x, collision.contacts[0].normal.y, 0.0f) * Types.s_fPOS_ImpactEffectSpawnOffset; if (null != m_goImpactParticleEffect) { Instantiate(m_goImpactParticleEffect, vPos, Quaternion.identity); } GameInstance.Object.GetAudioManager().PlayAudioAtLocation(transform.position, m_iDespawnEffect); DeInitBullet(); } } }