Minigame: Samurai Slice (Gold) (#79)

* Game: Samurai Slice (DS)

initial scene setup

* Samurai Slice (Gold) - Start animations

* Samurai Slice (Gold) - Finish core samurai animations

* Samurai Slice (Gold) - Basic interactions

* Samurai Slice (Gold): object prep

* Samurai Slice (Gold): object type setup

* Samurai Slice (Gold): object paths

* Samurai Slice (Gold): prep for other objects

* Samurai Slice (Gold): prep fish

* Samurai Slice (Gold): Objects complete

* Samurai Slice (Gold): dinero

quiero cien vbucks

* Samurai Slice (Gold): polish cash, slicing anim

* Samurai Slice (Gold): child catching

* Samurai Slice (Gold): feature complete
This commit is contained in:
minenice55
2022-05-16 01:29:26 -04:00
committed by GitHub
parent bf0d23bc47
commit c46f653612
109 changed files with 38114 additions and 2 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 440c5554544146b448285c8d5ea9bd26
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,59 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace HeavenStudio.Games.Scripts_NtrSamurai
{
public class NtrSamurai : MonoBehaviour
{
[Header("References")]
public Animator animator;
[Header("Properties")]
public bool stepping;
public void Init()
{
stepping = false;
}
// Update is called once per frame
void Update()
{
}
public void Bop()
{
if (!stepping && !(animator.GetCurrentAnimatorClipInfo(0)[0].clip.name == "Slash"))
animator.Play("Beat", -1, 0);
}
public void Step(bool off)
{
stepping = !off;
if (off)
{
animator.Play("Beat", -1, 0);
}
else
{
if (animator.GetCurrentAnimatorClipInfo(0)[0].clip.name == "Slash")
animator.Play("StepSeathe", -1, 0);
else
animator.Play("Step", -1, 0);
}
}
public void Slash()
{
stepping = false;
animator.Play("Slash", -1, 0);
}
public bool isStepping()
{
return stepping;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 91edf50b6967f864ca699d5f3dd0de5c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,56 @@
using DG.Tweening;
using NaughtyBezierCurves;
using HeavenStudio.Util;
using System;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using NaughtyBezierCurves;
namespace HeavenStudio.Games.Scripts_NtrSamurai
{
public class NtrSamuraiChild : MonoBehaviour
{
[Header("Transforms")]
public Transform DebrisPosL;
public Transform DebrisPosR;
public Transform WalkPos0;
public Transform WalkPos1;
[Header("Objects")]
public Animator anim;
public float startBeat = Single.MinValue;
public bool isMain = true;
// Update is called once per frame
void Update()
{
if (!isMain)
{
var cond = Conductor.instance;
float prog = Conductor.instance.GetPositionFromBeat(startBeat + 1f, 2f);
if (prog >= 0)
{
Walk();
transform.position = Vector3.Lerp(WalkPos0.position, WalkPos1.position, prog);
if (prog >= 1f)
{
GameObject.Destroy(gameObject);
}
}
}
}
public void Bop()
{
anim.Play("ChildBeat", -1, 0);
}
public void Walk()
{
anim.Play("ChildWalk");
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bfdb7063344c23f42b3c36732758c247
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,302 @@
using DG.Tweening;
using NaughtyBezierCurves;
using HeavenStudio.Util;
using System;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using NaughtyBezierCurves;
namespace HeavenStudio.Games.Scripts_NtrSamurai
{
public class NtrSamuraiObject : MonoBehaviour
{
[Header("Objects")]
public ParticleSystem moneyBurst;
public Animator anim;
public NtrSamuraiObject secondHalf;
[Header("Transforms")]
public Transform doubleLaunchPos;
public Transform heldPos;
public float startBeat;
public int type;
public bool isDebris = false;
public int holdingCash = 1;
BezierCurve3D currentCurve;
int flyProg = 0;
bool flying = true;
bool missedLaunch = false;
bool missedHit = false;
PlayerActionEvent launchProg;
PlayerActionEvent hitProg;
void Awake()
{
if (isDebris)
{
switch (type)
{
case (int) SamuraiSliceNtr.ObjectType.Fish:
anim.Play("ObjFishDebris");
break;
case (int) SamuraiSliceNtr.ObjectType.Demon:
anim.Play("ObjDemonDebris02");
break;
default:
anim.Play("ObjMelonDebris");
break;
}
currentCurve = SamuraiSliceNtr.instance.DebrisLeftCurve;
var cond = Conductor.instance;
float flyPos = cond.GetPositionFromBeat(startBeat, 1f);
transform.position = currentCurve.GetPoint(flyPos);
}
else
{
switch (type)
{
case (int) SamuraiSliceNtr.ObjectType.Fish:
anim.Play("ObjFish");
break;
case (int) SamuraiSliceNtr.ObjectType.Demon:
anim.Play("ObjDemon");
MultiSound.Play(new MultiSound.Sound[] {
new MultiSound.Sound("samuraiSliceNtr/ntrSamurai_in01", startBeat + 1f, 1.5f),
new MultiSound.Sound("samuraiSliceNtr/ntrSamurai_in01", startBeat + 1.5f, 1.25f),
new MultiSound.Sound("samuraiSliceNtr/ntrSamurai_in01", startBeat + 2f),
});
break;
default:
anim.Play("ObjMelon");
break;
}
launchProg = SamuraiSliceNtr.instance.ScheduleInput(startBeat, 2f, InputType.STANDARD_ALT_DOWN, LaunchSuccess, LaunchMiss, LaunchThrough);
//autoplay: launch anim
SamuraiSliceNtr.instance.ScheduleAutoplayInput(startBeat, 2f, InputType.STANDARD_ALT_DOWN, DoLaunchAutoplay, LaunchThrough, LaunchThrough);
//autoplay: unstep
SamuraiSliceNtr.instance.ScheduleAutoplayInput(startBeat, 1.75f, InputType.STANDARD_ALT_UP, DoUnStepAutoplay, LaunchThrough, LaunchThrough);
currentCurve = SamuraiSliceNtr.instance.InCurve;
transform.rotation = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z + (360f * startBeat));
var cond = Conductor.instance;
float flyPos = cond.GetPositionFromBeat(launchProg.startBeat, 3f);
transform.position = currentCurve.GetPoint(flyPos);
transform.rotation = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z + (-360f * Time.deltaTime) + UnityEngine.Random.Range(0f, 180f));
}
}
void Update()
{
var cond = Conductor.instance;
float flyPos;
if (flying)
{
switch (flyProg)
{
case -2: // being carried by a child
flyPos = cond.GetPositionFromBeat(startBeat + 2f, 2f);
if (heldPos == null || flyPos > 1f)
{
GameObject.Destroy(gameObject);
return;
}
transform.position = heldPos.position;
break;
case -1: // sliced by samurai, falling towards child
flyPos = cond.GetPositionFromBeat(startBeat, 1f);
transform.position = currentCurve.GetPoint(flyPos);
transform.rotation = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z + ((isDebris? 360f : -360f) * Time.deltaTime));
if (flyPos > 1f)
{
Jukebox.PlayOneShotGame("samuraiSliceNtr/ntrSamurai_catch");
if (!isDebris)
{
NtrSamuraiChild child = SamuraiSliceNtr.instance.CreateChild(startBeat + 1f);
heldPos = child.DebrisPosR;
secondHalf.heldPos = child.DebrisPosL;
}
flyProg = -2;
return;
}
break;
case 2: // fish first bounce
float jumpPos = cond.GetPositionFromBeat(launchProg.startBeat, 2f);
float yMul = jumpPos * 2f - 1f;
float yWeight = -(yMul*yMul) + 1f;
transform.position = doubleLaunchPos.position + new Vector3(0, 4.5f * yWeight);
transform.rotation = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z + (-2 * 360f * Time.deltaTime));
if (jumpPos > 2f)
{
// missed...
GameObject.Destroy(gameObject);
return;
}
break;
case 1: // launched from board to samurai
float flyDur = 3f;
switch (type)
{
case (int) SamuraiSliceNtr.ObjectType.Demon:
flyDur = 5f;
break;
default:
flyDur = 3f;
break;
}
flyPos = cond.GetPositionFromBeat(hitProg.startBeat, flyDur);
transform.position = currentCurve.GetPoint(flyPos);
transform.rotation = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z + (3 * 360f * Time.deltaTime));
if (flyPos > 1f)
{
// missed...
GameObject.Destroy(gameObject);
return;
}
break;
default: // object initial spawn, flying towards board
flyPos = cond.GetPositionFromBeat(launchProg.startBeat, 3f);
transform.position = currentCurve.GetPoint(flyPos);
transform.rotation = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z + (-360f * Time.deltaTime));
if (flyPos > 1f)
{
// missed...
GameObject.Destroy(gameObject);
return;
}
break;
}
}
}
void DoLaunch()
{
switch (type)
{
case (int) SamuraiSliceNtr.ObjectType.Fish:
if (flyProg == 2)
{
flyProg = 1;
hitProg = SamuraiSliceNtr.instance.ScheduleInput(startBeat + 4f, 2f, InputType.STANDARD_DOWN, HitSuccess, HitMiss, LaunchThrough);
SamuraiSliceNtr.instance.ScheduleAutoplayInput(startBeat + 4f, 2f, InputType.STANDARD_DOWN, DoSliceAutoplay, LaunchThrough, LaunchThrough);
currentCurve = SamuraiSliceNtr.instance.LaunchCurve;
Jukebox.PlayOneShotGame("samuraiSliceNtr/holy_mackerel" + UnityEngine.Random.Range(1, 4), pitch: UnityEngine.Random.Range(0.95f, 1.05f), volume: 1f/4);
}
else
{
flyProg = 2;
launchProg = SamuraiSliceNtr.instance.ScheduleInput(startBeat + 2f, 2f, InputType.STANDARD_ALT_DOWN, LaunchSuccess, LaunchMiss, LaunchThrough);
SamuraiSliceNtr.instance.ScheduleAutoplayInput(startBeat + 2f, 2f, InputType.STANDARD_ALT_DOWN, DoLaunchAutoplay, LaunchThrough, LaunchThrough);
//autoplay: unstep
SamuraiSliceNtr.instance.ScheduleAutoplayInput(startBeat + 2f, 1.75f, InputType.STANDARD_ALT_UP, DoUnStepAutoplay, LaunchThrough, LaunchThrough);
currentCurve = null;
Jukebox.PlayOneShotGame("samuraiSliceNtr/holy_mackerel" + UnityEngine.Random.Range(1, 4), pitch: UnityEngine.Random.Range(0.95f, 1.05f), volume: 0.8f);
}
break;
case (int) SamuraiSliceNtr.ObjectType.Demon:
flyProg = 1;
hitProg = SamuraiSliceNtr.instance.ScheduleInput(startBeat + 2f, 4f, InputType.STANDARD_DOWN, HitSuccess, HitMiss, LaunchThrough);
SamuraiSliceNtr.instance.ScheduleAutoplayInput(startBeat + 2f, 4f, InputType.STANDARD_DOWN, DoSliceAutoplay, LaunchThrough, LaunchThrough);
currentCurve = SamuraiSliceNtr.instance.LaunchHighCurve;
break;
default:
flyProg = 1;
hitProg = SamuraiSliceNtr.instance.ScheduleInput(startBeat + 2f, 2f, InputType.STANDARD_DOWN, HitSuccess, HitMiss, LaunchThrough);
SamuraiSliceNtr.instance.ScheduleAutoplayInput(startBeat + 2f, 2f, InputType.STANDARD_DOWN, DoSliceAutoplay, LaunchThrough, LaunchThrough);
currentCurve = SamuraiSliceNtr.instance.LaunchCurve;
break;
}
}
void DoLaunchAutoplay(PlayerActionEvent caller, float state)
{
SamuraiSliceNtr.instance.DoStep();
}
void DoSliceAutoplay(PlayerActionEvent caller, float state)
{
SamuraiSliceNtr.instance.DoSlice();
}
void DoUnStepAutoplay(PlayerActionEvent caller, float state)
{
if (SamuraiSliceNtr.instance.player.stepping)
{
SamuraiSliceNtr.instance.DoUnStep();
}
}
public void LaunchSuccess(PlayerActionEvent caller, float state)
{
launchProg.Disable();
DoLaunch();
Jukebox.PlayOneShotGame("samuraiSliceNtr/ntrSamurai_launchImpact", pitch: UnityEngine.Random.Range(0.85f, 1.05f));
}
public void LaunchMiss(PlayerActionEvent caller)
{
missedLaunch = true;
}
public void LaunchThrough(PlayerActionEvent caller) {}
public void HitSuccess(PlayerActionEvent caller, float state)
{
flyProg = -1;
hitProg.Disable();
if (UnityEngine.Random.Range(0f, 1f) >= 0.5f)
Jukebox.PlayOneShotGame("samuraiSliceNtr/ntrSamurai_just00", pitch: UnityEngine.Random.Range(0.95f, 1.05f));
else
Jukebox.PlayOneShotGame("samuraiSliceNtr/ntrSamurai_just01", pitch: UnityEngine.Random.Range(0.95f, 1.05f));
currentCurve = SamuraiSliceNtr.instance.DebrisRightCurve;
var mobj = GameObject.Instantiate(SamuraiSliceNtr.instance.objectPrefab, SamuraiSliceNtr.instance.objectHolder);
var mobjDat = mobj.GetComponent<NtrSamuraiObject>();
mobjDat.startBeat = caller.startBeat + caller.timer;
mobjDat.type = type;
mobjDat.isDebris = true;
mobjDat.flyProg = -1;
mobj.transform.position = transform.position;
mobj.transform.rotation = transform.rotation;
mobj.GetComponent<SpriteRenderer>().sortingOrder = 4;
mobj.SetActive(true);
secondHalf = mobjDat;
this.startBeat = caller.startBeat + caller.timer;
if (type == (int) SamuraiSliceNtr.ObjectType.Demon)
{
anim.Play("ObjDemonDebris01");
}
if (holdingCash > 0)
{
moneyBurst.Emit(holdingCash);
Jukebox.PlayOneShotGame((holdingCash > 2) ? "samuraiSliceNtr/ntrSamurai_scoreMany" : "samuraiSliceNtr/ntrSamurai_ng", pitch: UnityEngine.Random.Range(0.95f, 1.05f));
}
}
public void HitMiss(PlayerActionEvent caller)
{
missedHit = true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae0b3df22f9080c4cad91e4b72fe7105
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,142 @@
using HeavenStudio.Util;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
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) \n<color=#eb5454>[WIP]</color>", "00165D", false, false, new List<GameAction>()
{
new GameAction("spawn object", delegate
{
SamuraiSliceNtr.instance.ObjectIn(eventCaller.currentEntity.beat, eventCaller.currentEntity.type, (int) eventCaller.currentEntity.valA);
}, 8, false, 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 object spills out when sliced"),
}),
//new GameAction("start bopping", delegate { SamuraiSliceNtr.instance.Bop(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); }, 1),
});
}
}
}
namespace HeavenStudio.Games
{
using Scripts_NtrSamurai;
public class SamuraiSliceNtr : Minigame
{
public enum ObjectType {
Melon,
Fish,
Demon
}
[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;
//game scene
public static SamuraiSliceNtr instance;
public GameEvent bop = new GameEvent();
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))
{
player.Bop();
childParent.GetComponent<NtrSamuraiChild>().Bop();
}
if (PlayerInput.AltPressed())
DoStep();
if (PlayerInput.AltPressedUp() && player.isStepping())
DoUnStep();
if (PlayerInput.Pressed())
DoSlice();
}
public void DoStep()
{
Jukebox.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);
}
Jukebox.PlayOneShotGame("samuraiSliceNtr/ntrSamurai_through");
player.Slash();
}
public void Bop(float beat, float length)
{
bop.length = length;
bop.startBeat = beat;
}
public void ObjectIn(float beat, int type = (int) ObjectType.Melon, int value = 1)
{
var mobj = GameObject.Instantiate(objectPrefab, objectHolder);
var mobjDat = mobj.GetComponent<NtrSamuraiObject>();
mobjDat.startBeat = beat;
mobjDat.type = type;
mobjDat.holdingCash = value;
mobj.SetActive(true);
Jukebox.PlayOneShotGame("samuraiSliceNtr/ntrSamurai_in00");
}
public NtrSamuraiChild CreateChild(float beat)
{
var mobj = GameObject.Instantiate(childParent, objectHolder);
var mobjDat = mobj.GetComponent<NtrSamuraiChild>();
mobjDat.startBeat = beat;
mobjDat.isMain = false;
mobjDat.Bop();
mobj.SetActive(true);
return mobjDat;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 00eae865695fcff4e8ccadf976355847
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: