ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.11
Committed: Wed Sep 13 02:05:18 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.10: +15 -21 lines
Log Message:
preliminary uuid support

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     The authors can be reached via e-mail at crossfire-devel@real-time.com
22     */
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     extern const keyword resist_save[NROFATTACKS] = {
36 root 1.11 # define def(uc, lc, name, plus, change) KW_resist_ ## lc,
37     # include "attackinc.h"
38     # undef def
39 root 1.7 };
40    
41 root 1.10 extern const char *const resist_plus[NROFATTACKS] = {
42 root 1.11 # define def(uc, lc, name, plus, change) # plus,
43     # include "attackinc.h"
44     # undef def
45 root 1.7 };
46    
47 root 1.10 extern const char *const change_resist_msg[NROFATTACKS] = {
48 root 1.11 # define def(uc, lc, name, plus, change) # change,
49     # include "attackinc.h"
50     # undef def
51 root 1.7 };
52    
53     int resist_table[NROFATTACKS] = {
54 root 1.11 # define def(uc, lc, name, plus, change) ATNR_ ## uc,
55     # include "attackinc.h"
56     # undef def
57 root 1.7 };
58    
59 elmex 1.1 /* You unforunately need to looking in include/global.h to see what these
60     * correspond to.
61     */
62     struct Settings settings = {
63 root 1.10 LOGFILE, /* Logfile */
64     CSPORT, /* Client/server port */
65 elmex 1.1
66     /* Debug level */
67     #ifdef DEBUG
68     llevDebug,
69     #else
70     llevInfo,
71     #endif
72    
73 root 1.10 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 elmex 1.1 /* Armor enchantment stuff */
119 root 1.10 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 elmex 1.1 };
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 root 1.10 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 elmex 1.1 };
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 root 1.10 static void
164     init_emergency_mappath (void)
165 elmex 1.1 {
166 root 1.10 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 root 1.2 }
184 root 1.10 else if (online == 1)
185     {
186     settings.emergency_x = atoi (tmpbuf);
187 root 1.2 }
188    
189 root 1.10 else if (online == 2)
190     {
191     settings.emergency_y = atoi (tmpbuf);
192 root 1.2 }
193 root 1.10 online++;
194     if (online > 2)
195     break;
196 root 1.2 }
197 root 1.10 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 elmex 1.1 }
202     }
203 root 1.10
204 elmex 1.1
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 root 1.10 void
215     init_library (void)
216     {
217     init_environ ();
218     init_globals ();
219     init_objects ();
220     init_vars ();
221     init_block ();
222     ReadBmapNames ();
223     ReadSmooth ();
224     init_anim (); /* Must be after we read in the bitmaps */
225     init_archetypes (); /* Reads all archetypes from file */
226     init_dynamic ();
227     init_attackmess ();
228     init_clocks ();
229     init_emergency_mappath ();
230     init_experience ();
231 elmex 1.1 }
232    
233    
234     /* init_environ initializes values from the environmental variables.
235     * it needs to be called very early, since command line options should
236     * overwrite these if specified.
237     */
238 root 1.10 void
239     init_environ (void)
240     {
241     char *cp;
242 elmex 1.1
243 root 1.10 cp = getenv ("CROSSFIRE_LIBDIR");
244     if (cp)
245     settings.datadir = cp;
246     cp = getenv ("CROSSFIRE_LOCALDIR");
247     if (cp)
248     settings.localdir = cp;
249     cp = getenv ("CROSSFIRE_PLAYERDIR");
250     if (cp)
251     settings.playerdir = cp;
252     cp = getenv ("CROSSFIRE_MAPDIR");
253     if (cp)
254     settings.mapdir = cp;
255     cp = getenv ("CROSSFIRE_ARCHETYPES");
256     if (cp)
257     settings.archetypes = cp;
258     cp = getenv ("CROSSFIRE_TREASURES");
259     if (cp)
260     settings.treasures = cp;
261     cp = getenv ("CROSSFIRE_UNIQUEDIR");
262     if (cp)
263     settings.uniquedir = cp;
264     cp = getenv ("CROSSFIRE_TEMPLATEDIR");
265     if (cp)
266     settings.templatedir = cp;
267     cp = getenv ("CROSSFIRE_TMPDIR");
268     if (cp)
269     settings.tmpdir = cp;
270 elmex 1.1 }
271 root 1.10
272 elmex 1.1
273     /*
274     * Initialises all global variables.
275     * Might use environment-variables as default for some of them.
276     */
277    
278 root 1.10 void
279     init_globals (void)
280     {
281     if (settings.logfilename[0] == 0)
282     {
283     logfile = stderr;
284 elmex 1.1 }
285 root 1.10 else if ((logfile = fopen (settings.logfilename, "a")) == NULL)
286     {
287     fprintf (stderr, "Unable to open %s as the logfile - will use stderr instead\n", settings.logfilename);
288     logfile = stderr;
289 elmex 1.1 }
290 root 1.10 else
291     {
292     setvbuf (logfile, NULL, _IOLBF, 0);
293 elmex 1.1 }
294 root 1.10 exiting = 0;
295     first_player = NULL;
296     first_friendly_object = NULL;
297     first_map = NULL;
298     first_treasurelist = NULL;
299     first_artifactlist = NULL;
300     first_archetype = NULL;
301     *first_map_ext_path = 0;
302     warn_archetypes = 0;
303     nroftreasures = 0;
304     nrofartifacts = 0;
305     nrofallowedstr = 0;
306     ring_arch = NULL;
307     amulet_arch = NULL;
308     staff_arch = NULL;
309     trying_emergency_save = 0;
310     num_animations = 0;
311     animations_allocated = 0;
312     init_defaults ();
313 elmex 1.1 }
314    
315     /*
316     * Sets up and initialises the linked list of free and used objects.
317     * Allocates a certain chunk of objects and puts them on the free list.
318     * Called by init_library();
319     */
320    
321 pippijn 1.6 void
322 root 1.10 init_objects (void)
323 pippijn 1.6 {
324     /* Initialize all objects: */
325     objects = NULL;
326 elmex 1.1 active_objects = NULL;
327     }
328    
329     /*
330     * Initialises global variables which can be changed by options.
331     * Called by init_library().
332     */
333    
334 root 1.10 void
335     init_defaults (void)
336     {
337     editor = 0;
338     nroferrors = 0;
339 elmex 1.1 }
340    
341    
342 root 1.10 void
343     init_dynamic (void)
344     {
345     archetype *at = first_archetype;
346    
347     while (at)
348     {
349     if (at->clone.type == MAP)
350     {
351     if (at->clone.race)
352     {
353     strcpy (first_map_ext_path, at->clone.race);
354 elmex 1.1 }
355 root 1.10 if (EXIT_PATH (&at->clone))
356     {
357     strcpy (first_map_path, EXIT_PATH (&at->clone));
358     return;
359 elmex 1.1 }
360 root 1.2 }
361 root 1.10 at = at->next;
362 elmex 1.1 }
363 root 1.10 LOG (llevDebug, "You Need a archetype called 'map' and it have to contain start map\n");
364     exit (-1);
365 elmex 1.1 }
366    
367     unsigned long todtick;
368    
369     /*
370     * Write out the current time to the file so time does not
371     * reset every time the server reboots.
372     */
373    
374 root 1.10 void
375     write_todclock (void)
376 elmex 1.1 {
377 root 1.10 char filename[MAX_BUF];
378     FILE *fp;
379 elmex 1.1
380 root 1.10 sprintf (filename, "%s/clockdata", settings.localdir);
381     if ((fp = fopen (filename, "w")) == NULL)
382     {
383     LOG (llevError, "Cannot open %s for writing\n", filename);
384     return;
385 elmex 1.1 }
386 root 1.10 fprintf (fp, "%lu", todtick);
387     fclose (fp);
388 elmex 1.1 }
389    
390     /*
391     * Initializes the gametime and TOD counters
392     * Called by init_library().
393     */
394    
395 root 1.10 void
396     init_clocks (void)
397 elmex 1.1 {
398 root 1.10 char filename[MAX_BUF];
399     FILE *fp;
400     static int has_been_done = 0;
401    
402     if (has_been_done)
403     return;
404     else
405     has_been_done = 1;
406    
407     sprintf (filename, "%s/clockdata", settings.localdir);
408     LOG (llevDebug, "Reading clockdata from %s...", filename);
409     if ((fp = fopen (filename, "r")) == NULL)
410     {
411     LOG (llevError, "Can't open %s.\n", filename);
412     todtick = 0;
413     write_todclock ();
414     return;
415 elmex 1.1 }
416 root 1.10 fscanf (fp, "%lu", &todtick);
417     LOG (llevDebug, "todtick=%lu\n", todtick);
418     fclose (fp);
419 elmex 1.1 }
420    
421     /*
422     * Initializes the attack messages.
423     * Called by init_library().
424     */
425    
426     //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
427    
428 root 1.10 void
429     init_attackmess (void)
430     {
431     char buf[MAX_BUF];
432     char filename[MAX_BUF];
433     char *cp, *p;
434     FILE *fp;
435     static int has_been_done = 0;
436     int mess, level, comp;
437     int mode = 0, total = 0;
438    
439     if (has_been_done)
440     return;
441     else
442     has_been_done = 1;
443    
444     sprintf (filename, "%s/attackmess", settings.datadir);
445     LOG (llevDebug, "Reading attack messages from %s...", filename);
446     if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL)
447     {
448     LOG (llevError, "Can't open %s.\n", filename);
449     return;
450 elmex 1.1 }
451    
452 root 1.10 level = 0;
453     while (fgets (buf, MAX_BUF, fp) != NULL)
454     {
455     if (*buf == '#')
456     continue;
457     if ((cp = strchr (buf, '\n')) != NULL)
458     *cp = '\0';
459     cp = buf;
460     while (*cp == ' ') /* Skip blanks */
461     cp++;
462    
463     if (strncmp (cp, "TYPE:", 5) == 0)
464     {
465     p = strtok (buf, ":");
466     p = strtok (NULL, ":");
467     if (mode == 1)
468     {
469     attack_mess[mess][level].level = -1;
470     attack_mess[mess][level].buf1 = NULL;
471     attack_mess[mess][level].buf2 = NULL;
472     attack_mess[mess][level].buf3 = NULL;
473 root 1.2 }
474 root 1.10 level = 0;
475     mess = atoi (p);
476     mode = 1;
477     continue;
478     }
479     if (mode == 1)
480     {
481     p = strtok (buf, "=");
482     attack_mess[mess][level].level = atoi (buf);
483     p = strtok (NULL, "=");
484     if (p != NULL)
485     attack_mess[mess][level].buf1 = strdup_local (p);
486     else
487     attack_mess[mess][level].buf1 = strdup_local ("");
488     mode = 2;
489     continue;
490     }
491     else if (mode == 2)
492     {
493     p = strtok (buf, "=");
494     attack_mess[mess][level].level = atoi (buf);
495     p = strtok (NULL, "=");
496     if (p != NULL)
497     attack_mess[mess][level].buf2 = strdup_local (p);
498     else
499     attack_mess[mess][level].buf2 = strdup_local ("");
500     mode = 3;
501     continue;
502 root 1.2 }
503 root 1.10 else if (mode == 3)
504     {
505     p = strtok (buf, "=");
506     attack_mess[mess][level].level = atoi (buf);
507     p = strtok (NULL, "=");
508     if (p != NULL)
509     attack_mess[mess][level].buf3 = strdup_local (p);
510     else
511     attack_mess[mess][level].buf3 = strdup_local ("");
512     mode = 1;
513     level++;
514     total++;
515     continue;
516 root 1.2 }
517 elmex 1.1 }
518 root 1.10 LOG (llevDebug, "got %d messages in %d categories.\n", total, mess + 1);
519     close_and_delete (fp, comp);
520 elmex 1.1 }