- Fixed missing baby-dancer job in exp2.txt

- Added function battle_set_walkdelay in charge of updating walkdelays of characters based on two criterias: when the delay is induced by damage, if the current walk delay isn't over yet, do not update it. If the delay is instead caused by a skill, then the current walk delay cannot be decreased, only increased.
- Removed the canmove tick reset on skill cast cancel; likewise it isn't updated on begin casting. pc_can_move uses a skilltimer check to know whether you can move or not.
- Added GrandCross's can't move delay of 900ms to skill_cast_db
- Added Finger Offensive's can't move delay of 200ms/lv to skill_cast_db


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@5457 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
skotlex 2006-03-04 04:48:30 +00:00
parent c606e4de69
commit dc8dd724eb
10 changed files with 88 additions and 87 deletions

View File

@ -5,6 +5,11 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. EV
GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
2006/03/03 2006/03/03
* Added function battle_set_walkdelay in charge of updating walkdelays of
characters based on two criterias: when the delay is induced by damage, if
the current walk delay isn't over yet, do not update it. If the delay is
instead caused by a skill, then the current walk delay cannot be decreased,
only increased. [Skotlex]
* Added upgrade_svn5455.sql, it converts the manner and karma columns to * Added upgrade_svn5455.sql, it converts the manner and karma columns to
signed. Apply this if your tables have the field as unsigned (which would signed. Apply this if your tables have the field as unsigned (which would
explain mute always disappearing after relogging) [Skotlex] explain mute always disappearing after relogging) [Skotlex]

View File

@ -27,6 +27,10 @@
========================= =========================
03/03 03/03
* Fixed missing baby-dancer job in exp2.txt [Skotlex]
* Added GrandCross's can't move delay of 900ms to skill_cast_db and Finger
Offensive's can't move delay of 200ms/lv to skill_cast_db (values taken
from the code) [Skotlex]
* Updated skill_cast_db time info for some skills: [Skotlex] * Updated skill_cast_db time info for some skills: [Skotlex]
- Magnum's time2 is skill-block time - Magnum's time2 is skill-block time
- St. Recovery/ Cure's time2 is the confuse/blind duration - St. Recovery/ Cure's time2 is the confuse/blind duration

File diff suppressed because one or more lines are too long

View File

@ -369,7 +369,7 @@
//-- CR_HOLYCROSS //-- CR_HOLYCROSS
253,0,0,0,0,10000:11000:12000:13000:14000:15000:16000:17000:18000:19000 253,0,0,0,0,10000:11000:12000:13000:14000:15000:16000:17000:18000:19000
//-- CR_GRANDCROSS //-- CR_GRANDCROSS
254,2000,1500,0,900,10000:11000:12000:13000:14000:15000:16000:17000:18000:19000 254,2000,1500,900,900,10000:11000:12000:13000:14000:15000:16000:17000:18000:19000
//-- CR_DEVOTION //-- CR_DEVOTION
255,3000,0,0,0,30000:45000:60000:75000:90000 255,3000,0,0,0,30000:45000:60000:75000:90000
//-- CR_PROVIDENCE //-- CR_PROVIDENCE
@ -390,7 +390,7 @@
//-- MO_INVESTIGATE //-- MO_INVESTIGATE
266,1000,500,0,0,0 266,1000,500,0,0,0
//-- MO_FINGEROFFENSIVE //-- MO_FINGEROFFENSIVE
267,1000,500,0,0,0 267,1000,500,0:200:400:600:800,0,0
//-- MO_STEELBODY //-- MO_STEELBODY
268,5000,0,0,30000:60000:90000:120000:150000,0 268,5000,0,0,30000:60000:90000:120000:150000,0
//-- MO_BLADESTOP //-- MO_BLADESTOP
@ -504,8 +504,8 @@
//===== NPC Skills Part 2 ================== //===== NPC Skills Part 2 ==================
//-- NPC_DARKGRANDCROSS //-- NPC_DARKGRANDNESS
339,2000,1500,0,900,10000:11000:12000:13000:14000:15000:16000:17000:18000:19000 339,2000,1500,900,900,10000:11000:12000:13000:14000:15000:16000:17000:18000:19000
//-- NPC_STOP //-- NPC_STOP
340,0,0,0,10000,0 340,0,0,0,10000,0
//-- NPC_POWERUP //-- NPC_POWERUP

View File

@ -439,34 +439,52 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
return damage*ratio/100; return damage*ratio/100;
} }
/*==========================================
* Applies walk delay to character, considering that
* if type is 0, this is a damage induced delay: if previous delay is active, do not change it.
* if type is 1, this is a skill induced delay: walk-delay may only be increased, not decreased.
*------------------------------------------
*/
int battle_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int type)
{
unsigned int *canmove_tick=NULL;
if (delay <= 0) return 0;
switch (bl->type) {
case BL_PC:
canmove_tick = &((TBL_PC*)bl)->canmove_tick;
break;
case BL_MOB:
canmove_tick = &((TBL_MOB*)bl)->canmove_tick;
break;
case BL_NPC:
canmove_tick = &((TBL_NPC*)bl)->canmove_tick;
break;
}
if (!canmove_tick)
return 0;
if (type) {
if (DIFF_TICK(*canmove_tick, tick+delay) > 0)
return 0;
} else {
if (DIFF_TICK(*canmove_tick, tick) > 0)
return 0;
}
*canmove_tick = tick + delay;
return 1;
}
static int battle_walkdelay_sub(int tid, unsigned int tick, int id, int data) static int battle_walkdelay_sub(int tid, unsigned int tick, int id, int data)
{ {
struct block_list *bl = map_id2bl(id); struct block_list *bl = map_id2bl(id);
if (!bl || status_isdead(bl)) if (!bl || status_isdead(bl))
return 0; return 0;
switch (bl->type) { if (battle_set_walkdelay(bl, tick, data, 0))
case BL_PC: battle_stopwalking(bl,3);
{
struct map_session_data *sd = (struct map_session_data*)bl;
if (sd->walktimer != -1)
pc_stop_walking (sd,3);
if (sd->canmove_tick < tick)
sd->canmove_tick = tick + data;
}
break;
case BL_MOB:
{
struct mob_data *md = (struct mob_data*)bl;
if (md->state.state == MS_WALK)
mob_stop_walking(md,3);
if (md->canmove_tick < tick)
md->canmove_tick = tick + data;
}
break;
}
return 0; return 0;
} }
/*========================================== /*==========================================
* Applies walk delay based on attack type. [Skotlex] * Applies walk delay based on attack type. [Skotlex]
*------------------------------------------ *------------------------------------------
@ -489,31 +507,10 @@ int battle_walkdelay(struct block_list *bl, unsigned int tick, int adelay, int d
if (delay <= 0) if (delay <= 0)
return 0; return 0;
//See if it makes sense to set this trigger.
switch (bl->type) {
case BL_PC:
{
struct map_session_data *sd = (struct map_session_data*)bl;
if (DIFF_TICK(sd->canmove_tick, tick+adelay) > 0)
return 0;
if (!adelay) //No need of timer.
sd->canmove_tick = tick + delay;
break;
}
case BL_MOB:
{
struct mob_data *md = (struct mob_data*)bl;
if (DIFF_TICK(md->canmove_tick, tick+adelay) > 0)
return 0;
if (!adelay) //No need of timer.
md->canmove_tick = tick + delay;
break;
}
default:
return 0;
}
if (adelay > 0) if (adelay > 0)
add_timer(tick+adelay, battle_walkdelay_sub, bl->id, delay); add_timer(tick+adelay, battle_walkdelay_sub, bl->id, delay);
else
battle_set_walkdelay(bl, tick, delay, 0);
return 1; return 1;
} }
@ -580,10 +577,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
delay = 200; delay = 200;
else else
delay = 100; delay = 100;
if(sd) battle_set_walkdelay(bl, gettick(), delay, 1);
sd->canmove_tick = gettick() + delay;
else if(md)
md->canmove_tick = gettick() + delay;
if(sc->data[SC_SHRINK].timer != -1 && rand()%100<5*sc->data[SC_AUTOGUARD].val1) if(sc->data[SC_SHRINK].timer != -1 && rand()%100<5*sc->data[SC_AUTOGUARD].val1)
skill_blown(bl,src,skill_get_blewcount(CR_SHRINK,1)); skill_blown(bl,src,skill_get_blewcount(CR_SHRINK,1));

View File

@ -54,6 +54,7 @@ int battle_heal(struct block_list *bl,struct block_list *target,int hp,int sp,in
int battle_stopattack(struct block_list *bl); int battle_stopattack(struct block_list *bl);
int battle_iswalking(struct block_list *bl); int battle_iswalking(struct block_list *bl);
int battle_stopwalking(struct block_list *bl,int type); int battle_stopwalking(struct block_list *bl,int type);
int battle_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int type);
// 通常攻撃処理まとめ // 通常攻撃処理まとめ
int battle_weapon_attack( struct block_list *bl,struct block_list *target, int battle_weapon_attack( struct block_list *bl,struct block_list *target,

View File

@ -741,7 +741,7 @@ static int mob_attack(struct mob_data *md,unsigned int tick,int data)
//Use the attack delay for next can attack try //Use the attack delay for next can attack try
//But use the attack motion to know when it can start moving. [Skotlex] //But use the attack motion to know when it can start moving. [Skotlex]
md->attackabletime = tick + status_get_adelay(&md->bl); md->attackabletime = tick + status_get_adelay(&md->bl);
md->canmove_tick = tick + status_get_amotion(&md->bl); battle_set_walkdelay(&md->bl, tick, status_get_amotion(&md->bl), 1);
md->timer=add_timer(md->attackabletime,mob_timer,md->bl.id,0); md->timer=add_timer(md->attackabletime,mob_timer,md->bl.id,0);
md->state.state=MS_ATTACK; md->state.state=MS_ATTACK;

View File

@ -1472,12 +1472,8 @@ int npc_stop_walking(struct npc_data *nd,int type)
} }
if(type&0x01) if(type&0x01)
clif_fixnpcpos(nd); clif_fixnpcpos(nd);
if(type&0x02) { if(type&0x02)
int delay=status_get_dmotion(&nd->bl); battle_set_walkdelay(&nd->bl, gettick(), status_get_dmotion(&nd->bl), 1);
unsigned int tick = gettick();
if(nd->canmove_tick < tick)
nd->canmove_tick = tick + delay;
}
return 0; return 0;
} }

View File

@ -360,6 +360,9 @@ int pc_can_move(struct map_session_data *sd)
if ((sd->sc.option & OPTION_HIDE) && pc_checkskill(sd, RG_TUNNELDRIVE) <= 0) if ((sd->sc.option & OPTION_HIDE) && pc_checkskill(sd, RG_TUNNELDRIVE) <= 0)
return 0; return 0;
if (sd->skilltimer != -1 && pc_checkskill(sd, SA_FREECAST) <= 0)
return 0;
if (pc_issit(sd)) if (pc_issit(sd))
return 0; //Can't move while sitting... return 0; //Can't move while sitting...

View File

@ -1688,7 +1688,8 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
pc_checkskill(sd, MO_CHAINCOMBO) > 0) pc_checkskill(sd, MO_CHAINCOMBO) > 0)
delay += 300 * battle_config.combo_delay_rate / 100; delay += 300 * battle_config.combo_delay_rate / 100;
sc_start4(src,SC_COMBO,100,MO_TRIPLEATTACK,skilllv,0,0,delay); sc_start4(src,SC_COMBO,100,MO_TRIPLEATTACK,skilllv,0,0,delay);
sd->attackabletime = sd->canmove_tick = tick + delay; sd->attackabletime = tick + delay;
battle_set_walkdelay(src, tick, delay, 1);
clif_combo_delay(src, delay); clif_combo_delay(src, delay);
if (sd->status.party_id>0) //bonus from SG_FRIEND [Komurka] if (sd->status.party_id>0) //bonus from SG_FRIEND [Komurka]
@ -1702,7 +1703,8 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
(pc_checkskill(sd, MO_COMBOFINISH) > 0 && sd->spiritball > 0)) (pc_checkskill(sd, MO_COMBOFINISH) > 0 && sd->spiritball > 0))
delay += 300 * battle_config.combo_delay_rate /100; delay += 300 * battle_config.combo_delay_rate /100;
sc_start4(src,SC_COMBO,100,MO_CHAINCOMBO,skilllv,0,0,delay); sc_start4(src,SC_COMBO,100,MO_CHAINCOMBO,skilllv,0,0,delay);
sd->attackabletime = sd->canmove_tick = tick + delay; sd->attackabletime = tick + delay;
battle_set_walkdelay(src, tick, delay, 1);
clif_combo_delay(src,delay); clif_combo_delay(src,delay);
break; break;
} }
@ -1717,7 +1719,8 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
)) ))
delay += 300 * battle_config.combo_delay_rate /100; delay += 300 * battle_config.combo_delay_rate /100;
sc_start4(src,SC_COMBO,100,MO_COMBOFINISH,skilllv,0,0,delay); sc_start4(src,SC_COMBO,100,MO_COMBOFINISH,skilllv,0,0,delay);
sd->attackabletime = sd->canmove_tick = tick + delay; sd->attackabletime = tick + delay;
battle_set_walkdelay(src, tick, delay, 1);
clif_combo_delay(src,delay); clif_combo_delay(src,delay);
break; break;
} }
@ -1731,7 +1734,8 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
)) ))
delay += 300 * battle_config.combo_delay_rate /100; delay += 300 * battle_config.combo_delay_rate /100;
sc_start4(src,SC_COMBO,100,CH_TIGERFIST,skilllv,0,0,delay); sc_start4(src,SC_COMBO,100,CH_TIGERFIST,skilllv,0,0,delay);
sd->attackabletime = sd->canmove_tick = tick + delay; sd->attackabletime = tick + delay;
battle_set_walkdelay(src, tick, delay, 1);
clif_combo_delay(src,delay); clif_combo_delay(src,delay);
break; break;
} }
@ -1741,7 +1745,8 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
if(damage < status_get_hp(bl)) if(damage < status_get_hp(bl))
delay += 300 * battle_config.combo_delay_rate /100; delay += 300 * battle_config.combo_delay_rate /100;
sc_start4(src,SC_COMBO,100,CH_CHAINCRUSH,skilllv,0,0,delay); sc_start4(src,SC_COMBO,100,CH_CHAINCRUSH,skilllv,0,0,delay);
sd->attackabletime = sd->canmove_tick = tick + delay; sd->attackabletime = tick + delay;
battle_set_walkdelay(src, tick, delay, 1);
clif_combo_delay(src,delay); clif_combo_delay(src,delay);
break; break;
} }
@ -1765,7 +1770,8 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
case TK_DOWNKICK: case TK_DOWNKICK:
case TK_TURNKICK: case TK_TURNKICK:
// Delay normal attack table until skill's delay has passed. Let's make it skip one attack motion. [Skotlex] // Delay normal attack table until skill's delay has passed. Let's make it skip one attack motion. [Skotlex]
sd->attackabletime = sd->canmove_tick = tick + status_get_amotion(&sd->bl); sd->attackabletime = tick + status_get_amotion(&sd->bl);
battle_set_walkdelay(src, tick, status_get_amotion(&sd->bl), 1);
break; break;
case SL_STIN: case SL_STIN:
case SL_STUN: case SL_STUN:
@ -2610,7 +2616,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s
int i; int i;
for (i = 1; i < sd->spiritball_old; i++) for (i = 1; i < sd->spiritball_old; i++)
skill_addtimerskill(src, tick + i * 200, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag); skill_addtimerskill(src, tick + i * 200, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag);
sd->canmove_tick = tick + (sd->spiritball_old - 1) * 200; // sd->canmove_tick = tick + (sd->spiritball_old - 1) * 200; Should be handled by the canmove delay on skill_cast_db [Skotlex]
} }
if (sc && sc->data[SC_BLADESTOP].timer != -1) if (sc && sc->data[SC_BLADESTOP].timer != -1)
status_change_end(src,SC_BLADESTOP,-1); status_change_end(src,SC_BLADESTOP,-1);
@ -2666,7 +2672,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl,int s
clif_movechar(sd); clif_movechar(sd);
if(dx < 0) dx = -dx; if(dx < 0) dx = -dx;
if(dy < 0) dy = -dy; if(dy < 0) dy = -dy;
sd->attackabletime = sd->canmove_tick = tick + 100 + sd->speed * ((dx > dy)? dx:dy); sd->attackabletime = tick + 100 + sd->speed * ((dx > dy)? dx:dy);
battle_set_walkdelay(src, tick, 100 + sd->speed * ((dx > dy)? dx:dy), 1);
if(sd->canact_tick < sd->canmove_tick) if(sd->canact_tick < sd->canmove_tick)
sd->canact_tick = sd->canmove_tick; sd->canact_tick = sd->canmove_tick;
sd->speed = speed; sd->speed = speed;
@ -3113,10 +3120,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case CR_GRANDCROSS: case CR_GRANDCROSS:
case NPC_GRANDDARKNESS: case NPC_GRANDDARKNESS:
//These two are actually ground placed. //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); return skill_castend_pos2(src,src->x,src->y,skillid,skilllv,tick,0);
} }
tsc = status_get_sc(bl); tsc = status_get_sc(bl);
@ -4755,8 +4758,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
sc_start(bl,type,100,skilllv,skill_time)); sc_start(bl,type,100,skilllv,skill_time));
if (md) if (md)
mob_changestate(md,MS_DELAY,skill_time); mob_changestate(md,MS_DELAY,skill_time);
else if (sd) else
sd->attackabletime = sd->canmove_tick = tick + skill_time; battle_set_walkdelay(bl, tick, skill_time, 1);
} }
break; break;
@ -5547,7 +5550,7 @@ int skill_castend_id( int tid, unsigned int tick, int id,int data )
nullpo_retr(0, sd); nullpo_retr(0, sd);
//Code cleanup. //Code cleanup.
#define skill_failed(sd) { sd->skillid = sd->skilllv = sd->skillitem = sd->skillitemlv = -1; sd->canact_tick = sd->canmove_tick = tick; sd->skilltarget = 0; } #define skill_failed(sd) { sd->skillid = sd->skilllv = sd->skillitem = sd->skillitemlv = -1; sd->canact_tick = tick; sd->skilltarget = 0; }
if(sd->skillid != SA_CASTCANCEL && sd->skilltimer != tid ) if(sd->skillid != SA_CASTCANCEL && sd->skilltimer != tid )
{ /* タイマIDの確認 */ { /* タイマIDの確認 */
@ -5654,7 +5657,7 @@ int skill_castend_id( int tid, unsigned int tick, int id,int data )
sd->canact_tick = tick; sd->canact_tick = tick;
else else
sd->canact_tick = tick + skill_delayfix(&sd->bl, sd->skillid, sd->skilllv, 0); sd->canact_tick = tick + skill_delayfix(&sd->bl, sd->skillid, sd->skilllv, 0);
sd->canmove_tick = tick + skill_get_walkdelay(sd->skillid, sd->skilllv); battle_set_walkdelay(&sd->bl, tick, skill_get_walkdelay(sd->skillid, sd->skilllv), 1);
if (skill_get_casttype(sd->skillid) == CAST_NODAMAGE) if (skill_get_casttype(sd->skillid) == CAST_NODAMAGE)
skill_castend_nodamage_id(&sd->bl,bl,sd->skillid,sd->skilllv,tick,0); skill_castend_nodamage_id(&sd->bl,bl,sd->skillid,sd->skilllv,tick,0);
else else
@ -5686,7 +5689,7 @@ int skill_castend_pos( int tid, unsigned int tick, int id,int data )
nullpo_retr(0, sd); nullpo_retr(0, sd);
//Code cleanup. //Code cleanup.
#define skill_failed(sd) { sd->skillid = sd->skilllv = sd->skillitem = sd->skillitemlv = -1; sd->canact_tick = sd->canmove_tick = tick; } #define skill_failed(sd) { sd->skillid = sd->skilllv = sd->skillitem = sd->skillitemlv = -1; sd->canact_tick = tick; }
if( sd->skilltimer != tid ) if( sd->skilltimer != tid )
{ /* タイマIDの確認 */ { /* タイマIDの確認 */
@ -5761,7 +5764,7 @@ int skill_castend_pos( int tid, unsigned int tick, int id,int data )
pc_stop_walking(sd,0); pc_stop_walking(sd,0);
sd->canact_tick = tick + skill_delayfix(&sd->bl, sd->skillid, sd->skilllv, 0); sd->canact_tick = tick + skill_delayfix(&sd->bl, sd->skillid, sd->skilllv, 0);
sd->canmove_tick = tick + skill_get_walkdelay(sd->skillid, sd->skilllv); battle_set_walkdelay(&sd->bl, tick, skill_get_walkdelay(sd->skillid, sd->skilllv), 1);
skill_castend_pos2(&sd->bl,sd->skillx,sd->skilly,sd->skillid,sd->skilllv,tick,0); skill_castend_pos2(&sd->bl,sd->skillx,sd->skilly,sd->skillid,sd->skilllv,tick,0);
@ -7289,7 +7292,6 @@ static int skill_check_condition_char_sub (struct block_list *bl, va_list ap)
struct map_session_data *sd; struct map_session_data *sd;
struct map_session_data *tsd; struct map_session_data *tsd;
int *p_sd; //Contains the list of characters found. int *p_sd; //Contains the list of characters found.
unsigned int tick = gettick();
nullpo_retr(0, bl); nullpo_retr(0, bl);
nullpo_retr(0, ap); nullpo_retr(0, ap);
@ -7327,7 +7329,7 @@ static int skill_check_condition_char_sub (struct block_list *bl, va_list ap)
default: //Warning: Assuming Ensemble Dance/Songs for code speed. [Skotlex] default: //Warning: Assuming Ensemble Dance/Songs for code speed. [Skotlex]
{ {
int skilllv; int skilllv;
if(pc_issit(tsd) || tsd->skilltimer!=-1 || tsd->canmove_tick > tick) if(pc_issit(tsd) || !pc_can_move(tsd))
return 0; return 0;
if (sd->status.sex != tsd->status.sex && if (sd->status.sex != tsd->status.sex &&
(tsd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER && (tsd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER &&
@ -8561,12 +8563,10 @@ int skill_use_id (struct map_session_data *sd, int target_id, int skill_num, int
sd->skillx = 0; sd->skillx = 0;
sd->skilly = 0; sd->skilly = 0;
sd->canact_tick = tick + casttime + 100; sd->canact_tick = tick + casttime + 100;
//Recycling forcecast to store the skill's level. [Skotlex]
sd->canmove_tick = tick + (casttime>0 && (forcecast = pc_checkskill(sd,SA_FREECAST)) > 0?0:casttime);
if (casttime > 0) { if (casttime > 0) {
sd->skilltimer = add_timer (tick + casttime, skill_castend_id, sd->bl.id, 0); sd->skilltimer = add_timer (tick + casttime, skill_castend_id, sd->bl.id, 0);
if (forcecast > 0) if ((forcecast = pc_checkskill(sd,SA_FREECAST)) > 0)
status_quick_recalc_speed (sd, SA_FREECAST, forcecast, 1); status_quick_recalc_speed (sd, SA_FREECAST, forcecast, 1);
else else
pc_stop_walking(sd,0); pc_stop_walking(sd,0);
@ -8678,11 +8678,10 @@ int skill_use_pos (struct map_session_data *sd, int skill_x, int skill_y, int sk
sd->skilltarget = 0; sd->skilltarget = 0;
sd->canact_tick = tick + casttime + 100; sd->canact_tick = tick + casttime + 100;
sd->canmove_tick = tick + (casttime>0 && (skill = pc_checkskill(sd,SA_FREECAST))>0?0:casttime);
if (casttime > 0) { if (casttime > 0) {
sd->skilltimer = add_timer(tick + casttime, skill_castend_pos, sd->bl.id, 0); sd->skilltimer = add_timer(tick + casttime, skill_castend_pos, sd->bl.id, 0);
if (skill > 0) if ((skill = pc_checkskill(sd,SA_FREECAST))>0)
status_quick_recalc_speed (sd, SA_FREECAST, skill, 1); status_quick_recalc_speed (sd, SA_FREECAST, skill, 1);
else else
pc_stop_walking(sd,0); pc_stop_walking(sd,0);
@ -8709,12 +8708,11 @@ int skill_castcancel (struct block_list *bl, int type)
struct map_session_data *sd = (struct map_session_data *)bl; struct map_session_data *sd = (struct map_session_data *)bl;
unsigned long tick = gettick(); unsigned long tick = gettick();
nullpo_retr(0, sd); nullpo_retr(0, sd);
sd->canact_tick = tick;
sd->canmove_tick = tick;
if (sd->skilltimer != -1) { if (sd->skilltimer != -1) {
if ((ret = pc_checkskill(sd,SA_FREECAST)) > 0) { if ((ret = pc_checkskill(sd,SA_FREECAST)) > 0) {
status_quick_recalc_speed(sd, SA_FREECAST, ret, 0); //Updated to use calc_speed [Skotlex] status_quick_recalc_speed(sd, SA_FREECAST, ret, 0); //Updated to use calc_speed [Skotlex]
} }
sd->canact_tick = tick;
if (!type) { if (!type) {
if (skill_get_inf( sd->skillid ) & INF_GROUND_SKILL) if (skill_get_inf( sd->skillid ) & INF_GROUND_SKILL)
ret = delete_timer( sd->skilltimer, skill_castend_pos ); ret = delete_timer( sd->skilltimer, skill_castend_pos );