From 1443f47ca63972f737bd9cc0322f77dc416ff2a0 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Sat, 12 Sep 2020 13:13:23 -0300 Subject: This is Hercules v2019.09.22 --- src/map/atcommand.c | 69 +++--- src/map/battle.h | 4 +- src/map/clif.c | 316 ++++++++++++++++++++++++---- src/map/clif.h | 29 ++- src/map/guild.c | 54 ++++- src/map/guild.h | 1 + src/map/homunculus.c | 51 +++-- src/map/homunculus.h | 7 +- src/map/itemdb.c | 467 ++++++++++++++++++++++++++--------------- src/map/itemdb.h | 34 ++- src/map/log.c | 14 +- src/map/map.c | 48 ++--- src/map/map.h | 2 +- src/map/mapdefines.h | 10 +- src/map/messages_main.h | 88 +++++++- src/map/messages_re.h | 88 +++++++- src/map/messages_zero.h | 102 ++++++++- src/map/mob.c | 8 + src/map/npc.c | 13 +- src/map/packets.h | 13 ++ src/map/packets_keys_main.h | 7 +- src/map/packets_keys_zero.h | 7 +- src/map/packets_shuffle_main.h | 39 +++- src/map/packets_shuffle_re.h | 39 +++- src/map/packets_shuffle_zero.h | 35 +++ src/map/packets_struct.h | 116 +++++++++- src/map/pc.c | 136 +++++------- src/map/pc.h | 7 +- src/map/script.c | 110 +++++++++- src/map/script.h | 13 ++ src/map/skill.c | 4 +- src/map/status.c | 112 ++++++++-- src/map/status.h | 7 +- 33 files changed, 1612 insertions(+), 438 deletions(-) (limited to 'src/map') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 22969606d..145a5c95d 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -511,7 +511,7 @@ ACMD(where) return false; } - pl_sd = map->nick2sd(atcmd_player_name); + pl_sd = map->nick2sd(atcmd_player_name, true); if (pl_sd == NULL || strncmp(pl_sd->status.name, atcmd_player_name, NAME_LENGTH) != 0 || (pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) && pc_get_group_level(pl_sd) > pc_get_group_level(sd) && !pc_has_permission(sd, PC_PERM_WHO_DISPLAY_AID)) @@ -548,7 +548,7 @@ ACMD(jumpto) return false; } - if ((pl_sd=map->nick2sd(message)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) { + if ((pl_sd=map->nick2sd(message, true)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -2904,7 +2904,7 @@ ACMD(recall) return false; } - if ((pl_sd=map->nick2sd(message)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) { + if ((pl_sd=map->nick2sd(message, true)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -3229,7 +3229,7 @@ ACMD(kick) return false; } - if ((pl_sd=map->nick2sd(message)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) { + if ((pl_sd=map->nick2sd(message, true)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -3559,7 +3559,7 @@ ACMD(idsearch) safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,77), item_name); // Search results for '%s' (name: id): clif->message(fd, atcmd_output); - match = itemdb->search_name_array(item_array, MAX_SEARCH, item_name, 0); + match = itemdb->search_name_array(item_array, MAX_SEARCH, item_name, IT_SEARCH_NAME_PARTIAL); if (match > MAX_SEARCH) { safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,269), MAX_SEARCH, match); clif->message(fd, atcmd_output); @@ -4364,7 +4364,7 @@ ACMD(nuke) return false; } - if ((pl_sd = map->nick2sd(atcmd_player_name)) != NULL) { + if ((pl_sd = map->nick2sd(atcmd_player_name, true)) != NULL) { if (pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) { // you can kill only lower or same GM level skill->castend_nodamage_id(&pl_sd->bl, &pl_sd->bl, NPC_SELFDESTRUCTION, 99, timer->gettick(), 0); clif->message(fd, msg_fd(fd,109)); // Player has been nuked! @@ -4684,7 +4684,7 @@ ACMD(jail) return false; } - if ((pl_sd = map->nick2sd(atcmd_player_name)) == NULL) { + if ((pl_sd = map->nick2sd(atcmd_player_name, true)) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -4736,7 +4736,7 @@ ACMD(unjail) return false; } - if ((pl_sd = map->nick2sd(atcmd_player_name)) == NULL) { + if ((pl_sd = map->nick2sd(atcmd_player_name, true)) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -4815,7 +4815,7 @@ ACMD(jailfor) return false; } - if ((pl_sd = map->nick2sd(atcmd_player_name)) == NULL) { + if ((pl_sd = map->nick2sd(atcmd_player_name, true)) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -5346,7 +5346,7 @@ ACMD(follow) return true; } - if ((pl_sd = map->nick2sd(message)) == NULL) { + if ((pl_sd = map->nick2sd(message, true)) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -5596,7 +5596,7 @@ ACMD(useskill) if (!strcmp(target,"self")) pl_sd = sd; //quick keyword - else if ((pl_sd = map->nick2sd(target)) == NULL) { + else if ((pl_sd = map->nick2sd(target, true)) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -5664,7 +5664,7 @@ ACMD(skilltree) return false; } - if ( (pl_sd = map->nick2sd(target)) == NULL ) { + if ( (pl_sd = map->nick2sd(target, true)) == NULL ) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -5734,7 +5734,7 @@ ACMD(marry) return false; } - if ((pl_sd = map->nick2sd(player_name)) == NULL) { + if ((pl_sd = map->nick2sd(player_name, true)) == NULL) { clif->message(fd, msg_fd(fd,3)); return false; } @@ -5864,7 +5864,7 @@ ACMD(changegm) return false; } - if ((pl_sd=map->nick2sd(message)) == NULL || pl_sd->status.guild_id != sd->status.guild_id) { + if ((pl_sd=map->nick2sd(message, true)) == NULL || pl_sd->status.guild_id != sd->status.guild_id) { clif->message(fd, msg_fd(fd,1184)); // Target character must be online and be a guild member. return false; } @@ -5885,7 +5885,7 @@ ACMD(changeleader) return false; } - if (party->changeleader(sd, map->nick2sd(message))) + if (party->changeleader(sd, map->nick2sd(message, true))) return true; return false; } @@ -6349,7 +6349,7 @@ ACMD(mobsearch) } if (mob_id == atoi(mob_name)) { strcpy(mob_name,mob->db(mob_id)->jname); // DEFAULT_MOB_JNAME - //strcpy(mob_name,mob_db(mob_id)->name); // DEFAULT_MOB_NAME + //strcpy(mob_name,mob->db(mob_id)->name); // DEFAULT_MOB_NAME } snprintf(atcmd_output, sizeof atcmd_output, msg_fd(fd,1220), mob_name, mapindex_id2name(sd->mapindex)); // Mob Search... %s %s @@ -6651,7 +6651,7 @@ ACMD(trade) return false; } - if ((pl_sd = map->nick2sd(message)) == NULL) { + if ((pl_sd = map->nick2sd(message, true)) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -6695,7 +6695,7 @@ ACMD(unmute) return false; } - if ((pl_sd = map->nick2sd(message)) == NULL) { + if ((pl_sd = map->nick2sd(message, true)) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -6750,6 +6750,18 @@ ACMD(changesex) return true; } +ACMD(changecharsex) +{ + int i; + + pc->resetskill(sd, PCRESETSKILL_CHSEX); + // to avoid any problem with equipment and invalid sex, equipment is unequipped. + for (i=0; iequip_index[i] >= 0) pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); + chrif->changesex(sd, false); + return true; +} + /*================================================ * @mute - Mutes a player for a set amount of time *------------------------------------------------*/ @@ -6763,7 +6775,7 @@ ACMD(mute) return false; } - if ((pl_sd = map->nick2sd(atcmd_player_name)) == NULL) { + if ((pl_sd = map->nick2sd(atcmd_player_name, true)) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -7060,7 +7072,7 @@ ACMD(showmobs) if (mob_id == atoi(mob_name)) { strcpy(mob_name,mob->db(mob_id)->jname); // DEFAULT_MOB_JNAME - //strcpy(mob_name,mob_db(mob_id)->name); // DEFAULT_MOB_NAME + //strcpy(mob_name,mob->db(mob_id)->name); // DEFAULT_MOB_NAME } snprintf(atcmd_output, sizeof atcmd_output, msg_fd(fd,1252), // Mob Search... %s %s @@ -7441,7 +7453,7 @@ ACMD(iteminfo) return false; } if ((item_array[0] = itemdb->exists(atoi(message))) == NULL) - count = itemdb->search_name_array(item_array, MAX_SEARCH, message, 0); + count = itemdb->search_name_array(item_array, MAX_SEARCH, message, IT_SEARCH_NAME_PARTIAL); if (!count) { clif->message(fd, msg_fd(fd,19)); // Invalid item ID or name. @@ -7492,7 +7504,7 @@ ACMD(whodrops) return false; } if ((item_array[0] = itemdb->exists(atoi(message))) == NULL) - count = itemdb->search_name_array(item_array, MAX_SEARCH, message, 0); + count = itemdb->search_name_array(item_array, MAX_SEARCH, message, IT_SEARCH_NAME_PARTIAL); if (!count) { clif->message(fd, msg_fd(fd,19)); // Invalid item ID or name. @@ -7973,7 +7985,7 @@ ACMD(showdelay) ACMD(invite) { unsigned int did = sd->duel_group; - struct map_session_data *target_sd = map->nick2sd(message); + struct map_session_data *target_sd = map->nick2sd(message, true); if (did == 0) { @@ -8046,7 +8058,7 @@ ACMD(duel) } duel->create(sd, maxpl); } else { - struct map_session_data *target_sd = map->nick2sd(message); + struct map_session_data *target_sd = map->nick2sd(message, true); if (target_sd != NULL) { unsigned int newduel; if ((newduel = duel->create(sd, 2)) != -1) { @@ -8191,7 +8203,7 @@ ACMD(clone) return false; } - if ((pl_sd=map->nick2sd(message)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) { + if ((pl_sd=map->nick2sd(message, true)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) { clif->message(fd, msg_fd(fd,3)); // Character not found. return false; } @@ -9309,7 +9321,7 @@ ACMD(channel) return false; } - if (sub4[0] == '\0' || (pl_sd = map->nick2sd(sub4)) == NULL) { + if (sub4[0] == '\0' || (pl_sd = map->nick2sd(sub4, true)) == NULL) { safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1434), sub4);// Player '%s' was not found clif->message(fd, atcmd_output); return false; @@ -9356,7 +9368,7 @@ ACMD(channel) clif->message(fd, atcmd_output); return false; } - if (sub4[0] == '\0' || (pl_sd = map->nick2sd(sub4)) == NULL) { + if (sub4[0] == '\0' || (pl_sd = map->nick2sd(sub4, true)) == NULL) { safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1434), sub4);// Player '%s' was not found clif->message(fd, atcmd_output); return false; @@ -10115,6 +10127,7 @@ static void atcommand_basecommands(void) ACMD_DEF(clearweather), ACMD_DEF(uptime), ACMD_DEF(changesex), + ACMD_DEF(changecharsex), ACMD_DEF(mute), ACMD_DEF(refresh), ACMD_DEF(refreshall), @@ -10450,7 +10463,7 @@ static bool atcommand_exec(const int fd, struct map_session_data *sd, const char return true; } - ssd = map->nick2sd(charname); + ssd = map->nick2sd(charname, true); if (ssd == NULL) { sprintf(output, msg_fd(fd,1389), command); // %s failed. Player not found. clif->message(fd, output); diff --git a/src/map/battle.h b/src/map/battle.h index 779e360bf..4400d37d1 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -103,8 +103,8 @@ enum e_battle_check_target { //New definitions [Skotlex] enum battle_dmg_type { BDT_NORMAL = 0, // Normal attack //BDT_PICKUP = 1, // Pick up item - //BDT_SITDOWN = 2, // Sit down - //BDT_STANDUP = 3, // Stand up + BDT_SITDOWN = 2, // Sit down + BDT_STANDUP = 3, // Stand up BDT_ENDURE = 4, // Damage (endure) BDT_SPLASH = 5, // Splash BDT_SKILL = 6, // Skill diff --git a/src/map/clif.c b/src/map/clif.c index 1c245ed43..f6caa502e 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -4789,9 +4789,9 @@ static void clif_getareachar_unit(struct map_session_data *sd, struct block_list //Modifies the type of damage according to status changes [Skotlex] //Aegis data specifies that: 4 endure against single hit sources, 9 against multi-hit. -static inline int clif_calc_delay(int type, int div, int damage, int delay) +static inline enum battle_dmg_type clif_calc_delay(enum battle_dmg_type type, int div, int damage, int delay) { - return ( delay == 0 && damage > 0 ) ? ( div > 1 ? 9 : 4 ) : type; + return ( delay == 0 && damage > 0 ) ? ( div > 1 ? BDT_MULTIENDURE : BDT_ENDURE ) : type; } /*========================================== @@ -4822,7 +4822,7 @@ static int clif_calc_walkdelay(struct block_list *bl, int delay, int type, int d /// 08c8 .L .L .L .L .L .L .B
.W .B .L (ZC_NOTIFY_ACT2) /// type: @see enum battle_dmg_type /// for BDT_NORMAL: [ damage: total damage, div: amount of hits, damage2: assassin dual-wield damage ] -static int clif_damage(struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type, int64 in_damage2) +static int clif_damage(struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, enum battle_dmg_type type, int64 in_damage2) { struct packet_damage p; struct status_change *sc; @@ -5268,7 +5268,7 @@ static void clif_playerSkillToPacket(struct map_session_data *sd, struct SKILLDA skillData->sp = 0; skillData->range2 = 0; } -#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190814 +#if PACKETVER_RE_NUM >= 20190807 if (newSkill) skillData->level2 = 0; else @@ -5419,7 +5419,7 @@ static void clif_skillinfo(struct map_session_data *sd, int skill_id, int inf) p->sp = 0; p->range2 = 0; } -#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190814 +#if PACKETVER_RE_NUM >= 20190807 p->level2 = skill_lv; #endif if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) @@ -5573,7 +5573,7 @@ static void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, un /// Skill attack effect and damage. /// 0114 .W .L .L .L .L .L .W .W
.W .B (ZC_NOTIFY_SKILL) /// 01de .W .L .L .L .L .L .L .W
.W .B (ZC_NOTIFY_SKILL2) -static int clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int64 in_damage, int div, uint16 skill_id, uint16 skill_lv, int type) +static int clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int64 in_damage, int div, uint16 skill_id, uint16 skill_lv, enum battle_dmg_type type) { unsigned char buf[64]; struct status_change *sc; @@ -5675,7 +5675,7 @@ static int clif_skill_damage(struct block_list *src, struct block_list *dst, int /// Ground skill attack effect and damage (ZC_NOTIFY_SKILL_POSITION). /// 0115 .W .L .L .L .L .L .W .W .W .W
.W .B #if 0 -static int clif_skill_damage2(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int damage, int div, uint16 skill_id, uint16 skill_lv, int type) +static int clif_skill_damage2(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int damage, int div, uint16 skill_id, uint16 skill_lv, enum battle_dmg_type type) { unsigned char buf[64]; struct status_change *sc; @@ -6458,7 +6458,7 @@ static void clif_wis_message(int fd, const char *nick, const char *mes, int mes_ safestrncpy(WFIFOP(fd,28), mes, mes_len + 1); WFIFOSET(fd,WFIFOW(fd,2)); #else - ssd = map->nick2sd(nick); + ssd = map->nick2sd(nick, false); WFIFOHEAD(fd, mes_len + NAME_LENGTH + 9); WFIFOW(fd,0) = 0x97; @@ -8106,6 +8106,54 @@ static void clif_guild_allianceinfo(struct map_session_data *sd) WFIFOSET(fd,WFIFOW(fd,2)); } +static void clif_guild_castlelist(struct map_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814 + nullpo_retv(sd); + + struct guild *g = sd->guild; + if (g == NULL) + return; + + int castle_count = guild->checkcastles(g); + if (castle_count > 0) { + int len = sizeof(struct PACKET_ZC_GUILD_CASTLE_LIST) + castle_count; + struct PACKET_ZC_GUILD_CASTLE_LIST *p = aMalloc(len); + p->packetType = HEADER_ZC_GUILD_CASTLE_LIST; + p->packetLength = len; + + int i = 0; + struct DBIterator *iter = db_iterator(guild->castle_db); + for (struct guild_castle *gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter)) { + if (gc->guild_id == g->guild_id) { + p->castle_list[i] = gc->castle_id; + ++i; + } + } + dbi_destroy(iter); + + clif->send(p, len, &sd->bl, SELF); + aFree(p); + } +#endif +} + +static void clif_guild_castleinfo(struct map_session_data *sd, struct guild_castle *gc) +{ +#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814 + + nullpo_retv(sd); + nullpo_retv(gc); + + struct PACKET_ZC_CASTLE_INFO p = { 0 }; + p.packetType = HEADER_ZC_CASTLE_INFO; + p.castle_id = gc->castle_id; + p.economy = gc->economy; + p.defense = gc->defense; + clif->send(&p, sizeof(p), &sd->bl, SELF); +#endif +} + /// Guild member manager information (ZC_MEMBERMGR_INFO). /// 0154 .W { .L .L .W .W .W .W .W .L .L .L .50B .24B }* /// state: @@ -8689,14 +8737,14 @@ static void clif_emotion(struct block_list *bl, int type) /// 0191 .L .80B static void clif_talkiebox(struct block_list *bl, const char *talkie) { - unsigned char buf[MESSAGE_SIZE+6]; nullpo_retv(bl); nullpo_retv(talkie); + struct PACKET_ZC_TALKBOX_CHATCONTENTS p; - WBUFW(buf,0) = 0x191; - WBUFL(buf,2) = bl->id; - safestrncpy(WBUFP(buf,6),talkie,MESSAGE_SIZE); - clif->send(buf,packet_len(0x191),bl,AREA); + p.PacketType = HEADER_ZC_TALKBOX_CHATCONTENTS; + p.aid = bl->id; + safestrncpy(&p.message[0], talkie, TALKBOX_MESSAGE_SIZE); + clif->send(&p, sizeof(struct PACKET_ZC_TALKBOX_CHATCONTENTS), bl, AREA); } /// Displays wedding effect centered on an object (ZC_CONGRATULATION). @@ -9298,9 +9346,6 @@ static void clif_pcname_ack(int fd, struct block_list *bl) packet.gid = bl->id; const struct map_session_data *ssd = BL_UCCAST(BL_PC, bl); - const struct party_data *p = NULL; - const struct guild *g = NULL; - int ps = -1; if (ssd->fakename[0] != '\0' && ssd->disguise != -1) { packet.packet_id = reqName; @@ -9326,9 +9371,12 @@ static void clif_pcname_ack(int fd, struct block_list *bl) #endif memcpy(packet.name, ssd->status.name, NAME_LENGTH); + const struct party_data *p = NULL; + int ps = -1; if (ssd->status.party_id != 0) { p = party->search(ssd->status.party_id); } + const struct guild *g = NULL; if (ssd->status.guild_id != 0) { if ((g = ssd->guild) != NULL) { int i; @@ -9351,6 +9399,12 @@ static void clif_pcname_ack(int fd, struct block_list *bl) memcpy(packet.guild_name, g->name,NAME_LENGTH); memcpy(packet.position_name, g->position[ps].name, NAME_LENGTH); } + else if (ssd->status.clan_id != 0) { + struct clan *c = clan->search(ssd->status.clan_id); + if (c != 0) { + memcpy(packet.position_name, c->name, NAME_LENGTH); + } + } } clif->send_selforarea(fd, bl, &packet, len); @@ -11590,9 +11644,9 @@ static void clif_parse_WisMessage(int fd, struct map_session_data *sd) } // searching destination character - dstsd = map->nick2sd(target); + dstsd = map->nick2sd(target, false); - if (dstsd == NULL || strcmp(dstsd->status.name, target) != 0) { + if (dstsd == NULL) { // Character not found (or found through partial match). clif->wis_end(sd->fd, 1); return; @@ -12687,7 +12741,7 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin return; } //You can't use Graffiti/TalkieBox AND have a vending open, so this is safe. - safestrncpy(sd->message, RFIFOP(fd,skillmoreinfo), MESSAGE_SIZE); + safestrncpy(sd->message, RFIFOP(fd, skillmoreinfo), TALKBOX_MESSAGE_SIZE); } if( sd->ud.skilltimer != INVALID_TIMER ) @@ -13438,7 +13492,7 @@ static void clif_parse_PartyInvite2(int fd, struct map_session_data *sd) return; } - t_sd = map->nick2sd(name); + t_sd = map->nick2sd(name, true); if(t_sd && t_sd->state.noask) { // @noask [LuzZza] clif->noask_sub(sd, t_sd, 1); @@ -14401,6 +14455,7 @@ static void clif_parse_GuildRequestInfo(int fd, struct map_session_data *sd) case 0: // Basic Information Guild, hostile alliance information clif->guild_basicinfo(sd); clif->guild_allianceinfo(sd); + clif->guild_castlelist(sd); break; case 1: // Members list, list job title clif->guild_positionnamelist(sd); @@ -14711,7 +14766,7 @@ static void clif_parse_GuildInvite2(int fd, struct map_session_data *sd) struct map_session_data *t_sd = NULL; safestrncpy(nick, RFIFOP(fd, 2), NAME_LENGTH); - t_sd = map->nick2sd(nick); + t_sd = map->nick2sd(nick, true); clif_sub_guild_invite(fd, sd, t_sd); } @@ -15268,7 +15323,7 @@ static void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) safestrncpy(item_monster_name, p->str, sizeof(item_monster_name)); - if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, 1)) > 0 ) { + if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, IT_SEARCH_NAME_EXACT)) > 0 ) { for(i = 0; i < count; i++) { if( !item_array[i] ) continue; @@ -15752,7 +15807,7 @@ static void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd) safestrncpy(nick, RFIFOP(fd,2), NAME_LENGTH); - f_sd = map->nick2sd(nick); + f_sd = map->nick2sd(nick, true); // ensure that the request player's friend list is not full ARR_FIND(0, MAX_FRIENDS, i, sd->status.friends[i].char_id == 0); @@ -15978,18 +16033,18 @@ static void clif_ranklist_sub(struct PACKET_ZC_ACK_RANKING_sub *ranks, enum fame if (list[i].id > 0) { const char* name; if (strcmp(list[i].name, "-") == 0 && (name = map->charid2nick(list[i].id)) != NULL) { - strncpy(ranks[i].name, name, NAME_LENGTH); + strncpy(ranks->names[i].name, name, NAME_LENGTH); } else { - strncpy(ranks[i].name, list[i].name, NAME_LENGTH); + strncpy(ranks->names[i].name, list[i].name, NAME_LENGTH); } } else { - strncpy(ranks[i].name, "None", 5); + strncpy(ranks->names[i].name, "None", 5); } - ranks[i].points = list[i].fame; //points + ranks->points[i].points = list[i].fame; //points } for (;i < 10; i++) { // In case the MAX is less than 10. - strncpy(ranks[i].name, "Unavailable", 12); - ranks[i].points = 0; + strncpy(ranks->names[i].name, "Unavailable", 12); + ranks->points[i].points = 0; } #endif } @@ -16038,7 +16093,7 @@ static void clif_ranklist(struct map_session_data *sd, enum fame_list_type type) #if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190703 || PACKETVER_ZERO_NUM >= 20190724 clif->ranklist_sub2(p->chars, p->points, type); #else - clif->ranklist_sub(p->ranks, type); + clif->ranklist_sub(&p->ranks, type); #endif if (pc->famelist_type(sd->job) == type) { @@ -16398,10 +16453,14 @@ static void clif_parse_AutoRevive(int fd, struct map_session_data *sd) { if (pc_istrading(sd) || pc_isvending(sd)) return; + if (!pc_isdead(sd)) return; - int item_position = pc->search_inventory(sd, ITEMID_TOKEN_OF_SIEGFRIED); + if (sd->sc.data[SC_HELLPOWER]) //Cannot res while under the effect of SC_HELLPOWER. + return; + + int item_position = pc->have_item_chain(sd, ECC_SIEGFRIED); int hpsp = 100; if (item_position == INDEX_NOT_FOUND) { @@ -16411,18 +16470,15 @@ static void clif_parse_AutoRevive(int fd, struct map_session_data *sd) return; } - if (sd->sc.data[SC_HELLPOWER]) //Cannot res while under the effect of SC_HELLPOWER. - return; - if (!status->revive(&sd->bl, hpsp, hpsp)) return; if (item_position == INDEX_NOT_FOUND) - status_change_end(&sd->bl,SC_LIGHT_OF_REGENE,INVALID_TIMER); + status_change_end(&sd->bl, SC_LIGHT_OF_REGENE, INVALID_TIMER); else pc->delitem(sd, item_position, 1, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME); - clif->skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION, 4, 1); + clif->skill_nodamage(&sd->bl, &sd->bl, ALL_RESURRECTION, 4, 1); } /// Information about character's status values (ZC_ACK_STATUS_GM). @@ -16483,7 +16539,7 @@ static void clif_parse_Check(int fd, struct map_session_data *sd) safestrncpy(charname, RFIFOP(fd,packet_db[RFIFOW(fd,0)].pos[0]), sizeof(charname)); - if( ( pl_sd = map->nick2sd(charname) ) == NULL || pc_get_group_level(sd) < pc_get_group_level(pl_sd) ) { + if ((pl_sd = map->nick2sd(charname, true)) == NULL || pc_get_group_level(sd) < pc_get_group_level(pl_sd)) { return; } @@ -20608,7 +20664,7 @@ static int clif_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) * * @return clif->calc_walkdelay used in further processing **/ -static int clif_delay_damage(int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type) +static int clif_delay_damage(int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, enum battle_dmg_type type) { struct cdelayed_damage *dd; struct status_change *sc; @@ -23204,6 +23260,181 @@ static void clif_announce_refine_status(struct map_session_data *sd, int item_id #endif } +static void clif_parse_GuildCastleTeleportRequest(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); +static void clif_parse_GuildCastleTeleportRequest(int fd, struct map_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190522 || PACKETVER_ZERO_NUM >= 20190515 + const struct PACKET_CZ_CASTLE_TELEPORT_REQUEST *p = RFIFO2PTR(fd); + struct guild *g = sd->guild; + + if (g == NULL) + return; + + struct guild_castle *gc = guild->castle_search(p->castle_id); + if (gc == NULL) + return; + if (gc->enable_client_warp == false) + return; + if (gc->guild_id != g->guild_id) + return; + + if (map->list[sd->bl.m].flag.gvg_castle == 1) + return; + + int zeny = gc->client_warp.zeny; + if (gc->siege_type == SIEGE_TYPE_FE && map->agit_flag == 1) { + zeny = gc->client_warp.zeny_siege; + } else if (gc->siege_type == SIEGE_TYPE_SE && map->agit2_flag == 1) { + zeny = gc->client_warp.zeny_siege; + } else if (gc->siege_type == SIEGE_TYPE_TE) { + clif->guild_castleteleport_res(sd, SIEGE_TP_INVALID_MODE); + return; + } + + if (sd->status.zeny < zeny) { + clif->guild_castleteleport_res(sd, SIEGE_TP_NOT_ENOUGH_ZENY); + return; + } + sd->status.zeny -= zeny; + clif->updatestatus(sd, SP_ZENY); + pc->setpos(sd, gc->mapindex, gc->client_warp.x, gc->client_warp.y, CLR_OUTSIGHT); +#endif +} + +static void clif_guild_castleteleport_res(struct map_session_data *sd, enum siege_teleport_result result) +{ +#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814 + + nullpo_retv(sd); + + struct PACKET_ZC_CASTLE_TELEPORT_RESPONSE p = { 0 }; + p.packetType = HEADER_ZC_CASTLE_TELEPORT_RESPONSE; + p.result = (int16)result; + clif->send(&p, sizeof(p), &sd->bl, SELF); +#endif +} +static void clif_parse_GuildCastleInfoRequest(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); +static void clif_parse_GuildCastleInfoRequest(int fd, struct map_session_data *sd) +{ +#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190522 || PACKETVER_ZERO_NUM >= 20190515 + const struct PACKET_CZ_CASTLE_INFO_REQUEST *p = RFIFO2PTR(fd); + struct guild *g = sd->guild; + + if (g == NULL) + return; + + struct guild_castle *gc = guild->castle_search(p->castle_id); + if (gc == NULL) + return; + if (gc->guild_id != g->guild_id) + return; + clif->guild_castleinfo(sd, gc); +#endif +} + +static bool clif_lapineDdukDdak_open(struct map_session_data *sd, int item_id) +{ +#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) + nullpo_retr(false, sd); + nullpo_retr(false, itemdb->exists(item_id)); + struct PACKET_ZC_LAPINEDDUKDDAK_OPEN p; + + p.packetType = HEADER_ZC_LAPINEDDUKDDAK_OPEN; + p.itemId = item_id; + clif->send(&p, sizeof(p), &sd->bl, SELF); + + sd->state.lapine_ui = 1; + return true; +#else + return false; +#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) +} + +static bool clif_lapineDdukDdak_result(struct map_session_data *sd, enum lapineddukddak_result result) +{ +#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) + nullpo_retr(false, sd); + struct PACKET_ZC_LAPINEDDUKDDAK_RESULT p; + + p.packetType = HEADER_ZC_LAPINEDDUKDDAK_RESULT; + p.result = result; + clif->send(&p, sizeof(p), &sd->bl, SELF); + return true; +#else + return false; +#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) +} + +static void clif_parse_lapineDdukDdak_ack(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); +static void clif_parse_lapineDdukDdak_ack(int fd, struct map_session_data *sd) +{ +#if PACKETVER >= 20160302 + const struct PACKET_CZ_LAPINEDDUKDDAK_ACK *p = RP2PTR(fd); + struct item_data *it = itemdb->exists(p->itemId); + + if (it == NULL || it->lapineddukddak == NULL) + return; + if (pc_cant_act(sd)) + return; + if (pc->search_inventory(sd, it->nameid) == INDEX_NOT_FOUND) + return; + + if (((p->packetLength - sizeof(struct PACKET_CZ_LAPINEDDUKDDAK_ACK)) / sizeof(struct PACKET_CZ_LAPINEDDUKDDAK_ACK_sub)) != it->lapineddukddak->NeedCount) + return; + + for (int i = 0; i < it->lapineddukddak->NeedCount; ++i) { + int16 idx = p->items[i].index - 2; + Assert_retv(idx >= 0 && idx < sd->status.inventorySize); + + struct item itr = sd->status.inventory[idx]; + int j = 0; + for (j = 0; j < VECTOR_LENGTH(it->lapineddukddak->SourceItems); ++j) { + if (itr.nameid == VECTOR_INDEX(it->lapineddukddak->SourceItems, j).id) { + // Validate that the amount sent in the packet is matching the database + if (p->items[i].count != VECTOR_INDEX(it->lapineddukddak->SourceItems, j).amount) { + clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_INSUFFICIENT_AMOUNT); + return; + } + + // Validate that the player have enough of the item + if (itr.amount < VECTOR_INDEX(it->lapineddukddak->SourceItems, j).amount) { + clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_INSUFFICIENT_AMOUNT); + return; + } + + // Validate refine rate requirement + if ((itemdb_type(itr.nameid) == IT_ARMOR || itemdb_type(itr.nameid) == IT_WEAPON) + && (itr.refine < it->lapineddukddak->NeedRefineMin || itr.refine > it->lapineddukddak->NeedRefineMax)) + return; + + // All requirements are met, move to the next one + break; + } + } + // The item is not in sources list + if (j == VECTOR_LENGTH(it->lapineddukddak->SourceItems)) { + clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_INVALID_ITEM); + return; + } + } + + for (int i = 0; i < it->lapineddukddak->NeedCount; ++i) + pc->delitem(sd, p->items[i].index - 2, p->items[i].count, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT); + if (it->lapineddukddak->script != NULL) + script->run_item_lapineddukddak_script(sd, it, npc->fake_nd->bl.id); + clif->lapineDdukDdak_result(sd, LAPINEDDKUKDDAK_SUCCESS); + return; +#endif // PACKETVER >= 20160302 +} + +static void clif_parse_lapineDdukDdak_close(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); +static void clif_parse_lapineDdukDdak_close(int fd, struct map_session_data *sd) +{ +#if PACKETVER >= 20160504 + sd->state.lapine_ui = 0; +#endif // PACKETVER >= 20160504 +} + /*========================================== * Main client packet processing function *------------------------------------------*/ @@ -23888,6 +24119,8 @@ void clif_defaults(void) clif->guild_masterormember = clif_guild_masterormember; clif->guild_basicinfo = clif_guild_basicinfo; clif->guild_allianceinfo = clif_guild_allianceinfo; + clif->guild_castlelist = clif_guild_castlelist; + clif->guild_castleinfo = clif_guild_castleinfo; clif->guild_memberlist = clif_guild_memberlist; clif->guild_skillinfo = clif_guild_skillinfo; clif->guild_send_onlineinfo = clif_guild_send_onlineinfo; @@ -24429,4 +24662,11 @@ void clif_defaults(void) clif->pRefineryUIClose = clif_parse_RefineryUIClose; clif->pRefineryUIRefine = clif_parse_RefineryUIRefine; clif->announce_refine_status = clif_announce_refine_status; + clif->pGuildCastleTeleportRequest = clif_parse_GuildCastleTeleportRequest; + clif->pGuildCastleInfoRequest = clif_parse_GuildCastleInfoRequest; + clif->guild_castleteleport_res = clif_guild_castleteleport_res; + clif->lapineDdukDdak_open = clif_lapineDdukDdak_open; + clif->lapineDdukDdak_result = clif_lapineDdukDdak_result; + clif->plapineDdukDdak_ack = clif_parse_lapineDdukDdak_ack; + clif->plapineDdukDdak_close = clif_parse_lapineDdukDdak_close; } diff --git a/src/map/clif.h b/src/map/clif.h index 07d2ef4a8..4bc3abdeb 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -59,6 +59,7 @@ struct s_refine_requirement; struct PACKET_ZC_ACK_RANKING_sub; struct SKILLDATA; +enum battle_dmg_type; enum clif_messages; enum rodex_add_item; enum rodex_get_zeny; @@ -632,6 +633,13 @@ enum inventory_type { INVTYPE_GUILD_STORAGE = 3, }; +/** Guild Teleport Results */ +enum siege_teleport_result { + SIEGE_TP_SUCCESS = 0x0, + SIEGE_TP_NOT_ENOUGH_ZENY = 0x1, + SIEGE_TP_INVALID_MODE = 0x2 +}; + /** * Structures **/ @@ -719,6 +727,12 @@ enum market_buy_result { }; #endif +enum lapineddukddak_result { + LAPINEDDKUKDDAK_SUCCESS = 0, + LAPINEDDKUKDDAK_INSUFFICIENT_AMOUNT = 5, + LAPINEDDKUKDDAK_INVALID_ITEM = 7, +}; + /** * Clif.c Interface **/ @@ -861,7 +875,7 @@ struct clif_interface { void (*scriptclear) (struct map_session_data *sd, int npcid); /* client-user-interface-related */ void (*viewpoint) (struct map_session_data *sd, int npc_id, int type, int x, int y, int id, int color); - int (*damage) (struct block_list* src, struct block_list* dst, int sdelay, int ddelay, int64 damage, short div, unsigned char type, int64 damage2); + int (*damage) (struct block_list* src, struct block_list* dst, int sdelay, int ddelay, int64 damage, short div, enum battle_dmg_type type, int64 damage2); void (*sitting) (struct block_list* bl); void (*standing) (struct block_list* bl); void (*arrow_create_list) (struct map_session_data *sd); @@ -987,7 +1001,7 @@ struct clif_interface { void (*wedding_effect) (struct block_list *bl); void (*divorced) (struct map_session_data* sd, const char* name); void (*callpartner) (struct map_session_data *sd); - int (*skill_damage) (struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int64 damage, int div, uint16 skill_id, uint16 skill_lv, int type); + int (*skill_damage) (struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int64 damage, int div, uint16 skill_id, uint16 skill_lv, enum battle_dmg_type type); int (*skill_nodamage) (struct block_list *src,struct block_list *dst,uint16 skill_id,int heal,int fail); void (*skill_poseffect) (struct block_list *src, uint16 skill_id, int val, int x, int y, int64 tick); void (*skill_estimation) (struct map_session_data *sd,struct block_list *dst); @@ -1113,6 +1127,8 @@ struct clif_interface { void (*guild_masterormember) (struct map_session_data *sd); void (*guild_basicinfo) (struct map_session_data *sd); void (*guild_allianceinfo) (struct map_session_data *sd); + void (*guild_castlelist) (struct map_session_data *sd); + void (*guild_castleinfo) (struct map_session_data *sd, struct guild_castle *gc); void (*guild_memberlist) (struct map_session_data *sd); void (*guild_skillinfo) (struct map_session_data* sd); void (*guild_send_onlineinfo) (struct map_session_data *sd); //[LuzZza] @@ -1282,7 +1298,7 @@ struct clif_interface { /* */ void (*notify_bounditem) (struct map_session_data *sd, unsigned short index); /* */ - int (*delay_damage) (int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type); + int (*delay_damage) (int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, enum battle_dmg_type type); int (*delay_damage_sub) (int tid, int64 tick, int id, intptr_t data); /* NPC Market */ void (*npc_market_open) (struct map_session_data *sd, struct npc_data *nd); @@ -1646,6 +1662,13 @@ struct clif_interface { void (*pRefineryUIClose) (int fd, struct map_session_data *sd); void (*pRefineryUIRefine) (int fd, struct map_session_data *sd); void (*announce_refine_status) (struct map_session_data *sd, int item_id, int refine_level, bool success, enum send_target target); + void (*pGuildCastleTeleportRequest) (int fd, struct map_session_data *sd); + void (*pGuildCastleInfoRequest) (int fd, struct map_session_data *sd); + void (*guild_castleteleport_res) (struct map_session_data *sd, enum siege_teleport_result result); + bool (*lapineDdukDdak_open) (struct map_session_data *sd, int item_id); + bool (*lapineDdukDdak_result) (struct map_session_data *sd, enum lapineddukddak_result result); + void (*plapineDdukDdak_ack) (int fd, struct map_session_data *sd); + void (*plapineDdukDdak_close) (int fd, struct map_session_data *sd); }; #ifdef HERCULES_CORE diff --git a/src/map/guild.c b/src/map/guild.c index 415a46db5..2faf60e2b 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -169,7 +169,7 @@ static bool guild_read_castledb_libconfig(void) } libconfig->destroy(&castle_conf); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, config_filename); + ShowStatus("Done reading '"CL_WHITE"%u"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", db_size(guild->castle_db), config_filename); return true; } @@ -217,10 +217,59 @@ static bool guild_read_castledb_libconfig_sub(struct config_setting_t *it, int i } safestrncpy(gc->castle_event, name, sizeof(gc->castle_event)); + if (itemdb->lookup_const(it, "SiegeType", &i32) && (i32 >= SIEGE_TYPE_MAX || i32 < 0)) { + ShowWarning("guild_read_castledb_libconfig_sub: Invalid SiegeType in \"%s\", entry #%d, defaulting to SIEGE_TYPE_FE.\n", source, idx); + gc->siege_type = SIEGE_TYPE_FE; + } else { + gc->siege_type = i32; + } + + libconfig->setting_lookup_bool_real(it, "EnableClientWarp", &gc->enable_client_warp); + if (gc->enable_client_warp == true) { + struct config_setting_t *wd = libconfig->setting_get_member(it, "ClientWarp"); + guild->read_castledb_libconfig_sub_warp(wd, source, gc); + } idb_put(guild->castle_db, gc->castle_id, gc); return true; } +static bool guild_read_castledb_libconfig_sub_warp(struct config_setting_t *wd, const char *source, struct guild_castle *gc) +{ + nullpo_retr(false, wd); + nullpo_retr(false, gc); + nullpo_retr(false, source); + + int64 i64 = 0; + struct config_setting_t *it = libconfig->setting_get_member(wd, "Position"); + if (config_setting_is_list(it)) { + int m = map->mapindex2mapid(gc->mapindex); + + gc->client_warp.x = libconfig->setting_get_int_elem(it, 0); + gc->client_warp.y = libconfig->setting_get_int_elem(it, 1); + if (gc->client_warp.x < 0 || gc->client_warp.x >= map->list[m].xs || gc->client_warp.y < 0 || gc->client_warp.y >= map->list[m].ys) { + ShowWarning("guild_read_castledb_libconfig_sub_warp: Invalid Position in \"%s\", for castle (%d).\n", source, gc->castle_id); + return false; + } + } else { + ShowWarning("guild_read_castledb_libconfig_sub_warp: Invalid format for Position in \"%s\", for castle (%d).\n", source, gc->castle_id); + return false; + } + + if (libconfig->setting_lookup_int64(wd, "ZenyCost", &i64)) { + if (i64 > MAX_ZENY) { + ShowWarning("guild_read_castledb_libconfig_sub_warp: ZenyCost is too big in \"%s\", for castle (%d), capping to MAX_ZENY.\n", source, gc->castle_id); + } + gc->client_warp.zeny = cap_value((int)i64, 0, MAX_ZENY); + } + if (libconfig->setting_lookup_int64(wd, "ZenyCostSiegeTime", &i64)) { + if (i64 > MAX_ZENY) { + ShowWarning("guild_read_castledb_libconfig_sub_warp: ZenyCostSiegeTime is too big in \"%s\", for castle (%d), capping to MAX_ZENY.\n", source, gc->castle_id); + } + gc->client_warp.zeny_siege = cap_value((int)i64, 0, MAX_ZENY); + } + return true; +} + /// lookup: guild id -> guild* static struct guild *guild_search(int guild_id) { @@ -605,7 +654,7 @@ static int guild_recv_info(const struct guild *sg) before=*sg; //Perform the check on the user because the first load guild->check_member(sg); - if ((sd = map->nick2sd(sg->master)) != NULL) { + if ((sd = map->nick2sd(sg->master, false)) != NULL) { //If the guild master is online the first time the guild_info is received, //that means he was the first to join, so apply guild skill blocking here. if( battle_config.guild_skill_relog_delay == 1) @@ -2497,6 +2546,7 @@ void guild_defaults(void) guild->read_guildskill_tree_db = guild_read_guildskill_tree_db; guild->read_castledb_libconfig = guild_read_castledb_libconfig; guild->read_castledb_libconfig_sub = guild_read_castledb_libconfig_sub; + guild->read_castledb_libconfig_sub_warp = guild_read_castledb_libconfig_sub_warp; guild->payexp_timer_sub = guild_payexp_timer_sub; guild->send_xy_timer_sub = guild_send_xy_timer_sub; guild->send_xy_timer = guild_send_xy_timer; diff --git a/src/map/guild.h b/src/map/guild.h index d0374103f..41f52711d 100644 --- a/src/map/guild.h +++ b/src/map/guild.h @@ -166,6 +166,7 @@ struct guild_interface { bool (*read_guildskill_tree_db) (char* split[], int columns, int current); bool (*read_castledb_libconfig) (void); bool (*read_castledb_libconfig_sub) (struct config_setting_t *it, int idx, const char *source); + bool (*read_castledb_libconfig_sub_warp) (struct config_setting_t *wd, const char *source, struct guild_castle *gc); int (*payexp_timer_sub) (union DBKey key, struct DBData *data, va_list ap); int (*send_xy_timer_sub) (union DBKey key, struct DBData *data, va_list ap); int (*send_xy_timer) (int tid, int64 tick, int id, intptr_t data); diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 31744f479..43cb8d84b 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -172,7 +172,7 @@ static int homunculus_dead(struct homun_data *hd) } //Vaporize a character's homun. If flag, HP needs to be 80% or above. -static int homunculus_vaporize(struct map_session_data *sd, enum homun_state flag) +static int homunculus_vaporize(struct map_session_data *sd, enum homun_state state, bool force) { struct homun_data *hd; @@ -185,13 +185,13 @@ static int homunculus_vaporize(struct map_session_data *sd, enum homun_state fla if (status->isdead(&hd->bl)) return 0; //Can't vaporize a dead homun. - if (flag == HOM_ST_REST && get_percentage(hd->battle_status.hp, hd->battle_status.max_hp) < 80) + if (!force && get_percentage(hd->battle_status.hp, hd->battle_status.max_hp) < 80) return 0; hd->regen.state.block = 3; //Block regen while vaporized. //Delete timers when vaporized. homun->hunger_timer_delete(hd); - hd->homunculus.vaporize = flag; + hd->homunculus.vaporize = state; if(battle_config.hom_setting&0x40) memset(hd->blockskill, 0, sizeof(hd->blockskill)); clif->hominfo(sd, sd->hd, 0); @@ -258,7 +258,7 @@ static int homunculus_calc_skilltree(struct homun_data *hd, int flag_evolve) for( i = 0; i < MAX_SKILL_TREE && ( id = homun->dbs->skill_tree[c][i].id ) > 0; i++ ) { if( hd->homunculus.hskill[ id - HM_SKILLBASE ].id ) continue; //Skill already known. - j = ( flag_evolve ) ? 10 : hd->homunculus.intimacy; + j = ( flag_evolve ) ? 1000 : hd->homunculus.intimacy; if( j < homun->dbs->skill_tree[c][i].intimacylv ) continue; if(!battle_config.skillfree) { @@ -525,6 +525,21 @@ static bool homunculus_mutate(struct homun_data *hd, int homun_id) return true; } +static int homunculus_gainexp_real(struct homun_data *hd, unsigned int exp) +{ + nullpo_ret(hd); + nullpo_ret(hd->master); + + hd->homunculus.exp += exp; + + if (hd->master->state.showexp && hd->exp_next > 0) { + char output[256]; + sprintf(output, msg_fd(hd->master->fd, 449), exp, ((float)exp / (float)hd->exp_next * (float)100)); + clif_disp_onlyself(hd->master, output); + } + return 1; +} + static int homunculus_gainexp(struct homun_data *hd, unsigned int exp) { enum homun_type htype; @@ -550,16 +565,10 @@ static int homunculus_gainexp(struct homun_data *hd, unsigned int exp) break; } - hd->homunculus.exp += exp; - - if (hd->master->state.showexp && hd->exp_next > 0) { - char output[256]; - sprintf(output, "Homunculus Experience Gained Base:%u (%.2f%%)", exp, ((float)exp / (float)hd->exp_next * (float)100)); - clif_disp_onlyself(hd->master, output); - } + homun->gainexp_real(hd, exp); - if(hd->homunculus.exp < hd->exp_next) { - clif->hominfo(hd->master,hd,0); + if (hd->homunculus.exp < hd->exp_next) { + clif->hominfo(hd->master, hd, 0); return 0; } @@ -826,7 +835,7 @@ static int homunculus_db_search(int key, int type) * @param hom The homunculus source data. * @retval false in case of errors. */ -static bool homunculus_create(struct map_session_data *sd, const struct s_homunculus *hom) +static bool homunculus_create(struct map_session_data *sd, const struct s_homunculus *hom, bool is_new) { struct homun_data *hd; int i = 0; @@ -870,7 +879,9 @@ static bool homunculus_create(struct map_session_data *sd, const struct s_homunc map->addiddb(&hd->bl); status_calc_homunculus(hd,SCO_FIRST); - status_percent_heal(&hd->bl, 100, 100); + if (is_new) { + status_percent_heal(&hd->bl, 100, 100); + } hd->hungry_timer = INVALID_TIMER; return true; @@ -927,6 +938,7 @@ static bool homunculus_recv_data(int account_id, const struct s_homunculus *sh, { struct map_session_data *sd; struct homun_data *hd; + bool is_new = false; nullpo_retr(false, sh); @@ -942,15 +954,17 @@ static bool homunculus_recv_data(int account_id, const struct s_homunculus *sh, if (sd->status.char_id != sh->char_id && sd->status.hom_id != sh->hom_id) return false; - if (sd->status.hom_id == 0) //Hom just created. + if (sd->status.hom_id == 0) { // Hom just created. sd->status.hom_id = sh->hom_id; + is_new = true; + } if (sd->hd != NULL) { //uh? Overwrite the data. memcpy(&sd->hd->homunculus, sh, sizeof sd->hd->homunculus); sd->hd->homunculus.char_id = sd->status.char_id; // Correct char id if necessary. } else { - homun->create(sd, sh); + homun->create(sd, sh, is_new); } hd = sd->hd; @@ -1312,7 +1326,7 @@ static bool homunculus_read_skill_db_sub(char *split[], int columns, int current homun->dbs->skill_tree[classid][j].need[k].lv = atoi(split[3+k*2+minJobLevelPresent+1]); } - homun->dbs->skill_tree[classid][j].intimacylv = atoi(split[13+minJobLevelPresent]); + homun->dbs->skill_tree[classid][j].intimacylv = atoi(split[13+minJobLevelPresent]) * 100; return true; } @@ -1439,6 +1453,7 @@ void homunculus_defaults(void) homun->evolve = homunculus_evolve; homun->mutate = homunculus_mutate; homun->gainexp = homunculus_gainexp; + homun->gainexp_real = homunculus_gainexp_real; homun->add_intimacy = homunculus_add_intimacy; homun->consume_intimacy = homunculus_consume_intimacy; homun->healed = homunculus_healed; diff --git a/src/map/homunculus.h b/src/map/homunculus.h index 745c7cd84..2914a26cc 100644 --- a/src/map/homunculus.h +++ b/src/map/homunculus.h @@ -133,7 +133,7 @@ struct homun_skill_tree_entry { short id; unsigned char max; unsigned char joblv; - short intimacylv; + int intimacylv; struct { short id; unsigned char lv; @@ -167,7 +167,7 @@ struct homunculus_interface { enum homun_type (*class2type) (int class_); void (*damaged) (struct homun_data *hd); int (*dead) (struct homun_data *hd); - int (*vaporize) (struct map_session_data *sd, enum homun_state flag); + int (*vaporize) (struct map_session_data *sd, enum homun_state state, bool force); int (*delete) (struct homun_data *hd, int emote); int (*checkskill) (struct homun_data *hd, uint16 skill_id); int (*calc_skilltree) (struct homun_data *hd, int flag_evolve); @@ -178,6 +178,7 @@ struct homunculus_interface { bool (*evolve) (struct homun_data *hd); bool (*mutate) (struct homun_data *hd, int homun_id); int (*gainexp) (struct homun_data *hd, unsigned int exp); + int (*gainexp_real) (struct homun_data *hd, unsigned int exp); unsigned int (*add_intimacy) (struct homun_data * hd, unsigned int value); unsigned int (*consume_intimacy) (struct homun_data *hd, unsigned int value); void (*healed) (struct homun_data *hd); @@ -189,7 +190,7 @@ struct homunculus_interface { int (*change_name) (struct map_session_data *sd, const char *name); bool (*change_name_ack) (struct map_session_data *sd, const char *name, int flag); int (*db_search) (int key,int type); - bool (*create) (struct map_session_data *sd, const struct s_homunculus *hom); + bool (*create) (struct map_session_data *sd, const struct s_homunculus *hom, bool is_new); void (*init_timers) (struct homun_data * hd); bool (*call) (struct map_session_data *sd); bool (*recv_data) (int account_id, const struct s_homunculus *sh, int flag); diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 5c56794d8..a97325e57 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -117,73 +117,105 @@ static struct item_data *itemdb_name2id(const char *str) */ static int itemdb_searchname_array_sub(union DBKey key, struct DBData data, va_list ap) { - struct item_data *item = DB->data2ptr(&data); - char *str; - str=va_arg(ap,char *); + struct item_data *itd = DB->data2ptr(&data); + const char *str = va_arg(ap, const char *); + enum item_name_search_flag flag = va_arg(ap, enum item_name_search_flag); + nullpo_ret(str); - if (item == &itemdb->dummy) + + if (itd == &itemdb->dummy) return 1; //Invalid item. - if(stristr(item->jname,str)) - return 0; - if(battle_config.case_sensitive_aegisnames && strstr(item->name,str)) - return 0; - if(!battle_config.case_sensitive_aegisnames && stristr(item->name,str)) + + if ( + (flag == IT_SEARCH_NAME_PARTIAL + && (stristr(itd->jname, str) != NULL + || (battle_config.case_sensitive_aegisnames && strstr(itd->name, str)) + || (!battle_config.case_sensitive_aegisnames && stristr(itd->name, str)) + )) + || (flag == IT_SEARCH_NAME_EXACT + && (strcmp(itd->jname, str) == 0 + || (battle_config.case_sensitive_aegisnames && strcmp(itd->name, str) == 0) + || (!battle_config.case_sensitive_aegisnames && strcasecmp(itd->name, str) == 0) + )) + ) { + return 0; - return strcmpi(item->jname,str); + } else { + return 1; + } } -/*========================================== - * Founds up to N matches. Returns number of matches [Skotlex] - * search flag : - * 0 - approximate match - * 1 - exact match - *------------------------------------------*/ -static int itemdb_searchname_array(struct item_data **data, int size, const char *str, int flag) +/** + * Finds up to passed size matches + * @param data array of struct item_data for returning the results in + * @param size size of the array + * @param str string used in this search + * @param flag search mode refer to enum item_name_search_flag for possible values + * @return returns all found matches in the database which could be bigger than size + **/ +static int itemdb_searchname_array(struct item_data **data, const int size, const char *str, enum item_name_search_flag flag) { - struct item_data* item; - int i; - int count=0; - nullpo_ret(data); nullpo_ret(str); - // Search in the array - for( i = 0; i < ARRAYLENGTH(itemdb->array); ++i ) - { - item = itemdb->array[i]; - if( item == NULL ) + Assert_ret(flag >= IT_SEARCH_NAME_PARTIAL && flag < IT_SEARCH_NAME_MAX); + Assert_ret(size > 0); + + int + results_count = 0, + length = 0; + + // Search in array + for (int i = 0; i < ARRAYLENGTH(itemdb->array); ++i) { + struct item_data *itd = itemdb->array[i]; + + if (itd == NULL) continue; - if( - (!flag - && (stristr(item->jname,str) - || (battle_config.case_sensitive_aegisnames && strstr(item->name,str)) - || (!battle_config.case_sensitive_aegisnames && stristr(item->name,str)) - )) - || (flag - && (strcmp(item->jname,str) == 0 - || (battle_config.case_sensitive_aegisnames && strcmp(item->name,str) == 0) - || (!battle_config.case_sensitive_aegisnames && strcasecmp(item->name,str) == 0) - )) - ) { - if( count < size ) - data[count] = item; - ++count; + if ( + (flag == IT_SEARCH_NAME_PARTIAL + && (stristr(itd->jname, str) != NULL + || (battle_config.case_sensitive_aegisnames && strstr(itd->name, str)) + || (!battle_config.case_sensitive_aegisnames && stristr(itd->name, str)) + )) + || (flag == IT_SEARCH_NAME_EXACT + && (strcmp(itd->jname, str) == 0 + || (battle_config.case_sensitive_aegisnames && strcmp(itd->name, str) == 0) + || (!battle_config.case_sensitive_aegisnames && strcasecmp(itd->name, str) == 0) + )) + ) { + if (length < size) { + data[length] = itd; + ++length; + } + + ++results_count; } } - // search in the db - if( count < size ) - { - struct DBData *db_data[MAX_SEARCH]; - int db_count = 0; - size -= count; - db_count = itemdb->other->getall(itemdb->other, (struct DBData**)&db_data, size, itemdb->searchname_array_sub, str); - for (i = 0; i < db_count; i++) - data[count++] = DB->data2ptr(db_data[i]); - count += db_count; + // Search in dbmap + int dbmap_size = size - length; + if (dbmap_size > 0) { + struct DBData **dbmap_data = NULL; + int dbmap_count = 0; + CREATE(dbmap_data, struct DBData *, dbmap_size); + + dbmap_count = itemdb->other->getall(itemdb->other, dbmap_data, dbmap_size, itemdb->searchname_array_sub, str, flag); + dbmap_size = min(dbmap_count, dbmap_size); + + for (int i = 0; i < dbmap_size; ++i) { + data[length] = DB->data2ptr(dbmap_data[i]); + ++length; + } + + results_count += dbmap_count; + aFree(dbmap_data); + } else { // We got all matches we can return, so we only need to count now. + results_count += itemdb->other->getall(itemdb->other, NULL, 0, itemdb->searchname_array_sub, str, flag); } - return count; + + return results_count; } + /* [Ind/Hercules] */ static int itemdb_chain_item(unsigned short chain_id, int *rate) { @@ -1523,141 +1555,107 @@ static void itemdb_read_chains(void) else itemdb->chain_cache[ECC_ORE] = i; + if (!script->get_constant("ITMCHAIN_SIEGFRIED", &i)) + ShowWarning("itemdb_read_chains: failed to find 'ITMCHAIN_SIEGFRIED' chain to link to cache!\n"); + else + itemdb->chain_cache[ECC_SIEGFRIED] = i; + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename); } -/** - * @return: amount of retrieved entries. - **/ -static int itemdb_combo_split_atoi(char *str, int *val) +static bool itemdb_read_combodb_libconfig(void) { - int i; - - nullpo_ret(val); + struct config_t combo_conf; + char filepath[256]; + safesnprintf(filepath, sizeof(filepath), "%s/%s/%s", map->db_path, DBPATH, "item_combo_db.conf"); - for (i=0; iload_file(&combo_conf, filepath) == CONFIG_FALSE) { + ShowError("itemdb_read_combodb_libconfig: can't read %s\n", filepath); + return false; + } - val[i] = atoi(str); - str = strchr(str,':'); - if (str) - *str++=0; + struct config_setting_t *combo_db = NULL; + if ((combo_db = libconfig->setting_get_member(combo_conf.root, "combo_db")) == NULL) { + ShowError("itemdb_read_combodb_libconfig: can't read %s\n", filepath); + return false; } - if( i == 0 ) //No data found. - return 0; + int i = 0; + int count = 0; + struct config_setting_t *it = NULL; - return i; + while ((it = libconfig->setting_get_elem(combo_db, i++)) != NULL) { + if (itemdb->read_combodb_libconfig_sub(it, i - 1, filepath)) + ++count; + } + + libconfig->destroy(&combo_conf); + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filepath); + return true; } -/** - * ,<{ script }> - **/ -static void itemdb_read_combos(void) + +static bool itemdb_read_combodb_libconfig_sub(struct config_setting_t *it, int idx, const char *source) { - uint32 lines = 0, count = 0; - char line[1024]; - char filepath[256]; - FILE* fp; + nullpo_retr(false, it); + nullpo_retr(false, source); - safesnprintf(filepath, 256, "%s/%s", map->db_path, DBPATH"item_combo_db.txt"); + struct config_setting_t *t = NULL; - if ((fp = fopen(filepath, "r")) == NULL) { - ShowError("itemdb_read_combos: File not found \"%s\".\n", filepath); - return; + if ((t = libconfig->setting_get_member(it, "Items")) == NULL) { + ShowWarning("itemdb_read_combodb_libconfig_sub: invalid item list for combo (%d), in (%s), skipping..\n", idx, source); + return false; } - // process rows one by one - while(fgets(line, sizeof(line), fp)) { - char *str[2], *p; - - lines++; - - if (line[0] == '/' && line[1] == '/') - continue; - - memset(str, 0, sizeof(str)); + if (!config_setting_is_array(t)) { + ShowWarning("itemdb_read_combodb_libconfig_sub: the combo (%d) item list must be an array, in (%s), skipping..\n", idx, source); + return false; + } - p = line; - p = trim(p); - if (*p == '\0') - continue;// empty line + int len = libconfig->setting_length(t); + if (len > MAX_ITEMS_PER_COMBO) { + ShowWarning("itemdb_read_combodb_libconfig_sub: the size of combo (%d) item list is too big (%d, max = %d), in (%s), skipping..\n", idx, len, MAX_ITEMS_PER_COMBO, source); + return false; + } - if (!strchr(p,',')) { - /* is there even a single column? */ - ShowError("itemdb_read_combos: Insufficient columns in line %u of \"%s\", skipping.\n", lines, filepath); - continue; - } + struct item_combo *combo = NULL; + RECREATE(itemdb->combos, struct item_combo *, ++itemdb->combo_count); + CREATE(combo, struct item_combo, 1); - str[0] = p; - p = strchr(p,','); - *p = '\0'; - p++; + combo->id = itemdb->combo_count - 1; + combo->count = len; - str[1] = p; - p = strchr(p,','); - p++; + for (int i = 0; i < len; i++) { + struct item_data *item = NULL; + const char *name = libconfig->setting_get_string_elem(t, i); - if (str[1][0] != '{') { - ShowError("itemdb_read_combos(#1): Invalid format (Script column) in line %u of \"%s\", skipping.\n", lines, filepath); - continue; + if ((item = itemdb->name2id(name)) == NULL) { + ShowWarning("itemdb_read_combodb_libconfig_sub: unknown item '%s', in (%s), skipping..\n", name, source); + --itemdb->combo_count; + aFree(combo); + return false; } + combo->nameid[i] = item->nameid; + } - /* no ending key anywhere (missing \}\) */ - if ( str[1][strlen(str[1])-1] != '}' ) { - ShowError("itemdb_read_combos(#2): Invalid format (Script column) in line %u of \"%s\", skipping.\n", lines, filepath); - continue; - } else { - int items[MAX_ITEMS_PER_COMBO]; - int v = 0, retcount = 0; - struct item_combo *combo = NULL; - - if((retcount = itemdb->combo_split_atoi(str[0], items)) < 2) { - ShowError("itemdb_read_combos: line %u of \"%s\" doesn't have enough items to make for a combo (min:2), skipping.\n", lines, filepath); - continue; - } - - /* validate */ - for(v = 0; v < retcount; v++) { - if( !itemdb->exists(items[v]) ) { - ShowError("itemdb_read_combos: line %u of \"%s\" contains unknown item ID %d, skipping.\n", lines, filepath, items[v]); - break; - } - } - /* failed at some item */ - if( v < retcount ) - continue; - - RECREATE(itemdb->combos, struct item_combo*, ++itemdb->combo_count); - - CREATE(combo, struct item_combo, 1); - - combo->count = retcount; - combo->script = script->parse(str[1], filepath, lines, 0, NULL); - combo->id = itemdb->combo_count - 1; - /* populate ->nameid field */ - for( v = 0; v < retcount; v++ ) { - combo->nameid[v] = items[v]; - } - - itemdb->combos[itemdb->combo_count - 1] = combo; + const char *str = NULL; + if (libconfig->setting_lookup_string(it, "Script", &str) == CONFIG_TRUE) { + combo->script = *str ? script->parse(str, source, -idx, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; + } else { + ShowWarning("itemdb_read_combodb_libconfig_sub: invalid script for combo (%d) in (%s), skipping..\n", idx, source); + --itemdb->combo_count; + aFree(combo); + return false; + } - /* populate the items to refer to this combo */ - for( v = 0; v < retcount; v++ ) { - struct item_data * it; - int index; + itemdb->combos[combo->id] = combo; - it = itemdb->exists(items[v]); - index = it->combos_count; - RECREATE(it->combos, struct item_combo*, ++it->combos_count); - it->combos[index] = combo; - } - } - count++; + /* populate the items to refer to this combo */ + for (int i = 0; i < len; i++) { + struct item_data *item = itemdb->exists(combo->nameid[i]); + RECREATE(item->combos, struct item_combo *, ++item->combos_count); + item->combos[item->combos_count - 1] = combo; } - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%"PRIu32""CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, DBPATH"item_combo_db.txt"); - - return; + return true; } /*====================================== @@ -1721,6 +1719,14 @@ static int itemdb_validate_entry(struct item_data *entry, int n, const char *sou script->free_code(entry->unequip_script); entry->unequip_script = NULL; } + if (entry->rental_start_script != NULL) { + script->free_code(entry->rental_start_script); + entry->rental_start_script = NULL; + } + if (entry->rental_end_script != NULL) { + script->free_code(entry->rental_end_script); + entry->rental_end_script = NULL; + } return 0; #if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114 } @@ -1751,6 +1757,14 @@ static int itemdb_validate_entry(struct item_data *entry, int n, const char *sou script->free_code(entry->unequip_script); entry->unequip_script = NULL; } + if (entry->rental_start_script != NULL) { + script->free_code(entry->rental_start_script); + entry->rental_start_script = NULL; + } + if (entry->rental_end_script != NULL) { + script->free_code(entry->rental_end_script); + entry->rental_end_script = NULL; + } return 0; } } @@ -1878,7 +1892,14 @@ static int itemdb_validate_entry(struct item_data *entry, int n, const char *sou script->free_code(item->unequip_script); item->unequip_script = NULL; } - + if (item->rental_start_script != NULL && item->rental_start_script != entry->rental_start_script) { // Don't free if it's inheriting the same script + script->free_code(item->rental_start_script); + item->rental_start_script = NULL; + } + if (item->rental_end_script != NULL && item->rental_end_script != entry->rental_end_script) { // Don't free if it's inheriting the same script + script->free_code(item->rental_end_script); + item->rental_end_script = NULL; + } *item = *entry; return item->nameid; } @@ -1994,6 +2015,8 @@ static int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const * "> * OnEquipScript: <" OnEquip Script "> * OnUnequipScript: <" OnUnequip Script "> + * OnRentalStartScript: <" on renting script "> + * OnRentalEndScript: <" on renting end script "> * Inherit: inherit or override */ if( !itemdb->lookup_const(it, "Id", &i32) ) { @@ -2271,6 +2294,12 @@ static int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const if( libconfig->setting_lookup_string(it, "OnUnequipScript", &str) ) id.unequip_script = *str ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; + if (libconfig->setting_lookup_string(it, "OnRentalStartScript", &str) != CONFIG_FALSE) + id.rental_start_script = (*str != '\0') ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; + + if (libconfig->setting_lookup_string(it, "OnRentalEndScript", &str) != CONFIG_FALSE) + id.rental_end_script = (*str != '\0') ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; + return itemdb->validate_entry(&id, n, source); } @@ -2422,6 +2451,98 @@ static uint64 itemdb_unique_id(struct map_session_data *sd) return ((uint64)sd->status.char_id << 32) | sd->status.uniqueitem_counter++; } +static bool itemdb_read_libconfig_lapineddukddak(void) +{ + struct config_t item_lapineddukddak; + struct config_setting_t *it = NULL; + char filepath[256]; + + int i = 0; + int count = 0; + + safesnprintf(filepath, sizeof(filepath), "%s/%s", map->db_path, DBPATH"item_lapineddukddak.conf"); + if (libconfig->load_file(&item_lapineddukddak, filepath) == CONFIG_FALSE) + return false; + + while ((it = libconfig->setting_get_elem(item_lapineddukddak.root, i++)) != NULL) { + if (itemdb->read_libconfig_lapineddukddak_sub(it, filepath)) + ++count; + } + + libconfig->destroy(&item_lapineddukddak); + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filepath); + return true; +} + +static bool itemdb_read_libconfig_lapineddukddak_sub(struct config_setting_t *it, const char *source) +{ + nullpo_retr(false, it); + nullpo_retr(false, source); + + struct item_data *data = NULL; + const char *name = config_setting_name(it); + const char *str = NULL; + int i32 = 0; + + if ((data = itemdb->name2id(name)) == NULL) { + ShowWarning("itemdb_read_libconfig_lapineddukddak_sub: unknown item '%s', skipping..\n", name); + return false; + } + + data->lapineddukddak = aCalloc(1, sizeof(struct item_lapineddukddak)); + if (libconfig->setting_lookup_int(it, "NeedCount", &i32) == CONFIG_TRUE) + data->lapineddukddak->NeedCount = (int16)i32; + + if (libconfig->setting_lookup_int(it, "NeedRefineMin", &i32) == CONFIG_TRUE) + data->lapineddukddak->NeedRefineMin = (int8)i32; + + if (libconfig->setting_lookup_int(it, "NeedRefineMax", &i32) == CONFIG_TRUE) + data->lapineddukddak->NeedRefineMax = (int8)i32; + + struct config_setting_t *sources = libconfig->setting_get_member(it, "SourceItems"); + itemdb->read_libconfig_lapineddukddak_sub_sources(sources, data); + + if (libconfig->setting_lookup_string(it, "Script", &str) == CONFIG_TRUE) + data->lapineddukddak->script = *str ? script->parse(str, source, -data->nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL; + return true; +} + +static bool itemdb_read_libconfig_lapineddukddak_sub_sources(struct config_setting_t *sources, struct item_data *data) +{ + nullpo_retr(false, data); + nullpo_retr(false, data->lapineddukddak); + + int i = 0; + struct config_setting_t *entry = NULL; + + if (sources == NULL || !config_setting_is_group(sources)) + return false; + + VECTOR_INIT(data->lapineddukddak->SourceItems); + while ((entry = libconfig->setting_get_elem(sources, i++)) != NULL) { + struct item_data *edata = NULL; + struct itemlist_entry item = { 0 }; + const char *name = config_setting_name(entry); + int i32 = 0; + + if ((edata = itemdb->name2id(name)) == NULL) { + ShowWarning("itemdb_read_libconfig_lapineddukddak_sub: unknown item '%s', skipping..\n", name); + continue; + } + item.id = edata->nameid; + + if ((i32 = libconfig->setting_get_int(entry)) == CONFIG_TRUE && (i32 <= 0 || i32 > MAX_AMOUNT)) { + ShowWarning("itemdb_read_libconfig_lapineddukddak_sub: invalid amount (%d) for source item '%s', skipping..\n", i32, name); + continue; + } + item.amount = i32; + + VECTOR_ENSURE(data->lapineddukddak->SourceItems, 1, 1); + VECTOR_PUSH(data->lapineddukddak->SourceItems, item); + } + return true; +} + /** * Reads all item-related databases. */ @@ -2456,10 +2577,11 @@ static void itemdb_read(bool minimal) itemdb->name_constants(); - itemdb->read_combos(); + itemdb->read_combodb_libconfig(); itemdb->read_groups(); itemdb->read_chains(); itemdb->read_packages(); + itemdb->read_libconfig_lapineddukddak(); } /** @@ -2514,8 +2636,18 @@ static void destroy_item_data(struct item_data *self, int free_self) script->free_code(self->equip_script); if( self->unequip_script ) script->free_code(self->unequip_script); + if (self->rental_start_script != NULL) + script->free_code(self->rental_start_script); + if (self->rental_end_script != NULL) + script->free_code(self->rental_end_script); if( self->combos ) aFree(self->combos); + if (self->lapineddukddak != NULL) { + if (self->lapineddukddak->script != NULL) + script->free_code(self->lapineddukddak->script); + VECTOR_CLEAR(self->lapineddukddak->SourceItems); + aFree(self->lapineddukddak); + } HPM->data_store_destroy(&self->hdata); #if defined(DEBUG) // trash item @@ -2800,8 +2932,8 @@ void itemdb_defaults(void) itemdb->isrestricted = itemdb_isrestricted; itemdb->isidentified = itemdb_isidentified; itemdb->isidentified2 = itemdb_isidentified2; - itemdb->combo_split_atoi = itemdb_combo_split_atoi; - itemdb->read_combos = itemdb_read_combos; + itemdb->read_combodb_libconfig = itemdb_read_combodb_libconfig; + itemdb->read_combodb_libconfig_sub = itemdb_read_combodb_libconfig_sub; itemdb->gendercheck = itemdb_gendercheck; itemdb->validate_entry = itemdb_validate_entry; itemdb->readdb_options_additional_fields = itemdb_readdb_options_additional_fields; @@ -2820,4 +2952,7 @@ void itemdb_defaults(void) itemdb->lookup_const = itemdb_lookup_const; itemdb->lookup_const_mask = itemdb_lookup_const_mask; itemdb->addname_sub = itemdb_addname_sub; + itemdb->read_libconfig_lapineddukddak = itemdb_read_libconfig_lapineddukddak; + itemdb->read_libconfig_lapineddukddak_sub = itemdb_read_libconfig_lapineddukddak_sub; + itemdb->read_libconfig_lapineddukddak_sub_sources = itemdb_read_libconfig_lapineddukddak_sub_sources; } diff --git a/src/map/itemdb.h b/src/map/itemdb.h index f66abe066..14ead7707 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -39,7 +39,7 @@ struct hplugin_data_store; #ifndef MAX_ITEM_ID #if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114 -#define MAX_ITEM_ID 0x20000 +#define MAX_ITEM_ID INT32_MAX #else #define MAX_ITEM_ID 0xFFFF #endif @@ -139,7 +139,6 @@ enum item_itemid { ITEMID_COATING_BOTTLE = 7139, ITEMID_FRAGMENT_OF_CRYSTAL = 7321, ITEMID_SKULL_ = 7420, - ITEMID_TOKEN_OF_SIEGFRIED = 7621, ITEMID_SPECIAL_ALLOY_TRAP = 7940, ITEMID_CATNIP_FRUIT = 11602, ITEMID_RED_POUCH_OF_SURPRISE = 12024, @@ -359,6 +358,7 @@ enum geneticist_item_list { // enum e_chain_cache { ECC_ORE, + ECC_SIEGFRIED, /* */ ECC_MAX, }; @@ -412,6 +412,16 @@ enum ItemOptionTypes { IT_OPT_MAX }; +/** + * Item name search flags + **/ + +enum item_name_search_flag { + IT_SEARCH_NAME_PARTIAL, + IT_SEARCH_NAME_EXACT, + IT_SEARCH_NAME_MAX, +}; + /** Convenience item list (entry) used in various functions */ struct itemlist_entry { int id; ///< Item ID or (inventory) index @@ -482,6 +492,14 @@ struct itemdb_option { struct script_code *script; }; +struct item_lapineddukddak { + int16 NeedCount; + int8 NeedRefineMin; + int8 NeedRefineMax; + VECTOR_DECL(struct itemlist_entry) SourceItems; + struct script_code *script; +}; + struct item_data { int nameid; char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH]; @@ -516,6 +534,8 @@ struct item_data { struct script_code *script; ///< Default script for everything. struct script_code *equip_script; ///< Script executed once when equipping. struct script_code *unequip_script; ///< Script executed once when unequipping. + struct script_code *rental_start_script; ///< Script executed once this item get rented + struct script_code *rental_end_script; ///< Script executed once this item rent ends struct { unsigned available : 1; unsigned no_refine : 1; // [celest] @@ -549,6 +569,7 @@ struct item_data { /* TODO add a pointer to some sort of (struct extra) and gather all the not-common vals into it to save memory */ struct item_group *group; struct item_package *package; + struct item_lapineddukddak *lapineddukddak; struct hplugin_data_store *hdata; ///< HPM Plugin Data Store }; @@ -633,7 +654,7 @@ struct itemdb_interface { /* */ struct item_data* (*name2id) (const char *str); struct item_data* (*search_name) (const char *name); - int (*search_name_array) (struct item_data** data, int size, const char *str, int flag); + int (*search_name_array) (struct item_data **data, const int size, const char *str, enum item_name_search_flag flag); struct item_data* (*load)(int nameid); struct item_data* (*search)(int nameid); struct item_data* (*exists) (int nameid); @@ -666,8 +687,8 @@ struct itemdb_interface { int (*isrestricted) (struct item *item, int gmlv, int gmlv2, int(*func)(struct item_data *, int, int)); int (*isidentified) (int nameid); int (*isidentified2) (struct item_data *data); - int (*combo_split_atoi) (char *str, int *val); - void (*read_combos) (void); + bool (*read_combodb_libconfig) (void); + bool (*read_combodb_libconfig_sub) (struct config_setting_t *it, int idx, const char *source); int (*gendercheck) (struct item_data *id); int (*validate_entry) (struct item_data *entry, int n, const char *source); void (*readdb_options_additional_fields) (struct itemdb_option *ito, struct config_setting_t *t, const char *source); @@ -686,6 +707,9 @@ struct itemdb_interface { bool (*lookup_const) (const struct config_setting_t *it, const char *name, int *value); bool (*lookup_const_mask) (const struct config_setting_t *it, const char *name, int *value); int (*addname_sub) (union DBKey key, struct DBData *data, va_list ap); + bool (*read_libconfig_lapineddukddak) (void); + bool (*read_libconfig_lapineddukddak_sub) (struct config_setting_t *it, const char *source); + bool (*read_libconfig_lapineddukddak_sub_sources) (struct config_setting_t *sources, struct item_data *data); }; #ifdef HERCULES_CORE diff --git a/src/map/log.c b/src/map/log.c index 5bbca02a9..aa2f5f8f3 100644 --- a/src/map/log.c +++ b/src/map/log.c @@ -511,7 +511,7 @@ static void log_sql_final(void) /** * Initializes logs->config variables */ -void log_set_defaults(void) +static void log_set_defaults(void) { memset(&logs->config, 0, sizeof(logs->config)); @@ -540,7 +540,7 @@ void log_set_defaults(void) * * @retval false in case of error. */ -bool log_config_read_database(const char *filename, struct config_t *config, bool imported) +static bool log_config_read_database(const char *filename, struct config_t *config, bool imported) { struct config_setting_t *setting = NULL; @@ -596,7 +596,7 @@ bool log_config_read_database(const char *filename, struct config_t *config, boo * * @retval false in case of error. */ -bool log_config_read_filter_item(const char *filename, struct config_t *config, bool imported) +static bool log_config_read_filter_item(const char *filename, struct config_t *config, bool imported) { struct config_setting_t *setting = NULL; @@ -625,7 +625,7 @@ bool log_config_read_filter_item(const char *filename, struct config_t *config, * * @retval false in case of error. */ -bool log_config_read_filter_chat(const char *filename, struct config_t *config, bool imported) +static bool log_config_read_filter_chat(const char *filename, struct config_t *config, bool imported) { struct config_setting_t *setting = NULL; @@ -651,7 +651,7 @@ bool log_config_read_filter_chat(const char *filename, struct config_t *config, * * @retval false in case of error. */ -bool log_config_read_filter(const char *filename, struct config_t *config, bool imported) +static bool log_config_read_filter(const char *filename, struct config_t *config, bool imported) { bool retval = true; @@ -674,7 +674,7 @@ bool log_config_read_filter(const char *filename, struct config_t *config, bool * * @retval false in case of error. */ -bool log_config_read(const char *filename, bool imported) +static bool log_config_read(const char *filename, bool imported) { struct config_t config; struct config_setting_t *setting = NULL; @@ -755,7 +755,7 @@ bool log_config_read(const char *filename, bool imported) return retval; } -void log_config_complete(void) +static void log_config_complete(void) { if( logs->config.sql_logs ) { logs->pick_sub = log_pick_sub_sql; diff --git a/src/map/map.c b/src/map/map.c index f92be52e9..332bbe75f 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -2268,30 +2268,25 @@ static struct map_session_data *map_charid2sd(int charid) * (without sensitive case if necessary) * return map_session_data pointer or NULL *------------------------------------------*/ -static struct map_session_data *map_nick2sd(const char *nick) +static struct map_session_data *map_nick2sd(const char *nick, bool allow_partial) { - struct map_session_data* sd; - struct map_session_data* found_sd; - struct s_mapiterator* iter; - size_t nicklen; - int qty = 0; - - if( nick == NULL ) + if (nick == NULL) return NULL; - nicklen = strlen(nick); - iter = mapit_getallusers(); + struct s_mapiterator *iter = mapit_getallusers(); + struct map_session_data *found_sd = NULL; + + if (battle_config.partial_name_scan && allow_partial) { + int nicklen = (int)strlen(nick); + int qty = 0; - found_sd = NULL; - for (sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { - if( battle_config.partial_name_scan ) - {// partial name search - if( strnicmp(sd->status.name, nick, nicklen) == 0 ) - { + // partial name search + for (struct map_session_data *sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { + if (strnicmp(sd->status.name, nick, nicklen) == 0) { found_sd = sd; - if( strcmp(sd->status.name, nick) == 0 ) - {// Perfect Match + if (strcmp(sd->status.name, nick) == 0) { + // Perfect Match qty = 1; break; } @@ -2299,17 +2294,20 @@ static struct map_session_data *map_nick2sd(const char *nick) qty++; } } - else if( strcasecmp(sd->status.name, nick) == 0 ) - {// exact search only - found_sd = sd; - break; + + if (qty != 1) + found_sd = NULL; + } else { + // exact search only + for (struct map_session_data *sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { + if (strcasecmp(sd->status.name, nick) == 0) { + found_sd = sd; + break; + } } } mapit->free(iter); - if( battle_config.partial_name_scan && qty != 1 ) - found_sd = NULL; - return found_sd; } diff --git a/src/map/map.h b/src/map/map.h index 39eb07e4c..6b360e1bc 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -1208,7 +1208,7 @@ END_ZEROED_BLOCK; void (*addiddb) (struct block_list *bl); void (*deliddb) (struct block_list *bl); /* */ - struct map_session_data * (*nick2sd) (const char *nick); + struct map_session_data * (*nick2sd) (const char *nick, bool allow_partial); struct mob_data * (*getmob_boss) (int16 m); struct mob_data * (*id2boss) (int id); uint32 (*race_id2mask) (int race); diff --git a/src/map/mapdefines.h b/src/map/mapdefines.h index df9e9bccb..348ca98fd 100644 --- a/src/map/mapdefines.h +++ b/src/map/mapdefines.h @@ -21,6 +21,8 @@ #ifndef MAP_MAPDEFINES_H #define MAP_MAPDEFINES_H +#include "common/mmo.h" // packet versions + #define MAX_NPC_PER_MAP 512 #define AREA_SIZE (battle->bc->area_size) #define CHAT_AREA_SIZE (battle->bc->chat_area_size) @@ -57,8 +59,14 @@ #define MAPID_UPPERMASK 0x0fff #define MAPID_THIRDMASK (JOBL_THIRD|MAPID_UPPERMASK) -// Max size for inputs to Graffiti, Talkie Box and Vending text prompts +// Max size for inputs to Vending text prompts #define MESSAGE_SIZE (79 + 1) +// Max size for inputs to Graffiti, Talkie Box text prompts +#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828 +#define TALKBOX_MESSAGE_SIZE 21 +#else +#define TALKBOX_MESSAGE_SIZE (79 + 1) +#endif // String length you can write in the 'talking box' #define CHATBOX_SIZE (70 + 1) // Chatroom-related string sizes diff --git a/src/map/messages_main.h b/src/map/messages_main.h index bc5bcf55d..1ef24d6ab 100644 --- a/src/map/messages_main.h +++ b/src/map/messages_main.h @@ -24,7 +24,7 @@ /* This file is autogenerated, please do not commit manual changes -Latest version: 20190821 +Latest version: 20190918 */ enum clif_messages { @@ -21875,6 +21875,92 @@ Sold Out */ MSG_ID_E50 = 0xe50, #endif +#if PACKETVER >= 20190828 +/*20190828 to latest +์žฅ์ฐฉ ์ค‘์ธ ์•„์ดํ…œ์€ ๊ตํ™˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์žฅ์ฐฉ์„ ํ•ด์ œํ•œ ๋’ค ์‹œ๋„ํ•ด ์ฃผ์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. +*/ + MSG_ID_E51 = 0xe51, +#endif +#if PACKETVER >= 20190904 +/*20190904 to latest +๊ธธ๋“œ ์ฐฝ๊ณ  ์ด์šฉ ์ค‘์—” ์บ๋ฆญํ„ฐ ์„ ํƒ์ฐฝ์œผ๋กœ ์ด๋™ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E52 = 0xe52, +/*20190904 to latest +์•„์ดํ…œ ํƒœ๊ทธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E53 = 0xe53, +/*20190904 to latest +Monster +*/ + MSG_ID_E54 = 0xe54, +/*20190904 to latest +Unknown +*/ + MSG_ID_E55 = 0xe55, +/*20190904 to latest +Undead +*/ + MSG_ID_E56 = 0xe56, +/*20190904 to latest +Animal +*/ + MSG_ID_E57 = 0xe57, +/*20190904 to latest +Plant +*/ + MSG_ID_E58 = 0xe58, +/*20190904 to latest +Insect +*/ + MSG_ID_E59 = 0xe59, +/*20190904 to latest +Marine +*/ + MSG_ID_E5A = 0xe5a, +/*20190904 to latest +Devil +*/ + MSG_ID_E5B = 0xe5b, +/*20190904 to latest +Human +*/ + MSG_ID_E5C = 0xe5c, +/*20190904 to latest +Angel +*/ + MSG_ID_E5D = 0xe5d, +/*20190904 to latest +Dragon +*/ + MSG_ID_E5E = 0xe5e, +#endif +#if PACKETVER >= 20190918 +/*20190918 to latest +Balance: %s %c +*/ + MSG_ID_E5F = 0xe5f, +/*20190918 to latest + ^ff0000๋ณธ ์•„์ดํ…œ์„ ๊ตฌ๋งค ํ›„ 7์ผ ์ด๋‚ด์—๋Š” ์ฒญ์•ฝ ์ฒ ํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ, 7์ผ์ด ์ง€๋‚ฌ๊ฑฐ๋‚˜ ์•„์ดํ…œ์„ ๊ฐœ๋ด‰ํ•˜์‹œ๋ฉด ์ฒญ์•ฝ ์ฒ ํšŒ ๋Œ€์ƒ์—์„œ ์ œ์™ธ ๋ฉ๋‹ˆ๋‹ค.๋˜ํ•œ ๊ตฌ๋งค์‹œ ์‚ฌ์šฉ๋œ ๋ฌด๋ฃŒ์บ์‹œ๋Š” ์ฒญ์•ฝ์ฒ ํšŒ์‹œ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.^000000 ์ •๋ง๋กœ ์•„์ดํ…œ์„ ๊ตฌ๋งคํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ตฌ๋งคํ•˜์‹ค ๊ฒฝ์šฐ %s์บ์‹œ๊ฐ€ ์ฐจ๊ฐ๋ฉ๋‹ˆ๋‹ค. +*/ + MSG_ID_E60 = 0xe60, +/*20190918 to latest + ^ff0000๋ณธ ์•„์ดํ…œ์„ ๊ตฌ๋งค ํ›„ 7์ผ ์ด๋‚ด์—๋Š” ์ฒญ์•ฝ ์ฒ ํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ, 7์ผ์ด ์ง€๋‚ฌ๊ฑฐ๋‚˜ ์•„์ดํ…œ์„ ๊ฐœ๋ด‰ํ•˜์‹œ๋ฉด ์ฒญ์•ฝ ์ฒ ํšŒ ๋Œ€์ƒ์—์„œ ์ œ์™ธ ๋ฉ๋‹ˆ๋‹ค.๋˜ํ•œ ๊ตฌ๋งค์‹œ ์‚ฌ์šฉ๋œ ๋ฌด๋ฃŒ์บ์‹œ๋Š” ์ฒญ์•ฝ์ฒ ํšŒ์‹œ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.^000000 ์ •๋ง๋กœ ์•„์ดํ…œ์„ ๊ตฌ๋งคํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ตฌ๋งคํ•˜์‹ค ๊ฒฝ์šฐ ์ผ๋ฐ˜ %s์บ์‹œ, ๋ฌด๋ฃŒ %s์บ์‹œ๊ฐ€ ์ฐจ๊ฐ๋ฉ๋‹ˆ๋‹ค. +*/ + MSG_ID_E61 = 0xe61, +/*20190918 to latest +[%s]์˜ ํ˜ธ์ถœ์ด ๊ฑฐ๋ถ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E62 = 0xe62, +/*20190918 to latest +๊ตฌ๋งค ํ•œ๋„์•ก์€ ์†Œ์ง€์•ก์„ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E63 = 0xe63, +/*20190918 to latest +๋…ธ์ ์„ ์—ฌ๋Š”๋ฐ ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ตฌ๋งค๋…ธ์  ๊ฐœ์„ค์„ ๋‹ซ์•„์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. +*/ + MSG_ID_E64 = 0xe64, +#endif }; #endif /* MAP_MESSAGES_MAIN_H */ diff --git a/src/map/messages_re.h b/src/map/messages_re.h index efebecdb2..4ae3dee1d 100644 --- a/src/map/messages_re.h +++ b/src/map/messages_re.h @@ -24,7 +24,7 @@ /* This file is autogenerated, please do not commit manual changes -Latest version: 20190821 +Latest version: 20190918 */ enum clif_messages { @@ -21354,6 +21354,92 @@ Sold Out */ MSG_ID_E50 = 0xe50, #endif +#if PACKETVER >= 20190828 +/*20190828 to latest +์žฅ์ฐฉ ์ค‘์ธ ์•„์ดํ…œ์€ ๊ตํ™˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์žฅ์ฐฉ์„ ํ•ด์ œํ•œ ๋’ค ์‹œ๋„ํ•ด ์ฃผ์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. +*/ + MSG_ID_E51 = 0xe51, +#endif +#if PACKETVER >= 20190904 +/*20190904 to latest +๊ธธ๋“œ ์ฐฝ๊ณ  ์ด์šฉ ์ค‘์—” ์บ๋ฆญํ„ฐ ์„ ํƒ์ฐฝ์œผ๋กœ ์ด๋™ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E52 = 0xe52, +/*20190904 to latest +์•„์ดํ…œ ํƒœ๊ทธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E53 = 0xe53, +/*20190904 to latest +Monster +*/ + MSG_ID_E54 = 0xe54, +/*20190904 to latest +Unknown +*/ + MSG_ID_E55 = 0xe55, +/*20190904 to latest +Undead +*/ + MSG_ID_E56 = 0xe56, +/*20190904 to latest +Animal +*/ + MSG_ID_E57 = 0xe57, +/*20190904 to latest +Plant +*/ + MSG_ID_E58 = 0xe58, +/*20190904 to latest +Insect +*/ + MSG_ID_E59 = 0xe59, +/*20190904 to latest +Marine +*/ + MSG_ID_E5A = 0xe5a, +/*20190904 to latest +Devil +*/ + MSG_ID_E5B = 0xe5b, +/*20190904 to latest +Human +*/ + MSG_ID_E5C = 0xe5c, +/*20190904 to latest +Angel +*/ + MSG_ID_E5D = 0xe5d, +/*20190904 to latest +Dragon +*/ + MSG_ID_E5E = 0xe5e, +#endif +#if PACKETVER >= 20190918 +/*20190918 to latest +Balance: %s %c +*/ + MSG_ID_E5F = 0xe5f, +/*20190918 to latest + ^ff0000๋ณธ ์•„์ดํ…œ์„ ๊ตฌ๋งค ํ›„ 7์ผ ์ด๋‚ด์—๋Š” ์ฒญ์•ฝ ์ฒ ํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ, 7์ผ์ด ์ง€๋‚ฌ๊ฑฐ๋‚˜ ์•„์ดํ…œ์„ ๊ฐœ๋ด‰ํ•˜์‹œ๋ฉด ์ฒญ์•ฝ ์ฒ ํšŒ ๋Œ€์ƒ์—์„œ ์ œ์™ธ ๋ฉ๋‹ˆ๋‹ค.๋˜ํ•œ ๊ตฌ๋งค์‹œ ์‚ฌ์šฉ๋œ ๋ฌด๋ฃŒ์บ์‹œ๋Š” ์ฒญ์•ฝ์ฒ ํšŒ์‹œ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.^000000 ์ •๋ง๋กœ ์•„์ดํ…œ์„ ๊ตฌ๋งคํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ตฌ๋งคํ•˜์‹ค ๊ฒฝ์šฐ %s์บ์‹œ๊ฐ€ ์ฐจ๊ฐ๋ฉ๋‹ˆ๋‹ค. +*/ + MSG_ID_E60 = 0xe60, +/*20190918 to latest + ^ff0000๋ณธ ์•„์ดํ…œ์„ ๊ตฌ๋งค ํ›„ 7์ผ ์ด๋‚ด์—๋Š” ์ฒญ์•ฝ ์ฒ ํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ, 7์ผ์ด ์ง€๋‚ฌ๊ฑฐ๋‚˜ ์•„์ดํ…œ์„ ๊ฐœ๋ด‰ํ•˜์‹œ๋ฉด ์ฒญ์•ฝ ์ฒ ํšŒ ๋Œ€์ƒ์—์„œ ์ œ์™ธ ๋ฉ๋‹ˆ๋‹ค.๋˜ํ•œ ๊ตฌ๋งค์‹œ ์‚ฌ์šฉ๋œ ๋ฌด๋ฃŒ์บ์‹œ๋Š” ์ฒญ์•ฝ์ฒ ํšŒ์‹œ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.^000000 ์ •๋ง๋กœ ์•„์ดํ…œ์„ ๊ตฌ๋งคํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ตฌ๋งคํ•˜์‹ค ๊ฒฝ์šฐ ์ผ๋ฐ˜ %s์บ์‹œ, ๋ฌด๋ฃŒ %s์บ์‹œ๊ฐ€ ์ฐจ๊ฐ๋ฉ๋‹ˆ๋‹ค. +*/ + MSG_ID_E61 = 0xe61, +/*20190918 to latest +ํ˜ธ์ถœ์ด ๊ฑฐ๋ถ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E62 = 0xe62, +/*20190918 to latest +๊ตฌ๋งค ํ•œ๋„์•ก์€ ์†Œ์ง€์•ก์„ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E63 = 0xe63, +/*20190918 to latest +๋…ธ์ ์„ ์—ฌ๋Š”๋ฐ ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ตฌ๋งค๋…ธ์  ๊ฐœ์„ค์„ ๋‹ซ์•„์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. +*/ + MSG_ID_E64 = 0xe64, +#endif }; #endif /* MAP_MESSAGES_RE_H */ diff --git a/src/map/messages_zero.h b/src/map/messages_zero.h index 344dbb29e..039d215ac 100644 --- a/src/map/messages_zero.h +++ b/src/map/messages_zero.h @@ -24,7 +24,7 @@ /* This file is autogenerated, please do not commit manual changes -Latest version: 20190814 +Latest version: 20190918 */ enum clif_messages { @@ -17922,8 +17922,10 @@ Sale Start Time ๊ณ„์ • ํ•œ์ • */ MSG_ID_E48 = 0xe48, -/*20190814 to latest +/*20190814 to 20190814 ํŒ๋งค๊ธฐ๊ฐ„ : %d์›” %d์ผ ~ %d์›” %d์ผ +20190828 to latest +ํŒ๋งค๊ธฐ๊ฐ„ : %d์›” %d์ผ %d์‹œ %d๋ถ„ */ MSG_ID_E49 = 0xe49, /*20190814 to latest @@ -17947,6 +17949,102 @@ Sold Out */ MSG_ID_E4E = 0xe4e, #endif +#if PACKETVER >= 20190828 +/*20190828 to latest +~ %d์›” %d์ผ %d์‹œ %d๋ถ„ +*/ + MSG_ID_E4F = 0xe4f, +/*20190828 to latest +์ƒํ’ˆ์„ ๋”์ด์ƒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค +*/ + MSG_ID_E50 = 0xe50, +/*20190828 to latest +์žฅ์ฐฉ ์ค‘์ธ ์•„์ดํ…œ์€ ๊ตํ™˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์žฅ์ฐฉ์„ ํ•ด์ œํ•œ ๋’ค ์‹œ๋„ํ•ด ์ฃผ์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. +*/ + MSG_ID_E51 = 0xe51, +#endif +#if PACKETVER >= 20190911 +/*20190911 to latest +๊ธธ๋“œ ์ฐฝ๊ณ  ์ด์šฉ ์ค‘์—” ์บ๋ฆญํ„ฐ ์„ ํƒ์ฐฝ์œผ๋กœ ์ด๋™ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E52 = 0xe52, +/*20190911 to latest +์•„์ดํ…œ ํƒœ๊ทธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E53 = 0xe53, +/*20190911 to latest +Monster +*/ + MSG_ID_E54 = 0xe54, +/*20190911 to latest +Unknown +*/ + MSG_ID_E55 = 0xe55, +/*20190911 to latest +Undead +*/ + MSG_ID_E56 = 0xe56, +/*20190911 to latest +Animal +*/ + MSG_ID_E57 = 0xe57, +/*20190911 to latest +Plant +*/ + MSG_ID_E58 = 0xe58, +/*20190911 to latest +Insect +*/ + MSG_ID_E59 = 0xe59, +/*20190911 to latest +Marine +*/ + MSG_ID_E5A = 0xe5a, +/*20190911 to latest +Devil +*/ + MSG_ID_E5B = 0xe5b, +/*20190911 to latest +Human +*/ + MSG_ID_E5C = 0xe5c, +/*20190911 to latest +Angel +*/ + MSG_ID_E5D = 0xe5d, +/*20190911 to latest +Dragon +*/ + MSG_ID_E5E = 0xe5e, +/*20190911 to latest +Balance: %s %c +*/ + MSG_ID_E5F = 0xe5f, +/*20190911 to latest + ^ff0000๋ณธ ์•„์ดํ…œ์„ ๊ตฌ๋งค ํ›„ 7์ผ ์ด๋‚ด์—๋Š” ์ฒญ์•ฝ ์ฒ ํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ, 7์ผ์ด ์ง€๋‚ฌ๊ฑฐ๋‚˜ ์•„์ดํ…œ์„ ๊ฐœ๋ด‰ํ•˜์‹œ๋ฉด ์ฒญ์•ฝ ์ฒ ํšŒ ๋Œ€์ƒ์—์„œ ์ œ์™ธ ๋ฉ๋‹ˆ๋‹ค.๋˜ํ•œ ๊ตฌ๋งค์‹œ ์‚ฌ์šฉ๋œ ๋ฌด๋ฃŒ์บ์‹œ๋Š” ์ฒญ์•ฝ์ฒ ํšŒ์‹œ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.^000000 ์ •๋ง๋กœ ์•„์ดํ…œ์„ ๊ตฌ๋งคํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ตฌ๋งคํ•˜์‹ค ๊ฒฝ์šฐ %s์บ์‹œ๊ฐ€ ์ฐจ๊ฐ๋ฉ๋‹ˆ๋‹ค. +*/ + MSG_ID_E60 = 0xe60, +/*20190911 to latest + ^ff0000๋ณธ ์•„์ดํ…œ์„ ๊ตฌ๋งค ํ›„ 7์ผ ์ด๋‚ด์—๋Š” ์ฒญ์•ฝ ์ฒ ํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ, 7์ผ์ด ์ง€๋‚ฌ๊ฑฐ๋‚˜ ์•„์ดํ…œ์„ ๊ฐœ๋ด‰ํ•˜์‹œ๋ฉด ์ฒญ์•ฝ ์ฒ ํšŒ ๋Œ€์ƒ์—์„œ ์ œ์™ธ ๋ฉ๋‹ˆ๋‹ค.๋˜ํ•œ ๊ตฌ๋งค์‹œ ์‚ฌ์šฉ๋œ ๋ฌด๋ฃŒ์บ์‹œ๋Š” ์ฒญ์•ฝ์ฒ ํšŒ์‹œ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.^000000 ์ •๋ง๋กœ ์•„์ดํ…œ์„ ๊ตฌ๋งคํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ตฌ๋งคํ•˜์‹ค ๊ฒฝ์šฐ ์ผ๋ฐ˜ %s์บ์‹œ, ๋ฌด๋ฃŒ %s์บ์‹œ๊ฐ€ ์ฐจ๊ฐ๋ฉ๋‹ˆ๋‹ค. +*/ + MSG_ID_E61 = 0xe61, +/*20190911 to 20190911 +ํ˜ธ์ถœ์ด ๊ฑฐ๋ถ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +20190918 to latest +[%s]์˜ ํ˜ธ์ถœ์ด ๊ฑฐ๋ถ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E62 = 0xe62, +#endif +#if PACKETVER >= 20190918 +/*20190918 to latest +๊ตฌ๋งค ํ•œ๋„์•ก์€ ์†Œ์ง€์•ก์„ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +*/ + MSG_ID_E63 = 0xe63, +/*20190918 to latest +๋…ธ์ ์„ ์—ฌ๋Š”๋ฐ ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ตฌ๋งค๋…ธ์  ๊ฐœ์„ค์„ ๋‹ซ์•„์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. +*/ + MSG_ID_E64 = 0xe64, +#endif }; #endif /* MAP_MESSAGES_ZERO_H */ diff --git a/src/map/mob.c b/src/map/mob.c index bad3f7eb8..e04d6944e 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -239,6 +239,14 @@ static void mvptomb_destroy(struct mob_data *md) m = nd->bl.m; + struct s_mapiterator *iter = mapit_geteachpc(); + for (struct map_session_data *sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { + if (sd->npc_id == nd->bl.id) { + sd->state.npc_unloaded = 1; + } + } + mapit->free(iter); + clif->clearunit_area(&nd->bl,CLR_OUTSIGHT); map->delblock(&nd->bl); diff --git a/src/map/npc.c b/src/map/npc.c index 1c5c72af9..00207a745 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1258,6 +1258,9 @@ static void run_tomb(struct map_session_data *sd, struct npc_data *nd) char time[10]; nullpo_retv(nd); + + sd->npc_id = nd->bl.id; + strftime(time, sizeof(time), "%H:%M", localtime(&nd->u.tomb.kill_time)); // TODO: Find exact color? @@ -1349,8 +1352,10 @@ static int npc_scriptcont(struct map_session_data *sd, int id, bool closing) return 1; } - if(id != npc->fake_nd->bl.id) { // Not item script - if ((npc->checknear(sd,target)) == NULL){ + if (id != npc->fake_nd->bl.id) { // Not item script + if (sd->state.npc_unloaded != 0) { + sd->state.npc_unloaded = 0; + } else if ((npc->checknear(sd,target)) == NULL) { ShowWarning("npc_scriptcont: failed npc->checknear test.\n"); return 1; } @@ -1371,8 +1376,10 @@ static int npc_scriptcont(struct map_session_data *sd, int id, bool closing) if( sd->progressbar.npc_id && DIFF_TICK(sd->progressbar.timeout,timer->gettick()) > 0 ) return 1; - if( !sd->st ) + if( !sd->st ) { + sd->npc_id = 0; return 1; + } if( closing && sd->st->state == CLOSE ) sd->st->state = END; diff --git a/src/map/packets.h b/src/map/packets.h index 83a9d0322..8fb47eb7a 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -1954,4 +1954,17 @@ packet(0x96e,clif->ackmergeitems); packet(0x0b22,clif->pHotkeyRowShift2); // CZ_SHORTCUTKEYBAR_ROTATE #endif +#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190522 || PACKETVER_ZERO_NUM >= 20190515 + packet(0x0b28,clif->pGuildCastleTeleportRequest); + packet(0x0b2c,clif->pGuildCastleInfoRequest); +#endif + +#if PACKETVER >= 20160302 + packet(0x0a4f,clif->plapineDdukDdak_ack); +#endif + +#if PACKETVER >= 20160504 + packet(0x0a70,clif->plapineDdukDdak_close); +#endif + #endif /* MAP_PACKETS_H */ diff --git a/src/map/packets_keys_main.h b/src/map/packets_keys_main.h index 565835cd7..b7f25a83d 100644 --- a/src/map/packets_keys_main.h +++ b/src/map/packets_keys_main.h @@ -37,7 +37,7 @@ packetKeys(0x49357d72,0x22c370a1,0x5f836591); #endif -// 2010-11-23aRagexeRE, 2010-11-24aRagexeRE, 2010-11-24bRagexeRE, 2010-11-25aRagexeRE, 2010-11-26aRagexeRE, 2010-11-30aRagexeRE, 2010-12-07aRagexeRE, 2010-12-14aRagexeRE, 2010-12-21aRagexeRE, 2010-12-23aRagexeRE, 2010-12-28aRagexeRE, 2011-01-04aRagexeRE, 2011-01-05aRagexeRE, 2011-01-11aRagexeRE, 2011-01-18aRagexeRE, 2011-01-25aRagexeRE, 2011-01-26aRagexeRE, 2011-01-26bRagexeRE, 2011-01-31aRagexeRE, 2011-01-31bRagexeRE, 2011-01-31cRagexeRE, 2011-02-08aRagexeRE, 2011-02-15aRagexeRE, 2011-02-22aRagexeRE, 2011-02-23aRagexeRE, 2011-02-23bRagexeRE, 2011-02-24aRagexeRE, 2011-02-25aRagexeRE, 2011-02-28aRagexeRE, 2011-03-08aRagexeRE, 2011-03-09aRagexeRE, 2011-03-09bRagexeRE, 2011-03-09cRagexeRE, 2011-03-09dRagexeRE, 2011-03-15aRagexeRE, 2011-03-22aRagexeRE, 2011-03-29aRagexeRE, 2011-03-30aRagexeRE, 2011-03-30cRagexeRE, 2011-04-05aRagexeRE, 2011-04-12aRagexeRE, 2011-04-19aRagexeRE, 2011-04-20aRagexeRE, 2011-04-26aRagexeRE, 2011-04-27aRagexeRE, 2011-05-03aRagexeRE, 2011-05-11aRagexeRE, 2011-05-17bRagexeRE, 2011-05-24aRagexeRE, 2011-05-26aRagexeRE, 2011-05-31aRagexeRE, 2011-06-07aRagexeRE, 2011-06-08aRagexeRE, 2011-06-08bRagexeRE, 2011-06-08cRagexeRE, 2011-06-09aRagexeRE, 2011-06-14bRagexeRE, 2011-06-22aRagexeRE, 2011-06-28aRagexeRE, 2011-07-06aRagexeRE, 2011-07-13aRagexeRE, 2011-07-13bRagexeRE, 2011-07-13cRagexeRE, 2011-07-19aRagexeRE, 2011-07-26aRagexeRE, 2011-08-03aRagexeRE, 2011-08-03bRagexeRE, 2011-08-10aRagexeRE, 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE, 2018-04-04bRagexe, 2018-04-04cRagexeRE, 2018-04-18aRagexe, 2018-04-18bRagexeRE, 2018-04-25cRagexe, 2018-04-25cRagexeRE, 2018-05-02bRagexe, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-16cRagexeRE, 2018-05-23aRagexe, 2018-05-23aRagexeRE, 2018-05-30aRagexe, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexe, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20cRagexe, 2018-06-20dRagexeRE, 2018-06-20eRagexe, 2018-06-20eRagexeRE, 2018-06-21aRagexe, 2018-06-21aRagexeRE, 2018-07-04aRagexe, 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexe, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexe, 2018-07-18cRagexeRE, 2018-08-01cRagexe, 2018-08-01cRagexeRE, 2018-08-08bRagexe, 2018-08-08bRagexeRE, 2018-08-22cRagexe, 2018-08-22cRagexeRE, 2018-08-29aRagexe, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-12dRagexeRE, 2018-09-19aRagexe, 2018-09-19aRagexeRE, 2018-10-02aRagexe, 2018-10-02aRagexeRE, 2018-10-02bRagexe, 2018-10-02bRagexeRE, 2018-10-17_02aRagexe, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexe, 2018-10-17_03aRagexeRE, 2018-10-17bRagexe, 2018-10-17bRagexeRE, 2018-10-24bRagexe, 2018-10-31aRagexe, 2018-10-31bRagexe, 2018-10-31cRagexeRE, 2018-11-07aRagexe, 2018-11-07aRagexeRE, 2018-11-14cRagexe, 2018-11-14cRagexeRE, 2018-11-14dRagexe, 2018-11-14dRagexeRE, 2018-11-21bRagexe, 2018-11-21cRagexeRE, 2018-11-28aRagexe, 2018-11-28aRagexeRE, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-05bRagexeRE, 2018-12-12aRagexe, 2018-12-12aRagexeRE, 2018-12-12bRagexe, 2018-12-12bRagexeRE, 2018-12-19bRagexe, 2018-12-19bRagexeRE, 2018-12-26aRagexe, 2018-12-26aRagexeRE, 2019-01-09aRagexe, 2019-01-09bRagexeRE, 2019-01-16bRagexe, 2019-01-16bRagexeRE, 2019-01-16cRagexe, 2019-01-16cRagexeRE, 2019-01-23dRagexe, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-20aRagexeRE, 2019-02-27aRagexe, 2019-02-27bRagexeRE, 2019-02-28aRagexe, 2019-02-28aRagexeRE, 2019-03-06bRagexe, 2019-03-06bRagexeRE, 2019-03-06cRagexe, 2019-03-06cRagexeRE, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-20aRagexeRE, 2019-03-22aRagexe, 2019-03-22aRagexeRE, 2019-03-27bRagexe, 2019-03-27bRagexeRE, 2019-04-03aRagexe, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17aRagexe, 2019-04-17cRagexeRE, 2019-04-18aRagexe, 2019-04-18aRagexeRE, 2019-05-08cRagexe, 2019-05-08dRagexeRE, 2019-05-08eRagexeRE, 2019-05-22bRagexe, 2019-05-22bRagexeRE, 2019-05-22cRagexe, 2019-05-22cRagexeRE, 2019-05-23aRagexe, 2019-05-29aRagexe, 2019-05-29bRagexeRE, 2019-05-29cRagexe, 2019-05-29cRagexeRE, 2019-05-30aRagexe, 2019-05-30aRagexeRE, 2019-06-05JRagexeRE, 2019-06-05KRagexe, 2019-06-05LRagexeRE, 2019-06-05fRagexe, 2019-06-05hRagexeRE, 2019-06-19bRagexe, 2019-06-19cRagexeRE, 2019-06-19eRagexe, 2019-06-19hRagexe, 2019-06-26bRagexeRE, 2019-07-03aRagexe, 2019-07-03bRagexeRE, 2019-07-17aRagexe, 2019-07-17cRagexeRE, 2019-07-17dRagexe, 2019-07-17dRagexeRE, 2019-07-24aRagexe, 2019-07-24bRagexeRE, 2019-07-31bRagexe, 2019-07-31bRagexeRE, 2019-08-02aRagexe, 2019-08-02aRagexeRE, 2019-08-07aRagexe, 2019-08-07dRagexeRE, 2019-08-21aRagexe, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE +// 2010-11-23aRagexeRE, 2010-11-24aRagexeRE, 2010-11-24bRagexeRE, 2010-11-25aRagexeRE, 2010-11-26aRagexeRE, 2010-11-30aRagexeRE, 2010-12-07aRagexeRE, 2010-12-14aRagexeRE, 2010-12-21aRagexeRE, 2010-12-23aRagexeRE, 2010-12-28aRagexeRE, 2011-01-04aRagexeRE, 2011-01-05aRagexeRE, 2011-01-11aRagexeRE, 2011-01-18aRagexeRE, 2011-01-25aRagexeRE, 2011-01-26aRagexeRE, 2011-01-26bRagexeRE, 2011-01-31aRagexeRE, 2011-01-31bRagexeRE, 2011-01-31cRagexeRE, 2011-02-08aRagexeRE, 2011-02-15aRagexeRE, 2011-02-22aRagexeRE, 2011-02-23aRagexeRE, 2011-02-23bRagexeRE, 2011-02-24aRagexeRE, 2011-02-25aRagexeRE, 2011-02-28aRagexeRE, 2011-03-08aRagexeRE, 2011-03-09aRagexeRE, 2011-03-09bRagexeRE, 2011-03-09cRagexeRE, 2011-03-09dRagexeRE, 2011-03-15aRagexeRE, 2011-03-22aRagexeRE, 2011-03-29aRagexeRE, 2011-03-30aRagexeRE, 2011-03-30cRagexeRE, 2011-04-05aRagexeRE, 2011-04-12aRagexeRE, 2011-04-19aRagexeRE, 2011-04-20aRagexeRE, 2011-04-26aRagexeRE, 2011-04-27aRagexeRE, 2011-05-03aRagexeRE, 2011-05-11aRagexeRE, 2011-05-17bRagexeRE, 2011-05-24aRagexeRE, 2011-05-26aRagexeRE, 2011-05-31aRagexeRE, 2011-06-07aRagexeRE, 2011-06-08aRagexeRE, 2011-06-08bRagexeRE, 2011-06-08cRagexeRE, 2011-06-09aRagexeRE, 2011-06-14bRagexeRE, 2011-06-22aRagexeRE, 2011-06-28aRagexeRE, 2011-07-06aRagexeRE, 2011-07-13aRagexeRE, 2011-07-13bRagexeRE, 2011-07-13cRagexeRE, 2011-07-19aRagexeRE, 2011-07-26aRagexeRE, 2011-08-03aRagexeRE, 2011-08-03bRagexeRE, 2011-08-10aRagexeRE, 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE, 2018-04-04bRagexe, 2018-04-04cRagexeRE, 2018-04-18aRagexe, 2018-04-18bRagexeRE, 2018-04-25cRagexe, 2018-04-25cRagexeRE, 2018-05-02bRagexe, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-16cRagexeRE, 2018-05-23aRagexe, 2018-05-23aRagexeRE, 2018-05-30aRagexe, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexe, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20cRagexe, 2018-06-20dRagexeRE, 2018-06-20eRagexe, 2018-06-20eRagexeRE, 2018-06-21aRagexe, 2018-06-21aRagexeRE, 2018-07-04aRagexe, 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexe, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexe, 2018-07-18cRagexeRE, 2018-08-01cRagexe, 2018-08-01cRagexeRE, 2018-08-08bRagexe, 2018-08-08bRagexeRE, 2018-08-22cRagexe, 2018-08-22cRagexeRE, 2018-08-29aRagexe, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-12dRagexeRE, 2018-09-19aRagexe, 2018-09-19aRagexeRE, 2018-10-02aRagexe, 2018-10-02aRagexeRE, 2018-10-02bRagexe, 2018-10-02bRagexeRE, 2018-10-17_02aRagexe, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexe, 2018-10-17_03aRagexeRE, 2018-10-17bRagexe, 2018-10-17bRagexeRE, 2018-10-24bRagexe, 2018-10-31aRagexe, 2018-10-31bRagexe, 2018-10-31cRagexeRE, 2018-11-07aRagexe, 2018-11-07aRagexeRE, 2018-11-14cRagexe, 2018-11-14cRagexeRE, 2018-11-14dRagexe, 2018-11-14dRagexeRE, 2018-11-21bRagexe, 2018-11-21cRagexeRE, 2018-11-28aRagexe, 2018-11-28aRagexeRE, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-05bRagexeRE, 2018-12-12aRagexe, 2018-12-12aRagexeRE, 2018-12-12bRagexe, 2018-12-12bRagexeRE, 2018-12-19bRagexe, 2018-12-19bRagexeRE, 2018-12-26aRagexe, 2018-12-26aRagexeRE, 2019-01-09aRagexe, 2019-01-09bRagexeRE, 2019-01-16bRagexe, 2019-01-16bRagexeRE, 2019-01-16cRagexe, 2019-01-16cRagexeRE, 2019-01-23dRagexe, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-20aRagexeRE, 2019-02-27aRagexe, 2019-02-27bRagexeRE, 2019-02-28aRagexe, 2019-02-28aRagexeRE, 2019-03-06bRagexe, 2019-03-06bRagexeRE, 2019-03-06cRagexe, 2019-03-06cRagexeRE, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-20aRagexeRE, 2019-03-22aRagexe, 2019-03-22aRagexeRE, 2019-03-27bRagexe, 2019-03-27bRagexeRE, 2019-04-03aRagexe, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17aRagexe, 2019-04-17cRagexeRE, 2019-04-18aRagexe, 2019-04-18aRagexeRE, 2019-05-08cRagexe, 2019-05-08dRagexeRE, 2019-05-08eRagexeRE, 2019-05-22bRagexe, 2019-05-22bRagexeRE, 2019-05-22cRagexe, 2019-05-22cRagexeRE, 2019-05-23aRagexe, 2019-05-29aRagexe, 2019-05-29bRagexeRE, 2019-05-29cRagexe, 2019-05-29cRagexeRE, 2019-05-30aRagexe, 2019-05-30aRagexeRE, 2019-06-05JRagexeRE, 2019-06-05KRagexe, 2019-06-05LRagexeRE, 2019-06-05fRagexe, 2019-06-05hRagexeRE, 2019-06-19bRagexe, 2019-06-19cRagexeRE, 2019-06-19eRagexe, 2019-06-19hRagexe, 2019-06-26bRagexeRE, 2019-07-03aRagexe, 2019-07-03bRagexeRE, 2019-07-17aRagexe, 2019-07-17cRagexeRE, 2019-07-17dRagexe, 2019-07-17dRagexeRE, 2019-07-24aRagexe, 2019-07-24bRagexeRE, 2019-07-31bRagexe, 2019-07-31bRagexeRE, 2019-08-02aRagexe, 2019-08-02aRagexeRE, 2019-08-07aRagexe, 2019-08-07dRagexeRE, 2019-08-21aRagexe, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE, 2019-08-28aRagexe, 2019-08-28aRagexeRE, 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-04bRagexeRE, 2019-09-18bRagexe, 2019-09-18cRagexeRE #if PACKETVER == 20101123 || \ PACKETVER == 20101124 || \ PACKETVER == 20101125 || \ @@ -162,7 +162,10 @@ PACKETVER == 20190731 || \ PACKETVER == 20190802 || \ PACKETVER == 20190807 || \ - PACKETVER >= 20190821 + PACKETVER == 20190821 || \ + PACKETVER == 20190828 || \ + PACKETVER == 20190904 || \ + PACKETVER >= 20190918 packetKeys(0x00000000,0x00000000,0x00000000); #endif diff --git a/src/map/packets_keys_zero.h b/src/map/packets_keys_zero.h index 0e70ef641..2708d11e1 100644 --- a/src/map/packets_keys_zero.h +++ b/src/map/packets_keys_zero.h @@ -30,7 +30,7 @@ /* This file is autogenerated, please do not commit manual changes */ -// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero, 2018-10-10_2aRagexe_zero, 2018-10-24_2aRagexe_zero, 2018-11-14aRagexe_zero, 2018-11-20aRagexe_zero, 2018-11-28aRagexe_zero, 2018-12-12aRagexe_zero, 2018-12-19aRagexe_zero, 2018-12-26_2aRagexe_zero, 2019-01-16_2aRagexe_zero, 2019-01-17_1aRagexe_zero, 2019-01-30_2aRagexe_zero, 2019-02-13aRagexe_zero, 2019-02-20aRagexe_zero, 2019-02-27aRagexe_zero, 2019-03-13aRagexe_zero, 2019-03-27_2aRagexe_zero, 2019-03-27_3aRagexe_zero, 2019-04-03aRagexe_zero, 2019-04-10bRagexe_zero, 2019-04-24aRagexe_zero, 2019-05-02aRagexe_zero, 2019-05-08_2aRagexe_zero, 2019-05-08aRagexe_zero, 2019-05-15aRagexe_zero, 2019-05-29aRagexe_zero, 2019-05-30aRagexe_zero, 2019-06-05_2aRagexe_zero, 2019-06-26_2aRagexe_zero, 2019-06-26_3aRagexe_zero, 2019-07-09aRagexe_zero, 2019-07-10_3aRagexe_zero, 2019-07-17aRagexe_zero, 2019-07-24aRagexe_zero, 2019-08-14_3aRagexe_zero +// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero, 2018-10-10_2aRagexe_zero, 2018-10-24_2aRagexe_zero, 2018-11-14aRagexe_zero, 2018-11-20aRagexe_zero, 2018-11-28aRagexe_zero, 2018-12-12aRagexe_zero, 2018-12-19aRagexe_zero, 2018-12-26_2aRagexe_zero, 2019-01-16_2aRagexe_zero, 2019-01-17_1aRagexe_zero, 2019-01-30_2aRagexe_zero, 2019-02-13aRagexe_zero, 2019-02-20aRagexe_zero, 2019-02-27aRagexe_zero, 2019-03-13aRagexe_zero, 2019-03-27_2aRagexe_zero, 2019-03-27_3aRagexe_zero, 2019-04-03aRagexe_zero, 2019-04-10bRagexe_zero, 2019-04-24aRagexe_zero, 2019-05-02aRagexe_zero, 2019-05-08_2aRagexe_zero, 2019-05-08aRagexe_zero, 2019-05-15aRagexe_zero, 2019-05-29aRagexe_zero, 2019-05-30aRagexe_zero, 2019-06-05_2aRagexe_zero, 2019-06-26_2aRagexe_zero, 2019-06-26_3aRagexe_zero, 2019-07-09aRagexe_zero, 2019-07-10_3aRagexe_zero, 2019-07-17aRagexe_zero, 2019-07-24aRagexe_zero, 2019-08-14_3aRagexe_zero, 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero #if PACKETVER == 20171018 || \ PACKETVER == 20171019 || \ PACKETVER == 20171023 || \ @@ -91,7 +91,10 @@ PACKETVER == 20190710 || \ PACKETVER == 20190717 || \ PACKETVER == 20190724 || \ - PACKETVER >= 20190814 + PACKETVER == 20190814 || \ + PACKETVER == 20190828 || \ + PACKETVER == 20190911 || \ + PACKETVER >= 20190918 packetKeys(0x00000000,0x00000000,0x00000000); #endif diff --git a/src/map/packets_shuffle_main.h b/src/map/packets_shuffle_main.h index 082c940c9..e3e798dd1 100644 --- a/src/map/packets_shuffle_main.h +++ b/src/map/packets_shuffle_main.h @@ -9727,7 +9727,7 @@ packet(0x0967,clif->pSolveCharName,2); // CZ_REQNAME_BYGID // 6 #endif -// 2018-11-21bRagexe, 2018-11-28aRagexe, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-12aRagexe, 2018-12-12bRagexe, 2018-12-19bRagexe, 2018-12-26aRagexe, 2019-01-09aRagexe, 2019-01-16bRagexe, 2019-01-16cRagexe, 2019-01-23dRagexe, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-27aRagexe, 2019-02-28aRagexe, 2019-03-06bRagexe, 2019-03-06cRagexe, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-22aRagexe, 2019-03-27bRagexe, 2019-04-03aRagexe, 2019-04-17aRagexe, 2019-04-18aRagexe, 2019-05-08cRagexe, 2019-05-22bRagexe, 2019-05-22cRagexe, 2019-05-23aRagexe, 2019-05-29aRagexe, 2019-05-29cRagexe, 2019-05-30aRagexe, 2019-06-05fRagexe, 2019-06-05KRagexe, 2019-06-19bRagexe, 2019-06-19eRagexe, 2019-06-19hRagexe, 2019-07-03aRagexe, 2019-07-17aRagexe, 2019-07-17dRagexe, 2019-07-24aRagexe, 2019-07-31bRagexe, 2019-08-02aRagexe, 2019-08-07aRagexe, 2019-08-21aRagexe +// 2018-11-21bRagexe, 2018-11-28aRagexe, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-12aRagexe, 2018-12-12bRagexe, 2018-12-19bRagexe, 2018-12-26aRagexe, 2019-01-09aRagexe, 2019-01-16bRagexe, 2019-01-16cRagexe, 2019-01-23dRagexe, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-27aRagexe, 2019-02-28aRagexe, 2019-03-06bRagexe, 2019-03-06cRagexe, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-22aRagexe, 2019-03-27bRagexe, 2019-04-03aRagexe, 2019-04-17aRagexe, 2019-04-18aRagexe, 2019-05-08cRagexe, 2019-05-22bRagexe, 2019-05-22cRagexe, 2019-05-23aRagexe, 2019-05-29aRagexe, 2019-05-29cRagexe, 2019-05-30aRagexe, 2019-06-05fRagexe, 2019-06-05KRagexe, 2019-06-19bRagexe, 2019-06-19eRagexe, 2019-06-19hRagexe, 2019-07-03aRagexe, 2019-07-17aRagexe, 2019-07-17dRagexe, 2019-07-24aRagexe, 2019-07-31bRagexe, 2019-08-02aRagexe, 2019-08-07aRagexe, 2019-08-21aRagexe, 2019-08-28aRagexe #if PACKETVER == 20181121 || \ PACKETVER == 20181128 || \ PACKETVER == 20181205 || \ @@ -9761,7 +9761,8 @@ PACKETVER == 20190731 || \ PACKETVER == 20190802 || \ PACKETVER == 20190807 || \ - PACKETVER >= 20190821 + PACKETVER == 20190821 || \ + PACKETVER >= 20190828 packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26 packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5 packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36 @@ -9793,5 +9794,39 @@ packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14 #endif +// 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-18bRagexe +#if PACKETVER == 20190904 || \ + PACKETVER == 20190918 + packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26 + packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5 + packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36 + packet(0x0281,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK // 4 + packet(0x02c4,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ // 26 + packet(0x035f,clif->pWalkToXY,2); // CZ_REQUEST_MOVE // 5 + packet(0x0360,clif->pTickSend,2); // CZ_REQUEST_TIME // 6 + packet(0x0361,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION // 5 + packet(0x0362,clif->pTakeItem,2); // CZ_ITEM_PICKUP // 6 + packet(0x0363,clif->pDropItem,2,4); // CZ_ITEM_THROW // 6 + packet(0x0364,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE // 8 + packet(0x0365,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY // 8 + packet(0x0366,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND // 10 + packet(0x0367,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX // 31 + packet(0x0368,clif->pGetCharNameRequest,2); // CZ_REQNAME // 6 + packet(0x0369,clif->pSolveCharName,2); // CZ_REQNAME_BYGID // 6 + packet(0x0436,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER // 19 + packet(0x0437,clif->pActionRequest,2,6); // CZ_REQUEST_ACT // 7 + packet(0x0438,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL // 10 + packet(0x07e4,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES // -1 + packet(0x07ec,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD // 8 + packet(0x0802,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER // 18 + packet(0x0811,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE // -1 + packet(0x0815,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE // 2 + packet(0x0817,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE // 6 + packet(0x0819,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE // -1 + packet(0x0835,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO // -1 + packet(0x0838,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE // 2 + packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14 +#endif + #endif /* MAP_PACKETS_SHUFFLE_MAIN_H */ diff --git a/src/map/packets_shuffle_re.h b/src/map/packets_shuffle_re.h index 044788301..f2a1b96ad 100644 --- a/src/map/packets_shuffle_re.h +++ b/src/map/packets_shuffle_re.h @@ -9663,7 +9663,7 @@ packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 12 #endif -// 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexeRE, 2018-08-01cRagexeRE, 2018-08-08bRagexeRE, 2018-08-22cRagexeRE, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-09-12dRagexeRE, 2018-09-19aRagexeRE, 2018-10-02aRagexeRE, 2018-10-02bRagexeRE, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexeRE, 2018-10-17bRagexeRE, 2018-10-31cRagexeRE, 2018-11-07aRagexeRE, 2018-11-14cRagexeRE, 2018-11-14dRagexeRE, 2018-11-21cRagexeRE, 2018-11-28aRagexeRE, 2018-12-05bRagexeRE, 2018-12-12aRagexeRE, 2018-12-12bRagexeRE, 2018-12-19bRagexeRE, 2018-12-26aRagexeRE, 2019-01-09bRagexeRE, 2019-01-16bRagexeRE, 2019-01-16cRagexeRE, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-20aRagexeRE, 2019-02-27bRagexeRE, 2019-02-28aRagexeRE, 2019-03-06bRagexeRE, 2019-03-06cRagexeRE, 2019-03-20aRagexeRE, 2019-03-22aRagexeRE, 2019-03-27bRagexeRE, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17cRagexeRE, 2019-04-18aRagexeRE, 2019-05-08dRagexeRE, 2019-05-08eRagexeRE, 2019-05-22bRagexeRE, 2019-05-22cRagexeRE, 2019-05-29bRagexeRE, 2019-05-29cRagexeRE, 2019-05-30aRagexeRE, 2019-06-05hRagexeRE, 2019-06-05JRagexeRE, 2019-06-05LRagexeRE, 2019-06-19cRagexeRE, 2019-06-26bRagexeRE, 2019-07-03bRagexeRE, 2019-07-17cRagexeRE, 2019-07-17dRagexeRE, 2019-07-24bRagexeRE, 2019-07-31bRagexeRE, 2019-08-02aRagexeRE, 2019-08-07dRagexeRE, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE +// 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexeRE, 2018-08-01cRagexeRE, 2018-08-08bRagexeRE, 2018-08-22cRagexeRE, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-09-12dRagexeRE, 2018-09-19aRagexeRE, 2018-10-02aRagexeRE, 2018-10-02bRagexeRE, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexeRE, 2018-10-17bRagexeRE, 2018-10-31cRagexeRE, 2018-11-07aRagexeRE, 2018-11-14cRagexeRE, 2018-11-14dRagexeRE, 2018-11-21cRagexeRE, 2018-11-28aRagexeRE, 2018-12-05bRagexeRE, 2018-12-12aRagexeRE, 2018-12-12bRagexeRE, 2018-12-19bRagexeRE, 2018-12-26aRagexeRE, 2019-01-09bRagexeRE, 2019-01-16bRagexeRE, 2019-01-16cRagexeRE, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-20aRagexeRE, 2019-02-27bRagexeRE, 2019-02-28aRagexeRE, 2019-03-06bRagexeRE, 2019-03-06cRagexeRE, 2019-03-20aRagexeRE, 2019-03-22aRagexeRE, 2019-03-27bRagexeRE, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17cRagexeRE, 2019-04-18aRagexeRE, 2019-05-08dRagexeRE, 2019-05-08eRagexeRE, 2019-05-22bRagexeRE, 2019-05-22cRagexeRE, 2019-05-29bRagexeRE, 2019-05-29cRagexeRE, 2019-05-30aRagexeRE, 2019-06-05hRagexeRE, 2019-06-05JRagexeRE, 2019-06-05LRagexeRE, 2019-06-19cRagexeRE, 2019-06-26bRagexeRE, 2019-07-03bRagexeRE, 2019-07-17cRagexeRE, 2019-07-17dRagexeRE, 2019-07-24bRagexeRE, 2019-07-31bRagexeRE, 2019-08-02aRagexeRE, 2019-08-07dRagexeRE, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE, 2019-08-28aRagexeRE #if PACKETVER == 20180704 || \ PACKETVER == 20180711 || \ PACKETVER == 20180718 || \ @@ -9711,7 +9711,8 @@ PACKETVER == 20190731 || \ PACKETVER == 20190802 || \ PACKETVER == 20190807 || \ - PACKETVER >= 20190821 + PACKETVER == 20190821 || \ + PACKETVER >= 20190828 packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26 packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5 packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36 @@ -9743,5 +9744,39 @@ packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14 #endif +// 2019-09-04bRagexeRE, 2019-09-18cRagexeRE +#if PACKETVER == 20190904 || \ + PACKETVER == 20190918 + packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26 + packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5 + packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36 + packet(0x0281,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK // 4 + packet(0x02c4,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ // 26 + packet(0x035f,clif->pWalkToXY,2); // CZ_REQUEST_MOVE // 5 + packet(0x0360,clif->pTickSend,2); // CZ_REQUEST_TIME // 6 + packet(0x0361,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION // 5 + packet(0x0362,clif->pTakeItem,2); // CZ_ITEM_PICKUP // 6 + packet(0x0363,clif->pDropItem,2,4); // CZ_ITEM_THROW // 6 + packet(0x0364,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE // 8 + packet(0x0365,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY // 8 + packet(0x0366,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND // 10 + packet(0x0367,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX // 31 + packet(0x0368,clif->pGetCharNameRequest,2); // CZ_REQNAME // 6 + packet(0x0369,clif->pSolveCharName,2); // CZ_REQNAME_BYGID // 6 + packet(0x0436,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER // 19 + packet(0x0437,clif->pActionRequest,2,6); // CZ_REQUEST_ACT // 7 + packet(0x0438,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL // 10 + packet(0x07e4,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES // -1 + packet(0x07ec,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD // 8 + packet(0x0802,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER // 18 + packet(0x0811,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE // -1 + packet(0x0815,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE // 2 + packet(0x0817,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE // 6 + packet(0x0819,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE // -1 + packet(0x0835,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO // -1 + packet(0x0838,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE // 2 + packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14 +#endif + #endif /* MAP_PACKETS_SHUFFLE_RE_H */ diff --git a/src/map/packets_shuffle_zero.h b/src/map/packets_shuffle_zero.h index 109dadaba..4d6da7a8a 100644 --- a/src/map/packets_shuffle_zero.h +++ b/src/map/packets_shuffle_zero.h @@ -803,5 +803,40 @@ packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14 #endif +// 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero +#if PACKETVER == 20190828 || \ + PACKETVER == 20190911 || \ + PACKETVER == 20190918 + packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26 + packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5 + packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36 + packet(0x0281,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK // 4 + packet(0x02c4,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ // 26 + packet(0x035f,clif->pWalkToXY,2); // CZ_REQUEST_MOVE // 5 + packet(0x0360,clif->pTickSend,2); // CZ_REQUEST_TIME // 6 + packet(0x0361,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION // 5 + packet(0x0362,clif->pTakeItem,2); // CZ_ITEM_PICKUP // 6 + packet(0x0363,clif->pDropItem,2,4); // CZ_ITEM_THROW // 6 + packet(0x0364,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE // 8 + packet(0x0365,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY // 8 + packet(0x0366,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND // 10 + packet(0x0367,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX // 31 + packet(0x0368,clif->pGetCharNameRequest,2); // CZ_REQNAME // 6 + packet(0x0369,clif->pSolveCharName,2); // CZ_REQNAME_BYGID // 6 + packet(0x0436,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER // 19 + packet(0x0437,clif->pActionRequest,2,6); // CZ_REQUEST_ACT // 7 + packet(0x0438,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL // 10 + packet(0x07e4,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES // -1 + packet(0x07ec,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD // 8 + packet(0x0802,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER // 18 + packet(0x0811,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE // -1 + packet(0x0815,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE // 2 + packet(0x0817,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE // 6 + packet(0x0819,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE // -1 + packet(0x0835,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO // -1 + packet(0x0838,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE // 2 + packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14 +#endif + #endif /* MAP_PACKETS_SHUFFLE_ZERO_H */ diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index d12dc14d4..9c8c93865 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -3460,6 +3460,14 @@ struct PACKET_ZC_REFINE_STATUS { DEFINE_PACKET_HEADER(ZC_REFINE_STATUS, 0x0ada); #endif +struct PACKET_ZC_ACK_RANKING_name { + char name[NAME_LENGTH]; +} __attribute__((packed)); + +struct PACKET_ZC_ACK_RANKING_points { + uint32 points; +} __attribute__((packed)); + #if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190703 || PACKETVER_ZERO_NUM >= 20190724 struct PACKET_ZC_ACK_RANKING_sub { char name[NAME_LENGTH]; @@ -3476,21 +3484,22 @@ struct PACKET_ZC_ACK_RANKING { DEFINE_PACKET_HEADER(ZC_ACK_RANKING, 0x0af6); #elif PACKETVER_MAIN_NUM >= 20130605 || PACKETVER_RE_NUM >= 20130529 || defined(PACKETVER_ZERO) struct PACKET_ZC_ACK_RANKING_sub { - char name[NAME_LENGTH]; - uint32 points; + struct PACKET_ZC_ACK_RANKING_name names[10]; + struct PACKET_ZC_ACK_RANKING_points points[10]; } __attribute__((packed)); struct PACKET_ZC_ACK_RANKING { int16 packetType; int16 rankType; - struct PACKET_ZC_ACK_RANKING_sub ranks[10]; + struct PACKET_ZC_ACK_RANKING_sub ranks; uint32 myPoints; } __attribute__((packed)); + DEFINE_PACKET_HEADER(ZC_ACK_RANKING, 0x097d); #else struct PACKET_ZC_ACK_RANKING_sub { - char name[NAME_LENGTH]; - uint32 points; + struct PACKET_ZC_ACK_RANKING_name names[10]; + struct PACKET_ZC_ACK_RANKING_points points[10]; } __attribute__((packed)); #endif @@ -3514,7 +3523,7 @@ DEFINE_PACKET_HEADER(ZC_HAT_EFFECT, 0x0a3b); #endif // [4144] this struct updated not in all packets in client -#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190814 +#if PACKETVER_RE_NUM >= 20190807 struct SKILLDATA { uint16 id; int inf; @@ -3540,7 +3549,7 @@ struct PACKET_ZC_ADD_SKILL { int16 packetType; struct SKILLDATA skill; } __attribute__((packed)); -#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190814 +#if PACKETVER_RE_NUM >= 20190807 DEFINE_PACKET_HEADER(ZC_ADD_SKILL, 0x0b31); #else DEFINE_PACKET_HEADER(ZC_ADD_SKILL, 0x0111); @@ -3551,13 +3560,13 @@ struct PACKET_ZC_SKILLINFO_LIST { int16 packetLength; struct SKILLDATA skills[]; } __attribute__((packed)); -#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190814 +#if PACKETVER_RE_NUM >= 20190807 DEFINE_PACKET_HEADER(ZC_SKILLINFO_LIST, 0x0b32); #else DEFINE_PACKET_HEADER(ZC_SKILLINFO_LIST, 0x010f); #endif -#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190814 +#if PACKETVER_RE_NUM >= 20190807 struct PACKET_ZC_SKILLINFO_UPDATE2 { int16 packetType; uint16 id; @@ -3610,6 +3619,95 @@ struct PACKET_ZC_NPC_MARKET_PURCHASE_RESULT { DEFINE_PACKET_HEADER(ZC_NPC_MARKET_PURCHASE_RESULT, 0x09d7); #endif +struct PACKET_ZC_TALKBOX_CHATCONTENTS { + int16 PacketType; + uint32 aid; + char message[TALKBOX_MESSAGE_SIZE]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_TALKBOX_CHATCONTENTS, 0x0191); + +#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814 +struct PACKET_ZC_GUILD_CASTLE_LIST { + int16 packetType; + int16 packetLength; + int8 castle_list[]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_GUILD_CASTLE_LIST, 0x0b27); +#endif + +#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190522 || PACKETVER_ZERO_NUM >= 20190515 +struct PACKET_CZ_CASTLE_TELEPORT_REQUEST { + int16 packetType; + int8 castle_id; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_CASTLE_TELEPORT_REQUEST, 0x0b28); +#endif + +#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814 +struct PACKET_ZC_CASTLE_TELEPORT_RESPONSE { + int16 packetType; + int16 result; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_CASTLE_TELEPORT_RESPONSE, 0x0b2e); +#endif + +#if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814 +struct PACKET_ZC_CASTLE_INFO { + int16 packetType; + int8 castle_id; + int32 economy; + int32 defense; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_CASTLE_INFO, 0x0b2d); +#endif + +#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190522 || PACKETVER_ZERO_NUM >= 20190515 +struct PACKET_CZ_CASTLE_INFO_REQUEST { + int16 packetType; + int8 castle_id; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_CASTLE_INFO_REQUEST, 0x0b2c); +#endif + +#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) +struct PACKET_ZC_LAPINEDDUKDDAK_OPEN { + int16 packetType; +#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114 + int32 itemId; +#else + int16 itemId; +#endif +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_LAPINEDDUKDDAK_OPEN, 0x0a4e); +#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) + +#if PACKETVER >= 20160302 +struct PACKET_CZ_LAPINEDDUKDDAK_ACK_sub { + int16 index; + int16 count; +} __attribute__((packed)); + +struct PACKET_CZ_LAPINEDDUKDDAK_ACK { + int16 packetType; + int16 packetLength; +#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114 + int32 itemId; +#else + int16 itemId; +#endif + struct PACKET_CZ_LAPINEDDUKDDAK_ACK_sub items[]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(CZ_LAPINEDDUKDDAK_ACK, 0x0a4f); +#endif // PACKETVER >= 20160302 + +#if PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) +struct PACKET_ZC_LAPINEDDUKDDAK_RESULT { + int16 packetType; + int16 result; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_LAPINEDDUKDDAK_RESULT, 0x0a50); +#endif // PACKETVER_MAIN_NUM >= 20160601 || PACKETVER_RE_NUM >= 20160525 || defined(PACKETVER_ZERO) + #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute #pragma pack(pop) #endif // not NetBSD < 6 / Solaris diff --git a/src/map/pc.c b/src/map/pc.c index 24f71f47b..2cefa7674 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -565,72 +565,8 @@ static int pc_inventory_rental_clear(struct map_session_data *sd) /* assumes i is valid (from default areas where it is called, it is) */ static void pc_rental_expire(struct map_session_data *sd, int i) { - int nameid; - nullpo_retv(sd); Assert_retv(i >= 0 && i < sd->status.inventorySize); - nameid = sd->status.inventory[i].nameid; - - /* Soon to be dropped, we got plans to integrate it with item db */ - switch( nameid ) { - case ITEMID_BOARDING_HALTER: - status_change_end(&sd->bl,SC_ALL_RIDING,INVALID_TIMER); - break; - case ITEMID_LOVE_ANGEL: - if( sd->status.font == 1 ) { - sd->status.font = 0; - clif->font(sd); - } - break; - case ITEMID_SQUIRREL: - if( sd->status.font == 2 ) { - sd->status.font = 0; - clif->font(sd); - } - break; - case ITEMID_GOGO: - if( sd->status.font == 3 ) { - sd->status.font = 0; - clif->font(sd); - } - break; - case ITEMID_PICTURE_DIARY: - if( sd->status.font == 4 ) { - sd->status.font = 0; - clif->font(sd); - } - break; - case ITEMID_MINI_HEART: - if( sd->status.font == 5 ) { - sd->status.font = 0; - clif->font(sd); - } - break; - case ITEMID_NEWCOMER: - if( sd->status.font == 6 ) { - sd->status.font = 0; - clif->font(sd); - } - break; - case ITEMID_KID: - if( sd->status.font == 7 ) { - sd->status.font = 0; - clif->font(sd); - } - break; - case ITEMID_MAGIC_CASTLE: - if( sd->status.font == 8 ) { - sd->status.font = 0; - clif->font(sd); - } - break; - case ITEMID_BULGING_HEAD: - if( sd->status.font == 9 ) { - sd->status.font = 0; - clif->font(sd); - } - break; - } clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid); pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_RENTAL); @@ -1536,17 +1472,16 @@ static int pc_reg_received(struct map_session_data *sd) if (sd->status.guild_id) guild->member_joined(sd); - // pet - if (sd->status.pet_id > 0) - intif->request_petdata(sd->status.account_id, sd->status.char_id, sd->status.pet_id); - - // Homunculus [albator] - if( sd->status.hom_id > 0 ) - intif->homunculus_requestload(sd->status.account_id, sd->status.hom_id); - if( sd->status.mer_id > 0 ) - intif->mercenary_request(sd->status.mer_id, sd->status.char_id); - if( sd->status.ele_id > 0 ) - intif->elemental_request(sd->status.ele_id, sd->status.char_id); + if (sd->state.standalone == 0 && sd->state.autotrade == 0) { // prevents loading pets, homunculi, mercenaries or elementals if the character doesn't have a client attached + if (sd->status.pet_id != 0) + intif->request_petdata(sd->status.account_id, sd->status.char_id, sd->status.pet_id); + if (sd->status.hom_id != 0) + intif->homunculus_requestload(sd->status.account_id, sd->status.hom_id); + if (sd->status.mer_id != 0) + intif->mercenary_request(sd->status.mer_id, sd->status.char_id); + if (sd->status.ele_id != 0) + intif->elemental_request(sd->status.ele_id, sd->status.char_id); + } map->addiddb(&sd->bl); map->delnickdb(sd->status.char_id, sd->status.name); @@ -4790,13 +4725,15 @@ static int pc_additem(struct map_session_data *sd, const struct item *item_data, pc->equipitem(sd, i, data->equip); /* rental item check */ - if( item_data->expire_time ) { - if( time(NULL) > item_data->expire_time ) { - pc->rental_expire(sd,i); + if (item_data->expire_time > 0) { + if (time(NULL) > item_data->expire_time) { + pc->rental_expire(sd, i); } else { - int seconds = (int)( item_data->expire_time - time(NULL) ); + int seconds = (int)(item_data->expire_time - time(NULL)); clif->rental_time(sd->fd, sd->status.inventory[i].nameid, seconds); pc->inventory_rental_add(sd, seconds); + if (data->rental_start_script != NULL) + script->run_item_rental_start_script(sd, data, 0); } } quest->questinfo_refresh(sd); @@ -4827,12 +4764,21 @@ static int pc_delitem(struct map_session_data *sd, int n, int amount, int type, sd->status.inventory[n].amount -= amount; sd->weight -= sd->inventory_data[n]->weight*amount ; + + // It's here because the data would most likely get zeroed in following if [Hemagx] + struct item_data *itd = sd->inventory_data[n]; + bool is_rental = (sd->status.inventory[n].expire_time > 0) ? true : false; + if( sd->status.inventory[n].amount <= 0 ){ if(sd->status.inventory[n].equip) pc->unequipitem(sd, n, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); memset(&sd->status.inventory[n],0,sizeof(sd->status.inventory[0])); sd->inventory_data[n] = NULL; } + + if (is_rental && itd->rental_end_script != NULL) + script->run_item_rental_end_script(sd, itd, 0); + if(!(type&1)) clif->delitem(sd,n,amount,reason); if(!(type&2)) @@ -7765,7 +7711,7 @@ static int pc_resetskill(struct map_session_data *sd, int flag) pc->setoption(sd, i); if( homun_alive(sd->hd) && pc->checkskill(sd, AM_CALLHOMUN) ) - homun->vaporize(sd, HOM_ST_REST); + homun->vaporize(sd, HOM_ST_REST, true); if ((sd->sc.data[SC_SPRITEMABLE] && pc->checkskill(sd, SU_SPRITEMABLE))) status_change_end(&sd->bl, SC_SPRITEMABLE, INVALID_TIMER); @@ -8006,7 +7952,7 @@ static void pc_damage(struct map_session_data *sd, struct block_list *src, unsig if( sd->status.pet_id > 0 && sd->pd && battle_config.pet_damage_support ) pet->target_check(sd,src,1); - if( sd->status.ele_id > 0 ) + if (sd->status.ele_id != 0 && sd->ed != NULL) elemental->set_target(sd,src); if (battle_config.prevent_logout_trigger & PLT_DAMAGE) @@ -8054,7 +8000,7 @@ static int pc_dead(struct map_session_data *sd, struct block_list *src) if (sd->status.hom_id > 0){ if(battle_config.homunculus_auto_vapor && sd->hd) - homun->vaporize(sd, HOM_ST_REST); + homun->vaporize(sd, HOM_ST_REST, true); } if( sd->md ) @@ -9069,7 +9015,7 @@ static int pc_jobchange(struct map_session_data *sd, int class, int upper) pc->setoption(sd, i); if(homun_alive(sd->hd) && !pc->checkskill(sd, AM_CALLHOMUN)) - homun->vaporize(sd, HOM_ST_REST); + homun->vaporize(sd, HOM_ST_REST, true); if ((sd->sc.data[SC_SPRITEMABLE] && pc->checkskill(sd, SU_SPRITEMABLE))) status_change_end(&sd->bl, SC_SPRITEMABLE, INVALID_TIMER); @@ -12214,6 +12160,29 @@ static int pc_have_magnifier(struct map_session_data *sd) return n; } +/** + * checks if player have any item that listed in item chain + * @param sd map_session_data of Player + * @param chain_id unsigned short of item chain id + * @return index of inventory, INDEX_NOT_FOUND if it is not found + */ +static int pc_have_item_chain(struct map_session_data *sd, unsigned short chain_id) +{ + if (chain_id >= itemdb->chain_count) { + ShowError("itemdb_chain_item: unknown chain id %d\n", chain_id); + return INDEX_NOT_FOUND; + } + + for (int n = 0; n < itemdb->chains[chain_id].qty; n++) { + struct item_chain_entry *entry = &itemdb->chains[chain_id].items[n]; + int index = pc->search_inventory(sd, entry->id); + if (index != INDEX_NOT_FOUND) + return index; + } + + return INDEX_NOT_FOUND; +} + /** * Checks if player have basic skills learned. * @param sd Player Data @@ -12823,6 +12792,7 @@ void pc_defaults(void) pc->update_idle_time = pc_update_idle_time; pc->have_magnifier = pc_have_magnifier; + pc->have_item_chain = pc_have_item_chain; pc->check_basicskill = pc_check_basicskill; diff --git a/src/map/pc.h b/src/map/pc.h index 8df02a891..7a42be5be 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -238,6 +238,8 @@ struct map_session_data { unsigned int loggingout : 1; unsigned int warp_clean : 1; unsigned int refine_ui : 1; + unsigned int npc_unloaded : 1; ///< The player is talking with an unloaded NPCs (respawned tombstones) + unsigned int lapine_ui : 1; } state; struct { unsigned char no_weapon_damage, no_magic_damage, no_misc_damage; @@ -664,10 +666,10 @@ END_ZEROED_BLOCK; #define pc_issit(sd) ( (sd)->vd.dead_sit == 2 ) #define pc_isidle(sd) ( (sd)->chat_id != 0 || (sd)->state.vending || (sd)->state.buyingstore || DIFF_TICK(sockt->last_tick, (sd)->idletime) >= battle->bc->idle_no_share ) #define pc_istrading(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->state.trading ) -#define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1) +#define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1) /* equals pc_cant_act except it doesn't check for chat rooms */ -#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1) +#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1) #define pc_setdir(sd,b,h) ( (sd)->ud.dir = (b) ,(sd)->head_dir = (h) ) #define pc_setchatid(sd,n) ( (sd)->chat_id = (n) ) @@ -1184,6 +1186,7 @@ END_ZEROED_BLOCK; /* End */ void (*update_idle_time) (struct map_session_data* sd, enum e_battle_config_idletime type); int (*have_magnifier) (struct map_session_data *sd); + int (*have_item_chain) (struct map_session_data *sd, unsigned short chain_id); bool (*process_chat_message) (struct map_session_data *sd, const char *message); int (*wis_message_to_gm) (const char *sender_name, int permission, const char *message); diff --git a/src/map/script.c b/src/map/script.c index 779b22d80..18cd01238 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -105,7 +105,7 @@ static inline void SETVALUE(struct script_buf *buf, int i, int n) VECTOR_INDEX(*buf, i+2) = GetByte(n, 2); } -const char *script_op2name(int op) +static const char *script_op2name(int op) { #define RETURN_OP_NAME(type) case type: return #type switch( op ) { @@ -2813,7 +2813,7 @@ static struct map_session_data *script_charid2sd(struct script_state *st, int ch static struct map_session_data *script_nick2sd(struct script_state *st, const char *name) { struct map_session_data *sd; - if ((sd = map->nick2sd(name)) == NULL) { + if ((sd = map->nick2sd(name, false)) == NULL) { ShowWarning("script_nick2sd: Player name '%s' not found!\n", name); script->reportfunc(st); script->reportsrc(st); @@ -8780,7 +8780,7 @@ static BUILDIN(getcharid) struct map_session_data *sd; if (script_hasdata(st, 3)) - sd = map->nick2sd(script_getstr(st, 3)); + sd = map->nick2sd(script_getstr(st, 3), false); else sd = script->rid2sd(st); @@ -12629,7 +12629,7 @@ static BUILDIN(homunculus_morphembryo) clif->additem(sd, 0, 0, i); clif->emotion(&sd->hd->bl, E_SWT); } else { - homun->vaporize(sd, HOM_ST_MORPH); + homun->vaporize(sd, HOM_ST_MORPH, true); success = true; } } else { @@ -16488,7 +16488,7 @@ static BUILDIN(getmapxy) case 0: //Get Character Position if (script_hasdata(st,6)) { if (script_isstringtype(st,6)) - sd = map->nick2sd(script_getstr(st,6)); + sd = map->nick2sd(script_getstr(st,6), false); else sd = map->id2sd(script_getnum(st,6)); } else { @@ -16515,7 +16515,7 @@ static BUILDIN(getmapxy) case 2: //Get Pet Position if (script_hasdata(st,6)) { if (script_isstringtype(st,6)) - sd = map->nick2sd(script_getstr(st,6)); + sd = map->nick2sd(script_getstr(st,6), false); else { bl = map->id2bl(script_getnum(st,6)); break; @@ -16537,7 +16537,7 @@ static BUILDIN(getmapxy) case 4: //Get Homun Position if (script_hasdata(st,6)) { if (script_isstringtype(st,6)) { - sd = map->nick2sd(script_getstr(st,6)); + sd = map->nick2sd(script_getstr(st,6), false); } else { bl = map->id2bl(script_getnum(st,6)); break; @@ -16552,7 +16552,7 @@ static BUILDIN(getmapxy) case 5: //Get Mercenary Position if (script_hasdata(st,6)) { if (script_isstringtype(st,6)) { - sd = map->nick2sd(script_getstr(st,6)); + sd = map->nick2sd(script_getstr(st,6), false); } else { bl = map->id2bl(script_getnum(st,6)); break; @@ -16567,7 +16567,7 @@ static BUILDIN(getmapxy) case 6: //Get Elemental Position if (script_hasdata(st,6)) { if (script_isstringtype(st,6)) { - sd = map->nick2sd(script_getstr(st,6)); + sd = map->nick2sd(script_getstr(st,6), false); } else { bl = map->id2bl(script_getnum(st,6)); break; @@ -18806,7 +18806,7 @@ static BUILDIN(searchitem) if ((items[0] = itemdb->exists(atoi(itemname)))) { count = 1; } else { - count = itemdb->search_name_array(items, ARRAYLENGTH(items), itemname, 0); + count = itemdb->search_name_array(items, ARRAYLENGTH(items), itemname, IT_SEARCH_NAME_PARTIAL); if (count > MAX_SEARCH) count = MAX_SEARCH; } @@ -22746,6 +22746,19 @@ static BUILDIN(setfont) return true; } +static BUILDIN(getfont) +{ + struct map_session_data *sd = script->rid2sd(st); + + if (sd == NULL) { + script_pushint(st, 0); + return true; + } + + script_pushint(st, sd->status.font); + return true; +} + static int buildin_mobuseskill_sub(struct block_list *bl, va_list ap) { struct mob_data *md = NULL; @@ -23072,7 +23085,7 @@ static BUILDIN(getcharip) /* check if a character name is specified */ if (script_hasdata(st, 2)) { if (script_isstringtype(st, 2)) { - sd = map->nick2sd(script_getstr(st, 2)); + sd = map->nick2sd(script_getstr(st, 2), false); } else { int id = script_getnum(st, 2); sd = (map->id2sd(id) ? map->id2sd(id) : map->charid2sd(id)); @@ -25744,6 +25757,25 @@ static BUILDIN(identifyidx) return true; } +static BUILDIN(openlapineddukddakboxui) +{ + struct map_session_data *sd = script_rid2sd(st); + if (sd == NULL) + return false; + const int item_id = script_getnum(st, 2); + struct item_data *it = itemdb->exists(item_id); + if (it == NULL) { + ShowError("buildin_openlapineddukddakboxui: Item %d is not valid\n", item_id); + script->reportfunc(st); + script->reportsrc(st); + script_pushint(st, false); + return true; + } + clif->lapineDdukDdak_open(sd, item_id); + script_pushint(st, true); + return true; +} + /** * Adds a built-in script function. * @@ -25893,6 +25925,52 @@ static void script_run_item_unequip_script(struct map_session_data *sd, struct i script->current_item_id = 0; } +static void script_run_item_rental_start_script(struct map_session_data *sd, struct item_data *data, int oid) __attribute__((nonnull(1, 2))); + +/** + * Run item rental start script + * @param sd player session data. Must be correct and checked before. + * @param data rental item data. Must be correct and checked before. + * @param oid npc id. Can be also 0 or fake npc id. + **/ +static void script_run_item_rental_start_script(struct map_session_data *sd, struct item_data *data, int oid) +{ + script->current_item_id = data->nameid; + script->run(data->rental_start_script, 0, sd->bl.id, oid); + script->current_item_id = 0; +} + +static void script_run_item_rental_end_script(struct map_session_data *sd, struct item_data *data, int oid) __attribute__((nonnull(1, 2))); + +/** +* Run item rental end script +* @param sd player session data. Must be correct and checked before. +* @param data rental item data. Must be correct and checked before. +* @param oid npc id. Can be also 0 or fake npc id. +**/ +static void script_run_item_rental_end_script(struct map_session_data *sd, struct item_data *data, int oid) +{ + script->current_item_id = data->nameid; + script->run(data->rental_end_script, 0, sd->bl.id, oid); + script->current_item_id = 0; +} + +static void script_run_item_lapineddukddak_script(struct map_session_data *sd, struct item_data *data, int oid) __attribute__((nonnull (1, 2))); + +/** + * Run item lapineddukddak script for item. + * + * @param sd player session data. Must be correct and checked before. + * @param data unequipped item data. Must be correct and checked before. + * @param oid npc id. Can be also 0 or fake npc id. + */ +static void script_run_item_lapineddukddak_script(struct map_session_data *sd, struct item_data *data, int oid) +{ + script->current_item_id = data->nameid; + script->run(data->lapineddukddak->script, 0, sd->bl.id, oid); + script->current_item_id = 0; +} + #define BUILDIN_DEF(x,args) { buildin_ ## x , #x , args, false } #define BUILDIN_DEF2(x,x2,args) { buildin_ ## x , x2 , args, false } #define BUILDIN_DEF_DEPRECATED(x,args) { buildin_ ## x , #x , args, true } @@ -26328,6 +26406,7 @@ static void script_parse_builtin(void) BUILDIN_DEF(mercenary_set_faith,"ii"), BUILDIN_DEF(readbook,"ii"), BUILDIN_DEF(setfont,"i"), + BUILDIN_DEF(getfont, ""), BUILDIN_DEF(areamobuseskill,"siiiiviiiii"), BUILDIN_DEF(progressbar,"si"), BUILDIN_DEF(progressbar_unit,"si?"), @@ -26507,6 +26586,7 @@ static void script_parse_builtin(void) BUILDIN_DEF(identify, "i"), BUILDIN_DEF(identifyidx, "i"), + BUILDIN_DEF(openlapineddukddakboxui, "i"), }; int i, len = ARRAYLENGTH(BUILDIN); RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up @@ -27080,6 +27160,11 @@ static void script_hardcoded_constants(void) script->set_constant("GUILD_ONLINE_VENDOR", GUILD_ONLINE_VENDOR, false, false); script->set_constant("GUILD_ONLINE_NO_VENDOR", GUILD_ONLINE_NO_VENDOR, false, false); + script->constdb_comment("Siege Types"); + script->set_constant("SIEGE_TYPE_FE", SIEGE_TYPE_FE, false, false); + script->set_constant("SIEGE_TYPE_SE", SIEGE_TYPE_SE, false, false); + script->set_constant("SIEGE_TYPE_TE", SIEGE_TYPE_TE, false, false); + script->constdb_comment("Renewal"); #ifdef RENEWAL script->set_constant("RENEWAL", 1, false, false); @@ -27440,4 +27525,7 @@ void script_defaults(void) script->run_use_script = script_run_use_script; script->run_item_equip_script = script_run_item_equip_script; script->run_item_unequip_script = script_run_item_unequip_script; + script->run_item_rental_start_script = script_run_item_rental_start_script; + script->run_item_rental_end_script = script_run_item_rental_end_script; + script->run_item_lapineddukddak_script = script_run_item_lapineddukddak_script; } diff --git a/src/map/script.h b/src/map/script.h index 5dc480a15..57652e77a 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -541,6 +541,16 @@ enum pcblock_action_flag { PCBLOCK_ALL = 0xFF, }; +/** + * Types of Siege (WoE) + */ +enum siege_type { + SIEGE_TYPE_FE, + SIEGE_TYPE_SE, + SIEGE_TYPE_TE, + SIEGE_TYPE_MAX +}; + /** * Structures **/ @@ -1039,6 +1049,9 @@ struct script_interface { void (*run_use_script) (struct map_session_data *sd, struct item_data *data, int oid); void (*run_item_equip_script) (struct map_session_data *sd, struct item_data *data, int oid); void (*run_item_unequip_script) (struct map_session_data *sd, struct item_data *data, int oid); + void (*run_item_rental_end_script) (struct map_session_data *sd, struct item_data *data, int oid); + void (*run_item_rental_start_script) (struct map_session_data *sd, struct item_data *data, int oid); + void (*run_item_lapineddukddak_script) (struct map_session_data *sd, struct item_data *data, int oid); }; #ifdef HERCULES_CORE diff --git a/src/map/skill.c b/src/map/skill.c index af61c887c..ad27ef0e3 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -82,7 +82,7 @@ #endif static struct skill_interface skill_s; -struct s_skill_dbs skilldbs; +static struct s_skill_dbs skilldbs; struct skill_interface *skill; @@ -8710,7 +8710,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * case AM_REST: if (sd) { - if (homun->vaporize(sd,HOM_ST_REST)) + if (homun->vaporize(sd, HOM_ST_REST, false)) clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); else clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0); diff --git a/src/map/status.c b/src/map/status.c index dedfff49e..728e72a9c 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -9084,7 +9084,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en if (sd->status.pet_id > 0) pet->menu(sd, 3); if (homun_alive(sd->hd)) - homun->vaporize(sd,HOM_ST_REST); + homun->vaporize(sd, HOM_ST_REST, true); if (sd->md) mercenary->delete(sd->md,3); } @@ -11820,10 +11820,10 @@ static int status_change_timer(int tid, int64 tick, int id, intptr_t data) case SC_SPLASHER: #if 0 // custom Venom Splasher countdown timer - if (sce->val4 % 1000 == 0) { + if (sce->val4 % 1000 == 0 && bl && bl->type == BL_PC) { char counter[10]; snprintf (counter, 10, "%d", sce->val4/1000); - clif->message(bl, counter); + clif->message(BL_UCCAST(BL_PC, bl)->fd, counter); } #endif // 0 if((sce->val4 -= 500) > 0) { @@ -13409,25 +13409,104 @@ static bool status_readdb_sizefix(char *fields[], int columns, int current) return true; } -static bool status_readdb_scconfig(char *fields[], int columns, int current) +static bool status_read_scdb_libconfig(void) { - int val = 0; - char* type = fields[0]; + struct config_t status_conf; + char filepath[256]; + safesnprintf(filepath, sizeof(filepath), "%s/%s", map->db_path, "sc_config.conf"); - nullpo_retr(false, fields); - if( !script->get_constant(type, &val) ){ - ShowWarning("status_readdb_sc_conf: Invalid status type %s specified.\n", type); + if (libconfig->load_file(&status_conf, filepath) == CONFIG_FALSE) { + ShowError("status_read_scdb_libconfig: can't read %s\n", filepath); return false; } - status->dbs->sc_conf[val] = (int)strtol(fields[1], NULL, 0); - if (status->dbs->sc_conf[val] & SC_VISIBLE) - { - status->dbs->DisplayType[val] = true; + int i = 0; + int count = 0; + struct config_setting_t *it = NULL; + + while ((it = libconfig->setting_get_elem(status_conf.root, i++)) != NULL) { + if (status->read_scdb_libconfig_sub(it, i - 1, filepath)) + ++count; + } + + libconfig->destroy(&status_conf); + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filepath); + return true; +} + +static bool status_read_scdb_libconfig_sub(struct config_setting_t *it, int idx, const char *source) +{ + nullpo_retr(false, it); + nullpo_retr(false, source); + + int i32; + const char *name = config_setting_name(it); + + if (!script->get_constant(name, &i32) || i32 <= SC_NONE || i32 >= SC_MAX) { + ShowWarning("status_read_scdb_libconfig_sub: Invalid status type (%s) in \"%s\" entry #%d, skipping.\n", name, source, idx); + return false; } + libconfig->setting_lookup_bool_real(it, "Visible", &status->dbs->DisplayType[i32]); + + struct config_setting_t *fg = libconfig->setting_get_member(it, "Flags"); + if (fg != NULL) + status->read_scdb_libconfig_sub_flag(fg, i32, source); + return true; } + +static bool status_read_scdb_libconfig_sub_flag(struct config_setting_t *it, int type, const char *source) +{ + nullpo_retr(false, it); + nullpo_retr(false, source); + Assert_retr(false, type > SC_NONE && type < SC_MAX); + + int i = 0; + struct config_setting_t *t = NULL; + while ((t = libconfig->setting_get_elem(it, i++)) != NULL) { + const char *flag = config_setting_name(t); + bool on = libconfig->setting_get_bool_real(t); + int j; + + struct { + const char *name; + enum sc_conf_type value; + } flags[] = { + { "NoDeathReset", SC_NO_REM_DEATH }, + { "NoSave", SC_NO_SAVE }, + { "NoDispelReset", SC_NO_DISPELL }, + { "NoClearanceReset", SC_NO_CLEARANCE }, + { "Buff", SC_BUFF }, + { "Debuff", SC_DEBUFF }, + { "NoMadoReset", SC_MADO_NO_RESET }, + { "NoAllReset", SC_NO_CLEAR } + }; + + ARR_FIND(0, ARRAYLENGTH(flags), j, strcmpi(flag, flags[j].name) == 0); + if (j != ARRAYLENGTH(flags)) { + if (strcmp(flag, flags[j].name) != 0) { + ShowWarning("status_read_scdb_libconfig_sub_flag: flag (%s) for status effect (%d) is casesensitive, correct it to (%s).", flag, type, flags[i].name); + } + if (on) { + status->dbs->sc_conf[type] |= flags[j].value; + } else { + status->dbs->sc_conf[type] &= ~flags[j].value; + } + } else { + if (!status->read_scdb_libconfig_sub_flag_additional(it, type, source)) + ShowWarning("status_read_scdb_libconfig_sub_flag: invalid flag (%s) for status effect (%d).", flag, type); + } + } + return true; +} + +static bool status_read_scdb_libconfig_sub_flag_additional(struct config_setting_t *it, int type, const char *source) +{ + // to be used by plugins + return false; +} + /** * Read status db * job1.txt @@ -13466,7 +13545,7 @@ static int status_readdb(void) // sv->readdb(map->db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, status->readdb_job2); sv->readdb(map->db_path, DBPATH"size_fix.txt", ',', MAX_SINGLE_WEAPON_TYPE, MAX_SINGLE_WEAPON_TYPE, ARRAYLENGTH(status->dbs->atkmods), status->readdb_sizefix); - sv->readdb(map->db_path, "sc_config.txt", ',', 2, 2, SC_MAX, status->readdb_scconfig); + status->read_scdb_libconfig(); status->read_job_db(); pc->validate_levels(); @@ -13656,7 +13735,10 @@ void status_defaults(void) status->natural_heal_timer = status_natural_heal_timer; status->readdb_job2 = status_readdb_job2; status->readdb_sizefix = status_readdb_sizefix; - status->readdb_scconfig = status_readdb_scconfig; + status->read_scdb_libconfig = status_read_scdb_libconfig; + status->read_scdb_libconfig_sub = status_read_scdb_libconfig_sub; + status->read_scdb_libconfig_sub_flag = status_read_scdb_libconfig_sub_flag; + status->read_scdb_libconfig_sub_flag_additional = status_read_scdb_libconfig_sub_flag_additional; status->read_job_db = status_read_job_db; status->read_job_db_sub = status_read_job_db_sub; status->set_sc = status_set_sc; diff --git a/src/map/status.h b/src/map/status.h index dc7629dea..536003d04 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -50,7 +50,7 @@ struct pet_data; /** * SC configuration type - * @see db/sc_config.txt for more information + * @see db/sc_config.conf for more information **/ typedef enum sc_conf_type { SC_NO_REM_DEATH = 0x001, @@ -2387,7 +2387,10 @@ struct status_interface { int (*natural_heal_timer) (int tid, int64 tick, int id, intptr_t data); bool (*readdb_job2) (char *fields[], int columns, int current); bool (*readdb_sizefix) (char *fields[], int columns, int current); - bool (*readdb_scconfig) (char *fields[], int columns, int current); + bool (*read_scdb_libconfig) (void); + bool (*read_scdb_libconfig_sub) (struct config_setting_t *it, int idx, const char *source); + bool (*read_scdb_libconfig_sub_flag) (struct config_setting_t *it, int type, const char *source); + bool (*read_scdb_libconfig_sub_flag_additional) (struct config_setting_t *it, int type, const char *source); void (*read_job_db) (void); void (*read_job_db_sub) (int idx, const char *name, struct config_setting_t *jdb); void (*set_sc) (uint16 skill_id, sc_type sc, int icon, unsigned int flag); -- cgit v1.2.3-60-g2f50