From 1d347e770fddcdd051890cdf070fd2779ab113bf Mon Sep 17 00:00:00 2001 From: Anson Bridges Date: Mon, 19 Sep 2022 17:44:22 -0400 Subject: problems: player controller perf, boat perf, NAVSERVER PERF --- src/playercontroller.cpp | 313 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 src/playercontroller.cpp (limited to 'src/playercontroller.cpp') diff --git a/src/playercontroller.cpp b/src/playercontroller.cpp new file mode 100644 index 0000000..edf85be --- /dev/null +++ b/src/playercontroller.cpp @@ -0,0 +1,313 @@ +#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")); + 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]]); + get_node("Nametag")->set_text(init_info["nametag"]); +} + +void PlayerController::set_phys_transform(Transform trfrm, Vector3 lvel) { + set_transform(trfrm); + set_linear_velocity(lvel); +} + +PlayerController::_process(float _delta) { +// if is_player and !world.is_chatting: +// if Input.is_action_just_pressed("use"): +// initiate_use() +} + +void PlayerController::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 +} + +void PlayerController::set_net_owner(int owner_id) { +// $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() +} + +void PlayerController::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) +} + +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; +} + +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, "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().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 +} + +void PlayerController::damage(int dmg_amt, String _type, Array shooter, String extra = ".") { + 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") +} + +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); +} + + -- cgit v1.2.3