diff --git a/.gitignore b/.gitignore
index 7227cb3..5923e10 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@
/DungeonShooting_Godot/DungeonShooting.sln.DotSettings.user
/DungeonShooting_Godot/.VSCodeCounter
**/*.txt
+/DungeonShooting_Godot/buffTable
\ No newline at end of file
diff --git a/DungeonShooting_Godot/addons/dungeonShooting_plugin/generator/BuffGenerator.cs b/DungeonShooting_Godot/addons/dungeonShooting_plugin/generator/BuffGenerator.cs
index 92ce289..af7db64 100644
--- a/DungeonShooting_Godot/addons/dungeonShooting_plugin/generator/BuffGenerator.cs
+++ b/DungeonShooting_Godot/addons/dungeonShooting_plugin/generator/BuffGenerator.cs
@@ -15,8 +15,74 @@
{
public static bool Generate()
{
+ PropFragmentRegister.Init();
+ var outStr = "# 道具逻辑属性表\n\n";
+
+ outStr += GetSplit("Buff 属性片段");
+ outStr += GetTableTitle();
+ foreach (var fragment in PropFragmentRegister.BuffFragmentInfos)
+ {
+ outStr += GetTableLine(fragment.Value);
+ }
+ outStr += "\n\n";
+
+ outStr += GetSplit("主动道具使用条件片段");
+ outStr += GetTableTitle();
+ foreach (var fragment in PropFragmentRegister.ConditionFragmentInfos)
+ {
+ outStr += GetTableLine(fragment.Value);
+ }
+ outStr += "\n\n";
+
+ outStr += GetSplit("主动道具使用效果片段");
+ outStr += GetTableTitle();
+ foreach (var fragment in PropFragmentRegister.EffectFragmentInfos)
+ {
+ outStr += GetTableLine(fragment.Value);
+ }
+ outStr += "\n\n";
+
+ outStr += GetSplit("主动道具充能条件片段");
+ outStr += GetTableTitle();
+ foreach (var fragment in PropFragmentRegister.ChargeFragmentInfos)
+ {
+ outStr += GetTableLine(fragment.Value);
+ }
+ outStr += "\n\n";
+
+ if (!Directory.Exists("buffTable"))
+ {
+ Directory.CreateDirectory("buffTable");
+ }
+ File.WriteAllText("buffTable/BuffTable.md", outStr);
return true;
}
-
+
+ private static string GetSplit(string title)
+ {
+ return $"---\n### {title}\n";
+ }
+
+ private static string GetTableTitle()
+ {
+ return $"| 属性名称 | 描述 | 参数 |\n" +
+ $"|-|-|-|\n";
+ }
+
+ private static string GetTableLine(PropFragmentInfo fragmentInfo)
+ {
+ var arg = "";
+ for (var i = 0; i < fragmentInfo.ArgInfos.Count; i++)
+ {
+ var argInfo = fragmentInfo.ArgInfos[i];
+ if (i > 0)
+ {
+ arg += "
";
+ }
+ arg += $"参数{argInfo.ArgIndex}: {argInfo.Description}";
+ }
+
+ return $"| {fragmentInfo.Name} | {fragmentInfo.Description} | {arg} |\n";
+ }
}
#endif
diff --git a/DungeonShooting_Godot/excel/ActivePropBase.xlsx b/DungeonShooting_Godot/excel/ActivePropBase.xlsx
index 65bdb9c..d050768 100644
--- a/DungeonShooting_Godot/excel/ActivePropBase.xlsx
+++ b/DungeonShooting_Godot/excel/ActivePropBase.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/excel/ActivityBase.xlsx b/DungeonShooting_Godot/excel/ActivityBase.xlsx
index f6b3513..9ec1b0b 100644
--- a/DungeonShooting_Godot/excel/ActivityBase.xlsx
+++ b/DungeonShooting_Godot/excel/ActivityBase.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/excel/BuffPropBase.xlsx b/DungeonShooting_Godot/excel/BuffPropBase.xlsx
index 708a012..42fa73c 100644
--- a/DungeonShooting_Godot/excel/BuffPropBase.xlsx
+++ b/DungeonShooting_Godot/excel/BuffPropBase.xlsx
Binary files differ
diff --git a/DungeonShooting_Godot/excelTool/ExcelGenerator.cs b/DungeonShooting_Godot/excelTool/ExcelGenerator.cs
index baa592d..6cee45f 100644
--- a/DungeonShooting_Godot/excelTool/ExcelGenerator.cs
+++ b/DungeonShooting_Godot/excelTool/ExcelGenerator.cs
@@ -707,7 +707,16 @@
var tempStr = str.Substring(1, str.Length - 2);
var typeData = ConvertToType(tempStr, depth + 1);
var typeStr = typeData.TypeStr + "[]";
- var typeName = typeData.TypeName + "[]";
+ string typeName;
+ var index = typeData.TypeName.IndexOf(',');
+ if (index < 0)
+ {
+ typeName = typeData.TypeName + "[]";
+ }
+ else
+ {
+ typeName = typeData.TypeName.Substring(0, index) + "[]" + typeData.TypeName.Substring(index);
+ }
if (typeData.IsRefExcel) //引用过其他表
{
@@ -724,12 +733,13 @@
{
switch (typeName)
{
+ case "object": return typeof(JsonElement).FullName;
case "boolean": return "bool";
- case "vector2": return "SerializeVector2";
- case "vector3": return "SerializeVector3";
- case "color": return "SerializeColor";
- case "activityType": return "ActivityType";
- case "activityQuality": return "ActivityQuality";
+ case "vector2": return typeof(SerializeVector2).FullName;
+ case "vector3": return typeof(SerializeVector3).FullName;
+ case "color": return typeof(SerializeColor).FullName;
+ case "activityType": return typeof(ActivityType).FullName;
+ case "activityQuality": return typeof(ActivityQuality).FullName;
}
return typeName;
@@ -739,24 +749,25 @@
{
switch (typeName)
{
+ case "object":return typeof(JsonElement).AssemblyQualifiedName;
case "bool":
- case "boolean": return typeof(bool).FullName;
- case "byte": return typeof(byte).FullName;
- case "sbyte": return typeof(sbyte).FullName;
- case "short": return typeof(short).FullName;
- case "ushort": return typeof(ushort).FullName;
- case "int": return typeof(int).FullName;
- case "uint": return typeof(uint).FullName;
- case "long": return typeof(long).FullName;
- case "ulong": return typeof(ulong).FullName;
- case "string": return typeof(string).FullName;
- case "float": return typeof(float).FullName;
- case "double": return typeof(double).FullName;
- case "vector2": return "SerializeVector2";
- case "vector3": return "SerializeVector3";
- case "color": return "SerializeColor";
- case "activityType": return "ActivityType";
- case "activityQuality": return "ActivityQuality";
+ case "boolean": return typeof(bool).AssemblyQualifiedName;
+ case "byte": return typeof(byte).AssemblyQualifiedName;
+ case "sbyte": return typeof(sbyte).AssemblyQualifiedName;
+ case "short": return typeof(short).AssemblyQualifiedName;
+ case "ushort": return typeof(ushort).AssemblyQualifiedName;
+ case "int": return typeof(int).AssemblyQualifiedName;
+ case "uint": return typeof(uint).AssemblyQualifiedName;
+ case "long": return typeof(long).AssemblyQualifiedName;
+ case "ulong": return typeof(ulong).AssemblyQualifiedName;
+ case "string": return typeof(string).AssemblyQualifiedName;
+ case "float": return typeof(float).AssemblyQualifiedName;
+ case "double": return typeof(double).AssemblyQualifiedName;
+ case "vector2": return typeof(SerializeVector2).AssemblyQualifiedName;
+ case "vector3": return typeof(SerializeVector3).AssemblyQualifiedName;
+ case "color": return typeof(SerializeColor).AssemblyQualifiedName;
+ case "activityType": return typeof(ActivityType).AssemblyQualifiedName;
+ case "activityQuality": return typeof(ActivityQuality).AssemblyQualifiedName;
}
return typeName;
diff --git a/DungeonShooting_Godot/excelTool/version b/DungeonShooting_Godot/excelTool/version
index 62f9457..c793025 100644
--- a/DungeonShooting_Godot/excelTool/version
+++ b/DungeonShooting_Godot/excelTool/version
@@ -1 +1 @@
-6
\ No newline at end of file
+7
\ No newline at end of file
diff --git a/DungeonShooting_Godot/prefab/box/TreasureBox0001.tscn b/DungeonShooting_Godot/prefab/box/TreasureBox0001.tscn
index 804110c..71e3c5e 100644
--- a/DungeonShooting_Godot/prefab/box/TreasureBox0001.tscn
+++ b/DungeonShooting_Godot/prefab/box/TreasureBox0001.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=12 format=3 uid="uid://d2gj0yuup0gdb"]
[ext_resource type="Script" path="res://src/game/activity/box/TreasureBox.cs" id="1_wxils"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_l4sas"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_l4sas"]
[ext_resource type="Texture2D" uid="uid://dladvmgql1pwe" path="res://resource/sprite/box/TreasureBox0001.png" id="3_eed5t"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_1v1is"]
resource_local_to_scene = true
shader = ExtResource("2_l4sas")
diff --git a/DungeonShooting_Godot/prefab/bullet/laser/Laser0001.tscn b/DungeonShooting_Godot/prefab/bullet/laser/Laser0001.tscn
index 04de455..c70e71e 100644
--- a/DungeonShooting_Godot/prefab/bullet/laser/Laser0001.tscn
+++ b/DungeonShooting_Godot/prefab/bullet/laser/Laser0001.tscn
@@ -17,7 +17,7 @@
shape = SubResource("RectangleShape2D_l4vuk")
[node name="LineSprite" type="Sprite2D" parent="."]
-modulate = Color(1.5, 1.5, 1.5, 1)
+modulate = Color(1.6, 1.6, 1.6, 1)
position = Vector2(0, 1.19209e-07)
texture = ExtResource("2_uqalj")
centered = false
diff --git a/DungeonShooting_Godot/prefab/bullet/laser/Laser0002.tscn b/DungeonShooting_Godot/prefab/bullet/laser/Laser0002.tscn
index c989324..07111c2 100644
--- a/DungeonShooting_Godot/prefab/bullet/laser/Laser0002.tscn
+++ b/DungeonShooting_Godot/prefab/bullet/laser/Laser0002.tscn
@@ -6,7 +6,7 @@
[sub_resource type="RectangleShape2D" id="RectangleShape2D_l4vuk"]
resource_local_to_scene = true
-[node name="Laser0001" type="Area2D" node_paths=PackedStringArray("Particles2D")]
+[node name="Laser0002" type="Area2D" node_paths=PackedStringArray("Particles2D")]
collision_layer = 2
collision_mask = 0
monitorable = false
@@ -17,7 +17,7 @@
shape = SubResource("RectangleShape2D_l4vuk")
[node name="LineSprite" type="Sprite2D" parent="."]
-modulate = Color(1.5, 1.5, 1.5, 1)
+modulate = Color(1.6, 1.6, 1.6, 1)
position = Vector2(0, 1.19209e-07)
texture = ExtResource("2_ga23q")
centered = false
diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0001.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0001.tscn
index e1ddde3..8fc5d32 100644
--- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0001.tscn
+++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0001.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=7 format=3 uid="uid://bj4kmvt8jg1cf"]
[ext_resource type="Script" path="res://src/game/activity/bullet/normal/Bullet.cs" id="1_3d3df"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_mxa72"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_mxa72"]
[ext_resource type="SpriteFrames" uid="uid://baoxep7vami72" path="res://resource/spriteFrames/bullet/Bullet0001.tres" id="3_q4a0o"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_w5w0i"]
diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0002.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0002.tscn
index 4441bc7..6bfb5de 100644
--- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0002.tscn
+++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0002.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://bqkj0rn72ppge"]
[ext_resource type="Script" path="res://src/game/activity/bullet/normal/Bullet.cs" id="1_hepay"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_0n2yg"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_0n2yg"]
[ext_resource type="SpriteFrames" uid="uid://bpeodjqiy3mil" path="res://resource/spriteFrames/bullet/Bullet0002.tres" id="3_ldd0h"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_v77gw"]
resource_local_to_scene = true
shader = ExtResource("2_0n2yg")
diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0003.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0003.tscn
index 88082d7..bc835d7 100644
--- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0003.tscn
+++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0003.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=7 format=3 uid="uid://ee24ocwk8snj"]
[ext_resource type="Script" path="res://src/game/activity/bullet/normal/Bullet.cs" id="1_h6lfm"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_bteri"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_bteri"]
[ext_resource type="SpriteFrames" uid="uid://bcnhyin0aufl1" path="res://resource/spriteFrames/bullet/Bullet0003.tres" id="3_qvo0u"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_v77gw"]
resource_local_to_scene = true
shader = ExtResource("2_bteri")
diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn
index 57e55ab..8223206 100644
--- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn
+++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=12 format=3 uid="uid://d0h4xfi1oqf1l"]
[ext_resource type="Script" path="res://src/game/activity/bullet/normal/BoomBullet.cs" id="1_1jbgr"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_w1qob"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_w1qob"]
[ext_resource type="SpriteFrames" uid="uid://d3vma1qjo478l" path="res://resource/spriteFrames/bullet/Bullet0004.tres" id="3_bttus"]
[ext_resource type="Texture2D" uid="uid://h7hkgbwj1li" path="res://resource/sprite/common/Smoke.png" id="3_ofn8c"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_v77gw"]
resource_local_to_scene = true
shader = ExtResource("2_w1qob")
diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0005.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0005.tscn
index a6a0493..0585e3d 100644
--- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0005.tscn
+++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0005.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=12 format=3 uid="uid://cjgnw37tqiqh7"]
[ext_resource type="Script" path="res://src/game/activity/bullet/normal/BrushBullet.cs" id="1_13wdl"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_v0al6"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_v0al6"]
[ext_resource type="SpriteFrames" uid="uid://jj8oh76pi53j" path="res://resource/spriteFrames/bullet/Bullet0005.tres" id="3_mmvqn"]
[ext_resource type="Texture2D" uid="uid://h7hkgbwj1li" path="res://resource/sprite/common/Smoke.png" id="4_esjg6"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_v77gw"]
resource_local_to_scene = true
shader = ExtResource("2_v0al6")
diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0006.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0006.tscn
index 9e58d27..4465673 100644
--- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0006.tscn
+++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0006.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://c1fx7c1jwil26"]
[ext_resource type="Script" path="res://src/game/activity/bullet/normal/TrailBullet.cs" id="1_b8pov"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_iolc6"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_iolc6"]
[ext_resource type="SpriteFrames" uid="uid://dx4t45bq8ehhq" path="res://resource/spriteFrames/bullet/Bullet0006.tres" id="3_v2y7a"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_w5w0i"]
resource_local_to_scene = true
shader = ExtResource("2_iolc6")
diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0007.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0007.tscn
index 4dfced6..1693a68 100644
--- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0007.tscn
+++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0007.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://cybey66bhe4ro"]
[ext_resource type="Script" path="res://src/game/activity/bullet/normal/Bullet.cs" id="1_h4tn7"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_fgeyt"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_fgeyt"]
[ext_resource type="SpriteFrames" uid="uid://bkwoy70bnm74k" path="res://resource/spriteFrames/bullet/Bullet0007.tres" id="3_c1ec6"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_v77gw"]
resource_local_to_scene = true
shader = ExtResource("2_fgeyt")
diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0008.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0008.tscn
index 838ada7..e648d19 100644
--- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0008.tscn
+++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0008.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://d3dcmte122p6t"]
[ext_resource type="Script" path="res://src/game/activity/bullet/normal/ColorBullet.cs" id="1_qqm5l"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_t3qw6"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_t3qw6"]
[ext_resource type="SpriteFrames" uid="uid://ubdvau75andr" path="res://resource/spriteFrames/bullet/Bullet0008.tres" id="3_aoni0"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_v77gw"]
resource_local_to_scene = true
shader = ExtResource("2_t3qw6")
diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0009.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0009.tscn
index 2831163..4e8291e 100644
--- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0009.tscn
+++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0009.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://c4puxmnan51ds"]
[ext_resource type="Script" path="res://src/game/activity/bullet/normal/Arrow.cs" id="1_eots7"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_tscmb"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_tscmb"]
[ext_resource type="SpriteFrames" uid="uid://cyg3uvbakan08" path="res://resource/spriteFrames/bullet/Bullet0009.tres" id="3_l58ff"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_v77gw"]
resource_local_to_scene = true
shader = ExtResource("2_tscmb")
diff --git a/DungeonShooting_Godot/prefab/currency/Gold1.tscn b/DungeonShooting_Godot/prefab/currency/Gold1.tscn
index 5db5a1c..57994a4 100644
--- a/DungeonShooting_Godot/prefab/currency/Gold1.tscn
+++ b/DungeonShooting_Godot/prefab/currency/Gold1.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=24 format=3 uid="uid://bayga6rue4ldm"]
[ext_resource type="PackedScene" uid="uid://c7i2q4mx5qp2h" path="res://prefab/currency/GoldTemplate.tscn" id="1_7anjj"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_p7xui"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_p7xui"]
[ext_resource type="Texture2D" uid="uid://benn0iaclw8dk" path="res://resource/sprite/currency/Gold_1.png" id="3_lhsna"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_2tpx1"]
resource_local_to_scene = true
shader = ExtResource("2_p7xui")
diff --git a/DungeonShooting_Godot/prefab/currency/Gold10.tscn b/DungeonShooting_Godot/prefab/currency/Gold10.tscn
index e723646..56543f7 100644
--- a/DungeonShooting_Godot/prefab/currency/Gold10.tscn
+++ b/DungeonShooting_Godot/prefab/currency/Gold10.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=24 format=3 uid="uid://cpfeog5xk7frv"]
[ext_resource type="PackedScene" uid="uid://c7i2q4mx5qp2h" path="res://prefab/currency/GoldTemplate.tscn" id="1_q6rqs"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_fwuy2"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_fwuy2"]
[ext_resource type="Texture2D" uid="uid://7dy6itvggpwy" path="res://resource/sprite/currency/Gold_10.png" id="3_x42g4"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_2tpx1"]
resource_local_to_scene = true
shader = ExtResource("2_fwuy2")
diff --git a/DungeonShooting_Godot/prefab/currency/Gold5.tscn b/DungeonShooting_Godot/prefab/currency/Gold5.tscn
index 88de932..5aa77fa 100644
--- a/DungeonShooting_Godot/prefab/currency/Gold5.tscn
+++ b/DungeonShooting_Godot/prefab/currency/Gold5.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=24 format=3 uid="uid://dqeph6v1y3ycm"]
[ext_resource type="PackedScene" uid="uid://c7i2q4mx5qp2h" path="res://prefab/currency/GoldTemplate.tscn" id="1_t3bsk"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_r5r64"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_r5r64"]
[ext_resource type="Texture2D" uid="uid://bfpcqj2x8t2os" path="res://resource/sprite/currency/Gold_5.png" id="3_rf7nc"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_2tpx1"]
resource_local_to_scene = true
shader = ExtResource("2_r5r64")
diff --git a/DungeonShooting_Godot/prefab/currency/GoldTemplate.tscn b/DungeonShooting_Godot/prefab/currency/GoldTemplate.tscn
index a759eeb..55c52e2 100644
--- a/DungeonShooting_Godot/prefab/currency/GoldTemplate.tscn
+++ b/DungeonShooting_Godot/prefab/currency/GoldTemplate.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=6 format=3 uid="uid://c7i2q4mx5qp2h"]
[ext_resource type="Script" path="res://src/game/activity/currency/Gold.cs" id="1_p60kl"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_5nps8"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_5nps8"]
[ext_resource type="Texture2D" uid="uid://cthwlbqve6i1l" path="res://resource/sprite/currency/Gold_shadow.png" id="3_6xm1s"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_qdjhs"]
resource_local_to_scene = true
shader = ExtResource("2_5nps8")
diff --git a/DungeonShooting_Godot/prefab/effect/enemy/EnemyDead0001.tscn b/DungeonShooting_Godot/prefab/effect/enemy/EnemyDead0001.tscn
index 488e2c5..b00a234 100644
--- a/DungeonShooting_Godot/prefab/effect/enemy/EnemyDead0001.tscn
+++ b/DungeonShooting_Godot/prefab/effect/enemy/EnemyDead0001.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=31 format=3 uid="uid://pr88a1phtxgb"]
[ext_resource type="Script" path="res://src/game/effects/enemy/EnemyDead0001.cs" id="1_1re5v"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_s7bee"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_s7bee"]
[ext_resource type="Texture2D" uid="uid://cn64eauvwx1uj" path="res://resource/sprite/role/enemy0001/enemy0001_Debris.png" id="3_uinig"]
[ext_resource type="Texture2D" uid="uid://h7hkgbwj1li" path="res://resource/sprite/common/Smoke.png" id="4_t55wd"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_s1mj2"]
resource_local_to_scene = true
shader = ExtResource("2_s7bee")
diff --git a/DungeonShooting_Godot/prefab/effect/enemy/EnemyDead0002.tscn b/DungeonShooting_Godot/prefab/effect/enemy/EnemyDead0002.tscn
index 310d6fd..30f4965 100644
--- a/DungeonShooting_Godot/prefab/effect/enemy/EnemyDead0002.tscn
+++ b/DungeonShooting_Godot/prefab/effect/enemy/EnemyDead0002.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=19 format=3 uid="uid://nfx3lhkdhv6a"]
[ext_resource type="Script" path="res://src/game/effects/enemy/EnemyDead0002.cs" id="1_ghu6a"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_q163q"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_q163q"]
[ext_resource type="Texture2D" uid="uid://x3tjqgdgp43n" path="res://resource/sprite/role/enemy0002/Enemy0002_dead.png" id="3_l0kbp"]
[ext_resource type="Texture2D" uid="uid://h7hkgbwj1li" path="res://resource/sprite/common/Smoke.png" id="4_2wygu"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_s1mj2"]
resource_local_to_scene = true
shader = ExtResource("2_q163q")
diff --git a/DungeonShooting_Godot/prefab/item/Item0001.tscn b/DungeonShooting_Godot/prefab/item/Item0001.tscn
index f93433d..58432f4 100644
--- a/DungeonShooting_Godot/prefab/item/Item0001.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0001.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=8 format=3 uid="uid://dvvvi26mgoel"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_cilvq"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_1c01w"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_1c01w"]
[ext_resource type="Texture2D" uid="uid://b74yx6c2jifyd" path="res://resource/sprite/item/hall_b/item-31.png" id="3_mua0g"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_1c01w")
diff --git a/DungeonShooting_Godot/prefab/item/Item0002.tscn b/DungeonShooting_Godot/prefab/item/Item0002.tscn
index 0db6d80..95169de 100644
--- a/DungeonShooting_Godot/prefab/item/Item0002.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0002.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=7 format=3 uid="uid://c5e11paqgc8y3"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_qi3y4"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_u3oiv"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_u3oiv"]
[ext_resource type="Texture2D" uid="uid://dl15qkga1kc82" path="res://resource/sprite/item/hall_b/item-12.png" id="3_6b42f"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_u3oiv")
diff --git a/DungeonShooting_Godot/prefab/item/Item0003.tscn b/DungeonShooting_Godot/prefab/item/Item0003.tscn
index 7b242ec..4799714 100644
--- a/DungeonShooting_Godot/prefab/item/Item0003.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0003.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=8 format=3 uid="uid://cdcpa4l71tkja"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_nuuf6"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_fbidd"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_fbidd"]
[ext_resource type="Texture2D" uid="uid://dr2d6toqxxifv" path="res://resource/sprite/item/hall_b/item-32.png" id="3_4miy3"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_fbidd")
diff --git a/DungeonShooting_Godot/prefab/item/Item0004.tscn b/DungeonShooting_Godot/prefab/item/Item0004.tscn
index 83fec33..acc7fb7 100644
--- a/DungeonShooting_Godot/prefab/item/Item0004.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0004.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=8 format=3 uid="uid://cjvmk415l1m7w"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_1qbhq"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_lp5ce"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_lp5ce"]
[ext_resource type="Texture2D" uid="uid://belr22s50exy8" path="res://resource/sprite/item/hall_b/item-18.png" id="3_px2by"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_lp5ce")
diff --git a/DungeonShooting_Godot/prefab/item/Item0005.tscn b/DungeonShooting_Godot/prefab/item/Item0005.tscn
index 46425ec..d18cf25 100644
--- a/DungeonShooting_Godot/prefab/item/Item0005.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0005.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=8 format=3 uid="uid://bxcsdgbhapf15"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_rrftl"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_fshwj"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_fshwj"]
[ext_resource type="Texture2D" uid="uid://bijiqseh8y667" path="res://resource/sprite/item/hall_b/item-01.png" id="3_3isqs"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_fshwj")
diff --git a/DungeonShooting_Godot/prefab/item/Item0006.tscn b/DungeonShooting_Godot/prefab/item/Item0006.tscn
index 0e97ba7..2fa0579 100644
--- a/DungeonShooting_Godot/prefab/item/Item0006.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0006.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://c7agqlb1d1glq"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_bnso1"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_7ta72"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_7ta72"]
[ext_resource type="Texture2D" uid="uid://dim1k57cc7w53" path="res://resource/sprite/item/hall_c/item _06.png" id="3_xwbcy"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_7ta72")
diff --git a/DungeonShooting_Godot/prefab/item/Item0007.tscn b/DungeonShooting_Godot/prefab/item/Item0007.tscn
index c4d9301..37701de 100644
--- a/DungeonShooting_Godot/prefab/item/Item0007.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0007.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://du3l8ekq5vcqr"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_33s8u"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_3qjg4"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_3qjg4"]
[ext_resource type="Texture2D" uid="uid://c4in5w5wofmgv" path="res://resource/sprite/item/hall_a/Slice_48.png" id="3_oer44"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_3qjg4")
diff --git a/DungeonShooting_Godot/prefab/item/Item0008.tscn b/DungeonShooting_Godot/prefab/item/Item0008.tscn
index d9fa5f0..204c18f 100644
--- a/DungeonShooting_Godot/prefab/item/Item0008.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0008.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://0amttjqbukwo"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_ncbpe"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_f8wfl"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_f8wfl"]
[ext_resource type="Texture2D" uid="uid://dlhp210kvxqsw" path="res://resource/sprite/item/hall_c/item _08.png" id="3_5siud"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_f8wfl")
diff --git a/DungeonShooting_Godot/prefab/item/Item0009.tscn b/DungeonShooting_Godot/prefab/item/Item0009.tscn
index 0dc01a3..ea17061 100644
--- a/DungeonShooting_Godot/prefab/item/Item0009.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0009.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=9 format=3 uid="uid://cemj288a6xd8m"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_100f5"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_xs4fm"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_xs4fm"]
[ext_resource type="Texture2D" uid="uid://dduv45hy81atn" path="res://resource/sprite/item/hall_a/Slice_33.png" id="3_p8ykj"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_xs4fm")
diff --git a/DungeonShooting_Godot/prefab/item/Item0010.tscn b/DungeonShooting_Godot/prefab/item/Item0010.tscn
index a12c25e..05a990d 100644
--- a/DungeonShooting_Godot/prefab/item/Item0010.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0010.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://dvle8ryfwpncx"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_1vaym"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_8sjd2"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_8sjd2"]
[ext_resource type="Texture2D" uid="uid://ucsiiyagcsjl" path="res://resource/sprite/item/hall_a/Slice_54.png" id="3_rasn0"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_8sjd2")
diff --git a/DungeonShooting_Godot/prefab/item/Item0011.tscn b/DungeonShooting_Godot/prefab/item/Item0011.tscn
index 522a606..5a2c23c 100644
--- a/DungeonShooting_Godot/prefab/item/Item0011.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0011.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://ujdk13nr8pf0"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_8227x"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_4wa6q"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_4wa6q"]
[ext_resource type="Texture2D" uid="uid://bld54p7gwlrd" path="res://resource/sprite/item/hall_a/Slice_28.png" id="3_yhv2x"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_4wa6q")
diff --git a/DungeonShooting_Godot/prefab/item/Item0012.tscn b/DungeonShooting_Godot/prefab/item/Item0012.tscn
index 9d032a9..8cd7b64 100644
--- a/DungeonShooting_Godot/prefab/item/Item0012.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0012.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://cj43h3b0irhq8"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_8skba"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_lxtjp"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_lxtjp"]
[ext_resource type="Texture2D" uid="uid://rrxkyras3kdw" path="res://resource/sprite/item/hall_c/item _12.png" id="3_sslpn"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_lxtjp")
diff --git a/DungeonShooting_Godot/prefab/item/Item0013.tscn b/DungeonShooting_Godot/prefab/item/Item0013.tscn
index 08acb31..802fbe4 100644
--- a/DungeonShooting_Godot/prefab/item/Item0013.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0013.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://je626022bg3t"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_awjys"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_3lobq"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_3lobq"]
[ext_resource type="Texture2D" uid="uid://cnpxb0dsnfqn1" path="res://resource/sprite/item/hall_c/item _13.png" id="3_h48fx"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_3lobq")
diff --git a/DungeonShooting_Godot/prefab/item/Item0014.tscn b/DungeonShooting_Godot/prefab/item/Item0014.tscn
index 69924c1..596b157 100644
--- a/DungeonShooting_Godot/prefab/item/Item0014.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0014.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://dvmflitcbpffa"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_r3jfj"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_8ndm7"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_8ndm7"]
[ext_resource type="Texture2D" uid="uid://i1qpk06s6a4q" path="res://resource/sprite/item/hall_c/item _14.png" id="3_ttnc5"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_8ndm7")
diff --git a/DungeonShooting_Godot/prefab/item/Item0015.tscn b/DungeonShooting_Godot/prefab/item/Item0015.tscn
index 287bc5d..4ab97e2 100644
--- a/DungeonShooting_Godot/prefab/item/Item0015.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0015.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://c6mr1q78r7fq"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_4enip"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_hr30a"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_hr30a"]
[ext_resource type="Texture2D" uid="uid://daae1qo6hccxb" path="res://resource/sprite/item/hall_a/Slice_46.png" id="3_jgc28"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_hr30a")
diff --git a/DungeonShooting_Godot/prefab/item/Item0016.tscn b/DungeonShooting_Godot/prefab/item/Item0016.tscn
index a7dee2c..0846611 100644
--- a/DungeonShooting_Godot/prefab/item/Item0016.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0016.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://b4r3hpil3we2s"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_go51e"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_ot0d2"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_ot0d2"]
[ext_resource type="Texture2D" uid="uid://6mkb76o7ja47" path="res://resource/sprite/item/hall_a/Slice_03.png" id="3_bvm05"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_ot0d2")
diff --git a/DungeonShooting_Godot/prefab/item/Item0017.tscn b/DungeonShooting_Godot/prefab/item/Item0017.tscn
index 5bf250a..ddff498 100644
--- a/DungeonShooting_Godot/prefab/item/Item0017.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0017.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://dh4cenmpdj520"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_78dif"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_pybet"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_pybet"]
[ext_resource type="Texture2D" uid="uid://cel2hojxm4fgj" path="res://resource/sprite/item/hall_c/item _17.png" id="3_jojl2"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_pybet")
diff --git a/DungeonShooting_Godot/prefab/item/Item0018.tscn b/DungeonShooting_Godot/prefab/item/Item0018.tscn
index 93174b0..2a8a8c2 100644
--- a/DungeonShooting_Godot/prefab/item/Item0018.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0018.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://bgndxlp47w88s"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_7wxee"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_a30jc"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_a30jc"]
[ext_resource type="Texture2D" uid="uid://drxs2tol6j4yu" path="res://resource/sprite/item/hall_a/Slice_02.png" id="3_iuab1"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_a30jc")
diff --git a/DungeonShooting_Godot/prefab/item/Item0019.tscn b/DungeonShooting_Godot/prefab/item/Item0019.tscn
index 6380afa..6aa4337 100644
--- a/DungeonShooting_Godot/prefab/item/Item0019.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0019.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://dpvwcpqvm0e5"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_j36vv"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_tlcne"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_tlcne"]
[ext_resource type="Texture2D" uid="uid://dutmdqi3ygnt1" path="res://resource/sprite/item/hall_a/Slice_38.png" id="3_gwklf"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_tlcne")
diff --git a/DungeonShooting_Godot/prefab/item/Item0020.tscn b/DungeonShooting_Godot/prefab/item/Item0020.tscn
index 68d6ba5..60f3c49 100644
--- a/DungeonShooting_Godot/prefab/item/Item0020.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0020.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://b2t1chmutscrc"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_a2uqr"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_pbqh6"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_pbqh6"]
[ext_resource type="Texture2D" uid="uid://qbc428calfue" path="res://resource/sprite/item/hall_a/Slice_42.png" id="3_mkcwv"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_pbqh6")
diff --git a/DungeonShooting_Godot/prefab/item/Item0021.tscn b/DungeonShooting_Godot/prefab/item/Item0021.tscn
index b28b7e4..4b153fb 100644
--- a/DungeonShooting_Godot/prefab/item/Item0021.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0021.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://v32g2u0mm0gm"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_25f5i"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_0claj"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_0claj"]
[ext_resource type="Texture2D" uid="uid://bt3rvgedbniwq" path="res://resource/sprite/item/hall_a/Slice_22.png" id="3_os210"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_0claj")
diff --git a/DungeonShooting_Godot/prefab/item/Item0022.tscn b/DungeonShooting_Godot/prefab/item/Item0022.tscn
index 6c71965..9afa1f5 100644
--- a/DungeonShooting_Godot/prefab/item/Item0022.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0022.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://nhnikrjoc800"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_57gqj"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_a56xb"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_a56xb"]
[ext_resource type="Texture2D" uid="uid://d3s00dfmrnt4" path="res://resource/sprite/item/hall_a/Slice_34.png" id="3_yv7yv"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_a56xb")
diff --git a/DungeonShooting_Godot/prefab/item/Item0023.tscn b/DungeonShooting_Godot/prefab/item/Item0023.tscn
index a7cf0e4..a282d32 100644
--- a/DungeonShooting_Godot/prefab/item/Item0023.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0023.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://bwvw5mk32hia4"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_guouv"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_olbah"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_olbah"]
[ext_resource type="Texture2D" uid="uid://bxgpi41yec4v0" path="res://resource/sprite/item/hall_a/Slice_40.png" id="3_573p0"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_olbah")
diff --git a/DungeonShooting_Godot/prefab/item/Item0024.tscn b/DungeonShooting_Godot/prefab/item/Item0024.tscn
index 3f0da7a..0f23b7b 100644
--- a/DungeonShooting_Godot/prefab/item/Item0024.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0024.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://dl72vryy7pu2s"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_ovsfp"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_424in"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_424in"]
[ext_resource type="Texture2D" uid="uid://dsod7xnf66vfr" path="res://resource/sprite/item/hall_a/Slice_31.png" id="3_6jgg6"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_424in")
diff --git a/DungeonShooting_Godot/prefab/item/Item0025.tscn b/DungeonShooting_Godot/prefab/item/Item0025.tscn
index 77e193b..315da55 100644
--- a/DungeonShooting_Godot/prefab/item/Item0025.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0025.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://k5ooobibugrh"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_4pwnq"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_ekpbo"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_ekpbo"]
[ext_resource type="Texture2D" uid="uid://byjgmf7gf8yo4" path="res://resource/sprite/item/hall_c/item _55.png" id="3_n7ajr"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_ekpbo")
diff --git a/DungeonShooting_Godot/prefab/item/Item0026.tscn b/DungeonShooting_Godot/prefab/item/Item0026.tscn
index d3b0e2c..b236c07 100644
--- a/DungeonShooting_Godot/prefab/item/Item0026.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0026.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://fxxcimm100wh"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_0hlhe"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_43i86"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_43i86"]
[ext_resource type="Texture2D" uid="uid://bigva5som5fy5" path="res://resource/sprite/item/hall_a/Slice_14.png" id="3_qrjxc"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_43i86")
diff --git a/DungeonShooting_Godot/prefab/item/Item0031.tscn b/DungeonShooting_Godot/prefab/item/Item0031.tscn
index 9789668..a323976 100644
--- a/DungeonShooting_Godot/prefab/item/Item0031.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0031.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://bhcqel0ylhti3"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_g24mc"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_05yhp"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_05yhp"]
[ext_resource type="Texture2D" uid="uid://c45ffwqrk708i" path="res://resource/sprite/item/hall_c/item _31.png" id="3_7e6ju"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_05yhp")
diff --git a/DungeonShooting_Godot/prefab/item/Item0036.tscn b/DungeonShooting_Godot/prefab/item/Item0036.tscn
index 80cfacf..c15168d 100644
--- a/DungeonShooting_Godot/prefab/item/Item0036.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0036.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://bb8eqxcwl7qf6"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_j2ns6"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_ur1o2"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_ur1o2"]
[ext_resource type="Texture2D" uid="uid://d3uyv5ubtig1n" path="res://resource/sprite/item/hall_c/item _36.png" id="3_e7nf3"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_ur1o2")
diff --git a/DungeonShooting_Godot/prefab/item/Item0054.tscn b/DungeonShooting_Godot/prefab/item/Item0054.tscn
index 7951390..371e0e8 100644
--- a/DungeonShooting_Godot/prefab/item/Item0054.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0054.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://gnsdqotyf0e8"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_palmb"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_d2qpb"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_d2qpb"]
[ext_resource type="Texture2D" uid="uid://cbuxe012k3pfu" path="res://resource/sprite/item/hall_c/item _54.png" id="3_b15p3"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_d2qpb")
diff --git a/DungeonShooting_Godot/prefab/item/Item0056.tscn b/DungeonShooting_Godot/prefab/item/Item0056.tscn
index 69a275e..2270697 100644
--- a/DungeonShooting_Godot/prefab/item/Item0056.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0056.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://bkxabig8chkv6"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_ebb3f"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_5sjig"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_5sjig"]
[ext_resource type="Texture2D" uid="uid://u3ri36urv8xn" path="res://resource/sprite/item/hall_c/item _56.png" id="3_bkxin"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_5sjig")
diff --git a/DungeonShooting_Godot/prefab/item/Item0057.tscn b/DungeonShooting_Godot/prefab/item/Item0057.tscn
index 369a48e..85ea6d1 100644
--- a/DungeonShooting_Godot/prefab/item/Item0057.tscn
+++ b/DungeonShooting_Godot/prefab/item/Item0057.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://bhwiakjbpjbsb"]
[ext_resource type="Script" path="res://src/game/activity/item/ObstacleObject.cs" id="1_fsyqi"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_ot8r8"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_ot8r8"]
[ext_resource type="Texture2D" uid="uid://ce4byqcoo2n05" path="res://resource/sprite/item/hall_c/item _57.png" id="3_2h0tv"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wh4b7"]
resource_local_to_scene = true
shader = ExtResource("2_ot8r8")
diff --git a/DungeonShooting_Godot/prefab/map/RoomDoor_E.tscn b/DungeonShooting_Godot/prefab/map/RoomDoor_E.tscn
index e90e3fd..f3d96f0 100644
--- a/DungeonShooting_Godot/prefab/map/RoomDoor_E.tscn
+++ b/DungeonShooting_Godot/prefab/map/RoomDoor_E.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=8 format=3 uid="uid://yhewdkpru0up"]
[ext_resource type="Script" path="res://src/game/room/RoomDoor.cs" id="1_4c6sw"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_lwx51"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_lwx51"]
[ext_resource type="SpriteFrames" uid="uid://3ps6h2f54qa5" path="res://resource/spriteFrames/other/RoomDoor_E_Up.tres" id="3_pjvd8"]
[ext_resource type="SpriteFrames" uid="uid://b34tddsmqnj8s" path="res://resource/spriteFrames/other/RoomDoor_E_Down.tres" id="4_ln8k4"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_yvwpk"]
resource_local_to_scene = true
shader = ExtResource("2_lwx51")
diff --git a/DungeonShooting_Godot/prefab/map/RoomDoor_N.tscn b/DungeonShooting_Godot/prefab/map/RoomDoor_N.tscn
index 3f45c24..f52d942 100644
--- a/DungeonShooting_Godot/prefab/map/RoomDoor_N.tscn
+++ b/DungeonShooting_Godot/prefab/map/RoomDoor_N.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=7 format=3 uid="uid://cbtj6bsaqqomt"]
[ext_resource type="Script" path="res://src/game/room/RoomDoor.cs" id="1_220be"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_h5ru6"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_h5ru6"]
[ext_resource type="SpriteFrames" uid="uid://xs72aopsgpg6" path="res://resource/spriteFrames/other/RoomDoor_N.tres" id="3_apluc"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_yvwpk"]
resource_local_to_scene = true
shader = ExtResource("2_h5ru6")
diff --git a/DungeonShooting_Godot/prefab/map/RoomDoor_S.tscn b/DungeonShooting_Godot/prefab/map/RoomDoor_S.tscn
index 0c2f4ea..11f0c9e 100644
--- a/DungeonShooting_Godot/prefab/map/RoomDoor_S.tscn
+++ b/DungeonShooting_Godot/prefab/map/RoomDoor_S.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=7 format=3 uid="uid://bvfnnqo71knb"]
[ext_resource type="Script" path="res://src/game/room/RoomDoor.cs" id="1_f3qbq"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_6vvcd"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_6vvcd"]
[ext_resource type="SpriteFrames" uid="uid://xs72aopsgpg6" path="res://resource/spriteFrames/other/RoomDoor_N.tres" id="3_vbbxp"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_yvwpk"]
resource_local_to_scene = true
shader = ExtResource("2_6vvcd")
diff --git a/DungeonShooting_Godot/prefab/map/RoomDoor_W.tscn b/DungeonShooting_Godot/prefab/map/RoomDoor_W.tscn
index 8b50dba..f82236a 100644
--- a/DungeonShooting_Godot/prefab/map/RoomDoor_W.tscn
+++ b/DungeonShooting_Godot/prefab/map/RoomDoor_W.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=8 format=3 uid="uid://wmedlesabvr3"]
[ext_resource type="Script" path="res://src/game/room/RoomDoor.cs" id="1_agux2"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_wx2w3"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_wx2w3"]
[ext_resource type="SpriteFrames" uid="uid://3ps6h2f54qa5" path="res://resource/spriteFrames/other/RoomDoor_E_Up.tres" id="3_jquy0"]
[ext_resource type="SpriteFrames" uid="uid://b34tddsmqnj8s" path="res://resource/spriteFrames/other/RoomDoor_E_Down.tres" id="4_6gcqk"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_yvwpk"]
resource_local_to_scene = true
shader = ExtResource("2_wx2w3")
diff --git a/DungeonShooting_Godot/prefab/prop/ActiveProp.tscn b/DungeonShooting_Godot/prefab/prop/ActiveProp.tscn
index aa0946a..42d35bc 100644
--- a/DungeonShooting_Godot/prefab/prop/ActiveProp.tscn
+++ b/DungeonShooting_Godot/prefab/prop/ActiveProp.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=6 format=3 uid="uid://drjkrimgii1u0"]
[ext_resource type="Script" path="res://src/game/activity/prop/ActiveProp.cs" id="1_n541c"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_75di4"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_75di4"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_mrkt4"]
resource_local_to_scene = true
diff --git a/DungeonShooting_Godot/prefab/prop/BuffProp.tscn b/DungeonShooting_Godot/prefab/prop/BuffProp.tscn
index 331309b..1940118 100644
--- a/DungeonShooting_Godot/prefab/prop/BuffProp.tscn
+++ b/DungeonShooting_Godot/prefab/prop/BuffProp.tscn
@@ -1,7 +1,7 @@
[gd_scene load_steps=6 format=3 uid="uid://dfpic4nubu7cf"]
[ext_resource type="Script" path="res://src/game/activity/prop/BuffProp.cs" id="1_nlcp6"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_imicp"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_imicp"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_mrkt4"]
resource_local_to_scene = true
diff --git a/DungeonShooting_Godot/prefab/role/Enemy0001.tscn b/DungeonShooting_Godot/prefab/role/Enemy0001.tscn
index 7d51397..95d8d9f 100644
--- a/DungeonShooting_Godot/prefab/role/Enemy0001.tscn
+++ b/DungeonShooting_Godot/prefab/role/Enemy0001.tscn
@@ -2,13 +2,14 @@
[ext_resource type="PackedScene" uid="uid://dbrig6dq441wo" path="res://prefab/role/template/EnemyTemplate.tscn" id="1_2vqwe"]
[ext_resource type="Script" path="res://src/game/activity/role/enemy/Enemy.cs" id="2_0pcq3"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_x8agd"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_x8agd"]
[ext_resource type="SpriteFrames" uid="uid://cnctpyrn02rhd" path="res://resource/spriteFrames/role/Enemy0001.tres" id="4_qv8w5"]
[ext_resource type="Animation" uid="uid://b4mgiysicdk2b" path="res://resource/animation/enemy/Enemy_reset.res" id="5_ffnft"]
[ext_resource type="Animation" uid="uid://gvkkxspcdwrp" path="res://resource/animation/enemy/Enemy_astonished.res" id="5_jyt15"]
[ext_resource type="Animation" uid="uid://16rxpnsgj5tl" path="res://resource/animation/enemy/Enemy_notify.res" id="6_x8gmo"]
[ext_resource type="Animation" uid="uid://cmje7jsgrhgmx" path="res://resource/animation/enemy/Enemy_query.res" id="7_e37p2"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_3nkur"]
resource_local_to_scene = true
shader = ExtResource("3_x8agd")
diff --git a/DungeonShooting_Godot/prefab/role/Enemy0002.tscn b/DungeonShooting_Godot/prefab/role/Enemy0002.tscn
index bd2ff43..08c2957 100644
--- a/DungeonShooting_Godot/prefab/role/Enemy0002.tscn
+++ b/DungeonShooting_Godot/prefab/role/Enemy0002.tscn
@@ -2,13 +2,14 @@
[ext_resource type="PackedScene" uid="uid://dbrig6dq441wo" path="res://prefab/role/template/EnemyTemplate.tscn" id="1_fanet"]
[ext_resource type="Script" path="res://src/game/activity/role/enemy/NoWeaponEnemy.cs" id="2_3an4s"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_yunbp"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_yunbp"]
[ext_resource type="SpriteFrames" uid="uid://ctpkpxgcwb583" path="res://resource/spriteFrames/role/Enemy0002.tres" id="3_hbsqi"]
[ext_resource type="Animation" uid="uid://gvkkxspcdwrp" path="res://resource/animation/enemy/Enemy_astonished.res" id="5_p7gwr"]
[ext_resource type="Animation" uid="uid://b4mgiysicdk2b" path="res://resource/animation/enemy/Enemy_reset.res" id="6_pt7v0"]
[ext_resource type="Animation" uid="uid://cmje7jsgrhgmx" path="res://resource/animation/enemy/Enemy_query.res" id="7_h4cls"]
[ext_resource type="Animation" uid="uid://16rxpnsgj5tl" path="res://resource/animation/enemy/Enemy_notify.res" id="8_0688j"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_y5nia"]
resource_local_to_scene = true
shader = ExtResource("2_yunbp")
diff --git a/DungeonShooting_Godot/prefab/role/Role0001.tscn b/DungeonShooting_Godot/prefab/role/Role0001.tscn
index cb1c9cb..71e4939 100644
--- a/DungeonShooting_Godot/prefab/role/Role0001.tscn
+++ b/DungeonShooting_Godot/prefab/role/Role0001.tscn
@@ -2,7 +2,7 @@
[ext_resource type="PackedScene" uid="uid://cyrcv2jdgr8cf" path="res://prefab/role/template/RoleTemplate.tscn" id="1_10c2n"]
[ext_resource type="Script" path="res://src/game/activity/role/player/Player.cs" id="2_6xwnt"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_rk4gg"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_rk4gg"]
[ext_resource type="Texture2D" uid="uid://dn58ax3t6rf4x" path="res://resource/sprite/role/common/Role_shadow1.png" id="3_vx7tr"]
[ext_resource type="SpriteFrames" uid="uid://n11thtali6es" path="res://resource/spriteFrames/role/Role0001.tres" id="4_galcc"]
diff --git a/DungeonShooting_Godot/prefab/role/template/EnemyTemplate.tscn b/DungeonShooting_Godot/prefab/role/template/EnemyTemplate.tscn
index ae33b4a..1f91bec 100644
--- a/DungeonShooting_Godot/prefab/role/template/EnemyTemplate.tscn
+++ b/DungeonShooting_Godot/prefab/role/template/EnemyTemplate.tscn
@@ -1,7 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://dbrig6dq441wo"]
[ext_resource type="PackedScene" uid="uid://cyrcv2jdgr8cf" path="res://prefab/role/template/RoleTemplate.tscn" id="1_5po38"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_x8agd"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_x8agd"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_k8mt5"]
resource_local_to_scene = true
diff --git a/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn b/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn
index be6716b..e098e51 100644
--- a/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn
+++ b/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn
@@ -1,6 +1,6 @@
[gd_scene load_steps=9 format=3 uid="uid://cyrcv2jdgr8cf"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="1_xk5yk"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="1_xk5yk"]
[ext_resource type="Script" path="res://src/game/activity/role/MountRotation.cs" id="2_5ddpw"]
[ext_resource type="Script" path="res://src/framework/activity/hurt/HurtArea.cs" id="2_8jnvr"]
[ext_resource type="SpriteFrames" uid="uid://c8h5svp76h3kw" path="res://resource/spriteFrames/role/Role_tip.tres" id="3_bo78w"]
diff --git a/DungeonShooting_Godot/prefab/shell/Shell0001.tscn b/DungeonShooting_Godot/prefab/shell/Shell0001.tscn
index c1b2535..945ce6a 100644
--- a/DungeonShooting_Godot/prefab/shell/Shell0001.tscn
+++ b/DungeonShooting_Godot/prefab/shell/Shell0001.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=7 format=3 uid="uid://bj4yr6ru8nhwr"]
[ext_resource type="Script" path="res://src/game/activity/common/AutoFreezeObject.cs" id="1_2g70c"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_tdny6"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_tdny6"]
[ext_resource type="SpriteFrames" uid="uid://b8gksxl7auquc" path="res://resource/spriteFrames/shell/Shell0001.tres" id="3_ujn5y"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_px12l"]
resource_local_to_scene = true
shader = ExtResource("2_tdny6")
diff --git a/DungeonShooting_Godot/prefab/shell/Shell0002.tscn b/DungeonShooting_Godot/prefab/shell/Shell0002.tscn
index aa42706..ba501b3 100644
--- a/DungeonShooting_Godot/prefab/shell/Shell0002.tscn
+++ b/DungeonShooting_Godot/prefab/shell/Shell0002.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=7 format=3 uid="uid://cdhinm8rnppxt"]
[ext_resource type="Script" path="res://src/game/activity/common/AutoFreezeObject.cs" id="1_qi64y"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_s28nu"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_s28nu"]
[ext_resource type="SpriteFrames" uid="uid://cj8psdl2pova6" path="res://resource/spriteFrames/shell/Shell0002.tres" id="3_r560h"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_px12l"]
resource_local_to_scene = true
shader = ExtResource("2_s28nu")
diff --git a/DungeonShooting_Godot/prefab/shell/Shell0003.tscn b/DungeonShooting_Godot/prefab/shell/Shell0003.tscn
index f50ef2f..06c43db 100644
--- a/DungeonShooting_Godot/prefab/shell/Shell0003.tscn
+++ b/DungeonShooting_Godot/prefab/shell/Shell0003.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=7 format=3 uid="uid://ba5sxxjaappbj"]
[ext_resource type="Script" path="res://src/game/activity/common/AutoFreezeObject.cs" id="1_5hfb2"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_586dn"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_586dn"]
[ext_resource type="SpriteFrames" uid="uid://kc1jwvwdg660" path="res://resource/spriteFrames/shell/Shell0003.tres" id="3_j2kre"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_px12l"]
resource_local_to_scene = true
shader = ExtResource("2_586dn")
diff --git a/DungeonShooting_Godot/prefab/shell/Shell0004.tscn b/DungeonShooting_Godot/prefab/shell/Shell0004.tscn
index fc18f6b..e1c4461 100644
--- a/DungeonShooting_Godot/prefab/shell/Shell0004.tscn
+++ b/DungeonShooting_Godot/prefab/shell/Shell0004.tscn
@@ -1,9 +1,10 @@
[gd_scene load_steps=7 format=3 uid="uid://ycr5mjr25302"]
[ext_resource type="Script" path="res://src/game/activity/common/AutoFreezeObject.cs" id="1_ridlp"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_guwkk"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_guwkk"]
[ext_resource type="SpriteFrames" uid="uid://b8b0ye3iv1vwp" path="res://resource/spriteFrames/shell/Shell0004.tres" id="3_1s5f3"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_px12l"]
resource_local_to_scene = true
shader = ExtResource("2_guwkk")
diff --git a/DungeonShooting_Godot/prefab/ui/Encyclopedia.tscn b/DungeonShooting_Godot/prefab/ui/Encyclopedia.tscn
index 1a028c7..d51ed3f 100644
--- a/DungeonShooting_Godot/prefab/ui/Encyclopedia.tscn
+++ b/DungeonShooting_Godot/prefab/ui/Encyclopedia.tscn
@@ -2,16 +2,17 @@
[ext_resource type="Script" path="res://src/game/ui/encyclopedia/EncyclopediaPanel.cs" id="1_hd86y"]
[ext_resource type="Texture2D" uid="uid://c0st2iiql8igg" path="res://resource/sprite/ui/encyclopedia/TitleBg.png" id="3_gdtik"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_o1xl7"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_o1xl7"]
[ext_resource type="Texture2D" uid="uid://dahib4qcevboo" path="res://resource/sprite/ui/encyclopedia/Panel2.png" id="4_21546"]
[ext_resource type="Texture2D" uid="uid://jb73i5q1dv2a" path="res://resource/sprite/ui/encyclopedia/Tab.png" id="4_nm64b"]
[ext_resource type="Texture2D" uid="uid://brevrlfdtllmk" path="res://resource/sprite/ui/encyclopedia/Select.png" id="5_f0anf"]
[ext_resource type="Texture2D" uid="uid://cu5y32wfai4pn" path="res://resource/sprite/ui/encyclopedia/Item.png" id="5_niceh"]
[ext_resource type="Texture2D" uid="uid://conjg6fw6670x" path="res://resource/sprite/ui/encyclopedia/Panel.png" id="7_hfdat"]
-[ext_resource type="Shader" path="res://resource/material/Outline.gdshader" id="9_mmpq6"]
+[ext_resource type="Shader" path="res://resource/shader/Outline.gdshader" id="9_mmpq6"]
[ext_resource type="Texture2D" uid="uid://cuas0bdjlpmwb" path="res://resource/sprite/ui/encyclopedia/Close.png" id="10_jgsfw"]
[ext_resource type="Texture2D" uid="uid://7x5b5ed7hk7w" path="res://resource/sprite/ui/encyclopedia/CloseSelect.png" id="11_247gy"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_gm0bl"]
resource_local_to_scene = true
shader = ExtResource("3_o1xl7")
diff --git a/DungeonShooting_Godot/prefab/ui/MapEditorCreateMark.tscn b/DungeonShooting_Godot/prefab/ui/MapEditorCreateMark.tscn
index 2cee601..138aeef 100644
--- a/DungeonShooting_Godot/prefab/ui/MapEditorCreateMark.tscn
+++ b/DungeonShooting_Godot/prefab/ui/MapEditorCreateMark.tscn
@@ -5,12 +5,13 @@
[ext_resource type="Material" uid="uid://cces3bhds7jyi" path="res://resource/material/Blend.tres" id="2_xb40b"]
[ext_resource type="Texture2D" uid="uid://c5778ntk2rdon" path="res://resource/sprite/ui/commonIcon/Delete.png" id="3_7xihk"]
[ext_resource type="Texture2D" uid="uid://dligpyhp72sg7" path="res://resource/sprite/ui/commonIcon/Right.png" id="3_v5clf"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="4_7uegb"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="4_7uegb"]
[ext_resource type="Script" path="res://src/game/ui/mapEditorCreateMark/attribute/NumberAttribute.cs" id="6_1ym7l"]
[ext_resource type="Script" path="res://src/game/ui/mapEditorCreateMark/attribute/ObjectAttribute.cs" id="7_516p2"]
[ext_resource type="Script" path="res://src/game/ui/mapEditorCreateMark/attribute/OptionAttribute.cs" id="7_o1tg2"]
[ext_resource type="Texture2D" uid="uid://dggb6p4sdmfry" path="res://resource/sprite/ui/commonIcon/Edit.png" id="7_yeuy4"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_ywcv8"]
resource_local_to_scene = true
shader = ExtResource("4_7uegb")
diff --git a/DungeonShooting_Godot/prefab/ui/MapEditorMapMark.tscn b/DungeonShooting_Godot/prefab/ui/MapEditorMapMark.tscn
index 6f07965..c5db108 100644
--- a/DungeonShooting_Godot/prefab/ui/MapEditorMapMark.tscn
+++ b/DungeonShooting_Godot/prefab/ui/MapEditorMapMark.tscn
@@ -6,9 +6,10 @@
[ext_resource type="Texture2D" uid="uid://c5778ntk2rdon" path="res://resource/sprite/ui/commonIcon/Delete.png" id="4_urq7y"]
[ext_resource type="Texture2D" uid="uid://d4gduco55dqpk" path="res://resource/sprite/ui/commonIcon/Down.png" id="5_x5dpw"]
[ext_resource type="Texture2D" uid="uid://bn47bmilcw4x0" path="res://resource/sprite/ui/commonIcon/Select2.png" id="6_jpt3y"]
-[ext_resource type="Texture2D" uid="uid://dqvg18aacx6db" path="res://resource/sprite/ui/commonIcon/Visible.png" id="6_qiemx"]
+[ext_resource type="Texture2D" uid="uid://cpjm2q4000an2" path="res://resource/sprite/ui/commonIcon/Visible.png" id="6_qiemx"]
[ext_resource type="Texture2D" uid="uid://btetxb0hqoifk" path="res://resource/sprite/ui/commonIcon/MarkCell_placeholder.png" id="8_p8o70"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="9_vr0bo"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="9_vr0bo"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_xxv8l"]
resource_local_to_scene = true
diff --git a/DungeonShooting_Godot/prefab/ui/MapEditorSelectObject.tscn b/DungeonShooting_Godot/prefab/ui/MapEditorSelectObject.tscn
index 0460256..318c387 100644
--- a/DungeonShooting_Godot/prefab/ui/MapEditorSelectObject.tscn
+++ b/DungeonShooting_Godot/prefab/ui/MapEditorSelectObject.tscn
@@ -3,7 +3,8 @@
[ext_resource type="Script" path="res://src/game/ui/mapEditorSelectObject/MapEditorSelectObjectPanel.cs" id="1_hdfkd"]
[ext_resource type="Texture2D" uid="uid://bn47bmilcw4x0" path="res://resource/sprite/ui/commonIcon/Select2.png" id="3_4nhjm"]
[ext_resource type="Texture2D" uid="uid://blfvsup876agh" path="res://resource/sprite/ui/commonIcon/Search.png" id="3_laasd"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="4_uomdx"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="4_uomdx"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_8bgig"]
resource_local_to_scene = true
diff --git a/DungeonShooting_Godot/prefab/ui/MapEditorTools.tscn b/DungeonShooting_Godot/prefab/ui/MapEditorTools.tscn
index 9805b0d..ff37220 100644
--- a/DungeonShooting_Godot/prefab/ui/MapEditorTools.tscn
+++ b/DungeonShooting_Godot/prefab/ui/MapEditorTools.tscn
@@ -6,11 +6,12 @@
[ext_resource type="Script" path="res://src/game/ui/mapEditorTools/DoorDragArea.cs" id="3_3w0w6"]
[ext_resource type="Script" path="res://src/game/ui/mapEditorTools/DoorDragButton.cs" id="3_45muq"]
[ext_resource type="Texture2D" uid="uid://4wupcp53rrpi" path="res://resource/sprite/ui/mapEditorTools/DoorDragButton.png" id="3_trbb5"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="6_krtnu"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="6_krtnu"]
[ext_resource type="Texture2D" uid="uid://dnty1a2tcawos" path="res://resource/sprite/ui/commonIcon/Mark.png" id="6_n7h3g"]
[ext_resource type="Script" path="res://src/game/ui/mapEditorTools/MarkTool.cs" id="7_ekxcj"]
[ext_resource type="Texture2D" uid="uid://cuntr7hec044f" path="res://resource/sprite/ui/commonIcon/Select.png" id="7_mqmd6"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_wxp5t"]
resource_local_to_scene = true
shader = ExtResource("6_krtnu")
diff --git a/DungeonShooting_Godot/prefab/ui/RoomUI.tscn b/DungeonShooting_Godot/prefab/ui/RoomUI.tscn
index e0a86af..aec2060 100644
--- a/DungeonShooting_Godot/prefab/ui/RoomUI.tscn
+++ b/DungeonShooting_Godot/prefab/ui/RoomUI.tscn
@@ -13,7 +13,7 @@
[ext_resource type="Texture2D" uid="uid://0swkya4hn82c" path="res://resource/sprite/ui/roomUI/Panel.png" id="10_q3fs8"]
[ext_resource type="Texture2D" uid="uid://504f1r0mi33n" path="res://resource/sprite/weapon/weapon0005/Weapon0005.png" id="11_lsai4"]
[ext_resource type="Texture2D" uid="uid://bsu7re1lxnr72" path="res://resource/sprite/ui/roomUI/Cooldown.png" id="11_p0smc"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="12_fgyob"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="12_fgyob"]
[ext_resource type="Texture2D" uid="uid://dwysndc5ffski" path="res://resource/sprite/ui/roomUI/ChargeProgressBar.png" id="13_6w7qi"]
[ext_resource type="Texture2D" uid="uid://ck0w7at3oat5" path="res://resource/sprite/ui/roomUI/ChargeProgress.png" id="13_vuglj"]
[ext_resource type="PackedScene" uid="uid://bmj3p25gwpqpn" path="res://prefab/ui/RoomMap.tscn" id="16_rp3sg"]
diff --git a/DungeonShooting_Godot/prefab/ui/WeaponRoulette.tscn b/DungeonShooting_Godot/prefab/ui/WeaponRoulette.tscn
index ea763b4..9752ebf 100644
--- a/DungeonShooting_Godot/prefab/ui/WeaponRoulette.tscn
+++ b/DungeonShooting_Godot/prefab/ui/WeaponRoulette.tscn
@@ -3,9 +3,10 @@
[ext_resource type="Script" path="res://src/game/ui/weaponRoulette/WeaponRoulettePanel.cs" id="1_1uvbk"]
[ext_resource type="Texture2D" uid="uid://e6krxgte01j3" path="res://resource/sprite/ui/roulette/RouletteBg.png" id="2_k6gjh"]
[ext_resource type="Script" path="res://src/game/ui/weaponRoulette/WeaponSlot.cs" id="3_8v011"]
-[ext_resource type="Shader" path="res://resource/material/Outline.gdshader" id="4_p348k"]
+[ext_resource type="Shader" path="res://resource/shader/Outline.gdshader" id="4_p348k"]
[ext_resource type="Texture2D" uid="uid://dmm8jw06bhffh" path="res://resource/sprite/ui/commonIcon/Lock.png" id="6_7mog3"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_i1wmw"]
resource_local_to_scene = true
shader = ExtResource("4_p348k")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0001.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0001.tscn
index 503b43d..65e0171 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0001.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0001.tscn
@@ -2,9 +2,10 @@
[ext_resource type="PackedScene" uid="uid://cxltmhhp4rbyk" path="res://prefab/weapon/WeaponTemplate.tscn" id="1_ykl0r"]
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="2_t56pk"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_x1q03"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_x1q03"]
[ext_resource type="SpriteFrames" uid="uid://5m0qs7m4er5u" path="res://resource/spriteFrames/weapon/Weapon0001.tres" id="4_d5c81"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_5bfqf"]
resource_local_to_scene = true
shader = ExtResource("3_x1q03")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0002.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0002.tscn
index 184f949..a905006 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0002.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0002.tscn
@@ -2,7 +2,7 @@
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="1_hgtyo"]
[ext_resource type="PackedScene" uid="uid://cxltmhhp4rbyk" path="res://prefab/weapon/WeaponTemplate.tscn" id="1_r50xc"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_8nvny"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_8nvny"]
[ext_resource type="SpriteFrames" uid="uid://domhmo4flmlt0" path="res://resource/spriteFrames/weapon/Weapon0002.tres" id="3_4h3je"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_bywvu"]
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0003.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0003.tscn
index dee91f4..f41e58f 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0003.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0003.tscn
@@ -2,9 +2,10 @@
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="1_aeolk"]
[ext_resource type="PackedScene" uid="uid://cxltmhhp4rbyk" path="res://prefab/weapon/WeaponTemplate.tscn" id="1_c17wt"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_4yjnk"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_4yjnk"]
[ext_resource type="SpriteFrames" uid="uid://c7dt1uwdybn5" path="res://resource/spriteFrames/weapon/Weapon0003.tres" id="3_upkjt"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_c6pgc"]
resource_local_to_scene = true
shader = ExtResource("2_4yjnk")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0004.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0004.tscn
index 5fe50df..d697d44 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0004.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0004.tscn
@@ -2,9 +2,10 @@
[ext_resource type="PackedScene" uid="uid://cxltmhhp4rbyk" path="res://prefab/weapon/WeaponTemplate.tscn" id="1_kg172"]
[ext_resource type="Script" path="res://src/game/activity/weapon/knife/Knife.cs" id="2_v1wer"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_63s5g"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_63s5g"]
[ext_resource type="SpriteFrames" uid="uid://k2tktysa7j86" path="res://resource/spriteFrames/weapon/Weapon0004.tres" id="4_uymcs"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_o5ytq"]
resource_local_to_scene = true
shader = ExtResource("3_63s5g")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0005.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0005.tscn
index aa2b854..b76789c 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0005.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0005.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=8 format=3 uid="uid://bwhi5e52wiiay"]
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="1_3lu3r"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="1_466gw"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="1_466gw"]
[ext_resource type="PackedScene" uid="uid://cxltmhhp4rbyk" path="res://prefab/weapon/WeaponTemplate.tscn" id="1_lyhyf"]
[ext_resource type="SpriteFrames" uid="uid://djdvlmqsn8bie" path="res://resource/spriteFrames/weapon/Weapon0005.tres" id="2_m3plc"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_uftuv"]
resource_local_to_scene = true
shader = ExtResource("1_466gw")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0006.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0006.tscn
index 979066a..1679421 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0006.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0006.tscn
@@ -2,9 +2,10 @@
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="1_5nx8j"]
[ext_resource type="PackedScene" uid="uid://cxltmhhp4rbyk" path="res://prefab/weapon/WeaponTemplate.tscn" id="1_kx4jd"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="1_rp1bw"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="1_rp1bw"]
[ext_resource type="SpriteFrames" uid="uid://dx1mjbx4acs3q" path="res://resource/spriteFrames/weapon/Weapon0006.tres" id="2_j3sji"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_m6bme"]
resource_local_to_scene = true
shader = ExtResource("1_rp1bw")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0007.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0007.tscn
index ab2e6a3..51ac22d 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0007.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0007.tscn
@@ -2,9 +2,10 @@
[ext_resource type="PackedScene" uid="uid://cxltmhhp4rbyk" path="res://prefab/weapon/WeaponTemplate.tscn" id="1_5xnlm"]
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="1_exwbu"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_7rywx"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_7rywx"]
[ext_resource type="SpriteFrames" uid="uid://xxyokrbt10xm" path="res://resource/spriteFrames/weapon/Weapon0007.tres" id="3_ms2gs"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_sy2aq"]
resource_local_to_scene = true
shader = ExtResource("2_7rywx")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0008.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0008.tscn
index d7de309..39d6909 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0008.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0008.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=11 format=3 uid="uid://yt10i80hs3gt"]
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="1_l63x2"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="1_mhoa7"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="1_mhoa7"]
[ext_resource type="SpriteFrames" uid="uid://b2wpy40adyjs6" path="res://resource/spriteFrames/weapon/Weapon0008.tres" id="2_s0xbw"]
[ext_resource type="Animation" uid="uid://v3dltmdstqad" path="res://resource/animation/weapon/Weapon_floodlight.res" id="4_p833u"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_cbiyh"]
resource_local_to_scene = true
shader = ExtResource("1_mhoa7")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0009.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0009.tscn
index 285a2fa..b6e99f9 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0009.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0009.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=11 format=3 uid="uid://2lb2h8qunqyu"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="1_6fbtx"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="1_6fbtx"]
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="1_eprgt"]
[ext_resource type="SpriteFrames" uid="uid://c0xwj3kpk02ua" path="res://resource/spriteFrames/weapon/Weapon0009.tres" id="2_4kxpd"]
[ext_resource type="Animation" uid="uid://v3dltmdstqad" path="res://resource/animation/weapon/Weapon_floodlight.res" id="4_o2wqt"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_cbiyh"]
resource_local_to_scene = true
shader = ExtResource("1_6fbtx")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0010.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0010.tscn
index 571ff9f..7a3fc74 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0010.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0010.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=11 format=3 uid="uid://dhnrfqcojc367"]
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="1_bw5v7"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_pht5a"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="2_pht5a"]
[ext_resource type="SpriteFrames" uid="uid://cd7fhaqk587o2" path="res://resource/spriteFrames/weapon/Weapon0010.tres" id="3_nj0c6"]
[ext_resource type="Animation" uid="uid://v3dltmdstqad" path="res://resource/animation/weapon/Weapon_floodlight.res" id="4_2cd01"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_cbiyh"]
resource_local_to_scene = true
shader = ExtResource("2_pht5a")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0011.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0011.tscn
index 278775a..8666568 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0011.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0011.tscn
@@ -2,9 +2,10 @@
[ext_resource type="PackedScene" uid="uid://cxltmhhp4rbyk" path="res://prefab/weapon/WeaponTemplate.tscn" id="1_fgcwf"]
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="2_m84k4"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_4rq0j"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_4rq0j"]
[ext_resource type="SpriteFrames" uid="uid://xvfg1a0xj7ng" path="res://resource/spriteFrames/weapon/Weapon0011.tres" id="4_bnkqc"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_m6bme"]
resource_local_to_scene = true
shader = ExtResource("3_4rq0j")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0013.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0013.tscn
index c7c9280..71c44fe 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0013.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0013.tscn
@@ -2,9 +2,10 @@
[ext_resource type="PackedScene" uid="uid://cxltmhhp4rbyk" path="res://prefab/weapon/WeaponTemplate.tscn" id="1_f1h8o"]
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="2_bpgfu"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_0l3ip"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_0l3ip"]
[ext_resource type="SpriteFrames" uid="uid://cawsi08vaqfrn" path="res://resource/spriteFrames/weapon/Weapon0013.tres" id="4_w7ibl"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_sy2aq"]
resource_local_to_scene = true
shader = ExtResource("3_0l3ip")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0014.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0014.tscn
index b880d0d..9f8bd62 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0014.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0014.tscn
@@ -2,9 +2,10 @@
[ext_resource type="PackedScene" uid="uid://cxltmhhp4rbyk" path="res://prefab/weapon/WeaponTemplate.tscn" id="1_3op5w"]
[ext_resource type="Script" path="res://src/game/activity/weapon/gun/Gun.cs" id="2_toxwq"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_ch83c"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_ch83c"]
[ext_resource type="SpriteFrames" uid="uid://taxfr2lcy0f3" path="res://resource/spriteFrames/weapon/Weapon0014.tres" id="4_xdmw2"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_sy2aq"]
resource_local_to_scene = true
shader = ExtResource("3_ch83c")
diff --git a/DungeonShooting_Godot/prefab/weapon/Weapon0016.tscn b/DungeonShooting_Godot/prefab/weapon/Weapon0016.tscn
index 3e1648b..6e825c6 100644
--- a/DungeonShooting_Godot/prefab/weapon/Weapon0016.tscn
+++ b/DungeonShooting_Godot/prefab/weapon/Weapon0016.tscn
@@ -1,10 +1,11 @@
[gd_scene load_steps=11 format=3 uid="uid://b7s3fvpkltk1d"]
[ext_resource type="Script" path="res://src/game/activity/weapon/bow/Bow.cs" id="1_k4gvs"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_cui8l"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="3_cui8l"]
[ext_resource type="SpriteFrames" uid="uid://ccrflh6pjmq7r" path="res://resource/spriteFrames/weapon/Weapon0016.tres" id="4_buwa4"]
[ext_resource type="Animation" uid="uid://v3dltmdstqad" path="res://resource/animation/weapon/Weapon_floodlight.res" id="4_nl06y"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_sy2aq"]
resource_local_to_scene = true
shader = ExtResource("3_cui8l")
diff --git a/DungeonShooting_Godot/project.godot b/DungeonShooting_Godot/project.godot
index 7c6559c..2f7682e 100644
--- a/DungeonShooting_Godot/project.godot
+++ b/DungeonShooting_Godot/project.godot
@@ -31,7 +31,7 @@
[editor_plugins]
-enabled=PackedStringArray("res://addons/dungeonShooting_plugin/plugin.cfg")
+enabled=PackedStringArray()
[file_customization]
diff --git a/DungeonShooting_Godot/resource/config/ActivePropBase.json b/DungeonShooting_Godot/resource/config/ActivePropBase.json
index b43aeff..8120b14 100644
--- a/DungeonShooting_Godot/resource/config/ActivePropBase.json
+++ b/DungeonShooting_Godot/resource/config/ActivePropBase.json
@@ -6,11 +6,11 @@
"Buff": null,
"Condition": {
"HpFull": [
- 0
+ true
]
},
"Effect": {
- "Hp": [
+ "ChangeHp": [
2
]
},
@@ -27,7 +27,7 @@
"Buff": null,
"Condition": {
"AmmoFull": [
- 0
+ true
]
},
"Effect": {
@@ -76,5 +76,81 @@
"CooldownTime": 0,
"IsConsumables": false,
"MaxCount": 1
+ },
+ {
+ "Id": "0005",
+ "Remark": "\u9B54\u672F\u68D2",
+ "__Activity": "prop5004",
+ "Buff": null,
+ "Condition": null,
+ "Effect": {
+ "SwapWeapon": []
+ },
+ "Charge": {
+ "EnterRoom": [
+ 0.5
+ ]
+ },
+ "Duration": 0,
+ "CooldownTime": 0,
+ "IsConsumables": false,
+ "MaxCount": 1
+ },
+ {
+ "Id": "0006",
+ "Remark": "\u4FBF\u643A\u5F0F\u4F9B\u8840\u5668",
+ "__Activity": "prop5005",
+ "Buff": null,
+ "Condition": {
+ "HpFull": [
+ true
+ ],
+ "Gold": [
+ "\u003E=",
+ 25
+ ]
+ },
+ "Effect": {
+ "ChangeHp": [
+ 1
+ ],
+ "UseGold": [
+ 25
+ ]
+ },
+ "Charge": {
+ "EnterRoom": [
+ 1
+ ]
+ },
+ "Duration": 0,
+ "CooldownTime": 0,
+ "IsConsumables": false,
+ "MaxCount": 1
+ },
+ {
+ "Id": "0007",
+ "Remark": "\u4FBF\u643A\u5F0F\u732E\u8840\u5668",
+ "__Activity": "prop5006",
+ "Buff": null,
+ "Condition": {
+ "Hp": [
+ "\u003E",
+ 1
+ ]
+ },
+ "Effect": {
+ "ChangeHp": [
+ -1
+ ],
+ "GetGold": [
+ 20
+ ]
+ },
+ "Charge": null,
+ "Duration": 0,
+ "CooldownTime": 3,
+ "IsConsumables": false,
+ "MaxCount": 1
}
]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/config/ActivityBase.json b/DungeonShooting_Godot/resource/config/ActivityBase.json
index 501c22b..b1466f3 100644
--- a/DungeonShooting_Godot/resource/config/ActivityBase.json
+++ b/DungeonShooting_Godot/resource/config/ActivityBase.json
@@ -700,6 +700,48 @@
"ShowInMapEditor": true
},
{
+ "Id": "prop5004",
+ "Name": "\u9B54\u672F\u68D2",
+ "Type": 9,
+ "Quality": 1,
+ "Price": 0,
+ "Intro": "\u968F\u673A\u9009\u62E9\u623F\u95F4\u5185\u7684\u4E00\u4E2A\u624B\u6301\u6B66\u5668\u7684\u654C\u4EBA, \u4EA4\u6362\u4F60\u4EEC\u624B\u4E2D\u7684\u6B66\u5668",
+ "Details": "",
+ "IsStatic": false,
+ "__Material": "",
+ "Prefab": "res://prefab/prop/ActiveProp.tscn",
+ "Icon": "res://resource/sprite/prop/active/ActiveProp5004.png",
+ "ShowInMapEditor": true
+ },
+ {
+ "Id": "prop5005",
+ "Name": "\u4FBF\u643A\u5F0F\u4F9B\u8840\u5668",
+ "Type": 9,
+ "Quality": 1,
+ "Price": 0,
+ "Intro": "\u4F7F\u7528\u91D1\u5E01\u6362\u53D6\u8840\u91CF",
+ "Details": "",
+ "IsStatic": false,
+ "__Material": "",
+ "Prefab": "res://prefab/prop/ActiveProp.tscn",
+ "Icon": "res://resource/sprite/prop/active/ActiveProp5005.png",
+ "ShowInMapEditor": true
+ },
+ {
+ "Id": "prop5006",
+ "Name": "\u4FBF\u643A\u5F0F\u732E\u8840\u5668",
+ "Type": 9,
+ "Quality": 1,
+ "Price": 0,
+ "Intro": "\u4F7F\u7528\u8840\u91CF\u6362\u53D6\u91D1\u5E01",
+ "Details": "",
+ "IsStatic": false,
+ "__Material": "",
+ "Prefab": "res://prefab/prop/ActiveProp.tscn",
+ "Icon": "res://resource/sprite/prop/active/ActiveProp5006.png",
+ "ShowInMapEditor": true
+ },
+ {
"Id": "treasure_box0001",
"Name": "\u6728\u8D28\u5B9D\u7BB1",
"Type": 10,
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle1/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle1/Preview.png
index ce7fa71..ce03a6c 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle1/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle1/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle2/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle2/Preview.png
index a2253ad..9f59c42 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle2/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle2/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle3/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle3/Preview.png
index a7ad03b..8047e10 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle3/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle3/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/Preview.png
index 7f7b4b5..434657d 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/TileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/TileInfo.json
index 81d2236..d51b806 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/TileInfo.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle4/TileInfo.json
@@ -1 +1 @@
-{"NavigationVertices":[{"X":278,"Y":-218},{"X":278,"Y":-302},{"X":330,"Y":-362},{"X":330,"Y":82},{"X":-170,"Y":-362},{"X":186,"Y":-302},{"X":278,"Y":6},{"X":-170,"Y":82},{"X":186,"Y":6},{"X":-10,"Y":6},{"X":186,"Y":-78},{"X":-102,"Y":6},{"X":-102,"Y":-78},{"X":-10,"Y":-78},{"X":186,"Y":-218},{"X":-10,"Y":-218},{"X":-10,"Y":-302},{"X":-102,"Y":-302},{"X":-102,"Y":-218},{"X":278,"Y":-78}],"NavigationPolygon":[[0,1,2,3],[4,2,1,5],[6,3,7,8],[8,7,9,10],[11,9,7],[11,7,4,12],[10,9,13],[5,14,15,16],[4,5,16],[4,16,17],[4,17,18],[12,4,18],[13,12,18,15],[10,13,15,14],[19,10,14,0],[19,0,3],[19,3,6]],"Floor":[-11,-23,0,3,-11,-22,0,3,-11,-21,0,3,-11,-20,0,3,-11,-19,0,3,-11,-18,0,3,-11,-17,0,3,-11,-16,0,3,-11,-15,0,3,-11,-14,0,3,-11,-13,0,3,-11,-12,0,3,-11,-11,0,3,-11,-10,0,3,-11,-9,0,3,-11,-8,0,3,-11,-7,0,3,-11,-6,0,3,-11,-5,0,3,-11,-4,0,3,-11,-3,0,3,-11,-2,0,3,-11,-1,0,3,-11,0,0,3,-11,1,0,3,-11,2,0,3,-11,3,0,3,-11,4,0,3,-10,-23,0,3,-10,-22,0,3,-10,-21,0,3,-10,-20,0,3,-10,-19,0,3,-10,-18,0,3,-10,-17,0,3,-10,-16,0,3,-10,-15,0,3,-10,-14,0,3,-10,-13,0,3,-10,-12,0,3,-10,-11,0,3,-10,-10,0,3,-10,-9,0,3,-10,-8,0,3,-10,-7,0,3,-10,-6,0,3,-10,-5,0,3,-10,-4,0,3,-10,-3,0,3,-10,-2,0,3,-10,-1,0,3,-10,0,0,3,-10,1,0,3,-10,2,0,3,-10,3,0,3,-10,4,0,3,-9,-23,0,3,-9,-22,0,3,-9,-21,0,3,-9,-20,0,3,-9,-19,0,3,-9,-18,0,3,-9,-17,0,3,-9,-16,0,3,-9,-15,0,3,-9,-14,0,3,-9,-13,0,3,-9,-12,0,3,-9,-11,0,3,-9,-10,0,3,-9,-9,0,3,-9,-8,0,3,-9,-7,0,3,-9,-6,0,3,-9,-5,0,3,-9,-4,0,3,-9,-3,0,3,-9,-2,0,3,-9,-1,0,3,-9,0,0,3,-9,1,0,3,-9,2,0,3,-9,3,0,3,-9,4,0,3,-8,-23,0,3,-8,-22,0,3,-8,-21,0,3,-8,-20,0,3,-8,-19,0,3,-8,-18,0,3,-8,-17,0,3,-8,-16,0,3,-8,-15,0,3,-8,-14,0,3,-8,-13,0,3,-8,-12,0,3,-8,-11,0,3,-8,-10,0,3,-8,-9,0,3,-8,-8,0,3,-8,-7,0,3,-8,-6,0,3,-8,-5,0,3,-8,-4,0,3,-8,-3,0,3,-8,-2,0,3,-8,-1,0,3,-8,0,0,3,-8,1,0,3,-8,2,0,3,-8,3,0,3,-8,4,0,3,-7,-23,0,3,-7,-22,0,3,-7,-21,0,3,-7,-20,0,3,-7,-19,0,3,-7,-18,0,3,-7,-17,0,3,-7,-16,0,3,-7,-15,0,3,-7,-14,0,3,-7,-13,0,3,-7,-12,0,3,-7,-11,0,3,-7,-10,0,3,-7,-9,0,3,-7,-8,0,3,-7,-7,0,3,-7,-6,0,3,-7,-5,0,3,-7,-4,0,3,-7,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-7,4,0,3,-6,-23,0,3,-6,-22,0,3,-6,-21,0,3,-6,-20,0,3,-6,-14,0,3,-6,-13,0,3,-6,-12,0,3,-6,-11,0,3,-6,-10,0,3,-6,-9,0,3,-6,-8,0,3,-6,-7,0,3,-6,-6,0,3,-6,0,0,3,-6,1,0,3,-6,2,0,3,-6,3,0,3,-6,4,0,3,-5,-23,0,3,-5,-22,0,3,-5,-21,0,3,-5,-20,0,3,-5,-14,0,3,-5,-13,0,3,-5,-12,0,3,-5,-11,0,3,-5,-10,0,3,-5,-9,0,3,-5,-8,0,3,-5,-7,0,3,-5,-6,0,3,-5,0,0,3,-5,1,0,3,-5,2,0,3,-5,3,0,3,-5,4,0,3,-4,-23,0,3,-4,-22,0,3,-4,-21,0,3,-4,-20,0,3,-4,-14,0,3,-4,-13,0,3,-4,-12,0,3,-4,-11,0,3,-4,-10,0,3,-4,-9,0,3,-4,-8,0,3,-4,-7,0,3,-4,-6,0,3,-4,0,0,3,-4,1,0,3,-4,2,0,3,-4,3,0,3,-4,4,0,3,-3,-23,0,3,-3,-22,0,3,-3,-21,0,3,-3,-20,0,3,-3,-14,0,3,-3,-13,0,3,-3,-12,0,3,-3,-11,0,3,-3,-10,0,3,-3,-9,0,3,-3,-8,0,3,-3,-7,0,3,-3,-6,0,3,-3,0,0,3,-3,1,0,3,-3,2,0,3,-3,3,0,3,-3,4,0,3,-2,-23,0,3,-2,-22,0,3,-2,-21,0,3,-2,-20,0,3,-2,-14,0,3,-2,-13,0,3,-2,-12,0,3,-2,-11,0,3,-2,-10,0,3,-2,-9,0,3,-2,-8,0,3,-2,-7,0,3,-2,-6,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-2,4,0,3,-1,-23,0,3,-1,-22,0,3,-1,-21,0,3,-1,-20,0,3,-1,-19,0,3,-1,-18,0,3,-1,-17,0,3,-1,-16,0,3,-1,-15,0,3,-1,-14,0,3,-1,-13,0,3,-1,-12,0,3,-1,-11,0,3,-1,-10,0,3,-1,-9,0,3,-1,-8,0,3,-1,-7,0,3,-1,-6,0,3,-1,-5,0,3,-1,-4,0,3,-1,-3,0,3,-1,-2,0,3,-1,-1,0,3,-1,0,0,3,-1,1,0,3,-1,2,0,3,-1,3,0,3,-1,4,0,3,0,-23,0,3,0,-22,0,3,0,-21,0,3,0,-20,0,3,0,-19,0,3,0,-18,0,3,0,-17,0,3,0,-16,0,3,0,-15,0,3,0,-14,0,3,0,-13,0,3,0,-12,0,3,0,-11,0,3,0,-10,0,3,0,-9,0,3,0,-8,0,3,0,-7,0,3,0,-6,0,3,0,-5,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,0,1,0,3,0,2,0,3,0,3,0,3,0,4,0,3,1,-23,0,3,1,-22,0,3,1,-21,0,3,1,-20,0,3,1,-19,0,3,1,-18,0,3,1,-17,0,3,1,-16,0,3,1,-15,0,3,1,-14,0,3,1,-13,0,3,1,-12,0,3,1,-11,0,3,1,-10,0,3,1,-9,0,3,1,-8,0,3,1,-7,0,3,1,-6,0,3,1,-5,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,1,1,0,3,1,2,0,3,1,3,0,3,1,4,0,3,2,-23,0,3,2,-22,0,3,2,-21,0,3,2,-20,0,3,2,-19,0,3,2,-18,0,3,2,-17,0,3,2,-16,0,3,2,-15,0,3,2,-14,0,3,2,-13,0,3,2,-12,0,3,2,-11,0,3,2,-10,0,3,2,-9,0,3,2,-8,0,3,2,-7,0,3,2,-6,0,3,2,-5,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,2,1,0,3,2,2,0,3,2,3,0,3,2,4,0,3,3,-23,0,3,3,-22,0,3,3,-21,0,3,3,-20,0,3,3,-19,0,3,3,-18,0,3,3,-17,0,3,3,-16,0,3,3,-15,0,3,3,-14,0,3,3,-13,0,3,3,-12,0,3,3,-11,0,3,3,-10,0,3,3,-9,0,3,3,-8,0,3,3,-7,0,3,3,-6,0,3,3,-5,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,3,1,0,3,3,2,0,3,3,3,0,3,3,4,0,3,4,-23,0,3,4,-22,0,3,4,-21,0,3,4,-20,0,3,4,-19,0,3,4,-18,0,3,4,-17,0,3,4,-16,0,3,4,-15,0,3,4,-14,0,3,4,-13,0,3,4,-12,0,3,4,-11,0,3,4,-10,0,3,4,-9,0,3,4,-8,0,3,4,-7,0,3,4,-6,0,3,4,-5,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,4,1,0,3,4,2,0,3,4,3,0,3,4,4,0,3,5,-23,0,3,5,-22,0,3,5,-21,0,3,5,-20,0,3,5,-19,0,3,5,-18,0,3,5,-17,0,3,5,-16,0,3,5,-15,0,3,5,-14,0,3,5,-13,0,3,5,-12,0,3,5,-11,0,3,5,-10,0,3,5,-9,0,3,5,-8,0,3,5,-7,0,3,5,-6,0,3,5,-5,0,3,5,-4,0,3,5,-3,0,3,5,-2,0,3,5,-1,0,3,5,0,0,3,5,1,0,3,5,2,0,3,5,3,0,3,5,4,0,3,6,-23,0,3,6,-22,0,3,6,-21,0,3,6,-20,0,3,6,-19,0,3,6,-18,0,3,6,-17,0,3,6,-16,0,3,6,-15,0,3,6,-14,0,3,6,-13,0,3,6,-12,0,3,6,-11,0,3,6,-10,0,3,6,-9,0,3,6,-8,0,3,6,-7,0,3,6,-6,0,3,6,-5,0,3,6,-4,0,3,6,-3,0,3,6,-2,0,3,6,-1,0,3,6,0,0,3,6,1,0,3,6,2,0,3,6,3,0,3,6,4,0,3,7,-23,0,3,7,-22,0,3,7,-21,0,3,7,-20,0,3,7,-19,0,3,7,-18,0,3,7,-17,0,3,7,-16,0,3,7,-15,0,3,7,-14,0,3,7,-13,0,3,7,-12,0,3,7,-11,0,3,7,-10,0,3,7,-9,0,3,7,-8,0,3,7,-7,0,3,7,-6,0,3,7,-5,0,3,7,-4,0,3,7,-3,0,3,7,-2,0,3,7,-1,0,3,7,0,0,3,7,1,0,3,7,2,0,3,7,3,0,3,7,4,0,3,8,-23,0,3,8,-22,0,3,8,-21,0,3,8,-20,0,3,8,-19,0,3,8,-18,0,3,8,-17,0,3,8,-16,0,3,8,-15,0,3,8,-14,0,3,8,-13,0,3,8,-12,0,3,8,-11,0,3,8,-10,0,3,8,-9,0,3,8,-8,0,3,8,-7,0,3,8,-6,0,3,8,-5,0,3,8,-4,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,0,0,3,8,1,0,3,8,2,0,3,8,3,0,3,8,4,0,3,9,-23,0,3,9,-22,0,3,9,-21,0,3,9,-20,0,3,9,-19,0,3,9,-18,0,3,9,-17,0,3,9,-16,0,3,9,-15,0,3,9,-14,0,3,9,-13,0,3,9,-12,0,3,9,-11,0,3,9,-10,0,3,9,-9,0,3,9,-8,0,3,9,-7,0,3,9,-6,0,3,9,-5,0,3,9,-4,0,3,9,-3,0,3,9,-2,0,3,9,-1,0,3,9,0,0,3,9,1,0,3,9,2,0,3,9,3,0,3,9,4,0,3,10,-23,0,3,10,-22,0,3,10,-21,0,3,10,-20,0,3,10,-19,0,3,10,-18,0,3,10,-17,0,3,10,-16,0,3,10,-15,0,3,10,-14,0,3,10,-13,0,3,10,-12,0,3,10,-11,0,3,10,-10,0,3,10,-9,0,3,10,-8,0,3,10,-7,0,3,10,-6,0,3,10,-5,0,3,10,-4,0,3,10,-3,0,3,10,-2,0,3,10,-1,0,3,10,0,0,3,10,1,0,3,10,2,0,3,10,3,0,3,10,4,0,3,11,-23,0,3,11,-22,0,3,11,-21,0,3,11,-20,0,3,11,-19,0,3,11,-18,0,3,11,-17,0,3,11,-16,0,3,11,-15,0,3,11,-14,0,3,11,-13,0,3,11,-12,0,3,11,-11,0,3,11,-10,0,3,11,-9,0,3,11,-8,0,3,11,-7,0,3,11,-6,0,3,11,-5,0,3,11,-4,0,3,11,-3,0,3,11,-2,0,3,11,-1,0,3,11,0,0,3,11,1,0,3,11,2,0,3,11,3,0,3,11,4,0,3,12,-23,0,3,12,-22,0,3,12,-21,0,3,12,-20,0,3,12,-14,0,3,12,-13,0,3,12,-12,0,3,12,-11,0,3,12,-10,0,3,12,-9,0,3,12,-8,0,3,12,-7,0,3,12,-6,0,3,12,0,0,3,12,1,0,3,12,2,0,3,12,3,0,3,12,4,0,3,13,-23,0,3,13,-22,0,3,13,-21,0,3,13,-20,0,3,13,-14,0,3,13,-13,0,3,13,-12,0,3,13,-11,0,3,13,-10,0,3,13,-9,0,3,13,-8,0,3,13,-7,0,3,13,-6,0,3,13,0,0,3,13,1,0,3,13,2,0,3,13,3,0,3,13,4,0,3,14,-23,0,3,14,-22,0,3,14,-21,0,3,14,-20,0,3,14,-14,0,3,14,-13,0,3,14,-12,0,3,14,-11,0,3,14,-10,0,3,14,-9,0,3,14,-8,0,3,14,-7,0,3,14,-6,0,3,14,0,0,3,14,1,0,3,14,2,0,3,14,3,0,3,14,4,0,3,15,-23,0,3,15,-22,0,3,15,-21,0,3,15,-20,0,3,15,-14,0,3,15,-13,0,3,15,-12,0,3,15,-11,0,3,15,-10,0,3,15,-9,0,3,15,-8,0,3,15,-7,0,3,15,-6,0,3,15,0,0,3,15,1,0,3,15,2,0,3,15,3,0,3,15,4,0,3,16,-23,0,3,16,-22,0,3,16,-21,0,3,16,-20,0,3,16,-14,0,3,16,-13,0,3,16,-12,0,3,16,-11,0,3,16,-10,0,3,16,-9,0,3,16,-8,0,3,16,-7,0,3,16,-6,0,3,16,0,0,3,16,1,0,3,16,2,0,3,16,3,0,3,16,4,0,3,17,-23,0,3,17,-22,0,3,17,-21,0,3,17,-20,0,3,17,-19,0,3,17,-18,0,3,17,-17,0,3,17,-16,0,3,17,-15,0,3,17,-14,0,3,17,-13,0,3,17,-12,0,3,17,-11,0,3,17,-10,0,3,17,-9,0,3,17,-8,0,3,17,-7,0,3,17,-6,0,3,17,-5,0,3,17,-4,0,3,17,-3,0,3,17,-2,0,3,17,-1,0,3,17,0,0,3,17,1,0,3,17,2,0,3,17,3,0,3,17,4,0,3,18,-23,0,3,18,-22,0,3,18,-21,0,3,18,-20,0,3,18,-19,0,3,18,-18,0,3,18,-17,0,3,18,-16,0,3,18,-15,0,3,18,-14,0,3,18,-13,0,3,18,-12,0,3,18,-11,0,3,18,-10,0,3,18,-9,0,3,18,-8,0,3,18,-7,0,3,18,-6,0,3,18,-5,0,3,18,-4,0,3,18,-3,0,3,18,-2,0,3,18,-1,0,3,18,0,0,3,18,1,0,3,18,2,0,3,18,3,0,3,18,4,0,3,19,-23,0,3,19,-22,0,3,19,-21,0,3,19,-20,0,3,19,-19,0,3,19,-18,0,3,19,-17,0,3,19,-16,0,3,19,-15,0,3,19,-14,0,3,19,-13,0,3,19,-12,0,3,19,-11,0,3,19,-10,0,3,19,-9,0,3,19,-8,0,3,19,-7,0,3,19,-6,0,3,19,-5,0,3,19,-4,0,3,19,-3,0,3,19,-2,0,3,19,-1,0,3,19,0,0,3,19,1,0,3,19,2,0,3,19,3,0,3,19,4,0,3,20,-23,0,3,20,-22,0,3,20,-21,0,3,20,-20,0,3,20,-19,0,3,20,-18,0,3,20,-17,0,3,20,-16,0,3,20,-15,0,3,20,-14,0,3,20,-13,0,3,20,-12,0,3,20,-11,0,3,20,-10,0,3,20,-9,0,3,20,-8,0,3,20,-7,0,3,20,-6,0,3,20,-5,0,3,20,-4,0,3,20,-3,0,3,20,-2,0,3,20,-1,0,3,20,0,0,3,20,1,0,3,20,2,0,3,20,3,0,3,20,4,0,3],"Middle":[-11,-26,63,1,-11,-25,2,2,-11,-24,6,2,-10,-26,63,1,-10,-25,2,2,-10,-24,6,2,-9,-26,63,1,-9,-25,2,2,-9,-24,6,2,-8,-26,63,1,-8,-25,2,2,-8,-24,6,2,-7,-26,63,1,-7,-25,2,2,-7,-24,6,2,-6,-26,63,1,-6,-25,2,2,-6,-24,6,2,-6,-17,54,1,-6,-16,1,2,-6,-15,5,2,-6,-3,54,1,-6,-2,1,2,-6,-1,5,2,-5,-26,63,1,-5,-25,2,2,-5,-24,6,2,-5,-17,63,1,-5,-16,2,2,-5,-15,6,2,-5,-3,63,1,-5,-2,2,2,-5,-1,6,2,-4,-26,63,1,-4,-25,2,2,-4,-24,6,2,-4,-17,63,1,-4,-16,2,2,-4,-15,6,2,-4,-3,63,1,-4,-2,2,2,-4,-1,6,2,-3,-26,63,1,-3,-25,2,2,-3,-24,6,2,-3,-17,63,1,-3,-16,2,2,-3,-15,6,2,-3,-3,63,1,-3,-2,2,2,-3,-1,6,2,-2,-26,63,1,-2,-25,2,2,-2,-24,6,2,-2,-17,27,1,-2,-16,3,2,-2,-15,7,2,-2,-3,27,1,-2,-2,3,2,-2,-1,7,2,-1,-26,63,1,-1,-25,2,2,-1,-24,6,2,0,-26,63,1,0,-25,2,2,0,-24,6,2,1,-26,63,1,1,-25,2,2,1,-24,6,2,2,-26,63,1,2,-25,2,2,2,-24,6,2,3,-26,63,1,3,-25,2,2,3,-24,6,2,4,-26,63,1,4,-25,2,2,4,-24,6,2,5,-26,63,1,5,-25,2,2,5,-24,6,2,6,-26,63,1,6,-25,2,2,6,-24,6,2,7,-26,63,1,7,-25,2,2,7,-24,6,2,8,-26,63,1,8,-25,2,2,8,-24,6,2,9,-26,63,1,9,-25,2,2,9,-24,6,2,10,-26,63,1,10,-25,2,2,10,-24,6,2,11,-26,63,1,11,-25,2,2,11,-24,6,2,12,-26,63,1,12,-25,2,2,12,-24,6,2,12,-17,54,1,12,-16,1,2,12,-15,5,2,12,-3,54,1,12,-2,1,2,12,-1,5,2,13,-26,63,1,13,-25,2,2,13,-24,6,2,13,-17,63,1,13,-16,2,2,13,-15,6,2,13,-3,63,1,13,-2,2,2,13,-1,6,2,14,-26,63,1,14,-25,2,2,14,-24,6,2,14,-17,63,1,14,-16,2,2,14,-15,6,2,14,-3,63,1,14,-2,2,2,14,-1,6,2,15,-26,63,1,15,-25,2,2,15,-24,6,2,15,-17,63,1,15,-16,2,2,15,-15,6,2,15,-3,63,1,15,-2,2,2,15,-1,6,2,16,-26,63,1,16,-25,2,2,16,-24,6,2,16,-17,27,1,16,-16,3,2,16,-15,7,2,16,-3,27,1,16,-2,3,2,16,-1,7,2,17,-26,63,1,17,-25,2,2,17,-24,6,2,18,-26,63,1,18,-25,2,2,18,-24,6,2,19,-26,63,1,19,-25,2,2,19,-24,6,2,20,-26,63,1,20,-25,2,2,20,-24,6,2],"Top":[-13,-27,511,1,-13,-26,511,1,-13,-25,511,1,-13,-24,511,1,-13,-23,511,1,-13,-22,511,1,-13,-21,511,1,-13,-20,511,1,-13,-19,511,1,-13,-18,511,1,-13,-17,511,1,-13,-16,511,1,-13,-15,511,1,-13,-14,511,1,-13,-13,511,1,-13,-12,511,1,-13,-11,511,1,-13,-10,511,1,-13,-9,511,1,-13,-8,511,1,-13,-7,511,1,-13,-6,511,1,-13,-5,511,1,-13,-4,511,1,-13,-3,511,1,-13,-2,511,1,-13,-1,511,1,-13,0,511,1,-13,1,511,1,-13,2,511,1,-13,3,511,1,-13,4,511,1,-13,5,511,1,-13,6,511,1,-12,-27,511,1,-12,-26,255,1,-12,-25,219,1,-12,-24,219,1,-12,-23,219,1,-12,-22,219,1,-12,-21,219,1,-12,-20,219,1,-12,-19,219,1,-12,-18,219,1,-12,-17,219,1,-12,-16,219,1,-12,-15,219,1,-12,-14,219,1,-12,-13,219,1,-12,-12,219,1,-12,-11,219,1,-12,-10,219,1,-12,-9,219,1,-12,-8,219,1,-12,-7,219,1,-12,-6,219,1,-12,-5,219,1,-12,-4,219,1,-12,-3,219,1,-12,-2,219,1,-12,-1,219,1,-12,0,219,1,-12,1,219,1,-12,2,219,1,-12,3,219,1,-12,4,219,1,-12,5,507,1,-12,6,511,1,-11,-27,511,1,-11,5,504,1,-11,6,511,1,-10,-27,511,1,-10,5,504,1,-10,6,511,1,-9,-27,511,1,-9,5,504,1,-9,6,511,1,-8,-27,511,1,-8,5,504,1,-8,6,511,1,-7,-27,511,1,-7,5,504,1,-7,6,511,1,-6,-27,511,1,-6,-19,432,1,-6,-18,438,1,-6,-5,432,1,-6,-4,438,1,-6,5,504,1,-6,6,511,1,-5,-27,511,1,-5,-19,504,1,-5,-18,511,1,-5,-5,504,1,-5,-4,511,1,-5,5,504,1,-5,6,511,1,-4,-27,511,1,-4,-19,504,1,-4,-18,511,1,-4,-5,504,1,-4,-4,511,1,-4,5,504,1,-4,6,511,1,-3,-27,511,1,-3,-19,504,1,-3,-18,511,1,-3,-5,504,1,-3,-4,511,1,-3,5,504,1,-3,6,511,1,-2,-27,511,1,-2,-19,216,1,-2,-18,219,1,-2,-5,216,1,-2,-4,219,1,-2,5,504,1,-2,6,511,1,-1,-27,511,1,-1,5,504,1,-1,6,511,1,0,-27,511,1,0,5,504,1,0,6,511,1,1,-27,511,1,1,5,504,1,1,6,511,1,2,-27,511,1,2,5,504,1,2,6,511,1,3,-27,511,1,3,5,504,1,3,6,511,1,4,-27,511,1,4,5,504,1,4,6,511,1,5,-27,511,1,5,5,504,1,5,6,511,1,6,-27,511,1,6,5,504,1,6,6,511,1,7,-27,511,1,7,5,504,1,7,6,511,1,8,-27,511,1,8,5,504,1,8,6,511,1,9,-27,511,1,9,5,504,1,9,6,511,1,10,-27,511,1,10,5,504,1,10,6,511,1,11,-27,511,1,11,5,504,1,11,6,511,1,12,-27,511,1,12,-19,432,1,12,-18,438,1,12,-5,432,1,12,-4,438,1,12,5,504,1,12,6,511,1,13,-27,511,1,13,-19,504,1,13,-18,511,1,13,-5,504,1,13,-4,511,1,13,5,504,1,13,6,511,1,14,-27,511,1,14,-19,504,1,14,-18,511,1,14,-5,504,1,14,-4,511,1,14,5,504,1,14,6,511,1,15,-27,511,1,15,-19,504,1,15,-18,511,1,15,-5,504,1,15,-4,511,1,15,5,504,1,15,6,511,1,16,-27,511,1,16,-19,216,1,16,-18,219,1,16,-5,216,1,16,-4,219,1,16,5,504,1,16,6,511,1,17,-27,511,1,17,5,504,1,17,6,511,1,18,-27,511,1,18,5,504,1,18,6,511,1,19,-27,511,1,19,5,504,1,19,6,511,1,20,-27,511,1,20,5,504,1,20,6,511,1,21,-27,511,1,21,-26,447,1,21,-25,438,1,21,-24,438,1,21,-23,438,1,21,-22,438,1,21,-21,438,1,21,-20,438,1,21,-19,438,1,21,-18,438,1,21,-17,438,1,21,-16,438,1,21,-15,438,1,21,-14,438,1,21,-13,438,1,21,-12,438,1,21,-11,438,1,21,-10,438,1,21,-9,438,1,21,-8,438,1,21,-7,438,1,21,-6,438,1,21,-5,438,1,21,-4,438,1,21,-3,438,1,21,-2,438,1,21,-1,438,1,21,0,438,1,21,1,438,1,21,2,438,1,21,3,438,1,21,4,438,1,21,5,510,1,21,6,511,1,22,-27,511,1,22,-26,511,1,22,-25,511,1,22,-24,511,1,22,-23,511,1,22,-22,511,1,22,-21,511,1,22,-20,511,1,22,-19,511,1,22,-18,511,1,22,-17,511,1,22,-16,511,1,22,-15,511,1,22,-14,511,1,22,-13,511,1,22,-12,511,1,22,-11,511,1,22,-10,511,1,22,-9,511,1,22,-8,511,1,22,-7,511,1,22,-6,511,1,22,-5,511,1,22,-4,511,1,22,-3,511,1,22,-2,511,1,22,-1,511,1,22,0,511,1,22,1,511,1,22,2,511,1,22,3,511,1,22,4,511,1,22,5,511,1,22,6,511,1],"CustomFloor1":[],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[],"CustomMiddle2":[],"CustomTop":[]}
\ No newline at end of file
+{"NavigationVertices":[{"X":278,"Y":-218},{"X":278,"Y":-294},{"X":330,"Y":-362},{"X":330,"Y":90},{"X":-170,"Y":-362},{"X":186,"Y":-294},{"X":278,"Y":6},{"X":-170,"Y":90},{"X":186,"Y":6},{"X":-10,"Y":6},{"X":186,"Y":-70},{"X":-102,"Y":6},{"X":-102,"Y":-70},{"X":-10,"Y":-70},{"X":186,"Y":-218},{"X":-10,"Y":-218},{"X":-10,"Y":-294},{"X":-102,"Y":-294},{"X":-102,"Y":-218},{"X":278,"Y":-70}],"NavigationPolygon":[[0,1,2,3],[4,2,1,5],[6,3,7,8],[8,7,9,10],[11,9,7],[11,7,4,12],[10,9,13],[5,14,15,16],[4,5,16],[4,16,17],[4,17,18],[12,4,18],[13,12,18,15],[10,13,15,14],[19,10,14,0],[19,0,3],[19,3,6]],"Floor":[-11,-23,0,3,-11,-22,0,3,-11,-21,0,3,-11,-20,0,3,-11,-19,0,3,-11,-18,0,3,-11,-17,0,3,-11,-16,0,3,-11,-15,0,3,-11,-14,0,3,-11,-13,0,3,-11,-12,0,3,-11,-11,0,3,-11,-10,0,3,-11,-9,0,3,-11,-8,0,3,-11,-7,0,3,-11,-6,0,3,-11,-5,0,3,-11,-4,0,3,-11,-3,0,3,-11,-2,0,3,-11,-1,0,3,-11,0,0,3,-11,1,0,3,-11,2,0,3,-11,3,0,3,-11,4,0,3,-10,-23,0,3,-10,-22,0,3,-10,-21,0,3,-10,-20,0,3,-10,-19,0,3,-10,-18,0,3,-10,-17,0,3,-10,-16,0,3,-10,-15,0,3,-10,-14,0,3,-10,-13,0,3,-10,-12,0,3,-10,-11,0,3,-10,-10,0,3,-10,-9,0,3,-10,-8,0,3,-10,-7,0,3,-10,-6,0,3,-10,-5,0,3,-10,-4,0,3,-10,-3,0,3,-10,-2,0,3,-10,-1,0,3,-10,0,0,3,-10,1,0,3,-10,2,0,3,-10,3,0,3,-10,4,0,3,-9,-23,0,3,-9,-22,0,3,-9,-21,0,3,-9,-20,0,3,-9,-19,0,3,-9,-18,0,3,-9,-17,0,3,-9,-16,0,3,-9,-15,0,3,-9,-14,0,3,-9,-13,0,3,-9,-12,0,3,-9,-11,0,3,-9,-10,0,3,-9,-9,0,3,-9,-8,0,3,-9,-7,0,3,-9,-6,0,3,-9,-5,0,3,-9,-4,0,3,-9,-3,0,3,-9,-2,0,3,-9,-1,0,3,-9,0,0,3,-9,1,0,3,-9,2,0,3,-9,3,0,3,-9,4,0,3,-8,-23,0,3,-8,-22,0,3,-8,-21,0,3,-8,-20,0,3,-8,-19,0,3,-8,-18,0,3,-8,-17,0,3,-8,-16,0,3,-8,-15,0,3,-8,-14,0,3,-8,-13,0,3,-8,-12,0,3,-8,-11,0,3,-8,-10,0,3,-8,-9,0,3,-8,-8,0,3,-8,-7,0,3,-8,-6,0,3,-8,-5,0,3,-8,-4,0,3,-8,-3,0,3,-8,-2,0,3,-8,-1,0,3,-8,0,0,3,-8,1,0,3,-8,2,0,3,-8,3,0,3,-8,4,0,3,-7,-23,0,3,-7,-22,0,3,-7,-21,0,3,-7,-20,0,3,-7,-19,0,3,-7,-18,0,3,-7,-17,0,3,-7,-16,0,3,-7,-15,0,3,-7,-14,0,3,-7,-13,0,3,-7,-12,0,3,-7,-11,0,3,-7,-10,0,3,-7,-9,0,3,-7,-8,0,3,-7,-7,0,3,-7,-6,0,3,-7,-5,0,3,-7,-4,0,3,-7,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-7,4,0,3,-6,-23,0,3,-6,-22,0,3,-6,-21,0,3,-6,-20,0,3,-6,-14,0,3,-6,-13,0,3,-6,-12,0,3,-6,-11,0,3,-6,-10,0,3,-6,-9,0,3,-6,-8,0,3,-6,-7,0,3,-6,-6,0,3,-6,0,0,3,-6,1,0,3,-6,2,0,3,-6,3,0,3,-6,4,0,3,-5,-23,0,3,-5,-22,0,3,-5,-21,0,3,-5,-20,0,3,-5,-14,0,3,-5,-13,0,3,-5,-12,0,3,-5,-11,0,3,-5,-10,0,3,-5,-9,0,3,-5,-8,0,3,-5,-7,0,3,-5,-6,0,3,-5,0,0,3,-5,1,0,3,-5,2,0,3,-5,3,0,3,-5,4,0,3,-4,-23,0,3,-4,-22,0,3,-4,-21,0,3,-4,-20,0,3,-4,-14,0,3,-4,-13,0,3,-4,-12,0,3,-4,-11,0,3,-4,-10,0,3,-4,-9,0,3,-4,-8,0,3,-4,-7,0,3,-4,-6,0,3,-4,0,0,3,-4,1,0,3,-4,2,0,3,-4,3,0,3,-4,4,0,3,-3,-23,0,3,-3,-22,0,3,-3,-21,0,3,-3,-20,0,3,-3,-14,0,3,-3,-13,0,3,-3,-12,0,3,-3,-11,0,3,-3,-10,0,3,-3,-9,0,3,-3,-8,0,3,-3,-7,0,3,-3,-6,0,3,-3,0,0,3,-3,1,0,3,-3,2,0,3,-3,3,0,3,-3,4,0,3,-2,-23,0,3,-2,-22,0,3,-2,-21,0,3,-2,-20,0,3,-2,-14,0,3,-2,-13,0,3,-2,-12,0,3,-2,-11,0,3,-2,-10,0,3,-2,-9,0,3,-2,-8,0,3,-2,-7,0,3,-2,-6,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-2,4,0,3,-1,-23,0,3,-1,-22,0,3,-1,-21,0,3,-1,-20,0,3,-1,-19,0,3,-1,-18,0,3,-1,-17,0,3,-1,-16,0,3,-1,-15,0,3,-1,-14,0,3,-1,-13,0,3,-1,-12,0,3,-1,-11,0,3,-1,-10,0,3,-1,-9,0,3,-1,-8,0,3,-1,-7,0,3,-1,-6,0,3,-1,-5,0,3,-1,-4,0,3,-1,-3,0,3,-1,-2,0,3,-1,-1,0,3,-1,0,0,3,-1,1,0,3,-1,2,0,3,-1,3,0,3,-1,4,0,3,0,-23,0,3,0,-22,0,3,0,-21,0,3,0,-20,0,3,0,-19,0,3,0,-18,0,3,0,-17,0,3,0,-16,0,3,0,-15,0,3,0,-14,0,3,0,-13,0,3,0,-12,0,3,0,-11,0,3,0,-10,0,3,0,-9,0,3,0,-8,0,3,0,-7,0,3,0,-6,0,3,0,-5,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,0,1,0,3,0,2,0,3,0,3,0,3,0,4,0,3,1,-23,0,3,1,-22,0,3,1,-21,0,3,1,-20,0,3,1,-19,0,3,1,-18,0,3,1,-17,0,3,1,-16,0,3,1,-15,0,3,1,-14,0,3,1,-13,0,3,1,-12,0,3,1,-11,0,3,1,-10,0,3,1,-9,0,3,1,-8,0,3,1,-7,0,3,1,-6,0,3,1,-5,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,1,1,0,3,1,2,0,3,1,3,0,3,1,4,0,3,2,-23,0,3,2,-22,0,3,2,-21,0,3,2,-20,0,3,2,-19,0,3,2,-18,0,3,2,-17,0,3,2,-16,0,3,2,-15,0,3,2,-14,0,3,2,-13,0,3,2,-12,0,3,2,-11,0,3,2,-10,0,3,2,-9,0,3,2,-8,0,3,2,-7,0,3,2,-6,0,3,2,-5,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,2,1,0,3,2,2,0,3,2,3,0,3,2,4,0,3,3,-23,0,3,3,-22,0,3,3,-21,0,3,3,-20,0,3,3,-19,0,3,3,-18,0,3,3,-17,0,3,3,-16,0,3,3,-15,0,3,3,-14,0,3,3,-13,0,3,3,-12,0,3,3,-11,0,3,3,-10,0,3,3,-9,0,3,3,-8,0,3,3,-7,0,3,3,-6,0,3,3,-5,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,3,1,0,3,3,2,0,3,3,3,0,3,3,4,0,3,4,-23,0,3,4,-22,0,3,4,-21,0,3,4,-20,0,3,4,-19,0,3,4,-18,0,3,4,-17,0,3,4,-16,0,3,4,-15,0,3,4,-14,0,3,4,-13,0,3,4,-12,0,3,4,-11,0,3,4,-10,0,3,4,-9,0,3,4,-8,0,3,4,-7,0,3,4,-6,0,3,4,-5,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,4,1,0,3,4,2,0,3,4,3,0,3,4,4,0,3,5,-23,0,3,5,-22,0,3,5,-21,0,3,5,-20,0,3,5,-19,0,3,5,-18,0,3,5,-17,0,3,5,-16,0,3,5,-15,0,3,5,-14,0,3,5,-13,0,3,5,-12,0,3,5,-11,0,3,5,-10,0,3,5,-9,0,3,5,-8,0,3,5,-7,0,3,5,-6,0,3,5,-5,0,3,5,-4,0,3,5,-3,0,3,5,-2,0,3,5,-1,0,3,5,0,0,3,5,1,0,3,5,2,0,3,5,3,0,3,5,4,0,3,6,-23,0,3,6,-22,0,3,6,-21,0,3,6,-20,0,3,6,-19,0,3,6,-18,0,3,6,-17,0,3,6,-16,0,3,6,-15,0,3,6,-14,0,3,6,-13,0,3,6,-12,0,3,6,-11,0,3,6,-10,0,3,6,-9,0,3,6,-8,0,3,6,-7,0,3,6,-6,0,3,6,-5,0,3,6,-4,0,3,6,-3,0,3,6,-2,0,3,6,-1,0,3,6,0,0,3,6,1,0,3,6,2,0,3,6,3,0,3,6,4,0,3,7,-23,0,3,7,-22,0,3,7,-21,0,3,7,-20,0,3,7,-19,0,3,7,-18,0,3,7,-17,0,3,7,-16,0,3,7,-15,0,3,7,-14,0,3,7,-13,0,3,7,-12,0,3,7,-11,0,3,7,-10,0,3,7,-9,0,3,7,-8,0,3,7,-7,0,3,7,-6,0,3,7,-5,0,3,7,-4,0,3,7,-3,0,3,7,-2,0,3,7,-1,0,3,7,0,0,3,7,1,0,3,7,2,0,3,7,3,0,3,7,4,0,3,8,-23,0,3,8,-22,0,3,8,-21,0,3,8,-20,0,3,8,-19,0,3,8,-18,0,3,8,-17,0,3,8,-16,0,3,8,-15,0,3,8,-14,0,3,8,-13,0,3,8,-12,0,3,8,-11,0,3,8,-10,0,3,8,-9,0,3,8,-8,0,3,8,-7,0,3,8,-6,0,3,8,-5,0,3,8,-4,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,0,0,3,8,1,0,3,8,2,0,3,8,3,0,3,8,4,0,3,9,-23,0,3,9,-22,0,3,9,-21,0,3,9,-20,0,3,9,-19,0,3,9,-18,0,3,9,-17,0,3,9,-16,0,3,9,-15,0,3,9,-14,0,3,9,-13,0,3,9,-12,0,3,9,-11,0,3,9,-10,0,3,9,-9,0,3,9,-8,0,3,9,-7,0,3,9,-6,0,3,9,-5,0,3,9,-4,0,3,9,-3,0,3,9,-2,0,3,9,-1,0,3,9,0,0,3,9,1,0,3,9,2,0,3,9,3,0,3,9,4,0,3,10,-23,0,3,10,-22,0,3,10,-21,0,3,10,-20,0,3,10,-19,0,3,10,-18,0,3,10,-17,0,3,10,-16,0,3,10,-15,0,3,10,-14,0,3,10,-13,0,3,10,-12,0,3,10,-11,0,3,10,-10,0,3,10,-9,0,3,10,-8,0,3,10,-7,0,3,10,-6,0,3,10,-5,0,3,10,-4,0,3,10,-3,0,3,10,-2,0,3,10,-1,0,3,10,0,0,3,10,1,0,3,10,2,0,3,10,3,0,3,10,4,0,3,11,-23,0,3,11,-22,0,3,11,-21,0,3,11,-20,0,3,11,-19,0,3,11,-18,0,3,11,-17,0,3,11,-16,0,3,11,-15,0,3,11,-14,0,3,11,-13,0,3,11,-12,0,3,11,-11,0,3,11,-10,0,3,11,-9,0,3,11,-8,0,3,11,-7,0,3,11,-6,0,3,11,-5,0,3,11,-4,0,3,11,-3,0,3,11,-2,0,3,11,-1,0,3,11,0,0,3,11,1,0,3,11,2,0,3,11,3,0,3,11,4,0,3,12,-23,0,3,12,-22,0,3,12,-21,0,3,12,-20,0,3,12,-14,0,3,12,-13,0,3,12,-12,0,3,12,-11,0,3,12,-10,0,3,12,-9,0,3,12,-8,0,3,12,-7,0,3,12,-6,0,3,12,0,0,3,12,1,0,3,12,2,0,3,12,3,0,3,12,4,0,3,13,-23,0,3,13,-22,0,3,13,-21,0,3,13,-20,0,3,13,-14,0,3,13,-13,0,3,13,-12,0,3,13,-11,0,3,13,-10,0,3,13,-9,0,3,13,-8,0,3,13,-7,0,3,13,-6,0,3,13,0,0,3,13,1,0,3,13,2,0,3,13,3,0,3,13,4,0,3,14,-23,0,3,14,-22,0,3,14,-21,0,3,14,-20,0,3,14,-14,0,3,14,-13,0,3,14,-12,0,3,14,-11,0,3,14,-10,0,3,14,-9,0,3,14,-8,0,3,14,-7,0,3,14,-6,0,3,14,0,0,3,14,1,0,3,14,2,0,3,14,3,0,3,14,4,0,3,15,-23,0,3,15,-22,0,3,15,-21,0,3,15,-20,0,3,15,-14,0,3,15,-13,0,3,15,-12,0,3,15,-11,0,3,15,-10,0,3,15,-9,0,3,15,-8,0,3,15,-7,0,3,15,-6,0,3,15,0,0,3,15,1,0,3,15,2,0,3,15,3,0,3,15,4,0,3,16,-23,0,3,16,-22,0,3,16,-21,0,3,16,-20,0,3,16,-14,0,3,16,-13,0,3,16,-12,0,3,16,-11,0,3,16,-10,0,3,16,-9,0,3,16,-8,0,3,16,-7,0,3,16,-6,0,3,16,0,0,3,16,1,0,3,16,2,0,3,16,3,0,3,16,4,0,3,17,-23,0,3,17,-22,0,3,17,-21,0,3,17,-20,0,3,17,-19,0,3,17,-18,0,3,17,-17,0,3,17,-16,0,3,17,-15,0,3,17,-14,0,3,17,-13,0,3,17,-12,0,3,17,-11,0,3,17,-10,0,3,17,-9,0,3,17,-8,0,3,17,-7,0,3,17,-6,0,3,17,-5,0,3,17,-4,0,3,17,-3,0,3,17,-2,0,3,17,-1,0,3,17,0,0,3,17,1,0,3,17,2,0,3,17,3,0,3,17,4,0,3,18,-23,0,3,18,-22,0,3,18,-21,0,3,18,-20,0,3,18,-19,0,3,18,-18,0,3,18,-17,0,3,18,-16,0,3,18,-15,0,3,18,-14,0,3,18,-13,0,3,18,-12,0,3,18,-11,0,3,18,-10,0,3,18,-9,0,3,18,-8,0,3,18,-7,0,3,18,-6,0,3,18,-5,0,3,18,-4,0,3,18,-3,0,3,18,-2,0,3,18,-1,0,3,18,0,0,3,18,1,0,3,18,2,0,3,18,3,0,3,18,4,0,3,19,-23,0,3,19,-22,0,3,19,-21,0,3,19,-20,0,3,19,-19,0,3,19,-18,0,3,19,-17,0,3,19,-16,0,3,19,-15,0,3,19,-14,0,3,19,-13,0,3,19,-12,0,3,19,-11,0,3,19,-10,0,3,19,-9,0,3,19,-8,0,3,19,-7,0,3,19,-6,0,3,19,-5,0,3,19,-4,0,3,19,-3,0,3,19,-2,0,3,19,-1,0,3,19,0,0,3,19,1,0,3,19,2,0,3,19,3,0,3,19,4,0,3,20,-23,0,3,20,-22,0,3,20,-21,0,3,20,-20,0,3,20,-19,0,3,20,-18,0,3,20,-17,0,3,20,-16,0,3,20,-15,0,3,20,-14,0,3,20,-13,0,3,20,-12,0,3,20,-11,0,3,20,-10,0,3,20,-9,0,3,20,-8,0,3,20,-7,0,3,20,-6,0,3,20,-5,0,3,20,-4,0,3,20,-3,0,3,20,-2,0,3,20,-1,0,3,20,0,0,3,20,1,0,3,20,2,0,3,20,3,0,3,20,4,0,3],"CustomFloor1":[],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[],"CustomMiddle2":[],"CustomTop":[]}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle5/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle5/Preview.png
index d47180e..9e8b909 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle5/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle5/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle5/TileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle5/TileInfo.json
index 37b48eb..6061423 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle5/TileInfo.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle5/TileInfo.json
@@ -1 +1 @@
-{"NavigationVertices":[{"X":10,"Y":-186},{"X":42,"Y":-186},{"X":42,"Y":-154},{"X":-26,"Y":-78},{"X":-70,"Y":-78},{"X":74,"Y":-154},{"X":74,"Y":-106},{"X":6,"Y":-14},{"X":-26,"Y":-14},{"X":106,"Y":-106},{"X":106,"Y":-74},{"X":122,"Y":-74},{"X":122,"Y":-42},{"X":6,"Y":66},{"X":138,"Y":-42},{"X":138,"Y":66},{"X":-70,"Y":66},{"X":-122,"Y":66},{"X":-122,"Y":-234},{"X":10,"Y":-234}],"NavigationPolygon":[[0,1,2,3,4],[3,2,5,6,7,8],[6,9,10,7],[7,10,11,12,13],[12,14,15,13],[4,16,17,18],[4,18,19,0]],"Floor":[-8,-15,0,3,-8,-14,0,3,-8,-13,0,3,-8,-12,0,3,-8,-11,0,3,-8,-10,0,3,-7,-15,0,3,-7,-14,0,3,-7,-13,0,3,-7,-12,0,3,-7,-11,0,3,-7,-10,0,3,-6,-15,0,3,-6,-14,0,3,-6,-13,0,3,-6,-12,0,3,-6,-11,0,3,-6,-10,0,3,-5,-15,0,3,-5,-14,0,3,-5,-13,0,3,-5,-12,0,3,-5,-11,0,3,-5,-10,0,3,-4,-15,0,3,-4,-14,0,3,-4,-13,0,3,-4,-12,0,3,-4,-11,0,3,-4,-10,0,3,-4,-9,0,3,-4,-8,0,3,-4,-7,0,3,-4,-6,0,3,-3,-15,0,3,-3,-14,0,3,-3,-13,0,3,-3,-12,0,3,-3,-11,0,3,-3,-10,0,3,-3,-9,0,3,-3,-8,0,3,-3,-7,0,3,-3,-6,0,3,-2,-15,0,3,-2,-14,0,3,-2,-13,0,3,-2,-12,0,3,-2,-11,0,3,-2,-10,0,3,-2,-9,0,3,-2,-8,0,3,-2,-7,0,3,-2,-6,0,3,-2,-5,0,3,-2,-4,0,3,-2,-3,0,3,-2,-2,0,3,-1,-15,0,3,-1,-14,0,3,-1,-13,0,3,-1,-12,0,3,-1,-11,0,3,-1,-10,0,3,-1,-9,0,3,-1,-8,0,3,-1,-7,0,3,-1,-6,0,3,-1,-5,0,3,-1,-4,0,3,-1,-3,0,3,-1,-2,0,3,0,-15,0,3,0,-14,0,3,0,-13,0,3,0,-12,0,3,0,-11,0,3,0,-10,0,3,0,-9,0,3,0,-8,0,3,0,-7,0,3,0,-6,0,3,0,-5,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,1,-12,0,3,1,-11,0,3,1,-10,0,3,1,-9,0,3,1,-8,0,3,1,-7,0,3,1,-6,0,3,1,-5,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,2,-12,0,3,2,-11,0,3,2,-10,0,3,2,-9,0,3,2,-8,0,3,2,-7,0,3,2,-6,0,3,2,-5,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,3,-10,0,3,3,-9,0,3,3,-8,0,3,3,-7,0,3,3,-6,0,3,3,-5,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,4,-10,0,3,4,-9,0,3,4,-8,0,3,4,-7,0,3,4,-6,0,3,4,-5,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,5,-7,0,3,5,-6,0,3,5,-5,0,3,5,-4,0,3,5,-3,0,3,5,-2,0,3,6,-7,0,3,6,-6,0,3,6,-5,0,3,6,-4,0,3,6,-3,0,3,6,-2,0,3,7,-5,0,3,7,-4,0,3,7,-3,0,3,7,-2,0,3,0,-1,0,3,0,0,0,3,0,1,0,3,0,2,0,3,1,-1,0,3,1,0,0,3,1,1,0,3,1,2,0,3,2,-1,0,3,2,0,0,3,2,1,0,3,2,2,0,3,3,-1,0,3,3,0,0,3,3,1,0,3,3,2,0,3,4,-1,0,3,4,0,0,3,4,1,0,3,4,2,0,3,5,-1,0,3,5,0,0,3,5,1,0,3,5,2,0,3,6,-1,0,3,6,0,0,3,6,1,0,3,6,2,0,3,7,-1,0,3,7,0,0,3,7,1,0,3,7,2,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,0,0,3,8,1,0,3,8,2,0,3,-8,-9,0,3,-8,-8,0,3,-8,-7,0,3,-8,-6,0,3,-8,-5,0,3,-8,-4,0,3,-8,-3,0,3,-8,-2,0,3,-8,-1,0,3,-8,0,0,3,-8,1,0,3,-8,2,0,3,-8,3,0,3,-7,-9,0,3,-7,-8,0,3,-7,-7,0,3,-7,-6,0,3,-7,-5,0,3,-7,-4,0,3,-7,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-6,-9,0,3,-6,-8,0,3,-6,-7,0,3,-6,-6,0,3,-6,-5,0,3,-6,-4,0,3,-6,-3,0,3,-6,-2,0,3,-6,-1,0,3,-6,0,0,3,-6,1,0,3,-6,2,0,3,-6,3,0,3,-5,-9,0,3,-5,-8,0,3,-5,-7,0,3,-5,-6,0,3,-5,-5,0,3,-5,-4,0,3,-5,-3,0,3,-5,-2,0,3,-5,-1,0,3,-5,0,0,3,-5,1,0,3,-5,2,0,3,-5,3,0,3,0,3,0,3,1,3,0,3,2,3,0,3,3,3,0,3,4,3,0,3,5,3,0,3,6,3,0,3,7,3,0,3,8,3,0,3],"Middle":[-8,-18,63,1,-8,-17,2,2,-8,-16,6,2,-7,-18,63,1,-7,-17,2,2,-7,-16,6,2,-6,-18,63,1,-6,-17,2,2,-6,-16,6,2,-5,-18,63,1,-5,-17,2,2,-5,-16,6,2,-4,-18,63,1,-4,-17,2,2,-4,-16,6,2,-3,-18,63,1,-3,-17,2,2,-3,-16,6,2,-2,-18,63,1,-2,-17,2,2,-2,-16,6,2,-1,-18,63,1,-1,-17,2,2,-1,-16,6,2,0,-18,63,1,0,-17,2,2,0,-16,6,2,1,-15,54,1,1,-14,1,2,1,-13,5,2,2,-15,63,1,2,-14,2,2,2,-13,6,2,3,-13,54,1,3,-12,1,2,3,-11,5,2,4,-13,63,1,4,-12,2,2,4,-11,6,2,5,-10,54,1,5,-9,1,2,5,-8,5,2,6,-10,63,1,6,-9,2,2,6,-8,6,2,7,-8,54,1,7,-7,1,2,7,-6,5,2,8,-6,54,1,8,-5,1,2,8,-4,5,2],"Top":[-10,-19,511,1,-10,-18,511,1,-10,-17,511,1,-10,-16,511,1,-10,-15,511,1,-10,-14,511,1,-10,-13,511,1,-10,-12,511,1,-10,-11,511,1,-10,-10,511,1,-10,-9,511,1,-10,-8,511,1,-10,-7,511,1,-10,-6,511,1,-10,-5,511,1,-10,-4,511,1,-10,-3,511,1,-10,-2,511,1,-10,-1,511,1,-10,0,511,1,-10,1,511,1,-10,2,511,1,-10,3,511,1,-10,4,511,1,-10,5,511,1,-9,-19,511,1,-9,-18,255,1,-9,-17,219,1,-9,-16,219,1,-9,-15,219,1,-9,-14,219,1,-9,-13,219,1,-9,-12,219,1,-9,-11,219,1,-9,-10,219,1,-9,-9,219,1,-9,-8,219,1,-9,-7,219,1,-9,-6,219,1,-9,-5,219,1,-9,-4,219,1,-9,-3,219,1,-9,-2,219,1,-9,-1,219,1,-9,0,219,1,-9,1,219,1,-9,2,219,1,-9,3,219,1,-9,4,507,1,-9,5,511,1,-8,-19,511,1,-8,4,504,1,-8,5,511,1,-7,-19,511,1,-7,4,504,1,-7,5,511,1,-6,-19,511,1,-6,4,504,1,-6,5,511,1,-5,-19,511,1,-5,4,504,1,-5,5,511,1,-4,-19,511,1,-4,-5,432,1,-4,-4,438,1,-4,-3,438,1,-4,-2,438,1,-4,-1,438,1,-4,0,438,1,-4,1,438,1,-4,2,438,1,-4,3,438,1,-4,4,510,1,-4,5,511,1,-3,-19,511,1,-3,-5,216,1,-3,-4,219,1,-3,-3,219,1,-3,-2,219,1,-3,-1,507,1,-3,0,511,1,-3,1,511,1,-3,2,511,1,-3,3,511,1,-3,4,511,1,-3,5,511,1,-2,-19,511,1,-2,-1,504,1,-2,0,511,1,-2,1,511,1,-2,2,511,1,-2,3,511,1,-2,4,511,1,-2,5,511,1,-1,-19,511,1,-1,-1,216,1,-1,0,219,1,-1,1,219,1,-1,2,219,1,-1,3,219,1,-1,4,507,1,-1,5,511,1,0,-19,511,1,0,4,504,1,0,5,511,1,1,-19,511,1,1,-18,447,1,1,-17,438,1,1,-16,438,1,1,4,504,1,1,5,511,1,2,-19,511,1,2,-18,511,1,2,-17,511,1,2,-16,511,1,2,4,504,1,2,5,511,1,3,-16,511,1,3,-15,447,1,3,-14,438,1,3,4,504,1,3,5,511,1,4,-16,511,1,4,-15,511,1,4,-14,511,1,4,4,504,1,4,5,511,1,5,-14,511,1,5,-13,447,1,5,-12,438,1,5,-11,438,1,5,4,504,1,5,5,511,1,6,-14,511,1,6,-13,511,1,6,-12,511,1,6,-11,511,1,6,4,504,1,6,5,511,1,7,-11,511,1,7,-10,447,1,7,-9,438,1,7,4,504,1,7,5,511,1,8,-11,511,1,8,-10,511,1,8,-9,511,1,8,-8,447,1,8,-7,438,1,8,4,504,1,8,5,511,1,9,-9,511,1,9,-8,511,1,9,-7,511,1,9,-6,447,1,9,-5,438,1,9,-4,438,1,9,-3,438,1,9,-2,438,1,9,-1,438,1,9,0,438,1,9,1,438,1,9,2,438,1,9,3,438,1,9,4,510,1,9,5,511,1,10,-7,511,1,10,-6,511,1,10,-5,511,1,10,-4,511,1,10,-3,511,1,10,-2,511,1,10,-1,511,1,10,0,511,1,10,1,511,1,10,2,511,1,10,3,511,1,10,4,511,1,10,5,511,1],"CustomFloor1":[],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[],"CustomMiddle2":[],"CustomTop":[]}
\ No newline at end of file
+{"NavigationVertices":[{"X":10,"Y":-186},{"X":42,"Y":-186},{"X":42,"Y":-154},{"X":-26,"Y":-70},{"X":-70,"Y":-70},{"X":74,"Y":-154},{"X":74,"Y":-106},{"X":6,"Y":-6},{"X":-26,"Y":-6},{"X":106,"Y":-106},{"X":106,"Y":-74},{"X":122,"Y":-74},{"X":122,"Y":-42},{"X":6,"Y":74},{"X":138,"Y":-42},{"X":138,"Y":74},{"X":-70,"Y":74},{"X":-122,"Y":74},{"X":-122,"Y":-234},{"X":10,"Y":-234}],"NavigationPolygon":[[0,1,2,3,4],[3,2,5,6,7,8],[6,9,10,7],[7,10,11,12,13],[12,14,15,13],[4,16,17,18],[4,18,19,0]],"Floor":[-8,-15,0,3,-8,-14,0,3,-8,-13,0,3,-8,-12,0,3,-8,-11,0,3,-8,-10,0,3,-7,-15,0,3,-7,-14,0,3,-7,-13,0,3,-7,-12,0,3,-7,-11,0,3,-7,-10,0,3,-6,-15,0,3,-6,-14,0,3,-6,-13,0,3,-6,-12,0,3,-6,-11,0,3,-6,-10,0,3,-5,-15,0,3,-5,-14,0,3,-5,-13,0,3,-5,-12,0,3,-5,-11,0,3,-5,-10,0,3,-4,-15,0,3,-4,-14,0,3,-4,-13,0,3,-4,-12,0,3,-4,-11,0,3,-4,-10,0,3,-4,-9,0,3,-4,-8,0,3,-4,-7,0,3,-4,-6,0,3,-3,-15,0,3,-3,-14,0,3,-3,-13,0,3,-3,-12,0,3,-3,-11,0,3,-3,-10,0,3,-3,-9,0,3,-3,-8,0,3,-3,-7,0,3,-3,-6,0,3,-2,-15,0,3,-2,-14,0,3,-2,-13,0,3,-2,-12,0,3,-2,-11,0,3,-2,-10,0,3,-2,-9,0,3,-2,-8,0,3,-2,-7,0,3,-2,-6,0,3,-2,-5,0,3,-2,-4,0,3,-2,-3,0,3,-2,-2,0,3,-1,-15,0,3,-1,-14,0,3,-1,-13,0,3,-1,-12,0,3,-1,-11,0,3,-1,-10,0,3,-1,-9,0,3,-1,-8,0,3,-1,-7,0,3,-1,-6,0,3,-1,-5,0,3,-1,-4,0,3,-1,-3,0,3,-1,-2,0,3,0,-15,0,3,0,-14,0,3,0,-13,0,3,0,-12,0,3,0,-11,0,3,0,-10,0,3,0,-9,0,3,0,-8,0,3,0,-7,0,3,0,-6,0,3,0,-5,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,1,-12,0,3,1,-11,0,3,1,-10,0,3,1,-9,0,3,1,-8,0,3,1,-7,0,3,1,-6,0,3,1,-5,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,2,-12,0,3,2,-11,0,3,2,-10,0,3,2,-9,0,3,2,-8,0,3,2,-7,0,3,2,-6,0,3,2,-5,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,3,-10,0,3,3,-9,0,3,3,-8,0,3,3,-7,0,3,3,-6,0,3,3,-5,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,4,-10,0,3,4,-9,0,3,4,-8,0,3,4,-7,0,3,4,-6,0,3,4,-5,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,5,-7,0,3,5,-6,0,3,5,-5,0,3,5,-4,0,3,5,-3,0,3,5,-2,0,3,6,-7,0,3,6,-6,0,3,6,-5,0,3,6,-4,0,3,6,-3,0,3,6,-2,0,3,7,-5,0,3,7,-4,0,3,7,-3,0,3,7,-2,0,3,0,-1,0,3,0,0,0,3,0,1,0,3,0,2,0,3,1,-1,0,3,1,0,0,3,1,1,0,3,1,2,0,3,2,-1,0,3,2,0,0,3,2,1,0,3,2,2,0,3,3,-1,0,3,3,0,0,3,3,1,0,3,3,2,0,3,4,-1,0,3,4,0,0,3,4,1,0,3,4,2,0,3,5,-1,0,3,5,0,0,3,5,1,0,3,5,2,0,3,6,-1,0,3,6,0,0,3,6,1,0,3,6,2,0,3,7,-1,0,3,7,0,0,3,7,1,0,3,7,2,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,0,0,3,8,1,0,3,8,2,0,3,-8,-9,0,3,-8,-8,0,3,-8,-7,0,3,-8,-6,0,3,-8,-5,0,3,-8,-4,0,3,-8,-3,0,3,-8,-2,0,3,-8,-1,0,3,-8,0,0,3,-8,1,0,3,-8,2,0,3,-8,3,0,3,-7,-9,0,3,-7,-8,0,3,-7,-7,0,3,-7,-6,0,3,-7,-5,0,3,-7,-4,0,3,-7,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-6,-9,0,3,-6,-8,0,3,-6,-7,0,3,-6,-6,0,3,-6,-5,0,3,-6,-4,0,3,-6,-3,0,3,-6,-2,0,3,-6,-1,0,3,-6,0,0,3,-6,1,0,3,-6,2,0,3,-6,3,0,3,-5,-9,0,3,-5,-8,0,3,-5,-7,0,3,-5,-6,0,3,-5,-5,0,3,-5,-4,0,3,-5,-3,0,3,-5,-2,0,3,-5,-1,0,3,-5,0,0,3,-5,1,0,3,-5,2,0,3,-5,3,0,3,0,3,0,3,1,3,0,3,2,3,0,3,3,3,0,3,4,3,0,3,5,3,0,3,6,3,0,3,7,3,0,3,8,3,0,3],"CustomFloor1":[],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[],"CustomMiddle2":[],"CustomTop":[]}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle6/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle6/Preview.png
index 757a116..4bfb18e 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle6/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/battle/Battle6/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/boss/Boss1/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/boss/Boss1/Preview.png
index 478b35a..90aa2e0 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/boss/Boss1/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/boss/Boss1/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/boss/Boss1/TileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/boss/Boss1/TileInfo.json
index 29ba246..58234b0 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/boss/Boss1/TileInfo.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/boss/Boss1/TileInfo.json
@@ -1 +1 @@
-{"NavigationVertices":[{"X":198,"Y":54},{"X":234,"Y":82},{"X":-74,"Y":82},{"X":138,"Y":54},{"X":234,"Y":-154},{"X":198,"Y":-30},{"X":-74,"Y":-154},{"X":170,"Y":-30},{"X":-10,"Y":-110},{"X":22,"Y":-26},{"X":22,"Y":-78},{"X":170,"Y":2},{"X":138,"Y":2},{"X":-10,"Y":-78},{"X":-38,"Y":-26},{"X":-38,"Y":-110}],"NavigationPolygon":[[0,1,2,3],[4,1,0,5],[6,4,5,7,8],[9,10,7,11,12],[10,13,8],[9,12,3,2,14],[14,2,6,15],[8,15,6],[8,7,10]],"Floor":[-5,-10,0,3,-5,-9,0,3,-5,-8,0,3,-5,-7,0,3,-5,-6,0,3,-5,-5,0,3,-5,-4,0,3,-5,-3,0,3,-5,-2,0,3,-5,-1,0,3,-5,0,0,3,-5,1,0,3,-5,2,0,3,-5,3,0,3,-4,-10,0,3,-4,-9,0,3,-4,-8,0,3,-4,-7,0,3,-4,-6,0,3,-4,-5,0,3,-4,-4,0,3,-4,-3,0,3,-4,-2,0,3,-4,-1,0,3,-4,0,0,3,-4,1,0,3,-4,2,0,3,-4,3,0,3,-3,-10,0,3,-3,-9,0,3,-3,-8,0,3,-3,-7,0,3,-3,-6,0,3,-3,-5,0,3,-3,-4,0,3,-3,-3,0,3,-3,-2,0,3,-3,-1,0,3,-3,0,0,3,-3,1,0,3,-3,2,0,3,-3,3,0,3,-2,-10,0,3,-2,-9,0,3,-2,-8,0,3,-2,-2,0,3,-2,-1,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-1,-10,0,3,-1,-9,0,3,-1,-8,0,3,-1,-2,0,3,-1,-1,0,3,-1,0,0,3,-1,1,0,3,-1,2,0,3,-1,3,0,3,0,-10,0,3,0,-9,0,3,0,-8,0,3,0,-7,0,3,0,-6,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,0,1,0,3,0,2,0,3,0,3,0,3,1,-10,0,3,1,-9,0,3,1,-8,0,3,1,-7,0,3,1,-6,0,3,1,-5,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,1,1,0,3,1,2,0,3,1,3,0,3,2,-10,0,3,2,-9,0,3,2,-8,0,3,2,-7,0,3,2,-6,0,3,2,-5,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,2,1,0,3,2,2,0,3,2,3,0,3,3,-10,0,3,3,-9,0,3,3,-8,0,3,3,-7,0,3,3,-6,0,3,3,-5,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,3,1,0,3,3,2,0,3,3,3,0,3,4,-10,0,3,4,-9,0,3,4,-8,0,3,4,-7,0,3,4,-6,0,3,4,-5,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,4,1,0,3,4,2,0,3,4,3,0,3,5,-10,0,3,5,-9,0,3,5,-8,0,3,5,-7,0,3,5,-6,0,3,5,-5,0,3,5,-4,0,3,5,-3,0,3,5,-2,0,3,5,-1,0,3,5,0,0,3,5,1,0,3,5,2,0,3,5,3,0,3,6,-10,0,3,6,-9,0,3,6,-8,0,3,6,-7,0,3,6,-6,0,3,6,-5,0,3,6,-4,0,3,6,-3,0,3,6,-2,0,3,6,-1,0,3,6,0,0,3,6,1,0,3,6,2,0,3,6,3,0,3,7,-10,0,3,7,-9,0,3,7,-8,0,3,7,-7,0,3,7,-6,0,3,7,-5,0,3,7,-4,0,3,7,-3,0,3,7,-2,0,3,7,-1,0,3,7,2,0,3,7,3,0,3,8,-10,0,3,8,-9,0,3,8,-8,0,3,8,-7,0,3,8,-6,0,3,8,-5,0,3,8,-4,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,2,0,3,8,3,0,3,9,-10,0,3,9,-9,0,3,9,-8,0,3,9,-7,0,3,9,-6,0,3,9,-5,0,3,9,-4,0,3,9,-3,0,3,9,-2,0,3,9,-1,0,3,9,3,0,3,10,-10,0,3,10,-9,0,3,10,-8,0,3,10,-7,0,3,10,-6,0,3,10,-5,0,3,10,-4,0,3,10,-3,0,3,10,3,0,3,11,-10,0,3,11,-9,0,3,11,-8,0,3,11,-7,0,3,11,-6,0,3,11,-5,0,3,11,-4,0,3,11,-3,0,3,11,3,0,3,12,-10,0,3,12,-9,0,3,12,-8,0,3,12,-7,0,3,12,-6,0,3,12,-5,0,3,12,-4,0,3,12,-3,0,3,12,-2,0,3,12,-1,0,3,12,0,0,3,12,1,0,3,12,2,0,3,12,3,0,3,13,-10,0,3,13,-9,0,3,13,-8,0,3,13,-7,0,3,13,-6,0,3,13,-5,0,3,13,-4,0,3,13,-3,0,3,13,-2,0,3,13,-1,0,3,13,0,0,3,13,1,0,3,13,2,0,3,13,3,0,3,7,0,0,3,7,1,0,3,-5,4,0,3,-4,4,0,3,-3,4,0,3,-2,4,0,3,-1,4,0,3,0,4,0,3,1,4,0,3,2,4,0,3,3,4,0,3,4,4,0,3,5,4,0,3,6,4,0,3,7,4,0,3,8,4,0,3,9,4,0,3,10,4,0,3,11,4,0,3,12,4,0,3,13,4,0,3,14,-10,0,3,14,-9,0,3,14,-8,0,3,14,-7,0,3,14,-6,0,3,14,-5,0,3,14,-4,0,3,14,-3,0,3,14,-2,0,3,14,-1,0,3,14,0,0,3,14,1,0,3,14,2,0,3,14,3,0,3,14,4,0,3,10,-2,0,3,10,-1,0,3,-1,-7,0,3,-1,-6,0,3,8,0,0,3,8,1,0,3],"Middle":[-5,-13,63,1,-5,-12,2,2,-5,-11,6,2,-4,-13,63,1,-4,-12,2,2,-4,-11,6,2,-3,-13,63,1,-3,-12,2,2,-3,-11,6,2,-2,-13,63,1,-2,-12,2,2,-2,-11,6,2,-2,-5,50,1,-2,-4,1,2,-2,-3,5,2,-1,-13,63,1,-1,-12,2,2,-1,-11,6,2,-1,-5,56,1,-1,-4,2,2,-1,-3,6,2,0,-13,63,1,0,-12,2,2,0,-11,6,2,0,-5,24,1,0,-4,3,2,0,-3,7,2,1,-13,63,1,1,-12,2,2,1,-11,6,2,2,-13,63,1,2,-12,2,2,2,-11,6,2,3,-13,63,1,3,-12,2,2,3,-11,6,2,4,-13,63,1,4,-12,2,2,4,-11,6,2,5,-13,63,1,5,-12,2,2,5,-11,6,2,6,-13,63,1,6,-12,2,2,6,-11,6,2,7,-13,63,1,7,-12,2,2,7,-11,6,2,8,-13,63,1,8,-12,2,2,8,-11,6,2,9,-13,63,1,9,-12,2,2,9,-11,6,2,9,0,48,1,9,1,1,2,9,2,5,2,10,-13,63,1,10,-12,2,2,10,-11,6,2,10,0,56,1,10,1,2,2,10,2,6,2,11,-13,63,1,11,-12,2,2,11,-11,6,2,11,0,26,1,11,1,3,2,11,2,7,2,12,-13,63,1,12,-12,2,2,12,-11,6,2,13,-13,63,1,13,-12,2,2,13,-11,6,2,14,-13,63,1,14,-12,2,2,14,-11,6,2],"Top":[-7,-14,511,1,-7,-13,511,1,-7,-12,511,1,-7,-11,511,1,-7,-10,511,1,-7,-9,511,1,-7,-8,511,1,-7,-7,511,1,-7,-6,511,1,-7,-5,511,1,-7,-4,511,1,-7,-3,511,1,-7,-2,511,1,-7,-1,511,1,-7,0,511,1,-7,1,511,1,-7,2,511,1,-7,3,511,1,-7,4,511,1,-7,5,511,1,-7,6,511,1,-6,-14,511,1,-6,-13,255,1,-6,-12,219,1,-6,-11,219,1,-6,-10,219,1,-6,-9,219,1,-6,-8,219,1,-6,-7,219,1,-6,-6,219,1,-6,-5,219,1,-6,-4,219,1,-6,-3,219,1,-6,-2,219,1,-6,-1,219,1,-6,0,219,1,-6,1,219,1,-6,2,219,1,-6,3,219,1,-6,4,219,1,-6,5,507,1,-6,6,511,1,-5,-14,511,1,-5,5,504,1,-5,6,511,1,-4,-14,511,1,-4,5,504,1,-4,6,511,1,-3,-14,511,1,-3,5,504,1,-3,6,511,1,-2,-14,511,1,-2,-7,144,1,-2,-6,146,1,-2,5,504,1,-2,6,511,1,-1,-14,511,1,-1,5,504,1,-1,6,511,1,0,-14,511,1,0,5,504,1,0,6,511,1,1,-14,511,1,1,5,504,1,1,6,511,1,2,-14,511,1,2,5,504,1,2,6,511,1,3,-14,511,1,3,5,504,1,3,6,511,1,4,-14,511,1,4,5,504,1,4,6,511,1,5,-14,511,1,5,5,504,1,5,6,511,1,6,-14,511,1,6,5,504,1,6,6,511,1,7,-14,511,1,7,5,504,1,7,6,511,1,8,-14,511,1,8,5,504,1,8,6,511,1,9,-14,511,1,9,5,504,1,9,6,511,1,10,-14,511,1,10,5,504,1,10,6,511,1,11,-14,511,1,11,-2,144,1,11,-1,146,1,11,5,504,1,11,6,511,1,12,-14,511,1,12,5,504,1,12,6,511,1,13,-14,511,1,13,5,504,1,13,6,511,1,14,-14,511,1,14,5,504,1,14,6,511,1,15,-14,511,1,15,-13,447,1,15,-12,438,1,15,-11,438,1,15,-10,438,1,15,-9,438,1,15,-8,438,1,15,-7,438,1,15,-6,438,1,15,-5,438,1,15,-4,438,1,15,-3,438,1,15,-2,438,1,15,-1,438,1,15,0,438,1,15,1,438,1,15,2,438,1,15,3,438,1,15,4,438,1,15,5,510,1,15,6,511,1,16,-14,511,1,16,-13,511,1,16,-12,511,1,16,-11,511,1,16,-10,511,1,16,-9,511,1,16,-8,511,1,16,-7,511,1,16,-6,511,1,16,-5,511,1,16,-4,511,1,16,-3,511,1,16,-2,511,1,16,-1,511,1,16,0,511,1,16,1,511,1,16,2,511,1,16,3,511,1,16,4,511,1,16,5,511,1,16,6,511,1],"CustomFloor1":[],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[],"CustomMiddle2":[],"CustomTop":[]}
\ No newline at end of file
+{"NavigationVertices":[{"X":198,"Y":-22},{"X":170,"Y":-22},{"X":22,"Y":-26},{"X":22,"Y":-70},{"X":234,"Y":-154},{"X":234,"Y":90},{"X":198,"Y":54},{"X":-74,"Y":90},{"X":138,"Y":54},{"X":-74,"Y":-154},{"X":-10,"Y":-102},{"X":-10,"Y":-70},{"X":170,"Y":10},{"X":138,"Y":10},{"X":-38,"Y":-26},{"X":-38,"Y":-102}],"NavigationPolygon":[[0,1,2,3],[4,5,6,0],[6,5,7,8],[9,4,0,10],[3,11,10],[1,12,13,2],[2,13,8,7,14],[14,7,9,15],[10,15,9],[10,0,3]],"Floor":[-5,-10,0,3,-5,-9,0,3,-5,-8,0,3,-5,-7,0,3,-5,-6,0,3,-5,-5,0,3,-5,-4,0,3,-5,-3,0,3,-5,-2,0,3,-5,-1,0,3,-5,0,0,3,-5,1,0,3,-5,2,0,3,-5,3,0,3,-4,-10,0,3,-4,-9,0,3,-4,-8,0,3,-4,-7,0,3,-4,-6,0,3,-4,-5,0,3,-4,-4,0,3,-4,-3,0,3,-4,-2,0,3,-4,-1,0,3,-4,0,0,3,-4,1,0,3,-4,2,0,3,-4,3,0,3,-3,-10,0,3,-3,-9,0,3,-3,-8,0,3,-3,-7,0,3,-3,-6,0,3,-3,-5,0,3,-3,-4,0,3,-3,-3,0,3,-3,-2,0,3,-3,-1,0,3,-3,0,0,3,-3,1,0,3,-3,2,0,3,-3,3,0,3,-2,-10,0,3,-2,-9,0,3,-2,-8,0,3,-2,-2,0,3,-2,-1,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-1,-10,0,3,-1,-9,0,3,-1,-8,0,3,-1,-2,0,3,-1,-1,0,3,-1,0,0,3,-1,1,0,3,-1,2,0,3,-1,3,0,3,0,-10,0,3,0,-9,0,3,0,-8,0,3,0,-7,0,3,0,-6,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,0,1,0,3,0,2,0,3,0,3,0,3,1,-10,0,3,1,-9,0,3,1,-8,0,3,1,-7,0,3,1,-6,0,3,1,-5,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,1,1,0,3,1,2,0,3,1,3,0,3,2,-10,0,3,2,-9,0,3,2,-8,0,3,2,-7,0,3,2,-6,0,3,2,-5,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,2,1,0,3,2,2,0,3,2,3,0,3,3,-10,0,3,3,-9,0,3,3,-8,0,3,3,-7,0,3,3,-6,0,3,3,-5,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,3,1,0,3,3,2,0,3,3,3,0,3,4,-10,0,3,4,-9,0,3,4,-8,0,3,4,-7,0,3,4,-6,0,3,4,-5,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,4,1,0,3,4,2,0,3,4,3,0,3,5,-10,0,3,5,-9,0,3,5,-8,0,3,5,-7,0,3,5,-6,0,3,5,-5,0,3,5,-4,0,3,5,-3,0,3,5,-2,0,3,5,-1,0,3,5,0,0,3,5,1,0,3,5,2,0,3,5,3,0,3,6,-10,0,3,6,-9,0,3,6,-8,0,3,6,-7,0,3,6,-6,0,3,6,-5,0,3,6,-4,0,3,6,-3,0,3,6,-2,0,3,6,-1,0,3,6,0,0,3,6,1,0,3,6,2,0,3,6,3,0,3,7,-10,0,3,7,-9,0,3,7,-8,0,3,7,-7,0,3,7,-6,0,3,7,-5,0,3,7,-4,0,3,7,-3,0,3,7,-2,0,3,7,-1,0,3,7,2,0,3,7,3,0,3,8,-10,0,3,8,-9,0,3,8,-8,0,3,8,-7,0,3,8,-6,0,3,8,-5,0,3,8,-4,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,2,0,3,8,3,0,3,9,-10,0,3,9,-9,0,3,9,-8,0,3,9,-7,0,3,9,-6,0,3,9,-5,0,3,9,-4,0,3,9,-3,0,3,9,-2,0,3,9,-1,0,3,9,3,0,3,10,-10,0,3,10,-9,0,3,10,-8,0,3,10,-7,0,3,10,-6,0,3,10,-5,0,3,10,-4,0,3,10,-3,0,3,10,3,0,3,11,-10,0,3,11,-9,0,3,11,-8,0,3,11,-7,0,3,11,-6,0,3,11,-5,0,3,11,-4,0,3,11,-3,0,3,11,3,0,3,12,-10,0,3,12,-9,0,3,12,-8,0,3,12,-7,0,3,12,-6,0,3,12,-5,0,3,12,-4,0,3,12,-3,0,3,12,-2,0,3,12,-1,0,3,12,0,0,3,12,1,0,3,12,2,0,3,12,3,0,3,13,-10,0,3,13,-9,0,3,13,-8,0,3,13,-7,0,3,13,-6,0,3,13,-5,0,3,13,-4,0,3,13,-3,0,3,13,-2,0,3,13,-1,0,3,13,0,0,3,13,1,0,3,13,2,0,3,13,3,0,3,7,0,0,3,7,1,0,3,-5,4,0,3,-4,4,0,3,-3,4,0,3,-2,4,0,3,-1,4,0,3,0,4,0,3,1,4,0,3,2,4,0,3,3,4,0,3,4,4,0,3,5,4,0,3,6,4,0,3,7,4,0,3,8,4,0,3,9,4,0,3,10,4,0,3,11,4,0,3,12,4,0,3,13,4,0,3,14,-10,0,3,14,-9,0,3,14,-8,0,3,14,-7,0,3,14,-6,0,3,14,-5,0,3,14,-4,0,3,14,-3,0,3,14,-2,0,3,14,-1,0,3,14,0,0,3,14,1,0,3,14,2,0,3,14,3,0,3,14,4,0,3,10,-2,0,3,10,-1,0,3,-1,-7,0,3,-1,-6,0,3,8,0,0,3,8,1,0,3],"CustomFloor1":[],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[],"CustomMiddle2":[],"CustomTop":[]}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/Preinstall.json
index caaa543..0151d25 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/Preinstall.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/Preinstall.json
@@ -1 +1 @@
-[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":false,"WaveList":[[{"Position":{"X":39,"Y":8},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":-16,"Y":-18},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":66,"Y":6},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0009","Weight":100,"Attr":{"CurrAmmon":"1","ResidueAmmo":"25"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":66,"Y":47},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0010","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"120"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":47,"Y":-32},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0008","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"120"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":23,"Y":37},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":2,"Y":18},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0005","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":24,"Y":-30},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0006","Weight":100,"Attr":{"CurrAmmon":"20","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":40,"Y":-10},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0003","Weight":100,"Attr":{"CurrAmmon":"12","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":2,"Y":-37},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0007","Weight":100,"Attr":{"CurrAmmon":"60","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-2,"Y":47},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0002","Weight":100,"Attr":{"CurrAmmon":"7","ResidueAmmo":"70"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":29,"Y":63},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0013","Weight":100,"Attr":{"CurrAmmon":"50","ResidueAmmo":"250"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-30,"Y":39},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-19,"Y":71},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":48,"Y":29},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0004","Weight":100,"Attr":{"CurrAmmon":"180","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":20,"Y":94},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0014","Weight":100,"Attr":{"CurrAmmon":"5","ResidueAmmo":"60"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-14,"Y":97},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0011","Weight":100,"Attr":{"CurrAmmon":"20","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":9,"Y":-7},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0011","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-41,"Y":61},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0016","Weight":100,"Attr":{"CurrAmmon":"5","ResidueAmmo":"60"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":73,"Y":-19},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-72,"Y":71},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-67,"Y":50},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-91,"Y":46},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-92,"Y":74},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-26,"Y":-46},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-52,"Y":-33},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-79,"Y":-28},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-38,"Y":107},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5002","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":62,"Y":71},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]}]]}]
\ No newline at end of file
+[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":false,"WaveList":[[{"Position":{"X":39,"Y":8},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":-16,"Y":-18},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":66,"Y":6},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0009","Weight":100,"Attr":{"CurrAmmon":"1","ResidueAmmo":"25"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":66,"Y":47},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0010","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"120"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":47,"Y":-32},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0008","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"120"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":23,"Y":37},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":2,"Y":18},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0005","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":24,"Y":-30},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0006","Weight":100,"Attr":{"CurrAmmon":"20","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":40,"Y":-10},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0003","Weight":100,"Attr":{"CurrAmmon":"12","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":2,"Y":-37},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0007","Weight":100,"Attr":{"CurrAmmon":"60","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-2,"Y":47},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0002","Weight":100,"Attr":{"CurrAmmon":"7","ResidueAmmo":"70"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":29,"Y":63},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0013","Weight":100,"Attr":{"CurrAmmon":"50","ResidueAmmo":"250"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-30,"Y":39},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-19,"Y":71},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":48,"Y":29},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0004","Weight":100,"Attr":{"CurrAmmon":"180","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":20,"Y":94},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0014","Weight":100,"Attr":{"CurrAmmon":"5","ResidueAmmo":"60"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-14,"Y":97},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0011","Weight":100,"Attr":{"CurrAmmon":"20","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":9,"Y":-7},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0011","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-41,"Y":61},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0016","Weight":100,"Attr":{"CurrAmmon":"5","ResidueAmmo":"60"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":73,"Y":-19},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-72,"Y":71},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-67,"Y":50},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-91,"Y":46},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-92,"Y":74},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-26,"Y":-46},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-52,"Y":-33},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-79,"Y":-28},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-38,"Y":107},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5002","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":62,"Y":71},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":24,"Y":-15},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0014","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":71,"Y":-43},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0014","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-67,"Y":-101},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5004","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-84,"Y":-73},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5005","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]},{"Position":{"X":-54,"Y":-71},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5006","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":5.551115E-14}]}]]}]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/Preview.png
index beb8cab..65b6fc2 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/RoomInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/RoomInfo.json
index 5a7e0cd..6091345 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/RoomInfo.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/RoomInfo.json
@@ -1 +1 @@
-{"Position":{"X":-9,"Y":-11},"Size":{"X":20,"Y":21},"DoorAreaInfos":[{"Direction":2,"Start":48,"End":176},{"Direction":3,"Start":64,"End":208},{"Direction":0,"Start":80,"End":208},{"Direction":1,"Start":80,"End":224}],"GroupName":"Test1","RoomType":2,"RoomName":"Start","Weight":100,"Remark":""}
\ No newline at end of file
+{"Position":{"X":-9,"Y":-11},"Size":{"X":20,"Y":21},"DoorAreaInfos":[{"Direction":2,"Start":48,"End":176},{"Direction":3,"Start":0,"End":256},{"Direction":0,"Start":0,"End":208},{"Direction":1,"Start":0,"End":224}],"GroupName":"Test1","RoomType":2,"RoomName":"Start","Weight":100,"Remark":""}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/TileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/TileInfo.json
index e9bcf84..04f62db 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/TileInfo.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/inlet/Start/TileInfo.json
@@ -1 +1 @@
-{"NavigationVertices":[{"X":134,"Y":38},{"X":134,"Y":-6},{"X":138,"Y":-42},{"X":138,"Y":138},{"X":90,"Y":-122},{"X":90,"Y":-42},{"X":86,"Y":-58},{"X":86,"Y":-102},{"X":-42,"Y":-122},{"X":-38,"Y":-102},{"X":-42,"Y":-42},{"X":-38,"Y":-58},{"X":74,"Y":10},{"X":74,"Y":54},{"X":58,"Y":90},{"X":-26,"Y":38},{"X":-26,"Y":-6},{"X":90,"Y":-6},{"X":90,"Y":10},{"X":118,"Y":54},{"X":118,"Y":38},{"X":134,"Y":90},{"X":134,"Y":138},{"X":58,"Y":138},{"X":-58,"Y":138},{"X":-58,"Y":106},{"X":-86,"Y":38},{"X":-106,"Y":106},{"X":-106,"Y":-42},{"X":-86,"Y":-6}],"NavigationPolygon":[[0,1,2,3],[4,5,6,7],[8,4,7,9],[10,8,9,11],[12,13,14,15,16],[5,2,1,17],[17,18,12],[19,20,0,21],[3,22,21],[0,3,21],[19,21,14,13],[15,14,23,24,25],[26,15,25,27],[26,27,28,29],[29,28,10,16],[12,16,10,11,6,5,17]],"Floor":[-3,-4,0,3,-2,-4,0,3,-2,-3,0,3,-3,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-7,4,0,3,-7,5,0,3,-6,-3,0,3,-6,-2,0,3,-6,-1,0,3,-6,0,0,3,-6,1,0,3,-6,2,0,3,-6,3,0,3,-6,4,0,3,-6,5,0,3,-5,-3,0,3,-5,-2,0,3,-5,2,0,3,-5,3,0,3,-5,4,0,3,-5,5,0,3,-4,-3,0,3,-4,-2,0,3,-4,2,0,3,-4,3,0,3,-4,4,0,3,-4,5,0,3,-3,-2,0,3,-3,2,0,3,-3,3,0,3,-3,4,0,3,-3,5,0,3,-2,-2,0,3,-2,-1,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-2,4,0,3,-2,5,0,3,-4,6,0,3,-4,7,0,3,-3,6,0,3,-3,7,0,3,-2,6,0,3,-2,7,0,3,-1,3,0,3,-1,4,0,3,-1,7,0,3,0,3,0,3,0,4,0,3,0,7,0,3,1,3,0,3,1,4,0,3,1,5,0,3,1,6,0,3,1,7,0,3,2,3,0,3,2,4,0,3,2,5,0,3,2,6,0,3,2,7,0,3,3,3,0,3,3,4,0,3,3,5,0,3,3,6,0,3,-1,-4,0,3,-1,-3,0,3,-1,-2,0,3,-1,-1,0,3,-1,0,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,5,-4,0,3,5,-3,0,3,5,-1,0,3,3,1,0,3,3,2,0,3,4,1,0,3,4,2,0,3,4,3,0,3,4,4,0,3,5,3,0,3,5,4,0,3,6,3,0,3,6,4,0,3,6,-3,0,3,7,-3,0,3,7,-2,0,3,7,2,0,3,7,3,0,3,7,4,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,0,0,3,8,1,0,3,8,2,0,3,8,3,0,3,8,4,0,3,-1,2,0,3,0,2,0,3,1,2,0,3,2,2,0,3,2,1,0,3,1,1,0,3,0,1,0,3,-1,1,0,3,-1,5,0,3,0,5,0,3,0,6,0,3,-1,6,0,3,-7,-3,0,3,6,-2,0,3,5,-2,0,3,8,5,0,3,8,6,0,3,8,7,0,3,-3,-5,0,3,-3,-6,0,3,5,-6,0,3,5,-5,0,3,5,-7,0,3,-3,-7,0,3,5,-8,0,3,4,-8,0,3,3,-8,0,3,2,-8,0,3,1,-8,0,3,0,-8,0,3,-1,-8,0,3,-2,-8,0,3,-3,-8,0,3,3,7,0,3],"CustomFloor1":[-4,2,1,7,14,-3,3,1,8,15,-4,3,1,7,15,-5,3,1,6,15,6,4,1,8,15,5,4,1,7,15,-5,2,1,6,14,4,3,1,6,14,4,4,1,6,15,6,3,1,8,14,5,3,1,7,14,-3,2,1,8,14],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[-3,4,1,10,5,-3,5,1,10,6,2,4,1,10,5,2,5,1,10,6],"CustomMiddle2":[5,-4,1,6,0,5,-3,1,6,1,-2,-1,1,5,0,-2,0,1,5,1],"CustomTop":[]}
\ No newline at end of file
+{"NavigationVertices":[{"X":134,"Y":38},{"X":138,"Y":-122},{"X":138,"Y":138},{"X":134,"Y":90},{"X":134,"Y":-6},{"X":90,"Y":-6},{"X":86,"Y":-58},{"X":86,"Y":-102},{"X":-106,"Y":-122},{"X":-38,"Y":-102},{"X":74,"Y":10},{"X":74,"Y":54},{"X":58,"Y":90},{"X":-26,"Y":38},{"X":-26,"Y":-6},{"X":90,"Y":10},{"X":-38,"Y":-58},{"X":118,"Y":54},{"X":118,"Y":38},{"X":134,"Y":138},{"X":58,"Y":138},{"X":-58,"Y":138},{"X":-58,"Y":106},{"X":-86,"Y":38},{"X":-106,"Y":106},{"X":-86,"Y":-6}],"NavigationPolygon":[[0,1,2,3],[1,0,4],[1,4,5,6,7],[8,1,7,9],[10,11,12,13,14],[6,5,15,10,14,16],[17,18,0,3],[2,19,3],[17,3,12,11],[13,12,20,21,22],[23,13,22,24],[23,24,8,25],[25,8,9,16],[14,25,16]],"Floor":[-3,-4,0,3,-2,-4,0,3,-2,-3,0,3,-3,-3,0,3,-7,-2,0,3,-7,-1,0,3,-7,0,0,3,-7,1,0,3,-7,2,0,3,-7,3,0,3,-7,4,0,3,-7,5,0,3,-6,-3,0,3,-6,-2,0,3,-6,-1,0,3,-6,0,0,3,-6,1,0,3,-6,2,0,3,-6,3,0,3,-6,4,0,3,-6,5,0,3,-5,-3,0,3,-5,-2,0,3,-5,2,0,3,-5,3,0,3,-5,4,0,3,-5,5,0,3,-4,-3,0,3,-4,-2,0,3,-4,2,0,3,-4,3,0,3,-4,4,0,3,-4,5,0,3,-3,-2,0,3,-3,2,0,3,-3,3,0,3,-3,4,0,3,-3,5,0,3,-2,-2,0,3,-2,-1,0,3,-2,0,0,3,-2,1,0,3,-2,2,0,3,-2,3,0,3,-2,4,0,3,-2,5,0,3,-4,6,0,3,-4,7,0,3,-3,6,0,3,-3,7,0,3,-2,6,0,3,-2,7,0,3,-1,3,0,3,-1,4,0,3,-1,7,0,3,0,3,0,3,0,4,0,3,0,7,0,3,1,3,0,3,1,4,0,3,1,5,0,3,1,6,0,3,1,7,0,3,2,3,0,3,2,4,0,3,2,5,0,3,2,6,0,3,2,7,0,3,3,3,0,3,3,4,0,3,3,5,0,3,3,6,0,3,-1,-4,0,3,-1,-3,0,3,-1,-2,0,3,-1,-1,0,3,-1,0,0,3,0,-4,0,3,0,-3,0,3,0,-2,0,3,0,-1,0,3,0,0,0,3,1,-4,0,3,1,-3,0,3,1,-2,0,3,1,-1,0,3,1,0,0,3,2,-4,0,3,2,-3,0,3,2,-2,0,3,2,-1,0,3,2,0,0,3,3,-4,0,3,3,-3,0,3,3,-2,0,3,3,-1,0,3,3,0,0,3,4,-4,0,3,4,-3,0,3,4,-2,0,3,4,-1,0,3,4,0,0,3,5,-4,0,3,5,-3,0,3,5,-1,0,3,3,1,0,3,3,2,0,3,4,1,0,3,4,2,0,3,4,3,0,3,4,4,0,3,5,3,0,3,5,4,0,3,6,3,0,3,6,4,0,3,6,-3,0,3,7,-3,0,3,7,-2,0,3,7,2,0,3,7,3,0,3,7,4,0,3,8,-3,0,3,8,-2,0,3,8,-1,0,3,8,0,0,3,8,1,0,3,8,2,0,3,8,3,0,3,8,4,0,3,-1,2,0,3,0,2,0,3,1,2,0,3,2,2,0,3,2,1,0,3,1,1,0,3,0,1,0,3,-1,1,0,3,-1,5,0,3,0,5,0,3,0,6,0,3,-1,6,0,3,-7,-3,0,3,6,-2,0,3,5,-2,0,3,8,5,0,3,8,6,0,3,8,7,0,3,-3,-5,0,3,-3,-6,0,3,5,-6,0,3,5,-5,0,3,5,-7,0,3,-3,-7,0,3,5,-8,0,3,4,-8,0,3,3,-8,0,3,2,-8,0,3,1,-8,0,3,0,-8,0,3,-1,-8,0,3,-2,-8,0,3,-3,-8,0,3,3,7,0,3,-7,-8,0,3,-7,-7,0,3,-7,-6,0,3,-7,-5,0,3,-7,-4,0,3,-6,-8,0,3,-6,-7,0,3,-6,-6,0,3,-6,-5,0,3,-6,-4,0,3,-5,-8,0,3,-5,-7,0,3,-5,-6,0,3,-5,-5,0,3,-5,-4,0,3,-4,-8,0,3,-4,-7,0,3,-4,-6,0,3,-4,-5,0,3,-4,-4,0,3,6,-8,0,3,6,-7,0,3,6,-6,0,3,6,-5,0,3,6,-4,0,3,7,-8,0,3,7,-7,0,3,7,-6,0,3,7,-5,0,3,7,-4,0,3,8,-8,0,3,8,-7,0,3,8,-6,0,3,8,-5,0,3,8,-4,0,3],"CustomFloor1":[-4,2,1,7,14,-3,3,1,8,15,-4,3,1,7,15,-5,3,1,6,15,6,4,1,8,15,5,4,1,7,15,-5,2,1,6,14,4,3,1,6,14,4,4,1,6,15,6,3,1,8,14,5,3,1,7,14,-3,2,1,8,14],"CustomFloor2":[],"CustomFloor3":[],"CustomMiddle1":[-3,4,1,10,5,-3,5,1,10,6,2,4,1,10,5,2,5,1,10,6],"CustomMiddle2":[5,-4,1,6,0,5,-3,1,6,1,-2,-1,1,5,0,-2,0,1,5,1],"CustomTop":[]}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/outlet/End1/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/outlet/End1/Preview.png
index 3064845..572057f 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/outlet/End1/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/outlet/End1/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/reward/Reward1/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/reward/Reward1/Preinstall.json
index a9f951a..ad79eca 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/reward/Reward1/Preinstall.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/reward/Reward1/Preinstall.json
@@ -1 +1 @@
-[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":true,"WaveList":[[]]}]
\ No newline at end of file
+[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":true,"WaveList":[[{"Position":{"X":48,"Y":15},"Size":{"X":0,"Y":0},"SpecialMarkType":3,"DelayTime":0,"MarkList":[]}]]}]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/reward/Reward1/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/reward/Reward1/Preview.png
index 0a8e500..44451f1 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/reward/Reward1/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/reward/Reward1/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/shop/Shop1/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/Test1/shop/Shop1/Preinstall.json
index a9f951a..4c66c0f 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/shop/Shop1/Preinstall.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/shop/Shop1/Preinstall.json
@@ -1 +1 @@
-[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":true,"WaveList":[[]]}]
\ No newline at end of file
+[{"Name":"Preinstall1","Weight":100,"Remark":"","AutoFill":true,"WaveList":[[{"Position":{"X":0,"Y":0},"Size":{"X":0,"Y":0},"SpecialMarkType":4,"DelayTime":0,"MarkList":[]}]]}]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/Test1/shop/Shop1/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/Test1/shop/Shop1/Preview.png
index dfa0a6e..3f98607 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/Test1/shop/Shop1/Preview.png
+++ b/DungeonShooting_Godot/resource/map/tileMaps/Test1/shop/Shop1/Preview.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileSet/TileSet1/Main.png b/DungeonShooting_Godot/resource/map/tileSet/TileSet1/Main.png
index 193d030..f131d0a 100644
--- a/DungeonShooting_Godot/resource/map/tileSet/TileSet1/Main.png
+++ b/DungeonShooting_Godot/resource/map/tileSet/TileSet1/Main.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/map/tileSet/TileSet1/Test2.png b/DungeonShooting_Godot/resource/map/tileSet/TileSet1/Test2.png
index 78244d5..6fb9d7b 100644
--- a/DungeonShooting_Godot/resource/map/tileSet/TileSet1/Test2.png
+++ b/DungeonShooting_Godot/resource/map/tileSet/TileSet1/Test2.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/material/Blend.gdshader b/DungeonShooting_Godot/resource/material/Blend.gdshader
deleted file mode 100644
index 2fd8b76..0000000
--- a/DungeonShooting_Godot/resource/material/Blend.gdshader
+++ /dev/null
@@ -1,63 +0,0 @@
-shader_type canvas_item;
-
-//混合颜色
-uniform vec4 blend : source_color = vec4(1.0, 1.0, 1.0, 1.0);
-//混合度
-uniform float schedule : hint_range(0.0, 1.0, 0.01) = 0.0;
-//
-uniform vec4 modulate : source_color = vec4(1.0, 1.0, 1.0, 1.0);
-
-//------------------ 轮廓相关 --------------
-uniform bool show_outline = true;
-//轮廓颜色
-uniform vec4 outline_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
-//是否是彩虹轮廓
-uniform bool outline_rainbow = false;
-//轮廓是否使用 blend
-uniform bool outline_use_blend = true;
-//灰度
-uniform float grey : hint_range(0.0, 1.0, 0.01) = 0.0;
-
-//彩虹轮廓变化周期
-const float frequency = 0.25;
-const float light_offset = 0.5;
-
-void fragment() {
- float a = COLOR.a;
- //显示轮廓
- if (show_outline && a == 0.0) {
- vec2 size = TEXTURE_PIXEL_SIZE;
- float outline;
- outline = texture(TEXTURE, UV + vec2(-size.x, 0)).a;
- outline += texture(TEXTURE, UV + vec2(0, size.y)).a;
- outline += texture(TEXTURE, UV + vec2(size.x, 0)).a;
- outline += texture(TEXTURE, UV + vec2(0, -size.y)).a;
- outline = min(outline, 1.0);
- if (outline > 0.0) {
- if (outline_rainbow){
- vec4 animated_line_color = vec4(
- light_offset + sin(2.0 * 3.14 * frequency * TIME),
- light_offset + sin(2.0 * 3.14 * frequency * TIME + radians(120.0)),
- light_offset + sin(2.0 * 3.14 * frequency * TIME + radians(240.0)),
- 1.0
- );
- COLOR = mix(COLOR, animated_line_color, 1);
- a = animated_line_color.a;
- } else {
- COLOR = mix(COLOR, outline_color , 1);
- a = outline_color.a;
- }
- }
-
- if (outline_use_blend) {
- COLOR = mix(COLOR, blend, schedule);
- }
- } else { //非轮廓
- COLOR = mix(COLOR, blend, schedule);
- //灰度
- float grayColor = dot(COLOR.rgb, vec3(0.299, 0.587, 0.114));
- COLOR.rgb = mix(COLOR.rgb, vec3(grayColor), grey);
- }
- COLOR.a *= a;
- COLOR *= modulate;
-}
diff --git a/DungeonShooting_Godot/resource/material/Blend.tres b/DungeonShooting_Godot/resource/material/Blend.tres
index 707d8fa..5eb0079 100644
--- a/DungeonShooting_Godot/resource/material/Blend.tres
+++ b/DungeonShooting_Godot/resource/material/Blend.tres
@@ -1,6 +1,7 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://cces3bhds7jyi"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="1"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="1"]
+
[resource]
resource_local_to_scene = true
diff --git a/DungeonShooting_Godot/resource/material/GodRays.gdshader b/DungeonShooting_Godot/resource/material/GodRays.gdshader
deleted file mode 100644
index 4892b88..0000000
--- a/DungeonShooting_Godot/resource/material/GodRays.gdshader
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-Shader from Godot Shaders - the free shader library.
-godotshaders.com/shader/god-rays
-
-Feel free to use, improve and change this shader according to your needs
-and consider sharing the modified result on godotshaders.com.
-*/
-
-shader_type canvas_item;
-
-uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
-
-uniform float angle = -0.3;
-uniform float position = -0.2;
-uniform float spread : hint_range(0.0, 1.0) = 0.5;
-uniform float cutoff : hint_range(-1.0, 1.0) = 0.1;
-uniform float falloff : hint_range(0.0, 1.0) = 0.2;
-uniform float edge_fade : hint_range(0.0, 1.0) = 0.15;
-
-uniform float speed = 1.0;
-uniform float ray1_density = 8.0;
-uniform float ray2_density = 30.0;
-uniform float ray2_intensity : hint_range(0.0, 1.0) = 0.3;
-
-uniform vec4 color : source_color = vec4(1.0, 0.9, 0.65, 0.8);
-
-uniform bool hdr = false;
-uniform float seed = 5.0;
-
-float random(vec2 _uv) {
- _uv += min(TIME,0.0);
- return fract(sin(dot(_uv.xy, vec2(12.9898, 78.233))) * 43758.5453123);
-}
-
-float noise (in vec2 uv) {
- vec2 i = floor(uv);
- vec2 f = fract(uv);
-
- // Four corners in 2D of a tile
- float a = random(i);
- float b = random(i + vec2(1.0, 0.0));
- float c = random(i + vec2(0.0, 1.0));
- float d = random(i + vec2(1.0, 1.0));
-
-
- // Smooth Interpolation
-
- // Cubic Hermine Curve. Same as SmoothStep()
- vec2 u = f * f * (3.0-2.0 * f);
-
- // Mix 4 coorners percentages
- return mix(a, b, u.x) +
- (c - a)* u.y * (1.0 - u.x) +
- (d - b) * u.x * u.y;
-}
-
-mat2 rotate(float _angle){
- return mat2(vec2(cos(_angle), -sin(_angle)),
- vec2(sin(_angle), cos(_angle)));
-}
-
-vec4 screen(vec4 base, vec4 blend){
- return 1.0 - (1.0 - base) * (1.0 - blend);
-}
-
-void fragment()
-{
-
- // Rotate, skew and move the UVs
- vec2 transformed_uv = ( rotate(angle) * (UV - position) ) / ( (UV.y + spread) - (UV.y * spread) );
-
- // Animate the ray according the the new transformed UVs
- vec2 ray1 = vec2(transformed_uv.x * ray1_density + sin(TIME * 0.1 * speed) * (ray1_density * 0.2) + seed, 1.0);
- vec2 ray2 = vec2(transformed_uv.x * ray2_density + sin(TIME * 0.2 * speed) * (ray1_density * 0.2) + seed, 1.0);
-
- // Cut off the ray's edges
- float cut = step(cutoff, transformed_uv.x) * step(cutoff, 1.0 - transformed_uv.x);
- ray1 *= cut;
- ray2 *= cut;
-
- // Apply the noise pattern (i.e. create the rays)
- float rays;
-
- if (hdr){
- // This is not really HDR, but check this to not clamp the two merged rays making
- // their values go over 1.0. Can make for some nice effect
- rays = noise(ray1) + (noise(ray2) * ray2_intensity);
- }
- else{
- rays = clamp(noise(ray1) + (noise(ray2) * ray2_intensity), 0., 1.);
- }
-
- // Fade out edges
- rays *= smoothstep(0.0, falloff, (1.0 - UV.y)); // Bottom
- rays *= smoothstep(0.0 + cutoff, edge_fade + cutoff, transformed_uv.x); // Left
- rays *= smoothstep(0.0 + cutoff, edge_fade + cutoff, 1.0 - transformed_uv.x); // Right
-
- // Color to the rays
- vec3 shine = vec3(rays) * color.rgb;
-
- // Try different blending modes for a nicer effect. "Screen" is included in the code,
- // but take a look at https://godotshaders.com/snippet/blending-modes/ for more.
- // With "Screen" blend mode:
- shine = screen(texture(SCREEN_TEXTURE, SCREEN_UV), vec4(color)).rgb;
-
- COLOR = vec4(shine, rays * color.a);
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/material/Grid.gdshader b/DungeonShooting_Godot/resource/material/Grid.gdshader
deleted file mode 100644
index 571251f..0000000
--- a/DungeonShooting_Godot/resource/material/Grid.gdshader
+++ /dev/null
@@ -1,17 +0,0 @@
-shader_type canvas_item;
-render_mode blend_mix;
-
-uniform vec4 color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
-uniform vec2 size = vec2(1280.0, 720.0);
-uniform int line_width = 1;
-uniform vec2 offset = vec2(0.0, 0.0);
-uniform float grid_size = 16.0;
-
-void fragment() {
- vec2 uv = ((offset - vec2(float(line_width)) * 0.5f) / size) + UV;
- vec2 r = mod(size * uv, vec2(grid_size));
- vec2 lines = step(1.0 - float(line_width) / grid_size, r / vec2(grid_size));
- float alpha = dot(lines, vec2(1.0, 1.0));
- COLOR = color;
- COLOR.a *= alpha;
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/material/Grid.tres b/DungeonShooting_Godot/resource/material/Grid.tres
index 2b824d9..402ed51 100644
--- a/DungeonShooting_Godot/resource/material/Grid.tres
+++ b/DungeonShooting_Godot/resource/material/Grid.tres
@@ -1,6 +1,7 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://chcpnatun8hlf"]
-[ext_resource type="Shader" path="res://resource/material/Grid.gdshader" id="1_xhgfe"]
+[ext_resource type="Shader" path="res://resource/shader/Grid.gdshader" id="1_xhgfe"]
+
[resource]
resource_local_to_scene = true
diff --git a/DungeonShooting_Godot/resource/material/Mask.gdshader b/DungeonShooting_Godot/resource/material/Mask.gdshader
deleted file mode 100644
index 1c44ff4..0000000
--- a/DungeonShooting_Godot/resource/material/Mask.gdshader
+++ /dev/null
@@ -1,9 +0,0 @@
-shader_type canvas_item;
-
-uniform sampler2D mask_texture;
-
-void fragment() {
- vec2 size = TEXTURE_PIXEL_SIZE;
- COLOR.a = 1.0 - texture(mask_texture, UV).a;
-}
-
diff --git a/DungeonShooting_Godot/resource/material/OffsetVertex.gdshader b/DungeonShooting_Godot/resource/material/OffsetVertex.gdshader
deleted file mode 100644
index f63d041..0000000
--- a/DungeonShooting_Godot/resource/material/OffsetVertex.gdshader
+++ /dev/null
@@ -1,7 +0,0 @@
-shader_type canvas_item;
-
-uniform vec2 offset = vec2(0.0 , 0.0);
-
-void vertex() {
- VERTEX += offset;
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/material/Outline.gdshader b/DungeonShooting_Godot/resource/material/Outline.gdshader
deleted file mode 100644
index bb3072e..0000000
--- a/DungeonShooting_Godot/resource/material/Outline.gdshader
+++ /dev/null
@@ -1,22 +0,0 @@
-shader_type canvas_item;
-
-//轮廓颜色
-uniform vec4 outline_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
-
-void fragment() {
- float a = COLOR.a;
- //显示轮廓
- if (a == 0.0) {
- vec2 size = TEXTURE_PIXEL_SIZE;
- float outline;
- outline = texture(TEXTURE, UV + vec2(-size.x, 0)).a;
- outline += texture(TEXTURE, UV + vec2(0, size.y)).a;
- outline += texture(TEXTURE, UV + vec2(size.x, 0)).a;
- outline += texture(TEXTURE, UV + vec2(0, -size.y)).a;
- outline = min(outline, 1.0);
- if (outline > 0.0) {
- COLOR = mix(COLOR, outline_color , 1);
- COLOR.a = outline_color.a;
- }
- }
-}
diff --git a/DungeonShooting_Godot/resource/material/Outline.tres b/DungeonShooting_Godot/resource/material/Outline.tres
index c789b00..c644a62 100644
--- a/DungeonShooting_Godot/resource/material/Outline.tres
+++ b/DungeonShooting_Godot/resource/material/Outline.tres
@@ -1,6 +1,7 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://j8t31iuumvhr"]
-[ext_resource type="Shader" path="res://resource/material/Outline.gdshader" id="1_neih8"]
+[ext_resource type="Shader" path="res://resource/shader/Outline.gdshader" id="1_neih8"]
+
[resource]
resource_local_to_scene = true
diff --git a/DungeonShooting_Godot/resource/material/Outline2.gdshader b/DungeonShooting_Godot/resource/material/Outline2.gdshader
deleted file mode 100644
index 2f6d088..0000000
--- a/DungeonShooting_Godot/resource/material/Outline2.gdshader
+++ /dev/null
@@ -1,30 +0,0 @@
-shader_type canvas_item;
-
-//轮廓颜色
-uniform vec4 outline_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
-//轮廓缩放
-uniform float scale : hint_range(0.0, 2.0, 0.01) = 1.0;
-
-void fragment() {
- float a = COLOR.a;
- //显示轮廓
- if (a == 0.0) {
- vec2 size = TEXTURE_PIXEL_SIZE * 0.5;
- float outline;
- outline = texture(TEXTURE, UV + vec2(-size.x, 0)).a;
- outline += texture(TEXTURE, UV + vec2(0, size.y)).a;
- outline += texture(TEXTURE, UV + vec2(size.x, 0)).a;
- outline += texture(TEXTURE, UV + vec2(0, -size.y)).a;
-
- outline += texture(TEXTURE, UV + vec2(-size.x, -size.y)).a;
- outline += texture(TEXTURE, UV + vec2(size.x, size.y)).a;
- outline += texture(TEXTURE, UV + vec2(size.x, -size.y)).a;
- outline += texture(TEXTURE, UV + vec2(-size.x, size.y)).a;
-
- outline = min(outline, 1.0);
- if (outline > 0.0) {
- COLOR = mix(COLOR, outline_color , 1);
- COLOR.a = outline_color.a;
- }
- }
-}
diff --git a/DungeonShooting_Godot/resource/material/Outline2.tres b/DungeonShooting_Godot/resource/material/Outline2.tres
index dd8cdb5..7cc7bf2 100644
--- a/DungeonShooting_Godot/resource/material/Outline2.tres
+++ b/DungeonShooting_Godot/resource/material/Outline2.tres
@@ -1,6 +1,7 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://jywcy17le5fd"]
-[ext_resource type="Shader" path="res://resource/material/Outline2.gdshader" id="1_skooq"]
+[ext_resource type="Shader" path="res://resource/shader/Outline2.gdshader" id="1_skooq"]
+
[resource]
resource_local_to_scene = true
diff --git a/DungeonShooting_Godot/resource/material/RingOfPower.tres b/DungeonShooting_Godot/resource/material/RingOfPower.tres
new file mode 100644
index 0000000..91cc9bc
--- /dev/null
+++ b/DungeonShooting_Godot/resource/material/RingOfPower.tres
@@ -0,0 +1,13 @@
+[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://civgek3sgwh82"]
+
+[ext_resource type="Shader" path="res://resource/shader/RingOfPower.gdshader" id="1_skd47"]
+
+[resource]
+shader = ExtResource("1_skd47")
+shader_parameter/radius = 0.58
+shader_parameter/thickness = 0.2
+shader_parameter/color = Color(0.9, 0.4, 0.1, 1)
+shader_parameter/brightness = 5.0
+shader_parameter/angular_speed = 2.5
+shader_parameter/radial_speed = 1.4
+shader_parameter/alpha = 0.5
diff --git a/DungeonShooting_Godot/resource/material/Sawtooth.gdshader b/DungeonShooting_Godot/resource/material/Sawtooth.gdshader
deleted file mode 100644
index cbbc062..0000000
--- a/DungeonShooting_Godot/resource/material/Sawtooth.gdshader
+++ /dev/null
@@ -1,18 +0,0 @@
-shader_type canvas_item;
-
-void vertex() {
- VERTEX = VERTEX * vec2(4.0);
-}
-
-void fragment() {
- vec2 pixel_size = 1.0 / vec2(textureSize(TEXTURE, 0));
- vec4 color = vec4(0.0);
- for (int x = -1; x <= 1; x++) {
- for (int y = -1; y <= 1; y++) {
- color += texture(TEXTURE, UV + vec2(float(x), float(y)) * pixel_size / 2.0);
- }
- }
- color /= 9.0;
- COLOR = color;
-}
-
diff --git a/DungeonShooting_Godot/resource/material/Sawtooth.tres b/DungeonShooting_Godot/resource/material/Sawtooth.tres
index fc7553f..73c3175 100644
--- a/DungeonShooting_Godot/resource/material/Sawtooth.tres
+++ b/DungeonShooting_Godot/resource/material/Sawtooth.tres
@@ -1,6 +1,7 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://cca0ka64xmrrd"]
-[ext_resource type="Shader" path="res://resource/material/Sawtooth.gdshader" id="1_nrhtr"]
+[ext_resource type="Shader" path="res://resource/shader/Sawtooth.gdshader" id="1_nrhtr"]
+
[resource]
shader = ExtResource("1_nrhtr")
diff --git a/DungeonShooting_Godot/resource/shader/Blend.gdshader b/DungeonShooting_Godot/resource/shader/Blend.gdshader
new file mode 100644
index 0000000..2fd8b76
--- /dev/null
+++ b/DungeonShooting_Godot/resource/shader/Blend.gdshader
@@ -0,0 +1,63 @@
+shader_type canvas_item;
+
+//混合颜色
+uniform vec4 blend : source_color = vec4(1.0, 1.0, 1.0, 1.0);
+//混合度
+uniform float schedule : hint_range(0.0, 1.0, 0.01) = 0.0;
+//
+uniform vec4 modulate : source_color = vec4(1.0, 1.0, 1.0, 1.0);
+
+//------------------ 轮廓相关 --------------
+uniform bool show_outline = true;
+//轮廓颜色
+uniform vec4 outline_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
+//是否是彩虹轮廓
+uniform bool outline_rainbow = false;
+//轮廓是否使用 blend
+uniform bool outline_use_blend = true;
+//灰度
+uniform float grey : hint_range(0.0, 1.0, 0.01) = 0.0;
+
+//彩虹轮廓变化周期
+const float frequency = 0.25;
+const float light_offset = 0.5;
+
+void fragment() {
+ float a = COLOR.a;
+ //显示轮廓
+ if (show_outline && a == 0.0) {
+ vec2 size = TEXTURE_PIXEL_SIZE;
+ float outline;
+ outline = texture(TEXTURE, UV + vec2(-size.x, 0)).a;
+ outline += texture(TEXTURE, UV + vec2(0, size.y)).a;
+ outline += texture(TEXTURE, UV + vec2(size.x, 0)).a;
+ outline += texture(TEXTURE, UV + vec2(0, -size.y)).a;
+ outline = min(outline, 1.0);
+ if (outline > 0.0) {
+ if (outline_rainbow){
+ vec4 animated_line_color = vec4(
+ light_offset + sin(2.0 * 3.14 * frequency * TIME),
+ light_offset + sin(2.0 * 3.14 * frequency * TIME + radians(120.0)),
+ light_offset + sin(2.0 * 3.14 * frequency * TIME + radians(240.0)),
+ 1.0
+ );
+ COLOR = mix(COLOR, animated_line_color, 1);
+ a = animated_line_color.a;
+ } else {
+ COLOR = mix(COLOR, outline_color , 1);
+ a = outline_color.a;
+ }
+ }
+
+ if (outline_use_blend) {
+ COLOR = mix(COLOR, blend, schedule);
+ }
+ } else { //非轮廓
+ COLOR = mix(COLOR, blend, schedule);
+ //灰度
+ float grayColor = dot(COLOR.rgb, vec3(0.299, 0.587, 0.114));
+ COLOR.rgb = mix(COLOR.rgb, vec3(grayColor), grey);
+ }
+ COLOR.a *= a;
+ COLOR *= modulate;
+}
diff --git a/DungeonShooting_Godot/resource/shader/GodRays.gdshader b/DungeonShooting_Godot/resource/shader/GodRays.gdshader
new file mode 100644
index 0000000..4892b88
--- /dev/null
+++ b/DungeonShooting_Godot/resource/shader/GodRays.gdshader
@@ -0,0 +1,107 @@
+/*
+Shader from Godot Shaders - the free shader library.
+godotshaders.com/shader/god-rays
+
+Feel free to use, improve and change this shader according to your needs
+and consider sharing the modified result on godotshaders.com.
+*/
+
+shader_type canvas_item;
+
+uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
+
+uniform float angle = -0.3;
+uniform float position = -0.2;
+uniform float spread : hint_range(0.0, 1.0) = 0.5;
+uniform float cutoff : hint_range(-1.0, 1.0) = 0.1;
+uniform float falloff : hint_range(0.0, 1.0) = 0.2;
+uniform float edge_fade : hint_range(0.0, 1.0) = 0.15;
+
+uniform float speed = 1.0;
+uniform float ray1_density = 8.0;
+uniform float ray2_density = 30.0;
+uniform float ray2_intensity : hint_range(0.0, 1.0) = 0.3;
+
+uniform vec4 color : source_color = vec4(1.0, 0.9, 0.65, 0.8);
+
+uniform bool hdr = false;
+uniform float seed = 5.0;
+
+float random(vec2 _uv) {
+ _uv += min(TIME,0.0);
+ return fract(sin(dot(_uv.xy, vec2(12.9898, 78.233))) * 43758.5453123);
+}
+
+float noise (in vec2 uv) {
+ vec2 i = floor(uv);
+ vec2 f = fract(uv);
+
+ // Four corners in 2D of a tile
+ float a = random(i);
+ float b = random(i + vec2(1.0, 0.0));
+ float c = random(i + vec2(0.0, 1.0));
+ float d = random(i + vec2(1.0, 1.0));
+
+
+ // Smooth Interpolation
+
+ // Cubic Hermine Curve. Same as SmoothStep()
+ vec2 u = f * f * (3.0-2.0 * f);
+
+ // Mix 4 coorners percentages
+ return mix(a, b, u.x) +
+ (c - a)* u.y * (1.0 - u.x) +
+ (d - b) * u.x * u.y;
+}
+
+mat2 rotate(float _angle){
+ return mat2(vec2(cos(_angle), -sin(_angle)),
+ vec2(sin(_angle), cos(_angle)));
+}
+
+vec4 screen(vec4 base, vec4 blend){
+ return 1.0 - (1.0 - base) * (1.0 - blend);
+}
+
+void fragment()
+{
+
+ // Rotate, skew and move the UVs
+ vec2 transformed_uv = ( rotate(angle) * (UV - position) ) / ( (UV.y + spread) - (UV.y * spread) );
+
+ // Animate the ray according the the new transformed UVs
+ vec2 ray1 = vec2(transformed_uv.x * ray1_density + sin(TIME * 0.1 * speed) * (ray1_density * 0.2) + seed, 1.0);
+ vec2 ray2 = vec2(transformed_uv.x * ray2_density + sin(TIME * 0.2 * speed) * (ray1_density * 0.2) + seed, 1.0);
+
+ // Cut off the ray's edges
+ float cut = step(cutoff, transformed_uv.x) * step(cutoff, 1.0 - transformed_uv.x);
+ ray1 *= cut;
+ ray2 *= cut;
+
+ // Apply the noise pattern (i.e. create the rays)
+ float rays;
+
+ if (hdr){
+ // This is not really HDR, but check this to not clamp the two merged rays making
+ // their values go over 1.0. Can make for some nice effect
+ rays = noise(ray1) + (noise(ray2) * ray2_intensity);
+ }
+ else{
+ rays = clamp(noise(ray1) + (noise(ray2) * ray2_intensity), 0., 1.);
+ }
+
+ // Fade out edges
+ rays *= smoothstep(0.0, falloff, (1.0 - UV.y)); // Bottom
+ rays *= smoothstep(0.0 + cutoff, edge_fade + cutoff, transformed_uv.x); // Left
+ rays *= smoothstep(0.0 + cutoff, edge_fade + cutoff, 1.0 - transformed_uv.x); // Right
+
+ // Color to the rays
+ vec3 shine = vec3(rays) * color.rgb;
+
+ // Try different blending modes for a nicer effect. "Screen" is included in the code,
+ // but take a look at https://godotshaders.com/snippet/blending-modes/ for more.
+ // With "Screen" blend mode:
+ shine = screen(texture(SCREEN_TEXTURE, SCREEN_UV), vec4(color)).rgb;
+
+ COLOR = vec4(shine, rays * color.a);
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/shader/Grid.gdshader b/DungeonShooting_Godot/resource/shader/Grid.gdshader
new file mode 100644
index 0000000..571251f
--- /dev/null
+++ b/DungeonShooting_Godot/resource/shader/Grid.gdshader
@@ -0,0 +1,17 @@
+shader_type canvas_item;
+render_mode blend_mix;
+
+uniform vec4 color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
+uniform vec2 size = vec2(1280.0, 720.0);
+uniform int line_width = 1;
+uniform vec2 offset = vec2(0.0, 0.0);
+uniform float grid_size = 16.0;
+
+void fragment() {
+ vec2 uv = ((offset - vec2(float(line_width)) * 0.5f) / size) + UV;
+ vec2 r = mod(size * uv, vec2(grid_size));
+ vec2 lines = step(1.0 - float(line_width) / grid_size, r / vec2(grid_size));
+ float alpha = dot(lines, vec2(1.0, 1.0));
+ COLOR = color;
+ COLOR.a *= alpha;
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/shader/Mask.gdshader b/DungeonShooting_Godot/resource/shader/Mask.gdshader
new file mode 100644
index 0000000..1c44ff4
--- /dev/null
+++ b/DungeonShooting_Godot/resource/shader/Mask.gdshader
@@ -0,0 +1,9 @@
+shader_type canvas_item;
+
+uniform sampler2D mask_texture;
+
+void fragment() {
+ vec2 size = TEXTURE_PIXEL_SIZE;
+ COLOR.a = 1.0 - texture(mask_texture, UV).a;
+}
+
diff --git a/DungeonShooting_Godot/resource/shader/OffsetVertex.gdshader b/DungeonShooting_Godot/resource/shader/OffsetVertex.gdshader
new file mode 100644
index 0000000..f63d041
--- /dev/null
+++ b/DungeonShooting_Godot/resource/shader/OffsetVertex.gdshader
@@ -0,0 +1,7 @@
+shader_type canvas_item;
+
+uniform vec2 offset = vec2(0.0 , 0.0);
+
+void vertex() {
+ VERTEX += offset;
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/shader/Outline.gdshader b/DungeonShooting_Godot/resource/shader/Outline.gdshader
new file mode 100644
index 0000000..bb3072e
--- /dev/null
+++ b/DungeonShooting_Godot/resource/shader/Outline.gdshader
@@ -0,0 +1,22 @@
+shader_type canvas_item;
+
+//轮廓颜色
+uniform vec4 outline_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
+
+void fragment() {
+ float a = COLOR.a;
+ //显示轮廓
+ if (a == 0.0) {
+ vec2 size = TEXTURE_PIXEL_SIZE;
+ float outline;
+ outline = texture(TEXTURE, UV + vec2(-size.x, 0)).a;
+ outline += texture(TEXTURE, UV + vec2(0, size.y)).a;
+ outline += texture(TEXTURE, UV + vec2(size.x, 0)).a;
+ outline += texture(TEXTURE, UV + vec2(0, -size.y)).a;
+ outline = min(outline, 1.0);
+ if (outline > 0.0) {
+ COLOR = mix(COLOR, outline_color , 1);
+ COLOR.a = outline_color.a;
+ }
+ }
+}
diff --git a/DungeonShooting_Godot/resource/shader/Outline2.gdshader b/DungeonShooting_Godot/resource/shader/Outline2.gdshader
new file mode 100644
index 0000000..2f6d088
--- /dev/null
+++ b/DungeonShooting_Godot/resource/shader/Outline2.gdshader
@@ -0,0 +1,30 @@
+shader_type canvas_item;
+
+//轮廓颜色
+uniform vec4 outline_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
+//轮廓缩放
+uniform float scale : hint_range(0.0, 2.0, 0.01) = 1.0;
+
+void fragment() {
+ float a = COLOR.a;
+ //显示轮廓
+ if (a == 0.0) {
+ vec2 size = TEXTURE_PIXEL_SIZE * 0.5;
+ float outline;
+ outline = texture(TEXTURE, UV + vec2(-size.x, 0)).a;
+ outline += texture(TEXTURE, UV + vec2(0, size.y)).a;
+ outline += texture(TEXTURE, UV + vec2(size.x, 0)).a;
+ outline += texture(TEXTURE, UV + vec2(0, -size.y)).a;
+
+ outline += texture(TEXTURE, UV + vec2(-size.x, -size.y)).a;
+ outline += texture(TEXTURE, UV + vec2(size.x, size.y)).a;
+ outline += texture(TEXTURE, UV + vec2(size.x, -size.y)).a;
+ outline += texture(TEXTURE, UV + vec2(-size.x, size.y)).a;
+
+ outline = min(outline, 1.0);
+ if (outline > 0.0) {
+ COLOR = mix(COLOR, outline_color , 1);
+ COLOR.a = outline_color.a;
+ }
+ }
+}
diff --git a/DungeonShooting_Godot/resource/shader/RingOfPower.gdshader b/DungeonShooting_Godot/resource/shader/RingOfPower.gdshader
new file mode 100644
index 0000000..07a6be9
--- /dev/null
+++ b/DungeonShooting_Godot/resource/shader/RingOfPower.gdshader
@@ -0,0 +1,23 @@
+shader_type canvas_item;
+render_mode blend_add;
+
+uniform float radius : hint_range(0.0, 1.0, 0.01) = .7;
+uniform float thickness : hint_range(0.0, 1.0, 0.01) = .2;
+uniform vec4 color : source_color = vec4(0.9, 0.4, 0.1, 1.0);
+uniform float brightness : hint_range(0.0, 15.0, 0.01) = 5.0;
+uniform float angular_speed : hint_range(-5.0, 5.0, 0.01) = 2.5;
+uniform float radial_speed : hint_range(-5.0, 5.0, 0.01) = 1.4;
+uniform float alpha : hint_range(0.0, 1.0, 0.01) = .5;
+uniform sampler2D noise;
+
+void fragment() {
+ vec2 v = vec2(.5) - UV;
+ float d = length(v) * 2.;
+ float angle = atan(v.y, v.x) + (TIME * angular_speed);
+ float thick_ratio = 1. - (abs(d - max(0., radius)) / max(.0001, thickness));
+ vec2 polar = fract(vec2(angle / 6.28, d + (TIME * radial_speed)));
+ vec4 col = thick_ratio * brightness * color;
+ vec3 tex = texture(noise, polar).rgb;
+ col.a = (alpha * (tex.r + tex.g + tex.b) * clamp(thick_ratio, 0., 1.)) / 3.;
+ COLOR = col;
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/shader/Sawtooth.gdshader b/DungeonShooting_Godot/resource/shader/Sawtooth.gdshader
new file mode 100644
index 0000000..cbbc062
--- /dev/null
+++ b/DungeonShooting_Godot/resource/shader/Sawtooth.gdshader
@@ -0,0 +1,18 @@
+shader_type canvas_item;
+
+void vertex() {
+ VERTEX = VERTEX * vec2(4.0);
+}
+
+void fragment() {
+ vec2 pixel_size = 1.0 / vec2(textureSize(TEXTURE, 0));
+ vec4 color = vec4(0.0);
+ for (int x = -1; x <= 1; x++) {
+ for (int y = -1; y <= 1; y++) {
+ color += texture(TEXTURE, UV + vec2(float(x), float(y)) * pixel_size / 2.0);
+ }
+ }
+ color /= 9.0;
+ COLOR = color;
+}
+
diff --git a/DungeonShooting_Godot/resource/sprite/noise/Noise0001.png b/DungeonShooting_Godot/resource/sprite/noise/Noise0001.png
new file mode 100644
index 0000000..ce5c254
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/noise/Noise0001.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/noise/Noise0001.png.import b/DungeonShooting_Godot/resource/sprite/noise/Noise0001.png.import
new file mode 100644
index 0000000..42f901c
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/noise/Noise0001.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bcca04qkcqpr6"
+path="res://.godot/imported/Noise0001.png-f347b185a3f801652a2962595d57cd1d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/noise/Noise0001.png"
+dest_files=["res://.godot/imported/Noise0001.png-f347b185a3f801652a2962595d57cd1d.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+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/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/DungeonShooting_Godot/resource/sprite/noise/Noise0002.png b/DungeonShooting_Godot/resource/sprite/noise/Noise0002.png
new file mode 100644
index 0000000..9991518
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/noise/Noise0002.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/noise/Noise0002.png.import b/DungeonShooting_Godot/resource/sprite/noise/Noise0002.png.import
new file mode 100644
index 0000000..94146ab
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/noise/Noise0002.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://ces7pvy62tufw"
+path="res://.godot/imported/Noise0002.png-0473c04b472f8eaad80b32855fae62f6.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/noise/Noise0002.png"
+dest_files=["res://.godot/imported/Noise0002.png-0473c04b472f8eaad80b32855fae62f6.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+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/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/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5003.png b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5003.png
index ec4e4d5..cbdf94f 100644
--- a/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5003.png
+++ b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5003.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5004.png b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5004.png
new file mode 100644
index 0000000..6c6ba7b
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5004.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5004.png.import b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5004.png.import
new file mode 100644
index 0000000..3de1a23
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5004.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bo80bcwleji1v"
+path="res://.godot/imported/ActiveProp5004.png-d8820f3029374f01685c3c0e6fa5ba2c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/prop/active/ActiveProp5004.png"
+dest_files=["res://.godot/imported/ActiveProp5004.png-d8820f3029374f01685c3c0e6fa5ba2c.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+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/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/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5005.png b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5005.png
new file mode 100644
index 0000000..b409284
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5005.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5005.png.import b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5005.png.import
new file mode 100644
index 0000000..b834250
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5005.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bmtchn3tnb0rq"
+path="res://.godot/imported/ActiveProp5005.png-15f900b095a5bff93432e841f6c6aa7e.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/prop/active/ActiveProp5005.png"
+dest_files=["res://.godot/imported/ActiveProp5005.png-15f900b095a5bff93432e841f6c6aa7e.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+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/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/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5006.png b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5006.png
new file mode 100644
index 0000000..539f8f1
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5006.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5006.png.import b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5006.png.import
new file mode 100644
index 0000000..2c8c693
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/prop/active/ActiveProp5006.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://gwbclbl7vnt8"
+path="res://.godot/imported/ActiveProp5006.png-3dfe862becb03e916076078ebbcbd626.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/prop/active/ActiveProp5006.png"
+dest_files=["res://.godot/imported/ActiveProp5006.png-3dfe862becb03e916076078ebbcbd626.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+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/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/DungeonShooting_Godot/resource/sprite/role/shopBoss0001/ShopBoss0001.png b/DungeonShooting_Godot/resource/sprite/role/shopBoss0001/ShopBoss0001.png
new file mode 100644
index 0000000..495087d
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/role/shopBoss0001/ShopBoss0001.png
Binary files differ
diff --git a/DungeonShooting_Godot/resource/sprite/role/shopBoss0001/ShopBoss0001.png.import b/DungeonShooting_Godot/resource/sprite/role/shopBoss0001/ShopBoss0001.png.import
new file mode 100644
index 0000000..b496656
--- /dev/null
+++ b/DungeonShooting_Godot/resource/sprite/role/shopBoss0001/ShopBoss0001.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cfgdtj2quumhy"
+path="res://.godot/imported/ShopBoss0001.png-431c1b19fabb4c7c991c0092d16aec1c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://resource/sprite/role/shopBoss0001/ShopBoss0001.png"
+dest_files=["res://.godot/imported/ShopBoss0001.png-431c1b19fabb4c7c991c0092d16aec1c.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+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/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/DungeonShooting_Godot/resource/sprite/ui/roomUI/Cooldown.png b/DungeonShooting_Godot/resource/sprite/ui/roomUI/Cooldown.png
index 1445214..250e7bb 100644
--- a/DungeonShooting_Godot/resource/sprite/ui/roomUI/Cooldown.png
+++ b/DungeonShooting_Godot/resource/sprite/ui/roomUI/Cooldown.png
Binary files differ
diff --git a/DungeonShooting_Godot/scene/Dungeon.tscn b/DungeonShooting_Godot/scene/Dungeon.tscn
index 8944b1e..213bd35 100644
--- a/DungeonShooting_Godot/scene/Dungeon.tscn
+++ b/DungeonShooting_Godot/scene/Dungeon.tscn
@@ -5,8 +5,12 @@
[sub_resource type="Environment" id="Environment_g06jj"]
background_mode = 3
glow_enabled = true
+glow_levels/1 = 1.0
+glow_levels/2 = 1.0
+glow_levels/4 = 1.0
+glow_levels/5 = 0.0
glow_normalized = true
-glow_strength = 1.05
+glow_strength = 1.06
glow_blend_mode = 1
[node name="Dungeon" type="CanvasModulate"]
diff --git a/DungeonShooting_Godot/scene/Hall.tscn b/DungeonShooting_Godot/scene/Hall.tscn
index 0863e40..6d561ba 100644
--- a/DungeonShooting_Godot/scene/Hall.tscn
+++ b/DungeonShooting_Godot/scene/Hall.tscn
@@ -15,7 +15,7 @@
[ext_resource type="Texture2D" uid="uid://ci41ruj125hk2" path="res://resource/sprite/item/hall_c/item _20.png" id="11_tg3jo"]
[ext_resource type="Texture2D" uid="uid://dwstu11dix0nq" path="res://resource/sprite/item/hall_b/item-30.png" id="12_agfji"]
[ext_resource type="Texture2D" uid="uid://d08oi1tvpcd3p" path="res://resource/sprite/item/hall_b/item-29.png" id="13_unnpl"]
-[ext_resource type="Shader" path="res://resource/material/GodRays.gdshader" id="14_8vfgi"]
+[ext_resource type="Shader" path="res://resource/shader/GodRays.gdshader" id="14_8vfgi"]
[ext_resource type="Texture2D" uid="uid://uhhfgdhpk7i4" path="res://icon.png" id="15_1xqxd"]
[ext_resource type="Texture2D" uid="uid://iqj44lyknjr2" path="res://resource/sprite/item/hall_a/Slice_04.png" id="15_h7524"]
[ext_resource type="Texture2D" uid="uid://bm8xcx73s83ku" path="res://resource/sprite/item/hall_a/Slice_47.png" id="16_xj0e1"]
@@ -86,7 +86,7 @@
metadata/_edit_group_ = true
[node name="BirthMark" type="Marker2D" parent="." index="3"]
-position = Vector2(536, 310)
+position = Vector2(533, 180)
[node name="DungeonEntrance" type="Area2D" parent="." index="4"]
z_index = 15
diff --git a/DungeonShooting_Godot/scene/Main.tscn b/DungeonShooting_Godot/scene/Main.tscn
index b55999a..96c4215 100644
--- a/DungeonShooting_Godot/scene/Main.tscn
+++ b/DungeonShooting_Godot/scene/Main.tscn
@@ -2,7 +2,7 @@
[ext_resource type="Script" path="res://src/game/GameApplication.cs" id="1_mh1cq"]
[ext_resource type="Script" path="res://src/game/camera/GameCamera.cs" id="2_2j367"]
-[ext_resource type="Shader" path="res://resource/material/OffsetVertex.gdshader" id="2_fxoum"]
+[ext_resource type="Shader" path="res://resource/shader/OffsetVertex.gdshader" id="2_fxoum"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_pjtkw"]
shader = ExtResource("2_fxoum")
diff --git a/DungeonShooting_Godot/scene/test/TestLobby.tscn b/DungeonShooting_Godot/scene/test/TestLobby.tscn
new file mode 100644
index 0000000..ea8aa15
--- /dev/null
+++ b/DungeonShooting_Godot/scene/test/TestLobby.tscn
@@ -0,0 +1,20 @@
+[gd_scene load_steps=4 format=3 uid="uid://bcwbprtgyahy4"]
+
+[ext_resource type="Texture2D" uid="uid://c6pesrr162s6" path="res://resource/map/tileSet/TileSet2/Main.png" id="1_jh7pr"]
+[ext_resource type="Texture2D" uid="uid://cyl8dsbu2htyf" path="res://resource/sprite/role/role5.png" id="2_f5n01"]
+[ext_resource type="Texture2D" uid="uid://bi3othr1cld04" path="res://resource/sprite/role/role7.png" id="3_1v4l1"]
+
+[node name="TestLobby" type="Node2D"]
+scale = Vector2(4, 4)
+
+[node name="Main" type="Sprite2D" parent="."]
+position = Vector2(144, 112)
+texture = ExtResource("1_jh7pr")
+
+[node name="Role5" type="Sprite2D" parent="."]
+position = Vector2(124, 108)
+texture = ExtResource("2_f5n01")
+
+[node name="Role7" type="Sprite2D" parent="."]
+position = Vector2(236, 100)
+texture = ExtResource("3_1v4l1")
diff --git a/DungeonShooting_Godot/scene/test/TestNewTerrain.tscn b/DungeonShooting_Godot/scene/test/TestNewTerrain.tscn
index da3d648..71e43ac 100644
--- a/DungeonShooting_Godot/scene/test/TestNewTerrain.tscn
+++ b/DungeonShooting_Godot/scene/test/TestNewTerrain.tscn
@@ -1,12 +1,13 @@
-[gd_scene load_steps=10 format=3 uid="uid://iwm27vpirfef"]
+[gd_scene load_steps=9 format=3 uid="uid://iwm27vpirfef"]
[ext_resource type="Script" path="res://src/test/TestNewTerrain.cs" id="1_68mbo"]
[ext_resource type="PackedScene" uid="uid://cxhrcytrx0kcf" path="res://prefab/role/Role0001.tscn" id="3_bo13a"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="4_iy0ux"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="4_iy0ux"]
[ext_resource type="Texture2D" uid="uid://bda63puujv425" path="res://resource/sprite/role/common/Role_query.png" id="5_rv0km"]
-[ext_resource type="Shader" path="res://resource/material/GodRays.gdshader" id="6_bcjt6"]
+[ext_resource type="Shader" path="res://resource/shader/GodRays.gdshader" id="6_bcjt6"]
[ext_resource type="Texture2D" uid="uid://uhhfgdhpk7i4" path="res://icon.png" id="7_34lsg"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_7va3f"]
resource_local_to_scene = true
shader = ExtResource("4_iy0ux")
diff --git a/DungeonShooting_Godot/scene/test/TestOutline.tscn b/DungeonShooting_Godot/scene/test/TestOutline.tscn
index bced176..7215851 100644
--- a/DungeonShooting_Godot/scene/test/TestOutline.tscn
+++ b/DungeonShooting_Godot/scene/test/TestOutline.tscn
@@ -1,8 +1,9 @@
[gd_scene load_steps=4 format=3 uid="uid://bbwws7qlqlc0m"]
-[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="1_r82n1"]
+[ext_resource type="Shader" path="res://resource/shader/Blend.gdshader" id="1_r82n1"]
[ext_resource type="Texture2D" uid="uid://bls55gj8h3mgv" path="res://resource/sprite/prop/buff/BuffProp0001.png" id="2_yce7u"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_lhoej"]
shader = ExtResource("1_r82n1")
shader_parameter/blend = Color(1, 1, 1, 1)
diff --git a/DungeonShooting_Godot/scene/test/TestPerfectPixel.tscn b/DungeonShooting_Godot/scene/test/TestPerfectPixel.tscn
index 5e7cd81..2ace4f7 100644
--- a/DungeonShooting_Godot/scene/test/TestPerfectPixel.tscn
+++ b/DungeonShooting_Godot/scene/test/TestPerfectPixel.tscn
@@ -1,8 +1,9 @@
[gd_scene load_steps=4 format=3 uid="uid://x801hit8cj6w"]
-[ext_resource type="Shader" path="res://resource/material/OffsetVertex.gdshader" id="1_8hyja"]
+[ext_resource type="Shader" path="res://resource/shader/OffsetVertex.gdshader" id="1_8hyja"]
[ext_resource type="PackedScene" uid="uid://b3ybffxcq0kkb" path="res://scene/test/TestPerfectPixelScene.tscn" id="1_l3du1"]
+
[sub_resource type="ShaderMaterial" id="ShaderMaterial_lm6np"]
shader = ExtResource("1_8hyja")
shader_parameter/offset = Vector2(0, 0)
diff --git a/DungeonShooting_Godot/scene/test/TestShader.tscn b/DungeonShooting_Godot/scene/test/TestShader.tscn
new file mode 100644
index 0000000..7b70510
--- /dev/null
+++ b/DungeonShooting_Godot/scene/test/TestShader.tscn
@@ -0,0 +1,33 @@
+[gd_scene load_steps=5 format=3 uid="uid://bnoa5mkbw6o0n"]
+
+[ext_resource type="Texture2D" uid="uid://uhhfgdhpk7i4" path="res://icon.png" id="1_5e1lv"]
+[ext_resource type="Shader" path="res://resource/shader/RingOfPower.gdshader" id="2_cewpk"]
+[ext_resource type="Texture2D" uid="uid://bcca04qkcqpr6" path="res://resource/sprite/noise/Noise0001.png" id="3_cnv2p"]
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_1pb8g"]
+shader = ExtResource("2_cewpk")
+shader_parameter/radius = 0.58
+shader_parameter/thickness = 0.34
+shader_parameter/color = Color(0.9, 0.4, 0.1, 1)
+shader_parameter/brightness = 5.0
+shader_parameter/angular_speed = 2.5
+shader_parameter/radial_speed = 0.24
+shader_parameter/alpha = 0.5
+shader_parameter/noise = ExtResource("3_cnv2p")
+
+[node name="TestShader" type="Node2D"]
+
+[node name="Sprite2D" type="Sprite2D" parent="."]
+position = Vector2(168, 115)
+scale = Vector2(2.9375, 2.53125)
+texture = ExtResource("1_5e1lv")
+
+[node name="Sprite2D2" type="Sprite2D" parent="."]
+position = Vector2(1062, 627)
+scale = Vector2(25.25, 14.5938)
+texture = ExtResource("1_5e1lv")
+
+[node name="Sprite2D3" type="Sprite2D" parent="."]
+material = SubResource("ShaderMaterial_1pb8g")
+position = Vector2(314, 354)
+texture = ExtResource("1_5e1lv")
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig.cs b/DungeonShooting_Godot/src/config/ExcelConfig.cs
index 42d5e0a..df8bd8d 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig.cs
@@ -8,31 +8,22 @@
public static partial class ExcelConfig
{
///
- /// BuffPropBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ /// ActivePropBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
///
- public static List BuffPropBase_List { get; private set; }
+ public static List ActivePropBase_List { get; private set; }
///
- /// BuffPropBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ /// ActivePropBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
///
- public static Dictionary BuffPropBase_Map { get; private set; }
+ public static Dictionary ActivePropBase_Map { get; private set; }
///
- /// Sound.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ /// ActivityBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
///
- public static List Sound_List { get; private set; }
+ public static List ActivityBase_List { get; private set; }
///
- /// Sound.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ /// ActivityBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
///
- public static Dictionary Sound_Map { get; private set; }
-
- ///
- /// WeaponBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
- ///
- public static List WeaponBase_List { get; private set; }
- ///
- /// WeaponBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
- ///
- public static Dictionary WeaponBase_Map { get; private set; }
+ public static Dictionary ActivityBase_Map { get; private set; }
///
/// ActivityMaterial.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
@@ -53,6 +44,15 @@
public static Dictionary AiAttackAttr_Map { get; private set; }
///
+ /// BuffPropBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ ///
+ public static List BuffPropBase_List { get; private set; }
+ ///
+ /// BuffPropBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ ///
+ public static Dictionary BuffPropBase_Map { get; private set; }
+
+ ///
/// BulletBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
///
public static List BulletBase_List { get; private set; }
@@ -62,15 +62,6 @@
public static Dictionary BulletBase_Map { get; private set; }
///
- /// ActivePropBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
- ///
- public static List ActivePropBase_List { get; private set; }
- ///
- /// ActivePropBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
- ///
- public static Dictionary ActivePropBase_Map { get; private set; }
-
- ///
/// EnemyBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
///
public static List EnemyBase_List { get; private set; }
@@ -80,15 +71,6 @@
public static Dictionary EnemyBase_Map { get; private set; }
///
- /// ActivityBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
- ///
- public static List ActivityBase_List { get; private set; }
- ///
- /// ActivityBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
- ///
- public static Dictionary ActivityBase_Map { get; private set; }
-
- ///
/// LiquidMaterial.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
///
public static List LiquidMaterial_List { get; private set; }
@@ -97,6 +79,24 @@
///
public static Dictionary LiquidMaterial_Map { get; private set; }
+ ///
+ /// Sound.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ ///
+ public static List Sound_List { get; private set; }
+ ///
+ /// Sound.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ ///
+ public static Dictionary Sound_Map { get; private set; }
+
+ ///
+ /// WeaponBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同
+ ///
+ public static List WeaponBase_List { get; private set; }
+ ///
+ /// WeaponBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id
+ ///
+ public static Dictionary WeaponBase_Map { get; private set; }
+
private static bool _init = false;
///
@@ -107,75 +107,57 @@
if (_init) return;
_init = true;
- _InitBuffPropBaseConfig();
- _InitSoundConfig();
- _InitWeaponBaseConfig();
+ _InitActivePropBaseConfig();
+ _InitActivityBaseConfig();
_InitActivityMaterialConfig();
_InitAiAttackAttrConfig();
+ _InitBuffPropBaseConfig();
_InitBulletBaseConfig();
- _InitActivePropBaseConfig();
_InitEnemyBaseConfig();
- _InitActivityBaseConfig();
_InitLiquidMaterialConfig();
+ _InitSoundConfig();
+ _InitWeaponBaseConfig();
- _InitBuffPropBaseRef();
- _InitWeaponBaseRef();
_InitActivePropBaseRef();
- _InitEnemyBaseRef();
_InitActivityBaseRef();
+ _InitBuffPropBaseRef();
+ _InitEnemyBaseRef();
+ _InitWeaponBaseRef();
}
- private static void _InitBuffPropBaseConfig()
+ private static void _InitActivePropBaseConfig()
{
try
{
- var text = _ReadConfigAsText("res://resource/config/BuffPropBase.json");
- BuffPropBase_List = new List(JsonSerializer.Deserialize>(text));
- BuffPropBase_Map = new Dictionary();
- foreach (var item in BuffPropBase_List)
+ var text = _ReadConfigAsText("res://resource/config/ActivePropBase.json");
+ ActivePropBase_List = new List(JsonSerializer.Deserialize>(text));
+ ActivePropBase_Map = new Dictionary();
+ foreach (var item in ActivePropBase_List)
{
- BuffPropBase_Map.Add(item.Id, item);
+ ActivePropBase_Map.Add(item.Id, item);
}
}
catch (Exception e)
{
GD.PrintErr(e.ToString());
- throw new Exception("初始化表'BuffPropBase'失败!");
+ throw new Exception("初始化表'ActivePropBase'失败!");
}
}
- private static void _InitSoundConfig()
+ private static void _InitActivityBaseConfig()
{
try
{
- var text = _ReadConfigAsText("res://resource/config/Sound.json");
- Sound_List = JsonSerializer.Deserialize>(text);
- Sound_Map = new Dictionary();
- foreach (var item in Sound_List)
+ var text = _ReadConfigAsText("res://resource/config/ActivityBase.json");
+ ActivityBase_List = new List(JsonSerializer.Deserialize>(text));
+ ActivityBase_Map = new Dictionary();
+ foreach (var item in ActivityBase_List)
{
- Sound_Map.Add(item.Id, item);
+ ActivityBase_Map.Add(item.Id, item);
}
}
catch (Exception e)
{
GD.PrintErr(e.ToString());
- throw new Exception("初始化表'Sound'失败!");
- }
- }
- private static void _InitWeaponBaseConfig()
- {
- try
- {
- var text = _ReadConfigAsText("res://resource/config/WeaponBase.json");
- WeaponBase_List = new List(JsonSerializer.Deserialize>(text));
- WeaponBase_Map = new Dictionary();
- foreach (var item in WeaponBase_List)
- {
- WeaponBase_Map.Add(item.Id, item);
- }
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化表'WeaponBase'失败!");
+ throw new Exception("初始化表'ActivityBase'失败!");
}
}
private static void _InitActivityMaterialConfig()
@@ -214,6 +196,24 @@
throw new Exception("初始化表'AiAttackAttr'失败!");
}
}
+ private static void _InitBuffPropBaseConfig()
+ {
+ try
+ {
+ var text = _ReadConfigAsText("res://resource/config/BuffPropBase.json");
+ BuffPropBase_List = new List(JsonSerializer.Deserialize>(text));
+ BuffPropBase_Map = new Dictionary();
+ foreach (var item in BuffPropBase_List)
+ {
+ BuffPropBase_Map.Add(item.Id, item);
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化表'BuffPropBase'失败!");
+ }
+ }
private static void _InitBulletBaseConfig()
{
try
@@ -232,24 +232,6 @@
throw new Exception("初始化表'BulletBase'失败!");
}
}
- private static void _InitActivePropBaseConfig()
- {
- try
- {
- var text = _ReadConfigAsText("res://resource/config/ActivePropBase.json");
- ActivePropBase_List = new List(JsonSerializer.Deserialize>(text));
- ActivePropBase_Map = new Dictionary();
- foreach (var item in ActivePropBase_List)
- {
- ActivePropBase_Map.Add(item.Id, item);
- }
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化表'ActivePropBase'失败!");
- }
- }
private static void _InitEnemyBaseConfig()
{
try
@@ -268,24 +250,6 @@
throw new Exception("初始化表'EnemyBase'失败!");
}
}
- private static void _InitActivityBaseConfig()
- {
- try
- {
- var text = _ReadConfigAsText("res://resource/config/ActivityBase.json");
- ActivityBase_List = new List(JsonSerializer.Deserialize>(text));
- ActivityBase_Map = new Dictionary();
- foreach (var item in ActivityBase_List)
- {
- ActivityBase_Map.Add(item.Id, item);
- }
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化表'ActivityBase'失败!");
- }
- }
private static void _InitLiquidMaterialConfig()
{
try
@@ -304,7 +268,81 @@
throw new Exception("初始化表'LiquidMaterial'失败!");
}
}
+ private static void _InitSoundConfig()
+ {
+ try
+ {
+ var text = _ReadConfigAsText("res://resource/config/Sound.json");
+ Sound_List = JsonSerializer.Deserialize>(text);
+ Sound_Map = new Dictionary();
+ foreach (var item in Sound_List)
+ {
+ Sound_Map.Add(item.Id, item);
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化表'Sound'失败!");
+ }
+ }
+ private static void _InitWeaponBaseConfig()
+ {
+ try
+ {
+ var text = _ReadConfigAsText("res://resource/config/WeaponBase.json");
+ WeaponBase_List = new List(JsonSerializer.Deserialize>(text));
+ WeaponBase_Map = new Dictionary();
+ foreach (var item in WeaponBase_List)
+ {
+ WeaponBase_Map.Add(item.Id, item);
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化表'WeaponBase'失败!");
+ }
+ }
+ private static void _InitActivePropBaseRef()
+ {
+ foreach (Ref_ActivePropBase item in ActivePropBase_List)
+ {
+ try
+ {
+ if (!string.IsNullOrEmpty(item.__Activity))
+ {
+ item.Activity = ActivityBase_Map[item.__Activity];
+ }
+
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化'ActivePropBase'引用其他表数据失败, 当前行id: " + item.Id);
+ }
+ }
+ }
+ private static void _InitActivityBaseRef()
+ {
+ foreach (Ref_ActivityBase item in ActivityBase_List)
+ {
+ try
+ {
+ if (!string.IsNullOrEmpty(item.__Material))
+ {
+ item.Material = ActivityMaterial_Map[item.__Material];
+ }
+
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化'ActivityBase'引用其他表数据失败, 当前行id: " + item.Id);
+ }
+ }
+ }
private static void _InitBuffPropBaseRef()
{
foreach (Ref_BuffPropBase item in BuffPropBase_List)
@@ -324,6 +362,25 @@
}
}
}
+ private static void _InitEnemyBaseRef()
+ {
+ foreach (Ref_EnemyBase item in EnemyBase_List)
+ {
+ try
+ {
+ if (!string.IsNullOrEmpty(item.__Activity))
+ {
+ item.Activity = ActivityBase_Map[item.__Activity];
+ }
+
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr(e.ToString());
+ throw new Exception("初始化'EnemyBase'引用其他表数据失败, 当前行id: " + item.Id);
+ }
+ }
+ }
private static void _InitWeaponBaseRef()
{
foreach (Ref_WeaponBase item in WeaponBase_List)
@@ -392,63 +449,6 @@
}
}
}
- private static void _InitActivePropBaseRef()
- {
- foreach (Ref_ActivePropBase item in ActivePropBase_List)
- {
- try
- {
- if (!string.IsNullOrEmpty(item.__Activity))
- {
- item.Activity = ActivityBase_Map[item.__Activity];
- }
-
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化'ActivePropBase'引用其他表数据失败, 当前行id: " + item.Id);
- }
- }
- }
- private static void _InitEnemyBaseRef()
- {
- foreach (Ref_EnemyBase item in EnemyBase_List)
- {
- try
- {
- if (!string.IsNullOrEmpty(item.__Activity))
- {
- item.Activity = ActivityBase_Map[item.__Activity];
- }
-
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化'EnemyBase'引用其他表数据失败, 当前行id: " + item.Id);
- }
- }
- }
- private static void _InitActivityBaseRef()
- {
- foreach (Ref_ActivityBase item in ActivityBase_List)
- {
- try
- {
- if (!string.IsNullOrEmpty(item.__Material))
- {
- item.Material = ActivityMaterial_Map[item.__Material];
- }
-
- }
- catch (Exception e)
- {
- GD.PrintErr(e.ToString());
- throw new Exception("初始化'ActivityBase'引用其他表数据失败, 当前行id: " + item.Id);
- }
- }
- }
private static string _ReadConfigAsText(string path)
{
var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_ActivePropBase.cs b/DungeonShooting_Godot/src/config/ExcelConfig_ActivePropBase.cs
index f4f6479..f2a7f17 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_ActivePropBase.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_ActivePropBase.cs
@@ -31,7 +31,7 @@
/// value为buff初始化参数
///
[JsonInclude]
- public Dictionary Buff;
+ public Dictionary Buff;
///
/// 道具使用条件
@@ -39,7 +39,7 @@
/// 性名称请参阅condition属性表
///
[JsonInclude]
- public Dictionary Condition;
+ public Dictionary Condition;
///
/// 道具使用效果
@@ -47,7 +47,7 @@
/// 性名称请参阅effect属性表
///
[JsonInclude]
- public Dictionary Effect;
+ public Dictionary Effect;
///
/// 道具充能效果
@@ -56,7 +56,7 @@
/// 注意: 仅当'IsConsumables'为false是生效
///
[JsonInclude]
- public Dictionary Charge;
+ public Dictionary Charge;
///
/// 使用道具的效果持续时间
diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_BuffPropBase.cs b/DungeonShooting_Godot/src/config/ExcelConfig_BuffPropBase.cs
index 24f0e66..45c042d 100644
--- a/DungeonShooting_Godot/src/config/ExcelConfig_BuffPropBase.cs
+++ b/DungeonShooting_Godot/src/config/ExcelConfig_BuffPropBase.cs
@@ -31,7 +31,7 @@
/// value为buff初始化参数
///
[JsonInclude]
- public Dictionary Buff;
+ public Dictionary Buff;
///
/// 返回浅拷贝出的新对象
diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
index 2169f4a..ec21309 100644
--- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
+++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
@@ -2019,4 +2019,13 @@
}
}
}
+
+ ///
+ /// 通过标记创建时调用
+ ///
+ /// 当前所在的预设
+ /// 创建当前物体的标记对象
+ public virtual void OnCreateWithMark(RoomPreinstall roomPreinstall, ActivityMark activityMark)
+ {
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs
index e051a61..fd0e5d5 100644
--- a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs
+++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs
@@ -259,6 +259,21 @@
///
public const string Id_prop5003 = "prop5003";
///
+ /// 名称: 魔术棒
+ /// 简介: 随机选择房间内的一个手持武器的敌人, 交换你们手中的武器
+ ///
+ public const string Id_prop5004 = "prop5004";
+ ///
+ /// 名称: 便携式供血器
+ /// 简介: 使用金币换取血量
+ ///
+ public const string Id_prop5005 = "prop5005";
+ ///
+ /// 名称: 便携式献血器
+ /// 简介: 使用血量换取金币
+ ///
+ public const string Id_prop5006 = "prop5006";
+ ///
/// 名称: 木质宝箱
/// 简介: 木质宝箱
///
diff --git a/DungeonShooting_Godot/src/framework/common/WeightRandom.cs b/DungeonShooting_Godot/src/framework/common/WeightRandom.cs
index 2c432cc..161e1f1 100644
--- a/DungeonShooting_Godot/src/framework/common/WeightRandom.cs
+++ b/DungeonShooting_Godot/src/framework/common/WeightRandom.cs
@@ -14,6 +14,14 @@
{
_random = random;
}
+
+ ///
+ /// 设置随机数生成器
+ ///
+ public void SetSeedRandom(SeedRandom random)
+ {
+ _random = random;
+ }
///
/// 初始化权重列表
diff --git a/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs b/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs
index 0ebce39..1b59d19 100644
--- a/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs
+++ b/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs
@@ -287,6 +287,7 @@
{
if (IsFirstEnterFlag)
{
+ Player.Current.OnFirstEnterRoom(RoomInfo);
EventManager.EmitEvent(EventEnum.OnPlayerFirstEnterRoom, RoomInfo);
}
EventManager.EmitEvent(EventEnum.OnPlayerEnterRoom, RoomInfo);
diff --git a/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs b/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs
index 2fc4437..8781e28 100644
--- a/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs
+++ b/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs
@@ -102,7 +102,7 @@
///
public bool HasDesignatedRoom => DesignatedRoom != null && DesignatedRoom.Count > 0;
///
- /// 指定房间类型
+ /// 指定预设的房间类型
///
public DungeonRoomType DesignatedType;
///
diff --git a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs
index feb8ca2..3f82e5d 100644
--- a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs
+++ b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs
@@ -163,78 +163,148 @@
//当前尝试次数
var currTryCount = 0;
- //如果房间数量不够, 就一直生成
- while (!_rule.CanOverGenerator())
+ if (Config.HasDesignatedRoom) //指定房间列表
{
- if (_nextRoomType == DungeonRoomType.None)
+ for (var i = 0; i < Config.DesignatedRoom.Count; i++)
{
- _nextRoomType = _rule.GetNextRoomType(prevRoomInfo);
- }
- var nextRoomType = _nextRoomType;
-
- //上一个房间
- var tempPrevRoomInfo = _rule.GetConnectPrevRoom(prevRoomInfo, nextRoomType);
-
- //生成下一个房间
- var errorCode = GenerateRoom(tempPrevRoomInfo, nextRoomType, out var nextRoom);
- if (errorCode == GenerateRoomErrorCode.NoError) //生成成功
- {
- _failCount = 0;
- RoomInfos.Add(nextRoom);
- if (nextRoomType == DungeonRoomType.Inlet)
+ var roomSplit = Config.DesignatedRoom[i];
+ var nextRoomType = roomSplit.RoomInfo.RoomType;
+ var errorCode = GenerateRoom(prevRoomInfo, roomSplit.RoomInfo.RoomType, out var nextRoom);
+ if (errorCode == GenerateRoomErrorCode.NoError) //生成成功
{
- StartRoomInfo = nextRoom;
- }
- else if (nextRoomType == DungeonRoomType.Boss) //boss房间
- {
- BossRoomInfos.Add(nextRoom);
- }
- else if (nextRoomType == DungeonRoomType.Outlet)
- {
- EndRoomInfos.Add(nextRoom);
- }
- else if (nextRoomType == DungeonRoomType.Battle)
- {
- BattleRoomInfos.Add(nextRoom);
- }
- else if (nextRoomType == DungeonRoomType.Reward)
- {
- RewardRoomInfos.Add(nextRoom);
- }
- else if (nextRoomType == DungeonRoomType.Shop)
- {
- ShopRoomInfos.Add(nextRoom);
- }
- prevRoomInfo = nextRoom;
- _rule.GenerateRoomSuccess(tempPrevRoomInfo, nextRoom);
- _nextRoomType = _rule.GetNextRoomType(nextRoom);
- }
- else //生成失败
- {
- _rule.GenerateRoomFail(tempPrevRoomInfo, nextRoomType);
-
- //Debug.Log("生成第" + (_count + 1) + "个房间失败! 失败原因: " + errorCode);
- if (errorCode == GenerateRoomErrorCode.OutArea)
- {
- _failCount++;
- Debug.Log("超出区域失败次数: " + _failCount);
- if (_failCount >= _maxFailCount)
+ _failCount = 0;
+ RoomInfos.Add(nextRoom);
+ if (nextRoomType == DungeonRoomType.Inlet)
{
- //_enableLimitRange = false;
- _failCount = 0;
- _rangeX += 50;
- _rangeY += 50;
- Debug.Log("生成房间失败次数过多, 增大区域");
+ StartRoomInfo = nextRoom;
}
+ else if (nextRoomType == DungeonRoomType.Boss) //boss房间
+ {
+ BossRoomInfos.Add(nextRoom);
+ }
+ else if (nextRoomType == DungeonRoomType.Outlet)
+ {
+ EndRoomInfos.Add(nextRoom);
+ }
+ else if (nextRoomType == DungeonRoomType.Battle)
+ {
+ BattleRoomInfos.Add(nextRoom);
+ }
+ else if (nextRoomType == DungeonRoomType.Reward)
+ {
+ RewardRoomInfos.Add(nextRoom);
+ }
+ else if (nextRoomType == DungeonRoomType.Shop)
+ {
+ ShopRoomInfos.Add(nextRoom);
+ }
+
+ prevRoomInfo = nextRoom;
}
- currTryCount++;
- if (currTryCount >= maxTryCount)
+ else //生成失败
{
- return false;
+ //Debug.Log("生成第" + (_count + 1) + "个房间失败! 失败原因: " + errorCode);
+ if (errorCode == GenerateRoomErrorCode.OutArea)
+ {
+ _failCount++;
+ Debug.Log("超出区域失败次数: " + _failCount);
+ if (_failCount >= _maxFailCount)
+ {
+ //_enableLimitRange = false;
+ _failCount = 0;
+ _rangeX += 50;
+ _rangeY += 50;
+ Debug.Log("生成房间失败次数过多, 增大区域");
+ }
+ }
+
+ currTryCount++;
+ if (currTryCount >= maxTryCount)
+ {
+ return false;
+ }
+
+ i--;
}
}
}
-
+ else //正常随机生成
+ {
+ //如果房间数量不够, 就一直生成
+ while (!_rule.CanOverGenerator())
+ {
+ if (_nextRoomType == DungeonRoomType.None)
+ {
+ _nextRoomType = _rule.GetNextRoomType(prevRoomInfo);
+ }
+
+ var nextRoomType = _nextRoomType;
+
+ //上一个房间
+ var tempPrevRoomInfo = _rule.GetConnectPrevRoom(prevRoomInfo, nextRoomType);
+ //生成下一个房间
+ var errorCode = GenerateRoom(tempPrevRoomInfo, nextRoomType, out var nextRoom);
+ if (errorCode == GenerateRoomErrorCode.NoError) //生成成功
+ {
+ _failCount = 0;
+ RoomInfos.Add(nextRoom);
+ if (nextRoomType == DungeonRoomType.Inlet)
+ {
+ StartRoomInfo = nextRoom;
+ }
+ else if (nextRoomType == DungeonRoomType.Boss) //boss房间
+ {
+ BossRoomInfos.Add(nextRoom);
+ }
+ else if (nextRoomType == DungeonRoomType.Outlet)
+ {
+ EndRoomInfos.Add(nextRoom);
+ }
+ else if (nextRoomType == DungeonRoomType.Battle)
+ {
+ BattleRoomInfos.Add(nextRoom);
+ }
+ else if (nextRoomType == DungeonRoomType.Reward)
+ {
+ RewardRoomInfos.Add(nextRoom);
+ }
+ else if (nextRoomType == DungeonRoomType.Shop)
+ {
+ ShopRoomInfos.Add(nextRoom);
+ }
+
+ prevRoomInfo = nextRoom;
+ _rule.GenerateRoomSuccess(tempPrevRoomInfo, nextRoom);
+ _nextRoomType = _rule.GetNextRoomType(nextRoom);
+ }
+ else //生成失败
+ {
+ _rule.GenerateRoomFail(tempPrevRoomInfo, nextRoomType);
+
+ //Debug.Log("生成第" + (_count + 1) + "个房间失败! 失败原因: " + errorCode);
+ if (errorCode == GenerateRoomErrorCode.OutArea)
+ {
+ _failCount++;
+ Debug.Log("超出区域失败次数: " + _failCount);
+ if (_failCount >= _maxFailCount)
+ {
+ //_enableLimitRange = false;
+ _failCount = 0;
+ _rangeX += 50;
+ _rangeY += 50;
+ Debug.Log("生成房间失败次数过多, 增大区域");
+ }
+ }
+
+ currTryCount++;
+ if (currTryCount >= maxTryCount)
+ {
+ return false;
+ }
+ }
+ }
+ }
+
_roomGrid.Clear();
Debug.Log("房间总数: " + RoomInfos.Count);
Debug.Log("尝试次数: " + currTryCount);
@@ -251,9 +321,9 @@
// }
DungeonRoomSplit roomSplit;
- if (Config.HasDesignatedRoom && Config.DesignatedType == roomType) //执行指定了房间
+ if (Config.HasDesignatedRoom && Config.DesignatedRoom[RoomInfos.Count] != null) //执行指定了房间
{
- roomSplit = Random.RandomChoose(Config.DesignatedRoom);
+ roomSplit = Config.DesignatedRoom[RoomInfos.Count];
}
else //没有指定房间
{
diff --git a/DungeonShooting_Godot/src/framework/map/RandomPool.cs b/DungeonShooting_Godot/src/framework/map/RandomPool.cs
index 3328785..78429ad 100644
--- a/DungeonShooting_Godot/src/framework/map/RandomPool.cs
+++ b/DungeonShooting_Godot/src/framework/map/RandomPool.cs
@@ -54,10 +54,6 @@
{
FillBattleRoom(preinstall);
}
- else if (preinstall.RoomInfo.RoomType == DungeonRoomType.Reward)
- {
- FillRewardRoom(preinstall);
- }
}
//填充战斗房间
@@ -76,12 +72,12 @@
var weight = new int[] { 15, 2, 1 };
for (var i = 0; i < count; i++)
{
- var tempWave = GetOrCreateWave(preinstall, World.Random.RandomRangeInt(0, 2));
+ var tempWave = preinstall.GetOrCreateWave(World.Random.RandomRangeInt(0, 2));
var index = World.Random.RandomWeight(weight);
var activityType = arr[index];
//创建标记
- var mark = CreateMark(activityType, i * 0.3f, preinstall.RoomInfo.ToGlobalPosition(positionArray[i]));
+ var mark = ActivityMark.CreateMark(activityType, i * 0.3f, preinstall.RoomInfo.ToGlobalPosition(positionArray[i]));
if (activityType == ActivityType.Enemy) //敌人
{
@@ -109,37 +105,4 @@
tempWave.Add(mark);
}
}
-
- //填充奖励房间
- private void FillRewardRoom(RoomPreinstall preinstall)
- {
- var wave = GetOrCreateWave(preinstall, 0);
- var mark = CreateMark(ActivityType.Treasure, 0, (preinstall.RoomInfo.Waypoints + new Vector2(0.5f, 0.5f)) * GameConfig.TileCellSize);
- mark.Id = "treasure_box0001";
- wave.Add(mark);
- }
-
- private List GetOrCreateWave(RoomPreinstall preinstall,int waveIndex)
- {
- while (preinstall.WaveList.Count <= waveIndex)
- {
- preinstall.WaveList.Add(new List());
- }
-
- return preinstall.WaveList[waveIndex];
- }
-
- //创建标记
- private ActivityMark CreateMark(ActivityType activityType, float delayTime, Vector2 pos)
- {
- var mark = new ActivityMark();
- mark.Attr = new Dictionary();
- mark.ActivityType = activityType;
- mark.MarkType = SpecialMarkType.Normal;
- mark.VerticalSpeed = 0;
- mark.Altitude = activityType == ActivityType.Enemy ? 0 : 8;
- mark.DelayTime = delayTime;
- mark.Position = pos;
- return mark;
- }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs b/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs
index b1e974b..de5efc9 100644
--- a/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs
+++ b/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs
@@ -37,17 +37,34 @@
///
/// 物体初始海拔高度
///
- public int Altitude = 8;
+ public int Altitude { get; set; } = 8;
///
/// 物体初始纵轴速度
///
- public float VerticalSpeed = 0;
+ public float VerticalSpeed { get; set; } = 0;
///
/// 物体类型
///
public ActivityType ActivityType { get; set; }
-
+ ///
+ /// 快速创建标记
+ ///
+ /// 物体类型
+ /// 延时时间
+ /// 位置
+ public static ActivityMark CreateMark(ActivityType activityType, float delayTime, Vector2 pos)
+ {
+ var mark = new ActivityMark();
+ mark.Attr = new Dictionary();
+ mark.ActivityType = activityType;
+ mark.MarkType = SpecialMarkType.Normal;
+ mark.VerticalSpeed = 0;
+ mark.Altitude = activityType == ActivityType.Enemy ? 0 : 8;
+ mark.DelayTime = delayTime;
+ mark.Position = pos;
+ return mark;
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/PreinstallMarkManager.cs b/DungeonShooting_Godot/src/framework/map/preinstall/PreinstallMarkManager.cs
index 45501bf..e888f8d 100644
--- a/DungeonShooting_Godot/src/framework/map/preinstall/PreinstallMarkManager.cs
+++ b/DungeonShooting_Godot/src/framework/map/preinstall/PreinstallMarkManager.cs
@@ -106,6 +106,14 @@
{
return "出口标记";
}
+ else if (type == SpecialMarkType.ShopBoss)
+ {
+ return "商店老板标记";
+ }
+ else if (type == SpecialMarkType.Treasure)
+ {
+ return "奖励箱子标记";
+ }
return string.Empty;
}
diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs
index 827259a..d9425d2 100644
--- a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs
+++ b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs
@@ -99,72 +99,7 @@
var mark = new ActivityMark();
if (markInfo.SpecialMarkType == SpecialMarkType.Normal) //普通标记
{
- MarkInfoItem markInfoItem;
- if (markInfo.MarkList.Count == 0)
- {
- continue;
- }
- else if (markInfo.MarkList.Count == 1)
- {
- markInfoItem = markInfo.MarkList[0];
- }
- else
- {
- var tempArray = markInfo.MarkList.Select(item => item.Weight).ToArray();
- var index = world.Random.RandomWeight(tempArray);
- markInfoItem = markInfo.MarkList[index];
- }
-
- var activityBase = PreinstallMarkManager.GetMarkConfig(markInfoItem.Id);
- mark.Attr = markInfoItem.Attr;
- mark.VerticalSpeed = markInfoItem.VerticalSpeed;
- mark.Altitude = markInfoItem.Altitude;
-
- if (activityBase is RandomActivityBase) //随机物体
- {
- if (markInfoItem.Id == PreinstallMarkManager.RandomWeapon.Id) //随机武器
- {
- mark.Id = world.RandomPool.GetRandomWeapon()?.Id;
- mark.ActivityType = ActivityType.Weapon;
- }
- else if (markInfoItem.Id == PreinstallMarkManager.RandomEnemy.Id) //随机敌人
- {
- mark.Id = world.RandomPool.GetRandomEnemy()?.Id;
- mark.ActivityType = ActivityType.Enemy;
- }
- else if (markInfoItem.Id == PreinstallMarkManager.RandomProp.Id) //随机道具
- {
- mark.Id = world.RandomPool.GetRandomProp()?.Id;
- mark.ActivityType = ActivityType.Prop;
- }
- else //非随机物体
- {
- Debug.LogError("未知的随机物体:" + markInfoItem.Id);
- continue;
- }
- }
- else
- {
- mark.Id = markInfoItem.Id;
- mark.ActivityType = (ActivityType)activityBase.Type;
- if (mark.ActivityType == ActivityType.Enemy) //敌人类型
- {
- mark.DerivedAttr = new Dictionary();
- if (!mark.Attr.TryGetValue("Face", out var face) || face == "0") //随机方向
- {
- mark.DerivedAttr.Add("Face",
- world.Random.RandomChoose(
- ((int)FaceDirection.Left).ToString(),
- ((int)FaceDirection.Right).ToString()
- )
- );
- }
- else //指定方向
- {
- mark.DerivedAttr.Add("Face", face);
- }
- }
- }
+ if (HandlerNormalMark(world, markInfo, mark)) continue;
}
else if (markInfo.SpecialMarkType == SpecialMarkType.BirthPoint) //玩家出生标记
{
@@ -172,7 +107,15 @@
}
else if (markInfo.SpecialMarkType == SpecialMarkType.OutPoint) //出口标记
{
-
+
+ }
+ else if (markInfo.SpecialMarkType == SpecialMarkType.ShopBoss) //商店老板标记
+ {
+ HandlerShopBossMark(world, markInfo, mark);
+ }
+ else if (markInfo.SpecialMarkType == SpecialMarkType.Treasure) //奖励宝箱标记
+ {
+ HandlerTreasureMark(world, markInfo, mark);
}
else
{
@@ -209,6 +152,92 @@
CheckHasEnemy();
}
+ private static bool HandlerNormalMark(World world, MarkInfo markInfo, ActivityMark mark)
+ {
+ MarkInfoItem markInfoItem;
+ if (markInfo.MarkList.Count == 0) //未配置生成的物体
+ {
+ return true;
+ }
+ else if (markInfo.MarkList.Count == 1)
+ {
+ markInfoItem = markInfo.MarkList[0];
+ }
+ else
+ {
+ var tempArray = markInfo.MarkList.Select(item => item.Weight).ToArray();
+ var index = world.Random.RandomWeight(tempArray);
+ markInfoItem = markInfo.MarkList[index];
+ }
+
+ var activityBase = PreinstallMarkManager.GetMarkConfig(markInfoItem.Id);
+ mark.Attr = markInfoItem.Attr;
+ mark.VerticalSpeed = markInfoItem.VerticalSpeed;
+ mark.Altitude = markInfoItem.Altitude;
+
+ if (activityBase is RandomActivityBase) //随机物体
+ {
+ if (markInfoItem.Id == PreinstallMarkManager.RandomWeapon.Id) //随机武器
+ {
+ mark.Id = world.RandomPool.GetRandomWeapon()?.Id;
+ mark.ActivityType = ActivityType.Weapon;
+ }
+ else if (markInfoItem.Id == PreinstallMarkManager.RandomEnemy.Id) //随机敌人
+ {
+ mark.Id = world.RandomPool.GetRandomEnemy()?.Id;
+ mark.ActivityType = ActivityType.Enemy;
+ }
+ else if (markInfoItem.Id == PreinstallMarkManager.RandomProp.Id) //随机道具
+ {
+ mark.Id = world.RandomPool.GetRandomProp()?.Id;
+ mark.ActivityType = ActivityType.Prop;
+ }
+ else //非随机物体
+ {
+ Debug.LogError("未知的随机物体:" + markInfoItem.Id);
+ return true;
+ }
+ }
+ else
+ {
+ mark.Id = markInfoItem.Id;
+ mark.ActivityType = (ActivityType)activityBase.Type;
+ if (mark.ActivityType == ActivityType.Enemy) //敌人类型
+ {
+ mark.DerivedAttr = new Dictionary();
+ if (!mark.Attr.TryGetValue("Face", out var face) || face == "0") //随机方向
+ {
+ mark.DerivedAttr.Add("Face",
+ world.Random.RandomChoose(
+ ((int)FaceDirection.Left).ToString(),
+ ((int)FaceDirection.Right).ToString()
+ )
+ );
+ }
+ else //指定方向
+ {
+ mark.DerivedAttr.Add("Face", face);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private void HandlerShopBossMark(World world, MarkInfo markInfo, ActivityMark mark)
+ {
+ mark.Id = ActivityObject.Ids.Id_treasure_box0001;
+ mark.ActivityType = ActivityType.Treasure;
+ mark.Altitude = 0;
+ }
+
+ private void HandlerTreasureMark(World world, MarkInfo markInfo, ActivityMark mark)
+ {
+ mark.Id = ActivityObject.Ids.Id_treasure_box0001;
+ mark.ActivityType = ActivityType.Treasure;
+ mark.Altitude = 0;
+ }
+
private void CheckHasEnemy()
{
foreach (var marks in WaveList)
@@ -244,9 +273,15 @@
var activityMarks = WaveList[0];
foreach (var activityMark in activityMarks)
{
- if (activityMark.MarkType == SpecialMarkType.Normal)
+ if (activityMark.MarkType == SpecialMarkType.Normal ||
+ activityMark.MarkType == SpecialMarkType.Treasure ||
+ activityMark.MarkType == SpecialMarkType.ShopBoss)
{
var activityObject = CreateItem(activityMark);
+ if (activityObject == null)
+ {
+ continue;
+ }
//初始化属性
InitAttr(activityObject, activityMark);
if (_readyList == null)
@@ -254,6 +289,7 @@
_readyList = new List();
}
_readyList.Add(new PreloadData(activityObject, GetDefaultLayer(activityMark)));
+ activityObject.OnCreateWithMark(this, activityMark);
}
}
}
@@ -417,6 +453,10 @@
private ActivityObject CreateItem(ActivityMark activityMark)
{
var activityObject = ActivityObject.Create(activityMark.Id);
+ if (activityObject == null)
+ {
+ return null;
+ }
activityObject.Position = activityMark.Position;
activityObject.VerticalSpeed = activityMark.VerticalSpeed;
activityObject.Altitude = activityMark.Altitude;
@@ -435,9 +475,9 @@
}
///
- /// 获取房间内的玩家生成标记
+ /// 获取房间内的特殊标记
///
- public ActivityMark GetPlayerBirthMark()
+ public ActivityMark GetSpecialMark(SpecialMarkType specialMarkType)
{
if (WaveList.Count == 0)
{
@@ -445,7 +485,7 @@
}
var activityMarks = WaveList[0];
- var activityMark = activityMarks.FirstOrDefault(mark => mark.MarkType == SpecialMarkType.BirthPoint);
+ var activityMark = activityMarks.FirstOrDefault(mark => mark.MarkType == specialMarkType);
return activityMark;
}
@@ -473,6 +513,19 @@
_readyList.Clear();
}
}
+
+ ///
+ /// 获取或创建指定波数数据
+ ///
+ public List GetOrCreateWave(int waveIndex)
+ {
+ while (WaveList.Count <= waveIndex)
+ {
+ WaveList.Add(new List());
+ }
+
+ return WaveList[waveIndex];
+ }
//初始化物体属性
private void InitAttr(ActivityObject activityObject, ActivityMark activityMark)
diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs b/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs
index 385cff3..8a96abb 100644
--- a/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs
+++ b/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs
@@ -16,4 +16,12 @@
/// 地牢出口
///
OutPoint,
+ ///
+ /// 宝箱房刷新点
+ ///
+ Treasure,
+ ///
+ /// 商店房商店老板刷新点
+ ///
+ ShopBoss,
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonRoomGroup.cs b/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonRoomGroup.cs
index b6d55f2..5c47f06 100644
--- a/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonRoomGroup.cs
+++ b/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonRoomGroup.cs
@@ -151,6 +151,11 @@
{
if (_init)
{
+ foreach (var keyValuePair in _weightRandomMap)
+ {
+ keyValuePair.Value.SetSeedRandom(random);
+ }
+
return;
}
diff --git a/DungeonShooting_Godot/src/framework/map/serialize/room/RoomPreinstallInfo.cs b/DungeonShooting_Godot/src/framework/map/serialize/room/RoomPreinstallInfo.cs
index 2cb7c7f..8d14dd4 100644
--- a/DungeonShooting_Godot/src/framework/map/serialize/room/RoomPreinstallInfo.cs
+++ b/DungeonShooting_Godot/src/framework/map/serialize/room/RoomPreinstallInfo.cs
@@ -53,16 +53,7 @@
///
public void InitSpecialMark(DungeonRoomType roomType)
{
- var type = SpecialMarkType.Normal;
- if (roomType == DungeonRoomType.Inlet) //初始房间
- {
- type = SpecialMarkType.BirthPoint;
- }
- else if (roomType == DungeonRoomType.Outlet) //结束房间
- {
- type = SpecialMarkType.OutPoint;
- }
-
+ var type = GetRoomSpecialMark(roomType);
if (type != SpecialMarkType.Normal)
{
var preloading = WaveList[0];
@@ -74,4 +65,56 @@
preloading.Add(markInfo);
}
}
+
+ ///
+ /// 检查是否创建了特殊标记, 如果没有, 则会自动创建并返回false
+ ///
+ public bool CheckSpecialMark(DungeonRoomType roomType)
+ {
+ var type = GetRoomSpecialMark(roomType);
+ if (type == SpecialMarkType.Normal)
+ {
+ return true;
+ }
+
+ if (WaveList.Count> 0)
+ {
+ var markInfos = WaveList[0];
+ foreach (var markInfo in markInfos)
+ {
+ if (markInfo.SpecialMarkType == type)
+ {
+ return true;
+ }
+ }
+ }
+
+ InitSpecialMark(roomType);
+ return false;
+ }
+
+ ///
+ /// 获取指定类型房间中应该存在的特殊标记数据类型
+ ///
+ public SpecialMarkType GetRoomSpecialMark(DungeonRoomType roomType)
+ {
+ if (roomType == DungeonRoomType.Inlet) //初始房间
+ {
+ return SpecialMarkType.BirthPoint;
+ }
+ else if (roomType == DungeonRoomType.Outlet) //结束房间
+ {
+ return SpecialMarkType.OutPoint;
+ }
+ else if (roomType == DungeonRoomType.Shop) //商店房间
+ {
+ return SpecialMarkType.ShopBoss;
+ }
+ else if (roomType == DungeonRoomType.Reward) //奖励房间
+ {
+ return SpecialMarkType.Treasure;
+ }
+
+ return SpecialMarkType.Normal;
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs
index 02be8c1..d75c0b0 100644
--- a/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs
+++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs
@@ -76,7 +76,7 @@
{
base.OnInit();
OutlineColor = new Color(2.5f, 0, 0);
- SetBlendColor(new Color(2.0f, 2.0f, 2.0f));
+ SetBlendColor(new Color(2.5f, 2.5f, 2.5f));
}
public virtual void InitData(BulletData data, uint attackLayer)
diff --git a/DungeonShooting_Godot/src/game/activity/currency/Gold.cs b/DungeonShooting_Godot/src/game/activity/currency/Gold.cs
index 29eb440..991d072 100644
--- a/DungeonShooting_Godot/src/game/activity/currency/Gold.cs
+++ b/DungeonShooting_Godot/src/game/activity/currency/Gold.cs
@@ -1,4 +1,5 @@
+using System.Collections.Generic;
using Godot;
///
@@ -70,4 +71,29 @@
MoveController.ClearForce();
MoveController.SetAllVelocity(Vector2.Zero);
}
+
+ ///
+ /// 创建散落的金币
+ ///
+ /// 位置
+ /// 金币数量
+ /// 投抛力度
+ public static List CreateGold(Vector2 position, int count, int force = 10)
+ {
+ var list = new List();
+ var goldList = Utils.GetGoldList(count);
+ foreach (var id in goldList)
+ {
+ var o = ObjectManager.GetActivityObject(id);
+ o.Position = position;
+ o.Throw(0,
+ Utils.Random.RandomRangeInt(5 * force, 11 * force),
+ new Vector2(Utils.Random.RandomRangeInt(-2 * force, 2 * force), Utils.Random.RandomRangeInt(-2 * force, 2 * force)),
+ 0
+ );
+ list.Add(o);
+ }
+
+ return list;
+ }
}
diff --git a/DungeonShooting_Godot/src/game/activity/prop/ActiveProp.cs b/DungeonShooting_Godot/src/game/activity/prop/ActiveProp.cs
index 6a9cafb..830eb27 100644
--- a/DungeonShooting_Godot/src/game/activity/prop/ActiveProp.cs
+++ b/DungeonShooting_Godot/src/game/activity/prop/ActiveProp.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
+using System.Text.Json;
using Config;
using Godot;
@@ -121,43 +122,16 @@
{
var buffInfo = PropFragmentRegister.BuffFragmentInfos[keyValuePair.Key];
var item = keyValuePair.Value;
- switch (item.Length)
+ var buff = (BuffFragment)AddComponent(buffInfo.Type);
+ try
{
- case 0:
- {
- var buff = (BuffFragment)AddComponent(buffInfo.Type);
- _buffFragment.Add(buff);
- }
- break;
- case 1:
- {
- var buff = (BuffFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0]);
- _buffFragment.Add(buff);
- }
- break;
- case 2:
- {
- var buff = (BuffFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1]);
- _buffFragment.Add(buff);
- }
- break;
- case 3:
- {
- var buff = (BuffFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1], item[2]);
- _buffFragment.Add(buff);
- }
- break;
- case 4:
- {
- var buff = (BuffFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1], item[2], item[3]);
- _buffFragment.Add(buff);
- }
- break;
+ buff.InitParam(item);
}
+ catch (Exception e)
+ {
+ Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
+ }
+ _buffFragment.Add(buff);
}
}
@@ -168,43 +142,16 @@
{
var buffInfo = PropFragmentRegister.ConditionFragmentInfos[keyValuePair.Key];
var item = keyValuePair.Value;
- switch (item.Length)
+ var buff = (ConditionFragment)AddComponent(buffInfo.Type);
+ try
{
- case 0:
- {
- var buff = (ConditionFragment)AddComponent(buffInfo.Type);
- _conditionFragment.Add(buff);
- }
- break;
- case 1:
- {
- var buff = (ConditionFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0]);
- _conditionFragment.Add(buff);
- }
- break;
- case 2:
- {
- var buff = (ConditionFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1]);
- _conditionFragment.Add(buff);
- }
- break;
- case 3:
- {
- var buff = (ConditionFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1], item[2]);
- _conditionFragment.Add(buff);
- }
- break;
- case 4:
- {
- var buff = (ConditionFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1], item[2], item[3]);
- _conditionFragment.Add(buff);
- }
- break;
+ buff.InitParam(item);
}
+ catch (Exception e)
+ {
+ Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
+ }
+ _conditionFragment.Add(buff);
}
}
@@ -215,43 +162,16 @@
{
var buffInfo = PropFragmentRegister.EffectFragmentInfos[keyValuePair.Key];
var item = keyValuePair.Value;
- switch (item.Length)
+ var buff = (EffectFragment)AddComponent(buffInfo.Type);
+ try
{
- case 0:
- {
- var buff = (EffectFragment)AddComponent(buffInfo.Type);
- _effectFragment.Add(buff);
- }
- break;
- case 1:
- {
- var buff = (EffectFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0]);
- _effectFragment.Add(buff);
- }
- break;
- case 2:
- {
- var buff = (EffectFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1]);
- _effectFragment.Add(buff);
- }
- break;
- case 3:
- {
- var buff = (EffectFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1], item[2]);
- _effectFragment.Add(buff);
- }
- break;
- case 4:
- {
- var buff = (EffectFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1], item[2], item[3]);
- _effectFragment.Add(buff);
- }
- break;
+ buff.InitParam(item);
}
+ catch (Exception e)
+ {
+ Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
+ }
+ _effectFragment.Add(buff);
}
}
@@ -262,43 +182,16 @@
{
var buffInfo = PropFragmentRegister.ChargeFragmentInfos[keyValuePair.Key];
var item = keyValuePair.Value;
- switch (item.Length)
+ var buff = (ChargeFragment)AddComponent(buffInfo.Type);
+ try
{
- case 0:
- {
- var buff = (ChargeFragment)AddComponent(buffInfo.Type);
- _chargeFragment.Add(buff);
- }
- break;
- case 1:
- {
- var buff = (ChargeFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0]);
- _chargeFragment.Add(buff);
- }
- break;
- case 2:
- {
- var buff = (ChargeFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1]);
- _chargeFragment.Add(buff);
- }
- break;
- case 3:
- {
- var buff = (ChargeFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1], item[2]);
- _chargeFragment.Add(buff);
- }
- break;
- case 4:
- {
- var buff = (ChargeFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1], item[2], item[3]);
- _chargeFragment.Add(buff);
- }
- break;
+ buff.InitParam(item);
}
+ catch (Exception e)
+ {
+ Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
+ }
+ _chargeFragment.Add(buff);
}
}
@@ -626,70 +519,21 @@
Master.ThrowActiveProp(PackageIndex);
}
-
///
/// 添加被动属性
///
- public void AddBuffFragment() where T : BuffFragment, new()
+ public void AddBuffFragment(JsonElement[] arg) where T : BuffFragment, new()
{
var fragment = AddComponent();
_buffFragment.Add(fragment);
- if (Master != null)
+ try
{
- fragment.OnPickUpItem();
+ fragment.InitParam(arg);
}
- }
-
- ///
- /// 添加被动属性
- ///
- public void AddBuffFragment(float arg1) where T : BuffFragment, new()
- {
- var fragment = AddComponent();
- _buffFragment.Add(fragment);
- fragment.InitParam(arg1);
- if (Master != null)
+ catch (Exception e)
{
- fragment.OnPickUpItem();
+ Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
}
- }
-
- ///
- /// 添加被动属性
- ///
- public void AddBuffFragment(float arg1, float arg2) where T : BuffFragment, new()
- {
- var fragment = AddComponent();
- _buffFragment.Add(fragment);
- fragment.InitParam(arg1, arg2);
- if (Master != null)
- {
- fragment.OnPickUpItem();
- }
- }
-
- ///
- /// 添加被动属性
- ///
- public void AddBuffFragment(float arg1, float arg2, float arg3) where T : BuffFragment, new()
- {
- var fragment = AddComponent();
- _buffFragment.Add(fragment);
- fragment.InitParam(arg1, arg2, arg3);
- if (Master != null)
- {
- fragment.OnPickUpItem();
- }
- }
-
- ///
- /// 添加被动属性
- ///
- public void AddBuffFragment(float arg1, float arg2, float arg3, float arg4) where T : BuffFragment, new()
- {
- var fragment = AddComponent();
- _buffFragment.Add(fragment);
- fragment.InitParam(arg1, arg2, arg3, arg4);
if (Master != null)
{
fragment.OnPickUpItem();
diff --git a/DungeonShooting_Godot/src/game/activity/prop/BuffProp.cs b/DungeonShooting_Godot/src/game/activity/prop/BuffProp.cs
index c3139db..b1d3b55 100644
--- a/DungeonShooting_Godot/src/game/activity/prop/BuffProp.cs
+++ b/DungeonShooting_Godot/src/game/activity/prop/BuffProp.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
+using System.Text.Json;
using Config;
using Godot;
@@ -30,43 +31,16 @@
{
var buffInfo = PropFragmentRegister.BuffFragmentInfos[keyValuePair.Key];
var item = keyValuePair.Value;
- switch (item.Length)
+ var buff = (BuffFragment)AddComponent(buffInfo.Type);
+ try
{
- case 0:
- {
- var buff = (BuffFragment)AddComponent(buffInfo.Type);
- _buffFragment.Add(buff);
- }
- break;
- case 1:
- {
- var buff = (BuffFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0]);
- _buffFragment.Add(buff);
- }
- break;
- case 2:
- {
- var buff = (BuffFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1]);
- _buffFragment.Add(buff);
- }
- break;
- case 3:
- {
- var buff = (BuffFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1], item[2]);
- _buffFragment.Add(buff);
- }
- break;
- case 4:
- {
- var buff = (BuffFragment)AddComponent(buffInfo.Type);
- buff.InitParam(item[0], item[1], item[2], item[3]);
- _buffFragment.Add(buff);
- }
- break;
+ buff.InitParam(item);
}
+ catch (Exception e)
+ {
+ Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
+ }
+ _buffFragment.Add(buff);
}
}
@@ -92,70 +66,22 @@
buffFragment.OnRemoveItem();
}
}
-
- ///
- /// 添加被动属性
- ///
- public void AddBuffFragment() where T : BuffFragment, new()
- {
- var fragment = AddComponent();
- _buffFragment.Add(fragment);
- if (Master != null)
- {
- fragment.OnPickUpItem();
- }
- }
///
/// 添加被动属性
///
- public void AddBuffFragment(float arg1) where T : BuffFragment, new()
+ public void AddBuffFragment(JsonElement[] arg) where T : BuffFragment, new()
{
var fragment = AddComponent();
_buffFragment.Add(fragment);
- fragment.InitParam(arg1);
- if (Master != null)
+ try
{
- fragment.OnPickUpItem();
+ fragment.InitParam(arg);
}
- }
-
- ///
- /// 添加被动属性
- ///
- public void AddBuffFragment(float arg1, float arg2) where T : BuffFragment, new()
- {
- var fragment = AddComponent();
- _buffFragment.Add(fragment);
- fragment.InitParam(arg1, arg2);
- if (Master != null)
+ catch (Exception e)
{
- fragment.OnPickUpItem();
+ Debug.LogError($"初始化道具'{ActivityBase.Id}'参数时发生异常: {e.Message}\n{e.StackTrace}");
}
- }
-
- ///
- /// 添加被动属性
- ///
- public void AddBuffFragment(float arg1, float arg2, float arg3) where T : BuffFragment, new()
- {
- var fragment = AddComponent();
- _buffFragment.Add(fragment);
- fragment.InitParam(arg1, arg2, arg3);
- if (Master != null)
- {
- fragment.OnPickUpItem();
- }
- }
-
- ///
- /// 添加被动属性
- ///
- public void AddBuffFragment(float arg1, float arg2, float arg3, float arg4) where T : BuffFragment, new()
- {
- var fragment = AddComponent();
- _buffFragment.Add(fragment);
- fragment.InitParam(arg1, arg2, arg3, arg4);
if (Master != null)
{
fragment.OnPickUpItem();
diff --git a/DungeonShooting_Godot/src/game/activity/role/Role.cs b/DungeonShooting_Godot/src/game/activity/role/Role.cs
index ecb1011..4fbde5a 100644
--- a/DungeonShooting_Godot/src/game/activity/role/Role.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/Role.cs
@@ -1234,11 +1234,11 @@
return;
}
- var temp = weapon.AnimatedSprite.Position;
- if (Face == FaceDirection.Left)
- {
- temp.Y = -temp.Y;
- }
+ // var temp = weapon.AnimatedSprite.Position;
+ // if (Face == FaceDirection.Left)
+ // {
+ // temp.Y = -temp.Y;
+ // }
//var pos = GlobalPosition + temp.Rotated(weapon.GlobalRotation);
WeaponPack.RemoveItem(index);
//播放抛出效果
@@ -1246,6 +1246,21 @@
}
///
+ /// 从背包中移除指定武器, 不会触发投抛效果
+ ///
+ /// 武器在武器背包中的位置
+ public void RemoveWeapon(int index)
+ {
+ var weapon = WeaponPack.GetItem(index);
+ if (weapon == null)
+ {
+ return;
+ }
+
+ WeaponPack.RemoveItem(index);
+ }
+
+ ///
/// 扔掉所有武器
///
public void ThrowAllWeapon()
@@ -1342,6 +1357,14 @@
}
///
+ /// 使用金币
+ ///
+ public virtual void UseGold(int goldCount)
+ {
+ RoleState.Gold -= goldCount;
+ }
+
+ ///
/// 切换当前使用的武器的回调
///
private void OnChangeActiveItem(Weapon weapon)
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/AiRole.cs b/DungeonShooting_Godot/src/game/activity/role/ai/AiRole.cs
new file mode 100644
index 0000000..bbbd45f
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/AiRole.cs
@@ -0,0 +1,381 @@
+
+using AiState;
+using Godot;
+
+///
+/// Ai角色
+///
+public abstract partial class AiRole : Role
+{
+ ///
+ /// 目标是否在视野内
+ ///
+ public bool TargetInView { get; set; } = true;
+
+ ///
+ /// 敌人身上的状态机控制器
+ ///
+ public StateController StateController { get; private set; }
+
+ ///
+ /// 视野检测射线, 朝玩家打射线, 检测是否碰到墙
+ ///
+ [Export, ExportFillNode]
+ public RayCast2D ViewRay { get; set; }
+
+ ///
+ /// 导航代理
+ ///
+ [Export, ExportFillNode]
+ public NavigationAgent2D NavigationAgent2D { get; set; }
+
+ ///
+ /// 导航代理中点
+ ///
+ [Export, ExportFillNode]
+ public Marker2D NavigationPoint { get; set; }
+
+ ///
+ /// 不通过武发射子弹的开火点
+ ///
+ [Export, ExportFillNode]
+ public Marker2D FirePoint { get; set; }
+
+ ///
+ /// 当前敌人所看向的对象, 也就是枪口指向的对象
+ ///
+ public ActivityObject LookTarget { get; set; }
+
+ ///
+ /// 攻击锁定目标时间
+ ///
+ public float LockingTime { get; set; } = 1f;
+
+ ///
+ /// 锁定目标已经走过的时间
+ ///
+ public float LockTargetTime { get; set; } = 0;
+
+ ///
+ /// 视野半径, 单位像素, 发现玩家后改视野范围可以穿墙
+ ///
+ public float ViewRange { get; set; } = 250;
+
+ ///
+ /// 发现玩家后跟随玩家的视野半径
+ ///
+ public float TailAfterViewRange { get; set; } = 400;
+
+ ///
+ /// 背后的视野半径, 单位像素
+ ///
+ public float BackViewRange { get; set; } = 50;
+
+ ///
+ /// 攻击间隔时间, 秒
+ ///
+ public float AttackInterval { get; set; } = 0;
+
+ public override void OnInit()
+ {
+ base.OnInit();
+ IsAi = true;
+
+ StateController = AddComponent>();
+
+ //注册Ai状态机
+ StateController.Register(new AiNormalState());
+ StateController.Register(new AiTailAfterState());
+ StateController.Register(new AiFollowUpState());
+ StateController.Register(new AiLeaveForState());
+ StateController.Register(new AiSurroundState());
+ StateController.Register(new AiFindAmmoState());
+ StateController.Register(new AiAttackState());
+ StateController.Register(new AiAstonishedState());
+ StateController.Register(new AiNotifyState());
+
+ //默认状态
+ StateController.ChangeStateInstant(AIStateEnum.AiNormal);
+
+ //NavigationAgent2D.VelocityComputed += OnVelocityComputed;
+ }
+
+ ///
+ /// 返回地上的武器是否有可以拾取的, 也包含没有被其他敌人标记的武器
+ ///
+ public bool CheckUsableWeaponInUnclaimed()
+ {
+ foreach (var unclaimedWeapon in World.Weapon_UnclaimedWeapons)
+ {
+ //判断是否能拾起武器, 条件: 相同的房间
+ if (unclaimedWeapon.AffiliationArea == AffiliationArea)
+ {
+ if (!unclaimedWeapon.IsTotalAmmoEmpty())
+ {
+ if (!unclaimedWeapon.HasSign(SignNames.AiFindWeaponSign))
+ {
+ return true;
+ }
+ else
+ {
+ //判断是否可以移除该标记
+ var enemy = unclaimedWeapon.GetSign(SignNames.AiFindWeaponSign);
+ if (enemy == null || enemy.IsDestroyed) //标记当前武器的敌人已经被销毁
+ {
+ unclaimedWeapon.RemoveSign(SignNames.AiFindWeaponSign);
+ return true;
+ }
+ else if (!enemy.IsAllWeaponTotalAmmoEmpty()) //标记当前武器的敌人已经有新的武器了
+ {
+ unclaimedWeapon.RemoveSign(SignNames.AiFindWeaponSign);
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// 寻找可用的武器
+ ///
+ public Weapon FindTargetWeapon()
+ {
+ Weapon target = null;
+ var position = Position;
+ foreach (var weapon in World.Weapon_UnclaimedWeapons)
+ {
+ //判断是否能拾起武器, 条件: 相同的房间, 或者当前房间目前没有战斗, 或者不在战斗房间
+ if (weapon.AffiliationArea == AffiliationArea)
+ {
+ //还有弹药
+ if (!weapon.IsTotalAmmoEmpty())
+ {
+ //查询是否有其他敌人标记要拾起该武器
+ if (weapon.HasSign(SignNames.AiFindWeaponSign))
+ {
+ var enemy = weapon.GetSign(SignNames.AiFindWeaponSign);
+ if (enemy == this) //就是自己标记的
+ {
+
+ }
+ else if (enemy == null || enemy.IsDestroyed) //标记当前武器的敌人已经被销毁
+ {
+ weapon.RemoveSign(SignNames.AiFindWeaponSign);
+ }
+ else if (!enemy.IsAllWeaponTotalAmmoEmpty()) //标记当前武器的敌人已经有新的武器了
+ {
+ weapon.RemoveSign(SignNames.AiFindWeaponSign);
+ }
+ else //放弃这把武器
+ {
+ continue;
+ }
+ }
+
+ if (target == null) //第一把武器
+ {
+ target = weapon;
+ }
+ else if (target.Position.DistanceSquaredTo(position) >
+ weapon.Position.DistanceSquaredTo(position)) //距离更近
+ {
+ target = weapon;
+ }
+ }
+ }
+ }
+
+ return target;
+ }
+
+ ///
+ /// 获取武器攻击范围 (最大距离值与最小距离的中间值)
+ ///
+ /// 从最小到最大距离的过渡量, 0 - 1, 默认 0.5
+ public float GetWeaponRange(float weight = 0.5f)
+ {
+ if (WeaponPack.ActiveItem != null)
+ {
+ var attribute = WeaponPack.ActiveItem.Attribute;
+ return Mathf.Lerp(Utils.GetConfigRangeStart(attribute.Bullet.DistanceRange), Utils.GetConfigRangeEnd(attribute.Bullet.DistanceRange), weight);
+ }
+
+ return 0;
+ }
+
+ ///
+ /// 返回目标点是否在视野范围内
+ ///
+ public virtual bool IsInViewRange(Vector2 target)
+ {
+ var isForward = IsPositionInForward(target);
+ if (isForward)
+ {
+ if (GlobalPosition.DistanceSquaredTo(target) <= ViewRange * ViewRange) //没有超出视野半径
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// 返回目标点是否在跟随状态下的视野半径内
+ ///
+ public virtual bool IsInTailAfterViewRange(Vector2 target)
+ {
+ var isForward = IsPositionInForward(target);
+ if (isForward)
+ {
+ if (GlobalPosition.DistanceSquaredTo(target) <= TailAfterViewRange * TailAfterViewRange) //没有超出视野半径
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// 调用视野检测, 如果被墙壁和其它物体遮挡, 则返回true
+ ///
+ public bool TestViewRayCast(Vector2 target)
+ {
+ ViewRay.Enabled = true;
+ ViewRay.TargetPosition = ViewRay.ToLocal(target);
+ ViewRay.ForceRaycastUpdate();
+ return ViewRay.IsColliding();
+ }
+
+ ///
+ /// 调用视野检测完毕后, 需要调用 TestViewRayCastOver() 来关闭视野检测射线
+ ///
+ public void TestViewRayCastOver()
+ {
+ ViewRay.Enabled = false;
+ }
+
+ ///
+ /// AI 拾起武器操作
+ ///
+ public void DoPickUpWeapon()
+ {
+ //这几个状态不需要主动拾起武器操作
+ var state = StateController.CurrState;
+ if (state == AIStateEnum.AiNormal || state == AIStateEnum.AiNotify || state == AIStateEnum.AiAstonished || state == AIStateEnum.AiAttack)
+ {
+ return;
+ }
+
+ //拾起地上的武器
+ if (InteractiveItem is Weapon weapon)
+ {
+ if (WeaponPack.ActiveItem == null) //手上没有武器, 无论如何也要拾起
+ {
+ TriggerInteractive();
+ return;
+ }
+
+ //没弹药了
+ if (weapon.IsTotalAmmoEmpty())
+ {
+ return;
+ }
+
+ var index = WeaponPack.FindIndex((we, i) => we.ActivityBase.Id == weapon.ActivityBase.Id);
+ if (index != -1) //与武器背包中武器类型相同, 补充子弹
+ {
+ if (!WeaponPack.GetItem(index).IsAmmoFull())
+ {
+ TriggerInteractive();
+ }
+
+ return;
+ }
+
+ // var index2 = Holster.FindWeapon((we, i) =>
+ // we.Attribute.WeightType == weapon.Attribute.WeightType && we.IsTotalAmmoEmpty());
+ var index2 = WeaponPack.FindIndex((we, i) => we.IsTotalAmmoEmpty());
+ if (index2 != -1) //扔掉没子弹的武器
+ {
+ ThrowWeapon(index2);
+ TriggerInteractive();
+ return;
+ }
+
+ // if (Holster.HasVacancy()) //有空位, 拾起武器
+ // {
+ // TriggerInteractive();
+ // return;
+ // }
+ }
+ }
+
+ ///
+ /// 获取锁定目标的剩余时间
+ ///
+ public float GetLockRemainderTime()
+ {
+ var weapon = WeaponPack.ActiveItem;
+ if (weapon == null)
+ {
+ return LockingTime - LockTargetTime;
+ }
+ return weapon.Attribute.AiAttackAttr.LockingTime - LockTargetTime;
+ }
+
+ public override void LookTargetPosition(Vector2 pos)
+ {
+ LookTarget = null;
+ base.LookTargetPosition(pos);
+ }
+
+ ///
+ /// 执行移动操作
+ ///
+ public void DoMove()
+ {
+ // //计算移动
+ // NavigationAgent2D.MaxSpeed = EnemyRoleState.MoveSpeed;
+ // var nextPos = NavigationAgent2D.GetNextPathPosition();
+ // NavigationAgent2D.Velocity = (nextPos - Position - NavigationPoint.Position).Normalized() * RoleState.MoveSpeed;
+
+ AnimatedSprite.Play(AnimatorNames.Run);
+ //计算移动
+ var nextPos = NavigationAgent2D.GetNextPathPosition();
+ BasisVelocity = (nextPos - Position - NavigationPoint.Position).Normalized() * RoleState.MoveSpeed;
+ }
+
+ ///
+ /// 执行站立操作
+ ///
+ public void DoIdle()
+ {
+ AnimatedSprite.Play(AnimatorNames.Idle);
+ BasisVelocity = Vector2.Zero;
+ }
+
+ ///
+ /// 更新房间中标记的目标位置
+ ///
+ public void UpdateMarkTargetPosition()
+ {
+ if (LookTarget != null)
+ {
+ AffiliationArea.RoomInfo.MarkTargetPosition[LookTarget.Id] = LookTarget.Position;
+ }
+ }
+
+ // private void OnVelocityComputed(Vector2 velocity)
+ // {
+ // if (Mathf.Abs(velocity.X) >= 0.01f && Mathf.Abs(velocity.Y) >= 0.01f)
+ // {
+ // AnimatedSprite.Play(AnimatorNames.Run);
+ // BasisVelocity = velocity;
+ // }
+ // }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAstonishedState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAstonishedState.cs
new file mode 100644
index 0000000..0d7131b
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAstonishedState.cs
@@ -0,0 +1,56 @@
+using Godot;
+
+namespace AiState;
+
+///
+/// 发现目标时的惊讶状态
+///
+public class AiAstonishedState : StateBase
+{
+ ///
+ /// 下一个状态
+ ///
+ public AIStateEnum NextState;
+
+ private float _timer;
+ private object[] _args;
+
+ public AiAstonishedState() : base(AIStateEnum.AiAstonished)
+ {
+ }
+
+ public override void Enter(AIStateEnum prev, params object[] args)
+ {
+ if (args.Length == 0)
+ {
+ Debug.Log("进入 AINormalStateEnum.AiAstonished 状态必传入下一个状态做完参数!");
+ ChangeState(prev);
+ return;
+ }
+
+ _args = args;
+
+ NextState = (AIStateEnum)args[0];
+ _timer = 0.6f;
+
+ //播放惊讶表情
+ Master.AnimationPlayer.Play(AnimatorNames.Astonished);
+ }
+
+ public override void Process(float delta)
+ {
+ Master.DoIdle();
+ _timer -= delta;
+ if (_timer <= 0)
+ {
+ if (_args.Length == 1)
+ {
+ ChangeState(NextState);
+ }
+ else if (_args.Length == 2)
+ {
+ ChangeState(NextState, _args[1]);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAttackState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAttackState.cs
new file mode 100644
index 0000000..12acf2e
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiAttackState.cs
@@ -0,0 +1,314 @@
+using System;
+using Godot;
+
+namespace AiState;
+
+///
+/// ai 攻击状态
+///
+public class AiAttackState : StateBase
+{
+ ///
+ /// 上一个状态
+ ///
+ public AIStateEnum PrevState;
+
+ ///
+ /// 武器攻击状态
+ ///
+ public AiAttackEnum AttackState;
+
+ //是否移动结束
+ private bool _isMoveOver;
+
+ //移动停顿计时器
+ private float _pauseTimer;
+ private bool _moveFlag;
+
+ //下一个移动点
+ private Vector2 _nextPosition;
+
+ //上一帧位置
+ private Vector2 _prevPos;
+ //卡在一个位置的时间
+ private float _lockTimer;
+ //进入状态的时候是否有武器
+ private bool _hasWeapon = true;
+
+ public AiAttackState() : base(AIStateEnum.AiAttack)
+ {
+ }
+
+ public override void Enter(AIStateEnum prev, params object[] args)
+ {
+ if (Master.LookTarget == null)
+ {
+ throw new Exception("进入 AIAdvancedStateEnum.AiAttack 状态时角色没有攻击目标!");
+ }
+
+ var weapon = Master.WeaponPack.ActiveItem;
+
+ if (weapon != null)
+ {
+ _hasWeapon = true;
+ if (Master.IsAttack || !weapon.TriggerIsReady())
+ {
+ throw new Exception("进入 AIAdvancedStateEnum.AiAttack 状态时角色武器还无法触动扳机!");
+ }
+ }
+ else
+ {
+ _hasWeapon = false;
+ if (Master.IsAttack)
+ {
+ throw new Exception("进入 AIAdvancedStateEnum.AiAttack 状态时角色攻击状态还没准备好");
+ }
+ }
+
+ Master.BasisVelocity = Vector2.Zero;
+ AttackState = AiAttackEnum.None;
+ Master.LockTargetTime = 0;
+ PrevState = prev;
+
+ _isMoveOver = true;
+ _pauseTimer = 0;
+ _moveFlag = false;
+ }
+
+ public override void Exit(AIStateEnum next)
+ {
+ Master.MountLookTarget = true;
+ Master.LockTargetTime = 0;
+ }
+
+ public override void Process(float delta)
+ {
+ //更新标记位置
+ Master.UpdateMarkTargetPosition();
+
+ if (_hasWeapon)
+ {
+ WeaponRoleProcess(delta);
+ }
+ else
+ {
+ NoWeaponRoleProcess(delta);
+ }
+ }
+
+ //有武器的敌人更新逻辑
+ private void WeaponRoleProcess(float delta)
+ {
+ var weapon = Master.WeaponPack.ActiveItem;
+ if (weapon == null)
+ {
+ //攻击结束
+ ChangeState(PrevState);
+ }
+ else if (AttackState == AiAttackEnum.AttackInterval) //攻击完成
+ {
+ if (weapon.GetAttackTimer() <= 0) //攻击冷却完成
+ {
+ Master.MountLookTarget = true;
+ //这里要做换弹判断, 还有上膛判断
+ if (weapon.CurrAmmo <= 0) //换弹判断
+ {
+ if (!weapon.Reloading)
+ {
+ weapon.Reload();
+ }
+ }
+ else if (weapon.GetBeLoadedStateState() != 2) //上膛
+ {
+ if (weapon.GetBeLoadedStateState() == 0)
+ {
+ weapon.BeLoaded();
+ }
+ }
+ else
+ {
+ //攻击结束
+ ChangeState(PrevState);
+ }
+ }
+ MoveHandler(delta);
+ }
+ else //攻击状态
+ {
+ //触发扳机
+ AttackState = weapon.AiTriggerAttackState(AttackState);
+
+ if (AttackState == AiAttackEnum.LockingTime) //锁定玩家状态
+ {
+ Master.LockTargetTime += delta;
+
+ var aiLockRemainderTime = Master.GetLockRemainderTime();
+ Master.MountLookTarget = aiLockRemainderTime >= weapon.Attribute.AiAttackAttr.LockAngleTime;
+ //更新瞄准辅助线
+ if (weapon.Attribute.AiAttackAttr.ShowSubline)
+ {
+ if (Master.SubLine == null)
+ {
+ Master.InitSubLine();
+ }
+ else
+ {
+ Master.SubLine.Enable = true;
+ }
+
+ //播放警告删掉动画
+ if (!Master.SubLine.IsPlayWarnAnimation && aiLockRemainderTime <= 0.5f)
+ {
+ Master.SubLine.PlayWarnAnimation(0.5f);
+ }
+ }
+
+ if (weapon.Attribute.AiAttackAttr.LockingStand) //锁定目标时站立不动
+ {
+ Master.DoIdle();
+ }
+ else //正常移动
+ {
+ MoveHandler(delta);
+ }
+ }
+ else
+ {
+ Master.LockTargetTime = 0;
+ //关闭辅助线
+ if (Master.SubLine != null)
+ {
+ Master.SubLine.Enable = false;
+ }
+
+ if (AttackState == AiAttackEnum.Attack || AttackState == AiAttackEnum.AttackInterval)
+ {
+ if (weapon.Attribute.AiAttackAttr.AttackLockAngle) //开火时锁定枪口角度
+ {
+ //连发状态锁定角度
+ Master.MountLookTarget = !(weapon.GetContinuousCount() > 0 || weapon.GetAttackTimer() > 0);
+ }
+ else
+ {
+ Master.MountLookTarget = true;
+ }
+ }
+ else
+ {
+ Master.MountLookTarget = true;
+ }
+
+ if (AttackState == AiAttackEnum.Attack && weapon.Attribute.AiAttackAttr.FiringStand) //开火时站立不动
+ {
+ Master.DoIdle();
+ }
+ else //正常移动
+ {
+ MoveHandler(delta);
+ }
+
+ if (AttackState == AiAttackEnum.AttackInterval) //触发攻击完成
+ {
+ Master.AttackTimer = weapon.Attribute.TriggerInterval + Master.AttackInterval;
+ }
+ }
+ }
+ }
+
+ //没有武器的敌人攻击逻辑
+ private void NoWeaponRoleProcess(float delta)
+ {
+ var weapon = Master.WeaponPack.ActiveItem;
+ if (weapon != null)
+ {
+ //找到武器了, 攻击结束
+ ChangeState(PrevState);
+ }
+ else if (Master.AttackTimer > 0 || Master.MeleeAttackTimer > 0) //攻击结束
+ {
+ ChangeState(PrevState);
+ }
+ else //攻击状态
+ {
+ Master.Attack();
+ }
+ }
+
+ private void MoveHandler(float delta)
+ {
+
+ if (_pauseTimer >= 0)
+ {
+ Master.AnimatedSprite.Play(AnimatorNames.Idle);
+ _pauseTimer -= delta;
+ }
+ else if (_isMoveOver) //移动已经完成
+ {
+ RunOver(Master.LookTarget.Position);
+ _isMoveOver = false;
+ }
+ else
+ {
+ var masterPosition = Master.Position;
+ if (_lockTimer >= 1) //卡在一个点超过一秒
+ {
+ RunOver(Master.LookTarget.Position);
+ _isMoveOver = false;
+ _lockTimer = 0;
+ }
+ else if (Master.NavigationAgent2D.IsNavigationFinished()) //到达终点
+ {
+ _pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.5f);
+ _isMoveOver = true;
+ _moveFlag = false;
+ //站立
+ Master.DoIdle();
+ }
+ else if (!_moveFlag)
+ {
+ _moveFlag = true;
+ //移动
+ Master.DoMove();
+ }
+ else
+ {
+ var lastSlideCollision = Master.GetLastSlideCollision();
+ if (lastSlideCollision != null && lastSlideCollision.GetCollider() is Role) //碰到其他角色
+ {
+ _pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.3f);
+ _isMoveOver = true;
+ _moveFlag = false;
+ //站立
+ Master.DoIdle();
+ }
+ else
+ {
+ //移动
+ Master.DoMove();
+ }
+
+ if (_prevPos.DistanceSquaredTo(masterPosition) <= 1 * delta)
+ {
+ _lockTimer += delta;
+ }
+ else
+ {
+ _lockTimer = 0;
+ _prevPos = masterPosition;
+ }
+ }
+ }
+ }
+
+ private void RunOver(Vector2 targetPos)
+ {
+ var weapon = Master.WeaponPack.ActiveItem;
+ var distance = (int)(weapon == null ? 150 : (Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange) * 0.7f));
+ _nextPosition = new Vector2(
+ targetPos.X + Utils.Random.RandomRangeInt(-distance, distance),
+ targetPos.Y + Utils.Random.RandomRangeInt(-distance, distance)
+ );
+ Master.NavigationAgent2D.TargetPosition = _nextPosition;
+ }
+
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiFindAmmoState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiFindAmmoState.cs
new file mode 100644
index 0000000..2ebc81e
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiFindAmmoState.cs
@@ -0,0 +1,204 @@
+
+using System;
+using Godot;
+
+namespace AiState;
+
+///
+/// Ai 寻找弹药, 进入该状态需要在参数中传入目标武器对象
+///
+public class AiFindAmmoState : StateBase
+{
+ ///
+ /// 目标武器
+ ///
+ public Weapon TargetWeapon;
+
+ //导航目标点刷新计时器
+ private float _navigationUpdateTimer = 0;
+ private float _navigationInterval = 1f;
+
+ private float _tailAfterTimer = 0;
+ private ActivityObject _attackTarget;
+
+ private float _idleTimer = 0;
+ private bool _playAnimFlag = false;
+
+ public AiFindAmmoState() : base(AIStateEnum.AiFindAmmo)
+ {
+ }
+
+ public override void Enter(AIStateEnum prev, params object[] args)
+ {
+ if (args.Length == 0)
+ {
+ throw new Exception("进入 AiStateEnum.AiFindAmmo 状态必须要把目标武器当成参数传过来");
+ }
+
+ if (args.Length >= 2)
+ {
+ _attackTarget = (ActivityObject)args[1];
+ }
+ else
+ {
+ _attackTarget = null;
+ }
+
+ SetTargetWeapon((Weapon)args[0]);
+ _navigationUpdateTimer = _navigationInterval;
+ _tailAfterTimer = 0;
+
+ //标记武器
+ TargetWeapon.SetSign(SignNames.AiFindWeaponSign, Master);
+
+ _playAnimFlag = prev == AIStateEnum.AiLeaveFor;
+ if (_playAnimFlag)
+ {
+ Master.AnimationPlayer.Play(AnimatorNames.Query);
+ }
+ }
+
+ public override void Process(float delta)
+ {
+ if (_playAnimFlag && _idleTimer > 0)
+ {
+ _idleTimer -= delta;
+ return;
+ }
+
+ if (!Master.IsAllWeaponTotalAmmoEmpty()) //已经有弹药了
+ {
+ RunNextState();
+ return;
+ }
+
+ if (Master.LookTarget == null) //没有目标
+ {
+ //临时处理
+ var player = Player.Current;
+ var playerPos = player.GetCenterPosition();
+ if (Master.IsInViewRange(playerPos) && !Master.TestViewRayCast(playerPos)) //发现玩家
+ {
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ //发现玩家
+ Master.LookTarget = player;
+ //进入惊讶状态, 然后再进入通知状态
+ ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiFindAmmo, TargetWeapon);
+ return;
+ }
+ }
+
+ //更新目标位置
+ if (_navigationUpdateTimer <= 0)
+ {
+ //每隔一段时间秒更改目标位置
+ _navigationUpdateTimer = _navigationInterval;
+ var position = TargetWeapon.GlobalPosition;
+ Master.NavigationAgent2D.TargetPosition = position;
+ }
+ else
+ {
+ _navigationUpdateTimer -= delta;
+ }
+
+ if (TargetWeapon.IsDestroyed || TargetWeapon.IsTotalAmmoEmpty()) //已经被销毁, 或者弹药已经被其他角色捡走
+ {
+ //再去寻找其他武器
+ SetTargetWeapon(Master.FindTargetWeapon());
+
+ if (TargetWeapon == null) //也没有其他可用的武器了
+ {
+ RunNextState();
+ }
+ }
+ else if (TargetWeapon.Master == Master) //已经被自己拾起
+ {
+ RunNextState();
+ }
+ else if (TargetWeapon.Master != null) //武器已经被其他角色拾起!
+ {
+ //再去寻找其他武器
+ SetTargetWeapon(Master.FindTargetWeapon());
+
+ if (TargetWeapon == null) //也没有其他可用的武器了
+ {
+ RunNextState();
+ }
+ }
+ else
+ {
+ if (Master.LookTarget != null)
+ {
+ //检测目标没有超出跟随视野距离
+ var isInTailAfterRange = Master.IsInTailAfterViewRange(Master.LookTarget.GetCenterPosition());
+ if (isInTailAfterRange)
+ {
+ _tailAfterTimer = 0;
+ }
+ else
+ {
+ _tailAfterTimer += delta;
+ }
+ }
+
+ //向武器移动
+ if (!Master.NavigationAgent2D.IsNavigationFinished())
+ {
+ //移动
+ Master.DoMove();
+ }
+ else
+ {
+ //站立
+ Master.DoIdle();
+ }
+ }
+ }
+
+ private void RunNextState()
+ {
+ if (_attackTarget != null)
+ {
+ ChangeState(AIStateEnum.AiLeaveFor, _attackTarget);
+ }
+ else if (Master.LookTarget != null)
+ {
+ ChangeState(_tailAfterTimer > 10 ? AIStateEnum.AiNormal : AIStateEnum.AiTailAfter);
+ }
+ else
+ {
+ ChangeState(AIStateEnum.AiNormal);
+ }
+ }
+
+ private void SetTargetWeapon(Weapon weapon)
+ {
+ TargetWeapon = weapon;
+ if (weapon != null)
+ {
+ //设置目标点
+ Master.NavigationAgent2D.TargetPosition = TargetWeapon.GlobalPosition;
+ }
+ }
+
+ public override void DebugDraw()
+ {
+ if (TargetWeapon != null)
+ {
+ Master.DrawLine(Vector2.Zero, Master.ToLocal(TargetWeapon.GlobalPosition), Colors.Purple);
+
+ if (Master.LookTarget != null)
+ {
+ if (_tailAfterTimer <= 0)
+ {
+ Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.LookTarget.GetCenterPosition()), Colors.Orange);
+ }
+ else if (_tailAfterTimer <= 10)
+ {
+ Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.LookTarget.GetCenterPosition()), Colors.Blue);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiFollowUpState.cs
new file mode 100644
index 0000000..c231a9a
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiFollowUpState.cs
@@ -0,0 +1,147 @@
+
+using System;
+using Godot;
+
+namespace AiState;
+
+///
+/// 目标在视野内, 跟进目标, 如果距离在子弹有效射程内, 则开火
+///
+public class AiFollowUpState : StateBase
+{
+ //导航目标点刷新计时器
+ private float _navigationUpdateTimer = 0;
+ private float _navigationInterval = 0.3f;
+
+ public AiFollowUpState() : base(AIStateEnum.AiFollowUp)
+ {
+ }
+
+ public override void Enter(AIStateEnum prev, params object[] args)
+ {
+ if (Master.LookTarget == null)
+ {
+ throw new Exception("进入 AIAdvancedStateEnum.AiFollowUp 状态时角色没有攻击目标!");
+ }
+
+ _navigationUpdateTimer = 0;
+ Master.TargetInView = true;
+ }
+
+ public override void Process(float delta)
+ {
+ //先检查弹药是否打光
+ if (Master.IsAllWeaponTotalAmmoEmpty())
+ {
+ //再寻找是否有可用的武器
+ var targetWeapon = Master.FindTargetWeapon();
+ if (targetWeapon != null)
+ {
+ ChangeState(AIStateEnum.AiFindAmmo, targetWeapon);
+ return;
+ }
+ else
+ {
+ //切换到随机移动状态
+ ChangeState(AIStateEnum.AiSurround);
+ }
+ }
+
+ var playerPos = Master.LookTarget.GetCenterPosition();
+
+ //更新玩家位置
+ if (_navigationUpdateTimer <= 0)
+ {
+ //每隔一段时间秒更改目标位置
+ _navigationUpdateTimer = _navigationInterval;
+ Master.NavigationAgent2D.TargetPosition = playerPos;
+ }
+ else
+ {
+ _navigationUpdateTimer -= delta;
+ }
+
+ //是否在攻击范围内
+ var inAttackRange = false;
+
+ var weapon = Master.WeaponPack.ActiveItem;
+ var distanceSquared = Master.Position.DistanceSquaredTo(playerPos);
+ if (weapon != null)
+ {
+ inAttackRange = distanceSquared <= Mathf.Pow(Master.GetWeaponRange(0.7f), 2);
+ }
+ else
+ {
+ inAttackRange = distanceSquared <= Mathf.Pow(Master.ViewRange * 0.7f, 2);
+ }
+
+ if (!Master.NavigationAgent2D.IsNavigationFinished())
+ {
+ //移动
+ Master.DoMove();
+ }
+ else
+ {
+ //站立
+ Master.DoIdle();
+ }
+
+ //检测玩家是否在视野内
+ if (Master.IsInTailAfterViewRange(playerPos))
+ {
+ Master.TargetInView = !Master.TestViewRayCast(playerPos);
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ }
+ else
+ {
+ Master.TargetInView = false;
+ }
+
+ //在视野中
+ if (Master.TargetInView)
+ {
+ //更新标记位置
+ Master.UpdateMarkTargetPosition();
+ if (inAttackRange) //在攻击范围内
+ {
+ if (weapon != null)
+ {
+ //距离够近, 可以切换到环绕模式
+ if (distanceSquared <= Mathf.Pow(Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange) * 0.7f, 2))
+ {
+ ChangeState(AIStateEnum.AiSurround);
+ }
+ else if (!Master.IsAttack && weapon.TriggerIsReady()) //可以攻击
+ {
+ //攻击状态
+ ChangeState(AIStateEnum.AiAttack);
+ }
+ }
+ else
+ {
+ //距离够近, 可以切换到环绕模式
+ if (distanceSquared <= Mathf.Pow(Master.ViewRange * 0.7f, 2))
+ {
+ ChangeState(AIStateEnum.AiSurround);
+ }
+ else if (!Master.IsAttack && Master.NoWeaponAttack) //可以在没有武器时发起攻击
+ {
+ //攻击状态
+ ChangeState(AIStateEnum.AiAttack);
+ }
+ }
+ }
+ }
+ else //不在视野中
+ {
+ ChangeState(AIStateEnum.AiTailAfter);
+ }
+ }
+
+ public override void DebugDraw()
+ {
+ var playerPos = Master.LookTarget.GetCenterPosition();
+ Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Red);
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiLeaveForState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiLeaveForState.cs
new file mode 100644
index 0000000..f539df1
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiLeaveForState.cs
@@ -0,0 +1,136 @@
+
+using System;
+using Godot;
+
+namespace AiState;
+
+///
+/// 收到其他敌人通知, 前往发现目标的位置
+///
+public class AiLeaveForState : StateBase
+{
+ //导航目标点刷新计时器
+ private float _navigationUpdateTimer = 0;
+ private float _navigationInterval = 0.3f;
+
+ //目标
+ private ActivityObject _target;
+ //目标点
+ private Vector2 _targetPosition;
+
+ private float _idleTimer = 0;
+ private bool _playAnimFlag = false;
+
+ public AiLeaveForState() : base(AIStateEnum.AiLeaveFor)
+ {
+ }
+
+ public override void Enter(AIStateEnum prev, params object[] args)
+ {
+ if (args.Length == 0)
+ {
+ throw new Exception("进入 AINormalStateEnum.AiLeaveFor 状态必须带上目标对象");
+ }
+
+ _target = (ActivityObject)args[0];
+
+ //先检查弹药是否打光
+ if (Master.IsAllWeaponTotalAmmoEmpty())
+ {
+ //再寻找是否有可用的武器
+ var targetWeapon = Master.FindTargetWeapon();
+ if (targetWeapon != null)
+ {
+ ChangeState(AIStateEnum.AiFindAmmo, targetWeapon, _target);
+ return;
+ }
+ }
+
+ _idleTimer = 1;
+ _targetPosition = _target.GetCenterPosition();
+ Master.LookTargetPosition(_targetPosition);
+
+ _playAnimFlag = prev != AIStateEnum.AiFindAmmo;
+ if (_playAnimFlag)
+ {
+ Master.AnimationPlayer.Play(AnimatorNames.Query);
+ }
+
+ //看向目标位置
+ Master.LookTargetPosition(_target.GetCenterPosition());
+ }
+
+ public override void Exit(AIStateEnum next)
+ {
+ Master.AnimationPlayer.Play(AnimatorNames.Reset);
+ }
+
+ public override void Process(float delta)
+ {
+ if (_playAnimFlag && _idleTimer > 0)
+ {
+ _idleTimer -= delta;
+ return;
+ }
+ //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽
+
+ //更新玩家位置
+ if (_navigationUpdateTimer <= 0)
+ {
+ //每隔一段时间秒更改目标位置
+ _navigationUpdateTimer = _navigationInterval;
+ if (Master.AffiliationArea.RoomInfo.MarkTargetPosition.TryGetValue(_target.Id, out var pos))
+ {
+ _targetPosition = pos;
+ }
+ Master.NavigationAgent2D.TargetPosition = _targetPosition;
+ }
+ else
+ {
+ _navigationUpdateTimer -= delta;
+ }
+
+ if (!Master.NavigationAgent2D.IsNavigationFinished())
+ {
+ Master.LookTargetPosition(_targetPosition);
+ //移动
+ Master.DoMove();
+ }
+ else
+ {
+ //站立
+ Master.DoIdle();
+ }
+
+ var playerPos = Player.Current.GetCenterPosition();
+ //检测玩家是否在视野内, 如果在, 则切换到 AiTargetInView 状态
+ if (Master.IsInTailAfterViewRange(playerPos))
+ {
+ if (!Master.TestViewRayCast(playerPos)) //看到玩家
+ {
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ //切换成发现目标状态
+ Master.LookTarget = Player.Current;
+ ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiFollowUp);
+ return;
+ }
+ else
+ {
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ }
+ }
+
+ //移动到目标掉了, 还没发现目标
+ if (Master.NavigationAgent2D.IsNavigationFinished())
+ {
+ ChangeState(AIStateEnum.AiNormal);
+ }
+ }
+
+ public override void DebugDraw()
+ {
+ Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.NavigationAgent2D.TargetPosition), Colors.Yellow);
+ }
+}
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiNormalState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiNormalState.cs
new file mode 100644
index 0000000..6bcb86d
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiNormalState.cs
@@ -0,0 +1,178 @@
+
+using System.Linq;
+using Godot;
+
+namespace AiState;
+
+///
+/// AI 正常状态
+///
+public class AiNormalState : StateBase
+{
+ //下一个运动的坐标
+ private Vector2 _nextPos;
+
+ //是否移动结束
+ private bool _isMoveOver;
+
+ //上一次移动是否撞墙
+ private bool _againstWall;
+
+ //撞墙法线角度
+ private float _againstWallNormalAngle;
+
+ //移动停顿计时器
+ private float _pauseTimer;
+ private bool _moveFlag;
+
+ //上一帧位置
+ private Vector2 _prevPos;
+ //卡在一个位置的时间
+ private float _lockTimer;
+
+ public AiNormalState() : base(AIStateEnum.AiNormal)
+ {
+ }
+
+ public override void Enter(AIStateEnum prev, params object[] args)
+ {
+ _isMoveOver = true;
+ _againstWall = false;
+ _againstWallNormalAngle = 0;
+ _pauseTimer = 0;
+ _moveFlag = false;
+ Master.LookTarget = null;
+ }
+
+ public override void Process(float delta)
+ {
+ //检测玩家
+ var player = Player.Current;
+ //玩家中心点坐标
+ var playerPos = player.GetCenterPosition();
+
+ if (Master.IsInViewRange(playerPos) && !Master.TestViewRayCast(playerPos)) //发现玩家
+ {
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ //发现玩家
+ Master.LookTarget = player;
+ //判断是否进入通知状态
+ if (Master.World.Enemy_InstanceList.FindIndex(enemy =>
+ enemy != Master && !enemy.IsDie && enemy.AffiliationArea == Master.AffiliationArea &&
+ enemy.StateController.CurrState == AIStateEnum.AiNormal) != -1)
+ {
+ //进入惊讶状态, 然后再进入通知状态
+ ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiNotify);
+ }
+ else
+ {
+ //进入惊讶状态, 然后再进入跟随状态
+ ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiTailAfter);
+ }
+ return;
+ }
+ else if (_pauseTimer >= 0)
+ {
+ Master.AnimatedSprite.Play(AnimatorNames.Idle);
+ _pauseTimer -= delta;
+ }
+ else if (_isMoveOver) //没发现玩家, 且已经移动完成
+ {
+ RunOver();
+ _isMoveOver = false;
+ }
+ else //移动中
+ {
+ if (_lockTimer >= 1) //卡在一个点超过一秒
+ {
+ RunOver();
+ _isMoveOver = false;
+ _lockTimer = 0;
+ }
+ else if (Master.NavigationAgent2D.IsNavigationFinished()) //到达终点
+ {
+ _pauseTimer = Utils.Random.RandomRangeFloat(0.3f, 2f);
+ _isMoveOver = true;
+ _moveFlag = false;
+ //站立
+ Master.DoIdle();
+ }
+ else if (!_moveFlag)
+ {
+ _moveFlag = true;
+ var pos = Master.Position;
+ //移动
+ Master.DoMove();
+ _prevPos = pos;
+ }
+ else
+ {
+ var pos = Master.Position;
+ var lastSlideCollision = Master.GetLastSlideCollision();
+ if (lastSlideCollision != null && lastSlideCollision.GetCollider() is Role) //碰到其他角色
+ {
+ _pauseTimer = Utils.Random.RandomRangeFloat(0.1f, 0.5f);
+ _isMoveOver = true;
+ _moveFlag = false;
+ //站立
+ Master.DoIdle();
+ }
+ else
+ {
+ //移动
+ Master.DoMove();
+ }
+
+ if (_prevPos.DistanceSquaredTo(pos) <= 0.01f)
+ {
+ _lockTimer += delta;
+ }
+ else
+ {
+ _prevPos = pos;
+ }
+ }
+ }
+
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ }
+
+ //移动结束
+ private void RunOver()
+ {
+ float angle;
+ if (_againstWall)
+ {
+ angle = Utils.Random.RandomRangeFloat(_againstWallNormalAngle - Mathf.Pi * 0.5f,
+ _againstWallNormalAngle + Mathf.Pi * 0.5f);
+ }
+ else
+ {
+ angle = Utils.Random.RandomRangeFloat(0, Mathf.Pi * 2f);
+ }
+
+ var len = Utils.Random.RandomRangeInt(30, 200);
+ _nextPos = new Vector2(len, 0).Rotated(angle) + Master.GlobalPosition;
+ //获取射线碰到的坐标
+ if (Master.TestViewRayCast(_nextPos)) //碰到墙壁
+ {
+ _nextPos = Master.ViewRay.GetCollisionPoint();
+ _againstWall = true;
+ _againstWallNormalAngle = Master.ViewRay.GetCollisionNormal().Angle();
+ }
+ else
+ {
+ _againstWall = false;
+ }
+
+ Master.NavigationAgent2D.TargetPosition = _nextPos;
+ Master.LookTargetPosition(_nextPos);
+ }
+
+ public override void DebugDraw()
+ {
+ Master.DrawLine(new Vector2(0, -8), Master.ToLocal(_nextPos), Colors.Green);
+ }
+}
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiNotifyState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiNotifyState.cs
new file mode 100644
index 0000000..22726f1
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiNotifyState.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace AiState;
+
+///
+/// 发现目标, 通知其它敌人
+///
+public class AiNotifyState : StateBase
+{
+ private float _timer;
+
+ public AiNotifyState() : base(AIStateEnum.AiNotify)
+ {
+ }
+
+ public override void Enter(AIStateEnum prev, params object[] args)
+ {
+ if (Master.LookTarget == null)
+ {
+ throw new Exception("进入 AIAdvancedStateEnum.AiNotify 没有攻击目标!");
+ }
+ _timer = 1.2f;
+ //通知其它角色
+ Master.World.NotifyEnemyTarget(Master, Master.LookTarget);
+ Master.AnimationPlayer.Play(AnimatorNames.Notify);
+ }
+
+ public override void Process(float delta)
+ {
+ Master.DoIdle();
+ _timer -= delta;
+ if (_timer <= 0)
+ {
+ ChangeState(AIStateEnum.AiTailAfter);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiSurroundState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiSurroundState.cs
new file mode 100644
index 0000000..94afce7
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiSurroundState.cs
@@ -0,0 +1,187 @@
+
+using System;
+using Godot;
+
+namespace AiState;
+
+///
+/// 距离目标足够近, 在目标附近随机移动, 并开火
+///
+public class AiSurroundState : StateBase
+{
+ //是否移动结束
+ private bool _isMoveOver;
+
+ //移动停顿计时器
+ private float _pauseTimer;
+ private bool _moveFlag;
+
+ //下一个移动点
+ private Vector2 _nextPosition;
+
+ //上一帧位置
+ private Vector2 _prevPos;
+ //卡在一个位置的时间
+ private float _lockTimer;
+
+ public AiSurroundState() : base(AIStateEnum.AiSurround)
+ {
+ }
+
+ public override void Enter(AIStateEnum prev, params object[] args)
+ {
+ if (Master.LookTarget == null)
+ {
+ throw new Exception("进入 AIAdvancedStateEnum.AiSurround 状态时角色没有攻击目标!");
+ }
+
+ Master.TargetInView = true;
+ _isMoveOver = true;
+ _pauseTimer = 0;
+ _moveFlag = false;
+ }
+
+ public override void Process(float delta)
+ {
+ //先检查弹药是否打光
+ if (Master.IsAllWeaponTotalAmmoEmpty())
+ {
+ //再寻找是否有可用的武器
+ var targetWeapon = Master.FindTargetWeapon();
+ if (targetWeapon != null)
+ {
+ ChangeState(AIStateEnum.AiFindAmmo, targetWeapon);
+ return;
+ }
+ }
+
+ var playerPos = Master.LookTarget.GetCenterPosition();
+
+ //检测玩家是否在视野内
+ if (Master.IsInTailAfterViewRange(playerPos))
+ {
+ Master.TargetInView = !Master.TestViewRayCast(playerPos);
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ }
+ else
+ {
+ Master.TargetInView = false;
+ }
+
+ //在视野中
+ if (Master.TargetInView)
+ {
+ //更新标记位置
+ Master.UpdateMarkTargetPosition();
+
+ if (_pauseTimer >= 0)
+ {
+ Master.AnimatedSprite.Play(AnimatorNames.Idle);
+ _pauseTimer -= delta;
+ }
+ else if (_isMoveOver) //移动已经完成
+ {
+ RunOver(playerPos);
+ _isMoveOver = false;
+ }
+ else
+ {
+ var masterPosition = Master.Position;
+ if (_lockTimer >= 1) //卡在一个点超过一秒
+ {
+ RunOver(playerPos);
+ _isMoveOver = false;
+ _lockTimer = 0;
+ }
+ else if (Master.NavigationAgent2D.IsNavigationFinished()) //到达终点
+ {
+ _pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.5f);
+ _isMoveOver = true;
+ _moveFlag = false;
+ //站立
+ Master.DoIdle();
+ }
+ else if (!_moveFlag)
+ {
+ _moveFlag = true;
+ //移动
+ Master.DoMove();
+ }
+ else
+ {
+ var lastSlideCollision = Master.GetLastSlideCollision();
+ if (lastSlideCollision != null && lastSlideCollision.GetCollider() is Role) //碰到其他角色
+ {
+ _pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.3f);
+ _isMoveOver = true;
+ _moveFlag = false;
+ //站立
+ Master.DoIdle();
+ }
+ else
+ {
+ //移动
+ Master.DoMove();
+ }
+
+ if (_prevPos.DistanceSquaredTo(masterPosition) <= 1 * delta)
+ {
+ _lockTimer += delta;
+ }
+ else
+ {
+ _lockTimer = 0;
+ _prevPos = masterPosition;
+ }
+ }
+
+ var weapon = Master.WeaponPack.ActiveItem;
+ if (weapon != null)
+ {
+ if (masterPosition.DistanceSquaredTo(playerPos) > Mathf.Pow(Master.GetWeaponRange(0.7f), 2)) //玩家离开正常射击范围
+ {
+ ChangeState(AIStateEnum.AiFollowUp);
+ }
+ else if (!Master.IsAttack && weapon.TriggerIsReady()) //可以攻击
+ {
+ //发起攻击
+ ChangeState(AIStateEnum.AiAttack);
+ }
+ }
+ else
+ {
+ if (masterPosition.DistanceSquaredTo(playerPos) > Mathf.Pow(Master.ViewRange * 0.7f, 2)) //玩家离开正常射击范围
+ {
+ ChangeState(AIStateEnum.AiFollowUp);
+ }
+ else if (!Master.IsAttack && Master.NoWeaponAttack) //可以在没有武器时发起攻击
+ {
+ //攻击状态
+ ChangeState(AIStateEnum.AiAttack);
+ }
+ }
+ }
+ }
+ else //目标离开视野
+ {
+ ChangeState(AIStateEnum.AiTailAfter);
+ }
+ }
+
+ private void RunOver(Vector2 targetPos)
+ {
+ var weapon = Master.WeaponPack.ActiveItem;
+ var distance = (int)(weapon == null ? 150 : (Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange) * 0.7f));
+ _nextPosition = new Vector2(
+ targetPos.X + Utils.Random.RandomRangeInt(-distance, distance),
+ targetPos.Y + Utils.Random.RandomRangeInt(-distance, distance)
+ );
+ Master.NavigationAgent2D.TargetPosition = _nextPosition;
+ }
+
+ public override void DebugDraw()
+ {
+ Master.DrawLine(new Vector2(0, -8), Master.ToLocal(_nextPosition), Colors.White);
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/ai/state/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiTailAfterState.cs
new file mode 100644
index 0000000..05a5d9e
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/ai/state/AiTailAfterState.cs
@@ -0,0 +1,128 @@
+
+using System;
+using Godot;
+
+namespace AiState;
+
+///
+/// AI 发现玩家, 跟随玩家, 但是不在视野范围内
+///
+public class AiTailAfterState : StateBase
+{
+ ///
+ /// 目标是否在视野半径内
+ ///
+ private bool _isInViewRange;
+
+ //导航目标点刷新计时器
+ private float _navigationUpdateTimer = 0;
+ private float _navigationInterval = 0.3f;
+
+ //目标从视野消失时已经过去的时间
+ private float _viewTimer;
+
+ public AiTailAfterState() : base(AIStateEnum.AiTailAfter)
+ {
+ }
+
+ public override void Enter(AIStateEnum prev, params object[] args)
+ {
+ if (Master.LookTarget == null)
+ {
+ throw new Exception("进入 AIAdvancedStateEnum.AiTailAfter 状态时角色没有攻击目标!");
+ }
+
+ _isInViewRange = true;
+ _navigationUpdateTimer = 0;
+ _viewTimer = 0;
+
+ //先检查弹药是否打光
+ if (Master.IsAllWeaponTotalAmmoEmpty())
+ {
+ //再寻找是否有可用的武器
+ var targetWeapon = Master.FindTargetWeapon();
+ if (targetWeapon != null)
+ {
+ ChangeState(AIStateEnum.AiFindAmmo, targetWeapon);
+ }
+ }
+ }
+
+ public override void Process(float delta)
+ {
+ //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽
+
+ var playerPos = Master.LookTarget.GetCenterPosition();
+
+ //更新玩家位置
+ if (_navigationUpdateTimer <= 0)
+ {
+ //每隔一段时间秒更改目标位置
+ _navigationUpdateTimer = _navigationInterval;
+ Master.NavigationAgent2D.TargetPosition = playerPos;
+ }
+ else
+ {
+ _navigationUpdateTimer -= delta;
+ }
+
+ if (!Master.NavigationAgent2D.IsNavigationFinished())
+ {
+ //移动
+ Master.DoMove();
+ }
+ else
+ {
+ //站立
+ Master.DoIdle();
+ }
+ //检测玩家是否在视野内, 如果在, 则切换到 AiTargetInView 状态
+ if (Master.IsInTailAfterViewRange(playerPos))
+ {
+ if (!Master.TestViewRayCast(playerPos)) //看到玩家
+ {
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ //切换成发现目标状态
+ ChangeState(AIStateEnum.AiFollowUp);
+ return;
+ }
+ else
+ {
+ //关闭射线检测
+ Master.TestViewRayCastOver();
+ }
+ }
+
+ //检测玩家是否在穿墙视野范围内, 直接检测距离即可
+ _isInViewRange = Master.IsInViewRange(playerPos);
+ if (_isInViewRange)
+ {
+ _viewTimer = 0;
+ }
+ else //超出视野
+ {
+ if (_viewTimer > 10) //10秒
+ {
+ ChangeState(AIStateEnum.AiNormal);
+ }
+ else
+ {
+ _viewTimer += delta;
+ }
+ }
+ }
+
+ public override void DebugDraw()
+ {
+ var playerPos = Master.LookTarget.GetCenterPosition();
+ if (_isInViewRange)
+ {
+ Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Orange);
+ }
+ else
+ {
+ Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Blue);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
index 33bf27b..b18d1e3 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs
@@ -2,70 +2,16 @@
using System;
using System.Collections.Generic;
using Config;
-using EnemyState;
+using AiState;
using Godot;
///
-/// 高级敌人,可以携带武器
+/// 敌人,可以携带武器
///
[Tool]
-public partial class Enemy : Role
+public partial class Enemy : AiRole
{
///
- /// 目标是否在视野内
- ///
- public bool TargetInView { get; set; } = true;
-
- ///
- /// 敌人身上的状态机控制器
- ///
- public StateController StateController { get; private set; }
-
- ///
- /// 视野检测射线, 朝玩家打射线, 检测是否碰到墙
- ///
- [Export, ExportFillNode]
- public RayCast2D ViewRay { get; set; }
-
- ///
- /// 导航代理
- ///
- [Export, ExportFillNode]
- public NavigationAgent2D NavigationAgent2D { get; set; }
-
- ///
- /// 导航代理中点
- ///
- [Export, ExportFillNode]
- public Marker2D NavigationPoint { get; set; }
-
- ///
- /// 不通过武发射子弹的开火点
- ///
- [Export, ExportFillNode]
- public Marker2D FirePoint { get; set; }
-
- ///
- /// 当前敌人所看向的对象, 也就是枪口指向的对象
- ///
- public ActivityObject LookTarget { get; set; }
-
- ///
- /// 攻击锁定目标时间
- ///
- public float LockingTime { get; set; } = 1f;
-
- ///
- /// 锁定目标已经走过的时间
- ///
- public float LockTargetTime { get; set; } = 0;
-
- ///
- /// 敌人属性
- ///
- public EnemyRoleState EnemyRoleState { get; private set; }
-
- ///
/// 敌人属性
///
private ExcelConfig.EnemyBase _enemyAttribute;
@@ -117,10 +63,6 @@
public override void OnInit()
{
base.OnInit();
-
- IsAi = true;
-
- StateController = AddComponent>();
AttackLayer = PhysicsLayer.Obstacle | PhysicsLayer.Player;
EnemyLayer = PhysicsLayer.Player;
@@ -130,28 +72,11 @@
MaxHp = 20;
Hp = 20;
-
- //注册Ai状态机
- StateController.Register(new AiNormalState());
- StateController.Register(new AiTailAfterState());
- StateController.Register(new AiFollowUpState());
- StateController.Register(new AiLeaveForState());
- StateController.Register(new AiSurroundState());
- StateController.Register(new AiFindAmmoState());
- StateController.Register(new AiAttackState());
- StateController.Register(new AiAstonishedState());
- StateController.Register(new AiNotifyState());
-
- //默认状态
- StateController.ChangeStateInstant(AIStateEnum.AiNormal);
-
- //NavigationAgent2D.VelocityComputed += OnVelocityComputed;
}
protected override RoleState OnCreateRoleState()
{
- var roleState = new EnemyRoleState();
- EnemyRoleState = roleState;
+ var roleState = new RoleState();
var enemyBase = GetEnemyAttribute(ActivityBase.Id).Clone();
_enemyAttribute = enemyBase;
@@ -161,10 +86,10 @@
roleState.MoveSpeed = enemyBase.MoveSpeed;
roleState.Acceleration = enemyBase.Acceleration;
roleState.Friction = enemyBase.Friction;
- roleState.ViewRange = enemyBase.ViewRange;
- roleState.TailAfterViewRange = enemyBase.TailAfterViewRange;
- roleState.BackViewRange = enemyBase.BackViewRange;
- roleState.AttackInterval = enemyBase.AttackInterval;
+ ViewRange = enemyBase.ViewRange;
+ TailAfterViewRange = enemyBase.TailAfterViewRange;
+ BackViewRange = enemyBase.BackViewRange;
+ AttackInterval = enemyBase.AttackInterval;
roleState.Gold = Mathf.Max(0, Utils.Random.RandomConfigRange(enemyBase.Gold));
return roleState;
@@ -206,11 +131,12 @@
}
//创建金币
- CreateGold();
+ Gold.CreateGold(Position, RoleState.Gold);
//派发敌人死亡信号
EventManager.EmitEvent(EventEnum.OnEnemyDie, this);
Destroy();
+
}
protected override void Process(float delta)
@@ -240,28 +166,10 @@
MountPoint.SetLookAt(pos);
}
- if (EnemyRoleState.CanPickUpWeapon)
+ if (RoleState.CanPickUpWeapon)
{
//拾起武器操作
- EnemyPickUpWeapon();
- }
- }
-
- ///
- /// 创建散落的金币
- ///
- protected void CreateGold()
- {
- var goldList = Utils.GetGoldList(RoleState.Gold);
- foreach (var id in goldList)
- {
- var o = ObjectManager.GetActivityObject(id);
- o.Position = Position;
- o.Throw(0,
- Utils.Random.RandomRangeInt(50, 110),
- new Vector2(Utils.Random.RandomRangeInt(-20, 20), Utils.Random.RandomRangeInt(-20, 20)),
- 0
- );
+ DoPickUpWeapon();
}
}
@@ -312,276 +220,6 @@
}
///
- /// 返回地上的武器是否有可以拾取的, 也包含没有被其他敌人标记的武器
- ///
- public bool CheckUsableWeaponInUnclaimed()
- {
- foreach (var unclaimedWeapon in World.Weapon_UnclaimedWeapons)
- {
- //判断是否能拾起武器, 条件: 相同的房间
- if (unclaimedWeapon.AffiliationArea == AffiliationArea)
- {
- if (!unclaimedWeapon.IsTotalAmmoEmpty())
- {
- if (!unclaimedWeapon.HasSign(SignNames.AiFindWeaponSign))
- {
- return true;
- }
- else
- {
- //判断是否可以移除该标记
- var enemy = unclaimedWeapon.GetSign(SignNames.AiFindWeaponSign);
- if (enemy == null || enemy.IsDestroyed) //标记当前武器的敌人已经被销毁
- {
- unclaimedWeapon.RemoveSign(SignNames.AiFindWeaponSign);
- return true;
- }
- else if (!enemy.IsAllWeaponTotalAmmoEmpty()) //标记当前武器的敌人已经有新的武器了
- {
- unclaimedWeapon.RemoveSign(SignNames.AiFindWeaponSign);
- return true;
- }
- }
- }
- }
- }
-
- return false;
- }
-
- ///
- /// 寻找可用的武器
- ///
- public Weapon FindTargetWeapon()
- {
- Weapon target = null;
- var position = Position;
- foreach (var weapon in World.Weapon_UnclaimedWeapons)
- {
- //判断是否能拾起武器, 条件: 相同的房间, 或者当前房间目前没有战斗, 或者不在战斗房间
- if (weapon.AffiliationArea == AffiliationArea)
- {
- //还有弹药
- if (!weapon.IsTotalAmmoEmpty())
- {
- //查询是否有其他敌人标记要拾起该武器
- if (weapon.HasSign(SignNames.AiFindWeaponSign))
- {
- var enemy = weapon.GetSign(SignNames.AiFindWeaponSign);
- if (enemy == this) //就是自己标记的
- {
-
- }
- else if (enemy == null || enemy.IsDestroyed) //标记当前武器的敌人已经被销毁
- {
- weapon.RemoveSign(SignNames.AiFindWeaponSign);
- }
- else if (!enemy.IsAllWeaponTotalAmmoEmpty()) //标记当前武器的敌人已经有新的武器了
- {
- weapon.RemoveSign(SignNames.AiFindWeaponSign);
- }
- else //放弃这把武器
- {
- continue;
- }
- }
-
- if (target == null) //第一把武器
- {
- target = weapon;
- }
- else if (target.Position.DistanceSquaredTo(position) >
- weapon.Position.DistanceSquaredTo(position)) //距离更近
- {
- target = weapon;
- }
- }
- }
- }
-
- return target;
- }
-
- ///
- /// 获取武器攻击范围 (最大距离值与最小距离的中间值)
- ///
- /// 从最小到最大距离的过渡量, 0 - 1, 默认 0.5
- public float GetWeaponRange(float weight = 0.5f)
- {
- if (WeaponPack.ActiveItem != null)
- {
- var attribute = WeaponPack.ActiveItem.Attribute;
- return Mathf.Lerp(Utils.GetConfigRangeStart(attribute.Bullet.DistanceRange), Utils.GetConfigRangeEnd(attribute.Bullet.DistanceRange), weight);
- }
-
- return 0;
- }
-
- ///
- /// 返回目标点是否在视野范围内
- ///
- public bool IsInViewRange(Vector2 target)
- {
- var isForward = IsPositionInForward(target);
- if (isForward)
- {
- if (GlobalPosition.DistanceSquaredTo(target) <= EnemyRoleState.ViewRange * EnemyRoleState.ViewRange) //没有超出视野半径
- {
- return true;
- }
- }
-
- return false;
- }
-
- ///
- /// 返回目标点是否在跟随状态下的视野半径内
- ///
- public bool IsInTailAfterViewRange(Vector2 target)
- {
- var isForward = IsPositionInForward(target);
- if (isForward)
- {
- if (GlobalPosition.DistanceSquaredTo(target) <= EnemyRoleState.TailAfterViewRange * EnemyRoleState.TailAfterViewRange) //没有超出视野半径
- {
- return true;
- }
- }
-
- return false;
- }
-
- ///
- /// 调用视野检测, 如果被墙壁和其它物体遮挡, 则返回true
- ///
- public bool TestViewRayCast(Vector2 target)
- {
- ViewRay.Enabled = true;
- ViewRay.TargetPosition = ViewRay.ToLocal(target);
- ViewRay.ForceRaycastUpdate();
- return ViewRay.IsColliding();
- }
-
- ///
- /// 调用视野检测完毕后, 需要调用 TestViewRayCastOver() 来关闭视野检测射线
- ///
- public void TestViewRayCastOver()
- {
- ViewRay.Enabled = false;
- }
-
- ///
- /// AI 拾起武器操作
- ///
- private void EnemyPickUpWeapon()
- {
- //这几个状态不需要主动拾起武器操作
- var state = StateController.CurrState;
- if (state == AIStateEnum.AiNormal || state == AIStateEnum.AiNotify || state == AIStateEnum.AiAstonished || state == AIStateEnum.AiAttack)
- {
- return;
- }
-
- //拾起地上的武器
- if (InteractiveItem is Weapon weapon)
- {
- if (WeaponPack.ActiveItem == null) //手上没有武器, 无论如何也要拾起
- {
- TriggerInteractive();
- return;
- }
-
- //没弹药了
- if (weapon.IsTotalAmmoEmpty())
- {
- return;
- }
-
- var index = WeaponPack.FindIndex((we, i) => we.ActivityBase.Id == weapon.ActivityBase.Id);
- if (index != -1) //与武器背包中武器类型相同, 补充子弹
- {
- if (!WeaponPack.GetItem(index).IsAmmoFull())
- {
- TriggerInteractive();
- }
-
- return;
- }
-
- // var index2 = Holster.FindWeapon((we, i) =>
- // we.Attribute.WeightType == weapon.Attribute.WeightType && we.IsTotalAmmoEmpty());
- var index2 = WeaponPack.FindIndex((we, i) => we.IsTotalAmmoEmpty());
- if (index2 != -1) //扔掉没子弹的武器
- {
- ThrowWeapon(index2);
- TriggerInteractive();
- return;
- }
-
- // if (Holster.HasVacancy()) //有空位, 拾起武器
- // {
- // TriggerInteractive();
- // return;
- // }
- }
- }
-
- ///
- /// 获取锁定目标的剩余时间
- ///
- public float GetLockRemainderTime()
- {
- var weapon = WeaponPack.ActiveItem;
- if (weapon == null)
- {
- return LockingTime - LockTargetTime;
- }
- return weapon.Attribute.AiAttackAttr.LockingTime - LockTargetTime;
- }
-
- public override void LookTargetPosition(Vector2 pos)
- {
- LookTarget = null;
- base.LookTargetPosition(pos);
- }
-
- ///
- /// 执行移动操作
- ///
- public void DoMove()
- {
- // //计算移动
- // NavigationAgent2D.MaxSpeed = EnemyRoleState.MoveSpeed;
- // var nextPos = NavigationAgent2D.GetNextPathPosition();
- // NavigationAgent2D.Velocity = (nextPos - Position - NavigationPoint.Position).Normalized() * RoleState.MoveSpeed;
-
- AnimatedSprite.Play(AnimatorNames.Run);
- //计算移动
- var nextPos = NavigationAgent2D.GetNextPathPosition();
- BasisVelocity = (nextPos - Position - NavigationPoint.Position).Normalized() * RoleState.MoveSpeed;
- }
-
- ///
- /// 执行站立操作
- ///
- public void DoIdle()
- {
- AnimatedSprite.Play(AnimatorNames.Idle);
- BasisVelocity = Vector2.Zero;
- }
-
- ///
- /// 更新房间中标记的目标位置
- ///
- public void UpdateMarkTargetPosition()
- {
- if (LookTarget != null)
- {
- AffiliationArea.RoomInfo.MarkTargetPosition[LookTarget.Id] = LookTarget.Position;
- }
- }
-
- ///
/// 从标记出生时调用, 预加载波不会调用
///
public virtual void OnBornFromMark()
@@ -590,13 +228,4 @@
StateController.Enable = false;
this.CallDelay(0.7f, () => StateController.Enable = true);
}
-
- // private void OnVelocityComputed(Vector2 velocity)
- // {
- // if (Mathf.Abs(velocity.X) >= 0.01f && Mathf.Abs(velocity.Y) >= 0.01f)
- // {
- // AnimatedSprite.Play(AnimatorNames.Run);
- // BasisVelocity = velocity;
- // }
- // }
}
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/EnemyRoleState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/EnemyRoleState.cs
deleted file mode 100644
index ef3618a..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/EnemyRoleState.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-
-public class EnemyRoleState : RoleState
-{
- ///
- /// 视野半径, 单位像素, 发现玩家后改视野范围可以穿墙
- ///
- public float ViewRange = 250;
-
- ///
- /// 发现玩家后跟随玩家的视野半径
- ///
- public float TailAfterViewRange = 400;
-
- ///
- /// 背后的视野半径, 单位像素
- ///
- public float BackViewRange = 50;
-
- ///
- /// 攻击间隔时间, 秒
- ///
- public float AttackInterval = 0;
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs
index ed3d271..89d9ccc 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs
@@ -71,7 +71,7 @@
debris.BrushPrevPosition = BrushPrevPosition;
//创建金币
- CreateGold();
+ Gold.CreateGold(Position, RoleState.Gold);
//派发敌人死亡信号
EventManager.EmitEvent(EventEnum.OnEnemyDie, this);
@@ -82,7 +82,7 @@
{
if (name == AnimatorNames.Attack)
{
- AttackTimer = EnemyRoleState.AttackInterval;
+ AttackTimer = AttackInterval;
}
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiAstonishedState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiAstonishedState.cs
deleted file mode 100644
index c39aff9..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiAstonishedState.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using Godot;
-
-namespace EnemyState;
-
-///
-/// 发现目标时的惊讶状态
-///
-public class AiAstonishedState : StateBase
-{
- ///
- /// 下一个状态
- ///
- public AIStateEnum NextState;
-
- private float _timer;
- private object[] _args;
-
- public AiAstonishedState() : base(AIStateEnum.AiAstonished)
- {
- }
-
- public override void Enter(AIStateEnum prev, params object[] args)
- {
- if (args.Length == 0)
- {
- Debug.Log("进入 AINormalStateEnum.AiAstonished 状态必传入下一个状态做完参数!");
- ChangeState(prev);
- return;
- }
-
- _args = args;
-
- NextState = (AIStateEnum)args[0];
- _timer = 0.6f;
-
- //播放惊讶表情
- Master.AnimationPlayer.Play(AnimatorNames.Astonished);
- }
-
- public override void Process(float delta)
- {
- Master.DoIdle();
- _timer -= delta;
- if (_timer <= 0)
- {
- if (_args.Length == 1)
- {
- ChangeState(NextState);
- }
- else if (_args.Length == 2)
- {
- ChangeState(NextState, _args[1]);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiAttackState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiAttackState.cs
deleted file mode 100644
index ca847b3..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiAttackState.cs
+++ /dev/null
@@ -1,314 +0,0 @@
-using System;
-using Godot;
-
-namespace EnemyState;
-
-///
-/// ai 攻击状态
-///
-public class AiAttackState : StateBase
-{
- ///
- /// 上一个状态
- ///
- public AIStateEnum PrevState;
-
- ///
- /// 武器攻击状态
- ///
- public AiAttackEnum AttackState;
-
- //是否移动结束
- private bool _isMoveOver;
-
- //移动停顿计时器
- private float _pauseTimer;
- private bool _moveFlag;
-
- //下一个移动点
- private Vector2 _nextPosition;
-
- //上一帧位置
- private Vector2 _prevPos;
- //卡在一个位置的时间
- private float _lockTimer;
- //进入状态的时候是否有武器
- private bool _hasWeapon = true;
-
- public AiAttackState() : base(AIStateEnum.AiAttack)
- {
- }
-
- public override void Enter(AIStateEnum prev, params object[] args)
- {
- if (Master.LookTarget == null)
- {
- throw new Exception("进入 AIAdvancedStateEnum.AiAttack 状态时角色没有攻击目标!");
- }
-
- var weapon = Master.WeaponPack.ActiveItem;
-
- if (weapon != null)
- {
- _hasWeapon = true;
- if (Master.IsAttack || !weapon.TriggerIsReady())
- {
- throw new Exception("进入 AIAdvancedStateEnum.AiAttack 状态时角色武器还无法触动扳机!");
- }
- }
- else
- {
- _hasWeapon = false;
- if (Master.IsAttack)
- {
- throw new Exception("进入 AIAdvancedStateEnum.AiAttack 状态时角色攻击状态还没准备好");
- }
- }
-
- Master.BasisVelocity = Vector2.Zero;
- AttackState = AiAttackEnum.None;
- Master.LockTargetTime = 0;
- PrevState = prev;
-
- _isMoveOver = true;
- _pauseTimer = 0;
- _moveFlag = false;
- }
-
- public override void Exit(AIStateEnum next)
- {
- Master.MountLookTarget = true;
- Master.LockTargetTime = 0;
- }
-
- public override void Process(float delta)
- {
- //更新标记位置
- Master.UpdateMarkTargetPosition();
-
- if (_hasWeapon)
- {
- WeaponRoleProcess(delta);
- }
- else
- {
- NoWeaponRoleProcess(delta);
- }
- }
-
- //有武器的敌人更新逻辑
- private void WeaponRoleProcess(float delta)
- {
- var weapon = Master.WeaponPack.ActiveItem;
- if (weapon == null)
- {
- //攻击结束
- ChangeState(PrevState);
- }
- else if (AttackState == AiAttackEnum.AttackInterval) //攻击完成
- {
- if (weapon.GetAttackTimer() <= 0) //攻击冷却完成
- {
- Master.MountLookTarget = true;
- //这里要做换弹判断, 还有上膛判断
- if (weapon.CurrAmmo <= 0) //换弹判断
- {
- if (!weapon.Reloading)
- {
- weapon.Reload();
- }
- }
- else if (weapon.GetBeLoadedStateState() != 2) //上膛
- {
- if (weapon.GetBeLoadedStateState() == 0)
- {
- weapon.BeLoaded();
- }
- }
- else
- {
- //攻击结束
- ChangeState(PrevState);
- }
- }
- MoveHandler(delta);
- }
- else //攻击状态
- {
- //触发扳机
- AttackState = weapon.AiTriggerAttackState(AttackState);
-
- if (AttackState == AiAttackEnum.LockingTime) //锁定玩家状态
- {
- Master.LockTargetTime += delta;
-
- var aiLockRemainderTime = Master.GetLockRemainderTime();
- Master.MountLookTarget = aiLockRemainderTime >= weapon.Attribute.AiAttackAttr.LockAngleTime;
- //更新瞄准辅助线
- if (weapon.Attribute.AiAttackAttr.ShowSubline)
- {
- if (Master.SubLine == null)
- {
- Master.InitSubLine();
- }
- else
- {
- Master.SubLine.Enable = true;
- }
-
- //播放警告删掉动画
- if (!Master.SubLine.IsPlayWarnAnimation && aiLockRemainderTime <= 0.5f)
- {
- Master.SubLine.PlayWarnAnimation(0.5f);
- }
- }
-
- if (weapon.Attribute.AiAttackAttr.LockingStand) //锁定目标时站立不动
- {
- Master.DoIdle();
- }
- else //正常移动
- {
- MoveHandler(delta);
- }
- }
- else
- {
- Master.LockTargetTime = 0;
- //关闭辅助线
- if (Master.SubLine != null)
- {
- Master.SubLine.Enable = false;
- }
-
- if (AttackState == AiAttackEnum.Attack || AttackState == AiAttackEnum.AttackInterval)
- {
- if (weapon.Attribute.AiAttackAttr.AttackLockAngle) //开火时锁定枪口角度
- {
- //连发状态锁定角度
- Master.MountLookTarget = !(weapon.GetContinuousCount() > 0 || weapon.GetAttackTimer() > 0);
- }
- else
- {
- Master.MountLookTarget = true;
- }
- }
- else
- {
- Master.MountLookTarget = true;
- }
-
- if (AttackState == AiAttackEnum.Attack && weapon.Attribute.AiAttackAttr.FiringStand) //开火时站立不动
- {
- Master.DoIdle();
- }
- else //正常移动
- {
- MoveHandler(delta);
- }
-
- if (AttackState == AiAttackEnum.AttackInterval) //触发攻击完成
- {
- Master.AttackTimer = weapon.Attribute.TriggerInterval + Master.EnemyRoleState.AttackInterval;
- }
- }
- }
- }
-
- //没有武器的敌人攻击逻辑
- private void NoWeaponRoleProcess(float delta)
- {
- var weapon = Master.WeaponPack.ActiveItem;
- if (weapon != null)
- {
- //找到武器了, 攻击结束
- ChangeState(PrevState);
- }
- else if (Master.AttackTimer > 0 || Master.MeleeAttackTimer > 0) //攻击结束
- {
- ChangeState(PrevState);
- }
- else //攻击状态
- {
- Master.Attack();
- }
- }
-
- private void MoveHandler(float delta)
- {
-
- if (_pauseTimer >= 0)
- {
- Master.AnimatedSprite.Play(AnimatorNames.Idle);
- _pauseTimer -= delta;
- }
- else if (_isMoveOver) //移动已经完成
- {
- RunOver(Master.LookTarget.Position);
- _isMoveOver = false;
- }
- else
- {
- var masterPosition = Master.Position;
- if (_lockTimer >= 1) //卡在一个点超过一秒
- {
- RunOver(Master.LookTarget.Position);
- _isMoveOver = false;
- _lockTimer = 0;
- }
- else if (Master.NavigationAgent2D.IsNavigationFinished()) //到达终点
- {
- _pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.5f);
- _isMoveOver = true;
- _moveFlag = false;
- //站立
- Master.DoIdle();
- }
- else if (!_moveFlag)
- {
- _moveFlag = true;
- //移动
- Master.DoMove();
- }
- else
- {
- var lastSlideCollision = Master.GetLastSlideCollision();
- if (lastSlideCollision != null && lastSlideCollision.GetCollider() is Role) //碰到其他角色
- {
- _pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.3f);
- _isMoveOver = true;
- _moveFlag = false;
- //站立
- Master.DoIdle();
- }
- else
- {
- //移动
- Master.DoMove();
- }
-
- if (_prevPos.DistanceSquaredTo(masterPosition) <= 1 * delta)
- {
- _lockTimer += delta;
- }
- else
- {
- _lockTimer = 0;
- _prevPos = masterPosition;
- }
- }
- }
- }
-
- private void RunOver(Vector2 targetPos)
- {
- var weapon = Master.WeaponPack.ActiveItem;
- var distance = (int)(weapon == null ? 150 : (Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange) * 0.7f));
- _nextPosition = new Vector2(
- targetPos.X + Utils.Random.RandomRangeInt(-distance, distance),
- targetPos.Y + Utils.Random.RandomRangeInt(-distance, distance)
- );
- Master.NavigationAgent2D.TargetPosition = _nextPosition;
- }
-
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFindAmmoState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFindAmmoState.cs
deleted file mode 100644
index 207795b..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFindAmmoState.cs
+++ /dev/null
@@ -1,204 +0,0 @@
-
-using System;
-using Godot;
-
-namespace EnemyState;
-
-///
-/// Ai 寻找弹药, 进入该状态需要在参数中传入目标武器对象
-///
-public class AiFindAmmoState : StateBase
-{
- ///
- /// 目标武器
- ///
- public Weapon TargetWeapon;
-
- //导航目标点刷新计时器
- private float _navigationUpdateTimer = 0;
- private float _navigationInterval = 1f;
-
- private float _tailAfterTimer = 0;
- private ActivityObject _attackTarget;
-
- private float _idleTimer = 0;
- private bool _playAnimFlag = false;
-
- public AiFindAmmoState() : base(AIStateEnum.AiFindAmmo)
- {
- }
-
- public override void Enter(AIStateEnum prev, params object[] args)
- {
- if (args.Length == 0)
- {
- throw new Exception("进入 AiStateEnum.AiFindAmmo 状态必须要把目标武器当成参数传过来");
- }
-
- if (args.Length >= 2)
- {
- _attackTarget = (ActivityObject)args[1];
- }
- else
- {
- _attackTarget = null;
- }
-
- SetTargetWeapon((Weapon)args[0]);
- _navigationUpdateTimer = _navigationInterval;
- _tailAfterTimer = 0;
-
- //标记武器
- TargetWeapon.SetSign(SignNames.AiFindWeaponSign, Master);
-
- _playAnimFlag = prev == AIStateEnum.AiLeaveFor;
- if (_playAnimFlag)
- {
- Master.AnimationPlayer.Play(AnimatorNames.Query);
- }
- }
-
- public override void Process(float delta)
- {
- if (_playAnimFlag && _idleTimer > 0)
- {
- _idleTimer -= delta;
- return;
- }
-
- if (!Master.IsAllWeaponTotalAmmoEmpty()) //已经有弹药了
- {
- RunNextState();
- return;
- }
-
- if (Master.LookTarget == null) //没有目标
- {
- //临时处理
- var player = Player.Current;
- var playerPos = player.GetCenterPosition();
- if (Master.IsInViewRange(playerPos) && !Master.TestViewRayCast(playerPos)) //发现玩家
- {
- //关闭射线检测
- Master.TestViewRayCastOver();
- //发现玩家
- Master.LookTarget = player;
- //进入惊讶状态, 然后再进入通知状态
- ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiFindAmmo, TargetWeapon);
- return;
- }
- }
-
- //更新目标位置
- if (_navigationUpdateTimer <= 0)
- {
- //每隔一段时间秒更改目标位置
- _navigationUpdateTimer = _navigationInterval;
- var position = TargetWeapon.GlobalPosition;
- Master.NavigationAgent2D.TargetPosition = position;
- }
- else
- {
- _navigationUpdateTimer -= delta;
- }
-
- if (TargetWeapon.IsDestroyed || TargetWeapon.IsTotalAmmoEmpty()) //已经被销毁, 或者弹药已经被其他角色捡走
- {
- //再去寻找其他武器
- SetTargetWeapon(Master.FindTargetWeapon());
-
- if (TargetWeapon == null) //也没有其他可用的武器了
- {
- RunNextState();
- }
- }
- else if (TargetWeapon.Master == Master) //已经被自己拾起
- {
- RunNextState();
- }
- else if (TargetWeapon.Master != null) //武器已经被其他角色拾起!
- {
- //再去寻找其他武器
- SetTargetWeapon(Master.FindTargetWeapon());
-
- if (TargetWeapon == null) //也没有其他可用的武器了
- {
- RunNextState();
- }
- }
- else
- {
- if (Master.LookTarget != null)
- {
- //检测目标没有超出跟随视野距离
- var isInTailAfterRange = Master.IsInTailAfterViewRange(Master.LookTarget.GetCenterPosition());
- if (isInTailAfterRange)
- {
- _tailAfterTimer = 0;
- }
- else
- {
- _tailAfterTimer += delta;
- }
- }
-
- //向武器移动
- if (!Master.NavigationAgent2D.IsNavigationFinished())
- {
- //移动
- Master.DoMove();
- }
- else
- {
- //站立
- Master.DoIdle();
- }
- }
- }
-
- private void RunNextState()
- {
- if (_attackTarget != null)
- {
- ChangeState(AIStateEnum.AiLeaveFor, _attackTarget);
- }
- else if (Master.LookTarget != null)
- {
- ChangeState(_tailAfterTimer > 10 ? AIStateEnum.AiNormal : AIStateEnum.AiTailAfter);
- }
- else
- {
- ChangeState(AIStateEnum.AiNormal);
- }
- }
-
- private void SetTargetWeapon(Weapon weapon)
- {
- TargetWeapon = weapon;
- if (weapon != null)
- {
- //设置目标点
- Master.NavigationAgent2D.TargetPosition = TargetWeapon.GlobalPosition;
- }
- }
-
- public override void DebugDraw()
- {
- if (TargetWeapon != null)
- {
- Master.DrawLine(Vector2.Zero, Master.ToLocal(TargetWeapon.GlobalPosition), Colors.Purple);
-
- if (Master.LookTarget != null)
- {
- if (_tailAfterTimer <= 0)
- {
- Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.LookTarget.GetCenterPosition()), Colors.Orange);
- }
- else if (_tailAfterTimer <= 10)
- {
- Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.LookTarget.GetCenterPosition()), Colors.Blue);
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs
deleted file mode 100644
index d0f1bde..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs
+++ /dev/null
@@ -1,147 +0,0 @@
-
-using System;
-using Godot;
-
-namespace EnemyState;
-
-///
-/// 目标在视野内, 跟进目标, 如果距离在子弹有效射程内, 则开火
-///
-public class AiFollowUpState : StateBase
-{
- //导航目标点刷新计时器
- private float _navigationUpdateTimer = 0;
- private float _navigationInterval = 0.3f;
-
- public AiFollowUpState() : base(AIStateEnum.AiFollowUp)
- {
- }
-
- public override void Enter(AIStateEnum prev, params object[] args)
- {
- if (Master.LookTarget == null)
- {
- throw new Exception("进入 AIAdvancedStateEnum.AiFollowUp 状态时角色没有攻击目标!");
- }
-
- _navigationUpdateTimer = 0;
- Master.TargetInView = true;
- }
-
- public override void Process(float delta)
- {
- //先检查弹药是否打光
- if (Master.IsAllWeaponTotalAmmoEmpty())
- {
- //再寻找是否有可用的武器
- var targetWeapon = Master.FindTargetWeapon();
- if (targetWeapon != null)
- {
- ChangeState(AIStateEnum.AiFindAmmo, targetWeapon);
- return;
- }
- else
- {
- //切换到随机移动状态
- ChangeState(AIStateEnum.AiSurround);
- }
- }
-
- var playerPos = Master.LookTarget.GetCenterPosition();
-
- //更新玩家位置
- if (_navigationUpdateTimer <= 0)
- {
- //每隔一段时间秒更改目标位置
- _navigationUpdateTimer = _navigationInterval;
- Master.NavigationAgent2D.TargetPosition = playerPos;
- }
- else
- {
- _navigationUpdateTimer -= delta;
- }
-
- //是否在攻击范围内
- var inAttackRange = false;
-
- var weapon = Master.WeaponPack.ActiveItem;
- var distanceSquared = Master.Position.DistanceSquaredTo(playerPos);
- if (weapon != null)
- {
- inAttackRange = distanceSquared <= Mathf.Pow(Master.GetWeaponRange(0.7f), 2);
- }
- else
- {
- inAttackRange = distanceSquared <= Mathf.Pow(Master.EnemyRoleState.ViewRange * 0.7f, 2);
- }
-
- if (!Master.NavigationAgent2D.IsNavigationFinished())
- {
- //移动
- Master.DoMove();
- }
- else
- {
- //站立
- Master.DoIdle();
- }
-
- //检测玩家是否在视野内
- if (Master.IsInTailAfterViewRange(playerPos))
- {
- Master.TargetInView = !Master.TestViewRayCast(playerPos);
- //关闭射线检测
- Master.TestViewRayCastOver();
- }
- else
- {
- Master.TargetInView = false;
- }
-
- //在视野中
- if (Master.TargetInView)
- {
- //更新标记位置
- Master.UpdateMarkTargetPosition();
- if (inAttackRange) //在攻击范围内
- {
- if (weapon != null)
- {
- //距离够近, 可以切换到环绕模式
- if (distanceSquared <= Mathf.Pow(Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange) * 0.7f, 2))
- {
- ChangeState(AIStateEnum.AiSurround);
- }
- else if (!Master.IsAttack && weapon.TriggerIsReady()) //可以攻击
- {
- //攻击状态
- ChangeState(AIStateEnum.AiAttack);
- }
- }
- else
- {
- //距离够近, 可以切换到环绕模式
- if (distanceSquared <= Mathf.Pow(Master.EnemyRoleState.ViewRange * 0.7f, 2))
- {
- ChangeState(AIStateEnum.AiSurround);
- }
- else if (!Master.IsAttack && Master.NoWeaponAttack) //可以在没有武器时发起攻击
- {
- //攻击状态
- ChangeState(AIStateEnum.AiAttack);
- }
- }
- }
- }
- else //不在视野中
- {
- ChangeState(AIStateEnum.AiTailAfter);
- }
- }
-
- public override void DebugDraw()
- {
- var playerPos = Master.LookTarget.GetCenterPosition();
- Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Red);
- }
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiLeaveForState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiLeaveForState.cs
deleted file mode 100644
index 2ec0526..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiLeaveForState.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-
-using System;
-using Godot;
-
-namespace EnemyState;
-
-///
-/// 收到其他敌人通知, 前往发现目标的位置
-///
-public class AiLeaveForState : StateBase
-{
- //导航目标点刷新计时器
- private float _navigationUpdateTimer = 0;
- private float _navigationInterval = 0.3f;
-
- //目标
- private ActivityObject _target;
- //目标点
- private Vector2 _targetPosition;
-
- private float _idleTimer = 0;
- private bool _playAnimFlag = false;
-
- public AiLeaveForState() : base(AIStateEnum.AiLeaveFor)
- {
- }
-
- public override void Enter(AIStateEnum prev, params object[] args)
- {
- if (args.Length == 0)
- {
- throw new Exception("进入 AINormalStateEnum.AiLeaveFor 状态必须带上目标对象");
- }
-
- _target = (ActivityObject)args[0];
-
- //先检查弹药是否打光
- if (Master.IsAllWeaponTotalAmmoEmpty())
- {
- //再寻找是否有可用的武器
- var targetWeapon = Master.FindTargetWeapon();
- if (targetWeapon != null)
- {
- ChangeState(AIStateEnum.AiFindAmmo, targetWeapon, _target);
- return;
- }
- }
-
- _idleTimer = 1;
- _targetPosition = _target.GetCenterPosition();
- Master.LookTargetPosition(_targetPosition);
-
- _playAnimFlag = prev != AIStateEnum.AiFindAmmo;
- if (_playAnimFlag)
- {
- Master.AnimationPlayer.Play(AnimatorNames.Query);
- }
-
- //看向目标位置
- Master.LookTargetPosition(_target.GetCenterPosition());
- }
-
- public override void Exit(AIStateEnum next)
- {
- Master.AnimationPlayer.Play(AnimatorNames.Reset);
- }
-
- public override void Process(float delta)
- {
- if (_playAnimFlag && _idleTimer > 0)
- {
- _idleTimer -= delta;
- return;
- }
- //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽
-
- //更新玩家位置
- if (_navigationUpdateTimer <= 0)
- {
- //每隔一段时间秒更改目标位置
- _navigationUpdateTimer = _navigationInterval;
- if (Master.AffiliationArea.RoomInfo.MarkTargetPosition.TryGetValue(_target.Id, out var pos))
- {
- _targetPosition = pos;
- }
- Master.NavigationAgent2D.TargetPosition = _targetPosition;
- }
- else
- {
- _navigationUpdateTimer -= delta;
- }
-
- if (!Master.NavigationAgent2D.IsNavigationFinished())
- {
- Master.LookTargetPosition(_targetPosition);
- //移动
- Master.DoMove();
- }
- else
- {
- //站立
- Master.DoIdle();
- }
-
- var playerPos = Player.Current.GetCenterPosition();
- //检测玩家是否在视野内, 如果在, 则切换到 AiTargetInView 状态
- if (Master.IsInTailAfterViewRange(playerPos))
- {
- if (!Master.TestViewRayCast(playerPos)) //看到玩家
- {
- //关闭射线检测
- Master.TestViewRayCastOver();
- //切换成发现目标状态
- Master.LookTarget = Player.Current;
- ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiFollowUp);
- return;
- }
- else
- {
- //关闭射线检测
- Master.TestViewRayCastOver();
- }
- }
-
- //移动到目标掉了, 还没发现目标
- if (Master.NavigationAgent2D.IsNavigationFinished())
- {
- ChangeState(AIStateEnum.AiNormal);
- }
- }
-
- public override void DebugDraw()
- {
- Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.NavigationAgent2D.TargetPosition), Colors.Yellow);
- }
-}
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiNormalState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiNormalState.cs
deleted file mode 100644
index c4635c9..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiNormalState.cs
+++ /dev/null
@@ -1,178 +0,0 @@
-
-using System.Linq;
-using Godot;
-
-namespace EnemyState;
-
-///
-/// AI 正常状态
-///
-public class AiNormalState : StateBase
-{
- //下一个运动的坐标
- private Vector2 _nextPos;
-
- //是否移动结束
- private bool _isMoveOver;
-
- //上一次移动是否撞墙
- private bool _againstWall;
-
- //撞墙法线角度
- private float _againstWallNormalAngle;
-
- //移动停顿计时器
- private float _pauseTimer;
- private bool _moveFlag;
-
- //上一帧位置
- private Vector2 _prevPos;
- //卡在一个位置的时间
- private float _lockTimer;
-
- public AiNormalState() : base(AIStateEnum.AiNormal)
- {
- }
-
- public override void Enter(AIStateEnum prev, params object[] args)
- {
- _isMoveOver = true;
- _againstWall = false;
- _againstWallNormalAngle = 0;
- _pauseTimer = 0;
- _moveFlag = false;
- Master.LookTarget = null;
- }
-
- public override void Process(float delta)
- {
- //检测玩家
- var player = Player.Current;
- //玩家中心点坐标
- var playerPos = player.GetCenterPosition();
-
- if (Master.IsInViewRange(playerPos) && !Master.TestViewRayCast(playerPos)) //发现玩家
- {
- //关闭射线检测
- Master.TestViewRayCastOver();
- //发现玩家
- Master.LookTarget = player;
- //判断是否进入通知状态
- if (Master.World.Enemy_InstanceList.FindIndex(enemy =>
- enemy != Master && !enemy.IsDie && enemy.AffiliationArea == Master.AffiliationArea &&
- enemy.StateController.CurrState == AIStateEnum.AiNormal) != -1)
- {
- //进入惊讶状态, 然后再进入通知状态
- ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiNotify);
- }
- else
- {
- //进入惊讶状态, 然后再进入跟随状态
- ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiTailAfter);
- }
- return;
- }
- else if (_pauseTimer >= 0)
- {
- Master.AnimatedSprite.Play(AnimatorNames.Idle);
- _pauseTimer -= delta;
- }
- else if (_isMoveOver) //没发现玩家, 且已经移动完成
- {
- RunOver();
- _isMoveOver = false;
- }
- else //移动中
- {
- if (_lockTimer >= 1) //卡在一个点超过一秒
- {
- RunOver();
- _isMoveOver = false;
- _lockTimer = 0;
- }
- else if (Master.NavigationAgent2D.IsNavigationFinished()) //到达终点
- {
- _pauseTimer = Utils.Random.RandomRangeFloat(0.3f, 2f);
- _isMoveOver = true;
- _moveFlag = false;
- //站立
- Master.DoIdle();
- }
- else if (!_moveFlag)
- {
- _moveFlag = true;
- var pos = Master.Position;
- //移动
- Master.DoMove();
- _prevPos = pos;
- }
- else
- {
- var pos = Master.Position;
- var lastSlideCollision = Master.GetLastSlideCollision();
- if (lastSlideCollision != null && lastSlideCollision.GetCollider() is Role) //碰到其他角色
- {
- _pauseTimer = Utils.Random.RandomRangeFloat(0.1f, 0.5f);
- _isMoveOver = true;
- _moveFlag = false;
- //站立
- Master.DoIdle();
- }
- else
- {
- //移动
- Master.DoMove();
- }
-
- if (_prevPos.DistanceSquaredTo(pos) <= 0.01f)
- {
- _lockTimer += delta;
- }
- else
- {
- _prevPos = pos;
- }
- }
- }
-
- //关闭射线检测
- Master.TestViewRayCastOver();
- }
-
- //移动结束
- private void RunOver()
- {
- float angle;
- if (_againstWall)
- {
- angle = Utils.Random.RandomRangeFloat(_againstWallNormalAngle - Mathf.Pi * 0.5f,
- _againstWallNormalAngle + Mathf.Pi * 0.5f);
- }
- else
- {
- angle = Utils.Random.RandomRangeFloat(0, Mathf.Pi * 2f);
- }
-
- var len = Utils.Random.RandomRangeInt(30, 200);
- _nextPos = new Vector2(len, 0).Rotated(angle) + Master.GlobalPosition;
- //获取射线碰到的坐标
- if (Master.TestViewRayCast(_nextPos)) //碰到墙壁
- {
- _nextPos = Master.ViewRay.GetCollisionPoint();
- _againstWall = true;
- _againstWallNormalAngle = Master.ViewRay.GetCollisionNormal().Angle();
- }
- else
- {
- _againstWall = false;
- }
-
- Master.NavigationAgent2D.TargetPosition = _nextPos;
- Master.LookTargetPosition(_nextPos);
- }
-
- public override void DebugDraw()
- {
- Master.DrawLine(new Vector2(0, -8), Master.ToLocal(_nextPos), Colors.Green);
- }
-}
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiNotifyState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiNotifyState.cs
deleted file mode 100644
index 09a6b08..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiNotifyState.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace EnemyState;
-
-///
-/// 发现目标, 通知其它敌人
-///
-public class AiNotifyState : StateBase
-{
- private float _timer;
-
- public AiNotifyState() : base(AIStateEnum.AiNotify)
- {
- }
-
- public override void Enter(AIStateEnum prev, params object[] args)
- {
- if (Master.LookTarget == null)
- {
- throw new Exception("进入 AIAdvancedStateEnum.AiNotify 没有攻击目标!");
- }
- _timer = 1.2f;
- //通知其它角色
- Master.World.NotifyEnemyTarget(Master, Master.LookTarget);
- Master.AnimationPlayer.Play(AnimatorNames.Notify);
- }
-
- public override void Process(float delta)
- {
- Master.DoIdle();
- _timer -= delta;
- if (_timer <= 0)
- {
- ChangeState(AIStateEnum.AiTailAfter);
- }
- }
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs
deleted file mode 100644
index da694dd..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-
-using System;
-using Godot;
-
-namespace EnemyState;
-
-///
-/// 距离目标足够近, 在目标附近随机移动, 并开火
-///
-public class AiSurroundState : StateBase
-{
- //是否移动结束
- private bool _isMoveOver;
-
- //移动停顿计时器
- private float _pauseTimer;
- private bool _moveFlag;
-
- //下一个移动点
- private Vector2 _nextPosition;
-
- //上一帧位置
- private Vector2 _prevPos;
- //卡在一个位置的时间
- private float _lockTimer;
-
- public AiSurroundState() : base(AIStateEnum.AiSurround)
- {
- }
-
- public override void Enter(AIStateEnum prev, params object[] args)
- {
- if (Master.LookTarget == null)
- {
- throw new Exception("进入 AIAdvancedStateEnum.AiSurround 状态时角色没有攻击目标!");
- }
-
- Master.TargetInView = true;
- _isMoveOver = true;
- _pauseTimer = 0;
- _moveFlag = false;
- }
-
- public override void Process(float delta)
- {
- //先检查弹药是否打光
- if (Master.IsAllWeaponTotalAmmoEmpty())
- {
- //再寻找是否有可用的武器
- var targetWeapon = Master.FindTargetWeapon();
- if (targetWeapon != null)
- {
- ChangeState(AIStateEnum.AiFindAmmo, targetWeapon);
- return;
- }
- }
-
- var playerPos = Master.LookTarget.GetCenterPosition();
-
- //检测玩家是否在视野内
- if (Master.IsInTailAfterViewRange(playerPos))
- {
- Master.TargetInView = !Master.TestViewRayCast(playerPos);
- //关闭射线检测
- Master.TestViewRayCastOver();
- }
- else
- {
- Master.TargetInView = false;
- }
-
- //在视野中
- if (Master.TargetInView)
- {
- //更新标记位置
- Master.UpdateMarkTargetPosition();
-
- if (_pauseTimer >= 0)
- {
- Master.AnimatedSprite.Play(AnimatorNames.Idle);
- _pauseTimer -= delta;
- }
- else if (_isMoveOver) //移动已经完成
- {
- RunOver(playerPos);
- _isMoveOver = false;
- }
- else
- {
- var masterPosition = Master.Position;
- if (_lockTimer >= 1) //卡在一个点超过一秒
- {
- RunOver(playerPos);
- _isMoveOver = false;
- _lockTimer = 0;
- }
- else if (Master.NavigationAgent2D.IsNavigationFinished()) //到达终点
- {
- _pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.5f);
- _isMoveOver = true;
- _moveFlag = false;
- //站立
- Master.DoIdle();
- }
- else if (!_moveFlag)
- {
- _moveFlag = true;
- //移动
- Master.DoMove();
- }
- else
- {
- var lastSlideCollision = Master.GetLastSlideCollision();
- if (lastSlideCollision != null && lastSlideCollision.GetCollider() is Role) //碰到其他角色
- {
- _pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.3f);
- _isMoveOver = true;
- _moveFlag = false;
- //站立
- Master.DoIdle();
- }
- else
- {
- //移动
- Master.DoMove();
- }
-
- if (_prevPos.DistanceSquaredTo(masterPosition) <= 1 * delta)
- {
- _lockTimer += delta;
- }
- else
- {
- _lockTimer = 0;
- _prevPos = masterPosition;
- }
- }
-
- var weapon = Master.WeaponPack.ActiveItem;
- if (weapon != null)
- {
- if (masterPosition.DistanceSquaredTo(playerPos) > Mathf.Pow(Master.GetWeaponRange(0.7f), 2)) //玩家离开正常射击范围
- {
- ChangeState(AIStateEnum.AiFollowUp);
- }
- else if (!Master.IsAttack && weapon.TriggerIsReady()) //可以攻击
- {
- //发起攻击
- ChangeState(AIStateEnum.AiAttack);
- }
- }
- else
- {
- if (masterPosition.DistanceSquaredTo(playerPos) > Mathf.Pow(Master.EnemyRoleState.ViewRange * 0.7f, 2)) //玩家离开正常射击范围
- {
- ChangeState(AIStateEnum.AiFollowUp);
- }
- else if (!Master.IsAttack && Master.NoWeaponAttack) //可以在没有武器时发起攻击
- {
- //攻击状态
- ChangeState(AIStateEnum.AiAttack);
- }
- }
- }
- }
- else //目标离开视野
- {
- ChangeState(AIStateEnum.AiTailAfter);
- }
- }
-
- private void RunOver(Vector2 targetPos)
- {
- var weapon = Master.WeaponPack.ActiveItem;
- var distance = (int)(weapon == null ? 150 : (Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange) * 0.7f));
- _nextPosition = new Vector2(
- targetPos.X + Utils.Random.RandomRangeInt(-distance, distance),
- targetPos.Y + Utils.Random.RandomRangeInt(-distance, distance)
- );
- Master.NavigationAgent2D.TargetPosition = _nextPosition;
- }
-
- public override void DebugDraw()
- {
- Master.DrawLine(new Vector2(0, -8), Master.ToLocal(_nextPosition), Colors.White);
- }
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs
deleted file mode 100644
index 4fa2cc5..0000000
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-
-using System;
-using Godot;
-
-namespace EnemyState;
-
-///
-/// AI 发现玩家, 跟随玩家, 但是不在视野范围内
-///
-public class AiTailAfterState : StateBase
-{
- ///
- /// 目标是否在视野半径内
- ///
- private bool _isInViewRange;
-
- //导航目标点刷新计时器
- private float _navigationUpdateTimer = 0;
- private float _navigationInterval = 0.3f;
-
- //目标从视野消失时已经过去的时间
- private float _viewTimer;
-
- public AiTailAfterState() : base(AIStateEnum.AiTailAfter)
- {
- }
-
- public override void Enter(AIStateEnum prev, params object[] args)
- {
- if (Master.LookTarget == null)
- {
- throw new Exception("进入 AIAdvancedStateEnum.AiTailAfter 状态时角色没有攻击目标!");
- }
-
- _isInViewRange = true;
- _navigationUpdateTimer = 0;
- _viewTimer = 0;
-
- //先检查弹药是否打光
- if (Master.IsAllWeaponTotalAmmoEmpty())
- {
- //再寻找是否有可用的武器
- var targetWeapon = Master.FindTargetWeapon();
- if (targetWeapon != null)
- {
- ChangeState(AIStateEnum.AiFindAmmo, targetWeapon);
- }
- }
- }
-
- public override void Process(float delta)
- {
- //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽
-
- var playerPos = Master.LookTarget.GetCenterPosition();
-
- //更新玩家位置
- if (_navigationUpdateTimer <= 0)
- {
- //每隔一段时间秒更改目标位置
- _navigationUpdateTimer = _navigationInterval;
- Master.NavigationAgent2D.TargetPosition = playerPos;
- }
- else
- {
- _navigationUpdateTimer -= delta;
- }
-
- if (!Master.NavigationAgent2D.IsNavigationFinished())
- {
- //移动
- Master.DoMove();
- }
- else
- {
- //站立
- Master.DoIdle();
- }
- //检测玩家是否在视野内, 如果在, 则切换到 AiTargetInView 状态
- if (Master.IsInTailAfterViewRange(playerPos))
- {
- if (!Master.TestViewRayCast(playerPos)) //看到玩家
- {
- //关闭射线检测
- Master.TestViewRayCastOver();
- //切换成发现目标状态
- ChangeState(AIStateEnum.AiFollowUp);
- return;
- }
- else
- {
- //关闭射线检测
- Master.TestViewRayCastOver();
- }
- }
-
- //检测玩家是否在穿墙视野范围内, 直接检测距离即可
- _isInViewRange = Master.IsInViewRange(playerPos);
- if (_isInViewRange)
- {
- _viewTimer = 0;
- }
- else //超出视野
- {
- if (_viewTimer > 10) //10秒
- {
- ChangeState(AIStateEnum.AiNormal);
- }
- else
- {
- _viewTimer += delta;
- }
- }
- }
-
- public override void DebugDraw()
- {
- var playerPos = Master.LookTarget.GetCenterPosition();
- if (_isInViewRange)
- {
- Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Orange);
- }
- else
- {
- Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Blue);
- }
- }
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs
index 6153367..9834eac 100644
--- a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs
@@ -10,6 +10,11 @@
public partial class Player : Role
{
///
+ /// 当玩家第一次进入房间时调用
+ ///
+ public event Action OnFirstEnterRoomEvent;
+
+ ///
/// 获取当前操作的角色
///
public static Player Current { get; private set; }
@@ -420,4 +425,21 @@
base.AddGold(goldCount);
EventManager.EmitEvent(EventEnum.OnPlayerGoldChange, RoleState.Gold);
}
+
+ public override void UseGold(int goldCount)
+ {
+ base.UseGold(goldCount);
+ EventManager.EmitEvent(EventEnum.OnPlayerGoldChange, RoleState.Gold);
+ }
+
+ ///
+ /// 玩家第一次进入房间时调用
+ ///
+ public virtual void OnFirstEnterRoom(RoomInfo roomInfo)
+ {
+ if (OnFirstEnterRoomEvent != null)
+ {
+ OnFirstEnterRoomEvent(roomInfo);
+ }
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/role/shop/ShopBoss.cs b/DungeonShooting_Godot/src/game/activity/role/shop/ShopBoss.cs
new file mode 100644
index 0000000..b6153c3
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/activity/role/shop/ShopBoss.cs
@@ -0,0 +1,14 @@
+
+using Godot;
+
+///
+/// 商店老板
+///
+[Tool]
+public partial class ShopBoss : AiRole
+{
+ public override void OnCreateWithMark(RoomPreinstall roomPreinstall, ActivityMark activityMark)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/BuffFragment.cs b/DungeonShooting_Godot/src/game/buff/BuffFragment.cs
index 82dd69d..5b29f99 100644
--- a/DungeonShooting_Godot/src/game/buff/BuffFragment.cs
+++ b/DungeonShooting_Godot/src/game/buff/BuffFragment.cs
@@ -1,6 +1,4 @@
-using System;
-
///
/// 被动属性逻辑基类
///
diff --git a/DungeonShooting_Godot/src/game/buff/BuffFragmentAttribute.cs b/DungeonShooting_Godot/src/game/buff/BuffFragmentAttribute.cs
index bb12a62..ac3a753 100644
--- a/DungeonShooting_Godot/src/game/buff/BuffFragmentAttribute.cs
+++ b/DungeonShooting_Godot/src/game/buff/BuffFragmentAttribute.cs
@@ -1,21 +1,12 @@
using System;
+///
+/// buff片段
+///
[AttributeUsage(AttributeTargets.Class)]
-public class BuffFragmentAttribute : Attribute
+public class BuffFragmentAttribute : FragmentAttribute
{
- ///
- /// Buff属性名称
- ///
- public string BuffName { get; set; }
-
- ///
- /// 描述
- ///
- public string Description { get; set; }
-
- public BuffFragmentAttribute(string buffName, string description)
+ public BuffFragmentAttribute(string name, string description) : base(name, description)
{
- BuffName = buffName;
- Description = description;
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/ChargeFragmentAttribute.cs b/DungeonShooting_Godot/src/game/buff/ChargeFragmentAttribute.cs
index 4cf3f9c..6bf9b8f 100644
--- a/DungeonShooting_Godot/src/game/buff/ChargeFragmentAttribute.cs
+++ b/DungeonShooting_Godot/src/game/buff/ChargeFragmentAttribute.cs
@@ -1,21 +1,12 @@
using System;
+///
+/// 充能片段
+///
[AttributeUsage(AttributeTargets.Class)]
-public class ChargeFragmentAttribute : Attribute
+public class ChargeFragmentAttribute : FragmentAttribute
{
- ///
- /// 充能属性名称
- ///
- public string ChargeName { get; set; }
-
- ///
- /// 描述
- ///
- public string Description { get; set; }
-
- public ChargeFragmentAttribute(string chargeName, string description)
+ public ChargeFragmentAttribute(string name, string description) : base(name, description)
{
- ChargeName = chargeName;
- Description = description;
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/ConditionFragmentAttribute.cs b/DungeonShooting_Godot/src/game/buff/ConditionFragmentAttribute.cs
index 1d9191e..fd79f64 100644
--- a/DungeonShooting_Godot/src/game/buff/ConditionFragmentAttribute.cs
+++ b/DungeonShooting_Godot/src/game/buff/ConditionFragmentAttribute.cs
@@ -1,22 +1,13 @@
using System;
+///
+/// 条件片段
+///
[AttributeUsage(AttributeTargets.Class)]
-public class ConditionFragmentAttribute : Attribute
+public class ConditionFragmentAttribute : FragmentAttribute
{
- ///
- /// 条件名称
- ///
- public string ConditionName { get; set; }
-
- ///
- /// 描述
- ///
- public string Description { get; set; }
-
- public ConditionFragmentAttribute(string conditionName, string description)
+ public ConditionFragmentAttribute(string name, string description) : base(name, description)
{
- ConditionName = conditionName;
- Description = description;
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/EffectFragmentAttribute.cs b/DungeonShooting_Godot/src/game/buff/EffectFragmentAttribute.cs
index 3a5f9fc..5115b91 100644
--- a/DungeonShooting_Godot/src/game/buff/EffectFragmentAttribute.cs
+++ b/DungeonShooting_Godot/src/game/buff/EffectFragmentAttribute.cs
@@ -1,21 +1,12 @@
using System;
+///
+/// 主动效果片段
+///
[AttributeUsage(AttributeTargets.Class)]
-public class EffectFragmentAttribute : Attribute
+public class EffectFragmentAttribute : FragmentAttribute
{
- ///
- /// 效果名称
- ///
- public string EffectName { get; set; }
-
- ///
- /// 描述
- ///
- public string Description { get; set; }
-
- public EffectFragmentAttribute(string effectName, string description)
+ public EffectFragmentAttribute(string name, string description) : base(name, description)
{
- EffectName = effectName;
- Description = description;
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/FragmentAttribute.cs b/DungeonShooting_Godot/src/game/buff/FragmentAttribute.cs
new file mode 100644
index 0000000..e2100cd
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/buff/FragmentAttribute.cs
@@ -0,0 +1,63 @@
+using System;
+
+///
+/// 属性逻辑基类
+///
+public abstract class FragmentAttribute : Attribute
+{
+ ///
+ /// 属性名称
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// 描述
+ ///
+ public string Description { get; set; }
+
+ ///
+ /// 参数1 描述
+ ///
+ public string Arg1 { get; set; }
+
+ ///
+ /// 参数2 描述
+ ///
+ public string Arg2 { get; set; }
+
+ ///
+ /// 参数3 描述
+ ///
+ public string Arg3 { get; set; }
+
+ ///
+ /// 参数4 描述
+ ///
+ public string Arg4 { get; set; }
+
+ ///
+ /// 参数5 描述
+ ///
+ public string Arg5 { get; set; }
+
+ ///
+ /// 参数6 描述
+ ///
+ public string Arg6 { get; set; }
+
+ ///
+ /// 参数7 描述
+ ///
+ public string Arg7 { get; set; }
+
+ ///
+ /// 参数8 描述
+ ///
+ public string Arg8 { get; set; }
+
+ public FragmentAttribute(string name, string description)
+ {
+ Name = name;
+ Description = description;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/PropFragment.cs b/DungeonShooting_Godot/src/game/buff/PropFragment.cs
index 927ee2e..b1d6bd2 100644
--- a/DungeonShooting_Godot/src/game/buff/PropFragment.cs
+++ b/DungeonShooting_Godot/src/game/buff/PropFragment.cs
@@ -1,4 +1,6 @@
+using System.Text.Json;
+
///
/// 道具逻辑片段组件
///
@@ -10,6 +12,11 @@
public Role Role => Master?.Master;
///
+ /// 初始化被动属性参数
+ ///
+ public abstract void InitParam(JsonElement[] args);
+
+ ///
/// 当道具被拾起时调用 (在 Role 赋值之后调用)
///
public abstract void OnPickUpItem();
@@ -26,36 +33,4 @@
{
return Master != null;
}
-
- ///
- /// 初始化被动属性参数
- ///
- public virtual void InitParam(float arg1)
- {
- Debug.LogError($"'{GetType().FullName}'为实现1参数初始化函数!");
- }
-
- ///
- /// 初始化被动属性参数
- ///
- public virtual void InitParam(float arg1, float arg2)
- {
- Debug.LogError($"'{GetType().FullName}'为实现2参数初始化函数!");
- }
-
- ///
- /// 初始化被动属性参数
- ///
- public virtual void InitParam(float arg1, float arg2, float arg3)
- {
- Debug.LogError($"'{GetType().FullName}'为实现4参数初始化函数!");
- }
-
- ///
- /// 初始化被动属性参数
- ///
- public virtual void InitParam(float arg1, float arg2, float arg3, float arg4)
- {
- Debug.LogError($"'{GetType().FullName}'为实现4参数初始化函数!");
- }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_ActivePropsCapacity.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_ActivePropsCapacity.cs
index 6804fb9..79a09d0 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_ActivePropsCapacity.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_ActivePropsCapacity.cs
@@ -1,12 +1,18 @@
-[BuffFragment("ActivePropsCapacity", "主动道具背包容量 buff, 参数‘1’为主动道具背包增加的容量")]
+using System.Text.Json;
+
+[BuffFragment(
+ "ActivePropsCapacity",
+ "主动道具背包容量 buff",
+ Arg1 = "(int)主动道具背包增加的容量"
+)]
public class Buff_ActivePropsCapacity : BuffFragment
{
private int _value;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] arg)
{
- _value = (int)arg1;
+ _value = arg[0].GetInt32();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletBounceCount.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletBounceCount.cs
index b68ac1a..091849b 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletBounceCount.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletBounceCount.cs
@@ -1,12 +1,17 @@
-[BuffFragment("BulletBounceCount", "子弹弹射数量 buff, 参数‘1’为增加的弹射次数")]
+using System.Text.Json;
+
+[BuffFragment(
+ "BulletBounceCount", "子弹弹射数量 buff",
+ Arg1 = "(int)子弹增加的弹射次数"
+)]
public class Buff_BulletBounceCount : BuffFragment
{
private int _value;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] arg)
{
- _value = (int)arg1;
+ _value = arg[0].GetInt32();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletCount.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletCount.cs
index 8f1bf17..8d58e33 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletCount.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletCount.cs
@@ -1,19 +1,22 @@
+using System.Text.Json;
using Godot;
-[BuffFragment("BulletCount",
- "子弹数量 buff, " +
- "参数‘1’为子弹数量添加类型, 1: 具体数量, 2:百分比(小数), " +
- "参数‘2’为增加子弹的数量")]
+[BuffFragment(
+ "BulletCount",
+ "子弹数量 buff",
+ Arg1 = "(int)子弹数量添加类型, 1: 具体数量, 2:百分比",
+ Arg2 = "(float)增加子弹的数量"
+)]
public class Buff_BulletCount : BuffFragment
{
private int _type;
private float _value;
- public override void InitParam(float arg1, float arg2)
+ public override void InitParam(JsonElement[] arg)
{
- _type = (int)arg1;
- _value = (int)arg2;
+ _type = arg[0].GetInt32();
+ _value = arg[1].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDamage.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDamage.cs
index 93f13f6..4498fb4 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDamage.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDamage.cs
@@ -1,19 +1,22 @@
+using System.Text.Json;
using Godot;
-[BuffFragment("BulletDamage",
- "提升子弹伤害buff, " +
- "参数‘1’为伤害增加类型: 1:具体伤害, 2:百分比伤害(小数), " +
- "参数‘2’为增益伤害值")]
+[BuffFragment(
+ "BulletDamage",
+ "提升子弹伤害buff, ",
+ Arg1 = "(int)伤害增加类型: 1:具体伤害, 2:百分比伤害",
+ Arg2 = "(float)增益伤害值"
+)]
public class Buff_BulletDamage : BuffFragment
{
private int _type;
private float _value;
- public override void InitParam(float arg1, float arg2)
+ public override void InitParam(JsonElement[] arg)
{
- _type = (int)arg1;
- _value = arg2;
+ _type = arg[0].GetInt32();
+ _value = arg[1].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDeviationAngle.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDeviationAngle.cs
index fe3f7bb..a483376 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDeviationAngle.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDeviationAngle.cs
@@ -1,19 +1,23 @@
-[BuffFragment("BulletDeviationAngle",
- "子弹偏移角度 buff, " +
- "参数‘1’为增加子弹偏移角度下限, " +
- "参数‘2’为增加子弹偏移角度上限, 单位角度制, 会从上限和下限随机抽取值")]
+using System.Text.Json;
+
+[BuffFragment(
+ "BulletDeviationAngle",
+ "子弹偏移角度 buff, 单位角度制, 会从上限和下限随机抽取值",
+ Arg1 = "(float)增加子弹偏移角度下限",
+ Arg2 = "(float)增加子弹偏移角度上限"
+)]
public class Buff_BulletDeviationAngle : BuffFragment
{
private float _min;
private float _max;
-
- public override void InitParam(float arg1, float arg2)
+
+ public override void InitParam(JsonElement[] args)
{
- _min = arg1;
- _max = arg2;
+ _min = args[0].GetSingle();
+ _max = args[1].GetSingle();
}
-
+
public override void OnPickUpItem()
{
Role.RoleState.CalcBulletDeviationAngleEvent += CalcBulletDeviationAngleEvent;
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDistance.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDistance.cs
index 595022b..e18f3b4 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDistance.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletDistance.cs
@@ -1,17 +1,21 @@
-[BuffFragment("BulletDistance",
- "子弹射程 buff, " +
- "参数‘1’为射程增加类型: 1:具体射程, 2:百分比射程(小数), " +
- "参数‘2’为子弹增加的射程值")]
+using System.Text.Json;
+
+[BuffFragment(
+ "BulletDistance",
+ "子弹射程 buff, ",
+ Arg1 = "(int)子弹射程增加类型: 1:具体射程, 2:百分比射程",
+ Arg2 = "(float)子弹增加的射程值"
+)]
public class Buff_BulletDistance : BuffFragment
{
private int _type;
private float _value;
- public override void InitParam(float arg1, float arg2)
+ public override void InitParam(JsonElement[] args)
{
- _type = (int)arg1;
- _value = arg2;
+ _type = args[0].GetInt32();
+ _value = args[1].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletPenetration.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletPenetration.cs
index eb0732f..1b1d70f 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletPenetration.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletPenetration.cs
@@ -1,12 +1,18 @@
-[BuffFragment("BulletPenetration", "子弹穿透次数 buff, 参数‘1’为增加的穿透次数")]
+using System.Text.Json;
+
+[BuffFragment(
+ "BulletPenetration",
+ "子弹穿透次数 buff",
+ Arg1 = "(int)子弹增加的穿透次数"
+)]
public class Buff_BulletPenetration : BuffFragment
{
private int _value;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] args)
{
- _value = (int)arg1;
+ _value = args[0].GetInt32();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletRepel.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletRepel.cs
index 9e711f6..6033fbf 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletRepel.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletRepel.cs
@@ -1,18 +1,21 @@
+using System.Text.Json;
using Godot;
-[BuffFragment("BulletRepel",
- "子弹击退 buff, " +
- "参数‘1’为击退增加类型: 1:具体击退值, 2:百分比击退值(小数), " +
- "参数‘2’为子弹增加的击退值")]
+[BuffFragment(
+ "BulletRepel",
+ "子弹击退 buff, ",
+ Arg1 = "(int)击退增加类型: 1:具体击退值, 2:百分比击退值",
+ Arg2 = "(float)子弹增加的击退值"
+)]
public class Buff_BulletRepel : BuffFragment
{
private int _type;
private float _value;
- public override void InitParam(float arg1, float arg2)
+ public override void InitParam(JsonElement[] args)
{
- _type = (int)arg1;
- _value = arg2;
+ _type = args[0].GetInt32();
+ _value = args[1].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletSpeed.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletSpeed.cs
index a8c9ffa..7831ca9 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletSpeed.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_BulletSpeed.cs
@@ -1,17 +1,21 @@
-[BuffFragment("BulletSpeed",
- "子弹速度 buff, " +
- "参数‘1’为射速增加类型: 1:具体射速, 2:百分比射速(小数), " +
- "参数‘2’为子弹增加的射速值")]
+using System.Text.Json;
+
+[BuffFragment(
+ "BulletSpeed",
+ "子弹速度 buff, ",
+ Arg1 = "(int)子弹速度增加类型: 1:具体速度, 2:百分比速度",
+ Arg2 = "(float)子弹增加的速度值"
+)]
public class Buff_BulletSpeed : BuffFragment
{
private int _type;
private float _value;
- public override void InitParam(float arg1, float arg2)
+ public override void InitParam(JsonElement[] args)
{
- _type = (int)arg1;
- _value = arg2;
+ _type = args[0].GetInt32();
+ _value = args[1].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_GetGold.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_GetGold.cs
index d3cff87..bb004d2 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_GetGold.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_GetGold.cs
@@ -1,18 +1,22 @@
+using System.Text.Json;
using Godot;
-[BuffFragment("GetGold", "计算获取的金币buff, " +
- "参数‘1’为金币数量添加类型, 1: 具体数量, 2:百分比(小数), " +
- "参数‘2’为增加金币的数量值")]
+[BuffFragment(
+ "GetGold",
+ "计算获取的金币buff, ",
+ Arg1 = "(int)金币数量添加类型, 1: 具体数量, 2:百分比",
+ Arg2 = "(float)增加金币的数量值"
+)]
public class Buff_GetGold : BuffFragment
{
private int _type;
private float _value;
- public override void InitParam(float arg1, float arg2)
+ public override void InitParam(JsonElement[] args)
{
- _type = (int)arg1;
- _value = arg2;
+ _type = args[0].GetInt32();
+ _value = args[1].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_MaxHp.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_MaxHp.cs
index 8e7a107..292926f 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_MaxHp.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_MaxHp.cs
@@ -1,15 +1,20 @@
using System.Collections.Generic;
+using System.Text.Json;
-[BuffFragment("MaxHp", "血量上限 buff, 参数‘1’为血量上限值")]
+[BuffFragment(
+ "MaxHp",
+ "增加血量上限 buff",
+ Arg1 = "(int)增加血量上限值"
+)]
public class Buff_MaxHp : BuffFragment
{
private List _cacheId = new List();
private int _maxHp;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] args)
{
- _maxHp = (int)arg1;
+ _maxHp = args[0].GetInt32();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_MaxShield.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_MaxShield.cs
index 20ade21..805c140 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_MaxShield.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_MaxShield.cs
@@ -1,15 +1,20 @@
using System.Collections.Generic;
+using System.Text.Json;
-[BuffFragment("MaxShield", "护盾上限buff, 参数‘1’为护盾上限")]
+[BuffFragment(
+ "MaxShield",
+ "增加护盾上限buff",
+ Arg1 = "(int)增加的护盾上限值"
+)]
public class Buff_MaxShield : BuffFragment
{
private List _cacheId = new List();
private int _maxShield;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] args)
{
- _maxShield = (int)arg1;
+ _maxShield = args[0].GetInt32();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_MoveSpeed.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_MoveSpeed.cs
index e528c47..53b0219 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_MoveSpeed.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_MoveSpeed.cs
@@ -1,12 +1,18 @@
-[BuffFragment("MoveSpeed", "移速 buff, 参数‘1’为移动速度值")]
+using System.Text.Json;
+
+[BuffFragment(
+ "MoveSpeed",
+ "增加移速 buff",
+ Arg1 = "(float)增加的移动速度值"
+)]
public class Buff_MoveSpeed : BuffFragment
{
private float _moveSpeed;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] args)
{
- _moveSpeed = arg1;
+ _moveSpeed = args[0].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_OffsetInjury.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_OffsetInjury.cs
index 008abe0..4f5912e 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_OffsetInjury.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_OffsetInjury.cs
@@ -1,12 +1,18 @@
-[BuffFragment("OffsetInjury", "受伤时有概率抵消伤害的buff, 参数‘1’为抵消伤害概率百分比(小数)")]
+using System.Text.Json;
+
+[BuffFragment(
+ "OffsetInjury",
+ "受伤时有概率抵消伤害的 buff",
+ Arg1 = "(float)抵消伤害概率百分比"
+)]
public class Buff_OffsetInjury : BuffFragment
{
private float _value;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] args)
{
- _value = arg1;
+ _value = args[0].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_RandomBulletSpeed.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_RandomBulletSpeed.cs
index c2d1ab0..c625f0f 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_RandomBulletSpeed.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_RandomBulletSpeed.cs
@@ -1,17 +1,21 @@
-[BuffFragment("RandomBulletSpeed",
- "子弹增加随机速度 buff, " +
- "参数‘1’为增加子弹速度下限, " +
- "参数‘2’为增加子弹速度上限, 会从上限和下限随机抽取值")]
+using System.Text.Json;
+
+[BuffFragment(
+ "RandomBulletSpeed",
+ "子弹增加随机速度 buff, 会从上限和下限随机抽取值",
+ Arg1 = "(float)增加子弹速度下限",
+ Arg2 = "(float)增加子弹速度上限"
+)]
public class Buff_RandomBulletSpeed : BuffFragment
{
private float _min;
private float _max;
- public override void InitParam(float arg1, float arg2)
+ public override void InitParam(JsonElement[] args)
{
- _min = arg1;
- _max = arg2;
+ _min = args[0].GetSingle();
+ _max = args[1].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_Scattering.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_Scattering.cs
index edee925..dfd6ee8 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_Scattering.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_Scattering.cs
@@ -1,14 +1,19 @@
+using System.Text.Json;
using Godot;
-[BuffFragment("Scattering", "提高武器精准度buff, 参数‘1’为提升的精准度百分比值(小数)")]
+[BuffFragment(
+ "Scattering",
+ "提高武器精准度 buff",
+ Arg1 = "(float)精准度提升百分比值"
+)]
public class Buff_Scattering : BuffFragment
{
private float _value;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] args)
{
- _value = arg1;
+ _value = args[0].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_ShieldRecoveryTime.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_ShieldRecoveryTime.cs
index 88bb3df..fd86b85 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_ShieldRecoveryTime.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_ShieldRecoveryTime.cs
@@ -1,12 +1,18 @@
-[BuffFragment("ShieldRecoveryTime", "单格护盾减少的恢复时间, 参数‘1’单位: 秒")]
+using System.Text.Json;
+
+[BuffFragment(
+ "ShieldRecoveryTime",
+ "单格护盾减少的恢复时间, 单位: 秒",
+ Arg1 = "(float)单格护盾减少的恢复时间"
+)]
public class Buff_ShieldRecoveryTime : BuffFragment
{
private float _time;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] args)
{
- _time = arg1;
+ _time = args[0].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_WeaponCapacity.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_WeaponCapacity.cs
index 10b986a..44357fc 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_WeaponCapacity.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_WeaponCapacity.cs
@@ -1,12 +1,18 @@
-[BuffFragment("WeaponCapacity", "武器背包容量 buff, 参数‘1’为武器背包增加的容量")]
+using System.Text.Json;
+
+[BuffFragment(
+ "WeaponCapacity",
+ "武器背包容量 buff",
+ Arg1 = "(int)武器背包增加的容量"
+)]
public class Buff_WeaponCapacity : BuffFragment
{
private int _value;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] args)
{
- _value = (int)arg1;
+ _value = args[0].GetInt32();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/buff/Buff_WoundedInvincibleTime.cs b/DungeonShooting_Godot/src/game/buff/buff/Buff_WoundedInvincibleTime.cs
index 27b84ca..bca7e6d 100644
--- a/DungeonShooting_Godot/src/game/buff/buff/Buff_WoundedInvincibleTime.cs
+++ b/DungeonShooting_Godot/src/game/buff/buff/Buff_WoundedInvincibleTime.cs
@@ -1,12 +1,18 @@
-[BuffFragment("WoundedInvincibleTime", "延长无敌时间buff, 参数‘1’为延长时间, 单位秒")]
+using System.Text.Json;
+
+[BuffFragment(
+ "WoundedInvincibleTime",
+ "延长无敌时间 buff, 单位秒",
+ Arg1 = "(float)延长时间"
+)]
public class Buff_WoundedInvincibleTime : BuffFragment
{
private float _time;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] args)
{
- _time = arg1;
+ _time = args[0].GetSingle();
}
public override void OnPickUpItem()
diff --git a/DungeonShooting_Godot/src/game/buff/charge/Cha_EnterRoom.cs b/DungeonShooting_Godot/src/game/buff/charge/Cha_EnterRoom.cs
new file mode 100644
index 0000000..8745443
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/buff/charge/Cha_EnterRoom.cs
@@ -0,0 +1,43 @@
+
+using System.Text.Json;
+
+[ChargeFragment(
+ "EnterRoom",
+ "玩家第一次进入某个房间充能, 该条充能件仅对玩家生效",
+ Arg1 = "(float)充能量, 范围内0-1"
+)]
+public class Cha_EnterRoom : ChargeFragment
+{
+ private float _value = 0.2f;
+
+ public override void InitParam(JsonElement[] args)
+ {
+ _value = args[0].GetSingle();
+ }
+
+ public override void OnUse()
+ {
+ Master.ChargeProgress = 0;
+ }
+
+ public override void OnPickUpItem()
+ {
+ if (Role is Player player)
+ {
+ player.OnFirstEnterRoomEvent += OnFirstEnterRoom;
+ }
+ }
+
+ public override void OnRemoveItem()
+ {
+ if (Role is Player player)
+ {
+ player.OnFirstEnterRoomEvent -= OnFirstEnterRoom;
+ }
+ }
+
+ private void OnFirstEnterRoom(RoomInfo roomInfo)
+ {
+ Master.ChargeProgress += _value;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/charge/Cha_Hurt.cs b/DungeonShooting_Godot/src/game/buff/charge/Cha_Hurt.cs
index 36c7885..4f3f874 100644
--- a/DungeonShooting_Godot/src/game/buff/charge/Cha_Hurt.cs
+++ b/DungeonShooting_Godot/src/game/buff/charge/Cha_Hurt.cs
@@ -1,13 +1,18 @@
-[ChargeFragment("Hurt",
- "造成伤害充能, 参数1为充满能量需要造成的伤害值")]
+using System.Text.Json;
+
+[ChargeFragment(
+ "Hurt",
+ "造成伤害充能",
+ Arg1 = "(int)充满能量需要造成的伤害值"
+)]
public class Cha_Hurt : ChargeFragment
{
private int _value = 100;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] arg)
{
- _value = (int)arg1;
+ _value = arg[0].GetInt32();
}
public override void OnUse()
diff --git a/DungeonShooting_Godot/src/game/buff/condition/Cond_AmmoFull.cs b/DungeonShooting_Godot/src/game/buff/condition/Cond_AmmoFull.cs
index 189f9e3..f848878 100644
--- a/DungeonShooting_Godot/src/game/buff/condition/Cond_AmmoFull.cs
+++ b/DungeonShooting_Godot/src/game/buff/condition/Cond_AmmoFull.cs
@@ -1,14 +1,18 @@
-[ConditionFragment("AmmoFull",
- "判断当前武器弹药状态, " +
- "参数1可选值: 0:判断非满弹药, 1:判断满弹药")]
+using System.Text.Json;
+
+[ConditionFragment(
+ "AmmoFull",
+ "判断当前武器弹药状态, ",
+ Arg1 = "(boolean)是否判断满弹药"
+)]
public class Cond_AmmoFull : ConditionFragment
{
- private int _type;
+ private bool _type;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] arg)
{
- _type = (int)arg1;
+ _type = arg[0].GetBoolean();
}
public override bool OnCheckUse()
@@ -17,7 +21,7 @@
{
return false;
}
- if (_type == 0)
+ if (_type)
{
return !Role.WeaponPack.ActiveItem.IsAmmoFull();
}
diff --git a/DungeonShooting_Godot/src/game/buff/condition/Cond_Gold.cs b/DungeonShooting_Godot/src/game/buff/condition/Cond_Gold.cs
new file mode 100644
index 0000000..e012c4c
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/buff/condition/Cond_Gold.cs
@@ -0,0 +1,38 @@
+
+using System.Text.Json;
+
+[ConditionFragment(
+ "Gold",
+ "判断金币数量, ",
+ Arg1 = "(string)判断条件符号, 分别为: >, <, =, >=, <=",
+ Arg2 = "(int)比较的值"
+)]
+public class Cond_Gold : ConditionFragment
+{
+ private string _symbol;
+ private int _value;
+ public override void InitParam(JsonElement[] args)
+ {
+ _symbol = args[0].GetString();
+ _value = args[1].GetInt32();
+ }
+
+ public override bool OnCheckUse()
+ {
+ switch (_symbol)
+ {
+ case ">":
+ return Role.RoleState.Gold > _value;
+ case "<":
+ return Role.RoleState.Gold < _value;
+ case "=":
+ return Role.RoleState.Gold == _value;
+ case ">=":
+ return Role.RoleState.Gold >= _value;
+ case "<=":
+ return Role.RoleState.Gold <= _value;
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/condition/Cond_Hp.cs b/DungeonShooting_Godot/src/game/buff/condition/Cond_Hp.cs
new file mode 100644
index 0000000..fe93558
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/buff/condition/Cond_Hp.cs
@@ -0,0 +1,37 @@
+using System.Text.Json;
+
+[ConditionFragment(
+ "Hp",
+ "判断血量, ",
+ Arg1 = "(string)判断条件符号, 分别为: >, <, =, >=, <=",
+ Arg2 = "(int)比较的值"
+)]
+public class Cond_Hp : ConditionFragment
+{
+ private string _symbol;
+ private int _value;
+ public override void InitParam(JsonElement[] args)
+ {
+ _symbol = args[0].GetString();
+ _value = args[1].GetInt32();
+ }
+
+ public override bool OnCheckUse()
+ {
+ switch (_symbol)
+ {
+ case ">":
+ return Role.Hp > _value;
+ case "<":
+ return Role.Hp < _value;
+ case "=":
+ return Role.Hp == _value;
+ case ">=":
+ return Role.Hp >= _value;
+ case "<=":
+ return Role.Hp <= _value;
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/condition/Cond_HpFull.cs b/DungeonShooting_Godot/src/game/buff/condition/Cond_HpFull.cs
index a6ff375..851940e 100644
--- a/DungeonShooting_Godot/src/game/buff/condition/Cond_HpFull.cs
+++ b/DungeonShooting_Godot/src/game/buff/condition/Cond_HpFull.cs
@@ -1,19 +1,23 @@
-[ConditionFragment("HpFull",
- "判断满血状态, " +
- "参数1可选值: 0:判断非满血, 1:判断满血")]
+using System.Text.Json;
+
+[ConditionFragment(
+ "HpFull",
+ "判断满血状态, ",
+ Arg1 = "(boolean)判断非满血"
+)]
public class Cond_HpFull : ConditionFragment
{
- private int _type;
+ private bool _type;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] arg)
{
- _type = (int)arg1;
+ _type = arg[0].GetBoolean();
}
public override bool OnCheckUse()
{
- if (_type == 0)
+ if (_type)
{
return !Role.IsHpFull();
}
diff --git a/DungeonShooting_Godot/src/game/buff/effect/Eff_AreaTrigger.cs b/DungeonShooting_Godot/src/game/buff/effect/Eff_AreaTrigger.cs
index 69c0e16..f513dc4 100644
--- a/DungeonShooting_Godot/src/game/buff/effect/Eff_AreaTrigger.cs
+++ b/DungeonShooting_Godot/src/game/buff/effect/Eff_AreaTrigger.cs
@@ -1,10 +1,13 @@
using System.Collections.Generic;
+using System.Text.Json;
using Godot;
-[EffectFragment("AreaTrigger",
- "触发附近地上的武器开火, " +
- "参数1为最大作用半径, ")]
+[EffectFragment(
+ "AreaTrigger",
+ "触发附近地上的武器开火, ",
+ Arg1 = "(int)最大作用半径"
+)]
public class Eff_AreaTrigger : EffectFragment
{
private Prop5003Area _areaNode;
@@ -13,9 +16,9 @@
private int _radius = 250;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] arg)
{
- _radius = (int)arg1;
+ _radius = arg[0].GetInt32();
}
public override void Ready()
diff --git a/DungeonShooting_Godot/src/game/buff/effect/Eff_ChangeHp.cs b/DungeonShooting_Godot/src/game/buff/effect/Eff_ChangeHp.cs
new file mode 100644
index 0000000..13b84b1
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/buff/effect/Eff_ChangeHp.cs
@@ -0,0 +1,22 @@
+
+using System.Text.Json;
+
+[EffectFragment(
+ "ChangeHp",
+ "修改血量",
+ Arg1 = "(int)血量变化的具体值"
+)]
+public class Eff_ChangeHp : EffectFragment
+{
+ private int _value;
+
+ public override void InitParam(JsonElement[] arg)
+ {
+ _value = arg[0].GetInt32();
+ }
+
+ public override void OnUse()
+ {
+ Role.Hp += _value;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/effect/Eff_GetGold.cs b/DungeonShooting_Godot/src/game/buff/effect/Eff_GetGold.cs
new file mode 100644
index 0000000..0a28d6e
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/buff/effect/Eff_GetGold.cs
@@ -0,0 +1,23 @@
+
+
+using System.Text.Json;
+using Godot;
+
+[EffectFragment(
+ "GetGold",
+ "获得金币",
+ Arg1 = "(int)金币的值"
+)]
+public class Eff_GetGold : EffectFragment
+{
+ private int _value;
+ public override void InitParam(JsonElement[] args)
+ {
+ _value = args[0].GetInt32();
+ }
+
+ public override void OnUse()
+ {
+ Gold.CreateGold(Role.Position, _value);
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/effect/Eff_Hp.cs b/DungeonShooting_Godot/src/game/buff/effect/Eff_Hp.cs
deleted file mode 100644
index 1dc96e6..0000000
--- a/DungeonShooting_Godot/src/game/buff/effect/Eff_Hp.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-
-[EffectFragment("Hp", "修改血量, 参数1为血量变化的具体值")]
-public class Eff_Hp : EffectFragment
-{
- private int _value;
-
- public override void InitParam(float arg1)
- {
- _value = (int) arg1;
- }
-
- public override void OnUse()
- {
- Role.Hp += _value;
- }
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/effect/Eff_PiggyBank.cs b/DungeonShooting_Godot/src/game/buff/effect/Eff_PiggyBank.cs
index 1e80544..0f40b2e 100644
--- a/DungeonShooting_Godot/src/game/buff/effect/Eff_PiggyBank.cs
+++ b/DungeonShooting_Godot/src/game/buff/effect/Eff_PiggyBank.cs
@@ -1,16 +1,21 @@
+using System.Text.Json;
using Godot;
-[EffectFragment("PiggyBank", "存钱罐, 使用后返还存入的金币, 参数1为返还金币的倍率(小数)")]
+[EffectFragment(
+ "PiggyBank",
+ "存钱罐, 使用后返还存入的金币",
+ Arg1 = "(float)返还金币的倍率, 范围0-1"
+)]
public class Eff_PiggyBank : EffectFragment
{
private float _value;
//当前存入的金币数量
private float _currValue;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] arg)
{
- _value = arg1;
+ _value = arg[0].GetSingle();
}
public override bool OnCheckUse()
@@ -20,17 +25,7 @@
public override void OnUse()
{
- var goldList = Utils.GetGoldList(Mathf.FloorToInt(_currValue * _value));
- foreach (var id in goldList)
- {
- var o = ObjectManager.GetActivityObject(id);
- o.Position = Role.Position;
- o.Throw(0,
- Utils.Random.RandomRangeInt(50, 110),
- new Vector2(Utils.Random.RandomRangeInt(-20, 20), Utils.Random.RandomRangeInt(-20, 20)),
- 0
- );
- }
+ Gold.CreateGold(Role.Position, Mathf.FloorToInt(_currValue * _value));
_currValue = 0;
}
diff --git a/DungeonShooting_Godot/src/game/buff/effect/Eff_SwapWeapon.cs b/DungeonShooting_Godot/src/game/buff/effect/Eff_SwapWeapon.cs
new file mode 100644
index 0000000..d2b95ae
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/buff/effect/Eff_SwapWeapon.cs
@@ -0,0 +1,58 @@
+using System.Collections.Generic;
+using System.Text.Json;
+
+[EffectFragment(
+ "SwapWeapon",
+ "随机选择房间内的一个手持武器的敌人, 交换你们手中的武器"
+)]
+public class Eff_SwapWeapon : EffectFragment
+{
+ public override void InitParam(JsonElement[] args)
+ {
+
+ }
+
+ public override void OnUse()
+ {
+ var list = new List();
+ foreach (var enemy in Master.World.Enemy_InstanceList)
+ {
+ if (enemy.WeaponPack.ActiveItem != null)
+ {
+ list.Add(enemy);
+
+ }
+ }
+
+ var targetEnemy = Utils.Random.RandomChoose(list);
+ if (targetEnemy != null)
+ {
+ var enemyWeapon = targetEnemy.WeaponPack.ActiveItem;
+
+ var selfWeapon = Role.WeaponPack.ActiveItem;
+ targetEnemy.RemoveWeapon(enemyWeapon.PackageIndex);
+ Role.RemoveWeapon(selfWeapon.PackageIndex);
+
+ targetEnemy.PickUpWeapon(selfWeapon);
+ Role.PickUpWeapon(enemyWeapon);
+ }
+ }
+
+ public override bool OnCheckUse()
+ {
+ if (Role.World == null || Role.WeaponPack.ActiveItem == null)
+ {
+ return false;
+ }
+
+ foreach (var enemy in Master.World.Enemy_InstanceList)
+ {
+ if (enemy.WeaponPack.ActiveItem != null)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/buff/effect/Eff_TotalAmmo.cs b/DungeonShooting_Godot/src/game/buff/effect/Eff_TotalAmmo.cs
index 6984e62..66671f7 100644
--- a/DungeonShooting_Godot/src/game/buff/effect/Eff_TotalAmmo.cs
+++ b/DungeonShooting_Godot/src/game/buff/effect/Eff_TotalAmmo.cs
@@ -1,16 +1,23 @@
-[EffectFragment("TotalAmmo",
- "修改武器总弹药量, " +
- "参数1(选填)为弹药变化的具体值, 如果不传则表示补满弹药")]
+using System.Text.Json;
+
+[EffectFragment(
+ "TotalAmmo",
+ "修改武器总弹药量, ",
+ Arg1 = "(int|null)弹药变化的具体值, 如果不传则表示补满弹药"
+)]
public class Eff_TotalAmmo : EffectFragment
{
private bool _initParam = false;
private int _value;
- public override void InitParam(float arg1)
+ public override void InitParam(JsonElement[] args)
{
- _initParam = true;
- _value = (int) arg1;
+ if (args.Length > 0)
+ {
+ _initParam = true;
+ _value = args[0].GetInt32();
+ }
}
public override void OnUse()
diff --git a/DungeonShooting_Godot/src/game/buff/effect/Eff_UseGold.cs b/DungeonShooting_Godot/src/game/buff/effect/Eff_UseGold.cs
new file mode 100644
index 0000000..70eeda0
--- /dev/null
+++ b/DungeonShooting_Godot/src/game/buff/effect/Eff_UseGold.cs
@@ -0,0 +1,22 @@
+
+
+using System.Text.Json;
+
+[EffectFragment(
+ "UseGold",
+ "使用金币",
+ Arg1 = "(int)消耗金币的值"
+)]
+public class Eff_UseGold : EffectFragment
+{
+ private int _value;
+ public override void InitParam(JsonElement[] args)
+ {
+ _value = args[0].GetInt32();
+ }
+
+ public override void OnUse()
+ {
+ Role.UseGold(_value);
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/data/PropFragmentInfo.cs b/DungeonShooting_Godot/src/game/data/PropFragmentInfo.cs
index 578ad43..8c1fd1b 100644
--- a/DungeonShooting_Godot/src/game/data/PropFragmentInfo.cs
+++ b/DungeonShooting_Godot/src/game/data/PropFragmentInfo.cs
@@ -1,11 +1,31 @@
using System;
+using System.Collections.Generic;
///
/// 道具逻辑片段数据
///
public class PropFragmentInfo
{
+ public class PropFragmentArgInfo
+ {
+ ///
+ /// 参数索引
+ ///
+ public int ArgIndex;
+
+ ///
+ /// 参数描述
+ ///
+ public string Description;
+
+ public PropFragmentArgInfo(int argIndex, string description)
+ {
+ ArgIndex = argIndex;
+ Description = description;
+ }
+ }
+
///
/// buff 名称
///
@@ -21,10 +41,48 @@
///
public Type Type;
- public PropFragmentInfo(string name, string description, Type type)
+ ///
+ /// buff 参数信息
+ ///
+ public List ArgInfos = new List();
+
+ public PropFragmentInfo(FragmentAttribute attribute, Type type)
{
- Name = name;
- Description = description;
+ Name = attribute.Name;
+ Description = attribute.Description;
Type = type;
+
+ if (attribute.Arg1 != null)
+ {
+ ArgInfos.Add(new PropFragmentArgInfo(1, attribute.Arg1));
+ }
+ if (attribute.Arg2 != null)
+ {
+ ArgInfos.Add(new PropFragmentArgInfo(2, attribute.Arg2));
+ }
+ if (attribute.Arg3 != null)
+ {
+ ArgInfos.Add(new PropFragmentArgInfo(3, attribute.Arg3));
+ }
+ if (attribute.Arg4 != null)
+ {
+ ArgInfos.Add(new PropFragmentArgInfo(4, attribute.Arg4));
+ }
+ if (attribute.Arg5 != null)
+ {
+ ArgInfos.Add(new PropFragmentArgInfo(5, attribute.Arg5));
+ }
+ if (attribute.Arg6 != null)
+ {
+ ArgInfos.Add(new PropFragmentArgInfo(6, attribute.Arg6));
+ }
+ if (attribute.Arg7 != null)
+ {
+ ArgInfos.Add(new PropFragmentArgInfo(7, attribute.Arg7));
+ }
+ if (attribute.Arg8 != null)
+ {
+ ArgInfos.Add(new PropFragmentArgInfo(8, attribute.Arg8));
+ }
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/manager/EditorPlayManager.cs b/DungeonShooting_Godot/src/game/manager/EditorPlayManager.cs
index 1fdf611..79d0bf8 100644
--- a/DungeonShooting_Godot/src/game/manager/EditorPlayManager.cs
+++ b/DungeonShooting_Godot/src/game/manager/EditorPlayManager.cs
@@ -10,6 +10,9 @@
private static DungeonConfig _config;
+ ///
+ /// 地牢编辑器中的播放按钮
+ ///
public static void Play(UiBase prevUi)
{
if (IsPlay)
@@ -22,7 +25,39 @@
_config.GroupName = EditorTileMapManager.SelectDungeonGroup.GroupName;
_config.DesignatedType = EditorTileMapManager.SelectRoom.RoomInfo.RoomType;
_config.DesignatedRoom = new List();
- _config.DesignatedRoom.Add(EditorTileMapManager.SelectRoom);
+
+ if (_config.DesignatedType == DungeonRoomType.Inlet) //初始房间
+ {
+ var dungeonRoomGroup = GameApplication.Instance.RoomConfig[_config.GroupName];
+ _config.DesignatedRoom.Add(EditorTileMapManager.SelectRoom);
+ //随机选择战斗房间
+ for (var i = 0; i < 5; i++)
+ {
+ _config.DesignatedRoom.Add(Utils.Random.RandomChoose(dungeonRoomGroup.BattleList));
+ }
+ //结束房间
+ _config.DesignatedRoom.Add(Utils.Random.RandomChoose(dungeonRoomGroup.OutletList));
+ }
+ else if (_config.DesignatedType == DungeonRoomType.Outlet) //结束房间
+ {
+ var dungeonRoomGroup = GameApplication.Instance.RoomConfig[_config.GroupName];
+ //随机选择初始房间
+ _config.DesignatedRoom.Add(Utils.Random.RandomChoose(dungeonRoomGroup.InletList));
+ _config.DesignatedRoom.Add(EditorTileMapManager.SelectRoom);
+ }
+ else //其他类型房间
+ {
+ var dungeonRoomGroup = GameApplication.Instance.RoomConfig[_config.GroupName];
+ //随机选择初始房间
+ _config.DesignatedRoom.Add(Utils.Random.RandomChoose(dungeonRoomGroup.InletList));
+ for (var i = 0; i < 5; i++)
+ {
+ _config.DesignatedRoom.Add(EditorTileMapManager.SelectRoom);
+ }
+ //结束房间
+ _config.DesignatedRoom.Add(Utils.Random.RandomChoose(dungeonRoomGroup.OutletList));
+ }
+
UiManager.Open_Loading();
GameApplication.Instance.DungeonManager.EditorPlayDungeon(prevUi, _config, () =>
{
diff --git a/DungeonShooting_Godot/src/game/manager/PropFragmentRegister.cs b/DungeonShooting_Godot/src/game/manager/PropFragmentRegister.cs
index f13989b..01c18bd 100644
--- a/DungeonShooting_Godot/src/game/manager/PropFragmentRegister.cs
+++ b/DungeonShooting_Godot/src/game/manager/PropFragmentRegister.cs
@@ -47,14 +47,14 @@
var attribute = (BuffFragmentAttribute)type.GetCustomAttribute(typeof(BuffFragmentAttribute), false);
if (attribute != null)
{
- if (BuffFragmentInfos.ContainsKey(attribute.BuffName))
+ if (BuffFragmentInfos.ContainsKey(attribute.Name))
{
- GD.PrintErr($"Buff '{attribute.BuffName}' 重名!");
+ GD.PrintErr($"Buff '{attribute.Name}' 重名!");
continue;
}
- var buffInfo = new PropFragmentInfo(attribute.BuffName, attribute.Description, type);
- BuffFragmentInfos.Add(attribute.BuffName, buffInfo);
+ var buffInfo = new PropFragmentInfo(attribute, type);
+ BuffFragmentInfos.Add(attribute.Name, buffInfo);
}
}
//包含[ConditionAttribute]特性
@@ -65,14 +65,14 @@
var attribute = (ConditionFragmentAttribute)type.GetCustomAttribute(typeof(ConditionFragmentAttribute), false);
if (attribute != null)
{
- if (ConditionFragmentInfos.ContainsKey(attribute.ConditionName))
+ if (ConditionFragmentInfos.ContainsKey(attribute.Name))
{
- GD.PrintErr($"Condition '{attribute.ConditionName}' 重名!");
+ GD.PrintErr($"Condition '{attribute.Name}' 重名!");
continue;
}
- var conditionInfo = new PropFragmentInfo(attribute.ConditionName, attribute.Description, type);
- ConditionFragmentInfos.Add(attribute.ConditionName, conditionInfo);
+ var conditionInfo = new PropFragmentInfo(attribute, type);
+ ConditionFragmentInfos.Add(attribute.Name, conditionInfo);
}
}
//包含[EffectAttribute]特性
@@ -83,14 +83,14 @@
var attribute = (EffectFragmentAttribute)type.GetCustomAttribute(typeof(EffectFragmentAttribute), false);
if (attribute != null)
{
- if (EffectFragmentInfos.ContainsKey(attribute.EffectName))
+ if (EffectFragmentInfos.ContainsKey(attribute.Name))
{
- GD.PrintErr($"Effect '{attribute.EffectName}' 重名!");
+ GD.PrintErr($"Effect '{attribute.Name}' 重名!");
continue;
}
- var effectInfo = new PropFragmentInfo(attribute.EffectName, attribute.Description, type);
- EffectFragmentInfos.Add(attribute.EffectName, effectInfo);
+ var effectInfo = new PropFragmentInfo(attribute, type);
+ EffectFragmentInfos.Add(attribute.Name, effectInfo);
}
}
//包含[ChargeAttribute]特性
@@ -101,14 +101,14 @@
var attribute = (ChargeFragmentAttribute)type.GetCustomAttribute(typeof(ChargeFragmentAttribute), false);
if (attribute != null)
{
- if (ChargeFragmentInfos.ContainsKey(attribute.ChargeName))
+ if (ChargeFragmentInfos.ContainsKey(attribute.Name))
{
- GD.PrintErr($"Charge '{attribute.ChargeName}' 重名!");
+ GD.PrintErr($"Charge '{attribute.Name}' 重名!");
continue;
}
- var chargeInfo = new PropFragmentInfo(attribute.ChargeName, attribute.Description, type);
- ChargeFragmentInfos.Add(attribute.ChargeName, chargeInfo);
+ var chargeInfo = new PropFragmentInfo(attribute, type);
+ ChargeFragmentInfos.Add(attribute.Name, chargeInfo);
}
}
}
diff --git a/DungeonShooting_Godot/src/game/manager/ResourceManager.cs b/DungeonShooting_Godot/src/game/manager/ResourceManager.cs
index 89a8e0d..6df0248 100644
--- a/DungeonShooting_Godot/src/game/manager/ResourceManager.cs
+++ b/DungeonShooting_Godot/src/game/manager/ResourceManager.cs
@@ -186,6 +186,14 @@
{
return LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_BirthMark_png);
}
+ else if (markInfo.SpecialMarkType == SpecialMarkType.Treasure) //宝箱
+ {
+ return LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_BirthMark_png);
+ }
+ else if (markInfo.SpecialMarkType == SpecialMarkType.ShopBoss) //商店老板
+ {
+ return LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_BirthMark_png);
+ }
else if (markInfo.MarkList != null) //普通标记
{
if (markInfo.MarkList.Count > 1) //多个物体
diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
index 795089f..cc681d4 100644
--- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs
+++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
@@ -480,7 +480,7 @@
yield return 0;
//初始房间创建玩家标记
- var playerBirthMark = StartRoomInfo.RoomPreinstall.GetPlayerBirthMark();
+ var playerBirthMark = StartRoomInfo.RoomPreinstall.GetSpecialMark(SpecialMarkType.BirthPoint);
//创建玩家
var player = Player.Current;
diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorMapMark/MapEditorMapMarkPanel.cs b/DungeonShooting_Godot/src/game/ui/mapEditorMapMark/MapEditorMapMarkPanel.cs
index f53ef8e..9c59d27 100644
--- a/DungeonShooting_Godot/src/game/ui/mapEditorMapMark/MapEditorMapMarkPanel.cs
+++ b/DungeonShooting_Godot/src/game/ui/mapEditorMapMark/MapEditorMapMarkPanel.cs
@@ -151,7 +151,12 @@
{
item.InitWaveList();
}
-
+
+ //检测是否创建特殊标记
+ if (!item.CheckSpecialMark(EditorTileMapManager.SelectRoom.RoomInfo.RoomType))
+ {
+ EventManager.EmitEvent(EventEnum.OnTileMapDirty);
+ }
optionButton.AddItem($"{item.Name} ({item.Weight})");
}
diff --git a/DungeonShooting_Godot/src/game/ui/roomUI/ActivePropBarHandler.cs b/DungeonShooting_Godot/src/game/ui/roomUI/ActivePropBarHandler.cs
index f01ec1b..69a2654 100644
--- a/DungeonShooting_Godot/src/game/ui/roomUI/ActivePropBarHandler.cs
+++ b/DungeonShooting_Godot/src/game/ui/roomUI/ActivePropBarHandler.cs
@@ -51,7 +51,7 @@
}
else
{
- _shaderMaterial.SetShaderParameter("schedule", 0.6f);
+ _shaderMaterial.SetShaderParameter("schedule", 0.8f);
}
//冷却