ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/init.C
Revision: 1.32
Committed: Mon Apr 16 06:23:39 2007 UTC (17 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.31: +1 -1 lines
Log Message:
VERY EXPERIMENTAL

- change the way archetypes and treasurelists are being loaded:
  - referring to a nonexisting treasurelist will create an empty one
  - referring to a nonexisting archetype will create an empty one
  - archetypes/treasurelists will overwrite any existing object
    of the same name.

- net effect should be to allow reloading of archetypes and treasurelists
  at runtime at a later stage.

File Contents

# Content
1 /*
2 * CrossFire, A Multiplayer game for X-windows
3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
23 */
24
25 #define EXTERN // horrible hack
26
27 #include <global.h>
28 #include <object.h>
29
30 extern const char *const attacktype_desc[NROFATTACKS] = {
31 # define def(uc, lc, name, plus, change) # name,
32 # include "attackinc.h"
33 # undef def
34 };
35
36 extern const char *const resist_plus[NROFATTACKS] = {
37 # define def(uc, lc, name, plus, change) # plus,
38 # include "attackinc.h"
39 # undef def
40 };
41
42 extern const char *const change_resist_msg[NROFATTACKS] = {
43 # define def(uc, lc, name, plus, change) # change,
44 # include "attackinc.h"
45 # undef def
46 };
47
48 int resist_table[NROFATTACKS] = {
49 # define def(uc, lc, name, plus, change) ATNR_ ## uc,
50 # include "attackinc.h"
51 # undef def
52 };
53
54 /* You unforunately need to looking in include/global.h to see what these
55 * correspond to.
56 */
57 struct Settings settings = {
58 LOGFILE, /* Logfile */
59 CSPORT, /* Client/server port */
60
61 /* Debug level */
62 #ifdef DEBUG
63 llevDebug,
64 #else
65 llevInfo,
66 #endif
67
68 0, NULL, 0, /* dumpvalues, dumparg, daemonmode */
69 0, /* argc */
70 NULL, /* argv */
71 CONFDIR,
72 DATADIR,
73 LOCALDIR,
74 PLAYERDIR, MAPDIR, ARCHETYPES, REGIONS, TREASURES,
75 UNIQUE_DIR, TEMPLATE_DIR,
76 TMPDIR,
77 STAT_LOSS_ON_DEATH,
78 PK_LUCK_PENALTY,
79 PERMANENT_EXPERIENCE_RATIO,
80 DEATH_PENALTY_RATIO,
81 DEATH_PENALTY_LEVEL,
82 BALANCED_STAT_LOSS,
83 NOT_PERMADETH,
84 SIMPLE_EXP,
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 0,
101 1.0,
102
103 /* Armor enchantment stuff */
104 ARMOR_MAX_ENCHANT,
105 ARMOR_WEIGHT_REDUCTION,
106 ARMOR_WEIGHT_LINEAR,
107 ARMOR_SPEED_IMPROVEMENT,
108 ARMOR_SPEED_LINEAR,
109 1, /* no_player_stealing */
110 1, /* create_home_portals */
111 };
112
113 /* perhaps not the best place for this, but needs to be
114 * in some file in the common area so that standalone
115 * programs, like the random map generator, can be built.
116 */
117 const char *const spellpathnames[NRSPELLPATHS] = {
118 "Protection",
119 "Fire",
120 "Frost",
121 "Electricity",
122 "Missiles",
123 "Self",
124 "Summoning",
125 "Abjuration",
126 "Restoration",
127 "Detonation",
128 "Mind",
129 "Creation",
130 "Teleportation",
131 "Information",
132 "Transmutation",
133 "Transferrence",
134 "Turning",
135 "Wounding",
136 "Death",
137 "Light"
138 };
139
140 /*
141 * It is vital that init_library() is called by any functions
142 * using this library.
143 * If you want to lessen the size of the program using the library,
144 * you can replace the call to init_library() with init_globals() and
145 * init_function_pointers(). Good idea to also call init_vars and
146 * init_hash_table if you are doing any object loading.
147 */
148 void
149 init_library (void)
150 {
151 init_globals ();
152 init_block ();
153 init_archetypes (); /* Reads all archetypes from file */
154 init_dynamic ();
155 init_attackmess ();
156 init_experience ();
157 }
158
159
160 /* init_environ initialises values from the environmental variables.
161 * it needs to be called very early, since command line options should
162 * overwrite these if specified.
163 */
164 void
165 init_environ (void)
166 {
167 char *cp;
168
169 cp = getenv ("CROSSFIRE_LIBDIR");
170 if (cp)
171 settings.datadir = cp;
172 cp = getenv ("CROSSFIRE_LOCALDIR");
173 if (cp)
174 settings.localdir = cp;
175 cp = getenv ("CROSSFIRE_PLAYERDIR");
176 if (cp)
177 settings.playerdir = cp;
178 cp = getenv ("CROSSFIRE_MAPDIR");
179 if (cp)
180 settings.mapdir = cp;
181 cp = getenv ("CROSSFIRE_ARCHETYPES");
182 if (cp)
183 settings.archetypes = cp;
184 cp = getenv ("CROSSFIRE_TREASURES");
185 if (cp)
186 settings.treasures = cp;
187 cp = getenv ("CROSSFIRE_UNIQUEDIR");
188 if (cp)
189 settings.uniquedir = cp;
190 cp = getenv ("CROSSFIRE_TEMPLATEDIR");
191 if (cp)
192 settings.templatedir = cp;
193 cp = getenv ("CROSSFIRE_TMPDIR");
194 if (cp)
195 settings.tmpdir = cp;
196 }
197
198 /*
199 * Initialises all global variables.
200 * Might use environment-variables as default for some of them.
201 */
202 void
203 init_globals (void)
204 {
205 if (settings.logfilename[0] == 0)
206 logfile = stderr;
207 else if ((logfile = fopen (settings.logfilename, "a")) == NULL)
208 {
209 fprintf (stderr, "Unable to open %s as the logfile - will use stderr instead\n", settings.logfilename);
210 logfile = stderr;
211 }
212 else
213 setvbuf (logfile, NULL, _IOLBF, 0);
214 }
215
216 void
217 init_dynamic (void)
218 {
219 archetype *at = first_archetype;
220
221 while (at)
222 {
223 if (at->clone.type == MAP)
224 {
225 if (at->clone.race)
226 first_map_ext_path = at->clone.race;
227
228 if (EXIT_PATH (&at->clone))
229 {
230 first_map_path = EXIT_PATH (&at->clone);
231 return;
232 }
233 }
234
235 at = at->next;
236 }
237
238 LOG (llevDebug, "You need an archetype of type 'map' and it has to contain the player start map\n");
239 exit (-1);
240 }
241
242 /*
243 * initialises the attack messages.
244 * Called by init_library().
245 */
246
247 //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS];
248
249 void
250 init_attackmess (void)
251 {
252 char buf[MAX_BUF];
253 char filename[MAX_BUF];
254 char *cp, *p;
255 FILE *fp;
256 static int has_been_done = 0;
257 int mess, level, comp;
258 int mode = 0, total = 0;
259
260 if (has_been_done)
261 return;
262 else
263 has_been_done = 1;
264
265 sprintf (filename, "%s/attackmess", settings.datadir);
266 LOG (llevDebug, "Reading attack messages from %s...\n", filename);
267 if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL)
268 {
269 LOG (llevError, "Can't open %s.\n", filename);
270 return;
271 }
272
273 level = 0;
274 while (fgets (buf, MAX_BUF, fp) != NULL)
275 {
276 if (*buf == '#')
277 continue;
278 if ((cp = strchr (buf, '\n')) != NULL)
279 *cp = '\0';
280 cp = buf;
281 while (*cp == ' ') /* Skip blanks */
282 cp++;
283
284 if (strncmp (cp, "TYPE:", 5) == 0)
285 {
286 p = strtok (buf, ":");
287 p = strtok (NULL, ":");
288 if (mode == 1)
289 {
290 attack_mess[mess][level].level = -1;
291 attack_mess[mess][level].buf1 = NULL;
292 attack_mess[mess][level].buf2 = NULL;
293 attack_mess[mess][level].buf3 = NULL;
294 }
295 level = 0;
296 mess = atoi (p);
297 mode = 1;
298 continue;
299 }
300 if (mode == 1)
301 {
302 p = strtok (buf, "=");
303 attack_mess[mess][level].level = atoi (buf);
304 p = strtok (NULL, "=");
305 if (p != NULL)
306 attack_mess[mess][level].buf1 = strdup (p);
307 else
308 attack_mess[mess][level].buf1 = strdup ("");
309 mode = 2;
310 continue;
311 }
312 else if (mode == 2)
313 {
314 p = strtok (buf, "=");
315 attack_mess[mess][level].level = atoi (buf);
316 p = strtok (NULL, "=");
317 if (p != NULL)
318 attack_mess[mess][level].buf2 = strdup (p);
319 else
320 attack_mess[mess][level].buf2 = strdup ("");
321 mode = 3;
322 continue;
323 }
324 else if (mode == 3)
325 {
326 p = strtok (buf, "=");
327 attack_mess[mess][level].level = atoi (buf);
328 p = strtok (NULL, "=");
329 if (p != NULL)
330 attack_mess[mess][level].buf3 = strdup (p);
331 else
332 attack_mess[mess][level].buf3 = strdup ("");
333 mode = 1;
334 level++;
335 total++;
336 continue;
337 }
338 }
339 LOG (llevDebug, "got %d messages in %d categories.\n", total, mess + 1);
340 close_and_delete (fp, comp);
341 }