예제 #1
0
        protected override void ServerInitialize(ServerInitializeData data)
        {
            base.ServerInitialize(data);

            if (data.IsFirstTimeInit)
            {
                StructureDecaySystem.ServerResetDecayTimer(data.PrivateState);
            }
        }
예제 #2
0
        private void ServerRemote_PlaceAt(IItem item, Vector2Ushort tilePosition)
        {
            var character = ServerRemoteContext.Character;

            this.ServerValidateItemForRemoteCall(item, character);

            if (!this.SharedIsValidPlacementPosition(tilePosition, character, logErrors: true))
            {
                return;
            }

            if (character.TilePosition.TileDistanceTo(tilePosition)
                > ClientSeedPlacerHelper.MaxSeedPlacementDistance)
            {
                this.CallClient(character, _ => _.ClientRemote_CannotPlaceTooFar());
                return;
            }

            var plantObject = Server.World.CreateStaticWorldObject(this.ObjectPlantProto, tilePosition);

            if (this.ObjectPlantProto is IProtoObjectPlant protoFarmPlant)
            {
                protoFarmPlant.ServerSetBonusForCharacter(plantObject, character);
            }

            Logger.Important($"{character} has placed plant {plantObject} from seed {item}");

            this.ServerNotifyItemUsed(character, item);
            // decrease item count
            Server.Items.SetCount(item, (ushort)(item.Count - 1));

            character.ServerAddSkillExperience <SkillFarming>(SkillFarming.ExperienceForSeedPlanting);

            // restore structure points and reset decay for the farm(s) in the tile where the seed was planted
            foreach (var tileObject in plantObject.OccupiedTile.StaticObjects)
            {
                if (!(tileObject.ProtoStaticWorldObject is IProtoObjectFarm protoFarm))
                {
                    continue;
                }

                StructureDecaySystem.ServerResetDecayTimer(
                    tileObject.GetPrivateState <StructurePrivateState>());

                tileObject.GetPublicState <StaticObjectPublicState>()
                .StructurePointsCurrent = protoFarm.SharedGetStructurePointsMax(tileObject);
            }
        }
예제 #3
0
        protected override void ServerInitialize(ServerInitializeData data)
        {
            base.ServerInitialize(data);

            if (data.IsFirstTimeInit)
            {
                StructureDecaySystem.ServerResetDecayTimer(data.PrivateState,
                                                           StructureConstants.StructuresAbandonedDecayDelaySeconds);
            }
            else
            {
                var publicState = data.PublicState;
                publicState.StructurePointsCurrent = Math.Min(publicState.StructurePointsCurrent,
                                                              this.SharedGetStructurePointsMax(data.GameObject));
            }
        }
예제 #4
0
        public static void ServerOnObjectLandClaimDestroyed(
            IStaticWorldObject landClaimStructure)
        {
            if (!(landClaimStructure?.ProtoStaticWorldObject
                  is IProtoObjectLandClaim))
            {
                throw new Exception("Not a land claim structure: " + landClaimStructure);
            }

            var area = ServerGetLandClaimArea(landClaimStructure);

            if (area == null)
            {
                // area was already released (upgrade?)
                return;
            }

            var areaBounds = SharedGetLandClaimAreaBounds(area);

            ServerWorld.DestroyObject(area);

            Logger.Important("Land claim area removed: " + area);

            // reset decay for all the structures in the destroyed land claim area
            for (var x = (ushort)areaBounds.X; x < areaBounds.X + areaBounds.Width; x++)
            {
                for (var y = (ushort)areaBounds.Y; y < areaBounds.Y + areaBounds.Height; y++)
                {
                    var staticObjects = ServerWorld.GetStaticObjects(new Vector2Ushort(x, y));
                    foreach (var worldObject in staticObjects)
                    {
                        if (worldObject.ProtoStaticWorldObject is IProtoObjectStructure)
                        {
                            StructureDecaySystem.ServerResetDecayTimer(
                                worldObject.GetPrivateState <StructurePrivateState>());
                        }
                    }
                }
            }
        }
예제 #5
0
        private void SharedOnStageCompleted()
        {
            if (!this.ValidateRequiredItemsAvailable())
            {
                // don't have required items - cannot do building/repairing action
                this.AbortAction();
                return;
            }

            if (Api.IsServer)
            {
                // items are removing only on the Server-side
                this.Config.ServerDestroyRequiredItems(this.Character);

                // add building skill experience
                this.CharacterPrivateState.Skills.ServerAddSkillExperience <SkillBuilding>(
                    SkillBuilding.ExperienceAddWhenBuildOrRepairOneStage);

                // notify tool was used
                ServerItemUseObserver.NotifyItemUsed(this.Character, this.ItemConstructionTool);

                // reduce tool durability
                ItemDurabilitySystem.ServerModifyDurability(this.ItemConstructionTool, delta: -1);

                // reset decay timer
                StructureDecaySystem.ServerResetDecayTimer(
                    this.WorldObject.GetPrivateState <StructurePrivateState>());
            }

            this.currentStageDurationSeconds     = this.CalculateStageDurationSeconds(this.Character, isFirstStage: false);
            this.currentStageTimeRemainsSeconds += this.currentStageDurationSeconds;

            var newStructurePoints = this.ObjectPublicState.StructurePointsCurrent
                                     + this.stageStructureAddValue;

            // Please note: as we're using floating number (StructurePointsCurrent) to track the construction progress
            // it might cause some inaccuracy. In order to avoid this inaccuracy we're adding some tolerance.
            // The tolerance is also needed to handle the case when the blueprint was damaged only slightly.
            var completionTolerance = this.stageStructureAddValue / 2.0;

            if (newStructurePoints + completionTolerance < this.structurePointsMax)
            {
                // repairing/building is still possible - more stages are available
                if (Api.IsServer)
                {
                    this.ObjectPublicState.StructurePointsCurrent = (float)newStructurePoints;
                    Api.Logger.Important(
                        $"Building/repairing progressed: {this.WorldObject} structure points: {newStructurePoints}/{this.structurePointsMax}; by {this.Character}");
                }

                this.UpdateProgress();

                if (!this.ValidateRequiredItemsAvailable())
                {
                    // don't have enough required items - cannot continue building/repairing action
                    this.AbortAction();
                    return;
                }

                if (Api.IsServer &&
                    this.ItemConstructionTool.IsDestroyed)
                {
                    // tool was destroyed (durability 0)
                    this.AbortAction();
                    return;
                }

                return;
            }

            // repairing/building is completed
            if (Api.IsServer)
            {
                newStructurePoints = this.structurePointsMax;
                Api.Logger.Important(
                    $"Building/repairing completed: {this.WorldObject} structure points: {newStructurePoints}/{this.structurePointsMax}; by {this.Character}");
                this.ObjectPublicState.StructurePointsCurrent = (float)newStructurePoints;

                if (this.ObjectPublicState is ConstructionSitePublicState constructionSiteState)
                {
                    constructionSiteState.LastBuildActionDoneByCharacter = this.Character;
                }
            }
            else
            {
                // play success sound
                this.TargetWorldObject.ProtoWorldObject.SharedGetObjectSoundPreset()
                .PlaySound(ObjectSound.InteractSuccess);
            }

            this.SetCompleted(isCancelled: false);
            ConstructionSystem.SharedActionCompleted(this.Character, this);
        }