|
|
|
|
@@ -1,21 +1,29 @@
|
|
|
|
|
extends Node
|
|
|
|
|
|
|
|
|
|
var player_script := preload("res://scripts/Player.gd")
|
|
|
|
|
var player_script := load("res://scripts/Player.gd")
|
|
|
|
|
var server_map
|
|
|
|
|
@onready var Weapons = GameData.Weapons
|
|
|
|
|
var player_model = preload("res://scenes/models/player.tscn")
|
|
|
|
|
var player_model = load("res://scenes/models/player.tscn")
|
|
|
|
|
var peer = ENetMultiplayerPeer.new()
|
|
|
|
|
var settings
|
|
|
|
|
var clients = {}
|
|
|
|
|
var clients:Dictionary = {}
|
|
|
|
|
var last_client_id = 1
|
|
|
|
|
var map_path
|
|
|
|
|
var map_root_name
|
|
|
|
|
|
|
|
|
|
var spawnpoints_os = []
|
|
|
|
|
var spawnpoints_cs = []
|
|
|
|
|
var team_CS = {
|
|
|
|
|
"spawnpoints": [],
|
|
|
|
|
"members": [],
|
|
|
|
|
"round_score": 0,
|
|
|
|
|
"game_score": 0
|
|
|
|
|
}
|
|
|
|
|
var team_OS = {
|
|
|
|
|
"spawnpoints": [],
|
|
|
|
|
"members": [],
|
|
|
|
|
"round_score": 0,
|
|
|
|
|
"game_score": 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var cs_score = 0
|
|
|
|
|
var os_score = 0
|
|
|
|
|
var round_number = 0
|
|
|
|
|
var gamemode
|
|
|
|
|
|
|
|
|
|
@@ -41,7 +49,6 @@ func check_map_availability(path):
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
|
|
func check_gamemode_availability(gamemode):
|
|
|
|
|
print(str(settings["game"]))
|
|
|
|
|
var gamemodes = settings["game"]["gamemodes"].keys()
|
|
|
|
|
for gm in gamemodes:
|
|
|
|
|
if gm == gamemode:
|
|
|
|
|
@@ -54,9 +61,8 @@ func _ready():
|
|
|
|
|
GameData.read_settings()
|
|
|
|
|
settings = GameData.server_settings
|
|
|
|
|
|
|
|
|
|
################ prepairing map
|
|
|
|
|
################ parsing map
|
|
|
|
|
var path = "res://scenes/maps/%s.tscn" % arguments["map"] if arguments.has("map") else "res://scenes/maps/%s.tscn" % settings["defaults"]["map"]
|
|
|
|
|
|
|
|
|
|
if (check_map_availability(path)):
|
|
|
|
|
map_path = path
|
|
|
|
|
else:
|
|
|
|
|
@@ -65,7 +71,7 @@ func _ready():
|
|
|
|
|
print(str(map.split(".")[0]))
|
|
|
|
|
get_tree().quit()
|
|
|
|
|
return
|
|
|
|
|
################ prepairing gamemode
|
|
|
|
|
################ parsing gamemode
|
|
|
|
|
var gm = str(arguments["gamemode"]) if (arguments.has("gamemode")) else "TDM"
|
|
|
|
|
if(check_gamemode_availability(gm)):
|
|
|
|
|
print("Gamemode exists")
|
|
|
|
|
@@ -73,7 +79,21 @@ func _ready():
|
|
|
|
|
print("No")
|
|
|
|
|
StartServer(map_path, gm)
|
|
|
|
|
#######################################SERVER####################################
|
|
|
|
|
|
|
|
|
|
func check_gamemode_end_conditions():
|
|
|
|
|
match gamemode:
|
|
|
|
|
"TDM":
|
|
|
|
|
var kills_amount_to_win = settings["game"]["gamemodes"]["TDM"]["kills"]
|
|
|
|
|
if team_OS["round_score"] >= kills_amount_to_win:
|
|
|
|
|
team_OS["game_score"] += 1
|
|
|
|
|
print("OS won")
|
|
|
|
|
send_everyone([find_playermodel_by_internal_id(clients[clients.keys().pick_random()]["internal_id"]).end_round, 1]) # 1 = os is win
|
|
|
|
|
new_round()
|
|
|
|
|
|
|
|
|
|
elif team_CS["round_score"] >= kills_amount_to_win:
|
|
|
|
|
team_CS["game_score"] += 1
|
|
|
|
|
send_everyone([find_playermodel_by_internal_id(clients[clients.keys().pick_random()]["internal_id"]).end_round, -1]) # -1 = cs is win
|
|
|
|
|
print("CS won")
|
|
|
|
|
new_round()
|
|
|
|
|
func switch_map(new_map_path):
|
|
|
|
|
print("Switching map to %s" % new_map_path)
|
|
|
|
|
if (not check_map_availability(new_map_path)):
|
|
|
|
|
@@ -88,6 +108,15 @@ func switch_map(new_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)
|
|
|
|
|
|
|
|
|
|
func switch_gamemode(new_gamemode):
|
|
|
|
|
if not check_gamemode_availability(new_gamemode):
|
|
|
|
|
@@ -96,14 +125,19 @@ func switch_gamemode(new_gamemode):
|
|
|
|
|
gamemode = new_gamemode
|
|
|
|
|
|
|
|
|
|
func new_game(new_map_path, new_gamemode):
|
|
|
|
|
cs_score = 0
|
|
|
|
|
os_score = 0
|
|
|
|
|
team_OS["game_score"] = 0
|
|
|
|
|
team_OS["round_score"] = 0
|
|
|
|
|
team_CS["game_score"] = 0
|
|
|
|
|
team_CS["round_score"] = 0
|
|
|
|
|
|
|
|
|
|
round_number = 0
|
|
|
|
|
await switch_map(new_map_path)
|
|
|
|
|
await switch_gamemode(new_gamemode)
|
|
|
|
|
|
|
|
|
|
func new_round():
|
|
|
|
|
round_number += 1
|
|
|
|
|
team_OS["round_score"] = 0
|
|
|
|
|
team_CS["round_score"] = 0
|
|
|
|
|
|
|
|
|
|
func find_playermodel_by_internal_id(internal_id):
|
|
|
|
|
return server_map.get_node("player" + str(internal_id))
|
|
|
|
|
@@ -125,13 +159,21 @@ func StartServer(map_path, gm):
|
|
|
|
|
|
|
|
|
|
var spectator = preload("res://scenes/models/spectator.tscn").instantiate()
|
|
|
|
|
server_map.add_child(spectator)
|
|
|
|
|
var spawnpoints = server_map.find_children("spawnpoint*", "" ,true)
|
|
|
|
|
for spawnpoint in spawnpoints:
|
|
|
|
|
if spawnpoint.team == 0: # cs
|
|
|
|
|
spawnpoints_cs.push_back(spawnpoint)
|
|
|
|
|
elif spawnpoint.team > 0: # os
|
|
|
|
|
spawnpoints_os.push_back(spawnpoint)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func send_everyone(args):
|
|
|
|
|
if (typeof(args[0]) == 4): #string
|
|
|
|
|
for current_client_id in clients.keys():
|
|
|
|
|
if (args.size() == 1): rpc_id(int(current_client_id), args[0])
|
|
|
|
|
elif (args.size() == 2): rpc_id(int(current_client_id), args[0], args[1])
|
|
|
|
|
elif (args.size() == 3): rpc_id(int(current_client_id), args[0], args[1], args[2])
|
|
|
|
|
else: rpc_id(int(current_client_id), args[0], args[1], args[2], args[3])
|
|
|
|
|
else:
|
|
|
|
|
for current_client_id in clients.keys():
|
|
|
|
|
if (args.size() == 1): args[0].rpc_id(int(current_client_id))
|
|
|
|
|
elif (args.size() == 2): args[0].rpc_id(int(current_client_id), args[1])
|
|
|
|
|
elif (args.size() == 3): args[0].rpc_id(int(current_client_id), args[1], args[2])
|
|
|
|
|
else: args[0].rpc_id(int(current_client_id), args[1], args[2], args[3])
|
|
|
|
|
|
|
|
|
|
func send_everyone_except(client_id, args):
|
|
|
|
|
if (typeof(args[0]) == 4): #string
|
|
|
|
|
for current_client_id in clients.keys():
|
|
|
|
|
@@ -177,10 +219,7 @@ func _Peer_Connected(client_id):
|
|
|
|
|
client["is_playable"] = false
|
|
|
|
|
client["current_weapon"] = settings["game"]["weapons"]["knife"].duplicate()
|
|
|
|
|
|
|
|
|
|
print("New client's properties: " + str(clients[client_id]))
|
|
|
|
|
|
|
|
|
|
var puppet = player_model.instantiate()
|
|
|
|
|
#var CB3D = puppet.find_child("CharacterBody3D")
|
|
|
|
|
puppet.set_properties(clients[client_id])
|
|
|
|
|
|
|
|
|
|
server_map.add_child(puppet)
|
|
|
|
|
@@ -200,9 +239,9 @@ func client_ready(client_id):
|
|
|
|
|
else:
|
|
|
|
|
var index = abs(client["class_type"])
|
|
|
|
|
if (client["class_type"] > 0):
|
|
|
|
|
client["position"] = spawnpoints_os.pick_random().get_class_spawnpoint(index)
|
|
|
|
|
client["position"] = team_OS["spawnpoints"].pick_random().get_class_spawnpoint(index)
|
|
|
|
|
elif (client["class_type"] < 0):
|
|
|
|
|
client["position"] = spawnpoints_cs.pick_random().get_class_spawnpoint(index)
|
|
|
|
|
client["position"] = team_CS["spawnpoints"].pick_random().get_class_spawnpoint(index)
|
|
|
|
|
client_playermodel.set_properties(client)
|
|
|
|
|
client_playermodel.teleport.rpc_id(client_id, Vector3(client["position"].x, client["position"].y, client["position"].z))
|
|
|
|
|
|
|
|
|
|
@@ -210,6 +249,11 @@ func _Peer_Disconnected(client_id):
|
|
|
|
|
print("User " + str(client_id) + " has disconnected")
|
|
|
|
|
var client = clients[client_id]
|
|
|
|
|
var internal_id = client["internal_id"]
|
|
|
|
|
if (client["class_type"] < 0):
|
|
|
|
|
team_CS["members"].erase(client)
|
|
|
|
|
elif (client["class_type"] > 0):
|
|
|
|
|
team_OS["members"].erase(client)
|
|
|
|
|
|
|
|
|
|
rpc("despawn_puppet", internal_id)
|
|
|
|
|
var puppet = server_map.get_node("player" + str(internal_id))
|
|
|
|
|
server_map.remove_child(puppet)
|
|
|
|
|
@@ -242,7 +286,6 @@ func get_client_list(client_id):
|
|
|
|
|
|
|
|
|
|
@rpc ("any_peer", "call_remote", "reliable")
|
|
|
|
|
func get_server_settings(client_id):
|
|
|
|
|
print("Sending game settings")
|
|
|
|
|
var client = clients[client_id]
|
|
|
|
|
var internal_id = str(client["internal_id"])
|
|
|
|
|
var client_playermodel = find_playermodel_by_internal_id(internal_id)
|
|
|
|
|
@@ -250,7 +293,6 @@ func get_server_settings(client_id):
|
|
|
|
|
|
|
|
|
|
@rpc ("any_peer", "call_remote", "reliable")
|
|
|
|
|
func set_nickname(client_id, nickname):
|
|
|
|
|
print("Got nickname from client: " + str(nickname))
|
|
|
|
|
clients[client_id]["nickname"] = nickname
|
|
|
|
|
|
|
|
|
|
@rpc("any_peer", "call_remote", "reliable")
|
|
|
|
|
@@ -305,19 +347,30 @@ func shot(client_id):
|
|
|
|
|
if (client["current_weapon"]["magazine"] == 0):
|
|
|
|
|
return
|
|
|
|
|
client["last_shot"] = Time.get_ticks_msec()
|
|
|
|
|
var target_client_team = 1 if target_client["class_type"] > 0 else -1
|
|
|
|
|
var client_team = 1 if client["class_type"] > 0 else -1
|
|
|
|
|
|
|
|
|
|
target_client["HP"] -= damage
|
|
|
|
|
if (target_client_team == client_team):
|
|
|
|
|
if (settings["game"]["gamemodes"][gamemode]["firendlyfile"]):
|
|
|
|
|
target_client["HP"] -= damage
|
|
|
|
|
else:
|
|
|
|
|
target_client["HP"] -= damage
|
|
|
|
|
|
|
|
|
|
if (target_client["HP"] <= 0):
|
|
|
|
|
var index = abs(client["class_type"])
|
|
|
|
|
var respawn = Vector3(0, 10 ,0)
|
|
|
|
|
if (target_client["class_type"] > 0):
|
|
|
|
|
respawn = spawnpoints_os.pick_random().get_class_spawnpoint(index)
|
|
|
|
|
elif (target_client["class_type"] < 0):
|
|
|
|
|
respawn = spawnpoints_cs.pick_random().get_class_spawnpoint(index)
|
|
|
|
|
|
|
|
|
|
if (target_client_team == 1):
|
|
|
|
|
team_CS["round_score"] += 1
|
|
|
|
|
respawn = team_OS["spawnpoints"].pick_random().get_class_spawnpoint(index)
|
|
|
|
|
elif (target_client_team == -1):
|
|
|
|
|
team_OS["round_score"] += 1
|
|
|
|
|
respawn = team_CS["spawnpoints"].pick_random().get_class_spawnpoint(index)
|
|
|
|
|
|
|
|
|
|
print("Score(OS-CS): %s - %s" % [str(team_OS["round_score"]), str(team_CS["round_score"])])
|
|
|
|
|
target_client["position"] = respawn
|
|
|
|
|
target_client["HP"] = 100
|
|
|
|
|
target.teleport.rpc_id(target_client_id, target_client["position"])
|
|
|
|
|
check_gamemode_end_conditions()
|
|
|
|
|
target.set_hp.rpc_id(target_client_id, target_client["HP"])
|
|
|
|
|
elif (target is StaticBody3D):
|
|
|
|
|
var shapes = ["head", "body"]
|
|
|
|
|
@@ -325,6 +378,7 @@ func shot(client_id):
|
|
|
|
|
var shape = choose_collision_shape(target, shapes, shape_num)
|
|
|
|
|
target.shot.rpc_id(client_id, weapon_raycast.get_collision_point())
|
|
|
|
|
send_everyone_except(client_id, [target.shot, weapon_raycast.get_collision_point()])
|
|
|
|
|
|
|
|
|
|
func choose_collision_shape(target, shapes, shape_num):
|
|
|
|
|
var collision_shapes:Array
|
|
|
|
|
for s in target.get_children():
|
|
|
|
|
@@ -336,6 +390,7 @@ func choose_collision_shape(target, shapes, shape_num):
|
|
|
|
|
shape = collision_shapes[i]
|
|
|
|
|
break
|
|
|
|
|
return shape
|
|
|
|
|
|
|
|
|
|
@rpc("reliable", "call_remote", "any_peer")
|
|
|
|
|
func change_weapon(client_id, new_weapon_number):
|
|
|
|
|
var client = clients[client_id]
|
|
|
|
|
@@ -377,7 +432,7 @@ func reloading_complete(client_id, reloading_time):
|
|
|
|
|
else:
|
|
|
|
|
current_client_weapon["magazine"] += current_client_weapon["ammo"]
|
|
|
|
|
current_client_weapon["ammo"] = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@rpc("reliable", "any_peer", "call_remote")
|
|
|
|
|
func get_map(client_id):
|
|
|
|
|
rpc_id(client_id, "receive_map", map_path)
|
|
|
|
|
@@ -387,6 +442,11 @@ func choose_class(client_id, class_id):
|
|
|
|
|
var client = clients[client_id]
|
|
|
|
|
client["class_type"] = class_id
|
|
|
|
|
#here are must be checks if the teams are balanced. WIP.
|
|
|
|
|
if class_id > 0:
|
|
|
|
|
team_OS["members"].push_back(client)
|
|
|
|
|
elif class_id < 0:
|
|
|
|
|
team_CS["members"].push_back(client)
|
|
|
|
|
|
|
|
|
|
switch_class.rpc_id(client_id, class_id)
|
|
|
|
|
|
|
|
|
|
##########################################CLIENT#######################
|
|
|
|
|
@@ -399,13 +459,11 @@ var playermodel
|
|
|
|
|
|
|
|
|
|
@rpc ("reliable", "call_remote")
|
|
|
|
|
func set_character_properties(p):
|
|
|
|
|
print("Setting player properties to " + str(p))
|
|
|
|
|
player = p
|
|
|
|
|
|
|
|
|
|
@rpc("authority", "reliable", "call_remote")
|
|
|
|
|
func spawn_puppet(properties):
|
|
|
|
|
var puppet = player_model.instantiate()
|
|
|
|
|
#var CB3D = puppet.find_child("CharacterBody3D")
|
|
|
|
|
properties["ready"] = true
|
|
|
|
|
puppet.set_properties(properties.duplicate())
|
|
|
|
|
|
|
|
|
|
@@ -423,7 +481,6 @@ func receive_map(p):
|
|
|
|
|
|
|
|
|
|
@rpc("authority", "reliable", "call_remote")
|
|
|
|
|
func switch_class(class_id):
|
|
|
|
|
print("Switching to team: " + str(class_id))
|
|
|
|
|
if (class_id == 128): # team is full, you must chose another
|
|
|
|
|
current_map_instance.remove_child(choose_team_hud)
|
|
|
|
|
current_map_instance.add_child(choose_team_hud)
|
|
|
|
|
@@ -435,9 +492,10 @@ func switch_class(class_id):
|
|
|
|
|
playermodel.set_property("ready", true)
|
|
|
|
|
|
|
|
|
|
func spawn_player():
|
|
|
|
|
print(str(player_model))
|
|
|
|
|
playermodel = player_model.instantiate()
|
|
|
|
|
print(str(playermodel))
|
|
|
|
|
var properties = player_script.new().properties.duplicate()
|
|
|
|
|
#playermodel = player_node.find_child("player" + str(properties["internal_id"]))
|
|
|
|
|
|
|
|
|
|
properties = player
|
|
|
|
|
properties["is_playable"] = false
|
|
|
|
|
|