using Godot; using System; public partial class player : Camera3D { private const string _path = "/root/player/"; [Export] private Label _con; [Export] private Label _mousePosLabel; [Export] private Label _cursorPosLabel; [Export] private RayCast3D _cursor; [Export] private Node3D _cursorPoint; private bool _mUp, _mDown, _mLeft, _mRight, _wIn, _wOut; private enum buildingType { kash, pr, nuke } [Export] private PackedScene _kash_building; [Export] private PackedScene _pr_building; [Export] private PackedScene _nuke_building; [Export] private TextureProgressBar _nuke, _pr, _kash; [Export] private Label _chatter, _timer, _pr_count, _nuke_count, _kash_count; [Export] private AudioStreamPlayer _sndChtr, _sndBtn; [Export] private Timer _tmrChtr, _tmrCashGen; [Export] private Button _btnEnd, _btnNukes, _btnPR, _btnKashCow; private float Nukes { get => (float)_nuke.Value; set => _nuke.Value = value; } private float PR { get => (float)_pr.Value; set => _pr.Value = value; } private float Kash { get => (float)_kash.Value; set => _kash.Value = value; } private int KashFlow { get; set; } = 1; private int GameTime { get; set; } = 60; private string Chatter { get => _chatter.Get("text").ToString(); set { if (value != "") _sndChtr.Play(); _chatter.Set("text", value); _tmrChtr.Start(); } } public base_building CurrentBuilding { get; set; } public override void _Ready() { _tmrChtr.Start(); _tmrChtr.Timeout += () => Chatter = ""; _tmrCashGen.Timeout += MakeMoney; _btnEnd.Pressed += () => _sndBtn.Play(); _btnNukes.Pressed += () => HandleBtnNuke(); _btnPR.Pressed += () => HandleBtnPR(); _btnKashCow.Pressed += () => HandleBtnKash(); Chatter = "The enemy is stockpiling weapons of mass destruction."; SetBarLabels(); } private void UnHandBuilding() { if (CurrentBuilding != null) { GetParent().RemoveChild(CurrentBuilding); CurrentBuilding.QueueFree(); CurrentBuilding = null; game_manager.CurrentState = game_manager.State.Play; } } private void InstantiateBuilding(buildingType type) { PackedScene toInstantiate = null; UnHandBuilding(); switch (type) { case buildingType.kash: toInstantiate = _kash_building; break; case buildingType.pr: toInstantiate = _pr_building; break; case buildingType.nuke: toInstantiate = _nuke_building; break; default: toInstantiate = _kash_building; break; } CurrentBuilding = toInstantiate.Instantiate(); this.GetParent().CallDeferred("add_child", CurrentBuilding); game_manager.CurrentState = game_manager.State.Building; } private void HandleBtnNuke() { _sndBtn.Play(); InstantiateBuilding(buildingType.nuke); } private void HandleBtnPR() { _sndBtn.Play(); InstantiateBuilding(buildingType.pr); } private void HandleBtnKash() { _sndBtn.Play(); InstantiateBuilding(buildingType.kash); } public override void _Process(double delta) { Vector3 rot = this.Rotation; bool zin = true, zout = true; if (Input.IsActionPressed("CamNorth")) _mUp = true; if (Input.IsActionPressed("CamSouth")) _mDown = true; if (Input.IsActionPressed("CamEast")) _mRight = true; if (Input.IsActionPressed("CamWest")) _mLeft = true; this.Rotation -= rot; if (this.Position.Y < 5) zin = false; else if (this.Position.Y > 45) zout = false; if (_mLeft && this.Position.X > -30) this.Translate(new Vector3((float)-delta * 10, 0, 0)); if (_mRight && this.Position.X < 30) this.Translate(new Vector3((float)delta * 10, 0, 0)); if (_mUp && this.Position.Z > -25) this.Translate(new Vector3(0, 0, (float)-delta * 10)); if (_mDown && this.Position.Z < 25) this.Translate(new Vector3(0, 0, (float)delta * 10)); this.Rotation += rot; if (_wIn && zin) this.Translate(new Vector3(0, 0, (float)-delta * 10)); if (_wOut && zout) this.Translate(new Vector3(0, 0, (float)delta * 10)); _con.Set("text", this.Position); if (_cursor != null && _cursorPoint != null) { //Get the collision with map and change its X and Z value to always be in the center of a tile Vector3I collisionVector = (Vector3I)_cursor.GetCollisionPoint(); _cursorPosLabel.Text = "Virtual Cursor Postion" + collisionVector.ToString(); _cursorPoint.GlobalPosition = new Vector3(collisionVector.X - collisionVector.X % 2, 1.1f, collisionVector.Z - collisionVector.Z % 2); if (game_manager.CurrentState == game_manager.State.Building) HandleBuilding(); } } public override void _Input(InputEvent @event) { _mLeft = _mRight = _mUp = _mDown = _wIn = _wOut = false; if (@event is InputEventMouseMotion mouse) { Vector2 vec = mouse.Position; if (vec.X < 5) _mLeft = true; else if (vec.X > 1915) _mRight = true; if (vec.Y < 20) _mUp = true; else if (vec.Y > 1060) _mDown = true; _mousePosLabel.Text = "Mouse position: " + vec.ToString(); _cursor.Position = new Vector3( (vec.X - GetViewport().GetVisibleRect().Size.X / 2) * this.Position.Y / 1000, -((vec.Y - GetViewport().GetVisibleRect().Size.Y / 2) * this.Position.Y / 1000) , 0 ); } else if (@event is InputEventMouseButton mousebtn) { if (mousebtn.ButtonIndex == MouseButton.WheelUp) _wIn = true; else if (mousebtn.ButtonIndex == MouseButton.WheelDown) _wOut = true; } } private void CheckGame() { bool gameover = false; if (PR <= 0) gameover = true; else if (Nukes >= 100) { _btnEnd.Disabled = false; _btnEnd.Pressed += () => { _sndBtn.Play(); Nuke(); }; } if (GameTime <= 0) gameover = true; if (gameover) Chatter = "Game Over."; } public void BuildBuilding(int price, int pr, int nukes, int kashFlow = 0) { if (price > Kash) { Chatter = "Not enough money."; CheckGame(); return; } Nukes += nukes; PR += pr; Kash -= price; KashFlow += kashFlow; base_building tempBuilding = (base_building)CurrentBuilding.Duplicate(); GetParent().CallDeferred("add_child", tempBuilding); game_manager.CurrentState = game_manager.State.Play; SetBarLabels(); CheckGame(); } private void MakeMoney() { Kash += KashFlow; GameTime--; _timer.Set("text", GameTime.ToString()); SetBarLabels(); CheckGame(); } private void SetBarLabels() { _kash_count.Text = $"{Kash}M$({KashFlow}M$/s)"; _nuke_count.Text = $"{Nukes} Megatons"; _pr_count.Text = $"{PR}(%) Approval"; } public void HandleBuilding() { if (CurrentBuilding != null) { CurrentBuilding.GlobalPosition = _cursorPoint.GlobalPosition; if (Input.IsActionJustPressed("rotate")) { CurrentBuilding.RotateY(Mathf.DegToRad(90)); } if (Input.IsActionJustPressed("cancel")) { UnHandBuilding(); } if (Input.IsActionJustPressed("build")) { if (CurrentBuilding.IsPlaceable) { switch (CurrentBuilding.DisplayName) { case "Radio Tower": propaganda_building radio = (propaganda_building)CurrentBuilding; BuildBuilding(radio.KashCost, radio.Approval, 0); break; case "Nuke Silo": arms_building silo = (arms_building)CurrentBuilding; BuildBuilding(silo.KashCost, silo.Approval, silo.Megaton); break; case "Factory": kash_building factory = (kash_building)CurrentBuilding; BuildBuilding(factory.KashCost, 0, 0, factory.KashGenPerSec); break; default: break; } } } } } public void Nuke() { var scene = GD.Load("res://endings/mad.tscn"); var instance = scene.Instantiate(); GetNode("/root/").AddChild(instance); this.GetParent().QueueFree(); } }