Skip to content

Commit

Permalink
Fract war ebent update v0.7 (#2034)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kirus59 authored Jan 23, 2025
1 parent 1a03260 commit 6946cf2
Show file tree
Hide file tree
Showing 80 changed files with 491,324 additions and 266,012 deletions.
1 change: 1 addition & 0 deletions Content.Client/SS220/AdmemeEvents/EventRoleIcons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ private void OnGetStatusIcons(Entity<EventRoleComponent> entity, ref GetStatusIc
var viewer = _player.LocalSession?.AttachedEntity;

if (viewer != entity &&
!HasComp<ShowEventRoleIconsComponent>(viewer) &&
(!TryComp<EventRoleComponent>(viewer, out var viewerComp) ||
viewerComp.RoleGroupKey != entity.Comp.RoleGroupKey))
return;
Expand Down
112 changes: 112 additions & 0 deletions Content.Client/SS220/PlacerItem/AlignPlacerItemConstruction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt

using Content.Client.Gameplay;
using Content.Shared.Hands.Components;
using Content.Shared.Interaction;
using Content.Shared.RCD.Systems;
using Content.Shared.SS220.PlacerItem.Components;
using Content.Shared.SS220.PlacerItem.Systems;
using Robust.Client.Placement;
using Robust.Client.Player;
using Robust.Client.State;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using System.Numerics;

namespace Content.Client.SS220.PlacerItem;

public sealed class AlignPlacerItemConstruction : PlacementMode
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IStateManager _stateManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;

private readonly RCDSystem _rcdSystem;
private readonly PlacerItemSystem _placerItemSystem;
private readonly SharedTransformSystem _transformSystem;
private readonly SharedMapSystem _mapSystem;

private const float SearchBoxSize = 2f;
private const float PlaceColorBaseAlpha = 0.5f;

private EntityCoordinates _unalignedMouseCoords = default;

public AlignPlacerItemConstruction(PlacementManager pMan) : base(pMan)
{
IoCManager.InjectDependencies(this);
_rcdSystem = _entityManager.System<RCDSystem>();
_placerItemSystem = _entityManager.System<PlacerItemSystem>();
_transformSystem = _entityManager.System<SharedTransformSystem>();
_mapSystem = _entityManager.System<SharedMapSystem>();

ValidPlaceColor = ValidPlaceColor.WithAlpha(PlaceColorBaseAlpha);
}

public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
_unalignedMouseCoords = ScreenToCursorGrid(mouseScreen);
MouseCoords = _unalignedMouseCoords.AlignWithClosestGridTile(SearchBoxSize, _entityManager, _mapManager);

var gridId = _transformSystem.GetGrid(MouseCoords);
if (!_entityManager.TryGetComponent<MapGridComponent>(gridId, out var mapGrid))
return;

CurrentTile = _mapSystem.GetTileRef(gridId.Value, mapGrid, MouseCoords);

float tileSize = mapGrid.TileSize;
GridDistancing = tileSize;

if (pManager.CurrentPermission!.IsTile)
{
MouseCoords = new EntityCoordinates(MouseCoords.EntityId, new Vector2(CurrentTile.X + tileSize / 2,
CurrentTile.Y + tileSize / 2));
}
else
{
MouseCoords = new EntityCoordinates(MouseCoords.EntityId, new Vector2(CurrentTile.X + tileSize / 2 + pManager.PlacementOffset.X,
CurrentTile.Y + tileSize / 2 + pManager.PlacementOffset.Y));
}
}

public override bool IsValidPosition(EntityCoordinates position)
{
var player = _playerManager.LocalSession?.AttachedEntity;

// If the destination is out of interaction range, set the placer alpha to zero
if (!_entityManager.TryGetComponent<TransformComponent>(player, out var xform))
return false;

if (!_transformSystem.InRange(xform.Coordinates, position, SharedInteractionSystem.InteractionRange))
{
InvalidPlaceColor = InvalidPlaceColor.WithAlpha(0);
return false;
}
// Otherwise restore the alpha value
else
{
InvalidPlaceColor = InvalidPlaceColor.WithAlpha(PlaceColorBaseAlpha);
}

if (!_entityManager.TryGetComponent<HandsComponent>(player, out var hands))
return false;

var heldEntity = hands.ActiveHand?.HeldEntity;

if (!_entityManager.TryGetComponent<PlacerItemComponent>(heldEntity, out var placerItemComp))
return false;

if (!_rcdSystem.TryGetMapGridData(position, out var mapGridData))
return false;

// Determine if the user is hovering over a target
var currentState = _stateManager.CurrentState;

if (currentState is not GameplayStateBase screen)
return false;

var target = screen.GetClickedEntity(_transformSystem.ToMapCoordinates(_unalignedMouseCoords));

return _placerItemSystem.IsPlacementOperationStillValid((heldEntity.Value, placerItemComp), mapGridData.Value, target, player.Value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt

using Content.Shared.Hands.Components;
using Content.Shared.Interaction;
using Content.Shared.SS220.PlacerItem;
using Content.Shared.SS220.PlacerItem.Components;
using Robust.Client.Placement;
using Robust.Client.Player;
using Robust.Shared.Enums;

namespace Content.Client.SS220.PlacerItem;

public sealed class PlacerItemConstructionGhostSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IPlacementManager _placementManager = default!;

private string _placementMode = typeof(AlignPlacerItemConstruction).Name;
private Direction _placementDirection = default;

public override void Update(float frameTime)
{
base.Update(frameTime);

var placerEntity = _placementManager.CurrentPermission?.MobUid;
var placerProto = _placementManager.CurrentPermission?.EntityType;
var placerIsPlacerItem = HasComp<PlacerItemComponent>(placerEntity);

if (_placementManager.Eraser ||
(placerEntity != null && !placerIsPlacerItem))
return;

var player = _playerManager.LocalSession?.AttachedEntity;
if (!TryComp<HandsComponent>(player, out var hands))
return;

var heldEntity = hands.ActiveHand?.HeldEntity;
if (!TryComp<PlacerItemComponent>(heldEntity, out var comp) || !comp.Active)
{
if (placerIsPlacerItem)
{
_placementManager.Clear();
_placementDirection = default;
}

return;
}

// Update the direction
if (_placementDirection != _placementManager.Direction)
{
_placementDirection = _placementManager.Direction;
RaiseNetworkEvent(new PlacerItemUpdateDirectionEvent(GetNetEntity(heldEntity.Value), _placementDirection));
}

if (heldEntity == placerEntity && placerProto == comp.SpawnProto.Id)
return;

var newObjInfo = new PlacementInformation
{
MobUid = heldEntity.Value,
EntityType = comp.ConstructionGhostProto ?? comp.SpawnProto,
PlacementOption = _placementMode,
Range = (int)Math.Ceiling(SharedInteractionSystem.InteractionRange),
IsTile = false,
UseEditorContext = false,
};

_placementManager.Clear();
_placementManager.BeginPlacing(newObjInfo);
}
}
2 changes: 1 addition & 1 deletion Content.IntegrationTests/Tests/PostMapInitTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public sealed class PostMapInitTest
// SS220 Event Maps
"Snout",
"VoidZone",
"NTvsSSSP",
"FractWar",
};

/// <summary>
Expand Down
76 changes: 76 additions & 0 deletions Content.Server/SS220/Barricade/BarricadeSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.Projectiles;
using Content.Shared.SS220.Barricade;
using Microsoft.Extensions.DependencyModel;
using Robust.Server.GameObjects;
using Robust.Shared.Random;
using System.Numerics;

namespace Content.Server.SS220.Barricade;

public sealed partial class BarricadeSystem : SharedBarricadeSystem
{
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly IRobustRandom _random = default!;

protected override bool HitscanTryPassBarricade(Entity<BarricadeComponent> entity, EntityUid source, TransformComponent? sourceXform = null)
{
if (!Resolve(source, ref sourceXform))
return false;

var hitChance = CalculateHitChance(entity, sourceXform.GridUid, sourceXform.LocalPosition, _transform.GetWorldPosition(source));
var isHit = _random.Prob(hitChance);

return !isHit;
}

protected override bool ProjectileTryPassBarricade(Entity<BarricadeComponent> entity, Entity<ProjectileComponent> projEnt)
{
var (uid, comp) = entity;
var (projUid, projComp) = projEnt;

var passBarricade = EnsureComp<PassBarricadeComponent>(projUid);
if (passBarricade.CollideBarricades.TryGetValue(uid, out var isPass))
return isPass;

var hitChance = CalculateHitChance(entity, projComp.ShootGridUid, projComp.ShootGridPos, projComp.ShootWorldPos);
var isHit = _random.Prob(hitChance);

passBarricade.CollideBarricades.Add(uid, !isHit);
Dirty(projUid, passBarricade);

return !isHit;
}

private float CalculateHitChance(Entity<BarricadeComponent> entity, EntityUid? gridUid = null, Vector2? gridPos = null, Vector2? worldPos = null)
{
var (uid, comp) = entity;
var xform = Transform(entity);

float distance;
if (gridUid != null && gridPos != null && xform.ParentUid == gridUid)
{
var posDiff = xform.LocalPosition - gridPos;
distance = posDiff.Value.Length();
}
else if (worldPos != null)
{
var posDiff = _transform.GetWorldPosition(uid) - worldPos;
distance = posDiff.Value.Length();
}
else
{
distance = comp.MaxDistance;
}

var distanceDiff = comp.MaxDistance - comp.MinDistance;
var chanceDiff = comp.MaxHitChance - comp.MinHitChance;

/// How much the <see cref="BarricadeComponent.MinHitChances"/> will increase.
var increaseChance = Math.Clamp(distance - comp.MinDistance, 0, distanceDiff) / distanceDiff * chanceDiff;

var hitChance = Math.Clamp(comp.MinHitChance + increaseChance, comp.MinHitChance, comp.MaxHitChance);

return hitChance;
}
}
68 changes: 68 additions & 0 deletions Content.Server/SS220/EventCapturePoint/EventCapturePointSystem.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using System.Numerics;
using Content.Server.SS220.FractWar;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Shared.Item;
Expand All @@ -11,6 +12,7 @@
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Random;
using Robust.Shared.Timing;

namespace Content.Server.SS220.EventCapturePoint;

Expand All @@ -22,6 +24,12 @@ public sealed class EventCapturePointSystem : EntitySystem
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly AppearanceSystem _appearance = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly FractWarRuleSystem _fractWarRule = default!;

private const float RefreshWinPointsRate = 60f;

private TimeSpan _nextRefreshWinPoints = TimeSpan.Zero;

public override void Initialize()
{
Expand All @@ -36,6 +44,33 @@ public override void Initialize()
SubscribeLocalEvent<EventCapturePointComponent, FlagRemovalFinshedEvent>(OnFlagRemoved);
}

public override void Update(float frameTime)
{
base.Update(frameTime);

var gameRule = _fractWarRule.GetActiveGameRule();
if (gameRule is null)
return;

var query = EntityQueryEnumerator<EventCapturePointComponent>();
while (query.MoveNext(out _, out var component))
{
if (component.FlagEntity is not { } flagUid ||
!TryComp<EventCapturePointFlagComponent>(flagUid, out var flagComp) ||
flagComp.Fraction is not { } flagFraction)
continue;

if (!component.PointRetentionTime.TryAdd(flagFraction, TimeSpan.Zero))
component.PointRetentionTime[flagFraction] += TimeSpan.FromSeconds(frameTime);
}

if (_timing.CurTime >= _nextRefreshWinPoints)
{
RefreshWinPoints(gameRule);
_nextRefreshWinPoints = _timing.CurTime + TimeSpan.FromSeconds(RefreshWinPointsRate);
}
}

#region Listeners
private void OnActivated(Entity<EventCapturePointComponent> entity, ref ActivateInWorldEvent args)
{
Expand Down Expand Up @@ -72,6 +107,8 @@ private void OnFlagRemoved(Entity<EventCapturePointComponent> entity, ref FlagRe

private void OnPointShutdown(Entity<EventCapturePointComponent> entity, ref ComponentShutdown args)
{
RefreshWinPointsFromCapturePoint(entity.Comp);

if (entity.Comp.FlagEntity.HasValue &&
entity.Comp.FlagEntity.Value.Valid &&
EntityManager.EntityExists(entity.Comp.FlagEntity.Value))
Expand Down Expand Up @@ -178,4 +215,35 @@ public void AddOrRemoveFlag(Entity<EventCapturePointComponent> entity, EntityUid
else
AddFlag(entity, user, newFlag);
}

public void RefreshWinPoints(FractWarRuleComponent? gameRule = null)
{
gameRule ??= _fractWarRule.GetActiveGameRule();
if (gameRule is null)
return;

var query = EntityQueryEnumerator<EventCapturePointComponent>();
while (query.MoveNext(out _, out var comp))
{
RefreshWinPointsFromCapturePoint(comp, gameRule);
}
}

public void RefreshWinPointsFromCapturePoint(EventCapturePointComponent comp, FractWarRuleComponent? gameRule = null)
{
gameRule ??= _fractWarRule.GetActiveGameRule();

if (gameRule is null)
return;

foreach (var (fraction, retTime) in comp.PointRetentionTime)
{
var wp = comp.WinPointsCoefficient * (float)(retTime.TotalSeconds / comp.RetentionTimeForWinPoint.TotalSeconds);

if (!gameRule.FractionsWinPoints.TryAdd(fraction, wp))
gameRule.FractionsWinPoints[fraction] += wp;

comp.PointRetentionTime[fraction] = TimeSpan.Zero;
}
}
}
9 changes: 9 additions & 0 deletions Content.Server/SS220/FractWar/FractWarRuleComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
namespace Content.Server.SS220.FractWar;

[RegisterComponent]
public sealed partial class FractWarRuleComponent : Component
{
[ViewVariables]
public Dictionary<string, float> FractionsWinPoints = [];
}
Loading

0 comments on commit 6946cf2

Please sign in to comment.