diff --git a/components/Bullets/FireScan.tscn b/components/Bullets/FireScan.tscn index dc3873a..6677fee 100644 --- a/components/Bullets/FireScan.tscn +++ b/components/Bullets/FireScan.tscn @@ -1,15 +1,17 @@ [gd_scene load_steps=4 format=3 uid="uid://db2cbgyyjpydp"] [ext_resource type="PackedScene" uid="uid://crtdkysmnkith" path="res://components/Abstracts/BulletBase.tscn" id="1_cqre5"] -[ext_resource type="Script" path="res://scripts/Contents/Bullets/FireScan.gd" id="2_qprdp"] +[ext_resource type="Script" uid="uid://dlg4g03ppdd2x" path="res://scripts/Contents/Bullets/FireScan.gd" id="2_qprdp"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_4qcsn"] -size = Vector2(50, 50) +size = Vector2(10, 200) [node name="FireScan" instance=ExtResource("1_cqre5")] script = ExtResource("2_qprdp") displayName = "狱炎" -lifeDistance = 200.0 +speed = 15.0 +damage = 15.0 +lifeDistance = 500.0 [node name="hitbox" parent="." index="1"] shape = SubResource("RectangleShape2D_4qcsn") diff --git a/components/Bullets/FoxZhua.tscn b/components/Bullets/FoxZhua.tscn new file mode 100644 index 0000000..8c8920f --- /dev/null +++ b/components/Bullets/FoxZhua.tscn @@ -0,0 +1,223 @@ +[gd_scene load_steps=11 format=3 uid="uid://btqtch0v58e7h"] + +[ext_resource type="PackedScene" uid="uid://crtdkysmnkith" path="res://components/Abstracts/BulletBase.tscn" id="1_461id"] +[ext_resource type="Texture2D" uid="uid://ddvmfyk2g4r1m" path="res://resources/bullets/fox-zhua/zhua.webp" id="2_45k2a"] +[ext_resource type="Script" uid="uid://e2doeocb745a" path="res://scripts/Contents/Bullets/FoxZhua.gd" id="2_rl21b"] + +[sub_resource type="SpriteFrames" id="SpriteFrames_rl21b"] + +[sub_resource type="Animation" id="Animation_45k2a"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:scale") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0.5, 0.5)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath(".:modulate") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(1, 1, 1, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath(".:rotation") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [-0.7853982] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("%hitbox:disabled") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("hand:position") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(50, 0)] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("%texture/..:canTrace") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} + +[sub_resource type="Animation" id="Animation_oinqg"] +resource_name = "destroy" +length = 0.5 +step = 0.1 + +[sub_resource type="Animation" id="Animation_ynxlt"] +resource_name = "loop" +loop_mode = 1 +step = 0.1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 6.28319] +} + +[sub_resource type="Animation" id="Animation_kmogx"] +resource_name = "spawn" +length = 2.0 +step = 0.05 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:scale") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.3, 1.2, 1.4, 1.6, 2), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 0, +"values": [Vector2(0.5, 0.5), Vector2(1, 1), Vector2(1, 1), Vector2(3.5, 3.5), Vector2(3.5, 3.5), Vector2(0.5, 0.5)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath(".:modulate") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.2, 1.6, 2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 0, +"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath(".:rotation") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 1.4, 1.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [-0.7853982, -0.7853982, 0.7853981633974483] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("%hitbox:disabled") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 1.4, 1.6, 2), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [true, false, false, true] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("hand:position") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(50, 0), Vector2(100, 50)] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("%texture/..:canTrace") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, false] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_45k2a"] +_data = { +&"RESET": SubResource("Animation_45k2a"), +&"destroy": SubResource("Animation_oinqg"), +&"loop": SubResource("Animation_ynxlt"), +&"spawn": SubResource("Animation_kmogx") +} + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_45k2a"] +radius = 174.0 +height = 524.0 + +[node name="FoxZhua" instance=ExtResource("1_461id")] +script = ExtResource("2_rl21b") +canTrace = true +displayName = "爪" +damage = 15.0 +penerate = 1.0 +autoSpawnAnimation = true +freeAfterSpawn = true + +[node name="texture" parent="." index="0"] +modulate = Color(1, 1, 1, 0) +rotation = -0.7853982 +scale = Vector2(0.5, 0.5) +sprite_frames = SubResource("SpriteFrames_rl21b") + +[node name="animator" parent="texture" index="0"] +libraries = { +&"": SubResource("AnimationLibrary_45k2a") +} + +[node name="hand" type="Sprite2D" parent="texture" index="1"] +position = Vector2(50, 0) +texture = ExtResource("2_45k2a") + +[node name="hitbox" parent="." index="1"] +position = Vector2(267, -1) +rotation = 1.5707964 +shape = SubResource("CapsuleShape2D_45k2a") +disabled = true diff --git a/components/Characters/Chick.tscn b/components/Characters/Chick.tscn index ce48de3..6dc3283 100644 --- a/components/Characters/Chick.tscn +++ b/components/Characters/Chick.tscn @@ -43,15 +43,15 @@ animations = [{ }] [sub_resource type="RectangleShape2D" id="RectangleShape2D_x766l"] -size = Vector2(57, 62) +size = Vector2(57, 114) [sub_resource type="CircleShape2D" id="CircleShape2D_w0sit"] -radius = 37.054016 +radius = 61.03278 [node name="Chick" instance=ExtResource("1_goqmy")] script = ExtResource("2_r6bub") isBoss = true -displayName = "小鸡" +displayName = "狐狸" drops = Array[int]([0, 1]) dropCounts = Array[Vector2]([Vector2(10, 30), Vector2(15, 50)]) appleCount = Vector2i(2, 4) @@ -78,28 +78,31 @@ sprite_frames = SubResource("SpriteFrames_xji3d") animation = &"walk" [node name="staticAnimation" parent="texture" index="1"] -position = Vector2(0, -39) -scale = Vector2(0.42847547, 0.42847547) +position = Vector2(0, -94) +scale = Vector2(0.72807497, 0.72807497) sprite_frames = SubResource("SpriteFrames_x766l") animation = &"idle" [node name="hitbox" parent="texture/hurtbox" index="0"] -position = Vector2(-0.5, -51) +position = Vector2(-0.5, -113) shape = SubResource("RectangleShape2D_x766l") [node name="hitbox2" type="CollisionShape2D" parent="texture/hurtbox" index="1"] -position = Vector2(73, -76) +position = Vector2(117, -149) shape = SubResource("CircleShape2D_w0sit") [node name="normal" type="Node2D" parent="texture/weapons" index="0"] -position = Vector2(79, -63) +position = Vector2(134, -130) [node name="firepot" parent="texture/weapons/normal" index="0" instance=ExtResource("6_kvx3n")] unique_name_in_owner = true +[node name="foot" type="Node2D" parent="texture/weapons" index="1"] +position = Vector2(56, 28) + [node name="trailParticle" parent="texture" index="7"] position = Vector2(1, -50) [node name="statebar" parent="." index="4" node_paths=PackedStringArray("entity")] -position = Vector2(0, -167) +position = Vector2(0, -294) entity = NodePath("..") diff --git a/components/Effects/FirePot.tscn b/components/Effects/FirePot.tscn index 31171ca..bf710b0 100644 --- a/components/Effects/FirePot.tscn +++ b/components/Effects/FirePot.tscn @@ -1,30 +1,23 @@ -[gd_scene load_steps=13 format=3 uid="uid://dny25qkcvtaa2"] +[gd_scene load_steps=11 format=3 uid="uid://dny25qkcvtaa2"] [ext_resource type="PackedScene" uid="uid://bcvuuy2m0pke0" path="res://components/Abstracts/EffectBase.tscn" id="1_k7ukc"] [sub_resource type="Curve" id="Curve_ohc88"] -_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] -point_count = 2 +_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.2, 1), 0.0, 0.0, 0, 0, Vector2(0.5, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 4 [sub_resource type="CurveTexture" id="CurveTexture_6awim"] curve = SubResource("Curve_ohc88") [sub_resource type="Gradient" id="Gradient_14cxb"] -colors = PackedColorArray(0.780392, 0.498039, 0, 1, 1, 0, 0, 1) +offsets = PackedFloat32Array(0.5, 1) +colors = PackedColorArray(1, 1, 1, 1, 0, 0.6366434, 1, 1) [sub_resource type="GradientTexture1D" id="GradientTexture1D_2p6rn"] gradient = SubResource("Gradient_14cxb") -[sub_resource type="Gradient" id="Gradient_g8be5"] -offsets = PackedFloat32Array(0, 0.5, 1) -colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1) - -[sub_resource type="GradientTexture1D" id="GradientTexture1D_miml8"] -gradient = SubResource("Gradient_g8be5") - [sub_resource type="Curve" id="Curve_iaern"] -min_value = -200.0 -max_value = 200.0 +_limits = [-200.0, 200.0, 0.0, 1.0] _data = [Vector2(0, -200), 0.0, 0.0, 0, 0, Vector2(1, 200), 0.0, 0.0, 0, 0] point_count = 2 @@ -40,24 +33,27 @@ curve = SubResource("Curve_qy5ym") [sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_pah3d"] particle_flag_disable_z = true +emission_shape = 1 +emission_sphere_radius = 50.0 angle_min = 1.07288e-05 angle_max = 360.0 -spread = 15.0 +spread = 5.0 initial_velocity_min = 10.0 initial_velocity_max = 500.0 -gravity = Vector3(0, 0, 0) +gravity = Vector3(980, 0, 0) linear_accel_min = -2.23517e-06 linear_accel_max = -2.23517e-06 linear_accel_curve = SubResource("CurveTexture_1flsn") -scale_min = 2.0 -scale_max = 12.0 +scale_min = 4.0 +scale_max = 16.0 scale_over_velocity_curve = SubResource("CurveTexture_wcx7i") -color_ramp = SubResource("GradientTexture1D_miml8") color_initial_ramp = SubResource("GradientTexture1D_2p6rn") alpha_curve = SubResource("CurveTexture_6awim") [node name="FirePot" instance=ExtResource("1_k7ukc")] +metadata/_edit_vertical_guides_ = [808.0] -[node name="particles" parent="." index="0"] -amount = 50 +[node name="particles" parent="." index="1"] +amount = 100 +local_coords = true process_material = SubResource("ParticleProcessMaterial_pah3d") diff --git a/resources/bullets/fox-zhua/zhua.webp b/resources/bullets/fox-zhua/zhua.webp new file mode 100644 index 0000000..7a7e5dc Binary files /dev/null and b/resources/bullets/fox-zhua/zhua.webp differ diff --git a/resources/bullets/fox-zhua/zhua.webp.import b/resources/bullets/fox-zhua/zhua.webp.import new file mode 100644 index 0000000..0b587cb --- /dev/null +++ b/resources/bullets/fox-zhua/zhua.webp.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ddvmfyk2g4r1m" +path="res://.godot/imported/zhua.webp-2136658e701e8dcc0efd32c81ae003b3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resources/bullets/fox-zhua/zhua.webp" +dest_files=["res://.godot/imported/zhua.webp-2136658e701e8dcc0efd32c81ae003b3.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/AIPresets/Bullet.gd b/scripts/Contents/AIPresets/Bullet.gd index 3f9df46..5c3466f 100644 --- a/scripts/Contents/AIPresets/Bullet.gd +++ b/scripts/Contents/AIPresets/Bullet.gd @@ -17,3 +17,5 @@ static func faceToMouse(bullet: BulletBase): bullet.rotation = bullet.position.angle_to_point(bullet.get_global_mouse_position()) static func selfRotate(bullet: BulletBase, speed: float): bullet.rotation += deg_to_rad(speed) +static func lerpPosition(bullet: BulletBase, target: Vector2, speed: float): + bullet.position = bullet.position.lerp(target, speed) diff --git a/scripts/Contents/Bullets/FireScan.gd b/scripts/Contents/Bullets/FireScan.gd index 81660c0..79feb1d 100644 --- a/scripts/Contents/Bullets/FireScan.gd +++ b/scripts/Contents/Bullets/FireScan.gd @@ -1,9 +1,6 @@ extends BulletBase class_name FireScan -func register(): - speed = 10 - damage = 20 - func ai(): PresetBulletAI.forward(self, rotation) + damage = (1 - lifeDistancePercent()) * originalDamage diff --git a/scripts/Contents/Bullets/FoxZhua.gd b/scripts/Contents/Bullets/FoxZhua.gd new file mode 100644 index 0000000..c882e7f --- /dev/null +++ b/scripts/Contents/Bullets/FoxZhua.gd @@ -0,0 +1,7 @@ +extends BulletBase + +@export var canTrace: bool = true + +func ai(): + if canTrace: + PresetBulletAI.lerpPosition(self, launcher.currentFocusedBoss.getTrackingAnchor() - Vector2(0, 200), 0.1) diff --git a/scripts/Contents/Bullets/FoxZhua.gd.uid b/scripts/Contents/Bullets/FoxZhua.gd.uid new file mode 100644 index 0000000..3ff8c3e --- /dev/null +++ b/scripts/Contents/Bullets/FoxZhua.gd.uid @@ -0,0 +1 @@ +uid://e2doeocb745a diff --git a/scripts/Contents/Characters/Chick.gd b/scripts/Contents/Characters/Chick.gd index 752850e..5fde0dd 100644 --- a/scripts/Contents/Characters/Chick.gd +++ b/scripts/Contents/Characters/Chick.gd @@ -10,15 +10,17 @@ func register(): attackCooldownMap[1] = 12000 attackCooldownMap[2] = 2000 attackCooldownMap[3] = 3000 + attackCooldownMap[4] = 4000 sprintMultiplier = 50 func spawn(): texture.play("walk") func ai(): + tryAttack(4) PresetEntityAI.follow(self, currentFocusedBoss, 0) - PresetEntityAI.distanceAttack(self, currentFocusedBoss, 0, 200, 2) - PresetEntityAI.distanceAttack(self, currentFocusedBoss, 200, 700, 1) - PresetEntityAI.distanceAction(self, currentFocusedBoss, 700, INF, + PresetEntityAI.distanceAttack(self, currentFocusedBoss, 0, 500, 2) + PresetEntityAI.distanceAttack(self, currentFocusedBoss, 500, 1000, 1) + PresetEntityAI.distanceAction(self, currentFocusedBoss, 1000, INF, func(): PresetEntityAI.weightAttack(self, [0, 3], [5, 1], func(index): return index == 3) ) @@ -33,13 +35,15 @@ func attack(type): BulletBase.generate(ComponentManager.getBullet("ChickLaser"), self, texture.global_position, deg_to_rad(360.0 / laserCount * i)) elif type == 2: var weaponPos = findWeaponAnchor("normal") - var target = weaponPos.angle_to_point(currentFocusedBoss.position) + var target = weaponPos.angle_to_point(currentFocusedBoss.getTrackingAnchor()) firepot.global_rotation = target firepot.shot() BulletBase.generate(ComponentManager.getBullet("FireScan"), self, weaponPos, target) elif type == 3: BulletBase.generate(ComponentManager.getBullet("ChickSprint"), self, position, 0) trySprint() + elif type == 4: + BulletBase.generate(ComponentManager.getBullet("FoxZhua"), self, findWeaponAnchor("foot"), deg_to_rad(90)) return true func sprint(): move((currentFocusedBoss.position - position).normalized() * sprintMultiplier, true) diff --git a/scripts/Contents/Wave.gd b/scripts/Contents/Wave.gd index 2d6b80b..dbcecb3 100644 --- a/scripts/Contents/Wave.gd +++ b/scripts/Contents/Wave.gd @@ -66,11 +66,19 @@ static func create( wave.to = to_ wave.per = per_ return wave +static func hasBoss() -> bool: + for wave in data: + if canSpawn(wave): + if wave.isBoss: + return true + return false +static func canSpawn(wave: Wave) -> bool: + return wave.from <= current and wave.to >= current and int(current - wave.from) % wave.per == 0 static func entityCountOf(wave: Wave) -> int: - if wave.from <= current and wave.to >= current and int(current - wave.from) % wave.per == 0: + if canSpawn(wave): if wave.isBoss: return 1 - else: + elif !hasBoss(): return randi_range(ceil(wave.minCount), floor(wave.maxCount * (1 + GameRule.entityCountBoostPerWave * current))) return 0 static func spawn() -> Array: diff --git a/scripts/Statemachine/BulletBase.gd b/scripts/Statemachine/BulletBase.gd index 2474777..199378a 100644 --- a/scripts/Statemachine/BulletBase.gd +++ b/scripts/Statemachine/BulletBase.gd @@ -30,9 +30,11 @@ var destroying: bool = false var isChildSplit: bool = false var isChildRefract: bool = false var initialSpeed: float = 0 +var originalDamage: float = 0 func _ready(): initialSpeed = speed + originalDamage = damage if launcher.isSummon(): launcherSummoned = launcher launcher = launcher.myMaster @@ -99,6 +101,10 @@ func fullPenerate(): return penerate + launcher.fields.get(FieldStore.Entity.PENERATE) + GameRule.penerateRateInfluenceByLuckValue * launcher.fields[FieldStore.Entity.LUCK_VALUE] func timeLived(): return WorldManager.getTime() - spawnInWhen +func distanceLived(): + return position.distance_to(spawnInWhere) +func lifeDistancePercent(): + return distanceLived() / lifeDistance func dotLoop(): if await applyDot(): await TickTool.until(func(): return !UIState.currentPanel)