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:
parent
28f08398a1
commit
fd81bf267e
33 changed files with 1640 additions and 1077 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue