summaryrefslogtreecommitdiff
path: root/src/map/status.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/status.c')
-rw-r--r--src/map/status.c202
1 files changed, 111 insertions, 91 deletions
diff --git a/src/map/status.c b/src/map/status.c
index 29a1689a1..f6ca1ff00 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -1168,6 +1168,21 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
if( hp && !(flag&1) ) {
if( sc ) {
struct status_change_entry *sce;
+
+#ifdef DEVOTION_REFLECT_DAMAGE
+ if(src && (sce = sc->data[SC_DEVOTION])) {
+ struct block_list *d_bl = map->id2bl(sce->val1);
+
+ if(d_bl &&((d_bl->type == BL_MER && ((TBL_MER *)d_bl)->master && ((TBL_MER *)d_bl)->master->bl.id == target->id)
+ || (d_bl->type == BL_PC && ((TBL_PC *)d_bl)->devotion[sce->val2] == target->id)) && check_distance_bl(target, d_bl, sce->val3)) {
+ clif->damage(d_bl, d_bl, 0, 0, hp, 0, 0, 0);
+ status_fix_damage(NULL, d_bl, hp, 0);
+ return 0;
+ }
+ status_change_end(target, SC_DEVOTION, INVALID_TIMER);
+ }
+#endif
+
if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
status_change_end(target, SC_STONE, INVALID_TIMER);
status_change_end(target, SC_FREEZE, INVALID_TIMER);
@@ -1418,34 +1433,28 @@ int status_percent_change(struct block_list *src,struct block_list *target,signe
st = status->get_status_data(target);
-
- //It's safe now [MarkZD]
- if (hp_rate > 99)
- hp = st->hp;
- else if (hp_rate > 0)
- hp = st->hp>10000?
- hp_rate*(st->hp/100):
- ((int64)hp_rate*st->hp)/100;
- else if (hp_rate < -99)
- hp = st->max_hp;
- else if (hp_rate < 0)
- hp = st->max_hp>10000?
- (-hp_rate)*(st->max_hp/100):
- ((int64)-hp_rate*st->max_hp)/100;
+ if (hp_rate > 100)
+ hp_rate = 100;
+ else if (hp_rate < -100)
+ hp_rate = -100;
+ if (hp_rate > 0)
+ hp = APPLY_RATE(st->hp, hp_rate);
+ else
+ hp = APPLY_RATE(st->max_hp, -hp_rate);
if (hp_rate && !hp)
hp = 1;
if (flag == 2 && hp >= st->hp)
hp = st->hp-1; //Must not kill target.
- if (sp_rate > 99)
- sp = st->sp;
- else if (sp_rate > 0)
- sp = ((int64)sp_rate*st->sp)/100;
- else if (sp_rate < -99)
- sp = st->max_sp;
- else if (sp_rate < 0)
- sp = ((int64)-sp_rate)*st->max_sp/100;
+ if (sp_rate > 100)
+ sp_rate = 100;
+ else if (sp_rate < -100)
+ sp_rate = -100;
+ if (sp_rate > 0)
+ sp = APPLY_RATE(st->sp, sp_rate);
+ else
+ sp = APPLY_RATE(st->max_sp, -sp_rate);
if (sp_rate && !sp)
sp = 1;
@@ -1479,8 +1488,8 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
if (st == &status->dummy)
return 0; //Invalid target.
- hp = (int64)st->max_hp * per_hp/100;
- sp = (int64)st->max_sp * per_sp/100;
+ hp = APPLY_RATE(st->max_hp, per_hp);
+ sp = APPLY_RATE(st->max_sp, per_sp);
if(hp > st->max_hp - st->hp)
hp = st->max_hp - st->hp;
@@ -1752,14 +1761,16 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
bool is_detect = ((st->mode&MD_DETECTOR)?true:false);//god-knows-why gcc doesn't shut up until this happens
if (pc_isinvisible(sd))
return 0;
- if (tsc->option&hide_flag && !is_boss &&
- ((sd->special_state.perfect_hiding || !is_detect) ||
- (tsc->data[SC_CLOAKINGEXCEED] && is_detect)))
- return 0;
- if( tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && !skill_id )
- return 0;
- if( tsc->data[SC_STEALTHFIELD] && !is_boss )
- return 0;
+ if( tsc ) {
+ if (tsc->option&hide_flag && !is_boss &&
+ ((sd->special_state.perfect_hiding || !is_detect) ||
+ (tsc->data[SC_CLOAKINGEXCEED] && is_detect)))
+ return 0;
+ if( tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && !skill_id )
+ return 0;
+ if( tsc->data[SC_STEALTHFIELD] && !is_boss )
+ return 0;
+ }
}
break;
case BL_ITEM: //Allow targetting of items to pick'em up (or in the case of mobs, to loot them).
@@ -1792,38 +1803,41 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
//Checks whether the source can see and chase target.
int status_check_visibility(struct block_list *src, struct block_list *target) {
int view_range;
- struct status_data *st = status->get_status_data(src);
- struct status_change *tsc = status->get_sc(target);
+ struct status_change *tsc = NULL;
+
switch (src->type) {
- case BL_MOB:
- view_range = ((TBL_MOB*)src)->min_chase;
- break;
- case BL_PET:
- view_range = ((TBL_PET*)src)->db->range2;
- break;
- default:
- view_range = AREA_SIZE;
+ case BL_MOB:
+ view_range = ((TBL_MOB*)src)->min_chase;
+ break;
+ case BL_PET:
+ view_range = ((TBL_PET*)src)->db->range2;
+ break;
+ default:
+ view_range = AREA_SIZE;
}
if (src->m != target->m || !check_distance_bl(src, target, view_range))
return 0;
- if( tsc && tsc->data[SC_STEALTHFIELD] )
- return 0;
-
- switch (target->type)
- { //Check for chase-walk/hiding/cloaking opponents.
- case BL_PC:
- if ( tsc->data[SC_CLOAKINGEXCEED] && !(st->mode&MD_BOSS) )
- return 0;
- if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&MD_BOSS) &&
- ( ((TBL_PC*)target)->special_state.perfect_hiding || !(st->mode&MD_DETECTOR) ) )
- return 0;
- break;
- default:
- if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&(MD_BOSS|MD_DETECTOR)) )
+ if( ( tsc = status->get_sc(target) ) ) {
+ struct status_data *st = status->get_status_data(src);
+
+ if( tsc->data[SC_STEALTHFIELD] )
return 0;
+ switch (target->type) { //Check for chase-walk/hiding/cloaking opponents.
+ case BL_PC:
+ if ( tsc->data[SC_CLOAKINGEXCEED] && !(st->mode&MD_BOSS) )
+ return 0;
+ if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&MD_BOSS) &&
+ ( ((TBL_PC*)target)->special_state.perfect_hiding || !(st->mode&MD_DETECTOR) ) )
+ return 0;
+ break;
+ default:
+ if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&(MD_BOSS|MD_DETECTOR)) )
+ return 0;
+
+ }
}
return 1;
@@ -1836,11 +1850,11 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st)
short mod = -1;
switch( sd->weapontype2 ){ // adjustment for dual weilding
- case W_DAGGER: mod = 0; break; // 0, 1, 1
- case W_1HSWORD:
- case W_1HAXE: mod = 1;
- if( (sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS ) // 0, 2, 3
- mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2 ;
+ case W_DAGGER: mod = 0; break; // 0, 1, 1
+ case W_1HSWORD:
+ case W_1HAXE: mod = 1;
+ if( (sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS ) // 0, 2, 3
+ mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2 ;
}
amotion = ( sd->status.weapon < MAX_WEAPON_TYPE && mod < 0 )
@@ -1863,9 +1877,14 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st)
// percentual delay reduction from stats
amotion -= amotion * (4*st->agi + st->dex)/1000;
#endif
+
// raw delay adjustment from bAspd bonus
amotion += sd->bonus.aspd_add;
+ /* angra manyu disregards aspd_base and similar */
+ if( sd->equip_index[EQI_HAND_R] >= 0 && sd->status.inventory[sd->equip_index[EQI_HAND_R]].nameid == ITEMID_ANGRA_MANYU )
+ return 0;
+
return amotion;
}
@@ -2049,12 +2068,13 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) {
mbl = map->id2bl(md->master_id);
if (flag&8 && mbl) {
- struct status_data *mstatus = status->get_base_status(mbl);
- if (mstatus &&
- battle_config.slaves_inherit_speed&(mstatus->mode&MD_CANMOVE?1:2))
- mstatus->speed = mstatus->speed;
- if( mstatus->speed < 2 ) /* minimum for the unit to function properly */
- mstatus->speed = 2;
+ struct status_data *masterstatus = status->get_base_status(mbl);
+ if ( masterstatus ) {
+ if( battle_config.slaves_inherit_speed&(masterstatus->mode&MD_CANMOVE?1:2) )
+ masterstatus->speed = masterstatus->speed;
+ if( masterstatus->speed < 2 ) /* minimum for the unit to function properly */
+ masterstatus->speed = 2;
+ }
}
if (flag&16 && mbl) {
@@ -2453,10 +2473,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
pc->delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),true);
// Parse equipment.
- for(i=0;i<EQI_MAX-1;i++) {
+ for(i=0;i<EQI_MAX;i++) {
status->current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to status->current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
if(index < 0)
continue;
+ if(i == EQI_AMMO) continue;/* ammo has special handler down there */
if(i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index)
continue;
if(i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index)
@@ -2588,10 +2609,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
bstatus->def += (refinedef+50)/100;
//Parse Cards
- for(i=0;i<EQI_MAX-1;i++) {
+ for(i=0;i<EQI_MAX;i++) {
status->current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to status->current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
if(index < 0)
continue;
+ if(i == EQI_AMMO) continue;/* ammo doesn't have cards */
if(i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index)
continue;
if(i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index)
@@ -2765,9 +2787,9 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
if(sd->hprate < 0)
sd->hprate = 0;
if(sd->hprate!=100)
- bstatus->max_hp = (int64)bstatus->max_hp * sd->hprate/100;
+ bstatus->max_hp = APPLY_RATE(bstatus->max_hp, sd->hprate);
if(battle_config.hp_rate != 100)
- bstatus->max_hp = (int64)bstatus->max_hp * battle_config.hp_rate/100;
+ bstatus->max_hp = APPLY_RATE(bstatus->max_hp, battle_config.hp_rate);
if(bstatus->max_hp > (unsigned int)battle_config.max_hp)
bstatus->max_hp = battle_config.max_hp;
@@ -2799,9 +2821,9 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
if(sd->sprate < 0)
sd->sprate = 0;
if(sd->sprate!=100)
- bstatus->max_sp = (int64)bstatus->max_sp * sd->sprate/100;
+ bstatus->max_sp = APPLY_RATE(bstatus->max_sp, sd->sprate);
if(battle_config.sp_rate != 100)
- bstatus->max_sp = (int64)bstatus->max_sp * battle_config.sp_rate/100;
+ bstatus->max_sp = APPLY_RATE(bstatus->max_sp, battle_config.sp_rate);
if(bstatus->max_sp > (unsigned int)battle_config.max_sp)
bstatus->max_sp = battle_config.max_sp;
@@ -2820,11 +2842,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
&& battle_config.restart_hp_rate < 50)
bstatus->hp = bstatus->max_hp>>1;
else
- bstatus->hp = (int64)bstatus->max_hp * battle_config.restart_hp_rate/100;
+ bstatus->hp = APPLY_RATE(bstatus->max_hp, battle_config.restart_hp_rate);
if(!bstatus->hp)
bstatus->hp = 1;
- bstatus->sp = (int64)bstatus->max_sp * battle_config.restart_sp_rate /100;
+ bstatus->sp = APPLY_RATE(bstatus->max_sp, battle_config.restart_sp_rate);
if( !bstatus->sp ) /* the minimum for the respawn setting is SP:1 */
bstatus->sp = 1;
@@ -6560,10 +6582,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_NIBELUNGEN:
case SC_INTOABYSS:
case SC_SIEGFRIED:
- if( bl->type == BL_PC) {
- struct map_session_data *sd = BL_CAST(BL_PC,bl);
- if (!sd->status.party_id) return 0;
- }
+ if( sd && !sd->status.party_id )
+ return 0;
break;
case SC_ANGRIFFS_MODUS:
case SC_GOLDENE_FERSE:
@@ -7289,7 +7309,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = val1*20; //SP gained
break;
case SC_KYRIE:
- val2 = (int64)st->max_hp * (val1 * 2 + 10) / 100; //%Max HP to absorb
+ val2 = APPLY_RATE(st->max_hp, (val1 * 2 + 10)); //%Max HP to absorb
val3 = (val1 / 2 + 5); //Hits
break;
case SC_MAGICPOWER:
@@ -7946,11 +7966,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (sd->mapindex != val2)
{
int pos = (bl->x&0xFFFF)|(bl->y<<16); /// Current Coordinates
- int mapindex = sd->mapindex; /// Current Map
+ int map_index = sd->mapindex; /// Current Map
//1. Place in Jail (val2 -> Jail Map, val3 -> x, val4 -> y
pc->setpos(sd,(unsigned short)val2,val3,val4, CLR_TELEPORT);
//2. Set restore point (val3 -> return map, val4 return coords
- val3 = mapindex;
+ val3 = map_index;
val4 = pos;
} else if (!val3 || val3 == sd->mapindex) { //Use save point.
val3 = sd->status.save_point.map;
@@ -9389,15 +9409,15 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
case SC_BLADESTOP:
if(sce->val4) {
- int tid = sce->val4;
- struct block_list *tbl = map->id2bl(tid);
+ int target_id = sce->val4;
+ struct block_list *tbl = map->id2bl(target_id);
struct status_change *tsc = status->get_sc(tbl);
sce->val4 = 0;
if(tbl && tsc && tsc->data[SC_BLADESTOP]) {
tsc->data[SC_BLADESTOP]->val4 = 0;
status_change_end(tbl, SC_BLADESTOP, INVALID_TIMER);
}
- clif->bladestop(bl, tid, 0);
+ clif->bladestop(bl, target_id, 0);
}
break;
case SC_DANCING:
@@ -9695,8 +9715,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
case SC_CURSEDCIRCLE_TARGET:
{
struct block_list *src = map->id2bl(sce->val2);
- struct status_change *sc = status->get_sc(src);
- if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] && --(sc->data[SC_CURSEDCIRCLE_ATKER]->val2) == 0 ){
+ struct status_change *ssc = status->get_sc(src);
+ if( ssc && ssc->data[SC_CURSEDCIRCLE_ATKER] && --(ssc->data[SC_CURSEDCIRCLE_ATKER]->val2) == 0 ){
status_change_end(src, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER);
clif->bladestop(bl, sce->val2, 0);
}
@@ -9706,8 +9726,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if( sce->val2 ){
struct block_list *src = map->id2bl(sce->val2);
if(src) {
- struct status_change *sc = status->get_sc(src);
- sc->bs_counter--;
+ struct status_change *ssc = status->get_sc(src);
+ ssc->bs_counter--;
}
}
break;
@@ -9925,7 +9945,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
else if(opt_flag) {
clif->changeoption(bl);
if( sd && opt_flag&0x4 ) {
- clif->changelook(bl,LOOK_BASE,vd->class_);
+ clif->changelook(bl,LOOK_BASE,sd->vd.class_);
clif->get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield);
clif->changelook(bl,LOOK_WEAPON,sd->vd.weapon);
clif->changelook(bl,LOOK_SHIELD,sd->vd.shield);
@@ -10964,7 +10984,7 @@ int status_get_matk(struct block_list *bl, int flag) {
st->matk_min = status_base_matk_min(st) + (sd?sd->bonus.ematk:0);
st->matk_max = status_base_matk_max(st) + (sd?sd->bonus.ematk:0);
#endif
- if (bl->type&BL_PC && sd->matk_rate != 100) {
+ if (sd && sd->matk_rate != 100) {
st->matk_max = st->matk_max * sd->matk_rate/100;
st->matk_min = st->matk_min * sd->matk_rate/100;
}