224 lines
7.4 KiB
GDScript
224 lines
7.4 KiB
GDScript
extends Node
|
|
|
|
var team_CS = {
|
|
"spawnpoints": [],
|
|
"members": [],
|
|
"round_score": 0,
|
|
"game_score": 0
|
|
}
|
|
var team_OS = {
|
|
"spawnpoints": [],
|
|
"members": [],
|
|
"round_score": 0,
|
|
"game_score": 0
|
|
}
|
|
|
|
var round_number = 0
|
|
var gamemode
|
|
var map_path
|
|
var map_root_name
|
|
var server_map
|
|
|
|
func find_class_type_by_number(number):
|
|
var found_class
|
|
var classtypes = GameData.server_settings["game"]["classTypes"]
|
|
for classtype in classtypes:
|
|
if classtypes[classtype]["number"] == number:
|
|
found_class = classtypes[classtype].duplicate()
|
|
break
|
|
return found_class
|
|
|
|
func check_map_availability(path):
|
|
var maps = DirAccess.open("res://scenes/maps").get_files()
|
|
var map_name = (path.split("/")[-1]).split(".")[0]
|
|
for map in maps:
|
|
var checking_map_name = str(map.split(".")[0])
|
|
if(checking_map_name == map_name):
|
|
return true
|
|
return false
|
|
|
|
func check_gamemode_availability(gm):
|
|
var gamemodes = GameData.server_settings["game"]["gamemodes"].keys()
|
|
for g in gamemodes:
|
|
if gm == g:
|
|
return true
|
|
return false
|
|
|
|
func find_weapon_name_by_number(number):
|
|
var name = ""
|
|
for weapon in GameData.server_settings["game"]["weapons"].keys():
|
|
if (GameData.server_settings["game"]["weapons"][weapon].number == number):
|
|
name = weapon
|
|
return name
|
|
|
|
func find_weapon_by_number(number):
|
|
var found_weapon
|
|
for weapon in GameData.server_settings["game"]["weapons"].keys():
|
|
if (GameData.server_settings["game"]["weapons"][weapon]["number"] == number):
|
|
found_weapon = GameData.server_settings["game"]["weapons"][weapon].duplicate()
|
|
break
|
|
return found_weapon
|
|
|
|
func find_playermodel_by_internal_id(internal_id):
|
|
return server_map.get_node("player" + str(internal_id))
|
|
|
|
func reloading_complete(client_id, reloading_time):
|
|
await get_tree().create_timer(reloading_time).timeout
|
|
var client = Networking.clients[client_id]
|
|
if (!client["reloading"]): # if a client has interrupted the reloading
|
|
return
|
|
|
|
var weapons_list = GameData.server_settings["game"]["weapons"]
|
|
var current_client_weapon = client["current_weapon"]
|
|
var current_weapon_example = weapons_list.find_key(ServerUtils.find_weapon_by_number(current_client_weapon["number"]))
|
|
var current_weapon_settings = weapons_list[current_weapon_example]
|
|
var to_reload = current_weapon_settings["magazine"] - current_client_weapon["magazine"]
|
|
if (to_reload <= current_client_weapon["ammo"]):
|
|
current_client_weapon["magazine"] += to_reload
|
|
current_client_weapon["ammo"] -= to_reload
|
|
else:
|
|
current_client_weapon["magazine"] += current_client_weapon["ammo"]
|
|
current_client_weapon["ammo"] = 0
|
|
|
|
func choose_collision_shape(target, shape_num):
|
|
var collision_shapes:Array = []
|
|
for s in target.get_children():
|
|
if s is CollisionShape3D:
|
|
collision_shapes.push_back(s)
|
|
var shape
|
|
for i in range(0, collision_shapes.size()):
|
|
if i == shape_num:
|
|
shape = collision_shapes[i]
|
|
break
|
|
return shape
|
|
|
|
func new_round():
|
|
round_number += 1
|
|
team_OS["round_score"] = 0
|
|
team_CS["round_score"] = 0
|
|
print("CS members " + str(team_CS["members"]))
|
|
print("OS members " + str(team_OS["members"]))
|
|
for member in team_CS["members"]:
|
|
member["position"] = team_CS["spawnpoints"].pick_random().get_class_spawnpoint(abs(member["class_type"]))
|
|
ServerUtils.find_playermodel_by_internal_id(member["internal_id"]).teleport.rpc_id(Networking.clients.find_key(member), member["position"])
|
|
for member in team_OS["members"]:
|
|
member["position"] = team_OS["spawnpoints"].pick_random().get_class_spawnpoint(abs(member["class_type"]))
|
|
ServerUtils.find_playermodel_by_internal_id(member["internal_id"]).teleport.rpc_id(Networking.clients.find_key(member), member["position"])
|
|
send_scores()
|
|
|
|
func new_game(new_map_path, new_gamemode):
|
|
team_OS["game_score"] = 0
|
|
team_OS["round_score"] = 0
|
|
team_CS["game_score"] = 0
|
|
team_CS["round_score"] = 0
|
|
|
|
round_number = 0
|
|
send_scores()
|
|
new_map_path = map_path if (new_map_path == null) else new_map_path
|
|
new_gamemode = gamemode if (new_gamemode == null) else new_gamemode
|
|
await switch_map(new_map_path)
|
|
await switch_gamemode(new_gamemode)
|
|
|
|
func check_gamemode_end_conditions():
|
|
match gamemode:
|
|
"TDM":
|
|
var kills_amount_to_win = GameData.server_settings["game"]["gamemodes"]["TDM"]["kills"]
|
|
if team_OS["round_score"] >= kills_amount_to_win:
|
|
team_OS["game_score"] += 1
|
|
print("OS won")
|
|
NetUtils.send_everyone(["end_round", 1]) # 1 = os is win
|
|
new_round()
|
|
|
|
elif team_CS["round_score"] >= kills_amount_to_win:
|
|
team_CS["game_score"] += 1
|
|
NetUtils.send_everyone(["end_round", -1]) # -1 = cs is win
|
|
print("CS won")
|
|
new_round()
|
|
send_scores()
|
|
|
|
func switch_map(new_map_path):
|
|
print("Switching map to %s" % new_map_path)
|
|
if (not ServerUtils.check_map_availability(new_map_path)):
|
|
var default_map = GameData.server_settings["defaults"]["map"]
|
|
print("Error. No map found. Loading default map %s" % default_map)
|
|
new_map_path = "res://scenes/maps/%s.tscn" % default_map
|
|
if (not ServerUtils.check_map_availability(new_map_path)):
|
|
print("Error. Default map is not valid. Please, specify a valid map in a config file.")
|
|
return
|
|
map_path = new_map_path
|
|
get_tree().change_scene_to_file(map_path)
|
|
await get_tree().create_timer(0.1).timeout #I know that this isn't a good practice, but I didn't find anything better
|
|
map_root_name = (map_path.split("/")[-1]).split(".")[0]
|
|
server_map = get_tree().root.get_node(map_root_name)
|
|
|
|
var spawnpoints = server_map.find_children("spawnpoint*", "" ,true)
|
|
team_OS["spawnpoints"] = []
|
|
team_CS["spawnpoints"] = []
|
|
for spawnpoint in spawnpoints:
|
|
if spawnpoint.team == 0: # cs
|
|
team_CS["spawnpoints"].push_back(spawnpoint)
|
|
elif spawnpoint.team > 0: # os
|
|
team_OS["spawnpoints"].push_back(spawnpoint)
|
|
var spectator = preload("res://scenes/models/spectator.tscn").instantiate()
|
|
server_map.add_child(spectator)
|
|
|
|
func send_scores():
|
|
NetUtils.send_everyone(["update_round_status", {
|
|
"cs_round_score" = team_CS["round_score"],
|
|
"os_round_score" = team_OS["round_score"],
|
|
"os_game_score" = team_OS["game_score"],
|
|
"cs_game_score" = team_CS["game_score"],
|
|
"round_number" = round_number,
|
|
}])
|
|
|
|
func switch_gamemode(new_gamemode):
|
|
if not ServerUtils.check_gamemode_availability(new_gamemode):
|
|
print("No gamemode found")
|
|
return
|
|
gamemode = new_gamemode
|
|
|
|
func parse_arguments():
|
|
var arguments = {}
|
|
for argument in OS.get_cmdline_args():
|
|
if argument.find("=") > -1:
|
|
var key_value = argument.split("=")
|
|
arguments[key_value[0].lstrip("--")] = key_value[1]
|
|
else:
|
|
# Options without an argument will be present in the dictionary,
|
|
# with the value set to an empty string.
|
|
arguments[argument.lstrip("--")] = ""
|
|
return arguments
|
|
|
|
func setup_server():
|
|
var arguments = parse_arguments()
|
|
|
|
GameData.read_settings()
|
|
|
|
################ parsing map
|
|
var path = "res://scenes/maps/%s.tscn" % arguments["map"] if arguments.has("map") else "res://scenes/maps/%s.tscn" % GameData.server_settings["defaults"]["map"]
|
|
if (ServerUtils.check_map_availability(path)):
|
|
map_path = path
|
|
else:
|
|
print("Unknown map %s Available maps:" % path)
|
|
for map in DirAccess.open("res://scenes/maps").get_files():
|
|
print(str(map.split(".")[0]))
|
|
get_tree().quit()
|
|
return
|
|
################ parsing gamemode
|
|
var gm = str(arguments["gamemode"]) if (arguments.has("gamemode")) else "TDM"
|
|
if (ServerUtils.check_gamemode_availability(gm)):
|
|
print("Gamemode exists")
|
|
else:
|
|
print("No")
|
|
|
|
await new_game(map_path, gm)
|
|
|
|
var spectator = preload("res://scenes/models/spectator.tscn").instantiate()
|
|
server_map.add_child(spectator)
|
|
|
|
Networking.StartServer()
|
|
|
|
func _ready():
|
|
if "--server" in OS.get_cmdline_args():
|
|
setup_server()
|