Пример #1
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var randomDirections = new NativeArray <float2>(MaxRandomResults, Allocator.TempJob);
            var randomDistances  = new NativeArray <float>(MaxRandomResults, Allocator.TempJob);

            for (var i = 0; i < MaxRandomResults; i++)
            {
                randomDirections[i] = _random.NextFloat2Direction();
                randomDistances[i]  = _random.NextFloat();
            }

            var wanderStartJob = new WanderStartJob
            {
                ECBuffer         = ECBSystem.CreateCommandBuffer().ToConcurrent(),
                RandomDirections = randomDirections,
                RandomDistances  = randomDistances,
                Time             = (float)Time.ElapsedTime
            };
            var moveDoneJob = new MoveDoneJob
            {
                ECBuffer         = ECBSystem.CreateCommandBuffer().ToConcurrent(),
                RandomDirections = randomDirections,
                RandomDistances  = randomDistances,
                Time             = (float)Time.ElapsedTime
            };
            var wanderStartHandle = wanderStartJob.Schedule(this, inputDeps);
            var moveDoneHandle    = moveDoneJob.Schedule(this, wanderStartHandle);

            ECBSystem.AddJobHandleForProducer(wanderStartHandle);
            ECBSystem.AddJobHandleForProducer(moveDoneHandle);
            return(moveDoneHandle);
        }
Пример #2
0
    IEnumerator DoMovement()
    {
        while (Movement.Player == null || GameData.Paused)
        {
            yield return(null);
        }
        Vector3 prevTarget = t.position;

        while (true)
        {
            Vector3 target = (Vector2)Movement.Player.t.position + (Vector2)rng.NextFloat2Direction() * 0.5f;
            target.z = 5;
            for (int i = 0; i < 60; i++)
            {
                Vector3 pos = t.position;
                t.position = 97.5f * pos / 100f + target * 1.5f / 100f + prevTarget / 100f;
                while (GameData.Paused)
                {
                    yield return(null);
                }
                yield return(null);
            }
            prevTarget = target;
        }
    }
Пример #3
0
    protected override JobHandle OnUpdate(JobHandle handle)
    {
        if (init && count > 0)
        {
            em.DestroyEntity(boubleQuery);
            count = 0;
            return(handle);
        }

        count = boubleQuery.CalculateEntityCount();
        var f = GetSingleton <SpawnerRndAreaComp>();

        if (sd.rangeMultChanged)
        {
            List <float> ranges = new List <float>();
            ranges.Add(sd.defaultGrav);
            for (int i = 1; i < 6; i++)
            {
                ranges.Add(ranges[i - 1] * sd.rangeMult);
            }
            f.smallRange  = ranges[1];
            f.mediumRange = ranges[2];
            f.largeRange  = ranges[3];
            f.hugeRange   = ranges[4];
            f.superRange  = ranges[5];
            ranges.Clear();
            sd.rangeMultChanged = false;
            SetSingleton <SpawnerRndAreaComp>(f);
        }

        createCount = sd.totalCount - count;

        for (int i = 0; i < createCount; i++)
        {
            rndDir     = _random.NextFloat2Direction();
            rndPos.x   = rndDir.x;
            rndPos.y   = 0;
            rndPos.z   = rndDir.y;
            rndPos    *= init ? _random.NextFloat(0, sd.cylinderRadius) : sd.cylinderRadius;
            rndPos.y   = _random.NextFloat(-sd.cylinderHeight, sd.cylinderHeight);
            posList[i] = rndPos;
        }

        handle = new Joby {
            ecb          = _ecbs.CreateCommandBuffer().ToConcurrent(),
            f            = f, sd = sd,
            prefabEntity = _prefabEntity,
            absorb       = sd.absorb,
            bounce       = sd.bounce,
            posList      = posList,
            bubFrac      = .5f / BoubleAuth._grad
        }.Schedule(createCount, 10, handle);

        _ecbs.AddJobHandleForProducer(handle);

        init = false;

        return(handle);
    }
