diff options
-rw-r--r-- | .gitattributes | 1 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | cargo | 0 | ||||
-rw-r--r-- | godot/native/BasicDie.gdns | 8 | ||||
-rw-r--r-- | godot/project.godot | 38 | ||||
-rw-r--r-- | godot/scenes/Game.tscn | 12 | ||||
-rw-r--r-- | godot/scenes/levels/test_scene/TestScene.tscn | 11 | ||||
-rw-r--r-- | godot/scenes/levels/test_scene_movement/Floor.tscn | 22 | ||||
-rw-r--r-- | godot/scenes/levels/test_scene_movement/TestSceneMovement.tscn | 30 | ||||
-rw-r--r-- | godot/scenes/levels/test_scene_movement/Wall.tscn | 23 | ||||
-rw-r--r-- | godot/scenes/objects/Camera.tscn | 10 | ||||
-rw-r--r-- | godot/scenes/objects/Player.tscn | 20 | ||||
-rw-r--r-- | lib/x86_64-pc-windows-msvc/code_with_your_friends2022.dll | bin | 0 -> 482304 bytes | |||
-rwxr-xr-x | lib/x86_64-unknown-linux-gnu/libcode_with_your_friends2022.so | bin | 25714184 -> 29349984 bytes | |||
-rw-r--r-- | rust/src/basic_die.rs | 321 | ||||
-rw-r--r-- | rust/src/game.rs | 4 | ||||
-rw-r--r-- | rust/src/lib.rs | 4 |
17 files changed, 484 insertions, 21 deletions
diff --git a/.gitattributes b/.gitattributes index f37160a..24d1f8f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11,7 +11,6 @@ thirdparty/* linguist-vendored *.png filter=lfs diff=lfs merge=lfs -text *.ttf filter=lfs diff=lfs merge=lfs -text *.tza filter=lfs diff=lfs merge=lfs -text -*.godot filter=lfs diff=lfs merge=lfs -text *.material filter=lfs diff=lfs merge=lfs -text *.import filter=lfs diff=lfs merge=lfs -text *.mp3 filter=lfs diff=lfs merge=lfs -text @@ -34,3 +34,4 @@ rust/Cargo.lock rust/debug/ target/ tramp +make.bat diff --git a/godot/native/BasicDie.gdns b/godot/native/BasicDie.gdns new file mode 100644 index 0000000..ab5d534 --- /dev/null +++ b/godot/native/BasicDie.gdns @@ -0,0 +1,8 @@ +[gd_resource type="NativeScript" load_steps=2 format=2] + +[ext_resource path="res://native/game.gdnlib" type="GDNativeLibrary" id=1] + +[resource] +resource_name = "BasicDie" +class_name = "BasicDie" +library = ExtResource( 1 ) diff --git a/godot/project.godot b/godot/project.godot index 199576e..0191f34 100644 --- a/godot/project.godot +++ b/godot/project.godot @@ -1,3 +1,35 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:51efcd6bc26f0e3caf847b2f9c7249d1d9144f428911fc2615a6433d07b3a5a6 -size 529 +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=4 + +_global_script_classes=[ ] +_global_script_class_icons={ +} + +[application] + +config/name="code-with-your-friends2022" +run/main_scene="res://scenes/Game.tscn" +config/icon="res://assets/godot-ferris-32x32.png" + +[gdnative] + +singletons=[ ] + +[input] + +mouse_btn_left={ +"deadzone": 0.5, +"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null) + ] +} + +[rendering] + +environment/default_environment="res://default_env.tres" diff --git a/godot/scenes/Game.tscn b/godot/scenes/Game.tscn index 641f17b..72fef4e 100644 --- a/godot/scenes/Game.tscn +++ b/godot/scenes/Game.tscn @@ -1,3 +1,9 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fc9007950d7925a994a0292c4879f61a16d8ef7a01bc52bd38e6472489e80e3e -size 561 +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://native/Game.gdns" type="Script" id=1] +[ext_resource path="res://scenes/levels/test_scene_movement/TestSceneMovement.tscn" type="PackedScene" id=2] + +[node name="Game" type="Spatial"] +script = ExtResource( 1 ) + +[node name="TestScene" parent="." instance=ExtResource( 2 )] diff --git a/godot/scenes/levels/test_scene/TestScene.tscn b/godot/scenes/levels/test_scene/TestScene.tscn deleted file mode 100644 index ed981f8..0000000 --- a/godot/scenes/levels/test_scene/TestScene.tscn +++ /dev/null @@ -1,11 +0,0 @@ -[gd_scene load_steps=3 format=2] - -[ext_resource path="res://scenes/levels/test_scene/Floor.tscn" type="PackedScene" id=1] -[ext_resource path="res://scenes/W8.tscn" type="PackedScene" id=2] - -[node name="TestScene" type="Spatial"] - -[node name="Floor" parent="." instance=ExtResource( 1 )] - -[node name="RigidBody" parent="." instance=ExtResource( 2 )] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0339947, 2.91518, -1.40456 ) diff --git a/godot/scenes/levels/test_scene_movement/Floor.tscn b/godot/scenes/levels/test_scene_movement/Floor.tscn new file mode 100644 index 0000000..f8970a7 --- /dev/null +++ b/godot/scenes/levels/test_scene_movement/Floor.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=5 format=2] + +[ext_resource path="res://assets/textures/grass-texture-26.jpg" type="Texture" id=1] + +[sub_resource type="CubeMesh" id=1] + +[sub_resource type="SpatialMaterial" id=3] +albedo_texture = ExtResource( 1 ) + +[sub_resource type="BoxShape" id=2] + +[node name="StaticBody" type="StaticBody"] + +[node name="MeshInstance" type="MeshInstance" parent="."] +transform = Transform( 10, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0 ) +mesh = SubResource( 1 ) +skeleton = NodePath("../CollisionShape") +material/0 = SubResource( 3 ) + +[node name="CollisionShape" type="CollisionShape" parent="."] +transform = Transform( 10, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0 ) +shape = SubResource( 2 ) diff --git a/godot/scenes/levels/test_scene_movement/TestSceneMovement.tscn b/godot/scenes/levels/test_scene_movement/TestSceneMovement.tscn new file mode 100644 index 0000000..d23236b --- /dev/null +++ b/godot/scenes/levels/test_scene_movement/TestSceneMovement.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://scenes/levels/test_scene_uuuhhh/Wall.tscn" type="PackedScene" id=1] +[ext_resource path="res://scenes/levels/test_scene_uuuhhh/Floor.tscn" type="PackedScene" id=2] +[ext_resource path="res://scenes/objects/Player.tscn" type="PackedScene" id=3] + +[node name="TestScene" type="Spatial"] + +[node name="Floor" parent="." instance=ExtResource( 2 )] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0290833, -0.981747, 0.00208664 ) + +[node name="Floor2" parent="." instance=ExtResource( 2 )] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, -20 ) + +[node name="Floor3" parent="." instance=ExtResource( 2 )] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 20, -1, 0 ) + +[node name="Floor4" parent="." instance=ExtResource( 2 )] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 20, -1, -20 ) + +[node name="Floor5" parent="." instance=ExtResource( 2 )] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 40, -1, 0 ) + +[node name="Floor6" parent="." instance=ExtResource( 2 )] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 40, -1, -20 ) + +[node name="Wall" parent="." instance=ExtResource( 1 )] +transform = Transform( 0.766044, 0, 0.642788, 0, 2, 0, -0.642788, 0, 0.766044, 19.47, 0, -14 ) + +[node name="PlayerRoot" parent="." instance=ExtResource( 3 )] diff --git a/godot/scenes/levels/test_scene_movement/Wall.tscn b/godot/scenes/levels/test_scene_movement/Wall.tscn new file mode 100644 index 0000000..e3afe23 --- /dev/null +++ b/godot/scenes/levels/test_scene_movement/Wall.tscn @@ -0,0 +1,23 @@ +[gd_scene load_steps=5 format=2] + +[ext_resource path="res://assets/textures/sandstone-brick-wall-texture.jpg" type="Texture" id=1] + +[sub_resource type="CubeMesh" id=1] + +[sub_resource type="SpatialMaterial" id=2] +albedo_texture = ExtResource( 1 ) + +[sub_resource type="ConvexPolygonShape" id=3] +points = PoolVector3Array( 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1 ) + +[node name="StaticBody" type="StaticBody"] + +[node name="MeshInstance" type="MeshInstance" parent="."] +transform = Transform( 0.3, 0, 0, 0, 1, 0, 0, 0, 5, 0, 1, 0 ) +mesh = SubResource( 1 ) +skeleton = NodePath("") +material/0 = SubResource( 2 ) + +[node name="CollisionShape" type="CollisionShape" parent="."] +transform = Transform( 0.3, 0, 0, 0, 1, 0, 0, 0, 5, 0, 1, 0 ) +shape = SubResource( 3 ) diff --git a/godot/scenes/objects/Camera.tscn b/godot/scenes/objects/Camera.tscn new file mode 100644 index 0000000..1c13dd0 --- /dev/null +++ b/godot/scenes/objects/Camera.tscn @@ -0,0 +1,10 @@ +[gd_scene format=2] + +[node name="CameraRoot" type="Spatial"] + +[node name="CameraArmHorizontal" type="Spatial" parent="."] + +[node name="CameraArmVertical" type="Spatial" parent="CameraArmHorizontal"] + +[node name="Camera" type="Camera" parent="CameraArmHorizontal/CameraArmVertical"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10 ) diff --git a/godot/scenes/objects/Player.tscn b/godot/scenes/objects/Player.tscn new file mode 100644 index 0000000..aeb8f51 --- /dev/null +++ b/godot/scenes/objects/Player.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://scenes/objects/W8.tscn" type="PackedScene" id=1] +[ext_resource path="res://scenes/objects/Camera.tscn" type="PackedScene" id=2] +[ext_resource path="res://native/BasicDie.gdns" type="Script" id=3] + +[node name="PlayerRoot" type="Spatial"] +script = ExtResource( 3 ) +camera/camera_clamp = Vector2( 0, -1.3 ) +shooting/max_force = 30.0 +shooting/up_angle = 0.3 +shooting/stopping_velocity = 0.003 +input/camera_mouse_sensitivity = Vector2( 0.003, 0.002 ) +input/shoot_sensitivity = 0.1 + +[node name="W8" parent="." instance=ExtResource( 1 )] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 0 ) + +[node name="Camera" parent="." instance=ExtResource( 2 )] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0 ) diff --git a/lib/x86_64-pc-windows-msvc/code_with_your_friends2022.dll b/lib/x86_64-pc-windows-msvc/code_with_your_friends2022.dll Binary files differnew file mode 100644 index 0000000..115f39f --- /dev/null +++ b/lib/x86_64-pc-windows-msvc/code_with_your_friends2022.dll diff --git a/lib/x86_64-unknown-linux-gnu/libcode_with_your_friends2022.so b/lib/x86_64-unknown-linux-gnu/libcode_with_your_friends2022.so Binary files differindex 14b6058..03ade02 100755 --- a/lib/x86_64-unknown-linux-gnu/libcode_with_your_friends2022.so +++ b/lib/x86_64-unknown-linux-gnu/libcode_with_your_friends2022.so diff --git a/rust/src/basic_die.rs b/rust/src/basic_die.rs new file mode 100644 index 0000000..2a61197 --- /dev/null +++ b/rust/src/basic_die.rs @@ -0,0 +1,321 @@ +use std::borrow::Borrow; +use gdnative::api::*; +use gdnative::prelude::*; + +/// the input state for the player +enum InputState { + Default, + Shooting, + Moving +} + + +type SpatialRef = Option<Ref<Spatial>>; + +/// the basic die used by the player +#[derive(NativeClass)] +#[inherit(Spatial)] +#[register_with(Self::register_builder)] +pub struct BasicDie { + #[property(path="camera/camera_clamp")] + camera_clamp: Vector2, + #[property(path="shooting/max_force")] + max_force: f32, + #[property(path="shooting/up_angle")] + up_angle: f32, + #[property(path="shooting/stopping_velocity")] + stopping_velocity: f32, + #[property(path="shooting/stopping_min_milliseconds")] + stopping_min_ms: i64, + #[property(path="input/camera_mouse_sensitivity")] + mouse_sensitivity: Vector2, + #[property(path="input/shoot_sensitivity")] + shoot_sensitivity: f32, + + input_state: InputState, + current_force: f32, + last_shot_time: i64, + + action_shooting: String, + + node_die: SpatialRef, + + node_camera_root: SpatialRef, + node_camera_arm_horizontal: SpatialRef, + node_camera_arm_vertical: SpatialRef, + node_camera: SpatialRef, +} + +#[methods] +impl BasicDie { + // Register the builder for methods, properties and/or signals. + fn register_builder(_builder: &ClassBuilder<Self>) { + godot_print!("BasicDie builder is registered!"); + } + + fn new(_owner: &Spatial) -> Self { + BasicDie { + camera_clamp: Vector2 { x: 0.0, y: 0.0 }, + max_force: 0.0, + up_angle: 5.0, + stopping_velocity: 0.0, + stopping_min_ms: 1000, + mouse_sensitivity: Vector2 { x: 1.0, y: 1.0 }, + shoot_sensitivity: 1.0, + + input_state: InputState::Default, + current_force: 0.0, + last_shot_time: 0, + + action_shooting: String::from("mouse_btn_left"), + + node_die: None, + + node_camera_root: None, + node_camera_arm_horizontal: None, + node_camera_arm_vertical: None, + node_camera: None, + } + } + + #[export] + unsafe fn _ready(&mut self, owner: &Spatial) { + + Input::godot_singleton().set_mouse_mode(Input::MOUSE_MODE_CAPTURED); + owner.set_physics_process(true); + + self.last_shot_time = OS::godot_singleton().get_ticks_msec(); + + let search_node = | parent: &SpatialRef, name: String | { + let parent_node = match parent { + Some(node) => node.assume_safe().as_ref(), + None => owner + }; + match parent_node.get_node(NodePath::from_str(&name)) { + None => { godot_warn!("Could not find {}.", name); None }, + Some(node) => { + let save_node = node.assume_safe(); + match save_node.cast::<Spatial>() { + None => { godot_warn!("{} was not of type 'Spatial'.", name); None }, + Some(casted) => Some(casted.claim()) + } + } + } + }; + + // look for the camera and arm nodes + self.node_camera_root = search_node(&None, String::from("Camera")); + self.node_camera_arm_horizontal = search_node(&self.node_camera_root, String::from("CameraArmHorizontal")); + self.node_camera_arm_vertical = search_node(&self.node_camera_arm_horizontal, String::from("CameraArmVertical")); + self.node_camera = search_node(&self.node_camera_arm_vertical, String::from("Camera")); + + godot_print!("{:?}", self.node_camera_root); + godot_print!("{:?}", self.node_camera_arm_horizontal); + godot_print!("{:?}", self.node_camera_arm_vertical); + godot_print!("{:?}", self.node_camera); + + self.node_die = search_node(&None, String::from("W8")); + + godot_print!("Player is ready"); + } + + #[export] + unsafe fn _physics_process(&mut self, _owner: &Spatial, _delta: f64) { + + let die = match self.node_die { + None => { godot_warn!("No W8 assigned."); return; }, + Some(node) => match node.assume_safe().cast::<RigidBody>() { + None => { godot_warn!("W8 is not a RigidBody."); return; }, + Some(rb) => rb + } + }; + + // let the cam follow the die + match self.node_camera_root { + None => { godot_warn!("No W8 assigned."); }, + Some(cam) => { + cam.assume_safe().set_translation(die.translation()); + } + } + + // detect if the die stops moving + let delta_ms = OS::godot_singleton().get_ticks_msec() - self.last_shot_time; + if matches!(self.input_state, InputState::Moving) + && (delta_ms > self.stopping_min_ms) { + + // check if the velocity is less than the threshold and change input state in that case + let current_vel = die.linear_velocity().length(); + if current_vel <= self.stopping_velocity { + self.input_state = InputState::Default; + godot_print!("Die stopped moving at velocity {} after {} ms", current_vel, delta_ms); + } + }; + } + + #[export] + unsafe fn _input(&mut self, _owner: &Spatial, event: Ref<InputEvent>) { + + self.general_input(event.borrow()); + + match self.input_state { + InputState::Default => self.default_input(event), + InputState::Shooting => self.shooting_input(event), + InputState::Moving => self.moving_input(event), + } + } + + /// this input method will always be called, regardless of the input state + unsafe fn general_input(&mut self, event: &Ref<InputEvent>) { + let save_event = event.assume_safe(); + + // rotate camera horizontally + let mouse_event = save_event.cast::<InputEventMouseMotion>(); // get the input as mouse input + match mouse_event { + Some(motion_event) => { + let x_mov = motion_event.relative().x * self.mouse_sensitivity.x; + self.rotate_cam_horizontal(x_mov); + }, + _ => {} + } + + let key_event = save_event.cast::<InputEventKey>(); + match key_event { + Some(key_event) => { + if key_event.scancode() == GlobalConstants::KEY_ESCAPE { + Input::godot_singleton().set_mouse_mode(Input::MOUSE_MODE_VISIBLE); + } + }, + _ => {} + } + } + + /// this input method will be called when looking around, before taking a shot + unsafe fn default_input(&mut self, event: Ref<InputEvent>) { + let save_event = event.assume_safe(); + + // left mouse button was pressed => switch to shooting mode + if save_event.is_action_pressed(GodotString::from_str(&self.action_shooting), false, false) { + godot_print!("mouse_button, switching to shooting mode"); + self.input_state = InputState::Shooting; + return; + } + + // rotate camera vertically + let mouse_event = save_event.cast::<InputEventMouseMotion>(); // get the input as mouse input + match mouse_event { + Some(motion_event) => { + let y_mov = -motion_event.relative().y * self.mouse_sensitivity.y; + self.rotate_cam_vertical(y_mov); + }, + _ => {} + }; + } + + /// this input method will be called when player is currently taking a shot + unsafe fn shooting_input(&mut self, event: Ref<InputEvent>) { + let save_event = event.assume_safe(); + + // mouse released, shoot + if save_event.is_action_released(GodotString::from_str(&self.action_shooting), false) { + self.input_state = InputState::Moving; + self.shoot(); + self.current_force = 0.0; + return; + } + + // charge shot with vertical mouse movement + let mouse_event = save_event.cast::<InputEventMouseMotion>(); // get the input as mouse input + match mouse_event { + Some(motion_event) => { + let y_mov = motion_event.relative().y * self.shoot_sensitivity; + self.current_force = match self.current_force + y_mov { + x if x < 0.0 => 0.0, + x if x > self.max_force => self.max_force, + x => x + }; + + godot_print!("current force: {}", self.current_force); + }, + _ => {} + }; + } + + /// this input method will be called when player is moving + unsafe fn moving_input(&mut self, event: Ref<InputEvent>) { + let save_event = event.assume_safe(); + + // rotate camera vertically + let mouse_event = save_event.cast::<InputEventMouseMotion>(); // get the input as mouse input + match mouse_event { + Some(motion_event) => { + let y_mov = motion_event.relative().y * self.mouse_sensitivity.y; + self.rotate_cam_vertical(y_mov); + }, + _ => {} + }; + } + + unsafe fn rotate_cam_horizontal(&mut self, input: f32) { + // make sure the arm exists + match self.node_camera_arm_horizontal { + Some(arm) => { + // rotate the horizontal camera arm + let save_arm = arm.assume_safe(); + save_arm.rotate_object_local(Vector3 {x: 0.0, y: 1.0, z: 0.0}, input as f64) + }, + _ => godot_warn!("No horizontal camera arm assigned.") + } + } + + unsafe fn rotate_cam_vertical(&mut self, input: f32) { + // make sure the camera arm actually exists + match self.node_camera_arm_vertical { + Some(arm) => { + // check for the current rotation + let save_arm = arm.assume_safe(); + let current_rot = save_arm.rotation(); + + // clamp the rotation + if current_rot.x + input > self.camera_clamp.x || current_rot.x + input <= self.camera_clamp.y { + return; + } + + // actually rotate if possible + let save_arm = arm.assume_safe(); + save_arm.rotate_object_local(Vector3 {x: 1.0, y: 0.0, z: 0.0}, input as f64) + }, + _ => godot_warn!("No vertical camera arm assigned") + } + } + + unsafe fn shoot(&mut self) { + + // make sure the camera actually exists + let impulse_dir = match self.node_camera { + None => { godot_warn!("No camera assigned!"); return; }, + Some(cam) => { + // get the forward vector of the camera setting the up angle to the defined value in the editor + let mut forward_vector = -cam.assume_safe().global_transform().basis.c().normalized(); + forward_vector.y = self.up_angle; + + // calculate the impulse force + forward_vector.normalized() * self.current_force + } + }; + + // get the die + let die = match self.node_die { + None => { godot_warn!("No W8 assigned."); return; }, + Some(node) => + match node.assume_safe().cast::<RigidBody>() { + None => { godot_warn!("W8 is not a RigidBody."); return; }, + Some(rb) => rb + } + }; + + // actually add the force + die.apply_impulse(die.transform().origin, impulse_dir); + + self.last_shot_time = OS::godot_singleton().get_ticks_msec(); + } +} diff --git a/rust/src/game.rs b/rust/src/game.rs index ece5a54..61b23ed 100644 --- a/rust/src/game.rs +++ b/rust/src/game.rs @@ -40,7 +40,5 @@ impl Game { // This function will be called in every frame #[export] - unsafe fn _process(&self, _owner: &Spatial, delta: f64) { - godot_print!("Inside {} _process(), delta is {}", self.name, delta); - } + unsafe fn _process(&self, _owner: &Spatial, _delta: f64) { } } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 534955f..30f4f2a 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -5,6 +5,8 @@ mod buff_phase; mod buff_trait; mod buff_ball; mod buff_extra; +mod test; +mod basic_die; use gdnative::prelude::{godot_init, InitHandle}; @@ -12,6 +14,8 @@ use gdnative::prelude::{godot_init, InitHandle}; fn init(handle: InitHandle) { handle.add_class::<game::Game>(); handle.add_class::<spinning_cube::SpinningCube>(); + handle.add_class::<test::SpinningCubeReverse>(); + handle.add_class::<basic_die::BasicDie>(); } // macros that create the entry-points of the dynamic library. |