- Moved the duel functions to pc.c since they are so totally out of place in atcommand.c

- Fixed Spider Web not ending when hit by a fireelemental attack.
- Cast-time reductions from status changes will not be executed until right before casting, to prevent status changes from ending when attempting to cast and the attempt fails (invalid cells, not enough sp, wrong target, etc, etc)
- Added check to prevent Wand of Hermod from seeking for a partner to encore, since the partner is supposed to be the warp.
- Moved the duel auto-reject on logout from map_quit to unit_free
- Corrected the mob spawn reading code so that the event-name can be up to 50 characters long (which is the actual event length) and so that it can read spaces within them, it will also strip the leading/trailing quotes if you use them so that the event is actually found on mob-death (so you can do stuff like "My NPC::OnDead" as a valid event).
- Moved the homunc inherit speed from the master from status_calc_pc to LoadEndAck, since the hom's speed matches that of the master each time the master changes maps.


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9173 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
skotlex 2006-11-08 16:17:30 +00:00
parent 3501ccc736
commit 405f4633ec
14 changed files with 247 additions and 216 deletions

View File

@ -3,6 +3,22 @@ Date Added
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/11/08
* Fixed Spider Web not ending when hit by a fireelemental attack. [Skotlex]
* Cast-time reductions from status changes will not be executed until right
before casting, to prevent status changes from ending when attempting to
cast and the attempt fails (invalid cells, not enough sp, wrong target,
etc, etc) [Skotlex]
* Added check to prevent Wand of Hermod from seeking for a partner to
encore, since the partner is supposed to be the warp. [Skotlex]
* Corrected the mob spawn reading code so that the event-name can be up to
50 characters long (which is the actual event length) and so that it can
read spaces within them, it will also strip the leading/trailing quotes if
you use them so that the event is actually found on mob-death (so you can
do stuff like "My NPC::OnDead" as a valid event). [Skotlex]
* Moved the homunc inherit speed from the master from status_calc_pc to
LoadEndAck, since the hom's speed matches that of the master each time the
master changes maps. [Skotlex]
2006/11/07 2006/11/07
* Applied FlavioJs's patch which enables colored console output for Windows * Applied FlavioJs's patch which enables colored console output for Windows
systems. It also includes a config setting called systems. It also includes a config setting called

View File

@ -1003,177 +1003,6 @@ int atcommand_config_read(const char *cfgName) {
return 0; return 0;
} }
/*==========================================
* Duel organizing functions [LuzZza]
*------------------------------------------
*/
void duel_savetime(struct map_session_data* sd) {
time_t timer;
struct tm *t;
time(&timer);
t = localtime(&timer);
pc_setglobalreg(sd, "PC_LAST_DUEL_TIME",
t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min);
return;
}
int duel_checktime(struct map_session_data* sd) {
int diff;
time_t timer;
struct tm *t;
time(&timer);
t = localtime(&timer);
diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min -
pc_readglobalreg(sd, "PC_LAST_DUEL_TIME");
return !(diff >= 0 && diff < battle_config.duel_time_interval);
}
static int duel_showinfo_sub(struct map_session_data* sd,va_list va) {
struct map_session_data *ssd = va_arg(va, struct map_session_data*);
int *p = va_arg(va, int*);
char output[256];
if (sd->duel_group != ssd->duel_group) return 0;
sprintf(output, " %d. %s", ++(*p), (unsigned char *)sd->status.name);
clif_disp_onlyself(ssd, output, strlen(output));
return 1;
}
int duel_showinfo(
const unsigned int did, struct map_session_data* sd)
{
int p=0;
char output[256];
if(duel_list[did].max_players_limit > 0)
sprintf(output, msg_txt(370), //" -- Duels: %d/%d, Members: %d/%d, Max players: %d --"
did, duel_count,
duel_list[did].members_count,
duel_list[did].members_count + duel_list[did].invites_count,
duel_list[did].max_players_limit);
else
sprintf(output, msg_txt(371), //" -- Duels: %d/%d, Members: %d/%d --"
did, duel_count,
duel_list[did].members_count,
duel_list[did].members_count + duel_list[did].invites_count);
clif_disp_onlyself(sd, output, strlen(output));
clif_foreachclient(duel_showinfo_sub, sd, &p);
return 0;
}
int duel_create(
struct map_session_data* sd, const unsigned int maxpl)
{
int i=1;
char output[256];
while(duel_list[i].members_count > 0 && i < MAX_DUEL) i++;
if(i == MAX_DUEL) return 0;
duel_count++;
sd->duel_group = i;
duel_list[i].members_count++;
duel_list[i].invites_count = 0;
duel_list[i].max_players_limit = maxpl;
strcpy(output, msg_txt(372)); // " -- Duel has been created (@invite/@leave) --"
clif_disp_onlyself(sd, output, strlen(output));
clif_set0199(sd->fd, 1);
//clif_misceffect2(&sd->bl, 159);
return i;
}
int duel_invite(
const unsigned int did, struct map_session_data* sd,
struct map_session_data* target_sd)
{
char output[256];
sprintf(output, msg_txt(373), // " -- Player %s invites %s to duel --"
(unsigned char *)sd->status.name, (unsigned char *)target_sd->status.name);
clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
target_sd->duel_invite = did;
duel_list[did].invites_count++;
// "Blue -- Player %s invites you to PVP duel (@accept/@reject) --"
sprintf(output, msg_txt(374), (unsigned char *)sd->status.name);
clif_GMmessage((struct block_list *)target_sd, output, strlen(output)+1, 3);
return 0;
}
static int duel_leave_sub(struct map_session_data* sd,va_list va) {
int did = va_arg(va, int);
if (sd->duel_invite == did)
sd->duel_invite = 0;
return 0;
}
int duel_leave(
const unsigned int did, struct map_session_data* sd)
{
char output[256];
// " <- Player %s has left duel --"
sprintf(output, msg_txt(375), (unsigned char *)sd->status.name);
clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
duel_list[did].members_count--;
if(duel_list[did].members_count == 0) {
clif_foreachclient(duel_leave_sub, did);
duel_count--;
}
sd->duel_group = 0;
duel_savetime(sd);
clif_set0199(sd->fd, 0);
return 0;
}
int duel_accept(
const unsigned int did, struct map_session_data* sd)
{
char output[256];
duel_list[did].members_count++;
sd->duel_group = sd->duel_invite;
duel_list[did].invites_count--;
sd->duel_invite = 0;
// " -> Player %s has accepted duel --"
sprintf(output, msg_txt(376), (unsigned char *)sd->status.name);
clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
clif_set0199(sd->fd, 1);
//clif_misceffect2(&sd->bl, 159);
return 0;
}
int duel_reject(
const unsigned int did, struct map_session_data* sd)
{
char output[256];
// " -- Player %s has rejected duel --"
sprintf(output, msg_txt(377), (unsigned char *)sd->status.name);
clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
duel_list[did].invites_count--;
sd->duel_invite = 0;
return 0;
}
/*========================================== /*==========================================
// @ command processing functions // @ command processing functions
*------------------------------------------ *------------------------------------------

View File

@ -318,9 +318,6 @@ int atcommand_jumpto(const int fd, struct map_session_data* sd, const char* comm
int atcommand_recall(const int fd, struct map_session_data* sd, const char* command, const char* message); // [Yor] int atcommand_recall(const int fd, struct map_session_data* sd, const char* command, const char* message); // [Yor]
int atcommand_monster(const int fd, struct map_session_data* sd, const char* command, const char* message); int atcommand_monster(const int fd, struct map_session_data* sd, const char* command, const char* message);
int duel_leave(const unsigned int did, struct map_session_data* sd); // [LuzZza]
int duel_reject(const unsigned int did, struct map_session_data* sd); // [LuzZza]
int atcommand_config_read(const char *cfgName); int atcommand_config_read(const char *cfgName);
int msg_config_read(const char *cfgName); int msg_config_read(const char *cfgName);
void do_final_msg(void); void do_final_msg(void);

View File

@ -212,8 +212,12 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
if (tsc->data[SC_ARMOR_ELEMENT].val3 == atk_elem) if (tsc->data[SC_ARMOR_ELEMENT].val3 == atk_elem)
ratio -= tsc->data[SC_ARMOR_ELEMENT].val4; ratio -= tsc->data[SC_ARMOR_ELEMENT].val4;
} }
if(tsc->data[SC_SPIDERWEB].timer!=-1 && atk_elem == ELE_FIRE) // [Celest] if(tsc->data[SC_SPIDERWEB].timer!=-1 && atk_elem == ELE_FIRE)
{ // [Celest]
damage <<= 1; damage <<= 1;
status_change_end(target, SC_SPIDERWEB, -1);
}
} }
return damage*ratio/100; return damage*ratio/100;
} }

View File

@ -320,7 +320,7 @@ int clif_send_sub(struct block_list *bl, va_list ap)
//Check if hidden, better to modify the char's buffer than the //Check if hidden, better to modify the char's buffer than the
//given buffer to prevent intravision affecting the packet as //given buffer to prevent intravision affecting the packet as
//it's being received by everyone. [Skotlex] //it's being received by everyone. [Skotlex]
/* New implemenation... not quite correct yet as the client no longer /* New implementation... not quite correct yet as the client no longer
* displays correctly the SI_INTRAVISION effect. * displays correctly the SI_INTRAVISION effect.
if ((sd->special_state.intravision || sd->sc.data[SC_INTRAVISION].timer != -1 ) if ((sd->special_state.intravision || sd->sc.data[SC_INTRAVISION].timer != -1 )
&& bl != src_bl && WFIFOW(sd->fd,0) == 0x0196) && bl != src_bl && WFIFOW(sd->fd,0) == 0x0196)
@ -8345,11 +8345,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
if(merc_is_hom_active(sd->hd)) { if(merc_is_hom_active(sd->hd)) {
map_addblock(&sd->hd->bl); map_addblock(&sd->hd->bl);
clif_spawn(&sd->hd->bl); clif_spawn(&sd->hd->bl);
// clif_homunack(sd);
clif_hominfo(sd,sd->hd,1); clif_hominfo(sd,sd->hd,1);
clif_hominfo(sd,sd->hd,0); //for some reason, at least older clients want this sent twice clif_hominfo(sd,sd->hd,0); //for some reason, at least older clients want this sent twice
clif_send_homdata(sd,0,0); clif_send_homdata(sd,0,0);
clif_homskillinfoblock(sd); clif_homskillinfoblock(sd);
//Homunc mimic their master's speed on each map change. [Skotlex]
if (battle_config.slaves_inherit_speed)
status_calc_bl(&sd->hd->bl, SCB_SPEED);
} }
// view equipment item // view equipment item

View File

@ -1682,14 +1682,6 @@ int map_quit(struct map_session_data *sd) {
} }
} }
// Force exiting from duel and rejecting
// all duel invitations when player quit [LuzZza]
if(sd->duel_group > 0)
duel_leave(sd->duel_group, sd);
if(sd->duel_invite > 0)
duel_reject(sd->duel_invite, sd);
//Do we really need to remove the name? //Do we really need to remove the name?
idb_remove(charid_db,sd->status.char_id); idb_remove(charid_db,sd->status.char_id);
idb_remove(id_db,sd->bl.id); idb_remove(id_db,sd->bl.id);

View File

@ -159,10 +159,12 @@ int mob_parse_dataset(struct spawn_data *data) {
return 0; return 0;
//better safe than sorry, current md->npc_event has a size of 50 //better safe than sorry, current md->npc_event has a size of 50
if (strlen(data->eventname) >= 50) if ((i=strlen(data->eventname)) >= 50)
return 0; return 0;
if (data->eventname[0] && strlen(data->eventname) <= 2) if (data->eventname[0])
{
if(i <= 2)
{ //Portable monster big/small implementation. [Skotlex] { //Portable monster big/small implementation. [Skotlex]
i = atoi(data->eventname); i = atoi(data->eventname);
if (i) { if (i) {
@ -174,6 +176,12 @@ int mob_parse_dataset(struct spawn_data *data) {
data->state.ai=1; data->state.ai=1;
data->eventname[0] = '\0'; //Clear event as it is not used. data->eventname[0] = '\0'; //Clear event as it is not used.
} }
} else {
if (data->eventname[i-1] == '"');
data->eventname[i-1] = '\0'; //Remove trailing quote.
if (data->eventname[0] == '"') //Strip leading quotes
memmove(data->eventname, data->eventname+1, i-1);
}
} }
if (!data->level) if (!data->level)
data->level = mob_db(data->class_)->lv; data->level = mob_db(data->class_)->lv;
@ -2784,7 +2792,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event)
} }
md->skillidx = i; md->skillidx = i;
flag = unit_skilluse_pos2(&md->bl, x, y, ms[i].skill_id, ms[i].skill_lv, flag = unit_skilluse_pos2(&md->bl, x, y, ms[i].skill_id, ms[i].skill_lv,
skill_castfix_sc(&md->bl, ms[i].casttime), ms[i].cancel); ms[i].casttime, ms[i].cancel);
if (!flag) md->skillidx = -1; //Skill failed. if (!flag) md->skillidx = -1; //Skill failed.
return flag; return flag;
} else { } else {
@ -2814,7 +2822,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event)
} }
md->skillidx = i; md->skillidx = i;
flag = (bl && unit_skilluse_id2(&md->bl, bl->id, ms[i].skill_id, ms[i].skill_lv, flag = (bl && unit_skilluse_id2(&md->bl, bl->id, ms[i].skill_id, ms[i].skill_lv,
skill_castfix_sc(&md->bl,ms[i].casttime), ms[i].cancel)); ms[i].casttime, ms[i].cancel));
if (!flag) md->skillidx = -1; if (!flag) md->skillidx = -1;
return flag; return flag;
} else { } else {

View File

@ -2209,7 +2209,7 @@ int npc_parse_mob (char *w1, char *w2, char *w3, char *w4)
// 引数の個数チェック // 引数の個数チェック
if (sscanf(w1, "%15[^,],%d,%d,%d,%d", mapname, &x, &y, &xs, &ys) < 3 || if (sscanf(w1, "%15[^,],%d,%d,%d,%d", mapname, &x, &y, &xs, &ys) < 3 ||
sscanf(w4, "%d,%d,%u,%u,%23s", &class_, &num, &mob.delay1, &mob.delay2, mob.eventname) < 2 ) { sscanf(w4, "%d,%d,%u,%u,%49[^\r\n]", &class_, &num, &mob.delay1, &mob.delay2, mob.eventname) < 2 ) {
ShowError("bad monster line : %s %s %s (file %s)\n", w1, w3, w4, current_file); ShowError("bad monster line : %s %s %s (file %s)\n", w1, w3, w4, current_file);
return 1; return 1;
} }

View File

@ -7006,6 +7006,177 @@ void pc_setstand(struct map_session_data *sd){
sd->state.dead_sit = sd->vd.dead_sit = 0; sd->state.dead_sit = sd->vd.dead_sit = 0;
} }
/*==========================================
* Duel organizing functions [LuzZza]
*------------------------------------------
*/
void duel_savetime(struct map_session_data* sd) {
time_t timer;
struct tm *t;
time(&timer);
t = localtime(&timer);
pc_setglobalreg(sd, "PC_LAST_DUEL_TIME",
t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min);
return;
}
int duel_checktime(struct map_session_data* sd) {
int diff;
time_t timer;
struct tm *t;
time(&timer);
t = localtime(&timer);
diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min -
pc_readglobalreg(sd, "PC_LAST_DUEL_TIME");
return !(diff >= 0 && diff < battle_config.duel_time_interval);
}
static int duel_showinfo_sub(struct map_session_data* sd,va_list va) {
struct map_session_data *ssd = va_arg(va, struct map_session_data*);
int *p = va_arg(va, int*);
char output[256];
if (sd->duel_group != ssd->duel_group) return 0;
sprintf(output, " %d. %s", ++(*p), (unsigned char *)sd->status.name);
clif_disp_onlyself(ssd, output, strlen(output));
return 1;
}
int duel_showinfo(
const unsigned int did, struct map_session_data* sd)
{
int p=0;
char output[256];
if(duel_list[did].max_players_limit > 0)
sprintf(output, msg_txt(370), //" -- Duels: %d/%d, Members: %d/%d, Max players: %d --"
did, duel_count,
duel_list[did].members_count,
duel_list[did].members_count + duel_list[did].invites_count,
duel_list[did].max_players_limit);
else
sprintf(output, msg_txt(371), //" -- Duels: %d/%d, Members: %d/%d --"
did, duel_count,
duel_list[did].members_count,
duel_list[did].members_count + duel_list[did].invites_count);
clif_disp_onlyself(sd, output, strlen(output));
clif_foreachclient(duel_showinfo_sub, sd, &p);
return 0;
}
int duel_create(
struct map_session_data* sd, const unsigned int maxpl)
{
int i=1;
char output[256];
while(duel_list[i].members_count > 0 && i < MAX_DUEL) i++;
if(i == MAX_DUEL) return 0;
duel_count++;
sd->duel_group = i;
duel_list[i].members_count++;
duel_list[i].invites_count = 0;
duel_list[i].max_players_limit = maxpl;
strcpy(output, msg_txt(372)); // " -- Duel has been created (@invite/@leave) --"
clif_disp_onlyself(sd, output, strlen(output));
clif_set0199(sd->fd, 1);
//clif_misceffect2(&sd->bl, 159);
return i;
}
int duel_invite(
const unsigned int did, struct map_session_data* sd,
struct map_session_data* target_sd)
{
char output[256];
sprintf(output, msg_txt(373), // " -- Player %s invites %s to duel --"
(unsigned char *)sd->status.name, (unsigned char *)target_sd->status.name);
clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
target_sd->duel_invite = did;
duel_list[did].invites_count++;
// "Blue -- Player %s invites you to PVP duel (@accept/@reject) --"
sprintf(output, msg_txt(374), (unsigned char *)sd->status.name);
clif_GMmessage((struct block_list *)target_sd, output, strlen(output)+1, 3);
return 0;
}
static int duel_leave_sub(struct map_session_data* sd,va_list va) {
int did = va_arg(va, int);
if (sd->duel_invite == did)
sd->duel_invite = 0;
return 0;
}
int duel_leave(
const unsigned int did, struct map_session_data* sd)
{
char output[256];
// " <- Player %s has left duel --"
sprintf(output, msg_txt(375), (unsigned char *)sd->status.name);
clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
duel_list[did].members_count--;
if(duel_list[did].members_count == 0) {
clif_foreachclient(duel_leave_sub, did);
duel_count--;
}
sd->duel_group = 0;
duel_savetime(sd);
clif_set0199(sd->fd, 0);
return 0;
}
int duel_accept(
const unsigned int did, struct map_session_data* sd)
{
char output[256];
duel_list[did].members_count++;
sd->duel_group = sd->duel_invite;
duel_list[did].invites_count--;
sd->duel_invite = 0;
// " -> Player %s has accepted duel --"
sprintf(output, msg_txt(376), (unsigned char *)sd->status.name);
clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
clif_set0199(sd->fd, 1);
//clif_misceffect2(&sd->bl, 159);
return 0;
}
int duel_reject(
const unsigned int did, struct map_session_data* sd)
{
char output[256];
// " -- Player %s has rejected duel --"
sprintf(output, msg_txt(377), (unsigned char *)sd->status.name);
clif_disp_message(&sd->bl, output, strlen(output), DUEL_WOS);
duel_list[did].invites_count--;
sd->duel_invite = 0;
return 0;
}
int pc_split_str(char *str,char **val,int num) int pc_split_str(char *str,char **val,int num)
{ {
int i; int i;

View File

@ -304,6 +304,15 @@ extern int night_timer_tid;
int map_day_timer(int,unsigned int,int,int); // by [yor] int map_day_timer(int,unsigned int,int,int); // by [yor]
int map_night_timer(int,unsigned int,int,int); // by [yor] int map_night_timer(int,unsigned int,int,int); // by [yor]
//Duel functions // [LuzZza]
int duel_create(struct map_session_data* sd, const unsigned int maxpl);
int duel_invite(const unsigned int did, struct map_session_data* sd, struct map_session_data* target_sd);
int duel_accept(const unsigned int did, struct map_session_data* sd);
int duel_reject(const unsigned int did, struct map_session_data* sd);
int duel_leave(const unsigned int did, struct map_session_data* sd);
int duel_showinfo(const unsigned int did, struct map_session_data* sd);
int duel_checktime(struct map_session_data* sd);
int pc_read_motd(void); // [Valaris] int pc_read_motd(void); // [Valaris]
int pc_disguise(struct map_session_data *sd, int class_); int pc_disguise(struct map_session_data *sd, int class_);
#endif #endif

View File

@ -8533,7 +8533,6 @@ int skill_check_condition (struct map_session_data *sd, int skill, int lv, int t
*/ */
int skill_castfix (struct block_list *bl, int skill_id, int skill_lv) int skill_castfix (struct block_list *bl, int skill_id, int skill_lv)
{ {
int castnodex = skill_get_castnodex(skill_id, skill_lv);
int time = skill_get_cast(skill_id, skill_lv); int time = skill_get_cast(skill_id, skill_lv);
struct map_session_data *sd; struct map_session_data *sd;
@ -8541,7 +8540,7 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv)
BL_CAST(BL_PC, bl, sd); BL_CAST(BL_PC, bl, sd);
// calculate base cast time (reduced by dex) // calculate base cast time (reduced by dex)
if (!(castnodex&1)) { // castnodex&~1? wtf. [blackhole89] if (!(skill_get_castnodex(skill_id, skill_lv)&1)) {
int scale = battle_config.castrate_dex_scale - status_get_dex(bl); int scale = battle_config.castrate_dex_scale - status_get_dex(bl);
if (scale > 0) // not instant cast if (scale > 0) // not instant cast
time = time * scale / battle_config.castrate_dex_scale; time = time * scale / battle_config.castrate_dex_scale;
@ -8556,10 +8555,6 @@ int skill_castfix (struct block_list *bl, int skill_id, int skill_lv)
if (battle_config.cast_rate != 100) if (battle_config.cast_rate != 100)
time = time * battle_config.cast_rate / 100; time = time * battle_config.cast_rate / 100;
// calculate cast time reduced by skill bonuses
if (!(castnodex&2))
time = skill_castfix_sc(bl, time);
// return final cast time // return final cast time
return (time > 0) ? time : 0; return (time > 0) ? time : 0;
} }
@ -9743,7 +9738,7 @@ struct skill_unit_group *skill_initunitgroup (struct block_list *src, int count,
sd->skilllv_dance=skilllv; sd->skilllv_dance=skilllv;
} }
sc_start4(src,SC_DANCING,100,skillid,(int)group,skilllv,(i&UF_ENSEMBLE?BCT_SELF:0),skill_get_time(skillid,skilllv)+1000); sc_start4(src,SC_DANCING,100,skillid,(int)group,skilllv,(i&UF_ENSEMBLE?BCT_SELF:0),skill_get_time(skillid,skilllv)+1000);
if (sd && i&UF_ENSEMBLE && if (sd && i&UF_ENSEMBLE && skillid != CG_HERMODE && //Hermod is a encore with a warp!
battle_config.player_skill_partner_check && battle_config.player_skill_partner_check &&
(!battle_config.gm_skilluncond || pc_isGM(sd) < battle_config.gm_skilluncond) (!battle_config.gm_skilluncond || pc_isGM(sd) < battle_config.gm_skilluncond)
) { ) {

View File

@ -164,6 +164,7 @@ int skill_get_delay( int id ,int lv );
int skill_get_walkdelay( int id ,int lv ); int skill_get_walkdelay( int id ,int lv );
int skill_get_time( int id ,int lv ); int skill_get_time( int id ,int lv );
int skill_get_time2( int id ,int lv ); int skill_get_time2( int id ,int lv );
int skill_get_castnodex( int id ,int lv );
int skill_get_castdef( int id ); int skill_get_castdef( int id );
int skill_get_weapontype( int id ); int skill_get_weapontype( int id );
int skill_get_ammotype( int id ); int skill_get_ammotype( int id );

View File

@ -2266,12 +2266,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
if(memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill))) if(memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)))
clif_skillinfoblock(sd); clif_skillinfoblock(sd);
if(b_status.speed != status->speed) if(b_status.speed != status->speed)
{
clif_updatestatus(sd,SP_SPEED); clif_updatestatus(sd,SP_SPEED);
// If speed changes & slaves should inherits master's speed & master have homunc, update it
if (sd->hd && battle_config.slaves_inherit_speed)
status_calc_bl(&sd->hd->bl, SCB_SPEED);
}
if(b_weight != sd->weight) if(b_weight != sd->weight)
clif_updatestatus(sd,SP_WEIGHT); clif_updatestatus(sd,SP_WEIGHT);
if(b_max_weight != sd->max_weight) { if(b_max_weight != sd->max_weight) {

View File

@ -931,6 +931,9 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int
break; break;
} }
if (!(skill_get_castnodex(skill_num, skill_lv)&2))
casttime = skill_castfix_sc(src, casttime);
if( casttime>0 || temp){ if( casttime>0 || temp){
clif_skillcasting(src, src->id, target_id, 0,0, skill_num,casttime); clif_skillcasting(src, src->id, target_id, 0,0, skill_num,casttime);
@ -1047,12 +1050,14 @@ int unit_skilluse_pos2( struct block_list *src, int skill_x, int skill_y, int sk
unit_stop_attack(src); unit_stop_attack(src);
ud->state.skillcastcancel = castcancel; ud->state.skillcastcancel = castcancel;
if (!(skill_get_castnodex(skill_num, skill_lv)&2))
casttime = skill_castfix_sc(src, casttime);
if( casttime>0 ) { if( casttime>0 ) {
unit_stop_walking( src, 1); unit_stop_walking( src, 1);
clif_skillcasting(src, src->id, 0, skill_x,skill_y, skill_num,casttime); clif_skillcasting(src, src->id, 0, skill_x,skill_y, skill_num,casttime);
} } else
if( casttime<=0 )
ud->state.skillcastcancel=0; ud->state.skillcastcancel=0;
ud->canact_tick = tick + casttime + 100; ud->canact_tick = tick + casttime + 100;
@ -1727,6 +1732,13 @@ int unit_free(struct block_list *bl, int clrtype) {
} }
if (sd->followtimer != -1) if (sd->followtimer != -1)
pc_stop_following(sd); pc_stop_following(sd);
// Force exiting from duel and rejecting
// all duel invitations when player quit [LuzZza]
if(sd->duel_group > 0)
duel_leave(sd->duel_group, sd);
if(sd->duel_invite > 0)
duel_reject(sd->duel_invite, sd);
// Notify friends that this char logged out. [Skotlex] // Notify friends that this char logged out. [Skotlex]
clif_foreachclient(clif_friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 0); clif_foreachclient(clif_friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 0);