[WIP] Started adding achievements functionality
|
@ -67,7 +67,7 @@ moon64config.txt
|
|||
/sound/**/*.m64
|
||||
/sound/**/*.aiff
|
||||
!/textures/special/*.png
|
||||
!/textures/moon/*.png
|
||||
!/textures/moon/**/*.png
|
||||
!/textures/icons/*.png
|
||||
!/levels/**/*custom*.png
|
||||
!/levels/**/*custom*/**/*.png
|
||||
|
|
8
Makefile
|
@ -272,6 +272,9 @@ SRC_DIRS += src/moon/ui src/moon/ui/interfaces src/moon/ui/screens src/moon/ui/s
|
|||
# Moon64 SRC [View - Animations]
|
||||
SRC_DIRS += src/moon/ui/animation
|
||||
|
||||
# Moon64 SRC [View - Achievements]
|
||||
SRC_DIRS += src/moon/ui/screens/achievements
|
||||
|
||||
# Moon64 SRC [IO]
|
||||
SRC_DIRS += src/moon/io src/moon/io/modules
|
||||
|
||||
|
@ -722,6 +725,7 @@ all: $(BASEPACK_LST)
|
|||
# phony target for building resources
|
||||
res: $(BASEPACK_LST)
|
||||
|
||||
ifneq ($(NO_COPY),1)
|
||||
# prepares the basepack.lst
|
||||
$(BASEPACK_LST): $(EXE)
|
||||
@touch $(BASEPACK_LST)
|
||||
|
@ -734,10 +738,6 @@ $(BASEPACK_LST): $(EXE)
|
|||
@find levels -name \*.png -exec echo "{} gfx/{}" >> $(BASEPACK_LST) \;
|
||||
@find textures -name \*.png -exec echo "{} gfx/{}" >> $(BASEPACK_LST) \;
|
||||
@find texts -name \*.json -exec echo "{} {}" >> $(BASEPACK_LST) \;
|
||||
|
||||
ifneq ($(NO_COPY),1)
|
||||
# prepares the resource ZIP with base data
|
||||
$(BASEPACK_LST): $(EXE)
|
||||
@$(PYTHON) $(TOOLS_DIR)/mkzip.py $(BASEPACK_LST) $(BUILD_DIR)
|
||||
endif
|
||||
|
||||
|
|
|
@ -637,7 +637,7 @@
|
|||
"levels/ddd/2.rgba16.png": [32,32,2048,{"jp":[4765904,6144],"us":[4774192,6144],"eu":[4647792,6144],"sh":[4622160,6144]}],
|
||||
"levels/ddd/3.rgba16.png": [64,32,4096,{"jp":[4765904,8192],"us":[4774192,8192],"eu":[4647792,8192],"sh":[4622160,8192]}],
|
||||
"levels/ddd/4.rgba16.png": [32,32,2048,{"jp":[4765904,12288],"us":[4774192,12288],"eu":[4647792,12288],"sh":[4622160,12288]}],
|
||||
"levels/ending/cake.png": [153600,{"jp":[4834992,0],"us":[4843280,0]}],
|
||||
"levels/ending/cake.rgba16.png": [153600,{"jp":[4834992,0],"us":[4843280,0]}],
|
||||
"levels/ending/cake_eu.png": [143360,{"eu":[4716880,0]}],
|
||||
"levels/ending/eu_023000.rgba16.png": [64,32,4096,{"eu":[4716880,143360]}],
|
||||
"levels/ending/eu_024000.rgba16.png": [64,32,4096,{"eu":[4716880,147456]}],
|
||||
|
|
|
@ -385,7 +385,7 @@
|
|||
|
||||
// group 9
|
||||
#define MODEL_BOO 0x54 // boo_geo
|
||||
#define MODEL_BETA_BOO_KEY 0x55 // small_key_geo
|
||||
#define MODEL_BETA_BOO_KEY 0x55 // small_key_geo
|
||||
#define MODEL_HAUNTED_CHAIR 0x56 // haunted_chair_geo
|
||||
#define MODEL_MAD_PIANO 0x57 // mad_piano_geo
|
||||
#define MODEL_BOOKEND_PART 0x58 // bookend_part_geo
|
||||
|
|
|
@ -21,9 +21,6 @@ const GeoLayout ending_geo_000050[] = {
|
|||
GEO_OPEN_NODE(),
|
||||
GEO_NODE_ORTHO(100),
|
||||
GEO_OPEN_NODE(),
|
||||
#ifdef VERSION_EU
|
||||
GEO_BACKGROUND_COLOR(0x0001),
|
||||
#endif
|
||||
GEO_ASM(0, geo_exec_cake_end_screen),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
|
@ -37,4 +34,3 @@ const GeoLayout ending_geo_000050[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ const LevelScript level_script_entry[] = {
|
|||
SLEEP(/*frames*/ 2),
|
||||
BLACKOUT(/*active*/ FALSE),
|
||||
SET_REG(/*value*/ 0),
|
||||
#ifdef SM64_DEBUG
|
||||
#ifndef SM64_DEBUG
|
||||
EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_intro_entry_4),
|
||||
#else
|
||||
EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_intro_n64),
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
#ifdef VERSION_JP
|
||||
#define VAL_DIFF 25000
|
||||
#else
|
||||
#define VAL_DIFF 60000
|
||||
#endif
|
||||
|
||||
// Define lists for list of level for macros. Each of the following fields are described:
|
||||
// Argument 1: Internal ROM name of the level.
|
||||
|
@ -17,41 +13,41 @@
|
|||
|
||||
// NOTE: Be sure to edit sZoomOutAreaMasks in camera.c, as there isnt a good way to macro those right now.
|
||||
// TODO: Figure something out for sZoomOutAreaMasks?
|
||||
STUB_LEVEL( "", LEVEL_UNKNOWN_1, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
STUB_LEVEL( "", LEVEL_UNKNOWN_2, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
STUB_LEVEL( "", LEVEL_UNKNOWN_3, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
DEFINE_LEVEL("TERESA OBAKE", LEVEL_BBH, COURSE_BBH, bbh, spooky, 28000, 0x28, 0x28, 0x28, sDynBbh, sCamBBH)
|
||||
DEFINE_LEVEL("YYAMA1 % YSLD1", LEVEL_CCM, COURSE_CCM, ccm, snow, 17000, 0x10, 0x38, 0x38, _, sCamCCM)
|
||||
DEFINE_LEVEL("SELECT ROOM", LEVEL_CASTLE, COURSE_NONE, castle_inside, inside, 20000, 0x20, 0x20, 0x30, _, sCamCastle)
|
||||
DEFINE_LEVEL("HORROR DUNGEON", LEVEL_HMC, COURSE_HMC, hmc, cave, 16000, 0x28, 0x28, 0x28, sDynHmc, sCamHMC)
|
||||
DEFINE_LEVEL("SABAKU % PYRMD", LEVEL_SSL, COURSE_SSL, ssl, generic, 15000, 0x08, 0x30, 0x30, _, sCamSSL)
|
||||
DEFINE_LEVEL("BATTLE FIELD", LEVEL_BOB, COURSE_BOB, bob, generic, 15000, 0x08, 0x08, 0x08, _, _)
|
||||
DEFINE_LEVEL("YUKIYAMA2", LEVEL_SL, COURSE_SL, sl, snow, 14000, 0x10, 0x28, 0x28, _, sCamSL)
|
||||
DEFINE_LEVEL("POOL KAI", LEVEL_WDW, COURSE_WDW, wdw, grass, 17000, 0x10, 0x18, 0x18, sDynWdw, _)
|
||||
DEFINE_LEVEL("WTDG % TINBOTU", LEVEL_JRB, COURSE_JRB, jrb, water, 20000, 0x10, 0x18, 0x18, sDynJrb, _)
|
||||
DEFINE_LEVEL("BIG WORLD", LEVEL_THI, COURSE_THI, thi, grass, 20000, 0x0c, 0x0c, 0x20, _, sCamTHI)
|
||||
DEFINE_LEVEL("CLOCK TOWER", LEVEL_TTC, COURSE_TTC, ttc, machine, 18000, 0x18, 0x18, 0x18, _, _)
|
||||
DEFINE_LEVEL("RAINBOW CRUISE", LEVEL_RR, COURSE_RR, rr, sky, 20000, 0x20, 0x20, 0x20, _, sCamRR)
|
||||
DEFINE_LEVEL("MAIN MAP", LEVEL_CASTLE_GROUNDS, COURSE_NONE, castle_grounds, outside, 25000, 0x08, 0x08, 0x08, _, _)
|
||||
DEFINE_LEVEL("EXT1 YOKO SCRL", LEVEL_BITDW, COURSE_BITDW, bitdw, sky, 16000, 0x28, 0x28, 0x28, _, _)
|
||||
DEFINE_LEVEL("EXT7 HORI MINI", LEVEL_VCUTM, COURSE_VCUTM, vcutm, outside, 30000, 0x28, 0x28, 0x28, _, _)
|
||||
DEFINE_LEVEL("EXT2 TIKA LAVA", LEVEL_BITFS, COURSE_BITFS, bitfs, sky, 16000, 0x28, 0x28, 0x28, _, _)
|
||||
DEFINE_LEVEL("EXT9 SUISOU", LEVEL_SA, COURSE_SA, sa, inside, 20000, 0x10, 0x10, 0x10, _, _)
|
||||
DEFINE_LEVEL("EXT3 HEAVEN", LEVEL_BITS, COURSE_BITS, bits, sky, 16000, 0x28, 0x28, 0x28, _, _)
|
||||
DEFINE_LEVEL("FIREB1 % INVLC", LEVEL_LLL, COURSE_LLL, lll, fire, 22000, 0x08, 0x30, 0x30, _, _)
|
||||
DEFINE_LEVEL("WATER LAND", LEVEL_DDD, COURSE_DDD, ddd, water, 17000, 0x10, 0x20, 0x20, sDynDdd, _)
|
||||
DEFINE_LEVEL("MOUNTAIN", LEVEL_WF, COURSE_WF, wf, grass, 13000, 0x08, 0x08, 0x08, _, _)
|
||||
DEFINE_LEVEL("ENDING", LEVEL_ENDING, COURSE_CAKE_END, ending, generic, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
DEFINE_LEVEL("URANIWA", LEVEL_CASTLE_COURTYARD, COURSE_NONE, castle_courtyard, outside, 20000, 0x08, 0x08, 0x08, _, _)
|
||||
DEFINE_LEVEL("EXT4 MINI SLID", LEVEL_PSS, COURSE_PSS, pss, mountain, 20000, 0x28, 0x28, 0x28, _, _)
|
||||
DEFINE_LEVEL("IN THE FALL", LEVEL_COTMC, COURSE_COTMC, cotmc, cave, 18000, 0x28, 0x28, 0x28, _, sCamCotMC)
|
||||
DEFINE_LEVEL("EXT6 MARIO FLY", LEVEL_TOTWC, COURSE_TOTWC, totwc, sky, 20000, 0x20, 0x20, 0x20, _, _)
|
||||
DEFINE_LEVEL("KUPPA1", LEVEL_BOWSER_1, COURSE_BITDW, bowser_1, generic, VAL_DIFF, 0x40, 0x40, 0x40, _, _)
|
||||
DEFINE_LEVEL("EXT8 BLUE SKY", LEVEL_WMOTR, COURSE_WMOTR, wmotr, generic, 20000, 0x28, 0x28, 0x28, _, _)
|
||||
STUB_LEVEL( "", LEVEL_UNKNOWN_32, COURSE_NONE, 20000, 0x70, 0x00, 0x00, _, _)
|
||||
DEFINE_LEVEL("KUPPA2", LEVEL_BOWSER_2, COURSE_BITFS, bowser_2, fire, VAL_DIFF, 0x40, 0x40, 0x40, _, _)
|
||||
DEFINE_LEVEL("KUPPA3", LEVEL_BOWSER_3, COURSE_BITS, bowser_3, generic, VAL_DIFF, 0x40, 0x40, 0x40, _, _)
|
||||
STUB_LEVEL( "", LEVEL_UNKNOWN_35, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
DEFINE_LEVEL("DONKEY % SLID2", LEVEL_TTM, COURSE_TTM, ttm, mountain, 15000, 0x08, 0x08, 0x08, _, _)
|
||||
STUB_LEVEL( "", LEVEL_UNKNOWN_37, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
STUB_LEVEL( "", LEVEL_UNKNOWN_38, COURSE_NONE, 20000, 0x00, 0x00, 0x00, sDynUnk38, _)
|
||||
STUB_LEVEL ("UNKNOWN", LEVEL_UNKNOWN_1, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
STUB_LEVEL ("UNKNOWN", LEVEL_UNKNOWN_2, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
STUB_LEVEL ("UNKNOWN", LEVEL_UNKNOWN_3, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
DEFINE_LEVEL("BIG BOO HAUNT", LEVEL_BBH, COURSE_BBH, bbh, spooky, 28000, 0x28, 0x28, 0x28, sDynBbh, sCamBBH)
|
||||
DEFINE_LEVEL("COOL COOL MOUNTAIN", LEVEL_CCM, COURSE_CCM, ccm, snow, 17000, 0x10, 0x38, 0x38, _, sCamCCM)
|
||||
DEFINE_LEVEL("CASTLE INSIDE", LEVEL_CASTLE, COURSE_NONE, castle_inside, inside, 20000, 0x20, 0x20, 0x30, _, sCamCastle)
|
||||
DEFINE_LEVEL("HAZY MAZE CAVE", LEVEL_HMC, COURSE_HMC, hmc, cave, 16000, 0x28, 0x28, 0x28, sDynHmc, sCamHMC)
|
||||
DEFINE_LEVEL("SHIFTING SAND LAND", LEVEL_SSL, COURSE_SSL, ssl, generic, 15000, 0x08, 0x30, 0x30, _, sCamSSL)
|
||||
DEFINE_LEVEL("BOB OMB BATTLEFIELD", LEVEL_BOB, COURSE_BOB, bob, generic, 15000, 0x08, 0x08, 0x08, _, _)
|
||||
DEFINE_LEVEL("SNOWMAN LAND", LEVEL_SL, COURSE_SL, sl, snow, 14000, 0x10, 0x28, 0x28, _, sCamSL)
|
||||
DEFINE_LEVEL("WET DRY WORLD", LEVEL_WDW, COURSE_WDW, wdw, grass, 17000, 0x10, 0x18, 0x18, sDynWdw, _)
|
||||
DEFINE_LEVEL("JOLLY ROGER BAY", LEVEL_JRB, COURSE_JRB, jrb, water, 20000, 0x10, 0x18, 0x18, sDynJrb, _)
|
||||
DEFINE_LEVEL("TINY HUGE ISLAND", LEVEL_THI, COURSE_THI, thi, grass, 20000, 0x0c, 0x0c, 0x20, _, sCamTHI)
|
||||
DEFINE_LEVEL("TICK TOCK CLOCK", LEVEL_TTC, COURSE_TTC, ttc, machine, 18000, 0x18, 0x18, 0x18, _, _)
|
||||
DEFINE_LEVEL("RAINBOW RIDE", LEVEL_RR, COURSE_RR, rr, sky, 20000, 0x20, 0x20, 0x20, _, sCamRR)
|
||||
DEFINE_LEVEL("CASTLE GROUNDS", LEVEL_CASTLE_GROUNDS, COURSE_NONE, castle_grounds, outside, 25000, 0x08, 0x08, 0x08, _, _)
|
||||
DEFINE_LEVEL("BOWSER IN THE DARK WORLD", LEVEL_BITDW, COURSE_BITDW, bitdw, sky, 16000, 0x28, 0x28, 0x28, _, _)
|
||||
DEFINE_LEVEL("VANISH CAP", LEVEL_VCUTM, COURSE_VCUTM, vcutm, outside, 30000, 0x28, 0x28, 0x28, _, _)
|
||||
DEFINE_LEVEL("BOWSER IN THE FIRE SEA", LEVEL_BITFS, COURSE_BITFS, bitfs, sky, 16000, 0x28, 0x28, 0x28, _, _)
|
||||
DEFINE_LEVEL("SECRET ACUARIUM", LEVEL_SA, COURSE_SA, sa, inside, 20000, 0x10, 0x10, 0x10, _, _)
|
||||
DEFINE_LEVEL("BOWSER IN THE SKY", LEVEL_BITS, COURSE_BITS, bits, sky, 16000, 0x28, 0x28, 0x28, _, _)
|
||||
DEFINE_LEVEL("LETHAL LAVA LAND", LEVEL_LLL, COURSE_LLL, lll, fire, 22000, 0x08, 0x30, 0x30, _, _)
|
||||
DEFINE_LEVEL("DIRE DIRE DOCKS", LEVEL_DDD, COURSE_DDD, ddd, water, 17000, 0x10, 0x20, 0x20, sDynDdd, _)
|
||||
DEFINE_LEVEL("WHOMP FORTRESS", LEVEL_WF, COURSE_WF, wf, grass, 13000, 0x08, 0x08, 0x08, _, _)
|
||||
DEFINE_LEVEL("ENDING", LEVEL_ENDING, COURSE_CAKE_END, ending, generic, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
DEFINE_LEVEL("CASTLE COURTYARD", LEVEL_CASTLE_COURTYARD, COURSE_NONE, castle_courtyard, outside, 20000, 0x08, 0x08, 0x08, _, _)
|
||||
DEFINE_LEVEL("PRINCESS SECRET SLIDE", LEVEL_PSS, COURSE_PSS, pss, mountain, 20000, 0x28, 0x28, 0x28, _, _)
|
||||
DEFINE_LEVEL("IN THE FALL", LEVEL_COTMC, COURSE_COTMC, cotmc, cave, 18000, 0x28, 0x28, 0x28, _, sCamCotMC)
|
||||
DEFINE_LEVEL("WING CAP", LEVEL_TOTWC, COURSE_TOTWC, totwc, sky, 20000, 0x20, 0x20, 0x20, _, _)
|
||||
DEFINE_LEVEL("BITDW BOWSER", LEVEL_BOWSER_1, COURSE_BITDW, bowser_1, generic, VAL_DIFF, 0x40, 0x40, 0x40, _, _)
|
||||
DEFINE_LEVEL("WING MARIO", LEVEL_WMOTR, COURSE_WMOTR, wmotr, generic, 20000, 0x28, 0x28, 0x28, _, _)
|
||||
STUB_LEVEL ("UNKNOWN", LEVEL_UNKNOWN_32, COURSE_NONE, 20000, 0x70, 0x00, 0x00, _, _)
|
||||
DEFINE_LEVEL("BITFS BOWSER", LEVEL_BOWSER_2, COURSE_BITFS, bowser_2, fire, VAL_DIFF, 0x40, 0x40, 0x40, _, _)
|
||||
DEFINE_LEVEL("BITS BOWSER", LEVEL_BOWSER_3, COURSE_BITS, bowser_3, generic, VAL_DIFF, 0x40, 0x40, 0x40, _, _)
|
||||
STUB_LEVEL ("UNKNOWN", LEVEL_UNKNOWN_35, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
DEFINE_LEVEL("TALL TALL MOUNTAIN", LEVEL_TTM, COURSE_TTM, ttm, mountain, 15000, 0x08, 0x08, 0x08, _, _)
|
||||
STUB_LEVEL ("UNKNOWN", LEVEL_UNKNOWN_37, COURSE_NONE, 20000, 0x00, 0x00, 0x00, _, _)
|
||||
STUB_LEVEL ("UNKNOWN", LEVEL_UNKNOWN_38, COURSE_NONE, 20000, 0x00, 0x00, 0x00, sDynUnk38, _)
|
||||
|
|
|
@ -1873,6 +1873,16 @@ void set_sequence_player_volume(s32 player, f32 volume) {
|
|||
gSequencePlayers[player].volumeScale = pow(volume, 2);
|
||||
}
|
||||
|
||||
u8 is_playing(u16 seqId){
|
||||
int i;
|
||||
for (i = 0; i < sBackgroundMusicQueueSize; i++) {
|
||||
if (sBackgroundMusicQueue[i].seqId == seqId) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from threads: thread5_game_loop
|
||||
*/
|
||||
|
|
|
@ -64,4 +64,6 @@ void audio_set_sound_mode(u8 arg0);
|
|||
void set_sequence_player_volume(s32 player, f32 volume);
|
||||
void audio_init(void); // in load.c
|
||||
|
||||
u8 is_playing(u16 seqId);
|
||||
|
||||
#endif // AUDIO_EXTERNAL_H
|
|
@ -1,4 +1,5 @@
|
|||
// bowser.c.inc
|
||||
#include "game/hud.h"
|
||||
|
||||
void bowser_tail_anchor_act_0(void) {
|
||||
struct Object *bowser = o->parentObj;
|
||||
|
@ -96,6 +97,9 @@ void bhv_bowser_body_anchor_loop(void) {
|
|||
}
|
||||
|
||||
s32 bowser_spawn_shockwave(void) {
|
||||
o->oHealth = -1;
|
||||
o->oAction = 4;
|
||||
return 0;
|
||||
struct Object *wave;
|
||||
if (o->oBehParams2ndByte == 2) {
|
||||
wave = spawn_object(o, MODEL_BOWSER_WAVE, bhvBowserShockWave);
|
||||
|
@ -202,7 +206,6 @@ void bowser_bitdw_act_controller(void) {
|
|||
o->oBowserUnk110++;
|
||||
} else {
|
||||
o->oBowserUnk110 = 0;
|
||||
#ifndef VERSION_JP
|
||||
if (!gCurrDemoInput) {
|
||||
if (rand < 0.1)
|
||||
o->oAction = 3; // rare 1/10 chance
|
||||
|
@ -211,12 +214,6 @@ void bowser_bitdw_act_controller(void) {
|
|||
} else {
|
||||
o->oAction = 14; // ensure demo starts with action 14.
|
||||
}
|
||||
#else
|
||||
if (rand < 0.1)
|
||||
o->oAction = 3; // rare 1/10 chance
|
||||
else
|
||||
o->oAction = 14; // common
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -763,6 +760,20 @@ void bowser_spawn_grand_star_key(void) {
|
|||
cur_obj_play_sound_2(SOUND_GENERAL2_BOWSER_KEY);
|
||||
}
|
||||
gSecondCameraFocus->oAngleVelYaw = o->oAngleVelYaw;
|
||||
switch(o->oBehParams2ndByte){
|
||||
case 0:
|
||||
show_achievement("achievement.beatFirstBowser");
|
||||
break;
|
||||
case 1:
|
||||
show_achievement("achievement.beatSecondBowser");
|
||||
break;
|
||||
case 2:
|
||||
if(gHudDisplay.stars >= 120)
|
||||
show_achievement("achievement.beatGame120Stars");
|
||||
else
|
||||
show_achievement("achievement.beatFinalBowser");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bowser_fly_back_dead(void) {
|
||||
|
|
|
@ -177,13 +177,7 @@ void bully_step(void) {
|
|||
|
||||
void bully_spawn_coin(void) {
|
||||
struct Object *coin = spawn_object(o, MODEL_YELLOW_COIN, bhvMovingYellowCoin);
|
||||
#ifdef VERSION_JP //TODO: maybe move this ifdef logic to the header?
|
||||
cur_obj_play_sound_2(SOUND_GENERAL_COIN_SPURT);
|
||||
#elif VERSION_EU
|
||||
cur_obj_play_sound_2(SOUND_GENERAL_COIN_SPURT_EU);
|
||||
#else
|
||||
cur_obj_play_sound_2(SOUND_GENERAL_COIN_SPURT_2);
|
||||
#endif
|
||||
coin->oForwardVel = 10.0f;
|
||||
coin->oVelY = 100.0f;
|
||||
coin->oPosY = o->oPosY + 310.0f;
|
||||
|
|
|
@ -352,6 +352,7 @@ static void chain_chomp_released_end_cutscene(void) {
|
|||
if (cutscene_object(CUTSCENE_STAR_SPAWN, o) == -1) {
|
||||
set_mario_npc_dialog(0);
|
||||
o->oAction = CHAIN_CHOMP_ACT_UNLOAD_CHAIN;
|
||||
show_achievement("achievement.releaseChainChomp");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ static void eyerok_boss_act_die(void) {
|
|||
if (o->oTimer == 60) {
|
||||
if (cur_obj_update_dialog_with_cutscene(2, 0, CUTSCENE_DIALOG, DIALOG_118)) {
|
||||
spawn_default_star(0.0f, -900.0f, -3700.0f);
|
||||
show_achievement("achievement.beatEyerok");
|
||||
} else {
|
||||
o->oTimer -= 1;
|
||||
}
|
||||
|
|
|
@ -177,12 +177,8 @@ void king_bobomb_act_7(void) {
|
|||
spawn_mist_particles_variable(0, 0, 200.0f);
|
||||
spawn_triangle_break_particles(20, 138, 3.0f, 4);
|
||||
cur_obj_shake_screen(SHAKE_POS_SMALL);
|
||||
#ifndef VERSION_JP
|
||||
cur_obj_spawn_star_at_y_offset(2000.0f, 4500.0f, -4500.0f, 200.0f);
|
||||
#else
|
||||
o->oPosY += 100.0f;
|
||||
spawn_default_star(2000.0f, 4500.0f, -4500.0f);
|
||||
#endif
|
||||
show_achievement("achievement.beatKingBobOmb");
|
||||
o->oAction = 8;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,7 @@ void mr_i_act_3(void) {
|
|||
if (o->oBehParams2ndByte) {
|
||||
o->oPosY += 100.0f;
|
||||
spawn_default_star(1370, 2000.0f, -320.0f);
|
||||
show_achievement("achievement.beatMr.I");
|
||||
obj_mark_for_deletion(o);
|
||||
} else
|
||||
cur_obj_spawn_loot_blue_coin();
|
||||
|
|
|
@ -218,6 +218,7 @@ void whomp_act_8(void) {
|
|||
cur_obj_shake_screen(SHAKE_POS_SMALL);
|
||||
o->oPosY += 100.0f;
|
||||
spawn_default_star(180.0f, 3880.0f, 340.0f);
|
||||
show_achievement("achievement.beatKingWhomp");
|
||||
cur_obj_play_sound_2(SOUND_OBJ_KING_WHOMP_DEATH);
|
||||
o->oAction = 9;
|
||||
}
|
||||
|
|
|
@ -359,6 +359,7 @@ static void wiggler_act_shrink(void) {
|
|||
// 4 is the default scale, so shrink to 1/4 of regular size
|
||||
if (approach_f32_ptr(&o->header.gfx.scale[0], 1.0f, 0.1f)) {
|
||||
spawn_default_star(0.0f, 2048.0f, 0.0f);
|
||||
show_achievement("achievement.beatWiggler");
|
||||
o->oAction = WIGGLER_ACT_FALL_THROUGH_FLOOR;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,10 @@ void yoshi_walk_loop(void) {
|
|||
if (sp24 == 0 || sp24 == 15)
|
||||
cur_obj_play_sound_2(SOUND_GENERAL_YOSHI_WALK);
|
||||
|
||||
if (o->oInteractStatus == INT_STATUS_INTERACTED)
|
||||
if (o->oInteractStatus == INT_STATUS_INTERACTED){
|
||||
show_achievement("achievement.talkWithYoshi");
|
||||
o->oAction = YOSHI_ACT_TALK;
|
||||
}
|
||||
|
||||
if (o->oPosY < 2100.0f) {
|
||||
create_respawner(MODEL_YOSHI, bhvYoshi, 3000);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "engine/graph_node.h"
|
||||
#include "level_table.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "moon/achievements/achievements.h"
|
||||
|
||||
#define CBUTTON_MASK (U_CBUTTONS | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS)
|
||||
|
||||
|
@ -3702,18 +3703,6 @@ s32 move_point_along_spline(Vec3f p, struct CutsceneSplinePoint spline[], s16 *s
|
|||
}
|
||||
progressChange = (secondSpeed - firstSpeed) * *progress + firstSpeed;
|
||||
|
||||
#ifdef VERSION_EU
|
||||
if (gCamera->cutscene == CUTSCENE_INTRO_PEACH) {
|
||||
progressChange += progressChange * 0.19f;
|
||||
}
|
||||
if (gCamera->cutscene == CUTSCENE_CREDITS) {
|
||||
progressChange += progressChange * 0.15f;
|
||||
}
|
||||
if (gCamera->cutscene == CUTSCENE_ENDING) {
|
||||
progressChange += progressChange * 0.1f;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (1 <= (*progress += progressChange)) {
|
||||
(*splineSegment)++;
|
||||
if (spline[*splineSegment + 3].index == -1) {
|
||||
|
@ -9850,6 +9839,8 @@ BAD_RETURN(s32) cutscene_credits(struct Camera *c) {
|
|||
|
||||
cutscene_event(cutscene_credits_reset_spline, c, 0, 0);
|
||||
|
||||
show_achievement("achievement.watchEndCredits");
|
||||
|
||||
switch (gCurrLevelArea) {
|
||||
case AREA_BOB:
|
||||
pos = sBobCreditsSplinePositions;
|
||||
|
|
|
@ -263,7 +263,7 @@ void end_master_display_list(void) {
|
|||
}
|
||||
|
||||
Gfx **alloc_next_dl(void) {
|
||||
u32 size = 1000;
|
||||
u32 size = 0xFFFF;
|
||||
Gfx *new_chunk = alloc_only_pool_alloc(gGfxAllocOnlyPool, size * sizeof(Gfx));
|
||||
gSPBranchList(gDisplayListHeadInChunk++, new_chunk);
|
||||
gDisplayListHeadInChunk = new_chunk;
|
||||
|
|
|
@ -196,7 +196,7 @@ Gfx *geo_exec_cake_end_screen(s32 callContext, struct GraphNode *node, UNUSED f3
|
|||
Gfx *displayListHead = NULL;
|
||||
|
||||
if (callContext == GEO_CONTEXT_RENDER) {
|
||||
displayList = alloc_display_list(13 * sizeof(*displayList));
|
||||
displayList = alloc_display_list(20 * sizeof(*displayList));
|
||||
displayListHead = displayList;
|
||||
|
||||
generatedNode->fnNode.node.flags = (generatedNode->fnNode.node.flags & 0xFF) | 0x100;
|
||||
|
@ -205,7 +205,7 @@ Gfx *geo_exec_cake_end_screen(s32 callContext, struct GraphNode *node, UNUSED f3
|
|||
s32 y = 0;
|
||||
u32 w = SCREEN_HEIGHT * 2560 / 1920;
|
||||
u32 h = SCREEN_HEIGHT;
|
||||
u8 *texture = "levels/ending/cake";
|
||||
u8 *texture = "levels/ending/cake.rgba16";
|
||||
|
||||
gSPDisplayList(displayListHead++, dl_proj_mtx_fullscreen);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "sm64.h"
|
||||
#include "sound_init.h"
|
||||
#include "thread6.h"
|
||||
#include "moon/achievements/achievements.h"
|
||||
|
||||
#define INT_GROUND_POUND_OR_TWIRL (1 << 0) // 0x01
|
||||
#define INT_PUNCH (1 << 1) // 0x02
|
||||
|
@ -745,8 +746,9 @@ u32 interact_coin(struct MarioState *m, UNUSED u32 interactType, struct Object *
|
|||
if (COURSE_IS_MAIN_COURSE(gCurrCourseNum) && m->numCoins - o->oDamageOrCoinValue < 100
|
||||
&& m->numCoins >= 100) {
|
||||
bhv_spawn_star_no_level_exit(6);
|
||||
show_achievement("achievement.get100CoinStar");
|
||||
}
|
||||
|
||||
|
||||
if (o->oDamageOrCoinValue >= 2) {
|
||||
queue_rumble_data(5, 80);
|
||||
}
|
||||
|
@ -1088,7 +1090,7 @@ u32 interact_tornado(struct MarioState *m, UNUSED u32 interactType, struct Objec
|
|||
|
||||
play_sound(SOUND_MARIO_WAAAOOOW, m->marioObj->header.gfx.cameraToObject);
|
||||
queue_rumble_data(30, 60);
|
||||
|
||||
|
||||
return set_mario_action(m, ACT_TORNADO_TWIRLING, m->action == ACT_TWIRLING);
|
||||
}
|
||||
|
||||
|
@ -1110,7 +1112,7 @@ u32 interact_whirlpool(struct MarioState *m, UNUSED u32 interactType, struct Obj
|
|||
|
||||
play_sound(SOUND_MARIO_WAAAOOOW, m->marioObj->header.gfx.cameraToObject);
|
||||
queue_rumble_data(30, 60);
|
||||
|
||||
|
||||
return set_mario_action(m, ACT_CAUGHT_IN_WHIRLPOOL, 0);
|
||||
}
|
||||
|
||||
|
@ -1145,7 +1147,7 @@ u32 interact_flame(struct MarioState *m, UNUSED u32 interactType, struct Object
|
|||
if (!sInvulnerable && !(m->flags & MARIO_METAL_CAP) && !(m->flags & MARIO_VANISH_CAP)
|
||||
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
||||
queue_rumble_data(5, 80);
|
||||
|
||||
|
||||
o->oInteractStatus = INT_STATUS_INTERACTED;
|
||||
m->interactObj = o;
|
||||
|
||||
|
@ -1245,7 +1247,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object
|
|||
push_mario_out_of_object(m, o, 5.0f);
|
||||
drop_and_set_mario_action(m, bully_knock_back_mario(m), 0);
|
||||
queue_rumble_data(5, 80);
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -740,6 +740,7 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) {
|
|||
sDelayedWarpOp = WARP_OP_GAME_OVER;
|
||||
} else {
|
||||
sSourceWarpNodeId = WARP_NODE_DEATH;
|
||||
show_achievement("achievement.deathByFalling");
|
||||
}
|
||||
}
|
||||
sDelayedWarpTimer = 20;
|
||||
|
@ -750,9 +751,7 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) {
|
|||
sDelayedWarpTimer = 30;
|
||||
sSourceWarpNodeId = WARP_NODE_F2;
|
||||
play_transition(WARP_TRANSITION_FADE_INTO_COLOR, 0x1E, 0xFF, 0xFF, 0xFF);
|
||||
#ifndef VERSION_JP
|
||||
play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case WARP_OP_UNKNOWN_02: // bbh enter
|
||||
|
|
|
@ -37,7 +37,6 @@ void play_far_fall_sound(struct MarioState *m) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef VERSION_JP
|
||||
void play_knockback_sound(struct MarioState *m) {
|
||||
if (m->actionArg == 0 && (m->forwardVel <= -28.0f || m->forwardVel >= 28.0f)) {
|
||||
play_sound_if_no_flag(m, SOUND_MARIO_DOH, MARIO_MARIO_SOUND_PLAYED);
|
||||
|
@ -45,7 +44,6 @@ void play_knockback_sound(struct MarioState *m) {
|
|||
play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
s32 lava_boost_on_wall(struct MarioState *m) {
|
||||
m->faceAngle[1] = atan2s(m->wall->normal.z, m->wall->normal.x);
|
||||
|
@ -1544,6 +1542,7 @@ s32 act_lava_boost(struct MarioState *m) {
|
|||
|
||||
if (m->health < 0x100) {
|
||||
level_trigger_warp(m, WARP_OP_DEATH);
|
||||
show_achievement("achievement.deathByFire");
|
||||
}
|
||||
|
||||
m->marioBodyState->eyeState = MARIO_EYES_DEAD;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "thread6.h"
|
||||
#include "../../include/libc/stdlib.h"
|
||||
#include "pc/pc_main.h"
|
||||
#include "moon/achievements/achievements.h"
|
||||
|
||||
// TODO: put this elsewhere
|
||||
enum SaveOption { SAVE_OPT_SAVE_AND_CONTINUE = 1, SAVE_OPT_SAVE_AND_QUIT, SAVE_OPT_SAVE_EXIT_GAME, SAVE_OPT_CONTINUE_DONT_SAVE };
|
||||
|
@ -752,6 +753,7 @@ s32 act_quicksand_death(struct MarioState *m) {
|
|||
}
|
||||
if ((m->quicksandDepth += 5.0f) >= 180.0f) {
|
||||
level_trigger_warp(m, WARP_OP_DEATH);
|
||||
show_achievement("achievement.deathBySand");
|
||||
m->actionState = 2;
|
||||
}
|
||||
}
|
||||
|
@ -1171,11 +1173,7 @@ s32 act_exit_land_save_dialog(struct MarioState *m) {
|
|||
s32 act_death_exit(struct MarioState *m) {
|
||||
if (15 < m->actionTimer++
|
||||
&& launch_mario_until_land(m, ACT_DEATH_EXIT_LAND, MARIO_ANIM_GENERAL_FALL, -32.0f)) {
|
||||
#ifdef VERSION_JP
|
||||
play_sound(SOUND_MARIO_OOOF, m->marioObj->header.gfx.cameraToObject);
|
||||
#else
|
||||
play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject);
|
||||
#endif
|
||||
queue_rumble_data(5, 80);
|
||||
m->numLives--;
|
||||
// restore 7.75 units of health
|
||||
|
@ -1188,11 +1186,7 @@ s32 act_death_exit(struct MarioState *m) {
|
|||
|
||||
s32 act_unused_death_exit(struct MarioState *m) {
|
||||
if (launch_mario_until_land(m, ACT_FREEFALL_LAND_STOP, MARIO_ANIM_GENERAL_FALL, 0.0f)) {
|
||||
#ifdef VERSION_JP
|
||||
play_sound(SOUND_MARIO_OOOF, m->marioObj->header.gfx.cameraToObject);
|
||||
#else
|
||||
play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject);
|
||||
#endif
|
||||
m->numLives--;
|
||||
// restore 7.75 units of health
|
||||
m->healCounter = 31;
|
||||
|
@ -1204,11 +1198,7 @@ s32 act_unused_death_exit(struct MarioState *m) {
|
|||
|
||||
s32 act_falling_death_exit(struct MarioState *m) {
|
||||
if (launch_mario_until_land(m, ACT_DEATH_EXIT_LAND, MARIO_ANIM_GENERAL_FALL, 0.0f)) {
|
||||
#ifdef VERSION_JP
|
||||
play_sound(SOUND_MARIO_OOOF, m->marioObj->header.gfx.cameraToObject);
|
||||
#else
|
||||
play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject);
|
||||
#endif
|
||||
queue_rumble_data(5, 80);
|
||||
m->numLives--;
|
||||
// restore 7.75 units of health
|
||||
|
@ -1533,6 +1523,7 @@ s32 act_squished(struct MarioState *m) {
|
|||
if (m->actionTimer >= 15) {
|
||||
// 1 unit of health
|
||||
if (m->health < 0x0100) {
|
||||
show_achievement("achievement.deathByCrushing");
|
||||
level_trigger_warp(m, WARP_OP_DEATH);
|
||||
// woosh, he's gone!
|
||||
set_mario_action(m, ACT_DISAPPEARED, 0);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "thread6.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "pc/cheats.h"
|
||||
#include "moon/achievements/achievements.h"
|
||||
|
||||
struct LandingAction {
|
||||
s16 numFrames;
|
||||
|
@ -470,7 +471,7 @@ void update_walking_speed(struct MarioState *m) {
|
|||
}
|
||||
else {
|
||||
m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800);
|
||||
}
|
||||
}
|
||||
apply_slope_accel(m);
|
||||
}
|
||||
|
||||
|
@ -1252,7 +1253,7 @@ s32 act_riding_shell_ground(struct MarioState *m) {
|
|||
}
|
||||
|
||||
adjust_sound_for_speed(m);
|
||||
|
||||
|
||||
reset_rumble_timers();
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1354,6 +1355,7 @@ s32 act_burning_ground(struct MarioState *m) {
|
|||
m->health -= 10;
|
||||
if (m->health < 0x100) {
|
||||
set_mario_action(m, ACT_STANDING_DEATH, 0);
|
||||
show_achievement("achievement.deathByFire");
|
||||
}
|
||||
|
||||
m->marioBodyState->eyeState = MARIO_EYES_DEAD;
|
||||
|
@ -1853,7 +1855,7 @@ s32 act_long_jump_land(struct MarioState *m) {
|
|||
m->forwardVel = 0.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (!(m->input & INPUT_Z_DOWN)) {
|
||||
m->input &= ~INPUT_A_PRESSED;
|
||||
}
|
||||
|
|
|
@ -680,6 +680,8 @@ s32 act_hold_butt_slide_stop(struct MarioState *m) {
|
|||
return set_mario_action(m, ACT_THROWING, 0);
|
||||
}
|
||||
|
||||
printf("Butt sliding\n");
|
||||
|
||||
stopping_step(m, MARIO_ANIM_STAND_UP_FROM_SLIDING_WITH_LIGHT_OBJ, ACT_HOLD_IDLE);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -918,6 +918,7 @@ static s32 act_drowning(struct MarioState *m) {
|
|||
m->marioBodyState->eyeState = MARIO_EYES_DEAD;
|
||||
if (m->marioObj->header.gfx.unk38.animFrame == 30) {
|
||||
level_trigger_warp(m, WARP_OP_DEATH);
|
||||
show_achievement("achievement.deathByDrowning");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1081,7 +1082,7 @@ static s32 act_caught_in_whirlpool(struct MarioState *m) {
|
|||
set_mario_animation(m, MARIO_ANIM_GENERAL_FALL);
|
||||
vec3f_copy(m->marioObj->header.gfx.pos, m->pos);
|
||||
vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0);
|
||||
|
||||
|
||||
reset_rumble_timers();
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#define STUB_LEVEL(textname, _1, _2, _3, _4, _5, _6, _7, _8) textname,
|
||||
#define DEFINE_LEVEL(textname, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) textname,
|
||||
|
||||
static char gLevelSelect_StageNamesText[64][16] = {
|
||||
static char gLevelSelect_StageNamesText[64][64] = {
|
||||
#include "levels/level_defines.h"
|
||||
};
|
||||
#undef STUB_LEVEL
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#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"
|
||||
|
@ -17,91 +18,272 @@ extern "C" {
|
|||
#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"
|
||||
}
|
||||
|
||||
std::map<std::string, Achievement*> registeredAchievements;
|
||||
std::vector<AchievementEntry*> entries;
|
||||
#define ALL_MAIN_STARS 0x7F
|
||||
|
||||
using namespace std;
|
||||
|
||||
map<string, Achievement*> registeredAchievements;
|
||||
vector<AchievementEntry*> entries;
|
||||
bool cheatsGotEnabled = false;
|
||||
|
||||
namespace AchievementList {
|
||||
/* Star achievements */
|
||||
Achievement* GET_1_STAR = MoonAchievements::bind(new Achievement("achievement.get1Stars", "textures/segment2/segment2.05C00.rgba16", "Your journey begins!", "Get one star", 0, 150, nullptr));
|
||||
Achievement* GET_8_STARS = MoonAchievements::bind(new Achievement("achievement.get8Stars", "textures/segment2/segment2.05C00.rgba16", "You feel a strong power", "Get 8 stars", 0, 150, GET_1_STAR));
|
||||
Achievement* GET_30_STARS = MoonAchievements::bind(new Achievement("achievement.get30Stars", "textures/segment2/segment2.05C00.rgba16", "TBD", "Get 30 stars", 0, 150, GET_8_STARS));
|
||||
Achievement* GET_50_STARS = MoonAchievements::bind(new Achievement("achievement.get50Stars", "textures/segment2/segment2.05C00.rgba16", "Lucky Eight", "Get 50 stars", 0, 150, GET_30_STARS));
|
||||
Achievement* GET_70_STARS = MoonAchievements::bind(new Achievement("achievement.get70Stars", "textures/segment2/segment2.05C00.rgba16", "Halfway done!", "Get 70 stars", 0, 150, GET_50_STARS));
|
||||
Achievement* GET_120_STARS = MoonAchievements::bind(new Achievement("achievement.get120Stars", "textures/segment2/segment2.05C00.rgba16", "The Completionist", "Get 120 stars", 0, 150, GET_70_STARS));
|
||||
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/segment2/segment2.05C00.rgba16", "Super Man-rio", "Unlock the wing cap", 0, 150, nullptr));
|
||||
Achievement* UNL0CK_METAL_CAP = MoonAchievements::bind(new Achievement("achievement.unlockMetalCap", "textures/segment2/segment2.05C00.rgba16", "Heavy-Headed", "Unlock the metal cap", 0, 150, nullptr));
|
||||
Achievement* UNLOCK_VANISH_CAP = MoonAchievements::bind(new Achievement("achievement.unlockVanishCap", "textures/segment2/segment2.05C00.rgba16", "Wait, Where Is He?", "Unlock the vanish cap", 0, 150, nullptr));
|
||||
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/segment2/segment2.05C00.rgba16", "F Rank", "Get all 6 Main Stars in One Level", 0, 150, nullptr));
|
||||
Achievement* GET_100_COIN_STAR = MoonAchievements::bind(new Achievement("achievement.get100CoinStar", "textures/segment2/segment2.05C00.rgba16", "E Rank", "Get a 100 Coin Star in One Level", 0, 150, nullptr));
|
||||
Achievement* GET_ALL_LVL_COINS = MoonAchievements::bind(new Achievement("achievement.getAllCoins", "textures/segment2/segment2.05C00.rgba16", "D Rank", "Get all Coins in One Level", 0, 150, nullptr));
|
||||
Achievement* GET_FLOOR_0_STARS = MoonAchievements::bind(new Achievement("achievement.getAllStarsInBasement", "textures/segment2/segment2.05C00.rgba16", "B Rank", "Get all Main Stars in the Basement", 0, 150, nullptr));
|
||||
Achievement* GET_FLOOR_1_STARS = MoonAchievements::bind(new Achievement("achievement.getAllStarsInFloor1", "textures/segment2/segment2.05C00.rgba16", "C Rank", "Get all Main Stars in the First Floor", 0, 150, nullptr));
|
||||
Achievement* GET_FLOOR_2_STARS = MoonAchievements::bind(new Achievement("achievement.getAllStarsInFloor2", "textures/segment2/segment2.05C00.rgba16", "A Rank", "Get all Main Stars in the Second Floor", 0, 150, nullptr));
|
||||
Achievement* GET_FLOOR_3_STARS = MoonAchievements::bind(new Achievement("achievement.getAllStarsInFloor3", "textures/segment2/segment2.05C00.rgba16", "S Rank", "Get all Main Stars in the Third Floor", 0, 150, nullptr));
|
||||
Achievement* GET_CASTLE_STARS = MoonAchievements::bind(new Achievement("achievement.getAllCastleStars", "textures/segment2/segment2.05C00.rgba16", "S+ Rank", "Get all Castle Secret Stars", 0, 150, nullptr));
|
||||
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 Basement", 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 First Floor", 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_KINGBOB = MoonAchievements::bind(new Achievement("achievement.beatKingBobOmb", "textures/segment2/segment2.05C00.rgba16", "Explosive Test", "Beat King Bob-Omb", 0, 150, nullptr));
|
||||
Achievement* DEFEAT_XINGWHOMP = MoonAchievements::bind(new Achievement("achievement.beatKingWhomp", "textures/segment2/segment2.05C00.rgba16", "Come On And Slam", "Beat King Whomp", 0, 150, nullptr));
|
||||
Achievement* DEFEAT_ALL_BOOS = MoonAchievements::bind(new Achievement("achievement.beatAll3BoosOnLLL", "textures/segment2/segment2.05C00.rgba16", "Mario, Where Are You??", "Beat all 3 Boos from BBH", 0, 150, nullptr));
|
||||
Achievement* DEFEAT_MRI = MoonAchievements::bind(new Achievement("achievement.beatMr.I", "textures/segment2/segment2.05C00.rgba16", "I vs Eye", "Beat Mr.I", 0, 150, nullptr));
|
||||
Achievement* DEFEAT_ALL_BULLY = MoonAchievements::bind(new Achievement("achievement.beatAllBigBullies", "textures/segment2/segment2.05C00.rgba16", "The Real Bully", "Beat all big bullies from LLL", 0, 150, nullptr));
|
||||
Achievement* DEFEAT_EYEROK = MoonAchievements::bind(new Achievement("achievement.beatEyerok", "textures/segment2/segment2.05C00.rgba16", "Welcome To The Jam", "Beat Eyerok", 0, 150, nullptr));
|
||||
Achievement* DEFEAT_WIGGLER = MoonAchievements::bind(new Achievement("achievement.beatWiggler", "textures/segment2/segment2.05C00.rgba16", "Insecticude", "Beat Wiggler", 0, 150, nullptr));
|
||||
Achievement* DEFEAT_BOWSER1 = MoonAchievements::bind(new Achievement("achievement.beatFirstBowser", "textures/segment2/segment2.05C00.rgba16", "Bowser Trapped In The Dark", "Beat first Bowser", 0, 150, nullptr));
|
||||
Achievement* DEFEAT_BOWSER2 = MoonAchievements::bind(new Achievement("achievement.beatSecondBowser", "textures/segment2/segment2.05C00.rgba16", "Bowser Burned By The Lava", "Beat second Bowser", 0, 150, nullptr));
|
||||
Achievement* DEFEAT_BOWSER3 = MoonAchievements::bind(new Achievement("achievement.beatFinalBowser", "textures/segment2/segment2.05C00.rgba16", "Bowser Launched Into The Sky", "Beat final Bowser", 0, 150, nullptr));
|
||||
Achievement* DEFEAT_120S_BOWSER = MoonAchievements::bind(new Achievement("achievement.beatGame120Stars", "textures/segment2/segment2.05C00.rgba16", "Power Battle", "Beat final Bowser with 120 stars", 0, 150, nullptr));
|
||||
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_ENEMY = MoonAchievements::bind(new Achievement("achievement.deathByEnemy", "textures/segment2/segment2.05C00.rgba16", "Classic Way", "Get killed by a normal enemy", 0, 150, nullptr));
|
||||
Achievement* DEATH_BY_BOSS = MoonAchievements::bind(new Achievement("achievement.deathByBoss", "textures/segment2/segment2.05C00.rgba16", "Git Gud", "Get killed by a boss", 0, 150, nullptr));
|
||||
Achievement* DEATH_BY_BOWSER = MoonAchievements::bind(new Achievement("achievement.deathByBowser", "textures/segment2/segment2.05C00.rgba16", "Bad Ending", "Get killed by Bowser", 0, 150, nullptr));
|
||||
Achievement* DEATH_BY_CRUSHING = MoonAchievements::bind(new Achievement("achievement.deathByCrushing", "textures/segment2/segment2.05C00.rgba16", "Space Jam", "Get crushed", 0, 150, nullptr));
|
||||
Achievement* DEATH_BY_FALLING = MoonAchievements::bind(new Achievement("achievement.deathByFalling", "textures/segment2/segment2.05C00.rgba16", "My Leg!", "Die by falling", 0, 150, nullptr));
|
||||
Achievement* DEATH_BY_FIRE = MoonAchievements::bind(new Achievement("achievement.deathByFire", "textures/segment2/segment2.05C00.rgba16", "Roasted Mario", "Die by fire", 0, 150, nullptr));
|
||||
Achievement* DEATH_BY_SAND = MoonAchievements::bind(new Achievement("achievement.deathBySand", "textures/segment2/segment2.05C00.rgba16", "Sinked", "Die by sinking sand", 0, 150, nullptr));
|
||||
Achievement* DEATH_BY_DROWNING = MoonAchievements::bind(new Achievement("achievement.deathByDrowning", "textures/segment2/segment2.05C00.rgba16", "Under The Sea", "Die by drowning", 0, 150, nullptr));
|
||||
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", "Sinreked", "Die by sinking sand", 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* RELEASE_CHAIN_CHOMP = MoonAchievements::bind(new Achievement("achievement.releaseChainChomp", "textures/segment2/segment2.05C00.rgba16", "Who Let The Dog Out?", "Get killed by a boss", 0, 150, nullptr));
|
||||
Achievement* BEAT_EVERY_RACE = MoonAchievements::bind(new Achievement("achievement.beatEveryRace", "textures/segment2/segment2.05C00.rgba16", "Olympic Runner", "Beat every race", 0, 150, nullptr));
|
||||
Achievement* JUMP_1000_TIMES = MoonAchievements::bind(new Achievement("achievement.jump1000Times", "textures/segment2/segment2.05C00.rgba16", "Olympic Swimmer", "Grab every star that needs Metal Cap without it", 0, 150, nullptr));
|
||||
Achievement* TALK_25_TIMES = MoonAchievements::bind(new Achievement("achievement.talk25Times", "textures/segment2/segment2.05C00.rgba16", "Olympic Talker", "Talk 25 times with npcs", 0, 150, nullptr));
|
||||
Achievement* SLIDE_20_TIMES = MoonAchievements::bind(new Achievement("achievement.slide20Times", "textures/segment2/segment2.05C00.rgba16", "Burned Ass", "Go trough slides 20 times", 0, 150, nullptr));
|
||||
Achievement* WATCH_END_CREDITS = MoonAchievements::bind(new Achievement("achievement.watchEndCredits", "textures/segment2/segment2.05C00.rgba16", "The Cake Is A Lie?!", "Watch the end credits", 0, 150, nullptr));
|
||||
Achievement* TALK_WITH_YOSHI = MoonAchievements::bind(new Achievement("achievement.talkWithYoshi", "textures/segment2/segment2.05C00.rgba16", "It Is You?", "Talk with Yoshi", 0, 150, nullptr));
|
||||
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", "Who Let The Dog Out?", "Get killed by a boss", false, 0, 150, nullptr));
|
||||
|
||||
Achievement* TRIPLE_JUMP = MoonAchievements::bind(new Achievement("achievement.doATripleJump", "textures/segment2/segment2.05C00.rgba16", "Getting higher", "Do a triple jump", 0, 150, nullptr));
|
||||
Achievement* CHEATER = MoonAchievements::bind(new Achievement("", "textures/segment2/segment2.05C00.rgba16", "What a loser!", "You turned on cheats", 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;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MoonInternal{
|
||||
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 }
|
||||
};
|
||||
|
||||
void setupAchievementEngine(std::string status){
|
||||
if(status == "Update"){
|
||||
#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;
|
||||
}
|
||||
Moon::showAchievementById("achievement.get" + std::to_string(gHudDisplay.stars) + "Stars");
|
||||
|
||||
MoonTriggers::updateAllTriggers();
|
||||
}
|
||||
if(status == "Init"){
|
||||
Moon::registerHookListener({.hookName = HUD_DRAW, .callback = [](HookCall call){
|
||||
Moon::registerHookListener({.hookName = POST_HUD_DRAW, .callback = [](HookCall call){
|
||||
for (auto &aEntry : entries) {
|
||||
if( !aEntry->dead ) {
|
||||
int soundID = SOUND_GENERAL_COIN;
|
||||
|
@ -111,13 +293,13 @@ namespace MoonInternal{
|
|||
float titleWidth = MoonGetTextWidth(aEntry->achievement->title, 0.8, false);
|
||||
float descWidth = MoonGetTextWidth(aEntry->achievement->description, 0.8, false);
|
||||
|
||||
int achievementWidth = 31 + 15 + std::max(titleWidth, descWidth);
|
||||
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, std::min(31, aEntry->width - 1), 31, sys_strdup(aEntry->achievement->icon.c_str()));
|
||||
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);
|
||||
|
@ -156,17 +338,17 @@ namespace Moon {
|
|||
void showAchievement(Achievement* achievement){
|
||||
if(cheatsGotEnabled) return;
|
||||
|
||||
if(std::find_if(entries.begin(), entries.end(), [&cae = achievement] (auto &m) -> bool { return cae->id == m->achievement->id; }) != entries.end()) return;
|
||||
std::cout << "Achievement got triggered: " << achievement->title << std::endl;
|
||||
if(find_if(entries.begin(), entries.end(), [&cae = achievement] (auto &m) -> bool { return cae->id == m->achievement->id; }) != entries.end()) return;
|
||||
cout << "Achievement got triggered: " << achievement->title << endl;
|
||||
entries.push_back(new AchievementEntry({ .launchTime = 0, .dead = false, .achievement = achievement, .entryID = entries.size() }));
|
||||
}
|
||||
|
||||
void showAchievementById(std::string id){
|
||||
void showAchievementById(string id){
|
||||
if(registeredAchievements.find(id) == registeredAchievements.end()) return;
|
||||
Moon::showAchievement(registeredAchievements[id]);
|
||||
}
|
||||
|
||||
Achievement* getAchievementById(std::string id){
|
||||
Achievement* getAchievementById(string id){
|
||||
if(registeredAchievements.find(id) == registeredAchievements.end()) return NULL;
|
||||
return registeredAchievements[id];
|
||||
}
|
||||
|
@ -174,6 +356,6 @@ namespace Moon {
|
|||
|
||||
extern "C" {
|
||||
void show_achievement(char* id){
|
||||
Moon::showAchievementById(std::string(id));
|
||||
Moon::showAchievementById(string(id));
|
||||
}
|
||||
}
|
|
@ -10,15 +10,20 @@ class Achievement {
|
|||
public:
|
||||
std::string id;
|
||||
std::string icon;
|
||||
std::string lockedIcon;
|
||||
std::string title;
|
||||
std::string description;
|
||||
bool hasProgress = false;
|
||||
Achievement* parent;
|
||||
int sortId = 0;
|
||||
int points;
|
||||
long long duration;
|
||||
Achievement(std::string id, std::string icon, std::string title, std::string description, int points, float duration, Achievement* parent){
|
||||
Achievement(std::string id, std::string icon, std::string title, std::string description, bool hasProgress, int points, float duration, Achievement* parent){
|
||||
this->id = id;
|
||||
this->icon = icon;
|
||||
this->lockedIcon = icon+".locked";
|
||||
this->title = title;
|
||||
this->hasProgress = hasProgress;
|
||||
this->description = description;
|
||||
this->duration = duration;
|
||||
this->parent = parent;
|
||||
|
@ -32,6 +37,7 @@ struct AchievementEntry {
|
|||
Achievement* achievement;
|
||||
size_t entryID;
|
||||
|
||||
int progress = 0;
|
||||
int state = 0;
|
||||
int width = 32;
|
||||
int height = 32;
|
||||
|
|
|
@ -9,11 +9,37 @@
|
|||
#include <iostream>
|
||||
#include <map>
|
||||
#include "model_ids.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
map<int, GraphNode*> loadedGraphNodes;
|
||||
|
||||
namespace Moon {
|
||||
GraphNode * GetGraphNode(int modelId){
|
||||
MoonInternal::bindHook(LOAD_GRAPH_NODE);
|
||||
MoonInternal::initBindHook(1,
|
||||
(struct HookParameter){.name = "modelId", .parameter = (void*) &modelId}
|
||||
);
|
||||
GraphNode* graphNode = loadedGraphNodes[modelId];
|
||||
if(graphNode == NULL) return NULL;
|
||||
MoonInternal::callBindHook(1,
|
||||
(HookParameter){.name = "graphNode", .parameter = (void*) &graphNode}
|
||||
);
|
||||
return graphNode;
|
||||
}
|
||||
|
||||
int GetGraphNodeID( GraphNode* graphNode ){
|
||||
auto findResult = std::find_if(std::begin(loadedGraphNodes), std::end(loadedGraphNodes), [&](const std::pair<int, GraphNode*> &pair) {
|
||||
if(pair.second == nullptr || graphNode == nullptr) return false;
|
||||
return pair.second->prev == graphNode;
|
||||
});
|
||||
if (findResult != std::end(loadedGraphNodes))
|
||||
return findResult->first;
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
namespace MoonInternal {
|
||||
void setupModelEngine(string state) {
|
||||
if(state == "Init"){}
|
||||
|
@ -31,15 +57,6 @@ void bind_graph_node(int modelId, GraphNode *graphNode){
|
|||
loadedGraphNodes[modelId] = graphNode;
|
||||
}
|
||||
struct GraphNode * get_graph_node(int modelId){
|
||||
MoonInternal::bindHook(LOAD_GRAPH_NODE);
|
||||
MoonInternal::initBindHook(1,
|
||||
(struct HookParameter){.name = "modelId", .parameter = (void*) &modelId}
|
||||
);
|
||||
GraphNode* graphNode = loadedGraphNodes[modelId];
|
||||
if(graphNode == NULL) return NULL;
|
||||
MoonInternal::callBindHook(1,
|
||||
(HookParameter){.name = "graphNode", .parameter = (void*) &graphNode}
|
||||
);
|
||||
return graphNode;
|
||||
return Moon::GetGraphNode(modelId);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
#ifndef ModEngineModelModule
|
||||
#define ModEngineModelModule
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <string>
|
||||
|
||||
namespace Moon {
|
||||
|
||||
GraphNode * GetGraphNode(int modelId);
|
||||
int GetGraphNodeID( GraphNode* graphNode );
|
||||
}
|
||||
|
||||
namespace MoonInternal {
|
||||
|
@ -14,8 +17,6 @@ namespace MoonInternal {
|
|||
|
||||
#else
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void bind_graph_node(int modelId, struct GraphNode *graphNode);
|
||||
struct GraphNode * get_graph_node(int modelId);
|
||||
|
||||
|
|
|
@ -91,21 +91,61 @@ namespace MoonInternal {
|
|||
return data;
|
||||
}
|
||||
|
||||
float randomFloat(float min, float max) {
|
||||
assert(max > min);
|
||||
float random = ((float) rand()) / (float) RAND_MAX;
|
||||
float range = max - min;
|
||||
return (random*range) + min;
|
||||
}
|
||||
|
||||
void paletteSwap(u8* data, u8* cpy, int w, int h){
|
||||
float mr = 0.07;
|
||||
float mg = 0.72;
|
||||
float mb = 0.21;
|
||||
|
||||
for(int x = 0; x < w * h * 4; x++){
|
||||
if (x % 4 == 0 ) // R
|
||||
data[x] = (data[x] * mr + data[x + 1] * mg + data[x + 2] * mb);
|
||||
if (x % 4 == 1 ) // G
|
||||
data[x] = (data[x - 1] * mr + data[x] * mg + data[x + 1] * mb);
|
||||
if (x % 4 == 2 ) // B
|
||||
data[x] = (data[x - 2] * mr + data[x - 1] * mg + data[x] * mb);
|
||||
if (x % 4 == 3 ) // A
|
||||
data[x] = data[x];
|
||||
cpy[x] = data[x];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void loadTexture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi){
|
||||
|
||||
int w, h;
|
||||
u64 imgsize = 0;
|
||||
string path(fullpath);
|
||||
|
||||
if(!strcmp(fullpath, "gfx/mod-icons://Moon64.png")){
|
||||
gfx_rapi->upload_texture(moon64_logo.pixel_data, moon64_logo.width, moon64_logo.height);
|
||||
return;
|
||||
}
|
||||
|
||||
EntryFileData * imgdata = getTextureData(fullpath);
|
||||
bool isLockedAchievement = path.find("achievement") != std::string::npos && path.find(".locked") != std::string::npos;
|
||||
string fixedPath = isLockedAchievement ? path.substr(0, path.find(".locked")) + ".png" : string(fullpath);
|
||||
|
||||
EntryFileData * imgdata = getTextureData(fixedPath.c_str());
|
||||
if (imgdata) {
|
||||
u8 *data = stbi_load_from_memory(reinterpret_cast<const stbi_uc *>(imgdata->data), imgdata->size, &w, &h, NULL, 4);
|
||||
|
||||
if (data) {
|
||||
gfx_rapi->upload_texture(data, w, h);
|
||||
|
||||
u8 *cpy;
|
||||
|
||||
if (isLockedAchievement) {
|
||||
cpy = new u8[w * h * 4];
|
||||
paletteSwap(data, cpy, w, h);
|
||||
} else
|
||||
cpy = data;
|
||||
|
||||
gfx_rapi->upload_texture(cpy, w, h);
|
||||
stbi_image_free(data);
|
||||
return;
|
||||
} else {
|
||||
|
|
|
@ -117,7 +117,7 @@ namespace Moon {
|
|||
} else {
|
||||
tmpAlloc.push_back(0x9e);
|
||||
}
|
||||
if(static_cast<unsigned char>((char)int(c)) > 127)
|
||||
if(int(c) > 127)
|
||||
tmpAlloc.push_back(0x9e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "interfaces/moon-screen.h"
|
||||
#include "screens/options/main-view.h"
|
||||
#include "screens/addons/addons-view.h"
|
||||
#include "screens/achievements/achievements-view.h"
|
||||
|
||||
extern "C" {
|
||||
#include "game/game_init.h"
|
||||
|
@ -24,6 +25,7 @@ void MoonInitUI() {
|
|||
if(screens.empty()){
|
||||
screens.push_back(new MoonOptMain());
|
||||
screens.push_back(new MoonAddonsScreen());
|
||||
screens.push_back(new MoonAchievementsScreen());
|
||||
}
|
||||
|
||||
screens[currentScreen]->Mount();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "addons-view.h"
|
||||
#include "achievements-view.h"
|
||||
#include <iostream>
|
||||
#include "moon/ui/utils/moon-draw-utils.h"
|
||||
#include "moon/ui/moon-ui-manager.h"
|
||||
|
@ -10,29 +10,37 @@
|
|||
using namespace std;
|
||||
|
||||
extern "C" {
|
||||
#include "pc/platform.h"
|
||||
#include "sm64.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "pc/configfile.h"
|
||||
}
|
||||
|
||||
int scrollModifier = 0;
|
||||
|
||||
int focusFlag;
|
||||
int focusRange = 80;
|
||||
float focusAnim = focusRange / 2;
|
||||
|
||||
void MoonAddonsScreen::Init(){
|
||||
void MoonAchievementsScreen::Init(){
|
||||
this->scrollIndex = 0;
|
||||
scrollModifier = 0;
|
||||
}
|
||||
|
||||
void MoonAddonsScreen::Mount(){
|
||||
void MoonAchievementsScreen::Mount(){
|
||||
|
||||
}
|
||||
|
||||
bool dispatched;
|
||||
|
||||
void MoonAddonsScreen::changeScroll(int idx){
|
||||
bool sortByNID(const string &a, const string &b) {
|
||||
return registeredAchievements[a]->sortId < registeredAchievements[b]->sortId;
|
||||
}
|
||||
|
||||
vector<string> getAchievementKeys(){
|
||||
std::vector<string> keys;
|
||||
for(auto it = registeredAchievements.begin(); it != registeredAchievements.end(); ++it)
|
||||
if(it->first != "achievement.cheater")
|
||||
keys.push_back(it->first);
|
||||
sort(keys.begin(), keys.end(), sortByNID);
|
||||
return keys;
|
||||
}
|
||||
|
||||
void MoonAchievementsScreen::changeScroll(int idx){
|
||||
int size = getAchievementKeys().size();
|
||||
if(idx < 0){
|
||||
if(this->scrollIndex > 0){
|
||||
if(scrollModifier > 0 && this->scrollIndex == scrollModifier)
|
||||
|
@ -40,11 +48,11 @@ void MoonAddonsScreen::changeScroll(int idx){
|
|||
this->scrollIndex--;
|
||||
return;
|
||||
}
|
||||
this->scrollIndex = registeredAchievements.size() - 1;
|
||||
this->scrollIndex = size - 1;
|
||||
scrollModifier = this->scrollIndex - 4;
|
||||
return;
|
||||
}
|
||||
if(this->scrollIndex < registeredAchievements.size() - 1){
|
||||
if(this->scrollIndex < size - 1){
|
||||
if(this->scrollIndex > 3 && !((this->scrollIndex - scrollModifier) % 4)) scrollModifier++;
|
||||
this->scrollIndex++;
|
||||
return;
|
||||
|
@ -53,44 +61,32 @@ void MoonAddonsScreen::changeScroll(int idx){
|
|||
scrollModifier = 0;
|
||||
}
|
||||
|
||||
void MoonAddonsScreen::Update(){
|
||||
void MoonAchievementsScreen::Update(){
|
||||
float yStick = GetStickValue(MoonButtons::U_STICK, false);
|
||||
if(yStick > 0) {
|
||||
if(dispatched) return;
|
||||
MoonAddonsScreen::changeScroll(-1);
|
||||
MoonAchievementsScreen::changeScroll(-1);
|
||||
dispatched = true;
|
||||
}
|
||||
if(yStick < 0) {
|
||||
if(dispatched) return;
|
||||
MoonAddonsScreen::changeScroll(1);
|
||||
MoonAchievementsScreen::changeScroll(1);
|
||||
dispatched = true;
|
||||
}
|
||||
if(!yStick)
|
||||
dispatched = false;
|
||||
|
||||
if(IsBtnPressed(MoonButtons::A_BTN)) {
|
||||
|
||||
}
|
||||
if(IsBtnPressed(MoonButtons::B_BTN)) {
|
||||
MoonChangeUI(0);
|
||||
}
|
||||
|
||||
if(!(gGlobalTimer % 20))
|
||||
stickAnim = !stickAnim;
|
||||
|
||||
MoonScreen::Update();
|
||||
}
|
||||
|
||||
static std::string cropTxt(string txt, int length){
|
||||
int currLngt = min((int) txt.length(), length);
|
||||
string desc = txt.substr(0, currLngt);
|
||||
desc.erase(find_if(desc.rbegin(), desc.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), desc.end());
|
||||
return currLngt >= length ? desc + " ..." : desc;
|
||||
}
|
||||
|
||||
char *strdup(const char *src_str) noexcept {
|
||||
char *new_str = new char[std::strlen(src_str) + 1];
|
||||
std::strcpy(new_str, src_str);
|
||||
return new_str;
|
||||
}
|
||||
|
||||
void MoonAddonsScreen::Draw(){
|
||||
void MoonAchievementsScreen::Draw(){
|
||||
string curTitle = "Achievements";
|
||||
float step = 1.5;
|
||||
|
||||
|
@ -112,7 +108,9 @@ void MoonAddonsScreen::Draw(){
|
|||
|
||||
Color focusColor = {255, 255, 255, 40 + focusAnim};
|
||||
|
||||
int packAmount = registeredAchievements.size();
|
||||
vector<string> achievementList = getAchievementKeys();
|
||||
|
||||
int packAmount = achievementList.size();
|
||||
int maxPacks = 5;
|
||||
int iMod = scrollModifier;
|
||||
|
||||
|
@ -122,36 +120,35 @@ void MoonAddonsScreen::Draw(){
|
|||
if(index > packAmount - 1){
|
||||
this->scrollIndex = 0;
|
||||
scrollModifier = 0;
|
||||
cout << "Triggered overflow, coming back to 0" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
auto &addon = registeredAchievements[registeredAchievements.];
|
||||
auto &achievement = registeredAchievements[achievementList[index]];
|
||||
|
||||
if(addon == NULL) return;
|
||||
if(achievement == NULL) return;
|
||||
|
||||
bool selected = (i + iMod) == this->scrollIndex;
|
||||
int itemWidth = boxWidth - (selected ? 15 : 0);
|
||||
int itemWidth = boxWidth - 0;
|
||||
|
||||
MoonDrawRectangle(35, 45 + (i * 35), itemWidth - 20, 31, (i + iMod) == this->scrollIndex && !selected ? focusColor : (Color){0, 0, 0, 100}, true);
|
||||
string pathPrefix = "mod-icons://";
|
||||
string iconPath = pathPrefix.append(addon->name);
|
||||
char* parsed = strdup(iconPath.c_str());
|
||||
if(parsed != nullptr)
|
||||
MoonDrawTexture(35, 45 + (i * 35), 30, 30, parsed);
|
||||
MoonDrawText(35 + 26, 46 + (i * 35), to_string(i + iMod + 1), 0.5, {255, 255, 255, 255}, true, true);
|
||||
MoonDrawRectangle(35, 45 + (i * 35), itemWidth - 20, 31, selected ? focusColor : (Color){0, 0, 0, 100}, true);
|
||||
bool isUnlocked = find_if(entries.begin(), entries.end(), [&cae = achievement] (auto &m) -> bool { return cae->id == m->achievement->id; }) != entries.end();
|
||||
string iconPath = isUnlocked ? achievement->icon : achievement->lockedIcon;
|
||||
|
||||
MoonDrawText(70, 45 + (i * 35) + 3, cropTxt(addon->name, 37), 0.8, {255, 255, 255, 255}, true, true);
|
||||
char* parsed = sys_strdup(iconPath.c_str());
|
||||
if(parsed != nullptr){
|
||||
MoonDrawTexture (35, 45 + (i * 35), 30, 30, parsed);
|
||||
}
|
||||
|
||||
MoonDrawText(70, 45 + (i * 35) + 3, achievement->title, 0.8, {255, 255, 255, 255}, true, true);
|
||||
|
||||
int maxDesc = 37;
|
||||
int currLngt = min((int) addon->description.length(), maxDesc);
|
||||
MoonDrawText(70, 45 + (i * 35) + 16, cropTxt(addon->description, 37), 0.8, {255, 255, 255, 255}, true, true);
|
||||
int currLngt = min((int) achievement->description.length(), maxDesc);
|
||||
MoonDrawText(70, 45 + (i * 35) + 16, achievement->description, 0.8, {255, 255, 255, 255}, true, true);
|
||||
|
||||
string rawVer = to_string(addon->version);
|
||||
string version = "v"+rawVer.substr(0, rawVer.find(".")+2);
|
||||
string basePath = "textures/moon/controller/";
|
||||
basePath.append(stickAnim ? "stick-down.rgba16" : "stick-up.rgba16");
|
||||
|
||||
MoonDrawText(itemWidth + 13 - MoonGetTextWidth(version, 0.5, false), 45 + (i * 35) + 2, version, 0.5, {255, 255, 255, 255}, true, true);
|
||||
MoonDrawText(itemWidth + 13 - MoonGetTextWidth(addon->authors[0], 0.5, false), 45 + (i * 35) + 22, addon->authors[0], 0.5, {255, 255, 255, 255}, true, true);
|
||||
MoonDrawButton(5, GetScreenHeight() - 24, "Move", basePath, 16, 0, false);
|
||||
}
|
||||
|
||||
MoonScreen::Draw();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef MoonScreenAddons
|
||||
#define MoonScreenAddons
|
||||
#ifndef MoonScreenAchievements
|
||||
#define MoonScreenAchievements
|
||||
#include "moon/ui/interfaces/moon-screen.h"
|
||||
|
||||
class MoonAddonsScreen : public MoonScreen {
|
||||
class MoonAchievementsScreen : public MoonScreen {
|
||||
public:
|
||||
void Init();
|
||||
void Update();
|
||||
|
@ -10,6 +10,13 @@ public:
|
|||
void Mount();
|
||||
private:
|
||||
void changeScroll(int idx);
|
||||
int scrollModifier = 0;
|
||||
|
||||
int focusFlag;
|
||||
int focusRange = 80;
|
||||
float focusAnim = focusRange / 2;
|
||||
bool dispatched;
|
||||
bool stickAnim = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -143,6 +143,10 @@ void MoonAddonsScreen::Update(){
|
|||
}
|
||||
MoonChangeUI(0);
|
||||
}
|
||||
|
||||
if(!(gGlobalTimer % 20))
|
||||
stickAnim = !stickAnim;
|
||||
|
||||
MoonScreen::Update();
|
||||
}
|
||||
|
||||
|
@ -232,6 +236,11 @@ void MoonAddonsScreen::Draw(){
|
|||
MoonDrawRectangle(itemWidth + 16, 45 + (i * 35) + 21.7, 13, 9.3, currentSubItem == ItemButtons::TOGGLE ? focusColor : (Color){0, 0, 0, 100}, true);
|
||||
MoonDrawTexture (itemWidth + 18, 46 + (i * 35) + 21.7, 8, 8, "textures/special/remove.rgba16");
|
||||
}
|
||||
|
||||
string basePath = "textures/moon/controller/";
|
||||
basePath.append(stickAnim ? "stick-down.rgba16" : "stick-up.rgba16");
|
||||
|
||||
MoonDrawButton(5, GetScreenHeight() - 24, "Move", basePath, 16, 0, false);
|
||||
}
|
||||
|
||||
MoonScreen::Draw();
|
||||
|
|
|
@ -9,6 +9,7 @@ public:
|
|||
void Draw();
|
||||
void Mount();
|
||||
private:
|
||||
bool stickAnim = 0;
|
||||
void changeScroll(int idx);
|
||||
};
|
||||
|
||||
|
|
|
@ -36,5 +36,8 @@ MGameCategory::MGameCategory() : MoonCategory("TEXT_OPT_GAME"){
|
|||
this->catOptions.push_back(new MWValue(22, exitY + 17, "Texture Packs", { .btn = [](){
|
||||
MoonChangeUI(1);
|
||||
}}, false));
|
||||
this->catOptions.push_back(new MWValue(22, exitY + 34, "TEXT_EXIT_GAME", { .btn = game_exit}, true));
|
||||
this->catOptions.push_back(new MWValue(22, exitY + 34, "Achievements", { .btn = [](){
|
||||
MoonChangeUI(2);
|
||||
}}, false));
|
||||
this->catOptions.push_back(new MWValue(22, exitY + 51, "TEXT_EXIT_GAME", { .btn = game_exit}, true));
|
||||
}
|
|
@ -97,19 +97,6 @@ void MoonOptMain::Update(){
|
|||
MoonScreen::Update();
|
||||
}
|
||||
|
||||
void drawButton(int x, int y, string text, string texture, int size, int offset, bool rtl){
|
||||
if(!rtl){
|
||||
MoonDrawTexture(GFX_DIMENSIONS_FROM_LEFT_EDGE(x), y - 3 + offset, size, size, sys_strdup(texture.c_str()));
|
||||
MoonDrawText(x + 16 + 3, y, text, 0.8, {255, 255, 255, 255}, true, false);
|
||||
} else {
|
||||
x = GetScreenWidth(false) - x;
|
||||
int txtWidth = MoonGetTextWidth(text, 0.8, false);
|
||||
|
||||
MoonDrawTexture(GFX_DIMENSIONS_FROM_LEFT_EDGE(x) - txtWidth - size - 3, y - 3 + offset, size, size, sys_strdup(texture.c_str()));
|
||||
MoonDrawText(x - txtWidth, y, text, 0.8, {255, 255, 255, 255}, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
void MoonOptMain::Draw(){
|
||||
wstring curTitle = categories[categoryIndex]->titleKey ? Moon::getLanguageKey(categories[categoryIndex]->categoryName) : categories[categoryIndex]->categoryName;
|
||||
|
||||
|
@ -118,21 +105,22 @@ void MoonOptMain::Draw(){
|
|||
MoonDrawWideColoredText(SCREEN_WIDTH / 2 - txtWidth / 2, 20, curTitle, 1.0, {255, 255, 255, 255}, true, true);
|
||||
MoonDrawRectangle(25, 50, SCREEN_WIDTH - 50, GetScreenHeight() * 0.6, {0, 0, 0, 100}, true);
|
||||
|
||||
string stickTexture = "textures/moon/";
|
||||
string basePath = "textures/moon/controller/";
|
||||
|
||||
if(this->selected == NULL){
|
||||
stickTexture.append(stickAnim ? "stick-down.rgba16" : "stick-up.rgba16");
|
||||
drawButton(5, GetScreenHeight() - 24, "Move", stickTexture, 16, 0, false);
|
||||
basePath.append(stickAnim ? "stick-down.rgba16" : "stick-up.rgba16");
|
||||
MoonDrawButton(5, GetScreenHeight() - 24, "Move", basePath, 16, 0, false);
|
||||
} else{
|
||||
stickTexture.append(stickAnim ? "stick-left.rgba16" : "stick-right.rgba16");
|
||||
drawButton(5, GetScreenHeight() - 24, "Change value", stickTexture, 16, 0, false);
|
||||
basePath.append(stickAnim ? "stick-left.rgba16" : "stick-right.rgba16");
|
||||
MoonDrawButton(5, GetScreenHeight() - 24, "Change value", basePath, 16, 0, false);
|
||||
}
|
||||
|
||||
drawButton(7, GetScreenHeight() - 24, this->selected == NULL ? "Select" : "Back", this->selected == NULL ? "textures/moon/a-alt-btn.rgba16" : "textures/moon/b-alt-btn.rgba16", 10, 4, true);
|
||||
MoonDrawButton(7, GetScreenHeight() - 24, this->selected == NULL ? "Select" : "Back", this->selected == NULL ? "textures/moon/controller/a-alt-btn.rgba16" : "textures/moon/controller/b-alt-btn.rgba16", 10, 4, true);
|
||||
|
||||
MoonScreen::Draw();
|
||||
}
|
||||
|
||||
|
||||
void MoonOptMain::Dispose(){
|
||||
configfile_save(configfile_name());
|
||||
play_sound(SOUND_MENU_CHANGE_SELECT, gGlobalSoundSource);
|
||||
|
|
|
@ -11,6 +11,7 @@ public:
|
|||
void Dispose();
|
||||
private:
|
||||
void setCategory(int index);
|
||||
bool stickAnim = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
#include "gfx_dimensions.h"
|
||||
#include "moon/texts/moon-loader.h"
|
||||
#include "moon/texts/text-converter.h"
|
||||
#include "moon/ui/interfaces/moon-screen.h"
|
||||
|
||||
extern "C"{
|
||||
#include "pc/platform.h"
|
||||
}
|
||||
|
||||
float MoonGetTextWidth(std::wstring text, float scale, bool colored) {
|
||||
return (float)moon_get_text_width(Moon::GetTranslatedText(text), scale, colored);
|
||||
|
@ -73,4 +78,47 @@ void MoonDrawTexture(float x, float y, float w, float h, char* texture){
|
|||
gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, w * h - 1, CALC_DXT(w, G_IM_SIZ_32b_BYTES));
|
||||
gSPTextureRectangle(gDisplayListHead++, (int) x << 2, (int) y << 2, (int)(x + w) << 2, (int)(y + h) << 2, G_TX_RENDERTILE, 0, 0, 4 << 10, 1 << 10);
|
||||
gSPDisplayList(gDisplayListHead++, dl_hud_img_end);
|
||||
}
|
||||
|
||||
void MoonDrawBWTexture(float x, float y, float w, float h, char* texture){
|
||||
s32 xl = MAX(0, x);
|
||||
s32 yl = MAX(0, y);
|
||||
s32 xh = MAX(0, x + w - 1);
|
||||
s32 yh = MAX(0, y + h - 1);
|
||||
s32 s = 0;
|
||||
s32 t = 0;
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
gDPSetCycleType(gDisplayListHead++, G_CYC_COPY);
|
||||
gDPSetTexturePersp(gDisplayListHead++, G_TP_NONE);
|
||||
gDPSetAlphaCompare(gDisplayListHead++, G_AC_THRESHOLD);
|
||||
gDPSetBlendColor(gDisplayListHead++, 255, 255, 255, 255);
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_XLU_SURF, G_RM_AA_XLU_SURF2);
|
||||
gDPTileSync(gDisplayListHead++);
|
||||
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_I, G_IM_SIZ_8b, 32, texture);
|
||||
gDPSetTile(gDisplayListHead++, G_IM_FMT_I, G_IM_SIZ_8b, 4, 0, 7, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 0);
|
||||
gDPLoadSync(gDisplayListHead++);
|
||||
gDPLoadTile(gDisplayListHead++, 7, 0, 0, 124, 124);
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
gDPSetTile(gDisplayListHead++, G_IM_FMT_I, G_IM_SIZ_8b, 4, 0, 0, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 0);
|
||||
gDPSetTileSize(gDisplayListHead++, 0, 0, 0, 124, 124);
|
||||
gSPTextureRectangle(gDisplayListHead++, xl << 2, yl << 2, xh << 2, yh << 2, 0, s << 5, t << 5, 4096, 1024);
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
gDPSetCycleType(gDisplayListHead++, G_CYC_1CYCLE);
|
||||
gSPTexture(gDisplayListHead++, 65535, 65535, 0, G_TX_RENDERTILE, G_OFF);
|
||||
gDPSetTexturePersp(gDisplayListHead++, G_TP_PERSP);
|
||||
gDPSetAlphaCompare(gDisplayListHead++, G_AC_NONE);
|
||||
gDPSetRenderMode(gDisplayListHead++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
|
||||
}
|
||||
|
||||
void MoonDrawButton(int x, int y, std::string text, std::string texture, int size, int offset, bool rtl){
|
||||
if(!rtl){
|
||||
MoonDrawTexture(GFX_DIMENSIONS_FROM_LEFT_EDGE(x), y - 3 + offset, size, size, sys_strdup(texture.c_str()));
|
||||
MoonDrawText(x + 16 + 3, y, text, 0.8, {255, 255, 255, 255}, true, false);
|
||||
} else {
|
||||
x = GetScreenWidth(false) - x;
|
||||
int txtWidth = MoonGetTextWidth(text, 0.8, false);
|
||||
|
||||
MoonDrawTexture(GFX_DIMENSIONS_FROM_LEFT_EDGE(x) - txtWidth - size - 3, y - 3 + offset, size, size, sys_strdup(texture.c_str()));
|
||||
MoonDrawText(x - txtWidth, y, text, 0.8, {255, 255, 255, 255}, true, false);
|
||||
}
|
||||
}
|
|
@ -26,6 +26,8 @@ void MoonDrawColoredText(float x, float y, std::string text, float scale, struct
|
|||
void MoonDrawWideColoredText(float x, float y, std::wstring text, float scale, struct Color color, bool dropShadow, bool u4_3);
|
||||
|
||||
void MoonDrawTexture (float x, float y, float w, float h, char* texture);
|
||||
void MoonDrawBWTexture (float x, float y, float w, float h, char* texture);
|
||||
void MoonDrawRectangle (float x, float y, float w, float h, struct Color c, bool u4_3);
|
||||
void MoonDrawButton (int x, int y, std::string text, std::string texture, int size, int offset, bool rtl);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,6 +57,7 @@ void moon_draw_scaled_text(f32 x, f32 y, const u8 *str, float scaleX, float scal
|
|||
Mtx *_Matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
if (!_Matrix) return;
|
||||
guScale(_Matrix, scaleX, scaleY, 1.f);
|
||||
create_dl_ortho_matrix();
|
||||
create_dl_translation_matrix(MENU_MTX_PUSH, x, y, 0.0f);
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(_Matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
|
||||
|
||||
|
@ -140,7 +141,22 @@ void moon_draw_texture(s32 x, s32 y, u32 w, u32 h, char *texture) {
|
|||
gSPDisplayList(gDisplayListHead++, dl_hud_img_end);
|
||||
}
|
||||
|
||||
void moon_draw_uv_texture(s32 x, s32 y, u32 w, u32 h, u32 tw, u32 th, s32 u, s32 v, char *texture) {
|
||||
gSPDisplayList(gDisplayListHead++, dl_hud_img_begin);
|
||||
gDPSetTile(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_32b, 0, 0, G_TX_LOADTILE, 0, G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD);
|
||||
gDPTileSync(gDisplayListHead++);
|
||||
gDPSetTile(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_32b, 2, 0, G_TX_RENDERTILE, 0, G_TX_NOMIRROR, 3, G_TX_NOLOD, G_TX_NOMIRROR, 3, G_TX_NOLOD);
|
||||
gDPSetTileSize(gDisplayListHead++, G_TX_RENDERTILE, 0, 0, tw << G_TEXTURE_IMAGE_FRAC, th << G_TEXTURE_IMAGE_FRAC);
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_32b, 1, texture);
|
||||
gDPLoadSync(gDisplayListHead++);
|
||||
gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, w * h - 1, CALC_DXT(w, G_IM_SIZ_32b_BYTES));
|
||||
gSPTextureRectangle(gDisplayListHead++, x << 2, y << 2, (x + w) << 2, (y + h) << 2, G_TX_RENDERTILE, u, v, 4 << 10, 1 << 10);
|
||||
gSPDisplayList(gDisplayListHead++, dl_hud_img_end);
|
||||
}
|
||||
|
||||
void moon_draw_rectangle(f32 x, f32 y, f32 w, f32 h, struct Color c, u8 u4_3) {
|
||||
create_dl_ortho_matrix();
|
||||
Mtx *_Matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
|
||||
if (!_Matrix) return;
|
||||
|
||||
|
|
|
@ -16,5 +16,6 @@ void moon_draw_scaled_text(f32 x, f32 y, const u8 *str, float scaleX, float scal
|
|||
void moon_draw_text(f32 x, f32 y, const u8 *str, float scale);
|
||||
void moon_draw_rectangle(f32 x, f32 y, f32 w, f32 h, struct Color c, u8 u4_3);
|
||||
void moon_draw_texture(s32 x, s32 y, u32 w, u32 h, char *texture);
|
||||
void moon_draw_uv_texture(s32 x, s32 y, u32 w, u32 h, u32 tw, u32 th, s32 u, s32 v, char *texture);
|
||||
|
||||
#endif
|
|
@ -280,28 +280,6 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureData **n, const uin
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool preload_base_texture(void* user, const char *fullpath) {
|
||||
int w, h;
|
||||
u64 imgsize = 0;
|
||||
|
||||
u8 *imgdata = fs_load_file(fullpath, &imgsize);
|
||||
if (imgdata) {
|
||||
char texname[SYS_MAX_PATH];
|
||||
strncpy(texname, fullpath, sizeof(texname));
|
||||
texname[sizeof(texname)-1] = 0;
|
||||
char *dot = strrchr(texname, '.');
|
||||
if (dot) *dot = 0;
|
||||
|
||||
char *actualname = texname;
|
||||
if (!strncmp(FS_TEXTUREDIR "/", actualname, 4)) actualname += 4;
|
||||
actualname = sys_strdup(actualname);
|
||||
assert(actualname);
|
||||
|
||||
moon_load_base_texture(imgdata, imgsize, actualname);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void load_memory_texture(void *imgdata, long size) {
|
||||
int w, h;
|
||||
|
||||
|
@ -317,41 +295,6 @@ static inline void load_memory_texture(void *imgdata, long size) {
|
|||
gfx_rapi->upload_texture(missing_texture, MISSING_W, MISSING_H);
|
||||
}
|
||||
|
||||
|
||||
// this is taken straight from n64graphics
|
||||
static bool texname_to_texformat(const char *name, u8 *fmt, u8 *siz) {
|
||||
static const struct {
|
||||
const char *name;
|
||||
const u8 format;
|
||||
const u8 size;
|
||||
} fmt_table[] = {
|
||||
{ "rgba16", G_IM_FMT_RGBA, G_IM_SIZ_16b },
|
||||
{ "rgba32", G_IM_FMT_RGBA, G_IM_SIZ_32b },
|
||||
{ "ia1", G_IM_FMT_IA, G_IM_SIZ_8b }, // uhh
|
||||
{ "ia4", G_IM_FMT_IA, G_IM_SIZ_4b },
|
||||
{ "ia8", G_IM_FMT_IA, G_IM_SIZ_8b },
|
||||
{ "ia16", G_IM_FMT_IA, G_IM_SIZ_16b },
|
||||
{ "i4", G_IM_FMT_I, G_IM_SIZ_4b },
|
||||
{ "i8", G_IM_FMT_I, G_IM_SIZ_8b },
|
||||
{ "ci8", G_IM_FMT_I, G_IM_SIZ_8b },
|
||||
{ "ci16", G_IM_FMT_I, G_IM_SIZ_16b },
|
||||
};
|
||||
|
||||
char *fstr = strrchr(name, '.');
|
||||
if (!fstr) return false; // no format string?
|
||||
fstr++;
|
||||
|
||||
for (unsigned i = 0; i < sizeof(fmt_table) / sizeof(fmt_table[0]); ++i) {
|
||||
if (!sys_strcasecmp(fstr, fmt_table[i].name)) {
|
||||
*fmt = fmt_table[i].format;
|
||||
*siz = fmt_table[i].size;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void import_texture(int tile) {
|
||||
uint8_t fmt = rdp.texture_tile.fmt;
|
||||
uint8_t siz = rdp.texture_tile.siz;
|
||||
|
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 712 B After Width: | Height: | Size: 712 B |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 698 B After Width: | Height: | Size: 698 B |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |