├── .gitattributes ├── icon.png ├── Down Hill.ttf ├── Persistent_nodes.tscn ├── Tilesheet.png ├── Characters.png ├── Bullet_texture.png ├── misc └── finished-game.gif ├── UI.gd ├── .gitignore ├── Simple_prompt.gd ├── default_env.tres ├── Server_display.gd ├── Server_listener.tscn ├── Server_advertiser.tscn ├── Winner.gd ├── Base_font.tres ├── Username_text.gd ├── Game_UI.gd ├── Global.gd ├── Camera2D.gd ├── Username_text.tscn ├── icon.png.import ├── Tilesheet.png.import ├── Characters.png.import ├── Bullet_texture.png.import ├── Player_bullet.tscn ├── README.md ├── Server_display.tscn ├── Server_advertiser.gd ├── Game.gd ├── Player_bullet.gd ├── Server_browser.gd ├── Simple_prompt.tscn ├── Player.tscn ├── Server_listener.gd ├── Network_setup.tscn ├── Network_setup.gd ├── Network.gd ├── project.godot ├── Server_browser.tscn ├── Player.gd ├── export_presets.cfg └── Game.tscn /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelamanWarrior/Godot-Multiplayer-Shooter/HEAD/icon.png -------------------------------------------------------------------------------- /Down Hill.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelamanWarrior/Godot-Multiplayer-Shooter/HEAD/Down Hill.ttf -------------------------------------------------------------------------------- /Persistent_nodes.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene format=2] 2 | 3 | [node name="Persistent_nodes" type="Node"] 4 | -------------------------------------------------------------------------------- /Tilesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelamanWarrior/Godot-Multiplayer-Shooter/HEAD/Tilesheet.png -------------------------------------------------------------------------------- /Characters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelamanWarrior/Godot-Multiplayer-Shooter/HEAD/Characters.png -------------------------------------------------------------------------------- /Bullet_texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelamanWarrior/Godot-Multiplayer-Shooter/HEAD/Bullet_texture.png -------------------------------------------------------------------------------- /misc/finished-game.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelamanWarrior/Godot-Multiplayer-Shooter/HEAD/misc/finished-game.gif -------------------------------------------------------------------------------- /UI.gd: -------------------------------------------------------------------------------- 1 | extends CanvasLayer 2 | 3 | func _ready() -> void: 4 | Global.ui = self 5 | 6 | func _exit_tree() -> void: 7 | Global.ui = null 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Godot-specific ignores 3 | .import/ 4 | export.cfg 5 | export_presets.cfg 6 | 7 | # Mono-specific ignores 8 | .mono/ 9 | data_*/ 10 | -------------------------------------------------------------------------------- /Simple_prompt.gd: -------------------------------------------------------------------------------- 1 | extends Control 2 | 3 | func _on_Ok_pressed(): 4 | get_tree().change_scene("res://Network_setup.tscn") 5 | 6 | func set_text(text) -> void: 7 | $Label.text = text 8 | -------------------------------------------------------------------------------- /default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="ProceduralSky" id=1] 4 | 5 | [resource] 6 | background_mode = 2 7 | background_sky = SubResource( 1 ) 8 | -------------------------------------------------------------------------------- /Server_display.gd: -------------------------------------------------------------------------------- 1 | extends Label 2 | 3 | var ip_address = "" 4 | 5 | func _on_Join_button_pressed(): 6 | Network.ip_address = ip_address 7 | Network.join_server() 8 | get_parent().get_parent().queue_free() 9 | -------------------------------------------------------------------------------- /Server_listener.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://Server_listener.gd" type="Script" id=1] 4 | 5 | [node name="Server_listener" type="Node"] 6 | script = ExtResource( 1 ) 7 | -------------------------------------------------------------------------------- /Server_advertiser.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://Server_advertiser.gd" type="Script" id=1] 4 | 5 | [node name="Server_advertiser" type="Node"] 6 | script = ExtResource( 1 ) 7 | -------------------------------------------------------------------------------- /Winner.gd: -------------------------------------------------------------------------------- 1 | extends Label 2 | 3 | sync func return_to_lobby(): 4 | get_tree().change_scene("res://Network_setup.tscn") 5 | 6 | func _on_Win_timer_timeout(): 7 | if get_tree().is_network_server(): 8 | rpc("return_to_lobby") 9 | -------------------------------------------------------------------------------- /Base_font.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFont" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://Down Hill.ttf" type="DynamicFontData" id=1] 4 | 5 | [resource] 6 | size = 64 7 | use_mipmaps = true 8 | use_filter = true 9 | font_data = ExtResource( 1 ) 10 | -------------------------------------------------------------------------------- /Username_text.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | var player_following = null 4 | var text = "" setget text_set 5 | 6 | onready var label = $Label 7 | 8 | func _process(_delta: float) -> void: 9 | if player_following != null: 10 | global_position = player_following.global_position 11 | 12 | func text_set(new_text) -> void: 13 | text = new_text 14 | label.text = text 15 | -------------------------------------------------------------------------------- /Game_UI.gd: -------------------------------------------------------------------------------- 1 | extends CanvasLayer 2 | 3 | onready var win_timer = $Control/Winner/Win_timer 4 | onready var winner = $Control/Winner 5 | 6 | func _ready() -> void: 7 | winner.hide() 8 | 9 | func _process(_delta: float) -> void: 10 | if Global.alive_players.size() == 1 and get_tree().has_network_peer(): 11 | if Global.alive_players[0].name == str(get_tree().get_network_unique_id()): 12 | winner.show() 13 | 14 | if win_timer.time_left <= 0: 15 | win_timer.start() 16 | -------------------------------------------------------------------------------- /Global.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | var player_master = null 4 | var ui = null 5 | 6 | var alive_players = [] 7 | 8 | func instance_node_at_location(node: Object, parent: Object, location: Vector2) -> Object: 9 | var node_instance = instance_node(node, parent) 10 | node_instance.global_position = location 11 | return node_instance 12 | 13 | func instance_node(node: Object, parent: Object) -> Object: 14 | var node_instance = node.instance() 15 | parent.add_child(node_instance) 16 | return node_instance 17 | -------------------------------------------------------------------------------- /Camera2D.gd: -------------------------------------------------------------------------------- 1 | extends Camera2D 2 | 3 | var target_player = null 4 | 5 | func _process(delta: float) -> void: 6 | if Global.player_master != null: 7 | global_position = lerp(global_position, Global.player_master.global_position, delta * 10) 8 | else: 9 | if Global.alive_players.size() >= 1: 10 | if target_player == null: 11 | target_player = Global.alive_players[round(rand_range(0, Global.alive_players.size() - 1))] 12 | else: 13 | global_position = lerp(global_position, target_player.global_position, delta * 10) 14 | -------------------------------------------------------------------------------- /Username_text.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://Username_text.gd" type="Script" id=1] 4 | [ext_resource path="res://Base_font.tres" type="DynamicFont" id=2] 5 | 6 | [node name="Username_text" type="Node2D" groups=[ 7 | "Net", 8 | ]] 9 | z_index = 5 10 | script = ExtResource( 1 ) 11 | 12 | [node name="Label" type="Label" parent="."] 13 | margin_left = -197.0 14 | margin_top = -125.0 15 | margin_right = 197.0 16 | margin_bottom = -87.0 17 | custom_fonts/font = ExtResource( 2 ) 18 | text = "null" 19 | align = 1 20 | valign = 1 21 | __meta__ = { 22 | "_edit_use_anchors_": false 23 | } 24 | -------------------------------------------------------------------------------- /icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://icon.png" 13 | dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /Tilesheet.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/Tilesheet.png-bcf2b7907222dd458d826fd52a279a46.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://Tilesheet.png" 13 | dest_files=[ "res://.import/Tilesheet.png-bcf2b7907222dd458d826fd52a279a46.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=true 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /Characters.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/Characters.png-88d61f11b026c46e349cac528f4324fe.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://Characters.png" 13 | dest_files=[ "res://.import/Characters.png-88d61f11b026c46e349cac528f4324fe.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=true 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /Bullet_texture.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/Bullet_texture.png-16d5036bcb8e640d98680e841bc524a3.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://Bullet_texture.png" 13 | dest_files=[ "res://.import/Bullet_texture.png-16d5036bcb8e640d98680e841bc524a3.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=true 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /Player_bullet.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://Player_bullet.gd" type="Script" id=1] 4 | [ext_resource path="res://Bullet_texture.png" type="Texture" id=2] 5 | 6 | [sub_resource type="RectangleShape2D" id=1] 7 | extents = Vector2( 28, 12 ) 8 | 9 | [node name="Player_bullet" type="Sprite" groups=[ 10 | "Net", 11 | ]] 12 | texture = ExtResource( 2 ) 13 | script = ExtResource( 1 ) 14 | 15 | [node name="Hitbox" type="Area2D" parent="." groups=[ 16 | "Player_damager", 17 | ]] 18 | 19 | [node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] 20 | visible = false 21 | shape = SubResource( 1 ) 22 | 23 | [node name="Destroy_timer" type="Timer" parent="."] 24 | one_shot = true 25 | autostart = true 26 | [connection signal="timeout" from="Destroy_timer" to="." method="_on_Destroy_timer_timeout"] 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godot 3 Multiplayer Shooter 2 | 3 | ![gameplay](misc/finished-game.gif) 4 | 5 | You can follow the tutorial series for making this project [here on YouTube](https://youtube.com/playlist?list=PL6bQeQE-ybqDmGuN7Nz4ZbTAqyCMyEHQa). 6 | 7 | Feel free to use the code found in this project in your projects. 8 | Please note that this system will not work in 4.0, without some heavy adaptation. 9 | 10 | Only LAN multiplayer is shown in the tutorial series. 11 | If you are looking for WAN multiplayer where users can connect and play together on different networks, you will have to port forward to your server. 12 | If you're unsure what all this networking stuff means you can follow my [blogpost here](https://plug-world.com/posts/godot-multiplayer-lan-vs-wan-explanation/). 13 | 14 | This system relies on MultiplayerENet, which means that only Desktop and Mobile platforms will work with multiplayer. 15 | HTML5 Web platforms will not work in this case. 16 | 17 | Thanks :) 18 | -------------------------------------------------------------------------------- /Server_display.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://Server_display.gd" type="Script" id=1] 4 | [ext_resource path="res://Base_font.tres" type="DynamicFont" id=2] 5 | 6 | [node name="Server_display" type="Label" groups=[ 7 | "Server_display", 8 | ]] 9 | anchor_right = 1.0 10 | margin_right = -220.0 11 | margin_bottom = 130.0 12 | rect_min_size = Vector2( 0, 130 ) 13 | custom_fonts/font = ExtResource( 2 ) 14 | text = "N/A : 000.000.000" 15 | align = 1 16 | valign = 1 17 | script = ExtResource( 1 ) 18 | __meta__ = { 19 | "_edit_use_anchors_": false 20 | } 21 | 22 | [node name="Join_button" type="Button" parent="."] 23 | anchor_left = 1.0 24 | anchor_right = 1.0 25 | anchor_bottom = 1.0 26 | margin_left = -302.0 27 | margin_top = 13.0 28 | margin_bottom = -13.0 29 | custom_fonts/font = ExtResource( 2 ) 30 | text = "Join" 31 | __meta__ = { 32 | "_edit_use_anchors_": false 33 | } 34 | [connection signal="pressed" from="Join_button" to="." method="_on_Join_button_pressed"] 35 | -------------------------------------------------------------------------------- /Server_advertiser.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | export (float) var broadcast_interval = 1.0 4 | var server_info = {"name": "LAN Game"} 5 | 6 | var socket_udp 7 | var broadcast_timer = Timer.new() 8 | var broadcast_port = Network.DEFAULT_PORT 9 | 10 | func _enter_tree(): 11 | broadcast_timer.wait_time = broadcast_interval 12 | broadcast_timer.one_shot = false 13 | broadcast_timer.autostart = true 14 | 15 | if get_tree().is_network_server(): 16 | add_child(broadcast_timer) 17 | broadcast_timer.connect("timeout", self, "broadcast") 18 | 19 | socket_udp = PacketPeerUDP.new() 20 | socket_udp.set_broadcast_enabled(true) 21 | socket_udp.set_dest_address('255.255.255.255', broadcast_port) 22 | 23 | func broadcast(): 24 | server_info.name = Network.current_player_username 25 | var packet_message = to_json(server_info) 26 | var packet = packet_message.to_ascii() 27 | socket_udp.put_packet(packet) 28 | 29 | func _exit_tree(): 30 | broadcast_timer.stop() 31 | if socket_udp != null: 32 | socket_udp.close() 33 | -------------------------------------------------------------------------------- /Game.gd: -------------------------------------------------------------------------------- 1 | extends Node2D 2 | 3 | var current_spawn_location_instance_number = 1 4 | var current_player_for_spawn_location_number = null 5 | 6 | func _ready() -> void: 7 | get_tree().connect("network_peer_disconnected", self, "_player_disconnected") 8 | 9 | if get_tree().is_network_server(): 10 | setup_players_positions() 11 | 12 | func setup_players_positions() -> void: 13 | for player in Persistent_nodes.get_children(): 14 | if player.is_in_group("Player"): 15 | for spawn_location in $Spawn_locations.get_children(): 16 | if int(spawn_location.name) == current_spawn_location_instance_number and current_player_for_spawn_location_number != player: 17 | player.rpc("update_position", spawn_location.global_position) 18 | current_spawn_location_instance_number += 1 19 | current_player_for_spawn_location_number = player 20 | 21 | func _player_disconnected(id) -> void: 22 | if Persistent_nodes.has_node(str(id)): 23 | Persistent_nodes.get_node(str(id)).username_text_instance.queue_free() 24 | Persistent_nodes.get_node(str(id)).queue_free() 25 | -------------------------------------------------------------------------------- /Player_bullet.gd: -------------------------------------------------------------------------------- 1 | extends Sprite 2 | 3 | var velocity = Vector2(1, 0) 4 | var player_rotation 5 | 6 | export(int) var speed = 1400 7 | export(int) var damage = 25 8 | 9 | puppet var puppet_position setget puppet_position_set 10 | puppet var puppet_velocity = Vector2(0, 0) 11 | puppet var puppet_rotation = 0 12 | 13 | onready var initial_position = global_position 14 | 15 | var player_owner = 0 16 | 17 | func _ready() -> void: 18 | visible = false 19 | yield(get_tree(), "idle_frame") 20 | 21 | if get_tree().has_network_peer(): 22 | if is_network_master(): 23 | velocity = velocity.rotated(player_rotation) 24 | rotation = player_rotation 25 | rset("puppet_velocity", velocity) 26 | rset("puppet_rotation", rotation) 27 | rset("puppet_position", global_position) 28 | 29 | visible = true 30 | 31 | func _process(delta: float) -> void: 32 | if get_tree().has_network_peer(): 33 | if is_network_master(): 34 | global_position += velocity * speed * delta 35 | else: 36 | rotation = puppet_rotation 37 | global_position += puppet_velocity * speed * delta 38 | 39 | func puppet_position_set(new_value) -> void: 40 | puppet_position = new_value 41 | global_position = puppet_position 42 | 43 | sync func destroy() -> void: 44 | queue_free() 45 | 46 | func _on_Destroy_timer_timeout(): 47 | if get_tree().has_network_peer(): 48 | if get_tree().is_network_server(): 49 | rpc("destroy") 50 | -------------------------------------------------------------------------------- /Server_browser.gd: -------------------------------------------------------------------------------- 1 | extends Control 2 | 3 | onready var server_listener = $Server_listener 4 | onready var server_ip_text_edit = $Background_panel/Server_ip_text_edit 5 | onready var server_container = $Background_panel/VBoxContainer 6 | onready var manual_setup_button = $Background_panel/Manual_setup 7 | 8 | func _ready() -> void: 9 | server_ip_text_edit.hide() 10 | 11 | func _on_Server_listener_new_server(serverInfo): 12 | var server_node = Global.instance_node(load("res://Server_display.tscn"), server_container) 13 | server_node.text = "%s - %s" % [serverInfo.ip, serverInfo.name] 14 | server_node.ip_address = str(serverInfo.ip) 15 | 16 | func _on_Server_listener_remove_server(serverIp): 17 | for serverNode in server_container.get_children(): 18 | if serverNode.is_in_group("Server_display"): 19 | if serverNode.ip_address == serverIp: 20 | serverNode.queue_free() 21 | break 22 | 23 | func _on_Manual_setup_pressed(): 24 | if manual_setup_button.text != "exit setup": 25 | server_ip_text_edit.show() 26 | manual_setup_button.text = "exit setup" 27 | server_container.hide() 28 | server_ip_text_edit.call_deferred("grab_focus") 29 | else: 30 | server_ip_text_edit.text = "" 31 | server_ip_text_edit.hide() 32 | manual_setup_button.text = "manual setup" 33 | server_container.show() 34 | 35 | func _on_Join_server_pressed(): 36 | Network.ip_address = server_ip_text_edit.text 37 | hide() 38 | Network.join_server() 39 | 40 | func _on_Go_back_pressed(): 41 | get_tree().reload_current_scene() 42 | -------------------------------------------------------------------------------- /Simple_prompt.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://Down Hill.ttf" type="DynamicFontData" id=1] 4 | [ext_resource path="res://Simple_prompt.gd" type="Script" id=2] 5 | 6 | [sub_resource type="DynamicFont" id=1] 7 | size = 100 8 | use_mipmaps = true 9 | use_filter = true 10 | font_data = ExtResource( 1 ) 11 | 12 | [sub_resource type="DynamicFont" id=2] 13 | size = 100 14 | use_mipmaps = true 15 | use_filter = true 16 | font_data = ExtResource( 1 ) 17 | 18 | [node name="Simple_prompt" type="Control"] 19 | anchor_right = 1.0 20 | anchor_bottom = 1.0 21 | script = ExtResource( 2 ) 22 | __meta__ = { 23 | "_edit_use_anchors_": false 24 | } 25 | 26 | [node name="Panel" type="Panel" parent="."] 27 | anchor_left = 0.5 28 | anchor_top = 0.5 29 | anchor_right = 0.5 30 | anchor_bottom = 0.5 31 | margin_left = -704.0 32 | margin_top = -330.0 33 | margin_right = 704.0 34 | margin_bottom = 330.0 35 | 36 | [node name="Ok" type="Button" parent="Panel"] 37 | anchor_left = 0.5 38 | anchor_top = 1.0 39 | anchor_right = 0.5 40 | anchor_bottom = 1.0 41 | margin_left = -257.0 42 | margin_top = -310.0 43 | margin_right = 257.0 44 | margin_bottom = -113.0 45 | custom_fonts/font = SubResource( 1 ) 46 | text = "ok" 47 | 48 | [node name="Label" type="Label" parent="."] 49 | anchor_left = 0.5 50 | anchor_top = 0.5 51 | anchor_right = 0.5 52 | anchor_bottom = 0.5 53 | margin_left = -516.0 54 | margin_top = -155.5 55 | margin_right = 516.0 56 | margin_bottom = -68.5 57 | custom_fonts/font = SubResource( 2 ) 58 | text = "simple prompt" 59 | align = 1 60 | valign = 1 61 | [connection signal="pressed" from="Panel/Ok" to="." method="_on_Ok_pressed"] 62 | -------------------------------------------------------------------------------- /Player.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://Player.gd" type="Script" id=1] 4 | [ext_resource path="res://Characters.png" type="Texture" id=2] 5 | 6 | [sub_resource type="CapsuleShape2D" id=1] 7 | radius = 40.0 8 | height = 33.0 9 | 10 | [node name="Player" type="KinematicBody2D" groups=[ 11 | "Net", 12 | "Player", 13 | ]] 14 | script = ExtResource( 1 ) 15 | 16 | [node name="Sprite" type="Sprite" parent="."] 17 | scale = Vector2( 0.75, 0.75 ) 18 | texture = ExtResource( 2 ) 19 | offset = Vector2( 16, -6 ) 20 | region_enabled = true 21 | region_rect = Rect2( 512, 1500, 256, 250 ) 22 | 23 | [node name="CollisionShape2D" type="CollisionShape2D" parent="."] 24 | shape = SubResource( 1 ) 25 | 26 | [node name="Tween" type="Tween" parent="."] 27 | 28 | [node name="Network_tick_rate" type="Timer" parent="."] 29 | wait_time = 0.03 30 | autostart = true 31 | 32 | [node name="Reload_timer" type="Timer" parent="."] 33 | wait_time = 0.15 34 | one_shot = true 35 | 36 | [node name="Hit_timer" type="Timer" parent="."] 37 | wait_time = 0.1 38 | one_shot = true 39 | 40 | [node name="Shoot_point" type="Position2D" parent="."] 41 | position = Vector2( 98, 30 ) 42 | 43 | [node name="Hitbox" type="Area2D" parent="."] 44 | 45 | [node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] 46 | shape = SubResource( 1 ) 47 | [connection signal="timeout" from="Network_tick_rate" to="." method="_on_Network_tick_rate_timeout"] 48 | [connection signal="timeout" from="Reload_timer" to="." method="_on_Reload_timer_timeout"] 49 | [connection signal="timeout" from="Hit_timer" to="." method="_on_Hit_timer_timeout"] 50 | [connection signal="area_entered" from="Hitbox" to="." method="_on_Hitbox_area_entered"] 51 | -------------------------------------------------------------------------------- /Server_listener.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | signal new_server 4 | signal remove_server 5 | 6 | var clean_up_timer = Timer.new() 7 | var socket_udp = PacketPeerUDP.new() 8 | var listen_port = Network.DEFAULT_PORT 9 | var known_servers = {} 10 | 11 | export (int) var server_cleanup_threshold = 3 12 | 13 | func _init(): 14 | clean_up_timer.wait_time = server_cleanup_threshold 15 | clean_up_timer.one_shot = false 16 | clean_up_timer.autostart = true 17 | clean_up_timer.connect("timeout", self, 'clean_up') 18 | add_child(clean_up_timer) 19 | 20 | func _ready(): 21 | known_servers.clear() 22 | 23 | if socket_udp.listen(listen_port) != OK: 24 | print("GameServer LAN service: Error listening on port: " + str(listen_port)) 25 | else: 26 | print("GameServer LAN service: Listening on port: " + str(listen_port)) 27 | 28 | func _process(delta): 29 | if socket_udp.get_available_packet_count() > 0: 30 | var server_ip = socket_udp.get_packet_ip() 31 | var server_port = socket_udp.get_packet_port() 32 | var array_bytes = socket_udp.get_packet() 33 | 34 | if server_ip != '' and server_port > 0: 35 | if not known_servers.has(server_ip): 36 | var serverMessage = array_bytes.get_string_from_ascii() 37 | var gameInfo = parse_json(serverMessage) 38 | gameInfo.ip = server_ip 39 | gameInfo.lastSeen = OS.get_unix_time() 40 | known_servers[server_ip] = gameInfo 41 | emit_signal("new_server", gameInfo) 42 | print(socket_udp.get_packet_ip()) 43 | else: 44 | var gameInfo = known_servers[server_ip] 45 | gameInfo.lastSeen = OS.get_unix_time() 46 | 47 | func clean_up(): 48 | var now = OS.get_unix_time() 49 | for server_ip in known_servers: 50 | var serverInfo = known_servers[server_ip] 51 | if (now - serverInfo.lastSeen) > server_cleanup_threshold: 52 | known_servers.erase(server_ip) 53 | print('Remove old server: %s' % server_ip) 54 | emit_signal("remove_server", server_ip) 55 | 56 | func _exit_tree(): 57 | socket_udp.close() 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Network_setup.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://Base_font.tres" type="DynamicFont" id=1] 4 | [ext_resource path="res://Network_setup.gd" type="Script" id=2] 5 | [ext_resource path="res://UI.gd" type="Script" id=3] 6 | 7 | [node name="Network_setup" type="Control"] 8 | anchor_right = 1.0 9 | anchor_bottom = 1.0 10 | script = ExtResource( 2 ) 11 | __meta__ = { 12 | "_edit_use_anchors_": false 13 | } 14 | 15 | [node name="Multiplayer_configure" type="Control" parent="."] 16 | anchor_right = 1.0 17 | anchor_bottom = 1.0 18 | __meta__ = { 19 | "_edit_use_anchors_": false 20 | } 21 | 22 | [node name="Create_server" type="Button" parent="Multiplayer_configure"] 23 | anchor_left = 0.5 24 | anchor_top = 0.5 25 | anchor_right = 0.5 26 | anchor_bottom = 0.5 27 | margin_left = -267.5 28 | margin_top = -202.0 29 | margin_right = 267.5 30 | margin_bottom = -25.9999 31 | custom_fonts/font = ExtResource( 1 ) 32 | text = "Create Server" 33 | 34 | [node name="Join_server" type="Button" parent="Multiplayer_configure"] 35 | anchor_left = 0.5 36 | anchor_top = 0.5 37 | anchor_right = 0.5 38 | anchor_bottom = 0.5 39 | margin_left = -267.5 40 | margin_top = 24.0 41 | margin_right = 267.5 42 | margin_bottom = 200.0 43 | custom_fonts/font = ExtResource( 1 ) 44 | text = "Join Server" 45 | 46 | [node name="Username_text_edit" type="LineEdit" parent="Multiplayer_configure"] 47 | anchor_left = 0.5 48 | anchor_right = 0.5 49 | margin_left = -428.857 50 | margin_top = 125.139 51 | margin_right = 416.143 52 | margin_bottom = 229.139 53 | custom_fonts/font = ExtResource( 1 ) 54 | align = 1 55 | placeholder_text = "enter username" 56 | __meta__ = { 57 | "_edit_use_anchors_": false 58 | } 59 | 60 | [node name="UI" type="CanvasLayer" parent="."] 61 | script = ExtResource( 3 ) 62 | 63 | [node name="Start_game" type="Button" parent="UI"] 64 | margin_left = 27.0 65 | margin_top = 27.0 66 | margin_right = 391.0 67 | margin_bottom = 158.0 68 | custom_fonts/font = ExtResource( 1 ) 69 | text = "Start Game" 70 | __meta__ = { 71 | "_edit_use_anchors_": false 72 | } 73 | 74 | [node name="Device_ip_address" type="Label" parent="UI"] 75 | anchor_top = 1.0 76 | anchor_right = 1.0 77 | anchor_bottom = 1.0 78 | margin_top = -150.0 79 | margin_right = 0.00012207 80 | custom_fonts/font = ExtResource( 1 ) 81 | align = 1 82 | valign = 1 83 | __meta__ = { 84 | "_edit_use_anchors_": false 85 | } 86 | 87 | [node name="Spawn_locations" type="Node" parent="."] 88 | 89 | [node name="1" type="Position2D" parent="Spawn_locations"] 90 | position = Vector2( 192, 192 ) 91 | 92 | [node name="2" type="Position2D" parent="Spawn_locations"] 93 | position = Vector2( 1728, 192 ) 94 | 95 | [node name="3" type="Position2D" parent="Spawn_locations"] 96 | position = Vector2( 960, 192 ) 97 | 98 | [node name="4" type="Position2D" parent="Spawn_locations"] 99 | position = Vector2( 192, 896 ) 100 | 101 | [node name="5" type="Position2D" parent="Spawn_locations"] 102 | position = Vector2( 960, 896 ) 103 | 104 | [node name="6" type="Position2D" parent="Spawn_locations"] 105 | position = Vector2( 1728, 896 ) 106 | [connection signal="pressed" from="Multiplayer_configure/Create_server" to="." method="_on_Create_server_pressed"] 107 | [connection signal="pressed" from="Multiplayer_configure/Join_server" to="." method="_on_Join_server_pressed"] 108 | [connection signal="pressed" from="UI/Start_game" to="." method="_on_Start_game_pressed"] 109 | -------------------------------------------------------------------------------- /Network_setup.gd: -------------------------------------------------------------------------------- 1 | extends Control 2 | 3 | var player = load("res://Player.tscn") 4 | 5 | var current_spawn_location_instance_number = 1 6 | var current_player_for_spawn_location_number = null 7 | 8 | onready var multiplayer_config_ui = $Multiplayer_configure 9 | onready var username_text_edit = $Multiplayer_configure/Username_text_edit 10 | 11 | onready var device_ip_address = $UI/Device_ip_address 12 | onready var start_game = $UI/Start_game 13 | 14 | func _ready() -> void: 15 | get_tree().connect("network_peer_connected", self, "_player_connected") 16 | get_tree().connect("network_peer_disconnected", self, "_player_disconnected") 17 | get_tree().connect("connected_to_server", self, "_connected_to_server") 18 | 19 | device_ip_address.text = Network.ip_address 20 | 21 | if get_tree().network_peer != null: 22 | multiplayer_config_ui.hide() 23 | 24 | current_spawn_location_instance_number = 1 25 | for player in Persistent_nodes.get_children(): 26 | if player.is_in_group("Player"): 27 | for spawn_location in $Spawn_locations.get_children(): 28 | if int(spawn_location.name) == current_spawn_location_instance_number and current_player_for_spawn_location_number != player: 29 | player.rpc("update_position", spawn_location.global_position) 30 | player.rpc("enable") 31 | current_spawn_location_instance_number += 1 32 | current_player_for_spawn_location_number = player 33 | else: 34 | start_game.hide() 35 | 36 | func _process(_delta: float) -> void: 37 | if get_tree().network_peer != null: 38 | if get_tree().get_network_connected_peers().size() >= 1 and get_tree().is_network_server(): 39 | start_game.show() 40 | else: 41 | start_game.hide() 42 | 43 | func _player_connected(id) -> void: 44 | print("Player " + str(id) + " has connected") 45 | 46 | instance_player(id) 47 | 48 | func _player_disconnected(id) -> void: 49 | print("Player " + str(id) + " has disconnected") 50 | 51 | if Persistent_nodes.has_node(str(id)): 52 | Persistent_nodes.get_node(str(id)).username_text_instance.queue_free() 53 | Persistent_nodes.get_node(str(id)).queue_free() 54 | 55 | func _on_Create_server_pressed(): 56 | if username_text_edit.text != "": 57 | Network.current_player_username = username_text_edit.text 58 | multiplayer_config_ui.hide() 59 | Network.create_server() 60 | 61 | instance_player(get_tree().get_network_unique_id()) 62 | 63 | func _on_Join_server_pressed(): 64 | if username_text_edit.text != "": 65 | multiplayer_config_ui.hide() 66 | username_text_edit.hide() 67 | 68 | Global.instance_node(load("res://Server_browser.tscn"), self) 69 | 70 | func _connected_to_server() -> void: 71 | yield(get_tree().create_timer(0.1), "timeout") 72 | instance_player(get_tree().get_network_unique_id()) 73 | 74 | func instance_player(id) -> void: 75 | var player_instance = Global.instance_node_at_location(player, Persistent_nodes, get_node("Spawn_locations/" + str(current_spawn_location_instance_number)).global_position) 76 | player_instance.name = str(id) 77 | player_instance.set_network_master(id) 78 | player_instance.username = username_text_edit.text 79 | current_spawn_location_instance_number += 1 80 | 81 | func _on_Start_game_pressed(): 82 | rpc("switch_to_game") 83 | 84 | sync func switch_to_game() -> void: 85 | for child in Persistent_nodes.get_children(): 86 | if child.is_in_group("Player"): 87 | child.update_shoot_mode(true) 88 | 89 | get_tree().change_scene("res://Game.tscn") 90 | 91 | 92 | -------------------------------------------------------------------------------- /Network.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | const DEFAULT_PORT = 28960 4 | const MAX_CLIENTS = 6 5 | 6 | var server = null 7 | var client = null 8 | 9 | var ip_address = "" 10 | var current_player_username = "" 11 | 12 | var client_connected_to_server = false 13 | 14 | var networked_object_name_index = 0 setget networked_object_name_index_set 15 | puppet var puppet_networked_object_name_index = 0 setget puppet_networked_object_name_index_set 16 | 17 | onready var client_connection_timeout_timer = Timer.new() 18 | 19 | func _ready() -> void: 20 | add_child(client_connection_timeout_timer) 21 | client_connection_timeout_timer.wait_time = 10 22 | client_connection_timeout_timer.one_shot = true 23 | 24 | client_connection_timeout_timer.connect("timeout", self, "_client_connection_timeout") 25 | 26 | if OS.get_name() == "Windows": 27 | ip_address = IP.get_local_addresses()[3] 28 | elif OS.get_name() == "Android": 29 | ip_address = IP.get_local_addresses()[0] 30 | else: 31 | ip_address = IP.get_local_addresses()[3] 32 | 33 | for ip in IP.get_local_addresses(): 34 | if ip.begins_with("192.168.") and not ip.ends_with(".1"): 35 | ip_address = ip 36 | 37 | get_tree().connect("connected_to_server", self, "_connected_to_server") 38 | get_tree().connect("server_disconnected", self, "_server_disconnected") 39 | get_tree().connect("connection_failed", self, "_connection_failed") 40 | 41 | func create_server() -> void: 42 | server = NetworkedMultiplayerENet.new() 43 | server.create_server(DEFAULT_PORT, MAX_CLIENTS) 44 | get_tree().set_network_peer(server) 45 | Global.instance_node(load("res://Server_advertiser.tscn"), get_tree().current_scene) 46 | 47 | func join_server() -> void: 48 | client = NetworkedMultiplayerENet.new() 49 | client.create_client(ip_address, DEFAULT_PORT) 50 | get_tree().set_network_peer(client) 51 | client_connection_timeout_timer.start() 52 | 53 | func reset_network_connection() -> void: 54 | if get_tree().has_network_peer(): 55 | get_tree().network_peer = null 56 | 57 | func _connected_to_server() -> void: 58 | print("Successfully connected to the server") 59 | 60 | client_connected_to_server = true 61 | 62 | func _server_disconnected() -> void: 63 | print("Disconnected from the server") 64 | 65 | for child in Persistent_nodes.get_children(): 66 | if child.is_in_group("Net"): 67 | child.queue_free() 68 | 69 | reset_network_connection() 70 | 71 | if Global.ui != null: 72 | var prompt = Global.instance_node(load("res://Simple_prompt.tscn"), Global.ui) 73 | prompt.set_text("Disconnected from server") 74 | 75 | func _client_connection_timeout(): 76 | if client_connected_to_server == false: 77 | print("Client has been timed out") 78 | 79 | reset_network_connection() 80 | 81 | var connection_timeout_prompt = Global.instance_node(load("res://Simple_prompt.tscn"), get_tree().current_scene) 82 | connection_timeout_prompt.set_text("Connection timed out") 83 | 84 | func _connection_failed(): 85 | for child in Persistent_nodes.get_children(): 86 | if child.is_in_group("Net"): 87 | child.queue_free() 88 | 89 | reset_network_connection() 90 | 91 | if Global.ui != null: 92 | var prompt = Global.instance_node(load("res://Simple_prompt.tscn"), Global.ui) 93 | prompt.set_text("Connection failed") 94 | 95 | func puppet_networked_object_name_index_set(new_value): 96 | networked_object_name_index = new_value 97 | 98 | func networked_object_name_index_set(new_value): 99 | networked_object_name_index = new_value 100 | 101 | if get_tree().is_network_server(): 102 | rset("puppet_networked_object_name_index", networked_object_name_index) 103 | -------------------------------------------------------------------------------- /project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=4 10 | 11 | _global_script_classes=[ ] 12 | _global_script_class_icons={ 13 | 14 | } 15 | 16 | [application] 17 | 18 | config/name="Multiplayer Tutorial Youtube" 19 | run/main_scene="res://Network_setup.tscn" 20 | config/icon="res://icon.png" 21 | 22 | [autoload] 23 | 24 | Network="*res://Network.gd" 25 | Global="*res://Global.gd" 26 | Persistent_nodes="*res://Persistent_nodes.tscn" 27 | 28 | [display] 29 | 30 | window/size/width=1920 31 | window/size/height=1080 32 | window/size/test_width=1280 33 | window/size/test_height=720 34 | window/stretch/mode="2d" 35 | window/stretch/aspect="keep" 36 | 37 | [importer_defaults] 38 | 39 | texture={ 40 | "compress/bptc_ldr": 0, 41 | "compress/hdr_mode": 0, 42 | "compress/lossy_quality": 0.7, 43 | "compress/mode": 0, 44 | "compress/normal_map": 0, 45 | "detect_3d": true, 46 | "flags/anisotropic": false, 47 | "flags/filter": true, 48 | "flags/mipmaps": true, 49 | "flags/repeat": 0, 50 | "flags/srgb": 2, 51 | "process/HDR_as_SRGB": false, 52 | "process/fix_alpha_border": true, 53 | "process/invert_color": false, 54 | "process/premult_alpha": false, 55 | "size_limit": 0, 56 | "stream": false, 57 | "svg/scale": 1.0 58 | } 59 | 60 | [input] 61 | 62 | right={ 63 | "deadzone": 0.5, 64 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null) 65 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null) 66 | ] 67 | } 68 | left={ 69 | "deadzone": 0.5, 70 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null) 71 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null) 72 | ] 73 | } 74 | up={ 75 | "deadzone": 0.5, 76 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null) 77 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null) 78 | ] 79 | } 80 | down={ 81 | "deadzone": 0.5, 82 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null) 83 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null) 84 | ] 85 | } 86 | click={ 87 | "deadzone": 0.5, 88 | "events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null) 89 | ] 90 | } 91 | 92 | [rendering] 93 | 94 | quality/2d/use_pixel_snap=true 95 | environment/default_environment="res://default_env.tres" 96 | -------------------------------------------------------------------------------- /Server_browser.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://Base_font.tres" type="DynamicFont" id=1] 4 | [ext_resource path="res://Server_browser.gd" type="Script" id=2] 5 | [ext_resource path="res://Server_listener.tscn" type="PackedScene" id=3] 6 | 7 | [sub_resource type="Animation" id=1] 8 | resource_name = "Searching" 9 | length = 0.8 10 | loop = true 11 | tracks/0/type = "value" 12 | tracks/0/path = NodePath(".:text") 13 | tracks/0/interp = 1 14 | tracks/0/loop_wrap = true 15 | tracks/0/imported = false 16 | tracks/0/enabled = true 17 | tracks/0/keys = { 18 | "times": PoolRealArray( 0, 0.2, 0.4, 0.6 ), 19 | "transitions": PoolRealArray( 1, 1, 1, 1 ), 20 | "update": 1, 21 | "values": [ "Searching for Servers", "Searching for Servers.", "Searching for Servers..", "Searching for Servers..." ] 22 | } 23 | 24 | [node name="Server_browser" type="Control"] 25 | anchor_right = 1.0 26 | anchor_bottom = 1.0 27 | script = ExtResource( 2 ) 28 | __meta__ = { 29 | "_edit_use_anchors_": false 30 | } 31 | 32 | [node name="Background_panel" type="Panel" parent="."] 33 | anchor_right = 1.0 34 | anchor_bottom = 1.0 35 | margin_left = 96.0 36 | margin_top = 162.0 37 | margin_right = -95.9999 38 | margin_bottom = -53.9999 39 | __meta__ = { 40 | "_edit_use_anchors_": false 41 | } 42 | 43 | [node name="Manual_setup" type="Button" parent="Background_panel"] 44 | anchor_left = 1.0 45 | anchor_top = 1.0 46 | anchor_right = 1.0 47 | anchor_bottom = 1.0 48 | margin_left = -473.0 49 | margin_top = -175.0 50 | margin_right = -30.0001 51 | margin_bottom = -30.0001 52 | custom_fonts/font = ExtResource( 1 ) 53 | text = "Manual Setup" 54 | 55 | [node name="Go_back" type="Button" parent="Background_panel"] 56 | anchor_top = 1.0 57 | anchor_bottom = 1.0 58 | margin_left = 30.0 59 | margin_top = -170.0 60 | margin_right = 473.0 61 | margin_bottom = -25.0001 62 | custom_fonts/font = ExtResource( 1 ) 63 | text = "Go Back" 64 | __meta__ = { 65 | "_edit_use_anchors_": false 66 | } 67 | 68 | [node name="Server_ip_text_edit" type="LineEdit" parent="Background_panel"] 69 | anchor_left = 0.5 70 | anchor_top = 0.5 71 | anchor_right = 0.5 72 | anchor_bottom = 0.5 73 | margin_left = -403.0 74 | margin_top = -243.0 75 | margin_right = 403.0 76 | margin_bottom = -138.0 77 | custom_fonts/font = ExtResource( 1 ) 78 | align = 1 79 | __meta__ = { 80 | "_edit_use_anchors_": false 81 | } 82 | 83 | [node name="Type_in_server_ip" type="Label" parent="Background_panel/Server_ip_text_edit"] 84 | anchor_right = 1.0 85 | margin_top = -105.0 86 | margin_right = -6.10352e-05 87 | custom_fonts/font = ExtResource( 1 ) 88 | text = "Type in Server IP" 89 | align = 1 90 | valign = 1 91 | 92 | [node name="Join_server" type="Button" parent="Background_panel/Server_ip_text_edit"] 93 | anchor_left = 0.5 94 | anchor_top = 0.5 95 | anchor_right = 0.5 96 | anchor_bottom = 0.5 97 | margin_left = -221.5 98 | margin_top = 94.5 99 | margin_right = 221.5 100 | margin_bottom = 239.5 101 | custom_fonts/font = ExtResource( 1 ) 102 | text = "Join Server" 103 | __meta__ = { 104 | "_edit_use_anchors_": false 105 | } 106 | 107 | [node name="VBoxContainer" type="VBoxContainer" parent="Background_panel"] 108 | anchor_right = 1.0 109 | anchor_bottom = 1.0 110 | margin_left = 70.0 111 | margin_top = 40.0 112 | margin_right = -70.0 113 | margin_bottom = -175.0 114 | __meta__ = { 115 | "_edit_use_anchors_": false 116 | } 117 | 118 | [node name="Searching_for_servers" type="Label" parent="Background_panel/VBoxContainer"] 119 | margin_right = 1588.0 120 | margin_bottom = 70.0 121 | rect_min_size = Vector2( 0, 70 ) 122 | custom_fonts/font = ExtResource( 1 ) 123 | text = "Searching for Servers" 124 | align = 1 125 | valign = 1 126 | 127 | [node name="AnimationPlayer" type="AnimationPlayer" parent="Background_panel/VBoxContainer/Searching_for_servers"] 128 | autoplay = "Searching" 129 | playback_speed = 0.5 130 | anims/Searching = SubResource( 1 ) 131 | 132 | [node name="Server_browser_label" type="Label" parent="Background_panel"] 133 | anchor_right = 1.0 134 | margin_top = -176.0 135 | custom_fonts/font = ExtResource( 1 ) 136 | text = "Server Browser" 137 | align = 1 138 | valign = 1 139 | __meta__ = { 140 | "_edit_use_anchors_": false 141 | } 142 | 143 | [node name="Server_listener" parent="." instance=ExtResource( 3 )] 144 | [connection signal="pressed" from="Background_panel/Manual_setup" to="." method="_on_Manual_setup_pressed"] 145 | [connection signal="pressed" from="Background_panel/Go_back" to="." method="_on_Go_back_pressed"] 146 | [connection signal="pressed" from="Background_panel/Server_ip_text_edit/Join_server" to="." method="_on_Join_server_pressed"] 147 | [connection signal="new_server" from="Server_listener" to="." method="_on_Server_listener_new_server"] 148 | [connection signal="remove_server" from="Server_listener" to="." method="_on_Server_listener_remove_server"] 149 | -------------------------------------------------------------------------------- /Player.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody2D 2 | 3 | const speed = 400 4 | 5 | var hp = 100 setget set_hp 6 | var velocity = Vector2(0, 0) 7 | var can_shoot = true 8 | var is_reloading = false 9 | 10 | var player_bullet = load("res://Player_bullet.tscn") 11 | var username_text = load("res://Username_text.tscn") 12 | 13 | var username setget username_set 14 | var username_text_instance = null 15 | 16 | puppet var puppet_hp = 100 setget puppet_hp_set 17 | puppet var puppet_position = Vector2(0, 0) setget puppet_position_set 18 | puppet var puppet_velocity = Vector2() 19 | puppet var puppet_rotation = 0 20 | puppet var puppet_username = "" setget puppet_username_set 21 | 22 | onready var tween = $Tween 23 | onready var sprite = $Sprite 24 | onready var reload_timer = $Reload_timer 25 | onready var shoot_point = $Shoot_point 26 | onready var hit_timer = $Hit_timer 27 | 28 | func _ready(): 29 | get_tree().connect("network_peer_connected", self, "_network_peer_connected") 30 | 31 | username_text_instance = Global.instance_node_at_location(username_text, Persistent_nodes, global_position) 32 | username_text_instance.player_following = self 33 | 34 | update_shoot_mode(false) 35 | Global.alive_players.append(self) 36 | 37 | yield(get_tree(), "idle_frame") 38 | if get_tree().has_network_peer(): 39 | if is_network_master(): 40 | Global.player_master = self 41 | 42 | func _process(delta: float) -> void: 43 | if username_text_instance != null: 44 | username_text_instance.name = "username" + name 45 | 46 | if get_tree().has_network_peer(): 47 | if is_network_master() and visible: 48 | var x_input = int(Input.is_action_pressed("right")) - int(Input.is_action_pressed("left")) 49 | var y_input = int(Input.is_action_pressed("down")) - int(Input.is_action_pressed("up")) 50 | 51 | velocity = Vector2(x_input, y_input).normalized() 52 | 53 | move_and_slide(velocity * speed) 54 | 55 | look_at(get_global_mouse_position()) 56 | 57 | if Input.is_action_pressed("click") and can_shoot and not is_reloading: 58 | rpc("instance_bullet", get_tree().get_network_unique_id()) 59 | is_reloading = true 60 | reload_timer.start() 61 | else: 62 | rotation = lerp_angle(rotation, puppet_rotation, delta * 8) 63 | 64 | if not tween.is_active(): 65 | move_and_slide(puppet_velocity * speed) 66 | 67 | if hp <= 0: 68 | if username_text_instance != null: 69 | username_text_instance.visible = false 70 | 71 | if get_tree().has_network_peer(): 72 | if get_tree().is_network_server(): 73 | rpc("destroy") 74 | 75 | func lerp_angle(from, to, weight): 76 | return from + short_angle_dist(from, to) * weight 77 | 78 | func short_angle_dist(from, to): 79 | var max_angle = PI * 2 80 | var difference = fmod(to - from, max_angle) 81 | return fmod(2 * difference, max_angle) - difference 82 | 83 | func puppet_position_set(new_value) -> void: 84 | puppet_position = new_value 85 | 86 | tween.interpolate_property(self, "global_position", global_position, puppet_position, 0.1) 87 | tween.start() 88 | 89 | func set_hp(new_value): 90 | hp = new_value 91 | 92 | if get_tree().has_network_peer(): 93 | if is_network_master(): 94 | rset("puppet_hp", hp) 95 | 96 | func puppet_hp_set(new_value): 97 | puppet_hp = new_value 98 | 99 | if get_tree().has_network_peer(): 100 | if not is_network_master(): 101 | hp = puppet_hp 102 | 103 | func username_set(new_value) -> void: 104 | username = new_value 105 | 106 | if get_tree().has_network_peer(): 107 | if is_network_master() and username_text_instance != null: 108 | username_text_instance.text = username 109 | rset("puppet_username", username) 110 | 111 | func puppet_username_set(new_value) -> void: 112 | puppet_username = new_value 113 | 114 | if get_tree().has_network_peer(): 115 | if not is_network_master() and username_text_instance != null: 116 | username_text_instance.text = puppet_username 117 | 118 | func _network_peer_connected(id) -> void: 119 | rset_id(id, "puppet_username", username) 120 | 121 | func _on_Network_tick_rate_timeout(): 122 | if get_tree().has_network_peer(): 123 | if is_network_master(): 124 | rset_unreliable("puppet_position", global_position) 125 | rset_unreliable("puppet_velocity", velocity) 126 | rset_unreliable("puppet_rotation", rotation) 127 | 128 | sync func instance_bullet(id): 129 | var player_bullet_instance = Global.instance_node_at_location(player_bullet, Persistent_nodes, shoot_point.global_position) 130 | player_bullet_instance.name = "Bullet" + name + str(Network.networked_object_name_index) 131 | player_bullet_instance.set_network_master(id) 132 | player_bullet_instance.player_rotation = rotation 133 | player_bullet_instance.player_owner = id 134 | Network.networked_object_name_index += 1 135 | 136 | sync func update_position(pos): 137 | global_position = pos 138 | puppet_position = pos 139 | 140 | func update_shoot_mode(shoot_mode): 141 | if not shoot_mode: 142 | sprite.set_region_rect(Rect2(0, 1500, 256, 250)) 143 | else: 144 | sprite.set_region_rect(Rect2(512, 1500, 256, 250)) 145 | 146 | can_shoot = shoot_mode 147 | 148 | func _on_Reload_timer_timeout(): 149 | is_reloading = false 150 | 151 | func _on_Hit_timer_timeout(): 152 | modulate = Color(1, 1, 1, 1) 153 | 154 | func _on_Hitbox_area_entered(area): 155 | if get_tree().is_network_server(): 156 | if area.is_in_group("Player_damager") and area.get_parent().player_owner != int(name): 157 | rpc("hit_by_damager", area.get_parent().damage) 158 | 159 | area.get_parent().rpc("destroy") 160 | 161 | sync func hit_by_damager(damage): 162 | hp -= damage 163 | modulate = Color(5, 5, 5, 1) 164 | hit_timer.start() 165 | 166 | sync func enable() -> void: 167 | hp = 100 168 | can_shoot = false 169 | update_shoot_mode(false) 170 | username_text_instance.visible = true 171 | visible = true 172 | $CollisionShape2D.disabled = false 173 | $Hitbox/CollisionShape2D.disabled = false 174 | 175 | if get_tree().has_network_peer(): 176 | if is_network_master(): 177 | Global.player_master = self 178 | 179 | if not Global.alive_players.has(self): 180 | Global.alive_players.append(self) 181 | 182 | sync func destroy() -> void: 183 | username_text_instance.visible = false 184 | visible = false 185 | $CollisionShape2D.disabled = true 186 | $Hitbox/CollisionShape2D.disabled = true 187 | Global.alive_players.erase(self) 188 | 189 | if get_tree().has_network_peer(): 190 | if is_network_master(): 191 | Global.player_master = null 192 | 193 | func _exit_tree() -> void: 194 | Global.alive_players.erase(self) 195 | if get_tree().has_network_peer(): 196 | if is_network_master(): 197 | Global.player_master = null 198 | 199 | 200 | -------------------------------------------------------------------------------- /export_presets.cfg: -------------------------------------------------------------------------------- 1 | [preset.0] 2 | 3 | name="Android" 4 | platform="Android" 5 | runnable=true 6 | custom_features="" 7 | export_filter="all_resources" 8 | include_filter="" 9 | exclude_filter="" 10 | export_path="" 11 | patch_list=PoolStringArray( ) 12 | script_export_mode=1 13 | script_encryption_key="" 14 | 15 | [preset.0.options] 16 | 17 | graphics/32_bits_framebuffer=true 18 | xr_features/xr_mode=0 19 | xr_features/degrees_of_freedom=0 20 | xr_features/hand_tracking=0 21 | xr_features/focus_awareness=false 22 | one_click_deploy/clear_previous_install=false 23 | custom_template/debug="" 24 | custom_template/release="" 25 | custom_template/use_custom_build=false 26 | command_line/extra_args="" 27 | version/code=1 28 | version/name="1.0" 29 | package/unique_name="org.godotengine.$genname" 30 | package/name="" 31 | package/signed=true 32 | screen/immersive_mode=true 33 | screen/orientation=0 34 | screen/support_small=true 35 | screen/support_normal=true 36 | screen/support_large=true 37 | screen/support_xlarge=true 38 | screen/opengl_debug=false 39 | launcher_icons/main_192x192="" 40 | launcher_icons/adaptive_foreground_432x432="" 41 | launcher_icons/adaptive_background_432x432="" 42 | keystore/debug="" 43 | keystore/debug_user="" 44 | keystore/debug_password="" 45 | keystore/release="" 46 | keystore/release_user="" 47 | keystore/release_password="" 48 | apk_expansion/enable=false 49 | apk_expansion/SALT="" 50 | apk_expansion/public_key="" 51 | architectures/armeabi-v7a=true 52 | architectures/arm64-v8a=true 53 | architectures/x86=false 54 | architectures/x86_64=false 55 | permissions/custom_permissions=PoolStringArray( ) 56 | permissions/access_checkin_properties=false 57 | permissions/access_coarse_location=false 58 | permissions/access_fine_location=false 59 | permissions/access_location_extra_commands=false 60 | permissions/access_mock_location=false 61 | permissions/access_network_state=false 62 | permissions/access_surface_flinger=false 63 | permissions/access_wifi_state=false 64 | permissions/account_manager=false 65 | permissions/add_voicemail=false 66 | permissions/authenticate_accounts=false 67 | permissions/battery_stats=false 68 | permissions/bind_accessibility_service=false 69 | permissions/bind_appwidget=false 70 | permissions/bind_device_admin=false 71 | permissions/bind_input_method=false 72 | permissions/bind_nfc_service=false 73 | permissions/bind_notification_listener_service=false 74 | permissions/bind_print_service=false 75 | permissions/bind_remoteviews=false 76 | permissions/bind_text_service=false 77 | permissions/bind_vpn_service=false 78 | permissions/bind_wallpaper=false 79 | permissions/bluetooth=false 80 | permissions/bluetooth_admin=false 81 | permissions/bluetooth_privileged=false 82 | permissions/brick=false 83 | permissions/broadcast_package_removed=false 84 | permissions/broadcast_sms=false 85 | permissions/broadcast_sticky=false 86 | permissions/broadcast_wap_push=false 87 | permissions/call_phone=false 88 | permissions/call_privileged=false 89 | permissions/camera=false 90 | permissions/capture_audio_output=false 91 | permissions/capture_secure_video_output=false 92 | permissions/capture_video_output=false 93 | permissions/change_component_enabled_state=false 94 | permissions/change_configuration=false 95 | permissions/change_network_state=false 96 | permissions/change_wifi_multicast_state=true 97 | permissions/change_wifi_state=false 98 | permissions/clear_app_cache=false 99 | permissions/clear_app_user_data=false 100 | permissions/control_location_updates=false 101 | permissions/delete_cache_files=false 102 | permissions/delete_packages=false 103 | permissions/device_power=false 104 | permissions/diagnostic=false 105 | permissions/disable_keyguard=false 106 | permissions/dump=false 107 | permissions/expand_status_bar=false 108 | permissions/factory_test=false 109 | permissions/flashlight=false 110 | permissions/force_back=false 111 | permissions/get_accounts=false 112 | permissions/get_package_size=false 113 | permissions/get_tasks=false 114 | permissions/get_top_activity_info=false 115 | permissions/global_search=false 116 | permissions/hardware_test=false 117 | permissions/inject_events=false 118 | permissions/install_location_provider=false 119 | permissions/install_packages=false 120 | permissions/install_shortcut=false 121 | permissions/internal_system_window=false 122 | permissions/internet=true 123 | permissions/kill_background_processes=false 124 | permissions/location_hardware=false 125 | permissions/manage_accounts=false 126 | permissions/manage_app_tokens=false 127 | permissions/manage_documents=false 128 | permissions/master_clear=false 129 | permissions/media_content_control=false 130 | permissions/modify_audio_settings=false 131 | permissions/modify_phone_state=false 132 | permissions/mount_format_filesystems=false 133 | permissions/mount_unmount_filesystems=false 134 | permissions/nfc=false 135 | permissions/persistent_activity=false 136 | permissions/process_outgoing_calls=false 137 | permissions/read_calendar=false 138 | permissions/read_call_log=false 139 | permissions/read_contacts=false 140 | permissions/read_external_storage=false 141 | permissions/read_frame_buffer=false 142 | permissions/read_history_bookmarks=false 143 | permissions/read_input_state=false 144 | permissions/read_logs=false 145 | permissions/read_phone_state=false 146 | permissions/read_profile=false 147 | permissions/read_sms=false 148 | permissions/read_social_stream=false 149 | permissions/read_sync_settings=false 150 | permissions/read_sync_stats=false 151 | permissions/read_user_dictionary=false 152 | permissions/reboot=false 153 | permissions/receive_boot_completed=false 154 | permissions/receive_mms=false 155 | permissions/receive_sms=false 156 | permissions/receive_wap_push=false 157 | permissions/record_audio=false 158 | permissions/reorder_tasks=false 159 | permissions/restart_packages=false 160 | permissions/send_respond_via_message=false 161 | permissions/send_sms=false 162 | permissions/set_activity_watcher=false 163 | permissions/set_alarm=false 164 | permissions/set_always_finish=false 165 | permissions/set_animation_scale=false 166 | permissions/set_debug_app=false 167 | permissions/set_orientation=false 168 | permissions/set_pointer_speed=false 169 | permissions/set_preferred_applications=false 170 | permissions/set_process_limit=false 171 | permissions/set_time=false 172 | permissions/set_time_zone=false 173 | permissions/set_wallpaper=false 174 | permissions/set_wallpaper_hints=false 175 | permissions/signal_persistent_processes=false 176 | permissions/status_bar=false 177 | permissions/subscribed_feeds_read=false 178 | permissions/subscribed_feeds_write=false 179 | permissions/system_alert_window=false 180 | permissions/transmit_ir=false 181 | permissions/uninstall_shortcut=false 182 | permissions/update_device_stats=false 183 | permissions/use_credentials=false 184 | permissions/use_sip=false 185 | permissions/vibrate=false 186 | permissions/wake_lock=false 187 | permissions/write_apn_settings=false 188 | permissions/write_calendar=false 189 | permissions/write_call_log=false 190 | permissions/write_contacts=false 191 | permissions/write_external_storage=false 192 | permissions/write_gservices=false 193 | permissions/write_history_bookmarks=false 194 | permissions/write_profile=false 195 | permissions/write_secure_settings=false 196 | permissions/write_settings=false 197 | permissions/write_sms=false 198 | permissions/write_social_stream=false 199 | permissions/write_sync_settings=false 200 | permissions/write_user_dictionary=false 201 | -------------------------------------------------------------------------------- /Game.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=11 format=2] 2 | 3 | [ext_resource path="res://Tilesheet.png" type="Texture" id=1] 4 | [ext_resource path="res://Game.gd" type="Script" id=2] 5 | [ext_resource path="res://Camera2D.gd" type="Script" id=3] 6 | [ext_resource path="res://UI.gd" type="Script" id=4] 7 | [ext_resource path="res://Winner.gd" type="Script" id=5] 8 | [ext_resource path="res://Down Hill.ttf" type="DynamicFontData" id=6] 9 | [ext_resource path="res://Game_UI.gd" type="Script" id=7] 10 | 11 | [sub_resource type="ConvexPolygonShape2D" id=3] 12 | points = PoolVector2Array( 0, 0, 128, 0, 128, 128, 0, 128 ) 13 | 14 | [sub_resource type="TileSet" id=1] 15 | resource_local_to_scene = true 16 | 0/name = "Tilesheet.png 0" 17 | 0/texture = ExtResource( 1 ) 18 | 0/tex_offset = Vector2( 0, 0 ) 19 | 0/modulate = Color( 1, 1, 1, 1 ) 20 | 0/region = Rect2( 0, 0, 128, 128 ) 21 | 0/tile_mode = 0 22 | 0/occluder_offset = Vector2( 0, 0 ) 23 | 0/navigation_offset = Vector2( 0, 0 ) 24 | 0/shape_offset = Vector2( 0, 0 ) 25 | 0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) 26 | 0/shape_one_way = false 27 | 0/shape_one_way_margin = 0.0 28 | 0/shapes = [ ] 29 | 0/z_index = 0 30 | 1/name = "Tilesheet.png 1" 31 | 1/texture = ExtResource( 1 ) 32 | 1/tex_offset = Vector2( 0, 0 ) 33 | 1/modulate = Color( 1, 1, 1, 1 ) 34 | 1/region = Rect2( 512, 0, 128, 128 ) 35 | 1/tile_mode = 0 36 | 1/occluder_offset = Vector2( 0, 0 ) 37 | 1/navigation_offset = Vector2( 0, 0 ) 38 | 1/shape_offset = Vector2( 0, 0 ) 39 | 1/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) 40 | 1/shape_one_way = false 41 | 1/shape_one_way_margin = 0.0 42 | 1/shapes = [ ] 43 | 1/z_index = 0 44 | 2/name = "Tilesheet.png 2" 45 | 2/texture = ExtResource( 1 ) 46 | 2/tex_offset = Vector2( 0, 0 ) 47 | 2/modulate = Color( 1, 1, 1, 1 ) 48 | 2/region = Rect2( 2304, 0, 128, 128 ) 49 | 2/tile_mode = 0 50 | 2/occluder_offset = Vector2( 0, 0 ) 51 | 2/navigation_offset = Vector2( 0, 0 ) 52 | 2/shape_offset = Vector2( 0, 0 ) 53 | 2/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) 54 | 2/shape = SubResource( 3 ) 55 | 2/shape_one_way = false 56 | 2/shape_one_way_margin = 1.0 57 | 2/shapes = [ { 58 | "autotile_coord": Vector2( 0, 0 ), 59 | "one_way": false, 60 | "one_way_margin": 1.0, 61 | "shape": SubResource( 3 ), 62 | "shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) 63 | } ] 64 | 2/z_index = 0 65 | 3/name = "Tilesheet.png 3" 66 | 3/texture = ExtResource( 1 ) 67 | 3/tex_offset = Vector2( 0, 0 ) 68 | 3/modulate = Color( 1, 1, 1, 1 ) 69 | 3/region = Rect2( 2432, 0, 128, 128 ) 70 | 3/tile_mode = 0 71 | 3/occluder_offset = Vector2( 0, 0 ) 72 | 3/navigation_offset = Vector2( 0, 0 ) 73 | 3/shape_offset = Vector2( 0, 0 ) 74 | 3/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) 75 | 3/shape_one_way = false 76 | 3/shape_one_way_margin = 0.0 77 | 3/shapes = [ ] 78 | 3/z_index = 0 79 | 80 | [sub_resource type="DynamicFont" id=2] 81 | size = 120 82 | outline_size = 7 83 | outline_color = Color( 0, 0, 0, 1 ) 84 | use_mipmaps = true 85 | use_filter = true 86 | font_data = ExtResource( 6 ) 87 | 88 | [node name="Game" type="Node2D"] 89 | script = ExtResource( 2 ) 90 | 91 | [node name="TileMap" type="TileMap" parent="."] 92 | z_index = -1 93 | tile_set = SubResource( 1 ) 94 | cell_size = Vector2( 128, 128 ) 95 | format = 1 96 | tile_data = PoolIntArray( -655373, 3, 0, -655372, 3, 0, -655371, 3, 0, -655370, 3, 0, -655369, 3, 0, -655368, 3, 0, -655367, 3, 0, -655366, 3, 0, -655365, 3, 0, -655364, 3, 0, -655363, 3, 0, -655362, 3, 0, -655361, 3, 0, -720896, 3, 0, -720895, 3, 0, -720894, 3, 0, -720893, 3, 0, -720892, 3, 0, -720891, 3, 0, -720890, 3, 0, -720889, 3, 0, -720888, 3, 0, -720887, 3, 0, -720886, 3, 0, -720885, 3, 0, -720884, 3, 0, -720883, 3, 0, -720882, 3, 0, -720881, 3, 0, -720880, 3, 0, -720879, 3, 0, -720878, 3, 0, -720877, 3, 0, -720876, 3, 0, -720875, 3, 0, -720874, 3, 0, -720873, 3, 0, -720872, 3, 0, -720871, 3, 0, -720870, 3, 0, -720869, 3, 0, -720868, 3, 0, -720867, 3, 0, -720866, 3, 0, -720865, 3, 0, -720864, 3, 0, -720863, 3, 0, -720862, 3, 0, -720861, 3, 0, -720860, 3, 0, -720859, 3, 0, -720858, 3, 0, -720857, 3, 0, -720856, 3, 0, -720855, 3, 0, -720854, 3, 0, -720853, 3, 0, -720852, 3, 0, -720851, 3, 0, -589837, 3, 0, -589836, 3, 0, -589835, 3, 0, -589834, 3, 0, -589833, 3, 0, -589832, 3, 0, -589831, 3, 0, -589830, 3, 0, -589829, 3, 0, -589828, 3, 0, -589827, 3, 0, -589826, 3, 0, -589825, 3, 0, -655360, 3, 0, -655359, 3, 0, -655358, 3, 0, -655357, 3, 0, -655356, 3, 0, -655355, 3, 0, -655354, 3, 0, -655353, 3, 0, -655352, 3, 0, -655351, 3, 0, -655350, 3, 0, -655349, 3, 0, -655348, 3, 0, -655347, 3, 0, -655346, 3, 0, -655345, 3, 0, -655344, 3, 0, -655343, 3, 0, -655342, 3, 0, -655341, 3, 0, -655340, 3, 0, -655339, 3, 0, -655338, 3, 0, -655337, 3, 0, -655336, 3, 0, -655335, 3, 0, -655334, 3, 0, -655333, 3, 0, -655332, 3, 0, -655331, 3, 0, -655330, 3, 0, -655329, 3, 0, -655328, 3, 0, -655327, 3, 0, -655326, 3, 0, -655325, 3, 0, -655324, 3, 0, -655323, 3, 0, -655322, 3, 0, -655321, 3, 0, -655320, 3, 0, -655319, 3, 0, -655318, 3, 0, -655317, 3, 0, -655316, 3, 0, -655315, 3, 0, -524301, 3, 0, -524300, 3, 0, -524299, 3, 0, -524298, 3, 0, -524297, 3, 0, -524296, 3, 0, -524295, 3, 0, -524294, 3, 0, -524293, 3, 0, -524292, 3, 0, -524291, 3, 0, -524290, 3, 0, -524289, 3, 0, -589824, 3, 0, -589823, 3, 0, -589822, 3, 0, -589821, 3, 0, -589820, 3, 0, -589819, 3, 0, -589818, 3, 0, -589817, 3, 0, -589816, 3, 0, -589815, 3, 0, -589814, 3, 0, -589813, 3, 0, -589812, 3, 0, -589811, 3, 0, -589810, 3, 0, -589809, 3, 0, -589808, 3, 0, -589807, 3, 0, -589806, 3, 0, -589805, 3, 0, -589804, 3, 0, -589803, 3, 0, -589802, 3, 0, -589801, 3, 0, -589800, 3, 0, -589799, 3, 0, -589798, 3, 0, -589797, 3, 0, -589796, 3, 0, -589795, 3, 0, -589794, 3, 0, -589793, 3, 0, -589792, 3, 0, -589791, 3, 0, -589790, 3, 0, -589789, 3, 0, -589788, 3, 0, -589787, 3, 0, -589786, 3, 0, -589785, 3, 0, -589784, 3, 0, -589783, 3, 0, -589782, 3, 0, -589781, 3, 0, -589780, 3, 0, -589779, 3, 0, -458765, 3, 0, -458764, 3, 0, -458763, 3, 0, -458762, 3, 0, -458761, 3, 0, -458760, 3, 0, -458759, 3, 0, -458758, 3, 0, -458757, 3, 0, -458756, 3, 0, -458755, 3, 0, -458754, 3, 0, -458753, 3, 0, -524288, 3, 0, -524287, 3, 0, -524286, 3, 0, -524285, 3, 0, -524284, 3, 0, -524283, 3, 0, -524282, 3, 0, -524281, 3, 0, -524280, 3, 0, -524279, 3, 0, -524278, 3, 0, -524277, 3, 0, -524276, 3, 0, -524275, 3, 0, -524274, 3, 0, -524273, 3, 0, -524272, 3, 0, -524271, 3, 0, -524270, 3, 0, -524269, 3, 0, -524268, 3, 0, -524267, 3, 0, -524266, 3, 0, -524265, 3, 0, -524264, 3, 0, -524263, 3, 0, -524262, 3, 0, -524261, 3, 0, -524260, 3, 0, -524259, 3, 0, -524258, 3, 0, -524257, 3, 0, -524256, 3, 0, -524255, 3, 0, -524254, 3, 0, -524253, 3, 0, -524252, 3, 0, -524251, 3, 0, -524250, 3, 0, -524249, 3, 0, -524248, 3, 0, -524247, 3, 0, -524246, 3, 0, -524245, 3, 0, -524244, 3, 0, -524243, 3, 0, -393229, 3, 0, -393228, 3, 0, -393227, 3, 0, -393226, 3, 0, -393225, 3, 0, -393224, 3, 0, -393223, 3, 0, -393222, 3, 0, -393221, 3, 0, -393220, 3, 0, -393219, 3, 0, -393218, 3, 0, -393217, 3, 0, -458752, 3, 0, -458751, 3, 0, -458750, 3, 0, -458749, 3, 0, -458748, 3, 0, -458747, 3, 0, -458746, 3, 0, -458745, 3, 0, -458744, 3, 0, -458743, 3, 0, -458742, 3, 0, -458741, 3, 0, -458740, 3, 0, -458739, 3, 0, -458738, 3, 0, -458737, 3, 0, -458736, 3, 0, -458735, 3, 0, -458734, 3, 0, -458733, 3, 0, -458732, 3, 0, -458731, 3, 0, -458730, 3, 0, -458729, 3, 0, -458728, 3, 0, -458727, 3, 0, -458726, 3, 0, -458725, 3, 0, -458724, 3, 0, -458723, 3, 0, -458722, 3, 0, -458721, 3, 0, -458720, 3, 0, -458719, 3, 0, -458718, 3, 0, -458717, 3, 0, -458716, 3, 0, -458715, 3, 0, -458714, 3, 0, -458713, 3, 0, -458712, 3, 0, -458711, 3, 0, -458710, 3, 0, -458709, 3, 0, -458708, 3, 0, -458707, 3, 0, -327693, 3, 0, -327692, 3, 0, -327691, 3, 0, -327690, 3, 0, -327689, 3, 0, -327688, 3, 0, -327687, 3, 0, -327686, 3, 0, -327685, 3, 0, -327684, 3, 0, -327683, 3, 0, -327682, 3, 0, -327681, 3, 0, -393216, 3, 0, -393215, 3, 0, -393214, 3, 0, -393213, 3, 0, -393212, 3, 0, -393211, 3, 0, -393210, 3, 0, -393209, 3, 0, -393208, 3, 0, -393207, 3, 0, -393206, 3, 0, -393205, 3, 0, -393204, 3, 0, -393203, 3, 0, -393202, 3, 0, -393201, 3, 0, -393200, 3, 0, -393199, 3, 0, -393198, 3, 0, -393197, 3, 0, -393196, 3, 0, -393195, 3, 0, -393194, 3, 0, -393193, 3, 0, -393192, 3, 0, -393191, 3, 0, -393190, 3, 0, -393189, 3, 0, -393188, 3, 0, -393187, 3, 0, -393186, 3, 0, -393185, 3, 0, -393184, 3, 0, -393183, 3, 0, -393182, 3, 0, -393181, 3, 0, -393180, 3, 0, -393179, 3, 0, -393178, 3, 0, -393177, 3, 0, -393176, 3, 0, -393175, 3, 0, -393174, 3, 0, -393173, 3, 0, -393172, 3, 0, -393171, 3, 0, -262157, 3, 0, -262156, 3, 0, -262155, 3, 0, -262154, 3, 0, -262153, 3, 0, -262152, 3, 0, -262151, 3, 0, -262150, 3, 0, -262149, 3, 0, -262148, 3, 0, -262147, 3, 0, -262146, 3, 0, -262145, 3, 0, -327680, 3, 0, -327679, 3, 0, -327678, 3, 0, -327677, 3, 0, -327676, 3, 0, -327675, 3, 0, -327674, 3, 0, -327673, 3, 0, -327672, 3, 0, -327671, 3, 0, -327670, 3, 0, -327669, 3, 0, -327668, 3, 0, -327667, 3, 0, -327666, 3, 0, -327665, 3, 0, -327664, 3, 0, -327663, 3, 0, -327662, 3, 0, -327661, 3, 0, -327660, 3, 0, -327659, 3, 0, -327658, 3, 0, -327657, 3, 0, -327656, 3, 0, -327655, 3, 0, -327654, 3, 0, -327653, 3, 0, -327652, 3, 0, -327651, 3, 0, -327650, 3, 0, -327649, 3, 0, -327648, 3, 0, -327647, 3, 0, -327646, 3, 0, -327645, 3, 0, -327644, 3, 0, -327643, 3, 0, -327642, 3, 0, -327641, 3, 0, -327640, 3, 0, -327639, 3, 0, -327638, 3, 0, -327637, 3, 0, -327636, 3, 0, -327635, 3, 0, -196621, 3, 0, -196620, 3, 0, -196619, 3, 0, -196618, 3, 0, -196617, 3, 0, -196616, 3, 0, -196615, 3, 0, -196614, 3, 0, -196613, 3, 0, -196612, 3, 0, -196611, 3, 0, -196610, 3, 0, -196609, 3, 0, -262144, 3, 0, -262143, 3, 0, -262142, 3, 0, -262141, 3, 0, -262140, 3, 0, -262139, 3, 0, -262138, 3, 0, -262137, 3, 0, -262136, 3, 0, -262135, 3, 0, -262134, 3, 0, -262133, 3, 0, -262132, 3, 0, -262131, 3, 0, -262130, 3, 0, -262129, 3, 0, -262128, 3, 0, -262127, 3, 0, -262126, 3, 0, -262125, 3, 0, -262124, 3, 0, -262123, 3, 0, -262122, 3, 0, -262121, 3, 0, -262120, 3, 0, -262119, 3, 0, -262118, 3, 0, -262117, 3, 0, -262116, 3, 0, -262115, 3, 0, -262114, 3, 0, -262113, 3, 0, -262112, 3, 0, -262111, 3, 0, -262110, 3, 0, -262109, 3, 0, -262108, 3, 0, -262107, 3, 0, -262106, 3, 0, -262105, 3, 0, -262104, 3, 0, -262103, 3, 0, -262102, 3, 0, -262101, 3, 0, -262100, 3, 0, -262099, 3, 0, -131085, 3, 0, -131084, 3, 0, -131083, 3, 0, -131082, 3, 0, -131081, 3, 0, -131080, 3, 0, -131079, 3, 0, -131078, 3, 0, -131077, 3, 0, -131076, 3, 0, -131075, 2, 0, -131074, 2, 0, -131073, 2, 0, -196608, 2, 0, -196607, 2, 0, -196606, 2, 0, -196605, 2, 0, -196604, 2, 0, -196603, 2, 0, -196602, 2, 0, -196601, 2, 0, -196600, 2, 0, -196599, 2, 0, -196598, 2, 0, -196597, 2, 0, -196596, 2, 0, -196595, 2, 0, -196594, 2, 0, -196593, 2, 0, -196592, 2, 0, -196591, 2, 0, -196590, 2, 0, -196589, 2, 0, -196588, 2, 0, -196587, 2, 0, -196586, 2, 0, -196585, 2, 0, -196584, 2, 0, -196583, 2, 0, -196582, 2, 0, -196581, 2, 0, -196580, 2, 0, -196579, 2, 0, -196578, 2, 0, -196577, 2, 0, -196576, 2, 0, -196575, 2, 0, -196574, 2, 0, -196573, 3, 0, -196572, 3, 0, -196571, 3, 0, -196570, 3, 0, -196569, 3, 0, -196568, 3, 0, -196567, 3, 0, -196566, 3, 0, -196565, 3, 0, -196564, 3, 0, -196563, 3, 0, -65549, 3, 0, -65548, 3, 0, -65547, 3, 0, -65546, 3, 0, -65545, 3, 0, -65544, 3, 0, -65543, 3, 0, -65542, 3, 0, -65541, 3, 0, -65540, 3, 0, -65539, 2, 0, -65538, 1, 0, -65537, 1, 0, -131072, 1, 0, -131071, 1, 0, -131070, 1, 0, -131069, 1, 0, -131068, 1, 0, -131067, 1, 0, -131066, 1, 0, -131065, 1, 0, -131064, 1, 0, -131063, 1, 0, -131062, 1, 0, -131061, 1, 0, -131060, 1, 0, -131059, 1, 0, -131058, 1, 0, -131057, 1, 0, -131056, 1, 0, -131055, 1, 0, -131054, 1, 0, -131053, 1, 0, -131052, 1, 0, -131051, 1, 0, -131050, 1, 0, -131049, 1, 0, -131048, 1, 0, -131047, 1, 0, -131046, 1, 0, -131045, 1, 0, -131044, 1, 0, -131043, 1, 0, -131042, 1, 0, -131041, 1, 0, -131040, 1, 0, -131039, 1, 0, -131038, 2, 0, -131037, 3, 0, -131036, 3, 0, -131035, 3, 0, -131034, 3, 0, -131033, 3, 0, -131032, 3, 0, -131031, 3, 0, -131030, 3, 0, -131029, 3, 0, -131028, 3, 0, -131027, 3, 0, -13, 3, 0, -12, 3, 0, -11, 3, 0, -10, 3, 0, -9, 3, 0, -8, 3, 0, -7, 3, 0, -6, 3, 0, -5, 3, 0, -4, 3, 0, -3, 2, 0, -2, 1, 0, -1, 1, 0, -65536, 1, 0, -65535, 1, 0, -65534, 1, 0, -65533, 1, 0, -65532, 1, 0, -65531, 1, 0, -65530, 1, 0, -65529, 1, 0, -65528, 1, 0, -65527, 1, 0, -65526, 1, 0, -65525, 1, 0, -65524, 1, 0, -65523, 1, 0, -65522, 1, 0, -65521, 1, 0, -65520, 1, 0, -65519, 1, 0, -65518, 1, 0, -65517, 1, 0, -65516, 1, 0, -65515, 1, 0, -65514, 1, 0, -65513, 1, 0, -65512, 1, 0, -65511, 1, 0, -65510, 1, 0, -65509, 1, 0, -65508, 1, 0, -65507, 1, 0, -65506, 1, 0, -65505, 1, 0, -65504, 1, 0, -65503, 1, 0, -65502, 2, 0, -65501, 3, 0, -65500, 3, 0, -65499, 3, 0, -65498, 3, 0, -65497, 3, 0, -65496, 3, 0, -65495, 3, 0, -65494, 3, 0, -65493, 3, 0, -65492, 3, 0, -65491, 3, 0, 65523, 3, 0, 65524, 3, 0, 65525, 3, 0, 65526, 3, 0, 65527, 3, 0, 65528, 3, 0, 65529, 3, 0, 65530, 3, 0, 65531, 3, 0, 65532, 3, 0, 65533, 2, 0, 65534, 1, 0, 65535, 1, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 0, 5, 0, 0, 6, 0, 0, 7, 0, 0, 8, 0, 0, 9, 0, 0, 10, 0, 0, 11, 0, 0, 12, 0, 0, 13, 0, 0, 14, 0, 0, 15, 0, 0, 16, 0, 0, 17, 0, 0, 18, 0, 0, 19, 0, 0, 20, 0, 0, 21, 0, 0, 22, 0, 0, 23, 0, 0, 24, 0, 0, 25, 0, 0, 26, 0, 0, 27, 0, 0, 28, 0, 0, 29, 0, 0, 30, 0, 0, 31, 0, 0, 32, 1, 0, 33, 1, 0, 34, 2, 0, 35, 3, 0, 36, 3, 0, 37, 3, 0, 38, 3, 0, 39, 3, 0, 40, 3, 0, 41, 3, 0, 42, 3, 0, 43, 3, 0, 44, 3, 0, 45, 3, 0, 131059, 3, 0, 131060, 3, 0, 131061, 3, 0, 131062, 3, 0, 131063, 3, 0, 131064, 3, 0, 131065, 3, 0, 131066, 3, 0, 131067, 3, 0, 131068, 3, 0, 131069, 2, 0, 131070, 1, 0, 131071, 1, 0, 65536, 0, 0, 65537, 0, 0, 65538, 0, 0, 65539, 0, 0, 65540, 0, 0, 65541, 0, 0, 65542, 0, 0, 65543, 0, 0, 65544, 0, 0, 65545, 0, 0, 65546, 0, 0, 65547, 0, 0, 65548, 0, 0, 65549, 0, 0, 65550, 0, 0, 65551, 0, 0, 65552, 0, 0, 65553, 0, 0, 65554, 0, 0, 65555, 0, 0, 65556, 0, 0, 65557, 0, 0, 65558, 0, 0, 65559, 0, 0, 65560, 0, 0, 65561, 0, 0, 65562, 0, 0, 65563, 0, 0, 65564, 0, 0, 65565, 0, 0, 65566, 0, 0, 65567, 0, 0, 65568, 1, 0, 65569, 1, 0, 65570, 2, 0, 65571, 3, 0, 65572, 3, 0, 65573, 3, 0, 65574, 3, 0, 65575, 3, 0, 65576, 3, 0, 65577, 3, 0, 65578, 3, 0, 65579, 3, 0, 65580, 3, 0, 65581, 3, 0, 196595, 3, 0, 196596, 3, 0, 196597, 3, 0, 196598, 3, 0, 196599, 3, 0, 196600, 3, 0, 196601, 3, 0, 196602, 3, 0, 196603, 3, 0, 196604, 3, 0, 196605, 2, 0, 196606, 1, 0, 196607, 1, 0, 131072, 0, 0, 131073, 0, 0, 131074, 0, 0, 131075, 0, 0, 131076, 0, 0, 131077, 0, 0, 131078, 0, 0, 131079, 0, 0, 131080, 0, 0, 131081, 0, 0, 131082, 0, 0, 131083, 0, 0, 131084, 0, 0, 131085, 0, 0, 131086, 0, 0, 131087, 0, 0, 131088, 0, 0, 131089, 0, 0, 131090, 0, 0, 131091, 0, 0, 131092, 0, 0, 131093, 0, 0, 131094, 0, 0, 131095, 0, 0, 131096, 0, 0, 131097, 0, 0, 131098, 0, 0, 131099, 0, 0, 131100, 0, 0, 131101, 0, 0, 131102, 0, 0, 131103, 0, 0, 131104, 1, 0, 131105, 1, 0, 131106, 2, 0, 131107, 3, 0, 131108, 3, 0, 131109, 3, 0, 131110, 3, 0, 131111, 3, 0, 131112, 3, 0, 131113, 3, 0, 131114, 3, 0, 131115, 3, 0, 131116, 3, 0, 131117, 3, 0, 262131, 3, 0, 262132, 3, 0, 262133, 3, 0, 262134, 3, 0, 262135, 3, 0, 262136, 3, 0, 262137, 3, 0, 262138, 3, 0, 262139, 3, 0, 262140, 3, 0, 262141, 2, 0, 262142, 1, 0, 262143, 1, 0, 196608, 0, 0, 196609, 0, 0, 196610, 0, 0, 196611, 0, 0, 196612, 0, 0, 196613, 0, 0, 196614, 0, 0, 196615, 0, 0, 196616, 0, 0, 196617, 0, 0, 196618, 0, 0, 196619, 0, 0, 196620, 0, 0, 196621, 0, 0, 196622, 0, 0, 196623, 0, 0, 196624, 0, 0, 196625, 0, 0, 196626, 0, 0, 196627, 0, 0, 196628, 0, 0, 196629, 0, 0, 196630, 0, 0, 196631, 0, 0, 196632, 0, 0, 196633, 0, 0, 196634, 0, 0, 196635, 0, 0, 196636, 0, 0, 196637, 0, 0, 196638, 0, 0, 196639, 0, 0, 196640, 1, 0, 196641, 1, 0, 196642, 2, 0, 196643, 3, 0, 196644, 3, 0, 196645, 3, 0, 196646, 3, 0, 196647, 3, 0, 196648, 3, 0, 196649, 3, 0, 196650, 3, 0, 196651, 3, 0, 196652, 3, 0, 196653, 3, 0, 327667, 3, 0, 327668, 3, 0, 327669, 3, 0, 327670, 3, 0, 327671, 3, 0, 327672, 3, 0, 327673, 3, 0, 327674, 3, 0, 327675, 3, 0, 327676, 3, 0, 327677, 2, 0, 327678, 1, 0, 327679, 1, 0, 262144, 0, 0, 262145, 0, 0, 262146, 0, 0, 262147, 0, 0, 262148, 0, 0, 262149, 0, 0, 262150, 0, 0, 262151, 0, 0, 262152, 0, 0, 262153, 0, 0, 262154, 0, 0, 262155, 0, 0, 262156, 0, 0, 262157, 0, 0, 262158, 0, 0, 262159, 0, 0, 262160, 0, 0, 262161, 0, 0, 262162, 0, 0, 262163, 0, 0, 262164, 0, 0, 262165, 0, 0, 262166, 0, 0, 262167, 0, 0, 262168, 0, 0, 262169, 0, 0, 262170, 0, 0, 262171, 0, 0, 262172, 0, 0, 262173, 0, 0, 262174, 0, 0, 262175, 0, 0, 262176, 1, 0, 262177, 1, 0, 262178, 2, 0, 262179, 3, 0, 262180, 3, 0, 262181, 3, 0, 262182, 3, 0, 262183, 3, 0, 262184, 3, 0, 262185, 3, 0, 262186, 3, 0, 262187, 3, 0, 262188, 3, 0, 262189, 3, 0, 393203, 3, 0, 393204, 3, 0, 393205, 3, 0, 393206, 3, 0, 393207, 3, 0, 393208, 3, 0, 393209, 3, 0, 393210, 3, 0, 393211, 3, 0, 393212, 3, 0, 393213, 2, 0, 393214, 1, 0, 393215, 1, 0, 327680, 0, 0, 327681, 0, 0, 327682, 0, 0, 327683, 0, 0, 327684, 0, 0, 327685, 0, 0, 327686, 0, 0, 327687, 0, 0, 327688, 0, 0, 327689, 0, 0, 327690, 0, 0, 327691, 0, 0, 327692, 0, 0, 327693, 0, 0, 327694, 0, 0, 327695, 0, 0, 327696, 0, 0, 327697, 0, 0, 327698, 0, 0, 327699, 0, 0, 327700, 0, 0, 327701, 0, 0, 327702, 0, 0, 327703, 0, 0, 327704, 0, 0, 327705, 0, 0, 327706, 0, 0, 327707, 0, 0, 327708, 0, 0, 327709, 0, 0, 327710, 0, 0, 327711, 0, 0, 327712, 1, 0, 327713, 1, 0, 327714, 2, 0, 327715, 3, 0, 327716, 3, 0, 327717, 3, 0, 327718, 3, 0, 327719, 3, 0, 327720, 3, 0, 327721, 3, 0, 327722, 3, 0, 327723, 3, 0, 327724, 3, 0, 327725, 3, 0, 458739, 3, 0, 458740, 3, 0, 458741, 3, 0, 458742, 3, 0, 458743, 3, 0, 458744, 3, 0, 458745, 3, 0, 458746, 3, 0, 458747, 3, 0, 458748, 3, 0, 458749, 2, 0, 458750, 1, 0, 458751, 1, 0, 393216, 0, 0, 393217, 0, 0, 393218, 0, 0, 393219, 0, 0, 393220, 0, 0, 393221, 0, 0, 393222, 0, 0, 393223, 0, 0, 393224, 0, 0, 393225, 0, 0, 393226, 0, 0, 393227, 0, 0, 393228, 0, 0, 393229, 0, 0, 393230, 0, 0, 393231, 0, 0, 393232, 0, 0, 393233, 0, 0, 393234, 0, 0, 393235, 0, 0, 393236, 0, 0, 393237, 0, 0, 393238, 0, 0, 393239, 0, 0, 393240, 0, 0, 393241, 0, 0, 393242, 0, 0, 393243, 0, 0, 393244, 0, 0, 393245, 0, 0, 393246, 0, 0, 393247, 0, 0, 393248, 1, 0, 393249, 1, 0, 393250, 2, 0, 393251, 3, 0, 393252, 3, 0, 393253, 3, 0, 393254, 3, 0, 393255, 3, 0, 393256, 3, 0, 393257, 3, 0, 393258, 3, 0, 393259, 3, 0, 393260, 3, 0, 393261, 3, 0, 524275, 3, 0, 524276, 3, 0, 524277, 3, 0, 524278, 3, 0, 524279, 3, 0, 524280, 3, 0, 524281, 3, 0, 524282, 3, 0, 524283, 3, 0, 524284, 3, 0, 524285, 2, 0, 524286, 1, 0, 524287, 1, 0, 458752, 0, 0, 458753, 0, 0, 458754, 0, 0, 458755, 0, 0, 458756, 0, 0, 458757, 0, 0, 458758, 0, 0, 458759, 0, 0, 458760, 0, 0, 458761, 0, 0, 458762, 0, 0, 458763, 0, 0, 458764, 0, 0, 458765, 0, 0, 458766, 0, 0, 458767, 0, 0, 458768, 0, 0, 458769, 0, 0, 458770, 0, 0, 458771, 0, 0, 458772, 0, 0, 458773, 0, 0, 458774, 0, 0, 458775, 0, 0, 458776, 0, 0, 458777, 0, 0, 458778, 0, 0, 458779, 0, 0, 458780, 0, 0, 458781, 0, 0, 458782, 0, 0, 458783, 0, 0, 458784, 1, 0, 458785, 1, 0, 458786, 2, 0, 458787, 3, 0, 458788, 3, 0, 458789, 3, 0, 458790, 3, 0, 458791, 3, 0, 458792, 3, 0, 458793, 3, 0, 458794, 3, 0, 458795, 3, 0, 458796, 3, 0, 458797, 3, 0, 589811, 3, 0, 589812, 3, 0, 589813, 3, 0, 589814, 3, 0, 589815, 3, 0, 589816, 3, 0, 589817, 3, 0, 589818, 3, 0, 589819, 3, 0, 589820, 3, 0, 589821, 2, 0, 589822, 1, 0, 589823, 1, 0, 524288, 0, 0, 524289, 0, 0, 524290, 0, 0, 524291, 0, 0, 524292, 0, 0, 524293, 0, 0, 524294, 0, 0, 524295, 0, 0, 524296, 0, 0, 524297, 0, 0, 524298, 0, 0, 524299, 0, 0, 524300, 0, 0, 524301, 0, 0, 524302, 0, 0, 524303, 0, 0, 524304, 0, 0, 524305, 0, 0, 524306, 0, 0, 524307, 0, 0, 524308, 0, 0, 524309, 0, 0, 524310, 0, 0, 524311, 0, 0, 524312, 0, 0, 524313, 0, 0, 524314, 0, 0, 524315, 0, 0, 524316, 0, 0, 524317, 0, 0, 524318, 0, 0, 524319, 0, 0, 524320, 1, 0, 524321, 1, 0, 524322, 2, 0, 524323, 3, 0, 524324, 3, 0, 524325, 3, 0, 524326, 3, 0, 524327, 3, 0, 524328, 3, 0, 524329, 3, 0, 524330, 3, 0, 524331, 3, 0, 524332, 3, 0, 524333, 3, 0, 655347, 3, 0, 655348, 3, 0, 655349, 3, 0, 655350, 3, 0, 655351, 3, 0, 655352, 3, 0, 655353, 3, 0, 655354, 3, 0, 655355, 3, 0, 655356, 3, 0, 655357, 2, 0, 655358, 1, 0, 655359, 1, 0, 589824, 0, 0, 589825, 0, 0, 589826, 0, 0, 589827, 0, 0, 589828, 0, 0, 589829, 0, 0, 589830, 0, 0, 589831, 0, 0, 589832, 0, 0, 589833, 0, 0, 589834, 0, 0, 589835, 0, 0, 589836, 0, 0, 589837, 0, 0, 589838, 0, 0, 589839, 0, 0, 589840, 0, 0, 589841, 0, 0, 589842, 0, 0, 589843, 0, 0, 589844, 0, 0, 589845, 0, 0, 589846, 0, 0, 589847, 0, 0, 589848, 0, 0, 589849, 0, 0, 589850, 0, 0, 589851, 0, 0, 589852, 0, 0, 589853, 0, 0, 589854, 0, 0, 589855, 0, 0, 589856, 1, 0, 589857, 1, 0, 589858, 2, 0, 589859, 3, 0, 589860, 3, 0, 589861, 3, 0, 589862, 3, 0, 589863, 3, 0, 589864, 3, 0, 589865, 3, 0, 589866, 3, 0, 589867, 3, 0, 589868, 3, 0, 589869, 3, 0, 720883, 3, 0, 720884, 3, 0, 720885, 3, 0, 720886, 3, 0, 720887, 3, 0, 720888, 3, 0, 720889, 3, 0, 720890, 3, 0, 720891, 3, 0, 720892, 3, 0, 720893, 2, 0, 720894, 1, 0, 720895, 1, 0, 655360, 0, 0, 655361, 0, 0, 655362, 0, 0, 655363, 0, 0, 655364, 0, 0, 655365, 0, 0, 655366, 0, 0, 655367, 0, 0, 655368, 0, 0, 655369, 0, 0, 655370, 0, 0, 655371, 0, 0, 655372, 0, 0, 655373, 0, 0, 655374, 0, 0, 655375, 0, 0, 655376, 0, 0, 655377, 0, 0, 655378, 0, 0, 655379, 0, 0, 655380, 0, 0, 655381, 0, 0, 655382, 0, 0, 655383, 0, 0, 655384, 0, 0, 655385, 0, 0, 655386, 0, 0, 655387, 0, 0, 655388, 0, 0, 655389, 0, 0, 655390, 0, 0, 655391, 0, 0, 655392, 1, 0, 655393, 1, 0, 655394, 2, 0, 655395, 3, 0, 655396, 3, 0, 655397, 3, 0, 655398, 3, 0, 655399, 3, 0, 655400, 3, 0, 655401, 3, 0, 655402, 3, 0, 655403, 3, 0, 655404, 3, 0, 655405, 3, 0, 786419, 3, 0, 786420, 3, 0, 786421, 3, 0, 786422, 3, 0, 786423, 3, 0, 786424, 3, 0, 786425, 3, 0, 786426, 3, 0, 786427, 3, 0, 786428, 3, 0, 786429, 2, 0, 786430, 1, 0, 786431, 1, 0, 720896, 0, 0, 720897, 0, 0, 720898, 0, 0, 720899, 0, 0, 720900, 0, 0, 720901, 0, 0, 720902, 0, 0, 720903, 0, 0, 720904, 0, 0, 720905, 0, 0, 720906, 0, 0, 720907, 0, 0, 720908, 0, 0, 720909, 0, 0, 720910, 0, 0, 720911, 0, 0, 720912, 0, 0, 720913, 0, 0, 720914, 0, 0, 720915, 0, 0, 720916, 0, 0, 720917, 0, 0, 720918, 0, 0, 720919, 0, 0, 720920, 0, 0, 720921, 0, 0, 720922, 0, 0, 720923, 0, 0, 720924, 0, 0, 720925, 0, 0, 720926, 0, 0, 720927, 0, 0, 720928, 1, 0, 720929, 1, 0, 720930, 2, 0, 720931, 3, 0, 720932, 3, 0, 720933, 3, 0, 720934, 3, 0, 720935, 3, 0, 720936, 3, 0, 720937, 3, 0, 720938, 3, 0, 720939, 3, 0, 720940, 3, 0, 720941, 3, 0, 851955, 3, 0, 851956, 3, 0, 851957, 3, 0, 851958, 3, 0, 851959, 3, 0, 851960, 3, 0, 851961, 3, 0, 851962, 3, 0, 851963, 3, 0, 851964, 3, 0, 851965, 2, 0, 851966, 1, 0, 851967, 1, 0, 786432, 0, 0, 786433, 0, 0, 786434, 0, 0, 786435, 0, 0, 786436, 0, 0, 786437, 0, 0, 786438, 0, 0, 786439, 0, 0, 786440, 0, 0, 786441, 0, 0, 786442, 0, 0, 786443, 0, 0, 786444, 0, 0, 786445, 0, 0, 786446, 0, 0, 786447, 0, 0, 786448, 0, 0, 786449, 0, 0, 786450, 0, 0, 786451, 0, 0, 786452, 0, 0, 786453, 0, 0, 786454, 0, 0, 786455, 0, 0, 786456, 0, 0, 786457, 0, 0, 786458, 0, 0, 786459, 0, 0, 786460, 0, 0, 786461, 0, 0, 786462, 0, 0, 786463, 0, 0, 786464, 1, 0, 786465, 1, 0, 786466, 2, 0, 786467, 3, 0, 786468, 3, 0, 786469, 3, 0, 786470, 3, 0, 786471, 3, 0, 786472, 3, 0, 786473, 3, 0, 786474, 3, 0, 786475, 3, 0, 786476, 3, 0, 786477, 3, 0, 917491, 3, 0, 917492, 3, 0, 917493, 3, 0, 917494, 3, 0, 917495, 3, 0, 917496, 3, 0, 917497, 3, 0, 917498, 3, 0, 917499, 3, 0, 917500, 3, 0, 917501, 2, 0, 917502, 1, 0, 917503, 1, 0, 851968, 0, 0, 851969, 0, 0, 851970, 0, 0, 851971, 0, 0, 851972, 0, 0, 851973, 0, 0, 851974, 0, 0, 851975, 0, 0, 851976, 0, 0, 851977, 0, 0, 851978, 0, 0, 851979, 0, 0, 851980, 0, 0, 851981, 0, 0, 851982, 0, 0, 851983, 0, 0, 851984, 0, 0, 851985, 0, 0, 851986, 0, 0, 851987, 0, 0, 851988, 0, 0, 851989, 0, 0, 851990, 0, 0, 851991, 0, 0, 851992, 0, 0, 851993, 0, 0, 851994, 0, 0, 851995, 0, 0, 851996, 0, 0, 851997, 0, 0, 851998, 0, 0, 851999, 0, 0, 852000, 1, 0, 852001, 1, 0, 852002, 2, 0, 852003, 3, 0, 852004, 3, 0, 852005, 3, 0, 852006, 3, 0, 852007, 3, 0, 852008, 3, 0, 852009, 3, 0, 852010, 3, 0, 852011, 3, 0, 852012, 3, 0, 852013, 3, 0, 983027, 3, 0, 983028, 3, 0, 983029, 3, 0, 983030, 3, 0, 983031, 3, 0, 983032, 3, 0, 983033, 3, 0, 983034, 3, 0, 983035, 3, 0, 983036, 3, 0, 983037, 2, 0, 983038, 1, 0, 983039, 1, 0, 917504, 0, 0, 917505, 0, 0, 917506, 0, 0, 917507, 0, 0, 917508, 0, 0, 917509, 0, 0, 917510, 0, 0, 917511, 0, 0, 917512, 0, 0, 917513, 0, 0, 917514, 0, 0, 917515, 0, 0, 917516, 0, 0, 917517, 0, 0, 917518, 0, 0, 917519, 0, 0, 917520, 0, 0, 917521, 0, 0, 917522, 0, 0, 917523, 0, 0, 917524, 0, 0, 917525, 0, 0, 917526, 0, 0, 917527, 0, 0, 917528, 0, 0, 917529, 0, 0, 917530, 0, 0, 917531, 0, 0, 917532, 0, 0, 917533, 0, 0, 917534, 0, 0, 917535, 0, 0, 917536, 1, 0, 917537, 1, 0, 917538, 2, 0, 917539, 3, 0, 917540, 3, 0, 917541, 3, 0, 917542, 3, 0, 917543, 3, 0, 917544, 3, 0, 917545, 3, 0, 917546, 3, 0, 917547, 3, 0, 917548, 3, 0, 917549, 3, 0, 1048563, 3, 0, 1048564, 3, 0, 1048565, 3, 0, 1048566, 3, 0, 1048567, 3, 0, 1048568, 3, 0, 1048569, 3, 0, 1048570, 3, 0, 1048571, 3, 0, 1048572, 3, 0, 1048573, 2, 0, 1048574, 1, 0, 1048575, 1, 0, 983040, 0, 0, 983041, 0, 0, 983042, 0, 0, 983043, 0, 0, 983044, 0, 0, 983045, 0, 0, 983046, 0, 0, 983047, 0, 0, 983048, 0, 0, 983049, 0, 0, 983050, 0, 0, 983051, 0, 0, 983052, 0, 0, 983053, 0, 0, 983054, 0, 0, 983055, 0, 0, 983056, 0, 0, 983057, 0, 0, 983058, 0, 0, 983059, 0, 0, 983060, 0, 0, 983061, 0, 0, 983062, 0, 0, 983063, 0, 0, 983064, 0, 0, 983065, 0, 0, 983066, 0, 0, 983067, 0, 0, 983068, 0, 0, 983069, 0, 0, 983070, 0, 0, 983071, 0, 0, 983072, 1, 0, 983073, 1, 0, 983074, 2, 0, 983075, 3, 0, 983076, 3, 0, 983077, 3, 0, 983078, 3, 0, 983079, 3, 0, 983080, 3, 0, 983081, 3, 0, 983082, 3, 0, 983083, 3, 0, 983084, 3, 0, 983085, 3, 0, 1114099, 3, 0, 1114100, 3, 0, 1114101, 3, 0, 1114102, 3, 0, 1114103, 3, 0, 1114104, 3, 0, 1114105, 3, 0, 1114106, 3, 0, 1114107, 3, 0, 1114108, 3, 0, 1114109, 2, 0, 1114110, 1, 0, 1114111, 1, 0, 1048576, 0, 0, 1048577, 0, 0, 1048578, 0, 0, 1048579, 0, 0, 1048580, 0, 0, 1048581, 0, 0, 1048582, 0, 0, 1048583, 0, 0, 1048584, 0, 0, 1048585, 0, 0, 1048586, 0, 0, 1048587, 0, 0, 1048588, 0, 0, 1048589, 0, 0, 1048590, 0, 0, 1048591, 0, 0, 1048592, 0, 0, 1048593, 0, 0, 1048594, 0, 0, 1048595, 0, 0, 1048596, 0, 0, 1048597, 0, 0, 1048598, 0, 0, 1048599, 0, 0, 1048600, 0, 0, 1048601, 0, 0, 1048602, 0, 0, 1048603, 0, 0, 1048604, 0, 0, 1048605, 0, 0, 1048606, 0, 0, 1048607, 0, 0, 1048608, 1, 0, 1048609, 1, 0, 1048610, 2, 0, 1048611, 3, 0, 1048612, 3, 0, 1048613, 3, 0, 1048614, 3, 0, 1048615, 3, 0, 1048616, 3, 0, 1048617, 3, 0, 1048618, 3, 0, 1048619, 3, 0, 1048620, 3, 0, 1048621, 3, 0, 1179635, 3, 0, 1179636, 3, 0, 1179637, 3, 0, 1179638, 3, 0, 1179639, 3, 0, 1179640, 3, 0, 1179641, 3, 0, 1179642, 3, 0, 1179643, 3, 0, 1179644, 3, 0, 1179645, 2, 0, 1179646, 1, 0, 1179647, 1, 0, 1114112, 0, 0, 1114113, 0, 0, 1114114, 0, 0, 1114115, 0, 0, 1114116, 0, 0, 1114117, 0, 0, 1114118, 0, 0, 1114119, 0, 0, 1114120, 0, 0, 1114121, 0, 0, 1114122, 0, 0, 1114123, 0, 0, 1114124, 0, 0, 1114125, 0, 0, 1114126, 0, 0, 1114127, 0, 0, 1114128, 0, 0, 1114129, 0, 0, 1114130, 0, 0, 1114131, 0, 0, 1114132, 0, 0, 1114133, 0, 0, 1114134, 0, 0, 1114135, 0, 0, 1114136, 0, 0, 1114137, 0, 0, 1114138, 0, 0, 1114139, 0, 0, 1114140, 0, 0, 1114141, 0, 0, 1114142, 0, 0, 1114143, 0, 0, 1114144, 1, 0, 1114145, 1, 0, 1114146, 2, 0, 1114147, 3, 0, 1114148, 3, 0, 1114149, 3, 0, 1114150, 3, 0, 1114151, 3, 0, 1114152, 3, 0, 1114153, 3, 0, 1114154, 3, 0, 1114155, 3, 0, 1114156, 3, 0, 1114157, 3, 0, 1245171, 3, 0, 1245172, 3, 0, 1245173, 3, 0, 1245174, 3, 0, 1245175, 3, 0, 1245176, 3, 0, 1245177, 3, 0, 1245178, 3, 0, 1245179, 3, 0, 1245180, 3, 0, 1245181, 2, 0, 1245182, 1, 0, 1245183, 1, 0, 1179648, 1, 0, 1179649, 1, 0, 1179650, 1, 0, 1179651, 1, 0, 1179652, 1, 0, 1179653, 1, 0, 1179654, 1, 0, 1179655, 1, 0, 1179656, 1, 0, 1179657, 1, 0, 1179658, 1, 0, 1179659, 1, 0, 1179660, 1, 0, 1179661, 1, 0, 1179662, 1, 0, 1179663, 1, 0, 1179664, 1, 0, 1179665, 1, 0, 1179666, 1, 0, 1179667, 1, 0, 1179668, 1, 0, 1179669, 1, 0, 1179670, 1, 0, 1179671, 1, 0, 1179672, 1, 0, 1179673, 1, 0, 1179674, 1, 0, 1179675, 1, 0, 1179676, 1, 0, 1179677, 1, 0, 1179678, 1, 0, 1179679, 1, 0, 1179680, 1, 0, 1179681, 1, 0, 1179682, 2, 0, 1179683, 3, 0, 1179684, 3, 0, 1179685, 3, 0, 1179686, 3, 0, 1179687, 3, 0, 1179688, 3, 0, 1179689, 3, 0, 1179690, 3, 0, 1179691, 3, 0, 1179692, 3, 0, 1179693, 3, 0, 1310707, 3, 0, 1310708, 3, 0, 1310709, 3, 0, 1310710, 3, 0, 1310711, 3, 0, 1310712, 3, 0, 1310713, 3, 0, 1310714, 3, 0, 1310715, 3, 0, 1310716, 3, 0, 1310717, 2, 0, 1310718, 1, 0, 1310719, 1, 0, 1245184, 1, 0, 1245185, 1, 0, 1245186, 1, 0, 1245187, 1, 0, 1245188, 1, 0, 1245189, 1, 0, 1245190, 1, 0, 1245191, 1, 0, 1245192, 1, 0, 1245193, 1, 0, 1245194, 1, 0, 1245195, 1, 0, 1245196, 1, 0, 1245197, 1, 0, 1245198, 1, 0, 1245199, 1, 0, 1245200, 1, 0, 1245201, 1, 0, 1245202, 1, 0, 1245203, 1, 0, 1245204, 1, 0, 1245205, 1, 0, 1245206, 1, 0, 1245207, 1, 0, 1245208, 1, 0, 1245209, 1, 0, 1245210, 1, 0, 1245211, 1, 0, 1245212, 1, 0, 1245213, 1, 0, 1245214, 1, 0, 1245215, 1, 0, 1245216, 1, 0, 1245217, 1, 0, 1245218, 2, 0, 1245219, 3, 0, 1245220, 3, 0, 1245221, 3, 0, 1245222, 3, 0, 1245223, 3, 0, 1245224, 3, 0, 1245225, 3, 0, 1245226, 3, 0, 1245227, 3, 0, 1245228, 3, 0, 1245229, 3, 0, 1376243, 3, 0, 1376244, 3, 0, 1376245, 3, 0, 1376246, 3, 0, 1376247, 3, 0, 1376248, 3, 0, 1376249, 3, 0, 1376250, 3, 0, 1376251, 3, 0, 1376252, 3, 0, 1376253, 2, 0, 1376254, 2, 0, 1376255, 2, 0, 1310720, 2, 0, 1310721, 2, 0, 1310722, 2, 0, 1310723, 2, 0, 1310724, 2, 0, 1310725, 2, 0, 1310726, 2, 0, 1310727, 2, 0, 1310728, 2, 0, 1310729, 2, 0, 1310730, 2, 0, 1310731, 2, 0, 1310732, 2, 0, 1310733, 2, 0, 1310734, 2, 0, 1310735, 2, 0, 1310736, 2, 0, 1310737, 2, 0, 1310738, 2, 0, 1310739, 2, 0, 1310740, 2, 0, 1310741, 2, 0, 1310742, 2, 0, 1310743, 2, 0, 1310744, 2, 0, 1310745, 2, 0, 1310746, 2, 0, 1310747, 2, 0, 1310748, 2, 0, 1310749, 2, 0, 1310750, 2, 0, 1310751, 2, 0, 1310752, 2, 0, 1310753, 2, 0, 1310754, 2, 0, 1310755, 3, 0, 1310756, 3, 0, 1310757, 3, 0, 1310758, 3, 0, 1310759, 3, 0, 1310760, 3, 0, 1310761, 3, 0, 1310762, 3, 0, 1310763, 3, 0, 1310764, 3, 0, 1310765, 3, 0, 1441779, 3, 0, 1441780, 3, 0, 1441781, 3, 0, 1441782, 3, 0, 1441783, 3, 0, 1441784, 3, 0, 1441785, 3, 0, 1441786, 3, 0, 1441787, 3, 0, 1441788, 3, 0, 1441789, 3, 0, 1441790, 3, 0, 1441791, 3, 0, 1376256, 3, 0, 1376257, 3, 0, 1376258, 3, 0, 1376259, 3, 0, 1376260, 3, 0, 1376261, 3, 0, 1376262, 3, 0, 1376263, 3, 0, 1376264, 3, 0, 1376265, 3, 0, 1376266, 3, 0, 1376267, 3, 0, 1376268, 3, 0, 1376269, 3, 0, 1376270, 3, 0, 1376271, 3, 0, 1376272, 3, 0, 1376273, 3, 0, 1376274, 3, 0, 1376275, 3, 0, 1376276, 3, 0, 1376277, 3, 0, 1376278, 3, 0, 1376279, 3, 0, 1376280, 3, 0, 1376281, 3, 0, 1376282, 3, 0, 1376283, 3, 0, 1376284, 3, 0, 1376285, 3, 0, 1376286, 3, 0, 1376287, 3, 0, 1376288, 3, 0, 1376289, 3, 0, 1376290, 3, 0, 1376291, 3, 0, 1376292, 3, 0, 1376293, 3, 0, 1376294, 3, 0, 1376295, 3, 0, 1376296, 3, 0, 1376297, 3, 0, 1376298, 3, 0, 1376299, 3, 0, 1376300, 3, 0, 1376301, 3, 0, 1507315, 3, 0, 1507316, 3, 0, 1507317, 3, 0, 1507318, 3, 0, 1507319, 3, 0, 1507320, 3, 0, 1507321, 3, 0, 1507322, 3, 0, 1507323, 3, 0, 1507324, 3, 0, 1507325, 3, 0, 1507326, 3, 0, 1507327, 3, 0, 1441792, 3, 0, 1441793, 3, 0, 1441794, 3, 0, 1441795, 3, 0, 1441796, 3, 0, 1441797, 3, 0, 1441798, 3, 0, 1441799, 3, 0, 1441800, 3, 0, 1441801, 3, 0, 1441802, 3, 0, 1441803, 3, 0, 1441804, 3, 0, 1441805, 3, 0, 1441806, 3, 0, 1441807, 3, 0, 1441808, 3, 0, 1441809, 3, 0, 1441810, 3, 0, 1441811, 3, 0, 1441812, 3, 0, 1441813, 3, 0, 1441814, 3, 0, 1441815, 3, 0, 1441816, 3, 0, 1441817, 3, 0, 1441818, 3, 0, 1441819, 3, 0, 1441820, 3, 0, 1441821, 3, 0, 1441822, 3, 0, 1441823, 3, 0, 1441824, 3, 0, 1441825, 3, 0, 1441826, 3, 0, 1441827, 3, 0, 1441828, 3, 0, 1441829, 3, 0, 1441830, 3, 0, 1441831, 3, 0, 1441832, 3, 0, 1441833, 3, 0, 1441834, 3, 0, 1441835, 3, 0, 1441836, 3, 0, 1441837, 3, 0, 1572851, 3, 0, 1572852, 3, 0, 1572853, 3, 0, 1572854, 3, 0, 1572855, 3, 0, 1572856, 3, 0, 1572857, 3, 0, 1572858, 3, 0, 1572859, 3, 0, 1572860, 3, 0, 1572861, 3, 0, 1572862, 3, 0, 1572863, 3, 0, 1507328, 3, 0, 1507329, 3, 0, 1507330, 3, 0, 1507331, 3, 0, 1507332, 3, 0, 1507333, 3, 0, 1507334, 3, 0, 1507335, 3, 0, 1507336, 3, 0, 1507337, 3, 0, 1507338, 3, 0, 1507339, 3, 0, 1507340, 3, 0, 1507341, 3, 0, 1507342, 3, 0, 1507343, 3, 0, 1507344, 3, 0, 1507345, 3, 0, 1507346, 3, 0, 1507347, 3, 0, 1507348, 3, 0, 1507349, 3, 0, 1507350, 3, 0, 1507351, 3, 0, 1507352, 3, 0, 1507353, 3, 0, 1507354, 3, 0, 1507355, 3, 0, 1507356, 3, 0, 1507357, 3, 0, 1507358, 3, 0, 1507359, 3, 0, 1507360, 3, 0, 1507361, 3, 0, 1507362, 3, 0, 1507363, 3, 0, 1507364, 3, 0, 1507365, 3, 0, 1507366, 3, 0, 1507367, 3, 0, 1507368, 3, 0, 1507369, 3, 0, 1507370, 3, 0, 1507371, 3, 0, 1507372, 3, 0, 1507373, 3, 0, 1638387, 3, 0, 1638388, 3, 0, 1638389, 3, 0, 1638390, 3, 0, 1638391, 3, 0, 1638392, 3, 0, 1638393, 3, 0, 1638394, 3, 0, 1638395, 3, 0, 1638396, 3, 0, 1638397, 3, 0, 1638398, 3, 0, 1638399, 3, 0, 1572864, 3, 0, 1572865, 3, 0, 1572866, 3, 0, 1572867, 3, 0, 1572868, 3, 0, 1572869, 3, 0, 1572870, 3, 0, 1572871, 3, 0, 1572872, 3, 0, 1572873, 3, 0, 1572874, 3, 0, 1572875, 3, 0, 1572876, 3, 0, 1572877, 3, 0, 1572878, 3, 0, 1572879, 3, 0, 1572880, 3, 0, 1572881, 3, 0, 1572882, 3, 0, 1572883, 3, 0, 1572884, 3, 0, 1572885, 3, 0, 1572886, 3, 0, 1572887, 3, 0, 1572888, 3, 0, 1572889, 3, 0, 1572890, 3, 0, 1572891, 3, 0, 1572892, 3, 0, 1572893, 3, 0, 1572894, 3, 0, 1572895, 3, 0, 1572896, 3, 0, 1572897, 3, 0, 1572898, 3, 0, 1572899, 3, 0, 1572900, 3, 0, 1572901, 3, 0, 1572902, 3, 0, 1572903, 3, 0, 1572904, 3, 0, 1572905, 3, 0, 1572906, 3, 0, 1572907, 3, 0, 1572908, 3, 0, 1572909, 3, 0, 1703923, 3, 0, 1703924, 3, 0, 1703925, 3, 0, 1703926, 3, 0, 1703927, 3, 0, 1703928, 3, 0, 1703929, 3, 0, 1703930, 3, 0, 1703931, 3, 0, 1703932, 3, 0, 1703933, 3, 0, 1703934, 3, 0, 1703935, 3, 0, 1638400, 3, 0, 1638401, 3, 0, 1638402, 3, 0, 1638403, 3, 0, 1638404, 3, 0, 1638405, 3, 0, 1638406, 3, 0, 1638407, 3, 0, 1638408, 3, 0, 1638409, 3, 0, 1638410, 3, 0, 1638411, 3, 0, 1638412, 3, 0, 1638413, 3, 0, 1638414, 3, 0, 1638415, 3, 0, 1638416, 3, 0, 1638417, 3, 0, 1638418, 3, 0, 1638419, 3, 0, 1638420, 3, 0, 1638421, 3, 0, 1638422, 3, 0, 1638423, 3, 0, 1638424, 3, 0, 1638425, 3, 0, 1638426, 3, 0, 1638427, 3, 0, 1638428, 3, 0, 1638429, 3, 0, 1638430, 3, 0, 1638431, 3, 0, 1638432, 3, 0, 1638433, 3, 0, 1638434, 3, 0, 1638435, 3, 0, 1638436, 3, 0, 1638437, 3, 0, 1638438, 3, 0, 1638439, 3, 0, 1638440, 3, 0, 1638441, 3, 0, 1638442, 3, 0, 1638443, 3, 0, 1638444, 3, 0, 1638445, 3, 0, 1769459, 3, 0, 1769460, 3, 0, 1769461, 3, 0, 1769462, 3, 0, 1769463, 3, 0, 1769464, 3, 0, 1769465, 3, 0, 1769466, 3, 0, 1769467, 3, 0, 1769468, 3, 0, 1769469, 3, 0, 1769470, 3, 0, 1769471, 3, 0, 1703936, 3, 0, 1703937, 3, 0, 1703938, 3, 0, 1703939, 3, 0, 1703940, 3, 0, 1703941, 3, 0, 1703942, 3, 0, 1703943, 3, 0, 1703944, 3, 0, 1703945, 3, 0, 1703946, 3, 0, 1703947, 3, 0, 1703948, 3, 0, 1703949, 3, 0, 1703950, 3, 0, 1703951, 3, 0, 1703952, 3, 0, 1703953, 3, 0, 1703954, 3, 0, 1703955, 3, 0, 1703956, 3, 0, 1703957, 3, 0, 1703958, 3, 0, 1703959, 3, 0, 1703960, 3, 0, 1703961, 3, 0, 1703962, 3, 0, 1703963, 3, 0, 1703964, 3, 0, 1703965, 3, 0, 1703966, 3, 0, 1703967, 3, 0, 1703968, 3, 0, 1703969, 3, 0, 1703970, 3, 0, 1703971, 3, 0, 1703972, 3, 0, 1703973, 3, 0, 1703974, 3, 0, 1703975, 3, 0, 1703976, 3, 0, 1703977, 3, 0, 1703978, 3, 0, 1703979, 3, 0, 1703980, 3, 0, 1703981, 3, 0, 1834995, 3, 0, 1834996, 3, 0, 1834997, 3, 0, 1834998, 3, 0, 1834999, 3, 0, 1835000, 3, 0, 1835001, 3, 0, 1835002, 3, 0, 1835003, 3, 0, 1835004, 3, 0, 1835005, 3, 0, 1835006, 3, 0, 1835007, 3, 0, 1769472, 3, 0, 1769473, 3, 0, 1769474, 3, 0, 1769475, 3, 0, 1769476, 3, 0, 1769477, 3, 0, 1769478, 3, 0, 1769479, 3, 0, 1769480, 3, 0, 1769481, 3, 0, 1769482, 3, 0, 1769483, 3, 0, 1769484, 3, 0, 1769485, 3, 0, 1769486, 3, 0, 1769487, 3, 0, 1769488, 3, 0, 1769489, 3, 0, 1769490, 3, 0, 1769491, 3, 0, 1769492, 3, 0, 1769493, 3, 0, 1769494, 3, 0, 1769495, 3, 0, 1769496, 3, 0, 1769497, 3, 0, 1769498, 3, 0, 1769499, 3, 0, 1769500, 3, 0, 1769501, 3, 0, 1769502, 3, 0, 1769503, 3, 0, 1769504, 3, 0, 1769505, 3, 0, 1769506, 3, 0, 1769507, 3, 0, 1769508, 3, 0, 1769509, 3, 0, 1769510, 3, 0, 1769511, 3, 0, 1769512, 3, 0, 1769513, 3, 0, 1769514, 3, 0, 1769515, 3, 0, 1769516, 3, 0, 1769517, 3, 0, 1900531, 3, 0, 1900532, 3, 0, 1900533, 3, 0, 1900534, 3, 0, 1900535, 3, 0, 1900536, 3, 0, 1900537, 3, 0, 1900538, 3, 0, 1900539, 3, 0, 1900540, 3, 0, 1900541, 3, 0, 1900542, 3, 0, 1900543, 3, 0, 1835008, 3, 0, 1835009, 3, 0, 1835010, 3, 0, 1835011, 3, 0, 1835012, 3, 0, 1835013, 3, 0, 1835014, 3, 0, 1835015, 3, 0, 1835016, 3, 0, 1835017, 3, 0, 1835018, 3, 0, 1835019, 3, 0, 1835020, 3, 0, 1835021, 3, 0, 1835022, 3, 0, 1835023, 3, 0, 1835024, 3, 0, 1835025, 3, 0, 1835026, 3, 0, 1835027, 3, 0, 1835028, 3, 0, 1835029, 3, 0, 1835030, 3, 0, 1835031, 3, 0, 1835032, 3, 0, 1835033, 3, 0, 1835034, 3, 0, 1835035, 3, 0, 1835036, 3, 0, 1835037, 3, 0, 1835038, 3, 0, 1835039, 3, 0, 1835040, 3, 0, 1835041, 3, 0, 1835042, 3, 0, 1835043, 3, 0, 1835044, 3, 0, 1835045, 3, 0, 1835046, 3, 0, 1835047, 3, 0, 1835048, 3, 0, 1835049, 3, 0, 1835050, 3, 0, 1835051, 3, 0, 1835052, 3, 0, 1835053, 3, 0 ) 97 | 98 | [node name="Camera2D" type="Camera2D" parent="."] 99 | current = true 100 | script = ExtResource( 3 ) 101 | 102 | [node name="Spawn_locations" type="Node" parent="."] 103 | 104 | [node name="1" type="Position2D" parent="Spawn_locations"] 105 | position = Vector2( 512, 512 ) 106 | 107 | [node name="2" type="Position2D" parent="Spawn_locations"] 108 | position = Vector2( 3584, 512 ) 109 | 110 | [node name="3" type="Position2D" parent="Spawn_locations"] 111 | position = Vector2( 512, 1792 ) 112 | 113 | [node name="4" type="Position2D" parent="Spawn_locations"] 114 | position = Vector2( 3584, 1792 ) 115 | 116 | [node name="5" type="Position2D" parent="Spawn_locations"] 117 | position = Vector2( 2048, 512 ) 118 | 119 | [node name="6" type="Position2D" parent="Spawn_locations"] 120 | position = Vector2( 2048, 1792 ) 121 | 122 | [node name="UI" type="CanvasLayer" parent="."] 123 | script = ExtResource( 4 ) 124 | 125 | [node name="Game_UI" type="CanvasLayer" parent="."] 126 | script = ExtResource( 7 ) 127 | 128 | [node name="Control" type="Control" parent="Game_UI"] 129 | anchor_right = 1.0 130 | anchor_bottom = 1.0 131 | __meta__ = { 132 | "_edit_use_anchors_": false 133 | } 134 | 135 | [node name="Winner" type="Label" parent="Game_UI/Control"] 136 | anchor_top = 0.5 137 | anchor_right = 1.0 138 | anchor_bottom = 0.5 139 | margin_top = -35.5 140 | margin_right = 0.00012207 141 | margin_bottom = 57.5001 142 | custom_fonts/font = SubResource( 2 ) 143 | custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) 144 | custom_constants/shadow_offset_x = 6 145 | custom_constants/shadow_offset_y = 6 146 | text = "Winner Winner Chicken Dinner!" 147 | align = 1 148 | valign = 1 149 | script = ExtResource( 5 ) 150 | __meta__ = { 151 | "_edit_use_anchors_": false 152 | } 153 | 154 | [node name="Win_timer" type="Timer" parent="Game_UI/Control/Winner"] 155 | wait_time = 2.0 156 | [connection signal="timeout" from="Game_UI/Control/Winner/Win_timer" to="Game_UI/Control/Winner" method="_on_Win_timer_timeout"] 157 | --------------------------------------------------------------------------------