Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6575aa19c4 | ||
|
|
7ac03a54e4 | ||
|
|
874c524538 | ||
|
|
8623324fab | ||
|
|
80e429c8fa | ||
|
|
d96a4b6638 | ||
|
|
48a5620099 | ||
|
|
ad70108cdf | ||
|
|
97d08097fe | ||
|
|
961f365f52 | ||
|
|
78c711950a | ||
|
|
c0221b1445 | ||
|
|
dbcf17bab2 | ||
|
|
a88e0ee00f | ||
|
|
ba60bc7176 |
149
Content.Client/_CP14/Fishing/CP14FishingOverlay.cs
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Content.Client.Resources;
|
||||||
|
using Content.Shared._CP14.Fishing.Components;
|
||||||
|
using Content.Shared._CP14.Fishing.Prototypes;
|
||||||
|
using Content.Shared._CP14.Fishing.Systems;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.Player;
|
||||||
|
using Robust.Client.ResourceManagement;
|
||||||
|
using Robust.Shared.Enums;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Client._CP14.Fishing;
|
||||||
|
|
||||||
|
public sealed class CP14FishingOverlay : Overlay
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IComponentFactory _factory = default!;
|
||||||
|
[Dependency] private readonly IEntityManager _entity = default!;
|
||||||
|
[Dependency] private readonly IPlayerManager _player = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
|
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||||
|
|
||||||
|
private readonly SpriteSystem _sprite;
|
||||||
|
private readonly TransformSystem _transform;
|
||||||
|
private readonly CP14SharedFishingProcessSystem _sharedFishingProcess;
|
||||||
|
|
||||||
|
private Texture _backgroundTexture = default!;
|
||||||
|
private Texture _handleTopTexture = default!;
|
||||||
|
private Texture _handleMiddleTexture = default!;
|
||||||
|
private Texture _handleBottomTexture = default!;
|
||||||
|
|
||||||
|
private Texture _lootTexture = default!;
|
||||||
|
|
||||||
|
private Vector2 _backgroundOffset;
|
||||||
|
private Vector2 _backgroundHandleOffset;
|
||||||
|
private Vector2 _backgroundHandleSize;
|
||||||
|
|
||||||
|
private Vector2 _progressOffset;
|
||||||
|
private Vector2 _progressSize;
|
||||||
|
|
||||||
|
private EntityUid _process = EntityUid.Invalid;
|
||||||
|
|
||||||
|
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||||
|
|
||||||
|
public CP14FishingOverlay()
|
||||||
|
{
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
|
_sprite = _entity.System<SpriteSystem>();
|
||||||
|
_transform = _entity.System<TransformSystem>();
|
||||||
|
_sharedFishingProcess = _entity.System<CP14SharedFishingProcessSystem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(in OverlayDrawArgs args)
|
||||||
|
{
|
||||||
|
if (_player.LocalEntity is not { } localEntity)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_sharedFishingProcess.TryGetByUser(localEntity, out var fishingProcess))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Refresh the texture cache, with a new fishing process
|
||||||
|
if (_process != fishingProcess.Value.Owner)
|
||||||
|
{
|
||||||
|
_process = fishingProcess.Value.Owner;
|
||||||
|
|
||||||
|
UpdateCachedStyleSheet(_sharedFishingProcess.GetStyle(fishingProcess.Value));
|
||||||
|
|
||||||
|
var prototype = _prototype.Index(fishingProcess.Value.Comp.LootProtoId);
|
||||||
|
var iconPath = CP14FishingIconComponent.DefaultTexturePath;
|
||||||
|
|
||||||
|
if (prototype.Components.TryGetComponent(_factory.GetComponentName(typeof(CP14FishingIconComponent)), out var iconComponent))
|
||||||
|
{
|
||||||
|
var comp = (CP14FishingIconComponent) iconComponent;
|
||||||
|
iconPath = comp.TexturePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lootTexture = _resourceCache.GetTexture(iconPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getting the position of the player we will be working from
|
||||||
|
var worldPosition = _transform.GetWorldPosition(localEntity);
|
||||||
|
|
||||||
|
// Calculate the shift of the player relative to the bottom of the coordinates
|
||||||
|
var playerOffset = fishingProcess.Value.Comp.PlayerPositionNormalized * _backgroundHandleSize;
|
||||||
|
var playerHalfSize = fishingProcess.Value.Comp.PlayerHalfSizeNormalized * _backgroundHandleSize;
|
||||||
|
|
||||||
|
var lootOffset = fishingProcess.Value.Comp.LootPositionNormalized * _backgroundHandleSize + Vector2.UnitX * _backgroundHandleSize.X / 2;
|
||||||
|
|
||||||
|
DrawBackground(args.WorldHandle, worldPosition - _backgroundOffset);
|
||||||
|
DrawProgress(args.WorldHandle, worldPosition - _backgroundOffset + _progressOffset, _progressSize, fishingProcess.Value.Comp.Progress);
|
||||||
|
DrawHandle(args.WorldHandle, worldPosition - _backgroundOffset + _backgroundHandleOffset + playerOffset, playerHalfSize);
|
||||||
|
DrawLoot(args.WorldHandle, worldPosition - _backgroundOffset + _backgroundHandleOffset + lootOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawBackground(DrawingHandleWorld handle, Vector2 position)
|
||||||
|
{
|
||||||
|
handle.DrawTexture(_backgroundTexture, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawProgress(DrawingHandleWorld handle, Vector2 position, Vector2 size, float progress)
|
||||||
|
{
|
||||||
|
var vectorA = position;
|
||||||
|
var vectorB = position + new Vector2(size.X, size.Y * progress);
|
||||||
|
var box = new Box2(vectorA, vectorB);
|
||||||
|
|
||||||
|
handle.DrawRect(box, Color.Aqua);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawHandle(DrawingHandleWorld handle, Vector2 position, Vector2 halfSize)
|
||||||
|
{
|
||||||
|
var cursor = position - halfSize;
|
||||||
|
|
||||||
|
// Bottom
|
||||||
|
handle.DrawTexture(_handleBottomTexture, cursor);
|
||||||
|
cursor += new Vector2(0, _handleBottomTexture.Height / 32f);
|
||||||
|
|
||||||
|
// Middle
|
||||||
|
while (cursor.Y < position.Y + halfSize.Y - _handleTopTexture.Height / 32f)
|
||||||
|
{
|
||||||
|
handle.DrawTexture(_handleMiddleTexture, cursor);
|
||||||
|
cursor += new Vector2(0, _handleMiddleTexture.Height / 32f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Front
|
||||||
|
handle.DrawTexture(_handleTopTexture, cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawLoot(DrawingHandleWorld handle, Vector2 position)
|
||||||
|
{
|
||||||
|
handle.DrawTexture(_lootTexture, position - _lootTexture.Size / 64f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCachedStyleSheet(CP14FishingProcessStyleSheetPrototype styleSheet)
|
||||||
|
{
|
||||||
|
_backgroundTexture = _resourceCache.GetTexture(styleSheet.Background.Texture);
|
||||||
|
_handleTopTexture = _resourceCache.GetTexture(styleSheet.Handle.TopTexture);
|
||||||
|
_handleMiddleTexture = _resourceCache.GetTexture(styleSheet.Handle.MiddleTexture);
|
||||||
|
_handleBottomTexture = _resourceCache.GetTexture(styleSheet.Handle.BottomTexture);
|
||||||
|
|
||||||
|
_backgroundOffset = styleSheet.Background.Offset + Vector2.UnitX * _backgroundTexture.Width / 32f;
|
||||||
|
|
||||||
|
_backgroundHandleOffset = styleSheet.Background.HandleOffset;
|
||||||
|
_backgroundHandleSize = styleSheet.Background.HandleSize;
|
||||||
|
|
||||||
|
_progressOffset = styleSheet.Background.ProgressOffset;
|
||||||
|
_progressSize = styleSheet.Background.ProgressSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
Content.Client/_CP14/Fishing/CP14FishingOverlaySystem.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Content.Client.Overlays;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
|
||||||
|
namespace Content.Client._CP14.Fishing;
|
||||||
|
|
||||||
|
public sealed class CP14FishingOverlaySystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IOverlayManager _overlay = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
_overlay.AddOverlay(new CP14FishingOverlay());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Shutdown()
|
||||||
|
{
|
||||||
|
base.Shutdown();
|
||||||
|
|
||||||
|
_overlay.RemoveOverlay<StencilOverlay>();
|
||||||
|
}
|
||||||
|
}
|
||||||
5
Content.Client/_CP14/Fishing/CP14FishingProcessSystem.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
using Content.Shared._CP14.Fishing.Systems;
|
||||||
|
|
||||||
|
namespace Content.Client._CP14.Fishing;
|
||||||
|
|
||||||
|
public sealed class CP14FishingProcessSystem : CP14SharedFishingProcessSystem;
|
||||||
35
Content.Client/_CP14/Fishing/CP14FishingRodSystem.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
using Content.Client.Hands.Systems;
|
||||||
|
using Content.Shared._CP14.Fishing.Components;
|
||||||
|
using Content.Shared._CP14.Fishing.Systems;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Shared.Input;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Client._CP14.Fishing;
|
||||||
|
|
||||||
|
public sealed class CP14FishingRodSystem : CP14SharedFishingRodSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
[Dependency] private readonly InputSystem _input = default!;
|
||||||
|
[Dependency] private readonly HandsSystem _hands = default!;
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
if (!_timing.IsFirstTimePredicted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var handUid = _hands.GetActiveHandEntity();
|
||||||
|
|
||||||
|
if (!TryComp<CP14FishingRodComponent>(handUid, out var fishingRodComponent))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var reelKey = _input.CmdStates.GetState(EngineKeyFunctions.UseSecondary) == BoundKeyState.Down;
|
||||||
|
|
||||||
|
if (fishingRodComponent.Reeling == reelKey)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RaisePredictiveEvent(new RequestFishingRodReelMessage(reelKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
121
Content.Server/_CP14/Fishing/CP14FishingProcessSystem.cs
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
using Content.Shared._CP14.Fishing.Components;
|
||||||
|
using Content.Shared._CP14.Fishing.Core;
|
||||||
|
using Content.Shared._CP14.Fishing.Core.Behaviors;
|
||||||
|
using Content.Shared._CP14.Fishing.Events;
|
||||||
|
using Content.Shared._CP14.Fishing.Systems;
|
||||||
|
using Content.Shared.Throwing;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Server._CP14.Fishing;
|
||||||
|
|
||||||
|
public sealed class CP14FishingProcessSystem : CP14SharedFishingProcessSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
[Dependency] private readonly ThrowingSystem _throwing = default!;
|
||||||
|
[Dependency] private readonly CP14FishingPoolSystem _pool = default!;
|
||||||
|
|
||||||
|
/*
|
||||||
|
private readonly TimeSpan _dirtyDelay = TimeSpan.FromTicks(10000000000000);
|
||||||
|
private TimeSpan _dirtyDelayTime;
|
||||||
|
*/
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
// DON'T CALL BASE METHOD!!!
|
||||||
|
|
||||||
|
var query = EntityQueryEnumerator<CP14FishingProcessComponent>();
|
||||||
|
while (query.MoveNext(out var entityUid, out var processComponent))
|
||||||
|
{
|
||||||
|
Update((entityUid, processComponent), frameTime * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void FishPreUpdate(Entity<CP14FishingProcessComponent> process, Fish fish, float frameTime)
|
||||||
|
{
|
||||||
|
base.FishPreUpdate(process, fish, frameTime);
|
||||||
|
|
||||||
|
fish.UpdateSpeed(_random, _timing);
|
||||||
|
Dirty(process);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateDirty(Entity<CP14FishingProcessComponent> process)
|
||||||
|
{
|
||||||
|
base.UpdateDirty(process);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (_timing.CurTime < _dirtyDelayTime)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_dirtyDelayTime = _timing.CurTime + _dirtyDelay;
|
||||||
|
Dirty(process);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Finish(Entity<CP14FishingProcessComponent> process, bool success)
|
||||||
|
{
|
||||||
|
base.Finish(process, success);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
Reward(process);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Raising events before deletion
|
||||||
|
var ev = new CP14FishingFinishedEvent(success);
|
||||||
|
RaiseLocalEvent(process, ref ev, true);
|
||||||
|
|
||||||
|
// Either way, we need to delete the process
|
||||||
|
Stop(process);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Reward(Entity<CP14FishingProcessComponent> process)
|
||||||
|
{
|
||||||
|
base.Reward(process);
|
||||||
|
|
||||||
|
var pool = GetPool(process);
|
||||||
|
var rod = GetRod(process);
|
||||||
|
|
||||||
|
var coordinates = Transform(pool).Coordinates;
|
||||||
|
var targetCoordinates = Transform(process.Comp.User!.Value).Coordinates;
|
||||||
|
|
||||||
|
var loot = Spawn(process.Comp.LootProtoId, coordinates);
|
||||||
|
|
||||||
|
_throwing.TryThrow(loot, targetCoordinates, rod.Comp.ThrowPower);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity<CP14FishingProcessComponent> Start(
|
||||||
|
Entity<CP14FishingRodComponent> fishingRod,
|
||||||
|
Entity<CP14FishingPoolComponent> fishingPool,
|
||||||
|
EntityUid user)
|
||||||
|
{
|
||||||
|
var process = CreateProcess(fishingRod.Owner);
|
||||||
|
var loot = _pool.GetLootPrototypeId(fishingPool);
|
||||||
|
var style = GetStyle(fishingRod);
|
||||||
|
|
||||||
|
// Save entities
|
||||||
|
process.Comp.FishingRod = fishingRod;
|
||||||
|
process.Comp.FishingPool = fishingPool;
|
||||||
|
process.Comp.User = user;
|
||||||
|
|
||||||
|
process.Comp.Player = new Player(fishingRod.Comp.Size);
|
||||||
|
process.Comp.Fish = new Fish(new MixedBehavior(), _timing.CurTime + TimeSpan.FromSeconds(0.5f));
|
||||||
|
|
||||||
|
process.Comp.LootProtoId = loot;
|
||||||
|
process.Comp.StyleSheet = style;
|
||||||
|
|
||||||
|
Dirty(process);
|
||||||
|
|
||||||
|
Log.Debug($"Started new fishing process at {process}");
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity<CP14FishingProcessComponent> CreateProcess(EntityUid parent)
|
||||||
|
{
|
||||||
|
var entityUid = SpawnAttachedTo(null, Transform(parent).Coordinates);
|
||||||
|
var ensureComponent = AddComp<CP14FishingProcessComponent>(entityUid);
|
||||||
|
|
||||||
|
return (entityUid, ensureComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
31
Content.Server/_CP14/Fishing/CP14FishingRodSystem.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using Content.Shared._CP14.Fishing.Components;
|
||||||
|
using Content.Shared._CP14.Fishing.Systems;
|
||||||
|
using Content.Shared.Interaction;
|
||||||
|
|
||||||
|
namespace Content.Server._CP14.Fishing;
|
||||||
|
|
||||||
|
public sealed class CP14FishingRodSystem : CP14SharedFishingRodSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly CP14FishingProcessSystem _fishingProcess = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<CP14FishingPoolComponent, AfterInteractUsingEvent>(OnAfterInteractUsing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAfterInteractUsing(Entity<CP14FishingPoolComponent> entity, ref AfterInteractUsingEvent args)
|
||||||
|
{
|
||||||
|
if (args.Handled || !args.CanReach)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp<CP14FishingRodComponent>(args.Used, out var fishingRodComponent))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fishingRodComponent.Process is not null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fishingRodComponent.Process = _fishingProcess.Start((args.Used, fishingRodComponent), entity, args.User);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Components;
|
||||||
|
|
||||||
|
[RegisterComponent, NetworkedComponent]
|
||||||
|
public sealed partial class CP14FishingIconComponent : Component
|
||||||
|
{
|
||||||
|
public static readonly ResPath DefaultTexturePath = new("/Textures/_CP14/Interface/Fishing/Icons/default.png");
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public ResPath TexturePath = DefaultTexturePath;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using Content.Shared._CP14.Fishing.Prototypes;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Components;
|
||||||
|
|
||||||
|
[RegisterComponent, NetworkedComponent]
|
||||||
|
public sealed partial class CP14FishingPoolComponent : Component
|
||||||
|
{
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public ProtoId<CP14FishingPoolLootTablePrototype> LootTable = "Default";
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Content.Shared._CP14.Fishing.Core;
|
||||||
|
using Content.Shared._CP14.Fishing.Prototypes;
|
||||||
|
using Content.Shared._CP14.Fishing.Systems;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Components;
|
||||||
|
|
||||||
|
[Access(typeof(CP14SharedFishingProcessSystem))]
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
public sealed partial class CP14FishingProcessComponent : Component
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Boxes
|
||||||
|
*/
|
||||||
|
|
||||||
|
[ViewVariables, AutoNetworkedField]
|
||||||
|
public Player? Player;
|
||||||
|
|
||||||
|
[ViewVariables, AutoNetworkedField]
|
||||||
|
public Fish? Fish;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Progress
|
||||||
|
*/
|
||||||
|
|
||||||
|
[ViewVariables, AutoNetworkedField]
|
||||||
|
public float Progress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saved entities
|
||||||
|
*/
|
||||||
|
|
||||||
|
[ViewVariables, AutoNetworkedField]
|
||||||
|
public EntityUid? FishingRod = null;
|
||||||
|
|
||||||
|
[ViewVariables, AutoNetworkedField]
|
||||||
|
public EntityUid? User = null;
|
||||||
|
|
||||||
|
[ViewVariables, AutoNetworkedField]
|
||||||
|
public EntityUid? FishingPool = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loot
|
||||||
|
*/
|
||||||
|
|
||||||
|
[ViewVariables, AutoNetworkedField]
|
||||||
|
public EntProtoId LootProtoId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Style
|
||||||
|
*/
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public CP14FishingProcessStyleSheetPrototype? StyleSheet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalized
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Vector2 LootPositionNormalized => Vector2.UnitY * Fish?.Position ?? Vector2.Zero;
|
||||||
|
public Vector2 PlayerPositionNormalized => Vector2.UnitY * Player?.Position ?? Vector2.Zero;
|
||||||
|
public Vector2 PlayerHalfSizeNormalized => Vector2.UnitY * Player?.HalfSize ?? Vector2.Zero;
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using Content.Shared._CP14.Fishing.Prototypes;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Components;
|
||||||
|
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
public sealed partial class CP14FishingRodComponent : Component
|
||||||
|
{
|
||||||
|
[ViewVariables]
|
||||||
|
public static readonly ProtoId<CP14FishingProcessStyleSheetPrototype> DefaultStyle = "Default";
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public EntityUid? Process;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||||
|
public bool Reeling;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||||
|
public float Speed = 0.1f;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||||
|
public float Gravity = 0.075f;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||||
|
public float MaxVelocity = 0.3f;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||||
|
public float MinVelocity = -0.325f;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||||
|
public float Bouncing = 0.07f;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||||
|
public float Drag = 0.98f;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||||
|
public float Size = 0.25f;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||||
|
public float ThrowPower = 10f;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public ProtoId<CP14FishingProcessStyleSheetPrototype> Style = DefaultStyle;
|
||||||
|
}
|
||||||
18
Content.Shared/_CP14/Fishing/Core/Behaviors/Behavior.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Core.Behaviors;
|
||||||
|
|
||||||
|
[ImplicitDataDefinitionForInheritors, MeansImplicitUse]
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public abstract partial class Behavior
|
||||||
|
{
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float Speed { get; set; } = 0.25f;
|
||||||
|
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float Difficulty { get; set; } = 2f;
|
||||||
|
|
||||||
|
public abstract float CalculateSpeed(IRobustRandom random);
|
||||||
|
}
|
||||||
11
Content.Shared/_CP14/Fishing/Core/Behaviors/DartBehavior.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Core.Behaviors;
|
||||||
|
|
||||||
|
public sealed partial class DartBehavior : Behavior
|
||||||
|
{
|
||||||
|
public override float CalculateSpeed(IRobustRandom random)
|
||||||
|
{
|
||||||
|
return Speed * (0.5f + random.NextFloat() * Difficulty);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Core.Behaviors;
|
||||||
|
|
||||||
|
public sealed partial class FloaterBehaviour : Behavior
|
||||||
|
{
|
||||||
|
public override float CalculateSpeed(IRobustRandom random)
|
||||||
|
{
|
||||||
|
return Speed * (0.5f + random.NextFloat() * Difficulty);
|
||||||
|
}
|
||||||
|
}
|
||||||
13
Content.Shared/_CP14/Fishing/Core/Behaviors/MixedBehavior.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Core.Behaviors;
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed partial class MixedBehavior : Behavior
|
||||||
|
{
|
||||||
|
public override float CalculateSpeed(IRobustRandom random)
|
||||||
|
{
|
||||||
|
return Speed * (random.NextFloat() - 0.5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Core.Behaviors;
|
||||||
|
|
||||||
|
public sealed partial class SinkerBehavior : Behavior
|
||||||
|
{
|
||||||
|
public override float CalculateSpeed(IRobustRandom random)
|
||||||
|
{
|
||||||
|
return Speed * (1.0f + random.NextFloat() * 0.5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Core.Behaviors;
|
||||||
|
|
||||||
|
public sealed partial class SmoothBehavior : Behavior
|
||||||
|
{
|
||||||
|
public override float CalculateSpeed(IRobustRandom random)
|
||||||
|
{
|
||||||
|
return Speed * (0.5f + random.NextFloat() * Difficulty);
|
||||||
|
}
|
||||||
|
}
|
||||||
49
Content.Shared/_CP14/Fishing/Core/Fish.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using Content.Shared._CP14.Fishing.Core.Behaviors;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Core;
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class Fish
|
||||||
|
{
|
||||||
|
private const float MaxPosition = 1f;
|
||||||
|
private const float MinPosition = 0f;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float Position { get; private set; }
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
private readonly Behavior _behavior;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
private float _speed;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
private TimeSpan _updateSpeedTime;
|
||||||
|
|
||||||
|
public Fish(Behavior behavior, TimeSpan updateSpeedTime)
|
||||||
|
{
|
||||||
|
_behavior = behavior;
|
||||||
|
_updateSpeedTime = updateSpeedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(float frameTime)
|
||||||
|
{
|
||||||
|
// Update position
|
||||||
|
Position += _speed * frameTime;
|
||||||
|
|
||||||
|
// Clamp position
|
||||||
|
Position = Math.Clamp(Position, MinPosition, MaxPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateSpeed(IRobustRandom random, IGameTiming timing)
|
||||||
|
{
|
||||||
|
if (_updateSpeedTime > timing.CurTime)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_speed = _behavior.CalculateSpeed(random);
|
||||||
|
_updateSpeedTime = timing.CurTime + TimeSpan.FromSeconds(random.NextFloat(1.5f - 1f / _behavior.Difficulty, 2.5f - 1f / _behavior.Difficulty));
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Content.Shared/_CP14/Fishing/Core/Player.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Core;
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class Player
|
||||||
|
{
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float Size;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float Position;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float Velocity;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public float HalfSize => Size / 2f;
|
||||||
|
|
||||||
|
public Player(float size = 0.25f)
|
||||||
|
{
|
||||||
|
Size = size;
|
||||||
|
Position = HalfSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace Content.Shared._CP14.Fishing.Events;
|
||||||
|
|
||||||
|
[ByRefEvent]
|
||||||
|
public readonly struct CP14FishingFinishedEvent
|
||||||
|
{
|
||||||
|
public readonly bool Success;
|
||||||
|
|
||||||
|
public CP14FishingFinishedEvent(bool success)
|
||||||
|
{
|
||||||
|
Success = success;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Prototypes;
|
||||||
|
|
||||||
|
[Prototype("CP14FishingPoolLootTable")]
|
||||||
|
public sealed class CP14FishingPoolLootTablePrototype : IPrototype
|
||||||
|
{
|
||||||
|
[IdDataField]
|
||||||
|
public string ID { get; } = string.Empty;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public List<EntProtoId> Prototypes = [];
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Prototypes;
|
||||||
|
|
||||||
|
[Prototype("CP14FishingProcess")]
|
||||||
|
public sealed class CP14FishingProcessPrototype : IPrototype
|
||||||
|
{
|
||||||
|
[IdDataField]
|
||||||
|
public string ID { get; } = string.Empty;
|
||||||
|
|
||||||
|
[DataField, ViewVariables]
|
||||||
|
public EntProtoId LootProtoId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Prototypes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the style sheet for the fishing process, containing UI elements like background and handle configurations.
|
||||||
|
/// </summary>
|
||||||
|
[Prototype("CP14FishingProcessStyleSheet")]
|
||||||
|
public sealed partial class CP14FishingProcessStyleSheetPrototype : IPrototype
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the unique identifier for this fishing process style sheet prototype.
|
||||||
|
/// </summary>
|
||||||
|
[IdDataField]
|
||||||
|
public string ID { get; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Background settings for the fishing process UI.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, ViewVariables]
|
||||||
|
public BackgroundData Background = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle settings for the fishing process UI.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, ViewVariables]
|
||||||
|
public HandleData Handle = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains data related to the background of the fishing process UI.
|
||||||
|
/// </summary>
|
||||||
|
[DataDefinition, Serializable]
|
||||||
|
public sealed partial class BackgroundData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Path to the background texture image.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public string Texture = "/Textures/_CP14/Interface/Fishing/background.png";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Offset of the background texture in pixels.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("offset"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public Vector2 OffsetPixels = new(10, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Offset of the handle in pixels.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("handleOffset"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public Vector2 HandleOffsetPixels = new(16, 4);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Size of the handle in pixels.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("handleSize"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public Vector2 HandleSizePixels = new(149, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Offset of the progress bar in pixels.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("progressOffset"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public Vector2 ProgressOffsetPixels = new(31, 3);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Size of the progress bar in pixels.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("progressSize"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public Vector2 ProgressSizePixels = new(4, 144);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the background offset in units (pixels divided by 32).
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public Vector2 Offset => OffsetPixels / 32f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the handle offset in units (pixels divided by 32).
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public Vector2 HandleOffset => HandleOffsetPixels / 32f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the progress bar offset in units (pixels divided by 32).
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public Vector2 ProgressOffset => ProgressOffsetPixels / 32f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the progress bar size in units (pixels divided by 32).
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public Vector2 ProgressSize => ProgressSizePixels / 32f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the handle size in units (pixels divided by 32).
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public Vector2 HandleSize => HandleSizePixels / 32f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains data related to the handle elements of the fishing process UI.
|
||||||
|
/// </summary>
|
||||||
|
[DataDefinition, Serializable]
|
||||||
|
public sealed partial class HandleData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Path to the texture for the top part of the handle.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public string TopTexture = "/Textures/_CP14/Interface/Fishing/Handle/top.png";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Path to the texture for the middle part of the handle.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public string MiddleTexture = "/Textures/_CP14/Interface/Fishing/Handle/middle.png";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Path to the texture for the bottom part of the handle.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public string BottomTexture = "/Textures/_CP14/Interface/Fishing/Handle/bottom.png";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using Content.Shared._CP14.Fishing.Components;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Systems;
|
||||||
|
|
||||||
|
public sealed class CP14FishingPoolSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
|
||||||
|
public EntProtoId GetLootPrototypeId(Entity<CP14FishingPoolComponent> pool)
|
||||||
|
{
|
||||||
|
var lootTable = _prototype.Index(pool.Comp.LootTable);
|
||||||
|
var loot = _random.Pick(lootTable.Prototypes);
|
||||||
|
|
||||||
|
return loot;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using Content.Shared._CP14.Fishing.Components;
|
||||||
|
using Content.Shared._CP14.Fishing.Core;
|
||||||
|
using Content.Shared._CP14.Fishing.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Systems;
|
||||||
|
|
||||||
|
public abstract partial class CP14SharedFishingProcessSystem
|
||||||
|
{
|
||||||
|
protected Entity<CP14FishingRodComponent> GetRod(Entity<CP14FishingProcessComponent> process)
|
||||||
|
{
|
||||||
|
var entityUid = process.Comp.FishingRod!.Value;
|
||||||
|
var component = FishingRod.GetComponent(entityUid);
|
||||||
|
return (entityUid, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Entity<CP14FishingPoolComponent> GetPool(Entity<CP14FishingProcessComponent> process)
|
||||||
|
{
|
||||||
|
var entityUid = process.Comp.FishingPool!.Value;
|
||||||
|
var component = FishingPool.GetComponent(entityUid);
|
||||||
|
return (entityUid, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CP14FishingProcessStyleSheetPrototype GetStyle(Entity<CP14FishingProcessComponent> process)
|
||||||
|
{
|
||||||
|
return GetStyle(GetRod(process));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CP14FishingProcessStyleSheetPrototype GetStyle(Entity<CP14FishingRodComponent> fishingRod)
|
||||||
|
{
|
||||||
|
if (_prototype.TryIndex(fishingRod.Comp.Style, out var style))
|
||||||
|
return style;
|
||||||
|
|
||||||
|
Log.Error($"Failed to retrieve fishing rod style, {fishingRod.Comp.Style} not found. Reverting to default style.");
|
||||||
|
return _prototype.Index(CP14FishingRodComponent.DefaultStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static bool Collide(Fish fish, Player player)
|
||||||
|
{
|
||||||
|
var playerMin = player.Position - player.HalfSize;
|
||||||
|
var playerMax = player.Position + player.HalfSize;
|
||||||
|
return fish.Position >= playerMin && fish.Position <= playerMax;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Content.Shared._CP14.Fishing.Components;
|
||||||
|
using Content.Shared._CP14.Fishing.Core;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Systems;
|
||||||
|
|
||||||
|
public abstract partial class CP14SharedFishingProcessSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
|
|
||||||
|
protected EntityQuery<CP14FishingRodComponent> FishingRod;
|
||||||
|
protected EntityQuery<CP14FishingPoolComponent> FishingPool;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
FishingRod = GetEntityQuery<CP14FishingRodComponent>();
|
||||||
|
FishingPool = GetEntityQuery<CP14FishingPoolComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
var query = EntityQueryEnumerator<CP14FishingProcessComponent>();
|
||||||
|
while (query.MoveNext(out var entityUid, out var processComponent))
|
||||||
|
{
|
||||||
|
Update((entityUid, processComponent), frameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateReeling(Entity<CP14FishingProcessComponent> process,
|
||||||
|
Entity<CP14FishingRodComponent> fishingRod,
|
||||||
|
float frameTime)
|
||||||
|
{
|
||||||
|
if (process.Comp.Player is not { } player)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fishingRod.Comp.Reeling)
|
||||||
|
{
|
||||||
|
player.Velocity += fishingRod.Comp.Speed * frameTime;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.Velocity -= fishingRod.Comp.Gravity * frameTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateVelocity(Entity<CP14FishingProcessComponent> process,
|
||||||
|
Entity<CP14FishingRodComponent> fishingRod)
|
||||||
|
{
|
||||||
|
if (process.Comp.Player is not { } player)
|
||||||
|
return;
|
||||||
|
|
||||||
|
player.Velocity *= fishingRod.Comp.Drag;
|
||||||
|
player.Velocity = Math.Clamp(player.Velocity,
|
||||||
|
fishingRod.Comp.MinVelocity,
|
||||||
|
fishingRod.Comp.MaxVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdatePosition(Entity<CP14FishingProcessComponent> process,
|
||||||
|
float frameTime)
|
||||||
|
{
|
||||||
|
if (process.Comp.Player is not { } player)
|
||||||
|
return;
|
||||||
|
|
||||||
|
player.Position += process.Comp.Player.Velocity * frameTime;
|
||||||
|
|
||||||
|
var halfSize = process.Comp.Player.HalfSize;
|
||||||
|
process.Comp.Player.Position = Math.Clamp(process.Comp.Player.Position, halfSize, 1 - halfSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(Entity<CP14FishingProcessComponent> process, float frameTime)
|
||||||
|
{
|
||||||
|
if (process.Comp.Player is not { } player)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var fishingRod = GetRod(process);
|
||||||
|
|
||||||
|
UpdateReeling(process, fishingRod, frameTime);
|
||||||
|
UpdateVelocity(process, fishingRod);
|
||||||
|
UpdatePosition(process, frameTime);
|
||||||
|
|
||||||
|
if (process.Comp.Fish is { } fish)
|
||||||
|
{
|
||||||
|
FishPreUpdate(process, fish, frameTime);
|
||||||
|
|
||||||
|
fish.Update(frameTime);
|
||||||
|
var collides = Collide(fish, player);
|
||||||
|
|
||||||
|
var progressAdditive = collides ? 0.1f : -0.2f;
|
||||||
|
process.Comp.Progress = Math.Clamp(process.Comp.Progress + progressAdditive * frameTime, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateDirty(process);
|
||||||
|
|
||||||
|
if (process.Comp.Progress is 1 or 0)
|
||||||
|
Finish(process, process.Comp.Progress is 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void FishPreUpdate(Entity<CP14FishingProcessComponent> process, Fish fish, float frameTime)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void UpdateDirty(Entity<CP14FishingProcessComponent> process)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Finish(Entity<CP14FishingProcessComponent> process, bool success)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop(Entity<CP14FishingProcessComponent> process)
|
||||||
|
{
|
||||||
|
var rod = GetRod(process);
|
||||||
|
rod.Comp.Process = null;
|
||||||
|
Dirty(rod);
|
||||||
|
|
||||||
|
Del(process);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Reward(Entity<CP14FishingProcessComponent> process)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetByUser(EntityUid userEntityUid, [NotNullWhen(true)] out Entity<CP14FishingProcessComponent>? process)
|
||||||
|
{
|
||||||
|
process = null;
|
||||||
|
|
||||||
|
var query = EntityQueryEnumerator<CP14FishingProcessComponent>();
|
||||||
|
while (query.MoveNext(out var entityUid, out var processComponent))
|
||||||
|
{
|
||||||
|
if (processComponent.User != userEntityUid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
process = (entityUid, processComponent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
using Content.Shared._CP14.Fishing.Components;
|
||||||
|
using Content.Shared.Hands;
|
||||||
|
using Content.Shared.Hands.Components;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared._CP14.Fishing.Systems;
|
||||||
|
|
||||||
|
public abstract class CP14SharedFishingRodSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeAllEvent<RequestFishingRodReelMessage>(OnReel);
|
||||||
|
SubscribeLocalEvent<CP14FishingRodComponent, HandDeselectedEvent>(OnDeselected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnReel(RequestFishingRodReelMessage msg, EntitySessionEventArgs args)
|
||||||
|
{
|
||||||
|
var player = args.SenderSession.AttachedEntity;
|
||||||
|
|
||||||
|
if (!TryComp<HandsComponent>(player, out var hands))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp<CP14FishingRodComponent>(hands.ActiveHandEntity, out var fishingRodComponent))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fishingRodComponent.Reeling == msg.Reeling)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fishingRodComponent.Reeling = msg.Reeling;
|
||||||
|
Dirty(hands.ActiveHandEntity.Value, fishingRodComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDeselected(Entity<CP14FishingRodComponent> entity, ref HandDeselectedEvent args)
|
||||||
|
{
|
||||||
|
entity.Comp.Reeling = false;
|
||||||
|
Dirty(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
protected sealed class RequestFishingRodReelMessage : EntityEventArgs
|
||||||
|
{
|
||||||
|
public bool Reeling;
|
||||||
|
|
||||||
|
public RequestFishingRodReelMessage(bool reeling)
|
||||||
|
{
|
||||||
|
Reeling = reeling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
- type: entity
|
||||||
|
parent: BaseItem
|
||||||
|
id: CP14FishingRod
|
||||||
|
name: fishing rod
|
||||||
|
description: Wooden stick with string attached.
|
||||||
|
categories: [ ForkFiltered ]
|
||||||
|
components:
|
||||||
|
- type: Item
|
||||||
|
shape:
|
||||||
|
- 0,0,0,1
|
||||||
|
- type: Sprite
|
||||||
|
sprite: _CP14/Objects/Tools/fishing_rod.rsi
|
||||||
|
state: icon
|
||||||
|
- type: Damageable
|
||||||
|
damageContainer: Inorganic
|
||||||
|
- type: Destructible
|
||||||
|
thresholds:
|
||||||
|
- trigger:
|
||||||
|
!type:DamageTrigger
|
||||||
|
damage: 50
|
||||||
|
behaviors:
|
||||||
|
- !type:PlaySoundBehavior
|
||||||
|
sound:
|
||||||
|
collection: MetalBreak
|
||||||
|
- !type:CP14ModularDisassembleBehavior
|
||||||
|
- !type:DoActsBehavior
|
||||||
|
acts: ["Destruction"]
|
||||||
|
- type: CP14ModularCraftStartPoint
|
||||||
|
startSlots:
|
||||||
|
- FishingRodShaft
|
||||||
|
- type: MeleeWeapon
|
||||||
|
angle: 45
|
||||||
|
attackRate: 1
|
||||||
|
wideAnimationRotation: 135
|
||||||
|
wideAnimation: CP14WeaponArcSlash
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Blunt: 0.1
|
||||||
|
soundHit:
|
||||||
|
collection: MetalThud
|
||||||
|
cPAnimationLength: 0.25
|
||||||
|
- type: Clothing
|
||||||
|
equipDelay: 0.25
|
||||||
|
unequipDelay: 0.25
|
||||||
|
quickEquip: false
|
||||||
|
breakOnMove: false
|
||||||
|
slots:
|
||||||
|
- neck
|
||||||
|
- type: CP14FishingRod
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
snap:
|
snap:
|
||||||
- Wall
|
- Wall
|
||||||
components:
|
components:
|
||||||
|
- type: CP14FishingPool
|
||||||
- type: PlacementReplacement
|
- type: PlacementReplacement
|
||||||
key: floorTile
|
key: floorTile
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
@@ -120,4 +121,4 @@
|
|||||||
- CP14GatherableWaterAirLily
|
- CP14GatherableWaterAirLily
|
||||||
chance: 1
|
chance: 1
|
||||||
offset: 0.2
|
offset: 0.2
|
||||||
deleteSpawnerAfterSpawn: false
|
deleteSpawnerAfterSpawn: false
|
||||||
|
|||||||
4
Resources/Prototypes/_CP14/Fishing/lootTables.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
- type: CP14FishingPoolLootTable
|
||||||
|
id: Default
|
||||||
|
prototypes:
|
||||||
|
- CP14BaseLockpick
|
||||||
13
Resources/Prototypes/_CP14/Fishing/styleSheets.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
- type: CP14FishingProcessStyleSheet
|
||||||
|
id: Default
|
||||||
|
background:
|
||||||
|
texture: /Textures/_CP14/Interface/Fishing/Styles/Default/background.png
|
||||||
|
offset: 10, 0
|
||||||
|
handleOffset: 14, 5
|
||||||
|
handleSize: 11, 141
|
||||||
|
progressOffset: 4, 4
|
||||||
|
progressSize: 2, 142
|
||||||
|
handle:
|
||||||
|
topTexture: /Textures/_CP14/Interface/Fishing/Styles/Default/Handle/top.png
|
||||||
|
middleTexture: /Textures/_CP14/Interface/Fishing/Styles/Default/Handle/middle.png
|
||||||
|
bottomTexture: /Textures/_CP14/Interface/Fishing/Styles/Default/Handle/bottom.png
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
- files:
|
||||||
|
- "/fish.png"
|
||||||
|
license: "CC-BY-NC-SA-3.0"
|
||||||
|
copyright: "@omsoyk (Discord)"
|
||||||
|
source: "https://github.com/crystallpunk-14/crystall-punk-14"
|
||||||
|
|
||||||
|
- files:
|
||||||
|
- "/default.png"
|
||||||
|
license: "CC-BY-NC-SA-3.0"
|
||||||
|
copyright: "@tornadotech (Discord), Tornado-Technology (Github)"
|
||||||
|
source: "https://github.com/crystallpunk-14/crystall-punk-14"
|
||||||
BIN
Resources/Textures/_CP14/Interface/Fishing/Icons/default.png
Normal file
|
After Width: | Height: | Size: 222 B |
BIN
Resources/Textures/_CP14/Interface/Fishing/Icons/fish.png
Normal file
|
After Width: | Height: | Size: 256 B |
|
After Width: | Height: | Size: 161 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 215 B |
@@ -0,0 +1,9 @@
|
|||||||
|
- files:
|
||||||
|
- "/background.png"
|
||||||
|
- "Handle/top.png"
|
||||||
|
- "Handle/middle.png"
|
||||||
|
- "Handle/bottom.png"
|
||||||
|
license: "CC-BY-NC-SA-3.0"
|
||||||
|
copyright: "@omsoyk (Discord)"
|
||||||
|
source: "https://github.com/crystallpunk-14/crystall-punk-14"
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
BIN
Resources/Textures/_CP14/Objects/Tools/fishing_rod.rsi/icon.png
Normal file
|
After Width: | Height: | Size: 352 B |
|
After Width: | Height: | Size: 664 B |
|
After Width: | Height: | Size: 676 B |
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"size": {
|
||||||
|
"x": 48,
|
||||||
|
"y": 48
|
||||||
|
},
|
||||||
|
"license": "CLA",
|
||||||
|
"copyright": "Created by omsoyk (Discord) ",
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-left",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-right",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
Resources/Textures/_CP14/Objects/Tools/float.rsi/1.png
Normal file
|
After Width: | Height: | Size: 266 B |
BIN
Resources/Textures/_CP14/Objects/Tools/float.rsi/2.png
Normal file
|
After Width: | Height: | Size: 204 B |
BIN
Resources/Textures/_CP14/Objects/Tools/float.rsi/3.png
Normal file
|
After Width: | Height: | Size: 337 B |
BIN
Resources/Textures/_CP14/Objects/Tools/float.rsi/4.png
Normal file
|
After Width: | Height: | Size: 292 B |