this code?
int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 damage,int atk_elem,int def_type, int def_lv)
{
struct status_change *sc = NULL, *tsc = NULL;
int ratio;
if (src) sc = status_get_sc(src);
if (target) tsc = status_get_sc(target);
if (!CHK_ELEMENT(atk_elem))
atk_elem = rnd()%ELE_ALL;
if (!CHK_ELEMENT(def_type) || !CHK_ELEMENT_LEVEL(def_lv)) {
ShowError("battle_attr_fix: unknown attribute type: atk=%d def_type=%d def_lv=%d\n",atk_elem,def_type,def_lv);
return damage;
}
ratio = attr_fix_table[def_lv-1][atk_elem][def_type];
if (sc && sc->count) { //increase dmg by src status
switch(atk_elem){
case ELE_FIRE:
if (sc->data[SC_VOLCANO])
ratio += sc->data[SC_VOLCANO]->val3;
break;
case ELE_WIND:
if (sc->data[SC_VIOLENTGALE])
ratio += sc->data[SC_VIOLENTGALE]->val3;
break;
case ELE_WATER:
if (sc->data[SC_DELUGE])
ratio += sc->data[SC_DELUGE]->val3;
break;
case ELE_GHOST:
if (sc->data[SC_TELEKINESIS_INTENSE])
ratio += sc->data[SC_TELEKINESIS_INTENSE]->val3;
break;
}
}
if( target && target->type == BL_SKILL ) {
if( atk_elem == ELE_FIRE && battle_getcurrentskill(target) == GN_WALLOFTHORN ) {
struct skill_unit *su = (struct skill_unit*)target;
struct skill_unit_group *sg;
struct block_list *src2;
if( !su || !su->alive || (sg = su->group) == NULL || !sg || sg->val3 == -1 ||
(src2 = map_id2bl(sg->src_id)) == NULL || status_isdead(src2) )
return 0;
if( sg->unit_id != UNT_FIREWALL ) {
int x,y;
x = sg->val3 >> 16;
y = sg->val3 & 0xffff;
skill_unitsetting(src2,su->group->skill_id,su->group->skill_lv,x,y,1);
sg->val3 = -1;
sg->limit = DIFF_TICK(gettick(),sg->tick)+300;
}
}
}
if (tsc && tsc->count) { //increase dmg by target status
switch(atk_elem) {
case ELE_FIRE:
if (tsc->data[SC_SPIDERWEB]) {
tsc->data[SC_SPIDERWEB]->val1 = 0; // free to move now
if (tsc->data[SC_SPIDERWEB]->val2-- > 0)
ratio += 100; // double damage
if (tsc->data[SC_SPIDERWEB]->val2 == 0)
status_change_end(target, SC_SPIDERWEB, INVALID_TIMER);
}
if (tsc->data[SC_THORNSTRAP])
status_change_end(target, SC_THORNSTRAP, INVALID_TIMER);
if (tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB)
status_change_end(target, SC_CRYSTALIZE, INVALID_TIMER);
if (tsc->data[SC_EARTH_INSIGNIA])
ratio += 50;
if (tsc->data[SC_ASH])
ratio += 50;
break;
case ELE_HOLY:
if (tsc->data[SC_ORATIO])
ratio += tsc->data[SC_ORATIO]->val1 * 2;
break;
case ELE_POISON:
if (tsc->data[SC_VENOMIMPRESS])
ratio += tsc->data[SC_VENOMIMPRESS]->val2;
break;
case ELE_WIND:
if (tsc->data[SC_CRYSTALIZE] && target->type != BL_MOB)
ratio += 50;
if (tsc->data[SC_WATER_INSIGNIA])
ratio += 50;
break;
case ELE_WATER:
if (tsc->data[SC_FIRE_INSIGNIA])
ratio += 50;
break;
case ELE_EARTH:
if (tsc->data[SC_WIND_INSIGNIA])
ratio += 50;
status_change_end(target, SC_MAGNETICFIELD, INVALID_TIMER); //freed if received earth dmg
break;
case ELE_NEUTRAL:
if (tsc->data[SC_ANTI_M_BLAST])
ratio += tsc->data[SC_ANTI_M_BLAST]->val2;
break;
}
}
if (ratio < 100)
damage = damage - (damage * (100 - ratio) / 100);
else
damage = damage + (damage * (ratio - 100) / 100);
return i64max(damage,0);
}