Example #1
0
        public bool ServerGather(IStaticWorldObject worldObject, ICharacter character)
        {
            var lootDroplist = GetPublicState(worldObject).ProtoCharacterMob
                               .LootDroplist;

            var dropItemContext = new DropItemContext(character, worldObject);
            CreateItemResult dropItemResult;
            var attemptRemains = 200;

            do
            {
                dropItemResult = lootDroplist.TryDropToCharacterOrGround(character,
                                                                         character.TilePosition,
                                                                         dropItemContext,
                                                                         out _);
            }
            // ensure that at least something is spawned...
            // perhaps that's not a good idea, but we have an attempts limit
            while (dropItemResult.TotalCreatedCount == 0 &&
                   --attemptRemains > 0);

            // probably the attempts limit exceeded and nothing is spawned
            // we don't consider this as an issue as the probability of this is too rare

            Logger.Info(this + " was gathered", character);
            NotificationSystem.ServerSendItemsNotification(character, dropItemResult);
            character.ServerAddSkillExperience <SkillHunting>(SkillHunting.ExperienceForGather);
            Server.World.DestroyObject(worldObject);
            return(true);
        }
Example #2
0
        public bool ServerOnHackingStage(IStaticWorldObject worldObject, ICharacter character)
        {
            var publicState = GetPublicState(worldObject);

            publicState.HackingProgressPercent += 100 / this.HackingStagesNumber;
            if (publicState.HackingProgressPercent < 100)
            {
                return(true);
            }

            Server.World.DestroyObject(worldObject);

            var lootDroplist    = this.LootDroplist;
            var dropItemContext = new DropItemContext(character, worldObject);

            var dropItemResult = lootDroplist.TryDropToCharacterOrGround(
                character,
                character.TilePosition,
                dropItemContext,
                out _,
                probabilityMultiplier: this.ServerGetDropListProbabilityMultiplier(worldObject));

            if (dropItemResult.TotalCreatedCount > 0)
            {
                NotificationSystem.ServerSendItemsNotification(character, dropItemResult);
                var skillExperienceToAdd = SkillSearching.ExperienceAddWhenSearching
                                           * SearchSkillExperienceMultiplier;
                character.ServerAddSkillExperience <SkillSearching>(skillExperienceToAdd);
            }

            ServerObjectUseObserver.NotifyObjectUsed(character, worldObject);
            this.ServerOnHacked(character, worldObject);
            return(true);
        }
        private void ServerOnMineralStageMined(
            WeaponFinalCache weaponCache,
            IStaticWorldObject mineralObject,
            int damageStage)
        {
            var byCharacter   = weaponCache.Character;
            var byWeaponProto = weaponCache.ProtoWeapon;

            Logger.Info(
                $"{mineralObject} current damage stage changed to {damageStage}. Dropping items for that stage",
                byCharacter);

            try
            {
                var dropItemsList   = this.DropItemsConfig.GetForStage(damageStage);
                var dropItemContext = new DropItemContext(byCharacter,
                                                          mineralObject,
                                                          byWeaponProto,
                                                          weaponCache.ProtoExplosive);

                var objectDrone = weaponCache.Drone;
                if (objectDrone != null)
                {
                    // drop resources into the internal storage of the drone
                    var storageItemsContainer = ((IProtoDrone)objectDrone.ProtoGameObject)
                                                .ServerGetStorageItemsContainer(objectDrone);
                    dropItemsList.TryDropToContainer(storageItemsContainer, dropItemContext);
                }
                else if (byWeaponProto is IProtoItemWeaponMelee)
                {
                    var result = dropItemsList.TryDropToCharacterOrGround(byCharacter,
                                                                          mineralObject.TilePosition,
                                                                          dropItemContext,
                                                                          groundContainer: out _);
                    if (result.TotalCreatedCount > 0)
                    {
                        NotificationSystem.ServerSendItemsNotification(byCharacter, result);
                    }
                }
                else
                {
                    // not a melee weapon or cannot drop to the character inventory - drop on the ground only
                    dropItemsList.TryDropToGround(mineralObject.TilePosition,
                                                  dropItemContext,
                                                  out _);
                }
            }
            finally
            {
                if (byWeaponProto is IProtoItemToolMining ||
                    weaponCache.ProtoExplosive is ObjectBombMining)
                {
                    // add experience proportional to the mineral structure points (effectively - for the time spent on mining)
                    var exp = SkillProspecting.ExperienceAddPerStructurePoint;
                    exp *= this.StructurePointsMax / this.DamageStagesCount;
                    byCharacter?.ServerAddSkillExperience <SkillProspecting>(exp);
                }
            }
        }
Example #4
0
        public static bool ServerRollExtraLoot(DropItemContext context)
        {
            if (!context.HasCharacter)
            {
                return(false);
            }

            var character            = context.Character;
            var extraLootProbability = character.SharedGetFinalStatMultiplier(StatName.SearchingExtraLoot) - 1.0;

            return(RandomHelper.RollWithProbability(extraLootProbability));
        }
Example #5
0
        protected override void ServerOnStaticObjectDestroyedByCharacter(
            ICharacter byCharacter,
            IProtoItemWeapon byWeaponProto,
            IStaticWorldObject targetObject)
        {
            base.ServerOnStaticObjectDestroyedByCharacter(byCharacter, byWeaponProto, targetObject);

            // drop chance and gained experience depends on the vegetation growth stage
            var growthProgressFraction = this.GrowthStagesCount > 0
                                             ? GetPublicState(targetObject).GrowthStage / (double)this.GrowthStagesCount
                                             : 1;

            growthProgressFraction = MathHelper.Clamp(growthProgressFraction, 0.1, 1);

            try
            {
                var dropItemContext = new DropItemContext(byCharacter, targetObject);
                if (byWeaponProto is IProtoItemWeaponMelee)
                {
                    // a melee weapon - try drop items to character
                    var result = this.DroplistOnDestroy.TryDropToCharacter(
                        byCharacter,
                        dropItemContext,
                        probabilityMultiplier: growthProgressFraction);
                    if (result.IsEverythingCreated)
                    {
                        NotificationSystem.ServerSendItemsNotification(byCharacter, result);
                        return;
                    }

                    result.Rollback();
                }

                // not a melee weapon or cannot drop to character - drop on the ground only
                this.DroplistOnDestroy.TryDropToGround(
                    targetObject.TilePosition,
                    dropItemContext,
                    probabilityMultiplier: growthProgressFraction,
                    groundContainer: out _);
            }
            finally
            {
                if (byWeaponProto is IProtoItemToolWoodcutting)
                {
                    // add experience proportional to the tree structure points (effectively - for the time spent on woodcutting)
                    var exp = SkillWoodcutting.ExperienceAddPerStructurePoint;
                    exp *= this.StructurePointsMax * growthProgressFraction;
                    byCharacter?.ServerAddSkillExperience <SkillWoodcutting>(exp);
                }
            }
        }
Example #6
0
        public bool ServerGather(IStaticWorldObject worldObject, ICharacter character)
        {
            //MOD
            PublicState publicState = GetPublicState(worldObject);

            var lootDroplist = publicState.ProtoCharacterMob.LootDroplist;

            var dropItemContext = new DropItemContext(character, worldObject);

            CreateItemResult dropItemResultFinal = new CreateItemResult();

            var level = publicState.Level;

            for (int i = 0; i < level; i++)
            {
                CreateItemResult dropItemResult;

                var attemptRemains = 200;
                do
                {
                    dropItemResult = lootDroplist.TryDropToCharacterOrGround(character,
                                                                             character.TilePosition,
                                                                             dropItemContext,
                                                                             out _);

                    dropItemResultFinal.MergeWith(dropItemResult);
                }
                // ensure that at least something is spawned...
                // perhaps that's not a good idea, but we have an attempts limit
                while (dropItemResult.TotalCreatedCount == 0 && --attemptRemains > 0);
            }

            if (!dropItemResultFinal.IsEverythingCreated)
            {
                Logger.Warning("Not all loot items were provided by "
                               + worldObject
                               + " - there is not enough space in inventory and around the character");
            }

            // probably the attempts limit exceeded and nothing is spawned
            // we don't consider this as an issue as the probability of this is too rare

            Logger.Info(worldObject + " was gathered", character);
            Server.World.DestroyObject(worldObject);

            NotificationSystem.ServerSendItemsNotification(character, dropItemResultFinal);
            character.ServerAddSkillExperience <SkillHunting>(SkillHunting.ExperienceForGather * level);
            return(true);
        }
Example #7
0
        public static bool OnlyBeforeT4SpecializedOrPvE(DropItemContext context)
        {
            if (PveSystem.ServerIsPvE)
            {
                return(true);
            }

            if (Api.IsEditor)
            {
                return(true);
            }

            var timeRemains = TechConstants.PvpTechTimeGameTier4Specialized - Api.Server.Game.SecondsSinceWorldCreation;

            return(timeRemains > 0);
        }
Example #8
0
        private void ServerOnDamageStageIncreased(
            [CanBeNull] ICharacter byCharacter,
            IProtoItemWeapon byWeaponProto,
            IStaticWorldObject mineralObject,
            int damageStage)
        {
            Logger.Info(
                $"{mineralObject} current damage stage changed to {damageStage}. Dropping items for that stage",
                byCharacter);

            try
            {
                var dropItemsList   = this.DropItemsConfig.GetForStage(damageStage);
                var dropItemContext = new DropItemContext(byCharacter, mineralObject, byWeaponProto);

                if (byWeaponProto is IProtoItemWeaponMelee)
                {
                    var result = dropItemsList.TryDropToCharacter(byCharacter, dropItemContext);
                    if (result.IsEverythingCreated)
                    {
                        NotificationSystem.ServerSendItemsNotification(
                            byCharacter,
                            result);
                        return;
                    }

                    result.Rollback();
                }

                // not a melee weapon or cannot drop to the character inventory - drop on the ground only
                dropItemsList.TryDropToGround(mineralObject.TilePosition,
                                              dropItemContext,
                                              out _);
            }
            finally
            {
                if (byWeaponProto is IProtoItemToolMining)
                {
                    // add experience proportional to the mineral structure points (effectively - for the time spent on mining)
                    var exp = SkillMining.ExperienceAddPerStructurePoint;
                    exp *= this.StructurePointsMax / DamageStagesCount;
                    byCharacter?.ServerAddSkillExperience <SkillMining>(exp);
                }
            }
        }
        public static bool ConditionHasDeviceEquipped(DropItemContext context)
        {
            // Please note: checking this condition will also automatically deduct the device's durability.
            if (!context.HasCharacter)
            {
                return(false);
            }

            // find the device
            var itemDevice = context.Character.SharedGetPlayerContainerEquipment()
                             .GetItemsOfProto(protoItemKeiniteCollector)
                             .FirstOrDefault();

            if (itemDevice is null)
            {
                // don't have an equipped device
                return(false);
            }

            ItemDurabilitySystem.ServerModifyDurability(itemDevice, -DurabilityDecreasePerUse);
            return(true);
        }
Example #10
0
 static bool T5SpecializedPvPOnly(DropItemContext context)
 => !PveSystem.ServerIsPvE &&
 ServerTechTimeGateHelper.IsAvailableT5Specialized(context);
Example #11
0
 public static bool IsAvailableT3Basic(DropItemContext context)
 {
     return(IsTimeGateFinished(TechConstants.PvpTechTimeGameTier3Basic));
 }
Example #12
0
 public static bool IsAvailableT5Specialized(DropItemContext context)
 {
     return(IsTimeGateFinished(TechConstants.PvpTechTimeGameTier5Specialized));
 }
Example #13
0
 public static bool IsAvailableT3Basic(DropItemContext context)
 {
     return(IsTimeGateFinished(TechTier.Tier3, isSpecialized: false));
 }
Example #14
0
        protected override void ServerOnStaticObjectDestroyedByCharacter(
            ICharacter byCharacter,
            WeaponFinalCache weaponCache,
            IStaticWorldObject targetObject)
        {
            base.ServerOnStaticObjectDestroyedByCharacter(byCharacter, weaponCache, targetObject);

            // drop chance and gained experience depends on the vegetation growth stage
            var growthProgressFraction = this.SharedGetGrowthProgress(targetObject);

            growthProgressFraction = MathHelper.Clamp(growthProgressFraction, 0.1, 1);

            try
            {
                var dropItemsList   = this.DroplistOnDestroy;
                var dropItemContext = new DropItemContext(byCharacter,
                                                          targetObject,
                                                          weaponCache.ProtoWeapon,
                                                          weaponCache.ProtoExplosive);

                var objectDrone = weaponCache.Drone;
                if (objectDrone is not null)
                {
                    // drop resources into the internal storage of the drone
                    var storageItemsContainer = ((IProtoDrone)objectDrone.ProtoGameObject)
                                                .ServerGetStorageItemsContainer(objectDrone);
                    dropItemsList.TryDropToContainer(storageItemsContainer,
                                                     dropItemContext,
                                                     probabilityMultiplier: growthProgressFraction);
                }
                else if (weaponCache.ProtoWeapon is IProtoItemWeaponMelee)
                {
                    // a melee weapon - try drop items to character
                    var result = dropItemsList.TryDropToCharacterOrGround(
                        byCharacter,
                        targetObject.TilePosition,
                        dropItemContext,
                        groundContainer: out _,
                        probabilityMultiplier: growthProgressFraction);
                    if (result.TotalCreatedCount > 0)
                    {
                        NotificationSystem.ServerSendItemsNotification(byCharacter, result);
                    }
                }
                else
                {
                    // not a melee weapon or cannot drop to character - drop on the ground only
                    dropItemsList.TryDropToGround(
                        targetObject.TilePosition,
                        dropItemContext,
                        probabilityMultiplier: growthProgressFraction,
                        groundContainer: out _);
                }
            }
            finally
            {
                if (weaponCache.ProtoWeapon is IProtoItemToolWoodcutting)
                {
                    // add experience proportional to the vegetation structure points
                    // (effectively - for the time spent on woodcutting)
                    var exp = SkillLumbering.ExperienceAddPerStructurePoint;
                    exp *= this.StructurePointsMax * growthProgressFraction;
                    byCharacter?.ServerAddSkillExperience <SkillLumbering>(exp);
                }
            }
        }
        public bool ServerGather(IStaticWorldObject worldObject, ICharacter character)
        {
            var privateState = GetPrivateState(worldObject);

            if (privateState.IsDropListSpawned)
            {
                // this loot container was already search - drop list was already spawned
                return(true);
            }

            // spawn items accordingly to the droplist
            privateState.IsDropListSpawned = true;
            var skillExperienceToAdd = SkillSearching.ExperienceAddWhenSearching
                                       * this.SearchingSkillExperienceMultiplier;

            var lootDroplist    = this.ServerGetLootDroplist(worldObject);
            var dropItemContext = new DropItemContext(character, worldObject);

            CreateItemResult dropItemResult;

            if (this.IsAutoTakeAll)
            {
                // try to simply pickup the content
                dropItemResult = lootDroplist.TryDropToCharacter(character,
                                                                 dropItemContext,
                                                                 sendNoFreeSpaceNotification: false);
                if (dropItemResult.IsEverythingCreated &&
                    dropItemResult.TotalCreatedCount > 0)
                {
                    NotificationSystem.ServerSendItemsNotification(character, dropItemResult);
                    Server.World.DestroyObject(worldObject); // destroy object after success pickup
                    character.ServerAddSkillExperience <SkillSearching>(skillExperienceToAdd);
                    ServerLootEventHelper.OnLootReceived(character, worldObject);
                    return(true);
                }

                dropItemResult.Rollback();
            }

            // create a container and drop items there
            var attemptRemains = 100;
            var itemsContainer = privateState.ItemsContainer;

            do
            {
                dropItemResult = lootDroplist.TryDropToContainer(itemsContainer, dropItemContext);
            }
            // ensure that at least something is spawned...
            // perhaps that's not a good idea, but we have an attempts limit
            while (dropItemResult.TotalCreatedCount == 0 &&
                   --attemptRemains > 0);

            Server.Items.SetSlotsCount(itemsContainer, itemsContainer.OccupiedSlotsCount);

            character.ServerAddSkillExperience <SkillSearching>(skillExperienceToAdd);
            ServerLootEventHelper.OnLootReceived(character, worldObject);

            Server.World.EnterPrivateScope(character, worldObject);

            // register private scope exit on interaction cancel
            InteractionCheckerSystem.SharedRegister(
                character,
                worldObject,
                finishAction: isAbort =>
            {
                if (worldObject.IsDestroyed)
                {
                    return;
                }

                Server.World.ExitPrivateScope(character, worldObject);

                if (isAbort)
                {
                    // notify client
                    this.CallClient(character, _ => _.ClientRemote_FinishInteraction(worldObject));
                }

                if (this.IsAutoDestroyWhenLooted)
                {
                    // container was closed - destroy it
                    Server.World.DestroyObject(worldObject);
                }
            });

            Logger.Important($"Started object interaction with {worldObject} for {character}");
            this.CallClient(character, _ => _.ClientRemote_OnContainerOpened(worldObject));
            return(true);
        }
Example #16
0
        public bool ServerGather(IStaticWorldObject worldObject, ICharacter character)
        {
            var privateState = GetPrivateState(worldObject);

            if (privateState.IsDropListSpawned)
            {
                // this loot container was already search - drop list was already spawned
                return(true);
            }

            // spawn items accordingly to the droplist
            privateState.IsDropListSpawned = true;

            var lootDroplist    = this.ServerGetLootDroplist(worldObject);
            var dropItemContext = new DropItemContext(character, worldObject);
            CreateItemResult dropItemResult;
            var attemptRemains = 100;
            var itemsContainer = privateState.ItemsContainer;

            do
            {
                dropItemResult = lootDroplist.TryDropToContainer(itemsContainer, dropItemContext);
            }
            // ensure that at least something is spawned...
            // perhaps that's not a good idea, but we have an attempts limit
            while (dropItemResult.TotalCreatedCount == 0 &&
                   --attemptRemains > 0);

            Server.Items.SetSlotsCount(itemsContainer, (byte)itemsContainer.OccupiedSlotsCount);

            character.ServerAddSkillExperience <SkillSearching>(SkillSearching.ExperienceAddWhenSearching);

            Server.World.EnterPrivateScope(character, worldObject);

            // register private scope exit on interaction cancel
            InteractionCheckerSystem.SharedRegister(
                character,
                worldObject,
                finishAction: isAbort =>
            {
                if (worldObject.IsDestroyed)
                {
                    return;
                }

                Server.World.ExitPrivateScope(character, worldObject);

                if (isAbort)
                {
                    // notify client
                    this.CallClient(character, _ => _.ClientRemote_FinishInteraction(worldObject));
                }

                if (this.IsAutoDestroyWhenLooted)
                {
                    // container was closed - destroy it
                    Server.World.DestroyObject(worldObject);
                }
            });

            Logger.Important($"Started object interaction with {worldObject} for {character}");
            this.CallClient(character, _ => _.ClientRemote_OnContainerOpened(worldObject));
            return(true);
        }
Example #17
0
 public static bool IsAvailableT5Specialized(DropItemContext context)
 {
     return(IsTimeGateFinished(TechTier.Tier5, isSpecialized: true));
 }