ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.c
Revision: 1.3
Committed: Wed Feb 22 18:53:48 2006 UTC (18 years, 3 months ago) by elmex
Content type: text/plain
Branch: MAIN
Changes since 1.2: +5 -3 lines
Log Message:
UPSTREAM_2006-02-22 merge

File Contents

# User Rev Content
1 root 1.1 /*
2     * static char *rcsid_init_c =
3 elmex 1.3 * "$Id$";
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     USE_PERMANENT_EXPERIENCE,
60     BALANCED_STAT_LOSS,
61     NOT_PERMADETH,
62     SIMPLE_EXP,
63     RESET_LOCATION_TIME,
64     SET_TITLE,
65     RESURRECTION,
66     SEARCH_ITEMS,
67     SPELL_ENCUMBRANCE,
68     SPELL_FAILURE_EFFECTS,
69     CASTING_TIME,
70     REAL_WIZ,
71     RECYCLE_TMP_MAPS,
72     EXPLORE_MODE,
73     SPELLPOINT_LEVEL_DEPEND,
74     SET_FRIENDLY_FIRE,
75     "", /* Who format specifier */
76     "", /* who wiz format specifier */
77     MOTD,
78     "rules",
79     "news",
80     "", /* DM_MAIL */
81     0, /* This and the next 3 values are metaserver values */
82     "",
83     "",
84     0,
85     "",
86     0,0,0,0,0,0,0,0, /* worldmap settings*/
87     EMERGENCY_MAPPATH, EMERGENCY_X, EMERGENCY_Y,
88     0,
89     1.0,
90     /* Armor enchantment stuff */
91     ARMOR_MAX_ENCHANT,
92     ARMOR_WEIGHT_REDUCTION,
93     ARMOR_WEIGHT_LINEAR,
94     ARMOR_SPEED_IMPROVEMENT,
95     ARMOR_SPEED_LINEAR,
96     1, /* no_player_stealing */
97     };
98    
99     /* perhaps not the best place for this, but needs to be
100     * in some file in the common area so that standalone
101     * programs, like the random map generator, can be built.
102     */
103 elmex 1.3 const char* const spellpathnames[NRSPELLPATHS] = {
104 root 1.1 "Protection",
105     "Fire",
106     "Frost",
107     "Electricity",
108     "Missiles",
109     "Self",
110     "Summoning",
111     "Abjuration",
112     "Restoration",
113     "Detonation",
114     "Mind",
115     "Creation",
116     "Teleportation",
117     "Information",
118     "Transmutation",
119     "Transferrence",
120     "Turning",
121     "Wounding",
122     "Death",
123     "Light"
124     };
125    
126    
127     /* This loads the emergency map information from a
128     * .emergency file in the map directory. Doing this makes
129     * it easier to switch between map distributions (don't need
130     * to recompile. Note that there is no reason I see that
131     * this could not be re-loaded during play, but it seems
132     * like there should be little reason to do that.
133     */
134     static void init_emergency_mappath(void)
135     {
136     char filename[MAX_BUF], tmpbuf[MAX_BUF];
137     FILE *fp;
138     int online=0;
139    
140     /* If this file doesn't exist, not a big deal */
141     sprintf(filename,"%s/%s/.emergency",settings.datadir, settings.mapdir);
142     if ((fp = fopen(filename, "r"))!=NULL) {
143     while (fgets(tmpbuf, MAX_BUF-1, fp)) {
144     if (tmpbuf[0] == '#') continue; /* ignore comments */
145    
146     if (online == 0) {
147     tmpbuf[strlen(tmpbuf)-1] = 0; /* kill newline */
148     settings.emergency_mapname = strdup_local(tmpbuf);
149     }
150     else if (online == 1) {
151     settings.emergency_x = atoi(tmpbuf);
152     }
153    
154     else if (online == 2) {
155     settings.emergency_y = atoi(tmpbuf);
156     }
157     online++;
158     if (online>2) break;
159     }
160     fclose(fp);
161     if (online<=2)
162     LOG(llevError,"Online read partial data from %s\n", filename);
163     LOG(llevDebug,"Emergency mappath reset to %s (%d, %d)\n", settings.emergency_mapname,
164     settings.emergency_x, settings.emergency_y);
165     }
166     }
167    
168    
169     /*
170     * It is vital that init_library() is called by any functions
171     * using this library.
172     * If you want to lessen the size of the program using the library,
173     * you can replace the call to init_library() with init_globals() and
174     * init_function_pointers(). Good idea to also call init_vars and
175     * init_hash_table if you are doing any object loading.
176     */
177    
178     void init_library(void) {
179     init_environ();
180     init_globals();
181     init_hash_table();
182     init_objects();
183     init_vars();
184     init_block();
185     ReadBmapNames ();
186     ReadSmooth();
187     init_anim(); /* Must be after we read in the bitmaps */
188     init_archetypes(); /* Reads all archetypes from file */
189     init_dynamic ();
190     init_attackmess();
191     init_clocks();
192     init_emergency_mappath();
193     init_experience();
194     }
195    
196    
197     /* init_environ initializes values from the environmental variables.
198     * it needs to be called very early, since command line options should
199     * overwrite these if specified.
200     */
201     void init_environ(void) {
202     char *cp;
203    
204     cp=getenv("CROSSFIRE_LIBDIR");
205     if (cp) settings.datadir=cp;
206     cp=getenv("CROSSFIRE_LOCALDIR");
207     if (cp) settings.localdir=cp;
208     cp=getenv("CROSSFIRE_PLAYERDIR");
209     if (cp) settings.playerdir=cp;
210     cp=getenv("CROSSFIRE_MAPDIR");
211     if (cp) settings.mapdir=cp;
212     cp=getenv("CROSSFIRE_ARCHETYPES");
213     if (cp) settings.archetypes=cp;
214     cp=getenv("CROSSFIRE_TREASURES");
215     if (cp) settings.treasures=cp;
216     cp=getenv("CROSSFIRE_UNIQUEDIR");
217     if (cp) settings.uniquedir=cp;
218     cp=getenv("CROSSFIRE_TEMPLATEDIR");
219     if (cp) settings.templatedir=cp;
220     cp=getenv("CROSSFIRE_TMPDIR");
221     if (cp) settings.tmpdir=cp;
222     }
223    
224    
225     /*
226     * Initialises all global variables.
227     * Might use environment-variables as default for some of them.
228     */
229    
230     void init_globals(void) {
231     if (settings.logfilename[0] == 0) {
232     logfile = stderr;
233     }
234     else if ((logfile=fopen(settings.logfilename, "a"))==NULL) {
235     fprintf(stderr,"Unable to open %s as the logfile - will use stderr instead\n",
236     settings.logfilename);
237     logfile = stderr;
238     }
239 elmex 1.3 else {
240     setvbuf(logfile, NULL, _IOLBF, 0);
241     }
242 root 1.1 exiting = 0;
243     first_player=NULL;
244     first_friendly_object=NULL;
245     first_map=NULL;
246     first_treasurelist=NULL;
247     first_artifactlist=NULL;
248     first_archetype=NULL;
249     warn_archetypes=0;
250     first_map=NULL;
251     nroftreasures = 0;
252     nrofartifacts = 0;
253     nrofallowedstr=0;
254     ring_arch = NULL;
255     amulet_arch = NULL;
256     staff_arch = NULL;
257     undead_name = add_string("undead");
258     trying_emergency_save = 0;
259     num_animations=0;
260     animations=NULL;
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     if (at->clone.type == MAP && EXIT_PATH (&at->clone)) {
313     strcpy (first_map_path, EXIT_PATH (&at->clone));
314     return;
315     }
316     at = at->next;
317     }
318     LOG(llevDebug,"You Need a archetype called 'map' and it have to contain start map\n");
319     exit (-1);
320     }
321    
322     unsigned long todtick;
323    
324     /*
325     * Write out the current time to the file so time does not
326     * reset every time the server reboots.
327     */
328    
329     void write_todclock(void)
330     {
331     char filename[MAX_BUF];
332     FILE *fp;
333    
334     sprintf(filename, "%s/clockdata", settings.localdir);
335     if ((fp = fopen(filename, "w")) == NULL) {
336     LOG(llevError, "Cannot open %s for writing\n", filename);
337     return;
338     }
339     fprintf(fp, "%lu", todtick);
340     fclose(fp);
341     }
342    
343     /*
344     * Initializes the gametime and TOD counters
345     * Called by init_library().
346     */
347    
348     void init_clocks(void)
349     {
350     char filename[MAX_BUF];
351     FILE *fp;
352     static int has_been_done=0;
353    
354     if (has_been_done)
355     return;
356     else
357     has_been_done = 1;
358    
359     sprintf(filename, "%s/clockdata", settings.localdir);
360     LOG(llevDebug, "Reading clockdata from %s...", filename);
361     if ((fp = fopen(filename, "r")) == NULL) {
362     LOG(llevError, "Can't open %s.\n", filename);
363     todtick = 0;
364     write_todclock();
365     return;
366     }
367     fscanf(fp, "%lu", &todtick);
368     LOG(llevDebug, "todtick=%lu\n", todtick);
369     fclose(fp);
370     }
371    
372     /*
373     * Initializes the attack messages.
374     * Called by init_library().
375     */
376    
377     attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
378    
379     void init_attackmess(void){
380     char buf[MAX_BUF];
381     char filename[MAX_BUF];
382     char *cp, *p;
383     FILE *fp;
384     static int has_been_done=0;
385     int mess, level, comp;
386     int mode=0, total=0;
387    
388     if (has_been_done)
389     return;
390     else
391     has_been_done = 1;
392    
393     sprintf(filename, "%s/attackmess", settings.datadir);
394     LOG(llevDebug, "Reading attack messages from %s...", filename);
395     if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) {
396     LOG(llevError, "Can't open %s.\n", filename);
397     return;
398     }
399    
400     level = 0;
401     while (fgets(buf, MAX_BUF, fp)!=NULL) {
402     if (*buf=='#') continue;
403     if((cp=strchr(buf,'\n'))!=NULL)
404     *cp='\0';
405     cp=buf;
406     while(*cp==' ') /* Skip blanks */
407     cp++;
408    
409     if (strncmp(cp, "TYPE:", 5)==0) {
410     p = strtok(buf, ":");
411     p = strtok(NULL, ":");
412     if (mode == 1) {
413     attack_mess[mess][level].level = -1;
414     attack_mess[mess][level].buf1 = NULL;
415     attack_mess[mess][level].buf2 = NULL;
416     attack_mess[mess][level].buf3 = NULL;
417     }
418     level = 0;
419     mess = atoi(p);
420     mode = 1;
421     continue;
422     }
423     if (mode==1) {
424     p = strtok(buf, "=");
425     attack_mess[mess][level].level = atoi(buf);
426     p = strtok(NULL, "=");
427     if (p != NULL)
428     attack_mess[mess][level].buf1 = strdup_local(p);
429     else
430     attack_mess[mess][level].buf1 = strdup_local("");
431     mode = 2;
432     continue;
433     } else if (mode==2) {
434     p = strtok(buf, "=");
435     attack_mess[mess][level].level = atoi(buf);
436     p = strtok(NULL, "=");
437     if (p != NULL)
438     attack_mess[mess][level].buf2 = strdup_local(p);
439     else
440     attack_mess[mess][level].buf2 = strdup_local("");
441     mode = 3;
442     continue;
443     } else if (mode==3) {
444     p = strtok(buf, "=");
445     attack_mess[mess][level].level = atoi(buf);
446     p = strtok(NULL, "=");
447     if (p != NULL)
448     attack_mess[mess][level].buf3 = strdup_local(p);
449     else
450     attack_mess[mess][level].buf3 = strdup_local("");
451     mode = 1;
452     level++;
453     total++;
454     continue;
455     }
456     }
457     LOG(llevDebug, "got %d messages in %d categories.\n", total, mess+1);
458     close_and_delete(fp, comp);
459     }