diff options
author | skotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2006-02-17 21:33:54 +0000 |
---|---|---|
committer | skotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2006-02-17 21:33:54 +0000 |
commit | f06d3b26ad08bb054b6593fac39042cb20649c36 (patch) | |
tree | 53861eeb70d343a9d429f35d1cf29b1139c828b1 /src | |
parent | ff4c178309e0e18939d4077283a689e356311ce8 (diff) | |
download | hercules-f06d3b26ad08bb054b6593fac39042cb20649c36.tar.gz hercules-f06d3b26ad08bb054b6593fac39042cb20649c36.tar.bz2 hercules-f06d3b26ad08bb054b6593fac39042cb20649c36.tar.xz hercules-f06d3b26ad08bb054b6593fac39042cb20649c36.zip |
- Added NK value 3: No damage + area of effect skill (NK_SPLASH_NO_DAMAGE)
- Removed the double-cast specific code and made it use skill_addtimerskill instead.
- Modified party_foreachsamemap so that it returns to addition of the return value of the functions invoked. Type has been changed for "range", when 0, it scans all party members in the map.
- Updated most skill/battle code to use map_foreachinrange rather than map_foreachinarea.
- map_foreachinrange does not performs an exact range check anymore. However the relevant code is commented and anyone can enable it.
- Updated most skills to use skill_get_splash instead of hardcoded ranges.
- Added function skill_get_casttype which returns the type of function that should be invoked for that skill: skill_castend_pos, skill_castend_nodamage_id or skill_castend_damage_id.
- self skills are sent to skill_castend_nodamage_id regardless of nk (nk should signal if the skill causes damage above everything, it is used on autospell/effects).
- Due to the previous change, self skills where the target and src are different, and don't have an nk of no damage, they are sent to castend_damage_id (assumed target auto-selected skills)
- Applied the relevant updates to db/skill_db.txt, db/skill_unit_db also got updated, as trap ranges should all be 1, the splash damage range is defined now in skill_db
- Cleaned up the implementation of the code related to Gangster's paradise and TK_HP/SPtime
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5313 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r-- | src/map/battle.c | 54 | ||||
-rw-r--r-- | src/map/map.c | 12 | ||||
-rw-r--r-- | src/map/map.h | 2 | ||||
-rw-r--r-- | src/map/mob.c | 82 | ||||
-rw-r--r-- | src/map/party.c | 25 | ||||
-rw-r--r-- | src/map/party.h | 2 | ||||
-rw-r--r-- | src/map/pc.c | 5 | ||||
-rw-r--r-- | src/map/pet.c | 34 | ||||
-rw-r--r-- | src/map/skill.c | 681 | ||||
-rw-r--r-- | src/map/skill.h | 15 | ||||
-rw-r--r-- | src/map/status.c | 16 |
11 files changed, 383 insertions, 545 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index cb878a1d2..f7965a5b7 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -37,14 +37,13 @@ static struct eri *delay_damage_ers; //For battle delay damage structures. */
static int battle_counttargeted_sub(struct block_list *bl, va_list ap)
{
- int id, *c, target_lv;
+ int id, target_lv;
struct block_list *src;
nullpo_retr(0, bl);
nullpo_retr(0, ap);
id = va_arg(ap,int);
- nullpo_retr(0, c = va_arg(ap, int *));
src = va_arg(ap,struct block_list *);
target_lv = va_arg(ap,int);
@@ -53,18 +52,18 @@ static int battle_counttargeted_sub(struct block_list *bl, va_list ap) if (bl->type == BL_PC) {
struct map_session_data *sd = (struct map_session_data *)bl;
if (sd && sd->attacktarget == id && sd->attacktimer != -1 && sd->attacktarget_lv >= target_lv)
- (*c)++;
+ return 1;
}
else if (bl->type == BL_MOB) {
struct mob_data *md = (struct mob_data *)bl;
if (md && md->target_id == id && md->timer != -1 && md->state.state == MS_ATTACK && md->target_lv >= target_lv)
- (*c)++;
+ return 1;
//printf("md->target_lv:%d, target_lv:%d\n", md->target_lv, target_lv);
}
else if (bl->type == BL_PET) {
struct pet_data *pd = (struct pet_data *)bl;
if (pd && pd->target_id == id && pd->timer != -1 && pd->state.state == MS_ATTACK && pd->target_lv >= target_lv)
- (*c)++;
+ return 1;
}
return 0;
@@ -76,15 +75,9 @@ static int battle_counttargeted_sub(struct block_list *bl, va_list ap) */
int battle_counttargeted(struct block_list *bl,struct block_list *src,int target_lv)
{
- int c = 0;
nullpo_retr(0, bl);
-
- map_foreachinarea(battle_counttargeted_sub, bl->m,
- bl->x-AREA_SIZE, bl->y-AREA_SIZE,
- bl->x+AREA_SIZE, bl->y+AREA_SIZE, BL_CHAR,
- bl->id, &c, src, target_lv);
-
- return c;
+ return (map_foreachinrange(battle_counttargeted_sub, bl, AREA_SIZE, BL_CHAR,
+ bl->id, src, target_lv));
}
/*==========================================
@@ -124,7 +117,7 @@ static int battle_gettargeted_sub(struct block_list *bl, va_list ap) }
bl_list[(*c)++] = bl;
- return 0;
+ return 1;
}
int battle_getcurrentskill(struct block_list *bl)
@@ -171,10 +164,7 @@ struct block_list* battle_gettargeted(struct block_list *target) nullpo_retr(NULL, target);
memset(bl_list, 0, sizeof(bl_list));
- map_foreachinarea(battle_gettargeted_sub, target->m,
- target->x-AREA_SIZE, target->y-AREA_SIZE,
- target->x+AREA_SIZE, target->y+AREA_SIZE, BL_CHAR,
- bl_list, &c, target);
+ map_foreachinrange(battle_gettargeted_sub, target, AREA_SIZE, BL_CHAR, bl_list, &c, target);
if (c == 0 || c > 24)
return NULL;
return bl_list[rand()%c];
@@ -1554,8 +1544,7 @@ static struct Damage battle_calc_weapon_attack( ATK_ADDRATE(sd->crit_atk_rate);
if(sd->status.party_id && (skill=pc_checkskill(sd,TK_POWER)) > 0){
- i = 0;
- party_foreachsamemap(party_sub_count, sd, 0, &i);
+ i = party_foreachsamemap(party_sub_count, sd, 0);
ATK_ADDRATE(2*skill*i);
}
}
@@ -3122,21 +3111,16 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target, if (sd) sp = skill_get_sp(skillid,skilllv) * 2 / 3;
if ((sd && sd->status.sp >= sp) || !sd) {
- if (skill_get_inf(skillid) & INF_GROUND_SKILL)
- f = skill_castend_pos2(src, target->x, target->y, skillid, skilllv, tick, flag);
- else {
- switch(skill_get_nk(skillid)) {
- case NK_NO_DAMAGE:/* 支援系 */
- if((skillid == AL_HEAL || (skillid == ALL_RESURRECTION && !tsd)) && battle_check_undead(race,ele))
- f = skill_castend_damage_id(src, target, skillid, skilllv, tick, flag);
- else
- f = skill_castend_nodamage_id(src, target, skillid, skilllv, tick, flag);
- break;
- case NK_SPLASH_DAMAGE:
- default:
- f = skill_castend_damage_id(src, target, skillid, skilllv, tick, flag);
- break;
- }
+ switch (skill_get_casttype(skillid)) {
+ case CAST_GROUND:
+ f = skill_castend_pos2(src, target->x, target->y, skillid, skilllv, tick, flag);
+ break;
+ case CAST_NODAMAGE:
+ f = skill_castend_nodamage_id(src, target, skillid, skilllv, tick, flag);
+ break;
+ case CAST_DAMAGE:
+ f = skill_castend_damage_id(src, target, skillid, skilllv, tick, flag);
+ break;
}
if (sd && !f) { pc_heal(sd, 0, -sp); }
}
diff --git a/src/map/map.c b/src/map/map.c index d7cfa11db..cc43f3705 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -628,18 +628,18 @@ struct skill_unit *map_find_skill_unit_oncell(struct block_list *target,int x,in }
/*==========================================
- * Adapted from foreachinarea to use real ranges around a character area. [Skotlex]
+ * Adapted from foreachinarea for an easier invocation. [Skotlex]
*------------------------------------------
*/
-int map_foreachinrange(int (*func)(struct block_list*,va_list),int m,struct block_list *center, int range,int type,...) {
+int map_foreachinrange(int (*func)(struct block_list*,va_list),struct block_list *center, int range,int type,...) {
va_list ap;
- int bx,by;
+ int bx,by,m;
int returnCount =0; //total sum of returned values of func() [Skotlex]
struct block_list *bl=NULL;
int blockcount=bl_list_count,i,c;
int x0,x1,y0,y1;
-
+ m = center->m;
if (m < 0)
return 0;
va_start(ap,type);
@@ -661,7 +661,9 @@ int map_foreachinrange(int (*func)(struct block_list*,va_list),int m,struct bloc for(i=0;i<c && bl;i++,bl=bl->next){
if(bl && bl->type&type
&& bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1
- && check_distance_bl(center, bl, range)
+ //For speed purposes, it does not checks actual range by default.
+ //Feel free to uncomment if you want a more "exact" approach.
+// && check_distance_bl(center, bl, range)
&& bl_list_count<BL_LIST_MAX)
bl_list[bl_list_count++]=bl;
}
diff --git a/src/map/map.h b/src/map/map.h index 70c6b4ec1..645976375 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -1226,7 +1226,7 @@ int map_delblock_sub(struct block_list *, int); #define map_delblock(bl) map_delblock_sub(bl,1)
int map_moveblock(struct block_list *, int, int, unsigned int);
-int map_foreachinrange(int (*)(struct block_list*,va_list),int,struct block_list *,int,int,...);
+int map_foreachinrange(int (*)(struct block_list*,va_list),struct block_list *,int,int,...);
int map_foreachinarea(int (*)(struct block_list*,va_list),int,int,int,int,int,int,...);
// -- moonsoul (added map_foreachincell)
int map_foreachincell(int (*)(struct block_list*,va_list),int,int,int,int,...);
diff --git a/src/map/mob.c b/src/map/mob.c index 2f9e2de03..5cb4e5c92 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -722,9 +722,7 @@ static int mob_attack(struct mob_data *md,unsigned int tick,int data) if (status_get_mode(&md->bl)&MD_ASSIST && DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME)
{ // Link monsters nearby [Skotlex]
md->last_linktime = tick;
- map_foreachinarea(mob_linksearch, md->bl.m,
- md->bl.x-md->db->range2, md->bl.y-md->db->range2,
- md->bl.x+md->db->range2, md->bl.y+md->db->range2,
+ map_foreachinrange(mob_linksearch, &md->bl, md->db->range2,
BL_MOB, md->class_, tbl, tick);
}
@@ -1017,7 +1015,7 @@ static int mob_count_sub(struct block_list *bl,va_list ap) int mob_spawn (int id)
{
int x, y, i = 0;
- unsigned int c, tick = gettick();
+ unsigned int c =0, tick = gettick();
struct mob_data *md;
struct block_list *bl;
@@ -1037,7 +1035,8 @@ int mob_spawn (int id) }
}
md->bl.m = md->m;
- do {
+
+ while (i < 50) {
if (md->x0 == 0 && md->y0 == 0) {
x = rand()%(map[md->bl.m].xs-2)+1;
y = rand()%(map[md->bl.m].ys-2)+1;
@@ -1046,14 +1045,18 @@ int mob_spawn (int id) y = md->y0+rand()%(md->ys+1)-md->ys/2;
}
i++;
- if (battle_config.no_spawn_on_player && i <= battle_config.no_spawn_on_player)
- { //Avoid spawning on the view-range of players. [Skotlex]
- if (map_foreachinarea(mob_count_sub, md->bl.m,
- x-AREA_SIZE, y-AREA_SIZE, x+AREA_SIZE, y+AREA_SIZE,
- BL_PC) > 0)
- continue;
- }
- } while(map_getcell(md->bl.m,x,y,CELL_CHKNOPASS) && i < 50);
+ if (map_getcell(md->bl.m,x,y,CELL_CHKNOPASS))
+ continue;
+
+ //Avoid spawning on the view-range of players. [Skotlex]
+ if (battle_config.no_spawn_on_player &&
+ c++ < battle_config.no_spawn_on_player &&
+ map_foreachinrange(mob_count_sub, &md->bl, AREA_SIZE, BL_PC)
+ )
+ continue;
+ //Found a spot.
+ break;
+ }
if (i >= 50) {
if (md->spawndelay1 != -1 || md->spawndelay2 == -1)
@@ -1682,18 +1685,12 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap) (mode&MD_ANGRY && md->state.skillstate == MSS_FOLLOW)
) {
search_size = (blind_flag) ? 3 : md->db->range2;
- map_foreachinarea (mob_ai_sub_hard_activesearch, md->bl.m,
- md->bl.x-search_size,md->bl.y-search_size,
- md->bl.x+search_size,md->bl.y+search_size,
- md->special_state.ai?BL_CHAR:BL_PC,
- md, &tbl);
+ map_foreachinrange (mob_ai_sub_hard_activesearch, &md->bl,
+ search_size, md->special_state.ai?BL_CHAR:BL_PC, md, &tbl);
} else if (mode&MD_CHANGECHASE && (md->state.skillstate == MSS_RUSH || md->state.skillstate == MSS_FOLLOW)) {
search_size = (blind_flag && md->db->range>3) ? 3 : md->db->range;
- map_foreachinarea (mob_ai_sub_hard_changechase, md->bl.m,
- md->bl.x-search_size,md->bl.y-search_size,
- md->bl.x+search_size,md->bl.y+search_size,
- md->special_state.ai?BL_CHAR:BL_PC,
- md, &tbl);
+ map_foreachinrange (mob_ai_sub_hard_changechase, &md->bl,
+ search_size, md->special_state.ai?BL_CHAR:BL_PC, md, &tbl);
}
// Scan area for items to loot, avoid trying to loot of the mob is full and can't consume the items.
@@ -1702,10 +1699,8 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap) {
i = 0;
search_size = (blind_flag) ? 3 : md->db->range2;
- map_foreachinarea (mob_ai_sub_hard_lootsearch, md->bl.m,
- md->bl.x-search_size, md->bl.y-search_size,
- md->bl.x+search_size, md->bl.y+search_size,
- BL_ITEM, md, &i);
+ map_foreachinrange (mob_ai_sub_hard_lootsearch, &md->bl,
+ search_size, BL_ITEM, md, &i);
}
if (tbl)
@@ -1878,10 +1873,7 @@ static int mob_ai_sub_foreachclient(struct map_session_data *sd,va_list ap) nullpo_retr(0, ap);
tick=va_arg(ap,unsigned int);
- map_foreachinarea(mob_ai_sub_hard,sd->bl.m,
- sd->bl.x-AREA_SIZE*2,sd->bl.y-AREA_SIZE*2,
- sd->bl.x+AREA_SIZE*2,sd->bl.y+AREA_SIZE*2,
- BL_MOB,tick);
+ map_foreachinrange(mob_ai_sub_hard,&sd->bl, AREA_SIZE*2, BL_MOB,tick);
return 0;
}
@@ -3263,7 +3255,7 @@ int mobskill_castend_id( int tid, unsigned int tick, int id,int data ) inf = skill_get_inf(md->skillid);
if((inf&INF_ATTACK_SKILL ||
- (inf&INF_SELF_SKILL && md->bl.id != bl->id && skill_get_nk(md->skillid) != NK_NO_DAMAGE))
+ (inf&INF_SELF_SKILL && md->bl.id != bl->id && !(skill_get_nk(md->skillid)&NK_NO_DAMAGE)))
&& battle_check_target(&md->bl,bl, BCT_ENEMY)<=0 ) {
skill_failed(md);
return 0;
@@ -3286,17 +3278,11 @@ int mobskill_castend_id( int tid, unsigned int tick, int id,int data ) ShowInfo("MOB skill castend skill=%d, class = %d\n",md->skillid,md->class_);
// mob_stop_wShowInfo(md,0);
- switch( skill_get_nk(md->skillid) )
- {
- case NK_NO_DAMAGE:// 支援系
+
+ if (skill_get_casttype(md->skillid) == CAST_NODAMAGE)
skill_castend_nodamage_id(&md->bl,bl,md->skillid,md->skilllv,tick,0);
- break;
- // 攻撃系/吹き飛ばし系
- case NK_SPLASH_DAMAGE:
- default:
+ else
skill_castend_damage_id(&md->bl,bl,md->skillid,md->skilllv,tick,0);
- break;
- }
if (md->sc.count && md->sc.data[SC_MAGICPOWER].timer != -1 && md->skillid != HW_MAGICPOWER)
status_change_end(&md->bl, SC_MAGICPOWER, -1);
@@ -3604,7 +3590,6 @@ int mob_getfriendhpltmaxrate_sub(struct block_list *bl,va_list ap) struct block_list *mob_getfriendhpltmaxrate(struct mob_data *md,int rate)
{
struct block_list *fr=NULL;
- const int r=8;
int type = BL_MOB;
nullpo_retr(NULL, md);
@@ -3612,9 +3597,7 @@ struct block_list *mob_getfriendhpltmaxrate(struct mob_data *md,int rate) if (md->special_state.ai) //Summoned creatures. [Skotlex]
type = BL_PC;
- map_foreachinarea(mob_getfriendhpltmaxrate_sub, md->bl.m,
- md->bl.x-r ,md->bl.y-r, md->bl.x+r, md->bl.y+r,
- type,md,rate,&fr);
+ map_foreachinrange(mob_getfriendhpltmaxrate_sub, &md->bl, 8, type,md,rate,&fr);
return fr;
}
/*==========================================
@@ -3669,12 +3652,10 @@ int mob_getfriendstatus_sub(struct block_list *bl,va_list ap) struct mob_data *mob_getfriendstatus(struct mob_data *md,int cond1,int cond2)
{
struct mob_data *fr=NULL;
- const int r=8;
nullpo_retr(0, md);
- map_foreachinarea(mob_getfriendstatus_sub, md->bl.m,
- md->bl.x-r ,md->bl.y-r, md->bl.x+r, md->bl.y+r,
+ map_foreachinrange(mob_getfriendstatus_sub, &md->bl, 8,
BL_MOB,md,cond1,cond2,&fr);
return fr;
}
@@ -3772,7 +3753,8 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) continue; //Skill requisite failed to be fulfilled.
//Execute skill
- if (skill_get_inf(ms[i].skill_id) & INF_GROUND_SKILL) {
+ if (skill_get_casttype(ms[i].skill_id) == CAST_GROUND)
+ {
// 場所指定
struct block_list *bl = NULL;
int x = 0, y = 0;
@@ -4040,7 +4022,7 @@ int mob_clone_spawn(struct map_session_data *sd, char *map, int x, int y, const ms[i].cond2 = 95;
}
} else if (inf&INF_SELF_SKILL) {
- if (skill_get_nk(skill_id) != NK_NO_DAMAGE) { //Offensive skill
+ if (!(skill_get_nk(skill_id)&NK_NO_DAMAGE)) { //Offensive skill
ms[i].target = MST_TARGET;
ms[i].state = MSS_BERSERK;
} else //Self skill
diff --git a/src/map/party.c b/src/map/party.c index be8520d8f..31d4f0479 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -694,16 +694,13 @@ int party_send_dot_remove(struct map_session_data *sd) // party_foreachsamemap(party_sub_count, sd, 0, &c);
int party_sub_count(struct block_list *bl, va_list ap)
{
- int *c = va_arg(ap, int*);
-
- (*c)++;
return 1;
}
// 同じマップのパーティメンバー全体に処理をかける
// type==0 同じマップ
// !=0 画面内
-void party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int type,...)
+int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...)
{
struct party *p;
va_list ap;
@@ -711,25 +708,26 @@ void party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_ses int x0,y0,x1,y1;
struct block_list *list[MAX_PARTY];
int blockcount=0;
+ int total = 0; //Return value.
- nullpo_retv(sd);
+ nullpo_retr(0,sd);
if((p=party_search(sd->status.party_id))==NULL)
- return;
+ return 0;
- x0=sd->bl.x-AREA_SIZE;
- y0=sd->bl.y-AREA_SIZE;
- x1=sd->bl.x+AREA_SIZE;
- y1=sd->bl.y+AREA_SIZE;
+ x0=sd->bl.x-range;
+ y0=sd->bl.y-range;
+ x1=sd->bl.x+range;
+ y1=sd->bl.y+range;
- va_start(ap,type);
+ va_start(ap,range);
for(i=0;i<MAX_PARTY;i++){
struct party_member *m=&p->member[i];
if(m->sd!=NULL){
if(sd->bl.m!=m->sd->bl.m)
continue;
- if(type!=0 &&
+ if(range &&
(m->sd->bl.x<x0 || m->sd->bl.y<y0 ||
m->sd->bl.x>x1 || m->sd->bl.y>y1 ) )
continue;
@@ -741,9 +739,10 @@ void party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_ses for(i=0;i<blockcount;i++)
if(list[i]->prev) // 有効かどうかチェック
- func(list[i],ap);
+ total += func(list[i],ap);
map_freeblock_unlock(); // 解放を許可する
va_end(ap);
+ return total;
}
diff --git a/src/map/party.h b/src/map/party.h index b98731c18..f1a3f5fcc 100644 --- a/src/map/party.h +++ b/src/map/party.h @@ -41,7 +41,7 @@ int party_send_xy_clear(struct party *p); int party_exp_share(struct party *p,int map,unsigned int base_exp,unsigned int job_exp,int zeny);
int party_send_dot_remove(struct map_session_data *sd);
int party_sub_count(struct block_list *bl, va_list ap);
-void party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_session_data *sd,int type,...);
+int party_foreachsamemap(int (*func)(struct block_list *,va_list),struct map_session_data *sd,int type,...);
#endif
diff --git a/src/map/pc.c b/src/map/pc.c index c742a6db6..4a3381e4f 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -3108,7 +3108,7 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl) flag = pc_additem(sd,&tmp_item,1);
if(battle_config.show_steal_in_same_party)
- party_foreachsamemap(pc_show_steal,sd,1,sd,tmp_item.nameid,flag?1:0);
+ party_foreachsamemap(pc_show_steal,sd,AREA_SIZE,sd,tmp_item.nameid,flag?1:0);
if(flag)
clif_additem(sd,0,0,flag);
else
@@ -3721,8 +3721,7 @@ int pc_walktoxy (struct map_session_data *sd, int x, int y) if ((skill = guild_checkskill(g, GD_SOULCOLD)) > 0) guildflag |= skill<<4;
if ((skill = guild_checkskill(g, GD_HAWKEYES)) > 0) guildflag |= skill;
if (guildflag)
- map_foreachinarea (skill_guildaura_sub, sd->bl.m,
- sd->bl.x-2, sd->bl.y-2, sd->bl.x+2, sd->bl.y+2, BL_PC,
+ map_foreachinrange(skill_guildaura_sub, &sd->bl,2, BL_PC,
sd->bl.id, sd->status.guild_id, &guildflag);
}
diff --git a/src/map/pet.c b/src/map/pet.c index 5d80f978d..9177440d4 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -318,32 +318,27 @@ static int petskill_castend(struct pet_data *pd,unsigned int tick,int data) */
static int petskill_castend2(struct pet_data *pd, struct block_list *target, short skill_id, short skill_lv, short skill_x, short skill_y, unsigned int tick)
{ //Invoked after the casting time has passed.
- short delaytime =0;
+ int delaytime =0;
nullpo_retr(0, pd);
pd->state.state=MS_IDLE;
- if (skill_get_inf(skill_id) & INF_GROUND_SKILL)
+ if (skill_get_inf(skill_id)&INF_GROUND_SKILL)
{ //Area skill
skill_castend_pos2(&pd->bl, skill_x, skill_y, skill_id, skill_lv, tick,0);
} else { //Targeted Skill
- if (!target || !status_check_skilluse(&pd->bl, target, skill_id, 1))
+ if (!target)
return 0;
- //Skills with inf = 4 (cast on self) have view range (assumed party skills)
if(!check_distance_bl(&pd->bl, target,
- (skill_get_inf(skill_id) & INF_SELF_SKILL?battle_config.area_size:skill_get_range2(&pd->bl, skill_id, skill_lv))))
+ skill_get_range2(&pd->bl, skill_id, skill_lv)));
return 0;
- switch( skill_get_nk(skill_id) )
- {
- case NK_NO_DAMAGE:
- skill_castend_nodamage_id(&pd->bl,target, skill_id, skill_lv,tick, 0);
- break;
- case NK_SPLASH_DAMAGE:
- default:
- skill_castend_damage_id(&pd->bl,target,skill_id,skill_lv,tick,0);
- break;
- }
+ if (!status_check_skilluse(&pd->bl, target, skill_id, 1))
+ return 0;
+ if (skill_get_casttype(skill_id) == CAST_NODAMAGE)
+ skill_castend_nodamage_id(&pd->bl, target, skill_id, skill_lv, tick, 0);
+ else
+ skill_castend_damage_id(&pd->bl, target, skill_id, skill_lv, tick,0);
}
if (pd->timer != -1) //The above skill casting could had changed the state (Abracadabra?)
@@ -1460,12 +1455,9 @@ static int pet_ai_sub_hard(struct pet_data *pd,unsigned int tick) return 0;
// ペットによるルート
if(!pd->target_id && pd->loot && pd->loot->count < pd->loot->max && DIFF_TICK(gettick(),pd->loot->timer)>0)
- map_foreachinarea(pet_ai_sub_hard_lootsearch,pd->bl.m,
- pd->bl.x-6,pd->bl.y-6, //If pet_ai_sub_hard_lootsearch limits itself to a range of 5, WHY use AREA_SIZE here? o.O [Skotlex]
- pd->bl.x+6,pd->bl.y+6,
-// pd->bl.x-AREA_SIZE*2,pd->bl.y-AREA_SIZE*2,
-// pd->bl.x+AREA_SIZE*2,pd->bl.y+AREA_SIZE*2,
- BL_ITEM,pd,&i);
+ //Use half the pet's range of sight.
+ map_foreachinrange(pet_ai_sub_hard_lootsearch,&pd->bl,
+ pd->db->range2/2, BL_ITEM,pd,&i);
if(sd->pet.intimate > 0) {
dist = distance_bl(&sd->bl, &pd->bl);
diff --git a/src/map/skill.c b/src/map/skill.c index 04b13b82e..2e12158ab 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -649,13 +649,24 @@ struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list static int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int tick);
static int skill_unit_onleft(int skill_id, struct block_list *bl,unsigned int tick);
int skill_unit_effect(struct block_list *bl,va_list ap);
-int skill_castend_delay (struct block_list* src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag);
static void skill_moonlit(struct block_list* src, struct block_list* partner, int skilllv);
static int skill_check_pc_partner(struct map_session_data *sd, int skill_id, int* skill_lv, int range, int cast_flag);
int enchant_eff[5] = { 10, 14, 17, 19, 20 };
int deluge_eff[5] = { 5, 9, 12, 14, 15 };
+int skill_get_casttype(int id)
+{
+ int inf = skill_get_inf(id);
+ if (inf&(INF_GROUND_SKILL))
+ return CAST_GROUND;
+ if (inf&(INF_SELF_SKILL|INF_SUPPORT_SKILL))
+ return CAST_NODAMAGE;
+ if (skill_get_nk(id)&NK_NO_DAMAGE)
+ return CAST_NODAMAGE;
+ return CAST_DAMAGE;
+};
+
//Returns actual skill range taking into account attack range and AC_OWL [Skotlex]
int skill_get_range2(struct block_list *bl, int id, int lv) {
int range = skill_get_range(id, lv);
@@ -1229,57 +1240,43 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int //Reports say that autospell effects get triggered on skills and pretty much everything including splash attacks. [Skotlex]
//Here we use the nk value to trigger spells only on damage causing skills (otherwise stuff like AL_HEAL will trigger them)
- if(sd && !status_isdead(bl) && src != bl) {
- switch (skillid) {
- case KN_AUTOCOUNTER:
- case CR_REFLECTSHIELD:
- case SG_SUN_WARM:
- case SG_MOON_WARM:
- case SG_STAR_WARM:
- rate = 1;
- break;
- default:
- rate = (!skillid || skill_get_nk(skillid)!=NK_NO_DAMAGE);
- }
- if (rate) {
- struct block_list *tbl;
- int i;
- for (i = 0; i < MAX_PC_BONUS && sd->autospell[i].id; i++) {
+ if(sd && !status_isdead(bl) && src != bl &&
+ !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE)) {
+ struct block_list *tbl;
+ int i;
+ for (i = 0; i < MAX_PC_BONUS && sd->autospell[i].id; i++) {
- skill = (sd->autospell[i].id > 0) ? sd->autospell[i].id : -sd->autospell[i].id;
- //Prevents skill from retriggering themselves. [Skotlex]
- if (skill == skillid)
- continue;
+ skill = (sd->autospell[i].id > 0) ? sd->autospell[i].id : -sd->autospell[i].id;
+ //Prevents skill from retriggering themselves. [Skotlex]
+ if (skill == skillid)
+ continue;
- //skill2 reused to store skilllv.
- skill2 = (sd->autospell[i].lv > 0) ? sd->autospell[i].lv : 1;
- rate = (!sd->state.arrow_atk) ? sd->autospell[i].rate : sd->autospell[i].rate / 2;
+ //skill2 reused to store skilllv.
+ skill2 = (sd->autospell[i].lv > 0) ? sd->autospell[i].lv : 1;
+ rate = (!sd->state.arrow_atk) ? sd->autospell[i].rate : sd->autospell[i].rate / 2;
- if (rand()%1000 > rate)
- continue;
- if (sd->autospell[i].id < 0)
- tbl = src;
- else
- tbl = bl;
-
- if (tbl != src && !battle_check_range(src, tbl, skill_get_range2(src, skill, skill2)))
- continue; //Autoskills DO check for target-src range. [Skotlex]
-
- if (skill_get_inf(skill) & INF_GROUND_SKILL)
+ if (rand()%1000 > rate)
+ continue;
+ if (sd->autospell[i].id < 0)
+ tbl = src;
+ else
+ tbl = bl;
+
+ if (tbl != src && !battle_check_range(src, tbl, skill_get_range2(src, skill, skill2)))
+ continue; //Autoskills DO check for target-src range. [Skotlex]
+ rate = skill_get_inf(skill);
+ switch (skill_get_casttype(skill)) {
+ case CAST_GROUND:
skill_castend_pos2(src, tbl->x, tbl->y, skill, skill2, tick, 0);
- else {
- switch (skill_get_nk(skill)) {
- case NK_NO_DAMAGE:
- skill_castend_nodamage_id(src, tbl, skill, skill2, tick, 0);
- break;
- case NK_SPLASH_DAMAGE:
- default:
- skill_castend_damage_id(src, tbl, skill, skill2, tick, 0);
- break;
- }
- }
- break; //Only one auto skill comes off at a time.
+ break;
+ case CAST_NODAMAGE:
+ skill_castend_nodamage_id(src, tbl, skill, skill2, tick, 0);
+ break;
+ case CAST_DAMAGE:
+ skill_castend_damage_id(src, tbl, skill, skill2, tick, 0);
+ break;
}
+ break; //Only one auto skill comes off at a time.
}
}
return 0;
@@ -1365,7 +1362,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * }
//Trigger counter-spells to retaliate against damage causing skills. [Skotlex]
- if(dstsd && !status_isdead(bl) && src != bl &&(!skillid || skill_get_nk(skillid)!=NK_NO_DAMAGE))
+ if(dstsd && !status_isdead(bl) && src != bl && !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE))
{
struct block_list *tbl;
int i, skillid, skilllv, rate;
@@ -1385,19 +1382,17 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * tbl = bl;
else
tbl = src;
-
- if (skill_get_inf(skillid) & INF_GROUND_SKILL)
- skill_castend_pos2(bl, tbl->x, tbl->y, skillid, skilllv, tick, 0);
- else {
- switch (skill_get_nk(skillid)) {
- case NK_NO_DAMAGE:
- skill_castend_nodamage_id(bl, tbl, skillid, skilllv, tick, 0);
- break;
- case NK_SPLASH_DAMAGE:
- default:
- skill_castend_damage_id(bl, tbl, skillid, skilllv, tick, 0);
- break;
- }
+
+ switch (skill_get_casttype(skillid)) {
+ case CAST_GROUND:
+ skill_castend_pos2(bl, tbl->x, tbl->y, skillid, skilllv, tick, 0);
+ break;
+ case CAST_NODAMAGE:
+ skill_castend_nodamage_id(bl, tbl, skillid, skilllv, tick, 0);
+ break;
+ case CAST_DAMAGE:
+ skill_castend_damage_id(bl, tbl, skillid, skilllv, tick, 0);
+ break;
}
}
}
@@ -1526,7 +1521,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds return 0;
//Note that splash attacks often only check versus the targetted mob, those around the splash area normally don't get checked for being hidden/cloaked/etc. [Skotlex]
- if ((skill_get_nk(skillid) == NK_SPLASH_DAMAGE || skillid == ASC_METEORASSAULT || skillid == SN_SHARPSHOOTING || skillid == RG_RAID)
+ if (flag && skill_get_nk(skillid)&NK_SPLASH
&& !status_check_skilluse(dsrc, bl, skillid, 1))
return 0;
@@ -1897,7 +1892,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds sc->count && sc->data[SC_DOUBLECAST].timer != -1 &&
rand() % 100 < 40+10*sc->data[SC_DOUBLECAST].val1)
{
- skill_castend_delay (src, bl, skillid, skilllv, tick + dmg.div_*dmg.amotion, flag|1);
+ skill_addtimerskill(src, tick + dmg.div_*dmg.amotion, bl->id, 0, 0, skillid, skilllv, BF_MAGIC, flag|1);
}
map_freeblock_unlock();
@@ -2154,18 +2149,17 @@ static int skill_timerskill(int tid, unsigned int tick, int id,int data ) nullpo_retr(0, src);
if(src->type == BL_PC) {
- nullpo_retr(0, sd = (struct map_session_data *)src);
+ sd = (struct map_session_data *)src;
skl = &sd->skilltimerskill[data];
}
else if(src->type == BL_MOB) {
- nullpo_retr(0, md = (struct mob_data *)src);
+ md = (struct mob_data *)src;
skl = &md->skilltimerskill[data];
}
else if(src->type == BL_PET) { // [Valaris]
- nullpo_retr(0, pd = (struct pet_data *)src);
+ pd = (struct pet_data *)src;
skl = &pd->skilltimerskill[data];
}
-
else
return 0;
@@ -2199,9 +2193,9 @@ static int skill_timerskill(int tid, unsigned int tick, int id,int data ) return 0;
if(src->m != target->m)
return 0;
- if(sd && pc_isdead(sd))
+ if(status_isdead(src))
return 0;
- if(target->type == BL_PC && pc_isdead((struct map_session_data *)target) && skl->skill_id != RG_INTIMIDATE)
+ if(status_isdead(target) && skl->skill_id != RG_INTIMIDATE)
return 0;
switch(skl->skill_id) {
@@ -2252,7 +2246,7 @@ static int skill_timerskill(int tid, unsigned int tick, int id,int data ) case BA_FROSTJOKE: /* 寒いジョ?ク */
case DC_SCREAM: /* スクリ?ム */
- range=battle_config.area_size; //視界全?
+ range= skill_get_splash(skl->skill_id, skl->skill_lv);
map_foreachinarea(skill_frostjoke_scream,skl->map,skl->x-range,skl->y-range,
skl->x+range,skl->y+range,BL_CHAR,src,skl->skill_id,skl->skill_lv,tick);
break;
@@ -2388,44 +2382,6 @@ int skill_cleartimerskill(struct block_list *src) return 0;
}
-struct castend_delay {
- struct block_list *src;
- int target;
- int id;
- int lv;
- int flag;
-};
-int skill_castend_delay_sub (int tid, unsigned int tick, int id, int data)
-{
- struct castend_delay *dat = (struct castend_delay *)data;
- struct block_list *target = map_id2bl(dat->target);
-
- if (target && dat && map_id2bl(id) == dat->src && target->prev != NULL)
- skill_castend_damage_id(dat->src, target, dat->id, dat->lv, tick, dat->flag);
- aFree(dat);
- return 0;
-}
-int skill_castend_delay (struct block_list* src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag)
-{
- struct castend_delay *dat;
- nullpo_retr(0, src);
- nullpo_retr(0, bl);
-
- dat = (struct castend_delay *)aCalloc(1, sizeof(struct castend_delay));
- dat->src = src;
- dat->target = bl->id;
- dat->id = skillid;
- dat->lv = skilllv;
- dat->flag = flag;
- add_timer (tick, skill_castend_delay_sub, src->id, (int)dat);
-
- return 0;
-}
-
-/* 範?スキル使用???ャ分けここまで
- * -------------------------------------------------------------------------
- */
-
/*==========================================
* スキル使用?i詠?・完了?AID指定?U?系?j
* ?iスパゲッティに向けて1?前?i?I(ダ?ポ)?j
@@ -2458,9 +2414,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s if (bl->type == BL_PC)
tsd = (struct map_session_data *)bl;
- if ((skillid == CR_GRANDCROSS || skillid == NPC_GRANDDARKNESS) && src != bl)
- bl = src;
-
if (status_isdead(src) || (src != bl && status_isdead(bl)))
return 1;
@@ -2557,8 +2510,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s case MO_COMBOFINISH:
if (!(flag&1) && sc && sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_MONK)
{ //Becomes a splash attack when Soul Linked.
- map_foreachinarea(skill_area_sub,
- bl->m,bl->x-2,bl->y-2,bl->x+2,bl->y+2,BL_CHAR,
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
} else
@@ -2567,8 +2520,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s case TK_STORMKICK: // Taekwon kicks [Dralnu]
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinarea(skill_attack_area, src->m,
- src->x-2, src->y-2, src->x+2, src->y+2, BL_CHAR,
+ map_foreachinrange(skill_attack_area, src,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
BF_WEAPON, src, src, skillid, skilllv, tick, flag, BCT_ENEMY);
break;
case TK_JUMPKICK:
@@ -2588,7 +2541,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s case SN_SHARPSHOOTING: /* シャ?プシュ?ティング */
// Does it stop if touch an obstacle? it shouldn't shoot trough walls
- map_foreachinpath (skill_attack_area,src->m,src->x,src->y,bl->x,bl->y,2,BL_CHAR,
+ map_foreachinpath (skill_attack_area,src->m,src->x,src->y,bl->x,bl->y,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
BF_WEAPON,src,src,skillid,skilllv,tick,flag,BCT_ENEMY); // varargs
break;
@@ -2714,22 +2668,14 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s 0x0500);
}
} else {
- int ar = 1;
- int x = bl->x, y = bl->y;
- switch (skillid) {
- case NPC_SPLASHATTACK:
- ar=3;
- break;
- }
-
skill_area_temp[1]=bl->id;
- skill_area_temp[2]=x;
- skill_area_temp[3]=y;
+ skill_area_temp[2]=bl->x;
+ skill_area_temp[3]=bl->y;
/* まずタ?ゲットに?U?を加える */
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0);
/* その後タ?ゲット以外の範??の敵全?に??を?sう */
- map_foreachinarea(skill_area_sub,
- bl->m,x-ar,y-ar,x+ar,y+ar,BL_CHAR,
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
}
@@ -2744,12 +2690,12 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s } else {
skill_area_temp[0] = 0;
skill_area_temp[1] = bl->id;
- map_foreachinarea(skill_area_sub, bl->m,
- bl->x-2, bl->y-2, bl->x+2, bl->y+2, BL_CHAR,
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count);
skill_area_temp[0]--; //Substract one, the original target shouldn't count. [Skotlex]
- map_foreachinarea(skill_area_sub, bl->m,
- bl->x-1, bl->y-1, bl->x+1, bl->y+1, BL_CHAR,
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src, skillid, skilllv, tick, BCT_ENEMY|1,
skill_castend_damage_id);
}
@@ -2757,20 +2703,19 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s case SM_MAGNUM:
- if(flag&1){
- int dist = distance_blxy (bl, skill_area_temp[2], skill_area_temp[3]);
- skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,
- 0x0500|dist);
- } else {
- skill_area_temp[1]=src->id;
- skill_area_temp[2]=src->x;
- skill_area_temp[3]=src->y;
- map_foreachinarea(skill_area_sub,
- src->m,src->x-2,src->y-2,src->x+2,src->y+2,BL_CHAR,
+ if(flag&1)
+ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+ else {
+ //If we get here, someone changed magnum to be a enemy targetted skill,
+ //so treat it as such.
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
- status_change_start (src,SC_WATK_ELEMENT,100,3,20,0,0,skill_get_time2(skillid, skilllv),0); //Initiate 10% of your damage becomes fire element.
- clif_skill_nodamage (src,src,skillid,skilllv,1);
+ //Initiate 10% of your damage becomes fire element.
+ clif_skill_nodamage (src,bl,skillid,skilllv,
+ status_change_start (src,SC_WATK_ELEMENT,100,
+ 3,20,0,0,skill_get_time2(skillid, skilllv),0));
if (sd) pc_blockskill_start (sd, skillid, skill_get_time(skillid, skilllv));
}
break;
@@ -2789,17 +2734,17 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s for(i=0;i<c;i++){
skill_blown(src,bl,0x20000|1);
skill_area_temp[0]=0;
- map_foreachinarea(skill_area_sub,
- bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,BL_CHAR,
- src,skillid,skilllv,tick, flag|BCT_ENEMY ,
+ map_foreachinrange(skill_area_sub,bl,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY,
skill_area_sub_count);
if(skill_area_temp[0]>1) break;
}
clif_blown(bl); //Update target pos.
skill_area_temp[1]=bl->id;
/* その後タ?ゲット以外の範??の敵全?に??を?sう */
- map_foreachinarea(skill_area_sub,
- bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,BL_CHAR,
+ map_foreachinrange(skill_area_sub,bl,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0);
@@ -2822,7 +2767,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0) && !status_get_mexp(bl))
skill_blown(src,bl,skill_area_temp[2]);
for (i=0;i<4;i++) {
- map_foreachinarea(skill_area_sub,bl->m,x,y,x,y,BL_CHAR,
+ map_foreachincell(skill_area_sub,bl->m,x,y,BL_CHAR,
src,skillid,skilllv,tick,flag|BCT_ENEMY|1,
skill_castend_damage_id);
x += dirx[dir];
@@ -2836,7 +2781,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s {
skill_area_temp[1] = bl->id; //NOTE: This is used in skill_castend_nodamage_id to avoid affecting the target.
if (skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,0))
- map_foreachinarea(skill_area_sub,bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,BL_CHAR,
+ map_foreachinrange(skill_area_sub,bl,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
src,skillid,skilllv,tick,flag|BCT_ENEMY|1,
skill_castend_nodamage_id);
}
@@ -2868,6 +2814,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s case PR_ASPERSIO: /* アスペルシオ */
case MG_FROSTDIVER: /* フ?ストダイバ?[ */
case WZ_SIGHTBLASTER:
+ case WZ_SIGHTRASHER: /* サイトラッシャ?[ */
skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,flag);
break;
@@ -2896,54 +2843,36 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s /* 魔法系範??U?スキル */
case MG_NAPALMBEAT: /* ナパ?ムビ?ト */
case MG_FIREBALL: /* ファイヤ?ボ?ル */
- case WZ_SIGHTRASHER: /* サイトラッシャ?[ */
if (flag & 1) {
/* 個別にダ??ジを?える */
- if (bl->id != skill_area_temp[1]){
- if(skillid == MG_FIREBALL){ /* ファイヤ?ボ?ルなら中?Sからの距離を計算 */
- skill_area_temp[0] = distance_blxy(bl, skill_area_temp[2], skill_area_temp[3]);
- }
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,
- skill_area_temp[0]| 0x0500);
- }
+ if (bl->id == skill_area_temp[1])
+ break;
+ if(skillid == MG_FIREBALL) //Store distance.
+ skill_area_temp[0] = distance_blxy(bl, skill_area_temp[2], skill_area_temp[3]);
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick, skill_area_temp[0]| 0x0500);
} else {
- int ar;
skill_area_temp[0]=0;
skill_area_temp[1]=bl->id;
switch (skillid) {
case MG_NAPALMBEAT:
- ar = 1;
/* ナパ?[ムビ?[トは分散ダ??[ジなので敵の?狽?狽ヲる */
- map_foreachinarea(skill_area_sub,
- bl->m,bl->x-ar,bl->y-ar,bl->x+ar,bl->y+ar,BL_CHAR,
- src,skillid,skilllv,tick,flag|BCT_ENEMY,
- skill_area_sub_count);
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
+ src,skillid,skilllv,tick,flag|BCT_ENEMY,
+ skill_area_sub_count);
break;
case MG_FIREBALL:
- ar = 2;
skill_area_temp[2]=bl->x;
skill_area_temp[3]=bl->y;
break;
- case WZ_SIGHTRASHER:
- default:
- ar = 3;
- bl = src;
- status_change_end(src,SC_SIGHT,-1);
- break;
- }
- if (skillid==WZ_SIGHTRASHER) {
- /* スキルエフェクト表示 */
- clif_skill_nodamage(src,bl,skillid,skilllv,1);
- } else {
- /* タ?[ゲットに?U撃を加える(スキルエフェクト表示) */
- skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick,
- skill_area_temp[0]);
}
+ /* タ?[ゲットに?U撃を加える(スキルエフェクト表示) */
+ skill_attack(BF_MAGIC,src,src,bl,skillid,skilllv,tick, skill_area_temp[0]);
/* タ?[ゲット以外の範囲内の敵全体に??を?sう */
- map_foreachinarea(skill_area_sub,
- bl->m,bl->x-ar,bl->y-ar,bl->x+ar,bl->y+ar,BL_CHAR,
- src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
- skill_castend_damage_id);
+ map_foreachinrange(skill_area_sub,bl,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
}
break;
@@ -2954,24 +2883,18 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s } else {
skill_area_temp[0] = 0;
skill_area_temp[1] = bl->id;
- map_foreachinarea(skill_area_sub, bl->m,
- bl->x-1, bl->y-1, bl->x+1, bl->y+1, BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY,
- skill_area_sub_count);
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY,
+ skill_area_sub_count);
skill_attack(BF_MAGIC, src, src, bl, skillid, skilllv, tick, skill_area_temp[0]);
- map_foreachinarea(skill_area_sub, bl->m,
- bl->x-1, bl->y-1, bl->x+1, bl->y+1, BL_CHAR,
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
}
break;
- case WZ_FROSTNOVA: /* フ?ストノヴァ */
- map_foreachinarea(skill_attack_area, src->m,
- src->x-5, src->y-5, bl->x+5, bl->y+5, BL_CHAR,
- BF_MAGIC, src, src, skillid, skilllv, tick, flag, BCT_ENEMY);
- break;
-
case SL_STIN:
case SL_STUN:
case SL_SMA:
@@ -2991,26 +2914,16 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s skill_area_temp[0] = 0;
skill_area_temp[1] = bl->id;
if (flag & 0xf00000) //Warning, 0x100000 is currently BCT_NEUTRAL, so don't mix it when asking for the enemy. [Skotlex]
- map_foreachinarea(skill_area_sub, bl->m,
- bl->x-1, bl->y-1, bl->x+1, bl->y+1, BL_CHAR,
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count);
- map_foreachinarea(skill_area_sub, bl->m,
- bl->x-1, bl->y-1, bl->x+1, bl->y+1, BL_CHAR,
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src, skillid, skilllv, tick, BCT_ENEMY|1,
skill_castend_damage_id);
}
break;
- case CR_GRANDCROSS: /* グランドク?ス */
- case NPC_GRANDDARKNESS: /*闇グランドク?ス*/
- /* スキルユニット配置 */
- skill_castend_pos2(src,bl->x,bl->y,skillid,skilllv,tick,0);
- if(sd)
- sd->canmove_tick = tick + 900;
- else if(src->type == BL_MOB)
- mob_changestate((struct mob_data *)src,MS_DELAY,900);
- break;
-
case NPC_DARKBREATH:
clif_emotion(src,7);
skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
@@ -3021,6 +2934,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s case CR_ACIDDEMONSTRATION: // Acid Demonstration
case TF_THROWSTONE: /* ?ホ投げ */
case NPC_SMOKING: /* スモ?キング */
+ case NPC_SELFDESTRUCTION: /* 自爆 */
skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
break;
@@ -3046,32 +2960,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s if (sd) pc_blockskill_start (sd, skillid, (skilllv < 5 ? 10000: 15000));
break;
- case NPC_SELFDESTRUCTION: /* 自爆 */
- if (flag & 1) {
- /* 個別にダ??[ジを与える */
- if (bl->id != skill_area_temp[1])
- skill_attack(BF_MISC, src, src, bl, NPC_SELFDESTRUCTION, skilllv, tick, flag);
- } else {
- skill_area_temp[1] = bl->id;
- if(bl->type==BL_PC)
- skill_area_temp[2] = 999999;
- else
- skill_area_temp[2] = status_get_hp(src);
- clif_skill_nodamage(src, src, NPC_SELFDESTRUCTION, -1, 1);
- if(bl->type==BL_PC)
- map_foreachinarea(skill_area_sub, bl->m,
- bl->x-10, bl->y-10, bl->x+10, bl->y+10, BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
- skill_castend_damage_id);
- else
- map_foreachinarea(skill_area_sub, bl->m,
- bl->x-5, bl->y-5, bl->x+5, bl->y+5, BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
- skill_castend_damage_id);
- battle_damage(src, src, skill_area_temp[2], 0);
- }
- break;
-
/* HP吸?/HP吸?魔法 */
case NPC_BLOODDRAIN:
case NPC_ENERGYDRAIN:
@@ -3097,10 +2985,9 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s if (bl->id != skill_area_temp[1])
skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, 0x0500);
} else {
- int ar = sd->splash_range;
skill_area_temp[1] = bl->id;
- map_foreachinarea(skill_area_sub,
- bl->m, bl->x - ar, bl->y - ar, bl->x + ar, bl->y + ar, BL_CHAR,
+ map_foreachinrange(skill_area_sub, bl,
+ sd->splash_range, BL_CHAR,
src, skillid, skilllv, tick, flag | BCT_ENEMY | 1,
skill_castend_damage_id);
}
@@ -3133,7 +3020,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if(skillid < 0 || skillid > MAX_SKILL)
{ // remove the debug print when this case is finished
- ShowDebug("skill_castend_damage_id: skillid=%i\ncall: %p %p %i %i %i %i",skillid,
+ ShowDebug("skill_castend_nodamage_id: skillid=%i\ncall: %p %p %i %i %i %i",skillid,
src, bl,skillid,skilllv,tick,flag);
return 0;
}
@@ -3164,6 +3051,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if(status_isdead(bl) && skillid != NPC_REBIRTH && skillid != ALL_RESURRECTION && skillid != PR_REDEMPTIO)
return 1;
+ //Self skill with target changed? We assume these are offensive auto-select-target skills. [Skotlex]
+ if (skill_get_inf(skillid)&INF_SELF_SKILL && src != bl && !(skill_get_nk(skillid)&NK_NO_DAMAGE))
+ return skill_castend_damage_id (src, bl, skillid, skilllv, tick, flag);
+
if (skillid > 0 && skillid < MAX_SKILL)
type = SkillStatusChangeTable[skillid];
//Shouldn't be needed, skillnotok's return value is highly unlikely to have changed after you started casting. [Skotlex]
@@ -3187,10 +3078,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in return 0;
}
return skill_castend_damage_id (src, bl, skillid, skilllv, tick, flag);
- }
- break;
+ }
+ case NPC_SMOKING: //Since it is a self skill, this one ends here rather than in damage_id. [Skotlex]
+ return skill_castend_damage_id (src, bl, skillid, skilllv, tick, flag);
+ case CR_GRANDCROSS:
+ case NPC_GRANDDARKNESS:
+ //These two are actually ground placed.
+ if(sd)
+ sd->canmove_tick = tick + 900;
+ else if(md)
+ mob_changestate(md,MS_DELAY,900);
+ return skill_castend_pos2(src,src->x,src->y,skillid,skilllv,tick,0);
}
-
tsc = status_get_sc(bl);
map_freeblock_lock();
@@ -3246,7 +3145,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in }
skill_area_temp[0] = 0;
party_foreachsamemap(skill_area_sub,
- sd,1,
+ sd,skill_get_splash(skillid, skilllv),
src,skillid,skilllv,tick, flag|BCT_PARTY|1,
skill_castend_nodamage_id);
if (skill_area_temp[0] == 0) {
@@ -3325,15 +3224,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case AL_CRUCIS:
if (flag & 1) {
- int race = status_get_race (bl), ele = status_get_elem_type (bl);
- if (battle_check_target (src, bl, BCT_ENEMY) && (race == 6 || battle_check_undead (race, ele))) {
+ if (battle_check_target (src, bl, BCT_ENEMY))
status_change_start(bl,type,
23+skilllv*4 +status_get_lv(src) -status_get_lv(bl),
skilllv,0,0,0,0,0);
- }
} else {
- map_foreachinarea(skill_area_sub,
- src->m, src->x-15, src->y-15, src->x+15, src->y+15, BL_CHAR,
+ map_foreachinrange(skill_area_sub, src,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
skill_castend_nodamage_id);
clif_skill_nodamage(src, bl, skillid, skilllv, 1);
@@ -3606,7 +3503,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in status_change_start(bl,type,100,
skilllv,0,0,0,skill_get_time(skillid,skilllv),0));
break;
-
+ //Passive Magnum, should had been casted on yourself.
+ case SM_MAGNUM:
+ map_foreachinrange(skill_area_sub, src,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
+ //Initiate 10% of your damage becomes fire element.
+ clif_skill_nodamage (src,src,skillid,skilllv,
+ status_change_start (src,SC_WATK_ELEMENT,100,
+ 3,20,0,0,skill_get_time2(skillid, skilllv),0));
+ if (sd) pc_blockskill_start (sd, skillid, skill_get_time(skillid, skilllv));
+ break;
case LK_BERSERK: /* バ?サ?ク */
case KN_AUTOCOUNTER: /* オ?トカウンタ? */
case KN_TWOHANDQUICKEN: /* ツ?ハンドクイッケン */
@@ -3647,7 +3555,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case SG_STAR_WARM:
clif_skill_nodamage(src,bl,skillid,skilllv,
status_change_start(bl,type,100,
- skilllv,0,skillid,skill_get_range(skillid,skilllv),skill_get_time(skillid,skilllv),0));
+ skilllv,0,skillid,skill_get_splash(skillid,skilllv),skill_get_time(skillid,skilllv),0));
break;
case CG_MOONLIT: /* 月明りの泉に落ちる花びら */
@@ -3664,8 +3572,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in status_change_start(bl,type,100,skilllv,0,0,0,skill_get_time(skillid,skilllv),0 );
else
{
- map_foreachinarea(skill_area_sub,
- bl->m, bl->x-1, bl->y-1, bl->x+1, bl->y+1, BL_PC,
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_PC,
src, skillid, skilllv, tick, flag|BCT_ALL|1,
skill_castend_nodamage_id);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
@@ -3736,12 +3644,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case AC_CONCENTRATION: /* ?W中力向? */
{
- int range = 1;
clif_skill_nodamage(src,bl,skillid,skilllv,
status_change_start(bl,type,100,
skilllv,0,0,0,skill_get_time(skillid,skilllv),0));
- map_foreachinarea( status_change_timer_sub,
- src->m, src->x-range, src->y-range, src->x+range,src->y+range,BL_CHAR,
+ map_foreachinrange( status_change_timer_sub, src,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src,status_get_sc(src),type,tick);
}
break;
@@ -3915,8 +3822,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in break;
case RG_RAID: /* サプライズアタック */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinarea(skill_area_sub,
- bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,BL_CHAR,
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
status_change_end(src, SC_HIDING, -1); // ハイディング解?
@@ -3924,8 +3831,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case ASC_METEORASSAULT: /* ?テオアサルト */
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinarea(skill_area_sub,
- bl->m,bl->x-2,bl->y-2,bl->x+2,bl->y+2,BL_CHAR,
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
break;
@@ -3979,6 +3886,31 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in }
}
break;
+
+ case WZ_SIGHTRASHER:
+ //Passive side of the attack.
+ status_change_end(src,SC_SIGHT,-1);
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ map_foreachinrange(skill_area_sub,src,
+ skill_get_splash(skillid, skilllv),BL_CHAR,
+ src,skillid,skilllv,tick, flag|BCT_ENEMY|1,
+ skill_castend_damage_id);
+ break;
+
+ case WZ_FROSTNOVA:
+ map_foreachinrange(skill_attack_area, src,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
+ BF_MAGIC, src, src, skillid, skilllv, tick, flag, BCT_ENEMY);
+ break;
+
+ case NPC_SELFDESTRUCTION:
+ clif_skill_nodamage(src, src, skillid, -1, 1);
+ map_foreachinrange(skill_area_sub, bl,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY,
+ skill_castend_damage_id);
+ battle_damage(src, src, skill_area_temp[2], 0);
+ break;
/* パ?ティスキル */
case AL_ANGELUS: /* エンジェラス */
@@ -3992,7 +3924,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } else if (sd) {
/* パ?ティ全?への?? */
party_foreachsamemap (skill_area_sub,
- sd,1,
+ sd,skill_get_splash(skillid, skilllv),
src,skillid,skilllv,tick, flag|BCT_PARTY|1,
skill_castend_nodamage_id);
}
@@ -4010,7 +3942,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } else if (sd) {
/* パ?ティ全?への?? */
party_foreachsamemap(skill_area_sub,
- sd,1,
+ sd,skill_get_splash(skillid, skilllv),
src,skillid,skilllv,tick, flag|BCT_PARTY|1,
skill_castend_nodamage_id);
}
@@ -4772,7 +4704,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case BS_GREED:
if(sd){
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinarea(skill_greed,bl->m,bl->x-2,bl->y-2,bl->x+2,bl->y+2,BL_ITEM,bl);
+ map_foreachinrange(skill_greed,bl,
+ skill_get_splash(skillid, skilllv),BL_ITEM,bl);
}
break;
@@ -5498,8 +5431,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in else if (sd && sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) &&
strcmp(sd->status.name,g->master)==0) {
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinarea(skill_area_sub,
- src->m,src->x-15,src->y-15,src->x+15,src->y+15,BL_CHAR,
+ map_foreachinrange(skill_area_sub, src,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src,skillid,skilllv,tick, flag|BCT_GUILD|1,
skill_castend_nodamage_id);
guild_block_skill(sd,skill_get_time2(skillid,skilllv));
@@ -5523,8 +5456,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in else if (sd && sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) &&
strcmp(sd->status.name,g->master)==0) {
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinarea(skill_area_sub,
- src->m,src->x-15,src->y-15,src->x+15,src->y+15,BL_CHAR,
+ map_foreachinrange(skill_area_sub, src,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src,skillid,skilllv,tick, flag|BCT_GUILD|1,
skill_castend_nodamage_id);
guild_block_skill(sd,skill_get_time2(skillid,skilllv));
@@ -5553,8 +5486,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in else if (sd && sd->status.guild_id > 0 && (g = guild_search(sd->status.guild_id)) &&
strcmp(sd->status.name,g->master)==0) {
clif_skill_nodamage(src,bl,skillid,skilllv,1);
- map_foreachinarea(skill_area_sub,
- src->m,src->x-15,src->y-15,src->x+15,src->y+15,BL_CHAR,
+ map_foreachinrange(skill_area_sub, src,
+ skill_get_splash(skillid, skilllv), BL_CHAR,
src,skillid,skilllv,tick, flag|BCT_GUILD|1,
skill_castend_nodamage_id);
guild_block_skill(sd,skill_get_time2(skillid,skilllv));
@@ -5724,7 +5657,7 @@ int skill_castend_id( int tid, unsigned int tick, int id,int data ) } else {
inf2 = skill_get_inf(sd->skillid);
if((inf2&INF_ATTACK_SKILL ||
- (inf2&INF_SELF_SKILL && sd->bl.id != bl->id && skill_get_nk(sd->skillid) != NK_NO_DAMAGE)) //Self skills that cause damage (EF, Combo Skills, etc)
+ (inf2&INF_SELF_SKILL && sd->bl.id != bl->id && !(skill_get_nk(sd->skillid)&NK_NO_DAMAGE))) //Self skills that cause damage (EF, Combo Skills, etc)
&& battle_check_target(&sd->bl,bl, BCT_ENEMY)<=0
) {
skill_failed(sd);
@@ -5785,16 +5718,10 @@ int skill_castend_id( int tid, unsigned int tick, int id,int data ) sd->canact_tick = tick + delay;
if (skill_get_delaynowalk(sd->skillid, sd->skilllv)) //Skills that block you from moving until delay ends. [Skotlex]
sd->canmove_tick = tick + delay;
- switch( skill_get_nk(sd->skillid) )
- {
- case NK_NO_DAMAGE:
+ if (skill_get_casttype(sd->skillid) == CAST_NODAMAGE)
skill_castend_nodamage_id(&sd->bl,bl,sd->skillid,sd->skilllv,tick,0);
- break;
- case NK_SPLASH_DAMAGE:
- default:
+ else
skill_castend_damage_id(&sd->bl,bl,sd->skillid,sd->skilllv,tick,0);
- break;
- }
if(sd->sc.count && sd->sc.data[SC_MAGICPOWER].timer != -1 && sd->skillid != HW_MAGICPOWER)
status_change_end(&sd->bl,SC_MAGICPOWER,-1);
@@ -5945,46 +5872,40 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil {
case PR_BENEDICTIO: /* ?ケ??~福 */
skill_area_temp[1] = src->id;
+ i = skill_get_splash(skillid, skilllv);
map_foreachinarea(skill_area_sub,
- src->m, x-1, y-1, x+1, y+1, BL_PC,
+ src->m, x-i, y-i, x+i, y+i, BL_PC,
src, skillid, skilllv, tick, flag|BCT_ALL|1,
skill_castend_nodamage_id);
map_foreachinarea(skill_area_sub,
- src->m, x-1, y-1, x+1, y+1, BL_CHAR,
+ src->m, x-i, y-i, x+i, y+i, BL_CHAR,
src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
break;
case AC_SHOWER:
{ //One of the few skills that can attack traps.
- int r = 2;
+ i = skill_get_splash(skillid, skilllv);
+ clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
map_foreachinarea (skill_area_sub,
- src->m, x-r, y-r, x+r, y+r, BL_CHAR|BL_SKILL,
+ src->m, x-i, y-i, x+i, y+i, BL_CHAR|BL_SKILL,
src, skillid, skilllv, tick, flag|BCT_ENEMY|1,
skill_castend_damage_id);
}
break;
case BS_HAMMERFALL:
- {
- int r = 2;
- if (skilllv > 5) {
- r = 14;
- skilllv = 5; // スタン率?繧ェりすぎるため計算はLv5で固定
- }
- skill_area_temp[1] = src->id;
- skill_area_temp[2] = x;
- skill_area_temp[3] = y;
- map_foreachinarea (skill_area_sub,
- src->m, x-r, y-r, x+r, y+r, BL_CHAR,
- src, skillid, skilllv, tick, flag|BCT_ENEMY|2,
- skill_castend_nodamage_id);
- }
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea (skill_area_sub,
+ src->m, x-i, y-i, x+i, y+i, BL_CHAR,
+ src, skillid, skilllv, tick, flag|BCT_ENEMY|2,
+ skill_castend_nodamage_id);
break;
case HT_DETECTING: /* ディテクティング */
+ i = skill_get_splash(skillid, skilllv);
map_foreachinarea( status_change_timer_sub,
- src->m, x-3, y-3, x+3,y+3,BL_CHAR,
+ src->m, x-i, y-i, x+i,y+i,BL_CHAR,
src,status_get_sc(src),SC_SIGHT,tick);
break;
@@ -6025,7 +5946,8 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil break;
case RG_CLEANER: // [Valaris]
- map_foreachinarea(skill_graffitiremover,src->m,x-5,y-5,x+5,y+5,BL_SKILL);
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea(skill_graffitiremover,src->m,x-i,y-i,x+i,y+i,BL_SKILL);
break;
case SA_VOLCANO: /* ボルケ?ノ */
case SA_DELUGE: /* デリュ?ジ */
@@ -6036,11 +5958,9 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil case WZ_METEOR: //?テオスト?ム
{
- int flag=0, area = 7;
+ int flag=0, area = skill_get_splash(skillid, skilllv);
if (sc && sc->data[SC_MAGICPOWER].timer != -1)
flag = flag|2; //Store the magic power flag for future use. [Skotlex]
- if (skilllv > skill_get_max(skillid))
- area = area*3; //Double range area
for(i=0;i<2+(skilllv>>1);i++) {
int j=0;
do {
@@ -6151,8 +6071,9 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil potion_flag = 0;
clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
if(potion_hp > 0) {
+ i = skill_get_splash(skillid, skilllv);
map_foreachinarea(skill_area_sub,
- src->m,x-3,y-3,x+3,y+3,BL_CHAR,
+ src->m,x-i,y-i,x+i,y+i,BL_CHAR,
src,skillid,skilllv,tick,flag|BCT_PARTY|BCT_GUILD|1,
skill_castend_nodamage_id);
}
@@ -6163,7 +6084,8 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil case HW_GANBANTEIN:
if (rand()%100 < 80) {
clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
- map_foreachinarea (skill_ganbatein, src->m, x-1, y-1, x+1, y+1, BL_SKILL);
+ i = skill_get_splash(skillid, skilllv);
+ map_foreachinarea (skill_ganbatein, src->m, x-i, y-i, x+i, y+i, BL_SKILL);
} else {
clif_skill_fail(sd,skillid,0,0);
return 1;
@@ -6404,8 +6326,6 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid, if((flag&1)!=0)
limit=1000;
val1=skilllv+2;
- if(skilllv >= 6)
- range=2;
break;
case WZ_METEOR:
if (skilllv > skill_get_max(skillid)) //?L範囲?テオ
@@ -6890,7 +6810,8 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign break;
case UNT_FIREPILLAR_ACTIVE:
- map_foreachinarea(skill_attack_area,bl->m,bl->x-1,bl->y-1,bl->x+1,bl->y+1,sg->bl_flag,
+ map_foreachinrange(skill_attack_area,bl,
+ skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag,
BF_MAGIC,ss,&src->bl,sg->skill_id,sg->skill_lv,tick,0,BCT_ENEMY); // area damage [Celest]
sg->interval = -1; //Mark it used up so others can't trigger it for massive splash damage. [Skotlex]
sg->limit=DIFF_TICK(tick,sg->tick) + 1500;
@@ -6943,14 +6864,12 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign case UNT_FLASHER:
case UNT_FREEZINGTRAP:
case UNT_CLAYMORETRAP:
- map_foreachinarea(skill_count_target,src->bl.m
- ,src->bl.x-src->range,src->bl.y-src->range
- ,src->bl.x+src->range,src->bl.y+src->range
- ,sg->bl_flag,&src->bl,&splash_count);
- map_foreachinarea(skill_trap_splash,src->bl.m
- ,src->bl.x-src->range,src->bl.y-src->range
- ,src->bl.x+src->range,src->bl.y+src->range
- ,sg->bl_flag,&src->bl,tick,splash_count);
+ map_foreachinrange(skill_count_target,&src->bl,
+ skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag,
+ &src->bl,&splash_count);
+ map_foreachinrange(skill_trap_splash,&src->bl,
+ skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag,
+ &src->bl,tick,splash_count);
sg->unit_id = UNT_USED_TRAPS;
clif_changelook(&src->bl,LOOK_BASE,sg->unit_id);
sg->limit=DIFF_TICK(tick,sg->tick)+1500;
@@ -7404,15 +7323,13 @@ static void skill_moonlit(struct block_list* src, struct block_list* partner, in int range = skill_get_range2(src, CG_MOONLIT, skilllv);
int blowcount = range+1, time = skill_get_time(CG_MOONLIT,skilllv);
- map_foreachinarea(skill_moonlit_sub,src->m
- ,src->x-range,src->y-range
- ,src->x+range,src->y+range
- ,BL_CHAR,src,partner,blowcount);
+ map_foreachinrange(skill_moonlit_sub,src,
+ skill_get_splash(CG_MOONLIT, skilllv),
+ BL_CHAR,src,partner,blowcount);
if(partner)
- map_foreachinarea(skill_moonlit_sub,partner->m
- ,partner->x-range,partner->y-range
- ,partner->x+range,partner->y+range
- ,BL_CHAR,src,partner,blowcount);
+ map_foreachinrange(skill_moonlit_sub,partner,
+ skill_get_splash(CG_MOONLIT, skilllv),
+ BL_CHAR,src,partner,blowcount);
status_change_start(src,SC_DANCING,100,CG_MOONLIT,0,0,partner?partner->id:BCT_SELF,time+1000,0);
status_change_start(src,SkillStatusChangeTable[CG_MOONLIT],100,skilllv,0,0,0,time,0);
@@ -7539,9 +7456,8 @@ static int skill_check_pc_partner(struct map_session_data *sd, int skill_id, int //Else: new search for partners.
c = 0;
memset (p_sd, 0, sizeof(p_sd));
- i = map_foreachinarea(skill_check_condition_char_sub, sd->bl.m,
- sd->bl.x-range, sd->bl.y-range, sd->bl.x+range,
- sd->bl.y+range, BL_PC, &sd->bl, &c, &p_sd, skill_id);
+ i = map_foreachinrange(skill_check_condition_char_sub, &sd->bl,
+ range, BL_PC, &sd->bl, &c, &p_sd, skill_id);
if (skill_id != PR_BENEDICTIO) //Apply the average lv to encore skills.
*skill_lv = (i+(*skill_lv))/(c+1); //I know c should be one, but this shows how it could be used for the average of n partners.
@@ -7572,16 +7488,11 @@ static int skill_check_condition_mob_master_sub(struct block_list *bl,va_list ap static int skill_check_condition_hermod_sub(struct block_list *bl,va_list ap)
{
- int *c;
struct npc_data *nd;
-
- nullpo_retr(0, bl);
- nullpo_retr(0, ap);
- nullpo_retr(0, nd=(struct npc_data*)bl);
- nullpo_retr(0, c=va_arg(ap,int *));
+ nd=(struct npc_data*)bl;
if (nd->bl.subtype == WARP)
- (*c)++;
+ return 1;
return 0;
}
@@ -8018,19 +7929,16 @@ int skill_check_condition(struct map_session_data *sd,int type) break;
}
case CG_HERMODE:
+ if (map_foreachinrange (skill_check_condition_hermod_sub, &sd->bl,
+ skill_get_splash(skill, lv), BL_NPC) < 1)
{
- int c = 0;
- map_foreachinarea (skill_check_condition_hermod_sub, sd->bl.m,
- sd->bl.x-3, sd->bl.y-3, sd->bl.x+3, sd->bl.y+3, BL_NPC, &c);
- if (c < 1) {
- clif_skill_fail(sd,skill,0,0);
- return 0;
- }
+ clif_skill_fail(sd,skill,0,0);
+ return 0;
}
break;
case CG_MOONLIT: //Check there's no wall in the range+1 area around the caster. [Skotlex]
{
- int i,x,y,range = skill_get_range2(&sd->bl, skill, lv)+1;
+ int i,x,y,range = skill_get_splash(skill, lv)+1;
int size = range*2+1;
for (i=0;i<size*size;i++) {
x = sd->bl.x+(i%size-range);
@@ -9228,25 +9136,17 @@ int skill_autospell(struct map_session_data *sd,int skillid) static int skill_gangster_count(struct block_list *bl,va_list ap)
{
- int *c;
struct map_session_data *sd;
- nullpo_retr(0, bl);
- nullpo_retr(0, ap);
-
sd=(struct map_session_data*)bl;
- c=va_arg(ap,int *);
- if(sd && c && pc_issit(sd) && pc_checkskill(sd,RG_GANGSTER) > 0)
- (*c)++;
+ if(sd && pc_issit(sd) && pc_checkskill(sd,RG_GANGSTER) > 0)
+ return 1;
return 0;
}
static int skill_gangster_in(struct block_list *bl,va_list ap)
{
struct map_session_data *sd;
- nullpo_retr(0, bl);
- nullpo_retr(0, ap);
-
sd=(struct map_session_data*)bl;
if(sd && pc_issit(sd) && pc_checkskill(sd,RG_GANGSTER) > 0)
sd->state.gangsterparadise=1;
@@ -9256,9 +9156,6 @@ static int skill_gangster_in(struct block_list *bl,va_list ap) static int skill_gangster_out(struct block_list *bl,va_list ap)
{
struct map_session_data *sd;
- nullpo_retr(0, bl);
- nullpo_retr(0, ap);
-
sd=(struct map_session_data*)bl;
if(sd && sd->state.gangsterparadise)
sd->state.gangsterparadise=0;
@@ -9267,33 +9164,24 @@ static int skill_gangster_out(struct block_list *bl,va_list ap) int skill_gangsterparadise(struct map_session_data *sd ,int type)
{
- int range=1;
- int c=0;
+ int range;
nullpo_retr(0, sd);
- if(pc_checkskill(sd,RG_GANGSTER) <= 0)
+ if((range = pc_checkskill(sd,RG_GANGSTER)) <= 0)
return 0;
+ range = skill_get_splash(RG_GANGSTER, range);
if(type==1) {/* ?タった時の?? */
- map_foreachinarea(skill_gangster_count,sd->bl.m,
- sd->bl.x-range,sd->bl.y-range,
- sd->bl.x+range,sd->bl.y+range,BL_PC,&c);
- if(c > 1) {/*ギャングスタ??ャ功したら自分にもギャングスタ???ォ付?*/
- map_foreachinarea(skill_gangster_in,sd->bl.m,
- sd->bl.x-range,sd->bl.y-range,
- sd->bl.x+range,sd->bl.y+range,BL_PC);
+ if (map_foreachinrange(skill_gangster_count,&sd->bl, range, BL_PC) > 1)
+ { /*ギャングスタ??ャ功したら自分にもギャングスタ???ォ付?*/
+ map_foreachinrange(skill_gangster_in,&sd->bl, range, BL_PC);
sd->state.gangsterparadise = 1;
}
return 0;
}
else if(type==0) {/* 立ち?繧ェったときの?? */
- map_foreachinarea(skill_gangster_count,sd->bl.m,
- sd->bl.x-range,sd->bl.y-range,
- sd->bl.x+range,sd->bl.y+range,BL_PC,&c);
- if(c < 2)
- map_foreachinarea(skill_gangster_out,sd->bl.m,
- sd->bl.x-range,sd->bl.y-range,
- sd->bl.x+range,sd->bl.y+range,BL_PC);
+ if (map_foreachinrange(skill_gangster_count,&sd->bl, range, BL_PC) < 2)
+ map_foreachinrange(skill_gangster_out,&sd->bl, range, BL_PC);
sd->state.gangsterparadise = 0;
return 0;
}
@@ -9305,16 +9193,11 @@ int skill_gangsterparadise(struct map_session_data *sd ,int type) */
static int skill_rest_count(struct block_list *bl,va_list ap)
{
- int *c_r;
struct map_session_data *sd;
- nullpo_retr(0, bl);
- nullpo_retr(0, ap);
-
sd=(struct map_session_data*)bl;
- c_r=va_arg(ap,int *);
- if(sd && c_r && pc_issit(sd) && (pc_checkskill(sd,TK_HPTIME) > 0 || pc_checkskill(sd,TK_SPTIME) > 0 ))
- (*c_r)++;
+ if(sd && pc_issit(sd) && (pc_checkskill(sd,TK_HPTIME) > 0 || pc_checkskill(sd,TK_SPTIME) > 0 ))
+ return 1;
return 0;
}
@@ -9335,46 +9218,37 @@ static int skill_rest_in(struct block_list *bl,va_list ap) static int skill_rest_out(struct block_list *bl,va_list ap)
{
struct map_session_data *sd;
- nullpo_retr(0, bl);
- nullpo_retr(0, ap);
-
sd=(struct map_session_data*)bl;
- if(sd && sd->state.rest != 0){
+ if(sd && sd->state.rest != 0)
sd->state.rest=0;
- }
return 0;
}
int skill_rest(struct map_session_data *sd ,int type)
{
- int range=1;
- int c_r=0;
+ int range;
nullpo_retr(0, sd);
- if(pc_checkskill(sd,TK_HPTIME) <= 0 && pc_checkskill(sd,TK_SPTIME) <= 0)
+ if((range = pc_checkskill(sd,TK_HPTIME)) > 0)
+ range = skill_get_splash(TK_HPTIME, range);
+ else if ((range = pc_checkskill(sd,TK_SPTIME)) > 0)
+ range = skill_get_splash(TK_SPTIME, range);
+ else
return 0;
+
if(type==1) { //When you sit down
- map_foreachinarea(skill_rest_count,sd->bl.m,
- sd->bl.x-range,sd->bl.y-range,
- sd->bl.x+range,sd->bl.y+range,BL_PC,&c_r);
- if(c_r > 1) {
- map_foreachinarea(skill_rest_in,sd->bl.m,
- sd->bl.x-range,sd->bl.y-range,
- sd->bl.x+range,sd->bl.y+range,BL_PC);
+ if (map_foreachinrange(skill_rest_count,&sd->bl, range, BL_PC) > 1)
+ {
+ map_foreachinrange(skill_rest_in,&sd->bl, range, BL_PC);
sd->state.rest = 1;
status_calc_pc(sd,0);
}
return 0;
}
else if(type==0) { //When you stand up
- map_foreachinarea(skill_rest_count,sd->bl.m,
- sd->bl.x-range,sd->bl.y-range,
- sd->bl.x+range,sd->bl.y+range,BL_PC,&c_r);
- if(c_r < 2)
- map_foreachinarea(skill_rest_out,sd->bl.m,
- sd->bl.x-range,sd->bl.y-range,
- sd->bl.x+range,sd->bl.y+range,BL_PC);
+ if (map_foreachinrange(skill_rest_count,&sd->bl, range, BL_PC) < 2)
+ map_foreachinrange(skill_rest_out,&sd->bl, range, BL_PC);
sd->state.rest = 0;
status_calc_pc(sd,0);
return 0;
@@ -10195,7 +10069,6 @@ int skill_unit_timer_sub( struct block_list *bl, va_list ap ) {
struct skill_unit *unit;
struct skill_unit_group *group;
- int range;
unsigned int tick;
nullpo_retr(0, bl);
@@ -10208,12 +10081,11 @@ int skill_unit_timer_sub( struct block_list *bl, va_list ap ) group=unit->group;
nullpo_retr(0, group);
- range = unit->range;
/* onplace_timerイベント呼び?oし */
- if (range>=0 && group->interval!=-1) {
- map_foreachinarea(skill_unit_timer_sub_onplace, bl->m,
- bl->x-range,bl->y-range,bl->x+range,bl->y+range,group->bl_flag,bl,tick);
+ if (unit->range>=0 && group->interval!=-1) {
+ map_foreachinrange(skill_unit_timer_sub_onplace, bl, unit->range,
+ group->bl_flag,bl,tick);
if (!unit->alive)
return 0;
// マグヌスは発動したユニットは??怩キる
@@ -11637,7 +11509,6 @@ int do_init_skill(void) add_timer_func_list(skill_castend_id,"skill_castend_id");
add_timer_func_list(skill_castend_pos,"skill_castend_pos");
add_timer_func_list(skill_timerskill,"skill_timerskill");
- add_timer_func_list(skill_castend_delay_sub,"skill_castend_delay_sub");
add_timer_interval(gettick()+SKILLUNITTIMER_INVERVAL,skill_unit_timer,0,0,SKILLUNITTIMER_INVERVAL);
diff --git a/src/map/skill.h b/src/map/skill.h index 5035c8766..d18e2e59e 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -23,9 +23,9 @@ //Constants to identify a skill's nk value.
//The NK value applies only to non INF_GROUND_SKILL skills.
-#define NK_NO_DAMAGE 1
-#define NK_SPLASH_DAMAGE 2
-
+#define NK_NO_DAMAGE 0x1
+#define NK_SPLASH 0x2
+//A skill with 3 would be no damage + splash: area of effect.
//Constants to identify a skill's inf2 value.
#define INF2_QUEST_SKILL 1
//NPC skills are those that players can't have in their skill tree.
@@ -130,14 +130,19 @@ struct skill_unit_group; int do_init_skill(void);
+
+//Returns the cast type of the skill: ground cast, castend damage, castend no damage
+enum { CAST_GROUND, CAST_DAMAGE, CAST_NODAMAGE };
+int skill_get_casttype(int id); //[Skotlex]
// スキルデ?タベ?スへのアクセサ
int skill_get_hit( int id );
int skill_get_inf( int id );
int skill_get_pl( int id );
int skill_get_nk( int id );
int skill_get_max( int id );
-int skill_get_range( int id , int lv );
-int skill_get_range2(struct block_list *bl, int id, int lv);
+int skill_get_range( int id , int lv );
+int skill_get_range2(struct block_list *bl, int id, int lv);
+int skill_get_splash( int id , int lv );
int skill_get_hp( int id ,int lv );
int skill_get_mhp( int id ,int lv );
int skill_get_sp( int id ,int lv );
diff --git a/src/map/status.c b/src/map/status.c index e23a62b22..1dc45a26f 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -3535,6 +3535,11 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val if((elem == 7 || race == 6) && !(flag&1))
return 0;
break;
+ case SC_SIGNUMCRUCIS:
+ //Only affects demons and undead.
+ if(race != 6 && !undead_flag)
+ return 0;
+ break;
case SC_AETERNA:
if (sc->data[SC_STONE].timer != -1 || sc->data[SC_FREEZE].timer != -1)
return 0;
@@ -5173,10 +5178,9 @@ int status_change_timer(int tid, unsigned int tick, int id, int data) case SC_RUWACH: /* ルアフ */
case SC_SIGHTBLASTER:
{
- int range = skill_get_range2(bl,StatusSkillChangeTable[type], sc->data[type].val1);
- map_foreachinarea( status_change_timer_sub,
- bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,
- bl,sc,type,tick);
+ map_foreachinrange( status_change_timer_sub, bl,
+ skill_get_splash(StatusSkillChangeTable[type], sc->data[type].val1),
+ BL_CHAR, bl,sc,type,tick);
if( (--sc->data[type].val2)>0 ){
sc->data[type].timer=add_timer( /* タイマ?再設定 */
@@ -5199,8 +5203,8 @@ int status_change_timer(int tid, unsigned int tick, int id, int data) case SC_WARM: //SG skills [Komurka]
if( (--sc->data[type].val2)>0){
- map_foreachinarea( status_change_timer_sub,
- bl->m, bl->x-sc->data[type].val4, bl->y-sc->data[type].val4, bl->x+sc->data[type].val4,bl->y+sc->data[type].val4,BL_CHAR,
+ map_foreachinrange( status_change_timer_sub, bl,
+ sc->data[type].val4,BL_CHAR,
bl,sc,type,tick);
sc->data[type].timer=add_timer(tick+100, status_change_timer,bl->id, data);
return 0;
|