riversong code showcase

This commit is contained in:
Daniele Marotta
2026-05-21 15:52:18 +02:00
commit 4c9eea1c02
462 changed files with 23406 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
namespace DanieleMarotta.RiversongCodeShowcase
{
[Service(typeof(IUnlocksService))]
[InitializeAfter(typeof(HouseTierCountTrackingSystem))]
public class UnlocksManagerSystem : GameSystem, IInitializable, IDisposable, IUnlocksService
{
[InjectService]
private IGameDatabase _gameDatabase;
[InjectService]
private ISignalBus _signalBus;
[InjectService]
private IEntityCollection _entityCollection;
[InjectService]
private World _world;
private List<UnlockDefinition> _unlocks;
public UnlocksManagerSystem(IServiceLocator serviceLocator) : base(serviceLocator)
{
}
public UniTask InitializeAsync()
{
_unlocks = _gameDatabase.OfType<UnlockDefinition>();
foreach (var unlock in _unlocks)
if (unlock.Building)
_world.UnlocksState.AddBuildingUnlock(unlock.Building, unlock.RuntimeId);
_signalBus.Subscribe<WorldReadySignal>(OnWorldReady);
_signalBus.Subscribe<BuildingCreatedSignal>(OnBuildingCreated);
_signalBus.Subscribe<BuildingUpgradedSignal>(OnBuildingUpgraded);
return UniTask.CompletedTask;
}
public void Dispose()
{
_signalBus.Unsubscribe<WorldReadySignal>(OnWorldReady);
_signalBus.Unsubscribe<BuildingCreatedSignal>(OnBuildingCreated);
_signalBus.Unsubscribe<BuildingUpgradedSignal>(OnBuildingUpgraded);
}
private void OnWorldReady(WorldReadySignal signal)
{
_ = GrantFreeUnlocksWithDelayAsync();
}
private async UniTask GrantFreeUnlocksWithDelayAsync()
{
await UniTask.WaitForSeconds(2, true);
foreach (var unlock in _unlocks)
if (unlock.Conditions.Count <= 0)
Unlock(unlock);
}
private void OnBuildingCreated(BuildingCreatedSignal signal)
{
TryUnlockAvailableUnlocks();
}
private void OnBuildingUpgraded(BuildingUpgradedSignal signal)
{
TryUnlockAvailableUnlocks();
}
private void TryUnlockAvailableUnlocks()
{
foreach (var unlock in _unlocks)
if (CanUnlock(unlock))
Unlock(unlock);
}
private bool CanUnlock(UnlockDefinition unlock)
{
if (_world.UnlocksState.Unlocked.Contains(unlock.RuntimeId)) return false;
foreach (var condition in unlock.Conditions)
if (!IsConditionSatisfied(condition))
return false;
return true;
}
public void Unlock(UnlockDefinition unlock)
{
if (!_world.UnlocksState.Unlocked.Add(unlock.RuntimeId)) return;
switch (unlock.Type)
{
case UnlockType.UnlockBuilding:
UnlockBuilding(unlock);
break;
case UnlockType.None:
default:
throw new ArgumentOutOfRangeException();
}
_signalBus.Raise(new UnlockUnlockedSignal(unlock));
}
public void UnlockAll()
{
foreach (var unlock in _unlocks) Unlock(unlock);
}
private void UnlockBuilding(UnlockDefinition unlock)
{
var unlocksState = _world.UnlocksState;
var unlockedId = unlock.Building.RuntimeId;
unlocksState.UnlockedBuildings.Add(unlockedId);
unlocksState.TeasedBuildings.Remove(unlockedId);
foreach (var teased in unlock.TeasedBuildings)
{
if (unlocksState.UnlockedBuildings.Contains(teased.RuntimeId)) continue;
unlocksState.TeasedBuildings.Add(teased.RuntimeId);
}
}
private bool IsConditionSatisfied(UnlockCondition condition)
{
switch (condition.Type)
{
case UnlockConditionType.BuildingPlaced:
foreach (Building building in _entityCollection.GetInternalEntityList(typeof(Building)))
if (building.Definition.RuntimeId == condition.Building.RuntimeId)
return true;
return false;
case UnlockConditionType.HouseCountAtTierOrAbove:
var houseCount = 0;
var houseCountsByTier = _world.PopulationState.HouseCountsByTier;
for (var i = condition.MinHouseTierIndex; i < WorldPopulationState.MaxBuildingTier; i++) houseCount += houseCountsByTier[i];
return houseCount >= condition.HouseCount;
case UnlockConditionType.None:
default:
throw new ArgumentOutOfRangeException();
}
}
}
}