45 achievements

This commit is contained in:
madeline
2026-05-08 11:20:17 -07:00
parent 6217e071d2
commit be82e606b2
7 changed files with 149 additions and 26 deletions
+1 -2
View File
@@ -12,9 +12,8 @@
namespace dusk {
enum class AchievementCategory : uint8_t {
Story,
Collection,
Challenge,
Collection,
Minigame,
Misc,
Glitched
+14
View File
@@ -17,6 +17,7 @@ body {
window {
display: flex;
flex-flow: column;
position: relative;
height: 100%;
width: 100%;
max-width: 1088dp;
@@ -291,6 +292,19 @@ icon.question-mark {
decorator: text("" center center);
}
.achievement-total {
position: absolute;
top: 0;
right: 64dp;
height: 64dp;
line-height: 64dp;
font-family: "Fira Sans Condensed";
font-weight: bold;
font-size: 16dp;
color: rgba(224, 219, 200, 55%);
pointer-events: none;
}
.achievement-row {
display: flex;
align-items: flex-start;
+105 -20
View File
@@ -48,13 +48,13 @@ static constexpr auto ACHIEVEMENTS_FILENAME = "achievements.json";
std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
return {
// Story
// Challenge
{
{
"hero_of_twilight",
"Hero of Twilight",
"Deliver the finishing blow to Ganondorf.",
AchievementCategory::Story,
AchievementCategory::Challenge,
false, 0, 0, false
},
[](Achievement& a, json&) {
@@ -69,8 +69,8 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
{
"completionist",
"Completionist",
"100% the game.",
AchievementCategory::Story,
"Complete the game after collecting all equipment, heart containers, portals, bugs, poes, and hidden skills.",
AchievementCategory::Challenge,
false, 0, 0, false
},
[](Achievement& a, json&) {
@@ -352,7 +352,19 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
},
{}
},
// Challenge
{
{
"all_letters",
"We Deliver!",
"Collect all 16 postman letters.",
AchievementCategory::Collection,
true, 16, 0, false
},
[](Achievement& a, json&) {
a.progress = dMeter2Info_getRecieveLetterNum();
},
{}
},
{
{
"cave_of_ordeals",
@@ -428,7 +440,7 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
"dark_hammer_one_hit",
"Mortal Edge",
"Defeat Dark Hammer in a single hit.",
AchievementCategory::Challenge,
AchievementCategory::Misc,
false, 0, 0, false
},
[](Achievement& a, json&) {
@@ -481,7 +493,7 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
"bow_100m_hit",
"Long Shot",
"Hit an enemy from over 100 meters away with the bow.",
AchievementCategory::Challenge,
AchievementCategory::Misc,
false, 0, 0, false
},
[](Achievement& a, json&) {
@@ -616,6 +628,36 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
},
{}
},
{
{
"star_2_under_40s",
"Rising Star",
"Complete the STAR Prize 2 minigame in under 40 seconds.",
AchievementCategory::Minigame,
false, 0, 0, false
},
[](Achievement& a, json&) {
if(dComIfGs_getHookGameTime() > 0 && dComIfGs_getHookGameTime() <= 40000) {
a.progress = 1;
}
},
{}
},
{
{
"star_2_under_30s",
"Shooting Star",
"Complete the STAR Prize 2 minigame in under 30 seconds.",
AchievementCategory::Minigame,
false, 0, 0, false
},
[](Achievement& a, json&) {
if(dComIfGs_getHookGameTime() > 0 && dComIfGs_getHookGameTime() <= 30000) {
a.progress = 1;
}
},
{}
},
// Misc
{
{
@@ -800,19 +842,6 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
},
{}
},
{
{
"ultimate_delivery",
"The Ultimate Delivery",
"Have all 16 postman letters at the same time.",
AchievementCategory::Glitched,
true, 16, 0, false
},
[](Achievement& a, json&) {
a.progress = dMeter2Info_getRecieveLetterNum();
},
{}
},
{
{
"speedrun_4h",
@@ -918,6 +947,62 @@ std::vector<AchievementSystem::Entry> AchievementSystem::makeEntries() {
}
},
{}
},
{
{
"lakebed_before_lanayru",
"White Midna Glitch",
"Clear the Lakebed Temple before clearing Lanayru's Twilight.",
AchievementCategory::Glitched,
false, 0, 0, false
},
[](Achievement& a, json&) {
if (dComIfGs_isEventBit(dSv_event_flag_c::M_045) &&
!dComIfGs_isDarkClearLV(2)) {
a.progress = 1;
}
},
{}
},
{
{
"early_hidden_village",
"Quick Detour",
"Rescue the Hidden Village before clearing Goron Mines.",
AchievementCategory::Glitched,
false, 0, 0, false
},
[](Achievement& a, json&) {
if (dComIfGs_isEventBit(dSv_event_flag_c::F_0278) &&
!dComIfGs_isEventBit(dSv_event_flag_c::M_031)) {
a.progress = 1;
}
},
{}
},
{
{
"forest_temple_no_boomerang",
"Must Have Been The Wind",
"Complete the Forest Temple without obtaining the Gale Boomerang.",
AchievementCategory::Glitched,
false, 0, 0, false
},
[](Achievement& a, json&) {
if (!dComIfGs_isEventBit(dSv_event_flag_c::M_022)) {
return;
}
if (daPy_getPlayerActorClass() == nullptr) {
return;
}
for (int i = 0; i < 24; ++i) {
if (dComIfGs_getItem(i, false) == dItemNo_BOOMERANG_e) {
return;
}
}
a.progress = 1;
},
{}
}
};
}
+25 -2
View File
@@ -16,9 +16,8 @@ struct CategoryInfo {
};
constexpr CategoryInfo kCategories[] = {
{AchievementCategory::Story, "Story"},
{AchievementCategory::Collection, "Collection"},
{AchievementCategory::Challenge, "Challenge"},
{AchievementCategory::Collection, "Collection"},
{AchievementCategory::Minigame, "Minigame"},
{AchievementCategory::Misc, "Misc"},
{AchievementCategory::Glitched, "Glitched"},
@@ -114,6 +113,13 @@ private:
AchievementsWindow::AchievementsWindow() {
const auto all = AchievementSystem::get().getAchievements();
{
auto elem = mDocument->CreateElement("div");
elem->SetClass("achievement-total", true);
mTotalEl = mRoot->AppendChild(std::move(elem));
updateTotal();
}
for (const auto& catInfo : kCategories) {
int catTotal = 0;
for (const auto& a : all) {
@@ -201,8 +207,25 @@ void AchievementsWindow::update() {
if (dirty) {
mSnapshot = current;
refresh_active_tab();
updateTotal();
}
Window::update();
}
void AchievementsWindow::updateTotal() {
if (mTotalEl == nullptr) {
return;
}
const auto all = AchievementSystem::get().getAchievements();
int total = static_cast<int>(all.size());
int unlocked = 0;
for (const auto& a : all) {
if (a.unlocked) {
++unlocked;
}
}
const int pct = total > 0 ? (unlocked * 100 / total) : 0;
mTotalEl->SetInnerRML(fmt::format("{}%", pct));
}
} // namespace dusk::ui
+2
View File
@@ -13,7 +13,9 @@ public:
void update() override;
private:
void updateTotal();
std::vector<Achievement> mSnapshot;
Rml::Element* mTotalEl = nullptr;
};
} // namespace dusk::ui
+2
View File
@@ -14,6 +14,7 @@
#include "d/actor/d_a_midna.h"
#include "d/d_model.h"
#include "d/d_tresure.h"
#include "dusk/achievements.h"
#include "dusk/frame_interpolation.h"
#include "dusk/livesplit.h"
#include "dusk/logging.h"
@@ -828,6 +829,7 @@ void fapGm_Execute() {
cCt_Counter(0);
#ifdef TARGET_PC
dusk::speedrun::onGameFrame();
dusk::AchievementSystem::get().tick();
#endif
}
-2
View File
@@ -46,7 +46,6 @@
#include <system_error>
#include <thread>
#include "SSystem/SComponent/c_API.h"
#include "dusk/achievements.h"
#include "dusk/app_info.hpp"
#include "dusk/crash_reporting.h"
#include "dusk/dusk.h"
@@ -283,7 +282,6 @@ void main01(void) {
dusk::gyro::read(pacing.sim_pace);
fapGm_Execute();
mDoAud_Execute();
dusk::AchievementSystem::get().tick();
dusk::game_clock::commit_sim_tick();
}
}