void DetachEntitiesOnDeath(PTAMain world, PTAEntity entity) { // NOTE(SpectatorQL): I would really like to put these in a union and just loop through an array, but oh well. PTAEntity lTurret = Self.LTurretSlot; PTAEntity rTurret = Self.RTurretSlot; PTAEntity drive = Self.DriveSlot; if (lTurret != null) { PTAEntity.DetachEntity(lTurret); Self.LTurretSlot = null; DetermineEntityFate(world, lTurret); } if (rTurret != null) { PTAEntity.DetachEntity(rTurret); Self.RTurretSlot = null; DetermineEntityFate(world, rTurret); } if (drive != null) { PTAEntity.DetachEntity(drive); Self.DriveSlot = null; DetermineEntityFate(world, drive); } }
public static void HostileThink(PTAMain world, PTAEntity entity, float dt) { float timeToSpawn = entity.Data.TimeToSpawn; Color fadingEntityColor = entity.Renderer.material.color; if (timeToSpawn > 0) { if (fadingEntityColor.a < 0) { fadingEntityColor.a = 1.0f; } fadingEntityColor.a -= dt; entity.Renderer.material.color = fadingEntityColor; timeToSpawn -= dt; entity.Data.TimeToSpawn = timeToSpawn; if (timeToSpawn > 0) { return; } } else { fadingEntityColor.a = 1.0f; entity.Renderer.material.color = fadingEntityColor; entity.Collider.BoxCollider.enabled = true; entity.HasSpawned = true; } }
public static PTAEntity CreatePlayer(PTAMain world) { PTAEntity entity = GetFreeEntity(world); entity.GameObject.layer = PlayerLayer; entity.Transform.localScale = new Vector3(2.0f, 2.0f, 2.0f); entity.Transform.rotation = Quaternion.identity; entity.Renderer.material.color = Color.white; entity.Renderer.sprite = world.Sprites[(int)EntityType.Player]; entity.Data = new EntityData { Health = 1, AttackSpeed = 1.5f, MovementSpeed = 0.1f }; entity.Think = ThinkFunctions.PlayerThink; entity.EntityTypeID = EntityType.Player; entity.HasSpawned = true; return(entity); }
static PTAEntity CreateEntity(PTAMain world) { if (world.RunningEntityIndex >= PTAMain.ENTITY_COUNT) { Debug.LogError("PTAEntity limit reached!"); return(null); } PTAEntity entity = world.Entities[world.RunningEntityIndex]; GameObject entityObject = GameObject.Instantiate(world.EntityPrefab); entity.GameObject = entityObject; entity.Transform = entityObject.transform; entity.Rigidbody = entityObject.GetComponent <Rigidbody2D>(); entity.Renderer = entityObject.GetComponent <SpriteRenderer>(); entity.Collider = entityObject.GetComponent <PTACollider>(); entity.Collider.BoxCollider = entityObject.GetComponent <BoxCollider2D>(); entity.Collider.Self = entity; entity.Collider.World = world; entity.Move = MoveFunctions.MoveStub; entity.Think = ThinkFunctions.ThinkStub; entity.IsActive = true; entity.EntityID = (uint)world.RunningEntityIndex; ++world.RunningEntityIndex; return(entity); }
public static void SineMove(PTAEntity entity) { if (!entity.HasSpawned) { return; } entity.Rigidbody.velocity = Vector2.zero; Vector2 entityPosition = entity.Transform.position; Vector2 newPosition = entity.Transform.position; newPosition.x += entity.Data.MovementSpeed; float sineValue = Mathf.Sin(entity.Data.TSine); float sineRange = 0.10f; sineValue = Mathf.Clamp(sineValue, -sineRange, sineRange); newPosition.y += sineValue; entity.Rigidbody.MovePosition(newPosition); float rotationAngle = Mathf.Atan2(newPosition.y - entityPosition.y, newPosition.x - entityPosition.x) * Mathf.Rad2Deg; Vector3 eulers = entity.Transform.eulerAngles; eulers.z = rotationAngle; entity.Transform.eulerAngles = eulers; if (entity.Data.TSine > (2.0f * Mathf.PI)) { entity.Data.TSine -= (2.0f * Mathf.PI); } entity.Data.TSine += 0.15f; }
public static void AttachEntity(PTAEntity entity, PTAEntity newParent, Vector3 alignPoint) { entity.Collider.BoxCollider.enabled = false; entity.Transform.parent = newParent.Transform; alignPoint.x /= newParent.Transform.localScale.x; alignPoint.y /= newParent.Transform.localScale.y; entity.Transform.localPosition = alignPoint; entity.Transform.localRotation = Quaternion.identity; }
public static PTAEntity TurnIntoWildPowerup(PTAMain world, PTAEntity entity) { entity.Move = MoveFunctions.MoveStub; entity.Think = ThinkFunctions.WildPowerupThink; entity.EntityTypeID = EntityType.WildPowerup; entity.Data.Health = 1; entity.Data.MovementSpeed = 0.08f; return(entity); }
public static PTAEntity CreateDrivePowerup(PTAMain world) { PTAEntity entity = CreatePowerupInternal(world); PowerupType powerupType = PowerupType.Drive; entity.Renderer.sprite = world.PowerupSprites[(int)powerupType]; entity.PowerupTypeID = powerupType; return(entity); }
public static PTAEntity CreateEnemy(PTAMain world) { PTAEntity entity = GetFreeEntity(world); entity.GameObject.layer = ThingsLayer; entity.Transform.rotation = Quaternion.identity; entity.Transform.localScale = new Vector3(2.0f, 2.0f, 2.0f); EntityData entityData = new EntityData(); EnemyType enemyType = DetermineEnemyType(world); switch (enemyType) { case EnemyType.Weak: { entity.Renderer.material.color = Color.red; entityData.Health = 1; entityData.MovementSpeed = 0.08f; entityData.TimeToSpawn = 2.0f; break; } case EnemyType.Strong: { entity.Renderer.material.color = Color.yellow; entityData.Health = 2; entityData.MovementSpeed = 0.08f; entityData.TimeToSpawn = 2.0f; break; } case EnemyType.Uber: { entity.Renderer.material.color = Color.green; entityData.Health = 3; entityData.MovementSpeed = 0.08f; entityData.TimeToSpawn = 2.0f; break; } } entity.EnemyTypeID = enemyType; entity.Data = entityData; entity.EntityTypeID = EntityType.Enemy; entity.HasSpawned = true; entity.Renderer.sprite = world.Sprites[(int)EntityType.Enemy]; return(entity); }
// TODO(SpectatorQL): Is it necessary to split Move and Think? void FixedUpdate() { for (int i = 0; i < ENTITY_COUNT; ++i) { PTAEntity entity = Entities[i]; if (entity.IsActive) { entity.Move(entity); } } }
public static PTAEntity CreateFriendlyBullet(PTAMain world) { PTAEntity entity = CreateBulletInternal(world); entity.Move = MoveFunctions.LinearMove; entity.Think = ThinkFunctions.ThinkStub; entity.GameObject.layer = PlayerLayer; entity.Renderer.material.color = Color.white; entity.Data.MovementSpeed = 0.3f; return(entity); }
public PTAEntity GetNext() { PTAEntity result = null; if (Top != -1) { result = Entities[Top]; result.GameObject.SetActive(true); result.IsActive = true; Entities[Top] = null; --Top; } return(result); }
public void Add(PTAEntity entity) { if (entity == null) { return; } if (!entity.IsActive) { return; } entity.GameObject.SetActive(false); entity.IsActive = false; ++Top; Entities[Top] = entity; }
static PTAEntity CreateBulletInternal(PTAMain world) { PTAEntity entity = GetFreeEntity(world); entity.Transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); entity.Transform.rotation = Quaternion.identity; entity.Collider.BoxCollider.enabled = true; entity.EntityTypeID = EntityType.Bullet; entity.HasSpawned = true; entity.Renderer.sprite = world.Sprites[(int)EntityType.Bullet]; return(entity); }
public static void WildPowerupThink(PTAMain world, PTAEntity entity, float dt) { entity.Rigidbody.velocity = Vector2.zero; Vector2 entityPosition = entity.Transform.position; Vector2 direction = (Vector2)world.PlayerEntity.Transform.position - entityPosition; Vector2 newPosition = entityPosition + direction.normalized * entity.Data.MovementSpeed; entity.Rigidbody.MovePosition(newPosition); float rotationAngle = Mathf.Atan2(newPosition.y - entityPosition.y, newPosition.x - entityPosition.x) * Mathf.Rad2Deg; Vector3 eulers = entity.Transform.eulerAngles; eulers.z = rotationAngle; entity.Transform.eulerAngles = eulers; }
static PTAEntity GetFreeEntity(PTAMain world) { PTAEntity entity = world.FreeEntities.GetNext(); if (entity == null) { entity = CreateEntity(world); if (entity == null) { // TODO(SpectatorQL): Do _something_ when this happens. Debug.Assert(false, "__PANIC__"); return(null); } } return(entity); }
void OnCollisionEnter2D(Collision2D collision) { PTACollider collider = collision.gameObject.GetComponent <PTACollider>(); if (collider != null) { PTAEntity entity = collider.Self; if (entity.EntityTypeID == EntityType.Bullet) { World.FreeEntities.Add(entity); } else { float safetyNet = 0.25f; Vector2 oldPosition = collision.gameObject.transform.position; Vector2 newPosition = new Vector2(); if (WallTypeID == WallType.XWall) { if (oldPosition.x > 0) { newPosition.x = -(oldPosition.x - safetyNet); } else { newPosition.x = -(oldPosition.x + safetyNet); } newPosition.y = oldPosition.y; } else if (WallTypeID == WallType.YWall) { newPosition.x = oldPosition.x; if (transform.position.y > 0) { newPosition.y = -(oldPosition.y - safetyNet); } else { newPosition.y = -(oldPosition.y + safetyNet); } } collision.gameObject.transform.position = newPosition; } } }
static PTAEntity CreatePowerupInternal(PTAMain world) { PTAEntity entity = GetFreeEntity(world); entity.Transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); entity.Transform.rotation = Quaternion.identity; entity.Renderer.material.color = Color.white; entity.Move = MoveFunctions.MoveStub; entity.Think = ThinkFunctions.ThinkStub; entity.GameObject.layer = ThingsLayer; entity.EntityTypeID = EntityType.Powerup; entity.HasSpawned = true; return(entity); }
public static void LinearMove(PTAEntity entity) { if (!entity.HasSpawned) { return; } entity.Rigidbody.velocity = Vector2.zero; Vector2 entityPosition = entity.Transform.position; Vector2 newPosition = entityPosition + entity.Data.MoveDirection.normalized * entity.Data.MovementSpeed; entity.Rigidbody.MovePosition(newPosition); float rotationAngle = Mathf.Atan2(newPosition.y - entityPosition.y, newPosition.x - entityPosition.x) * Mathf.Rad2Deg; Vector3 eulers = entity.Transform.eulerAngles; eulers.z = rotationAngle; entity.Transform.eulerAngles = eulers; }
void DetermineEntityFate(PTAMain world, PTAEntity entity) { float spawnChance = Random.value; if (spawnChance < World.WaveData.PowerupStayChance) { World.FreeEntities.Add(entity); } else { spawnChance = Random.value; if (spawnChance < World.WaveData.WildPowerupSpawnChance) { World.FreeEntities.Add(entity); } else { PTAEntity.TurnIntoWildPowerup(World, entity); ++world.WaveData.WildPowerupCount; } } }
// NOTE(SpectatorQL): Some day I need to learn how to handle a mess like this... // Like, where does this code _actually_ belong? What should it _actually_ do? // Create messages for the world to process? Act immediately, like I do here? // Or maybe an entirely different approach is "the right thing to do"? void OnCollisionEnter2D(Collision2D collision) { PTACollider collider = collision.gameObject.GetComponent <PTACollider>(); if (collider != null) { PTAEntity other = collider.Self; if (Self.EntityTypeID == EntityType.Player) { if (other.EntityTypeID == EntityType.Powerup) { if (other.PowerupTypeID == PowerupType.Turret) { if (Self.LTurretSlot == null) { PTAEntity.AttachEntity(other, Self, World.EntityAlignment.Points.LTurretPosition); Self.LTurretSlot = other; --World.WaveData.PowerupCount; } else if (Self.RTurretSlot == null) { PTAEntity.AttachEntity(other, Self, World.EntityAlignment.Points.RTurretPosition); Self.RTurretSlot = other; --World.WaveData.PowerupCount; } } else if (other.PowerupTypeID == PowerupType.Drive) { if (Self.DriveSlot == null) { PTAEntity.AttachEntity(other, Self, World.EntityAlignment.Points.DrivePosition); Self.DriveSlot = other; --World.WaveData.PowerupCount; } } } else if (other.EntityTypeID == EntityType.Bullet) { World.FreeEntities.Add(other); --Self.Data.Health; if (Self.Data.Health == 0) { DetachEntitiesOnDeath(World, Self); World.FreeEntities.Add(Self); if (Self.EntityTypeID == EntityType.Enemy) { --World.WaveData.EnemyCount; --World.WaveData.EnemiesOnScreen; } } } else if (other.EntityTypeID == EntityType.Enemy) { if (!World.Cheats.Invincibility) { World.StartCoroutine(World.TemporaryInvincibility()); World.FreeEntities.Add(other); --Self.Data.Health; if (Self.Data.Health == 0) { World.FreeEntities.Add(Self.LTurretSlot); World.FreeEntities.Add(Self.RTurretSlot); World.FreeEntities.Add(Self.DriveSlot); World.FreeEntities.Add(Self); Debug.Log("Guess I'll die."); } } } else if (other.EntityTypeID == EntityType.WildPowerup) { if (!World.Cheats.Invincibility) { World.StartCoroutine(World.TemporaryInvincibility()); World.FreeEntities.Add(other); --Self.Data.Health; if (Self.Data.Health == 0) { World.FreeEntities.Add(Self.LTurretSlot); World.FreeEntities.Add(Self.RTurretSlot); World.FreeEntities.Add(Self.DriveSlot); World.FreeEntities.Add(Self); Debug.Log("Guess I'll die."); } } } } else if (Self.EntityTypeID == EntityType.Enemy) { if (other.EntityTypeID == EntityType.Powerup) { if (other.PowerupTypeID == PowerupType.Turret) { if (Self.LTurretSlot == null) { PTAEntity.AttachEntity(other, Self, World.EntityAlignment.Points.LTurretPosition); Self.LTurretSlot = other; --World.WaveData.PowerupCount; } else if (Self.RTurretSlot == null) { PTAEntity.AttachEntity(other, Self, World.EntityAlignment.Points.RTurretPosition); Self.RTurretSlot = other; --World.WaveData.PowerupCount; } } else if (other.PowerupTypeID == PowerupType.Drive) { if (Self.DriveSlot == null) { PTAEntity.AttachEntity(other, Self, World.EntityAlignment.Points.DrivePosition); Self.DriveSlot = other; --World.WaveData.PowerupCount; } } } else if (other.EntityTypeID == EntityType.Bullet) { World.FreeEntities.Add(other); --Self.Data.Health; if (Self.Data.Health == 0) { DetachEntitiesOnDeath(World, Self); World.FreeEntities.Add(Self); if (Self.EntityTypeID == EntityType.Enemy) { --World.WaveData.EnemyCount; --World.WaveData.EnemiesOnScreen; } } } else if (other.EntityTypeID == EntityType.Player) { --Self.Data.Health; if (Self.Data.Health == 0) { DetachEntitiesOnDeath(World, Self); World.FreeEntities.Add(Self); --World.WaveData.EnemyCount; --World.WaveData.EnemiesOnScreen; } } } else if (Self.EntityTypeID == EntityType.WildPowerup) { if (other.EntityTypeID == EntityType.Bullet) { World.FreeEntities.Add(other); --Self.Data.Health; if (Self.Data.Health == 0) { DetachEntitiesOnDeath(World, Self); --World.WaveData.WildPowerupCount; World.FreeEntities.Add(Self); } } else if (other.EntityTypeID == EntityType.Player) { --Self.Data.Health; if (Self.Data.Health == 0) { DetachEntitiesOnDeath(World, Self); --World.WaveData.WildPowerupCount; World.FreeEntities.Add(Self); } } } } }
public static void ThinkStub(PTAMain world, PTAEntity entity, float dt) { }
public static void DetachEntity(PTAEntity entity) { entity.Transform.parent = null; entity.Collider.BoxCollider.enabled = true; }
public static void PlayerThink(PTAMain world, PTAEntity entity, float dt) { // TODO(SpectatorQL): Android controls will be _very_ different from this. // TODO(SpectatorQL): Move input management out of here. float speed = entity.Data.MovementSpeed; Vector2 newPosition = entity.Transform.position; if (Input.GetKey(KeyCode.W)) { newPosition.y += speed; } if (Input.GetKey(KeyCode.S)) { newPosition.y -= speed; } if (Input.GetKey(KeyCode.A)) { newPosition.x -= speed; } if (Input.GetKey(KeyCode.D)) { newPosition.x += speed; } bool firing = false; if (Input.GetMouseButton(0)) { firing = true; } Vector3 mousePosition = Input.mousePosition; mousePosition.z = 10.0f; Vector3 worldMousePosition = Camera.main.ScreenToWorldPoint(mousePosition); float angle = Mathf.Atan2(worldMousePosition.y - newPosition.y, worldMousePosition.x - newPosition.x); angle = Mathf.Rad2Deg * angle; entity.Transform.position = newPosition; Quaternion newRotation = entity.Transform.rotation; newRotation.eulerAngles = new Vector3(0.0f, 0.0f, angle); entity.Transform.rotation = newRotation; float runningAttackSpeed = entity.Data.RunningAttackSpeed; if (firing) { if (runningAttackSpeed <= 0) { Vector2 fireDirection = worldMousePosition - entity.Transform.position; PTAEntity newBullet = PTAEntity.CreateFriendlyBullet(world); if (newBullet != null) { newBullet.Transform.position = entity.Transform.position; newBullet.Data.MoveDirection = fireDirection.normalized; } runningAttackSpeed = entity.Data.AttackSpeed; } } if (runningAttackSpeed > 0) { runningAttackSpeed -= dt; } entity.Data.RunningAttackSpeed = runningAttackSpeed; }
public static void MoveStub(PTAEntity entity) { entity.Rigidbody.velocity = Vector2.zero; }
void Start() { PTAEntity.PlayerLayer = LayerMask.NameToLayer("Player"); PTAEntity.ThingsLayer = LayerMask.NameToLayer("Things"); if (PTAEntity.PlayerLayer == -1 || PTAEntity.ThingsLayer == -1) { Debug.LogError("Layers are missing! Check the layers settings in Edit/Project Settings/Tags and Layers !"); } Vector2 bottomLeft = Camera.main.ScreenToWorldPoint(new Vector3(0, 0, 10)); Vector2 topRight = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 10)); float offscreenOffset = 1.0f; PlayArea.MinX = bottomLeft.x - offscreenOffset; PlayArea.MinY = bottomLeft.y - offscreenOffset; PlayArea.MaxX = topRight.x + offscreenOffset; PlayArea.MaxY = topRight.y + offscreenOffset; PlayArea.Center = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width / 2, Screen.height / 2, 10)); Vector2 xWallSize = new Vector2(1.0f, PlayArea.MaxY - PlayArea.MinY); Vector2 yWallSize = new Vector2(PlayArea.MaxX - PlayArea.MinX, 1.0f); const int WALL_COUNT = 2; for (WallType i = 0; i < WallType.Count; ++i) { for (int j = 0; j < WALL_COUNT; ++j) { PTAWall wall = Instantiate(WallPrefab).GetComponent <PTAWall>(); wall.World = this; wall.BoxCollider = wall.gameObject.GetComponent <BoxCollider2D>(); wall.WallTypeID = i; if (wall.WallTypeID == WallType.XWall) { wall.BoxCollider.size = xWallSize; } else if (wall.WallTypeID == WallType.YWall) { wall.BoxCollider.size = yWallSize; } if (j == 0) { if (wall.WallTypeID == WallType.XWall) { wall.transform.position = new Vector2(PlayArea.MinX, PlayArea.Center.y); } else if (wall.WallTypeID == WallType.YWall) { wall.transform.position = new Vector2(PlayArea.Center.x, PlayArea.MinY); } } else if (j == 1) { if (wall.WallTypeID == WallType.XWall) { wall.transform.position = new Vector2(PlayArea.MaxX, PlayArea.Center.y); } else if (wall.WallTypeID == WallType.YWall) { wall.transform.position = new Vector2(PlayArea.Center.x, PlayArea.MaxY); } } else { Debug.LogError($"Error! Too many walls of type {i} have been spawned!"); } } } Entities = new PTAEntity[ENTITY_COUNT]; for (int i = 0; i < ENTITY_COUNT; ++i) { Entities[i] = new PTAEntity(); } PlayerEntity = PTAEntity.CreatePlayer(this); #if UNITY_EDITOR PTAEntity turretL = PTAEntity.CreateTurretPowerup(this); turretL.Transform.position = GenerateEntityPosition(); ++WaveData.PowerupCount; PTAEntity turretR = PTAEntity.CreateTurretPowerup(this); turretR.Transform.position = GenerateEntityPosition(); ++WaveData.PowerupCount; PTAEntity freeTurret = PTAEntity.CreateTurretPowerup(this); freeTurret.Transform.position = GenerateEntityPosition(); ++WaveData.PowerupCount; PTAEntity drive = PTAEntity.CreateDrivePowerup(this); drive.Transform.position = GenerateEntityPosition(); ++WaveData.PowerupCount; #else Cheats.Invincibility = false; Cheats.RapidFire = false; #endif UI = FindObjectOfType <PTAUI>(); }
void Update() { float dt = Time.deltaTime; Debug.Assert(WaveData.EnemyCount >= 0); Debug.Assert(WaveData.EnemiesOnScreen >= 0); if (WaveData.EnemyCount > 0) { Debug.Assert(WaveData.EnemiesOnScreen <= WaveData.EnemyCount && WaveData.EnemiesOnScreen >= 0); while (WaveData.EnemiesOnScreen < WaveData.MaxSpawnedEnemiesOnScreen && WaveData.EnemiesOnScreen < WaveData.EnemyCount) { PTAEntity enemyEntity = PTAEntity.CreateEnemy(this); if (enemyEntity != null) { enemyEntity.HasSpawned = false; enemyEntity.Move = MoveFunctions.SineMove; enemyEntity.Data.MoveDirection = UnityEngine.Random.insideUnitCircle; enemyEntity.Think = ThinkFunctions.HostileThink; enemyEntity.Transform.position = GenerateEntityPosition(); enemyEntity.Collider.BoxCollider.enabled = false; } ++WaveData.EnemiesOnScreen; Debug.Assert(WaveData.EnemiesOnScreen <= WaveData.EnemyCount); Debug.Assert(WaveData.EnemiesOnScreen <= WaveData.MaxSpawnedEnemiesOnScreen); Debug.Assert(WaveData.EnemiesOnScreen == Entities.Count(ent => { return(ent.EntityTypeID == EntityType.Enemy && ent.IsActive); })); } } else { Debug.Assert(WaveData.WildPowerupCount >= 0); if (WaveData.WildPowerupCount == 0) { int nextWave = WaveData.CurrentWave + 1; if (nextWave < WaveData.MaxWave) { int newEnemyCount = nextWave; WaveData.EnemyCount = newEnemyCount; if (nextWave % 5 == 0 && WaveData.PowerupWaitTime > WaveData.MinPowerupWaitTime) { WaveData.PowerupWaitTime -= 0.5f; } UI.WaveText.text = $"Wave: {nextWave}"; WaveData.CurrentWave = nextWave; } else { // TODO(SpectatorQL): End screen. WaveData.EnemyCount = 0; Debug.Log("YOU WIN!!!"); } } } if (WaveData.PowerupCount < WaveData.MaxPowerupsOnScreen) { if (WaveData.RunningPowerupTime <= 0) { // NOTE(SpectatorQL): Oh, so this thing is _exclusive_ but the float version is _inclusive_. Gotta love Unity... PowerupType powerupType = (PowerupType)UnityEngine.Random.Range(0, (int)PowerupType.Count); Debug.Assert(powerupType < PowerupType.Count); PTAEntity powerupEntity = null; switch (powerupType) { case PowerupType.Turret: { powerupEntity = PTAEntity.CreateTurretPowerup(this); break; } case PowerupType.Drive: { powerupEntity = PTAEntity.CreateDrivePowerup(this); break; } } if (powerupEntity != null) { powerupEntity.Transform.position = GenerateEntityPosition(); } WaveData.RunningPowerupTime = WaveData.PowerupWaitTime; ++WaveData.PowerupCount; } } if (WaveData.RunningPowerupTime > 0) { WaveData.RunningPowerupTime -= dt; } if (Cheats.RapidFire) { PlayerEntity.Data.AttackSpeed = Cheats.RapidFireSpeed; } for (int i = 0; i < ENTITY_COUNT; ++i) { PTAEntity entity = Entities[i]; if (entity.IsActive) { entity.Think(this, entity, dt); } } }