summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFate <fate-tmw@googlemail.com>2008-12-01 14:05:09 -0700
committerFate <fate-tmw@googlemail.com>2008-12-01 14:05:09 -0700
commit28677f9e8071015f65a81254232d12da6393f144 (patch)
tree78de457ad6410acfafcb4a8138d876af1f6fb36a
parent41ad58a56c0f9d27ca61709141115981520fc9ea (diff)
downloadtmwa-28677f9e8071015f65a81254232d12da6393f144.tar.gz
tmwa-28677f9e8071015f65a81254232d12da6393f144.tar.bz2
tmwa-28677f9e8071015f65a81254232d12da6393f144.tar.xz
tmwa-28677f9e8071015f65a81254232d12da6393f144.zip
Added mutations to mobs (must change mob_db.txt)
-rw-r--r--save/account.txt2
-rw-r--r--src/map/battle.c39
-rw-r--r--src/map/clif.c2
-rw-r--r--src/map/map.h18
-rw-r--r--src/map/mob.c182
-rw-r--r--src/map/mob.h1
-rw-r--r--src/map/npc.c1
-rw-r--r--src/map/skill.c4
8 files changed, 211 insertions, 38 deletions
diff --git a/save/account.txt b/save/account.txt
index 7d6fe0e..34c80cb 100644
--- a/save/account.txt
+++ b/save/account.txt
@@ -10,6 +10,6 @@
// valitidy time : 0: unlimited account, <other value>: date calculated by addition of 1/1/1970 + value (number of seconds since the 1/1/1970)
// memo field : max 254 char
// ban time : 0: no ban, <other value>: banned until the date: date calculated by addition of 1/1/1970 + value (number of seconds since the 1/1/1970)
-0 s1 p1 2008-11-24 15:54:26.750 S 38707 0 a@a.com - 0 127.0.0.1 - 0
+0 s1 p1 2008-11-30 15:41:05.125 S 38708 0 a@a.com - 0 127.0.0.1 - 0
1 s2 p2 2006-03-04 16:54:40.974 S 3 0 a@a.com - 0 - - 0
2000000 %newid%
diff --git a/src/map/battle.c b/src/map/battle.c
index b49e90a..918853b 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -98,7 +98,7 @@ int battle_get_lv(struct block_list *bl)
{
nullpo_retr(0, bl);
if(bl->type==BL_MOB && (struct mob_data *)bl)
- return mob_db[((struct mob_data *)bl)->class].lv;
+ return ((struct mob_data *)bl)->stats[MOB_LV];
else if(bl->type==BL_PC && (struct map_session_data *)bl)
return ((struct map_session_data *)bl)->status.base_level;
else if(bl->type==BL_PET && (struct pet_data *)bl)
@@ -152,7 +152,7 @@ int battle_get_max_hp(struct block_list *bl)
struct status_change *sc_data=battle_get_sc_data(bl);
int max_hp=1;
if(bl->type==BL_MOB && ((struct mob_data*)bl)) {
- max_hp = mob_db[((struct mob_data*)bl)->class].max_hp;
+ max_hp = ((struct mob_data*)bl)->stats[MOB_MAX_HP];
if(mob_db[((struct mob_data*)bl)->class].mexp > 0) {
if(battle_config.mvp_hp_rate != 100)
max_hp = (max_hp * battle_config.mvp_hp_rate)/100;
@@ -196,7 +196,7 @@ int battle_get_str(struct block_list *bl)
nullpo_retr(0, bl);
sc_data=battle_get_sc_data(bl);
if(bl->type==BL_MOB && ((struct mob_data *)bl))
- str = mob_db[((struct mob_data *)bl)->class].str;
+ str = ((struct mob_data *)bl)->stats[MOB_STR];
else if(bl->type==BL_PC && ((struct map_session_data *)bl))
return ((struct map_session_data *)bl)->paramc[0];
else if(bl->type==BL_PET && ((struct pet_data *)bl))
@@ -230,7 +230,7 @@ int battle_get_agi(struct block_list *bl)
nullpo_retr(0, bl);
sc_data=battle_get_sc_data(bl);
if(bl->type==BL_MOB && (struct mob_data *)bl)
- agi=mob_db[((struct mob_data *)bl)->class].agi;
+ agi=((struct mob_data *)bl)->stats[MOB_AGI];
else if(bl->type==BL_PC && (struct map_session_data *)bl)
agi=((struct map_session_data *)bl)->paramc[1];
else if(bl->type==BL_PET && (struct pet_data *)bl)
@@ -268,7 +268,7 @@ int battle_get_vit(struct block_list *bl)
nullpo_retr(0, bl);
sc_data=battle_get_sc_data(bl);
if(bl->type==BL_MOB && (struct mob_data *)bl)
- vit=mob_db[((struct mob_data *)bl)->class].vit;
+ vit=((struct mob_data *)bl)->stats[MOB_VIT];
else if(bl->type==BL_PC && (struct map_session_data *)bl)
vit=((struct map_session_data *)bl)->paramc[2];
else if(bl->type==BL_PET && (struct pet_data *)bl)
@@ -296,7 +296,7 @@ int battle_get_int(struct block_list *bl)
nullpo_retr(0, bl);
sc_data=battle_get_sc_data(bl);
if(bl->type==BL_MOB && (struct mob_data *)bl)
- int_=mob_db[((struct mob_data *)bl)->class].int_;
+ int_=((struct mob_data *)bl)->stats[MOB_INT];
else if(bl->type==BL_PC && (struct map_session_data *)bl)
int_=((struct map_session_data *)bl)->paramc[3];
else if(bl->type==BL_PET && (struct pet_data *)bl)
@@ -329,7 +329,7 @@ int battle_get_dex(struct block_list *bl)
nullpo_retr(0, bl);
sc_data=battle_get_sc_data(bl);
if(bl->type==BL_MOB && (struct mob_data *)bl)
- dex=mob_db[((struct mob_data *)bl)->class].dex;
+ dex=((struct mob_data *)bl)->stats[MOB_DEX];
else if(bl->type==BL_PC && (struct map_session_data *)bl)
dex=((struct map_session_data *)bl)->paramc[4];
else if(bl->type==BL_PET && (struct pet_data *)bl)
@@ -366,7 +366,7 @@ int battle_get_luk(struct block_list *bl)
nullpo_retr(0, bl);
sc_data=battle_get_sc_data(bl);
if(bl->type==BL_MOB && (struct mob_data *)bl)
- luk=mob_db[((struct mob_data *)bl)->class].luk;
+ luk=((struct mob_data *)bl)->stats[MOB_LUK];
else if(bl->type==BL_PC && (struct map_session_data *)bl)
luk=((struct map_session_data *)bl)->paramc[5];
else if(bl->type==BL_PET && (struct pet_data *)bl)
@@ -550,7 +550,7 @@ int battle_get_atk(struct block_list *bl)
if(bl->type==BL_PC && (struct map_session_data *)bl)
atk = ((struct map_session_data*)bl)->watk;
else if(bl->type==BL_MOB && (struct mob_data *)bl)
- atk = mob_db[((struct mob_data*)bl)->class].atk1;
+ atk = ((struct mob_data*)bl)->stats[MOB_ATK1];
else if(bl->type==BL_PET && (struct pet_data *)bl)
atk = mob_db[((struct pet_data*)bl)->class].atk1;
@@ -597,7 +597,7 @@ int battle_get_atk2(struct block_list *bl)
struct status_change *sc_data=battle_get_sc_data(bl);
int atk2=0;
if(bl->type==BL_MOB && (struct mob_data *)bl)
- atk2 = mob_db[((struct mob_data*)bl)->class].atk2;
+ atk2 = ((struct mob_data*)bl)->stats[MOB_ATK2];
else if(bl->type==BL_PET && (struct pet_data *)bl)
atk2 = mob_db[((struct pet_data*)bl)->class].atk2;
if(sc_data) {
@@ -716,7 +716,7 @@ int battle_get_def(struct block_list *bl)
skillid = ((struct map_session_data *)bl)->skillid;
}
else if(bl->type==BL_MOB && (struct mob_data *)bl) {
- def = mob_db[((struct mob_data *)bl)->class].def;
+ def = ((struct mob_data *)bl)->stats[MOB_DEF];
skilltimer = ((struct mob_data *)bl)->skilltimer;
skillid = ((struct mob_data *)bl)->skillid;
}
@@ -778,7 +778,7 @@ int battle_get_mdef(struct block_list *bl)
if(bl->type==BL_PC && (struct map_session_data *)bl)
mdef = ((struct map_session_data *)bl)->mdef;
else if(bl->type==BL_MOB && (struct mob_data *)bl)
- mdef = mob_db[((struct mob_data *)bl)->class].mdef;
+ mdef = ((struct mob_data *)bl)->stats[MOB_MDEF];
else if(bl->type==BL_PET && (struct pet_data *)bl)
mdef = mob_db[((struct pet_data *)bl)->class].mdef;
@@ -817,7 +817,7 @@ int battle_get_def2(struct block_list *bl)
if(bl->type==BL_PC)
def2 = ((struct map_session_data *)bl)->def2;
else if(bl->type==BL_MOB)
- def2 = mob_db[((struct mob_data *)bl)->class].vit;
+ def2 = ((struct mob_data *)bl)->stats[MOB_VIT];
else if(bl->type==BL_PET)
def2 = mob_db[((struct pet_data *)bl)->class].vit;
@@ -847,7 +847,7 @@ int battle_get_mdef2(struct block_list *bl)
nullpo_retr(0, bl);
if(bl->type==BL_MOB)
- mdef2 = mob_db[((struct mob_data *)bl)->class].int_ + (mob_db[((struct mob_data *)bl)->class].vit>>1);
+ mdef2 = ((struct mob_data *)bl)->stats[MOB_INT] + (((struct mob_data *)bl)->stats[MOB_VIT]>>1);
else if(bl->type==BL_PC)
mdef2 = ((struct map_session_data *)bl)->mdef2 + (((struct map_session_data *)bl)->paramc[2]>>1);
else if(bl->type==BL_PET)
@@ -874,8 +874,7 @@ int battle_get_speed(struct block_list *bl)
struct status_change *sc_data=battle_get_sc_data(bl);
int speed = 1000;
if(bl->type==BL_MOB && (struct mob_data *)bl)
-// speed = mob_db[((struct mob_data *)bl)->class].speed;
- speed = ((struct mob_data *)bl)->speed;
+ speed = ((struct mob_data *)bl)->stats[MOB_SPEED];
else if(bl->type==BL_PET && (struct pet_data *)bl)
speed = ((struct pet_data *)bl)->msd->petDB->speed;
@@ -928,7 +927,7 @@ int battle_get_adelay(struct block_list *bl)
struct status_change *sc_data=battle_get_sc_data(bl);
int adelay=4000,aspd_rate = 100,i;
if(bl->type==BL_MOB && (struct mob_data *)bl)
- adelay = mob_db[((struct mob_data *)bl)->class].adelay;
+ adelay = ((struct mob_data *)bl)->stats[MOB_ADELAY];
else if(bl->type==BL_PET && (struct pet_data *)bl)
adelay = mob_db[((struct pet_data *)bl)->class].adelay;
@@ -1203,7 +1202,10 @@ int battle_get_mexp(struct block_list *bl)
{
nullpo_retr(0, bl);
if(bl->type==BL_MOB && (struct mob_data *)bl) {
- return mob_db[((struct mob_data *)bl)->class].mexp;
+ const struct mob_data *mob = (struct mob_data *) bl;
+ const int retval = (mob_db[mob->class].mexp * (int) (mob->stats[MOB_XP_BONUS])) >> MOB_XP_BONUS_SHIFT;
+ fprintf(stderr, "Modifier of %x: -> %d\n", mob->stats[MOB_XP_BONUS], retval);
+ return retval;
}
else if(bl->type==BL_PET && (struct pet_data *)bl)
return mob_db[((struct pet_data *)bl)->class].mexp;
@@ -4334,7 +4336,6 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
short *opt1;
int race = 7, ele = 0;
int damage,rdamage = 0;
- int i;
struct Damage wd;
nullpo_retr(0, src);
diff --git a/src/map/clif.c b/src/map/clif.c
index 418e56a..426ee53 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1388,7 +1388,7 @@ int clif_spawnmob(struct mob_data *md)
WBUFW(buf,0)=0x7c;
WBUFL(buf,2)=md->bl.id;
- WBUFW(buf,6)=md->speed;
+ WBUFW(buf,6)=md->stats[MOB_SPEED];
WBUFW(buf,8)=md->opt1;
WBUFW(buf,10)=md->opt2;
WBUFW(buf,12)=md->option;
diff --git a/src/map/map.h b/src/map/map.h
index 54179ac..afaf61e 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -410,6 +410,22 @@ struct npc_data {
#define MOB_SENSIBLE_MASK 0xf000 // fate: mob mode flags that I actually understand
+enum mob_stat {
+ MOB_LV,
+ MOB_MAX_HP,
+ MOB_STR, MOB_AGI, MOB_VIT, MOB_INT, MOB_DEX, MOB_LUK,
+ MOB_ATK1, MOB_ATK2, // low and high attacks
+ MOB_ADELAY, // attack delay
+ MOB_DEF, MOB_MDEF,
+ MOB_SPEED,
+ // These must come last:
+ MOB_XP_BONUS, /* [Fate] Encoded as base to 1024: 1024 means 100% */
+ MOB_LAST
+};
+
+#define MOB_XP_BONUS_BASE 1024
+#define MOB_XP_BONUS_SHIFT 10
+
struct mob_data {
struct block_list bl;
short n;
@@ -431,7 +447,6 @@ struct mob_data {
} state;
int timer;
short to_x,to_y;
- short speed;
int hp;
int target_id,attacked_id;
short target_lv;
@@ -468,6 +483,7 @@ struct mob_data {
struct skill_unit_group skillunit[MAX_MOBSKILLUNITGROUP];
struct skill_unit_group_tickset skillunittick[MAX_SKILLUNITGROUPTICKSET];
char npc_event[50];
+ unsigned short stats[MOB_LAST]; // [Fate] mob-specific stats
short size;
};
struct pet_data {
diff --git a/src/map/mob.c b/src/map/mob.c
index dc40630..f43e049 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -74,6 +74,9 @@ int mobdb_checkid(const int id)
return id;
}
+static void
+mob_init(struct mob_data *md);
+
/*==========================================
* The minimum data set for MOB spawning
*------------------------------------------
@@ -82,8 +85,6 @@ int mob_spawn_dataset(struct mob_data *md,const char *mobname,int class)
{
nullpo_retr(0, md);
- md->bl.prev=NULL;
- md->bl.next=NULL;
if(strcmp(mobname,"--en--")==0)
memcpy(md->name,mob_db[class].name,24);
else if(strcmp(mobname,"--ja--")==0)
@@ -91,6 +92,8 @@ int mob_spawn_dataset(struct mob_data *md,const char *mobname,int class)
else
memcpy(md->name,mobname,24);
+ md->bl.prev=NULL;
+ md->bl.next=NULL;
md->n = 0;
md->base_class = md->class = class;
md->bl.id= npc_get_new_npc_id();
@@ -99,11 +102,157 @@ int mob_spawn_dataset(struct mob_data *md,const char *mobname,int class)
md->timer = -1;
md->target_id=0;
md->attacked_id=0;
- md->speed=mob_db[class].speed;
+
+ mob_init(md);
return 0;
}
+// Mutation values indicate how `valuable' a change to each stat is, XP wise.
+// For one 256th of change, we give out that many 1024th fractions of XP change
+// (i.e., 1024 means a 100% XP increase for a single point of adjustment, 4 means 100% XP bonus for doubling the value)
+static int
+mutation_value[MOB_XP_BONUS] =
+{
+ 2, // MOB_LV
+ 3, // MOB_MAX_HP
+ 1, // MOB_STR
+ 2, // MOB_AGI
+ 1, // MOB_VIT
+ 0, // MOB_INT
+ 2, // MOB_DEX
+ 2, // MOB_LUK
+ 1, // MOB_ATK1
+ 1, // MOB_ATK2
+ 2, // MOB_ADELAY
+ 2, // MOB_DEF
+ 2, // MOB_MDEF
+ 2, // MOB_SPEED
+};
+
+// The mutation scale indicates how far `up' we can go, with 256 indicating 100% Note that this may stack with multiple
+// calls to `mutate'.
+static int
+mutation_scale[MOB_XP_BONUS] =
+{
+ 16, // MOB_LV
+ 256, // MOB_MAX_HP
+ 32, // MOB_STR
+ 48, // MOB_AGI
+ 48, // MOB_VIT
+ 48, // MOB_INT
+ 48, // MOB_DEX
+ 64, // MOB_LUK
+ 48, // MOB_ATK1
+ 48, // MOB_ATK2
+ 80, // MOB_ADELAY
+ 48, // MOB_DEF
+ 48, // MOB_MDEF
+ 80, // MOB_SPEED
+};
+
+
+/*========================================
+ * Mutates a MOB. For large `direction' values, calling this multiple times will give bigger XP boni.
+ *----------------------------------------
+ */
+static void
+mob_mutate(struct mob_data *md, int stat, int intensity) // intensity: positive: strengthen, negative: weaken. 256 = 100%.
+{
+ int old_stat;
+ int new_stat;
+ int real_intensity;
+ int sign = 1;
+
+ if (!md || stat < 0 || stat >= MOB_XP_BONUS || intensity == 0)
+ return;
+
+ while (intensity > mutation_scale[stat]) {
+ mob_mutate(md, stat, mutation_scale[stat]); // give better XP assignments
+ intensity -= mutation_scale[stat];
+ }
+ while (intensity < -mutation_scale[stat]) {
+ mob_mutate(md, stat, mutation_scale[stat]); // give better XP assignments
+ intensity += mutation_scale[stat];
+ }
+
+ if (!intensity)
+ return;
+
+ // MOB_ADELAY and MOB_SPEED are special because going DOWN is good here.
+ if (stat == MOB_ADELAY || stat == MOB_SPEED)
+ sign = -1;
+
+ // Now compute the new stat
+ old_stat = md->stats[stat];
+ new_stat = old_stat + ((old_stat * sign * intensity) / 256);
+
+ if (new_stat < 0)
+ new_stat = 0;
+
+ if (old_stat == 0)
+ real_intensity = 0;
+ else
+ real_intensity = sign * (((new_stat - old_stat) << 8) / old_stat);
+
+ md->stats[stat] = new_stat;
+
+ // Adjust XP value
+ md->stats[MOB_XP_BONUS] += mutation_value[stat] * real_intensity;
+ if (md->stats[MOB_XP_BONUS] <= 0)
+ md->stats[MOB_XP_BONUS] = 1;
+
+ // Sanitise
+ if (md->stats[MOB_ATK1] > md->stats[MOB_ATK2]) {
+ int swap = md->stats[MOB_ATK2];
+ md->stats[MOB_ATK2] = md->stats[MOB_ATK1];
+ md->stats[MOB_ATK1] = swap;
+ }
+}
+
+
+static void
+mob_init(struct mob_data *md)
+{
+ int i;
+ const int class = md->class;
+ const int mutations_nr = mob_db[class].mutations_nr;
+ const int mutation_power = mob_db[class].mutation_power;
+
+ md->stats[MOB_LV] = mob_db[class].lv;
+ md->stats[MOB_MAX_HP] = mob_db[class].max_hp;
+ md->stats[MOB_STR] = mob_db[class].str;
+ md->stats[MOB_AGI] = mob_db[class].agi;
+ md->stats[MOB_VIT] = mob_db[class].vit;
+ md->stats[MOB_INT] = mob_db[class].int_;
+ md->stats[MOB_DEX] = mob_db[class].dex;
+ md->stats[MOB_LUK] = mob_db[class].luk;
+ md->stats[MOB_ATK1] = mob_db[class].atk1;
+ md->stats[MOB_ATK2] = mob_db[class].atk2;
+ md->stats[MOB_ADELAY] = mob_db[class].adelay;
+ md->stats[MOB_DEF] = mob_db[class].def;
+ md->stats[MOB_MDEF] = mob_db[class].mdef;
+ md->stats[MOB_SPEED] = mob_db[class].speed;
+ md->stats[MOB_XP_BONUS] = MOB_XP_BONUS_BASE;
+
+ for (i = 0; i < mutations_nr; i++) {
+ int stat_nr = MRAND(MOB_XP_BONUS + 1);
+ int strength;
+
+ if (stat_nr >= MOB_XP_BONUS)
+ stat_nr = MOB_MAX_HP;
+
+ strength = ((MRAND((mutation_power >> 1)) + (MRAND((mutation_power >> 1))) + 2) * mutation_scale[stat_nr]) / 100;
+
+ strength = MRAND(2)? strength : -strength;
+
+ if (strength < -240)
+ strength = -240; /* Don't go too close to zero */
+
+ mob_mutate(md, stat_nr, strength);
+ }
+}
+
/*==========================================
* The MOB appearance for one time (for scripts)
@@ -845,7 +994,7 @@ int mob_spawn(int id)
if(!md || !md->bl.type || md->bl.type!=BL_MOB)
return -1;
-
+
md->last_spawntime=tick;
if( md->bl.prev!=NULL ){
// clif_clearchar_area(&md->bl,3);
@@ -884,9 +1033,10 @@ int mob_spawn(int id)
md->attacked_id = 0;
md->target_id = 0;
md->move_fail_count = 0;
+ mob_init(md);
- if(!md->speed)
- md->speed = mob_db[md->class].speed;
+ if(!md->stats[MOB_SPEED])
+ md->stats[MOB_SPEED] = mob_db[md->class].speed;
md->def_ele = mob_db[md->class].element;
md->master_id=0;
md->master_dist=0;
@@ -2304,7 +2454,8 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
per=(double)md->dmglog[i].dmg*256*(9+(double)((count > 6)? 6:count))/10/(double)max_hp;
if(per>512) per=512;
if(per<1) per=1;
- base_exp=mob_db[md->class].base_exp*per/256;
+
+ base_exp = ((mob_db[md->class].base_exp * md->stats[MOB_XP_BONUS]) >> MOB_XP_BONUS_SHIFT) * per/256;
if(base_exp < 1) base_exp = 1;
if(sd && md && battle_config.pk_mode==1 && (mob_db[md->class].lv - sd->status.base_level >= 20)) {
base_exp*=1.15; // pk_mode additional exp if monster >20 levels [Valaris]
@@ -2421,8 +2572,8 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
// mvp処理
if(mvp_sd && mob_db[md->class].mexp > 0 ){
int j;
- int mexp;
- temp = ((double)mob_db[md->class].mexp * (double)battle_config.mvp_exp_rate * (9.+(double)count)/1000.);
+ int mexp = battle_get_mexp(&md->bl);
+ temp = ((double)mexp * (double)battle_config.mvp_exp_rate * (9.+(double)count)/1000.);
mexp = (temp > 2147483647.)? 0x7fffffff:(int)temp;
if(mexp < 1) mexp = 1;
clif_mvp_effect(mvp_sd); // エフェクト
@@ -2543,7 +2694,7 @@ int mob_class_change(struct mob_data *md,int *value)
md->target_id = 0;
md->move_fail_count = 0;
- md->speed = mob_db[md->class].speed;
+ md->stats[MOB_SPEED] = mob_db[md->class].speed;
md->def_ele = mob_db[md->class].element;
mob_changestate(md,MS_IDLE,0);
@@ -2781,6 +2932,8 @@ int mob_summonslave(struct mob_data *md2,int *value,int amount,int flag)
}
mob_spawn_dataset(md,"--ja--",class);
+ md->bl.prev=NULL;
+ md->bl.next=NULL;
md->bl.m=m;
md->bl.x=x;
md->bl.y=y;
@@ -2790,7 +2943,7 @@ int mob_summonslave(struct mob_data *md2,int *value,int amount,int flag)
md->y0=y;
md->xs=0;
md->ys=0;
- md->speed=md2->speed;
+ md->stats[MOB_SPEED]=md2->stats[MOB_SPEED];
md->spawndelay1=-1; // 一度のみフラグ
md->spawndelay2=-1; // 一度のみフラグ
@@ -3647,12 +3800,12 @@ static int mob_readdb(void)
}
while(fgets(line,1020,fp)){
int class,i;
- char *str[55],*p,*np;
+ char *str[57],*p,*np;
if(line[0] == '/' && line[1] == '/')
continue;
- for(i=0,p=line;i<55;i++){
+ for(i=0,p=line;i<57;i++){
while (*p == '\t' || *p == ' ') p++;
if((np=strchr(p,','))!=NULL){
str[i]=p;
@@ -3753,6 +3906,9 @@ static int mob_readdb(void)
mob_db[class].mvpitem[i].nameid=atoi(str[47+i*2]);
mob_db[class].mvpitem[i].p=atoi(str[48+i*2])*battle_config.mvp_item_rate/100;
}
+ mob_db[class].mutations_nr = atoi(str[55]);
+ mob_db[class].mutation_power = atoi(str[56]);
+
for(i=0;i<MAX_RANDOMMONSTER;i++)
mob_db[class].summonper[i]=0;
mob_db[class].maxskill=0;
diff --git a/src/map/mob.h b/src/map/mob.h
index 7c1467b..2675e44 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -28,6 +28,7 @@ struct mob_db {
int size,race,element,mode;
int speed,adelay,amotion,dmotion;
int mexp,mexpper;
+ int mutations_nr, mutation_power;
struct { int nameid,p; } dropitem[8];
struct { int nameid,p; } mvpitem[3];
int view_class,sex;
diff --git a/src/map/npc.c b/src/map/npc.c
index a82fe12..31a0c42 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -1729,7 +1729,6 @@ int npc_parse_mob(char *w1,char *w2,char *w3,char *w4)
md->timer = -1;
md->target_id=0;
md->attacked_id=0;
- md->speed=mob_db[class].speed;
if (mob_db[class].mode&0x02)
md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
diff --git a/src/map/skill.c b/src/map/skill.c
index 9047e7f..460a328 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -8227,8 +8227,8 @@ int skill_status_change_timer(int tid, unsigned int tick, int id, int data)
case SC_SELFDESTRUCTION: /* 自爆 */
if(--sc_data[type].val3>0){
struct mob_data *md;
- if(bl->type==BL_MOB && (md=(struct mob_data *)bl) && md->speed > 250){
- md->speed -= 250;
+ if(bl->type==BL_MOB && (md=(struct mob_data *)bl) && md->stats[MOB_SPEED] > 250){
+ md->stats[MOB_SPEED] -= 250;
md->next_walktime=tick;
}
sc_data[type].timer=add_timer( /* タイマー再設定 */