ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.17
Committed: Mon Dec 18 02:35:00 2006 UTC (17 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.16: +0 -1 lines
Log Message:
- remove recycle_tmp_maps setting (hardwired to true)
- replace object->flags by std::bitset, seems to be way
  more efficient, for some unexplainable and not looked-into reason.
  its way cleaner, too...

File Contents

# User Rev Content
1 elmex 1.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 root 1.13 The authors can be reached via e-mail at <crossfire@schmorp.de>
22 elmex 1.1 */
23    
24 root 1.10 #define EXTERN // horrible hack
25 root 1.7
26 elmex 1.1 #include <global.h>
27     #include <object.h>
28    
29 root 1.10 extern const char *const attacktype_desc[NROFATTACKS] = {
30 root 1.11 # define def(uc, lc, name, plus, change) # name,
31     # include "attackinc.h"
32     # undef def
33 root 1.7 };
34    
35 root 1.10 extern const char *const resist_plus[NROFATTACKS] = {
36 root 1.11 # define def(uc, lc, name, plus, change) # plus,
37     # include "attackinc.h"
38     # undef def
39 root 1.7 };
40    
41 root 1.10 extern const char *const change_resist_msg[NROFATTACKS] = {
42 root 1.11 # define def(uc, lc, name, plus, change) # change,
43     # include "attackinc.h"
44     # undef def
45 root 1.7 };
46    
47     int resist_table[NROFATTACKS] = {
48 root 1.11 # define def(uc, lc, name, plus, change) ATNR_ ## uc,
49     # include "attackinc.h"
50     # undef def
51 root 1.7 };
52    
53 elmex 1.1 /* You unforunately need to looking in include/global.h to see what these
54     * correspond to.
55     */
56     struct Settings settings = {
57 root 1.10 LOGFILE, /* Logfile */
58     CSPORT, /* Client/server port */
59 elmex 1.1
60     /* Debug level */
61     #ifdef DEBUG
62     llevDebug,
63     #else
64     llevInfo,
65     #endif
66    
67 root 1.10 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     EXPLORE_MODE,
93     SPELLPOINT_LEVEL_DEPEND,
94     SET_FRIENDLY_FIRE,
95     MOTD,
96     "rules",
97     "news",
98     "", /* DM_MAIL */
99     0, 0, 0, 0, 0, 0, 0, 0, /* worldmap settings */
100     EMERGENCY_MAPPATH, EMERGENCY_X, EMERGENCY_Y,
101     0,
102     1.0,
103    
104 elmex 1.1 /* Armor enchantment stuff */
105 root 1.10 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 elmex 1.1 };
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 root 1.10 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 elmex 1.1 };
140    
141    
142     /* This loads the emergency map information from a
143     * .emergency file in the map directory. Doing this makes
144     * it easier to switch between map distributions (don't need
145     * to recompile. Note that there is no reason I see that
146     * this could not be re-loaded during play, but it seems
147     * like there should be little reason to do that.
148     */
149 root 1.10 static void
150     init_emergency_mappath (void)
151 elmex 1.1 {
152 root 1.10 char filename[MAX_BUF], tmpbuf[MAX_BUF];
153     FILE *fp;
154     int online = 0;
155    
156     /* If this file doesn't exist, not a big deal */
157     sprintf (filename, "%s/%s/.emergency", settings.datadir, settings.mapdir);
158     if ((fp = fopen (filename, "r")) != NULL)
159     {
160     while (fgets (tmpbuf, MAX_BUF - 1, fp))
161     {
162     if (tmpbuf[0] == '#')
163     continue; /* ignore comments */
164    
165     if (online == 0)
166     {
167     tmpbuf[strlen (tmpbuf) - 1] = 0; /* kill newline */
168 root 1.16 settings.emergency_mapname = strdup (tmpbuf);
169 root 1.2 }
170 root 1.10 else if (online == 1)
171     {
172     settings.emergency_x = atoi (tmpbuf);
173 root 1.2 }
174    
175 root 1.10 else if (online == 2)
176     {
177     settings.emergency_y = atoi (tmpbuf);
178 root 1.2 }
179 root 1.10 online++;
180     if (online > 2)
181     break;
182 root 1.2 }
183 root 1.10 fclose (fp);
184     if (online <= 2)
185     LOG (llevError, "Online read partial data from %s\n", filename);
186     LOG (llevDebug, "Emergency mappath reset to %s (%d, %d)\n", settings.emergency_mapname, settings.emergency_x, settings.emergency_y);
187 elmex 1.1 }
188     }
189 root 1.10
190 elmex 1.1
191     /*
192     * It is vital that init_library() is called by any functions
193     * using this library.
194     * If you want to lessen the size of the program using the library,
195     * you can replace the call to init_library() with init_globals() and
196     * init_function_pointers(). Good idea to also call init_vars and
197     * init_hash_table if you are doing any object loading.
198     */
199    
200 root 1.10 void
201     init_library (void)
202     {
203     init_environ ();
204     init_globals ();
205     init_vars ();
206     init_block ();
207     ReadBmapNames ();
208     ReadSmooth ();
209     init_anim (); /* Must be after we read in the bitmaps */
210     init_archetypes (); /* Reads all archetypes from file */
211     init_dynamic ();
212     init_attackmess ();
213     init_clocks ();
214     init_emergency_mappath ();
215     init_experience ();
216 elmex 1.1 }
217    
218    
219     /* init_environ initializes values from the environmental variables.
220     * it needs to be called very early, since command line options should
221     * overwrite these if specified.
222     */
223 root 1.10 void
224     init_environ (void)
225     {
226     char *cp;
227 elmex 1.1
228 root 1.10 cp = getenv ("CROSSFIRE_LIBDIR");
229     if (cp)
230     settings.datadir = cp;
231     cp = getenv ("CROSSFIRE_LOCALDIR");
232     if (cp)
233     settings.localdir = cp;
234     cp = getenv ("CROSSFIRE_PLAYERDIR");
235     if (cp)
236     settings.playerdir = cp;
237     cp = getenv ("CROSSFIRE_MAPDIR");
238     if (cp)
239     settings.mapdir = cp;
240     cp = getenv ("CROSSFIRE_ARCHETYPES");
241     if (cp)
242     settings.archetypes = cp;
243     cp = getenv ("CROSSFIRE_TREASURES");
244     if (cp)
245     settings.treasures = cp;
246     cp = getenv ("CROSSFIRE_UNIQUEDIR");
247     if (cp)
248     settings.uniquedir = cp;
249     cp = getenv ("CROSSFIRE_TEMPLATEDIR");
250     if (cp)
251     settings.templatedir = cp;
252     cp = getenv ("CROSSFIRE_TMPDIR");
253     if (cp)
254     settings.tmpdir = cp;
255 elmex 1.1 }
256 root 1.10
257 elmex 1.1
258     /*
259     * Initialises all global variables.
260     * Might use environment-variables as default for some of them.
261     */
262    
263 root 1.10 void
264     init_globals (void)
265     {
266     if (settings.logfilename[0] == 0)
267 root 1.12 logfile = stderr;
268 root 1.10 else if ((logfile = fopen (settings.logfilename, "a")) == NULL)
269     {
270     fprintf (stderr, "Unable to open %s as the logfile - will use stderr instead\n", settings.logfilename);
271     logfile = stderr;
272 elmex 1.1 }
273 root 1.10 else
274 root 1.12 setvbuf (logfile, NULL, _IOLBF, 0);
275 elmex 1.1 }
276    
277 root 1.10 void
278     init_dynamic (void)
279     {
280     archetype *at = first_archetype;
281    
282     while (at)
283     {
284     if (at->clone.type == MAP)
285     {
286     if (at->clone.race)
287 root 1.12 strcpy (first_map_ext_path, at->clone.race);
288    
289 root 1.10 if (EXIT_PATH (&at->clone))
290     {
291     strcpy (first_map_path, EXIT_PATH (&at->clone));
292     return;
293 elmex 1.1 }
294 root 1.2 }
295 root 1.12
296 root 1.10 at = at->next;
297 elmex 1.1 }
298 root 1.12
299 root 1.10 LOG (llevDebug, "You Need a archetype called 'map' and it have to contain start map\n");
300     exit (-1);
301 elmex 1.1 }
302    
303     unsigned long todtick;
304    
305     /*
306     * Write out the current time to the file so time does not
307     * reset every time the server reboots.
308     */
309    
310 root 1.10 void
311     write_todclock (void)
312 elmex 1.1 {
313 root 1.10 char filename[MAX_BUF];
314     FILE *fp;
315 elmex 1.1
316 root 1.10 sprintf (filename, "%s/clockdata", settings.localdir);
317     if ((fp = fopen (filename, "w")) == NULL)
318     {
319     LOG (llevError, "Cannot open %s for writing\n", filename);
320     return;
321 elmex 1.1 }
322 root 1.10 fprintf (fp, "%lu", todtick);
323     fclose (fp);
324 elmex 1.1 }
325    
326     /*
327     * Initializes the gametime and TOD counters
328     * Called by init_library().
329     */
330    
331 root 1.10 void
332     init_clocks (void)
333 elmex 1.1 {
334 root 1.10 char filename[MAX_BUF];
335     FILE *fp;
336     static int has_been_done = 0;
337    
338     if (has_been_done)
339     return;
340     else
341     has_been_done = 1;
342    
343     sprintf (filename, "%s/clockdata", settings.localdir);
344     LOG (llevDebug, "Reading clockdata from %s...", filename);
345     if ((fp = fopen (filename, "r")) == NULL)
346     {
347     LOG (llevError, "Can't open %s.\n", filename);
348     todtick = 0;
349     write_todclock ();
350     return;
351 elmex 1.1 }
352 root 1.10 fscanf (fp, "%lu", &todtick);
353     LOG (llevDebug, "todtick=%lu\n", todtick);
354     fclose (fp);
355 elmex 1.1 }
356    
357     /*
358     * Initializes the attack messages.
359     * Called by init_library().
360     */
361    
362     //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
363    
364 root 1.10 void
365     init_attackmess (void)
366     {
367     char buf[MAX_BUF];
368     char filename[MAX_BUF];
369     char *cp, *p;
370     FILE *fp;
371     static int has_been_done = 0;
372     int mess, level, comp;
373     int mode = 0, total = 0;
374    
375     if (has_been_done)
376     return;
377     else
378     has_been_done = 1;
379    
380     sprintf (filename, "%s/attackmess", settings.datadir);
381     LOG (llevDebug, "Reading attack messages from %s...", filename);
382     if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL)
383     {
384     LOG (llevError, "Can't open %s.\n", filename);
385     return;
386 elmex 1.1 }
387    
388 root 1.10 level = 0;
389     while (fgets (buf, MAX_BUF, fp) != NULL)
390     {
391     if (*buf == '#')
392     continue;
393     if ((cp = strchr (buf, '\n')) != NULL)
394     *cp = '\0';
395     cp = buf;
396     while (*cp == ' ') /* Skip blanks */
397     cp++;
398    
399     if (strncmp (cp, "TYPE:", 5) == 0)
400     {
401     p = strtok (buf, ":");
402     p = strtok (NULL, ":");
403     if (mode == 1)
404     {
405     attack_mess[mess][level].level = -1;
406     attack_mess[mess][level].buf1 = NULL;
407     attack_mess[mess][level].buf2 = NULL;
408     attack_mess[mess][level].buf3 = NULL;
409 root 1.2 }
410 root 1.10 level = 0;
411     mess = atoi (p);
412     mode = 1;
413     continue;
414     }
415     if (mode == 1)
416     {
417     p = strtok (buf, "=");
418     attack_mess[mess][level].level = atoi (buf);
419     p = strtok (NULL, "=");
420     if (p != NULL)
421 root 1.16 attack_mess[mess][level].buf1 = strdup (p);
422 root 1.10 else
423 root 1.16 attack_mess[mess][level].buf1 = strdup ("");
424 root 1.10 mode = 2;
425     continue;
426     }
427     else if (mode == 2)
428     {
429     p = strtok (buf, "=");
430     attack_mess[mess][level].level = atoi (buf);
431     p = strtok (NULL, "=");
432     if (p != NULL)
433 root 1.16 attack_mess[mess][level].buf2 = strdup (p);
434 root 1.10 else
435 root 1.16 attack_mess[mess][level].buf2 = strdup ("");
436 root 1.10 mode = 3;
437     continue;
438 root 1.2 }
439 root 1.10 else if (mode == 3)
440     {
441     p = strtok (buf, "=");
442     attack_mess[mess][level].level = atoi (buf);
443     p = strtok (NULL, "=");
444     if (p != NULL)
445 root 1.16 attack_mess[mess][level].buf3 = strdup (p);
446 root 1.10 else
447 root 1.16 attack_mess[mess][level].buf3 = strdup ("");
448 root 1.10 mode = 1;
449     level++;
450     total++;
451     continue;
452 root 1.2 }
453 elmex 1.1 }
454 root 1.10 LOG (llevDebug, "got %d messages in %d categories.\n", total, mess + 1);
455     close_and_delete (fp, comp);
456 elmex 1.1 }