Shops & Weapon Icons

Added stations to loadout generator
Overhauled Trade menu to sell station inventory contents
Placing stations in ZoneGenerator
Moved weapons to new item type: WeaponItemData
Implemented icon sets for weapon functionality
Renamed MegaCorporation to Faction
Implemented quality-dependent item pricing
Added unoccupied space helper function for entity
Moved sector generation settings to settings file
This commit is contained in:
Reinier Vens 2021-03-20 04:20:17 +00:00
commit fd81bf267e
33 changed files with 1640 additions and 1077 deletions

View file

@ -36,7 +36,7 @@ public class Corporation : DatabaseEntry, INamedEntry
}
[RethinkTable("Galaxy"), Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
public class MegaCorporation : DatabaseEntry, INamedEntry
public class Faction : DatabaseEntry, INamedEntry
{
[InspectableField, JsonProperty("name"), Key(1)]
public string Name;
@ -71,7 +71,7 @@ public class MegaCorporation : DatabaseEntry, INamedEntry
[InspectableField, JsonProperty("influence"), Key(11)]
public int InfluenceDistance = 4;
[InspectableDatabaseLink(typeof(MegaCorporation)), RangedFloat(0, 1), JsonProperty("allegiance"), Key(12)]
[InspectableDatabaseLink(typeof(Faction)), RangedFloat(0, 1), JsonProperty("allegiance"), Key(12)]
public Dictionary<Guid, float> Allegiance = new Dictionary<Guid, float>();
[IgnoreMember] public string EntryName

View file

@ -31,7 +31,7 @@ public interface INamedEntry
//Union(10, typeof(ZoneData)),
Union(11, typeof(PlayerData)),
Union(12, typeof(Corporation)),
Union(13, typeof(MegaCorporation)),
Union(13, typeof(Faction)),
Union(14, typeof(OrbitalEntity)),
Union(15, typeof(OrbitData)),
Union(16, typeof(BodyData)),
@ -49,6 +49,7 @@ public interface INamedEntry
Union(28, typeof(PlanetData)),
Union(29, typeof(CargoBayData)),
Union(30, typeof(DockingBayData)),
Union(31, typeof(WeaponItemData)),
JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<DatabaseEntry>))]
//[Union(21, typeof(ContractData))]
//[Union(22, typeof(Station))]

View file

