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; } }
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 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); }
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 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); }
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); }
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); }
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); }
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 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); }
static EnemyType DetermineEnemyType(PTAMain world) { EnemyType result = EnemyType.Weak; // NOTE(SpectatorQL): If randomPoint equals 1 there's a chance that the following loop code will cause an off-by-one error. // It is extremely unlikely, because floating point precision is dumb enough to allow me to do this shit 99.999999% of the time. // But at some point in the future this thing WILL crash and I'll be extremely sad when it does. // That's also why I think I should use integers instead of floats for probability-based things and only // cast to float when absolutely necessary. // NOTE(SpectatorQL): Ok, so the thing is like this. .NET System.Random.NextDouble() function // will _NEVER_ return 1.0 but Unity Random.value property _CAN_ possibly return 1.0. // This the single most retarded thing I have encountered in programming up to this point in time {2019-08-20, 14:33}. float randomPoint = UnityEngine.Random.value; if (randomPoint == 1.0f) { randomPoint = 0.99999999999999978f; } // NOTE(SpectatorQL): Because Unity is dogshit. float[] enemyProb = world.EnemyProbability.Values; int enemyTypeCount = (int)EnemyType.Count; for (int i = 0; i < enemyTypeCount; ++i) { int index = world.WaveData.CurrentWave * enemyTypeCount + i; Debug.Assert(index < enemyProb.Length); if (randomPoint < enemyProb[index]) { result = (EnemyType)i; break; } else { randomPoint -= enemyProb[i]; } } Debug.Assert(result < EnemyType.Count); return(result); }
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; } } }
public static void ThinkStub(PTAMain world, PTAEntity entity, float dt) { }
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; }