nav collision
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
# Godot 4+ specific ignores
|
# Godot 4+ specific ignores
|
||||||
.godot/
|
.godot/
|
||||||
/android/
|
/android/
|
||||||
|
|
||||||
|
**/*.xm
|
||||||
|
**/*.it
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
[gd_scene format=3 uid="uid://crgeyg1m54cg8"]
|
[gd_scene format=3 uid="uid://crgeyg1m54cg8"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://dtqv683r772sd" path="res://player.gd" id="1_3dxm6"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cqisk1m0in4a4" path="res://shield.png" id="1_03owx"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dgkao0lkjfn8x" path="res://gun-handheld-reduced.png" id="1_glv2v"]
|
[ext_resource type="Texture2D" uid="uid://dgkao0lkjfn8x" path="res://gun-handheld-reduced.png" id="1_glv2v"]
|
||||||
[ext_resource type="Texture2D" uid="uid://de7h5yetxbjii" path="res://gui-reduced.png" id="2_uu6xs"]
|
[ext_resource type="Texture2D" uid="uid://de7h5yetxbjii" path="res://gui-reduced.png" id="2_uu6xs"]
|
||||||
[ext_resource type="Script" uid="uid://biacb353kq32o" path="res://level_mesh.gd" id="3_cm0pq"]
|
[ext_resource type="Script" uid="uid://biacb353kq32o" path="res://level_mesh.gd" id="3_cm0pq"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bj63s2jg8oinu" path="res://rock22.jpg" id="4_fos0i"]
|
[ext_resource type="Texture2D" uid="uid://bj63s2jg8oinu" path="res://rock22.jpg" id="4_fos0i"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cbfvjlda1hapx" path="res://metall001-new-tileable2.png" id="5_fos0i"]
|
[ext_resource type="Texture2D" uid="uid://cbfvjlda1hapx" path="res://metall001-new-tileable2.png" id="5_fos0i"]
|
||||||
|
[ext_resource type="Script" uid="uid://djgd6mugw2s47" path="res://godot-mod-player-g4-master/addons/modplayer/ModPlayer.gd" id="7_lgr22"]
|
||||||
|
[ext_resource type="Script" uid="uid://cc2rv3wnwas52" path="res://wall_segment.gd" id="7_trn2v"]
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_03owx"]
|
||||||
|
shading_mode = 2
|
||||||
|
albedo_color = Color(0.1415951, 0.43394297, 0.68819517, 1)
|
||||||
|
|
||||||
|
[sub_resource type="PrismMesh" id="PrismMesh_1065d"]
|
||||||
|
|
||||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_lgr22"]
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_lgr22"]
|
||||||
sky_top_color = Color(0.15010819, 0.09080864, 3.6098065e-08, 1)
|
sky_top_color = Color(0.15010819, 0.09080864, 3.6098065e-08, 1)
|
||||||
@@ -25,7 +35,6 @@ sky = SubResource("Sky_3dxm6")
|
|||||||
ambient_light_source = 3
|
ambient_light_source = 3
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cm0pq"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cm0pq"]
|
||||||
cull_mode = 1
|
|
||||||
shading_mode = 2
|
shading_mode = 2
|
||||||
specular_mode = 2
|
specular_mode = 2
|
||||||
albedo_texture = ExtResource("4_fos0i")
|
albedo_texture = ExtResource("4_fos0i")
|
||||||
@@ -34,50 +43,86 @@ fov_override = 33.9
|
|||||||
distance_fade_mode = 1
|
distance_fade_mode = 1
|
||||||
distance_fade_max_distance = 2.0
|
distance_fade_max_distance = 2.0
|
||||||
|
|
||||||
[sub_resource type="ImmediateMesh" id="ImmediateMesh_fos0i"]
|
[sub_resource type="ImmediateMesh" id="ImmediateMesh_03owx"]
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fos0i"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fos0i"]
|
||||||
shading_mode = 2
|
|
||||||
specular_mode = 2
|
specular_mode = 2
|
||||||
albedo_texture = ExtResource("5_fos0i")
|
albedo_texture = ExtResource("5_fos0i")
|
||||||
texture_filter = 2
|
texture_filter = 4
|
||||||
fov_override = 33.9
|
fov_override = 33.9
|
||||||
distance_fade_mode = 2
|
distance_fade_mode = 2
|
||||||
distance_fade_max_distance = 1.0
|
distance_fade_max_distance = 1.0
|
||||||
|
|
||||||
[sub_resource type="ImmediateMesh" id="ImmediateMesh_3dxm6"]
|
[sub_resource type="ImmediateMesh" id="ImmediateMesh_wkp8b"]
|
||||||
|
|
||||||
|
[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_20pc6"]
|
||||||
|
data = PackedVector3Array(1.9799999, 0, 0.57, 0.7, 0, 0.89, 1.916, 2.7717, 0.31399998, 0.7, 0, 0.89, 0.188, 1.6502, 1.082, 1.916, 2.7717, 0.31399998, 1.916, 2.7717, 0.31399998, 0.188, 1.6502, 1.082, 1.9799999, 5, 0.57, 0.188, 1.6502, 1.082, 0.7, 5, 0.89, 1.9799999, 5, 0.57, 0.7, 0, 0.89, 1.66, 0, 3.4499998, 0.188, 1.6502, 1.082, 1.66, 0, 3.4499998, 1.3399999, 1.4045, 3.7059999, 0.188, 1.6502, 1.082, 0.188, 1.6502, 1.082, 1.3399999, 1.4045, 3.7059999, 0.7, 5, 0.89, 1.3399999, 1.4045, 3.7059999, 1.66, 5, 3.4499998, 0.7, 5, 0.89, 1.66, 0, 3.4499998, 2.9399998, 0, 5.0499997, 1.3399999, 1.4045, 3.7059999, 2.9399998, 0, 5.0499997, 2.958, 1.2507, 5.694, 1.3399999, 1.4045, 3.7059999, 1.3399999, 1.4045, 3.7059999, 2.958, 1.2507, 5.694, 1.66, 5, 3.4499998, 2.958, 1.2507, 5.694, 2.9399998, 5, 5.0499997, 1.66, 5, 3.4499998, 2.9399998, 0, 5.0499997, 6.16, 0, 4.96, 2.958, 1.2507, 5.694, 6.16, 0, 4.96, 5.118, 1.7171999, 5.148, 2.958, 1.2507, 5.694, 2.958, 1.2507, 5.694, 5.118, 1.7171999, 5.148, 2.9399998, 5, 5.0499997, 5.118, 1.7171999, 5.148, 6.16, 5, 4.96, 2.9399998, 5, 5.0499997, 6.16, 0, 4.96, 7.1, 0, 10.17, 5.118, 1.7171999, 5.148, 7.1, 0, 10.17, 6.5239997, 1.3377, 9.658, 5.118, 1.7171999, 5.148, 5.118, 1.7171999, 5.148, 6.5239997, 1.3377, 9.658, 6.16, 5, 4.96, 6.5239997, 1.3377, 9.658, 7.1, 5, 10.17, 6.16, 5, 4.96, 7.1, 0, 10.17, 4.54, 0, 13.049999, 6.5239997, 1.3377, 9.658, 4.54, 0, 13.049999, 3.964, 2.7186, 13.497999, 6.5239997, 1.3377, 9.658, 6.5239997, 1.3377, 9.658, 3.964, 2.7186, 13.497999, 7.1, 5, 10.17, 3.964, 2.7186, 13.497999, 4.54, 5, 13.049999, 7.1, 5, 10.17, 4.54, 0, 13.049999, 6.7799997, 0, 15.929999, 3.964, 2.7186, 13.497999, 6.7799997, 0, 15.929999, 6.908, 1.9440999, 16.633999, 3.964, 2.7186, 13.497999, 3.964, 2.7186, 13.497999, 6.908, 1.9440999, 16.633999, 4.54, 5, 13.049999, 6.908, 1.9440999, 16.633999, 6.7799997, 5, 15.929999, 4.54, 5, 13.049999, 6.7799997, 0, 15.929999, 10.3, 0, 15.29, 6.908, 1.9440999, 16.633999, 10.3, 0, 15.29, 11.068, 2.4175, 15.481999, 6.908, 1.9440999, 16.633999, 6.908, 1.9440999, 16.633999, 11.068, 2.4175, 15.481999, 6.7799997, 5, 15.929999, 11.068, 2.4175, 15.481999, 10.3, 5, 15.29, 6.7799997, 5, 15.929999, 10.3, 0, 15.29, 11.259999, 0, 11.45, 11.068, 2.4175, 15.481999, 11.259999, 0, 11.45, 12.334, 2.0367, 11.054, 11.068, 2.4175, 15.481999, 11.068, 2.4175, 15.481999, 12.334, 2.0367, 11.054, 10.3, 5, 15.29, 12.334, 2.0367, 11.054, 11.259999, 5, 11.45, 10.3, 5, 15.29, 11.259999, 0, 11.45, 9.28, 0, 6.08, 12.334, 2.0367, 11.054, 9.28, 0, 6.08, 8.846, 1.1595, 7.3719997, 12.334, 2.0367, 11.054, 12.334, 2.0367, 11.054, 8.846, 1.1595, 7.3719997, 11.259999, 5, 11.45, 8.846, 1.1595, 7.3719997, 9.28, 5, 6.08, 11.259999, 5, 11.45, 9.28, 0, 6.08, 15.74, 0, 8.25, 8.846, 1.1595, 7.3719997, 15.74, 0, 8.25, 16.123999, 1.4636999, 8.506, 8.846, 1.1595, 7.3719997, 8.846, 1.1595, 7.3719997, 16.123999, 1.4636999, 8.506, 9.28, 5, 6.08, 16.123999, 1.4636999, 8.506, 15.74, 5, 8.25, 9.28, 5, 6.08, 15.74, 0, 8.25, 17.02, 0, 6.33, 16.123999, 1.4636999, 8.506, 17.02, 0, 6.33, 17.821999, 1.3002, 5.534, 16.123999, 1.4636999, 8.506, 16.123999, 1.4636999, 8.506, 17.821999, 1.3002, 5.534, 15.74, 5, 8.25, 17.821999, 1.3002, 5.534, 17.02, 5, 6.33, 15.74, 5, 8.25, 17.02, 0, 6.33, 13.04, 0, 2.32, 17.821999, 1.3002, 5.534, 13.04, 0, 2.32, 13.134, 2.981, 1.388, 17.821999, 1.3002, 5.534, 17.821999, 1.3002, 5.534, 13.134, 2.981, 1.388, 17.02, 5, 6.33, 13.134, 2.981, 1.388, 13.04, 5, 2.32, 17.02, 5, 6.33, 13.04, 0, 2.32, 8.38, 0, 1.8499999, 13.134, 2.981, 1.388, 8.38, 0, 1.8499999, 8.254, 2.2742, 1.214, 13.134, 2.981, 1.388, 13.134, 2.981, 1.388, 8.254, 2.2742, 1.214, 13.04, 5, 2.32, 8.254, 2.2742, 1.214, 8.38, 5, 1.8499999, 13.04, 5, 2.32, 8.38, 0, 1.8499999, 5.2, 0, 2.48, 8.254, 2.2742, 1.214, 5.2, 0, 2.48, 5.454, 2.3258998, 2.22, 8.254, 2.2742, 1.214, 8.254, 2.2742, 1.214, 5.454, 2.3258998, 2.22, 8.38, 5, 1.8499999, 5.454, 2.3258998, 2.22, 5.2, 5, 2.48, 8.38, 5, 1.8499999, 5.2, 0, 2.48, 3.8999999, 0, 1.2099999, 5.454, 2.3258998, 2.22, 3.8999999, 0, 1.2099999, 4.028, 2.1676, 0.826, 5.454, 2.3258998, 2.22, 5.454, 2.3258998, 2.22, 4.028, 2.1676, 0.826, 5.2, 5, 2.48, 4.028, 2.1676, 0.826, 3.8999999, 5, 1.2099999, 5.2, 5, 2.48, 3.8999999, 0, 1.2099999, 1.9799999, 0, 0.57, 4.028, 2.1676, 0.826, 1.9799999, 0, 0.57, 1.916, 2.2347999, 0.31399998, 4.028, 2.1676, 0.826, 4.028, 2.1676, 0.826, 1.916, 2.2347999, 0.31399998, 3.8999999, 5, 1.2099999, 1.916, 2.2347999, 0.31399998, 1.9799999, 5, 0.57, 3.8999999, 5, 1.2099999)
|
||||||
|
backface_collision = true
|
||||||
|
|
||||||
[node name="Node3D" type="Node3D" unique_id=1749101855]
|
[node name="Node3D" type="Node3D" unique_id=1749101855]
|
||||||
|
|
||||||
[node name="Camera3D" type="Camera3D" parent="." unique_id=1552004731]
|
[node name="WallMark" type="Sprite3D" parent="." unique_id=1606442103]
|
||||||
|
pixel_size = 0.02
|
||||||
|
texture = ExtResource("1_03owx")
|
||||||
|
|
||||||
|
[node name="SidePoint" type="MeshInstance3D" parent="WallMark" unique_id=909669364]
|
||||||
|
transform = Transform3D(0.2, 0, 0, 0, -3.3225813e-08, -0.19999997, 0, 0.760118, -8.742277e-09, 0, 0, 0.5)
|
||||||
|
material_override = SubResource("StandardMaterial3D_03owx")
|
||||||
|
mesh = SubResource("PrismMesh_1065d")
|
||||||
|
|
||||||
|
[node name="FloorMark" type="Sprite3D" parent="." unique_id=1733002043]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, 0)
|
||||||
|
pixel_size = 0.02
|
||||||
|
texture = ExtResource("1_03owx")
|
||||||
|
|
||||||
|
[node name="SidePoint" type="MeshInstance3D" parent="FloorMark" unique_id=2041287788]
|
||||||
|
transform = Transform3D(0.2, 0, 0, 0, -3.3225813e-08, -0.19999997, 0, 0.760118, -8.742277e-09, 0, 0, 0.5)
|
||||||
|
material_override = SubResource("StandardMaterial3D_03owx")
|
||||||
|
mesh = SubResource("PrismMesh_1065d")
|
||||||
|
|
||||||
|
[node name="Player" type="Node3D" parent="." unique_id=1544606435 node_paths=PackedStringArray("_cam", "_ray")]
|
||||||
|
script = ExtResource("1_3dxm6")
|
||||||
|
_cam = NodePath("Look")
|
||||||
|
_ray = NodePath("Look/RayCast3D")
|
||||||
|
|
||||||
|
[node name="Look" type="Camera3D" parent="Player" unique_id=1552004731]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1.1841735)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1.1841735)
|
||||||
|
|
||||||
[node name="Sprite3D2" type="Sprite3D" parent="." unique_id=2128191748]
|
[node name="Sprite3D2" type="Sprite3D" parent="Player/Look" unique_id=2128191748]
|
||||||
transform = Transform3D(0.75, 0, 0, 0, 0.75, 0, 0, 0, 0.75, 0, 0, 0)
|
transform = Transform3D(0.75, 0, 0, 0, 0.75, 0, 0, 0, 0.75, 0, 0, -1.1841735)
|
||||||
billboard = 1
|
billboard = 1
|
||||||
texture_filter = 0
|
texture_filter = 0
|
||||||
texture = ExtResource("2_uu6xs")
|
texture = ExtResource("2_uu6xs")
|
||||||
|
|
||||||
[node name="Sprite3D" type="Sprite3D" parent="." unique_id=328920978]
|
[node name="Sprite3D" type="Sprite3D" parent="Player/Look" unique_id=328920978]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.47348556, -0.6719171, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.47348556, -0.6719171, -1.1841735)
|
||||||
billboard = 1
|
billboard = 1
|
||||||
texture_filter = 0
|
texture_filter = 0
|
||||||
render_priority = 1
|
render_priority = 1
|
||||||
texture = ExtResource("1_glv2v")
|
texture = ExtResource("1_glv2v")
|
||||||
|
|
||||||
|
[node name="RayCast3D" type="RayCast3D" parent="Player/Look" unique_id=987966127]
|
||||||
|
transform = Transform3D(-100, -1.509958e-05, -6.6002363e-13, 0, -4.371139e-06, 100, -1.509958e-05, 100, 4.371139e-06, 0, 0, 0)
|
||||||
|
collision_mask = 32774
|
||||||
|
hit_from_inside = true
|
||||||
|
collide_with_areas = true
|
||||||
|
debug_shape_thickness = 1
|
||||||
|
|
||||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=2112481184]
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=2112481184]
|
||||||
environment = SubResource("Environment_r0du0")
|
environment = SubResource("Environment_r0du0")
|
||||||
|
|
||||||
[node name="AreaLight3D" type="AreaLight3D" parent="." unique_id=1499708949]
|
[node name="AreaLight3D" type="AreaLight3D" parent="." unique_id=1499708949]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.8187913, 0.6215458, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.3378613, -0.5583314, -4.607884)
|
||||||
|
light_color = Color(0.9137892, 0.027400356, 0.120897986, 1)
|
||||||
|
light_energy = 16.0
|
||||||
|
|
||||||
[node name="LevelMesh" type="Polygon2D" parent="." unique_id=1028271676 node_paths=PackedStringArray("_floor_mesh", "_wall_mesh")]
|
[node name="LevelMesh" type="Polygon2D" parent="." unique_id=1028271676 node_paths=PackedStringArray("_floor_mesh", "_wall_mesh")]
|
||||||
self_modulate = Color(1, 1, 1, 0)
|
self_modulate = Color(1, 1, 1, 0)
|
||||||
position = Vector2(-38, -25)
|
position = Vector2(-38, -25)
|
||||||
color = Color(0.45490196, 0.45490196, 0.45490196, 0.6)
|
color = Color(0.45490196, 0.45490196, 0.45490196, 0.6)
|
||||||
polygon = PackedVector2Array(198, 57, 70, 89, 166, 345, 294, 505, 550, 537, 710, 1017, 454, 1305, 678, 1593, 1030, 1529, 1130.7727, 1130.3756, 902, 505, 1574, 825, 1702, 633, 1192, 256, 838, 185, 518, 249, 390, 121)
|
polygon = PackedVector2Array(198, 57, 70, 89, 166, 345, 294, 505, 615.9999, 495.99997, 710, 1017, 454, 1305, 678, 1593, 1030, 1529, 1126, 1145, 927.9999, 607.99994, 1574, 825, 1702, 633, 1303.9999, 232, 838, 185, 520, 248, 390, 121)
|
||||||
uv = PackedVector2Array(198, 57, 70, 89, 166, 345, 294, 505, 550, 537, 710, 1017, 454, 1305, 678, 1593, 1030, 1529, 934, 793, 902, 473, 1574, 825, 1702, 633, 1094, 313, 794.0979, 279.67758, 518, 249, 390, 121)
|
uv = PackedVector2Array(198, 57, 70, 89, 166, 345, 294, 505, 550, 537, 710, 1017, 454, 1305, 678, 1593, 1030, 1529, 934, 793, 902, 473, 1574, 825, 1702, 633, 1094, 313, 794.0979, 279.67758, 518, 249, 390, 121)
|
||||||
polygons = [PackedInt32Array(0, 1, 2), PackedInt32Array(5, 6, 7), PackedInt32Array(5, 7, 8), PackedInt32Array(5, 8, 9), PackedInt32Array(4, 5, 10), PackedInt32Array(5, 9, 10), PackedInt32Array(10, 11, 13), PackedInt32Array(11, 12, 13), PackedInt32Array(10, 13, 14), PackedInt32Array(4, 10, 14), PackedInt32Array(4, 14, 15), PackedInt32Array(2, 3, 15), PackedInt32Array(3, 4, 15), PackedInt32Array(0, 2, 16), PackedInt32Array(2, 15, 16)]
|
polygons = [PackedInt32Array(2, 1, 0), PackedInt32Array(7, 6, 5), PackedInt32Array(8, 7, 5), PackedInt32Array(9, 8, 5), PackedInt32Array(10, 5, 4), PackedInt32Array(10, 9, 5), PackedInt32Array(13, 11, 10), PackedInt32Array(13, 12, 11), PackedInt32Array(14, 10, 4), PackedInt32Array(14, 13, 10), PackedInt32Array(15, 14, 4), PackedInt32Array(15, 3, 2), PackedInt32Array(15, 4, 3), PackedInt32Array(16, 2, 0), PackedInt32Array(16, 15, 2)]
|
||||||
script = ExtResource("3_cm0pq")
|
script = ExtResource("3_cm0pq")
|
||||||
_floor_mesh = NodePath("FloorMesh")
|
_floor_mesh = NodePath("FloorMesh")
|
||||||
_wall_mesh = NodePath("WallMesh")
|
_wall_mesh = NodePath("WallMesh")
|
||||||
@@ -86,9 +131,26 @@ _scale = 0.01
|
|||||||
[node name="FloorMesh" type="MeshInstance3D" parent="LevelMesh" unique_id=961663820]
|
[node name="FloorMesh" type="MeshInstance3D" parent="LevelMesh" unique_id=961663820]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.325726, -1.0841981, -12.307181)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.325726, -1.0841981, -12.307181)
|
||||||
material_override = SubResource("StandardMaterial3D_cm0pq")
|
material_override = SubResource("StandardMaterial3D_cm0pq")
|
||||||
mesh = SubResource("ImmediateMesh_fos0i")
|
mesh = SubResource("ImmediateMesh_03owx")
|
||||||
|
|
||||||
[node name="WallMesh" type="MeshInstance3D" parent="LevelMesh" unique_id=653175378]
|
[node name="WallMesh" type="MeshInstance3D" parent="LevelMesh" unique_id=653175378]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.325726, -1.0841981, -12.307181)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.325726, -1.0841981, -12.307181)
|
||||||
material_override = SubResource("StandardMaterial3D_fos0i")
|
material_override = SubResource("StandardMaterial3D_fos0i")
|
||||||
mesh = SubResource("ImmediateMesh_3dxm6")
|
mesh = SubResource("ImmediateMesh_wkp8b")
|
||||||
|
|
||||||
|
[node name="WallMesh_col" type="StaticBody3D" parent="LevelMesh/WallMesh" unique_id=141738477]
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="LevelMesh/WallMesh/WallMesh_col" unique_id=1446575305]
|
||||||
|
shape = SubResource("ConcavePolygonShape3D_20pc6")
|
||||||
|
|
||||||
|
[node name="WallSegments" type="Node2D" parent="LevelMesh" unique_id=1390058976]
|
||||||
|
|
||||||
|
[node name="WallSegment" type="Line2D" parent="LevelMesh/WallSegments" unique_id=2053155144]
|
||||||
|
points = PackedVector2Array(710, 1017, 390, 1369)
|
||||||
|
script = ExtResource("7_trn2v")
|
||||||
|
|
||||||
|
[node name="ModPlayer" type="Node" parent="." unique_id=1374096575]
|
||||||
|
script = ExtResource("7_lgr22")
|
||||||
|
file = "res://mod211-headache.xm"
|
||||||
|
playing = true
|
||||||
|
metadata/_custom_type_script = "uid://djgd6mugw2s47"
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
##
|
||||||
|
## Godot Mod Player Plugin by arlez80 (Yui Kinomoto)
|
||||||
|
##
|
||||||
|
|
||||||
|
@tool
|
||||||
|
extends EditorPlugin
|
||||||
|
|
||||||
|
# Nothing to do, the main logic to expose this to the user
|
||||||
|
# is done via `class_name` in `ModPlayer.gd`.
|
||||||
|
|
||||||
|
func _get_plugin_name():
|
||||||
|
return "Godot Mod Player"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bfmp165qm0qf
|
||||||
@@ -0,0 +1,271 @@
|
|||||||
|
##
|
||||||
|
## MOD parser by あるる(きのもと 結衣) @arlez80
|
||||||
|
##
|
||||||
|
## MIT License
|
||||||
|
##
|
||||||
|
|
||||||
|
@warning_ignore_start("untyped_declaration")
|
||||||
|
@warning_ignore_start("unsafe_method_access")
|
||||||
|
@warning_ignore_start("unused_variable")
|
||||||
|
|
||||||
|
class_name Mod
|
||||||
|
|
||||||
|
const period_table:Array[int] = [
|
||||||
|
1712,1616,1525,1440,1357,1281,1209,1141,1077,1017, 961, 907,
|
||||||
|
856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
|
||||||
|
428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
|
||||||
|
214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
|
||||||
|
107, 101, 95, 90, 85, 80, 76, 71, 67, 64, 60, 57,
|
||||||
|
]
|
||||||
|
|
||||||
|
enum ModFlags {
|
||||||
|
LINEAR_FREQUENCY_TABLE = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ModWaveFormType {
|
||||||
|
SINE_WAVEFORM = 0,
|
||||||
|
SAW_WAVEFORM = 1,
|
||||||
|
SQUARE_WAVEFORM = 2,
|
||||||
|
RAMDOM_WAVEFORM = 3,
|
||||||
|
REV_SAW_WAVEFORM = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ModLoopType {
|
||||||
|
NO_LOOP = 0,
|
||||||
|
FORWARD_LOOP = 1,
|
||||||
|
PING_PONG_LOOP = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModData:
|
||||||
|
var module_name:String
|
||||||
|
var tracker_name:String
|
||||||
|
var version:int
|
||||||
|
var flags:int = 0
|
||||||
|
|
||||||
|
var song_length:int
|
||||||
|
var unknown_number:int
|
||||||
|
var channel_count:int
|
||||||
|
var song_positions:PackedByteArray
|
||||||
|
var magic:String
|
||||||
|
var patterns:Array # ModPattern[][]
|
||||||
|
var instruments:Array[ModInstrument]
|
||||||
|
|
||||||
|
var init_tick:int = 6
|
||||||
|
var init_bpm:int = 125
|
||||||
|
var restart_position:int = 0
|
||||||
|
|
||||||
|
class ModPatternNote:
|
||||||
|
var key_number:int
|
||||||
|
var note:int
|
||||||
|
var instrument:int
|
||||||
|
var volume:int = 0
|
||||||
|
var effect_command:int
|
||||||
|
var effect_param:int
|
||||||
|
|
||||||
|
class ModInstrument:
|
||||||
|
var name:String
|
||||||
|
var samples:Array[ModSample]
|
||||||
|
var volume_envelope:ModEnvelope
|
||||||
|
var panning_envelope:ModEnvelope
|
||||||
|
var vibrato_type:ModWaveFormType = ModWaveFormType.SINE_WAVEFORM
|
||||||
|
var vibrato_speed:int = -1
|
||||||
|
var vibrato_depth:int = -1
|
||||||
|
var vibrato_depth_shift:int = -1
|
||||||
|
var volume_fadeout:int = -1
|
||||||
|
|
||||||
|
class ModSample:
|
||||||
|
var data:PackedByteArray
|
||||||
|
var name:String
|
||||||
|
var length:int
|
||||||
|
var loop_start:int
|
||||||
|
var loop_length:int
|
||||||
|
var volume:int
|
||||||
|
var finetune:int
|
||||||
|
var loop_type:int = ModLoopType.FORWARD_LOOP # set(ModLoopType)
|
||||||
|
var bit:int = 8 # 8 or 16
|
||||||
|
var panning:int = -1
|
||||||
|
var relative_note:int = 0
|
||||||
|
|
||||||
|
class ModEnvelope:
|
||||||
|
var points:Array[ModEnvelopePoint]
|
||||||
|
var point_count:int
|
||||||
|
var sustain_point:int
|
||||||
|
var loop_start_point:int
|
||||||
|
var loop_end_point:int
|
||||||
|
|
||||||
|
var enabled:bool
|
||||||
|
var sustain_enabled:bool
|
||||||
|
var loop_enabled:bool
|
||||||
|
|
||||||
|
func set_flag( f:int ):
|
||||||
|
self.enabled = ( f & 1 ) != 0
|
||||||
|
self.sustain_enabled = ( f & 2 ) != 0
|
||||||
|
self.loop_enabled = ( f & 4 ) != 0
|
||||||
|
|
||||||
|
class ModEnvelopePoint:
|
||||||
|
var frame:int
|
||||||
|
var value:int
|
||||||
|
|
||||||
|
class ModParseResult:
|
||||||
|
var error:int = OK
|
||||||
|
var data:ModData = null
|
||||||
|
|
||||||
|
func _init():
|
||||||
|
pass
|
||||||
|
|
||||||
|
## ファイルから読み込み
|
||||||
|
## @param path ファイルパス
|
||||||
|
## @return 読んだ Modファイルデータ
|
||||||
|
func read_file( path:String ) -> ModParseResult:
|
||||||
|
var result: = ModParseResult.new( )
|
||||||
|
|
||||||
|
var f: = FileAccess.open( path, FileAccess.READ )
|
||||||
|
if f.get_error( ) != OK:
|
||||||
|
result.error = f.get_error( )
|
||||||
|
return result
|
||||||
|
|
||||||
|
var stream:StreamPeerBuffer = StreamPeerBuffer.new( )
|
||||||
|
stream.set_data_array( f.get_buffer( f.get_length( ) ) )
|
||||||
|
stream.big_endian = true
|
||||||
|
|
||||||
|
result.data = self._read( stream )
|
||||||
|
return result
|
||||||
|
|
||||||
|
## 配列から読み込み
|
||||||
|
## @param data データ
|
||||||
|
## @return ModData
|
||||||
|
func read_data( data:PackedByteArray ) -> ModParseResult:
|
||||||
|
var stream:StreamPeerBuffer = StreamPeerBuffer.new( )
|
||||||
|
stream.set_data_array( data )
|
||||||
|
stream.big_endian = true
|
||||||
|
|
||||||
|
var result: = ModParseResult.new( )
|
||||||
|
result.data = self._read( stream )
|
||||||
|
return result
|
||||||
|
|
||||||
|
## ストリームから読み込み
|
||||||
|
## @param stream ストリーム
|
||||||
|
## @return 読んだ Modファイルデータ
|
||||||
|
func _read( stream:StreamPeerBuffer ) -> ModData:
|
||||||
|
var mod: = ModData.new( )
|
||||||
|
mod.module_name = self._read_string( stream, 20 )
|
||||||
|
mod.tracker_name = ""
|
||||||
|
mod.instruments = self._read_instruments( stream )
|
||||||
|
mod.song_length = stream.get_u8( )
|
||||||
|
mod.unknown_number = stream.get_u8( )
|
||||||
|
mod.song_positions = stream.get_partial_data( 128 )[1]
|
||||||
|
var max_song_position:int = 0
|
||||||
|
for sp in mod.song_positions:
|
||||||
|
if max_song_position < sp:
|
||||||
|
max_song_position = sp
|
||||||
|
|
||||||
|
mod.magic = self._read_string( stream, 4 )
|
||||||
|
var channel_count:int = 4
|
||||||
|
match mod.magic:
|
||||||
|
"6CHN":
|
||||||
|
channel_count = 6
|
||||||
|
"FLT8", "8CHN", "CD81", "OKTA":
|
||||||
|
channel_count = 8
|
||||||
|
"16CN":
|
||||||
|
channel_count = 16
|
||||||
|
"32CN":
|
||||||
|
channel_count = 32
|
||||||
|
_:
|
||||||
|
if mod.magic.substr( 2 ) == "CH":
|
||||||
|
channel_count = int( mod.magic )
|
||||||
|
# print( "Unknown magic" )
|
||||||
|
# breakpoint
|
||||||
|
pass
|
||||||
|
mod.channel_count = channel_count
|
||||||
|
|
||||||
|
mod.patterns = self._read_patterns( stream, max_song_position + 1, channel_count )
|
||||||
|
self._read_sample_data( stream, mod.instruments )
|
||||||
|
|
||||||
|
return mod
|
||||||
|
|
||||||
|
## 楽器データを読み込む
|
||||||
|
## @param stream ストリーム
|
||||||
|
## @return 楽器データ
|
||||||
|
func _read_instruments( stream:StreamPeerBuffer ) -> Array[ModInstrument]:
|
||||||
|
var instruments:Array[ModInstrument] = []
|
||||||
|
|
||||||
|
for i in range( 31 ):
|
||||||
|
var sample: = ModSample.new( )
|
||||||
|
sample.name = self._read_string( stream, 22 )
|
||||||
|
sample.length = stream.get_u16( ) * 2
|
||||||
|
var finetune:int = stream.get_u8( ) & 0x0F
|
||||||
|
if 0x08 < finetune:
|
||||||
|
finetune = finetune - 0x10
|
||||||
|
sample.finetune = finetune * 16
|
||||||
|
sample.volume = stream.get_u8( )
|
||||||
|
sample.loop_start = stream.get_u16( ) * 2
|
||||||
|
sample.loop_length = stream.get_u16( ) * 2
|
||||||
|
if sample.loop_length < 8:
|
||||||
|
sample.loop_type = ModLoopType.NO_LOOP
|
||||||
|
else:
|
||||||
|
sample.loop_type = ModLoopType.FORWARD_LOOP
|
||||||
|
|
||||||
|
var instrument: = ModInstrument.new( )
|
||||||
|
instrument.name = sample.name
|
||||||
|
instrument.samples = []
|
||||||
|
for k in range( 96 ):
|
||||||
|
instrument.samples.append( sample )
|
||||||
|
instrument.volume_envelope = ModEnvelope.new( )
|
||||||
|
instrument.volume_envelope.enabled = false
|
||||||
|
instrument.panning_envelope = ModEnvelope.new( )
|
||||||
|
instrument.panning_envelope.enabled = false
|
||||||
|
|
||||||
|
instruments.append( instrument )
|
||||||
|
|
||||||
|
return instruments
|
||||||
|
|
||||||
|
## パターンを読み込む
|
||||||
|
## @param stream ストリームデータ
|
||||||
|
## @param max_positions 最大パターン数
|
||||||
|
## @param channels 最大チャンネル数
|
||||||
|
## @return パターンデータ
|
||||||
|
func _read_patterns( stream:StreamPeerBuffer, max_position:int, channels:int ) -> Array: # Array of Array of Array of ModPatternNote
|
||||||
|
var patterns:Array = [] # Array of Array of Array of ModPatternNote
|
||||||
|
|
||||||
|
for position in ( max_position ):
|
||||||
|
var pattern:Array = [] # Array of Array of ModPatternNote
|
||||||
|
for i in range( 64 ):
|
||||||
|
var line:Array[ModPatternNote] = []
|
||||||
|
for ch in ( channels ):
|
||||||
|
var v1:int = stream.get_u16( )
|
||||||
|
var v2:int = stream.get_u16( )
|
||||||
|
var mod_pattern_note: = ModPatternNote.new( )
|
||||||
|
mod_pattern_note.instrument = ( ( v1 >> 8 ) & 0xF0 ) | ( ( v2 >> 12 ) & 0x0F )
|
||||||
|
mod_pattern_note.key_number = v1 & 0x0FFF
|
||||||
|
mod_pattern_note.effect_command = ( v2 >> 8 ) & 0x0F
|
||||||
|
mod_pattern_note.effect_param = v2 & 0x0FF
|
||||||
|
# TODO: 遅かったら二分探索にでもしませんか
|
||||||
|
if 0 < mod_pattern_note.key_number:
|
||||||
|
mod_pattern_note.note = 23
|
||||||
|
for k in period_table:
|
||||||
|
mod_pattern_note.note += 1
|
||||||
|
if k <= mod_pattern_note.key_number:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
mod_pattern_note.note = 0
|
||||||
|
line.append( mod_pattern_note )
|
||||||
|
pattern.append( line )
|
||||||
|
patterns.append( pattern )
|
||||||
|
|
||||||
|
return patterns
|
||||||
|
|
||||||
|
## 楽器のデータに基づき、波形を読み込む
|
||||||
|
## @param stream ストリーム
|
||||||
|
## @param instruments 波形を読み込む楽器データリスト
|
||||||
|
func _read_sample_data( stream:StreamPeerBuffer, instruments:Array[ModInstrument] ) -> void:
|
||||||
|
for instrument in instruments:
|
||||||
|
var sample:Mod.ModSample = instrument.samples[0]
|
||||||
|
if 0 < sample.length:
|
||||||
|
sample.data = stream.get_partial_data( sample.length )[1]
|
||||||
|
|
||||||
|
## 文字列の読み込み
|
||||||
|
## @param stream ストリーム
|
||||||
|
## @param size 文字列サイズ
|
||||||
|
## @return 読み込んだ文字列を返す
|
||||||
|
func _read_string( stream:StreamPeerBuffer, size:int ) -> String:
|
||||||
|
return stream.get_partial_data( size )[1].get_string_from_ascii( )
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://ii8p1hyx5nbe
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
uid://djgd6mugw2s47
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://x5sjwrimtdmi"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/modplayer/ModPlayer.gd" id="1"]
|
||||||
|
|
||||||
|
[node name="ModPlayer" type="Node"]
|
||||||
|
script = ExtResource("1")
|
||||||
@@ -0,0 +1,275 @@
|
|||||||
|
##
|
||||||
|
## XM parser by あるる(きのもと 結衣) @arlez80
|
||||||
|
##
|
||||||
|
## This script required Mod.gd for declaring the data structures.
|
||||||
|
##
|
||||||
|
## MIT License
|
||||||
|
##
|
||||||
|
|
||||||
|
@warning_ignore_start("untyped_declaration")
|
||||||
|
@warning_ignore_start("unsafe_method_access")
|
||||||
|
@warning_ignore_start("unused_variable")
|
||||||
|
@warning_ignore_start("int_as_enum_without_cast")
|
||||||
|
@warning_ignore_start("return_value_discarded")
|
||||||
|
|
||||||
|
class_name XM
|
||||||
|
|
||||||
|
enum XMNoteFlags {
|
||||||
|
NOTE = 0x01,
|
||||||
|
INSTRUMENT = 0x02,
|
||||||
|
VOLUME = 0x04,
|
||||||
|
EFFECT_COMMAND = 0x08,
|
||||||
|
EFFECT_PARAM = 0x10,
|
||||||
|
|
||||||
|
FIRST_BYTE_AS_FLAGS = 0x80,
|
||||||
|
}
|
||||||
|
|
||||||
|
## ファイルから読み込む
|
||||||
|
## @param path ファイルパス
|
||||||
|
## @return xm
|
||||||
|
func read_file( path:String ) -> Mod.ModParseResult:
|
||||||
|
var result: = Mod.ModParseResult.new( )
|
||||||
|
|
||||||
|
var f: = FileAccess.open( path, FileAccess.READ )
|
||||||
|
if f.get_error( ) != OK:
|
||||||
|
result.error = f.get_error( )
|
||||||
|
return result
|
||||||
|
|
||||||
|
var stream:StreamPeerBuffer = StreamPeerBuffer.new( )
|
||||||
|
stream.set_data_array( f.get_buffer( f.get_length( ) ) )
|
||||||
|
|
||||||
|
result.data = self._read( stream )
|
||||||
|
if result.data == null:
|
||||||
|
result.error = ERR_PARSE_ERROR
|
||||||
|
return result
|
||||||
|
|
||||||
|
## 配列から読み込む
|
||||||
|
## @param data データ
|
||||||
|
## @return xm
|
||||||
|
func read_data( data:PackedByteArray ) -> Mod.ModParseResult:
|
||||||
|
var stream:StreamPeerBuffer = StreamPeerBuffer.new( )
|
||||||
|
stream.set_data_array( data )
|
||||||
|
|
||||||
|
var result: = Mod.ModParseResult.new( )
|
||||||
|
result.data = self._read( stream )
|
||||||
|
if result.data == null:
|
||||||
|
result.error = ERR_PARSE_ERROR
|
||||||
|
return result
|
||||||
|
|
||||||
|
## ストリームから読み込み
|
||||||
|
## @param stream ストリーム
|
||||||
|
## @return xm
|
||||||
|
func _read( stream:StreamPeerBuffer ) -> Mod.ModData:
|
||||||
|
var xm: = Mod.ModData.new( )
|
||||||
|
|
||||||
|
if self._read_string( stream, 17 ) != "Extended Module: ":
|
||||||
|
return null
|
||||||
|
xm.module_name = self._read_string( stream, 20 )
|
||||||
|
if stream.get_u8( ) != 0x1A:
|
||||||
|
return null
|
||||||
|
xm.tracker_name = self._read_string( stream, 20 )
|
||||||
|
xm.version = stream.get_u16( )
|
||||||
|
|
||||||
|
var header_size:int = stream.get_u32( )
|
||||||
|
xm.song_length = stream.get_u16( )
|
||||||
|
xm.restart_position = stream.get_u16( )
|
||||||
|
xm.channel_count = stream.get_u16( )
|
||||||
|
|
||||||
|
var pattern_count:int = stream.get_u16( )
|
||||||
|
var instrument_count:int = stream.get_u16( )
|
||||||
|
xm.flags = stream.get_u16( )
|
||||||
|
xm.init_tick = stream.get_u16( )
|
||||||
|
xm.init_bpm = stream.get_u16( )
|
||||||
|
|
||||||
|
xm.song_positions = stream.get_partial_data( header_size - 20 )[1]
|
||||||
|
|
||||||
|
xm.patterns = self._read_patterns( stream, xm.flags, pattern_count, xm.channel_count )
|
||||||
|
if len( xm.patterns ) == 0:
|
||||||
|
return null
|
||||||
|
|
||||||
|
xm.instruments = self._read_instruments( stream, instrument_count )
|
||||||
|
if len( xm.instruments ) == 0:
|
||||||
|
return null
|
||||||
|
|
||||||
|
return xm
|
||||||
|
|
||||||
|
## パターン読み込み
|
||||||
|
## @param stream ストリーム
|
||||||
|
## @param xm_file_flags XMデータに関するフラグ
|
||||||
|
## @param pattern_count パターン数
|
||||||
|
## @param channles 最大チャンネル数
|
||||||
|
## @return パターンデータ
|
||||||
|
func _read_patterns( stream:StreamPeerBuffer, xm_file_flags:int, pattern_count:int, channels:int ) -> Array: # Array of Array of Array of ModPatternNote
|
||||||
|
var patterns:Array = [] # Array of Array of Array of ModPatternNote
|
||||||
|
|
||||||
|
for i in ( pattern_count ):
|
||||||
|
var pattern:Array = [] # Array of Array of ModPatternNote
|
||||||
|
|
||||||
|
if stream.get_u32( ) != 9:
|
||||||
|
return []
|
||||||
|
if stream.get_u8( ) != 0:
|
||||||
|
return []
|
||||||
|
var row_count:int = stream.get_u16( )
|
||||||
|
var size:int = stream.get_u16( )
|
||||||
|
for k in ( row_count ):
|
||||||
|
var line:Array[Mod.ModPatternNote] = []
|
||||||
|
for ch in ( channels ):
|
||||||
|
var patr: = Mod.ModPatternNote.new( )
|
||||||
|
if 0 < size:
|
||||||
|
var first:int = stream.get_u8( )
|
||||||
|
size -= 1
|
||||||
|
if first & XMNoteFlags.FIRST_BYTE_AS_FLAGS != 0:
|
||||||
|
if first & XMNoteFlags.NOTE != 0:
|
||||||
|
patr.note = stream.get_u8( )
|
||||||
|
size -= 1
|
||||||
|
else:
|
||||||
|
patr.note = first
|
||||||
|
first = 0xFF
|
||||||
|
if 0 < patr.note:
|
||||||
|
patr.note -= 1
|
||||||
|
if first & XMNoteFlags.INSTRUMENT != 0:
|
||||||
|
patr.instrument = stream.get_u8( )
|
||||||
|
size -= 1
|
||||||
|
if first & XMNoteFlags.VOLUME != 0:
|
||||||
|
patr.volume = stream.get_u8( )
|
||||||
|
size -= 1
|
||||||
|
if first & XMNoteFlags.EFFECT_COMMAND != 0:
|
||||||
|
patr.effect_command = stream.get_u8( )
|
||||||
|
size -= 1
|
||||||
|
if first & XMNoteFlags.EFFECT_PARAM != 0:
|
||||||
|
patr.effect_param = stream.get_u8( )
|
||||||
|
size -= 1
|
||||||
|
if 0 < patr.note:
|
||||||
|
if xm_file_flags & Mod.ModFlags.LINEAR_FREQUENCY_TABLE != 0:
|
||||||
|
patr.key_number = self._conv_linear_freq( patr.note )
|
||||||
|
else:
|
||||||
|
patr.key_number = self._conv_amiga_freq( patr.note )
|
||||||
|
line.append( patr )
|
||||||
|
pattern.append( line )
|
||||||
|
patterns.append( pattern )
|
||||||
|
|
||||||
|
return patterns
|
||||||
|
|
||||||
|
## ノート番号からAMIGA式で周波数計算する
|
||||||
|
## @param note ノート番号
|
||||||
|
## @return 周波数
|
||||||
|
func _conv_amiga_freq( note:int ) -> int:
|
||||||
|
return int( 6848.0 / pow( 2.0, note / 12.0 ) )
|
||||||
|
|
||||||
|
## ノート番号から線形で周波数計算する
|
||||||
|
## @param note ノート番号
|
||||||
|
## @return 周波数
|
||||||
|
func _conv_linear_freq( note:int ) -> int:
|
||||||
|
return 7680 - note * 64
|
||||||
|
|
||||||
|
## 楽器データを読み込む
|
||||||
|
## @param stream ストリーム
|
||||||
|
## @param instrument_count 楽器数
|
||||||
|
## @return 楽器データ
|
||||||
|
func _read_instruments( stream:StreamPeerBuffer, instrument_count:int ) -> Array[Mod.ModInstrument]:
|
||||||
|
var instruments:Array[Mod.ModInstrument] = []
|
||||||
|
|
||||||
|
for i in ( instrument_count ):
|
||||||
|
var inst: = Mod.ModInstrument.new( )
|
||||||
|
var size:int = stream.get_u32( )
|
||||||
|
var remain_size:int = size
|
||||||
|
inst.name = self._read_string( stream, 22 )
|
||||||
|
#print( "%d/%d %s" % [ i, instrument_count, inst.name] )
|
||||||
|
var instrument_type:int = stream.get_u8( )
|
||||||
|
if instrument_type != 0:
|
||||||
|
# 0以外のやつもいるらしいので無視
|
||||||
|
#return []
|
||||||
|
pass
|
||||||
|
|
||||||
|
var sample_count:int = stream.get_u16( )
|
||||||
|
var sample_numbers:Array = []
|
||||||
|
remain_size -= 4 + 22 + 1 + 2
|
||||||
|
if 0 < sample_count:
|
||||||
|
var sample_header_size:int = stream.get_u32( )
|
||||||
|
sample_numbers = stream.get_partial_data( 96 )[1]
|
||||||
|
inst.volume_envelope = Mod.ModEnvelope.new( )
|
||||||
|
for k in range( 12 ):
|
||||||
|
var ve: = Mod.ModEnvelopePoint.new( )
|
||||||
|
ve.frame = stream.get_u16( )
|
||||||
|
ve.value = stream.get_u16( )
|
||||||
|
inst.volume_envelope.points.append( ve )
|
||||||
|
inst.panning_envelope = Mod.ModEnvelope.new( )
|
||||||
|
for k in range( 12 ):
|
||||||
|
var pe: = Mod.ModEnvelopePoint.new( )
|
||||||
|
pe.frame = stream.get_u16( )
|
||||||
|
pe.value = stream.get_u16( )
|
||||||
|
inst.panning_envelope.points.append( pe )
|
||||||
|
remain_size -= 4 + 96 + 48 + 48
|
||||||
|
inst.volume_envelope.point_count = stream.get_u8( )
|
||||||
|
inst.panning_envelope.point_count = stream.get_u8( )
|
||||||
|
inst.volume_envelope.sustain_point = stream.get_u8( )
|
||||||
|
inst.volume_envelope.loop_start_point = stream.get_u8( )
|
||||||
|
inst.volume_envelope.loop_end_point = stream.get_u8( )
|
||||||
|
inst.panning_envelope.sustain_point = stream.get_u8( )
|
||||||
|
inst.panning_envelope.loop_start_point = stream.get_u8( )
|
||||||
|
inst.panning_envelope.loop_end_point = stream.get_u8( )
|
||||||
|
inst.volume_envelope.set_flag( stream.get_u8( ) )
|
||||||
|
inst.panning_envelope.set_flag( stream.get_u8( ) )
|
||||||
|
inst.vibrato_type = stream.get_u8( )
|
||||||
|
inst.vibrato_speed = stream.get_u8( )
|
||||||
|
inst.vibrato_depth = stream.get_u8( )
|
||||||
|
inst.vibrato_depth_shift = stream.get_u8( )
|
||||||
|
inst.volume_fadeout = stream.get_u16( )
|
||||||
|
remain_size -= 16
|
||||||
|
|
||||||
|
if 0 < remain_size:
|
||||||
|
stream.get_partial_data( remain_size ) # reserved
|
||||||
|
|
||||||
|
if 0 < sample_count:
|
||||||
|
var sounds:Array[Mod.ModSample] = []
|
||||||
|
# Sound Header
|
||||||
|
for k in ( sample_count ):
|
||||||
|
var xms: = Mod.ModSample.new( )
|
||||||
|
xms.length = stream.get_u32( )
|
||||||
|
xms.loop_start = stream.get_u32( )
|
||||||
|
xms.loop_length = stream.get_u32( )
|
||||||
|
xms.volume = stream.get_u8( )
|
||||||
|
xms.finetune = stream.get_8( )
|
||||||
|
xms.loop_type = stream.get_u8( )
|
||||||
|
if xms.loop_type & 16 != 0:
|
||||||
|
xms.bit = 16
|
||||||
|
xms.loop_type &= 3
|
||||||
|
xms.panning = stream.get_u8( )
|
||||||
|
xms.relative_note = stream.get_8( )
|
||||||
|
stream.get_u8( ) # Reserved
|
||||||
|
xms.name = self._read_string( stream, 22 )
|
||||||
|
sounds.append( xms )
|
||||||
|
# Sound Data
|
||||||
|
for xms in sounds:
|
||||||
|
var d:Array[int] = []
|
||||||
|
var p:int = 0
|
||||||
|
|
||||||
|
if xms.bit == 16:
|
||||||
|
for k in ( xms.length >> 1 ):
|
||||||
|
p += stream.get_16( )
|
||||||
|
d.append( p & 0xFF )
|
||||||
|
d.append( ( p >> 8 ) & 0xFF )
|
||||||
|
else:
|
||||||
|
for k in ( xms.length ):
|
||||||
|
p += stream.get_8( )
|
||||||
|
d.append( p & 0xFF )
|
||||||
|
|
||||||
|
xms.data = PackedByteArray( d )
|
||||||
|
|
||||||
|
inst.samples = []
|
||||||
|
for k in sample_numbers:
|
||||||
|
if len( sounds ) <= k:
|
||||||
|
inst.samples.append( sounds[0] )
|
||||||
|
else:
|
||||||
|
inst.samples.append( sounds[k] )
|
||||||
|
|
||||||
|
instruments.append( inst )
|
||||||
|
|
||||||
|
return instruments
|
||||||
|
|
||||||
|
## 文字列の読み込み
|
||||||
|
## @param stream ストリーム
|
||||||
|
## @param size 文字列サイズ
|
||||||
|
## @return 読み込んだ文字列を返す
|
||||||
|
func _read_string( stream:StreamPeerBuffer, size:int ) -> String:
|
||||||
|
return stream.get_partial_data( size )[1].get_string_from_ascii( )
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://cmuxvykwoxljq
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 924 B |
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://ba4eaiuaq67p"
|
||||||
|
path="res://.godot/imported/icon.png-1b6fd777bf08247b7c845db8b9125613.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://godot-mod-player-g4-master/addons/modplayer/icon.png"
|
||||||
|
dest_files=["res://.godot/imported/icon.png-1b6fd777bf08247b7c845db8b9125613.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[plugin]
|
||||||
|
name="Godot Mod Player"
|
||||||
|
description="A plugin that playing Mod Files for Godot Engine."
|
||||||
|
author="arlez80"
|
||||||
|
version="4.3.0"
|
||||||
|
script="GMP.gd"
|
||||||
+37
-4
@@ -32,25 +32,29 @@ func _prepare_polygons() -> void:
|
|||||||
var polys := Geometry2D.triangulate_delaunay(polygon)
|
var polys := Geometry2D.triangulate_delaunay(polygon)
|
||||||
var pickled := Array()
|
var pickled := Array()
|
||||||
for i in polys.size() / 3:
|
for i in polys.size() / 3:
|
||||||
pickled.push_front(PackedInt32Array([polys[i * 3 + 0], polys[i * 3 + 1], polys[i * 3 + 2]]))
|
pickled.push_back(PackedInt32Array([polys[i * 3 + 0], polys[i * 3 + 1], polys[i * 3 + 2]]))
|
||||||
polygons = pickled
|
polygons = pickled
|
||||||
_fix_acute_polygons()
|
_fix_polygons()
|
||||||
|
|
||||||
|
|
||||||
func _fix_acute_polygons() -> void:
|
func _fix_polygons() -> void:
|
||||||
# Outside triangles are in reversed winding, find and eliminate.
|
# Outside triangles are in reversed winding, find and eliminate.
|
||||||
var new := Array()
|
var new := Array()
|
||||||
for poly in polygons as Array[PackedInt32Array]:
|
for poly in polygons as Array[PackedInt32Array]:
|
||||||
var ab := polygon[poly[1]] - polygon[poly[0]]
|
var ab := polygon[poly[1]] - polygon[poly[0]]
|
||||||
var ac := polygon[poly[2]] - polygon[poly[0]]
|
var ac := polygon[poly[2]] - polygon[poly[0]]
|
||||||
if (ab.x * ac.y - ab.y * ac.x) * 0.5 <= 0:
|
if (ab.x * ac.y - ab.y * ac.x) * 0.5 <= 0:
|
||||||
new.push_front(poly)
|
# Fix winding as well.
|
||||||
|
new.push_back(PackedInt32Array([poly[2],poly[1],poly[0]]))
|
||||||
polygons = new
|
polygons = new
|
||||||
|
|
||||||
|
|
||||||
func _prepare_mesh() -> void:
|
func _prepare_mesh() -> void:
|
||||||
_prepare_floor_mesh()
|
_prepare_floor_mesh()
|
||||||
_prepare_wall_mesh()
|
_prepare_wall_mesh()
|
||||||
|
|
||||||
|
_prepare_floor_collision()
|
||||||
|
_prepare_wall_collision()
|
||||||
|
|
||||||
|
|
||||||
func _prepare_floor_mesh() -> void:
|
func _prepare_floor_mesh() -> void:
|
||||||
@@ -76,6 +80,7 @@ func _prepare_floor_mesh() -> void:
|
|||||||
_floor_mesh.mesh = m
|
_floor_mesh.mesh = m
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: Make last segment UV stretch to edge, tiling it.
|
||||||
func _prepare_wall_mesh() -> void:
|
func _prepare_wall_mesh() -> void:
|
||||||
var m := ImmediateMesh.new()
|
var m := ImmediateMesh.new()
|
||||||
m.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
|
m.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
|
||||||
@@ -121,3 +126,31 @@ func _prepare_wall_mesh() -> void:
|
|||||||
ndy = rng.randf_range(-1.0, 1.0)
|
ndy = rng.randf_range(-1.0, 1.0)
|
||||||
m.surface_end()
|
m.surface_end()
|
||||||
_wall_mesh.mesh = m
|
_wall_mesh.mesh = m
|
||||||
|
|
||||||
|
|
||||||
|
func _prepare_floor_collision() -> void:
|
||||||
|
if _floor_mesh.get_node_or_null("FloorMesh_col"):
|
||||||
|
_floor_mesh.remove_child(_floor_mesh.get_node("FloorMesh_col"))
|
||||||
|
_floor_mesh.create_convex_collision()
|
||||||
|
(_floor_mesh.get_node("FloorMesh_col") as StaticBody3D).set_collision_layer_value(2, 1)
|
||||||
|
|
||||||
|
|
||||||
|
func _prepare_wall_collision() -> void:
|
||||||
|
if _wall_mesh.get_node_or_null("WallMesh_col"):
|
||||||
|
_wall_mesh.remove_child(_wall_mesh.get_node("WallMesh_col"))
|
||||||
|
_wall_mesh.create_trimesh_collision()
|
||||||
|
_wall_mesh.get_node("WallMesh_col").get_node("CollisionShape3D").shape.backface_collision = true
|
||||||
|
(_wall_mesh.get_node("WallMesh_col") as StaticBody3D).set_collision_layer_value(3, 1)
|
||||||
|
#var shape := ConcavePolygonShape3D.new()
|
||||||
|
#shape.backface_collision = true
|
||||||
|
#var faces := PackedVector3Array()
|
||||||
|
#for ld in polygon.size():
|
||||||
|
#var nd := (ld + 1) % polygon.size()
|
||||||
|
#faces.push_back(Vector3(polygon[ld].x * _scale, 0, polygon[ld].y * _scale))
|
||||||
|
#faces.push_back(Vector3(polygon[nd].x * _scale, 0, polygon[nd].y * _scale))
|
||||||
|
#faces.push_back(Vector3(polygon[ld].x * _scale, 5, polygon[ld].y * _scale))
|
||||||
|
#faces.push_back(Vector3(polygon[nd].x * _scale, 0, polygon[nd].y * _scale))
|
||||||
|
#faces.push_back(Vector3(polygon[nd].x * _scale, 5, polygon[nd].y * _scale))
|
||||||
|
#faces.push_back(Vector3(polygon[ld].x * _scale, 5, polygon[ld].y * _scale))
|
||||||
|
#shape.set_faces(faces)
|
||||||
|
#(_wall_mesh.get_node("Area3D").get_node("CollisionShape3D") as CollisionShape3D).shape = shape
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
extends Node3D
|
||||||
|
|
||||||
|
var _rotation_target_x : Vector3
|
||||||
|
var _rotation_target_y : Vector3
|
||||||
|
@export var _cam : Camera3D
|
||||||
|
@export var _ray : RayCast3D
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
_rotation_target_y = self.rotation
|
||||||
|
_rotation_target_x = _cam.rotation
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: Interpolation.
|
||||||
|
# TODO: Hiding/Popping animation.
|
||||||
|
func _physics_process(_delta: float) -> void:
|
||||||
|
var wmark := get_parent_node_3d().get_node("WallMark") as Sprite3D
|
||||||
|
var fmark := get_parent_node_3d().get_node("FloorMark") as Sprite3D
|
||||||
|
# Walls.
|
||||||
|
if _ray.is_colliding() and (_ray.get_collider() as StaticBody3D).get_collision_layer_value(3):
|
||||||
|
var normflat := Vector3(_ray.get_collision_normal().x, 0, _ray.get_collision_normal().z)
|
||||||
|
var posflat := Vector3(_ray.get_collision_point().x, 0, _ray.get_collision_point().z)
|
||||||
|
wmark.look_at_from_position(posflat, posflat + normflat, Vector3.UP)
|
||||||
|
wmark.position = posflat + normflat
|
||||||
|
wmark.show()
|
||||||
|
else:
|
||||||
|
wmark.hide()
|
||||||
|
|
||||||
|
# Floor.
|
||||||
|
if _ray.is_colliding() and (_ray.get_collider() as StaticBody3D).get_collision_layer_value(2):
|
||||||
|
var posflat := Vector3(_ray.get_collision_point().x, 0, _ray.get_collision_point().z)
|
||||||
|
fmark.position = posflat
|
||||||
|
fmark.show()
|
||||||
|
else:
|
||||||
|
fmark.hide()
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
self.rotation.y = lerp_angle(_rotation_target_y.y, _rotation_target_y.y, 1.0 - exp(-30 * delta))
|
||||||
|
_cam.rotation.x = lerp_angle(_cam.rotation.x, _rotation_target_x.x, 1.0 - exp(-20 * delta))
|
||||||
|
|
||||||
|
|
||||||
|
func _input(event: InputEvent) -> void:
|
||||||
|
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
||||||
|
var motion := event as InputEventMouseMotion
|
||||||
|
var preserve := rotation
|
||||||
|
rotation = _rotation_target_y
|
||||||
|
self.rotate_y(deg_to_rad(motion.relative.x) * -0.25)
|
||||||
|
_rotation_target_y = rotation
|
||||||
|
rotation = preserve
|
||||||
|
|
||||||
|
preserve = _cam.rotation
|
||||||
|
_cam.rotate_x(deg_to_rad(motion.relative.y) * -0.2)
|
||||||
|
var camera_rot := _cam.rotation_degrees
|
||||||
|
camera_rot.x = clamp(camera_rot.x, -30, 30)
|
||||||
|
_cam.rotation_degrees = camera_rot
|
||||||
|
_rotation_target_x = _cam.rotation
|
||||||
|
_cam.rotation = preserve
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dtqv683r772sd
|
||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,41 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cqisk1m0in4a4"
|
||||||
|
path.s3tc="res://.godot/imported/shield.png-bdf8e401b772eb7c90cb1fa4b7e06cd1.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://shield.png"
|
||||||
|
dest_files=["res://.godot/imported/shield.png-bdf8e401b772eb7c90cb1fa4b7e06cd1.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
@tool
|
||||||
|
extends Line2D
|
||||||
|
|
||||||
|
|
||||||
|
var _id : int
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://cc2rv3wnwas52
|
||||||
Reference in New Issue
Block a user