Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed Audio/335571__magntron__gamemusic_120bpm.mp3
Binary file not shown.
19 changes: 0 additions & 19 deletions Audio/335571__magntron__gamemusic_120bpm.mp3.import

This file was deleted.

Binary file added Audio/Song1.ogg
Binary file not shown.
19 changes: 19 additions & 0 deletions Audio/Song1.ogg.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[remap]

importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://iq0xxe5cggs8"
path="res://.godot/imported/Song1.ogg-1d785b9ae3fbaa8393048e39af66ed86.oggvorbisstr"

[deps]

source_file="res://Audio/Song1.ogg"
dest_files=["res://.godot/imported/Song1.ogg-1d785b9ae3fbaa8393048e39af66ed86.oggvorbisstr"]

[params]

loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4
Binary file added Audio/Song2.ogg
Binary file not shown.
19 changes: 19 additions & 0 deletions Audio/Song2.ogg.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[remap]

importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://ckis6k6vuums"
path="res://.godot/imported/Song2.ogg-b95c04f3512de6fa42e0f9c35aba831f.oggvorbisstr"

[deps]

source_file="res://Audio/Song2.ogg"
dest_files=["res://.godot/imported/Song2.ogg-b95c04f3512de6fa42e0f9c35aba831f.oggvorbisstr"]

[params]

loop=false
loop_offset=0.0
bpm=0.0
beat_count=0
bar_beats=4
Binary file added Audio/Song3.ogg
Binary file not shown.
19 changes: 19 additions & 0 deletions Audio/Song3.ogg.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[remap]

importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://ceyw5mjkem2pi"
path="res://.godot/imported/Song3.ogg-d4e6a5f1a550561df18989fb495ba591.oggvorbisstr"

[deps]

source_file="res://Audio/Song3.ogg"
dest_files=["res://.godot/imported/Song3.ogg-d4e6a5f1a550561df18989fb495ba591.oggvorbisstr"]

[params]

loop=false
loop_offset=0.0
bpm=0.0
beat_count=0
bar_beats=4
Binary file added Audio/midi/Song1.mid
Binary file not shown.
Binary file added Audio/midi/Song2.mid
Binary file not shown.
Binary file added Audio/midi/Song3.mid
Binary file not shown.
Binary file added Audio/midi/florestan-subset.sf2
Binary file not shown.
112 changes: 112 additions & 0 deletions Classes/MidiMaestro/MidiMaestro.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System;
using System.Linq;
using FunkEngine;
using Godot;
using Melanchall.DryWetMidi.Core;
using Melanchall.DryWetMidi.Interaction;
using Melanchall.DryWetMidi.Multimedia;

public partial class MidiMaestro : Resource
{
private MidiFile _midiFile;

//The four note rows that we care about
private midiNoteInfo[] _upNotes;
private midiNoteInfo[] _downNotes;
private midiNoteInfo[] _leftNotes;
private midiNoteInfo[] _rightNotes;

private MidiFile strippedSong;

Check warning on line 19 in Classes/MidiMaestro/MidiMaestro.cs

View workflow job for this annotation

GitHub Actions / build

The field 'MidiMaestro.strippedSong' is never used

Check warning on line 19 in Classes/MidiMaestro/MidiMaestro.cs

View workflow job for this annotation

GitHub Actions / build

The field 'MidiMaestro.strippedSong' is never used

private SongData songData;

//The path relative to the Audio folder. Will change later
public MidiMaestro(string filePath)
{
if (!FileAccess.FileExists(filePath))
{
GD.PrintErr("ERROR: Unable to load level Midi file: " + filePath);
}

_midiFile = MidiFile.Read(filePath);

//Strip out the notes from the midi file
foreach (var track in _midiFile.GetTrackChunks())
{
string trackName = track.Events.OfType<SequenceTrackNameEvent>().FirstOrDefault()?.Text;
midiNoteInfo[] noteEvents = track
.GetNotes()
.Select(note => new midiNoteInfo(note, _midiFile.GetTempoMap()))
.ToArray();

switch (trackName)
{
case "Up":
_upNotes = noteEvents;
break;
case "Down":
_downNotes = noteEvents;
break;
case "Left":
_leftNotes = noteEvents;
break;
case "Right":
_rightNotes = noteEvents;
break;
}
}

//Populate the song data
songData = new SongData
{
//TODO: Allow for changes in this data
Bpm = 120,
//Fudge the numbers a bit if we have a really short song
SongLength =
_midiFile.GetDuration<MetricTimeSpan>().Seconds < 20
? 20
: _midiFile.GetDuration<MetricTimeSpan>().Seconds,
NumLoops = 1,
};
}

public midiNoteInfo[] GetNotes(ArrowType arrowType)
{
return arrowType switch
{
ArrowType.Up => _upNotes,
ArrowType.Down => _downNotes,
ArrowType.Left => _leftNotes,
ArrowType.Right => _rightNotes,
_ => throw new ArgumentOutOfRangeException(nameof(arrowType), arrowType, null),
};
}

public SongData GetSongData()
{
return songData;
}
}

//A facade to wrap the midi notes. This is a simple class that wraps a Note object from the DryWetMidi library.
public class midiNoteInfo
{
private readonly Melanchall.DryWetMidi.Interaction.Note _note;
private readonly TempoMap _tempoMap;

public midiNoteInfo(Melanchall.DryWetMidi.Interaction.Note note, TempoMap tempoMap)
{
_note = note;
_tempoMap = tempoMap;
}

public long GetStartTimeTicks() => _note.Time;

public float GetStartTimeSeconds() =>
_note.TimeAs<MetricTimeSpan>(_tempoMap).Milliseconds / 1000f
+ _note.TimeAs<MetricTimeSpan>(_tempoMap).Seconds;

public long GetEndTime() => _note.EndTime;

public long GetDuration() => _note.Length;
}
25 changes: 25 additions & 0 deletions Classes/MidiMaestro/SongTemplate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace FunkEngine.Classes.MidiMaestro;

public partial class SongTemplate
{
public string Name;
public string AudioLocation;
public string MIDILocation;
public string EnemyScenePath;
public SongData SongData;

public SongTemplate(
SongData songData,
string name = "",
string audioLocation = "",
string midiLocation = "",
string enemyScenePath = ""
)
{
Name = name;
AudioLocation = audioLocation;
MIDILocation = midiLocation;
SongData = songData;
EnemyScenePath = enemyScenePath;
}
}
3 changes: 2 additions & 1 deletion Funk Engine.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Godot.NET.Sdk/4.3.0">
<Project Sdk="Godot.NET.Sdk/4.3.0">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
Expand All @@ -8,6 +8,7 @@
</PropertyGroup>
<ItemGroup>
<Content Include="SaveData\SaveData.json" />
<PackageReference Include="Melanchall.DryWetMidi" Version="7.2.0" />
</ItemGroup>
<Target Name="Husky" BeforeTargets="Restore;CollectPackageReferences" Condition="'$(HUSKY)' != 0">
<Exec Command="dotnet tool restore" StandardOutputImportance="Low" StandardErrorImportance="High" />
Expand Down
5 changes: 3 additions & 2 deletions Globals/FunkEngineNameSpace.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using FunkEngine.Classes.MidiMaestro;
using Godot;

namespace FunkEngine;
Expand Down Expand Up @@ -40,8 +41,8 @@ public struct BattleConfig
{
public Stages RoomType;
public MapGrid.Room BattleRoom;
public int TodoEnemyAndChart;
public SongData CurSong;
public string EnemyScenePath;
public SongTemplate CurSong;
}

public enum BattleEffectTrigger
Expand Down
44 changes: 42 additions & 2 deletions Globals/Scribe.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using FunkEngine;
using FunkEngine.Classes.MidiMaestro;
using Godot;

/**
Expand Down Expand Up @@ -151,7 +152,46 @@ public partial class Scribe : Node
),
};

//TODO: Item pool(s)
public static readonly SongTemplate[] SongDictionary = new[]
{
new SongTemplate(
new SongData
{
Bpm = 120,
SongLength = -1,
NumLoops = 5,
},
"Song1",
"Audio/Song1.ogg",
"Audio/midi/song1.mid"
),
new SongTemplate(
new SongData
{
Bpm = 60,
SongLength = -1,
NumLoops = 1,
},
"Song2",
"Audio/Song2.ogg",
"Audio/midi/Song2.mid",
"res://scenes/Puppets/Enemies/Parasifly/Parasifly.tscn"
),
new SongTemplate(
new SongData
{
Bpm = 120,
SongLength = -1,
NumLoops = 1,
},
"Song3",
"Audio/Song3.ogg",
"Audio/midi/Song3.mid",
"res://scenes/Puppets/Enemies/TheGWS/GWS.tscn"
),
};

//TODO: Item pool(s)

public static RelicTemplate[] GetRandomRelics(RelicTemplate[] ownedRelics, int count)
{
Expand All @@ -171,7 +211,7 @@ public static RelicTemplate[] GetRandomRelics(RelicTemplate[] ownedRelics, int c
}
return availableRelics;
}

public static Note[] GetRandomRewardNotes(int count)
{
var availableNotes = Scribe
Expand Down
22 changes: 15 additions & 7 deletions Globals/StageProducer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public partial class StageProducer : Node
public void StartGame()
{
Map.InitMapGrid(MapSize.X, MapSize.Y, 3);
GlobalRng.Randomize();
_seed = GlobalRng.Seed;
_lastRngState = GlobalRng.State;
PlayerStats = new PlayerStats();
Expand Down Expand Up @@ -59,6 +60,10 @@ public void TransitionStage(Stages nextStage, int nextRoomIdx = -1)
Config = MakeConfig(nextStage, nextRoomIdx);
GetTree().ChangeSceneToFile("res://scenes/BattleDirector/test_battle_scene.tscn");
break;
case Stages.Boss:
Config = MakeConfig(nextStage, nextRoomIdx);
GetTree().ChangeSceneToFile("res://scenes/BattleDirector/test_battle_scene.tscn");
break;
case Stages.Controls:
GetTree().ChangeSceneToFile("res://scenes/Remapping/Remap.tscn");
break;
Expand Down Expand Up @@ -90,14 +95,17 @@ private BattleConfig MakeConfig(Stages nextRoom, int nextRoomIdx)
BattleConfig result = new BattleConfig();
result.BattleRoom = Map.GetRooms()[nextRoomIdx];
result.RoomType = nextRoom;
if (nextRoom is Stages.Battle or Stages.Boss)
switch (nextRoom)
{
result.CurSong = new SongData
{
Bpm = 120,
SongLength = -1,
NumLoops = 5,
};
case Stages.Battle:
int songIdx = GlobalRng.RandiRange(1, 2);
result.CurSong = Scribe.SongDictionary[songIdx];
result.EnemyScenePath = Scribe.SongDictionary[songIdx].EnemyScenePath;
break;
case Stages.Boss:
result.EnemyScenePath = "res://scenes/Puppets/Enemies/BossBlood/Boss1.tscn";
result.CurSong = Scribe.SongDictionary[0];
break;
}

return result;
Expand Down
Loading