HeavenStudio/Assets/Scripts/Games/SamuraiSliceNtr/SamuraiSliceNtr.cs
minenice55 3002e48350
Alternate Control Styles Support (#554)
* add mouse controller

* support different control styles in options

deprecate old input check methods

* fully functional input actions system

* btsds InputAction

* blue bear InputAction

* more games

fix bugs with some input related systems

* coin toss re-toss

* cheer readers touch

* dog ninja touch

* multiple games

* last of the easy games' touch

* more specialized games

* specialized games 2

* finish ktb games

* remove legacy settings disclaimer

* "only" two games left

* karate man touch

* rockers touch

still needs fixes and bad judge strum

* DSGuy flicking animation

* playstyle chart property

* improve performance of minigame preloading

* improve look of cursor

make assetbundles use chunk-based compression
refactor assetbundle loading methods a bit

* prime conductor stream playback to stabilize seeking operations

* fix air rally swing on pad release

* use virtual mouse pointer

* add UniTask

* make BeatAction use UniTask

* implement UniTask to replace some coroutines

* add touch style UI elements and effects

games now support the ability to define two cursor colours if they need split screen touch inputs

* update plugins and buildscript

* implement thresholded pointer position clipping

* fix clamping

* instant show / hide

fix discord game SDK crashes
2023-10-29 19:44:47 +00:00

280 lines
10 KiB
C#

using HeavenStudio.Util;
using HeavenStudio.InputSystem;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using DG.Tweening;
using NaughtyBezierCurves;
namespace HeavenStudio.Games.Loaders
{
using static Minigames;
public static class NtrSamuraiLoader
{
public static Minigame AddGame(EventCaller eventCaller) {
return new Minigame("samuraiSliceNtr", "Samurai Slice (DS)", "b6b5b6", false, false, new List<GameAction>()
{
new GameAction("bop", "Bop")
{
function = delegate {var e = eventCaller.currentEntity; SamuraiSliceNtr.instance.Bop(e.beat, e.length, e["whoBops"], e["whoBopsAuto"]); },
resizable = true,
parameters = new List<Param>()
{
new Param("whoBops", SamuraiSliceNtr.WhoBops.Both, "Who Bops?", "Who will bop?"),
new Param("whoBopsAuto", SamuraiSliceNtr.WhoBops.None, "Who Bops? (Auto)", "Who will automatically begin bopping?")
}
},
new GameAction("melon", "Melon")
{
function = delegate
{
SamuraiSliceNtr.instance.ObjectIn(eventCaller.currentEntity.beat, (int)SamuraiSliceNtr.ObjectType.Melon, (int) eventCaller.currentEntity["valA"], eventCaller.currentEntity["2b2t"]);
},
defaultLength = 5,
parameters = new List<Param>()
{
new Param("2b2t", false, "Melon2B2T", "Should the melon be reskinned as the 2B2T melon?"),
new Param("valA", new EntityTypes.Integer(0, 30, 1), "Money", "The amount of coins the melon spills out when sliced"),
}
},
new GameAction("fish", "Fish")
{
function = delegate
{
SamuraiSliceNtr.instance.ObjectIn(eventCaller.currentEntity.beat, (int)SamuraiSliceNtr.ObjectType.Fish, (int) eventCaller.currentEntity["valA"]);
},
defaultLength = 7,
parameters = new List<Param>()
{
new Param("valA", new EntityTypes.Integer(0, 30, 1), "Money", "The amount of coins the fish spills out when sliced"),
}
},
new GameAction("demon", "Demon")
{
function = delegate
{
SamuraiSliceNtr.instance.ObjectIn(eventCaller.currentEntity.beat, (int)SamuraiSliceNtr.ObjectType.Demon, (int) eventCaller.currentEntity["valA"]);
},
defaultLength = 7,
parameters = new List<Param>()
{
new Param("valA", new EntityTypes.Integer(0, 30, 1), "Money", "The amount of coins the demon spills out when sliced"),
}
},
//backwards compatibility
new GameAction("spawn object", "Toss Object")
{
function = delegate
{
SamuraiSliceNtr.instance.ObjectIn(eventCaller.currentEntity.beat, eventCaller.currentEntity["type"], (int) eventCaller.currentEntity["valA"]);
},
defaultLength = 8,
parameters = new List<Param>()
{
new Param("type", SamuraiSliceNtr.ObjectType.Melon, "Object", "The object to spawn"),
new Param("valA", new EntityTypes.Integer(0, 30, 1), "Money", "The amount of coins the melon spills out when sliced"),
},
hidden = true
},
},
new List<string>() {"ntr", "normal"},
"ntrsamurai", "en",
new List<string>() {"en"}
);
}
}
}
namespace HeavenStudio.Games
{
using Scripts_NtrSamurai;
public class SamuraiSliceNtr : Minigame
{
public enum ObjectType {
Melon,
Fish,
Demon,
Melon2B2T,
}
public enum WhoBops
{
Samurai = 0,
Children = 1,
Both = 2,
None = 3
}
private bool goBopSamurai = true;
private bool goBopChild = true;
[Header("References")]
public NtrSamurai player;
public GameObject launcher;
public GameObject objectPrefab;
public GameObject childParent;
public Transform objectHolder;
public BezierCurve3D InCurve;
public BezierCurve3D LaunchCurve;
public BezierCurve3D LaunchHighCurve;
public BezierCurve3D NgLaunchCurve;
public BezierCurve3D DebrisLeftCurve;
public BezierCurve3D DebrisRightCurve;
public BezierCurve3D NgDebrisCurve;
//game scene
public static SamuraiSliceNtr instance;
public GameEvent bop = new GameEvent();
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);
}
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_AltDown =
new("NtrSamuraiAltDown", new int[] { IAAltDownCat, IAAltDownCat, IAAltDownCat },
IA_PadAltPress, IA_TouchAltPress, IA_BatonAltPress);
public static PlayerInput.InputAction InputAction_AltUp =
new("NtrSamuraiAltUp", new int[] { IAAltUpCat, IAFlickCat, IAAltUpCat },
IA_PadAltRelease, IA_TouchBasicRelease, IA_BatonAltRelease);
private void Awake()
{
instance = this;
}
// Update is called once per frame
void Update()
{
var cond = Conductor.instance;
if (cond.ReportBeat(ref bop.lastReportedBeat, bop.startBeat % 1))
{
if (goBopSamurai) player.Bop();
if (goBopChild) childParent.GetComponent<NtrSamuraiChild>().Bop();
}
if (PlayerInput.GetIsAction(InputAction_AltDown))
DoStep();
if (PlayerInput.GetIsAction(InputAction_AltUp) && player.isStepping())
DoUnStep();
if (PlayerInput.GetIsAction(InputAction_FlickPress))
DoSlice();
}
public void Bop(double beat, float length, int whoBops, int whoBopsAuto)
{
goBopSamurai = whoBopsAuto == (int)WhoBops.Samurai || whoBopsAuto == (int)WhoBops.Both;
goBopChild = whoBopsAuto == (int)WhoBops.Children || whoBopsAuto == (int)WhoBops.Both;
for (int i = 0; i < length; i++)
{
BeatAction.New(instance, new List<BeatAction.Action>()
{
new BeatAction.Action(beat + i, delegate { BopSingle(whoBops); })
});
}
}
void BopSingle(int whoBops)
{
switch (whoBops)
{
case (int)WhoBops.Samurai:
player.Bop();
break;
case (int)WhoBops.Children:
childParent.GetComponent<NtrSamuraiChild>().Bop();
break;
case (int)WhoBops.Both:
player.Bop();
childParent.GetComponent<NtrSamuraiChild>().Bop();
break;
default:
break;
}
}
public void DoStep()
{
SoundByte.PlayOneShotGame("samuraiSliceNtr/ntrSamurai_launchThrough");
player.Step(false);
launcher.GetComponent<Animator>().Play("Launch", -1, 0);
}
public void DoUnStep()
{
player.Step(true);
launcher.GetComponent<Animator>().Play("UnStep", -1, 0);
}
public void DoSlice()
{
if (player.isStepping())
{
launcher.GetComponent<Animator>().Play("UnStep", -1, 0);
}
SoundByte.PlayOneShotGame("samuraiSliceNtr/ntrSamurai_through");
player.Slash();
}
public void Bop(double beat, float length)
{
bop.length = length;
bop.startBeat = beat;
}
public void ObjectIn(double beat, int type = (int) ObjectType.Melon, int value = 1, bool funnyMinecraft = false)
{
var mobj = GameObject.Instantiate(objectPrefab, objectHolder);
var mobjDat = mobj.GetComponent<NtrSamuraiObject>();
mobjDat.startBeat = beat;
mobjDat.type = funnyMinecraft ? (int)ObjectType.Melon2B2T : type;
mobjDat.holdingCash = value;
mobj.SetActive(true);
SoundByte.PlayOneShotGame("samuraiSliceNtr/ntrSamurai_in00");
}
public NtrSamuraiChild CreateChild(double beat)
{
var mobj = GameObject.Instantiate(childParent, objectHolder);
var mobjDat = mobj.GetComponent<NtrSamuraiChild>();
mobjDat.startBeat = beat;
mobjDat.isMain = false;
mobjDat.Bop();
mobj.SetActive(true);
mobj.GetComponent<SortingGroup>().sortingOrder = 7;
return mobjDat;
}
}
}