diff --git a/DungeonShooting_Godot/DungeonShooting.csproj b/DungeonShooting_Godot/DungeonShooting.csproj index 97e725f..672ba00 100644 --- a/DungeonShooting_Godot/DungeonShooting.csproj +++ b/DungeonShooting_Godot/DungeonShooting.csproj @@ -1,4 +1,4 @@ - + net7.0 true diff --git a/DungeonShooting_Godot/DungeonShooting.csproj.old b/DungeonShooting_Godot/DungeonShooting.csproj.old index e36028f..97e725f 100644 --- a/DungeonShooting_Godot/DungeonShooting.csproj.old +++ b/DungeonShooting_Godot/DungeonShooting.csproj.old @@ -1,4 +1,4 @@ - + net7.0 true diff --git a/DungeonShooting_Godot/DungeonShooting.csproj.old.1 b/DungeonShooting_Godot/DungeonShooting.csproj.old.1 deleted file mode 100644 index 65ee589..0000000 --- a/DungeonShooting_Godot/DungeonShooting.csproj.old.1 +++ /dev/null @@ -1,11 +0,0 @@ - - - net7.0 - true - - - - - - - \ No newline at end of file diff --git a/DungeonShooting_Godot/DungeonShooting.csproj.old.2 b/DungeonShooting_Godot/DungeonShooting.csproj.old.2 deleted file mode 100644 index 543224c..0000000 --- a/DungeonShooting_Godot/DungeonShooting.csproj.old.2 +++ /dev/null @@ -1,11 +0,0 @@ - - - net7.0 - true - - - - - - - \ No newline at end of file diff --git a/DungeonShooting_Godot/DungeonShooting.csproj.old.3 b/DungeonShooting_Godot/DungeonShooting.csproj.old.3 deleted file mode 100644 index 36c02a1..0000000 --- a/DungeonShooting_Godot/DungeonShooting.csproj.old.3 +++ /dev/null @@ -1,11 +0,0 @@ - - - net7.0 - true - - - - - - - \ No newline at end of file diff --git a/DungeonShooting_Godot/DungeonShooting.sln.DotSettings.user b/DungeonShooting_Godot/DungeonShooting.sln.DotSettings.user index 639eefb..43de714 100644 --- a/DungeonShooting_Godot/DungeonShooting.sln.DotSettings.user +++ b/DungeonShooting_Godot/DungeonShooting.sln.DotSettings.user @@ -2,4 +2,7 @@ WARNING On On - On \ No newline at end of file + On + <SessionState ContinuousTestingMode="0" IsActive="True" Name="解决方案中的所有测试" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <Solution /> +</SessionState> \ No newline at end of file diff --git a/DungeonShooting_Godot/excel/excelFile/ActivityBase.xlsx b/DungeonShooting_Godot/excel/excelFile/ActivityBase.xlsx index 9ba6191..1c0ddcf 100644 --- a/DungeonShooting_Godot/excel/excelFile/ActivityBase.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/ActivityBase.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/ActivityMaterial.xlsx b/DungeonShooting_Godot/excel/excelFile/ActivityMaterial.xlsx index 216f7f6..474fcbe 100644 --- a/DungeonShooting_Godot/excel/excelFile/ActivityMaterial.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/ActivityMaterial.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx b/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx index 9bafc6d..edb6abc 100644 --- a/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/BulletBase.xlsx b/DungeonShooting_Godot/excel/excelFile/BulletBase.xlsx index 9d78f08..0d2d771 100644 --- a/DungeonShooting_Godot/excel/excelFile/BulletBase.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/BulletBase.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/EnemyBase.xlsx b/DungeonShooting_Godot/excel/excelFile/EnemyBase.xlsx new file mode 100644 index 0000000..b3f6cab --- /dev/null +++ b/DungeonShooting_Godot/excel/excelFile/EnemyBase.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/Sound.xlsx b/DungeonShooting_Godot/excel/excelFile/Sound.xlsx index 63764f1..ad0d8fe 100644 --- a/DungeonShooting_Godot/excel/excelFile/Sound.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/Sound.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/WeaponBase.xlsx b/DungeonShooting_Godot/excel/excelFile/WeaponBase.xlsx index 6a85ce0..98e9781 100644 --- a/DungeonShooting_Godot/excel/excelFile/WeaponBase.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/WeaponBase.xlsx Binary files differ diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0001.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0001.tscn index 740c1cd..d372636 100644 --- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0001.tscn +++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0001.tscn @@ -40,10 +40,11 @@ [sub_resource type="RectangleShape2D" id="RectangleShape2D_lcqb8"] size = Vector2(9, 4) -[node name="Bullet0001" type="CharacterBody2D" node_paths=PackedStringArray("CollisionArea", "ShadowSprite", "AnimatedSprite", "Collision")] +[node name="Bullet0001" type="CharacterBody2D" node_paths=PackedStringArray("CollisionArea", "CollisionShape2D", "ShadowSprite", "AnimatedSprite", "Collision")] collision_layer = 2 script = ExtResource("1_3d3df") CollisionArea = NodePath("AnimatedSprite/CollisionArea") +CollisionShape2D = NodePath("AnimatedSprite/CollisionArea/CollisionShape2D") ShadowSprite = NodePath("ShadowSprite") AnimatedSprite = NodePath("AnimatedSprite") Collision = NodePath("Collision") diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0002.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0002.tscn index b1a1813..f2e1881 100644 --- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0002.tscn +++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0002.tscn @@ -32,10 +32,11 @@ [sub_resource type="CircleShape2D" id="CircleShape2D_e2yn3"] radius = 3.0 -[node name="Bullet0002" type="CharacterBody2D" node_paths=PackedStringArray("CollisionArea", "ShadowSprite", "AnimatedSprite", "Collision")] +[node name="Bullet0002" type="CharacterBody2D" node_paths=PackedStringArray("CollisionArea", "CollisionShape2D", "ShadowSprite", "AnimatedSprite", "Collision")] collision_layer = 2 script = ExtResource("1_hepay") CollisionArea = NodePath("AnimatedSprite/CollisionArea") +CollisionShape2D = NodePath("AnimatedSprite/CollisionArea/CollisionShape2D") ShadowSprite = NodePath("ShadowSprite") AnimatedSprite = NodePath("AnimatedSprite") Collision = NodePath("Collision") diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0003.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0003.tscn index 65b9e2a..638f697 100644 --- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0003.tscn +++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0003.tscn @@ -29,10 +29,11 @@ [sub_resource type="RectangleShape2D" id="RectangleShape2D_c0onq"] size = Vector2(6, 3.125) -[node name="Bullet0003" type="CharacterBody2D" node_paths=PackedStringArray("CollisionArea", "ShadowSprite", "AnimatedSprite", "Collision")] +[node name="Bullet0003" type="CharacterBody2D" node_paths=PackedStringArray("CollisionArea", "CollisionShape2D", "ShadowSprite", "AnimatedSprite", "Collision")] collision_layer = 2 script = ExtResource("1_h6lfm") CollisionArea = NodePath("AnimatedSprite/CollisionArea") +CollisionShape2D = NodePath("AnimatedSprite/CollisionArea/CollisionShape2D") ShadowSprite = NodePath("ShadowSprite") AnimatedSprite = NodePath("AnimatedSprite") Collision = NodePath("Collision") diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn index df7551b..294456c 100644 --- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn +++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn @@ -58,11 +58,12 @@ color = Color(0.619608, 0.619608, 0.619608, 1) anim_offset_max = 1.0 -[node name="Bullet0003" type="CharacterBody2D" node_paths=PackedStringArray("Particles", "CollisionArea", "ShadowSprite", "AnimatedSprite", "Collision")] +[node name="Bullet0003" type="CharacterBody2D" node_paths=PackedStringArray("Particles", "CollisionArea", "CollisionShape2D", "ShadowSprite", "AnimatedSprite", "Collision")] collision_layer = 2 script = ExtResource("1_1jbgr") Particles = NodePath("AnimatedSprite/GPUParticles2D") CollisionArea = NodePath("AnimatedSprite/CollisionArea") +CollisionShape2D = NodePath("AnimatedSprite/CollisionArea/CollisionShape2D") ShadowSprite = NodePath("ShadowSprite") AnimatedSprite = NodePath("AnimatedSprite") Collision = NodePath("Collision") diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0005.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0005.tscn new file mode 100644 index 0000000..6b0b303 --- /dev/null +++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0005.tscn @@ -0,0 +1,61 @@ +[gd_scene load_steps=7 format=3 uid="uid://cjgnw37tqiqh7"] + +[ext_resource type="Script" path="res://src/game/activity/bullet/normal/Bullet.cs" id="1_vpnof"] +[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_v0al6"] +[ext_resource type="SpriteFrames" uid="uid://bcnhyin0aufl1" path="res://resource/spriteFrames/bullet/Bullet0003.tres" id="3_8mltb"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_v77gw"] +resource_local_to_scene = true +shader = ExtResource("2_v0al6") +shader_parameter/blend = Color(0, 0, 0, 0.470588) +shader_parameter/schedule = 1.0 +shader_parameter/modulate = Color(1, 1, 1, 1) +shader_parameter/show_outline = false +shader_parameter/outline_color = Color(0, 0, 0, 1) +shader_parameter/outline_rainbow = false +shader_parameter/outline_use_blend = true + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_p0wfd"] +resource_local_to_scene = true +shader = ExtResource("2_v0al6") +shader_parameter/blend = Color(1, 1, 1, 1) +shader_parameter/schedule = 0.0 +shader_parameter/modulate = Color(1, 1, 1, 1) +shader_parameter/show_outline = false +shader_parameter/outline_color = Color(0, 0, 0, 1) +shader_parameter/outline_rainbow = false +shader_parameter/outline_use_blend = true + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_c0onq"] +size = Vector2(6, 3.125) + +[node name="Bullet0005" type="CharacterBody2D" node_paths=PackedStringArray("CollisionArea", "CollisionShape2D", "ShadowSprite", "AnimatedSprite", "Collision")] +collision_layer = 2 +script = ExtResource("1_vpnof") +CollisionArea = NodePath("AnimatedSprite/CollisionArea") +CollisionShape2D = NodePath("AnimatedSprite/CollisionArea/CollisionShape2D") +ShadowSprite = NodePath("ShadowSprite") +AnimatedSprite = NodePath("AnimatedSprite") +Collision = NodePath("Collision") + +[node name="ShadowSprite" type="Sprite2D" parent="."] +z_index = -1 +material = SubResource("ShaderMaterial_v77gw") + +[node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] +modulate = Color(1.6, 1.6, 1.6, 1) +material = SubResource("ShaderMaterial_p0wfd") +sprite_frames = ExtResource("3_8mltb") + +[node name="CollisionArea" type="Area2D" parent="AnimatedSprite"] +visible = false +collision_layer = 0 +collision_mask = 0 +monitorable = false + +[node name="CollisionShape2D" type="CollisionShape2D" parent="AnimatedSprite/CollisionArea"] +position = Vector2(1, 0) +shape = SubResource("RectangleShape2D_c0onq") + +[node name="Collision" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_c0onq") diff --git a/DungeonShooting_Godot/prefab/effect/enemy/EbenyDead0001.tscn b/DungeonShooting_Godot/prefab/effect/enemy/EbenyDead0001.tscn new file mode 100644 index 0000000..d92969c --- /dev/null +++ b/DungeonShooting_Godot/prefab/effect/enemy/EbenyDead0001.tscn @@ -0,0 +1,207 @@ +[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="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/effects/common/Smoke.png" id="4_t55wd"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_s1mj2"] +resource_local_to_scene = true +shader = ExtResource("2_s7bee") +shader_parameter/blend = Color(0, 0, 0, 0.470588) +shader_parameter/schedule = 1.0 +shader_parameter/modulate = Color(1, 1, 1, 1) +shader_parameter/show_outline = true +shader_parameter/outline_color = Color(0, 0, 0, 1) +shader_parameter/outline_rainbow = false +shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_08fn3"] +shader = ExtResource("2_s7bee") +shader_parameter/blend = Color(1, 1, 1, 1) +shader_parameter/schedule = 0.0 +shader_parameter/modulate = Color(1, 1, 1, 1) +shader_parameter/show_outline = false +shader_parameter/outline_color = Color(0, 0, 0, 1) +shader_parameter/outline_rainbow = false +shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 + +[sub_resource type="AtlasTexture" id="AtlasTexture_cldwb"] +atlas = ExtResource("3_uinig") +region = Rect2(0, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ehtnl"] +atlas = ExtResource("3_uinig") +region = Rect2(16, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_j05gd"] +atlas = ExtResource("3_uinig") +region = Rect2(32, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_7el6f"] +atlas = ExtResource("3_uinig") +region = Rect2(48, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_n7sw3"] +atlas = ExtResource("3_uinig") +region = Rect2(64, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_mumsm"] +atlas = ExtResource("3_uinig") +region = Rect2(80, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_gx41d"] +atlas = ExtResource("3_uinig") +region = Rect2(96, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_r4nx1"] +atlas = ExtResource("3_uinig") +region = Rect2(112, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_s8j4o"] +atlas = ExtResource("3_uinig") +region = Rect2(128, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_2svrb"] +atlas = ExtResource("3_uinig") +region = Rect2(144, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_twd5t"] +atlas = ExtResource("3_uinig") +region = Rect2(160, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8w5ka"] +atlas = ExtResource("3_uinig") +region = Rect2(176, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_6iumv"] +atlas = ExtResource("3_uinig") +region = Rect2(192, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_lpilf"] +atlas = ExtResource("3_uinig") +region = Rect2(208, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_n1a5a"] +atlas = ExtResource("3_uinig") +region = Rect2(224, 0, 16, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_q0oeq"] +atlas = ExtResource("3_uinig") +region = Rect2(240, 0, 16, 16) + +[sub_resource type="SpriteFrames" id="SpriteFrames_15g84"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_cldwb") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ehtnl") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_j05gd") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_7el6f") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_n7sw3") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_mumsm") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_gx41d") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_r4nx1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_s8j4o") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_2svrb") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_twd5t") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_8w5ka") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_6iumv") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_lpilf") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_n1a5a") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_q0oeq") +}], +"loop": false, +"name": &"default", +"speed": 5.0 +}] + +[sub_resource type="CircleShape2D" id="CircleShape2D_0xl2q"] +radius = 4.0 + +[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_p3lv8"] +particles_animation = true +particles_anim_h_frames = 3 +particles_anim_v_frames = 1 +particles_anim_loop = false + +[sub_resource type="Gradient" id="Gradient_ryemi"] +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0.537255) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_orgu0"] +gradient = SubResource("Gradient_ryemi") + +[sub_resource type="Curve" id="Curve_21dxk"] +_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.177419, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.0272727), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_rutlp"] +curve = SubResource("Curve_21dxk") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_ku1mm"] +particle_flag_disable_z = true +angle_max = 360.0 +gravity = Vector3(0, 0, 0) +scale_min = 0.4 +scale_max = 1.5 +scale_curve = SubResource("CurveTexture_rutlp") +color = Color(0.811765, 0.0980392, 0.0980392, 0.627451) +color_ramp = SubResource("GradientTexture1D_orgu0") +anim_offset_max = 1.0 + +[node name="Effect0001" type="CharacterBody2D" node_paths=PackedStringArray("ShadowSprite", "AnimatedSprite", "Collision")] +collision_layer = 128 +script = ExtResource("1_1re5v") +ShadowSprite = NodePath("ShadowSprite") +AnimatedSprite = NodePath("AnimatedSprite") +Collision = NodePath("Collision") + +[node name="ShadowSprite" type="Sprite2D" parent="."] +z_index = -1 +material = SubResource("ShaderMaterial_s1mj2") + +[node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] +material = SubResource("ShaderMaterial_08fn3") +sprite_frames = SubResource("SpriteFrames_15g84") + +[node name="Collision" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_0xl2q") + +[node name="GPUParticles2D" type="GPUParticles2D" parent="."] +material = SubResource("CanvasItemMaterial_p3lv8") +emitting = false +process_material = SubResource("ParticleProcessMaterial_ku1mm") +texture = ExtResource("4_t55wd") +fixed_fps = 20 diff --git a/DungeonShooting_Godot/prefab/effect/enemy/EbenyDead0002.tscn b/DungeonShooting_Godot/prefab/effect/enemy/EbenyDead0002.tscn new file mode 100644 index 0000000..92f5491 --- /dev/null +++ b/DungeonShooting_Godot/prefab/effect/enemy/EbenyDead0002.tscn @@ -0,0 +1,129 @@ +[gd_scene load_steps=19 format=3 uid="uid://nfx3lhkdhv6a"] + +[ext_resource type="Script" path="res://src/game/activity/common/AutoFreezeObject.cs" id="1_iop26"] +[ext_resource type="Texture2D" uid="uid://x3tjqgdgp43n" path="res://resource/sprite/role/enemy0002/Enemy0002_dead.png" id="2_3cyjy"] +[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_4hojo"] +[ext_resource type="Texture2D" uid="uid://h7hkgbwj1li" path="res://resource/sprite/effects/common/Smoke.png" id="4_m7xko"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_s1mj2"] +resource_local_to_scene = true +shader = ExtResource("2_4hojo") +shader_parameter/blend = Color(0, 0, 0, 0.470588) +shader_parameter/schedule = 1.0 +shader_parameter/modulate = Color(1, 1, 1, 1) +shader_parameter/show_outline = true +shader_parameter/outline_color = Color(0, 0, 0, 1) +shader_parameter/outline_rainbow = false +shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_08fn3"] +resource_local_to_scene = true +shader = ExtResource("2_4hojo") +shader_parameter/blend = Color(1, 1, 1, 1) +shader_parameter/schedule = 0.0 +shader_parameter/modulate = Color(1, 1, 1, 1) +shader_parameter/show_outline = true +shader_parameter/outline_color = Color(0, 0, 0, 1) +shader_parameter/outline_rainbow = false +shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 + +[sub_resource type="AtlasTexture" id="AtlasTexture_ag5h2"] +atlas = ExtResource("2_3cyjy") +region = Rect2(0, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_toly3"] +atlas = ExtResource("2_3cyjy") +region = Rect2(32, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_bqash"] +atlas = ExtResource("2_3cyjy") +region = Rect2(64, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_lx5fo"] +atlas = ExtResource("2_3cyjy") +region = Rect2(96, 0, 32, 32) + +[sub_resource type="SpriteFrames" id="SpriteFrames_vhsqr"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_ag5h2") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_toly3") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_bqash") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_lx5fo") +}], +"loop": false, +"name": &"dead", +"speed": 5.0 +}] + +[sub_resource type="CircleShape2D" id="CircleShape2D_0xl2q"] +radius = 4.0 + +[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_p3lv8"] +particles_animation = true +particles_anim_h_frames = 3 +particles_anim_v_frames = 1 +particles_anim_loop = false + +[sub_resource type="Gradient" id="Gradient_ryemi"] +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0.537255) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_orgu0"] +gradient = SubResource("Gradient_ryemi") + +[sub_resource type="Curve" id="Curve_21dxk"] +_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.177419, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.0272727), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_rutlp"] +curve = SubResource("Curve_21dxk") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_ku1mm"] +particle_flag_disable_z = true +angle_max = 360.0 +gravity = Vector3(0, 0, 0) +scale_min = 0.4 +scale_max = 1.5 +scale_curve = SubResource("CurveTexture_rutlp") +color = Color(0.811765, 0.0980392, 0.0980392, 0.627451) +color_ramp = SubResource("GradientTexture1D_orgu0") +anim_offset_max = 1.0 + +[node name="Effect0002" type="CharacterBody2D" node_paths=PackedStringArray("ShadowSprite", "AnimatedSprite", "Collision")] +collision_layer = 128 +script = ExtResource("1_iop26") +AnimationName = "dead" +AutoToGrey = true +ShadowSprite = NodePath("ShadowSprite") +AnimatedSprite = NodePath("AnimatedSprite") +Collision = NodePath("Collision") +ThrowCollisionSize = Vector2(14, 14) + +[node name="ShadowSprite" type="Sprite2D" parent="."] +z_index = -1 +material = SubResource("ShaderMaterial_s1mj2") + +[node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] +material = SubResource("ShaderMaterial_08fn3") +sprite_frames = SubResource("SpriteFrames_vhsqr") +animation = &"dead" +offset = Vector2(0, -9) + +[node name="Collision" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_0xl2q") + +[node name="GPUParticles2D" type="GPUParticles2D" parent="."] +material = SubResource("CanvasItemMaterial_p3lv8") +emitting = false +process_material = SubResource("ParticleProcessMaterial_ku1mm") +texture = ExtResource("4_m7xko") +fixed_fps = 20 diff --git a/DungeonShooting_Godot/prefab/effect/enemy/Effect0001.tscn b/DungeonShooting_Godot/prefab/effect/enemy/Effect0001.tscn deleted file mode 100644 index 1dcd443..0000000 --- a/DungeonShooting_Godot/prefab/effect/enemy/Effect0001.tscn +++ /dev/null @@ -1,205 +0,0 @@ -[gd_scene load_steps=31 format=3 uid="uid://pr88a1phtxgb"] - -[ext_resource type="Script" path="res://src/game/effects/enemy/EnemyDebris.cs" id="1_ttosm"] -[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_h62s7"] -[ext_resource type="Texture2D" uid="uid://cn64eauvwx1uj" path="res://resource/sprite/role/enemy0001/enemy0001_Debris.png" id="3_6ewaj"] -[ext_resource type="Texture2D" uid="uid://h7hkgbwj1li" path="res://resource/sprite/effects/common/Smoke.png" id="4_wu0t6"] - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_s1mj2"] -resource_local_to_scene = true -shader = ExtResource("2_h62s7") -shader_parameter/blend = Color(0, 0, 0, 0.470588) -shader_parameter/schedule = 1.0 -shader_parameter/modulate = Color(1, 1, 1, 1) -shader_parameter/show_outline = true -shader_parameter/outline_color = Color(0, 0, 0, 1) -shader_parameter/outline_rainbow = false -shader_parameter/outline_use_blend = true - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_08fn3"] -shader = ExtResource("2_h62s7") -shader_parameter/blend = Color(1, 1, 1, 1) -shader_parameter/schedule = 0.0 -shader_parameter/modulate = Color(1, 1, 1, 1) -shader_parameter/show_outline = false -shader_parameter/outline_color = Color(0, 0, 0, 1) -shader_parameter/outline_rainbow = false -shader_parameter/outline_use_blend = true - -[sub_resource type="AtlasTexture" id="AtlasTexture_cldwb"] -atlas = ExtResource("3_6ewaj") -region = Rect2(0, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_ehtnl"] -atlas = ExtResource("3_6ewaj") -region = Rect2(16, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_j05gd"] -atlas = ExtResource("3_6ewaj") -region = Rect2(32, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_7el6f"] -atlas = ExtResource("3_6ewaj") -region = Rect2(48, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_n7sw3"] -atlas = ExtResource("3_6ewaj") -region = Rect2(64, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_mumsm"] -atlas = ExtResource("3_6ewaj") -region = Rect2(80, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_gx41d"] -atlas = ExtResource("3_6ewaj") -region = Rect2(96, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_r4nx1"] -atlas = ExtResource("3_6ewaj") -region = Rect2(112, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_s8j4o"] -atlas = ExtResource("3_6ewaj") -region = Rect2(128, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_2svrb"] -atlas = ExtResource("3_6ewaj") -region = Rect2(144, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_twd5t"] -atlas = ExtResource("3_6ewaj") -region = Rect2(160, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_8w5ka"] -atlas = ExtResource("3_6ewaj") -region = Rect2(176, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_6iumv"] -atlas = ExtResource("3_6ewaj") -region = Rect2(192, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_lpilf"] -atlas = ExtResource("3_6ewaj") -region = Rect2(208, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_n1a5a"] -atlas = ExtResource("3_6ewaj") -region = Rect2(224, 0, 16, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_q0oeq"] -atlas = ExtResource("3_6ewaj") -region = Rect2(240, 0, 16, 16) - -[sub_resource type="SpriteFrames" id="SpriteFrames_15g84"] -animations = [{ -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_cldwb") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_ehtnl") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_j05gd") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_7el6f") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_n7sw3") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_mumsm") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_gx41d") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_r4nx1") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_s8j4o") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_2svrb") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_twd5t") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_8w5ka") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_6iumv") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_lpilf") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_n1a5a") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_q0oeq") -}], -"loop": true, -"name": &"default", -"speed": 5.0 -}] - -[sub_resource type="CircleShape2D" id="CircleShape2D_0xl2q"] -radius = 4.0 - -[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_p3lv8"] -particles_animation = true -particles_anim_h_frames = 3 -particles_anim_v_frames = 1 -particles_anim_loop = false - -[sub_resource type="Gradient" id="Gradient_ryemi"] -colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0.537255) - -[sub_resource type="GradientTexture1D" id="GradientTexture1D_orgu0"] -gradient = SubResource("Gradient_ryemi") - -[sub_resource type="Curve" id="Curve_21dxk"] -_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.177419, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.0272727), 0.0, 0.0, 0, 0] -point_count = 3 - -[sub_resource type="CurveTexture" id="CurveTexture_rutlp"] -curve = SubResource("Curve_21dxk") - -[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_ku1mm"] -particle_flag_disable_z = true -angle_max = 360.0 -gravity = Vector3(0, 0, 0) -scale_min = 0.4 -scale_max = 1.5 -scale_curve = SubResource("CurveTexture_rutlp") -color = Color(0.811765, 0.0980392, 0.0980392, 0.627451) -color_ramp = SubResource("GradientTexture1D_orgu0") -anim_offset_max = 1.0 - -[node name="Effect0001" type="CharacterBody2D" node_paths=PackedStringArray("ShadowSprite", "AnimatedSprite", "Collision")] -collision_layer = 128 -script = ExtResource("1_ttosm") -ShadowSprite = NodePath("ShadowSprite") -AnimatedSprite = NodePath("AnimatedSprite") -Collision = NodePath("Collision") - -[node name="ShadowSprite" type="Sprite2D" parent="."] -z_index = -1 -material = SubResource("ShaderMaterial_s1mj2") - -[node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] -material = SubResource("ShaderMaterial_08fn3") -sprite_frames = SubResource("SpriteFrames_15g84") - -[node name="Collision" type="CollisionShape2D" parent="."] -shape = SubResource("CircleShape2D_0xl2q") - -[node name="GPUParticles2D" type="GPUParticles2D" parent="."] -material = SubResource("CanvasItemMaterial_p3lv8") -emitting = false -process_material = SubResource("ParticleProcessMaterial_ku1mm") -texture = ExtResource("4_wu0t6") -fixed_fps = 20 diff --git a/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0001.tscn b/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0001.tscn new file mode 100644 index 0000000..1ffbf1b --- /dev/null +++ b/DungeonShooting_Godot/prefab/effect/enemy/EnemyBlood0001.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=5 format=3 uid="uid://m0s0k5nw7nbi"] + +[ext_resource type="Material" uid="uid://c1chld6lkpgji" path="res://resource/material/SmokeParticleMaterial.tres" id="1_leomh"] +[ext_resource type="Texture2D" uid="uid://h7hkgbwj1li" path="res://resource/sprite/effects/common/Smoke.png" id="2_c2t2e"] +[ext_resource type="Script" path="res://src/game/effects/AutoDestroyParticles.cs" id="3_5cpi6"] + +[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_emuda"] +particles_animation = true +particles_anim_h_frames = 3 +particles_anim_v_frames = 1 +particles_anim_loop = false + +[node name="EnemyBloodEffect" type="GPUParticles2D" node_paths=PackedStringArray("Particles2D")] +modulate = Color(0.811765, 0.0980392, 0.0980392, 0.627451) +material = SubResource("CanvasItemMaterial_emuda") +emitting = false +amount = 10 +process_material = ExtResource("1_leomh") +texture = ExtResource("2_c2t2e") +lifetime = 1.2 +one_shot = true +explosiveness = 1.0 +fixed_fps = 20 +script = ExtResource("3_5cpi6") +Particles2D = [] diff --git a/DungeonShooting_Godot/prefab/effect/enemy/EnemyBloodEffect.tscn b/DungeonShooting_Godot/prefab/effect/enemy/EnemyBloodEffect.tscn deleted file mode 100644 index 94e488c..0000000 --- a/DungeonShooting_Godot/prefab/effect/enemy/EnemyBloodEffect.tscn +++ /dev/null @@ -1,26 +0,0 @@ -[gd_scene load_steps=5 format=3 uid="uid://m0s0k5nw7nbi"] - -[ext_resource type="Material" uid="uid://c1chld6lkpgji" path="res://resource/material/SmokeParticleMaterial.tres" id="1_leomh"] -[ext_resource type="Texture2D" uid="uid://h7hkgbwj1li" path="res://resource/sprite/effects/common/Smoke.png" id="2_c2t2e"] -[ext_resource type="Script" path="res://src/game/effects/AutoDestroyParticles.cs" id="3_5cpi6"] - -[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_emuda"] -particles_animation = true -particles_anim_h_frames = 3 -particles_anim_v_frames = 1 -particles_anim_loop = false - -[node name="EnemyBloodEffect" type="GPUParticles2D" node_paths=PackedStringArray("Particles2D")] -modulate = Color(0.811765, 0.0980392, 0.0980392, 0.627451) -material = SubResource("CanvasItemMaterial_emuda") -emitting = false -amount = 10 -process_material = ExtResource("1_leomh") -texture = ExtResource("2_c2t2e") -lifetime = 1.2 -one_shot = true -explosiveness = 1.0 -fixed_fps = 20 -script = ExtResource("3_5cpi6") -DelayTime = 2.0 -Particles2D = [] diff --git a/DungeonShooting_Godot/prefab/effect/weapon/BulletDisappear.tscn b/DungeonShooting_Godot/prefab/effect/weapon/BulletDisappear.tscn index 0f40391..a5c2a07 100644 --- a/DungeonShooting_Godot/prefab/effect/weapon/BulletDisappear.tscn +++ b/DungeonShooting_Godot/prefab/effect/weapon/BulletDisappear.tscn @@ -34,6 +34,9 @@ }, { "duration": 1.0, "texture": SubResource("AtlasTexture_41eg5") +}, { +"duration": 1.0, +"texture": null }], "loop": false, "name": &"default", @@ -73,7 +76,7 @@ scale = Vector2(0.5, 0.5) sprite_frames = SubResource("SpriteFrames_ub3cw") script = ExtResource("2_l2qlq") -DelayTime = 0.3 +DelayTime = 0.5 Particles2D = [NodePath("GPUParticles2D")] [node name="GPUParticles2D" type="GPUParticles2D" parent="."] diff --git a/DungeonShooting_Godot/prefab/effect/weapon/BulletSmoke.tscn b/DungeonShooting_Godot/prefab/effect/weapon/BulletSmoke.tscn index a6c4f6b..83786a2 100644 --- a/DungeonShooting_Godot/prefab/effect/weapon/BulletSmoke.tscn +++ b/DungeonShooting_Godot/prefab/effect/weapon/BulletSmoke.tscn @@ -24,6 +24,8 @@ [node name="BulletSmoke" type="AnimatedSprite2D" node_paths=PackedStringArray("Particles2D")] sprite_frames = ExtResource("1_r62v8") +frame = 4 +frame_progress = 1.0 offset = Vector2(8, 0) script = ExtResource("2_r547d") Particles2D = [NodePath("GpuParticles2D")] diff --git a/DungeonShooting_Godot/prefab/effect/weapon/ShotFire.tscn b/DungeonShooting_Godot/prefab/effect/weapon/ShotFire.tscn index 2e53592..380a59a 100644 --- a/DungeonShooting_Godot/prefab/effect/weapon/ShotFire.tscn +++ b/DungeonShooting_Godot/prefab/effect/weapon/ShotFire.tscn @@ -33,6 +33,9 @@ }, { "duration": 1.0, "texture": SubResource("AtlasTexture_qi1pq") +}, { +"duration": 1.0, +"texture": null }], "loop": false, "name": &"default", @@ -44,5 +47,5 @@ sprite_frames = SubResource("SpriteFrames_73j16") offset = Vector2(8, 0) script = ExtResource("2_lnwju") -DelayTime = 0.2 +DelayTime = 0.5 Particles2D = [] diff --git a/DungeonShooting_Godot/prefab/effect/weapon/ShotFire2.tscn b/DungeonShooting_Godot/prefab/effect/weapon/ShotFire2.tscn index 7073dc9..cf55d21 100644 --- a/DungeonShooting_Godot/prefab/effect/weapon/ShotFire2.tscn +++ b/DungeonShooting_Godot/prefab/effect/weapon/ShotFire2.tscn @@ -33,6 +33,9 @@ }, { "duration": 1.0, "texture": SubResource("AtlasTexture_ud7n7") +}, { +"duration": 1.0, +"texture": null }], "loop": false, "name": &"default", @@ -44,5 +47,5 @@ sprite_frames = SubResource("SpriteFrames_rry1m") offset = Vector2(5.5, 0) script = ExtResource("2_4ecjw") -DelayTime = 0.2 +DelayTime = 0.5 Particles2D = [] diff --git a/DungeonShooting_Godot/prefab/role/Enemy0001.tscn b/DungeonShooting_Godot/prefab/role/Enemy0001.tscn index 7326d5a..5b0906b 100644 --- a/DungeonShooting_Godot/prefab/role/Enemy0001.tscn +++ b/DungeonShooting_Godot/prefab/role/Enemy0001.tscn @@ -1,9 +1,13 @@ -[gd_scene load_steps=7 format=3 uid="uid://b8s1dgu63fddf"] +[gd_scene load_steps=13 format=3 uid="uid://b8s1dgu63fddf"] -[ext_resource type="PackedScene" uid="uid://dbrig6dq441wo" path="res://prefab/role/template/AdvancedEnemyTemplate.tscn" id="1_2vqwe"] -[ext_resource type="Script" path="res://src/game/activity/role/enemy/AdvancedEnemy.cs" id="2_thbey"] +[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="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_f7y56"] resource_local_to_scene = true @@ -15,6 +19,7 @@ shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 [sub_resource type="ShaderMaterial" id="ShaderMaterial_2kup1"] resource_local_to_scene = true @@ -26,20 +31,36 @@ shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 -[node name="Enemy0001" node_paths=PackedStringArray("ViewRay", "NavigationAgent2D", "NavigationPoint", "MountPoint", "BackMountPoint", "MeleeAttackArea", "MeleeAttackCollision", "HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_2vqwe")] -script = ExtResource("2_thbey") +[sub_resource type="RectangleShape2D" id="RectangleShape2D_rkrey"] +size = Vector2(12, 18) + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_ur1ug"] +_data = { +"RESET": ExtResource("5_ffnft"), +"astonished": ExtResource("5_jyt15"), +"notify": ExtResource("6_x8gmo"), +"query": ExtResource("7_e37p2") +} + +[node name="Enemy0001" node_paths=PackedStringArray("ViewRay", "NavigationAgent2D", "NavigationPoint", "FirePoint", "HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "TipRoot", "TipSprite", "AnimationPlayer", "MountPoint", "BackMountPoint", "MeleeAttackArea", "MeleeAttackCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_2vqwe")] +script = ExtResource("2_0pcq3") ViewRay = NodePath("ViewRay") NavigationAgent2D = NodePath("NavigationPoint/NavigationAgent2D") NavigationPoint = NodePath("NavigationPoint") -MountPoint = NodePath("MountPoint") -BackMountPoint = NodePath("BackMountPoint") -MeleeAttackArea = NodePath("MountPoint/MeleeAttackArea") -MeleeAttackCollision = NodePath("MountPoint/MeleeAttackArea/MeleeAttackCollision") +FirePoint = NodePath("FirePoint") HurtArea = NodePath("HurtArea") HurtCollision = NodePath("HurtArea/HurtCollision") InteractiveArea = NodePath("InteractiveArea") InteractiveCollision = NodePath("InteractiveArea/InteractiveCollision") +TipRoot = NodePath("TipRoot") +TipSprite = NodePath("TipRoot/TipSprite") +AnimationPlayer = NodePath("AnimationPlayer") +MountPoint = NodePath("MountPoint") +BackMountPoint = NodePath("BackMountPoint") +MeleeAttackArea = NodePath("MountPoint/MeleeAttackArea") +MeleeAttackCollision = NodePath("MountPoint/MeleeAttackArea/MeleeAttackCollision") ShadowSprite = NodePath("ShadowSprite") AnimatedSprite = NodePath("AnimatedSprite") Collision = NodePath("Collision") @@ -50,3 +71,14 @@ [node name="AnimatedSprite" parent="." index="2"] material = SubResource("ShaderMaterial_2kup1") sprite_frames = ExtResource("4_qv8w5") + +[node name="HurtCollision" parent="HurtArea" index="0"] +shape = SubResource("RectangleShape2D_rkrey") + +[node name="FirePoint" parent="." index="8"] +position = Vector2(2, -9) + +[node name="AnimationPlayer" parent="." index="11"] +libraries = { +"": SubResource("AnimationLibrary_ur1ug") +} diff --git a/DungeonShooting_Godot/prefab/role/Enemy0002.tscn b/DungeonShooting_Godot/prefab/role/Enemy0002.tscn index c9fd918..77eae57 100644 --- a/DungeonShooting_Godot/prefab/role/Enemy0002.tscn +++ b/DungeonShooting_Godot/prefab/role/Enemy0002.tscn @@ -1,13 +1,17 @@ -[gd_scene load_steps=7 format=3 uid="uid://b5r3hd8kv2wmd"] +[gd_scene load_steps=13 format=3 uid="uid://daqsdld5gnwwr"] -[ext_resource type="PackedScene" uid="uid://dxeqcssparqoo" path="res://prefab/role/template/EnemyTemplate.tscn" id="1_rikvp"] -[ext_resource type="Script" path="res://src/game/activity/role/enemy/Enemy.cs" id="2_wjtfl"] -[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_gr4gs"] -[ext_resource type="SpriteFrames" uid="uid://ctpkpxgcwb583" path="res://resource/spriteFrames/role/Enemy0002.tres" id="4_ehtyi"] +[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="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_7theg"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_5rnql"] resource_local_to_scene = true -shader = ExtResource("3_gr4gs") +shader = ExtResource("2_yunbp") shader_parameter/blend = Color(0, 0, 0, 0.470588) shader_parameter/schedule = 1.0 shader_parameter/modulate = Color(1, 1, 1, 1) @@ -15,10 +19,11 @@ shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_ntjmx"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_4qvs8"] resource_local_to_scene = true -shader = ExtResource("3_gr4gs") +shader = ExtResource("2_yunbp") shader_parameter/blend = Color(1, 1, 1, 1) shader_parameter/schedule = 0.0 shader_parameter/modulate = Color(1, 1, 1, 1) @@ -26,24 +31,100 @@ shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 -[node name="Enemy0002" node_paths=PackedStringArray("ViewRay", "NavigationAgent2D", "NavigationPoint", "HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_rikvp")] -script = ExtResource("2_wjtfl") +[sub_resource type="Animation" id="Animation_bn678"] +resource_name = "attack" +length = 0.6 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("AnimatedSprite:animation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [&"attack"] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("AnimatedSprite:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0, 7] +} +tracks/2/type = "method" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath(".") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0.3), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"ShootBullet" +}] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_3ge8m"] +_data = { +"RESET": ExtResource("6_pt7v0"), +"astonished": ExtResource("5_p7gwr"), +"attack": SubResource("Animation_bn678"), +"notify": ExtResource("8_0688j"), +"query": ExtResource("7_h4cls") +} + +[node name="Enemy0002" node_paths=PackedStringArray("ViewRay", "NavigationAgent2D", "NavigationPoint", "FirePoint", "HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "TipRoot", "TipSprite", "AnimationPlayer", "MountPoint", "BackMountPoint", "MeleeAttackArea", "MeleeAttackCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_fanet")] +script = ExtResource("2_3an4s") +CanPickUpWeapon = false ViewRay = NodePath("ViewRay") NavigationAgent2D = NodePath("NavigationPoint/NavigationAgent2D") NavigationPoint = NodePath("NavigationPoint") +FirePoint = NodePath("FirePoint") HurtArea = NodePath("HurtArea") HurtCollision = NodePath("HurtArea/HurtCollision") InteractiveArea = NodePath("InteractiveArea") InteractiveCollision = NodePath("InteractiveArea/InteractiveCollision") +TipRoot = NodePath("TipRoot") +TipSprite = NodePath("TipRoot/TipSprite") +AnimationPlayer = NodePath("AnimationPlayer") +MountPoint = NodePath("MountPoint") +BackMountPoint = NodePath("BackMountPoint") +MeleeAttackArea = NodePath("MountPoint/MeleeAttackArea") +MeleeAttackCollision = NodePath("MountPoint/MeleeAttackArea/MeleeAttackCollision") ShadowSprite = NodePath("ShadowSprite") AnimatedSprite = NodePath("AnimatedSprite") Collision = NodePath("Collision") [node name="ShadowSprite" parent="." index="0"] -material = SubResource("ShaderMaterial_7theg") +material = SubResource("ShaderMaterial_5rnql") -[node name="AnimatedSprite" parent="." index="1"] -material = SubResource("ShaderMaterial_ntjmx") -position = Vector2(0, -10) -sprite_frames = ExtResource("4_ehtyi") +[node name="AnimatedSprite" parent="." index="2"] +material = SubResource("ShaderMaterial_4qvs8") +sprite_frames = ExtResource("3_hbsqi") +animation = &"attack" +offset = Vector2(0, -9) + +[node name="HurtCollision" parent="HurtArea" index="0"] +position = Vector2(0, -7) + +[node name="MountPoint" parent="." index="7"] +position = Vector2(4, -9) + +[node name="FirePoint" parent="." index="8"] +position = Vector2(7, -6) + +[node name="AnimationPlayer" parent="." index="11"] +libraries = { +"": SubResource("AnimationLibrary_3ge8m") +} diff --git a/DungeonShooting_Godot/prefab/role/Role0001.tscn b/DungeonShooting_Godot/prefab/role/Role0001.tscn index 97d017d..a541d06 100644 --- a/DungeonShooting_Godot/prefab/role/Role0001.tscn +++ b/DungeonShooting_Godot/prefab/role/Role0001.tscn @@ -1,6 +1,6 @@ -[gd_scene load_steps=7 format=3 uid="uid://cxhrcytrx0kcf"] +[gd_scene load_steps=9 format=3 uid="uid://cxhrcytrx0kcf"] -[ext_resource type="PackedScene" uid="uid://cyrcv2jdgr8cf" path="res://prefab/role/template/AdvancedRoleTemplate.tscn" id="1_10c2n"] +[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="SpriteFrames" uid="uid://n11thtali6es" path="res://resource/spriteFrames/role/Role0001.tres" id="4_galcc"] @@ -15,6 +15,7 @@ shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 [sub_resource type="ShaderMaterial" id="ShaderMaterial_8hgu2"] resource_local_to_scene = true @@ -26,18 +27,27 @@ shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 -[node name="Role0001" node_paths=PackedStringArray("MountPoint", "BackMountPoint", "MeleeAttackArea", "MeleeAttackCollision", "HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_10c2n")] +[sub_resource type="RectangleShape2D" id="RectangleShape2D_ve262"] +size = Vector2(12, 18) + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_ka171"] + +[node name="Role0001" node_paths=PackedStringArray("HurtArea", "HurtCollision", "InteractiveArea", "InteractiveCollision", "TipRoot", "TipSprite", "AnimationPlayer", "MountPoint", "BackMountPoint", "MeleeAttackArea", "MeleeAttackCollision", "ShadowSprite", "AnimatedSprite", "Collision") instance=ExtResource("1_10c2n")] collision_layer = 8 script = ExtResource("2_6xwnt") -MountPoint = NodePath("MountPoint") -BackMountPoint = NodePath("BackMountPoint") -MeleeAttackArea = NodePath("MountPoint/MeleeAttackArea") -MeleeAttackCollision = NodePath("MountPoint/MeleeAttackArea/MeleeAttackCollision") HurtArea = NodePath("HurtArea") HurtCollision = NodePath("HurtArea/HurtCollision") InteractiveArea = NodePath("InteractiveArea") InteractiveCollision = NodePath("InteractiveArea/InteractiveCollision") +TipRoot = NodePath("TipRoot") +TipSprite = NodePath("TipRoot/TipSprite") +AnimationPlayer = NodePath("AnimationPlayer") +MountPoint = NodePath("MountPoint") +BackMountPoint = NodePath("BackMountPoint") +MeleeAttackArea = NodePath("MountPoint/MeleeAttackArea") +MeleeAttackCollision = NodePath("MountPoint/MeleeAttackArea/MeleeAttackCollision") ShadowSprite = NodePath("ShadowSprite") AnimatedSprite = NodePath("AnimatedSprite") Collision = NodePath("Collision") @@ -48,4 +58,11 @@ [node name="AnimatedSprite" parent="." index="2"] material = SubResource("ShaderMaterial_8hgu2") sprite_frames = ExtResource("4_galcc") -frame_progress = 0.658799 + +[node name="HurtCollision" parent="HurtArea" index="0"] +shape = SubResource("RectangleShape2D_ve262") + +[node name="AnimationPlayer" parent="." index="8"] +libraries = { +"": SubResource("AnimationLibrary_ka171") +} diff --git a/DungeonShooting_Godot/prefab/role/template/AdvancedEnemyTemplate.tscn b/DungeonShooting_Godot/prefab/role/template/AdvancedEnemyTemplate.tscn deleted file mode 100644 index b02e44a..0000000 --- a/DungeonShooting_Godot/prefab/role/template/AdvancedEnemyTemplate.tscn +++ /dev/null @@ -1,48 +0,0 @@ -[gd_scene load_steps=5 format=3 uid="uid://dbrig6dq441wo"] - -[ext_resource type="PackedScene" uid="uid://cyrcv2jdgr8cf" path="res://prefab/role/template/AdvancedRoleTemplate.tscn" id="1_5po38"] -[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="3_x8agd"] - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_8vxx6"] -resource_local_to_scene = true -shader = ExtResource("3_x8agd") -shader_parameter/blend = Color(0, 0, 0, 0.470588) -shader_parameter/schedule = 1.0 -shader_parameter/modulate = Color(1, 1, 1, 1) -shader_parameter/show_outline = true -shader_parameter/outline_color = Color(0, 0, 0, 1) -shader_parameter/outline_rainbow = false -shader_parameter/outline_use_blend = true - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_k8mt5"] -resource_local_to_scene = true -shader = ExtResource("3_x8agd") -shader_parameter/blend = Color(1, 1, 1, 1) -shader_parameter/schedule = 0.0 -shader_parameter/modulate = Color(1, 1, 1, 1) -shader_parameter/show_outline = true -shader_parameter/outline_color = Color(0, 0, 0, 1) -shader_parameter/outline_rainbow = false -shader_parameter/outline_use_blend = true - -[node name="AdvancedEnemyTemplate" instance=ExtResource("1_5po38")] -collision_layer = 16 -collision_mask = 25 - -[node name="ShadowSprite" parent="." index="0"] -material = SubResource("ShaderMaterial_8vxx6") - -[node name="AnimatedSprite" parent="." index="2"] -material = SubResource("ShaderMaterial_k8mt5") - -[node name="ViewRay" type="RayCast2D" parent="." index="6"] -position = Vector2(0, -8) -enabled = false - -[node name="NavigationPoint" type="Marker2D" parent="." index="8"] -position = Vector2(0, -5) - -[node name="NavigationAgent2D" type="NavigationAgent2D" parent="NavigationPoint" index="0"] -path_desired_distance = 3.0 -target_desired_distance = 3.0 -radius = 20.0 diff --git a/DungeonShooting_Godot/prefab/role/template/AdvancedRoleTemplate.tscn b/DungeonShooting_Godot/prefab/role/template/AdvancedRoleTemplate.tscn deleted file mode 100644 index 2394511..0000000 --- a/DungeonShooting_Godot/prefab/role/template/AdvancedRoleTemplate.tscn +++ /dev/null @@ -1,83 +0,0 @@ -[gd_scene load_steps=8 format=3 uid="uid://cyrcv2jdgr8cf"] - -[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="1_xk5yk"] -[ext_resource type="Script" path="res://src/game/activity/role/MountRotation.cs" id="2_5ddpw"] - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_v2kfw"] -resource_local_to_scene = true -shader = ExtResource("1_xk5yk") -shader_parameter/blend = Color(0, 0, 0, 0.470588) -shader_parameter/schedule = 0.0 -shader_parameter/modulate = Color(1, 1, 1, 1) -shader_parameter/show_outline = true -shader_parameter/outline_color = Color(0, 0, 0, 1) -shader_parameter/outline_rainbow = false -shader_parameter/outline_use_blend = true - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_yif6x"] -resource_local_to_scene = true -shader = ExtResource("1_xk5yk") -shader_parameter/blend = Color(1, 1, 1, 1) -shader_parameter/schedule = 0.0 -shader_parameter/modulate = Color(1, 1, 1, 1) -shader_parameter/show_outline = true -shader_parameter/outline_color = Color(0, 0, 0, 1) -shader_parameter/outline_rainbow = false -shader_parameter/outline_use_blend = true - -[sub_resource type="CircleShape2D" id="CircleShape2D_5pj80"] -radius = 4.0 - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_1eja2"] -size = Vector2(12, 18) - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_n68nu"] -size = Vector2(10, 16.5) - -[node name="AdvancedRoleTemplate" type="CharacterBody2D"] -collision_layer = 0 - -[node name="ShadowSprite" type="Sprite2D" parent="."] -z_index = -1 -material = SubResource("ShaderMaterial_v2kfw") - -[node name="BackMountPoint" type="Marker2D" parent="."] -position = Vector2(0, -12) - -[node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] -material = SubResource("ShaderMaterial_yif6x") -position = Vector2(0, -12) - -[node name="Collision" type="CollisionShape2D" parent="."] -position = Vector2(0, -4) -shape = SubResource("CircleShape2D_5pj80") - -[node name="HurtArea" type="Area2D" parent="."] -collision_layer = 0 -collision_mask = 0 -monitoring = false - -[node name="HurtCollision" type="CollisionShape2D" parent="HurtArea"] -position = Vector2(0, -9) -shape = SubResource("RectangleShape2D_1eja2") - -[node name="InteractiveArea" type="Area2D" parent="."] -visible = false -collision_layer = 0 -collision_mask = 4 -monitorable = false - -[node name="InteractiveCollision" type="CollisionShape2D" parent="InteractiveArea"] -position = Vector2(0, -5) -shape = SubResource("RectangleShape2D_n68nu") - -[node name="MountPoint" type="Marker2D" parent="."] -position = Vector2(2, -8) -script = ExtResource("2_5ddpw") - -[node name="MeleeAttackArea" type="Area2D" parent="MountPoint"] -collision_layer = 0 -collision_mask = 0 -monitorable = false - -[node name="MeleeAttackCollision" type="CollisionPolygon2D" parent="MountPoint/MeleeAttackArea"] diff --git a/DungeonShooting_Godot/prefab/role/template/EnemyTemplate.tscn b/DungeonShooting_Godot/prefab/role/template/EnemyTemplate.tscn index 8d83646..28fcf5f 100644 --- a/DungeonShooting_Godot/prefab/role/template/EnemyTemplate.tscn +++ b/DungeonShooting_Godot/prefab/role/template/EnemyTemplate.tscn @@ -1,11 +1,11 @@ -[gd_scene load_steps=5 format=3 uid="uid://dxeqcssparqoo"] +[gd_scene load_steps=5 format=3 uid="uid://dbrig6dq441wo"] -[ext_resource type="PackedScene" uid="uid://0uc4naitjprl" path="res://prefab/role/template/RoleTemplate.tscn" id="1_u04qy"] -[ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_tedjs"] +[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"] -[sub_resource type="ShaderMaterial" id="ShaderMaterial_fhls5"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_8vxx6"] resource_local_to_scene = true -shader = ExtResource("2_tedjs") +shader = ExtResource("3_x8agd") shader_parameter/blend = Color(0, 0, 0, 0.470588) shader_parameter/schedule = 1.0 shader_parameter/modulate = Color(1, 1, 1, 1) @@ -14,9 +14,9 @@ shader_parameter/outline_rainbow = false shader_parameter/outline_use_blend = true -[sub_resource type="ShaderMaterial" id="ShaderMaterial_lnent"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_k8mt5"] resource_local_to_scene = true -shader = ExtResource("2_tedjs") +shader = ExtResource("3_x8agd") shader_parameter/blend = Color(1, 1, 1, 1) shader_parameter/schedule = 0.0 shader_parameter/modulate = Color(1, 1, 1, 1) @@ -25,21 +25,23 @@ shader_parameter/outline_rainbow = false shader_parameter/outline_use_blend = true -[node name="EnemyTemplate" instance=ExtResource("1_u04qy")] +[node name="EnemyTemplate" instance=ExtResource("1_5po38")] collision_layer = 16 collision_mask = 25 [node name="ShadowSprite" parent="." index="0"] -material = SubResource("ShaderMaterial_fhls5") +material = SubResource("ShaderMaterial_8vxx6") -[node name="AnimatedSprite" parent="." index="1"] -material = SubResource("ShaderMaterial_lnent") +[node name="AnimatedSprite" parent="." index="2"] +material = SubResource("ShaderMaterial_k8mt5") -[node name="ViewRay" type="RayCast2D" parent="." index="5"] +[node name="ViewRay" type="RayCast2D" parent="." index="6"] position = Vector2(0, -8) enabled = false -[node name="NavigationPoint" type="Marker2D" parent="." index="6"] +[node name="FirePoint" type="Marker2D" parent="." index="8"] + +[node name="NavigationPoint" type="Marker2D" parent="." index="9"] position = Vector2(0, -5) [node name="NavigationAgent2D" type="NavigationAgent2D" parent="NavigationPoint" index="0"] diff --git a/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn b/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn index ad986de..edd302e 100644 --- a/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn +++ b/DungeonShooting_Godot/prefab/role/template/RoleTemplate.tscn @@ -1,6 +1,8 @@ -[gd_scene load_steps=7 format=3 uid="uid://0uc4naitjprl"] +[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="Script" path="res://src/game/activity/role/MountRotation.cs" id="2_5ddpw"] +[ext_resource type="SpriteFrames" uid="uid://c8h5svp76h3kw" path="res://resource/spriteFrames/role/Role_tip.tres" id="3_bo78w"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_v2kfw"] resource_local_to_scene = true @@ -40,9 +42,12 @@ z_index = -1 material = SubResource("ShaderMaterial_v2kfw") +[node name="BackMountPoint" type="Marker2D" parent="."] +position = Vector2(0, -12) + [node name="AnimatedSprite" type="AnimatedSprite2D" parent="."] material = SubResource("ShaderMaterial_yif6x") -position = Vector2(0, -12) +offset = Vector2(0, -12) [node name="Collision" type="CollisionShape2D" parent="."] position = Vector2(0, -4) @@ -66,3 +71,23 @@ [node name="InteractiveCollision" type="CollisionShape2D" parent="InteractiveArea"] position = Vector2(0, -5) shape = SubResource("RectangleShape2D_n68nu") + +[node name="MountPoint" type="Marker2D" parent="."] +position = Vector2(2, -8) +script = ExtResource("2_5ddpw") + +[node name="MeleeAttackArea" type="Area2D" parent="MountPoint"] +collision_layer = 0 +collision_mask = 0 +monitorable = false + +[node name="MeleeAttackCollision" type="CollisionPolygon2D" parent="MountPoint/MeleeAttackArea"] + +[node name="TipRoot" type="Node2D" parent="."] + +[node name="TipSprite" type="AnimatedSprite2D" parent="TipRoot"] +visible = false +position = Vector2(0, -22) +sprite_frames = ExtResource("3_bo78w") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] diff --git a/DungeonShooting_Godot/prefab/shell/Shell0001.tscn b/DungeonShooting_Godot/prefab/shell/Shell0001.tscn index eceaf5d..c1b2535 100644 --- a/DungeonShooting_Godot/prefab/shell/Shell0001.tscn +++ b/DungeonShooting_Godot/prefab/shell/Shell0001.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=7 format=3 uid="uid://bj4yr6ru8nhwr"] -[ext_resource type="Script" path="res://src/game/activity/shell/Shell.cs" id="1_2g70c"] +[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="SpriteFrames" uid="uid://b8gksxl7auquc" path="res://resource/spriteFrames/shell/Shell0001.tres" id="3_ujn5y"] @@ -35,6 +35,8 @@ ShadowSprite = NodePath("ShadowSprite") AnimatedSprite = NodePath("AnimatedSprite") Collision = NodePath("Collision") +ShadowOffset = Vector2(0, 1) +ThrowCollisionSize = Vector2(5, 5) [node name="ShadowSprite" type="Sprite2D" parent="."] z_index = -1 diff --git a/DungeonShooting_Godot/prefab/shell/Shell0002.tscn b/DungeonShooting_Godot/prefab/shell/Shell0002.tscn index 7fc2e03..aa42706 100644 --- a/DungeonShooting_Godot/prefab/shell/Shell0002.tscn +++ b/DungeonShooting_Godot/prefab/shell/Shell0002.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=7 format=3 uid="uid://cdhinm8rnppxt"] -[ext_resource type="Script" path="res://src/game/activity/shell/Shell.cs" id="1_qi64y"] +[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="SpriteFrames" uid="uid://cj8psdl2pova6" path="res://resource/spriteFrames/shell/Shell0002.tres" id="3_r560h"] @@ -35,6 +35,8 @@ ShadowSprite = NodePath("ShadowSprite") AnimatedSprite = NodePath("AnimatedSprite") Collision = NodePath("Collision") +ShadowOffset = Vector2(0, 1) +ThrowCollisionSize = Vector2(5, 5) [node name="ShadowSprite" type="Sprite2D" parent="."] z_index = -1 diff --git a/DungeonShooting_Godot/prefab/shell/Shell0003.tscn b/DungeonShooting_Godot/prefab/shell/Shell0003.tscn index fecfbcb..f50ef2f 100644 --- a/DungeonShooting_Godot/prefab/shell/Shell0003.tscn +++ b/DungeonShooting_Godot/prefab/shell/Shell0003.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=7 format=3 uid="uid://ba5sxxjaappbj"] -[ext_resource type="Script" path="res://src/game/activity/shell/Shell.cs" id="1_5hfb2"] +[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="SpriteFrames" uid="uid://kc1jwvwdg660" path="res://resource/spriteFrames/shell/Shell0003.tres" id="3_j2kre"] @@ -35,6 +35,8 @@ ShadowSprite = NodePath("ShadowSprite") AnimatedSprite = NodePath("AnimatedSprite") Collision = NodePath("Collision") +ShadowOffset = Vector2(0, 1) +ThrowCollisionSize = Vector2(5, 5) [node name="ShadowSprite" type="Sprite2D" parent="."] z_index = -1 diff --git a/DungeonShooting_Godot/prefab/shell/Shell0004.tscn b/DungeonShooting_Godot/prefab/shell/Shell0004.tscn index 42d8fd0..fc18f6b 100644 --- a/DungeonShooting_Godot/prefab/shell/Shell0004.tscn +++ b/DungeonShooting_Godot/prefab/shell/Shell0004.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=7 format=3 uid="uid://ycr5mjr25302"] -[ext_resource type="Script" path="res://src/game/activity/shell/Shell.cs" id="1_ridlp"] +[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="SpriteFrames" uid="uid://b8b0ye3iv1vwp" path="res://resource/spriteFrames/shell/Shell0004.tres" id="3_1s5f3"] @@ -35,6 +35,8 @@ ShadowSprite = NodePath("ShadowSprite") AnimatedSprite = NodePath("AnimatedSprite") Collision = NodePath("Collision") +ShadowOffset = Vector2(0, 1) +ThrowCollisionSize = Vector2(5, 5) [node name="ShadowSprite" type="Sprite2D" parent="."] z_index = -1 diff --git a/DungeonShooting_Godot/project.godot b/DungeonShooting_Godot/project.godot index 5382858..66967c6 100644 --- a/DungeonShooting_Godot/project.godot +++ b/DungeonShooting_Godot/project.godot @@ -24,7 +24,7 @@ window/size/viewport_width=1920 window/size/viewport_height=1080 window/stretch/aspect="keep_width" -window/vsync/use_vsync=false +window/vsync/vsync_mode=0 [dotnet] @@ -182,6 +182,11 @@ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":88,"key_label":0,"unicode":120,"echo":false,"script":null) ] } +exchangeProp={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":90,"key_label":0,"unicode":122,"echo":false,"script":null) +] +} [layer_names] diff --git a/DungeonShooting_Godot/resource/animation/enemy/Enemy_astonished.res b/DungeonShooting_Godot/resource/animation/enemy/Enemy_astonished.res new file mode 100644 index 0000000..715ff3c --- /dev/null +++ b/DungeonShooting_Godot/resource/animation/enemy/Enemy_astonished.res Binary files differ diff --git a/DungeonShooting_Godot/resource/animation/enemy/Enemy_notify.res b/DungeonShooting_Godot/resource/animation/enemy/Enemy_notify.res new file mode 100644 index 0000000..d1cc298 --- /dev/null +++ b/DungeonShooting_Godot/resource/animation/enemy/Enemy_notify.res Binary files differ diff --git a/DungeonShooting_Godot/resource/animation/enemy/Enemy_query.res b/DungeonShooting_Godot/resource/animation/enemy/Enemy_query.res new file mode 100644 index 0000000..81299b9 --- /dev/null +++ b/DungeonShooting_Godot/resource/animation/enemy/Enemy_query.res Binary files differ diff --git a/DungeonShooting_Godot/resource/animation/enemy/Enemy_reset.res b/DungeonShooting_Godot/resource/animation/enemy/Enemy_reset.res new file mode 100644 index 0000000..ef1a612 --- /dev/null +++ b/DungeonShooting_Godot/resource/animation/enemy/Enemy_reset.res Binary files differ diff --git a/DungeonShooting_Godot/resource/config/ActivityBase.json b/DungeonShooting_Godot/resource/config/ActivityBase.json index c9bb74b..ce102c7 100644 --- a/DungeonShooting_Godot/resource/config/ActivityBase.json +++ b/DungeonShooting_Godot/resource/config/ActivityBase.json @@ -186,19 +186,31 @@ "Intro": "", "Details": "", "IsStatic": false, - "__Material": "0002", + "__Material": "0005", "Prefab": "res://prefab/bullet/normal/Bullet0004.tscn", "Icon": "", "ShowInMapEditor": false }, { + "Id": "bullet0005", + "Type": 6, + "Name": "\u654C\u65B9\u4E13\u7528\u5B50\u5F39", + "Intro": "", + "Details": "", + "IsStatic": false, + "__Material": "0004", + "Prefab": "res://prefab/bullet/normal/Bullet0005.tscn", + "Icon": "", + "ShowInMapEditor": false + }, + { "Id": "shell0001", "Type": 7, "Name": "", "Intro": "", "Details": "", "IsStatic": false, - "__Material": "", + "__Material": "0006", "Prefab": "res://prefab/shell/Shell0001.tscn", "Icon": "", "ShowInMapEditor": false @@ -210,7 +222,7 @@ "Intro": "", "Details": "", "IsStatic": false, - "__Material": "", + "__Material": "0006", "Prefab": "res://prefab/shell/Shell0002.tscn", "Icon": "", "ShowInMapEditor": false @@ -222,7 +234,7 @@ "Intro": "", "Details": "", "IsStatic": false, - "__Material": "", + "__Material": "0006", "Prefab": "res://prefab/shell/Shell0003.tscn", "Icon": "", "ShowInMapEditor": false @@ -234,20 +246,32 @@ "Intro": "", "Details": "", "IsStatic": false, - "__Material": "", + "__Material": "0006", "Prefab": "res://prefab/shell/Shell0004.tscn", "Icon": "", "ShowInMapEditor": false }, { - "Id": "effect0001", + "Id": "enemy_dead0001", "Type": 8, "Name": "", - "Intro": "\u654C\u4EBA\u6B7B\u4EA1\u788E\u7247", + "Intro": "\u654C\u4EBA1\u6B7B\u4EA1\u788E\u7247", "Details": "", "IsStatic": false, "__Material": "", - "Prefab": "res://prefab/effect/enemy/Effect0001.tscn", + "Prefab": "res://prefab/effect/enemy/EbenyDead0001.tscn", + "Icon": "", + "ShowInMapEditor": false + }, + { + "Id": "enemy_dead0002", + "Type": 8, + "Name": "", + "Intro": "\u654C\u4EBA2\u6B7B\u4EA1", + "Details": "", + "IsStatic": false, + "__Material": "", + "Prefab": "res://prefab/effect/enemy/EbenyDead0002.tscn", "Icon": "", "ShowInMapEditor": false }, diff --git a/DungeonShooting_Godot/resource/config/ActivityMaterial.json b/DungeonShooting_Godot/resource/config/ActivityMaterial.json index 56f528a..2d40acf 100644 --- a/DungeonShooting_Godot/resource/config/ActivityMaterial.json +++ b/DungeonShooting_Godot/resource/config/ActivityMaterial.json @@ -3,33 +3,84 @@ "Id": "0001", "Remark": "\u9ED8\u8BA4\u6750\u8D28\u5C5E\u6027", "Friction": 140, + "GravityScale": 1, + "RotationType": 0, "RotationFriction": 140, "Bounce": true, "BounceStrength": 0.5, "FallBounceStrength": 0.5, "FallBounceSpeed": 0.75, - "FallBounceRotation": 0.5 + "FallBounceRotation": 0.5, + "DynamicCollision": false }, { "Id": "0002", "Remark": "\u7403\u4F53\u6750\u8D28\uFF0C\u6469\u64E6\u529B\u8F83\u4F4E", "Friction": 40, + "GravityScale": 1, + "RotationType": 1, "RotationFriction": 40, "Bounce": true, "BounceStrength": 0.7, "FallBounceStrength": 0.7, "FallBounceSpeed": 0.85, - "FallBounceRotation": 0.85 + "FallBounceRotation": 0.85, + "DynamicCollision": true }, { "Id": "0003", - "Remark": "\u5B50\u5F39,\u53CD\u5F39\u6D88\u8017\u4F4E", + "Remark": "\u666E\u901A\u5B50\u5F39,\u53CD\u5F39\u6D88\u8017\u4F4E,\u65E0\u91CD\u529B\u4E0B\u5760", "Friction": 140, + "GravityScale": 0, + "RotationType": 1, "RotationFriction": 140, "Bounce": true, "BounceStrength": 1, "FallBounceStrength": 0.5, "FallBounceSpeed": 0.75, - "FallBounceRotation": 0.5 + "FallBounceRotation": 0.5, + "DynamicCollision": true + }, + { + "Id": "0004", + "Remark": "\u6B63\u5E38\u91CD\u529B\u5B50\u5F39", + "Friction": 140, + "GravityScale": 1, + "RotationType": 2, + "RotationFriction": 140, + "Bounce": true, + "BounceStrength": 1, + "FallBounceStrength": 0.5, + "FallBounceSpeed": 0.75, + "FallBounceRotation": 0.5, + "DynamicCollision": true + }, + { + "Id": "0005", + "Remark": "\u7403\u4F53\u5B50\u5F39\uFF0C\u6469\u64E6\u529B\u8F83\u4F4E", + "Friction": 40, + "GravityScale": 1, + "RotationType": 1, + "RotationFriction": 40, + "Bounce": true, + "BounceStrength": 0.7, + "FallBounceStrength": 0.7, + "FallBounceSpeed": 0.85, + "FallBounceRotation": 0.85, + "DynamicCollision": false + }, + { + "Id": "0006", + "Remark": "\u5F39\u58F3, \u6469\u64E6\u529B\u6BD4\u9ED8\u8BA4\u6750\u8D28\u4F4E", + "Friction": 100, + "GravityScale": 1, + "RotationType": 0, + "RotationFriction": 100, + "Bounce": true, + "BounceStrength": 0.5, + "FallBounceStrength": 0.5, + "FallBounceSpeed": 0.75, + "FallBounceRotation": 0.5, + "DynamicCollision": false } ] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/config/AiAttackAttr.json b/DungeonShooting_Godot/resource/config/AiAttackAttr.json index 3d27a46..251daae 100644 --- a/DungeonShooting_Godot/resource/config/AiAttackAttr.json +++ b/DungeonShooting_Godot/resource/config/AiAttackAttr.json @@ -2,6 +2,7 @@ { "Id": "0001", "Remark": "", + "LockingStand": true, "FiringStand": true, "ShowSubline": false, "LockingTime": 1, @@ -13,6 +14,7 @@ { "Id": "0002", "Remark": "", + "LockingStand": true, "FiringStand": true, "ShowSubline": false, "LockingTime": 2, @@ -24,6 +26,7 @@ { "Id": "0003", "Remark": "", + "LockingStand": true, "FiringStand": true, "ShowSubline": false, "LockingTime": 1, @@ -35,6 +38,7 @@ { "Id": "0004", "Remark": "\u79FB\u52A8\u5C04\u51FB", + "LockingStand": false, "FiringStand": false, "ShowSubline": false, "LockingTime": 0.7, @@ -46,6 +50,7 @@ { "Id": "0005", "Remark": "\u4F7F\u7528\u8FDC\u8DDD\u79BB\u6B66\u5668", + "LockingStand": true, "FiringStand": true, "ShowSubline": true, "LockingTime": 1.5, @@ -57,6 +62,7 @@ { "Id": "0006", "Remark": "", + "LockingStand": true, "FiringStand": true, "ShowSubline": false, "LockingTime": 0.5, @@ -68,6 +74,7 @@ { "Id": "0007", "Remark": "\u6FC0\u5149\u6B66\u5668", + "LockingStand": true, "FiringStand": true, "ShowSubline": true, "LockingTime": 1.5, @@ -79,6 +86,7 @@ { "Id": "0008", "Remark": "\u69B4\u5F39\u70AE", + "LockingStand": true, "FiringStand": true, "ShowSubline": false, "LockingTime": 1.5, diff --git a/DungeonShooting_Godot/resource/config/BulletBase.json b/DungeonShooting_Godot/resource/config/BulletBase.json index 6ce1a2e..1d45efc 100644 --- a/DungeonShooting_Godot/resource/config/BulletBase.json +++ b/DungeonShooting_Godot/resource/config/BulletBase.json @@ -24,7 +24,6 @@ 300, 400 ], - "UseGravity": false, "VerticalSpeed": [ 0 ], @@ -44,7 +43,7 @@ 4 ], "RepelRange": [ - 30 + 15 ], "DeviationAngleRange": [ -10, @@ -61,7 +60,6 @@ 200, 250 ], - "UseGravity": false, "VerticalSpeed": [ 0 ], @@ -81,7 +79,7 @@ 3 ], "RepelRange": [ - 10 + 15 ], "DeviationAngleRange": [ 0 @@ -97,7 +95,6 @@ 300, 400 ], - "UseGravity": false, "VerticalSpeed": [ 0 ], @@ -117,7 +114,7 @@ 20 ], "RepelRange": [ - 200 + 75 ], "DeviationAngleRange": [ 0 @@ -133,7 +130,6 @@ 600, 600 ], - "UseGravity": false, "VerticalSpeed": [ 0 ], @@ -153,7 +149,7 @@ 30 ], "RepelRange": [ - 150 + 85 ], "DeviationAngleRange": [ 0 @@ -169,7 +165,6 @@ 270, 360 ], - "UseGravity": true, "VerticalSpeed": [ 70 ], @@ -177,7 +172,42 @@ 999 ], "Penetration": [ - 1 + 0 + ] + }, + { + "Id": "0006", + "Name": "\u654C\u65B9\u4E13\u7528\u5B50\u5F39", + "Type": 1, + "Prefab": "bullet0005", + "HarmRange": [ + 5 + ], + "RepelRange": [ + 30 + ], + "DeviationAngleRange": [ + 0 + ], + "SpeedRange": [ + 100, + 100 + ], + "LifeTimeRange": [ + -1 + ], + "DistanceRange": [ + 270, + 360 + ], + "VerticalSpeed": [ + 170 + ], + "BounceCount": [ + 0 + ], + "Penetration": [ + 0 ] }, { @@ -189,7 +219,7 @@ 5 ], "RepelRange": [ - 40 + 35 ], "DeviationAngleRange": [ 0 @@ -205,7 +235,6 @@ 600, 600 ], - "UseGravity": false, "VerticalSpeed": null, "BounceCount": [ 0 @@ -221,7 +250,7 @@ 25 ], "RepelRange": [ - 150 + 70 ], "DeviationAngleRange": [ 0 @@ -235,7 +264,6 @@ "DistanceRange": [ 35 ], - "UseGravity": false, "VerticalSpeed": null, "BounceCount": null, "Penetration": null diff --git a/DungeonShooting_Godot/resource/config/EnemyBase.json b/DungeonShooting_Godot/resource/config/EnemyBase.json new file mode 100644 index 0000000..968950a --- /dev/null +++ b/DungeonShooting_Godot/resource/config/EnemyBase.json @@ -0,0 +1,26 @@ +[ + { + "Id": "0001", + "__Activity": "enemy0001", + "Remark": "\u654C\u4EBA1", + "MoveSpeed": 120, + "Acceleration": 1500, + "Friction": 900, + "CanPickUpWeapon": true, + "ViewRange": 250, + "TailAfterViewRange": 400, + "BackViewRange": 50 + }, + { + "Id": "0002", + "__Activity": "enemy0002", + "Remark": "\u654C\u4EBA2", + "MoveSpeed": 120, + "Acceleration": 1500, + "Friction": 900, + "CanPickUpWeapon": false, + "ViewRange": 250, + "TailAfterViewRange": 400, + "BackViewRange": 50 + } +] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json b/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json index d515189..7e4b0e7 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/GroupConfig.json @@ -31,6 +31,10 @@ { "ErrorType": 0, "Path": "resource/map/tileMaps/TestGroup1/inlet/Start2" + }, + { + "ErrorType": 0, + "Path": "resource/map/tileMaps/TestGroup1/inlet/Start3" } ], "OutletList": [ diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle2/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle2/Preinstall.json index 80edbe9..d380491 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle2/Preinstall.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle2/Preinstall.json @@ -1 +1 @@ -[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":178,"Y":-21},"Size":{"X":92,"Y":73},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0007","CurrAmmon":"60","ResidueAmmo":"60"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":76,"Y":168},"Size":{"X":43,"Y":77},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]}],[{"Position":{"X":89,"Y":19},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":65,"Y":142},"Size":{"X":48,"Y":160},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":79,"Y":45},"Size":{"X":46,"Y":121},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":181,"Y":203},"Size":{"X":66,"Y":33},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-19,"Y":100},"Size":{"X":97,"Y":63},"SpecialMarkType":0,"DelayTime":1.5,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":117,"Y":-14},"Size":{"X":122,"Y":78},"SpecialMarkType":0,"DelayTime":2,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]}],[{"Position":{"X":78,"Y":89},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-79,"Y":15},"Size":{"X":30,"Y":140},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0007","CurrAmmon":"60","ResidueAmmo":"60"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-50,"Y":114},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":2,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0003","CurrAmmon":"12","ResidueAmmo":"12"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":45,"Y":187},"Size":{"X":42,"Y":72},"SpecialMarkType":0,"DelayTime":3,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0003","CurrAmmon":"12","ResidueAmmo":"12"},"Altitude":0,"VerticalSpeed":0}]}]]}] \ No newline at end of file +[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":178,"Y":-21},"Size":{"X":92,"Y":73},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0007","CurrAmmon":"60","ResidueAmmo":"60"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":76,"Y":168},"Size":{"X":43,"Y":77},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":24,"Y":103},"Size":{"X":66,"Y":48},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0002","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]}],[{"Position":{"X":89,"Y":19},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":65,"Y":142},"Size":{"X":48,"Y":160},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":79,"Y":45},"Size":{"X":46,"Y":121},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":181,"Y":203},"Size":{"X":66,"Y":33},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-19,"Y":100},"Size":{"X":97,"Y":63},"SpecialMarkType":0,"DelayTime":1.5,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":117,"Y":-14},"Size":{"X":122,"Y":78},"SpecialMarkType":0,"DelayTime":2,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":126,"Y":207},"Size":{"X":81,"Y":27},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0002","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]}],[{"Position":{"X":78,"Y":89},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-79,"Y":15},"Size":{"X":30,"Y":140},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0007","CurrAmmon":"60","ResidueAmmo":"60"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-50,"Y":114},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":2,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0003","CurrAmmon":"12","ResidueAmmo":"12"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":45,"Y":187},"Size":{"X":42,"Y":72},"SpecialMarkType":0,"DelayTime":3,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0003","CurrAmmon":"12","ResidueAmmo":"12"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":119,"Y":-45},"Size":{"X":91,"Y":37},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0002","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-27,"Y":80},"Size":{"X":112,"Y":34},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0002","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]}]]}] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle2/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle2/Preview.png index 7f5ea4d..41a778f 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle2/Preview.png +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle2/Preview.png Binary files differ diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json index c401b01..cb5ad6b 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json @@ -1 +1 @@ -[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":19,"Y":2},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":24,"Y":-14},"Size":{"X":0,"Y":0},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":6,"Y":34},"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":-42,"Y":9},"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":-63,"Y":-18},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-31,"Y":-16},"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":-47,"Y":32},"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":2,"Y":-25},"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":-80,"Y":14},"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":-75,"Y":47},"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":46,"Y":1},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0011","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":36,"Y":49},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0012","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-90,"Y":-23},"Size":{"X":3,"Y":6},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0013","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-91,"Y":-6},"Size":{"X":0,"Y":0},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0014","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}],[{"Position":{"X":57,"Y":56},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":67,"Y":28},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":60,"Y":-19},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":34,"Y":23},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1.5,"MarkList":[{"Id":"prop0002","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-11,"Y":8},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-20,"Y":33},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}]]}] \ No newline at end of file +[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":19,"Y":2},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":24,"Y":-14},"Size":{"X":0,"Y":0},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":6,"Y":34},"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":-42,"Y":9},"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":-63,"Y":-18},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-31,"Y":-16},"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":-47,"Y":32},"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":2,"Y":-25},"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":-80,"Y":14},"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":-75,"Y":47},"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":46,"Y":1},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0011","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":36,"Y":49},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0012","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-90,"Y":-23},"Size":{"X":3,"Y":6},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0013","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-91,"Y":-6},"Size":{"X":0,"Y":0},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0014","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}],[{"Position":{"X":57,"Y":56},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":67,"Y":28},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":60,"Y":-19},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":34,"Y":23},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1.5,"MarkList":[{"Id":"prop0002","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-11,"Y":8},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-20,"Y":33},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-90,"Y":34},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0005","CurrAmmon":"10","ResidueAmmo":"10"},"Altitude":0,"VerticalSpeed":0}]}]]}] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preview.png index d64d95a..e7bb706 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preview.png +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preview.png Binary files differ diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preinstall.json index ed652d3..571aa13 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preinstall.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preinstall.json @@ -1 +1 @@ -[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":0,"Y":0},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":16,"Y":26},"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":-16,"Y":25},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-35,"Y":-40},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0002","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":37,"Y":-13},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]}]]}] \ No newline at end of file +[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":0,"Y":0},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":16,"Y":26},"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":-16,"Y":25},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":37,"Y":-13},"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":-11,"Y":-12},"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":10,"Y":-39},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":2,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-114,"Y":-5},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0002","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]}]]}] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preview.png index 6d2fd01..1b93c25 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preview.png +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/Preview.png Binary files differ diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/RoomInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/RoomInfo.json index 27eaead..dd8ba53 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/RoomInfo.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/RoomInfo.json @@ -1 +1 @@ -{"Position":{"X":-5,"Y":-5},"Size":{"X":10,"Y":12},"DoorAreaInfos":[{"Direction":3,"Start":0,"End":128},{"Direction":0,"Start":0,"End":160},{"Direction":1,"Start":0,"End":160}],"GroupName":"TestGroup1","RoomType":1,"RoomName":"Start2","Weight":100,"Remark":""} \ No newline at end of file +{"Position":{"X":-11,"Y":-7},"Size":{"X":16,"Y":14},"DoorAreaInfos":[{"Direction":3,"Start":96,"End":224},{"Direction":0,"Start":0,"End":192},{"Direction":1,"Start":0,"End":128},{"Direction":2,"Start":64,"End":144}],"GroupName":"TestGroup1","RoomType":1,"RoomName":"Start2","Weight":100,"Remark":""} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/TileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/TileInfo.json index 60689b8..4b13f17 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/TileInfo.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start2/TileInfo.json @@ -1 +1 @@ -{"NavigationList":[{"Type":0,"Points":[-56,-56,56,-56,56,96,40,96,40,48,-40,48,-40,96,-56,96]}],"Floor":[-3,-4,0,0,8,-3,-3,0,0,8,-3,-2,0,0,8,-3,-1,0,0,8,-3,0,0,0,8,-3,1,0,0,8,-3,2,0,0,8,-3,3,0,0,8,-3,4,0,0,8,-3,5,0,0,8,-2,-2,0,0,8,-2,-4,0,0,8,-2,-3,0,0,8,-2,-1,0,0,8,-2,0,0,0,8,-2,1,0,0,8,-2,2,0,0,8,-1,-1,0,0,8,-1,-4,0,0,8,-1,-3,0,0,8,-1,-2,0,0,8,-1,0,0,0,8,-1,1,0,0,8,-1,2,0,0,8,0,0,0,0,8,0,-4,0,0,8,0,-3,0,0,8,0,-2,0,0,8,0,-1,0,0,8,0,1,0,0,8,0,2,0,0,8,1,1,0,0,8,1,-4,0,0,8,1,-3,0,0,8,1,-2,0,0,8,1,-1,0,0,8,1,0,0,0,8,1,2,0,0,8,2,1,0,0,8,2,-4,0,0,8,2,-3,0,0,8,2,-2,0,0,8,2,-1,0,0,8,2,0,0,0,8,2,2,0,0,8,2,3,0,0,8,2,4,0,0,8,2,5,0,0,8,-4,-4,0,0,8,-4,-3,0,0,8,-4,-2,0,0,8,-4,-1,0,0,8,-4,0,0,0,8,-4,1,0,0,8,-4,2,0,0,8,-4,3,0,0,8,-4,4,0,0,8,-4,5,0,0,8,3,-4,0,0,8,3,-3,0,0,8,3,-2,0,0,8,3,-1,0,0,8,3,0,0,0,8,3,1,0,0,8,3,2,0,0,8,3,3,0,0,8,3,4,0,0,8,3,5,0,0,8],"Middle":[-4,-5,0,2,7,-3,-5,0,2,7,-2,-5,0,2,7,-1,-5,0,2,7,0,-5,0,2,7,1,-5,0,2,7,2,-5,0,2,7,3,-5,0,2,7],"Top":[-5,-5,0,3,4,-5,-4,0,3,3,-5,-3,0,3,3,-5,-2,0,3,3,-5,-1,0,3,3,-5,0,0,3,3,-5,1,0,3,3,-5,2,0,3,3,-5,3,0,3,3,-5,4,0,3,3,-5,5,0,3,3,-5,6,0,11,2,-4,6,0,2,2,-3,6,0,2,2,-2,3,0,1,2,-2,4,0,1,3,-2,5,0,1,3,-2,6,0,13,2,-1,3,0,2,2,0,3,0,2,2,1,3,0,3,2,1,4,0,3,3,1,5,0,3,3,1,6,0,11,2,2,6,0,2,2,3,6,0,2,2,4,-5,0,1,4,4,-4,0,1,3,4,-3,0,1,3,4,-2,0,1,3,4,-1,0,1,3,4,0,0,1,3,4,1,0,1,3,4,2,0,1,3,4,3,0,1,3,4,4,0,1,3,4,5,0,1,3,4,6,0,13,2]} \ No newline at end of file +{"NavigationList":[{"Type":0,"Points":[-152,-88,-120,-88,-120,-24,-56,-24,-56,-88,56,-88,56,96,40,96,40,48,-24,48,-24,96,-88,96,-88,16,-136,16,-136,32,-152,32]}],"Floor":[-3,-4,0,0,8,-3,-3,0,0,8,-3,-2,0,0,8,-3,-1,0,0,8,-3,0,0,0,8,-3,1,0,0,8,-3,2,0,0,8,-3,3,0,0,8,-3,4,0,0,8,-3,5,0,0,8,-2,-2,0,0,8,-2,-4,0,0,8,-2,-3,0,0,8,-2,-1,0,0,8,-2,0,0,0,8,-2,1,0,0,8,-2,2,0,0,8,-1,-1,0,0,8,-1,-4,0,0,8,-1,-3,0,0,8,-1,-2,0,0,8,-1,0,0,0,8,-1,1,0,0,8,-1,2,0,0,8,0,0,0,0,8,0,-4,0,0,8,0,-3,0,0,8,0,-2,0,0,8,0,-1,0,0,8,0,1,0,0,8,0,2,0,0,8,1,1,0,0,8,1,-4,0,0,8,1,-3,0,0,8,1,-2,0,0,8,1,-1,0,0,8,1,0,0,0,8,1,2,0,0,8,2,1,0,0,8,2,-4,0,0,8,2,-3,0,0,8,2,-2,0,0,8,2,-1,0,0,8,2,0,0,0,8,2,2,0,0,8,2,3,0,0,8,2,4,0,0,8,2,5,0,0,8,-4,-4,0,0,8,-4,-3,0,0,8,-4,-2,0,0,8,-4,-1,0,0,8,-4,0,0,0,8,-4,1,0,0,8,-4,2,0,0,8,-4,3,0,0,8,-4,4,0,0,8,-4,5,0,0,8,3,-4,0,0,8,3,-3,0,0,8,3,-2,0,0,8,3,-1,0,0,8,3,0,0,0,8,3,1,0,0,8,3,2,0,0,8,3,3,0,0,8,3,4,0,0,8,3,5,0,0,8,-9,-4,0,0,8,-9,-3,0,0,8,-9,-2,0,0,8,-9,-1,0,0,8,-9,0,0,0,8,-9,1,0,0,8,-8,-4,0,0,8,-8,-3,0,0,8,-8,-2,0,0,8,-8,-1,0,0,8,-8,0,0,0,8,-10,1,0,0,8,-10,0,0,0,8,-10,-1,0,0,8,-10,-2,0,0,8,-10,-3,0,0,8,-10,-4,0,0,8,-10,-5,0,0,8,-9,-5,0,0,8,-9,-6,0,0,8,-8,-6,0,0,8,-8,-5,0,0,8,-7,-2,0,0,8,-6,-2,0,0,8,-5,-2,0,0,8,-7,-1,0,0,8,-6,-1,0,0,8,-5,-1,0,0,8,-7,0,0,0,8,-6,0,0,0,8,-5,0,0,0,8,-10,-6,0,0,8,-4,-5,0,0,8,-3,-5,0,0,8,-2,-5,0,0,8,-1,-5,0,0,8,0,-5,0,0,8,1,-5,0,0,8,2,-5,0,0,8,3,-5,0,0,8,3,-6,0,0,8,2,-6,0,0,8,1,-6,0,0,8,0,-6,0,0,8,-1,-6,0,0,8,-2,-6,0,0,8,-3,-6,0,0,8,-4,-6,0,0,8,-2,4,0,0,8,-2,3,0,0,8,-2,5,0,0,8,-5,1,0,0,8,-5,2,0,0,8,-5,3,0,0,8,-5,4,0,0,8,-5,5,0,0,8,-6,1,0,0,8,-6,2,0,0,8,-6,3,0,0,8,-6,4,0,0,8,-6,5,0,0,8],"Middle":[-10,-7,0,2,7,-9,-7,0,2,7,-8,-7,0,2,7,-7,-3,0,1,7,-6,-3,0,2,7,-5,-3,0,3,7,-4,-7,0,2,7,-3,-7,0,2,7,-2,-7,0,2,7,-1,-7,0,2,7,0,-7,0,2,7,1,-7,0,2,7,2,-7,0,2,7,3,-7,0,2,7],"Top":[-11,-7,0,3,4,-11,-6,0,3,3,-11,-5,0,3,3,-11,-4,0,3,3,-11,-3,0,3,3,-11,-2,0,3,3,-11,-1,0,3,3,-11,0,0,3,3,-11,1,0,3,3,-11,2,0,11,2,-10,2,0,2,2,-9,2,0,2,2,-8,1,0,1,2,-8,2,0,13,2,-7,-7,0,1,4,-7,-6,0,1,3,-7,-5,0,1,3,-7,-4,0,1,3,-7,1,0,3,2,-7,2,0,3,3,-7,3,0,3,3,-7,4,0,3,3,-7,5,0,3,3,-7,6,0,11,2,-6,6,0,2,2,-5,-7,0,3,4,-5,-6,0,3,3,-5,-5,0,3,3,-5,-4,0,3,3,-5,6,0,2,2,-4,6,0,2,2,-3,6,0,2,2,-2,6,0,2,2,-1,3,0,1,2,-1,4,0,1,3,-1,5,0,1,3,-1,6,0,13,2,0,3,0,2,2,1,3,0,3,2,1,4,0,3,3,1,5,0,3,3,1,6,0,11,2,2,6,0,2,2,3,6,0,2,2,4,-7,0,1,4,4,-6,0,1,3,4,-5,0,1,3,4,-4,0,1,3,4,-3,0,1,3,4,-2,0,1,3,4,-1,0,1,3,4,0,0,1,3,4,1,0,1,3,4,2,0,1,3,4,3,0,1,3,4,4,0,1,3,4,5,0,1,3,4,6,0,13,2]} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/Preinstall.json new file mode 100644 index 0000000..1579f73 --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/Preinstall.json @@ -0,0 +1 @@ +[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":-84,"Y":-46},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":-85,"Y":-71},"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":-56,"Y":-72},"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":30,"Y":75},"Size":{"X":29,"Y":28},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-88,"Y":70},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0.8,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":65,"Y":-66},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0002","CurrAmmon":"7","ResidueAmmo":"7"},"Altitude":0,"VerticalSpeed":0}]}]]}] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/Preview.png b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/Preview.png new file mode 100644 index 0000000..2215059 --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/Preview.png Binary files differ diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/Preview.png.import b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/Preview.png.import new file mode 100644 index 0000000..59dce7f --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/Preview.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://hrny6himu2o8" +path="res://.godot/imported/Preview.png-36e30cc056284bf63e359cca99f69e15.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/map/tileMaps/TestGroup1/inlet/Start3/Preview.png" +dest_files=["res://.godot/imported/Preview.png-36e30cc056284bf63e359cca99f69e15.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/map/tileMaps/TestGroup1/inlet/Start3/RoomInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/RoomInfo.json new file mode 100644 index 0000000..a5d10e3 --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/RoomInfo.json @@ -0,0 +1 @@ +{"Position":{"X":-8,"Y":-7},"Size":{"X":15,"Y":14},"DoorAreaInfos":[{"Direction":1,"Start":0,"End":96},{"Direction":2,"Start":0,"End":208},{"Direction":0,"Start":0,"End":192},{"Direction":3,"Start":0,"End":208}],"GroupName":"TestGroup1","RoomType":1,"RoomName":"Start3","Weight":100,"Remark":""} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/TileInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/TileInfo.json new file mode 100644 index 0000000..53a6fcc --- /dev/null +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start3/TileInfo.json @@ -0,0 +1 @@ +{"NavigationList":[{"Type":0,"Points":[-104,-88,88,-88,88,96,-104,96,-104,40,72,40,72,0,-104,0]}],"Floor":[-7,-6,0,0,8,-7,-5,0,0,8,-7,-4,0,0,8,-7,-3,0,0,8,-7,-2,0,0,8,-7,-1,0,0,8,-7,2,0,0,8,-7,3,0,0,8,-7,4,0,0,8,-7,5,0,0,8,-6,-6,0,0,8,-6,-5,0,0,8,-6,-4,0,0,8,-6,-3,0,0,8,-6,-2,0,0,8,-6,-1,0,0,8,-6,2,0,0,8,-6,3,0,0,8,-6,4,0,0,8,-6,5,0,0,8,-5,-6,0,0,8,-5,-5,0,0,8,-5,-4,0,0,8,-5,-3,0,0,8,-5,-2,0,0,8,-5,-1,0,0,8,-5,2,0,0,8,-5,3,0,0,8,-5,4,0,0,8,-5,5,0,0,8,-4,-6,0,0,8,-4,-5,0,0,8,-4,-4,0,0,8,-4,-3,0,0,8,-4,-2,0,0,8,-4,-1,0,0,8,-4,2,0,0,8,-4,3,0,0,8,-4,4,0,0,8,-4,5,0,0,8,-3,-6,0,0,8,-3,-5,0,0,8,-3,-4,0,0,8,-3,-3,0,0,8,-3,-2,0,0,8,-3,-1,0,0,8,-3,2,0,0,8,-3,3,0,0,8,-3,4,0,0,8,-3,5,0,0,8,-2,-6,0,0,8,-2,-5,0,0,8,-2,-4,0,0,8,-2,-3,0,0,8,-2,-2,0,0,8,-2,-1,0,0,8,-2,2,0,0,8,-2,3,0,0,8,-2,4,0,0,8,-2,5,0,0,8,-1,-6,0,0,8,-1,-5,0,0,8,-1,-4,0,0,8,-1,-3,0,0,8,-1,-2,0,0,8,-1,-1,0,0,8,-1,2,0,0,8,-1,3,0,0,8,-1,4,0,0,8,-1,5,0,0,8,0,-6,0,0,8,0,-5,0,0,8,0,-4,0,0,8,0,-3,0,0,8,0,-2,0,0,8,0,-1,0,0,8,0,2,0,0,8,0,3,0,0,8,0,4,0,0,8,0,5,0,0,8,1,-6,0,0,8,1,-5,0,0,8,1,-4,0,0,8,1,-3,0,0,8,1,-2,0,0,8,1,-1,0,0,8,1,2,0,0,8,1,3,0,0,8,1,4,0,0,8,1,5,0,0,8,2,-6,0,0,8,2,-5,0,0,8,2,-4,0,0,8,2,-3,0,0,8,2,-2,0,0,8,2,-1,0,0,8,2,2,0,0,8,2,3,0,0,8,2,4,0,0,8,2,5,0,0,8,3,-6,0,0,8,3,-5,0,0,8,3,-4,0,0,8,3,-3,0,0,8,3,-2,0,0,8,3,-1,0,0,8,3,2,0,0,8,3,3,0,0,8,3,4,0,0,8,3,5,0,0,8,4,-6,0,0,8,4,-5,0,0,8,4,-4,0,0,8,4,-3,0,0,8,4,-2,0,0,8,4,-1,0,0,8,4,2,0,0,8,4,3,0,0,8,4,4,0,0,8,4,5,0,0,8,5,-6,0,0,8,5,-5,0,0,8,5,-4,0,0,8,5,-3,0,0,8,5,-2,0,0,8,5,-1,0,0,8,5,0,0,0,8,5,1,0,0,8,5,2,0,0,8,5,3,0,0,8,5,4,0,0,8,5,5,0,0,8,4,0,0,0,8,4,1,0,0,8],"Middle":[-7,-7,0,2,7,-7,1,0,2,7,-6,-7,0,2,7,-6,1,0,2,7,-5,-7,0,2,7,-5,1,0,2,7,-4,-7,0,2,7,-4,1,0,2,7,-3,-7,0,2,7,-3,1,0,2,7,-2,-7,0,2,7,-2,1,0,2,7,-1,-7,0,2,7,-1,1,0,2,7,0,-7,0,2,7,0,1,0,2,7,1,-7,0,2,7,1,1,0,2,7,2,-7,0,2,7,2,1,0,2,7,3,-7,0,2,7,3,1,0,3,7,4,-7,0,2,7,5,-7,0,2,7],"Top":[-8,-7,0,3,4,-8,-6,0,3,3,-8,-5,0,3,3,-8,-4,0,3,3,-8,-3,0,3,3,-8,-2,0,3,3,-8,-1,0,3,3,-8,0,0,11,2,-8,1,0,3,4,-8,2,0,3,3,-8,3,0,3,3,-8,4,0,3,3,-8,5,0,3,3,-8,6,0,11,2,-7,0,0,2,2,-7,6,0,2,2,-6,0,0,2,2,-6,6,0,2,2,-5,0,0,2,2,-5,6,0,2,2,-4,0,0,2,2,-4,6,0,2,2,-3,0,0,2,2,-3,6,0,2,2,-2,0,0,2,2,-2,6,0,2,2,-1,0,0,2,2,-1,6,0,2,2,0,0,0,2,2,0,6,0,2,2,1,0,0,2,2,1,6,0,2,2,2,0,0,2,2,2,6,0,2,2,3,0,0,3,2,3,6,0,2,2,4,6,0,2,2,5,6,0,2,2,6,-7,0,1,4,6,-6,0,1,3,6,-5,0,1,3,6,-4,0,1,3,6,-3,0,1,3,6,-2,0,1,3,6,-1,0,1,3,6,0,0,1,3,6,1,0,1,3,6,2,0,1,3,6,3,0,1,3,6,4,0,1,3,6,5,0,1,3,6,6,0,13,2]} \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileSprite/map1/16x16 dungeon ii wall reconfig v04 spritesheet.png b/DungeonShooting_Godot/resource/map/tileSprite/map1/16x16 dungeon ii wall reconfig v04 spritesheet.png index 26c54b7..00d2144 100644 --- a/DungeonShooting_Godot/resource/map/tileSprite/map1/16x16 dungeon ii wall reconfig v04 spritesheet.png +++ b/DungeonShooting_Godot/resource/map/tileSprite/map1/16x16 dungeon ii wall reconfig v04 spritesheet.png Binary files differ diff --git a/DungeonShooting_Godot/resource/material/Blend.gdshader b/DungeonShooting_Godot/resource/material/Blend.gdshader index f952fc5..bbd35e5 100644 --- a/DungeonShooting_Godot/resource/material/Blend.gdshader +++ b/DungeonShooting_Godot/resource/material/Blend.gdshader @@ -15,6 +15,8 @@ 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; @@ -46,13 +48,16 @@ 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/OffsetVertex.gdshader b/DungeonShooting_Godot/resource/material/OffsetVertex.gdshader new file mode 100644 index 0000000..f63d041 --- /dev/null +++ b/DungeonShooting_Godot/resource/material/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/sprite/role/common/Role_astonished.png b/DungeonShooting_Godot/resource/sprite/role/common/Role_astonished.png new file mode 100644 index 0000000..8d232dd --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/common/Role_astonished.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/common/Role_astonished.png.import b/DungeonShooting_Godot/resource/sprite/role/common/Role_astonished.png.import new file mode 100644 index 0000000..6eb2d0d --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/common/Role_astonished.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b75k7hefqy3tm" +path="res://.godot/imported/Role_astonished.png-8166b8786411283003a535d1677d0104.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/sprite/role/common/Role_astonished.png" +dest_files=["res://.godot/imported/Role_astonished.png-8166b8786411283003a535d1677d0104.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/common/Role_notify.png b/DungeonShooting_Godot/resource/sprite/role/common/Role_notify.png new file mode 100644 index 0000000..f2bddef --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/common/Role_notify.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/common/Role_notify.png.import b/DungeonShooting_Godot/resource/sprite/role/common/Role_notify.png.import new file mode 100644 index 0000000..0bd8a72 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/common/Role_notify.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://6jka6itu76x7" +path="res://.godot/imported/Role_notify.png-be3f9ba9bf6d85ab3633bbe6cbe960e3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/sprite/role/common/Role_notify.png" +dest_files=["res://.godot/imported/Role_notify.png-be3f9ba9bf6d85ab3633bbe6cbe960e3.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/common/Role_query.png b/DungeonShooting_Godot/resource/sprite/role/common/Role_query.png new file mode 100644 index 0000000..6e3c961 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/common/Role_query.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/common/Role_query.png.import b/DungeonShooting_Godot/resource/sprite/role/common/Role_query.png.import new file mode 100644 index 0000000..ec5e582 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/common/Role_query.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bda63puujv425" +path="res://.godot/imported/Role_query.png-99c4efcb33f8ce117e8e1704e40b8b3e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/sprite/role/common/Role_query.png" +dest_files=["res://.godot/imported/Role_query.png-99c4efcb33f8ce117e8e1704e40b8b3e.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/enemy0002/Enemy0002_attack.png b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_attack.png new file mode 100644 index 0000000..30c95c6 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_attack.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_attack.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_attack.png.import new file mode 100644 index 0000000..5342ed6 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_attack.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://byvhnaggvvfex" +path="res://.godot/imported/Enemy0002_attack.png-f20e305d5da437157c0eadd45ddd9904.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/sprite/role/enemy0002/Enemy0002_attack.png" +dest_files=["res://.godot/imported/Enemy0002_attack.png-f20e305d5da437157c0eadd45ddd9904.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/enemy0002/Enemy0002_dead.png b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_dead.png new file mode 100644 index 0000000..69431f9 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_dead.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_dead.png.import b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_dead.png.import new file mode 100644 index 0000000..1c26740 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/role/enemy0002/Enemy0002_dead.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://x3tjqgdgp43n" +path="res://.godot/imported/Enemy0002_dead.png-9318cf73f87fed753124e3e669c47c34.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/sprite/role/enemy0002/Enemy0002_dead.png" +dest_files=["res://.godot/imported/Enemy0002_dead.png-9318cf73f87fed753124e3e669c47c34.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/role0001/roll/Sprite-0002.png b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0002.png deleted file mode 100644 index df4b964..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0002.png +++ /dev/null Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0002.png.import b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0002.png.import deleted file mode 100644 index 10663d3..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0002.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d3thq2unooyl5" -path="res://.godot/imported/Sprite-0002.png-213031b39254f00c0c725e4252a9d486.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://resource/sprite/role/role0001/roll/Sprite-0002.png" -dest_files=["res://.godot/imported/Sprite-0002.png-213031b39254f00c0c725e4252a9d486.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/role0001/roll/Sprite-0003.png b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0003.png deleted file mode 100644 index 12b6942..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0003.png +++ /dev/null Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0003.png.import b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0003.png.import deleted file mode 100644 index c89343a..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0003.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ccqgkq5qv33il" -path="res://.godot/imported/Sprite-0003.png-e6803dc1c9e8f17b579f63f5e8cb8e23.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://resource/sprite/role/role0001/roll/Sprite-0003.png" -dest_files=["res://.godot/imported/Sprite-0003.png-e6803dc1c9e8f17b579f63f5e8cb8e23.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/role0001/roll/Sprite-0004.png b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0004.png deleted file mode 100644 index 6bc1574..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0004.png +++ /dev/null Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0004.png.import b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0004.png.import deleted file mode 100644 index 5e6e424..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0004.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://sknj4eflhbvc" -path="res://.godot/imported/Sprite-0004.png-8d2b0ef4221d99fc8d9133c4f11809ff.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://resource/sprite/role/role0001/roll/Sprite-0004.png" -dest_files=["res://.godot/imported/Sprite-0004.png-8d2b0ef4221d99fc8d9133c4f11809ff.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/role0001/roll/Sprite-0005.png b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0005.png deleted file mode 100644 index a1128d2..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0005.png +++ /dev/null Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0005.png.import b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0005.png.import deleted file mode 100644 index 7d04efe..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0005.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c8ijooj30lvpw" -path="res://.godot/imported/Sprite-0005.png-9c344cd4269051bef354e37f494af4b3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://resource/sprite/role/role0001/roll/Sprite-0005.png" -dest_files=["res://.godot/imported/Sprite-0005.png-9c344cd4269051bef354e37f494af4b3.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/role0001/roll/Sprite-0006.png b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0006.png deleted file mode 100644 index 0bb3b72..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0006.png +++ /dev/null Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0006.png.import b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0006.png.import deleted file mode 100644 index 2912fea..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0006.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://blqx76rvx6c34" -path="res://.godot/imported/Sprite-0006.png-1cb8bb9f32bbeef7eb914435df8b325e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://resource/sprite/role/role0001/roll/Sprite-0006.png" -dest_files=["res://.godot/imported/Sprite-0006.png-1cb8bb9f32bbeef7eb914435df8b325e.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/role0001/roll/Sprite-0007.png b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0007.png deleted file mode 100644 index a7f4176..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0007.png +++ /dev/null Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0007.png.import b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0007.png.import deleted file mode 100644 index 3dc376b..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0007.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://48qebkjqggub" -path="res://.godot/imported/Sprite-0007.png-e2c0f4efb93a9c9e29fa2a8da4c24baf.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://resource/sprite/role/role0001/roll/Sprite-0007.png" -dest_files=["res://.godot/imported/Sprite-0007.png-e2c0f4efb93a9c9e29fa2a8da4c24baf.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/role0001/roll/Sprite-0008.png b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0008.png index b15c6ef..462e9a3 100644 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0008.png +++ b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0008.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0008.png.import b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0008.png.import index 8da943b..db9467b 100644 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0008.png.import +++ b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0008.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dvrxriqd6dk1d" +uid="uid://b2hdk7nca5rda" path="res://.godot/imported/Sprite-0008.png-bf19680d71b1e849c210397f3a25fca2.ctex" metadata={ "vram_texture": false diff --git a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0009.png b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0009.png index 12b6942..7508707 100644 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0009.png +++ b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0009.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0009.png.import b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0009.png.import index c606373..98a613f 100644 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0009.png.import +++ b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0009.png.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://ceqi6d4vhbpt" +uid="uid://bmoh16y1r2h1w" path="res://.godot/imported/Sprite-0009.png-d266a086bd0825b44bd46a64ac6248f3.ctex" metadata={ "vram_texture": false diff --git a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0010.png b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0010.png deleted file mode 100644 index df4b964..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0010.png +++ /dev/null Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0010.png.import b/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0010.png.import deleted file mode 100644 index b6b498e..0000000 --- a/DungeonShooting_Godot/resource/sprite/role/role0001/roll/Sprite-0010.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cp8d5kqfwcyjf" -path="res://.godot/imported/Sprite-0010.png-c80699f0403ae66453b70f57a31ecc59.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://resource/sprite/role/role0001/roll/Sprite-0010.png" -dest_files=["res://.godot/imported/Sprite-0010.png-c80699f0403ae66453b70f57a31ecc59.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/spriteFrames/role/Enemy0002.tres b/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0002.tres index 227127a..76aae0b 100644 --- a/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0002.tres +++ b/DungeonShooting_Godot/resource/spriteFrames/role/Enemy0002.tres @@ -1,9 +1,42 @@ -[gd_resource type="SpriteFrames" load_steps=19 format=3 uid="uid://ctpkpxgcwb583"] +[gd_resource type="SpriteFrames" load_steps=28 format=3 uid="uid://ctpkpxgcwb583"] [ext_resource type="Texture2D" uid="uid://ba6ke6xp63lnv" path="res://resource/sprite/role/enemy0002/Enemy0002.png" id="1_bvqwm"] +[ext_resource type="Texture2D" uid="uid://byvhnaggvvfex" path="res://resource/sprite/role/enemy0002/Enemy0002_attack.png" id="1_ery1t"] [ext_resource type="Texture2D" uid="uid://bwafpoxpkx3lu" path="res://resource/sprite/role/enemy0002/Enemy0002_idle.png" id="2_755ta"] [ext_resource type="Texture2D" uid="uid://dibftt2rj5omq" path="res://resource/sprite/role/enemy0002/Enemy0002_run.png" id="3_xwtnk"] +[sub_resource type="AtlasTexture" id="AtlasTexture_dndp7"] +atlas = ExtResource("1_ery1t") +region = Rect2(0, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_vs2pd"] +atlas = ExtResource("1_ery1t") +region = Rect2(32, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_0k6qn"] +atlas = ExtResource("1_ery1t") +region = Rect2(64, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_h5xlr"] +atlas = ExtResource("1_ery1t") +region = Rect2(96, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_djcbg"] +atlas = ExtResource("1_ery1t") +region = Rect2(128, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_10of8"] +atlas = ExtResource("1_ery1t") +region = Rect2(160, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_5cxnc"] +atlas = ExtResource("1_ery1t") +region = Rect2(192, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_3f3fu"] +atlas = ExtResource("1_ery1t") +region = Rect2(224, 0, 32, 32) + [sub_resource type="AtlasTexture" id="AtlasTexture_pbkbq"] atlas = ExtResource("2_755ta") region = Rect2(32, 0, 32, 32) @@ -68,6 +101,35 @@ animations = [{ "frames": [{ "duration": 1.0, +"texture": SubResource("AtlasTexture_dndp7") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_vs2pd") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_0k6qn") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_h5xlr") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_djcbg") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_10of8") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_5cxnc") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_3f3fu") +}], +"loop": false, +"name": &"attack", +"speed": 15.0 +}, { +"frames": [{ +"duration": 1.0, "texture": ExtResource("1_bvqwm") }], "loop": true, @@ -98,7 +160,7 @@ }], "loop": true, "name": &"idle", -"speed": 7.0 +"speed": 10.0 }, { "frames": [{ "duration": 1.0, diff --git a/DungeonShooting_Godot/resource/spriteFrames/role/Role0001.tres b/DungeonShooting_Godot/resource/spriteFrames/role/Role0001.tres index 8205354..481275b 100644 --- a/DungeonShooting_Godot/resource/spriteFrames/role/Role0001.tres +++ b/DungeonShooting_Godot/resource/spriteFrames/role/Role0001.tres @@ -1,4 +1,4 @@ -[gd_resource type="SpriteFrames" load_steps=21 format=3 uid="uid://n11thtali6es"] +[gd_resource type="SpriteFrames" load_steps=17 format=3 uid="uid://n11thtali6es"] [ext_resource type="Texture2D" uid="uid://ekas4lqprrml" path="res://resource/sprite/role/role0001/idle/Sprite-0002.png" id="1_le6bk"] [ext_resource type="Texture2D" uid="uid://b81k08ofpf2oo" path="res://resource/sprite/role/role0001/idle/Sprite-0003.png" id="2_whsc2"] @@ -14,12 +14,8 @@ [ext_resource type="Texture2D" uid="uid://d32g0f5vk68sj" path="res://resource/sprite/role/role0001/run/Sprite-0004.png" id="12_cbabh"] [ext_resource type="Texture2D" uid="uid://cw83liyy6gnln" path="res://resource/sprite/role/role0001/run/Sprite-0003.png" id="13_u0cmp"] [ext_resource type="Texture2D" uid="uid://b1gh481w2xvsl" path="res://resource/sprite/role/role0001/run/Sprite-0002.png" id="14_nlfq5"] -[ext_resource type="Texture2D" uid="uid://sknj4eflhbvc" path="res://resource/sprite/role/role0001/roll/Sprite-0004.png" id="17_xnddk"] -[ext_resource type="Texture2D" uid="uid://c8ijooj30lvpw" path="res://resource/sprite/role/role0001/roll/Sprite-0005.png" id="18_1doii"] -[ext_resource type="Texture2D" uid="uid://blqx76rvx6c34" path="res://resource/sprite/role/role0001/roll/Sprite-0006.png" id="19_ilt25"] -[ext_resource type="Texture2D" uid="uid://48qebkjqggub" path="res://resource/sprite/role/role0001/roll/Sprite-0007.png" id="20_tp03g"] -[ext_resource type="Texture2D" uid="uid://dvrxriqd6dk1d" path="res://resource/sprite/role/role0001/roll/Sprite-0008.png" id="21_oocqa"] -[ext_resource type="Texture2D" uid="uid://ceqi6d4vhbpt" path="res://resource/sprite/role/role0001/roll/Sprite-0009.png" id="22_yc5ek"] +[ext_resource type="Texture2D" uid="uid://b2hdk7nca5rda" path="res://resource/sprite/role/role0001/roll/Sprite-0008.png" id="21_oocqa"] +[ext_resource type="Texture2D" uid="uid://bmoh16y1r2h1w" path="res://resource/sprite/role/role0001/roll/Sprite-0009.png" id="22_yc5ek"] [resource] animations = [{ @@ -85,18 +81,6 @@ }, { "frames": [{ "duration": 1.0, -"texture": ExtResource("17_xnddk") -}, { -"duration": 1.0, -"texture": ExtResource("18_1doii") -}, { -"duration": 1.0, -"texture": ExtResource("19_ilt25") -}, { -"duration": 1.0, -"texture": ExtResource("20_tp03g") -}, { -"duration": 1.0, "texture": ExtResource("21_oocqa") }, { "duration": 1.0, diff --git a/DungeonShooting_Godot/resource/spriteFrames/role/Role_tip.tres b/DungeonShooting_Godot/resource/spriteFrames/role/Role_tip.tres new file mode 100644 index 0000000..f1a0e7a --- /dev/null +++ b/DungeonShooting_Godot/resource/spriteFrames/role/Role_tip.tres @@ -0,0 +1,107 @@ +[gd_resource type="SpriteFrames" load_steps=14 format=3 uid="uid://c8h5svp76h3kw"] + +[ext_resource type="Texture2D" uid="uid://b75k7hefqy3tm" path="res://resource/sprite/role/common/Role_astonished.png" id="1_tbb6m"] +[ext_resource type="Texture2D" uid="uid://6jka6itu76x7" path="res://resource/sprite/role/common/Role_notify.png" id="2_0e3tg"] +[ext_resource type="Texture2D" uid="uid://bda63puujv425" path="res://resource/sprite/role/common/Role_query.png" id="2_70ucj"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_fn2rk"] +atlas = ExtResource("2_0e3tg") +region = Rect2(0, 0, 10, 10) + +[sub_resource type="AtlasTexture" id="AtlasTexture_cofxm"] +atlas = ExtResource("2_0e3tg") +region = Rect2(10, 0, 10, 10) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ml0d0"] +atlas = ExtResource("2_0e3tg") +region = Rect2(20, 0, 10, 10) + +[sub_resource type="AtlasTexture" id="AtlasTexture_w7tts"] +atlas = ExtResource("2_0e3tg") +region = Rect2(30, 0, 10, 10) + +[sub_resource type="AtlasTexture" id="AtlasTexture_sfnsa"] +atlas = ExtResource("2_0e3tg") +region = Rect2(40, 0, 10, 10) + +[sub_resource type="AtlasTexture" id="AtlasTexture_i8sk2"] +atlas = ExtResource("2_0e3tg") +region = Rect2(50, 0, 10, 10) + +[sub_resource type="AtlasTexture" id="AtlasTexture_iu1kr"] +atlas = ExtResource("2_0e3tg") +region = Rect2(60, 0, 10, 10) + +[sub_resource type="AtlasTexture" id="AtlasTexture_men28"] +atlas = ExtResource("2_0e3tg") +region = Rect2(70, 0, 10, 10) + +[sub_resource type="AtlasTexture" id="AtlasTexture_mrwdd"] +atlas = ExtResource("2_0e3tg") +region = Rect2(80, 0, 10, 10) + +[sub_resource type="AtlasTexture" id="AtlasTexture_v47to"] +atlas = ExtResource("2_0e3tg") +region = Rect2(90, 0, 10, 10) + +[resource] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": ExtResource("1_tbb6m") +}], +"loop": false, +"name": &"astonished", +"speed": 5.0 +}, { +"frames": [], +"loop": true, +"name": &"default", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_fn2rk") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_cofxm") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ml0d0") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_w7tts") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_sfnsa") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_i8sk2") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_iu1kr") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_men28") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_mrwdd") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_v47to") +}, { +"duration": 1.0, +"texture": null +}], +"loop": false, +"name": &"notify", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("2_70ucj") +}], +"loop": false, +"name": &"query", +"speed": 5.0 +}] diff --git a/DungeonShooting_Godot/scene/Main.tscn b/DungeonShooting_Godot/scene/Main.tscn index 080a8f2..346e221 100644 --- a/DungeonShooting_Godot/scene/Main.tscn +++ b/DungeonShooting_Godot/scene/Main.tscn @@ -2,22 +2,10 @@ [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"] -[sub_resource type="Shader" id="1"] -code = "shader_type canvas_item; - -uniform vec2 offset = vec2(0.0 , 0.0); - -void vertex() { - - VERTEX += offset; - -} - -" - -[sub_resource type="ShaderMaterial" id="2"] -shader = SubResource("1") +[sub_resource type="ShaderMaterial" id="ShaderMaterial_pjtkw"] +shader = ExtResource("2_fxoum") shader_parameter/offset = Vector2(0, 0) [node name="Main" type="Node2D" node_paths=PackedStringArray("SubViewport", "SubViewportContainer", "SceneRoot", "GlobalNodeRoot")] @@ -32,12 +20,13 @@ layer = -1 [node name="SubViewportContainer" type="SubViewportContainer" parent="ViewCanvas"] -material = SubResource("2") +material = SubResource("ShaderMaterial_pjtkw") offset_right = 480.0 offset_bottom = 270.0 scale = Vector2(4, 4) [node name="SubViewport" type="SubViewport" parent="ViewCanvas/SubViewportContainer"] +disable_3d = true handle_input_locally = false use_hdr_2d = true canvas_item_default_texture_filter = 0 @@ -47,6 +36,7 @@ [node name="SceneRoot" type="Node2D" parent="ViewCanvas/SubViewportContainer/SubViewport"] [node name="Camera2D" type="Camera2D" parent="ViewCanvas/SubViewportContainer/SubViewport"] +process_callback = 0 editor_draw_drag_margin = true script = ExtResource("2_2j367") diff --git a/DungeonShooting_Godot/scene/test/TestPerfectPixel.tscn b/DungeonShooting_Godot/scene/test/TestPerfectPixel.tscn new file mode 100644 index 0000000..5e7cd81 --- /dev/null +++ b/DungeonShooting_Godot/scene/test/TestPerfectPixel.tscn @@ -0,0 +1,32 @@ +[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="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) + +[node name="TestPerfectPixel" type="SubViewportContainer"] +material = SubResource("ShaderMaterial_lm6np") +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -4.0 +offset_top = -4.0 +offset_right = -4.0 +offset_bottom = -4.0 +grow_horizontal = 2 +grow_vertical = 2 +scale = Vector2(4, 4) + +[node name="SubViewport" type="SubViewport" parent="."] +disable_3d = true +handle_input_locally = false +use_hdr_2d = true +canvas_item_default_texture_filter = 0 +size = Vector2i(482, 272) +render_target_update_mode = 4 + +[node name="TestPerfectPixelScene" parent="SubViewport" node_paths=PackedStringArray("SubViewportContainer") instance=ExtResource("1_l3du1")] +SubViewportContainer = NodePath("../..") diff --git a/DungeonShooting_Godot/scene/test/TestPerfectPixelScene.tscn b/DungeonShooting_Godot/scene/test/TestPerfectPixelScene.tscn new file mode 100644 index 0000000..e8bcfc6 --- /dev/null +++ b/DungeonShooting_Godot/scene/test/TestPerfectPixelScene.tscn @@ -0,0 +1,81 @@ +[gd_scene load_steps=6 format=3 uid="uid://b3ybffxcq0kkb"] + +[ext_resource type="Script" path="res://src/test/TestPerfectPixelScene.cs" id="1_u6ihh"] +[ext_resource type="TileSet" uid="uid://b00g22o1cqhe8" path="res://resource/map/tileSet/map1/TileSet1.tres" id="1_wc2ux"] +[ext_resource type="Texture2D" uid="uid://dto03bc2qbhnj" path="res://resource/sprite/shell/Shell0001.png" id="3_kc4l0"] +[ext_resource type="SpriteFrames" uid="uid://n11thtali6es" path="res://resource/spriteFrames/role/Role0001.tres" id="4_6nerw"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_tmsub"] + +[node name="TestPerfectPixelScene" type="Node2D" node_paths=PackedStringArray("Player", "FpsLabel", "Camera2D")] +script = ExtResource("1_u6ihh") +Player = NodePath("Root/Player") +FpsLabel = NodePath("CanvasLayer/FPS") +Camera2D = NodePath("Camera2D") +Speed = 150.0 +CameraRecoveryScale = 7.0 +Type = 2 + +[node name="TileMap" type="TileMap" parent="."] +tile_set = ExtResource("1_wc2ux") +format = 2 +layer_0/tile_data = PackedInt32Array(1900589, 0, 8, 1835053, 0, 8, 1769517, 0, 8, 1703981, 0, 8, 1638445, 0, 8, 1572909, 0, 8, 1507373, 0, 8, 1441837, 0, 8, 1376301, 0, 8, 1310765, 0, 8, 1245229, 0, 8, 1179693, 0, 8, 1114157, 0, 8, 1048621, 0, 8, 983085, 0, 8, 917549, 0, 8, 852013, 0, 8, 786477, 0, 8, 720941, 0, 8, 655405, 0, 8, 589869, 0, 8, 524333, 0, 8, 458797, 0, 8, 393261, 0, 8, 327725, 0, 8, 262189, 0, 8, 196653, 0, 8, 131117, 0, 8, 65581, 0, 8, 45, 0, 8, -65491, 0, 8, -131027, 0, 8, -196563, 0, 8, -262099, 0, 8, 1900588, 0, 8, 1835052, 0, 8, 1769516, 0, 8, 1703980, 0, 8, 1638444, 0, 8, 1572908, 0, 8, 1507372, 0, 8, 1441836, 0, 8, 1376300, 0, 8, 1310764, 0, 8, 1245228, 0, 8, 1179692, 0, 8, 1114156, 0, 8, 1048620, 0, 8, 983084, 0, 8, 917548, 0, 8, 852012, 0, 8, 786476, 0, 8, 720940, 0, 8, 655404, 0, 8, 589868, 0, 8, 524332, 0, 8, 458796, 0, 8, 393260, 0, 8, 327724, 0, 8, 262188, 0, 8, 196652, 0, 8, 131116, 0, 8, 65580, 0, 8, 44, 0, 8, -65492, 0, 8, -131028, 0, 8, -196564, 0, 8, -262100, 0, 8, 1900587, 0, 8, 1835051, 0, 8, 1769515, 0, 8, 1703979, 0, 8, 1638443, 0, 8, 1572907, 0, 8, 1507371, 0, 8, 1441835, 0, 8, 1376299, 0, 8, 1310763, 0, 8, 1245227, 0, 8, 1179691, 0, 8, 1114155, 0, 8, 1048619, 0, 8, 983083, 0, 8, 917547, 0, 8, 852011, 0, 8, 786475, 0, 8, 720939, 0, 8, 655403, 0, 8, 589867, 0, 8, 524331, 0, 8, 458795, 0, 8, 393259, 0, 8, 327723, 0, 8, 262187, 0, 8, 196651, 0, 8, 131115, 0, 8, 65579, 0, 8, 43, 0, 8, -65493, 0, 8, -131029, 0, 8, -196565, 0, 8, -262101, 0, 8, 1900586, 0, 8, 1835050, 0, 8, 1769514, 0, 8, 1703978, 0, 8, 1638442, 0, 8, 1572906, 0, 8, 1507370, 0, 8, 1441834, 0, 8, 1376298, 0, 8, 1310762, 0, 8, 1245226, 0, 8, 1179690, 0, 8, 1114154, 0, 8, 1048618, 0, 8, 983082, 0, 8, 917546, 0, 8, 852010, 0, 8, 786474, 0, 8, 720938, 0, 8, 655402, 0, 8, 589866, 0, 8, 524330, 0, 8, 458794, 0, 8, 393258, 0, 8, 327722, 0, 8, 262186, 0, 8, 196650, 0, 8, 131114, 0, 8, 65578, 0, 8, 42, 0, 8, -65494, 0, 8, -131030, 0, 8, -196566, 0, 8, -262102, 0, 8, 1900585, 0, 8, 1835049, 0, 8, 1769513, 0, 8, 1703977, 0, 8, 1638441, 0, 8, 1572905, 0, 8, 1507369, 0, 8, 1441833, 0, 8, 1376297, 0, 8, 1310761, 0, 8, 1245225, 0, 8, 1179689, 0, 8, 1114153, 0, 8, 1048617, 0, 8, 983081, 0, 8, 917545, 0, 8, 852009, 0, 8, 786473, 0, 8, 720937, 0, 8, 655401, 0, 8, 589865, 0, 8, 524329, 0, 8, 458793, 0, 8, 393257, 0, 8, 327721, 0, 8, 262185, 0, 8, 196649, 0, 8, 131113, 0, 8, 65577, 0, 8, 41, 0, 8, -65495, 0, 8, -131031, 0, 8, -196567, 0, 8, -262103, 0, 8, 1900584, 0, 8, 1835048, 0, 8, 1769512, 0, 8, 1703976, 0, 8, 1638440, 0, 8, 1572904, 0, 8, 1507368, 0, 8, 1441832, 0, 8, 1376296, 0, 8, 1310760, 0, 8, 1245224, 0, 8, 1179688, 0, 8, 1114152, 0, 8, 1048616, 0, 8, 983080, 0, 8, 917544, 0, 8, 852008, 0, 8, 786472, 0, 8, 720936, 0, 8, 655400, 0, 8, 589864, 0, 8, 524328, 0, 8, 458792, 0, 8, 393256, 0, 8, 327720, 0, 8, 262184, 0, 8, 196648, 0, 8, 131112, 0, 8, 65576, 0, 8, 40, 0, 8, -65496, 0, 8, -131032, 0, 8, -196568, 0, 8, -262104, 0, 8, 1900583, 0, 8, 1835047, 0, 8, 1769511, 0, 8, 1703975, 0, 8, 1638439, 0, 8, 1572903, 0, 8, 1507367, 0, 8, 1441831, 0, 8, 1376295, 0, 8, 1310759, 0, 8, 1245223, 0, 8, 1179687, 0, 8, 1114151, 0, 8, 1048615, 0, 8, 983079, 0, 8, 917543, 0, 8, 852007, 0, 8, 786471, 0, 8, 720935, 0, 8, 655399, 0, 8, 589863, 0, 8, 524327, 0, 8, 458791, 0, 8, 393255, 0, 8, 327719, 0, 8, 262183, 0, 8, 196647, 0, 8, 131111, 0, 8, 65575, 0, 8, 39, 0, 8, -65497, 0, 8, -131033, 0, 8, -196569, 0, 8, -262105, 0, 8, 1900582, 0, 8, 1835046, 0, 8, 1769510, 0, 8, 1703974, 0, 8, 1638438, 0, 8, 1572902, 0, 8, 1507366, 0, 8, 1441830, 0, 8, 1376294, 0, 8, 1310758, 0, 8, 1245222, 0, 8, 1179686, 0, 8, 1114150, 0, 8, 1048614, 0, 8, 983078, 0, 8, 917542, 0, 8, 852006, 0, 8, 786470, 0, 8, 720934, 0, 8, 655398, 0, 8, 589862, 0, 8, 524326, 0, 8, 458790, 0, 8, 393254, 0, 8, 327718, 0, 8, 262182, 0, 8, 196646, 0, 8, 131110, 0, 8, 65574, 0, 8, 38, 0, 8, -65498, 0, 8, -131034, 0, 8, -196570, 0, 8, -262106, 0, 8, 1900581, 0, 8, 1835045, 0, 8, 1769509, 0, 8, 1703973, 0, 8, 1638437, 0, 8, 1572901, 0, 8, 1507365, 0, 8, 1441829, 0, 8, 1376293, 0, 8, 1310757, 0, 8, 1245221, 0, 8, 1179685, 0, 8, 1114149, 0, 8, 1048613, 0, 8, 983077, 0, 8, 917541, 0, 8, 852005, 0, 8, 786469, 0, 8, 720933, 0, 8, 655397, 0, 8, 589861, 0, 8, 524325, 0, 8, 458789, 0, 8, 393253, 0, 8, 327717, 0, 8, 262181, 0, 8, 196645, 0, 8, 131109, 0, 8, 65573, 0, 8, 37, 0, 8, -65499, 0, 8, -131035, 0, 8, -196571, 0, 8, -262107, 0, 8, 1900580, 0, 8, 1835044, 0, 8, 1769508, 0, 8, 1703972, 0, 8, 1638436, 0, 8, 1572900, 0, 8, 1507364, 0, 8, 1441828, 0, 8, 1376292, 0, 8, 1310756, 0, 8, 1245220, 0, 8, 1179684, 0, 8, 1114148, 0, 8, 1048612, 0, 8, 983076, 0, 8, 917540, 0, 8, 852004, 0, 8, 786468, 0, 8, 720932, 0, 8, 655396, 0, 8, 589860, 0, 8, 524324, 0, 8, 458788, 0, 8, 393252, 0, 8, 327716, 0, 8, 262180, 0, 8, 196644, 0, 8, 131108, 0, 8, 65572, 0, 8, 36, 0, 8, -65500, 0, 8, -131036, 0, 8, -196572, 0, 8, -262108, 0, 8, 1900579, 0, 8, 1835043, 0, 8, 1769507, 0, 8, 1703971, 0, 8, 1638435, 0, 8, 1572899, 0, 8, 1507363, 0, 8, 1441827, 0, 8, 1376291, 0, 8, 1310755, 0, 8, 1245219, 0, 8, 1179683, 0, 8, 1114147, 0, 8, 1048611, 0, 8, 983075, 0, 8, 917539, 0, 8, 852003, 0, 8, 786467, 0, 8, 720931, 0, 8, 655395, 0, 8, 589859, 0, 8, 524323, 0, 8, 458787, 0, 8, 393251, 0, 8, 327715, 0, 8, 262179, 0, 8, 196643, 0, 8, 131107, 0, 8, 65571, 0, 8, 35, 0, 8, -65501, 0, 8, -131037, 0, 8, -196573, 0, 8, -262109, 0, 8, 1900578, 0, 8, 1835042, 0, 8, 1769506, 0, 8, 1703970, 0, 8, 1638434, 0, 8, 1572898, 0, 8, 1507362, 0, 8, 1441826, 0, 8, 1376290, 0, 8, 1310754, 0, 8, 1245218, 0, 8, 1179682, 0, 8, 1114146, 0, 8, 1048610, 0, 8, 983074, 0, 8, 917538, 0, 8, 852002, 0, 8, 786466, 0, 8, 720930, 0, 8, 655394, 0, 8, 589858, 0, 8, 524322, 0, 8, 458786, 0, 8, 393250, 0, 8, 327714, 0, 8, 262178, 0, 8, 196642, 0, 8, 131106, 0, 8, 65570, 0, 8, 34, 0, 8, -65502, 0, 8, -131038, 0, 8, -196574, 0, 8, -262110, 0, 8, 1900577, 0, 8, 1835041, 0, 8, 1769505, 0, 8, 1703969, 0, 8, 1638433, 0, 8, 1572897, 0, 8, 1507361, 0, 8, 1441825, 0, 8, 1376289, 0, 8, 1310753, 0, 8, 1245217, 0, 8, 1179681, 0, 8, 1114145, 0, 8, 1048609, 0, 8, 983073, 0, 8, 917537, 0, 8, 852001, 0, 8, 786465, 0, 8, 720929, 0, 8, 655393, 0, 8, 589857, 0, 8, 524321, 0, 8, 458785, 0, 8, 393249, 0, 8, 327713, 0, 8, 262177, 0, 8, 196641, 0, 8, 131105, 0, 8, 65569, 0, 8, 33, 0, 8, -65503, 0, 8, -131039, 0, 8, -196575, 0, 8, -262111, 0, 8, 1900576, 0, 8, 1835040, 0, 8, 1769504, 0, 8, 1703968, 0, 8, 1638432, 0, 8, 1572896, 0, 8, 1507360, 0, 8, 1441824, 0, 8, 1376288, 0, 8, 1310752, 0, 8, 1245216, 0, 8, 1179680, 0, 8, 1114144, 0, 8, 1048608, 0, 8, 983072, 0, 8, 917536, 0, 8, 852000, 0, 8, 786464, 0, 8, 720928, 0, 8, 655392, 0, 8, 589856, 0, 8, 524320, 0, 8, 458784, 0, 8, 393248, 0, 8, 327712, 0, 8, 262176, 0, 8, 196640, 0, 8, 131104, 0, 8, 65568, 0, 8, 32, 0, 8, -65504, 0, 8, -131040, 0, 8, -196576, 0, 8, -262112, 0, 8, 1900575, 0, 8, 1835039, 0, 8, 1769503, 0, 8, 1703967, 0, 8, 1638431, 0, 8, 1572895, 0, 8, 1507359, 0, 8, 1441823, 0, 8, 1376287, 0, 8, 1310751, 0, 8, 1245215, 0, 8, 1179679, 0, 8, 1114143, 0, 8, 1048607, 0, 8, 983071, 0, 8, 917535, 0, 8, 851999, 0, 8, 786463, 0, 8, 720927, 0, 8, 655391, 0, 8, 589855, 0, 8, 524319, 0, 8, 458783, 0, 8, 393247, 0, 8, 327711, 0, 8, 262175, 0, 8, 196639, 0, 8, 131103, 0, 8, 65567, 0, 8, 31, 0, 8, -65505, 0, 8, -131041, 0, 8, -196577, 0, 8, -262113, 0, 8, 1900574, 0, 8, 1835038, 0, 8, 1769502, 0, 8, 1703966, 0, 8, 1638430, 0, 8, 1572894, 0, 8, 1507358, 0, 8, 1441822, 0, 8, 1376286, 0, 8, 1310750, 0, 8, 1245214, 0, 8, 1179678, 0, 8, 1114142, 0, 8, 1048606, 0, 8, 983070, 0, 8, 917534, 0, 8, 851998, 0, 8, 786462, 0, 8, 720926, 0, 8, 655390, 0, 8, 589854, 0, 8, 524318, 0, 8, 458782, 0, 8, 393246, 0, 8, 327710, 0, 8, 262174, 0, 8, 196638, 0, 8, 131102, 0, 8, 65566, 0, 8, 30, 0, 8, -65506, 0, 8, -131042, 0, 8, -196578, 0, 8, -262114, 0, 8, 1900573, 0, 8, 1835037, 0, 8, 1769501, 0, 8, 1703965, 0, 8, 1638429, 0, 8, 1572893, 0, 8, 1507357, 0, 8, 1441821, 0, 8, 1376285, 0, 8, 1310749, 0, 8, 1245213, 0, 8, 1179677, 0, 8, 1114141, 0, 8, 1048605, 0, 8, 983069, 0, 8, 917533, 0, 8, 851997, 0, 8, 786461, 0, 8, 720925, 0, 8, 655389, 0, 8, 589853, 0, 8, 524317, 0, 8, 458781, 0, 8, 393245, 0, 8, 327709, 0, 8, 262173, 0, 8, 196637, 0, 8, 131101, 0, 8, 65565, 0, 8, 29, 0, 8, -65507, 0, 8, -131043, 0, 8, -196579, 0, 8, -262115, 0, 8, 1900572, 0, 8, 1835036, 0, 8, 1769500, 0, 8, 1703964, 0, 8, 1638428, 0, 8, 1572892, 0, 8, 1507356, 0, 8, 1441820, 0, 8, 1376284, 0, 8, 1310748, 0, 8, 1245212, 0, 8, 1179676, 0, 8, 1114140, 0, 8, 1048604, 0, 8, 983068, 0, 8, 917532, 0, 8, 851996, 0, 8, 786460, 0, 8, 720924, 0, 8, 655388, 0, 8, 589852, 0, 8, 524316, 0, 8, 458780, 0, 8, 393244, 0, 8, 327708, 0, 8, 262172, 0, 8, 196636, 0, 8, 131100, 0, 8, 65564, 0, 8, 28, 0, 8, -65508, 0, 8, -131044, 0, 8, -196580, 0, 8, -262116, 0, 8, 1900571, 0, 8, 1835035, 0, 8, 1769499, 0, 8, 1703963, 0, 8, 1638427, 0, 8, 1572891, 0, 8, 1507355, 0, 8, 1441819, 0, 8, 1376283, 0, 8, 1310747, 0, 8, 1245211, 0, 8, 1179675, 0, 8, 1114139, 0, 8, 1048603, 0, 8, 983067, 0, 8, 917531, 0, 8, 851995, 0, 8, 786459, 0, 8, 720923, 0, 8, 655387, 0, 8, 589851, 0, 8, 524315, 0, 8, 458779, 0, 8, 393243, 0, 8, 327707, 0, 8, 262171, 0, 8, 196635, 0, 8, 131099, 0, 8, 65563, 0, 8, 27, 0, 8, -65509, 0, 8, -131045, 0, 8, -196581, 0, 8, -262117, 0, 8, 1900570, 0, 8, 1835034, 0, 8, 1769498, 0, 8, 1703962, 0, 8, 1638426, 0, 8, 1572890, 0, 8, 1507354, 0, 8, 1441818, 0, 8, 1376282, 0, 8, 1310746, 0, 8, 1245210, 0, 8, 1179674, 0, 8, 1114138, 0, 8, 1048602, 0, 8, 983066, 0, 8, 917530, 0, 8, 851994, 0, 8, 786458, 0, 8, 720922, 0, 8, 655386, 0, 8, 589850, 0, 8, 524314, 0, 8, 458778, 0, 8, 393242, 0, 8, 327706, 0, 8, 262170, 0, 8, 196634, 0, 8, 131098, 0, 8, 65562, 0, 8, 26, 0, 8, -65510, 0, 8, -131046, 0, 8, -196582, 0, 8, -262118, 0, 8, 1900569, 0, 8, 1835033, 0, 8, 1769497, 0, 8, 1703961, 0, 8, 1638425, 0, 8, 1572889, 0, 8, 1507353, 0, 8, 1441817, 0, 8, 1376281, 0, 8, 1310745, 0, 8, 1245209, 0, 8, 1179673, 0, 8, 1114137, 0, 8, 1048601, 0, 8, 983065, 0, 8, 917529, 0, 8, 851993, 0, 8, 786457, 0, 8, 720921, 0, 8, 655385, 0, 8, 589849, 0, 8, 524313, 0, 8, 458777, 0, 8, 393241, 0, 8, 327705, 0, 8, 262169, 0, 8, 196633, 0, 8, 131097, 0, 8, 65561, 0, 8, 25, 0, 8, -65511, 0, 8, -131047, 0, 8, -196583, 0, 8, -262119, 0, 8, 1900568, 0, 8, 1835032, 0, 8, 1769496, 0, 8, 1703960, 0, 8, 1638424, 0, 8, 1572888, 0, 8, 1507352, 0, 8, 1441816, 0, 8, 1376280, 0, 8, 1310744, 0, 8, 1245208, 0, 8, 1179672, 0, 8, 1114136, 0, 8, 1048600, 0, 8, 983064, 0, 8, 917528, 0, 8, 851992, 0, 8, 786456, 0, 8, 720920, 0, 8, 655384, 0, 8, 589848, 0, 8, 524312, 0, 8, 458776, 0, 8, 393240, 0, 8, 327704, 0, 8, 262168, 0, 8, 196632, 0, 8, 131096, 0, 8, 65560, 0, 8, 24, 0, 8, -65512, 0, 8, -131048, 0, 8, -196584, 0, 8, -262120, 0, 8, 1900567, 0, 8, 1835031, 0, 8, 1769495, 0, 8, 1703959, 0, 8, 1638423, 0, 8, 1572887, 0, 8, 1507351, 0, 8, 1441815, 0, 8, 1376279, 0, 8, 1310743, 0, 8, 1245207, 0, 8, 1179671, 0, 8, 1114135, 0, 8, 1048599, 0, 8, 983063, 0, 8, 917527, 0, 8, 851991, 0, 8, 786455, 0, 8, 720919, 0, 8, 655383, 0, 8, 589847, 0, 8, 524311, 0, 8, 458775, 0, 8, 393239, 0, 8, 327703, 0, 8, 262167, 0, 8, 196631, 0, 8, 131095, 0, 8, 65559, 0, 8, 23, 0, 8, -65513, 0, 8, -131049, 0, 8, -196585, 0, 8, -262121, 0, 8, 1900566, 0, 8, 1835030, 0, 8, 1769494, 0, 8, 1703958, 0, 8, 1638422, 0, 8, 1572886, 0, 8, 1507350, 0, 8, 1441814, 0, 8, 1376278, 0, 8, 1310742, 0, 8, 1245206, 0, 8, 1179670, 0, 8, 1114134, 0, 8, 1048598, 0, 8, 983062, 0, 8, 917526, 0, 8, 851990, 0, 8, 786454, 0, 8, 720918, 0, 8, 655382, 0, 8, 589846, 0, 8, 524310, 0, 8, 458774, 0, 8, 393238, 0, 8, 327702, 0, 8, 262166, 0, 8, 196630, 0, 8, 131094, 0, 8, 65558, 0, 8, 22, 0, 8, -65514, 0, 8, -131050, 0, 8, -196586, 0, 8, -262122, 0, 8, 1900565, 0, 8, 1835029, 0, 8, 1769493, 0, 8, 1703957, 0, 8, 1638421, 0, 8, 1572885, 0, 8, 1507349, 0, 8, 1441813, 0, 8, 1376277, 0, 8, 1310741, 0, 8, 1245205, 0, 8, 1179669, 0, 8, 1114133, 0, 8, 1048597, 0, 8, 983061, 0, 8, 917525, 0, 8, 851989, 0, 8, 786453, 0, 8, 720917, 0, 8, 655381, 0, 8, 589845, 0, 8, 524309, 0, 8, 458773, 0, 8, 393237, 0, 8, 327701, 0, 8, 262165, 0, 8, 196629, 0, 8, 131093, 0, 8, 65557, 0, 8, 21, 0, 8, -65515, 0, 8, -131051, 0, 8, -196587, 0, 8, -262123, 0, 8, 1900564, 0, 8, 1835028, 0, 8, 1769492, 0, 8, 1703956, 0, 8, 1638420, 0, 8, 1572884, 0, 8, 1507348, 0, 8, 1441812, 0, 8, 1376276, 0, 8, 1310740, 0, 8, 1245204, 0, 8, 1179668, 0, 8, 1114132, 0, 8, 1048596, 0, 8, 983060, 0, 8, 917524, 0, 8, 851988, 0, 8, 786452, 0, 8, 720916, 0, 8, 655380, 0, 8, 589844, 0, 8, 524308, 0, 8, 458772, 0, 8, 393236, 0, 8, 327700, 0, 8, 262164, 0, 8, 196628, 0, 8, 131092, 0, 8, 65556, 0, 8, 20, 0, 8, -65516, 0, 8, -131052, 0, 8, -196588, 0, 8, -262124, 0, 8, 1900563, 0, 8, 1835027, 0, 8, 1769491, 0, 8, 1703955, 0, 8, 1638419, 0, 8, 1572883, 0, 8, 1507347, 0, 8, 1441811, 0, 8, 1376275, 0, 8, 1310739, 0, 8, 1245203, 0, 8, 1179667, 0, 8, 1114131, 0, 8, 1048595, 0, 8, 983059, 0, 8, 917523, 0, 8, 851987, 0, 8, 786451, 0, 8, 720915, 0, 8, 655379, 0, 8, 589843, 0, 8, 524307, 0, 8, 458771, 0, 8, 393235, 0, 8, 327699, 0, 8, 262163, 0, 8, 196627, 0, 8, 131091, 0, 8, 65555, 0, 8, 19, 0, 8, -65517, 0, 8, -131053, 0, 8, -196589, 0, 8, -262125, 0, 8, 1900562, 0, 8, 1835026, 0, 8, 1769490, 0, 8, 1703954, 0, 8, 1638418, 0, 8, 1572882, 0, 8, 1507346, 0, 8, 1441810, 0, 8, 1376274, 0, 8, 1310738, 0, 8, 1245202, 0, 8, 1179666, 0, 8, 1114130, 0, 8, 1048594, 0, 8, 983058, 0, 8, 917522, 0, 8, 851986, 0, 8, 786450, 0, 8, 720914, 0, 8, 655378, 0, 8, 589842, 0, 8, 524306, 0, 8, 458770, 0, 8, 393234, 0, 8, 327698, 0, 8, 262162, 0, 8, 196626, 0, 8, 131090, 0, 8, 65554, 0, 8, 18, 0, 8, -65518, 0, 8, -131054, 0, 8, -196590, 0, 8, -262126, 0, 8, 1900561, 0, 8, 1835025, 0, 8, 1769489, 0, 8, 1703953, 0, 8, 1638417, 0, 8, 1572881, 0, 8, 1507345, 0, 8, 1441809, 0, 8, 1376273, 0, 8, 1310737, 0, 8, 1245201, 0, 8, 1179665, 0, 8, 1114129, 0, 8, 1048593, 0, 8, 983057, 0, 8, 917521, 0, 8, 851985, 0, 8, 786449, 0, 8, 720913, 0, 8, 655377, 0, 8, 589841, 0, 8, 524305, 0, 8, 458769, 0, 8, 393233, 0, 8, 327697, 0, 8, 262161, 0, 8, 196625, 0, 8, 131089, 0, 8, 65553, 0, 8, 17, 0, 8, -65519, 0, 8, -131055, 0, 8, -196591, 0, 8, -262127, 0, 8, 1900560, 0, 8, 1835024, 0, 8, 1769488, 0, 8, 1703952, 0, 8, 1638416, 0, 8, 1572880, 0, 8, 1507344, 0, 8, 1441808, 0, 8, 1376272, 0, 8, 1310736, 0, 8, 1245200, 0, 8, 1179664, 0, 8, 1114128, 0, 8, 1048592, 0, 8, 983056, 0, 8, 917520, 0, 8, 851984, 0, 8, 786448, 0, 8, 720912, 0, 8, 655376, 0, 8, 589840, 0, 8, 524304, 0, 8, 458768, 0, 8, 393232, 0, 8, 327696, 0, 8, 262160, 0, 8, 196624, 0, 8, 131088, 0, 8, 65552, 0, 8, 16, 0, 8, -65520, 0, 8, -131056, 0, 8, -196592, 0, 8, -262128, 0, 8, 1900559, 0, 8, 1835023, 0, 8, 1769487, 0, 8, 1703951, 0, 8, 1638415, 0, 8, 1572879, 0, 8, 1507343, 0, 8, 1441807, 0, 8, 1376271, 0, 8, 1310735, 0, 8, 1245199, 0, 8, 1179663, 0, 8, 1114127, 0, 8, 1048591, 0, 8, 983055, 0, 8, 917519, 0, 8, 851983, 0, 8, 786447, 0, 8, 720911, 0, 8, 655375, 0, 8, 589839, 0, 8, 524303, 0, 8, 458767, 0, 8, 393231, 0, 8, 327695, 0, 8, 262159, 0, 8, 196623, 0, 8, 131087, 0, 8, 65551, 0, 8, 15, 0, 8, -65521, 0, 8, -131057, 0, 8, -196593, 0, 8, -262129, 0, 8, 1900558, 0, 8, 1835022, 0, 8, 1769486, 0, 8, 1703950, 0, 8, 1638414, 0, 8, 1572878, 0, 8, 1507342, 0, 8, 1441806, 0, 8, 1376270, 0, 8, 1310734, 0, 8, 1245198, 0, 8, 1179662, 0, 8, 1114126, 0, 8, 1048590, 0, 8, 983054, 0, 8, 917518, 0, 8, 851982, 0, 8, 786446, 0, 8, 720910, 0, 8, 655374, 0, 8, 589838, 0, 8, 524302, 0, 8, 458766, 0, 8, 393230, 0, 8, 327694, 0, 8, 262158, 0, 8, 196622, 0, 8, 131086, 0, 8, 65550, 0, 8, 14, 0, 8, -65522, 0, 8, -131058, 0, 8, -196594, 0, 8, -262130, 0, 8, 1900557, 0, 8, 1835021, 0, 8, 1769485, 0, 8, 1703949, 0, 8, 1638413, 0, 8, 1572877, 0, 8, 1507341, 0, 8, 1441805, 0, 8, 1376269, 0, 8, 1310733, 0, 8, 1245197, 0, 8, 1179661, 0, 8, 1114125, 0, 8, 1048589, 0, 8, 983053, 0, 8, 917517, 0, 8, 851981, 0, 8, 786445, 0, 8, 720909, 0, 8, 655373, 0, 8, 589837, 0, 8, 524301, 0, 8, 458765, 0, 8, 393229, 0, 8, 327693, 0, 8, 262157, 0, 8, 196621, 0, 8, 131085, 0, 8, 65549, 0, 8, 13, 0, 8, -65523, 0, 8, -131059, 0, 8, -196595, 0, 8, -262131, 0, 8, 1900556, 0, 8, 1835020, 0, 8, 1769484, 0, 8, 1703948, 0, 8, 1638412, 0, 8, 1572876, 0, 8, 1507340, 0, 8, 1441804, 0, 8, 1376268, 0, 8, 1310732, 0, 8, 1245196, 0, 8, 1179660, 0, 8, 1114124, 0, 8, 1048588, 0, 8, 983052, 0, 8, 917516, 0, 8, 851980, 0, 8, 786444, 0, 8, 720908, 0, 8, 655372, 0, 8, 589836, 0, 8, 524300, 0, 8, 458764, 0, 8, 393228, 0, 8, 327692, 0, 8, 262156, 0, 8, 196620, 0, 8, 131084, 0, 8, 65548, 0, 8, 12, 0, 8, -65524, 0, 8, -131060, 0, 8, -196596, 0, 8, -262132, 0, 8, 1900555, 0, 8, 1835019, 0, 8, 1769483, 0, 8, 1703947, 0, 8, 1638411, 0, 8, 1572875, 0, 8, 1507339, 0, 8, 1441803, 0, 8, 1376267, 0, 8, 1310731, 0, 8, 1245195, 0, 8, 1179659, 0, 8, 1114123, 0, 8, 1048587, 0, 8, 983051, 0, 8, 917515, 0, 8, 851979, 0, 8, 786443, 0, 8, 720907, 0, 8, 655371, 0, 8, 589835, 0, 8, 524299, 0, 8, 458763, 0, 8, 393227, 0, 8, 327691, 0, 8, 262155, 0, 8, 196619, 0, 8, 131083, 0, 8, 65547, 0, 8, 11, 0, 8, -65525, 0, 8, -131061, 0, 8, -196597, 0, 8, -262133, 0, 8, 1900554, 0, 8, 1835018, 0, 8, 1769482, 0, 8, 1703946, 0, 8, 1638410, 0, 8, 1572874, 0, 8, 1507338, 0, 8, 1441802, 0, 8, 1376266, 0, 8, 1310730, 0, 8, 1245194, 0, 8, 1179658, 0, 8, 1114122, 0, 8, 1048586, 0, 8, 983050, 0, 8, 917514, 0, 8, 851978, 0, 8, 786442, 0, 8, 720906, 0, 8, 655370, 0, 8, 589834, 0, 8, 524298, 0, 8, 458762, 0, 8, 393226, 0, 8, 327690, 0, 8, 262154, 0, 8, 196618, 0, 8, 131082, 0, 8, 65546, 0, 8, 10, 0, 8, -65526, 0, 8, -131062, 0, 8, -196598, 0, 8, -262134, 0, 8, 1900553, 0, 8, 1835017, 0, 8, 1769481, 0, 8, 1703945, 0, 8, 1638409, 0, 8, 1572873, 0, 8, 1507337, 0, 8, 1441801, 0, 8, 1376265, 0, 8, 1310729, 0, 8, 1245193, 0, 8, 1179657, 0, 8, 1114121, 0, 8, 1048585, 0, 8, 983049, 0, 8, 917513, 0, 8, 851977, 0, 8, 786441, 0, 8, 720905, 0, 8, 655369, 0, 8, 589833, 0, 8, 524297, 0, 8, 458761, 0, 8, 393225, 0, 8, 327689, 0, 8, 262153, 0, 8, 196617, 0, 8, 131081, 0, 8, 65545, 0, 8, 9, 0, 8, -65527, 0, 8, -131063, 0, 8, -196599, 0, 8, -262135, 0, 8, 1900552, 0, 8, 1835016, 0, 8, 1769480, 0, 8, 1703944, 0, 8, 1638408, 0, 8, 1572872, 0, 8, 1507336, 0, 8, 1441800, 0, 8, 1376264, 0, 8, 1310728, 0, 8, 1245192, 0, 8, 1179656, 0, 8, 1114120, 0, 8, 1048584, 0, 8, 983048, 0, 8, 917512, 0, 8, 851976, 0, 8, 786440, 0, 8, 720904, 0, 8, 655368, 0, 8, 589832, 0, 8, 524296, 0, 8, 458760, 0, 8, 393224, 0, 8, 327688, 0, 8, 262152, 0, 8, 196616, 0, 8, 131080, 0, 8, 65544, 0, 8, 8, 0, 8, -65528, 0, 8, -131064, 0, 8, -196600, 0, 8, -262136, 0, 8, 1900551, 0, 8, 1835015, 0, 8, 1769479, 0, 8, 1703943, 0, 8, 1638407, 0, 8, 1572871, 0, 8, 1507335, 0, 8, 1441799, 0, 8, 1376263, 0, 8, 1310727, 0, 8, 1245191, 0, 8, 1179655, 0, 8, 1114119, 0, 8, 1048583, 0, 8, 983047, 0, 8, 917511, 0, 8, 851975, 0, 8, 786439, 0, 8, 720903, 0, 8, 655367, 0, 8, 589831, 0, 8, 524295, 0, 8, 458759, 0, 8, 393223, 0, 8, 327687, 0, 8, 262151, 0, 8, 196615, 0, 8, 131079, 0, 8, 65543, 0, 8, 7, 0, 8, -65529, 0, 8, -131065, 0, 8, -196601, 0, 8, -262137, 0, 8, 1900550, 0, 8, 1835014, 0, 8, 1769478, 0, 8, 1703942, 0, 8, 1638406, 0, 8, 1572870, 0, 8, 1507334, 0, 8, 1441798, 0, 8, 1376262, 0, 8, 1310726, 0, 8, 1245190, 0, 8, 1179654, 0, 8, 1114118, 0, 8, 1048582, 0, 8, 983046, 0, 8, 917510, 0, 8, 851974, 0, 8, 786438, 0, 8, 720902, 0, 8, 655366, 0, 8, 589830, 0, 8, 524294, 0, 8, 458758, 0, 8, 393222, 0, 8, 327686, 0, 8, 262150, 0, 8, 196614, 0, 8, 131078, 0, 8, 65542, 0, 8, 6, 0, 8, -65530, 0, 8, -131066, 0, 8, -196602, 0, 8, -262138, 0, 8, 1900549, 0, 8, 1835013, 0, 8, 1769477, 0, 8, 1703941, 0, 8, 1638405, 0, 8, 1572869, 0, 8, 1507333, 0, 8, 1441797, 0, 8, 1376261, 0, 8, 1310725, 0, 8, 1245189, 0, 8, 1179653, 0, 8, 1114117, 0, 8, 1048581, 0, 8, 983045, 0, 8, 917509, 0, 8, 851973, 0, 8, 786437, 0, 8, 720901, 0, 8, 655365, 0, 8, 589829, 0, 8, 524293, 0, 8, 458757, 0, 8, 393221, 0, 8, 327685, 0, 8, 262149, 0, 8, 196613, 0, 8, 131077, 0, 8, 65541, 0, 8, 5, 0, 8, -65531, 0, 8, -131067, 0, 8, -196603, 0, 8, -262139, 0, 8, 1900548, 0, 8, 1835012, 0, 8, 1769476, 0, 8, 1703940, 0, 8, 1638404, 0, 8, 1572868, 0, 8, 1507332, 0, 8, 1441796, 0, 8, 1376260, 0, 8, 1310724, 0, 8, 1245188, 0, 8, 1179652, 0, 8, 1114116, 0, 8, 1048580, 0, 8, 983044, 0, 8, 917508, 0, 8, 851972, 0, 8, 786436, 0, 8, 720900, 0, 8, 655364, 0, 8, 589828, 0, 8, 524292, 0, 8, 458756, 0, 8, 393220, 0, 8, 327684, 0, 8, 262148, 0, 8, 196612, 0, 8, 131076, 0, 8, 65540, 0, 8, 4, 0, 8, -65532, 0, 8, -131068, 0, 8, -196604, 0, 8, -262140, 0, 8, 1900547, 0, 8, 1835011, 0, 8, 1769475, 0, 8, 1703939, 0, 8, 1638403, 0, 8, 1572867, 0, 8, 1507331, 0, 8, 1441795, 0, 8, 1376259, 0, 8, 1310723, 0, 8, 1245187, 0, 8, 1179651, 0, 8, 1114115, 0, 8, 1048579, 0, 8, 983043, 0, 8, 917507, 0, 8, 851971, 0, 8, 786435, 0, 8, 720899, 0, 8, 655363, 0, 8, 589827, 0, 8, 524291, 0, 8, 458755, 0, 8, 393219, 0, 8, 327683, 0, 8, 262147, 0, 8, 196611, 0, 8, 131075, 0, 8, 65539, 0, 8, 3, 0, 8, -65533, 0, 8, -131069, 0, 8, -196605, 0, 8, -262141, 0, 8, 1900546, 0, 8, 1835010, 0, 8, 1769474, 0, 8, 1703938, 0, 8, 1638402, 0, 8, 1572866, 0, 8, 1507330, 0, 8, 1441794, 0, 8, 1376258, 0, 8, 1310722, 0, 8, 1245186, 0, 8, 1179650, 0, 8, 1114114, 0, 8, 1048578, 0, 8, 983042, 0, 8, 917506, 0, 8, 851970, 0, 8, 786434, 0, 8, 720898, 0, 8, 655362, 0, 8, 589826, 0, 8, 524290, 0, 8, 458754, 0, 8, 393218, 0, 8, 327682, 0, 8, 262146, 0, 8, 196610, 0, 8, 131074, 0, 8, 65538, 0, 8, 2, 0, 8, -65534, 0, 8, -131070, 0, 8, -196606, 0, 8, -262142, 0, 8, 1900545, 0, 8, 1835009, 0, 8, 1769473, 0, 8, 1703937, 0, 8, 1638401, 0, 8, 1572865, 0, 8, 1507329, 0, 8, 1441793, 0, 8, 1376257, 0, 8, 1310721, 0, 8, 1245185, 0, 8, 1179649, 0, 8, 1114113, 0, 8, 1048577, 0, 8, 983041, 0, 8, 917505, 0, 8, 851969, 0, 8, 786433, 0, 8, 720897, 0, 8, 655361, 0, 8, 589825, 0, 8, 524289, 0, 8, 458753, 0, 8, 393217, 0, 8, 327681, 0, 8, 262145, 0, 8, 196609, 0, 8, 131073, 0, 8, 65537, 0, 8, 1, 0, 8, -65535, 0, 8, -131071, 0, 8, -196607, 0, 8, -262143, 0, 8, 1900544, 0, 8, 1835008, 0, 8, 1769472, 0, 8, 1703936, 0, 8, 1638400, 0, 8, 1572864, 0, 8, 1507328, 0, 8, 1441792, 0, 8, 1376256, 0, 8, 1310720, 0, 8, 1245184, 0, 8, 1179648, 0, 8, 1114112, 0, 8, 1048576, 0, 8, 983040, 0, 8, 917504, 0, 8, 851968, 0, 8, 786432, 0, 8, 720896, 0, 8, 655360, 0, 8, 589824, 0, 8, 524288, 0, 8, 458752, 0, 8, 393216, 0, 8, 327680, 0, 8, 262144, 0, 8, 196608, 0, 8, 131072, 0, 8, 65536, 0, 8, 0, 0, 8, -65536, 0, 8, -131072, 0, 8, -196608, 0, 8, -262144, 0, 8, 1966079, 0, 8, 1900543, 0, 8, 1835007, 0, 8, 1769471, 0, 8, 1703935, 0, 8, 1638399, 0, 8, 1572863, 0, 8, 1507327, 0, 8, 1441791, 0, 8, 1376255, 0, 8, 1310719, 0, 8, 1245183, 0, 8, 1179647, 0, 8, 1114111, 0, 8, 1048575, 0, 8, 983039, 0, 8, 917503, 0, 8, 851967, 0, 8, 786431, 0, 8, 720895, 0, 8, 655359, 0, 8, 589823, 0, 8, 524287, 0, 8, 458751, 0, 8, 393215, 0, 8, 327679, 0, 8, 262143, 0, 8, 196607, 0, 8, 131071, 0, 8, 65535, 0, 8, -1, 0, 8, -65537, 0, 8, -131073, 0, 8, -196609, 0, 8, 1966078, 0, 8, 1900542, 0, 8, 1835006, 0, 8, 1769470, 0, 8, 1703934, 0, 8, 1638398, 0, 8, 1572862, 0, 8, 1507326, 0, 8, 1441790, 0, 8, 1376254, 0, 8, 1310718, 0, 8, 1245182, 0, 8, 1179646, 0, 8, 1114110, 0, 8, 1048574, 0, 8, 983038, 0, 8, 917502, 0, 8, 851966, 0, 8, 786430, 0, 8, 720894, 0, 8, 655358, 0, 8, 589822, 0, 8, 524286, 0, 8, 458750, 0, 8, 393214, 0, 8, 327678, 0, 8, 262142, 0, 8, 196606, 0, 8, 131070, 0, 8, 65534, 0, 8, -2, 0, 8, -65538, 0, 8, -131074, 0, 8, -196610, 0, 8, 1966077, 0, 8, 1900541, 0, 8, 1835005, 0, 8, 1769469, 0, 8, 1703933, 0, 8, 1638397, 0, 8, 1572861, 0, 8, 1507325, 0, 8, 1441789, 0, 8, 1376253, 0, 8, 1310717, 0, 8, 1245181, 0, 8, 1179645, 0, 8, 1114109, 0, 8, 1048573, 0, 8, 983037, 0, 8, 917501, 0, 8, 851965, 0, 8, 786429, 0, 8, 720893, 0, 8, 655357, 0, 8, 589821, 0, 8, 524285, 0, 8, 458749, 0, 8, 393213, 0, 8, 327677, 0, 8, 262141, 0, 8, 196605, 0, 8, 131069, 0, 8, 65533, 0, 8, -3, 0, 8, -65539, 0, 8, -131075, 0, 8, -196611, 0, 8, 1966076, 0, 8, 1900540, 0, 8, 1835004, 0, 8, 1769468, 0, 8, 1703932, 0, 8, 1638396, 0, 8, 1572860, 0, 8, 1507324, 0, 8, 1441788, 0, 8, 1376252, 0, 8, 1310716, 0, 8, 1245180, 0, 8, 1179644, 0, 8, 1114108, 0, 8, 1048572, 0, 8, 983036, 0, 8, 917500, 0, 8, 851964, 0, 8, 786428, 0, 8, 720892, 0, 8, 655356, 0, 8, 589820, 0, 8, 524284, 0, 8, 458748, 0, 8, 393212, 0, 8, 327676, 0, 8, 262140, 0, 8, 196604, 0, 8, 131068, 0, 8, 65532, 0, 8, -4, 0, 8, -65540, 0, 8, -131076, 0, 8, -196612, 0, 8, 1966075, 0, 8, 1900539, 0, 8, 1835003, 0, 8, 1769467, 0, 8, 1703931, 0, 8, 1638395, 0, 8, 1572859, 0, 8, 1507323, 0, 8, 1441787, 0, 8, 1376251, 0, 8, 1310715, 0, 8, 1245179, 0, 8, 1179643, 0, 8, 1114107, 0, 8, 1048571, 0, 8, 983035, 0, 8, 917499, 0, 8, 851963, 0, 8, 786427, 0, 8, 720891, 0, 8, 655355, 0, 8, 589819, 0, 8, 524283, 0, 8, 458747, 0, 8, 393211, 0, 8, 327675, 0, 8, 262139, 0, 8, 196603, 0, 8, 131067, 0, 8, 65531, 0, 8, -5, 0, 8, -65541, 0, 8, -131077, 0, 8, -196613, 0, 8, -131078, 196608, 3, -262150, 196608, 4, -262148, 131072, 7, -65542, 196608, 3, -196614, 196608, 3, -6, 196608, 3, 65530, 196608, 3, 131066, 196608, 3, 196602, 196608, 3, 262138, 196608, 3, 327674, 196608, 3, 393210, 196608, 3, 458746, 196608, 3, 524282, 196608, 3, 589818, 196608, 3, 655354, 196608, 3, 720890, 196608, 3, 786426, 196608, 3, 851962, 196608, 3, 917498, 196608, 3, 983034, 196608, 3, 1048570, 196608, 3, 1114106, 196608, 3, 1179642, 196608, 3, 1245178, 196608, 3, 1310714, 196608, 3, 1376250, 196608, 3, 1441786, 196608, 3, 1507322, 196608, 3, 1572858, 196608, 3, 1638394, 196608, 3, 1703930, 196608, 3, 1769466, 196608, 3, 1835002, 196608, 3, 1900538, 196608, 3, 1966074, 196608, 3, 2031612, 131072, 2, 2031610, 720896, 2, -262149, 131072, 7, -262147, 131072, 7, 2031613, 131072, 2, 2031611, 131072, 2, -262146, 131072, 7, 2031614, 131072, 2, -262145, 131072, 7, 2031615, 131072, 2, -327680, 131072, 7, 1966080, 131072, 2, -327679, 131072, 7, 1966081, 131072, 2, -327678, 131072, 7, 1966082, 131072, 2, -327677, 131072, 7, 1966083, 131072, 2, -327676, 131072, 7, 1966084, 131072, 2, -327675, 131072, 7, 1966085, 131072, 2, -327674, 131072, 7, 1966086, 131072, 2, -327673, 131072, 7, 1966087, 131072, 2, -327672, 131072, 7, 1966088, 131072, 2, -327671, 131072, 7, 1966089, 196608, 2, -327670, 131072, 7, 1966090, 0, 8, -327669, 131072, 7, 1966091, 0, 8, -327668, 131072, 7, 1966092, 0, 8, -327667, 131072, 7, 1966093, 0, 8, -327666, 131072, 7, 1966094, 0, 8, -327665, 131072, 7, 1966095, 0, 8, -327664, 131072, 7, 1966096, 0, 8, -327663, 131072, 7, 1966097, 0, 8, -327662, 131072, 7, 1966098, 0, 8, -327661, 131072, 7, 1966099, 0, 8, -327660, 131072, 7, 1966100, 0, 8, -327659, 131072, 7, 1966101, 0, 8, -327658, 131072, 7, 1966102, 0, 8, -327657, 131072, 7, 1966103, 0, 8, -327656, 131072, 7, 1966104, 0, 8, -327655, 131072, 7, 1966105, 0, 8, -327654, 131072, 7, 1966106, 0, 8, -327653, 131072, 7, 1966107, 65536, 2, -327652, 131072, 7, 1966108, 131072, 2, -327651, 131072, 7, 1966109, 131072, 2, -327650, 131072, 7, 1966110, 131072, 2, -327649, 131072, 7, 1966111, 131072, 2, -327648, 131072, 7, 1966112, 131072, 2, -327647, 131072, 7, 1966113, 131072, 2, -327646, 131072, 7, 1966114, 131072, 2, -327645, 131072, 7, 1966115, 131072, 2, -327644, 131072, 7, 1966116, 196608, 2, -327643, 131072, 7, 1966117, 0, 8, -327642, 131072, 7, 1966118, 0, 8, -327641, 131072, 7, 1966119, 0, 8, -327640, 131072, 7, 1966120, 0, 8, -327639, 131072, 7, 1966121, 0, 8, -327638, 131072, 7, 1966122, 0, 8, -327637, 131072, 7, 1966123, 0, 8, -327636, 131072, 7, 1966124, 0, 8, -327635, 131072, 7, 1966125, 0, 8, -196562, 65536, 3, -327634, 65536, 4, -131026, 65536, 3, -262098, 65536, 3, -65490, 65536, 3, 46, 65536, 3, 65582, 65536, 3, 131118, 65536, 3, 196654, 65536, 3, 262190, 65536, 3, 327726, 65536, 3, 393262, 65536, 3, 458798, 65536, 3, 524334, 65536, 3, 589870, 65536, 3, 655406, 65536, 7, 720942, 0, 8, 786478, 0, 8, 852014, 0, 8, 917550, 0, 8, 983086, 0, 8, 1048622, 0, 8, 1114158, 0, 8, 1179694, 0, 8, 1245230, 0, 8, 1310766, 0, 8, 1376302, 0, 8, 1441838, 0, 8, 1507374, 0, 8, 1572910, 0, 8, 1638446, 0, 8, 1703982, 0, 8, 1769518, 0, 8, 1835054, 0, 8, 1900590, 0, 8, 1966126, 0, 8, 2949189, 0, 8, 2883653, 0, 8, 2818117, 0, 8, 2752581, 0, 8, 2687045, 0, 8, 2621509, 0, 8, 2555973, 0, 8, 2490437, 0, 8, 2424901, 0, 8, 2359365, 0, 8, 2293829, 0, 8, 2228293, 0, 8, 2162757, 0, 8, 2097221, 0, 8, 2031685, 0, 8, 1966149, 0, 8, 1900613, 0, 8, 1835077, 0, 8, 1769541, 0, 8, 1704005, 0, 8, 1638469, 0, 8, 1572933, 0, 8, 1507397, 0, 8, 1441861, 0, 8, 1376325, 0, 8, 1310789, 0, 8, 1245253, 0, 8, 1179717, 0, 8, 1114181, 0, 8, 1048645, 0, 8, 983109, 0, 8, 917573, 0, 8, 852037, 0, 8, 786501, 0, 8, 720965, 0, 8, 2949188, 0, 8, 2883652, 0, 8, 2818116, 0, 8, 2752580, 0, 8, 2687044, 0, 8, 2621508, 0, 8, 2555972, 0, 8, 2490436, 0, 8, 2424900, 0, 8, 2359364, 0, 8, 2293828, 0, 8, 2228292, 0, 8, 2162756, 0, 8, 2097220, 0, 8, 2031684, 0, 8, 1966148, 0, 8, 1900612, 0, 8, 1835076, 0, 8, 1769540, 0, 8, 1704004, 0, 8, 1638468, 0, 8, 1572932, 0, 8, 1507396, 0, 8, 1441860, 0, 8, 1376324, 0, 8, 1310788, 0, 8, 1245252, 0, 8, 1179716, 0, 8, 1114180, 0, 8, 1048644, 0, 8, 983108, 0, 8, 917572, 0, 8, 852036, 0, 8, 786500, 0, 8, 720964, 0, 8, 2949187, 0, 8, 2883651, 0, 8, 2818115, 0, 8, 2752579, 0, 8, 2687043, 0, 8, 2621507, 0, 8, 2555971, 0, 8, 2490435, 0, 8, 2424899, 0, 8, 2359363, 0, 8, 2293827, 0, 8, 2228291, 0, 8, 2162755, 0, 8, 2097219, 0, 8, 2031683, 0, 8, 1966147, 0, 8, 1900611, 0, 8, 1835075, 0, 8, 1769539, 0, 8, 1704003, 0, 8, 1638467, 0, 8, 1572931, 0, 8, 1507395, 0, 8, 1441859, 0, 8, 1376323, 0, 8, 1310787, 0, 8, 1245251, 0, 8, 1179715, 0, 8, 1114179, 0, 8, 1048643, 0, 8, 983107, 0, 8, 917571, 0, 8, 852035, 0, 8, 786499, 0, 8, 720963, 0, 8, 2949186, 0, 8, 2883650, 0, 8, 2818114, 0, 8, 2752578, 0, 8, 2687042, 0, 8, 2621506, 0, 8, 2555970, 0, 8, 2490434, 0, 8, 2424898, 0, 8, 2359362, 0, 8, 2293826, 0, 8, 2228290, 0, 8, 2162754, 0, 8, 2097218, 0, 8, 2031682, 0, 8, 1966146, 0, 8, 1900610, 0, 8, 1835074, 0, 8, 1769538, 0, 8, 1704002, 0, 8, 1638466, 0, 8, 1572930, 0, 8, 1507394, 0, 8, 1441858, 0, 8, 1376322, 0, 8, 1310786, 0, 8, 1245250, 0, 8, 1179714, 0, 8, 1114178, 0, 8, 1048642, 0, 8, 983106, 0, 8, 917570, 0, 8, 852034, 0, 8, 786498, 0, 8, 720962, 0, 8, 2949185, 0, 8, 2883649, 0, 8, 2818113, 0, 8, 2752577, 0, 8, 2687041, 0, 8, 2621505, 0, 8, 2555969, 0, 8, 2490433, 0, 8, 2424897, 0, 8, 2359361, 0, 8, 2293825, 0, 8, 2228289, 0, 8, 2162753, 0, 8, 2097217, 0, 8, 2031681, 0, 8, 1966145, 0, 8, 1900609, 0, 8, 1835073, 0, 8, 1769537, 0, 8, 1704001, 0, 8, 1638465, 0, 8, 1572929, 0, 8, 1507393, 0, 8, 1441857, 0, 8, 1376321, 0, 8, 1310785, 0, 8, 1245249, 0, 8, 1179713, 0, 8, 1114177, 0, 8, 1048641, 0, 8, 983105, 0, 8, 917569, 0, 8, 852033, 0, 8, 786497, 0, 8, 720961, 0, 8, 2949184, 0, 8, 2883648, 0, 8, 2818112, 0, 8, 2752576, 0, 8, 2687040, 0, 8, 2621504, 0, 8, 2555968, 0, 8, 2490432, 0, 8, 2424896, 0, 8, 2359360, 0, 8, 2293824, 0, 8, 2228288, 0, 8, 2162752, 0, 8, 2097216, 0, 8, 2031680, 0, 8, 1966144, 0, 8, 1900608, 0, 8, 1835072, 0, 8, 1769536, 0, 8, 1704000, 0, 8, 1638464, 0, 8, 1572928, 0, 8, 1507392, 0, 8, 1441856, 0, 8, 1376320, 0, 8, 1310784, 0, 8, 1245248, 0, 8, 1179712, 0, 8, 1114176, 0, 8, 1048640, 0, 8, 983104, 0, 8, 917568, 0, 8, 852032, 0, 8, 786496, 0, 8, 720960, 0, 8, 2949183, 0, 8, 2883647, 0, 8, 2818111, 0, 8, 2752575, 0, 8, 2687039, 0, 8, 2621503, 0, 8, 2555967, 0, 8, 2490431, 0, 8, 2424895, 0, 8, 2359359, 0, 8, 2293823, 0, 8, 2228287, 0, 8, 2162751, 0, 8, 2097215, 0, 8, 2031679, 0, 8, 1966143, 0, 8, 1900607, 0, 8, 1835071, 0, 8, 1769535, 0, 8, 1703999, 0, 8, 1638463, 0, 8, 1572927, 0, 8, 1507391, 0, 8, 1441855, 0, 8, 1376319, 0, 8, 1310783, 0, 8, 1245247, 0, 8, 1179711, 0, 8, 1114175, 0, 8, 1048639, 0, 8, 983103, 0, 8, 917567, 0, 8, 852031, 0, 8, 786495, 0, 8, 720959, 0, 8, 2949182, 0, 8, 2883646, 0, 8, 2818110, 0, 8, 2752574, 0, 8, 2687038, 0, 8, 2621502, 0, 8, 2555966, 0, 8, 2490430, 0, 8, 2424894, 0, 8, 2359358, 0, 8, 2293822, 0, 8, 2228286, 0, 8, 2162750, 0, 8, 2097214, 0, 8, 2031678, 0, 8, 1966142, 0, 8, 1900606, 0, 8, 1835070, 0, 8, 1769534, 0, 8, 1703998, 0, 8, 1638462, 0, 8, 1572926, 0, 8, 1507390, 0, 8, 1441854, 0, 8, 1376318, 0, 8, 1310782, 0, 8, 1245246, 0, 8, 1179710, 0, 8, 1114174, 0, 8, 1048638, 0, 8, 983102, 0, 8, 917566, 0, 8, 852030, 0, 8, 786494, 0, 8, 720958, 0, 8, 2949181, 0, 8, 2883645, 0, 8, 2818109, 0, 8, 2752573, 0, 8, 2687037, 0, 8, 2621501, 0, 8, 2555965, 0, 8, 2490429, 0, 8, 2424893, 0, 8, 2359357, 0, 8, 2293821, 0, 8, 2228285, 0, 8, 2162749, 0, 8, 2097213, 0, 8, 2031677, 0, 8, 1966141, 0, 8, 1900605, 0, 8, 1835069, 0, 8, 1769533, 0, 8, 1703997, 0, 8, 1638461, 0, 8, 1572925, 0, 8, 1507389, 0, 8, 1441853, 0, 8, 1376317, 0, 8, 1310781, 0, 8, 1245245, 0, 8, 1179709, 0, 8, 1114173, 0, 8, 1048637, 0, 8, 983101, 0, 8, 917565, 0, 8, 852029, 0, 8, 786493, 0, 8, 720957, 0, 8, 2949180, 0, 8, 2883644, 0, 8, 2818108, 0, 8, 2752572, 0, 8, 2687036, 0, 8, 2621500, 0, 8, 2555964, 0, 8, 2490428, 0, 8, 2424892, 0, 8, 2359356, 0, 8, 2293820, 0, 8, 2228284, 0, 8, 2162748, 0, 8, 2097212, 0, 8, 2031676, 0, 8, 1966140, 0, 8, 1900604, 0, 8, 1835068, 0, 8, 1769532, 0, 8, 1703996, 0, 8, 1638460, 0, 8, 1572924, 0, 8, 1507388, 0, 8, 1441852, 0, 8, 1376316, 0, 8, 1310780, 0, 8, 1245244, 0, 8, 1179708, 0, 8, 1114172, 0, 8, 1048636, 0, 8, 983100, 0, 8, 917564, 0, 8, 852028, 0, 8, 786492, 0, 8, 720956, 0, 8, 2949179, 0, 8, 2883643, 0, 8, 2818107, 0, 8, 2752571, 0, 8, 2687035, 0, 8, 2621499, 0, 8, 2555963, 0, 8, 2490427, 0, 8, 2424891, 0, 8, 2359355, 0, 8, 2293819, 0, 8, 2228283, 0, 8, 2162747, 0, 8, 2097211, 0, 8, 2031675, 0, 8, 1966139, 0, 8, 1900603, 0, 8, 1835067, 0, 8, 1769531, 0, 8, 1703995, 0, 8, 1638459, 0, 8, 1572923, 0, 8, 1507387, 0, 8, 1441851, 0, 8, 1376315, 0, 8, 1310779, 0, 8, 1245243, 0, 8, 1179707, 0, 8, 1114171, 0, 8, 1048635, 0, 8, 983099, 0, 8, 917563, 0, 8, 852027, 0, 8, 786491, 0, 8, 720955, 0, 8, 2949178, 0, 8, 2883642, 0, 8, 2818106, 0, 8, 2752570, 0, 8, 2687034, 0, 8, 2621498, 0, 8, 2555962, 0, 8, 2490426, 0, 8, 2424890, 0, 8, 2359354, 0, 8, 2293818, 0, 8, 2228282, 0, 8, 2162746, 0, 8, 2097210, 0, 8, 2031674, 0, 8, 1966138, 0, 8, 1900602, 0, 8, 1835066, 0, 8, 1769530, 0, 8, 1703994, 0, 8, 1638458, 0, 8, 1572922, 0, 8, 1507386, 0, 8, 1441850, 0, 8, 1376314, 0, 8, 1310778, 0, 8, 1245242, 0, 8, 1179706, 0, 8, 1114170, 0, 8, 1048634, 0, 8, 983098, 0, 8, 917562, 0, 8, 852026, 0, 8, 786490, 0, 8, 720954, 0, 8, 2949177, 0, 8, 2883641, 0, 8, 2818105, 0, 8, 2752569, 0, 8, 2687033, 0, 8, 2621497, 0, 8, 2555961, 0, 8, 2490425, 0, 8, 2424889, 0, 8, 2359353, 0, 8, 2293817, 0, 8, 2228281, 0, 8, 2162745, 0, 8, 2097209, 0, 8, 2031673, 0, 8, 1966137, 0, 8, 1900601, 0, 8, 1835065, 0, 8, 1769529, 0, 8, 1703993, 0, 8, 1638457, 0, 8, 1572921, 0, 8, 1507385, 0, 8, 1441849, 0, 8, 1376313, 0, 8, 1310777, 0, 8, 1245241, 0, 8, 1179705, 0, 8, 1114169, 0, 8, 1048633, 0, 8, 983097, 0, 8, 917561, 0, 8, 852025, 0, 8, 786489, 0, 8, 720953, 0, 8, 2949176, 0, 8, 2883640, 0, 8, 2818104, 0, 8, 2752568, 0, 8, 2687032, 0, 8, 2621496, 0, 8, 2555960, 0, 8, 2490424, 0, 8, 2424888, 0, 8, 2359352, 0, 8, 2293816, 0, 8, 2228280, 0, 8, 2162744, 0, 8, 2097208, 0, 8, 2031672, 0, 8, 1966136, 0, 8, 1900600, 0, 8, 1835064, 0, 8, 1769528, 0, 8, 1703992, 0, 8, 1638456, 0, 8, 1572920, 0, 8, 1507384, 0, 8, 1441848, 0, 8, 1376312, 0, 8, 1310776, 0, 8, 1245240, 0, 8, 1179704, 0, 8, 1114168, 0, 8, 1048632, 0, 8, 983096, 0, 8, 917560, 0, 8, 852024, 0, 8, 786488, 0, 8, 720952, 0, 8, 2949175, 0, 8, 2883639, 0, 8, 2818103, 0, 8, 2752567, 0, 8, 2687031, 0, 8, 2621495, 0, 8, 2555959, 0, 8, 2490423, 0, 8, 2424887, 0, 8, 2359351, 0, 8, 2293815, 0, 8, 2228279, 0, 8, 2162743, 0, 8, 2097207, 0, 8, 2031671, 0, 8, 1966135, 0, 8, 1900599, 0, 8, 1835063, 0, 8, 1769527, 0, 8, 1703991, 0, 8, 1638455, 0, 8, 1572919, 0, 8, 1507383, 0, 8, 1441847, 0, 8, 1376311, 0, 8, 1310775, 0, 8, 1245239, 0, 8, 1179703, 0, 8, 1114167, 0, 8, 1048631, 0, 8, 983095, 0, 8, 917559, 0, 8, 852023, 0, 8, 786487, 0, 8, 720951, 0, 8, 2949174, 0, 8, 2883638, 0, 8, 2818102, 0, 8, 2752566, 0, 8, 2687030, 0, 8, 2621494, 0, 8, 2555958, 0, 8, 2490422, 0, 8, 2424886, 0, 8, 2359350, 0, 8, 2293814, 0, 8, 2228278, 0, 8, 2162742, 0, 8, 2097206, 0, 8, 2031670, 0, 8, 1966134, 0, 8, 1900598, 0, 8, 1835062, 0, 8, 1769526, 0, 8, 1703990, 0, 8, 1638454, 0, 8, 1572918, 0, 8, 1507382, 0, 8, 1441846, 0, 8, 1376310, 0, 8, 1310774, 0, 8, 1245238, 0, 8, 1179702, 0, 8, 1114166, 0, 8, 1048630, 0, 8, 983094, 0, 8, 917558, 0, 8, 852022, 0, 8, 786486, 0, 8, 720950, 0, 8, 2949173, 0, 8, 2883637, 0, 8, 2818101, 0, 8, 2752565, 0, 8, 2687029, 0, 8, 2621493, 0, 8, 2555957, 0, 8, 2490421, 0, 8, 2424885, 0, 8, 2359349, 0, 8, 2293813, 0, 8, 2228277, 0, 8, 2162741, 0, 8, 2097205, 0, 8, 2031669, 0, 8, 1966133, 0, 8, 1900597, 0, 8, 1835061, 0, 8, 1769525, 0, 8, 1703989, 0, 8, 1638453, 0, 8, 1572917, 0, 8, 1507381, 0, 8, 1441845, 0, 8, 1376309, 0, 8, 1310773, 0, 8, 1245237, 0, 8, 1179701, 0, 8, 1114165, 0, 8, 1048629, 0, 8, 983093, 0, 8, 917557, 0, 8, 852021, 0, 8, 786485, 0, 8, 720949, 0, 8, 2949172, 0, 8, 2883636, 0, 8, 2818100, 0, 8, 2752564, 0, 8, 2687028, 0, 8, 2621492, 0, 8, 2555956, 0, 8, 2490420, 0, 8, 2424884, 0, 8, 2359348, 0, 8, 2293812, 0, 8, 2228276, 0, 8, 2162740, 0, 8, 2097204, 0, 8, 2031668, 0, 8, 1966132, 0, 8, 1900596, 0, 8, 1835060, 0, 8, 1769524, 0, 8, 1703988, 0, 8, 1638452, 0, 8, 1572916, 0, 8, 1507380, 0, 8, 1441844, 0, 8, 1376308, 0, 8, 1310772, 0, 8, 1245236, 0, 8, 1179700, 0, 8, 1114164, 0, 8, 1048628, 0, 8, 983092, 0, 8, 917556, 0, 8, 852020, 0, 8, 786484, 0, 8, 720948, 0, 8, 2949171, 0, 8, 2883635, 0, 8, 2818099, 0, 8, 2752563, 0, 8, 2687027, 0, 8, 2621491, 0, 8, 2555955, 0, 8, 2490419, 0, 8, 2424883, 0, 8, 2359347, 0, 8, 2293811, 0, 8, 2228275, 0, 8, 2162739, 0, 8, 2097203, 0, 8, 2031667, 0, 8, 1966131, 0, 8, 1900595, 0, 8, 1835059, 0, 8, 1769523, 0, 8, 1703987, 0, 8, 1638451, 0, 8, 1572915, 0, 8, 1507379, 0, 8, 1441843, 0, 8, 1376307, 0, 8, 1310771, 0, 8, 1245235, 0, 8, 1179699, 0, 8, 1114163, 0, 8, 1048627, 0, 8, 983091, 0, 8, 917555, 0, 8, 852019, 0, 8, 786483, 0, 8, 720947, 0, 8, 2949170, 0, 8, 2883634, 0, 8, 2818098, 0, 8, 2752562, 0, 8, 2687026, 0, 8, 2621490, 0, 8, 2555954, 0, 8, 2490418, 0, 8, 2424882, 0, 8, 2359346, 0, 8, 2293810, 0, 8, 2228274, 0, 8, 2162738, 0, 8, 2097202, 0, 8, 2031666, 0, 8, 1966130, 0, 8, 1900594, 0, 8, 1835058, 0, 8, 1769522, 0, 8, 1703986, 0, 8, 1638450, 0, 8, 1572914, 0, 8, 1507378, 0, 8, 1441842, 0, 8, 1376306, 0, 8, 1310770, 0, 8, 1245234, 0, 8, 1179698, 0, 8, 1114162, 0, 8, 1048626, 0, 8, 983090, 0, 8, 917554, 0, 8, 852018, 0, 8, 786482, 0, 8, 720946, 0, 8, 2949169, 0, 8, 2883633, 0, 8, 2818097, 0, 8, 2752561, 0, 8, 2687025, 0, 8, 2621489, 0, 8, 2555953, 0, 8, 2490417, 0, 8, 2424881, 0, 8, 2359345, 0, 8, 2293809, 0, 8, 2228273, 0, 8, 2162737, 0, 8, 2097201, 0, 8, 2031665, 0, 8, 1966129, 0, 8, 1900593, 0, 8, 1835057, 0, 8, 1769521, 0, 8, 1703985, 0, 8, 1638449, 0, 8, 1572913, 0, 8, 1507377, 0, 8, 1441841, 0, 8, 1376305, 0, 8, 1310769, 0, 8, 1245233, 0, 8, 1179697, 0, 8, 1114161, 0, 8, 1048625, 0, 8, 983089, 0, 8, 917553, 0, 8, 852017, 0, 8, 786481, 0, 8, 720945, 0, 8, 2949168, 0, 8, 2883632, 0, 8, 2818096, 0, 8, 2752560, 0, 8, 2687024, 0, 8, 2621488, 0, 8, 2555952, 0, 8, 2490416, 0, 8, 2424880, 0, 8, 2359344, 0, 8, 2293808, 0, 8, 2228272, 0, 8, 2162736, 0, 8, 2097200, 0, 8, 2031664, 0, 8, 1966128, 0, 8, 1900592, 0, 8, 1835056, 0, 8, 1769520, 0, 8, 1703984, 0, 8, 1638448, 0, 8, 1572912, 0, 8, 1507376, 0, 8, 1441840, 0, 8, 1376304, 0, 8, 1310768, 0, 8, 1245232, 0, 8, 1179696, 0, 8, 1114160, 0, 8, 1048624, 0, 8, 983088, 0, 8, 917552, 0, 8, 852016, 0, 8, 786480, 0, 8, 720944, 0, 8, 2949167, 0, 8, 2883631, 0, 8, 2818095, 0, 8, 2752559, 0, 8, 2687023, 0, 8, 2621487, 0, 8, 2555951, 0, 8, 2490415, 0, 8, 2424879, 0, 8, 2359343, 0, 8, 2293807, 0, 8, 2228271, 0, 8, 2162735, 0, 8, 2097199, 0, 8, 2031663, 0, 8, 1966127, 0, 8, 1900591, 0, 8, 1835055, 0, 8, 1769519, 0, 8, 1703983, 0, 8, 1638447, 0, 8, 1572911, 0, 8, 1507375, 0, 8, 1441839, 0, 8, 1376303, 0, 8, 1310767, 0, 8, 1245231, 0, 8, 1179695, 0, 8, 1114159, 0, 8, 1048623, 0, 8, 983087, 0, 8, 917551, 0, 8, 852015, 0, 8, 786479, 0, 8, 720943, 0, 8, 2949166, 0, 8, 2883630, 0, 8, 2818094, 0, 8, 2752558, 0, 8, 2687022, 0, 8, 2621486, 0, 8, 2555950, 0, 8, 2490414, 0, 8, 2424878, 0, 8, 2359342, 0, 8, 2293806, 0, 8, 2228270, 0, 8, 2162734, 0, 8, 2097198, 0, 8, 2031662, 0, 8, 2949165, 0, 8, 2883629, 0, 8, 2818093, 0, 8, 2752557, 0, 8, 2687021, 0, 8, 2621485, 0, 8, 2555949, 0, 8, 2490413, 0, 8, 2424877, 0, 8, 2359341, 0, 8, 2293805, 0, 8, 2228269, 0, 8, 2162733, 0, 8, 2097197, 0, 8, 2031661, 0, 8, 2949164, 0, 8, 2883628, 0, 8, 2818092, 0, 8, 2752556, 0, 8, 2687020, 0, 8, 2621484, 0, 8, 2555948, 0, 8, 2490412, 0, 8, 2424876, 0, 8, 2359340, 0, 8, 2293804, 0, 8, 2228268, 0, 8, 2162732, 0, 8, 2097196, 0, 8, 2031660, 0, 8, 2949163, 0, 8, 2883627, 0, 8, 2818091, 0, 8, 2752555, 0, 8, 2687019, 0, 8, 2621483, 0, 8, 2555947, 0, 8, 2490411, 0, 8, 2424875, 0, 8, 2359339, 0, 8, 2293803, 0, 8, 2228267, 0, 8, 2162731, 0, 8, 2097195, 0, 8, 2031659, 0, 8, 2949162, 0, 8, 2883626, 0, 8, 2818090, 0, 8, 2752554, 0, 8, 2687018, 0, 8, 2621482, 0, 8, 2555946, 0, 8, 2490410, 0, 8, 2424874, 0, 8, 2359338, 0, 8, 2293802, 0, 8, 2228266, 0, 8, 2162730, 0, 8, 2097194, 0, 8, 2031658, 0, 8, 2949161, 0, 8, 2883625, 0, 8, 2818089, 0, 8, 2752553, 0, 8, 2687017, 0, 8, 2621481, 0, 8, 2555945, 0, 8, 2490409, 0, 8, 2424873, 0, 8, 2359337, 0, 8, 2293801, 0, 8, 2228265, 0, 8, 2162729, 0, 8, 2097193, 0, 8, 2031657, 0, 8, 2949160, 0, 8, 2883624, 0, 8, 2818088, 0, 8, 2752552, 0, 8, 2687016, 0, 8, 2621480, 0, 8, 2555944, 0, 8, 2490408, 0, 8, 2424872, 0, 8, 2359336, 0, 8, 2293800, 0, 8, 2228264, 0, 8, 2162728, 0, 8, 2097192, 0, 8, 2031656, 0, 8, 2949159, 0, 8, 2883623, 0, 8, 2818087, 0, 8, 2752551, 0, 8, 2687015, 0, 8, 2621479, 0, 8, 2555943, 0, 8, 2490407, 0, 8, 2424871, 0, 8, 2359335, 0, 8, 2293799, 0, 8, 2228263, 0, 8, 2162727, 0, 8, 2097191, 0, 8, 2031655, 0, 8, 2949158, 0, 8, 2883622, 0, 8, 2818086, 0, 8, 2752550, 0, 8, 2687014, 0, 8, 2621478, 0, 8, 2555942, 0, 8, 2490406, 0, 8, 2424870, 0, 8, 2359334, 0, 8, 2293798, 0, 8, 2228262, 0, 8, 2162726, 0, 8, 2097190, 0, 8, 2031654, 0, 8, 2949157, 0, 8, 2883621, 0, 8, 2818085, 0, 8, 2752549, 0, 8, 2687013, 0, 8, 2621477, 0, 8, 2555941, 0, 8, 2490405, 0, 8, 2424869, 0, 8, 2359333, 0, 8, 2293797, 0, 8, 2228261, 0, 8, 2162725, 0, 8, 2097189, 0, 8, 2031653, 0, 8, 2031652, 196608, 3, 2097188, 196608, 3, 2162724, 196608, 3, 2228260, 196608, 3, 2293796, 196608, 3, 2359332, 196608, 3, 2424868, 196608, 3, 2490404, 196608, 3, 2555940, 196608, 3, 2621476, 196608, 3, 2687012, 196608, 3, 2752548, 196608, 3, 2818084, 196608, 3, 2883620, 196608, 3, 2949156, 196608, 3, 3014694, 131072, 2, 3014692, 720896, 2, 3014695, 131072, 2, 3014693, 131072, 2, 3014696, 131072, 2, 3014697, 131072, 2, 3014698, 131072, 2, 3014699, 131072, 2, 3014700, 131072, 2, 3014701, 131072, 2, 3014702, 131072, 2, 655407, 131072, 7, 3014703, 131072, 2, 655408, 131072, 7, 3014704, 131072, 2, 655409, 131072, 7, 3014705, 131072, 2, 655410, 131072, 7, 3014706, 131072, 2, 655411, 131072, 7, 3014707, 131072, 2, 655412, 131072, 7, 3014708, 131072, 2, 655413, 131072, 7, 3014709, 131072, 2, 655414, 131072, 7, 3014710, 131072, 2, 655415, 131072, 7, 3014711, 131072, 2, 655416, 131072, 7, 3014712, 131072, 2, 655417, 131072, 7, 3014713, 131072, 2, 655418, 131072, 7, 3014714, 196608, 2, 655419, 131072, 7, 3014715, 0, 8, 655420, 131072, 7, 3014716, 0, 8, 655421, 131072, 7, 3014717, 0, 8, 655422, 131072, 7, 3014718, 0, 8, 655423, 131072, 7, 3014719, 0, 8, 655424, 196608, 7, 3014720, 0, 8, 655425, 0, 8, 3014721, 0, 8, 655426, 0, 8, 3014722, 0, 8, 655427, 0, 8, 3014723, 0, 8, 655428, 0, 8, 3014724, 0, 8, 655429, 0, 8, 3014725, 0, 8, 786502, 0, 8, 655430, 0, 8, 852038, 0, 8, 720966, 0, 8, 917574, 0, 8, 983110, 0, 8, 1048646, 0, 8, 1114182, 0, 8, 1179718, 0, 8, 1245254, 0, 8, 1310790, 0, 8, 1376326, 0, 8, 1441862, 65536, 2, 1507398, 65536, 3, 1572934, 65536, 3, 1638470, 65536, 3, 1704006, 65536, 3, 1769542, 65536, 3, 1835078, 65536, 3, 1900614, 65536, 3, 1966150, 65536, 3, 2031686, 65536, 3, 2097222, 65536, 3, 2162758, 65536, 3, 2228294, 65536, 3, 2293830, 65536, 3, 2359366, 65536, 3, 2424902, 65536, 3, 2490438, 65536, 3, 2555974, 65536, 3, 2621510, 65536, 3, 2687046, 65536, 7, 2752582, 0, 8, 2818118, 0, 8, 2883654, 0, 8, 2949190, 0, 8, 3014726, 0, 8, 3801114, 0, 8, 3735578, 0, 8, 3670042, 0, 8, 3604506, 0, 8, 3538970, 0, 8, 3473434, 0, 8, 3407898, 0, 8, 3342362, 0, 8, 3276826, 0, 8, 3211290, 0, 8, 3145754, 0, 8, 3080218, 0, 8, 3014682, 0, 8, 2949146, 0, 8, 2883610, 0, 8, 2818074, 0, 8, 2752538, 0, 8, 2687002, 0, 8, 2621466, 0, 8, 2555930, 0, 8, 2490394, 0, 8, 2424858, 0, 8, 2359322, 0, 8, 2293786, 0, 8, 2228250, 0, 8, 2162714, 0, 8, 2097178, 0, 8, 2031642, 0, 8, 3801113, 0, 8, 3735577, 0, 8, 3670041, 0, 8, 3604505, 0, 8, 3538969, 0, 8, 3473433, 0, 8, 3407897, 0, 8, 3342361, 0, 8, 3276825, 0, 8, 3211289, 0, 8, 3145753, 0, 8, 3080217, 0, 8, 3014681, 0, 8, 2949145, 0, 8, 2883609, 0, 8, 2818073, 0, 8, 2752537, 0, 8, 2687001, 0, 8, 2621465, 0, 8, 2555929, 0, 8, 2490393, 0, 8, 2424857, 0, 8, 2359321, 0, 8, 2293785, 0, 8, 2228249, 0, 8, 2162713, 0, 8, 2097177, 0, 8, 2031641, 0, 8, 3801112, 0, 8, 3735576, 0, 8, 3670040, 0, 8, 3604504, 0, 8, 3538968, 0, 8, 3473432, 0, 8, 3407896, 0, 8, 3342360, 0, 8, 3276824, 0, 8, 3211288, 0, 8, 3145752, 0, 8, 3080216, 0, 8, 3014680, 0, 8, 2949144, 0, 8, 2883608, 0, 8, 2818072, 0, 8, 2752536, 0, 8, 2687000, 0, 8, 2621464, 0, 8, 2555928, 0, 8, 2490392, 0, 8, 2424856, 0, 8, 2359320, 0, 8, 2293784, 0, 8, 2228248, 0, 8, 2162712, 0, 8, 2097176, 0, 8, 2031640, 0, 8, 3801111, 0, 8, 3735575, 0, 8, 3670039, 0, 8, 3604503, 0, 8, 3538967, 0, 8, 3473431, 0, 8, 3407895, 0, 8, 3342359, 0, 8, 3276823, 0, 8, 3211287, 0, 8, 3145751, 0, 8, 3080215, 0, 8, 3014679, 0, 8, 2949143, 0, 8, 2883607, 0, 8, 2818071, 0, 8, 2752535, 0, 8, 2686999, 0, 8, 2621463, 0, 8, 2555927, 0, 8, 2490391, 0, 8, 2424855, 0, 8, 2359319, 0, 8, 2293783, 0, 8, 2228247, 0, 8, 2162711, 0, 8, 2097175, 0, 8, 2031639, 0, 8, 3801110, 0, 8, 3735574, 0, 8, 3670038, 0, 8, 3604502, 0, 8, 3538966, 0, 8, 3473430, 0, 8, 3407894, 0, 8, 3342358, 0, 8, 3276822, 0, 8, 3211286, 0, 8, 3145750, 0, 8, 3080214, 0, 8, 3014678, 0, 8, 2949142, 0, 8, 2883606, 0, 8, 2818070, 0, 8, 2752534, 0, 8, 2686998, 0, 8, 2621462, 0, 8, 2555926, 0, 8, 2490390, 0, 8, 2424854, 0, 8, 2359318, 0, 8, 2293782, 0, 8, 2228246, 0, 8, 2162710, 0, 8, 2097174, 0, 8, 2031638, 0, 8, 3801109, 0, 8, 3735573, 0, 8, 3670037, 0, 8, 3604501, 0, 8, 3538965, 0, 8, 3473429, 0, 8, 3407893, 0, 8, 3342357, 0, 8, 3276821, 0, 8, 3211285, 0, 8, 3145749, 0, 8, 3080213, 0, 8, 3014677, 0, 8, 2949141, 0, 8, 2883605, 0, 8, 2818069, 0, 8, 2752533, 0, 8, 2686997, 0, 8, 2621461, 0, 8, 2555925, 0, 8, 2490389, 0, 8, 2424853, 0, 8, 2359317, 0, 8, 2293781, 0, 8, 2228245, 0, 8, 2162709, 0, 8, 2097173, 0, 8, 2031637, 0, 8, 3801108, 0, 8, 3735572, 0, 8, 3670036, 0, 8, 3604500, 0, 8, 3538964, 0, 8, 3473428, 0, 8, 3407892, 0, 8, 3342356, 0, 8, 3276820, 0, 8, 3211284, 0, 8, 3145748, 0, 8, 3080212, 0, 8, 3014676, 0, 8, 2949140, 0, 8, 2883604, 0, 8, 2818068, 0, 8, 2752532, 0, 8, 2686996, 0, 8, 2621460, 0, 8, 2555924, 0, 8, 2490388, 0, 8, 2424852, 0, 8, 2359316, 0, 8, 2293780, 0, 8, 2228244, 0, 8, 2162708, 0, 8, 2097172, 0, 8, 2031636, 0, 8, 3801107, 0, 8, 3735571, 0, 8, 3670035, 0, 8, 3604499, 0, 8, 3538963, 0, 8, 3473427, 0, 8, 3407891, 0, 8, 3342355, 0, 8, 3276819, 0, 8, 3211283, 0, 8, 3145747, 0, 8, 3080211, 0, 8, 3014675, 0, 8, 2949139, 0, 8, 2883603, 0, 8, 2818067, 0, 8, 2752531, 0, 8, 2686995, 0, 8, 2621459, 0, 8, 2555923, 0, 8, 2490387, 0, 8, 2424851, 0, 8, 2359315, 0, 8, 2293779, 0, 8, 2228243, 0, 8, 2162707, 0, 8, 2097171, 0, 8, 2031635, 0, 8, 3801106, 0, 8, 3735570, 0, 8, 3670034, 0, 8, 3604498, 0, 8, 3538962, 0, 8, 3473426, 0, 8, 3407890, 0, 8, 3342354, 0, 8, 3276818, 0, 8, 3211282, 0, 8, 3145746, 0, 8, 3080210, 0, 8, 3014674, 0, 8, 2949138, 0, 8, 2883602, 0, 8, 2818066, 0, 8, 2752530, 0, 8, 2686994, 0, 8, 2621458, 0, 8, 2555922, 0, 8, 2490386, 0, 8, 2424850, 0, 8, 2359314, 0, 8, 2293778, 0, 8, 2228242, 0, 8, 2162706, 0, 8, 2097170, 0, 8, 2031634, 0, 8, 3801105, 0, 8, 3735569, 0, 8, 3670033, 0, 8, 3604497, 0, 8, 3538961, 0, 8, 3473425, 0, 8, 3407889, 0, 8, 3342353, 0, 8, 3276817, 0, 8, 3211281, 0, 8, 3145745, 0, 8, 3080209, 0, 8, 3014673, 0, 8, 2949137, 0, 8, 2883601, 0, 8, 2818065, 0, 8, 2752529, 0, 8, 2686993, 0, 8, 2621457, 0, 8, 2555921, 0, 8, 2490385, 0, 8, 2424849, 0, 8, 2359313, 0, 8, 2293777, 0, 8, 2228241, 0, 8, 2162705, 0, 8, 2097169, 0, 8, 2031633, 0, 8, 3801104, 0, 8, 3735568, 0, 8, 3670032, 0, 8, 3604496, 0, 8, 3538960, 0, 8, 3473424, 0, 8, 3407888, 0, 8, 3342352, 0, 8, 3276816, 0, 8, 3211280, 0, 8, 3145744, 0, 8, 3080208, 0, 8, 3014672, 0, 8, 2949136, 0, 8, 2883600, 0, 8, 2818064, 0, 8, 2752528, 0, 8, 2686992, 0, 8, 2621456, 0, 8, 2555920, 0, 8, 2490384, 0, 8, 2424848, 0, 8, 2359312, 0, 8, 2293776, 0, 8, 2228240, 0, 8, 2162704, 0, 8, 2097168, 0, 8, 2031632, 0, 8, 3801103, 0, 8, 3735567, 0, 8, 3670031, 0, 8, 3604495, 0, 8, 3538959, 0, 8, 3473423, 0, 8, 3407887, 0, 8, 3342351, 0, 8, 3276815, 0, 8, 3211279, 0, 8, 3145743, 0, 8, 3080207, 0, 8, 3014671, 0, 8, 2949135, 0, 8, 2883599, 0, 8, 2818063, 0, 8, 2752527, 0, 8, 2686991, 0, 8, 2621455, 0, 8, 2555919, 0, 8, 2490383, 0, 8, 2424847, 0, 8, 2359311, 0, 8, 2293775, 0, 8, 2228239, 0, 8, 2162703, 0, 8, 2097167, 0, 8, 2031631, 0, 8, 3801102, 0, 8, 3735566, 0, 8, 3670030, 0, 8, 3604494, 0, 8, 3538958, 0, 8, 3473422, 0, 8, 3407886, 0, 8, 3342350, 0, 8, 3276814, 0, 8, 3211278, 0, 8, 3145742, 0, 8, 3080206, 0, 8, 3014670, 0, 8, 2949134, 0, 8, 2883598, 0, 8, 2818062, 0, 8, 2752526, 0, 8, 2686990, 0, 8, 2621454, 0, 8, 2555918, 0, 8, 2490382, 0, 8, 2424846, 0, 8, 2359310, 0, 8, 2293774, 0, 8, 2228238, 0, 8, 2162702, 0, 8, 2097166, 0, 8, 2031630, 0, 8, 3801101, 0, 8, 3735565, 0, 8, 3670029, 0, 8, 3604493, 0, 8, 3538957, 0, 8, 3473421, 0, 8, 3407885, 0, 8, 3342349, 0, 8, 3276813, 0, 8, 3211277, 0, 8, 3145741, 0, 8, 3080205, 0, 8, 3014669, 0, 8, 2949133, 0, 8, 2883597, 0, 8, 2818061, 0, 8, 2752525, 0, 8, 2686989, 0, 8, 2621453, 0, 8, 2555917, 0, 8, 2490381, 0, 8, 2424845, 0, 8, 2359309, 0, 8, 2293773, 0, 8, 2228237, 0, 8, 2162701, 0, 8, 2097165, 0, 8, 2031629, 0, 8, 3801100, 0, 8, 3735564, 0, 8, 3670028, 0, 8, 3604492, 0, 8, 3538956, 0, 8, 3473420, 0, 8, 3407884, 0, 8, 3342348, 0, 8, 3276812, 0, 8, 3211276, 0, 8, 3145740, 0, 8, 3080204, 0, 8, 3014668, 0, 8, 2949132, 0, 8, 2883596, 0, 8, 2818060, 0, 8, 2752524, 0, 8, 2686988, 0, 8, 2621452, 0, 8, 2555916, 0, 8, 2490380, 0, 8, 2424844, 0, 8, 2359308, 0, 8, 2293772, 0, 8, 2228236, 0, 8, 2162700, 0, 8, 2097164, 0, 8, 2031628, 0, 8, 3801099, 0, 8, 3735563, 0, 8, 3670027, 0, 8, 3604491, 0, 8, 3538955, 0, 8, 3473419, 0, 8, 3407883, 0, 8, 3342347, 0, 8, 3276811, 0, 8, 3211275, 0, 8, 3145739, 0, 8, 3080203, 0, 8, 3014667, 0, 8, 2949131, 0, 8, 2883595, 0, 8, 2818059, 0, 8, 2752523, 0, 8, 2686987, 0, 8, 2621451, 0, 8, 2555915, 0, 8, 2490379, 0, 8, 2424843, 0, 8, 2359307, 0, 8, 2293771, 0, 8, 2228235, 0, 8, 2162699, 0, 8, 2097163, 0, 8, 2031627, 0, 8, 3801098, 0, 8, 3735562, 0, 8, 3670026, 0, 8, 3604490, 0, 8, 3538954, 0, 8, 3473418, 0, 8, 3407882, 0, 8, 3342346, 0, 8, 3276810, 0, 8, 3211274, 0, 8, 3145738, 0, 8, 3080202, 0, 8, 3014666, 0, 8, 2949130, 0, 8, 2883594, 0, 8, 2818058, 0, 8, 2752522, 0, 8, 2686986, 0, 8, 2621450, 0, 8, 2555914, 0, 8, 2490378, 0, 8, 2424842, 0, 8, 2359306, 0, 8, 2293770, 0, 8, 2228234, 0, 8, 2162698, 0, 8, 2097162, 0, 8, 2031626, 0, 8, 2031625, 196608, 3, 2097161, 196608, 3, 2162697, 196608, 3, 2228233, 196608, 3, 2293769, 196608, 3, 2359305, 196608, 3, 2424841, 196608, 3, 2490377, 196608, 3, 2555913, 196608, 3, 2621449, 196608, 3, 2686985, 196608, 3, 2752521, 196608, 3, 2818057, 196608, 3, 2883593, 196608, 3, 2949129, 196608, 3, 3014665, 196608, 3, 3080201, 196608, 3, 3145737, 196608, 3, 3211273, 196608, 3, 3276809, 196608, 3, 3342345, 196608, 3, 3407881, 196608, 3, 3473417, 196608, 3, 3538953, 196608, 3, 3604489, 196608, 7, 3670025, 0, 8, 3735561, 0, 8, 3801097, 0, 8, 3866635, 0, 8, 3866633, 0, 8, 3866636, 0, 8, 3866634, 0, 8, 3866637, 0, 8, 3866638, 0, 8, 3866639, 0, 8, 3866640, 0, 8, 3866641, 0, 8, 3866642, 0, 8, 3866643, 0, 8, 3866644, 0, 8, 3866645, 0, 8, 3866646, 0, 8, 3866647, 0, 8, 3866648, 0, 8, 3866649, 0, 8, 3866650, 0, 8, 2031643, 65536, 3, 2097179, 65536, 3, 2162715, 65536, 3, 2228251, 65536, 3, 2293787, 65536, 3, 2359323, 65536, 3, 2424859, 65536, 3, 2490395, 65536, 3, 2555931, 65536, 3, 2621467, 65536, 3, 2687003, 65536, 3, 2752539, 65536, 3, 2818075, 65536, 3, 2883611, 65536, 3, 2949147, 65536, 3, 3014683, 65536, 3, 3080219, 65536, 3, 3145755, 65536, 3, 3211291, 65536, 3, 3276827, 65536, 3, 3342363, 65536, 3, 3407899, 65536, 3, 3473435, 65536, 3, 3538971, 65536, 3, 3604507, 65536, 7, 3670043, 0, 8, 3735579, 0, 8, 3801115, 0, 8, 3866651, 0, 8, 4915231, 0, 8, 4849695, 0, 8, 4784159, 0, 8, 4718623, 0, 8, 4653087, 0, 8, 4587551, 0, 8, 4522015, 0, 8, 4456479, 0, 8, 4390943, 0, 8, 4325407, 0, 8, 4259871, 0, 8, 4194335, 0, 8, 4128799, 0, 8, 4063263, 0, 8, 3997727, 0, 8, 3932191, 0, 8, 3866655, 0, 8, 3801119, 0, 8, 3735583, 0, 8, 3670047, 0, 8, 4915230, 0, 8, 4849694, 0, 8, 4784158, 0, 8, 4718622, 0, 8, 4653086, 0, 8, 4587550, 0, 8, 4522014, 0, 8, 4456478, 0, 8, 4390942, 0, 8, 4325406, 0, 8, 4259870, 0, 8, 4194334, 0, 8, 4128798, 0, 8, 4063262, 0, 8, 3997726, 0, 8, 3932190, 0, 8, 3866654, 0, 8, 3801118, 0, 8, 3735582, 0, 8, 3670046, 0, 8, 4915229, 0, 8, 4849693, 0, 8, 4784157, 0, 8, 4718621, 0, 8, 4653085, 0, 8, 4587549, 0, 8, 4522013, 0, 8, 4456477, 0, 8, 4390941, 0, 8, 4325405, 0, 8, 4259869, 0, 8, 4194333, 0, 8, 4128797, 0, 8, 4063261, 0, 8, 3997725, 0, 8, 3932189, 0, 8, 3866653, 0, 8, 3801117, 0, 8, 3735581, 0, 8, 3670045, 0, 8, 4915228, 0, 8, 4849692, 0, 8, 4784156, 0, 8, 4718620, 0, 8, 4653084, 0, 8, 4587548, 0, 8, 4522012, 0, 8, 4456476, 0, 8, 4390940, 0, 8, 4325404, 0, 8, 4259868, 0, 8, 4194332, 0, 8, 4128796, 0, 8, 4063260, 0, 8, 3997724, 0, 8, 3932188, 0, 8, 3866652, 0, 8, 3801116, 0, 8, 3735580, 0, 8, 3670044, 0, 8, 4915227, 0, 8, 4849691, 0, 8, 4784155, 0, 8, 4718619, 0, 8, 4653083, 0, 8, 4587547, 0, 8, 4522011, 0, 8, 4456475, 0, 8, 4390939, 0, 8, 4325403, 0, 8, 4259867, 0, 8, 4194331, 0, 8, 4128795, 0, 8, 4063259, 0, 8, 3997723, 0, 8, 3932187, 0, 8, 4915226, 0, 8, 4849690, 0, 8, 4784154, 0, 8, 4718618, 0, 8, 4653082, 0, 8, 4587546, 0, 8, 4522010, 0, 8, 4456474, 0, 8, 4390938, 0, 8, 4325402, 0, 8, 4259866, 0, 8, 4194330, 0, 8, 4128794, 0, 8, 4063258, 0, 8, 3997722, 0, 8, 3932186, 0, 8, 4915225, 0, 8, 4849689, 0, 8, 4784153, 0, 8, 4718617, 0, 8, 4653081, 0, 8, 4587545, 0, 8, 4522009, 0, 8, 4456473, 0, 8, 4390937, 0, 8, 4325401, 0, 8, 4259865, 0, 8, 4194329, 0, 8, 4128793, 0, 8, 4063257, 0, 8, 3997721, 0, 8, 3932185, 0, 8, 4915224, 0, 8, 4849688, 0, 8, 4784152, 0, 8, 4718616, 0, 8, 4653080, 0, 8, 4587544, 0, 8, 4522008, 0, 8, 4456472, 0, 8, 4390936, 0, 8, 4325400, 0, 8, 4259864, 0, 8, 4194328, 0, 8, 4128792, 0, 8, 4063256, 0, 8, 3997720, 0, 8, 3932184, 0, 8, 4915223, 0, 8, 4849687, 0, 8, 4784151, 0, 8, 4718615, 0, 8, 4653079, 0, 8, 4587543, 0, 8, 4522007, 0, 8, 4456471, 0, 8, 4390935, 0, 8, 4325399, 0, 8, 4259863, 0, 8, 4194327, 0, 8, 4128791, 0, 8, 4063255, 0, 8, 3997719, 0, 8, 3932183, 0, 8, 4915222, 0, 8, 4849686, 0, 8, 4784150, 0, 8, 4718614, 0, 8, 4653078, 0, 8, 4587542, 0, 8, 4522006, 0, 8, 4456470, 0, 8, 4390934, 0, 8, 4325398, 0, 8, 4259862, 0, 8, 4194326, 0, 8, 4128790, 0, 8, 4063254, 0, 8, 3997718, 0, 8, 3932182, 0, 8, 4915221, 0, 8, 4849685, 0, 8, 4784149, 0, 8, 4718613, 0, 8, 4653077, 0, 8, 4587541, 0, 8, 4522005, 0, 8, 4456469, 0, 8, 4390933, 0, 8, 4325397, 0, 8, 4259861, 0, 8, 4194325, 0, 8, 4128789, 0, 8, 4063253, 0, 8, 3997717, 0, 8, 3932181, 0, 8, 4915220, 0, 8, 4849684, 0, 8, 4784148, 0, 8, 4718612, 0, 8, 4653076, 0, 8, 4587540, 0, 8, 4522004, 0, 8, 4456468, 0, 8, 4390932, 0, 8, 4325396, 0, 8, 4259860, 0, 8, 4194324, 0, 8, 4128788, 0, 8, 4063252, 0, 8, 3997716, 0, 8, 3932180, 0, 8, 4915219, 0, 8, 4849683, 0, 8, 4784147, 0, 8, 4718611, 0, 8, 4653075, 0, 8, 4587539, 0, 8, 4522003, 0, 8, 4456467, 0, 8, 4390931, 0, 8, 4325395, 0, 8, 4259859, 0, 8, 4194323, 0, 8, 4128787, 0, 8, 4063251, 0, 8, 3997715, 0, 8, 3932179, 0, 8, 4915218, 0, 8, 4849682, 0, 8, 4784146, 0, 8, 4718610, 0, 8, 4653074, 0, 8, 4587538, 0, 8, 4522002, 0, 8, 4456466, 0, 8, 4390930, 0, 8, 4325394, 0, 8, 4259858, 0, 8, 4194322, 0, 8, 4128786, 0, 8, 4063250, 0, 8, 3997714, 0, 8, 3932178, 0, 8, 4915217, 0, 8, 4849681, 0, 8, 4784145, 0, 8, 4718609, 0, 8, 4653073, 0, 8, 4587537, 0, 8, 4522001, 0, 8, 4456465, 0, 8, 4390929, 0, 8, 4325393, 0, 8, 4259857, 0, 8, 4194321, 0, 8, 4128785, 0, 8, 4063249, 0, 8, 3997713, 0, 8, 3932177, 0, 8, 4915216, 0, 8, 4849680, 0, 8, 4784144, 0, 8, 4718608, 0, 8, 4653072, 0, 8, 4587536, 0, 8, 4522000, 0, 8, 4456464, 0, 8, 4390928, 0, 8, 4325392, 0, 8, 4259856, 0, 8, 4194320, 0, 8, 4128784, 0, 8, 4063248, 0, 8, 3997712, 0, 8, 3932176, 0, 8, 4915215, 0, 8, 4849679, 0, 8, 4784143, 0, 8, 4718607, 0, 8, 4653071, 0, 8, 4587535, 0, 8, 4521999, 0, 8, 4456463, 0, 8, 4390927, 0, 8, 4325391, 0, 8, 4259855, 0, 8, 4194319, 0, 8, 4128783, 0, 8, 4063247, 0, 8, 3997711, 0, 8, 3932175, 0, 8, 4915214, 0, 8, 4849678, 0, 8, 4784142, 0, 8, 4718606, 0, 8, 4653070, 0, 8, 4587534, 0, 8, 4521998, 0, 8, 4456462, 0, 8, 4390926, 0, 8, 4325390, 0, 8, 4259854, 0, 8, 4194318, 0, 8, 4128782, 0, 8, 4063246, 0, 8, 3997710, 0, 8, 3932174, 0, 8, 4915213, 0, 8, 4849677, 0, 8, 4784141, 0, 8, 4718605, 0, 8, 4653069, 0, 8, 4587533, 0, 8, 4521997, 0, 8, 4456461, 0, 8, 4390925, 0, 8, 4325389, 0, 8, 4259853, 0, 8, 4194317, 0, 8, 4128781, 0, 8, 4063245, 0, 8, 3997709, 0, 8, 3932173, 0, 8, 4915212, 0, 8, 4849676, 0, 8, 4784140, 0, 8, 4718604, 0, 8, 4653068, 0, 8, 4587532, 0, 8, 4521996, 0, 8, 4456460, 0, 8, 4390924, 0, 8, 4325388, 0, 8, 4259852, 0, 8, 4194316, 0, 8, 4128780, 0, 8, 4063244, 0, 8, 3997708, 0, 8, 3932172, 0, 8, 4915211, 0, 8, 4849675, 0, 8, 4784139, 0, 8, 4718603, 0, 8, 4653067, 0, 8, 4587531, 0, 8, 4521995, 0, 8, 4456459, 0, 8, 4390923, 0, 8, 4325387, 0, 8, 4259851, 0, 8, 4194315, 0, 8, 4128779, 0, 8, 4063243, 0, 8, 3997707, 0, 8, 3932171, 0, 8, 4915210, 0, 8, 4849674, 0, 8, 4784138, 0, 8, 4718602, 0, 8, 4653066, 0, 8, 4587530, 0, 8, 4521994, 0, 8, 4456458, 0, 8, 4390922, 0, 8, 4325386, 0, 8, 4259850, 0, 8, 4194314, 0, 8, 4128778, 0, 8, 4063242, 0, 8, 3997706, 0, 8, 3932170, 0, 8, 4915209, 0, 8, 4849673, 0, 8, 4784137, 0, 8, 4718601, 0, 8, 4653065, 0, 8, 4587529, 0, 8, 4521993, 0, 8, 4456457, 0, 8, 4390921, 0, 8, 4325385, 0, 8, 4259849, 0, 8, 4194313, 0, 8, 4128777, 0, 8, 4063241, 0, 8, 3997705, 0, 8, 3932169, 0, 8, 4915208, 0, 8, 4849672, 0, 8, 4784136, 0, 8, 4718600, 0, 8, 4653064, 0, 8, 4587528, 0, 8, 4521992, 0, 8, 4456456, 0, 8, 4390920, 0, 8, 4325384, 0, 8, 4259848, 0, 8, 4194312, 0, 8, 4128776, 0, 8, 4063240, 0, 8, 3997704, 0, 8, 3932168, 0, 8, 3866632, 0, 8, 3801096, 0, 8, 3735560, 0, 8, 3670024, 0, 8, 4915207, 0, 8, 4849671, 0, 8, 4784135, 0, 8, 4718599, 0, 8, 4653063, 0, 8, 4587527, 0, 8, 4521991, 0, 8, 4456455, 0, 8, 4390919, 0, 8, 4325383, 0, 8, 4259847, 0, 8, 4194311, 0, 8, 4128775, 0, 8, 4063239, 0, 8, 3997703, 0, 8, 3932167, 0, 8, 3866631, 0, 8, 3801095, 0, 8, 3735559, 0, 8, 3670023, 0, 8, 4915206, 0, 8, 4849670, 0, 8, 4784134, 0, 8, 4718598, 0, 8, 4653062, 0, 8, 4587526, 0, 8, 4521990, 0, 8, 4456454, 0, 8, 4390918, 0, 8, 4325382, 0, 8, 4259846, 0, 8, 4194310, 0, 8, 4128774, 0, 8, 4063238, 0, 8, 3997702, 0, 8, 3932166, 0, 8, 3866630, 0, 8, 3801094, 0, 8, 3735558, 0, 8, 3670022, 0, 8, 4915205, 0, 8, 4849669, 0, 8, 4784133, 0, 8, 4718597, 0, 8, 4653061, 0, 8, 4587525, 0, 8, 4521989, 0, 8, 4456453, 0, 8, 4390917, 0, 8, 4325381, 0, 8, 4259845, 0, 8, 4194309, 0, 8, 4128773, 0, 8, 4063237, 0, 8, 3997701, 0, 8, 3932165, 0, 8, 3866629, 0, 8, 3801093, 0, 8, 3735557, 0, 8, 3670021, 0, 8, 4915204, 0, 8, 4849668, 0, 8, 4784132, 0, 8, 4718596, 0, 8, 4653060, 0, 8, 4587524, 0, 8, 4521988, 0, 8, 4456452, 0, 8, 4390916, 0, 8, 4325380, 0, 8, 4259844, 0, 8, 4194308, 0, 8, 4128772, 0, 8, 4063236, 0, 8, 3997700, 0, 8, 3932164, 0, 8, 3866628, 0, 8, 3801092, 0, 8, 3735556, 0, 8, 3670020, 0, 8, 4915203, 0, 8, 4849667, 0, 8, 4784131, 0, 8, 4718595, 0, 8, 4653059, 0, 8, 4587523, 0, 8, 4521987, 0, 8, 4456451, 0, 8, 4390915, 0, 8, 4325379, 0, 8, 4259843, 0, 8, 4194307, 0, 8, 4128771, 0, 8, 4063235, 0, 8, 3997699, 0, 8, 3932163, 0, 8, 3866627, 0, 8, 3801091, 0, 8, 3735555, 0, 8, 3670019, 0, 8, 4915202, 0, 8, 4849666, 0, 8, 4784130, 0, 8, 4718594, 0, 8, 4653058, 0, 8, 4587522, 0, 8, 4521986, 0, 8, 4456450, 0, 8, 4390914, 0, 8, 4325378, 0, 8, 4259842, 0, 8, 4194306, 0, 8, 4128770, 0, 8, 4063234, 0, 8, 3997698, 0, 8, 3932162, 0, 8, 3866626, 0, 8, 3801090, 0, 8, 3735554, 0, 8, 3670018, 0, 8, 4915201, 0, 8, 4849665, 0, 8, 4784129, 0, 8, 4718593, 0, 8, 4653057, 0, 8, 4587521, 0, 8, 4521985, 0, 8, 4456449, 0, 8, 4390913, 0, 8, 4325377, 0, 8, 4259841, 0, 8, 4194305, 0, 8, 4128769, 0, 8, 4063233, 0, 8, 3997697, 0, 8, 3932161, 0, 8, 3866625, 0, 8, 3801089, 0, 8, 3735553, 0, 8, 3670017, 0, 8, 4915200, 0, 8, 4849664, 0, 8, 4784128, 0, 8, 4718592, 0, 8, 4653056, 0, 8, 4587520, 0, 8, 4521984, 0, 8, 4456448, 0, 8, 4390912, 0, 8, 4325376, 0, 8, 4259840, 0, 8, 4194304, 0, 8, 4128768, 0, 8, 4063232, 0, 8, 3997696, 0, 8, 3932160, 0, 8, 3866624, 0, 8, 3801088, 0, 8, 3735552, 0, 8, 3670016, 0, 8, 4980735, 0, 8, 4915199, 0, 8, 4849663, 0, 8, 4784127, 0, 8, 4718591, 0, 8, 4653055, 0, 8, 4587519, 0, 8, 4521983, 0, 8, 4456447, 0, 8, 4390911, 0, 8, 4325375, 0, 8, 4259839, 0, 8, 4194303, 0, 8, 4128767, 0, 8, 4063231, 0, 8, 3997695, 0, 8, 3932159, 0, 8, 3866623, 0, 8, 3801087, 0, 8, 3735551, 0, 8, 4980734, 0, 8, 4915198, 0, 8, 4849662, 0, 8, 4784126, 0, 8, 4718590, 0, 8, 4653054, 0, 8, 4587518, 0, 8, 4521982, 0, 8, 4456446, 0, 8, 4390910, 0, 8, 4325374, 0, 8, 4259838, 0, 8, 4194302, 0, 8, 4128766, 0, 8, 4063230, 0, 8, 3997694, 0, 8, 3932158, 0, 8, 3866622, 0, 8, 3801086, 0, 8, 3735550, 0, 8, 4980733, 0, 8, 4915197, 0, 8, 4849661, 0, 8, 4784125, 0, 8, 4718589, 0, 8, 4653053, 0, 8, 4587517, 0, 8, 4521981, 0, 8, 4456445, 0, 8, 4390909, 0, 8, 4325373, 0, 8, 4259837, 0, 8, 4194301, 0, 8, 4128765, 0, 8, 4063229, 0, 8, 3997693, 0, 8, 3932157, 0, 8, 3866621, 0, 8, 3801085, 0, 8, 3735549, 0, 8, 4980732, 0, 8, 4915196, 0, 8, 4849660, 0, 8, 4784124, 0, 8, 4718588, 0, 8, 4653052, 0, 8, 4587516, 0, 8, 4521980, 0, 8, 4456444, 0, 8, 4390908, 0, 8, 4325372, 0, 8, 4259836, 0, 8, 4194300, 0, 8, 4128764, 0, 8, 4063228, 0, 8, 3997692, 0, 8, 3932156, 0, 8, 3866620, 0, 8, 3801084, 0, 8, 3735548, 0, 8, 4980731, 0, 8, 4915195, 0, 8, 4849659, 0, 8, 4784123, 0, 8, 4718587, 0, 8, 4653051, 0, 8, 4587515, 0, 8, 4521979, 0, 8, 4456443, 0, 8, 4390907, 0, 8, 4325371, 0, 8, 4259835, 0, 8, 4194299, 0, 8, 4128763, 0, 8, 4063227, 0, 8, 3997691, 0, 8, 3932155, 0, 8, 3866619, 0, 8, 3801083, 0, 8, 3735547, 0, 8, 3801082, 196608, 3, 3670010, 196608, 4, 3670012, 131072, 7, 3866618, 196608, 3, 3735546, 196608, 3, 3932154, 196608, 3, 3997690, 196608, 3, 4063226, 196608, 3, 4128762, 196608, 3, 4194298, 196608, 3, 4259834, 196608, 3, 4325370, 196608, 3, 4390906, 196608, 3, 4456442, 196608, 3, 4521978, 196608, 3, 4587514, 196608, 3, 4653050, 196608, 3, 4718586, 196608, 3, 4784122, 196608, 3, 4849658, 196608, 3, 4915194, 196608, 3, 4980730, 196608, 3, 5046268, 131072, 2, 5046266, 720896, 2, 3670011, 131072, 7, 3670013, 131072, 7, 5046269, 131072, 2, 5046267, 131072, 2, 3670014, 131072, 7, 5046270, 131072, 2, 3670015, 131072, 7, 5046271, 131072, 2, 3604480, 131072, 7, 4980736, 131072, 2, 3604481, 131072, 7, 4980737, 131072, 2, 3604482, 131072, 7, 4980738, 131072, 2, 3604483, 131072, 7, 4980739, 131072, 2, 3604484, 131072, 7, 4980740, 131072, 2, 3604485, 131072, 7, 4980741, 131072, 2, 3604486, 131072, 7, 4980742, 131072, 2, 3604487, 131072, 7, 4980743, 131072, 2, 3604488, 131072, 7, 4980744, 131072, 2, 4980745, 131072, 2, 4980746, 131072, 2, 4980747, 131072, 2, 4980748, 131072, 2, 4980749, 131072, 2, 4980750, 131072, 2, 4980751, 131072, 2, 4980752, 131072, 2, 4980753, 131072, 2, 4980754, 196608, 2, 4980755, 0, 8, 4980756, 0, 8, 4980757, 0, 8, 4980758, 0, 8, 4980759, 0, 8, 4980760, 0, 8, 4980761, 0, 8, 4980762, 0, 8, 4980763, 0, 8, 3604508, 131072, 7, 4980764, 0, 8, 3604509, 131072, 7, 4980765, 0, 8, 3604510, 131072, 7, 4980766, 0, 8, 3604511, 131072, 7, 4980767, 0, 8, 3735584, 65536, 3, 3604512, 65536, 4, 3801120, 65536, 3, 3670048, 65536, 3, 3866656, 65536, 3, 3932192, 65536, 3, 3997728, 65536, 3, 4063264, 65536, 3, 4128800, 65536, 3, 4194336, 65536, 3, 4259872, 65536, 3, 4325408, 65536, 3, 4390944, 65536, 3, 4456480, 65536, 3, 4522016, 65536, 3, 4587552, 65536, 3, 4653088, 65536, 3, 4718624, 65536, 7, 4784160, 0, 8, 4849696, 0, 8, 4915232, 0, 8, 4980768, 0, 8, 4915288, 0, 8, 4849752, 0, 8, 4784216, 0, 8, 4718680, 0, 8, 4653144, 0, 8, 4587608, 0, 8, 4522072, 0, 8, 3604568, 0, 8, 3539032, 0, 8, 3473496, 0, 8, 3407960, 0, 8, 3342424, 0, 8, 3276888, 0, 8, 3211352, 0, 8, 3145816, 0, 8, 3080280, 0, 8, 3014744, 0, 8, 2949208, 0, 8, 2883672, 0, 8, 2818136, 0, 8, 2752600, 0, 8, 4915287, 0, 8, 4849751, 0, 8, 4784215, 0, 8, 4718679, 0, 8, 4653143, 0, 8, 4587607, 0, 8, 4522071, 0, 8, 4456535, 0, 8, 4390999, 0, 8, 4325463, 0, 8, 4259927, 0, 8, 4194391, 0, 8, 4128855, 0, 8, 4063319, 0, 8, 3997783, 0, 8, 3932247, 0, 8, 3866711, 0, 8, 3801175, 0, 8, 3735639, 0, 8, 3670103, 0, 8, 3604567, 0, 8, 3539031, 0, 8, 3473495, 0, 8, 3407959, 0, 8, 3342423, 0, 8, 3276887, 0, 8, 3211351, 0, 8, 3145815, 0, 8, 3080279, 0, 8, 3014743, 0, 8, 2949207, 0, 8, 2883671, 0, 8, 2818135, 0, 8, 2752599, 0, 8, 4915286, 0, 8, 4849750, 0, 8, 4784214, 0, 8, 4718678, 0, 8, 4653142, 0, 8, 4587606, 0, 8, 4522070, 0, 8, 4456534, 0, 8, 4390998, 0, 8, 4325462, 0, 8, 4259926, 0, 8, 4194390, 0, 8, 4128854, 0, 8, 4063318, 0, 8, 3997782, 0, 8, 3932246, 0, 8, 3866710, 0, 8, 3801174, 0, 8, 3735638, 0, 8, 3670102, 0, 8, 3604566, 0, 8, 3539030, 0, 8, 3473494, 0, 8, 3407958, 0, 8, 3342422, 0, 8, 3276886, 0, 8, 3211350, 0, 8, 3145814, 0, 8, 3080278, 0, 8, 3014742, 0, 8, 2949206, 0, 8, 2883670, 0, 8, 2818134, 0, 8, 2752598, 0, 8, 4915285, 0, 8, 4849749, 0, 8, 4784213, 0, 8, 4718677, 0, 8, 4653141, 0, 8, 4587605, 0, 8, 4522069, 0, 8, 4456533, 0, 8, 4390997, 0, 8, 4325461, 0, 8, 4259925, 0, 8, 4194389, 0, 8, 4128853, 0, 8, 4063317, 0, 8, 3997781, 0, 8, 3932245, 0, 8, 3866709, 0, 8, 3801173, 0, 8, 3735637, 0, 8, 3670101, 0, 8, 3604565, 0, 8, 3539029, 0, 8, 3473493, 0, 8, 3407957, 0, 8, 3342421, 0, 8, 3276885, 0, 8, 3211349, 0, 8, 3145813, 0, 8, 3080277, 0, 8, 3014741, 0, 8, 2949205, 0, 8, 2883669, 0, 8, 2818133, 0, 8, 2752597, 0, 8, 4915284, 0, 8, 4849748, 0, 8, 4784212, 0, 8, 4718676, 0, 8, 4653140, 0, 8, 4587604, 0, 8, 4522068, 0, 8, 4456532, 0, 8, 4390996, 0, 8, 4325460, 0, 8, 4259924, 0, 8, 4194388, 0, 8, 4128852, 0, 8, 4063316, 0, 8, 3997780, 0, 8, 3932244, 0, 8, 3866708, 0, 8, 3801172, 0, 8, 3735636, 0, 8, 3670100, 0, 8, 3604564, 0, 8, 3539028, 0, 8, 3473492, 0, 8, 3407956, 0, 8, 3342420, 0, 8, 3276884, 0, 8, 3211348, 0, 8, 3145812, 0, 8, 3080276, 0, 8, 3014740, 0, 8, 2949204, 0, 8, 2883668, 0, 8, 2818132, 0, 8, 2752596, 0, 8, 4915283, 0, 8, 4849747, 0, 8, 4784211, 0, 8, 4718675, 0, 8, 4653139, 0, 8, 4587603, 0, 8, 4522067, 0, 8, 4456531, 0, 8, 4390995, 0, 8, 4325459, 0, 8, 4259923, 0, 8, 4194387, 0, 8, 4128851, 0, 8, 4063315, 0, 8, 3997779, 0, 8, 3932243, 0, 8, 3866707, 0, 8, 3801171, 0, 8, 3735635, 0, 8, 3670099, 0, 8, 3604563, 0, 8, 3539027, 0, 8, 3473491, 0, 8, 3407955, 0, 8, 3342419, 0, 8, 3276883, 0, 8, 3211347, 0, 8, 3145811, 0, 8, 3080275, 0, 8, 3014739, 0, 8, 2949203, 0, 8, 2883667, 0, 8, 2818131, 0, 8, 2752595, 0, 8, 4915282, 0, 8, 4849746, 0, 8, 4784210, 0, 8, 4718674, 0, 8, 4653138, 0, 8, 4587602, 0, 8, 4522066, 0, 8, 4456530, 0, 8, 4390994, 0, 8, 4325458, 0, 8, 4259922, 0, 8, 4194386, 0, 8, 4128850, 0, 8, 4063314, 0, 8, 3997778, 0, 8, 3932242, 0, 8, 3866706, 0, 8, 3801170, 0, 8, 3735634, 0, 8, 3670098, 0, 8, 3604562, 0, 8, 3539026, 0, 8, 3473490, 0, 8, 3407954, 0, 8, 3342418, 0, 8, 3276882, 0, 8, 3211346, 0, 8, 3145810, 0, 8, 3080274, 0, 8, 3014738, 0, 8, 2949202, 0, 8, 2883666, 0, 8, 2818130, 0, 8, 2752594, 0, 8, 4915281, 0, 8, 4849745, 0, 8, 4784209, 0, 8, 4718673, 0, 8, 4653137, 0, 8, 4587601, 0, 8, 4522065, 0, 8, 4456529, 0, 8, 4390993, 0, 8, 4325457, 0, 8, 4259921, 0, 8, 4194385, 0, 8, 4128849, 0, 8, 4063313, 0, 8, 3997777, 0, 8, 3932241, 0, 8, 3866705, 0, 8, 3801169, 0, 8, 3735633, 0, 8, 3670097, 0, 8, 3604561, 0, 8, 3539025, 0, 8, 3473489, 0, 8, 3407953, 0, 8, 3342417, 0, 8, 3276881, 0, 8, 3211345, 0, 8, 3145809, 0, 8, 3080273, 0, 8, 3014737, 0, 8, 2949201, 0, 8, 2883665, 0, 8, 2818129, 0, 8, 2752593, 0, 8, 4915280, 0, 8, 4849744, 0, 8, 4784208, 0, 8, 4718672, 0, 8, 4653136, 0, 8, 4587600, 0, 8, 4522064, 0, 8, 4456528, 0, 8, 4390992, 0, 8, 4325456, 0, 8, 4259920, 0, 8, 4194384, 0, 8, 4128848, 0, 8, 4063312, 0, 8, 3997776, 0, 8, 3932240, 0, 8, 3866704, 0, 8, 3801168, 0, 8, 3735632, 0, 8, 3670096, 0, 8, 3604560, 0, 8, 3539024, 0, 8, 3473488, 0, 8, 3407952, 0, 8, 3342416, 0, 8, 3276880, 0, 8, 3211344, 0, 8, 3145808, 0, 8, 3080272, 0, 8, 3014736, 0, 8, 2949200, 0, 8, 2883664, 0, 8, 2818128, 0, 8, 2752592, 0, 8, 4915279, 0, 8, 4849743, 0, 8, 4784207, 0, 8, 4718671, 0, 8, 4653135, 0, 8, 4587599, 0, 8, 4522063, 0, 8, 4456527, 0, 8, 4390991, 0, 8, 4325455, 0, 8, 4259919, 0, 8, 4194383, 0, 8, 4128847, 0, 8, 4063311, 0, 8, 3997775, 0, 8, 3932239, 0, 8, 3866703, 0, 8, 3801167, 0, 8, 3735631, 0, 8, 3670095, 0, 8, 3604559, 0, 8, 3539023, 0, 8, 3473487, 0, 8, 3407951, 0, 8, 3342415, 0, 8, 3276879, 0, 8, 3211343, 0, 8, 3145807, 0, 8, 3080271, 0, 8, 3014735, 0, 8, 2949199, 0, 8, 2883663, 0, 8, 2818127, 0, 8, 2752591, 0, 8, 4915278, 0, 8, 4849742, 0, 8, 4784206, 0, 8, 4718670, 0, 8, 4653134, 0, 8, 4587598, 0, 8, 4522062, 0, 8, 4456526, 0, 8, 4390990, 0, 8, 4325454, 0, 8, 4259918, 0, 8, 4194382, 0, 8, 4128846, 0, 8, 4063310, 0, 8, 3997774, 0, 8, 3932238, 0, 8, 3866702, 0, 8, 3801166, 0, 8, 3735630, 0, 8, 3670094, 0, 8, 3604558, 0, 8, 3539022, 0, 8, 3473486, 0, 8, 3407950, 0, 8, 3342414, 0, 8, 3276878, 0, 8, 3211342, 0, 8, 3145806, 0, 8, 3080270, 0, 8, 3014734, 0, 8, 2949198, 0, 8, 2883662, 0, 8, 2818126, 0, 8, 2752590, 0, 8, 4915277, 0, 8, 4849741, 0, 8, 4784205, 0, 8, 4718669, 0, 8, 4653133, 0, 8, 4587597, 0, 8, 4522061, 0, 8, 4456525, 0, 8, 4390989, 0, 8, 4325453, 0, 8, 4259917, 0, 8, 4194381, 0, 8, 4128845, 0, 8, 4063309, 0, 8, 3997773, 0, 8, 3932237, 0, 8, 3866701, 0, 8, 3801165, 0, 8, 3735629, 0, 8, 3670093, 0, 8, 3604557, 0, 8, 3539021, 0, 8, 3473485, 0, 8, 3407949, 0, 8, 3342413, 0, 8, 3276877, 0, 8, 3211341, 0, 8, 3145805, 0, 8, 3080269, 0, 8, 3014733, 0, 8, 2949197, 0, 8, 2883661, 0, 8, 2818125, 0, 8, 2752589, 0, 8, 4915276, 0, 8, 4849740, 0, 8, 4784204, 0, 8, 4718668, 0, 8, 4653132, 0, 8, 4587596, 0, 8, 4522060, 0, 8, 4456524, 0, 8, 4390988, 0, 8, 4325452, 0, 8, 4259916, 0, 8, 4194380, 0, 8, 4128844, 0, 8, 4063308, 0, 8, 3997772, 0, 8, 3932236, 0, 8, 3866700, 0, 8, 3801164, 0, 8, 3735628, 0, 8, 3670092, 0, 8, 3604556, 0, 8, 3539020, 0, 8, 3473484, 0, 8, 3407948, 0, 8, 3342412, 0, 8, 3276876, 0, 8, 3211340, 0, 8, 3145804, 0, 8, 3080268, 0, 8, 3014732, 0, 8, 2949196, 0, 8, 2883660, 0, 8, 2818124, 0, 8, 2752588, 0, 8, 4915275, 0, 8, 4849739, 0, 8, 4784203, 0, 8, 4718667, 0, 8, 4653131, 0, 8, 4587595, 0, 8, 4522059, 0, 8, 4456523, 0, 8, 4390987, 0, 8, 4325451, 0, 8, 4259915, 0, 8, 4194379, 0, 8, 4128843, 0, 8, 4063307, 0, 8, 3997771, 0, 8, 3932235, 0, 8, 3866699, 0, 8, 3801163, 0, 8, 3735627, 0, 8, 3670091, 0, 8, 3604555, 0, 8, 3539019, 0, 8, 3473483, 0, 8, 3407947, 0, 8, 3342411, 0, 8, 3276875, 0, 8, 3211339, 0, 8, 3145803, 0, 8, 3080267, 0, 8, 3014731, 0, 8, 2949195, 0, 8, 2883659, 0, 8, 2818123, 0, 8, 2752587, 0, 8, 4915274, 0, 8, 4849738, 0, 8, 4784202, 0, 8, 4718666, 0, 8, 4653130, 0, 8, 4587594, 0, 8, 4522058, 0, 8, 4456522, 0, 8, 4390986, 0, 8, 4325450, 0, 8, 4259914, 0, 8, 4194378, 0, 8, 4128842, 0, 8, 4063306, 0, 8, 3997770, 0, 8, 3932234, 0, 8, 3866698, 0, 8, 3801162, 0, 8, 3735626, 0, 8, 3670090, 0, 8, 3604554, 0, 8, 3539018, 0, 8, 3473482, 0, 8, 3407946, 0, 8, 3342410, 0, 8, 3276874, 0, 8, 3211338, 0, 8, 3145802, 0, 8, 3080266, 0, 8, 3014730, 0, 8, 2949194, 0, 8, 2883658, 0, 8, 2818122, 0, 8, 2752586, 0, 8, 4915273, 0, 8, 4849737, 0, 8, 4784201, 0, 8, 4718665, 0, 8, 4653129, 0, 8, 4587593, 0, 8, 4522057, 0, 8, 4456521, 0, 8, 4390985, 0, 8, 4325449, 0, 8, 4259913, 0, 8, 4194377, 0, 8, 4128841, 0, 8, 4063305, 0, 8, 3997769, 0, 8, 3932233, 0, 8, 3866697, 0, 8, 3801161, 0, 8, 3735625, 0, 8, 3670089, 0, 8, 3604553, 0, 8, 3539017, 0, 8, 3473481, 0, 8, 3407945, 0, 8, 3342409, 0, 8, 3276873, 0, 8, 3211337, 0, 8, 3145801, 0, 8, 3080265, 0, 8, 3014729, 0, 8, 2949193, 0, 8, 2883657, 0, 8, 2818121, 0, 8, 2752585, 0, 8, 4915272, 0, 8, 4849736, 0, 8, 4784200, 0, 8, 4718664, 0, 8, 4653128, 0, 8, 4587592, 0, 8, 4522056, 0, 8, 4456520, 0, 8, 4390984, 0, 8, 4325448, 0, 8, 4259912, 0, 8, 4194376, 0, 8, 4128840, 0, 8, 4063304, 0, 8, 3997768, 0, 8, 3932232, 0, 8, 3866696, 0, 8, 3801160, 0, 8, 3735624, 0, 8, 3670088, 0, 8, 3604552, 0, 8, 3539016, 0, 8, 3473480, 0, 8, 3407944, 0, 8, 3342408, 0, 8, 3276872, 0, 8, 3211336, 0, 8, 3145800, 0, 8, 3080264, 0, 8, 3014728, 0, 8, 2949192, 0, 8, 2883656, 0, 8, 2818120, 0, 8, 2752584, 0, 8, 4915271, 0, 8, 4849735, 0, 8, 4784199, 0, 8, 4718663, 0, 8, 4653127, 0, 8, 4587591, 0, 8, 4522055, 0, 8, 4456519, 0, 8, 4390983, 0, 8, 4325447, 0, 8, 4259911, 0, 8, 4194375, 0, 8, 4128839, 0, 8, 4063303, 0, 8, 3997767, 0, 8, 3932231, 0, 8, 3866695, 0, 8, 3801159, 0, 8, 3735623, 0, 8, 3670087, 0, 8, 3604551, 0, 8, 3539015, 0, 8, 3473479, 0, 8, 3407943, 0, 8, 3342407, 0, 8, 3276871, 0, 8, 3211335, 0, 8, 3145799, 0, 8, 3080263, 0, 8, 3014727, 0, 8, 2949191, 0, 8, 2883655, 0, 8, 2818119, 0, 8, 2752583, 0, 8, 4915270, 0, 8, 4849734, 0, 8, 4784198, 0, 8, 4718662, 0, 8, 4653126, 0, 8, 4587590, 0, 8, 4522054, 0, 8, 4456518, 0, 8, 4390982, 0, 8, 4325446, 0, 8, 4259910, 0, 8, 4194374, 0, 8, 4128838, 0, 8, 4063302, 0, 8, 3997766, 0, 8, 3932230, 0, 8, 3866694, 0, 8, 3801158, 0, 8, 3735622, 0, 8, 3670086, 0, 8, 3604550, 0, 8, 3539014, 0, 8, 3473478, 0, 8, 3407942, 0, 8, 3342406, 0, 8, 3276870, 0, 8, 3211334, 0, 8, 3145798, 0, 8, 3080262, 0, 8, 4915269, 0, 8, 4849733, 0, 8, 4784197, 0, 8, 4718661, 0, 8, 4653125, 0, 8, 4587589, 0, 8, 4522053, 0, 8, 4456517, 0, 8, 4390981, 0, 8, 4325445, 0, 8, 4259909, 0, 8, 4194373, 0, 8, 4128837, 0, 8, 4063301, 0, 8, 3997765, 0, 8, 3932229, 0, 8, 3866693, 0, 8, 3801157, 0, 8, 3735621, 0, 8, 3670085, 0, 8, 3604549, 0, 8, 3539013, 0, 8, 3473477, 0, 8, 3407941, 0, 8, 3342405, 0, 8, 3276869, 0, 8, 3211333, 0, 8, 3145797, 0, 8, 3080261, 0, 8, 4915268, 0, 8, 4849732, 0, 8, 4784196, 0, 8, 4718660, 0, 8, 4653124, 0, 8, 4587588, 0, 8, 4522052, 0, 8, 4456516, 0, 8, 4390980, 0, 8, 4325444, 0, 8, 4259908, 0, 8, 4194372, 0, 8, 4128836, 0, 8, 4063300, 0, 8, 3997764, 0, 8, 3932228, 0, 8, 3866692, 0, 8, 3801156, 0, 8, 3735620, 0, 8, 3670084, 0, 8, 3604548, 0, 8, 3539012, 0, 8, 3473476, 0, 8, 3407940, 0, 8, 3342404, 0, 8, 3276868, 0, 8, 3211332, 0, 8, 3145796, 0, 8, 3080260, 0, 8, 4915267, 0, 8, 4849731, 0, 8, 4784195, 0, 8, 4718659, 0, 8, 4653123, 0, 8, 4587587, 0, 8, 4522051, 0, 8, 4456515, 0, 8, 4390979, 0, 8, 4325443, 0, 8, 4259907, 0, 8, 4194371, 0, 8, 4128835, 0, 8, 4063299, 0, 8, 3997763, 0, 8, 3932227, 0, 8, 3866691, 0, 8, 3801155, 0, 8, 3735619, 0, 8, 3670083, 0, 8, 3604547, 0, 8, 3539011, 0, 8, 3473475, 0, 8, 3407939, 0, 8, 3342403, 0, 8, 3276867, 0, 8, 3211331, 0, 8, 3145795, 0, 8, 3080259, 0, 8, 4915266, 0, 8, 4849730, 0, 8, 4784194, 0, 8, 4718658, 0, 8, 4653122, 0, 8, 4587586, 0, 8, 4522050, 0, 8, 4456514, 0, 8, 4390978, 0, 8, 4325442, 0, 8, 4259906, 0, 8, 4194370, 0, 8, 4128834, 0, 8, 4063298, 0, 8, 3997762, 0, 8, 3932226, 0, 8, 3866690, 0, 8, 3801154, 0, 8, 3735618, 0, 8, 3670082, 0, 8, 3604546, 0, 8, 3539010, 0, 8, 3473474, 0, 8, 3407938, 0, 8, 3342402, 0, 8, 3276866, 0, 8, 3211330, 0, 8, 3145794, 0, 8, 3080258, 0, 8, 4915265, 0, 8, 4849729, 0, 8, 4784193, 0, 8, 4718657, 0, 8, 4653121, 0, 8, 4587585, 0, 8, 4522049, 0, 8, 4456513, 0, 8, 4390977, 0, 8, 4325441, 0, 8, 4259905, 0, 8, 4194369, 0, 8, 4128833, 0, 8, 4063297, 0, 8, 3997761, 0, 8, 3932225, 0, 8, 3866689, 0, 8, 3801153, 0, 8, 3735617, 0, 8, 3670081, 0, 8, 3604545, 0, 8, 3539009, 0, 8, 3473473, 0, 8, 3407937, 0, 8, 3342401, 0, 8, 3276865, 0, 8, 3211329, 0, 8, 3145793, 0, 8, 3080257, 0, 8, 4915264, 0, 8, 4849728, 0, 8, 4784192, 0, 8, 4718656, 0, 8, 4653120, 0, 8, 4587584, 0, 8, 4522048, 0, 8, 4456512, 0, 8, 4390976, 0, 8, 4325440, 0, 8, 4259904, 0, 8, 4194368, 0, 8, 4128832, 0, 8, 4063296, 0, 8, 3997760, 0, 8, 3932224, 0, 8, 3866688, 0, 8, 3801152, 0, 8, 3735616, 0, 8, 3670080, 0, 8, 3604544, 0, 8, 3539008, 0, 8, 3473472, 0, 8, 3407936, 0, 8, 3342400, 0, 8, 3276864, 0, 8, 3211328, 0, 8, 3145792, 0, 8, 3080256, 0, 8, 4915263, 0, 8, 4849727, 0, 8, 4784191, 0, 8, 4718655, 0, 8, 4653119, 0, 8, 4587583, 0, 8, 4522047, 0, 8, 4456511, 0, 8, 4390975, 0, 8, 4325439, 0, 8, 4259903, 0, 8, 4194367, 0, 8, 4128831, 0, 8, 4063295, 0, 8, 3997759, 0, 8, 3932223, 0, 8, 3866687, 0, 8, 3801151, 0, 8, 3735615, 0, 8, 3670079, 0, 8, 3604543, 0, 8, 3539007, 0, 8, 3473471, 0, 8, 3407935, 0, 8, 3342399, 0, 8, 3276863, 0, 8, 3211327, 0, 8, 3145791, 0, 8, 3080255, 0, 8, 4915262, 0, 8, 4849726, 0, 8, 4784190, 0, 8, 4718654, 0, 8, 4653118, 0, 8, 4587582, 0, 8, 4522046, 0, 8, 4456510, 0, 8, 4390974, 0, 8, 4325438, 0, 8, 4259902, 0, 8, 4194366, 0, 8, 4128830, 0, 8, 4063294, 0, 8, 3997758, 0, 8, 3932222, 0, 8, 3866686, 0, 8, 3801150, 0, 8, 3735614, 0, 8, 3670078, 0, 8, 3604542, 0, 8, 3539006, 0, 8, 3473470, 0, 8, 3407934, 0, 8, 3342398, 0, 8, 3276862, 0, 8, 3211326, 0, 8, 3145790, 0, 8, 3080254, 0, 8, 4915261, 0, 8, 4849725, 0, 8, 4784189, 0, 8, 4718653, 0, 8, 4653117, 0, 8, 4587581, 0, 8, 4522045, 0, 8, 4456509, 0, 8, 4390973, 0, 8, 4325437, 0, 8, 4259901, 0, 8, 4194365, 0, 8, 4128829, 0, 8, 4063293, 0, 8, 3997757, 0, 8, 3932221, 0, 8, 3866685, 0, 8, 3801149, 0, 8, 3735613, 0, 8, 3670077, 0, 8, 3604541, 0, 8, 3539005, 0, 8, 3473469, 0, 8, 3407933, 0, 8, 3342397, 0, 8, 3276861, 0, 8, 3211325, 0, 8, 3145789, 0, 8, 3080253, 0, 8, 4915260, 0, 8, 4849724, 0, 8, 4784188, 0, 8, 4718652, 0, 8, 4653116, 0, 8, 4587580, 0, 8, 4522044, 0, 8, 4456508, 0, 8, 4390972, 0, 8, 4325436, 0, 8, 4259900, 0, 8, 4194364, 0, 8, 4128828, 0, 8, 4063292, 0, 8, 3997756, 0, 8, 3932220, 0, 8, 3866684, 0, 8, 3801148, 0, 8, 3735612, 0, 8, 3670076, 0, 8, 3604540, 0, 8, 3539004, 0, 8, 3473468, 0, 8, 3407932, 0, 8, 3342396, 0, 8, 3276860, 0, 8, 3211324, 0, 8, 3145788, 0, 8, 3080252, 0, 8, 4915259, 0, 8, 4849723, 0, 8, 4784187, 0, 8, 4718651, 0, 8, 4653115, 0, 8, 4587579, 0, 8, 4522043, 0, 8, 4456507, 0, 8, 4390971, 0, 8, 4325435, 0, 8, 4259899, 0, 8, 4194363, 0, 8, 4128827, 0, 8, 4063291, 0, 8, 3997755, 0, 8, 3932219, 0, 8, 3866683, 0, 8, 3801147, 0, 8, 3735611, 0, 8, 3670075, 0, 8, 3604539, 0, 8, 3539003, 0, 8, 3473467, 0, 8, 3407931, 0, 8, 3342395, 0, 8, 3276859, 0, 8, 3211323, 0, 8, 3145787, 0, 8, 3080251, 0, 8, 3080250, 196608, 3, 3145786, 196608, 3, 3211322, 196608, 3, 3276858, 196608, 3, 3342394, 196608, 3, 3407930, 196608, 3, 3473466, 196608, 3, 3539002, 196608, 3, 3604538, 196608, 3, 3670074, 196608, 3, 3735610, 196608, 3, 3801146, 196608, 3, 3866682, 196608, 3, 3932218, 196608, 3, 3997754, 196608, 3, 4063290, 196608, 3, 4128826, 196608, 3, 4194362, 196608, 3, 4259898, 196608, 3, 4325434, 196608, 3, 4390970, 196608, 3, 4456506, 196608, 3, 4522042, 196608, 3, 4587578, 196608, 3, 4653114, 196608, 3, 4718650, 196608, 7, 4784186, 0, 8, 4849722, 0, 8, 4915258, 0, 8, 4980796, 0, 8, 4980794, 0, 8, 4980797, 0, 8, 4980795, 0, 8, 4980798, 0, 8, 4980799, 0, 8, 4980800, 0, 8, 4980801, 0, 8, 4980802, 65536, 2, 4980803, 131072, 2, 4980804, 131072, 2, 4980805, 131072, 2, 4980806, 131072, 2, 2687047, 131072, 7, 4980807, 131072, 2, 2687048, 131072, 7, 4980808, 131072, 2, 2687049, 131072, 7, 4980809, 131072, 2, 2687050, 131072, 7, 4980810, 131072, 2, 2687051, 131072, 7, 4980811, 131072, 2, 2687052, 131072, 7, 4980812, 131072, 2, 2687053, 131072, 7, 4980813, 131072, 2, 2687054, 131072, 7, 4980814, 196608, 2, 2687055, 131072, 7, 4980815, 0, 8, 2687056, 131072, 7, 4980816, 0, 8, 2687057, 131072, 7, 4980817, 0, 8, 2687058, 131072, 7, 4980818, 0, 8, 2687059, 131072, 7, 4980819, 0, 8, 2687060, 131072, 7, 4980820, 0, 8, 2687061, 196608, 7, 4980821, 0, 8, 2687062, 0, 8, 4980822, 0, 8, 2687063, 0, 8, 4980823, 0, 8, 2687064, 0, 8, 4980824, 0, 8, 2818137, 0, 8, 2687065, 0, 8, 2883673, 0, 8, 2752601, 0, 8, 2949209, 0, 8, 3014745, 0, 8, 3080281, 0, 8, 3145817, 0, 8, 3211353, 0, 8, 3276889, 0, 8, 3342425, 0, 8, 3407961, 0, 8, 3473497, 0, 8, 3539033, 0, 8, 3604569, 0, 8, 4522073, 0, 8, 4587609, 0, 8, 4653145, 0, 8, 4718681, 0, 8, 4784217, 0, 8, 4849753, 0, 8, 4915289, 0, 8, 4980825, 0, 8, 589888, 196608, 4, 589890, 0, 8, 589889, 196608, 7, 589891, 0, 8, 1376353, 0, 8, 1310817, 0, 8, 1245281, 0, 8, 1179745, 0, 8, 1114209, 0, 8, 1048673, 0, 8, 983137, 0, 8, 917601, 0, 8, 852065, 0, 8, 786529, 0, 8, 720993, 0, 8, 655457, 0, 8, 589921, 0, 8, 524385, 0, 8, 458849, 0, 8, 393313, 0, 8, 327777, 0, 8, 262241, 0, 8, 196705, 0, 8, 131169, 0, 8, 1376352, 0, 8, 1310816, 0, 8, 1245280, 0, 8, 1179744, 0, 8, 1114208, 0, 8, 1048672, 0, 8, 983136, 0, 8, 917600, 0, 8, 852064, 0, 8, 786528, 0, 8, 720992, 0, 8, 655456, 0, 8, 589920, 0, 8, 524384, 0, 8, 458848, 0, 8, 393312, 0, 8, 327776, 0, 8, 262240, 0, 8, 196704, 0, 8, 131168, 0, 8, 1376351, 0, 8, 1310815, 0, 8, 1245279, 0, 8, 1179743, 0, 8, 1114207, 0, 8, 1048671, 0, 8, 983135, 0, 8, 917599, 0, 8, 852063, 0, 8, 786527, 0, 8, 720991, 0, 8, 655455, 0, 8, 589919, 0, 8, 524383, 0, 8, 458847, 0, 8, 393311, 0, 8, 327775, 0, 8, 262239, 0, 8, 196703, 0, 8, 131167, 0, 8, 1376350, 0, 8, 1310814, 0, 8, 1245278, 0, 8, 1179742, 0, 8, 1114206, 0, 8, 1048670, 0, 8, 983134, 0, 8, 917598, 0, 8, 852062, 0, 8, 786526, 0, 8, 720990, 0, 8, 655454, 0, 8, 589918, 0, 8, 524382, 0, 8, 458846, 0, 8, 393310, 0, 8, 327774, 0, 8, 262238, 0, 8, 196702, 0, 8, 131166, 0, 8, 1376349, 0, 8, 1310813, 0, 8, 1245277, 0, 8, 1179741, 0, 8, 1114205, 0, 8, 1048669, 0, 8, 983133, 0, 8, 917597, 0, 8, 852061, 0, 8, 786525, 0, 8, 720989, 0, 8, 655453, 0, 8, 589917, 0, 8, 524381, 0, 8, 458845, 0, 8, 393309, 0, 8, 327773, 0, 8, 262237, 0, 8, 196701, 0, 8, 131165, 0, 8, 1376348, 0, 8, 1310812, 0, 8, 1245276, 0, 8, 1179740, 0, 8, 1114204, 0, 8, 1048668, 0, 8, 983132, 0, 8, 917596, 0, 8, 852060, 0, 8, 786524, 0, 8, 720988, 0, 8, 655452, 0, 8, 589916, 0, 8, 524380, 0, 8, 458844, 0, 8, 393308, 0, 8, 327772, 0, 8, 262236, 0, 8, 196700, 0, 8, 131164, 0, 8, 1376347, 0, 8, 1310811, 0, 8, 1245275, 0, 8, 1179739, 0, 8, 1114203, 0, 8, 1048667, 0, 8, 983131, 0, 8, 917595, 0, 8, 852059, 0, 8, 786523, 0, 8, 720987, 0, 8, 655451, 0, 8, 589915, 0, 8, 524379, 0, 8, 458843, 0, 8, 393307, 0, 8, 327771, 0, 8, 262235, 0, 8, 196699, 0, 8, 131163, 0, 8, 1376346, 0, 8, 1310810, 0, 8, 1245274, 0, 8, 1179738, 0, 8, 1114202, 0, 8, 1048666, 0, 8, 983130, 0, 8, 917594, 0, 8, 852058, 0, 8, 786522, 0, 8, 720986, 0, 8, 655450, 0, 8, 589914, 0, 8, 524378, 0, 8, 458842, 0, 8, 393306, 0, 8, 327770, 0, 8, 262234, 0, 8, 196698, 0, 8, 131162, 0, 8, 1376345, 0, 8, 1310809, 0, 8, 1245273, 0, 8, 1179737, 0, 8, 1114201, 0, 8, 1048665, 0, 8, 983129, 0, 8, 917593, 0, 8, 852057, 0, 8, 786521, 0, 8, 720985, 0, 8, 655449, 0, 8, 589913, 0, 8, 524377, 0, 8, 458841, 0, 8, 393305, 0, 8, 327769, 0, 8, 262233, 0, 8, 196697, 0, 8, 131161, 0, 8, 1376344, 0, 8, 1310808, 0, 8, 1245272, 0, 8, 1179736, 0, 8, 1114200, 0, 8, 1048664, 0, 8, 983128, 0, 8, 917592, 0, 8, 852056, 0, 8, 786520, 0, 8, 720984, 0, 8, 655448, 0, 8, 589912, 0, 8, 524376, 0, 8, 458840, 0, 8, 393304, 0, 8, 327768, 0, 8, 262232, 0, 8, 196696, 0, 8, 131160, 0, 8, 1376343, 0, 8, 1310807, 0, 8, 1245271, 0, 8, 1179735, 0, 8, 1114199, 0, 8, 1048663, 0, 8, 983127, 0, 8, 917591, 0, 8, 852055, 0, 8, 786519, 0, 8, 720983, 0, 8, 655447, 0, 8, 589911, 0, 8, 524375, 0, 8, 458839, 0, 8, 393303, 0, 8, 327767, 0, 8, 262231, 0, 8, 196695, 0, 8, 131159, 0, 8, 1376342, 0, 8, 1310806, 0, 8, 1245270, 0, 8, 1179734, 0, 8, 1114198, 0, 8, 1048662, 0, 8, 983126, 0, 8, 917590, 0, 8, 852054, 0, 8, 786518, 0, 8, 720982, 0, 8, 655446, 0, 8, 589910, 0, 8, 524374, 0, 8, 458838, 0, 8, 393302, 0, 8, 327766, 0, 8, 262230, 0, 8, 196694, 0, 8, 131158, 0, 8, 1376341, 0, 8, 1310805, 0, 8, 1245269, 0, 8, 1179733, 0, 8, 1114197, 0, 8, 1048661, 0, 8, 983125, 0, 8, 917589, 0, 8, 852053, 0, 8, 786517, 0, 8, 720981, 0, 8, 655445, 0, 8, 589909, 0, 8, 524373, 0, 8, 458837, 0, 8, 393301, 0, 8, 327765, 0, 8, 262229, 0, 8, 196693, 0, 8, 131157, 0, 8, 1376340, 0, 8, 1310804, 0, 8, 1245268, 0, 8, 1179732, 0, 8, 1114196, 0, 8, 1048660, 0, 8, 983124, 0, 8, 917588, 0, 8, 852052, 0, 8, 786516, 0, 8, 720980, 0, 8, 655444, 0, 8, 589908, 0, 8, 524372, 0, 8, 458836, 0, 8, 393300, 0, 8, 327764, 0, 8, 262228, 0, 8, 196692, 0, 8, 131156, 0, 8, 1376339, 0, 8, 1310803, 0, 8, 1245267, 0, 8, 1179731, 0, 8, 1114195, 0, 8, 1048659, 0, 8, 983123, 0, 8, 917587, 0, 8, 852051, 0, 8, 786515, 0, 8, 720979, 0, 8, 655443, 0, 8, 589907, 0, 8, 524371, 0, 8, 458835, 0, 8, 393299, 0, 8, 327763, 0, 8, 262227, 0, 8, 196691, 0, 8, 131155, 0, 8, 1376338, 0, 8, 1310802, 0, 8, 1245266, 0, 8, 1179730, 0, 8, 1114194, 0, 8, 1048658, 0, 8, 983122, 0, 8, 917586, 0, 8, 852050, 0, 8, 786514, 0, 8, 720978, 0, 8, 655442, 0, 8, 589906, 0, 8, 524370, 0, 8, 458834, 0, 8, 393298, 0, 8, 327762, 0, 8, 262226, 0, 8, 196690, 0, 8, 131154, 0, 8, 1376337, 0, 8, 1310801, 0, 8, 1245265, 0, 8, 1179729, 0, 8, 1114193, 0, 8, 1048657, 0, 8, 983121, 0, 8, 917585, 0, 8, 852049, 0, 8, 786513, 0, 8, 720977, 0, 8, 655441, 0, 8, 589905, 0, 8, 524369, 0, 8, 458833, 0, 8, 393297, 0, 8, 327761, 0, 8, 262225, 0, 8, 196689, 0, 8, 131153, 0, 8, 1376336, 0, 8, 1310800, 0, 8, 1245264, 0, 8, 1179728, 0, 8, 1114192, 0, 8, 1048656, 0, 8, 983120, 0, 8, 917584, 0, 8, 852048, 0, 8, 786512, 0, 8, 720976, 0, 8, 655440, 0, 8, 589904, 0, 8, 524368, 0, 8, 458832, 0, 8, 393296, 0, 8, 327760, 0, 8, 262224, 0, 8, 196688, 0, 8, 131152, 0, 8, 1376335, 0, 8, 1310799, 0, 8, 1245263, 0, 8, 1179727, 0, 8, 1114191, 0, 8, 1048655, 0, 8, 983119, 0, 8, 917583, 0, 8, 852047, 0, 8, 786511, 0, 8, 720975, 0, 8, 655439, 0, 8, 589903, 0, 8, 524367, 0, 8, 458831, 0, 8, 393295, 0, 8, 327759, 0, 8, 262223, 0, 8, 196687, 0, 8, 131151, 0, 8, 1376334, 0, 8, 1310798, 0, 8, 1245262, 0, 8, 1179726, 0, 8, 1114190, 0, 8, 1048654, 0, 8, 983118, 0, 8, 917582, 0, 8, 852046, 0, 8, 786510, 0, 8, 720974, 0, 8, 655438, 0, 8, 589902, 0, 8, 524366, 0, 8, 458830, 0, 8, 393294, 0, 8, 327758, 0, 8, 262222, 0, 8, 196686, 0, 8, 131150, 0, 8, 1376333, 0, 8, 1310797, 0, 8, 1245261, 0, 8, 1179725, 0, 8, 1114189, 0, 8, 1048653, 0, 8, 983117, 0, 8, 917581, 0, 8, 852045, 0, 8, 786509, 0, 8, 720973, 0, 8, 655437, 0, 8, 589901, 0, 8, 524365, 0, 8, 458829, 0, 8, 393293, 0, 8, 327757, 0, 8, 262221, 0, 8, 196685, 0, 8, 131149, 0, 8, 1376332, 0, 8, 1310796, 0, 8, 1245260, 0, 8, 1179724, 0, 8, 1114188, 0, 8, 1048652, 0, 8, 983116, 0, 8, 917580, 0, 8, 852044, 0, 8, 786508, 0, 8, 720972, 0, 8, 655436, 0, 8, 589900, 0, 8, 524364, 0, 8, 458828, 0, 8, 393292, 0, 8, 327756, 0, 8, 262220, 0, 8, 196684, 0, 8, 131148, 0, 8, 1376331, 0, 8, 1310795, 0, 8, 1245259, 0, 8, 1179723, 0, 8, 1114187, 0, 8, 1048651, 0, 8, 983115, 0, 8, 917579, 0, 8, 852043, 0, 8, 786507, 0, 8, 720971, 0, 8, 655435, 0, 8, 589899, 0, 8, 524363, 0, 8, 458827, 0, 8, 393291, 0, 8, 327755, 0, 8, 262219, 0, 8, 196683, 0, 8, 131147, 0, 8, 1376330, 0, 8, 1310794, 0, 8, 1245258, 0, 8, 1179722, 0, 8, 1114186, 0, 8, 1048650, 0, 8, 983114, 0, 8, 917578, 0, 8, 852042, 0, 8, 786506, 0, 8, 720970, 0, 8, 655434, 0, 8, 589898, 0, 8, 524362, 0, 8, 458826, 0, 8, 393290, 0, 8, 327754, 0, 8, 262218, 0, 8, 196682, 0, 8, 131146, 0, 8, 1376329, 0, 8, 1310793, 0, 8, 1245257, 0, 8, 1179721, 0, 8, 1114185, 0, 8, 1048649, 0, 8, 983113, 0, 8, 917577, 0, 8, 852041, 0, 8, 786505, 0, 8, 720969, 0, 8, 655433, 0, 8, 589897, 0, 8, 524361, 0, 8, 458825, 0, 8, 393289, 0, 8, 327753, 0, 8, 262217, 0, 8, 196681, 0, 8, 131145, 0, 8, 1376328, 0, 8, 1310792, 0, 8, 1245256, 0, 8, 1179720, 0, 8, 1114184, 0, 8, 1048648, 0, 8, 983112, 0, 8, 917576, 0, 8, 852040, 0, 8, 786504, 0, 8, 720968, 0, 8, 655432, 0, 8, 589896, 0, 8, 524360, 0, 8, 458824, 0, 8, 393288, 0, 8, 327752, 0, 8, 262216, 0, 8, 196680, 0, 8, 131144, 0, 8, 1376327, 0, 8, 1310791, 0, 8, 1245255, 0, 8, 1179719, 0, 8, 1114183, 0, 8, 1048647, 0, 8, 983111, 0, 8, 917575, 0, 8, 852039, 0, 8, 786503, 0, 8, 720967, 0, 8, 655431, 0, 8, 589895, 0, 8, 524359, 0, 8, 458823, 0, 8, 393287, 0, 8, 327751, 0, 8, 262215, 0, 8, 196679, 0, 8, 131143, 0, 8, 589894, 0, 8, 524358, 0, 8, 458822, 0, 8, 393286, 0, 8, 327750, 0, 8, 262214, 0, 8, 196678, 0, 8, 131142, 0, 8, 589893, 0, 8, 524357, 0, 8, 458821, 0, 8, 393285, 0, 8, 327749, 0, 8, 262213, 0, 8, 196677, 0, 8, 131141, 0, 8, 589892, 0, 8, 524356, 0, 8, 458820, 0, 8, 393284, 0, 8, 327748, 0, 8, 262212, 0, 8, 196676, 0, 8, 131140, 0, 8, 524355, 0, 8, 458819, 0, 8, 393283, 0, 8, 327747, 0, 8, 262211, 0, 8, 196675, 0, 8, 131139, 0, 8, 524354, 0, 8, 458818, 0, 8, 393282, 0, 8, 327746, 0, 8, 262210, 0, 8, 196674, 0, 8, 131138, 0, 8, 196673, 196608, 3, 65601, 196608, 4, 65603, 131072, 7, 262209, 196608, 3, 131137, 196608, 3, 327745, 196608, 3, 393281, 196608, 3, 458817, 196608, 3, 524353, 196608, 3, 65602, 131072, 7, 65604, 131072, 7, 65605, 131072, 7, 65606, 131072, 7, 65607, 131072, 7, 1441863, 131072, 2, 65608, 131072, 7, 1441864, 131072, 2, 65609, 131072, 7, 1441865, 131072, 2, 65610, 131072, 7, 1441866, 131072, 2, 65611, 131072, 7, 1441867, 131072, 2, 65612, 131072, 7, 1441868, 131072, 2, 65613, 131072, 7, 1441869, 131072, 2, 65614, 131072, 7, 1441870, 131072, 2, 65615, 131072, 7, 1441871, 131072, 2, 65616, 131072, 7, 1441872, 131072, 2, 65617, 131072, 7, 1441873, 131072, 2, 65618, 131072, 7, 1441874, 131072, 2, 65619, 131072, 7, 1441875, 131072, 2, 65620, 131072, 7, 1441876, 131072, 2, 65621, 131072, 7, 1441877, 196608, 2, 65622, 131072, 7, 1441878, 0, 8, 65623, 131072, 7, 1441879, 0, 8, 65624, 131072, 7, 1441880, 0, 8, 65625, 131072, 7, 1441881, 0, 8, 65626, 131072, 7, 1441882, 0, 8, 65627, 131072, 7, 1441883, 0, 8, 65628, 131072, 7, 1441884, 0, 8, 65629, 131072, 7, 1441885, 0, 8, 65630, 131072, 7, 1441886, 0, 8, 65631, 131072, 7, 1441887, 0, 8, 65632, 131072, 7, 1441888, 0, 8, 65633, 131072, 7, 1441889, 0, 8, 196706, 65536, 3, 65634, 65536, 4, 262242, 65536, 3, 131170, 65536, 3, 327778, 65536, 3, 393314, 65536, 3, 458850, 65536, 3, 524386, 65536, 3, 589922, 65536, 3, 655458, 65536, 3, 720994, 65536, 3, 786530, 65536, 3, 852066, 65536, 7, 917602, 0, 8, 983138, 0, 8, 1048674, 0, 8, 1114210, 0, 8, 1179746, 0, 8, 1245282, 0, 8, 1310818, 0, 8, 1376354, 0, 8, 1441890, 0, 8, 3539069, 0, 8, 3473533, 0, 8, 3407997, 0, 8, 3342461, 0, 8, 3276925, 0, 8, 3211389, 0, 8, 3145853, 0, 8, 3080317, 0, 8, 3014781, 0, 8, 2949245, 0, 8, 2883709, 0, 8, 2818173, 0, 8, 2752637, 0, 8, 2687101, 0, 8, 2621565, 0, 8, 2556029, 0, 8, 2490493, 0, 8, 2424957, 0, 8, 2359421, 0, 8, 2293885, 0, 8, 2228349, 0, 8, 2162813, 0, 8, 2097277, 0, 8, 2031741, 0, 8, 1966205, 0, 8, 1900669, 0, 8, 1835133, 0, 8, 1769597, 0, 8, 1704061, 0, 8, 1638525, 0, 8, 1572989, 0, 8, 1507453, 0, 8, 1441917, 0, 8, 1376381, 0, 8, 1310845, 0, 8, 1245309, 0, 8, 1179773, 0, 8, 1114237, 0, 8, 1048701, 0, 8, 983165, 0, 8, 917629, 0, 8, 3539068, 0, 8, 3473532, 0, 8, 3407996, 0, 8, 3342460, 0, 8, 3276924, 0, 8, 3211388, 0, 8, 3145852, 0, 8, 3080316, 0, 8, 3014780, 0, 8, 2949244, 0, 8, 2883708, 0, 8, 2818172, 0, 8, 2752636, 0, 8, 2687100, 0, 8, 2621564, 0, 8, 2556028, 0, 8, 2490492, 0, 8, 2424956, 0, 8, 2359420, 0, 8, 2293884, 0, 8, 2228348, 0, 8, 2162812, 0, 8, 2097276, 0, 8, 2031740, 0, 8, 1966204, 0, 8, 1900668, 0, 8, 1835132, 0, 8, 1769596, 0, 8, 1704060, 0, 8, 1638524, 0, 8, 1572988, 0, 8, 1507452, 0, 8, 1441916, 0, 8, 1376380, 0, 8, 1310844, 0, 8, 1245308, 0, 8, 1179772, 0, 8, 1114236, 0, 8, 1048700, 0, 8, 983164, 0, 8, 917628, 0, 8, 3539067, 0, 8, 3473531, 0, 8, 3407995, 0, 8, 3342459, 0, 8, 3276923, 0, 8, 3211387, 0, 8, 3145851, 0, 8, 3080315, 0, 8, 3014779, 0, 8, 2949243, 0, 8, 2883707, 0, 8, 2818171, 0, 8, 2752635, 0, 8, 2687099, 0, 8, 2621563, 0, 8, 2556027, 0, 8, 2490491, 0, 8, 2424955, 0, 8, 2359419, 0, 8, 2293883, 0, 8, 2228347, 0, 8, 2162811, 0, 8, 2097275, 0, 8, 2031739, 0, 8, 1966203, 0, 8, 1900667, 0, 8, 1835131, 0, 8, 1769595, 0, 8, 1704059, 0, 8, 1638523, 0, 8, 1572987, 0, 8, 1507451, 0, 8, 1441915, 0, 8, 1376379, 0, 8, 1310843, 0, 8, 1245307, 0, 8, 1179771, 0, 8, 1114235, 0, 8, 1048699, 0, 8, 983163, 0, 8, 917627, 0, 8, 3539066, 0, 8, 3473530, 0, 8, 3407994, 0, 8, 3342458, 0, 8, 3276922, 0, 8, 3211386, 0, 8, 3145850, 0, 8, 3080314, 0, 8, 3014778, 0, 8, 2949242, 0, 8, 2883706, 0, 8, 2818170, 0, 8, 2752634, 0, 8, 2687098, 0, 8, 2621562, 0, 8, 2556026, 0, 8, 2490490, 0, 8, 2424954, 0, 8, 2359418, 0, 8, 2293882, 0, 8, 2228346, 0, 8, 2162810, 0, 8, 2097274, 0, 8, 2031738, 0, 8, 1966202, 0, 8, 1900666, 0, 8, 1835130, 0, 8, 1769594, 0, 8, 1704058, 0, 8, 1638522, 0, 8, 1572986, 0, 8, 1507450, 0, 8, 1441914, 0, 8, 1376378, 0, 8, 1310842, 0, 8, 1245306, 0, 8, 1179770, 0, 8, 1114234, 0, 8, 1048698, 0, 8, 983162, 0, 8, 917626, 0, 8, 3539065, 0, 8, 3473529, 0, 8, 3407993, 0, 8, 3342457, 0, 8, 3276921, 0, 8, 3211385, 0, 8, 3145849, 0, 8, 3080313, 0, 8, 3014777, 0, 8, 2949241, 0, 8, 2883705, 0, 8, 2818169, 0, 8, 2752633, 0, 8, 2687097, 0, 8, 2621561, 0, 8, 2556025, 0, 8, 2490489, 0, 8, 2424953, 0, 8, 2359417, 0, 8, 2293881, 0, 8, 2228345, 0, 8, 2162809, 0, 8, 2097273, 0, 8, 2031737, 0, 8, 1966201, 0, 8, 1900665, 0, 8, 1835129, 0, 8, 1769593, 0, 8, 1704057, 0, 8, 1638521, 0, 8, 1572985, 0, 8, 1507449, 0, 8, 1441913, 0, 8, 1376377, 0, 8, 1310841, 0, 8, 1245305, 0, 8, 1179769, 0, 8, 1114233, 0, 8, 1048697, 0, 8, 983161, 0, 8, 917625, 0, 8, 3539064, 0, 8, 3473528, 0, 8, 3407992, 0, 8, 3342456, 0, 8, 3276920, 0, 8, 3211384, 0, 8, 3145848, 0, 8, 3080312, 0, 8, 3014776, 0, 8, 2949240, 0, 8, 2883704, 0, 8, 2818168, 0, 8, 2752632, 0, 8, 2687096, 0, 8, 2621560, 0, 8, 2556024, 0, 8, 2490488, 0, 8, 2424952, 0, 8, 2359416, 0, 8, 2293880, 0, 8, 2228344, 0, 8, 2162808, 0, 8, 2097272, 0, 8, 2031736, 0, 8, 1966200, 0, 8, 1900664, 0, 8, 1835128, 0, 8, 1769592, 0, 8, 1704056, 0, 8, 1638520, 0, 8, 1572984, 0, 8, 1507448, 0, 8, 1441912, 0, 8, 1376376, 0, 8, 1310840, 0, 8, 1245304, 0, 8, 1179768, 0, 8, 1114232, 0, 8, 1048696, 0, 8, 983160, 0, 8, 917624, 0, 8, 3539063, 0, 8, 3473527, 0, 8, 3407991, 0, 8, 3342455, 0, 8, 3276919, 0, 8, 3211383, 0, 8, 3145847, 0, 8, 3080311, 0, 8, 3014775, 0, 8, 2949239, 0, 8, 2883703, 0, 8, 2818167, 0, 8, 2752631, 0, 8, 2687095, 0, 8, 2621559, 0, 8, 2556023, 0, 8, 2490487, 0, 8, 2424951, 0, 8, 2359415, 0, 8, 2293879, 0, 8, 2228343, 0, 8, 2162807, 0, 8, 2097271, 0, 8, 2031735, 0, 8, 1966199, 0, 8, 1900663, 0, 8, 1835127, 0, 8, 1769591, 0, 8, 1704055, 0, 8, 1638519, 0, 8, 1572983, 0, 8, 1507447, 0, 8, 1441911, 0, 8, 1376375, 0, 8, 1310839, 0, 8, 1245303, 0, 8, 1179767, 0, 8, 1114231, 0, 8, 1048695, 0, 8, 983159, 0, 8, 917623, 0, 8, 3539062, 0, 8, 3473526, 0, 8, 3407990, 0, 8, 3342454, 0, 8, 3276918, 0, 8, 3211382, 0, 8, 3145846, 0, 8, 3080310, 0, 8, 3014774, 0, 8, 2949238, 0, 8, 2883702, 0, 8, 2818166, 0, 8, 2752630, 0, 8, 2687094, 0, 8, 2621558, 0, 8, 2556022, 0, 8, 2490486, 0, 8, 2424950, 0, 8, 2359414, 0, 8, 2293878, 0, 8, 2228342, 0, 8, 2162806, 0, 8, 2097270, 0, 8, 2031734, 0, 8, 1966198, 0, 8, 1900662, 0, 8, 1835126, 0, 8, 1769590, 0, 8, 1704054, 0, 8, 1638518, 0, 8, 1572982, 0, 8, 1507446, 0, 8, 1441910, 0, 8, 1376374, 0, 8, 1310838, 0, 8, 1245302, 0, 8, 1179766, 0, 8, 1114230, 0, 8, 1048694, 0, 8, 983158, 0, 8, 917622, 0, 8, 3539061, 0, 8, 3473525, 0, 8, 3407989, 0, 8, 3342453, 0, 8, 3276917, 0, 8, 3211381, 0, 8, 3145845, 0, 8, 3080309, 0, 8, 3014773, 0, 8, 2949237, 0, 8, 2883701, 0, 8, 2818165, 0, 8, 2752629, 0, 8, 2687093, 0, 8, 2621557, 0, 8, 2556021, 0, 8, 2490485, 0, 8, 2424949, 0, 8, 2359413, 0, 8, 2293877, 0, 8, 2228341, 0, 8, 2162805, 0, 8, 2097269, 0, 8, 2031733, 0, 8, 1966197, 0, 8, 1900661, 0, 8, 1835125, 0, 8, 1769589, 0, 8, 1704053, 0, 8, 1638517, 0, 8, 1572981, 0, 8, 1507445, 0, 8, 1441909, 0, 8, 1376373, 0, 8, 1310837, 0, 8, 1245301, 0, 8, 1179765, 0, 8, 1114229, 0, 8, 1048693, 0, 8, 983157, 0, 8, 917621, 0, 8, 3539060, 0, 8, 3473524, 0, 8, 3407988, 0, 8, 3342452, 0, 8, 3276916, 0, 8, 3211380, 0, 8, 3145844, 0, 8, 3080308, 0, 8, 3014772, 0, 8, 2949236, 0, 8, 2883700, 0, 8, 2818164, 0, 8, 2752628, 0, 8, 2687092, 0, 8, 2621556, 0, 8, 2556020, 0, 8, 2490484, 0, 8, 2424948, 0, 8, 2359412, 0, 8, 2293876, 0, 8, 2228340, 0, 8, 2162804, 0, 8, 2097268, 0, 8, 2031732, 0, 8, 1966196, 0, 8, 1900660, 0, 8, 1835124, 0, 8, 1769588, 0, 8, 1704052, 0, 8, 1638516, 0, 8, 1572980, 0, 8, 1507444, 0, 8, 1441908, 0, 8, 1376372, 0, 8, 1310836, 0, 8, 1245300, 0, 8, 1179764, 0, 8, 1114228, 0, 8, 1048692, 0, 8, 983156, 0, 8, 917620, 0, 8, 3539059, 0, 8, 3473523, 0, 8, 3407987, 0, 8, 3342451, 0, 8, 3276915, 0, 8, 3211379, 0, 8, 3145843, 0, 8, 3080307, 0, 8, 3014771, 0, 8, 2949235, 0, 8, 2883699, 0, 8, 2818163, 0, 8, 2752627, 0, 8, 2687091, 0, 8, 2621555, 0, 8, 2556019, 0, 8, 2490483, 0, 8, 2424947, 0, 8, 2359411, 0, 8, 2293875, 0, 8, 2228339, 0, 8, 2162803, 0, 8, 2097267, 0, 8, 2031731, 0, 8, 1966195, 0, 8, 1900659, 0, 8, 1835123, 0, 8, 1769587, 0, 8, 1704051, 0, 8, 1638515, 0, 8, 1572979, 0, 8, 1507443, 0, 8, 1441907, 0, 8, 1376371, 0, 8, 1310835, 0, 8, 1245299, 0, 8, 1179763, 0, 8, 1114227, 0, 8, 1048691, 0, 8, 983155, 0, 8, 917619, 0, 8, 3539058, 0, 8, 3473522, 0, 8, 3407986, 0, 8, 3342450, 0, 8, 3276914, 0, 8, 3211378, 0, 8, 3145842, 0, 8, 3080306, 0, 8, 3014770, 0, 8, 2949234, 0, 8, 2883698, 0, 8, 2818162, 0, 8, 2752626, 0, 8, 2687090, 0, 8, 2621554, 0, 8, 2556018, 0, 8, 2490482, 0, 8, 2424946, 0, 8, 2359410, 0, 8, 2293874, 0, 8, 2228338, 0, 8, 2162802, 0, 8, 2097266, 0, 8, 2031730, 0, 8, 1966194, 0, 8, 1900658, 0, 8, 1835122, 0, 8, 1769586, 0, 8, 1704050, 0, 8, 1638514, 0, 8, 1572978, 0, 8, 1507442, 0, 8, 1441906, 0, 8, 1376370, 0, 8, 1310834, 0, 8, 1245298, 0, 8, 1179762, 0, 8, 1114226, 0, 8, 1048690, 0, 8, 983154, 0, 8, 917618, 0, 8, 3539057, 0, 8, 3473521, 0, 8, 3407985, 0, 8, 3342449, 0, 8, 3276913, 0, 8, 3211377, 0, 8, 3145841, 0, 8, 3080305, 0, 8, 3014769, 0, 8, 2949233, 0, 8, 2883697, 0, 8, 2818161, 0, 8, 2752625, 0, 8, 2687089, 0, 8, 2621553, 0, 8, 2556017, 0, 8, 2490481, 0, 8, 2424945, 0, 8, 2359409, 0, 8, 2293873, 0, 8, 2228337, 0, 8, 2162801, 0, 8, 2097265, 0, 8, 2031729, 0, 8, 1966193, 0, 8, 1900657, 0, 8, 1835121, 0, 8, 1769585, 0, 8, 1704049, 0, 8, 1638513, 0, 8, 1572977, 0, 8, 1507441, 0, 8, 1441905, 0, 8, 1376369, 0, 8, 1310833, 0, 8, 1245297, 0, 8, 1179761, 0, 8, 1114225, 0, 8, 1048689, 0, 8, 983153, 0, 8, 917617, 0, 8, 3539056, 0, 8, 3473520, 0, 8, 3407984, 0, 8, 3342448, 0, 8, 3276912, 0, 8, 3211376, 0, 8, 3145840, 0, 8, 3080304, 0, 8, 3014768, 0, 8, 2949232, 0, 8, 2883696, 0, 8, 2818160, 0, 8, 2752624, 0, 8, 2687088, 0, 8, 2621552, 0, 8, 2556016, 0, 8, 2490480, 0, 8, 2424944, 0, 8, 2359408, 0, 8, 2293872, 0, 8, 2228336, 0, 8, 2162800, 0, 8, 2097264, 0, 8, 2031728, 0, 8, 1966192, 0, 8, 1900656, 0, 8, 1835120, 0, 8, 1769584, 0, 8, 1704048, 0, 8, 1638512, 0, 8, 1572976, 0, 8, 1507440, 0, 8, 1441904, 0, 8, 1376368, 0, 8, 1310832, 0, 8, 1245296, 0, 8, 1179760, 0, 8, 1114224, 0, 8, 1048688, 0, 8, 983152, 0, 8, 917616, 0, 8, 3539055, 0, 8, 3473519, 0, 8, 3407983, 0, 8, 3342447, 0, 8, 3276911, 0, 8, 3211375, 0, 8, 3145839, 0, 8, 3080303, 0, 8, 3014767, 0, 8, 2949231, 0, 8, 2883695, 0, 8, 2818159, 0, 8, 2752623, 0, 8, 2687087, 0, 8, 2621551, 0, 8, 2556015, 0, 8, 2490479, 0, 8, 2424943, 0, 8, 2359407, 0, 8, 2293871, 0, 8, 2228335, 0, 8, 2162799, 0, 8, 2097263, 0, 8, 2031727, 0, 8, 1966191, 0, 8, 1900655, 0, 8, 1835119, 0, 8, 1769583, 0, 8, 1704047, 0, 8, 1638511, 0, 8, 1572975, 0, 8, 1507439, 0, 8, 1441903, 0, 8, 1376367, 0, 8, 1310831, 0, 8, 1245295, 0, 8, 1179759, 0, 8, 1114223, 0, 8, 1048687, 0, 8, 983151, 0, 8, 917615, 0, 8, 3539054, 0, 8, 3473518, 0, 8, 3407982, 0, 8, 3342446, 0, 8, 3276910, 0, 8, 3211374, 0, 8, 3145838, 0, 8, 3080302, 0, 8, 3014766, 0, 8, 2949230, 0, 8, 2883694, 0, 8, 2818158, 0, 8, 2752622, 0, 8, 2687086, 0, 8, 2621550, 0, 8, 2556014, 0, 8, 2490478, 0, 8, 2424942, 0, 8, 2359406, 0, 8, 2293870, 0, 8, 2228334, 0, 8, 2162798, 0, 8, 2097262, 0, 8, 2031726, 0, 8, 1966190, 0, 8, 1900654, 0, 8, 1835118, 0, 8, 1769582, 0, 8, 1704046, 0, 8, 1638510, 0, 8, 1572974, 0, 8, 1507438, 0, 8, 1441902, 0, 8, 1376366, 0, 8, 1310830, 0, 8, 1245294, 0, 8, 1179758, 0, 8, 1114222, 0, 8, 1048686, 0, 8, 983150, 0, 8, 917614, 0, 8, 3539053, 0, 8, 3473517, 0, 8, 3407981, 0, 8, 3342445, 0, 8, 3276909, 0, 8, 3211373, 0, 8, 3145837, 0, 8, 3080301, 0, 8, 3014765, 0, 8, 2949229, 0, 8, 2883693, 0, 8, 2818157, 0, 8, 2752621, 0, 8, 2687085, 0, 8, 2621549, 0, 8, 2556013, 0, 8, 2490477, 0, 8, 2424941, 0, 8, 2359405, 0, 8, 2293869, 0, 8, 2228333, 0, 8, 2162797, 0, 8, 2097261, 0, 8, 2031725, 0, 8, 1966189, 0, 8, 1900653, 0, 8, 1835117, 0, 8, 1769581, 0, 8, 1704045, 0, 8, 1638509, 0, 8, 1572973, 0, 8, 1507437, 0, 8, 1441901, 0, 8, 1376365, 0, 8, 1310829, 0, 8, 1245293, 0, 8, 1179757, 0, 8, 1114221, 0, 8, 1048685, 0, 8, 983149, 0, 8, 917613, 0, 8, 3539052, 0, 8, 3473516, 0, 8, 3407980, 0, 8, 3342444, 0, 8, 3276908, 0, 8, 3211372, 0, 8, 3145836, 0, 8, 3080300, 0, 8, 3014764, 0, 8, 2949228, 0, 8, 2883692, 0, 8, 2818156, 0, 8, 2752620, 0, 8, 2687084, 0, 8, 2621548, 0, 8, 2556012, 0, 8, 2490476, 0, 8, 2424940, 0, 8, 2359404, 0, 8, 2293868, 0, 8, 2228332, 0, 8, 2162796, 0, 8, 2097260, 0, 8, 2031724, 0, 8, 1966188, 0, 8, 1900652, 0, 8, 1835116, 0, 8, 1769580, 0, 8, 1704044, 0, 8, 1638508, 0, 8, 1572972, 0, 8, 1507436, 0, 8, 1441900, 0, 8, 1376364, 0, 8, 1310828, 0, 8, 1245292, 0, 8, 1179756, 0, 8, 1114220, 0, 8, 1048684, 0, 8, 983148, 0, 8, 917612, 0, 8, 3539051, 0, 8, 3473515, 0, 8, 3407979, 0, 8, 3342443, 0, 8, 3276907, 0, 8, 3211371, 0, 8, 3145835, 0, 8, 3080299, 0, 8, 3014763, 0, 8, 2949227, 0, 8, 2883691, 0, 8, 2818155, 0, 8, 2752619, 0, 8, 2687083, 0, 8, 2621547, 0, 8, 2556011, 0, 8, 2490475, 0, 8, 2424939, 0, 8, 2359403, 0, 8, 2293867, 0, 8, 2228331, 0, 8, 2162795, 0, 8, 2097259, 0, 8, 2031723, 0, 8, 1966187, 0, 8, 1900651, 0, 8, 1835115, 0, 8, 1769579, 0, 8, 1704043, 0, 8, 1638507, 0, 8, 1572971, 0, 8, 1507435, 0, 8, 1441899, 0, 8, 1376363, 0, 8, 1310827, 0, 8, 1245291, 0, 8, 1179755, 0, 8, 1114219, 0, 8, 1048683, 0, 8, 983147, 0, 8, 917611, 0, 8, 3539050, 0, 8, 3473514, 0, 8, 3407978, 0, 8, 3342442, 0, 8, 3276906, 0, 8, 3211370, 0, 8, 3145834, 0, 8, 3080298, 0, 8, 3014762, 0, 8, 2949226, 0, 8, 2883690, 0, 8, 2818154, 0, 8, 2752618, 0, 8, 2687082, 0, 8, 2621546, 0, 8, 2556010, 0, 8, 2490474, 0, 8, 2424938, 0, 8, 2359402, 0, 8, 2293866, 0, 8, 2228330, 0, 8, 2162794, 0, 8, 2097258, 0, 8, 2031722, 0, 8, 1966186, 0, 8, 1900650, 0, 8, 1835114, 0, 8, 1769578, 0, 8, 1704042, 0, 8, 1638506, 0, 8, 1572970, 0, 8, 1507434, 0, 8, 1441898, 0, 8, 1376362, 0, 8, 1310826, 0, 8, 1245290, 0, 8, 1179754, 0, 8, 1114218, 0, 8, 1048682, 0, 8, 983146, 0, 8, 917610, 0, 8, 3539049, 0, 8, 3473513, 0, 8, 3407977, 0, 8, 3342441, 0, 8, 3276905, 0, 8, 3211369, 0, 8, 3145833, 0, 8, 3080297, 0, 8, 3014761, 0, 8, 2949225, 0, 8, 2883689, 0, 8, 2818153, 0, 8, 2752617, 0, 8, 2687081, 0, 8, 2621545, 0, 8, 2556009, 0, 8, 2490473, 0, 8, 2424937, 0, 8, 2359401, 0, 8, 2293865, 0, 8, 2228329, 0, 8, 2162793, 0, 8, 2097257, 0, 8, 2031721, 0, 8, 1966185, 0, 8, 1900649, 0, 8, 1835113, 0, 8, 1769577, 0, 8, 1704041, 0, 8, 1638505, 0, 8, 1572969, 0, 8, 1507433, 0, 8, 1441897, 0, 8, 1376361, 0, 8, 1310825, 0, 8, 1245289, 0, 8, 1179753, 0, 8, 1114217, 0, 8, 1048681, 0, 8, 983145, 0, 8, 917609, 0, 8, 3539048, 0, 8, 3473512, 0, 8, 3407976, 0, 8, 3342440, 0, 8, 3276904, 0, 8, 3211368, 0, 8, 3145832, 0, 8, 3080296, 0, 8, 3014760, 0, 8, 2949224, 0, 8, 2883688, 0, 8, 2818152, 0, 8, 2752616, 0, 8, 2687080, 0, 8, 2621544, 0, 8, 2556008, 0, 8, 2490472, 0, 8, 2424936, 0, 8, 2359400, 0, 8, 2293864, 0, 8, 2228328, 0, 8, 2162792, 0, 8, 2097256, 0, 8, 2031720, 0, 8, 1966184, 0, 8, 1900648, 0, 8, 1835112, 0, 8, 1769576, 0, 8, 1704040, 0, 8, 1638504, 0, 8, 1572968, 0, 8, 1507432, 0, 8, 1441896, 0, 8, 1376360, 0, 8, 1310824, 0, 8, 1245288, 0, 8, 1179752, 0, 8, 1114216, 0, 8, 1048680, 0, 8, 983144, 0, 8, 917608, 0, 8, 3539047, 0, 8, 3473511, 0, 8, 3407975, 0, 8, 3342439, 0, 8, 3276903, 0, 8, 3211367, 0, 8, 3145831, 0, 8, 3080295, 0, 8, 3014759, 0, 8, 2949223, 0, 8, 2883687, 0, 8, 2818151, 0, 8, 2752615, 0, 8, 2687079, 0, 8, 2621543, 0, 8, 2556007, 0, 8, 2490471, 0, 8, 2424935, 0, 8, 2359399, 0, 8, 2293863, 0, 8, 2228327, 0, 8, 2162791, 0, 8, 2097255, 0, 8, 2031719, 0, 8, 1966183, 0, 8, 1900647, 0, 8, 1835111, 0, 8, 1769575, 0, 8, 1704039, 0, 8, 1638503, 0, 8, 1572967, 0, 8, 1507431, 0, 8, 1441895, 0, 8, 1376359, 0, 8, 1310823, 0, 8, 1245287, 0, 8, 1179751, 0, 8, 1114215, 0, 8, 1048679, 0, 8, 983143, 0, 8, 917607, 0, 8, 3539046, 0, 8, 3473510, 0, 8, 3407974, 0, 8, 3342438, 0, 8, 3276902, 0, 8, 3211366, 0, 8, 3145830, 0, 8, 3080294, 0, 8, 3014758, 0, 8, 2949222, 0, 8, 2883686, 0, 8, 2818150, 0, 8, 2752614, 0, 8, 2687078, 0, 8, 2621542, 0, 8, 2556006, 0, 8, 2490470, 0, 8, 2424934, 0, 8, 2359398, 0, 8, 2293862, 0, 8, 2228326, 0, 8, 2162790, 0, 8, 2097254, 0, 8, 2031718, 0, 8, 1966182, 0, 8, 1900646, 0, 8, 1835110, 0, 8, 1769574, 0, 8, 1704038, 0, 8, 1638502, 0, 8, 1572966, 0, 8, 1507430, 0, 8, 1441894, 0, 8, 1376358, 0, 8, 1310822, 0, 8, 1245286, 0, 8, 1179750, 0, 8, 1114214, 0, 8, 1048678, 0, 8, 983142, 0, 8, 917606, 0, 8, 3539045, 0, 8, 3473509, 0, 8, 3407973, 0, 8, 3342437, 0, 8, 3276901, 0, 8, 3211365, 0, 8, 3145829, 0, 8, 3080293, 0, 8, 3014757, 0, 8, 2949221, 0, 8, 2883685, 0, 8, 2818149, 0, 8, 2752613, 0, 8, 2687077, 0, 8, 2621541, 0, 8, 2556005, 0, 8, 2490469, 0, 8, 2424933, 0, 8, 2359397, 0, 8, 2293861, 0, 8, 2228325, 0, 8, 2162789, 0, 8, 2097253, 0, 8, 2031717, 0, 8, 1966181, 0, 8, 1900645, 0, 8, 1835109, 0, 8, 1769573, 0, 8, 1704037, 0, 8, 1638501, 0, 8, 1572965, 0, 8, 1507429, 0, 8, 1441893, 0, 8, 1376357, 0, 8, 1310821, 0, 8, 1245285, 0, 8, 1179749, 0, 8, 1114213, 0, 8, 1048677, 0, 8, 983141, 0, 8, 917605, 0, 8, 3539044, 0, 8, 3473508, 0, 8, 3407972, 0, 8, 3342436, 0, 8, 3276900, 0, 8, 3211364, 0, 8, 3145828, 0, 8, 3080292, 0, 8, 3014756, 0, 8, 2949220, 0, 8, 2883684, 0, 8, 2818148, 0, 8, 2752612, 0, 8, 2687076, 0, 8, 2621540, 0, 8, 2556004, 0, 8, 2490468, 0, 8, 2424932, 0, 8, 2359396, 0, 8, 2293860, 0, 8, 2228324, 0, 8, 2162788, 0, 8, 2097252, 0, 8, 2031716, 0, 8, 1966180, 0, 8, 1900644, 0, 8, 1835108, 0, 8, 1769572, 0, 8, 1704036, 0, 8, 1638500, 0, 8, 1572964, 0, 8, 1507428, 0, 8, 1441892, 0, 8, 1376356, 0, 8, 1310820, 0, 8, 1245284, 0, 8, 1179748, 0, 8, 1114212, 0, 8, 1048676, 0, 8, 983140, 0, 8, 917604, 0, 8, 3539043, 0, 8, 3473507, 0, 8, 3407971, 0, 8, 3342435, 0, 8, 3276899, 0, 8, 3211363, 0, 8, 3145827, 0, 8, 3080291, 0, 8, 3014755, 0, 8, 2949219, 0, 8, 2883683, 0, 8, 2818147, 0, 8, 2752611, 0, 8, 2687075, 0, 8, 2621539, 0, 8, 2556003, 0, 8, 2490467, 0, 8, 2424931, 0, 8, 2359395, 0, 8, 2293859, 0, 8, 2228323, 0, 8, 2162787, 0, 8, 2097251, 0, 8, 2031715, 0, 8, 1966179, 0, 8, 1900643, 0, 8, 1835107, 0, 8, 1769571, 0, 8, 1704035, 0, 8, 1638499, 0, 8, 1572963, 0, 8, 1507427, 0, 8, 1441891, 0, 8, 1376355, 0, 8, 1310819, 0, 8, 1245283, 0, 8, 1179747, 0, 8, 1114211, 0, 8, 1048675, 0, 8, 983139, 0, 8, 917603, 0, 8, 3539042, 0, 8, 3473506, 0, 8, 3407970, 0, 8, 3342434, 0, 8, 3276898, 0, 8, 3211362, 0, 8, 3145826, 0, 8, 3080290, 0, 8, 3014754, 0, 8, 2949218, 0, 8, 2883682, 0, 8, 2818146, 0, 8, 2752610, 0, 8, 2687074, 0, 8, 2621538, 0, 8, 2556002, 0, 8, 2490466, 0, 8, 2424930, 0, 8, 2359394, 0, 8, 2293858, 0, 8, 2228322, 0, 8, 2162786, 0, 8, 2097250, 0, 8, 2031714, 0, 8, 1966178, 0, 8, 1900642, 0, 8, 1835106, 0, 8, 1769570, 0, 8, 1704034, 0, 8, 1638498, 0, 8, 1572962, 0, 8, 1507426, 0, 8, 3539041, 0, 8, 3473505, 0, 8, 3407969, 0, 8, 3342433, 0, 8, 3276897, 0, 8, 3211361, 0, 8, 3145825, 0, 8, 3080289, 0, 8, 3014753, 0, 8, 2949217, 0, 8, 2883681, 0, 8, 2818145, 0, 8, 2752609, 0, 8, 2687073, 0, 8, 2621537, 0, 8, 2556001, 0, 8, 2490465, 0, 8, 2424929, 0, 8, 2359393, 0, 8, 2293857, 0, 8, 2228321, 0, 8, 2162785, 0, 8, 2097249, 0, 8, 2031713, 0, 8, 1966177, 0, 8, 1900641, 0, 8, 1835105, 0, 8, 1769569, 0, 8, 1704033, 0, 8, 1638497, 0, 8, 1572961, 0, 8, 1507425, 0, 8, 3539040, 0, 8, 3473504, 0, 8, 3407968, 0, 8, 3342432, 0, 8, 3276896, 0, 8, 3211360, 0, 8, 3145824, 0, 8, 3080288, 0, 8, 3014752, 0, 8, 2949216, 0, 8, 2883680, 0, 8, 2818144, 0, 8, 2752608, 0, 8, 2687072, 0, 8, 2621536, 0, 8, 2556000, 0, 8, 2490464, 0, 8, 2424928, 0, 8, 2359392, 0, 8, 2293856, 0, 8, 2228320, 0, 8, 2162784, 0, 8, 2097248, 0, 8, 2031712, 0, 8, 1966176, 0, 8, 1900640, 0, 8, 1835104, 0, 8, 1769568, 0, 8, 1704032, 0, 8, 1638496, 0, 8, 1572960, 0, 8, 1507424, 0, 8, 3539039, 0, 8, 3473503, 0, 8, 3407967, 0, 8, 3342431, 0, 8, 3276895, 0, 8, 3211359, 0, 8, 3145823, 0, 8, 3080287, 0, 8, 3014751, 0, 8, 2949215, 0, 8, 2883679, 0, 8, 2818143, 0, 8, 2752607, 0, 8, 2687071, 0, 8, 2621535, 0, 8, 2555999, 0, 8, 2490463, 0, 8, 2424927, 0, 8, 2359391, 0, 8, 2293855, 0, 8, 2228319, 0, 8, 2162783, 0, 8, 2097247, 0, 8, 2031711, 0, 8, 1966175, 0, 8, 1900639, 0, 8, 1835103, 0, 8, 1769567, 0, 8, 1704031, 0, 8, 1638495, 0, 8, 1572959, 0, 8, 1507423, 0, 8, 3539038, 0, 8, 3473502, 0, 8, 3407966, 0, 8, 3342430, 0, 8, 3276894, 0, 8, 3211358, 0, 8, 3145822, 0, 8, 3080286, 0, 8, 3014750, 0, 8, 2949214, 0, 8, 2883678, 0, 8, 2818142, 0, 8, 2752606, 0, 8, 2687070, 0, 8, 2621534, 0, 8, 2555998, 0, 8, 2490462, 0, 8, 2424926, 0, 8, 2359390, 0, 8, 2293854, 0, 8, 2228318, 0, 8, 2162782, 0, 8, 2097246, 0, 8, 2031710, 0, 8, 1966174, 0, 8, 1900638, 0, 8, 1835102, 0, 8, 1769566, 0, 8, 1704030, 0, 8, 1638494, 0, 8, 1572958, 0, 8, 1507422, 0, 8, 3539037, 0, 8, 3473501, 0, 8, 3407965, 0, 8, 3342429, 0, 8, 3276893, 0, 8, 3211357, 0, 8, 3145821, 0, 8, 3080285, 0, 8, 3014749, 0, 8, 2949213, 0, 8, 2883677, 0, 8, 2818141, 0, 8, 2752605, 0, 8, 2687069, 0, 8, 2621533, 0, 8, 2555997, 0, 8, 2490461, 0, 8, 2424925, 0, 8, 2359389, 0, 8, 2293853, 0, 8, 2228317, 0, 8, 2162781, 0, 8, 2097245, 0, 8, 2031709, 0, 8, 1966173, 0, 8, 1900637, 0, 8, 1835101, 0, 8, 1769565, 0, 8, 1704029, 0, 8, 1638493, 0, 8, 1572957, 0, 8, 1507421, 0, 8, 3539036, 0, 8, 3473500, 0, 8, 3407964, 0, 8, 3342428, 0, 8, 3276892, 0, 8, 3211356, 0, 8, 3145820, 0, 8, 3080284, 0, 8, 3014748, 0, 8, 2949212, 0, 8, 2883676, 0, 8, 2818140, 0, 8, 2752604, 0, 8, 2687068, 0, 8, 2621532, 0, 8, 2555996, 0, 8, 2490460, 0, 8, 2424924, 0, 8, 2359388, 0, 8, 2293852, 0, 8, 2228316, 0, 8, 2162780, 0, 8, 2097244, 0, 8, 2031708, 0, 8, 1966172, 0, 8, 1900636, 0, 8, 1835100, 0, 8, 1769564, 0, 8, 1704028, 0, 8, 1638492, 0, 8, 1572956, 0, 8, 1507420, 0, 8, 3539035, 0, 8, 3473499, 0, 8, 3407963, 0, 8, 3342427, 0, 8, 3276891, 0, 8, 3211355, 0, 8, 3145819, 0, 8, 3080283, 0, 8, 3014747, 0, 8, 2949211, 0, 8, 2883675, 0, 8, 2818139, 0, 8, 2752603, 0, 8, 2687067, 0, 8, 2621531, 0, 8, 2555995, 0, 8, 2490459, 0, 8, 2424923, 0, 8, 2359387, 0, 8, 2293851, 0, 8, 2228315, 0, 8, 2162779, 0, 8, 2097243, 0, 8, 2031707, 0, 8, 1966171, 0, 8, 1900635, 0, 8, 1835099, 0, 8, 1769563, 0, 8, 1704027, 0, 8, 1638491, 0, 8, 1572955, 0, 8, 1507419, 0, 8, 3539034, 0, 8, 3473498, 0, 8, 3407962, 0, 8, 3342426, 0, 8, 3276890, 0, 8, 3211354, 0, 8, 3145818, 0, 8, 3080282, 0, 8, 3014746, 0, 8, 2949210, 0, 8, 2883674, 0, 8, 2818138, 0, 8, 2752602, 0, 8, 2687066, 0, 8, 2621530, 0, 8, 2555994, 0, 8, 2490458, 0, 8, 2424922, 0, 8, 2359386, 0, 8, 2293850, 0, 8, 2228314, 0, 8, 2162778, 0, 8, 2097242, 0, 8, 2031706, 0, 8, 1966170, 0, 8, 1900634, 0, 8, 1835098, 0, 8, 1769562, 0, 8, 1704026, 0, 8, 1638490, 0, 8, 1572954, 0, 8, 1507418, 0, 8, 2621529, 0, 8, 2555993, 0, 8, 2490457, 0, 8, 2424921, 0, 8, 2359385, 0, 8, 2293849, 0, 8, 2228313, 0, 8, 2162777, 0, 8, 2097241, 0, 8, 2031705, 0, 8, 1966169, 0, 8, 1900633, 0, 8, 1835097, 0, 8, 1769561, 0, 8, 1704025, 0, 8, 1638489, 0, 8, 1572953, 0, 8, 1507417, 0, 8, 2621528, 0, 8, 2555992, 0, 8, 2490456, 0, 8, 2424920, 0, 8, 2359384, 0, 8, 2293848, 0, 8, 2228312, 0, 8, 2162776, 0, 8, 2097240, 0, 8, 2031704, 0, 8, 1966168, 0, 8, 1900632, 0, 8, 1835096, 0, 8, 1769560, 0, 8, 1704024, 0, 8, 1638488, 0, 8, 1572952, 0, 8, 1507416, 0, 8, 2621527, 0, 8, 2555991, 0, 8, 2490455, 0, 8, 2424919, 0, 8, 2359383, 0, 8, 2293847, 0, 8, 2228311, 0, 8, 2162775, 0, 8, 2097239, 0, 8, 2031703, 0, 8, 1966167, 0, 8, 1900631, 0, 8, 1835095, 0, 8, 1769559, 0, 8, 1704023, 0, 8, 1638487, 0, 8, 1572951, 0, 8, 1507415, 0, 8, 2621526, 0, 8, 2555990, 0, 8, 2490454, 0, 8, 2424918, 0, 8, 2359382, 0, 8, 2293846, 0, 8, 2228310, 0, 8, 2162774, 0, 8, 2097238, 0, 8, 2031702, 0, 8, 1966166, 0, 8, 1900630, 0, 8, 1835094, 0, 8, 1769558, 0, 8, 1704022, 0, 8, 1638486, 0, 8, 1572950, 0, 8, 1507414, 0, 8, 1507413, 196608, 3, 1572949, 196608, 3, 1638485, 196608, 3, 1704021, 196608, 3, 1769557, 196608, 3, 1835093, 196608, 3, 1900629, 196608, 3, 1966165, 196608, 3, 2031701, 196608, 3, 2097237, 196608, 3, 2162773, 196608, 3, 2228309, 196608, 3, 2293845, 196608, 3, 2359381, 196608, 3, 2424917, 196608, 3, 2490453, 196608, 3, 2555989, 196608, 3, 2621525, 196608, 3, 3604570, 0, 8, 3604571, 0, 8, 3604572, 0, 8, 3604573, 0, 8, 3604574, 0, 8, 3604575, 0, 8, 3604576, 0, 8, 3604577, 0, 8, 3604578, 0, 8, 852067, 131072, 7, 3604579, 0, 8, 852068, 131072, 7, 3604580, 0, 8, 852069, 131072, 7, 3604581, 0, 8, 852070, 131072, 7, 3604582, 0, 8, 852071, 131072, 7, 3604583, 0, 8, 852072, 131072, 7, 3604584, 0, 8, 852073, 131072, 7, 3604585, 0, 8, 852074, 131072, 7, 3604586, 0, 8, 852075, 131072, 7, 3604587, 0, 8, 852076, 131072, 7, 3604588, 0, 8, 852077, 131072, 7, 3604589, 0, 8, 852078, 131072, 7, 3604590, 0, 8, 852079, 131072, 7, 3604591, 0, 8, 852080, 131072, 7, 3604592, 0, 8, 852081, 131072, 7, 3604593, 0, 8, 852082, 131072, 7, 3604594, 0, 8, 852083, 131072, 7, 3604595, 0, 8, 852084, 131072, 7, 3604596, 0, 8, 852085, 131072, 7, 3604597, 0, 8, 852086, 131072, 7, 3604598, 0, 8, 852087, 131072, 7, 3604599, 0, 8, 852088, 131072, 7, 3604600, 0, 8, 852089, 131072, 7, 3604601, 65536, 2, 852090, 131072, 7, 3604602, 131072, 2, 852091, 131072, 7, 3604603, 131072, 2, 852092, 131072, 7, 3604604, 131072, 2, 852093, 131072, 7, 3604605, 131072, 2, 983166, 65536, 3, 852094, 65536, 4, 1048702, 65536, 3, 917630, 65536, 3, 1114238, 65536, 3, 1179774, 65536, 3, 1245310, 65536, 3, 1310846, 65536, 3, 1376382, 65536, 3, 1441918, 65536, 3, 1507454, 65536, 3, 1572990, 65536, 3, 1638526, 65536, 3, 1704062, 65536, 3, 1769598, 65536, 3, 1835134, 65536, 3, 1900670, 65536, 3, 1966206, 65536, 3, 2031742, 65536, 3, 2097278, 65536, 3, 2162814, 65536, 3, 2228350, 65536, 3, 2293886, 65536, 3, 2359422, 65536, 3, 2424958, 65536, 3, 2490494, 65536, 3, 2556030, 65536, 3, 2621566, 65536, 3, 2687102, 65536, 3, 2752638, 65536, 3, 2818174, 65536, 3, 2883710, 65536, 3, 2949246, 65536, 3, 3014782, 65536, 3, 3080318, 65536, 3, 3145854, 65536, 3, 3211390, 65536, 3, 3276926, 65536, 3, 3342462, 65536, 3, 3407998, 65536, 3, 3473534, 65536, 3, 3539070, 65536, 3, 3604606, 851968, 2, 5701752, 0, 8, 5636216, 0, 8, 5570680, 0, 8, 5505144, 0, 8, 5439608, 0, 8, 5374072, 0, 8, 5308536, 0, 8, 5243000, 0, 8, 5177464, 0, 8, 5111928, 0, 8, 5046392, 0, 8, 4980856, 0, 8, 4915320, 0, 8, 4849784, 0, 8, 4784248, 0, 8, 4718712, 0, 8, 4653176, 0, 8, 4587640, 0, 8, 4522104, 0, 8, 4456568, 0, 8, 4391032, 0, 8, 4325496, 0, 8, 4259960, 0, 8, 4194424, 0, 8, 4128888, 0, 8, 4063352, 0, 8, 3997816, 0, 8, 3932280, 0, 8, 3866744, 0, 8, 3801208, 0, 8, 3735672, 0, 8, 3670136, 0, 8, 5701751, 0, 8, 5636215, 0, 8, 5570679, 0, 8, 5505143, 0, 8, 5439607, 0, 8, 5374071, 0, 8, 5308535, 0, 8, 5242999, 0, 8, 5177463, 0, 8, 5111927, 0, 8, 5046391, 0, 8, 4980855, 0, 8, 4915319, 0, 8, 4849783, 0, 8, 4784247, 0, 8, 4718711, 0, 8, 4653175, 0, 8, 4587639, 0, 8, 4522103, 0, 8, 4456567, 0, 8, 4391031, 0, 8, 4325495, 0, 8, 4259959, 0, 8, 4194423, 0, 8, 4128887, 0, 8, 4063351, 0, 8, 3997815, 0, 8, 3932279, 0, 8, 3866743, 0, 8, 3801207, 0, 8, 3735671, 0, 8, 3670135, 0, 8, 5701750, 0, 8, 5636214, 0, 8, 5570678, 0, 8, 5505142, 0, 8, 5439606, 0, 8, 5374070, 0, 8, 5308534, 0, 8, 5242998, 0, 8, 5177462, 0, 8, 5111926, 0, 8, 5046390, 0, 8, 4980854, 0, 8, 4915318, 0, 8, 4849782, 0, 8, 4784246, 0, 8, 4718710, 0, 8, 4653174, 0, 8, 4587638, 0, 8, 4522102, 0, 8, 4456566, 0, 8, 4391030, 0, 8, 4325494, 0, 8, 4259958, 0, 8, 4194422, 0, 8, 4128886, 0, 8, 4063350, 0, 8, 3997814, 0, 8, 3932278, 0, 8, 3866742, 0, 8, 3801206, 0, 8, 3735670, 0, 8, 3670134, 0, 8, 5701749, 0, 8, 5636213, 0, 8, 5570677, 0, 8, 5505141, 0, 8, 5439605, 0, 8, 5374069, 0, 8, 5308533, 0, 8, 5242997, 0, 8, 5177461, 0, 8, 5111925, 0, 8, 5046389, 0, 8, 4980853, 0, 8, 4915317, 0, 8, 4849781, 0, 8, 4784245, 0, 8, 4718709, 0, 8, 4653173, 0, 8, 4587637, 0, 8, 4522101, 0, 8, 4456565, 0, 8, 4391029, 0, 8, 4325493, 0, 8, 4259957, 0, 8, 4194421, 0, 8, 4128885, 0, 8, 4063349, 0, 8, 3997813, 0, 8, 3932277, 0, 8, 3866741, 0, 8, 3801205, 0, 8, 3735669, 0, 8, 3670133, 0, 8, 5701748, 0, 8, 5636212, 0, 8, 5570676, 0, 8, 5505140, 0, 8, 5439604, 0, 8, 5374068, 0, 8, 5308532, 0, 8, 5242996, 0, 8, 5177460, 0, 8, 5111924, 0, 8, 5046388, 0, 8, 4980852, 0, 8, 4915316, 0, 8, 4849780, 0, 8, 4784244, 0, 8, 4718708, 0, 8, 4653172, 0, 8, 4587636, 0, 8, 4522100, 0, 8, 4456564, 0, 8, 4391028, 0, 8, 4325492, 0, 8, 4259956, 0, 8, 4194420, 0, 8, 4128884, 0, 8, 4063348, 0, 8, 3997812, 0, 8, 3932276, 0, 8, 3866740, 0, 8, 3801204, 0, 8, 3735668, 0, 8, 3670132, 0, 8, 5701747, 0, 8, 5636211, 0, 8, 5570675, 0, 8, 5505139, 0, 8, 5439603, 0, 8, 5374067, 0, 8, 5308531, 0, 8, 5242995, 0, 8, 5177459, 0, 8, 5111923, 0, 8, 5046387, 0, 8, 4980851, 0, 8, 4915315, 0, 8, 4849779, 0, 8, 4784243, 0, 8, 4718707, 0, 8, 4653171, 0, 8, 4587635, 0, 8, 4522099, 0, 8, 4456563, 0, 8, 4391027, 0, 8, 4325491, 0, 8, 4259955, 0, 8, 4194419, 0, 8, 4128883, 0, 8, 4063347, 0, 8, 3997811, 0, 8, 3932275, 0, 8, 3866739, 0, 8, 3801203, 0, 8, 3735667, 0, 8, 3670131, 0, 8, 5701746, 0, 8, 5636210, 0, 8, 5570674, 0, 8, 5505138, 0, 8, 5439602, 0, 8, 5374066, 0, 8, 5308530, 0, 8, 5242994, 0, 8, 5177458, 0, 8, 5111922, 0, 8, 5046386, 0, 8, 4980850, 0, 8, 4915314, 0, 8, 4849778, 0, 8, 4784242, 0, 8, 4718706, 0, 8, 4653170, 0, 8, 4587634, 0, 8, 4522098, 0, 8, 4456562, 0, 8, 4391026, 0, 8, 4325490, 0, 8, 4259954, 0, 8, 4194418, 0, 8, 4128882, 0, 8, 4063346, 0, 8, 3997810, 0, 8, 3932274, 0, 8, 3866738, 0, 8, 3801202, 0, 8, 3735666, 0, 8, 3670130, 0, 8, 5701745, 0, 8, 5636209, 0, 8, 5570673, 0, 8, 5505137, 0, 8, 5439601, 0, 8, 5374065, 0, 8, 5308529, 0, 8, 5242993, 0, 8, 5177457, 0, 8, 5111921, 0, 8, 5046385, 0, 8, 4980849, 0, 8, 4915313, 0, 8, 4849777, 0, 8, 4784241, 0, 8, 4718705, 0, 8, 4653169, 0, 8, 4587633, 0, 8, 4522097, 0, 8, 4456561, 0, 8, 4391025, 0, 8, 4325489, 0, 8, 4259953, 0, 8, 4194417, 0, 8, 4128881, 0, 8, 4063345, 0, 8, 3997809, 0, 8, 3932273, 0, 8, 3866737, 0, 8, 3801201, 0, 8, 3735665, 0, 8, 3670129, 0, 8, 5701744, 0, 8, 5636208, 0, 8, 5570672, 0, 8, 5505136, 0, 8, 5439600, 0, 8, 5374064, 0, 8, 5308528, 0, 8, 5242992, 0, 8, 5177456, 0, 8, 5111920, 0, 8, 5046384, 0, 8, 4980848, 0, 8, 4915312, 0, 8, 4849776, 0, 8, 4784240, 0, 8, 4718704, 0, 8, 4653168, 0, 8, 4587632, 0, 8, 4522096, 0, 8, 4456560, 0, 8, 4391024, 0, 8, 4325488, 0, 8, 4259952, 0, 8, 4194416, 0, 8, 4128880, 0, 8, 4063344, 0, 8, 3997808, 0, 8, 3932272, 0, 8, 3866736, 0, 8, 3801200, 0, 8, 3735664, 0, 8, 3670128, 0, 8, 5701743, 0, 8, 5636207, 0, 8, 5570671, 0, 8, 5505135, 0, 8, 5439599, 0, 8, 5374063, 0, 8, 5308527, 0, 8, 5242991, 0, 8, 5177455, 0, 8, 5111919, 0, 8, 5046383, 0, 8, 4980847, 0, 8, 4915311, 0, 8, 4849775, 0, 8, 4784239, 0, 8, 4718703, 0, 8, 4653167, 0, 8, 4587631, 0, 8, 4522095, 0, 8, 4456559, 0, 8, 4391023, 0, 8, 4325487, 0, 8, 4259951, 0, 8, 4194415, 0, 8, 4128879, 0, 8, 4063343, 0, 8, 3997807, 0, 8, 3932271, 0, 8, 3866735, 0, 8, 3801199, 0, 8, 3735663, 0, 8, 3670127, 0, 8, 5701742, 0, 8, 5636206, 0, 8, 5570670, 0, 8, 5505134, 0, 8, 5439598, 0, 8, 5374062, 0, 8, 5308526, 0, 8, 5242990, 0, 8, 5177454, 0, 8, 5111918, 0, 8, 5046382, 0, 8, 4980846, 0, 8, 4915310, 0, 8, 4849774, 0, 8, 4784238, 0, 8, 4718702, 0, 8, 4653166, 0, 8, 4587630, 0, 8, 4522094, 0, 8, 4456558, 0, 8, 4391022, 0, 8, 4325486, 0, 8, 4259950, 0, 8, 4194414, 0, 8, 4128878, 0, 8, 4063342, 0, 8, 3997806, 0, 8, 3932270, 0, 8, 3866734, 0, 8, 3801198, 0, 8, 3735662, 0, 8, 3670126, 0, 8, 5701741, 0, 8, 5636205, 0, 8, 5570669, 0, 8, 5505133, 0, 8, 5439597, 0, 8, 5374061, 0, 8, 5308525, 0, 8, 5242989, 0, 8, 5177453, 0, 8, 5111917, 0, 8, 5046381, 0, 8, 4980845, 0, 8, 4915309, 0, 8, 4849773, 0, 8, 4784237, 0, 8, 4718701, 0, 8, 4653165, 0, 8, 4587629, 0, 8, 4522093, 0, 8, 4456557, 0, 8, 4391021, 0, 8, 4325485, 0, 8, 4259949, 0, 8, 4194413, 0, 8, 4128877, 0, 8, 4063341, 0, 8, 3997805, 0, 8, 3932269, 0, 8, 3866733, 0, 8, 3801197, 0, 8, 3735661, 0, 8, 3670125, 0, 8, 5701740, 0, 8, 5636204, 0, 8, 5570668, 0, 8, 5505132, 0, 8, 5439596, 0, 8, 5374060, 0, 8, 5308524, 0, 8, 5242988, 0, 8, 5177452, 0, 8, 5111916, 0, 8, 5046380, 0, 8, 4980844, 0, 8, 4915308, 0, 8, 4849772, 0, 8, 4784236, 0, 8, 4718700, 0, 8, 4653164, 0, 8, 4587628, 0, 8, 4522092, 0, 8, 4456556, 0, 8, 4391020, 0, 8, 4325484, 0, 8, 4259948, 0, 8, 4194412, 0, 8, 4128876, 0, 8, 4063340, 0, 8, 3997804, 0, 8, 3932268, 0, 8, 3866732, 0, 8, 3801196, 0, 8, 3735660, 0, 8, 3670124, 0, 8, 5701739, 0, 8, 5636203, 0, 8, 5570667, 0, 8, 5505131, 0, 8, 5439595, 0, 8, 5374059, 0, 8, 5308523, 0, 8, 5242987, 0, 8, 5177451, 0, 8, 5111915, 0, 8, 5046379, 0, 8, 4980843, 0, 8, 4915307, 0, 8, 4849771, 0, 8, 4784235, 0, 8, 4718699, 0, 8, 4653163, 0, 8, 4587627, 0, 8, 4522091, 0, 8, 4456555, 0, 8, 4391019, 0, 8, 4325483, 0, 8, 4259947, 0, 8, 4194411, 0, 8, 4128875, 0, 8, 4063339, 0, 8, 3997803, 0, 8, 3932267, 0, 8, 3866731, 0, 8, 3801195, 0, 8, 3735659, 0, 8, 3670123, 0, 8, 5701738, 0, 8, 5636202, 0, 8, 5570666, 0, 8, 5505130, 0, 8, 5439594, 0, 8, 5374058, 0, 8, 5308522, 0, 8, 5242986, 0, 8, 5177450, 0, 8, 5111914, 0, 8, 5046378, 0, 8, 4980842, 0, 8, 4915306, 0, 8, 4849770, 0, 8, 4784234, 0, 8, 4718698, 0, 8, 4653162, 0, 8, 4587626, 0, 8, 4522090, 0, 8, 4456554, 0, 8, 4391018, 0, 8, 4325482, 0, 8, 4259946, 0, 8, 4194410, 0, 8, 4128874, 0, 8, 4063338, 0, 8, 3997802, 0, 8, 3932266, 0, 8, 3866730, 0, 8, 3801194, 0, 8, 3735658, 0, 8, 3670122, 0, 8, 5701737, 0, 8, 5636201, 0, 8, 5570665, 0, 8, 5505129, 0, 8, 5439593, 0, 8, 5374057, 0, 8, 5308521, 0, 8, 5242985, 0, 8, 5177449, 0, 8, 5111913, 0, 8, 5046377, 0, 8, 4980841, 0, 8, 4915305, 0, 8, 4849769, 0, 8, 4784233, 0, 8, 4718697, 0, 8, 4653161, 0, 8, 4587625, 0, 8, 4522089, 0, 8, 4456553, 0, 8, 4391017, 0, 8, 4325481, 0, 8, 4259945, 0, 8, 4194409, 0, 8, 4128873, 0, 8, 4063337, 0, 8, 3997801, 0, 8, 3932265, 0, 8, 3866729, 0, 8, 3801193, 0, 8, 3735657, 0, 8, 3670121, 0, 8, 5701736, 0, 8, 5636200, 0, 8, 5570664, 0, 8, 5505128, 0, 8, 5439592, 0, 8, 5374056, 0, 8, 5308520, 0, 8, 5242984, 0, 8, 5177448, 0, 8, 5111912, 0, 8, 5046376, 0, 8, 4980840, 0, 8, 4915304, 0, 8, 4849768, 0, 8, 4784232, 0, 8, 4718696, 0, 8, 4653160, 0, 8, 4587624, 0, 8, 4522088, 0, 8, 4456552, 0, 8, 4391016, 0, 8, 4325480, 0, 8, 4259944, 0, 8, 4194408, 0, 8, 4128872, 0, 8, 4063336, 0, 8, 3997800, 0, 8, 3932264, 0, 8, 3866728, 0, 8, 3801192, 0, 8, 3735656, 0, 8, 3670120, 0, 8, 5701735, 0, 8, 5636199, 0, 8, 5570663, 0, 8, 5505127, 0, 8, 5439591, 0, 8, 5374055, 0, 8, 5308519, 0, 8, 5242983, 0, 8, 5177447, 0, 8, 5111911, 0, 8, 5046375, 0, 8, 4980839, 0, 8, 4915303, 0, 8, 4849767, 0, 8, 4784231, 0, 8, 4718695, 0, 8, 4653159, 0, 8, 4587623, 0, 8, 4522087, 0, 8, 4456551, 0, 8, 4391015, 0, 8, 4325479, 0, 8, 4259943, 0, 8, 4194407, 0, 8, 4128871, 0, 8, 4063335, 0, 8, 3997799, 0, 8, 3932263, 0, 8, 3866727, 0, 8, 3801191, 0, 8, 3735655, 0, 8, 3670119, 0, 8, 5701734, 0, 8, 5636198, 0, 8, 5570662, 0, 8, 5505126, 0, 8, 5439590, 0, 8, 5374054, 0, 8, 5308518, 0, 8, 5242982, 0, 8, 5177446, 0, 8, 5111910, 0, 8, 5046374, 0, 8, 4980838, 0, 8, 4915302, 0, 8, 4849766, 0, 8, 4784230, 0, 8, 4718694, 0, 8, 4653158, 0, 8, 4587622, 0, 8, 4522086, 0, 8, 5701733, 0, 8, 5636197, 0, 8, 5570661, 0, 8, 5505125, 0, 8, 5439589, 0, 8, 5374053, 0, 8, 5308517, 0, 8, 5242981, 0, 8, 5177445, 0, 8, 5111909, 0, 8, 5046373, 0, 8, 4980837, 0, 8, 4915301, 0, 8, 4849765, 0, 8, 4784229, 0, 8, 4718693, 0, 8, 4653157, 0, 8, 4587621, 0, 8, 4522085, 0, 8, 5701732, 0, 8, 5636196, 0, 8, 5570660, 0, 8, 5505124, 0, 8, 5439588, 0, 8, 5374052, 0, 8, 5308516, 0, 8, 5242980, 0, 8, 5177444, 0, 8, 5111908, 0, 8, 5046372, 0, 8, 4980836, 0, 8, 4915300, 0, 8, 4849764, 0, 8, 4784228, 0, 8, 4718692, 0, 8, 4653156, 0, 8, 4587620, 0, 8, 4522084, 0, 8, 5701731, 0, 8, 5636195, 0, 8, 5570659, 0, 8, 5505123, 0, 8, 5439587, 0, 8, 5374051, 0, 8, 5308515, 0, 8, 5242979, 0, 8, 5177443, 0, 8, 5111907, 0, 8, 5046371, 0, 8, 4980835, 0, 8, 4915299, 0, 8, 4849763, 0, 8, 4784227, 0, 8, 4718691, 0, 8, 4653155, 0, 8, 4587619, 0, 8, 4522083, 0, 8, 5701730, 0, 8, 5636194, 0, 8, 5570658, 0, 8, 5505122, 0, 8, 5439586, 0, 8, 5374050, 0, 8, 5308514, 0, 8, 5242978, 0, 8, 5177442, 0, 8, 5111906, 0, 8, 5046370, 0, 8, 4980834, 0, 8, 4915298, 0, 8, 4849762, 0, 8, 4784226, 0, 8, 4718690, 0, 8, 4653154, 0, 8, 4587618, 0, 8, 4522082, 0, 8, 5701729, 0, 8, 5636193, 0, 8, 5570657, 0, 8, 5505121, 0, 8, 5439585, 0, 8, 5374049, 0, 8, 5308513, 0, 8, 5242977, 0, 8, 5177441, 0, 8, 5111905, 0, 8, 5046369, 0, 8, 4980833, 0, 8, 4915297, 0, 8, 4849761, 0, 8, 4784225, 0, 8, 4718689, 0, 8, 4653153, 0, 8, 4587617, 0, 8, 4522081, 0, 8, 5701728, 0, 8, 5636192, 0, 8, 5570656, 0, 8, 5505120, 0, 8, 5439584, 0, 8, 5374048, 0, 8, 5308512, 0, 8, 5242976, 0, 8, 5177440, 0, 8, 5111904, 0, 8, 5046368, 0, 8, 4980832, 0, 8, 4915296, 0, 8, 4849760, 0, 8, 4784224, 0, 8, 4718688, 0, 8, 4653152, 0, 8, 4587616, 0, 8, 4522080, 0, 8, 5701727, 0, 8, 5636191, 0, 8, 5570655, 0, 8, 5505119, 0, 8, 5439583, 0, 8, 5374047, 0, 8, 5308511, 0, 8, 5242975, 0, 8, 5177439, 0, 8, 5111903, 0, 8, 5046367, 0, 8, 4980831, 0, 8, 4915295, 0, 8, 4849759, 0, 8, 4784223, 0, 8, 4718687, 0, 8, 4653151, 0, 8, 4587615, 0, 8, 4522079, 0, 8, 5701726, 0, 8, 5636190, 0, 8, 5570654, 0, 8, 5505118, 0, 8, 5439582, 0, 8, 5374046, 0, 8, 5308510, 0, 8, 5242974, 0, 8, 5177438, 0, 8, 5111902, 0, 8, 5046366, 0, 8, 4980830, 0, 8, 4915294, 0, 8, 4849758, 0, 8, 4784222, 0, 8, 4718686, 0, 8, 4653150, 0, 8, 4587614, 0, 8, 4522078, 0, 8, 5701725, 0, 8, 5636189, 0, 8, 5570653, 0, 8, 5505117, 0, 8, 5439581, 0, 8, 5374045, 0, 8, 5308509, 0, 8, 5242973, 0, 8, 5177437, 0, 8, 5111901, 0, 8, 5046365, 0, 8, 4980829, 0, 8, 4915293, 0, 8, 4849757, 0, 8, 4784221, 0, 8, 4718685, 0, 8, 4653149, 0, 8, 4587613, 0, 8, 4522077, 0, 8, 5701724, 0, 8, 5636188, 0, 8, 5570652, 0, 8, 5505116, 0, 8, 5439580, 0, 8, 5374044, 0, 8, 5308508, 0, 8, 5242972, 0, 8, 5177436, 0, 8, 5111900, 0, 8, 5046364, 0, 8, 4980828, 0, 8, 4915292, 0, 8, 4849756, 0, 8, 4784220, 0, 8, 4718684, 0, 8, 4653148, 0, 8, 4587612, 0, 8, 4522076, 0, 8, 5701723, 0, 8, 5636187, 0, 8, 5570651, 0, 8, 5505115, 0, 8, 5439579, 0, 8, 5374043, 0, 8, 5308507, 0, 8, 5242971, 0, 8, 5177435, 0, 8, 5111899, 0, 8, 5046363, 0, 8, 4980827, 0, 8, 4915291, 0, 8, 4849755, 0, 8, 4784219, 0, 8, 4718683, 0, 8, 4653147, 0, 8, 4587611, 0, 8, 4522075, 0, 8, 5701722, 0, 8, 5636186, 0, 8, 5570650, 0, 8, 5505114, 0, 8, 5439578, 0, 8, 5374042, 0, 8, 5308506, 0, 8, 5242970, 0, 8, 5177434, 0, 8, 5111898, 0, 8, 5046362, 0, 8, 4980826, 0, 8, 4915290, 0, 8, 4849754, 0, 8, 4784218, 0, 8, 4718682, 0, 8, 4653146, 0, 8, 4587610, 0, 8, 4522074, 0, 8, 5701721, 0, 8, 5636185, 0, 8, 5570649, 0, 8, 5505113, 0, 8, 5439577, 0, 8, 5374041, 0, 8, 5308505, 0, 8, 5242969, 0, 8, 5177433, 0, 8, 5111897, 0, 8, 5046361, 0, 8, 5701720, 0, 8, 5636184, 0, 8, 5570648, 0, 8, 5505112, 0, 8, 5439576, 0, 8, 5374040, 0, 8, 5308504, 0, 8, 5242968, 0, 8, 5177432, 0, 8, 5111896, 0, 8, 5046360, 0, 8, 5701719, 0, 8, 5636183, 0, 8, 5570647, 0, 8, 5505111, 0, 8, 5439575, 0, 8, 5374039, 0, 8, 5308503, 0, 8, 5242967, 0, 8, 5177431, 0, 8, 5111895, 0, 8, 5046359, 0, 8, 5701718, 0, 8, 5636182, 0, 8, 5570646, 0, 8, 5505110, 0, 8, 5439574, 0, 8, 5374038, 0, 8, 5308502, 0, 8, 5242966, 0, 8, 5177430, 0, 8, 5111894, 0, 8, 5046358, 0, 8, 5701717, 0, 8, 5636181, 0, 8, 5570645, 0, 8, 5505109, 0, 8, 5439573, 0, 8, 5374037, 0, 8, 5308501, 0, 8, 5242965, 0, 8, 5177429, 0, 8, 5111893, 0, 8, 5046357, 0, 8, 5701716, 0, 8, 5636180, 0, 8, 5570644, 0, 8, 5505108, 0, 8, 5439572, 0, 8, 5374036, 0, 8, 5308500, 0, 8, 5242964, 0, 8, 5177428, 0, 8, 5111892, 0, 8, 5046356, 0, 8, 5701715, 0, 8, 5636179, 0, 8, 5570643, 0, 8, 5505107, 0, 8, 5439571, 0, 8, 5374035, 0, 8, 5308499, 0, 8, 5242963, 0, 8, 5177427, 0, 8, 5111891, 0, 8, 5046355, 0, 8, 5701714, 0, 8, 5636178, 0, 8, 5570642, 0, 8, 5505106, 0, 8, 5439570, 0, 8, 5374034, 0, 8, 5308498, 0, 8, 5242962, 0, 8, 5177426, 0, 8, 5111890, 0, 8, 5046354, 0, 8, 5701713, 0, 8, 5636177, 0, 8, 5570641, 0, 8, 5505105, 0, 8, 5439569, 0, 8, 5374033, 0, 8, 5308497, 0, 8, 5242961, 0, 8, 5177425, 0, 8, 5111889, 0, 8, 5046353, 0, 8, 5701712, 0, 8, 5636176, 0, 8, 5570640, 0, 8, 5505104, 0, 8, 5439568, 0, 8, 5374032, 0, 8, 5308496, 0, 8, 5242960, 0, 8, 5177424, 0, 8, 5111888, 0, 8, 5046352, 0, 8, 5701711, 0, 8, 5636175, 0, 8, 5570639, 0, 8, 5505103, 0, 8, 5439567, 0, 8, 5374031, 0, 8, 5308495, 0, 8, 5242959, 0, 8, 5177423, 0, 8, 5111887, 0, 8, 5046351, 0, 8, 5046350, 196608, 3, 5111886, 196608, 3, 5177422, 196608, 3, 5242958, 196608, 3, 5308494, 196608, 3, 5374030, 196608, 3, 5439566, 196608, 3, 5505102, 196608, 3, 5570638, 196608, 3, 5636174, 196608, 3, 5701710, 196608, 3, 5767248, 131072, 2, 5767246, 720896, 2, 5767249, 131072, 2, 5767247, 131072, 2, 5767250, 131072, 2, 5767251, 131072, 2, 5767252, 131072, 2, 5767253, 131072, 2, 5767254, 131072, 2, 5767255, 131072, 2, 5767256, 131072, 2, 5767257, 131072, 2, 5767258, 131072, 2, 5767259, 131072, 2, 5767260, 131072, 2, 5767261, 131072, 2, 5767262, 131072, 2, 5767263, 131072, 2, 5767264, 131072, 2, 5767265, 131072, 2, 5767266, 131072, 2, 5767267, 131072, 2, 5767268, 131072, 2, 5767269, 131072, 2, 5767270, 131072, 2, 5767271, 131072, 2, 5767272, 131072, 2, 5767273, 131072, 2, 5767274, 131072, 2, 5767275, 131072, 2, 5767276, 131072, 2, 5767277, 131072, 2, 5767278, 131072, 2, 5767279, 131072, 2, 5767280, 131072, 2, 5767281, 131072, 2, 5767282, 131072, 2, 5767283, 131072, 2, 5767284, 131072, 2, 5767285, 131072, 2, 5767286, 131072, 2, 5767287, 131072, 2, 5767288, 131072, 2, 3670137, 65536, 3, 3735673, 65536, 3, 3801209, 65536, 3, 3866745, 65536, 3, 3932281, 65536, 3, 3997817, 65536, 3, 4063353, 65536, 3, 4128889, 65536, 3, 4194425, 65536, 3, 4259961, 65536, 3, 4325497, 65536, 3, 4391033, 65536, 3, 4456569, 65536, 3, 4522105, 65536, 3, 4587641, 65536, 3, 4653177, 65536, 3, 4718713, 65536, 3, 4784249, 65536, 3, 4849785, 65536, 3, 4915321, 65536, 3, 4980857, 65536, 3, 5046393, 65536, 3, 5111929, 65536, 3, 5177465, 65536, 3, 5243001, 65536, 3, 5308537, 65536, 3, 5374073, 65536, 3, 5439609, 65536, 3, 5505145, 65536, 3, 5570681, 65536, 3, 5636217, 65536, 3, 5701753, 65536, 3, 5767289, 851968, 2, 3670104, 65536, 2, 3670105, 131072, 2, 3670106, 131072, 2, 3670107, 131072, 2, 3670108, 131072, 2, 3670109, 131072, 2, 3670110, 131072, 2, 3670111, 131072, 2, 3670112, 131072, 2, 3670113, 131072, 2, 3670114, 131072, 2, 3670115, 131072, 2, 3670116, 131072, 2, 3670117, 131072, 2, 3670118, 196608, 2, 3735654, 196608, 3, 3801190, 196608, 3, 3866726, 196608, 3, 3932262, 196608, 3, 3997798, 196608, 3, 4063334, 196608, 3, 4128870, 196608, 3, 4194406, 196608, 3, 4259942, 196608, 3, 4325478, 196608, 3, 4391014, 196608, 3, 4456550, 196608, 7, 4456536, 65536, 7, 4456537, 131072, 7, 4456538, 131072, 7, 4456539, 131072, 7, 4456540, 131072, 7, 4456541, 131072, 7, 4456542, 131072, 7, 4456543, 131072, 7, 4456544, 131072, 7, 4456545, 131072, 7, 4456546, 131072, 7, 4456547, 131072, 7, 4456548, 131072, 7, 4456549, 131072, 7, 3735640, 65536, 3, 3801176, 65536, 3, 3866712, 65536, 3, 3932248, 65536, 3, 3997784, 65536, 3, 4063320, 65536, 3, 4128856, 65536, 3, 4194392, 65536, 3, 4259928, 65536, 3, 4325464, 65536, 3, 4391000, 65536, 3, 6094913, 0, 8, 6029377, 0, 8, 5963841, 0, 8, 5898305, 0, 8, 5832769, 0, 8, 5767233, 0, 8, 5701697, 0, 8, 5636161, 0, 8, 5570625, 0, 8, 5505089, 0, 8, 5439553, 0, 8, 5374017, 0, 8, 5308481, 0, 8, 5242945, 0, 8, 5177409, 0, 8, 5111873, 0, 8, 5046337, 0, 8, 6094912, 0, 8, 6029376, 0, 8, 5963840, 0, 8, 5898304, 0, 8, 5832768, 0, 8, 5767232, 0, 8, 5701696, 0, 8, 5636160, 0, 8, 5570624, 0, 8, 5505088, 0, 8, 5439552, 0, 8, 5374016, 0, 8, 5308480, 0, 8, 5242944, 0, 8, 5177408, 0, 8, 5111872, 0, 8, 5046336, 0, 8, 6094911, 0, 8, 6029375, 0, 8, 5963839, 0, 8, 5898303, 0, 8, 5832767, 0, 8, 5767231, 0, 8, 5701695, 0, 8, 5636159, 0, 8, 5570623, 0, 8, 5505087, 0, 8, 5439551, 0, 8, 5374015, 0, 8, 5308479, 0, 8, 5242943, 0, 8, 5177407, 0, 8, 5111871, 0, 8, 5046335, 0, 8, 6094910, 0, 8, 6029374, 0, 8, 5963838, 0, 8, 5898302, 0, 8, 5832766, 0, 8, 5767230, 0, 8, 5701694, 0, 8, 5636158, 0, 8, 5570622, 0, 8, 5505086, 0, 8, 5439550, 0, 8, 5374014, 0, 8, 5308478, 0, 8, 5242942, 0, 8, 5177406, 0, 8, 5111870, 0, 8, 5046334, 0, 8, 6094909, 0, 8, 6029373, 0, 8, 5963837, 0, 8, 5898301, 0, 8, 5832765, 0, 8, 5767229, 0, 8, 5701693, 0, 8, 5636157, 0, 8, 5570621, 0, 8, 5505085, 0, 8, 5439549, 0, 8, 5374013, 0, 8, 5308477, 0, 8, 5242941, 0, 8, 5177405, 0, 8, 5111869, 0, 8, 5046333, 0, 8, 6094908, 0, 8, 6029372, 0, 8, 5963836, 0, 8, 5898300, 0, 8, 5832764, 0, 8, 5767228, 0, 8, 5701692, 0, 8, 5636156, 0, 8, 5570620, 0, 8, 5505084, 0, 8, 5439548, 0, 8, 5374012, 0, 8, 5308476, 0, 8, 5242940, 0, 8, 5177404, 0, 8, 5111868, 0, 8, 5046332, 0, 8, 6094907, 0, 8, 6029371, 0, 8, 5963835, 0, 8, 5898299, 0, 8, 5832763, 0, 8, 5767227, 0, 8, 5701691, 0, 8, 5636155, 0, 8, 5570619, 0, 8, 5505083, 0, 8, 5439547, 0, 8, 5374011, 0, 8, 5308475, 0, 8, 5242939, 0, 8, 5177403, 0, 8, 5111867, 0, 8, 5046331, 0, 8, 6094906, 0, 8, 6029370, 0, 8, 5963834, 0, 8, 5898298, 0, 8, 5832762, 0, 8, 5767226, 0, 8, 5701690, 0, 8, 5636154, 0, 8, 5570618, 0, 8, 5505082, 0, 8, 5439546, 0, 8, 5374010, 0, 8, 5308474, 0, 8, 5242938, 0, 8, 5177402, 0, 8, 5111866, 0, 8, 5046330, 0, 8, 6094905, 0, 8, 6029369, 0, 8, 5963833, 0, 8, 5898297, 0, 8, 5832761, 0, 8, 5767225, 0, 8, 5701689, 0, 8, 5636153, 0, 8, 5570617, 0, 8, 5505081, 0, 8, 5439545, 0, 8, 5374009, 0, 8, 5308473, 0, 8, 5242937, 0, 8, 5177401, 0, 8, 5111865, 0, 8, 5046329, 0, 8, 4980793, 0, 8, 4915257, 0, 8, 4849721, 0, 8, 4784185, 0, 8, 6094904, 0, 8, 6029368, 0, 8, 5963832, 0, 8, 5898296, 0, 8, 5832760, 0, 8, 5767224, 0, 8, 5701688, 0, 8, 5636152, 0, 8, 5570616, 0, 8, 5505080, 0, 8, 5439544, 0, 8, 5374008, 0, 8, 5308472, 0, 8, 5242936, 0, 8, 5177400, 0, 8, 5111864, 0, 8, 5046328, 0, 8, 4980792, 0, 8, 4915256, 0, 8, 4849720, 0, 8, 4784184, 0, 8, 6094903, 0, 8, 6029367, 0, 8, 5963831, 0, 8, 5898295, 0, 8, 5832759, 0, 8, 5767223, 0, 8, 5701687, 0, 8, 5636151, 0, 8, 5570615, 0, 8, 5505079, 0, 8, 5439543, 0, 8, 5374007, 0, 8, 5308471, 0, 8, 5242935, 0, 8, 5177399, 0, 8, 5111863, 0, 8, 5046327, 0, 8, 4980791, 0, 8, 4915255, 0, 8, 4849719, 0, 8, 4784183, 0, 8, 6094902, 0, 8, 6029366, 0, 8, 5963830, 0, 8, 5898294, 0, 8, 5832758, 0, 8, 5767222, 0, 8, 5701686, 0, 8, 5636150, 0, 8, 5570614, 0, 8, 5505078, 0, 8, 5439542, 0, 8, 5374006, 0, 8, 5308470, 0, 8, 5242934, 0, 8, 5177398, 0, 8, 5111862, 0, 8, 5046326, 0, 8, 4980790, 0, 8, 4915254, 0, 8, 4849718, 0, 8, 4784182, 0, 8, 6094901, 0, 8, 6029365, 0, 8, 5963829, 0, 8, 5898293, 0, 8, 5832757, 0, 8, 5767221, 0, 8, 5701685, 0, 8, 5636149, 0, 8, 5570613, 0, 8, 5505077, 0, 8, 5439541, 0, 8, 5374005, 0, 8, 5308469, 0, 8, 5242933, 0, 8, 5177397, 0, 8, 5111861, 0, 8, 5046325, 0, 8, 4980789, 0, 8, 4915253, 0, 8, 4849717, 0, 8, 4784181, 0, 8, 6094900, 0, 8, 6029364, 0, 8, 5963828, 0, 8, 5898292, 0, 8, 5832756, 0, 8, 5767220, 0, 8, 5701684, 0, 8, 5636148, 0, 8, 5570612, 0, 8, 5505076, 0, 8, 5439540, 0, 8, 5374004, 0, 8, 5308468, 0, 8, 5242932, 0, 8, 5177396, 0, 8, 5111860, 0, 8, 5046324, 0, 8, 4980788, 0, 8, 4915252, 0, 8, 4849716, 0, 8, 4784180, 0, 8, 6094899, 0, 8, 6029363, 0, 8, 5963827, 0, 8, 5898291, 0, 8, 5832755, 0, 8, 5767219, 0, 8, 5701683, 0, 8, 5636147, 0, 8, 5570611, 0, 8, 5505075, 0, 8, 5439539, 0, 8, 5374003, 0, 8, 5308467, 0, 8, 5242931, 0, 8, 5177395, 0, 8, 5111859, 0, 8, 5046323, 0, 8, 4980787, 0, 8, 4915251, 0, 8, 4849715, 0, 8, 4784179, 0, 8, 6094898, 0, 8, 6029362, 0, 8, 5963826, 0, 8, 5898290, 0, 8, 5832754, 0, 8, 5767218, 0, 8, 5701682, 0, 8, 5636146, 0, 8, 5570610, 0, 8, 5505074, 0, 8, 5439538, 0, 8, 5374002, 0, 8, 5308466, 0, 8, 5242930, 0, 8, 5177394, 0, 8, 5111858, 0, 8, 5046322, 0, 8, 4980786, 0, 8, 4915250, 0, 8, 4849714, 0, 8, 4784178, 0, 8, 6094897, 0, 8, 6029361, 0, 8, 5963825, 0, 8, 5898289, 0, 8, 5832753, 0, 8, 5767217, 0, 8, 5701681, 0, 8, 5636145, 0, 8, 5570609, 0, 8, 5505073, 0, 8, 5439537, 0, 8, 5374001, 0, 8, 5308465, 0, 8, 5242929, 0, 8, 5177393, 0, 8, 5111857, 0, 8, 5046321, 0, 8, 4980785, 0, 8, 4915249, 0, 8, 4849713, 0, 8, 4784177, 0, 8, 6094896, 0, 8, 6029360, 0, 8, 5963824, 0, 8, 5898288, 0, 8, 5832752, 0, 8, 5767216, 0, 8, 5701680, 0, 8, 5636144, 0, 8, 5570608, 0, 8, 5505072, 0, 8, 5439536, 0, 8, 5374000, 0, 8, 5308464, 0, 8, 5242928, 0, 8, 5177392, 0, 8, 5111856, 0, 8, 5046320, 0, 8, 4980784, 0, 8, 4915248, 0, 8, 4849712, 0, 8, 4784176, 0, 8, 6094895, 0, 8, 6029359, 0, 8, 5963823, 0, 8, 5898287, 0, 8, 5832751, 0, 8, 5767215, 0, 8, 5701679, 0, 8, 5636143, 0, 8, 5570607, 0, 8, 5505071, 0, 8, 5439535, 0, 8, 5373999, 0, 8, 5308463, 0, 8, 5242927, 0, 8, 5177391, 0, 8, 5111855, 0, 8, 5046319, 0, 8, 4980783, 0, 8, 4915247, 0, 8, 4849711, 0, 8, 4784175, 0, 8, 6094894, 0, 8, 6029358, 0, 8, 5963822, 0, 8, 5898286, 0, 8, 5832750, 0, 8, 5767214, 0, 8, 5701678, 0, 8, 5636142, 0, 8, 5570606, 0, 8, 5505070, 0, 8, 5439534, 0, 8, 5373998, 0, 8, 5308462, 0, 8, 5242926, 0, 8, 5177390, 0, 8, 5111854, 0, 8, 5046318, 0, 8, 4980782, 0, 8, 4915246, 0, 8, 4849710, 0, 8, 4784174, 0, 8, 6094893, 0, 8, 6029357, 0, 8, 5963821, 0, 8, 5898285, 0, 8, 5832749, 0, 8, 5767213, 0, 8, 5701677, 0, 8, 5636141, 0, 8, 5570605, 0, 8, 5505069, 0, 8, 5439533, 0, 8, 5373997, 0, 8, 5308461, 0, 8, 5242925, 0, 8, 5177389, 0, 8, 5111853, 0, 8, 5046317, 0, 8, 4980781, 0, 8, 4915245, 0, 8, 4849709, 0, 8, 4784173, 0, 8, 6094892, 0, 8, 6029356, 0, 8, 5963820, 0, 8, 5898284, 0, 8, 5832748, 0, 8, 5767212, 0, 8, 5701676, 0, 8, 5636140, 0, 8, 5570604, 0, 8, 5505068, 0, 8, 5439532, 0, 8, 5373996, 0, 8, 5308460, 0, 8, 5242924, 0, 8, 5177388, 0, 8, 5111852, 0, 8, 5046316, 0, 8, 4980780, 0, 8, 4915244, 0, 8, 4849708, 0, 8, 4784172, 0, 8, 6094891, 0, 8, 6029355, 0, 8, 5963819, 0, 8, 5898283, 0, 8, 5832747, 0, 8, 5767211, 0, 8, 5701675, 0, 8, 5636139, 0, 8, 5570603, 0, 8, 5505067, 0, 8, 5439531, 0, 8, 5373995, 0, 8, 5308459, 0, 8, 5242923, 0, 8, 5177387, 0, 8, 5111851, 0, 8, 5046315, 0, 8, 4980779, 0, 8, 4915243, 0, 8, 4849707, 0, 8, 4784171, 0, 8, 6094890, 0, 8, 6029354, 0, 8, 5963818, 0, 8, 5898282, 0, 8, 5832746, 0, 8, 5767210, 0, 8, 5701674, 0, 8, 5636138, 0, 8, 5570602, 0, 8, 5505066, 0, 8, 5439530, 0, 8, 5373994, 0, 8, 5308458, 0, 8, 5242922, 0, 8, 5177386, 0, 8, 5111850, 0, 8, 5046314, 0, 8, 4980778, 0, 8, 4915242, 0, 8, 4849706, 0, 8, 4784170, 0, 8, 6094889, 0, 8, 6029353, 0, 8, 5963817, 0, 8, 5898281, 0, 8, 5832745, 0, 8, 5767209, 0, 8, 5701673, 0, 8, 5636137, 0, 8, 5570601, 0, 8, 5505065, 0, 8, 5439529, 0, 8, 5373993, 0, 8, 5308457, 0, 8, 5242921, 0, 8, 5177385, 0, 8, 5111849, 0, 8, 5046313, 0, 8, 4980777, 0, 8, 4915241, 0, 8, 4849705, 0, 8, 4784169, 0, 8, 6094888, 0, 8, 6029352, 0, 8, 5963816, 0, 8, 5898280, 0, 8, 5832744, 0, 8, 5767208, 0, 8, 5701672, 0, 8, 5636136, 0, 8, 5570600, 0, 8, 5505064, 0, 8, 5439528, 0, 8, 5373992, 0, 8, 5308456, 0, 8, 5242920, 0, 8, 5177384, 0, 8, 5111848, 0, 8, 5046312, 0, 8, 4980776, 0, 8, 4915240, 0, 8, 4849704, 0, 8, 4784168, 0, 8, 6094887, 0, 8, 6029351, 0, 8, 5963815, 0, 8, 5898279, 0, 8, 5832743, 0, 8, 5767207, 0, 8, 5701671, 0, 8, 5636135, 0, 8, 5570599, 0, 8, 5505063, 0, 8, 5439527, 0, 8, 5373991, 0, 8, 5308455, 0, 8, 5242919, 0, 8, 5177383, 0, 8, 5111847, 0, 8, 5046311, 0, 8, 4980775, 0, 8, 4915239, 0, 8, 4849703, 0, 8, 4784167, 0, 8, 6094886, 0, 8, 6029350, 0, 8, 5963814, 0, 8, 5898278, 0, 8, 5832742, 0, 8, 5767206, 0, 8, 5701670, 0, 8, 5636134, 0, 8, 5570598, 0, 8, 5505062, 0, 8, 5439526, 0, 8, 5373990, 0, 8, 5308454, 0, 8, 5242918, 0, 8, 5177382, 0, 8, 5111846, 0, 8, 5046310, 0, 8, 4980774, 0, 8, 4915238, 0, 8, 4849702, 0, 8, 4784166, 0, 8, 6094885, 0, 8, 6029349, 0, 8, 5963813, 0, 8, 5898277, 0, 8, 5832741, 0, 8, 5767205, 0, 8, 5701669, 0, 8, 5636133, 0, 8, 5570597, 0, 8, 5505061, 0, 8, 5439525, 0, 8, 5373989, 0, 8, 5308453, 0, 8, 5242917, 0, 8, 5177381, 0, 8, 5111845, 0, 8, 5046309, 0, 8, 4980773, 0, 8, 4915237, 0, 8, 4849701, 0, 8, 4784165, 0, 8, 6094884, 0, 8, 6029348, 0, 8, 5963812, 0, 8, 5898276, 0, 8, 5832740, 0, 8, 5767204, 0, 8, 5701668, 0, 8, 5636132, 0, 8, 5570596, 0, 8, 5505060, 0, 8, 5439524, 0, 8, 5373988, 0, 8, 5308452, 0, 8, 5242916, 0, 8, 5177380, 0, 8, 5111844, 0, 8, 5046308, 0, 8, 4980772, 0, 8, 4915236, 0, 8, 4849700, 0, 8, 4784164, 0, 8, 6094883, 0, 8, 6029347, 0, 8, 5963811, 0, 8, 5898275, 0, 8, 5832739, 0, 8, 5767203, 0, 8, 5701667, 0, 8, 5636131, 0, 8, 5570595, 0, 8, 5505059, 0, 8, 5439523, 0, 8, 5373987, 0, 8, 5308451, 0, 8, 5242915, 0, 8, 5177379, 0, 8, 5111843, 0, 8, 5046307, 0, 8, 4980771, 0, 8, 4915235, 0, 8, 4849699, 0, 8, 4784163, 0, 8, 6094882, 0, 8, 6029346, 0, 8, 5963810, 0, 8, 5898274, 0, 8, 5832738, 0, 8, 5767202, 0, 8, 5701666, 0, 8, 5636130, 0, 8, 5570594, 0, 8, 5505058, 0, 8, 5439522, 0, 8, 5373986, 0, 8, 5308450, 0, 8, 5242914, 0, 8, 5177378, 0, 8, 5111842, 0, 8, 5046306, 0, 8, 4980770, 0, 8, 4915234, 0, 8, 4849698, 0, 8, 4784162, 0, 8, 6094881, 0, 8, 6029345, 0, 8, 5963809, 0, 8, 5898273, 0, 8, 5832737, 0, 8, 5767201, 0, 8, 5701665, 0, 8, 5636129, 0, 8, 5570593, 0, 8, 5505057, 0, 8, 5439521, 0, 8, 5373985, 0, 8, 5308449, 0, 8, 5242913, 0, 8, 5177377, 0, 8, 5111841, 0, 8, 5046305, 0, 8, 4980769, 0, 8, 4915233, 0, 8, 4849697, 0, 8, 4784161, 0, 8, 6094880, 0, 8, 6029344, 0, 8, 5963808, 0, 8, 5898272, 0, 8, 5832736, 0, 8, 5767200, 0, 8, 5701664, 0, 8, 5636128, 0, 8, 5570592, 0, 8, 5505056, 0, 8, 5439520, 0, 8, 5373984, 0, 8, 5308448, 0, 8, 5242912, 0, 8, 5177376, 0, 8, 5111840, 0, 8, 5046304, 0, 8, 6094879, 0, 8, 6029343, 0, 8, 5963807, 0, 8, 5898271, 0, 8, 5832735, 0, 8, 5767199, 0, 8, 5701663, 0, 8, 5636127, 0, 8, 5570591, 0, 8, 5505055, 0, 8, 5439519, 0, 8, 5373983, 0, 8, 5308447, 0, 8, 5242911, 0, 8, 5177375, 0, 8, 5111839, 0, 8, 5046303, 0, 8, 6094878, 0, 8, 6029342, 0, 8, 5963806, 0, 8, 5898270, 0, 8, 5832734, 0, 8, 5767198, 0, 8, 5701662, 0, 8, 5636126, 0, 8, 5570590, 0, 8, 5505054, 0, 8, 5439518, 0, 8, 5373982, 0, 8, 5308446, 0, 8, 5242910, 0, 8, 5177374, 0, 8, 5111838, 0, 8, 5046302, 0, 8, 6094877, 0, 8, 6029341, 0, 8, 5963805, 0, 8, 5898269, 0, 8, 5832733, 0, 8, 5767197, 0, 8, 5701661, 0, 8, 5636125, 0, 8, 5570589, 0, 8, 5505053, 0, 8, 5439517, 0, 8, 5373981, 0, 8, 5308445, 0, 8, 5242909, 0, 8, 5177373, 0, 8, 5111837, 0, 8, 5046301, 0, 8, 6094876, 0, 8, 6029340, 0, 8, 5963804, 0, 8, 5898268, 0, 8, 5832732, 0, 8, 5767196, 0, 8, 5701660, 0, 8, 5636124, 0, 8, 5570588, 0, 8, 5505052, 0, 8, 5439516, 0, 8, 5373980, 0, 8, 5308444, 0, 8, 5242908, 0, 8, 5177372, 0, 8, 5111836, 0, 8, 5046300, 0, 8, 6094875, 0, 8, 6029339, 0, 8, 5963803, 0, 8, 5898267, 0, 8, 5832731, 0, 8, 5767195, 0, 8, 5701659, 0, 8, 5636123, 0, 8, 5570587, 0, 8, 5505051, 0, 8, 5439515, 0, 8, 5373979, 0, 8, 5308443, 0, 8, 5242907, 0, 8, 5177371, 0, 8, 5111835, 0, 8, 5046299, 0, 8, 6094874, 0, 8, 6029338, 0, 8, 5963802, 0, 8, 5898266, 0, 8, 5832730, 0, 8, 5767194, 0, 8, 5701658, 0, 8, 5636122, 0, 8, 5570586, 0, 8, 5505050, 0, 8, 5439514, 0, 8, 5373978, 0, 8, 5308442, 0, 8, 5242906, 0, 8, 5177370, 0, 8, 5111834, 0, 8, 5046298, 0, 8, 6094873, 0, 8, 6029337, 0, 8, 5963801, 0, 8, 5898265, 0, 8, 5832729, 0, 8, 5767193, 0, 8, 5701657, 0, 8, 5636121, 0, 8, 5570585, 0, 8, 5505049, 0, 8, 5439513, 0, 8, 5373977, 0, 8, 5308441, 0, 8, 5242905, 0, 8, 5177369, 0, 8, 5111833, 0, 8, 5046297, 0, 8, 6094872, 0, 8, 6029336, 0, 8, 5963800, 0, 8, 5898264, 0, 8, 5832728, 0, 8, 5767192, 0, 8, 5701656, 0, 8, 5636120, 0, 8, 5570584, 0, 8, 5505048, 0, 8, 5439512, 0, 8, 5373976, 0, 8, 5308440, 0, 8, 5242904, 0, 8, 5177368, 0, 8, 5111832, 0, 8, 5046296, 0, 8, 6094871, 0, 8, 6029335, 0, 8, 5963799, 0, 8, 5898263, 0, 8, 5832727, 0, 8, 5767191, 0, 8, 5701655, 0, 8, 5636119, 0, 8, 5570583, 0, 8, 5505047, 0, 8, 5439511, 0, 8, 5373975, 0, 8, 5308439, 0, 8, 5242903, 0, 8, 5177367, 0, 8, 5111831, 0, 8, 5046295, 0, 8, 6094870, 0, 8, 6029334, 0, 8, 5963798, 0, 8, 5898262, 0, 8, 5832726, 0, 8, 5767190, 0, 8, 5701654, 0, 8, 5636118, 0, 8, 5570582, 0, 8, 5505046, 0, 8, 5439510, 0, 8, 5373974, 0, 8, 5308438, 0, 8, 5242902, 0, 8, 5177366, 0, 8, 5111830, 0, 8, 5046294, 0, 8, 6094869, 0, 8, 6029333, 0, 8, 5963797, 0, 8, 5898261, 0, 8, 5832725, 0, 8, 5767189, 0, 8, 5701653, 0, 8, 5636117, 0, 8, 5570581, 0, 8, 5505045, 0, 8, 5439509, 0, 8, 5373973, 0, 8, 5308437, 0, 8, 5242901, 0, 8, 5177365, 0, 8, 5111829, 0, 8, 5046293, 0, 8, 6094868, 0, 8, 6029332, 0, 8, 5963796, 0, 8, 5898260, 0, 8, 5832724, 0, 8, 5767188, 0, 8, 5701652, 0, 8, 5636116, 0, 8, 5570580, 0, 8, 5505044, 0, 8, 5439508, 0, 8, 5373972, 0, 8, 5308436, 0, 8, 5242900, 0, 8, 5177364, 0, 8, 5111828, 0, 8, 5046292, 0, 8, 6094867, 0, 8, 6029331, 0, 8, 5963795, 0, 8, 5898259, 0, 8, 5832723, 0, 8, 5767187, 0, 8, 5701651, 0, 8, 5636115, 0, 8, 5570579, 0, 8, 5505043, 0, 8, 5439507, 0, 8, 5373971, 0, 8, 5308435, 0, 8, 5242899, 0, 8, 5177363, 0, 8, 5111827, 0, 8, 5046291, 0, 8, 5046290, 196608, 3, 5111826, 196608, 3, 5177362, 196608, 3, 5242898, 196608, 3, 5308434, 196608, 3, 5373970, 196608, 3, 5439506, 196608, 3, 5505042, 196608, 3, 5570578, 196608, 3, 5636114, 196608, 3, 5701650, 196608, 3, 5767186, 196608, 3, 5832722, 196608, 3, 5898258, 196608, 3, 5963794, 196608, 3, 6029330, 196608, 3, 6094866, 196608, 3, 6160404, 131072, 2, 6160402, 720896, 2, 6160405, 131072, 2, 6160403, 131072, 2, 6160406, 131072, 2, 6160407, 131072, 2, 6160408, 131072, 2, 6160409, 131072, 2, 6160410, 131072, 2, 6160411, 131072, 2, 6160412, 131072, 2, 6160413, 131072, 2, 6160414, 131072, 2, 6160415, 131072, 2, 6160416, 131072, 2, 4718625, 131072, 7, 6160417, 131072, 2, 4718626, 131072, 7, 6160418, 131072, 2, 4718627, 131072, 7, 6160419, 131072, 2, 4718628, 131072, 7, 6160420, 131072, 2, 4718629, 131072, 7, 6160421, 131072, 2, 4718630, 131072, 7, 6160422, 131072, 2, 4718631, 131072, 7, 6160423, 131072, 2, 4718632, 131072, 7, 6160424, 131072, 2, 4718633, 131072, 7, 6160425, 131072, 2, 4718634, 131072, 7, 6160426, 131072, 2, 4718635, 131072, 7, 6160427, 131072, 2, 4718636, 131072, 7, 6160428, 131072, 2, 4718637, 131072, 7, 6160429, 131072, 2, 4718638, 131072, 7, 6160430, 131072, 2, 4718639, 131072, 7, 6160431, 131072, 2, 4718640, 131072, 7, 6160432, 131072, 2, 4718641, 131072, 7, 6160433, 131072, 2, 4718642, 131072, 7, 6160434, 131072, 2, 4718643, 131072, 7, 6160435, 131072, 2, 4718644, 131072, 7, 6160436, 131072, 2, 4718645, 131072, 7, 6160437, 131072, 2, 4718646, 131072, 7, 6160438, 131072, 2, 4718647, 131072, 7, 6160439, 131072, 2, 4718648, 131072, 7, 6160440, 131072, 2, 4718649, 131072, 7, 6160441, 131072, 2, 6160442, 131072, 2, 6160443, 131072, 2, 6160444, 131072, 2, 6160445, 131072, 2, 6160446, 131072, 2, 6160447, 131072, 2, 6160448, 131072, 2, 6160449, 131072, 2, 5046338, 65536, 3, 5111874, 65536, 3, 5177410, 65536, 3, 5242946, 65536, 3, 5308482, 65536, 3, 5374018, 65536, 3, 5439554, 65536, 3, 5505090, 65536, 3, 5570626, 65536, 3, 5636162, 65536, 3, 5701698, 65536, 3, 5767234, 65536, 3, 5832770, 65536, 3, 5898306, 65536, 3, 5963842, 65536, 3, 6029378, 65536, 3, 6094914, 65536, 3, 6160450, 851968, 2) + +[node name="Camera2D" type="Camera2D" parent="."] +position = Vector2(0, -1) +rotation = 0.798384 +process_callback = 0 + +[node name="Root" type="Node2D" parent="."] + +[node name="Shell" type="Sprite2D" parent="Root"] +position = Vector2(113, 64) +texture = ExtResource("3_kc4l0") + +[node name="Shell2" type="Sprite2D" parent="Root"] +position = Vector2(150.78, 64.17) +texture = ExtResource("3_kc4l0") + +[node name="Shell3" type="Sprite2D" parent="Root"] +position = Vector2(129.23, 76.25) +rotation = -0.439823 +texture = ExtResource("3_kc4l0") + +[node name="Shell4" type="Sprite2D" parent="Root"] +position = Vector2(145.335, 92.68) +rotation = -3.64425 +texture = ExtResource("3_kc4l0") + +[node name="Shell5" type="Sprite2D" parent="Root"] +position = Vector2(116.22, 94.035) +rotation = 1.66679 +scale = Vector2(1.24, 1.24) +texture = ExtResource("3_kc4l0") + +[node name="Shell6" type="Sprite2D" parent="Root"] +position = Vector2(132.43, 58.21) +rotation = 0.785398 +scale = Vector2(1.265, 1.265) +texture = ExtResource("3_kc4l0") + +[node name="Shell7" type="Sprite2D" parent="Root"] +position = Vector2(169.315, 56.36) +texture = ExtResource("3_kc4l0") + +[node name="Player" type="CharacterBody2D" parent="Root"] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Root/Player"] +shape = SubResource("RectangleShape2D_tmsub") + +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="Root/Player"] +sprite_frames = ExtResource("4_6nerw") +animation = &"idle" +autoplay = "idle" + +[node name="CanvasLayer" type="CanvasLayer" parent="."] + +[node name="FPS" type="Label" parent="CanvasLayer"] +offset_left = 16.0 +offset_top = 11.0 +offset_right = 25.0 +offset_bottom = 51.0 diff --git a/DungeonShooting_Godot/src/config/ExcelConfig.cs b/DungeonShooting_Godot/src/config/ExcelConfig.cs index f9d7eaf..32a1ea5 100644 --- a/DungeonShooting_Godot/src/config/ExcelConfig.cs +++ b/DungeonShooting_Godot/src/config/ExcelConfig.cs @@ -44,6 +44,15 @@ public static Dictionary BulletBase_Map { get; private set; } /// + /// EnemyBase.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同 + /// + public static List EnemyBase_List { get; private set; } + /// + /// EnemyBase.xlsx表数据集合, 里 Map 形式存储, key 为 Id + /// + public static Dictionary EnemyBase_Map { get; private set; } + + /// /// Sound.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同 /// public static List Sound_List { get; private set; } @@ -75,10 +84,12 @@ _InitActivityMaterialConfig(); _InitAiAttackAttrConfig(); _InitBulletBaseConfig(); + _InitEnemyBaseConfig(); _InitSoundConfig(); _InitWeaponBaseConfig(); _InitActivityBaseRef(); + _InitEnemyBaseRef(); _InitWeaponBaseRef(); } private static void _InitActivityBaseConfig() @@ -153,6 +164,24 @@ throw new Exception("初始化表'BulletBase'失败!"); } } + private static void _InitEnemyBaseConfig() + { + try + { + var text = _ReadConfigAsText("res://resource/config/EnemyBase.json"); + EnemyBase_List = new List(JsonSerializer.Deserialize>(text)); + EnemyBase_Map = new Dictionary(); + foreach (var item in EnemyBase_List) + { + EnemyBase_Map.Add(item.Id, item); + } + } + catch (Exception e) + { + GD.PrintErr(e.ToString()); + throw new Exception("初始化表'EnemyBase'失败!"); + } + } private static void _InitSoundConfig() { try @@ -209,6 +238,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) diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_ActivityMaterial.cs b/DungeonShooting_Godot/src/config/ExcelConfig_ActivityMaterial.cs index d0d756b..f3fa9c6 100644 --- a/DungeonShooting_Godot/src/config/ExcelConfig_ActivityMaterial.cs +++ b/DungeonShooting_Godot/src/config/ExcelConfig_ActivityMaterial.cs @@ -26,6 +26,21 @@ public float Friction; /// + /// 重力缩放,如果为0则会关闭重力 + /// + [JsonInclude] + public float GravityScale; + + /// + /// 物体旋转控制类型:
+ /// 0.不受运动影响
+ /// 1.只受水平方向运动速度影响
+ /// 2.受水平和垂直运动方向影响, 可以做迫击炮炮弹的效果 + ///
+ [JsonInclude] + public byte RotationType; + + /// /// 旋转摩擦力 /// [JsonInclude] @@ -62,6 +77,12 @@ public float FallBounceRotation; /// + /// 动态开关碰撞器,在物体高度大于16时是否关闭碰撞检测 + /// + [JsonInclude] + public bool DynamicCollision; + + /// /// 返回浅拷贝出的新对象 /// public ActivityMaterial Clone() @@ -70,12 +91,15 @@ inst.Id = Id; inst.Remark = Remark; inst.Friction = Friction; + inst.GravityScale = GravityScale; + inst.RotationType = RotationType; inst.RotationFriction = RotationFriction; inst.Bounce = Bounce; inst.BounceStrength = BounceStrength; inst.FallBounceStrength = FallBounceStrength; inst.FallBounceSpeed = FallBounceSpeed; inst.FallBounceRotation = FallBounceRotation; + inst.DynamicCollision = DynamicCollision; return inst; } } diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs b/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs index 0dceead..c3c734c 100644 --- a/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs +++ b/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs @@ -20,6 +20,12 @@ public string Remark; /// + /// 锁定目标时是否站立不动 + /// + [JsonInclude] + public bool LockingStand; + + /// /// 开火时是否站立不动 /// [JsonInclude] @@ -75,6 +81,7 @@ var inst = new AiAttackAttr(); inst.Id = Id; inst.Remark = Remark; + inst.LockingStand = LockingStand; inst.FiringStand = FiringStand; inst.ShowSubline = ShowSubline; inst.LockingTime = LockingTime; diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_BulletBase.cs b/DungeonShooting_Godot/src/config/ExcelConfig_BulletBase.cs index dce87f4..549ed11 100644 --- a/DungeonShooting_Godot/src/config/ExcelConfig_BulletBase.cs +++ b/DungeonShooting_Godot/src/config/ExcelConfig_BulletBase.cs @@ -84,13 +84,6 @@ public float[] DistanceRange; /// - /// 是否开启重力下坠
- /// 只有Type为1时有效 - ///
- [JsonInclude] - public bool UseGravity; - - /// /// 初始纵轴速度区间
/// 只有Type为1时有效
/// 格式为[value]或者[min,max] @@ -130,7 +123,6 @@ inst.SpeedRange = SpeedRange; inst.LifeTimeRange = LifeTimeRange; inst.DistanceRange = DistanceRange; - inst.UseGravity = UseGravity; inst.VerticalSpeed = VerticalSpeed; inst.BounceCount = BounceCount; inst.Penetration = Penetration; diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_EnemyBase.cs b/DungeonShooting_Godot/src/config/ExcelConfig_EnemyBase.cs new file mode 100644 index 0000000..cedad80 --- /dev/null +++ b/DungeonShooting_Godot/src/config/ExcelConfig_EnemyBase.cs @@ -0,0 +1,94 @@ +using System.Text.Json.Serialization; +using System.Collections.Generic; + +namespace Config; + +public static partial class ExcelConfig +{ + public class EnemyBase + { + /// + /// 表Id + /// + [JsonInclude] + public string Id; + + /// + /// 绑定的ActivityBase表数据 + /// + public ActivityBase Activity; + + /// + /// 备注 + /// + [JsonInclude] + public string Remark; + + /// + /// 移动速度 + /// + [JsonInclude] + public float MoveSpeed; + + /// + /// 移动加速度 + /// + [JsonInclude] + public float Acceleration; + + /// + /// 移动摩擦力, 仅用于人物基础移动 + /// + [JsonInclude] + public float Friction; + + /// + /// 是否可以拾起武器 + /// + [JsonInclude] + public bool CanPickUpWeapon; + + /// + /// 视野半径, 单位像素, 发现玩家后改视野范围可以穿墙 + /// + [JsonInclude] + public float ViewRange; + + /// + /// 发现玩家后跟随玩家的视野半径 + /// + [JsonInclude] + public float TailAfterViewRange; + + /// + /// 背后的视野半径, 单位像素 + /// + [JsonInclude] + public float BackViewRange; + + /// + /// 返回浅拷贝出的新对象 + /// + public EnemyBase Clone() + { + var inst = new EnemyBase(); + inst.Id = Id; + inst.Activity = Activity; + inst.Remark = Remark; + inst.MoveSpeed = MoveSpeed; + inst.Acceleration = Acceleration; + inst.Friction = Friction; + inst.CanPickUpWeapon = CanPickUpWeapon; + inst.ViewRange = ViewRange; + inst.TailAfterViewRange = TailAfterViewRange; + inst.BackViewRange = BackViewRange; + return inst; + } + } + private class Ref_EnemyBase : EnemyBase + { + [JsonInclude] + public string __Activity; + + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs index 44ba25a..e4b4f57 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -10,7 +10,8 @@ /// 该类提供基础物体运动模拟, 互动接口, 自定义组件, 协程等功能
/// ActivityObject 子类实例化请不要直接使用 new, 而用该在类上标上 [Tool], 并在 ActivityObject.xlsx 配置文件中注册物体, 导出配置表后使用 ActivityObject.Create(id) 来创建实例.
///
-public abstract partial class ActivityObject : CharacterBody2D, IDestroy, ICoroutine +[Tool] +public partial class ActivityObject : CharacterBody2D, IDestroy, ICoroutine { /// /// 是否是调试模式 @@ -18,9 +19,14 @@ public static bool IsDebug { get; set; } /// + /// 实例唯一 Id + /// + public long Id { get; set; } + + /// /// 当前物体对应的配置数据, 如果不是通过 ActivityObject.Create() 函数创建出来的对象那么 ItemConfig 为 null /// - public ExcelConfig.ActivityBase ItemConfig { get; private set; } + public ExcelConfig.ActivityBase ActivityBase { get; private set; } /// /// 是否是静态物体, 如果为true, 则会禁用移动处理 @@ -68,6 +74,7 @@ /// /// 阴影偏移 /// + [Export] public Vector2 ShadowOffset { get; protected set; } = new Vector2(0, 2); /// @@ -163,11 +170,6 @@ /// 是否启用垂直方向上的运动模拟, 默认开启, 如果禁用, 那么下落和投抛效果, 同样 Throw() 函数也将失效 /// public bool EnableVerticalMotion { get; set; } = true; - - /// - /// 撞到墙壁反弹时是否锁定旋转角度, 如果为 false, 则反弹后将直接修改旋转角度 - /// - public bool BounceLockRotation { get; set; } = true; /// /// 是否启用物体更新行为, 默认 true, 如果禁用, 则会停止当前物体的 Process(), PhysicsProcess() 调用, 并且禁用 Collision 节点, 禁用后所有组件也同样被禁用行为 @@ -215,21 +217,11 @@ /// public bool ShowOutline { - get => _showOutline; + get => _blendShaderMaterial == null ? false : _blendShaderMaterial.GetShaderParameter(_shader_show_outline).AsBool(); set { - if (_blendShaderMaterial != null) - { - if (value != _showOutline) - { - _blendShaderMaterial.SetShaderParameter("show_outline", value); - if (_shadowBlendShaderMaterial != null) - { - _shadowBlendShaderMaterial.SetShaderParameter("show_outline", value); - } - _showOutline = value; - } - } + _blendShaderMaterial?.SetShaderParameter(_shader_show_outline, value); + _shadowBlendShaderMaterial?.SetShaderParameter(_shader_show_outline, value); } } @@ -238,33 +230,25 @@ /// public Color OutlineColor { - get - { - if (!_initOutlineColor) - { - _initOutlineColor = true; - if (_blendShaderMaterial != null) - { - _outlineColor = _blendShaderMaterial.GetShaderParameter("outline_color").AsColor(); - } - } + get => _blendShaderMaterial == null ? Colors.Black : _blendShaderMaterial.GetShaderParameter(_shader_outline_color).AsColor(); + set => _blendShaderMaterial?.SetShaderParameter(_shader_outline_color, value); + } - return _outlineColor; - } - set - { - _initOutlineColor = true; - if (value != _outlineColor) - { - _blendShaderMaterial.SetShaderParameter("outline_color", value); - } - - _outlineColor = value; - } + /// + /// 灰度 + /// + public float Grey + { + get => _blendShaderMaterial == null ? 0 : _blendShaderMaterial.GetShaderParameter(_shader_grey).AsSingle(); + set => _blendShaderMaterial?.SetShaderParameter(_shader_grey, value); } // -------------------------------------------------------------------------------- + private static readonly StringName _shader_grey = "grey"; + private static readonly StringName _shader_outline_color = "outline_color"; + private static readonly StringName _shader_show_outline = "show_outline"; + //是否正在调用组件 Update 函数 private bool _updatingComp = false; //组件集合 @@ -321,17 +305,13 @@ private bool _processingBecomesStaticImage = false; + //击退外力 + private ExternalForce _repelForce; + // -------------------------------------------------------------------------------- //实例索引 private static long _instanceIndex = 0; - - //是否启用描边 - private bool _showOutline = false; - - //描边颜色 - private bool _initOutlineColor = false; - private Color _outlineColor = new Color(0, 0, 0, 1); //冻结显示的Sprite private FreezeSprite _freezeSprite; @@ -356,20 +336,25 @@ { ActivityMaterial = config.Material; } + + //GravityScale 为 0 时关闭重力 + if (ActivityMaterial.GravityScale == 0) + { + EnableVerticalMotion = false; + } World = world; - ItemConfig = config; + ActivityBase = config; Name = GetType().Name + (_instanceIndex++); + Id = _instanceIndex; _blendShaderMaterial = AnimatedSprite.Material as ShaderMaterial; _shadowBlendShaderMaterial = ShadowSprite.Material as ShaderMaterial; - if (_blendShaderMaterial != null) - { - _showOutline = _blendShaderMaterial.GetShaderParameter("show_outline").AsBool(); - } - if (_shadowBlendShaderMaterial != null) + + if (_shadowBlendShaderMaterial != null && _blendShaderMaterial != null) { - _shadowBlendShaderMaterial.SetShaderParameter("show_outline", _showOutline); + var value = _blendShaderMaterial.GetShaderParameter(_shader_show_outline); + _shadowBlendShaderMaterial.SetShaderParameter(_shader_show_outline, value); } ShadowSprite.Visible = false; @@ -1103,9 +1088,9 @@ var ysp = VerticalSpeed; _altitude += VerticalSpeed * delta; - _verticalSpeed -= GameConfig.G * delta; + _verticalSpeed -= GameConfig.G * ActivityMaterial.GravityScale * delta; - //当高度大于16时, 显示在所有物体上 + //当高度大于16时, 显示在所有物体上, 并且关闭碰撞 if (Altitude >= 16) { AnimatedSprite.ZIndex = 20; @@ -1114,6 +1099,11 @@ { AnimatedSprite.ZIndex = 0; } + //动态开关碰撞器 + if (ActivityMaterial.DynamicCollision) + { + Collision.Disabled = Altitude >= 16; + } //达到最高点 if (ysp > 0 && ysp * VerticalSpeed < 0) @@ -1327,6 +1317,8 @@ /// public void CalcShadowTransform() { + //偏移 + ShadowSprite.Offset = AnimatedSprite.Offset; //缩放 ShadowSprite.Scale = AnimatedSprite.Scale; //阴影角度 @@ -1715,4 +1707,58 @@ } _freezeSprite.Unfreeze(); } + + /// + /// 获取中心点坐标 + /// + public Vector2 GetCenterPosition() + { + return AnimatedSprite.Position + Position; + } + + /// + /// 设置物体朝向 + /// + public void SetFace(FaceDirection face) + { + if ((face == FaceDirection.Left && Scale.X > 0) || (face == FaceDirection.Right && Scale.X < 0)) + { + Scale *= new Vector2(-1, 1); + } + } + + /// + /// 添加一个击退力 + /// + public void AddRepelForce(Vector2 velocity) + { + if (_repelForce == null) + { + _repelForce = new ExternalForce(ForceNames.Repel); + } + + //不在 MoveController 中 + if (_repelForce.MoveController == null) + { + _repelForce.Velocity = velocity; + MoveController.AddForce(_repelForce); + } + else + { + _repelForce.Velocity += velocity; + } + } + + /// + /// 获取击退力 + /// + public Vector2 GetRepelForce() + { + if (_repelForce == null || _repelForce.MoveController == null) + { + return Vector2.Zero; + } + + return _repelForce.Velocity; + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject_EditorTool.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject_EditorTool.cs index 69f87b8..b1a033d 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject_EditorTool.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject_EditorTool.cs @@ -29,6 +29,7 @@ { var material = ResourceManager.Load(ResourcePath.resource_material_Blend_tres, false); + material.ResourceLocalToScene = true; material.SetShaderParameter("blend", new Color(0, 0, 0, 0.47058824F)); material.SetShaderParameter("schedule", 1); material.SetShaderParameter("modulate", new Color(1, 1, 1, 1)); @@ -43,6 +44,7 @@ { var material = ResourceManager.Load(ResourcePath.resource_material_Blend_tres, false); + material.ResourceLocalToScene = true; material.SetShaderParameter("blend", new Color(1, 1, 1, 1)); material.SetShaderParameter("schedule", 0); material.SetShaderParameter("modulate", new Color(1, 1, 1, 1)); diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs index a6c0b2a..02b1b5e 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Init.cs @@ -89,6 +89,11 @@ /// public const string Id_bullet0004 = "bullet0004"; /// + /// 名称: 敌方专用子弹
+ /// 简介: + ///
+ public const string Id_bullet0005 = "bullet0005"; + /// /// 名称:
/// 简介: ///
@@ -110,9 +115,14 @@ public const string Id_shell0004 = "shell0004"; /// /// 名称:
- /// 简介: 敌人死亡碎片 + /// 简介: 敌人1死亡碎片 ///
- public const string Id_effect0001 = "effect0001"; + public const string Id_enemy_dead0001 = "enemy_dead0001"; + /// + /// 名称:
+ /// 简介: 敌人2死亡 + ///
+ public const string Id_enemy_dead0002 = "enemy_dead0002"; /// /// 名称: 鞋子
/// 简介: 提高移动速度 diff --git a/DungeonShooting_Godot/src/framework/activity/Component.cs b/DungeonShooting_Godot/src/framework/activity/Component.cs index be0680d..e8fa947 100644 --- a/DungeonShooting_Godot/src/framework/activity/Component.cs +++ b/DungeonShooting_Godot/src/framework/activity/Component.cs @@ -169,7 +169,6 @@ /// /// 如果启用了组件, 则每帧会调用一次 Process /// - /// public virtual void Process(float delta) { } @@ -177,7 +176,6 @@ /// /// 如果启用了组件, 则每物理帧会调用一次 PhysicsProcess /// - /// public virtual void PhysicsProcess(float delta) { } diff --git a/DungeonShooting_Godot/src/framework/activity/ExternalForce.cs b/DungeonShooting_Godot/src/framework/activity/ExternalForce.cs index fee637c..4f06156 100644 --- a/DungeonShooting_Godot/src/framework/activity/ExternalForce.cs +++ b/DungeonShooting_Godot/src/framework/activity/ExternalForce.cs @@ -7,6 +7,11 @@ public class ExternalForce { /// + /// 所在的移动控制器 + /// + public MoveController MoveController { get; set; } + + /// /// 当前力的名称 /// public string Name { get; } diff --git a/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs b/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs index f193d53..ef0f435 100644 --- a/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs +++ b/DungeonShooting_Godot/src/framework/activity/components/MoveController.cs @@ -210,6 +210,7 @@ public T AddForce(T force) where T : ExternalForce { RemoveForce(force.Name); + force.MoveController = this; _forceList.Add(force); return force; } @@ -223,6 +224,7 @@ { if (_forceList[i].Name == name) { + _forceList[i].MoveController = null; _forceList.RemoveAt(i); return; } @@ -276,6 +278,11 @@ ///
public void ClearForce() { + foreach (var force in _forceList) + { + force.MoveController = null; + } + _forceList.Clear(); } @@ -305,6 +312,7 @@ //自动销毁 if (CheckAutoDestroy(force)) { + force.MoveController = null; _forceList.Remove(force); externalForces[i] = null; } @@ -347,20 +355,16 @@ //新速度 var newVelocity = Master.Velocity; - if (!Master.BounceLockRotation) //跟着反弹角度 - { - Rotation = newVelocity.Angle(); - } - if (newVelocity.X == 0f && _basisVelocity.X * finallyVelocity.X > 0) - { - _basisVelocity.X = 0; - } - - if (newVelocity.Y == 0f && _basisVelocity.Y * finallyVelocity.Y > 0) - { - _basisVelocity.Y = 0; - } + // if (newVelocity.X == 0f && _basisVelocity.X * finallyVelocity.X > 0) + // { + // _basisVelocity.X = 0; + // } + // + // if (newVelocity.Y == 0f && _basisVelocity.Y * finallyVelocity.Y > 0) + // { + // _basisVelocity.Y = 0; + // } //是否撞到物体 KinematicCollision2D collision; @@ -379,10 +383,15 @@ newVelocity = finallyEf.Reflect(no); var rotation = newVelocity.Angle(); - if (!Master.BounceLockRotation) //跟着反弹角度 + if (Master.ActivityMaterial.RotationType == 1) //跟着反弹角度 { Rotation = rotation; } + else if (Master.ActivityMaterial.RotationType == 2) //跟着反弹角度, 带垂直角度 + { + Rotation = rotation; + AnimatedSprite.Rotation = new Vector2(newVelocity.X, newVelocity.Y - Master.VerticalSpeed).Angle() - rotation; + } var length = _forceList.Count; if (length != 0) @@ -399,6 +408,16 @@ } else //没有撞到物体 { + if (Master.ActivityMaterial.RotationType == 1) //跟着反弹角度 + { + Rotation = newVelocity.Angle(); + } + else if (Master.ActivityMaterial.RotationType == 2) //跟着反弹角度, 带垂直角度 + { + var rotation = Rotation = newVelocity.Angle(); + AnimatedSprite.Rotation = new Vector2(newVelocity.X, newVelocity.Y - Master.VerticalSpeed).Angle() - rotation; + } + //调整外力速率 for (var i = 0; i < _forceList.Count; i++) { diff --git a/DungeonShooting_Godot/src/framework/activity/components/StateBase.cs b/DungeonShooting_Godot/src/framework/activity/components/StateBase.cs index ce71a11..42a8e57 100644 --- a/DungeonShooting_Godot/src/framework/activity/components/StateBase.cs +++ b/DungeonShooting_Godot/src/framework/activity/components/StateBase.cs @@ -49,15 +49,6 @@ } /// - /// 是否允许切换至下一个状态, 该函数由状态机控制器调用, 不需要手动调用 - /// - /// 下一个状态类型 - public virtual bool CanChangeState(S next) - { - return true; - } - - /// /// 从当前状态退出时调用 /// /// 下一个状态类型 diff --git a/DungeonShooting_Godot/src/framework/activity/components/StateController.cs b/DungeonShooting_Godot/src/framework/activity/components/StateController.cs index d33027c..942dd5f 100644 --- a/DungeonShooting_Godot/src/framework/activity/components/StateController.cs +++ b/DungeonShooting_Godot/src/framework/activity/components/StateController.cs @@ -133,8 +133,9 @@ CurrStateBase = newState; newState.Enter(default, arg); } - else if (CurrStateBase.CanChangeState(next)) + else { + // Debug.Log($"changeState: {CurrState} => {next}"); _isChangeState = !late; var prev = CurrStateBase.State; CurrStateBase.Exit(next); diff --git a/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs b/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs index 18371c0..d902fe9 100644 --- a/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs +++ b/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs @@ -23,7 +23,7 @@ for (var i = 0; i < pairs.Length; i++) { var item = pairs[i]; - try + //try { var canNext = true; @@ -131,11 +131,11 @@ } } } - catch (Exception e) - { - Debug.LogError("执行协程发生异常: \n" + e); - ProxyStopCoroutine(ref coroutineList, item.Id); - } + // catch (Exception e) + // { + // Debug.LogError("执行协程发生异常: \n" + e); + // ProxyStopCoroutine(ref coroutineList, item.Id); + // } } } diff --git a/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs b/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs index fe66f00..ddec291 100644 --- a/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs +++ b/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs @@ -90,7 +90,7 @@ //如果是玩家 if (activityObject == Player.Current) { - OnPlayerInsertRoom(); + CallDeferred(nameof(OnPlayerInsertRoom)); } } @@ -114,7 +114,7 @@ { return _includeItems.Count; } - + /// /// 统计符合条件的数量 /// @@ -224,6 +224,37 @@ return false; } + + /// + /// 遍历该该区域的物体 + /// + /// 操作函数, 返回 false 表示跳出循环 + public void ForEachIncludeItems(Func handler) + { + foreach (var activityObject in _includeItems) + { + if (!activityObject.IsDestroyed && handler(activityObject)) + { + return; + } + } + } + + /// + /// 遍历该进入该区域的物体 + /// + /// 操作函数, 返回 false 表示跳出循环 + public void ForEachEnterItems(Func handler) + { + foreach (var activityObject in _enterItems) + { + if (!activityObject.IsDestroyed && handler(activityObject)) + { + return; + } + } + } + /// /// 返回物体是否进入了该区域 @@ -238,8 +269,7 @@ if (body is ActivityObject activityObject) { _enterItems.Add(activityObject); - //注意需要延时调用 - CallDeferred(nameof(InsertItem), activityObject); + InsertItem(activityObject); } } diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs index ff5d0c9..fdc3258 100644 --- a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs +++ b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs @@ -297,6 +297,13 @@ //播放出生动画 activityObject.StartCoroutine(OnActivityObjectBirth(activityObject)); activityObject.PutDown(GetDefaultLayer(activityMark)); + activityObject.UpdateFall((float)GameApplication.Instance.GetProcessDeltaTime()); + + if (activityObject is Enemy enemy) + { + //出生调用 + enemy.OnBornFromMark(); + } var effect = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_common_Effect1_tscn); var node = (Node2D)effect; @@ -431,7 +438,7 @@ else if (activityMark.ActivityType == ActivityType.Enemy) //敌人类型 { var role = (Role)activityObject; - if (role is AdvancedEnemy enemy && activityMark.Attr.TryGetValue("Weapon", out var weaponId)) //使用的武器 + if (role is Enemy enemy && activityMark.Attr.TryGetValue("Weapon", out var weaponId)) //使用的武器 { if (!string.IsNullOrEmpty(weaponId)) { diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs b/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs index 9541c00..5af5be5 100644 --- a/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs +++ b/DungeonShooting_Godot/src/framework/map/preinstall/SpecialMarkType.cs @@ -5,7 +5,7 @@ public enum SpecialMarkType { /// - /// 正常类型 + /// 普通标记 /// Normal, /// diff --git a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs index a249dda..39bb1f9 100644 --- a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs @@ -104,6 +104,11 @@ /// 是否处于闭关状态, 也就是房间门没有主动打开 /// public bool IsSeclusion { get; private set; } = false; + + /// + /// 用于标记攻击目标位置 + /// + public Dictionary MarkTargetPosition { get; private set; } = new Dictionary(); public bool IsDestroyed { get; private set; } private bool _openDoorFlag = true; @@ -340,6 +345,8 @@ { AffiliationArea.Destroy(); } + + MarkTargetPosition.Clear(); } /// diff --git a/DungeonShooting_Godot/src/game/AnimatorNames.cs b/DungeonShooting_Godot/src/game/AnimatorNames.cs index b393c9f..bf3d97d 100644 --- a/DungeonShooting_Godot/src/game/AnimatorNames.cs +++ b/DungeonShooting_Godot/src/game/AnimatorNames.cs @@ -1,4 +1,6 @@ +using Godot; + /// /// 预制动画名称 /// @@ -7,65 +9,85 @@ /// /// 默认动画 /// - public const string Default = "default"; + public static readonly StringName Default = "default"; /// /// 静止不动 /// - public const string Idle = "idle"; + public static readonly StringName Idle = "idle"; /// /// 奔跑 /// - public const string Run = "run"; + public static readonly StringName Run = "run"; /// /// 倒退奔跑 /// - public const string ReverseRun = "reverseRun"; + public static readonly StringName ReverseRun = "reverseRun"; /// /// 翻滚 /// - public const string Roll = "roll"; + public static readonly StringName Roll = "roll"; /// /// 武器泛光动画 /// - public const string Floodlight = "floodlight"; + public static readonly StringName Floodlight = "floodlight"; /// /// 开门动画 /// - public const string OpenDoor = "openDoor"; + public static readonly StringName OpenDoor = "openDoor"; /// /// 关门动画 /// - public const string CloseDoor = "closeDoor"; + public static readonly StringName CloseDoor = "closeDoor"; /// /// 开火 /// - public const string Fire = "fire"; + public static readonly StringName Fire = "fire"; /// /// 换弹 /// - public const string Reloading = "reloading"; + public static readonly StringName Reloading = "reloading"; /// /// 子弹上膛 /// - public const string BeLoaded = "beLoaded"; + public static readonly StringName BeLoaded = "beLoaded"; /// /// ui入场 /// - public const string In = "in"; + public static readonly StringName In = "in"; /// /// ui出场 /// - public const string Out = "out"; + public static readonly StringName Out = "out"; /// /// 显示动画 /// - public const string Show = "show"; + public static readonly StringName Show = "show"; /// /// 播放特效 /// - public const string Play = "play"; + public static readonly StringName Play = "play"; /// /// 物体移动 /// - public const string Move = "move"; + public static readonly StringName Move = "move"; + /// + /// 攻击 + /// + public static readonly StringName Attack = "attack"; + /// + /// 惊讶动作 + /// + public static readonly StringName Astonished = "astonished"; + /// + /// 通知动作 + /// + public static readonly StringName Notify = "notify"; + /// + /// 疑惑动作 + /// + public static readonly StringName Query = "query"; + /// + /// 重置动画 + /// + public static readonly StringName Reset = "RESET"; } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/Cursor.cs b/DungeonShooting_Godot/src/game/Cursor.cs index 7f8e528..aca4d11 100644 --- a/DungeonShooting_Godot/src/game/Cursor.cs +++ b/DungeonShooting_Godot/src/game/Cursor.cs @@ -13,7 +13,7 @@ /// /// 非GUI模式下鼠标指针所挂载的角色 /// - private AdvancedRole _mountRole; + private Role _mountRole; private Sprite2D center; private Sprite2D lt; @@ -88,7 +88,7 @@ /// /// 设置非GUI模式下鼠标指针所挂载的角色 /// - public void SetMountRole(AdvancedRole role) + public void SetMountRole(Role role) { _mountRole = role; } @@ -96,7 +96,7 @@ /// /// 获取非GUI模式下鼠标指针所挂载的角色 /// - public AdvancedRole GetMountRole() + public Role GetMountRole() { return _mountRole; } diff --git a/DungeonShooting_Godot/src/game/GameApplication.cs b/DungeonShooting_Godot/src/game/GameApplication.cs index 86b0d3d..276b27d 100644 --- a/DungeonShooting_Godot/src/game/GameApplication.cs +++ b/DungeonShooting_Godot/src/game/GameApplication.cs @@ -31,7 +31,7 @@ /// 全局根节点 /// [Export] public Node2D GlobalNodeRoot; - + /// /// 游戏目标帧率 /// @@ -91,6 +91,8 @@ InitRoomConfig(); //初始化武器数据 Weapon.InitWeaponAttribute(); + //初始化敌人数据 + Enemy.InitEnemyAttribute(); DungeonConfig = new DungeonConfig(); DungeonConfig.GroupName = RoomConfig.FirstOrDefault().Key; @@ -104,14 +106,12 @@ //随机化种子 //GD.Randomize(); //固定帧率 - //Engine.MaxFps = TargetFps; + Engine.MaxFps = TargetFps; //调试绘制开关 - //IsDebug = true; ActivityObject.IsDebug = false; //Engine.TimeScale = 0.2f; //调整窗口分辨率 OnWindowSizeChanged(); - RefreshSubViewportSize(); //窗体大小改变 GetWindow().SizeChanged += OnWindowSizeChanged; @@ -184,8 +184,7 @@ /// public Vector2 GlobalToViewPosition(Vector2 globalPos) { - //return globalPos; - return globalPos / PixelScale - (ViewportSize / 2) + GameCamera.Main.GlobalPosition; + return globalPos / PixelScale - (ViewportSize / 2) + GameCamera.Main.GlobalPosition - GameCamera.Main.PixelOffset; } /// @@ -193,9 +192,7 @@ /// public Vector2 ViewToGlobalPosition(Vector2 viewPos) { - // 3.5写法 - //return (viewPos - GameCamera.Main.GlobalPosition + (GameConfig.ViewportSize / 2)) * GameConfig.WindowScale - GameCamera.Main.SubPixelPosition; - return (viewPos - (GameCamera.Main.GlobalPosition + GameCamera.Main.Offset) + (ViewportSize / 2)) * PixelScale; + return (viewPos + GameCamera.Main.PixelOffset - (GameCamera.Main.GlobalPosition + GameCamera.Main.Offset) + (ViewportSize / 2)) * PixelScale; } public long StartCoroutine(IEnumerator able) @@ -274,11 +271,12 @@ private void RefreshSubViewportSize() { var s = new Vector2I((int)ViewportSize.X, (int)ViewportSize.Y); - s.X = s.X / 2 * 2; - s.Y = s.Y / 2 * 2; + s.X = s.X / 2 * 2 + 2; + s.Y = s.Y / 2 * 2 + 2; SubViewport.Size = s; SubViewportContainer.Scale = new Vector2(PixelScale, PixelScale); SubViewportContainer.Size = s; + SubViewportContainer.Position = new Vector2(-PixelScale, -PixelScale); } //初始化鼠标 diff --git a/DungeonShooting_Godot/src/game/activity/ForceNames.cs b/DungeonShooting_Godot/src/game/activity/ForceNames.cs index ae60220..f732a84 100644 --- a/DungeonShooting_Godot/src/game/activity/ForceNames.cs +++ b/DungeonShooting_Godot/src/game/activity/ForceNames.cs @@ -8,4 +8,8 @@ /// 投抛外力 /// public const string Throw = "throw"; + /// + /// 击退外力 + /// + public const string Repel = "repel"; } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs b/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs index 6bbec1c..637b9b3 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/explode/Explode.cs @@ -30,6 +30,10 @@ /// public uint AttackLayer { get; private set; } + /// + /// 产生爆炸的子弹数据 + /// + public BulletData BulletData { get; private set; } private bool _init = false; private float _hitRadius; @@ -51,13 +55,13 @@ /// /// 初始化爆炸数据 /// - /// 爆炸所在区域 + /// 产生爆炸的子弹数据 /// 攻击的层级 /// 伤害半径 /// 造成的伤害 /// 击退半径 /// 最大击退速度 - public void Init(AffiliationArea affiliationArea, uint attackLayer, float hitRadius, int harm, float repelledRadius, float maxRepelled) + public void Init(BulletData bulletData, uint attackLayer, float hitRadius, int harm, float repelledRadius, float maxRepelled) { if (!_init) { @@ -68,7 +72,8 @@ AnimationPlayer.AnimationFinished += OnAnimationFinish; BodyEntered += OnBodyEntered; } - + + BulletData = bulletData; AttackLayer = attackLayer; _hitRadius = hitRadius; _harm = harm; @@ -78,6 +83,7 @@ CircleShape.Radius = Mathf.Max(hitRadius, maxRepelled); //冲击波 + var affiliationArea = bulletData.TriggerRole?.AffiliationArea; if (affiliationArea != null) { ShockWave(affiliationArea); @@ -87,7 +93,7 @@ /// /// 播放爆炸, triggerRole 为触发该爆炸的角色 /// - public void RunPlay(AdvancedRole triggerRole = null) + public void RunPlay(Role triggerRole = null) { GameCamera.Main.CreateShake(new Vector2(6, 6), 0.7f, true); AnimationPlayer.Play(AnimatorNames.Play); @@ -138,7 +144,7 @@ { if (o is Role role) //是角色 { - role.CallDeferred(nameof(role.Hurt), _harm, angle); + role.CallDeferred(nameof(role.Hurt), BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole, _harm, angle); } else if (o is Bullet bullet) //是子弹 { @@ -155,7 +161,7 @@ { var repelled = (_repelledRadius - len) / _repelledRadius * _maxRepelled; //o.MoveController.SetAllVelocity(Vector2.Zero); - o.MoveController.AddForce(Vector2.FromAngle(angle) * repelled); + o.AddRepelForce(Vector2.FromAngle(angle) * repelled); } } } diff --git a/DungeonShooting_Godot/src/game/activity/bullet/laser/Laser.cs b/DungeonShooting_Godot/src/game/activity/bullet/laser/Laser.cs index 5a62788..f516e71 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/laser/Laser.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/laser/Laser.cs @@ -142,10 +142,10 @@ //击退 if (BulletData.Repel != 0) { - role.MoveController.AddForce(Vector2.FromAngle(Rotation) * BulletData.Repel); + role.AddRepelForce(Vector2.FromAngle(Rotation) * BulletData.Repel); } //造成伤害 - role.CallDeferred(nameof(Role.Hurt), BulletData.Harm, Rotation); + role.CallDeferred(nameof(Role.Hurt), BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole, BulletData.Harm, Rotation); } } diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs index fa1826f..065162f 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/BoomBullet.cs @@ -58,6 +58,7 @@ { //播放撞击音效 SoundManager.PlaySoundByConfig("collision0001", Position, BulletData.TriggerRole); + //这里不调用父类的 OnFallToGround() 函数, 因为这种子弹落地不需要销毁 } /// @@ -70,7 +71,7 @@ explode.Position = pos; explode.RotationDegrees = Utils.Random.RandomRangeInt(0, 360); explode.AddToActivityRootDeferred(RoomLayerEnum.YSortLayer); - explode.Init(BulletData.TriggerRole?.AffiliationArea, AttackLayer, 25, BulletData.Harm, 50, BulletData.Repel); + explode.Init(BulletData, AttackLayer, 25, BulletData.Harm, 50, BulletData.Repel); explode.RunPlay(BulletData.TriggerRole); if (AffiliationArea != null) { diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs index 2e7af1e..a444a13 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/Bullet.cs @@ -16,10 +16,16 @@ public string Logotype { get; set; } /// - /// 碰撞区域 + /// 子弹伤害碰撞区域 /// [Export, ExportFillNode] public Area2D CollisionArea { get; set; } + + /// + /// 子弹伤害碰撞检测形状 + /// + [Export, ExportFillNode] + public CollisionShape2D CollisionShape2D { get; set; } /// /// 攻击的层级 @@ -54,38 +60,34 @@ CollisionArea.AreaEntered += OnArea2dEntered; _init = true; } - + CurrentBounce = 0; CurrentPenetration = 0; CurrFlyDistance = 0; - BounceLockRotation = false; BulletData = data; AttackLayer = attackLayer; Rotation = data.Rotation; - - float altitude; + var triggerRole = data.TriggerRole; - if (triggerRole != null) + if (data.TriggerRole != null && data.TriggerRole.AffiliationArea != null) //设置所属区域 { - altitude = -triggerRole.MountPoint.Position.Y; - if (triggerRole.AffiliationArea != null) //设置所属区域 + if (triggerRole.AffiliationArea != null) { triggerRole.AffiliationArea.InsertItem(this); } } - else - { - altitude = 8; - } - Position = data.Position + new Vector2(0, altitude); - Altitude = altitude; + Position = data.Position + new Vector2(0, data.Altitude); + Altitude = data.Altitude; if (data.VerticalSpeed != 0) { VerticalSpeed = data.VerticalSpeed; } - EnableVerticalMotion = data.BulletBase.UseGravity; + else + { + VerticalSpeed = 0; + } //BasisVelocity = new Vector2(data.FlySpeed, 0).Rotated(Rotation); MoveController.AddForce(new Vector2(data.FlySpeed, 0).Rotated(Rotation)); @@ -107,7 +109,6 @@ this.CallDelay(data.LifeTime, OnLimeOver); } } - public override void OnMoveCollision(KinematicCollision2D collision) { @@ -140,12 +141,12 @@ { if (BulletData.Repel != 0) { - role.MoveController.AddForce(Velocity.Normalized() * BulletData.Repel); + role.AddRepelForce(Velocity.Normalized() * BulletData.Repel); } } //造成伤害 - role.CallDeferred(nameof(AdvancedRole.Hurt), BulletData.Harm, Rotation); + role.CallDeferred(nameof(Role.Hurt), BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole, BulletData.Harm, Rotation); //穿透次数 CurrentPenetration++; @@ -174,6 +175,13 @@ DoReclaim(); } + protected override void OnFallToGround() + { + //落地销毁 + PlayDisappearEffect(); + DoReclaim(); + } + /// /// 显示红色描边 /// @@ -207,6 +215,11 @@ protected override void Process(float delta) { + if (ActivityMaterial.DynamicCollision) + { + //子弹高度大于 16 关闭碰撞检测 + CollisionShape2D.Disabled = Altitude >= 16; + } //距离太大, 自动销毁 CurrFlyDistance += BulletData.FlySpeed * delta; if (CurrFlyDistance >= BulletData.MaxDistance) diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/IBullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/IBullet.cs index a81f718..9611387 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/normal/IBullet.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/IBullet.cs @@ -12,7 +12,7 @@ /// 离开对象池时的事件 /// event Action OnLeavePoolEvent; - + /// /// 攻击的层级 /// diff --git a/DungeonShooting_Godot/src/game/activity/common/AutoFreezeObject.cs b/DungeonShooting_Godot/src/game/activity/common/AutoFreezeObject.cs new file mode 100644 index 0000000..cd245fd --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/common/AutoFreezeObject.cs @@ -0,0 +1,63 @@ + +using Godot; + +/// +/// 停止移动后自动冻结对象 +/// +[Tool] +public partial class AutoFreezeObject : ActivityObject +{ + /// + /// 自动播放的动画, 物体会等待该动画播完完成后进入冻结状态, 该动画不能是循环动画 + /// + [Export] + public string AnimationName { get; set; } + + /// + /// 在冻结前是否变灰 + /// + [Export] + public bool AutoToGrey { get; set; } + + private bool _playFlag = false; + private float _grey = 0; + + public override void OnInit() + { + if (!string.IsNullOrEmpty(AnimationName)) + { + _playFlag = true; + AnimatedSprite.AnimationFinished += OnAnimationFinished; + AnimatedSprite.Play(AnimationName); + } + } + + protected override void Process(float delta) + { + //落地静止后将弹壳变为静态贴图 + if (!_playFlag &&!IsThrowing && Altitude <= 0 && MoveController.IsMotionless()) + { + if (AutoToGrey && _grey < 1) + { + //变灰动画时间, 0.5秒 + _grey = Mathf.Min(1, _grey + delta / 0.5f); + Grey = _grey; + return; + } + if (AffiliationArea != null) + { + Freeze(); + } + else + { + Debug.Log(Name + "投抛到画布外了, 强制消除..."); + Destroy(); + } + } + } + + private void OnAnimationFinished() + { + _playFlag = false; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/package/Package.cs b/DungeonShooting_Godot/src/game/activity/package/Package.cs index 4dd43dd..7c2d6e4 100644 --- a/DungeonShooting_Godot/src/game/activity/package/Package.cs +++ b/DungeonShooting_Godot/src/game/activity/package/Package.cs @@ -56,16 +56,15 @@ { capacity = 0; } - - if (capacity == Capacity) - { - return; - } - + if (ItemSlot == null) { ItemSlot = new T[capacity]; } + else if (capacity == Capacity) + { + return; + } else if (ItemSlot.Length > capacity) //删减格子 { var newArray = new T[capacity]; @@ -76,9 +75,8 @@ { newArray[i] = packageItem; } - else + else if (packageItem != null) //溢出的item { - //溢出的item packageItem.OnOverflowItem(); packageItem.Master = null; packageItem.PackageIndex = -1; @@ -97,7 +95,6 @@ ItemSlot = newArray; } Capacity = capacity; - } /// @@ -153,7 +150,7 @@ for (var i = 0; i < ItemSlot.Length; i++) { var item = ItemSlot[i]; - if (item != null && item.ItemConfig.Id == id) + if (item != null && item.ActivityBase.Id == id) { return i; } @@ -422,7 +419,7 @@ for (var i = 0; i < ItemSlot.Length; i++) { var packageItem = ItemSlot[i]; - if (packageItem != null && packageItem.ItemConfig.Id == itemId) + if (packageItem != null && packageItem.ActivityBase.Id == itemId) { return i; } @@ -444,7 +441,7 @@ for (var i = 0; i < ItemSlot.Length; i++) { var packageItem = ItemSlot[i]; - if (packageItem != null && packageItem.ItemConfig.Id == itemId) + if (packageItem != null && packageItem.ActivityBase.Id == itemId) { return packageItem; } diff --git a/DungeonShooting_Godot/src/game/activity/prop/Prop.cs b/DungeonShooting_Godot/src/game/activity/prop/Prop.cs index beb1751..c79dfc0 100644 --- a/DungeonShooting_Godot/src/game/activity/prop/Prop.cs +++ b/DungeonShooting_Godot/src/game/activity/prop/Prop.cs @@ -32,7 +32,7 @@ /// 触发扔掉道具效果, 并不会管道具是否在道具背包中 /// /// 触发扔掉该道具的的角色 - public void ThrowProp(AdvancedRole master) + public void ThrowProp(Role master) { ThrowProp(master, master.GlobalPosition); } @@ -47,7 +47,7 @@ //阴影偏移 ShadowOffset = new Vector2(0, 2); GlobalRotation = 0; - var startHeight = -master.GetCenterPosition().Y; + var startHeight = 8; Throw(startPosition, startHeight, 0, Vector2.Zero, 0); //继承role的移动速度 diff --git a/DungeonShooting_Godot/src/game/activity/prop/active/ActiveProp.cs b/DungeonShooting_Godot/src/game/activity/prop/active/ActiveProp.cs index aaa78c3..28aaa0b 100644 --- a/DungeonShooting_Godot/src/game/activity/prop/active/ActiveProp.cs +++ b/DungeonShooting_Godot/src/game/activity/prop/active/ActiveProp.cs @@ -230,7 +230,7 @@ { if (master is Player player) { - var item = player.ActivePropsPack.GetItemById(ItemConfig.Id); + var item = player.ActivePropsPack.GetItemById(ActivityBase.Id); if (item == null) //没有同类型物体 { if (!player.ActivePropsPack.HasVacancy()) //没有空位置, 扔掉当前道具 @@ -269,7 +269,7 @@ if (master is Player player) { //查找相同类型的道具 - var item = player.ActivePropsPack.GetItemById(ItemConfig.Id); + var item = player.ActivePropsPack.GetItemById(ActivityBase.Id); if (item == null) //没有同类型物体 { if (player.ActivePropsPack.HasVacancy()) //还有空位, 拾起道具 diff --git a/DungeonShooting_Godot/src/game/activity/prop/active/ActiveProp5001.cs b/DungeonShooting_Godot/src/game/activity/prop/active/ActiveProp5001.cs index eb4662c..2bac5e6 100644 --- a/DungeonShooting_Godot/src/game/activity/prop/active/ActiveProp5001.cs +++ b/DungeonShooting_Godot/src/game/activity/prop/active/ActiveProp5001.cs @@ -16,24 +16,16 @@ public override bool OnCheckUse() { - if (Master is AdvancedRole advancedRole) - { - return advancedRole.WeaponPack.ActiveItem != null && !advancedRole.WeaponPack.ActiveItem.IsAmmoFull(); - } - - return false; + return Master.WeaponPack.ActiveItem != null && !Master.WeaponPack.ActiveItem.IsAmmoFull(); } protected override int OnUse() { - if (Master is AdvancedRole advancedRole) + var weapon = Master.WeaponPack.ActiveItem; + if (weapon != null) { - var weapon = advancedRole.WeaponPack.ActiveItem; - if (weapon != null) - { - weapon.SetTotalAmmo(weapon.Attribute.MaxAmmoCapacity); - return 1; - } + weapon.SetTotalAmmo(weapon.Attribute.MaxAmmoCapacity); + return 1; } return 0; diff --git a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0008.cs b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0008.cs index e72de6d..b7d2de6 100644 --- a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0008.cs +++ b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0008.cs @@ -19,12 +19,12 @@ Master.RoleState.CalcFinalScatteringEvent -= CalcFinalScatteringEvent; } - private void CalcStartScatteringEvent(Weapon weapon, float originValue, RefValue refValue) + private void CalcStartScatteringEvent(float originValue, RefValue refValue) { refValue.Value *= 0.5f; } - private void CalcFinalScatteringEvent(Weapon weapon, float originValue, RefValue refValue) + private void CalcFinalScatteringEvent(float originValue, RefValue refValue) { refValue.Value *= 0.5f; } diff --git a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0009.cs b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0009.cs index ff94d5f..4fad8f8 100644 --- a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0009.cs +++ b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0009.cs @@ -19,12 +19,12 @@ Master.RoleState.CalcBulletDistanceEvent -= CalcBulletDistanceEvent; } - private void CalcBulletSpeedEvent(Weapon weapon, float originSpeed, RefValue speed) + private void CalcBulletSpeedEvent(float originSpeed, RefValue speed) { speed.Value += originSpeed * 0.25f; } - private void CalcBulletDistanceEvent(Weapon weapon, float originDistance, RefValue distance) + private void CalcBulletDistanceEvent(float originDistance, RefValue distance) { distance.Value += originDistance * 0.25f; } diff --git a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0010.cs b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0010.cs index 3e323e9..6254213 100644 --- a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0010.cs +++ b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0010.cs @@ -25,12 +25,12 @@ Master.RoleState.CalcBulletRepelEvent -= CalcBulletRepelEvent; } - private void CalcBulletCountEvent(Weapon weapon, int originCount, RefValue refValue) + private void CalcBulletCountEvent(int originCount, RefValue refValue) { refValue.Value += originCount; } - private void CalcBulletDeviationAngleEvent(Weapon weapon, float originAngle, RefValue refValue) + private void CalcBulletDeviationAngleEvent(float originAngle, RefValue refValue) { refValue.Value += Utils.Random.RandomRangeFloat(-8, 8); } @@ -45,14 +45,15 @@ refValue.Value = Mathf.Max(1, refValue.Value - Mathf.FloorToInt(refValue.Value * 0.35f)); } - private void CalcBulletSpeedEvent(Weapon weapon, float originSpeed, RefValue speed) + private void CalcBulletSpeedEvent(float originSpeed, RefValue speed) { speed.Value += originSpeed * Utils.Random.RandomRangeFloat(-0.05f, 0.05f); } - private void CalcBulletRepelEvent(Weapon weapon, float originRepel, RefValue repel) + private void CalcBulletRepelEvent(float originRepel, RefValue repel) { - if (weapon.Attribute.IsMelee || repel.Value < 0) + if (repel.Value < 0 || (Master.WeaponPack.ActiveItem != null && + Master.WeaponPack.ActiveItem.Attribute.IsMelee)) { return; } diff --git a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0011.cs b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0011.cs index 025eb43..6485291 100644 --- a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0011.cs +++ b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0011.cs @@ -17,7 +17,7 @@ Master.RoleState.CalcBulletBounceCountEvent -= CalcBulletBounceCountEvent; } - private void CalcBulletBounceCountEvent(Weapon weapon, int originBounce, RefValue bounce) + private void CalcBulletBounceCountEvent(int originBounce, RefValue bounce) { bounce.Value += 2; } diff --git a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0012.cs b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0012.cs index bc65ac3..a24b0fc 100644 --- a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0012.cs +++ b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0012.cs @@ -17,7 +17,7 @@ Master.RoleState.CalcBulletPenetrationEvent -= CalcBulletPenetrationEvent; } - private void CalcBulletPenetrationEvent(Weapon weapon, int origin, RefValue penetration) + private void CalcBulletPenetrationEvent(int origin, RefValue penetration) { penetration.Value += 1; } diff --git a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0013.cs b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0013.cs index 05e0202..e43270a 100644 --- a/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0013.cs +++ b/DungeonShooting_Godot/src/game/activity/prop/buff/BuffProp0013.cs @@ -8,17 +8,11 @@ { public override void OnPickUpItem() { - if (Master is AdvancedRole advancedRole) - { - advancedRole.WeaponPack.SetCapacity(advancedRole.WeaponPack.Capacity + 1); - } + Master.WeaponPack.SetCapacity(Master.WeaponPack.Capacity + 1); } public override void OnRemoveItem() { - if (Master is AdvancedRole advancedRole) - { - advancedRole.WeaponPack.SetCapacity(advancedRole.WeaponPack.Capacity - 1); - } + Master.WeaponPack.SetCapacity(Master.WeaponPack.Capacity - 1); } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/AdvancedRole.cs b/DungeonShooting_Godot/src/game/activity/role/AdvancedRole.cs deleted file mode 100644 index 01d64b3..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/AdvancedRole.cs +++ /dev/null @@ -1,430 +0,0 @@ -using Godot; - -/// -/// 高级角色,可以拾起和使用武器 -/// -public abstract partial class AdvancedRole : Role -{ - /// - /// 角色携带的武器背包 - /// - public Package WeaponPack { get; private set; } - - /// - /// 武器挂载点 - /// - [Export, ExportFillNode] - public MountRotation MountPoint { get; set; } - /// - /// 背后武器的挂载点 - /// - [Export, ExportFillNode] - public Marker2D BackMountPoint { get; set; } - - /// - /// 近战碰撞检测区域 - /// - [Export, ExportFillNode] - public Area2D MeleeAttackArea { get; set; } - - /// - /// 近战碰撞检测区域的碰撞器 - /// - [Export, ExportFillNode] - public CollisionPolygon2D MeleeAttackCollision { get; set; } - - /// - /// 近战攻击时挥动武器的角度 - /// - [Export] - public float MeleeAttackAngle { get; set; } = 120; - - /// - /// 武器挂载点是否始终指向目标 - /// - public bool MountLookTarget { get; set; } = true; - - /// - /// 是否处于近战攻击中 - /// - public bool IsMeleeAttack { get; private set; } - - /// - /// 当前角色所看向的对象, 也就是枪口指向的对象 - /// - public ActivityObject LookTarget { get; set; } - - //近战计时器 - private float _meleeAttackTimer = 0; - - /// - /// 当拾起某个武器时调用 - /// - protected virtual void OnPickUpWeapon(Weapon weapon) - { - } - - /// - /// 当扔掉某个武器时调用 - /// - protected virtual void OnThrowWeapon(Weapon weapon) - { - } - - /// - /// 当切换到某个武器时调用 - /// - protected virtual void OnExchangeWeapon(Weapon weapon) - { - } - - public override void OnInit() - { - base.OnInit(); - WeaponPack = AddComponent>(); - WeaponPack.SetCapacity(4); - - MountPoint.Master = this; - - MeleeAttackCollision.Disabled = true; - //切换武器回调 - WeaponPack.ChangeActiveItemEvent += OnChangeActiveItem; - //近战区域进入物体 - MeleeAttackArea.BodyEntered += OnMeleeAttackBodyEntered; - } - - protected override void Process(float delta) - { - if (IsDie) - { - return; - } - - if (_meleeAttackTimer > 0) - { - _meleeAttackTimer -= delta; - } - - //看向目标 - if (LookTarget != null && MountLookTarget) - { - var pos = LookTarget.Position; - //脸的朝向 - var gPos = Position; - if (pos.X > gPos.X && Face == FaceDirection.Left) - { - Face = FaceDirection.Right; - } - else if (pos.X < gPos.X && Face == FaceDirection.Right) - { - Face = FaceDirection.Left; - } - //枪口跟随目标 - MountPoint.SetLookAt(pos); - } - - base.Process(delta); - } - - /// - /// 当武器放到后背时调用, 用于设置武器位置和角度 - /// - /// 武器实例 - /// 放入武器背包的位置 - public virtual void OnPutBackMount(Weapon weapon, int index) - { - if (index < 8) - { - if (index % 2 == 0) - { - weapon.Position = new Vector2(-4, 3); - weapon.RotationDegrees = 90 - (index / 2f) * 20; - weapon.Scale = new Vector2(-1, 1); - } - else - { - weapon.Position = new Vector2(4, 3); - weapon.RotationDegrees = 270 + (index - 1) / 2f * 20; - weapon.Scale = new Vector2(1, 1); - } - } - else - { - weapon.Visible = false; - } - } - - protected override void OnAffiliationChange(AffiliationArea prevArea) - { - //身上的武器的所属区域也得跟着变 - WeaponPack.ForEach((weapon, i) => - { - if (AffiliationArea != null) - { - AffiliationArea.InsertItem(weapon); - } - else if (weapon.AffiliationArea != null) - { - weapon.AffiliationArea.RemoveItem(weapon); - } - }); - } - - public override Vector2 GetCenterPosition() - { - return MountPoint.GlobalPosition; - } - - public override void LookTargetPosition(Vector2 pos) - { - LookTarget = null; - if (MountLookTarget) - { - //脸的朝向 - var gPos = GlobalPosition; - if (pos.X > gPos.X && Face == FaceDirection.Left) - { - Face = FaceDirection.Right; - } - else if (pos.X < gPos.X && Face == FaceDirection.Right) - { - Face = FaceDirection.Left; - } - //枪口跟随目标 - MountPoint.SetLookAt(pos); - } - } - - /// - /// 返回所有武器是否弹药都打光了 - /// - public bool IsAllWeaponTotalAmmoEmpty() - { - foreach (var weapon in WeaponPack.ItemSlot) - { - if (weapon != null && !weapon.IsTotalAmmoEmpty()) - { - return false; - } - } - - return true; - } - - //------------------------------------------------------------------------------------- - - /// - /// 拾起一个武器, 返回是否成功拾起, 如果不想立刻切换到该武器, exchange 请传 false - /// - /// 武器对象 - /// 是否立即切换到该武器, 默认 true - public bool PickUpWeapon(Weapon weapon, bool exchange = true) - { - if (WeaponPack.PickupItem(weapon, exchange) != -1) - { - //从可互动队列中移除 - InteractiveItemList.Remove(weapon); - OnPickUpWeapon(weapon); - return true; - } - - return false; - } - - /// - /// 切换到下一个武器 - /// - public void ExchangeNextWeapon() - { - var weapon = WeaponPack.ActiveItem; - WeaponPack.ExchangeNext(); - if (WeaponPack.ActiveItem != weapon) - { - OnExchangeWeapon(WeaponPack.ActiveItem); - } - } - - /// - /// 切换到上一个武器 - /// - public void ExchangePrevWeapon() - { - var weapon = WeaponPack.ActiveItem; - WeaponPack.ExchangePrev(); - if (WeaponPack.ActiveItem != weapon) - { - OnExchangeWeapon(WeaponPack.ActiveItem); - } - } - - /// - /// 扔掉当前使用的武器, 切换到上一个武器 - /// - public void ThrowWeapon() - { - ThrowWeapon(WeaponPack.ActiveIndex); - } - - /// - /// 扔掉指定位置的武器 - /// - /// 武器在武器背包中的位置 - public void ThrowWeapon(int index) - { - var weapon = WeaponPack.GetItem(index); - if (weapon == null) - { - return; - } - - var temp = weapon.AnimatedSprite.Position; - if (Face == FaceDirection.Left) - { - temp.Y = -temp.Y; - } - //var pos = GlobalPosition + temp.Rotated(weapon.GlobalRotation); - WeaponPack.RemoveItem(index); - //播放抛出效果 - weapon.ThrowWeapon(this, GlobalPosition); - } - - /// - /// 切换到下一个武器 - /// - public void ExchangeNextActiveProp() - { - var prop = ActivePropsPack.ActiveItem; - ActivePropsPack.ExchangeNext(); - if (prop != ActivePropsPack.ActiveItem) - { - OnExchangeActiveProp(ActivePropsPack.ActiveItem); - } - } - - /// - /// 切换到上一个武器 - /// - public void ExchangePrevActiveProp() - { - var prop = ActivePropsPack.ActiveItem; - ActivePropsPack.ExchangePrev(); - if (prop != ActivePropsPack.ActiveItem) - { - OnExchangeActiveProp(ActivePropsPack.ActiveItem); - } - } - - //------------------------------------------------------------------------------------- - - - /// - /// 触发换弹 - /// - public virtual void Reload() - { - if (WeaponPack.ActiveItem != null) - { - WeaponPack.ActiveItem.Reload(); - } - } - - public override void Attack() - { - if (!IsMeleeAttack && WeaponPack.ActiveItem != null) - { - WeaponPack.ActiveItem.Trigger(this); - } - } - - /// - /// 触发近战攻击 - /// - public virtual void MeleeAttack() - { - if (IsMeleeAttack || _meleeAttackTimer > 0) - { - return; - } - - if (WeaponPack.ActiveItem != null && WeaponPack.ActiveItem.Attribute.CanMeleeAttack) - { - IsMeleeAttack = true; - _meleeAttackTimer = RoleState.MeleeAttackTime; - MountLookTarget = false; - - //WeaponPack.ActiveItem.TriggerMeleeAttack(this); - //播放近战动画 - PlayAnimation_MeleeAttack(() => - { - MountLookTarget = true; - IsMeleeAttack = false; - }); - } - } - - /// - /// 切换当前使用的武器的回调 - /// - private void OnChangeActiveItem(Weapon weapon) - { - //这里处理近战区域 - if (weapon != null) - { - MeleeAttackCollision.Polygon = Utils.CreateSectorPolygon( - Utils.ConvertAngle(-MeleeAttackAngle / 2f), - (weapon.GetLocalFirePosition() - weapon.GripPoint.Position).Length() * 1.2f, - MeleeAttackAngle, - 6 - ); - MeleeAttackArea.CollisionMask = AttackLayer | PhysicsLayer.Bullet; - } - } - - /// - /// 近战区域碰到敌人 - /// - private void OnMeleeAttackBodyEntered(Node2D body) - { - var activeWeapon = WeaponPack.ActiveItem; - if (activeWeapon == null) - { - return; - } - var activityObject = body.AsActivityObject(); - if (activityObject != null) - { - if (activityObject is AdvancedRole role) //攻击角色 - { - var damage = Utils.Random.RandomConfigRange(activeWeapon.Attribute.MeleeAttackHarmRange); - damage = RoleState.CalcDamage(damage); - - //击退 - if (role is not Player) //目标不是玩家才会触发击退 - { - var attr = IsAi ? activeWeapon.AiUseAttribute : activeWeapon.PlayerUseAttribute; - var repel = Utils.Random.RandomConfigRange(attr.MeleeAttackRepelRange); - var position = role.GlobalPosition - MountPoint.GlobalPosition; - var v2 = position.Normalized() * repel; - role.MoveController.AddForce(v2); - } - - role.CallDeferred(nameof(Hurt), damage, (role.GetCenterPosition() - GlobalPosition).Angle()); - } - else if (activityObject is Bullet bullet) //攻击子弹 - { - var attackLayer = bullet.AttackLayer; - if (CollisionWithMask(attackLayer)) //是攻击玩家的子弹 - { - bullet.PlayDisappearEffect(); - bullet.Destroy(); - } - } - } - } - - protected override void OnDestroy() - { - base.OnDestroy(); - WeaponPack.Destroy(); - } -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/AdvancedRole_Animation.cs b/DungeonShooting_Godot/src/game/activity/role/AdvancedRole_Animation.cs deleted file mode 100644 index e829a1f..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/AdvancedRole_Animation.cs +++ /dev/null @@ -1,78 +0,0 @@ - -using System; -using Godot; -using Vector2 = Godot.Vector2; - -public partial class AdvancedRole -{ - /// - /// 播放近战攻击动画 - /// - public virtual void PlayAnimation_MeleeAttack(Action finish) - { - var r = MountPoint.RotationDegrees; - //var gp = MountPoint.GlobalPosition; - var p1 = MountPoint.Position; - var p2 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r - MeleeAttackAngle / 2f)); - var p3 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r + MeleeAttackAngle / 2f)); - - var tween = CreateTween(); - tween.SetParallel(); - - tween.TweenProperty(MountPoint, "rotation_degrees", r - MeleeAttackAngle / 2f, 0.1); - tween.TweenProperty(MountPoint, "position", p2, 0.1); - tween.TweenProperty(MountPoint, "position", p2, 0.1); - tween.Chain(); - - tween.TweenCallback(Callable.From(() => - { - MountPoint.RotationDegrees = r + MeleeAttackAngle / 2f; - MountPoint.Position = p3; - //重新计算武器阴影位置 - var activeItem = WeaponPack.ActiveItem; - activeItem.CalcShadowTransform(); - //创建屏幕抖动 - if (Face == FaceDirection.Right) - { - //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 90)) * 5); - GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 180)) * 6); - } - else - { - //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(270 - r)) * 5); - GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(-r)) * 6); - } - //播放特效 - var effect = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_weapon_MeleeAttack1_tscn); - var sprite = (Node2D)effect; - var localFirePosition = activeItem.GetLocalFirePosition() - activeItem.GripPoint.Position; - localFirePosition *= 0.9f; - sprite.Position = p1 + localFirePosition.Rotated(Mathf.DegToRad(r)); - sprite.RotationDegrees = r; - AddChild(sprite); - effect.PlayEffect(); - - //启用近战碰撞区域 - MeleeAttackCollision.Disabled = false; - })); - tween.Chain(); - - tween.TweenInterval(0.1f); - tween.Chain(); - - tween.TweenCallback(Callable.From(() => - { - //关闭近战碰撞区域 - MeleeAttackCollision.Disabled = true; - })); - tween.TweenProperty(MountPoint, "rotation_degrees", r, 0.2); - tween.TweenProperty(MountPoint, "position", p1, 0.2); - tween.Chain(); - - tween.TweenCallback(Callable.From(() => - { - finish(); - })); - tween.Play(); - } -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/MountRotation.cs b/DungeonShooting_Godot/src/game/activity/role/MountRotation.cs index eca09e9..e265b10 100644 --- a/DungeonShooting_Godot/src/game/activity/role/MountRotation.cs +++ b/DungeonShooting_Godot/src/game/activity/role/MountRotation.cs @@ -15,7 +15,7 @@ /// /// 所在的角色 /// - public AdvancedRole Master { get; set; } + public Role Master { get; set; } /// /// 当前节点真实的旋转角度, 角度制 diff --git a/DungeonShooting_Godot/src/game/activity/role/Role.cs b/DungeonShooting_Godot/src/game/activity/role/Role.cs index 0fda986..c1daa8a 100644 --- a/DungeonShooting_Godot/src/game/activity/role/Role.cs +++ b/DungeonShooting_Godot/src/game/activity/role/Role.cs @@ -16,7 +16,7 @@ /// /// 角色属性 /// - public RoleState RoleState { get; } = new RoleState(); + public RoleState RoleState { get; private set; } /// /// 默认攻击对象层级 @@ -72,11 +72,99 @@ [Export, ExportFillNode] public CollisionShape2D InteractiveCollision { get; set; } - /// + /// + /// 用于提示状态的根节点 + /// + [Export, ExportFillNode] + public Node2D TipRoot { get; set; } + + /// + /// 用于提示当前敌人状态 + /// + [Export, ExportFillNode] + public AnimatedSprite2D TipSprite { get; set; } + + /// + /// 动画播放器 + /// + [Export, ExportFillNode] + public AnimationPlayer AnimationPlayer { get; set; } + + /// /// 脸的朝向 /// public FaceDirection Face { get => _face; set => SetFace(value); } private FaceDirection _face; + + /// + /// 角色携带的武器背包 + /// + public Package WeaponPack { get; private set; } + + /// + /// 武器挂载点 + /// + [Export, ExportFillNode] + public MountRotation MountPoint { get; set; } + + /// + /// 背后武器的挂载点 + /// + [Export, ExportFillNode] + public Marker2D BackMountPoint { get; set; } + + /// + /// 近战碰撞检测区域 + /// + [Export, ExportFillNode] + public Area2D MeleeAttackArea { get; set; } + + /// + /// 近战碰撞检测区域的碰撞器 + /// + [Export, ExportFillNode] + public CollisionPolygon2D MeleeAttackCollision { get; set; } + + /// + /// 近战攻击时挥动武器的角度 + /// + [Export] + public float MeleeAttackAngle { get; set; } = 120; + + /// + /// 武器挂载点是否始终指向目标 + /// + public bool MountLookTarget { get; set; } = true; + + /// + /// 是否处于攻击中, 近战攻击远程攻击都算 + /// + public bool IsAttack + { + get + { + if (AttackTimer > 0 || MeleeAttackTimer > 0) + { + return true; + } + var weapon = WeaponPack.ActiveItem; + if (weapon != null) + { + return weapon.GetAttackTimer() > 0 || weapon.GetContinuousCount() > 0; + } + return false; + } + } + + /// + /// 攻击计时器 + /// + public float AttackTimer { get; set; } + + /// + /// 近战计时器 + /// + public float MeleeAttackTimer { get; set; } /// /// 是否死亡 @@ -217,6 +305,16 @@ /// public List InteractiveItemList { get; } = new List(); + /// + /// 角色看向的坐标 + /// + public Vector2 LookPosition { get; protected set; } + + /// + /// 是否可以在没有武器时发动攻击 + /// + public bool NoWeaponAttack { get; set; } + //初始缩放 private Vector2 _startScale; //当前可互动的物体 @@ -231,6 +329,24 @@ //护盾恢复计时器 private float _shieldRecoveryTimer = 0; + protected override void OnExamineExportFillNode(string propertyName, Node node, bool isJustCreated) + { + base.OnExamineExportFillNode(propertyName, node, isJustCreated); + if (propertyName == nameof(TipSprite)) + { + var sprite = (AnimatedSprite2D)node; + sprite.SpriteFrames = + ResourceManager.Load(ResourcePath.resource_spriteFrames_role_Role_tip_tres); + } + } + + /// + /// 创建角色的 RoleState 对象 + /// + protected virtual RoleState OnCreateRoleState() + { + return new RoleState(); + } /// /// 当血量改变时调用 @@ -270,9 +386,11 @@ /// /// 当受伤时调用 /// + /// 触发伤害的对象, 为 null 表示不存在对象或者对象已经被销毁 /// 受到的伤害 + /// 伤害角度(弧度制) /// 是否受到真实伤害, 如果为false, 则表示该伤害被互动格挡掉了 - protected virtual void OnHit(int damage, bool realHarm) + protected virtual void OnHit(ActivityObject target, int damage, float angle, bool realHarm) { } @@ -337,18 +455,11 @@ { } - - /// - /// 触发攻击 - /// - public virtual void Attack() - { - } - public override void OnInit() { + RoleState = OnCreateRoleState(); ActivePropsPack = AddComponent>(); - ActivePropsPack.SetCapacity(1); + ActivePropsPack.SetCapacity(RoleState.CanPickUpWeapon ? 1 : 0); _startScale = Scale; @@ -361,10 +472,38 @@ //连接互动物体信号 InteractiveArea.BodyEntered += _OnPropsEnter; InteractiveArea.BodyExited += _OnPropsExit; + + //------------------------ + + WeaponPack = AddComponent>(); + WeaponPack.SetCapacity(2); + + MountPoint.Master = this; + + MeleeAttackCollision.Disabled = true; + //切换武器回调 + WeaponPack.ChangeActiveItemEvent += OnChangeActiveItem; + //近战区域进入物体 + MeleeAttackArea.BodyEntered += OnMeleeAttackBodyEntered; } protected override void Process(float delta) - { + { + if (IsDie) + { + return; + } + + if (AttackTimer > 0) + { + AttackTimer -= delta; + } + + if (MeleeAttackTimer > 0) + { + MeleeAttackTimer -= delta; + } + //检查可互动的物体 bool findFlag = false; for (int i = 0; i < InteractiveItemList.Count; i++) @@ -473,6 +612,14 @@ } } + if (Face == FaceDirection.Right) + { + TipRoot.Scale = Vector2.One; + } + else + { + TipRoot.Scale = new Vector2(-1, 1); + } } /// @@ -498,31 +645,6 @@ } /// - /// 获取当前角色的中心点坐标 - /// - public virtual Vector2 GetCenterPosition() - { - return AnimatedSprite.GlobalPosition; - } - - /// - /// 使角色看向指定的坐标的方向 - /// - public virtual void LookTargetPosition(Vector2 pos) - { - //脸的朝向 - var gPos = GlobalPosition; - if (pos.X > gPos.X && Face == FaceDirection.Left) - { - Face = FaceDirection.Right; - } - else if (pos.X < gPos.X && Face == FaceDirection.Right) - { - Face = FaceDirection.Left; - } - } - - /// /// 判断指定坐标是否在角色视野方向 /// public bool IsPositionInForward(Vector2 pos) @@ -669,9 +791,10 @@ /// /// 受到伤害, 如果是在碰撞信号处理函数中调用该函数, 请使用 CallDeferred 来延时调用, 否则很有可能导致报错 /// + /// 触发伤害的对象, 为 null 表示不存在对象或者对象已经被销毁 /// 伤害的量 /// 伤害角度(弧度制) - public virtual void Hurt(int damage, float angle) + public virtual void Hurt(ActivityObject target, int damage, float angle) { //受伤闪烁, 无敌状态 if (Invincible) @@ -700,7 +823,7 @@ // blood.Rotation = angle; // GameApplication.Instance.Node3D.GetRoot().AddChild(blood); } - OnHit(damage, !flag); + OnHit(target, damage, angle, !flag); //受伤特效 PlayHitAnimation(); @@ -842,6 +965,338 @@ return Mathf.Pi - rotation; } + /// + /// 获取开火点高度 + /// + public virtual float GetFirePointAltitude() + { + return -MountPoint.Position.Y; + } + + /// + /// 当拾起某个武器时调用 + /// + protected virtual void OnPickUpWeapon(Weapon weapon) + { + } + + /// + /// 当扔掉某个武器时调用 + /// + protected virtual void OnThrowWeapon(Weapon weapon) + { + } + + /// + /// 当切换到某个武器时调用 + /// + protected virtual void OnExchangeWeapon(Weapon weapon) + { + } + + /// + /// 当武器放到后背时调用, 用于设置武器位置和角度 + /// + /// 武器实例 + /// 放入武器背包的位置 + public virtual void OnPutBackMount(Weapon weapon, int index) + { + if (index < 8) + { + if (index % 2 == 0) + { + weapon.Position = new Vector2(-4, 3); + weapon.RotationDegrees = 90 - (index / 2f) * 20; + weapon.Scale = new Vector2(-1, 1); + } + else + { + weapon.Position = new Vector2(4, 3); + weapon.RotationDegrees = 270 + (index - 1) / 2f * 20; + weapon.Scale = new Vector2(1, 1); + } + } + else + { + weapon.Visible = false; + } + } + + protected override void OnAffiliationChange(AffiliationArea prevArea) + { + //身上的武器的所属区域也得跟着变 + WeaponPack.ForEach((weapon, i) => + { + if (AffiliationArea != null) + { + AffiliationArea.InsertItem(weapon); + } + else if (weapon.AffiliationArea != null) + { + weapon.AffiliationArea.RemoveItem(weapon); + } + }); + } + + public virtual void LookTargetPosition(Vector2 pos) + { + LookPosition = pos; + if (MountLookTarget) + { + //脸的朝向 + var gPos = Position; + if (pos.X > gPos.X && Face == FaceDirection.Left) + { + Face = FaceDirection.Right; + } + else if (pos.X < gPos.X && Face == FaceDirection.Right) + { + Face = FaceDirection.Left; + } + //枪口跟随目标 + MountPoint.SetLookAt(pos); + } + } + + /// + /// 返回所有武器是否弹药都打光了 + /// + public virtual bool IsAllWeaponTotalAmmoEmpty() + { + foreach (var weapon in WeaponPack.ItemSlot) + { + if (weapon != null && !weapon.IsTotalAmmoEmpty()) + { + return false; + } + } + + return true; + } + + //------------------------------------------------------------------------------------- + + /// + /// 拾起一个武器, 返回是否成功拾起, 如果不想立刻切换到该武器, exchange 请传 false + /// + /// 武器对象 + /// 是否立即切换到该武器, 默认 true + public bool PickUpWeapon(Weapon weapon, bool exchange = true) + { + if (WeaponPack.PickupItem(weapon, exchange) != -1) + { + //从可互动队列中移除 + InteractiveItemList.Remove(weapon); + OnPickUpWeapon(weapon); + return true; + } + + return false; + } + + /// + /// 切换到下一个武器 + /// + public void ExchangeNextWeapon() + { + var weapon = WeaponPack.ActiveItem; + WeaponPack.ExchangeNext(); + if (WeaponPack.ActiveItem != weapon) + { + OnExchangeWeapon(WeaponPack.ActiveItem); + } + } + + /// + /// 切换到上一个武器 + /// + public void ExchangePrevWeapon() + { + var weapon = WeaponPack.ActiveItem; + WeaponPack.ExchangePrev(); + if (WeaponPack.ActiveItem != weapon) + { + OnExchangeWeapon(WeaponPack.ActiveItem); + } + } + + /// + /// 扔掉当前使用的武器, 切换到上一个武器 + /// + public void ThrowWeapon() + { + ThrowWeapon(WeaponPack.ActiveIndex); + } + + /// + /// 扔掉指定位置的武器 + /// + /// 武器在武器背包中的位置 + public void ThrowWeapon(int index) + { + var weapon = WeaponPack.GetItem(index); + if (weapon == null) + { + return; + } + + var temp = weapon.AnimatedSprite.Position; + if (Face == FaceDirection.Left) + { + temp.Y = -temp.Y; + } + //var pos = GlobalPosition + temp.Rotated(weapon.GlobalRotation); + WeaponPack.RemoveItem(index); + //播放抛出效果 + weapon.ThrowWeapon(this, GlobalPosition); + } + + /// + /// 扔掉所有武器 + /// + public void ThrowAllWeapon() + { + var weapons = WeaponPack.GetAndClearItem(); + for (var i = 0; i < weapons.Length; i++) + { + weapons[i].ThrowWeapon(this); + } + } + + /// + /// 切换到下一个武器 + /// + public void ExchangeNextActiveProp() + { + var prop = ActivePropsPack.ActiveItem; + ActivePropsPack.ExchangeNext(); + if (prop != ActivePropsPack.ActiveItem) + { + OnExchangeActiveProp(ActivePropsPack.ActiveItem); + } + } + + /// + /// 切换到上一个武器 + /// + public void ExchangePrevActiveProp() + { + var prop = ActivePropsPack.ActiveItem; + ActivePropsPack.ExchangePrev(); + if (prop != ActivePropsPack.ActiveItem) + { + OnExchangeActiveProp(ActivePropsPack.ActiveItem); + } + } + + //------------------------------------------------------------------------------------- + + + /// + /// 触发换弹 + /// + public virtual void Reload() + { + if (WeaponPack.ActiveItem != null) + { + WeaponPack.ActiveItem.Reload(); + } + } + + /// + /// 攻击函数 + /// + public virtual void Attack() + { + if (MeleeAttackTimer <= 0 && WeaponPack.ActiveItem != null) + { + WeaponPack.ActiveItem.Trigger(this); + } + } + + /// + /// 触发近战攻击 + /// + public virtual void MeleeAttack() + { + if (IsAttack) + { + return; + } + + if (WeaponPack.ActiveItem != null && !WeaponPack.ActiveItem.Reloading && WeaponPack.ActiveItem.Attribute.CanMeleeAttack) + { + MeleeAttackTimer = RoleState.MeleeAttackTime; + MountLookTarget = false; + + //播放近战动画 + PlayAnimation_MeleeAttack(() => + { + MountLookTarget = true; + }); + } + } + + /// + /// 切换当前使用的武器的回调 + /// + private void OnChangeActiveItem(Weapon weapon) + { + //这里处理近战区域 + if (weapon != null) + { + MeleeAttackCollision.Polygon = Utils.CreateSectorPolygon( + Utils.ConvertAngle(-MeleeAttackAngle / 2f), + (weapon.GetLocalFirePosition() - weapon.GripPoint.Position).Length() * 1.2f, + MeleeAttackAngle, + 6 + ); + MeleeAttackArea.CollisionMask = AttackLayer | PhysicsLayer.Bullet; + } + } + + /// + /// 近战区域碰到敌人 + /// + private void OnMeleeAttackBodyEntered(Node2D body) + { + var activeWeapon = WeaponPack.ActiveItem; + if (activeWeapon == null) + { + return; + } + var activityObject = body.AsActivityObject(); + if (activityObject != null) + { + if (activityObject is Role role) //攻击角色 + { + var damage = Utils.Random.RandomConfigRange(activeWeapon.Attribute.MeleeAttackHarmRange); + damage = RoleState.CalcDamage(damage); + + //击退 + if (role is not Player) //目标不是玩家才会触发击退 + { + var attr = IsAi ? activeWeapon.AiUseAttribute : activeWeapon.PlayerUseAttribute; + var repel = Utils.Random.RandomConfigRange(attr.MeleeAttackRepelRange); + var position = role.GlobalPosition - MountPoint.GlobalPosition; + var v2 = position.Normalized() * repel; + role.AddRepelForce(v2); + } + + role.CallDeferred(nameof(Hurt), this, damage, (role.GetCenterPosition() - GlobalPosition).Angle()); + } + else if (activityObject is Bullet bullet) //攻击子弹 + { + var attackLayer = bullet.AttackLayer; + if (CollisionWithMask(attackLayer)) //是攻击玩家的子弹 + { + bullet.PlayDisappearEffect(); + bullet.Destroy(); + } + } + } + } + protected override void OnDestroy() { //销毁道具 @@ -851,5 +1306,7 @@ } BuffPropPack.Clear(); ActivePropsPack.Destroy(); + + WeaponPack.Destroy(); } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/RoleState.cs b/DungeonShooting_Godot/src/game/activity/role/RoleState.cs index 7344daf..2af6bf3 100644 --- a/DungeonShooting_Godot/src/game/activity/role/RoleState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/RoleState.cs @@ -7,6 +7,11 @@ public class RoleState { /// + /// 是否可以拾起武器 + /// + public bool CanPickUpWeapon = false; + + /// /// 移动速度 /// public float MoveSpeed = 120f; @@ -22,16 +27,6 @@ public float Friction = 900f; /// - /// 翻滚速度 - /// - public float RollSpeed = 180f; - - /// - /// 翻滚冷却时间 - /// - public float RollTime = 0.5f; - - /// /// 单格护盾恢复时间, 单位: 秒 /// public float ShieldRecoveryTime = 18; @@ -86,13 +81,13 @@ /// /// 武器初始散射值增量 /// - public event Action> CalcStartScatteringEvent; - public float CalcStartScattering(Weapon weapon, float value) + public event Action> CalcStartScatteringEvent; + public float CalcStartScattering(float value) { if (CalcStartScatteringEvent != null) { var result = new RefValue(value); - CalcStartScatteringEvent(weapon, value, result); + CalcStartScatteringEvent(value, result); return result.Value; } @@ -102,13 +97,13 @@ /// /// 武器最终散射值增量 /// - public event Action> CalcFinalScatteringEvent; - public float CalcFinalScattering(Weapon weapon, float value) + public event Action> CalcFinalScatteringEvent; + public float CalcFinalScattering(float value) { if (CalcFinalScatteringEvent != null) { var result = new RefValue(value); - CalcFinalScatteringEvent(weapon, value, result); + CalcFinalScatteringEvent(value, result); return result.Value; } @@ -118,13 +113,13 @@ /// /// 武器开火发射子弹数量 /// - public event Action> CalcBulletCountEvent; - public int CalcBulletCount(Weapon weapon, int count) + public event Action> CalcBulletCountEvent; + public int CalcBulletCount(int count) { if (CalcBulletCountEvent != null) { var result = new RefValue(count); - CalcBulletCountEvent(weapon, count, result); + CalcBulletCountEvent(count, result); return result.Value; } @@ -134,13 +129,13 @@ /// /// 子弹偏移角度, 角度制 /// - public event Action> CalcBulletDeviationAngleEvent; - public float CalcBulletDeviationAngle(Weapon weapon, float angle) + public event Action> CalcBulletDeviationAngleEvent; + public float CalcBulletDeviationAngle(float angle) { if (CalcBulletDeviationAngleEvent != null) { var result = new RefValue(angle); - CalcBulletDeviationAngleEvent(weapon, angle, result); + CalcBulletDeviationAngleEvent(angle, result); return result.Value; } @@ -150,13 +145,13 @@ /// /// 子弹速度 /// - public event Action> CalcBulletSpeedEvent; - public float CalcBulletSpeed(Weapon weapon, float speed) + public event Action> CalcBulletSpeedEvent; + public float CalcBulletSpeed(float speed) { if (CalcBulletSpeedEvent != null) { var result = new RefValue(speed); - CalcBulletSpeedEvent(weapon, speed, result); + CalcBulletSpeedEvent(speed, result); return result.Value; } @@ -166,13 +161,13 @@ /// /// 子弹射程 /// - public event Action> CalcBulletDistanceEvent; - public float CalcBulletDistance(Weapon weapon, float distance) + public event Action> CalcBulletDistanceEvent; + public float CalcBulletDistance(float distance) { if (CalcBulletDistanceEvent != null) { var result = new RefValue(distance); - CalcBulletDistanceEvent(weapon, distance, result); + CalcBulletDistanceEvent(distance, result); return result.Value; } @@ -182,13 +177,13 @@ /// /// 子弹击退 /// - public event Action> CalcBulletRepelEvent; - public float CalcBulletRepel(Weapon weapon, float distance) + public event Action> CalcBulletRepelEvent; + public float CalcBulletRepel(float distance) { if (CalcBulletRepelEvent != null) { var result = new RefValue(distance); - CalcBulletRepelEvent(weapon, distance, result); + CalcBulletRepelEvent(distance, result); return result.Value; } @@ -198,13 +193,13 @@ /// /// 子弹反弹次数 /// - public event Action> CalcBulletBounceCountEvent; - public int CalcBulletBounceCount(Weapon weapon, int distance) + public event Action> CalcBulletBounceCountEvent; + public int CalcBulletBounceCount(int distance) { if (CalcBulletBounceCountEvent != null) { var result = new RefValue(distance); - CalcBulletBounceCountEvent(weapon, distance, result); + CalcBulletBounceCountEvent(distance, result); return result.Value; } @@ -214,13 +209,13 @@ /// /// 子弹穿透次数 /// - public event Action> CalcBulletPenetrationEvent; - public int CalcBulletPenetration(Weapon weapon, int distance) + public event Action> CalcBulletPenetrationEvent; + public int CalcBulletPenetration(int distance) { if (CalcBulletPenetrationEvent != null) { var result = new RefValue(distance); - CalcBulletPenetrationEvent(weapon, distance, result); + CalcBulletPenetrationEvent(distance, result); return result.Value; } diff --git a/DungeonShooting_Godot/src/game/activity/role/Role_Animation.cs b/DungeonShooting_Godot/src/game/activity/role/Role_Animation.cs new file mode 100644 index 0000000..1dfcc68 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/Role_Animation.cs @@ -0,0 +1,78 @@ + +using System; +using Godot; +using Vector2 = Godot.Vector2; + +public partial class Role +{ + /// + /// 播放近战攻击动画 + /// + public virtual void PlayAnimation_MeleeAttack(Action finish) + { + var r = MountPoint.RotationDegrees; + //var gp = MountPoint.GlobalPosition; + var p1 = MountPoint.Position; + var p2 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r - MeleeAttackAngle / 2f)); + var p3 = p1 + new Vector2(6, 0).Rotated(Mathf.DegToRad(r + MeleeAttackAngle / 2f)); + + var tween = CreateTween(); + tween.SetParallel(); + + tween.TweenProperty(MountPoint, "rotation_degrees", r - MeleeAttackAngle / 2f, 0.1); + tween.TweenProperty(MountPoint, "position", p2, 0.1); + tween.TweenProperty(MountPoint, "position", p2, 0.1); + tween.Chain(); + + tween.TweenCallback(Callable.From(() => + { + MountPoint.RotationDegrees = r + MeleeAttackAngle / 2f; + MountPoint.Position = p3; + //重新计算武器阴影位置 + var activeItem = WeaponPack.ActiveItem; + activeItem.CalcShadowTransform(); + //创建屏幕抖动 + if (Face == FaceDirection.Right) + { + //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 90)) * 5); + GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 180)) * 6); + } + else + { + //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(270 - r)) * 5); + GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(-r)) * 6); + } + //播放特效 + var effect = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_weapon_MeleeAttack1_tscn); + var sprite = (Node2D)effect; + var localFirePosition = activeItem.GetLocalFirePosition() - activeItem.GripPoint.Position; + localFirePosition *= 0.9f; + sprite.Position = p1 + localFirePosition.Rotated(Mathf.DegToRad(r)); + sprite.RotationDegrees = r; + AddChild(sprite); + effect.PlayEffect(); + + //启用近战碰撞区域 + MeleeAttackCollision.Disabled = false; + })); + tween.Chain(); + + tween.TweenInterval(0.1f); + tween.Chain(); + + tween.TweenCallback(Callable.From(() => + { + //关闭近战碰撞区域 + MeleeAttackCollision.Disabled = true; + })); + tween.TweenProperty(MountPoint, "rotation_degrees", r, 0.2); + tween.TweenProperty(MountPoint, "position", p1, 0.2); + tween.Chain(); + + tween.TweenCallback(Callable.From(() => + { + finish(); + })); + tween.Play(); + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/SubLine.cs b/DungeonShooting_Godot/src/game/activity/role/SubLine.cs index 03039ac..5f9dd84 100644 --- a/DungeonShooting_Godot/src/game/activity/role/SubLine.cs +++ b/DungeonShooting_Godot/src/game/activity/role/SubLine.cs @@ -5,7 +5,7 @@ /// /// 瞄准辅助线 /// -public class SubLine : Component +public class SubLine : Component { /// /// 是否正在播放警告闪烁动画 diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AIStateEnum.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AIStateEnum.cs index 05dbbc5..9b923d5 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/AIStateEnum.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/AIStateEnum.cs @@ -1,18 +1,18 @@ -public enum AiStateEnum +public enum AIStateEnum { /// /// Ai 状态, 正常, 未发现目标 /// AiNormal, - // /// - // /// 发现目标, 但不知道在哪 - // /// - // AiProbe, /// /// 找到玩家,准备通知其他敌人 /// - AiFind, + AiNotify, + /// + /// 惊讶状态 + /// + AiAstonished, /// /// 收到其他敌人通知, 前往发现目标的位置 /// @@ -33,4 +33,8 @@ /// Ai 寻找弹药 /// AiFindAmmo, + /// + /// Ai攻击 + /// + AiAttack, } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs deleted file mode 100644 index 46b5c5c..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs +++ /dev/null @@ -1,509 +0,0 @@ -#region 基础敌人设计思路 -/* -敌人有三种状态: -状态1: 未发现玩家, 视野不可穿墙, 该状态下敌人移动比较规律, 移动速度较慢, 一旦玩家进入视野或者听到玩家枪声, 立刻切换至状态3, 该房间的敌人不能再回到状态1 -状态2: 发现有玩家, 但不知道在哪, 视野不可穿墙, 该情况下敌人移动速度明显加快, 移动不规律, 一旦玩家进入视野或者听到玩家枪声, 立刻切换至状态3 -状态3: 明确知道玩家的位置, 视野允许穿墙, 移动速度与状态2一致, 进入该状态时, 敌人之间会相互告知玩家所在位置, 并朝着玩家位置开火, - 如果有墙格挡, 则有一定概率继续开火, 一旦玩家立刻敌人视野超哥一段时间, 敌人自动切换为状态2 - -敌人状态1只存在于少数房间内, 比如特殊房间, 大部分情况下敌人应该是状态2, 或者玩家进入房间时就被敌人发现 -*/ -#endregion - - -using System; -using AdvancedState; -using Godot; - -/// -/// 高级敌人,可以携带武器 -/// -[Tool] -public partial class AdvancedEnemy : AdvancedRole -{ - /// - /// 目标是否在视野内 - /// - public bool TargetInView { get; set; } = true; - - /// - /// 敌人身上的状态机控制器 - /// - public StateController StateController { get; private set; } - - /// - /// 视野半径, 单位像素, 发现玩家后改视野范围可以穿墙 - /// - public float ViewRange { get; set; } = 250; - - /// - /// 发现玩家后的视野半径 - /// - public float TailAfterViewRange { get; set; } = 400; - - /// - /// 背后的视野半径, 单位像素 - /// - public float BackViewRange { get; set; } = 50; - - /// - /// 视野检测射线, 朝玩家打射线, 检测是否碰到墙 - /// - [Export, ExportFillNode] - public RayCast2D ViewRay { get; private set; } - - /// - /// 导航代理 - /// - [Export, ExportFillNode] - public NavigationAgent2D NavigationAgent2D { get; private set; } - - /// - /// 导航代理中点 - /// - [Export, ExportFillNode] - public Marker2D NavigationPoint { get; private set; } - - /// - /// Ai攻击状态, 调用 Attack() 函数后会刷新 - /// - public AiAttackState AttackState { get; private set; } - - //锁定目标时间 - private float _lockTargetTime = 0; - - public override void OnInit() - { - base.OnInit(); - IsAi = true; - StateController = AddComponent>(); - - AttackLayer = PhysicsLayer.Wall | PhysicsLayer.Player; - EnemyLayer = PhysicsLayer.Player; - Camp = CampEnum.Camp2; - - RoleState.MoveSpeed = 20; - - MaxHp = 20; - Hp = 20; - - //PathSign = new PathSign(this, PathSignLength, GameApplication.Instance.Node3D.Player); - - //注册Ai状态机 - StateController.Register(new AiNormalState()); - //StateController.Register(new AiProbeState()); - StateController.Register(new AiTailAfterState()); - StateController.Register(new AiFollowUpState()); - StateController.Register(new AiLeaveForState()); - StateController.Register(new AiSurroundState()); - StateController.Register(new AiFindAmmoState()); - - //默认状态 - StateController.ChangeStateInstant(AiStateEnum.AiNormal); - } - - public override void EnterTree() - { - if (!World.Enemy_InstanceList.Contains(this)) - { - World.Enemy_InstanceList.Add(this); - } - } - - public override void ExitTree() - { - World.Enemy_InstanceList.Remove(this); - } - - protected override void OnDie() - { - //扔掉所有武器 - var weapons = WeaponPack.GetAndClearItem(); - for (var i = 0; i < weapons.Length; i++) - { - weapons[i].ThrowWeapon(this); - } - - var effPos = Position + new Vector2(0, -Altitude); - //血液特效 - var blood = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_enemy_EnemyBloodEffect_tscn); - blood.Position = effPos - new Vector2(0, 12); - blood.AddToActivityRoot(RoomLayerEnum.NormalLayer); - blood.PlayEffect(); - - //创建敌人碎片 - var count = Utils.Random.RandomRangeInt(3, 6); - for (var i = 0; i < count; i++) - { - var debris = Create(Ids.Id_effect0001); - debris.PutDown(effPos, RoomLayerEnum.NormalLayer); - debris.InheritVelocity(this); - } - - //派发敌人死亡信号 - EventManager.EmitEvent(EventEnum.OnEnemyDie, this); - Destroy(); - } - - protected override void Process(float delta) - { - base.Process(delta); - if (IsDie) - { - return; - } - //目标在视野内的时间 - var currState = StateController.CurrState; - if (currState == AiStateEnum.AiSurround || currState == AiStateEnum.AiFollowUp) - { - var weapon = WeaponPack.ActiveItem; - if (weapon != null) - { - if (weapon.GetBeLoadedStateState() >= 2 && !weapon.IsAttackIntervalTime()) //必须在可以开火时记录时间 - { - _lockTargetTime += delta; - } - else - { - _lockTargetTime = 0; - } - - if (AttackState == AiAttackState.LockingTime) //锁定玩家状态 - { - var aiLockRemainderTime = weapon.GetAiLockRemainderTime(); - MountLookTarget = aiLockRemainderTime >= weapon.Attribute.AiAttackAttr.LockAngleTime; - //更新瞄准辅助线 - if (weapon.Attribute.AiAttackAttr.ShowSubline) - { - if (SubLine == null) - { - InitSubLine(); - } - else - { - SubLine.Enable = true; - } - - //播放警告删掉动画 - if (!SubLine.IsPlayWarnAnimation && aiLockRemainderTime <= 0.5f) - { - SubLine.PlayWarnAnimation(0.5f); - } - } - } - else - { - //关闭辅助线 - if (SubLine != null) - { - SubLine.Enable = false; - } - - if (AttackState == AiAttackState.Attack || AttackState == AiAttackState.AttackInterval) - { - if (weapon.Attribute.AiAttackAttr.AttackLockAngle) //开火时锁定枪口角度 - { - //连发状态锁定角度 - MountLookTarget = !(weapon.GetContinuousCount() > 0 || weapon.GetAttackTimer() > 0); - } - else - { - MountLookTarget = true; - } - } - else - { - MountLookTarget = true; - } - } - } - else - { - MountLookTarget = true; - _lockTargetTime = 0; - } - } - else - { - MountLookTarget = true; - _lockTargetTime = 0; - } - - //拾起武器操作 - EnemyPickUpWeapon(); - } - - protected override void OnHit(int damage, bool realHarm) - { - //受到伤害 - var state = StateController.CurrState; - if (state == AiStateEnum.AiNormal || state == AiStateEnum.AiLeaveFor) //|| state == AiStateEnum.AiProbe - { - StateController.ChangeState(AiStateEnum.AiTailAfter); - } - } - - /// - /// 返回地上的武器是否有可以拾取的, 也包含没有被其他敌人标记的武器 - /// - 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; - } - - /// - /// 检查是否能切换到 AiStateEnum.AiLeaveFor 状态 - /// - public bool CanChangeLeaveFor() - { - if (!World.Enemy_IsFindTarget) - { - return false; - } - - var currState = StateController.CurrState; - if (currState == AiStateEnum.AiNormal)// || currState == AiStateEnum.AiProbe) - { - //判断是否在同一个房间内 - return World.Enemy_FindTargetAffiliationSet.Contains(AffiliationArea); - } - - return false; - } - - public override void Attack() - { - var weapon = WeaponPack.ActiveItem; - if (weapon != null) - { - AttackState = weapon.AiTriggerAttackState(); - } - else //没有武器 - { - AttackState = AiAttackState.NoWeapon; - } - } - - /// - /// 获取武器攻击范围 (最大距离值与最小距离的中间值) - /// - /// 从最小到最大距离的过渡量, 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) <= ViewRange * ViewRange) //没有超出视野半径 - { - return true; - } - } - - return false; - } - - /// - /// 返回目标点是否在跟随状态下的视野半径内 - /// - public bool IsInTailAfterViewRange(Vector2 target) - { - var isForward = IsPositionInForward(target); - if (isForward) - { - if (GlobalPosition.DistanceSquaredTo(target) <= TailAfterViewRange * TailAfterViewRange) //没有超出视野半径 - { - return true; - } - } - - return false; - } - - /// - /// 调用视野检测, 如果被墙壁和其它物体遮挡, 则返回被挡住视野的物体对象, 视野无阻则返回 null - /// - 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) - { - return; - } - - //拾起地上的武器 - if (InteractiveItem is Weapon weapon) - { - if (WeaponPack.ActiveItem == null) //手上没有武器, 无论如何也要拾起 - { - TriggerInteractive(); - return; - } - - //没弹药了 - if (weapon.IsTotalAmmoEmpty()) - { - return; - } - - var index = WeaponPack.FindIndex((we, i) => we.ItemConfig.Id == weapon.ItemConfig.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 GetLockTime() - { - return _lockTargetTime; - } - - /// - /// 强制设置锁定目标时间 - /// - public void SetLockTargetTime(float time) - { - _lockTargetTime = time; - } -} diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs deleted file mode 100644 index 62bc132..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs +++ /dev/null @@ -1,43 +0,0 @@ - -/// -/// 调用 Enemy.EnemyAttack() 函数返回的结果 -/// -public enum AiAttackState -{ - /// - /// 未触发 EnemyAttack() - /// - None, - /// - /// 触发切换武器 - /// - ExchangeWeapon, - /// - /// 没有弹药了 - /// - NoAmmo, - /// - /// 换弹中 - /// - Reloading, - /// - /// 触发换弹 - /// - TriggerReload, - /// - /// 没有武器 - /// - NoWeapon, - /// - /// 正在锁定目标中 - /// - LockingTime, - /// - /// 攻击间隙时间 - /// - AttackInterval, - /// - /// 成功触发攻击 - /// - Attack, -} \ 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 a27cedc..ae95977 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs @@ -1,9 +1,24 @@ - +#region 基础敌人设计思路 +/* +敌人有三种状态: +状态1: 未发现玩家, 视野不可穿墙, 该状态下敌人移动比较规律, 移动速度较慢, 一旦玩家进入视野或者听到玩家枪声, 立刻切换至状态3, 该房间的敌人不能再回到状态1 +状态2: 发现有玩家, 但不知道在哪, 视野不可穿墙, 该情况下敌人移动速度明显加快, 移动不规律, 一旦玩家进入视野或者听到玩家枪声, 立刻切换至状态3 +状态3: 明确知道玩家的位置, 视野允许穿墙, 移动速度与状态2一致, 进入该状态时, 敌人之间会相互告知玩家所在位置, 并朝着玩家位置开火, + 如果有墙格挡, 则有一定概率继续开火, 一旦玩家立刻敌人视野超哥一段时间, 敌人自动切换为状态2 + +敌人状态1只存在于少数房间内, 比如特殊房间, 大部分情况下敌人应该是状态2, 或者玩家进入房间时就被敌人发现 +*/ +#endregion + + +using System; +using System.Collections.Generic; +using Config; +using EnemyState; using Godot; -using NnormalState; /// -/// 基础敌人 +/// 高级敌人,可以携带武器 /// [Tool] public partial class Enemy : Role @@ -16,54 +31,108 @@ /// /// 敌人身上的状态机控制器 /// - public StateController StateController { get; private set; } - - /// - /// 视野半径, 单位像素, 发现玩家后改视野范围可以穿墙 - /// - public float ViewRange { get; set; } = 250; - - /// - /// 发现玩家后的视野半径 - /// - public float TailAfterViewRange { get; set; } = 400; - - /// - /// 背后的视野半径, 单位像素 - /// - public float BackViewRange { get; set; } = 50; - + public StateController StateController { get; private set; } + /// /// 视野检测射线, 朝玩家打射线, 检测是否碰到墙 /// [Export, ExportFillNode] - public RayCast2D ViewRay { get; private set; } + public RayCast2D ViewRay { get; set; } /// /// 导航代理 /// [Export, ExportFillNode] - public NavigationAgent2D NavigationAgent2D { get; private set; } + public NavigationAgent2D NavigationAgent2D { get; set; } /// /// 导航代理中点 /// [Export, ExportFillNode] - public Marker2D NavigationPoint { get; private set; } + public Marker2D NavigationPoint { get; set; } /// - /// Ai攻击状态, 调用 Attack() 函数后会刷新 + /// 不通过武发射子弹的开火点 /// - public AiAttackState AttackState { get; private set; } + [Export, ExportFillNode] + public Marker2D FirePoint { get; set; } - //锁定目标时间 - private float _lockTargetTime = 0; + /// + /// 当前敌人所看向的对象, 也就是枪口指向的对象 + /// + 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; + + private static bool _init = false; + private static Dictionary _enemyAttributeMap = + new Dictionary(); + + /// + /// 初始化敌人属性数据 + /// + public static void InitEnemyAttribute() + { + if (_init) + { + return; + } + + _init = true; + foreach (var enemyAttr in ExcelConfig.EnemyBase_List) + { + if (enemyAttr.Activity != null) + { + if (!_enemyAttributeMap.TryAdd(enemyAttr.Activity.Id, enemyAttr)) + { + Debug.LogError("发现重复注册的敌人属性: " + enemyAttr.Id); + } + } + } + } + + /// + /// 根据 ActivityBase.Id 获取对应敌人的属性数据 + /// + public static ExcelConfig.EnemyBase GetEnemyAttribute(string itemId) + { + if (itemId == null) + { + return null; + } + if (_enemyAttributeMap.TryGetValue(itemId, out var attr)) + { + return attr; + } + + throw new Exception($"敌人'{itemId}'没有在 EnemyBase 表中配置属性数据!"); + } + public override void OnInit() { base.OnInit(); + IsAi = true; - StateController = AddComponent>(); + + StateController = AddComponent>(); AttackLayer = PhysicsLayer.Wall | PhysicsLayer.Player; EnemyLayer = PhysicsLayer.Player; @@ -73,11 +142,37 @@ MaxHp = 20; Hp = 20; - + + //注册Ai状态机 StateController.Register(new AiNormalState()); StateController.Register(new AiTailAfterState()); StateController.Register(new AiFollowUpState()); - StateController.ChangeState(AiStateEnum.AiNormal); + 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); + } + + protected override RoleState OnCreateRoleState() + { + var roleState = new EnemyRoleState(); + EnemyRoleState = roleState; + var enemyBase = GetEnemyAttribute(ActivityBase.Id).Clone(); + _enemyAttribute = enemyBase; + + roleState.CanPickUpWeapon = enemyBase.CanPickUpWeapon; + roleState.MoveSpeed = enemyBase.MoveSpeed; + roleState.Acceleration = enemyBase.Acceleration; + roleState.Friction = enemyBase.Friction; + roleState.ViewRange = enemyBase.ViewRange; + roleState.TailAfterViewRange = enemyBase.TailAfterViewRange; + roleState.BackViewRange = enemyBase.BackViewRange; + return roleState; } public override void EnterTree() @@ -93,65 +188,208 @@ World.Enemy_InstanceList.Remove(this); } - public override void Attack() - { - Debug.Log("触发攻击"); - } - - protected override void OnHit(int damage, bool realHarm) - { - //受到伤害 - var state = StateController.CurrState; - if (state == AiStateEnum.AiNormal || state == AiStateEnum.AiLeaveFor) //|| state == AiStateEnum.AiProbe - { - StateController.ChangeState(AiStateEnum.AiTailAfter); - } - } - protected override void OnDie() { + //扔掉所有武器 + ThrowAllWeapon(); + var effPos = Position + new Vector2(0, -Altitude); //血液特效 - var blood = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_enemy_EnemyBloodEffect_tscn); + var blood = ObjectManager.GetPoolItem(ResourcePath.prefab_effect_enemy_EnemyBlood0001_tscn); blood.Position = effPos - new Vector2(0, 12); blood.AddToActivityRoot(RoomLayerEnum.NormalLayer); blood.PlayEffect(); + var realVelocity = GetRealVelocity(); //创建敌人碎片 var count = Utils.Random.RandomRangeInt(3, 6); for (var i = 0; i < count; i++) { - var debris = Create(Ids.Id_effect0001); + var debris = Create(Ids.Id_enemy_dead0001); debris.PutDown(effPos, RoomLayerEnum.NormalLayer); - debris.InheritVelocity(this); + debris.MoveController.AddForce(Velocity + realVelocity); } //派发敌人死亡信号 EventManager.EmitEvent(EventEnum.OnEnemyDie, this); Destroy(); } - - /// - /// 检查是否能切换到 AiStateEnum.AiLeaveFor 状态 - /// - public bool CanChangeLeaveFor() + + protected override void Process(float delta) { - if (!World.Enemy_IsFindTarget) + base.Process(delta); + if (IsDie) + { + return; + } + + //看向目标 + if (LookTarget != null && MountLookTarget) + { + var pos = LookTarget.Position; + LookPosition = pos; + //脸的朝向 + var gPos = Position; + if (pos.X > gPos.X && Face == FaceDirection.Left) + { + Face = FaceDirection.Right; + } + else if (pos.X < gPos.X && Face == FaceDirection.Right) + { + Face = FaceDirection.Left; + } + //枪口跟随目标 + MountPoint.SetLookAt(pos); + } + + //拾起武器操作 + EnemyPickUpWeapon(); + } + + public override bool IsAllWeaponTotalAmmoEmpty() + { + if (!_enemyAttribute.CanPickUpWeapon) { return false; } + return base.IsAllWeaponTotalAmmoEmpty(); + } - var currState = StateController.CurrState; - if (currState == AiStateEnum.AiNormal)// || currState == AiStateEnum.AiProbe) + protected override void OnHit(ActivityObject target, int damage, float angle, bool realHarm) + { + //受到伤害 + var state = StateController.CurrState; + if (state == AIStateEnum.AiNormal) { - //判断是否在同一个房间内 - return World.Enemy_FindTargetAffiliationSet.Contains(AffiliationArea); + LookTarget = target; + //判断是否进入通知状态 + if (World.Enemy_InstanceList.FindIndex(enemy => + enemy != this && !enemy.IsDie && enemy.AffiliationArea == AffiliationArea && + enemy.StateController.CurrState == AIStateEnum.AiNormal) != -1) + { + //进入惊讶状态, 然后再进入通知状态 + StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiNotify); + } + else + { + //进入惊讶状态, 然后再进入跟随状态 + StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiTailAfter); + } } - + else if (state == AIStateEnum.AiLeaveFor) + { + LookTarget = target; + StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiTailAfter); + } + } + + /// + /// 返回地上的武器是否有可以拾取的, 也包含没有被其他敌人标记的武器 + /// + 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) @@ -159,7 +397,7 @@ var isForward = IsPositionInForward(target); if (isForward) { - if (GlobalPosition.DistanceSquaredTo(target) <= ViewRange * ViewRange) //没有超出视野半径 + if (GlobalPosition.DistanceSquaredTo(target) <= EnemyRoleState.ViewRange * EnemyRoleState.ViewRange) //没有超出视野半径 { return true; } @@ -176,7 +414,7 @@ var isForward = IsPositionInForward(target); if (isForward) { - if (GlobalPosition.DistanceSquaredTo(target) <= TailAfterViewRange * TailAfterViewRange) //没有超出视野半径 + if (GlobalPosition.DistanceSquaredTo(target) <= EnemyRoleState.TailAfterViewRange * EnemyRoleState.TailAfterViewRange) //没有超出视野半径 { return true; } @@ -186,7 +424,7 @@ } /// - /// 调用视野检测, 如果被墙壁和其它物体遮挡, 则返回被挡住视野的物体对象, 视野无阻则返回 null + /// 调用视野检测, 如果被墙壁和其它物体遮挡, 则返回true /// public bool TestViewRayCast(Vector2 target) { @@ -203,29 +441,120 @@ { 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 GetLockTime() + public float GetLockRemainderTime() { - return _lockTargetTime; + 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() + { + AnimatedSprite.Play(AnimatorNames.Run); + //计算移动 + var nextPos = NavigationAgent2D.GetNextPathPosition(); + BasisVelocity = (nextPos - Position - NavigationPoint.Position).Normalized() * RoleState.MoveSpeed; } /// - /// 强制设置锁定目标时间 + /// 执行站立操作 /// - public void SetLockTargetTime(float time) + public void DoIdle() { - _lockTargetTime = time; + AnimatedSprite.Play(AnimatorNames.Idle); + BasisVelocity = Vector2.Zero; } /// - /// 获取攻击范围 + /// 更新房间中标记的目标位置 /// - /// 从最小到最大距离的过渡量, 0 - 1, 默认 0.5 - public float GetAttackRange(float weight = 0.5f) + public void UpdateMarkTargetPosition() { - return 200; + if (LookTarget != null) + { + AffiliationArea.RoomInfo.MarkTargetPosition[LookTarget.Id] = LookTarget.Position; + } } -} \ No newline at end of file + + /// + /// 从标记出生时调用, 预加载波不会调用 + /// + public virtual void OnBornFromMark() + { + //罚站 0.7 秒 + StateController.Enable = false; + this.CallDelay(0.7f, () => StateController.Enable = true); + } +} diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/EnemyRoleState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/EnemyRoleState.cs new file mode 100644 index 0000000..174b52e --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/EnemyRoleState.cs @@ -0,0 +1,18 @@ + +public class EnemyRoleState : RoleState +{ + /// + /// 视野半径, 单位像素, 发现玩家后改视野范围可以穿墙 + /// + public float ViewRange = 250; + + /// + /// 发现玩家后跟随玩家的视野半径 + /// + public float TailAfterViewRange = 400; + + /// + /// 背后的视野半径, 单位像素 + /// + public float BackViewRange = 50; +} \ 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 new file mode 100644 index 0000000..62352c2 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs @@ -0,0 +1,60 @@ + +using Config; +using Godot; + +/// +/// 没有武器的敌人 +/// +[Tool] +public partial class NoWeaponEnemy : Enemy +{ + public override void OnInit() + { + base.OnInit(); + NoWeaponAttack = true; + AnimationPlayer.AnimationFinished += OnAnimationFinished; + } + + public override void Attack() + { + if (AnimationPlayer.CurrentAnimation != AnimatorNames.Attack) + { + AnimationPlayer.Play(AnimatorNames.Attack); + } + } + + public void ShootBullet() + { + var targetPosition = LookTarget.GetCenterPosition(); + var bulletData = FireManager.GetBulletData(this, 0, ExcelConfig.BulletBase_Map["0006"]); + for (var i = 0; i < 8; i++) + { + var data = bulletData.Clone(); + var tempPos = new Vector2(targetPosition.X + Utils.Random.RandomRangeInt(-30, 30), targetPosition.Y + + Utils.Random.RandomRangeInt(-30, 30)); + FireManager.SetParabolaTarget(data, tempPos); + FireManager.ShootBullet(data, AttackLayer); + } + } + + protected override void OnDie() + { + var realVelocity = GetRealVelocity(); + var effPos = Position; + var debris = Create(Ids.Id_enemy_dead0002); + debris.PutDown(effPos, RoomLayerEnum.NormalLayer); + debris.MoveController.AddForce(Velocity + realVelocity); + debris.SetFace(Face); + + //派发敌人死亡信号 + EventManager.EmitEvent(EventEnum.OnEnemyDie, this); + Destroy(); + } + + private void OnAnimationFinished(StringName name) + { + if (name == AnimatorNames.Attack) + { + AttackTimer = 2f; + } + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFindAmmoState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFindAmmoState.cs deleted file mode 100644 index ab9ef33..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFindAmmoState.cs +++ /dev/null @@ -1,154 +0,0 @@ - -using Godot; - -namespace AdvancedState; - -/// -/// Ai 寻找弹药, 进入该状态需要在参数中传入目标武器对象 -/// -public class AiFindAmmoState : StateBase -{ - - private Weapon _target; - - //导航目标点刷新计时器 - private float _navigationUpdateTimer = 0; - private float _navigationInterval = 1f; - - private bool _isInTailAfterRange = false; - private float _tailAfterTimer = 0; - - public AiFindAmmoState() : base(AiStateEnum.AiFindAmmo) - { - } - - public override void Enter(AiStateEnum prev, params object[] args) - { - if (args.Length == 0) - { - Debug.LogError("进入 AiStateEnum.AiFindAmmo 状态必须要把目标武器当成参数传过来"); - ChangeState(prev); - return; - } - - SetTargetWeapon((Weapon)args[0]); - _navigationUpdateTimer = 0; - _isInTailAfterRange = false; - _tailAfterTimer = 0; - - //标记武器 - _target.SetSign(SignNames.AiFindWeaponSign, Master); - } - - public override void Process(float delta) - { - if (!Master.IsAllWeaponTotalAmmoEmpty()) //已经有弹药了 - { - ChangeState(GetNextState()); - return; - } - - //更新目标位置 - if (_navigationUpdateTimer <= 0) - { - //每隔一段时间秒更改目标位置 - _navigationUpdateTimer = _navigationInterval; - var position = _target.GlobalPosition; - Master.NavigationAgent2D.TargetPosition = position; - } - else - { - _navigationUpdateTimer -= delta; - } - - var playerPos = Player.Current.GetCenterPosition(); - //枪口指向玩家 - Master.LookTargetPosition(playerPos); - - if (_target.IsDestroyed || _target.IsTotalAmmoEmpty()) //已经被销毁, 或者弹药已经被其他角色捡走 - { - //再去寻找其他武器 - SetTargetWeapon(Master.FindTargetWeapon()); - - if (_target == null) //也没有其他可用的武器了 - { - ChangeState(GetNextState()); - } - } - else if (_target.Master == Master) //已经被自己拾起 - { - ChangeState(GetNextState()); - } - else if (_target.Master != null) //武器已经被其他角色拾起! - { - //再去寻找其他武器 - SetTargetWeapon(Master.FindTargetWeapon()); - - if (_target == null) //也没有其他可用的武器了 - { - ChangeState(GetNextState()); - } - } - else - { - //检测目标没有超出跟随视野距离 - _isInTailAfterRange = Master.IsInTailAfterViewRange(playerPos); - if (_isInTailAfterRange) - { - _tailAfterTimer = 0; - } - else - { - _tailAfterTimer += delta; - } - - //向武器移动 - if (!Master.NavigationAgent2D.IsNavigationFinished()) - { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = - (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - } - else - { - Master.BasisVelocity = Vector2.Zero; - } - } - } - - private AiStateEnum GetNextState() - { - return _tailAfterTimer > 10 ? AiStateEnum.AiNormal : AiStateEnum.AiTailAfter; - } - - private void SetTargetWeapon(Weapon weapon) - { - _target = weapon; - //设置目标点 - if (_target != null) - { - Master.NavigationAgent2D.TargetPosition = _target.GlobalPosition; - } - } - - public override void DebugDraw() - { - if (_target != null) - { - Master.DrawLine(Vector2.Zero, Master.ToLocal(_target.GlobalPosition), Colors.Purple); - - if (_tailAfterTimer <= 0) - { - Master.DrawLine(Vector2.Zero, Master.ToLocal(Player.Current.GetCenterPosition()), Colors.Orange); - } - else if (_tailAfterTimer <= 10) - { - Master.DrawLine(Vector2.Zero, Master.ToLocal(Player.Current.GetCenterPosition()), Colors.Blue); - } - - } - } -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs deleted file mode 100644 index 904b327..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiFollowUpState.cs +++ /dev/null @@ -1,132 +0,0 @@ - -using Godot; - -namespace AdvancedState; - -/// -/// 目标在视野内, 跟进目标, 如果距离在子弹有效射程内, 则开火 -/// -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) - { - _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 = Player.Current.GetCenterPosition(); - - //更新玩家位置 - if (_navigationUpdateTimer <= 0) - { - //每隔一段时间秒更改目标位置 - _navigationUpdateTimer = _navigationInterval; - Master.NavigationAgent2D.TargetPosition = playerPos; - } - else - { - _navigationUpdateTimer -= delta; - } - - var masterPosition = Master.GlobalPosition; - - //是否在攻击范围内 - var inAttackRange = false; - - var weapon = Master.WeaponPack.ActiveItem; - if (weapon != null) - { - inAttackRange = masterPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(Master.GetWeaponRange(0.7f), 2); - } - - //枪口指向玩家 - Master.LookTargetPosition(playerPos); - - if (!Master.NavigationAgent2D.IsNavigationFinished()) - { - if (weapon == null || !weapon.Attribute.AiAttackAttr.FiringStand || - (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)) - { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - masterPosition - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - } - else - { - Master.AnimatedSprite.Play(AnimatorNames.Idle); - Master.BasisVelocity = Vector2.Zero; - } - } - else - { - Master.BasisVelocity = Vector2.Zero; - } - - //检测玩家是否在视野内 - if (Master.IsInTailAfterViewRange(playerPos)) - { - Master.TargetInView = !Master.TestViewRayCast(playerPos); - //关闭射线检测 - Master.TestViewRayCastOver(); - } - else - { - Master.TargetInView = false; - } - - //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑 - if (Master.TargetInView || Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack) - { - if (inAttackRange) //在攻击范围内 - { - //发起攻击 - Master.Attack(); - - //距离够近, 可以切换到环绕模式 - if (Master.GlobalPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange), 2) * 0.7f) - { - ChangeState(AiStateEnum.AiSurround); - } - } - } - else //不在视野中 - { - ChangeState(AiStateEnum.AiTailAfter); - } - } - - public override void DebugDraw() - { - var playerPos = Player.Current.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/advancedState/AiLeaveForState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiLeaveForState.cs deleted file mode 100644 index 73e339b..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiLeaveForState.cs +++ /dev/null @@ -1,103 +0,0 @@ - -using Godot; - -namespace AdvancedState; - -/// -/// 收到其他敌人通知, 前往发现目标的位置 -/// -public class AiLeaveForState : StateBase -{ - //导航目标点刷新计时器 - private float _navigationUpdateTimer = 0; - private float _navigationInterval = 0.3f; - - public AiLeaveForState() : base(AiStateEnum.AiLeaveFor) - { - } - - public override void Enter(AiStateEnum prev, params object[] args) - { - if (Master.World.Enemy_IsFindTarget) - { - Master.NavigationAgent2D.TargetPosition = Master.World.Enemy_FindTargetPosition; - } - else - { - ChangeState(prev); - return; - } - - //先检查弹药是否打光 - if (Master.IsAllWeaponTotalAmmoEmpty()) - { - //再寻找是否有可用的武器 - var targetWeapon = Master.FindTargetWeapon(); - if (targetWeapon != null) - { - ChangeState(AiStateEnum.AiFindAmmo, targetWeapon); - } - } - } - - public override void Process(float delta) - { - //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽 - - //更新玩家位置 - if (_navigationUpdateTimer <= 0) - { - //每隔一段时间秒更改目标位置 - _navigationUpdateTimer = _navigationInterval; - Master.NavigationAgent2D.TargetPosition = Master.World.Enemy_FindTargetPosition; - } - else - { - _navigationUpdateTimer -= delta; - } - - if (!Master.NavigationAgent2D.IsNavigationFinished()) - { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.LookTargetPosition(Master.World.Enemy_FindTargetPosition); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - } - else - { - Master.BasisVelocity = Vector2.Zero; - } - - var playerPos = Player.Current.GetCenterPosition(); - //检测玩家是否在视野内, 如果在, 则切换到 AiTargetInView 状态 - if (Master.IsInTailAfterViewRange(playerPos)) - { - if (!Master.TestViewRayCast(playerPos)) //看到玩家 - { - //关闭射线检测 - Master.TestViewRayCastOver(); - //切换成发现目标状态 - ChangeState(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/advancedState/AiNormalState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiNormalState.cs deleted file mode 100644 index 5f469d1..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiNormalState.cs +++ /dev/null @@ -1,183 +0,0 @@ - -using Godot; - -namespace AdvancedState; - -/// -/// AI 正常状态 -/// -public class AiNormalState : StateBase -{ - //是否发现玩家 - private bool _isFindPlayer; - - //下一个运动的坐标 - 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) - { - _isFindPlayer = false; - _isMoveOver = true; - _againstWall = false; - _againstWallNormalAngle = 0; - _pauseTimer = 0; - _moveFlag = false; - } - - public override void Process(float delta) - { - //其他敌人发现玩家 - if (Master.CanChangeLeaveFor()) - { - ChangeState(AiStateEnum.AiLeaveFor); - return; - } - - if (_isFindPlayer) //已经找到玩家了 - { - //现临时处理, 直接切换状态 - ChangeState(AiStateEnum.AiTailAfter); - } - else //没有找到玩家 - { - //检测玩家 - var player = Player.Current; - //玩家中心点坐标 - var playerPos = player.GetCenterPosition(); - - if (Master.IsInViewRange(playerPos) && !Master.TestViewRayCast(playerPos)) //发现玩家 - { - //发现玩家 - _isFindPlayer = true; - } - 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.BasisVelocity = Vector2.Zero; - } - else if (!_moveFlag) - { - _moveFlag = true; - var pos = Master.GlobalPosition; - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - _prevPos = pos; - } - else - { - var pos = Master.GlobalPosition; - var lastSlideCollision = Master.GetLastSlideCollision(); - if (lastSlideCollision != null && lastSlideCollision.GetCollider() is AdvancedRole) //碰到其他角色 - { - _pauseTimer = Utils.Random.RandomRangeFloat(0.1f, 0.5f); - _isMoveOver = true; - _moveFlag = false; - Master.BasisVelocity = Vector2.Zero; - } - else - { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - } - - 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/advancedState/AiProbeState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiProbeState.cs deleted file mode 100644 index 3f8a865..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiProbeState.cs +++ /dev/null @@ -1,20 +0,0 @@ -// -// /// -// /// Ai 不确定玩家位置 -// /// -// public class AiProbeState : StateBase -// { -// public AiProbeState() : base(AiStateEnum.AiProbe) -// { -// } -// -// public override void Process(float delta) -// { -// //其他敌人发现玩家 -// if (Master.CanChangeLeaveFor()) -// { -// ChangeState(AiStateEnum.AiLeaveFor); -// return; -// } -// } -// } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs deleted file mode 100644 index 39cdf6c..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiSurroundState.cs +++ /dev/null @@ -1,187 +0,0 @@ - -using Godot; - -namespace AdvancedState; - -/// -/// 距离目标足够近, 在目标附近随机移动, 并开火 -/// -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) - { - 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 = Player.Current.GetCenterPosition(); - var weapon = Master.WeaponPack.ActiveItem; - - //枪口指向玩家 - Master.LookTargetPosition(playerPos); - - //检测玩家是否在视野内 - if (Master.IsInTailAfterViewRange(playerPos)) - { - Master.TargetInView = !Master.TestViewRayCast(playerPos); - //关闭射线检测 - Master.TestViewRayCastOver(); - } - else - { - Master.TargetInView = false; - } - - //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑 - if (Master.TargetInView || - (weapon != null && weapon.Attribute.AiAttackAttr.FiringStand && - (Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack) - )) - { - if (_pauseTimer >= 0) - { - Master.AnimatedSprite.Play(AnimatorNames.Idle); - _pauseTimer -= delta; - } - else if (_isMoveOver) //移动已经完成 - { - RunOver(playerPos); - _isMoveOver = false; - } - else - { - 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.BasisVelocity = Vector2.Zero; - } - else if (!_moveFlag) - { - _moveFlag = true; - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = - (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - } - else - { - var pos = Master.GlobalPosition; - var lastSlideCollision = Master.GetLastSlideCollision(); - if (lastSlideCollision != null && lastSlideCollision.GetCollider() is AdvancedRole) //碰到其他角色 - { - _pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.3f); - _isMoveOver = true; - _moveFlag = false; - Master.BasisVelocity = Vector2.Zero; - } - else - { - //判断开火状态, 进行移动 - if (weapon == null || !weapon.Attribute.AiAttackAttr.FiringStand || - (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)) - { //正常移动 - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - } - else //站立不动 - { - Master.AnimatedSprite.Play(AnimatorNames.Idle); - Master.BasisVelocity = Vector2.Zero; - } - } - - if (_prevPos.DistanceSquaredTo(pos) <= 0.01f) - { - _lockTimer += delta; - } - else - { - _prevPos = pos; - } - } - - if (weapon != null) - { - var position = Master.GlobalPosition; - if (position.DistanceSquaredTo(playerPos) > Mathf.Pow(Master.GetWeaponRange(0.7f), 2)) //玩家离开正常射击范围 - { - ChangeState(AiStateEnum.AiFollowUp); - } - else - { - //发起攻击 - Master.Attack(); - } - } - } - } - 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/advancedState/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiTailAfterState.cs deleted file mode 100644 index 569690e..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiTailAfterState.cs +++ /dev/null @@ -1,137 +0,0 @@ - -using Godot; - -namespace AdvancedState; - -/// -/// 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) - { - _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 = Player.Current.GetCenterPosition(); - - //更新玩家位置 - if (_navigationUpdateTimer <= 0) - { - //每隔一段时间秒更改目标位置 - _navigationUpdateTimer = _navigationInterval; - Master.NavigationAgent2D.TargetPosition = playerPos; - } - else - { - _navigationUpdateTimer -= delta; - } - - //枪口指向玩家 - Master.LookTargetPosition(playerPos); - - if (!Master.NavigationAgent2D.IsNavigationFinished()) - { - var weapon = Master.WeaponPack.ActiveItem; - if (weapon == null || !weapon.Attribute.AiAttackAttr.FiringStand || - (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)) - { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - } - else - { - Master.AnimatedSprite.Play(AnimatorNames.Idle); - Master.BasisVelocity = Vector2.Zero; - } - } - else - { - Master.BasisVelocity = Vector2.Zero; - } - //检测玩家是否在视野内, 如果在, 则切换到 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 = Player.Current.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/normalState/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiFollowUpState.cs deleted file mode 100644 index 35c2caa..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiFollowUpState.cs +++ /dev/null @@ -1,108 +0,0 @@ - -using Godot; - -namespace NnormalState; - -/// -/// 目标在视野内, 跟进目标, 如果距离在子弹有效射程内, 则开火 -/// -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) - { - _navigationUpdateTimer = 0; - Master.TargetInView = true; - } - - public override void Process(float delta) - { - var playerPos = Player.Current.GetCenterPosition(); - - //更新玩家位置 - if (_navigationUpdateTimer <= 0) - { - //每隔一段时间秒更改目标位置 - _navigationUpdateTimer = _navigationInterval; - Master.NavigationAgent2D.TargetPosition = playerPos; - } - else - { - _navigationUpdateTimer -= delta; - } - - var masterPosition = Master.GlobalPosition; - - //是否在攻击范围内 - var inAttackRange = masterPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(Master.GetAttackRange(0.7f), 2); - - //枪口指向玩家 - Master.LookTargetPosition(playerPos); - - if (!Master.NavigationAgent2D.IsNavigationFinished()) - { - if (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack) - { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - masterPosition - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - } - else - { - Master.AnimatedSprite.Play(AnimatorNames.Idle); - Master.BasisVelocity = Vector2.Zero; - } - } - else - { - Master.BasisVelocity = Vector2.Zero; - } - - //检测玩家是否在视野内 - if (Master.IsInTailAfterViewRange(playerPos)) - { - Master.TargetInView = !Master.TestViewRayCast(playerPos); - //关闭射线检测 - Master.TestViewRayCastOver(); - } - else - { - Master.TargetInView = false; - } - - //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑 - if (Master.TargetInView || Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack) - { - if (inAttackRange) //在攻击范围内 - { - //发起攻击 - Master.Attack(); - - //距离够近, 可以切换到环绕模式 - // if (Master.GlobalPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange), 2) * 0.7f) - // { - // ChangeState(AiStateEnum.AiSurround); - // } - } - } - else //不在视野中 - { - ChangeState(AiStateEnum.AiTailAfter); - } - } - - public override void DebugDraw() - { - var playerPos = Player.Current.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/normalState/AiNormalState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiNormalState.cs deleted file mode 100644 index 9cf340a..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiNormalState.cs +++ /dev/null @@ -1,177 +0,0 @@ -using Godot; - -namespace NnormalState; - -/// -/// AI 正常状态 -/// -public class AiNormalState : StateBase -{ - //是否发现玩家 - private bool _isFindPlayer; - - //下一个运动的坐标 - 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) - { - _isFindPlayer = false; - _isMoveOver = true; - _againstWall = false; - _againstWallNormalAngle = 0; - _pauseTimer = 0; - _moveFlag = false; - } - - public override void Process(float delta) - { - //其他敌人发现玩家 - if (Master.CanChangeLeaveFor()) - { - ChangeState(AiStateEnum.AiLeaveFor); - return; - } - - if (_isFindPlayer) //已经找到玩家了 - { - //现临时处理, 直接切换状态 - ChangeState(AiStateEnum.AiTailAfter); - } - else //没有找到玩家 - { - //检测玩家 - var player = Player.Current; - //玩家中心点坐标 - var playerPos = player.GetCenterPosition(); - - if (Master.IsInViewRange(playerPos) && !Master.TestViewRayCast(playerPos)) //发现玩家 - { - //发现玩家 - _isFindPlayer = true; - } - 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.BasisVelocity = Vector2.Zero; - } - else if (!_moveFlag) - { - _moveFlag = true; - var pos = Master.GlobalPosition; - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - _prevPos = pos; - } - else - { - var pos = Master.GlobalPosition; - var lastSlideCollision = Master.GetLastSlideCollision(); - if (lastSlideCollision != null && lastSlideCollision.GetCollider() is AdvancedRole) //碰到其他角色 - { - _pauseTimer = Utils.Random.RandomRangeFloat(0.1f, 0.5f); - _isMoveOver = true; - _moveFlag = false; - Master.BasisVelocity = Vector2.Zero; - } - else - { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - pos - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - } - - 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); - } -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiTailAfterState.cs deleted file mode 100644 index 3d29972..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/normalState/AiTailAfterState.cs +++ /dev/null @@ -1,124 +0,0 @@ - -using Godot; - -namespace NnormalState; - -/// -/// 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) - { - _isInViewRange = true; - _navigationUpdateTimer = 0; - _viewTimer = 0; - } - - public override void Process(float delta) - { - //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽 - - var playerPos = Player.Current.GetCenterPosition(); - - //更新玩家位置 - if (_navigationUpdateTimer <= 0) - { - //每隔一段时间秒更改目标位置 - _navigationUpdateTimer = _navigationInterval; - Master.NavigationAgent2D.TargetPosition = playerPos; - } - else - { - _navigationUpdateTimer -= delta; - } - - //枪口指向玩家 - Master.LookTargetPosition(playerPos); - - if (!Master.NavigationAgent2D.IsNavigationFinished()) - { - if (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack) - { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; - } - else - { - Master.AnimatedSprite.Play(AnimatorNames.Idle); - Master.BasisVelocity = Vector2.Zero; - } - } - else - { - Master.BasisVelocity = Vector2.Zero; - } - //检测玩家是否在视野内, 如果在, 则切换到 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 = Player.Current.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/state/AiAstonishedState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiAstonishedState.cs new file mode 100644 index 0000000..c39aff9 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiAstonishedState.cs @@ -0,0 +1,56 @@ +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 new file mode 100644 index 0000000..6b70f5e --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiAttackState.cs @@ -0,0 +1,309 @@ +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 (!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(); + + 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); + } + } + } + } + + //没有武器的敌人攻击逻辑 + 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 new file mode 100644 index 0000000..108652c --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFindAmmoState.cs @@ -0,0 +1,202 @@ + +using System; +using Godot; + +namespace EnemyState; + +/// +/// Ai 寻找弹药, 进入该状态需要在参数中传入目标武器对象 +/// +public class AiFindAmmoState : StateBase +{ + + private Weapon _target; + + //导航目标点刷新计时器 + 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; + + //标记武器 + _target.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, _target); + return; + } + } + + //更新目标位置 + if (_navigationUpdateTimer <= 0) + { + //每隔一段时间秒更改目标位置 + _navigationUpdateTimer = _navigationInterval; + var position = _target.GlobalPosition; + Master.NavigationAgent2D.TargetPosition = position; + } + else + { + _navigationUpdateTimer -= delta; + } + + if (_target.IsDestroyed || _target.IsTotalAmmoEmpty()) //已经被销毁, 或者弹药已经被其他角色捡走 + { + //再去寻找其他武器 + SetTargetWeapon(Master.FindTargetWeapon()); + + if (_target == null) //也没有其他可用的武器了 + { + RunNextState(); + } + } + else if (_target.Master == Master) //已经被自己拾起 + { + RunNextState(); + } + else if (_target.Master != null) //武器已经被其他角色拾起! + { + //再去寻找其他武器 + SetTargetWeapon(Master.FindTargetWeapon()); + + if (_target == 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) + { + _target = weapon; + if (weapon != null) + { + //设置目标点 + Master.NavigationAgent2D.TargetPosition = _target.GlobalPosition; + } + } + + public override void DebugDraw() + { + if (_target != null) + { + Master.DrawLine(Vector2.Zero, Master.ToLocal(_target.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 new file mode 100644 index 0000000..c6ae3d6 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs @@ -0,0 +1,147 @@ + +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 (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 new file mode 100644 index 0000000..2ec0526 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiLeaveForState.cs @@ -0,0 +1,136 @@ + +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 new file mode 100644 index 0000000..c4635c9 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiNormalState.cs @@ -0,0 +1,178 @@ + +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 new file mode 100644 index 0000000..09a6b08 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiNotifyState.cs @@ -0,0 +1,37 @@ +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 new file mode 100644 index 0000000..2d3c914 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs @@ -0,0 +1,187 @@ + +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 (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 new file mode 100644 index 0000000..4fa2cc5 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs @@ -0,0 +1,128 @@ + +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 21e4ab7..72c65e9 100644 --- a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs +++ b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs @@ -6,7 +6,7 @@ /// 玩家角色基类, 所有角色都必须继承该类 /// [Tool] -public partial class Player : AdvancedRole +public partial class Player : Role { /// /// 获取当前操作的角色 @@ -18,6 +18,8 @@ /// public StateController StateController { get; private set; } + public PlayerRoleState PlayerRoleState { get; private set; } + /// /// 是否可以翻滚 /// @@ -52,6 +54,8 @@ MaxShield = 0; Shield = 0; + WeaponPack.SetCapacity(4); + // debug用 // RoleState.Acceleration = 3000; // RoleState.Friction = 3000; @@ -72,10 +76,17 @@ StateController.Register(new PlayerRollState()); //默认状态 StateController.ChangeStateInstant(PlayerStateEnum.Idle); - + //InitSubLine(); } + protected override RoleState OnCreateRoleState() + { + var roleState = new PlayerRoleState(); + PlayerRoleState = roleState; + return roleState; + } + protected override void Process(float delta) { base.Process(delta); @@ -90,24 +101,21 @@ } //脸的朝向 - if (LookTarget == null) + var gPos = Position; + Vector2 mousePos = InputManager.CursorPosition; + if (mousePos.X > gPos.X && Face == FaceDirection.Left) { - var gPos = GlobalPosition; - Vector2 mousePos = InputManager.CursorPosition; - if (mousePos.X > gPos.X && Face == FaceDirection.Left) - { - Face = FaceDirection.Right; - } - else if (mousePos.X < gPos.X && Face == FaceDirection.Right) - { - Face = FaceDirection.Left; - } + Face = FaceDirection.Right; + } + else if (mousePos.X < gPos.X && Face == FaceDirection.Right) + { + Face = FaceDirection.Left; + } - if (MountLookTarget) - { - //枪口跟随鼠标 - MountPoint.SetLookAt(mousePos); - } + if (MountLookTarget) + { + //枪口跟随鼠标 + MountPoint.SetLookAt(mousePos); } if (InputManager.ExchangeWeapon) //切换武器 @@ -186,14 +194,14 @@ { //Hurt(1000, 0); Hp = 0; - Hurt(1000, 0); + Hurt(this, 1000, 0); } else if (Input.IsKeyPressed(Key.O)) //测试用, 消灭房间内所有敌人 { var enemyList = AffiliationArea.FindIncludeItems(o => o.CollisionWithMask(PhysicsLayer.Enemy)); foreach (var enemy in enemyList) { - ((AdvancedEnemy)enemy).Hurt(1000, 0); + ((Enemy)enemy).Hurt(this, 1000, 0); } } // //测试用 @@ -209,6 +217,15 @@ // freezeSprite.ActivityObject.MoveController.AddForce(temp.Normalized() * 300 * (25f - temp.Length()) / 25f); // } // } + + if (Face == FaceDirection.Right) + { + TipRoot.Scale = Vector2.One; + } + else + { + TipRoot.Scale = new Vector2(-1, 1); + } } protected override void OnPickUpWeapon(Weapon weapon) @@ -227,7 +244,7 @@ return 1; } - protected override void OnHit(int damage, bool realHarm) + protected override void OnHit(ActivityObject target, int damage, float angle, bool realHarm) { //进入无敌状态 if (realHarm) //真实伤害 @@ -344,9 +361,9 @@ /// public void OverRoll() { - _rollCoolingTimer = RoleState.RollTime; + _rollCoolingTimer = PlayerRoleState.RollCoolingTime; } - + // protected override void DebugDraw() // { // base.DebugDraw(); diff --git a/DungeonShooting_Godot/src/game/activity/role/player/PlayerRoleState.cs b/DungeonShooting_Godot/src/game/activity/role/player/PlayerRoleState.cs new file mode 100644 index 0000000..a276605 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/player/PlayerRoleState.cs @@ -0,0 +1,18 @@ + +public class PlayerRoleState : RoleState +{ + /// + /// 翻滚速度 + /// + public float RollSpeed = 400f; + + /// + /// 翻滚持续时间 + /// + public float RollTime = 0.15f; + + /// + /// 翻滚冷却时间 + /// + public float RollCoolingTime = 0.5f; +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/player/state/PlayerRollState.cs b/DungeonShooting_Godot/src/game/activity/role/player/state/PlayerRollState.cs index 229b5df..f108c44 100644 --- a/DungeonShooting_Godot/src/game/activity/role/player/state/PlayerRollState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/player/state/PlayerRollState.cs @@ -22,37 +22,59 @@ } _coroutineId = Master.StartCoroutine(RunRoll()); - Master.AnimatedSprite.Play(AnimatorNames.Roll); - //隐藏武器 - Master.BackMountPoint.Visible = false; - Master.MountPoint.Visible = false; + // //隐藏武器 + // Master.BackMountPoint.Visible = false; + // Master.MountPoint.Visible = false; //禁用伤害碰撞 Master.HurtCollision.Disabled = true; //翻滚移动方向 _moveDir = InputManager.MoveAxis; - Master.BasisVelocity = _moveDir * Master.RoleState.RollSpeed; + Master.BasisVelocity = _moveDir * Master.PlayerRoleState.RollSpeed; } public override void Exit(PlayerStateEnum next) { - //显示武器 - Master.BackMountPoint.Visible = true; - Master.MountPoint.Visible = true; + // //显示武器 + // Master.BackMountPoint.Visible = true; + // Master.MountPoint.Visible = true; //启用伤害碰撞 Master.HurtCollision.Disabled = false; + Master.BasisVelocity = Master.BasisVelocity.LimitLength(Master.RoleState.MoveSpeed); } public override void Process(float delta) { - Master.BasisVelocity = _moveDir * Master.RoleState.RollSpeed; + Master.BasisVelocity = _moveDir * Master.PlayerRoleState.RollSpeed; } //翻滚逻辑处理 private IEnumerator RunRoll() { - yield return Master.AnimatedSprite.ToSignal(Master.AnimatedSprite, AnimatedSprite2D.SignalName.AnimationFinished); + Master.AnimationPlayer.Play(AnimatorNames.Roll); + var time = 0f; + var time2 = 0f; + while (time < Master.PlayerRoleState.RollTime) + { + var delta = (float)Master.GetProcessDeltaTime(); + time += delta; + time2 += delta; + if (time2 >= 0.02f) + { + time2 %= 0.02f; + //拖尾效果 + var staticSprite = ObjectManager.GetPoolItemByClass(); + staticSprite.FromActivityObject(Master); + staticSprite.SetShowTimeout(0.2f); + staticSprite.ZIndex = 1; + var roomLayer = Master.World.GetRoomLayer(RoomLayerEnum.NormalLayer); + roomLayer.AddChild(staticSprite); + //roomLayer.MoveChild(staticSprite, Master.GetIndex()); + } + + yield return null; + } _coroutineId = -1; Master.OverRoll(); if (InputManager.MoveAxis != Vector2.Zero) //切换到移动状态 diff --git a/DungeonShooting_Godot/src/game/activity/shell/Shell.cs b/DungeonShooting_Godot/src/game/activity/shell/Shell.cs deleted file mode 100644 index 379448d..0000000 --- a/DungeonShooting_Godot/src/game/activity/shell/Shell.cs +++ /dev/null @@ -1,32 +0,0 @@ - -using Godot; - -/// -/// 弹壳类 -/// -[Tool] -public partial class Shell : ActivityObject -{ - public override void OnInit() - { - ShadowOffset = new Vector2(0, 1); - ThrowCollisionSize = new Vector2(5, 5); - } - - protected override void Process(float delta) - { - //落地静止后将弹壳变为静态贴图 - if (!IsThrowing && Altitude <= 0 && MoveController.IsMotionless()) - { - if (AffiliationArea != null) - { - Freeze(); - } - else - { - Debug.Log("弹壳投抛到画布外了, 强制消除..."); - Destroy(); - } - } - } -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/weapon/AiAttackEnum.cs b/DungeonShooting_Godot/src/game/activity/weapon/AiAttackEnum.cs new file mode 100644 index 0000000..9ee4dc5 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/weapon/AiAttackEnum.cs @@ -0,0 +1,43 @@ + +/// +/// 调用 Weapon.AiTriggerAttackState() 函数返回的结果 +/// +public enum AiAttackEnum +{ + /// + /// 未触发 AiTriggerAttackState() + /// + None, + /// + /// 触发切换武器 + /// + ExchangeWeapon, + /// + /// 没有弹药了 + /// + NoAmmo, + /// + /// 换弹中 + /// + Reloading, + /// + /// 触发换弹 + /// + TriggerReload, + /// + /// 没有武器 + /// + NoWeapon, + /// + /// 正在锁定目标中 + /// + LockingTime, + /// + /// 攻击间隙时间 + /// + AttackInterval, + /// + /// 成功触发攻击 + /// + Attack, +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs index 43295bc..62cb32e 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs @@ -6,7 +6,7 @@ /// /// 武器的基类 /// -public abstract partial class Weapon : ActivityObject, IPackageItem +public abstract partial class Weapon : ActivityObject, IPackageItem { /// /// 武器使用的属性数据, 该属性会根据是否是玩家使用武器, 如果是Ai使用武器, 则会返回 AiUseAttribute 的属性对象 @@ -32,7 +32,7 @@ /// public CampEnum TargetCamp { get; set; } - public AdvancedRole Master { get; set; } + public Role Master { get; set; } public int PackageIndex { get; set; } = -1; @@ -148,7 +148,7 @@ /// /// 上一次触发改武器开火的角色, 可能为 null /// - public AdvancedRole TriggerRole { get; private set; } + public Role TriggerRole { get; private set; } /// /// 上一次触发改武器开火的触发开火攻击的层级, 数据源自于: @@ -279,19 +279,19 @@ return attr; } - throw new Exception($"武器'{itemId}'没有在 Weapon 表中配置属性数据!"); + throw new Exception($"武器'{itemId}'没有在 WeaponBase 表中配置属性数据!"); } public override void OnInit() { - InitWeapon(GetWeaponAttribute(ItemConfig.Id).Clone()); + InitWeapon(GetWeaponAttribute(ActivityBase.Id).Clone()); AnimatedSprite.AnimationFinished += OnAnimationFinished; } /// /// 初始化武器属性 /// - public void InitWeapon(ExcelConfig.WeaponBase attribute) + private void InitWeapon(ExcelConfig.WeaponBase attribute) { _playerWeaponAttribute = attribute; _weaponAttribute = attribute; @@ -307,7 +307,7 @@ if (Attribute.AmmoCapacity > Attribute.MaxAmmoCapacity) { Attribute.AmmoCapacity = Attribute.MaxAmmoCapacity; - Debug.LogError("弹夹的容量不能超过弹药上限, 武器id: " + ItemConfig.Id); + Debug.LogError("弹夹的容量不能超过弹药上限, 武器id: " + ActivityBase.Id); } //弹药量 CurrAmmo = Attribute.AmmoCapacity; @@ -397,7 +397,7 @@ /// 当武器被拾起时调用 /// /// 拾起该武器的角色 - protected virtual void OnPickUp(AdvancedRole master) + protected virtual void OnPickUp(Role master) { } @@ -405,7 +405,7 @@ /// 当武器从武器背包中移除时调用 /// /// 移除该武器的角色 - protected virtual void OnRemove(AdvancedRole master) + protected virtual void OnRemove(Role master) { } @@ -604,7 +604,7 @@ //自动上膛 if (_beLoadedState == -1) { - BeLoadedHandler(); + BeLoaded(); } } } @@ -695,7 +695,7 @@ /// 扳机函数, 调用即视为按下扳机 /// /// 按下扳机的角色, 如果传 null, 则视为走火 - public void Trigger(AdvancedRole triggerRole) + public void Trigger(Role triggerRole) { //不能触发扳机 if (!NoMasterCanTrigger && Master == null) return; @@ -733,7 +733,7 @@ else if (_attackTimer <= 0) { //触发上膛操作 - BeLoadedHandler(); + BeLoaded(); } } } @@ -894,7 +894,7 @@ } /// - /// 获取攻击冷却计时时间, 等于 0 表示冷却完成 + /// 获取攻击冷却计时时间, 小于等于 0 表示冷却完成 /// public float GetAttackTimer() { @@ -910,6 +910,14 @@ } /// + /// 是否可以按下扳机并发射了 + /// + public bool TriggerIsReady() + { + return GetBeLoadedStateState() >= 2 && !IsAttackIntervalTime(); + } + + /// /// 获取上膛状态,-1: 等待执行自动上膛 , 0: 未上膛, 1: 上膛中, 2: 已经完成上膛 /// public sbyte GetBeLoadedStateState() @@ -1032,7 +1040,7 @@ var bulletCount = Utils.Random.RandomConfigRange(Attribute.FireBulletCountRange); if (Master != null) { - bulletCount = Master.RoleState.CalcBulletCount(this, bulletCount); + bulletCount = Master.RoleState.CalcBulletCount(bulletCount); fireRotation += Master.MountPoint.RealRotation; } else @@ -1097,7 +1105,7 @@ /// /// 根据触扳机的角色对象判断该角色使用的武器数据 /// - public ExcelConfig.WeaponBase GetUseAttribute(AdvancedRole triggerRole) + public ExcelConfig.WeaponBase GetUseAttribute(Role triggerRole) { if (triggerRole == null || !triggerRole.IsAi) { @@ -1117,7 +1125,7 @@ { return (uint)TriggerRoleAttackLayer; } - return Master != null ? Master.AttackLayer : AdvancedRole.DefaultAttackLayer; + return Master != null ? Master.AttackLayer : Role.DefaultAttackLayer; } /// @@ -1209,7 +1217,7 @@ /// public void Reload() { - if (CurrAmmo < Attribute.AmmoCapacity && ResidueAmmo > 0 && !Reloading && _beLoadedState != 1) + if (!Reloading && CurrAmmo < Attribute.AmmoCapacity && ResidueAmmo > 0 && _beLoadedState != 1) { Reloading = true; _playReloadFinishSoundFlag = false; @@ -1263,6 +1271,59 @@ _reloadTimer = 0; _reloadUseTime = 0; } + + /// + /// 触发上膛 + /// + public void BeLoaded() + { + if (_beLoadedState > 0) + { + return; + } + //上膛抛弹 + if (!Attribute.ReloadThrowShell && !Attribute.ContinuousShoot && Attribute.BeLoadedTime > 0) + { + ThrowShellHandler(0.6f); + } + + //开始上膛 + OnBeginBeLoaded(); + + //上膛时间为0, 直接结束上膛 + if (Attribute.BeLoadedTime <= 0) + { + //直接上膛完成 + _beLoadedState = 2; + OnBeLoadedFinish(); + return; + } + + //上膛中 + _beLoadedState = 1; + _beLoadedStateTimer = Attribute.BeLoadedTime; + + //播放上膛动画 + if (IsAutoPlaySpriteFrames) + { + if (Attribute.BeLoadedSoundDelayTime <= 0) + { + PlaySpriteAnimation(AnimatorNames.BeLoaded); + PlayAnimationPlayer(AnimatorNames.BeLoaded); + } + else + { + this.CallDelay(Attribute.BeLoadedSoundDelayTime, () => + { + PlaySpriteAnimation(AnimatorNames.BeLoaded); + PlayAnimationPlayer(AnimatorNames.BeLoaded); + }); + } + } + + //播放上膛音效 + PlayBeLoadedSound(); + } //播放换弹开始音效 private void PlayBeginReloadSound() @@ -1338,7 +1399,7 @@ if (_attackTimer <= 0) { //执行自动上膛 - BeLoadedHandler(); + BeLoaded(); } else if (CurrAmmo > 0) { @@ -1413,53 +1474,6 @@ OnAloneReloadStateFinish(); } - //上膛处理 - private void BeLoadedHandler() - { - //上膛抛弹 - if (!Attribute.ReloadThrowShell && !Attribute.ContinuousShoot && Attribute.BeLoadedTime > 0) - { - ThrowShellHandler(0.6f); - } - - //开始上膛 - OnBeginBeLoaded(); - - //上膛时间为0, 直接结束上膛 - if (Attribute.BeLoadedTime <= 0) - { - //直接上膛完成 - _beLoadedState = 2; - OnBeLoadedFinish(); - return; - } - - //上膛中 - _beLoadedState = 1; - _beLoadedStateTimer = Attribute.BeLoadedTime; - - //播放上膛动画 - if (IsAutoPlaySpriteFrames) - { - if (Attribute.BeLoadedSoundDelayTime <= 0) - { - PlaySpriteAnimation(AnimatorNames.BeLoaded); - PlayAnimationPlayer(AnimatorNames.BeLoaded); - } - else - { - this.CallDelay(Attribute.BeLoadedSoundDelayTime, () => - { - PlaySpriteAnimation(AnimatorNames.BeLoaded); - PlayAnimationPlayer(AnimatorNames.BeLoaded); - }); - } - } - - //播放上膛音效 - PlayBeLoadedSound(); - } - //抛弹逻辑 private void ThrowShellHandler(float speedScale) { @@ -1473,13 +1487,13 @@ this.CallDelay(Attribute.ThrowShellDelayTime, () => { _reloadShellFlag = true; - ThrowShell(Attribute.Shell, speedScale); + FireManager.ThrowShell(this, Attribute.Shell, speedScale); }); } else if (Attribute.ThrowShellDelayTime == 0) { _reloadShellFlag = true; - ThrowShell(Attribute.Shell, speedScale); + FireManager.ThrowShell(this, Attribute.Shell, speedScale); } } @@ -1490,8 +1504,8 @@ var finalScatteringRange = Attribute.FinalScatteringRange; if (Master != null) { - startScatteringRange = Master.RoleState.CalcStartScattering(this, startScatteringRange); - finalScatteringRange = Master.RoleState.CalcFinalScattering(this, finalScatteringRange); + startScatteringRange = Master.RoleState.CalcStartScattering(startScatteringRange); + finalScatteringRange = Master.RoleState.CalcFinalScattering(finalScatteringRange); } if (startScatteringRange <= finalScatteringRange) { @@ -1512,8 +1526,8 @@ var finalScatteringRange = Attribute.FinalScatteringRange; if (Master != null) { - startScatteringRange = Master.RoleState.CalcStartScattering(this, startScatteringRange); - finalScatteringRange = Master.RoleState.CalcFinalScattering(this, finalScatteringRange); + startScatteringRange = Master.RoleState.CalcStartScattering(startScatteringRange); + finalScatteringRange = Master.RoleState.CalcFinalScattering(finalScatteringRange); } if (startScatteringRange <= finalScatteringRange) { @@ -1606,13 +1620,13 @@ { var result = new CheckInteractiveResult(this); - if (master is AdvancedRole roleMaster) //碰到角色 + if (master is Role roleMaster) //碰到角色 { if (Master == null) { var masterWeapon = roleMaster.WeaponPack.ActiveItem; //查找是否有同类型武器 - var index = roleMaster.WeaponPack.FindIndex(ItemConfig.Id); + var index = roleMaster.WeaponPack.FindIndex(ActivityBase.Id); if (index != -1) //如果有这个武器 { if (CurrAmmo + ResidueAmmo != 0) //子弹不为空 @@ -1652,11 +1666,11 @@ public override void Interactive(ActivityObject master) { - if (master is AdvancedRole roleMaster) //与role互动 + if (master is Role roleMaster) //与role互动 { var holster = roleMaster.WeaponPack; //查找是否有同类型武器 - var index = holster.FindIndex(ItemConfig.Id); + var index = holster.FindIndex(ActivityBase.Id); if (index != -1) //如果有这个武器 { if (CurrAmmo + ResidueAmmo == 0) //没有子弹了 @@ -1727,7 +1741,7 @@ /// 触发扔掉武器时抛出的效果, 并不会管武器是否在武器背包中 /// /// 触发扔掉该武器的的角色 - public void ThrowWeapon(AdvancedRole master) + public void ThrowWeapon(Role master) { ThrowWeapon(master, master.GlobalPosition); } @@ -1737,7 +1751,7 @@ /// /// 触发扔掉该武器的的角色 /// 投抛起始位置 - public void ThrowWeapon(AdvancedRole master, Vector2 startPosition) + public void ThrowWeapon(Role master, Vector2 startPosition) { //阴影偏移 ShadowOffset = new Vector2(0, 2); @@ -1904,185 +1918,99 @@ //-------------------------------- Ai相关 ----------------------------- /// - /// Ai 调用, 刷新 Ai 攻击状态并返回, 并不会调用相应的函数 - /// - public AiAttackState AiRefreshAttackState() - { - AiAttackState flag; - if (IsTotalAmmoEmpty()) //当前武器弹药打空 - { - //切换到有子弹的武器 - var index = Master.WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty()); - if (index != -1) - { - flag = AiAttackState.ExchangeWeapon; - } - else //所有子弹打光 - { - flag = AiAttackState.NoAmmo; - } - } - else if (Reloading) //换弹中 - { - flag = AiAttackState.TriggerReload; - } - else if (IsAmmoEmpty()) //弹夹已经打空 - { - flag = AiAttackState.Reloading; - } - else if (_beLoadedState == 0 || _beLoadedState == -1) //需要上膛 - { - flag = AiAttackState.AttackInterval; - } - else if (_beLoadedState == 1) //上膛中 - { - flag = AiAttackState.AttackInterval; - } - else if (_continuousCount >= 1) //连发中 - { - flag = AiAttackState.Attack; - } - else if (IsAttackIntervalTime()) //开火间隙 - { - flag = AiAttackState.AttackInterval; - } - else - { - var enemy = (AdvancedEnemy)Master; - if (enemy.GetLockTime() >= Attribute.AiAttackAttr.LockingTime) //正常射击 - { - if (GetDelayedAttackTime() > 0) - { - flag = AiAttackState.Attack; - } - else - { - if (Attribute.ContinuousShoot) //连发 - { - flag = AiAttackState.Attack; - } - else //单发 - { - flag = AiAttackState.Attack; - } - } - } - else //锁定时间没到 - { - flag = AiAttackState.LockingTime; - } - } - - return flag; - } - - /// /// Ai调用, 触发扣动扳机, 并返回攻击状态 /// - public AiAttackState AiTriggerAttackState() + public AiAttackEnum AiTriggerAttackState() { - AiAttackState flag; + AiAttackEnum flag; if (IsTotalAmmoEmpty()) //当前武器弹药打空 { //切换到有子弹的武器 var index = Master.WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty()); if (index != -1) { - flag = AiAttackState.ExchangeWeapon; + flag = AiAttackEnum.ExchangeWeapon; Master.WeaponPack.ExchangeByIndex(index); } else //所有子弹打光 { - flag = AiAttackState.NoAmmo; + flag = AiAttackEnum.NoAmmo; } } else if (Reloading) //换弹中 { - flag = AiAttackState.TriggerReload; + flag = AiAttackEnum.TriggerReload; } else if (IsAmmoEmpty()) //弹夹已经打空 { - flag = AiAttackState.Reloading; + flag = AiAttackEnum.Reloading; Reload(); } else if (_beLoadedState == 0 || _beLoadedState == -1) //需要上膛 { - flag = AiAttackState.AttackInterval; + flag = AiAttackEnum.AttackInterval; if (_attackTimer <= 0) { - Master.Attack(); + BeLoaded(); } } else if (_beLoadedState == 1) //上膛中 { - flag = AiAttackState.AttackInterval; + flag = AiAttackEnum.AttackInterval; } else if (_continuousCount >= 1) //连发中 { - flag = AiAttackState.Attack; + flag = AiAttackEnum.Attack; } else if (IsAttackIntervalTime()) //开火间隙 { - flag = AiAttackState.AttackInterval; + flag = AiAttackEnum.AttackInterval; } else { - var enemy = (AdvancedEnemy)Master; - if (enemy.GetLockTime() >= Attribute.AiAttackAttr.LockingTime) //正常射击 + var enemy = (Enemy)Master; + if (enemy.LockTargetTime >= Attribute.AiAttackAttr.LockingTime) //正常射击 { if (GetDelayedAttackTime() > 0) { - flag = AiAttackState.Attack; + flag = AiAttackEnum.Attack; enemy.Attack(); if (_attackFlag) { - enemy.SetLockTargetTime(0); + enemy.LockingTime = 0; } } else { if (Attribute.ContinuousShoot) //连发 { - flag = AiAttackState.Attack; + flag = AiAttackEnum.Attack; enemy.Attack(); if (_attackFlag) { - enemy.SetLockTargetTime(0); + enemy.LockingTime = 0; } } else //单发 { - flag = AiAttackState.Attack; + flag = AiAttackEnum.Attack; enemy.Attack(); if (_attackFlag) { - enemy.SetLockTargetTime(0); + enemy.LockingTime = 0; } } } } else //锁定时间没到 { - flag = AiAttackState.LockingTime; + flag = AiAttackEnum.LockingTime; } } return flag; } - /// - /// 获取Ai锁定目标的剩余时间 - /// - public float GetAiLockRemainderTime() - { - if (Master is AdvancedEnemy enemy) - { - return Attribute.AiAttackAttr.LockingTime - enemy.GetLockTime(); - } - - return 0; - } - // /// // /// 获取 Ai 对于该武器的评分, 评分越高, 代表 Ai 会越优先选择该武器, 如果为 -1, 则表示 Ai 不会使用该武器 // /// diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon_Bullet.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon_Bullet.cs deleted file mode 100644 index 2370533..0000000 --- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon_Bullet.cs +++ /dev/null @@ -1,145 +0,0 @@ - -using System; -using Config; -using Godot; - -public partial class Weapon -{ - //-------------------------------- 子弹相关 ----------------------------- - - /// - /// 投抛弹壳的默认实现方式, shellId为弹壳id - /// - protected ActivityObject ThrowShell(ExcelConfig.ActivityBase shell, float speedScale = 1) - { - var startPos = ShellPoint.GlobalPosition; - float startHeight; - if (Master != null) - { - var shellPosition = (Master != null ? Master.MountPoint.Position : Position) + ShellPoint.Position; - startHeight = -shellPosition.Y; - startPos.Y += startHeight; - } - else - { - startHeight = Altitude; - } - - var direction = GlobalRotationDegrees + Utils.Random.RandomRangeInt(-30, 30) + 180; - var verticalSpeed = Utils.Random.RandomRangeInt((int)(60 * speedScale), (int)(120 * speedScale)); - var velocity = new Vector2(Utils.Random.RandomRangeInt((int)(20 * speedScale), (int)(60 * speedScale)), 0).Rotated(direction * Mathf.Pi / 180); - var rotate = Utils.Random.RandomRangeInt((int)(-720 * speedScale), (int)(720 * speedScale)); - var shellInstance = Create(shell); - shellInstance.Rotation = (Master != null ? Master.MountPoint.RealRotation : Rotation); - shellInstance.Throw(startPos, startHeight, verticalSpeed, velocity, rotate); - shellInstance.InheritVelocity(Master != null ? Master : this); - if (Master == null) - { - AffiliationArea.InsertItem(shellInstance); - } - else - { - Master.AffiliationArea.InsertItem(shellInstance); - } - - return shellInstance; - } - - /// - /// 发射子弹 - /// - protected IBullet ShootBullet(float fireRotation, ExcelConfig.BulletBase bullet) - { - if (bullet.Type == 1) //实体子弹 - { - return ShootSolidBullet(fireRotation, bullet); - } - else if (bullet.Type == 2) //激光子弹 - { - return ShootLaser(fireRotation, bullet); - } - - return null; - } - - /// - /// 发射子弹的默认实现方式 - /// - private Bullet ShootSolidBullet(float fireRotation, ExcelConfig.BulletBase bullet) - { - var data = new BulletData() - { - Weapon = this, - BulletBase = bullet, - TriggerRole = TriggerRole, - Harm = Utils.Random.RandomConfigRange(bullet.HarmRange), - Repel = Utils.Random.RandomConfigRange(bullet.RepelRange), - MaxDistance = Utils.Random.RandomConfigRange(bullet.DistanceRange), - FlySpeed = Utils.Random.RandomConfigRange(bullet.SpeedRange), - VerticalSpeed = Utils.Random.RandomConfigRange(bullet.VerticalSpeed), - BounceCount = Utils.Random.RandomConfigRange(bullet.BounceCount), - Penetration = Utils.Random.RandomConfigRange(bullet.Penetration), - Position = FirePoint.GlobalPosition, - }; - - var deviationAngle = Utils.Random.RandomConfigRange(bullet.DeviationAngleRange); - if (TriggerRole != null) - { - var roleState = TriggerRole.RoleState; - data.Harm = roleState.CalcDamage(data.Harm); - data.Repel = roleState.CalcBulletRepel(this, data.Repel); - data.FlySpeed = roleState.CalcBulletSpeed(this, data.FlySpeed); - data.MaxDistance = roleState.CalcBulletDistance(this, data.MaxDistance); - data.BounceCount = roleState.CalcBulletBounceCount(this, data.BounceCount); - data.Penetration = roleState.CalcBulletPenetration(this, data.Penetration); - deviationAngle = roleState.CalcBulletDeviationAngle(this, deviationAngle); - - if (TriggerRole.IsAi) //只有玩家使用该武器才能获得正常速度的子弹 - { - data.FlySpeed *= AiUseAttribute.AiAttackAttr.BulletSpeedScale; - } - } - - data.Rotation = fireRotation + Mathf.DegToRad(deviationAngle); - //创建子弹 - var bulletInstance = ObjectManager.GetBullet(bullet.Prefab); - bulletInstance.InitData(data, GetAttackLayer()); - return bulletInstance; - } - - /// - /// 发射射线的默认实现方式 - /// - private Laser ShootLaser(float fireRotation, ExcelConfig.BulletBase bullet) - { - var data = new BulletData() - { - Weapon = this, - BulletBase = bullet, - TriggerRole = TriggerRole, - Harm = Utils.Random.RandomConfigRange(bullet.HarmRange), - Repel = Utils.Random.RandomConfigRange(bullet.RepelRange), - MaxDistance = Utils.Random.RandomConfigRange(bullet.DistanceRange), - BounceCount = Utils.Random.RandomConfigRange(bullet.BounceCount), - LifeTime = Utils.Random.RandomConfigRange(bullet.LifeTimeRange), - Position = FirePoint.GlobalPosition, - }; - - var deviationAngle = Utils.Random.RandomConfigRange(bullet.DeviationAngleRange); - if (TriggerRole != null) - { - var roleState = TriggerRole.RoleState; - data.Harm = roleState.CalcDamage(data.Harm); - data.Repel = roleState.CalcBulletRepel(this, data.Repel); - data.BounceCount = roleState.CalcBulletBounceCount(this, data.BounceCount); - deviationAngle = roleState.CalcBulletDeviationAngle(this, deviationAngle); - } - - data.Rotation = fireRotation + Mathf.DegToRad(deviationAngle); - //创建激光 - var laser = ObjectManager.GetLaser(bullet.Prefab); - laser.AddToActivityRoot(RoomLayerEnum.YSortLayer); - laser.InitData(data, GetAttackLayer(), 3); - return laser; - } -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs b/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs index 76ed43c..a5fb906 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs @@ -30,7 +30,7 @@ protected override void OnShoot(float fireRotation) { - ShootBullet(fireRotation, Attribute.Bullet); + FireManager.ShootBullet(this, fireRotation, Attribute.Bullet); } // //测试用, 敌人被消灭时触发手上武器开火 diff --git a/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs b/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs index 1df0f76..b465060 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/knife/Knife.cs @@ -127,7 +127,7 @@ var activityObject = body.AsActivityObject(); if (activityObject != null) { - if (activityObject is AdvancedRole role) //碰到角色 + if (activityObject is Role role) //碰到角色 { var damage = Utils.Random.RandomConfigRange(Attribute.Bullet.HarmRange); //计算子弹造成的伤害 @@ -141,7 +141,7 @@ //计算击退 if (TriggerRole != null) { - repel = TriggerRole.RoleState.CalcBulletRepel(this, repel); + repel = TriggerRole.RoleState.CalcBulletRepel(repel); } if (repel != 0) { @@ -155,11 +155,11 @@ position = role.GlobalPosition - GlobalPosition; } var v2 = position.Normalized() * repel; - role.MoveController.AddForce(v2); + role.AddRepelForce(v2); } //造成伤害 - role.CallDeferred(nameof(AdvancedRole.Hurt), damage, (role.GetCenterPosition() - GlobalPosition).Angle()); + role.CallDeferred(nameof(Role.Hurt), TriggerRole, damage, (role.GetCenterPosition() - GlobalPosition).Angle()); } else if (activityObject is Bullet bullet) //攻击子弹 { diff --git a/DungeonShooting_Godot/src/game/camera/GameCamera.cs b/DungeonShooting_Godot/src/game/camera/GameCamera.cs index 74a355b..b35d63a 100644 --- a/DungeonShooting_Godot/src/game/camera/GameCamera.cs +++ b/DungeonShooting_Godot/src/game/camera/GameCamera.cs @@ -20,7 +20,7 @@ DataDelta = dataDelta; } } - + /// /// 当前场景的相机对象 /// @@ -34,9 +34,8 @@ /// /// 恢复系数 /// - [Export] - public float RecoveryCoefficient = 25f; - + [Export] public float RecoveryCoefficient = 25f; + /// /// 抖动开关 /// @@ -46,14 +45,17 @@ /// 镜头跟随鼠标进度 (0 - 1) /// public float FollowsMouseAmount = 0.15f; - + /// /// 相机跟随目标 /// - private AdvancedRole _followTarget; - - // 3.5 - //public Vector2 SubPixelPosition { get; private set; } + private Role _followTarget; + + /// + /// SubViewportContainer 中的像素偏移, 因为游戏开启了完美像素, SubViewport 节点下的相机运动会造成非常大的抖动, + /// 为了解决这个问题, 在 SubViewport 父节点中对 SubViewport 进行整体偏移, 以抵消相机造成的巨大抖动 + /// + public Vector2 PixelOffset { get; private set; } private long _index = 0; @@ -64,6 +66,8 @@ private Vector2 _camPos; private Vector2 _shakeOffset = Vector2.Zero; + + public ShaderMaterial _offsetShader; public GameCamera() { @@ -72,6 +76,7 @@ public override void _Ready() { + _offsetShader = (ShaderMaterial)GameApplication.Instance.SubViewportContainer.Material; _camPos = GlobalPosition; } @@ -81,36 +86,28 @@ var newDelta = (float)delta; _Shake(newDelta); - // 3.5 写法 - // var player = GameApplication.Instance.RoomManager.Player; - // var viewportContainer = GameApplication.Instance.SubViewportContainer; - // var camPos = player.GlobalPosition; - // _camPos = _camPos.Lerp(camPos, Mathf.Min(6 * newDelta, 1)) + _shakeOffset; - // SubPixelPosition = _camPos.Round() - _camPos; - // (viewportContainer.Material as ShaderMaterial)?.SetShaderParameter("offset", SubPixelPosition); - // GlobalPosition = _camPos.Round(); - - var world = GameApplication.Instance.World; if (world != null && !world.Pause && _followTarget != null) { var mousePosition = InputManager.CursorPosition; var targetPosition = _followTarget.GlobalPosition; - //if (targetPosition.DistanceSquaredTo(mousePosition) >= 39999.992F) // >= (60 / 0.3f) * (60 / 0.3f) if (targetPosition.DistanceSquaredTo(mousePosition) >= (60 / FollowsMouseAmount) * (60 / FollowsMouseAmount)) { _camPos = targetPosition.MoveToward(mousePosition, 60); } else { - //targetPos = targetPosition.Lerp(mousePosition, 0.3f); //这里的0.3就是上面的 (60 / 0.3f) * (60 / 0.3f) 中的 0.3 _camPos = targetPosition.Lerp(mousePosition, FollowsMouseAmount); } - //_camPos = _camPos.Lerp(targetPos, 20 * newDelta); - GlobalPosition = _camPos.Round(); + var cameraPosition = _camPos; + var roundPos = cameraPosition.Round(); + PixelOffset = roundPos - cameraPosition; + _offsetShader.SetShaderParameter("offset", PixelOffset); + GlobalPosition = roundPos; + Offset = _shakeOffset.Round(); - + //调用相机更新事件 if (OnPositionUpdateEvent != null) { @@ -122,7 +119,7 @@ /// /// 设置相机跟随目标 /// - public void SetFollowTarget(AdvancedRole target) + public void SetFollowTarget(Role target) { _followTarget = target; if (target != null) @@ -135,7 +132,7 @@ /// /// 获取相机跟随目标 /// - public AdvancedRole GetFollowTarget() + public Role GetFollowTarget() { return _followTarget; } @@ -200,9 +197,10 @@ { var distance = _CalculateDistanceSquared(delta); distance = new Vector2(Mathf.Sqrt(distance.X), Mathf.Sqrt(distance.Y)); + var offset = Offset; _shakeOffset += _processDirection + new Vector2( - (float)GD.RandRange(-distance.X, distance.X) - Offset.X, - (float)GD.RandRange(-distance.Y, distance.Y) - Offset.Y + (float)GD.RandRange(-distance.X, distance.X) - offset.X, + (float)GD.RandRange(-distance.Y, distance.Y) - offset.Y ); _processDistanceSquared = Vector2.Zero; _processDirection = _processDirection.Lerp(Vector2.Zero, RecoveryCoefficient * delta); diff --git a/DungeonShooting_Godot/src/game/data/BulletData.cs b/DungeonShooting_Godot/src/game/data/BulletData.cs index 34547ad..a53fc26 100644 --- a/DungeonShooting_Godot/src/game/data/BulletData.cs +++ b/DungeonShooting_Godot/src/game/data/BulletData.cs @@ -5,10 +5,10 @@ /// /// 子弹数据 /// -public class BulletData +public class BulletData : IClone { /// - /// 发射该子弹的武器 + /// 发射该子弹的武器, 可能为null /// public Weapon Weapon; @@ -18,9 +18,9 @@ public ExcelConfig.BulletBase BulletBase; /// - /// 发射该子弹的角色 + /// 发射该子弹的角色, 可能为null /// - public AdvancedRole TriggerRole; + public Role TriggerRole; /// /// 造成的伤害 @@ -43,6 +43,11 @@ public float FlySpeed; /// + /// 初始离地高度 + /// + public float Altitude; + + /// /// 纵轴速度 /// public float VerticalSpeed; @@ -71,4 +76,25 @@ /// 旋转角度 /// public float Rotation; + + public BulletData Clone() + { + return new BulletData + { + Weapon = Weapon, + BulletBase = BulletBase, + TriggerRole = TriggerRole, + Harm = Harm, + Repel = Repel, + MaxDistance = MaxDistance, + FlySpeed = FlySpeed, + Altitude = Altitude, + VerticalSpeed = VerticalSpeed, + BounceCount = BounceCount, + Penetration = Penetration, + LifeTime = LifeTime, + Position = Position, + Rotation = Rotation + }; + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/effects/AutoDestroyParticles.cs b/DungeonShooting_Godot/src/game/effects/AutoDestroyParticles.cs index 05ed68f..c05b1c4 100644 --- a/DungeonShooting_Godot/src/game/effects/AutoDestroyParticles.cs +++ b/DungeonShooting_Godot/src/game/effects/AutoDestroyParticles.cs @@ -11,7 +11,7 @@ /// 延时销毁时间 /// [Export] - public float DelayTime { get; set; } = 1f; + public float DelayTime { get; set; } = 2f; /// /// 子节点包含的例子特效, 在创建完成后自动播放 @@ -29,11 +29,13 @@ public virtual void PlayEffect() { Emitting = true; + Restart(); if (Particles2D != null) { foreach (var gpuParticles2D in Particles2D) { gpuParticles2D.Emitting = true; + Restart(); } } _timer = 0; diff --git a/DungeonShooting_Godot/src/game/effects/AutoDestroySprite.cs b/DungeonShooting_Godot/src/game/effects/AutoDestroySprite.cs index ad8d15d..7dd66e6 100644 --- a/DungeonShooting_Godot/src/game/effects/AutoDestroySprite.cs +++ b/DungeonShooting_Godot/src/game/effects/AutoDestroySprite.cs @@ -16,7 +16,7 @@ /// 延时销毁时间 /// [Export] - public float DelayTime { get; set; } = 1f; + public float DelayTime { get; set; } = 2f; /// /// 子节点包含的例子特效, 在创建完成后自动播放 diff --git a/DungeonShooting_Godot/src/game/effects/SmearingSprite.cs b/DungeonShooting_Godot/src/game/effects/SmearingSprite.cs new file mode 100644 index 0000000..1e2fa24 --- /dev/null +++ b/DungeonShooting_Godot/src/game/effects/SmearingSprite.cs @@ -0,0 +1,70 @@ + +using Godot; + +/// +/// 拖影精灵 +/// +public partial class SmearingSprite : Sprite2D, IPoolItem +{ + public bool IsRecycled { get; set; } + public string Logotype { get; set; } + public bool IsDestroyed { get; set; } + + private double _timeOut = -1; + private double _totalTime = 0; + + /// + /// 从 ActivityObject 的 AnimatedSprite 中复制动画帧 + /// + public void FromActivityObject(ActivityObject activityObject) + { + var currentTexture = activityObject.GetCurrentTexture(); + Texture = currentTexture; + Offset = activityObject.AnimatedSprite.Offset; + GlobalPosition = activityObject.AnimatedSprite.GlobalPosition; + GlobalScale = activityObject.AnimatedSprite.GlobalScale; + GlobalRotation = activityObject.AnimatedSprite.GlobalRotation; + } + + /// + /// 设置显示的时间, 过期会自动回收 + /// + public void SetShowTimeout(float time) + { + _totalTime = time; + _timeOut = time; + } + + public override void _Process(double delta) + { + if (_timeOut > 0) + { + _timeOut -= delta; + Modulate = new Color(1, 1, 1, (float)(_timeOut / _totalTime)); + if (_timeOut <= 0) + { + ObjectPool.Reclaim(this); + } + } + } + + public void Destroy() + { + if (IsDestroyed) + { + return; + } + + IsDestroyed = true; + QueueFree(); + } + public void OnReclaim() + { + GetParent().RemoveChild(this); + } + + public void OnLeavePool() + { + Modulate = Colors.White; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/effects/enemy/EnemyDead0001.cs b/DungeonShooting_Godot/src/game/effects/enemy/EnemyDead0001.cs new file mode 100644 index 0000000..d600a25 --- /dev/null +++ b/DungeonShooting_Godot/src/game/effects/enemy/EnemyDead0001.cs @@ -0,0 +1,48 @@ + +using System.Collections; +using Godot; + +/// +/// 敌人死亡碎片 +/// +[Tool] +public partial class EnemyDead0001 : ActivityObject +{ + + private GpuParticles2D _gpuParticles2D; + private bool _playOver = false; + + public override void OnInit() + { + var frameCount = AnimatedSprite.SpriteFrames.GetFrameCount(AnimatorNames.Default); + AnimatedSprite.Frame = Utils.Random.RandomRangeInt(0, frameCount - 1); + + Throw( + Utils.Random.RandomRangeInt(0, 16), + Utils.Random.RandomRangeInt(10, 60), + new Vector2(Utils.Random.RandomRangeInt(-25, 25), Utils.Random.RandomRangeInt(-25, 25)), + Utils.Random.RandomRangeInt(-360, 360) + ); + + StartCoroutine(EmitParticles()); + } + + protected override void Process(float delta) + { + if (_playOver && !IsThrowing && Altitude <= 0 && MoveController.IsMotionless()) + { + MoveController.SetAllVelocity(Vector2.Zero); + Freeze(); + } + } + + public IEnumerator EmitParticles() + { + var gpuParticles2D = GetNode("GPUParticles2D"); + gpuParticles2D.Emitting = true; + yield return new WaitForSeconds(Utils.Random.RandomRangeFloat(1f, 2.5f)); + gpuParticles2D.Emitting = false; + yield return new WaitForSeconds(1); + _playOver = true; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/effects/enemy/EnemyDebris.cs b/DungeonShooting_Godot/src/game/effects/enemy/EnemyDebris.cs deleted file mode 100644 index d96d1c2..0000000 --- a/DungeonShooting_Godot/src/game/effects/enemy/EnemyDebris.cs +++ /dev/null @@ -1,48 +0,0 @@ - -using System.Collections; -using Godot; - -/// -/// 敌人死亡碎片 -/// -[Tool] -public partial class EnemyDebris : ActivityObject -{ - - private GpuParticles2D _gpuParticles2D; - private bool _playOver = false; - - public override void OnInit() - { - var frameCount = AnimatedSprite.SpriteFrames.GetFrameCount(AnimatorNames.Default); - AnimatedSprite.Frame = Utils.Random.RandomRangeInt(0, frameCount - 1); - - Throw( - Utils.Random.RandomRangeInt(0, 16), - Utils.Random.RandomRangeInt(10, 60), - new Vector2(Utils.Random.RandomRangeInt(-25, 25), Utils.Random.RandomRangeInt(-25, 25)), - Utils.Random.RandomRangeInt(-360, 360) - ); - - StartCoroutine(EmitParticles()); - } - - protected override void Process(float delta) - { - if (_playOver && !IsThrowing && Altitude <= 0 && MoveController.IsMotionless()) - { - MoveController.SetAllVelocity(Vector2.Zero); - Freeze(); - } - } - - public IEnumerator EmitParticles() - { - var gpuParticles2D = GetNode("GPUParticles2D"); - gpuParticles2D.Emitting = true; - yield return new WaitForSeconds(Utils.Random.RandomRangeFloat(1f, 2.5f)); - gpuParticles2D.Emitting = false; - yield return new WaitForSeconds(1); - _playOver = true; - } -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/manager/FireManager.cs b/DungeonShooting_Godot/src/game/manager/FireManager.cs new file mode 100644 index 0000000..1a77262 --- /dev/null +++ b/DungeonShooting_Godot/src/game/manager/FireManager.cs @@ -0,0 +1,292 @@ + +using Config; +using Godot; + +public static class FireManager +{ + + /// + /// 投抛弹壳的默认实现方式, shellId为弹壳id + /// + public static ActivityObject ThrowShell(Weapon weapon, ExcelConfig.ActivityBase shell, float speedScale = 1) + { + var startPos = weapon.ShellPoint.GlobalPosition; + float startHeight; + var master = weapon.Master; + if (master != null) + { + var shellPosition = master.MountPoint.Position + weapon.ShellPoint.Position; + startHeight = -shellPosition.Y; + startPos.Y += startHeight; + } + else + { + startHeight = weapon.Altitude; + } + + var direction = weapon.GlobalRotationDegrees + Utils.Random.RandomRangeInt(-30, 30) + 180; + var verticalSpeed = Utils.Random.RandomRangeInt((int)(60 * speedScale), (int)(120 * speedScale)); + var velocity = new Vector2(Utils.Random.RandomRangeInt((int)(20 * speedScale), (int)(60 * speedScale)), 0).Rotated(direction * Mathf.Pi / 180); + var rotate = Utils.Random.RandomRangeInt((int)(-720 * speedScale), (int)(720 * speedScale)); + var shellInstance = ActivityObject.Create(shell); + shellInstance.Rotation = (master != null ? master.MountPoint.RealRotation : weapon.Rotation); + shellInstance.Throw(startPos, startHeight, verticalSpeed, velocity, rotate); + shellInstance.InheritVelocity(master != null ? master : weapon); + if (master == null) + { + weapon.AffiliationArea.InsertItem(shellInstance); + } + else + { + master.AffiliationArea.InsertItem(shellInstance); + } + + return shellInstance; + } + + /// + /// 根据武器创建 BulletData + /// + public static BulletData GetBulletData(Weapon weapon, float fireRotation, ExcelConfig.BulletBase bullet) + { + if (bullet.Type == 1) //实体子弹 + { + return CreateSolidBulletData(weapon, fireRotation, bullet); + } + else if (bullet.Type == 2) //激光子弹 + { + return CreateLaserData(weapon, fireRotation, bullet); + } + else + { + Debug.LogError("暂未支持的子弹类型: " + bullet.Type); + } + + return null; + } + + /// + /// 根据角色创建 BulletData + /// + public static BulletData GetBulletData(Role trigger, float fireRotation, ExcelConfig.BulletBase bullet) + { + if (bullet.Type == 1) //实体子弹 + { + return CreateSolidBulletData(trigger, fireRotation, bullet); + } + + return null; + } + + public static void SetParabolaTarget(BulletData bulletData, Vector2 targetPosition) + { + var distance = bulletData.Position.DistanceTo(targetPosition); + var height = bulletData.Altitude; + var time = distance / bulletData.FlySpeed; + bulletData.VerticalSpeed = -(height - 0.5f * GameConfig.G * time * time) / time; + bulletData.Rotation = bulletData.Position.AngleToPoint(targetPosition); + } + + /// + /// 通过武器发射子弹 + /// + public static IBullet ShootBullet(Weapon weapon, float fireRotation, ExcelConfig.BulletBase bullet) + { + if (bullet.Type == 1) //实体子弹 + { + return ShootSolidBullet(CreateSolidBulletData(weapon, fireRotation, bullet), weapon.GetAttackLayer()); + } + else if (bullet.Type == 2) //激光子弹 + { + return ShootLaser(CreateLaserData(weapon, fireRotation, bullet), weapon.GetAttackLayer()); + } + else + { + Debug.LogError("暂未支持的子弹类型: " + bullet.Type); + } + + return null; + } + + /// + /// 通 Role 对象直接发射子弹 + /// + public static IBullet ShootBullet(Role trigger, float fireRotation, ExcelConfig.BulletBase bullet) + { + if (bullet.Type == 1) //实体子弹 + { + return ShootSolidBullet(CreateSolidBulletData(trigger, fireRotation, bullet), trigger.AttackLayer); + } + + return null; + } + + /// + /// 通过 BulletData 直接发射子弹 + /// + public static IBullet ShootBullet(BulletData bulletData, uint attackLayer) + { + if (bulletData.BulletBase.Type == 1) //实体子弹 + { + return ShootSolidBullet(bulletData, attackLayer); + } + else if (bulletData.BulletBase.Type == 2) //激光子弹 + { + return ShootLaser(bulletData, attackLayer); + } + else + { + Debug.LogError("暂未支持的子弹类型: " + bulletData.BulletBase.Type); + } + + return null; + } + + /// + /// 发射子弹的默认实现方式 + /// + private static Bullet ShootSolidBullet(BulletData bulletData, uint attackLayer) + { + //创建子弹 + var bulletInstance = ObjectManager.GetBullet(bulletData.BulletBase.Prefab); + bulletInstance.InitData(bulletData, attackLayer); + return bulletInstance; + } + + /// + /// 发射射线的默认实现方式 + /// + private static Laser ShootLaser(BulletData bulletData, uint attackLayer) + { + //创建激光 + var laser = ObjectManager.GetLaser(bulletData.BulletBase.Prefab); + laser.AddToActivityRoot(RoomLayerEnum.YSortLayer); + laser.InitData(bulletData, attackLayer, 3); + return laser; + } + + //----------------------------------------------------------------------------------- + + private static BulletData CreateSolidBulletData(Weapon weapon, float fireRotation, ExcelConfig.BulletBase bullet) + { + var data = new BulletData() + { + Weapon = weapon, + BulletBase = bullet, + TriggerRole = weapon.TriggerRole, + Harm = Utils.Random.RandomConfigRange(bullet.HarmRange), + Repel = Utils.Random.RandomConfigRange(bullet.RepelRange), + MaxDistance = Utils.Random.RandomConfigRange(bullet.DistanceRange), + FlySpeed = Utils.Random.RandomConfigRange(bullet.SpeedRange), + VerticalSpeed = Utils.Random.RandomConfigRange(bullet.VerticalSpeed), + BounceCount = Utils.Random.RandomConfigRange(bullet.BounceCount), + Penetration = Utils.Random.RandomConfigRange(bullet.Penetration), + Position = weapon.FirePoint.GlobalPosition, + }; + + var deviationAngle = Utils.Random.RandomConfigRange(bullet.DeviationAngleRange); + if (weapon.TriggerRole != null) + { + data.Altitude = weapon.TriggerRole.GetFirePointAltitude(); + var roleState = weapon.TriggerRole.RoleState; + data.Harm = roleState.CalcDamage(data.Harm); + data.Repel = roleState.CalcBulletRepel(data.Repel); + data.FlySpeed = roleState.CalcBulletSpeed(data.FlySpeed); + data.MaxDistance = roleState.CalcBulletDistance(data.MaxDistance); + data.BounceCount = roleState.CalcBulletBounceCount(data.BounceCount); + data.Penetration = roleState.CalcBulletPenetration(data.Penetration); + deviationAngle = roleState.CalcBulletDeviationAngle(deviationAngle); + + if (weapon.TriggerRole.IsAi) //只有玩家使用该武器才能获得正常速度的子弹 + { + data.FlySpeed *= weapon.AiUseAttribute.AiAttackAttr.BulletSpeedScale; + } + } + else + { + data.Altitude = 1; + } + + data.Rotation = fireRotation + Mathf.DegToRad(deviationAngle); + return data; + } + + private static BulletData CreateSolidBulletData(Role role, float fireRotation, ExcelConfig.BulletBase bullet) + { + var data = new BulletData() + { + Weapon = null, + BulletBase = bullet, + TriggerRole = role, + Harm = Utils.Random.RandomConfigRange(bullet.HarmRange), + Repel = Utils.Random.RandomConfigRange(bullet.RepelRange), + MaxDistance = Utils.Random.RandomConfigRange(bullet.DistanceRange), + FlySpeed = Utils.Random.RandomConfigRange(bullet.SpeedRange), + VerticalSpeed = Utils.Random.RandomConfigRange(bullet.VerticalSpeed), + BounceCount = Utils.Random.RandomConfigRange(bullet.BounceCount), + Penetration = Utils.Random.RandomConfigRange(bullet.Penetration), + }; + + if (role is Enemy enemy) + { + data.Position = enemy.FirePoint.GlobalPosition; + } + else + { + data.Position = role.MountPoint.GlobalPosition; + } + + var deviationAngle = Utils.Random.RandomConfigRange(bullet.DeviationAngleRange); + data.Altitude = role.GetFirePointAltitude(); + var roleState = role.RoleState; + data.Harm = roleState.CalcDamage(data.Harm); + data.Repel = roleState.CalcBulletRepel(data.Repel); + data.FlySpeed = roleState.CalcBulletSpeed(data.FlySpeed); + data.MaxDistance = roleState.CalcBulletDistance(data.MaxDistance); + data.BounceCount = roleState.CalcBulletBounceCount(data.BounceCount); + data.Penetration = roleState.CalcBulletPenetration(data.Penetration); + deviationAngle = roleState.CalcBulletDeviationAngle(deviationAngle); + + // if (role.IsAi) //只有玩家使用该武器才能获得正常速度的子弹 + // { + // data.FlySpeed *= weapon.AiUseAttribute.AiAttackAttr.BulletSpeedScale; + // } + + data.Rotation = fireRotation + Mathf.DegToRad(deviationAngle); + return data; + } + + private static BulletData CreateLaserData(Weapon weapon, float fireRotation, ExcelConfig.BulletBase bullet) + { + var data = new BulletData() + { + Weapon = weapon, + BulletBase = bullet, + TriggerRole = weapon.TriggerRole, + Harm = Utils.Random.RandomConfigRange(bullet.HarmRange), + Repel = Utils.Random.RandomConfigRange(bullet.RepelRange), + MaxDistance = Utils.Random.RandomConfigRange(bullet.DistanceRange), + BounceCount = Utils.Random.RandomConfigRange(bullet.BounceCount), + LifeTime = Utils.Random.RandomConfigRange(bullet.LifeTimeRange), + Position = weapon.FirePoint.GlobalPosition, + }; + + var deviationAngle = Utils.Random.RandomConfigRange(bullet.DeviationAngleRange); + if (weapon.TriggerRole != null) + { + data.Altitude = weapon.TriggerRole.GetFirePointAltitude(); + var roleState = weapon.TriggerRole.RoleState; + data.Harm = roleState.CalcDamage(data.Harm); + data.Repel = roleState.CalcBulletRepel(data.Repel); + data.BounceCount = roleState.CalcBulletBounceCount(data.BounceCount); + deviationAngle = roleState.CalcBulletDeviationAngle(deviationAngle); + } + else + { + data.Altitude = 1; + } + + data.Rotation = fireRotation + Mathf.DegToRad(deviationAngle); + return data; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/manager/InputManager.cs b/DungeonShooting_Godot/src/game/manager/InputManager.cs index 6d92161..f143b97 100644 --- a/DungeonShooting_Godot/src/game/manager/InputManager.cs +++ b/DungeonShooting_Godot/src/game/manager/InputManager.cs @@ -81,9 +81,13 @@ /// public static void Update(float delta) { - var application = GameApplication.Instance; MoveAxis = Input.GetVector("move_left", "move_right", "move_up", "move_down"); - CursorPosition = application.GlobalToViewPosition(application.GetGlobalMousePosition()); + var application = GameApplication.Instance; + if (application != null) + { + CursorPosition = application.GlobalToViewPosition(application.GetGlobalMousePosition()); + } + ExchangeWeapon = Input.IsActionJustPressed("exchangeWeapon"); ThrowWeapon = Input.IsActionJustPressed("throwWeapon"); Interactive = Input.IsActionJustPressed("interactive"); @@ -93,5 +97,6 @@ Roll = Input.IsActionJustPressed("roll"); UseActiveProp = Input.IsActionJustPressed("useActiveProp"); RemoveProp = Input.IsActionJustPressed("removeProp"); + ExchangeProp = Input.IsActionJustPressed("exchangeProp"); } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/manager/ObjectManager.cs b/DungeonShooting_Godot/src/game/manager/ObjectManager.cs index 4c5336e..27206a3 100644 --- a/DungeonShooting_Godot/src/game/manager/ObjectManager.cs +++ b/DungeonShooting_Godot/src/game/manager/ObjectManager.cs @@ -35,6 +35,22 @@ return item; } + /// + /// 根据类型直接获取实例对象 + /// + public static T GetPoolItemByClass() where T : IPoolItem, new() + { + var name = typeof(T).FullName; + var item = ObjectPool.GetItem(name); + if (item == null) + { + item = new T(); + item.Logotype = name; + } + + return item; + } + public static Bullet GetBullet(string id) { var bullet = ObjectPool.GetItem(id); diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs index 8ad701a..2b8e3fe 100644 --- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs +++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs @@ -15,10 +15,12 @@ public const string prefab_bullet_normal_Bullet0002_tscn = "res://prefab/bullet/normal/Bullet0002.tscn"; public const string prefab_bullet_normal_Bullet0003_tscn = "res://prefab/bullet/normal/Bullet0003.tscn"; public const string prefab_bullet_normal_Bullet0004_tscn = "res://prefab/bullet/normal/Bullet0004.tscn"; + public const string prefab_bullet_normal_Bullet0005_tscn = "res://prefab/bullet/normal/Bullet0005.tscn"; public const string prefab_effect_Blood_tscn = "res://prefab/effect/Blood.tscn"; public const string prefab_effect_common_Effect1_tscn = "res://prefab/effect/common/Effect1.tscn"; - public const string prefab_effect_enemy_Effect0001_tscn = "res://prefab/effect/enemy/Effect0001.tscn"; - public const string prefab_effect_enemy_EnemyBloodEffect_tscn = "res://prefab/effect/enemy/EnemyBloodEffect.tscn"; + public const string prefab_effect_enemy_EbenyDead0001_tscn = "res://prefab/effect/enemy/EbenyDead0001.tscn"; + public const string prefab_effect_enemy_EbenyDead0002_tscn = "res://prefab/effect/enemy/EbenyDead0002.tscn"; + public const string prefab_effect_enemy_EnemyBlood0001_tscn = "res://prefab/effect/enemy/EnemyBlood0001.tscn"; public const string prefab_effect_weapon_BulletDisappear_tscn = "res://prefab/effect/weapon/BulletDisappear.tscn"; public const string prefab_effect_weapon_BulletSmoke_tscn = "res://prefab/effect/weapon/BulletSmoke.tscn"; public const string prefab_effect_weapon_MeleeAttack1_tscn = "res://prefab/effect/weapon/MeleeAttack1.tscn"; @@ -43,9 +45,14 @@ public const string prefab_prop_buff_BuffProp0009_tscn = "res://prefab/prop/buff/BuffProp0009.tscn"; public const string prefab_prop_buff_BuffProp0010_tscn = "res://prefab/prop/buff/BuffProp0010.tscn"; public const string prefab_prop_buff_BuffProp0011_tscn = "res://prefab/prop/buff/BuffProp0011.tscn"; + public const string prefab_prop_buff_BuffProp0012_tscn = "res://prefab/prop/buff/BuffProp0012.tscn"; + public const string prefab_prop_buff_BuffProp0013_tscn = "res://prefab/prop/buff/BuffProp0013.tscn"; + public const string prefab_prop_buff_BuffProp0014_tscn = "res://prefab/prop/buff/BuffProp0014.tscn"; public const string prefab_role_Enemy0001_tscn = "res://prefab/role/Enemy0001.tscn"; + public const string prefab_role_Enemy0002_tscn = "res://prefab/role/Enemy0002.tscn"; public const string prefab_role_Role0001_tscn = "res://prefab/role/Role0001.tscn"; - public const string prefab_role_RoleTemplate_tscn = "res://prefab/role/RoleTemplate.tscn"; + public const string prefab_role_template_EnemyTemplate_tscn = "res://prefab/role/template/EnemyTemplate.tscn"; + public const string prefab_role_template_RoleTemplate_tscn = "res://prefab/role/template/RoleTemplate.tscn"; public const string prefab_shell_Shell0001_tscn = "res://prefab/shell/Shell0001.tscn"; public const string prefab_shell_Shell0002_tscn = "res://prefab/shell/Shell0002.tscn"; public const string prefab_shell_Shell0003_tscn = "res://prefab/shell/Shell0003.tscn"; @@ -101,6 +108,7 @@ public const string resource_map_tileSprite_map1_16x16dungeoniiwallreconfigv04spritesheet_png = "res://resource/map/tileSprite/map1/16x16 dungeon ii wall reconfig v04 spritesheet.png"; public const string resource_material_Blend_gdshader = "res://resource/material/Blend.gdshader"; public const string resource_material_Blend_tres = "res://resource/material/Blend.tres"; + public const string resource_material_OffsetVertex_gdshader = "res://resource/material/OffsetVertex.gdshader"; public const string resource_material_SmokeParticleMaterial_tres = "res://resource/material/SmokeParticleMaterial.tres"; public const string resource_sound_bgm_Intro_ogg = "res://resource/sound/bgm/Intro.ogg"; public const string resource_sound_sfx_beLoaded_BeLoaded0001_ogg = "res://resource/sound/sfx/beLoaded/BeLoaded0001.ogg"; @@ -196,6 +204,9 @@ public const string resource_sprite_prop_buff_BuffProp0009_png = "res://resource/sprite/prop/buff/BuffProp0009.png"; public const string resource_sprite_prop_buff_BuffProp0010_png = "res://resource/sprite/prop/buff/BuffProp0010.png"; public const string resource_sprite_prop_buff_BuffProp0011_png = "res://resource/sprite/prop/buff/BuffProp0011.png"; + public const string resource_sprite_prop_buff_BuffProp0012_png = "res://resource/sprite/prop/buff/BuffProp0012.png"; + public const string resource_sprite_prop_buff_BuffProp0013_png = "res://resource/sprite/prop/buff/BuffProp0013.png"; + public const string resource_sprite_prop_buff_BuffProp0014_png = "res://resource/sprite/prop/buff/BuffProp0014.png"; public const string resource_sprite_role_role10_png = "res://resource/sprite/role/role10.png"; public const string resource_sprite_role_role3_png = "res://resource/sprite/role/role3.png"; public const string resource_sprite_role_role4_png = "res://resource/sprite/role/role4.png"; @@ -204,10 +215,17 @@ public const string resource_sprite_role_role7_png = "res://resource/sprite/role/role7.png"; public const string resource_sprite_role_role8_png = "res://resource/sprite/role/role8.png"; public const string resource_sprite_role_role9_png = "res://resource/sprite/role/role9.png"; + public const string resource_sprite_role_common_Role_astonished_png = "res://resource/sprite/role/common/Role_astonished.png"; + public const string resource_sprite_role_common_Role_notify_png = "res://resource/sprite/role/common/Role_notify.png"; + public const string resource_sprite_role_common_Role_query_png = "res://resource/sprite/role/common/Role_query.png"; public const string resource_sprite_role_enemy0001_enemy0001_png = "res://resource/sprite/role/enemy0001/enemy0001.png"; public const string resource_sprite_role_enemy0001_enemy0001_Debris_png = "res://resource/sprite/role/enemy0001/enemy0001_Debris.png"; public const string resource_sprite_role_enemy0001_enemy0001_Icon_png = "res://resource/sprite/role/enemy0001/enemy0001_Icon.png"; public const string resource_sprite_role_enemy0002_Enemy0002_png = "res://resource/sprite/role/enemy0002/Enemy0002.png"; + public const string resource_sprite_role_enemy0002_Enemy0002_attack_png = "res://resource/sprite/role/enemy0002/Enemy0002_attack.png"; + public const string resource_sprite_role_enemy0002_Enemy0002_dead_png = "res://resource/sprite/role/enemy0002/Enemy0002_dead.png"; + public const string resource_sprite_role_enemy0002_Enemy0002_idle_png = "res://resource/sprite/role/enemy0002/Enemy0002_idle.png"; + public const string resource_sprite_role_enemy0002_Enemy0002_run_png = "res://resource/sprite/role/enemy0002/Enemy0002_run.png"; public const string resource_sprite_role_role0001_Role0001_png = "res://resource/sprite/role/role0001/Role0001.png"; public const string resource_sprite_role_role0001_Role0001_Icon_png = "res://resource/sprite/role/role0001/Role0001_Icon.png"; public const string resource_sprite_role_role0001_idle_Sprite0002_png = "res://resource/sprite/role/role0001/idle/Sprite-0002.png"; @@ -315,6 +333,7 @@ public const string resource_spriteFrames_bullet_Bullet0003_tres = "res://resource/spriteFrames/bullet/Bullet0003.tres"; public const string resource_spriteFrames_bullet_Bullet0004_tres = "res://resource/spriteFrames/bullet/Bullet0004.tres"; public const string resource_spriteFrames_effect_KnifeHit1_tres = "res://resource/spriteFrames/effect/KnifeHit1.tres"; + public const string resource_spriteFrames_effect_weapon_Collision1_tres = "res://resource/spriteFrames/effect/weapon/Collision1.tres"; public const string resource_spriteFrames_other_RoomDoor_E_Down_tres = "res://resource/spriteFrames/other/RoomDoor_E_Down.tres"; public const string resource_spriteFrames_other_RoomDoor_E_Up_tres = "res://resource/spriteFrames/other/RoomDoor_E_Up.tres"; public const string resource_spriteFrames_other_RoomDoor_N_tres = "res://resource/spriteFrames/other/RoomDoor_N.tres"; @@ -334,9 +353,13 @@ public const string resource_spriteFrames_prop_buff_BuffProp0009_tres = "res://resource/spriteFrames/prop/buff/BuffProp0009.tres"; public const string resource_spriteFrames_prop_buff_BuffProp0010_tres = "res://resource/spriteFrames/prop/buff/BuffProp0010.tres"; public const string resource_spriteFrames_prop_buff_BuffProp0011_tres = "res://resource/spriteFrames/prop/buff/BuffProp0011.tres"; + public const string resource_spriteFrames_prop_buff_BuffProp0012_tres = "res://resource/spriteFrames/prop/buff/BuffProp0012.tres"; + public const string resource_spriteFrames_prop_buff_BuffProp0013_tres = "res://resource/spriteFrames/prop/buff/BuffProp0013.tres"; + public const string resource_spriteFrames_prop_buff_BuffProp0014_tres = "res://resource/spriteFrames/prop/buff/BuffProp0014.tres"; public const string resource_spriteFrames_role_Enemy0001_tres = "res://resource/spriteFrames/role/Enemy0001.tres"; public const string resource_spriteFrames_role_Enemy0002_tres = "res://resource/spriteFrames/role/Enemy0002.tres"; public const string resource_spriteFrames_role_Role0001_tres = "res://resource/spriteFrames/role/Role0001.tres"; + public const string resource_spriteFrames_role_Role_tip_tres = "res://resource/spriteFrames/role/Role_tip.tres"; public const string resource_spriteFrames_shell_Shell0001_tres = "res://resource/spriteFrames/shell/Shell0001.tres"; public const string resource_spriteFrames_shell_Shell0002_tres = "res://resource/spriteFrames/shell/Shell0002.tres"; public const string resource_spriteFrames_shell_Shell0003_tres = "res://resource/spriteFrames/shell/Shell0003.tres"; @@ -362,6 +385,8 @@ public const string scene_test_TestNewTileMap_tscn = "res://scene/test/TestNewTileMap.tscn"; public const string scene_test_TestOptimizeSprite_tscn = "res://scene/test/TestOptimizeSprite.tscn"; public const string scene_test_TestOutline_tscn = "res://scene/test/TestOutline.tscn"; + public const string scene_test_TestPerfectPixel_tscn = "res://scene/test/TestPerfectPixel.tscn"; + public const string scene_test_TestPerfectPixelScene_tscn = "res://scene/test/TestPerfectPixelScene.tscn"; public const string scene_test_TestRoomFog_tscn = "res://scene/test/TestRoomFog.tscn"; public const string scene_test_TestTileLayer_tscn = "res://scene/test/TestTileLayer.tscn"; } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/manager/SoundManager.cs b/DungeonShooting_Godot/src/game/manager/SoundManager.cs index 80790b0..2195543 100644 --- a/DungeonShooting_Godot/src/game/manager/SoundManager.cs +++ b/DungeonShooting_Godot/src/game/manager/SoundManager.cs @@ -198,7 +198,7 @@ /// 音效Id /// 播放音效的位置, 该位置为 SubViewport 下的坐标, 也就是 使用的坐标 /// 触发播放音效的角色, 因为 Npc 产生的音效声音更小, 可以传 null - public static GameAudioPlayer2D PlaySoundByConfig(string id, Vector2 viewPosition, AdvancedRole triggerRole = null) + public static GameAudioPlayer2D PlaySoundByConfig(string id, Vector2 viewPosition, Role triggerRole = null) { var sound = ExcelConfig.Sound_Map[id]; return PlaySoundByConfig(sound, viewPosition, triggerRole); @@ -210,7 +210,7 @@ /// 音效数据 /// 播放音效的位置, 该位置为 SubViewport 下的坐标, 也就是 使用的坐标 /// 触发播放音效的角色, 因为 Npc 产生的音效声音更小, 可以传 null - public static GameAudioPlayer2D PlaySoundByConfig(ExcelConfig.Sound sound, Vector2 viewPosition, AdvancedRole triggerRole = null) + public static GameAudioPlayer2D PlaySoundByConfig(ExcelConfig.Sound sound, Vector2 viewPosition, Role triggerRole = null) { return PlaySoundEffectPosition( sound.Path, @@ -226,7 +226,7 @@ /// 播放音效的位置, 该位置为 SubViewport 下的坐标, 也就是 使用的坐标 /// 延时时间 /// 触发播放音效的角色, 因为 Npc 产生的音效声音更小, 可以传 null - public static GameAudioPlayer2D PlaySoundByConfigDelay(string id, Vector2 viewPosition, float delayTime, AdvancedRole triggerRole = null) + public static GameAudioPlayer2D PlaySoundByConfigDelay(string id, Vector2 viewPosition, float delayTime, Role triggerRole = null) { var sound = ExcelConfig.Sound_Map[id]; return PlaySoundByConfigDelay(sound, viewPosition, delayTime, triggerRole); @@ -239,7 +239,7 @@ /// 播放音效的位置, 该位置为 SubViewport 下的坐标, 也就是 使用的坐标 /// 延时时间 /// 触发播放音效的角色, 因为 Npc 产生的音效声音更小, 可以传 null - public static GameAudioPlayer2D PlaySoundByConfigDelay(ExcelConfig.Sound sound, Vector2 viewPosition, float delayTime, AdvancedRole triggerRole = null) + public static GameAudioPlayer2D PlaySoundByConfigDelay(ExcelConfig.Sound sound, Vector2 viewPosition, float delayTime, Role triggerRole = null) { return PlaySoundEffectPositionDelay( sound.Path, @@ -303,7 +303,7 @@ /// /// 计算指定角色播放音效使用的音量 /// - public static float CalcRoleVolume(float volume, AdvancedRole role) + public static float CalcRoleVolume(float volume, Role role) { if (role is not Player) { diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs index 09a0576..7e70905 100644 --- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs +++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs @@ -183,8 +183,6 @@ OnCheckEnemy(); } - //更新敌人视野 - UpdateEnemiesView(); if (ActivityObject.IsDebug) { QueueRedraw(); @@ -565,25 +563,11 @@ foreach (var enemy in World.Enemy_InstanceList) { //不与玩家处于同一个房间 - if (enemy.AffiliationArea != playerAffiliationArea) + if (!enemy.IsDestroyed && enemy.AffiliationArea != playerAffiliationArea) { - if (enemy is Enemy e) + if (enemy.StateController.CurrState != AIStateEnum.AiNormal) { - if (e.StateController.CurrState != AiStateEnum.AiNormal) - { - e.StateController.ChangeState(AiStateEnum.AiNormal); - } - } - else if (enemy is AdvancedEnemy ae) - { - if (ae.StateController.CurrState != AiStateEnum.AiNormal) - { - ae.StateController.ChangeState(AiStateEnum.AiNormal); - } - } - else - { - throw new Exception("World.Enemy_InstanceList 混入了非 Enemy 和 AdvancedEnemy 类型的对象!"); + enemy.StateController.ChangeState(AIStateEnum.AiNormal); } } } @@ -634,42 +618,6 @@ } } - /// - /// 更新敌人视野 - /// - private void UpdateEnemiesView() - { - World.Enemy_IsFindTarget = false; - World.Enemy_FindTargetAffiliationSet.Clear(); - for (var i = 0; i < World.Enemy_InstanceList.Count; i++) - { - var enemy = World.Enemy_InstanceList[i]; - AiStateEnum state; - if (enemy is Enemy e) - { - state = e.StateController.CurrState; - } - else if (enemy is AdvancedEnemy ae) - { - state = ae.StateController.CurrState; - } - else - { - throw new Exception("World.Enemy_InstanceList 混入了非 Enemy 和 AdvancedEnemy 类型的对象!"); - } - if (state == AiStateEnum.AiFollowUp || state == AiStateEnum.AiSurround) //目标在视野内 - { - if (!World.Enemy_IsFindTarget) - { - World.Enemy_IsFindTarget = true; - World.Enemy_FindTargetPosition = Player.Current.GetCenterPosition(); - World.Enemy_FindTargetAffiliationSet.Add(Player.Current.AffiliationArea); - } - World.Enemy_FindTargetAffiliationSet.Add(enemy.AffiliationArea); - } - } - } - private void DisposeRoomInfo(RoomInfo roomInfo) { roomInfo.Destroy(); diff --git a/DungeonShooting_Godot/src/game/room/World.cs b/DungeonShooting_Godot/src/game/room/World.cs index 30a6676..35673f9 100644 --- a/DungeonShooting_Godot/src/game/room/World.cs +++ b/DungeonShooting_Godot/src/game/room/World.cs @@ -62,22 +62,7 @@ /// /// 记录所有存活的敌人 /// - public List Enemy_InstanceList { get; } = new List(); - - /// - /// 公共属性, 敌人是否找到目标, 如果找到目标, 则与目标同房间的所有敌人都会知道目标的位置 - /// - public bool Enemy_IsFindTarget { get; set; } - - /// - /// 公共属性, 敌人在哪个区域找到的目标, 所有该区域下的敌人都会知道目标的位置 - /// - public HashSet Enemy_FindTargetAffiliationSet { get; } = new HashSet(); - - /// - /// 公共属性, 敌人找到的目标的位置, 如果目标在视野内, 则一直更新 - /// - public Vector2 Enemy_FindTargetPosition { get; set; } + public List Enemy_InstanceList { get; } = new List(); private bool _pause = false; private List _coroutineList; @@ -115,6 +100,31 @@ return null; } + + /// + /// 通知其他敌人发现目标了 + /// + /// 发送通知的角色 + /// 目标 + public void NotifyEnemyTarget(Role self, ActivityObject target) + { + foreach (var role in Enemy_InstanceList) + { + if (role != self && !role.IsDestroyed && role.AffiliationArea == self.AffiliationArea) + { + //将未发现目标的敌人状态置为惊讶状态 + var controller = role.StateController; + //延时通知效果 + role.CallDelay(Utils.Random.RandomRangeFloat(0.2f, 1f), () => + { + if (controller.CurrState == AIStateEnum.AiNormal) + { + controller.ChangeState(AIStateEnum.AiLeaveFor, target); + } + }); + } + } + } public long StartCoroutine(IEnumerator able) { diff --git a/DungeonShooting_Godot/src/game/ui/bottomTips/BottomTipsPanel.cs b/DungeonShooting_Godot/src/game/ui/bottomTips/BottomTipsPanel.cs index a7bba64..495fb5d 100644 --- a/DungeonShooting_Godot/src/game/ui/bottomTips/BottomTipsPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/bottomTips/BottomTipsPanel.cs @@ -69,24 +69,27 @@ yield return 0; //向上移动 - var frame = GameApplication.Instance.TargetFps * _animationTime; - var stepPixel = _movePixel / frame; - for (var i = 0; i < frame; i++) + var time = 0f; + while (time < _animationTime) { - pos.X = L_Panel.Instance.Position.X; - pos.Y -= stepPixel; - L_Panel.Instance.Position = pos; + L_Panel.Instance.Position = new Vector2( + pos.X, + pos.Y - Mathf.Lerp(0, _movePixel, Mathf.Min(time / _animationTime, 1)) + ); + time += (float)GetProcessDeltaTime(); yield return 0; } yield return new WaitForSeconds(3.5f); //向下移动 - for (var i = 0; i < frame; i++) + while (time > 0) { - pos.X = L_Panel.Instance.Position.X; - pos.Y += stepPixel; - L_Panel.Instance.Position = pos; + L_Panel.Instance.Position = new Vector2( + pos.X, + pos.Y - Mathf.Lerp(0, _movePixel, Mathf.Max(time / _animationTime, 0)) + ); + time -= (float)GetProcessDeltaTime(); yield return 0; } diff --git a/DungeonShooting_Godot/src/game/ui/roomUI/InteractiveTipBar.cs b/DungeonShooting_Godot/src/game/ui/roomUI/InteractiveTipBar.cs index 3203984..3dd9265 100644 --- a/DungeonShooting_Godot/src/game/ui/roomUI/InteractiveTipBar.cs +++ b/DungeonShooting_Godot/src/game/ui/roomUI/InteractiveTipBar.cs @@ -70,7 +70,7 @@ { _interactiveTarget = interactiveItem; //显示互动提示 - ShowBar(result.Target, result.Target.ItemConfig.Name, icon); + ShowBar(result.Target, result.Target.ActivityBase.Name, icon); } else { diff --git a/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs b/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs index 56f26c3..9d8132b 100644 --- a/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs @@ -1,4 +1,5 @@ +using Godot; using UI.BottomTips; namespace UI.RoomUI; @@ -54,13 +55,27 @@ _weaponBar.Process(delta); _activePropBar.Process(delta); _lifeBar.Process(delta); + + QueueRedraw(); } //玩家拾起道具, 弹出提示 private void OnPlayerPickUpProp(object propObj) { var prop = (Prop)propObj; - var message = $"{prop.ItemConfig.Name}\n{prop.ItemConfig.Intro}"; + var message = $"{prop.ActivityBase.Name}\n{prop.ActivityBase.Intro}"; BottomTipsPanel.ShowTips(prop.GetDefaultTexture(), message); } + + public override void _Draw() + { + foreach (var role in World.Current.Enemy_InstanceList) + { + if (!role.IsDestroyed) + { + var position = GameApplication.Instance.ViewToGlobalPosition(role.Position); + DrawString(ResourceManager.DefaultFont16Px, position, role.StateController.CurrState.ToString()); + } + } + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/test/TestPerfectPixelScene.cs b/DungeonShooting_Godot/src/test/TestPerfectPixelScene.cs new file mode 100644 index 0000000..1878e8a --- /dev/null +++ b/DungeonShooting_Godot/src/test/TestPerfectPixelScene.cs @@ -0,0 +1,81 @@ +using Godot; +using System; + +public partial class TestPerfectPixelScene : Node2D +{ + public enum HandlerType + { + UnHandler, + NormalHandler, + OffsetHandler + } + + [Export] + public CharacterBody2D Player; + + [Export] + public Label FpsLabel; + + [Export] + public Camera2D Camera2D; + + [Export] + public float Speed = 50; + + [Export] + public float CameraRecoveryScale = 5; + + [Export] + public SubViewportContainer SubViewportContainer; + + [Export] + public HandlerType Type; + + private ShaderMaterial _shaderMaterial; + private Vector2 _cameraPos; + + public override void _Ready() + { + if (SubViewportContainer != null) + { + _shaderMaterial = (ShaderMaterial)SubViewportContainer.Material; + } + } + + public override void _Process(double delta) + { + InputManager.Update((float)delta); + + + } + + public override void _PhysicsProcess(double delta) + { + FpsLabel.Text = "FPS: " + Engine.GetFramesPerSecond(); + Player.Velocity = InputManager.MoveAxis * Speed; + Player.MoveAndSlide(); + + var playerPos = Player.GlobalPosition; + //_cameraPos = playerPos; + _cameraPos = _cameraPos.MoveToward(playerPos, playerPos.DistanceTo(_cameraPos) * (float)delta * CameraRecoveryScale); + + if (Type == HandlerType.UnHandler) + { + Camera2D.GlobalPosition = _cameraPos; + } + else if (Type == HandlerType.NormalHandler) + { + Camera2D.GlobalPosition = _cameraPos.Round(); + } + else if (Type == HandlerType.OffsetHandler) + { + if (_shaderMaterial != null) + { + var cameraPosition = _cameraPos; + var offset = cameraPosition.Round() - cameraPosition; + _shaderMaterial.SetShaderParameter("offset", offset); + Camera2D.GlobalPosition = cameraPosition.Round(); + } + } + } +}