The projectile weapon allows the projectile queue to be fired sequentially.

抛射体武器,允许循序发射抛射体队列了。
This commit is contained in:
Cold-Mint 2024-08-11 23:29:23 +08:00
parent 05ac2dec60
commit ef58f3885b
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
8 changed files with 90 additions and 18 deletions

View File

@ -34,6 +34,7 @@ collision_layer = 64
collision_mask = 38 collision_mask = 38
script = ExtResource("1_ubaid") script = ExtResource("1_ubaid")
CharacterName = "character_evil_crow" CharacterName = "character_evil_crow"
CanMutateAfterDeath = false
MaxHp = 50 MaxHp = 50
CampId = "Mazoku" CampId = "Mazoku"

View File

@ -0,0 +1,39 @@
[gd_scene load_steps=5 format=3 uid="uid://bdxgx5vcof8em"]
[ext_resource type="Script" path="res://scripts/projectile/Projectile.cs" id="1_ib3qh"]
[ext_resource type="Texture2D" uid="uid://b1twcink38sh0" path="res://sprites/Player.png" id="2_dxg46"]
[sub_resource type="CircleShape2D" id="CircleShape2D_dgro2"]
[sub_resource type="CircleShape2D" id="CircleShape2D_8117d"]
radius = 11.0
[node name="curseOfTheUndead" type="CharacterBody2D"]
collision_layer = 0
collision_mask = 0
script = ExtResource("1_ib3qh")
Life = 5000
Durability = 1.0
MaxDamage = 3
MinDamage = 10
DamageType = 2
KnockbackForce = Vector2(2, -3)
Speed = 500.0
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_dgro2")
[node name="CollisionDetectionArea" type="Area2D" parent="."]
collision_layer = 16
collision_mask = 78
[node name="CollisionShape2D" type="CollisionShape2D" parent="CollisionDetectionArea"]
shape = SubResource("CircleShape2D_8117d")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
bus = &"SoundEffect"
area_mask = 16
[node name="Player" type="Sprite2D" parent="."]
scale = Vector2(0.3, 0.3)
texture = ExtResource("2_dxg46")

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://dnnn2xyayiehk"] [gd_scene load_steps=9 format=3 uid="uid://dnnn2xyayiehk"]
[ext_resource type="Texture2D" uid="uid://wt50kx6bup51" path="res://sprites/weapon/StaffNecromancy.png" id="1_ms3us"] [ext_resource type="Texture2D" uid="uid://wt50kx6bup51" path="res://sprites/weapon/StaffNecromancy.png" id="1_ms3us"]
[ext_resource type="Script" path="res://scripts/weapon/ProjectileWeapon.cs" id="1_w8hhv"] [ext_resource type="Script" path="res://scripts/weapon/ProjectileWeapon.cs" id="1_w8hhv"]
[ext_resource type="PackedScene" uid="uid://c01av43yk1q71" path="res://prefab/projectile/curseOfTheUndead.tscn" id="2_34250"] [ext_resource type="PackedScene" uid="uid://c01av43yk1q71" path="res://prefab/projectile/curseOfTheUndead.tscn" id="2_34250"]
[ext_resource type="Texture2D" uid="uid://dg5vwprt66w4j" path="res://sprites/weapon/StaffNecromancy_Icon.png" id="3_31iau"] [ext_resource type="Texture2D" uid="uid://dg5vwprt66w4j" path="res://sprites/weapon/StaffNecromancy_Icon.png" id="3_31iau"]
[ext_resource type="PackedScene" uid="uid://bdxgx5vcof8em" path="res://prefab/projectile/Catapult.tscn" id="3_hk5nr"]
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="4_ffr2k"] [ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="4_ffr2k"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_obcq2"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_obcq2"]
@ -16,16 +17,14 @@ size = Vector2(49, 5.25)
collision_layer = 8 collision_layer = 8
collision_mask = 34 collision_mask = 34
script = ExtResource("1_w8hhv") script = ExtResource("1_w8hhv")
ProjectileScenes = [ExtResource("2_34250")] ProjectileScenes = [ExtResource("2_34250"), ExtResource("3_hk5nr")]
Sequentially = true
FiringIntervalAsMillisecond = 300 FiringIntervalAsMillisecond = 300
_recoil = null
UniqueIcon = ExtResource("3_31iau") UniqueIcon = ExtResource("3_31iau")
_minContactInjury = null
_maxContactInjury = null
[node name="DamageArea2D" type="Area2D" parent="."] [node name="DamageArea2D" type="Area2D" parent="."]
collision_layer = 8 collision_layer = 8
collision_mask = 70 collision_mask = 102
[node name="CollisionShape2D" type="CollisionShape2D" parent="DamageArea2D"] [node name="CollisionShape2D" type="CollisionShape2D" parent="DamageArea2D"]
position = Vector2(25.5, 0.5) position = Vector2(25.5, 0.5)

View File

@ -77,6 +77,13 @@ public partial class CharacterTemplate : CharacterBody2D
[Export] public string? CharacterName; [Export] public string? CharacterName;
/// <summary>
/// <para>Can mutate after death</para>
/// <para>是否允许死后变异</para>
/// </summary>
[Export]
public bool CanMutateAfterDeath { get; set; } = true;
protected IItemContainer? ProtectedItemContainer; protected IItemContainer? ProtectedItemContainer;
//Item containers are used to store items. //Item containers are used to store items.

