diff --git a/assets/rewards/DefaultReward.tres b/assets/rewards/DefaultReward.tres new file mode 100644 index 0000000..ddf91f8 --- /dev/null +++ b/assets/rewards/DefaultReward.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="MoneyReward" load_steps=3 format=3 uid="uid://kqqqjubwm37a"] + +[ext_resource type="PackedScene" uid="uid://3x821ng2yf57" path="res://scenes/templates/money_reward.tscn" id="1_g5bk7"] +[ext_resource type="Script" uid="uid://dtfmy3los1si1" path="res://scripts/resources/MoneyReward.cs" id="1_qd0ii"] + +[resource] +script = ExtResource("1_qd0ii") +Cost = 500 +Scene = ExtResource("1_g5bk7") +Name = "moneybag" +Description = "rwd_moneybag" +metadata/_custom_type_script = "uid://dtfmy3los1si1" diff --git a/assets/sprites/atlases/atlas1.png b/assets/sprites/atlases/atlas1.png index 9bd9d0a..d9cff53 100644 Binary files a/assets/sprites/atlases/atlas1.png and b/assets/sprites/atlases/atlas1.png differ diff --git a/assets/sprites/money_bag.tres b/assets/sprites/money_bag.tres new file mode 100644 index 0000000..196d1ab --- /dev/null +++ b/assets/sprites/money_bag.tres @@ -0,0 +1,7 @@ +[gd_resource type="AtlasTexture" load_steps=2 format=3 uid="uid://c3qw52yoseb1k"] + +[ext_resource type="Texture2D" uid="uid://dvldjlg0nr355" path="res://assets/sprites/atlases/atlas1.png" id="1_rucxc"] + +[resource] +atlas = ExtResource("1_rucxc") +region = Rect2(504, 16, 46, 49) diff --git a/assets/sprites/pon.png b/assets/sprites/pon.png new file mode 100644 index 0000000..524f2a1 Binary files /dev/null and b/assets/sprites/pon.png differ diff --git a/assets/sprites/pon.png.import b/assets/sprites/pon.png.import new file mode 100644 index 0000000..3de5c8f --- /dev/null +++ b/assets/sprites/pon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://br5wk508s7joi" +path="res://.godot/imported/pon.png-3e7efb58dffb516a84244a831349a644.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/sprites/pon.png" +dest_files=["res://.godot/imported/pon.png-3e7efb58dffb516a84244a831349a644.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/project.godot b/project.godot index 52b0f34..89fbd46 100644 --- a/project.godot +++ b/project.godot @@ -29,7 +29,8 @@ Cursor="*res://scripts/Cursor.cs" GameRegistry="*res://scripts/systems/GameRegistry.cs" Cheats="res://scripts/debug/Cheats.cs" AudioSequencer="*res://scenes/audio_sequencer.tscn" -SettingsSerializer="*res://scripts/SettingsSerializer.cs" +SaveSerializer="*res://scripts/SaveSerializer.cs" +PlayerProgress="*res://scripts/PlayerProgress.cs" [display] diff --git a/scenes/gui/reward_scene.tscn b/scenes/gui/reward_scene.tscn index 3213a82..cc99fa9 100644 --- a/scenes/gui/reward_scene.tscn +++ b/scenes/gui/reward_scene.tscn @@ -20,7 +20,7 @@ tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [Color(1, 1, 1, 1)] +"values": [Color(1, 1, 0.921569, 1)] } [sub_resource type="Animation" id="Animation_mbhdb"] @@ -136,6 +136,7 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 mouse_filter = 2 +color = Color(1, 1, 0.921569, 1) [node name="AnimationPlayer" type="AnimationPlayer" parent="."] libraries = { diff --git a/scenes/templates/level_template.tscn b/scenes/templates/level_template.tscn index 553f49f..dcb6344 100644 --- a/scenes/templates/level_template.tscn +++ b/scenes/templates/level_template.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=42 format=3 uid="uid://dd3yegl1xo44m"] +[gd_scene load_steps=43 format=3 uid="uid://dd3yegl1xo44m"] [ext_resource type="Script" uid="uid://bndu1h5kgcde8" path="res://scripts/level/RuntimeLevelData.cs" id="1_31ltw"] [ext_resource type="Script" uid="uid://bso32xkw738sy" path="res://scripts/level/PoolContainer.cs" id="2_s5sti"] @@ -24,6 +24,7 @@ [ext_resource type="Script" uid="uid://1lkhoh43h86m" path="res://scripts/level/GameTimer.cs" id="19_s7icd"] [ext_resource type="Script" uid="uid://84gvlkflxdhk" path="res://scripts/level/zombe_spawners/RowSpawner.cs" id="22_8qqc4"] [ext_resource type="Script" uid="uid://puqxp2xeg1r2" path="res://scripts/level/LevelRunner.cs" id="23_8vb7v"] +[ext_resource type="Resource" uid="uid://kqqqjubwm37a" path="res://assets/rewards/DefaultReward.tres" id="24_7v6ps"] [ext_resource type="Script" uid="uid://bc3s06ejbotma" path="res://scripts/gui/ZombieLevelPreviewer.cs" id="24_y5tw7"] [ext_resource type="Script" uid="uid://b31mnk4enldc4" path="res://scripts/level/InitialPackedSceneSpawner.cs" id="26_i7rp7"] @@ -425,7 +426,7 @@ tracks/0/path = NodePath("WinFade:color") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { -"times": PackedFloat32Array(0, 4, 5), +"times": PackedFloat32Array(0, 3, 5), "transitions": PackedFloat32Array(1, 1, 1), "update": 0, "values": [Color(1, 1, 0.92, 0), Color(1, 1, 0.92, 0), Color(1, 1, 0.92, 1)] @@ -704,6 +705,7 @@ wait_time = 2.5 [node name="LevelRunner" type="Node" parent="." node_paths=PackedStringArray("rowSpawner", "waveTimer", "player", "rewardParent")] script = ExtResource("23_8vb7v") +defaultReward = ExtResource("24_7v6ps") rowSpawner = NodePath("../RowSpawner") waveTimer = NodePath("WaveTimer") approachNotificationTime = 5.0 diff --git a/scenes/templates/money_reward.tscn b/scenes/templates/money_reward.tscn new file mode 100644 index 0000000..51f3c1b --- /dev/null +++ b/scenes/templates/money_reward.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=4 format=3 uid="uid://3x821ng2yf57"] + +[ext_resource type="Script" uid="uid://cwf2y3pxi6psc" path="res://scripts/droppable-items/DroppableItem.cs" id="1_jgexe"] +[ext_resource type="Texture2D" uid="uid://c3qw52yoseb1k" path="res://assets/sprites/money_bag.tres" id="1_wewwq"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_wewwq"] +size = Vector2(46, 50) + +[node name="MoneyReward" type="Area2D"] +script = ExtResource("1_jgexe") + +[node name="MoneyBag" type="Sprite2D" parent="."] +texture = ExtResource("1_wewwq") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_wewwq") diff --git a/scripts/PlayerProgress.cs b/scripts/PlayerProgress.cs new file mode 100644 index 0000000..ef4c36b --- /dev/null +++ b/scripts/PlayerProgress.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using Godot; +using Newlon; + +public partial class PlayerProgress : Node +{ + public static PlayerProgress Instance { get; private set; } + + public override void _EnterTree() + { + Instance = this; + } + + public List PlayerPlants { get; set; } = new(); + public int MaxSeedpackets = 9; + public int Money { get; set; } +} diff --git a/scripts/PlayerProgress.cs.uid b/scripts/PlayerProgress.cs.uid new file mode 100644 index 0000000..57798df --- /dev/null +++ b/scripts/PlayerProgress.cs.uid @@ -0,0 +1 @@ +uid://bkexfs6kuuuf2 diff --git a/scripts/SaveSerializer.cs b/scripts/SaveSerializer.cs new file mode 100644 index 0000000..b06581a --- /dev/null +++ b/scripts/SaveSerializer.cs @@ -0,0 +1,99 @@ +using Godot; +using Godot.Collections; +using Newlon; +using System.Text.Json; +using System.Collections.Generic; + +public partial class SaveSerializer : Node +{ + const string SAVE_PATH = "user://save.json"; + public override void _Ready() + { + GetTree().AutoAcceptQuit = false; + LoadGame(); + } + + public override void _Notification(int what) + { + if (what == NotificationWMCloseRequest) + { + SaveGame(); + GetTree().Quit(); + } + } + public static void SaveGame() + { + var access = FileAccess.Open(SAVE_PATH, FileAccess.ModeFlags.Write); + var playerProgress = PlayerProgress.Instance; + var save = new SaveData + { + + SFXVolume = (float)Settings.SFX, + MusicVolume = (float)Settings.Music, + SplashSeen = Settings.Splash, + Money = playerProgress.Money, + SeedpacketSlots = playerProgress.MaxSeedpackets, + PlayerPlants = [], + + SaveGameVersion = (string)ProjectSettings.GetSetting("application/config/version") + }; + + foreach (var plant in playerProgress.PlayerPlants) + { + save.PlayerPlants.Add(plant.internal_id); + } + + access.StoreString(JsonSerializer.Serialize(save)); + + access.Close(); + } + public static void LoadGame() + { + if (FileAccess.FileExists(SAVE_PATH) == false) + { + InitiateCleanSave(); + return; + } + + var access = FileAccess.Open(SAVE_PATH, FileAccess.ModeFlags.Read); + + var parsed = JsonSerializer.Deserialize(access.GetAsText()); + + Settings.SFX = parsed.SFXVolume; + Settings.Music = parsed.MusicVolume; + Settings.Splash = parsed.SplashSeen; + + AudioServer.SetBusVolumeDb(1, Mathf.LinearToDb((float)Settings.SFX)); + AudioServer.SetBusVolumeDb(2, Mathf.LinearToDb((float)Settings.Music)); + + var playerProgress = PlayerProgress.Instance; + playerProgress.MaxSeedpackets = parsed.SeedpacketSlots; + playerProgress.PlayerPlants = []; + + foreach (var plantId in parsed.PlayerPlants) + { + playerProgress.PlayerPlants.Add(GameRegistry.GetPlantByName(plantId)); + } + + + access.Close(); + } + private static void InitiateCleanSave() + { + PlayerProgress.Instance.PlayerPlants = new List([GameRegistry.GetPlantByName("peashooter")]); + PlayerProgress.Instance.Money = 0; + + SaveGame(); + } + private partial class SaveData + { + public float SFXVolume { get; set; } + public float MusicVolume { get; set; } + public string SaveGameVersion { get; set; } + public bool SplashSeen { get; set; } + public List PlayerPlants { get; set; } + public int Money { get; set; } = 0; + public int SeedpacketSlots { get; set; } = 6; + public List FinishedLevels { get; set; } = new(); + } +} diff --git a/scripts/SettingsSerializer.cs.uid b/scripts/SaveSerializer.cs.uid similarity index 100% rename from scripts/SettingsSerializer.cs.uid rename to scripts/SaveSerializer.cs.uid diff --git a/scripts/SettingsSerializer.cs b/scripts/SettingsSerializer.cs deleted file mode 100644 index b9e637c..0000000 --- a/scripts/SettingsSerializer.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Godot; - -public partial class SettingsSerializer : Node -{ - const string CFG_PATH = "user://config.cfg"; - public override void _EnterTree() - { - GetTree().AutoAcceptQuit = false; - if (FileAccess.FileExists(CFG_PATH) == false) return; - - var access = FileAccess.Open(CFG_PATH, FileAccess.ModeFlags.Read); - - Settings.SFX = float.Parse(access.GetLine().Split(" ")[1]); - Settings.Music = float.Parse(access.GetLine().Split(" ")[1]); - Settings.Splash = bool.Parse(access.GetLine().Split(" ")[1]); - - AudioServer.SetBusVolumeDb(0, Mathf.LinearToDb((float)Settings.SFX)); - AudioServer.SetBusVolumeDb(1, Mathf.LinearToDb((float)Settings.Music)); - - access.Close(); - } - public override void _ExitTree() - { - var access = FileAccess.Open(CFG_PATH, FileAccess.ModeFlags.Write); - access.Resize(0); - access.StoreString(string.Format("SFX {0}\nMusic {1}\nSplash {2}\n", Settings.SFX,Settings.Music,Settings.Splash)); - - access.Close(); - } - - public override void _Notification(int what) - { - if (what == NotificationWMCloseRequest) - { - _ExitTree(); - GetTree().Quit(); - } - } - - -} diff --git a/scripts/droppable-items/DroppableItem.cs b/scripts/droppable-items/DroppableItem.cs index ea05cbe..2281cfe 100644 --- a/scripts/droppable-items/DroppableItem.cs +++ b/scripts/droppable-items/DroppableItem.cs @@ -2,7 +2,7 @@ using Godot; [GlobalClass] -public abstract partial class DroppableItem : Area2D +public partial class DroppableItem : Area2D { [Signal] public delegate void PickedUpEventHandler(); public override void _InputEvent(Viewport viewport, InputEvent @event, int shapeIdx) @@ -10,8 +10,9 @@ public abstract partial class DroppableItem : Area2D if (@event.IsActionPressed("primary_action")) { PickUp(); + EmitSignal(SignalName.PickedUp); } } - public abstract void PickUp(); + public virtual void PickUp() {} } diff --git a/scripts/droppable-items/DroppableSeedpacket.cs b/scripts/droppable-items/DroppableSeedpacket.cs index ed18e41..acc952f 100644 --- a/scripts/droppable-items/DroppableSeedpacket.cs +++ b/scripts/droppable-items/DroppableSeedpacket.cs @@ -17,9 +17,4 @@ public partial class DroppableSeedpacket : DroppableItem _cost.LabelSettings = plant.customFrame.font; } } - - public override void PickUp() - { - EmitSignal(SignalName.PickedUp); - } } diff --git a/scripts/gui/almanach/AlmanachGrid.cs b/scripts/gui/almanach/AlmanachGrid.cs index f14ad0b..911cec4 100644 --- a/scripts/gui/almanach/AlmanachGrid.cs +++ b/scripts/gui/almanach/AlmanachGrid.cs @@ -28,7 +28,7 @@ public partial class AlmanachGrid : GridContainer } else { - var list = GameRegistry.GetPlants(); + var list = PlayerProgress.Instance.PlayerPlants; list.Sort((a, b) => { return a.Order - b.Order; diff --git a/scripts/gui/choose_your_seeds/GridLoader.cs b/scripts/gui/choose_your_seeds/GridLoader.cs index 21d0198..fba5db8 100644 --- a/scripts/gui/choose_your_seeds/GridLoader.cs +++ b/scripts/gui/choose_your_seeds/GridLoader.cs @@ -11,7 +11,7 @@ public partial class GridLoader : GridContainer { _plantCard = ResourceLoader.Load(SEEDPACKED_UID); - var list = GameRegistry.GetPlants(); + var list = PlayerProgress.Instance.PlayerPlants; list.Sort((a, b) => { return a.Order - b.Order; diff --git a/scripts/gui/seedpackets/ChoosableHandler.cs b/scripts/gui/seedpackets/ChoosableHandler.cs index 7af1730..40e2749 100644 --- a/scripts/gui/seedpackets/ChoosableHandler.cs +++ b/scripts/gui/seedpackets/ChoosableHandler.cs @@ -8,7 +8,7 @@ public class ChoosableHandler : SeedpacketHandler, ISeedpacketPress public void Pressed() { - if (LevelGUIElements.Instance.SeedpacketsHotbar.GetChildCount() >= PlayerInfo.MaxSeedpackets) return; + if (LevelGUIElements.Instance.SeedpacketsHotbar.GetChildCount() >= PlayerProgress.Instance.MaxSeedpackets) return; _owner.disablePacket = true; var hotbarSeedpacket = Seedpacket.Prefab.Instantiate(); diff --git a/scripts/level/LevelController.cs b/scripts/level/LevelController.cs index a975d18..7119457 100644 --- a/scripts/level/LevelController.cs +++ b/scripts/level/LevelController.cs @@ -58,7 +58,6 @@ public partial class LevelController : Node RuntimeLevelData.LevelResource = null; _isLevelRunning = false; - if (Reward != null) { GetTree().ChangeSceneToFile(REWARD_SCENE_UID); diff --git a/scripts/level/LevelRunner.cs b/scripts/level/LevelRunner.cs index 34462af..c717029 100644 --- a/scripts/level/LevelRunner.cs +++ b/scripts/level/LevelRunner.cs @@ -127,13 +127,24 @@ public partial class LevelRunner : Node RuntimeLevelData.Instance.SetLevelState(RuntimeLevelData.LevelStates.Win); - var reward = resource.reward.Scene.Instantiate(); + DroppableItem reward; + if (resource.reward.Redeem()) + { + reward = resource.reward.Scene.Instantiate(); + LevelController.Instance.SetReward(resource.reward); + } + else + { + defaultReward.Redeem(); + reward = defaultReward.Scene.Instantiate(); + LevelController.Instance.SetReward(defaultReward); + + } + if (reward is DroppableSeedpacket seedpacket && resource.reward is PlantReward plantReward) { seedpacket.plant = plantReward.Plant; } - LevelController.Instance.SetReward(resource.reward); - player.Play("win"); Callable.From(() => { rewardParent.AddChild(reward); @@ -145,6 +156,8 @@ public partial class LevelRunner : Node }).CallDeferred(); reward.PickedUp += () => { + player.Play("win"); + var tween = CreateTween(); var camera = GetViewport().GetCamera2D(); tween.TweenProperty(reward, "global_position", camera.GlobalPosition, 4.0); diff --git a/scripts/resources/MoneyReward.cs b/scripts/resources/MoneyReward.cs index 4808e76..a87ca82 100644 --- a/scripts/resources/MoneyReward.cs +++ b/scripts/resources/MoneyReward.cs @@ -9,5 +9,10 @@ public partial class MoneyReward : RewardResource { return Scene; } + public override bool Redeem() + { + PlayerProgress.Instance.Money += Cost; + return true; + } } diff --git a/scripts/resources/PlantReward.cs b/scripts/resources/PlantReward.cs index 7700d68..1ea5d19 100644 --- a/scripts/resources/PlantReward.cs +++ b/scripts/resources/PlantReward.cs @@ -11,5 +11,18 @@ public partial class PlantReward : RewardResource { return Plant.Scene; } + public override bool Redeem() + { + if (PlayerProgress.Instance.PlayerPlants.Contains(Plant) == false) + { + PlayerProgress.Instance.PlayerPlants.Add(Plant); + return true; + } + else + { + return false; + } + } + } diff --git a/scripts/resources/RewardResource.cs b/scripts/resources/RewardResource.cs index 258bb69..e1a4bbb 100644 --- a/scripts/resources/RewardResource.cs +++ b/scripts/resources/RewardResource.cs @@ -9,4 +9,5 @@ public abstract partial class RewardResource : Resource [Export] public string Name { get; private set; } [Export] public string Description { get; private set; } public abstract PackedScene GetPreview(); + public abstract bool Redeem(); } diff --git a/scripts/systems/GameRegistry.cs b/scripts/systems/GameRegistry.cs index 4e4ccd5..dae99e2 100644 --- a/scripts/systems/GameRegistry.cs +++ b/scripts/systems/GameRegistry.cs @@ -10,7 +10,7 @@ public partial class GameRegistry : Node public static readonly Dictionary PlantDictionary = []; public static readonly Dictionary ZombieDictionary = []; - public override void _Ready() + public override void _EnterTree() { //Plant init string[] plantFiles = ResourceLoader.ListDirectory(PLANT_RESOURCE_PATH); diff --git a/scripts/systems/static-data/PlayerInfo.cs b/scripts/systems/static-data/PlayerInfo.cs deleted file mode 100644 index cda1ee7..0000000 --- a/scripts/systems/static-data/PlayerInfo.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Godot; -using System; - -public partial class PlayerInfo : Node -{ - public static int MaxSeedpackets = 9; -} diff --git a/scripts/systems/static-data/PlayerInfo.cs.uid b/scripts/systems/static-data/PlayerInfo.cs.uid deleted file mode 100644 index f99278c..0000000 --- a/scripts/systems/static-data/PlayerInfo.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dpbaw8osly0ir