mirror of
https://github.com/RHeavenStudioPlus/HeavenStudioPlus.git
synced 2024-11-10 11:45:09 +00:00
Merge pull request #55 from jakobwcrowe/master
DJ School: Additional gameplay implementation and tuning.
This commit is contained in:
commit
41ca962595
6 changed files with 218 additions and 50 deletions
|
@ -52,6 +52,33 @@ AnimatorState:
|
||||||
m_MirrorParameter:
|
m_MirrorParameter:
|
||||||
m_CycleOffsetParameter:
|
m_CycleOffsetParameter:
|
||||||
m_TimeParameter:
|
m_TimeParameter:
|
||||||
|
--- !u!1102 &-1143804635325942891
|
||||||
|
AnimatorState:
|
||||||
|
serializedVersion: 6
|
||||||
|
m_ObjectHideFlags: 1
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Unhold
|
||||||
|
m_Speed: -1
|
||||||
|
m_CycleOffset: 0
|
||||||
|
m_Transitions:
|
||||||
|
- {fileID: 5013820772242190312}
|
||||||
|
m_StateMachineBehaviours: []
|
||||||
|
m_Position: {x: 50, y: 50, z: 0}
|
||||||
|
m_IKOnFeet: 0
|
||||||
|
m_WriteDefaultValues: 1
|
||||||
|
m_Mirror: 0
|
||||||
|
m_SpeedParameterActive: 0
|
||||||
|
m_MirrorParameterActive: 0
|
||||||
|
m_CycleOffsetParameterActive: 0
|
||||||
|
m_TimeParameterActive: 0
|
||||||
|
m_Motion: {fileID: 7400000, guid: 3958816d51b511b4a9c0505c45de204a, type: 2}
|
||||||
|
m_Tag:
|
||||||
|
m_SpeedParameter:
|
||||||
|
m_MirrorParameter:
|
||||||
|
m_CycleOffsetParameter:
|
||||||
|
m_TimeParameter:
|
||||||
--- !u!1101 &-295531023391595954
|
--- !u!1101 &-295531023391595954
|
||||||
AnimatorStateTransition:
|
AnimatorStateTransition:
|
||||||
m_ObjectHideFlags: 1
|
m_ObjectHideFlags: 1
|
||||||
|
@ -148,6 +175,28 @@ AnimatorState:
|
||||||
m_MirrorParameter:
|
m_MirrorParameter:
|
||||||
m_CycleOffsetParameter:
|
m_CycleOffsetParameter:
|
||||||
m_TimeParameter:
|
m_TimeParameter:
|
||||||
|
--- !u!1101 &5013820772242190312
|
||||||
|
AnimatorStateTransition:
|
||||||
|
m_ObjectHideFlags: 1
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name:
|
||||||
|
m_Conditions: []
|
||||||
|
m_DstStateMachine: {fileID: 0}
|
||||||
|
m_DstState: {fileID: -4698968861401447970}
|
||||||
|
m_Solo: 0
|
||||||
|
m_Mute: 0
|
||||||
|
m_IsExit: 0
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TransitionDuration: 0
|
||||||
|
m_TransitionOffset: 0
|
||||||
|
m_ExitTime: 0
|
||||||
|
m_HasExitTime: 1
|
||||||
|
m_HasFixedDuration: 0
|
||||||
|
m_InterruptionSource: 0
|
||||||
|
m_OrderedInterruption: 1
|
||||||
|
m_CanTransitionToSelf: 1
|
||||||
--- !u!1107 &6962450605454016305
|
--- !u!1107 &6962450605454016305
|
||||||
AnimatorStateMachine:
|
AnimatorStateMachine:
|
||||||
serializedVersion: 6
|
serializedVersion: 6
|
||||||
|
@ -159,7 +208,7 @@ AnimatorStateMachine:
|
||||||
m_ChildStates:
|
m_ChildStates:
|
||||||
- serializedVersion: 1
|
- serializedVersion: 1
|
||||||
m_State: {fileID: -7055007684483605004}
|
m_State: {fileID: -7055007684483605004}
|
||||||
m_Position: {x: 430, y: -30, z: 0}
|
m_Position: {x: 490, y: -90, z: 0}
|
||||||
- serializedVersion: 1
|
- serializedVersion: 1
|
||||||
m_State: {fileID: 1884598382658345919}
|
m_State: {fileID: 1884598382658345919}
|
||||||
m_Position: {x: 580, y: -160, z: 0}
|
m_Position: {x: 580, y: -160, z: 0}
|
||||||
|
@ -172,6 +221,9 @@ AnimatorStateMachine:
|
||||||
- serializedVersion: 1
|
- serializedVersion: 1
|
||||||
m_State: {fileID: 7914765862687888288}
|
m_State: {fileID: 7914765862687888288}
|
||||||
m_Position: {x: 330, y: -170, z: 0}
|
m_Position: {x: 330, y: -170, z: 0}
|
||||||
|
- serializedVersion: 1
|
||||||
|
m_State: {fileID: -1143804635325942891}
|
||||||
|
m_Position: {x: 490, y: -30, z: 0}
|
||||||
m_ChildStateMachines: []
|
m_ChildStateMachines: []
|
||||||
m_AnyStateTransitions: []
|
m_AnyStateTransitions: []
|
||||||
m_EntryTransitions: []
|
m_EntryTransitions: []
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 38 KiB |
|
@ -124,8 +124,8 @@ namespace RhythmHeavenMania
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LateUpdate works a bit better but causes a bit of bugs, so remind me to fix those eventually
|
// LateUpdate works a bit better(?) but causes some bugs (like issues with bop animations).
|
||||||
private void LateUpdate()
|
private void Update()
|
||||||
{
|
{
|
||||||
if (Beatmap.entities.Count < 1)
|
if (Beatmap.entities.Count < 1)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -7,6 +7,13 @@ namespace RhythmHeavenMania.Games.DJSchool
|
||||||
{
|
{
|
||||||
public class DJSchool : Minigame
|
public class DJSchool : Minigame
|
||||||
{
|
{
|
||||||
|
public enum DJVoice
|
||||||
|
{
|
||||||
|
Standard,
|
||||||
|
Cool,
|
||||||
|
Hyped
|
||||||
|
}
|
||||||
|
|
||||||
[Header("Components")]
|
[Header("Components")]
|
||||||
[SerializeField] private Student student;
|
[SerializeField] private Student student;
|
||||||
[SerializeField] private GameObject djYellow;
|
[SerializeField] private GameObject djYellow;
|
||||||
|
@ -32,9 +39,11 @@ namespace RhythmHeavenMania.Games.DJSchool
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
if (Conductor.instance.ReportBeat(ref bop.lastReportedBeat, bop.startBeat % 1))
|
var cond = Conductor.instance;
|
||||||
|
|
||||||
|
if (cond.ReportBeat(ref bop.lastReportedBeat, bop.startBeat % 1))
|
||||||
{
|
{
|
||||||
if (Conductor.instance.songPositionInBeats >= bop.startBeat && Conductor.instance.songPositionInBeats < bop.startBeat + bop.length)
|
if (cond.songPositionInBeats >= bop.startBeat && cond.songPositionInBeats < bop.startBeat + bop.length)
|
||||||
{
|
{
|
||||||
if (student.anim.IsAnimationNotPlaying())
|
if (student.anim.IsAnimationNotPlaying())
|
||||||
{
|
{
|
||||||
|
@ -49,6 +58,12 @@ namespace RhythmHeavenMania.Games.DJSchool
|
||||||
}
|
}
|
||||||
if (djYellowAnim.IsAnimationNotPlaying())
|
if (djYellowAnim.IsAnimationNotPlaying())
|
||||||
{
|
{
|
||||||
|
var yellowState = djYellowAnim.GetCurrentAnimatorStateInfo(0);
|
||||||
|
if (yellowState.IsName("Hey"))
|
||||||
|
{
|
||||||
|
PostScratchoFace();
|
||||||
|
}
|
||||||
|
|
||||||
if (djYellowHolding)
|
if (djYellowHolding)
|
||||||
{
|
{
|
||||||
djYellowAnim.Play("HoldBop", 0, 0);
|
djYellowAnim.Play("HoldBop", 0, 0);
|
||||||
|
@ -75,20 +90,18 @@ namespace RhythmHeavenMania.Games.DJSchool
|
||||||
|
|
||||||
string[] sounds = new string[] { };
|
string[] sounds = new string[] { };
|
||||||
|
|
||||||
if (type == 0)
|
switch (type)
|
||||||
{
|
{
|
||||||
sounds = new string[] { "djSchool/breakCmon1", "djSchool/breakCmon2", "djSchool/ooh" };
|
case 0:
|
||||||
|
sounds = new string[] { "djSchool/breakCmon1", "djSchool/breakCmon2", "djSchool/ooh" };
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
sounds = new string[] { "djSchool/breakCmonAlt1", "djSchool/breakCmonAlt2", "djSchool/oohAlt" };
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sounds = new string[] { "djSchool/breakCmonLoud1", "djSchool/breakCmonLoud2", "djSchool/oohLoud" };
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (type == 1)
|
|
||||||
{
|
|
||||||
sounds = new string[] { "djSchool/breakCmonAlt1", "djSchool/breakCmonAlt2", "djSchool/oohAlt" };
|
|
||||||
}
|
|
||||||
else if (type == 2)
|
|
||||||
{
|
|
||||||
SetDJYellowHead(2);
|
|
||||||
sounds = new string[] { "djSchool/breakCmonLoud1", "djSchool/breakCmonLoud2", "djSchool/oohLoud" };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MultiSound.Play(new MultiSound.Sound[]
|
MultiSound.Play(new MultiSound.Sound[]
|
||||||
{
|
{
|
||||||
|
@ -105,11 +118,11 @@ namespace RhythmHeavenMania.Games.DJSchool
|
||||||
{
|
{
|
||||||
djYellow.GetComponent<Animator>().Play("Hold", 0, 0);
|
djYellow.GetComponent<Animator>().Play("Hold", 0, 0);
|
||||||
djYellowHolding = true;
|
djYellowHolding = true;
|
||||||
SetDJYellowHead(1);
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
student.holdBeat = beat;
|
student.holdBeat = beat;
|
||||||
|
student.eligible = true;
|
||||||
student.ResetState();
|
student.ResetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,11 +144,11 @@ namespace RhythmHeavenMania.Games.DJSchool
|
||||||
{
|
{
|
||||||
djYellow.GetComponent<Animator>().Play("Hold", 0, 0);
|
djYellow.GetComponent<Animator>().Play("Hold", 0, 0);
|
||||||
djYellowHolding = true;
|
djYellowHolding = true;
|
||||||
SetDJYellowHead(1);
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
student.holdBeat = beat - 0.5f;
|
student.holdBeat = beat - 0.5f;
|
||||||
|
student.eligible = true;
|
||||||
student.ResetState();
|
student.ResetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,12 +190,44 @@ namespace RhythmHeavenMania.Games.DJSchool
|
||||||
});
|
});
|
||||||
|
|
||||||
student.swipeBeat = beat;
|
student.swipeBeat = beat;
|
||||||
|
student.eligible = true;
|
||||||
student.ResetState();
|
student.ResetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetDJYellowHead(int type)
|
public void SetDJYellowHead(int type, bool resetAfterBeats = false)
|
||||||
{
|
{
|
||||||
headSprite.sprite = headSprites[type];
|
headSprite.sprite = headSprites[type];
|
||||||
|
|
||||||
|
if (resetAfterBeats)
|
||||||
|
{
|
||||||
|
BeatAction.New(djYellow, new List<BeatAction.Action>()
|
||||||
|
{
|
||||||
|
new BeatAction.Action(Mathf.Floor(Conductor.instance.songPositionInBeats) + 2f, delegate
|
||||||
|
{
|
||||||
|
var yellowState = djYellowAnim.GetCurrentAnimatorStateInfo(0);
|
||||||
|
if (yellowState.IsName("Idle")
|
||||||
|
|| yellowState.IsName("IdleBop")
|
||||||
|
|| yellowState.IsName("IdleBop2")
|
||||||
|
|| yellowState.IsName("BreakCmon"))
|
||||||
|
{
|
||||||
|
SetDJYellowHead(0);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostScratchoFace()
|
||||||
|
{
|
||||||
|
if (student.missed)
|
||||||
|
{
|
||||||
|
student.missed = false;
|
||||||
|
SetDJYellowHead(3, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetDJYellowHead(2, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,6 +16,9 @@ namespace RhythmHeavenMania.Games.DJSchool
|
||||||
public float holdBeat;
|
public float holdBeat;
|
||||||
public float swipeBeat;
|
public float swipeBeat;
|
||||||
public bool isHolding;
|
public bool isHolding;
|
||||||
|
public bool shouldBeHolding;
|
||||||
|
public bool eligible;
|
||||||
|
public bool missed;
|
||||||
|
|
||||||
[Header("Components")]
|
[Header("Components")]
|
||||||
[SerializeField] private SpriteRenderer flash;
|
[SerializeField] private SpriteRenderer flash;
|
||||||
|
@ -24,49 +27,88 @@ namespace RhythmHeavenMania.Games.DJSchool
|
||||||
[SerializeField] private GameObject TurnTable;
|
[SerializeField] private GameObject TurnTable;
|
||||||
[SerializeField] private GameObject slamFX;
|
[SerializeField] private GameObject slamFX;
|
||||||
|
|
||||||
|
private Animator tableAnim;
|
||||||
|
|
||||||
|
private DJSchool game;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
game = DJSchool.instance;
|
||||||
anim = GetComponent<Animator>();
|
anim = GetComponent<Animator>();
|
||||||
TurnTable.GetComponent<Animator>().speed = 0;
|
tableAnim = TurnTable.GetComponent<Animator>();
|
||||||
|
tableAnim.speed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
if (!isHolding)
|
float beatToUse = shouldBeHolding ? swipeBeat : holdBeat;
|
||||||
|
float normalizedBeat = Conductor.instance.GetPositionFromMargin(beatToUse + 2, 1);
|
||||||
|
|
||||||
|
if (eligible)
|
||||||
{
|
{
|
||||||
float normalizedBeatHold = Conductor.instance.GetPositionFromBeat(holdBeat, 2);
|
StateCheck(normalizedBeat);
|
||||||
|
|
||||||
StateCheck(normalizedBeatHold);
|
if (normalizedBeat > Minigame.LateTime())
|
||||||
|
|
||||||
if (PlayerInput.Pressed())
|
|
||||||
{
|
{
|
||||||
if (state.perfect)
|
eligible = false;
|
||||||
|
missed = true;
|
||||||
|
|
||||||
|
if (shouldBeHolding)
|
||||||
{
|
{
|
||||||
Hold(true);
|
shouldBeHolding = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Hold(false);
|
shouldBeHolding = true;
|
||||||
|
game.SetDJYellowHead(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (isHolding)
|
|
||||||
|
if (!isHolding)
|
||||||
{
|
{
|
||||||
float normalizedBeatSwipe = Conductor.instance.GetPositionFromBeat(swipeBeat, 2);
|
if (PlayerInput.Pressed())
|
||||||
|
|
||||||
StateCheck(normalizedBeatSwipe);
|
|
||||||
|
|
||||||
print(normalizedBeatSwipe); ;
|
|
||||||
|
|
||||||
if (PlayerInput.PressedUp())
|
|
||||||
{
|
{
|
||||||
if (state.perfect)
|
if (!shouldBeHolding && state.perfect && eligible)
|
||||||
{
|
{
|
||||||
Swipe();
|
Hold(true);
|
||||||
|
eligible = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UnHold();
|
if (!shouldBeHolding)
|
||||||
|
eligible = false;
|
||||||
|
|
||||||
|
Hold(false);
|
||||||
|
|
||||||
|
missed = true;
|
||||||
|
game.SetDJYellowHead(3, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (PlayerInput.PressedUp())
|
||||||
|
{
|
||||||
|
if (shouldBeHolding && state.perfect && eligible)
|
||||||
|
{
|
||||||
|
Swipe(true);
|
||||||
|
eligible = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (shouldBeHolding)
|
||||||
|
{
|
||||||
|
Swipe(false);
|
||||||
|
eligible = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UnHold();
|
||||||
|
}
|
||||||
|
|
||||||
|
missed = true;
|
||||||
|
game.SetDJYellowHead(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +117,13 @@ namespace RhythmHeavenMania.Games.DJSchool
|
||||||
public void Hold(bool ace)
|
public void Hold(bool ace)
|
||||||
{
|
{
|
||||||
isHolding = true;
|
isHolding = true;
|
||||||
|
|
||||||
|
if (ace)
|
||||||
|
{
|
||||||
|
missed = false;
|
||||||
|
shouldBeHolding = true;
|
||||||
|
game.SetDJYellowHead(1);
|
||||||
|
}
|
||||||
|
|
||||||
Jukebox.PlayOneShotGame("djSchool/recordStop");
|
Jukebox.PlayOneShotGame("djSchool/recordStop");
|
||||||
anim.Play("Hold", 0, 0);
|
anim.Play("Hold", 0, 0);
|
||||||
|
@ -91,29 +140,51 @@ namespace RhythmHeavenMania.Games.DJSchool
|
||||||
{
|
{
|
||||||
isHolding = false;
|
isHolding = false;
|
||||||
|
|
||||||
anim.speed = -1;
|
anim.Play("Unhold", 0, 0);
|
||||||
anim.Play("Hold", 0, 0);
|
|
||||||
|
|
||||||
// Settings.GetMusicMixer().audioMixer.FindSnapshot("Main").TransitionTo(0.15f);
|
// Settings.GetMusicMixer().audioMixer.FindSnapshot("Main").TransitionTo(0.15f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Swipe()
|
public void Swipe(bool ace)
|
||||||
{
|
{
|
||||||
isHolding = false;
|
isHolding = false;
|
||||||
|
|
||||||
|
if (ace)
|
||||||
|
{
|
||||||
|
missed = false;
|
||||||
|
shouldBeHolding = false;
|
||||||
|
Jukebox.PlayOneShotGame("djSchool/recordSwipe");
|
||||||
|
FlashFX(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Missed record swipe sound should play here.
|
||||||
|
}
|
||||||
|
|
||||||
Jukebox.PlayOneShotGame("djSchool/recordSwipe");
|
|
||||||
anim.Play("Swipe", 0, 0);
|
anim.Play("Swipe", 0, 0);
|
||||||
|
|
||||||
FlashFX(false);
|
tableAnim.speed = 1;
|
||||||
|
tableAnim.Play("Student_Turntable_Swipe", 0, 0);
|
||||||
TurnTable.GetComponent<Animator>().speed = 1;
|
|
||||||
TurnTable.GetComponent<Animator>().Play("Student_Turntable_Swipe", 0, 0);
|
|
||||||
|
|
||||||
Instantiate(slamFX).SetActive(true);
|
Instantiate(slamFX).SetActive(true);
|
||||||
|
|
||||||
// Settings.GetMusicMixer().audioMixer.FindSnapshot("Main").TransitionTo(0.15f);
|
// Settings.GetMusicMixer().audioMixer.FindSnapshot("Main").TransitionTo(0.15f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnAce()
|
||||||
|
{
|
||||||
|
if (!shouldBeHolding)
|
||||||
|
{
|
||||||
|
Hold(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Swipe(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
eligible = false;
|
||||||
|
}
|
||||||
|
|
||||||
private void FlashFX(bool inverse)
|
private void FlashFX(bool inverse)
|
||||||
{
|
{
|
||||||
GameObject prefab = flashFX;
|
GameObject prefab = flashFX;
|
||||||
|
|
|
@ -191,11 +191,11 @@ namespace RhythmHeavenMania
|
||||||
new GameAction("and stop ooh", delegate { DJSchool.instance.AndStop(eventCaller.currentEntity.beat); }, 2.5f),
|
new GameAction("and stop ooh", delegate { DJSchool.instance.AndStop(eventCaller.currentEntity.beat); }, 2.5f),
|
||||||
new GameAction("break c'mon ooh", delegate { DJSchool.instance.BreakCmon(eventCaller.currentEntity.beat, eventCaller.currentEntity.type); }, 3f, false, new List<Param>()
|
new GameAction("break c'mon ooh", delegate { DJSchool.instance.BreakCmon(eventCaller.currentEntity.beat, eventCaller.currentEntity.type); }, 3f, false, new List<Param>()
|
||||||
{
|
{
|
||||||
new Param("type", new EntityTypes.Integer(0, 2, 0), "Type"),
|
new Param("type", DJSchool.DJVoice.Standard, "Voice"),
|
||||||
}),
|
}),
|
||||||
new GameAction("scratch-o hey", delegate { DJSchool.instance.ScratchoHey(eventCaller.currentEntity.beat, eventCaller.currentEntity.type); }, 3f, false, new List<Param>()
|
new GameAction("scratch-o hey", delegate { DJSchool.instance.ScratchoHey(eventCaller.currentEntity.beat, eventCaller.currentEntity.type); }, 3f, false, new List<Param>()
|
||||||
{
|
{
|
||||||
new Param("type", new EntityTypes.Integer(0, 2, 0), "Type"),
|
new Param("type", DJSchool.DJVoice.Standard, "Voice"),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
new Minigame("rhythmTweezers", "Rhythm Tweezers", "98b389", false, false, new List<GameAction>()
|
new Minigame("rhythmTweezers", "Rhythm Tweezers", "98b389", false, false, new List<GameAction>()
|
||||||
|
|
Loading…
Reference in a new issue