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(); } }
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); }
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(); } }
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; }
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); }
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; } }
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); }
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; } }
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); }
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(); }
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(); }
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); }
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(); }
public static bool SharedIsDeconstructable(IProtoObjectStructure protoObjectStructure) { return(protoObjectStructure.ConfigRepair.IsAllowed); }
// TODO: Fix it to IProtoObjectCrate when it implemented public ProtoObjectCrateViewModel([NotNull] IProtoObjectStructure crate) : base(crate) { }
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(); }
public ViewModelStructure() { this.ProtoStructure = new ObjectCampfire(); }