ajout d'un ecran de chargement.
This commit is contained in:
parent
52bcbe10b9
commit
a9ed135b1b
11 changed files with 249 additions and 27 deletions
BIN
assets/GUI/loading_screens/new_loading_bg_0.tga
Normal file
BIN
assets/GUI/loading_screens/new_loading_bg_0.tga
Normal file
Binary file not shown.
BIN
assets/GUI/loading_screens/new_loading_bg_1.tga
Normal file
BIN
assets/GUI/loading_screens/new_loading_bg_1.tga
Normal file
Binary file not shown.
BIN
assets/GUI/loading_screens/new_loading_bg_test.tga
Normal file
BIN
assets/GUI/loading_screens/new_loading_bg_test.tga
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 MiB |
|
@ -17,6 +17,7 @@ func _on_character_creation_menu_valid_button_pressed():
|
||||||
|
|
||||||
func _on_character_selection_menu_character_selected(slot):
|
func _on_character_selection_menu_character_selected(slot):
|
||||||
print( "selected character slot "+str( slot )+"." )
|
print( "selected character slot "+str( slot )+"." )
|
||||||
|
global.character_slot = slot
|
||||||
$character_selection_menu.hide()
|
$character_selection_menu.hide()
|
||||||
$character_creation_menu.show()
|
$character_creation_menu.show()
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,6 @@ _sections_unfolded = [ "Mouse", "Size Flags", "Theme", "Visibility", "custom_sty
|
||||||
|
|
||||||
[node name="Test" type="MarginContainer" parent="Windows" index="0"]
|
[node name="Test" type="MarginContainer" parent="Windows" index="0"]
|
||||||
|
|
||||||
editor/display_folded = true
|
|
||||||
anchor_left = 0.0
|
anchor_left = 0.0
|
||||||
anchor_top = 0.0
|
anchor_top = 0.0
|
||||||
anchor_right = 0.0
|
anchor_right = 0.0
|
||||||
|
|
|
@ -14,10 +14,15 @@ func _ready():
|
||||||
# pass
|
# pass
|
||||||
|
|
||||||
|
|
||||||
func _on_slot0_character_button_pressed():
|
|
||||||
emit_signal( "character_selected", 0 )
|
|
||||||
|
|
||||||
|
|
||||||
func _on_return_button_pressed():
|
func _on_return_button_pressed():
|
||||||
emit_signal( "return_button_pressed" )
|
emit_signal( "return_button_pressed" )
|
||||||
|
|
||||||
|
func _on_slot0_character_button_pressed():
|
||||||
|
emit_signal( "character_selected", 0 )
|
||||||
|
func _on_slot1_character_button_pressed():
|
||||||
|
emit_signal( "character_selected", 1 )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,20 +66,45 @@ size_flags_horizontal = 1
|
||||||
size_flags_vertical = 1
|
size_flags_vertical = 1
|
||||||
alignment = 0
|
alignment = 0
|
||||||
|
|
||||||
[node name="slot0_box" type="HBoxContainer" parent="h_box_container/character_slots" index="0"]
|
[node name="return_button" type="Button" parent="h_box_container/character_slots" index="0"]
|
||||||
|
|
||||||
anchor_left = 0.0
|
anchor_left = 0.0
|
||||||
anchor_top = 0.0
|
anchor_top = 0.0
|
||||||
anchor_right = 0.0
|
anchor_right = 0.0
|
||||||
anchor_bottom = 0.0
|
anchor_bottom = 0.0
|
||||||
|
margin_right = 54.0
|
||||||
|
margin_bottom = 20.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
focus_mode = 2
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 2
|
||||||
|
size_flags_vertical = 2
|
||||||
|
toggle_mode = false
|
||||||
|
enabled_focus_mode = 2
|
||||||
|
shortcut = null
|
||||||
|
group = null
|
||||||
|
text = "Retour"
|
||||||
|
flat = false
|
||||||
|
align = 1
|
||||||
|
_sections_unfolded = [ "Size Flags" ]
|
||||||
|
|
||||||
|
[node name="slot0_box" type="HBoxContainer" parent="h_box_container/character_slots" index="1"]
|
||||||
|
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_top = 201.0
|
||||||
margin_right = 342.0
|
margin_right = 342.0
|
||||||
margin_bottom = 128.0
|
margin_bottom = 329.0
|
||||||
rect_pivot_offset = Vector2( 0, 0 )
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
rect_clip_content = false
|
rect_clip_content = false
|
||||||
mouse_filter = 1
|
mouse_filter = 1
|
||||||
mouse_default_cursor_shape = 0
|
mouse_default_cursor_shape = 0
|
||||||
size_flags_horizontal = 1
|
size_flags_horizontal = 1
|
||||||
size_flags_vertical = 1
|
size_flags_vertical = 2
|
||||||
custom_constants/separation = 8
|
custom_constants/separation = 8
|
||||||
alignment = 0
|
alignment = 0
|
||||||
_sections_unfolded = [ "Size Flags", "custom_constants" ]
|
_sections_unfolded = [ "Size Flags", "custom_constants" ]
|
||||||
|
@ -133,28 +158,71 @@ flat = true
|
||||||
align = 1
|
align = 1
|
||||||
_sections_unfolded = [ "Size Flags" ]
|
_sections_unfolded = [ "Size Flags" ]
|
||||||
|
|
||||||
[node name="return_button" type="Button" parent="h_box_container/character_slots" index="1"]
|
[node name="slot1_box" type="HBoxContainer" parent="h_box_container/character_slots" index="2"]
|
||||||
|
|
||||||
anchor_left = 0.0
|
anchor_left = 0.0
|
||||||
anchor_top = 0.0
|
anchor_top = 0.0
|
||||||
anchor_right = 0.0
|
anchor_right = 0.0
|
||||||
anchor_bottom = 0.0
|
anchor_bottom = 0.0
|
||||||
margin_top = 580.0
|
margin_top = 402.0
|
||||||
margin_right = 54.0
|
margin_right = 342.0
|
||||||
margin_bottom = 600.0
|
margin_bottom = 530.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 1
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 2
|
||||||
|
custom_constants/separation = 8
|
||||||
|
alignment = 0
|
||||||
|
_sections_unfolded = [ "Size Flags", "custom_constants" ]
|
||||||
|
|
||||||
|
[node name="character_button" type="TextureButton" parent="h_box_container/character_slots/slot1_box" index="0"]
|
||||||
|
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_right = 128.0
|
||||||
|
margin_bottom = 128.0
|
||||||
|
rect_min_size = Vector2( 128, 128 )
|
||||||
rect_pivot_offset = Vector2( 0, 0 )
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
rect_clip_content = false
|
rect_clip_content = false
|
||||||
focus_mode = 2
|
focus_mode = 2
|
||||||
mouse_filter = 0
|
mouse_filter = 0
|
||||||
mouse_default_cursor_shape = 0
|
mouse_default_cursor_shape = 0
|
||||||
size_flags_horizontal = 2
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 10
|
size_flags_vertical = 1
|
||||||
toggle_mode = false
|
toggle_mode = false
|
||||||
enabled_focus_mode = 2
|
enabled_focus_mode = 2
|
||||||
shortcut = null
|
shortcut = null
|
||||||
group = null
|
group = null
|
||||||
text = "Retour"
|
texture_normal = ExtResource( 3 )
|
||||||
flat = false
|
_sections_unfolded = [ "Rect", "Size Flags", "Textures" ]
|
||||||
|
|
||||||
|
[node name="character_name" type="Button" parent="h_box_container/character_slots/slot1_box" index="1"]
|
||||||
|
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_left = 136.0
|
||||||
|
margin_top = 54.0
|
||||||
|
margin_right = 342.0
|
||||||
|
margin_bottom = 74.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
focus_mode = 2
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 4
|
||||||
|
toggle_mode = false
|
||||||
|
enabled_focus_mode = 2
|
||||||
|
shortcut = null
|
||||||
|
group = null
|
||||||
|
text = "Créer un nouveau personnage."
|
||||||
|
flat = true
|
||||||
align = 1
|
align = 1
|
||||||
_sections_unfolded = [ "Size Flags" ]
|
_sections_unfolded = [ "Size Flags" ]
|
||||||
|
|
||||||
|
@ -175,10 +243,14 @@ size_flags_horizontal = 3
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
_sections_unfolded = [ "Size Flags" ]
|
_sections_unfolded = [ "Size Flags" ]
|
||||||
|
|
||||||
|
[connection signal="pressed" from="h_box_container/character_slots/return_button" to="." method="_on_return_button_pressed"]
|
||||||
|
|
||||||
[connection signal="pressed" from="h_box_container/character_slots/slot0_box/character_button" to="." method="_on_slot0_character_button_pressed"]
|
[connection signal="pressed" from="h_box_container/character_slots/slot0_box/character_button" to="." method="_on_slot0_character_button_pressed"]
|
||||||
|
|
||||||
[connection signal="pressed" from="h_box_container/character_slots/slot0_box/character_name" to="." method="_on_slot0_character_button_pressed"]
|
[connection signal="pressed" from="h_box_container/character_slots/slot0_box/character_name" to="." method="_on_slot0_character_button_pressed"]
|
||||||
|
|
||||||
[connection signal="pressed" from="h_box_container/character_slots/return_button" to="." method="_on_return_button_pressed"]
|
[connection signal="pressed" from="h_box_container/character_slots/slot1_box/character_button" to="." method="_on_slot1_character_button_pressed"]
|
||||||
|
|
||||||
|
[connection signal="pressed" from="h_box_container/character_slots/slot1_box/character_name" to="." method="_on_slot1_character_button_pressed"]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ uv2_triplanar_sharpness = 1.0
|
||||||
proximity_fade_enable = false
|
proximity_fade_enable = false
|
||||||
distance_fade_enable = false
|
distance_fade_enable = false
|
||||||
|
|
||||||
[node name="Character" type="KinematicBody" index="0"]
|
[node name="Character" type="KinematicBody"]
|
||||||
|
|
||||||
transform = Transform( 1, 0, 0, 0, 0.589355, 0, 0, 0, 1, -0.0409546, 1.06519, 6.02408 )
|
transform = Transform( 1, 0, 0, 0, 0.589355, 0, 0, 0, 1, -0.0409546, 1.06519, 6.02408 )
|
||||||
input_ray_pickable = true
|
input_ray_pickable = true
|
||||||
|
|
|
@ -38,5 +38,5 @@ func change_title():
|
||||||
# $Game/Character/MeshInstance.get_surface_material(0).albedo_color = $GUI/character_creation_menu/v_box_container/h_box_container/center_container/character_creation_scene/mesh_instance.get_surface_material(0).albedo_color
|
# $Game/Character/MeshInstance.get_surface_material(0).albedo_color = $GUI/character_creation_menu/v_box_container/h_box_container/center_container/character_creation_scene/mesh_instance.get_surface_material(0).albedo_color
|
||||||
|
|
||||||
func _on_login_scene_character_creation_finished():
|
func _on_login_scene_character_creation_finished():
|
||||||
global.goto_scene( "res://game_scene/game_scene.tscn", "Main" )
|
global.goto_scene_loading( "res://game_scene/game_scene.tscn" )
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,92 @@
|
||||||
[gd_scene load_steps=3 format=2]
|
[gd_scene load_steps=4 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://scenes/Main.gd" type="Script" id=1]
|
[ext_resource path="res://scenes/Main.gd" type="Script" id=1]
|
||||||
[ext_resource path="res://login_scene/login_scene.tscn" type="PackedScene" id=2]
|
[ext_resource path="res://login_scene/login_scene.tscn" type="PackedScene" id=2]
|
||||||
|
[ext_resource path="res://assets/GUI/loading_screens/new_loading_bg_test.tga" type="Texture" id=3]
|
||||||
|
|
||||||
[node name="Main" type="Node"]
|
[node name="Main" type="Node" index="0"]
|
||||||
|
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
||||||
_sections_unfolded = [ "Pause" ]
|
_sections_unfolded = [ "Pause" ]
|
||||||
|
|
||||||
[node name="login_scene" parent="." index="0" instance=ExtResource( 2 )]
|
[node name="login_scene" parent="." index="0" instance=ExtResource( 2 )]
|
||||||
|
|
||||||
|
[node name="background_loader" type="Panel" parent="." index="1"]
|
||||||
|
|
||||||
|
visible = false
|
||||||
|
self_modulate = Color( 0, 0, 0, 1 )
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
_sections_unfolded = [ "Mouse", "Visibility", "custom_constants" ]
|
||||||
|
|
||||||
|
[node name="center_container" type="MarginContainer" parent="background_loader" index="0"]
|
||||||
|
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
|
||||||
|
[node name="texture_rect" type="TextureRect" parent="background_loader/center_container" index="0"]
|
||||||
|
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_left = 8.0
|
||||||
|
margin_right = 1024.0
|
||||||
|
margin_bottom = 600.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 1
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 5
|
||||||
|
size_flags_vertical = 5
|
||||||
|
texture = ExtResource( 3 )
|
||||||
|
expand = true
|
||||||
|
stretch_mode = 7
|
||||||
|
_sections_unfolded = [ "Rect", "Size Flags" ]
|
||||||
|
|
||||||
|
[node name="progress_bar" type="ProgressBar" parent="background_loader/center_container" index="1"]
|
||||||
|
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_left = 388.0
|
||||||
|
margin_top = 584.0
|
||||||
|
margin_right = 644.0
|
||||||
|
margin_bottom = 600.0
|
||||||
|
rect_min_size = Vector2( 256, 0 )
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 6
|
||||||
|
size_flags_vertical = 10
|
||||||
|
min_value = 0.0
|
||||||
|
max_value = 100.0
|
||||||
|
step = 1.0
|
||||||
|
page = 0.0
|
||||||
|
value = 0.0
|
||||||
|
exp_edit = false
|
||||||
|
rounded = true
|
||||||
|
percent_visible = true
|
||||||
|
_sections_unfolded = [ "Margin", "Rect", "Size Flags" ]
|
||||||
|
|
||||||
[connection signal="character_creation_finished" from="login_scene" to="." method="_on_login_scene_character_creation_finished"]
|
[connection signal="character_creation_finished" from="login_scene" to="." method="_on_login_scene_character_creation_finished"]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,16 @@ var character_camera = null
|
||||||
var character_creation_mesh = null
|
var character_creation_mesh = null
|
||||||
var character_creation_camera = null
|
var character_creation_camera = null
|
||||||
|
|
||||||
var player_name
|
var player_name = null
|
||||||
var player_color
|
var player_color = null
|
||||||
|
var character_slot = null
|
||||||
|
|
||||||
|
# BG loader
|
||||||
|
var loader
|
||||||
|
var wait_frames
|
||||||
|
var time_max = 100 # msec
|
||||||
|
#var current_scene
|
||||||
|
var main_scene = null
|
||||||
func _ready():
|
func _ready():
|
||||||
var root = get_tree().get_root()
|
var root = get_tree().get_root()
|
||||||
# current_scene = root.get_child(root.get_child_count() -1)
|
# current_scene = root.get_child(root.get_child_count() -1)
|
||||||
|
@ -16,8 +23,69 @@ func _ready():
|
||||||
# character = get_tree().get_root().get_node( "Main/Game/Character" )
|
# character = get_tree().get_root().get_node( "Main/Game/Character" )
|
||||||
# character_camera = get_tree().get_root().get_node( "Main/Game/Character/Camera_rotation_helper/Camera" )
|
# character_camera = get_tree().get_root().get_node( "Main/Game/Character/Camera_rotation_helper/Camera" )
|
||||||
# character_creation_camera = get_tree().get_root().get_node( "Main/login_scene/character_creation_menu/v_box_container/h_box_container/center_container/character_creation_scene/camera" )
|
# character_creation_camera = get_tree().get_root().get_node( "Main/login_scene/character_creation_menu/v_box_container/h_box_container/center_container/character_creation_scene/camera" )
|
||||||
|
main_scene = root.get_node( "Main" )
|
||||||
|
|
||||||
func goto_scene(path, parent):
|
func goto_scene_loading( path ):
|
||||||
|
get_tree().get_root().get_node("Main/background_loader").show()
|
||||||
|
loader = ResourceLoader.load_interactive( path )
|
||||||
|
if loader == null: # check for errors
|
||||||
|
show_error()
|
||||||
|
return
|
||||||
|
set_process(true)
|
||||||
|
|
||||||
|
current_scene.queue_free() # get rid of the old scene
|
||||||
|
|
||||||
|
# start your "loading..." animation
|
||||||
|
# get_node("animation").play("loading")
|
||||||
|
|
||||||
|
wait_frames = 1
|
||||||
|
|
||||||
|
func _process(time):
|
||||||
|
if loader == null:
|
||||||
|
# no need to process anymore
|
||||||
|
set_process(false)
|
||||||
|
return
|
||||||
|
|
||||||
|
if wait_frames > 0: # wait for frames to let the "loading" animation to show up
|
||||||
|
wait_frames -= 1
|
||||||
|
return
|
||||||
|
|
||||||
|
var t = OS.get_ticks_msec()
|
||||||
|
while OS.get_ticks_msec() < t + time_max: # use "time_max" to control how much time we block this thread
|
||||||
|
|
||||||
|
# poll your loader
|
||||||
|
var err = loader.poll()
|
||||||
|
|
||||||
|
if err == ERR_FILE_EOF: # load finished
|
||||||
|
var resource = loader.get_resource()
|
||||||
|
loader = null
|
||||||
|
set_new_scene( resource )
|
||||||
|
break
|
||||||
|
elif err == OK:
|
||||||
|
update_progress()
|
||||||
|
else: # error during loading
|
||||||
|
show_error()
|
||||||
|
loader = null
|
||||||
|
break
|
||||||
|
|
||||||
|
func update_progress():
|
||||||
|
print("test: "+str(loader.get_stage())+" / "+str(loader.get_stage_count()) )
|
||||||
|
var progress = int( (float(loader.get_stage()) / loader.get_stage_count()) *100 )
|
||||||
|
# update your progress bar?
|
||||||
|
get_tree().get_root().get_node("Main/background_loader/center_container/progress_bar").value = progress
|
||||||
|
|
||||||
|
|
||||||
|
# or update a progress animation?
|
||||||
|
# var len = get_node("animation").get_current_animation_length()
|
||||||
|
# call this on a paused animation. use "true" as the second parameter to force the animation to update
|
||||||
|
# get_node("animation").seek(progress * len, true)
|
||||||
|
|
||||||
|
func set_new_scene( scene_resource ):
|
||||||
|
get_tree().get_root().get_node("Main/background_loader").hide()
|
||||||
|
current_scene = scene_resource.instance()
|
||||||
|
main_scene.add_child(current_scene)
|
||||||
|
|
||||||
|
func goto_scene( path ):
|
||||||
# This function will usually be called from a signal callback,
|
# This function will usually be called from a signal callback,
|
||||||
# or some other function from the running scene.
|
# or some other function from the running scene.
|
||||||
# Deleting the current scene at this point might be
|
# Deleting the current scene at this point might be
|
||||||
|
@ -27,10 +95,10 @@ func goto_scene(path, parent):
|
||||||
# The way around this is deferring the load to a later time, when
|
# The way around this is deferring the load to a later time, when
|
||||||
# it is ensured that no code from the current scene is running:
|
# it is ensured that no code from the current scene is running:
|
||||||
|
|
||||||
call_deferred("_deferred_goto_scene", path, parent)
|
call_deferred("_deferred_goto_scene", path)
|
||||||
|
|
||||||
|
|
||||||
func _deferred_goto_scene(path, parent):
|
func _deferred_goto_scene( path ):
|
||||||
# Immediately free the current scene,
|
# Immediately free the current scene,
|
||||||
# there is no risk here.
|
# there is no risk here.
|
||||||
current_scene.free()
|
current_scene.free()
|
||||||
|
@ -42,7 +110,7 @@ func _deferred_goto_scene(path, parent):
|
||||||
current_scene = s.instance()
|
current_scene = s.instance()
|
||||||
|
|
||||||
# Add it to the active scene, as child of root.
|
# Add it to the active scene, as child of root.
|
||||||
get_tree().get_root().get_node( parent ).add_child( current_scene )
|
path.add_child( current_scene )
|
||||||
|
|
||||||
# Optional, to make it compatible with the SceneTree.change_scene() API.
|
# Optional, to make it compatible with the SceneTree.change_scene() API.
|
||||||
get_tree().set_current_scene( current_scene )
|
get_tree().set_current_scene( current_scene )
|
Loading…
Reference in a new issue