diff --git a/components/Bullets/HealingMissle.tscn b/components/Bullets/HealingMissle.tscn new file mode 100644 index 0000000..9fc1bd5 --- /dev/null +++ b/components/Bullets/HealingMissle.tscn @@ -0,0 +1,27 @@ +[gd_scene load_steps=5 format=3 uid="uid://ds6yxgj6r8f4v"] + +[ext_resource type="PackedScene" uid="uid://crtdkysmnkith" path="res://components/Abstracts/BulletBase.tscn" id="1_1wl5l"] +[ext_resource type="Texture2D" uid="uid://dpvk6pja35rdb" path="res://resources/items/apple-white.png" id="2_0jb7f"] +[ext_resource type="Script" uid="uid://d2ubbdwexom6t" path="res://scripts/Contents/Bullets/HealingMissle.gd" id="2_nxr84"] + +[sub_resource type="SpriteFrames" id="SpriteFrames_nxr84"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": ExtResource("2_0jb7f") +}], +"loop": true, +"name": &"default", +"speed": 5.0 +}] + +[node name="HealingMissle" instance=ExtResource("1_1wl5l")] +script = ExtResource("2_nxr84") +speed = 1.0 +lifeTime = 5000.0 +allowFriendlyDamage = true + +[node name="texture" parent="." index="0"] +modulate = Color(0.0068707466, 1, 0, 1) +scale = Vector2(0.44360867, 0.44360867) +sprite_frames = SubResource("SpriteFrames_nxr84") diff --git a/components/Characters/Rooster.tscn b/components/Characters/Rooster.tscn index 61dea8f..6cf793e 100644 --- a/components/Characters/Rooster.tscn +++ b/components/Characters/Rooster.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=14 format=3 uid="uid://dky8574uqc18r"] +[gd_scene load_steps=15 format=3 uid="uid://dky8574uqc18r"] [ext_resource type="PackedScene" uid="uid://cvogxi7mktumf" path="res://components/Abstracts/EntityBase.tscn" id="1_e5pl8"] [ext_resource type="Script" uid="uid://cthtupc6dtbav" path="res://scripts/Contents/Characters/Rooster.gd" id="2_oqdqd"] [ext_resource type="PackedScene" uid="uid://dldnbpubu2jgm" path="res://components/Weapons/GrassWall.tscn" id="3_0omr3"] +[ext_resource type="PackedScene" uid="uid://blwoev5sencdh" path="res://components/Weapons/Gobo.tscn" id="3_jluqw"] [ext_resource type="PackedScene" uid="uid://c0n3igy4hucrg" path="res://components/Weapons/PurpleCrystal.tscn" id="3_joj4g"] [ext_resource type="AudioStream" uid="uid://cdrevrq7n6yqa" path="res://resources/sounds/effect/Boing.mp3" id="4_66s6c"] [ext_resource type="AudioStream" uid="uid://benyec5bqni0b" path="res://resources/sounds/effect/Chomp.wav" id="4_k0yme"] @@ -59,10 +60,13 @@ metadata/_edit_vertical_guides_ = [71.0] [node name="weaponStore" parent="." index="1"] process_mode = 4 -[node name="PurpleCrystal" parent="weaponStore" index="0" instance=ExtResource("3_joj4g")] +[node name="Gobo" parent="weaponStore" index="0" instance=ExtResource("3_jluqw")] +offset_bottom = 446.0 + +[node name="PurpleCrystal" parent="weaponStore" index="1" instance=ExtResource("3_joj4g")] offset_bottom = 350.0 -[node name="GrassWall" parent="weaponStore" index="1" instance=ExtResource("3_0omr3")] +[node name="GrassWall" parent="weaponStore" index="2" instance=ExtResource("3_0omr3")] [node name="sprint" parent="sounds" index="0"] stream = ExtResource("4_66s6c") diff --git a/components/Summons/Gobo.tscn b/components/Summons/Gobo.tscn new file mode 100644 index 0000000..c313bae --- /dev/null +++ b/components/Summons/Gobo.tscn @@ -0,0 +1,46 @@ +[gd_scene load_steps=7 format=3 uid="uid://b2ilo4ag801m2"] + +[ext_resource type="PackedScene" uid="uid://cvogxi7mktumf" path="res://components/Abstracts/EntityBase.tscn" id="1_hgynr"] +[ext_resource type="Texture2D" uid="uid://xen2edbhf052" path="res://resources/characters/gobo/gobo-a.svg" id="2_e0tdx"] +[ext_resource type="Script" uid="uid://cqax27sw0wlme" path="res://scripts/Contents/Summons/Gobo.gd" id="2_ftr65"] +[ext_resource type="Texture2D" uid="uid://s12imwmfics6" path="res://resources/characters/gobo/gobo-b.svg" id="3_ftr65"] +[ext_resource type="Texture2D" uid="uid://d38bjxoowbg7t" path="res://resources/characters/gobo/gobo-c.svg" id="4_w2qsx"] + +[sub_resource type="SpriteFrames" id="SpriteFrames_0xeeo"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": ExtResource("2_e0tdx") +}], +"loop": true, +"name": &"idle", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("2_e0tdx") +}, { +"duration": 1.0, +"texture": ExtResource("3_ftr65") +}, { +"duration": 1.0, +"texture": ExtResource("4_w2qsx") +}], +"loop": true, +"name": &"walk", +"speed": 5.0 +}] + +[node name="Gobo" instance=ExtResource("1_hgynr")] +script = ExtResource("2_ftr65") +attraction = 0.0 +displayName = "Gobo" + +[node name="texture" parent="." index="3"] +sprite_frames = SubResource("SpriteFrames_0xeeo") +animation = &"walk" +frame = 2 +frame_progress = 0.92641157 + +[node name="statebar" parent="." index="4"] +position = Vector2(0, -122) diff --git a/components/Weapons/Gobo.tscn b/components/Weapons/Gobo.tscn new file mode 100644 index 0000000..db5c642 --- /dev/null +++ b/components/Weapons/Gobo.tscn @@ -0,0 +1,39 @@ +[gd_scene load_steps=4 format=3 uid="uid://blwoev5sencdh"] + +[ext_resource type="PackedScene" uid="uid://ckq2cq6m23hq3" path="res://components/Abstracts/WeaponCardBase.tscn" id="1_0udcw"] +[ext_resource type="Script" uid="uid://cbg3xkg1giv35" path="res://scripts/Contents/Weapons/Gobo.gd" id="2_7yxbe"] +[ext_resource type="Texture2D" uid="uid://xen2edbhf052" path="res://resources/characters/gobo/gobo-a.svg" id="2_tw58e"] + +[node name="Gobo" instance=ExtResource("1_0udcw")] +script = ExtResource("2_7yxbe") +avatarTexture = ExtResource("2_tw58e") +displayName = "Gobo" +quality = 4 +typeTopic = 4 +store = { +"atk": 50, +"health": 200, +"percent": 0.1 +} +storeType = { +"atk": 1, +"health": 1, +"percent": 2 +} +descriptionTemplate = "召唤[b]Gobo[/b],Gobo会自主行动,每受到$atk点伤害后会发射一枚[b]疗愈导弹[/b]。 +[b]疗愈导弹[/b]命中障碍物或友军时对其产生Gobo剩余生命值×$percent点的治疗。 +Gobo初始拥有$health点生命值。" +cooldown = 1000.0 + +[node name="avatar" parent="container/info" index="0"] +texture = ExtResource("2_tw58e") + +[node name="name" parent="container/info" index="2"] +displayName = "Gobo" +quality = 4 +typeTopic = 4 + +[node name="description" parent="container" index="2"] +text = "[center]召唤[b]Gobo[/b],Gobo会自主行动,每受到[color=cyan]50[/color]点伤害后会发射一枚[b]疗愈导弹[/b]。 +[b]疗愈导弹[/b]命中障碍物或友军时对其产生Gobo剩余生命值×[color=cyan]10.0%[/color]点的治疗。 +Gobo初始拥有[color=cyan]200[/color]点生命值。[/center]" diff --git a/resources/characters/gobo/gobo-a.svg b/resources/characters/gobo/gobo-a.svg new file mode 100644 index 0000000..a117c67 --- /dev/null +++ b/resources/characters/gobo/gobo-a.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/characters/gobo/gobo-a.svg.import b/resources/characters/gobo/gobo-a.svg.import new file mode 100644 index 0000000..56073bf --- /dev/null +++ b/resources/characters/gobo/gobo-a.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://xen2edbhf052" +path="res://.godot/imported/gobo-a.svg-324026b3e192456adada726ade96da2d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resources/characters/gobo/gobo-a.svg" +dest_files=["res://.godot/imported/gobo-a.svg-324026b3e192456adada726ade96da2d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/resources/characters/gobo/gobo-b.svg b/resources/characters/gobo/gobo-b.svg new file mode 100644 index 0000000..1622b6b --- /dev/null +++ b/resources/characters/gobo/gobo-b.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/characters/gobo/gobo-b.svg.import b/resources/characters/gobo/gobo-b.svg.import new file mode 100644 index 0000000..ef7baf1 --- /dev/null +++ b/resources/characters/gobo/gobo-b.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://s12imwmfics6" +path="res://.godot/imported/gobo-b.svg-075dcd98d32f1272ba543e817534f6fc.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resources/characters/gobo/gobo-b.svg" +dest_files=["res://.godot/imported/gobo-b.svg-075dcd98d32f1272ba543e817534f6fc.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/resources/characters/gobo/gobo-c.svg b/resources/characters/gobo/gobo-c.svg new file mode 100644 index 0000000..fe18434 --- /dev/null +++ b/resources/characters/gobo/gobo-c.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/characters/gobo/gobo-c.svg.import b/resources/characters/gobo/gobo-c.svg.import new file mode 100644 index 0000000..510d403 --- /dev/null +++ b/resources/characters/gobo/gobo-c.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d38bjxoowbg7t" +path="res://.godot/imported/gobo-c.svg-7d92174bbaa3236d452fc842786da9f3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resources/characters/gobo/gobo-c.svg" +dest_files=["res://.godot/imported/gobo-c.svg-7d92174bbaa3236d452fc842786da9f3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/resources/items/apple-white.png b/resources/items/apple-white.png new file mode 100644 index 0000000..ee4bef7 Binary files /dev/null and b/resources/items/apple-white.png differ diff --git a/resources/items/apple-white.png.import b/resources/items/apple-white.png.import new file mode 100644 index 0000000..32e61bd --- /dev/null +++ b/resources/items/apple-white.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dpvk6pja35rdb" +path="res://.godot/imported/apple-white.png-d39950409511c2e490d5c9c504fbd06c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resources/items/apple-white.png" +dest_files=["res://.godot/imported/apple-white.png-d39950409511c2e490d5c9c504fbd06c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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/scripts/Contents/Bullets/HealingMissle.gd b/scripts/Contents/Bullets/HealingMissle.gd new file mode 100644 index 0000000..7bdc218 --- /dev/null +++ b/scripts/Contents/Bullets/HealingMissle.gd @@ -0,0 +1,5 @@ +extends BulletBase +class_name HealingMissleBullet + +func ai(): + PresetBulletAI.forward(self, rotation) diff --git a/scripts/Contents/Bullets/HealingMissle.gd.uid b/scripts/Contents/Bullets/HealingMissle.gd.uid new file mode 100644 index 0000000..4561a5b --- /dev/null +++ b/scripts/Contents/Bullets/HealingMissle.gd.uid @@ -0,0 +1 @@ +uid://d2ubbdwexom6t diff --git a/scripts/Contents/Summons/Gobo.gd b/scripts/Contents/Summons/Gobo.gd new file mode 100644 index 0000000..2953bb8 --- /dev/null +++ b/scripts/Contents/Summons/Gobo.gd @@ -0,0 +1,32 @@ +extends SummonBase +class_name GoboSummon + +var percent: float = 0.0 +var healthSinceLastLaunch: float = 0 + +func initHealth(maxHealth: float): + super.initHealth(maxHealth) + healthSinceLastLaunch = maxHealth + +func register(): + fields[FieldStore.Entity.MOVEMENT_SPEED] = 1.5 + healthChanged.connect( + func(newHealth): + if healthSinceLastLaunch - newHealth >= 1: + launch() + healthSinceLastLaunch = newHealth + ) +func ai(): + var target = BulletTool.findClosetBulletCanDamage(position, get_tree(), self) + if is_instance_valid(target): + move(target.position - position) + +func launch(): + for bullet in BulletBase.generate( + ComponentManager.getBullet("HealingMissle"), + self, + position, + position.angle_to_point(EntityTool.findClosetEntity(myMaster.position, get_tree(), isPlayer(), !isPlayer(), [self]).position) + ): + if bullet is HealingMissleBullet: + bullet.baseDamage = health * percent * -1 diff --git a/scripts/Contents/Summons/Gobo.gd.uid b/scripts/Contents/Summons/Gobo.gd.uid new file mode 100644 index 0000000..ec06fc2 --- /dev/null +++ b/scripts/Contents/Summons/Gobo.gd.uid @@ -0,0 +1 @@ +uid://cqax27sw0wlme diff --git a/scripts/Contents/Weapons/Gobo.gd b/scripts/Contents/Weapons/Gobo.gd new file mode 100644 index 0000000..8d96fe7 --- /dev/null +++ b/scripts/Contents/Weapons/Gobo.gd @@ -0,0 +1,13 @@ +@tool +extends Weapon + +func update(to: int, origin: Dictionary, _entity: EntityBase): + origin["health"] += 5 * to * soulLevel + origin["percent"] += 0.02 * to * soulLevel + return origin +func attack(entity: EntityBase): + var gobo = entity.summon(ComponentManager.getSummon("Gobo")) + if gobo is GoboSummon: + gobo.percent = readStore("percent") + gobo.initHealth(readStore("health")) + return true diff --git a/scripts/Contents/Weapons/Gobo.gd.uid b/scripts/Contents/Weapons/Gobo.gd.uid new file mode 100644 index 0000000..a7aa8fb --- /dev/null +++ b/scripts/Contents/Weapons/Gobo.gd.uid @@ -0,0 +1 @@ +uid://cbg3xkg1giv35 diff --git a/scripts/Contents/Weapons/Shield.gd b/scripts/Contents/Weapons/Shield.gd index 35f14ad..53cbdca 100644 --- a/scripts/Contents/Weapons/Shield.gd +++ b/scripts/Contents/Weapons/Shield.gd @@ -7,7 +7,6 @@ func update(to: int, origin: Dictionary, _entity: EntityBase): return origin func attack(entity: EntityBase): var summon = entity.summon(ComponentManager.getSummon("Shield")) - if !summon: return true - summon.fields[FieldStore.Entity.MAX_HEALTH] = readStore("atk") - summon.health = summon.fields[FieldStore.Entity.MAX_HEALTH] + if summon: + summon.initHealth(readStore("atk")) return true diff --git a/scripts/Statemachine/BulletBase.gd b/scripts/Statemachine/BulletBase.gd index 2495bcb..faa21b9 100644 --- a/scripts/Statemachine/BulletBase.gd +++ b/scripts/Statemachine/BulletBase.gd @@ -10,7 +10,7 @@ class_name BulletBase @export var penerateDamageReduction: float = 0.0 @export var lifeDistance: float = -1 # -1表示无限距离 @export var lifeTime: float = -1 # -1表示无限时间 -@export var indisDamage: bool = false # 是否无差别伤害(不区分敌我) +@export var allowFriendlyDamage: bool = false # 是否无差别伤害(不区分敌我) @export var canDamageSelf: bool = false # 是否可以伤害发射者 @export var autoSpawnAnimation: bool = false @export var autoLoopAnimation: bool = false diff --git a/scripts/Statemachine/EntityBase.gd b/scripts/Statemachine/EntityBase.gd index 9f9172d..f600f1e 100644 --- a/scripts/Statemachine/EntityBase.gd +++ b/scripts/Statemachine/EntityBase.gd @@ -200,6 +200,10 @@ func _physics_process(_delta: float) -> void: trailParticle.emitting = trailing # 通用方法 +func initHealth(maxHealth: float): + fields[FieldStore.Entity.MAX_HEALTH] = maxHealth + health = maxHealth + statebar.forceSync() func rebuildWeaponIcons(): if isPlayer(): for i in UIState.skillIconContainer.get_children(): diff --git a/scripts/Tools/BulletTool.gd b/scripts/Tools/BulletTool.gd index 1bfaa25..4fa0c13 100644 --- a/scripts/Tools/BulletTool.gd +++ b/scripts/Tools/BulletTool.gd @@ -8,9 +8,12 @@ static func fromArea(area: Area2D) -> BulletBase: static func canDamage(bullet: BulletBase, target: EntityBase) -> bool: if !bullet or !target or !bullet.launcher: return false if target.currentInvinsible: return false - if !bullet.canDamageSelf && target == bullet.launcher: return false if !GameRule.allowFriendlyFire: - if target.isPlayer() == bullet.launcher.isPlayer() and bullet.launcher.currentFocusedBoss != target: return false + if target.isPlayer() == bullet.launcher.isPlayer() and bullet.launcher.currentFocusedBoss != target and !bullet.allowFriendlyDamage: + return false + if !bullet.canDamageSelf: + if target == bullet.launcher: + return false return true static func findClosetBullet(to: Vector2, fromTree: SceneTree) -> BulletBase: var result: BulletBase = null