Enemy Loadout Generation
Modified zone generator to scale the radius and mass of a zone according to galaxy density Added loadout generator which procedurally generates ships and turrets Generating 3 randomized ships in each occupied zone Fixed DatabaseCache.GetAll for parent types Fixed wormhole traversal bug for returning to previous zone (ZoneRenderer subscriptions not being properly disposed)
This commit is contained in:
parent
c0494ee3d8
commit
ebde23a64d
25 changed files with 5421 additions and 148 deletions
|
|
@ -107,6 +107,11 @@ public class DatabaseCache
|
|||
{
|
||||
_entries[entry.ID] = entry;
|
||||
_types[type].Add(entry);
|
||||
foreach (var parentType in type.GetParentTypes())
|
||||
{
|
||||
if(_types.ContainsKey(parentType))
|
||||
_types[parentType].Add(entry);
|
||||
}
|
||||
|
||||
if (remote)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -405,7 +405,7 @@ public abstract class Entity
|
|||
var itemShapeInset = hullData.Shape.Inset(itemData.Shape, hullCoord, item.Rotation);
|
||||
var hardpointShapeInset = hullData.Shape.Inset(hardpoint.Shape, hardpoint.Position);
|
||||
|
||||
// Check every cell of the hardpoint shape
|
||||
// Check every cell of the hardpoint shape for existing items
|
||||
foreach(var v in hardpointShapeInset.Coordinates)
|
||||
if (GearOccupancy[v.x, v.y] != null)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -32,31 +32,32 @@ public static class Extensions
|
|||
|
||||
public static T[] WeightedRandomElements<T>(this IEnumerable<T> collection, ref Random random, Func<T, float> weightFunction, int count)
|
||||
{
|
||||
var weights = new Dictionary<T, float>(collection.Count());
|
||||
var elements = collection as T[] ?? collection.ToArray();
|
||||
var weights = new Dictionary<T, float>(elements.Length);
|
||||
var totalWeight = 0f;
|
||||
foreach (var x in collection)
|
||||
foreach (var x in elements)
|
||||
{
|
||||
weights[x] = weightFunction(x);
|
||||
totalWeight += weights[x];
|
||||
}
|
||||
|
||||
var elements = new T[count];
|
||||
var randomElements = new T[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var targetWeight = random.NextFloat(totalWeight);
|
||||
var accumWeight = 0f;
|
||||
foreach (var x in collection)
|
||||
foreach (var x in elements)
|
||||
{
|
||||
accumWeight += weights[x];
|
||||
if (accumWeight > targetWeight)
|
||||
{
|
||||
elements[i] = x;
|
||||
randomElements[i] = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return elements;
|
||||
return randomElements;
|
||||
}
|
||||
|
||||
// Thanks, https://stackoverflow.com/a/48599119
|
||||
|
|
|
|||
|
|
@ -175,6 +175,50 @@ public class Shape
|
|||
);
|
||||
return shape;
|
||||
}
|
||||
|
||||
// TODO: Use the power of math to optimize this function!
|
||||
// Try to find a rotation and position with which a shape can be placed to fit within another shape
|
||||
public bool FitsWithin(Shape other, out ItemRotation rotation, out int2 position)
|
||||
{
|
||||
// Try every item orientation
|
||||
foreach(var rot in (ItemRotation[])Enum.GetValues(typeof(ItemRotation)))
|
||||
{
|
||||
rotation = rot;
|
||||
if (FitsWithin(other, rot, out var pos))
|
||||
{
|
||||
position = pos;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
rotation = ItemRotation.None;
|
||||
position = int2.zero;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to find a position with which a shape can be placed to fit within another shape
|
||||
public bool FitsWithin(Shape other, ItemRotation rotation, out int2 position)
|
||||
{
|
||||
// Try every item position that could possibly fit
|
||||
for(int x = 0; x < other.Width - Width + 1; x++)
|
||||
{
|
||||
for (int y = 0; y < other.Height - Height + 1; y++)
|
||||
{
|
||||
position = int2(x, y);
|
||||
var fits = true;
|
||||
foreach (var v in Coordinates)
|
||||
{
|
||||
fits = fits && other[Rotate(v, rotation) + position];
|
||||
if (!fits) break;
|
||||
}
|
||||
|
||||
if (fits) return true;
|
||||
}
|
||||
}
|
||||
|
||||
position = int2.zero;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[MessagePackObject,
|
||||
|
|
|
|||
155
Assets/Scripts/ServerShared/LoadoutGenerator.cs
Normal file
155
Assets/Scripts/ServerShared/LoadoutGenerator.cs
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
using Random = Unity.Mathematics.Random;
|
||||
|
||||
public class LoadoutGenerator
|
||||
{
|
||||
public Random Random;
|
||||
public ItemManager ItemManager { get; }
|
||||
public Sector Sector { get; }
|
||||
public SectorZone Zone { get; }
|
||||
public MegaCorporation Faction { get; }
|
||||
public float PriceExponent { get; }
|
||||
|
||||
public LoadoutGenerator(
|
||||
ref Random random,
|
||||
ItemManager itemManager,
|
||||
Sector sector,
|
||||
SectorZone zone,
|
||||
MegaCorporation faction,
|
||||
float priceExponent)
|
||||
{
|
||||
Random = random;
|
||||
ItemManager = itemManager;
|
||||
Sector = sector;
|
||||
Zone = zone;
|
||||
Faction = faction;
|
||||
PriceExponent = priceExponent;
|
||||
}
|
||||
|
||||
public EntityPack GenerateShipLoadout()
|
||||
{
|
||||
var hull = ItemManager.CreateInstance(RandomHull(HullType.Ship)) as EquippableItem;
|
||||
var entity = new Ship(ItemManager, null, hull, ItemManager.GameplaySettings.DefaultEntitySettings);
|
||||
entity.Faction = Faction;
|
||||
OutfitEntity(entity);
|
||||
return EntitySerializer.Pack(entity);
|
||||
}
|
||||
|
||||
public EntityPack GenerateTurretLoadout()
|
||||
{
|
||||
var hull = ItemManager.CreateInstance(RandomHull(HullType.Turret)) as EquippableItem;
|
||||
var entity = new OrbitalEntity(ItemManager, null, hull, Guid.Empty, ItemManager.GameplaySettings.DefaultEntitySettings);
|
||||
entity.Faction = Faction;
|
||||
OutfitEntity(entity);
|
||||
return EntitySerializer.Pack(entity);
|
||||
}
|
||||
|
||||
public HullData RandomHull(HullType type)
|
||||
{
|
||||
return ItemManager.ItemData.GetAll<HullData>()
|
||||
.Where(item => item.HullType == type && (item.Manufacturer == Faction.ID || Faction.Allegiance.ContainsKey(item.Manufacturer)))
|
||||
.WeightedRandomElements(ref Random,
|
||||
item =>
|
||||
(item.Manufacturer == Faction.ID ? 1 : Faction.Allegiance[item.Manufacturer]) / // Prioritize items from allied manufacturers
|
||||
Zone.Distance[Sector.HomeZones[ItemManager.ItemData.Get<MegaCorporation>(item.Manufacturer)]] / // Penalize distance to manufacturer headquarters
|
||||
pow(item.Price, PriceExponent), // Penalize item price to a controllable degree
|
||||
1
|
||||
).FirstOrDefault();
|
||||
}
|
||||
|
||||
public T RandomItem<T>(Predicate<T> filter = null) where T : EquippableItemData
|
||||
{
|
||||
return ItemManager.ItemData.GetAll<T>()
|
||||
.Where(item => Sector.ContainsFaction(item.Manufacturer) &&
|
||||
(item.Manufacturer == Faction.ID || Faction.Allegiance.ContainsKey(item.Manufacturer)) &&
|
||||
(filter?.Invoke(item) ?? true))
|
||||
.WeightedRandomElements(ref Random, item =>
|
||||
(item.Manufacturer == Faction.ID ? 1 : Faction.Allegiance[item.Manufacturer]) * // Prioritize items from allied manufacturers
|
||||
item.Shape.Coordinates.Length / // Prioritize items that fill more of the hardpoint's slots
|
||||
Zone.Distance[Sector.HomeZones[ItemManager.ItemData.Get<MegaCorporation>(item.Manufacturer)]] / // Penalize distance to manufacturer headquarters
|
||||
pow(item.Price, PriceExponent), // Penalize item price to a controllable degree
|
||||
1
|
||||
).FirstOrDefault();
|
||||
}
|
||||
|
||||
public T RandomItem<T>(HardpointData hardpoint, Predicate<T> filter = null) where T : EquippableItemData
|
||||
{
|
||||
return RandomItem<T>(item => item.HardpointType == hardpoint.Type &&
|
||||
(filter?.Invoke(item) ?? true) &&
|
||||
item.Shape.FitsWithin(hardpoint.Shape, hardpoint.Rotation, out _));
|
||||
}
|
||||
|
||||
private void OutfitEntity(Entity entity)
|
||||
{
|
||||
var hullData = ItemManager.GetData(entity.Hull) as HullData;
|
||||
foreach (var hardpoint in hullData.Hardpoints)
|
||||
{
|
||||
if (hardpoint.Type == HardpointType.ControlModule)
|
||||
{
|
||||
var controllerData = RandomItem<GearData>(hardpoint,
|
||||
item => item.Behaviors.Any(b => entity is Ship && b is CockpitData || entity is OrbitalEntity && b is TurretControllerData));
|
||||
if (controllerData == null) throw new InvalidLoadoutException("No compatible controller found for entity!");
|
||||
var controller = ItemManager.CreateInstance(controllerData) as EquippableItem;
|
||||
if (!entity.TryEquip(controller))
|
||||
{
|
||||
throw new InvalidLoadoutException($"Failed to equip selected {Enum.GetName(typeof(HardpointType), hardpoint.Type)}!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var itemData = RandomItem<GearData>(hardpoint);
|
||||
if (itemData == null) ItemManager.Log($"No compatible item found for entity {Enum.GetName(typeof(HardpointType), hardpoint.Type)} hardpoint!");
|
||||
else
|
||||
{
|
||||
//throw new InvalidLoadoutException($"No compatible item found for entity {Enum.GetName(typeof(HardpointType), hardpoint.Type)} hardpoint!");
|
||||
var item = ItemManager.CreateInstance(itemData) as EquippableItem;
|
||||
if (!entity.TryEquip(item))
|
||||
{
|
||||
throw new InvalidLoadoutException($"Failed to equip selected {Enum.GetName(typeof(HardpointType), hardpoint.Type)}!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var emptyShape = new Shape(hullData.Shape.Width, hullData.Shape.Height);
|
||||
foreach (var v in hullData.Shape.Coordinates)
|
||||
{
|
||||
if (hullData.InteriorCells[v] && entity.Hardpoints[v.x, v.y] == null)
|
||||
emptyShape[v] = true;
|
||||
}
|
||||
|
||||
var capacitorData = RandomItem<GearData>(item =>
|
||||
item.Behaviors.Any(b => b is CapacitorData) &&
|
||||
item.Shape.FitsWithin(emptyShape, out _, out _));
|
||||
if (capacitorData == null) throw new InvalidLoadoutException("No compatible capacitor found for entity!");
|
||||
|
||||
if(!capacitorData.Shape.FitsWithin(emptyShape, out var capacitorRotation, out var capacitorPosition))
|
||||
throw new InvalidLoadoutException("Failed to equip selected capacitor!");
|
||||
var capacitor = ItemManager.CreateInstance(capacitorData) as EquippableItem;
|
||||
capacitor.Rotation = capacitorRotation;
|
||||
if (!entity.TryEquip(capacitor, capacitorPosition))
|
||||
{
|
||||
throw new InvalidLoadoutException("Failed to equip selected capacitor!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class InvalidLoadoutException : Exception
|
||||
{
|
||||
public InvalidLoadoutException()
|
||||
{
|
||||
}
|
||||
|
||||
public InvalidLoadoutException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public InvalidLoadoutException(string message, Exception inner)
|
||||
: base(message, inner)
|
||||
{
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/ServerShared/LoadoutGenerator.cs.meta
Normal file
3
Assets/Scripts/ServerShared/LoadoutGenerator.cs.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bbaf437585db46c9986f0a4f2c778444
|
||||
timeCreated: 1615957107
|
||||
|
|
@ -21,6 +21,7 @@ public class Sector
|
|||
public SectorZone Entrance { get; }
|
||||
public SectorZone Exit { get; }
|
||||
|
||||
private HashSet<Guid> _containedFactions;
|
||||
private SectorZone[] _exitPath;
|
||||
private Dictionary<MegaCorporation, MarkovNameGenerator> _nameGenerators = new Dictionary<MegaCorporation, MarkovNameGenerator>();
|
||||
|
||||
|
|
@ -249,9 +250,10 @@ public class Sector
|
|||
if(progressCallback!=null) Thread.Sleep(500); // Inserting Delay to make it seem like it's doing more work lmao
|
||||
}
|
||||
|
||||
private void GenerateSector()
|
||||
public bool ContainsFaction(Guid factionID)
|
||||
{
|
||||
|
||||
_containedFactions ??= new HashSet<Guid>(Factions.Select(f => f.ID));
|
||||
return _containedFactions.Contains(factionID);
|
||||
}
|
||||
|
||||
// Cache distance matrix and calculate isolation for every zone (used extensively for placing stuff)
|
||||
|
|
|
|||
|
|
@ -87,8 +87,6 @@ public class SectorGenerationSettings
|
|||
[Serializable, MessagePackObject(keyAsPropertyName:true), JsonObject]
|
||||
public class ZoneGenerationSettings
|
||||
{
|
||||
public GalaxyShapeSettings ShapeSettings;
|
||||
|
||||
public ExponentialCurve PlanetSafetyRadius;
|
||||
|
||||
public float MassFloor = 1;
|
||||
|
|
@ -104,6 +102,8 @@ public class ZoneGenerationSettings
|
|||
|
||||
public ExponentialLerp ZoneRadius;
|
||||
public ExponentialLerp ZoneMass;
|
||||
public ExponentialLerp SubZoneCount;
|
||||
public float ZoneBoundaryRadius;
|
||||
|
||||
public float BeltProbability = .05f;
|
||||
public float BeltMassCeiling = 500f;
|
||||
|
|
|
|||
|
|
@ -74,11 +74,26 @@ public class Zone
|
|||
var entity = EntitySerializer.Unpack(_itemManager, this, entityPack);
|
||||
Entities.Add(entity);
|
||||
entity.Activate();
|
||||
if (entity is Ship {IsPlayerShip: false} ship)
|
||||
{
|
||||
Agents.Add(CreateAgent(ship));
|
||||
if (lengthsq(ship.Position) < 1)
|
||||
ship.Position = _itemManager.Random.NextFloat3(float3(-pack.Radius * .5f), float3(pack.Radius * .5f));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Associate planets with stored entities for planetary colonies
|
||||
}
|
||||
|
||||
private Agent CreateAgent(Ship ship)
|
||||
{
|
||||
var agent = new Minion(ship);
|
||||
var task = new PatrolOrbitsTask();
|
||||
task.Circuit = Orbits.OrderBy(_ => _itemManager.Random.NextFloat()).Take(4).Select(x => x.Key).ToArray();
|
||||
agent.Task = task;
|
||||
return agent;
|
||||
}
|
||||
|
||||
public ZonePack PackZone()
|
||||
{
|
||||
return new ZonePack
|
||||
|
|
|
|||
|
|
@ -14,36 +14,8 @@ using static Unity.Mathematics.math;
|
|||
using float2 = Unity.Mathematics.float2;
|
||||
using Random = Unity.Mathematics.Random;
|
||||
|
||||
public class ZoneGenerator
|
||||
public static class ZoneGenerator
|
||||
{
|
||||
// public static ZonePack GenerateZone(
|
||||
// ZoneGenerationSettings settings,
|
||||
// Dictionary<string,GalaxyMapLayerData> mapLayers,
|
||||
// IEnumerable<SimpleCommodityData> resources,
|
||||
// string name,
|
||||
// float2 position)
|
||||
// {
|
||||
// var random = new Random(Convert.ToUInt32(abs(name.GetHashCode())));
|
||||
// var radius = settings.ZoneRadius.Evaluate(random.NextFloat() * mapLayers["Radius"].Evaluate(position, settings.ShapeSettings));
|
||||
// var mass = settings.ZoneMass.Evaluate(random.NextFloat() * mapLayers["Mass"].Evaluate(position, settings.ShapeSettings));
|
||||
//
|
||||
// return GenerateZone(settings, mapLayers, resources, name, position, mass, radius, random);
|
||||
// }
|
||||
|
||||
public static ZonePack GenerateZone(
|
||||
ZoneGenerationSettings settings,
|
||||
// Dictionary<string,GalaxyMapLayerData> mapLayers,
|
||||
// IEnumerable<SimpleCommodityData> resources,
|
||||
float mass,
|
||||
float radius)
|
||||
{
|
||||
var name = Guid.NewGuid().ToString().Substring(0, 8);
|
||||
var position = float2(0f);
|
||||
var random = new Random(Convert.ToUInt32(abs(name.GetHashCode())));
|
||||
|
||||
return GenerateZone(settings, name, position, mass, radius, random, 6);
|
||||
}
|
||||
|
||||
private class Circle
|
||||
{
|
||||
public float2 Center;
|
||||
|
|
@ -62,35 +34,34 @@ public class ZoneGenerator
|
|||
}
|
||||
|
||||
private const int MaximumPlacementSamples = 32;
|
||||
private static ZonePack GenerateZone(
|
||||
ZoneGenerationSettings settings,
|
||||
// Dictionary<string,GalaxyMapLayerData> mapLayers,
|
||||
// IEnumerable<SimpleCommodityData> resources,
|
||||
string name,
|
||||
float2 position,
|
||||
float mass,
|
||||
float radius,
|
||||
Random random,
|
||||
int targetSubzoneCount)
|
||||
{
|
||||
|
||||
public static ZonePack GenerateZone(
|
||||
ItemManager itemManager,
|
||||
ZoneGenerationSettings zoneSettings,
|
||||
Sector sector,
|
||||
SectorZone sectorZone)
|
||||
{
|
||||
var pack = new ZonePack();
|
||||
|
||||
pack.Radius = radius;
|
||||
pack.Mass = mass;
|
||||
|
||||
var random = new Random(unchecked((uint) sectorZone.Name.GetHashCode()) ^ hash(sectorZone.Position));
|
||||
|
||||
var density = saturate(sector.Settings.CloudDensity(sectorZone.Position));
|
||||
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, radius);
|
||||
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(radius * .25f, radius * .75f) * random.NextFloat2Direction();
|
||||
var startPosition = random.NextFloat(pack.Radius * .25f, pack.Radius * .5f) * random.NextFloat2Direction();
|
||||
occupiedAreas.Add(new Circle(startPosition, boundaryTangentRadius(startPosition)));
|
||||
|
||||
int samples = 0;
|
||||
|
|
@ -99,7 +70,7 @@ public class ZoneGenerator
|
|||
samples = 0;
|
||||
for (int i = 0; i < MaximumPlacementSamples; i++)
|
||||
{
|
||||
var samplePos = random.NextFloat2(-radius, radius);
|
||||
var samplePos = random.NextFloat2(-pack.Radius, pack.Radius);
|
||||
var rad = tangentRadius(samplePos);
|
||||
if (rad > 0)
|
||||
{
|
||||
|
|
@ -114,11 +85,11 @@ public class ZoneGenerator
|
|||
var totalArea = occupiedAreas.Sum(c => c.Area);
|
||||
foreach (var c in occupiedAreas)
|
||||
{
|
||||
planets.AddRange(GenerateEntities(settings, ref random, c.Area / totalArea * pack.Mass, c.Radius, c.Center));
|
||||
planets.AddRange(GenerateEntities(zoneSettings, ref random, c.Area / totalArea * pack.Mass, c.Radius, c.Center));
|
||||
}
|
||||
}
|
||||
else
|
||||
planets.AddRange(GenerateEntities(settings, ref random, pack.Mass, pack.Radius, float2.zero));
|
||||
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>();
|
||||
|
|
@ -153,9 +124,9 @@ public class ZoneGenerator
|
|||
{
|
||||
// Dictionary<Guid, float> planetResources = new Dictionary<Guid, float>();
|
||||
BodyType bodyType = planet.Belt ? BodyType.Asteroid :
|
||||
planet.Mass > settings.SunMass ? BodyType.Sun :
|
||||
planet.Mass > settings.GasGiantMass ? BodyType.GasGiant :
|
||||
planet.Mass > settings.PlanetMass ? BodyType.Planet : BodyType.Planetoid;
|
||||
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)
|
||||
// {
|
||||
|
|
@ -193,13 +164,13 @@ public class ZoneGenerator
|
|||
if (planetData is AsteroidBeltData beltData)
|
||||
{
|
||||
beltData.Asteroids =
|
||||
Enumerable.Range(0, (int) (settings.AsteroidCount.Evaluate(beltData.Mass.Value * orbitMap[planet].Distance.Value)))
|
||||
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)*settings.AsteroidBeltWidth.Evaluate(orbitMap[planet].Distance.Value),
|
||||
Distance = orbitMap[planet].Distance.Value + random.NextFloat()*(random.NextFloat()-.5f)*zoneSettings.AsteroidBeltWidth.Evaluate(orbitMap[planet].Distance.Value),
|
||||
Phase = random.NextFloat(),
|
||||
Size = random.NextFloat(),
|
||||
RotationSpeed = settings.AsteroidRotationSpeed.Evaluate(random.NextFloat())
|
||||
RotationSpeed = zoneSettings.AsteroidRotationSpeed.Evaluate(random.NextFloat())
|
||||
})
|
||||
//.OrderByDescending(a=>a.Size)
|
||||
.ToArray();
|
||||
|
|
@ -209,25 +180,25 @@ public class ZoneGenerator
|
|||
if (gas is SunData sun)
|
||||
{
|
||||
float primary = random.NextFloat();
|
||||
float secondary = frac(primary + 1 + settings.SunSecondaryColorDistance * (random.NextFloat() > .5 ? 1 : -1));
|
||||
float secondary = frac(primary + 1 + zoneSettings.SunSecondaryColorDistance * (random.NextFloat() > .5 ? 1 : -1));
|
||||
gas.Colors.Value = new []
|
||||
{
|
||||
float4(ColorMath.HsvToRgb(float3(primary, settings.SunColorSaturation, .5f)), 0),
|
||||
float4(ColorMath.HsvToRgb(float3(secondary, settings.SunColorSaturation, 1)), 1)
|
||||
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, settings.SunFogTintSaturation, 1));
|
||||
sun.LightColor.Value = ColorMath.HsvToRgb(float3(primary, settings.SunLightSaturation, 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 + settings.GasGiantBandColorSeparation);
|
||||
float left = frac(primary + 1 - settings.GasGiantBandColorSeparation);
|
||||
float right = frac(primary + zoneSettings.GasGiantBandColorSeparation);
|
||||
float left = frac(primary + 1 - zoneSettings.GasGiantBandColorSeparation);
|
||||
|
||||
// Create n time keys from 0 to 1
|
||||
var bandCount = (int) (settings.GasGiantBandCount.Evaluate(random.NextFloat()) + .5f);
|
||||
var bandCount = (int) (zoneSettings.GasGiantBandCount.Evaluate(random.NextFloat()) + .5f);
|
||||
var times = Enumerable.Range(0, bandCount)
|
||||
.Select(i => (float) i / (bandCount-1));
|
||||
|
||||
|
|
@ -235,9 +206,9 @@ public class ZoneGenerator
|
|||
// Saturation and Value are random with curves applied
|
||||
gas.Colors.Value = times
|
||||
.Select(time => float4(ColorMath.HsvToRgb(float3(
|
||||
random.NextFloat() > settings.GasGiantBandAltColorChance ? primary : (random.NextFloat() > .5f ? right : left),
|
||||
settings.GasGiantBandSaturation.Evaluate(random.NextFloat()),
|
||||
settings.GasGiantBandSaturation.Evaluate(random.NextFloat()))),time))
|
||||
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;
|
||||
|
|
@ -250,6 +221,15 @@ public class ZoneGenerator
|
|||
return planetData;
|
||||
}).ToList();
|
||||
|
||||
if (sectorZone.Owner != null)
|
||||
{
|
||||
var loadoutGenerator = new LoadoutGenerator(ref random, itemManager, sector, sectorZone, sectorZone.Owner, 1);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
pack.Entities.Add(loadoutGenerator.GenerateShipLoadout());
|
||||
}
|
||||
}
|
||||
|
||||
return pack;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue