/* * CrossFire, A Multiplayer game for X-windows * * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team * Copyright (C) 2002 Mark Wedel & Crossfire Development Team * Copyright (C) 1992 Frank Tore Johansen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * The authors can be reached via e-mail at */ #define EXTERN // horrible hack #include #include extern const char *const attacktype_desc[NROFATTACKS] = { # define def(uc, lc, name, plus, change) # name, # include "attackinc.h" # undef def }; extern const char *const resist_plus[NROFATTACKS] = { # define def(uc, lc, name, plus, change) # plus, # include "attackinc.h" # undef def }; extern const char *const change_resist_msg[NROFATTACKS] = { # define def(uc, lc, name, plus, change) # change, # include "attackinc.h" # undef def }; int resist_table[NROFATTACKS] = { # define def(uc, lc, name, plus, change) ATNR_ ## uc, # include "attackinc.h" # undef def }; /* You unforunately need to looking in include/global.h to see what these * correspond to. */ struct Settings settings = { LOGFILE, /* Logfile */ CSPORT, /* Client/server port */ /* Debug level */ #ifdef DEBUG llevDebug, #else llevInfo, #endif 0, NULL, 0, /* dumpvalues, dumparg, daemonmode */ 0, /* argc */ NULL, /* argv */ CONFDIR, DATADIR, LOCALDIR, PLAYERDIR, MAPDIR, ARCHETYPES, REGIONS, TREASURES, UNIQUE_DIR, TEMPLATE_DIR, TMPDIR, STAT_LOSS_ON_DEATH, PK_LUCK_PENALTY, PERMANENT_EXPERIENCE_RATIO, DEATH_PENALTY_RATIO, DEATH_PENALTY_LEVEL, BALANCED_STAT_LOSS, NOT_PERMADETH, SIMPLE_EXP, RESET_LOCATION_TIME, SET_TITLE, RESURRECTION, SEARCH_ITEMS, SPELL_ENCUMBRANCE, SPELL_FAILURE_EFFECTS, CASTING_TIME, REAL_WIZ, EXPLORE_MODE, SPELLPOINT_LEVEL_DEPEND, SET_FRIENDLY_FIRE, MOTD, "rules", "news", "", /* DM_MAIL */ 0, 0, 0, 0, 0, 0, 0, 0, /* worldmap settings */ 0, 1.0, /* Armor enchantment stuff */ ARMOR_MAX_ENCHANT, ARMOR_WEIGHT_REDUCTION, ARMOR_WEIGHT_LINEAR, ARMOR_SPEED_IMPROVEMENT, ARMOR_SPEED_LINEAR, 1, /* no_player_stealing */ 1, /* create_home_portals */ }; /* perhaps not the best place for this, but needs to be * in some file in the common area so that standalone * programs, like the random map generator, can be built. */ const char *const spellpathnames[NRSPELLPATHS] = { "Protection", "Fire", "Frost", "Electricity", "Missiles", "Self", "Summoning", "Abjuration", "Restoration", "Detonation", "Mind", "Creation", "Teleportation", "Information", "Transmutation", "Transferrence", "Turning", "Wounding", "Death", "Light" }; /* * It is vital that init_library() is called by any functions * using this library. * If you want to lessen the size of the program using the library, * you can replace the call to init_library() with init_globals() and * init_function_pointers(). Good idea to also call init_vars and * init_hash_table if you are doing any object loading. */ void init_library (void) { init_environ (); init_globals (); init_vars (); init_block (); ReadBmapNames (); ReadSmooth (); init_anim (); /* Must be after we read in the bitmaps */ init_archetypes (); /* Reads all archetypes from file */ init_dynamic (); init_attackmess (); init_clocks (); init_experience (); } /* init_environ initialises values from the environmental variables. * it needs to be called very early, since command line options should * overwrite these if specified. */ void init_environ (void) { char *cp; cp = getenv ("CROSSFIRE_LIBDIR"); if (cp) settings.datadir = cp; cp = getenv ("CROSSFIRE_LOCALDIR"); if (cp) settings.localdir = cp; cp = getenv ("CROSSFIRE_PLAYERDIR"); if (cp) settings.playerdir = cp; cp = getenv ("CROSSFIRE_MAPDIR"); if (cp) settings.mapdir = cp; cp = getenv ("CROSSFIRE_ARCHETYPES"); if (cp) settings.archetypes = cp; cp = getenv ("CROSSFIRE_TREASURES"); if (cp) settings.treasures = cp; cp = getenv ("CROSSFIRE_UNIQUEDIR"); if (cp) settings.uniquedir = cp; cp = getenv ("CROSSFIRE_TEMPLATEDIR"); if (cp) settings.templatedir = cp; cp = getenv ("CROSSFIRE_TMPDIR"); if (cp) settings.tmpdir = cp; } /* * Initialises all global variables. * Might use environment-variables as default for some of them. */ void init_globals (void) { if (settings.logfilename[0] == 0) logfile = stderr; else if ((logfile = fopen (settings.logfilename, "a")) == NULL) { fprintf (stderr, "Unable to open %s as the logfile - will use stderr instead\n", settings.logfilename); logfile = stderr; } else setvbuf (logfile, NULL, _IOLBF, 0); } void init_dynamic (void) { archetype *at = first_archetype; while (at) { if (at->clone.type == MAP) { if (at->clone.race) first_map_ext_path = at->clone.race; if (EXIT_PATH (&at->clone)) { first_map_path = EXIT_PATH (&at->clone); return; } } at = at->next; } LOG (llevDebug, "You Need a archetype called 'map' and it have to contain start map\n"); exit (-1); } unsigned long todtick; /* * Write out the current time to the file so time does not * reset every time the server reboots. */ void write_todclock (void) { char filename[MAX_BUF]; FILE *fp; sprintf (filename, "%s/clockdata", settings.localdir); if ((fp = fopen (filename, "w")) == NULL) { LOG (llevError, "Cannot open %s for writing\n", filename); return; } fprintf (fp, "%lu", todtick); fclose (fp); } /* * initialises the gametime and TOD counters * Called by init_library(). */ void init_clocks (void) { char filename[MAX_BUF]; FILE *fp; static int has_been_done = 0; if (has_been_done) return; else has_been_done = 1; sprintf (filename, "%s/clockdata", settings.localdir); LOG (llevDebug, "Reading clockdata from %s...\n", filename); if ((fp = fopen (filename, "r")) == NULL) { LOG (llevError, "Can't open %s.\n", filename); todtick = 0; write_todclock (); return; } fscanf (fp, "%lu", &todtick); LOG (llevDebug, "todtick=%lu\n", todtick); fclose (fp); } /* * initialises the attack messages. * Called by init_library(). */ //attackmess_t attack_mess[NROFATTACKMESS][MAXATTACKMESS]; void init_attackmess (void) { char buf[MAX_BUF]; char filename[MAX_BUF]; char *cp, *p; FILE *fp; static int has_been_done = 0; int mess, level, comp; int mode = 0, total = 0; if (has_been_done) return; else has_been_done = 1; sprintf (filename, "%s/attackmess", settings.datadir); LOG (llevDebug, "Reading attack messages from %s...\n", filename); if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL) { LOG (llevError, "Can't open %s.\n", filename); return; } level = 0; while (fgets (buf, MAX_BUF, fp) != NULL) { if (*buf == '#') continue; if ((cp = strchr (buf, '\n')) != NULL) *cp = '\0'; cp = buf; while (*cp == ' ') /* Skip blanks */ cp++; if (strncmp (cp, "TYPE:", 5) == 0) { p = strtok (buf, ":"); p = strtok (NULL, ":"); if (mode == 1) { attack_mess[mess][level].level = -1; attack_mess[mess][level].buf1 = NULL; attack_mess[mess][level].buf2 = NULL; attack_mess[mess][level].buf3 = NULL; } level = 0; mess = atoi (p); mode = 1; continue; } if (mode == 1) { p = strtok (buf, "="); attack_mess[mess][level].level = atoi (buf); p = strtok (NULL, "="); if (p != NULL) attack_mess[mess][level].buf1 = strdup (p); else attack_mess[mess][level].buf1 = strdup (""); mode = 2; continue; } else if (mode == 2) { p = strtok (buf, "="); attack_mess[mess][level].level = atoi (buf); p = strtok (NULL, "="); if (p != NULL) attack_mess[mess][level].buf2 = strdup (p); else attack_mess[mess][level].buf2 = strdup (""); mode = 3; continue; } else if (mode == 3) { p = strtok (buf, "="); attack_mess[mess][level].level = atoi (buf); p = strtok (NULL, "="); if (p != NULL) attack_mess[mess][level].buf3 = strdup (p); else attack_mess[mess][level].buf3 = strdup (""); mode = 1; level++; total++; continue; } } LOG (llevDebug, "got %d messages in %d categories.\n", total, mess + 1); close_and_delete (fp, comp); }