2020-12-22 03:13:43 +00:00
/ * This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at https : //mozilla.org/MPL/2.0/. */
using System ;
2020-03-22 19:05:26 +00:00
using System.Collections ;
using System.Collections.Generic ;
using System.Linq ;
2020-05-04 00:07:36 +01:00
using Unity.Mathematics ;
2020-03-22 19:05:26 +00:00
using static Unity . Mathematics . math ;
2020-05-04 00:07:36 +01:00
using float2 = Unity . Mathematics . float2 ;
2020-04-30 02:54:31 +01:00
using Random = Unity . Mathematics . Random ;
2020-05-10 00:16:33 +01:00
using JM.LinqFaster ;
2020-12-01 00:16:11 +00:00
using UniRx ;
2020-05-30 02:44:22 +01:00
using float4 = Unity . Mathematics . float4 ;
2020-03-22 19:05:26 +00:00
2020-12-10 23:20:38 +00:00
public class ItemManager
2020-03-22 19:05:26 +00:00
{
2020-04-30 02:54:31 +01:00
public Random Random = new Random ( ( uint ) ( DateTime . Now . Ticks % uint . MaxValue ) ) ;
2020-12-10 23:20:38 +00:00
// public Dictionary<string, GalaxyMapLayerData> MapLayers = new Dictionary<string, GalaxyMapLayerData>();
// public SimpleCommodityData[] Resources;
// public Dictionary<Guid, List<IController>> CorporationControllers = new Dictionary<Guid, List<IController>>();
// public Dictionary<Guid, ZoneDefinition> GalaxyZones;
2020-04-23 03:31:17 +01:00
2020-04-09 07:48:45 +01:00
private Action < string > _logger ;
2020-04-16 03:08:18 +01:00
private double _time ;
private float _deltaTime ;
2020-11-27 22:47:33 +00:00
private Dictionary < Guid , Zone > _zones = new Dictionary < Guid , Zone > ( ) ;
2020-12-20 03:04:52 +00:00
2020-11-27 22:47:33 +00:00
// private Guid _forceLoadZone;
2020-05-12 01:42:13 +01:00
2020-12-10 23:20:38 +00:00
// public GlobalData GlobalData => _globalData ?? (_globalData = ItemData.GetAll<GlobalData>().FirstOrDefault());
2021-03-31 04:07:11 +01:00
public CultCache ItemData { get ; }
2020-12-10 23:20:38 +00:00
public GameplaySettings GameplaySettings { get ; }
2020-05-10 00:16:33 +01:00
2021-04-09 14:01:34 +01:00
// public double Time
// {
// get => _time;
// set
// {
// _deltaTime = (float) (value - _time);
// _time = value;
// //Log($"GameContext delta time: {_deltaTime}");
// }
// }
2020-04-16 03:08:18 +01:00
2020-04-09 07:48:45 +01:00
// private readonly Dictionary<CraftedItemData, int> Tier = new Dictionary<CraftedItemData, int>();
2020-03-27 01:53:03 +00:00
2021-03-31 04:07:11 +01:00
public ItemManager ( CultCache itemData , GameplaySettings settings , Action < string > logger )
2020-03-27 01:53:03 +00:00
{
2020-12-10 23:20:38 +00:00
ItemData = itemData ;
2020-12-20 03:04:52 +00:00
GameplaySettings = settings ;
2020-04-09 07:48:45 +01:00
_logger = logger ;
2020-04-16 03:08:18 +01:00
}
public void Log ( string s )
{
_logger ( s ) ;
}
2020-12-01 00:16:11 +00:00
// public void Update()
// {
// foreach(var zone in _zones.Values)
// zone.Update((float) Time, _deltaTime);
//
// foreach (var corporation in Cache.GetAll<Corporation>())
// {
// foreach (var tasks in corporation.Tasks
// .Select(id => Cache.Get<AgentTask>(id)) // Fetch the tasks from the database cache
// .Where(task => !task.Reserved) // Filter out tasks that have already been reserved
// .GroupBy(task => task.Type)) // Group tasks by type
// {
// // Create a list of available controllers for this task type
// var availableControllers = CorporationControllers[corporation.ID]
// .Where(controller => controller.Available && controller.TaskType == tasks.Key).ToList();
//
// // Iterate over the highest priority tasks for which controllers are available
// foreach (var task in tasks.OrderByDescending(task => task.Priority).Take(availableControllers.Count))
// {
// // Find the nearest controller for this task
// IController nearestController = availableControllers[0];
// List<ZoneDefinition> nearestControllerPath = FindPath(GalaxyZones[availableControllers.First().Zone.Data.ID], GalaxyZones[task.Zone], true);
// foreach (var controller in availableControllers.Skip(1))
// {
// var path = FindPath(GalaxyZones[controller.Zone.Data.ID], GalaxyZones[task.Zone], true);
// if (path.Count < nearestControllerPath.Count)
// {
// nearestControllerPath = path;
// nearestController = controller;
// }
// }
// task.Reserved = true;
// nearestController.AssignTask(task.ID);
// }
// }
// }
//
// }
2020-05-28 04:50:40 +01:00
2020-04-09 07:48:45 +01:00
// public int ItemTier(CraftedItemData itemData)
// {
// if (Tier.ContainsKey(itemData)) return Tier[itemData];
//
// Tier[itemData] = itemData.Ingredients.Keys.Max(ci => _cache.Get<ItemData>(ci) is CraftedItemData craftableIngredient ? ItemTier(craftableIngredient) : 0);
//
// return Tier[itemData];
// }
2020-03-22 19:05:26 +00:00
public SimpleCommodityData GetData ( SimpleCommodity item )
{
2021-04-18 05:13:20 +01:00
return item . Data . Value as SimpleCommodityData ;
2020-03-22 19:05:26 +00:00
}
public CraftedItemData GetData ( CraftedItemInstance item )
{
2021-04-18 05:13:20 +01:00
return item . Data . Value as CraftedItemData ;
2020-03-22 19:05:26 +00:00
}
2021-04-18 05:13:20 +01:00
public EquippableItemData GetData ( EquippableItem item )
2020-03-22 19:05:26 +00:00
{
2021-04-18 05:13:20 +01:00
return item . Data . Value as EquippableItemData ;
2020-03-22 19:05:26 +00:00
}
public float GetMass ( ItemInstance item )
{
2021-04-18 05:13:20 +01:00
return item switch
2020-03-22 19:05:26 +00:00
{
2021-04-18 05:13:20 +01:00
CraftedItemInstance _ = > item . Data . Value . Mass ,
SimpleCommodity commodity = > item . Data . Value . Mass * commodity . Quantity ,
_ = > 0
} ;
2020-03-22 19:05:26 +00:00
}
2020-06-05 04:16:33 +01:00
public float GetThermalMass ( ItemInstance item )
2020-03-22 19:05:26 +00:00
{
2021-04-18 05:13:20 +01:00
var data = item . Data . Value ;
return item switch
2020-03-22 19:05:26 +00:00
{
2021-04-18 05:13:20 +01:00
CraftedItemInstance _ = > data . Mass * data . SpecificHeat ,
SimpleCommodity commodity = > data . Mass * data . SpecificHeat * commodity . Quantity ,
_ = > 0
} ;
2020-03-22 19:05:26 +00:00
}
// Returns stat when not equipped
2020-12-10 23:20:38 +00:00
public float Evaluate ( PerformanceStat stat , EquippableItem item )
2020-03-22 19:05:26 +00:00
{
2021-03-22 05:22:31 +00:00
var data = GetData ( item ) ;
var quality = pow ( item . Quality , stat . QualityExponent ) ;
var durabilityExponent = lerp (
GameplaySettings . DurabilityQualityMin ,
GameplaySettings . DurabilityQualityMax ,
pow ( item . Quality , GameplaySettings . DurabilityQualityExponent ) ) ;
var durability = pow ( item . Durability / data . Durability , durabilityExponent * stat . DurabilityExponentMultiplier ) ;
var result = lerp ( stat . Min , stat . Max , quality * durability ) ;
2021-03-27 10:03:24 +00:00
if ( float . IsNaN ( result ) )
throw new InvalidOperationException ( $"Performance Stat on {data.Name} evaluating as NaN: input data is invalid! Durability: {item.Durability} / {data.Durability}" ) ;
2020-03-22 19:05:26 +00:00
return result ;
2021-03-22 05:22:31 +00:00
2020-03-22 19:05:26 +00:00
}
2020-05-25 03:05:30 +01:00
2021-03-20 04:20:17 +00:00
public int GetPrice ( CraftedItemInstance item )
{
var data = GetData ( item ) ;
return ( int ) ( GameplaySettings . QualityPriceModifier . Evaluate ( item . Quality ) * data . Price ) ;
}
2020-12-12 03:42:58 +00:00
public SimpleCommodity CreateInstance ( SimpleCommodityData item , int count )
2020-03-22 19:05:26 +00:00
{
if ( item ! = null )
2020-06-02 07:01:03 +01:00
{
var newItem = new SimpleCommodity
2020-03-22 19:05:26 +00:00
{
2021-04-18 05:13:20 +01:00
Data = new DatabaseLink < ItemData > { LinkID = item . ID } ,
2020-05-25 03:05:30 +01:00
Quantity = count
2020-03-22 19:05:26 +00:00
} ;
2020-12-10 23:20:38 +00:00
//ItemData.Add(newItem);
2020-06-02 07:01:03 +01:00
return newItem ;
}
2020-03-22 19:05:26 +00:00
2020-04-09 07:48:45 +01:00
_logger ( "Attempted to create Simple Commodity instance using missing or incorrect item id" ) ;
return null ;
2020-03-22 19:05:26 +00:00
}
2021-01-19 01:22:56 +00:00
public ItemInstance Instantiate ( ItemInstance item )
{
2021-04-18 05:13:20 +01:00
var data = item . Data . Value ;
2021-01-19 01:22:56 +00:00
if ( data is CraftedItemData c )
2021-01-27 00:05:30 +00:00
{
2021-03-08 02:57:38 +00:00
var i = CreateInstance ( c ) ;
2021-01-27 00:05:30 +00:00
i . Rotation = item . Rotation ;
return i ;
}
2021-01-19 01:22:56 +00:00
if ( item is SimpleCommodity s )
2021-01-27 00:05:30 +00:00
{
var i = CreateInstance ( data as SimpleCommodityData , s . Quantity ) ;
i . Rotation = item . Rotation ;
return i ;
}
2021-01-19 01:22:56 +00:00
return null ;
}
2021-03-27 10:03:24 +00:00
public CraftedItemInstance CreateInstance ( CraftedItemData item , float quality )
{
if ( item is EquippableItemData equippableItemData )
{
2021-04-18 05:13:20 +01:00
return new EquippableItem
2021-03-27 10:03:24 +00:00
{
2021-04-18 05:13:20 +01:00
Data = new DatabaseLink < ItemData > { LinkID = item . ID } , Quality = quality , Durability = equippableItemData . Durability
2021-03-27 10:03:24 +00:00
} ;
}
var newCommodity = new CompoundCommodity
{
2021-04-18 05:13:20 +01:00
Data = new DatabaseLink < ItemData > { LinkID = item . ID } ,
2021-03-27 10:03:24 +00:00
Quality = quality
} ;
return newCommodity ;
}
2020-03-22 19:05:26 +00:00
2021-03-08 02:57:38 +00:00
public CraftedItemInstance CreateInstance ( CraftedItemData item )
2020-03-22 19:05:26 +00:00
{
if ( item = = null )
{
2022-07-10 02:53:09 +01:00
throw new NullReferenceException ( "Attempted to create crafted item instance using missing or incorrect item data!" ) ;
2020-04-09 07:48:45 +01:00
return null ;
2020-03-22 19:05:26 +00:00
}
2021-03-08 02:57:38 +00:00
var quality = Random . NextFloat ( ) ;
var tier = GameplaySettings . Tiers [ 0 ] ;
foreach ( var t in GameplaySettings . Tiers )
{
if ( t . Rarity > quality )
tier = t ;
}
2020-03-22 19:05:26 +00:00
2021-03-27 10:03:24 +00:00
return CreateInstance ( item , tier . Quality ) ;
2020-03-22 19:05:26 +00:00
}
2020-05-25 03:05:30 +01:00
2021-03-08 02:57:38 +00:00
public ( RarityTier tier , int upgrades ) GetTier ( CraftedItemInstance item )
{
var tier = GameplaySettings . Tiers [ 0 ] ;
foreach ( var t in GameplaySettings . Tiers )
if ( item . Quality + . 001f > t . Quality )
tier = t ;
int upgrades = ( int ) ( ( item . Quality - tier . Quality ) / . 0499f ) ;
return ( tier , upgrades ) ;
}
2020-04-16 03:08:18 +01:00
}