nightward/Assets/Resources/Prefabs/HorseRush/Script/HorseRushPanel.cs

640 lines
20 KiB
C#

using System;
using System.Collections.Generic;
using DG.Tweening;
using GUPS.AntiCheat.Protected;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class HorseRushPanel : MonoBehaviour
{
[SerializeField] HorseRushManager _horseRushManager;
[SerializeField] List<BubbleCard> _bubbleCardList;
[SerializeField] List<GameObject> _touchButtonObjectList;
[SerializeField] GameObject _commander;
[SerializeField] Button _leftButton;
[SerializeField] Button _rightButton;
[SerializeField] GameObject _leftEffect;
[SerializeField] GameObject _rightEffect;
public TextMeshProUGUI[] texts_money; // 0 채팅 코인, 1 골드, 2 하트
#region TEST
[Header("## SLIDER")]
[SerializeField] Slider _timer;
[SerializeField] Image _fillImage;
[SerializeField] Text _rushTimeText;
[SerializeField] Text _feverTimeText;
[SerializeField] Slider _bottomSlider;
[SerializeField] Image _bottomFillImage;
[Header("## UI")]
[SerializeField] Text _scoreText;
[SerializeField] Text _comboText;
[SerializeField] GameObject _combo;
[SerializeField] Image _background;
[SerializeField] Image _stunImage;
[SerializeField] Image _loveEffectImage;
#endregion
#region Rush System member variable
float STUN_TIME;
float RUSH_LIMIT_TIME;
float FEVER_TIME;
float BONUS_TIME;
ProtectedInt32 DEFAULT_FEVER_COUNT;
int FEVER_INCREASE_MIN;
int FEVER_INCREASE_MAX;
int FEVER_INCREASE_LIMIT;
bool _isGameStart = false;
public bool IsGameStart => _isGameStart;
bool _isFree;
bool _isGameOver = true;
float _limitTime;
public float LimitTime => _limitTime;
float _rushTime;
public float RushTime => _rushTime;
float _addRushTimeValue;
float _stunTime;
public float StunTime => _stunTime;
bool IsStun => _stunTime > 0;
float _feverTime;
public float FeverTime => _feverTime;
bool IsFever => _feverTime > 0;
// 전체 누적 콤보
int _totalComboCount = 0;
int _comboCount = 0;
int _levelComboCount = 0;
ProtectedInt32 _maxcombo;
int _feverLevel = 0;
long _score = 0;
// 피버 관련 변수 추가
int _currentFeverStreak = 0; // 현재 연속 피버 횟수
int _maxFeverStreak = 0; // 최대 연속 피버 횟수
public int MaxFeverStreak => _maxFeverStreak;
int _missionFeverCount = 0;
// 미션 성공으로 지급된 photo 아이디
int _missionSuccessPhotoID = -1;
public int MissionSuccessPhotoID => _missionSuccessPhotoID;
// 더블 스코어 관련 변수 추가
private int _normalDoubleScoreCount = 0; // 일반 상태에서의 더블 스코어 성공 횟수
public int NormalDoubleScoreCount => _normalDoubleScoreCount;
ProtectedInt32 m_GachaCoint, m_ChatCoint;
#endregion
#region UI System member variable
float NORMAL_BUBBLE_MOVE_SPEED = 0.05f;
float FEVER_BUBBLE_MOVE_SPEED = 0.0f;
float BUBBLE_MOVE_SPEED = 0.1f;
readonly float BUBBLE_MOVE_Y_VALUE = 240f;
readonly float BUUBLE_MOVE_Y_ADDED_VALUE = 2640f;
readonly float DEFAULT_LIMIT_TIME = 180f;
#endregion
private Animator _leftAnimator;
private Animator _rightAnimator;
int _touchSoundCount = 0;
float _nextTimeUpdate = 0.1f;
private Sprite _feverBgSprite;
private Sprite _normalBgSprite;
List<eSound> _normalTouchSound = new List<eSound> { eSound.s020_Noraml_Hit, eSound.s021_Noraml_Hit, eSound.s022_Noraml_Hit, eSound.s023_Noraml_Hit, eSound.s024_Noraml_Hit, eSound.s025_Noraml_Hit };
List<eSound> _impactTouchSound = new List<eSound> { eSound.s026_Impact_Hit, eSound.s027_Impact_Hit, eSound.s028_Impact_Hit, eSound.s029_Impact_Hit };
// 클래스 멤버 변수에 추가
private float _lastTouchTime = 0f;
// 애니메이션 진행 여부 확인용 플래그 변수 추가
private bool _isAnimationPlaying = false;
void Awake()
{
STUN_TIME = 0.5f;
RUSH_LIMIT_TIME = 2f;
FEVER_TIME = 8f;
BONUS_TIME = 0.4f;
FEVER_INCREASE_MIN = 5;
FEVER_INCREASE_MAX = 15;
FEVER_INCREASE_LIMIT = 10;
_leftButton.onClick.AddListener(() => Touch(isTouchLeft: true));
_rightButton.onClick.AddListener(() => Touch(isTouchLeft: false));
// 버튼의 넓이만 스크린의 절반으로 설정 나머지는 원래 사이즈 그대로로
_leftButton.GetComponent<RectTransform>().sizeDelta = new Vector2(Screen.width / 2, _leftButton.GetComponent<RectTransform>().sizeDelta.y);
_rightButton.GetComponent<RectTransform>().sizeDelta = new Vector2(Screen.width / 2, _rightButton.GetComponent<RectTransform>().sizeDelta.y);
_feverBgSprite = Resources.Load<Sprite>("Prefabs/HorseRush/Image/RushBg_Fever");
_normalBgSprite = Resources.Load<Sprite>("Prefabs/HorseRush/Image/RushBg");
}
void Start()
{
_leftAnimator = _leftEffect.GetComponent<Animator>();
_rightAnimator = _rightEffect.GetComponent<Animator>();
//_missionFeverCount = DataManager.Instance.GlobalValue<int>("MISSION_FEVER_COUNT");
}
void Update()
{
// 키보드 입력 처리
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
Touch(isTouchLeft: true);
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
Touch(isTouchLeft: false);
}
if (!_isGameStart) return;
_rushTime -= Time.deltaTime;
_limitTime -= Time.deltaTime;
if (_nextTimeUpdate <= 0)
{
TimeSpan timeSpan = TimeSpan.FromSeconds(_limitTime);
_rushTimeText.text = string.Format("{0:D2}:{1:D2}", timeSpan.Minutes, timeSpan.Seconds);
_nextTimeUpdate = 0.1f;
}
_nextTimeUpdate -= Time.deltaTime;
if (_rushTime <= 0 || _limitTime <= 0)
{
_isGameStart = false;
_isGameOver = true;
_horseRushManager.GameOver(_isFree, _score, _normalDoubleScoreCount, _maxcombo, _maxFeverStreak, _missionSuccessPhotoID);
//gameObject.SetActive(false);
}
_timer.value = _limitTime / DEFAULT_LIMIT_TIME;
if (IsFever)
{
_bottomSlider.value = _feverTime / FEVER_TIME;
}
else
{
_bottomSlider.value = _rushTime / RUSH_LIMIT_TIME;
}
_stunTime = Mathf.Max(0, _stunTime - Time.deltaTime);
if (IsStun)
{
_touchButtonObjectList.ForEach(obj => obj.GetComponent<Image>().fillAmount = 1 - _stunTime / STUN_TIME);
}
bool beforeFever = IsFever;
_feverTime = Mathf.Max(0, _feverTime - Time.deltaTime);
bool canFeverIncreaseCondition = (DEFAULT_FEVER_COUNT + (FEVER_INCREASE_MAX * _feverLevel)) < _levelComboCount;
bool canDefaultComboCondition = (DEFAULT_FEVER_COUNT + (FEVER_INCREASE_MIN * _feverLevel)) < _comboCount;
if (canDefaultComboCondition && canFeverIncreaseCondition)
{
Debug.Log("<color=red>###### F E V E R ######</color>");
SoundInfo.Ins.Play_BGM(eBGM.b003_Fever);
// _bottomFillImage.color = new Color(1, 0.84f, 0.33f, 1);
FadeFeverBg(_feverBgSprite);
LevelUpFever();
}
if (beforeFever && !IsFever)
{
SoundInfo.Ins.Play_BGM(eBGM.b002_MiniGame);
// _bottomFillImage.color = new Color(0.86f, 0, 0, 1);
FadeFeverBg(_normalBgSprite);
}
}
void OnEnable()
{
_combo.SetActive(false);
_stunImage.DOFade(0, 0);
_stunImage.fillAmount = 1;
_loveEffectImage.DOFade(0, 0);
_loveEffectImage.fillAmount = 1;
_timer.value = 1;
_bottomSlider.value = 1;
_limitTime = DEFAULT_LIMIT_TIME;
TimeSpan timeSpan = TimeSpan.FromSeconds(_limitTime);
_rushTimeText.text = string.Format("{0:D2}:{1:D2}", timeSpan.Minutes, timeSpan.Seconds);
_scoreText.text = "0";
Init();
}
void OnDisable()
{
_isGameStart = false;
}
void Init()
{
for (int i = 0; i < _bubbleCardList.Count; i++)
{
_bubbleCardList[i].transform.DOKill();
float moveValue = BUUBLE_MOVE_Y_ADDED_VALUE + (-i * BUBBLE_MOVE_Y_VALUE);
_bubbleCardList[i].transform.DOLocalMoveY(moveValue, BUBBLE_MOVE_SPEED);
_bubbleCardList[i].SetScale(i, BUBBLE_MOVE_SPEED);
_bubbleCardList[i].SetCard(IsFever);
_bubbleCardList[i].SetOpacity(i, IsFever);
}
_touchButtonObjectList.ForEach(obj => obj.GetComponent<Image>().fillAmount = 1);
}
public void GameStart(bool isFree)
{
gameObject.SetActive(true);
//if (GameManager.Instance.IsPackageCPurchased())
//{
// // 피버 발생 조건 20% 감소, 미션 카운트 5->3회
// DEFAULT_FEVER_COUNT = 80;
// FEVER_INCREASE_MIN = 4;
// FEVER_INCREASE_MAX = 12;
//}
//else
//{
// DEFAULT_FEVER_COUNT = 100;
// FEVER_INCREASE_MIN = 5;
// FEVER_INCREASE_MAX = 15;
//}
_isGameOver = false;
//var albums = DataManager.Instance.GetAllPhotoDatas();
//var curPhotos = albums[GameManager.Instance.SelectedMinigameAlbum.ID];
//foreach (var photo in curPhotos.Values)
//{
// if (photo.CollectionMethod == NerdNavis.AdultGacha.Enum.CollectionMethod.FullCollection)
// {
// _feverBgSprite = Resources.Load<Sprite>(photo.ImagePath);
// }
// else if (GameManager.Instance.CurrentMinigameType == GameManager.MinigameType.Sexy && photo.CollectionMethod == NerdNavis.AdultGacha.Enum.CollectionMethod.Mission)
// {
// _normalBgSprite = Resources.Load<Sprite>(photo.ImagePath);
// }
// else if (GameManager.Instance.CurrentMinigameType == GameManager.MinigameType.General && photo.CollectionMethod == NerdNavis.AdultGacha.Enum.CollectionMethod.Default)
// {
// _normalBgSprite = Resources.Load<Sprite>(photo.ImagePath);
// }
//}
FadeFeverBg(_normalBgSprite);
// 게임 상태 초기화
_isFree = isFree;
_limitTime = DEFAULT_LIMIT_TIME;
_rushTime = RUSH_LIMIT_TIME;
_stunTime = 0;
_feverTime = 0;
_totalComboCount = 0;
_maxcombo = 0; _maxcombo.Obfuscate();
_comboCount = 0;
_levelComboCount = 0;
_feverLevel = 0;
_score = 0;
m_GachaCoint = 0; m_GachaCoint.Obfuscate();
m_ChatCoint = 0; m_ChatCoint.Obfuscate();
DEFAULT_FEVER_COUNT = 100; DEFAULT_FEVER_COUNT.Obfuscate();
// UI 초기화
_combo.SetActive(false);
_stunImage.DOFade(0, 0);
_stunImage.fillAmount = 1;
_loveEffectImage.DOFade(0, 0);
_loveEffectImage.fillAmount = 1;
_timer.value = 1;
_bottomSlider.value = 1;
texts_money[0].text = SaveMgr.Ins.Get_Money(eMoney.Chat).ToString();
texts_money[1].text = SaveMgr.Ins.Get_Money(eMoney.Gacha).ToString();
texts_money[2].text = SaveMgr.Ins.Get_Money(eMoney.AlbumOpen).ToString();
// 시간 텍스트 초기화
TimeSpan timeSpan = TimeSpan.FromSeconds(_limitTime);
_rushTimeText.text = string.Format("{0:D2}:{1:D2}", timeSpan.Minutes, timeSpan.Seconds);
// 점수 텍스트 초기화
_scoreText.text = "0";
SetAddRushTime();
// 피버 스트릭 초기화 추가
_currentFeverStreak = 0;
_maxFeverStreak = 0;
// 미션 성공으로 지급된 photo 아이디 초기화
_missionSuccessPhotoID = -1;
// 더블 스코어 카운트 초기화
_normalDoubleScoreCount = 0;
Init();
}
public void Touch(bool isTouchLeft)
{
// 애니메이션이 진행 중일 때는 입력 무시
if (_isAnimationPlaying && !IsFever)
return;
if (_isGameOver) return;
// 현재 시간이 마지막 터치 시간 + 이동 속도보다 작으면 입력 무시
if (Time.time < _lastTouchTime + (IsFever ? FEVER_BUBBLE_MOVE_SPEED : NORMAL_BUBBLE_MOVE_SPEED))
{
return;
}
_isGameStart = true;
if (IsStun)
{
return;
}
// 유효한 입력이므로 마지막 터치 시간 업데이트
_lastTouchTime = Time.time;
if (isTouchLeft)
{
_leftAnimator.SetTrigger("Touch");
}
else
{
_rightAnimator.SetTrigger("Touch");
}
BubbleCard lastBubbleCard = _bubbleCardList[^1].GetComponent<BubbleCard>();
bool isCorrect = isTouchLeft ? lastBubbleCard.IsLeftCarrot : !lastBubbleCard.IsLeftCarrot;
if (lastBubbleCard.IsFever)
{
isCorrect = true;
}
if (isCorrect)
{
AddComboCount(lastBubbleCard.IsHeartCarrot);
MoveBubbleCard();
lastBubbleCard.transform.SetAsFirstSibling();
_rushTime = Mathf.Min(RUSH_LIMIT_TIME, _rushTime + _addRushTimeValue);
if (!IsFever)
{
m_ChatCoint += lastBubbleCard.IsHeartCarrot ? 1 : 0;
m_ChatCoint.Obfuscate();
}
}
else
{
_comboCount = 0;
_comboText.text = ConvertToSpriteText(0);
_combo.SetActive(false);
// 콤보가 끊길 때 피버 스트릭도 초기화
_currentFeverStreak = 0;
--DEFAULT_FEVER_COUNT;
if (DEFAULT_FEVER_COUNT < table_GlobalValue.Ins.Get_Int("FEVER_CONDITION_MIN_COUNT"))
DEFAULT_FEVER_COUNT = table_GlobalValue.Ins.Get_Int("FEVER_CONDITION_MIN_COUNT");
DEFAULT_FEVER_COUNT.Obfuscate();
if (lastBubbleCard.IsSkullStone)
{
_isGameStart = false;
_isGameOver = true;
_horseRushManager.GameOver(_isFree, _score, _normalDoubleScoreCount, _maxcombo, _maxFeverStreak, _missionSuccessPhotoID);
}
else
{
_stunImage.DOFade(1, 0.2f).OnComplete(() => _stunImage.DOFade(0, 0.2f));
_stunTime = STUN_TIME;
}
}
}
private string ConvertToSpriteText(int count)
{
string countString = count.ToString();
_combo.SetActive(count >= 1);
_combo.transform.localScale = Vector3.one;
if (count == 1)
{
_combo.transform.DOScale(1.2f, 0.2f).OnComplete(() => _combo.transform.DOScale(1f, 0.2f));
}
return countString;
}
public void MoveBubbleCard()
{
// 애니메이션 시작 전 플래그 활성화
_isAnimationPlaying = true;
// 기존의 DOTween 시퀀스 생성 및 애니메이션 처리 코드
DOTween.Kill(_bubbleCardList[^1].transform);
if (_bubbleCardList == null || _bubbleCardList.Count == 0) return;
Sequence sequence = DOTween.Sequence();
BubbleCard lastCard = _bubbleCardList[^1];
if (lastCard == null || lastCard.transform == null) return;
lastCard.transform.DOKill();
lastCard.transform.localPosition = new Vector3(lastCard.transform.localPosition.x, BUUBLE_MOVE_Y_ADDED_VALUE, lastCard.transform.localPosition.z);
_bubbleCardList.RemoveAt(_bubbleCardList.Count - 1);
_bubbleCardList.Insert(0, lastCard);
lastCard.SetCard(IsFever);
for (int i = 0; i < _bubbleCardList.Count; i++)
{
var card = _bubbleCardList[i];
if (card == null || card.transform == null) continue;
card.transform.DOKill();
float moveValue = BUUBLE_MOVE_Y_ADDED_VALUE + (-i * BUBBLE_MOVE_Y_VALUE);
// 각 카드의 트윈을 시퀀스에 추가하기 전에 유효성 검사
var tween = card.transform.DOLocalMoveY(moveValue, BUBBLE_MOVE_SPEED)
.SetTarget(card.transform)
.OnKill(() => { if (card != null) card.transform.localPosition = new Vector3(card.transform.localPosition.x, moveValue, card.transform.localPosition.z); });
sequence.Join(tween);
card.SetScale(i, BUBBLE_MOVE_SPEED);
card.SetOpacity(i, IsFever);
}
// 시퀀스가 완료되거나 중단될 때의 처리
sequence.OnKill(() =>
{
foreach (var card in _bubbleCardList)
{
if (card != null && card.transform != null)
{
DOTween.Kill(card.transform);
}
}
_isAnimationPlaying = false;
});
}
void AddComboCount(bool isDoubleScore)
{
_totalComboCount++;
_comboCount++;
if (_maxcombo < _comboCount)
{
_maxcombo = _comboCount;
_maxcombo.Obfuscate();
}
BubbleCard lastBubbleCard = _bubbleCardList[^1];
if (!lastBubbleCard.IsFever && isDoubleScore)
{
_normalDoubleScoreCount++;
}
if (!IsFever)
{
_levelComboCount++;
}
if (_totalComboCount % 100 == 0)
{
SetAddRushTime();
}
int addScore = 1;
_score += isDoubleScore ? addScore * 2 : addScore;
_comboText.transform.localScale = Vector3.one;
StartBounceEffect();
int soundLimit = isDoubleScore ? 5 : 9;
var targetList = isDoubleScore ? _impactTouchSound : _normalTouchSound;
if (soundLimit < _touchSoundCount++)
{
SoundInfo.Ins.Play_OneShot(targetList[UnityEngine.Random.Range(0, targetList.Count)]);
Sequence loveSequence = DOTween.Sequence();
loveSequence.Append(_loveEffectImage.DOFade(0.3f, 0.15f))
.Append(_loveEffectImage.DOFade(0.1f, 0.1f))
.Append(_loveEffectImage.DOFade(0.4f, 0.15f))
.Append(_loveEffectImage.DOFade(0, 0.3f));
loveSequence.Play();
_touchSoundCount = 0;
}
else
{
SoundInfo.Ins.Play_OneShot(eSound.s001_ButtonClick);
}
_scoreText.text = _score.ToString();
_comboText.text = ConvertToSpriteText(_comboCount);
}
void LevelUpFever()
{
_feverTime = FEVER_TIME;
Init();
_levelComboCount = 0;
_feverLevel = Mathf.Min(_feverLevel + 1, FEVER_INCREASE_LIMIT - 1);
_currentFeverStreak++;
_maxFeverStreak = Mathf.Max(_maxFeverStreak, _currentFeverStreak);
if (_maxFeverStreak >= 3)
{
var tdata = table_album.Ins.Get_SpecialAlbum(SaveMgr.Ins.m_SelectMiniGameGirl, eCollectionMethod.Mission);
if (!SaveMgr.Ins.IsOpenAlbum(tdata))
{
SaveMgr.Ins.Open_Album(tdata);
SaveMgr.Ins.Save();
}
}
}
void SetAddRushTime()
{
int isNotHumanCount = 20000;
if (_totalComboCount >= isNotHumanCount)
{
_addRushTimeValue = 0;
}
else
{
_addRushTimeValue = Mathf.Max(0.2f, ((BONUS_TIME * 100f) - Mathf.Round(_totalComboCount / (30f / _totalComboCount * 150f))) / 100f);
Debug.Log($"addRushTimeValue: {_addRushTimeValue}");
}
}
void FadeFeverBg(Sprite newSprite)
{
Sequence sequence = DOTween.Sequence();
_background.color = new Color(_background.color.r, _background.color.g, _background.color.b, 1f);
_background.sprite = newSprite;
sequence.Append(_background.DOFade(0, 0.15f))
.Append(_background.DOFade(1, 0.15f));
}
void StartBounceEffect()
{
if (_comboText == null) return;
float bounceDuration = 0.2f;
float maxScale = 1.5f;
Vector3 originalScale = _comboText.transform.localScale;
Vector3 targetScale = originalScale * maxScale;
DOTween.Kill(_comboText.transform);
Sequence sequence = DOTween.Sequence();
sequence.SetTarget(_comboText.transform);
sequence.Append(_comboText.transform.DOScale(targetScale, bounceDuration / 2).SetEase(Ease.OutQuad))
.Append(_comboText.transform.DOScale(originalScale, bounceDuration / 2).SetEase(Ease.InQuad));
}
public void OnClick_GameLeave()
{
gameObject.SetActive(false);
}
}