diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/map/atcommand.c | 171 | ||||
-rw-r--r-- | src/map/atcommand.h | 3 | ||||
-rw-r--r-- | src/map/battle.c | 6 | ||||
-rw-r--r-- | src/map/clif.c | 6 | ||||
-rw-r--r-- | src/map/map.c | 8 | ||||
-rw-r--r-- | src/map/mob.c | 36 | ||||
-rw-r--r-- | src/map/npc.c | 2 | ||||
-rw-r--r-- | src/map/pc.c | 171 | ||||
-rw-r--r-- | src/map/pc.h | 9 | ||||
-rw-r--r-- | src/map/skill.c | 9 | ||||
-rw-r--r-- | src/map/skill.h | 1 | ||||
-rw-r--r-- | src/map/status.c | 5 | ||||
-rw-r--r-- | src/map/unit.c | 20 |
13 files changed, 231 insertions, 216 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c index c644a9468..1f31c6303 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -1004,177 +1004,6 @@ int atcommand_config_read(const char *cfgName) { }
/*==========================================
- * 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
*------------------------------------------
*/
diff --git a/src/map/atcommand.h b/src/map/atcommand.h index 4b8f31185..06bd3664f 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -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_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 msg_config_read(const char *cfgName);
void do_final_msg(void);
diff --git a/src/map/battle.c b/src/map/battle.c index c278a330a..b0a3995cd 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -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) 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; + status_change_end(target, SC_SPIDERWEB, -1); + } + } return damage*ratio/100; } diff --git a/src/map/clif.c b/src/map/clif.c index fdb7537ca..31cdf4889 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -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
//given buffer to prevent intravision affecting the packet as
//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.
if ((sd->special_state.intravision || sd->sc.data[SC_INTRAVISION].timer != -1 )
&& 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)) {
map_addblock(&sd->hd->bl);
clif_spawn(&sd->hd->bl);
-// clif_homunack(sd);
clif_hominfo(sd,sd->hd,1);
clif_hominfo(sd,sd->hd,0); //for some reason, at least older clients want this sent twice
clif_send_homdata(sd,0,0);
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
diff --git a/src/map/map.c b/src/map/map.c index f55a85170..6c00496cd 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -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? idb_remove(charid_db,sd->status.char_id); idb_remove(id_db,sd->bl.id); diff --git a/src/map/mob.c b/src/map/mob.c index f19bd292b..ae742b617 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -159,20 +159,28 @@ int mob_parse_dataset(struct spawn_data *data) { return 0; //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; - if (data->eventname[0] && strlen(data->eventname) <= 2) - { //Portable monster big/small implementation. [Skotlex] - i = atoi(data->eventname); - if (i) { - if (i&2) - data->state.size=1; - else if (i&4) - data->state.size=2; - if (i&8) - data->state.ai=1; - data->eventname[0] = '\0'; //Clear event as it is not used. + if (data->eventname[0]) + { + if(i <= 2) + { //Portable monster big/small implementation. [Skotlex] + i = atoi(data->eventname); + if (i) { + if (i&2) + data->state.size=1; + else if (i&4) + data->state.size=2; + if (i&8) + data->state.ai=1; + 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) @@ -2784,7 +2792,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) } md->skillidx = i; 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. return flag; } else { @@ -2814,7 +2822,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) } md->skillidx = i; 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; return flag; } else { diff --git a/src/map/npc.c b/src/map/npc.c index a5cc3ac09..075cc2fe1 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -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 ||
- 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);
return 1;
}
diff --git a/src/map/pc.c b/src/map/pc.c index 07b387d1f..c68b5b2ff 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -7006,6 +7006,177 @@ void pc_setstand(struct map_session_data *sd){ 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 i; diff --git a/src/map/pc.h b/src/map/pc.h index 7672bf415..d4397db8f 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -304,6 +304,15 @@ extern int night_timer_tid; int map_day_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_disguise(struct map_session_data *sd, int class_);
#endif
diff --git a/src/map/skill.c b/src/map/skill.c index 02c5e1e03..291c2c863 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -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 castnodex = skill_get_castnodex(skill_id, skill_lv); int time = skill_get_cast(skill_id, skill_lv); 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); // 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); if (scale > 0) // not instant cast 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) 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 (time > 0) ? time : 0; } @@ -9743,7 +9738,7 @@ struct skill_unit_group *skill_initunitgroup (struct block_list *src, int count, 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); - 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.gm_skilluncond || pc_isGM(sd) < battle_config.gm_skilluncond) ) { diff --git a/src/map/skill.h b/src/map/skill.h index 3f5884390..50781bfbd 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -164,6 +164,7 @@ int skill_get_delay( int id ,int lv ); int skill_get_walkdelay( int id ,int lv );
int skill_get_time( 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_weapontype( int id );
int skill_get_ammotype( int id );
diff --git a/src/map/status.c b/src/map/status.c index f0b16afed..99b8cfec4 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -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)))
clif_skillinfoblock(sd);
if(b_status.speed != status->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)
clif_updatestatus(sd,SP_WEIGHT);
if(b_max_weight != sd->max_weight) {
diff --git a/src/map/unit.c b/src/map/unit.c index c8e4fb341..2f46a0d9c 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -930,6 +930,9 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int casttime = casttime * ((distance_bl(src,target)-1)/3+1); break; } + + if (!(skill_get_castnodex(skill_num, skill_lv)&2)) + casttime = skill_castfix_sc(src, casttime); if( casttime>0 || temp){ @@ -1047,12 +1050,14 @@ int unit_skilluse_pos2( struct block_list *src, int skill_x, int skill_y, int sk unit_stop_attack(src); ud->state.skillcastcancel = castcancel; + + if (!(skill_get_castnodex(skill_num, skill_lv)&2)) + casttime = skill_castfix_sc(src, casttime); + if( casttime>0 ) { unit_stop_walking( src, 1); clif_skillcasting(src, src->id, 0, skill_x,skill_y, skill_num,casttime); - } - - if( casttime<=0 ) + } else ud->state.skillcastcancel=0; ud->canact_tick = tick + casttime + 100; @@ -1727,7 +1732,14 @@ int unit_free(struct block_list *bl, int clrtype) { } if (sd->followtimer != -1) 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] clif_foreachclient(clif_friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 0); party_send_logout(sd); |