View File

@ -19,7 +19,8 @@ public static class LootRegister
new LootGroup(0.8f, new LootGroup(0.8f,
[ [
new LootEntry("staff_necromancy"), new LootEntry("staff_necromancy"),
]) ]),
new LootGroup(1, [new LootEntry("portable_backpacks")])
]; ];
var testLootList = new LootList(Config.LootListId.Test, lootGroups); var testLootList = new LootList(Config.LootListId.Test, lootGroups);
LootListManager.RegisterLootList(testLootList); LootListManager.RegisterLootList(testLootList);

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using ColdMint.scripts.camp; using ColdMint.scripts.camp;
using ColdMint.scripts.character; using ColdMint.scripts.character;
using ColdMint.scripts.damage; using ColdMint.scripts.damage;
using ColdMint.scripts.inventory;
using ColdMint.scripts.pickable; using ColdMint.scripts.pickable;
using ColdMint.scripts.projectile.decorator; using ColdMint.scripts.projectile.decorator;
using Godot; using Godot;
@ -142,13 +141,11 @@ public partial class Projectile : CharacterBody2D
return true; return true;
} }
//Match any item now if (target is PickAbleTemplate pickAbleTemplate)
//现在使它识别任何物品
if (target is IItem)
{ {
//Bullets are allowed to strike objects. //The picked-up item cannot resist the bullet.
//允许子弹撞击物品 //被拾起的物品无法抵挡子弹
return true; return !pickAbleTemplate.Picked;
} }
if (target is not CharacterTemplate characterTemplate) if (target is not CharacterTemplate characterTemplate)

View File

@ -37,7 +37,7 @@ public class NodeSpawnOnKillCharacterDecorator : IProjectileDecorator
return; return;
} }
if (PackedScenePath == null || DefaultParentNode == null) if (PackedScenePath == null || DefaultParentNode == null || !target.CanMutateAfterDeath)
{ {
return; return;
} }

View File

@ -24,12 +24,39 @@ public partial class ProjectileWeapon : WeaponTemplate
[Export] protected PackedScene[] ProjectileScenes { get; set; } = []; [Export] protected PackedScene[] ProjectileScenes { get; set; } = [];
/// <summary>
/// <para>Whether to launch in the order of the projectile list</para>
/// <para>是否按照抛射体列表的循序发射</para>
/// </summary>
[Export]
protected bool Sequentially { get; set; }
private int _projectileIndex;
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
_marker2D = GetNode<Marker2D>("Marker2D"); _marker2D = GetNode<Marker2D>("Marker2D");
} }
/// <summary>
/// <para>GetNextProjectileScene</para>
/// <para>获取下一个抛射体</para>
/// </summary>
/// <returns></returns>
private PackedScene GetNextProjectileScene()
{
if (Sequentially)
{
_projectileIndex = (_projectileIndex + 1) % ProjectileScenes.Length;
return ProjectileScenes[_projectileIndex];
}
else
{
return ProjectileScenes[RandomUtils.Instance.Next(ProjectileScenes.Length)];
}
}
protected override void DoFire(Node2D? owner, Vector2 enemyGlobalPosition) protected override void DoFire(Node2D? owner, Vector2 enemyGlobalPosition)
{ {
@ -50,6 +77,7 @@ public partial class ProjectileWeapon : WeaponTemplate
LogCat.LogError("projectile_container_is_null"); LogCat.LogError("projectile_container_is_null");
return; return;
} }
//Empty list check //Empty list check
//空列表检查 //空列表检查
if (ProjectileScenes is []) if (ProjectileScenes is [])
@ -60,8 +88,7 @@ public partial class ProjectileWeapon : WeaponTemplate
//Get the first projectile //Get the first projectile
//获取第一个抛射体 //获取第一个抛射体
var projectileScene = ProjectileScenes[0]; var projectileScene = GetNextProjectileScene();
// var projectileScene = _projectileCache[_projectiles[0]];
var projectile = NodeUtils.InstantiatePackedScene<Projectile>(projectileScene); var projectile = NodeUtils.InstantiatePackedScene<Projectile>(projectileScene);
if (projectile == null) return; if (projectile == null) return;
if (Config.IsDebug()) if (Config.IsDebug())
@ -73,6 +100,7 @@ public partial class ProjectileWeapon : WeaponTemplate
}; };
projectile.AddProjectileDecorator(nodeSpawnOnKillCharacterDecorator); projectile.AddProjectileDecorator(nodeSpawnOnKillCharacterDecorator);
} }
NodeUtils.CallDeferredAddChild(GameSceneNodeHolder.ProjectileContainer, projectile); NodeUtils.CallDeferredAddChild(GameSceneNodeHolder.ProjectileContainer, projectile);
projectile.Owner = owner; projectile.Owner = owner;
projectile.Velocity = (enemyGlobalPosition - _marker2D.GlobalPosition).Normalized() * projectile.Speed; projectile.Velocity = (enemyGlobalPosition - _marker2D.GlobalPosition).Normalized() * projectile.Speed;