protected virtual IStaticWorldObject ServerCreateConstructionSite(
            Vector2Ushort tilePosition,
            IProtoObjectStructure protoStructure,
            ICharacter byCharacter)
        {
            if (protoStructure == null)
            {
                throw new ArgumentNullException(nameof(protoStructure));
            }

            var protoConstructionSite = Api.GetProtoEntity <ObjectConstructionSite>();
            var constructionSite      = Server.World.CreateStaticWorldObject(protoConstructionSite, tilePosition);

            var serverState = ObjectConstructionSite.GetPublicState(constructionSite);

            serverState.Setup(protoStructure);

            constructionSite.ProtoStaticWorldObject.SharedCreatePhysics(constructionSite);

            Logger.Important("Construction site created: " + constructionSite);
            protoConstructionSite.ServerOnBuilt(constructionSite, byCharacter);
            Api.SafeInvoke(() => ServerStructureBuilt?.Invoke(byCharacter, constructionSite));
            Api.SafeInvoke(() => SharedWallConstructionRefreshHelper.SharedRefreshNeighborObjects(
                               constructionSite,
                               isDestroy: false));

            return(constructionSite);
        }
        public ViewModelConstructionBuildRequirementsTooltip(
            ConstructionSitePublicState constructionSitePublicState)
        {
            this.constructionSitePublicState = constructionSitePublicState;

            if (constructionSitePublicState == null)
            {
                if (!IsDesignTime)
                {
                    throw new Exception("No construction site server public state provided in game");
                }

                // fake data
                this.protoStructure = new ObjectFloorWood();
            }
            else
            {
                // actual data
                this.protoStructure = this.constructionSitePublicState.ConstructionProto;
                this.constructionSitePublicState.ClientSubscribe(
                    _ => _.StructurePointsCurrent,
                    newStructurePoints => this.UpdateStageCountRemains(),
                    this);

                this.UpdateStageCountRemains();
            }
        }
Esempio n. 3
0
        private IStaticWorldObject ServerCreateConstructionSite(
            Vector2Ushort tilePosition,
            IProtoObjectStructure protoStructure,
            ICharacter byCharacter)
        {
            if (protoStructure == null)
            {
                throw new ArgumentNullException(nameof(protoStructure));
            }

            var protoConstructionSite = protoStructure.ConstructionSitePrototype;
            var constructionSite      = Server.World.CreateStaticWorldObject(protoConstructionSite, tilePosition);

            var serverState = ProtoObjectConstructionSite.GetPublicState(constructionSite);

            serverState.Setup(protoStructure);

            // reinitialize to build proper physics and occupy proper layout
            constructionSite.ServerRebuildScopeAndPhysics();

            Logger.Important("Construction site created: " + constructionSite);
            protoConstructionSite.ServerOnBuilt(constructionSite, byCharacter);
            Api.SafeInvoke(() => ServerStructureBuilt?.Invoke(byCharacter, constructionSite));
            Api.SafeInvoke(() => SharedWallConstructionRefreshHelper.SharedRefreshNeighborObjects(
                               constructionSite,
                               isDestroy: false));

            return(constructionSite);
        }
Esempio n. 4
0
        public static void ServerReplaceConstructionSiteWithStructure(
            IStaticWorldObject worldObject,
            IProtoObjectStructure protoStructure,
            ICharacter byCharacter)
        {
            if (worldObject?.IsDestroyed ?? true)
            {
                throw new Exception("Construction site doesn't exist or already destroyed: " + worldObject);
            }

            var tilePosition = worldObject.TilePosition;

            // destroy construction site
            Server.World.DestroyObject(worldObject);

            // create structure
            var structure = ConstructionSystem.ServerCreateStructure(
                protoStructure,
                tilePosition,
                byCharacter: byCharacter);

            if (byCharacter == null)
            {
                return;
            }

            Instance.ServerNotifyOnStructurePlacedOrRelocated(structure, byCharacter);
            Api.SafeInvoke(() => ServerStructureBuilt?.Invoke(byCharacter, structure));
        }
        public ViewModelConstructionRepairRequirementsTooltip(StaticObjectPublicState objectPublicState)
        {
            this.objectPublicState = objectPublicState;

            if (objectPublicState == null)
            {
                if (!IsDesignTime)
                {
                    throw new Exception("No construction site server public state provided in game");
                }

                // fake data
                this.protoStructure = new ObjectFloorWood();
            }
            else
            {
                // actual data
                this.protoStructure = (IProtoObjectStructure)this.objectPublicState.GameObject.ProtoGameObject;
                this.objectPublicState.ClientSubscribe(
                    _ => _.StructurePointsCurrent,
                    newStructurePoints => this.UpdateStageCountRemains(),
                    this);

                this.UpdateStageCountRemains();
            }
        }
