Updated Convex Mirror to match official behavior (#2506)
* Updated Convex Mirror to match official behavior * Fixes #2498. * When a MVP dies it will only show the respawn time once instead of flooding the chat window. * The Boss icon will now properly display itself when the MVP respawns if the player has already consumed a Convex Mirror. * Converted some integers to constant values. * Made use of the other BOSS_INFO packet messages. * Properly end the status when the player changes maps. * Small cleanups and updated status change documentation. Thanks to @esu1214 and @Lemongrass3110!
This commit is contained in:
parent
76923ac506
commit
951ff55573
@ -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
|
||||
|
@ -16436,25 +16436,37 @@ void clif_parse_Adopt_reply(int fd, struct map_session_data *sd){
|
||||
/// Convex Mirror (ZC_BOSS_INFO).
|
||||
/// 0293 <infoType>.B <x>.L <y>.L <minHours>.W <minMinutes>.W <maxHours>.W <maxMinutes>.W <monster name>.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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user