Add backend round&games mechanic

This commit is contained in:
leca 2024-03-05 02:46:07 +03:00
parent dc8b70f14b
commit 7190a51e62
4 changed files with 121 additions and 39 deletions

View File

@ -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")):

View File

@ -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

View File

@ -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))

View File

@ -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,