From 123c1a2d9a5034902468b9f3ae5a139fff5c2f95 Mon Sep 17 00:00:00 2001 From: Anson Bridges Date: Tue, 20 Sep 2022 17:35:31 -0400 Subject: moving stuff off of laptop --- src/PlayerController.gd | 297 ------------------------ src/player_controller/.sconsign.dblite | Bin 0 -> 27268 bytes src/player_controller/PlayerController.gd | 297 ++++++++++++++++++++++++ src/player_controller/SConstruct | 2 +- src/player_controller/___player_controller.h | 18 ++ src/player_controller/gdlibrary.cpp | 17 ++ src/player_controller/gdlibrary.os | Bin 0 -> 406904 bytes src/player_controller/player_controller.h | 18 -- src/player_controller/playercam.cpp | 107 +++++++++ src/player_controller/playercam.h | 43 ++++ src/player_controller/playercam.os | Bin 0 -> 413784 bytes src/player_controller/playercontroller.cpp | 325 +++++++++++++++++++++++++++ src/player_controller/playercontroller.h | 93 ++++++++ src/playercontroller.cpp | 315 -------------------------- src/playercontroller.h | 85 ------- 15 files changed, 901 insertions(+), 716 deletions(-) delete mode 100644 src/PlayerController.gd create mode 100644 src/player_controller/.sconsign.dblite create mode 100644 src/player_controller/PlayerController.gd create mode 100644 src/player_controller/___player_controller.h create mode 100644 src/player_controller/gdlibrary.cpp create mode 100644 src/player_controller/gdlibrary.os delete mode 100644 src/player_controller/player_controller.h create mode 100644 src/player_controller/playercam.cpp create mode 100644 src/player_controller/playercam.h create mode 100644 src/player_controller/playercam.os create mode 100644 src/player_controller/playercontroller.cpp create mode 100644 src/player_controller/playercontroller.h delete mode 100644 src/playercontroller.cpp delete mode 100644 src/playercontroller.h diff --git a/src/PlayerController.gd b/src/PlayerController.gd deleted file mode 100644 index 241cbe0..0000000 --- a/src/PlayerController.gd +++ /dev/null @@ -1,297 +0,0 @@ -extends RigidBody - -# Game -export var team: String = "RED" -export var health: int = 100 -var weapon: Node = null -var world: Spatial = null - -# Camera -export var mouse_sensitivity:float = 12.0 -export var FOV:float = 90.0 -var mouse_axis: Vector2 = Vector2.ZERO -onready var head: Spatial = $Neck/Head -onready var neck: Spatial = $Neck - -# Move -var velocity := Vector3() -var direction := Vector3() -var move_axis := Vector2() -var floorspeed := Vector3() -var jumping:bool = false -var can_jump:bool = true -onready var nav: NavigationAgent = $NavigationAgent - -# Walk -const FLOOR_MAX_ANGLE: float = deg2rad(46.0) -export var jump_height: float = 300.0 -var in_water : bool = false -var swim_speed : float = 450.0 -var climb_speed : float = 5.0 - -# Control -var controlling_machine: bool = false #whether character is riding/controlling something -var machine : RigidBody = null -export var is_player: bool = false #whether character is currently controlled by a player -var ladder_m: Spatial = null - -#physics -var player_state: PhysicsDirectBodyState = null -var is_on_floor:bool -var floor_normal : Vector3 = Vector3.UP -var acceleration:float = 80.0 -export var walk_speed:float = 5.0 -var c_friction:float = 4.0 -var air_control:float = 0.3 - -# Called when the node enters the scene tree -func _ready() -> void: - weapon = preload("res://scenes/weapons/w_Rockets.tscn").instance() - add_child(weapon) - world = get_tree().get_root().get_node("GAMEWORLD") - - $"%UseRay".add_exception(self) - $"%MeleeRay".add_exception(self) - $"%UseRay".add_exception($AreaDetect) - $"%MeleeRay".add_exception($AreaDetect) - -func get_init_info() -> Dictionary: - return {"linear_velocity" : linear_velocity, "angular_velocity" : angular_velocity, "controlling_machine" : controlling_machine, "team" : team, "health" : health, "nametag" : $Nametag.text} - -func mp_init(init_info: Dictionary): - for variable in init_info.keys(): - set(variable, init_info[variable]) - $Nametag.text = init_info["nametag"] - -remote func set_phys_transform(trfrm: Transform, lvel: Vector3): - transform = trfrm - linear_velocity = lvel - -# Called every frame. 'delta' is the elapsed time since the previous frame -func _process(_delta: float) -> void: - if is_player and !world.is_chatting: - if Input.is_action_just_pressed("use"): - initiate_use() - - if controlling_machine: - if Input.is_action_just_pressed("fire"): - machine.attack1() - if Input.is_action_just_pressed("fire2"): - machine.attack2() - machine.direction_input(Input.get_action_strength("move_forward"),Input.get_action_strength("move_backward"), Input.get_action_strength("move_right"),Input.get_action_strength("move_left"), Input.get_action_strength("alt_right"),Input.get_action_strength("alt_left")) - machine.misc_input(Input.get_action_strength("move_duck"),Input.get_action_strength("move_jump"),Input.get_action_strength("move_walk")) - machine.mouse_input(Input.get_action_strength("fire"), Input.get_action_strength("fire3"),Input.get_action_strength("fire2")) - else: - jumping = Input.get_action_strength("move_jump") - if Input.is_action_just_pressed("fire"): - weapon.attack1() - move_axis.x = Input.get_action_strength("move_forward") - Input.get_action_strength("move_backward") - move_axis.y = Input.get_action_strength("move_right") - Input.get_action_strength("move_left") - - -func initiate_use(): - if controlling_machine: - machine.relinquish_control() - return - if ladder_m != null: - leave_ladder() - return - if $"%UseRay".is_colliding(): - var area_c = $"%UseRay".get_collider() - match area_c.name: - "SteerArea": - world.rpc_id(1, "_call_on_server", "_client_request_control_vehicle", {"id" : world.client_id, "machine_path" : area_c.get_parent().get_path(), "char_name" : name}) - "LadderArea": - mount_ladder(area_c.get_parent()) - "TugArea": - pass - "PickupArea": - pass - _: - pass - -remotesync func set_net_owner(owner_id: int): - $Nametag.text = "" - set_network_master(owner_id) - if owner_id != 1: - $Nametag.text = world.players_info[owner_id][0] - if get_tree().get_network_unique_id() != 1: - if owner_id == world.client_id: - $Nametag.visible = false - world.player_char = self - is_player = true - world.cam.attach(self, "FIRSTPERSON", "./Neck/Head") - else: - $Nametag.visible = true - is_player = false - world.get_node("HUD").update_characters() - -func deselect_character(): - if is_network_master(): - world.player_char = null - if world.client_id != 1: world.cam.attach(world, "STATIC", "./DEFAULTCAM") - rpc("set_net_owner", 1) - -func take_control_of_machine(slave_machine: RigidBody): - machine = slave_machine - controlling_machine = true - -func lose_machine(): - if is_network_master(): world.cam.attach(self, "FIRSTPERSON", "./Neck/Head") - controlling_machine = false - machine = null - -# Called every physics tick. 'delta' is constant -func _physics_process(delta: float) -> void: - if is_network_master(): - if ladder_m != null: - climb_ladder(delta) - elif !on_floor_test() and in_water: - swim(delta) - else: - walk(delta) - is_on_floor = false #reset whether is on floor in between frames - -# called each physics frame -func on_floor_test() -> bool: - if $Feet.is_colliding(): - is_on_floor = true - floor_normal = Vector3.UP - floorspeed = $Feet.get_collider().get_linear_velocity() if $Feet.get_collider().has_method("get_linear_velocity") else Vector3.ZERO - return true - if player_state: - for i in range(player_state.get_contact_count()): - var contact_angle_from_up : float = Vector3.UP.angle_to(player_state.get_contact_local_normal(i)) - if contact_angle_from_up < FLOOR_MAX_ANGLE: - floor_normal = player_state.get_contact_local_normal(i) - is_on_floor = true - return true - return false - -#modify simulated physics results -func _integrate_forces(state: PhysicsDirectBodyState) -> void: - if !is_network_master(): - return - player_state = state - velocity = state.get_linear_velocity() - $normal_vis.look_at($normal_vis.global_transform.origin + global_transform.basis.z, floor_normal) - for i in range(player_state.get_contact_count()): - var contact_angle_from_up : float = Vector3.UP.angle_to(player_state.get_contact_local_normal(i)) - if contact_angle_from_up > FLOOR_MAX_ANGLE and !is_on_floor: - friction = 0 - break - if i == player_state.get_contact_count() - 1: - friction = 1 - - rpc("set_phys_transform", transform, linear_velocity) - if global_transform.origin.y < -30: - rpc("damage", 500000, "drown", [1, "Davy Jones"]) - -func walk(_delta: float) -> void: - # Input - direction = Vector3() - var aim: Basis = head.get_global_transform().basis - direction += -move_axis.x * aim.z + move_axis.y * aim.x - direction.y = 0 - direction = direction.normalized() - - if floor_normal != Vector3.UP: direction = direction.rotated(floor_normal.cross(Vector3.UP).normalized(), Vector3.UP.angle_to(floor_normal)) - - # Jump - if is_player and jumping and is_on_floor and can_jump: - jump() - - #max walk speed - var _speed = walk_speed - var _temp_accel: float = acceleration - var _cspeed = sqrt(pow(velocity.x-floorspeed.x,2)+pow(velocity.z-floorspeed.z,2)) - - if not is_on_floor: - _temp_accel *= air_control - - var projVel = Vector2(velocity.x-floorspeed.x,velocity.z-floorspeed.z).dot(Vector2(direction.x,direction.z)) - - if is_on_floor: - add_central_force(-mass*_cspeed*linear_velocity.normalized()*c_friction)#friction - if _speed - _cspeed > 0: - add_central_force (mass*Vector3(direction.x*_temp_accel, 0, direction.z*_temp_accel))#velocity.x += direction.x*_temp_accel - else: - add_central_force(mass*Vector3(direction.x*(_speed-projVel), 0, direction.z*(_speed-projVel))) - elif 1.0 - projVel > 0: - add_central_force (mass*Vector3(direction.x*_temp_accel, 0, direction.z*_temp_accel)) - -func jump(): - can_jump = false - apply_central_impulse(Vector3.UP*jump_height) - yield(get_tree().create_timer(0.05),"timeout") - can_jump = true - -func swim(_delta: float): - #drag and buoyancy - add_central_force(Vector3.UP*weight*1.0) - add_central_force(-1*linear_velocity*100) - #controls - var dir: Basis = head.get_global_transform().basis - var m_dir: Vector3 = -move_axis.x * dir.z + move_axis.y * dir.x - m_dir = m_dir.normalized() - add_central_force(swim_speed*m_dir) - if jumping: - add_central_force(Vector3.UP*weight*0.5) - -func enter_water(): - in_water = true - -func exit_water(): - in_water = false - -func mount_ladder(target_ladder: Spatial): - var ladder_tracker = Spatial.new() - ladder_tracker.name = name - target_ladder.add_child(ladder_tracker) - ladder_tracker.transform = target_ladder.bottom.transform - - ladder_tracker.global_transform.origin = target_ladder.get_nearest_point_to_route(global_transform.origin) - look_at(global_transform.origin + target_ladder.global_transform.basis.x, target_ladder.global_transform.basis.y) - - ladder_m = ladder_tracker - global_transform.origin = ladder_m.global_transform.origin - global_transform.basis = ladder_m.global_transform.basis.orthonormalized() - linear_velocity = Vector3.ZERO - set_gravity_scale(0.0) - -#called each frame while climbing ladder -func climb_ladder(delta: float): - var new_ladder_pos = ladder_m.global_transform.origin + ladder_m.global_transform.basis.y.normalized() * move_axis.x * delta * climb_speed - var prog = ladder_m.get_parent().get_climb_scalar(new_ladder_pos) - if prog >= 0.0 and prog <= 1.0: - ladder_m.global_transform.origin = new_ladder_pos - global_transform.origin = ladder_m.global_transform.origin - global_transform.basis = ladder_m.global_transform.basis.orthonormalized() - -func leave_ladder(): - if (ladder_m.get_parent().top.global_transform.origin - global_transform.origin).length_squared() < 0.01: - apply_central_impulse(-400*ladder_m.global_transform.basis.z) - global_transform.basis = world.global_transform.basis - set_gravity_scale(1.0) - ladder_m.queue_free() - ladder_m = null - -remotesync func damage(dmg_amt: int, _type: String, shooter: Array, extra: String): - health -= dmg_amt - if health <= 0 and is_network_master(): - if shooter[0] != get_network_master() and shooter[0] != 1: world.rpc_id(shooter[0], "game_killsound") - if get_network_master() == 1: - world._call_on_server("_character_death", {"killer_id" : shooter[0], "killer" : shooter[1], "victim_mp_id" : get_network_master(), "victim" : name, "extra" : extra}) - else: - world.rpc_id(1, "_call_on_server", "_character_death", {"killer_id" : shooter[0], "killer" : shooter[1], "victim_mp_id" : get_network_master(), "victim" : name, "extra" : extra}) - elif is_network_master(): - if shooter[0] != get_network_master() and shooter[0] != 1: world.rpc_id(shooter[0], "game_hitsound") - -remotesync func remove_dead_character(): - if is_network_master() and machine != null: - machine.relinquish_control() - deselect_character() - queue_free() - -remotesync func net_apply_impulse(impulse_v: Vector3): - apply_central_impulse(impulse_v) diff --git a/src/player_controller/.sconsign.dblite b/src/player_controller/.sconsign.dblite new file mode 100644 index 0000000..577a41d Binary files /dev/null and b/src/player_controller/.sconsign.dblite differ diff --git a/src/player_controller/PlayerController.gd b/src/player_controller/PlayerController.gd new file mode 100644 index 0000000..241cbe0 --- /dev/null +++ b/src/player_controller/PlayerController.gd @@ -0,0 +1,297 @@ +extends RigidBody + +# Game +export var team: String = "RED" +export var health: int = 100 +var weapon: Node = null +var world: Spatial = null + +# Camera +export var mouse_sensitivity:float = 12.0 +export var FOV:float = 90.0 +var mouse_axis: Vector2 = Vector2.ZERO +onready var head: Spatial = $Neck/Head +onready var neck: Spatial = $Neck + +# Move +var velocity := Vector3() +var direction := Vector3() +var move_axis := Vector2() +var floorspeed := Vector3() +var jumping:bool = false +var can_jump:bool = true +onready var nav: NavigationAgent = $NavigationAgent + +# Walk +const FLOOR_MAX_ANGLE: float = deg2rad(46.0) +export var jump_height: float = 300.0 +var in_water : bool = false +var swim_speed : float = 450.0 +var climb_speed : float = 5.0 + +# Control +var controlling_machine: bool = false #whether character is riding/controlling something +var machine : RigidBody = null +export var is_player: bool = false #whether character is currently controlled by a player +var ladder_m: Spatial = null + +#physics +var player_state: PhysicsDirectBodyState = null +var is_on_floor:bool +var floor_normal : Vector3 = Vector3.UP +var acceleration:float = 80.0 +export var walk_speed:float = 5.0 +var c_friction:float = 4.0 +var air_control:float = 0.3 + +# Called when the node enters the scene tree +func _ready() -> void: + weapon = preload("res://scenes/weapons/w_Rockets.tscn").instance() + add_child(weapon) + world = get_tree().get_root().get_node("GAMEWORLD") + + $"%UseRay".add_exception(self) + $"%MeleeRay".add_exception(self) + $"%UseRay".add_exception($AreaDetect) + $"%MeleeRay".add_exception($AreaDetect) + +func get_init_info() -> Dictionary: + return {"linear_velocity" : linear_velocity, "angular_velocity" : angular_velocity, "controlling_machine" : controlling_machine, "team" : team, "health" : health, "nametag" : $Nametag.text} + +func mp_init(init_info: Dictionary): + for variable in init_info.keys(): + set(variable, init_info[variable]) + $Nametag.text = init_info["nametag"] + +remote func set_phys_transform(trfrm: Transform, lvel: Vector3): + transform = trfrm + linear_velocity = lvel + +# Called every frame. 'delta' is the elapsed time since the previous frame +func _process(_delta: float) -> void: + if is_player and !world.is_chatting: + if Input.is_action_just_pressed("use"): + initiate_use() + + if controlling_machine: + if Input.is_action_just_pressed("fire"): + machine.attack1() + if Input.is_action_just_pressed("fire2"): + machine.attack2() + machine.direction_input(Input.get_action_strength("move_forward"),Input.get_action_strength("move_backward"), Input.get_action_strength("move_right"),Input.get_action_strength("move_left"), Input.get_action_strength("alt_right"),Input.get_action_strength("alt_left")) + machine.misc_input(Input.get_action_strength("move_duck"),Input.get_action_strength("move_jump"),Input.get_action_strength("move_walk")) + machine.mouse_input(Input.get_action_strength("fire"), Input.get_action_strength("fire3"),Input.get_action_strength("fire2")) + else: + jumping = Input.get_action_strength("move_jump") + if Input.is_action_just_pressed("fire"): + weapon.attack1() + move_axis.x = Input.get_action_strength("move_forward") - Input.get_action_strength("move_backward") + move_axis.y = Input.get_action_strength("move_right") - Input.get_action_strength("move_left") + + +func initiate_use(): + if controlling_machine: + machine.relinquish_control() + return + if ladder_m != null: + leave_ladder() + return + if $"%UseRay".is_colliding(): + var area_c = $"%UseRay".get_collider() + match area_c.name: + "SteerArea": + world.rpc_id(1, "_call_on_server", "_client_request_control_vehicle", {"id" : world.client_id, "machine_path" : area_c.get_parent().get_path(), "char_name" : name}) + "LadderArea": + mount_ladder(area_c.get_parent()) + "TugArea": + pass + "PickupArea": + pass + _: + pass + +remotesync func set_net_owner(owner_id: int): + $Nametag.text = "" + set_network_master(owner_id) + if owner_id != 1: + $Nametag.text = world.players_info[owner_id][0] + if get_tree().get_network_unique_id() != 1: + if owner_id == world.client_id: + $Nametag.visible = false + world.player_char = self + is_player = true + world.cam.attach(self, "FIRSTPERSON", "./Neck/Head") + else: + $Nametag.visible = true + is_player = false + world.get_node("HUD").update_characters() + +func deselect_character(): + if is_network_master(): + world.player_char = null + if world.client_id != 1: world.cam.attach(world, "STATIC", "./DEFAULTCAM") + rpc("set_net_owner", 1) + +func take_control_of_machine(slave_machine: RigidBody): + machine = slave_machine + controlling_machine = true + +func lose_machine(): + if is_network_master(): world.cam.attach(self, "FIRSTPERSON", "./Neck/Head") + controlling_machine = false + machine = null + +# Called every physics tick. 'delta' is constant +func _physics_process(delta: float) -> void: + if is_network_master(): + if ladder_m != null: + climb_ladder(delta) + elif !on_floor_test() and in_water: + swim(delta) + else: + walk(delta) + is_on_floor = false #reset whether is on floor in between frames + +# called each physics frame +func on_floor_test() -> bool: + if $Feet.is_colliding(): + is_on_floor = true + floor_normal = Vector3.UP + floorspeed = $Feet.get_collider().get_linear_velocity() if $Feet.get_collider().has_method("get_linear_velocity") else Vector3.ZERO + return true + if player_state: + for i in range(player_state.get_contact_count()): + var contact_angle_from_up : float = Vector3.UP.angle_to(player_state.get_contact_local_normal(i)) + if contact_angle_from_up < FLOOR_MAX_ANGLE: + floor_normal = player_state.get_contact_local_normal(i) + is_on_floor = true + return true + return false + +#modify simulated physics results +func _integrate_forces(state: PhysicsDirectBodyState) -> void: + if !is_network_master(): + return + player_state = state + velocity = state.get_linear_velocity() + $normal_vis.look_at($normal_vis.global_transform.origin + global_transform.basis.z, floor_normal) + for i in range(player_state.get_contact_count()): + var contact_angle_from_up : float = Vector3.UP.angle_to(player_state.get_contact_local_normal(i)) + if contact_angle_from_up > FLOOR_MAX_ANGLE and !is_on_floor: + friction = 0 + break + if i == player_state.get_contact_count() - 1: + friction = 1 + + rpc("set_phys_transform", transform, linear_velocity) + if global_transform.origin.y < -30: + rpc("damage", 500000, "drown", [1, "Davy Jones"]) + +func walk(_delta: float) -> void: + # Input + direction = Vector3() + var aim: Basis = head.get_global_transform().basis + direction += -move_axis.x * aim.z + move_axis.y * aim.x + direction.y = 0 + direction = direction.normalized() + + if floor_normal != Vector3.UP: direction = direction.rotated(floor_normal.cross(Vector3.UP).normalized(), Vector3.UP.angle_to(floor_normal)) + + # Jump + if is_player and jumping and is_on_floor and can_jump: + jump() + + #max walk speed + var _speed = walk_speed + var _temp_accel: float = acceleration + var _cspeed = sqrt(pow(velocity.x-floorspeed.x,2)+pow(velocity.z-floorspeed.z,2)) + + if not is_on_floor: + _temp_accel *= air_control + + var projVel = Vector2(velocity.x-floorspeed.x,velocity.z-floorspeed.z).dot(Vector2(direction.x,direction.z)) + + if is_on_floor: + add_central_force(-mass*_cspeed*linear_velocity.normalized()*c_friction)#friction + if _speed - _cspeed > 0: + add_central_force (mass*Vector3(direction.x*_temp_accel, 0, direction.z*_temp_accel))#velocity.x += direction.x*_temp_accel + else: + add_central_force(mass*Vector3(direction.x*(_speed-projVel), 0, direction.z*(_speed-projVel))) + elif 1.0 - projVel > 0: + add_central_force (mass*Vector3(direction.x*_temp_accel, 0, direction.z*_temp_accel)) + +func jump(): + can_jump = false + apply_central_impulse(Vector3.UP*jump_height) + yield(get_tree().create_timer(0.05),"timeout") + can_jump = true + +func swim(_delta: float): + #drag and buoyancy + add_central_force(Vector3.UP*weight*1.0) + add_central_force(-1*linear_velocity*100) + #controls + var dir: Basis = head.get_global_transform().basis + var m_dir: Vector3 = -move_axis.x * dir.z + move_axis.y * dir.x + m_dir = m_dir.normalized() + add_central_force(swim_speed*m_dir) + if jumping: + add_central_force(Vector3.UP*weight*0.5) + +func enter_water(): + in_water = true + +func exit_water(): + in_water = false + +func mount_ladder(target_ladder: Spatial): + var ladder_tracker = Spatial.new() + ladder_tracker.name = name + target_ladder.add_child(ladder_tracker) + ladder_tracker.transform = target_ladder.bottom.transform + + ladder_tracker.global_transform.origin = target_ladder.get_nearest_point_to_route(global_transform.origin) + look_at(global_transform.origin + target_ladder.global_transform.basis.x, target_ladder.global_transform.basis.y) + + ladder_m = ladder_tracker + global_transform.origin = ladder_m.global_transform.origin + global_transform.basis = ladder_m.global_transform.basis.orthonormalized() + linear_velocity = Vector3.ZERO + set_gravity_scale(0.0) + +#called each frame while climbing ladder +func climb_ladder(delta: float): + var new_ladder_pos = ladder_m.global_transform.origin + ladder_m.global_transform.basis.y.normalized() * move_axis.x * delta * climb_speed + var prog = ladder_m.get_parent().get_climb_scalar(new_ladder_pos) + if prog >= 0.0 and prog <= 1.0: + ladder_m.global_transform.origin = new_ladder_pos + global_transform.origin = ladder_m.global_transform.origin + global_transform.basis = ladder_m.global_transform.basis.orthonormalized() + +func leave_ladder(): + if (ladder_m.get_parent().top.global_transform.origin - global_transform.origin).length_squared() < 0.01: + apply_central_impulse(-400*ladder_m.global_transform.basis.z) + global_transform.basis = world.global_transform.basis + set_gravity_scale(1.0) + ladder_m.queue_free() + ladder_m = null + +remotesync func damage(dmg_amt: int, _type: String, shooter: Array, extra: String): + health -= dmg_amt + if health <= 0 and is_network_master(): + if shooter[0] != get_network_master() and shooter[0] != 1: world.rpc_id(shooter[0], "game_killsound") + if get_network_master() == 1: + world._call_on_server("_character_death", {"killer_id" : shooter[0], "killer" : shooter[1], "victim_mp_id" : get_network_master(), "victim" : name, "extra" : extra}) + else: + world.rpc_id(1, "_call_on_server", "_character_death", {"killer_id" : shooter[0], "killer" : shooter[1], "victim_mp_id" : get_network_master(), "victim" : name, "extra" : extra}) + elif is_network_master(): + if shooter[0] != get_network_master() and shooter[0] != 1: world.rpc_id(shooter[0], "game_hitsound") + +remotesync func remove_dead_character(): + if is_network_master() and machine != null: + machine.relinquish_control() + deselect_character() + queue_free() + +remotesync func net_apply_impulse(impulse_v: Vector3): + apply_central_impulse(impulse_v) diff --git a/src/player_controller/SConstruct b/src/player_controller/SConstruct index f4bb318..119ad0b 100644 --- a/src/player_controller/SConstruct +++ b/src/player_controller/SConstruct @@ -12,7 +12,7 @@ opts.Add(EnumVariable('platform', "Compilation platform", '', ['', 'windows', 'x opts.Add(EnumVariable('p', "Compilation target, alias for 'platform'", '', ['', 'windows', 'x11', 'linux', 'osx'])) opts.Add(BoolVariable('use_llvm', "Use the LLVM / Clang compiler", 'no')) opts.Add(PathVariable('target_path', 'The path where the lib is installed.', '../../godot/bin/')) -opts.Add(PathVariable('target_name', 'The library name.', 'libgdexample', PathVariable.PathAccept)) +opts.Add(PathVariable('target_name', 'The library name.', 'libplayercontroller', PathVariable.PathAccept)) # Local dependency paths, adapt them to your setup godot_headers_path = "../../godot-cpp/godot-headers/" diff --git a/src/player_controller/___player_controller.h b/src/player_controller/___player_controller.h new file mode 100644 index 0000000..2514f79 --- /dev/null +++ b/src/player_controller/___player_controller.h @@ -0,0 +1,18 @@ +#ifndef PLAYER_CONTROLLER_H +#define PLAYER_CONTROLLER_H + +#include +#include + +namespace godot { + +class PlayerController : public RigidBody { + GODOT_CLASS(PlayerController, RigidBody) + +private: + String +public: + static void _register_methods(); + + PlayerController(); + ~PlayerController(); diff --git a/src/player_controller/gdlibrary.cpp b/src/player_controller/gdlibrary.cpp new file mode 100644 index 0000000..13bc8a1 --- /dev/null +++ b/src/player_controller/gdlibrary.cpp @@ -0,0 +1,17 @@ +#include "playercam.h" +#include "playercontroller.h" + +extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) { + godot::Godot::gdnative_init(o); +} + +extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) { + godot::Godot::gdnative_terminate(o); +} + +extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) { + godot::Godot::nativescript_init(handle); + + godot::register_class(); + godot::register_class(); +} diff --git a/src/player_controller/gdlibrary.os b/src/player_controller/gdlibrary.os new file mode 100644 index 0000000..c984489 Binary files /dev/null and b/src/player_controller/gdlibrary.os differ diff --git a/src/player_controller/player_controller.h b/src/player_controller/player_controller.h deleted file mode 100644 index 2514f79..0000000 --- a/src/player_controller/player_controller.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PLAYER_CONTROLLER_H -#define PLAYER_CONTROLLER_H - -#include -#include - -namespace godot { - -class PlayerController : public RigidBody { - GODOT_CLASS(PlayerController, RigidBody) - -private: - String -public: - static void _register_methods(); - - PlayerController(); - ~PlayerController(); diff --git a/src/player_controller/playercam.cpp b/src/player_controller/playercam.cpp new file mode 100644 index 0000000..f321c09 --- /dev/null +++ b/src/player_controller/playercam.cpp @@ -0,0 +1,107 @@ +#include "playercam.h" +#include "InputEventMouseMotion.hpp" + + +using namespace godot; + +PlayerCam::PlayerCam () { } +PlayerCam::~PlayerCam () { } + +void PlayerCam::_register_methods() { + register_method("_ready", &PlayerCam::_ready); + register_method("_input", &PlayerCam::_input); + register_method("attach", &PlayerCam::attach); + register_method("mouse_firstperson", &PlayerCam::mouse_firstperson); + register_method("mouse_thirdperson", &PlayerCam::mouse_thirdperson); + register_method("mouse_arm", &PlayerCam::mouse_arm); + register_method("mouse_freecam", &PlayerCam::mouse_freecam); +} + +void PlayerCam::_init() { + mode = String("STATIC"); + head = nullptr; + neck = nullptr; + player = nullptr; + arm = nullptr; + mouse_axis = Vector2::ZERO; + mouse_sensitivity = 12.0; +} + +void PlayerCam::_ready() { + Input *input_singleton = Input::get_singleton(); + input_singleton->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); + set_current(true); +} + +void PlayerCam::_input(const Ref event) { + Input const *input_singleton = Input::get_singleton(); + Ref event_m(event); + if(event_m.is_valid() && input_singleton->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED){ + mouse_axis = event_m->get_relative(); + if(mode == "FIRSTPERSON")mouse_firstperson(); + else if(mode == "THIRDPERSON")mouse_thirdperson(); + else if(mode == "STATIC"); + else if(mode == "ARM")mouse_arm(); + else if(mode == "FREECAM")mouse_freecam(); + } +} + +void PlayerCam::attach(Node* new_parent, String c_mode, String extra_path) { + if(get_parent() != nullptr) + get_parent()->remove_child(this); + if(c_mode == "FIRSTPERSON") { + head = (Spatial*)new_parent->find_node("Head", true, false); neck = (Spatial*)new_parent->find_node("Neck", true, false); + arm = nullptr; mode = c_mode; + } + else if (c_mode == "THIRDPERSON") { + head = (Spatial*)new_parent->find_node("Head", true, false); neck = (Spatial*)new_parent->find_node("Neck", true, false); + arm = (SpringArm*)new_parent->find_node("SpringArm", true, false); mode = c_mode; + } + else if(c_mode == "ARM") { + head = nullptr; neck = nullptr; + arm = (SpringArm*)new_parent->find_node("SpringArm", true, false); mode = c_mode; + } + else { + head = nullptr; neck = nullptr; arm = nullptr; + } + new_parent->get_node(NodePath(extra_path))->add_child(this); + set_transform(Transform::IDENTITY); +} + +void PlayerCam::mouse_firstperson() { + if(mouse_axis.length_squared() > 0.0){ + float horizontal = -mouse_axis.x * (mouse_sensitivity / 100.0); + float vertical = -mouse_axis.y * (mouse_sensitivity / 100.0); + + neck->rotate_y(Math::deg2rad(horizontal)); + head->rotate_x(Math::deg2rad(vertical)); + + //vertical clamp + Vector3 new_rot = head->get_rotation_degrees(); + new_rot.x = Math::clamp((double)new_rot.x, -90.0, 90.0); + head->set_rotation_degrees(new_rot); + } +} + +void PlayerCam::mouse_thirdperson() { + Vector3 new_arm_rot = arm->get_rotation_degrees(); + new_arm_rot.x = Math::clamp((double)(get_rotation_degrees().x-mouse_axis.y*(mouse_sensitivity / 100)),-90.0,90.0); + new_arm_rot.y -= mouse_axis.x*(mouse_sensitivity / 100.0); + arm->set_rotation_degrees(new_arm_rot); + Vector3 new_head_rot = Vector3(arm->get_rotation_degrees().x, 0, 0); + Vector3 new_neck_rot = Vector3(0, arm->get_rotation_degrees().y, 0); + + head->set_rotation_degrees(new_head_rot); + neck->set_rotation_degrees(new_neck_rot); +} + +void PlayerCam::mouse_arm() { + //arm->rotation_degrees.x = Math::clamp(rotation_degrees.x-mouse_axis.y*(mouse_sensitivity / 100),-70,70); + //arm->rotation_degrees.y -= mouse_axis.x*(mouse_sensitivity / 100); +} + +void PlayerCam::mouse_freecam() { +// pass +} + + diff --git a/src/player_controller/playercam.h b/src/player_controller/playercam.h new file mode 100644 index 0000000..dd089de --- /dev/null +++ b/src/player_controller/playercam.h @@ -0,0 +1,43 @@ +#ifndef PLAYERCAMGDS_H +#define PLAYERCAMGDS_H + +#include +#include +#include +#include +#include + +namespace godot { + +class PlayerCam : public ClippedCamera { + GODOT_CLASS(PlayerCam, ClippedCamera) + +private: + String mode; + Spatial* head; + Spatial* neck; + RigidBody* player; + SpringArm* arm; + Vector2 mouse_axis; + float mouse_sensitivity; + +public: + static void _register_methods(); + + PlayerCam(); + ~PlayerCam(); + + void _init(); + + void _ready(); + void _input(const Ref event); + void attach(Node* new_parent, String c_mode, String extra_path = "."); + void mouse_firstperson(); + void mouse_thirdperson(); + void mouse_arm(); + void mouse_freecam(); + +}; + +} +#endif diff --git a/src/player_controller/playercam.os b/src/player_controller/playercam.os new file mode 100644 index 0000000..2b88b46 Binary files /dev/null and b/src/player_controller/playercam.os differ diff --git a/src/player_controller/playercontroller.cpp b/src/player_controller/playercontroller.cpp new file mode 100644 index 0000000..6ea5544 --- /dev/null +++ b/src/player_controller/playercontroller.cpp @@ -0,0 +1,325 @@ +#include "playercontroller.h" +#include +#include +#include + +using namespace godot; + +PlayerController::PlayerController () { } +PlayerController::~PlayerController () { } + +void PlayerController::_register_methods() { + register_method("_ready", &PlayerController::_ready); + register_method("get_init_info", &PlayerController::get_init_info); + register_method("mp_init", &PlayerController::mp_init); + register_method("set_phys_transform", &PlayerController::set_phys_transform, GODOT_METHOD_RPC_MODE_REMOTE); + register_method("_process", &PlayerController::_process); + register_method("initiate_use", &PlayerController::initiate_use); + register_method("set_net_owner", &PlayerController::set_net_owner, GODOT_METHOD_RPC_MODE_REMOTESYNC); + register_method("deselect_character", &PlayerController::deselect_character); + register_method("take_control_of_machine", &PlayerController::take_control_of_machine); + register_method("lose_machine", &PlayerController::lose_machine); + register_method("_physics_process", &PlayerController::_physics_process); + register_method("on_floor_test", &PlayerController::on_floor_test); + register_method("_integrate_forces", &PlayerController::_integrate_forces); + register_method("walk", &PlayerController::walk); + register_method("jump", &PlayerController::jump); + register_method("swim", &PlayerController::swim); + register_method("enter_water", &PlayerController::enter_water); + register_method("exit_water", &PlayerController::exit_water); + register_method("mount_ladder", &PlayerController::mount_ladder); + register_method("climb_ladder", &PlayerController::climb_ladder); + register_method("leave_ladder", &PlayerController::leave_ladder); + register_method("damage", &PlayerController::damage, GODOT_METHOD_RPC_MODE_REMOTESYNC); + register_method("remove_dead_character", &PlayerController::remove_dead_character, GODOT_METHOD_RPC_MODE_REMOTESYNC); + register_method("net_apply_impulse", &PlayerController::net_apply_impulse, GODOT_METHOD_RPC_MODE_REMOTESYNC); + + register_property("team", &PlayerController::team, String("RED")); + register_property("health", &PlayerController::health, int(100)); + register_property("mouse_sensitivity", &PlayerController::mouse_sensitivity, float(12.0)); + register_property("FOV", &PlayerController::FOV, float(90.0)); + register_property("jump_height", &PlayerController::jump_height, float(300.0)); + register_property("is_player", &PlayerController::is_player, bool(false)); + register_property("walk_speed", &PlayerController::walk_speed, float(5.0)); +} + +void PlayerController::_init() { + weapon = nullptr; + world = nullptr; + mouse_axis = Vector2::ZERO; + velocity = Vector3::ZERO; + direction = Vector3::ZERO; + move_axis = Vector2::ZERO; + floorspeed = Vector3::ZERO; + jumping = false; + can_jump = true; + FLOOR_MAX_ANGLE = Math::deg2rad(46.0); + in_water = false; + swim_speed = 450.0; + climb_speed = 5.0; + controlling_machine = false; + machine = nullptr; + ladder_m = nullptr; + player_state = nullptr; + is_on_floor = false; + floor_normal = Vector3::UP; + acceleration = 80.0; + c_friction = 4.0; + air_control = 0.3; +} + +void PlayerController::_ready() { + head = get_node(NodePath("Neck/Head")); + neck = get_node(NodePath("Neck")); + useray = get_node(NodePath("Neck/Head/UseRay")); + nametag = get_node(NodePath("Nametag")); + nav = get_node(NodePath("NavigationAgent")); + Ref p = ResourceLoader::get_singleton()->load("res://scenes/weapons/w_Rockets.tscn"); + weapon = (Node *)p->instance(); + add_child(weapon); + world = get_tree()->get_root()->get_node("GAMEWORLD"); + cam = (PlayerCam *)world->call("get_cam"); +} + +Dictionary PlayerController::get_init_info() { + return Dictionary::make("linear_velocity", get_linear_velocity(), "angular_velocity", get_angular_velocity(), "controlling_machine", controlling_machine, "team", team, "health", health, "nametag", get_node("Nametag")->get_text()); +} + +void PlayerController::mp_init(Dictionary init_info) { + for(int i = 0; i < init_info.keys().size(); i++) + set(init_info.keys()[i], init_info[init_info.keys()[i]]); + nametag->set_text(init_info["nametag"]); +} + +void PlayerController::set_phys_transform(Transform trfrm, Vector3 lvel) { + set_transform(trfrm); + set_linear_velocity(lvel); +} + +void PlayerController::_process(float _delta) { + const Input *input_singleton = Input::get_singleton(); + if(is_player && !world->call("is_chatting_f")){ + if(input_singleton->is_action_just_pressed("use")) + initiate_use(); + if(controlling_machine) { + if(input_singleton->is_action_just_pressed("fire"))machine->call("attack1"); + if(input_singleton->is_action_just_pressed("fire2"))machine->call("attack2"); + } + } +} + +void PlayerController::initiate_use() { + if(controlling_machine){machine->call("relinquish_control"); return; } + if(ladder_m != nullptr) { leave_ladder(); return; } + if(useray->is_colliding()){ + const Node *area_c = (Node *) useray->get_collider(); + if(area_c->get_name() == "SteerArea") + world->rpc_id(1, "_call_on_server", "_client_request_control_vehicle", Dictionary::make("id", world->call("get_client_id"), "machine_path", area_c->get_parent()->get_path(), "char_name", get_name())); + else if(area_c->get_name() == "LadderArea") + mount_ladder((Spatial *)area_c->get_parent()); + else if(area_c->get_name() == "TugArea")return; + else if(area_c->get_name() == "PickupArea")return; + } +} + +void PlayerController::set_net_owner(int owner_id) { + nametag->set_text(""); + set_network_master(owner_id); + if(owner_id != 1) + nametag->set_text(String(world->call("get_players_info")[owner_id][0])); + if(get_tree()->get_network_unique_id() != 1){ + if(owner_id == (int)world->call("get_client_id")){ + nametag->set_visible(false); + world->call("set_player_char", this); + is_player = true; + cam->attach(this, "FIRSTPERSON", "./Neck/Head"); + }else{ + nametag->set_visible(true); + is_player = false; + } + world->get_node("HUD")->call("update_characters"); + } +} + +void PlayerController::deselect_character() { + if(is_network_master()){ + world->call("set_player_char", nullptr); + if((int)world->call("get_client_id") != 1)cam->attach(world, "STATIC", "./DEFAULTCAM"); + rpc("set_net_owner", 1); + } +} + +void PlayerController::take_control_of_machine(RigidBody *slave_machine) { + machine = slave_machine; + controlling_machine = true; +} + +void PlayerController::lose_machine() { + if(is_network_master())cam->attach(this, "FIRSTPERSON", "./Neck/Head"); + controlling_machine = false; + machine = nullptr; +} + +void PlayerController::_physics_process(float delta) { + if(is_network_master()) { + if (ladder_m != nullptr) + climb_ladder(delta); + else if( !on_floor_test() && in_water) + swim(delta); + else + walk(delta); + is_on_floor = false;// #reset whether is on floor in between frames + } +} + +bool PlayerController::on_floor_test() { + const RayCast *feet = get_node("Feet"); + if(feet->is_colliding()){ + is_on_floor = true; + floor_normal = Vector3::UP; + floorspeed = feet->get_collider()->has_method("get_linear_velocity") ? feet->get_collider()->get_linear_velocity() : Vector3::ZERO; + return true; + } + if(player_state){ + for(int i = 0;i< player_state->get_contact_count()) { + float contact_angle_from_up = Vector3::UP.angle_to(player_state->get_contact_local_normal(i)) + if(contact_angle_from_up < FLOOR_MAX_ANGLE) { + floor_normal = player_state->get_contact_local_normal(i); + is_on_floor = true; + return true; + } + } + } + return false; +} + +void PlayerController::_integrate_forces(PhysicsDirectBodyState *state) { + if(!is_network_master()) return; + player_state = state; + velocity = state->get_linear_velocity(); + for(int i=0; i < player_state->get_contact_count(); i++) { + float contact_angle_from_up = Vector3::UP.angle_to(player_state->get_contact_local_normal(i)); + if(contact_angle_from_up > FLOOR_MAX_ANGLE && !is_on_floor){ + set_friction(0); + break; + } + if(i == player_state.get_contact_count() - 1) + set_friction(1); + } + rpc("set_phys_transform", get_transform(), get_linear_velocity()); + if(get_global_transform().origin.y < -30) + rpc("damage", 500000, "drown", Array::make(1, String("Davy Jones")); +} + +void PlayerController::walk(float _delta) { +// # Input +// direction = Vector3() +// var aim: Basis = head.get_global_transform().basis +// direction += -move_axis.x * aim.z + move_axis.y * aim.x +// direction.y = 0 +// direction = direction.normalized() +// +// if floor_normal != Vector3.UP: direction = direction.rotated(floor_normal.cross(Vector3.UP).normalized(), Vector3.UP.angle_to(floor_normal)) +// +// # Jump +// if is_player and jumping and is_on_floor and can_jump: +// jump() +// +// #max walk speed +// var _speed = walk_speed +// var _temp_accel: float = acceleration +// var _cspeed = sqrt(pow(velocity.x-floorspeed.x,2)+pow(velocity.z-floorspeed.z,2)) +// +// if not is_on_floor: +// _temp_accel *= air_control +} + +void PlayerController::jump() { + can_jump = false; + apply_central_impulse(Vector3.UP*jump_height); + yield(get_tree().create_timer(0.05),"timeout"); + can_jump = true; +} + +void PlayerController::swim(float _delta) { +// #drag and buoyancy + add_central_force(Vector3::UP*weight); + add_central_force(-100*linear_velocity); +// #controls + Basis dir = head->get_global_transform().basis; + Vector3 m_dir = -move_axis.x * dir.z + move_axis.y * dir.x; + m_dir = m_dir.normalized(); + add_central_force(swim_speed*m_dir); + if(jumping) add_central_force(Vector3::UP*get_weight()*0.5); +} + +void PlayerController::enter_water() { + in_water = true; +} + +void PlayerController::exit_water() { + in_water = false; +} + +void PlayerController::mount_ladder(Spatial *target_ladder) { + Spatial *ladder_tracker = Spatial::new(); + ladder_tracker->name = get_name(); + target_ladder->add_child(ladder_tracker); + ladder_tracker->set_transform(target_ladder->get_node("BOTTOM")->get_transform(); + + ladder_tracker->set_global_transform( Transform(target_ladder->call("get_nearest_point_to_route", get_global_transform().origin), ladder_tracker->get_global_transform().basis ) ); + look_at(get_global_transform().origin + target_ladder->get_global_transform().basis.x, target_ladder->get_global_transform().basis.y) + + ladder_m = ladder_tracker; + Transform t = ladder_m->get_global_transform(); + set_global_transform( Transform(t.origin, t.basis.orthonormalized())); + set_linear_velocity(Vector3::ZERO); + set_gravity_scale(0.0); +} + +void PlayerController::climb_ladder(float delta) { + Vector3 new_ladder_pos = ladder_m->get_global_transform().origin + ladder_m->get_global_transform().basis.y.normalized() * move_axis.x * delta * climb_speed; + float prog = ladder_m->get_parent()->call("get_climb_scalar", new_ladder_pos) + if(prog >= 0.0 and && <= 1.0) + ladder_m->set_global_transform(Transform(new_ladder_pos, ladder_m->get_global_transform().basis)); + Transform t = ladder_m->get_global_transform(); + set_global_transform( Transform(t.origin, t.basis.orthonormalized())); +} + +void PlayerController::leave_ladder() { + if((ladder_m->get_parent()->get_node("TOP")->global_transform.origin - get_global_transform().origin).length_squared() < 0.01) + apply_central_impulse(-400*ladder_m->get_global_transform().basis.z); + Transform t = get_global_transform(); + t.basis = world->get_global_transform().basis; + set_global_transform(t); + set_gravity_scale(1.0); + ladder_m->queue_free(); + ladder_m = nullptr; +} + +void PlayerController::damage(int dmg_amt, String _type, Array shooter, String extra = ".") { + health -= dmg_amt; + int shooter_id = shooter[0]; + String shooter_text = shooter[1]; + if(health <= 0 && is_network_master()){ + if(shooter_id != get_network_master() && shooter_id != 1) world->rpc_id(shooter_id, "game_killsound"); + if(get_network_master() == 1) + world->call("_call_on_server", "_character_death", Dictionary::make("killer_id", shooter_id, "killer", shooter_text, "victim_mp_id", get_network_master(), "victim", get_name(), "extra", extra)); + else + world->rpc_id(1, "_call_on_server", "_character_death", Dictionary::make("killer_id", shooter_id, "killer", shooter_text, "victim_mp_id", get_network_master(), "victim", get_name(), "extra", extra)); + } else if( is_network_master()) + if(shooter_id != get_network_master() && shooter_id != 1) world->rpc_id(shooter_id, "game_hitsound"); +} + +void PlayerController::remove_dead_character() { + if(is_network_master() && machine != nullptr) + machine->call("relinquish_control"); + deselect_character(); + queue_free(); +} + +void PlayerController::net_apply_impulse(Vector3 impulse_v) { + apply_central_impulse(impulse_v); +} + + diff --git a/src/player_controller/playercontroller.h b/src/player_controller/playercontroller.h new file mode 100644 index 0000000..402f7d3 --- /dev/null +++ b/src/player_controller/playercontroller.h @@ -0,0 +1,93 @@ +#ifndef PLAYERCONTROLLER_H +#define PLAYERCONTROLLER_H + +#include "playercam.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace godot { + +class PlayerController : public RigidBody { + GODOT_CLASS(PlayerController, RigidBody) + +private: + String team; + int health; + Node *weapon; + Spatial *world; + PlayerCam *cam; + float mouse_sensitivity; + float FOV; + Vector2 mouse_axis; + Spatial *head; + Spatial *neck; + RayCast *useray; + Label3D *nametag; + Vector3 velocity; + Vector3 direction; + Vector2 move_axis; + Vector3 floorspeed; + bool jumping; + bool can_jump; + NavigationAgent *nav; + float FLOOR_MAX_ANGLE; + float jump_height; + bool in_water; + float swim_speed; + float climb_speed; + bool controlling_machine; + RigidBody *machine; + bool is_player; + Spatial *ladder_m; + PhysicsDirectBodyState *player_state; + bool is_on_floor; + Vector3 floor_normal; + float acceleration; + float walk_speed; + float c_friction; + float air_control; + + +public: + static void _register_methods(); + + PlayerController(); + ~PlayerController(); + + void _init(); + + void _ready(); + Dictionary get_init_info(); + void mp_init(Dictionary init_info); + void set_phys_transform(Transform trfrm, Vector3 lvel); + void _process(float _delta); + void initiate_use(); + void set_net_owner(int owner_id); + void deselect_character(); + void take_control_of_machine(RigidBody *slave_machine); + void lose_machine(); + void _physics_process(float delta); + bool on_floor_test(); + void _integrate_forces(PhysicsDirectBodyState *state); + void walk(float _delta); + void jump(); + void swim(float _delta); + void enter_water(); + void exit_water(); + void mount_ladder(Spatial *target_ladder); + void climb_ladder(float delta); + void leave_ladder(); + void damage(int dmg_amt, String _type, Array shooter, String extra); + void remove_dead_character(); + void net_apply_impulse(Vector3 impulse_v); +}; + +} +#endif diff --git a/src/playercontroller.cpp b/src/playercontroller.cpp deleted file mode 100644 index af8aa5a..0000000 --- a/src/playercontroller.cpp +++ /dev/null @@ -1,315 +0,0 @@ -#include "playercontroller.h" - -using namespace godot; - -PlayerController::PlayerController () { } -PlayerController::~PlayerController () { } - -void PlayerController::_register_methods() { - register_method("_ready", &PlayerController::_ready); - register_method("get_init_info", &PlayerController::get_init_info); - register_method("mp_init", &PlayerController::mp_init); - register_method("set_phys_transform", &PlayerController::set_phys_transform, GODOT_METHOD_RPC_MODE_REMOTE); - register_method("_process", &PlayerController::_process); - register_method("initiate_use", &PlayerController::initiate_use); - register_method("set_net_owner", &PlayerController::set_net_owner, GODOT_METHOD_RPC_MODE_REMOTESYNC); - register_method("deselect_character", &PlayerController::deselect_character); - register_method("take_control_of_machine", &PlayerController::take_control_of_machine); - register_method("lose_machine", &PlayerController::lose_machine); - register_method("_physics_process", &PlayerController::_physics_process); - register_method("on_floor_test", &PlayerController::on_floor_test); - register_method("_integrate_forces", &PlayerController::_integrate_forces); - register_method("walk", &PlayerController::walk); - register_method("jump", &PlayerController::jump); - register_method("swim", &PlayerController::swim); - register_method("enter_water", &PlayerController::enter_water); - register_method("exit_water", &PlayerController::exit_water); - register_method("mount_ladder", &PlayerController::mount_ladder); - register_method("climb_ladder", &PlayerController::climb_ladder); - register_method("leave_ladder", &PlayerController::leave_ladder); - register_method("damage", &PlayerController::damage, GODOT_METHOD_RPC_MODE_REMOTESYNC); - register_method("remove_dead_character", &PlayerController::remove_dead_character, GODOT_METHOD_RPC_MODE_REMOTESYNC); - register_method("net_apply_impulse", &PlayerController::net_apply_impulse, GODOT_METHOD_RPC_MODE_REMOTESYNC); - - register_property("team", &PlayerController::team, String("RED")); - register_property("health", &PlayerController::health, int(100)); - register_property("mouse_sensitivity", &PlayerController::mouse_sensitivity, float(12.0)); - register_property("FOV", &PlayerController::FOV, float(90.0)); - register_property("jump_height", &PlayerController::jump_height, float(300.0)); - register_property("is_player", &PlayerController::is_player, bool(false)); - register_property("walk_speed", &PlayerController::walk_speed, float(5.0)); -} - -void PlayerController::_init() { - weapon = nullptr; - world = nullptr; - mouse_axis = Vector2::ZERO; - velocity = Vector3::ZERO; - direction = Vector3::ZERO; - move_axis = Vector2::ZERO; - floorspeed = Vector3::ZERO; - jumping = false; - can_jump = true; - FLOOR_MAX_ANGLE = deg2rad(46.0); - in_water = false; - swim_speed = 450.0; - climb_speed = 5.0; - controlling_machine = false; - machine = nullptr; - ladder_m = nullptr; - player_state = nullptr; - is_on_floor = false; - floor_normal = Vector3::UP; - acceleration = 80.0; - c_friction = 4.0; - air_control = 0.3; -} - -void PlayerController::_ready() { - head = get_node(NodePath("Neck/Head")); - neck = get_node(NodePath("Neck")); - useray = get_node(NodePath("Neck/Head/UseRay")); - nametag = get_node(NodePath("Nametag")); - nav = get_node(NodePath("NavigationAgent")); - weapon = (Node *)ResourceLoader::get_singleton()->load("res://scenes/weapons/w_Rockets.tscn")->instance() - add_child(weapon) - world = get_tree()->get_root()->get_node("GAMEWORLD") -} - -Dictionary PlayerController::get_init_info() { - return Dictionary::make("linear_velocity", get_linear_velocity(), "angular_velocity", get_angular_velocity(), "controlling_machine", controlling_machine, "team", team, "health", health, "nametag", get_node("Nametag")->get_text()); -} - -void PlayerController::mp_init(Dictionary init_info) { - for(int i = 0; i < init_info.keys().size(); i++) - set(init_info.keys()[i], init_info[init_info.keys()[i]]); - nametag->set_text(init_info["nametag"]); -} - -void PlayerController::set_phys_transform(Transform trfrm, Vector3 lvel) { - set_transform(trfrm); - set_linear_velocity(lvel); -} - -void PlayerController::_process(float _delta) { - const Input *input_singleton = Input::get_singleton(); - if(is_player && !world->call("is_chatting_f")){ - if(input_singleton->is_action_just_pressed("use")) - initiate_use(); - if(controlling_machine) { - if(input_singleton->is_action_just_pressed("fire"))machine->call("attack1"); - if(input_singleton->is_action_just_pressed("fire2"))machine->call("attack2"); - } -} - -void PlayerController::initiate_use() { - if(controlling_machine){machine->call("relinquish_control"); return; } - if(ladder_m != nullptr) { leave_ladder(); return; } - if(useray->is_colliding()){ - const Node *area_c = useray->get_collider(); - if(area_c->get_name() == "SteerArea") - world.rpc_id(1, "_call_on_server", "_client_request_control_vehicle", {"id" : world->call("get_client_id"), "machine_path" : area_c->get_parent()->get_path(), "char_name" : get_name()}); - else if(area_c->get_name() == "LadderArea") - mount_ladder(area_c->get_parent()); - else if(area_c->get_name() == "TugArea")return; - else if(area_c->get_name() == "PickupArea")return; - } -} - -void PlayerController::set_net_owner(int owner_id) { - nametag->set_text(""); - set_network_master(owner_id); - if(owner_id != 1) - nametag->set_text(String(world->get_players_info()[owner_id][0])); - if(get_tree()->get_network_unique_id() != 1){ - if(owner_id == world->get_client_id()){ - nametag->set_visible(false); - world.player_char = self; - is_player = true; - world.cam.attach(this, "FIRSTPERSON", "./Neck/Head"); - }else{ - nametag->set_visible(true); - is_player = false; - } - world->get_node("HUD")->call("update_characters"); - } -} - -void PlayerController::deselect_character() { - if is_network_master(): - world.player_char = null - if(world->get_client_id() != 1) world.cam.attach(world, "STATIC", "./DEFAULTCAM") - rpc("set_net_owner", 1) -} - -void PlayerController::take_control_of_machine(RigidBody *slave_machine) { - machine = slave_machine; - controlling_machine = true; -} - -void PlayerController::lose_machine() { - if is_network_master()world.cam.attach(self, "FIRSTPERSON", "./Neck/Head"); - controlling_machine = false; - machine = nullptr; -} - -void PlayerController::_physics_process(float delta) { - if(is_network_master()) { - if (ladder_m != nullptr) - climb_ladder(delta); - else if( !on_floor_test() && in_water) - swim(delta); - else - walk(delta); - is_on_floor = false;// #reset whether is on floor in between frames - } -} - -bool PlayerController::on_floor_test() { - const RayCast *feet = get_node("Feet"); - if(feet->is_colliding()){ - is_on_floor = true; - floor_normal = Vector3::UP; - floorspeed = feet->get_collider()->has_method("get_linear_velocity") ? feet->get_collider()->get_linear_velocity() : Vector3::ZERO; - return true; - } - if(player_state){ - for(int i = 0;i< player_state->get_contact_count()) { - float contact_angle_from_up = Vector3::UP.angle_to(player_state->get_contact_local_normal(i)) - if(contact_angle_from_up < FLOOR_MAX_ANGLE) { - floor_normal = player_state->get_contact_local_normal(i); - is_on_floor = true; - return true; - } - } - } - return false; -} - -void PlayerController::_integrate_forces(PhysicsDirectBodyState *state) { - if(!is_network_master()) return; - player_state = state; - velocity = state->get_linear_velocity(); - for(int i=0; i < player_state->get_contact_count(); i++) { - float contact_angle_from_up = Vector3::UP.angle_to(player_state->get_contact_local_normal(i)); - if(contact_angle_from_up > FLOOR_MAX_ANGLE && !is_on_floor){ - set_friction(0); - break; - } - if(i == player_state.get_contact_count() - 1) - set_friction(1); - } - rpc("set_phys_transform", get_transform(), get_linear_velocity()); - if(get_global_transform().origin.y < -30) - rpc("damage", 500000, "drown", Array::make(1, String("Davy Jones")); -} - -void PlayerController::walk(float _delta) { -// # Input -// direction = Vector3() -// var aim: Basis = head.get_global_transform().basis -// direction += -move_axis.x * aim.z + move_axis.y * aim.x -// direction.y = 0 -// direction = direction.normalized() -// -// if floor_normal != Vector3.UP: direction = direction.rotated(floor_normal.cross(Vector3.UP).normalized(), Vector3.UP.angle_to(floor_normal)) -// -// # Jump -// if is_player and jumping and is_on_floor and can_jump: -// jump() -// -// #max walk speed -// var _speed = walk_speed -// var _temp_accel: float = acceleration -// var _cspeed = sqrt(pow(velocity.x-floorspeed.x,2)+pow(velocity.z-floorspeed.z,2)) -// -// if not is_on_floor: -// _temp_accel *= air_control -} - -void PlayerController::jump() { - can_jump = false; - apply_central_impulse(Vector3.UP*jump_height); - yield(get_tree().create_timer(0.05),"timeout"); - can_jump = true; -} - -void PlayerController::swim(float _delta) { -// #drag and buoyancy - add_central_force(Vector3.UP*weight*1.0); - add_central_force(-1*linear_velocity*100); -// #controls - Basis dir = head->get_global_transform().basis; - Vector3 m_dir = -move_axis.x * dir.z + move_axis.y * dir.x; - m_dir = m_dir.normalized(); - add_central_force(swim_speed*m_dir); - if(jumping) add_central_force(Vector3.UP*get_weight()*0.5); -} - -void PlayerController::enter_water() { - in_water = true; -} - -void PlayerController::exit_water() { - in_water = false; -} - -void PlayerController::mount_ladder(Spatial target_ladder) { -// var ladder_tracker = Spatial.new() -// ladder_tracker.name = name -// target_ladder.add_child(ladder_tracker) -// ladder_tracker.transform = target_ladder.bottom.transform -// -// ladder_tracker.global_transform.origin = target_ladder.get_nearest_point_to_route(global_transform.origin) -// look_at(global_transform.origin + target_ladder.global_transform.basis.x, target_ladder.global_transform.basis.y) -// -// ladder_m = ladder_tracker -// global_transform.origin = ladder_m.global_transform.origin -// global_transform.basis = ladder_m.global_transform.basis.orthonormalized() -// linear_velocity = Vector3.ZERO -// set_gravity_scale(0.0) -} - -void PlayerController::climb_ladder(float delta) { -// var new_ladder_pos = ladder_m.global_transform.origin + ladder_m.global_transform.basis.y.normalized() * move_axis.x * delta * climb_speed -// var prog = ladder_m.get_parent().get_climb_scalar(new_ladder_pos) -// if prog >= 0.0 and prog <= 1.0: -// ladder_m.global_transform.origin = new_ladder_pos -// global_transform.origin = ladder_m.global_transform.origin -// global_transform.basis = ladder_m.global_transform.basis.orthonormalized() -} - -void PlayerController::leave_ladder() { - if((ladder_m->get_parent()->get_node("TOP")->global_transform.origin - get_global_transform().origin).length_squared() < 0.01) - apply_central_impulse(-400*ladder_m->get_global_transform().basis.z); - global_transform.basis = world.global_transform.basis - set_gravity_scale(1.0); - ladder_m->queue_free(); - ladder_m = nullptr; -} - -void PlayerController::damage(int dmg_amt, String _type, Array shooter, String extra = ".") { - health -= dmg_amt; - if(health <= 0 && is_network_master()){ - if(shooter[0] != get_network_master() and shooter[0] != 1) world.rpc_id(shooter[0], "game_killsound"); - if(get_network_master() == 1) - world._call_on_server("_character_death", {"killer_id" : shooter[0], "killer" : shooter[1], "victim_mp_id" : get_network_master(), "victim" : name, "extra" : extra}); - else - world.rpc_id(1, "_call_on_server", "_character_death", {"killer_id" : shooter[0], "killer" : shooter[1], "victim_mp_id" : get_network_master(), "victim" : name, "extra" : extra}); - } else if( is_network_master()) - if(shooter[0] != get_network_master() and shooter[0] != 1) world.rpc_id(shooter[0], "game_hitsound"); - } -} - -void PlayerController::remove_dead_character() { - if(is_network_master() && machine != nullptr) - machine->call("relinquish_control"); - deselect_character(); - queue_free(); -} - -void PlayerController::net_apply_impulse(Vector3 impulse_v) { - apply_central_impulse(impulse_v); -} - - diff --git a/src/playercontroller.h b/src/playercontroller.h deleted file mode 100644 index b373db8..0000000 --- a/src/playercontroller.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef PLAYERCONTROLLER_H -#define PLAYERCONTROLLER_H - -#include -#include - -namespace godot { - -class PlayerController : public RigidBody { - GODOT_CLASS(PlayerController, RigidBody) - -private: - String team; - int health; - Node *weapon; - Spatial *world; - float mouse_sensitivity; - float FOV; - Vector2 mouse_axis; - Spatial *head; - Spatial *neck; - RayCast *useray; - Label3D *nametag; - Vector3 velocity; - Vector3 direction; - Vector3 move_axis; - Vector3 floorspeed; - bool jumping; - bool can_jump; - NavigationAgent nav; - float FLOOR_MAX_ANGLE; - float jump_height; - bool in_water; - float swim_speed; - float climb_speed; - bool controlling_machine; - RigidBody *machine; - bool is_player; - Spatial *ladder_m; - PhysicsDirectBodyState *player_state; - bool is_on_floor; - Vector3 floor_normal; - float acceleration; - float walk_speed; - float c_friction; - float air_control; - - -public: - static void _register_methods(); - - PlayerController(); - ~PlayerController(); - - void _init(); - - void _ready(); - Dictionary get_init_info(); - void mp_init(Dictionary init_info); - void set_phys_transform(Transform trfrm, Vector3 lvel); - void _process(float _delta); - void initiate_use(); - void set_net_owner(int owner_id); - void deselect_character(); - void take_control_of_machine(RigidBody slave_machine); - void lose_machine(); - void _physics_process(float delta); - bool on_floor_test(); - void _integrate_forces(PhysicsDirectBodyState *state); - void walk(float _delta); - void jump(); - void swim(float _delta); - void enter_water(); - void exit_water(); - void mount_ladder(Spatial *target_ladder); - void climb_ladder(float delta); - void leave_ladder(); - void damage(int dmg_amt, String _type, Array shooter, String extra); - void remove_dead_character(); - void net_apply_impulse(Vector3 impulse_v); - -}; - -} -#endif -- cgit v1.2.3