1 // SONIC ROBO BLAST 2 2 //----------------------------------------------------------------------------- 3 // Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. 4 // Copyright (C) 2012-2020 by Sonic Team Junior. 5 // 6 // This program is free software distributed under the 7 // terms of the GNU General Public License, version 2. 8 // See the 'LICENSE' file for more details. 9 //----------------------------------------------------------------------------- 10 /// \file m_cond.h 11 /// \brief Unlockable condition system for SRB2 version 2.1 12 13 #include "doomdef.h" 14 15 // -------- 16 // Typedefs 17 // -------- 18 19 // DEHackEd structure for each is listed after the condition type 20 // [required] <optional> 21 typedef enum 22 { 23 UC_PLAYTIME, // PLAYTIME [tics] 24 UC_GAMECLEAR, // GAMECLEAR <x times> 25 UC_ALLEMERALDS, // ALLEMERALDS <x times> 26 UC_ULTIMATECLEAR, // ULTIMATECLEAR <x times> 27 UC_OVERALLSCORE, // OVERALLSCORE [score to beat] 28 UC_OVERALLTIME, // OVERALLTIME [time to beat, tics] 29 UC_OVERALLRINGS, // OVERALLRINGS [rings to beat] 30 UC_MAPVISITED, // MAPVISITED [map number] 31 UC_MAPBEATEN, // MAPBEATEN [map number] 32 UC_MAPALLEMERALDS, // MAPALLEMERALDS [map number] 33 UC_MAPULTIMATE, // MAPULTIMATE [map number] 34 UC_MAPPERFECT, // MAPPERFECT [map number] 35 UC_MAPSCORE, // MAPSCORE [map number] [score to beat] 36 UC_MAPTIME, // MAPTIME [map number] [time to beat, tics] 37 UC_MAPRINGS, // MAPRINGS [map number] [rings to beat] 38 UC_NIGHTSSCORE, // NIGHTSSCORE [map number] <mare, omit or "0" for overall> [score to beat] 39 UC_NIGHTSTIME, // NIGHTSTIME [map number] <mare, omit "0" overall> [time to beat, tics] 40 UC_NIGHTSGRADE, // NIGHTSGRADE [map number] <mare, omit "0" overall> [grade] 41 UC_TRIGGER, // TRIGGER [trigger number] 42 UC_TOTALEMBLEMS, // TOTALEMBLEMS [number of emblems] 43 UC_EMBLEM, // EMBLEM [emblem number] 44 UC_EXTRAEMBLEM, // EXTRAEMBLEM [extra emblem number] 45 UC_CONDITIONSET, // CONDITIONSET [condition set number] 46 } conditiontype_t; 47 48 // Condition Set information 49 typedef struct 50 { 51 UINT32 id; /// <- The ID of this condition. 52 /// In an unlock condition, all conditions with the same ID 53 /// must be true to fulfill the unlockable requirements. 54 /// Only one ID set needs to be true, however. 55 conditiontype_t type;/// <- The type of condition 56 INT32 requirement; /// <- The requirement for this variable. 57 INT16 extrainfo1; /// <- Extra information for the condition when needed. 58 INT16 extrainfo2; /// <- Extra information for the condition when needed. 59 } condition_t; 60 typedef struct 61 { 62 UINT32 numconditions; /// <- number of conditions. 63 condition_t *condition; /// <- All conditionals to be checked. 64 UINT8 achieved; /// <- Whether this conditional has been achieved already or not. 65 /// (Conditional checking is skipped if true -- it's assumed you can't relock an unlockable) 66 } conditionset_t; 67 68 // Emblem information 69 #define ET_GLOBAL 0 // Emblem with a position in space 70 #define ET_SKIN 1 // Skin specific emblem with a position in space, var == skin 71 #define ET_MAP 2 // Beat the map 72 #define ET_SCORE 3 // Get the score 73 #define ET_TIME 4 // Get the time 74 #define ET_RINGS 5 // Get the rings 75 #define ET_NGRADE 6 // Get the grade 76 #define ET_NTIME 7 // Get the time (NiGHTS mode) 77 78 // Global emblem flags 79 #define GE_NIGHTSPULL 1 // sun off the nights track - loop it 80 #define GE_NIGHTSITEM 2 // moon on the nights track - find it 81 82 // Map emblem flags 83 #define ME_ALLEMERALDS 1 84 #define ME_ULTIMATE 2 85 #define ME_PERFECT 4 86 87 typedef struct 88 { 89 UINT8 type; ///< Emblem type 90 INT16 tag; ///< Tag of emblem mapthing 91 INT16 level; ///< Level on which this emblem can be found. 92 UINT8 sprite; ///< emblem sprite to use, 0 - 25 93 UINT16 color; ///< skincolor to use 94 INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin) 95 char hint[110]; ///< Hint for emblem hints menu 96 UINT8 collected; ///< Do you have this emblem? 97 } emblem_t; 98 typedef struct 99 { 100 char name[20]; ///< Name of the goal (used in the "emblem awarded" cecho) 101 char description[40]; ///< Description of goal (used in statistics) 102 UINT8 conditionset; ///< Condition set that awards this emblem. 103 UINT8 showconditionset; ///< Condition set that shows this emblem. 104 UINT8 sprite; ///< emblem sprite to use, 0 - 25 105 UINT16 color; ///< skincolor to use 106 UINT8 collected; ///< Do you have this emblem? 107 } extraemblem_t; 108 109 // Unlockable information 110 typedef struct 111 { 112 char name[64]; 113 char objective[64]; 114 UINT16 height; // menu height 115 UINT8 conditionset; 116 UINT8 showconditionset; 117 INT16 type; 118 INT16 variable; 119 UINT8 nocecho; 120 UINT8 nochecklist; 121 UINT8 unlocked; 122 } unlockable_t; 123 124 #define SECRET_NONE -6 // Does nil. Use with levels locked by UnlockRequired 125 #define SECRET_ITEMFINDER -5 // Enables Item Finder/Emblem Radar 126 #define SECRET_EMBLEMHINTS -4 // Enables Emblem Hints 127 #define SECRET_PANDORA -3 // Enables Pandora's Box 128 #define SECRET_RECORDATTACK -2 // Enables Record Attack on the main menu 129 #define SECRET_NIGHTSMODE -1 // Enables NiGHTS Mode on the main menu 130 #define SECRET_HEADER 0 // Does nothing on its own, just serves as a header for the menu 131 #define SECRET_LEVELSELECT 1 // Selectable level select 132 #define SECRET_WARP 2 // Selectable warp 133 #define SECRET_SOUNDTEST 3 // Sound Test 134 #define SECRET_CREDITS 4 // Enables Credits 135 136 // If you have more secrets than these variables allow in your game, 137 // you seriously need to get a life. 138 #define MAXCONDITIONSETS 128 139 #define MAXEMBLEMS 512 140 #define MAXEXTRAEMBLEMS 16 141 #define MAXUNLOCKABLES 32 142 143 extern conditionset_t conditionSets[MAXCONDITIONSETS]; 144 extern emblem_t emblemlocations[MAXEMBLEMS]; 145 extern extraemblem_t extraemblems[MAXEXTRAEMBLEMS]; 146 extern unlockable_t unlockables[MAXUNLOCKABLES]; 147 148 extern INT32 numemblems; 149 extern INT32 numextraemblems; 150 151 extern UINT32 unlocktriggers; 152 153 // Condition set setup 154 void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2); 155 156 // Clearing secrets 157 void M_ClearConditionSet(UINT8 set); 158 void M_ClearSecrets(void); 159 160 // Updating conditions and unlockables 161 void M_CheckUnlockConditions(void); 162 UINT8 M_UpdateUnlockablesAndExtraEmblems(void); 163 void M_SilentUpdateUnlockablesAndEmblems(void); 164 UINT8 M_CheckLevelEmblems(void); 165 UINT8 M_CompletionEmblems(void); 166 167 // Checking unlockable status 168 UINT8 M_AnySecretUnlocked(void); 169 UINT8 M_SecretUnlocked(INT32 type); 170 UINT8 M_MapLocked(INT32 mapnum); 171 INT32 M_CountEmblems(void); 172 173 // Emblem shit 174 emblem_t *M_GetLevelEmblems(INT32 mapnum); 175 skincolornum_t M_GetEmblemColor(emblem_t *em); 176 const char *M_GetEmblemPatch(emblem_t *em, boolean big); 177 skincolornum_t M_GetExtraEmblemColor(extraemblem_t *em); 178 const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big); 179 180 // If you're looking to compare stats for unlocks or what not, use these 181 // They stop checking upon reaching the target number so they 182 // should be (theoretically?) slightly faster. 183 UINT8 M_GotEnoughEmblems(INT32 number); 184 UINT8 M_GotHighEnoughScore(INT32 tscore); 185 UINT8 M_GotLowEnoughTime(INT32 tictime); 186 UINT8 M_GotHighEnoughRings(INT32 trings); 187 188 #define M_Achieved(a) ((a) >= MAXCONDITIONSETS || conditionSets[a].achieved) 189