summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog.txt12
-rw-r--r--db/skill_cast_db.txt2
-rw-r--r--db/skill_db.txt2
-rw-r--r--src/map/battle.c4
-rw-r--r--src/map/clif.c2
-rw-r--r--src/map/mob.c10
-rw-r--r--src/map/skill.c46
-rw-r--r--src/map/status.c120
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;
}