summaryrefslogtreecommitdiff
path: root/src/map/skill.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/skill.c')
-rw-r--r--src/map/skill.c91
1 files changed, 61 insertions, 30 deletions
diff --git a/src/map/skill.c b/src/map/skill.c
index c541ad4ac..614acaf09 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -6436,7 +6436,7 @@ static int skill_dance_overlap_sub(struct block_list *bl, va_list ap)
struct skill_unit *target = (struct skill_unit*)bl,
*src = va_arg(ap, struct skill_unit*);
int flag = va_arg(ap, int);
- if (!target || !target->group || !target->group->state.song_dance)
+ if (!target || !target->group || !(target->group->state.song_dance&0x1))
return 0;
if (!(target->val2 & src->val2 & ~UF_ENSEMBLE)) //They don't match (song + dance) is valid.
return 0;
@@ -6456,7 +6456,7 @@ static int skill_dance_overlap_sub(struct block_list *bl, va_list ap)
//When 1, this unit has been positioned, so start the cancel effect.
int skill_dance_overlap(struct skill_unit *unit, int flag)
{
- if (!unit || !unit->group || !unit->group->state.song_dance)
+ if (!unit || !unit->group || !(unit->group->state.song_dance&0x1))
return 0;
if (!flag && !(unit->val2&UF_ENSEMBLE))
return 0; //Nothing to remove, this unit is not overlapped.
@@ -6711,7 +6711,7 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid,
group->state.into_abyss = (sc && sc->data[SC_INTOABYSS].timer != -1); //Store into abyss state, to know it shouldn't give traps back. [Skotlex]
group->state.magic_power = (flag&2 || (sc && sc->data[SC_MAGICPOWER].timer != -1)); //Store the magic power flag. [Skotlex]
group->state.ammo_consume = (sd && sd->state.arrow_atk); //Store if this skill needs to consume ammo.
- group->state.song_dance = (unit_flag&(UF_DANCE|UF_SONG)); //Signals if this is a song/dance (does not counts duets)
+ group->state.song_dance = (unit_flag&(UF_DANCE|UF_SONG)?1:0)|(unit_flag&UF_ENSEMBLE?2:0); //Signals if this is a song/dance/duet
//if tick is greater than current, do not invoke onplace function just yet. [Skotlex]
if (DIFF_TICK(group->tick, gettick()) > 100)
@@ -6754,7 +6754,7 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid,
uy+=(i/5-2);
break;
default:
- if (group->state.song_dance) {
+ if (group->state.song_dance&0x1) {
val1 = skillid; //Holds SKILL id to use.
val2 = unit_flag&(UF_DANCE|UF_SONG); //Store whether this is a song/dance
}
@@ -6827,9 +6827,6 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
map_getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR))
return 0; //AoE skills are ineffective. [Skotlex]
- if (battle_check_target(&src->bl,bl,sg->target_flag)<=0)
- return 0;
-
sc = status_get_sc(bl);
if (sc && sc->option&OPTION_HIDE && sg->skill_id != WZ_HEAVENDRIVE)
@@ -6885,8 +6882,9 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
case UNT_SIEGFRIED:
case UNT_HERMODE:
//Needed to check when a dancer/bard leaves their ensemble area.
- if (sg->src_id==bl->id && (!sc || sc->data[SC_SPIRIT].timer == -1 || sc->data[SC_SPIRIT].val2 != SL_BARDDANCER))
- return sg->skill_id;
+ if (sg->src_id==bl->id &&
+ !(sc && sc->data[SC_SPIRIT].timer == -1 && sc->data[SC_SPIRIT].val2 != SL_BARDDANCER))
+ return skillid;
if (sc && sc->data[type].timer==-1)
sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
break;
@@ -6971,7 +6969,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
}
type = SkillStatusChangeTable(sg->skill_id);
skillid = sg->skill_id;
- if (sg->state.song_dance && src->val2&UF_ENSEMBLE)
+ if (sg->state.song_dance&0x1 && src->val2&UF_ENSEMBLE)
{ //Treat this group as if it were BA_DISSONANCE/DC_UGLYDANCE.
//Values will be restored on proper switch case.
src->val1 = sg->unit_id;
@@ -7183,7 +7181,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_UGLYDANCE: //Ugly Dance [Skotlex]
if (ss->id != bl->id)
skill_additional_effect(ss, bl, sg->skill_id, sg->skill_lv, BF_LONG|BF_SKILL|BF_MISC, tick);
- if (sg->state.song_dance && src->val2&UF_ENSEMBLE)
+ if (sg->state.song_dance&0x1 && src->val2&UF_ENSEMBLE)
{ //Restore values.
sg->skill_id = skillid;
sg->unit_id = src->val1;
@@ -7193,7 +7191,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_DISSONANCE:
skill_attack(BF_MISC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
- if (sg->state.song_dance && src->val2&UF_ENSEMBLE)
+ if (sg->state.song_dance&0x1 && src->val2&UF_ENSEMBLE)
{ //Restore values.
sg->skill_id = skillid;
sg->unit_id = src->val1;
@@ -7489,12 +7487,10 @@ int skill_unit_effect (struct block_list *bl, va_list ap)
{
struct skill_unit *unit;
struct skill_unit_group *group;
- int flag;
+ int flag,skill_id;
unsigned int tick;
- nullpo_retr(0, bl);
- nullpo_retr(0, ap);
- nullpo_retr(0, unit=va_arg(ap,struct skill_unit*));
+ unit=va_arg(ap,struct skill_unit*);
tick = va_arg(ap,unsigned int);
flag = va_arg(ap,unsigned int);
@@ -7502,13 +7498,23 @@ int skill_unit_effect (struct block_list *bl, va_list ap)
return 0;
nullpo_retr(0, group=unit->group);
+
+ //Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
+ skill_id = group->skill_id;
+ //Target-type check.
+ if(!(group->bl_flag&bl->type && battle_check_target(&unit->bl,bl,group->target_flag)>0))
+ {
+ if (flag&4 && group->src_id == bl->id && group->state.song_dance&0x2)
+ skill_unit_onleft(skill_id, bl, tick);//Ensemble check to terminate it.
+ return 0;
+ }
if (flag&1)
skill_unit_onplace(unit,bl,tick);
else
skill_unit_onout(unit,bl,tick);
- if (flag&4) skill_unit_onleft(group->skill_id, bl, tick);
+ if (flag&4) skill_unit_onleft(skill_id, bl, tick);
return 0;
}
@@ -9589,7 +9595,7 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int
skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_SETICEWALL);
break;
default:
- if (group->state.song_dance) //Check for dissonance.
+ if (group->state.song_dance&0x1) //Check for dissonance.
skill_dance_overlap(unit, 1);
break;
}
@@ -9612,7 +9618,7 @@ int skill_delunit (struct skill_unit *unit)
skill_unit_onlimit( unit,gettick() );
- if (group->state.song_dance) //Restore dissonance effect.
+ if (group->state.song_dance&0x1) //Restore dissonance effect.
skill_dance_overlap(unit, 0);
if (!unit->range) {
@@ -10000,28 +10006,53 @@ int skill_unit_timer (int tid, unsigned int tick, int id, int data)
int skill_unit_move_sub (struct block_list *bl, va_list ap)
{
struct skill_unit *unit = (struct skill_unit *)bl;
+ struct skill_unit_group *group;
struct block_list *target;
unsigned int tick,flag,result;
int skill_id;
-
+
target=va_arg(ap,struct block_list*);
tick = va_arg(ap,unsigned int);
flag = va_arg(ap,int);
- nullpo_retr(0, unit->group);
-
- if (!(unit->group->bl_flag&target->type))
- return 0; //we don't target this type of bl
+ nullpo_retr(0, group=unit->group);
- skill_id = unit->group->skill_id; //Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
+ if (!unit->alive || target->prev==NULL)
+ return 0;
+
+ //Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
+ skill_id = unit->group->skill_id;
if (unit->group->interval!=-1 &&
!(skill_get_unit_flag(skill_id)&UF_DUALMODE)) //Skills in dual mode have to trigger both. [Skotlex]
return 0;
-
- if (!unit->alive || target->prev==NULL)
- return 0;
+ //Target-type check.
+ if(!(group->bl_flag&target->type && battle_check_target(&unit->bl,target,group->target_flag)>0))
+ {
+ if(group->src_id == target->id && group->state.song_dance&0x2)
+ { //Ensemble check to see if they went out/in of the area [Skotlex]
+ if (flag&1)
+ {
+ if (flag&2)
+ { //Clear skill ids we have stored in onout.
+ int i;
+ for(i=0; i<8 && skill_unit_temp[i]!=skill_id; i++);
+ if (i<8)
+ skill_unit_temp[i] = 0;
+ }
+ }
+ else
+ {
+ if (flag&2 && skill_unit_index < 7) //Store this unit id.
+ skill_unit_temp[skill_unit_index++] = skill_id;
+ }
+ if (flag&4)
+ skill_unit_onleft(skill_id,target,tick);
+ }
+ return 0;
+ }
+
if (flag&1)
{
result = skill_unit_onplace(unit,target,tick);
@@ -10128,7 +10159,7 @@ int skill_unit_move_unit_group (struct skill_unit_group *group, int m, int dx, i
if (!unit1->alive)
continue;
if (!(m_flag[i]&0x2)) {
- if (group->state.song_dance) //Restore dissonance effect.
+ if (group->state.song_dance&0x1) //Restore dissonance effect.
skill_dance_overlap(unit1, 0);
map_foreachincell(skill_unit_effect,unit1->bl.m,
unit1->bl.x,unit1->bl.y,group->bl_flag,&unit1->bl,tick,4);
@@ -10159,7 +10190,7 @@ int skill_unit_move_unit_group (struct skill_unit_group *group, int m, int dx, i
break; //Don't move the cell as a cell will end on this tile anyway.
}
if (!(m_flag[i]&0x2)) { //We only moved the cell in 0-1
- if (group->state.song_dance) //Check for dissonance effect.
+ if (group->state.song_dance&0x1) //Check for dissonance effect.
skill_dance_overlap(unit1, 1);
clif_skill_setunit(unit1);
map_foreachincell(skill_unit_effect,unit1->bl.m,