ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.16
Committed: Thu Dec 14 22:45:40 2006 UTC (17 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.15: +7 -7 lines
Log Message:
- implement event watcher autoncancellation on reload
- used it everywhere
- removed lots of compatibility cruft
  - configure does no longer check for mandatory unix functionality/headers
  - confgiure now runs much faster

File Contents

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