diff --git a/doc/status_change.txt b/doc/status_change.txt index b9758b77ca..512de3b892 100644 --- a/doc/status_change.txt +++ b/doc/status_change.txt @@ -1072,8 +1072,11 @@ SC_ITEMBOOST (SI_ITEMBOOST) val1: +% Drop SC_BOSSMAPINFO (SI_BOSSMAPINFO) - desc: - val1: + desc: Used to display Boss location on minimap + val1: Boss game ID + val2: Used to keep timer message from spamming chat window + val3: + val4: Remaining tick SC_LIFEINSURANCE (SI_LIFEINSURANCE) desc: Remove death pleanlties diff --git a/src/map/clif.cpp b/src/map/clif.cpp index eb5e129a7e..6c22571c70 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -16436,25 +16436,37 @@ void clif_parse_Adopt_reply(int fd, struct map_session_data *sd){ /// Convex Mirror (ZC_BOSS_INFO). /// 0293 .B .L .L .W .W .W .W .51B /// infoType: -/// 0 = No boss on this map (BOSS_INFO_NOT). -/// 1 = Boss is alive (position update) (BOSS_INFO_ALIVE). -/// 2 = Boss is alive (initial announce) (BOSS_INFO_ALIVE_WITHMSG). -/// 3 = Boss is dead (BOSS_INFO_DEAD). -void clif_bossmapinfo(int fd, struct mob_data *md, short flag) +/// BOSS_INFO_NOT = No boss on this map. +/// BOSS_INFO_ALIVE = Boss is alive (position update). +/// BOSS_INFO_ALIVE_WITHMSG = Boss is alive (initial announce). +/// BOSS_INFO_DEAD = Boss is dead. +void clif_bossmapinfo(struct map_session_data *sd, struct mob_data *md, enum e_bossmap_info flag) { + int fd = sd->fd; + WFIFOHEAD(fd,70); memset(WFIFOP(fd,0),0,70); WFIFOW(fd,0) = 0x293; - if( md != NULL ) { - if( md->bl.prev != NULL ) { // Boss on This Map - if( flag ) { - WFIFOB(fd,2) = 1; - WFIFOL(fd,3) = md->bl.x; - WFIFOL(fd,7) = md->bl.y; - } else - WFIFOB(fd,2) = 2; // First Time - } else if (md->spawn_timer != INVALID_TIMER) { // Boss is Dead + switch (flag) { + case BOSS_INFO_NOT: + WFIFOB(fd,2) = BOSS_INFO_NOT; + // No data required + break; + case BOSS_INFO_ALIVE: + WFIFOB(fd,2) = BOSS_INFO_ALIVE; + // Update X/Y + WFIFOL(fd,3) = md->bl.x; + WFIFOL(fd,7) = md->bl.y; + break; + case BOSS_INFO_ALIVE_WITHMSG: + WFIFOB(fd,2) = BOSS_INFO_ALIVE_WITHMSG; + // Current X/Y + WFIFOL(fd,3) = md->bl.x; + WFIFOL(fd,7) = md->bl.y; + break; + case BOSS_INFO_DEAD: + { const struct TimerData * timer_data = get_timer(md->spawn_timer); unsigned int seconds; int hours, minutes; @@ -16464,13 +16476,17 @@ void clif_bossmapinfo(int fd, struct mob_data *md, short flag) seconds = seconds - (60 * 60 * hours); minutes = seconds / 60; - WFIFOB(fd,2) = 3; + WFIFOB(fd,2) = BOSS_INFO_DEAD; + // Add respawn info WFIFOW(fd,11) = hours; // Hours WFIFOW(fd,13) = minutes; // Minutes } - safestrncpy(WFIFOCP(fd,19), md->db->jname, NAME_LENGTH); + break; } + if (md != NULL) + safestrncpy(WFIFOCP(fd,19), md->db->jname, NAME_LENGTH); + WFIFOSET(fd,70); } diff --git a/src/map/clif.h b/src/map/clif.h index 2ff93e0539..396a253507 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -172,6 +172,14 @@ enum e_party_invite_reply { PARTY_REPLY_INVALID_MAPPROPERTY_ME, ///< return=9 : !TODO "Cannot join a party in this map" -> MsgStringTable[1871] (since 20110205) }; +/// Enum for Convex Mirror (SC_BOSSMAPINFO) +enum e_bossmap_info { + BOSS_INFO_NOT = 0, + BOSS_INFO_ALIVE, + BOSS_INFO_ALIVE_WITHMSG, + BOSS_INFO_DEAD, +}; + #define packet_len(cmd) packet_db[cmd].len extern struct s_packet_db packet_db[MAX_PACKET_DB+1]; extern int packet_db_ack[MAX_ACK_FUNC + 1]; @@ -909,7 +917,7 @@ void clif_Auction_message(int fd, unsigned char flag); void clif_Auction_close(int fd, unsigned char flag); void clif_parse_Auction_cancelreg(int fd, struct map_session_data *sd); -void clif_bossmapinfo(int fd, struct mob_data *md, short flag); +void clif_bossmapinfo(struct map_session_data *sd, struct mob_data *md, enum e_bossmap_info flag); void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd); // ADOPTION diff --git a/src/map/status.c b/src/map/status.c index 3328f95d15..b7ecfa78fe 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -9619,14 +9619,14 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty case SC_BOSSMAPINFO: if( sd != NULL ) { struct mob_data *boss_md = map_getmob_boss(bl->m); // Search for Boss on this Map - if( boss_md == NULL || boss_md->bl.prev == NULL ) { // No MVP on this map - MVP is dead - clif_bossmapinfo(sd->fd, boss_md, 1); - return 0; // No need to start SC + + if( boss_md == NULL ) { // No MVP on this map + clif_bossmapinfo(sd, NULL, BOSS_INFO_NOT); + return 0; } val1 = boss_md->bl.id; - if( (val4 = tick/1000) < 1 ) - val4 = 1; tick_time = 1000; // [GodLesZ] tick time + val4 = tick / tick_time; } break; case SC_HIDING: @@ -11505,7 +11505,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty } break; case SC_BOSSMAPINFO: - clif_bossmapinfo(sd->fd, map_id2boss(sce->val1), 0); // First Message + if (sd) + clif_bossmapinfo(sd, map_id2boss(sce->val1), BOSS_INFO_ALIVE_WITHMSG); // First Message break; case SC_MERC_HPUP: status_percent_heal(bl, 100, 0); // Recover Full HP @@ -12827,13 +12828,20 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_BOSSMAPINFO: if( sd && --(sce->val4) >= 0 ) { struct mob_data *boss_md = map_id2boss(sce->val1); - if( boss_md && sd->bl.m == boss_md->bl.m ) { - clif_bossmapinfo(sd->fd, boss_md, 1); // Update X, Y on minimap - if (boss_md->bl.prev != NULL) { - sc_timer_next(5000 + tick, status_change_timer, bl->id, data); + + if (boss_md) { + if (sd->bl.m != boss_md->bl.m) // Not on same map anymore return 0; + else if (boss_md->bl.prev != NULL) { // Boss is alive - Update X, Y on minimap + sce->val2 = 0; + clif_bossmapinfo(sd, boss_md, BOSS_INFO_ALIVE); + } else if (boss_md->spawn_timer != INVALID_TIMER && !sce->val2) { // Boss is dead + sce->val2 = 1; + clif_bossmapinfo(sd, boss_md, BOSS_INFO_DEAD); } } + sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + return 0; } break;