Files
butchers-games-test/Assets/Scripts/Game/Core/CoreController.cs
T
Boris Nikolaev 5f1e94b653 add project files
2026-08-14 01:58:31 +03:00

342 lines
7.8 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;
using Ambiance;
using OHM.UnityToolkit.FSM;
using OHM.UnityToolkit.Pooling;
public class CoreController : CoreBehaviour
{
[SerializeField]
public CoreDef def;
[SerializeField]
public CamController cam;
[SerializeField]
public ScoreController scoreController;
[SerializeField]
private Transform dynamicCont;
[SerializeField]
public PickupSkinProvider pickupSkinProvider;
[HideInInspector]
public UnityEvent onWarmup;
[HideInInspector]
public UnityEvent onGameStarted;
[HideInInspector]
public UnityEvent onGameWon;
[HideInInspector]
public UnityEvent onGameOver;
[NonSerialized]
public List<Section> debugForcedLevel;
private List<Section> _currentLevelPrefabs;
private List<Section> previousSectionsToRemove;
[NonSerialized]
public int keyCountToSpawn;
public CoreCurrenciesController currenciesController = new CoreCurrenciesController();
private System.Random random = new System.Random();
private int _currentSeed;
public FiniteStateMachine<GameStateType> GameStateMachine = new FiniteStateMachine<GameStateType>();
public GameStateType GS_WARMUP;
public GameStateType GS_STARTED;
public GameStateType GS_WON;
public GameStateType GS_GAME_OVER;
public float progressionRatio;
private Coroutine _warmupCoroutine;
private PlayerSkinDef _playerSkinDef;
public List<Section> CurrentSections { get; private set; }
public int CurrentSectionIndex { get; private set; }
public List<Section> CurrentLevelPrefabs => _currentLevelPrefabs;
public long CurrentLevelIdx { get; private set; }
public Player CurrentPlayer { get; private set; }
public static event Action<Section, int, int> OnSectionCreated;
public void Awake()
{
GS_WARMUP = new GameStateType
{
startAction = EnterWarmup
};
GS_STARTED = new GameStateType
{
startAction = EnterGame,
updateAction = GameUpdate,
getInputsListenerFunc = GameGetInputsListener
};
GS_WON = new GameStateType
{
startAction = EnterWon
};
GS_GAME_OVER = new GameStateType
{
startAction = EnterGameOver
};
GameStateMachine = new FiniteStateMachine<GameStateType>();
}
private void Update()
{
GameStateMachine.Update();
}
public void Warmup(long levelIdx)
{
bool levelChanged = CurrentLevelIdx != levelIdx;
if (levelChanged)
{
previousSectionsToRemove = ((def.GetProgression().removePreviousSectionsForNextGame && _currentLevelPrefabs != null) ? new List<Section>(_currentLevelPrefabs) : null);
}
int seed;
if (!levelChanged && def.GetProgression().replaySameLevelsAfterGameOver)
{
seed = _currentSeed;
}
else
{
seed = (_currentSeed = random.Next());
}
random = new System.Random(seed);
CurrentLevelIdx = levelIdx;
GameStateMachine.SetState(GS_WARMUP);
}
private void EnterWarmup()
{
Cleanup();
SetupAmbiance();
if (_warmupCoroutine != null)
{
StopCoroutine(_warmupCoroutine);
}
_warmupCoroutine = StartCoroutine(WarmupCoroutine());
}
private IEnumerator WarmupCoroutine()
{
yield return new WaitForEndOfFrame();
GenerateLevel();
yield return CreateCurrentSection();
CurrentPlayer = CreatePlayer();
scoreController.InitScore(CurrentPlayer.richManagePlayer.curScore);
cam.Warmup();
onWarmup.Invoke();
}
public void ChangeRichValueStartRV()
{
CurrentPlayer.richManagePlayer.SetRichPoorValue(base.CoreDef.player.richValueStartABTestStartRich, true);
}
private void SetupAmbiance()
{
int levelIdx = (int)CurrentLevelIdx;
AmbianceController.Instance.SetLevelIdx(levelIdx, onFire: false, forceReload: true);
}
private void Cleanup()
{
scoreController.Reset();
currenciesController.Reset();
CurrentSections = new List<Section>();
CurrentPlayer = null;
PoolsManager.ReleaseAllPooledChildren(dynamicCont);
var children = new List<Transform>();
foreach (Transform child in dynamicCont)
{
children.Add(child);
}
foreach (Transform child in children)
{
PoolsManager.ReleaseObject(child.gameObject);
}
}
public bool IsReadyToPlay()
{
return CurrentPlayer != null && CurrentPlayer.IsReady;
}
public void GenerateLevel()
{
List<Section> generated = LevelGenerator.GenerateLevel(base.CoreDef, CurrentLevelIdx, random, debugForcedLevel, previousSectionsToRemove);
debugForcedLevel = null;
CurrentSectionIndex = 0;
_currentLevelPrefabs = CreateAllSection(generated);
}
private Section CreateSection(Section prefab, Transform pos)
{
Section section = UnityEngine.Object.Instantiate(prefab, dynamicCont);
section.Setup(base.CoreDef);
if (pos != null)
{
section.transform.position = pos.position;
section.transform.rotation = pos.rotation;
}
CurrentSections.Add(section);
return section;
}
private List<Section> CreateAllSection(List<Section> sectionsPrefabs)
{
var result = new List<Section>();
bool turnRight = UnityEngine.Random.Range(0, 1) == 0;
ProgressionDef progression = def.GetProgression();
bool useTurn = progression.useTurn;
int sinceTurn = 0;
for (int i = 0; i < sectionsPrefabs.Count; i++)
{
result.Add(sectionsPrefabs[i]);
if (useTurn && i != 0 && i < sectionsPrefabs.Count - 2 && sinceTurn >= progression.turnEachSection)
{
result.Add(turnRight ? progression.GroundRight : progression.GroundLeft);
result.Add(progression.SafeZone);
sinceTurn = 0;
turnRight = !turnRight;
}
sinceTurn++;
}
return result;
}
private IEnumerator CreateCurrentSection()
{
Transform pos = null;
for (int i = 0; i < _currentLevelPrefabs.Count; i++)
{
Section section = CreateSection(_currentLevelPrefabs[i], pos);
yield return new WaitForEndOfFrame();
pos = section.endLevel;
}
yield return new WaitForEndOfFrame();
}
private Player CreatePlayer()
{
Player player = UnityEngine.Object.Instantiate(_playerSkinDef.prefab, dynamicCont);
player.transform.position = Vector3.zero;
player.onWin = (Action<int>)Delegate.Combine(player.onWin, new Action<int>(Win));
player.onLose = (Action)Delegate.Combine(player.onLose, new Action(GameOver));
player.richManagePlayer.onUpdateScore += OnUpdateScore;
cam.SetTarget(player);
return player;
}
public void SetPlayerSkin(PlayerSkinDef skin)
{
_playerSkinDef = skin;
if (CurrentPlayer == null)
{
return;
}
bool wasShopMode = CurrentPlayer.ShopMode;
UnityEngine.Object.Destroy(CurrentPlayer.gameObject);
CurrentPlayer = CreatePlayer();
if (wasShopMode)
{
CurrentPlayer.ShopSkinMode();
}
}
public void Go()
{
if (IsReadyToPlay())
{
CurrentPlayer.Go();
onGameStarted.Invoke();
GameStateMachine.SetState(GS_STARTED);
}
}
private void EnterGame()
{
UnityEngine.Debug.Log("Enter Game");
cam.Go();
}
private void GameUpdate()
{
}
private IInputsListener GameGetInputsListener()
{
return CurrentPlayer.movePlayer.swerveInput;
}
private void OnUpdateScore(long score)
{
scoreController.UpdateScore(score, CurrentPlayer.movePlayer.transform, ScoreController.ScoreType.DEFAULT_SCORE);
}
private void Win(int multCurrency)
{
scoreController.SetMultCurrency(multCurrency);
cam.Win(true);
GameStateMachine.SetState(GS_WON);
}
private void EnterWon()
{
UnityEngine.Debug.Log("VICTORY");
onGameWon.Invoke();
}
public void WinCurrencies()
{
currenciesController.WinCurrency((int)scoreController.Score, CurrentPlayer.movePlayer.transform);
}
public void WinCurrenciesRaw(int rawValue)
{
currenciesController.WinCurrency(rawValue, CurrentPlayer.movePlayer.transform);
}
private void GameOver()
{
cam.GameOver();
GameStateMachine.SetState(GS_GAME_OVER);
}
private void EnterGameOver()
{
UnityEngine.Debug.Log("GAME OVER");
onGameOver.Invoke();
}
public IInputsListener GetCurrentInputsListener()
{
Func<IInputsListener> func = GameStateMachine.CurrentState?.getInputsListenerFunc;
return (func != null) ? func() : null;
}
}