diff --git a/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.png b/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.png new file mode 100644 index 00000000..710489bc --- /dev/null +++ b/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3efcfee3110f59a82f3b0eba463dc8d15f84697f862a8417c86120cfaf9760a +size 368 diff --git a/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.png.import b/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.png.import new file mode 100644 index 00000000..2401da6d --- /dev/null +++ b/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://gkb4es8bcqtx" +path="res://.godot/imported/BulletFreezeCrystal.png-fec4ac4800a6713a3adbf5ba12fd6d69.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.png" +dest_files=["res://.godot/imported/BulletFreezeCrystal.png-fec4ac4800a6713a3adbf5ba12fd6d69.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/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.pxc b/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.pxc new file mode 100644 index 00000000..fcf0c47a Binary files /dev/null and b/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.pxc differ diff --git a/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.pxc1 b/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.pxc1 new file mode 100644 index 00000000..ad80282f Binary files /dev/null and b/ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.pxc1 differ diff --git a/Resources/Bullets/simple_enemy_bullet.tres b/Resources/Bullets/simple_enemy_bullet.tres index aeeb3480..a00d826b 100644 --- a/Resources/Bullets/simple_enemy_bullet.tres +++ b/Resources/Bullets/simple_enemy_bullet.tres @@ -15,6 +15,7 @@ Owner = 2 DamageType = 0 RotateSprite = false Controllable = false +Freezable = true Grazeable = true -GrazeValue = 0.2 +GrazeValue = 1.0 TimeModifiers = null diff --git a/Resources/Bullets/simple_enemy_bullet_big.tres b/Resources/Bullets/simple_enemy_bullet_big.tres index 736080d5..b5b0ba4b 100644 --- a/Resources/Bullets/simple_enemy_bullet_big.tres +++ b/Resources/Bullets/simple_enemy_bullet_big.tres @@ -15,6 +15,7 @@ Owner = 2 DamageType = 0 RotateSprite = false Controllable = false +Freezable = true Grazeable = true -GrazeValue = 0.2 +GrazeValue = 1.0 TimeModifiers = null diff --git a/Resources/Bullets/simple_ice_bullet.tres b/Resources/Bullets/simple_ice_bullet.tres index 0ffffcf4..05f62895 100644 --- a/Resources/Bullets/simple_ice_bullet.tres +++ b/Resources/Bullets/simple_ice_bullet.tres @@ -15,7 +15,9 @@ LifeTime = 10.0 DestroyOnCollision = true Owner = 1 DamageType = 3 +RotateSprite = false Controllable = false +Freezable = true Grazeable = false GrazeValue = 0.2 TimeModifiers = null diff --git a/Resources/Items/Ammo1.tres b/Resources/Items/Ammo1.tres index de1c12bb..750075ea 100644 --- a/Resources/Items/Ammo1.tres +++ b/Resources/Items/Ammo1.tres @@ -13,6 +13,7 @@ ShortName = null ItemDescription = &"Ammo for Ice-Based Weapons" ItemKey = &"ICE_AMMO" Item = 3 +Price = 0 Amount = 10 Max = 250 PickupIfMaxed = false diff --git a/Resources/Items/Blue_Keycard.tres b/Resources/Items/Blue_Keycard.tres index bde7f1aa..68f5e026 100644 --- a/Resources/Items/Blue_Keycard.tres +++ b/Resources/Items/Blue_Keycard.tres @@ -14,6 +14,7 @@ ShortName = null ItemDescription = &"Activates Blue KeyPads" ItemKey = &"BLUE_KEY" Item = 1 +Price = 0 Amount = 1 Max = 1 PickupIfMaxed = false diff --git a/Resources/Items/Cheat_Gun_Item.tres b/Resources/Items/Cheat_Gun_Item.tres index 83032962..1378733e 100644 --- a/Resources/Items/Cheat_Gun_Item.tres +++ b/Resources/Items/Cheat_Gun_Item.tres @@ -11,6 +11,7 @@ ShortName = &"CHAET" ItemDescription = &"Does massive damage" ItemKey = &"CHEAT_GUN" Item = 9 +Price = 0 WeaponData = ExtResource("2_0na1t") Amount = 1 Max = 1 diff --git a/Resources/Items/Generic_Keycard.tres b/Resources/Items/Generic_Keycard.tres index a54d6b9c..aa2dfde9 100644 --- a/Resources/Items/Generic_Keycard.tres +++ b/Resources/Items/Generic_Keycard.tres @@ -14,6 +14,7 @@ ShortName = null ItemDescription = &"Activates Gray KeyPads" ItemKey = &"GRAY_KEY" Item = 1 +Price = 0 Amount = 1 Max = 99 PickupIfMaxed = false diff --git a/Resources/Items/Green_Keycard.tres b/Resources/Items/Green_Keycard.tres index 82d241ef..bd74133a 100644 --- a/Resources/Items/Green_Keycard.tres +++ b/Resources/Items/Green_Keycard.tres @@ -14,6 +14,7 @@ ShortName = null ItemDescription = &"Activates Green KeyPads" ItemKey = &"GREEN_KEY" Item = 2 +Price = 0 Amount = 1 Max = 1 PickupIfMaxed = false diff --git a/Resources/Items/Heart_Extend_Pickup.tres b/Resources/Items/Heart_Extend_Pickup.tres index 61f7059c..7b22b23e 100644 --- a/Resources/Items/Heart_Extend_Pickup.tres +++ b/Resources/Items/Heart_Extend_Pickup.tres @@ -17,6 +17,7 @@ ShortName = null ItemDescription = &"Extends the max health" ItemKey = &"HEALTH_EXTEND" Item = 13 +Price = 0 ItemEffect = SubResource("Resource_bltl4") Amount = 1 Max = 10 diff --git a/Resources/Items/IceShotgun.tres b/Resources/Items/IceShotgun.tres index 2f2252e1..2202040b 100644 --- a/Resources/Items/IceShotgun.tres +++ b/Resources/Items/IceShotgun.tres @@ -11,6 +11,7 @@ ShortName = &"IC-27" ItemDescription = &"Shoots ice pellets in a wide spread" ItemKey = &"ICE_SHOTGUN" Item = 9 +Price = 0 WeaponData = ExtResource("2_3le6e") Amount = 1 Max = 1 diff --git a/Resources/Items/IcicleGun.tres b/Resources/Items/IcicleGun.tres index c010ffe6..82cde98a 100644 --- a/Resources/Items/IcicleGun.tres +++ b/Resources/Items/IcicleGun.tres @@ -11,6 +11,7 @@ ShortName = &"IC-9" ItemDescription = &"Cirno\'s custom gun, shoots ice pellets and never runs out of ammo" ItemKey = &"ICICLE_GUN" Item = 9 +Price = 0 WeaponData = ExtResource("1_itajb") Amount = 1 Max = 1 diff --git a/Resources/Items/Shield_Extend_Pickup.tres b/Resources/Items/Shield_Extend_Pickup.tres index 2377784f..c4dcbd4c 100644 --- a/Resources/Items/Shield_Extend_Pickup.tres +++ b/Resources/Items/Shield_Extend_Pickup.tres @@ -17,6 +17,7 @@ ShortName = null ItemDescription = &"Extends the max shield" ItemKey = &"SHIELD_EXTEND" Item = 13 +Price = 0 ItemEffect = SubResource("Resource_7h0ch") Amount = 1 Max = 10 diff --git a/Resources/Items/Spider_Bomb_Pickup.tres b/Resources/Items/Spider_Bomb_Pickup.tres index e6699c3e..cdb567b2 100644 --- a/Resources/Items/Spider_Bomb_Pickup.tres +++ b/Resources/Items/Spider_Bomb_Pickup.tres @@ -38,6 +38,7 @@ ShortName = null ItemDescription = &"A snowball packed of explosive, explodes on contact" ItemKey = &"SPIDER_BOMB" Item = 5 +Price = 0 ItemEffect = SubResource("Resource_2pgyg") WeaponData = SubResource("Resource_v5a4k") Amount = 1 diff --git a/Resources/Items/Yellow_Keycard.tres b/Resources/Items/Yellow_Keycard.tres index 2b9d1f35..a1957bde 100644 --- a/Resources/Items/Yellow_Keycard.tres +++ b/Resources/Items/Yellow_Keycard.tres @@ -14,6 +14,7 @@ ShortName = null ItemDescription = &"Opens Yellow KeyPads" ItemKey = &"YELLOW_KEY" Item = 0 +Price = 0 Amount = 1 Max = 1 PickupIfMaxed = false diff --git a/Scenes/Actors/fsm_player.tscn b/Scenes/Actors/fsm_player.tscn index 53dd73d2..34f9cbfa 100644 --- a/Scenes/Actors/fsm_player.tscn +++ b/Scenes/Actors/fsm_player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=85 format=3 uid="uid://c4pr2707hbeph"] +[gd_scene load_steps=87 format=3 uid="uid://c4pr2707hbeph"] [ext_resource type="Script" uid="uid://d2ubk5gucny6s" path="res://Scripts/Components/FSM/PlayerFSMProxy.cs" id="1_g3wua"] [ext_resource type="Script" uid="uid://bw2hakslndaxm" path="res://Scripts/Components/FSM/PlayerStateMachine.cs" id="1_mpmil"] @@ -42,6 +42,8 @@ [ext_resource type="Resource" uid="uid://clr1gln7nxa1o" path="res://Resources/Items/Power_Pickup.tres" id="40_m1iep"] [ext_resource type="Script" uid="uid://c8f4tbcjcfsu1" path="res://Scripts/Components/FSM/Player/AutoPickupModule.cs" id="41_v2m0j"] [ext_resource type="Script" uid="uid://d2r5eh3wn16bg" path="res://Scripts/Components/FSM/Player/PlayerGrazingModule.cs" id="42_awrib"] +[ext_resource type="Script" uid="uid://ru6yajru35t0" path="res://Scripts/Components/FSM/Player/FreezeModule.cs" id="43_nfq4p"] +[ext_resource type="PackedScene" uid="uid://ckfhlsboy6mfr" path="res://Scenes/Weapons/Bullets/Ice.tscn" id="44_m1iep"] [sub_resource type="CircleShape2D" id="CircleShape2D_b3hxm"] radius = 5.0 @@ -353,7 +355,7 @@ _damageReceiver = NodePath("../../DamageReceiver") _activationProvider = NodePath("../../InteractionProvider") _interactionController = NodePath("../../InteractionController") _storageModule = NodePath("../../Storage") -_moduleNodes = [NodePath("../../InteractionController"), NodePath("../../ItemUser"), NodePath("../../ConveyorBeltMover"), NodePath("../../AutoPickupModule"), NodePath("../../GrazingModule")] +_moduleNodes = [NodePath("../../InteractionController"), NodePath("../../ItemUser"), NodePath("../../ConveyorBeltMover"), NodePath("../../AutoPickupModule"), NodePath("../../GrazingModule"), NodePath("../../FreezeModule")] [node name="Cutscene" type="Node2D" parent="StateMachine" node_paths=PackedStringArray("_animationProvider")] script = ExtResource("4_22ff8") @@ -561,6 +563,14 @@ Shield = NodePath("../DamageReceiver/ShieldProvider") [node name="CollisionShape2D" type="CollisionShape2D" parent="GrazingModule"] shape = SubResource("CircleShape2D_awrib") +[node name="FreezeModule" type="Node2D" parent="." node_paths=PackedStringArray("Shield", "InputProvider")] +script = ExtResource("43_nfq4p") +ResourceCost = 5.0 +IceLife = 2.0 +IceScene = ExtResource("44_m1iep") +Shield = NodePath("../DamageReceiver/ShieldProvider") +InputProvider = NodePath("../InputProvider") + [connection signal="area_entered" from="DamageReceiver" to="DamageReceiver" method="_on_damage_hitbox_area_entered"] [connection signal="area_entered" from="InteractionProvider" to="InteractionProvider" method="_on_interaction_controller_area_entered"] [connection signal="area_exited" from="InteractionProvider" to="InteractionProvider" method="_on_interaction_controller_area_exited"] diff --git a/Scenes/Weapons/Bullets/Ice.tscn b/Scenes/Weapons/Bullets/Ice.tscn new file mode 100644 index 00000000..cbc0e199 --- /dev/null +++ b/Scenes/Weapons/Bullets/Ice.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=4 format=3 uid="uid://ckfhlsboy6mfr"] + +[ext_resource type="Script" uid="uid://csw0c6gjcmx34" path="res://Scripts/Actors/Ice.cs" id="1_lwlxi"] +[ext_resource type="Texture2D" uid="uid://gkb4es8bcqtx" path="res://ExternalMaterial/BulletFreezeCrystal/BulletFreezeCrystal.png" id="2_0qvt4"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_2ofk8"] +radius = 9.05539 + +[node name="Ice" type="Area2D"] +collision_layer = 8 +collision_mask = 136 +script = ExtResource("1_lwlxi") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_2ofk8") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("2_0qvt4") + +[connection signal="area_entered" from="." to="." method="OnAreaEntered"] diff --git a/Scripts/Actors/Ice.cs b/Scripts/Actors/Ice.cs new file mode 100644 index 00000000..51babd66 --- /dev/null +++ b/Scripts/Actors/Ice.cs @@ -0,0 +1,36 @@ +using Cirno.Scripts.Components.FSM.Player; +using Godot; + +namespace Cirno.Scripts.Actors; + +public partial class Ice : Area2D +{ + public double Life { get; set; } = 2f; + //public float FreezeRange { get; private set; } = 16f; + + public FreezeModule FreezeModule { get; set; } + + public override void _PhysicsProcess(double delta) + { + Life -= delta; + + if (Life <= 0) + { + QueueFree(); + } + + } + + private void OnAreaEntered(Area2D area) + { + if (area is not Bullet bullet) return; + if (bullet.IsFrozen) return; + if (bullet.BulletOwner is BulletOwner.Player) return; + if (!bullet.BulletInfo.Freezable) return; + + bullet.Freeze(); + var ice = bullet.CreateSibling(FreezeModule.IceScene); + ice.Life = Life; + ice.FreezeModule = FreezeModule; + } +} \ No newline at end of file diff --git a/Scripts/Actors/Ice.cs.uid b/Scripts/Actors/Ice.cs.uid new file mode 100644 index 00000000..17d20f13 --- /dev/null +++ b/Scripts/Actors/Ice.cs.uid @@ -0,0 +1 @@ +uid://csw0c6gjcmx34 diff --git a/Scripts/Bullet.cs b/Scripts/Bullet.cs index 8454b654..985b1fc3 100644 --- a/Scripts/Bullet.cs +++ b/Scripts/Bullet.cs @@ -30,6 +30,8 @@ public partial class Bullet : Area2D public bool IsGrazed { get; set; } = false; + public bool IsFrozen { get; private set; } = false; + [Signal] public delegate void OnDestroyEventHandler(); private AudioStreamPlayer2D _grazeSound; @@ -182,8 +184,7 @@ public partial class Bullet : Area2D { ApplyTimeModifiers(delta); } - - + if (BulletInfo.Controllabe) { ControlBullet(delta); @@ -273,6 +274,13 @@ public partial class Bullet : Area2D EmitSignal(SignalName.OnDestroy); QueueFree(); } + + public void Freeze() + { + IsFrozen = true; + EmitSignal(SignalName.OnDestroy); + QueueFree(); + } } public enum BulletOwner diff --git a/Scripts/Components/Actors/InputProvider.cs b/Scripts/Components/Actors/InputProvider.cs index cba09d62..17fbfa8a 100644 --- a/Scripts/Components/Actors/InputProvider.cs +++ b/Scripts/Components/Actors/InputProvider.cs @@ -18,4 +18,7 @@ public abstract partial class InputProvider : Node2D public abstract bool GetWeaponNextJustPressed(); public abstract bool GetWeaponPreviousJustPressed(); public abstract bool GetPauseJustPressed(); + + public abstract bool GetFreezeJustPressed(); + public abstract bool GetFreezePressed(); } \ No newline at end of file diff --git a/Scripts/Components/Actors/KeyboardInputProvider.cs b/Scripts/Components/Actors/KeyboardInputProvider.cs index 0228e3ba..c741acdf 100644 --- a/Scripts/Components/Actors/KeyboardInputProvider.cs +++ b/Scripts/Components/Actors/KeyboardInputProvider.cs @@ -35,6 +35,7 @@ public partial class KeyboardInputProvider : InputProvider [Export] private StringName _previousWeaponActionName = "previous_weapon"; [Export] private StringName _inventoryActionName = "inventory"; [Export] private StringName _pauseActionName = "pause"; + [Export] private StringName _freezeActionName = "Freeze"; private enum AimInputMethod { RightStick, Mouse } private AimInputMethod _lastUsedInput = AimInputMethod.RightStick; @@ -163,5 +164,15 @@ public partial class KeyboardInputProvider : InputProvider { return GetActionJustPressed(_pauseActionName); } + + public override bool GetFreezeJustPressed() + { + return GetActionJustPressed(_freezeActionName); + } + + public override bool GetFreezePressed() + { + return GetActionPressed(_freezeActionName); + } } \ No newline at end of file diff --git a/Scripts/Components/BulletSpawner.cs b/Scripts/Components/BulletSpawner.cs index 629c3be9..87321f52 100644 --- a/Scripts/Components/BulletSpawner.cs +++ b/Scripts/Components/BulletSpawner.cs @@ -99,6 +99,7 @@ public class BulletInfo public float Spread { get; set; } public bool RotateSprite { get; set; } = false; public bool Controllabe { get; set; } = false; + public bool Freezable { get; set; } = true; public PackedScene BulletScene { get; set; } public PackedScene DestructionParticlesScene { get; set; } public IBulletModifier Modifier { get; set; } diff --git a/Scripts/Components/FSM/Player/FreezeModule.cs b/Scripts/Components/FSM/Player/FreezeModule.cs new file mode 100644 index 00000000..54614b48 --- /dev/null +++ b/Scripts/Components/FSM/Player/FreezeModule.cs @@ -0,0 +1,98 @@ +using System.Collections.Generic; +using Cirno.Scripts.Actors; +using Cirno.Scripts.Components.Actors; +using Godot; + +namespace Cirno.Scripts.Components.FSM.Player; + +public partial class FreezeModule : ModuleBase +{ + [Export] public float ResourceCost { get; private set; } = 15f; + + [Export] public float FreezeRadius { get; private set; } = 64f; + [Export] public double Cooldown { get; private set; } = 0.5f; + [Export] public double IceLife { get; private set; } = 4f; + [Export] public PackedScene IceScene { get; private set; } + + [ExportGroup("Providers")] + [Export] + public ActorResourceProvider Shield { get; private set; } + + [Export] + public InputProvider InputProvider { get; private set; } + + public bool Enabled { get; set; } = false; + + private double _cooldownTimer = 0; + + public override void EnterState(PlayerState state) + { + Enabled = true; + } + + public override void ExitState(PlayerState state) + { + Enabled = false; + } + + public override void Init(IStateMachine machine) + { + + } + + public override void Process(double delta) + { + if (!Enabled) return; + // TODO: Handle cooldown + } + + public override void PhysicsProcess(double delta) + { + if (!Enabled) return; + if (InputProvider.GetFreezeJustPressed()) + { + if (Shield.CurrentResource >= ResourceCost) + { + Shield.CurrentResource -= ResourceCost; + FreezeBullets(); + } + } + } + + private void FreezeBullets() + { + var bullets = GetNearbyBullets(); + foreach (var bullet in bullets) + { + bullet.Freeze(); + var ice = bullet.CreateSibling(IceScene); + ice.Life = IceLife; + ice.FreezeModule = this; + + } + } + + private List GetNearbyBullets() + { + var nearbyBullets = new List(); + + foreach (var child in GameManager.Instance.BulletsContainer.GetChildren()) + { + if (child is not Bullet bullet) continue; + if (bullet.BulletOwner is BulletOwner.Player) + { + continue; + } + if (bullet.IsFrozen) continue; + if (!bullet.BulletInfo.Freezable) continue; + + var distance = GlobalPosition.DistanceTo(bullet.GlobalPosition); + if (distance <= FreezeRadius) + { + nearbyBullets.Add(bullet); + } + } + + return nearbyBullets; + } +} \ No newline at end of file diff --git a/Scripts/Components/FSM/Player/FreezeModule.cs.uid b/Scripts/Components/FSM/Player/FreezeModule.cs.uid new file mode 100644 index 00000000..b534817c --- /dev/null +++ b/Scripts/Components/FSM/Player/FreezeModule.cs.uid @@ -0,0 +1 @@ +uid://ru6yajru35t0 diff --git a/Scripts/Components/FSM/Player/PlayerFSMItemUseModule.cs b/Scripts/Components/FSM/Player/PlayerFSMItemUseModule.cs index 9c004b3e..62eec7c2 100644 --- a/Scripts/Components/FSM/Player/PlayerFSMItemUseModule.cs +++ b/Scripts/Components/FSM/Player/PlayerFSMItemUseModule.cs @@ -25,13 +25,11 @@ public partial class PlayerFSMItemUseModule : ModuleBase x).ToList(), Grazeable = Grazeable, GrazeValue = GrazeValue, diff --git a/project.godot b/project.godot index 6cf1553c..b4aafe25 100644 --- a/project.godot +++ b/project.godot @@ -324,6 +324,12 @@ inventory={ , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } +Freeze={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null) +, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":4,"position":Vector2(203, 23),"global_position":Vector2(219, 107),"factor":1.0,"button_index":3,"canceled":false,"pressed":true,"double_click":false,"script":null) +] +} [internationalization]