ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.c
Revision: 1.2
Committed: Fri Feb 3 07:25:24 2006 UTC (18 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.1: +2 -1 lines
Log Message:
initial cfperl/cf.schmorp.de import

File Contents

# Content
1 /*
2 * static char *rcsid_init_c =
3 * "$Id: init.c,v 1.1.1.1 2006/02/03 07:11:31 root Exp $";
4 */
5
6 /*
7 CrossFire, A Multiplayer game for X-windows
8
9 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 The authors can be reached via e-mail at crossfire-devel@real-time.com
27 */
28
29 #define EXTERN
30 #define INIT_C
31 #include <global.h>
32 #include <object.h>
33
34 /* You unforunately need to looking in include/global.h to see what these
35 * correspond to.
36 */
37 struct Settings settings = {
38 LOGFILE, /* Logfile */
39 CSPORT, /* Client/server port */
40
41 /* Debug level */
42 #ifdef DEBUG
43 llevDebug,
44 #else
45 llevInfo,
46 #endif
47
48 0, NULL, 0, /* dumpvalues, dumparg, daemonmode */
49 0, /* argc */
50 NULL, /* argv */
51 CONFDIR,
52 DATADIR,
53 LOCALDIR,
54 PLAYERDIR, MAPDIR, ARCHETYPES,REGIONS,TREASURES,
55 UNIQUE_DIR, TEMPLATE_DIR,
56 TMPDIR,
57 STAT_LOSS_ON_DEATH,
58 PK_LUCK_PENALTY,
59 USE_PERMANENT_EXPERIENCE,
60 BALANCED_STAT_LOSS,
61 NOT_PERMADETH,
62 SIMPLE_EXP,
63 RESET_LOCATION_TIME,
64 SET_TITLE,
65 RESURRECTION,
66 SEARCH_ITEMS,
67 SPELL_ENCUMBRANCE,
68 SPELL_FAILURE_EFFECTS,
69 CASTING_TIME,
70 REAL_WIZ,
71 RECYCLE_TMP_MAPS,
72 EXPLORE_MODE,
73 SPELLPOINT_LEVEL_DEPEND,
74 SET_FRIENDLY_FIRE,
75 "", /* Who format specifier */
76 "", /* who wiz format specifier */
77 MOTD,
78 "rules",
79 "news",
80 "", /* DM_MAIL */
81 0, /* This and the next 3 values are metaserver values */
82 "",
83 "",
84 0,
85 "",
86 0,0,0,0,0,0,0,0, /* worldmap settings*/
87 EMERGENCY_MAPPATH, EMERGENCY_X, EMERGENCY_Y,
88 0,
89 1.0,
90 /* Armor enchantment stuff */
91 ARMOR_MAX_ENCHANT,
92 ARMOR_WEIGHT_REDUCTION,
93 ARMOR_WEIGHT_LINEAR,
94 ARMOR_SPEED_IMPROVEMENT,
95 ARMOR_SPEED_LINEAR,
96 1, /* no_player_stealing */
97 };
98
99 /* perhaps not the best place for this, but needs to be
100 * in some file in the common area so that standalone
101 * programs, like the random map generator, can be built.
102 */
103 char *spellpathnames[NRSPELLPATHS] = {
104 "Protection",
105 "Fire",
106 "Frost",
107 "Electricity",
108 "Missiles",
109 "Self",
110 "Summoning",
111 "Abjuration",
112 "Restoration",
113 "Detonation",
114 "Mind",
115 "Creation",
116 "Teleportation",
117 "Information",
118 "Transmutation",
119 "Transferrence",
120 "Turning",
121 "Wounding",
122 "Death",
123 "Light"
124 };
125
126
127 /* This loads the emergency map information from a
128 * .emergency file in the map directory. Doing this makes
129 * it easier to switch between map distributions (don't need
130 * to recompile. Note that there is no reason I see that
131 * this could not be re-loaded during play, but it seems
132 * like there should be little reason to do that.
133 */
134 static void init_emergency_mappath(void)
135 {
136 char filename[MAX_BUF], tmpbuf[MAX_BUF];
137 FILE *fp;
138 int online=0;
139
140 /* If this file doesn't exist, not a big deal */
141 sprintf(filename,"%s/%s/.emergency",settings.datadir, settings.mapdir);
142 if ((fp = fopen(filename, "r"))!=NULL) {
143 while (fgets(tmpbuf, MAX_BUF-1, fp)) {
144 if (tmpbuf[0] == '#') continue; /* ignore comments */
145
146 if (online == 0) {
147 tmpbuf[strlen(tmpbuf)-1] = 0; /* kill newline */
148 settings.emergency_mapname = strdup_local(tmpbuf);
149 }
150 else if (online == 1) {
151 settings.emergency_x = atoi(tmpbuf);
152 }
153
154 else if (online == 2) {
155 settings.emergency_y = atoi(tmpbuf);
156 }
157 online++;
158 if (online>2) break;
159 }
160 fclose(fp);
161 if (online<=2)
162 LOG(llevError,"Online read partial data from %s\n", filename);
163 LOG(llevDebug,"Emergency mappath reset to %s (%d, %d)\n", settings.emergency_mapname,
164 settings.emergency_x, settings.emergency_y);
165 }
166 }
167
168
169 /*
170 * It is vital that init_library() is called by any functions
171 * using this library.
172 * If you want to lessen the size of the program using the library,
173 * you can replace the call to init_library() with init_globals() and
174 * init_function_pointers(). Good idea to also call init_vars and
175 * init_hash_table if you are doing any object loading.
176 */
177
178 void init_library(void) {
179 init_environ();
180 init_globals();
181 init_hash_table();
182 init_objects();
183 init_vars();
184 init_block();
185 ReadBmapNames ();
186 ReadSmooth();
187 init_anim(); /* Must be after we read in the bitmaps */
188 init_archetypes(); /* Reads all archetypes from file */
189 init_dynamic ();
190 init_attackmess();
191 init_clocks();
192 init_emergency_mappath();
193 init_experience();
194 }
195
196
197 /* init_environ initializes values from the environmental variables.
198 * it needs to be called very early, since command line options should
199 * overwrite these if specified.
200 */
201 void init_environ(void) {
202 char *cp;
203
204 cp=getenv("CROSSFIRE_LIBDIR");
205 if (cp) settings.datadir=cp;
206 cp=getenv("CROSSFIRE_LOCALDIR");
207 if (cp) settings.localdir=cp;
208 cp=getenv("CROSSFIRE_PLAYERDIR");
209 if (cp) settings.playerdir=cp;
210 cp=getenv("CROSSFIRE_MAPDIR");
211 if (cp) settings.mapdir=cp;
212 cp=getenv("CROSSFIRE_ARCHETYPES");
213 if (cp) settings.archetypes=cp;
214 cp=getenv("CROSSFIRE_TREASURES");
215 if (cp) settings.treasures=cp;
216 cp=getenv("CROSSFIRE_UNIQUEDIR");
217 if (cp) settings.uniquedir=cp;
218 cp=getenv("CROSSFIRE_TEMPLATEDIR");
219 if (cp) settings.templatedir=cp;
220 cp=getenv("CROSSFIRE_TMPDIR");
221 if (cp) settings.tmpdir=cp;
222 }
223
224
225 /*
226 * Initialises all global variables.
227 * Might use environment-variables as default for some of them.
228 */
229
230 void init_globals(void) {
231 if (settings.logfilename[0] == 0) {
232 logfile = stderr;
233 }
234 else if ((logfile=fopen(settings.logfilename, "a"))==NULL) {
235 fprintf(stderr,"Unable to open %s as the logfile - will use stderr instead\n",
236 settings.logfilename);
237 logfile = stderr;
238 }
239 setlinebuf(logfile);
240 exiting = 0;
241 first_player=NULL;
242 first_friendly_object=NULL;
243 first_map=NULL;
244 first_treasurelist=NULL;
245 first_artifactlist=NULL;
246 first_archetype=NULL;
247 warn_archetypes=0;
248 first_map=NULL;
249 nroftreasures = 0;
250 nrofartifacts = 0;
251 nrofallowedstr=0;
252 ring_arch = NULL;
253 amulet_arch = NULL;
254 staff_arch = NULL;
255 undead_name = add_string("undead");
256 trying_emergency_save = 0;
257 num_animations=0;
258 animations=NULL;
259 animations_allocated=0;
260 init_defaults();
261 }
262
263 /*
264 * Sets up and initialises the linked list of free and used objects.
265 * Allocates a certain chunk of objects and puts them on the free list.
266 * Called by init_library();
267 */
268
269 void init_objects(void) {
270 int i;
271 /* Initialize all objects: */
272 objects=NULL;
273 active_objects = NULL;
274
275 #ifdef MEMORY_DEBUG
276 free_objects=NULL;
277 #else
278 free_objects=objarray;
279 objarray[0].prev=NULL,
280 objarray[0].next= &objarray[1],
281 SET_FLAG(&objarray[0], FLAG_REMOVED);
282 SET_FLAG(&objarray[0], FLAG_FREED);
283 for(i=1;i<STARTMAX-1;i++) {
284 objarray[i].next= &objarray[i+1];
285 objarray[i].prev= &objarray[i-1];
286 SET_FLAG(&objarray[i], FLAG_REMOVED);
287 SET_FLAG(&objarray[i], FLAG_FREED);
288 }
289 objarray[STARTMAX-1].next=NULL;
290 objarray[STARTMAX-1].prev= &objarray[STARTMAX-2];
291 SET_FLAG(&objarray[STARTMAX-1], FLAG_REMOVED);
292 SET_FLAG(&objarray[STARTMAX-1], FLAG_FREED);
293 #endif
294 }
295
296 /*
297 * Initialises global variables which can be changed by options.
298 * Called by init_library().
299 */
300
301 void init_defaults(void) {
302 editor=0;
303 nroferrors=0;
304 }
305
306
307 void init_dynamic (void) {
308 archetype *at = first_archetype;
309 while (at) {
310 if (at->clone.type == MAP && EXIT_PATH (&at->clone)) {
311 strcpy (first_map_path, EXIT_PATH (&at->clone));
312 return;
313 }
314 at = at->next;
315 }
316 LOG(llevDebug,"You Need a archetype called 'map' and it have to contain start map\n");
317 exit (-1);
318 }
319
320 unsigned long todtick;
321
322 /*
323 * Write out the current time to the file so time does not
324 * reset every time the server reboots.
325 */
326
327 void write_todclock(void)
328 {
329 char filename[MAX_BUF];
330 FILE *fp;
331
332 sprintf(filename, "%s/clockdata", settings.localdir);
333 if ((fp = fopen(filename, "w")) == NULL) {
334 LOG(llevError, "Cannot open %s for writing\n", filename);
335 return;
336 }
337 fprintf(fp, "%lu", todtick);
338 fclose(fp);
339 }
340
341 /*
342 * Initializes the gametime and TOD counters
343 * Called by init_library().
344 */
345
346 void init_clocks(void)
347 {
348 char filename[MAX_BUF];
349 FILE *fp;
350 static int has_been_done=0;
351
352 if (has_been_done)
353 return;
354 else
355 has_been_done = 1;
356
357 sprintf(filename, "%s/clockdata", settings.localdir);
358 LOG(llevDebug, "Reading clockdata from %s...", filename);
359 if ((fp = fopen(filename, "r")) == NULL) {
360 LOG(llevError, "Can't open %s.\n", filename);
361 todtick = 0;
362 write_todclock();
363 return;
364 }
365 fscanf(fp, "%lu", &todtick);
366 LOG(llevDebug, "todtick=%lu\n", todtick);
367 fclose(fp);
368 }
369
370 /*
371 * Initializes the attack messages.
372 * Called by init_library().
373 */
374
375 attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
376
377 void init_attackmess(void){
378 char buf[MAX_BUF];
379 char filename[MAX_BUF];
380 char *cp, *p;
381 FILE *fp;
382 static int has_been_done=0;
383 int mess, level, comp;
384 int mode=0, total=0;
385
386 if (has_been_done)
387 return;
388 else
389 has_been_done = 1;
390
391 sprintf(filename, "%s/attackmess", settings.datadir);
392 LOG(llevDebug, "Reading attack messages from %s...", filename);
393 if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) {
394 LOG(llevError, "Can't open %s.\n", filename);
395 return;
396 }
397
398 level = 0;
399 while (fgets(buf, MAX_BUF, fp)!=NULL) {
400 if (*buf=='#') 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 p = strtok(buf, ":");
409 p = strtok(NULL, ":");
410 if (mode == 1) {
411 attack_mess[mess][level].level = -1;
412 attack_mess[mess][level].buf1 = NULL;
413 attack_mess[mess][level].buf2 = NULL;
414 attack_mess[mess][level].buf3 = NULL;
415 }
416 level = 0;
417 mess = atoi(p);
418 mode = 1;
419 continue;
420 }
421 if (mode==1) {
422 p = strtok(buf, "=");
423 attack_mess[mess][level].level = atoi(buf);
424 p = strtok(NULL, "=");
425 if (p != NULL)
426 attack_mess[mess][level].buf1 = strdup_local(p);
427 else
428 attack_mess[mess][level].buf1 = strdup_local("");
429 mode = 2;
430 continue;
431 } else if (mode==2) {
432 p = strtok(buf, "=");
433 attack_mess[mess][level].level = atoi(buf);
434 p = strtok(NULL, "=");
435 if (p != NULL)
436 attack_mess[mess][level].buf2 = strdup_local(p);
437 else
438 attack_mess[mess][level].buf2 = strdup_local("");
439 mode = 3;
440 continue;
441 } else if (mode==3) {
442 p = strtok(buf, "=");
443 attack_mess[mess][level].level = atoi(buf);
444 p = strtok(NULL, "=");
445 if (p != NULL)
446 attack_mess[mess][level].buf3 = strdup_local(p);
447 else
448 attack_mess[mess][level].buf3 = strdup_local("");
449 mode = 1;
450 level++;
451 total++;
452 continue;
453 }
454 }
455 LOG(llevDebug, "got %d messages in %d categories.\n", total, mess+1);
456 close_and_delete(fp, comp);
457 }