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,217 @@
using System;
using System.Collections.Generic;
using System.Text;
using Cysharp.Threading.Tasks;
namespace DanieleMarotta.RiversongCodeShowcase
{
public class BuildMenuUIController : UIControllerSystem<BuildMenuUIView>, IUpdatable, IDisposable
{
[InjectService]
private IGameDatabase _gameDatabase;
[InjectService]
private IEditingService _editingService;
[InjectService]
private ISignalBus _signalBus;
[InjectService]
private World _world;
[InjectService]
private TextFormatHelper _textFormatHelper;
[InjectService]
private ICancelAction _cancelAction;
private BuildMenuModel _model;
private List<BuildingDefinition> _pendingBuildings = new();
private List<BuildingDefinition> _pendingTeasers = new();
private bool _isPlayingButtonAnimation;
private Action _onUnlockAnimationStarted;
public BuildMenuUIController(IServiceLocator serviceLocator) : base(serviceLocator)
{
}
protected override BuildMenuUIView View => UIRoot.GetView<BuildMenuUIView>();
public override async UniTask InitializeAsync()
{
await base.InitializeAsync();
var buildings = _gameDatabase.OfType<BuildingDefinition>();
buildings.Sort((x, y) => x.UIOrder.CompareTo(y.UIOrder));
_model = new BuildMenuModel();
var sb = new StringBuilder();
foreach (var building in buildings)
{
if (_world.UnlocksState.TryGetBuildingUnlock(building, out var unlockId))
{
var unlock = _gameDatabase.WithId<UnlockDefinition>(unlockId);
_textFormatHelper.FormatUnlockConditions(unlock, sb);
}
var buildingModel = new BuildMenuBuildingModel
{
Building = building,
UnlockConditions = sb.ToString()
};
_model.Buildings.Add(buildingModel);
sb.Clear();
}
View.SetModel(_model);
View.ButtonClick += OnButtonClick;
_editingService.ActiveToolChanged += OnActiveToolChanged;
_signalBus.Subscribe<UnlockUnlockedSignal>(OnUnlockUnlocked);
foreach (var unlockId in _world.UnlocksState.Unlocked)
{
var unlock = _gameDatabase.WithId<UnlockDefinition>(unlockId);
OnUnlockUnlocked(unlock);
}
_cancelAction.AddHandler(
(int)CancelActions.CloseBuildMenu,
_ =>
{
if (!View.IsOpen()) return false;
CloseView();
return true;
});
}
public void Dispose()
{
View.ButtonClick -= OnButtonClick;
_editingService.ActiveToolChanged -= OnActiveToolChanged;
_signalBus.Unsubscribe<UnlockUnlockedSignal>(OnUnlockUnlocked);
}
private void OnButtonClick(BuildingDefinition building)
{
if (!_world.UnlocksState.UnlockedBuildings.Contains(building.RuntimeId)) return;
var buildTool = _editingService.EditingState.BuildTool;
buildTool.Building = building;
_editingService.ActivateTool(buildTool);
}
private void OnActiveToolChanged(EditTool tool)
{
BuildingDefinition selectedBuilding = null;
if (tool is BuildTool buildTool) selectedBuilding = buildTool.Building;
_model.SelectedBuilding = selectedBuilding;
}
private void OnUnlockUnlocked(UnlockDefinition unlock)
{
if (unlock.Building)
{
_pendingBuildings.Add(unlock.Building);
_pendingBuildings.Sort();
}
if (unlock.TeasedBuildings.Count > 0)
{
foreach (var teasedBuilding in unlock.TeasedBuildings) _pendingTeasers.Add(teasedBuilding);
_pendingTeasers.Sort();
}
}
private void OnUnlockUnlocked(UnlockUnlockedSignal signal)
{
OnUnlockUnlocked(signal.Unlock);
}
public void Update()
{
UpdateModels();
UpdateButtons();
}
private void UpdateModels()
{
foreach (var buildingModel in _model.Buildings) buildingModel.IsUnlocked = _world.UnlocksState.UnlockedBuildings.Contains(buildingModel.Building.RuntimeId);
}
private void UpdateButtons()
{
if (!View.IsOpen() || _isPlayingButtonAnimation || (_pendingBuildings.Count <= 0 && _pendingTeasers.Count <= 0)) return;
if (_pendingBuildings.Count > 0)
{
var building = _pendingBuildings[0];
_pendingBuildings.RemoveAt(0);
_ = UnlockButtonAsync(building);
return;
}
while (_pendingTeasers.Count > 0)
{
var teaserBuilding = _pendingTeasers[0];
_pendingTeasers.RemoveAt(0);
if (_world.UnlocksState.UnlockedBuildings.Contains(teaserBuilding.RuntimeId)) continue;
_ = CreateTeaserButtonAsync(teaserBuilding);
break;
}
}
private async UniTask UnlockButtonAsync(BuildingDefinition building)
{
_isPlayingButtonAnimation = true;
try
{
_onUnlockAnimationStarted ??= () => _signalBus.Raise(new BuildMenuButtonUnlockAnimationStartedSignal());
await View.UnlockOrCreateUnlockedButtonAsync(building, _onUnlockAnimationStarted);
await UniTask.WaitForSeconds(0.5f, true);
}
finally
{
_isPlayingButtonAnimation = false;
}
}
private async UniTask CreateTeaserButtonAsync(BuildingDefinition building)
{
_isPlayingButtonAnimation = true;
try
{
await View.CreateTeaserButtonAsync(building);
await UniTask.WaitForSeconds(0.5f, true);
}
finally
{
_isPlayingButtonAnimation = false;
}
}
protected override void CloseView(bool animate = true)
{
if (_isPlayingButtonAnimation) return;
base.CloseView(animate);
}
}
}