Пример #4
0
            private static void SetNewTarget(ref MovementState movementState, ref EnemyState enemyState, ref Translation translation, out float3 toTarget, out float3 fromTargetToPlayer, ref Random Random)
            {
                float2 newDirection   = Random.NextFloat2Direction();
                float3 newDirection3D = new float3(newDirection.x, 0, newDirection.y);

                enemyState.CurrAIState = EnemyAIState.Follow;
                movementState.Target   = enemyState.PlayerPosition + newDirection3D * enemyState.DesiredDistance;
                UpdateTarget(movementState, enemyState, translation, out toTarget, out fromTargetToPlayer);
            }
Пример #5
0
        //Random initial heading must be set to readonly becuase it is the subject of the command buffer
        public void Execute(Entity entity, int index, [ReadOnly] ref RandomInitialHeading randomInitialHeading, ref Heading heading)
        {
            heading = new Heading
            {
                Value = Random.NextFloat2Direction()
            };

            CommandBuffer.RemoveComponent <RandomInitialHeading>(entity);
        }
Пример #6
0
    ////

    Boid spawn(ref Unity.Mathematics.Random rand, float2 SpawnRect)
    {
        return(new Boid {
            pos = rand.NextFloat2() * SpawnRect,
            vel = rand.NextFloat2Direction() * rand.NextFloat() * 0.2f * SpeedTarget,
            forward = float2(0, 1),
            //size = (rand.NextFloat() + 0.8f) * BoidSize,
            size = BoidSize,

            color = BoidColors.Evaluate(rand.NextFloat()),
        });
    }
Пример #7
0
        protected override void OnUpdate(EntityCommandBuffer.Concurrent ecb)
        {
            lastSpawnTime -= Time.DeltaTime;
            if (lastSpawnTime <= 0)
            {
                lastSpawnTime = setup.spawnInterval;
                lastSpawnTime = float.MaxValue;

                var spawnCount     = setup.spawnCount;
                var spawnRadius    = setup.spawnRadius;
                var playerPos      = (float3)GameManager.GetPlayerPosition();
                var random         = new Random(mainRandom.NextUInt(uint.MinValue, uint.MaxValue));
                var enemyArchetype = enemyPrefab;

                float3 RandomPointOnCircle(float spawnRaduis)
                {
                    var pos = random.NextFloat2Direction() * spawnRaduis;

                    return(new float3(pos.x, 0, pos.y) + playerPos);
                }

                Job
                .WithCode(() =>
                {
                    var jobIndex = 0;
                    for (int i = 0; i < spawnCount; i++)
                    {
                        var enemy = ecb.CreateEntity(jobIndex, enemyArchetype);
                        ecb.AddComponent(jobIndex, enemy, new Translation {
                            Value = RandomPointOnCircle(spawnRadius)
                        });
                        ecb.AddComponent(jobIndex, enemy, new Rotation {
                            Value = quaternion.Euler(0, random.NextFloat(-math.PI, math.PI), 0)
                        });
                    }
                })
                .Schedule();
            }
        }
