1 //********************************************************************************************
2 //*
3 //*    This file is part of Egoboo.
4 //*
5 //*    Egoboo is free software: you can redistribute it and/or modify it
6 //*    under the terms of the GNU General Public License as published by
7 //*    the Free Software Foundation, either version 3 of the License, or
8 //*    (at your option) any later version.
9 //*
10 //*    Egoboo is distributed in the hope that it will be useful, but
11 //*    WITHOUT ANY WARRANTY; without even the implied warranty of
12 //*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 //*    General Public License for more details.
14 //*
15 //*    You should have received a copy of the GNU General Public License
16 //*    along with Egoboo.  If not, see <http://www.gnu.org/licenses/>.
17 //*
18 //********************************************************************************************
19 
20 /// @file file_formats/module_file.c
21 /// @brief Functions for reading and writing Egoboo's menu.txt file ( /modules/*.mod/gamedat/menu.txt )
22 /// @details
23 
24 #include "module_file.h"
25 
26 #include "char.inl"
27 #include "enchant.inl"
28 #include "log.h"
29 #include "menu.h"
30 #include "sound.h"
31 #include "graphic.h"
32 #include "passage.h"
33 #include "input.h"
34 #include "game.h"
35 #include "quest.h"
36 
37 #include "egoboo_vfs.h"
38 #include "egoboo_strutil.h"
39 #include "egoboo_setup.h"
40 #include "egoboo_fileutil.h"
41 #include "egoboo.h"
42 
43 //--------------------------------------------------------------------------------------------
44 //--------------------------------------------------------------------------------------------
module_load_info_vfs(const char * szLoadName,mod_file_t * pmod)45 mod_file_t * module_load_info_vfs( const char * szLoadName, mod_file_t * pmod )
46 {
47     /// @details BB@> this function actually reads in the module data
48 
49     vfs_FILE * fileread;
50     int cnt;
51     char cTmp;
52 
53     // clear all the module info
54     if ( NULL == pmod ) return NULL;
55 
56     memset( pmod, 0, sizeof( *pmod ) );
57 
58     // see if we can open the file
59     fileread = vfs_openRead( szLoadName );
60     if ( NULL == fileread ) return NULL;
61 
62     // Read basic data
63     fget_next_name( fileread, pmod->longname, sizeof( pmod->longname ) );
64     fget_next_string( fileread, pmod->reference, SDL_arraysize( pmod->reference ) );
65     pmod->unlockquest.id    = fget_next_idsz( fileread );
66     pmod->unlockquest.level = fget_int( fileread );
67 
68     pmod->importamount = fget_next_int( fileread );
69     pmod->allowexport  = fget_next_bool( fileread );
70     pmod->minplayers   = fget_next_int( fileread );
71     pmod->maxplayers   = fget_next_int( fileread );
72 
73     cTmp = fget_next_char( fileread );
74     if ( 'T' == toupper( cTmp ) )  pmod->respawnvalid = btrue;
75     if ( 'A' == toupper( cTmp ) )  pmod->respawnvalid = RESPAWN_ANYTIME;
76 
77     fget_next_char( fileread );
78     pmod->rtscontrol = bfalse;        //< depecrated, not in use
79 
80     fget_next_string( fileread, pmod->rank, SDL_arraysize( pmod->rank ) );
81     str_trim( pmod->rank );
82 
83     // convert the special ranks of "unranked" or "-" ("rank 0") to an empty string
84     if ( 0 == strncmp( pmod->rank, "-", RANKSIZE ) )
85     {
86         pmod->rank[0] = CSTR_END;
87     }
88     else if ( 'U' == toupper( pmod->rank[0] ) )
89     {
90         pmod->rank[0] = CSTR_END;
91     }
92     pmod->rank[RANKSIZE-1] = CSTR_END;
93 
94     // Read the summary
95     for ( cnt = 0; cnt < SUMMARYLINES; cnt++ )
96     {
97         // load the string
98         fget_next_string( fileread,  pmod->summary[cnt], SDL_arraysize( pmod->summary[cnt] ) );
99         pmod->summary[cnt][SUMMARYSIZE-1] = CSTR_END;
100 
101         // remove the '_' characters
102         str_decode( pmod->summary[cnt], SDL_arraysize( pmod->summary[cnt] ), pmod->summary[cnt] );
103     }
104 
105     // Assume default module type as a sidequest
106     pmod->moduletype = FILTER_SIDE;
107 
108     // Read expansions
109     while ( goto_colon( NULL, fileread, btrue ) )
110     {
111         IDSZ idsz = fget_idsz( fileread );
112 
113         // Read module type
114         if ( idsz == MAKE_IDSZ( 'T', 'Y', 'P', 'E' ) )
115         {
116             // grab the expansion value
117             cTmp = fget_first_letter( fileread );
118 
119             // parse the expansion value
120             if ( 'M' == toupper( cTmp ) )  pmod->moduletype = FILTER_MAIN;
121             else if ( 'S' == toupper( cTmp ) )  pmod->moduletype = FILTER_SIDE;
122             else if ( 'T' == toupper( cTmp ) )  pmod->moduletype = FILTER_TOWN;
123             else if ( 'F' == toupper( cTmp ) )  pmod->moduletype = FILTER_FUN;
124             else if ( 'S' == toupper( cTmp ) )  pmod->moduletype = FILTER_STARTER;
125         }
126         else if ( idsz == MAKE_IDSZ( 'B', 'E', 'A', 'T' ) )
127         {
128             pmod->beaten = btrue;
129         }
130     }
131 
132     vfs_close( fileread );
133 
134     return pmod;
135 }
136 
137 //--------------------------------------------------------------------------------------------
module_has_idsz_vfs(const char * szModName,IDSZ idsz,size_t buffer_len,char * buffer)138 int module_has_idsz_vfs( const char *szModName, IDSZ idsz, size_t buffer_len, char * buffer )
139 {
140     /// @details ZZ@> This function returns btrue if the named module has the required IDSZ
141 
142     vfs_FILE *fileread;
143     STRING newloadname;
144     Uint32 newidsz;
145     int foundidsz;
146     int cnt;
147 
148     if ( idsz == IDSZ_NONE ) return btrue;
149 
150     if ( 0 == strcmp( szModName, "NONE" ) ) return bfalse;
151 
152     snprintf( newloadname, SDL_arraysize( newloadname ), "mp_modules/%s/gamedat/menu.txt", szModName );
153 
154     fileread = vfs_openRead( newloadname );
155     if ( NULL == fileread ) return bfalse;
156 
157     // Read basic data
158     goto_colon( NULL, fileread, bfalse );  // Name of module...  Doesn't matter
159     goto_colon( NULL, fileread, bfalse );  // Reference directory...
160     goto_colon( NULL, fileread, bfalse );  // Reference IDSZ...
161     goto_colon( NULL, fileread, bfalse );  // Import...
162     goto_colon( NULL, fileread, bfalse );  // Export...
163     goto_colon( NULL, fileread, bfalse );  // Min players...
164     goto_colon( NULL, fileread, bfalse );  // Max players...
165     goto_colon( NULL, fileread, bfalse );  // Respawn...
166     goto_colon( NULL, fileread, bfalse );  // BAD! NOT USED
167     goto_colon( NULL, fileread, bfalse );  // Rank...
168 
169     // Summary...
170     for ( cnt = 0; cnt < SUMMARYLINES; cnt++ )
171     {
172         goto_colon( NULL, fileread, bfalse );
173     }
174 
175     // Now check expansions
176     foundidsz = bfalse;
177     while ( goto_colon( NULL, fileread, btrue ) )
178     {
179         newidsz = fget_idsz( fileread );
180         if ( newidsz == idsz )
181         {
182             foundidsz = btrue;
183             break;
184         }
185     }
186 
187     if ( NULL != buffer )
188     {
189         if ( buffer_len < 1 )
190         {
191             /* nothing */
192         }
193         else if ( 1 == buffer_len )
194         {
195             buffer[0] = CSTR_END;
196         }
197         else
198         {
199             vfs_gets( buffer, buffer_len, fileread );
200         }
201     }
202 
203     vfs_close( fileread );
204 
205     return foundidsz;
206 }
207 
208 //--------------------------------------------------------------------------------------------
module_add_idsz_vfs(const char * szModName,IDSZ idsz,size_t buffer_len,const char * buffer)209 void module_add_idsz_vfs( const char *szModName, IDSZ idsz, size_t buffer_len, const char * buffer )
210 {
211     /// @details ZZ@> This function appends an IDSZ to the module's menu.txt file
212     vfs_FILE *filewrite;
213 
214     // Only add if there isn't one already
215     if ( !module_has_idsz_vfs( szModName, idsz, 0, NULL ) )
216     {
217         STRING src_file, dst_file;
218 
219         // make sure that the file exists in the user data directory since we are WRITING to it
220         snprintf( src_file, SDL_arraysize( src_file ), "mp_modules/%s/gamedat/menu.txt", szModName );
221         snprintf( dst_file, SDL_arraysize( dst_file ), "/modules/%s/gamedat/menu.txt", szModName );
222         vfs_copyFile( src_file, dst_file );
223 
224         // Try to open the file in append mode
225         filewrite = vfs_openAppend( dst_file );
226         if ( filewrite )
227         {
228             // output the expansion IDSZ
229             vfs_printf( filewrite, "\n:[%s]", undo_idsz( idsz ) );
230 
231             // output an optional parameter
232             if ( NULL != buffer && buffer_len > 1 )
233             {
234                 vfs_printf( filewrite, " %s", undo_idsz( idsz ) );
235             }
236 
237             // end the line
238             vfs_printf( filewrite, "\n" );
239 
240             // invalidate any module list so that we will reload them
241             module_list_valid = bfalse;
242 
243             // close the file
244             vfs_close( filewrite );
245         }
246     }
247 }
248