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

# 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     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 elmex 1.1 /* Armor enchantment stuff */
113 root 1.10 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 elmex 1.1 };
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 root 1.10 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 elmex 1.1 };
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 root 1.10 static void
158     init_emergency_mappath (void)
159 elmex 1.1 {
160 root 1.10 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 root 1.2 }
178 root 1.10 else if (online == 1)
179     {
180     settings.emergency_x = atoi (tmpbuf);
181 root 1.2 }
182    
183 root 1.10 else if (online == 2)
184     {
185     settings.emergency_y = atoi (tmpbuf);
186 root 1.2 }
187 root 1.10 online++;
188     if (online > 2)
189     break;
190 root 1.2 }
191 root 1.10 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 elmex 1.1 }
196     }
197 root 1.10
198 elmex 1.1
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 root 1.10 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 elmex 1.1 }
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 root 1.10 void
232     init_environ (void)
233     {
234     char *cp;
235 elmex 1.1
236 root 1.10 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 elmex 1.1 }
264 root 1.10
265 elmex 1.1
266     /*
267     * Initialises all global variables.
268     * Might use environment-variables as default for some of them.
269     */
270    
271 root 1.10 void
272     init_globals (void)
273     {
274     if (settings.logfilename[0] == 0)
275 root 1.12 logfile = stderr;
276 root 1.10 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 elmex 1.1 }
281 root 1.10 else
282 root 1.12 setvbuf (logfile, NULL, _IOLBF, 0);
283 elmex 1.1 }
284    
285 root 1.10 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 root 1.12 strcpy (first_map_ext_path, at->clone.race);
296    
297 root 1.10 if (EXIT_PATH (&at->clone))
298     {
299     strcpy (first_map_path, EXIT_PATH (&at->clone));
300     return;
301 elmex 1.1 }
302 root 1.2 }
303 root 1.12
304 root 1.10 at = at->next;
305 elmex 1.1 }
306 root 1.12
307 root 1.10 LOG (llevDebug, "You Need a archetype called 'map' and it have to contain start map\n");
308     exit (-1);
309 elmex 1.1 }
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 root 1.10 void
319     write_todclock (void)
320 elmex 1.1 {
321 root 1.10 char filename[MAX_BUF];
322     FILE *fp;
323 elmex 1.1
324 root 1.10 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 elmex 1.1 }
330 root 1.10 fprintf (fp, "%lu", todtick);
331     fclose (fp);
332 elmex 1.1 }
333    
334     /*
335     * Initializes the gametime and TOD counters
336     * Called by init_library().
337     */
338    
339 root 1.10 void
340     init_clocks (void)
341 elmex 1.1 {
342 root 1.10 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 elmex 1.1 }
360 root 1.10 fscanf (fp, "%lu", &todtick);
361     LOG (llevDebug, "todtick=%lu\n", todtick);
362     fclose (fp);
363 elmex 1.1 }
364    
365     /*
366     * Initializes the attack messages.
367     * Called by init_library().
368     */
369    
370     //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
371    
372 root 1.10 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 elmex 1.1 }
395    
396 root 1.10 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 root 1.2 }
418 root 1.10 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 root 1.2 }
447 root 1.10 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 root 1.2 }
461 elmex 1.1 }
462 root 1.10 LOG (llevDebug, "got %d messages in %d categories.\n", total, mess + 1);
463     close_and_delete (fp, comp);
464 elmex 1.1 }