Пример #8
0
    public static ZonePack GenerateZone(
        ItemManager itemManager,
        ZoneGenerationSettings zoneSettings,
        Galaxy galaxy,
        GalaxyZone galaxyZone,
        bool isTutorial = false)
    {
        var pack = new ZonePack();

        var random = new Random(unchecked ((uint)galaxyZone.Name.GetHashCode()) ^ hash(galaxyZone.Position));

        var density = saturate(galaxy.Background.CloudDensity(galaxyZone.Position) / 2);

        pack.Radius = zoneSettings.ZoneRadius.Evaluate(density);
        pack.Mass   = zoneSettings.ZoneMass.Evaluate(density);
        var targetSubzoneCount = zoneSettings.SubZoneCount.Evaluate(density);

        //Debug.Log($"Generating zone at position {zone.Position} with radius {zoneRadius} and mass {zoneMass}");

        var planets = new List <GeneratorPlanet>();

        if (targetSubzoneCount > 1)
        {
            var zoneBoundary = new Circle(float2.zero, pack.Radius * zoneSettings.ZoneBoundaryRadius);
            float boundaryTangentRadius(float2 point) => - zoneBoundary.DistanceTo(point);

            var occupiedAreas = new List <Circle>();
            float tangentRadius(float2 point) => min(boundaryTangentRadius(point), occupiedAreas.Min(circle => circle.DistanceTo(point)));

            var startPosition = random.NextFloat(pack.Radius * .25f, pack.Radius * .5f) * random.NextFloat2Direction();
            occupiedAreas.Add(new Circle(startPosition, boundaryTangentRadius(startPosition)));

            int samples = 0;
            while (occupiedAreas.Count < targetSubzoneCount && samples < MaximumPlacementSamples)
            {
                samples = 0;
                for (int i = 0; i < MaximumPlacementSamples; i++)
                {
                    var samplePos = random.NextFloat2(-pack.Radius, pack.Radius);
                    var rad       = tangentRadius(samplePos);
                    if (rad > 0)
                    {
                        occupiedAreas.Add(new Circle(samplePos, rad));
                        break;
                    }

                    samples++;
                }
            }

            var totalArea = occupiedAreas.Sum(c => c.Area);
            foreach (var c in occupiedAreas)
            {
                planets.AddRange(GenerateEntities(zoneSettings, ref random, c.Area / totalArea * pack.Mass, c.Radius, c.Center));
            }
        }
        else
        {
            planets.AddRange(GenerateEntities(zoneSettings, ref random, pack.Mass, pack.Radius, float2.zero));
        }

        // Create collections to map between zone generator output and database entries
        var orbitMap        = new Dictionary <GeneratorPlanet, OrbitData>();
        var orbitInverseMap = new Dictionary <OrbitData, GeneratorPlanet>();

        // Create orbit database entries
        pack.Orbits = planets.Select(planet =>
        {
            var data = new OrbitData
            {
                FixedPosition = planet.FixedPosition,
                Distance      = new ReactiveProperty <float>(planet.Distance),
                //Period = planet.Period,
                Phase = planet.Phase
            };
            orbitMap[planet]      = data;
            orbitInverseMap[data] = planet;
            return(data);
        }).ToList();

        // Link OrbitData parents to database GUIDs
        foreach (var data in pack.Orbits)
        {
            data.Parent = orbitInverseMap[data].Parent != null
                ? orbitMap[orbitInverseMap[data].Parent].ID
                : Guid.Empty;
        }

        // Cache resource densities
        // var resourceMaps = mapLayers.Values
        //  .ToDictionary(m => m.ID, m => m.Evaluate(zone.Position, settings.ShapeSettings));

        pack.Planets = planets.Where(p => !p.Empty).Select(planet =>
        {
            // Dictionary<Guid, float> planetResources = new Dictionary<Guid, float>();
            BodyType bodyType = planet.Belt ? BodyType.Asteroid :
                                planet.Mass > zoneSettings.SunMass ? BodyType.Sun :
                                planet.Mass > zoneSettings.GasGiantMass ? BodyType.GasGiant :
                                planet.Mass > zoneSettings.PlanetMass ? BodyType.Planet : BodyType.Planetoid;

            // foreach (var r in resources)
            // {
            //  if ((bodyType & r.ResourceBodyType) != 0)
            //  {
            //   float quantity = ResourceValue(ref random, settings, r, r.ResourceDensity.Aggregate(1f, (m, rdm) => m * resourceMaps[rdm]));
            //   if (r.Floor < quantity) planetResources.Add(r.ID, quantity);
            //  }
            // }

            BodyData planetData;
            switch (bodyType)
            {
            case BodyType.Asteroid:
                planetData = new AsteroidBeltData();
                break;

            case BodyType.Planetoid:
            case BodyType.Planet:
                planetData = new PlanetData();
                break;

            case BodyType.GasGiant:
                planetData = new GasGiantData();
                break;

            case BodyType.Sun:
                planetData = new SunData();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            planetData.Mass.Value = planet.Mass;
            planetData.Orbit      = orbitMap[planet].ID;
            // planetData.Resources = planetResources;
            planetData.Name.Value = planetData.ID.ToString().Substring(0, 8);
            if (planetData is AsteroidBeltData beltData)
            {
                beltData.Asteroids =
                    Enumerable.Range(0, (int)(zoneSettings.AsteroidCount.Evaluate(beltData.Mass.Value * orbitMap[planet].Distance.Value)))
                    .Select(_ => new Asteroid
                {
                    Distance      = orbitMap[planet].Distance.Value + random.NextFloat() * (random.NextFloat() - .5f) * zoneSettings.AsteroidBeltWidth.Evaluate(orbitMap[planet].Distance.Value),
                    Phase         = random.NextFloat(),
                    Size          = random.NextFloat(),
                    RotationSpeed = zoneSettings.AsteroidRotationSpeed.Evaluate(random.NextFloat())
                })
                    //.OrderByDescending(a=>a.Size)
                    .ToArray();
            }
            else if (planetData is GasGiantData gas)
            {
                if (gas is SunData sun)
                {
                    float primary    = random.NextFloat();
                    float secondary  = frac(primary + 1 + zoneSettings.SunSecondaryColorDistance * (random.NextFloat() > .5 ? 1 : -1));
                    gas.Colors.Value = new []
                    {
                        float4(ColorMath.HsvToRgb(float3(primary, zoneSettings.SunColorSaturation, .5f)), 0),
                        float4(ColorMath.HsvToRgb(float3(secondary, zoneSettings.SunColorSaturation, 1)), 1)
                    };
                    sun.FogTintColor.Value = ColorMath.HsvToRgb(float3(primary, zoneSettings.SunFogTintSaturation, 1));
                    sun.LightColor.Value   = ColorMath.HsvToRgb(float3(primary, zoneSettings.SunLightSaturation, 1));
                    gas.FirstOffsetDomainRotationSpeed.Value = 5;
                }
                else
                {
                    // Define primary color and two adjacent colors
                    float primary = random.NextFloat();
                    float right   = frac(primary + zoneSettings.GasGiantBandColorSeparation);
                    float left    = frac(primary + 1 - zoneSettings.GasGiantBandColorSeparation);

                    // Create n time keys from 0 to 1
                    var bandCount = (int)(zoneSettings.GasGiantBandCount.Evaluate(random.NextFloat()) + .5f);
                    var times     = Enumerable.Range(0, bandCount)
                                    .Select(i => (float)i / (bandCount - 1));

                    // Each band has a chance of being either the primary or one of the adjacent hues
                    // Saturation and Value are random with curves applied
                    gas.Colors.Value = times
                                       .Select(time => float4(ColorMath.HsvToRgb(float3(
                                                                                     random.NextFloat() > zoneSettings.GasGiantBandAltColorChance ? primary : (random.NextFloat() > .5f ? right : left),
                                                                                     zoneSettings.GasGiantBandSaturation.Evaluate(random.NextFloat()),
                                                                                     zoneSettings.GasGiantBandSaturation.Evaluate(random.NextFloat()))), time))
                                       .ToArray();

                    gas.FirstOffsetDomainRotationSpeed.Value = 0;
                }
                gas.AlbedoRotationSpeed.Value             = -3;
                gas.FirstOffsetRotationSpeed.Value        = 5;
                gas.SecondOffsetRotationSpeed.Value       = 10;
                gas.SecondOffsetDomainRotationSpeed.Value = -25;
            }
            return(planetData);
        }).ToList();

        var nearestFaction         = galaxy.Factions.MinBy(f => galaxy.HomeZones[f].Distance[galaxyZone]);
        var nearestFactionHomeZone = galaxy.HomeZones[nearestFaction];
        var factionPresence        = nearestFaction.InfluenceDistance - nearestFactionHomeZone.Distance[galaxyZone] + 1;

        var storyStations           = galaxyZone.Locations.Where(story => story.Type == LocationType.Station).ToArray();
        var stationCount            = (int)(random.NextFloat() * (factionPresence + 1)) + storyStations.Length;
        var potentialLagrangePoints = planets
                                      .Where(p => p.Parent != null && p.Parent.Children
                                             .TrueForAll(c => !(c != p && abs(c.Distance - p.Distance) < .1f))) // Filter Rosettes
                                      .OrderBy(p => p.Distance)
                                      .ToArray();
        // Pick a selection from the middle of the distribution
        var selectedStationOrbits = potentialLagrangePoints
                                    .Skip(potentialLagrangePoints.Length / 2)
                                    .Take(stationCount)
                                    .Select(p => orbitMap[p])
                                    .ToArray();

        var loadoutGenerators = new Dictionary <Faction, LoadoutGenerator>();

        LoadoutGenerator GetLoadoutGenerator(Faction faction)
        {
            if (!loadoutGenerators.ContainsKey(faction))
            {
                loadoutGenerators[faction] = isTutorial
                                ? new LoadoutGenerator(ref random, itemManager, faction, .5f)
                                : new LoadoutGenerator(ref random, itemManager, galaxy, galaxyZone, faction, .5f);
            }
            return(loadoutGenerators[faction]);
        }

        OrbitData CreateLagrangeOrbit(OrbitData baseOrbit)
        {
            var lagrangeOrbit = new OrbitData
            {
                ID       = Guid.NewGuid(),
                Parent   = baseOrbit.Parent,
                Distance = new ReactiveProperty <float>(baseOrbit.Distance.Value),
                Phase    = baseOrbit.Phase + PI / 3 * sign(random.NextFloat() - .5f)
            };

            pack.Orbits.Add(lagrangeOrbit);
            return(lagrangeOrbit);
        }

        void PlaceTurret(OrbitData orbit, LoadoutGenerator loadoutGenerator, int distanceMultiplier)
        {
            var phase = 20f * distanceMultiplier / orbit.Distance.Value;

            var turretOrbit = new OrbitData
            {
                ID       = Guid.NewGuid(),
                Parent   = orbit.Parent,
                Distance = new ReactiveProperty <float>(orbit.Distance.Value),
                Phase    = orbit.Phase + phase
            };

            pack.Orbits.Add(turretOrbit);
            var turret = loadoutGenerator.GenerateTurretLoadout();

            turret.Orbit = turretOrbit.ID;
            pack.Entities.Add(turret);
        }

        void PlaceTurrets(OrbitData orbit, LoadoutGenerator loadoutGenerator, int count)
        {
            for (int t = 0; t < count; t++)
            {
                var dist = t / 2;
                if (t % 2 == 0)
                {
                    dist = -dist;
                }
                PlaceTurret(orbit, loadoutGenerator, dist);
            }
        }

        for (var i = 0; i < storyStations.Length; i++)
        {
            var story         = storyStations[i];
            var orbit         = selectedStationOrbits[i];
            var lagrangeOrbit = CreateLagrangeOrbit(orbit);
            var station       = GetLoadoutGenerator(story.Faction).GenerateStationLoadout();
            station.Orbit          = lagrangeOrbit.ID;
            station.SecurityLevel  = story.Security;
            station.SecurityRadius = pack.Radius;
            station.Story          = i;
            pack.Entities.Add(station);

            PlaceTurrets(lagrangeOrbit, GetLoadoutGenerator(story.Faction), story.Turrets);
        }

        for (var i = storyStations.Length; i < selectedStationOrbits.Length; i++)
        {
            var orbit    = selectedStationOrbits[i];
            var security = (SecurityLevel)((int)((1f - pow(random.NextFloat(), factionPresence / 2f)) * 3f));

            var lagrangeOrbit = CreateLagrangeOrbit(orbit);
            var station       = GetLoadoutGenerator(nearestFaction).GenerateStationLoadout();
            station.Orbit          = lagrangeOrbit.ID;
            station.SecurityLevel  = security;
            station.SecurityRadius = pack.Radius;
            pack.Entities.Add(station);

            PlaceTurrets(lagrangeOrbit, GetLoadoutGenerator(nearestFaction), 2);
        }

        var enemyCount = (int)(random.NextFloat() * factionPresence * 2) + stationCount;

        for (int i = 0; i < enemyCount; i++)
        {
            pack.Entities.Add(GetLoadoutGenerator(nearestFaction).GenerateShipLoadout());
        }

        return(pack);
    }