using Godot; using System; public partial class IQEnemy : CharacterBody2D { // Misc float GlobalTimer; Node2D VAH; // Shorthand refrence // Enemy Stats public int IQ; public float HP; public float MaxHP; float RegenerationAmmount; float RegenerationInterval; float WalkSpeed; float JumpHeight; // Enemy Conditions float CurrentYVelocity; float PreviousYVelocity; bool GroundDetected; bool LedgeDetected; bool WallDetected; String FacingDirection; // Enemy Abilities bool AbilityJump = false; bool AbilityMove = false; bool AbilityAttack = false; bool AbilityDash = false; bool AbilityCloak = false; bool AbilityTeleport = false; bool AbilityRegenerate = false; public override void _Ready() { // Read & Set Abilities if (HasMeta("AbilityJump")) AbilityJump = (bool)GetMeta("AbilityJump"); if (HasMeta("AbilityMove")) AbilityMove = (bool)GetMeta("AbilityMove"); if (HasMeta("AbilityAttack")) AbilityAttack = (bool)GetMeta("AbilityAttack"); if (HasMeta("AbilityDash")) AbilityDash = (bool)GetMeta("AbilityDash"); if (HasMeta("AbilityCloak")) AbilityCloak = (bool)GetMeta("AbilityCloak"); if (HasMeta("AbilityTeleport")) AbilityTeleport = (bool)GetMeta("AbilityTeleport"); if (HasMeta("AbilityRegenerate")) AbilityRegenerate = (bool)GetMeta("AbilityRegenerate"); if (HasMeta("RegenerationAmmount")) RegenerationAmmount = (float)GetMeta("RegenerationAmmount"); else RegenerationAmmount = 1.0f; if (HasMeta("RegenerationInterval")) RegenerationInterval = (float)GetMeta("RegenerationInterval"); else RegenerationInterval = 1.0f; if (HasMeta("WalkSpeed")) WalkSpeed = (float)GetMeta("WalkSpeed"); else WalkSpeed = 20.0f; if (HasMeta("JumpHeight")) JumpHeight = (float)GetMeta("JumpHeight"); else JumpHeight = 250.0f; JumpHeight *= -1; // Read and set stats if (HasMeta("MaxHP")) MaxHP = (float)GetMeta("MaxHP"); FacingDirection = "RIGHT"; VAH = GetNode("VisualsAndHitboxes"); // Set up collision detection VAH.GetNode("GroundDetector").BodyEntered += OnGroundEntered; // Ground VAH.GetNode("GroundDetector").BodyExited += OnGroundExited; VAH.GetNode("LedgeDetector").BodyEntered += OnLedgeEntered; // Ledge VAH.GetNode("LedgeDetector").BodyExited += OnLedgeExited; VAH.GetNode("WallDetector").BodyEntered += OnWallEntered; // Wall VAH.GetNode("WallDetector").BodyExited += OnWallExited; GroundDetected = false; LedgeDetected = false; WallDetected = false; // Apply IQ based permenant modifiers IQ = (int)GetMeta("IQ"); // Read IQ if (IQ >= 100) MaxHP += 20; HP = MaxHP; if (IQ >= 100 && HasMeta("RegenerationInterval")) RegenerationInterval *= 0.9f; if (IQ >= 100 && HasMeta("RegenerationAmmount")) RegenerationAmmount *= 1.05f; // 5% increase WalkSpeed += IQ / 10; JumpHeight += IQ / 15; } public override void _PhysicsProcess(double delta) { // Update Timer GlobalTimer = GetTree().Root.GetNode("CommonData").GlobalTimer; // Show current hp for testing purposes if (HasMeta("CurrentHP")) SetMeta("CurrentHP", HP); // Regenerate Health if (AbilityRegenerate){ if (GlobalTimer % RegenerationInterval == 0){Regenerate(RegenerationAmmount);} } // Movement // Add gravity. if (GroundDetected == false){Velocity = new Vector2(Velocity[0],Velocity[1] + 10);} #region 20IQ if (IQ >= 0 && IQ <= 20){ // Goomba ahh diddy blud if (GroundDetected && LedgeDetected == false){Flip();} // Flip when presented with a ledge if (WallDetected){Flip();} // Flip when comeing in contact with a wall if (GroundDetected){Velocity = new Vector2(WalkSpeed * VAH.Scale[0], Velocity[1]);} // Walk } #endregion #region 30IQ if (IQ > 20 && IQ <= 30){ // Goomba w/ hopps (no judy) Velocity = new Vector2(WalkSpeed * VAH.Scale[0], Velocity[1]); // Walk if (WallDetected && GroundDetected && Velocity[1] == 0){Velocity = new Vector2(Velocity[0], JumpHeight);} // Jump if (WallDetected && GroundDetected && Velocity[1] > 0){Flip();} // Wall too high } #endregion #region 40IQ if (IQ > 30 && IQ <= 40){ // Adds jumping when reaching edge as feature (also adding directional x force) if (GroundDetected){Velocity = new Vector2(WalkSpeed * VAH.Scale[0], Velocity[1]);} // Walk on ground else{Velocity = new Vector2(WalkSpeed * VAH.Scale[0] * 2, Velocity[1]);} // Walk on air if (WallDetected && GroundDetected && Velocity[1] == 0){Velocity = new Vector2(Velocity[0], JumpHeight);} // Jump //if (GroundDetected && LedgeDetected == false && Velocity[1] == 0){Velocity = new Vector2(Velocity[0] * 50, JumpHeight);} // Jump at ledge if (GroundDetected && LedgeDetected == false && Velocity[1] == 0){Velocity = new Vector2(Velocity[0], JumpHeight);} // Jump at ledge if (WallDetected && GroundDetected && Velocity[1] > 0){Flip();} // Wall too high } #endregion #region 60IQ if (IQ > 40 && IQ <= 60){ // Concious of what side of the enemy the player is on var CurrentLevel = GetTree().Root.GetChildren(); float DistanceFromPlayerX = GlobalPosition[0] - CurrentLevel[2].GetNode("Player").GlobalPosition[0]; if (DistanceFromPlayerX > (30.0f / (IQ / 4))){ if (VAH.Scale[0] > 0){Flip();}} // left of player if (DistanceFromPlayerX < (-30.0f / (IQ / 4))){ if (VAH.Scale[0] < 0){Flip();}} // right of player if (DistanceFromPlayerX < (-30.0f / (IQ / 4)) && GroundDetected && GlobalPosition[0] > CurrentLevel[2].GetNode("Player").GlobalPosition[1]) {Velocity = new Vector2(Velocity[0], JumpHeight);} // Jump when player is overhead if (GroundDetected){Velocity = new Vector2(WalkSpeed * VAH.Scale[0], Velocity[1]);} // Walk on ground else{Velocity = new Vector2(WalkSpeed * VAH.Scale[0] * 2, Velocity[1]);} // Walk on air if (WallDetected && GroundDetected && Velocity[1] == 0){Velocity = new Vector2(Velocity[0], JumpHeight);} // Jump //if (GroundDetected && LedgeDetected == false && Velocity[1] == 0){Velocity = new Vector2(Velocity[0] * 50, JumpHeight);} // Jump at ledge if (GroundDetected && LedgeDetected == false && Velocity[1] == 0){Velocity = new Vector2(Velocity[0], JumpHeight);} // Jump at ledge } #endregion #region 80IQ if (IQ > 60 && IQ <= 80){ // Maintan distance to avoid melee attacks and optimise ranged attacks } #endregion #region 1000IQ if (IQ > 80 && IQ <= 100){ // Basic Pathfinding } #endregion #region 120IQ if (IQ > 100 && IQ <= 120){ // Advanced Pathfindinhg } #endregion #region 140IQ if (IQ > 120 && IQ <= 140){ // Advanced movement options } #endregion MoveAndSlide(); // Updates physics applied this frame } void Flip(){ VAH.Scale = new Vector2(-1 * VAH.Scale[0],1); WallDetected = false; LedgeDetected = true; if (FacingDirection == "RIGHT"){FacingDirection = "LEFT";} else if (FacingDirection == "LEFT"){FacingDirection = "RIGHT";} } public void Regenerate(float ammount){ if (HP < MaxHP) HP += ammount; if (HP > MaxHP) HP = MaxHP; // Catch errors } public void Damage(float ammount){ HP -= ammount; if (HP <= 0) Kill(); } public void Kill(){ QueueFree(); // Change to proper death w/ corpse } // Ground Detection public void OnGroundEntered(Node2D body){if (body is TileMapLayer tileLayer) GroundDetected = true;} public void OnGroundExited(Node2D body){if (body is TileMapLayer tileLayer) GroundDetected = false;} // Ledge Detection public void OnLedgeEntered(Node2D body){if (body is TileMapLayer tileLayer) LedgeDetected = true;} public void OnLedgeExited(Node2D body){if (body is TileMapLayer tileLayer) LedgeDetected = false;} // Wall Detection public void OnWallEntered(Node2D body){if (body is TileMapLayer tileLayer) WallDetected = true;} public void OnWallExited(Node2D body){if (body is TileMapLayer tileLayer) WallDetected = false;} }