Browse Source

sunday update

Lurkars 6 years ago
parent
commit
5efcfeca73
  1. 104
      ext/server.py
  2. 106
      project.godot
  3. 85
      resources/ui/i18n.csv
  4. BIN
      resources/ui/i18n.de.translation
  5. BIN
      resources/ui/i18n.en.translation
  6. 28
      resources/ui/theme.tres
  7. 0
      scenes/game/World.tscn
  8. 48
      scenes/game/test_world.tscn
  9. 0
      scenes/lanes/StartLanes.tscn
  10. 66
      scenes/menu/ingame.tscn
  11. 82
      scenes/menu/lobby.tscn
  12. 71
      scenes/menu/local_game.tscn
  13. 125
      scenes/menu/main.tscn
  14. 40
      scenes/menu/player_settings.tscn
  15. 91
      scenes/menu/server.tscn
  16. 72
      scenes/menu/settings.tscn
  17. 10
      scenes/menus/BaseMenu.tscn
  18. 70
      scenes/menus/DirectHostMenu.tscn
  19. 103
      scenes/menus/DirectJoinMenu.tscn
  20. 69
      scenes/menus/IngameMenu.tscn
  21. 147
      scenes/menus/LobbyMenu.tscn
  22. 108
      scenes/menus/LocalGameMenu.tscn
  23. 90
      scenes/menus/MainMenu.tscn
  24. 159
      scenes/menus/MultiplayerMenu.tscn
  25. 99
      scenes/menus/ServerCreateGameMenu.tscn
  26. 189
      scenes/menus/SettingsControlsMenu.tscn
  27. 156
      scenes/menus/SettingsMenu.tscn
  28. 39
      scenes/menus/SettingsPlayerMenu.tscn
  29. 6
      scenes/player/BotPlayer.tscn
  30. 30
      scenes/player/HumanPlayer.tscn
  31. 4
      scenes/player/Player.tscn
  32. 12
      scenes/road/roadBump.tscn
  33. 3
      scenes/road/roadCornerSmall.tscn
  34. 1
      scenes/road/roadCornerSmallFlipped.tscn
  35. 8
      scenes/road/roadRamp.tscn
  36. 8
      scenes/road/roadRampFlipped.tscn
  37. 8
      scenes/road/roadRampLong.tscn
  38. 8
      scenes/road/roadRampLongCurved.tscn
  39. 8
      scenes/road/roadRampLongCurvedFlipped.tscn
  40. 8
      scenes/road/roadRampLongFlipped.tscn
  41. 12
      scenes/road/roadStart.tscn
  42. 8
      scenes/road/roadStraight.tscn
  43. 8
      scenes/road/roadStraightArrow.tscn
  44. 8
      scenes/road/roadStraightLong.tscn
  45. 8
      scenes/road/roadStraightLongBump.tscn
  46. 4
      scenes/road/roadStraightLongBumpRound.tscn
  47. 8
      scenes/road/roadStraightLongMid.tscn
  48. 8
      scenes/road/roadStraightSkew.tscn
  49. 8
      scenes/road/roadStraightSkewFlipped.tscn
  50. 8
      scripts/Util.gd
  51. 172
      scripts/game/game.gd
  52. 13
      scripts/game/local_storage.gd
  53. 5
      scripts/game/route.gd
  54. 10
      scripts/game/world.gd
  55. 22
      scripts/menu/direct_host.gd
  56. 34
      scripts/menu/direct_join.gd
  57. 59
      scripts/menu/main.gd
  58. 15
      scripts/menu/player_settings.gd
  59. 32
      scripts/menu/server.gd
  60. 22
      scripts/menu/settings.gd
  61. 33
      scripts/menus/direct_host.gd
  62. 27
      scripts/menus/direct_join.gd
  63. 8
      scripts/menus/ingame.gd
  64. 38
      scripts/menus/lobby.gd
  65. 15
      scripts/menus/local_game.gd
  66. 43
      scripts/menus/main.gd
  67. 141
      scripts/menus/server.gd
  68. 44
      scripts/menus/server_create.gd
  69. 67
      scripts/menus/settings.gd
  70. 89
      scripts/menus/settings_controls.gd
  71. 14
      scripts/menus/settings_player.gd
  72. 44
      scripts/networking/client.gd
  73. 14
      scripts/networking/game_server.gd
  74. 35
      scripts/networking/game_server_requests.gd
  75. 156
      scripts/networking/server.gd
  76. 37
      scripts/player/HumanControls.gd
  77. 3
      scripts/player/base_inventory.gd
  78. 10
      scripts/player/base_player.gd
  79. 9
      scripts/player/bot_controls.gd
  80. 5
      scripts/player/bot_inventory.gd
  81. 51
      scripts/player/human_controls.gd
  82. 15
      scripts/player/human_inventory.gd
  83. 3
      scripts/player/inventory_preview.gd
  84. 40
      scripts/player/player.gd
  85. 4
      scripts/player/race_car.gd
  86. 25
      scripts/road/road.gd
  87. 2
      scripts/road/roads_factory.gd

104
ext/server.py

@ -1,15 +1,24 @@
#!flask/bin/python
import subprocess
import sqlite3
import secrets
from flask import Flask, abort, request, jsonify
START_PORT = 8128
GAME_EXEC = '/opt/godot/Godot_v3.1.1-stable_linux_server.64'
GAME_EXEC_ARG_PACK = '--main-pack'
GAME_EXEC_ARG_PACK_PATH = '/opt/godot/Muffrace Pre Alpha.pck'
GAME_EXEC_ARG_PORT = '--port={0}'
GAME_EXEC_ARG_ID = '--server-id={0}'
GAME_EXEC_ARG_SECRET = '--secret={0}'
GAME_EXEC_ARG_BOTS = '--bots={0}'
games = {}
try:
with sqlite3.connect("database.db") as con:
cur = con.cursor()
cur.execute(
'CREATE TABLE IF NOT EXISTS games (id INTEGER PRIMARY KEY, secret TEXT, ip TEXT, running INTEGER, port INTEGER, player_count INTEGER)')
'CREATE TABLE IF NOT EXISTS games (id INTEGER PRIMARY KEY, name TEXT, secret TEXT, ip TEXT, running INTEGER, port INTEGER, player_count INTEGER, bots INTEGER)')
con.commit()
except:
con.rollback()
@ -21,9 +30,20 @@ app = Flask(__name__)
@app.route('/client/game/create', methods=['POST'])
def create_game():
# TODO: block multiple request from same game
# TODO: block multiple request from same user
if not request.json:
abort(400)
if not 'name' in request.json:
abort(400)
bots = False
name = request.json.get('name')
if 'bots' in request.json:
bots = request.json.get('bots')
try:
with sqlite3.connect("database.db") as con:
# check free port
port = START_PORT
cur = con.cursor()
cur.execute("SELECT * FROM games WHERE port=?", (port,))
@ -32,14 +52,35 @@ def create_game():
port += 1
cur.execute("SELECT * FROM games WHERE port=?", (port,))
rows = cur.fetchall()
token = secrets.token_hex(32)
cur.execute("INSERT INTO games (secret, ip,port) VALUES (?,?,?)",
(token, request.remote_addr, port))
# check duplicate name
base_name = name
base_name_count = 1
cur.execute("SELECT * FROM games WHERE name=?", (name,))
rows = cur.fetchall()
while rows:
base_name_count += 1
name = base_name + "_" + str(base_name_count)
cur.execute("SELECT * FROM games WHERE name=?", (name,))
rows = cur.fetchall()
# gen secret
secret = secrets.token_hex(32)
cur.execute("INSERT INTO games (name,secret,ip,port,bots,running) VALUES (?,?,?,?,?,0)",
(name, secret, request.remote_addr, port, bots))
con.commit()
cur.execute("SELECT id FROM games WHERE secret=?",
(secret,))
result = cur.fetchone()
if result[0]:
games[result[0]] = subprocess.Popen([GAME_EXEC, GAME_EXEC_ARG_PACK, GAME_EXEC_ARG_PACK_PATH, GAME_EXEC_ARG_ID.format(int(result[0])), GAME_EXEC_ARG_PORT.format(
port), GAME_EXEC_ARG_SECRET.format(secret), GAME_EXEC_ARG_BOTS.format(int(bots))])
except:
con.rollback()
abort(500)
finally:
con.close()
return jsonify({'port': port})
return jsonify({'name': name, 'port': port})
@app.route('/client/games', methods=['GET'])
@ -47,12 +88,11 @@ def get_games():
try:
with sqlite3.connect("database.db") as con:
cur = con.cursor()
query = "SELECT * FROM games"
query = "SELECT * FROM games ORDER BY running"
if 'open' in request.args:
query = "SELECT * FROM games WHERE running=0"
cur.execute(query)
rows = cur.fetchall()
token = secrets.token_hex(32)
except:
con.rollback()
finally:
@ -60,22 +100,33 @@ def get_games():
result = []
for row in rows:
result.append(
{'player_count': row[5], 'running': (row[3] == 1), 'port': row[4]})
{'name': row[1], 'player_count': row[6], 'running': (row[4] == 1), 'port': row[5], 'bots': row[7]})
return jsonify(result)
@app.route('/game', methods=['DELETE'])
def close_game():
@app.route('/game', methods=['PUT'])
def update_game():
if not request.json:
abort(400)
if not 'token' in request.json:
if not 'secret' in request.json or not 'player_count' in request.json or not 'running' in request.json:
abort(400)
token = request.json.get('token')
secret = request.json.get('secret')
player_count = request.json.get('player_count')
running = request.json.get('running')
try:
with sqlite3.connect("database.db") as con:
cur = con.cursor()
cur.execute("DELETE FROM games WHERE secret=?", (token,))
cur.execute("SELECT id FROM games WHERE secret=?",
(secret,))
result = cur.fetchone()
if result[0]:
game_id = result[0]
cur.execute("UPDATE games SET player_count=?,running=? WHERE id=?",
(player_count, running, game_id,))
con.commit()
else:
abort(401)
except:
con.rollback()
return jsonify(False)
@ -84,21 +135,30 @@ def close_game():
return jsonify(True)
@app.route('/game', methods=['PUT'])
def update_game():
@app.route('/game', methods=['DELETE'])
def close_game():
if not request.json:
abort(400)
if not 'token' in request.json or not 'player_count' in request.json or not 'running' in request.json:
if not 'secret' in request.json:
abort(400)
token = request.json.get('token')
player_count = request.json.get('player_count')
running = request.json.get('running')
secret = request.json.get('secret')
try:
with sqlite3.connect("database.db") as con:
cur = con.cursor()
cur.execute("UPDATE games SET player_count=?,running=? WHERE secret=?",
(player_count, running, token,))
cur.execute("SELECT id FROM games WHERE secret=?",
(secret,))
result = cur.fetchone()
if result[0]:
game_id = result[0]
cur.execute("DELETE FROM games WHERE id=?", (game_id,))
con.commit()
if games[game_id]:
games[game_id].terminate()
games[game_id].communicate()
del games[game_id]
else:
abort(401)
except:
con.rollback()
return jsonify(False)

106
project.godot

@ -12,22 +12,32 @@ _global_script_classes=[ {
"base": "Spatial",
"class": "BaseInventory",
"language": "GDScript",
"path": "res://scripts/player/BaseInventory.gd"
"path": "res://scripts/player/base_inventory.gd"
}, {
"base": "Node",
"class": "BasePlayer",
"language": "GDScript",
"path": "res://scripts/player/BasePlayer.gd"
"path": "res://scripts/player/base_player.gd"
}, {
"base": "Spatial",
"class": "GameServer",
"language": "GDScript",
"path": "res://scripts/networking/game_server.gd"
}, {
"base": "Spatial",
"class": "GameServerRequests",
"language": "GDScript",
"path": "res://scripts/networking/game_server_requests.gd"
}, {
"base": "BasePlayer",
"class": "Player",
"language": "GDScript",
"path": "res://scripts/player/Player.gd"
"path": "res://scripts/player/player.gd"
}, {
"base": "Spatial",
"class": "Preview",
"language": "GDScript",
"path": "res://scripts/player/InventoryPreview.gd"
"path": "res://scripts/player/inventory_preview.gd"
}, {
"base": "MeshInstance",
"class": "Road",
@ -52,6 +62,8 @@ _global_script_classes=[ {
_global_script_class_icons={
"BaseInventory": "",
"BasePlayer": "",
"GameServer": "",
"GameServerRequests": "",
"Player": "",
"Preview": "",
"Road": "",
@ -62,37 +74,102 @@ _global_script_class_icons={
[application]
config/name="MUR_pre_aplha"
run/main_scene="res://scenes/menu/main.tscn"
config/name="MUR_pre_alpha"
run/main_scene="res://scenes/menus/MainMenu.tscn"
boot_splash/fullsize=false
config/icon="res://icon.png"
[autoload]
game="*res://scripts/game/game.gd"
client="*res://scripts/networking/client.gd"
server="*res://scripts/networking/server.gd"
game_server="*res://scripts/networking/game_server.gd"
roads_factory="*res://scripts/road/roads_factory.gd"
Util="*res://scripts/Util.gd"
local_storage="*res://scripts/game/local_storage.gd"
Util="*res://scripts/Util.gd"
[display]
window/size/width=1920
window/size/height=1080
window/size/resizable=false
window/size/fullscreen=true
[input]
ui_navigate_left={
ui_cancel={
"deadzone": 0.5,
"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)
"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":16777217,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_navigate_right={
controls_thrust={
"deadzone": 0.5,
"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":16777232,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
]
}
controls_break={
"deadzone": 0.5,
"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":16777234,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
]
}
controls_add_road={
"deadzone": 0.5,
"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":32,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":5,"pressure":0.0,"pressed":false,"script":null)
]
}
controls_next_road_type={
"deadzone": 0.5,
"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)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_navigate_up={
controls_prev_road_type={
"deadzone": 0.5,
"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)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
]
}
controls_next_road_variant={
"deadzone": 0.5,
"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)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_navigate_down={
controls_prev_road_variant={
"deadzone": 0.5,
"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)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
]
}
controls_reset={
"deadzone": 0.5,
"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":69,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":4,"pressure":0.0,"pressed":false,"script":null)
]
}
debug_camera_1={
"deadzone": 0.5,
"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":49,"unicode":0,"echo":false,"script":null)
]
}
debug_camera_2={
"deadzone": 0.5,
"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":50,"unicode":0,"echo":false,"script":null)
]
}
debug_camera_3={
"deadzone": 0.5,
"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":51,"unicode":0,"echo":false,"script":null)
]
}
debug_camera_4={
"deadzone": 0.5,
"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":52,"unicode":0,"echo":false,"script":null)
]
}
@ -105,6 +182,11 @@ ui_navigate_down={
3d_physics/layer_5="player_4"
3d_physics/layer_6="preview"
[locale]
translations=PoolStringArray( "res://resources/ui/i18n.csv", "res://resources/ui/i18n.en.translation", "res://resources/ui/i18n.de.translation" )
locale_filter=[ 0, [ ] ]
[rendering]
threads/thread_model=2

85
resources/ui/i18n.csv

@ -0,0 +1,85 @@
,en,de
BACK,back,Zurück
MULTIPLAYER,multiplayer,Multiplayer
PRACTISE,practise,Training
SETTINGS,settings,Einstellungen
DEBUG,debug EN,Debug DE
HOST,host,Host
JOIN,join,Beitreten
QUIT,quit,Beenden
DIRECT_HOST,direct host,Direkt hosten
DIRECT_JOIN,direct join,Direkt beitreten
OPEN_GAMES_ONLY,open games only,Nur offene Spiele
REFRESH,refresh,Aktualisieren
CREATE_GAME,create game,Spiel erstellen
PLAYER_NAME,name,Name
PLAYER_COLOR,color,Farbe
BOTS,bots,Bots
GAME,game,Spiel
PORT,port,Port
IP,IP,IP
RESUME,resume,Fortsetzen
END_GAME,end game,Spiel beenden
START_GAME,start game,Spiel starten
GAME_NAME,name,Name
READY,ready,Bereit
ALERT,Alert!,Fehler!
CONTROLS,controls,Steuerung
RESET,reset,Zurücksetzen
PRESS_KEY,Press any key...,Taste drücken…
ERROR_SERVER_CREATION,Cannot create Server!,Server konnte nicht erstellt werden!
INVALID_IP4,Invalid IPv4 address!,Ungültige IPv4 Adresse!
SERVER_DISCONNECTED,Server disconnected!,Serververbindung getrennt!
SERVER_NO_CONNECTION,No connection to server!,Keine Verbindung zu Server!
CONNECTION_FAILED,Connection failed!,Verbindung fehlgeschlagen!
SYSTEM,system,System
LOCALE,language,Sprache
LOCALE_EN,english,Englisch (english)
LOCALE_DE,german (Deutsch),Deutsch
GRAPHICS,graphics,Grafik
SAVE,save,Speichern
KEYBOARD,keyboard,Tastatur
JOYPAD,joypad,Joypad
Up,,Hoch
Down,,Runter
Left,,Links
Right,,Rechts
Space,,Leertaste
Control,,Strg
PageUp,,Bild hoch
PageDown,,Bild runter
Insert,,Einf
Delete,,Entf
Home,,Pos 1
End,,Ende
,,
StraightLong,straight,Gerade
Straight,short straight,kurze Gerade
CornerLarge,right corner,Rechtskurve
CornerLargeFlipped,left corner,Linkskurve
CornerLarger,long right corner,lange Rechtskurve
CornerLargerFlipped,long left corner,lange Linkskurve
CornerSmall,short right corner,kurze Rechtskurve
CornerSmallFlipped,short left corner,kurze Linkskurve
StraightLongBump,bump,Bodenwelle
Bump,small bump,kurze Bodenwelle
StraightSkew,right skew,rechte Schräge
StraightSkewFlipped,left skew,linke Schräge
RampLong,ramp up,Rampe hoch
RampLongFlipped,ramp down,Rampe runter
RampLongCurved,curved ramp up,Rundung hoch
RampLongCurvedFlipped,curved ramp down,Rundung runter
Ramp,short ramp up,kurze Rampe hoch
RampFlipped,short ramp down,kurze Rampe runter
CurvedFlipped,shicane right,Schikane rechts
Curved,shicane left,Schikane links
Loop,looping,Looping
,,
controls_thrust,thrust,Beschleunigen
controls_break,break,Bremsen
controls_add_road,add,Setzen
controls_next_road_type,next type,Nächste Kategorie
controls_prev_road_type,previous type,Vorherige Kategorie
controls_next_road_variant,next variant,Nächste Variante
controls_prev_road_variant,previous variant,Vorherige Variante
controls_reset,reset,Zurücksetzen

BIN
resources/ui/i18n.de.translation

BIN
resources/ui/i18n.en.translation

28
resources/ui/theme.tres

@ -4,3 +4,31 @@
[resource]
default_font = ExtResource( 1 )
Button/colors/font_color = Color( 0.878431, 0.878431, 0.878431, 1 )
Button/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 )
Button/colors/font_color_hover = Color( 0.941176, 0.941176, 0.941176, 1 )
Button/colors/font_color_pressed = Color( 1, 1, 1, 1 )
Button/constants/hseparation = 2
Button/fonts/font = null
Button/styles/disabled = null
Button/styles/focus = null
Button/styles/hover = null
Button/styles/normal = null
Button/styles/pressed = null
ItemList/colors/font_color = Color( 0.627451, 0.627451, 0.627451, 1 )
ItemList/colors/font_color_selected = Color( 1, 1, 1, 1 )
ItemList/colors/guide_color = Color( 0, 0, 0, 0.1 )
ItemList/constants/hseparation = 4
ItemList/constants/icon_margin = 4
ItemList/constants/line_separation = 2
ItemList/constants/vseparation = 2
ItemList/fonts/font = null
ItemList/styles/bg = null
ItemList/styles/bg_focus = null
ItemList/styles/cursor = null
ItemList/styles/cursor_unfocused = null
ItemList/styles/selected = null
ItemList/styles/selected_focus = null
Panel/styles/panel = null
Panel/styles/panelf = null
Panel/styles/panelnc = null

0
scenes/game/world.tscn → scenes/game/World.tscn

48
scenes/game/test_world.tscn

@ -1,48 +0,0 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://scenes/road/roadStartPositions.tscn" type="PackedScene" id=1]
[ext_resource path="res://scenes/road/roadStart.tscn" type="PackedScene" id=2]
[ext_resource path="res://scenes/road/roadStraightLong.tscn" type="PackedScene" id=3]
[ext_resource path="res://scenes/road/roadStraightLongBump.tscn" type="PackedScene" id=4]
[ext_resource path="res://scenes/raceCar/raceCar.tscn" type="PackedScene" id=5]
[node name="world" type="Spatial"]
[node name="sun" type="DirectionalLight" parent="."]
transform = Transform( 0.324827, 0.775291, 0.541675, -0.754407, -0.133022, 0.642788, 0.570402, -0.617438, 0.541675, 0, 100, 0 )
visible = false
light_energy = 5.0
directional_shadow_mode = 1
directional_shadow_max_distance = 25.0
[node name="route" type="Spatial" parent="."]
transform = Transform( 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0 )
[node name="roadStartPositions" parent="route" instance=ExtResource( 1 )]
[node name="roadStart" parent="route" instance=ExtResource( 2 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2 )
[node name="roadStraightLong" parent="route" instance=ExtResource( 3 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 4 )
[node name="roadStraightLongBump" parent="route" instance=ExtResource( 4 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 6 )
[node name="roadStraightLong2" parent="route" instance=ExtResource( 3 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 8 )
[node name="players" type="Spatial" parent="."]
transform = Transform( 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0 )
[node name="raceCar" parent="players" instance=ExtResource( 5 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.258, 0.015, 0.45 )
[node name="raceCar2" parent="players" instance=ExtResource( 5 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0887639, 0, 0.416576 )
[node name="raceCar3" parent="players" instance=ExtResource( 5 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0902514, 0, 0.416576 )
[node name="raceCar4" parent="players" instance=ExtResource( 5 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.260719, 0, 0.416576 )

0
scenes/lanes/start.tscn → scenes/lanes/StartLanes.tscn

66
scenes/menu/ingame.tscn

@ -1,66 +0,0 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menu/ingame.gd" type="Script" id=2]
[ext_resource path="res://assets/icons/open.png" type="Texture" id=3]
[ext_resource path="res://assets/icons/wrench.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/arrowLeft.png" type="Texture" id=5]
[node name="ingame_menu" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -0.857361
margin_right = -0.857361
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" type="Panel" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -155.0
margin_top = -155.0
margin_right = 155.0
margin_bottom = 155.0
grow_horizontal = 2
grow_vertical = 2
[node name="resume" type="Button" parent="menu"]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -0.857422
margin_top = -153.725
margin_right = -0.857422
margin_bottom = -97.7245
text = "Resume"
icon = ExtResource( 3 )
flat = true
[node name="settings" type="Button" parent="menu"]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -0.572113
margin_top = -25.128
margin_right = -0.572113
margin_bottom = 30.872
text = "Settings"
icon = ExtResource( 4 )
flat = true
[node name="end" type="Button" parent="menu"]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -0.572113
margin_top = 98.872
margin_right = -0.572113
margin_bottom = 154.872
text = "End Game"
icon = ExtResource( 5 )
flat = true
[connection signal="pressed" from="menu/resume" to="." method="_on_resume_pressed"]
[connection signal="pressed" from="menu/settings" to="." method="_on_settings_pressed"]
[connection signal="pressed" from="menu/end" to="." method="_on_end_pressed"]

82
scenes/menu/lobby.tscn

@ -1,82 +0,0 @@
[gd_scene load_steps=9 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menu/lobby.gd" type="Script" id=2]
[ext_resource path="res://scenes/menu/base_menu.tscn" type="PackedScene" id=3]
[ext_resource path="res://assets/icons/checkmark.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/question.png" type="Texture" id=5]
[ext_resource path="res://scenes/menu/player_settings.tscn" type="PackedScene" id=6]
[ext_resource path="res://assets/fonts/Kenney Future Narrow.ttf" type="DynamicFontData" id=7]
[sub_resource type="DynamicFont" id=1]
size = 100
font_data = ExtResource( 7 )
[node name="lobby" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 0.857376
margin_top = 0.857422
margin_right = 0.857422
margin_bottom = 0.857422
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" parent="." instance=ExtResource( 3 )]
[node name="players" type="ItemList" parent="menu"]
margin_left = 13.0
margin_top = 18.0
margin_right = 500.0
margin_bottom = 413.0
[node name="ready_icon" type="Button" parent="menu/players"]
visible = false
margin_right = 62.0
margin_bottom = 56.0
icon = ExtResource( 4 )
[node name="not_ready_icon" type="Button" parent="menu/players"]
visible = false
margin_right = 62.0
margin_bottom = 56.0
icon = ExtResource( 5 )
[node name="player_settings" parent="menu" instance=ExtResource( 6 )]
margin_left = 510.586
margin_top = 21.0499
margin_right = 875.586
margin_bottom = 238.05
[node name="ready" type="CheckButton" parent="menu"]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -166.0
margin_top = -58.0
text = "Ready"
flat = true
[node name="countdown" type="Label" parent="."]
visible = false
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -94.0
margin_top = -56.5
margin_right = 94.0
margin_bottom = 56.5
custom_fonts/font = SubResource( 1 )
text = "3"
align = 1
valign = 1
[node name="countdown_timer" type="Timer" parent="."]
process_mode = 0
wait_time = 3.0
one_shot = true
[connection signal="toggled" from="menu/ready" to="." method="_on_ready_toggled"]
[editable path="menu"]

71
scenes/menu/local_game.tscn

@ -1,71 +0,0 @@
[gd_scene load_steps=7 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menu/local_game.gd" type="Script" id=2]
[ext_resource path="res://resources/ui/font.tres" type="DynamicFont" id=3]
[ext_resource path="res://assets/icons/exitRight.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/return.png" type="Texture" id=5]
[ext_resource path="res://scenes/menu/player_settings.tscn" type="PackedScene" id=6]
[node name="local_game" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 0.857376
margin_top = 0.857422
margin_right = 0.857422
margin_bottom = 0.857422
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" type="Panel" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -217.5
margin_top = -187.5
margin_right = 217.5
margin_bottom = 187.5
grow_horizontal = 2
grow_vertical = 2
[node name="bots" type="CheckButton" parent="menu"]
margin_left = 18.8485
margin_top = 238.232
margin_right = 184.849
margin_bottom = 296.232
pressed = true
text = "Bots"
flat = true
[node name="start" type="Button" parent="menu"]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -143.0
margin_top = -56.0
rect_pivot_offset = Vector2( 1.89856, 0.845154 )
custom_fonts/font = ExtResource( 3 )
text = "Start"
icon = ExtResource( 4 )
flat = true
[node name="back" type="Button" parent="menu"]
anchor_top = 1.0
anchor_bottom = 1.0
margin_top = -56.0
margin_right = 132.0
rect_pivot_offset = Vector2( 0.606262, -0.447205 )
custom_fonts/font = ExtResource( 3 )
text = "Back"
icon = ExtResource( 5 )
flat = true
[node name="player_settings" parent="menu" instance=ExtResource( 6 )]
margin_left = 27.4727
margin_top = 18.9189
margin_right = 392.473
margin_bottom = 235.919
[connection signal="pressed" from="menu/start" to="." method="_on_start_pressed"]
[connection signal="pressed" from="menu/back" to="." method="_on_back_pressed"]

125
scenes/menu/main.tscn

@ -1,125 +0,0 @@
[gd_scene load_steps=10 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menu/main.gd" type="Script" id=2]
[ext_resource path="res://assets/icons/massiveMultiplayer.png" type="Texture" id=3]
[ext_resource path="res://assets/icons/singleplayer.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/wrench.png" type="Texture" id=5]
[ext_resource path="res://assets/icons/power.png" type="Texture" id=6]
[ext_resource path="res://assets/icons/cpu.png" type="Texture" id=7]
[ext_resource path="res://assets/icons/exitRight.png" type="Texture" id=8]
[sub_resource type="StyleBoxFlat" id=1]
bg_color = Color( 0.85098, 0.670588, 0.188235, 1 )
[node name="main_menu" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -0.857361
margin_right = -0.857361
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" type="Panel" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -155.0
margin_top = -201.5
margin_right = 155.0
margin_bottom = 201.5
grow_horizontal = 2
grow_vertical = 2
[node name="online" type="Button" parent="menu"]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -0.857422
margin_top = -194.725
margin_right = -0.857422
margin_bottom = -138.725
text = "Multiplayer"
icon = ExtResource( 3 )
flat = true
[node name="practice" type="Button" parent="menu"]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_top = -132.154
margin_bottom = -76.154
text = "Practice"
icon = ExtResource( 4 )
flat = true
[node name="settings" type="Button" parent="menu"]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -0.572113
margin_top = -66.128
margin_right = -0.572113
margin_bottom = -10.128
text = "Settings"
icon = ExtResource( 5 )
flat = true
[node name="quit" type="Button" parent="menu"]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -0.572113
margin_top = 132.872
margin_right = -0.572113
margin_bottom = 188.872
text = "Quit"
icon = ExtResource( 6 )
flat = true
[node name="debug" type="Panel" parent="menu"]
margin_top = 193.0
margin_right = 309.0
margin_bottom = 327.0
custom_styles/panel = SubResource( 1 )
[node name="debug_label" type="Label" parent="menu/debug"]
anchor_right = 1.0
margin_top = 3.0
margin_bottom = 60.0
text = "debug
localhost:8128"
align = 1
valign = 1
[node name="quick_host" type="Button" parent="menu/debug"]
anchor_top = 0.5
anchor_bottom = 0.5
margin_left = 16.3244
margin_top = 1.68341
margin_right = 145.324
margin_bottom = 57.6834
text = "Host"
icon = ExtResource( 7 )
[node name="quick_join" type="Button" parent="menu/debug"]
anchor_top = 0.5
anchor_bottom = 0.5
margin_left = 161.885
margin_top = 2.32294
margin_right = 290.885
margin_bottom = 58.3229
text = "Join"
icon = ExtResource( 8 )
[node name="error_dialog" type="AcceptDialog" parent="."]
margin_right = 138.0
margin_bottom = 84.0
dialog_text = "Server disconnected!"
[connection signal="pressed" from="menu/online" to="." method="_on_online_pressed"]
[connection signal="pressed" from="menu/practice" to="." method="_on_practice_pressed"]
[connection signal="pressed" from="menu/settings" to="." method="_on_settings_pressed"]
[connection signal="pressed" from="menu/quit" to="." method="_on_quit_pressed"]
[connection signal="pressed" from="menu/debug/quick_host" to="." method="_on_quick_host_pressed"]
[connection signal="pressed" from="menu/debug/quick_join" to="." method="_on_quick_join_pressed"]

40
scenes/menu/player_settings.tscn

@ -1,40 +0,0 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://scripts/menu/player_settings.gd" type="Script" id=1]
[node name="player_settings" type="Control"]
margin_left = 513.0
margin_top = 23.0
margin_right = 878.0
margin_bottom = 240.0
script = ExtResource( 1 )
[node name="name_label" type="Label" parent="."]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_top = -95.5
margin_bottom = -68.5
text = "Name"
[node name="name" type="LineEdit" parent="."]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_top = -51.5
margin_bottom = -14.5
[node name="color_label" type="Label" parent="."]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_top = 1.5
margin_bottom = 28.5
text = "Color"
[node name="color" type="ColorPickerButton" parent="."]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_top = 46.5
margin_bottom = 79.5

91
scenes/menu/server.tscn

@ -1,91 +0,0 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menu/server.gd" type="Script" id=2]
[ext_resource path="res://scenes/menu/base_menu.tscn" type="PackedScene" id=3]
[ext_resource path="res://assets/icons/exitRight.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/fistPlus.png" type="Texture" id=5]
[ext_resource path="res://assets/icons/cpu.png" type="Texture" id=6]
[ext_resource path="res://assets/icons/open.png" type="Texture" id=7]
[node name="server" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 0.857376
margin_top = 0.857422
margin_right = 0.857422
margin_bottom = 0.857422
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" parent="." instance=ExtResource( 3 )]
[node name="filter" type="Control" parent="menu"]
editor/display_folded = true
margin_left = 14.0
margin_top = 16.0
margin_right = 878.0
margin_bottom = 45.0
[node name="open" type="CheckButton" parent="menu/filter"]
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -317.0
margin_top = -16.5
margin_bottom = 23.5
text = "Open Games only"
[node name="games" type="ItemList" parent="menu"]
margin_left = 13.0
margin_top = 60.0
margin_right = 880.0
margin_bottom = 414.0
[node name="join" type="Button" parent="menu"]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -120.0
margin_top = -56.0
text = "Join"
icon = ExtResource( 4 )
flat = true
[node name="create" type="Button" parent="menu"]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -366.0
margin_top = -56.0
margin_right = -126.0
text = "Create Game"
icon = ExtResource( 5 )
flat = true
[node name="direct_host" type="Button" parent="menu"]
margin_left = 10.0
margin_top = 2.0
margin_right = 235.0
margin_bottom = 58.0
text = "Direct Host"
icon = ExtResource( 6 )
flat = true
[node name="direct_join" type="Button" parent="menu"]
margin_left = 230.0
margin_top = 2.0
margin_right = 446.0
margin_bottom = 58.0
text = "Direct Join"
icon = ExtResource( 7 )
flat = true
[node name="error_dialog" type="AcceptDialog" parent="."]
margin_right = 138.0
margin_bottom = 84.0
[connection signal="pressed" from="menu/direct_host" to="." method="_on_direct_host_pressed"]
[connection signal="pressed" from="menu/direct_join" to="." method="_on_direct_join_pressed"]

72
scenes/menu/settings.tscn

@ -1,72 +0,0 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menu/settings.gd" type="Script" id=2]
[ext_resource path="res://scenes/menu/base_menu.tscn" type="PackedScene" id=3]
[ext_resource path="res://scenes/menu/player_settings.tscn" type="PackedScene" id=4]
[ext_resource path="res://assets/icons/save.png" type="Texture" id=5]
[node name="settings" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 1.45612
margin_top = 1.45612
margin_right = 1.45605
margin_bottom = 1.45612
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" parent="." instance=ExtResource( 3 )]
[node name="tabs" type="TabContainer" parent="menu"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -438.5
margin_top = -217.5
margin_right = 440.5
margin_bottom = 177.5
tab_align = 0
[node name="Game" type="Tabs" parent="menu/tabs"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 4.0
margin_top = 45.0
margin_right = -4.0
margin_bottom = -4.0
[node name="player_settings" parent="menu/tabs/Game" instance=ExtResource( 4 )]
margin_left = 15.4583
margin_top = 10.7114
margin_right = 380.458
margin_bottom = 227.711
[node name="bots" type="CheckButton" parent="menu/tabs/Game"]
margin_left = 8.38535
margin_top = 226.162
margin_right = 153.385
margin_bottom = 266.162
text = "Bots"
[node name="Controls" type="Tabs" parent="menu/tabs"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 4.0
margin_top = 45.0
margin_right = -4.0
margin_bottom = -4.0
[node name="save" type="Button" parent="menu"]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -147.0
margin_top = -56.0
text = "Save"
icon = ExtResource( 5 )
flat = true
[connection signal="pressed" from="menu/save" to="." method="_on_save_pressed"]

10
scenes/menu/base_menu.tscn → scenes/menus/BaseMenu.tscn

@ -8,15 +8,15 @@ anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -454.0
margin_left = -472.5
margin_top = -234.5
margin_right = 454.0
margin_right = 472.5
margin_bottom = 234.5
grow_horizontal = 2
grow_vertical = 2
rect_clip_content = true
size_flags_horizontal = 4
size_flags_vertical = 4
size_flags_horizontal = 6
size_flags_vertical = 6
[node name="back" type="Button" parent="."]
anchor_top = 1.0
@ -24,6 +24,6 @@ anchor_bottom = 1.0
margin_top = -56.0
margin_right = 132.0
custom_fonts/font = ExtResource( 1 )
text = "Back"
text = "BACK"
icon = ExtResource( 2 )
flat = true

70
scenes/menu/direct_host.tscn → scenes/menus/DirectHostMenu.tscn

@ -1,12 +1,12 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menu/direct_host.gd" type="Script" id=2]
[ext_resource path="res://scripts/menus/direct_host.gd" type="Script" id=2]
[ext_resource path="res://resources/ui/font.tres" type="DynamicFont" id=3]
[ext_resource path="res://assets/icons/exitRight.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/return.png" type="Texture" id=5]
[node name="direct_host" type="Control"]
[node name="direct_host_menu" type="Control"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
@ -24,12 +24,43 @@ anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -217.5
margin_top = -60.5
margin_top = -53.5
margin_right = 217.5
margin_bottom = 60.5
margin_bottom = 53.5
grow_horizontal = 2
grow_vertical = 2
[node name="GridContainer" type="GridContainer" parent="menu"]
margin_left = 16.0
margin_top = 12.0
margin_right = 429.0
margin_bottom = 52.0
columns = 3
[node name="port_label" type="Label" parent="menu/GridContainer"]
margin_top = 6.0
margin_right = 65.0
margin_bottom = 33.0
text = "PORT"
[node name="port" type="LineEdit" parent="menu/GridContainer"]
margin_left = 69.0
margin_right = 266.0
margin_bottom = 40.0
focus_neighbour_right = NodePath("../bots")
focus_neighbour_bottom = NodePath("../../back")
size_flags_horizontal = 3
text = "8128"
max_length = 5
[node name="bots" type="CheckButton" parent="menu/GridContainer"]
margin_left = 270.0
margin_right = 413.0
margin_bottom = 40.0
focus_neighbour_left = NodePath("../port")
focus_neighbour_bottom = NodePath("../../host")
text = "BOTS"
[node name="host" type="Button" parent="menu"]
anchor_left = 1.0
anchor_top = 1.0
@ -37,9 +68,13 @@ anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -143.0
margin_top = -56.0001
grow_horizontal = 0
grow_vertical = 0
rect_pivot_offset = Vector2( 1.89856, 0.845154 )
focus_neighbour_left = NodePath("../back")
focus_neighbour_top = NodePath("../GridContainer/bots")
custom_fonts/font = ExtResource( 3 )
text = "Host"
text = "HOST"
icon = ExtResource( 4 )
flat = true
@ -49,29 +84,12 @@ anchor_bottom = 1.0
margin_top = -56.0
margin_right = 132.0
rect_pivot_offset = Vector2( 0.606262, -0.447205 )
focus_neighbour_top = NodePath("../GridContainer/port")
focus_neighbour_right = NodePath("../host")
custom_fonts/font = ExtResource( 3 )
text = "Back"
text = "BACK"
icon = ExtResource( 5 )
flat = true
[node name="port_label" type="Label" parent="menu"]
margin_left = 122.969
margin_top = 30.2159
margin_right = 187.969
margin_bottom = 57.2159
text = "Port"
[node name="port" type="LineEdit" parent="menu"]
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -219.911
margin_top = -34.0125
margin_right = -111.911
margin_bottom = 2.98752
text = "8128"
max_length = 5
[connection signal="text_changed" from="menu/GridContainer/port" to="." method="_on_port_text_changed"]
[connection signal="pressed" from="menu/host" to="." method="_on_host_pressed"]
[connection signal="pressed" from="menu/back" to="." method="_on_back_pressed"]
[connection signal="text_changed" from="menu/port" to="." method="_on_port_text_changed"]

103
scenes/menu/direct_join.tscn → scenes/menus/DirectJoinMenu.tscn

@ -1,12 +1,12 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menu/direct_join.gd" type="Script" id=2]
[ext_resource path="res://scripts/menus/direct_join.gd" type="Script" id=2]
[ext_resource path="res://resources/ui/font.tres" type="DynamicFont" id=3]
[ext_resource path="res://assets/icons/exitRight.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/return.png" type="Texture" id=5]
[node name="direct_join" type="Control"]
[node name="direct_join_menu" type="Control"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
@ -24,12 +24,56 @@ anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -217.5
margin_top = -89.5
margin_top = -73.5
margin_right = 217.5
margin_bottom = 89.5
margin_bottom = 73.5
grow_horizontal = 2
grow_vertical = 2
[node name="GridContainer" type="GridContainer" parent="menu"]
margin_left = 18.0
margin_top = 11.0
margin_right = 425.0
margin_bottom = 89.0
columns = 2
[node name="ip_label" type="Label" parent="menu/GridContainer"]
margin_right = 65.0
margin_bottom = 37.0
size_flags_vertical = 1
text = "IP"
valign = 1
[node name="ip" type="LineEdit" parent="menu/GridContainer"]
margin_left = 69.0
margin_right = 407.0
margin_bottom = 37.0
focus_neighbour_bottom = NodePath("../port")
size_flags_horizontal = 3
text = "127.0.0.1"
caret_blink = true
caret_blink_speed = 0.5
[node name="port_label" type="Label" parent="menu/GridContainer"]
margin_top = 41.0
margin_right = 65.0
margin_bottom = 78.0
size_flags_vertical = 1
text = "PORT"
valign = 1
[node name="port" type="LineEdit" parent="menu/GridContainer"]
margin_left = 69.0
margin_top = 41.0
margin_right = 407.0
margin_bottom = 78.0
focus_neighbour_top = NodePath("../ip")
focus_neighbour_bottom = NodePath("../../join")
text = "8128"
max_length = 5
caret_blink = true
caret_blink_speed = 0.5
[node name="join" type="Button" parent="menu"]
anchor_left = 1.0
anchor_top = 1.0
@ -37,9 +81,13 @@ anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -143.0
margin_top = -56.0
grow_horizontal = 0
grow_vertical = 0
rect_pivot_offset = Vector2( 1.89856, 0.845154 )
focus_neighbour_left = NodePath("../back")
focus_neighbour_top = NodePath("../GridContainer/port")
custom_fonts/font = ExtResource( 3 )
text = "Join"
text = "JOIN"
icon = ExtResource( 4 )
flat = true
@ -49,52 +97,13 @@ anchor_bottom = 1.0
margin_top = -56.0
margin_right = 132.001
rect_pivot_offset = Vector2( 0.606262, -0.447205 )
focus_neighbour_top = NodePath("../GridContainer/port")
focus_neighbour_right = NodePath("../join")
custom_fonts/font = ExtResource( 3 )
text = "Back"
text = "BACK"
icon = ExtResource( 5 )
flat = true
[node name="ip_label" type="Label" parent="menu"]
margin_left = 29.8937
margin_top = 31.5762
margin_right = 94.8937
margin_bottom = 58.5762
text = "Ip"
[node name="ip" type="LineEdit" parent="menu"]
margin_left = 140.0
margin_top = 22.0
margin_right = 422.0
margin_bottom = 60.0
text = "127.0.0.1"
[node name="port_label" type="Label" parent="menu"]
margin_left = 25.9189
margin_top = 88.3152
margin_right = 90.9189
margin_bottom = 115.315
text = "Port"
[node name="port" type="LineEdit" parent="menu"]
margin_left = 139.136
margin_top = 80.3719
margin_right = 247.136
margin_bottom = 117.372
text = "8128"
max_length = 5
[node name="error" type="Label" parent="menu"]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_left = -1.0
margin_top = 11.0
margin_right = -1.0
margin_bottom = 60.0
custom_colors/font_color = Color( 1, 0, 0.117647, 1 )
align = 1
valign = 1
[node name="error_dialog" type="AcceptDialog" parent="."]
margin_right = 138.0
margin_bottom = 84.0

69
scenes/menus/IngameMenu.tscn

@ -0,0 +1,69 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menus/ingame.gd" type="Script" id=2]
[ext_resource path="res://assets/icons/open.png" type="Texture" id=3]
[ext_resource path="res://assets/icons/wrench.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/arrowLeft.png" type="Texture" id=5]
[node name="ingame_menu" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -0.857361
margin_right = -0.857361
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" type="Panel" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -155.0
margin_top = -100.5
margin_right = 155.0
margin_bottom = 100.5
grow_horizontal = 2
grow_vertical = 2
[node name="GridContainer" type="GridContainer" parent="menu"]
anchor_right = 1.0
anchor_bottom = 1.0
[node name="resume" type="Button" parent="menu/GridContainer"]
margin_right = 310.0
margin_bottom = 64.0
focus_neighbour_top = NodePath("../end")
focus_neighbour_bottom = NodePath("../settings")
size_flags_horizontal = 3
size_flags_vertical = 3
text = "RESUME"
icon = ExtResource( 3 )
flat = true
[node name="settings" type="Button" parent="menu/GridContainer"]
margin_top = 68.0
margin_right = 310.0
margin_bottom = 132.0
focus_neighbour_top = NodePath("../resume")
focus_neighbour_bottom = NodePath("../end")
size_flags_horizontal = 3
size_flags_vertical = 3
text = "SETTINGS"
icon = ExtResource( 4 )
flat = true
[node name="end" type="Button" parent="menu/GridContainer"]
margin_top = 136.0
margin_right = 310.0
margin_bottom = 200.0
focus_neighbour_top = NodePath("../settings")
focus_neighbour_bottom = NodePath(".")
size_flags_horizontal = 3
size_flags_vertical = 3
text = "END_GAME"
icon = ExtResource( 5 )
flat = true
[connection signal="pressed" from="menu/GridContainer/resume" to="." method="_on_resume_pressed"]
[connection signal="pressed" from="menu/GridContainer/settings" to="." method="_on_settings_pressed"]
[connection signal="pressed" from="menu/GridContainer/end" to="." method="_on_end_pressed"]

147
scenes/menus/LobbyMenu.tscn

@ -0,0 +1,147 @@
[gd_scene load_steps=9 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menus/lobby.gd" type="Script" id=2]
[ext_resource path="res://scenes/menus/BaseMenu.tscn" type="PackedScene" id=3]
[ext_resource path="res://assets/icons/checkmark.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/question.png" type="Texture" id=5]
[ext_resource path="res://scenes/menus/SettingsPlayerMenu.tscn" type="PackedScene" id=6]
[ext_resource path="res://assets/fonts/Kenney Future Narrow.ttf" type="DynamicFontData" id=7]
[sub_resource type="DynamicFont" id=1]
size = 100
font_data = ExtResource( 7 )
[node name="lobby_menu" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 0.857376
margin_top = 0.857422
margin_right = 0.857422
margin_bottom = 0.857422
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" parent="." instance=ExtResource( 3 )]
[node name="back" parent="menu" index="0"]
focus_neighbour_right = NodePath("../ready")
[node name="top_bar" type="GridContainer" parent="menu"]
margin_left = 14.0
margin_top = 12.0
margin_right = 940.0
margin_bottom = 52.0
columns = 2
[node name="server_name" type="Label" parent="menu/top_bar"]
margin_right = 779.0
margin_bottom = 40.0
mouse_filter = 1
size_flags_horizontal = 3
size_flags_vertical = 1
text = "Server"
valign = 1
[node name="server_bots" type="CheckButton" parent="menu/top_bar"]
margin_left = 783.0
margin_right = 926.0
margin_bottom = 40.0
disabled = true
text = "Bots"
align = 2
[node name="mid" type="GridContainer" parent="menu"]
margin_left = 12.0
margin_top = 57.0
margin_right = 936.0
margin_bottom = 397.0
columns = 3
[node name="players" type="ItemList" parent="menu/mid"]
margin_right = 456.0
margin_bottom = 340.0
size_flags_horizontal = 3
[node name="ready_icon" type="Button" parent="menu/mid/players"]
visible = false
margin_right = 62.0
margin_bottom = 56.0
icon = ExtResource( 4 )
[node name="not_ready_icon" type="Button" parent="menu/mid/players"]
visible = false
margin_right = 62.0
margin_bottom = 56.0
icon = ExtResource( 5 )
[node name="VSeparator" type="VSeparator" parent="menu/mid"]
margin_left = 460.0
margin_right = 464.0
margin_bottom = 340.0
[node name="player_settings" parent="menu/mid" instance=ExtResource( 6 )]
margin_left = 468.0
margin_top = 0.0
margin_right = 924.0
margin_bottom = 340.0
[node name="name_label" parent="menu/mid/player_settings/GridContainer" index="0"]
margin_right = 456.0
margin_bottom = 27.0
[node name="name" parent="menu/mid/player_settings/GridContainer" index="1"]
margin_top = 31.0
margin_right = 456.0
margin_bottom = 68.0
focus_neighbour_bottom = NodePath("../color")
[node name="color_label" parent="menu/mid/player_settings/GridContainer" index="2"]
margin_top = 72.0
margin_right = 456.0
margin_bottom = 99.0
[node name="color" parent="menu/mid/player_settings/GridContainer" index="3"]
margin_top = 103.0
margin_right = 456.0
margin_bottom = 136.0
focus_neighbour_top = NodePath("../name")
focus_neighbour_bottom = NodePath("../../../../ready")
[node name="ready" type="CheckButton" parent="menu"]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -166.0
margin_top = -58.0
grow_vertical = 0
focus_neighbour_left = NodePath("../back")
focus_neighbour_top = NodePath("../mid/player_settings/GridContainer/color")
text = "READY"
flat = true
[node name="countdown" type="Label" parent="."]
visible = false
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -94.0
margin_top = -56.5
margin_right = 94.0
margin_bottom = 56.5
custom_fonts/font = SubResource( 1 )
text = "3"
align = 1
valign = 1
[node name="countdown_timer" type="Timer" parent="."]
process_mode = 0
wait_time = 3.0
one_shot = true
[connection signal="toggled" from="menu/ready" to="." method="_on_ready_toggled"]
[editable path="menu"]
[editable path="menu/mid/player_settings"]

108
scenes/menus/LocalGameMenu.tscn

@ -0,0 +1,108 @@
[gd_scene load_steps=7 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menus/local_game.gd" type="Script" id=2]
[ext_resource path="res://scenes/menus/SettingsPlayerMenu.tscn" type="PackedScene" id=3]
[ext_resource path="res://resources/ui/font.tres" type="DynamicFont" id=4]
[ext_resource path="res://assets/icons/exitRight.png" type="Texture" id=5]
[ext_resource path="res://assets/icons/return.png" type="Texture" id=6]
[node name="local_game_menu" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 0.857376
margin_top = 0.857422
margin_right = 0.857422
margin_bottom = 0.857422
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" type="Panel" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -217.5
margin_top = -130.5
margin_right = 217.5
margin_bottom = 130.5
grow_horizontal = 2
grow_vertical = 2
[node name="GridContainer" type="GridContainer" parent="menu"]
margin_left = 19.0
margin_top = 21.0
margin_right = 418.0
margin_bottom = 197.0
[node name="player_settings" parent="menu/GridContainer" instance=ExtResource( 3 )]
margin_left = 0.0
margin_top = 0.0
margin_right = 399.0
margin_bottom = 132.0
[node name="name_label" parent="menu/GridContainer/player_settings/GridContainer" index="0"]
margin_right = 399.0
margin_bottom = 27.0
[node name="name" parent="menu/GridContainer/player_settings/GridContainer" index="1"]
margin_top = 31.0
margin_right = 399.0
margin_bottom = 68.0
focus_neighbour_bottom = NodePath("../color")
[node name="color_label" parent="menu/GridContainer/player_settings/GridContainer" index="2"]
margin_top = 72.0
margin_right = 399.0
margin_bottom = 99.0
[node name="color" parent="menu/GridContainer/player_settings/GridContainer" index="3"]
margin_top = 103.0
margin_right = 399.0
margin_bottom = 136.0
focus_neighbour_top = NodePath("../name")
focus_neighbour_bottom = NodePath("../../../bots")
[node name="bots" type="CheckButton" parent="menu/GridContainer"]
margin_top = 136.0
margin_right = 143.0
margin_bottom = 176.0
focus_neighbour_top = NodePath("../player_settings/GridContainer/color")
focus_neighbour_bottom = NodePath("../../start")
size_flags_horizontal = 0
pressed = true
text = "BOTS"
flat = true
[node name="start" type="Button" parent="menu"]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -234.0
margin_top = -56.0
grow_horizontal = 0
rect_pivot_offset = Vector2( 1.89856, 0.845154 )
focus_neighbour_left = NodePath("../back")
focus_neighbour_top = NodePath("../GridContainer/bots")
custom_fonts/font = ExtResource( 4 )
text = "START_GAME"
icon = ExtResource( 5 )
flat = true
[node name="back" type="Button" parent="menu"]
anchor_top = 1.0
anchor_bottom = 1.0
margin_top = -56.0
margin_right = 132.0
rect_pivot_offset = Vector2( 0.606262, -0.447205 )
focus_neighbour_top = NodePath("../GridContainer/bots")
focus_neighbour_right = NodePath("../start")
custom_fonts/font = ExtResource( 4 )
text = "BACK"
icon = ExtResource( 6 )
flat = true
[connection signal="pressed" from="menu/start" to="." method="_on_start_pressed"]
[connection signal="pressed" from="menu/back" to="." method="_on_back_pressed"]
[editable path="menu/GridContainer/player_settings"]

90
scenes/menus/MainMenu.tscn

@ -0,0 +1,90 @@
[gd_scene load_steps=7 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menus/main.gd" type="Script" id=2]
[ext_resource path="res://assets/icons/massiveMultiplayer.png" type="Texture" id=3]
[ext_resource path="res://assets/icons/singleplayer.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/wrench.png" type="Texture" id=5]
[ext_resource path="res://assets/icons/power.png" type="Texture" id=6]
[node name="main_menu" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -0.857361
margin_right = -0.857361
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" type="Panel" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -155.0
margin_top = -132.5
margin_right = 155.0
margin_bottom = 132.5
grow_horizontal = 2
grow_vertical = 2
[node name="GridContainer" type="GridContainer" parent="menu"]
anchor_right = 1.0
anchor_bottom = 1.0
[node name="multiplayer" type="Button" parent="menu/GridContainer"]
margin_right = 310.0
margin_bottom = 63.0
focus_neighbour_top = NodePath("../quit")
focus_neighbour_bottom = NodePath("../practice")
size_flags_horizontal = 3
size_flags_vertical = 3
text = "MULTIPLAYER"
icon = ExtResource( 3 )
flat = true
[node name="practice" type="Button" parent="menu/GridContainer"]
margin_top = 67.0
margin_right = 310.0
margin_bottom = 130.0
focus_neighbour_top = NodePath("../multiplayer")
focus_neighbour_bottom = NodePath("../settings")
size_flags_horizontal = 3
size_flags_vertical = 3
text = "PRACTISE"
icon = ExtResource( 4 )
flat = true
[node name="settings" type="Button" parent="menu/GridContainer"]
margin_top = 134.0
margin_right = 310.0
margin_bottom = 197.0
focus_neighbour_top = NodePath("../practice")
focus_neighbour_bottom = NodePath("../quit")
size_flags_horizontal = 3
size_flags_vertical = 3
text = "SETTINGS"
icon = ExtResource( 5 )
flat = true
[node name="quit" type="Button" parent="menu/GridContainer"]
margin_top = 201.0
margin_right = 310.0
margin_bottom = 264.0
focus_neighbour_top = NodePath("../settings")
focus_neighbour_bottom = NodePath("../multiplayer")
size_flags_horizontal = 3
size_flags_vertical = 3
text = "QUIT"
icon = ExtResource( 6 )
flat = true
[node name="error_dialog" type="AcceptDialog" parent="."]
margin_right = 138.0
margin_bottom = 84.0
window_title = "ALERT"
dialog_text = "Server disconnected!"
[connection signal="pressed" from="menu/GridContainer/multiplayer" to="." method="_on_online_pressed"]
[connection signal="pressed" from="menu/GridContainer/multiplayer" to="." method="_on_multiplayer_pressed"]
[connection signal="pressed" from="menu/GridContainer/practice" to="." method="_on_practice_pressed"]
[connection signal="pressed" from="menu/GridContainer/settings" to="." method="_on_settings_pressed"]
[connection signal="pressed" from="menu/GridContainer/quit" to="." method="_on_quit_pressed"]

159
scenes/menus/MultiplayerMenu.tscn

@ -0,0 +1,159 @@
[gd_scene load_steps=11 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menus/server.gd" type="Script" id=2]
[ext_resource path="res://scenes/menus/BaseMenu.tscn" type="PackedScene" id=3]
[ext_resource path="res://assets/icons/cpu.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/exitRight.png" type="Texture" id=5]
[ext_resource path="res://assets/icons/car.png" type="Texture" id=6]
[ext_resource path="res://assets/icons/trophy.png" type="Texture" id=7]
[ext_resource path="res://assets/icons/locked.png" type="Texture" id=8]
[ext_resource path="res://assets/icons/massiveMultiplayer.png" type="Texture" id=9]
[ext_resource path="res://assets/icons/fistPlus.png" type="Texture" id=10]
[node name="multiplayer_menu" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -0.142624
margin_top = 2.85742
margin_right = -0.142578
margin_bottom = 2.85742
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" parent="." instance=ExtResource( 3 )]
[node name="back" parent="menu" index="0"]
focus_neighbour_top = NodePath("../games")
focus_neighbour_right = NodePath("../bottom_bar/refresh")
[node name="top_bar" type="GridContainer" parent="menu"]
anchor_right = 1.0
margin_bottom = 56.0
columns = 3
[node name="direct_host" type="Button" parent="menu/top_bar"]
margin_right = 239.0
margin_bottom = 56.0
focus_neighbour_right = NodePath("../direct_join")
focus_neighbour_bottom = NodePath("../../games")
text = "DIRECT_HOST"
icon = ExtResource( 4 )
flat = true
[node name="direct_join" type="Button" parent="menu/top_bar"]
margin_left = 243.0
margin_right = 473.0
margin_bottom = 56.0
focus_neighbour_left = NodePath("../direct_host")
focus_neighbour_right = NodePath("../open")
focus_neighbour_bottom = NodePath("../../games")
text = "DIRECT_JOIN"
icon = ExtResource( 5 )
flat = true
[node name="open" type="CheckButton" parent="menu/top_bar"]
margin_left = 477.0
margin_right = 945.0
margin_bottom = 56.0
focus_neighbour_left = NodePath("../direct_join")
focus_neighbour_bottom = NodePath("../../games")
size_flags_horizontal = 3
disabled = true
pressed = true
text = "OPEN_GAMES_ONLY"
align = 2
[node name="games" type="ItemList" parent="menu"]
margin_left = 13.0
margin_top = 60.0
margin_right = 931.0
margin_bottom = 414.0
focus_neighbour_top = NodePath("../top_bar/open")
focus_neighbour_bottom = NodePath("../bottom_bar/join")
[node name="open_icon" type="Button" parent="menu/games"]
visible = false
margin_right = 12.0
margin_bottom = 33.0
icon = ExtResource( 6 )
[node name="running_icon" type="Button" parent="menu/games"]
visible = false
margin_right = 12.0
margin_bottom = 33.0
icon = ExtResource( 7 )
[node name="private_icon" type="Button" parent="menu/games"]
visible = false
margin_right = 12.0
margin_bottom = 33.0
icon = ExtResource( 8 )
[node name="bottom_bar" type="GridContainer" parent="menu"]
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 380.0
margin_top = -56.0
grow_horizontal = 0
columns = 3
[node name="refresh" type="Button" parent="menu/bottom_bar"]
margin_right = 183.0
margin_bottom = 56.0
grow_horizontal = 0
focus_neighbour_left = NodePath("../../back")
focus_neighbour_top = NodePath("../../games")
focus_neighbour_right = NodePath("../create")
text = "REFRESH"
icon = ExtResource( 9 )
flat = true
align = 0
[node name="create" type="Button" parent="menu/bottom_bar"]
margin_left = 187.0
margin_right = 441.0
margin_bottom = 56.0
focus_neighbour_left = NodePath("../refresh")
focus_neighbour_top = NodePath("../../games")
focus_neighbour_right = NodePath("../join")
disabled = true
text = "CREATE_GAME"
icon = ExtResource( 10 )
flat = true
align = 2
[node name="join" type="Button" parent="menu/bottom_bar"]
margin_left = 445.0
margin_right = 565.0
margin_bottom = 56.0
focus_neighbour_left = NodePath("../create")
focus_neighbour_top = NodePath("../../games")
disabled = true
text = "JOIN"
icon = ExtResource( 5 )
flat = true
align = 2
[node name="error_dialog" type="AcceptDialog" parent="."]
margin_right = 138.0
margin_bottom = 84.0
window_title = "ALERT"
[node name="refresh_timer" type="Timer" parent="."]
wait_time = 5.0
autostart = true
[connection signal="draw" from="." to="." method="_on_multiplayer_menu_draw"]
[connection signal="hide" from="." to="." method="_on_multiplayer_menu_hide"]
[connection signal="pressed" from="menu/top_bar/direct_host" to="." method="_on_direct_host_pressed"]
[connection signal="pressed" from="menu/top_bar/direct_join" to="." method="_on_direct_join_pressed"]
[connection signal="toggled" from="menu/top_bar/open" to="." method="_on_open_toggled"]
[connection signal="item_selected" from="menu/games" to="." method="_on_games_item_selected"]
[connection signal="nothing_selected" from="menu/games" to="." method="_on_games_nothing_selected"]
[connection signal="pressed" from="menu/bottom_bar/refresh" to="." method="_on_refresh_pressed"]
[connection signal="pressed" from="menu/bottom_bar/create" to="." method="_on_create_pressed"]
[connection signal="pressed" from="menu/bottom_bar/join" to="." method="_on_join_pressed"]
[connection signal="timeout" from="refresh_timer" to="." method="_on_refresh_timer_timeout"]
[editable path="menu"]

99
scenes/menus/ServerCreateGameMenu.tscn

@ -0,0 +1,99 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menus/server_create.gd" type="Script" id=2]
[ext_resource path="res://resources/ui/font.tres" type="DynamicFont" id=3]
[ext_resource path="res://assets/icons/fistPlus.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/return.png" type="Texture" id=5]
[node name="server_create_menu" type="Control"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -512.0
margin_top = -300.0
margin_right = 512.0
margin_bottom = 300.0
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" type="Panel" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -217.5
margin_top = -68.5
margin_right = 217.5
margin_bottom = 68.5
grow_horizontal = 2
grow_vertical = 2
[node name="GridContainer" type="GridContainer" parent="menu"]
margin_left = 12.0
margin_top = 11.0
margin_right = 427.0
margin_bottom = 92.0
columns = 2
[node name="name_label" type="Label" parent="menu/GridContainer"]
margin_top = 5.0
margin_right = 162.0
margin_bottom = 32.0
text = "GAME_NAME"
[node name="name" type="LineEdit" parent="menu/GridContainer"]
margin_left = 166.0
margin_right = 415.0
margin_bottom = 37.0
focus_neighbour_left = NodePath("../../back")
focus_neighbour_right = NodePath("../../create")
focus_neighbour_bottom = NodePath("../bots")
size_flags_horizontal = 3
[node name="bots" type="CheckButton" parent="menu/GridContainer"]
margin_top = 41.0
margin_right = 143.0
margin_bottom = 81.0
focus_neighbour_left = NodePath("../../back")
focus_neighbour_top = NodePath("../name")
focus_neighbour_right = NodePath("../../create")
focus_neighbour_bottom = NodePath("../../create")
size_flags_horizontal = 0
text = "BOTS"
[node name="create" type="Button" parent="menu"]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -255.0
margin_top = -56.0001
margin_right = -1.0
grow_horizontal = 0
grow_vertical = 0
rect_pivot_offset = Vector2( 1.89856, 0.845154 )
focus_neighbour_left = NodePath("../back")
focus_neighbour_top = NodePath("../GridContainer/bots")
focus_neighbour_right = NodePath("../GridContainer/name")
custom_fonts/font = ExtResource( 3 )
text = "CREATE_GAME"
icon = ExtResource( 4 )
flat = true
[node name="back" type="Button" parent="menu"]
anchor_top = 1.0
anchor_bottom = 1.0
margin_top = -56.0
margin_right = 132.0
rect_pivot_offset = Vector2( 0.606262, -0.447205 )
focus_neighbour_top = NodePath("../GridContainer/bots")
focus_neighbour_right = NodePath("../create")
custom_fonts/font = ExtResource( 3 )
text = "Back"
icon = ExtResource( 5 )
flat = true
[connection signal="text_changed" from="menu/GridContainer/name" to="." method="_on_name_text_changed"]
[connection signal="pressed" from="menu/create" to="." method="_on_create_pressed"]
[connection signal="pressed" from="menu/back" to="." method="_on_back_pressed"]

189
scenes/menus/SettingsControlsMenu.tscn

@ -0,0 +1,189 @@
[gd_scene load_steps=20 format=2]
[ext_resource path="res://scripts/menus/settings_controls.gd" type="Script" id=1]
[ext_resource path="res://assets/icons/keySmall_3d.png" type="Texture" id=2]
[ext_resource path="res://assets/icons/buttonA.png" type="Texture" id=3]
[ext_resource path="res://assets/icons/buttonB.png" type="Texture" id=4]
[ext_resource path="res://assets/icons/buttonX.png" type="Texture" id=5]
[ext_resource path="res://assets/icons/buttonY.png" type="Texture" id=6]
[ext_resource path="res://assets/icons/buttonL1.png" type="Texture" id=7]
[ext_resource path="res://assets/icons/buttonR1.png" type="Texture" id=8]
[ext_resource path="res://assets/icons/buttonL2.png" type="Texture" id=9]
[ext_resource path="res://assets/icons/buttonR2.png" type="Texture" id=10]
[ext_resource path="res://assets/icons/buttonL.png" type="Texture" id=11]
[ext_resource path="res://assets/icons/buttonR.png" type="Texture" id=12]
[ext_resource path="res://assets/icons/buttonSelect.png" type="Texture" id=13]
[ext_resource path="res://assets/icons/buttonStart.png" type="Texture" id=14]
[ext_resource path="res://assets/icons/DPAD_up.png" type="Texture" id=15]
[ext_resource path="res://assets/icons/DPAD_down.png" type="Texture" id=16]
[ext_resource path="res://assets/icons/DPAD_left.png" type="Texture" id=17]
[ext_resource path="res://assets/icons/DPAD_right.png" type="Texture" id=18]
[ext_resource path="res://assets/icons/fightJ.png" type="Texture" id=19]
[node name="settings_controls_menu" type="Control"]
margin_left = 12.0
margin_top = 8.0
margin_right = 858.0
margin_bottom = 335.0
script = ExtResource( 1 )
[node name="key_dialog" type="ConfirmationDialog" parent="."]
margin_left = 18.0
margin_top = 16.0
margin_right = 311.0
margin_bottom = 100.0
popup_exclusive = true
window_title = ""
dialog_text = "Press any key..."
[node name="ScrollContainer" type="ScrollContainer" parent="."]
editor/display_folded = true
anchor_right = 1.0
anchor_bottom = 1.0
[node name="grid" type="GridContainer" parent="ScrollContainer"]
margin_right = 846.0
margin_bottom = 327.0
size_flags_horizontal = 3
size_flags_vertical = 3
columns = 3
[node name="empty" type="Label" parent="ScrollContainer/grid"]
margin_bottom = 14.0
[node name="keyboard_label" type="Label" parent="ScrollContainer/grid"]
margin_left = 4.0
margin_right = 423.0
margin_bottom = 14.0
size_flags_horizontal = 3
text = "KEYBOARD"
align = 1
valign = 1
[node name="joypad_label" type="Label" parent="ScrollContainer/grid"]
margin_left = 427.0
margin_right = 846.0
margin_bottom = 14.0
size_flags_horizontal = 3
text = "JOYPAD"
align = 1
valign = 1
[node name="icons" type="GridContainer" parent="."]
visible = false
margin_right = 40.0
margin_bottom = 40.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="key" type="Button" parent="icons"]
margin_right = 62.0
margin_bottom = 56.0
icon = ExtResource( 2 )
[node name="joypad" type="GridContainer" parent="icons"]
editor/display_folded = true
margin_top = 60.0
margin_right = 62.0
margin_bottom = 1076.0
[node name="0" type="Button" parent="icons/joypad"]
margin_right = 62.0
margin_bottom = 56.0
icon = ExtResource( 3 )
[node name="1" type="Button" parent="icons/joypad"]
margin_top = 60.0
margin_right = 62.0
margin_bottom = 116.0
icon = ExtResource( 4 )
[node name="2" type="Button" parent="icons/joypad"]
margin_top = 120.0
margin_right = 62.0
margin_bottom = 176.0
icon = ExtResource( 5 )
[node name="3" type="Button" parent="icons/joypad"]
margin_top = 180.0
margin_right = 62.0
margin_bottom = 236.0
icon = ExtResource( 6 )
[node name="4" type="Button" parent="icons/joypad"]
margin_top = 240.0
margin_right = 62.0
margin_bottom = 296.0
icon = ExtResource( 7 )
[node name="5" type="Button" parent="icons/joypad"]
margin_top = 300.0
margin_right = 62.0
margin_bottom = 356.0
icon = ExtResource( 8 )
[node name="6" type="Button" parent="icons/joypad"]
margin_top = 360.0
margin_right = 62.0
margin_bottom = 416.0
icon = ExtResource( 9 )
[node name="7" type="Button" parent="icons/joypad"]
margin_top = 420.0
margin_right = 62.0
margin_bottom = 476.0
icon = ExtResource( 10 )
[node name="8" type="Button" parent="icons/joypad"]
margin_top = 480.0
margin_right = 62.0
margin_bottom = 536.0
icon = ExtResource( 11 )
[node name="9" type="Button" parent="icons/joypad"]
margin_top = 540.0
margin_right = 62.0
margin_bottom = 596.0
icon = ExtResource( 12 )
[node name="10" type="Button" parent="icons/joypad"]
margin_top = 600.0
margin_right = 62.0
margin_bottom = 656.0
icon = ExtResource( 13 )
[node name="11" type="Button" parent="icons/joypad"]
margin_top = 660.0
margin_right = 62.0
margin_bottom = 716.0
icon = ExtResource( 14 )
[node name="12" type="Button" parent="icons/joypad"]
margin_top = 720.0
margin_right = 62.0
margin_bottom = 776.0
icon = ExtResource( 15 )
[node name="13" type="Button" parent="icons/joypad"]
margin_top = 780.0
margin_right = 62.0
margin_bottom = 836.0
icon = ExtResource( 16 )
[node name="14" type="Button" parent="icons/joypad"]
margin_top = 840.0
margin_right = 62.0
margin_bottom = 896.0
icon = ExtResource( 17 )
[node name="15" type="Button" parent="icons/joypad"]
margin_top = 900.0
margin_right = 62.0
margin_bottom = 956.0
icon = ExtResource( 18 )
[node name="other" type="Button" parent="icons/joypad"]
margin_top = 960.0
margin_right = 62.0
margin_bottom = 1016.0
icon = ExtResource( 19 )

156
scenes/menus/SettingsMenu.tscn

@ -0,0 +1,156 @@
[gd_scene load_steps=7 format=2]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=1]
[ext_resource path="res://scripts/menus/settings.gd" type="Script" id=2]
[ext_resource path="res://scenes/menus/BaseMenu.tscn" type="PackedScene" id=3]
[ext_resource path="res://scenes/menus/SettingsPlayerMenu.tscn" type="PackedScene" id=4]
[ext_resource path="res://scenes/menus/SettingsControlsMenu.tscn" type="PackedScene" id=5]
[ext_resource path="res://assets/icons/save.png" type="Texture" id=6]
[node name="settings_menu" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 1.45612
margin_top = 1.45612
margin_right = 1.45605
margin_bottom = 1.45612
theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="menu" parent="." instance=ExtResource( 3 )]
[node name="tabs" type="TabContainer" parent="menu"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -464.5
margin_top = -223.5
margin_right = 459.5
margin_bottom = 177.5
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
tab_align = 0
[node name="game" type="Tabs" parent="menu/tabs"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 4.0
margin_top = 45.0
margin_right = -4.0
margin_bottom = -4.0
[node name="GridContainer" type="GridContainer" parent="menu/tabs/game"]
margin_left = 9.0
margin_top = 10.0
margin_right = 416.0
margin_bottom = 200.0
[node name="settings_player" parent="menu/tabs/game/GridContainer" instance=ExtResource( 4 )]
margin_left = 0.0
margin_top = 0.0
margin_right = 407.0
margin_bottom = 146.0
[node name="name_label" parent="menu/tabs/game/GridContainer/settings_player/GridContainer" index="0"]
margin_right = 407.0
margin_bottom = 27.0
[node name="name" parent="menu/tabs/game/GridContainer/settings_player/GridContainer" index="1"]
margin_top = 31.0
margin_right = 407.0
margin_bottom = 68.0
[node name="color_label" parent="menu/tabs/game/GridContainer/settings_player/GridContainer" index="2"]
margin_top = 72.0
margin_right = 407.0
margin_bottom = 99.0
[node name="color" parent="menu/tabs/game/GridContainer/settings_player/GridContainer" index="3"]
margin_top = 103.0
margin_right = 407.0
margin_bottom = 136.0
[node name="bots" type="CheckButton" parent="menu/tabs/game/GridContainer"]
margin_top = 150.0
margin_right = 143.0
margin_bottom = 190.0
size_flags_horizontal = 0
size_flags_vertical = 0
text = "Bots"
[node name="controls" type="Tabs" parent="menu/tabs"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 4.0
margin_top = 45.0
margin_right = -4.0
margin_bottom = -4.0
[node name="settings_controls" parent="menu/tabs/controls" instance=ExtResource( 5 )]
[node name="graphics" type="Tabs" parent="menu/tabs"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 4.0
margin_top = 45.0
margin_right = -4.0
margin_bottom = -4.0
[node name="system" type="Tabs" parent="menu/tabs"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 4.0
margin_top = 45.0
margin_right = -4.0
margin_bottom = -4.0
[node name="GridContainer" type="GridContainer" parent="menu/tabs/system"]
margin_left = 12.0
margin_top = 8.0
margin_right = 476.0
margin_bottom = 124.0
columns = 2
[node name="locale_label" type="Label" parent="menu/tabs/system/GridContainer"]
margin_right = 102.0
margin_bottom = 27.0
text = "LOCALE"
valign = 1
[node name="locales" type="ItemList" parent="menu/tabs/system/GridContainer"]
margin_left = 106.0
margin_right = 464.0
margin_bottom = 27.0
size_flags_horizontal = 3
auto_height = true
[node name="save" type="Button" parent="menu"]
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -147.0
margin_top = -56.0
grow_horizontal = 0
grow_vertical = 0
size_flags_horizontal = 3
size_flags_vertical = 3
text = "SAVE"
icon = ExtResource( 6 )
flat = true
[connection signal="item_selected" from="menu/tabs/system/GridContainer/locales" to="." method="_on_locales_item_selected"]
[connection signal="tree_exiting" from="menu/tabs/system/GridContainer/locales" to="." method="_on_locales_tree_exiting"]
[connection signal="visibility_changed" from="menu/tabs/system/GridContainer/locales" to="." method="_init_locales"]
[connection signal="pressed" from="menu/save" to="." method="_on_save_pressed"]
[editable path="menu"]
[editable path="menu/tabs/game/GridContainer/settings_player"]
[editable path="menu/tabs/controls/settings_controls"]

39
scenes/menus/SettingsPlayerMenu.tscn

@ -0,0 +1,39 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://scripts/menus/settings_player.gd" type="Script" id=1]
[node name="settings_player_menu" type="Control"]
margin_left = 513.0
margin_top = 23.0
margin_right = 878.0
margin_bottom = 116.0
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource( 1 )
[node name="GridContainer" type="GridContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
[node name="name_label" type="Label" parent="GridContainer"]
margin_right = 365.0
margin_bottom = 14.0
text = "PLAYER_NAME"
[node name="name" type="LineEdit" parent="GridContainer"]
margin_top = 18.0
margin_right = 365.0
margin_bottom = 42.0
size_flags_horizontal = 3
[node name="color_label" type="Label" parent="GridContainer"]
margin_top = 46.0
margin_right = 365.0
margin_bottom = 60.0
text = "PLAYER_COLOR"
[node name="color" type="ColorPickerButton" parent="GridContainer"]
margin_top = 64.0
margin_right = 365.0
margin_bottom = 84.0
size_flags_horizontal = 3

6
scenes/player/BotPlayer.tscn

@ -1,7 +1,9 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://scripts/player/BotControls.gd" type="Script" id=1]
[ext_resource path="res://scripts/player/BotInventory.gd" type="Script" id=2]
[ext_resource path="res://scripts/player/bot_controls.gd" type="Script" id=1]
[ext_resource path="res://scripts/player/bot_inventory.gd" type="Script" id=2]
[node name="BotPlayer" type="Spatial"]
script = ExtResource( 1 )

30
scenes/player/HumanPlayer.tscn

@ -1,21 +1,22 @@
[gd_scene load_steps=10 format=2]
[gd_scene load_steps=11 format=2]
[ext_resource path="res://scripts/player/HumanControls.gd" type="Script" id=1]
[ext_resource path="res://scripts/player/human_controls.gd" type="Script" id=1]
[ext_resource path="res://assets/fonts/Kenney Future Narrow.ttf" type="DynamicFontData" id=2]
[ext_resource path="res://scenes/menu/ingame.tscn" type="PackedScene" id=3]
[ext_resource path="res://scripts/player/HumanInventory.gd" type="Script" id=4]
[ext_resource path="res://scenes/road/roadStraightLong.tscn" type="PackedScene" id=5]
[ext_resource path="res://scripts/player/InventoryPreview.gd" type="Script" id=6]
[ext_resource path="res://resources/ui/theme.tres" type="Theme" id=3]
[ext_resource path="res://scenes/menus/IngameMenu.tscn" type="PackedScene" id=4]
[ext_resource path="res://scripts/player/human_inventory.gd" type="Script" id=5]
[ext_resource path="res://scenes/road/roadStraightLong.tscn" type="PackedScene" id=6]
[ext_resource path="res://scripts/player/inventory_preview.gd" type="Script" id=7]
[sub_resource type="ViewportTexture" id=1]
viewport_path = NodePath("inventory/viewport")
[sub_resource type="DynamicFont" id=2]
size = 11
size = 14
font_data = ExtResource( 2 )
[sub_resource type="DynamicFont" id=3]
size = 100
size = 85
font_data = ExtResource( 2 )
[node name="HumanPlayer" type="Spatial"]
@ -65,6 +66,7 @@ margin_top = -39.0
margin_right = 77.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource( 3 )
align = 1
valign = 1
@ -84,12 +86,12 @@ align = 1
valign = 1
uppercase = true
[node name="ingame_menu" parent="hud" instance=ExtResource( 3 )]
[node name="ingame_menu" parent="hud" instance=ExtResource( 4 )]
visible = false
[node name="inventory" type="Spatial" parent="."]
editor/display_folded = true
script = ExtResource( 4 )
script = ExtResource( 5 )
[node name="viewport" type="Viewport" parent="inventory"]
size = Vector2( 150, 150 )
@ -107,8 +109,12 @@ far = 20.0
[node name="view" type="Spatial" parent="inventory"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -50, -1000, 0 )
[node name="roadStraightLong" parent="inventory/view" instance=ExtResource( 5 )]
[node name="roadStraightLong" parent="inventory/view" instance=ExtResource( 6 )]
transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, 0, 0 )
[node name="preview" type="Spatial" parent="inventory"]
script = ExtResource( 6 )
script = ExtResource( 7 )
[node name="camera" type="InterpolatedCamera" parent="."]
fov = 100.0
far = 250.0

4
scenes/player/Player.tscn

@ -1,7 +1,7 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://scripts/player/Player.gd" type="Script" id=1]
[ext_resource path="res://scripts/player/raceCar.gd" type="Script" id=2]
[ext_resource path="res://scripts/player/player.gd" type="Script" id=1]
[ext_resource path="res://scripts/player/race_car.gd" type="Script" id=2]
[ext_resource path="res://assets/raceCar/body.obj" type="ArrayMesh" id=3]
[ext_resource path="res://assets/raceCar/wheel.obj" type="ArrayMesh" id=4]

12
scenes/road/roadBump.tscn

@ -1,13 +1,19 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadBump.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadBump.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadBump.tres" type="Curve3D" id=3]
[node name="roadBump" type="MeshInstance"]
transform = Transform( 1, 0, 0, 0, 1, -0.0001179, 0, 0.0001179, 1, 0, 0, 0 )
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
reset_index = 1
speed_constrains = PoolVector3Array( 0.45, 0.8, 0.09, 0.45, 0.8, -0.02, 1.15, 1.55, 0.09 )
force_penalties = PoolVector3Array( 0, 30, 20, 0, 0, -30, 0, 20, 20 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

3
scenes/road/roadCornerSmall.tscn

@ -11,8 +11,7 @@ material/1 = null
material/2 = null
script = ExtResource( 2 )
end_rotation = Vector3( 0, -1.571, 0 )
end_rotation_phi = -1.571
speed_constrains = PoolVector3Array( 0.1, 0.97, 0.07 )
speed_constrains = PoolVector3Array( 0.1, 0.79, 0.07 )
force_penalties = PoolVector3Array( 0, 0, 50 )
torque_penalties = PoolVector3Array( 0, 0, 2 )

1
scenes/road/roadCornerSmallFlipped.tscn

@ -11,7 +11,6 @@ material/1 = null
material/2 = null
script = ExtResource( 2 )
end_rotation = Vector3( 0, 1.571, 0 )
end_rotation_phi = 1.571
speed_constrains = PoolVector3Array( 0.1, 0.79, 0.07 )
force_penalties = PoolVector3Array( 0, 0, 50 )
torque_penalties = PoolVector3Array( 0, 0, -2 )

8
scenes/road/roadRamp.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadRamp.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadRamp.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadRamp.tres" type="Curve3D" id=3]
[node name="roadRamp" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

8
scenes/road/roadRampFlipped.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadRampFlipped.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadRampFlipped.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadRampFlipped.tres" type="Curve3D" id=3]
[node name="roadRampFlipped" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

8
scenes/road/roadRampLong.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadRampLong.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadRampLong.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadRampLong.tres" type="Curve3D" id=3]
[node name="roadRampLong" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

8
scenes/road/roadRampLongCurved.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadRampLongCurved.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadRampLongCurved.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadRampLongCurved.tres" type="Curve3D" id=3]
[node name="roadRampLongCurved" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

8
scenes/road/roadRampLongCurvedFlipped.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadRampLongCurvedFlipped.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadRampLongCurvedFlipped.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadRampLongCurvedFlipped.tres" type="Curve3D" id=3]
[node name="roadRampLongCurvedFlipped" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

8
scenes/road/roadRampLongFlipped.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadRampLongFlipped.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadRampLongFlipped.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadRampLongFlipped.tres" type="Curve3D" id=3]
[node name="roadRampLongFlipped" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

12
scenes/road/roadStart.tscn

@ -1,8 +1,9 @@
[gd_scene load_steps=4 format=2]
[gd_scene load_steps=5 format=2]
[ext_resource path="res://assets/road/roadStart.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadStart.tres" type="Curve3D" id=2]
[ext_resource path="res://scenes/lanes/start.tscn" type="PackedScene" id=3]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadStart.tres" type="Curve3D" id=3]
[ext_resource path="res://scenes/lanes/StartLanes.tscn" type="PackedScene" id=4]
[node name="roadStart" type="MeshInstance"]
mesh = ExtResource( 1 )
@ -12,10 +13,11 @@ material/2 = null
material/3 = null
material/4 = null
material/5 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )
[node name="lanes" parent="." instance=ExtResource( 3 )]
[node name="lanes" parent="." instance=ExtResource( 4 )]
[editable path="lanes"]

8
scenes/road/roadStraight.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadStraight.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadStraight.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadStraight.tres" type="Curve3D" id=3]
[node name="roadStraight" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

8
scenes/road/roadStraightArrow.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadStraightArrow.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadStraightArrow.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadStraightArrow.tres" type="Curve3D" id=3]
[node name="roadStraightArrow" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

8
scenes/road/roadStraightLong.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadStraightLong.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadStraightLong.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadStraightLong.tres" type="Curve3D" id=3]
[node name="roadStraightLong" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

8
scenes/road/roadStraightLongBump.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadStraightLongBump.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadStraightLongBump.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadStraightLongBump.tres" type="Curve3D" id=3]
[node name="roadStraightLongBump" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

4
scenes/road/roadStraightLongBumpRound.tscn

@ -1,9 +1,11 @@
[gd_scene load_steps=2 format=2]
[gd_scene load_steps=3 format=2]
[ext_resource path="res://assets/road/roadStraightLongBumpRound.obj" type="ArrayMesh" id=1]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[node name="roadStraightLongBumpRound" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )

8
scenes/road/roadStraightLongMid.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadStraightLongMid.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadStraightLongMid.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadStraightLongMid.tres" type="Curve3D" id=3]
[node name="roadStraightLongMid" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

8
scenes/road/roadStraightSkew.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadStraightSkew.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadStraightSkew.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadStraightSkew.tres" type="Curve3D" id=3]
[node name="roadStraightSkew" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

8
scenes/road/roadStraightSkewFlipped.tscn

@ -1,13 +1,15 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=4 format=2]
[ext_resource path="res://assets/road/roadStraightSkewFlipped.obj" type="ArrayMesh" id=1]
[ext_resource path="res://resources/road/roadStraightSkewFlipped.tres" type="Curve3D" id=2]
[ext_resource path="res://scripts/road/road.gd" type="Script" id=2]
[ext_resource path="res://resources/road/roadStraightSkewFlipped.tres" type="Curve3D" id=3]
[node name="roadStraightSkewFlipped" type="MeshInstance"]
mesh = ExtResource( 1 )
material/0 = null
material/1 = null
material/2 = null
script = ExtResource( 2 )
[node name="Path" type="Path" parent="."]
curve = ExtResource( 2 )
curve = ExtResource( 3 )

8
scripts/Util.gd

@ -2,5 +2,11 @@ extends Node
class_name Util
static func Curve_get_last_point(curve:Curve3D):
static func clear_node(node:Node):
for idx in range(node.get_child_count()):
node.remove_child(node.get_child(0))
static func curve_get_last_point(curve:Curve3D):
return curve.get_point_position(curve.get_point_count() - 1)

172
scripts/game/game.gd

@ -3,96 +3,22 @@ extends Node
const MAX_PEERS = 4
const LOBBY_READY_WAIT_TIME = 3
var world_scene = preload("res://scenes/game/world.tscn")
var player_scene = preload("res://scenes/player/Player.tscn")
var human_player_scene = preload("res://scenes/player/HumanPlayer.tscn")
var bot_player_scene = preload("res://scenes/player/BotPlayer.tscn")
var World = preload("res://scenes/game/World.tscn")
var Player = preload("res://scenes/player/Player.tscn")
var HumanPlayer = preload("res://scenes/player/HumanPlayer.tscn")
var BotPlayer = preload("res://scenes/player/BotPlayer.tscn")
var players = {}
var game_name = ""
var bots:bool = false
var game_running:bool = false
var dedicated_server:bool = false
var game_ready_timer:Timer
signal players_changed(players)
signal connection_failed()
signal connection_succeeded()
signal server_disconnected()
signal game_ready(ready)
signal game_started()
signal game_ended()
signal game_error(type, data)
func _ready():
for argument in OS.get_cmdline_args():
if argument.split("=")[0] == "--port":
var err = host_game(int(argument.split("=")[1]))
if err != OK:
print("Could not create Server!")
get_tree().quit()
dedicated_server = true
func host_game(port:int):
var host = NetworkedMultiplayerENet.new()
var err = host.create_server(port, MAX_PEERS)
get_tree().set_network_peer(host)
get_tree().connect("network_peer_connected", self, "_player_connected")
get_tree().connect("network_peer_disconnected", self,"_player_disconnected")
if game_ready_timer == null:
game_ready_timer = Timer.new()
game_ready_timer.set_name("game_ready_timer")
game_ready_timer.set_timer_process_mode(Timer.TIMER_PROCESS_PHYSICS)
game_ready_timer.set_one_shot(true)
game_ready_timer.set_autostart(false)
game_ready_timer.set_wait_time(LOBBY_READY_WAIT_TIME)
game_ready_timer.connect("timeout",self,"start_game")
add_child(game_ready_timer)
if err == OK:
print("Game hosted on Port " + str(port))
else:
emit_signal("game_error", "HOST", err)
return err
func join_game(ip, port:int):
get_tree().connect("connected_to_server", self, "_connected_ok")
get_tree().connect("connection_failed", self, "_connected_fail")
get_tree().connect("server_disconnected", self, "_server_disconnected")
var host = NetworkedMultiplayerENet.new()
host.create_client(ip, port)
get_tree().set_network_peer(host)
func _connected_ok():
rpc("set_player", get_tree().get_network_unique_id())
emit_signal("connection_succeeded")
func _connected_fail():
get_tree().disconnect("connected_to_server", self, "_connected_ok")
get_tree().disconnect("connection_failed", self, "_connected_fail")
get_tree().disconnect("server_disconnected", self, "_server_disconnected")
get_tree().set_network_peer(null)
emit_signal("connection_failed")
func _server_disconnected():
quit_game()
emit_signal("server_disconnected")
func _player_connected(id):
pass
func _player_disconnected(id):
if get_tree().is_network_server():
print("disconnect: " + str(id))
if game_running: # Game is in progress
emit_signal("game_error", "DISCONNECTED", [id])
rpc("remove_player" ,id)
# TODO!
else:
rpc("remove_player" ,id)
remote func set_player(id, new_name:String = " ", new_color:Color = Color.black, new_ready:bool = false):
players[id] = {"name" : new_name, "color" : new_color, "ready" : new_ready, "prepared" : false}
@ -104,16 +30,16 @@ remote func set_player(id, new_name:String = " ", new_color:Color = Color.black,
rpc_id(id, "set_player", p_id, players[p_id].name, players[p_id].color, players[p_id].ready)
rpc_id(p_id, "set_player", id, new_name, new_color, new_ready)
all_ready = all_ready && players[p_id].ready
print("set_player:")
print(players[id])
rpc("game_ready", all_ready)
func update_player(new_name:String = " ", new_color:Color = Color.black, new_ready:bool = false):
if get_tree().is_network_server():
set_player(get_tree().get_network_unique_id(), new_name, new_color, new_ready)
else:
rpc("set_player",get_tree().get_network_unique_id(), new_name, new_color, new_ready)
remotesync func remove_player(id):
players.erase(id)
@ -125,24 +51,20 @@ remotesync func remove_player(id):
emit_signal("players_changed", players)
if get_tree().is_network_server() && game_running && dedicated_server && players.empty():
print("All players disconnected, close server!")
get_tree().quit()
remotesync func game_ready(all_ready:bool):
if get_tree().is_network_server():
print("game ready: " + str(all_ready))
if all_ready:
game_ready_timer.start()
game_running = true
else:
game_ready_timer.stop()
game_running = false
emit_signal("game_ready", all_ready)
remotesync func prepare_game(bots:bool):
remotesync func prepare_game():
get_tree().set_pause(true)
var world = world_scene.instance()
var world = World.instance()
get_tree().get_root().add_child(world)
get_tree().get_root().get_node("main_menu").hide()
@ -151,55 +73,47 @@ remotesync func prepare_game(bots:bool):
var controls
var player = players[p_id]
var _player_scene = player_scene.instance()
_player_scene.set_network_master(p_id)
_player_scene.set_name(str(p_id))
_player_scene.set_player_name(player.name)
_player_scene.set_player_color(player.color)
world.get_node("players").add_child(_player_scene)
var player_scene = Player.instance()
player_scene.set_network_master(p_id)
player_scene.set_name(str(p_id))
player_scene.set_player_name(player.name)
player_scene.set_player_color(player.color)
world.get_node("players").add_child(player_scene)
if p_id == get_tree().get_network_unique_id():
controls = human_player_scene.instance()
controls = HumanPlayer.instance()
controls.set_name("HumanControl_" + str(p_id))
world.add_child(controls)
controls.set_player(_player_scene.get_path())
controls.set_player(player_scene.get_path())
controls.set_network_master(p_id)
_player_scene.set_start(_player_scene.get_index())
player_scene.set_start(player_scene.get_index())
if bots:
for index in range(MAX_PEERS-players.size()):
var bot_index = players.size() + index
var _player_scene = player_scene.instance()
_player_scene.set_name("bot_player" + str(bot_index))
world.get_node("players").add_child(_player_scene)
_player_scene.add_to_group("bots")
var player_scene = Player.instance()
player_scene.set_name("bot_player" + str(bot_index))
player_scene.set_player_color(Color(randf(),randf(),randf()))
world.get_node("players").add_child(player_scene)
player_scene.add_to_group("bots")
if get_tree().is_network_server():
var bot = bot_player_scene.instance()
var bot = BotPlayer.instance()
bot.set_name("bot" + str(bot_index))
world.add_child(bot)
bot.set_player(_player_scene.get_path())
bot.set_player(player_scene.get_path())
bot.set_network_master(get_tree().get_network_unique_id())
_player_scene.set_start(bot_index)
player_scene.set_start(bot_index)
if players.has(get_tree().get_network_unique_id()):
rpc_id(1, "player_prepared", get_tree().get_network_unique_id())
if get_tree().is_network_server():
if players.has(get_tree().get_network_unique_id()):
player_prepared(get_tree().get_network_unique_id())
print("prepare game")
print(players)
else:
rpc_id(1, "player_prepared", get_tree().get_network_unique_id())
func start_game():
if get_tree().is_network_server():
get_tree().set_refuse_new_network_connections(true)
print("start game")
rpc("prepare_game", false)
remotesync func player_prepared(id):
if get_tree().is_network_server():
players[id].prepared = true
@ -209,26 +123,28 @@ remotesync func player_prepared(id):
if all_prepared:
rpc("post_start_game")
remotesync func post_start_game():
get_tree().set_pause(false)
game_running = true
emit_signal("game_started")
func local_game(name:String, color:Color, bots:bool):
var localhost = NetworkedMultiplayerENet.new()
localhost.create_server(0, 0)
get_tree().set_network_peer(localhost)
players[get_tree().get_network_unique_id()] = { "name" : name, "color" : color }
prepare_game(bots)
post_start_game()
remotesync func set_bots(has_bots:bool):
bots = has_bots
func quit_game():
if has_node("/root/world"):
get_node("/root/world").queue_free()
players.clear()
get_tree().set_refuse_new_network_connections(false)
get_tree().set_network_peer(null)
get_tree().get_root().get_node("main_menu").show()
if get_tree().get_root().has_node("multiplayer_menu"):
get_tree().get_root().get_node("multiplayer_menu").show()
get_tree().get_root().get_node("main_menu").hide()
elif get_tree().get_root().has_node("main_menu"):
get_tree().get_root().get_node("main_menu").show()
game_running = false
bots = false
game_name = ""
emit_signal("game_ended")

13
scripts/game/local_storage.gd

@ -2,6 +2,11 @@ extends Node
const FILE_PATH = "user://local_storage"
func _ready():
TranslationServer.set_locale(read_value("locale","en"))
func read_content():
var f = File.new()
var err = f.open(FILE_PATH, File.READ)
@ -11,6 +16,7 @@ func read_content():
f.close()
return content
func write_content(content:Dictionary):
var f = File.new()
var err = f.open(FILE_PATH, File.WRITE)
@ -18,28 +24,33 @@ func write_content(content:Dictionary):
f.store_string(to_json(content))
f.close()
func write_value(key:String, value):
var content = read_content()
content[key] = value
write_content(content)
func read_value(key:String, default = null):
var content = read_content()
if content.has(key):
if content.has(key) && content.get(key) != null:
return content.get(key)
else:
return default
func delete_value(key:String):
var content = read_content()
content.erase(key)
write_content(content)
func write_values(new_content:Dictionary):
var content = read_content()
for key in new_content:
content[key] = new_content[key]
write_content(content)
func read_values():
return read_content()

5
scripts/game/route.gd

@ -5,18 +5,22 @@ class_name Route
signal road_added(road)
signal road_removed(road)
func get_last_road():
if get_child_count() > 0:
return get_child(get_child_count() - 1)
else:
return null
func get_road(road_index):
return get_child(road_index)
remotesync func set_network_master(id:int, recursive:bool = true):
.set_network_master(id)
remotesync func add_road(type, creator):
var transform = get_global_transform()
var last_road = get_last_road()
@ -41,6 +45,7 @@ remotesync func add_road(type, creator):
emit_signal("road_added", new_road)
remotesync func remove_road(road_index):
var road = get_child(road_index)
remove_child(road)

10
scripts/game/world.gd

@ -5,7 +5,8 @@ var route:Route
var first:Player
var last:Player
const remove_last = 1
const REMOVE_LAST = 1
func _ready():
route = get_node("route")
@ -18,6 +19,7 @@ func _physics_process(delta):
#destroy_after_last()
check_autotrack()
func set_player_order():
players = get_node("players").get_children()
players.sort_custom(PlayerSorter,"sort")
@ -26,6 +28,7 @@ func set_player_order():
if players.size() > 0 && players[players.size()-1] != last:
last = players[players.size()-1]
func new_first(player):
if first != null:
first.rpc("set_first",false)
@ -34,20 +37,23 @@ func new_first(player):
var p_id = first.get_network_master()
route.rpc("set_network_master",p_id)
func destroy_after_last():
if last != null:
if last.position.x != -1:
var max_index = last.position.x - remove_last
var max_index = last.position.x - REMOVE_LAST
if max_index > 0:
for i in range(max_index):
route.rpc("remove_road", i)
func check_autotrack():
if first != null:
if first.position.x != -1 && route.get_last_road() != null:
if first.position.x == route.get_last_road().get_index():
route.rpc("add_road", roads_factory.STRAIGHT, -1)
class PlayerSorter:
static func sort(a, b):
return a.position.x > b.position.x || a.position.x == b.position.x && a.position.y > b.position.y

22
scripts/menu/direct_host.gd

@ -1,22 +0,0 @@
extends Control
var lobby_menu_scene = preload("res://scenes/menu/lobby.tscn")
func _on_host_pressed():
var port = get_node("menu/port").text
var err = game.host_game(int(port))
if err == OK:
var lobby_menu = lobby_menu_scene.instance()
get_tree().get_root().add_child(lobby_menu)
game.set_player(get_tree().get_network_unique_id())
queue_free()
else:
_on_back_pressed()
get_tree().get_root().get_node("server").show_error_dialog("Cannot create Server!")
func _on_back_pressed():
queue_free()
get_tree().get_root().get_node("server").show()

34
scripts/menu/direct_join.gd

@ -1,34 +0,0 @@
extends Control
var lobby_menu_scene = preload("res://scenes/menu/lobby.tscn")
func _ready():
game.connect("connection_succeeded", self, "_connection_succeeded")
game.connect("connection_failed", self, "_connection_failed")
func _on_join_pressed():
var ip = get_node("menu/ip").text
if not ip.is_valid_ip_address():
show_error_dialog("Invalid IPv4 address!")
return
var port = get_node("menu/port").text
game.join_game(ip, int(port))
func _connection_succeeded():
var lobby_menu = lobby_menu_scene.instance()
get_tree().get_root().add_child(lobby_menu)
queue_free()
func _connection_failed():
show_error_dialog("Connection failed!")
func _on_back_pressed():
queue_free()
get_tree().get_root().get_node("server").show()
func show_error_dialog(text:String):
var dialog = get_node("error_dialog")
dialog.set_text(text)
dialog.popup_centered()

59
scripts/menu/main.gd

@ -1,59 +0,0 @@
extends Control
var server_menu_scene = preload("res://scenes/menu/server.tscn")
var local_menu_scene = preload("res://scenes/menu/local_game.tscn")
var lobby_menu_scene = preload("res://scenes/menu/lobby.tscn")
var settings_menu_scene = preload("res://scenes/menu/settings.tscn")
func _ready():
game.connect("server_disconnected", self, "_server_disconnected")
func _on_online_pressed():
var server_menu = server_menu_scene.instance()
get_tree().get_root().add_child(server_menu)
hide()
func _on_practice_pressed():
var local_menu = local_menu_scene.instance()
get_tree().get_root().add_child(local_menu)
hide()
func _on_settings_pressed():
var settings_menu = settings_menu_scene.instance()
get_tree().get_root().add_child(settings_menu)
hide()
func _on_quit_pressed():
get_tree().quit()
func _on_quick_host_pressed():
var err = game.host_game(8128)
if err != OK:
show_error_dialog("Cannot create Server!")
return
var lobby_menu = lobby_menu_scene.instance()
get_tree().get_root().add_child(lobby_menu)
game.set_player(get_tree().get_network_unique_id())
hide()
func _on_quick_join_pressed():
game.connect("connection_succeeded", self, "_quick_connection_succeeded")
game.connect("connection_failed", self, "_quick_connection_failed")
game.join_game("127.0.0.1", 8128)
func _quick_connection_succeeded():
var lobby_menu = lobby_menu_scene.instance()
get_tree().get_root().add_child(lobby_menu)
hide()
func _quick_connection_failed():
show_error_dialog("Connection failed!")
func _server_disconnected():
show_error_dialog("Server disconnected!")
func show_error_dialog(text:String):
var dialog = get_node("error_dialog")
dialog.set_text(text)
dialog.popup_centered()

15
scripts/menu/player_settings.gd

@ -1,15 +0,0 @@
extends Control
func _ready():
var values = local_storage.read_values()
if values.has('player_name'):
get_name_node().set_text(values['player_name'])
if values.has('player_color'):
get_color_node().set_pick_color(Color(values['player_color']))
func get_name_node():
return get_node("name")
func get_color_node():
return get_node("color")

32
scripts/menu/server.gd

@ -1,32 +0,0 @@
extends Control
var direct_host_menu_scene = preload("res://scenes/menu/direct_host.tscn")
var direct_join_menu_scene = preload("res://scenes/menu/direct_join.tscn")
func _ready():
get_node("menu/back").connect("pressed",self,"_on_back_pressed")
game.connect("server_disconnected", self, "_server_disconnected")
func _on_back_pressed():
queue_free()
get_tree().get_root().get_node("main_menu").show()
func _on_direct_host_pressed():
var direct_host_menu = direct_host_menu_scene.instance()
get_tree().get_root().add_child(direct_host_menu)
get_tree().get_root().get_node("main_menu").hide()
hide()
func _on_direct_join_pressed():
var direct_join_menu = direct_join_menu_scene.instance()
get_tree().get_root().add_child(direct_join_menu)
get_tree().get_root().get_node("main_menu").hide()
hide()
func _server_disconnected():
show_error_dialog("Server disconnected!")
func show_error_dialog(text:String):
var dialog = get_node("error_dialog")
dialog.set_text(text)
dialog.popup_centered()

22
scripts/menu/settings.gd

@ -1,22 +0,0 @@
extends Control
onready var player_settings = get_node("menu/tabs/Game/player_settings")
func _ready():
get_node("menu/back").connect("pressed",self,"_on_back_pressed")
get_node("menu/tabs/Game/bots").set_pressed(local_storage.read_value("bots", true))
func _on_back_pressed():
queue_free()
get_tree().get_root().get_node("main_menu").show()
func _on_save_pressed():
var values = {}
values['player_name'] = player_settings.get_name_node().text
values['player_color'] = player_settings.get_color_node().color.to_html()
values['bots'] = get_node("menu/tabs/Game/bots").is_pressed()
local_storage.write_values(values)
_on_back_pressed()

33
scripts/menus/direct_host.gd

@ -0,0 +1,33 @@
extends Control
var LobbyMenu = preload("res://scenes/menus/LobbyMenu.tscn")
func _ready():
find_node("bots").set_pressed(local_storage.read_value("bots", true))
func _draw():
find_node("host").grab_focus()
func _on_host_pressed():
var port = find_node("port").text
var bots = find_node("bots").is_pressed()
var err = server.host_game(int(port), bots)
if err == OK:
var lobby_menu = LobbyMenu.instance()
get_tree().get_root().add_child(lobby_menu)
game.set_player(get_tree().get_network_unique_id())
queue_free()
else:
_on_back_pressed()
get_tree().get_root().get_node("multiplayer_menu").show_error_dialog(tr("ERROR_SERVER_CREATION"))
func _on_back_pressed():
queue_free()
get_tree().get_root().get_node("multiplayer_menu").show()

27
scripts/menus/direct_join.gd

@ -0,0 +1,27 @@
extends Control
func _draw():
find_node("join").grab_focus()
func _on_join_pressed():
var ip = find_node("ip").text
if not ip.is_valid_ip_address():
show_error_dialog(tr("INVALIP_IP4"))
return
var port = find_node("port").text
client.join_game(ip, int(port))
queue_free()
func _on_back_pressed():
queue_free()
func show_error_dialog(text:String):
var dialog = get_node("error_dialog")
dialog.set_text(text)
dialog.popup_centered()

8
scripts/menu/ingame.gd → scripts/menus/ingame.gd

@ -1,5 +1,10 @@
extends Control
func _draw():
find_node("resume").grab_focus()
func _physics_process(delta):
if Input.is_action_just_pressed("ui_cancel"):
if is_visible_in_tree():
@ -7,11 +12,14 @@ func _physics_process(delta):
else:
show()
func _on_resume_pressed():
hide()
func _on_settings_pressed():
pass
func _on_end_pressed():
game.quit_game()

38
scripts/menu/lobby.gd → scripts/menus/lobby.gd

@ -1,27 +1,43 @@
extends Control
onready var countdown_timer = get_node("countdown_timer")
onready var player_settings = get_node("menu/player_settings")
onready var player_list = get_node("menu/players")
onready var player_settings = find_node("player_settings")
onready var player_list = find_node("players")
func _ready():
if get_tree().get_root().has_node("multiplayer_menu"):
get_tree().get_root().get_node("multiplayer_menu").hide()
if get_tree().get_root().has_node("main_menu"):
get_tree().get_root().get_node("main_menu").hide()
get_node("menu/back").connect("pressed",self,"_on_back_pressed")
game.connect("players_changed", self, "_players_changed")
game.connect("game_ready", self, "_game_ready")
game.connect("game_started", self, "_game_started")
game.connect("server_disconnected", self, "_server_disconnected")
client.connect("server_disconnected", self, "_server_disconnected")
player_settings.get_name_node().connect("text_changed",self,"_on_name_text_changed")
player_settings.get_color_node().connect("color_changed",self,"_on_color_color_changed")
player_settings.get_color_node().connect("draw",self,"_on_player_changed")
countdown_timer.set_wait_time(game.LOBBY_READY_WAIT_TIME)
countdown_timer.set_wait_time(server.LOBBY_READY_WAIT_TIME)
if game.game_name:
find_node("server_name").set_text(game.game_name)
find_node("server_name").set_tooltip(game.game_name)
func _draw():
find_node("ready").grab_focus()
func _physics_process(delta):
if not countdown_timer.is_stopped():
get_node("countdown").text = str(int(countdown_timer.get_time_left()) + 1)
func _players_changed(players):
player_list.clear()
for p_id in players:
@ -35,6 +51,8 @@ func _players_changed(players):
player_list.set_item_icon(player_list.get_item_count()-1, player_list.get_node("ready_icon").get_button_icon())
else:
player_list.set_item_icon(player_list.get_item_count()-1, player_list.get_node("not_ready_icon").get_button_icon())
find_node("server_bots").set_pressed(game.bots)
func _game_ready(all_ready):
if all_ready:
@ -47,31 +65,37 @@ func _game_ready(all_ready):
func _game_started():
queue_free()
func _on_name_text_changed(new_text):
_on_player_changed()
func _on_color_color_changed(color):
_on_player_changed()
func _on_ready_toggled(button_pressed):
_on_player_changed()
player_settings.get_name_node().set_editable(not button_pressed)
player_settings.get_color_node().set_disabled(button_pressed)
func _on_player_changed():
var name = player_settings.get_name_node().text
var color = player_settings.get_color_node().color
var ready = get_node("menu/ready").pressed
var ready = find_node("ready").pressed
game.update_player(name,color,ready)
func _on_back_pressed():
game.quit_game()
if get_tree().get_root().has_node("server"):
get_tree().get_root().get_node("server").show()
if get_tree().get_root().has_node("multiplayer_menu"):
get_tree().get_root().get_node("multiplayer_menu").show()
get_tree().get_root().get_node("main_menu").hide()
elif get_tree().get_root().has_node("main_menu"):
get_tree().get_root().get_node("main_menu").show()
queue_free()
func _server_disconnected():
_on_back_pressed()

15
scripts/menu/local_game.gd → scripts/menus/local_game.gd

@ -1,16 +1,23 @@
extends Control
onready var player_settings = get_node("menu/player_settings")
onready var player_settings = find_node("player_settings")
func _ready():
get_node("menu/bots").set_pressed(local_storage.read_value("bots", true))
find_node("bots").set_pressed(local_storage.read_value("bots", true))
func _draw():
find_node("start").grab_focus()
func _on_start_pressed():
var name = player_settings.get_name_node().text
var color = player_settings.get_color_node().color
var bots = get_node("menu/bots").is_pressed()
var bots = find_node("bots").is_pressed()
queue_free()
game.local_game(name,color,bots)
server.local_game(name,color,bots)
func _on_back_pressed():
queue_free()

43
scripts/menus/main.gd

@ -0,0 +1,43 @@
extends Control
var MultiplayerMenu = preload("res://scenes/menus/MultiplayerMenu.tscn")
var LocalGameMenu = preload("res://scenes/menus/LocalGameMenu.tscn")
var SettingsMenu = preload("res://scenes/menus/SettingsMenu.tscn")
func _ready():
game.connect("server_disconnected", self, "_server_disconnected")
func _draw():
find_node("multiplayer").grab_focus()
func _on_multiplayer_pressed():
var multiplayer_menu = MultiplayerMenu.instance()
get_tree().get_root().add_child(multiplayer_menu)
hide()
func _on_practice_pressed():
var local_game_menu = LocalGameMenu.instance()
get_tree().get_root().add_child(local_game_menu)
hide()
func _on_settings_pressed():
var settings_menu = SettingsMenu.instance()
get_tree().get_root().add_child(settings_menu)
hide()
func _on_quit_pressed():
get_tree().quit()
func _server_disconnected():
show_error_dialog(tr("SERVER_DISCONNECTED"))
func show_error_dialog(text:String):
var dialog = get_node("error_dialog")
dialog.set_text(text)
dialog.popup_centered()

141
scripts/menus/server.gd

@ -0,0 +1,141 @@
extends Control
var ServerCreateGameMenu = preload("res://scenes/menus/ServerCreateGameMenu.tscn")
var LobbyMenu = preload("res://scenes/menus/LobbyMenu.tscn")
var DirectHostMenu = preload("res://scenes/menus/DirectHostMenu.tscn")
var DirectJoinMenu = preload("res://scenes/menus/DirectJoinMenu.tscn")
onready var games_list = get_node("menu/games")
var games = []
var selected_game = {}
func _ready():
get_node("menu/back").connect("pressed",self,"_on_back_pressed")
client.connect("connection_succeeded", self, "_connection_succeeded")
client.connect("connection_failed", self, "_connection_failed")
client.connect("server_disconnected", self, "_server_disconnected")
func _draw():
find_node("refresh").grab_focus()
func _on_multiplayer_menu_draw():
get_games(find_node("open").is_pressed())
get_node("refresh_timer").start()
func _on_multiplayer_menu_hide():
get_node("refresh_timer").stop()
func _on_back_pressed():
queue_free()
get_tree().get_root().get_node("main_menu").show()
func _on_direct_host_pressed():
var direct_host_menu = DirectHostMenu.instance()
get_tree().get_root().add_child(direct_host_menu)
get_tree().get_root().get_node("main_menu").hide()
func _on_direct_join_pressed():
var direct_join_menu = DirectJoinMenu.instance()
get_tree().get_root().add_child(direct_join_menu)
get_tree().get_root().get_node("main_menu").hide()
func _on_open_toggled(button_pressed):
get_games(button_pressed)
func _on_refresh_pressed():
if get_node("refresh_timer").is_stopped():
get_node("refresh_timer").start()
get_games(find_node("open").is_pressed())
func _on_refresh_timer_timeout():
get_games(find_node("open").is_pressed())
func _server_disconnected():
show_error_dialog(tr("SERVER_DISCONNECTED"))
func show_error_dialog(text:String):
var dialog = get_node("error_dialog")
dialog.set_text(text)
dialog.popup_centered()
func get_games(only_open:bool):
var req = game_server.http()
req.connect_http(self,"_on_get_games")
if only_open:
req.get_request('client/games?open')
else:
req.get_request('client/games')
func _on_get_games(result, response_code, headers, body):
if result == OK && response_code == HTTPClient.RESPONSE_OK:
find_node("create").set_disabled(false)
find_node("open").set_disabled(false)
var json = JSON.parse(body.get_string_from_utf8())
games_list.clear()
games = json.result
for game in games:
var name = game.name
name += " ("
name += str(game.player_count)
name += "/4)"
if game.bots:
name += " [with Bots]"
games_list.add_item(name)
if game.running:
games_list.set_item_icon(games_list.get_item_count()-1, games_list.get_node("running_icon").get_button_icon())
elif game.has('private') && game.private:
games_list.set_item_icon(games_list.get_item_count()-1, games_list.get_node("private_icon").get_button_icon())
else:
games_list.set_item_icon(games_list.get_item_count()-1, games_list.get_node("open_icon").get_button_icon())
else:
find_node("create").set_disabled(true)
find_node("join").set_disabled(true)
find_node("open").set_disabled(true)
show_error_dialog(tr("SERVER_NO_CONNECTION"))
get_node("refresh_timer").stop()
func _on_create_pressed():
var server_create_game_menu = ServerCreateGameMenu.instance()
get_tree().get_root().add_child(server_create_game_menu)
get_tree().get_root().get_node("main_menu").hide()
func _on_join_pressed():
client.join_game(game_server.SERVER_ADDR, int(selected_game['port']))
func _connection_succeeded():
var lobby_menu = LobbyMenu.instance()
if selected_game && selected_game.has('name'):
game.game_name = selected_game.name
get_tree().get_root().add_child(lobby_menu)
get_node("refresh_timer").stop()
hide()
func _connection_failed():
show_error_dialog(tr("CONNECTION_FAILED"))
func _on_games_item_selected(index):
selected_game = games[index]
find_node("join").set_disabled(false)
func _on_games_nothing_selected():
find_node("join").set_disabled(true)

44
scripts/menus/server_create.gd

@ -0,0 +1,44 @@
extends Control
func _ready():
var player_name = local_storage.read_value("player_name", false)
var game_title = "New Game"
if player_name:
game_title += " by " + player_name
find_node("name").set_text(game_title)
find_node("bots").set_pressed(local_storage.read_value("bots", true))
func _draw():
find_node("create").grab_focus()
func _on_create_pressed():
var req = game_server.http()
req.connect_http(self,"_on_game_created")
var server_name = find_node("name").text
var bots = 0
if find_node("bots").is_pressed():
bots = 1
req.post_request('client/game/create', to_json({'name' : server_name, 'bots' : bots}))
func _on_game_created(result, response_code, headers, body):
if result == OK && response_code == HTTPClient.RESPONSE_OK:
var json = JSON.parse(body.get_string_from_utf8())
game.game_name = json.result['name']
client.join_game(game_server.SERVER_ADDR, int(json.result['port']))
queue_free()
func _on_name_text_changed(new_text):
if new_text:
find_node("create").set_disabled(false)
else:
find_node("create").set_disabled(true)
func _on_back_pressed():
queue_free()
get_tree().get_root().get_node("multiplayer_menu").show()

67
scripts/menus/settings.gd

@ -0,0 +1,67 @@
extends Control
onready var player_settings = find_node("settings_player")
onready var game_tab = find_node("game")
onready var controls_tab = find_node("controls")
onready var graphics_tab = find_node("graphics")
onready var system_tab = find_node("system")
var locale
func _ready():
get_node("menu/back").connect("pressed",self,"_on_back_pressed")
find_node("bots").set_pressed(local_storage.read_value("bots", true))
game_tab.set_name(tr("GAME"))
controls_tab.set_name(tr("CONTROLS"))
graphics_tab.set_name(tr("GRAPHICS"))
system_tab.set_name(tr("SYSTEM"))
func _on_back_pressed():
queue_free()
get_tree().get_root().get_node("main_menu").show()
func _on_locales_item_selected(index):
match index:
0:
locale = "en"
1:
locale = "de"
_:
locale = "en"
TranslationServer.set_locale(locale)
game_tab.set_name(tr("GAME"))
controls_tab.set_name(tr("CONTROLS"))
graphics_tab.set_name(tr("GRAPHICS"))
system_tab.set_name(tr("SYSTEM"))
func _init_locales():
var locales = find_node("locales")
locales.clear()
locales.add_item(tr("LOCALE_EN"))
locales.add_item(tr("LOCALE_DE"))
locale = local_storage.read_value("locale","en")
match locale:
"en":
locales.select(0)
_on_locales_item_selected(0)
"de":
locales.select(1)
_on_locales_item_selected(1)
func _on_locales_tree_exiting():
TranslationServer.set_locale(local_storage.read_value("locale","en"))
func _on_save_pressed():
var values = {}
values['player_name'] = player_settings.get_name_node().text
values['player_color'] = player_settings.get_color_node().color.to_html()
values['bots'] = find_node("bots").is_pressed()
values['locale'] = locale
local_storage.write_values(values)
_on_back_pressed()

89
scripts/menus/settings_controls.gd

@ -0,0 +1,89 @@
tool
extends Control
onready var grid = find_node("grid")
onready var key_dialog = get_node("key_dialog")
const INPUT_TYPE_KEY = 0
const INPUT_TYPE_JOYPAD = 1
var last_action:String
var last_event:InputEvent
var new_inputs = {}
func _ready():
init_mapping()
func init_mapping():
new_inputs = {}
for action in InputMap.get_actions():
if action.begins_with("controls_"):
var action_label = Label.new()
action_label.set_name(action + "_label")
action_label.set_text(action)
grid.add_child(action_label)
var key_action_button = Button.new()
key_action_button.set_h_size_flags(SIZE_SHRINK_CENTER)
key_action_button.set_flat(true)
key_action_button.set_meta("action",action)
key_action_button.set_button_icon(get_node("icons/key").get_button_icon())
var joypad_action_button = Button.new()
joypad_action_button.set_h_size_flags(SIZE_SHRINK_CENTER)
joypad_action_button.set_flat(true)
joypad_action_button.set_meta("action",action)
for mapping in InputMap.get_action_list(action):
if mapping is InputEventKey:
key_action_button.set_text(mapping.as_text())
key_action_button.set_tooltip(mapping.as_text())
elif mapping is InputEventJoypadButton:
joypad_action_button.set_tooltip(str(mapping.button_index))
if has_node("icons/joypad/" + str(mapping.button_index)):
joypad_action_button.set_button_icon(get_node("icons/joypad/" + str(mapping.button_index)).get_button_icon())
else:
joypad_action_button.set_button_icon(get_node("icons/joypad/other").get_button_icon())
joypad_action_button.set_text(str(mapping.button_index))
grid.add_child(key_action_button)
key_action_button.connect("pressed",self,"_on_button_pressed",[action, INPUT_TYPE_KEY])
grid.add_child(joypad_action_button)
joypad_action_button.connect("pressed",self,"_on_button_pressed",[action, INPUT_TYPE_JOYPAD])
func _unhandled_input(event):
if key_dialog.is_visible_in_tree():
if key_dialog.get_meta("type") == INPUT_TYPE_KEY && event is InputEventKey:
last_event = event
key_dialog.set_text(tr(last_event.as_text()))
key_dialog.get_ok().set_disabled(false)
elif key_dialog.get_meta("type") == INPUT_TYPE_JOYPAD && event is InputEventJoypadButton:
last_event = event
key_dialog.set_text(last_event.as_text())
key_dialog.get_ok().set_disabled(false)
func _on_button_pressed(action, type):
last_action = action
last_event = null
key_dialog.set_text(tr("PRESS_KEY"))
key_dialog.set_meta("type", type)
key_dialog.connect("confirmed",self,"_on_dialog_confirmed")
key_dialog.get_ok().set_disabled(true)
key_dialog.popup_centered()
func _on_dialog_confirmed(type):
if not new_inputs.has(last_action):
new_inputs[last_action] = {}
match key_dialog.get_meta("type"):
INPUT_TYPE_KEY:
if last_event is InputEventKey:
new_inputs[last_action]["key"] = OS.get_scancode_string(last_event.scancode)
INPUT_TYPE_JOYPAD:
if last_event is InputEventJoypadButton:
new_inputs[last_action]["joypad"] = last_event.button_index

14
scripts/menus/settings_player.gd

@ -0,0 +1,14 @@
extends Control
func _ready():
get_name_node().set_text(local_storage.read_value("player_name", "Player"))
get_color_node().set_pick_color(Color(local_storage.read_value("player_color", "#000000")))
func get_name_node():
return find_node("name")
func get_color_node():
return find_node("color")

44
scripts/networking/client.gd

@ -0,0 +1,44 @@
extends Node
signal connection_failed()
signal connection_succeeded()
signal server_disconnected()
func join_game(ip, port:int):
get_tree().connect("connected_to_server", self, "_connected_ok")
get_tree().connect("connection_failed", self, "_connected_fail")
get_tree().connect("server_disconnected", self, "_server_disconnected")
game.connect("game_ended",self,"_game_ended")
var host = NetworkedMultiplayerENet.new()
host.create_client(ip, port)
get_tree().set_network_peer(host)
func _connected_ok():
game.rpc("set_player", get_tree().get_network_unique_id())
emit_signal("connection_succeeded")
func _connected_fail():
get_tree().disconnect("connected_to_server", self, "_connected_ok")
get_tree().disconnect("connection_failed", self, "_connected_fail")
get_tree().disconnect("server_disconnected", self, "_server_disconnected")
get_tree().set_network_peer(null)
emit_signal("connection_failed")
func _server_disconnected():
game.quit_game()
emit_signal("server_disconnected")
func _game_ended():
get_tree().disconnect("connected_to_server", self, "_connected_ok")
get_tree().disconnect("connection_failed", self, "_connected_fail")
get_tree().disconnect("server_disconnected", self, "_server_disconnected")
game.disconnect("game_ended",self,"_game_ended")
get_tree().set_refuse_new_network_connections(false)
get_tree().set_network_peer(null)

14
scripts/networking/game_server.gd

@ -0,0 +1,14 @@
extends Spatial
class_name GameServer
const SERVER_ADDR = "127.0.0.1"
const API_ADDR = "http://" + SERVER_ADDR + ":5000/"
const HEADERS = ["Content-Type: application/json"]
const SSL = false
func http():
var game_server_requests = GameServerRequests.new()
add_child(game_server_requests)
return game_server_requests

35
scripts/networking/game_server_requests.gd

@ -0,0 +1,35 @@
extends Spatial
class_name GameServerRequests
var http:HTTPRequest
func _ready():
http = HTTPRequest.new()
add_child(http)
http.connect("request_completed",self, "_self_destroy")
func connect_http(node,function):
http.connect("request_completed",node,function)
func get_request(path:String):
http.request(game_server.API_ADDR + path, game_server.HEADERS, game_server.SSL, HTTPClient.METHOD_GET)
func post_request(path:String, data:String = ""):
http.request(game_server.API_ADDR + path, game_server.HEADERS, game_server.SSL, HTTPClient.METHOD_POST, data)
func put_request(path:String, data:String = ""):
http.request(game_server.API_ADDR + path, game_server.HEADERS, game_server.SSL, HTTPClient.METHOD_PUT, data)
func delete_request(path:String, data:String = ""):
http.request(game_server.API_ADDR + path, game_server.HEADERS, game_server.SSL, HTTPClient.METHOD_DELETE, data)
func _self_destroy(result, response_code, headers, body):
queue_free()

156
scripts/networking/server.gd

@ -0,0 +1,156 @@
extends Node
const MAX_PEERS = 4
const LOBBY_READY_WAIT_TIME = 3
const EMPTY_WAIT_TIME = 30
var port:int = -1
var dedicated_server:bool = false
var server_secret:String = ""
var server_id:String = "[GAME:-1] "
var timer:Timer
signal server_error(type, data)
func _ready():
for argument in OS.get_cmdline_args():
if argument.split("=")[0] == "--port":
dedicated_server = true
port = int(argument.split("=")[1])
if argument.split("=")[0] == "--server-id":
server_id = "[GAME:" + str(argument.split("=")[1]) + "] "
if argument.split("=")[0] == "--secret":
server_secret=argument.split("=")[1]
if argument.split("=")[0] == "--bots":
game.set_bots(bool(int(argument.split("=")[1])))
if dedicated_server:
var err = host_game(port)
if err == OK:
print(server_id + "New game hosted: port=" + str(port) + " secret=" + str(server_secret) + " bots=" + str(game.bots))
else:
print(server_id + "Could not create Server! (port=" + str(port) + " secret=" + str(server_secret) + ")")
quit_server()
func host_game(port:int, set_bots:bool = false):
var host = NetworkedMultiplayerENet.new()
var err = host.create_server(port, MAX_PEERS)
get_tree().set_network_peer(host)
get_tree().connect("network_peer_connected", self, "_client_connected")
get_tree().connect("network_peer_disconnected", self,"_client_disconnected")
game.connect("players_changed",self,"_players_changed")
game.connect("game_ready",self,"_game_ready")
game.connect("game_ended",self,"_game_ended")
if set_bots:
game.bots = true
if timer == null:
timer = Timer.new()
timer.set_name("timer")
timer.set_timer_process_mode(Timer.TIMER_PROCESS_PHYSICS)
timer.set_one_shot(true)
timer.set_autostart(false)
add_child(timer)
if err != OK:
emit_signal("server_error", "HOST", err)
return err
func local_game(name:String, color:Color, bots:bool):
var localhost = NetworkedMultiplayerENet.new()
localhost.create_server(0, 0)
get_tree().set_network_peer(localhost)
game.bots = bots
game.set_player(get_tree().get_network_unique_id(), name, color)
game.prepare_game()
game.post_start_game()
func update_server_data():
var req = game_server.http()
req.put_request("game",to_json({'secret' : server_secret, 'player_count' : game.players.size(), 'running' : game.game_running}))
func _client_connected(id):
if get_tree().is_network_server():
if dedicated_server:
print(server_id + "peer connected: " + str(id))
game.rpc_id(id, "set_bots" ,game.bots)
if not timer.is_stopped():
timer.disconnect("timeout",self,"quit_server")
timer.stop()
func _client_disconnected(id):
if get_tree().is_network_server():
if dedicated_server:
print(server_id + "peer disconnected: " + str(id))
if game.game_running:
emit_signal("server_error", "DISCONNECTED", [id])
game.rpc("remove_player" ,id)
else:
game.rpc("remove_player" ,id)
func _players_changed(players):
if get_tree().is_network_server():
if dedicated_server:
update_server_data()
if players.empty():
if game.game_running:
print(server_id + "All players disconnected, close server.")
quit_server()
else:
print(server_id + "All players disconnected, wait for closing...")
timer.set_wait_time(EMPTY_WAIT_TIME)
timer.connect("timeout",self,"quit_server",[true])
timer.start()
func quit_server(triggered:bool = false):
if dedicated_server && triggered:
print(server_id + "Closing time over...quit")
var req = game_server.http()
req.connect_http(self,"_on_delete_server")
req.delete_request("game",to_json({'secret' : server_secret}))
func _on_delete_server(result, response_code, headers, body):
if result != OK || response_code != HTTPClient.RESPONSE_OK:
print(server_id + "ERROR: _on_delete_server, server is in undefined state!")
func _start_game():
if get_tree().is_network_server():
get_tree().set_refuse_new_network_connections(true)
game.rpc("prepare_game")
func _game_ready(all_ready):
if get_tree().is_network_server():
if all_ready:
timer.set_wait_time(LOBBY_READY_WAIT_TIME)
timer.connect("timeout",self,"_start_game")
timer.start()
else:
timer.disconnect("timeout",self,"_start_game")
timer.stop()
func _game_ended():
get_tree().disconnect("network_peer_connected", self, "_client_connected")
get_tree().disconnect("network_peer_disconnected", self,"_client_disconnected")
game.disconnect("players_changed",self,"_players_changed")
game.disconnect("game_ready",self,"_game_ready")
game.disconnect("game_ended",self,"_game_ended")
get_tree().set_refuse_new_network_connections(false)
get_tree().set_network_peer(null)

37
scripts/player/HumanControls.gd

@ -1,37 +0,0 @@
extends Spatial
var player:Player
var camera:InterpolatedCamera
func _physics_process(delta):
if is_network_master() && player != null:
if player.is_out:
camera.set_speed(0.1)
if player.timer.get_time_left() > 0:
get_node("hud/reset").set_text(str(int(player.timer.get_time_left()) + 1))
else:
get_node("hud/reset").set_text("reset")
if Input.is_action_pressed("ui_down"):
camera.set_speed(10)
player.reset()
get_node("hud/reset").set_text("")
else:
if Input.is_action_pressed("ui_up") && player.current_speed <= player.MAX_SPEED:
player.current_speed += player.speed_factor
elif Input.is_action_pressed("ui_down") && player.current_speed <= player.MAX_SPEED:
player.current_speed -= player.speed_factor
elif player.current_speed > 0:
player.current_speed -= player.speed_factor * player.brake_factor
elif player.current_speed < 0:
player.current_speed = 0
get_node("hud/speed").set_text(str(player.current_speed))
func set_player(path:String):
player = get_node(path)
get_node("inventory").set_player(player)
camera = InterpolatedCamera.new()
camera.set_target_path(path + "/Path/PathFollow/raceCar/CameraTarget")
camera.set_interpolation_enabled(true)
camera.set_speed(10)
add_child(camera)

3
scripts/player/BaseInventory.gd → scripts/player/base_inventory.gd

@ -51,12 +51,15 @@ var index:int = 0
signal item_changed(index)
func _ready():
route = get_node("/root/world/route")
func set_player(new_player:Player):
player = new_player
func set_item():
if is_network_master():
if item:

10
scripts/player/BasePlayer.gd → scripts/player/base_player.gd

@ -2,39 +2,43 @@ extends Node
class_name BasePlayer
# player vars
export var player_color:Color
var player_name:String
# positions
var is_out:bool = false
var position:Vector2
var road_index:int = -1
# puppets
puppet var slave_position:Vector2
func get_race_car():
pass
func get_player_name():
return player_name
func set_player_name(new_name):
player_name = new_name
func get_player_color():
return player_color
func set_player_color(new_color):
player_color = new_color
var material = SpatialMaterial.new()
material.set_albedo(player_color)
get_race_car().get_node("body").set_surface_material(1,material)
func set_start(position:int):
pass
remotesync func set_first(is_first:bool):
if is_first:
add_to_group("first")

9
scripts/player/BotControls.gd → scripts/player/bot_controls.gd

@ -5,9 +5,11 @@ var player:Player
var overspeed_rate:float = 0.8
var underspeed_rate:float = 0.8
func _ready():
randomize()
func _physics_process(delta):
if is_network_master() && player != null:
if player.is_out:
@ -27,21 +29,24 @@ func _physics_process(delta):
if constrain.z > 0 && speed < constrain.z && rate > underspeed_rate:
player.current_speed += player.speed_factor
elif player.current_speed > 0 && rate > overspeed_rate:
player.current_speed -= player.speed_factor * player.brake_factor
player.current_speed -= player.speed_factor * player.friction_brake_factor
if not has_constrain:
if player.current_speed <= player.MAX_SPEED && rate > underspeed_rate:
player.current_speed += player.speed_factor
elif player.current_speed > 0 && rate > overspeed_rate:
player.current_speed -= player.speed_factor * player.brake_factor
player.current_speed -= player.speed_factor * player.friction_brake_factor
if player.current_speed < 0:
player.current_speed = 0
func set_player(path:String):
player = get_node(path)
get_node("inventory").set_player(player)
func set_overspeed_rate(new_overspeed_rate:float):
overspeed_rate = new_overspeed_rate
func set_underspeed_rate(new_underspeed_rate:float):
underspeed_rate = new_underspeed_rate

5
scripts/player/BotInventory.gd → scripts/player/bot_inventory.gd

@ -2,18 +2,21 @@ extends BaseInventory
var rand:RandomNumberGenerator = RandomNumberGenerator.new()
func _ready():
rand.randomize()
func _on_raceCar_road_entered(road):
if is_network_master():
if player != null:
if player.is_in_group("first"):
if route.get_last_road().get_index() <= (road.get_index() +2):
type = rand.randi_range(0,roads.size() -1)
type = rand.randi_range(0,roads.size() -2) # TODO: remove special, loop need fixes!
index = rand.randi_range(0, roads[type].size() -1)
route.rpc("add_road", roads[type][index], -1)
func set_player(new_player:Player):
player = new_player
player.get_race_car().connect("road_entered",self,"_on_raceCar_road_entered")

51
scripts/player/human_controls.gd

@ -0,0 +1,51 @@
extends Spatial
var player:Player
onready var camera:InterpolatedCamera = get_node("camera")
func _physics_process(delta):
if is_network_master() && player != null:
if player.is_out:
camera.set_speed(0.1)
if player.timer.get_time_left() > 0:
get_node("hud/reset").set_text(str(int(player.timer.get_time_left()) + 1))
else:
get_node("hud/reset").set_text(tr("RESET"))
if Input.is_action_pressed("controls_reset"):
if player.reset():
camera.set_speed(10)
get_node("hud/reset").set_text("")
else:
if Input.is_action_pressed("controls_thrust") && player.current_speed <= player.MAX_SPEED:
player.current_speed += player.speed_factor
elif Input.is_action_pressed("controls_break") && player.current_speed <= player.MAX_SPEED:
player.current_speed -= player.speed_factor * player.brake_factor
elif player.current_speed > 0:
player.current_speed -= player.speed_factor * player.friction_brake_factor
elif player.current_speed < 0:
player.current_speed = 0
get_node("hud/speed").set_text(str(player.current_speed))
if Input.is_action_pressed("debug_camera_1"):
set_debug_camera(0)
elif Input.is_action_pressed("debug_camera_2"):
set_debug_camera(1)
elif Input.is_action_pressed("debug_camera_3"):
set_debug_camera(2)
elif Input.is_action_pressed("debug_camera_4"):
set_debug_camera(3)
func set_player(path:String):
player = get_node(path)
get_node("inventory").set_player(player)
camera.set_target_path(player.find_node("CameraTarget").get_path())
camera.set_interpolation_enabled(true)
camera.set_speed(10)
func set_debug_camera(idx):
if idx < player.get_parent().get_child_count():
camera.set_target_path(player.get_parent().get_child(idx).find_node("CameraTarget").get_path())

15
scripts/player/HumanInventory.gd → scripts/player/human_inventory.gd

@ -3,6 +3,7 @@ extends BaseInventory
var view:Spatial
var preview:Spatial
func _ready():
view = get_node("view")
preview = get_node("preview")
@ -10,6 +11,7 @@ func _ready():
hud_track.get_texture().set_viewport_path_in_scene(str(get_path()) + "/viewport")
connect("item_changed",self,"_on_item_changed")
func _physics_process(delta):
if is_network_master():
if player != null:
@ -19,26 +21,26 @@ func _physics_process(delta):
set_item()
if preview.item:
preview.item.show()
if Input.is_action_just_pressed("ui_select"):
if Input.is_action_just_pressed("controls_add_road"):
route.rpc("add_road", roads[type][index], get_tree().get_network_unique_id())
if Input.is_action_just_pressed("ui_navigate_left"):
if Input.is_action_just_pressed("controls_prev_road_type"):
type -= 1
if type < 0:
type = roads.size() -1
index = 0
set_item()
if Input.is_action_just_pressed("ui_navigate_right"):
if Input.is_action_just_pressed("controls_next_road_type"):
type += 1
if type > roads.size() - 1:
type = 0
index = 0
set_item()
if Input.is_action_just_pressed("ui_navigate_down"):
if Input.is_action_just_pressed("controls_prev_road_variant"):
index -= 1
if index < 0:
index = roads[type].size() -1
set_item()
if Input.is_action_just_pressed("ui_navigate_up"):
if Input.is_action_just_pressed("controls_next_road_variant"):
index += 1
if index > roads[type].size() - 1:
index = 0
@ -48,6 +50,7 @@ func _physics_process(delta):
if preview.item:
preview.item.hide()
func _on_item_changed(road_identifier):
if is_network_master():
if view.get_child_count() > 0:
@ -55,4 +58,4 @@ func _on_item_changed(road_identifier):
view.add_child(item)
get_node("../hud/inventory/type").set_text(road_identifier)
get_node("../hud/inventory/type").set_text(tr(road_identifier))

3
scripts/player/InventoryPreview.gd → scripts/player/inventory_preview.gd

@ -6,11 +6,13 @@ var player:Player
var route:Route
var item:Road
func _ready():
route = get_node("/root/world/route")
route.connect("road_added",self,"_on_route_road_added")
get_parent().connect("item_changed",self,"_on_inventory_item_changed")
func _on_route_road_added(road):
if is_network_master() && item:
var transform = road.get_global_transform();
@ -20,6 +22,7 @@ func _on_route_road_added(road):
transform.basis = transform.basis.rotated(road.get_end_rotation().normalized(), road.get_end_rotation().length())
item.set_global_transform(transform)
func _on_inventory_item_changed(road_identifier):
if is_network_master():
if item:

40
scripts/player/Player.gd → scripts/player/player.gd

@ -7,9 +7,9 @@ var MAX_SPEED:float = 0.2
var current_speed:float = 0.0
export var speed_factor:float = 0.001
export var brake_factor:float = 0.8
export var brake_factor:float = 2.0
export var friction_brake_factor:float = 0.8
# nodes
var timer:Timer
var path:Path
var follow:PathFollow
@ -25,7 +25,8 @@ var last_rotation:Vector3 = Vector3(0,0,0)
var torque_penalty:Vector3
var force_penalty:Vector3
const lane_offset = [-0.085, 0.085, -0.255, 0.255 ]
const LANE_OFFSET = [-0.085, 0.085, -0.255, 0.255 ]
func _ready():
timer = get_node("ResetTimer")
@ -34,6 +35,7 @@ func _ready():
path.curve.set_bake_interval(0.05)
follow = get_node("Path/PathFollow")
func _physics_process(delta):
if is_network_master():
if not is_out:
@ -43,7 +45,6 @@ func _physics_process(delta):
if follow.get_offset() < 0:
follow.set_offset(0)
# curve
if has_next && (path.curve.get_point_count() == 0 || follow.get_unit_offset() >= 1.0):
has_next = false
if path.curve.get_point_count() > 0:
@ -74,7 +75,6 @@ func _physics_process(delta):
is_resetable = false
timer.start()
# position
check_position()
else:
var race_car = get_race_car()
@ -89,29 +89,34 @@ func _physics_process(delta):
else:
position = slave_position
func get_race_car():
return get_node("Path/PathFollow/raceCar")
func get_road():
return get_race_car().road
func _on_raceCar_road_entered(road):
buffered_curve = road.get_lane_curve(lane)
buffered_rotation = last_rotation
if path.curve.get_point_count() > 0:
buffered_translate = Util.Curve_get_last_point(path.curve)
buffered_translate = Util.curve_get_last_point(path.curve)
if road.get_end_rotation().length() != 0:
last_rotation += road.get_end_rotation()
has_next = true
master func check_position():
position = Vector2(road_index, follow.get_offset())
rset("slave_position", position)
master func reset():
if is_resetable:
has_next = false
@ -131,17 +136,8 @@ master func reset():
force_penalty = Vector3(0,0,0)
torque_penalty = Vector3(0,0,0)
var road_before = route.get_road(road.get_index() - 1)
if road_before == null:
road_before = road
last_rotation = road_before.get_rotation()
var point = Util.Curve_get_last_point(road_before.get_lane_curve(lane))
if last_rotation.length() != 0:
point = point.rotated(last_rotation.normalized(), last_rotation.length())
buffered_translate = road_before.get_translation() + point
follow.set_transform(road.get_transform())
buffered_translate = road.get_translation()
last_rotation = road.get_rotation()
race_car.road = null
race_car.collider = null
@ -153,12 +149,20 @@ master func reset():
race_car.transform = Transform()
race_car.get_node("ray").set_enabled(true)
follow.set_transform(road.get_transform())
is_out = false
is_resetable = false
return true
else:
return false
func set_start(new_lane:int):
lane = new_lane
follow.set_h_offset(lane_offset[lane])
follow.set_h_offset(LANE_OFFSET[lane])
func _on_ResetTimer_timeout():
is_resetable = true

4
scripts/player/raceCar.gd → scripts/player/race_car.gd

@ -8,15 +8,17 @@ puppet var slave_transform:Transform
signal road_entered(road)
func _ready():
road_ray = get_node("ray")
func _physics_process(delta):
if is_network_master():
if road_ray.is_colliding():
if road_ray.get_collider() != collider:
var parent = road_ray.get_collider().get_parent()
if parent is Road && road != parent && !parent.is_preview():
if parent is Road && (road == null || road.get_index() < parent.get_index()) && !parent.is_preview():
collider = road_ray.get_collider()
road = parent
emit_signal("road_entered",road)

25
scripts/road/road.gd

@ -17,6 +17,7 @@ export (PoolVector3Array) var torque_penalties = PoolVector3Array()
var creator:String = ""
var preview:bool = false
func _ready():
if not has_node("StaticBody"):
var body = StaticBody.new()
@ -27,31 +28,38 @@ func _ready():
body.add_child(shape)
add_child(body)
func get_creator():
return creator
func set_creator(new_creator):
creator = str(new_creator)
# Artist TODO:
func set_color(new_color):
pass
pass # TODO
func get_path():
return get_node("Path")
func get_curve():
return get_path().get_curve()
func get_lane_curve(lane:int):
if has_node("lanes"):
return get_node("lanes").get_child(lane).get_curve()
else:
return get_path().get_curve()
func get_end_rotation():
return end_rotation
func set_preview(prev):
preview = prev
if prev:
@ -59,12 +67,15 @@ func set_preview(prev):
else:
set_material_override(null)
func is_preview():
return preview
func get_next_lane(lane):
return lane
func penalty_index(distance:float, speed:float):
for index in range(speed_constrains.size()):
var constrain = speed_constrains[index]
@ -73,20 +84,22 @@ func penalty_index(distance:float, speed:float):
return index
return -1
func get_torque_penalty(index:int):
if index >= 0:
while torque_penalties.size() < (index + 1):
index-=1
if torque_penalties.size() < (index + 1):
return get_torque_penalty(index - 1)
if get_rotation().length() != 0:
return torque_penalties[index].rotated(get_rotation().normalized(), get_rotation().length())
else:
return torque_penalties[index]
return Vector3(0,0,0)
func get_force_penalty(index:int):
if index >= 0:
while force_penalties.size() < (index + 1):
index-=1
if force_penalties.size() < (index + 1):
return get_force_penalty(index - 1)
if get_rotation().length() != 0:
return force_penalties[index].rotated(get_rotation().normalized(), get_rotation().length())
else:

2
scripts/road/roads_factory.gd

@ -2,7 +2,6 @@ extends Node
class_name TracksFactory
const STRAIGHT = "StraightLong"
const STRAIGHT_SMALL = "Straight"
const CURVE_RIGHT = "CornerLarge"
@ -25,6 +24,7 @@ const CURVED_RIGHT = "CurvedFlipped"
const CURVED_LEFT = "Curved"
const LOOP = "Loop"
func get_road_instance(road):
var instance = load("res://scenes/road/road" + road + ".tscn").instance()
if !instance.get_script():

Loading…
Cancel
Save