feat: tweaks and work on enemy car

This commit is contained in:
Sara 2024-05-23 15:57:09 +02:00
parent c8e9e2fb4d
commit a8f7bd20db
24 changed files with 430 additions and 54 deletions

View file

@ -0,0 +1,27 @@
[gd_scene load_steps=4 format=3 uid="uid://g5cbht0novdc"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_36cjj"]
shading_mode = 0
albedo_color = Color(0.535553, 0.57272, 1, 1)
[sub_resource type="CapsuleMesh" id="CapsuleMesh_2fqgx"]
material = SubResource("StandardMaterial3D_36cjj")
radius = 0.195
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_v1t6q"]
radius = 0.308023
[node name="Beam" type="Beam"]
collision_layer = 0
collision_mask = 4
monitoring = false
monitorable = false
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0)
mesh = SubResource("CapsuleMesh_2fqgx")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0)
shape = SubResource("CapsuleShape3D_v1t6q")
disabled = true

View file

@ -0,0 +1,25 @@
[gd_scene load_steps=4 format=3 uid="uid://b74cqcryut76c"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_36cjj"]
shading_mode = 0
albedo_color = Color(0.227451, 0.827451, 0.678431, 1)
[sub_resource type="CapsuleMesh" id="CapsuleMesh_2fqgx"]
material = SubResource("StandardMaterial3D_36cjj")
radius = 0.39
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_v1t6q"]
radius = 0.308023
[node name="Beam" type="Beam"]
collision_layer = 0
collision_mask = 4
monitorable = false
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0)
mesh = SubResource("CapsuleMesh_2fqgx")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0)
shape = SubResource("CapsuleShape3D_v1t6q")

View file

@ -8,6 +8,7 @@ albedo_color = Color(0.227451, 0.827451, 0.678431, 1)
material = SubResource("StandardMaterial3D_36cjj")
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_v1t6q"]
radius = 0.0869471
[node name="Beam" type="Beam"]
collision_layer = 0

View file

@ -1,5 +1,6 @@
[gd_scene load_steps=13 format=3 uid="uid://dkvgi7x2epurk"]
[gd_scene load_steps=14 format=3 uid="uid://dkvgi7x2epurk"]
[ext_resource type="PackedScene" uid="uid://1eawpg0buvah" path="res://GameObjects/player_turret.tscn" id="1_ing2c"]
[ext_resource type="PackedScene" uid="uid://bm2mavtmnbaw1" path="res://Models/CarParts/SM_Veh_Hatch_01.fbx" id="1_tymeg"]
[ext_resource type="PackedScene" uid="uid://cr1ytl0o43ftv" path="res://GameObjects/beacon_powerup.tscn" id="1_uhbx0"]
[ext_resource type="PackedScene" uid="uid://bfq7ipx01ag7p" path="res://Models/CarParts/SM_Veh_Hatch_01_Bonnet_01.fbx" id="2_l8ox5"]
@ -22,13 +23,14 @@ rough = true
absorbent = true
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_4xe1s"]
points = PackedVector3Array(-1, -0.6, -2.11, 1, -0.6, -2.11, -1, -0.6, 1.405, 1, -0.6, 1.405, 0.76, -0.6, 2.065, -0.76, -0.6, 2.065, -0.74, 0.555, -1.74, 0.74, 0.555, -1.74, -0.665, 0.585, 0, 0.665, 0.585, 0, 0.665, -0.085, 1.88, -0.665, -0.085, 1.88)
points = PackedVector3Array(-1.155, -0.6, -3.48, 1.155, -0.6, -3.48, -1.155, -0.6, 1.405, 1.155, -0.6, 1.405, 1.155, -0.6, 2.81, -1.155, -0.6, 2.81, -1.155, 1.16, -3.48, 1.155, 1.16, -3.48, -1.155, 1.16, 0.65, 1.155, 1.16, 0.65, 1.155, 0.335, 2.81, -1.155, 0.335, 2.81)
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_p38n5"]
radius = 0.48558
height = 2.765
[node name="CarPlayer" type="CarPlayer"]
turret_scene = ExtResource("1_uhbx0")
turret_scene = ExtResource("1_ing2c")
beacon_scene = ExtResource("1_uhbx0")
shield_scene = ExtResource("1_uhbx0")
oversteer_curve = SubResource("Curve_dpk6q")

View file