Esempio n. 6
0
 protected override void WindowClosed()
 {
     this.lastSelectedStructure = this.ViewModel.SelectedStructure?.ProtoStructure;
     this.DataContext           = null;
     this.ViewModel.Dispose();
     this.ViewModel = null;
 }
        public ProtoObjectStructureViewModel([NotNull] IProtoObjectStructure structure) : base(structure)
        {
            Description        = structure.Description;
            DescriptionUpgrade = structure.DescriptionUpgrade;

            IsAutoUnlocked = structure.IsAutoUnlocked;
        }
Esempio n. 8
0
        private static bool SharedIsTooFarToPlace(
            IProtoObjectStructure protoStructure,
            Vector2Ushort tilePosition,
            ICharacter character,
            bool logErrors)
        {
            if (character.TilePosition.TileDistanceTo(tilePosition)
                <= MaxDistanceToBuild ||
                CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                return(false);
            }

            if (!logErrors)
            {
                return(true);
            }

            Logger.Info(
                $"Cannot place {protoStructure} at {tilePosition}: player character is too far.",
                character);

            if (IsClient)
            {
                Instance.ClientRemote_CannotBuildTooFar(protoStructure);
            }
            else
            {
                Instance.CallClient(character, _ => _.ClientRemote_CannotBuildTooFar(protoStructure));
            }

            return(true);
        }
Esempio n. 9
0
 private void AppendLineStructure(StringBuilder sb, IProtoObjectStructure structure)
 {
     sb.Append("* ")
     .Append(structure.ShortId)
     .Append(" - ")
     .Append(structure.Name)
     .AppendLine();
 }
        public void Setup(IProtoObjectStructure protoStructure)
        {
            this.ConstructionProto = protoStructure;

            // set structure points to match first build stage
            this.StructurePointsCurrent = protoStructure.StructurePointsMaxForConstructionSite
                                          / protoStructure.ConfigBuild.StagesCount;
            if (this.StructurePointsCurrent < 1)
            {
                this.StructurePointsCurrent = 1;
            }
        }
Esempio n. 11
0
        public static IStaticWorldObject ServerCreateStructure(
            IProtoObjectStructure protoStructure,
            Vector2Ushort tilePosition,
            ICharacter byCharacter)
        {
            var structure = Api.Server.World.CreateStaticWorldObject(
                protoStructure,
                tilePosition);

            Logger.Important(byCharacter + " built " + structure);
            protoStructure.ServerOnBuilt(structure, byCharacter);
            return(structure);
        }
Esempio n. 12
0
            public ViewModelStructureInfo(IProtoObjectStructure protoStructure)
            {
                this.ProtoStructure = protoStructure;

                if (IsDesignTime)
                {
                    this.Icon = Brushes.BlueViolet;
                    return;
                }

                if (protoStructure is not null)
                {
                    this.Icon = Client.UI.GetTextureBrush(this.ProtoStructure.Icon);
                }
            }
        public DeconstructionActionState(
            ICharacter character,
            IStaticWorldObject worldObject,
            IItem itemCrowbarTool)
            : base(character)
        {
            this.WorldObject          = worldObject;
            this.ItemCrowbarTool      = itemCrowbarTool;
            this.ProtoItemCrowbarTool = (IProtoItemToolCrowbar)itemCrowbarTool?.ProtoGameObject;
            this.protoStructure       = (IProtoObjectStructure)worldObject.ProtoWorldObject;

            this.currentStageDurationSeconds = this.CalculateStageDurationSeconds(character, isFirstStage: true);

            this.currentStageTimeRemainsSeconds = this.currentStageDurationSeconds;
            this.ObjectPublicState = worldObject.GetPublicState <StaticObjectPublicState>();

            this.structurePointsMax = this.protoStructure.SharedGetStructurePointsMax(worldObject);

            // use build config to determine how many deconstruction steps required
            var stagesCount = 10;

            if (!(this.protoStructure is IProtoObjectLandClaim))
            {
                if (this.protoStructure.ConfigBuild.IsAllowed)
                {
                    stagesCount = this.protoStructure.ConfigBuild.StagesCount;
                }
                else
                {
                    stagesCount = this.protoStructure.GetStructureActiveConfig(worldObject)
                                  .StagesCount;
                }
            }

            if (stagesCount <= 0)
            {
                // force at least 1 deconstruction stage
                stagesCount = 1;
            }

            this.stageStructureRemoveValue = this.structurePointsMax / stagesCount;
            if (this.stageStructureRemoveValue < 1)
            {
                this.stageStructureRemoveValue = 1;
            }
        }
