ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.24
Committed: Fri Feb 16 19:43:40 2007 UTC (17 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.23: +0 -1 lines
Log Message:
- identified random memory corrutpion bug
- fixed most likely cause for bug above
- rewrote object loader etc. into a simple one-line lookahead
  parser.
- rewrote/cleaned up archetype, treasure, artifact, formula parser.
- some optimisations / cleanups

File Contents

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