@ -2,7 +2,8 @@
[sub_resource type="Animation" id="Animation_xagif"]
resource_name = "explode"
length = 0.4
length = 0.05
step = 0.01
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
@ -10,10 +11,10 @@ tracks/0/path = NodePath("CollisionShape3D:shape:radius")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.4),
"times": PackedFloat32Array(0, 0.05),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0.001, 10.0]
"values": [0.001, 2.0]
}
tracks/1/type = "value"
tracks/1/imported = false
@ -22,10 +23,10 @@ tracks/1/path = NodePath("MeshInstance3D:mesh:radius")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.4),
"times": PackedFloat32Array(0, 0.05),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0.5, 10.0]
"values": [0.5, 4.0]
}
tracks/2/type = "value"
tracks/2/imported = false
@ -34,10 +35,10 @@ tracks/2/path = NodePath("MeshInstance3D:mesh:height")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.4),
"times": PackedFloat32Array(0, 0.05),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [1.0, 20.0]
"values": [1.0, 8.0]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_eacvo"]

View file

@ -0,0 +1,67 @@
[gd_scene load_steps=7 format=3 uid="uid://b3p3ikural0cq"]
[ext_resource type="PackedScene" uid="uid://dsi3prgr34t85" path="res://Models/SM_Veh_Armored_Truck_01.fbx" id="1_2m0nm"]
[sub_resource type="Curve" id="Curve_dpk6q"]
_data = [Vector2(0.962441, 0), 0.0, 0.0, 0, 0, Vector2(1, 0.32967), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="Curve" id="Curve_htvme"]
_data = [Vector2(0.683099, 0), 0.0, 0.0, 0, 0, Vector2(0.823944, 0.230769), 0.0615885, 0.0615885, 0, 0]
point_count = 2
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_vwjm3"]
friction = 0.0
rough = true
absorbent = true
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_4xe1s"]
points = PackedVector3Array(-1.155, -0.6, -3.48, 1.155, -0.6, -3.48, -1.155, -0.6, 1.405, 1.155, -0.6, 1.405, 1.155, -0.6, 2.81, -1.155, -0.6, 2.81, -1.155, 1.16, -3.48, 1.155, 1.16, -3.48, -1.155, 1.16, 0.65, 1.155, 1.16, 0.65, 1.155, 0.335, 2.81, -1.155, 0.335, 2.81)
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_p38n5"]
radius = 0.48558
height = 2.765
[node name="EnemyCar" type="EnemyCar"]
oversteer_curve = SubResource("Curve_dpk6q")
oversteer_curve_x_scale = 40.0
understeer_curve = SubResource("Curve_htvme")
understeer_curve_x_scale = 40.0
max_slide_speed = 10.0
oversteer_speed_penalty = 10.0
collision_layer = 7
collision_mask = 3
mass = 1000.0
physics_material_override = SubResource("PhysicsMaterial_vwjm3")
center_of_mass_mode = 1
center_of_mass = Vector3(0, 0.2, 0)
can_sleep = false
custom_integrator = true
continuous_cd = true
max_contacts_reported = 128
contact_monitor = true
linear_damp_mode = 1
linear_damp = 0.5
[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(-1, -2.02334e-08, -8.50491e-08, -2.87879e-08, 0.994803, 0.10182, 8.25469e-08, 0.10182, -0.994803, 4.6449e-07, 2.24116, -4.7912)
fov = 68.9128
[node name="Body" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.27103, 0.174572)
shape = SubResource("ConvexPolygonShape3D_4xe1s")
[node name="FrontWheels" type="CollisionShape3D" parent="."]
transform = Transform3D(-4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0, 1, 0, 0.466215, 1.97394)
shape = SubResource("CapsuleShape3D_p38n5")
[node name="BackWheels" type="CollisionShape3D" parent="."]
transform = Transform3D(-4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0, 1, 0, 0.466215, -2.11718)
shape = SubResource("CapsuleShape3D_p38n5")
[node name="RoofSlot" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.31348, -0.510359)
[node name="Root Scene" parent="." instance=ExtResource("1_2m0nm")]
[node name="NavigationAgent3D" type="NavigationAgent3D" parent="."]

View file

@ -8,7 +8,7 @@ top_radius = 0.055
height = 0.39
[sub_resource type="SphereShape3D" id="SphereShape3D_rdc8b"]
radius = 167.996
radius = 61.2859
[sub_resource type="BoxMesh" id="BoxMesh_ag1t0"]
size = Vector3(0.205, 1, 0.83)
@ -19,27 +19,29 @@ radius = 0.392821
[node name="Turret" type="Turret"]
attack_classes = [&"EnemyTargetBody"]
beam_scene = ExtResource("1_xm6id")
fire_time = 0.2
charge_time = 0.0
lock_time = 0.5
collision_layer = 0
collision_mask = 0
can_sleep = false
freeze = true
freeze_mode = 1
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0758235, 0)
mesh = SubResource("CylinderMesh_1btvq")
[node name="AwarenessArea" type="Area3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -15.7959, 0)
collision_layer = 0
collision_mask = 2
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="AwarenessArea"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 13.9111, 0)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.33142, -0.152048)
shape = SubResource("SphereShape3D_rdc8b")
[node name="Gun" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.273896, 0)
top_level = true
[node name="Root Scene" parent="Gun" instance=ExtResource("2_vsdye")]
transform = Transform3D(1.30858, 0, 0, 0, 1.30858, 0, 0, 0, 1.30858, 0.00200939, -0.12911, -0.0137266)

