riversong code showcase
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user