///ALTER TABLE `mob_db` ADD `attr` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `Mode`
///ALTER TABLE `mob_db2` ADD `attr` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `Mode`
Index: src/map/status.h
===================================================================
--- src/map/status.h (revision 17271)
+++ src/map/status.h (working copy)
@@ -1428,6 +1428,15 @@
MD_MASK = 0xFFFF,
};
+enum e_attr {
+ ATR_IGNOREMELEE = 0x01, //takes 1 HP damage from melee physical attacks
+ ATR_IGNOREMAGIC = 0x02, //takes 1 HP damage from magic
+ ATR_IGNORERANGED = 0x04, //takes 1 HP damage from ranged physical attacks
+ ATR_MVP = 0x08, //MVP - instant kill / coma-like skills don't work
+ ATR_IGNOREMISC = 0x10, //takes 1 HP damage from "none" attack type
+ ATR_KNOCKBACK_IMMUNE = 0x20, //can't be knocked back
+};
+
//Status change option definitions (options are what makes status changes visible to chars
//who were not on your field of sight when it happened)
@@ -1616,6 +1625,7 @@
speed,
amotion, adelay, dmotion,
mode;
+ enum e_attr attr; //attribute
short
hit, flee, cri, flee2,
def2, mdef2,
@@ -1780,6 +1790,7 @@
#define status_get_race(bl) status_get_status_data(bl)->race
#define status_get_size(bl) status_get_status_data(bl)->size
#define status_get_mode(bl) status_get_status_data(bl)->mode
+#define status_get_attr(bl) status_get_status_data(bl)->attr
int status_get_party_id(struct block_list *bl);
int status_get_guild_id(struct block_list *bl);
int status_get_emblem_id(struct block_list *bl);
Index: src/map/battle.c
===================================================================
--- src/map/battle.c (revision 17271)
+++ src/map/battle.c (working copy)
@@ -737,6 +737,7 @@
struct status_change *sc;
struct status_change_entry *sce;
int div_ = d->div_, flag = d->flag;
+ int attr;
nullpo_ret(bl);
@@ -745,6 +746,20 @@
if( battle_config.ksprotection && mob_ksprotected(src, bl) )
return 0;
+ attr = status_get_attr(bl);
+ if (attr) {
+ if (attr&ATR_KNOCKBACK_IMMUNE) //no pushback
+ d->blewcount = 0;
+ if ( (attr&ATR_IGNOREMELEE && flag&(BF_SHORT|BF_WEAPON) == (BF_LONG|BF_WEAPON) ) //physical melee
+ || (attr&ATR_IGNOREMAGIC && flag&(BF_MAGIC) ) //magic
+ || (attr&ATR_IGNORERANGED && flag&(BF_LONG|BF_WEAPON) == (BF_LONG|BF_WEAPON) ) //physical ranged
+ || (attr&ATR_IGNOREMISC && flag&(BF_MISC) ) //misc
+ ) {
+ d->damage = d->damage2 = 1;
+ return 1; //do 1 dammage
+ }
+ }
+
if (bl->type == BL_PC) {
sd=(struct map_session_data *)bl;
//Special no damage states
@@ -760,6 +775,7 @@
if(!damage) return 0;
}
+
sc = status_get_sc(bl);
if( sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
@@ -1692,7 +1708,7 @@
//Initial flag
flag.rh=1;
flag.weapon=1;
- flag.infdef=(tstatus->mode&MD_PLANT && skill_id != RA_CLUSTERBOMB
+ flag.infdef=( (tstatus->mode&MD_PLANT) && skill_id != RA_CLUSTERBOMB
#ifdef RENEWAL
&& skill_id != HT_FREEZINGTRAP
#endif
@@ -3460,7 +3476,7 @@
#ifdef RENEWAL
if( flag.cri ){
- ATK_ADDRATE( sd->bonus.crit_atk_rate >= 100 ? sd->bonus.crit_atk_rate - 60 : 40 );
+ ATK_ADDRATE( sd->bonus.crit_atk_rate >= 100 ? sd->bonus.crit_atk_rate - 60 : 40 );
}
#endif
Index: src/map/mob.c
===================================================================
--- src/map/mob.c (revision 17271)
+++ src/map/mob.c (working copy)
@@ -3739,18 +3739,19 @@
status->mode = (int)strtol(str[25], NULL, 0);
if (!battle_config.monster_active_enable)
status->mode &= ~MD_AGGRESSIVE;
+ status->attr = (int)strtol(str[26], NULL, 0);
- status->speed = atoi(str[26]);
+ status->speed = atoi(str[27]);
status->aspd_rate = 1000;
- i = atoi(str[27]);
+ i = atoi(str[28]);
status->adelay = cap_value(i, battle_config.monster_max_aspd*2, 4000);
- i = atoi(str[28]);
+ i = atoi(str[29]);
status->amotion = cap_value(i, battle_config.monster_max_aspd, 2000);
//If the attack animation is longer than the delay, the client crops the attack animation!
//On aegis there is no real visible effect of having a recharge-time less than amotion anyway.
if (status->adelay < status->amotion)
status->adelay = status->amotion;
- status->dmotion = atoi(str[29]);
+ status->dmotion = atoi(str[30]);
if(battle_config.monster_damage_delay_rate != 100)
status->dmotion = status->dmotion * battle_config.monster_damage_delay_rate / 100;
@@ -3762,7 +3763,7 @@
// MVP EXP Bonus: MEXP
// Some new MVP's MEXP multipled by high exp-rate cause overflow. [LuzZza]
- exp = (double)atoi(str[30]) * (double)battle_config.mvp_exp_rate / 100.;
+ exp = (double)atoi(str[31]) * (double)battle_config.mvp_exp_rate / 100.;
db->mexp = (unsigned int)cap_value(exp, 0, UINT_MAX);
//Now that we know if it is an mvp or not, apply battle_config modifiers [Skotlex]
@@ -3784,13 +3785,13 @@
// MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per
for(i = 0; i < MAX_MVP_DROP; i++) {
int rate_adjust = battle_config.item_rate_mvp;;
- db->mvpitem[i].nameid = atoi(str[31+i*2]);
+ db->mvpitem[i].nameid = atoi(str[32+i*2]);
if (!db->mvpitem[i].nameid) {
db->mvpitem[i].p = 0; //No item....
continue;
}
item_dropratio_adjust(db->mvpitem[i].nameid, class_, &rate_adjust);
- db->mvpitem[i].p = mob_drop_adjust(atoi(str[32+i*2]), rate_adjust, battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
+ db->mvpitem[i].p = mob_drop_adjust(atoi(str[33+i*2]), rate_adjust, battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
//calculate and store Max available drop chance of the MVP item
if (db->mvpitem[i].p) {
@@ -3807,7 +3808,7 @@
int rate = 0, rate_adjust, type;
unsigned short ratemin, ratemax;
struct item_data *id;
- k = 31 + MAX_MVP_DROP*2 + i*2;
+ k = 32 + MAX_MVP_DROP*2 + i*2;
db->dropitem[i].nameid = atoi(str[k]);
if (!db->dropitem[i].nameid) {
db->dropitem[i].p = 0; //No drop.
@@ -3914,7 +3915,7 @@
}
}
- sv_readdb(db_path, filename[fi], ',', 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP, 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP, -1, &mob_readdb_sub);
+ sv_readdb(db_path, filename[fi], ',', 32+2*MAX_MVP_DROP+2*MAX_MOB_DROP, 32+2*MAX_MVP_DROP+2*MAX_MOB_DROP, -1, &mob_readdb_sub);
}
}
@@ -3939,12 +3940,12 @@
while( SQL_SUCCESS == Sql_NextRow(mmysql_handle) ) {
// wrap the result into a TXT-compatible format
char line[1024];
- char* str[31+2*MAX_MVP_DROP+2*MAX_MOB_DROP];
+ char* str[32+2*MAX_MVP_DROP+2*MAX_MOB_DROP];
char* p;
int i;
lines++;
- for(i = 0, p = line; i < 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP; i++)
+ for(i = 0, p = line; i < 32+2*MAX_MVP_DROP+2*MAX_MOB_DROP; i++)
{
char* data;
size_t len;