@ -13,7 +13,7 @@ using int2 = Unity.Mathematics.int2;
public abstract class Entity
{
public Zone Zone;
public MegaCorporation Faction;
public Faction Faction;
public EquippableItem Hull;
public float3 Position;
@ -78,6 +78,8 @@ public abstract class Entity
}
}
public HullData HullData { get; }
public EntitySettings Settings { get; }
public bool OverrideShutdown { get; set; }
@ -162,6 +164,7 @@ public abstract class Entity
ItemManager = itemManager;
Zone = zone;
Hull = hull;
HullData = itemManager.GetData(hull) as HullData;
Name = hull.Name;
MapEntity();
TriggerGroups = new (List<Weapon> triggers, List<EquippedItem> items)[itemManager.GameplaySettings.TriggerGroupCount];
@ -277,6 +280,21 @@ public abstract class Entity
return CargoBays.FirstOrDefault(c => c.ItemsOfType.ContainsKey(itemDataID));
}
public Shape UnoccupiedSpace
{
get
{
var emptyShape = new Shape(HullData.Shape.Width, HullData.Shape.Height);
foreach (var v in HullData.Shape.Coordinates)
{
if (HullData.InteriorCells[v] && GearOccupancy[v.x, v.y] == null && Hardpoints[v.x,v.y] == null)
emptyShape[v] = true;
}
return emptyShape;
}
}
// Attempts to move a given number of items of the given type to the target Entity
// Returns the number of items successfully transferred
public int TryTransferItems(Entity target, Guid itemDataID, int quantity)
@ -1040,7 +1058,18 @@ public class EquippedCargoBay : EquippedItem
public float Mass { get; private set; }
public float ThermalMass { get; private set; }
public string Name { get; }
public Shape UnoccupiedSpace
{
get
{
var unoccupied = new Shape(Data.InteriorShape.Width, Data.InteriorShape.Height);
foreach (var v in unoccupied.AllCoordinates)
unoccupied[v] = Occupancy[v.x, v.y] == null;
return unoccupied;
}
}
public EquippedCargoBay(ItemManager itemManager, EquippableItem item, int2 position, Entity entity, string name) : base(itemManager, item, position, entity)
{
Data = ItemManager.GetData(EquippableItem) as CargoBayData;
@ -1101,6 +1130,7 @@ public class EquippedCargoBay : EquippedItem
if (remainingQuantity == 0) return true;
}
// TODO: Try alternate item rotations / use Shape.FitsWithin
// Search all the space in the cargo bay for an empty space where the item fits
foreach (var cargoCoord in Data.InteriorShape.Coordinates)
{

View file

@ -87,7 +87,7 @@ public static class EntitySerializer
private static void Restore(ItemManager itemManager, Zone zone, EntityPack pack, Entity entity, bool instantiate = false)
{
entity.Name = pack.Name;
entity.Faction = itemManager.ItemData.Get<MegaCorporation>(pack.Faction);
entity.Faction = itemManager.ItemData.Get<Faction>(pack.Faction);
entity.Children = pack.Children.Select(c =>
{
var child = Unpack(itemManager, zone, c, instantiate);

View file

@ -44,6 +44,60 @@ public enum HardpointType
ControlModule
}
public enum WeaponType
{
ElectromagneticallyPropelled,
ExplosivelyPropelled,
Laser,
Electrostatic,
ParticleProjection,
Missile,
MicroMissile,
SplitMissile,
Mine,
Jet
}
public enum WeaponRange
{
Melee,
Short,
Medium,
Long
}
public enum WeaponCaliber
{
Small,
Medium,
Large,
ExtraLarge
}
[Flags]
public enum WeaponFireType
{
None = 0,
Direct = 1 << 0,
Guided = 1 << 1,
Seeking = 1 << 2,
Continuous = 1 << 3,
Charged = 1 << 4
}
[Flags]
public enum WeaponModifiers
{
None = 0,
Airburst = 1 << 0,
Incendiary = 1 << 1,
ArmorPenetrating = 1 << 2,
NegativeEntropy = 1 << 3,
RapidFire = 1 << 4,
Burst = 1 << 5,
Cluster = 1 << 6
}
public enum DamageType
{
Kinetic,

View file

@ -219,14 +219,7 @@ public class Shape
}
}
[MessagePackObject,
Union(0, typeof(SimpleCommodityData)),
Union(1, typeof(CompoundCommodityData)),
Union(2, typeof(GearData)),
Union(3, typeof(HullData)),
Union(4, typeof(CargoBayData)),
Union(5, typeof(DockingBayData)),
JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<ItemData>))]
[MessagePackObject, JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<ItemData>))]
public abstract class ItemData : DatabaseEntry, INamedEntry
{
[InspectableField, JsonProperty("name"), Key(1)]
@ -235,7 +228,7 @@ public abstract class ItemData : DatabaseEntry, INamedEntry
[InspectableText, JsonProperty("description"), Key(2)]
public string Description;
[InspectableDatabaseLink(typeof(MegaCorporation)), JsonProperty("creator"), Key(3)]
[InspectableDatabaseLink(typeof(Faction)), JsonProperty("creator"), Key(3)]
public Guid Manufacturer;
[InspectableField, JsonProperty("mass"), Key(4)]
@ -288,12 +281,7 @@ public class SimpleCommodityData : ItemData
public SimpleCommodityCategory Category;
}
[MessagePackObject,
Union(0, typeof(CompoundCommodityData)),
Union(1, typeof(GearData)),
Union(2, typeof(HullData)),
JsonObject(MemberSerialization.OptIn),
JsonConverter(typeof(JsonKnownTypesConverter<CraftedItemData>))]
[MessagePackObject, JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<CraftedItemData>))]
public abstract class CraftedItemData : ItemData
{
[InspectableField, JsonProperty("ingredientQualityWeight"), Key(9)]
@ -310,9 +298,7 @@ public class CompoundCommodityData : CraftedItemData
public CompoundCommodityCategory Category;
}
[Union(0, typeof(GearData)),
Union(1, typeof(HullData)),
JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<EquippableItemData>))]
[JsonObject(MemberSerialization.OptIn), JsonConverter(typeof(JsonKnownTypesConverter<EquippableItemData>))]
public abstract class EquippableItemData : CraftedItemData
{
[InspectableTexture, JsonProperty("schematic"), Key(10)]
@ -405,7 +391,25 @@ public class DockingBayData : CargoBayData
{
[InspectableField, JsonProperty("maxSize"), Key(21)]
public int2 MaxSize;
[IgnoreMember] public override HardpointType HardpointType => HardpointType.Tool;
}
[RethinkTable("Items"), Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)]
public class WeaponItemData : GearData
{
[InspectableField, JsonProperty("range"), Key(21)]
public WeaponRange WeaponRange;
[InspectableField, JsonProperty("caliber"), Key(22)]
public WeaponCaliber WeaponCaliber;
[InspectableField, JsonProperty("weaponType"), Key(23)]
public WeaponType WeaponType;
[InspectableField, JsonProperty("fireTypes"), Key(24)]
public WeaponFireType WeaponFireTypes;
[InspectableField, JsonProperty("modifiers"), Key(25)]
public WeaponModifiers WeaponModifiers;
}
[RethinkTable("Items"), Inspectable, MessagePackObject, JsonObject(MemberSerialization.OptIn)]

View file

@ -272,144 +272,12 @@ public class ItemManager
return result;
}
// public Entity CreateEntity(Guid zoneID, Guid corporation, Guid loadout)
// {
// if (!(ItemData.Get(loadout) is LoadoutData loadoutData))
// {
// _logger("Attempted to spawn invalid loadout ID");
// return null;
// }
//
// if (!(ItemData.Get(loadoutData.Hull) is HullData hullData))
// {
// _logger("Attempted to spawn loadout with invalid hull ID");
// return null;
// }
//
// if (!(ItemData.Get(zoneID) is ZoneData zoneData))
// {
// _logger("Attempted to spawn entity with invalid zone ID");
// return null;
// }
//
// if (!(ItemData.Get(corporation) is Corporation corpData))
// {
// _logger("Attempted to spawn entity with invalid corporation ID");
// return null;
// }
//
// var gearData = loadoutData.Gear
// .Take(hullData.Hardpoints.Count)
// .Where(id => id != Guid.Empty)
// .Select(id => ItemData.Get<GearData>(id))
// .ToArray();
//
// if (gearData.Any(g=>g==null))
// {
// _logger("Attempted to spawn loadout with invalid gear ID");
// return null;
// }
//
// var gear = gearData
// .Select(gd => CreateInstance(gd.ID, GlobalData.StartingGearQualityMin, GlobalData.StartingGearQualityMax))
// .ToArray();
//
// if (gear.Any(g=>g==null))
// return null;
//
// foreach(var g in gear)
// ItemData.Add(g);
//
// var cargoData = loadoutData.CompoundCargo
// .SelectMany(x => Enumerable.Repeat(ItemData.Get<CraftedItemData>(x.Key), x.Value))
// .ToArray();
//
// if (cargoData.Any(g=>g==null))
// {
// _logger("Attempted to spawn loadout with invalid cargo ID");
// return null;
// }
//
// var cargo = cargoData
// .Select(gd => CreateInstance(gd.ID, GlobalData.StartingGearQualityMin, GlobalData.StartingGearQualityMax))
// .ToArray();
//
// if (cargo.Any(g=>g==null))
// return null;
//
// foreach(var c in cargo)
// ItemData.Add(c);
//
// var simpleCargo = loadoutData.SimpleCargo?
// .Select(x => CreateInstance(x.Key, x.Value))
// .ToArray() ?? new SimpleCommodity[0];
//
// if (simpleCargo.Any(g=>g==null))
// return null;
//
// var hull = CreateInstance(loadoutData.Hull, GlobalData.StartingGearQualityMin, GlobalData.StartingGearQualityMax);
//
// if(hull==null)
// return null;
//
// // Get target zone
// var zone = _zones[zoneID];
//
// if (hullData.HullType == HullType.Ship)
// {
// var entity = CreateShip(hull.ID, gear.Select(g => g.ID),
// cargo.Select(c => c.ID).Concat(simpleCargo.Select(c => c.ID)), zone, corporation, Guid.Empty, loadoutData.Name);
// entity.Active = true;
// return entity;
// }
//
// if (hullData.HullType == HullType.Station)
// {
// var distance = lerp(.2f, .8f, Random.NextFloat()) * zoneData.Radius;
// var orbit = new OrbitData
// {
// Context = this,
// Distance = new ReactiveProperty<float>(distance),
// Parent = zone.Orbits.Values.Select(o=>o.Data)
// .First(orbitData => orbitData.Parent == Guid.Empty).ID,
// Phase = Random.NextFloat()
// };
// zone.AddOrbit(orbit);
//
// var entity = new OrbitalEntity(this, hull.ID, gear.Select(g => g.ID),
// cargo.Select(c => c.ID).Concat(simpleCargo.Select(c => c.ID)), orbit.ID, zone, corporation)
// {
// Name = $"{loadoutData.Name} {Random.NextInt(1,255):X}",
// Temperature = 293,
// Population = 4
// };
// entity.Active = true;
// var parentCorp = ItemData.Get<MegaCorporation>(corpData.Parent);
// foreach (var attribute in parentCorp.Personality)
// entity.Personality[attribute.Key] = attribute.Value;
// ItemData.Add(entity);
//
// zone.Entities[entity.ID] = entity;
// return entity;
// }
//
// return null;
// }
//
// public Ship CreateShip(Guid hull, IEnumerable<Guid> gear, IEnumerable<Guid> cargo, Zone zone, Guid corporation, Guid homeEntity, string typeName)
// {
//
// var ship = new Ship(this, hull, gear, cargo, zone, corporation)
// {
// Name = $"{typeName} {Random.NextInt(1,255):X}",
// HomeEntity = homeEntity
// };
// ItemData.Add(ship);
//
// zone.Entities[ship.ID] = ship;
// return ship;
// }
public int GetPrice(CraftedItemInstance item)
{
var data = GetData(item);
return (int) (GameplaySettings.QualityPriceModifier.Evaluate(item.Quality) * data.Price);
}
public SimpleCommodity CreateInstance(SimpleCommodityData item, int count)
{
if (item != null)

View file

@ -11,7 +11,7 @@ public class LoadoutGenerator
public ItemManager ItemManager { get; }
public Sector Sector { get; }
public SectorZone Zone { get; }
public MegaCorporation Faction { get; }
public Faction Faction { get; }
public float PriceExponent { get; }
public LoadoutGenerator(
@ -19,7 +19,7 @@ public class LoadoutGenerator
ItemManager itemManager,
Sector sector,
SectorZone zone,
MegaCorporation faction,
Faction faction,
float priceExponent)
{
Random = random;
@ -48,6 +48,38 @@ public class LoadoutGenerator
return EntitySerializer.Pack(entity);
}
public EntityPack GenerateStationLoadout()
{
var hullData = RandomHull(HullType.Station);
var hull = ItemManager.CreateInstance(hullData) as EquippableItem;
var entity = new OrbitalEntity(ItemManager, null, hull, Guid.Empty, ItemManager.GameplaySettings.DefaultEntitySettings);
entity.Faction = Faction;
OutfitEntity(entity);
var emptyShape = entity.UnoccupiedSpace;
var dockingBayData = RandomItem<DockingBayData>(item => item.Shape.FitsWithin(emptyShape, out _, out _));
if (dockingBayData == null) throw new InvalidLoadoutException("No compatible docking bay found for station!");
dockingBayData.Shape.FitsWithin(emptyShape, out var cargoRotation, out var cargoPosition);
var dockingBay = ItemManager.CreateInstance(dockingBayData) as EquippableItem;
dockingBay.Rotation = cargoRotation;
if (!entity.TryEquip(dockingBay, cargoPosition))
{
throw new InvalidLoadoutException("Failed to equip selected docking bay!");
}
var cargo = entity.CargoBays.First();
var inventory = RandomItems<EquippableItemData>(16, data => !(data is CargoBayData));
foreach (var item in inventory)
{
var instance = ItemManager.CreateInstance(item);
cargo.TryStore(instance);
}
return EntitySerializer.Pack(entity);
}
public HullData RandomHull(HullType type)
{
return ItemManager.ItemData.GetAll<HullData>()
@ -55,13 +87,13 @@ public class LoadoutGenerator
.WeightedRandomElements(ref Random,
item =>
(Faction == null || 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
Zone.Distance[Sector.HomeZones[ItemManager.ItemData.Get<Faction>(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
public T[] RandomItems<T>(int count, Predicate<T> filter = null) where T : EquippableItemData
{
return ItemManager.ItemData.GetAll<T>()
.Where(item => Sector.ContainsFaction(item.Manufacturer) &&
@ -69,11 +101,16 @@ public class LoadoutGenerator
(filter?.Invoke(item) ?? true))
.WeightedRandomElements(ref Random, item =>
(Faction == null || 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
item.Shape.Coordinates.Length * item.Shape.Coordinates.Length / // Prioritize larger items
Zone.Distance[Sector.HomeZones[ItemManager.ItemData.Get<Faction>(item.Manufacturer)]] / // Penalize distance to manufacturer headquarters
pow(item.Price, PriceExponent), // Penalize item price to a controllable degree
1
).FirstOrDefault();
count
);
}
public T RandomItem<T>(Predicate<T> filter = null) where T : EquippableItemData
{
return RandomItems(1, filter).FirstOrDefault();
}
public T RandomItem<T>(HardpointData hardpoint, Predicate<T> filter = null) where T : EquippableItemData
@ -88,7 +125,7 @@ public class LoadoutGenerator
var hullData = ItemManager.GetData(entity.Hull) as HullData;
foreach (var v in hullData.Shape.Coordinates) entity.HullConductivity[v.x, v.y] = true;
var previousItems = new List<EquippableItemData>();
foreach (var hardpoint in hullData.Hardpoints)
foreach (var hardpoint in hullData.Hardpoints.OrderByDescending(h=>h.Shape.Coordinates.Length))
{
if (hardpoint.Type == HardpointType.ControlModule)
{
@ -103,7 +140,7 @@ public class LoadoutGenerator
}
else
{
// If a previously selected item fits, use that one
// If a previously selected item fits, use that one (this is why we must process larger hardpoints first)
var itemData = previousItems
.FirstOrDefault(i => i.HardpointType == hardpoint.Type && i.Shape.FitsWithin(hardpoint.Shape, hardpoint.Rotation, out _));
itemData ??= RandomItem<GearData>(hardpoint);
@ -121,26 +158,31 @@ public class LoadoutGenerator
}
}
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 emptyShape = entity.UnoccupiedSpace;
var cargoData = RandomItem<CargoBayData>(item =>
!(item is DockingBayData) &&
item.Shape.FitsWithin(emptyShape, out _, out _));
if (cargoData == null) throw new InvalidLoadoutException("No compatible cargo bay found for entity!");
cargoData.Shape.FitsWithin(emptyShape, out var cargoRotation, out var cargoPosition);
var cargo = ItemManager.CreateInstance(cargoData) as EquippableItem;
cargo.Rotation = cargoRotation;
if (!entity.TryEquip(cargo, cargoPosition))
throw new InvalidLoadoutException("Failed to equip selected cargo bay!");
emptyShape = entity.UnoccupiedSpace;
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!");
capacitorData.Shape.FitsWithin(emptyShape, out var capacitorRotation, out var capacitorPosition);
var capacitor = ItemManager.CreateInstance(capacitorData) as EquippableItem;
capacitor.Rotation = capacitorRotation;
if (!entity.TryEquip(capacitor, capacitorPosition))
{
throw new InvalidLoadoutException("Failed to equip selected capacitor!");
}
}
}

View file

@ -12,18 +12,18 @@ using Random = Unity.Mathematics.Random;
public class Sector
{
public Dictionary<MegaCorporation, SectorZone> HomeZones = new Dictionary<MegaCorporation, SectorZone>();
public Dictionary<MegaCorporation, SectorZone> BossZones = new Dictionary<MegaCorporation, SectorZone>();
public Dictionary<Faction, SectorZone> HomeZones = new Dictionary<Faction, SectorZone>();
public Dictionary<Faction, SectorZone> BossZones = new Dictionary<Faction, SectorZone>();
public SectorGenerationSettings Settings { get; }
public MegaCorporation[] Factions { get; }
public Faction[] Factions { get; }
public SectorZone[] Zones { get; }
public SectorZone Entrance { get; }
public SectorZone Exit { get; }
private HashSet<Guid> _containedFactions;
private SectorZone[] _exitPath;
private Dictionary<MegaCorporation, MarkovNameGenerator> _nameGenerators = new Dictionary<MegaCorporation, MarkovNameGenerator>();
private Dictionary<Faction, MarkovNameGenerator> _nameGenerators = new Dictionary<Faction, MarkovNameGenerator>();
public SectorZone[] ExitPath
{
@ -36,7 +36,7 @@ public class Sector
public Sector(DatabaseCache database, SavedGame savedGame)
{
Settings = savedGame.Settings;
Factions = savedGame.Factions.Select(database.Get<MegaCorporation>).ToArray();
Factions = savedGame.Factions.Select(database.Get<Faction>).ToArray();
Zones = savedGame.Zones.Select(zone =>
{
return new SectorZone
@ -70,7 +70,7 @@ public class Sector
public Sector(SectorGenerationSettings settings, DatabaseCache database, uint seed = 0, Action<string> progressCallback = null, float minLineSeparation = .01f)
{
Settings = settings;
var megas = database.GetAll<MegaCorporation>();
var megas = database.GetAll<Faction>();
var random = new Random(seed == 0 ? (uint) (DateTime.Now.Ticks % uint.MaxValue) : seed);
Factions = megas.OrderBy(x => random.NextFloat()).Take(settings.MegaCount).ToArray();
@ -382,8 +382,8 @@ public class SectorZone
public List<SectorZone> AdjacentZones = new List<SectorZone>();
public int Isolation;
public Dictionary<SectorZone, int> Distance;
public MegaCorporation[] Factions;
public MegaCorporation Owner;
public Faction[] Factions;
public Faction Owner;
public Zone Contents;
public ZonePack PackedContents;
}

View file

@ -134,6 +134,7 @@ public class GameplaySettings
{
public EntitySettings DefaultEntitySettings;
public RarityTier[] Tiers;
public ExponentialLerp QualityPriceModifier;
public float DefaultShutdownPerformance = .25f;
public float SevereHeatstrokeRiskThreshold = .25f;
public float WormholeDepth = 1000;

View file

@ -221,14 +221,22 @@ public static class ZoneGenerator
return planetData;
}).ToList();
if (sectorZone.Owner != null)
var nearestFaction = sector.Factions.MinBy(f => sector.HomeZones[f].Distance[sectorZone]);
var nearestFactionHomeZone = sector.HomeZones[nearestFaction];
var factionPresence = nearestFaction.InfluenceDistance - nearestFactionHomeZone.Distance[sectorZone];
var loadoutGenerator = new LoadoutGenerator(ref random, itemManager, sector, sectorZone, nearestFaction, 1);
for (int i = 0; i < factionPresence; i++)
{
var loadoutGenerator = new LoadoutGenerator(ref random, itemManager, sector, sectorZone, sectorZone.Owner, 1);
for (int i = 0; i < 3; i++)
{
pack.Entities.Add(loadoutGenerator.GenerateShipLoadout());
}
pack.Entities.Add(loadoutGenerator.GenerateShipLoadout());
}
var replacePlanet = pack.Planets.MinBy(p => p.Mass.Value);
pack.Planets.Remove(replacePlanet);
var stationOrbit = replacePlanet.Orbit;
var station = loadoutGenerator.GenerateStationLoadout();
((OrbitalEntityPack) station).Orbit = stationOrbit;
pack.Entities.Add(station);
return pack;
}