OneMoreRoundWeapon.ModelPresentation.cs
using Sandbox;
/// <summary>
/// Presentation-only bridge between generic weapon events and optional model
/// adapters living on spawned view/world model prefabs.
///
/// BaseWeaponModel still owns stock attack/reload/muzzle/brass/tracer behavior.
/// This layer only handles OMR capabilities that BaseWeaponModel does not know
/// about, currently generic manual cycling.
/// </summary>
public partial class OneMoreRoundWeapon
{
private GameObject _adapterViewModel;
private GameObject _adapterWorldModel;
private OMRWeaponModelPresentationAdapter _viewModelPresentationAdapter;
private OMRWeaponModelPresentationAdapter _worldModelPresentationAdapter;
private void BindWeaponModelPresentationEvents()
{
PresentationEvent -= HandleWeaponModelPresentationEvent;
PresentationEvent += HandleWeaponModelPresentationEvent;
}
private void HandleWeaponModelPresentationEvent(
WeaponPresentationEvent presentationEvent
)
{
ResolveWeaponModelPresentationAdapters();
switch ( presentationEvent.Kind )
{
case WeaponPresentationEventKind.CycleStarted:
BeginCycleOnPresentationAdapters();
break;
case WeaponPresentationEventKind.CycleCompleted:
CompleteCycleOnPresentationAdapters();
break;
case WeaponPresentationEventKind.Holstered:
ResetWeaponModelPresentationState();
break;
}
}
private void UpdateWeaponModelPresentation()
{
ResolveWeaponModelPresentationAdapters();
if ( HasOpticProfile )
{
_viewModelPresentationAdapter?.ApplyOpticPresentation(
AimFraction,
IsScopePresentationActive
);
_worldModelPresentationAdapter?.ApplyOpticPresentation(
AimFraction,
IsScopePresentationActive
);
}
else
{
_viewModelPresentationAdapter?.ResetOpticPresentation();
_worldModelPresentationAdapter?.ResetOpticPresentation();
}
if ( !IsCyclePresentationActive )
return;
float progress = CyclePresentationProgress;
_viewModelPresentationAdapter?.UpdateCyclePresentation( progress );
_worldModelPresentationAdapter?.UpdateCyclePresentation( progress );
}
private void BeginCycleOnPresentationAdapters()
{
if ( !HasCycleProfile )
return;
float duration = CycleProfile.Duration;
OMRWeaponCycleKind kind = CycleProfile.Kind;
_viewModelPresentationAdapter?.BeginCyclePresentation(
kind,
duration
);
_worldModelPresentationAdapter?.BeginCyclePresentation(
kind,
duration
);
}
private void CompleteCycleOnPresentationAdapters()
{
_viewModelPresentationAdapter?.CompleteCyclePresentation();
_worldModelPresentationAdapter?.CompleteCyclePresentation();
}
private void ResolveWeaponModelPresentationAdapters()
{
GameObject currentViewModel = ViewModel;
GameObject currentWorldModel = WorldModel;
if ( currentViewModel != _adapterViewModel )
{
_adapterViewModel = currentViewModel;
_viewModelPresentationAdapter = FindPresentationAdapter(
currentViewModel
);
}
if ( currentWorldModel != _adapterWorldModel )
{
_adapterWorldModel = currentWorldModel;
_worldModelPresentationAdapter = FindPresentationAdapter(
currentWorldModel
);
}
}
private static OMRWeaponModelPresentationAdapter FindPresentationAdapter(
GameObject model
)
{
if ( model is null || !model.IsValid )
return null;
return model.Components.Get<OMRWeaponModelPresentationAdapter>(
FindMode.InSelf |
FindMode.InDescendants
);
}
private void ResetWeaponModelPresentationState()
{
_viewModelPresentationAdapter?.ResetCyclePresentation();
_worldModelPresentationAdapter?.ResetCyclePresentation();
_viewModelPresentationAdapter?.ResetOpticPresentation();
_worldModelPresentationAdapter?.ResetOpticPresentation();
_adapterViewModel = null;
_adapterWorldModel = null;
_viewModelPresentationAdapter = null;
_worldModelPresentationAdapter = null;
}
}