private void ServerRemote_CreateUnstuckRequest()
        {
            var character = ServerRemoteContext.Character;

            if (serverRequests.ContainsKey(character))
            {
                this.CallClient(character, _ => _.ClientRemote_UnstuckAlreadyQueued());
                return;
            }

            if (character.GetPublicState <ICharacterPublicState>()
                .IsDead)
            {
                // character is dead
                this.CallClient(character, _ => _.ClientRemote_UnstuckFailedDead());
                return;
            }

            var vehicle = character.SharedGetCurrentVehicle();

            if (vehicle != null)
            {
                VehicleSystem.ServerCharacterExitCurrentVehicle(character, force: true);

                if (vehicle.GetPublicState <VehiclePublicState>().PilotCharacter != null)
                {
                    // cannot quit vehicle here, cannot unstuck
                    this.CallClient(character, _ => _.ClientRemote_UnstuckImpossible());
                    return;
                }
            }

            var delay = LandClaimSystem.SharedIsPositionInsideOwnedOrFreeArea(character.TilePosition,
                                                                              character)
                            ? UnstuckDelaySecondsTotal
                            : UnstuckDelaySecondsOnEnemyBaseTotal;

            var unstuckTime = Server.Game.FrameTime + delay;

            PlayerCharacter.GetPublicState(character).UnstuckExecutionTime = unstuckTime;

            serverRequests.Add(character,
                               new CharacterUnstuckRequest(
                                   unstuckAfter: unstuckTime,
                                   initialPosition: character.Position));
        }
        public static bool SharedValidateCanUnstuck(ICharacter character)
        {
            using var tempAreas = Api.Shared.GetTempList <ILogicObject>();
            var bounds = new RectangleInt(
                offset: character.TilePosition - (1, 1),
                size: (2, 2));

            LandClaimSystem.SharedGetAreasInBounds(bounds, tempAreas, addGracePadding: false);
            if (tempAreas.Any(LandClaimSystem.SharedIsAreaUnderRaid))
            {
                Logger.Info("Cannot unstuck when located in an area under raid", character);
                LandClaimSystem.SharedSendNotificationActionForbiddenUnderRaidblock(character);
                return(false);
            }

            return(true);
        }
        private static Vector2Ushort?TryFindZoneSpawnPosition(
            ICharacter character,
            IServerZone spawnZone,
            Random random,
            bool isRespawn)
        {
            var characterDeathPosition = Vector2Ushort.Zero;

            if (isRespawn && character.ProtoCharacter is PlayerCharacter)
            {
                characterDeathPosition = PlayerCharacter.GetPrivateState(character)
                                         .LastDeathPosition;
            }

            for (var attempt = 0; attempt < SpawnInZoneAttempts; attempt++)
            {
                var randomPosition = spawnZone.GetRandomPosition(random);

                if (isRespawn)
                {
                    var sqrDistance = randomPosition.TileSqrDistanceTo(characterDeathPosition);
                    if (sqrDistance > MaxDistanceWhenRespawnSqr ||
                        sqrDistance < MinDistanceWhenRespawnSqr)
                    {
                        // too close or too far for the respawn
                        continue;
                    }
                }

                if (LandClaimSystem.SharedGetAreaAtPosition(randomPosition) is ILogicObject area &&
                    !LandClaimSystem.ServerIsOwnedArea(area, character))
                {
                    // the land is claimed by another player
                    continue;
                }

                if (ServerCharacterSpawnHelper.IsPositionValidForCharacterSpawn(randomPosition.ToVector2D(),
                                                                                isPlayer: true))
                {
                    // valid position found
                    return(randomPosition);
                }
            }

            return(null);
        }
Beispiel #4
0
        protected virtual double ServerCalculateGrowthStageDuration(
            byte growthStage,
            TPrivateState privateState,
            TPublicState publicState)
        {
            var objectVegetation = privateState.GameObject;
            var duration         = this.cachedGrowthStageDurationSeconds;

            if (LandClaimSystem.SharedIsObjectInsideAnyArea((IStaticWorldObject)objectVegetation))
            {
                // don't apply scaled rate to vegetation located inside the land claim areas
                // (as these are usually planted by players inside their bases and protected)
                return(duration);
            }

            return(ServerSpawnRateScaleHelper.AdjustDurationByRate(duration));
        }
Beispiel #5
0
        private void ServerRemote_LeaderDissolveFaction()
        {
            var currentLeader     = ServerRemoteContext.Character;
            var currentLeaderName = currentLeader.Name;

            ServerValidateHasAccessRights(currentLeader,
                                          FactionMemberAccessRights.Leader,
                                          out var faction);

            if (LandClaimSystem.SharedEnumerateAllFactionAreas(SharedGetClanTag(faction))
                .Any())
            {
                throw new Exception("The faction cannot be dissolved as it still have land claims.");
            }

            Logger.Important("Faction leader dissolved the faction: " + faction, currentLeader);

            // remove all faction members have been removed
            var memberEntries = ServerGetFactionMembersReadOnly(faction);

            while (memberEntries.Count > 0)
            {
                var memberName = memberEntries[0].Name;
                ServerRemoveMemberNoChecks(memberName, faction);
                if (memberName == currentLeaderName)
                {
                    continue;
                }

                try
                {
                    var member = Server.Characters.GetPlayerCharacter(memberName);
                    if (member.ServerIsOnline)
                    {
                        this.CallClient(member,
                                        _ => _.ClientRemote_RemovedFromFaction(currentLeaderName));
                    }
                }
                catch (Exception ex)
                {
                    Logger.Exception(ex);
                }
            }

            ServerRemoveFaction(faction);
        }
Beispiel #6
0
        public IEnumerable <string> ServerGetLandOwners()
        {
            var area       = (ILogicObject)this.GameObject;
            var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(area);

            if (areasGroup is null)
            {
                // perhaps a new area
                return(this.DirectLandOwners);
            }

            var faction = LandClaimAreasGroup.GetPublicState(areasGroup).ServerFaction;

            return(faction is null
                       ? this.DirectLandOwners
                       : FactionSystem.ServerGetFactionMemberNames(faction));
        }
Beispiel #7
0
        public ObjectLandClaimCanUpgradeCheckResult ServerRemote_UpgradeStructure(
            IStaticWorldObject oldWorldObjectLandClaim,
            IProtoObjectLandClaim upgradeStructure)
        {
            this.VerifyGameObject(oldWorldObjectLandClaim);
            var character = ServerRemoteContext.Character;
            var result    = this.SharedCanUpgrade(oldWorldObjectLandClaim,
                                                  upgradeStructure,
                                                  character,
                                                  out var upgradeEntry);

            if (result != ObjectLandClaimCanUpgradeCheckResult.Success)
            {
                return(result);
            }

            // consume items
            upgradeEntry.ServerDestroyRequiredItems(character);

            // copy all items to temp container
            var oldStorage = GetPrivateState(oldWorldObjectLandClaim).ItemsContainer;

            var tempStorageOwner = Server.World.CreateLogicObject <LogicObjectTempItemsContainerHolder>();
            var tempStorage      = Server.Items.CreateContainer(
                owner: tempStorageOwner, // we must set an owner, unfortunately
                slotsCount: (byte)oldStorage.OccupiedSlotsCount);

            Server.Items.TryMoveAllItems(oldStorage, tempStorage);

            // upgrade (it will destroy an existing structure and place new in its place)
            var upgradedWorldObjectLandClaim = LandClaimSystem.ServerUpgrade(oldWorldObjectLandClaim,
                                                                             upgradeStructure,
                                                                             character);

            // move all items from temp container to the upgraded land claim
            var newStorage = GetPrivateState(upgradedWorldObjectLandClaim).ItemsContainer;

            Server.Items.TryMoveAllItems(tempStorage, newStorage);
            Server.Items.DestroyContainer(tempStorage);
            Server.World.DestroyObject(tempStorageOwner);

            // notify client (to play sound)
            ConstructionPlacementSystem.Instance.ServerOnStructurePlaced(upgradedWorldObjectLandClaim, character);

            return(result);
        }
Beispiel #8
0
        protected override void ServerOnStaticObjectZeroStructurePoints(
            WeaponFinalCache weaponCache,
            ICharacter byCharacter,
            IWorldObject targetObject)
        {
            var tilePosition = targetObject.TilePosition;

            base.ServerOnStaticObjectZeroStructurePoints(weaponCache, byCharacter, targetObject);

            if (weaponCache != null)
            {
                // wall was destroyed (and not deconstructed by a crowbar or any other means)
                ObjectWallDestroyed.ServerSpawnDestroyedWall(tilePosition, this);
                LandClaimSystem.ServerOnRaid(((IStaticWorldObject)targetObject).Bounds,
                                             byCharacter);
            }
        }
Beispiel #9
0
        protected override double ServerCalculateGrowthStageDuration(
            byte growthStage,
            VegetationPrivateState privateState,
            VegetationPublicState publicState)
        {
            var objectTree = (IStaticWorldObject)privateState.GameObject;
            var duration   = base.ServerCalculateGrowthStageDuration(growthStage, privateState, publicState);

            if (LandClaimSystem.SharedIsObjectInsideAnyArea(objectTree))
            {
                return(duration);
            }

            // x1.5 faster growth when not inside any land claim area as this resource
            // is rare and essential especially for PvP
            return(duration / 1.5);
        }
Beispiel #10
0
        private static bool IsBaseMusicShouldPlay(ICharacter character)
        {
            using var tempListAreasNearby           = Api.Shared.GetTempList <ILogicObject>();
            using var tempListOwnedAreaGroupsNearby = Api.Shared.GetTempList <ILogicObject>();
            LandClaimSystem.SharedGetAreasInBounds(
                new RectangleInt(character.TilePosition.X, character.TilePosition.Y, 1, 1).Inflate(2),
                tempListAreasNearby,
                addGracePadding: true);

            // find owned bases (area groups) nearby
            foreach (var area in tempListAreasNearby.AsList())
            {
                if (LandClaimSystem.SharedIsOwnedArea(area,
                                                      character,
                                                      requireFactionPermission: false))
                {
                    var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(area);
                    tempListOwnedAreaGroupsNearby.AddIfNotContains(areasGroup);
                }
            }

            if (tempListOwnedAreaGroupsNearby.Count == 0)
            {
                return(false);
            }

            var allAreas = (List <ILogicObject>)LandClaimSystem.SharedEnumerateAllAreas();

            // check every owned base whether it has at least single T2 or higher tier land claim
            foreach (var areasGroup in tempListOwnedAreaGroupsNearby.AsList())
            {
                foreach (var area in allAreas)
                {
                    var areaPublicState = LandClaimArea.GetPublicState(area);
                    if (areaPublicState.LandClaimAreasGroup == areasGroup &&
                        areaPublicState.LandClaimTier > 1)
                    {
                        // found an area on the base with land claim tier > 1
                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #11
0
        private static void ServerRefreshLandClaimAreasGroup(ILogicObject areasGroup)
        {
            var areas = LandClaimAreasGroup.GetPrivateState(areasGroup).ServerLandClaimsAreas;

            foreach (var area in areas)
            {
                var areaBounds = LandClaimSystem.SharedGetLandClaimAreaBounds(area, addGracePadding: true);
                var owners     = LandClaimArea.GetPrivateState(area).LandOwners;

                foreach (var owner in owners)
                {
                    var character = Server.Characters.GetPlayerCharacter(owner);
                    if (character == null ||
                        !character.ServerIsOnline)
                    {
                        continue;
                    }

                    if (!areaBounds.Contains(character.TilePosition))
                    {
                        continue;
                    }

                    // the land claim area contains an online owner character
                    ServerResetDecayTimer();
                    return;
                }
            }

            // helper method to reset the decay timer for all land claim buildings inside this areas group
            void ServerResetDecayTimer()
            {
                var decayDelayDuration = LandClaimSystem.ServerGetDecayDelayDurationForLandClaimAreas(areas);

                foreach (var area in areas)
                {
                    var worldObject = LandClaimArea.GetPrivateState(area)
                                      .ServerLandClaimWorldObject;

                    StructureDecaySystem.ServerResetDecayTimer(
                        worldObject.GetPrivateState <StructurePrivateState>(),
                        decayDelayDuration);
                }
            }
        }
Beispiel #12
0
        public ViewModelWindowLandClaim(
            IStaticWorldObject landClaimWorldObject,
            ILogicObject area)
        {
            this.landClaimWorldObject = landClaimWorldObject;

            this.privateState = LandClaimArea.GetPrivateState(area);

            var protoStructureWithOwnersList =
                ((IProtoObjectWithOwnersList)landClaimWorldObject.ProtoStaticWorldObject);
            var canEditOwners = protoStructureWithOwnersList
                                .SharedCanEditOwners(landClaimWorldObject, ClientCurrentCharacterHelper.Character);

            this.ViewModelOwnersEditor = new ViewModelWorldObjectOwnersEditor(
                this.privateState.LandOwners,
                callbackServerSetOwnersList: ownersList => LandClaimSystem.ClientSetAreaOwners(
                    area,
                    ownersList),
                title: AccessListTitle + ":",
                emptyListMessage: AccessListEmpty,
                canEditOwners: canEditOwners,
                // exclude founder name
                ownersListFilter: name => name != this.FounderName);

            this.protoObjectLandClaim =
                (IProtoObjectLandClaim)this.landClaimWorldObject.ProtoStaticWorldObject;

            var upgrade = this.protoObjectLandClaim.ConfigUpgrade.Entries.FirstOrDefault();

            if (upgrade != null)
            {
                this.ViewModelStructureUpgrade          = new ViewModelStructureUpgrade(upgrade);
                this.ViewModelProtoLandClaimInfoUpgrade = new ViewModelProtoLandClaimInfo(
                    (IProtoObjectLandClaim)upgrade.ProtoStructure);
            }

            this.ViewModelItemsContainerExchange = new ViewModelItemsContainerExchange(
                landClaimWorldObject.GetPrivateState <ObjectLandClaimPrivateState>().ItemsContainer,
                callbackTakeAllItemsSuccess: () => { })
            {
                IsContainerTitleVisible = false
            };

            this.ViewModelProtoLandClaimInfoCurrent = new ViewModelProtoLandClaimInfo(this.protoObjectLandClaim);
        }
Beispiel #13
0
        protected override double SharedCalculateDamageByWeapon(
            WeaponFinalCache weaponCache,
            double damagePreMultiplier,
            IStaticWorldObject targetObject,
            out double obstacleBlockDamageCoef)
        {
            if (IsServer)
            {
                damagePreMultiplier = LandClaimSystem.ServerAdjustDamageToUnprotectedStrongBuilding(weaponCache,
                                                                                                    targetObject,
                                                                                                    damagePreMultiplier);
            }

            return(base.SharedCalculateDamageByWeapon(weaponCache,
                                                      damagePreMultiplier,
                                                      targetObject,
                                                      out obstacleBlockDamageCoef));
        }
Beispiel #14
0
        public static void ClientLeaderDissolveFaction()
        {
            ClientValidateHasAccessRights(FactionMemberAccessRights.Leader);

            if (LandClaimSystem.ClientEnumerateAllCurrentFactionAreas()
                .Any())
            {
                NotificationSystem.ClientShowNotification(
                    title: null,
                    CoreStrings.Faction_DialogDissolveFaction_ErrorHasLandClaimsClaims,
                    NotificationColor.Bad);
                return;
            }

            Instance.CallServer(
                _ => _.ServerRemote_LeaderDissolveFaction());
            Logger.Important("Requested faction dissolve");
        }
Beispiel #15
0
        public override bool CanAddItem(CanAddItemContext context)
        {
            var character = context.ByCharacter;

            if (character is null)
            {
                return(true);
            }

            if (!LandClaimSystem.ValidateIsNotUnderRaidblock(context.Container.OwnerAsStaticObject,
                                                             character))
            {
                // don't allow to place anything in tinker table while the area is under raid
                return(false);
            }

            return(ItemDisassemblySystem.SharedCanDisassemble(context.Item.ProtoItem));
        }
        public static string ServerSetOwner(ushort x, ushort y, string newOwnerName)
        {
            using var tempList = Api.Shared.GetTempList <ILogicObject>();
            LandClaimSystem.SharedGetAreasInBounds(new RectangleInt(x, y, 1, 1), tempList, addGracePadding: false);

            var landClaimsModified = 0;

            foreach (var area in tempList.AsList())
            {
                var privateState = LandClaimArea.GetPrivateState(area);
                privateState.LandClaimFounder = newOwnerName;
                privateState.LandOwners.Clear();
                privateState.LandOwners.Add(newOwnerName);
                landClaimsModified++;
            }

            return($"Modified {landClaimsModified} land claims");
        }
Beispiel #17
0
        private SetOwnersResult ServerRemote_SetOwners(IWorldObject worldObject, List <string> newOwners)
        {
            var maxOwners = worldObject.ProtoGameObject is IProtoObjectDoor
                                ? RateDoorOwnersMax.SharedValue
                                : byte.MaxValue;

            if (newOwners.Count > maxOwners)
            {
                return(SetOwnersResult.ErrorAccessListSizeLimitExceeded);
            }

            var character = ServerRemoteContext.Character;

            if (worldObject is IStaticWorldObject staticWorldObject)
            {
                if (!staticWorldObject.ProtoStaticWorldObject
                    .SharedCanInteract(character, worldObject, writeToLog: true))
                {
                    throw new Exception("Cannot interact with " + worldObject);
                }

                if (!SharedIsOwner(character, worldObject))
                {
                    throw new Exception("Not an owner");
                }

                var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(staticWorldObject);
                if (areasGroup is not null &&
                    LandClaimAreasGroup.GetPublicState(areasGroup).ServerFaction is not null)
                {
                    throw new Exception(
                              "Cannot modify owners list for an object within a faction land claim area");
                }
            }
            else // dynamic world object (a vehicle, etc)
            {
                if (!worldObject.ProtoWorldObject.SharedCanInteract(character, worldObject, writeToLog: false))
                {
                    throw new Exception("Cannot interact with " + worldObject);
                }
            }

            return(ServerSetOwners(worldObject, newOwners, byOwner: character));
        }
        public string Execute(
            ShieldProtectionStatus status,
            [CurrentCharacterIfNull] ICharacter character = null)
        {
            if (!LandClaimShieldProtectionConstants.SharedIsEnabled)
            {
                return("S.H.I.E.L.D. protection is not available");
            }

            if (status == ShieldProtectionStatus.Active)
            {
                status = ShieldProtectionStatus.Activating;
            }

            using var tempAreas = Api.Shared.GetTempList <ILogicObject>();
            LandClaimSystem.SharedGetAreasInBounds(
                new RectangleInt(character.TilePosition, (1, 1)),
                tempAreas,
                addGracePadding: false);

            var area = tempAreas.AsList().FirstOrDefault();

            if (area is null)
            {
                return("No base exist near " + character.Name);
            }

            var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(area);

            LandClaimShieldProtectionSystem.SharedGetShieldProtectionMaxStatsForBase(areasGroup,
                                                                                     out _,
                                                                                     out _);

            var privateState = LandClaimAreasGroup.GetPrivateState(areasGroup);

            privateState.ShieldProtectionCooldownExpirationTime = 0;

            var publicState = LandClaimAreasGroup.GetPublicState(areasGroup);

            publicState.Status = status;
            publicState.ShieldActivationTime = Server.Game.FrameTime;

            return($"Status of the S.H.I.E.L.D. changed to {status}.");
        }
        public string Execute([CurrentCharacterIfNull] ICharacter character)
        {
            using var tempAreas = Api.Shared.GetTempList <ILogicObject>();

            LandClaimSystem.SharedGetAreasInBounds(
                new RectangleInt(character.TilePosition.X, character.TilePosition.Y, 1, 1),
                tempAreas,
                addGracePadding: false);

            foreach (var logicObject in tempAreas.AsList())
            {
                LandClaimSystem.ServerSetRaidblock(logicObject,
                                                   byCharacter: null,
                                                   durationMultiplier: 1.0,
                                                   isStructureDestroyed: true);
            }

            return(string.Empty);
        }
        private static void SetupBoundsForLandClaimsInScope(
            IClientSceneObject sceneObject,
            Vector2D sceneObjectPosition,
            Vector2Ushort originTilePosition,
            RectangleInt originBounds,
            IProtoObjectLandClaim originProtoObjectLandClaim)
        {
            var landClaims = Api.Client.World.GetStaticWorldObjectsOfProto <IProtoObjectLandClaim>();

            foreach (var landClaim in landClaims)
            {
                var protoObjectLandClaim    = (IProtoObjectLandClaim)landClaim.ProtoGameObject;
                var landClaimCenterPosition = LandClaimSystem
                                              .SharedCalculateLandClaimObjectCenterTilePosition(
                    landClaim.TilePosition,
                    protoObjectLandClaim);

                var landClaimBounds = LandClaimSystem.SharedCalculateLandClaimAreaBounds(
                    landClaimCenterPosition,
                    protoObjectLandClaim.LandClaimWithGraceAreaSize);

                var intersectionDepth = CalculateIntersectionDepth(originBounds, landClaimBounds);
                if (intersectionDepth < 0)
                {
                    // no intersection
                    continue;
                }

                intersectionDepth = (intersectionDepth + 1) / 2;
                intersectionDepth = Math.Min(intersectionDepth,
                                             originProtoObjectLandClaim.LandClaimGraceAreaPaddingSizeOneDirection + 1);

                var exceptBounds = originBounds.Inflate(-intersectionDepth);
                using var tempList = Api.Shared.WrapObjectInTempList(exceptBounds);

                AddBoundLabels(sceneObject,
                               sceneObjectPosition,
                               exceptBounds: tempList.AsList(),
                               protoObjectLandClaim,
                               positionOffset: landClaimCenterPosition.ToVector2D()
                               - originTilePosition.ToVector2D());
            }
        }
Beispiel #21
0
        private static bool ServerIsNeedDespawn(ICharacter character, double serverTime)
        {
            var privateState = character.GetPrivateState <PlayerCharacterPrivateState>();

            if (character.ServerIsOnline)
            {
                return(false);
            }

            // player offline
            var publicState = character.GetPublicState <PlayerCharacterPublicState>();

            if (publicState.IsDead ||
                privateState.IsDespawned)
            {
                return(false);
            }

            if (character.ProtoCharacter is PlayerCharacterSpectator ||
                Server.Characters.IsSpectator(character))
            {
                return(false);
            }

            var offlineSinceTime = privateState.ServerLastActiveTime;

            if (serverTime < offlineSinceTime + OfflineDurationToDespawn)
            {
                // despawn timeout is not reached yet
                return(false);
            }

            if (LandClaimSystem.SharedIsOwnedLand(character.TilePosition,
                                                  character,
                                                  requireFactionPermission: false,
                                                  out _))
            {
                // do not despawn as the player is inside the owned land claim area
                return(false);
            }

            return(true);
        }
        private async void RequestDecayInfoTextAsync()
        {
            var result = await LandClaimSystem.ClientGetDecayInfoText(this.landClaimWorldObject);

            if (this.IsDisposed)
            {
                return;
            }

            this.DecayInfoText = string.Format(
                DecayInfoFormat,
                ClientTimeFormatHelper.FormatTimeDuration(
                    TimeSpan.FromSeconds(result.DecayDelayDuration),
                    trimRemainder: true),
                ClientTimeFormatHelper.FormatTimeDuration(
                    TimeSpan.FromSeconds(result.DecayDuration),
                    trimRemainder: true),
                this.ViewModelProtoLandClaimInfoCurrent.CurrentStructureLandClaimDestructionTimeout);
        }
        private void ServerExplode(IStaticWorldObject worldObject, ICharacter character)
        {
            Logger.Important(worldObject + " exploded");

            this.ServerSendObjectDestroyedEvent(worldObject);

            ExplosionHelper.ServerExplode(
                character: character,
                protoObjectExplosive: this,
                explosionPreset: this.ExplosionPreset,
                epicenterPosition: worldObject.TilePosition.ToVector2D() + this.Layout.Center,
                damageDescriptionCharacters: this.damageDescriptionCharacters,
                physicsSpace: worldObject.PhysicsBody.PhysicsSpace,
                executeExplosionCallback: this.ServerExecuteExplosion);

            Server.World.DestroyObject(worldObject);

            LandClaimSystem.ServerOnRaid(worldObject.TilePosition, this.DamageRadius, character);
        }
Beispiel #24
0
        public override bool CanAddItem(CanAddItemContext context)
        {
            var character = context.ByCharacter;

            if (character is null)
            {
                return(true);
            }

            if (!LandClaimSystem.ValidateIsNotUnderRaidblock(context.Container.OwnerAsStaticObject,
                                                             character))
            {
                // don't allow to place anything in a trash can while the area is under raid
                return(false);
            }

            // allow everything
            return(true);
        }
Beispiel #25
0
        private static bool ServerCheckCanSpawn(IProtoWorldObject protoObjectToSpawn, Vector2Ushort spawnPosition)
        {
            return(protoObjectToSpawn switch
            {
                IProtoCharacterMob
                => ServerCharacterSpawnHelper.IsPositionValidForCharacterSpawn(
                    spawnPosition.ToVector2D(),
                    isPlayer: false) &&
                !LandClaimSystem.SharedIsLandClaimedByAnyone(spawnPosition),

                IProtoStaticWorldObject protoStaticWorldObject
                // Please note: land claim check must be integrated in the object tile requirements
                => protoStaticWorldObject.CheckTileRequirements(
                    spawnPosition,
                    character: null,
                    logErrors: false),

                _ => throw new ArgumentOutOfRangeException("Unknown object type to spawn: " + protoObjectToSpawn)
            });
Beispiel #26
0
        private static bool IsOwner(ILogicObject areasGroup)
        {
            if (areasGroup.ClientHasPrivateState)
            {
                return(true);
            }

            var areas = LandClaimSystem.ClientGetKnownAreasForGroup(areasGroup);

            foreach (var area in areas)
            {
                if (LandClaimSystem.ClientIsOwnedArea(area))
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #27
0
 private static void ServerUpdate()
 {
     ServerNotifiedCharactersForAreasGroups.ProcessAndRemove(
         removeCondition: key =>
     {
         // determine whether the raid has ended
         var areasGroup = key.AreasGroup;
         return(areasGroup.IsDestroyed ||
                !LandClaimSystem.SharedIsAreasGroupUnderRaid(areasGroup));
     },
         removeCallback: pair =>
     {
         // notify all the previously notified players
         var previouslyNotifiedCharacters = pair.Value;
         Instance.CallClient(previouslyNotifiedCharacters,
                             _ => _.ClientRemote_AllyBaseRaidEnded(
                                 pair.Key.AreasGroup.Id));
     });
 }
        public static async void ClientTakeVehicle(uint vehicleGameObjectId)
        {
            var vehicleAssemblyBay = InteractionCheckerSystem.SharedGetCurrentInteraction(
                ClientCurrentCharacterHelper.Character);

            var result = await Instance.CallServer(_ => _.ServerRemote_TakeVehicle(vehicleGameObjectId));

            if (result == TakeVehicleResult.Success)
            {
                Client.Audio.PlayOneShot(SoundResourceTakeVehicle, vehicleAssemblyBay);
                WindowObjectVehicleAssemblyBay.CloseActiveMenu();
                return;
            }

            if (result == TakeVehicleResult.BaseUnderRaidblock)
            {
                LandClaimSystem.SharedSendNotificationActionForbiddenUnderRaidblock(
                    ClientCurrentCharacterHelper.Character);
                return;
            }

            var error = result.GetDescription();

            if (string.IsNullOrEmpty(error))
            {
                return;
            }

            var currentInteractionObject =
                InteractionCheckerSystem.SharedGetCurrentInteraction(ClientCurrentCharacterHelper.Character);

            if (!(currentInteractionObject?.ProtoWorldObject is IProtoVehicleAssemblyBay protoVehicleAssemblyBay))
            {
                return;
            }

            NotificationSystem.ClientShowNotification(
                Notification_CannotTakeVehicle_Title,
                error,
                NotificationColor.Bad,
                protoVehicleAssemblyBay.Icon);
        }
        private static void Refresh()
        {
            var position   = ClientCurrentCharacterHelper.Character?.TilePosition ?? Vector2Ushort.Zero;
            var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(position, addGracePadding: false)
                             ?? LandClaimSystem.SharedGetLandClaimAreasGroup(position, addGracePadding: true);

            var lastRaidTime = areasGroup is not null
                                   ? LandClaimAreasGroup.GetPublicState(areasGroup).LastRaidTime ?? double.MinValue
                                   : double.MinValue;

            var time = Api.Client.CurrentGame.ServerFrameTimeRounded;
            var timeSinceRaidStart   = time - lastRaidTime;
            var timeRemainsToRaidEnd = LandClaimSystemConstants.SharedRaidBlockDurationSeconds - timeSinceRaidStart;

            timeRemainsToRaidEnd = Math.Max(timeRemainsToRaidEnd, 0);

            if (timeRemainsToRaidEnd <= 0)
            {
                // no raid here - hide notification
                currentNotification?.Hide(quick: true);
                currentNotification = null;
                return;
            }

            // raid here, display/update notification
            var text = GetNotificationText(timeRemainsToRaidEnd);

            if (currentNotification is not null &&
                !currentNotification.IsHiding)
            {
                currentNotification.Message = text;
                return;
            }

            currentNotification = NotificationSystem.ClientShowNotification(
                title: Notification_Title,
                message: text,
                autoHide: false,
                // TODO: add custom icon here, currently we're using a placeholder icon
                icon: Api.GetProtoEntity <ItemBombModern>().Icon,
                playSound: false);
        }
Beispiel #30
0
        public static bool SharedIsOwner(ICharacter who, IWorldObject worldObject, out bool isFactionAccess)
        {
            isFactionAccess = false;

            switch (worldObject)
            {
            case IStaticWorldObject staticWorldObject:
            {
                var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(staticWorldObject);
                if (areasGroup is null ||
                    LandClaimAreasGroup.GetPublicState(areasGroup).FactionClanTag is not {
                    } clanTag ||
                    string.IsNullOrEmpty(clanTag))
                {
                    break;
                }

                // the static object is inside the faction-owned land claim,
                // verify permission
                isFactionAccess = true;
                return(SharedHasFactionAccessRights(who,
                                                    FactionMemberAccessRights.LandClaimManagement,
                                                    clanTag));
            }

            case IDynamicWorldObject when worldObject.ProtoGameObject is IProtoVehicle:
            {
                var clanTag = worldObject.GetPublicState <VehiclePublicState>().ClanTag;
                if (string.IsNullOrEmpty(clanTag))
                {
                    break;
                }

                // the vehicle is owned by faction
                // verify whether the character has the access right
                isFactionAccess = true;
                return(WorldObjectAccessModeSystem.SharedHasAccess(who, worldObject, writeToLog: true));
            }
            }

            return(SharedGetDirectOwners(worldObject).Contains(who.Name));
        }