ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.4
Committed: Sun Sep 3 07:57:54 2006 UTC (17 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.3: +1 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 elmex 1.1 /*
2     * static char *rcsid_init_c =
3 root 1.4 * "$Id: init.C,v 1.3 2006-09-03 00:18:39 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     void init_objects(void) {
272     int i;
273     /* Initialize all objects: */
274     objects=NULL;
275     active_objects = NULL;
276    
277     #ifdef MEMORY_DEBUG
278     free_objects=NULL;
279     #else
280     free_objects=objarray;
281     objarray[0].prev=NULL,
282     objarray[0].next= &objarray[1],
283     SET_FLAG(&objarray[0], FLAG_REMOVED);
284     SET_FLAG(&objarray[0], FLAG_FREED);
285     for(i=1;i<STARTMAX-1;i++) {
286     objarray[i].next= &objarray[i+1];
287     objarray[i].prev= &objarray[i-1];
288     SET_FLAG(&objarray[i], FLAG_REMOVED);
289     SET_FLAG(&objarray[i], FLAG_FREED);
290     }
291     objarray[STARTMAX-1].next=NULL;
292     objarray[STARTMAX-1].prev= &objarray[STARTMAX-2];
293     SET_FLAG(&objarray[STARTMAX-1], FLAG_REMOVED);
294     SET_FLAG(&objarray[STARTMAX-1], FLAG_FREED);
295     #endif
296     }
297    
298     /*
299     * Initialises global variables which can be changed by options.
300     * Called by init_library().
301     */
302    
303     void init_defaults(void) {
304     editor=0;
305     nroferrors=0;
306     }
307    
308    
309     void init_dynamic (void) {
310     archetype *at = first_archetype;
311     while (at) {
312 root 1.2 if (at->clone.type == MAP) {
313 elmex 1.1 if (at->clone.race) {
314     strcpy (first_map_ext_path, at->clone.race);
315     }
316     if (EXIT_PATH (&at->clone)) {
317     strcpy (first_map_path, EXIT_PATH (&at->clone));
318     return;
319     }
320 root 1.2 }
321     at = at->next;
322 elmex 1.1 }
323     LOG(llevDebug,"You Need a archetype called 'map' and it have to contain start map\n");
324     exit (-1);
325     }
326    
327     unsigned long todtick;
328    
329     /*
330     * Write out the current time to the file so time does not
331     * reset every time the server reboots.
332     */
333    
334     void write_todclock(void)
335     {
336     char filename[MAX_BUF];
337     FILE *fp;
338    
339     sprintf(filename, "%s/clockdata", settings.localdir);
340     if ((fp = fopen(filename, "w")) == NULL) {
341 root 1.2 LOG(llevError, "Cannot open %s for writing\n", filename);
342     return;
343 elmex 1.1 }
344     fprintf(fp, "%lu", todtick);
345     fclose(fp);
346     }
347    
348     /*
349     * Initializes the gametime and TOD counters
350     * Called by init_library().
351     */
352    
353     void init_clocks(void)
354     {
355     char filename[MAX_BUF];
356     FILE *fp;
357     static int has_been_done=0;
358    
359     if (has_been_done)
360     return;
361     else
362     has_been_done = 1;
363    
364     sprintf(filename, "%s/clockdata", settings.localdir);
365     LOG(llevDebug, "Reading clockdata from %s...", filename);
366     if ((fp = fopen(filename, "r")) == NULL) {
367     LOG(llevError, "Can't open %s.\n", filename);
368 root 1.2 todtick = 0;
369     write_todclock();
370     return;
371 elmex 1.1 }
372     fscanf(fp, "%lu", &todtick);
373     LOG(llevDebug, "todtick=%lu\n", todtick);
374     fclose(fp);
375     }
376    
377     /*
378     * Initializes the attack messages.
379     * Called by init_library().
380     */
381    
382     //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
383    
384     void init_attackmess(void){
385     char buf[MAX_BUF];
386     char filename[MAX_BUF];
387     char *cp, *p;
388     FILE *fp;
389     static int has_been_done=0;
390     int mess, level, comp;
391     int mode=0, total=0;
392    
393     if (has_been_done)
394     return;
395     else
396     has_been_done = 1;
397    
398     sprintf(filename, "%s/attackmess", settings.datadir);
399     LOG(llevDebug, "Reading attack messages from %s...", filename);
400     if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) {
401     LOG(llevError, "Can't open %s.\n", filename);
402 root 1.2 return;
403 elmex 1.1 }
404    
405     level = 0;
406     while (fgets(buf, MAX_BUF, fp)!=NULL) {
407     if (*buf=='#') continue;
408 root 1.2 if((cp=strchr(buf,'\n'))!=NULL)
409 elmex 1.1 *cp='\0';
410 root 1.2 cp=buf;
411     while(*cp==' ') /* Skip blanks */
412     cp++;
413    
414     if (strncmp(cp, "TYPE:", 5)==0) {
415     p = strtok(buf, ":");
416     p = strtok(NULL, ":");
417     if (mode == 1) {
418     attack_mess[mess][level].level = -1;
419     attack_mess[mess][level].buf1 = NULL;
420     attack_mess[mess][level].buf2 = NULL;
421     attack_mess[mess][level].buf3 = NULL;
422     }
423     level = 0;
424     mess = atoi(p);
425     mode = 1;
426     continue;
427     }
428     if (mode==1) {
429     p = strtok(buf, "=");
430     attack_mess[mess][level].level = atoi(buf);
431     p = strtok(NULL, "=");
432     if (p != NULL)
433     attack_mess[mess][level].buf1 = strdup_local(p);
434     else
435     attack_mess[mess][level].buf1 = strdup_local("");
436     mode = 2;
437     continue;
438     } else if (mode==2) {
439     p = strtok(buf, "=");
440     attack_mess[mess][level].level = atoi(buf);
441     p = strtok(NULL, "=");
442     if (p != NULL)
443     attack_mess[mess][level].buf2 = strdup_local(p);
444     else
445     attack_mess[mess][level].buf2 = strdup_local("");
446     mode = 3;
447     continue;
448     } else if (mode==3) {
449     p = strtok(buf, "=");
450     attack_mess[mess][level].level = atoi(buf);
451     p = strtok(NULL, "=");
452     if (p != NULL)
453     attack_mess[mess][level].buf3 = strdup_local(p);
454     else
455     attack_mess[mess][level].buf3 = strdup_local("");
456     mode = 1;
457     level++;
458     total++;
459     continue;
460     }
461 elmex 1.1 }
462     LOG(llevDebug, "got %d messages in %d categories.\n", total, mess+1);
463     close_and_delete(fp, comp);
464     }