Skip to content

Commit 619a881

Browse files
committed
pad engine, beatlines
1 parent 873a6c0 commit 619a881

File tree

21 files changed

+809
-207
lines changed

21 files changed

+809
-207
lines changed

Encore/src/RhythmEngine/ChartLoaders/GuitarLoader.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,16 @@ Encore::RhythmEngine::GuitarLoader::GetNoteType(const smf::MidiEvent &event) {
8787
return 0;
8888
}
8989
}
90-
if (!chart.empty()) {
91-
if (chart[0].back().StartTicks + 170 >= event.tick) {
92-
return 1;
90+
if (!chart[0].empty()) {
91+
// DUDE ARE YOU A FUCKING MORON
92+
// HOPOS HAVE SPECIFIC REQURIEMENTS TO BE HOPOS, NOT JUST "its close enough"
93+
// GOD FUCKING DAMN
94+
// ALSO THAT IF STATEMENT IS FUCKING UTTERLY USELESS
95+
// oh my god i might DIE what the FUCK
96+
if (chart[0].back().Lane != PlasticFrets[GetEventLane(Difficulty, event)]) {
97+
if (chart[0].back().StartTicks + 170 >= event.tick) {
98+
return 1;
99+
}
93100
}
94101
}
95102
return 0;
@@ -130,11 +137,17 @@ void Encore::RhythmEngine::GuitarLoader::GetChartEvents(smf::MidiEventList track
130137
}
131138
}
132139
void Encore::RhythmEngine::GuitarLoader::CreateNote(const smf::MidiEvent &event) {
140+
int lengthTicks = event.getLinkedEvent()->tick - event.tick;
141+
double lengthSec = event.getLinkedEvent()->seconds - event.seconds;
142+
if (event.getLinkedEvent()->tick - event.tick < 170) {
143+
lengthTicks = 0;
144+
lengthSec = 0;
145+
}
133146
chart[0].push_back(
134147
{ event.tick,
135-
event.getLinkedEvent()->tick - event.tick,
148+
lengthTicks,
136149
event.seconds,
137-
event.getLinkedEvent()->seconds - event.seconds,
150+
lengthSec,
138151
GetNoteType(event),
139152
PlasticFrets[GetEventLane(Difficulty, event)] }
140153
);
@@ -187,6 +200,12 @@ void Encore::RhythmEngine::GuitarLoader::GetNotes(smf::MidiEventList track) {
187200
}
188201
if (chart[0].back().StartTicks == event.tick) {
189202
chart[0].back().Lane += PlasticFrets[GetEventLane(Difficulty, event)];
203+
chart[0].back().NoteType = 0;
204+
if (!ForceHopoOn.empty()) {
205+
if (ForceHopoOn.front().first <= event.tick) {
206+
chart[0].back().NoteType = 1;
207+
}
208+
}
190209
} else {
191210
CreateNote(event);
192211
}

Encore/src/RhythmEngine/ChartLoaders/PadLoader.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void Encore::RhythmEngine::PadLoader::CheckEvents(const smf::MidiEvent &event) {
4848

4949
[[nodiscard]] int
5050
Encore::RhythmEngine::PadLoader::GetNoteType(const smf::MidiEvent &event) {
51-
if (!LiftMarkers.empty()) {
51+
if (!LiftMarkers[GetEventLane(Difficulty, event)].empty()) {
5252
if (LiftMarkers[GetEventLane(Difficulty, event)].front() == event.tick) {
5353
return 1; // lift
5454
}
@@ -79,28 +79,37 @@ void Encore::RhythmEngine::PadLoader::GetChartEvents(smf::MidiEventList track) {
7979
}
8080

8181
void Encore::RhythmEngine::PadLoader::CreateNote(const smf::MidiEvent &event) {
82+
int lengthTicks = event.getLinkedEvent()->tick - event.tick;
83+
double lengthSec = event.getLinkedEvent()->seconds - event.seconds;
84+
if (event.getLinkedEvent()->tick - event.tick < 170) {
85+
lengthTicks = 0;
86+
lengthSec = 0;
87+
}
8288
chart[GetEventLane(Difficulty, event)].push_back(
8389
{
8490
event.tick,
85-
event.getLinkedEvent()->tick - event.tick,
91+
lengthTicks,
8692
event.seconds,
87-
event.getLinkedEvent()->seconds - event.seconds,
93+
lengthSec,
8894
GetNoteType(event),
8995
}
9096
);
9197
// i hate how solos need note counts before entering lol
92-
if (event.tick >= chart.solos[CurrentSolo].StartTick) {
93-
chart.solos[CurrentSolo].NoteCount++;
98+
if (!chart.solos.empty()) {
99+
if (event.tick >= chart.solos[CurrentSolo].StartTick) {
100+
chart.solos[CurrentSolo].NoteCount++;
101+
}
94102
}
95103
}
96104

97105
void Encore::RhythmEngine::PadLoader::GetNotes(smf::MidiEventList track) {
98106
track.linkNotePairs();
99107
for (int eventInt = 0; eventInt < track.size(); eventInt++) {
100108
smf::MidiEvent &event = track[eventInt];
109+
if (event[0] == 255) continue;
101110
CheckEvents(event);
102-
CheckModifiers(event);
103-
if (IsInLiftMarkerRange(Difficulty, event) && event.isNoteOn()) {
111+
if (IsInPitchRange(Difficulty, event) && event.isNoteOn()) {
112+
CheckModifiers(event);
104113
CreateNote(event);
105114
}
106115
}

Encore/src/RhythmEngine/Engine/BaseEngine.h

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
#ifndef BASEENGINE_H
66
#define BASEENGINE_H
77
#include "BaseStats.h"
8+
#include "timingvalues.h"
89
#include "RhythmEngine/NoteVector.h"
910

1011
#include <memory>
12+
#include <span>
1113

1214
namespace Encore::RhythmEngine {
1315
enum HitState {
@@ -21,7 +23,19 @@ namespace Encore::RhythmEngine {
2123
BaseEngine(auto _chart, auto _stats) : chart(_chart), stats(_stats) {};
2224
virtual ~BaseEngine() {};
2325
virtual void SetStatsInputState(InputChannel channel, Action action) {};
24-
26+
bool EarlyStrike(double noteStartTime, double inputTime, double inputOffset) {
27+
if (noteStartTime - goodFrontend > inputTime - inputOffset) {
28+
return true;
29+
}
30+
return false;
31+
}
32+
bool InHitwindow(double noteStartTime, double inputTime, double inputOffset) {
33+
if ((noteStartTime - goodFrontend < inputTime - inputOffset)
34+
&& (noteStartTime + goodBackend > inputTime - inputOffset)) {
35+
return true;
36+
}
37+
return false;
38+
}
2539
void ProcessInput(InputChannel channel, Action action);
2640
/*
2741
* Before hitting the note,
@@ -30,8 +44,53 @@ namespace Encore::RhythmEngine {
3044
* If that check went well, hit the note.
3145
* If not, the player overhit the note and should be penalized.
3246
*/
33-
std::shared_ptr<BaseChart<EncNote, 5>> chart;
34-
std::shared_ptr<BaseStats<5>> stats;
47+
std::shared_ptr<BaseChart<EncNote, 5> > chart;
48+
std::shared_ptr<BaseStats<5> > stats;
49+
50+
virtual void UpdateOnFrame(double CurrentTime) {
51+
52+
};
53+
void CheckMissedNotes(int Lane, double SongTime) const {
54+
auto &chartLane = chart->at(Lane);
55+
if (chartLane.empty())
56+
return;
57+
auto itr = chartLane.begin();
58+
59+
for (int notePos = 0; notePos < chartLane.size(); notePos++) {
60+
// no need to check things in the hitwindow
61+
auto& curNote = chartLane.at(notePos);
62+
if (curNote.StartSeconds + curNote.LengthSeconds + goodBackend
63+
>= SongTime - stats->InputOffset) {
64+
return;
65+
}
66+
if (curNote.StartSeconds + goodBackend < SongTime - stats->InputOffset
67+
&& !curNote.NotePassed) {
68+
stats->Combo = 0;
69+
stats->Misses += 1;
70+
stats->AttemptedNotes += 1;
71+
curNote.NotePassed = true;
72+
chart->overdrive.UpdateEventViaNote(false, curNote.StartTicks);
73+
stats->AudioMuted = true;
74+
Encore::EncoreLog(
75+
LOG_DEBUG, TextFormat("Missed note %01i", stats->AttemptedNotes)
76+
);
77+
}
78+
if (curNote.StartSeconds + curNote.LengthSeconds + goodBackend + 0.5
79+
< SongTime - stats->InputOffset) {
80+
chartLane.erase(chartLane.begin());
81+
}
82+
}
83+
84+
}
85+
void RemoveMissedNote(
86+
const EncNote &note, const double CurrentTime, const int lane
87+
) const {
88+
if (note.StartSeconds + note.LengthSeconds + goodBackend + 0.5
89+
< CurrentTime - stats->InputOffset) {
90+
chart->at(lane).erase(chart->at(lane).begin());
91+
}
92+
}
93+
3594
private:
3695
virtual bool PlayerIsPaused() = 0;
3796
virtual void TogglePause() = 0;

Encore/src/RhythmEngine/Engine/BaseStats.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ namespace Encore::RhythmEngine {
1414
UpStrum = 1,
1515
DownStrum = 2
1616
};
17+
enum StatsType {
18+
Pad = 1,
19+
Guitar = 0
20+
};
1721
/**
1822
* @brief BaseStats is the default base class for handling statistics
1923
* that Encore needs to keep track of. This is basic gameplay information,
@@ -39,6 +43,7 @@ namespace Encore::RhythmEngine {
3943
double OverdriveActivationTick = 0.0;
4044
bool OverdriveActive = false;
4145

46+
int Type = 0;
4247
double Score = 0;
4348
int Combo = 0;
4449
int PerfectHits = 0;
@@ -54,7 +59,7 @@ namespace Encore::RhythmEngine {
5459
StrumState strumState = StrumState::Default;
5560
void HitNote(int chordSize) {
5661
Combo++;
57-
Score = (25 * chordSize) * multiplier();
62+
Score += (25 * chordSize) * multiplier();
5863
// PerfectHits = 0;
5964
NotesHit++;
6065
AttemptedNotes++;

Encore/src/RhythmEngine/Engine/GuitarEngine.cpp

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,8 @@
88
#include "gameplay/enctime.h"
99

1010
#include <bit>
11+
#include <filesystem>
1112

12-
bool EarlyStrike(double noteStartTime, double inputTime, double inputOffset) {
13-
if (noteStartTime - goodFrontend > inputTime - inputOffset) {
14-
return true;
15-
}
16-
return false;
17-
}
18-
bool InHitwindow(double noteStartTime, double inputTime, double inputOffset) {
19-
if ((noteStartTime - goodFrontend < inputTime - inputOffset)
20-
&& (noteStartTime + goodBackend > inputTime - inputOffset)) {
21-
return true;
22-
}
23-
return false;
24-
}
2513
bool MaskMatch(uint8_t noteMask, uint8_t playerMask) {
2614
// chord check
2715
if (std::has_single_bit(noteMask)) {
@@ -56,16 +44,22 @@ bool Encore::RhythmEngine::GuitarEngine::ActivateOverdrive(
5644
if (stats->OverdriveFill >= 0.25 && channel == InputChannel::OVERDRIVE
5745
&& action == Action::PRESS) {
5846
stats->OverdriveActive = true;
59-
stats->OverdriveActivationTime = TheSongTime.GetSongTime(); // todo: set to
47+
stats->OverdriveActivationTime = TheSongTime.GetElapsedTime(); // todo: set to
6048
// current input time
6149
return true;
6250
}
6351
return false;
6452
}
53+
void Encore::RhythmEngine::GuitarEngine::UpdateOnFrame(double CurrentTime) {
54+
CheckMissedNotes(0, TheSongTime.GetElapsedTime());
55+
stats->OverdriveFill += chart->overdrive.CheckOverdrive(CurrentTime);
56+
if (stats->OverdriveFill > 1.0) stats->OverdriveFill = 1.0;
57+
// there is ONLY lane 0 for guitar
58+
}
6559
void Encore::RhythmEngine::GuitarEngine::SetStatsInputState(
6660
InputChannel channel, Action action
6761
) {
68-
stats->InputTime = TheSongTime.GetSongTime(); // todo: REPLACE WITH ACTUAL SONG TIME
62+
stats->InputTime = TheSongTime.GetElapsedTime(); // todo: REPLACE WITH ACTUAL SONG TIME
6963
// (IN SECONDS)
7064
if (action == Action::PRESS) {
7165
switch (channel) {
@@ -113,12 +107,15 @@ void Encore::RhythmEngine::GuitarEngine::SetStatsInputState(
113107
int Encore::RhythmEngine::GuitarEngine::RunHitStateCheck(
114108
InputChannel channel, Action action
115109
) {
116-
if (chart->empty())
110+
if (chart->at(0).empty())
117111
return CheckNextInput;
118-
;
112+
119113
auto curNoteItr = chart->at(0).begin();
120114
while (curNoteItr->StartSeconds + goodBackend
121-
< TheSongTime.GetSongTime() - stats->InputOffset) {
115+
< TheSongTime.GetElapsedTime() - stats->InputOffset) {
116+
if (curNoteItr + 1 == chart->at(0).end()) {
117+
return CheckNextInput;
118+
}
122119
++curNoteItr;
123120
}
124121
EncNote &CurrentNote = *curNoteItr;
@@ -130,6 +127,7 @@ int Encore::RhythmEngine::GuitarEngine::RunHitStateCheck(
130127
// miss should be managed by current frame
131128
// overhit is managed here
132129
if (EarlyStrike(CurrentNote.StartSeconds, stats->InputTime, stats->InputOffset)) {
130+
chart->overdrive.UpdateEventViaNote(false, CurrentNote.StartTicks);
133131
return OverhitNote;
134132
}
135133
// if frets match, continue and try to hit
@@ -155,7 +153,8 @@ int Encore::RhythmEngine::GuitarEngine::RunHitStateCheck(
155153
&& InHitwindow(CurrentNote.StartSeconds, stats->InputTime, stats->InputOffset)
156154
&& (HittableAsHopo(CurrentNote.NoteType, stats->Combo)
157155
|| HittableAsTap(CurrentNote.NoteType) || strum)) {
158-
stats->HitNote(std::popcount(chart->at(0).front().Lane));
156+
stats->HitNote(std::popcount(CurrentNote.Lane));
157+
chart->overdrive.UpdateEventViaNote(true, CurrentNote.StartTicks);
159158
stats->FretAfterStrum = false;
160159
chart->at(0).erase(curNoteItr);
161160
return HitState::HitNote;
@@ -170,4 +169,4 @@ void Encore::RhythmEngine::GuitarEngine::HitNote() {
170169
}
171170
void Encore::RhythmEngine::GuitarEngine::Overhit() {
172171
stats->Overhit();
173-
}
172+
}

Encore/src/RhythmEngine/Engine/GuitarEngine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace Encore::RhythmEngine {
4040

4141

4242
public:
43+
void UpdateOnFrame(double CurrentTime) override;
4344
void SetStatsInputState(InputChannel channel, Action action) override;
4445
void HitNote() override;
4546
void Overhit() override;

Encore/src/RhythmEngine/Engine/GuitarStats.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace Encore::RhythmEngine {
1010
class GuitarStats final : public BaseStats<5> {
1111
public:
12+
int Type = 0;
1213
explicit GuitarStats(int BaseScore) : BaseStats<5>(BaseScore) {}
1314
double FretAfterStrumTime = -1;
1415
bool FretAfterStrum = false;

0 commit comments

Comments
 (0)