case AL_WARP:
{
const struct point *p[4];
struct skill_unit_group *group;
int i, lv, wx, wy;
int maxcount=0;
int x,y;
unsigned short mapindex;
mapindex = mapindex_name2id((char*)map);
if(!mapindex) { //Given map not found?
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
skill_failed(sd);
return 0;
}
p[0] = &sd->status.save_point;
p[1] = &sd->status.memo_point[0];
p[2] = &sd->status.memo_point[1];
p[3] = &sd->status.memo_point[2];
if((maxcount = skill_get_maxcount(skill_id, sd->menuskill_val)) > 0) {
for(i=0;i<MAX_SKILLUNITGROUP && sd->ud.skillunit[i] && maxcount;i++) {
if(sd->ud.skillunit[i]->skill_id == skill_id)
maxcount--;
}
if(!maxcount) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
skill_failed(sd);
return 0;
}
}
lv = sd->skillitem==skill_id?sd->skillitemlv:pc_checkskill(sd,skill_id);
wx = sd->menuskill_val>>16;
wy = sd->menuskill_val&0xffff;
if( lv <= 0 ) return 0;
if( lv > 4 ) lv = 4; // crash prevention
// check if the chosen map exists in the memo list
ARR_FIND( 0, lv, i, mapindex == p[i]->map );
if( i < lv ) {
x=p[i]->x;
y=p[i]->y;
} else {
skill_failed(sd);
return 0;
}
if(!skill_check_condition_castend(sd, sd->menuskill_id, lv))
{ // This checks versus skill_id/skill_lv...
skill_failed(sd);
return 0;
}
skill_consume_requirement(sd,sd->menuskill_id,lv,2);
sd->skillitem = sd->skillitemlv = 0; // Clear data that's skipped in 'skill_castend_pos' [Inkfish]
if((group=skill_unitsetting(&sd->bl,skill_id,lv,wx,wy,0))==NULL) {
skill_failed(sd);
return 0;
}
group->val1 = (group->val1<<16)|(short)0;
// record the destination coordinates
group->val2 = (x<<16)|y;
group->val3 = mapindex;
}