ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.6
Committed: Thu Sep 7 09:37:11 2006 UTC (17 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.5: +6 -5 lines
Log Message:
Cleaned up code a little.

File Contents

# User Rev Content
1 elmex 1.1 /*
2     * static char *rcsid_init_c =
3 pippijn 1.6 * "$Id: init.C,v 1.5 2006-09-04 11:07:59 root Exp $";
4 elmex 1.1 */
5    
6     /*
7     CrossFire, A Multiplayer game for X-windows
8    
9     Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10     Copyright (C) 1992 Frank Tore Johansen
11    
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; either version 2 of the License, or
15     (at your option) any later version.
16    
17     This program is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20     GNU General Public License for more details.
21    
22     You should have received a copy of the GNU General Public License
23     along with this program; if not, write to the Free Software
24     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25    
26     The authors can be reached via e-mail at crossfire-devel@real-time.com
27     */
28    
29     #define EXTERN
30     #define INIT_C
31     #include <global.h>
32     #include <object.h>
33    
34     /* You unforunately need to looking in include/global.h to see what these
35     * correspond to.
36     */
37     struct Settings settings = {
38     LOGFILE, /* Logfile */
39     CSPORT, /* Client/server port */
40    
41     /* Debug level */
42     #ifdef DEBUG
43     llevDebug,
44     #else
45     llevInfo,
46     #endif
47    
48     0, NULL, 0, /* dumpvalues, dumparg, daemonmode */
49     0, /* argc */
50     NULL, /* argv */
51     CONFDIR,
52     DATADIR,
53     LOCALDIR,
54     PLAYERDIR, MAPDIR, ARCHETYPES,REGIONS,TREASURES,
55     UNIQUE_DIR, TEMPLATE_DIR,
56     TMPDIR,
57     STAT_LOSS_ON_DEATH,
58     PK_LUCK_PENALTY,
59     PERMANENT_EXPERIENCE_RATIO,
60     DEATH_PENALTY_RATIO,
61     DEATH_PENALTY_LEVEL,
62     BALANCED_STAT_LOSS,
63     NOT_PERMADETH,
64     SIMPLE_EXP,
65     RESET_LOCATION_TIME,
66     SET_TITLE,
67     RESURRECTION,
68     SEARCH_ITEMS,
69     SPELL_ENCUMBRANCE,
70     SPELL_FAILURE_EFFECTS,
71     CASTING_TIME,
72     REAL_WIZ,
73     RECYCLE_TMP_MAPS,
74     EXPLORE_MODE,
75     SPELLPOINT_LEVEL_DEPEND,
76     SET_FRIENDLY_FIRE,
77     "", /* Who format specifier */
78     "", /* who wiz format specifier */
79     MOTD,
80     "rules",
81     "news",
82     "", /* DM_MAIL */
83     0, /* This and the next 3 values are metaserver values */
84     "",
85     "",
86     0,
87     "",
88     0,0,0,0,0,0,0,0, /* worldmap settings*/
89     EMERGENCY_MAPPATH, EMERGENCY_X, EMERGENCY_Y,
90     0,
91     1.0,
92     /* Armor enchantment stuff */
93     ARMOR_MAX_ENCHANT,
94     ARMOR_WEIGHT_REDUCTION,
95     ARMOR_WEIGHT_LINEAR,
96     ARMOR_SPEED_IMPROVEMENT,
97     ARMOR_SPEED_LINEAR,
98     1, /* no_player_stealing */
99     1, /* create_home_portals */
100     };
101    
102     /* perhaps not the best place for this, but needs to be
103     * in some file in the common area so that standalone
104     * programs, like the random map generator, can be built.
105     */
106     const char* const spellpathnames[NRSPELLPATHS] = {
107     "Protection",
108     "Fire",
109     "Frost",
110     "Electricity",
111     "Missiles",
112     "Self",
113     "Summoning",
114     "Abjuration",
115     "Restoration",
116     "Detonation",
117     "Mind",
118     "Creation",
119     "Teleportation",
120     "Information",
121     "Transmutation",
122     "Transferrence",
123     "Turning",
124     "Wounding",
125     "Death",
126     "Light"
127     };
128    
129    
130     /* This loads the emergency map information from a
131     * .emergency file in the map directory. Doing this makes
132     * it easier to switch between map distributions (don't need
133     * to recompile. Note that there is no reason I see that
134     * this could not be re-loaded during play, but it seems
135     * like there should be little reason to do that.
136     */
137     static void init_emergency_mappath(void)
138     {
139     char filename[MAX_BUF], tmpbuf[MAX_BUF];
140     FILE *fp;
141     int online=0;
142    
143     /* If this file doesn't exist, not a big deal */
144     sprintf(filename,"%s/%s/.emergency",settings.datadir, settings.mapdir);
145     if ((fp = fopen(filename, "r"))!=NULL) {
146 root 1.2 while (fgets(tmpbuf, MAX_BUF-1, fp)) {
147     if (tmpbuf[0] == '#') continue; /* ignore comments */
148    
149     if (online == 0) {
150     tmpbuf[strlen(tmpbuf)-1] = 0; /* kill newline */
151     settings.emergency_mapname = strdup_local(tmpbuf);
152     }
153     else if (online == 1) {
154     settings.emergency_x = atoi(tmpbuf);
155     }
156    
157     else if (online == 2) {
158     settings.emergency_y = atoi(tmpbuf);
159     }
160     online++;
161     if (online>2) break;
162     }
163     fclose(fp);
164     if (online<=2)
165     LOG(llevError,"Online read partial data from %s\n", filename);
166     LOG(llevDebug,"Emergency mappath reset to %s (%d, %d)\n", settings.emergency_mapname,
167     settings.emergency_x, settings.emergency_y);
168 elmex 1.1 }
169     }
170    
171    
172     /*
173     * It is vital that init_library() is called by any functions
174     * using this library.
175     * If you want to lessen the size of the program using the library,
176     * you can replace the call to init_library() with init_globals() and
177     * init_function_pointers(). Good idea to also call init_vars and
178     * init_hash_table if you are doing any object loading.
179     */
180    
181     void init_library(void) {
182     init_environ();
183     init_globals();
184     init_objects();
185     init_vars();
186     init_block();
187     ReadBmapNames ();
188     ReadSmooth();
189     init_anim(); /* Must be after we read in the bitmaps */
190     init_archetypes(); /* Reads all archetypes from file */
191     init_dynamic ();
192     init_attackmess();
193     init_clocks();
194     init_emergency_mappath();
195     init_experience();
196     }
197    
198    
199     /* init_environ initializes values from the environmental variables.
200     * it needs to be called very early, since command line options should
201     * overwrite these if specified.
202     */
203     void init_environ(void) {
204     char *cp;
205    
206     cp=getenv("CROSSFIRE_LIBDIR");
207     if (cp) settings.datadir=cp;
208     cp=getenv("CROSSFIRE_LOCALDIR");
209     if (cp) settings.localdir=cp;
210     cp=getenv("CROSSFIRE_PLAYERDIR");
211     if (cp) settings.playerdir=cp;
212     cp=getenv("CROSSFIRE_MAPDIR");
213     if (cp) settings.mapdir=cp;
214     cp=getenv("CROSSFIRE_ARCHETYPES");
215     if (cp) settings.archetypes=cp;
216     cp=getenv("CROSSFIRE_TREASURES");
217     if (cp) settings.treasures=cp;
218     cp=getenv("CROSSFIRE_UNIQUEDIR");
219     if (cp) settings.uniquedir=cp;
220     cp=getenv("CROSSFIRE_TEMPLATEDIR");
221     if (cp) settings.templatedir=cp;
222     cp=getenv("CROSSFIRE_TMPDIR");
223     if (cp) settings.tmpdir=cp;
224     }
225    
226    
227     /*
228     * Initialises all global variables.
229     * Might use environment-variables as default for some of them.
230     */
231    
232     void init_globals(void) {
233     if (settings.logfilename[0] == 0) {
234 root 1.2 logfile = stderr;
235 elmex 1.1 }
236     else if ((logfile=fopen(settings.logfilename, "a"))==NULL) {
237 root 1.2 fprintf(stderr,"Unable to open %s as the logfile - will use stderr instead\n",
238     settings.logfilename);
239     logfile = stderr;
240 elmex 1.1 }
241     else {
242 root 1.2 setvbuf(logfile, NULL, _IOLBF, 0);
243 elmex 1.1 }
244     exiting = 0;
245     first_player=NULL;
246     first_friendly_object=NULL;
247     first_map=NULL;
248     first_treasurelist=NULL;
249     first_artifactlist=NULL;
250     first_archetype=NULL;
251     *first_map_ext_path=0;
252     warn_archetypes=0;
253     nroftreasures = 0;
254     nrofartifacts = 0;
255     nrofallowedstr=0;
256     ring_arch = NULL;
257     amulet_arch = NULL;
258     staff_arch = NULL;
259     trying_emergency_save = 0;
260     num_animations=0;
261     animations_allocated=0;
262     init_defaults();
263     }
264    
265     /*
266     * Sets up and initialises the linked list of free and used objects.
267     * Allocates a certain chunk of objects and puts them on the free list.
268     * Called by init_library();
269     */
270    
271 pippijn 1.6 void
272     init_objects(void)
273     {
274     /* Initialize all objects: */
275     objects = NULL;
276 elmex 1.1 active_objects = NULL;
277     }
278    
279     /*
280     * Initialises global variables which can be changed by options.
281     * Called by init_library().
282     */
283    
284     void init_defaults(void) {
285     editor=0;
286     nroferrors=0;
287     }
288    
289    
290     void init_dynamic (void) {
291     archetype *at = first_archetype;
292     while (at) {
293 root 1.2 if (at->clone.type == MAP) {
294 elmex 1.1 if (at->clone.race) {
295     strcpy (first_map_ext_path, at->clone.race);
296     }
297     if (EXIT_PATH (&at->clone)) {
298     strcpy (first_map_path, EXIT_PATH (&at->clone));
299     return;
300     }
301 root 1.2 }
302     at = at->next;
303 elmex 1.1 }
304     LOG(llevDebug,"You Need a archetype called 'map' and it have to contain start map\n");
305     exit (-1);
306     }
307    
308     unsigned long todtick;
309    
310     /*
311     * Write out the current time to the file so time does not
312     * reset every time the server reboots.
313     */
314    
315     void write_todclock(void)
316     {
317     char filename[MAX_BUF];
318     FILE *fp;
319    
320     sprintf(filename, "%s/clockdata", settings.localdir);
321     if ((fp = fopen(filename, "w")) == NULL) {
322 root 1.2 LOG(llevError, "Cannot open %s for writing\n", filename);
323     return;
324 elmex 1.1 }
325     fprintf(fp, "%lu", todtick);
326     fclose(fp);
327     }
328    
329     /*
330     * Initializes the gametime and TOD counters
331     * Called by init_library().
332     */
333    
334     void init_clocks(void)
335     {
336     char filename[MAX_BUF];
337     FILE *fp;
338     static int has_been_done=0;
339    
340     if (has_been_done)
341     return;
342     else
343     has_been_done = 1;
344    
345     sprintf(filename, "%s/clockdata", settings.localdir);
346     LOG(llevDebug, "Reading clockdata from %s...", filename);
347     if ((fp = fopen(filename, "r")) == NULL) {
348     LOG(llevError, "Can't open %s.\n", filename);
349 root 1.2 todtick = 0;
350     write_todclock();
351     return;
352 elmex 1.1 }
353     fscanf(fp, "%lu", &todtick);
354     LOG(llevDebug, "todtick=%lu\n", todtick);
355     fclose(fp);
356     }
357    
358     /*
359     * Initializes the attack messages.
360     * Called by init_library().
361     */
362    
363     //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
364    
365     void init_attackmess(void){
366     char buf[MAX_BUF];
367     char filename[MAX_BUF];
368     char *cp, *p;
369     FILE *fp;
370     static int has_been_done=0;
371     int mess, level, comp;
372     int mode=0, total=0;
373    
374     if (has_been_done)
375     return;
376     else
377     has_been_done = 1;
378    
379     sprintf(filename, "%s/attackmess", settings.datadir);
380     LOG(llevDebug, "Reading attack messages from %s...", filename);
381     if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) {
382     LOG(llevError, "Can't open %s.\n", filename);
383 root 1.2 return;
384 elmex 1.1 }
385    
386     level = 0;
387     while (fgets(buf, MAX_BUF, fp)!=NULL) {
388     if (*buf=='#') continue;
389 root 1.2 if((cp=strchr(buf,'\n'))!=NULL)
390 elmex 1.1 *cp='\0';
391 root 1.2 cp=buf;
392     while(*cp==' ') /* Skip blanks */
393     cp++;
394    
395     if (strncmp(cp, "TYPE:", 5)==0) {
396     p = strtok(buf, ":");
397     p = strtok(NULL, ":");
398     if (mode == 1) {
399     attack_mess[mess][level].level = -1;
400     attack_mess[mess][level].buf1 = NULL;
401     attack_mess[mess][level].buf2 = NULL;
402     attack_mess[mess][level].buf3 = NULL;
403     }
404     level = 0;
405     mess = atoi(p);
406     mode = 1;
407     continue;
408     }
409     if (mode==1) {
410     p = strtok(buf, "=");
411     attack_mess[mess][level].level = atoi(buf);
412     p = strtok(NULL, "=");
413     if (p != NULL)
414     attack_mess[mess][level].buf1 = strdup_local(p);
415     else
416     attack_mess[mess][level].buf1 = strdup_local("");
417     mode = 2;
418     continue;
419     } else if (mode==2) {
420     p = strtok(buf, "=");
421     attack_mess[mess][level].level = atoi(buf);
422     p = strtok(NULL, "=");
423     if (p != NULL)
424     attack_mess[mess][level].buf2 = strdup_local(p);
425     else
426     attack_mess[mess][level].buf2 = strdup_local("");
427     mode = 3;
428     continue;
429     } else if (mode==3) {
430     p = strtok(buf, "=");
431     attack_mess[mess][level].level = atoi(buf);
432     p = strtok(NULL, "=");
433     if (p != NULL)
434     attack_mess[mess][level].buf3 = strdup_local(p);
435     else
436     attack_mess[mess][level].buf3 = strdup_local("");
437     mode = 1;
438     level++;
439     total++;
440     continue;
441     }
442 elmex 1.1 }
443     LOG(llevDebug, "got %d messages in %d categories.\n", total, mess+1);
444     close_and_delete(fp, comp);
445     }