00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <global.h>
00038
00039 sint64 *levels;
00041 #define TRUE 1
00042 #define FALSE 0
00043
00044 static const float exp_att_mult[NROFATTACKS+2] = {
00045 0.0,
00046 0.0,
00047 0.0,
00048 0.0,
00049 0.0,
00050 0.0,
00051 0.4,
00052 1.5,
00053 0.0,
00054 0.1,
00055 0.3,
00056 0.2,
00057 0.3,
00058 0.0,
00059 0.0,
00060 0.0,
00061 0.0,
00062 0.0,
00063 0.0,
00064 0.0
00065 };
00066
00067 static const float exp_prot_mult[NROFATTACKS+2] = {
00068 0.4,
00069 0.5,
00070 0.1,
00071 0.1,
00072 0.1,
00073 0.1,
00074 0.1,
00075 0.1,
00076 0.1,
00077 0.1,
00078 0.1,
00079 0.1,
00080 0.1,
00081 0.1,
00082 0.1,
00083 0.0,
00084 0.0,
00085 0.0,
00086 0.0,
00087 0.0
00088 };
00089
00104 sint64 new_exp(const object *ob) {
00105 double att_mult, prot_mult, spec_mult;
00106 double exp;
00107 int i;
00108 long mask = 1;
00109
00110 att_mult = prot_mult = spec_mult = 1.0;
00111 for (i = 0; i < NROFATTACKS; i++) {
00112 mask = 1<<i;
00113 att_mult += (exp_att_mult[i]*((ob->attacktype&mask) != FALSE));
00114
00115
00116
00117
00118 prot_mult += (exp_prot_mult[i] * 200 * ob->resist[i]) / 100.0;
00119 }
00120
00121 if (prot_mult < 0)
00122 prot_mult = 1;
00123
00124 spec_mult += (0.3*(QUERY_FLAG(ob, FLAG_SEE_INVISIBLE) != FALSE))+
00125 (0.5*(QUERY_FLAG(ob, FLAG_SPLITTING) != FALSE))+
00126 (0.3*(QUERY_FLAG(ob, FLAG_HITBACK) != FALSE))+
00127 (0.1*(QUERY_FLAG(ob, FLAG_REFL_MISSILE) != FALSE))+
00128 (0.3*(QUERY_FLAG(ob, FLAG_REFL_SPELL) != FALSE))+
00129 (1.0*(QUERY_FLAG(ob, FLAG_NO_MAGIC) != FALSE))+
00130 (0.1*(QUERY_FLAG(ob, FLAG_USE_SCROLL) != FALSE))+
00131 (0.2*(QUERY_FLAG(ob, FLAG_USE_RANGE) != FALSE))+
00132 (0.1*(QUERY_FLAG(ob, FLAG_USE_BOW) != FALSE));
00133
00134 exp = MAX(ob->stats.maxhp, 5);
00135 exp *= (QUERY_FLAG(ob, FLAG_CAST_SPELL) && has_ability(ob)) ? (40+MIN(ob->stats.maxsp, 80))/40 : 1;
00136 exp *= (80.0/(70.0+ob->stats.wc))*(80.0/(70.0+ob->stats.ac))*(50.0+ob->stats.dam)/50.0;
00137 exp *= att_mult*prot_mult*spec_mult;
00138 exp *= 2.0/(2.0-(MIN(FABS(ob->speed), 0.95)));
00139 exp *= (20.0+ob->stats.Con)/20.0;
00140 if (QUERY_FLAG(ob, FLAG_STAND_STILL))
00141 exp /= 2;
00142
00143 return (sint64)exp;
00144 }
00145
00151 int has_ability(const object *ob) {
00152 object *tmp;
00153
00154 for (tmp = ob->inv; tmp != NULL; tmp = tmp->below)
00155 if (tmp->type == SPELL || tmp->type == SPELLBOOK)
00156 return TRUE;
00157 return FALSE;
00158 }
00159
00170 void init_experience(void) {
00171 char buf[MAX_BUF], *cp;
00172 int lastlevel = 0, comp;
00173 sint64 lastexp = -1, tmpexp;
00174 FILE *fp;
00175
00176 snprintf(buf, sizeof(buf), "%s/exp_table", settings.confdir);
00177
00178 if ((fp = open_and_uncompress(buf, 0, &comp)) == NULL) {
00179 LOG(llevError, "Fatal error: could not open experience table (%s)\n", buf);
00180 exit(1);
00181 }
00182 while (fgets(buf, MAX_BUF-1, fp) != NULL) {
00183 if (buf[0] == '#')
00184 continue;
00185
00186
00187 if ((cp = strrchr(buf, '\n')) != NULL)
00188 *cp = '\0';
00189
00190
00191 if (buf[0] == 0)
00192 continue;
00193 cp = buf;
00194 while (isspace(*cp) && *cp != 0)
00195 cp++;
00196 if (!strncasecmp(cp, "max_level", 9)) {
00197 if (settings.max_level) {
00198 LOG(llevDebug, "Got more than one max_level value from exp_table file?\n");
00199 free(levels);
00200 }
00201 settings.max_level = atoi(cp+9);
00202 if (!settings.max_level) {
00203 LOG(llevDebug, "Got invalid max_level from exp_table file? %s\n", buf);
00204 } else {
00205 levels = calloc(settings.max_level+1, sizeof(sint64));
00206 }
00207 }
00208 while (isdigit(*cp) && *cp != 0) {
00209 if (!settings.max_level) {
00210 LOG(llevError, "max_level is not set in exp_table file. Did you remember to update it?\n");
00211 exit(1);
00212 }
00213
00214 tmpexp = atoll(cp);
00215
00216
00217
00218 if (tmpexp <= lastexp) {
00219 #ifndef WIN32
00220 LOG(llevError, "Experience for level %d is lower than previous level (%lld <= %lld)\n", lastlevel+1, tmpexp, lastexp);
00221 #else
00222 LOG(llevError, "Experience for level %d is lower than previous level (%I64d <= %I64d)\n", lastlevel+1, tmpexp, lastexp);
00223 #endif
00224 exit(1);
00225 }
00226 lastlevel++;
00227 if (lastlevel > settings.max_level) {
00228 LOG(llevError, "Too many levels specified in table (%d > %d)\n", lastlevel, settings.max_level);
00229 exit(1);
00230 }
00231 levels[lastlevel] = tmpexp;
00232 lastexp = tmpexp;
00233
00234
00235
00236 while (isdigit(*cp) && *cp != 0)
00237 cp++;
00238 while (!isdigit(*cp) && *cp != 0)
00239 cp++;
00240 }
00241 }
00242 close_and_delete(fp, comp);
00243 if (settings.max_level == 0 || lastlevel != settings.max_level) {
00244 LOG(llevError, "Fatal: exp_table does not have any level definition or not %d as defined, found %d.\n", settings.max_level, lastlevel);
00245 exit(1);
00246 }
00247 if (lastlevel != settings.max_level && lastlevel != 0) {
00248 LOG(llevError, "Warning: exp_table does not have %d entries (%d)\n", settings.max_level, lastlevel);
00249 exit(1);
00250 }
00251 }
00252
00257 void dump_experience(void) {
00258 int i;
00259
00260 for (i = 1; i <= settings.max_level; i++) {
00261 fprintf(logfile, "%4d %20"FMT64"\n", i, levels[i]);
00262 }
00263 exit(0);
00264 }
00265
00269 void free_experience(void) {
00270 FREE_AND_CLEAR(levels);
00271 }