Files
2025-05-12 18:07:43 -07:00

349 lines
14 KiB
C#

using Godot;
using System;
using System.Collections.Generic;
public partial class Humanoid : CharacterBody3D {
Options _Options;
Reference _Reference;
[Export]
public AnimationTree Animator;
[Export]
public AnimQuickState CurrentAnimation;
[Export]
public Vector2 InputDirection;
UIMode CurrentUIMode = UIMode.Game;
(UIMode, Control)[] UIFrames;
public ProgressBar HealthBar;
ProgressBar StaminaBar;
public ITool EquippedTool;
Node Backpack;
public string PlayerName = "";
public float Health = 100;
public float MaxHealth = 100;
public float Stamina = 100;
public float MaxStamina = 100;
public float StaminaDrain = 5;
public float StaminaCharge = 5;
public float JumpStamina = 10;
public bool Running = false;
public float JumpVelocity = 5.5f;
public float RotationSpeed = 1f;
public float FallDistanceForDamage = 15;
public float FallDamageScale = 5f;
public Ability Ability;
public float Gravity = ProjectSettings.GetSetting( "physics/3d/default_gravity" ).AsSingle();
public bool mouseLock = true;
public float Speed {
get {
if( Running ) {
return 9f;
}
return 5f;
}
}
public override void _EnterTree() {
_Options = GetNode<Options>( "/root/Options" );
_Reference = GetNode<Reference>("/root/Reference");
string[] Data = Name.ToString().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
string PID = Data[0];
string AID = Data[1];
PlayerName = Data[2];
this.SetMultiplayerAuthority( Convert.ToInt32(PID), true );
if( IsMultiplayerAuthority() ) {
_Reference.Humanoid = this;
_Options.isAlive = true;
_Reference.Humanoid = this;
_Reference.Camera = GetChild<Camera3D>( 0 );
_Reference.Camera.GetChild<AudioListener3D>(0).MakeCurrent();
_Reference.Camera.Current = true;
UIFrames = new (UIMode, Control) [] {
( UIMode.Game, GetNode<Control>( "/root/GameRoot/UI/GameUI/Game" ) ),
( UIMode.Inventory, GetNode<Control>( "/root/GameRoot/UI/GameUI/Inventory" ) ),
( UIMode.Pause, GetNode<Control>( "/root/GameRoot/UI/SettingsFrame" ) )
};
HealthBar = GetNode<ProgressBar>( "/root/GameRoot/UI/GameUI/Game/HealthBar" );
StaminaBar = GetNode<ProgressBar>( "/root/GameRoot/UI/GameUI/Game/StaminaBar" );
Input.MouseMode = Input.MouseModeEnum.ConfinedHidden;
SetUIMode( CurrentUIMode );
HealthBar.MaxValue = MaxHealth;
HealthBar.Value = Health;
StaminaBar.MaxValue = MaxStamina;
StaminaBar.Value = Stamina;
EquipTool( 0 );
List<Vector3> spawnPoints = new List<Vector3>();
foreach (Node3D cur in _Reference.PlayerSpawnPoints.GetChildren()){
spawnPoints.Add(cur.GlobalPosition);
}
int chosenSpawn = new Random(DateTime.Now.Millisecond).Next(0, spawnPoints.Count);
this.SetDeferred("global_position", spawnPoints[chosenSpawn]);
Ability _Ability = (Ability)Convert.ToInt32(AID);
if (_Ability == Ability.Vitality){
MaxHealth *= 1.25f;
Health = MaxHealth;
} else if ( _Ability == Ability.Stamina ){
MaxStamina *= 1.25f;
StaminaCharge *= 1.25f;
Stamina = MaxStamina;
} else if ( _Ability == Ability.Strength ){
_Reference.Inventory.UpdateMaxWeight(500);
}
GetNode<Node3D>("PlayerModel").Visible = false;
}
}
public enum AnimQuickState{
Idle,
Walk,
Run,
Jump
}
Vector3 GetMovement( float deltaTime ) {
// Copy current velocity off the CharacterBody3d
Vector3 velocity = Velocity;
if( CurrentUIMode == UIMode.Game ) {
// Add the gravity.
if ( IsOnFloor() ) {
if ( Input.GetActionStrength( "Jump" ) == 1 && Stamina >= JumpStamina ) {
CurrentAnimation = AnimQuickState.Jump;
Stamina -= JumpStamina;
velocity.Y = JumpVelocity;
}
} else {
CurrentAnimation = AnimQuickState.Idle;
velocity.Y -= Gravity * deltaTime;
}
if (Running && Stamina <= 0){
Running = false;
}
// Get the input direction and handle the movement/deceleration.
Vector2 inputDir = Input.GetVector("Left", "Right", "Forward", "Backward");
Vector3 direction = (Transform.Basis * new Vector3(inputDir.X, 0, inputDir.Y)).Normalized();
if( direction != Vector3.Zero ) { // If there was input
velocity.X = direction.X * Speed;
velocity.Z = direction.Z * Speed;
if (Running){
Stamina -= deltaTime * StaminaDrain;
StaminaBar.Value = Stamina;
StaminaBar.MaxValue = MaxStamina;
CurrentAnimation = AnimQuickState.Run;
InputDirection = inputDir;
}else{
if (Stamina < MaxStamina){
Stamina += deltaTime * StaminaCharge / 2;
StaminaBar.Value = Stamina;
StaminaBar.MaxValue = MaxStamina;
}
CurrentAnimation = AnimQuickState.Walk;
InputDirection = inputDir;
}
} else { // If there was no input
velocity.X = Mathf.MoveToward( Velocity.X, 0, Speed );
velocity.Z = Mathf.MoveToward( Velocity.Z, 0, Speed );
if (Stamina < MaxStamina){
Stamina += deltaTime * StaminaCharge;
StaminaBar.Value = Stamina;
StaminaBar.MaxValue = MaxStamina;
}
CurrentAnimation = AnimQuickState.Idle;
}
} else {
velocity = new Vector3 (
Mathf.MoveToward( Velocity.X, 0, Speed /6 ),
velocity.Y - (Gravity * deltaTime),
Mathf.MoveToward( Velocity.Z, 0, Speed /6 )
);
if (Stamina < MaxStamina){
Stamina += deltaTime * StaminaCharge;
StaminaBar.Value = Stamina;
StaminaBar.MaxValue = MaxStamina;
}
CurrentAnimation = AnimQuickState.Idle;
}
return velocity;
}
public void EquipTool(int BackpackIndex ) {
if( Backpack == null ) {
Backpack = GetNode<Node>( "/root/GameRoot/UI/GameUI/Game/ToolBar" );
}
var Children = Backpack.GetChildren();
if( Children.Count > BackpackIndex ) {
foreach( Label cur in Children ) {
cur.Modulate = new Color( 1, 1, 1 );
}
if (EquippedTool != null ) {
EquippedTool.UnEquipped();
}
// If same button is pressed put tool away
Label UILabel = Backpack.GetChild<Label>( BackpackIndex );
UILabel.Modulate = new Color(1,0,1);
EquippedTool = ( ITool )UILabel.GetChild(0);
EquippedTool.Equiped();
}
}
enum UIMode {
Game,
Inventory,
Pause
}
void SetUIMode(UIMode mode) {
if (CurrentUIMode == UIMode.Inventory ) {
foreach( var cur in UIFrames ) {
if( cur.Item1 == UIMode.Inventory ) {
Inventory inv = (Inventory)cur.Item2;
if( inv._splitFrame != null ) {
inv._splitFrame.Free();
inv._splitFrame = null;
}
}
}
}
CurrentUIMode = mode;
foreach (var cur in UIFrames) {
if (cur.Item1 == mode) {
cur.Item2.Visible = true;
} else {
cur.Item2.Visible = false;
}
}
if (mode == UIMode.Game) {
Input.MouseMode = Input.MouseModeEnum.Captured;
mouseLock = true;
} else {
Input.MouseMode = Input.MouseModeEnum.Visible;
mouseLock = false;
}
}
public override void _Input( InputEvent _event ) {
if( IsMultiplayerAuthority() ) {
if( _event is InputEventKey eventKey ) {
int KeyCode = (int)eventKey.PhysicalKeycode;
if( eventKey.Keycode == Key.Escape ) {
if( eventKey.Pressed ) {
if( CurrentUIMode != UIMode.Pause ) {
SetUIMode( UIMode.Pause );
} else {
SetUIMode( UIMode.Game );
}
}
} else if( eventKey.Keycode == Key.Tab ) {
if( eventKey.Pressed ) {
if( CurrentUIMode != UIMode.Inventory ) {
SetUIMode( UIMode.Inventory );
} else {
SetUIMode( UIMode.Game );
}
}
}
if( CurrentUIMode == UIMode.Game ) {
if( eventKey.Keycode == Key.Shift ) {
if( eventKey.Pressed && Stamina > 0 ) {
Running = true;
} else {
Running = false;
}
} else if( eventKey.Pressed && KeyCode >= 49 && KeyCode <= 57 ) {
EquipTool( KeyCode - 49 );
} else if( eventKey.Pressed ) {
if( EquippedTool != null ) {
EquippedTool.KeyPress( eventKey.Keycode );
}
} else if( !eventKey.Pressed ) {
if( EquippedTool != null ) {
EquippedTool.KeyRelease( eventKey.Keycode );
}
}
}
} else if ( _event is InputEventMouseMotion ) {
if( mouseLock ) {
InputEventMouseMotion inputEventMouseMotion = (InputEventMouseMotion)_event;
Vector2 LookChange = inputEventMouseMotion.Relative;
// Horizontal Rotation
RotateY( LookChange.X * RotationSpeed * -0.002f );
// Vertical Rotation
_Reference.Camera.RotateX( LookChange.Y * RotationSpeed * -0.002f );
if( _Reference.Camera.RotationDegrees.X < -90 ) {
_Reference.Camera.RotationDegrees = new Vector3( -90, _Reference.Camera.RotationDegrees.Y, _Reference.Camera.RotationDegrees.Z );
} else if( _Reference.Camera.RotationDegrees.X > 90 ) {
_Reference.Camera.RotationDegrees = new Vector3( 90, _Reference.Camera.RotationDegrees.Y, _Reference.Camera.RotationDegrees.Z );
}
}
} else if ( _event is InputEventMouseButton _mouseevent ) {
if( mouseLock ) {
if( _mouseevent.ButtonIndex == MouseButton.Left ) {
if( EquippedTool != null && _mouseevent.Pressed ) {
EquippedTool.LeftMouseDown();
} else if( EquippedTool != null && !_mouseevent.Pressed ) {
EquippedTool.LeftMouseUp();
}
} else if( _mouseevent.ButtonIndex == MouseButton.Right ) {
if( EquippedTool != null && _mouseevent.Pressed ) {
EquippedTool.RightMouseDown();
} else if( EquippedTool != null && !_mouseevent.Pressed ) {
EquippedTool.RightMouseUp();
}
}
}
}
}
}
void SetAnimation(){
AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)Animator.Get("parameters/playback");
stateMachine.Travel( CurrentAnimation.ToString() );
Animator.Set("parameters/Walk/BlendSpace2D/blend_position", InputDirection);
Animator.Set("parameters/Run/BlendSpace2D/blend_position", InputDirection);
}
float LastY = -1;
public override void _PhysicsProcess( double _dT ) {
SetAnimation();
if( IsMultiplayerAuthority() ) {
float deltaTime = Convert.ToSingle( _dT );
// Fall Damage
if( IsOnFloor() ) {
if( LastY != -1 ) {
float FallDistance = LastY - GlobalPosition.Y;
if( FallDistance > FallDistanceForDamage ) {
_Reference.GameHandler.TakeDamage( (FallDistance - FallDistanceForDamage) * FallDamageScale, 0, Multiplayer.GetUniqueId() );
}
LastY = -1;
}
} else {
if( LastY == -1 ) {
LastY = GlobalPosition.Y;
}
}
// Copy the Velocity back onto the CharacterBody3d
Velocity = GetMovement( deltaTime );
// Apply Motion
MoveAndSlide();
}
}
}