View file

@ -19,8 +19,14 @@ size = Vector3(0.205, 1, 0.83)
[node name="Turret" type="Turret"]
attack_classes = [&"CarPlayer"]
beam_scene = ExtResource("1_7e7bw")
collision_layer = 11
collision_mask = 11
collision_layer = 9
collision_mask = 9
axis_lock_linear_x = true
axis_lock_linear_y = true
axis_lock_linear_z = true
axis_lock_angular_x = true
axis_lock_angular_y = true
axis_lock_angular_z = true
freeze = true
freeze_mode = 1

View file

@ -43,4 +43,14 @@ offset_top = 30.0
offset_right = 437.0
offset_bottom = 339.0
[node name="Label" type="Label" parent="GameUI/ControlsScreen"]
layout_mode = 0
offset_left = 25.0
offset_top = 19.0
offset_right = 388.0
offset_bottom = 290.0
text = "W : Accelerate
SPACE : Handbrake
A/D : Steering"
[node name="Camera3D" type="Camera3D" parent="."]

File diff suppressed because one or more lines are too long

BIN
godot/Models/SM_Veh_Armored_Truck_01.fbx (Stored with Git LFS) Normal file

Binary file not shown.

View file

@ -0,0 +1,41 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://dsi3prgr34t85"
path="res://.godot/imported/SM_Veh_Armored_Truck_01.fbx-28be66d7362753ffc32958c9e877fc38.scn"
[deps]
source_file="res://Models/SM_Veh_Armored_Truck_01.fbx"
dest_files=["res://.godot/imported/SM_Veh_Armored_Truck_01.fbx-28be66d7362753ffc32958c9e877fc38.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=1.0
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={
"materials": {
"Body1": {
"use_external/enabled": true,
"use_external/path": "res://Models/World/City/city.tres"
}
}
}
gltf/naming_version=1
gltf/embedded_image_handling=1

View file

@ -62,6 +62,8 @@ void CarPlayer::damage() {
void CarPlayer::destroy_all_powerups() {
for(int i = 0; i < this->roof_slot->get_child_count(); ++i) {
if(this->roof_slot->get_child(0)->is_class("Turret"))
Ref<RallyRushGameMode>(GameRoot3D::get_singleton()->get_game_mode())->notify_end_turret_pickup();
this->roof_slot->get_child(0)->queue_free();
}
}
@ -74,7 +76,10 @@ void CarPlayer::activate_powerup(Ref<PackedScene> scene) {
this->end_of_powerup = Time::get_singleton()->get_ticks_msec() * 0.001 + this->powerup_duration;
}
void CarPlayer::activate_turret() { this->activate_powerup(this->turret); }
void CarPlayer::activate_turret() {
Ref<RallyRushGameMode>(GameRoot3D::get_singleton()->get_game_mode())->notify_turret_pickup();
this->activate_powerup(this->turret);
}
void CarPlayer::activate_beacon() { this->activate_powerup(this->beacon); }
void CarPlayer::activate_shield() { this->activate_powerup(this->turret); }

View file

@ -1,6 +1,7 @@
#include "drone.hpp"
#include "godot_cpp/classes/animation_player.hpp"
#include "godot_cpp/classes/global_constants.hpp"
#include "rally_rush_game_mode.hpp"
#include "utils/game_root.hpp"
#include "utils/godot_macros.h"
#include <godot_cpp/classes/navigation_agent3d.hpp>
@ -15,6 +16,10 @@ void Drone::_ready() { GDGAMEONLY();
this->agent = this->get_node<NavigationAgent3D>("NavigationAgent3D");
this->anim = this->get_node<AnimationPlayer>("AnimationPlayer");
this->player = Object::cast_to<CarPlayer>(GameRoot3D::get_singleton()->get_players()[0]->to_node());
RallyRushGameMode *game_mode = Ref<RallyRushGameMode>(GameRoot3D::get_singleton()->get_game_mode()).ptr();
game_mode->connect("key_found", callable_mp(this, &Drone::key_found));
game_mode->connect("turret_pickup", callable_mp(this, &Drone::start_flee));
game_mode->connect("end_turret_pickup", callable_mp(this, &Drone::end_flee));
this->recalculate_navigation();
}
@ -35,7 +40,7 @@ void Drone::_process(double delta_time) { GDGAMEONLY();
void Drone::process_chase(double delta_time) {
this->process_navigate(delta_time);
if(this->get_global_position().distance_to(this->agent->get_target_position()) < 2.f) {
if(this->get_global_position().distance_to(this->agent->get_target_position()) < this->target_distance) {
this->anim->play("drop");
this->state = DroneState::DROP;
}
@ -73,6 +78,22 @@ void Drone::spawn_explosion() {
this->queue_free();
}
void Drone::key_found(int total) {
if(total == 2) {
this->speed *= 2;
}
}
void Drone::start_flee() {
if(this->state == DroneState::CHASE)
this->state = DroneState::FLEE;
}
void Drone::end_flee() {
if(this->state == DroneState::FLEE)
this->state = DroneState::CHASE;
}
void Drone::set_explosion_scene(Ref<PackedScene> scene) {
this->explosion_scene = scene;
}

View file

@ -22,6 +22,10 @@ public:
void process_navigate(double delta_time);
void recalculate_navigation();
void spawn_explosion();
void key_found(int total);
void start_flee();
void end_flee();
void set_explosion_scene(Ref<PackedScene> scene);
Ref<PackedScene> get_explosion_scene() const;
@ -30,6 +34,7 @@ private:
int next_recalc{10};
float speed{30.f};
float lead_time{2.f};
float target_distance{3.f};
DroneState state{DroneState::CHASE};
CarPlayer *player{nullptr};
Ref<PackedScene> explosion_scene{};

View file

@ -1,4 +1,5 @@
#include "drone_target.hpp"
#include "godot_cpp/variant/utility_functions.hpp"
#include "utils/godot_macros.h"
namespace godot {
@ -13,6 +14,7 @@ void EnemyTargetBody::_enter_tree() {
}
void EnemyTargetBody::damage() {
UtilityFunctions::print("enemy destroyed");
this->get_owner()->queue_free();
}
}

39
src/enemy_car.cpp Normal file
View file

@ -0,0 +1,39 @@
#include "enemy_car.hpp"
#include "godot_cpp/classes/navigation_agent3d.hpp"
#include "utils/game_root.hpp"
#include "utils/godot_macros.h"
namespace godot {
void EnemyCar::_bind_methods() {
#define CLASSNAME EnemyCar
GDSIGNAL("damage");
}
void EnemyCar::_enter_tree() {
CarPhysics::_enter_tree();
GDGAMEONLY();
this->player = Object::cast_to<CarPlayer>(GameRoot3D::get_singleton()->get_players()[0]->to_node());
this->agent = this->get_node<NavigationAgent3D>("NavigationAgent3D");
}
void EnemyCar::_process(double delta_time) { GDGAMEONLY();
this->process_navigate();
}
void EnemyCar::process_navigate() {
--this->next_recalc;
if(this->next_recalc <= 0)
this->recalculate_navigation();
Vector3 const target_direction{this->agent->get_next_path_position() - this->get_global_position()};
Vector3 const direction{this->get_global_basis().get_column(2)};
float const ang_dif = target_direction.signed_angle_to(direction.normalized(), this->get_global_basis().get_column(1));
this->set_target_speed(this->max_speed);
this->set_current_steering(Math::abs(ang_dif) * this->steering_speed);
this->set_brake(target_direction.length() < this->brake_distance);
}
void EnemyCar::recalculate_navigation() {
this->next_recalc = this->recalc_frame_interval;
this->agent->set_target_position(this->player->get_global_position() + this->player->get_global_basis().get_column(2) * 4.f);
}
}

31
src/enemy_car.hpp Normal file
View file

@ -0,0 +1,31 @@
#ifndef ENEMY_CAR_HPP
#define ENEMY_CAR_HPP
#include "car_physics.hpp"
#include "car_player.hpp"
#include "godot_cpp/classes/navigation_agent3d.hpp"
namespace godot {
class EnemyCar : public CarPhysics {
GDCLASS(EnemyCar, CarPhysics);
static void _bind_methods();
public:
virtual void _enter_tree() override;
virtual void _process(double delta_time) override;
void damage();
protected:
void process_navigate();
void recalculate_navigation();
private:
int next_recalc{0};
int recalc_frame_interval{10};
float turn_target_speed{3.f};
float max_speed{45.f};
float brake_distance{7.f};
float steering_speed{1.f};
NavigationAgent3D *agent{nullptr};
CarPlayer *player{nullptr};
};
}
#endif // !ENEMY_CAR_HPP

View file

@ -8,6 +8,8 @@ void RallyRushGameMode::_bind_methods() {
#define CLASSNAME RallyRushGameMode
GDSIGNAL("key_found", PropertyInfo(Variant::INT, "total_found"));
GDSIGNAL("all_keys_found");
GDSIGNAL("turret_pickup");
GDSIGNAL("end_turret_pickup");
}
int RallyRushGameMode::get_num_found_keys() {
@ -21,6 +23,13 @@ void RallyRushGameMode::notify_key_found() {
this->emit_signal("all_keys_found");
}
void RallyRushGameMode::notify_turret_pickup() {
this->emit_signal("turret_pickup");
}
void RallyRushGameMode::notify_end_turret_pickup() {
this->emit_signal("end_turret_pickup");
}
#define GAME_END_SCENE "res://Levels/game_end_screen.tscn"
void RallyRushGameMode::notify_player_death() {

View file

@ -12,6 +12,8 @@ public:
void notify_key_found();
void notify_player_death();
void notify_player_escaped();
void notify_turret_pickup();
void notify_end_turret_pickup();
private:
int num_keys_found{0};
};

View file

@ -7,6 +7,7 @@
#include "drone.hpp"
#include "drone_target.hpp"
#include "end_screen.hpp"
#include "enemy_car.hpp"
#include "enemy_spawnpoint.hpp"
#include "exit_door.hpp"
#include "exit_trigger.hpp"
@ -60,6 +61,7 @@ void initialize_gdextension_types(ModuleInitializationLevel p_level)
ClassDB::register_class<EnemyTargetBody>();
ClassDB::register_class<WeaponPickup>();
ClassDB::register_class<BeaconPowerup>();
ClassDB::register_class<EnemyCar>();
}
extern "C"

View file

@ -13,16 +13,20 @@ void Turret::_bind_methods() {
#define CLASSNAME Turret
GDPROPERTY_HINTED(attack_classes, Variant::ARRAY, PROPERTY_HINT_ARRAY_TYPE, "StringName");
GDPROPERTY_HINTED(beam_scene, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene");
GDPROPERTY(fire_time, Variant::FLOAT);
GDPROPERTY(charge_time, Variant::FLOAT);
GDPROPERTY(lock_time, Variant::FLOAT);
}
void Turret::_enter_tree() {
this->set_freeze_mode(FreezeMode::FREEZE_MODE_KINEMATIC);
void Turret::_enter_tree() { GDGAMEONLY();
this->set_freeze_enabled(true);
GDGAMEONLY();
Area3D *awareness_area = this->get_node<Area3D>("AwarenessArea");
awareness_area->connect("body_entered", callable_mp(this, &Turret::detect_node));
awareness_area->connect("body_exited", callable_mp(this, &Turret::lose_node));
this->gun_node = this->get_node<Node3D>("Gun");
this->awareness_changed();
this->gun_node->set_as_top_level(true);
this->gun_node_offset = this->gun_node->get_position();
}
void Turret::_process(double delta_time) { GDGAMEONLY();
@ -34,41 +38,51 @@ void Turret::_process(double delta_time) { GDGAMEONLY();
break;
}
this->try_next_state();
this->gun_node->set_global_position(this->get_global_position() + this->gun_node_offset);
}
void Turret::awareness_changed() {
if(this->current_target != nullptr)
if(this->state != TurretState::WAITING)
return;
this->current_target = this->select_target();
if(this->current_target == nullptr)
if(this->current_target == nullptr) {
this->state = TurretState::WAITING;
else
} else {
this->state = TurretState::LOCKING;
UtilityFunctions::print(this->get_path(), " new target ", this->current_target->get_path());
}
this->last_state_switch = Time::get_singleton()->get_ticks_msec() * 0.001f;
}
Node3D *Turret::select_target() {
for(Node3D *node : this->awareness)
if(!this->invert_attack_classes && this->attack_classes.has(node->get_class()))
return node;
else if(this->invert_attack_classes && !this->attack_classes.has(node->get_class())) {
UtilityFunctions::print("selecting inverted target");
for(Node3D *node : this->awareness) {
if(!this->invert_attack_classes && this->attack_classes.has(node->get_class())) {
UtilityFunctions::print(this->get_path(), " selecting regular target ", node->get_path());
return node;
}
else if(this->invert_attack_classes && !this->attack_classes.has(node->get_class())) {
UtilityFunctions::print(this->get_path(), " selecting inverted target ", node->get_path());
return node;
}
}
return nullptr;
}
void Turret::lead_target(double delta_time) {
if(!this->current_target)
if(this->current_target == nullptr)
return;
Vector3 const target_position = this->current_target->get_global_position();
Vector3 const target_heading = (target_position - this->last_target_position) / delta_time;
this->aim_position = target_position + (target_heading * this->lead_distance);
if(this->current_target->is_class("CarPlayer")) {
Vector3 const target_heading = (target_position - this->last_target_position) / delta_time;
this->aim_position = target_position + (target_heading * this->lead_distance);
} else {
this->aim_position = target_position;
}
Vector3 const z = (this->aim_position - this->gun_node->get_global_position()).normalized();
Vector3 const x = z.cross({0.f, 1.f, 0.f});
Vector3 const y = z.cross(x);
Vector3 const y = x.cross(z);
this->gun_node->set_global_basis({x,y,z});
this->last_target_position = target_position;
@ -77,20 +91,18 @@ void Turret::lead_target(double delta_time) {
void Turret::detect_node(Node3D *node) {
if(!this->awareness.has(node)) {
this->awareness.insert(node);
this->awareness_changed();
}
this->awareness_changed();
UtilityFunctions::print(this->get_path(), " detected node ", node->get_path());
}
void Turret::lose_node(Node3D *node) {
if(this->awareness.has(node)) {
this->awareness.erase(node);
if(node == this->current_target) {
this->current_target = nullptr;
this->awareness_changed();
}
}
if(node == this->current_target) {
this->current_target = nullptr;
}
this->awareness_changed();
UtilityFunctions::print(this->get_path(), " lost track of node ", node->get_path());
}
void Turret::try_next_state() {
@ -137,7 +149,32 @@ void Turret::beam_ended() {
this->last_state_switch = Time::get_singleton()->get_ticks_msec() * 0.001f;
}
void Turret::set_fire_time(float val) {
this->fire_time = val;
}
float Turret::get_fire_time() const {
return this->fire_time;
}
void Turret::set_charge_time(float val) {
this->charge_time = val;
}
float Turret::get_charge_time() const {
return this->charge_time;
}
void Turret::set_lock_time(float val) {
this->lock_time = val;
}
float Turret::get_lock_time() const {
return this->lock_time;
}
void Turret::set_invert_targets(bool value) {
UtilityFunctions::print(this->get_path(), " invert targets");
this->invert_attack_classes = value;
this->current_target = nullptr;
this->awareness_changed();

View file

@ -34,6 +34,13 @@ public:
void beam_ended();
void set_fire_time(float val);
float get_fire_time() const;
void set_charge_time(float val);
float get_charge_time() const;
void set_lock_time(float val);
float get_lock_time() const;
void set_invert_targets(bool value);
void set_attack_classes(Array array);
Array get_attack_classes() const;
@ -48,7 +55,7 @@ private:
float lead_distance{1.2f};
Node3D *gun_node{nullptr};
Vector3 gun_node_offset{0.f, 0.f, 0.f};
TurretState state{TurretState::WAITING};

@ -1 +1 @@
Subproject commit a9e33a3781665cba3bb16fbc77d1535d88f344a0
Subproject commit 7bdb5e70eb1138c898f4f7382d2906ad6528090f