using System; using Godot; public partial class GameHandler : Node3D { Reference _Reference; Options _Options; [Export] public PackedScene[] MapList; [Export] public PackedScene Player; [Export] public PackedScene Sun; public bool serverRunning = false; public override void _Ready() { _Options = GetNode( "/root/Options" ); _Reference = GetNode("/root/Reference"); _Reference.GameHandler = this; _Reference.GameUI = GetNode("/root/GameRoot/UI/GameUI"); _Reference.Lighting = GetNode("/root/GameRoot/Lighting"); _Reference.ItemSpawner = GetNode("/root/GameRoot/ItemSpawner"); _Reference.ItemSpawnPath = GetNode("/root/GameRoot/PickupItems"); _Reference.ToolBar = GetNode("/root/GameRoot/UI/GameUI/Game/ToolBar"); string[] CMDS = OS.GetCmdlineArgs(); bool temp_launch_as_server = false; for( int i = 0; i < CMDS.Length; i++ ) { if( CMDS [i].ToLower() == "--map" | CMDS [i].ToLower() == "/map" ) { _Options.SelectedMap = Convert.ToInt32( CMDS [i + 1] ); } else if( CMDS [i].ToLower() == "--port" | CMDS [i].ToLower() == "/port" ) { _Options.Port = Convert.ToInt32( CMDS [i + 1] ); } else if( CMDS [i].ToLower() == "--players" | CMDS [i].ToLower() == "/players" ) { _Options.maxPlayers = Convert.ToInt32( CMDS [i + 1] ); } else if( CMDS [i].ToLower() == "--host" | CMDS [i].ToLower() == "/host" ) { _Options.Host = CMDS [i + 1]; } else if( CMDS [i].ToLower() == "server" ) { temp_launch_as_server = true; } } if( OS.HasFeature( "dedicated_server" ) || DisplayServer.GetName() == "headless" || temp_launch_as_server ) { StartServer(); } } public void StartServer(){ _Options.isServer = true; _Options.connection = new ENetMultiplayerPeer(); _Options.connection.CreateServer( _Options.Port, _Options.maxPlayers ); Multiplayer.MultiplayerPeer = _Options.connection; _Options.connection.PeerConnected += peerConnected; _Options.connection.PeerDisconnected += peerDisconnected; Node3D MapSelected = _Reference.GameHandler.MapList[_Options.SelectedMap].Instantiate(); MapSelected.SetMultiplayerAuthority(Multiplayer.GetUniqueId()); MapSelected.Name = "Workspace"; _Reference.Workspace = MapSelected; _Reference.GameHandler.AddChild( MapSelected ); // Spawn the sun AddChild( Sun.Instantiate() ); ResetItemDrops(); serverRunning = true; } public void StopServer(){ serverRunning = false; } public void StopClient(){ _Options.connection.PeerConnected -= peerConnected; _Options.connection.PeerDisconnected -= peerDisconnected; _Reference.Workspace.Multiplayer.ConnectedToServer -= ConnectedToServer; _Reference.Workspace.Multiplayer.ConnectionFailed -= ConnectionFailed; _Reference.Workspace.Multiplayer.ServerDisconnected -= DisconnectedFromServer; } public void StartClient(){ _Options.connection = new ENetMultiplayerPeer(); _Options.connection.CreateClient( _Options.Host, _Options.Port ); Multiplayer.MultiplayerPeer = _Options.connection; Multiplayer.ConnectedToServer += ConnectedToServer; Multiplayer.ConnectionFailed += ConnectionFailed; Multiplayer.ServerDisconnected += DisconnectedFromServer; } public void RemovePlayer(int id){ if (HasNode(id.ToString())) { GetNode(id.ToString()).QueueFree(); } } double timeElapsed = 0; void ResetItemDrops(){ foreach( Node3D cur in _Reference.ItemSpawnPath.GetChildren()){ cur.QueueFree(); } foreach( Node3D cur in _Reference.ItemSpawnPoints.GetChildren() ){ string[] PickupItems = _Reference.ItemSpawner._SpawnableScenes; int chosenItem = new Random(DateTime.Now.Millisecond).Next(0, PickupItems.Length); PackedScene ps = GD.Load(PickupItems[chosenItem]); Node3D prefab = ps.Instantiate(); prefab.Name = Guid.NewGuid().ToString(); _Reference.ItemSpawnPath.AddChild( prefab ); prefab.GlobalPosition = cur.GlobalPosition; } } public override void _Process(double delta) { if(serverRunning){ timeElapsed += delta; if (timeElapsed > _Options.timeBetweenDropsReset * 60){ ResetItemDrops(); timeElapsed = 0; } } } // Called on server public void peerConnected( long peerID ) { } public void peerDisconnected( long peerID ) { RemovePlayer(Convert.ToInt32(peerID)); } // Called on client public void ConnectedToServer() { _Reference.Alert.PerformAlert( "Connected to server successfully" ); } public void ConnectionFailed() { _Reference.Alert.PerformAlert( "Connection failed" ); } public void DisconnectedFromServer() { _Reference.Alert.PerformAlert( "Disconnected from server" ); } /////////////////////////////////////////////////////////////////////// /// RPC's /////////////////////////////////////////////////////////////////////// [Rpc( MultiplayerApi.RpcMode.AnyPeer, CallLocal = true, TransferChannel = 1, TransferMode = MultiplayerPeer.TransferModeEnum.Reliable)] void _takeDamage(float DMG, int Creator, int Hit){ // Take Damage Humanoid HitUser = null; foreach(Node cur in _Reference.GameHandler.GetChildren()){ if ( cur.Name.ToString().Split(new char[]{','})[0] == Hit.ToString() ){ HitUser = (Humanoid)cur; break; } } Humanoid CreatorUser = null; foreach(Node cur in _Reference.GameHandler.GetChildren()){ if ( cur.Name.ToString().Split(new char[]{','})[0] == Creator.ToString() ){ CreatorUser = (Humanoid)cur; break; } } HitUser.Health -= DMG; // If Player Died if( HitUser.Health <= 0 ) { // Stuff to do on the died players computer if (HitUser.GetMultiplayerAuthority() == Multiplayer.GetUniqueId()){ Input.MouseMode = Input.MouseModeEnum.Visible; _Reference.Alert.PerformAlert("You died from Player : " + CreatorUser.PlayerName); } // Stuff to do on the killers computer else if (CreatorUser.GetMultiplayerAuthority() == Multiplayer.GetUniqueId()){ _Reference.Alert.PerformAlert("You killed Player : " + HitUser.PlayerName); } // Stuff to do on Server else if ( Multiplayer.GetUniqueId() == 1 ){ } // Stuff to perform for everybody // Award the player points // Notify Player of kill // Reset Dead player } // Update UI For Hit Player if (HitUser.GetMultiplayerAuthority() == Multiplayer.GetUniqueId()){ HitUser.HealthBar.MaxValue = HitUser.MaxHealth; HitUser.HealthBar.Value = Convert.ToDouble( HitUser.Health ); } } public void TakeDamage(float DMG, int Creator, int Hit){ Rpc("_takeDamage", DMG, Creator, Hit); } [Rpc( MultiplayerApi.RpcMode.AnyPeer, CallLocal = false, TransferChannel = 1, TransferMode = MultiplayerPeer.TransferModeEnum.Reliable)] void _Shoot(int Creator, int itemID, Vector3 initialPosition, Vector3 ImpulseVector){ if (Multiplayer.GetUniqueId() == 1){ PackedScene ps = GD.Load("res://Prefab/bullet.tscn"); Bullet physicsBullet = ps.Instantiate(); physicsBullet.Name = Guid.NewGuid().ToString(); physicsBullet.Creator = Creator; physicsBullet.Damage = new GameItem(itemID).ItemStats.ToolDamage; GetNode("/root/GameRoot/Game").AddChild(physicsBullet); physicsBullet.SetDeferred("global_position", initialPosition); physicsBullet.CallDeferred("apply_impulse", ImpulseVector); } } public void Shoot(int ToolID, Vector3 LookVector, float ImpulseForce){ Rpc("_Shoot", Multiplayer.GetUniqueId(), ToolID, _Reference.Humanoid.GlobalPosition + LookVector * 4, LookVector * ImpulseForce); } [Rpc( MultiplayerApi.RpcMode.AnyPeer, CallLocal = false, TransferChannel = 1, TransferMode = MultiplayerPeer.TransferModeEnum.Reliable)] void _SpawnPlayer( int UniqueID, string PlayerName, int AbilityIndex ){ if (Multiplayer.IsServer()){ Humanoid playerCharacter = _Reference.GameHandler.Player.Instantiate(); playerCharacter.Name = UniqueID.ToString() + "," + AbilityIndex + "," + PlayerName; playerCharacter.PlayerName = PlayerName; AddChild(playerCharacter, true); playerCharacter.SetMultiplayerAuthority( UniqueID ); } } public void SpawnPlayer( int UniqueID, string PlayerName, Ability _Ability ){ Rpc( "_SpawnPlayer", UniqueID, PlayerName, (int)_Ability ); } [Rpc( MultiplayerApi.RpcMode.AnyPeer, CallLocal = true, TransferChannel = 1, TransferMode = MultiplayerPeer.TransferModeEnum.Reliable)] void _clearItemNetworked(string ItemName){ Node3D item = _Reference.ItemSpawnPath.GetNode(ItemName); if (item != null){ try{ item.QueueFree(); }catch{} } } public void ClearItemNetworked( string ItemName ){ Rpc("_clearItemNetworked", ItemName); } public class HumanoidStats { public int HumanoidOwner { get; set; } public string UserName { get; set; } public int MaxHealth { get; set; } public int Health { get; set; } } }