ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.c
Revision: 1.2
Committed: Fri Feb 3 07:25:24 2006 UTC (18 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.1: +2 -1 lines
Log Message:
initial cfperl/cf.schmorp.de import

File Contents

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