From eabc137ce8dc958bf2422f434111e46742fd13cf Mon Sep 17 00:00:00 2001 From: Rendo Date: Sun, 14 Dec 2025 03:05:17 +0500 Subject: [PATCH] First ever primary weapon --- gui/buy_menu/buy_button/buy_button.tscn | 9 +-- gui/buy_menu/buy_menu.tscn | 18 +++-- levels/prototype.tscn | 2 +- multiplayer/session.gd | 48 +++++++++++++ players/molikman.tscn | 2 +- project.godot | 4 ++ weapons/gun/mc/droppable_mc.tscn | 36 ++++++++++ weapons/gun/mc/mc255.tscn | 69 +++++++++++++++++++ weapons/gun/semi_pellet_shoot_state.gd | 55 +++++++++++++++ weapons/gun/semi_pellet_shoot_state.gd.uid | 1 + ...uto_shoot_state.gd => semi_shoot_state.gd} | 0 ...t_state.gd.uid => semi_shoot_state.gd.uid} | 0 weapons/gun/sp/starting_pistol.tscn | 2 +- weapons/mc.tres | 6 +- 14 files changed, 237 insertions(+), 15 deletions(-) create mode 100644 weapons/gun/mc/droppable_mc.tscn create mode 100644 weapons/gun/mc/mc255.tscn create mode 100644 weapons/gun/semi_pellet_shoot_state.gd create mode 100644 weapons/gun/semi_pellet_shoot_state.gd.uid rename weapons/gun/{semi_auto_shoot_state.gd => semi_shoot_state.gd} (100%) rename weapons/gun/{semi_auto_shoot_state.gd.uid => semi_shoot_state.gd.uid} (100%) diff --git a/gui/buy_menu/buy_button/buy_button.tscn b/gui/buy_menu/buy_button/buy_button.tscn index 6a5f424..529f60b 100644 --- a/gui/buy_menu/buy_button/buy_button.tscn +++ b/gui/buy_menu/buy_button/buy_button.tscn @@ -4,11 +4,12 @@ [ext_resource type="Script" uid="uid://bq32y7eee1f63" path="res://gui/buy_menu/buy_button/buy_button.gd" id="1_impj7"] [node name="BuyButton" type="Button"] +custom_minimum_size = Vector2(64, 96) anchors_preset = -1 -anchor_right = 0.035 -anchor_bottom = 0.075 -offset_right = -4.799999 -offset_bottom = -14.000004 +anchor_right = 0.05 +anchor_bottom = 0.133 +offset_right = -24.0 +offset_bottom = -55.760002 text = "3600" icon = ExtResource("1_apu4l") icon_alignment = 1 diff --git a/gui/buy_menu/buy_menu.tscn b/gui/buy_menu/buy_menu.tscn index e8e76a0..13951d2 100644 --- a/gui/buy_menu/buy_menu.tscn +++ b/gui/buy_menu/buy_menu.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=5 format=3 uid="uid://j5lgbg8c0pq"] +[gd_scene load_steps=6 format=3 uid="uid://j5lgbg8c0pq"] [ext_resource type="PackedScene" uid="uid://b1ej6kmbjpm78" path="res://gui/buy_menu/buy_button/buy_button.tscn" id="1_8guql"] [ext_resource type="Script" uid="uid://dba17sgimp4j0" path="res://gui/buy_menu/buy_menu.gd" id="1_ko0fn"] [ext_resource type="Resource" uid="uid://b081hg7uxx1wu" path="res://weapons/mm_molik.tres" id="2_0gws3"] [ext_resource type="Script" uid="uid://dk4diwvruvkch" path="res://gui/buy_menu/player_money_label.gd" id="2_ll0n6"] +[ext_resource type="Resource" uid="uid://x1as1lkonk54" path="res://weapons/mc.tres" id="4_8uk5y"] [node name="BuyMenu" type="ColorRect"] anchors_preset = 15 @@ -26,21 +27,24 @@ mouse_filter = 2 [node name="PanelContainer" type="PanelContainer" parent="CenterContainer"] layout_mode = 2 -[node name="AbilitiesContainer" type="VBoxContainer" parent="CenterContainer/PanelContainer"] +[node name="WeaponsContainer" type="VBoxContainer" parent="CenterContainer/PanelContainer"] layout_mode = 2 -[node name="Label" type="Label" parent="CenterContainer/PanelContainer/AbilitiesContainer"] +[node name="Label" type="Label" parent="CenterContainer/PanelContainer/WeaponsContainer"] layout_mode = 2 script = ExtResource("2_ll0n6") -[node name="WeaponsContainer" type="GridContainer" parent="CenterContainer/PanelContainer/AbilitiesContainer"] +[node name="WeaponsContainer" type="GridContainer" parent="CenterContainer/PanelContainer/WeaponsContainer"] layout_mode = 2 columns = 5 -[node name="HBoxContainer" type="HBoxContainer" parent="CenterContainer/PanelContainer/AbilitiesContainer"] +[node name="BuyButton" parent="CenterContainer/PanelContainer/WeaponsContainer/WeaponsContainer" instance=ExtResource("1_8guql")] +layout_mode = 2 +weapon = ExtResource("4_8uk5y") + +[node name="AbilitiesContainer" type="HBoxContainer" parent="CenterContainer/PanelContainer/WeaponsContainer"] layout_mode = 2 -[node name="BuyButton" parent="CenterContainer/PanelContainer/AbilitiesContainer/HBoxContainer" instance=ExtResource("1_8guql")] -custom_minimum_size = Vector2(64, 96) +[node name="MolotovButton" parent="CenterContainer/PanelContainer/WeaponsContainer/AbilitiesContainer" instance=ExtResource("1_8guql")] layout_mode = 2 weapon = ExtResource("2_0gws3") diff --git a/levels/prototype.tscn b/levels/prototype.tscn index 2204a83..6354cc1 100644 --- a/levels/prototype.tscn +++ b/levels/prototype.tscn @@ -298,7 +298,7 @@ script = ExtResource("11_02ic3") exlusion_list = [NodePath("MultiplayerSpawner"), NodePath("Bomb"), NodePath("Parenter")] [node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="DynamicObjectsContainer"] -_spawnable_scenes = PackedStringArray("uid://cxdgk74ln5xpn", "uid://dtbpyfdawb02b", "uid://dgfqppi21c2u0", "uid://b6qahd6q60js7", "uid://l4t1mflutm3t") +_spawnable_scenes = PackedStringArray("uid://cxdgk74ln5xpn", "uid://dtbpyfdawb02b", "uid://dgfqppi21c2u0", "uid://b6qahd6q60js7", "uid://l4t1mflutm3t", "uid://b3xux7url8d2s") spawn_path = NodePath("..") [node name="Parenter" type="Node" parent="DynamicObjectsContainer"] diff --git a/multiplayer/session.gd b/multiplayer/session.gd index 57afe4f..7e4ef1a 100644 --- a/multiplayer/session.gd +++ b/multiplayer/session.gd @@ -346,6 +346,54 @@ func shoot(id:int , limb_damage: int, torso_damage: int,head_damage: int, distan hit_player.take_damage(int(float(damage) * reduction)) +func shoot_pellets(id:int,amount: int, limb_total_damage: int, torso_total_damage: int,head_total_damage: int, distance: float, arc: float, damage_reduction_curve: Curve = null): + if multiplayer.is_server() == false: + return + + var player: Player = player_nodes[id] + var player_camera: Camera3D = player.get_node("Camera3D") + var space: PhysicsDirectSpaceState3D = player.get_world_3d().direct_space_state + var head_damage: int = head_total_damage / amount + var torso_damage: int = torso_total_damage / amount + var limb_damage: int = limb_total_damage / amount + + for i in range(amount): + var endpoint: Vector3 = player_camera.global_position - player_camera.global_basis.z.rotated(Vector3.RIGHT,randf_range(-arc/2,arc/2)).rotated(Vector3.UP,randf_range(-arc/2,arc/2)) * distance + + var ray = PhysicsRayQueryParameters3D.create(player_camera.global_position,endpoint,1) + ray.exclude = [player.get_rid()] + ray.collide_with_areas = false + match player.team: + TEAMS.DEFENCE: + ray.collision_mask |= ATTACK_LAYER + TEAMS.ATTACK: + ray.collision_mask |= DEFENCE_LAYER + _: + ray.collision_mask |= ATTACK_LAYER | DEFENCE_LAYER + + var collision = space.intersect_ray(ray) + + + if collision != {} and collision["collider"] is Player: + var hit_player: Player = collision["collider"] + var shape_object: CollisionShape3D = hit_player.shape_owner_get_owner(collision["shape"]) + var reduction: float = 1 + var damage: int = 0 + + match shape_object.get_groups()[0]: + "Head": + damage = head_damage + "Limb": + damage = limb_damage + _: + damage = torso_damage + + if damage_reduction_curve != null: + var distance_to_hit = (player_camera.global_position - collision["position"]).length()/distance + reduction = damage_reduction_curve.sample(distance_to_hit) + + hit_player.take_damage(int(float(damage) * reduction)) + func interact(id: int) -> void: if multiplayer.is_server() == false: return diff --git a/players/molikman.tscn b/players/molikman.tscn index 737639b..b35b9cc 100644 --- a/players/molikman.tscn +++ b/players/molikman.tscn @@ -1231,7 +1231,7 @@ player = NodePath("..") player_input = NodePath("../PlayerInput") [node name="WeaponSpawner" type="MultiplayerSpawner" parent="WeaponSystem"] -_spawnable_scenes = PackedStringArray("uid://djwjl8xll53vn", "uid://ts4xccpkjd3g", "uid://bxdatd1ilfgmc", "uid://c5q7e5dj86187") +_spawnable_scenes = PackedStringArray("uid://djwjl8xll53vn", "uid://ts4xccpkjd3g", "uid://bxdatd1ilfgmc", "uid://c5q7e5dj86187", "uid://8ohlfmr5bp0k") spawn_path = NodePath("..") [node name="StartingWeaponSpawner" type="Node" parent="WeaponSystem" node_paths=PackedStringArray("weapon_system")] diff --git a/project.godot b/project.godot index 27ba90e..638ab73 100644 --- a/project.godot +++ b/project.godot @@ -29,6 +29,10 @@ Registry="*res://systems/registry.gd" Shop="*res://gui/buy_menu/shop.gd" MouseConfiner="*res://gui/mouse_confiner.gd" +[debug] + +gdscript/warnings/integer_division=0 + [display] window/size/viewport_width=1280 diff --git a/weapons/gun/mc/droppable_mc.tscn b/weapons/gun/mc/droppable_mc.tscn new file mode 100644 index 0000000..4c47165 --- /dev/null +++ b/weapons/gun/mc/droppable_mc.tscn @@ -0,0 +1,36 @@ +[gd_scene load_steps=6 format=3 uid="uid://b3xux7url8d2s"] + +[ext_resource type="Script" uid="uid://cskgqgkr7pmb0" path="res://systems/weapon_system/dropped_weapon.gd" id="1_xr2im"] +[ext_resource type="PackedScene" uid="uid://8ohlfmr5bp0k" path="res://weapons/gun/mc/mc255.tscn" id="2_nf8ho"] +[ext_resource type="PackedScene" uid="uid://b57k7qap3jn6a" path="res://models/weapons/mc255.glb" id="3_nf8ho"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_477rq"] +size = Vector3(0.122802734, 0.3173828, 1.263977) + +[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_ddvbd"] +properties/0/path = NodePath(".:position") +properties/0/spawn = true +properties/0/replication_mode = 1 +properties/1/path = NodePath(".:rotation") +properties/1/spawn = true +properties/1/replication_mode = 1 + +[node name="DroppableMC255" type="RigidBody3D" node_paths=PackedStringArray("weapon")] +collision_layer = 8 +collision_mask = 9 +continuous_cd = true +script = ExtResource("1_xr2im") +slot = &"primary" +weapon = NodePath("MC255") +team = 3 + +[node name="MC255" parent="." instance=ExtResource("2_nf8ho")] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -3.0517578e-05, 0.25790405) +shape = SubResource("BoxShape3D_477rq") + +[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] +replication_config = SubResource("SceneReplicationConfig_ddvbd") + +[node name="mc255" parent="." instance=ExtResource("3_nf8ho")] diff --git a/weapons/gun/mc/mc255.tscn b/weapons/gun/mc/mc255.tscn new file mode 100644 index 0000000..883b5c7 --- /dev/null +++ b/weapons/gun/mc/mc255.tscn @@ -0,0 +1,69 @@ +[gd_scene load_steps=10 format=3 uid="uid://8ohlfmr5bp0k"] + +[ext_resource type="Script" uid="uid://e6lqknfl4ngt" path="res://systems/weapon_system/weapon_substate_machine.gd" id="1_uck67"] +[ext_resource type="Script" uid="uid://ofv4e3dsfe8" path="res://weapons/gun/idle_state.gd" id="2_rkf02"] +[ext_resource type="Script" uid="uid://cvueeftqbxb7r" path="res://weapons/gun/semi_pellet_shoot_state.gd" id="3_jk5g7"] +[ext_resource type="Script" uid="uid://hmekwp8444ao" path="res://weapons/gun/reload_state.gd" id="4_fs8hh"] +[ext_resource type="Script" uid="uid://bmj0bwy2tlian" path="res://weapons/gun/intro_state.gd" id="5_3ok4b"] + +[sub_resource type="Curve" id="Curve_cmn6f"] +_limits = [0.0, 0.1, 0.0, 20.0] +_data = [Vector2(0, 0.1), 0.0, 0.0, 0, 0, Vector2(20, 0.1), -2.2834061e-05, 0.0, 0, 0] +point_count = 2 +metadata/_snap_enabled = true +metadata/_snap_count = 8 + +[sub_resource type="Curve" id="Curve_jk5g7"] + +[sub_resource type="Curve" id="Curve_bwg3m"] +_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(0.25301203, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_bwg3m"] +properties/0/path = NodePath(".:ammo") +properties/0/spawn = true +properties/0/replication_mode = 2 +properties/1/path = NodePath(".:remaining_ammo") +properties/1/spawn = true +properties/1/replication_mode = 2 + +[node name="MC255" type="Node" node_paths=PackedStringArray("enter_state")] +script = ExtResource("1_uck67") +animation_prefix = &"baked_mc_" +weapon_gid = &"mc" +max_ammo = 5 +ammo_mags = 8 +speed_modifier = 0.9 +slot = &"primary" +enter_state = NodePath("Intro") +metadata/_custom_type_script = "uid://e6lqknfl4ngt" + +[node name="Idle" type="Node" parent="."] +script = ExtResource("2_rkf02") + +[node name="Shoot" type="Node" parent="." node_paths=PackedStringArray("fire_timer")] +script = ExtResource("3_jk5g7") +vertical_curve = SubResource("Curve_cmn6f") +horizontal_curve = SubResource("Curve_jk5g7") +damage_reduction_curve = SubResource("Curve_bwg3m") +torso_total_damage = 100 +head_total_damage = 150 +limb_total_damage = 70 +arc = 0.08726646259971647 +max_pellets = 30 +min_pellets = 30 +shoot_distance = 40.0 +fire_timer = NodePath("../FireTimer") + +[node name="Reload" type="Node" parent="."] +script = ExtResource("4_fs8hh") + +[node name="Intro" type="Node" parent="."] +script = ExtResource("5_3ok4b") + +[node name="FireTimer" type="Timer" parent="."] +wait_time = 2.0 +one_shot = true + +[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] +replication_config = SubResource("SceneReplicationConfig_bwg3m") diff --git a/weapons/gun/semi_pellet_shoot_state.gd b/weapons/gun/semi_pellet_shoot_state.gd new file mode 100644 index 0000000..5210493 --- /dev/null +++ b/weapons/gun/semi_pellet_shoot_state.gd @@ -0,0 +1,55 @@ +extends WeaponState + +@export var vertical_curve: Curve +@export var horizontal_curve: Curve +@export var damage_reduction_curve: Curve + +@export var emptyable: bool +@export var torso_total_damage: int +@export var head_total_damage: int +@export var limb_total_damage: int +@export_range(0,179,0.01,"radians_as_degrees") var arc: float +@export_range(1,20,1,"or_greater") var max_pellets: int = 1 +@export_range(1,20,1,"or_greater") var min_pellets: int = 1 +@export var shoot_distance: float = 100 + +@export var fire_timer: Timer + +var bullets_shot: int = 0 + +func _enter() -> void: + fire() + machine.animation_player.animation_finished.connect(on_animation_finished) + +func _exit() -> void: + bullets_shot = 0 + machine.animation_player.animation_finished.disconnect(on_animation_finished) + +func on_animation_finished(animation): + if animation == with_morphems("shoot"): + transition.emit("Idle") + +func _use_begin() -> void: + if fire_timer.time_left > 0: + return + fire() + +func fire() -> void: + if machine.ammo == 0 or fire_timer.time_left > 0: + return + machine.ammo -= 1 + bullets_shot += 1 + + machine.animation_player.stop() + machine.animation_player.play(with_morphems("shoot")) + + if is_multiplayer_authority(): + var pellets: int = randi_range(min_pellets,max_pellets) + Session.shoot_pellets(int(machine.player.name),pellets,limb_total_damage,torso_total_damage,head_total_damage,shoot_distance,arc,damage_reduction_curve) + machine.player.get_node("ShootAudio").multiplayer_play() + + fire_timer.start() + machine.player_camera.recoil(horizontal_curve.sample(bullets_shot),vertical_curve.sample(bullets_shot)) + +func with_morphems(animation): + return machine.animation_prefix + ((animation+"_empty") if emptyable and machine.ammo == 0 else animation) diff --git a/weapons/gun/semi_pellet_shoot_state.gd.uid b/weapons/gun/semi_pellet_shoot_state.gd.uid new file mode 100644 index 0000000..30dea2b --- /dev/null +++ b/weapons/gun/semi_pellet_shoot_state.gd.uid @@ -0,0 +1 @@ +uid://cvueeftqbxb7r diff --git a/weapons/gun/semi_auto_shoot_state.gd b/weapons/gun/semi_shoot_state.gd similarity index 100% rename from weapons/gun/semi_auto_shoot_state.gd rename to weapons/gun/semi_shoot_state.gd diff --git a/weapons/gun/semi_auto_shoot_state.gd.uid b/weapons/gun/semi_shoot_state.gd.uid similarity index 100% rename from weapons/gun/semi_auto_shoot_state.gd.uid rename to weapons/gun/semi_shoot_state.gd.uid diff --git a/weapons/gun/sp/starting_pistol.tscn b/weapons/gun/sp/starting_pistol.tscn index 97c117c..86695c8 100644 --- a/weapons/gun/sp/starting_pistol.tscn +++ b/weapons/gun/sp/starting_pistol.tscn @@ -2,7 +2,7 @@ [ext_resource type="Script" uid="uid://e6lqknfl4ngt" path="res://systems/weapon_system/weapon_substate_machine.gd" id="1_g7s1i"] [ext_resource type="Script" uid="uid://ofv4e3dsfe8" path="res://weapons/gun/idle_state.gd" id="2_cmn6f"] -[ext_resource type="Script" uid="uid://vj13r83l3xyq" path="res://weapons/gun/semi_auto_shoot_state.gd" id="3_016ti"] +[ext_resource type="Script" uid="uid://vj13r83l3xyq" path="res://weapons/gun/semi_shoot_state.gd" id="3_016ti"] [ext_resource type="Script" uid="uid://hmekwp8444ao" path="res://weapons/gun/reload_state.gd" id="4_hoqxt"] [ext_resource type="Script" uid="uid://bmj0bwy2tlian" path="res://weapons/gun/intro_state.gd" id="5_ud1dr"] diff --git a/weapons/mc.tres b/weapons/mc.tres index 9c5aa9d..9feb901 100644 --- a/weapons/mc.tres +++ b/weapons/mc.tres @@ -1,11 +1,15 @@ -[gd_resource type="Resource" script_class="WeaponResource" load_steps=3 format=3 uid="uid://x1as1lkonk54"] +[gd_resource type="Resource" script_class="WeaponResource" load_steps=5 format=3 uid="uid://x1as1lkonk54"] [ext_resource type="Texture2D" uid="uid://j0fon3ridaoa" path="res://textures/icons/mc.png" id="1_0sdd5"] +[ext_resource type="PackedScene" uid="uid://b3xux7url8d2s" path="res://weapons/gun/mc/droppable_mc.tscn" id="1_mlled"] [ext_resource type="Script" uid="uid://bvnn2eiwqbu7t" path="res://systems/weapon_system/weapon_resource.gd" id="1_tgluf"] +[ext_resource type="PackedScene" uid="uid://8ohlfmr5bp0k" path="res://weapons/gun/mc/mc255.tscn" id="4_grphl"] [resource] script = ExtResource("1_tgluf") cost = 1500 preview = ExtResource("1_0sdd5") +dropped_scene = ExtResource("1_mlled") +weapon_system_scene = ExtResource("4_grphl") slot = &"primary" metadata/_custom_type_script = "uid://bvnn2eiwqbu7t"