253 lines
10 KiB
C#
253 lines
10 KiB
C#
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<Options>( "/root/Options" );
|
|
_Reference = GetNode<Reference>("/root/Reference");
|
|
_Reference.GameHandler = this;
|
|
|
|
_Reference.GameUI = GetNode<Control>("/root/GameRoot/UI/GameUI");
|
|
_Reference.Lighting = GetNode<WorldEnvironment>("/root/GameRoot/Lighting");
|
|
_Reference.ItemSpawner = GetNode<MultiplayerSpawner>("/root/GameRoot/ItemSpawner");
|
|
_Reference.ItemSpawnPath = GetNode<Node>("/root/GameRoot/PickupItems");
|
|
_Reference.ToolBar = GetNode<Control>("/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<Node3D>();
|
|
MapSelected.SetMultiplayerAuthority(Multiplayer.GetUniqueId());
|
|
MapSelected.Name = "Workspace";
|
|
_Reference.Workspace = MapSelected;
|
|
_Reference.GameHandler.AddChild( MapSelected );
|
|
|
|
// Spawn the sun
|
|
AddChild( Sun.Instantiate<Node3D>() );
|
|
|
|
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<PackedScene>(PickupItems[chosenItem]);
|
|
Node3D prefab = ps.Instantiate<Node3D>();
|
|
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<PackedScene>("res://Prefab/bullet.tscn");
|
|
Bullet physicsBullet = ps.Instantiate<Bullet>();
|
|
physicsBullet.Name = Guid.NewGuid().ToString();
|
|
physicsBullet.Creator = Creator;
|
|
physicsBullet.Damage = new GameItem(itemID).ItemStats.ToolDamage;
|
|
GetNode<Node3D>("/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<Humanoid>();
|
|
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<Node3D>(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; }
|
|
}
|
|
|
|
} |