mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-07 22:35:55 +00:00
2D Character and weapons
This commit is contained in:
parent
072f6d0ce6
commit
cc9c4e5aa1
37 changed files with 1115 additions and 91 deletions
9
Scripts/Components/Actors/IMouseAimProvider.cs
Normal file
9
Scripts/Components/Actors/IMouseAimProvider.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Components.Actors;
|
||||
|
||||
public interface IMouseAimProvider
|
||||
{
|
||||
public Vector2 GetMouseAimInput();
|
||||
}
|
||||
1
Scripts/Components/Actors/IMouseAimProvider.cs.uid
Normal file
1
Scripts/Components/Actors/IMouseAimProvider.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://mr42tbagcs8t
|
||||
|
|
@ -6,28 +6,19 @@ namespace Cirno.Scripts.Components.Actors;
|
|||
|
||||
public partial class KeyboardInputProvider : InputProvider
|
||||
{
|
||||
[ExportCategory("Movement")]
|
||||
[Export]
|
||||
public StringName LeftAxisName { get; private set; } = "left";
|
||||
[Export]
|
||||
public StringName RightAxisName { get; private set; } = "right";
|
||||
[Export]
|
||||
public StringName UpAxisName { get; private set; } = "up";
|
||||
[Export]
|
||||
public StringName DownAxisName { get; private set; } = "down";
|
||||
[ExportCategory("Movement")] [Export] public StringName LeftAxisName { get; private set; } = "left";
|
||||
[Export] public StringName RightAxisName { get; private set; } = "right";
|
||||
[Export] public StringName UpAxisName { get; private set; } = "up";
|
||||
[Export] public StringName DownAxisName { get; private set; } = "down";
|
||||
|
||||
[ExportCategory("Aiming")]
|
||||
[Export]
|
||||
public StringName LeftAimName { get; private set; } = "aim_left";
|
||||
[Export]
|
||||
public StringName RightAimName { get; private set; } = "aim_right";
|
||||
[Export]
|
||||
public StringName UpAimName { get; private set; } = "aim_up";
|
||||
[Export]
|
||||
public StringName DownAimName { get; private set; } = "aim_down";
|
||||
[ExportCategory("Aiming")] [Export] public StringName LeftAimName { get; private set; } = "aim_left";
|
||||
[Export] public StringName RightAimName { get; private set; } = "aim_right";
|
||||
[Export] public StringName UpAimName { get; private set; } = "aim_up";
|
||||
[Export] public StringName DownAimName { get; private set; } = "aim_down";
|
||||
|
||||
[ExportCategory("Action Names")] [Export]
|
||||
private StringName _shootActionName = "shoot";
|
||||
|
||||
[ExportCategory("Action Names")]
|
||||
[Export] private StringName _shootActionName = "shoot";
|
||||
[Export] private StringName _useActionName = "Use";
|
||||
[Export] private StringName _scanActionName = "scan";
|
||||
[Export] private StringName _strafeActionName = "strafe";
|
||||
|
|
@ -38,7 +29,14 @@ public partial class KeyboardInputProvider : InputProvider
|
|||
[Export] private StringName _freezeActionName = "Freeze";
|
||||
[Export] private StringName _reloadActionName = "Reload";
|
||||
|
||||
private enum AimInputMethod { RightStick, Mouse }
|
||||
private IMouseAimProvider _mouseAImProvider;
|
||||
|
||||
private enum AimInputMethod
|
||||
{
|
||||
RightStick,
|
||||
Mouse
|
||||
}
|
||||
|
||||
private AimInputMethod _lastUsedInput = AimInputMethod.RightStick;
|
||||
|
||||
public override void _Ready()
|
||||
|
|
@ -49,11 +47,19 @@ public partial class KeyboardInputProvider : InputProvider
|
|||
|
||||
private void DelayedRegisterGameManager()
|
||||
{
|
||||
_mouseAImProvider = GetNodeOrNull<IMouseAimProvider>("MouseAimProvider");
|
||||
|
||||
if (_mouseAImProvider is null)
|
||||
{
|
||||
GD.Print("Mouse aim provider is null");
|
||||
}
|
||||
|
||||
if (GameManager.Instance is null)
|
||||
{
|
||||
GD.Print("No GameManager found for keyboard inputprovider");
|
||||
return;
|
||||
}
|
||||
|
||||
GameManager.Instance.GameStateChange += InstanceOnGameStateChange;
|
||||
_enabled = true;
|
||||
}
|
||||
|
|
@ -63,7 +69,7 @@ public partial class KeyboardInputProvider : InputProvider
|
|||
private void InstanceOnGameStateChange(GameState state)
|
||||
{
|
||||
if (state is not GameState.Playing) return;
|
||||
|
||||
|
||||
_enabled = false;
|
||||
|
||||
_ = DelayResume();
|
||||
|
|
@ -75,7 +81,7 @@ public partial class KeyboardInputProvider : InputProvider
|
|||
await Task.Delay(200);
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
|
||||
public override Vector2 GetMovementInput()
|
||||
{
|
||||
return Input.GetVector(LeftAxisName, RightAxisName, UpAxisName, DownAxisName);
|
||||
|
|
@ -98,26 +104,27 @@ public partial class KeyboardInputProvider : InputProvider
|
|||
|
||||
return _lastUsedInput == AimInputMethod.RightStick ? rightStickInput : mouseInput;
|
||||
}
|
||||
|
||||
|
||||
private Vector2 GetRightStickInput()
|
||||
{
|
||||
return new Vector2(
|
||||
Input.GetAxis(LeftAimName,RightAimName),
|
||||
Input.GetAxis(LeftAimName, RightAimName),
|
||||
Input.GetAxis(UpAimName, DownAimName)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private Vector2 GetMouseAimInput()
|
||||
{
|
||||
//Camera2D camera = GetViewport().GetCamera2D();
|
||||
//if (camera == null) return Vector2.Zero; // Ensure there's a valid camera
|
||||
|
||||
//Vector2 mouseScreenPos = GetViewport().get_local_mouse_position();
|
||||
if (GameManager.Instance is null) return Vector2.Zero;
|
||||
|
||||
Vector2 mouseWorldPos = DisplayServer.MouseGetPosition();// GameManager.Instance.GetGlobalMousePosition();
|
||||
|
||||
return mouseWorldPos - GameManager.Instance.PlayerPosition.Value; // Get direction vector
|
||||
return _mouseAImProvider?.GetMouseAimInput() ?? Vector2.Zero;
|
||||
// //Camera2D camera = GetViewport().GetCamera2D();
|
||||
// //if (camera == null) return Vector2.Zero; // Ensure there's a valid camera
|
||||
//
|
||||
// //Vector2 mouseScreenPos = GetViewport().get_local_mouse_position();
|
||||
// if (GameManager.Instance is null) return Vector2.Zero;
|
||||
//
|
||||
// Vector2 mouseWorldPos = DisplayServer.MouseGetPosition();// GameManager.Instance.GetGlobalMousePosition();
|
||||
//
|
||||
// return mouseWorldPos - GameManager.Instance.PlayerPosition.Value; // Get direction vector
|
||||
}
|
||||
|
||||
public override bool GetActionJustPressed(string action)
|
||||
|
|
@ -134,12 +141,12 @@ public partial class KeyboardInputProvider : InputProvider
|
|||
{
|
||||
return GetActionJustPressed(_inventoryActionName);
|
||||
}
|
||||
|
||||
|
||||
public override bool GetShootPressed()
|
||||
{
|
||||
return _enabled && GetActionPressed(_shootActionName);
|
||||
}
|
||||
|
||||
|
||||
public override bool GetShootJustPressed()
|
||||
{
|
||||
return GetActionJustPressed(_shootActionName);
|
||||
|
|
@ -149,6 +156,7 @@ public partial class KeyboardInputProvider : InputProvider
|
|||
{
|
||||
return GetActionJustPressed(_useActionName);
|
||||
}
|
||||
|
||||
public override bool GetScanJustPressed()
|
||||
{
|
||||
return GetActionJustPressed(_scanActionName);
|
||||
|
|
@ -173,25 +181,24 @@ public partial class KeyboardInputProvider : InputProvider
|
|||
{
|
||||
return GetActionJustPressed(_pauseActionName);
|
||||
}
|
||||
|
||||
|
||||
public override bool GetFreezeJustPressed()
|
||||
{
|
||||
return GetActionJustPressed(_freezeActionName);
|
||||
}
|
||||
|
||||
|
||||
public override bool GetFreezePressed()
|
||||
{
|
||||
return GetActionPressed(_freezeActionName);
|
||||
}
|
||||
|
||||
|
||||
public override bool GetReloadJustPressed()
|
||||
{
|
||||
return GetActionJustPressed(_reloadActionName);
|
||||
}
|
||||
|
||||
|
||||
public override bool GetReloadPressed()
|
||||
{
|
||||
return GetActionPressed(_reloadActionName);
|
||||
}
|
||||
|
||||
}
|
||||
13
Scripts/Components/Actors/MouseAimProvider2D.cs
Normal file
13
Scripts/Components/Actors/MouseAimProvider2D.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Components.Actors;
|
||||
|
||||
public partial class MouseAimProvider2D : Node2D, IMouseAimProvider
|
||||
{
|
||||
public Vector2 GetMouseAimInput()
|
||||
{
|
||||
var mouseWorldPos = this.GetGlobalMousePosition();
|
||||
|
||||
return mouseWorldPos - this.GlobalPosition;
|
||||
}
|
||||
}
|
||||
1
Scripts/Components/Actors/MouseAimProvider2D.cs.uid
Normal file
1
Scripts/Components/Actors/MouseAimProvider2D.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bfmnmk0rfwa1i
|
||||
16
Scripts/Components/Actors/MouseAimProvider3D.cs
Normal file
16
Scripts/Components/Actors/MouseAimProvider3D.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using Cirno.Scripts.Misc;
|
||||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Components.Actors;
|
||||
|
||||
public partial class MouseAimProvider3D : Node3D, IMouseAimProvider
|
||||
{
|
||||
public Vector2 GetMouseAimInput()
|
||||
{
|
||||
Vector2 mouseWorldPos = DisplayServer.MouseGetPosition();
|
||||
|
||||
var screenPosition = CameraController3D.Instance.UnprojectPosition(this.GlobalPosition);
|
||||
|
||||
return mouseWorldPos - screenPosition;
|
||||
}
|
||||
}
|
||||
1
Scripts/Components/Actors/MouseAimProvider3D.cs.uid
Normal file
1
Scripts/Components/Actors/MouseAimProvider3D.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://1fryvj4omkin
|
||||
|
|
@ -24,7 +24,7 @@ public partial class BulletSpawner : Node2D
|
|||
for (int i = 0; i < bulletInfo.BulletCount; i++)
|
||||
{
|
||||
// bullet = this.CreateChildOf<Bullet>(_gameManager.BulletsContainer, bulletScene, bulletInfo.Position);
|
||||
bullet = PoolingManager.Instance.SpawnBullet(bulletInfo.OriginalBulletResource);
|
||||
bullet = PoolingManager.Instance.SpawnBullet<Bullet>(bulletInfo.OriginalBulletResource);
|
||||
bullet.GlobalPosition = bulletInfo.Position;
|
||||
|
||||
// var bullet = this.CreateChildOf<Bullet>(_gameManager.BulletsContainer, bulletInfo.BulletScene ?? BulletScene, bulletInfo.Position);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ public partial class IsoMovementModule : ModuleBase<PlayerState, CharacterBody3D
|
|||
public int MovementSpeed => _isStrafing ? StrafeSpeed : Speed;
|
||||
|
||||
private IStateMachine<PlayerState, CharacterBody3D> _stateMachine;
|
||||
|
||||
private CharacterBody3D MainObject => _stateMachine.MainObject;
|
||||
|
||||
public override void EnterState(PlayerState state)
|
||||
|
|
|
|||
70
Scripts/Components/FSM/3DPlayer/PlayerWeaponModule3D.cs
Normal file
70
Scripts/Components/FSM/3DPlayer/PlayerWeaponModule3D.cs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
using Cirno.Scripts.Components.Actors;
|
||||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Components.FSM._3DPlayer;
|
||||
|
||||
public partial class PlayerWeaponModule3D : ModuleBase<PlayerState, CharacterBody3D>
|
||||
{
|
||||
[Export] public PlayerWeaponProvider3D WeaponProvider { get; private set; }
|
||||
|
||||
[Export] public InputProvider InputProvider { get; private set; }
|
||||
[Export] public IsoPlayerStorageModule Storage { get; private set; }
|
||||
|
||||
private IStateMachine<PlayerState, CharacterBody3D> _stateMachine;
|
||||
private CharacterBody3D MainObject => _stateMachine.MainObject;
|
||||
|
||||
public override void EnterState(PlayerState state)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void ExitState(PlayerState state)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Init(IStateMachine<PlayerState, CharacterBody3D> machine)
|
||||
{
|
||||
_stateMachine = machine;
|
||||
|
||||
WeaponProvider.Init(MainObject);
|
||||
}
|
||||
|
||||
public override void Process(double delta)
|
||||
{
|
||||
WeaponProvider.Update(delta);
|
||||
|
||||
HandleShoot();
|
||||
|
||||
HandleWeaponSwitch();
|
||||
}
|
||||
|
||||
public override void PhysicsProcess(double delta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void HandleShoot()
|
||||
{
|
||||
if (InputProvider.GetReloadJustPressed())
|
||||
{
|
||||
WeaponProvider.Reload();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InputProvider.GetShootPressed()) return;
|
||||
WeaponProvider.Shoot(Storage.AimingDirection);
|
||||
}
|
||||
|
||||
private void HandleWeaponSwitch()
|
||||
{
|
||||
if (InputProvider.GetWeaponNextJustPressed())
|
||||
{
|
||||
WeaponProvider.NextWeapon();
|
||||
}
|
||||
else if (InputProvider.GetWeaponPreviousJustPressed())
|
||||
{
|
||||
WeaponProvider.PreviousWeapon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://d2psafx4f3f58
|
||||
286
Scripts/Components/FSM/3DPlayer/PlayerWeaponProvider3D.cs
Normal file
286
Scripts/Components/FSM/3DPlayer/PlayerWeaponProvider3D.cs
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Cirno.Scripts.Weapons;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace Cirno.Scripts.Components.FSM._3DPlayer;
|
||||
|
||||
public partial class PlayerWeaponProvider3D : Node
|
||||
{
|
||||
[Export] public IsoPlayerStorageModule StorageModule { get; set; }
|
||||
[Export] public PackedScene WeaponTemplate { get; private set; }
|
||||
|
||||
[Export] public double WeaponSwitchCooldown { get; private set; } = 0.5d;
|
||||
|
||||
[Export] public Marker3D WeaponRightOffset { get; private set; } // local offset when facing right
|
||||
[Export] public Marker3D WeaponLeftOffset { get; private set; } // local offset when facing left
|
||||
|
||||
public Array<Weapon3D> EquippedWeapons { get; set; } = [];
|
||||
|
||||
private int _currentWeaponIndex = 0;
|
||||
|
||||
private double _switchCooldown = 0d;
|
||||
private bool _switching = false;
|
||||
|
||||
private int CurrentWeaponIndex
|
||||
{
|
||||
get => Math.Clamp(_currentWeaponIndex, 0, EquippedWeapons.Count -1);
|
||||
|
||||
set
|
||||
{
|
||||
if (value > EquippedWeapons.Count - 1)
|
||||
{
|
||||
_currentWeaponIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value < 0)
|
||||
{
|
||||
_currentWeaponIndex = EquippedWeapons.Count - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
_currentWeaponIndex = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Weapon3D EquippedWeapon { get; set; }
|
||||
|
||||
private CharacterBody3D _parent;
|
||||
|
||||
public void Init(CharacterBody3D parent)
|
||||
{
|
||||
_parent = parent;
|
||||
|
||||
InventoryManager.Instance.WeaponEquip += this.OnInventoryWeaponEquipped;
|
||||
|
||||
InventoryManager.Instance.ItemAdded += OnInventoryWeaponAdded;
|
||||
|
||||
EquipStartupWeapon();
|
||||
}
|
||||
|
||||
public void Update(double delta)
|
||||
{
|
||||
RotateWeapon();
|
||||
|
||||
if (!_switching) return;
|
||||
_switchCooldown += delta;
|
||||
if (_switchCooldown >= WeaponSwitchCooldown)
|
||||
{
|
||||
_switching = false;
|
||||
_switchCooldown = 0d;
|
||||
}
|
||||
}
|
||||
|
||||
private void RotateWeapon()
|
||||
{
|
||||
if (EquippedWeapon is null) return;
|
||||
|
||||
//EquippedWeapon.RotateWeapon(StorageModule.FacingDirection, WeaponLeftOffset.Position, WeaponRightOffset.Position);
|
||||
|
||||
|
||||
|
||||
// EquippedWeapon.SetRotation(angle + Mathf.Pi / 2.0f);
|
||||
//
|
||||
//
|
||||
//
|
||||
// EquippedWeapon.FlipH = facingLeft;
|
||||
//
|
||||
// // 3. Position on correct side (assuming EquippedWeapon is a child of the Player node)
|
||||
// EquippedWeapon.Position = facingLeft ? WeaponLeftOffset : WeaponRightOffset;
|
||||
}
|
||||
|
||||
private void OnInventoryWeaponEquipped(string itemKey)
|
||||
{
|
||||
Equip(itemKey, true);
|
||||
}
|
||||
|
||||
private void OnInventoryWeaponAdded(LootItem item, int amount)
|
||||
{
|
||||
if (item.Item is not ItemTypes.Weapon) return;
|
||||
Equip(item, false);
|
||||
}
|
||||
|
||||
private void EquipStartupWeapon()
|
||||
{
|
||||
if (EquippedWeapon is not null) return;
|
||||
if (!string.IsNullOrWhiteSpace(GlobalState.Session.EquippedWeaponId))
|
||||
{
|
||||
// equip it
|
||||
Equip(GlobalState.Session.EquippedWeaponId, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to equip whatever is first
|
||||
var weaponData = InventoryManager.Instance.Items.FirstOrDefault(x => x.Item.Item is ItemTypes.Weapon);
|
||||
if (weaponData is null) return;
|
||||
|
||||
Equip(weaponData.Item.ItemKey, false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// This is a soft equip
|
||||
public void AddWeapon(Weapon3D weapon)
|
||||
{
|
||||
EquippedWeapons.Add(weapon);
|
||||
}
|
||||
|
||||
// Triggered by event in inventorymanager
|
||||
private void EquipWeapon(Weapon3D weapon)
|
||||
{
|
||||
if (EquippedWeapon == weapon)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Need to start cooldown
|
||||
EquippedWeapon?.Hide();
|
||||
|
||||
EquippedWeapon = weapon;
|
||||
CurrentWeaponIndex = EquippedWeapons.IndexOf(weapon);
|
||||
GlobalState.Session.EquippedWeaponId = weapon.WeaponData.ItemKey;
|
||||
|
||||
EquippedWeapon.Show();
|
||||
|
||||
_switching = true;
|
||||
_switchCooldown = 0d;
|
||||
|
||||
InventoryManager.Instance.UpdateEquippedWeapon(weapon.WeaponData.ItemKey);
|
||||
}
|
||||
|
||||
public void NextWeapon()
|
||||
{
|
||||
CurrentWeaponIndex += 1;
|
||||
|
||||
Equip(EquippedWeapons[CurrentWeaponIndex], true);
|
||||
}
|
||||
|
||||
public void PreviousWeapon()
|
||||
{
|
||||
CurrentWeaponIndex -= 1;
|
||||
|
||||
Equip(EquippedWeapons[CurrentWeaponIndex], true);
|
||||
}
|
||||
|
||||
public void Shoot(Vector2 direction)
|
||||
{
|
||||
if (EquippedWeapon == null) return;
|
||||
if (_switching) return;
|
||||
|
||||
EquippedWeapon.ShootDirection = direction;
|
||||
EquippedWeapon.Shoot();
|
||||
}
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
if (EquippedWeapon == null) return;
|
||||
if (_switching) return;
|
||||
|
||||
EquippedWeapon.Reload();
|
||||
}
|
||||
|
||||
// Remastered method
|
||||
private LootItem GetItemFromInventory(string itemKey)
|
||||
{
|
||||
return InventoryManager.Instance.Items.FirstOrDefault(x => x.Item.ItemKey == itemKey)?.Item;
|
||||
}
|
||||
|
||||
private Weapon3D GetWeaponFromLocal(string itemKey)
|
||||
{
|
||||
return EquippedWeapons.FirstOrDefault(x => x.WeaponData.ItemKey == itemKey);
|
||||
}
|
||||
|
||||
// Remastered method
|
||||
private Weapon3D SpawnWeapon(string itemKey)
|
||||
{
|
||||
return SpawnWeapon(GetItemFromInventory(itemKey));
|
||||
}
|
||||
|
||||
// Remastered method
|
||||
private Weapon3D SpawnWeapon(LootItem startingItem)
|
||||
{
|
||||
if (startingItem is null)
|
||||
{
|
||||
GD.Print($"Could not spawn weapon was not in the inventory.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (WeaponTemplate == null)
|
||||
{
|
||||
GD.Print("Could not spawn weapon because template is null");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if it's not spawned already
|
||||
var maybeExistingWeapon = GetWeaponFromLocal(startingItem.ItemKey);
|
||||
if (maybeExistingWeapon is not null) return maybeExistingWeapon;
|
||||
|
||||
var weapon = WeaponTemplate.Instantiate<Weapon3D>();
|
||||
this.AddChild(weapon);
|
||||
//this.CreateSibling<Weapon>(WeaponTemplate);
|
||||
weapon.WeaponData = startingItem.WeaponData;
|
||||
|
||||
weapon.Sprite.Texture = startingItem.InventorySprite;
|
||||
|
||||
this.AddWeapon(weapon);
|
||||
return weapon;
|
||||
}
|
||||
|
||||
public Weapon3D Equip(LootItem item, bool force)
|
||||
{
|
||||
var maybeExistingWeapon = GetWeaponFromLocal(item.ItemKey);
|
||||
if (maybeExistingWeapon is not null) return Equip(maybeExistingWeapon, force);
|
||||
|
||||
// Spawn if not present
|
||||
var spawnedWeapon = SpawnWeapon(item);
|
||||
return Equip(spawnedWeapon, force);
|
||||
}
|
||||
|
||||
public Weapon3D Equip(string itemKey, bool force)
|
||||
{
|
||||
// Check in local inventory first
|
||||
var maybeExistingWeapon = GetWeaponFromLocal(itemKey);
|
||||
if (maybeExistingWeapon is not null) return Equip(maybeExistingWeapon, force);
|
||||
|
||||
// Spawn if not present
|
||||
var spawnedWeapon = SpawnWeapon(itemKey);
|
||||
if (spawnedWeapon is null)
|
||||
{
|
||||
GD.Print($"Tried to spawn weapon {itemKey} but failed because it was null.");
|
||||
return null;
|
||||
};
|
||||
return Equip(spawnedWeapon, force);
|
||||
}
|
||||
|
||||
public Weapon3D Equip(Weapon3D weapon, bool force)
|
||||
{
|
||||
// When we get here we already have a spawned weapon and it's in the list
|
||||
|
||||
if (weapon is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Always equip it if there's nothing equipped
|
||||
if (this.EquippedWeapon is null)
|
||||
{
|
||||
this.EquipWeapon(weapon);
|
||||
return weapon;
|
||||
}
|
||||
|
||||
// If it's a soft equip check for priority
|
||||
if (!force && this.EquippedWeapon.WeaponData.Priority < weapon.WeaponData.Priority)
|
||||
{
|
||||
this.EquipWeapon(weapon);
|
||||
return weapon;
|
||||
}
|
||||
|
||||
EquipWeapon(weapon);
|
||||
return weapon;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://by0x0qmbmkoak
|
||||
|
|
@ -75,6 +75,7 @@ public partial class FreezeModule : ModuleBase<PlayerState, CharacterBody2D>
|
|||
private List<Bullet> GetNearbyBullets()
|
||||
{
|
||||
return (from child in PoolingManager.Instance.GetAllActiveBullets()
|
||||
.Cast<Bullet>()
|
||||
where child is not null
|
||||
where child.Enabled // Could be redundant but better check in case of errors
|
||||
where child.BulletOwner is not BulletOwner.Player
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue