Esempio n. 1
0
        public ITextureResource GetTexture(Vector2Ushort tilePosition, out DrawMode drawMode)
        {
            var textureIndex = PositionalRandom.Get(
                tilePosition,
                minInclusive: 0,
                maxExclusive: this.TextureResources.Count,
                seed: 792396596);

            if (this.CanFlipHorizontally)
            {
                drawMode = PositionalRandom.Get(
                    tilePosition,
                    minInclusive: 0,
                    maxExclusive: 2,
                    seed: 628275376)
                           == 0
                               ? DrawMode.FlipHorizontally
                               : DrawMode.Default;
            }
            else
            {
                drawMode = DrawMode.Default;
            }

            return(this.TextureResources[textureIndex]);
        }
Esempio n. 2
0
        protected override void ClientInitialize(ClientInitializeData data)
        {
            base.ClientInitialize(data);

            var gameObject  = data.GameObject;
            var clientState = data.ClientState;
            var publicState = data.PublicState;

            clientState.LastGrowthStage = publicState.GrowthStage;

            var spriteRenderer = clientState.Renderer;

            spriteRenderer.TextureResource = SystemVegetation.ClientGetTexture(
                this,
                gameObject,
                publicState);

            clientState.Renderer = spriteRenderer;

            // flip renderer with some deterministic randomization
            if (this.CanFlipSprite &&
                PositionalRandom.Get(gameObject.TilePosition, 0, 3, seed: 721886451) == 0)
            {
                spriteRenderer.DrawMode = DrawMode.FlipHorizontally;
            }

            if (this.IsAutoAddShadow)
            {
                this.ClientAddShadowRenderer(data);
            }
        }
        public static void Setup(
            IComponentSpriteRenderer renderer,
            float power,
            float pivotY,
            bool canFlip = true)
        {
            var worldObject = renderer.SceneObject.AttachedWorldObject;

            if (worldObject == null)
            {
                // blueprint - use default rendering
                return;
            }

            var isRenderingFlipped = canFlip &&
                                     PositionalRandom.Get(worldObject.TilePosition, 0, 3, seed: 9125835) == 0;

            var phaseOffset = (byte)PositionalRandom.Get(worldObject.TilePosition, 0, 8, seed: 614392664);

            var preset = new GrassAnimationPreset(power, pivotY, phaseOffset, isRenderingFlipped);

            if (!Materials.TryGetValue(preset, out var material))
            {
                // no cached material found for the required preset - create and setup new material
                Materials[preset] = material = RenderingMaterial.Create(EffectResource);
                material.EffectParameters
                .Set("Flip", isRenderingFlipped ? 1 : 0)
                .Set("Power", power)
                .Set("PivotY", pivotY)
                .Set("PhaseOffset", phaseOffset);
            }

            renderer.RenderingMaterial = material;
        }
Esempio n. 4
0
 public static bool IsGroundSpriteFlipped(Vector2Ushort tilePosition)
 {
     return(PositionalRandom.Get(tilePosition,
                                 minInclusive: 0,
                                 maxExclusive: 2,
                                 seed: 218936133)
            == 0);
 }
 protected override ITextureResource ClientGetTextureResource(
     IStaticWorldObject gameObject,
     StaticObjectPublicState publicState)
 {
     return(this.textures[PositionalRandom.Get(gameObject.TilePosition,
                                               minInclusive: 0,
                                               maxExclusive: this.textures.Length,
                                               seed: 791838756)]);
 }
Esempio n. 6
0
        // calculate a random tree scale depending on the tree position and seed
        private double SharedGetVisualScaleCoef(IStaticWorldObject worldObject)
        {
            const int maxDifferencePercents = 30;

            return(PositionalRandom.Get(worldObject.TilePosition,
                                        minInclusive: 100 - maxDifferencePercents / 2,
                                        maxExclusive: 100 + maxDifferencePercents / 2,
                                        seed: (uint)(worldObject.Id + this.ShortId.GetHashCode()))
                   / 100.0);
        }
Esempio n. 7
0
        protected override void ClientInitialize(ClientInitializeData data)
        {
            base.ClientInitialize(data);

            // flip renderer with some deterministic randomization
            if (this.CanFlipSprite &&
                PositionalRandom.Get(data.GameObject.TilePosition, 0, 2, seed: 9125835) == 0)
            {
                data.ClientState.Renderer.DrawMode = DrawMode.FlipHorizontally;
            }
        }
Esempio n. 8
0
        protected virtual ITextureResource ClientGetTextureResource(
            IStaticWorldObject gameObject,
            TPublicState publicState)
        {
            var damageStage = this.SharedCalculateDamageStage(publicState.StructurePointsCurrent);
            // select deterministically which sprites row in the atlas to use
            // (each row - different look for the same mineral)
            var rowIndex = (byte)PositionalRandom.Get(gameObject.TilePosition,
                                                      minInclusive: 0,
                                                      maxExclusive: this.TextureVariantsCount,
                                                      seed: 691237523);

            return(this.textureAtlasResource.Chunk(damageStage, rowIndex));
        }
Esempio n. 9
0
        public override byte ClientGetTextureAtlasColumn(
            IStaticWorldObject worldObject,
            VegetationPublicState publicState)
        {
            var growthStage = publicState.GrowthStage;

            if (growthStage == this.GrowthStagesCount)
            {
                // full grown - select one of two variants based on position
                return((byte)(growthStage
                              + PositionalRandom.Get(worldObject.TilePosition, 0, 2, seed: 90139875u)));
            }

            return(growthStage);
        }
Esempio n. 10
0
        protected virtual void ClientApplyTreeRandomScale(
            IStaticWorldObject worldObject,
            IComponentSpriteRenderer renderer)
        {
            // if this is not a blueprint, apply random scale (depending on the tree position and seed)
            const int maxDifferencePercents = 30;

            var scaleCoef = PositionalRandom.Get(worldObject.TilePosition,
                                                 minInclusive: 100 - maxDifferencePercents / 2,
                                                 maxExclusive: 100 + maxDifferencePercents / 2,
                                                 seed: (uint)(worldObject.Id + this.ShortId.GetHashCode()))
                            / 100.0;

            renderer.Scale            *= scaleCoef;
            renderer.DrawOrderOffsetY *= scaleCoef;
        }
Esempio n. 11
0
        protected override void ClientSetupRenderer(IComponentSpriteRenderer renderer)
        {
            renderer.PositionOffset   = (0.5, 0.0);
            renderer.SpritePivotPoint = (0.5, 0);
            renderer.DrawOrderOffsetY = 0.38;
            renderer.Scale            = 1.3;

            // making the grass choose random element of the atlas depending on world position
            var position   = renderer.SceneObject.Position.ToVector2Ushort();
            var atlasChunk = (byte)PositionalRandom.Get(position, 0, 4, seed: 12345);

            renderer.TextureResource = textureAtlas.Chunk(atlasChunk, 0);

            ClientGrassRenderingHelper.Setup(renderer,
                                             power: 0.1f,
                                             pivotY: 0.2f);
        }
Esempio n. 12
0
        protected override void ClientInitialize(ClientInitializeData data)
        {
            base.ClientInitialize(data);

            // hacking progress display
            Api.Client.UI.AttachControl(
                data.GameObject,
                new ObjectHackingProgressDisplayControl(data.PublicState),
                positionOffset: this.SharedGetObjectCenterWorldOffset(data.GameObject) + (0, 1.35),
                isFocusable: false);

            // flip renderer with some deterministic randomization
            if (this.CanFlipSprite &&
                PositionalRandom.Get(data.GameObject.TilePosition, 0, 2, seed: 9125835) == 0)
            {
                data.ClientState.Renderer.DrawMode = DrawMode.FlipHorizontally;
            }
        }
Esempio n. 13
0
        protected override void ClientSetupRenderer(IComponentSpriteRenderer renderer)
        {
            base.ClientSetupRenderer(renderer);
            renderer.DrawOrderOffsetY = 0.5;

            var worldObject = renderer.SceneObject.AttachedWorldObject;

            if (worldObject == null)
            {
                return;
            }

            // flip renderer with some deterministic randomization
            if (PositionalRandom.Get(worldObject.TilePosition, 0, 2, seed: 925309274) == 0)
            {
                renderer.DrawMode = DrawMode.FlipHorizontally;
            }
        }
Esempio n. 14
0
        protected override void ClientInitialize(ClientInitializeData data)
        {
            // don't use base implementation
            //base.ClientInitialize(data);

            var renderer = Client.Rendering.CreateSpriteRenderer(
                data.GameObject,
                textureResource: this.DefaultTexture);

            data.ClientState.Renderer = renderer;

            // flip renderer with some deterministic randomization
            if (this.CanFlipSprite &&
                PositionalRandom.Get(data.GameObject.TilePosition, 0, 3, seed: 721886451) == 0)
            {
                renderer.DrawMode = DrawMode.FlipHorizontally;
            }

            this.ClientSetupRenderer(renderer);
        }
Esempio n. 15
0
        public string Execute()
        {
            var world             = Server.World;
            var changesDone       = 0;
            var tempCheckQueue    = new Queue <Tile>();
            var tempNeighborTiles = new HashSet <Tile>();

            Process(world.GetStaticWorldObjectsOfProto <ObjectPropRoadHorizontal>(),
                    protoBroken1: Api.GetProtoEntity <ObjectPropRoadHorizontal2>(),
                    protoBroken2: Api.GetProtoEntity <ObjectPropRoadHorizontal3>(),
                    protoBroken3: Api.GetProtoEntity <ObjectPropRoadHorizontal4>(),
                    seed: 696159212);

            Process(world.GetStaticWorldObjectsOfProto <ObjectPropRoadVertical>(),
                    protoBroken1: Api.GetProtoEntity <ObjectPropRoadVertical2>(),
                    protoBroken2: Api.GetProtoEntity <ObjectPropRoadVertical3>(),
                    protoBroken3: Api.GetProtoEntity <ObjectPropRoadVertical4>(),
                    seed: 918246523);

            return($"Replaced {changesDone} roads");

            void Process(
                IEnumerable <IStaticWorldObject> enumerationAllRoads,
                IProtoStaticWorldObject protoBroken1,
                IProtoStaticWorldObject protoBroken2,
                IProtoStaticWorldObject protoBroken3,
                uint seed)
            {
                var listAllRoads = enumerationAllRoads.ToList();

                listAllRoads.Shuffle();

                foreach (var worldObject in listAllRoads)
                {
                    switch (PositionalRandom.Get(worldObject.TilePosition,
                                                 minInclusive: 0,
                                                 maxExclusive: 16,
                                                 seed))
                    {
                    // normal road
                    default:
                        continue;

                    // a little damaged road
                    case 10:
                    case 11:
                    case 12:
                        TryReplace(worldObject, protoBroken1);
                        continue;

                    // damaged road
                    case 13:
                    case 14:
                        TryReplace(worldObject, protoBroken2);
                        continue;

                    // severe damaged road
                    case 15:
                        TryReplace(worldObject, protoBroken3);
                        continue;
                    }
                }

                // helper method to replace the object
                void TryReplace(IStaticWorldObject worldObject, IProtoStaticWorldObject replacementProto)
                {
                    tempCheckQueue.Clear();
                    tempNeighborTiles.Clear();
                    foreach (var tile in worldObject.OccupiedTiles)
                    {
                        tempCheckQueue.Enqueue(tile);
                    }

                    CollectNeighborTilesRecursive(tempCheckQueue, tempNeighborTiles, depthRemains: 12);

                    foreach (var neighborTile in tempNeighborTiles)
                    {
                        foreach (var neighborTileStaticObject in neighborTile.StaticObjects)
                        {
                            if (neighborTileStaticObject.ProtoStaticWorldObject == replacementProto)
                            {
                                // found same proto type in a neighbor tile, don't allow replacement
                                return;
                            }
                        }
                    }

                    world.DestroyObject(worldObject);
                    world.CreateStaticWorldObject(replacementProto, worldObject.TilePosition);
                    changesDone++;
                }
            }
        }
Esempio n. 16
0
        public string Execute()
        {
            var world             = Server.World;
            var changesDone       = 0;
            var tempCheckQueue    = new Queue <Tile>();
            var tempNeighborTiles = new HashSet <Tile>();

            Process(world.GetStaticWorldObjectsOfProto <ObjectPropRuinsWallHorizontal01>(),
                    protoBroken1: Api.GetProtoEntity <ObjectPropRuinsWallHorizontal02>(),
                    protoBroken2: Api.GetProtoEntity <ObjectPropRuinsWallHorizontal03>(),
                    protoBroken3: Api.GetProtoEntity <ObjectPropRuinsWallHorizontal04>(),
                    seed: 823731251,
                    defaultVariantRateIncrease: 4);

            Process(world.GetStaticWorldObjectsOfProto <ObjectPropRuinsWallVertical01>(),
                    protoBroken1: Api.GetProtoEntity <ObjectPropRuinsWallVertical01>(),
                    protoBroken2: Api.GetProtoEntity <ObjectPropRuinsWallVertical02>(),
                    protoBroken3: Api.GetProtoEntity <ObjectPropRuinsWallVertical02>(),
                    seed: 155436192,
                    defaultVariantRateIncrease: 2);

            return($"Replaced {changesDone} walls");

            void Process(
                IEnumerable <IStaticWorldObject> enumerationAllObjects,
                IProtoStaticWorldObject protoBroken1,
                IProtoStaticWorldObject protoBroken2,
                IProtoStaticWorldObject protoBroken3,
                uint seed,
                byte defaultVariantRateIncrease)
            {
                var listAllObjects = enumerationAllObjects.ToList();

                listAllObjects.Shuffle();

                foreach (var worldObject in listAllObjects)
                {
                    bool isOk;
                    var  attempt = 0;

                    do
                    {
                        var randomNumber = PositionalRandom.Get(worldObject.TilePosition,
                                                                minInclusive: 0,
                                                                maxExclusive: 4 + defaultVariantRateIncrease,
                                                                seed);
                        isOk = randomNumber switch
                        {
                            0 => TryReplace(worldObject, protoBroken1),
                            1 => TryReplace(worldObject, protoBroken2),
                            2 => TryReplace(worldObject, protoBroken3),
                            _ => true
                        };
                    }while (!isOk &&
                            ++attempt < 8);
                }

                // helper method to replace the object
                bool TryReplace(IStaticWorldObject worldObject, IProtoStaticWorldObject replacementProto)
                {
                    if (ReferenceEquals(worldObject.ProtoGameObject, replacementProto))
                    {
                        // no replacement necessary
                        return(true);
                    }

                    tempCheckQueue.Clear();
                    tempNeighborTiles.Clear();
                    foreach (var tile in worldObject.OccupiedTiles)
                    {
                        tempCheckQueue.Enqueue(tile);
                    }

                    CollectNeighborTilesRecursive(tempCheckQueue,
                                                  tempNeighborTiles,
                                                  // will process only up to 4 neighbors
                                                  // by distance from the occupied tiles
                                                  depthRemains: 5);

                    foreach (var neighborTile in tempNeighborTiles)
                    {
                        foreach (var neighborTileStaticObject in neighborTile.StaticObjects)
                        {
                            if (ReferenceEquals(neighborTileStaticObject.ProtoStaticWorldObject,
                                                replacementProto))
                            {
                                // found the same proto type in a neighbor tile, don't allow replacement
                                return(false);
                            }
                        }
                    }

                    world.DestroyObject(worldObject);
                    world.CreateStaticWorldObject(replacementProto, worldObject.TilePosition);
                    changesDone++;
                    return(true);
                }
            }
        }
Esempio n. 17
0
 private static bool SharedIsAlternativeVariant(Vector2Ushort tilePosition)
 {
     return(PositionalRandom.Get(tilePosition, 0, 2, seed: 9125835) == 0);
 }
Esempio n. 18
0
        public static void ClientExplode(
            Vector2D position,
            ExplosionPreset explosionPreset,
            float volume = 1.0f)
        {
            // add screen shakes
            ClientComponentCameraScreenShakes.AddRandomShakes(
                duration: explosionPreset.ScreenShakesDuration,
                worldDistanceMin: explosionPreset.ScreenShakesWorldDistanceMin,
                worldDistanceMax: explosionPreset.ScreenShakesWorldDistanceMax);

            // play sound
            var explosionSoundEmitter = Client.Audio.PlayOneShot(explosionPreset.SoundSet.GetSound(),
                                                                 worldPosition: position,
                                                                 volume: volume,
                                                                 pitch: RandomHelper.Range(0.95f, 1.05f));

            // extend explosion sound distance
            explosionSoundEmitter.CustomMinDistance = (float)explosionPreset.LightWorldSize / 3;
            explosionSoundEmitter.CustomMaxDistance = (float)explosionPreset.LightWorldSize;

            // create explosion renderer
            var explosionSpriteAnimationDuration = explosionPreset.SpriteAnimationDuration;
            var explosionSceneObject             = Client.Scene.CreateSceneObject("Temp explosion",
                                                                                  position);

            explosionSceneObject.Destroy(delay: explosionSpriteAnimationDuration);

            var explosionSpriteRenderer = Client.Rendering.CreateSpriteRenderer(
                explosionSceneObject,
                TextureResource.NoTexture,
                drawOrder: DrawOrder.Explosion,
                spritePivotPoint: (0.5, 0.5));

            explosionSpriteRenderer.Color = explosionPreset.SpriteColorMultiplicative;
            explosionSpriteRenderer.Size  = explosionPreset.SpriteSize;
            if (explosionPreset.SpriteColorAdditive.HasValue
                // ReSharper disable once CompareOfFloatsByEqualityOperator
                || explosionPreset.SpriteBrightness != 1)
            {
                var renderingMaterial = RenderingMaterial.Create(EffectResourceAdditiveColorEffect);
                renderingMaterial.EffectParameters
                .Set("ColorAdditive", explosionPreset.SpriteColorAdditive ?? Colors.Black)
                .Set("Brightness", explosionPreset.SpriteBrightness);
                explosionSpriteRenderer.RenderingMaterial = renderingMaterial;
            }

            var isFlipped = 0
                            == PositionalRandom.Get(position.ToVector2Ushort(),
                                                    minInclusive: 0,
                                                    maxExclusive: 2,
                                                    seed: 893243289);

            if (isFlipped)
            {
                explosionSpriteRenderer.DrawMode = DrawMode.FlipHorizontally;
            }

            ClientComponentOneShotSpriteSheetAnimationHelper.Setup(
                explosionSpriteRenderer,
                explosionPreset.SpriteAtlasResources.TakeByRandom(),
                explosionSpriteAnimationDuration);

            // add light source for the explosion
            var explosionLight = ClientLighting.CreateLightSourceSpot(
                explosionSceneObject,
                explosionPreset.LightColor,
                size: explosionPreset.LightWorldSize,
                positionOffset: (0, 0),
                spritePivotPoint: (0.5, 0.5));

            ClientComponentOneShotLightAnimation.Setup(
                explosionLight,
                explosionPreset.LightDuration);

            // add blast wave
            var blastAnimationDuration = explosionPreset.BlastwaveAnimationDuration;

            if (blastAnimationDuration > 0)
            {
                ClientTimersSystem.AddAction(
                    explosionPreset.BlastwaveDelay,
                    () =>
                {
                    var blastSceneObject = Client.Scene.CreateSceneObject("Temp explosion",
                                                                          position);

                    blastSceneObject.Destroy(delay: blastAnimationDuration);

                    var blastSpriteRenderer = Client.Rendering.CreateSpriteRenderer(
                        blastSceneObject,
                        new TextureResource("FX/ExplosionBlast"),
                        drawOrder: DrawOrder.Explosion - 1,
                        spritePivotPoint: (0.5, 0.5));

                    // animate blast wave
                    ClientComponentGenericAnimationHelper.Setup(
                        blastSceneObject,
                        blastAnimationDuration,
                        updateCallback: alpha =>
                    {
                        var blastwaveAlpha        = (byte)(byte.MaxValue * (1 - alpha));
                        blastSpriteRenderer.Color = explosionPreset.BlastWaveColor
                                                    .WithAlpha(blastwaveAlpha);

                        var sizeX = MathHelper.Lerp(explosionPreset.BlastwaveSizeFrom.X,
                                                    explosionPreset.BlastwaveSizeTo.X,
                                                    alpha);
                        var sizeY = MathHelper.Lerp(explosionPreset.BlastwaveSizeFrom.Y,
                                                    explosionPreset.BlastwaveSizeTo.Y,
                                                    alpha);
                        blastSpriteRenderer.Size = new Size2F(sizeX, sizeY);
                    });
                });
            }

            ClientGroundExplosionAnimationHelper.OnExplode(
                delaySeconds: explosionSpriteAnimationDuration / 2,
                position: position);
        }