HeavenStudio/Assets/Scripts/Games/NailCarpenter/NailCarpenter.cs
fu-majime 21f5cfdd5f sfx
2024-02-27 09:29:49 +09:00

338 lines
14 KiB
C#

using HeavenStudio.Util;
using HeavenStudio.InputSystem;
using Jukebox;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace HeavenStudio.Games.Loaders
{
using static Minigames;
public static class PcoNailLoader
{
public static Minigame AddGame(EventCaller eventCaller)
{
return new Minigame("nailCarpenter", "Nail Carpenter", "fab96e", false, false, new List<GameAction>()
{
new GameAction("bop", "Bop")
{
function = delegate { var e = eventCaller.currentEntity; NailCarpenter.instance.ToggleBop(e.beat, e.length, e["toggle2"], e["toggle"]); },
resizable = true,
parameters = new List<Param>()
{
new Param("toggle2", true, "Bop", "Toggle if Boss should bop for the duration of this event."),
new Param("toggle", false, "Bop (Auto)", "Toggle if the man should automatically bop until another Bop event is reached.")
}
},
new GameAction("puddingNail", "Pudding Nail")
{
defaultLength = 4f,
resizable = true
},
new GameAction("cherryNail", "Cherry Nail")
{
defaultLength = 2f,
resizable = true
},
new GameAction("cakeNail", "Cake Nail")
{
defaultLength = 2f,
resizable = true
},
new GameAction("cakeLongNail", "Cake Long Nail")
{
defaultLength = 2f,
resizable = true
},
},
new List<string>() { "pco", "normal" },
"pconail", "en",
new List<string>() { }
);
}
}
}
namespace HeavenStudio.Games
{
using Scripts_NailCarpenter;
public class NailCarpenter : Minigame
{
public GameObject baseNail;
public GameObject baseLongNail;
public GameObject basePudding;
[SerializeField] ParticleSystem splashEffect;
public Animator HammerArm;
public Animator EffectSweat;
public Animator EffectShock;
public Transform scrollingHolder;
public Transform nailHolder;
public Transform boardTrans;
const float nailDistance = -9f;
const float boardWidth = 19.2f;
float scrollRate => nailDistance / (Conductor.instance.pitchedSecPerBeat * 2f);
private bool missed;
private bool hasSlurped;
enum sweetsType
{
Pudding=0,
LayerCake=1,
};
const int IAAltDownCat = IAMAXCAT;
const int IAAltUpCat = IAMAXCAT + 1;
protected static bool IA_PadAltPress(out double dt)
{
return PlayerInput.GetPadDown(InputController.ActionsPad.South, out dt);
}
protected static bool IA_BatonAltPress(out double dt)
{
return PlayerInput.GetSqueezeDown(out dt);
}
protected static bool IA_TouchAltPress(out double dt)
{
return PlayerInput.GetTouchDown(InputController.ActionsTouch.Tap, out dt)
&& instance.IsExpectingInputNow(InputAction_AltStart);
}
protected static bool IA_PadAltRelease(out double dt)
{
return PlayerInput.GetPadUp(InputController.ActionsPad.South, out dt);
}
protected static bool IA_BatonAltRelease(out double dt)
{
return PlayerInput.GetSqueezeUp(out dt);
}
public static PlayerInput.InputAction InputAction_AltStart =
new("PcoNailAltStart", new int[] { IAAltDownCat, IAAltDownCat, IAAltDownCat },
IA_PadAltPress, IA_TouchAltPress, IA_BatonAltPress);
public static PlayerInput.InputAction InputAction_AltFinish =
new("PcoNailAltFinish", new int[] { IAAltUpCat, IAFlickCat, IAAltUpCat },
IA_PadAltRelease, IA_TouchFlick, IA_BatonAltRelease);
public static PlayerInput.InputAction InputAction_TouchRelease =
new("PcoNailTouchRelease", new int[] { IAEmptyCat, IAReleaseCat, IAEmptyCat },
IA_Empty, IA_TouchBasicRelease, IA_Empty);
public static NailCarpenter instance;
// Start is called before the first frame update
void Awake()
{
instance = this;
SetupBopRegion("nailCarpenter", "bop", "toggle");
}
public override void OnBeatPulse(double beat)
{
// if (BeatIsInBopRegion(beat)) SomenPlayer.DoScaledAnimationAsync("HeadBob", 0.5f);
}
void Update()
{
var cond = Conductor.instance;
if (!cond.isPlaying) return;
// Debug.Log(newBeat);
if (PlayerInput.GetIsAction(InputAction_BasicPress) && !IsExpectingInputNow(InputAction_BasicPress))
{
SoundByte.PlayOneShot("miss");
HammerArm.DoScaledAnimationAsync("hammerHit", 0.5f);
hasSlurped = false;
EffectSweat.DoScaledAnimationAsync("BlobSweating", 0.5f);
// ScoreMiss();
}
// Object scroll.
var scrollPos = scrollingHolder.localPosition;
var newScrollX = scrollPos.x + (scrollRate * Time.deltaTime);
scrollingHolder.localPosition = new Vector3(newScrollX, scrollPos.y, scrollPos.z);
// Board scroll.
var boardPos = boardTrans.localPosition;
var newBoardX = boardPos.x + (scrollRate * Time.deltaTime);
newBoardX %= boardWidth;
boardTrans.localPosition = new Vector3(newBoardX, boardPos.y, boardPos.z);
}
public override void OnGameSwitch(double beat)
{
double startBeat;
double endBeat = double.MaxValue;
var entities = GameManager.instance.Beatmap.Entities;
startBeat = beat;
// find out when the next game switch (or remix end) happens
RiqEntity firstEnd = entities.Find(c => (c.datamodel.StartsWith("gameManager/switchGame") || c.datamodel.Equals("gameManager/end")) && c.beat > startBeat);
endBeat = firstEnd?.beat ?? double.MaxValue;
// Nail events.
List<RiqEntity> pudNailEvents = entities.FindAll(v => v.datamodel == "nailCarpenter/puddingNail");
List<RiqEntity> chrNailEvents = entities.FindAll(v => v.datamodel == "nailCarpenter/cherryNail");
List<RiqEntity> cakeNailEvents = entities.FindAll(v => v.datamodel == "nailCarpenter/cakeNail");
List<RiqEntity> cklNailEvents = entities.FindAll(v => v.datamodel == "nailCarpenter/cakeLongNail");
var sounds = new List<MultiSound.Sound>(){};
// Spawn pudding and nail.
for (int i = 0; i < pudNailEvents.Count; i++) {
var nailBeat = pudNailEvents[i].beat;
var nailLength = pudNailEvents[i].length;
// Only consider nailgie events that aren't past the start point.
if (startBeat <= nailBeat + nailLength) {
int nailInEvent = Mathf.CeilToInt(nailLength);
for (int b = 0; b < nailInEvent; b++)
{
var targetNailBeat = nailBeat + (1f * b);
if (startBeat <= targetNailBeat && targetNailBeat < endBeat)
{
sounds.Add(new MultiSound.Sound("nailCarpenter/one", targetNailBeat));
SpawnPudding(targetNailBeat, startBeat, (int)sweetsType.Pudding);
SpawnNail(targetNailBeat+0.5f, startBeat);
}
}
}
}
// Spawn cherry and nail.
for (int i = 0; i < chrNailEvents.Count; i++) {
var nailBeat = chrNailEvents[i].beat;
var nailLength = chrNailEvents[i].length;
// Only consider nailgie events that aren't past the start point.
if (startBeat <= nailBeat + nailLength) {
int nailInEvent = Mathf.CeilToInt(nailLength + 1) / 2;
for (int b = 0; b < nailInEvent; b++)
{
var targetNailBeat = nailBeat + (2f * b);
if (startBeat <= targetNailBeat && targetNailBeat < endBeat)
{
sounds.Add(new MultiSound.Sound("nailCarpenter/three", targetNailBeat));
SpawnPudding(targetNailBeat, startBeat, (int)sweetsType.Pudding);
SpawnNail(targetNailBeat+0.5f, startBeat);
SpawnNail(targetNailBeat+1.0f, startBeat);
SpawnNail(targetNailBeat+1.5f, startBeat);
}
}
}
}
// Spawn cake and nail.
for (int i = 0; i < cakeNailEvents.Count; i++) {
var nailBeat = cakeNailEvents[i].beat;
var nailLength = cakeNailEvents[i].length;
// Only consider nailgie events that aren't past the start point.
if (startBeat <= nailBeat + nailLength) {
int nailInEvent = Mathf.CeilToInt(nailLength + 1) / 2;
for (int b = 0; b < nailInEvent; b++)
{
var targetNailBeat = nailBeat + (2f * b);
if (startBeat <= targetNailBeat && targetNailBeat < endBeat)
{
sounds.Add(new MultiSound.Sound("nailCarpenter/alarm", targetNailBeat));
SpawnPudding(targetNailBeat, startBeat, (int)sweetsType.Pudding);
SpawnNail(targetNailBeat+0.5f, startBeat);
SpawnPudding(targetNailBeat+1.0f, startBeat, (int)sweetsType.Pudding);
SpawnNail(targetNailBeat+1.25f, startBeat);
SpawnNail(targetNailBeat+1.75f, startBeat);
}
}
}
}
// Spawn long nail.
for (int i = 0; i < cklNailEvents.Count; i++) {
var nailBeat = cklNailEvents[i].beat;
var nailLength = cklNailEvents[i].length;
// Only consider nailgie events that aren't past the start point.
if (startBeat <= nailBeat + nailLength) {
int nailInEvent = Mathf.CeilToInt(nailLength + 1) / 2;
for (int b = 0; b < nailInEvent; b++)
{
var targetNailBeat = nailBeat + (2f * b);
if (startBeat <= targetNailBeat && targetNailBeat < endBeat)
{
sounds.Add(new MultiSound.Sound("nailCarpenter/signal1", targetNailBeat));
sounds.Add(new MultiSound.Sound("nailCarpenter/signal2", targetNailBeat+1f));
SpawnPudding(targetNailBeat, startBeat, (int)sweetsType.LayerCake);
SpawnNail(targetNailBeat+0.5f, startBeat);
SpawnLongNail(targetNailBeat+1f, startBeat);
}
}
}
}
if (sounds.Count > 0) {
MultiSound.Play(sounds.ToArray(), forcePlay: true);
}
}
public override void OnPlay(double beat)
{
OnGameSwitch(beat);
}
public void ToggleBop(double beat, float length, bool bopOrNah, bool autoBop)
{
if (bopOrNah)
{
for (int i = 0; i < length; i++)
{
BeatAction.New(instance, new List<BeatAction.Action>()
{
new BeatAction.Action(beat + i, delegate
{
// SomenPlayer.DoScaledAnimationAsync("HeadBob", 0.5f);
})
});
}
}
}
private void SpawnNail(double beat, double startBeat)
{
var newNail = Instantiate(baseNail, nailHolder).GetComponent<Nail>();
newNail.targetBeat = beat;
var nailX = (beat - startBeat) * -nailDistance / 2f;
newNail.transform.localPosition = new Vector3((float)nailX, 0f, 0f);
newNail.Init();
newNail.gameObject.SetActive(true);
}
private void SpawnLongNail(double beat, double startBeat)
{
var newNail = Instantiate(baseLongNail, nailHolder).GetComponent<LongNail>();
newNail.targetBeat = beat;
var nailX = (beat - startBeat + 0.5f) * -nailDistance / 2f;
newNail.transform.localPosition = new Vector3((float)nailX, 0f, 0f);
newNail.Init();
newNail.gameObject.SetActive(true);
}
private void SpawnPudding(double beat, double startBeat, int sweetType)
{
var newPudding = Instantiate(basePudding, nailHolder).GetComponent<Pudding>();
newPudding.targetBeat = beat;
newPudding.puddingType = 2*sweetType;
var puddingX = (beat - startBeat) * -nailDistance / 2f;
newPudding.transform.localPosition = new Vector3((float)puddingX, 0f, 0f);
newPudding.Init();
newPudding.gameObject.SetActive(true);
}
}
}