ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.c
Revision: 1.1.1.1 (vendor branch)
Committed: Fri Feb 3 07:11:31 2006 UTC (18 years, 3 months ago) by root
Content type: text/plain
Branch: UPSTREAM
CVS Tags: UPSTREAM_2006_02_03
Changes since 1.1: +0 -0 lines
Log Message:
initial import

File Contents

# Content
1 /*
2 * static char *rcsid_init_c =
3 * "$Id: init.c,v 1.45 2006/01/08 20:52:11 akirschbaum 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 exiting = 0;
240 first_player=NULL;
241 first_friendly_object=NULL;
242 first_map=NULL;
243 first_treasurelist=NULL;
244 first_artifactlist=NULL;
245 first_archetype=NULL;
246 warn_archetypes=0;
247 first_map=NULL;
248 nroftreasures = 0;
249 nrofartifacts = 0;
250 nrofallowedstr=0;
251 ring_arch = NULL;
252 amulet_arch = NULL;
253 staff_arch = NULL;
254 undead_name = add_string("undead");
255 trying_emergency_save = 0;
256 num_animations=0;
257 animations=NULL;
258 animations_allocated=0;
259 init_defaults();
260 }
261
262 /*
263 * Sets up and initialises the linked list of free and used objects.
264 * Allocates a certain chunk of objects and puts them on the free list.
265 * Called by init_library();
266 */
267
268 void init_objects(void) {
269 int i;
270 /* Initialize all objects: */
271 objects=NULL;
272 active_objects = NULL;
273
274 #ifdef MEMORY_DEBUG
275 free_objects=NULL;
276 #else
277 free_objects=objarray;
278 objarray[0].prev=NULL,
279 objarray[0].next= &objarray[1],
280 SET_FLAG(&objarray[0], FLAG_REMOVED);
281 SET_FLAG(&objarray[0], FLAG_FREED);
282 for(i=1;i<STARTMAX-1;i++) {
283 objarray[i].next= &objarray[i+1];
284 objarray[i].prev= &objarray[i-1];
285 SET_FLAG(&objarray[i], FLAG_REMOVED);
286 SET_FLAG(&objarray[i], FLAG_FREED);
287 }
288 objarray[STARTMAX-1].next=NULL;
289 objarray[STARTMAX-1].prev= &objarray[STARTMAX-2];
290 SET_FLAG(&objarray[STARTMAX-1], FLAG_REMOVED);
291 SET_FLAG(&objarray[STARTMAX-1], FLAG_FREED);
292 #endif
293 }
294
295 /*
296 * Initialises global variables which can be changed by options.
297 * Called by init_library().
298 */
299
300 void init_defaults(void) {
301 editor=0;
302 nroferrors=0;
303 }
304
305
306 void init_dynamic (void) {
307 archetype *at = first_archetype;
308 while (at) {
309 if (at->clone.type == MAP && EXIT_PATH (&at->clone)) {
310 strcpy (first_map_path, EXIT_PATH (&at->clone));
311 return;
312 }
313 at = at->next;
314 }
315 LOG(llevDebug,"You Need a archetype called 'map' and it have to contain start map\n");
316 exit (-1);
317 }
318
319 unsigned long todtick;
320
321 /*
322 * Write out the current time to the file so time does not
323 * reset every time the server reboots.
324 */
325
326 void write_todclock(void)
327 {
328 char filename[MAX_BUF];
329 FILE *fp;
330
331 sprintf(filename, "%s/clockdata", settings.localdir);
332 if ((fp = fopen(filename, "w")) == NULL) {
333 LOG(llevError, "Cannot open %s for writing\n", filename);
334 return;
335 }
336 fprintf(fp, "%lu", todtick);
337 fclose(fp);
338 }
339
340 /*
341 * Initializes the gametime and TOD counters
342 * Called by init_library().
343 */
344
345 void init_clocks(void)
346 {
347 char filename[MAX_BUF];
348 FILE *fp;
349 static int has_been_done=0;
350
351 if (has_been_done)
352 return;
353 else
354 has_been_done = 1;
355
356 sprintf(filename, "%s/clockdata", settings.localdir);
357 LOG(llevDebug, "Reading clockdata from %s...", filename);
358 if ((fp = fopen(filename, "r")) == NULL) {
359 LOG(llevError, "Can't open %s.\n", filename);
360 todtick = 0;
361 write_todclock();
362 return;
363 }
364 fscanf(fp, "%lu", &todtick);
365 LOG(llevDebug, "todtick=%lu\n", todtick);
366 fclose(fp);
367 }
368
369 /*
370 * Initializes the attack messages.
371 * Called by init_library().
372 */
373
374 attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
375
376 void init_attackmess(void){
377 char buf[MAX_BUF];
378 char filename[MAX_BUF];
379 char *cp, *p;
380 FILE *fp;
381 static int has_been_done=0;
382 int mess, level, comp;
383 int mode=0, total=0;
384
385 if (has_been_done)
386 return;
387 else
388 has_been_done = 1;
389
390 sprintf(filename, "%s/attackmess", settings.datadir);
391 LOG(llevDebug, "Reading attack messages from %s...", filename);
392 if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) {
393 LOG(llevError, "Can't open %s.\n", filename);
394 return;
395 }
396
397 level = 0;
398 while (fgets(buf, MAX_BUF, fp)!=NULL) {
399 if (*buf=='#') continue;
400 if((cp=strchr(buf,'\n'))!=NULL)
401 *cp='\0';
402 cp=buf;
403 while(*cp==' ') /* Skip blanks */
404 cp++;
405
406 if (strncmp(cp, "TYPE:", 5)==0) {
407 p = strtok(buf, ":");
408 p = strtok(NULL, ":");
409 if (mode == 1) {
410 attack_mess[mess][level].level = -1;
411 attack_mess[mess][level].buf1 = NULL;
412 attack_mess[mess][level].buf2 = NULL;
413 attack_mess[mess][level].buf3 = NULL;
414 }
415 level = 0;
416 mess = atoi(p);
417 mode = 1;
418 continue;
419 }
420 if (mode==1) {
421 p = strtok(buf, "=");
422 attack_mess[mess][level].level = atoi(buf);
423 p = strtok(NULL, "=");
424 if (p != NULL)
425 attack_mess[mess][level].buf1 = strdup_local(p);
426 else
427 attack_mess[mess][level].buf1 = strdup_local("");
428 mode = 2;
429 continue;
430 } else if (mode==2) {
431 p = strtok(buf, "=");
432 attack_mess[mess][level].level = atoi(buf);
433 p = strtok(NULL, "=");
434 if (p != NULL)
435 attack_mess[mess][level].buf2 = strdup_local(p);
436 else
437 attack_mess[mess][level].buf2 = strdup_local("");
438 mode = 3;
439 continue;
440 } else if (mode==3) {
441 p = strtok(buf, "=");
442 attack_mess[mess][level].level = atoi(buf);
443 p = strtok(NULL, "=");
444 if (p != NULL)
445 attack_mess[mess][level].buf3 = strdup_local(p);
446 else
447 attack_mess[mess][level].buf3 = strdup_local("");
448 mode = 1;
449 level++;
450 total++;
451 continue;
452 }
453 }
454 LOG(llevDebug, "got %d messages in %d categories.\n", total, mess+1);
455 close_and_delete(fp, comp);
456 }