예제 #1
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);

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

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

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

            var currentStructurePoints = this.ObjectPublicState.StructurePointsCurrent;
            var newStructurePoints     = currentStructurePoints
                                         + 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;

            // Please note: client will simply always construct until finished
            // Server will keep building stages until the completion tolerance reached.
            if ((Api.IsClient && currentStructurePoints < this.structurePointsMax) ||
                (Api.IsServer && 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}");

                    if (this.IsRepair)
                    {
                        ((IProtoObjectStructure)this.WorldObject.ProtoStaticWorldObject)
                        .ServerOnRepairStageFinished(this.WorldObject, 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.IsRepair)
                {
                    ((IProtoObjectStructure)this.WorldObject.ProtoStaticWorldObject)
                    .ServerOnRepairStageFinished(this.WorldObject, this.Character);
                }

                if (this.ObjectPublicState is ConstructionSitePublicState constructionSiteState)
                {
                    constructionSiteState.LastBuildActionDoneByCharacter = this.Character;
                    var constructionProto = ProtoObjectConstructionSite.SharedGetConstructionProto(this.WorldObject);

                    // add skill experience for building
                    this.CharacterPrivateState.Skills.ServerAddSkillExperience <SkillBuilding>(
                        SkillBuilding.ExperienceAddWhenBuildingFinished
                        * constructionProto.BuildingSkillExperienceMultiplier);
                }
                else
                {
                    // add skill experience for repair
                    this.CharacterPrivateState.Skills.ServerAddSkillExperience <SkillBuilding>(
                        SkillBuilding.ExperienceAddWhenRepairFinished
                        * ((IProtoObjectStructure)this.WorldObject.ProtoGameObject).BuildingSkillExperienceMultiplier);
                }
            }

            this.SetCompleted(isCancelled: false);
            ConstructionSystem.SharedActionCompleted(this.Character, this);
        }
예제 #2
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);

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

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

            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)
            {
                // add building skill experience
                this.CharacterPrivateState.Skills.ServerAddSkillExperience <SkillBuilding>(
                    SkillBuilding.ExperienceAddWhenBuildingFinished);

                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.*/
                Api.GetProtoEntity <ObjectConstructionSite>().SharedGetObjectSoundPreset()
                .PlaySound(ObjectSound.InteractSuccess);
            }

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