ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.12
Committed: Thu Sep 14 18:13:01 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.11: +6 -56 lines
Log Message:
presuppose iso c++0x

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_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 }
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 void
238 init_environ (void)
239 {
240 char *cp;
241
242 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 }
270
271
272 /*
273 * Initialises all global variables.
274 * Might use environment-variables as default for some of them.
275 */
276
277 void
278 init_globals (void)
279 {
280 if (settings.logfilename[0] == 0)
281 logfile = stderr;
282 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 }
287 else
288 setvbuf (logfile, NULL, _IOLBF, 0);
289 }
290
291 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 strcpy (first_map_ext_path, at->clone.race);
302
303 if (EXIT_PATH (&at->clone))
304 {
305 strcpy (first_map_path, EXIT_PATH (&at->clone));
306 return;
307 }
308 }
309
310 at = at->next;
311 }
312
313 LOG (llevDebug, "You Need a archetype called 'map' and it have to contain start map\n");
314 exit (-1);
315 }
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 void
325 write_todclock (void)
326 {
327 char filename[MAX_BUF];
328 FILE *fp;
329
330 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 }
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
346 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 {
361 LOG (llevError, "Can't open %s.\n", filename);
362 todtick = 0;
363 write_todclock ();
364 return;
365 }
366 fscanf (fp, "%lu", &todtick);
367 LOG (llevDebug, "todtick=%lu\n", todtick);
368 fclose (fp);
369 }
370
371 /*
372 * Initializes the attack messages.
373 * Called by init_library().
374 */
375
376 //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
377
378 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 }
401
402 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 }
424 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 }
453 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 }
467 }
468 LOG (llevDebug, "got %d messages in %d categories.\n", total, mess + 1);
469 close_and_delete (fp, comp);
470 }