ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.25
Committed: Tue Mar 6 03:06:00 2007 UTC (17 years, 2 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.24: +0 -1 lines
Log Message:
- automake insists on naming all libdirs .../cfserver now. i have to concur :/
- correctly reattach to players on reload, this likely fixes the reload crash bug.
- init env vars very early, so perl gets to see them.

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_globals ();
153 init_block ();
154 ReadBmapNames ();
155 ReadSmooth ();
156 init_anim (); /* Must be after we read in the bitmaps */
157 init_archetypes (); /* Reads all archetypes from file */
158 init_dynamic ();
159 init_attackmess ();
160 init_clocks ();
161 init_experience ();
162 }
163
164
165 /* init_environ initialises values from the environmental variables.
166 * it needs to be called very early, since command line options should
167 * overwrite these if specified.
168 */
169 void
170 init_environ (void)
171 {
172 char *cp;
173
174 cp = getenv ("CROSSFIRE_LIBDIR");
175 if (cp)
176 settings.datadir = cp;
177 cp = getenv ("CROSSFIRE_LOCALDIR");
178 if (cp)
179 settings.localdir = cp;
180 cp = getenv ("CROSSFIRE_PLAYERDIR");
181 if (cp)
182 settings.playerdir = cp;
183 cp = getenv ("CROSSFIRE_MAPDIR");
184 if (cp)
185 settings.mapdir = cp;
186 cp = getenv ("CROSSFIRE_ARCHETYPES");
187 if (cp)
188 settings.archetypes = cp;
189 cp = getenv ("CROSSFIRE_TREASURES");
190 if (cp)
191 settings.treasures = cp;
192 cp = getenv ("CROSSFIRE_UNIQUEDIR");
193 if (cp)
194 settings.uniquedir = cp;
195 cp = getenv ("CROSSFIRE_TEMPLATEDIR");
196 if (cp)
197 settings.templatedir = cp;
198 cp = getenv ("CROSSFIRE_TMPDIR");
199 if (cp)
200 settings.tmpdir = cp;
201 }
202
203
204 /*
205 * Initialises all global variables.
206 * Might use environment-variables as default for some of them.
207 */
208
209 void
210 init_globals (void)
211 {
212 if (settings.logfilename[0] == 0)
213 logfile = stderr;
214 else if ((logfile = fopen (settings.logfilename, "a")) == NULL)
215 {
216 fprintf (stderr, "Unable to open %s as the logfile - will use stderr instead\n", settings.logfilename);
217 logfile = stderr;
218 }
219 else
220 setvbuf (logfile, NULL, _IOLBF, 0);
221 }
222
223 void
224 init_dynamic (void)
225 {
226 archetype *at = first_archetype;
227
228 while (at)
229 {
230 if (at->clone.type == MAP)
231 {
232 if (at->clone.race)
233 first_map_ext_path = at->clone.race;
234
235 if (EXIT_PATH (&at->clone))
236 {
237 first_map_path = EXIT_PATH (&at->clone);
238 return;
239 }
240 }
241
242 at = at->next;
243 }
244
245 LOG (llevDebug, "You Need a archetype called 'map' and it have to contain start map\n");
246 exit (-1);
247 }
248
249 unsigned long todtick;
250
251 /*
252 * Write out the current time to the file so time does not
253 * reset every time the server reboots.
254 */
255
256 void
257 write_todclock (void)
258 {
259 char filename[MAX_BUF];
260 FILE *fp;
261
262 sprintf (filename, "%s/clockdata", settings.localdir);
263 if ((fp = fopen (filename, "w")) == NULL)
264 {
265 LOG (llevError, "Cannot open %s for writing\n", filename);
266 return;
267 }
268 fprintf (fp, "%lu", todtick);
269 fclose (fp);
270 }
271
272 /*
273 * initialises the gametime and TOD counters
274 * Called by init_library().
275 */
276
277 void
278 init_clocks (void)
279 {
280 char filename[MAX_BUF];
281 FILE *fp;
282 static int has_been_done = 0;
283
284 if (has_been_done)
285 return;
286 else
287 has_been_done = 1;
288
289 sprintf (filename, "%s/clockdata", settings.localdir);
290 LOG (llevDebug, "Reading clockdata from %s...\n", filename);
291 if ((fp = fopen (filename, "r")) == NULL)
292 {
293 LOG (llevError, "Can't open %s.\n", filename);
294 todtick = 0;
295 write_todclock ();
296 return;
297 }
298 fscanf (fp, "%lu", &todtick);
299 LOG (llevDebug, "todtick=%lu\n", todtick);
300 fclose (fp);
301 }
302
303 /*
304 * initialises the attack messages.
305 * Called by init_library().
306 */
307
308 //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
309
310 void
311 init_attackmess (void)
312 {
313 char buf[MAX_BUF];
314 char filename[MAX_BUF];
315 char *cp, *p;
316 FILE *fp;
317 static int has_been_done = 0;
318 int mess, level, comp;
319 int mode = 0, total = 0;
320
321 if (has_been_done)
322 return;
323 else
324 has_been_done = 1;
325
326 sprintf (filename, "%s/attackmess", settings.datadir);
327 LOG (llevDebug, "Reading attack messages from %s...\n", filename);
328 if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL)
329 {
330 LOG (llevError, "Can't open %s.\n", filename);
331 return;
332 }
333
334 level = 0;
335 while (fgets (buf, MAX_BUF, fp) != NULL)
336 {
337 if (*buf == '#')
338 continue;
339 if ((cp = strchr (buf, '\n')) != NULL)
340 *cp = '\0';
341 cp = buf;
342 while (*cp == ' ') /* Skip blanks */
343 cp++;
344
345 if (strncmp (cp, "TYPE:", 5) == 0)
346 {
347 p = strtok (buf, ":");
348 p = strtok (NULL, ":");
349 if (mode == 1)
350 {
351 attack_mess[mess][level].level = -1;
352 attack_mess[mess][level].buf1 = NULL;
353 attack_mess[mess][level].buf2 = NULL;
354 attack_mess[mess][level].buf3 = NULL;
355 }
356 level = 0;
357 mess = atoi (p);
358 mode = 1;
359 continue;
360 }
361 if (mode == 1)
362 {
363 p = strtok (buf, "=");
364 attack_mess[mess][level].level = atoi (buf);
365 p = strtok (NULL, "=");
366 if (p != NULL)
367 attack_mess[mess][level].buf1 = strdup (p);
368 else
369 attack_mess[mess][level].buf1 = strdup ("");
370 mode = 2;
371 continue;
372 }
373 else if (mode == 2)
374 {
375 p = strtok (buf, "=");
376 attack_mess[mess][level].level = atoi (buf);
377 p = strtok (NULL, "=");
378 if (p != NULL)
379 attack_mess[mess][level].buf2 = strdup (p);
380 else
381 attack_mess[mess][level].buf2 = strdup ("");
382 mode = 3;
383 continue;
384 }
385 else if (mode == 3)
386 {
387 p = strtok (buf, "=");
388 attack_mess[mess][level].level = atoi (buf);
389 p = strtok (NULL, "=");
390 if (p != NULL)
391 attack_mess[mess][level].buf3 = strdup (p);
392 else
393 attack_mess[mess][level].buf3 = strdup ("");
394 mode = 1;
395 level++;
396 total++;
397 continue;
398 }
399 }
400 LOG (llevDebug, "got %d messages in %d categories.\n", total, mess + 1);
401 close_and_delete (fp, comp);
402 }