ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.13
Committed: Thu Sep 14 22:33:58 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.12: +1 -1 lines
Log Message:
indent

File Contents

# User Rev Content
1 elmex 1.1 /*
2     CrossFire, A Multiplayer game for X-windows
3    
4     Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5     Copyright (C) 1992 Frank Tore Johansen
6    
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21 root 1.13 The authors can be reached via e-mail at <crossfire@schmorp.de>
22 elmex 1.1 */
23    
24 root 1.10 #define EXTERN // horrible hack
25 root 1.7
26 elmex 1.1 #include <global.h>
27     #include <object.h>
28    
29 root 1.10 extern const char *const attacktype_desc[NROFATTACKS] = {
30 root 1.11 # define def(uc, lc, name, plus, change) # name,
31     # include "attackinc.h"
32     # undef def
33 root 1.7 };
34    
35     extern const keyword resist_save[NROFATTACKS] = {
36 root 1.11 # define def(uc, lc, name, plus, change) KW_resist_ ## lc,
37     # include "attackinc.h"
38     # undef def
39 root 1.7 };
40    
41 root 1.10 extern const char *const resist_plus[NROFATTACKS] = {
42 root 1.11 # define def(uc, lc, name, plus, change) # plus,
43     # include "attackinc.h"
44     # undef def
45 root 1.7 };
46    
47 root 1.10 extern const char *const change_resist_msg[NROFATTACKS] = {
48 root 1.11 # define def(uc, lc, name, plus, change) # change,
49     # include "attackinc.h"
50     # undef def
51 root 1.7 };
52    
53     int resist_table[NROFATTACKS] = {
54 root 1.11 # define def(uc, lc, name, plus, change) ATNR_ ## uc,
55     # include "attackinc.h"
56     # undef def
57 root 1.7 };
58    
59 elmex 1.1 /* You unforunately need to looking in include/global.h to see what these
60     * correspond to.
61     */
62     struct Settings settings = {
63 root 1.10 LOGFILE, /* Logfile */
64     CSPORT, /* Client/server port */
65 elmex 1.1
66     /* Debug level */
67     #ifdef DEBUG
68     llevDebug,
69     #else
70     llevInfo,
71     #endif
72    
73 root 1.10 0, NULL, 0, /* dumpvalues, dumparg, daemonmode */
74     0, /* argc */
75     NULL, /* argv */
76     CONFDIR,
77     DATADIR,
78     LOCALDIR,
79     PLAYERDIR, MAPDIR, ARCHETYPES, REGIONS, TREASURES,
80     UNIQUE_DIR, TEMPLATE_DIR,
81     TMPDIR,
82     STAT_LOSS_ON_DEATH,
83     PK_LUCK_PENALTY,
84     PERMANENT_EXPERIENCE_RATIO,
85     DEATH_PENALTY_RATIO,
86     DEATH_PENALTY_LEVEL,
87     BALANCED_STAT_LOSS,
88     NOT_PERMADETH,
89     SIMPLE_EXP,
90     RESET_LOCATION_TIME,
91     SET_TITLE,
92     RESURRECTION,
93     SEARCH_ITEMS,
94     SPELL_ENCUMBRANCE,
95     SPELL_FAILURE_EFFECTS,
96     CASTING_TIME,
97     REAL_WIZ,
98     RECYCLE_TMP_MAPS,
99     EXPLORE_MODE,
100     SPELLPOINT_LEVEL_DEPEND,
101     SET_FRIENDLY_FIRE,
102     "", /* Who format specifier */
103     "", /* who wiz format specifier */
104     MOTD,
105     "rules",
106     "news",
107     "", /* DM_MAIL */
108     0, /* This and the next 3 values are metaserver values */
109     "",
110     "",
111     0,
112     "",
113     0, 0, 0, 0, 0, 0, 0, 0, /* worldmap settings */
114     EMERGENCY_MAPPATH, EMERGENCY_X, EMERGENCY_Y,
115     0,
116     1.0,
117    
118 elmex 1.1 /* Armor enchantment stuff */
119 root 1.10 ARMOR_MAX_ENCHANT,
120     ARMOR_WEIGHT_REDUCTION,
121     ARMOR_WEIGHT_LINEAR,
122     ARMOR_SPEED_IMPROVEMENT,
123     ARMOR_SPEED_LINEAR,
124     1, /* no_player_stealing */
125     1, /* create_home_portals */
126 elmex 1.1 };
127    
128     /* perhaps not the best place for this, but needs to be
129     * in some file in the common area so that standalone
130     * programs, like the random map generator, can be built.
131     */
132 root 1.10 const char *const spellpathnames[NRSPELLPATHS] = {
133     "Protection",
134     "Fire",
135     "Frost",
136     "Electricity",
137     "Missiles",
138     "Self",
139     "Summoning",
140     "Abjuration",
141     "Restoration",
142     "Detonation",
143     "Mind",
144     "Creation",
145     "Teleportation",
146     "Information",
147     "Transmutation",
148     "Transferrence",
149     "Turning",
150     "Wounding",
151     "Death",
152     "Light"
153 elmex 1.1 };
154    
155    
156     /* This loads the emergency map information from a
157     * .emergency file in the map directory. Doing this makes
158     * it easier to switch between map distributions (don't need
159     * to recompile. Note that there is no reason I see that
160     * this could not be re-loaded during play, but it seems
161     * like there should be little reason to do that.
162     */
163 root 1.10 static void
164     init_emergency_mappath (void)
165 elmex 1.1 {
166 root 1.10 char filename[MAX_BUF], tmpbuf[MAX_BUF];
167     FILE *fp;
168     int online = 0;
169    
170     /* If this file doesn't exist, not a big deal */
171     sprintf (filename, "%s/%s/.emergency", settings.datadir, settings.mapdir);
172     if ((fp = fopen (filename, "r")) != NULL)
173     {
174     while (fgets (tmpbuf, MAX_BUF - 1, fp))
175     {
176     if (tmpbuf[0] == '#')
177     continue; /* ignore comments */
178    
179     if (online == 0)
180     {
181     tmpbuf[strlen (tmpbuf) - 1] = 0; /* kill newline */
182     settings.emergency_mapname = strdup_local (tmpbuf);
183 root 1.2 }
184 root 1.10 else if (online == 1)
185     {
186     settings.emergency_x = atoi (tmpbuf);
187 root 1.2 }
188    
189 root 1.10 else if (online == 2)
190     {
191     settings.emergency_y = atoi (tmpbuf);
192 root 1.2 }
193 root 1.10 online++;
194     if (online > 2)
195     break;
196 root 1.2 }
197 root 1.10 fclose (fp);
198     if (online <= 2)
199     LOG (llevError, "Online read partial data from %s\n", filename);
200     LOG (llevDebug, "Emergency mappath reset to %s (%d, %d)\n", settings.emergency_mapname, settings.emergency_x, settings.emergency_y);
201 elmex 1.1 }
202     }
203 root 1.10
204 elmex 1.1
205     /*
206     * It is vital that init_library() is called by any functions
207     * using this library.
208     * If you want to lessen the size of the program using the library,
209     * you can replace the call to init_library() with init_globals() and
210     * init_function_pointers(). Good idea to also call init_vars and
211     * init_hash_table if you are doing any object loading.
212     */
213    
214 root 1.10 void
215     init_library (void)
216     {
217     init_environ ();
218     init_globals ();
219     init_vars ();
220     init_block ();
221     ReadBmapNames ();
222     ReadSmooth ();
223     init_anim (); /* Must be after we read in the bitmaps */
224     init_archetypes (); /* Reads all archetypes from file */
225     init_dynamic ();
226     init_attackmess ();
227     init_clocks ();
228     init_emergency_mappath ();
229     init_experience ();
230 elmex 1.1 }
231    
232    
233     /* init_environ initializes values from the environmental variables.
234     * it needs to be called very early, since command line options should
235     * overwrite these if specified.
236     */
237 root 1.10 void
238     init_environ (void)
239     {
240     char *cp;
241 elmex 1.1
242 root 1.10 cp = getenv ("CROSSFIRE_LIBDIR");
243     if (cp)
244     settings.datadir = cp;
245     cp = getenv ("CROSSFIRE_LOCALDIR");
246     if (cp)
247     settings.localdir = cp;
248     cp = getenv ("CROSSFIRE_PLAYERDIR");
249     if (cp)
250     settings.playerdir = cp;
251     cp = getenv ("CROSSFIRE_MAPDIR");
252     if (cp)
253     settings.mapdir = cp;
254     cp = getenv ("CROSSFIRE_ARCHETYPES");
255     if (cp)
256     settings.archetypes = cp;
257     cp = getenv ("CROSSFIRE_TREASURES");
258     if (cp)
259     settings.treasures = cp;
260     cp = getenv ("CROSSFIRE_UNIQUEDIR");
261     if (cp)
262     settings.uniquedir = cp;
263     cp = getenv ("CROSSFIRE_TEMPLATEDIR");
264     if (cp)
265     settings.templatedir = cp;
266     cp = getenv ("CROSSFIRE_TMPDIR");
267     if (cp)
268     settings.tmpdir = cp;
269 elmex 1.1 }
270 root 1.10
271 elmex 1.1
272     /*
273     * Initialises all global variables.
274     * Might use environment-variables as default for some of them.
275     */
276    
277 root 1.10 void
278     init_globals (void)
279     {
280     if (settings.logfilename[0] == 0)
281 root 1.12 logfile = stderr;
282 root 1.10 else if ((logfile = fopen (settings.logfilename, "a")) == NULL)
283     {
284     fprintf (stderr, "Unable to open %s as the logfile - will use stderr instead\n", settings.logfilename);
285     logfile = stderr;
286 elmex 1.1 }
287 root 1.10 else
288 root 1.12 setvbuf (logfile, NULL, _IOLBF, 0);
289 elmex 1.1 }
290    
291 root 1.10 void
292     init_dynamic (void)
293     {
294     archetype *at = first_archetype;
295    
296     while (at)
297     {
298     if (at->clone.type == MAP)
299     {
300     if (at->clone.race)
301 root 1.12 strcpy (first_map_ext_path, at->clone.race);
302    
303 root 1.10 if (EXIT_PATH (&at->clone))
304     {
305     strcpy (first_map_path, EXIT_PATH (&at->clone));
306     return;
307 elmex 1.1 }
308 root 1.2 }
309 root 1.12
310 root 1.10 at = at->next;
311 elmex 1.1 }
312 root 1.12
313 root 1.10 LOG (llevDebug, "You Need a archetype called 'map' and it have to contain start map\n");
314     exit (-1);
315 elmex 1.1 }
316    
317     unsigned long todtick;
318    
319     /*
320     * Write out the current time to the file so time does not
321     * reset every time the server reboots.
322     */
323    
324 root 1.10 void
325     write_todclock (void)
326 elmex 1.1 {
327 root 1.10 char filename[MAX_BUF];
328     FILE *fp;
329 elmex 1.1
330 root 1.10 sprintf (filename, "%s/clockdata", settings.localdir);
331     if ((fp = fopen (filename, "w")) == NULL)
332     {
333     LOG (llevError, "Cannot open %s for writing\n", filename);
334     return;
335 elmex 1.1 }
336 root 1.10 fprintf (fp, "%lu", todtick);
337     fclose (fp);
338 elmex 1.1 }
339    
340     /*
341     * Initializes the gametime and TOD counters
342     * Called by init_library().
343     */
344    
345 root 1.10 void
346     init_clocks (void)
347 elmex 1.1 {
348 root 1.10 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     {
361     LOG (llevError, "Can't open %s.\n", filename);
362     todtick = 0;
363     write_todclock ();
364     return;
365 elmex 1.1 }
366 root 1.10 fscanf (fp, "%lu", &todtick);
367     LOG (llevDebug, "todtick=%lu\n", todtick);
368     fclose (fp);
369 elmex 1.1 }
370    
371     /*
372     * Initializes the attack messages.
373     * Called by init_library().
374     */
375    
376     //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
377    
378 root 1.10 void
379     init_attackmess (void)
380     {
381     char buf[MAX_BUF];
382     char filename[MAX_BUF];
383     char *cp, *p;
384     FILE *fp;
385     static int has_been_done = 0;
386     int mess, level, comp;
387     int mode = 0, total = 0;
388    
389     if (has_been_done)
390     return;
391     else
392     has_been_done = 1;
393    
394     sprintf (filename, "%s/attackmess", settings.datadir);
395     LOG (llevDebug, "Reading attack messages from %s...", filename);
396     if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL)
397     {
398     LOG (llevError, "Can't open %s.\n", filename);
399     return;
400 elmex 1.1 }
401    
402 root 1.10 level = 0;
403     while (fgets (buf, MAX_BUF, fp) != NULL)
404     {
405     if (*buf == '#')
406     continue;
407     if ((cp = strchr (buf, '\n')) != NULL)
408     *cp = '\0';
409     cp = buf;
410     while (*cp == ' ') /* Skip blanks */
411     cp++;
412    
413     if (strncmp (cp, "TYPE:", 5) == 0)
414     {
415     p = strtok (buf, ":");
416     p = strtok (NULL, ":");
417     if (mode == 1)
418     {
419     attack_mess[mess][level].level = -1;
420     attack_mess[mess][level].buf1 = NULL;
421     attack_mess[mess][level].buf2 = NULL;
422     attack_mess[mess][level].buf3 = NULL;
423 root 1.2 }
424 root 1.10 level = 0;
425     mess = atoi (p);
426     mode = 1;
427     continue;
428     }
429     if (mode == 1)
430     {
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].buf1 = strdup_local (p);
436     else
437     attack_mess[mess][level].buf1 = strdup_local ("");
438     mode = 2;
439     continue;
440     }
441     else if (mode == 2)
442     {
443     p = strtok (buf, "=");
444     attack_mess[mess][level].level = atoi (buf);
445     p = strtok (NULL, "=");
446     if (p != NULL)
447     attack_mess[mess][level].buf2 = strdup_local (p);
448     else
449     attack_mess[mess][level].buf2 = strdup_local ("");
450     mode = 3;
451     continue;
452 root 1.2 }
453 root 1.10 else if (mode == 3)
454     {
455     p = strtok (buf, "=");
456     attack_mess[mess][level].level = atoi (buf);
457     p = strtok (NULL, "=");
458     if (p != NULL)
459     attack_mess[mess][level].buf3 = strdup_local (p);
460     else
461     attack_mess[mess][level].buf3 = strdup_local ("");
462     mode = 1;
463     level++;
464     total++;
465     continue;
466 root 1.2 }
467 elmex 1.1 }
468 root 1.10 LOG (llevDebug, "got %d messages in %d categories.\n", total, mess + 1);
469     close_and_delete (fp, comp);
470 elmex 1.1 }