Add backend round&games mechanic
This commit is contained in:
parent
dc8b70f14b
commit
7190a51e62
|
@ -21,6 +21,9 @@ var Weapons = {
|
|||
var client_settings
|
||||
var server_settings
|
||||
|
||||
func _ready():
|
||||
read_settings()
|
||||
|
||||
func read_settings():
|
||||
var user_dir = DirAccess.open(".")
|
||||
if(!user_dir.dir_exists("./settings")):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -279,3 +279,7 @@ func teleport(pos):
|
|||
func change_weapon_puppet(i_id, new_weapon_number):
|
||||
if (int(i_id) == properties["internal_id"]):
|
||||
change_weapon(new_weapon_number)
|
||||
|
||||
@rpc("authority", "call_remote", "reliable")
|
||||
func end_round(result):
|
||||
print("Result: %s" % str(result))
|
||||
|
|
|
@ -2,7 +2,24 @@
|
|||
"port": 2390,
|
||||
"maxclients": 10,
|
||||
"enableAntiCheat": false,
|
||||
"defaults":{
|
||||
"map": "training",
|
||||
"gamemode": "TDM"
|
||||
},
|
||||
"game": {
|
||||
"gamemodes":{
|
||||
"TDM": {
|
||||
"duration": 15,
|
||||
"kills": 3,
|
||||
"rounds": 3,
|
||||
"friendlyfire": false
|
||||
},
|
||||
"operation_cleaning": {
|
||||
"duration": 20,
|
||||
"rounds": 3,
|
||||
"friendlyfire": false
|
||||
}
|
||||
},
|
||||
"moving": {
|
||||
"walk": 12,
|
||||
"run": 24,
|
||||
|
|
Loading…
Reference in New Issue