riversong code showcase
This commit is contained in:
126
Source/Riversong/Game/World/Population/PopulationNeedsSystem.cs
Normal file
126
Source/Riversong/Game/World/Population/PopulationNeedsSystem.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public class PopulationNeedsSystem : GameSystem, IInitializable, IDisposable, IUpdatable
|
||||
{
|
||||
private const float MaxHappinessScoreChangeRate = 0.1f;
|
||||
|
||||
[InjectService]
|
||||
private ISignalBus _signalBus;
|
||||
|
||||
[InjectService]
|
||||
private IEntityCache _entityCache;
|
||||
|
||||
[InjectService]
|
||||
private World _world;
|
||||
|
||||
[InjectService]
|
||||
private GameConfig _config;
|
||||
|
||||
public PopulationNeedsSystem(IServiceLocator serviceLocator) : base(serviceLocator)
|
||||
{
|
||||
}
|
||||
|
||||
public UniTask InitializeAsync()
|
||||
{
|
||||
_signalBus.Subscribe<EndOfWeekSignal>(OnEndOfWeek);
|
||||
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_signalBus.Unsubscribe<EndOfWeekSignal>(OnEndOfWeek);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_world.TimeState.DayNightCycleStep != DayNightCycleStep.Day) return;
|
||||
|
||||
foreach (var house in _entityCache.GetHouses())
|
||||
{
|
||||
ref var needsState = ref house.GetNeedsStateRW();
|
||||
ref var storage = ref house.GetStorageRW();
|
||||
|
||||
var targetHappiness = 1f;
|
||||
var happinessScore = 0;
|
||||
var maxHappinessScore = 0;
|
||||
needsState.AllNeedsMet = true;
|
||||
|
||||
for (var i = 0; i < needsState.Needs.Length; i++)
|
||||
{
|
||||
var need = needsState.Needs[i];
|
||||
|
||||
if (need.TierIndex > house.TierIndex) break;
|
||||
if (need.Type != PopulationNeedType.Product) throw new NotImplementedException();
|
||||
|
||||
if (need.Current < need.YieldOnFetch)
|
||||
{
|
||||
var productCount = storage.AvailableNow(need.ProductHandle);
|
||||
if (productCount > 0)
|
||||
{
|
||||
storage.Take(need.ProductHandle, productCount);
|
||||
need.Current += (ushort)math.min(productCount * need.YieldOnFetch, ushort.MaxValue);
|
||||
}
|
||||
}
|
||||
|
||||
var needMet = need.Current > 0;
|
||||
if (needMet) happinessScore += need.HappinessScore;
|
||||
|
||||
maxHappinessScore += need.HappinessScore;
|
||||
|
||||
needsState.AllNeedsMet &= needMet;
|
||||
needsState.Needs[i] = need;
|
||||
}
|
||||
|
||||
if (maxHappinessScore > 0)
|
||||
{
|
||||
needsState.MaxHappinessScore += MaxHappinessScoreChangeRate * Time.deltaTime;
|
||||
needsState.MaxHappinessScore = math.min(needsState.MaxHappinessScore, maxHappinessScore);
|
||||
|
||||
targetHappiness = needsState.MaxHappinessScore > 0 ? math.saturate(happinessScore / needsState.MaxHappinessScore) : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
needsState.MaxHappinessScore = 0;
|
||||
}
|
||||
|
||||
needsState.Happiness = Mathf.MoveTowards(needsState.Happiness, targetHappiness, _config.Population.OverallHappinessChangeRate * Time.deltaTime);
|
||||
needsState.Happiness = math.saturate(needsState.Happiness);
|
||||
needsState.OverallHappinessWeight = math.saturate((float)(_world.TimeState.TotalWeeks - house.WeekCreated) / _config.Population.HouseWeightRampUpWeekCount);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEndOfWeek(EndOfWeekSignal signal)
|
||||
{
|
||||
foreach (var house in _entityCache.GetHouses())
|
||||
{
|
||||
ref var needsState = ref house.GetNeedsStateRW();
|
||||
|
||||
if (needsState.AllNeedsMet)
|
||||
needsState.NeedsMetForWeeks++;
|
||||
else
|
||||
needsState.NeedsMetForWeeks = 0;
|
||||
|
||||
for (var i = 0; i < needsState.Needs.Length; i++)
|
||||
{
|
||||
var need = needsState.Needs[i];
|
||||
|
||||
if (need.TierIndex > house.TierIndex) break;
|
||||
if (need.Type != PopulationNeedType.Product) continue;
|
||||
|
||||
if (need.Current >= need.ConsumptionRate)
|
||||
need.Current -= need.ConsumptionRate;
|
||||
else
|
||||
need.Current = 0;
|
||||
|
||||
needsState.Needs[i] = need;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user