Skip to content

Commit

Permalink
Merge branch 'spray-paint' of https://github.com/DEATHB4DEFEAT/Einste…
Browse files Browse the repository at this point in the history
…in-Engines into loadouts-v4
  • Loading branch information
DEATHB4DEFEAT committed Nov 15, 2024
2 parents 61125b0 + b5fda12 commit 9659956
Show file tree
Hide file tree
Showing 24 changed files with 294 additions and 264 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ csharp_style_expression_bodied_constructors = false:suggestion
#csharp_style_expression_bodied_indexers = true:silent
#csharp_style_expression_bodied_lambdas = true:silent
#csharp_style_expression_bodied_local_functions = false:silent
csharp_style_expression_bodied_methods = false:suggestion
csharp_style_expression_bodied_methods = true:suggestion
#csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:suggestion

Expand Down
91 changes: 38 additions & 53 deletions Content.Client/Paint/PaintVisualizerSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Linq;
using Robust.Client.GameObjects;
using static Robust.Client.GameObjects.SpriteComponent;
using Content.Shared.Clothing;
Expand All @@ -11,13 +10,10 @@ namespace Content.Client.Paint;

public sealed class PaintedVisualizerSystem : VisualizerSystem<PaintedComponent>
{
/// <summary>
/// Visualizer for Paint which applies a shader and colors the entity.
/// </summary>

[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly IPrototypeManager _protoMan = default!;


public override void Initialize()
{
base.Initialize();
Expand All @@ -27,59 +23,73 @@ public override void Initialize()
SubscribeLocalEvent<PaintedComponent, EquipmentVisualsUpdatedEvent>(OnEquipmentVisualsUpdated);
}


protected override void OnAppearanceChange(EntityUid uid, PaintedComponent component, ref AppearanceChangeEvent args)
{
var shader = _protoMan.Index<ShaderPrototype>(component.ShaderName).Instance();

if (args.Sprite == null)
if (args.Sprite == null
|| !_appearance.TryGetData(uid, PaintVisuals.Painted, out bool isPainted))
return;

// What is this even doing? It's not even checking what the value is.
if (!_appearance.TryGetData(uid, PaintVisuals.Painted, out bool isPainted))
return;

var sprite = args.Sprite;

foreach (var spriteLayer in sprite.AllLayers)
var shader = _protoMan.Index<ShaderPrototype>(component.ShaderName).Instance();
foreach (var spriteLayer in args.Sprite.AllLayers)
{
if (spriteLayer is not Layer layer)
continue;

if (layer.Shader == null || layer.Shader == shader) // If shader isn't null we dont want to replace the original shader.
if (layer.Shader == null || layer.Shader == shader)
{
layer.Shader = shader;
layer.Color = component.Color;
}
}
}

private void OnHeldVisualsUpdated(EntityUid uid, PaintedComponent component, HeldVisualsUpdatedEvent args)
private void OnShutdown(EntityUid uid, PaintedComponent component, ref ComponentShutdown args)
{
if (args.RevealedLayers.Count == 0)
if (!TryComp(uid, out SpriteComponent? sprite))
return;
component.BeforeColor = sprite.Color;

if (!TryComp(args.User, out SpriteComponent? sprite))
if (Terminating(uid))
return;

foreach (var revealed in args.RevealedLayers)
foreach (var spriteLayer in sprite.AllLayers)
{
if (!sprite.LayerMapTryGet(revealed, out var layer))
if (spriteLayer is not Layer layer
|| layer.Shader != _protoMan.Index<ShaderPrototype>(component.ShaderName).Instance())
continue;

sprite.LayerSetShader(layer, component.ShaderName);
sprite.LayerSetColor(layer, component.Color);
layer.Shader = null;
if (layer.Color == component.Color)
layer.Color = component.BeforeColor;
}
}

private void OnEquipmentVisualsUpdated(EntityUid uid, PaintedComponent component, EquipmentVisualsUpdatedEvent args)
private void OnHeldVisualsUpdated(EntityUid uid, PaintedComponent component, HeldVisualsUpdatedEvent args) =>
UpdateVisuals(component, args);
private void OnEquipmentVisualsUpdated(EntityUid uid, PaintedComponent component, EquipmentVisualsUpdatedEvent args) =>
UpdateVisuals(component, args);
private void UpdateVisuals(PaintedComponent component, EntityEventArgs args)
{
if (args.RevealedLayers.Count == 0)
return;
var layers = new HashSet<string>();
var entity = EntityUid.Invalid;

if (!TryComp(args.Equipee, out SpriteComponent? sprite))
switch (args)
{
case HeldVisualsUpdatedEvent hgs:
layers = hgs.RevealedLayers;
entity = hgs.User;
break;
case EquipmentVisualsUpdatedEvent eqs:
layers = eqs.RevealedLayers;
entity = eqs.Equipee;
break;
}

if (layers.Count == 0 || !TryComp(entity, out SpriteComponent? sprite))
return;

foreach (var revealed in args.RevealedLayers)
foreach (var revealed in layers)
{
if (!sprite.LayerMapTryGet(revealed, out var layer))
continue;
Expand All @@ -88,29 +98,4 @@ private void OnEquipmentVisualsUpdated(EntityUid uid, PaintedComponent component
sprite.LayerSetColor(layer, component.Color);
}
}

private void OnShutdown(EntityUid uid, PaintedComponent component, ref ComponentShutdown args)
{
if (!TryComp(uid, out SpriteComponent? sprite))
return;

component.BeforeColor = sprite.Color;
var shader = _protoMan.Index<ShaderPrototype>(component.ShaderName).Instance();

if (!Terminating(uid))
{
foreach (var spriteLayer in sprite.AllLayers)
{
if (spriteLayer is not Layer layer)
continue;

if (layer.Shader == shader) // If shader isn't same as one in component we need to ignore it.
{
layer.Shader = null;
if (layer.Color == component.Color) // If color isn't the same as one in component we don't want to change it.
layer.Color = component.BeforeColor;
}
}
}
}
}
2 changes: 1 addition & 1 deletion Content.Server/Chat/Systems/ChatSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace Content.Server.Chat.Systems;

// Dear contributor. When I was introducing changes to this system only god and I knew what I was doing.
// Now only god knows. Please don't touch this code ever again. If you do have to, increment this counter as a warning for others:
// TOTAL_HOURS_WASTED_HERE_EE = 17
// TOTAL_HOURS_WASTED_HERE_EE = 18

// TODO refactor whatever active warzone this class and chatmanager have become
/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Clothing/Systems/LoadoutSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public void ApplyCharacterLoadout(
if (loadoutProto.CustomDescription && loadout.Item2.CustomDescription != null)
_meta.SetEntityDescription(loadout.Item1, loadout.Item2.CustomDescription);
if (loadoutProto.CustomColorTint && !string.IsNullOrEmpty(loadout.Item2.CustomColorTint))
_paint.Paint(new EntityWhitelist(), loadout.Item1, Color.FromHex(loadout.Item2.CustomColorTint));
_paint.Paint(null, null, loadout.Item1, Color.FromHex(loadout.Item2.CustomColorTint));

foreach (var component in loadoutProto.Components.Values)
{
Expand Down
130 changes: 60 additions & 70 deletions Content.Server/Paint/PaintSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,8 @@ public override void Initialize()

private void OnInteract(EntityUid uid, PaintComponent component, AfterInteractEvent args)
{
if (!args.CanReach)
return;

if (args.Target is not { Valid: true } target)
if (!args.CanReach
|| args.Target is not { Valid: true } target)
return;

PrepPaint(uid, component, target, args.User);
Expand All @@ -73,19 +71,22 @@ private void OnPaintVerb(EntityUid uid, PaintComponent component, GetVerbsEvent<
args.Verbs.Add(verb);
}

private void PrepPaint(EntityUid uid, PaintComponent component, EntityUid target, EntityUid user)
{

var doAfterEventArgs = new DoAfterArgs(EntityManager, user, component.Delay, new PaintDoAfterEvent(), uid, target: target, used: uid)
{
BreakOnUserMove = true,
BreakOnTargetMove = true,
NeedHand = true,
BreakOnHandChange = true,
};

_doAfterSystem.TryStartDoAfter(doAfterEventArgs);
}
private void PrepPaint(EntityUid uid, PaintComponent component, EntityUid target, EntityUid user) =>
_doAfterSystem.TryStartDoAfter(
new DoAfterArgs(
EntityManager,
user,
component.Delay,
new PaintDoAfterEvent(),
uid,
target: target,
used: uid)
{
BreakOnUserMove = true,
BreakOnTargetMove = true,
NeedHand = true,
BreakOnHandChange = true,
});

private void OnPaint(Entity<PaintComponent> entity, ref PaintDoAfterEvent args)
{
Expand All @@ -110,7 +111,9 @@ public void Paint(Entity<PaintComponent> entity, EntityUid target, EntityUid use
return;
}

if (!entity.Comp.Blacklist?.IsValid(target, EntityManager) != true || HasComp<HumanoidAppearanceComponent>(target) || HasComp<SubFloorHideComponent>(target))
if (!entity.Comp.Whitelist?.IsValid(target, EntityManager) == true
|| !entity.Comp.Blacklist?.IsValid(target, EntityManager) == false
|| HasComp<HumanoidAppearanceComponent>(target) || HasComp<SubFloorHideComponent>(target))
{
_popup.PopupEntity(Loc.GetString("paint-failure", ("target", target)), user, user, PopupType.Medium);
return;
Expand All @@ -121,33 +124,29 @@ public void Paint(Entity<PaintComponent> entity, EntityUid target, EntityUid use
EnsureComp<PaintedComponent>(target, out var paint);
EnsureComp<AppearanceComponent>(target);

paint.Color = entity.Comp.Color; // Set the target color to the color specified in the spray paint yml
paint.Color = entity.Comp.Color;
_audio.PlayPvs(entity.Comp.Spray, entity);
paint.Enabled = true;

if (HasComp<InventoryComponent>(target)) // Paint any clothing the target is wearing.
{
if (_inventory.TryGetSlots(target, out var slotDefinitions))
// Paint any clothing the target is wearing
if (HasComp<InventoryComponent>(target)
&& _inventory.TryGetSlots(target, out var slotDefinitions))
foreach (var slot in slotDefinitions)
{
foreach (var slot in slotDefinitions)
{
if (!_inventory.TryGetSlotEntity(target, slot.Name, out var slotEnt))
continue;

if (HasComp<PaintedComponent>(slotEnt.Value)
|| !entity.Comp.Blacklist?.IsValid(slotEnt.Value, EntityManager) != true
|| HasComp<RandomSpriteComponent>(slotEnt.Value)
|| HasComp<HumanoidAppearanceComponent>(slotEnt.Value))
continue;

EnsureComp<PaintedComponent>(slotEnt.Value, out var slotToPaint);
EnsureComp<AppearanceComponent>(slotEnt.Value);
slotToPaint.Color = entity.Comp.Color;
_appearanceSystem.SetData(slotEnt.Value, PaintVisuals.Painted, true);
Dirty(slotEnt.Value, slotToPaint);
}
if (!_inventory.TryGetSlotEntity(target, slot.Name, out var slotEnt)
|| HasComp<PaintedComponent>(slotEnt.Value)
|| !entity.Comp.Whitelist?.IsValid(slotEnt.Value, EntityManager) != true
|| !entity.Comp.Blacklist?.IsValid(slotEnt.Value, EntityManager) != false
|| HasComp<RandomSpriteComponent>(slotEnt.Value)
|| HasComp<HumanoidAppearanceComponent>(slotEnt.Value))
continue;

EnsureComp<PaintedComponent>(slotEnt.Value, out var slotToPaint);
EnsureComp<AppearanceComponent>(slotEnt.Value);
slotToPaint.Color = entity.Comp.Color;
_appearanceSystem.SetData(slotEnt.Value, PaintVisuals.Painted, true);
Dirty(slotEnt.Value, slotToPaint);
}
}

_popup.PopupEntity(Loc.GetString("paint-success", ("target", target)), user, user, PopupType.Medium);
_appearanceSystem.SetData(target, PaintVisuals.Painted, true);
Expand All @@ -159,9 +158,10 @@ public void Paint(Entity<PaintComponent> entity, EntityUid target, EntityUid use
_popup.PopupEntity(Loc.GetString("paint-empty", ("used", entity)), user, user, PopupType.Medium);
}

public void Paint(EntityWhitelist blacklist, EntityUid target, Color color)
public void Paint(EntityWhitelist? whitelist, EntityWhitelist? blacklist, EntityUid target, Color color)
{
if (blacklist.IsValid(target, EntityManager))
if (!whitelist?.IsValid(target, EntityManager) != true
|| !blacklist?.IsValid(target, EntityManager) != false)
return;

EnsureComp<PaintedComponent>(target, out var paint);
Expand All @@ -170,43 +170,33 @@ public void Paint(EntityWhitelist blacklist, EntityUid target, Color color)
paint.Color = color;
paint.Enabled = true;

if (HasComp<InventoryComponent>(target))
{
if (_inventory.TryGetSlots(target, out var slotDefinitions))
if (HasComp<InventoryComponent>(target)
&& _inventory.TryGetSlots(target, out var slotDefinitions))
foreach (var slot in slotDefinitions)
{
foreach (var slot in slotDefinitions)
{
if (!_inventory.TryGetSlotEntity(target, slot.Name, out var slotEnt)
|| blacklist.IsValid(slotEnt.Value, EntityManager))
continue;

EnsureComp<PaintedComponent>(slotEnt.Value, out var slotToPaint);
EnsureComp<AppearanceComponent>(slotEnt.Value);
slotToPaint.Color = color;
_appearanceSystem.SetData(slotEnt.Value, PaintVisuals.Painted, true);
Dirty(slotEnt.Value, slotToPaint);
}
if (!_inventory.TryGetSlotEntity(target, slot.Name, out var slotEnt)
|| !whitelist?.IsValid(slotEnt.Value, EntityManager) != true
|| !blacklist?.IsValid(slotEnt.Value, EntityManager) != false)
continue;

EnsureComp<PaintedComponent>(slotEnt.Value, out var slotToPaint);
EnsureComp<AppearanceComponent>(slotEnt.Value);
slotToPaint.Color = color;
_appearanceSystem.SetData(slotEnt.Value, PaintVisuals.Painted, true);
Dirty(slotEnt.Value, slotToPaint);
}
}

_appearanceSystem.SetData(target, PaintVisuals.Painted, true);
Dirty(target, paint);
}

private bool CanPaint(Entity<PaintComponent> reagent, EntityUid target)
{
if (HasComp<HumanoidAppearanceComponent>(target) || HasComp<SubFloorHideComponent>(target))
if (HasComp<HumanoidAppearanceComponent>(target)
|| HasComp<SubFloorHideComponent>(target)
|| !_solutionContainer.TryGetSolution(reagent.Owner, reagent.Comp.Solution, out _, out var solution))
return false;

if (_solutionContainer.TryGetSolution(reagent.Owner, reagent.Comp.Solution, out _, out var solution))
{
var quantity = solution.RemoveReagent(reagent.Comp.Reagent, reagent.Comp.ConsumptionUnit);
if (quantity > 0)// checks quantity of solution is more than 0.
return true;

if (quantity < 1)
return false;
}
return false;
var quantity = solution.RemoveReagent(reagent.Comp.Reagent, reagent.Comp.ConsumptionUnit);
return (quantity > 0);
}
}
15 changes: 15 additions & 0 deletions Content.Server/Polymorph/Systems/PolymorphSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Robust.Server.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

Expand All @@ -31,6 +32,7 @@ public sealed partial class PolymorphSystem : EntitySystem
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly ISerializationManager _serialization = default!;
[Dependency] private readonly ActionsSystem _actions = default!;
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly SharedBuckleSystem _buckle = default!;
Expand Down Expand Up @@ -201,6 +203,19 @@ private void OnDestruction(Entity<PolymorphedEntityComponent> ent, ref Destructi

var child = Spawn(configuration.Entity, _transform.GetMapCoordinates(uid, targetTransformComp), rotation: _transform.GetWorldRotation(uid));

// Copy specified components over
foreach (var compName in configuration.CopiedComponents)
{
if (!_compFact.TryGetRegistration(compName, out var reg)
|| !EntityManager.TryGetComponent(uid, reg.Idx, out var comp))
continue;

var copy = _serialization.CreateCopy(comp, notNullableOverride: true);
copy.Owner = child;
AddComp(child, copy, true);
}

// Ensure the resulting entity is sentient (why? this sucks)
MakeSentientCommand.MakeSentient(child, EntityManager);

var polymorphedComp = _compFact.GetComponent<PolymorphedEntityComponent>();
Expand Down
Loading

0 comments on commit 9659956

Please sign in to comment.