ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.11
Committed: Wed Sep 13 02:05:18 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.10: +15 -21 lines
Log Message:
preliminary uuid support

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-devel@real-time.com
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 keyword resist_save[NROFATTACKS] = {
36 # define def(uc, lc, name, plus, change) KW_resist_ ## lc,
37 # include "attackinc.h"
38 # undef def
39 };
40
41 extern const char *const resist_plus[NROFATTACKS] = {
42 # define def(uc, lc, name, plus, change) # plus,
43 # include "attackinc.h"
44 # undef def
45 };
46
47 extern const char *const change_resist_msg[NROFATTACKS] = {
48 # define def(uc, lc, name, plus, change) # change,
49 # include "attackinc.h"
50 # undef def
51 };
52
53 int resist_table[NROFATTACKS] = {
54 # define def(uc, lc, name, plus, change) ATNR_ ## uc,
55 # include "attackinc.h"
56 # undef def
57 };
58
59 /* You unforunately need to looking in include/global.h to see what these
60 * correspond to.
61 */
62 struct Settings settings = {
63 LOGFILE, /* Logfile */
64 CSPORT, /* Client/server port */
65
66 /* Debug level */
67 #ifdef DEBUG
68 llevDebug,
69 #else
70 llevInfo,
71 #endif
72
73 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 /* Armor enchantment stuff */
119 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 };
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 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 };
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 static void
164 init_emergency_mappath (void)
165 {
166 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 }
184 else if (online == 1)
185 {
186 settings.emergency_x = atoi (tmpbuf);
187 }
188
189 else if (online == 2)
190 {
191 settings.emergency_y = atoi (tmpbuf);
192 }
193 online++;
194 if (online > 2)
195 break;
196 }
197 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 }
202 }
203
204
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 void
215 init_library (void)
216 {
217 init_environ ();
218 init_globals ();
219 init_objects ();
220 init_vars ();
221 init_block ();
222 ReadBmapNames ();
223 ReadSmooth ();
224 init_anim (); /* Must be after we read in the bitmaps */
225 init_archetypes (); /* Reads all archetypes from file */
226 init_dynamic ();
227 init_attackmess ();
228 init_clocks ();
229 init_emergency_mappath ();
230 init_experience ();
231 }
232
233
234 /* init_environ initializes values from the environmental variables.
235 * it needs to be called very early, since command line options should
236 * overwrite these if specified.
237 */
238 void
239 init_environ (void)
240 {
241 char *cp;
242
243 cp = getenv ("CROSSFIRE_LIBDIR");
244 if (cp)
245 settings.datadir = cp;
246 cp = getenv ("CROSSFIRE_LOCALDIR");
247 if (cp)
248 settings.localdir = cp;
249 cp = getenv ("CROSSFIRE_PLAYERDIR");
250 if (cp)
251 settings.playerdir = cp;
252 cp = getenv ("CROSSFIRE_MAPDIR");
253 if (cp)
254 settings.mapdir = cp;
255 cp = getenv ("CROSSFIRE_ARCHETYPES");
256 if (cp)
257 settings.archetypes = cp;
258 cp = getenv ("CROSSFIRE_TREASURES");
259 if (cp)
260 settings.treasures = cp;
261 cp = getenv ("CROSSFIRE_UNIQUEDIR");
262 if (cp)
263 settings.uniquedir = cp;
264 cp = getenv ("CROSSFIRE_TEMPLATEDIR");
265 if (cp)
266 settings.templatedir = cp;
267 cp = getenv ("CROSSFIRE_TMPDIR");
268 if (cp)
269 settings.tmpdir = cp;
270 }
271
272
273 /*
274 * Initialises all global variables.
275 * Might use environment-variables as default for some of them.
276 */
277
278 void
279 init_globals (void)
280 {
281 if (settings.logfilename[0] == 0)
282 {
283 logfile = stderr;
284 }
285 else if ((logfile = fopen (settings.logfilename, "a")) == NULL)
286 {
287 fprintf (stderr, "Unable to open %s as the logfile - will use stderr instead\n", settings.logfilename);
288 logfile = stderr;
289 }
290 else
291 {
292 setvbuf (logfile, NULL, _IOLBF, 0);
293 }
294 exiting = 0;
295 first_player = NULL;
296 first_friendly_object = NULL;
297 first_map = NULL;
298 first_treasurelist = NULL;
299 first_artifactlist = NULL;
300 first_archetype = NULL;
301 *first_map_ext_path = 0;
302 warn_archetypes = 0;
303 nroftreasures = 0;
304 nrofartifacts = 0;
305 nrofallowedstr = 0;
306 ring_arch = NULL;
307 amulet_arch = NULL;
308 staff_arch = NULL;
309 trying_emergency_save = 0;
310 num_animations = 0;
311 animations_allocated = 0;
312 init_defaults ();
313 }
314
315 /*
316 * Sets up and initialises the linked list of free and used objects.
317 * Allocates a certain chunk of objects and puts them on the free list.
318 * Called by init_library();
319 */
320
321 void
322 init_objects (void)
323 {
324 /* Initialize all objects: */
325 objects = NULL;
326 active_objects = NULL;
327 }
328
329 /*
330 * Initialises global variables which can be changed by options.
331 * Called by init_library().
332 */
333
334 void
335 init_defaults (void)
336 {
337 editor = 0;
338 nroferrors = 0;
339 }
340
341
342 void
343 init_dynamic (void)
344 {
345 archetype *at = first_archetype;
346
347 while (at)
348 {
349 if (at->clone.type == MAP)
350 {
351 if (at->clone.race)
352 {
353 strcpy (first_map_ext_path, at->clone.race);
354 }
355 if (EXIT_PATH (&at->clone))
356 {
357 strcpy (first_map_path, EXIT_PATH (&at->clone));
358 return;
359 }
360 }
361 at = at->next;
362 }
363 LOG (llevDebug, "You Need a archetype called 'map' and it have to contain start map\n");
364 exit (-1);
365 }
366
367 unsigned long todtick;
368
369 /*
370 * Write out the current time to the file so time does not
371 * reset every time the server reboots.
372 */
373
374 void
375 write_todclock (void)
376 {
377 char filename[MAX_BUF];
378 FILE *fp;
379
380 sprintf (filename, "%s/clockdata", settings.localdir);
381 if ((fp = fopen (filename, "w")) == NULL)
382 {
383 LOG (llevError, "Cannot open %s for writing\n", filename);
384 return;
385 }
386 fprintf (fp, "%lu", todtick);
387 fclose (fp);
388 }
389
390 /*
391 * Initializes the gametime and TOD counters
392 * Called by init_library().
393 */
394
395 void
396 init_clocks (void)
397 {
398 char filename[MAX_BUF];
399 FILE *fp;
400 static int has_been_done = 0;
401
402 if (has_been_done)
403 return;
404 else
405 has_been_done = 1;
406
407 sprintf (filename, "%s/clockdata", settings.localdir);
408 LOG (llevDebug, "Reading clockdata from %s...", filename);
409 if ((fp = fopen (filename, "r")) == NULL)
410 {
411 LOG (llevError, "Can't open %s.\n", filename);
412 todtick = 0;
413 write_todclock ();
414 return;
415 }
416 fscanf (fp, "%lu", &todtick);
417 LOG (llevDebug, "todtick=%lu\n", todtick);
418 fclose (fp);
419 }
420
421 /*
422 * Initializes the attack messages.
423 * Called by init_library().
424 */
425
426 //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
427
428 void
429 init_attackmess (void)
430 {
431 char buf[MAX_BUF];
432 char filename[MAX_BUF];
433 char *cp, *p;
434 FILE *fp;
435 static int has_been_done = 0;
436 int mess, level, comp;
437 int mode = 0, total = 0;
438
439 if (has_been_done)
440 return;
441 else
442 has_been_done = 1;
443
444 sprintf (filename, "%s/attackmess", settings.datadir);
445 LOG (llevDebug, "Reading attack messages from %s...", filename);
446 if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL)
447 {
448 LOG (llevError, "Can't open %s.\n", filename);
449 return;
450 }
451
452 level = 0;
453 while (fgets (buf, MAX_BUF, fp) != NULL)
454 {
455 if (*buf == '#')
456 continue;
457 if ((cp = strchr (buf, '\n')) != NULL)
458 *cp = '\0';
459 cp = buf;
460 while (*cp == ' ') /* Skip blanks */
461 cp++;
462
463 if (strncmp (cp, "TYPE:", 5) == 0)
464 {
465 p = strtok (buf, ":");
466 p = strtok (NULL, ":");
467 if (mode == 1)
468 {
469 attack_mess[mess][level].level = -1;
470 attack_mess[mess][level].buf1 = NULL;
471 attack_mess[mess][level].buf2 = NULL;
472 attack_mess[mess][level].buf3 = NULL;
473 }
474 level = 0;
475 mess = atoi (p);
476 mode = 1;
477 continue;
478 }
479 if (mode == 1)
480 {
481 p = strtok (buf, "=");
482 attack_mess[mess][level].level = atoi (buf);
483 p = strtok (NULL, "=");
484 if (p != NULL)
485 attack_mess[mess][level].buf1 = strdup_local (p);
486 else
487 attack_mess[mess][level].buf1 = strdup_local ("");
488 mode = 2;
489 continue;
490 }
491 else if (mode == 2)
492 {
493 p = strtok (buf, "=");
494 attack_mess[mess][level].level = atoi (buf);
495 p = strtok (NULL, "=");
496 if (p != NULL)
497 attack_mess[mess][level].buf2 = strdup_local (p);
498 else
499 attack_mess[mess][level].buf2 = strdup_local ("");
500 mode = 3;
501 continue;
502 }
503 else if (mode == 3)
504 {
505 p = strtok (buf, "=");
506 attack_mess[mess][level].level = atoi (buf);
507 p = strtok (NULL, "=");
508 if (p != NULL)
509 attack_mess[mess][level].buf3 = strdup_local (p);
510 else
511 attack_mess[mess][level].buf3 = strdup_local ("");
512 mode = 1;
513 level++;
514 total++;
515 continue;
516 }
517 }
518 LOG (llevDebug, "got %d messages in %d categories.\n", total, mess + 1);
519 close_and_delete (fp, comp);
520 }