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
script = ExtResource("1_ubaid")
CharacterName = "character_evil_crow"
CanMutateAfterDeath = false
MaxHp = 50
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="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="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"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_obcq2"]
@ -16,16 +17,14 @@ size = Vector2(49, 5.25)
collision_layer = 8
collision_mask = 34
script = ExtResource("1_w8hhv")
ProjectileScenes = [ExtResource("2_34250")]
ProjectileScenes = [ExtResource("2_34250"), ExtResource("3_hk5nr")]
Sequentially = true
FiringIntervalAsMillisecond = 300
_recoil = null
UniqueIcon = ExtResource("3_31iau")
_minContactInjury = null
_maxContactInjury = null
[node name="DamageArea2D" type="Area2D" parent="."]
collision_layer = 8
collision_mask = 70
collision_mask = 102
[node name="CollisionShape2D" type="CollisionShape2D" parent="DamageArea2D"]
position = Vector2(25.5, 0.5)

View File

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

View File

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

View File

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

View File

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

View File

@ -24,12 +24,39 @@ public partial class ProjectileWeapon : WeaponTemplate
[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()
{
base._Ready();
_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)
{
@ -50,6 +77,7 @@ public partial class ProjectileWeapon : WeaponTemplate
LogCat.LogError("projectile_container_is_null");
return;
}
//Empty list check
//空列表检查
if (ProjectileScenes is [])
@ -60,8 +88,7 @@ public partial class ProjectileWeapon : WeaponTemplate
//Get the first projectile
//获取第一个抛射体
var projectileScene = ProjectileScenes[0];
// var projectileScene = _projectileCache[_projectiles[0]];
var projectileScene = GetNextProjectileScene();
var projectile = NodeUtils.InstantiatePackedScene<Projectile>(projectileScene);
if (projectile == null) return;
if (Config.IsDebug())
@ -73,6 +100,7 @@ public partial class ProjectileWeapon : WeaponTemplate
};
projectile.AddProjectileDecorator(nodeSpawnOnKillCharacterDecorator);
}
NodeUtils.CallDeferredAddChild(GameSceneNodeHolder.ProjectileContainer, projectile);
projectile.Owner = owner;
projectile.Velocity = (enemyGlobalPosition - _marker2D.GlobalPosition).Normalized() * projectile.Speed;