feat: tweaks to various mechanics
This commit is contained in:
parent
b8d487f14e
commit
63b5b54db0
|
@ -6,7 +6,7 @@ albedo_color = Color(0.535553, 0.57272, 1, 1)
|
|||
|
||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_2fqgx"]
|
||||
material = SubResource("StandardMaterial3D_36cjj")
|
||||
radius = 0.195
|
||||
radius = 0.05
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_v1t6q"]
|
||||
radius = 0.308023
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[gd_scene load_steps=9 format=3 uid="uid://ccfpovpj7uvo"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://dxyimydfpu8jp" path="res://GameObjects/damage_area.tscn" id="1_fajyr"]
|
||||
[ext_resource type="Material" uid="uid://b151co1fkexdi" path="res://Models/World/City/city.tres" id="2_2ou5w"]
|
||||
[ext_resource type="Material" uid="uid://b151co1fkexdi" path="res://Models/city.tres" id="2_2ou5w"]
|
||||
|
||||
[sub_resource type="SphereShape3D" id="SphereShape3D_i7yu8"]
|
||||
radius = 2.1793
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://1eawpg0buvah"]
|
||||
[gd_scene load_steps=8 format=3 uid="uid://1eawpg0buvah"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://b74cqcryut76c" path="res://GameObjects/anti_air_beam.tscn" id="1_newd3"]
|
||||
[ext_resource type="PackedScene" uid="uid://g5cbht0novdc" path="res://GameObjects/aiming_beam.tscn" id="2_blu28"]
|
||||
[ext_resource type="PackedScene" uid="uid://v5p6ih28q6ro" path="res://Models/SM_Wep_Shotgun_Plasma_01.fbx" id="2_vsdye"]
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_1btvq"]
|
||||
|
@ -19,6 +20,7 @@ radius = 0.392821
|
|||
[node name="Turret" type="Turret"]
|
||||
attack_classes = [&"EnemyTargetBody"]
|
||||
beam_scene = ExtResource("1_newd3")
|
||||
guiding_beam_scene = ExtResource("2_blu28")
|
||||
fire_time = 0.2
|
||||
charge_time = 0.0
|
||||
lock_time = 0.5
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,7 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://brpccv2gy7pjs"]
|
||||
[gd_scene load_steps=8 format=3 uid="uid://brpccv2gy7pjs"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://d0ir0dpghkikq" path="res://GameObjects/beam.tscn" id="1_7e7bw"]
|
||||
[ext_resource type="PackedScene" uid="uid://g5cbht0novdc" path="res://GameObjects/aiming_beam.tscn" id="2_616om"]
|
||||
[ext_resource type="PackedScene" uid="uid://v5p6ih28q6ro" path="res://Models/SM_Wep_Shotgun_Plasma_01.fbx" id="2_snu5d"]
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_sewkr"]
|
||||
|
@ -19,6 +20,9 @@ size = Vector3(0.205, 1, 0.83)
|
|||
[node name="Turret" type="Turret"]
|
||||
attack_classes = [&"CarPlayer"]
|
||||
beam_scene = ExtResource("1_7e7bw")
|
||||
guiding_beam_scene = ExtResource("2_616om")
|
||||
fire_time = 0.15
|
||||
charge_time = 1.3
|
||||
collision_layer = 9
|
||||
collision_mask = 9
|
||||
axis_lock_linear_x = true
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://dro5j4614bj8d"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://b151co1fkexdi" path="res://Models/World/City/city.tres" id="1_tjjf4"]
|
||||
[ext_resource type="Material" uid="uid://b151co1fkexdi" path="res://Models/city.tres" id="1_tjjf4"]
|
||||
|
||||
[sub_resource type="ArrayMesh" id="ArrayMesh_ihi1d"]
|
||||
_surfaces = [{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://dw47vdyt678og"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://b151co1fkexdi" path="res://Models/World/City/city.tres" id="1_nxymn"]
|
||||
[ext_resource type="Material" uid="uid://b151co1fkexdi" path="res://Models/city.tres" id="1_nxymn"]
|
||||
|
||||
[sub_resource type="ArrayMesh" id="ArrayMesh_qnxxj"]
|
||||
_surfaces = [{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://d2ltua7nsbicf"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://cbfimnkdsgwdi" path="res://Models/World/Forest/forest.tres" id="1_cupkv"]
|
||||
[ext_resource type="Material" uid="uid://cbfimnkdsgwdi" path="res://Models/forest.tres" id="1_cupkv"]
|
||||
|
||||
[sub_resource type="ArrayMesh" id="ArrayMesh_tcqye"]
|
||||
_surfaces = [{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://dcljtjjyxymd"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://k8w3xmh1vhia" path="res://Models/World/Harbour/containers.tres" id="1_fgu0h"]
|
||||
[ext_resource type="Material" uid="uid://k8w3xmh1vhia" path="res://Models/containers.tres" id="1_fgu0h"]
|
||||
|
||||
[sub_resource type="ArrayMesh" id="ArrayMesh_3g704"]
|
||||
_surfaces = [{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[gd_scene load_steps=60 format=3 uid="uid://coc0bvuqnit2x"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://45e28s7j77mx" path="res://Models/World/Harbour/crane.tres" id="1_ginbe"]
|
||||
[ext_resource type="Material" uid="uid://45e28s7j77mx" path="res://Models/crane.tres" id="1_ginbe"]
|
||||
|
||||
[sub_resource type="ArrayMesh" id="ArrayMesh_6ken0"]
|
||||
_surfaces = [{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[gd_scene load_steps=13 format=3 uid="uid://bqeot1gwbtwd"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://b151co1fkexdi" path="res://Models/World/City/city.tres" id="1_d8gyh"]
|
||||
[ext_resource type="Material" uid="uid://b151co1fkexdi" path="res://Models/city.tres" id="1_d8gyh"]
|
||||
|
||||
[sub_resource type="ArrayMesh" id="ArrayMesh_gde8f"]
|
||||
_surfaces = [{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://boh0mf73cpyk3"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://b151co1fkexdi" path="res://Models/World/City/city.tres" id="1_0mlbt"]
|
||||
[ext_resource type="Material" uid="uid://b151co1fkexdi" path="res://Models/city.tres" id="1_0mlbt"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vnx1q"]
|
||||
resource_name = "lambert10"
|
||||
|
|
|
@ -10,11 +10,15 @@ config_version=5
|
|||
|
||||
[application]
|
||||
|
||||
config/name="godot cpp template"
|
||||
config/name="rally rush"
|
||||
run/main_scene="res://boot.tscn"
|
||||
config/features=PackedStringArray("4.2", "Forward Plus")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[display]
|
||||
|
||||
window/size/mode=3
|
||||
|
||||
[input]
|
||||
|
||||
steer_left={
|
||||
|
|
12
src/beam.cpp
12
src/beam.cpp
|
@ -10,11 +10,15 @@ void Beam::_bind_methods() {
|
|||
|
||||
void Beam::_enter_tree() { GDGAMEONLY();
|
||||
this->mesh_instance = this->get_node<MeshInstance3D>("MeshInstance3D");
|
||||
if(this->mesh_instance)
|
||||
this->mesh = this->mesh_instance->get_mesh();
|
||||
if(this->mesh_instance) {
|
||||
this->mesh = this->mesh_instance->get_mesh()->duplicate();
|
||||
this->mesh_instance->set_mesh(this->mesh);
|
||||
}
|
||||
this->collision_shape = this->get_node<CollisionShape3D>("CollisionShape3D");
|
||||
if(this->collision_shape)
|
||||
this->shape = this->collision_shape->get_shape();
|
||||
if(this->collision_shape) {
|
||||
this->shape = this->collision_shape->get_shape()->duplicate();
|
||||
this->collision_shape->set_shape(shape);
|
||||
}
|
||||
this->connect("body_entered", callable_mp(this, &Beam::body_entered));
|
||||
}
|
||||
|
||||
|
|
|
@ -165,6 +165,10 @@ float CarPhysics::get_current_acceleration() const {
|
|||
: (this->engine_brake_force * (1.f-Math::abs(this->current_oversteer * this->oversteer_brake_penalty)))));
|
||||
}
|
||||
|
||||
Vector3 CarPhysics::get_local_velocity() const {
|
||||
return this->local_velocity;
|
||||
}
|
||||
|
||||
Vector3 CarPhysics::local_to_world_velocity() const {
|
||||
Basis const basis = this->get_global_basis();
|
||||
Vector3 world_velocity{
|
||||
|
|
|
@ -38,6 +38,7 @@ protected:
|
|||
float get_current_acceleration() const;
|
||||
public:
|
||||
// convert the local_velocity to world coordinates
|
||||
Vector3 get_local_velocity() const;
|
||||
Vector3 local_to_world_velocity() const;
|
||||
Vector3 world_to_local_velocity() const;
|
||||
float get_current_speed() const;
|
||||
|
|
|
@ -19,12 +19,23 @@ void CarPlayer::_bind_methods() {
|
|||
|
||||
void CarPlayer::_ready() { GDGAMEONLY();
|
||||
this->roof_slot = this->get_node<Node3D>("RoofSlot");
|
||||
this->camera = this->get_node<Camera3D>("Camera3D");
|
||||
}
|
||||
|
||||
void CarPlayer::_process(double delta_time) { GDGAMEONLY();
|
||||
if(this->roof_slot->get_child_count() > 0 && Time::get_singleton()->get_ticks_msec() * 0.001 > this->end_of_powerup) {
|
||||
this->destroy_all_powerups();
|
||||
}
|
||||
double time = Time::get_singleton()->get_ticks_msec() * 0.001;
|
||||
this->set_visible(time > grace_timer_end || (int(time / this->grace_time_flash) % 2 == 0));
|
||||
|
||||
Vector3 const camera_direction{-(this->get_local_velocity().length() > 3.f ? this->local_to_world_velocity() : this->get_global_basis().get_column(2)).normalized()};
|
||||
this->camera->set_global_position(this->get_global_position() + camera_direction * this->camera_distance + Vector3{0.f, camera_height, 0.f});
|
||||
float speed_fraction = this->get_current_speed() / this->max_speed;
|
||||
this->camera->set_fov(Math::move_toward(float(this->camera->get_fov()), float(this->camera_stopped_fov + (this->camera_fullspeed_fov - this->camera_stopped_fov) * speed_fraction), float(this->fov_lerp_delta * delta_time)));
|
||||
Vector3 const x = Vector3{0.f, 1.f, 0.f}.cross(camera_direction);
|
||||
Vector3 const y = camera_direction.cross(x);
|
||||
this->camera->set_global_basis({x, y, camera_direction});
|
||||
}
|
||||
|
||||
void CarPlayer::setup_player_input(PlayerInput *input) {
|
||||
|
@ -53,11 +64,15 @@ void CarPlayer::on_accelerate(Ref<InputEvent> input, float value) {
|
|||
}
|
||||
|
||||
void CarPlayer::damage() {
|
||||
double time = Time::get_singleton()->get_ticks_msec() * 0.001;
|
||||
if(time < this->grace_timer_end)
|
||||
return;
|
||||
--this->health;
|
||||
if(this->health <= 0) {
|
||||
RallyRushGameMode *game_mode = Ref<RallyRushGameMode>(GameRoot3D::get_singleton()->get_game_mode()).ptr();
|
||||
game_mode->notify_player_death();
|
||||
}
|
||||
this->grace_timer_end = time + this->grace_time;
|
||||
}
|
||||
|
||||
void CarPlayer::destroy_all_powerups() {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define CAR_PLAYER_HPP
|
||||
|
||||
#include "car_physics.hpp"
|
||||
#include "godot_cpp/classes/camera3d.hpp"
|
||||
#include "godot_cpp/classes/packed_scene.hpp"
|
||||
#include "utils/player.hpp"
|
||||
#include <godot_cpp/classes/input_event.hpp>
|
||||
|
@ -42,17 +43,25 @@ private:
|
|||
int health{5};
|
||||
double end_of_powerup{0.0};
|
||||
bool takes_damage{true};
|
||||
float grace_timer_end{0.f};
|
||||
|
||||
Node3D *roof_slot{nullptr};
|
||||
Camera3D *camera{nullptr};
|
||||
|
||||
Ref<PackedScene> turret;
|
||||
Ref<PackedScene> beacon;
|
||||
Ref<PackedScene> shield;
|
||||
|
||||
const float max_speed{40.f};
|
||||
const float max_speed_reverse{10.f};
|
||||
const float steering_factor{0.7f};
|
||||
const float powerup_duration{10.f};
|
||||
float const max_speed{40.f};
|
||||
float const steering_factor{0.7f};
|
||||
float const powerup_duration{10.f};
|
||||
float const camera_distance{4.f};
|
||||
float const camera_height{2.f};
|
||||
float const camera_fullspeed_fov{90.f};
|
||||
float const camera_stopped_fov{70.f};
|
||||
float const fov_lerp_delta{40.f};
|
||||
float const grace_time{1.f};
|
||||
float const grace_time_flash{0.1f};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ void DamageArea::_process(double delta_time) {
|
|||
}
|
||||
|
||||
void DamageArea::body_entered(Node3D *node) {
|
||||
if(this->target_classes.has(node->get_class()) && (!this->car || this->car->get_current_speed() > 30)) {
|
||||
if(this->target_classes.has(node->get_class()) && (!this->car || this->car->get_current_speed() > 10.f)) {
|
||||
node->call("damage");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ void Drone::spawn_explosion() {
|
|||
|
||||
void Drone::key_found(int total) {
|
||||
if(total == 2) {
|
||||
this->speed *= 2;
|
||||
this->speed *= 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ 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_HINTED(guiding_beam_scene, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene");
|
||||
GDPROPERTY(fire_time, Variant::FLOAT);
|
||||
GDPROPERTY(charge_time, Variant::FLOAT);
|
||||
GDPROPERTY(lock_time, Variant::FLOAT);
|
||||
|
@ -125,8 +126,13 @@ void Turret::try_next_state() {
|
|||
return;
|
||||
else this->state = next_state;
|
||||
this->last_state_switch = time;
|
||||
if(state == TurretState::FIRING) {
|
||||
switch(this->state) {
|
||||
case TurretState::FIRING:
|
||||
this->create_beam();
|
||||
break;
|
||||
case TurretState::CHARGING:
|
||||
this->create_guiding_beam();
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,16 +140,27 @@ void Turret::create_beam() {
|
|||
Vector3 const from = this->gun_node->get_global_position();
|
||||
Vector3 const to = from + this->gun_node->get_global_basis().get_column(2) * 1000.f;
|
||||
Ref<PhysicsRayQueryParameters3D> query{PhysicsRayQueryParameters3D::create(from, to)};
|
||||
Dictionary result = this->get_world_3d()->get_direct_space_state()->intersect_ray(query);
|
||||
if(result.is_empty())
|
||||
return;
|
||||
Beam *beam = Object::cast_to<Beam>(this->beam_scene->instantiate());
|
||||
this->add_child(beam);
|
||||
Dictionary result{this->get_world_3d()->get_direct_space_state()->intersect_ray(query)};
|
||||
if(result.is_empty()) return;
|
||||
Beam *beam{Object::cast_to<Beam>(this->beam_scene->instantiate())};
|
||||
this->gun_node->add_child(beam);
|
||||
beam->set_from_to(from, result["position"]);
|
||||
beam->set_end_time(this->fire_time);
|
||||
beam->connect("tree_exited", callable_mp(this, &Turret::beam_ended));
|
||||
}
|
||||
|
||||
void Turret::create_guiding_beam() {
|
||||
Vector3 const from = this->gun_node->get_global_position();
|
||||
Vector3 const to = from + this->gun_node->get_global_basis().get_column(2) * 1000.f;
|
||||
Ref<PhysicsRayQueryParameters3D> query{PhysicsRayQueryParameters3D::create(from, to)};
|
||||
Dictionary result{this->get_world_3d()->get_direct_space_state()->intersect_ray(query)};
|
||||
if(result.is_empty()) return;
|
||||
Beam *beam{Object::cast_to<Beam>(this->guiding_beam_scene->instantiate())};
|
||||
this->gun_node->add_child(beam);
|
||||
beam->set_from_to(from, result["position"]);
|
||||
beam->set_end_time(this->charge_time);
|
||||
}
|
||||
|
||||
void Turret::beam_ended() {
|
||||
this->state = TurretState::LOCKING;
|
||||
this->last_state_switch = Time::get_singleton()->get_ticks_msec() * 0.001f;
|
||||
|
@ -206,4 +223,12 @@ void Turret::set_beam_scene(Ref<PackedScene> scene) {
|
|||
Ref<PackedScene> Turret::get_beam_scene() const {
|
||||
return this->beam_scene;
|
||||
}
|
||||
|
||||
void Turret::set_guiding_beam_scene(Ref<PackedScene> scene) {
|
||||
this->guiding_beam_scene = scene;
|
||||
}
|
||||
|
||||
Ref<PackedScene> Turret::get_guiding_beam_scene() const {
|
||||
return this->guiding_beam_scene;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public:
|
|||
void lose_node(Node3D *node);
|
||||
void try_next_state();
|
||||
void create_beam();
|
||||
|
||||
void create_guiding_beam();
|
||||
|
||||
void beam_ended();
|
||||
|
||||
|
@ -46,6 +46,8 @@ public:
|
|||
Array get_attack_classes() const;
|
||||
void set_beam_scene(Ref<PackedScene> scene);
|
||||
Ref<PackedScene> get_beam_scene() const;
|
||||
void set_guiding_beam_scene(Ref<PackedScene> scene);
|
||||
Ref<PackedScene> get_guiding_beam_scene() const;
|
||||
private:
|
||||
Node3D *current_target{nullptr};
|
||||
bool invert_attack_classes{false};
|
||||
|
@ -63,6 +65,7 @@ private:
|
|||
HashSet<Node3D*> awareness{};
|
||||
|
||||
Ref<PackedScene> beam_scene{};
|
||||
Ref<PackedScene> guiding_beam_scene{};
|
||||
|
||||
float fire_time{1.0f};
|
||||
float charge_time{1.f};
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
#include "weapon_pickup.hpp"
|
||||
#include "car_player.hpp"
|
||||
#include "godot_cpp/classes/random_number_generator.hpp"
|
||||
#include "utils/godot_macros.h"
|
||||
|
||||
namespace godot {
|
||||
void WeaponPickup::_bind_methods() {
|
||||
#define CLASSNAME WeaponPickup
|
||||
}
|
||||
|
||||
void WeaponPickup::_enter_tree() {
|
||||
void WeaponPickup::_enter_tree() { GDGAMEONLY();
|
||||
this->connect("body_entered", callable_mp(this, &WeaponPickup::body_entered));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue