Files
OldThink/Content.Server/Construction/ConstructionSystem.cs

567 lines
20 KiB
C#
Raw Normal View History

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
2021-06-09 22:19:39 +02:00
using Content.Server.Construction.Components;
using Content.Server.DoAfter;
using Content.Server.Hands.Components;
using Content.Server.Inventory.Components;
using Content.Server.Items;
using Content.Server.Stack;
using Content.Server.Storage.Components;
using Content.Shared.ActionBlocker;
using Content.Shared.Construction;
2021-06-09 22:19:39 +02:00
using Content.Shared.Construction.Prototypes;
using Content.Shared.Construction.Steps;
using Content.Shared.Coordinates;
using Content.Shared.Examine;
2021-06-09 22:19:39 +02:00
using Content.Shared.Interaction.Helpers;
2021-09-26 15:18:45 +02:00
using Content.Shared.Popups;
ECS verbs and update context menu (#4594) * Functioning ECS verbs Currently only ID card console works. * Changed verb types and allow ID card insertions * Verb GUI sorting and verb networking * More networking, and shared components * Clientside verbs work now. * Verb enums changed to bitmask flags * Verb Categories redo * Fix range check * GasTank Verb * Remove unnecessary bodypart verb * Buckle Verb * buckle & unbuckle verbs * Updated range checks * Item cabinet verbs * Add range user override * construction verb * Chemistry machine verbs * Climb Verb * Generalise pulled entity verbs * ViewVariables Verb * rejuvenate, delete, sentient, control verbs * Outfit verb * inrangeunoccluded and tubedirection verbs * attach-to verbs * remove unused verbs and move VV * Rename DebugVerbSystem * Ghost role and pointing verbs * Remove global verbs * Allow verbs to raise events * Changing categories and simplifying debug verbs * Add rotate and flip verbs * fix rejuvenate test * redo context menu * new Add Gas debug verb * Add Set Temperature debug verb * Uncuff verb * Disposal unit verbs * Add pickup verb * lock/unlock verb * Remove verb type, add specific verb events * rename verb messages -> events * Context menu displays verbs by interaction type * Updated context menu HandleMove previously, checked if entities moved 1 tile from click location. Now checks if entities moved out of view. Now you can actually right-click interact with yourself while walking! * Misc Verb menu GUI changes * Fix non-human/ghost verbs * Update types and categories * Allow non-ghost/human to open context menu * configuration verb * tagger verb * Morgue Verbs * Medical Scanner Verbs * Fix solution refactor merge issues * Fix context menu in-view check * Remove prepare GUI * Redo verb restrictions * Fix context menu UI * Disposal Verbs * Spill verb * Light verb * Hand Held light verb * power cell verbs * storage verbs and adding names to insert/eject * Pulling verb * Close context menu on verb execution * Strip verb * AmmoBox verb * fix pull verb * gun barrel verbs revolver verb energy weapon verbs Bolt action verb * Magazine gun barrel verbs * Add charger verbs * PDA verbs * Transfer amount verb * Add reagent verb * make alt-click use ECS verbs * Delete old verb files * Magboot verb * finalising tweaks * context menu visibility changes * code cleanup * Update AdminAddReagentUI.cs * Remove HasFlag * Consistent verb keys * Remove Linq, add comment * Fix in-inventory check * Update GUI text alignment and padding * Added close-menu option * Changed some "interaction" verbs to "activation" * Remove verb keys, use sorted sets * fix master merge * update some verb text * Undo Changes Remove some new verbs that can be added later undid some .ftl bugfixes, can and should be done separately * fix merge * Undo file rename * fix merge * Misc Cleanup * remove contraction * Fix keybinding issue * fix comment * merge fix * fix merge * fix merge * fix merge * fix merge * fix open-close verbs * adjust uncuff verb * fix merge and undo the renaming of SharedPullableComponent to PullableComponent. I'm tired of all of those merge conflicts
2021-10-05 14:29:03 +11:00
using Content.Shared.Verbs;
using JetBrains.Annotations;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
2021-06-09 22:19:39 +02:00
namespace Content.Server.Construction
{
/// <summary>
/// The server-side implementation of the construction system, which is used for constructing entities in game.
/// </summary>
[UsedImplicitly]
internal class ConstructionSystem : SharedConstructionSystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IRobustRandom _robustRandom = default!;
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly StackSystem _stackSystem = default!;
private readonly Dictionary<ICommonSession, HashSet<int>> _beingBuilt = new();
Add the trash man (#1367) * Add disposal.rsi * Rename disposal resource to disposal.rsi and create basic components * Add disposal nets * Add pushing entities along the disposal network * Add disposal unit * Unregister disposable component * Add flush and selfinsert verbs to disposal unit * Add gradual disposals movement * Fix being able to walk through space for a while after exiting disposals * Multiply disposals speed by 10 And fix early returns when moving an entity * Rename Disposable component to InDisposals * Remove DisposalNet and add on anchor events * Remove anchored events, moved to interfaces * Code cleanup * Fix adjacent tubes' connections when a tube connects * Fix jittery movement in disposals * Remove Logger.Debug call * Move disposals updates to InDisposalsComponent * Fix adjacent connection valid directions check * Disposal tubes now throw you out where they are facing * Add disposal unit exit cooldown * Set different disposal pipe sprite state depending on anchored value * Add recycler * Add recycler animation * Add bloody texture to the recycler when grinding a living being * Add PowerDevice component to the disposal unit * Made the Recycler center on the grid * Add disposal junction * Add picking a random direction if junction is entered from the output side * Add disposal flush and clang sounds Taken from VGStation * Move disposal flush and clang sound file names to exposedata * Add disposalsmap.yml to test with * Add summaries to DisposalUnit fields * Add sideDegrees yaml property to disposal junctions * Fix outdated usings * Add conveyor resources * Update RobustToolbox * More merge fixes Add conveyor collision masks * Add ConveyorComponent * Fix crash when reentering a body * Merge branch 'master' into disposals-1147 * Reduce recycler bounds, set hard to false, add summary and expose "safe" to yaml * Move IAnchored and IUnAnchored to AnchorableComponent * Update power components and remove old disposals map * Remove redundant sprite layers * Add tile pry command * Fix tilepry command * Fix DisposalJunctionComponent missing a component reference * Add anchor by radius command * Add Y-Junctions * Add disposal bend * Add unanchor command * Change DisposalJunction prototypes to specify their angles * Fix disposal units being hidden below the floor * Removed IAnhored and IUnAnchored interfaces * Replace CanBeNull annotation with nullable reference types * Update showwires command * Add recycler recycling items * Added angle and speed properties to ConveyorComponent * Fix conveyort textures * Add animation to the disposal unit * Fix anchor and unanchor commands sometimes not finding any entities * Fix not reading flush_time from disposal unit prototype * Fix merge conflict wrong using * Fix disposal, recycling and conveyor texture paths Delete diverters * Update visualizer names * Add DisposableComponent, change drag and drop to work with multiple components Ignoreinsideblocker client side for drag and drops, like on the server Add more comments * Add conveyor belts properly moving entities on top * Anchorr wires * Change conveyor bounds to 0.49 * Anchor catwalks, airlocks, gravity generators, low walls, wires and windows * Add starting/stopping conveyors * Add reversed conveyors * Add conveyor switches * Move InDisposalsComponent code to DisposableComponent * Add ExitVector method to tubes * Fix not updating tube references when disconnecting one * Replace IoCManager call with dependency * Add tubes disconnecting if they move too far apart from one another * Move disposals action blocking to shared * Add rotating and flipping pipes * Make conveyor intersection calculations approximate * Fix 1% chance of the server crashing when initializing the map Happens when emergency lockers remove themselves * Add disposal unit interface * Make disposal units refuse items if not powered * Make disposal tubes hide only when anchored * Make disposal junction arrows visible to mere mortals * Add disposal tubes breaking * Add tubeconnections command * Add missing verb attribute * Add flipped disposal junction * Add ids and linking to conveyors and switches * Add conveyor switch prying and placing * Add anchoring conveyor switches and refactor placing them * Add missing serializable attributes from DisposableComponentState * Make conveyor speed VV ReadWrite * Change drawdepth of conveyors to FloorObjects * Make conveyor anchored check consistent * Remove anchoring interaction from switches * Add conveyor switch id syncing and move switches slightly when pried * Make entities in containers not able to be moved by conveyors * Add conveyor and switches loose textures * Merge conflict fixes * Add disposal unit test * Add flushing test to disposal unit test * Add disposal unit flush fail test * Add disposals to the saltern map * Fix saltern disposal junctions * Add power checks to the recycler * Fix disposal unit placement in maintenance closet * Remove disposal junctions from saltern * Readd junctions to saltern * Add the chemmaster to saltern at the request of Ike * Move the chemistry disposal unit * Fix casing of disposal flush sound * More merge conflict fixes * Fix a compiler warning. * Remove popup invocation from buckle * Remove showPopup parameter from InteractionChecks * Remove unnecessary physics components Fixes the physics system dying * Replace PhysicsComponent usages with CollidableComponent * Update existing code for the new controller system * Change conveyors to use a VirtualController instead of teleporting the entity * Remove visualizer 2d suffix and update physics code * Transition code to new controller system * Fix shuttles not moving * Fix throwing * Fix guns * Change hands to use physics.Stop() and remove item fumble method * Add syncing conveyor switches states * Fix the recycler wanting to be a conveyor too hard * Fix showwires > showsubfloor rename in mapping command * Fix wifi air conveyors * Fix test error * Add showsubfloorforever command Changes drawdepth of the relevant entities * Disable opening the disposal unit interface while inside * Add closing the disposal unit interface when getting inside * Add closing the interface when the disposal unit component is removed * Add removing entities on disposal unit component removal * Delay disposal unit flush and fix serialization * Implement pressure in disposal units * Fix chain engaging a disposal unit * Implement states to the disposal unit * Fix missing imports from merge conflict * Update Content.Server/GameObjects/Components/Conveyor/ConveyorComponent.cs Co-authored-by: Pieter-Jan Briers <pieterjan.briers@gmail.com> * Address some reviews * Fix za buildo * Use container helper to detach disposables * Make conveyors use the construction system * Make conveyor groups and syncing sane * Make flip flip brave * Add activate interface to conveyor switches * Fix not removing the switch from its group when it's deleted * Fix not registering conveyors and switches on initialize * Stop using 0 as null * Disconnect conveyors and switches when disposing of a group * Make disposal units not able to be exited when flushing * Make disposal units flush after a configurable 30 seconds * Add handle and light layers to the disposal unit * Merge engaging and flushing * Update saltern.yml * I love using 0 as null * Make disposal unit visual layers make sense * Remove duplicate remove method in disposal units and update light * Replace DisposableComponent with disposal holders * Fix disposal holders deleting their contents on deletion * Account for disposal unit pressure in tests and make a failed flush autoengage * Rename disposable to holder * Fix junction connections * Disable self insert and flush verbs when inside a disposal unit * Fix spamming the engage button making the animation reset * Make the recycler take materials into account properly Fix cablestack1 not existing * Merge conflict fixes * Fix pipes not being saved anchored * Change conveyors and groups to not use an id Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com> Co-authored-by: Pieter-Jan Briers <pieterjan.briers@gmail.com>
2020-07-30 23:45:28 +02:00
public override void Initialize()
{
base.Initialize();
2020-04-20 10:36:02 +01:00
SubscribeNetworkEvent<TryStartStructureConstructionMessage>(HandleStartStructureConstruction);
SubscribeNetworkEvent<TryStartItemConstructionMessage>(HandleStartItemConstruction);
ECS verbs and update context menu (#4594) * Functioning ECS verbs Currently only ID card console works. * Changed verb types and allow ID card insertions * Verb GUI sorting and verb networking * More networking, and shared components * Clientside verbs work now. * Verb enums changed to bitmask flags * Verb Categories redo * Fix range check * GasTank Verb * Remove unnecessary bodypart verb * Buckle Verb * buckle & unbuckle verbs * Updated range checks * Item cabinet verbs * Add range user override * construction verb * Chemistry machine verbs * Climb Verb * Generalise pulled entity verbs * ViewVariables Verb * rejuvenate, delete, sentient, control verbs * Outfit verb * inrangeunoccluded and tubedirection verbs * attach-to verbs * remove unused verbs and move VV * Rename DebugVerbSystem * Ghost role and pointing verbs * Remove global verbs * Allow verbs to raise events * Changing categories and simplifying debug verbs * Add rotate and flip verbs * fix rejuvenate test * redo context menu * new Add Gas debug verb * Add Set Temperature debug verb * Uncuff verb * Disposal unit verbs * Add pickup verb * lock/unlock verb * Remove verb type, add specific verb events * rename verb messages -> events * Context menu displays verbs by interaction type * Updated context menu HandleMove previously, checked if entities moved 1 tile from click location. Now checks if entities moved out of view. Now you can actually right-click interact with yourself while walking! * Misc Verb menu GUI changes * Fix non-human/ghost verbs * Update types and categories * Allow non-ghost/human to open context menu * configuration verb * tagger verb * Morgue Verbs * Medical Scanner Verbs * Fix solution refactor merge issues * Fix context menu in-view check * Remove prepare GUI * Redo verb restrictions * Fix context menu UI * Disposal Verbs * Spill verb * Light verb * Hand Held light verb * power cell verbs * storage verbs and adding names to insert/eject * Pulling verb * Close context menu on verb execution * Strip verb * AmmoBox verb * fix pull verb * gun barrel verbs revolver verb energy weapon verbs Bolt action verb * Magazine gun barrel verbs * Add charger verbs * PDA verbs * Transfer amount verb * Add reagent verb * make alt-click use ECS verbs * Delete old verb files * Magboot verb * finalising tweaks * context menu visibility changes * code cleanup * Update AdminAddReagentUI.cs * Remove HasFlag * Consistent verb keys * Remove Linq, add comment * Fix in-inventory check * Update GUI text alignment and padding * Added close-menu option * Changed some "interaction" verbs to "activation" * Remove verb keys, use sorted sets * fix master merge * update some verb text * Undo Changes Remove some new verbs that can be added later undid some .ftl bugfixes, can and should be done separately * fix merge * Undo file rename * fix merge * Misc Cleanup * remove contraction * Fix keybinding issue * fix comment * merge fix * fix merge * fix merge * fix merge * fix merge * fix open-close verbs * adjust uncuff verb * fix merge and undo the renaming of SharedPullableComponent to PullableComponent. I'm tired of all of those merge conflicts
2021-10-05 14:29:03 +11:00
SubscribeLocalEvent<ConstructionComponent, GetOtherVerbsEvent>(AddDeconstructVerb);
SubscribeLocalEvent<ConstructionComponent, ExaminedEvent>(HandleConstructionExamined);
}
ECS verbs and update context menu (#4594) * Functioning ECS verbs Currently only ID card console works. * Changed verb types and allow ID card insertions * Verb GUI sorting and verb networking * More networking, and shared components * Clientside verbs work now. * Verb enums changed to bitmask flags * Verb Categories redo * Fix range check * GasTank Verb * Remove unnecessary bodypart verb * Buckle Verb * buckle & unbuckle verbs * Updated range checks * Item cabinet verbs * Add range user override * construction verb * Chemistry machine verbs * Climb Verb * Generalise pulled entity verbs * ViewVariables Verb * rejuvenate, delete, sentient, control verbs * Outfit verb * inrangeunoccluded and tubedirection verbs * attach-to verbs * remove unused verbs and move VV * Rename DebugVerbSystem * Ghost role and pointing verbs * Remove global verbs * Allow verbs to raise events * Changing categories and simplifying debug verbs * Add rotate and flip verbs * fix rejuvenate test * redo context menu * new Add Gas debug verb * Add Set Temperature debug verb * Uncuff verb * Disposal unit verbs * Add pickup verb * lock/unlock verb * Remove verb type, add specific verb events * rename verb messages -> events * Context menu displays verbs by interaction type * Updated context menu HandleMove previously, checked if entities moved 1 tile from click location. Now checks if entities moved out of view. Now you can actually right-click interact with yourself while walking! * Misc Verb menu GUI changes * Fix non-human/ghost verbs * Update types and categories * Allow non-ghost/human to open context menu * configuration verb * tagger verb * Morgue Verbs * Medical Scanner Verbs * Fix solution refactor merge issues * Fix context menu in-view check * Remove prepare GUI * Redo verb restrictions * Fix context menu UI * Disposal Verbs * Spill verb * Light verb * Hand Held light verb * power cell verbs * storage verbs and adding names to insert/eject * Pulling verb * Close context menu on verb execution * Strip verb * AmmoBox verb * fix pull verb * gun barrel verbs revolver verb energy weapon verbs Bolt action verb * Magazine gun barrel verbs * Add charger verbs * PDA verbs * Transfer amount verb * Add reagent verb * make alt-click use ECS verbs * Delete old verb files * Magboot verb * finalising tweaks * context menu visibility changes * code cleanup * Update AdminAddReagentUI.cs * Remove HasFlag * Consistent verb keys * Remove Linq, add comment * Fix in-inventory check * Update GUI text alignment and padding * Added close-menu option * Changed some "interaction" verbs to "activation" * Remove verb keys, use sorted sets * fix master merge * update some verb text * Undo Changes Remove some new verbs that can be added later undid some .ftl bugfixes, can and should be done separately * fix merge * Undo file rename * fix merge * Misc Cleanup * remove contraction * Fix keybinding issue * fix comment * merge fix * fix merge * fix merge * fix merge * fix merge * fix open-close verbs * adjust uncuff verb * fix merge and undo the renaming of SharedPullableComponent to PullableComponent. I'm tired of all of those merge conflicts
2021-10-05 14:29:03 +11:00
private void AddDeconstructVerb(EntityUid uid, ConstructionComponent component, GetOtherVerbsEvent args)
{
if (!args.CanAccess)
return;
if (component.Target?.Name == component.DeconstructionNodeIdentifier ||
component.Node?.Name == component.DeconstructionNodeIdentifier)
return;
Verb verb = new();
//verb.Category = VerbCategories.Construction;
//TODO VERBS add more construction verbs? Until then, removing construction category
verb.Text = Loc.GetString("deconstructible-verb-begin-deconstruct");
verb.IconTexture = "/Textures/Interface/hammer_scaled.svg.192dpi.png";
verb.Act = () =>
{
component.SetNewTarget(component.DeconstructionNodeIdentifier);
if (component.Target == null)
{
// Maybe check, but on the flip-side a better solution might be to not make it undeconstructible in the first place, no?
component.Owner.PopupMessage(args.User, Loc.GetString("deconstructible-verb-activate-no-target-text"));
}
else
{
component.Owner.PopupMessage(args.User, Loc.GetString("deconstructible-verb-activate-text"));
}
};
args.Verbs.Add(verb);
}
private void HandleConstructionExamined(EntityUid uid, ConstructionComponent component, ExaminedEvent args)
{
if (component.Target != null)
{
args.PushMarkup(Loc.GetString(
"construction-component-to-create-header",
("targetName", component.Target.Name)) + "\n");
}
if (component.Edge == null && component.TargetNextEdge != null)
{
var preventStepExamine = false;
foreach (var condition in component.TargetNextEdge.Conditions)
{
preventStepExamine |= condition.DoExamine(args);
}
if (!preventStepExamine)
component.TargetNextEdge.Steps[0].DoExamine(args);
return;
}
if (component.Edge != null)
{
var preventStepExamine = false;
foreach (var condition in component.Edge.Conditions)
{
preventStepExamine |= condition.DoExamine(args);
}
if (preventStepExamine) return;
}
if (component.EdgeNestedStepProgress == null)
{
if (component.EdgeStep < component.Edge?.Steps.Count)
component.Edge.Steps[component.EdgeStep].DoExamine(args);
return;
}
foreach (var list in component.EdgeNestedStepProgress)
{
if(list.Count == 0) continue;
list[0].DoExamine(args);
}
}
private IEnumerable<IEntity> EnumerateNearby(IEntity user)
{
if (user.TryGetComponent(out HandsComponent? hands))
{
foreach (var itemComponent in hands?.GetAllHeldItems()!)
{
if (itemComponent.Owner.TryGetComponent(out ServerStorageComponent? storage))
{
foreach (var storedEntity in storage.StoredEntities!)
{
yield return storedEntity;
}
}
yield return itemComponent.Owner;
}
}
if (user!.TryGetComponent(out InventoryComponent? inventory))
{
foreach (var held in inventory.GetAllHeldItems())
{
if (held.TryGetComponent(out ServerStorageComponent? storage))
{
foreach (var storedEntity in storage.StoredEntities!)
{
yield return storedEntity;
}
}
yield return held;
}
}
foreach (var near in IoCManager.Resolve<IEntityLookup>().GetEntitiesInRange(user!, 2f, LookupFlags.Approximate | LookupFlags.IncludeAnchored))
{
yield return near;
}
}
private async Task<IEntity?> Construct(IEntity user, string materialContainer, ConstructionGraphPrototype graph, ConstructionGraphEdge edge, ConstructionGraphNode targetNode)
{
// We need a place to hold our construction items!
var container = ContainerHelpers.EnsureContainer<Container>(user, materialContainer, out var existed);
if (existed)
{
user.PopupMessageCursor(Loc.GetString("construction-system-construct-cannot-start-another-construction"));
return null;
}
var containers = new Dictionary<string, Container>();
var doAfterTime = 0f;
// HOLY SHIT THIS IS SOME HACKY CODE.
// But I'd rather do this shit than risk having collisions with other containers.
Container GetContainer(string name)
{
if (containers!.ContainsKey(name))
return containers[name];
while (true)
{
var random = _robustRandom.Next();
var c = ContainerHelpers.EnsureContainer<Container>(user!, random.ToString(), out var existed);
if (existed) continue;
containers[name] = c;
return c;
}
}
void FailCleanup()
{
foreach (var entity in container!.ContainedEntities.ToArray())
{
container.Remove(entity);
}
foreach (var cont in containers!.Values)
{
foreach (var entity in cont.ContainedEntities.ToArray())
{
cont.Remove(entity);
}
}
// If we don't do this, items are invisible for some fucking reason. Nice.
Timer.Spawn(1, ShutdownContainers);
}
void ShutdownContainers()
{
container!.Shutdown();
foreach (var c in containers!.Values.ToArray())
{
c.Shutdown();
}
}
var failed = false;
var steps = new List<ConstructionGraphStep>();
foreach (var step in edge.Steps)
{
doAfterTime += step.DoAfter;
var handled = false;
switch (step)
{
case MaterialConstructionGraphStep materialStep:
foreach (var entity in EnumerateNearby(user))
{
if (!materialStep.EntityValid(entity, out var stack))
continue;
var splitStack = _stackSystem.Split(entity.Uid, materialStep.Amount, user.ToCoordinates(), stack);
if (splitStack == null)
continue;
if (string.IsNullOrEmpty(materialStep.Store))
{
if (!container.Insert(splitStack))
continue;
}
else if (!GetContainer(materialStep.Store).Insert(splitStack))
continue;
handled = true;
break;
}
break;
case ArbitraryInsertConstructionGraphStep arbitraryStep:
foreach (var entity in EnumerateNearby(user))
{
if (!arbitraryStep.EntityValid(entity))
continue;
if (string.IsNullOrEmpty(arbitraryStep.Store))
{
if (!container.Insert(entity))
continue;
}
else if (!GetContainer(arbitraryStep.Store).Insert(entity))
continue;
handled = true;
break;
}
break;
}
if (handled == false)
{
failed = true;
break;
}
steps.Add(step);
}
if (failed)
{
user.PopupMessageCursor(Loc.GetString("construction-system-construct-no-materials"));
FailCleanup();
return null;
}
var doAfterArgs = new DoAfterEventArgs(user, doAfterTime)
{
BreakOnDamage = true,
BreakOnStun = true,
BreakOnTargetMove = false,
BreakOnUserMove = true,
NeedHand = false,
};
if (await _doAfterSystem.WaitDoAfter(doAfterArgs) == DoAfterStatus.Cancelled)
{
FailCleanup();
return null;
}
Removed EntityManager member variable from Components and EntitySystems (#2502) * Removed EntityManager member variable from Components and EntitySystems * Removed EntityManager with minor corecctions * Update PathfindingSystem.cs * Update InteractionSystem.cs * Update Content.Server/GameObjects/EntitySystems/Click/ExamineSystem.cs Co-authored-by: Víctor Aguilera Puerto <6766154+Zumorica@users.noreply.github.com> * Update Content.Client/GameObjects/Components/Suspicion/SuspicionRoleComponent.cs Co-authored-by: Clyybber <darkmine956@gmail.com> * Update Content.Client/GameObjects/Components/Suspicion/TraitorOverlay.cs Co-authored-by: Clyybber <darkmine956@gmail.com> * Update Content.Server/GameObjects/Components/Buckle/BuckleComponent.cs Co-authored-by: Clyybber <darkmine956@gmail.com> * Update Content.Server/GameObjects/Components/Buckle/BuckleComponent.cs Co-authored-by: Clyybber <darkmine956@gmail.com> * Update Content.Server/GameObjects/Components/PDA/PDAComponent.cs Co-authored-by: Clyybber <darkmine956@gmail.com> * Update Content.Server/GameObjects/Components/Singularity/SingularityComponent.cs Co-authored-by: Clyybber <darkmine956@gmail.com> * Update Content.Server/GameObjects/Components/Singularity/SingularityComponent.cs Co-authored-by: Clyybber <darkmine956@gmail.com> * Update Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingSystem.cs Co-authored-by: Clyybber <darkmine956@gmail.com> * Update Content.Server/GameObjects/EntitySystems/Click/ExamineSystem.cs Co-authored-by: Clyybber <darkmine956@gmail.com> * Update Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs Co-authored-by: Clyybber <darkmine956@gmail.com> * Update Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs Co-authored-by: Clyybber <darkmine956@gmail.com> * Update Content.Server/GameObjects/Components/Stack/StackComponent.cs Co-authored-by: Clyybber <darkmine956@gmail.com> Co-authored-by: Víctor Aguilera Puerto <6766154+Zumorica@users.noreply.github.com> Co-authored-by: Clyybber <darkmine956@gmail.com> Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
2020-11-18 15:45:53 +01:00
var newEntity = EntityManager.SpawnEntity(graph.Nodes[edge.Target].Entity, user.Transform.Coordinates);
// Yes, this should throw if it's missing the component.
var construction = newEntity.GetComponent<ConstructionComponent>();
// We attempt to set the pathfinding target.
construction.Target = targetNode;
// We preserve the containers...
foreach (var (name, cont) in containers)
{
var newCont = ContainerHelpers.EnsureContainer<Container>(newEntity, name);
foreach (var entity in cont.ContainedEntities.ToArray())
{
cont.ForceRemove(entity);
newCont.Insert(entity);
}
}
// We now get rid of all them.
ShutdownContainers();
// We have step completed steps!
foreach (var step in steps)
{
foreach (var completed in step.Completed)
{
await completed.PerformAction(newEntity, user);
}
}
// And we also have edge completed effects!
foreach (var completed in edge.Completed)
{
await completed.PerformAction(newEntity, user);
}
return newEntity;
}
2020-06-06 10:40:53 +02:00
private async void HandleStartItemConstruction(TryStartItemConstructionMessage ev, EntitySessionEventArgs args)
2020-06-06 10:40:53 +02:00
{
if (!_prototypeManager.TryIndex(ev.PrototypeName, out ConstructionPrototype? constructionPrototype))
{
Logger.Error($"Tried to start construction of invalid recipe '{ev.PrototypeName}'!");
return;
}
if (!_prototypeManager.TryIndex(constructionPrototype.Graph, out ConstructionGraphPrototype? constructionGraph))
{
Logger.Error($"Invalid construction graph '{constructionPrototype.Graph}' in recipe '{ev.PrototypeName}'!");
return;
}
var startNode = constructionGraph.Nodes[constructionPrototype.StartNode];
var targetNode = constructionGraph.Nodes[constructionPrototype.TargetNode];
var pathFind = constructionGraph.Path(startNode.Name, targetNode.Name);
var user = args.SenderSession.AttachedEntity;
2020-06-06 10:40:53 +02:00
if (user == null || !Get<ActionBlockerSystem>().CanInteract(user)) return;
if (!user.TryGetComponent(out HandsComponent? hands)) return;
2020-06-06 10:40:53 +02:00
foreach (var condition in constructionPrototype.Conditions)
2020-06-06 10:40:53 +02:00
{
if (!condition.Condition(user, user.ToCoordinates(), Direction.South))
return;
2020-06-06 10:40:53 +02:00
}
if(pathFind == null)
throw new InvalidDataException($"Can't find path from starting node to target node in construction! Recipe: {ev.PrototypeName}");
var edge = startNode.GetEdge(pathFind[0].Name);
2020-06-06 10:40:53 +02:00
if(edge == null)
throw new InvalidDataException($"Can't find edge from starting node to the next node in pathfinding! Recipe: {ev.PrototypeName}");
2020-06-06 10:40:53 +02:00
// No support for conditions here!
2020-06-06 10:40:53 +02:00
foreach (var step in edge.Steps)
2020-06-06 10:40:53 +02:00
{
switch (step)
{
case ToolConstructionGraphStep _:
case NestedConstructionGraphStep _:
throw new InvalidDataException("Invalid first step for construction recipe!");
}
}
var item = await Construct(user, "item_construction", constructionGraph, edge, targetNode);
if(item != null && item.TryGetComponent(out ItemComponent? itemComp))
hands.PutInHandOrDrop(itemComp);
}
private async void HandleStartStructureConstruction(TryStartStructureConstructionMessage ev, EntitySessionEventArgs args)
{
if (!_prototypeManager.TryIndex(ev.PrototypeName, out ConstructionPrototype? constructionPrototype))
{
Logger.Error($"Tried to start construction of invalid recipe '{ev.PrototypeName}'!");
RaiseNetworkEvent(new AckStructureConstructionMessage(ev.Ack));
return;
}
if (!_prototypeManager.TryIndex(constructionPrototype.Graph, out ConstructionGraphPrototype? constructionGraph))
{
Logger.Error($"Invalid construction graph '{constructionPrototype.Graph}' in recipe '{ev.PrototypeName}'!");
RaiseNetworkEvent(new AckStructureConstructionMessage(ev.Ack));
return;
}
var user = args.SenderSession.AttachedEntity;
if (user == null)
{
Logger.Error($"Client sent {nameof(TryStartStructureConstructionMessage)} with no attached entity!");
return;
}
if (user.IsInContainer())
{
user.PopupMessageCursor(Loc.GetString("construction-system-inside-container"));
return;
}
var startNode = constructionGraph.Nodes[constructionPrototype.StartNode];
var targetNode = constructionGraph.Nodes[constructionPrototype.TargetNode];
var pathFind = constructionGraph.Path(startNode.Name, targetNode.Name);
2020-06-06 10:40:53 +02:00
if (_beingBuilt.TryGetValue(args.SenderSession, out var set))
{
if (!set.Add(ev.Ack))
{
user.PopupMessageCursor(Loc.GetString("construction-system-already-building"));
return;
}
}
else
{
var newSet = new HashSet<int> {ev.Ack};
_beingBuilt[args.SenderSession] = newSet;
}
foreach (var condition in constructionPrototype.Conditions)
{
if (!condition.Condition(user, ev.Location, ev.Angle.GetCardinalDir()))
{
Cleanup();
return;
}
}
void Cleanup()
{
_beingBuilt[args.SenderSession].Remove(ev.Ack);
}
if (user == null
|| !Get<ActionBlockerSystem>().CanInteract(user)
|| !user.TryGetComponent(out HandsComponent? hands) || hands.GetActiveHand == null
|| !user.InRangeUnobstructed(ev.Location, ignoreInsideBlocker:constructionPrototype.CanBuildInImpassable))
{
Cleanup();
return;
}
if(pathFind == null)
throw new InvalidDataException($"Can't find path from starting node to target node in construction! Recipe: {ev.PrototypeName}");
var edge = startNode.GetEdge(pathFind[0].Name);
if(edge == null)
throw new InvalidDataException($"Can't find edge from starting node to the next node in pathfinding! Recipe: {ev.PrototypeName}");
var valid = false;
var holding = hands.GetActiveHand?.Owner;
if (holding == null)
{
Cleanup();
return;
}
// No support for conditions here!
foreach (var step in edge.Steps)
{
switch (step)
{
case EntityInsertConstructionGraphStep entityInsert:
if (entityInsert.EntityValid(holding))
valid = true;
break;
case ToolConstructionGraphStep _:
case NestedConstructionGraphStep _:
throw new InvalidDataException("Invalid first step for item recipe!");
}
if (valid)
break;
}
if (!valid)
{
Cleanup();
return;
}
var structure = await Construct(user, (ev.Ack + constructionPrototype.GetHashCode()).ToString(), constructionGraph, edge, targetNode);
if (structure == null)
{
Cleanup();
return;
}
// We do this to be able to move the construction to its proper position in case it's anchored...
// Oh wow transform anchoring is amazing wow I love it!!!!
var wasAnchored = structure.Transform.Anchored;
structure.Transform.Anchored = false;
structure.Transform.Coordinates = ev.Location;
structure.Transform.LocalRotation = constructionPrototype.CanRotate ? ev.Angle : Angle.Zero;
structure.Transform.Anchored = wasAnchored;
RaiseNetworkEvent(new AckStructureConstructionMessage(ev.Ack));
Cleanup();
2020-06-06 10:40:53 +02:00
}
}
}