mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 08:55:35 +00:00
Destroyable chests
This commit is contained in:
parent
f1f542efc4
commit
80e0eda977
14 changed files with 253 additions and 27 deletions
|
|
@ -1,8 +1,10 @@
|
|||
using Godot;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Cirno.Scripts;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Godot.Collections;
|
||||
|
||||
public partial class Barrel : Area2D, IDestructible
|
||||
{
|
||||
|
|
@ -19,6 +21,7 @@ public partial class Barrel : Area2D, IDestructible
|
|||
[Export] public BulletResource ExplosionData { get; set; }
|
||||
|
||||
[Export] public BulletOwner BulletGroup { get; set; } = BulletOwner.None;
|
||||
[Export] public Array<DamageResistance> DamageResistances { get; set; } = [];
|
||||
|
||||
[ExportCategory("On Death Activation")]
|
||||
[Export]
|
||||
|
|
@ -136,7 +139,9 @@ public partial class Barrel : Area2D, IDestructible
|
|||
{
|
||||
if (_isDestroyed || Indestructible) return;
|
||||
|
||||
_currentHealth -= damage;
|
||||
var dmg = DamageResistances.Aggregate(damage, (current, resistance) => current * resistance.CalculateDamage(current, damageType));
|
||||
|
||||
_currentHealth -= dmg;
|
||||
if (_currentHealth > 0) return;
|
||||
_isDestroyed = true;
|
||||
Explode();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
[gd_scene load_steps=12 format=3 uid="uid://djf0y08ix66fn"]
|
||||
[gd_scene load_steps=16 format=3 uid="uid://djf0y08ix66fn"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cqh7bh0s374ac" path="res://Scripts/Chest.cs" id="1_cwpn7"]
|
||||
[ext_resource type="Texture2D" uid="uid://qeh4ai8h6sw5" path="res://Sprites/Chest.png" id="2_w7a1a"]
|
||||
[ext_resource type="Script" uid="uid://cqwvssstkrdmw" path="res://Scripts/Components/Actors/ActorResourceProvider.cs" id="3_s8kek"]
|
||||
[ext_resource type="Script" uid="uid://cq3hkweplldbr" path="res://Scripts/Components/Actors/GenericDamageReceiver.cs" id="3_u7mm1"]
|
||||
[ext_resource type="PackedScene" uid="uid://b57ep58h4bs3l" path="res://Scenes/Props/Chest_Broken.tscn" id="4_7lp3q"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_ihal6"]
|
||||
radius = 16.0
|
||||
|
|
@ -74,6 +77,9 @@ animations = [{
|
|||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_isrvb"]
|
||||
size = Vector2(12, 10)
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_7lp3q"]
|
||||
radius = 7.0
|
||||
|
||||
[node name="Chest" type="Area2D" groups=["Interactable"]]
|
||||
collision_layer = 4
|
||||
collision_mask = 2
|
||||
|
|
@ -96,3 +102,20 @@ gravity_scale = 0.0
|
|||
[node name="CollisionShape2D" type="CollisionShape2D" parent="RigidBody2D"]
|
||||
position = Vector2(0, -3)
|
||||
shape = SubResource("RectangleShape2D_isrvb")
|
||||
|
||||
[node name="DamageReceiver" type="Area2D" parent="." node_paths=PackedStringArray("HealthProvider")]
|
||||
collision_layer = 64
|
||||
collision_mask = 136
|
||||
script = ExtResource("3_u7mm1")
|
||||
HealthProvider = NodePath("Health")
|
||||
Debris = ExtResource("4_7lp3q")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="DamageReceiver"]
|
||||
shape = SubResource("CircleShape2D_7lp3q")
|
||||
|
||||
[node name="Health" type="Node2D" parent="DamageReceiver"]
|
||||
script = ExtResource("3_s8kek")
|
||||
ResourceName = "Health"
|
||||
MaxResource = 8.0
|
||||
|
||||
[connection signal="area_entered" from="DamageReceiver" to="DamageReceiver" method="_on_damage_hitbox_area_entered"]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,15 @@
|
|||
[gd_scene load_steps=6 format=3 uid="uid://clyyl3jgpfoo7"]
|
||||
[gd_scene load_steps=8 format=3 uid="uid://clyyl3jgpfoo7"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cpx2fxtumgmud" path="res://Scenes/Barrel.cs" id="1_gn5xq"]
|
||||
[ext_resource type="Script" uid="uid://ddsqqfx1usc3j" path="res://Scripts/Resources/DamageResistance.cs" id="2_n641h"]
|
||||
[ext_resource type="Texture2D" uid="uid://d2f16ke8c7vwx" path="res://Sprites/Barrel.png" id="3_c3t2t"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_c3bn4"]
|
||||
script = ExtResource("2_n641h")
|
||||
DamageType = 4
|
||||
Attribute = 3
|
||||
metadata/_custom_type_script = "uid://ddsqqfx1usc3j"
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_2ewfl"]
|
||||
size = Vector2(11, 14)
|
||||
|
||||
|
|
@ -13,13 +20,14 @@ region = Rect2(16, 0, 16, 16)
|
|||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ss2y0"]
|
||||
size = Vector2(11, 14)
|
||||
|
||||
[node name="Barrel" type="Area2D" groups=["Destroyable"]]
|
||||
[node name="BrokenBarrel" type="Area2D" groups=["Destroyable"]]
|
||||
collision_layer = 64
|
||||
collision_mask = 10
|
||||
script = ExtResource("1_gn5xq")
|
||||
Health = 2.0
|
||||
ExplosionRadius = 0.0
|
||||
ExplosionDamage = 0.0
|
||||
DamageResistances = [SubResource("Resource_c3bn4")]
|
||||
metadata/_edit_group_ = true
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
|
|
|
|||
53
Scenes/Props/Chest_Broken.tscn
Normal file
53
Scenes/Props/Chest_Broken.tscn
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://b57ep58h4bs3l"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cpx2fxtumgmud" path="res://Scenes/Barrel.cs" id="1_v36o1"]
|
||||
[ext_resource type="Texture2D" uid="uid://qeh4ai8h6sw5" path="res://Sprites/Chest.png" id="2_v36o1"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_2ewfl"]
|
||||
size = Vector2(11, 14)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_v36o1"]
|
||||
atlas = ExtResource("2_v36o1")
|
||||
region = Rect2(32, 0, 16, 16)
|
||||
|
||||
[sub_resource type="SpriteFrames" id="SpriteFrames_ejqcg"]
|
||||
animations = [{
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_v36o1")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"default",
|
||||
"speed": 5.0
|
||||
}]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ss2y0"]
|
||||
size = Vector2(11, 14)
|
||||
|
||||
[node name="Broken Chest" type="Area2D" groups=["Destroyable"]]
|
||||
collision_layer = 64
|
||||
collision_mask = 10
|
||||
script = ExtResource("1_v36o1")
|
||||
Indestructible = true
|
||||
Health = 2.0
|
||||
ExplosionRadius = 0.0
|
||||
ExplosionDamage = 0.0
|
||||
metadata/_edit_group_ = true
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
visible = false
|
||||
position = Vector2(0.5, -1)
|
||||
shape = SubResource("RectangleShape2D_2ewfl")
|
||||
|
||||
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
|
||||
sprite_frames = SubResource("SpriteFrames_ejqcg")
|
||||
|
||||
[node name="RigidBody2D" type="RigidBody2D" parent="."]
|
||||
collision_layer = 64
|
||||
collision_mask = 10
|
||||
gravity_scale = 0.0
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="RigidBody2D"]
|
||||
visible = false
|
||||
position = Vector2(0.5, -1)
|
||||
shape = SubResource("RectangleShape2D_ss2y0")
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,8 +1,11 @@
|
|||
using Godot;
|
||||
using System.Linq;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace Cirno.Scripts.Components.Actors;
|
||||
|
||||
public partial class DamageReceiverActorModule : ActorModule
|
||||
public partial class DamageReceiverActorModule : ActorModule, IHittable
|
||||
{
|
||||
protected Actor _actor;
|
||||
|
||||
|
|
@ -14,6 +17,8 @@ public partial class DamageReceiverActorModule : ActorModule
|
|||
|
||||
[Export] public BulletOwner BulletGroup { get; set; } = BulletOwner.None;
|
||||
|
||||
[Export] public Array<DamageResistance> DamageResistances { get; set; } = [];
|
||||
|
||||
public override void Init(Actor actor)
|
||||
{
|
||||
_actor = actor;
|
||||
|
|
@ -42,14 +47,14 @@ public partial class DamageReceiverActorModule : ActorModule
|
|||
|
||||
if (BulletGroup is BulletOwner.None)
|
||||
{
|
||||
this.Hit(bullet.Damage);
|
||||
this.Hit(bullet.Damage, bullet.DamageType);
|
||||
bullet.RequestCollisionDestruction();
|
||||
return;
|
||||
}
|
||||
|
||||
if (bullet.BulletInfo.Owner == BulletGroup) return;
|
||||
|
||||
this.Hit(bullet.Damage);
|
||||
this.Hit(bullet.Damage, bullet.DamageType);
|
||||
bullet.RequestCollisionDestruction();
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +63,9 @@ public partial class DamageReceiverActorModule : ActorModule
|
|||
if (_actor.IsDestroyed) return;
|
||||
if (Invulnerable) return;
|
||||
|
||||
HealthProvider.CurrentResource -= damage;
|
||||
var dmg = DamageResistances.Aggregate(damage, (current, resistance) => current * resistance.CalculateDamage(current, damageType));
|
||||
|
||||
HealthProvider.CurrentResource -= dmg;
|
||||
}
|
||||
|
||||
protected void OnDeath()
|
||||
|
|
|
|||
65
Scripts/Components/Actors/GenericDamageReceiver.cs
Normal file
65
Scripts/Components/Actors/GenericDamageReceiver.cs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
using System.Linq;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace Cirno.Scripts.Components.Actors;
|
||||
|
||||
public partial class GenericDamageReceiver : Area2D, IHittable
|
||||
{
|
||||
[Export] public ActorResourceProvider HealthProvider { get; private set; }
|
||||
|
||||
[Export] public bool Invulnerable { get; private set; } = false;
|
||||
|
||||
[Export] public BulletOwner BulletGroup { get; set; } = BulletOwner.None;
|
||||
|
||||
[Export] public PackedScene Debris { get; set; }
|
||||
|
||||
[Export] public Array<DamageResistance> DamageResistances { get; set; } = [];
|
||||
|
||||
private Node2D _parent;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_parent = GetParent<Node2D>();
|
||||
HealthProvider.FillResource();
|
||||
HealthProvider.ResourceDepleted += OnDeath;
|
||||
}
|
||||
|
||||
private void _on_damage_hitbox_area_entered(Area2D area)
|
||||
{
|
||||
if (Invulnerable) return;
|
||||
if (area is not Bullet bullet) return;
|
||||
|
||||
if (BulletGroup is BulletOwner.None)
|
||||
{
|
||||
this.Hit(bullet.Damage, bullet.DamageType);
|
||||
bullet.RequestCollisionDestruction();
|
||||
return;
|
||||
}
|
||||
|
||||
if (bullet.BulletInfo.Owner == BulletGroup) return;
|
||||
|
||||
this.Hit(bullet.Damage, bullet.DamageType);
|
||||
bullet.RequestCollisionDestruction();
|
||||
}
|
||||
|
||||
public void Hit(float damage, DamageType damageType = DamageType.Neutral)
|
||||
{
|
||||
if (Invulnerable) return;
|
||||
|
||||
var dmg = DamageResistances.Aggregate(damage, (current, resistance) => current * resistance.CalculateDamage(current, damageType));
|
||||
|
||||
HealthProvider.CurrentResource -= dmg;
|
||||
}
|
||||
|
||||
private void OnDeath()
|
||||
{
|
||||
if (Debris is not null)
|
||||
{
|
||||
_parent.CreateSibling<Node2D>(Debris);
|
||||
}
|
||||
|
||||
_parent.QueueFree();
|
||||
}
|
||||
}
|
||||
1
Scripts/Components/Actors/GenericDamageReceiver.cs.uid
Normal file
1
Scripts/Components/Actors/GenericDamageReceiver.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cq3hkweplldbr
|
||||
6
Scripts/Components/Actors/IHittable.cs
Normal file
6
Scripts/Components/Actors/IHittable.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
namespace Cirno.Scripts.Components.Actors;
|
||||
|
||||
public interface IHittable
|
||||
{
|
||||
public void Hit(float damage, DamageType damageType = DamageType.Neutral);
|
||||
}
|
||||
9
Scripts/Enums/DamageAttribute.cs
Normal file
9
Scripts/Enums/DamageAttribute.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
namespace Cirno.Scripts.Enums;
|
||||
|
||||
public enum DamageAttribute
|
||||
{
|
||||
Neutral,
|
||||
Resist,
|
||||
Weak,
|
||||
Immune,
|
||||
}
|
||||
37
Scripts/Resources/DamageResistance.cs
Normal file
37
Scripts/Resources/DamageResistance.cs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using Cirno.Scripts.Enums;
|
||||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Resources;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class DamageResistance : Resource
|
||||
{
|
||||
[Export]
|
||||
public DamageType DamageType { get; set; } = DamageType.Neutral;
|
||||
|
||||
[Export]
|
||||
public DamageAttribute Attribute { get; set; } = DamageAttribute.Neutral;
|
||||
|
||||
public float CalculateDamage(float damage, DamageType incomingDamageType)
|
||||
{
|
||||
if (DamageType != incomingDamageType) return 1;
|
||||
|
||||
switch (Attribute)
|
||||
{
|
||||
case DamageAttribute.Neutral:
|
||||
return 1;
|
||||
break;
|
||||
case DamageAttribute.Resist:
|
||||
return 0.5f;
|
||||
break;
|
||||
case DamageAttribute.Weak:
|
||||
return 2;
|
||||
break;
|
||||
case DamageAttribute.Immune:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
1
Scripts/Resources/DamageResistance.cs.uid
Normal file
1
Scripts/Resources/DamageResistance.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://ddsqqfx1usc3j
|
||||
BIN
Sprites/Chest.aseprite
(Stored with Git LFS)
BIN
Sprites/Chest.aseprite
(Stored with Git LFS)
Binary file not shown.
BIN
Sprites/Chest.png
(Stored with Git LFS)
BIN
Sprites/Chest.png
(Stored with Git LFS)
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue