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