riversong code showcase
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
[UpdateAfter(typeof(PopulationNeedsSystem))]
|
||||
public class PopulationUpdateSystem : GameSystem, IInitializable, IUpdatable
|
||||
{
|
||||
[InjectService]
|
||||
private ISignalBus _signalBus;
|
||||
|
||||
[InjectService]
|
||||
private World _world;
|
||||
|
||||
[InjectService]
|
||||
private IEntityCache _entityCache;
|
||||
|
||||
[InjectService]
|
||||
private GameConfig _config;
|
||||
|
||||
public PopulationUpdateSystem(IServiceLocator serviceLocator) : base(serviceLocator)
|
||||
{
|
||||
}
|
||||
|
||||
public UniTask InitializeAsync()
|
||||
{
|
||||
_world.PopulationState.Happiness = _config.Population.InitialeOverallHappiness;
|
||||
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_world.TimeState.DayNightCycleStep != DayNightCycleStep.Day) return;
|
||||
|
||||
UpdateOverallHappiness();
|
||||
UpdatePopulation();
|
||||
}
|
||||
|
||||
private void UpdateOverallHappiness()
|
||||
{
|
||||
var targetHappiness = 0f;
|
||||
var totalWeight = 0f;
|
||||
|
||||
foreach (var house in _entityCache.GetHouses())
|
||||
{
|
||||
ref var needsState = ref house.GetNeedsStateRW();
|
||||
targetHappiness += needsState.OverallHappinessWeight * needsState.Happiness;
|
||||
totalWeight += needsState.OverallHappinessWeight;
|
||||
}
|
||||
|
||||
if (totalWeight > 0) targetHappiness = math.saturate(targetHappiness / totalWeight);
|
||||
|
||||
var grace = _world.TimeState.TotalWeeks < _config.Population.GraceWeekCount;
|
||||
if (grace) targetHappiness = math.max(targetHappiness, _config.Population.GraceMinHappiness);
|
||||
|
||||
var populationState = _world.PopulationState;
|
||||
var delta = math.abs(targetHappiness - populationState.Happiness);
|
||||
const float halfOnePercent = 0.005f;
|
||||
populationState.Sentiment = delta > halfOnePercent ? math.sign(targetHappiness - populationState.Happiness) : 0;
|
||||
populationState.Happiness = Mathf.MoveTowards(populationState.Happiness, targetHappiness, _config.Population.OverallHappinessChangeRate * Time.deltaTime);
|
||||
populationState.Happiness = math.saturate(populationState.Happiness);
|
||||
}
|
||||
|
||||
private void UpdatePopulation()
|
||||
{
|
||||
var populationState = _world.PopulationState;
|
||||
|
||||
populationState.PopulationCapacity = 0;
|
||||
foreach (var house in _entityCache.GetHouses()) populationState.PopulationCapacity += house.PopulationCapacity;
|
||||
|
||||
var growthRate = _config.Population.GrowthRatePeakValue * _config.Population.GrowthRateCurve.Evaluate(populationState.Happiness);
|
||||
if (populationState.Sentiment > 0) growthRate = math.max(growthRate, 0);
|
||||
|
||||
populationState.GrowthAccumulator += growthRate * Time.deltaTime;
|
||||
if (math.abs(populationState.GrowthAccumulator) < 1) return;
|
||||
|
||||
var delta = (int)math.sign(populationState.GrowthAccumulator);
|
||||
populationState.GrowthAccumulator -= delta;
|
||||
|
||||
var updatedPopulation = math.clamp(populationState.Population + delta, 0, populationState.PopulationCapacity);
|
||||
if (updatedPopulation == populationState.Population) return;
|
||||
|
||||
populationState.Population = updatedPopulation;
|
||||
_signalBus.Raise(new PopulationChangedSignal(updatedPopulation));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user