ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.c
Revision: 1.1.1.3 (vendor branch)
Committed: Wed Mar 15 14:04:36 2006 UTC (18 years, 2 months ago) by elmex
Content type: text/plain
Branch: UPSTREAM
CVS Tags: UPSTREAM_2006_03_15
Changes since 1.1.1.2: +4 -2 lines
Log Message:
cvs -z9 -d:ext:elmex@cvs.schmorp.de:/schmorpforge import cf.schmorp.de UPSTREAM UPSTREAM_2006_03_15

File Contents

# User Rev Content
1 root 1.1 /*
2     * static char *rcsid_init_c =
3 elmex 1.1.1.3 * "$Id: init.c,v 1.48 2006/03/07 18:46:21 cavesomething Exp $";
4 root 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 elmex 1.1.1.3 PERMANENT_EXPERIENCE_RATIO,
60     DEATH_PENALTY_RATIO,
61     DEATH_PENALTY_LEVEL,
62 root 1.1 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     };
100    
101     /* perhaps not the best place for this, but needs to be
102     * in some file in the common area so that standalone
103     * programs, like the random map generator, can be built.
104     */
105 elmex 1.1.1.2 const char* const spellpathnames[NRSPELLPATHS] = {
106 root 1.1 "Protection",
107     "Fire",
108     "Frost",
109     "Electricity",
110     "Missiles",
111     "Self",
112     "Summoning",
113     "Abjuration",
114     "Restoration",
115     "Detonation",
116     "Mind",
117     "Creation",
118     "Teleportation",
119     "Information",
120     "Transmutation",
121     "Transferrence",
122     "Turning",
123     "Wounding",
124     "Death",
125     "Light"
126     };
127    
128    
129     /* This loads the emergency map information from a
130     * .emergency file in the map directory. Doing this makes
131     * it easier to switch between map distributions (don't need
132     * to recompile. Note that there is no reason I see that
133     * this could not be re-loaded during play, but it seems
134     * like there should be little reason to do that.
135     */
136     static void init_emergency_mappath(void)
137     {
138     char filename[MAX_BUF], tmpbuf[MAX_BUF];
139     FILE *fp;
140     int online=0;
141    
142     /* If this file doesn't exist, not a big deal */
143     sprintf(filename,"%s/%s/.emergency",settings.datadir, settings.mapdir);
144     if ((fp = fopen(filename, "r"))!=NULL) {
145     while (fgets(tmpbuf, MAX_BUF-1, fp)) {
146     if (tmpbuf[0] == '#') continue; /* ignore comments */
147    
148     if (online == 0) {
149     tmpbuf[strlen(tmpbuf)-1] = 0; /* kill newline */
150     settings.emergency_mapname = strdup_local(tmpbuf);
151     }
152     else if (online == 1) {
153     settings.emergency_x = atoi(tmpbuf);
154     }
155    
156     else if (online == 2) {
157     settings.emergency_y = atoi(tmpbuf);
158     }
159     online++;
160     if (online>2) break;
161     }
162     fclose(fp);
163     if (online<=2)
164     LOG(llevError,"Online read partial data from %s\n", filename);
165     LOG(llevDebug,"Emergency mappath reset to %s (%d, %d)\n", settings.emergency_mapname,
166     settings.emergency_x, settings.emergency_y);
167     }
168     }
169    
170    
171     /*
172     * It is vital that init_library() is called by any functions
173     * using this library.
174     * If you want to lessen the size of the program using the library,
175     * you can replace the call to init_library() with init_globals() and
176     * init_function_pointers(). Good idea to also call init_vars and
177     * init_hash_table if you are doing any object loading.
178     */
179    
180     void init_library(void) {
181     init_environ();
182     init_globals();
183     init_hash_table();
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     logfile = stderr;
235     }
236     else if ((logfile=fopen(settings.logfilename, "a"))==NULL) {
237     fprintf(stderr,"Unable to open %s as the logfile - will use stderr instead\n",
238     settings.logfilename);
239     logfile = stderr;
240     }
241 elmex 1.1.1.2 else {
242     setvbuf(logfile, NULL, _IOLBF, 0);
243     }
244 root 1.1 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     warn_archetypes=0;
252     first_map=NULL;
253     nroftreasures = 0;
254     nrofartifacts = 0;
255     nrofallowedstr=0;
256     ring_arch = NULL;
257     amulet_arch = NULL;
258     staff_arch = NULL;
259     undead_name = add_string("undead");
260     trying_emergency_save = 0;
261     num_animations=0;
262     animations=NULL;
263     animations_allocated=0;
264     init_defaults();
265     }
266    
267     /*
268     * Sets up and initialises the linked list of free and used objects.
269     * Allocates a certain chunk of objects and puts them on the free list.
270     * Called by init_library();
271     */
272    
273     void init_objects(void) {
274     int i;
275     /* Initialize all objects: */
276     objects=NULL;
277     active_objects = NULL;
278    
279     #ifdef MEMORY_DEBUG
280     free_objects=NULL;
281     #else
282     free_objects=objarray;
283     objarray[0].prev=NULL,
284     objarray[0].next= &objarray[1],
285     SET_FLAG(&objarray[0], FLAG_REMOVED);
286     SET_FLAG(&objarray[0], FLAG_FREED);
287     for(i=1;i<STARTMAX-1;i++) {
288     objarray[i].next= &objarray[i+1];
289     objarray[i].prev= &objarray[i-1];
290     SET_FLAG(&objarray[i], FLAG_REMOVED);
291     SET_FLAG(&objarray[i], FLAG_FREED);
292     }
293     objarray[STARTMAX-1].next=NULL;
294     objarray[STARTMAX-1].prev= &objarray[STARTMAX-2];
295     SET_FLAG(&objarray[STARTMAX-1], FLAG_REMOVED);
296     SET_FLAG(&objarray[STARTMAX-1], FLAG_FREED);
297     #endif
298     }
299    
300     /*
301     * Initialises global variables which can be changed by options.
302     * Called by init_library().
303     */
304    
305     void init_defaults(void) {
306     editor=0;
307     nroferrors=0;
308     }
309    
310    
311     void init_dynamic (void) {
312     archetype *at = first_archetype;
313     while (at) {
314     if (at->clone.type == MAP && EXIT_PATH (&at->clone)) {
315     strcpy (first_map_path, EXIT_PATH (&at->clone));
316     return;
317     }
318     at = at->next;
319     }
320     LOG(llevDebug,"You Need a archetype called 'map' and it have to contain start map\n");
321     exit (-1);
322     }
323    
324     unsigned long todtick;
325    
326     /*
327     * Write out the current time to the file so time does not
328     * reset every time the server reboots.
329     */
330    
331     void write_todclock(void)
332     {
333     char filename[MAX_BUF];
334     FILE *fp;
335    
336     sprintf(filename, "%s/clockdata", settings.localdir);
337     if ((fp = fopen(filename, "w")) == NULL) {
338     LOG(llevError, "Cannot open %s for writing\n", filename);
339     return;
340     }
341     fprintf(fp, "%lu", todtick);
342     fclose(fp);
343     }
344    
345     /*
346     * Initializes the gametime and TOD counters
347     * Called by init_library().
348     */
349    
350     void init_clocks(void)
351     {
352     char filename[MAX_BUF];
353     FILE *fp;
354     static int has_been_done=0;
355    
356     if (has_been_done)
357     return;
358     else
359     has_been_done = 1;
360    
361     sprintf(filename, "%s/clockdata", settings.localdir);
362     LOG(llevDebug, "Reading clockdata from %s...", filename);
363     if ((fp = fopen(filename, "r")) == NULL) {
364     LOG(llevError, "Can't open %s.\n", filename);
365     todtick = 0;
366     write_todclock();
367     return;
368     }
369     fscanf(fp, "%lu", &todtick);
370     LOG(llevDebug, "todtick=%lu\n", todtick);
371     fclose(fp);
372     }
373    
374     /*
375     * Initializes the attack messages.
376     * Called by init_library().
377     */
378    
379     attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
380    
381     void init_attackmess(void){
382     char buf[MAX_BUF];
383     char filename[MAX_BUF];
384     char *cp, *p;
385     FILE *fp;
386     static int has_been_done=0;
387     int mess, level, comp;
388     int mode=0, total=0;
389    
390     if (has_been_done)
391     return;
392     else
393     has_been_done = 1;
394    
395     sprintf(filename, "%s/attackmess", settings.datadir);
396     LOG(llevDebug, "Reading attack messages from %s...", filename);
397     if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) {
398     LOG(llevError, "Can't open %s.\n", filename);
399     return;
400     }
401    
402     level = 0;
403     while (fgets(buf, MAX_BUF, fp)!=NULL) {
404     if (*buf=='#') continue;
405     if((cp=strchr(buf,'\n'))!=NULL)
406     *cp='\0';
407     cp=buf;
408     while(*cp==' ') /* Skip blanks */
409     cp++;
410    
411     if (strncmp(cp, "TYPE:", 5)==0) {
412     p = strtok(buf, ":");
413     p = strtok(NULL, ":");
414     if (mode == 1) {
415     attack_mess[mess][level].level = -1;
416     attack_mess[mess][level].buf1 = NULL;
417     attack_mess[mess][level].buf2 = NULL;
418     attack_mess[mess][level].buf3 = NULL;
419     }
420     level = 0;
421     mess = atoi(p);
422     mode = 1;
423     continue;
424     }
425     if (mode==1) {
426     p = strtok(buf, "=");
427     attack_mess[mess][level].level = atoi(buf);
428     p = strtok(NULL, "=");
429     if (p != NULL)
430     attack_mess[mess][level].buf1 = strdup_local(p);
431     else
432     attack_mess[mess][level].buf1 = strdup_local("");
433     mode = 2;
434     continue;
435     } else if (mode==2) {
436     p = strtok(buf, "=");
437     attack_mess[mess][level].level = atoi(buf);
438     p = strtok(NULL, "=");
439     if (p != NULL)
440     attack_mess[mess][level].buf2 = strdup_local(p);
441     else
442     attack_mess[mess][level].buf2 = strdup_local("");
443     mode = 3;
444     continue;
445     } else if (mode==3) {
446     p = strtok(buf, "=");
447     attack_mess[mess][level].level = atoi(buf);
448     p = strtok(NULL, "=");
449     if (p != NULL)
450     attack_mess[mess][level].buf3 = strdup_local(p);
451     else
452     attack_mess[mess][level].buf3 = strdup_local("");
453     mode = 1;
454     level++;
455     total++;
456     continue;
457     }
458     }
459     LOG(llevDebug, "got %d messages in %d categories.\n", total, mess+1);
460     close_and_delete(fp, comp);
461     }