Esempio n. 14
0
        public static IStaticWorldObject ServerUpgrade(
            IStaticWorldObject oldStructure,
            IProtoObjectStructure upgradeStructure,
            ICharacter character)
        {
            if (!(oldStructure?.ProtoStaticWorldObject
                  is IProtoObjectLandClaim))
            {
                throw new Exception("Not a land claim structure: " + oldStructure);
            }

            var tilePosition = oldStructure.TilePosition;
            var area         = ServerGetLandClaimArea(oldStructure);

            // release area
            oldStructure.GetPublicState <ObjectLandClaimPublicState>().LandClaimAreaObject = null;

            // destroy old structure
            ServerWorld.DestroyObject(oldStructure);

            // create new structure
            var upgradedObject = ServerWorld.CreateStaticWorldObject(upgradeStructure, tilePosition);

            // get area for the old land claim structure
            var areaPrivateState = LandClaimArea.GetPrivateState(area);
            var areaPublicState  = LandClaimArea.GetPublicState(area);

            // update it to use upgraded land claim structure
            areaPrivateState.ServerLandClaimWorldObject = upgradedObject;
            areaPublicState.SetupAreaProperties(areaPrivateState);

            // set this area to the structure public state
            upgradedObject.GetPublicState <ObjectLandClaimPublicState>()
            .LandClaimAreaObject = area;

            Logger.Important($"Successfully upgraded: {oldStructure} to {upgradedObject}", character);

            Instance.CallClient(
                Server.Characters.EnumerateAllPlayerCharacters(onlyOnline: true),
                _ => _.ClientRemote_OnLandClaimUpgraded(area));

            return(upgradedObject);
        }
Esempio n. 15
0
        public static void ClientToggleConstructionMenu()
        {
            if (ClientCloseConstructionMenu())
            {
                // just closed the construction menu
                return;
            }

            if (ClientCurrentCharacterHelper.PublicState.CurrentVehicle != null)
            {
                Logger.Important("Construction menu is not accessible while in a vehicle");
                return;
            }

            WindowConstructionMenu.Open(
                onStructureProtoSelected:
                selectedProtoStructure =>
            {
                ClientEnsureConstructionToolIsSelected();
                currentSelectedProtoConstruction = selectedProtoStructure;

                componentObjectPlacementHelper = Client.Scene
                                                 .CreateSceneObject("ConstructionHelper")
                                                 .AddComponent <ClientComponentObjectPlacementHelper>();

                // repeat placement for held button only for walls, floor and farms
                var isRepeatCallbackIfHeld = selectedProtoStructure.IsRepeatPlacement;

                componentObjectPlacementHelper
                .Setup(selectedProtoStructure,
                       isCancelable: true,
                       isRepeatCallbackIfHeld: isRepeatCallbackIfHeld,
                       isDrawConstructionGrid: true,
                       isBlockingInput: true,
                       validateCanPlaceCallback: ClientValidateCanBuild,
                       placeSelectedCallback: ClientConstructionPlaceSelectedCallback,
                       delayRemainsSeconds: 0.4);
            },
                onClosed: OnStructureSelectWindowOpenedOrClosed);

            OnStructureSelectWindowOpenedOrClosed();
        }
Esempio n. 16
0
        private void OnSelectedHandler(IProtoObjectStructure selectedProtoStructure)
        {
            if (selectedProtoStructure is null)
            {
                return;
            }

            var character = Api.Client.Characters.CurrentPlayerCharacter;

            if (!selectedProtoStructure.ConfigBuild.CheckStageCanBeBuilt(character))
            {
                Api.Logger.Warning(
                    $"Cannot build selected structure {selectedProtoStructure.ShortId} - not enough resources.");
                return;
            }

            //this.ViewModel.StructureSelectedCallback = null;
            this.CloseWindow();
            this.onSelected.Invoke(selectedProtoStructure);
        }
        public static void ClientToggleConstructionMenu()
        {
            if (ClientCloseConstructionMenu())
            {
                // just closed the construction menu
                return;
            }

            WindowConstructionMenu.Open(
                onStructureProtoSelected:
                selectedProtoStructure =>
            {
                ClientEnsureConstructionToolIsSelected();
                currentSelectedProtoConstruction = selectedProtoStructure;

                componentObjectPlacementHelper = Client.Scene
                                                 .CreateSceneObject(
                    "ConstructionHelper",
                    Vector2D.Zero)
                                                 .AddComponent <
                    ClientComponentObjectPlacementHelper>();

                // repeat placement for held button only for walls, floor and farms
                var isRepeatCallbackIfHeld = selectedProtoStructure is IProtoObjectWall ||
                                             selectedProtoStructure is IProtoObjectFloor ||
                                             selectedProtoStructure is IProtoObjectFarm;

                componentObjectPlacementHelper
                .Setup(selectedProtoStructure,
                       isCancelable: true,
                       isRepeatCallbackIfHeld: isRepeatCallbackIfHeld,
                       isDrawConstructionGrid: true,
                       isBlockingInput: true,
                       validateCanPlaceCallback: ClientValidateCanBuild,
                       placeSelectedCallback: ClientConstructionPlaceSelectedCallback,
                       delayRemainsSeconds: 0.4);
            },
                onClosed: OnStructureSelectWindowOpenedOrClosed);

            OnStructureSelectWindowOpenedOrClosed();
        }
