mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 06:45:33 +00:00
Implemented battery weapons
This commit is contained in:
parent
d5c22045b7
commit
54fa750bca
20 changed files with 372 additions and 264 deletions
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=645 format=4 uid="uid://cupulrjeeivxm"]
|
||||
[gd_scene load_steps=647 format=4 uid="uid://cupulrjeeivxm"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://kno58homctew" path="res://addons/func_godot/src/map/func_godot_map.gd" id="1_amw6e"]
|
||||
[ext_resource type="Resource" uid="uid://cx41lsryg5wpm" path="res://3D/TrenchBroom/map_settings.tres" id="2_smtsr"]
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
[ext_resource type="Material" uid="uid://c47ulvm6n2tgk" path="res://textures/Floors/Floor228.tres" id="19_ue087"]
|
||||
[ext_resource type="Material" uid="uid://bchj40rv0q85g" path="res://textures/Floors/Floor255.tres" id="20_4fwvw"]
|
||||
[ext_resource type="Material" uid="uid://dnegblycwcpc8" path="res://textures/Manual/Blue_Panel_Wall.tres" id="20_aae8v"]
|
||||
[ext_resource type="Material" path="res://textures/Manual/Chevron.tres" id="20_r2p4f"]
|
||||
[ext_resource type="Material" uid="uid://dfs1tc2ry78pb" path="res://textures/Manual/Chevron.tres" id="20_r2p4f"]
|
||||
[ext_resource type="Material" uid="uid://bh0uo0cm3cr15" path="res://textures/Various/Various6.tres" id="21_81m4u"]
|
||||
[ext_resource type="Material" uid="uid://crk5xgfn3svey" path="res://textures/Floors/Floor178.tres" id="21_cr7d0"]
|
||||
[ext_resource type="Material" uid="uid://qbhdbykuieqn" path="res://textures/Manual/Floor_Mine_001.tres" id="21_v7uwt"]
|
||||
|
|
@ -111,6 +111,8 @@
|
|||
[ext_resource type="PackedScene" uid="uid://yath5bvxo3cn" path="res://3D/Scenes/Props/Wall_Emitter_3D.tscn" id="105_64qw8"]
|
||||
[ext_resource type="PackedScene" uid="uid://djm3rsc7ul5jb" path="res://3D/Scenes/Props/Tube_3D_Emitter.tscn" id="106_upccm"]
|
||||
[ext_resource type="Resource" uid="uid://ct1fa2huvy34n" path="res://Resources/Items/Ammo1.tres" id="107_0njqu"]
|
||||
[ext_resource type="Resource" uid="uid://ckfqrq8a0uj1t" path="res://Resources/Items/LaserWeapon.tres" id="108_r6j3v"]
|
||||
[ext_resource type="Resource" uid="uid://bgcgeg187vg1h" path="res://Resources/Items/IcicleRepeater.tres" id="109_gbc0s"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_0njqu"]
|
||||
albedo_texture = ExtResource("3_bryct")
|
||||
|
|
@ -5594,6 +5596,24 @@ Billboard = true
|
|||
PixelSize = 0.05
|
||||
metadata/_edit_group_ = true
|
||||
|
||||
[node name="Weapon" type="Marker3D" parent="Props"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.340561, 1.3534348, 29.91616)
|
||||
script = ExtResource("76_bin7h")
|
||||
Item = ExtResource("108_r6j3v")
|
||||
AutoSpawn = true
|
||||
Billboard = true
|
||||
PixelSize = 0.05
|
||||
metadata/_edit_group_ = true
|
||||
|
||||
[node name="Weapon2" type="Marker3D" parent="Props"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.757989, 1.3534348, 28.568409)
|
||||
script = ExtResource("76_bin7h")
|
||||
Item = ExtResource("109_gbc0s")
|
||||
AutoSpawn = true
|
||||
Billboard = true
|
||||
PixelSize = 0.05
|
||||
metadata/_edit_group_ = true
|
||||
|
||||
[node name="Ammo3" type="Marker3D" parent="Props"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.25383, 1.3534348, 28.412422)
|
||||
script = ExtResource("76_bin7h")
|
||||
|
|
|
|||
|
|
@ -12,17 +12,12 @@ ShortName = &"IC-9"
|
|||
ItemDescription = &"Cirno\'s custom gun, shoots ice pellets and never runs out of ammo"
|
||||
ItemKey = &"ICICLE_GUN"
|
||||
Item = 9
|
||||
Tier = 0
|
||||
Price = 0
|
||||
WeaponData = ExtResource("1_itajb")
|
||||
WeaponData3D = ExtResource("3_nh721")
|
||||
Amount = 1
|
||||
Max = 1
|
||||
PickupIfMaxed = false
|
||||
ConsumeOnUse = false
|
||||
UiType = 14
|
||||
Selectable = true
|
||||
AutoPickup = false
|
||||
InventorySprite = ExtResource("2_eaoas")
|
||||
DropScenePath = &"res://Scenes/Items/GenericItem.tscn"
|
||||
DropScenePath3D = &"uid://cnot7sft7lpf3"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
[gd_resource type="Resource" script_class="LootItem" load_steps=4 format=3 uid="uid://ckfqrq8a0uj1t"]
|
||||
[gd_resource type="Resource" script_class="LootItem" load_steps=5 format=3 uid="uid://ckfqrq8a0uj1t"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://d04hnwyg3sqlu" path="res://Sprites/Items/LaserWeapon.png" id="1_h548w"]
|
||||
[ext_resource type="Resource" uid="uid://do0jwf5jhx1i5" path="res://Resources/Weapons/LaserWeapon.tres" id="2_rec72"]
|
||||
[ext_resource type="Script" uid="uid://epnwjptvks3t" path="res://Scripts/Resources/LootItem.cs" id="3_2blkp"]
|
||||
[ext_resource type="Resource" uid="uid://d2tgk8rnd4sfs" path="res://Resources/Weapons/LaserWeapon_3D.tres" id="3_rec72"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("3_2blkp")
|
||||
|
|
@ -11,16 +12,12 @@ ShortName = &"Laser"
|
|||
ItemDescription = &"Laser"
|
||||
ItemKey = &"LASER_WEAPON"
|
||||
Item = 9
|
||||
Tier = 0
|
||||
Price = 0
|
||||
WeaponData = ExtResource("2_rec72")
|
||||
WeaponData3D = ExtResource("3_rec72")
|
||||
Amount = 1
|
||||
Max = 1
|
||||
PickupIfMaxed = false
|
||||
ConsumeOnUse = false
|
||||
UiType = 22
|
||||
Selectable = true
|
||||
AutoPickup = false
|
||||
InventorySprite = ExtResource("1_h548w")
|
||||
DropScenePath = &"res://Scenes/Items/GenericItem.tscn"
|
||||
DropScenePath3D = &"uid://cnot7sft7lpf3"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
[resource]
|
||||
script = ExtResource("2_p6a7h")
|
||||
LevelId = 0
|
||||
MapName = &"iso Test"
|
||||
MapDescription = null
|
||||
ScenePath = &"uid://ec4m3geediis"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
[resource]
|
||||
script = ExtResource("1_fmydh")
|
||||
EggIndex = 0
|
||||
StartingEquipment = Array[ExtResource("1_xjbmv")]([ExtResource("1_juefn"), ExtResource("2_xjbmv")])
|
||||
RemoveEquipment = Array[ExtResource("1_xjbmv")]([ExtResource("1_wchkt"), ExtResource("2_2v4s6"), ExtResource("3_73lvc"), ExtResource("4_vnxsw")])
|
||||
metadata/_custom_type_script = "uid://mja0rk7n2kln"
|
||||
|
|
|
|||
|
|
@ -10,17 +10,12 @@ script = ExtResource("2_m8dps")
|
|||
Name = &"Icicle Gun"
|
||||
BulletData = ExtResource("1_sd6j2")
|
||||
Priority = 1
|
||||
AmmoPerShot = 1
|
||||
RateOfFire = 0.1
|
||||
BulletCapacity = 100
|
||||
ReloadTime = 0.1
|
||||
AutoReload = true
|
||||
InfiniteAmmo = true
|
||||
ItemKey = &"ICICLE_GUN"
|
||||
AmmoKey = &""
|
||||
BulletsPerShot = 1
|
||||
SpreadAngle = 5.0
|
||||
RandomSpread = 2.5
|
||||
_rotationOffset = 0.0
|
||||
ReloadSound = ExtResource("2_sd6j2")
|
||||
ShootSound = ExtResource("3_sd6j2")
|
||||
|
|
|
|||
|
|
@ -9,18 +9,17 @@
|
|||
script = ExtResource("4_ld57e")
|
||||
Name = &"Icicle Gun"
|
||||
BulletData = ExtResource("1_d2kl0")
|
||||
Priority = 1
|
||||
AmmoPerShot = 1
|
||||
RateOfFire = 0.1
|
||||
Priority = 10
|
||||
AmmoPerShot = 5
|
||||
RateOfFire = 0.052999999999883585
|
||||
BulletCapacity = 100
|
||||
ReloadTime = 0.1
|
||||
AutoReload = true
|
||||
InfiniteAmmo = true
|
||||
ReloadTime = 0.5
|
||||
InfiniteAmmo = false
|
||||
ItemKey = &"ICICLE_GUN"
|
||||
AmmoKey = &""
|
||||
BulletsPerShot = 1
|
||||
AmmoKey = &"BATTERY"
|
||||
RechargeTime = 0.19999999999708962
|
||||
RechargeAmount = 5
|
||||
SpreadAngle = 5.0
|
||||
RandomSpread = 2.5
|
||||
_rotationOffset = 0.0
|
||||
ReloadSound = ExtResource("2_sdmjb")
|
||||
ShootSound = ExtResource("3_hj8fq")
|
||||
|
|
|
|||
|
|
@ -10,17 +10,11 @@ script = ExtResource("4_ai75q")
|
|||
Name = &"Icicle Repeater"
|
||||
BulletData = ExtResource("1_2567x")
|
||||
Priority = 10
|
||||
AmmoPerShot = 1
|
||||
RateOfFire = 0.05
|
||||
BulletCapacity = 6
|
||||
ReloadTime = 0.5
|
||||
AutoReload = true
|
||||
InfiniteAmmo = false
|
||||
ItemKey = &"ICICLE_REPEATER_T0"
|
||||
AmmoKey = &"ICE_AMMO"
|
||||
BulletsPerShot = 1
|
||||
SpreadAngle = 0.0
|
||||
RandomSpread = 0.0
|
||||
_rotationOffset = 0.0
|
||||
ReloadSound = ExtResource("2_2sfo4")
|
||||
ShootSound = ExtResource("3_3qbca")
|
||||
|
|
|
|||
20
Resources/Weapons/LaserWeapon_3D.tres
Normal file
20
Resources/Weapons/LaserWeapon_3D.tres
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
[gd_resource type="Resource" script_class="WeaponResource" load_steps=4 format=3 uid="uid://d2tgk8rnd4sfs"]
|
||||
|
||||
[ext_resource type="Resource" uid="uid://csmq6hngkx41e" path="res://Resources/Bullets/3D/icicle_gun_bullets_3D.tres" id="1_boxvv"]
|
||||
[ext_resource type="AudioStream" uid="uid://c1au3v0mynil8" path="res://SFX/Weapons/Laser_shoot 7.wav" id="2_f21bu"]
|
||||
[ext_resource type="Script" uid="uid://b6fmrnipv88bk" path="res://Scripts/Resources/WeaponResource.cs" id="4_wga0n"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("4_wga0n")
|
||||
Name = &"Laser"
|
||||
BulletData = ExtResource("1_boxvv")
|
||||
Priority = 1
|
||||
AmmoPerShot = 2
|
||||
RateOfFire = 0.3000000000029104
|
||||
BulletCapacity = 5
|
||||
ReloadTime = 0.6000000000058208
|
||||
ItemKey = &"LASER_WEAPON"
|
||||
AmmoKey = &"SHIELD"
|
||||
SpreadAngle = 5.0
|
||||
RandomSpread = 2.5
|
||||
ShootSound = ExtResource("2_f21bu")
|
||||
|
|
@ -202,8 +202,9 @@ collision_mask = 17
|
|||
script = ExtResource("1_cc7e7")
|
||||
PlayerFSM = NodePath("StateMachine")
|
||||
|
||||
[node name="StateMachine" type="Node" parent="."]
|
||||
[node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("Storage")]
|
||||
script = ExtResource("1_vsywg")
|
||||
Storage = NodePath("../Storage")
|
||||
|
||||
[node name="Init" type="Node" parent="StateMachine"]
|
||||
script = ExtResource("2_3oyrx")
|
||||
|
|
@ -288,9 +289,10 @@ Deceleration = 20.0
|
|||
Gravity = -20.0
|
||||
FallSpeed = 4.0
|
||||
|
||||
[node name="Storage" type="Node" parent="." node_paths=PackedStringArray("Root")]
|
||||
[node name="Storage" type="Node" parent="." node_paths=PackedStringArray("Root", "Shield")]
|
||||
script = ExtResource("6_habpy")
|
||||
Root = NodePath("..")
|
||||
Shield = NodePath("../DamageReceiver/ShieldProvider")
|
||||
|
||||
[node name="MouseAimProvider" type="Node3D" parent="."]
|
||||
script = ExtResource("9_2ffwi")
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://cfgc6ik8vb08c"]
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cfgc6ik8vb08c"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dutroqc0grqyv" path="res://Scripts/Weapons/Weapon3D.cs" id="1_gdxml"]
|
||||
[ext_resource type="Resource" uid="uid://b8apu0l5fm4k" path="res://Resources/Weapons/IcicleGun.tres" id="2_s6td3"]
|
||||
[ext_resource type="Texture2D" uid="uid://duwiasewxvcb5" path="res://Sprites/Items/Icicle_Gun.png" id="3_6jcxd"]
|
||||
|
||||
[node name="Weapon" type="Node3D" node_paths=PackedStringArray("Muzzle", "Pivot", "Sprite")]
|
||||
script = ExtResource("1_gdxml")
|
||||
WeaponData = ExtResource("2_s6td3")
|
||||
Muzzle = NodePath("Muzzle")
|
||||
Pivot = NodePath("Pivot")
|
||||
Sprite = NodePath("Sprite3D")
|
||||
|
|
@ -19,6 +17,8 @@ Sprite = NodePath("Sprite3D")
|
|||
one_shot = true
|
||||
|
||||
[node name="Sprite3D" type="Sprite3D" parent="."]
|
||||
visible = false
|
||||
pixel_size = 0.05
|
||||
billboard = 1
|
||||
texture_filter = 0
|
||||
texture = ExtResource("3_6jcxd")
|
||||
|
|
|
|||
|
|
@ -6,5 +6,6 @@ public partial class IsoPlayerStateMachine : StateMachineBase<PlayerState,Charac
|
|||
{
|
||||
[Export] public override PlayerState InitialState { get; protected set; } = PlayerState.Init;
|
||||
|
||||
[Export] public IsoPlayerStorageModule Storage { get; private set; }
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +1,14 @@
|
|||
using Godot;
|
||||
using Cirno.Scripts.Components.Actors;
|
||||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Components.FSM._3DPlayer;
|
||||
|
||||
public partial class IsoPlayerStorageModule : Node
|
||||
{
|
||||
[Export] public IsoPlayerFSMProxy Root { get; private set; }
|
||||
|
||||
[Export] public ActorResourceProvider Shield { get; private set; }
|
||||
|
||||
public Node RootAsNode => Root;
|
||||
|
||||
public Vector2 FacingDirection { get; set; } = Vector2.Down;
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ public partial class PlayerWeaponProvider3D : Node
|
|||
weapon.WeaponData = startingItem.WeaponData3D;
|
||||
|
||||
weapon.Sprite.Texture = startingItem.InventorySprite;
|
||||
|
||||
weapon.Init();
|
||||
this.AddWeapon(weapon);
|
||||
return weapon;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public partial class Shooting : EnemyStateBase3D
|
|||
//DamageReceiver.HealthProvider.ResourceDepleted += HealthProviderOnResourceDepleted;
|
||||
|
||||
EquippedWeapon.WeaponData = Storage.Root.EnemyResource.Weapon;
|
||||
EquippedWeapon.Init();
|
||||
|
||||
_currentStrafeTarget = null;
|
||||
|
||||
|
|
|
|||
9
Scripts/Enums/WeaponAmmoType.cs
Normal file
9
Scripts/Enums/WeaponAmmoType.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
namespace Cirno.Scripts.Enums;
|
||||
|
||||
public enum WeaponAmmoType
|
||||
{
|
||||
Infinite,
|
||||
Ammo,
|
||||
Shield,
|
||||
Battery,
|
||||
}
|
||||
1
Scripts/Enums/WeaponAmmoType.cs.uid
Normal file
1
Scripts/Enums/WeaponAmmoType.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://0ouvmqwpq4xa
|
||||
|
|
@ -34,6 +34,11 @@ public partial class WeaponResource : Resource
|
|||
|
||||
[Export] public StringName ItemKey;
|
||||
[Export] public StringName AmmoKey;
|
||||
|
||||
[ExportCategory("Battery Recharge")]
|
||||
[Export] public double RechargeTime = 0.5d;
|
||||
[Export]public int RechargeAmount = 1;
|
||||
|
||||
#region Bullet spawn data
|
||||
[ExportCategory("Bullet Spawn Data")]
|
||||
[Export] public int BulletsPerShot = 1;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Cirno.Scripts.Controllers;
|
||||
using Cirno.Scripts.Enums;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Cirno.Scripts.Utils;
|
||||
using Godot;
|
||||
|
|
@ -7,220 +8,279 @@ namespace Cirno.Scripts.Weapons;
|
|||
|
||||
public partial class Weapon3D : Node3D
|
||||
{
|
||||
[Export]
|
||||
public WeaponResource WeaponData { get; set; }
|
||||
[Export] public WeaponResource WeaponData { get; set; }
|
||||
|
||||
[Export]
|
||||
public PackedScene BulletScene { get; set; }
|
||||
|
||||
[Export]
|
||||
public Marker3D Muzzle { get; set; }
|
||||
|
||||
[Export]
|
||||
public Marker3D Pivot { get; set; }
|
||||
|
||||
[Export]
|
||||
public Sprite3D Sprite { get; private set; }
|
||||
[Export] public PackedScene BulletScene { get; set; }
|
||||
|
||||
[Export] public StringName PowerKey { get; set; } = "POWER";
|
||||
|
||||
[Signal]
|
||||
public delegate void ShootingEventHandler();
|
||||
[Export] public Marker3D Muzzle { get; set; }
|
||||
|
||||
[Signal]
|
||||
public delegate void ReloadingEventHandler();
|
||||
|
||||
[Signal] public delegate void EmptyEventHandler();
|
||||
|
||||
public int Ammo { get; set; } = 0;
|
||||
[Export] public Marker3D Pivot { get; set; }
|
||||
|
||||
private int _loadedAmmo;
|
||||
public int LoadedAmmo
|
||||
{
|
||||
get => _loadedAmmo;
|
||||
private set
|
||||
{
|
||||
_loadedAmmo = value;
|
||||
InventoryManager.Instance?.NotifyLoadedAmmoChange(WeaponData?.ItemKey, _loadedAmmo);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 ShootDirection { get; set; } = Vector2.Zero;
|
||||
|
||||
private Timer _cooldownTimer;
|
||||
|
||||
private GameManager _gameManager;
|
||||
[Export] public Sprite3D Sprite { get; private set; }
|
||||
|
||||
private readonly StringName _shieldAmmoType = "SHIELD";
|
||||
private bool UsesBattery => WeaponData.AmmoKey == _shieldAmmoType;
|
||||
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
public override void _Ready()
|
||||
{
|
||||
_cooldownTimer = GetNode<Timer>("./ShootTimer");
|
||||
|
||||
// Start full
|
||||
if (WeaponData != null)
|
||||
{
|
||||
LoadedAmmo = WeaponData.BulletCapacity;
|
||||
}
|
||||
}
|
||||
[Export] public StringName PowerKey { get; set; } = "POWER";
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
EmitSignalReloading();
|
||||
|
||||
_cooldownTimer.Start(WeaponData.ReloadTime);
|
||||
|
||||
if (WeaponData.InfiniteAmmo || string.IsNullOrWhiteSpace(WeaponData.AmmoKey))
|
||||
{
|
||||
LoadedAmmo = WeaponData.BulletCapacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
var ammoToLoad = InventoryManager.Instance.RemoveItem(WeaponData.AmmoKey, WeaponData.BulletCapacity - LoadedAmmo);
|
||||
|
||||
if (ammoToLoad > 0)
|
||||
{
|
||||
LoadedAmmo = ammoToLoad;
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitSignalEmpty();
|
||||
//GD.Print("Out of ammo");
|
||||
}
|
||||
}
|
||||
}
|
||||
[Signal]
|
||||
public delegate void ShootingEventHandler();
|
||||
|
||||
public void Shoot(BulletOwner? ownerOverride = null)
|
||||
{
|
||||
// Waiting on reload or Rate of Fire cooldown?
|
||||
if (!_cooldownTimer.IsStopped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
[Signal]
|
||||
public delegate void ReloadingEventHandler();
|
||||
|
||||
// Check for battery if it's used
|
||||
// if (UsesBattery)
|
||||
// {
|
||||
// if (GameManager.Instance.Player.Shield.CurrentResource >= WeaponData.AmmoPerShot)
|
||||
// {
|
||||
// GameManager.Instance.Player.Shield.CurrentResource -= WeaponData.AmmoPerShot;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// EmitSignalEmpty();
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
// Out of ammo?
|
||||
if (LoadedAmmo < WeaponData.AmmoPerShot)
|
||||
{
|
||||
if (WeaponData.AutoReload)
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
EmitSignalEmpty();
|
||||
return;
|
||||
}
|
||||
|
||||
EmitSignalShooting();
|
||||
|
||||
// TODO: Shoot at muzzle position, need to provide a way to turn it, on a radius?
|
||||
[Signal]
|
||||
public delegate void EmptyEventHandler();
|
||||
|
||||
float halfSpread = WeaponData.SpreadAngle / 2f;
|
||||
float spreadStep = WeaponData.BulletsPerShot > 1 ? WeaponData.SpreadAngle / (WeaponData.BulletsPerShot - 1) : 0;
|
||||
|
||||
for (int i = 0; i < WeaponData.BulletsPerShot; i++)
|
||||
{
|
||||
// Calculate angle offset for this bullet
|
||||
float spreadOffset = -halfSpread + (spreadStep * i);
|
||||
public int Ammo { get; set; } = 0;
|
||||
|
||||
// Add random spread
|
||||
if (WeaponData.RandomSpread > 0)
|
||||
{
|
||||
// Gaussian with mean = 0, stddev = WeaponData.RandomSpread
|
||||
spreadOffset += RandomStuff.GaussianClamped(
|
||||
mean: 0f,
|
||||
stdDev: WeaponData.RandomSpread, // tuning knob
|
||||
min: -halfSpread,
|
||||
max: halfSpread
|
||||
);
|
||||
}
|
||||
|
||||
// Rotate the ShootDirection by the spread angle
|
||||
Vector2 spreadDirection = ShootDirection.Rotated(Mathf.DegToRad(spreadOffset));
|
||||
private int _loadedAmmo;
|
||||
|
||||
// Restore pooling
|
||||
var bullet = PoolingManager.Instance.SpawnBullet<Bullet3D>(WeaponData.BulletData);
|
||||
|
||||
//var bullet = WeaponData.BulletData.BulletScene.Instantiate<Bullet3D>()
|
||||
|
||||
bullet.GlobalPosition = Muzzle.GlobalPosition;
|
||||
|
||||
//var bullet = this.CreateChildOf<Bullet>(_gameManager.BulletsContainer, WeaponData.BulletData.BulletScene, _muzzle.GlobalPosition);
|
||||
public int LoadedAmmo
|
||||
{
|
||||
get => _loadedAmmo;
|
||||
private set
|
||||
{
|
||||
_loadedAmmo = value;
|
||||
InventoryManager.Instance?.NotifyLoadedAmmoChange(WeaponData?.ItemKey, _loadedAmmo);
|
||||
}
|
||||
}
|
||||
|
||||
if (bullet == null)
|
||||
{
|
||||
GD.PrintErr("Bullet is null, not shooting");
|
||||
return;
|
||||
};
|
||||
|
||||
var bulletData = WeaponData.MakeBullet(Muzzle.GlobalPosition.ToVector2()); // TODO: Fix for 3D
|
||||
if (ownerOverride.HasValue)
|
||||
{
|
||||
bulletData.Owner = ownerOverride.Value;
|
||||
}
|
||||
public Vector2 ShootDirection { get; set; } = Vector2.Zero;
|
||||
|
||||
if (bulletData.Owner is BulletOwner.Player || ownerOverride is BulletOwner.Player)
|
||||
{
|
||||
// Apply the P multiplier
|
||||
bulletData.Damage *=
|
||||
GetBulletStrengthMultiplier(bulletData.Damage, bulletData.OriginalBulletResource.MaxDamage, 20);
|
||||
}
|
||||
|
||||
bullet.Initialize(bulletData);
|
||||
|
||||
//bullet.SetDirection(ShootDirection);
|
||||
bullet.SetDirection(spreadDirection);
|
||||
bullet.Speed = WeaponData.BulletData.BulletSpeed;
|
||||
}
|
||||
private Timer _cooldownTimer;
|
||||
private Timer _rechargeTimer;
|
||||
|
||||
if (!UsesBattery)
|
||||
{
|
||||
LoadedAmmo -= WeaponData.AmmoPerShot;
|
||||
}
|
||||
|
||||
//_inventoryManager.NotifyLoadedAmmoChange(WeaponData.ItemKey, LoadedAmmo);
|
||||
// if (!string.IsNullOrWhiteSpace(WeaponData?.AmmoKey))
|
||||
// {
|
||||
// // Notify hud to decrease weapon
|
||||
//
|
||||
// }
|
||||
|
||||
_cooldownTimer.Start(WeaponData?.RateOfFire ?? 0);
|
||||
}
|
||||
private GameManager _gameManager;
|
||||
|
||||
private float GetBulletStrengthMultiplier(float baseDamage, float maxDamage, float maxPower)
|
||||
{
|
||||
var p = InventoryManager.Instance.GetItemCount(PowerKey);
|
||||
private readonly StringName _shieldAmmoType = "SHIELD";
|
||||
private readonly StringName _batteryAmmoType = "BATTERY";
|
||||
//private bool UsesBattery => WeaponData.AmmoKey == _shieldAmmoType;
|
||||
|
||||
float minMultiplier = 1.0f;
|
||||
float maxMultiplier = maxDamage / baseDamage;
|
||||
private WeaponAmmoType _ammoType = WeaponAmmoType.Infinite;
|
||||
|
||||
float normalizedPower = Mathf.Clamp((float)p / maxPower, 0f, 1f);
|
||||
return Mathf.Lerp(minMultiplier, maxMultiplier, normalizedPower);
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
|
||||
}
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
public override void _Ready()
|
||||
{
|
||||
_cooldownTimer = GetNode<Timer>("./ShootTimer");
|
||||
|
||||
//Init();
|
||||
}
|
||||
|
||||
public void Show()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
SetAmmoType();
|
||||
|
||||
if (_ammoType is WeaponAmmoType.Battery && _rechargeTimer is null)
|
||||
{
|
||||
_rechargeTimer = new Timer();
|
||||
this.AddChild(_rechargeTimer);
|
||||
_rechargeTimer.Timeout += RechargeTimerOnTimeout;
|
||||
|
||||
_rechargeTimer.Start(WeaponData.RechargeTime);
|
||||
}
|
||||
|
||||
// Start full
|
||||
if (WeaponData != null)
|
||||
{
|
||||
LoadedAmmo = WeaponData.BulletCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
private void RechargeTimerOnTimeout()
|
||||
{
|
||||
if (LoadedAmmo < WeaponData.BulletCapacity)
|
||||
{
|
||||
LoadedAmmo += WeaponData.RechargeAmount;
|
||||
}
|
||||
|
||||
_rechargeTimer.Start(WeaponData.RechargeTime);
|
||||
}
|
||||
|
||||
private void SetAmmoType()
|
||||
{
|
||||
if (WeaponData.InfiniteAmmo || string.IsNullOrWhiteSpace(WeaponData.AmmoKey))
|
||||
{
|
||||
_ammoType = WeaponAmmoType.Infinite;
|
||||
return;
|
||||
}
|
||||
|
||||
if (WeaponData.AmmoKey == _shieldAmmoType)
|
||||
{
|
||||
_ammoType = WeaponAmmoType.Shield;
|
||||
return;
|
||||
}
|
||||
|
||||
if (WeaponData.AmmoKey == _batteryAmmoType)
|
||||
{
|
||||
_ammoType = WeaponAmmoType.Battery;
|
||||
return;
|
||||
}
|
||||
|
||||
_ammoType = WeaponAmmoType.Ammo;
|
||||
}
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
EmitSignalReloading();
|
||||
|
||||
_cooldownTimer.Start(WeaponData.ReloadTime);
|
||||
|
||||
if (_ammoType is WeaponAmmoType.Infinite)
|
||||
{
|
||||
LoadedAmmo = WeaponData.BulletCapacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
var ammoToLoad =
|
||||
InventoryManager.Instance.RemoveItem(WeaponData.AmmoKey, WeaponData.BulletCapacity - LoadedAmmo);
|
||||
|
||||
if (ammoToLoad > 0)
|
||||
{
|
||||
LoadedAmmo = ammoToLoad;
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitSignalEmpty();
|
||||
//GD.Print("Out of ammo");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool HandlePreShoot()
|
||||
{
|
||||
// Waiting on reload or Rate of Fire cooldown?
|
||||
if (!_cooldownTimer.IsStopped())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle Shield powered weapons
|
||||
if (_ammoType is WeaponAmmoType.Shield)
|
||||
{
|
||||
if (GameController.Instance.Player.Storage.Shield.CurrentResource >= WeaponData.AmmoPerShot)
|
||||
{
|
||||
GameController.Instance.Player.Storage.Shield.CurrentResource -= WeaponData.AmmoPerShot;
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitSignalEmpty();
|
||||
}
|
||||
_cooldownTimer.Start(WeaponData?.RateOfFire ?? 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Out of ammo?
|
||||
if (LoadedAmmo < WeaponData.AmmoPerShot)
|
||||
{
|
||||
if (_ammoType is WeaponAmmoType.Ammo && WeaponData.AutoReload)
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
|
||||
EmitSignalEmpty();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_ammoType is WeaponAmmoType.Ammo or WeaponAmmoType.Battery)
|
||||
{
|
||||
LoadedAmmo -= WeaponData.AmmoPerShot;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Shoot(BulletOwner? ownerOverride = null)
|
||||
{
|
||||
if (!HandlePreShoot()) return;
|
||||
|
||||
EmitSignalShooting();
|
||||
|
||||
// TODO: Shoot at muzzle position, need to provide a way to turn it, on a radius?
|
||||
|
||||
float halfSpread = WeaponData.SpreadAngle / 2f;
|
||||
float spreadStep = WeaponData.BulletsPerShot > 1 ? WeaponData.SpreadAngle / (WeaponData.BulletsPerShot - 1) : 0;
|
||||
|
||||
for (int i = 0; i < WeaponData.BulletsPerShot; i++)
|
||||
{
|
||||
// Calculate angle offset for this bullet
|
||||
float spreadOffset = -halfSpread + (spreadStep * i);
|
||||
|
||||
// Add random spread
|
||||
if (WeaponData.RandomSpread > 0)
|
||||
{
|
||||
// Gaussian with mean = 0, stddev = WeaponData.RandomSpread
|
||||
spreadOffset += RandomStuff.GaussianClamped(
|
||||
mean: 0f,
|
||||
stdDev: WeaponData.RandomSpread, // tuning knob
|
||||
min: -halfSpread,
|
||||
max: halfSpread
|
||||
);
|
||||
}
|
||||
|
||||
// Rotate the ShootDirection by the spread angle
|
||||
Vector2 spreadDirection = ShootDirection.Rotated(Mathf.DegToRad(spreadOffset));
|
||||
|
||||
// Restore pooling
|
||||
var bullet = PoolingManager.Instance.SpawnBullet<Bullet3D>(WeaponData.BulletData);
|
||||
|
||||
//var bullet = WeaponData.BulletData.BulletScene.Instantiate<Bullet3D>()
|
||||
|
||||
bullet.GlobalPosition = Muzzle.GlobalPosition;
|
||||
|
||||
var bulletData = WeaponData.MakeBullet(Muzzle.GlobalPosition.ToVector2()); // TODO: Fix for 3D
|
||||
if (ownerOverride.HasValue)
|
||||
{
|
||||
bulletData.Owner = ownerOverride.Value;
|
||||
}
|
||||
|
||||
if (bulletData.Owner is BulletOwner.Player || ownerOverride is BulletOwner.Player)
|
||||
{
|
||||
// Apply the P multiplier
|
||||
bulletData.Damage *=
|
||||
GetBulletStrengthMultiplier(bulletData.Damage, bulletData.OriginalBulletResource.MaxDamage, 20);
|
||||
}
|
||||
|
||||
bullet.Initialize(bulletData);
|
||||
|
||||
//bullet.SetDirection(ShootDirection);
|
||||
bullet.SetDirection(spreadDirection);
|
||||
bullet.Speed = WeaponData.BulletData.BulletSpeed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//_inventoryManager.NotifyLoadedAmmoChange(WeaponData.ItemKey, LoadedAmmo);
|
||||
// if (!string.IsNullOrWhiteSpace(WeaponData?.AmmoKey))
|
||||
// {
|
||||
// // Notify hud to decrease weapon
|
||||
//
|
||||
// }
|
||||
|
||||
if (_ammoType is WeaponAmmoType.Ammo && WeaponData.AutoReload)
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
_cooldownTimer.Start(WeaponData?.RateOfFire ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
private float GetBulletStrengthMultiplier(float baseDamage, float maxDamage, float maxPower)
|
||||
{
|
||||
var p = InventoryManager.Instance.GetItemCount(PowerKey);
|
||||
|
||||
float minMultiplier = 1.0f;
|
||||
float maxMultiplier = maxDamage / baseDamage;
|
||||
|
||||
float normalizedPower = Mathf.Clamp((float)p / maxPower, 0f, 1f);
|
||||
return Mathf.Lerp(minMultiplier, maxMultiplier, normalizedPower);
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
}
|
||||
|
||||
public void Show()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -3,32 +3,39 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d04hnwyg3sqlu"
|
||||
path="res://.godot/imported/LaserWeapon.png-e292e12aa34e57d3d32457a4c9af747e.ctex"
|
||||
path.s3tc="res://.godot/imported/LaserWeapon.png-e292e12aa34e57d3d32457a4c9af747e.s3tc.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
"imported_formats": ["s3tc_bptc"],
|
||||
"vram_texture": true
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://Sprites/Items/LaserWeapon.png"
|
||||
dest_files=["res://.godot/imported/LaserWeapon.png-e292e12aa34e57d3d32457a4c9af747e.ctex"]
|
||||
dest_files=["res://.godot/imported/LaserWeapon.png-e292e12aa34e57d3d32457a4c9af747e.s3tc.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/generate=true
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
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=1
|
||||
detect_3d/compress_to=0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue