summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/battle.c17
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/charcommand.c2
-rw-r--r--src/map/chrif.c2
-rw-r--r--src/map/clif.c2
-rw-r--r--src/map/guild.c12
-rw-r--r--src/map/map.c2
-rw-r--r--src/map/mob.c12
-rw-r--r--src/map/npc.c16
-rw-r--r--src/map/pc.c4
-rw-r--r--src/map/pet.c6
-rw-r--r--src/map/script.c6
-rw-r--r--src/map/skill.c47
-rw-r--r--src/map/skill.h3
-rw-r--r--src/map/unit.c5
15 files changed, 71 insertions, 67 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 9ec58981e..cee92d515 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -2778,6 +2778,7 @@ int battle_weapon_attack(struct block_list* src, struct block_list* target, unsi
struct status_data *sstatus, *tstatus;
struct status_change *sc, *tsc;
int damage,rdamage=0,rdelay=0;
+ int skillv;
struct Damage wd;
nullpo_retr(0, src);
@@ -2874,19 +2875,21 @@ int battle_weapon_attack(struct block_list* src, struct block_list* target, unsi
}
}
}
- //Recycled the damage variable rather than use a new one... [Skotlex]
- if(sd && (damage = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0)
+
+ if(sd && (skillv = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0)
{
- int triple_rate= 30 - damage; //Base Rate
+ int triple_rate= 30 - skillv; //Base Rate
if (sc && sc->data[SC_SKILLRATE_UP].timer!=-1 && sc->data[SC_SKILLRATE_UP].val1 == MO_TRIPLEATTACK)
{
triple_rate+= triple_rate*(sc->data[SC_SKILLRATE_UP].val2)/100;
status_change_end(src,SC_SKILLRATE_UP,-1);
}
if (rand()%100 < triple_rate)
- return skill_attack(BF_WEAPON,src,src,target,MO_TRIPLEATTACK,damage,tick,0);
+ return skill_attack(BF_WEAPON,src,src,target,MO_TRIPLEATTACK,skillv,tick,0);
}
- else if (sc) {
+
+ if (sc)
+ {
if (sc->data[SC_SACRIFICE].timer != -1)
return skill_attack(BF_WEAPON,src,src,target,PA_SACRIFICE,sc->data[SC_SACRIFICE].val1,tick,0);
if (sc->data[SC_MAGICALATTACK].timer != -1)
@@ -3340,7 +3343,7 @@ static const struct battle_data_short {
{ "enable_perfect_flee", &battle_config.enable_perfect_flee },
{ "casting_rate", &battle_config.cast_rate },
{ "delay_rate", &battle_config.delay_rate },
- { "delay_dependon_agi", &battle_config.delay_dependon_agi },
+ { "delay_dependon_dex", &battle_config.delay_dependon_dex },
{ "skill_delay_attack_enable", &battle_config.sdelay_attack_enable },
{ "left_cardfix_to_right", &battle_config.left_cardfix_to_right },
{ "skill_add_range", &battle_config.skill_add_range },
@@ -3734,7 +3737,7 @@ void battle_set_defaults()
battle_config.enable_perfect_flee = BL_PC|BL_PET;
battle_config.cast_rate=100;
battle_config.delay_rate=100;
- battle_config.delay_dependon_agi=0;
+ battle_config.delay_dependon_dex=0;
battle_config.sdelay_attack_enable=0;
battle_config.left_cardfix_to_right=0;
battle_config.skill_add_range=0;
diff --git a/src/map/battle.h b/src/map/battle.h
index c574f2db5..8796ac48e 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -94,7 +94,7 @@ extern struct Battle_Config {
unsigned short critical_rate;
unsigned short enable_baseatk;
unsigned short enable_perfect_flee;
- unsigned short cast_rate,delay_rate,delay_dependon_agi;
+ unsigned short cast_rate,delay_rate,delay_dependon_dex;
unsigned short sdelay_attack_enable;
unsigned short left_cardfix_to_right;
unsigned short skill_add_range;
diff --git a/src/map/charcommand.c b/src/map/charcommand.c
index ca7da3f7b..7d4151b64 100644
--- a/src/map/charcommand.c
+++ b/src/map/charcommand.c
@@ -1349,7 +1349,7 @@ int charcommand_fakename(const int fd, struct map_session_data* sd, const char*
return 0;
}
- memcpy(pl_sd->fakename,name, NAME_LENGTH-1);
+ memcpy(pl_sd->fakename, name, NAME_LENGTH);
clif_charnameack(0, &pl_sd->bl);
clif_displaymessage(sd->fd,"Fake name enabled.");
diff --git a/src/map/chrif.c b/src/map/chrif.c
index ba11565b7..1adee71a9 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -668,7 +668,7 @@ int chrif_char_ask_name_answer(int fd)
char player_name[NAME_LENGTH];
acc = RFIFOL(fd,2); // account_id of who has asked (-1 if nobody)
- memcpy(player_name, RFIFOP(fd,6), NAME_LENGTH-1);
+ memcpy(player_name, RFIFOP(fd,6), NAME_LENGTH);
player_name[NAME_LENGTH-1] = '\0';
sd = map_id2sd(acc);
diff --git a/src/map/clif.c b/src/map/clif.c
index fd5f69bd0..a4ffc3b6b 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -10825,7 +10825,7 @@ void clif_parse_PMIgnore(int fd, struct map_session_data *sd)
return;
}
//Insert in position i
- memcpy(sd->ignore[i].name, nick, NAME_LENGTH-1);
+ memcpy(sd->ignore[i].name, nick, NAME_LENGTH);
WFIFOB(fd,3) = 0; // success
WFIFOSET(fd, packet_len(0x0d1));
if (strcmp(wisp_server_name, nick) == 0)
diff --git a/src/map/guild.c b/src/map/guild.c
index 74d2a1978..857eeffb0 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -182,9 +182,9 @@ static int guild_read_castledb(void)
gc=(struct guild_castle *)aCalloc(1,sizeof(struct guild_castle));
gc->castle_id=atoi(str[0]);
- memcpy(gc->map_name,mapindex_normalize_name(str[1]),MAP_NAME_LENGTH-1);
- memcpy(gc->castle_name,str[2],NAME_LENGTH-1);
- memcpy(gc->castle_event,str[3],NAME_LENGTH-1);
+ memcpy(gc->map_name,mapindex_normalize_name(str[1]),MAP_NAME_LENGTH);
+ memcpy(gc->castle_name,str[2],NAME_LENGTH);
+ memcpy(gc->castle_event,str[3],NAME_LENGTH);
idb_put(castle_db,gc->castle_id,gc);
@@ -336,7 +336,7 @@ void guild_makemember(struct guild_member *m,struct map_session_data *sd)
// m->exp_payper =0;
m->online =1;
m->position =MAX_GUILDPOSITION-1;
- memcpy(m->name,sd->status.name,NAME_LENGTH-1);
+ memcpy(m->name,sd->status.name,NAME_LENGTH);
return;
}
// ギルド競合確認
@@ -1032,7 +1032,7 @@ int guild_change_position(int guild_id,int idx,
//Mode 0x10 <- Expel.
p.mode=mode&0x11;
p.exp_mode=exp_mode;
- memcpy(p.name,name,NAME_LENGTH-1);
+ memcpy(p.name,name,NAME_LENGTH);
p.name[NAME_LENGTH-1] = '\0'; //Security check... [Skotlex]
return intif_guild_position(guild_id,idx,&p);
}
@@ -1462,7 +1462,7 @@ int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id
for(j=0;j<MAX_GUILDALLIANCE;j++)
if(g[i]->alliance[j].guild_id==0){
g[i]->alliance[j].guild_id=guild_id[1-i];
- memcpy(g[i]->alliance[j].name,guild_name[1-i],NAME_LENGTH-1);
+ memcpy(g[i]->alliance[j].name,guild_name[1-i],NAME_LENGTH);
g[i]->alliance[j].opposition=flag&1;
break;
}
diff --git a/src/map/map.c b/src/map/map.c
index 5af776569..6df33fe26 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -2464,7 +2464,7 @@ int map_addmap(char *mapname)
return 1;
}
- memcpy(map[map_num].name, mapindex_normalize_name(mapname), MAP_NAME_LENGTH-1);
+ memcpy(map[map_num].name, mapindex_normalize_name(mapname), MAP_NAME_LENGTH);
map_num++;
return 0;
}
diff --git a/src/map/mob.c b/src/map/mob.c
index 76a89f2e1..79ae84435 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -204,7 +204,7 @@ struct mob_data* mob_spawn_dataset(struct spawn_data *data)
md->bl.y = data->y;
md->class_ = data->class_;
md->db = mob_db(md->class_);
- memcpy(md->name, data->name, NAME_LENGTH-1);
+ memcpy(md->name, data->name, NAME_LENGTH);
if (data->state.ai)
md->special_state.ai = data->state.ai;
if (data->state.size)
@@ -2338,9 +2338,9 @@ int mob_class_change (struct mob_data *md, int class_)
md->class_ = class_;
md->db = mob_db(class_);
if (battle_config.override_mob_names==1)
- memcpy(md->name,md->db->name,NAME_LENGTH-1);
+ memcpy(md->name,md->db->name,NAME_LENGTH);
else
- memcpy(md->name,md->db->jname,NAME_LENGTH-1);
+ memcpy(md->name,md->db->jname,NAME_LENGTH);
mob_stop_attack(md);
mob_stop_walking(md, 0);
@@ -3210,9 +3210,9 @@ int mob_parse_dbrow(char** str)
status = &db->status;
db->vd.class_ = class_;
- memcpy(db->sprite, str[1], NAME_LENGTH-1);
- memcpy(db->jname, str[2], NAME_LENGTH-1);
- memcpy(db->name, str[3], NAME_LENGTH-1);
+ strncpy(db->sprite, str[1], NAME_LENGTH);
+ strncpy(db->jname, str[2], NAME_LENGTH);
+ strncpy(db->name, str[3], NAME_LENGTH);
db->lv = atoi(str[4]);
db->lv = cap_value(db->lv, 1, USHRT_MAX);
status->max_hp = atoi(str[5]);
diff --git a/src/map/npc.c b/src/map/npc.c
index f037bea2d..61a8ef093 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -464,7 +464,7 @@ int npc_addeventtimer(struct npc_data *nd,int tick,const char *name)
if(evname==NULL){
ShowFatalError("npc_addeventtimer: out of memory !\n");exit(1);
}
- memcpy(evname,name,NAME_LENGTH-1);
+ strncpy(evname,name,NAME_LENGTH);
evname[NAME_LENGTH-1] = '\0';
nd->eventtimer[i]=add_timer(gettick()+tick,
npc_event_timer,nd->bl.id,(int)evname);
@@ -1660,8 +1660,8 @@ int npc_parse_warp (char *w1,char *w2,char *w3,char *w4)
nd->bl.m = m;
nd->bl.x = x;
nd->bl.y = y;
- memcpy(nd->name, w3, NAME_LENGTH-1);
- memcpy(nd->exname, w3, NAME_LENGTH-1);
+ strncpy(nd->name, w3, NAME_LENGTH);
+ strncpy(nd->exname, w3, NAME_LENGTH);
if (!battle_config.warp_point_debug)
nd->class_ = WARP_CLASS;
@@ -1761,7 +1761,7 @@ static int npc_parse_shop (char *w1, char *w2, char *w3, char *w4)
nd->bl.x = x;
nd->bl.y = y;
nd->bl.id = npc_get_new_npc_id();
- memcpy(nd->name, w3, NAME_LENGTH-1);
+ memcpy(nd->name, w3, NAME_LENGTH);
nd->name[NAME_LENGTH-1] = '\0';
nd->class_ = m==-1?-1:atoi(w4);
nd->speed = 200;
@@ -2036,11 +2036,11 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
}
if (p) {
*p = 0;
- memcpy(nd->name, w3, NAME_LENGTH-1);
- memcpy(nd->exname, p+2, NAME_LENGTH-1);
+ memcpy(nd->name, w3, NAME_LENGTH);
+ memcpy(nd->exname, p+2, NAME_LENGTH);
} else {
- memcpy(nd->name, w3, NAME_LENGTH-1);
- memcpy(nd->exname, w3, NAME_LENGTH-1);
+ memcpy(nd->name, w3, NAME_LENGTH);
+ memcpy(nd->exname, w3, NAME_LENGTH);
}
if((dnd = npc_name2id(nd->exname))){
diff --git a/src/map/pc.c b/src/map/pc.c
index caa4b535c..22dad96f0 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -4578,9 +4578,9 @@ int pc_allskillup(struct map_session_data *sd)
//pc_calc_skilltree takes care of setting the ID to valid skills. [Skotlex]
if (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill)
{ //Get ALL skills except npc/guild ones. [Skotlex]
- //and except SG_DEVIL [Komurka]
+ //and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage]
for(i=0;i<MAX_SKILL;i++){
- if(!(skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)) && i!=SG_DEVIL)
+ if(!(skill_get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)) && i!=SG_DEVIL && i!=MO_TRIPLEATTACK && i!=RG_SNATCHER)
sd->status.skill[i].lv=skill_get_max(i); //Nonexistant skills should return a max of 0 anyway.
}
}
diff --git a/src/map/pet.c b/src/map/pet.c
index 02ae3b5e2..82168ac48 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -709,7 +709,7 @@ int pet_change_name_ack(struct map_session_data *sd, char* name, int flag)
clif_send_petstatus(sd); //Send status so client knows oet name change got rejected.
return 0;
}
- memcpy(pd->pet.name, name, NAME_LENGTH-1);
+ memcpy(pd->pet.name, name, NAME_LENGTH);
clif_charnameack (0,&pd->bl);
pd->pet.rename_flag = 1;
clif_pet_equip(pd);
@@ -1327,8 +1327,8 @@ int read_petdb()
}
pet_db[j].class_ = nameid;
- memcpy(pet_db[j].name,str[1],NAME_LENGTH-1);
- memcpy(pet_db[j].jname,str[2],NAME_LENGTH-1);
+ strncpy(pet_db[j].name,str[1],NAME_LENGTH);
+ strncpy(pet_db[j].jname,str[2],NAME_LENGTH);
pet_db[j].itemID=atoi(str[3]);
pet_db[j].EggID=atoi(str[4]);
pet_db[j].AcceID=atoi(str[5]);
diff --git a/src/map/script.c b/src/map/script.c
index 2a4c4ccc5..46042f085 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -6132,7 +6132,7 @@ char *buildin_getpartyname_sub(int party_id)
if(p!=NULL){
char *buf;
buf=(char *)aMallocA(NAME_LENGTH*sizeof(char));
- memcpy(buf, p->party.name, NAME_LENGTH-1);
+ memcpy(buf, p->party.name, NAME_LENGTH);
buf[NAME_LENGTH-1] = '\0';
return buf;
}
@@ -6248,7 +6248,7 @@ char *buildin_getguildname_sub(int guild_id)
if(g!=NULL){
char *buf;
buf=(char *)aMallocA(NAME_LENGTH*sizeof(char));
- memcpy(buf, g->name, NAME_LENGTH-1);
+ memcpy(buf, g->name, NAME_LENGTH);
buf[NAME_LENGTH-1] = '\0';
return buf;
}
@@ -6277,7 +6277,7 @@ char *buildin_getguildmaster_sub(int guild_id)
if(g!=NULL){
char *buf;
buf=(char *)aMallocA(NAME_LENGTH*sizeof(char));
- memcpy(buf, g->master, NAME_LENGTH-1);
+ memcpy(buf, g->master, NAME_LENGTH);
buf[NAME_LENGTH-1] = '\0';
return buf;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index 11706ac42..0fff9ba0c 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -683,7 +683,7 @@ int skill_get_maxcount( int id ){ skill_get (skill_db[id].maxcount, id, 1); }
int skill_get_blewcount( int id ,int lv ){ skill_get (skill_db[id].blewcount[lv-1], id, lv); }
int skill_get_mhp( int id ,int lv ){ skill_get (skill_db[id].mhp[lv-1], id, lv); }
int skill_get_castnodex( int id ,int lv ){ skill_get (skill_db[id].castnodex[lv-1], id, lv); }
-int skill_get_delaynodex( int id ,int lv ){ skill_get (skill_db[id].delaynoagi[lv-1], id, lv); }
+int skill_get_delaynodex( int id ,int lv ){ skill_get (skill_db[id].delaynodex[lv-1], id, lv); }
int skill_get_nocast ( int id ){ skill_get (skill_db[id].nocast, id, 1); }
int skill_get_type( int id ){ skill_get (skill_db[id].skill_type, id, 1); }
int skill_get_unit_id ( int id, int flag ){ skill_get (skill_db[id].unit_id[flag], id, 1); }
@@ -858,12 +858,12 @@ int skillnotok (int skillid, struct map_session_data *sd)
if (i > MAX_SKILL || i < 0)
return 1;
- if (sd->blockskill[i] > 0)
- return 1;
-
if (battle_config.gm_skilluncond && pc_isGM(sd) >= battle_config.gm_skilluncond)
return 0; // gm's can do anything damn thing they want
+ if (sd->blockskill[i] > 0)
+ return 1;
+
// Check skill restrictions [Celest]
if(!map_flag_vs(m) && skill_get_nocast (skillid) & 1)
return 1;
@@ -8671,7 +8671,7 @@ int skill_check_condition (struct map_session_data *sd, int skill, int lv, int t
}
/*==========================================
- *
+ * Does cast-time reductions based on dex, item bonuses and config setting
*------------------------------------------*/
int skill_castfix (struct block_list *bl, int skill_id, int skill_lv)
{
@@ -8689,9 +8689,10 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv)
else return 0; // instant cast
}
- // calculate cast time reduced by card bonuses
- if (sd && sd->castrate != 100)
- time = time * sd->castrate / 100;
+ // calculate cast time reduced by item/card bonuses
+ if (!(skill_get_castnodex(skill_id, skill_lv)&4))
+ if (sd && sd->castrate != 100)
+ time = time * sd->castrate / 100;
// config cast time multiplier
if (battle_config.cast_rate != 100)
@@ -8725,11 +8726,11 @@ int skill_castfix_sc (struct block_list *bl, int time)
}
/*==========================================
- *
+ * Does delay reductions based on dex,
*------------------------------------------*/
int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv)
{
- int delaynochange = skill_get_delaynodex(skill_id, skill_lv);
+ int delaynodex = skill_get_delaynodex(skill_id, skill_lv);
int time = skill_get_delay(skill_id, skill_lv);
nullpo_retr(0, bl);
@@ -8756,9 +8757,9 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv)
time -= 4*status_get_agi(bl) - 2*status_get_dex(bl);
break;
default:
- if (battle_config.delay_dependon_agi && !(delaynochange&1))
- { // if skill casttime is allowed to be reduced by agi
- int scale = battle_config.castrate_dex_scale - status_get_agi(bl);
+ if (battle_config.delay_dependon_dex && !(delaynodex&1))
+ { // if skill delay is allowed to be reduced by dex
+ int scale = battle_config.castrate_dex_scale - status_get_dex(bl);
if (scale > 0)
time = time * scale / battle_config.castrate_dex_scale;
else //To be capped later to minimum.
@@ -8766,13 +8767,7 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv)
}
}
- if (bl->type == BL_PC && ((TBL_PC*)bl)->delayrate != 100)
- time = time * ((TBL_PC*)bl)->delayrate / 100;
-
- if (battle_config.delay_rate != 100)
- time = time * battle_config.delay_rate / 100;
-
- if (!(delaynochange&2))
+ if (!(delaynodex&2))
{
struct status_change *sc;
sc= status_get_sc(bl);
@@ -8793,8 +8788,14 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv)
}
}
- return (time < battle_config.min_skill_delay_limit)?
- battle_config.min_skill_delay_limit:time;
+ if (!(delaynodex&4))
+ if (bl->type == BL_PC && ((TBL_PC*)bl)->delayrate != 100)
+ time = time * ((TBL_PC*)bl)->delayrate / 100;
+
+ if (battle_config.delay_rate != 100)
+ time = time * battle_config.delay_rate / 100;
+
+ return max(time, battle_config.min_skill_delay_limit);
}
/*=========================================
@@ -11553,7 +11554,7 @@ int skill_readdb (void)
skill_split_atoi(split[1],skill_db[i].castnodex);
if (!split[2])
continue;
- skill_split_atoi(split[2],skill_db[i].delaynoagi);
+ skill_split_atoi(split[2],skill_db[i].delaynodex);
}
fclose(fp);
ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n",path);
diff --git a/src/map/skill.h b/src/map/skill.h
index 9d61a8f54..29bd94ac9 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -71,8 +71,7 @@ struct skill_db {
int hp[MAX_SKILL_LEVEL],sp[MAX_SKILL_LEVEL],mhp[MAX_SKILL_LEVEL],hp_rate[MAX_SKILL_LEVEL],sp_rate[MAX_SKILL_LEVEL],zeny[MAX_SKILL_LEVEL];
int weapon,ammo,ammo_qty[MAX_SKILL_LEVEL],state,spiritball[MAX_SKILL_LEVEL];
int itemid[10],amount[10];
- int castnodex[MAX_SKILL_LEVEL];
- int delaynoagi[MAX_SKILL_LEVEL];
+ int castnodex[MAX_SKILL_LEVEL], delaynodex[MAX_SKILL_LEVEL];
int nocast;
int unit_id[2];
int unit_layout_type[MAX_SKILL_LEVEL];
diff --git a/src/map/unit.c b/src/map/unit.c
index c4ca10395..a60ab2d95 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -954,7 +954,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int
break;
case MO_FINGEROFFENSIVE:
if(sd)
- casttime += casttime * ((skill_lv > sd->spiritball)? sd->spiritball:skill_lv);
+ casttime += casttime * min(skill_lv, sd->spiritball);
break;
case MO_EXTREMITYFIST:
if (sc && sc->data[SC_COMBO].timer != -1 &&
@@ -981,6 +981,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int
break;
}
+ // moved here to prevent Suffragium from ending if skill fails
if (!(skill_get_castnodex(skill_num, skill_lv)&2))
casttime = skill_castfix_sc(src, casttime);
@@ -1116,7 +1117,7 @@ int unit_skilluse_pos2( struct block_list *src, int skill_x, int skill_y, int sk
unit_stop_attack(src);
ud->state.skillcastcancel = castcancel;
-
+ // moved here to prevent Suffragium from ending if skill fails
if (!(skill_get_castnodex(skill_num, skill_lv)&2))
casttime = skill_castfix_sc(src, casttime);