From 3eb666be67a0a786ae11180570b9f08a098c453c Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@54d463be-8e91-2dee-dedb-b68131a5f0ec> Date: Sat, 5 Feb 2005 09:38:27 +0000 Subject: * Updated Sharp Shooting AoE code * Tidied up explicit typecasts in status_get_max_hp * Non-MVP / miniboss summoned monsters should give exp * Fixed a typo that was blocking packet version 5 clients (628sak) from logging in git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/stable@1042 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog.txt | 12 ++++++ db/skill_cast_db.txt | 2 +- db/skill_db.txt | 2 +- src/map/battle.c | 4 +- src/map/clif.c | 2 +- src/map/mob.c | 10 ++++- src/map/skill.c | 46 +++++++++++++++++++- src/map/status.c | 120 +++++++++++++++++++++++++++++---------------------- 8 files changed, 137 insertions(+), 61 deletions(-) diff --git a/Changelog.txt b/Changelog.txt index 596c713e5..11b7d012a 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,5 +1,17 @@ Date Added +02/05 + * Updated Sharp Shooting AoE code, thanks to Neodis / k-Athena [celest] + - Update: Adapt jA's path_search algorithm and removed the need of struct + 'dev' in map_session_data + - Update: Increase range to 14 + * Tidied up explicit typecasts in status_get_max_hp, thanks to Ilpalazzo-sama + [celest] + * Non-MVP / miniboss summoned monsters should give exp, my mistake ^^; [celest] + Note:- minibosses are considered a 'Boss' as well, not just MVP's + * Fixed a typo that was preventing packet version 5 clients (628sak) from + logging in (it was supposed to only block those with 4 or below) [celest] + 02/04 * Fixed more compile signed/unsigned errors [SVN 1040: MouseJstr] * TXT convertors now read the import command in inter_athena.conf diff --git a/db/skill_cast_db.txt b/db/skill_cast_db.txt index 774ca5aa0..01bebcd24 100644 --- a/db/skill_cast_db.txt +++ b/db/skill_cast_db.txt @@ -242,7 +242,7 @@ 379,0,1000:1200:1400:1600:1800:2000:2200:2400:2600:2800,0,0 //ASC_BREAKER 380,0,0,30000,0 //SN_SIGHT#トゥルーサイト# 381,1000,1200,0,0,0 //SN_FALCONASSAULT -382,2000,0,0,0 //SN_SHARPSHOOTING +382,2000,500,0,0 //SN_SHARPSHOOTING 383,2000:2400:2800:3200:3600:4000:4400:4800:5200:5600,0,130000:160000:190000:220000:250000:280000:310000:340000:370000:400000,0 //SN_WINDWALK#ウインドウォーク# 384,5000:5000:6000:6000:7000:7000:8000:8000:9000:10000,0,15000:20000:25000:30000:35000:40000:45000:50000:55000:60000,5000 //WS_MELTDOWN#メルトダウン# diff --git a/db/skill_db.txt b/db/skill_db.txt index 41c563d17..785950be6 100644 --- a/db/skill_db.txt +++ b/db/skill_db.txt @@ -439,7 +439,7 @@ 379,5,6,1,0,0,10,1,no,0,0,0,weapon,0 //ASC_BREAKER#?ウルブレ?カ?# 380,0,6,4,0,1,10,1,no,0,0,0,weapon,0 //SN_SIGHT#トゥル?サイト# 381,9,8,1,0,0,5,1:2:3:4:5,yes,0,0,0,misc,0 //SN_FALCONASSAULT#フ?ルコンアサルト# -382,9,8,1,0,0,5,1,no,0,0,0,weapon,0 //SN_SHARPSHOOTING#シャ?プシュ?ティング# +382,14,8,1,0,0,5,1,no,0,0,0,weapon,0 //SN_SHARPSHOOTING#シャ?プシュ?ティング# 383,0,6,4,0,1,10,1,yes,0,0,0,magic,0 //SN_WINDWALK#ウインドウォ?ク# 384,0,0,4,0,1,10,1,yes,0,0,0,magic,0 //WS_MELTDOWN#メルト?ウン# 385,0,0,4,0,1,1,1,yes,0,0,0,magic,0 //WS_CREATECOIN#クリエイトコイン# diff --git a/src/map/battle.c b/src/map/battle.c index b9908f835..1bc612e0c 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1793,14 +1793,14 @@ static struct Damage battle_calc_pc_weapon_attack( cri <<= 1; } - if(skill_num == SN_SHARPSHOOTING && rand()%100 < 50) + if(skill_num == SN_SHARPSHOOTING) cri += 200; } if(tsd && tsd->critical_def) cri = cri * (100-tsd->critical_def) / 100; - if(da == 0 && (skill_num==0 || skill_num == KN_AUTOCOUNTER || skill_num == SN_SHARPSHOOTING) && skill_lv >= 0 && //ダブルアタックが発動していない + if(da == 0 && (skill_num==0 || skill_num == KN_AUTOCOUNTER || skill_num == SN_SHARPSHOOTING) && //ダブルアタックが発動していない (rand() % 1000) < cri) // 判定(スキルの場合は無視) { damage += atkmax; diff --git a/src/map/clif.c b/src/map/clif.c index 6ce1fc9c6..16c3b4589 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10662,7 +10662,7 @@ static int clif_parse(int fd) { } // check if version is accepted - if (packet_ver <= 5 || // reject really old client versions + if (packet_ver < 5 || // reject really old client versions (packet_ver <= 9 && (battle_config.packet_ver_flag & 1) == 0) || // older than 6sept04 (packet_ver == 10 && (battle_config.packet_ver_flag & 2) == 0) || (packet_ver == 11 && (battle_config.packet_ver_flag & 4) == 0) || diff --git a/src/map/mob.c b/src/map/mob.c index 1068b515a..a8b9aa8cb 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2158,6 +2158,7 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type) int mvp_damage,max_hp; unsigned int tick = gettick(); struct map_session_data *mvp_sd = NULL, *second_sd = NULL,*third_sd = NULL; + struct block_list *master = NULL; double tdmg,temp; struct item item; int ret; @@ -2470,7 +2471,11 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type) if(sd && battle_config.pk_mode && (mob_db[md->class_].lv - sd->status.base_level >= 20)) { job_exp*=1.15; // pk_mode additional exp if monster >20 levels [Valaris] } - if(md->master_id || (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1)) { // for summoned creatures [Valaris] + if(md->master_id) { + master = map_id2bl(md->master_id); + } + if((master && status_get_mode(master)&0x20) || // check if its master is a boss (MVP's and minibosses) + (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1)) { // for summoned creatures [Valaris] base_exp = 0; job_exp = 0; } @@ -2530,7 +2535,8 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type) struct delay_item_drop *ditem; int drop_rate; - if(md->master_id || (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1)) // Added [Valaris] + if((master && status_get_mode(master)&0x20) || // check if its master is a boss (MVP's and minibosses) + (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1)) // Added [Valaris] break; // End if(mob_db[md->class_].dropitem[i].nameid <= 0) diff --git a/src/map/skill.c b/src/map/skill.c index f06cafba4..d4963e521 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -33,8 +33,8 @@ #endif #define SKILLUNITTIMER_INVERVAL 100 - #define STATE_BLIND 0x10 +#define swap(x,y) { int t; t = x; x = y; y = t; } /* スキル番?=>ステ?タス異常番??換テ?ブル */ int SkillStatusChangeTable[]={ /* skill.hのenumのSC_***とあわせること */ @@ -1673,6 +1673,9 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds case NPC_SELFDESTRUCTION: case NPC_SELFDESTRUCTION2: break; + case SN_SHARPSHOOTING: + clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,0,0,0); + break; default: clif_skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, skillid, (lv!=0)?lv:skilllv, (skillid==0)? 5:type ); } @@ -2284,13 +2287,52 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s case LK_JOINTBEAT: /* ジョイントビ?ト */ // case PA_PRESSURE: /* プレッシャ? */ // case PA_SACRIFICE: /* サクリファイス */ - case SN_SHARPSHOOTING: /* シャ?プシュ?ティング */ +// case SN_SHARPSHOOTING: /* シャ?プシュ?ティング */ case CG_ARROWVULCAN: /* アロ?バルカン */ case ASC_BREAKER: /* ソウルブレ?カ? */ case HW_MAGICCRASHER: /* マジッククラッシャ? */ case ITM_TOMAHAWK: skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); break; + + case SN_SHARPSHOOTING: /* シャ?プシュ?ティング */ + { + int dx, dy, wx = 0, wy = 0; + int weight, num = 0; + int x1 = src->x, y1 = src->y; + int x0 = bl->x, y0 = bl->y; + + dx = (x1 - x0); + if (dx < 0) { + swap(x0, x1); + swap(y0, y1); + dx = -dx; + } + dy = (y1 - y0); + weight = dx > abs(dy) ? dx : abs(y1 - y0); + while ((x0 != x1 || y0 != y1) && num < skill_get_range(skillid)) { + wx += dx; + wy += dy; + if (wx >= weight) { + wx -= weight; x0 ++; + } + if (wy >= weight) { + wy -= weight; y0 ++; + } else if (wy < 0) { + wy += weight; y0 --; + } + if (x0 == x1) { + if (dy > 0) { y0++; } + else { y0--; } + } + map_foreachinarea (skill_attack_area,src->m,x0,y0,x0,y0,0, + BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); + num++; // make sure it doesn't run infinitely + } + clif_skill_nodamage(src,bl,skillid,skilllv,1); + } + break; + case PA_PRESSURE: /* プレッシャ? */ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); if (rand()%100 < 50) diff --git a/src/map/status.c b/src/map/status.c index e9ead5a03..03cbd37b2 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1383,16 +1383,22 @@ int status_get_hp(struct block_list *bl) int status_get_max_hp(struct block_list *bl) { nullpo_retr(1, bl); + if(bl->type==BL_PC && ((struct map_session_data *)bl)) return ((struct map_session_data *)bl)->status.max_hp; else { - struct status_change *sc_data=status_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; + struct status_change *sc_data; + int max_hp = 1; + + if(bl->type == BL_MOB) { + struct mob_data *md; + nullpo_retr(1, md = (struct mob_data *)bl); + max_hp = mob_db[md->class_].max_hp; + if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris] - max_hp+=(((struct mob_data *)bl)->level - mob_db[((struct mob_data *)bl)->class_].lv)*status_get_vit(bl); - if(mob_db[((struct mob_data*)bl)->class_].mexp > 0) { + max_hp += (md->level - mob_db[md->class_].lv) * status_get_vit(bl); + + if(mob_db[md->class_].mexp > 0) { if(battle_config.mvp_hp_rate != 100) max_hp = (max_hp * battle_config.mvp_hp_rate)/100; } @@ -1401,9 +1407,12 @@ int status_get_max_hp(struct block_list *bl) max_hp = (max_hp * battle_config.monster_hp_rate)/100; } } - else if(bl->type==BL_PET && ((struct pet_data*)bl)) { - max_hp = mob_db[((struct pet_data*)bl)->class_].max_hp; - if(mob_db[((struct pet_data*)bl)->class_].mexp > 0) { + else if(bl->type == BL_PET) { + struct pet_data *pd; + nullpo_retr(1, pd = (struct pet_data*)bl); + max_hp = mob_db[pd->class_].max_hp; + + if(mob_db[pd->class_].mexp > 0) { if(battle_config.mvp_hp_rate != 100) max_hp = (max_hp * battle_config.mvp_hp_rate)/100; } @@ -1412,11 +1421,13 @@ int status_get_max_hp(struct block_list *bl) max_hp = (max_hp * battle_config.monster_hp_rate)/100; } } + + sc_data = status_get_sc_data(bl); if(sc_data) { - if(sc_data[SC_APPLEIDUN].timer!=-1) - max_hp += ((5+sc_data[SC_APPLEIDUN].val1*2+((sc_data[SC_APPLEIDUN].val2+1)>>1) - +sc_data[SC_APPLEIDUN].val3/10) * max_hp)/100; - if(sc_data[SC_GOSPEL].timer!=-1 && + if(sc_data[SC_APPLEIDUN].timer != -1) + max_hp += ((5 + sc_data[SC_APPLEIDUN].val1 * 2 + ((sc_data[SC_APPLEIDUN].val2 + 1) >> 1) + + sc_data[SC_APPLEIDUN].val3 / 10) * max_hp)/100; + if(sc_data[SC_GOSPEL].timer != -1 && sc_data[SC_GOSPEL].val4 == BCT_PARTY && sc_data[SC_GOSPEL].val3 == 4) max_hp += max_hp * 25 / 100; @@ -2108,36 +2119,39 @@ int status_get_mdef(struct block_list *bl) */ int status_get_def2(struct block_list *bl) { - struct status_change *sc_data; - int def2=1; - + int def2 = 1; nullpo_retr(1, bl); - sc_data=status_get_sc_data(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; - else if(bl->type==BL_PET) - def2 = mob_db[((struct pet_data *)bl)->class_].vit; - - if(bl->type != BL_PC && sc_data) { - if( sc_data[SC_ANGELUS].timer!=-1) - def2 = def2*(110+5*sc_data[SC_ANGELUS].val1)/100; - if( sc_data[SC_PROVOKE].timer!=-1) - def2 = (def2*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100; - if(sc_data[SC_POISON].timer!=-1) - def2 = def2*75/100; - //コンセントレーション時は減算 - if( sc_data[SC_CONCENTRATION].timer!=-1) - def2 = def2*(100 - 5*sc_data[SC_CONCENTRATION].val1)/100; - - if(sc_data[SC_GOSPEL].timer!=-1) { - if (sc_data[SC_GOSPEL].val4 == BCT_PARTY && - sc_data[SC_GOSPEL].val3 == 11) - def2 += def2*25/100; - else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY && - sc_data[SC_GOSPEL].val3 == 5) - def2 = 0; + return ((struct map_session_data *)bl)->def2; + else { + struct status_change *sc_data; + + if(bl->type==BL_MOB) + def2 = mob_db[((struct mob_data *)bl)->class_].vit; + else if(bl->type==BL_PET) + def2 = mob_db[((struct pet_data *)bl)->class_].vit; + + sc_data = status_get_sc_data(bl); + if(sc_data) { + if(sc_data[SC_ANGELUS].timer != -1) + def2 = def2*(110+5*sc_data[SC_ANGELUS].val1)/100; + if(sc_data[SC_PROVOKE].timer!=-1) + def2 = (def2*(100 - 6*sc_data[SC_PROVOKE].val1)+50)/100; + if(sc_data[SC_POISON].timer!=-1) + def2 = def2*75/100; + //コンセントレーション時は減算 + if( sc_data[SC_CONCENTRATION].timer!=-1) + def2 = def2*(100 - 5*sc_data[SC_CONCENTRATION].val1)/100; + + if(sc_data[SC_GOSPEL].timer!=-1) { + if (sc_data[SC_GOSPEL].val4 == BCT_PARTY && + sc_data[SC_GOSPEL].val3 == 11) + def2 += def2*25/100; + else if (sc_data[SC_GOSPEL].val4 == BCT_ENEMY && + sc_data[SC_GOSPEL].val3 == 5) + def2 = 0; + } } } if(def2 < 1) def2 = 1; @@ -2150,20 +2164,22 @@ int status_get_def2(struct block_list *bl) */ int status_get_mdef2(struct block_list *bl) { - int mdef2=0; - struct status_change *sc_data=status_get_sc_data(bl); - + int mdef2 = 0; 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); - 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) - mdef2 = mob_db[((struct pet_data *)bl)->class_].int_ + (mob_db[((struct pet_data *)bl)->class_].vit>>1); - if(sc_data) { - if( sc_data[SC_MINDBREAKER].timer!=-1 && bl->type != BL_PC) + + if(bl->type == BL_PC) + return ((struct map_session_data *)bl)->mdef2 + (((struct map_session_data *)bl)->paramc[2]>>1); + else { + struct status_change *sc_data = status_get_sc_data(bl); + if(bl->type == BL_MOB) + mdef2 = mob_db[((struct mob_data *)bl)->class_].int_ + (mob_db[((struct mob_data *)bl)->class_].vit>>1); + else if(bl->type == BL_PET) + mdef2 = mob_db[((struct pet_data *)bl)->class_].int_ + (mob_db[((struct pet_data *)bl)->class_].vit>>1); + if(sc_data) { + if(sc_data[SC_MINDBREAKER].timer!=-1) mdef2 -= (mdef2*6*sc_data[SC_MINDBREAKER].val1)/100; } + } if(mdef2 < 0) mdef2 = 0; return mdef2; } -- cgit v1.2.3-70-g09d2