aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.gitignore1
-rw-r--r--cargo0
-rw-r--r--godot/native/BasicDie.gdns8
-rw-r--r--godot/project.godot12
-rw-r--r--godot/scenes/Game.tscn5
-rw-r--r--godot/scenes/levels/test_scene/TestScene.tscn11
-rw-r--r--godot/scenes/levels/test_scene_movement/Floor.tscn22
-rw-r--r--godot/scenes/levels/test_scene_movement/TestSceneMovement.tscn31
-rw-r--r--godot/scenes/levels/test_scene_movement/Wall.tscn23
-rw-r--r--godot/scenes/objects/Camera.tscn10
-rw-r--r--godot/scenes/objects/Player.tscn21
-rw-r--r--godot/scenes/objects/W8.tscn21
-rw-r--r--lib/x86_64-pc-windows-msvc/code_with_your_friends2022.dllbin397824 -> 482304 bytes
-rwxr-xr-xlib/x86_64-unknown-linux-gnu/libcode_with_your_friends2022.sobin25714184 -> 30387968 bytes
-rw-r--r--rust/src/basic_die.rs376
-rw-r--r--rust/src/buff_ball.rs91
-rw-r--r--rust/src/buff_bounce.rs52
-rw-r--r--rust/src/buff_extra.rs4
-rw-r--r--rust/src/buff_phase.rs27
-rw-r--r--rust/src/game.rs3
-rw-r--r--rust/src/lib.rs4
21 files changed, 602 insertions, 120 deletions
diff --git a/.gitignore b/.gitignore
index 5146acf..c0cdeaa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,4 @@ rust/Cargo.lock
rust/debug/
target/
tramp
+make.bat
diff --git a/cargo b/cargo
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cargo
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.dll
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
Binary files differ
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
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
Binary files differ
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.