diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 8 | ||||
-rw-r--r-- | src/map/mob.c | 34 | ||||
-rw-r--r-- | src/map/skill.c | 41 | ||||
-rw-r--r-- | src/map/status.c | 34 | ||||
-rw-r--r-- | src/map/status.h | 2 |
5 files changed, 73 insertions, 46 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index 819e4be65..93829cb6e 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -390,6 +390,12 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i damage >>= 2; //75% reduction } + if(sc->data[SC_ARMOR].timer != -1 && + sc->data[SC_ARMOR].val3&flag && + sc->data[SC_ARMOR].val4&flag) + //NPC_DEFENDER + damage -= damage*sc->data[SC_ARMOR].val2/100; + if(sc->data[SC_ENERGYCOAT].timer!=-1 && flag&BF_WEAPON){ struct status_data *status = status_get_status_data(bl); int per = 100*status->sp / status->max_sp -1; //100% should be counted as the 80~99% interval @@ -3463,7 +3469,7 @@ int battle_config_switch(const char *str) { strncmpi(str, "non",3) == 0 || strncmpi(str, "nein",4) == 0) return 0; - return atoi(str); + return (int)strtol(str,NULL,0); } static const struct battle_data_short { diff --git a/src/map/mob.c b/src/map/mob.c index 3e5338654..a1adac8fb 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -546,7 +546,7 @@ int mob_can_reach(struct mob_data *md,struct block_list *bl,int range, int state switch (state) { case MSS_RUSH: case MSS_FOLLOW: - easy = 0; //(battle_config.mob_ai&1?0:1); + easy = 0; //(battle_config.mob_ai&0x1?0:1); break; case MSS_LOOT: default: @@ -722,14 +722,14 @@ static int mob_can_changetarget(struct mob_data* md, struct block_list* target, { if (md->state.provoke_flag == target->id) return 1; - else if (!battle_config.mob_ai&4) + else if (!battle_config.mob_ai&0x4) return 0; } switch (md->state.skillstate) { case MSS_BERSERK: //Only Assist, Angry or Aggressive+CastSensor mobs can change target while attacking. if (mode&(MD_ASSIST|MD_ANGRY) || (mode&(MD_AGGRESSIVE|MD_CASTSENSOR)) == (MD_AGGRESSIVE|MD_CASTSENSOR)) - return (battle_config.mob_ai&4 || check_distance_bl(&md->bl, target, 3)); + return (battle_config.mob_ai&0x4 || check_distance_bl(&md->bl, target, 3)); else return 0; case MSS_RUSH: @@ -802,7 +802,7 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap) !(status_get_mode(&md->bl)&MD_BOSS)) return 0; //Gangster paradise protection. default: - if (!(battle_config.mob_ai&128) && (*target) && (*target)->type == BL_HOM && bl->type != BL_HOM) + if (!(battle_config.mob_ai&0x80) && (*target) && (*target)->type == BL_HOM && bl->type != BL_HOM) return 0; //For some reason Homun targets are never overriden. dist = distance_bl(&md->bl, bl); @@ -1102,20 +1102,20 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap) tbl = map_id2bl(md->target_id); if (!tbl || tbl->m != md->bl.m || (md->ud.attacktimer == -1 && !status_check_skilluse(&md->bl, tbl, 0, 0)) || - (md->ud.walktimer != -1 && !(battle_config.mob_ai&1) && !check_distance_bl(&md->bl, tbl, md->min_chase)) || + (md->ud.walktimer != -1 && !(battle_config.mob_ai&0x1) && !check_distance_bl(&md->bl, tbl, md->min_chase)) || ( tbl->type == BL_PC && !(mode&MD_BOSS) && ((TBL_PC*)tbl)->state.gangsterparadise )) { //Unlock current target. - if (tbl && tbl->m != md->bl.m && battle_config.mob_ai&64) + if (tbl && tbl->m != md->bl.m && battle_config.mob_ai&0x40) { //Chase to a nearby warp [Skotlex] tbl = NULL; map_foreachinrange (mob_ai_sub_hard_warpsearch, &md->bl, view_range, BL_NPC, md, &tbl); if (tbl) unit_walktobl(&md->bl, tbl, 0, 1); - } else if (battle_config.mob_ai&8) //Inmediately stop chasing. + } else if (battle_config.mob_ai&0x8) //Inmediately stop chasing. mob_stop_walking(md,1); - mob_unlocktarget(md, tick-(battle_config.mob_ai&8?3000:0)); //Imediately do random walk. + mob_unlocktarget(md, tick-(battle_config.mob_ai&0x8?3000:0)); //Imediately do random walk. tbl = NULL; } } @@ -1126,7 +1126,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap) if (md->attacked_id == md->target_id) { if (!battle_check_range(&md->bl, tbl, md->status.rhw.range) && - ((!can_move && battle_config.mob_ai&2) || + ((!can_move && battle_config.mob_ai&0x2) || (!mob_can_reach(md, tbl, md->min_chase, MSS_RUSH)))) { //Rude-attacked (avoid triggering due to can-walk delay). if (DIFF_TICK(tick, md->ud.canmove_tick) > 0 && @@ -1138,7 +1138,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap) if (md->bl.m != abl->m || abl->prev == NULL || (dist = distance_bl(&md->bl, abl)) >= MAX_MINCHASE || battle_check_target(bl, abl, BCT_ENEMY) <= 0 || - (battle_config.mob_ai&2 && !status_check_skilluse(bl, abl, 0, 0)) || + (battle_config.mob_ai&0x2 && !status_check_skilluse(bl, abl, 0, 0)) || !mob_can_reach(md, abl, dist+md->db->range3, MSS_RUSH) || ( //Gangster Paradise check abl->type == BL_PC && !(mode&MD_BOSS) && @@ -1154,7 +1154,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap) unit_walktoxy(&md->bl, md->bl.x + dist * mask[dir][0], md->bl.y + dist * mask[dir][1], 0); } } - } else if (!(battle_config.mob_ai&2) && !status_check_skilluse(bl, abl, 0, 0)) { + } else if (!(battle_config.mob_ai&0x2) && !status_check_skilluse(bl, abl, 0, 0)) { //Can't attack back, but didn't invoke a rude attacked skill... md->attacked_id = 0; //Simply unlock, shouldn't attempt to run away when in dumb_ai mode. } else { //Attackable @@ -1238,7 +1238,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap) md->state.skillstate = md->state.aggressive?MSS_FOLLOW:MSS_RUSH; if (md->ud.walktimer != -1 && md->ud.target == tbl->id && ( - !(battle_config.mob_ai&1) || + !(battle_config.mob_ai&0x1) || check_distance_blxy(tbl, md->ud.to_x, md->ud.to_y, md->status.rhw.range) )) //Current target tile is still within attack range. return 0; @@ -1352,7 +1352,7 @@ static int mob_ai_sub_lazy(DBKey key,void * data,va_list ap) if(md->bl.type!=BL_MOB || md->bl.prev == NULL) return 0; - if (md->nd || (battle_config.mob_ai&32 && map[md->bl.m].users>0)) + if (md->nd || (battle_config.mob_ai&0x20 && map[md->bl.m].users>0)) return mob_ai_sub_hard(&md->bl, ap); tick=va_arg(ap,unsigned int); @@ -1421,7 +1421,7 @@ static int mob_ai_lazy(int tid,unsigned int tick,int id,int data) static int mob_ai_hard(int tid,unsigned int tick,int id,int data) { - if (battle_config.mob_ai&32) + if (battle_config.mob_ai&0x20) map_foreachiddb(mob_ai_sub_lazy,tick); else clif_foreachclient(mob_ai_sub_foreachclient,tick); @@ -2547,7 +2547,7 @@ int mob_getfriendhprate_sub(struct block_list *bl,va_list ap) max_rate=va_arg(ap,int); fr=va_arg(ap,struct block_list **); - if( md->bl.id == bl->id && !(battle_config.mob_ai&16)) + if( md->bl.id == bl->id && !(battle_config.mob_ai&0x10)) return 0; if ((*fr) != NULL) //A friend was already found. @@ -2604,7 +2604,7 @@ int mob_getfriendstatus_sub(struct block_list *bl,va_list ap) nullpo_retr(0, md=(struct mob_data *)bl); nullpo_retr(0, mmd=va_arg(ap,struct mob_data *)); - if( mmd->bl.id == bl->id && !(battle_config.mob_ai&16) ) + if( mmd->bl.id == bl->id && !(battle_config.mob_ai&0x10) ) return 0; if (battle_check_target(&mmd->bl,bl,BCT_ENEMY)>0) @@ -2657,7 +2657,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) return 0; //Skill act delay only affects non-event skills. //Pick a starting position and loop from that. - i = battle_config.mob_ai&256?rand()%md->db->maxskill:0; + i = battle_config.mob_ai&0x100?rand()%md->db->maxskill:0; for (n = 0; n < md->db->maxskill; i++, n++) { int c2, flag = 0; diff --git a/src/map/skill.c b/src/map/skill.c index 610fc5790..c4a035f07 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -3537,17 +3537,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } break; - case AL_INCAGI: - case AL_BLESSING: - case PR_SLOWPOISON: - case PR_IMPOSITIO: - case PR_LEXAETERNA: - case PR_SUFFRAGIUM: - case PR_BENEDICTIO: - clif_skill_nodamage(src,bl,skillid,skilllv, - sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv))); - break; - case CR_PROVIDENCE: if(sd && dstsd){ //Check they are not another crusader [Skotlex] if ((dstsd->class_&MAPID_UPPERMASK) == MAPID_CRUSADER) { @@ -3682,6 +3671,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in sc_start4(src,SC_WATK_ELEMENT,100,3,20,0,0,skill_get_time2(skillid, skilllv)); if (sd) skill_blockpc_start (sd, skillid, skill_get_time(skillid, skilllv)); break; + + case AL_INCAGI: + case AL_BLESSING: + case PR_SLOWPOISON: + case PR_IMPOSITIO: + case PR_LEXAETERNA: + case PR_SUFFRAGIUM: + case PR_BENEDICTIO: case LK_BERSERK: case KN_AUTOCOUNTER: case KN_TWOHANDQUICKEN: @@ -3722,6 +3719,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case NJ_KASUMIKIRI: case NJ_UTSUSEMI: case NJ_NEN: + case NPC_DEFENDER: clif_skill_nodamage(src,bl,skillid,skilllv, sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv))); break; @@ -4837,8 +4835,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in break; case NPC_REBIRTH: - //New rebirth System uses Kaizel lv1. [Skotlex] - sc_start(bl,type,100,1,skill_get_time(SL_KAIZEL,skilllv)); + //New rebirth System uses Kaizel [Skotlex] + sc_start(bl,type,100,skilllv,skill_get_time(SL_KAIZEL,skilllv)); break; case NPC_DARKBLESSING: @@ -4936,10 +4934,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } break; - case NPC_DEFENDER: - clif_skill_nodamage(src,bl,skillid,skilllv,1); - break; - case NPC_POWERUP: sc_start(bl,SC_INCATKRATE,100,40*skilllv,skill_get_time(skillid, skilllv)); clif_skill_nodamage(src,bl,skillid,skilllv, @@ -5661,11 +5655,18 @@ int skill_castend_id (int tid, unsigned int tick, int id, int data) if(md) { if(ud->skillid != NPC_EMOTION)//Set afterskill delay. md->last_thinktime=tick + (tid==-1?md->status.adelay:md->status.amotion); + if(battle_config.mob_ai&0x200) { //pass on delay to same skill. + int i; + for (i = 0; i < md->db->maxskill; i++) + if (md->db->skill[i].skill_id == ud->skillid) + md->skilldelay[i]=tick; + } else if(md->skillidx >= 0) { md->skilldelay[md->skillidx]=tick; if (md->db->skill[md->skillidx].emotion >= 0) clif_emotion(src, md->db->skill[md->skillidx].emotion); } + } if(src != target && battle_config.skill_add_range && @@ -5844,6 +5845,12 @@ int skill_castend_pos (int tid, unsigned int tick, int id, int data) if(md) { md->last_thinktime=tick + (tid==-1?md->status.adelay:md->status.amotion); + if(battle_config.mob_ai&0x200) { //pass on delay to same skill. + int i; + for (i = 0; i < md->db->maxskill; i++) + if (md->db->skill[i].skill_id == ud->skillid) + md->skilldelay[i]=tick; + } else if(md->skillidx >= 0) { md->skilldelay[md->skillidx]=tick; if (md->db->skill[md->skillidx].emotion >= 0) diff --git a/src/map/status.c b/src/map/status.c index ef3e73021..7cd554b3e 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -215,7 +215,7 @@ void initChangeTables(void) { add_sc(NPC_SLEEPATTACK, SC_SLEEP);
set_sc(NPC_KEEPING, SC_KEEPING, SI_BLANK, SCB_DEF);
add_sc(NPC_DARKBLESSING, SC_COMA);
- set_sc(NPC_BARRIER, SC_BARRIER, SI_BLANK, SCB_MDEF);
+ set_sc(NPC_BARRIER, SC_BARRIER, SI_BLANK, SCB_MDEF|SCB_DEF);
add_sc(NPC_LICK, SC_STUN);
set_sc(NPC_HALLUCINATION, SC_HALLUCINATION, SI_HALLUCINATION, SCB_NONE);
add_sc(NPC_REBIRTH, SC_KAIZEL);
@@ -2946,12 +2946,17 @@ void status_calc_bl(struct block_list *bl, unsigned long flag) if(flag&SCB_WATK) {
status->rhw.atk = status_calc_watk(bl, sc, b_status->rhw.atk);
- status->rhw.atk2 = status_calc_watk(bl, sc, b_status->rhw.atk2);
+ if (!sd) //Should not affect weapon refine bonus
+ status->rhw.atk2 = status_calc_watk(bl, sc, b_status->rhw.atk2);
if(status->lhw && b_status->lhw && b_status->lhw->atk) {
- if (sd) sd->state.lr_flag = 1;
- status->lhw->atk = status_calc_watk(bl, sc, b_status->lhw->atk);
- status->lhw->atk2 = status_calc_watk(bl, sc, b_status->lhw->atk2);
- if (sd) sd->state.lr_flag = 0;
+ if (sd) {
+ sd->state.lr_flag = 1;
+ status->lhw->atk = status_calc_watk(bl, sc, b_status->lhw->atk);
+ sd->state.lr_flag = 0;
+ } else {
+ status->lhw->atk = status_calc_watk(bl, sc, b_status->lhw->atk);
+ status->lhw->atk2= status_calc_watk(bl, sc, b_status->lhw->atk2);
+ }
}
}
@@ -3512,16 +3517,18 @@ static signed char status_calc_def(struct block_list *bl, struct status_change * if(sc->data[SC_BERSERK].timer!=-1)
return 0;
- if(sc->data[SC_KEEPING].timer!=-1)
- return 100;
if(sc->data[SC_SKA].timer != -1)
return sc->data[SC_SKA].val3;
- if (sc->data[SC_DEFENCE].timer != -1) //[orn]
- def += sc->data[SC_DEFENCE].val2 ;
+ if(sc->data[SC_BARRIER].timer!=-1)
+ return 100;
+ if(sc->data[SC_KEEPING].timer!=-1)
+ return 90;
if(sc->data[SC_STEELBODY].timer!=-1)
return 90;
if(sc->data[SC_DRUMBATTLE].timer!=-1)
def += sc->data[SC_DRUMBATTLE].val3;
+ if (sc->data[SC_DEFENCE].timer != -1) //[orn]
+ def += sc->data[SC_DEFENCE].val2 ;
if(sc->data[SC_INCDEFRATE].timer!=-1)
def += def * sc->data[SC_INCDEFRATE].val1/100;
if(sc->data[SC_FREEZE].timer!=-1)
@@ -5611,6 +5618,13 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val if (map[bl->m].flag.pvp)
tick /=2;
break;
+ case SC_ARMOR:
+ //NPC_DEFENDER:
+ val2 = 80; //Damage reduction
+ //Attack requirements to be blocked:
+ val3 = BF_LONG; //Range
+ val4 = BF_WEAPON|BF_MISC; //Type
+ break;
case SC_INTRAVISION:
case SC_ARMOR_ELEMENT:
//Place here SCs that have no SCB_* data, no skill associated, no ICON
diff --git a/src/map/status.h b/src/map/status.h index df8adafc7..d8da56888 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -112,7 +112,7 @@ enum { SC_DELUGE,
SC_VIOLENTGALE,
SC_WATK_ELEMENT,
- SC_LANDPROTECTOR, //Available
+ SC_ARMOR,
SC_ARMOR_ELEMENT,
SC_NOCHAT,
SC_BABY,
|