492 lines
20 KiB
C#
492 lines
20 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
using HeavenStudio.Util;
|
|
|
|
namespace HeavenStudio.Games.Loaders
|
|
{
|
|
using static Minigames;
|
|
public static class RvlKarateLoader
|
|
{
|
|
public static Minigame AddGame(EventCaller eventCaller) {
|
|
return new Minigame("karateman", "Karate Man", "70A8D8", false, false, new List<GameAction>()
|
|
{
|
|
new GameAction("bop", delegate { KarateMan.instance.Bop(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); }, 0.5f, true),
|
|
new GameAction("hit", delegate
|
|
{
|
|
KarateMan.instance.Shoot(eventCaller.currentEntity.beat, eventCaller.currentEntity.type);
|
|
}, 2, false, new List<Param>()
|
|
{
|
|
new Param("type", KarateMan.HitType.Pot, "Object", "The object to fire")
|
|
}),
|
|
new GameAction("bulb", delegate {
|
|
var e = eventCaller.currentEntity;
|
|
var c = KarateMan.instance.LightBulbColors[e.type];
|
|
if(e.type == (int)KarateMan.LightBulbType.Custom) c = e.colorA;
|
|
KarateMan.instance.Shoot(e.beat, 1, tint: c);
|
|
}, 2, false, new List<Param>()
|
|
{
|
|
new Param("type", KarateMan.LightBulbType.Normal, "Type", "The preset bulb type. Yellow is used for kicks while Blue is used for combos"),
|
|
new Param("colorA", new Color(), "Custom Color", "The color to use when the bulb type is set to Custom")
|
|
}),
|
|
new GameAction("kick", delegate { KarateMan.instance.Shoot(eventCaller.currentEntity.beat, 4); }, 4.5f),
|
|
new GameAction("combo", delegate { KarateMan.instance.Combo(eventCaller.currentEntity.beat); }, 4f),
|
|
new GameAction("hit3", delegate
|
|
{
|
|
var e = eventCaller.currentEntity;
|
|
switch ((KarateMan.HitThree)e.type)
|
|
{
|
|
case KarateMan.HitThree.HitTwo: KarateMan.instance.Hit2(e.beat); break;
|
|
case KarateMan.HitThree.HitThreeAlt: KarateMan.instance.Hit3(e.beat, true); break;
|
|
case KarateMan.HitThree.HitFour: KarateMan.instance.Hit4(e.beat); break;
|
|
default: KarateMan.instance.Hit3(e.beat); break;
|
|
}
|
|
}, 1f, false, new List<Param>()
|
|
{
|
|
new Param("type", KarateMan.HitThree.HitThree, "Type", "What should be called out")
|
|
}),
|
|
new GameAction("prepare", delegate { KarateMan.instance.Prepare(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); }, 1f, true),
|
|
new GameAction("set background color", delegate {
|
|
var e = eventCaller.currentEntity;
|
|
var c = KarateMan.instance.BackgroundColors[e.type];
|
|
if(e.type == (int)KarateMan.BackgroundType.Custom) c = e.colorA;
|
|
KarateMan.instance.SetBackgroundColor(e.type, e.type2, c, e.colorB);
|
|
}, 0.5f, false, new List<Param>()
|
|
{
|
|
new Param("type", KarateMan.BackgroundType.Yellow, "Background Type", "The preset background type"),
|
|
new Param("type2", KarateMan.ShadowType.Tinted, "Shadow Type", "The shadow type. If Tinted doesn't work with your background color try Custom"),
|
|
new Param("colorA", new Color(), "Custom Background Color", "The background color to use when background type is set to Custom"),
|
|
new Param("colorB", new Color(), "Custom Shadow Color", "The shadow color to use when shadow type is set to Custom"),
|
|
|
|
}),
|
|
new GameAction("set background fx", delegate {
|
|
KarateMan.instance.SetBackgroundFX((KarateMan.BackgroundFXType)eventCaller.currentEntity.type);
|
|
}, 0.5f, false, new List<Param>()
|
|
{
|
|
new Param("type", KarateMan.BackgroundFXType.None, "FX Type", "The background effect to be displayed")
|
|
|
|
}),
|
|
// These are still here for backwards-compatibility but are hidden in the editor
|
|
new GameAction("pot", delegate { KarateMan.instance.Shoot(eventCaller.currentEntity.beat, 0); }, 2, hidden: true),
|
|
new GameAction("rock", delegate { KarateMan.instance.Shoot(eventCaller.currentEntity.beat, 2); }, 2, hidden: true),
|
|
new GameAction("ball", delegate { KarateMan.instance.Shoot(eventCaller.currentEntity.beat, 3); }, 2, hidden: true),
|
|
new GameAction("tacobell", delegate { KarateMan.instance.Shoot(eventCaller.currentEntity.beat, 999); }, 2, hidden: true),
|
|
new GameAction("hit4", delegate { KarateMan.instance.Hit4(eventCaller.currentEntity.beat); }, hidden: true),
|
|
new GameAction("bgfxon", delegate { KarateMan.instance.SetBackgroundFX(KarateMan.BackgroundFXType.Sunburst); }, hidden: true),
|
|
new GameAction("bgfxoff", delegate { KarateMan.instance.SetBackgroundFX(KarateMan.BackgroundFXType.None); }, hidden: true),
|
|
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace HeavenStudio.Games
|
|
{
|
|
using Scripts_KarateMan;
|
|
|
|
public class KarateMan : Minigame
|
|
{
|
|
|
|
public enum HitType
|
|
{
|
|
Pot = 0,
|
|
Rock = 2,
|
|
Ball = 3,
|
|
CookingPot = 6,
|
|
Alien = 7,
|
|
|
|
TacoBell = 999
|
|
}
|
|
|
|
public enum HitThree
|
|
{
|
|
HitTwo,
|
|
HitThree,
|
|
HitThreeAlt,
|
|
HitFour
|
|
}
|
|
|
|
public enum LightBulbType
|
|
{
|
|
Normal,
|
|
Blue,
|
|
Yellow,
|
|
Custom
|
|
}
|
|
|
|
public enum BackgroundType
|
|
{
|
|
Yellow,
|
|
Fuchsia,
|
|
Blue,
|
|
Red,
|
|
Orange,
|
|
Pink,
|
|
Custom
|
|
}
|
|
|
|
public enum BackgroundFXType
|
|
{
|
|
None,
|
|
Sunburst,
|
|
Rings
|
|
}
|
|
|
|
public enum ShadowType
|
|
{
|
|
Tinted,
|
|
Custom
|
|
}
|
|
|
|
public Color[] LightBulbColors;
|
|
public Color[] BackgroundColors;
|
|
public Color[] ShadowColors;
|
|
public static Color ShadowBlendColor = new Color(195f / 255f, 48f / 255f, 2f / 255f);
|
|
|
|
const float hitVoiceOffset = 0.042f;
|
|
|
|
public GameObject Pot, Bomb;
|
|
public KarateJoe KarateJoe;
|
|
|
|
public List<Minigame.Eligible> EligibleCombos = new List<Minigame.Eligible>();
|
|
|
|
public static KarateMan instance { get; set; }
|
|
|
|
public Sprite[] ObjectSprites;
|
|
public Sprite[] BarrelSprites;
|
|
public Sprite[] CookingPotSprites;
|
|
public Sprite[] OtherSprites;
|
|
|
|
public List<BGSpriteC> BGSprites;
|
|
public SpriteRenderer BGSprite;
|
|
public SpriteRenderer BGFXSprite;
|
|
|
|
public BackgroundType BGType = BackgroundType.Yellow;
|
|
public BackgroundFXType BGFXType = BackgroundFXType.None;
|
|
public Color BGColor;
|
|
|
|
public ShadowType Shadow = ShadowType.Tinted;
|
|
public Color ShadowColor = Color.black;
|
|
|
|
private float newBeat;
|
|
|
|
public GameEvent bop = new GameEvent();
|
|
public GameEvent prepare = new GameEvent();
|
|
|
|
private float bgBeat;
|
|
|
|
public ParticleSystem potHitEffect;
|
|
|
|
public GameObject comboRef;
|
|
|
|
public GameObject HIT3Ref;
|
|
|
|
public Sprite[] Numbers;
|
|
|
|
|
|
[System.Serializable]
|
|
public class BGSpriteC
|
|
{
|
|
public List<Sprite> Sprites;
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
instance = this;
|
|
BGType = 0;
|
|
BGColor = BackgroundColors[0];
|
|
Shadow = 0;
|
|
}
|
|
|
|
public override void OnGameSwitch(float beat)
|
|
{
|
|
base.OnGameSwitch(beat);
|
|
SetBackgroundColor((int)BGType, (int)Shadow, BGColor, ShadowColor);
|
|
}
|
|
|
|
public void Combo(float beat)
|
|
{
|
|
comboRef.GetComponent<Animator>().enabled = true;
|
|
comboRef.GetComponent<Animator>().Play("comboRef");
|
|
Jukebox.PlayOneShotGame("karateman/barrelOutCombos");
|
|
|
|
Shoot(beat, 0, true, "PotCombo1", 0, new Vector2(-0.94f, -2.904f));
|
|
Shoot(beat + 0.25f, 0, true, "PotCombo2", 1, new Vector2(-0.94f, -2.904f));
|
|
Shoot(beat + 0.5f, 0, true, "PotCombo3", 2, new Vector2(-0.776f, -3.162f));
|
|
Shoot(beat + 0.75f, 0, true, "PotCombo4", 3, new Vector2(1.453f, -3.162f));
|
|
Shoot(beat + 1f, 0, true, "PotCombo5", 4, new Vector2(0.124f, -3.123f));
|
|
Shoot(beat + 1.5f, 4, true, "PotCombo6", 5, new Vector2(-1.333f, -2.995f));
|
|
|
|
MultiSound.Play(new MultiSound.Sound[]
|
|
{
|
|
new MultiSound.Sound("karateman/punchy1", beat + 1f),
|
|
new MultiSound.Sound("karateman/punchy2", beat + 1.25f),
|
|
new MultiSound.Sound("karateman/punchy3", beat + 1.5f),
|
|
new MultiSound.Sound("karateman/punchy4", beat + 1.75f),
|
|
new MultiSound.Sound("karateman/ko", beat + 2f),
|
|
new MultiSound.Sound("karateman/pow", beat + 2.5f)
|
|
});
|
|
}
|
|
|
|
public void Shoot(float beat, int type, bool combo = false, string throwAnim = "", int comboIndex = 0, Vector2 endShadowPos = new Vector2(), UnityEngine.Color tint = default)
|
|
{
|
|
GameObject pot = Instantiate(Pot);
|
|
pot.transform.parent = Pot.transform.parent;
|
|
|
|
if (KarateJoe.instance.anim.IsAnimationNotPlaying())
|
|
KarateJoe.instance.SetHead(0);
|
|
|
|
Pot p = pot.GetComponent<Pot>();
|
|
|
|
pot.SetActive(true);
|
|
p.startBeat = beat;
|
|
p.createBeat = beat;
|
|
p.isThrown = true;
|
|
p.type = type;
|
|
|
|
if(type <= ObjectSprites.Length)
|
|
p.Sprite.GetComponent<SpriteRenderer>().sprite = ObjectSprites[type];
|
|
|
|
if (combo)
|
|
{
|
|
p.comboIndex = comboIndex;
|
|
p.throwAnim = throwAnim;
|
|
p.combo = true;
|
|
KarateJoe.currentComboPots.Add(p);
|
|
p.endShadowThrowPos = endShadowPos;
|
|
}
|
|
else
|
|
{
|
|
p.throwAnim = "PotThrow";
|
|
|
|
string outSnd = "";
|
|
switch (type)
|
|
{
|
|
case 0:
|
|
if (Starpelly.Mathp.GetDecimalFromFloat(beat) == 0f)
|
|
outSnd = "karateman/objectOut";
|
|
else
|
|
outSnd = "karateman/offbeatObjectOut";
|
|
p.hitSnd = "karateman/potHit";
|
|
break;
|
|
case 1:
|
|
outSnd = "karateman/lightbulbOut";
|
|
p.hitSnd = "karateman/lightbulbHit";
|
|
if (tint != default && tint != Color.black) {
|
|
p.BulbLightSprite.SetActive(true);
|
|
p.BulbLightSprite.GetComponent<SpriteRenderer>().color = tint;
|
|
}
|
|
break;
|
|
case 2:
|
|
if (Starpelly.Mathp.GetDecimalFromFloat(beat) == 0f)
|
|
outSnd = "karateman/objectOut";
|
|
else
|
|
outSnd = "karateman/offbeatObjectOut";
|
|
p.hitSnd = "karateman/rockHit";
|
|
break;
|
|
case 3:
|
|
if (Starpelly.Mathp.GetDecimalFromFloat(beat) == 0f)
|
|
outSnd = "karateman/objectOut";
|
|
else
|
|
outSnd = "karateman/offbeatObjectOut";
|
|
p.hitSnd = "karateman/soccerHit";
|
|
break;
|
|
case 4:
|
|
p.kick = true;
|
|
outSnd = "karateman/barrelOutKicks";
|
|
p.hitSnd = "karateman/barrelBreak";
|
|
|
|
MultiSound.Play(new MultiSound.Sound[]
|
|
{
|
|
new MultiSound.Sound("karateman/punchKick1", beat + 1f),
|
|
new MultiSound.Sound("karateman/punchKick2", beat + 1.5f),
|
|
new MultiSound.Sound("karateman/punchKick3", beat + 1.75f),
|
|
new MultiSound.Sound("karateman/punchKick4", beat + 2.25f)
|
|
});
|
|
break;
|
|
case 6:
|
|
if (Starpelly.Mathp.GetDecimalFromFloat(beat) == 0f)
|
|
outSnd = "karateman/objectOut";
|
|
else
|
|
outSnd = "karateman/offbeatObjectOut";
|
|
p.hitSnd = "karateman/cookingPot";
|
|
break;
|
|
case 7:
|
|
if (Starpelly.Mathp.GetDecimalFromFloat(beat) == 0f)
|
|
outSnd = "karateman/objectOut";
|
|
else
|
|
outSnd = "karateman/offbeatObjectOut";
|
|
p.hitSnd = "karateman/alienHit";
|
|
break;
|
|
case 999:
|
|
p.Sprite.GetComponent<SpriteRenderer>().sprite = OtherSprites[0];
|
|
if (Starpelly.Mathp.GetDecimalFromFloat(beat) == 0f)
|
|
outSnd = "karateman/objectOut";
|
|
else
|
|
outSnd = "karateman/offbeatObjectOut";
|
|
p.hitSnd = "karateman/tacobell";
|
|
break;
|
|
}
|
|
|
|
p.endShadowThrowPos = new Vector2(-1.036f, -2.822f);
|
|
|
|
Jukebox.PlayOneShotGame(outSnd);
|
|
}
|
|
p.Init();
|
|
}
|
|
|
|
List<Beatmap.Entity> cuedVoices = new List<Beatmap.Entity>(); // "Hit" voices cued in advance are stored here so they aren't called multiple times in Update().
|
|
private void Update()
|
|
{
|
|
if (Conductor.instance.ReportBeat(ref newBeat))
|
|
{
|
|
if (BGFXSprite.enabled)
|
|
{
|
|
var type = (int)BGFXType - 1;
|
|
if (bgBeat % 2 == 0)
|
|
{
|
|
BGFXSprite.sprite = BGSprites[type].Sprites[0];
|
|
}
|
|
else
|
|
{
|
|
BGFXSprite.sprite = BGSprites[type].Sprites[1];
|
|
}
|
|
bgBeat++;
|
|
}
|
|
}
|
|
|
|
if (Conductor.instance.ReportBeat(ref bop.lastReportedBeat, bop.startBeat % 1))
|
|
{
|
|
if (Conductor.instance.songPositionInBeats >= bop.startBeat && Conductor.instance.songPositionInBeats < bop.startBeat + bop.length)
|
|
{
|
|
if (KarateJoe.anim.IsAnimationNotPlaying())
|
|
KarateJoe.anim.Play("Bop", 0, 0);
|
|
}
|
|
}
|
|
|
|
if (prepare.length > 0)
|
|
{
|
|
if (Conductor.instance.songPositionInBeats >= prepare.startBeat && Conductor.instance.songPositionInBeats < prepare.startBeat + prepare.length)
|
|
{
|
|
if (KarateJoe.anim.IsAnimationNotPlaying())
|
|
KarateJoe.AnimPlay("Prepare");
|
|
}
|
|
else
|
|
{
|
|
KarateJoe.AnimPlay("Idle");
|
|
prepare.length = 0;
|
|
}
|
|
}
|
|
|
|
if (!Conductor.instance.isPlaying)
|
|
return;
|
|
|
|
// Call "hit" voice slightly early to account for sound offset.
|
|
var hitVoiceEvents = GameManager.instance.Beatmap.entities.FindAll(c => c.datamodel == "karateman/hit3" || c.datamodel == "karateman/hit4");
|
|
for (int i = 0; i < hitVoiceEvents.Count; i++)
|
|
{
|
|
var hitEvent = hitVoiceEvents[i];
|
|
var timeToEvent = hitEvent.beat - Conductor.instance.songPositionInBeats;
|
|
if (timeToEvent <= 1f && timeToEvent > 0f && !cuedVoices.Contains(hitEvent))
|
|
{
|
|
cuedVoices.Add(hitEvent);
|
|
var sound = "karateman/hit";
|
|
if (hitEvent.type == (int)KarateMan.HitThree.HitThreeAlt) sound += "Alt";
|
|
MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound(sound, hitEvent.beat - hitVoiceOffset * Conductor.instance.songBpm / 60f) });
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetBackgroundFX(BackgroundFXType type)
|
|
{
|
|
BGFXType = type;
|
|
|
|
if (BGFXType == BackgroundFXType.None)
|
|
{
|
|
BGFXSprite.enabled = false;
|
|
}
|
|
else
|
|
{
|
|
BGFXSprite.enabled = true;
|
|
BGFXSprite.sprite = BGSprites[(int)type - 1].Sprites[0];
|
|
}
|
|
}
|
|
|
|
public void SetBackgroundColor(int type, int shadowType, Color backgroundColor, Color shadowColor)
|
|
{
|
|
BGType = (BackgroundType)type;
|
|
BGColor = backgroundColor;
|
|
BGSprite.color = backgroundColor;
|
|
Shadow = (ShadowType)shadowType;
|
|
ShadowColor = shadowColor;
|
|
}
|
|
|
|
public void Bop(float beat, float length)
|
|
{
|
|
bop.length = length;
|
|
bop.startBeat = beat;
|
|
}
|
|
|
|
public void Hit2(float beat)
|
|
{
|
|
MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("karateman/two", beat + 0.5f) });
|
|
}
|
|
|
|
public void Hit3(float beat, bool alt = false)
|
|
{
|
|
var sound = "karateman/three";
|
|
if (alt) sound += "Alt";
|
|
MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound(sound, beat + 0.5f) });
|
|
GameObject hit3 = Instantiate(HIT3Ref, this.transform);
|
|
hit3.transform.GetChild(0).GetChild(1).GetComponent<SpriteRenderer>().sprite = Numbers[2];
|
|
BeatAction.New(hit3, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beat + 0.5f, delegate { hit3.transform.GetChild(0).gameObject.SetActive(true); }),
|
|
new BeatAction.Action(beat + 4.5f, delegate { Destroy(hit3); })
|
|
});
|
|
}
|
|
|
|
public void Hit4(float beat)
|
|
{
|
|
MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("karateman/four", beat + 0.5f) });
|
|
GameObject hit4 = Instantiate(HIT3Ref, this.transform);
|
|
hit4.transform.GetChild(0).GetChild(1).GetComponent<SpriteRenderer>().sprite = Numbers[3];
|
|
BeatAction.New(hit4, new List<BeatAction.Action>()
|
|
{
|
|
new BeatAction.Action(beat + 0.5f, delegate { hit4.transform.GetChild(0).gameObject.SetActive(true); }),
|
|
new BeatAction.Action(beat + 4.5f, delegate { Destroy(hit4); })
|
|
});
|
|
}
|
|
|
|
public void Prepare(float beat, float length)
|
|
{
|
|
prepare.startBeat = beat;
|
|
prepare.length = length;
|
|
}
|
|
|
|
public void CreateBomb(Transform parent, Vector2 scale, ref GameObject shadow)
|
|
{
|
|
GameObject bomb = Instantiate(Bomb, parent);
|
|
bomb.SetActive(true);
|
|
bomb.transform.localScale = scale;
|
|
shadow.transform.parent = bomb.transform;
|
|
shadow.transform.SetAsLastSibling();
|
|
bomb.GetComponent<Bomb>().shadow = shadow;
|
|
}
|
|
|
|
public Color GetShadowColor()
|
|
{
|
|
if(Shadow == ShadowType.Custom)
|
|
{
|
|
return ShadowColor;
|
|
}
|
|
else if(BGType < BackgroundType.Custom)
|
|
{
|
|
return ShadowColors[(int)BGType];
|
|
}
|
|
|
|
return Color.LerpUnclamped(BGColor, ShadowBlendColor, 0.45f);
|
|
}
|
|
}
|
|
} |