ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.14
Committed: Thu Sep 21 00:05:24 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.13: +0 -6 lines
Log Message:
further simplify and speed up map saving, fixed
- flag_player_sold was incorrectly saved as "player sold 1"
- flag_has_ready_range was not saved
- flag_is_dust is not in use anymore

not well tested

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 "", /* Who format specifier */
97 "", /* who wiz format specifier */
98 MOTD,
99 "rules",
100 "news",
101 "", /* DM_MAIL */
102 0, /* This and the next 3 values are metaserver values */
103 "",
104 "",
105 0,
106 "",
107 0, 0, 0, 0, 0, 0, 0, 0, /* worldmap settings */
108 EMERGENCY_MAPPATH, EMERGENCY_X, EMERGENCY_Y,
109 0,
110 1.0,
111
112 /* Armor enchantment stuff */
113 ARMOR_MAX_ENCHANT,
114 ARMOR_WEIGHT_REDUCTION,
115 ARMOR_WEIGHT_LINEAR,
116 ARMOR_SPEED_IMPROVEMENT,
117 ARMOR_SPEED_LINEAR,
118 1, /* no_player_stealing */
119 1, /* create_home_portals */
120 };
121
122 /* perhaps not the best place for this, but needs to be
123 * in some file in the common area so that standalone
124 * programs, like the random map generator, can be built.
125 */
126 const char *const spellpathnames[NRSPELLPATHS] = {
127 "Protection",
128 "Fire",
129 "Frost",
130 "Electricity",
131 "Missiles",
132 "Self",
133 "Summoning",
134 "Abjuration",
135 "Restoration",
136 "Detonation",
137 "Mind",
138 "Creation",
139 "Teleportation",
140 "Information",
141 "Transmutation",
142 "Transferrence",
143 "Turning",
144 "Wounding",
145 "Death",
146 "Light"
147 };
148
149
150 /* This loads the emergency map information from a
151 * .emergency file in the map directory. Doing this makes
152 * it easier to switch between map distributions (don't need
153 * to recompile. Note that there is no reason I see that
154 * this could not be re-loaded during play, but it seems
155 * like there should be little reason to do that.
156 */
157 static void
158 init_emergency_mappath (void)
159 {
160 char filename[MAX_BUF], tmpbuf[MAX_BUF];
161 FILE *fp;
162 int online = 0;
163
164 /* If this file doesn't exist, not a big deal */
165 sprintf (filename, "%s/%s/.emergency", settings.datadir, settings.mapdir);
166 if ((fp = fopen (filename, "r")) != NULL)
167 {
168 while (fgets (tmpbuf, MAX_BUF - 1, fp))
169 {
170 if (tmpbuf[0] == '#')
171 continue; /* ignore comments */
172
173 if (online == 0)
174 {
175 tmpbuf[strlen (tmpbuf) - 1] = 0; /* kill newline */
176 settings.emergency_mapname = strdup_local (tmpbuf);
177 }
178 else if (online == 1)
179 {
180 settings.emergency_x = atoi (tmpbuf);
181 }
182
183 else if (online == 2)
184 {
185 settings.emergency_y = atoi (tmpbuf);
186 }
187 online++;
188 if (online > 2)
189 break;
190 }
191 fclose (fp);
192 if (online <= 2)
193 LOG (llevError, "Online read partial data from %s\n", filename);
194 LOG (llevDebug, "Emergency mappath reset to %s (%d, %d)\n", settings.emergency_mapname, settings.emergency_x, settings.emergency_y);
195 }
196 }
197
198
199 /*
200 * It is vital that init_library() is called by any functions
201 * using this library.
202 * If you want to lessen the size of the program using the library,
203 * you can replace the call to init_library() with init_globals() and
204 * init_function_pointers(). Good idea to also call init_vars and
205 * init_hash_table if you are doing any object loading.
206 */
207
208 void
209 init_library (void)
210 {
211 init_environ ();
212 init_globals ();
213 init_vars ();
214 init_block ();
215 ReadBmapNames ();
216 ReadSmooth ();
217 init_anim (); /* Must be after we read in the bitmaps */
218 init_archetypes (); /* Reads all archetypes from file */
219 init_dynamic ();
220 init_attackmess ();
221 init_clocks ();
222 init_emergency_mappath ();
223 init_experience ();
224 }
225
226
227 /* init_environ initializes values from the environmental variables.
228 * it needs to be called very early, since command line options should
229 * overwrite these if specified.
230 */
231 void
232 init_environ (void)
233 {
234 char *cp;
235
236 cp = getenv ("CROSSFIRE_LIBDIR");
237 if (cp)
238 settings.datadir = cp;
239 cp = getenv ("CROSSFIRE_LOCALDIR");
240 if (cp)
241 settings.localdir = cp;
242 cp = getenv ("CROSSFIRE_PLAYERDIR");
243 if (cp)
244 settings.playerdir = cp;
245 cp = getenv ("CROSSFIRE_MAPDIR");
246 if (cp)
247 settings.mapdir = cp;
248 cp = getenv ("CROSSFIRE_ARCHETYPES");
249 if (cp)
250 settings.archetypes = cp;
251 cp = getenv ("CROSSFIRE_TREASURES");
252 if (cp)
253 settings.treasures = cp;
254 cp = getenv ("CROSSFIRE_UNIQUEDIR");
255 if (cp)
256 settings.uniquedir = cp;
257 cp = getenv ("CROSSFIRE_TEMPLATEDIR");
258 if (cp)
259 settings.templatedir = cp;
260 cp = getenv ("CROSSFIRE_TMPDIR");
261 if (cp)
262 settings.tmpdir = cp;
263 }
264
265
266 /*
267 * Initialises all global variables.
268 * Might use environment-variables as default for some of them.
269 */
270
271 void
272 init_globals (void)
273 {
274 if (settings.logfilename[0] == 0)
275 logfile = stderr;
276 else if ((logfile = fopen (settings.logfilename, "a")) == NULL)
277 {
278 fprintf (stderr, "Unable to open %s as the logfile - will use stderr instead\n", settings.logfilename);
279 logfile = stderr;
280 }
281 else
282 setvbuf (logfile, NULL, _IOLBF, 0);
283 }
284
285 void
286 init_dynamic (void)
287 {
288 archetype *at = first_archetype;
289
290 while (at)
291 {
292 if (at->clone.type == MAP)
293 {
294 if (at->clone.race)
295 strcpy (first_map_ext_path, at->clone.race);
296
297 if (EXIT_PATH (&at->clone))
298 {
299 strcpy (first_map_path, EXIT_PATH (&at->clone));
300 return;
301 }
302 }
303
304 at = at->next;
305 }
306
307 LOG (llevDebug, "You Need a archetype called 'map' and it have to contain start map\n");
308 exit (-1);
309 }
310
311 unsigned long todtick;
312
313 /*
314 * Write out the current time to the file so time does not
315 * reset every time the server reboots.
316 */
317
318 void
319 write_todclock (void)
320 {
321 char filename[MAX_BUF];
322 FILE *fp;
323
324 sprintf (filename, "%s/clockdata", settings.localdir);
325 if ((fp = fopen (filename, "w")) == NULL)
326 {
327 LOG (llevError, "Cannot open %s for writing\n", filename);
328 return;
329 }
330 fprintf (fp, "%lu", todtick);
331 fclose (fp);
332 }
333
334 /*
335 * Initializes the gametime and TOD counters
336 * Called by init_library().
337 */
338
339 void
340 init_clocks (void)
341 {
342 char filename[MAX_BUF];
343 FILE *fp;
344 static int has_been_done = 0;
345
346 if (has_been_done)
347 return;
348 else
349 has_been_done = 1;
350
351 sprintf (filename, "%s/clockdata", settings.localdir);
352 LOG (llevDebug, "Reading clockdata from %s...", filename);
353 if ((fp = fopen (filename, "r")) == NULL)
354 {
355 LOG (llevError, "Can't open %s.\n", filename);
356 todtick = 0;
357 write_todclock ();
358 return;
359 }
360 fscanf (fp, "%lu", &todtick);
361 LOG (llevDebug, "todtick=%lu\n", todtick);
362 fclose (fp);
363 }
364
365 /*
366 * Initializes the attack messages.
367 * Called by init_library().
368 */
369
370 //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
371
372 void
373 init_attackmess (void)
374 {
375 char buf[MAX_BUF];
376 char filename[MAX_BUF];
377 char *cp, *p;
378 FILE *fp;
379 static int has_been_done = 0;
380 int mess, level, comp;
381 int mode = 0, total = 0;
382
383 if (has_been_done)
384 return;
385 else
386 has_been_done = 1;
387
388 sprintf (filename, "%s/attackmess", settings.datadir);
389 LOG (llevDebug, "Reading attack messages from %s...", filename);
390 if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL)
391 {
392 LOG (llevError, "Can't open %s.\n", filename);
393 return;
394 }
395
396 level = 0;
397 while (fgets (buf, MAX_BUF, fp) != NULL)
398 {
399 if (*buf == '#')
400 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 {
409 p = strtok (buf, ":");
410 p = strtok (NULL, ":");
411 if (mode == 1)
412 {
413 attack_mess[mess][level].level = -1;
414 attack_mess[mess][level].buf1 = NULL;
415 attack_mess[mess][level].buf2 = NULL;
416 attack_mess[mess][level].buf3 = NULL;
417 }
418 level = 0;
419 mess = atoi (p);
420 mode = 1;
421 continue;
422 }
423 if (mode == 1)
424 {
425 p = strtok (buf, "=");
426 attack_mess[mess][level].level = atoi (buf);
427 p = strtok (NULL, "=");
428 if (p != NULL)
429 attack_mess[mess][level].buf1 = strdup_local (p);
430 else
431 attack_mess[mess][level].buf1 = strdup_local ("");
432 mode = 2;
433 continue;
434 }
435 else if (mode == 2)
436 {
437 p = strtok (buf, "=");
438 attack_mess[mess][level].level = atoi (buf);
439 p = strtok (NULL, "=");
440 if (p != NULL)
441 attack_mess[mess][level].buf2 = strdup_local (p);
442 else
443 attack_mess[mess][level].buf2 = strdup_local ("");
444 mode = 3;
445 continue;
446 }
447 else if (mode == 3)
448 {
449 p = strtok (buf, "=");
450 attack_mess[mess][level].level = atoi (buf);
451 p = strtok (NULL, "=");
452 if (p != NULL)
453 attack_mess[mess][level].buf3 = strdup_local (p);
454 else
455 attack_mess[mess][level].buf3 = strdup_local ("");
456 mode = 1;
457 level++;
458 total++;
459 continue;
460 }
461 }
462 LOG (llevDebug, "got %d messages in %d categories.\n", total, mess + 1);
463 close_and_delete (fp, comp);
464 }