ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.c
Revision: 1.1.1.1 (vendor branch)
Committed: Fri Feb 3 07:11:31 2006 UTC (18 years, 3 months ago) by root
Content type: text/plain
Branch: UPSTREAM
CVS Tags: UPSTREAM_2006_02_03
Changes since 1.1: +0 -0 lines
Log Message:
initial import

File Contents

# User Rev Content
1 root 1.1 /*
2     * static char *rcsid_init_c =
3     * "$Id: init.c,v 1.45 2006/01/08 20:52:11 akirschbaum Exp $";
4     */
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     char *spellpathnames[NRSPELLPATHS] = {
104     "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     exiting = 0;
240     first_player=NULL;
241     first_friendly_object=NULL;
242     first_map=NULL;
243     first_treasurelist=NULL;
244     first_artifactlist=NULL;
245     first_archetype=NULL;
246     warn_archetypes=0;
247     first_map=NULL;
248     nroftreasures = 0;
249     nrofartifacts = 0;
250     nrofallowedstr=0;
251     ring_arch = NULL;
252     amulet_arch = NULL;
253     staff_arch = NULL;
254     undead_name = add_string("undead");
255     trying_emergency_save = 0;
256     num_animations=0;
257     animations=NULL;
258     animations_allocated=0;
259     init_defaults();
260     }
261    
262     /*
263     * Sets up and initialises the linked list of free and used objects.
264     * Allocates a certain chunk of objects and puts them on the free list.
265     * Called by init_library();
266     */
267    
268     void init_objects(void) {
269     int i;
270     /* Initialize all objects: */
271     objects=NULL;
272     active_objects = NULL;
273    
274     #ifdef MEMORY_DEBUG
275     free_objects=NULL;
276     #else
277     free_objects=objarray;
278     objarray[0].prev=NULL,
279     objarray[0].next= &objarray[1],
280     SET_FLAG(&objarray[0], FLAG_REMOVED);
281     SET_FLAG(&objarray[0], FLAG_FREED);
282     for(i=1;i<STARTMAX-1;i++) {
283     objarray[i].next= &objarray[i+1];
284     objarray[i].prev= &objarray[i-1];
285     SET_FLAG(&objarray[i], FLAG_REMOVED);
286     SET_FLAG(&objarray[i], FLAG_FREED);
287     }
288     objarray[STARTMAX-1].next=NULL;
289     objarray[STARTMAX-1].prev= &objarray[STARTMAX-2];
290     SET_FLAG(&objarray[STARTMAX-1], FLAG_REMOVED);
291     SET_FLAG(&objarray[STARTMAX-1], FLAG_FREED);
292     #endif
293     }
294    
295     /*
296     * Initialises global variables which can be changed by options.
297     * Called by init_library().
298     */
299    
300     void init_defaults(void) {
301     editor=0;
302     nroferrors=0;
303     }
304    
305    
306     void init_dynamic (void) {
307     archetype *at = first_archetype;
308     while (at) {
309     if (at->clone.type == MAP && EXIT_PATH (&at->clone)) {
310     strcpy (first_map_path, EXIT_PATH (&at->clone));
311     return;
312     }
313     at = at->next;
314     }
315     LOG(llevDebug,"You Need a archetype called 'map' and it have to contain start map\n");
316     exit (-1);
317     }
318    
319     unsigned long todtick;
320    
321     /*
322     * Write out the current time to the file so time does not
323     * reset every time the server reboots.
324     */
325    
326     void write_todclock(void)
327     {
328     char filename[MAX_BUF];
329     FILE *fp;
330    
331     sprintf(filename, "%s/clockdata", settings.localdir);
332     if ((fp = fopen(filename, "w")) == NULL) {
333     LOG(llevError, "Cannot open %s for writing\n", filename);
334     return;
335     }
336     fprintf(fp, "%lu", todtick);
337     fclose(fp);
338     }
339    
340     /*
341     * Initializes the gametime and TOD counters
342     * Called by init_library().
343     */
344    
345     void init_clocks(void)
346     {
347     char filename[MAX_BUF];
348     FILE *fp;
349     static int has_been_done=0;
350    
351     if (has_been_done)
352     return;
353     else
354     has_been_done = 1;
355    
356     sprintf(filename, "%s/clockdata", settings.localdir);
357     LOG(llevDebug, "Reading clockdata from %s...", filename);
358     if ((fp = fopen(filename, "r")) == NULL) {
359     LOG(llevError, "Can't open %s.\n", filename);
360     todtick = 0;
361     write_todclock();
362     return;
363     }
364     fscanf(fp, "%lu", &todtick);
365     LOG(llevDebug, "todtick=%lu\n", todtick);
366     fclose(fp);
367     }
368    
369     /*
370     * Initializes the attack messages.
371     * Called by init_library().
372     */
373    
374     attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
375    
376     void init_attackmess(void){
377     char buf[MAX_BUF];
378     char filename[MAX_BUF];
379     char *cp, *p;
380     FILE *fp;
381     static int has_been_done=0;
382     int mess, level, comp;
383     int mode=0, total=0;
384    
385     if (has_been_done)
386     return;
387     else
388     has_been_done = 1;
389    
390     sprintf(filename, "%s/attackmess", settings.datadir);
391     LOG(llevDebug, "Reading attack messages from %s...", filename);
392     if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) {
393     LOG(llevError, "Can't open %s.\n", filename);
394     return;
395     }
396    
397     level = 0;
398     while (fgets(buf, MAX_BUF, fp)!=NULL) {
399     if (*buf=='#') continue;
400     if((cp=strchr(buf,'\n'))!=NULL)
401     *cp='\0';
402     cp=buf;
403     while(*cp==' ') /* Skip blanks */
404     cp++;
405    
406     if (strncmp(cp, "TYPE:", 5)==0) {
407     p = strtok(buf, ":");
408     p = strtok(NULL, ":");
409     if (mode == 1) {
410     attack_mess[mess][level].level = -1;
411     attack_mess[mess][level].buf1 = NULL;
412     attack_mess[mess][level].buf2 = NULL;
413     attack_mess[mess][level].buf3 = NULL;
414     }
415     level = 0;
416     mess = atoi(p);
417     mode = 1;
418     continue;
419     }
420     if (mode==1) {
421     p = strtok(buf, "=");
422     attack_mess[mess][level].level = atoi(buf);
423     p = strtok(NULL, "=");
424     if (p != NULL)
425     attack_mess[mess][level].buf1 = strdup_local(p);
426     else
427     attack_mess[mess][level].buf1 = strdup_local("");
428     mode = 2;
429     continue;
430     } else if (mode==2) {
431     p = strtok(buf, "=");
432     attack_mess[mess][level].level = atoi(buf);
433     p = strtok(NULL, "=");
434     if (p != NULL)
435     attack_mess[mess][level].buf2 = strdup_local(p);
436     else
437     attack_mess[mess][level].buf2 = strdup_local("");
438     mode = 3;
439     continue;
440     } else if (mode==3) {
441     p = strtok(buf, "=");
442     attack_mess[mess][level].level = atoi(buf);
443     p = strtok(NULL, "=");
444     if (p != NULL)
445     attack_mess[mess][level].buf3 = strdup_local(p);
446     else
447     attack_mess[mess][level].buf3 = strdup_local("");
448     mode = 1;
449     level++;
450     total++;
451     continue;
452     }
453     }
454     LOG(llevDebug, "got %d messages in %d categories.\n", total, mess+1);
455     close_and_delete(fp, comp);
456     }