diff options
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | cargo | 0 | ||||
| -rw-r--r-- | godot/native/BasicDie.gdns | 8 | ||||
| -rw-r--r-- | godot/project.godot | 12 | ||||
| -rw-r--r-- | godot/scenes/Game.tscn | 5 | ||||
| -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 | 31 | ||||
| -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 | 21 | ||||
| -rw-r--r-- | godot/scenes/objects/W8.tscn | 21 | ||||
| -rw-r--r-- | lib/x86_64-pc-windows-msvc/code_with_your_friends2022.dll | bin | 397824 -> 482304 bytes | |||
| -rwxr-xr-x | lib/x86_64-unknown-linux-gnu/libcode_with_your_friends2022.so | bin | 25714184 -> 30387968 bytes | |||
| -rw-r--r-- | rust/src/basic_die.rs | 376 | ||||
| -rw-r--r-- | rust/src/buff_ball.rs | 91 | ||||
| -rw-r--r-- | rust/src/buff_bounce.rs | 52 | ||||
| -rw-r--r-- | rust/src/buff_extra.rs | 4 | ||||
| -rw-r--r-- | rust/src/buff_phase.rs | 27 | ||||
| -rw-r--r-- | rust/src/game.rs | 3 | ||||
| -rw-r--r-- | rust/src/lib.rs | 4 | 
21 files changed, 602 insertions, 120 deletions
| @@ -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 a8f6586..0191f34 100644 --- a/godot/project.godot +++ b/godot/project.godot @@ -8,6 +8,10 @@  config_version=4 +_global_script_classes=[  ] +_global_script_class_icons={ +} +  [application]  config/name="code-with-your-friends2022" @@ -18,6 +22,14 @@ config/icon="res://assets/godot-ferris-32x32.png"  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 68704bb..6d09370 100644 --- a/godot/scenes/Game.tscn +++ b/godot/scenes/Game.tscn @@ -10,6 +10,10 @@  [sub_resource type="CubeMesh" id=2]  [sub_resource type="SphereMesh" id=3] +[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 ) @@ -47,3 +51,4 @@ mesh = SubResource( 3 )  material/0 = null  [connection signal="body_entered" from="Area2" to="Area2" method="_on_Area2_body_entered"] +[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..d1c08e3 --- /dev/null +++ b/godot/scenes/levels/test_scene_movement/TestSceneMovement.tscn @@ -0,0 +1,31 @@ +[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 )] +input/current_buff_index = 1 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..8cfdd6e --- /dev/null +++ b/godot/scenes/objects/Player.tscn @@ -0,0 +1,21 @@ +[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 +input/current_buff_index = 5 + +[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/godot/scenes/objects/W8.tscn b/godot/scenes/objects/W8.tscn index 91f58eb..8766011 100644 --- a/godot/scenes/objects/W8.tscn +++ b/godot/scenes/objects/W8.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=6 format=2]  [ext_resource path="res://assets/game_objects/W8baseColor_Mat.material" type="Material" id=2] @@ -20,12 +20,27 @@ surfaces/0 = {  [sub_resource type="ConvexPolygonShape" id=2]  points = PoolVector3Array( -0.0850063, -0.879389, -0.0282584, 0.0288993, 0.929375, 0.0289349, 0.0288993, 0.929375, -0.0289349, 0.929367, -0.0289314, 0.0289314, -0.0289784, -0.0289338, 0.929338, -0.929369, 0.028929, 0.028929, 0.0288993, -0.0289349, -0.929375, 0.0288993, -0.929375, 0.0289349, -0.0850063, 0.0282584, -0.879389, 0.0282247, 0.084959, 0.87945, 0.857489, 0.056933, -0.0855785, -0.879454, -0.0849424, 0.0282549, 0.0570775, -0.885814, -0.0571088, 0.0570775, -0.0571088, 0.885814, -0.0571532, 0.885743, -0.0571043, -0.0571532, 0.885743, 0.0571043, 0.0570775, 0.0571088, -0.885814, -0.885806, -0.057097, -0.057097, 0.879446, 0.0849494, 0.0282572, 0.857335, -0.0571018, -0.0855632, -0.0571532, 0.0571043, 0.885743, -0.0571532, -0.885743, 0.0571043, -0.885806, 0.057097, -0.057097, -0.0571532, -0.0571043, -0.885743, 0.0570775, 0.0571088, 0.885814, -0.0571532, -0.885743, -0.0571043, -0.0571532, 0.0571043, -0.885743, 0.0570775, -0.885814, 0.0571088, 0.0570775, 0.885814, 0.0571088, -0.0571532, -0.0571043, 0.885743, -0.885806, 0.057097, 0.057097, 0.0570775, 0.885814, -0.0571088, 0.0570775, -0.0571088, -0.885814, 0.857335, -0.0571018, 0.0855632, -0.885806, -0.057097, 0.057097, 0.857489, 0.056933, 0.0855785, 0.929425, 0.0287513, -0.0289333, 0.929367, -0.0289314, -0.0289314, -0.0289784, 0.929338, -0.0289338, 0.0288993, 0.0289349, -0.929375, -0.929369, -0.028929, -0.028929, -0.0283039, -0.87942, -0.0849561, 0.084933, 0.0282608, 0.879461, -0.0289784, 0.929338, 0.0289338, -0.0289784, -0.0289338, -0.929338, -0.0289784, 0.0289338, 0.929338, 0.0288993, -0.0289349, 0.929375, 0.0288993, -0.929375, -0.0289349, -0.0289784, -0.929338, 0.0289338, -0.929369, 0.028929, -0.028929, -0.0283039, 0.0849561, -0.87942, -0.879454, -0.0282549, 0.0849424, 0.879512, 0.0280816, 0.0849558, 0.879446, -0.0849494, -0.0282572, -0.0282988, -0.822574, 0.141805, 0.17021, 0.0280745, -0.794261, -0.879454, 0.0849424, -0.0282549, -0.0283039, 0.87942, 0.0849561, 0.0282247, 0.87945, -0.084959, 0.0282247, -0.084959, -0.87945, -0.879454, -0.0282549, -0.0849424, -0.0850063, 0.0282584, 0.879389, -0.0850063, 0.879389, 0.0282584, 0.084933, -0.0282608, 0.879461 ) +[sub_resource type="SphereShape" id=3] + +[sub_resource type="SphereMesh" id=4] +  [node name="RigidBody" type="RigidBody"] -[node name="Cone" type="MeshInstance" parent="."] +[node name="MeshDie" type="MeshInstance" parent="."]  mesh = SubResource( 1 )  skeleton = NodePath("../..")  material/0 = null -[node name="CollisionShape" type="CollisionShape" parent="."] +[node name="CollisionShapeDie" type="CollisionShape" parent="."]  shape = SubResource( 2 ) + +[node name="CollisionShapeSphere" type="CollisionShape" parent="."] +transform = Transform( 0.7, 0, 0, 0, 0.7, 0, 0, 0, 0.7, 0, 0, 0 ) +shape = SubResource( 3 ) +disabled = true + +[node name="MeshSphere" type="MeshInstance" parent="."] +transform = Transform( 0.7, 0, 0, 0, 0.7, 0, 0, 0, 0.7, 0, 0, 0 ) +visible = false +mesh = SubResource( 4 ) +material/0 = ExtResource( 2 ) 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.dllBinary files differ index 04c4295..115f39f 100644 --- a/lib/x86_64-pc-windows-msvc/code_with_your_friends2022.dll +++ 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.soBinary files differ index 14b6058..962bdb5 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..dbcccc8 --- /dev/null +++ b/rust/src/basic_die.rs @@ -0,0 +1,376 @@ +use std::borrow::Borrow; +use gdnative::api::*; +use gdnative::prelude::*; +use crate::buff_trait::Buff; +use crate::buff_ball::BuffBall; +use crate::buff_bounce::BuffBounce; +use crate::buff_phase::BuffPhase; +use crate::buff_extra::BuffExtra; + +/// 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, +    #[property(path="input/current_buff_index")] +    current_buff_index: i32, + +    all_buffs: [Option<Box<dyn Buff>>; 5], + +    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, +            current_buff_index: 0, +            all_buffs: [None, None, None, None, None], + +            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")); + +        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.claim() +            } +        }; + +        self.all_buffs = [ +            None, +            Some(Box::new(BuffBall  ::new(Box::new(die)))), +            Some(Box::new(BuffBounce::new(Box::new(die)))), +            Some(Box::new(BuffPhase ::new(Box::new(die)))), +            Some(Box::new(BuffExtra ::new())), +        ]; + +        godot_print!("Current Buff: {}", self.current_buff_index); +        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()); +            } +        } + +        let delta_ms = OS::godot_singleton().get_ticks_msec() - self.last_shot_time; + +        // deactivate the Ball Buff after 5 seconds +        if matches!(self.input_state, InputState::Moving) +           && delta_ms > 5000 +           && self.current_buff_index == 1 { +            match self.all_buffs[1] { +                Some(ref mut buff) => buff.revert_buff(), +                None => {} +            } +        } + +        // detect if the die stops moving +        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); +                 +                //deactivate the old buff +                godot_print!("Current Buff: {}", self.current_buff_index); +                match self.all_buffs[self.current_buff_index as usize] { +                    Some(ref mut buff) => buff.revert_buff(), +                    None => {} +                } +                //TODO: find out which side is up and update the current buff index accordingly +            } +        }; +    } + +    #[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 +            } +        }; + +        // apply the current buff +        godot_print!("Current Buff: {}", self.current_buff_index); +        match self.all_buffs[self.current_buff_index as usize] { +            Some(ref mut buff) => buff.execute_buff(), +            None => {} +        } + +        // 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/buff_ball.rs b/rust/src/buff_ball.rs index 4b89dbb..219e675 100644 --- a/rust/src/buff_ball.rs +++ b/rust/src/buff_ball.rs @@ -2,71 +2,66 @@ use gdnative::api::*;  use gdnative::prelude::*;  use crate::buff_trait::Buff; -struct BuffBall { +pub struct BuffBall {      name: String,      description: String, - -    die_body: Option<Ref<RigidBody>>, -    sphere_body: Option<Ref<RigidBody>> +    collision_die: Ref<CollisionShape>, +    collision_sphere: Ref<CollisionShape>, +    mesh_die: Ref<MeshInstance>, +    mesh_sphere: Ref<MeshInstance>,  }  impl BuffBall { -    fn new(die_body: Option<Ref<RigidBody>>, sphere_body: Option<Ref<RigidBody>>) -> Self { + +    pub fn new(die_body: Box<Ref<RigidBody>>) -> Self { + +        // find a collision shape +        fn search<T: SubClass<Node>> (die_body: &Box<Ref<RigidBody>>, name: String) -> Option<Ref<T>> { +            unsafe{ +            match die_body.assume_safe().get_node(&name) { +                None => {  +                    godot_warn!("Could not find {}", name);  +                    None +                } +                Some(node) => { +                    match node.assume_safe().cast::<T>() { +                        None => { +                            godot_warn!("{} is not a {}", name, std::any::type_name::<T>()); +                            None +                        }, +                        Some(cs) => Some(cs.claim()) +                    } +                } +            } +            } +        } +          BuffBall {              name: String::from("Ball"),              description: String::from("Roll the dice"), - -            die_body, -            sphere_body +            collision_die:    search::<CollisionShape>(&die_body, String::from("CollisionShapeDie"   )).unwrap(), +            collision_sphere: search::<CollisionShape>(&die_body, String::from("CollisionShapeSphere")).unwrap(), +            mesh_die:    search::<MeshInstance>(&die_body, String::from("MeshDie"   )).unwrap(), +            mesh_sphere: search::<MeshInstance>(&die_body, String::from("MeshSphere")).unwrap(),          }      }  }  impl Buff for BuffBall {      unsafe fn execute_buff(&mut self) { -        // make sure the sphere rigid body exists -        match &self.sphere_body { -            Some(sphere) => { -                // make sure the dice rigid body exists -                match &self.die_body { -                    Some(die) => { -                        // get the safe references from the ref<> -                        let save_sphere = sphere.assume_safe(); -                        let save_die = die.assume_safe(); - -                        // set the properties of the rigid bodies -                        save_die.set_process(false); -                        save_sphere.set_process(true); -                        save_sphere.show(); -                    }, -                    None => godot_warn!("Die body not assigned") -                } -            }, -            None => godot_warn!("Sphere body not assigned") -        } +        self.collision_die.assume_safe().set_disabled(true); +        self.collision_sphere.assume_safe().set_disabled(false); +        self.mesh_die.assume_safe().set_visible(false); +        self.mesh_sphere.assume_safe().set_visible(true); +        godot_print!("Ball activated");      }      unsafe fn revert_buff(&mut self) { -        // make sure the sphere rigid body exists -        match &self.sphere_body { -            Some(sphere) => { -                // make sure the dice rigid body exists -                match &self.die_body { -                    Some(die) => { -                        // get the safe references from the ref<> -                        let save_sphere = sphere.assume_safe(); -                        let save_die = die.assume_safe(); - -                        // set the properties of the rigid bodies -                        save_die.set_process(true); -                        save_sphere.set_process(false); -                        save_sphere.hide(); -                    }, -                    None => godot_warn!("Die body not assigned") -                } -            }, -            None => godot_warn!("Sphere body not assigned") -        } +        self.collision_die.assume_safe().set_disabled(false); +        self.collision_sphere.assume_safe().set_disabled(true); +        self.mesh_sphere.assume_safe().set_visible(false); +        self.mesh_die.assume_safe().set_visible(true); +        godot_print!("Ball deactivated");      }      fn get_name(self) -> GodotString { diff --git a/rust/src/buff_bounce.rs b/rust/src/buff_bounce.rs index 179642d..cb9ded8 100644 --- a/rust/src/buff_bounce.rs +++ b/rust/src/buff_bounce.rs @@ -2,22 +2,21 @@ use gdnative::api::*;  use gdnative::prelude::*;  use crate::buff_trait::Buff; -struct BuffBounce { +pub struct BuffBounce {      name: String,      description: String, -    rigid_body: Option<Ref<RigidBody>>, +    rigid_body: Box<Ref<RigidBody>>,      target_bounciness: f64,      previous_bounciness: f64  }  impl BuffBounce { -    fn new(rigid_body: Option<Ref<RigidBody>>) -> Self { +    pub fn new(rigid_body: Box<Ref<RigidBody>>) -> Self {          BuffBounce {              name: String::from("Bounce"),              description: String::from("Let's the die bounce more than usual."),              rigid_body, -              target_bounciness: 1.0,              previous_bounciness: 0.0          } @@ -25,43 +24,30 @@ impl BuffBounce {  }  impl Buff for BuffBounce { -    unsafe fn execute_buff(&mut self) { -        // make sure the rigid body exists -        match &self.rigid_body { -            Some(body) => { -                let safe_body = body.assume_safe(); -                // get the physics material -                match safe_body.physics_material_override() { -                    Some(mat) => { -                        let save_mat = mat.assume_safe(); -                        self.previous_bounciness = save_mat.bounce(); -                        save_mat.set_bounce(self.target_bounciness); -                    }, -                    None => godot_warn!("Physics material was not found") -                } +    unsafe fn execute_buff(&mut self) { +        // get the physics material +        match self.rigid_body.assume_safe().physics_material_override() { +            Some(mat) => { +                let save_mat = mat.assume_safe(); +                self.previous_bounciness = save_mat.bounce(); +                save_mat.set_bounce(self.target_bounciness);              }, -            None => godot_warn!("No rigid body initialized to apply properties to") +            None => godot_warn!("Physics material was not found")          } +        godot_print!("Bounce activated");      }      unsafe fn revert_buff(&mut self) { -        // make sure the rigid body exists -        match &self.rigid_body { -            Some(body) => { -                let safe_body = body.assume_safe(); - -                // get the physics material -                match safe_body.physics_material_override() { -                    Some(mat) => { -                        let save_mat = mat.assume_safe(); -                        save_mat.set_bounce(self.previous_bounciness); -                    }, -                    None => godot_warn!("Physics material was not found") -                } +        // get the physics material +        match self.rigid_body.assume_safe().physics_material_override() { +            Some(mat) => { +                let save_mat = mat.assume_safe(); +                save_mat.set_bounce(self.previous_bounciness);              }, -            None => godot_warn!("No rigid body initialized to apply properties to") +            None => godot_warn!("Physics material was not found")          } +        godot_print!("Bounce deactivated");      }      fn get_name(self) -> GodotString { diff --git a/rust/src/buff_extra.rs b/rust/src/buff_extra.rs index 473cdde..a7b7902 100644 --- a/rust/src/buff_extra.rs +++ b/rust/src/buff_extra.rs @@ -2,13 +2,13 @@ use gdnative::api::*;  use gdnative::prelude::*;  use crate::buff_trait::Buff; -struct BuffExtra { +pub struct BuffExtra {      name: String,      description: String,  }  impl BuffExtra { -    fn new() -> Self { +    pub fn new() -> Self {          BuffExtra {              name: String::from("Extra Stroke"),              description: String::from("One additional stroke that doesn't count"), diff --git a/rust/src/buff_phase.rs b/rust/src/buff_phase.rs index e64508e..f69fecc 100644 --- a/rust/src/buff_phase.rs +++ b/rust/src/buff_phase.rs @@ -2,16 +2,16 @@ use gdnative::api::*;  use gdnative::prelude::*;  use crate::buff_trait::Buff; -struct BuffPhase { +pub struct BuffPhase {      name: String,      description: String, -    rigid_body: Option<Ref<RigidBody>>, +    rigid_body: Box<Ref<RigidBody>>,      wall_layer_bit: i64,  }  impl BuffPhase { -    fn new(rigid_body: Option<Ref<RigidBody>>) -> Self { +    pub fn new(rigid_body: Box<Ref<RigidBody>>) -> Self {          // calculate the bit for the mask to enable/ disable collision detection          let mask_layer = 2;          let mask_bit = 2_i64.pow(mask_layer - 1); @@ -20,7 +20,6 @@ impl BuffPhase {              name: String::from("Phase"),              description: String::from("Phases through thin fences"),              rigid_body, -              wall_layer_bit: mask_bit,          }      } @@ -28,26 +27,12 @@ impl BuffPhase {  impl Buff for BuffPhase {      unsafe fn execute_buff(&mut self) { -        match &self.rigid_body { -            Some(body) => { -                // actually disable the collision to the fences -                let save_body = body.assume_safe(); -                save_body.set_collision_mask_bit(self.wall_layer_bit, false); -            }, -            None => godot_warn!("Rigid body not found") -        } +        // actually disable the collision to the fences +        self.rigid_body.assume_safe().set_collision_mask_bit(self.wall_layer_bit, false);      }      unsafe fn revert_buff(& mut self) { -        // make sure the rigid body exists -        match &self.rigid_body { -            Some(body) => { -                // actually enable the collision again -                let save_body = body.assume_safe(); -                save_body.set_collision_mask_bit(self.wall_layer_bit, false); -            }, -            None => godot_warn!("Rigid body not found") -        } +        self.rigid_body.assume_safe().set_collision_mask_bit(self.wall_layer_bit, false);      }      fn get_name(self) -> GodotString { diff --git a/rust/src/game.rs b/rust/src/game.rs index 7004f96..61b23ed 100644 --- a/rust/src/game.rs +++ b/rust/src/game.rs @@ -40,6 +40,5 @@ impl Game {      // This function will be called in every frame      #[export] -    unsafe fn _process(&self, _owner: &Spatial, delta: f64) { -    } +    unsafe fn _process(&self, _owner: &Spatial, _delta: f64) { }  } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 401b668..1be319a 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -6,6 +6,8 @@ mod buff_trait;  mod buff_ball;  mod buff_extra;  pub mod goal_trigger; +mod test; +mod basic_die;  use gdnative::prelude::{godot_init, InitHandle}; @@ -14,6 +16,8 @@ fn init(handle: InitHandle) {      handle.add_class::<game::Game>();      handle.add_class::<spinning_cube::SpinningCube>();      handle.add_class::<goal_trigger::GoalTriggerZone>(); +    handle.add_class::<test::SpinningCubeReverse>(); +    handle.add_class::<basic_die::BasicDie>();  }  // macros that create the entry-points of the dynamic library. | 
