diff --git a/Assets/Sprites/Ships/health-green.png b/Assets/Sprites/Ships/health-green.png new file mode 100644 index 0000000..7835d22 Binary files /dev/null and b/Assets/Sprites/Ships/health-green.png differ diff --git a/Assets/Sprites/Ships/health-green.png.import b/Assets/Sprites/Ships/health-green.png.import new file mode 100644 index 0000000..fe4841b --- /dev/null +++ b/Assets/Sprites/Ships/health-green.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/health-green.png-4731e1654f1cf6585b81aadbc26e806d.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Ships/health-green.png" +dest_files=[ "res://.import/health-green.png-4731e1654f1cf6585b81aadbc26e806d.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Assets/Sprites/Ships/health-grey.png b/Assets/Sprites/Ships/health-grey.png new file mode 100644 index 0000000..ab07955 Binary files /dev/null and b/Assets/Sprites/Ships/health-grey.png differ diff --git a/Assets/Sprites/Ships/health-grey.png.import b/Assets/Sprites/Ships/health-grey.png.import new file mode 100644 index 0000000..95bf377 --- /dev/null +++ b/Assets/Sprites/Ships/health-grey.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/health-grey.png-bcba478fd3fed9f2f17f792a3d16b360.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Ships/health-grey.png" +dest_files=[ "res://.import/health-grey.png-bcba478fd3fed9f2f17f792a3d16b360.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Assets/Sprites/Ships/health-orange.png b/Assets/Sprites/Ships/health-orange.png new file mode 100644 index 0000000..cea2299 Binary files /dev/null and b/Assets/Sprites/Ships/health-orange.png differ diff --git a/Assets/Sprites/Ships/health-orange.png.import b/Assets/Sprites/Ships/health-orange.png.import new file mode 100644 index 0000000..ac286ed --- /dev/null +++ b/Assets/Sprites/Ships/health-orange.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/health-orange.png-9990d8299172b15be0a3789a8754974f.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Ships/health-orange.png" +dest_files=[ "res://.import/health-orange.png-9990d8299172b15be0a3789a8754974f.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Assets/Sprites/Ships/health-red.png b/Assets/Sprites/Ships/health-red.png new file mode 100644 index 0000000..a65a56f Binary files /dev/null and b/Assets/Sprites/Ships/health-red.png differ diff --git a/Assets/Sprites/Ships/health-red.png.import b/Assets/Sprites/Ships/health-red.png.import new file mode 100644 index 0000000..0180206 --- /dev/null +++ b/Assets/Sprites/Ships/health-red.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/health-red.png-72789e525e79317dc633a787c0acebda.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Ships/health-red.png" +dest_files=[ "res://.import/health-red.png-72789e525e79317dc633a787c0acebda.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Assets/Sprites/Ships/health.xcf b/Assets/Sprites/Ships/health.xcf new file mode 100644 index 0000000..1d8d625 Binary files /dev/null and b/Assets/Sprites/Ships/health.xcf differ diff --git a/Assets/Sprites/Ships/spaceship_spritesheet.png b/Assets/Sprites/Ships/spaceship_spritesheet.png new file mode 100644 index 0000000..cd8ecb8 Binary files /dev/null and b/Assets/Sprites/Ships/spaceship_spritesheet.png differ diff --git a/Assets/Sprites/Ships/spaceship_spritesheet.png.import b/Assets/Sprites/Ships/spaceship_spritesheet.png.import new file mode 100644 index 0000000..2d58c25 --- /dev/null +++ b/Assets/Sprites/Ships/spaceship_spritesheet.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/spaceship_spritesheet.png-2d89419fd5f7955dfd129b3f651af4b1.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Ships/spaceship_spritesheet.png" +dest_files=[ "res://.import/spaceship_spritesheet.png-2d89419fd5f7955dfd129b3f651af4b1.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Assets/Sprites/Ships/thrust_spritesheet.png b/Assets/Sprites/Ships/thrust_spritesheet.png new file mode 100644 index 0000000..421bac5 Binary files /dev/null and b/Assets/Sprites/Ships/thrust_spritesheet.png differ diff --git a/Assets/Sprites/Ships/thrust_spritesheet.png.import b/Assets/Sprites/Ships/thrust_spritesheet.png.import new file mode 100644 index 0000000..d210ad6 --- /dev/null +++ b/Assets/Sprites/Ships/thrust_spritesheet.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/thrust_spritesheet.png-45d215604095befdeadc8cf1e1567aa9.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Ships/thrust_spritesheet.png" +dest_files=[ "res://.import/thrust_spritesheet.png-45d215604095befdeadc8cf1e1567aa9.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/Networking/ServerConnection.cs b/Networking/ServerConnection.cs index 7c6c3be..daab57f 100644 --- a/Networking/ServerConnection.cs +++ b/Networking/ServerConnection.cs @@ -34,237 +34,237 @@ public class ServerConnection : Node public override void _Ready() { - MyGame = GetNode("/root/Game"); - _serilogger = MyGame._serilogger; - - // TODO: move config to its own method - var clientConfig = new ConfigFile(); - Godot.Error err; - - _serilogger.Debug("ServerConnection.cs: Attempting to load embedded client config"); - err = clientConfig.Load("res://Resources/client.cfg"); - if (err == Godot.Error.Ok) - { - _serilogger.Information("ServerConnection.cs: Successfully loaded the config from 'res://Resources/client.cfg'"); - url = (String)clientConfig.GetValue("amqp", "server_string", "amqp://127.0.0.1:5672"); - _serilogger.Debug("ServerConnection.cs: config file: setting url to " + url); - disableCertValidation = (bool)clientConfig.GetValue("amqp", "disable_cert_validation", true); - _serilogger.Debug("ServerConnection.cs: config file: setting cert validation to " + disableCertValidation); - } - - _serilogger.Debug("ServerConnection.cs: Overriding with client local/user config"); - err = clientConfig.Load("user://client.cfg"); - if (err == Godot.Error.Ok) - { - _serilogger.Information("ServerConnection.cs: Successfully loaded the config from 'user://client.cfg'"); - url = (String)clientConfig.GetValue("amqp", "server_string", "amqp://127.0.0.1:5672"); - _serilogger.Debug("ServerConnection.cs: config file: setting url to " + url); - disableCertValidation = (bool)clientConfig.GetValue("amqp", "disable_cert_validation", true); - _serilogger.Debug("ServerConnection.cs: config file: setting cert validation to " + disableCertValidation); - } - - InitializeAMQP(); + MyGame = GetNode("/root/Game"); + _serilogger = MyGame._serilogger; + + // TODO: move config to its own method + var clientConfig = new ConfigFile(); + Godot.Error err; + + _serilogger.Debug("ServerConnection.cs: Attempting to load embedded client config"); + err = clientConfig.Load("res://Resources/client.cfg"); + if (err == Godot.Error.Ok) + { + _serilogger.Information("ServerConnection.cs: Successfully loaded the config from 'res://Resources/client.cfg'"); + url = (String)clientConfig.GetValue("amqp", "server_string", "amqp://127.0.0.1:5672"); + _serilogger.Debug("ServerConnection.cs: config file: setting url to " + url); + disableCertValidation = (bool)clientConfig.GetValue("amqp", "disable_cert_validation", true); + _serilogger.Debug("ServerConnection.cs: config file: setting cert validation to " + disableCertValidation); + } + + _serilogger.Debug("ServerConnection.cs: Overriding with client local/user config"); + err = clientConfig.Load("user://client.cfg"); + if (err == Godot.Error.Ok) + { + _serilogger.Information("ServerConnection.cs: Successfully loaded the config from 'user://client.cfg'"); + url = (String)clientConfig.GetValue("amqp", "server_string", "amqp://127.0.0.1:5672"); + _serilogger.Debug("ServerConnection.cs: config file: setting url to " + url); + disableCertValidation = (bool)clientConfig.GetValue("amqp", "disable_cert_validation", true); + _serilogger.Debug("ServerConnection.cs: config file: setting cert validation to " + disableCertValidation); + } + + InitializeAMQP(); } public void RemovePlayerSelf() { - // TODO do we need this anymore? Delete and remove references to it + // TODO do we need this anymore? Delete and remove references to it } private void GameEventReceived(IReceiverLink receiver, Message message) { - _serilogger.Verbose("ServerConnection.cs: Game Event received!"); - try - { - receiver.Accept(message); - byte[] binaryBody = (byte[])message.Body; - MemoryStream st = new MemoryStream(binaryBody, false); - GameEvent egeb = Serializer.Deserialize(st); - - this.ProcessGameEvent(egeb); // TODO: move this into it's own class to declutter the networking code - } - catch (Exception ex) - { - _serilogger.Warning("ServerConnection.cs: Issue deserializing game event."); - _serilogger.Error($"ServerConnection.cs: {ex.Message}"); - // TODO: if this continues - warn player of connection issues - return; - } + _serilogger.Verbose("ServerConnection.cs: Game Event received!"); + try + { + receiver.Accept(message); + byte[] binaryBody = (byte[])message.Body; + MemoryStream st = new MemoryStream(binaryBody, false); + GameEvent egeb = Serializer.Deserialize(st); + + this.ProcessGameEvent(egeb); // TODO: move this into it's own class to declutter the networking code + } + catch (Exception ex) + { + _serilogger.Warning("ServerConnection.cs: Issue deserializing game event."); + _serilogger.Error($"ServerConnection.cs: {ex.Message}"); + // TODO: if this continues - warn player of connection issues + return; + } } private void SecurityReceived(IReceiverLink receiver, Message message) { - _serilogger.Debug("ServerConnection.cs: Security Event received!"); - try - { - receiver.Accept(message); - byte[] binaryBody = (byte[])message.Body; - MemoryStream st = new MemoryStream(binaryBody, false); - Security security = Serializer.Deserialize(st); - - this.ProcessSecurity(security); // TODO: move this into it's own class to declutter the networking code - } - catch (System.Exception) - { - - throw; - } + _serilogger.Debug("ServerConnection.cs: Security Event received!"); + try + { + receiver.Accept(message); + byte[] binaryBody = (byte[])message.Body; + MemoryStream st = new MemoryStream(binaryBody, false); + Security security = Serializer.Deserialize(st); + + this.ProcessSecurity(security); // TODO: move this into it's own class to declutter the networking code + } + catch (System.Exception) + { + + throw; + } } public void SendCommand(Command commandBuffer) { - try - { - _serilogger.Verbose("ServerConnection.cs: Sending command"); - MemoryStream st = new MemoryStream(); - Serializer.Serialize(st, commandBuffer); - byte[] msgBytes = st.ToArray(); - Message msg = new Message(msgBytes); - commandsSender.Send(msg, null, null); // don't care about the ack on our message being received - } - catch (Exception ex) - { - _serilogger.Error("ServerConnection.cs: Send Command failed."); - _serilogger.Error(ex.Message); - - // TODO: let player know / return to login screen - - return; - } + try + { + _serilogger.Verbose("ServerConnection.cs: Sending command"); + MemoryStream st = new MemoryStream(); + Serializer.Serialize(st, commandBuffer); + byte[] msgBytes = st.ToArray(); + Message msg = new Message(msgBytes); + commandsSender.Send(msg, null, null); // don't care about the ack on our message being received + } + catch (Exception ex) + { + _serilogger.Error("ServerConnection.cs: Send Command failed."); + _serilogger.Error(ex.Message); + + // TODO: let player know / return to login screen + + return; + } } public void SendSecurity(Security security) { - try - { - _serilogger.Debug("ServerConnection.cs: Sending security"); - MemoryStream st = new MemoryStream(); - Serializer.Serialize(st, security); - byte[] msgBytes = st.ToArray(); - Message msg = new Message(msgBytes); - securitySender.Send(msg, null, null); // don't care about the ack on our message being received - - - } - catch (Exception ex) - { - _serilogger.Error("ServerConnection.cs: Send Security failed."); - _serilogger.Error(ex.Message); - - // TODO: let player know / return to login screen - - return; - } + try + { + _serilogger.Debug("ServerConnection.cs: Sending security"); + MemoryStream st = new MemoryStream(); + Serializer.Serialize(st, security); + byte[] msgBytes = st.ToArray(); + Message msg = new Message(msgBytes); + securitySender.Send(msg, null, null); // don't care about the ack on our message being received + + + } + catch (Exception ex) + { + _serilogger.Error("ServerConnection.cs: Send Security failed."); + _serilogger.Error(ex.Message); + + // TODO: let player know / return to login screen + + return; + } } async void InitializeAMQP() { - String linkid; - - _serilogger.Information("ServerConnection.cs: Initializing AMQP connection"); - Connection.DisableServerCertValidation = disableCertValidation; - try - { - //Trace.TraceLevel = TraceLevel.Frame; - //Trace.TraceListener = (l, f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:mm:ss.fff]") + " " + string.Format(f, a)); - factory = new ConnectionFactory(); - _serilogger.Information("ServerConnection.cs: connecting to " + url); - Address address = new Address(url); - - // TODO: does this need to be async? it causes some issues - amqpConnection = await factory.CreateAsync(address); - amqpSession = new Session(amqpConnection); - } - catch (Exception ex) - { - _serilogger.Error("ServerConnection.cs: AMQP connection/session failed for " + url); - _serilogger.Error($"ServerConnection.cs: {ex.Message}"); - // TODO: let player know - return; - } - - // set up senders and receivers //////////////////////////////////////////// - linkid = "srt-game-client-command-receiver-" + UUID; - _serilogger.Debug("ServerConnection.cs: Creating AMQ receiver for game events: " + linkid); - Source eventOutSource = new Source - { - Address = gameEventsTopic, - Capabilities = new Symbol[] { new Symbol("topic") } - }; - gameEventsReceiver = new ReceiverLink(amqpSession, linkid, eventOutSource, null); - gameEventsReceiver.Start(10, GameEventReceived); - - linkid = "srt-game-client-security-receiver-" + UUID; - _serilogger.Debug("ServerConnection.cs: Creating AMQ receiver for security events: " + linkid); - Source securityOutSource = new Source - { - Address = securityOutTopic, - Capabilities = new Symbol[] { new Symbol("topic") } - }; - securityOutReceiver = new ReceiverLink(amqpSession, linkid, securityOutSource, null); - securityOutReceiver.Start(10, SecurityReceived); - - linkid = "srt-game-client-command-sender-" + UUID; - _serilogger.Debug("ServerConnection.cs: Creating AMQ sender for player commands: " + linkid); - Target commandInTarget = new Target - { - Address = commandsQueue, - Capabilities = new Symbol[] { new Symbol("queue") } - }; - commandsSender = new SenderLink(amqpSession, linkid, commandInTarget, null); - - linkid = "srt-game-security-sender-" + UUID; - _serilogger.Debug("ServerConnection.cs: Creating AMQ sender for security commands: " + linkid); - Target securityInTarget = new Target - { - Address = securityQueue, - Capabilities = new Symbol[] { new Symbol("queue") } - }; - securitySender = new SenderLink(amqpSession, linkid, securityInTarget, null); - - _serilogger.Debug("ServerConnection.cs: Finished initializing AMQP connection"); - - // send announce message - _serilogger.Debug($"ServerConnection.cs: Sending announce message for our client: {UUID}"); - Security announceMessage = new Security(); - announceMessage.Uuid = UUID; - announceMessage.security_type = Security.SecurityType.SecurityTypeAnnounce; - SendSecurity(announceMessage); + String linkid; + + _serilogger.Information("ServerConnection.cs: Initializing AMQP connection"); + Connection.DisableServerCertValidation = disableCertValidation; + try + { + //Trace.TraceLevel = TraceLevel.Frame; + //Trace.TraceListener = (l, f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:mm:ss.fff]") + " " + string.Format(f, a)); + factory = new ConnectionFactory(); + _serilogger.Information("ServerConnection.cs: connecting to " + url); + Address address = new Address(url); + + // TODO: does this need to be async? it causes some issues + amqpConnection = await factory.CreateAsync(address); + amqpSession = new Session(amqpConnection); + } + catch (Exception ex) + { + _serilogger.Error("ServerConnection.cs: AMQP connection/session failed for " + url); + _serilogger.Error($"ServerConnection.cs: {ex.Message}"); + // TODO: let player know + return; + } + + // set up senders and receivers //////////////////////////////////////////// + linkid = "srt-game-client-command-receiver-" + UUID; + _serilogger.Debug("ServerConnection.cs: Creating AMQ receiver for game events: " + linkid); + Source eventOutSource = new Source + { + Address = gameEventsTopic, + Capabilities = new Symbol[] { new Symbol("topic") } + }; + gameEventsReceiver = new ReceiverLink(amqpSession, linkid, eventOutSource, null); + gameEventsReceiver.Start(10, GameEventReceived); + + linkid = "srt-game-client-security-receiver-" + UUID; + _serilogger.Debug("ServerConnection.cs: Creating AMQ receiver for security events: " + linkid); + Source securityOutSource = new Source + { + Address = securityOutTopic, + Capabilities = new Symbol[] { new Symbol("topic") } + }; + securityOutReceiver = new ReceiverLink(amqpSession, linkid, securityOutSource, null); + securityOutReceiver.Start(10, SecurityReceived); + + linkid = "srt-game-client-command-sender-" + UUID; + _serilogger.Debug("ServerConnection.cs: Creating AMQ sender for player commands: " + linkid); + Target commandInTarget = new Target + { + Address = commandsQueue, + Capabilities = new Symbol[] { new Symbol("queue") } + }; + commandsSender = new SenderLink(amqpSession, linkid, commandInTarget, null); + + linkid = "srt-game-security-sender-" + UUID; + _serilogger.Debug("ServerConnection.cs: Creating AMQ sender for security commands: " + linkid); + Target securityInTarget = new Target + { + Address = securityQueue, + Capabilities = new Symbol[] { new Symbol("queue") } + }; + securitySender = new SenderLink(amqpSession, linkid, securityInTarget, null); + + _serilogger.Debug("ServerConnection.cs: Finished initializing AMQP connection"); + + // send announce message + _serilogger.Debug($"ServerConnection.cs: Sending announce message for our client: {UUID}"); + Security announceMessage = new Security(); + announceMessage.Uuid = UUID; + announceMessage.security_type = Security.SecurityType.SecurityTypeAnnounce; + SendSecurity(announceMessage); } private void ProcessSecurity(Security security) { - try - { - switch (security.security_type) - { - case Security.SecurityType.SecurityTypeAnnounce: - _serilogger.Debug($"ServerConnection.cs: Received announce for {security.Uuid}"); - - // check if the received announce matches our ServerConnection UUID - if (security.Uuid == UUID) { - _serilogger.Debug("ServerConnection.cs: Received announce message matches our UUID, processing"); - MyGame.ProcessAnnounce(security); - } - break; - case Security.SecurityType.SecurityTypeJoin: - // TODO: do something fancy because a player joined - break; - case Security.SecurityType.SecurityTypeLeave: - // TODO: do something fancy because a player left - break; - case Security.SecurityType.SecurityTypeUnspecified: - _serilogger.Verbose("ServerConnection.cs: Unspecified security message received"); - break; - } - } - catch (Exception ex) - { - _serilogger.Error("ServerConnection.cs: Issue processing security event:"); - _serilogger.Error(ex.Message); - return; - } + try + { + switch (security.security_type) + { + case Security.SecurityType.SecurityTypeAnnounce: + _serilogger.Debug($"ServerConnection.cs: Received announce for {security.Uuid}"); + + // check if the received announce matches our ServerConnection UUID + if (security.Uuid == UUID) { + _serilogger.Debug("ServerConnection.cs: Received announce message matches our UUID, processing"); + MyGame.ProcessAnnounce(security); + } + break; + case Security.SecurityType.SecurityTypeJoin: + // TODO: do something fancy because a player joined + break; + case Security.SecurityType.SecurityTypeLeave: + // TODO: do something fancy because a player left + break; + case Security.SecurityType.SecurityTypeUnspecified: + _serilogger.Verbose("ServerConnection.cs: Unspecified security message received"); + break; + } + } + catch (Exception ex) + { + _serilogger.Error("ServerConnection.cs: Issue processing security event:"); + _serilogger.Error(ex.Message); + return; + } } /// @@ -279,83 +279,83 @@ private void ProcessSecurity(Security security) /// private void ProcessGameEvent(GameEvent egeb) { - try - { - switch (egeb.game_event_type) - { - case GameEvent.GameEventType.GameEventTypeCreate: - _serilogger.Debug("ServerConnection.cs: EntityGameEventBuffer [create]"); - switch (egeb.game_object_type) - { - case GameEvent.GameObjectType.GameObjectTypePlayer: - _serilogger.Debug($"ServerConnection.cs: Got create for a ship {egeb.Uuid}"); - MyGame.PlayerCreateQueue.Enqueue(egeb); - break; - - case GameEvent.GameObjectType.GameObjectTypeMissile: - _serilogger.Debug($"ServerConnection.cs: Got create for a missile {egeb.Uuid} owner {egeb.OwnerUuid}"); - MyGame.MissileCreateQueue.Enqueue(egeb); - break; - } - break; - - case GameEvent.GameEventType.GameEventTypeDestroy: - _serilogger.Debug("ServerConnection.cs: EntityGameEventBuffer [destroy]"); - - switch (egeb.game_object_type) - { - case GameEvent.GameObjectType.GameObjectTypePlayer: - _serilogger.Debug($"ServerConnection.cs: Got destroy for player {egeb.Uuid}"); - MyGame.PlayerDestroyQueue.Enqueue(egeb); - break; - - case GameEvent.GameObjectType.GameObjectTypeMissile: - _serilogger.Debug($"ServerConnection.cs: Got destroy for missile {egeb.Uuid} owner {egeb.OwnerUuid}"); - MyGame.MissileDestroyQueue.Enqueue(egeb); - break; - - } - break; - - case GameEvent.GameEventType.GameEventTypeRetrieve: - _serilogger.Debug("ServerConnection.cs: EntityGameEventBuffer [retrieve]"); - break; - - case GameEvent.GameEventType.GameEventTypeUpdate: - _serilogger.Verbose("ServerConnection.cs: EntityGameEventBuffer [update]"); - - // find/update the Node2D - if (egeb.Uuid == null || egeb.Uuid.Length < 1) // TODO: any additional validation goes here - { - _serilogger.Warning("ServerConnection.cs: got update event with invalid UUID, IGNORING..."); - return; - } - - switch (egeb.game_object_type) - { - case GameEvent.GameObjectType.GameObjectTypePlayer: - _serilogger.Verbose($"ServerConnection.cs: Got update for player {egeb.Uuid}"); - MyGame.PlayerUpdateQueue.Enqueue(egeb); - break; - - case GameEvent.GameObjectType.GameObjectTypeMissile: - _serilogger.Verbose($"ServerConnection.cs: Got update for missile {egeb.Uuid} owner {egeb.OwnerUuid}"); - MyGame.MissileUpdateQueue.Enqueue(egeb); - break; - } - break; - - default: - _serilogger.Debug("ServerConnection.cs: EntityGameEventBuffer type:[?????], IGNORING..."); - break; - } - } - catch (Exception ex) - { - _serilogger.Error("ServerConnection.cs: Issue processing game event:"); - _serilogger.Error(ex.Message); - return; - } + try + { + switch (egeb.game_event_type) + { + case GameEvent.GameEventType.GameEventTypeCreate: + _serilogger.Debug("ServerConnection.cs: EntityGameEventBuffer [create]"); + switch (egeb.game_object_type) + { + case GameEvent.GameObjectType.GameObjectTypePlayer: + _serilogger.Debug($"ServerConnection.cs: Got create for a ship {egeb.Uuid}"); + MyGame.PlayerCreateQueue.Enqueue(egeb); + break; + + case GameEvent.GameObjectType.GameObjectTypeMissile: + _serilogger.Debug($"ServerConnection.cs: Got create for a missile {egeb.Uuid} owner {egeb.OwnerUuid}"); + MyGame.MissileCreateQueue.Enqueue(egeb); + break; + } + break; + + case GameEvent.GameEventType.GameEventTypeDestroy: + _serilogger.Debug("ServerConnection.cs: EntityGameEventBuffer [destroy]"); + + switch (egeb.game_object_type) + { + case GameEvent.GameObjectType.GameObjectTypePlayer: + _serilogger.Debug($"ServerConnection.cs: Got destroy for player {egeb.Uuid}"); + MyGame.PlayerDestroyQueue.Enqueue(egeb); + break; + + case GameEvent.GameObjectType.GameObjectTypeMissile: + _serilogger.Debug($"ServerConnection.cs: Got destroy for missile {egeb.Uuid} owner {egeb.OwnerUuid}"); + MyGame.MissileDestroyQueue.Enqueue(egeb); + break; + + } + break; + + case GameEvent.GameEventType.GameEventTypeRetrieve: + _serilogger.Debug("ServerConnection.cs: EntityGameEventBuffer [retrieve]"); + break; + + case GameEvent.GameEventType.GameEventTypeUpdate: + _serilogger.Verbose("ServerConnection.cs: EntityGameEventBuffer [update]"); + + // find/update the Node2D + if (egeb.Uuid == null || egeb.Uuid.Length < 1) // TODO: any additional validation goes here + { + _serilogger.Warning("ServerConnection.cs: got update event with invalid UUID, IGNORING..."); + return; + } + + switch (egeb.game_object_type) + { + case GameEvent.GameObjectType.GameObjectTypePlayer: + _serilogger.Verbose($"ServerConnection.cs: Got update for player {egeb.Uuid}"); + MyGame.PlayerUpdateQueue.Enqueue(egeb); + break; + + case GameEvent.GameObjectType.GameObjectTypeMissile: + _serilogger.Verbose($"ServerConnection.cs: Got update for missile {egeb.Uuid} owner {egeb.OwnerUuid}"); + MyGame.MissileUpdateQueue.Enqueue(egeb); + break; + } + break; + + default: + _serilogger.Debug("ServerConnection.cs: EntityGameEventBuffer type:[?????], IGNORING..."); + break; + } + } + catch (Exception ex) + { + _serilogger.Error("ServerConnection.cs: Issue processing game event:"); + _serilogger.Error(ex.Message); + return; + } } // // Called every frame. 'delta' is the elapsed time since the previous frame. diff --git a/Resources/client.cfg b/Resources/client.cfg index e76882c..1a39e2a 100644 --- a/Resources/client.cfg +++ b/Resources/client.cfg @@ -5,4 +5,4 @@ server_string="amqp://localhost:5672" disable_cert_validation=true [game] -log_level=3 ; 0=fatal, 1=err, 2=warn, 3=inf, 4=dbg, 5=verbose \ No newline at end of file +log_level=4 ; 0=fatal, 1=err, 2=warn, 3=inf, 4=dbg, 5=verbose \ No newline at end of file diff --git a/Scenes/LoginScreen.cs b/Scenes/LoginScreen.cs index c46c6e0..fe6f276 100644 --- a/Scenes/LoginScreen.cs +++ b/Scenes/LoginScreen.cs @@ -11,36 +11,36 @@ public class LoginScreen : Control public override void _Ready() { - MyGame = GetNode("/root/Game"); - _serilogger = MyGame._serilogger; + MyGame = GetNode("/root/Game"); + _serilogger = MyGame._serilogger; textField = this.GetNode("VBoxContainer/HBoxContainer/NameLineEdit"); textField.GrabFocus(); - // TODO: need to interrogate server for the initial defaults for things like - // missile speed + // TODO: need to interrogate server for the initial defaults for things like + // missile speed } private void _on_JoinButton_button_up() { - _serilogger.Information($"LoginScreen: trying to login as {textField.Text}"); - MyGame.myUuid = textField.Text; - - //EmitSignal("SetPlayerName", textField.Text); - bool success = MyGame.JoinGameAsPlayer(textField.Text); - if (!success) - { - _serilogger.Information($"LoginScreen: join failed TODO tell player why"); - // TODO: alert errors or something - } - else - { - // since we successfully joined the game, we can remove this node - // which is the login screen. removing the login screen "displays" - // the main game window - QueueFree(); - MyGame.initializeGameUI(); - } + _serilogger.Information($"LoginScreen: trying to login as {textField.Text}"); + MyGame.myUuid = textField.Text; + + //EmitSignal("SetPlayerName", textField.Text); + bool success = MyGame.JoinGameAsPlayer(textField.Text); + if (!success) + { + _serilogger.Information($"LoginScreen: join failed TODO tell player why"); + // TODO: alert errors or something + } + else + { + // since we successfully joined the game, we can remove this node + // which is the login screen. removing the login screen "displays" + // the main game window + QueueFree(); + MyGame.initializeGameUI(); + } } } diff --git a/Scenes/SupportScenes/HitPoints.gd b/Scenes/SupportScenes/HitPoints.gd new file mode 100644 index 0000000..ec0113b --- /dev/null +++ b/Scenes/SupportScenes/HitPoints.gd @@ -0,0 +1,22 @@ +extends TextureProgress + +onready var healthyTexture = preload("res://Assets/Sprites/Ships/health-green.png") +onready var damagedTexture = preload("res://Assets/Sprites/Ships/health-orange.png") +onready var brokenTexture = preload("res://Assets/Sprites/Ships/health-red.png") + +const IS_HEALTHY: int = 70 +const IS_DAMAGED: int = 30 + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + if value >= IS_HEALTHY: + texture_progress = healthyTexture + elif value > IS_DAMAGED: + texture_progress = damagedTexture + else: + texture_progress = brokenTexture diff --git a/Scenes/SupportScenes/Player.tscn b/Scenes/SupportScenes/Player.tscn index 8484c13..e52469c 100644 --- a/Scenes/SupportScenes/Player.tscn +++ b/Scenes/SupportScenes/Player.tscn @@ -1,10 +1,13 @@ -[gd_scene load_steps=9 format=2] +[gd_scene load_steps=16 format=2] -[ext_resource path="res://Assets/Sprites/Ships/ship.png" type="Texture" id=1] +[ext_resource path="res://Assets/Sprites/Ships/spaceship_spritesheet.png" type="Texture" id=1] [ext_resource path="res://Scenes/SupportScenes/PlayerShip.cs" type="Script" id=2] [ext_resource path="res://Assets/UIElements/ShipShaders/whitebox.png" type="Texture" id=3] [ext_resource path="res://Assets/UIElements/ShipShaders/HitPointRing.gdshader" type="Shader" id=4] [ext_resource path="res://Assets/Sounds/ship-explode.wav" type="AudioStream" id=5] +[ext_resource path="res://Scenes/SupportScenes/HitPoints.gd" type="Script" id=6] +[ext_resource path="res://Assets/Sprites/Ships/health-grey.png" type="Texture" id=7] +[ext_resource path="res://Assets/Sprites/Ships/thrust_spritesheet.png" type="Texture" id=8] [ext_resource path="res://Assets/Sounds/453391__breviceps__warp-sfx.wav" type="AudioStream" id=6] [ext_resource path="res://Assets/Sounds/400126__harrietniamh__sci-fi-warp.wav" type="AudioStream" id=7] @@ -18,19 +21,195 @@ shader_param/red = 1.0 shader_param/green = 0.0 shader_param/blue = 0.0 +[sub_resource type="Animation" id=2] +length = 0.001 +tracks/0/type = "value" +tracks/0/path = NodePath("ShipSprite:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ 0 ] +} +tracks/1/type = "value" +tracks/1/path = NodePath("ThrustSprite:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ 0 ] +} + +[sub_resource type="Animation" id=5] +resource_name = "brake" +length = 0.75 +tracks/0/type = "value" +tracks/0/path = NodePath("ShipSprite:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 27, 28, 29, 30, 31, 32, 33, 34 ] +} +tracks/1/type = "value" +tracks/1/path = NodePath("ThrustSprite:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 27, 28, 29, 30, 31, 32, 33, 34 ] +} + +[sub_resource type="Animation" id=7] +resource_name = "cruise" +length = 0.1 +tracks/0/type = "value" +tracks/0/path = NodePath("ShipSprite:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ 0 ] +} +tracks/1/type = "value" +tracks/1/path = NodePath("ThrustSprite:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ 0 ] +} + +[sub_resource type="Animation" id=8] +resource_name = "left" +length = 0.75 +tracks/0/type = "value" +tracks/0/path = NodePath("ShipSprite:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 9, 10, 11, 12, 13, 14, 15, 16 ] +} +tracks/1/type = "value" +tracks/1/path = NodePath("ThrustSprite:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 9, 10, 11, 12, 13, 14, 15, 16 ] +} + +[sub_resource type="Animation" id=9] +resource_name = "right" +length = 0.75 +tracks/0/type = "value" +tracks/0/path = NodePath("ShipSprite:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 1, 2, 3, 4, 5, 6, 7, 8 ] +} +tracks/1/type = "value" +tracks/1/path = NodePath("ThrustSprite:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 1, 2, 3, 4, 5, 6, 7, 8 ] +} + +[sub_resource type="Animation" id=4] +resource_name = "thrust" +length = 0.75 +tracks/0/type = "value" +tracks/0/path = NodePath("ShipSprite:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 18, 19, 20, 21, 22, 23, 24, 25 ] +} +tracks/1/type = "value" +tracks/1/path = NodePath("ThrustSprite:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7 ), +"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1, 1 ), +"update": 1, +"values": [ 18, 19, 20, 21, 22, 23, 24, 25 ] +} + [node name="ShipThings" type="Node2D"] [node name="Stat" type="Node2D" parent="."] [node name="IDLabel" type="Label" parent="Stat"] +modulate = Color( 1, 1, 1, 0.4 ) margin_left = -35.0 -margin_top = 28.0 +margin_top = 34.0 margin_right = 35.0 -margin_bottom = 42.0 +margin_bottom = 48.0 grow_horizontal = 2 text = "UUIDUUID" align = 1 +[node name="VectorLbl" type="Label" parent="Stat"] +visible = true +margin_left = -50.0 +margin_top = 75.0 +margin_right = 50.0 +margin_bottom = 89.0 +align = 1 + [node name="LinearVelocity" type="Label" parent="Stat"] visible = false margin_left = -33.0 @@ -94,12 +273,18 @@ __meta__ = { [node name="PlayerShip" type="KinematicBody2D" parent="."] script = ExtResource( 2 ) -[node name="Sprite" type="Sprite" parent="PlayerShip"] -scale = Vector2( 0.25, 0.25 ) +[node name="ShipSprite" type="Sprite" parent="PlayerShip"] texture = ExtResource( 1 ) +hframes = 9 +vframes = 4 + +[node name="ThrustSprite" type="Sprite" parent="PlayerShip"] +texture = ExtResource( 8 ) +hframes = 9 +vframes = 4 [node name="ShipHitBox" type="CollisionPolygon2D" parent="PlayerShip"] -polygon = PoolVector2Array( -5, -31, 5, -31, 11, -10, 16, 5, 26, 10, 29, 28, -17, 28, -28, 28, -28, 15, -25, 10, -16, 4 ) +polygon = PoolVector2Array( -6, -44, 6, -44, 20, 4, 32, 9, 35, 21, 35, 33, 23, 33, 11, 27, -12, 28, -23, 32, -34, 32, -36, 20, -32, 8, -19, 4 ) [node name="RemoteTransform2D" type="RemoteTransform2D" parent="PlayerShip"] remote_path = NodePath("../../Stat") @@ -107,7 +292,19 @@ update_rotation = false [node name="Camera2D" type="Camera2D" parent="PlayerShip"] +[node name="HitPoints" type="TextureProgress" parent="PlayerShip"] +margin_left = -65.0 +margin_top = -65.0 +margin_right = 65.0 +margin_bottom = 65.0 +rect_pivot_offset = Vector2( 65, 65 ) +value = 100.0 +texture_progress = ExtResource( 7 ) +fill_mode = 5 +script = ExtResource( 6 ) + [node name="HitPointShader" type="Sprite" parent="PlayerShip"] +visible = false material = SubResource( 1 ) scale = Vector2( 1.3, 1.3 ) texture = ExtResource( 3 ) @@ -117,6 +314,13 @@ texture = ExtResource( 3 ) [node name="ExplodeSound" type="AudioStreamPlayer2D" parent="PlayerShip"] stream = ExtResource( 5 ) +[node name="ShipSpritePlayer" type="AnimationPlayer" parent="PlayerShip"] +anims/RESET = SubResource( 2 ) +anims/brake = SubResource( 5 ) +anims/cruise = SubResource( 7 ) +anims/left = SubResource( 8 ) +anims/right = SubResource( 9 ) +anims/thrust = SubResource( 4 ) [node name="WarpInSound" type="AudioStreamPlayer2D" parent="PlayerShip"] stream = ExtResource( 6 ) diff --git a/Scenes/SupportScenes/PlayerShip.cs b/Scenes/SupportScenes/PlayerShip.cs index 4ea0829..90f8850 100644 --- a/Scenes/SupportScenes/PlayerShip.cs +++ b/Scenes/SupportScenes/PlayerShip.cs @@ -27,6 +27,8 @@ public class PlayerShip : KinematicBody2D public int MissileDamage = 25; + public string TravelState = "default"; + // the reload time is the minimum time between missile firings // relevant when two players are very close to one another and // prevents missile spamming @@ -45,23 +47,29 @@ public class PlayerShip : KinematicBody2D Node2D shipThing; - Sprite hitPointRing; + Sprite thrustSprite; + TextureProgress hitPointRing; + AnimationPlayer shipAnimator; + Label vectorLbl; /// /// Called when the node enters the scene tree for the first time. /// public override void _Ready() { - MyGame = GetNode("/root/Game"); - _serilogger = MyGame._serilogger; - - shipThing = (Node2D)GetParent(); - Label playerIDLabel = (Label)shipThing.GetNode("Stat/IDLabel"); - - hitPointRing = (Sprite)GetNode("HitPointShader"); - - // TODO: deal with really long UUIDs - playerIDLabel.Text = uuid; + MyGame = GetNode("/root/Game"); + _serilogger = MyGame._serilogger; + + shipThing = (Node2D)GetParent(); + Label playerIDLabel = (Label)shipThing.GetNode("Stat/IDLabel"); + + hitPointRing = (TextureProgress)GetNode("HitPoints"); + shipAnimator = (AnimationPlayer)GetNode("ShipSpritePlayer"); + vectorLbl = (Label)GetParent().GetNode("Stat").GetNode("VectorLbl"); + thrustSprite = (Sprite)GetNode("ThrustSprite"); + + // TODO: deal with really long UUIDs + playerIDLabel.Text = uuid; } /// @@ -71,18 +79,18 @@ public override void _Ready() /// public GameEvent CreatePlayerGameEventBuffer(GameEvent.GameEventType BufferType) { - GameEvent egeb = new GameEvent(); - egeb.game_event_type = BufferType; - egeb.game_object_type = GameEvent.GameObjectType.GameObjectTypePlayer; - egeb.Uuid = uuid; + GameEvent egeb = new GameEvent(); + egeb.game_event_type = BufferType; + egeb.game_object_type = GameEvent.GameObjectType.GameObjectTypePlayer; + egeb.Uuid = uuid; - egeb.PositionX = (int)GlobalPosition.x; - egeb.PositionY = (int)GlobalPosition.y; + egeb.PositionX = (int)GlobalPosition.x; + egeb.PositionY = (int)GlobalPosition.y; - egeb.Angle = RotationDegrees; - egeb.AbsoluteVelocity = CurrentVelocity; + egeb.Angle = RotationDegrees; + egeb.AbsoluteVelocity = CurrentVelocity; - return egeb; + return egeb; } /// @@ -91,13 +99,79 @@ public GameEvent CreatePlayerGameEventBuffer(GameEvent.GameEventType BufferType) /// public void UpdateFromGameEventBuffer(GameEvent egeb) { - _serilogger.Verbose("PlayerShip.cs: UpdateFromGameEventBuffer"); - GlobalPosition = new Vector2(egeb.PositionX, egeb.PositionY); - RotationDegrees = egeb.Angle; - CurrentVelocity = egeb.AbsoluteVelocity; - HitPoints = egeb.HitPoints; + _serilogger.Verbose("PlayerShip.cs: UpdateFromGameEventBuffer"); + GlobalPosition = new Vector2(egeb.PositionX, egeb.PositionY); + UpdateShipAnimation(egeb.Angle, egeb.AbsoluteVelocity); + RotationDegrees = egeb.Angle; + CurrentVelocity = egeb.AbsoluteVelocity; + HitPoints = egeb.HitPoints; } + void UpdateShipAnimation(float rot, float vel) { + /* + Rotation -180 to 0 to 180 + */ + bool leftturn = false; + bool rightturn = false; + bool turning = (RotationDegrees != rot); + + bool cruise = !turning && (CurrentVelocity == vel || CurrentVelocity == MaxSpeed); + bool thrust = (CurrentVelocity < vel); + bool brake = (CurrentVelocity > vel && vel == 0); + if(!shipAnimator.IsPlaying()) { + if (thrust || CurrentVelocity == MaxSpeed) { + thrustSprite.Visible = true; + } else { + thrustSprite.Visible = false; + } + if (!turning) { + if (shipAnimator.AssignedAnimation == "left" || shipAnimator.AssignedAnimation == "right"){ + //shipAnimator.PlayBackwards(shipAnimator.AssignedAnimation); + } + if (thrust && shipAnimator.AssignedAnimation != "thrust") { + shipAnimator.Play("thrust"); + vectorLbl.Text = "thrust"; + } else if (brake && shipAnimator.AssignedAnimation != "brake") { + shipAnimator.Play("brake"); + vectorLbl.Text = "thrust"; + } else if (shipAnimator.AssignedAnimation != "cruise") { + shipAnimator.Play("cruise"); + vectorLbl.Text = "cruise"; + } + } else { + float trueRotation = GetTrueRotation(RotationDegrees); + float trueNewRotation = GetTrueRotation(rot); + if (trueRotation > 270 && trueNewRotation < 90) { + leftturn = true; + rightturn = false; + } else if (trueRotation < 90 && trueNewRotation > 270) { + leftturn = false; + rightturn = true; + } else { + leftturn = trueRotation < trueNewRotation; + rightturn = trueRotation > trueNewRotation; + } + + if (leftturn && shipAnimator.AssignedAnimation != "left") { + shipAnimator.Play("left"); + //vectorLbl.Text = RotationDegrees.ToString(); + } else if (rightturn && shipAnimator.AssignedAnimation != "right") { + shipAnimator.Play("right"); + //vectorLbl.Text = RotationDegrees.ToString(); + } + } + } + } + + public float GetTrueRotation(float degrees) { + float val = 0; + if (degrees < 0) { + val = Math.Abs(degrees); + } else if (degrees > 0) { + val = 360 - degrees; + } + return val; + } /// /// /// @@ -112,42 +186,42 @@ public void ExpirePlayer() // TODO: this is unused -- should we relocate fire methods from Game.cs? public void FireMissile() { - // only one missile allowed for now - if (MyMissile != null) { return; } + // only one missile allowed for now + if (MyMissile != null) { return; } - PackedScene missileScene = (PackedScene)ResourceLoader.Load("res://SpaceMissile.tscn"); - MyMissile = (SpaceMissile)missileScene.Instance(); + PackedScene missileScene = (PackedScene)ResourceLoader.Load("res://SpaceMissile.tscn"); + MyMissile = (SpaceMissile)missileScene.Instance(); - MyMissile.uuid = Guid.NewGuid().ToString(); + MyMissile.uuid = Guid.NewGuid().ToString(); - // missile should point in the same direction as the ship - MyMissile.Rotation = Rotation; + // missile should point in the same direction as the ship + MyMissile.Rotation = Rotation; - // TODO: need to offset this to the front of the ship - // start at our position - MyMissile.Position = GlobalPosition; + // TODO: need to offset this to the front of the ship + // start at our position + MyMissile.Position = GlobalPosition; - // negative direction is "up" - Vector2 offset = new Vector2(0, -100); + // negative direction is "up" + Vector2 offset = new Vector2(0, -100); - // rotate the offset to match the current ship heading - offset = offset.Rotated(Rotation); - MyMissile.Position = MyMissile.Position + offset; + // rotate the offset to match the current ship heading + offset = offset.Rotated(Rotation); + MyMissile.Position = MyMissile.Position + offset; - // set missile's parameters based on current modifiers - MyMissile.MissileSpeed = MissileSpeed; - MyMissile.MissileLife = MissileLife; - MyMissile.MissileDamage = MissileDamage; + // set missile's parameters based on current modifiers + MyMissile.MissileSpeed = MissileSpeed; + MyMissile.MissileLife = MissileLife; + MyMissile.MissileDamage = MissileDamage; - // this is a poop way to do this - MyMissile.MyPlayer = this; + // this is a poop way to do this + MyMissile.MyPlayer = this; - // put the missile into the missiles group so we can send updates about it later - MyMissile.AddToGroup("missiles"); + // put the missile into the missiles group so we can send updates about it later + MyMissile.AddToGroup("missiles"); - Node rootNode = GetNode("/root/"); - rootNode.CallDeferred("add_child", MyMissile); - _serilogger.Debug("Added missile instance!"); + Node rootNode = GetNode("/root/"); + rootNode.CallDeferred("add_child", MyMissile); + _serilogger.Debug("Added missile instance!"); } /// @@ -156,9 +230,9 @@ public void FireMissile() /// public void TakeDamage(int Damage) { - _serilogger.Debug($"Player.cs: {uuid}: Taking damage: {Damage}"); - HitPoints -= Damage; - _serilogger.Debug($"Player.cs: {uuid}: Hitpoints: {HitPoints}"); + _serilogger.Debug($"Player.cs: {uuid}: Taking damage: {Damage}"); + HitPoints -= Damage; + _serilogger.Debug($"Player.cs: {uuid}: Hitpoints: {HitPoints}"); } void CheckMissileReload(float delta) @@ -176,19 +250,23 @@ void CheckMissileReload(float delta) void UpdateHitPointRing() { - float hitPointRatio = (float)HitPoints / (float)MyGame.PlayerDefaultHitPoints; - _serilogger.Verbose($"PlayerShip.cs: hitpoints is {HitPoints} for UUID {uuid}"); - _serilogger.Verbose($"PlayerShip.cs: hitpoint ratio {hitPointRatio} for UUID {uuid}"); - - ShaderMaterial ringShader = (ShaderMaterial)hitPointRing.Material; - ringShader.SetShaderParam("fill_ratio", hitPointRatio); - _serilogger.Verbose($"PlayerShip.cs: shader fill_ratio is {ringShader.GetShaderParam("fill_ratio")}"); + hitPointRing.MaxValue = (float)MyGame.PlayerDefaultHitPoints; + hitPointRing.Value = (float)HitPoints; + _serilogger.Verbose($"PlayerShip.cs: hitpoints is {HitPoints} for UUID {uuid}"); + _serilogger.Debug($"PlayerShip.cs: hitpoint ratio {hitPointRing.Value}/{hitPointRing.MaxValue} for UUID {uuid}"); + /* + float hitPointRatio = (float)HitPoints / (float)MyGame.PlayerDefaultHitPoints; + ShaderMaterial ringShader = (ShaderMaterial)hitPointRing.Material; + ringShader.SetShaderParam("fill_ratio", hitPointRatio); + _serilogger.Debug($"PlayerShip.cs: shader fill_ratio is {ringShader.GetShaderParam("fill_ratio")}"); + */ + } public override void _Process(float delta) { - CheckMissileReload(delta); - UpdateHitPointRing(); + CheckMissileReload(delta); + UpdateHitPointRing(); } void _on_ExplodeSound_finished() diff --git a/Scenes/SupportScenes/SpaceMissile.cs b/Scenes/SupportScenes/SpaceMissile.cs index 6d8756b..a8a6e4a 100644 --- a/Scenes/SupportScenes/SpaceMissile.cs +++ b/Scenes/SupportScenes/SpaceMissile.cs @@ -31,65 +31,65 @@ public class SpaceMissile : Area2D /// public void UpdateFromGameEventBuffer(GameEvent egeb) { - _serilogger.Verbose($"SpaceMissile.cs: updating missile {uuid}"); - this.GlobalPosition = new Vector2(egeb.PositionX, egeb.PositionY); - this.RotationDegrees = egeb.Angle; + _serilogger.Verbose($"SpaceMissile.cs: updating missile {uuid}"); + this.GlobalPosition = new Vector2(egeb.PositionX, egeb.PositionY); + this.RotationDegrees = egeb.Angle; } public void Expire() { - // stop the regular animation and play the explosion animation - _serilogger.Debug($"SpaceMissile.cs: missile {uuid} expiring"); - GetNode("Sprite").Hide(); - GetNode("Animations").Hide(); - missileAnimation.Stop(); - missileAnimation.Frame = 0; - missileExplosion.Play(); - GetNode("ExplodeSound").Play(); - - if (MyPlayer != null) MyPlayer.MyMissile = null; + // stop the regular animation and play the explosion animation + _serilogger.Debug($"SpaceMissile.cs: missile {uuid} expiring"); + GetNode("Sprite").Hide(); + GetNode("Animations").Hide(); + missileAnimation.Stop(); + missileAnimation.Frame = 0; + missileExplosion.Play(); + GetNode("ExplodeSound").Play(); + + if (MyPlayer != null) MyPlayer.MyMissile = null; } // Called when the node enters the scene tree for the first time. public override void _Ready() { - MyGame = GetNode("/root/Game"); - _serilogger = MyGame._serilogger; + MyGame = GetNode("/root/Game"); + _serilogger = MyGame._serilogger; - // connect the hit signal to handling the hit - //Connect(nameof(Hit), this, "_HandleHit"); + // connect the hit signal to handling the hit + //Connect(nameof(Hit), this, "_HandleHit"); - missileAnimation = GetNode("Animations"); - missileExplosion = GetNode("Explosion"); - //GetNode("FireSound").Play(); + missileAnimation = GetNode("Animations"); + missileExplosion = GetNode("Explosion"); + //GetNode("FireSound").Play(); } public override void _Process(float delta) { - if (missileAnimation.Animation == "launch" && missileAnimation.Frame > 30) - { - missileAnimation.Frame = 0; - missileAnimation.Play("travel"); - } + if (missileAnimation.Animation == "launch" && missileAnimation.Frame > 30) + { + missileAnimation.Frame = 0; + missileAnimation.Play("travel"); + } } void _on_Explosion_animation_finished() { - _serilogger.Debug($"SpaceMissile.cs: Explosion animation finished - freeing queue"); - // when the explosion animation finishes, remove the missile from the scene - QueueFree(); + _serilogger.Debug($"SpaceMissile.cs: Explosion animation finished - freeing queue"); + // when the explosion animation finishes, remove the missile from the scene + QueueFree(); } public override void _PhysicsProcess(float delta) { - // TODO disable the collision shape until the missile is "away" from the ship - - // create a new vector and rotate it by the current heading of the missile - // then move the missile in the direction of that vector - Vector2 velocity = new Vector2(0, -1); - velocity = velocity.Rotated(Rotation); - velocity = velocity * MissileSpeed * delta; - Position += velocity; + // TODO disable the collision shape until the missile is "away" from the ship + + // create a new vector and rotate it by the current heading of the missile + // then move the missile in the direction of that vector + Vector2 velocity = new Vector2(0, -1); + velocity = velocity.Rotated(Rotation); + velocity = velocity * MissileSpeed * delta; + Position += velocity; } //void _onSpaceMissileBodyEntered(Node body) diff --git a/export_presets.cfg b/export_presets.cfg index 7842d6a..b2aa97e 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -7,16 +7,16 @@ custom_features="" export_filter="all_resources" include_filter="*.cfg" exclude_filter="export_presets.cfg" -export_path="" +export_path="../srt-client.x86_64" script_export_mode=1 script_encryption_key="" [preset.0.options] -custom_template/debug="" -custom_template/release="" +custom_template/debug="/home/ldary/Godot/Godot_v3.5.1-stable_mono_export_templates/templates/linux_x11_64_debug" +custom_template/release="/home/ldary/Godot/Godot_v3.5.1-stable_mono_export_templates/templates/linux_x11_64_release" binary_format/64_bits=true -binary_format/embed_pck=false +binary_format/embed_pck=true texture_format/bptc=false texture_format/s3tc=true texture_format/etc=false diff --git a/project.godot b/project.godot index f82be6f..c8b39e8 100644 --- a/project.godot +++ b/project.godot @@ -30,26 +30,31 @@ net=false rotate_left={ "deadzone": 0.5, "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"physical_scancode":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null) ] } rotate_right={ "deadzone": 0.5, "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"physical_scancode":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) ] } thrust_forward={ "deadzone": 0.5, "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"physical_scancode":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null) ] } thrust_reverse={ "deadzone": 0.5, "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"physical_scancode":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null) ] } fire={ "deadzone": 0.5, "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777238,"physical_scancode":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":false,"script":null) ] } zoom_in={