mirror of https://github.com/sm64pc/sm64pc.git
364 lines
21 KiB
C++
364 lines
21 KiB
C++
#include "achievements.h"
|
|
#include "moon/mod-engine/hooks/hook.h"
|
|
#include "moon/ui/utils/moon-draw-utils.h"
|
|
#include "moon/ui/interfaces/moon-screen.h"
|
|
#include "moon/utils/umath.h"
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
#include "moon/ui/interfaces/moon-screen.h"
|
|
#include "moon/ui/animation/algorithms.h"
|
|
#include "moon/mod-engine/models/mod-model.h"
|
|
|
|
extern "C" {
|
|
#include "pc/cheats.h"
|
|
#include "moon/utils/moon-gfx.h"
|
|
#include "pc/platform.h"
|
|
#include "game/level_update.h"
|
|
#include "audio/external.h"
|
|
#include "audio_defines.h"
|
|
#include "game/area.h"
|
|
#include "game/object_list_processor.h"
|
|
#include "sm64.h"
|
|
#include "level_table.h"
|
|
#include "game/save_file.h"
|
|
}
|
|
|
|
#define ALL_MAIN_STARS 0x7F
|
|
|
|
using namespace std;
|
|
|
|
map<string, Achievement*> registeredAchievements;
|
|
map<int, vector<AchievementEntry*>> entries;
|
|
bool cheatsGotEnabled = true;
|
|
|
|
namespace AchievementList {
|
|
/* Star achievements */
|
|
Achievement* GET_1_STAR = MoonAchievements::bind(new Achievement("achievement.get1Stars", "textures/moon/achievements/stars.1.rgba16", "Your journey begins!", "Get one star", false, 0, 150, nullptr));
|
|
Achievement* GET_8_STARS = MoonAchievements::bind(new Achievement("achievement.get8Stars", "textures/moon/achievements/stars.8.rgba16", "You feel a strong power", "Get 8 stars", false, 0, 150, GET_1_STAR));
|
|
Achievement* GET_30_STARS = MoonAchievements::bind(new Achievement("achievement.get30Stars", "textures/moon/achievements/stars.30.rgba16", "Earning A Quarter", "Get 30 stars", false, 0, 150, GET_8_STARS));
|
|
Achievement* GET_31_STARS = MoonAchievements::bind(new Achievement("achievement.get31Stars", "textures/moon/achievements/stars.31.rgba16", "Extra Cent", "Get 31 stars", false, 0, 150, GET_8_STARS));
|
|
Achievement* GET_50_STARS = MoonAchievements::bind(new Achievement("achievement.get50Stars", "textures/moon/achievements/stars.50.rgba16", "Lucky Eight", "Get 50 stars", false, 0, 150, GET_30_STARS));
|
|
Achievement* GET_70_STARS = MoonAchievements::bind(new Achievement("achievement.get70Stars", "textures/moon/achievements/stars.70.rgba16", "Halfway done!", "Get 70 stars", false, 0, 150, GET_50_STARS));
|
|
Achievement* GET_120_STARS = MoonAchievements::bind(new Achievement("achievement.get120Stars", "textures/moon/achievements/stars.120.rgba16", "The Completionist", "Get 120 stars", false, 0, 150, GET_70_STARS));
|
|
|
|
/* Cap Achievements */
|
|
Achievement* UNLOCK_WING_CAP = MoonAchievements::bind(new Achievement("achievement.unlockWingCap", "textures/moon/achievements/caps.wing-cap.rgba16", "Super Man-rio", "Unlock the wing cap", false, 0, 150, nullptr));
|
|
Achievement* UNL0CK_METAL_CAP = MoonAchievements::bind(new Achievement("achievement.unlockMetalCap", "textures/moon/achievements/caps.metal-cap.rgba16", "Heavy-Headed", "Unlock the metal cap", false, 0, 150, nullptr));
|
|
Achievement* UNLOCK_VANISH_CAP = MoonAchievements::bind(new Achievement("achievement.unlockVanishCap", "textures/moon/achievements/caps.vanish-cap.rgba16", "Wait, Where Is He?", "Unlock the vanish cap", false, 0, 150, nullptr));
|
|
|
|
/* Level Achievements */
|
|
Achievement* GET_6_LEVEL_STARS = MoonAchievements::bind(new Achievement("achievement.get6MainStars", "textures/moon/achievements/ranks.f.rgba16", "F Rank", "Get all 6 Main Stars in One Level", false, 0, 150, nullptr));
|
|
Achievement* GET_100_COIN_STAR = MoonAchievements::bind(new Achievement("achievement.get100CoinStar", "textures/moon/achievements/ranks.e.rgba16", "E Rank", "Get a 100 Coin Star in One Level", false, 0, 150, nullptr));
|
|
Achievement* GET_ALL_LVL_COINS = MoonAchievements::bind(new Achievement("achievement.getAllCoins", "textures/moon/achievements/ranks.d.rgba16", "D Rank", "Get all Coins in One Level", false, 0, 150, nullptr));
|
|
Achievement* GET_FLOOR_0_STARS = MoonAchievements::bind(new Achievement("achievement.getAllStarsInBasement", "textures/moon/achievements/ranks.b.rgba16", "B Rank", "Get all Main Stars in the First Floor", false, 0, 150, nullptr));
|
|
Achievement* GET_FLOOR_1_STARS = MoonAchievements::bind(new Achievement("achievement.getAllStarsInFloor1", "textures/moon/achievements/ranks.c.rgba16", "C Rank", "Get all Main Stars in the Basement", false, 0, 150, nullptr));
|
|
Achievement* GET_FLOOR_2_STARS = MoonAchievements::bind(new Achievement("achievement.getAllStarsInFloor2", "textures/moon/achievements/ranks.a.rgba16", "A Rank", "Get all Main Stars in the Second Floor", false, 0, 150, nullptr));
|
|
Achievement* GET_FLOOR_3_STARS = MoonAchievements::bind(new Achievement("achievement.getAllStarsInFloor3", "textures/moon/achievements/ranks.s.rgba16", "S Rank", "Get all Main Stars in the Third Floor", false, 0, 150, nullptr));
|
|
Achievement* GET_CASTLE_STARS = MoonAchievements::bind(new Achievement("achievement.getAllCastleStars", "textures/moon/achievements/ranks.splus.rgba16", "S+ Rank", "Get all Castle Secret Stars", false, 0, 150, nullptr));
|
|
|
|
/* Boss Achievements */
|
|
Achievement* DEFEAT_MRI = MoonAchievements::bind(new Achievement("achievement.beatMr.I", "textures/moon/achievements/bosses.mr-i.rgba16", "I vs Eye", "Beat Mr.I", false, 0, 150, nullptr));
|
|
Achievement* DEFEAT_WIGGLER = MoonAchievements::bind(new Achievement("achievement.beatWiggler", "textures/moon/achievements/bosses.wiggler.rgba16", "Insecticude", "Beat Wiggler", false, 0, 150, nullptr));
|
|
Achievement* DEFEAT_KINGBOB = MoonAchievements::bind(new Achievement("achievement.beatKingBobOmb", "textures/moon/achievements/bosses.big-bob.rgba16", "Explosive Test", "Beat King Bob-Omb", false, 0, 150, nullptr));
|
|
Achievement* DEFEAT_ALL_BULLY = MoonAchievements::bind(new Achievement("achievement.beatAllBigBullies", "textures/moon/achievements/bosses.big-bully.rgba16", "The Real Bully", "Beat all big bullies from LLL", false, 0, 150, nullptr));
|
|
Achievement* DEFEAT_EYEROK = MoonAchievements::bind(new Achievement("achievement.beatEyerok", "textures/moon/achievements/bosses.eyerok.rgba16", "Welcome To The Jam", "Beat Eyerok", false, 0, 150, nullptr));
|
|
Achievement* DEFEAT_KINGWHOMP = MoonAchievements::bind(new Achievement("achievement.beatKingWhomp", "textures/moon/achievements/bosses.king-whomp.rgba16", "Come On And Slam", "Beat King Whomp", false, 0, 150, nullptr));
|
|
Achievement* DEFEAT_BOWSER2 = MoonAchievements::bind(new Achievement("achievement.beatSecondBowser", "textures/moon/achievements/bowser.2.rgba16", "Bowser Burned By The Lava", "Beat second Bowser", false, 0, 150, nullptr));
|
|
Achievement* DEFEAT_BOWSER1 = MoonAchievements::bind(new Achievement("achievement.beatFirstBowser", "textures/moon/achievements/bowser.1.rgba16", "Bowser Trapped In The Dark", "Beat first Bowser", false, 0, 150, nullptr));
|
|
Achievement* DEFEAT_120S_BOWSER = MoonAchievements::bind(new Achievement("achievement.beatGame120Stars", "textures/moon/achievements/bowser.3-with-120-stars.rgba16", "Power Battle", "Beat final Bowser with 120 stars", false, 0, 150, nullptr));
|
|
Achievement* DEFEAT_ALL_BOOS = MoonAchievements::bind(new Achievement("achievement.beatAll3BoosOnLLL", "textures/moon/achievements/bosses.big-boo.rgba16", "Mario, Where Are You??", "Beat all Boos from BBH", false, 0, 150, nullptr));
|
|
Achievement* DEFEAT_BOWSER3 = MoonAchievements::bind(new Achievement("achievement.beatFinalBowser", "textures/moon/achievements/bowser.3.rgba16", "Bowser Launched Into The Sky", "Beat final Bowser", false, 0, 150, nullptr));
|
|
|
|
/* Death Achievements */
|
|
Achievement* DEATH_BY_BOSS = MoonAchievements::bind(new Achievement("achievement.deathByBoss", "textures/moon/achievements/deaths.boss.rgba16", "Git Gud", "Get killed by a boss", false, 0, 150, nullptr));
|
|
Achievement* DEATH_BY_FALLING = MoonAchievements::bind(new Achievement("achievement.deathByFalling", "textures/moon/achievements/deaths.falling.rgba16", "My Leg!", "Die by falling", false, 0, 150, nullptr));
|
|
Achievement* DEATH_BY_SAND = MoonAchievements::bind(new Achievement("achievement.deathBySand", "textures/moon/achievements/deaths.quicksand.rgba16", "Sinked", "Die in the quicksand", false, 0, 150, nullptr));
|
|
Achievement* DEATH_BY_CRUSHING = MoonAchievements::bind(new Achievement("achievement.deathByCrushing", "textures/moon/achievements/deaths.crushed.rgba16", "Space Jam", "Get crushed", false, 0, 150, nullptr));
|
|
Achievement* DEATH_BY_BOWSER = MoonAchievements::bind(new Achievement("achievement.deathByBowser", "textures/moon/achievements/deaths.bowser.rgba16", "Bad Ending", "Get killed by Bowser", false, 0, 150, nullptr));
|
|
Achievement* DEATH_BY_ENEMY = MoonAchievements::bind(new Achievement("achievement.deathByEnemy", "textures/moon/achievements/deaths.standard.rgba16", "Classic Way", "Get killed by a normal enemy", false, 0, 150, nullptr));
|
|
Achievement* DEATH_BY_DROWNING = MoonAchievements::bind(new Achievement("achievement.deathByDrowning", "textures/moon/achievements/deaths.drowning.rgba16", "Under The Sea", "Die by drowning", false, 0, 150, nullptr));
|
|
Achievement* DEATH_BY_FIRE = MoonAchievements::bind(new Achievement("achievement.deathByFire", "textures/moon/achievements/extras.carpet-burn.rgba16", "Roasted Mario", "Die by fire", false, 0, 150, nullptr));
|
|
|
|
/* Extra Achievements */
|
|
Achievement* TALK_WITH_YOSHI = MoonAchievements::bind(new Achievement("achievement.talkWithYoshi", "textures/moon/achievements/extras.yoshi.rgba16", "It Is You?", "Talk with Yoshi", false, 0, 150, nullptr));
|
|
Achievement* SLIDE_100_TIMES = MoonAchievements::bind(new Achievement("achievement.slide20Times", "textures/moon/achievements/extras.carpet-burn.rgba16", "Burned Ass", "Go trough slides 100 times", false, 0, 150, nullptr));
|
|
// Achievement* BEAT_EVERY_RACE = MoonAchievements::bind(new Achievement("achievement.beatEveryRace", "textures/moon/achievements/extras.runner.rgba16", "Olympic Runner", "Beat every race", false, 0, 150, nullptr));
|
|
Achievement* TALK_25_TIMES = MoonAchievements::bind(new Achievement("achievement.talk25Times", "textures/moon/achievements/extras.talker.rgba16", "Olympic Talker", "Talk 25 times with npcs", false, 0, 150, nullptr));
|
|
Achievement* JUMP_1000_TIMES = MoonAchievements::bind(new Achievement("achievement.jump1000Times", "textures/moon/achievements/extras.swimmer.rgba16", "Olympic Swimmer", "Grab every star that needs Metal Cap without it", false, 0, 150, nullptr));
|
|
Achievement* WATCH_END_CREDITS = MoonAchievements::bind(new Achievement("achievement.watchEndCredits", "textures/moon/achievements/extras.cake.rgba16", "The Cake Is A Lie?!", "Watch the end credits", false, 0, 150, nullptr));
|
|
Achievement* RELEASE_CHAIN_CHOMP = MoonAchievements::bind(new Achievement("achievement.releaseChainChomp", "textures/moon/achievements/extras.chain-chomp.rgba16", "Chain-Chomp Unleashed", "Unleash the Chain-Chomp", false, 0, 150, nullptr));
|
|
|
|
Achievement* CHEATER = MoonAchievements::bind(new Achievement("achievement.cheater", "mod-icons://Moon64", "What a loser!", "You turned on cheats", false, 0, 150, nullptr));
|
|
};
|
|
|
|
int nId = 0;
|
|
|
|
namespace MoonAchievements {
|
|
Achievement* bind(Achievement* achievement){
|
|
achievement->sortId = nId;
|
|
registeredAchievements[achievement->id] = achievement;
|
|
nId++;
|
|
return achievement;
|
|
}
|
|
}
|
|
|
|
map<int, int> levelCoins = {
|
|
{ LEVEL_BOB, 146 },
|
|
{ LEVEL_WF, 141 },
|
|
{ LEVEL_JRB, 104 },
|
|
{ LEVEL_CCM, 154 },
|
|
{ LEVEL_BBH, 151 },
|
|
{ LEVEL_HMC, 134 },
|
|
{ LEVEL_LLL, 133 },
|
|
{ LEVEL_SSL, 136 },
|
|
{ LEVEL_DDD, 106 },
|
|
{ LEVEL_SL, 125 },
|
|
{ LEVEL_WDW, 147 },
|
|
{ LEVEL_TTM, 135 },
|
|
{ LEVEL_THI, 182 },
|
|
{ LEVEL_TTC, 128 },
|
|
{ LEVEL_RR, 146 }
|
|
};
|
|
|
|
#define NEXT_FLOOR -1
|
|
|
|
vector<int> castleStars = {
|
|
LEVEL_SSL,
|
|
LEVEL_LLL,
|
|
LEVEL_HMC,
|
|
LEVEL_DDD,
|
|
NEXT_FLOOR,
|
|
LEVEL_BOB,
|
|
LEVEL_CCM,
|
|
LEVEL_BBH,
|
|
LEVEL_WF,
|
|
LEVEL_JRB,
|
|
NEXT_FLOOR,
|
|
LEVEL_THI,
|
|
LEVEL_WDW,
|
|
LEVEL_TTM,
|
|
LEVEL_SL,
|
|
NEXT_FLOOR,
|
|
LEVEL_TTC,
|
|
LEVEL_RR,
|
|
NEXT_FLOOR,
|
|
};
|
|
|
|
namespace MoonTriggers {
|
|
|
|
int jumpCount = 0;
|
|
int slideCount = 0;
|
|
int npcTalk = 0;
|
|
|
|
bool executed = false;
|
|
|
|
int getObjectsAmount(vector<int> ids){
|
|
int count = 0;
|
|
for (s32 i = 0; i != NUM_OBJ_LISTS; ++i) {
|
|
struct ObjectNode *listHead = &gObjectLists[i];
|
|
struct Object *next = (struct Object *) listHead->next;
|
|
while (next != (struct Object *) listHead) {
|
|
int id = Moon::GetGraphNodeID(next->header.gfx.sharedChild);
|
|
if( find(ids.begin(), ids.end(), id) != ids.end())
|
|
count++;
|
|
next = (struct Object *) next->header.next;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
void actionTriggers(){
|
|
switch(gMarioState->action){
|
|
case ACT_BUTT_SLIDE:
|
|
if(!executed)
|
|
slideCount++;
|
|
executed = true;
|
|
break;
|
|
case ACT_JUMP:
|
|
case ACT_JUMP_KICK:
|
|
case ACT_DOUBLE_JUMP:
|
|
case ACT_TRIPLE_JUMP:
|
|
case ACT_LONG_JUMP:
|
|
case ACT_JUMP_LAND:
|
|
if(!executed)
|
|
jumpCount++;
|
|
executed = true;
|
|
break;
|
|
case ACT_READING_NPC_DIALOG:
|
|
if(!executed)
|
|
npcTalk++;
|
|
executed = true;
|
|
break;
|
|
default:
|
|
executed = false;
|
|
}
|
|
|
|
if(slideCount >= 100)
|
|
Moon::showAchievement(AchievementList::SLIDE_100_TIMES);
|
|
if(jumpCount >= 1000)
|
|
Moon::showAchievement(AchievementList::JUMP_1000_TIMES);
|
|
if(npcTalk >= 25)
|
|
Moon::showAchievement(AchievementList::TALK_25_TIMES);
|
|
}
|
|
|
|
void deathTrigger(){
|
|
if( gMarioState->health < 0x0100 ){
|
|
if(is_playing(0x16)){
|
|
Moon::showAchievement(AchievementList::DEATH_BY_BOSS);
|
|
return;
|
|
}
|
|
if(is_playing(0x07) || is_playing(0x19)){
|
|
Moon::showAchievement(AchievementList::DEATH_BY_BOWSER);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void starsTrigger(){
|
|
if( levelCoins.find(gCurrLevelNum) != levelCoins.end() && gHudDisplay.coins >= levelCoins[gCurrLevelNum])
|
|
Moon::showAchievement(AchievementList::GET_ALL_LVL_COINS);
|
|
|
|
|
|
if(gCurrLevelNum == LEVEL_LLL && gCurrAreaIndex != 2){
|
|
if(getObjectsAmount({0x56, 0x57}) == 0)
|
|
Moon::showAchievement(AchievementList::DEFEAT_ALL_BULLY);
|
|
}
|
|
|
|
if(gCurrLevelNum == LEVEL_BBH){
|
|
if(getObjectsAmount({0x54}) == 0)
|
|
Moon::showAchievement(AchievementList::DEFEAT_ALL_BOOS);
|
|
}
|
|
|
|
bool allObtainedStars = false;
|
|
int currentFloor = 0;
|
|
Achievement* castleAchievements[] = {
|
|
AchievementList::GET_FLOOR_0_STARS,
|
|
AchievementList::GET_FLOOR_1_STARS,
|
|
AchievementList::GET_FLOOR_2_STARS,
|
|
AchievementList::GET_FLOOR_3_STARS
|
|
};
|
|
|
|
for( auto &star : castleStars){
|
|
if(star == NEXT_FLOOR){
|
|
if(allObtainedStars)
|
|
Moon::showAchievement(castleAchievements[currentFloor]);
|
|
currentFloor++;
|
|
continue;
|
|
}
|
|
|
|
s32 stars = save_file_get_star_flags(gCurrSaveFileNum - 1, star - 1);
|
|
if(stars > 6){
|
|
Moon::showAchievement(AchievementList::GET_6_LEVEL_STARS);
|
|
allObtainedStars = true;
|
|
} else {
|
|
allObtainedStars = false;
|
|
}
|
|
}
|
|
|
|
s32 stars = save_file_get_star_flags(gCurrSaveFileNum - 1, -1);
|
|
if(stars >= 5)
|
|
Moon::showAchievement(AchievementList::GET_CASTLE_STARS);
|
|
|
|
Moon::showAchievementById("achievement.get" + to_string(gHudDisplay.stars) + "Stars");
|
|
}
|
|
|
|
void updateAllTriggers(){
|
|
actionTriggers();
|
|
deathTrigger();
|
|
starsTrigger();
|
|
}
|
|
|
|
}
|
|
|
|
namespace MoonInternal {
|
|
|
|
void setupAchievementEngine(string status){
|
|
if(status == "Update" && gHudDisplay.flags != HUD_DISPLAY_NONE){
|
|
if(Cheats.EnableCheats) {
|
|
Moon::showAchievement(AchievementList::CHEATER);
|
|
cheatsGotEnabled = true;
|
|
}
|
|
|
|
MoonTriggers::updateAllTriggers();
|
|
}
|
|
if(status == "Init"){
|
|
Moon::registerHookListener({.hookName = POST_HUD_DRAW, .callback = [](HookCall call){
|
|
for (auto &aEntry : entries[gCurrSaveFileNum - 1]) {
|
|
if( !aEntry->dead ) {
|
|
int soundID = SOUND_GENERAL_COIN;
|
|
|
|
bool shouldClose = aEntry->launchTime >= aEntry->achievement->duration;
|
|
|
|
float titleWidth = MoonGetTextWidth(aEntry->achievement->title, 0.8, false);
|
|
float descWidth = MoonGetTextWidth(aEntry->achievement->description, 0.8, false);
|
|
|
|
int achievementWidth = 31 + 15 + max(titleWidth, descWidth);
|
|
|
|
int aX = GetScreenWidth(false) / 2 - aEntry->width / 2;
|
|
int aY = GetScreenHeight() - aEntry->y;
|
|
|
|
MoonDrawRectangle(aX, aY, aEntry->width, aEntry->height, {0, 0, 0, 150}, false);
|
|
MoonDrawTexture(GFX_DIMENSIONS_FROM_LEFT_EDGE(aX), aY, min(31, aEntry->width - 1), 31, sys_strdup(aEntry->achievement->icon.c_str()));
|
|
if(!shouldClose && aEntry->width >= achievementWidth * 0.9){
|
|
MoonDrawText(aX + 32 + 5, aY + 2, aEntry->achievement->title, 0.8, {255,255,255,255}, true, false);
|
|
MoonDrawText(aX + 32 + 5, aY + 16, aEntry->achievement->description, 0.8, {255,255,255,255}, true, false);
|
|
}
|
|
|
|
#ifndef GAME_DEBUG
|
|
bool shouldUpdate = gMenuMode == -1 && !gWarpTransition.isActive;
|
|
#else
|
|
bool shouldUpdate = !gWarpTransition.isActive;
|
|
#endif
|
|
if(shouldUpdate){
|
|
int expectedY = aEntry->height + 45;
|
|
|
|
if (aEntry->launchTime == 1)
|
|
play_sound(soundID, gGlobalSoundSource);
|
|
|
|
aEntry->dead = aEntry->launchTime >= aEntry->achievement->duration + 35 && floor(aEntry->width) <= 0;
|
|
float dT = (aEntry->launchTime + 1.0f) / ((float)aEntry->achievement->duration);
|
|
if(aEntry->width <= 32 && !shouldClose)
|
|
aEntry->y = MathUtil::Lerp(aEntry->y, !shouldClose ? expectedY : 0, !shouldClose ? 0.17f : 0.28f);
|
|
|
|
if(ceil(aEntry->y) >= ceil(expectedY) || shouldClose)
|
|
aEntry->width = MathUtil::Lerp(aEntry->width, !shouldClose ? achievementWidth : 0, !shouldClose ? 0.2f : 0.45f);
|
|
|
|
aEntry->launchTime++;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}});
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace Moon {
|
|
void showAchievement(Achievement* achievement){
|
|
return; // here at saturn we dont show achievements
|
|
if(cheatsGotEnabled || gCurrDemoInput) return;
|
|
|
|
if(find_if(entries[gCurrSaveFileNum - 1].begin(), entries[gCurrSaveFileNum - 1].end(), [&cae = achievement] (auto &m) -> bool { return cae->id == m->achievement->id; }) != entries[gCurrSaveFileNum - 1].end()) return;
|
|
#ifdef GAME_DEBUG
|
|
cout << "Achievement got triggered: " << achievement->title << endl;
|
|
#endif
|
|
entries[gCurrSaveFileNum - 1].push_back(new AchievementEntry({ .launchTime = 0, .dead = false, .achievement = achievement, .entryID = entries.size() }));
|
|
}
|
|
|
|
void showAchievementById(string id){
|
|
if(registeredAchievements.find(id) == registeredAchievements.end()) return;
|
|
Moon::showAchievement(registeredAchievements[id]);
|
|
}
|
|
|
|
Achievement* getAchievementById(string id){
|
|
if(registeredAchievements.find(id) == registeredAchievements.end()) return NULL;
|
|
return registeredAchievements[id];
|
|
}
|
|
}
|
|
|
|
extern "C" {
|
|
void show_achievement(char* id){
|
|
Moon::showAchievementById(string(id));
|
|
}
|
|
} |