Esempio n. 18
0
        public ViewModelStructure(IProtoObjectStructure protoStructure)
        {
            this.ProtoStructure = protoStructure;

            if (IsDesignTime)
            {
                this.IsCanBuild = true;
                this.Icon       = Brushes.BlueViolet;
                return;
            }

            if (protoStructure is null)
            {
                return;
            }

            this.UpdateIsCanBuild();
            this.SubscribeToContainersEvents();

            this.Icon = Client.UI.GetTextureBrush(this.ProtoStructure.Icon);
        }
Esempio n. 19
0
        private bool SharedValidateCanUpgradeToNextStage(
            IStaticWorldObject objectLaunchpad,
            ICharacter character,
            out IProtoObjectStructure upgradeStructure)
        {
            if (!this.SharedCanInteract(character, objectLaunchpad, writeToLog: true))
            {
                // cannot interact
                upgradeStructure = null;
                return(false);
            }

            upgradeStructure = this.ConfigUpgrade.Entries[0].ProtoStructure;
            if (upgradeStructure is null)
            {
                // no upgrade exists
                return(false);
            }

            if (!upgradeStructure.ListedInTechNodes.Any(
                    techNode => character.SharedGetTechnologies().SharedIsNodeUnlocked(techNode)) &&
                !CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                // has not yet researched the relevant technology
                return(false);
            }

            var privateState        = GetPrivateState(objectLaunchpad);
            var taskCompletionState = privateState.TaskCompletionState;

            if (!taskCompletionState.All(flag => flag))
            {
                Logger.Warning(character + " has not completed all the tasks yet - cannot upgrade: " + objectLaunchpad);
                return(false);
            }

            // all tasks completed
            return(true);
        }
        private static void Update()
        {
            if (LoadingSplashScreenManager.Instance.CurrentState
                != LoadingSplashScreenState.Hidden)
            {
                return;
            }

            IStaticWorldObject    worldObject    = null;
            IProtoObjectStructure protoStructure = null;

            var selectedProtoItem = ClientHotbarSelectedItemManager.SelectedItem?.ProtoItem;

            if (selectedProtoItem is IProtoItemToolToolbox ||
                selectedProtoItem is IProtoItemToolCrowbar)
            {
                worldObject    = ClientComponentObjectInteractionHelper.MouseOverObject as IStaticWorldObject;
                protoStructure = worldObject?.ProtoGameObject as IProtoObjectStructure;
            }

            if (currentTooltipsWorldObject != worldObject)
            {
                tooltipBuildOrRepair?.Destroy();
                tooltipBuildOrRepair = null;

                tooltipRelocate?.Destroy();
                tooltipRelocate = null;

                tooltipDeconstruct?.Destroy();
                tooltipDeconstruct = null;

                currentTooltipsWorldObject = worldObject;
            }

            if (protoStructure is null)
            {
                return;
            }

            // process structure repair tooltip
            var isBuildTooltipRequired
                = selectedProtoItem is IProtoItemToolToolbox &&
                  protoStructure.ClientIsConstructionOrRepairRequirementsTooltipShouldBeDisplayed(worldObject);

            if (tooltipBuildOrRepair is null)
            {
                if (isBuildTooltipRequired)
                {
                    tooltipBuildOrRepair = ConstructionOrRepairRequirementsTooltip.CreateAndAttach(worldObject);
                }
            }
            else if (!isBuildTooltipRequired)
            {
                tooltipBuildOrRepair.Destroy();
                tooltipBuildOrRepair = null;
            }

            // process structure relocation tooltip
            var canRelocate = selectedProtoItem is IProtoItemToolToolbox &&
                              !ConstructionRelocationSystem.IsInObjectPlacementMode &&
                              ConstructionRelocationSystem.SharedIsRelocatable(worldObject);

            if (tooltipRelocate is null)
            {
                if (canRelocate)
                {
                    tooltipRelocate = ConstructionRelocationTooltip.CreateAndAttach(worldObject);
                }
            }
            else if (!canRelocate)
            {
                tooltipRelocate.Destroy();
                tooltipRelocate = null;
            }

            // process structure deconstruction tooltip
            var canDeconstruct = selectedProtoItem is IProtoItemToolCrowbar &&
                                 DeconstructionSystem.SharedIsDeconstructable(protoStructure);

            if (tooltipDeconstruct is null)
            {
                if (canDeconstruct)
                {
                    tooltipDeconstruct = ConstructionDeconstructTooltip.CreateAndAttach(worldObject);
                }
            }
            else if (!canDeconstruct)
            {
                tooltipDeconstruct.Destroy();
                tooltipDeconstruct = null;
            }
        }
 public ConstructionUpgradeEntry(IProtoObjectStructure protoStructure)
 {
     this.ProtoStructure = protoStructure;
     this.requiredItems  = new InputItems();
     this.RequiredItems  = this.requiredItems.AsReadOnly();
 }
Esempio n. 22
0
 public static bool SharedIsDeconstructable(IProtoObjectStructure protoObjectStructure)
 {
     return(protoObjectStructure.ConfigRepair.IsAllowed);
 }
Esempio n. 23
0
 // TODO: Fix it to IProtoObjectCrate when it implemented
 public ProtoObjectCrateViewModel([NotNull] IProtoObjectStructure crate) : base(crate)
 {
 }
Esempio n. 24
0
        private void ServerRemote_PlaceStructure(
            IProtoObjectStructure protoStructure,
            Vector2Ushort tilePosition)
        {
            var character = ServerRemoteContext.Character;

            if (!protoStructure.SharedIsTechUnlocked(character))
            {
                Logger.Error(
                    $"Cannot build {protoStructure} at {tilePosition}: player character doesn't have unlocked tech node for this structure.",
                    character);
                return;
            }

            if (SharedIsTooFarToPlace(protoStructure,
                                      tilePosition,
                                      character,
                                      logErrors: true))
            {
                return;
            }

            // validate if the structure can be placed there
            if (!protoStructure.CheckTileRequirements(tilePosition, character, logErrors: true))
            {
                return;
            }

            // validate if there are enough required items/resources to build the structure
            var configBuild = protoStructure.ConfigBuild;

            if (!configBuild.CheckStageCanBeBuilt(character))
            {
                Logger.Error(
                    $"Cannot build {protoStructure} at {tilePosition}: player character doesn't have enough resources (or not allowed).",
                    character);
                return;
            }

            var selectedHotbarItem = PlayerCharacter.GetPublicState(character).SelectedItem;

            if (!(selectedHotbarItem?.ProtoItem is IProtoItemToolToolbox))
            {
                Logger.Error(
                    $"Cannot build {protoStructure} at {tilePosition}: player character doesn't have selected construction tool.",
                    character);
                return;
            }

            // consume required items/resources (for 1 stage)
            configBuild.ServerDestroyRequiredItems(character);

            if (configBuild.StagesCount > 1)
            {
                if (AllowInstantPlacementInCreativeMode &&
                    CreativeModeSystem.SharedIsInCreativeMode(character))
                {
                    // instant placement allowed
                }
                else
                {
                    // there are multiple construction stages - spawn and setup a construction site
                    var constructionSite = this.ServerCreateConstructionSite(tilePosition, protoStructure, character);
                    this.ServerNotifyOnStructurePlacedOrRelocated(constructionSite, character);
                    return;
                }
            }

            ServerDecalsDestroyHelper.DestroyAllDecals(tilePosition, protoStructure.Layout);

            // there is only one construction stage - simply spawn the structure
            var structure = ConstructionSystem.ServerCreateStructure(
                protoStructure,
                tilePosition,
                character);

            this.ServerNotifyOnStructurePlacedOrRelocated(structure, character);
            Api.SafeInvoke(() => ServerStructureBuilt?.Invoke(character, structure));
        }
 public TechNodeEffectStructureUnlock(IProtoObjectStructure structure)
 {
     this.Structure = structure ?? throw new ArgumentNullException();
 }
Esempio n. 26
0
 public ViewModelStructure()
 {
     this.ProtoStructure = new ObjectCampfire();
 }