diff --git a/Readme.md b/Readme.md index e7d9d724..35f5a1aa 100644 --- a/Readme.md +++ b/Readme.md @@ -13,7 +13,7 @@ COGITO is made by [Philip Drobar](https://www.philipdrobar.com) with help from [ ## Principles of this template The structure of this template always tries to adhere to the following principles: - **Complete**: When you download COGITO and press play, you get a functioning project out of the box. Game menu, save slot select, options and a playable level are all included. -- **Versatile**: Wether your game is set in the future, the past or the present, use melee, projectile or no weapons at all, have low poly, stylized or realistic graphics, the template will have features for you. +- **Versatile**: Whether your game is set in the future, the past or the present, use melee, projectile or no weapons at all, have low poly, stylized or realistic graphics, the template will have features for you. - **Modular**: Do not want to use a feature? You will be able to hide it, ignore it or strip it out without breaking COGITO. At the same time, COGITO is designed to be extendable with your own custom features or other add-ons. - **Approachable**: While there will always be a learning curve, we strive to make COGTIO approachable and intuitive to use, so it doesn't get in your way of making your game. diff --git a/addons/cogito/Assets/VFX/Impacts/Textures/bulletdecal.png b/addons/cogito/Assets/VFX/Impacts/Textures/bulletdecal.png new file mode 100644 index 00000000..fb247afb Binary files /dev/null and b/addons/cogito/Assets/VFX/Impacts/Textures/bulletdecal.png differ diff --git a/addons/cogito/Assets/VFX/Impacts/Textures/bulletdecal.png.import b/addons/cogito/Assets/VFX/Impacts/Textures/bulletdecal.png.import new file mode 100644 index 00000000..93d95c92 --- /dev/null +++ b/addons/cogito/Assets/VFX/Impacts/Textures/bulletdecal.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://csyaglhc6j7nw" +path.s3tc="res://.godot/imported/bulletdecal.png-c1c0e05ecec82b366bb0b0562d0a9f76.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://addons/cogito/Assets/VFX/Impacts/Textures/bulletdecal.png" +dest_files=["res://.godot/imported/bulletdecal.png-c1c0e05ecec82b366bb0b0562d0a9f76.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/addons/cogito/Assets/VFX/Impacts/bullet_decal.tscn b/addons/cogito/Assets/VFX/Impacts/bullet_decal.tscn new file mode 100644 index 00000000..20360a17 --- /dev/null +++ b/addons/cogito/Assets/VFX/Impacts/bullet_decal.tscn @@ -0,0 +1,7 @@ +[gd_scene load_steps=2 format=3 uid="uid://c2ptmtes2fp8c"] + +[ext_resource type="Texture2D" uid="uid://csyaglhc6j7nw" path="res://addons/cogito/Assets/VFX/Impacts/Textures/bulletdecal.png" id="1_m4v46"] + +[node name="BulletDecal" type="Decal"] +size = Vector3(0.075, 0.075, 0.075) +texture_albedo = ExtResource("1_m4v46") diff --git a/addons/cogito/CogitoObjects/cogito_button.gd b/addons/cogito/CogitoObjects/cogito_button.gd index b1a4112e..a7a5c6cc 100644 --- a/addons/cogito/CogitoObjects/cogito_button.gd +++ b/addons/cogito/CogitoObjects/cogito_button.gd @@ -104,7 +104,7 @@ func press(): object.interact(player_interaction_component) -func _on_damage_received(damage): +func _on_damage_received(_damage,_bullet_direction,_bullet_position): interact(CogitoSceneManager._current_player_node.player_interaction_component) diff --git a/addons/cogito/CogitoObjects/cogito_projectile.gd b/addons/cogito/CogitoObjects/cogito_projectile.gd index c67f9a0c..f87dd8e5 100644 --- a/addons/cogito/CogitoObjects/cogito_projectile.gd +++ b/addons/cogito/CogitoObjects/cogito_projectile.gd @@ -16,6 +16,8 @@ var damage_amount : int = 0 ## Array of Scenes that will get spawned on parent position on death. @export var spawn_on_death : Array[PackedScene] = [] +var Direction + func _ready(): add_to_group("interactable") self.add_to_group("Persist") #Adding object to group for persistence @@ -31,6 +33,9 @@ func on_timeout(): ## Checking collision event for property tags. func _on_body_entered(collider: Node): + var collision_point = global_transform.origin + var bullet_direction = (collision_point - CogitoSceneManager._current_player_node.get_global_transform().origin).normalized() ##This is hacky TODO needs to be fixed for Multiplayer support + if stick_on_impact: self.linear_velocity = Vector3.ZERO self.angular_velocity = Vector3.ZERO @@ -39,12 +44,12 @@ func _on_body_entered(collider: Node): if collider.has_signal("damage_received"): if( !collider.cogito_properties && !cogito_properties): # Case where neither projectile nor the object hit have properties defined. print("Projectile: Collider nor projectile have CogitoProperties, damaging as usual.") - deal_damage(collider) + deal_damage(collider,bullet_direction, collision_point) return if( collider.cogito_properties && !cogito_properties): # Case were only collider has properties. print("Projectile: Collider has CogitoProperties, currently ignoring these and damaging as usual.") - deal_damage(collider) + deal_damage(collider,bullet_direction, collision_point) if( !collider.cogito_properties && cogito_properties): # Case where only the projectile has properties defined. match cogito_properties.material_properties: @@ -59,7 +64,7 @@ func _on_body_entered(collider: Node): if( cogito_properties.material_properties == CogitoProperties.MaterialProperties.SOFT && collider.cogito_properties.material_properties == CogitoProperties.MaterialProperties.SOFT): # When both objects are soft, damage the hit object. print("Projectile: Soft object hit, dealing damage.") - deal_damage(collider) + deal_damage(collider,bullet_direction, collision_point) # Manually setting the reaction collider and calling reactions on object hit, skipping the reaction threshold time. collider.cogito_properties.reaction_collider = self @@ -84,9 +89,11 @@ func stick_to_object(collider: Node): #self.linear_velocity = Vector3.ZERO #self.angular_velocity = Vector3.ZERO -func deal_damage(collider: Node): - print(self.name, ": dealing damage amount ", damage_amount, " on collider ", collider.name) - collider.damage_received.emit(damage_amount) +func deal_damage(collider: Node,bullet_direction,bullet_position): + bullet_direction = Direction + print(self.name, ": dealing damage amount ", damage_amount, " on collider ", collider.name, " at ",bullet_position, " in direction ", Direction ) + + collider.damage_received.emit(damage_amount,bullet_direction,bullet_position) if destroy_on_impact: die() diff --git a/addons/cogito/CogitoObjects/cogito_switch.gd b/addons/cogito/CogitoObjects/cogito_switch.gd index 9e3305f3..78c2eb51 100644 --- a/addons/cogito/CogitoObjects/cogito_switch.gd +++ b/addons/cogito/CogitoObjects/cogito_switch.gd @@ -129,7 +129,7 @@ func check_for_item() -> bool: player_interaction_component.send_hint(null,item_hint) # Sends the key hint with the default hint icon. return false -func _on_damage_received(): +func _on_damage_received(_damage,_bullet_direction,_bullet_position): interact(CogitoSceneManager._current_player_node.player_interaction_component) func set_state(): diff --git a/addons/cogito/Components/HitboxComponent.gd b/addons/cogito/Components/HitboxComponent.gd index dfbb602a..57fd8683 100644 --- a/addons/cogito/Components/HitboxComponent.gd +++ b/addons/cogito/Components/HitboxComponent.gd @@ -2,6 +2,16 @@ extends Node class_name HitboxComponent @export var health_attribute : CogitoHealthAttribute +## PackedScene that will get spawned on global hit position +@export var spawn_at_global_collision: PackedScene +## PackedScene that will get spawned on parents local hit position +@export var spawn_at_local_collision: PackedScene +## Apply force to Rigidbodies on hit +@export var apply_force_on_hit : bool +## Multiplier of force applied to rigidbody, if force apply is true +@export var applied_force_multipler : int + +@onready var parent = get_parent() func _ready() -> void: if get_parent().has_signal("damage_received"): @@ -10,6 +20,27 @@ func _ready() -> void: else: print("HitboxComponent: Parent ", get_parent().name, " is missing a damage_received() signal.") -func damage(damage_amount:float): + +func damage(damage_amount: float, _hit_direction:= Vector3.ZERO, _hit_position:= Vector3.ZERO): + if health_attribute: health_attribute.subtract(damage_amount) + + if spawn_at_global_collision != null: + var spawned_object = spawn_at_global_collision.instantiate() + spawned_object.position = _hit_position + get_tree().current_scene.add_child(spawned_object) + + if spawn_at_local_collision != null: + var local_hit_position = parent.to_local(_hit_position) + var spawned_object = spawn_at_local_collision.instantiate() + spawned_object.position = local_hit_position + parent.add_child(spawned_object) + + if apply_force_on_hit: + ##TODO Handle CharacterBody3D for NPC knockback + if parent is RigidBody3D: + parent.apply_impulse(_hit_direction * damage_amount * applied_force_multipler, _hit_position) + if parent is CharacterBody3D: + parent.apply_knockback(_hit_direction *damage_amount * applied_force_multipler) + diff --git a/addons/cogito/Components/HitboxComponent.tscn b/addons/cogito/Components/HitboxComponent.tscn index 11431f0a..e26b429a 100644 --- a/addons/cogito/Components/HitboxComponent.tscn +++ b/addons/cogito/Components/HitboxComponent.tscn @@ -4,3 +4,5 @@ [node name="HitboxComponent" type="Node"] script = ExtResource("1_7oy1x") +apply_force_on_hit = true +applied_force_multipler = 2 diff --git a/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn b/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn index f5d73e67..0c2e44cf 100644 --- a/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn +++ b/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn @@ -84,7 +84,7 @@ volumetric_fog_ambient_inject = 0.1 volumetric_fog_sky_affect = 0.1 volumetric_fog_temporal_reprojection_amount = 0.85 -[sub_resource type="Resource" id="Resource_n6ij1"] +[sub_resource type="Resource" id="Resource_2sxlv"] resource_local_to_scene = true script = ExtResource("4_hlewe") grid = true @@ -897,7 +897,7 @@ environment = SubResource("Environment_obnk3") [node name="Player" parent="." instance=ExtResource("2_7qwrr")] transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 5.13854, 0.8, -5.43073) -inventory_data = SubResource("Resource_n6ij1") +inventory_data = SubResource("Resource_2sxlv") [node name="CONNECTOR_TO_LOBBY" type="Node3D" parent="."] diff --git a/addons/cogito/Enemies/cogito_basic_enemy.gd b/addons/cogito/Enemies/cogito_basic_enemy.gd index 42909ba3..17596453 100644 --- a/addons/cogito/Enemies/cogito_basic_enemy.gd +++ b/addons/cogito/Enemies/cogito_basic_enemy.gd @@ -81,6 +81,16 @@ var can_play_footstep: bool = true var wiggle_vector : Vector2 = Vector2.ZERO var wiggle_index : float = 0.0 +var knockback_force: Vector3 = Vector3.ZERO +var knockback_timer: float = 0.0 +@export var knockback_duration: float = 0.5 +@export var knockback_strength: float = 10.0 + + +func apply_knockback(direction: Vector3): + knockback_force = direction.normalized() * knockback_strength + knockback_timer = knockback_duration + func _enter_tree() -> void: current_state = EnemyState.IDLE @@ -102,7 +112,14 @@ func find_cogito_properties(): func _physics_process(delta: float) -> void: if attack_cooldown > 0: attack_cooldown -= delta - + + if knockback_timer > 0: + knockback_timer -= delta + velocity = knockback_force + knockback_force = lerp(knockback_force, Vector3.ZERO, delta * 5) + move_and_slide() + return + match current_state: EnemyState.PATROLLING: handle_patrolling(delta) diff --git a/addons/cogito/Enemies/cogito_basic_enemy.tscn b/addons/cogito/Enemies/cogito_basic_enemy.tscn index e5af46d5..0e278cc7 100644 --- a/addons/cogito/Enemies/cogito_basic_enemy.tscn +++ b/addons/cogito/Enemies/cogito_basic_enemy.tscn @@ -6,9 +6,9 @@ [ext_resource type="AudioStream" uid="uid://bd7xfxmsaeu0o" path="res://addons/cogito/Assets/Audio/435666__mirkosukovic__alarm-siren.wav" id="3_7u8yw"] [ext_resource type="PackedScene" uid="uid://cqgg1nng0vvbh" path="res://addons/cogito/Components/Attributes/HealthAttribute.tscn" id="4_y8n8v"] [ext_resource type="PackedScene" uid="uid://bc2hryr610vgo" path="res://addons/cogito/PackedScenes/simple_particle_puff.tscn" id="5_ni6ul"] -[ext_resource type="Script" path="res://addons/cogito/Components/HitboxComponent.gd" id="5_qh1ls"] [ext_resource type="PackedScene" uid="uid://crv3r7dscbxlx" path="res://addons/cogito/Enemies/body/basic_enemy_corpse.tscn" id="7_8vdb4"] [ext_resource type="PackedScene" uid="uid://cj0yaeh3yg7tu" path="res://addons/cogito/Components/Properties/CogitoProperties.tscn" id="7_15n6t"] +[ext_resource type="PackedScene" uid="uid://k28yrbg3k3pw" path="res://addons/cogito/Components/HitboxComponent.tscn" id="8_lq5js"] [ext_resource type="AudioStream" uid="uid://up2hfhgq1qx6" path="res://addons/cogito/Assets/Audio/Kenney/Footsteps/footstep00.ogg" id="8_vyi83"] [ext_resource type="AudioStream" uid="uid://crj07wq4oocwi" path="res://addons/cogito/Assets/Audio/Kenney/Footsteps/footstep01.ogg" id="9_5fsuu"] [ext_resource type="AudioStream" uid="uid://dewyukd562k37" path="res://addons/cogito/Assets/Audio/Kenney/Footsteps/footstep02.ogg" id="10_ab7fy"] @@ -55,7 +55,6 @@ stream_4/stream = ExtResource("12_3m7c4") stream_4/weight = 1.0 [node name="CogitoEnemy" type="CharacterBody3D"] -motion_mode = 1 script = ExtResource("1_0lcvu") attack_stagger = 20.0 attack_sound = ExtResource("2_q5685") @@ -86,7 +85,6 @@ script = ExtResource("2_6jysp") detection_ray_cast_3d = NodePath("DetectionRayCast3D") indicator_light = NodePath("../Mesh_Body/Mesh_Face/IndicatorLight") detection_area = NodePath("DetectionArea3D") -spot_time = 2.0 alarm_sound = ExtResource("3_7u8yw") indicator_mesh = NodePath("../Mesh_Body/Mesh_Face") @@ -116,8 +114,7 @@ spawn_on_death = Array[PackedScene]([ExtResource("5_ni6ul"), ExtResource("7_8vdb value_max = 5.0 value_start = 5.0 -[node name="HitboxComponent" type="Node" parent="." node_paths=PackedStringArray("health_attribute")] -script = ExtResource("5_qh1ls") +[node name="HitboxComponent" parent="." node_paths=PackedStringArray("health_attribute") instance=ExtResource("8_lq5js")] health_attribute = NodePath("../HealthAttribute") [node name="CogitoProperties" parent="." instance=ExtResource("7_15n6t")] diff --git a/addons/cogito/PackedScenes/Pickups/pickup_laser_rifle.tscn b/addons/cogito/PackedScenes/Pickups/pickup_laser_rifle.tscn index ff714584..d474ba33 100644 --- a/addons/cogito/PackedScenes/Pickups/pickup_laser_rifle.tscn +++ b/addons/cogito/PackedScenes/Pickups/pickup_laser_rifle.tscn @@ -135,11 +135,12 @@ size = Vector3(0.0973389, 0.0952759, 0.815624) [sub_resource type="BoxShape3D" id="BoxShape3D_5bhcv"] size = Vector3(0.0973389, 0.0457916, 0.443713) -[sub_resource type="Resource" id="Resource_4kc11"] +[sub_resource type="Resource" id="Resource_fmssf"] resource_local_to_scene = true script = ExtResource("3_iw0du") inventory_item = ExtResource("3_auoh1") quantity = 1 +origin_index = -1 [node name="Pickup_LaserRifle" type="RigidBody3D"] collision_layer = 3 @@ -166,4 +167,4 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00152874, 0.187482, 0.03864 shape = SubResource("BoxShape3D_5bhcv") [node name="PickupComponent" parent="." instance=ExtResource("2_3uch0")] -slot_data = SubResource("Resource_4kc11") +slot_data = SubResource("Resource_fmssf") diff --git a/addons/cogito/PackedScenes/projectile_pistol.tscn b/addons/cogito/PackedScenes/projectile_pistol.tscn index 0df335e9..bd97d63b 100644 --- a/addons/cogito/PackedScenes/projectile_pistol.tscn +++ b/addons/cogito/PackedScenes/projectile_pistol.tscn @@ -23,7 +23,7 @@ rings = 1 height = 0.25 radius = 0.05 -[sub_resource type="Resource" id="Resource_s1k6p"] +[sub_resource type="Resource" id="Resource_w3sph"] resource_local_to_scene = true script = ExtResource("4_tbkmk") inventory_item = ExtResource("3_7etap") @@ -62,7 +62,7 @@ wait_time = 30.0 autostart = true [node name="PickupComponent" parent="." instance=ExtResource("4_acy7b")] -slot_data = SubResource("Resource_s1k6p") +slot_data = SubResource("Resource_w3sph") [node name="CogitoProperties" parent="." instance=ExtResource("5_6jfy1")] material_properties = 1 diff --git a/addons/cogito/Scripts/bullet_decal_pool.gd b/addons/cogito/Scripts/bullet_decal_pool.gd new file mode 100644 index 00000000..056c5eb1 --- /dev/null +++ b/addons/cogito/Scripts/bullet_decal_pool.gd @@ -0,0 +1,32 @@ +##Credit to Majikayo Games SimpleFPSController for this code +##https://github.com/majikayogames/SimpleFPSController + +class_name BulletDecalPool + +const MAX_BULLET_DECALS = 1000 +static var decal_pool := [] + +static func spawn_bullet_decal(global_pos : Vector3, normal : Vector3, parent : Node3D, bullet_basis : Basis, texture_override = null): + var decal_instance : Node3D + if len(decal_pool) >= MAX_BULLET_DECALS and is_instance_valid(decal_pool[0]): + decal_instance = decal_pool.pop_front() + decal_pool.push_back(decal_instance) + decal_instance.reparent(parent) + else: + decal_instance = preload("res://addons/cogito/Assets/VFX/Impacts/bullet_decal.tscn").instantiate() + parent.add_child(decal_instance) + decal_pool.push_back(decal_instance) + + # Clear invalid if necessary. Parent may have gotten .queue_free()'d + if not is_instance_valid(decal_pool[0]): + decal_pool.pop_front() + + # Rotate decal towards player for things like horizontal knife slash decals + decal_instance.global_transform = Transform3D(bullet_basis, global_pos) * Transform3D(Basis().rotated(Vector3(1,0,0), deg_to_rad(90)), Vector3()) + # Align to surface + decal_instance.global_basis = Basis(Quaternion(decal_instance.global_basis.y, normal)) * decal_instance.global_basis + + #decal_instance.get_node("GPUParticles3D").emitting = true + + if texture_override is Texture2D: + decal_instance.texture_albedo = texture_override diff --git a/addons/cogito/Wieldables/laser_rifle.tscn b/addons/cogito/Wieldables/laser_rifle.tscn index 5e6f506a..e2e45803 100644 --- a/addons/cogito/Wieldables/laser_rifle.tscn +++ b/addons/cogito/Wieldables/laser_rifle.tscn @@ -2,8 +2,8 @@ [ext_resource type="Script" path="res://addons/cogito/Wieldables/wieldable_laser_rifle.gd" id="1_2rut3"] [ext_resource type="AudioStream" uid="uid://clsajk36s7luk" path="res://addons/cogito/Assets/Audio/Kenney/error_004.ogg" id="2_f7ale"] -[ext_resource type="Resource" uid="uid://txiu5yxexevm" path="res://addons/cogito/InventoryPD/Items/Cogito_LaserRifle.tres" id="2_i0fx0"] [ext_resource type="PackedScene" uid="uid://dnauxhdncgngx" path="res://addons/cogito/PackedScenes/laser_ray.tscn" id="2_ic084"] +[ext_resource type="PackedScene" uid="uid://bc2hryr610vgo" path="res://addons/cogito/PackedScenes/simple_particle_puff.tscn" id="3_aueyu"] [ext_resource type="AnimationLibrary" uid="uid://c1du0rcgmr542" path="res://addons/cogito/Wieldables/Animations/Wieldable_LaserRifle.res" id="3_fjq23"] [ext_resource type="Script" path="res://addons/cogito/Assets/Shader/ViewmodelSpace.gd" id="5_fa3wp"] @@ -269,6 +269,7 @@ script = ExtResource("1_2rut3") laser_ray_prefab = ExtResource("2_ic084") ray_lifespan = 3.0 default_position = Vector3(0.329, -0.264, -0.535) +collision_scene = ExtResource("3_aueyu") sound_primary_use = ExtResource("2_f7ale") wieldable_mesh = NodePath("LaserRifleMesh") anim_equip = "LaserRifle/equip" diff --git a/addons/cogito/Wieldables/wieldable_laser_rifle.gd b/addons/cogito/Wieldables/wieldable_laser_rifle.gd index d547bb68..d677dab6 100644 --- a/addons/cogito/Wieldables/wieldable_laser_rifle.gd +++ b/addons/cogito/Wieldables/wieldable_laser_rifle.gd @@ -14,6 +14,14 @@ extends CogitoWieldable ## Default position for tweening from ADS @export var default_position : Vector3 +@export_group("Collisions") +## Spawn hit decal on Collision hit +@export var decal_spawn : bool = true +## Hit decal texture, if blank will be set to default bullet decal texture +@export var decal_texture : Texture2D +## Scene that spawns when a bullet of the weapon collides with anything +@export var collision_scene : PackedScene + @export_group("Audio") @export var sound_primary_use : AudioStream @export var sound_secondary_use : AudioStream @@ -103,12 +111,31 @@ func hit_scan_collision(collision_point:Vector3): spawn_node.add_child(instantiated_ray) if bullet_collision: - hit_scan_damage(bullet_collision.collider) + hit_scan_damage(bullet_collision.collider, bullet_direction, bullet_collision.position) + + if collision_scene !=null: + hit_scan_scene(bullet_collision) + + if decal_spawn == true: + var bullet_collider = bullet_collision.collider + var bullet_collision_position = bullet_collision.position + var bullet_collision_normal = bullet_collision.normal + var bullet_global_basis = bullet_point.get_global_transform().basis + # Spawn bullet decal with collision parameters + BulletDecalPool.spawn_bullet_decal(bullet_collision_position, bullet_collision_normal, bullet_collider, bullet_global_basis,decal_texture) -func hit_scan_damage(collider): +func hit_scan_damage(collider, bullet_direction, bullet_position): if collider.has_signal("damage_received"): - collider.damage_received.emit(item_reference.wieldable_damage) + collider.damage_received.emit(item_reference.wieldable_damage,bullet_direction,bullet_position) + + +func hit_scan_scene(bullet_collision): + if collision_scene !=null: + var hit_indicator = collision_scene.instantiate() + var world = get_tree().get_root().get_child(0) + world.add_child(hit_indicator) + hit_indicator.global_translate(bullet_collision.position) # Function called when wieldable reload is attempted diff --git a/addons/cogito/Wieldables/wieldable_pickaxe.gd b/addons/cogito/Wieldables/wieldable_pickaxe.gd index bf54edeb..ef1a847b 100644 --- a/addons/cogito/Wieldables/wieldable_pickaxe.gd +++ b/addons/cogito/Wieldables/wieldable_pickaxe.gd @@ -4,6 +4,8 @@ extends CogitoWieldable @export var damage_area : Area3D @export var uses_stamina : bool = false @export var stamina_cost : int = 4 +##Collision hit can be defined using Camera-Collider raycast, or Hitbox-Collider raycast. Camera-Collider is more reliable but less accurate, Hitbox-collider is more accurate but less reliable +@export var use_camera_collision : bool @export_group("Audio") @export var swing_sound : AudioStream @@ -11,14 +13,16 @@ extends CogitoWieldable var trigger_has_been_pressed : bool = false var player_stamina : CogitoAttribute = null + func _ready(): if wieldable_mesh: wieldable_mesh.hide() damage_area.body_entered.connect(_on_body_entered) - + if uses_stamina: player_stamina = grab_player_stamina_attribute() + func grab_player_stamina_attribute() -> CogitoAttribute: @@ -53,4 +57,25 @@ func action_primary(_passed_item_reference:InventoryItemPD, _is_released: bool): func _on_body_entered(collider): if collider.has_signal("damage_received"): - collider.damage_received.emit(item_reference.wieldable_damage) + var player = player_interaction_component.get_parent() + var hit_position : Vector3 + var bullet_direction : Vector3 + + if use_camera_collision: + #Camera-Collider raycast + hit_position = player_interaction_component.Get_Camera_Collision() + bullet_direction = (hit_position - player.get_global_transform().origin).normalized() + else: + #Hitbox-Collider raycast + var space_state = damage_area.get_world_3d().direct_space_state + var hitbox_origin = damage_area.global_transform.origin + var ray_params = PhysicsRayQueryParameters3D.new() + ray_params.from = hitbox_origin + ray_params.to = collider.global_transform.origin + var result = space_state.intersect_ray(ray_params) + if result.size() > 0: + hit_position = result.position + bullet_direction = (hit_position - hitbox_origin).normalized() + + collider.damage_received.emit(item_reference.wieldable_damage, bullet_direction, hit_position) + diff --git a/addons/cogito/Wieldables/wieldable_toy_pistol.gd b/addons/cogito/Wieldables/wieldable_toy_pistol.gd index ccff3030..905903a9 100644 --- a/addons/cogito/Wieldables/wieldable_toy_pistol.gd +++ b/addons/cogito/Wieldables/wieldable_toy_pistol.gd @@ -69,6 +69,7 @@ func action_primary(_passed_item_reference : InventoryItemPD, _is_released: bool Projectile.global_transform.basis = bullet_point.global_transform.basis Projectile.damage_amount = _passed_item_reference.wieldable_damage Projectile.set_linear_velocity(Direction * projectile_velocity) + Projectile.Direction = Direction Projectile.reparent(get_tree().get_current_scene())