diff options
Diffstat (limited to 'src/map')
34 files changed, 813 insertions, 512 deletions
diff --git a/src/map/achievement.c b/src/map/achievement.c index 7ab80e183..c2ebb5fdd 100644 --- a/src/map/achievement.c +++ b/src/map/achievement.c @@ -1099,7 +1099,8 @@ static bool achievement_get_rewards(struct map_session_data *sd, const struct ac */ static void achievement_readdb_ranks(void) { - const char *filename = "db/achievement_rank_db.conf"; + char filename[256]; + libconfig->format_db_path("achievement_rank_db.conf", filename, sizeof(filename)); struct config_t ar_conf = { 0 }; struct config_setting_t *ardb = NULL, *conf = NULL; int entry = 0; @@ -1777,7 +1778,8 @@ static void achievement_readdb_additional_fields(const struct config_setting_t * */ static void achievement_readb(void) { - const char *filename = "db/"DBPATH"achievement_db.conf"; + char filename[256]; + libconfig->format_db_path(DBPATH"achievement_db.conf", filename, sizeof(filename)); struct config_t ach_conf = { 0 }; struct config_setting_t *achdb = NULL, *conf = NULL; int entry = 0, count = 0; diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 145a5c95d..f57583cfc 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -5369,7 +5369,6 @@ ACMD(follow) ACMD(dropall) { int type = -1; - int count = 0; if (message[0] != '\0') { type = atoi(message); @@ -5380,25 +5379,32 @@ ACMD(dropall) } } + int count = 0, count_skipped = 0; for (int i = 0; i < sd->status.inventorySize; i++) { - if (sd->status.inventory[i].amount) { + if (sd->status.inventory[i].amount > 0) { struct item_data *item_data = itemdb->exists(sd->status.inventory[i].nameid); if (item_data == NULL) { ShowWarning("Non-existant item %d on dropall list (account_id: %d, char_id: %d)\n", sd->status.inventory[i].nameid, sd->status.account_id, sd->status.char_id); continue; } + if (!pc->candrop(sd, &sd->status.inventory[i])) continue; + if (type == -1 || type == item_data->type) { if (sd->status.inventory[i].equip != 0) pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC | PCUNEQUIPITEM_FORCE); - count += sd->status.inventory[i].amount; - pc->dropitem(sd, i, sd->status.inventory[i].amount); + + int amount = sd->status.inventory[i].amount; + if (pc->dropitem(sd, i, amount) != 0) + count += amount; + else + count_skipped += amount; } } } - sprintf(atcmd_output, msg_fd(fd, 1502), count); // %d items are dropped! + sprintf(atcmd_output, msg_fd(fd, 1502), count, count_skipped); // %d items are dropped (%d skipped)! clif->message(fd, atcmd_output); return true; } diff --git a/src/map/battle.c b/src/map/battle.c index 37fc03bca..7fb5355e6 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -3467,11 +3467,6 @@ static int64 battle_calc_gvg_damage(struct block_list *src, struct block_list *b case NC_SELFDESTRUCTION: break; default: - /* Uncomment if you want god-mode Emperiums at 100 defense. [Kisuka] - if (md && md->guardian_data) { - damage -= damage * (md->guardian_data->castle->defense/100) * battle_config.castle_defense_rate/100; - } - */ break; } return damage; @@ -4343,7 +4338,7 @@ static struct Damage battle_calc_misc_attack(struct block_list *src, struct bloc } break; } - + battle->reflect_trap(target, src, &md, skill_id); return md; @@ -7188,7 +7183,6 @@ static const struct battle_data { { "skill_removetrap_type", &battle_config.skill_removetrap_type, 0, 0, 1, }, { "disp_experience", &battle_config.disp_experience, 0, 0, 1, }, { "disp_zeny", &battle_config.disp_zeny, 0, 0, 1, }, - { "castle_defense_rate", &battle_config.castle_defense_rate, 100, 0, 100, }, { "bone_drop", &battle_config.bone_drop, 0, 0, 2, }, { "buyer_name", &battle_config.buyer_name, 1, 0, 1, }, { "skill_wall_check", &battle_config.skill_wall_check, 1, 0, 1, }, @@ -7321,6 +7315,7 @@ static const struct battle_data { { "mob_remove_delay", &battle_config.mob_remove_delay, 60000, 1000, INT_MAX, }, { "mob_active_time", &battle_config.mob_active_time, 0, 0, INT_MAX, }, { "boss_active_time", &battle_config.boss_active_time, 0, 0, INT_MAX, }, + { "slave_chase_masters_chasetarget", &battle_config.slave_chase_masters_chasetarget, 1, 0, 1, }, { "sg_miracle_skill_duration", &battle_config.sg_miracle_skill_duration, 3600000, 0, INT_MAX, }, { "hvan_explosion_intimate", &battle_config.hvan_explosion_intimate, 45000, 0, 100000, }, { "quest_exp_rate", &battle_config.quest_exp_rate, 100, 0, INT_MAX, }, diff --git a/src/map/battle.h b/src/map/battle.h index 4400d37d1..dd6265b1e 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -342,7 +342,6 @@ struct Battle_Config { int skill_removetrap_type; int disp_experience; int disp_zeny; - int castle_defense_rate; int backstab_bow_penalty; int hp_rate; int sp_rate; @@ -405,6 +404,7 @@ struct Battle_Config { int mob_remove_delay; // Dynamic Mobs - delay before removing mobs from a map [Skotlex] int mob_active_time; //Duration through which mobs execute their Hard AI after players leave their area of sight. int boss_active_time; + int slave_chase_masters_chasetarget; int show_hp_sp_drain, show_hp_sp_gain; //[Skotlex] int show_katar_crit_bonus; diff --git a/src/map/battleground.c b/src/map/battleground.c index c2772a2b9..e0d2e8003 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -169,13 +169,13 @@ static int bg_team_leave(struct map_session_data *sd, enum bg_team_leave_type fl switch (flag) { default: case BGTL_QUIT: - sprintf(output, "Server : %s has quit the game...", sd->status.name); + sprintf(output, msg_txt(464), sd->status.name); // Server : %s has quit the game... break; case BGTL_LEFT: - sprintf(output, "Server : %s is leaving the battlefield...", sd->status.name); + sprintf(output, msg_txt(454), sd->status.name); // Server : %s is leaving the battlefield... break; case BGTL_AFK: - sprintf(output, "Server : %s has been afk-kicked from the battlefield...", sd->status.name); + sprintf(output, msg_txt(455), sd->status.name); // Server : %s has been afk-kicked from the battlefield... break; } clif->bg_message(bgd, 0, "Server", output); @@ -860,9 +860,9 @@ static enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, str if ( ( tick = pc_readglobalreg(sd, script->add_variable(bg->gdelay_var)) ) && tsec < tick ) { char response[100]; if( (tick-tsec) > 60 ) - sprintf(response, "You are a deserter! Wait %u minute(s) before you can apply again", (tick - tsec) / 60); + sprintf(response, msg_sd(sd, 456), (tick - tsec) / 60); // You are a deserter! Wait %u minute(s) before you can apply again else - sprintf(response, "You are a deserter! Wait %u seconds before you can apply again", (tick - tsec)); + sprintf(response, msg_sd(sd, 457), (tick - tsec)); // You are a deserter! Wait %u seconds before you can apply again clif->messagecolor_self(sd->fd, COLOR_RED, response); return BGQA_FAIL_DESERTER; } @@ -870,9 +870,9 @@ static enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, str if ( ( tick = pc_readglobalreg(sd, script->add_variable(arena->delay_var)) ) && tsec < tick ) { char response[100]; if( (tick-tsec) > 60 ) - sprintf(response, "You can't reapply to this arena so fast. Apply to the different arena or wait %u minute(s)", (tick - tsec) / 60); + sprintf(response, msg_sd(sd, 458), (tick - tsec) / 60); // You can't reapply to this arena so fast. Apply to the different arena or wait %u minute(s) else - sprintf(response, "You can't reapply to this arena so fast. Apply to the different arena or wait %u seconds", (tick - tsec)); + sprintf(response, msg_sd(sd, 459), (tick - tsec)); // You can't reapply to this arena so fast. Apply to the different arena or wait %u seconds clif->messagecolor_self(sd->fd, COLOR_RED, response); return BGQA_FAIL_COOLDOWN; } @@ -894,9 +894,9 @@ static enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, str if ( count < arena->min_team_players ) { char response[121]; if( count != sd->guild->connect_member && sd->guild->connect_member >= arena->min_team_players ) - sprintf(response, "Can't apply: not enough members in your team/guild that have not entered the queue in individual mode, minimum is %d", arena->min_team_players); + sprintf(response, msg_sd(sd, 460), arena->min_team_players); // Can't apply: not enough members in your team/guild that have not entered the queue in individual mode, minimum is %d else - sprintf(response, "Can't apply: not enough members in your team/guild, minimum is %d", arena->min_team_players); + sprintf(response, msg_sd(sd, 461), arena->min_team_players); // Can't apply: not enough members in your team/guild, minimum is %d clif->messagecolor_self(sd->fd, COLOR_RED, response); return BGQA_FAIL_TEAM_COUNT; } @@ -926,9 +926,9 @@ static enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, str if( count < arena->min_team_players ) { char response[121]; if( count != p->party.count && p->party.count >= arena->min_team_players ) - sprintf(response, "Can't apply: not enough members in your team/party that have not entered the queue in individual mode, minimum is %d", arena->min_team_players); + sprintf(response, msg_sd(sd, 462), arena->min_team_players); // Can't apply: not enough members in your team/party that have not entered the queue in individual mode, minimum is %d else - sprintf(response, "Can't apply: not enough members in your team/party, minimum is %d",arena->min_team_players); + sprintf(response, msg_sd(sd, 463), arena->min_team_players); // Can't apply: not enough members in your team/party, minimum is %d clif->messagecolor_self(sd->fd, COLOR_RED, response); return BGQA_FAIL_TEAM_COUNT; } diff --git a/src/map/channel.c b/src/map/channel.c index e27e9fb0b..c87e425eb 100644 --- a/src/map/channel.c +++ b/src/map/channel.c @@ -324,7 +324,7 @@ static void channel_join_sub(struct channel_data *chan, struct map_session_data if (!stealth && (chan->options&HCS_OPT_ANNOUNCE_JOIN)) { char message[60]; - sprintf(message, "#%s '%s' joined",chan->name,sd->status.name); + sprintf(message, msg_txt(897), chan->name, sd->status.name); // #%s '%s' joined clif->channel_msg(chan,sd,message); } @@ -442,7 +442,7 @@ static void channel_leave(struct channel_data *chan, struct map_session_data *sd channel->delete(chan); } else if (!channel->config->closing && (chan->options & HCS_OPT_ANNOUNCE_JOIN)) { char message[60]; - sprintf(message, "#%s '%s' left",chan->name,sd->status.name); + sprintf(message, msg_txt(898), chan->name, sd->status.name); // #%s '%s' left clif->channel_msg(chan,sd,message); } diff --git a/src/map/chrif.c b/src/map/chrif.c index a3277d4c2..ddc106d0c 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -1226,6 +1226,7 @@ static bool chrif_save_scdata(struct map_session_data *sd) } else { data.tick = INFINITE_DURATION; } + data.total_tick = sc->data[i]->total_tick; data.type = i; data.val1 = sc->data[i]->val1; data.val2 = sc->data[i]->val2; @@ -1273,8 +1274,8 @@ static bool chrif_load_scdata(int fd) for (i = 0; i < count; i++) { const struct status_change_data *data = RFIFOP(fd,14 + i*sizeof(struct status_change_data)); - status->change_start(NULL, &sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, - data->tick, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_LOADED|SCFLAG_FIXEDRATE); + status->change_start_sub(NULL, &sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, + data->tick, data->total_tick, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_LOADED|SCFLAG_FIXEDRATE); } pc->scdata_received(sd); diff --git a/src/map/clif.c b/src/map/clif.c index f6caa502e..9f30408e4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -2935,10 +2935,10 @@ static void clif_inventoryStart(struct map_session_data *sd, enum inventory_type nullpo_retv(sd); nullpo_retv(name); - char buf[sizeof(struct ZC_INVENTORY_START) + 24]; + char buf[sizeof(struct PACKET_ZC_INVENTORY_START) + 24]; memset(buf, 0, sizeof(buf)); - struct ZC_INVENTORY_START *p = (struct ZC_INVENTORY_START *)buf; - p->packetType = 0xb08; + struct PACKET_ZC_INVENTORY_START *p = (struct PACKET_ZC_INVENTORY_START *)buf; + p->packetType = HEADER_ZC_INVENTORY_START; #if PACKETVER_RE_NUM >= 20180912 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002 p->invType = type; #endif @@ -2946,11 +2946,11 @@ static void clif_inventoryStart(struct map_session_data *sd, enum inventory_type int strLen = (int)safestrnlen(name, 24) + 1; if (strLen > 24) strLen = 24; - const int len = sizeof(struct ZC_INVENTORY_START) + strLen; + const int len = sizeof(struct PACKET_ZC_INVENTORY_START) + strLen; p->packetLength = len; safestrncpy(p->name, name, strLen); #else - const int len = sizeof(struct ZC_INVENTORY_START); + const int len = sizeof(struct PACKET_ZC_INVENTORY_START); safestrncpy(p->name, name, NAME_LENGTH); #endif clif->send(p, len, &sd->bl, SELF); @@ -2962,8 +2962,8 @@ static void clif_inventoryEnd(struct map_session_data *sd, enum inventory_type t #if PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002 nullpo_retv(sd); - struct ZC_INVENTORY_END p; - p.packetType = 0xb0b; + struct PACKET_ZC_INVENTORY_END p; + p.packetType = HEADER_ZC_INVENTORY_END; #if PACKETVER_RE_NUM >= 20180912 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002 p.invType = type; #endif @@ -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 +#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190918 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 +#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190918 p->level2 = skill_lv; #endif if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) @@ -5899,7 +5899,7 @@ static void clif_skill_estimation(struct map_session_data *sd, struct block_list { struct status_data *dstatus; unsigned char buf[64]; - int i;//, fix; + int i, fix; nullpo_retv(sd); nullpo_retv(dst); @@ -5921,9 +5921,9 @@ static void clif_skill_estimation(struct map_session_data *sd, struct block_list + ((battle_config.estimation_type&2) ? dstatus->mdef2 : 0); WBUFW(buf,18) = dstatus->def_ele; for(i=0;i<9;i++) { - WBUFB(buf,20+i)= (unsigned char)battle->attr_ratio(i+1,dstatus->def_ele, dstatus->ele_lv); + // WBUFB(buf,20+i)= (unsigned char)battle->attr_ratio(i+1,dstatus->def_ele, dstatus->ele_lv); // The following caps negative attributes to 0 since the client displays them as 255-fix. [Skotlex] - //WBUFB(buf,20+i)= (unsigned char)((fix=battle->attr_ratio(i+1,dstatus->def_ele, dstatus->ele_lv))<0?0:fix); + WBUFB(buf,20+i)= (unsigned char)((fix=battle->attr_ratio(i+1,dstatus->def_ele, dstatus->ele_lv))<0?0:fix); } clif->send(buf,packet_len(0x18c),&sd->bl,sd->status.party_id>0?PARTY_SAMEMAP:SELF); @@ -6041,7 +6041,7 @@ static void clif_cooking_list(struct map_session_data *sd, int trigger, uint16 s } } -static void clif_status_change_notick(struct block_list *bl, int type, int flag, int tick, int val1, int val2, int val3) +static void clif_status_change_notick(struct block_list *bl, int type, int flag, int tick, int total_tick, int val1, int val2, int val3) { struct packet_sc_notick p; struct map_session_data *sd; @@ -6070,7 +6070,7 @@ static void clif_status_change_notick(struct block_list *bl, int type, int flag, /// 08ff <id>.L <index>.W <remain msec>.L { <val>.L }*3 (PACKETVER >= 20111108) /// 0983 <index>.W <id>.L <state>.B <total msec>.L <remain msec>.L { <val>.L }*3 (PACKETVER >= 20120618) /// 0984 <id>.L <index>.W <total msec>.L <remain msec>.L { <val>.L }*3 (PACKETVER >= 20120618) -static void clif_status_change(struct block_list *bl, int type, int flag, int tick, int val1, int val2, int val3) +static void clif_status_change_sub(struct block_list *bl, int type, int flag, int tick, int total_tick, int val1, int val2, int val3) { struct packet_status_change p; struct map_session_data *sd; @@ -6094,7 +6094,7 @@ static void clif_status_change(struct block_list *bl, int type, int flag, int ti p.state = (unsigned char)flag; #if PACKETVER >= 20120618 - p.Total = tick; /* at this stage remain and total are the same value I believe */ + p.Total = total_tick; #endif #if PACKETVER >= 20090121 p.Left = tick; @@ -6105,6 +6105,13 @@ static void clif_status_change(struct block_list *bl, int type, int flag, int ti clif->send(&p,sizeof(p), bl, (sd && sd->status.option&OPTION_INVISIBLE) ? SELF : AREA); } +/// Notifies clients of a status change. +/// @see clif_status_change_sub +static void clif_status_change(struct block_list *bl, int type, int flag, int total_tick, int val1, int val2, int val3) +{ + clif->status_change_sub(bl, type, flag, total_tick, total_tick, val1, val2, val3); +} + /// Send message (modified by [Yor]) (ZC_NOTIFY_PLAYERCHAT). /// 008e <packet len>.W <message>.?B static void clif_displaymessage(const int fd, const char *mes) @@ -10769,7 +10776,7 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) if( map->list[sd->bl.m].flag.allowks && !map_flag_ks(sd->bl.m) ) { char output[128]; - sprintf(output, "[ Kill Steal Protection Disabled. KS is allowed in this map ]"); + sprintf(output, "%s", msg_sd(sd, 893)); // [ Kill Steal Protection Disabled. KS is allowed in this map ] clif->broadcast(&sd->bl, output, (int)strlen(output) + 1, BC_BLUE, SELF); } @@ -11664,7 +11671,7 @@ static void clif_parse_WisMessage(int fd, struct map_session_data *sd) // if player is autotrading if (dstsd->state.autotrade) { char output[256]; - sprintf(output, "%s is in autotrade mode and cannot receive whispered messages.", dstsd->status.name); + sprintf(output, msg_fd(fd, 894), dstsd->status.name); // %s is in autotrade mode and cannot receive whispered messages. clif->wis_message(fd, map->wisp_server_name, output, (int)strlen(output)); return; } @@ -14298,7 +14305,7 @@ static void clif_parse_CloseVending(int fd, struct map_session_data *sd) __attri /// 012e static void clif_parse_CloseVending(int fd, struct map_session_data *sd) { - if (pc_istrading(sd) || pc_isdead(sd)) + if (sd->npc_id || sd->state.buyingstore || sd->state.trading) return; vending->close(sd); @@ -16091,7 +16098,10 @@ static void clif_ranklist(struct map_session_data *sd, enum fame_list_type type) p->packetType = HEADER_ZC_ACK_RANKING; p->rankType = type; #if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190703 || PACKETVER_ZERO_NUM >= 20190724 +PRAGMA_GCC9(GCC diagnostic push) +PRAGMA_GCC9(GCC diagnostic ignored "-Waddress-of-packed-member") clif->ranklist_sub2(p->chars, p->points, type); +PRAGMA_GCC9(GCC diagnostic pop) #else clif->ranklist_sub(&p->ranks, type); #endif @@ -16683,7 +16693,7 @@ static void clif_Mail_refreshinbox(struct map_session_data *sd) if( md->full ) {// TODO: is this official? char output[100]; - sprintf(output, "Inbox is full (Max %d). Delete some mails.", MAIL_MAX_INBOX); + sprintf(output, msg_sd(sd, 511), MAIL_MAX_INBOX); // Inbox is full (Max %d). Delete some mails. clif_disp_onlyself(sd, output); } } @@ -19784,7 +19794,8 @@ static void clif_cashshop_db(void) { struct config_t cashshop_conf; struct config_setting_t *cashshop = NULL, *cats = NULL; - const char *config_filename = "db/cashshop_db.conf"; // FIXME hardcoded name + char config_filename[256]; + libconfig->format_db_path("cashshop_db.conf", config_filename, sizeof(config_filename)); int i, item_count_t = 0; for( i = 0; i < CASHSHOP_TAB_MAX; i++ ) { CREATE(clif->cs.data[i], struct hCSData *, 1); @@ -20599,7 +20610,7 @@ static void clif_show_modifiers(struct map_session_data *sd) if( sd->status.mod_exp != 100 || sd->status.mod_drop != 100 || sd->status.mod_death != 100 ) { char output[128]; - snprintf(output,128,"Base EXP : %d%% | Base Drop: %d%% | Base Death Penalty: %d%%", + snprintf(output,128, msg_sd(sd, 896), // Base EXP : %d%% | Base Drop: %d%% | Base Death Penalty: %d%% sd->status.mod_exp,sd->status.mod_drop,sd->status.mod_death); clif->broadcast2(&sd->bl, output, (int)strlen(output) + 1, 0xffbc90, 0x190, 12, 0, 0, SELF); } @@ -21055,7 +21066,8 @@ static bool clif_parse_roulette_db(void) { struct config_t roulette_conf; struct config_setting_t *roulette = NULL, *levels = NULL; - const char *config_filename = "db/roulette_db.conf"; // FIXME hardcoded name + char config_filename[256]; + libconfig->format_db_path("roulette_db.conf", config_filename, sizeof(config_filename)); int i, j, item_count_t = 0; for( i = 0; i < MAX_ROULETTE_LEVEL; i++ ) { @@ -22539,7 +22551,8 @@ static bool clif_parse_attendance_db(void) { struct config_t attendance_conf; struct config_setting_t *attendance = NULL, *it = NULL; - const char *config_filename = "db/attendance_db.conf"; // FIXME hardcoded name + char config_filename[256]; + libconfig->format_db_path("attendance_db.conf", config_filename, sizeof(config_filename)); int i = 0; if (!libconfig->load_file(&attendance_conf, config_filename)) @@ -23676,9 +23689,9 @@ static void packetdb_loaddb(void) static void clif_bc_ready(void) { if( battle_config.display_status_timers ) - clif->status_change = clif_status_change; + clif->status_change_sub = clif_status_change_sub; else - clif->status_change = clif_status_change_notick; + clif->status_change_sub = clif_status_change_notick; switch( battle_config.packet_obfuscation ) { case 0: @@ -23896,6 +23909,7 @@ void clif_defaults(void) clif->autospell = clif_autospell; clif->combo_delay = clif_combo_delay; clif->status_change = clif_status_change; + clif->status_change_sub = clif_status_change_sub; clif->insert_card = clif_insert_card; clif->inventoryList = clif_inventoryList; clif->inventoryItems = clif_inventoryItems; diff --git a/src/map/clif.h b/src/map/clif.h index 4bc3abdeb..0dfc00c01 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -902,7 +902,8 @@ struct clif_interface { void (*cooking_list) (struct map_session_data *sd, int trigger, uint16 skill_id, int qty, int list_type); void (*autospell) (struct map_session_data *sd,uint16 skill_lv); void (*combo_delay) (struct block_list *bl,int wait); - void (*status_change) (struct block_list *bl,int type,int flag,int tick,int val1, int val2, int val3); + void (*status_change) (struct block_list *bl, int type, int flag, int total_tick, int val1, int val2, int val3); + void (*status_change_sub) (struct block_list *bl, int type, int flag, int tick, int total_tick, int val1, int val2, int val3); void (*insert_card) (struct map_session_data *sd,int idx_equip,int idx_card,int flag); void (*inventoryList) (struct map_session_data *sd); void (*inventoryItems) (struct map_session_data *sd, enum inventory_type type); diff --git a/src/map/guild.c b/src/map/guild.c index 2faf60e2b..dbfe03d3e 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -152,7 +152,8 @@ static bool guild_read_castledb_libconfig(void) { struct config_t castle_conf; struct config_setting_t *castle_db = NULL, *it = NULL; - const char *config_filename = "db/castle_db.conf"; // FIXME hardcoded name + char config_filename[256]; + libconfig->format_db_path("castle_db.conf", config_filename, sizeof(config_filename)); int i = 0; if (libconfig->load_file(&castle_conf, config_filename) == 0) @@ -565,6 +566,7 @@ static int guild_check_member(const struct guild *g) if (i == INDEX_NOT_FOUND) { sd->status.guild_id=0; sd->guild_emblem_id=0; + sd->guild = NULL; ShowWarning("guild: check_member %d[%s] is not member\n",sd->status.account_id,sd->status.name); } } @@ -581,8 +583,11 @@ static int guild_recv_noinfo(int guild_id) iter = mapit_getallusers(); for (sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { - if( sd->status.guild_id == guild_id ) + if (sd->status.guild_id == guild_id) { sd->status.guild_id = 0; // erase guild + sd->guild_emblem_id = 0; + sd->guild = NULL; + } } mapit->free(iter); @@ -872,6 +877,8 @@ static void guild_member_joined(struct map_session_data *sd) i = guild->getindex(g, sd->status.account_id, sd->status.char_id); if (i == INDEX_NOT_FOUND) { sd->status.guild_id = 0; + sd->guild_emblem_id = 0; + sd->guild = NULL; } else { g->member[i].sd = sd; sd->guild = g; diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 43cb8d84b..fbb94334c 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -401,7 +401,7 @@ static bool homunculus_levelup(struct homun_data *hd) if ( battle_config.homunculus_show_growth ) { char output[256] ; sprintf(output, - "Growth: hp:%d sp:%d str(%.2f) agi(%.2f) vit(%.2f) int(%.2f) dex(%.2f) luk(%.2f) ", + msg_sd(hd->master, 892), // Growth: hp:%d sp:%d str(%.2f) agi(%.2f) vit(%.2f) int(%.2f) dex(%.2f) luk(%.2f) growth_max_hp, growth_max_sp, growth_str/10.0, growth_agi/10.0, growth_vit/10.0, growth_int/10.0, growth_dex/10.0, growth_luk/10.0); diff --git a/src/map/irc-bot.c b/src/map/irc-bot.c index 996107fea..a0c7276a9 100644 --- a/src/map/irc-bot.c +++ b/src/map/irc-bot.c @@ -396,7 +396,7 @@ static void irc_userjoin(int fd, char *cmd, char *source, char *target, char *ms ircbot->parse_source(source,source_nick,source_ident,source_host); if( ircbot->channel ) { - snprintf(send_string, 150, "[ #%s ] User IRC.%s joined the channel.",ircbot->channel->name,source_nick); + snprintf(send_string, 150, msg_txt(468), ircbot->channel->name, source_nick); // [ #%s ] User IRC.%s joined the channel. clif->channel_msg2(ircbot->channel,send_string); } } @@ -414,9 +414,9 @@ static void irc_userleave(int fd, char *cmd, char *source, char *target, char *m if( ircbot->channel ) { if (!strcmpi(cmd, "QUIT")) - snprintf(send_string, 150, "[ #%s ] User IRC.%s left the channel. [Quit: %s]",ircbot->channel->name,source_nick,msg); + snprintf(send_string, 150, msg_txt(465), ircbot->channel->name, source_nick, msg); // [ #%s ] User IRC.%s left the channel. [Quit: %s] else - snprintf(send_string, 150, "[ #%s ] User IRC.%s left the channel. [%s]",ircbot->channel->name,source_nick,msg); + snprintf(send_string, 150, msg_txt(466), ircbot->channel->name, source_nick, msg); // [ #%s ] User IRC.%s left the channel. [%s] clif->channel_msg2(ircbot->channel,send_string); } } @@ -433,7 +433,7 @@ static void irc_usernick(int fd, char *cmd, char *source, char *target, char *ms ircbot->parse_source(source,source_nick,source_ident,source_host); if( ircbot->channel ) { - snprintf(send_string, 150, "[ #%s ] User IRC.%s is now known as IRC.%s",ircbot->channel->name,source_nick,msg); + snprintf(send_string, 150, msg_txt(467), ircbot->channel->name, source_nick, msg); // [ #%s ] User IRC.%s is now known as IRC.%s clif->channel_msg2(ircbot->channel,send_string); } } diff --git a/src/map/itemdb.c b/src/map/itemdb.c index a97325e57..5dc3d9317 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -846,11 +846,8 @@ static void itemdb_read_groups(void) { struct config_t item_group_conf; struct config_setting_t *itg = NULL, *it = NULL; -#ifdef RENEWAL - const char *config_filename = "db/re/item_group.conf"; // FIXME hardcoded name -#else - const char *config_filename = "db/pre-re/item_group.conf"; // FIXME hardcoded name -#endif + char config_filename[256]; + libconfig->format_db_path(DBPATH"item_group.conf", config_filename, sizeof(config_filename)); const char *itname; int i = 0, count = 0, c; unsigned int *gsize = NULL; @@ -1144,11 +1141,8 @@ static void itemdb_read_packages(void) { struct config_t item_packages_conf; struct config_setting_t *itg = NULL, *it = NULL, *t = NULL; -#ifdef RENEWAL - const char *config_filename = "db/re/item_packages.conf"; // FIXME hardcoded name -#else - const char *config_filename = "db/pre-re/item_packages.conf"; // FIXME hardcoded name -#endif + char config_filename[256]; + libconfig->format_db_path(DBPATH"item_packages.conf", config_filename, sizeof(config_filename)); const char *itname; int i = 0, count = 0, c = 0, highest_gcount = 0; unsigned int *must = NULL, *random = NULL, *rgroup = NULL, **rgroups = NULL; @@ -1393,7 +1387,8 @@ static void itemdb_read_options(void) struct config_t item_options_db; struct config_setting_t *ito = NULL, *conf = NULL; int index = 0, count = 0; - const char *filepath = "db/item_options.conf"; + char filepath[256]; + libconfig->format_db_path("item_options.conf", filepath, sizeof(filepath)); VECTOR_DECL(int) duplicate_id; if (!libconfig->load_file(&item_options_db, filepath)) @@ -1494,11 +1489,8 @@ static void itemdb_read_chains(void) { struct config_t item_chain_conf; struct config_setting_t *itc = NULL; -#ifdef RENEWAL - const char *config_filename = "db/re/item_chain.conf"; // FIXME hardcoded name -#else - const char *config_filename = "db/pre-re/item_chain.conf"; // FIXME hardcoded name -#endif + char config_filename[256]; + libconfig->format_db_path(DBPATH"item_chain.conf", config_filename, sizeof(config_filename)); int i = 0, count = 0; if (!libconfig->load_file(&item_chain_conf, config_filename)) diff --git a/src/map/map.c b/src/map/map.c index 332bbe75f..50ad9a5cd 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -45,7 +45,6 @@ #include "map/mapreg.h" #include "map/mercenary.h" #include "map/mob.h" -#include "map/npc.h" #include "map/npc.h" // npc_setcells(), npc_unsetcells() #include "map/party.h" #include "map/path.h" @@ -4055,6 +4054,7 @@ static bool map_config_read_database(const char *filename, struct config_t *conf return false; } libconfig->setting_lookup_mutable_string(setting, "db_path", map->db_path, sizeof(map->db_path)); + libconfig->set_db_path(map->db_path); libconfig->setting_lookup_int(setting, "save_settings", &map->save_settings); if (libconfig->setting_lookup_int(setting, "autosave_time", &map->autosave_interval) == CONFIG_TRUE) { @@ -5574,12 +5574,8 @@ static void read_map_zone_db(void) { struct config_t map_zone_db; struct config_setting_t *zones = NULL; - /* TODO: #ifndef required for re/pre-re */ -#ifdef RENEWAL - const char *config_filename = "db/re/map_zone_db.conf"; // FIXME hardcoded name -#else - const char *config_filename = "db/pre-re/map_zone_db.conf"; // FIXME hardcoded name -#endif + char config_filename[256]; + libconfig->format_db_path(DBPATH"map_zone_db.conf", config_filename, sizeof(config_filename)); if (!libconfig->load_file(&map_zone_db, config_filename)) return; @@ -6305,6 +6301,7 @@ static CPCMD(gm_position) map->cpsd->bl.x = x; map->cpsd->bl.y = y; map->cpsd->bl.m = m; + map->cpsd->mapindex = map_id2index(m); } static CPCMD(gm_use) { @@ -6333,6 +6330,8 @@ static void map_cp_defaults(void) map->cpsd->bl.x = mapindex->default_x; map->cpsd->bl.y = mapindex->default_y; map->cpsd->bl.m = map->mapname2mapid(mapindex->default_map); + Assert_retv(map->cpsd->bl.m >= 0); + map->cpsd->mapindex = map_id2index(map->cpsd->bl.m); console->input->addCommand("gm:info",CPCMD_A(gm_position)); console->input->addCommand("gm:use",CPCMD_A(gm_use)); @@ -6774,6 +6773,7 @@ void map_defaults(void) map->extra_scripts_count = 0; sprintf(map->db_path ,"db"); + libconfig->set_db_path(map->db_path); sprintf(map->help_txt ,"conf/help.txt"); sprintf(map->charhelp_txt ,"conf/charhelp.txt"); @@ -6835,7 +6835,10 @@ void map_defaults(void) map->bl_list_size = 0; //all in a big chunk, respects order +PRAGMA_GCC9(GCC diagnostic push) +PRAGMA_GCC9(GCC diagnostic ignored "-Warray-bounds") memset(ZEROED_BLOCK_POS(map), 0, ZEROED_BLOCK_SIZE(map)); +PRAGMA_GCC9(GCC diagnostic pop) map->cpsd = NULL; map->list = NULL; diff --git a/src/map/messages_main.h b/src/map/messages_main.h index 1ef24d6ab..69fc34ee9 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: 20190918 +Latest version: 20191016 */ enum clif_messages { @@ -759,7 +759,7 @@ Congratulations! You are the MVP! Your reward item is MSG_YOU_RECEIVE_MVP_ITEM = 0x8f, /*20031028 to latest !! -!! +! */ MSG_YOU_RECEIVE_MVP_ITEM2 = 0x90, /*20031028 to latest @@ -4013,7 +4013,6 @@ Mouse wheel skills for F7 and F8 are Disabled.[/q2 OFF] MSG_EXPLAIN_QUICKSPELL2 = 0x302, /*20040112 to latest /q3 : /quickspell (/q1) + /quickspell2 (/q2) -/q3: /quickspell (/q1) + /quickspell2 (/q2) */ MSG_EXPLAIN_QUICKSPELL3 = 0x303, #endif @@ -5264,7 +5263,7 @@ High Wizard MSG_WIZARD_H = 0x3da, /*20050613 to latest White Smith -WhiteSmith +MasterSmith */ MSG_BLACKSMITH_H = 0x3db, /*20050613 to latest @@ -7082,7 +7081,6 @@ Quest List #if PACKETVER >= 20070807 /*20070807 to latest RO SHOP -RO Shop */ MSG_RO_SHOP = 0x526, #endif @@ -10960,7 +10958,6 @@ ITEM MSG_MACRO_SKILL = 0x775, /*20110228 to 20110228 Next attack time : -Next attack time: 20110308 to latest TACTIC 20130807 to 20130814 @@ -10977,6 +10974,7 @@ TACTIC MSG_MACRO_ETC = 0x777, /*20110228 to 20110228 When invited to a party +When invited to the party 20110308 to latest COMBAT 20130807 to 20130814 @@ -11021,7 +11019,6 @@ ATTACK MSG_MACRO_ATTACK = 0x77d, /*20110308 to latest Next attack time : -Next attack time: 20130807 to 20130814 ATTACK */ @@ -11030,11 +11027,11 @@ ATTACK When died 20130807 to 20130814 Next attack time : -Next attack time: */ MSG_MACRO_WHEN_DIED = 0x77f, /*20110308 to latest When invited to a party +When invited to the party 20130807 to 20130814 When died */ @@ -11043,6 +11040,7 @@ When died Pickup Item 20130807 to 20130814 When invited to a party +When invited to the party */ MSG_MACRO_PICKUP_ITEM = 0x781, /*20110308 to latest @@ -11072,7 +11070,6 @@ Any work in progress (NPC dialog, manufacturing ...) quit and try again. ExMacro_SaveData%d 20110412 to latest SaveData_ExMacro%d -SaveData_ExMacro %d 20130807 to 20130814 몬스터 사냥을 통해 얻을 수 있는 Job경험치가 %d분간 %.2f배로 증가합니다. Monster Job hunting experience that you can get through the doubling of %d is %.2f minutes. @@ -11083,7 +11080,6 @@ Monster Job hunting experience that you can get through the doubling of %d is %. Settings for [%s] are stored in. 20130807 to 20130814 SaveData_ExMacro%d -SaveData_ExMacro %d */ MSG_MACRO_SAVE_DATA2 = 0x786, #endif @@ -11351,57 +11347,44 @@ Current location of the shop and chat room creation is disabled. MSG_REPLAY_ELAPSEDTIME = 0x7a3, /*20110816 to latest Speed : X 1/4 -Speed: X 1/4 20130807 to 20130814 Elapsed time: %d:%d:%d / %d:%d:%d */ MSG_REPLAY_SPEED1_4 = 0x7a4, /*20110816 to latest Speed : X 1/2 -Speed: X 1/2 20130807 to 20130814 Speed : X 1/4 -Speed: X 1/4 */ MSG_REPLAY_SPEED1_2 = 0x7a5, /*20110816 to latest Speed : X 1 -Speed: X 1 20130807 to 20130814 Speed : X 1/2 -Speed: X 1/2 */ MSG_REPLAY_SPEED1 = 0x7a6, /*20110816 to latest Speed : X 2 -Speed: X 2 20130807 to 20130814 Speed : X 1 -Speed: X 1 */ MSG_REPLAY_SPEED2 = 0x7a7, /*20110816 to latest Speed : X 4 -Speed: X 4 20130807 to 20130814 Speed : X 2 -Speed: X 2 */ MSG_REPLAY_SPEED4 = 0x7a8, /*20110816 to latest Speed : X 8 -Speed: X 8 20130807 to 20130814 Speed : X 4 -Speed: X 4 */ MSG_REPLAY_SPEED8 = 0x7a9, /*20110816 to latest Speed : X 16 -Speed: X 16 20130807 to 20130814 Speed : X 8 -Speed: X 8 */ MSG_REPLAY_SPEED16 = 0x7aa, /*20110816 to latest @@ -11409,12 +11392,10 @@ Speed : 알수없음 Speed: Unknown 20130807 to 20130814 Speed : X 16 -Speed: X 16 */ MSG_REPLAY_SPEEDUNKNOWN = 0x7ab, /*20110816 to latest Service Info : %s -Service Info: %s 20130807 to 20130814 Speed : 알수없음 Speed: Unknown @@ -11422,25 +11403,20 @@ Speed: Unknown MSG_REPLAY_CHRVICEINFO = 0x7ac, /*20110816 to latest Character Name : %s -Character Name: %s 20130807 to 20130814 Service Info : %s -Service Info: %s */ MSG_REPLAY_CHARACTERNAME = 0x7ad, /*20110816 to latest Map Name : %s -Map Name: %s 20130807 to 20130814 Character Name : %s -Character Name: %s */ MSG_REPLAY_MAPNAME = 0x7ae, /*20110816 to latest Record Time: %d-%01d-%01d %d: %02d: %02d 20130807 to 20130814 Map Name : %s -Map Name: %s */ MSG_REPLAY_RECORDTIME = 0x7af, /*20110816 to latest @@ -11523,20 +11499,24 @@ Stop MSG_REPLAY_START2 = 0x7bb, /*20110816 to latest Open Option +Open Options 20130807 to 20130814 Input FileName -> Start */ MSG_REPLAY_OPENOPTION = 0x7bc, /*20110816 to latest Close Option +Close Options 20130807 to 20130814 Open Option +Open Options */ MSG_REPLAY_CLOSEOPION = 0x7bd, /*20110816 to latest End 20130807 to 20130814 Close Option +Close Options */ MSG_REPLAY_END = 0x7be, /*20110816 to latest @@ -11601,6 +11581,7 @@ The same file exists already. MSG_REPLAY_RECORDSTART = 0x7c6, /*20110816 to latest is Saved. +Recording saved 20130807 to 20130814 Record Start */ @@ -11609,17 +11590,16 @@ Record Start #if PACKETVER >= 20110823 /*20110823 to latest Weight : %3d / %3d -Weight: %3d / %3d 20130807 to 20130814 is Saved. +Recording saved */ MSG_WEIGHT = 0x7c8, /*20110823 to latest Total : %s C -Total: %s C +Total: %s EUR 20130807 to 20130814 Weight : %3d / %3d -Weight: %3d / %3d */ MSG_TOTAL = 0x7c9, /*20110823 to latest @@ -11627,7 +11607,7 @@ Weight: %3d / %3d [Shuriken] must be equipped. 20130807 to 20130814 Total : %s C -Total: %s C +Total: %s EUR */ MSG_FAIL_NEED_EQUIPPED_SYURIKEN = 0x7ca, #endif @@ -11647,7 +11627,6 @@ Base Lv. %d MSG__BASIC_MSG_JOB = 0x7cc, /*20110831 to latest Zeny : %s -Zeny: %s 20130807 to 20130814 Job Lv. %d */ @@ -11656,7 +11635,6 @@ Job Lv. %d Trilinear 20130807 to 20130814 Zeny : %s -Zeny: %s */ MSG_GRAPHIC_MSG_TRILINEAR = 0x7ce, /*20110831 to latest @@ -11679,6 +11657,7 @@ skill MSG_GRAPHIC_MSG_ITEM = 0x7d1, /*20110831 to latest NoCtrl +Ctrl 20130807 to 20130814 item */ @@ -11688,10 +11667,12 @@ item More 20130807 to 20130814 NoCtrl +Ctrl */ MSG_GRAPHIC_MSG_BATTLE = 0x7d3, /*20110831 to latest (Character/Total Slot) +(Characters/Total slots) 20130807 to 20130814 전장 More @@ -11702,6 +11683,7 @@ Premium Service VIP Service 20130807 to 20130814 (Character/Total Slot) +(Characters/Total slots) */ MSG_CHARACTER_MSG_PREMIUMSERVICE = 0x7d5, /*20110831 to latest @@ -13040,6 +13022,7 @@ Move Combining items will be only one kind at a time. 20120320 to latest Make Character +Create Character 20130807 to 20130814 이름변경 Rename @@ -13052,6 +13035,7 @@ You cannot have more than 30,000 stacked items. http://ro.game.gnjoy.com/ 20130807 to 20130814 Make Character +Create Character */ MSG_UAE_URL = 0x877, #endif @@ -13371,7 +13355,6 @@ Change to Default UI MSG_NAVIGATION_HELP = 0x89d, /*20120417 to latest ALL -All 20130807 to 20130814 도움말 Help @@ -13381,7 +13364,6 @@ Help Map 20130807 to 20130814 ALL -All */ MSG_NAVIGATION_MAP = 0x89f, /*20120417 to latest @@ -15516,7 +15498,7 @@ You entered more than 1 Billion Zeny, the price will be set to 1 Billion Zeny. ErrorCode : %d, ErrorValue : %d 20130612 to latest ErrorCategory : %d, ErrorCode : %d (%d,%d,%d,%d) -ErrorCategory: %d, ErrorCode: %d (%d,%d,%d,%d) +ErrorCode : %d, ErrorValue : %d 20130807 to 20130814 AuthTicket is Not Vaild AuthTicket is Not Valid @@ -15531,7 +15513,7 @@ AuthTicket is Not Valid %d%% ( Basic 100%% + Premium %d%% + Internet cafe %d%% + %s Server %d%% ) 20130807 to 20130814 ErrorCategory : %d, ErrorCode : %d (%d,%d,%d,%d) -ErrorCategory: %d, ErrorCode: %d (%d,%d,%d,%d) +ErrorCode : %d, ErrorValue : %d */ MSG_BASIC_EXP_MSG_INDONESIA = 0x9a6, /*20130618 to 20130925 @@ -15564,7 +15546,6 @@ The price of^0000FF %s^000000 MSG_WARNING_PRICE1 = 0x9a9, /*20130626 to latest 100000000 -1000000000 20130807 to 20130814 %s 의 가격이 The price of^0000FF %s^000000 @@ -15575,7 +15556,6 @@ The price of^0000FF %s^000000 is over ^FF0000%d^0000FF Billion^000000 Zeny and 20130807 to 20130814 100000000 -1000000000 */ MSG_WARNING_PRICE3 = 0x9ab, /*20130626 to latest @@ -16352,7 +16332,7 @@ You can not open the mail. MSG_FAILED_TO_WRITE_MAIL = 0xa2c, /*20140416 to latest You are currently joined in CLan !! -You are currently joined in Clan !! +You currently belong to a clan. */ MSG_JOINED_IN_CLAN = 0xa2d, /*20140416 to latest @@ -16423,17 +16403,14 @@ The recipient's name does not exist. #if PACKETVER >= 20140430 /*20140430 to latest E X P : %.1f%% ( basic %.1f%% premium %.1f%% + %s %.1f%%) -EXP : %.1f%% (Basic %.1f%% Premium %.1f%% + %s %.1f%%) */ MSG_TAIWAN_PERSONALINFO_EXPMSG = 0xa38, /*20140430 to latest DROP : %.1f%% ( basic %.1f%% premium %.1f%% + %s %.1f%%) -DROP : %.1f%% (Basic %.1f%% Premium %.1f%% + %s %.1f%%) */ MSG_TAIWAN_PERSONALINFO_DROPMSG = 0xa39, /*20140430 to latest DEATH : %.1f%% ( basic %.1f%% premium %.1f%% + %s %.1f%%) -DEATH: %.1f%% (Basic %.1f%% Premium %.1f%% + %s %.1f%%) */ MSG_TAIWAN_PERSONALINFO_DEATHMSG = 0xa3a, #endif @@ -16684,7 +16661,6 @@ Adventure %s GD 20141001 to latest %s -%s */ MSG_CASH_GEDARE_MONEY = 0xa5f, /*20140723 to 20140723 @@ -16925,17 +16901,14 @@ Please empty at least 5 amount of possession in item window. MSG_NOT_ENOUGH_SPACE_IN_ITEM_BODY = 0xa85, /*20140917 to latest E X P : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%%) -EXP : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%% ) */ MSG_JPN_PERSONALINFO_EXPMSG = 0xa86, /*20140917 to latest DROP : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%%) -DROP : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%% ) */ MSG_JPN_PERSONALINFO_DROPMSG = 0xa87, /*20140917 to latest DEATH : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%%) -DEATH : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%% ) */ MSG_JPN_PERSONALINFO_DEATHMSG = 0xa88, /*20140917 to latest @@ -17381,12 +17354,10 @@ Withdraw MSG_ID_AD7 = 0xad7, /*20150304 to latest 1 z UP -1z UP */ MSG_ID_AD8 = 0xad8, /*20150304 to latest 1 z Down -1z Down */ MSG_ID_AD9 = 0xad9, /*20150304 to latest @@ -17561,17 +17532,14 @@ Send Mail #if PACKETVER >= 20150729 /*20150729 to latest E X P : %.1f%% ( basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) -E X P: %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) */ MSG_ID_AF9 = 0xaf9, /*20150729 to latest DROP : %.1f%% ( basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) -DROP : %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) */ MSG_ID_AFA = 0xafa, /*20150729 to latest DEATH : %.1f%% ( basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) -DEATH: %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) */ MSG_ID_AFB = 0xafb, #endif @@ -17581,6 +17549,7 @@ DEATH: %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) Name with this tag cannot be used. 20181002 to latest 해당 내용은 이름으로 사용하실 수 없습니다. +You cannot use the tag as a name. */ MSG_ID_AFC = 0xafc, #endif @@ -17803,7 +17772,6 @@ SNS통신 TWITTER 20160824 to latest Twitter -TWITTER */ MSG_ID_B1D = 0xb1d, /*20160224 to latest @@ -18167,7 +18135,6 @@ The [%s] is not present, the default AI will be used instead. %.1f%% ( Premium %.1f%% + %s %.1f%%) 20160706 to latest %.1f%% ( Basic 100.0%% + Premium %.1f%% + %s %.1f%%) -%.1f%% ( Basic 100.0%% + Premium %.1f%% + %s %.1f%%) */ MSG_ID_B62 = 0xb62, #endif @@ -18784,10 +18751,12 @@ Weight limit has reached toover 70%. Or less then 10 invenrory space. MSG_ID_BCE = 0xbce, /*20161123 to latest C +EUR */ MSG_ID_BCF = 0xbcf, /*20161123 to latest C +EUR */ MSG_ID_BD0 = 0xbd0, /*20161123 to latest @@ -19041,10 +19010,12 @@ SP MSG_ID_BFD = 0xbfd, /*20161228 to latest Lv +Lv. */ MSG_ID_BFE = 0xbfe, /*20161228 to latest Lv +Lv. */ MSG_ID_BFF = 0xbff, /*20161228 to latest @@ -19057,6 +19028,7 @@ Exp MSG_ID_C01 = 0xc01, /*20161228 to latest Play Replay Flie +Start replay */ MSG_ID_C02 = 0xc02, /*20161228 to latest @@ -19073,14 +19045,17 @@ Basicinfo MSG_ID_C05 = 0xc05, /*20161228 to latest Equip +Equipment */ MSG_ID_C06 = 0xc06, /*20161228 to latest Item +Items */ MSG_ID_C07 = 0xc07, /*20161228 to latest Skill +Skills */ MSG_ID_C08 = 0xc08, /*20161228 to latest @@ -19093,10 +19068,12 @@ Party MSG_ID_C0A = 0xc0a, /*20161228 to latest Chatting +Chat */ MSG_ID_C0B = 0xc0b, /*20161228 to latest Shortcut +Hotkeys */ MSG_ID_C0C = 0xc0c, /*20161228 to latest @@ -19105,15 +19082,16 @@ Status MSG_ID_C0D = 0xc0d, /*20161228 to latest ALL -All */ MSG_ID_C0E = 0xc0e, /*20161228 to latest User Defined File Name +Custom file name */ MSG_ID_C0F = 0xc0f, /*20161228 to latest Repeated File Check +Check file */ MSG_ID_C10 = 0xc10, /*20161228 to latest @@ -19122,10 +19100,12 @@ on MSG_ID_C11 = 0xc11, /*20161228 to latest <Basic Skin> +<Basic> */ MSG_ID_C12 = 0xc12, /*20161228 to latest Select Skin +Choose skin */ MSG_ID_C13 = 0xc13, #endif @@ -19675,6 +19655,7 @@ Loading the mailbox. MSG_ID_C76 = 0xc76, /*20170315 to latest NOW LOADING.. +Loading... */ MSG_ID_C77 = 0xc77, /*20170315 to latest @@ -19939,6 +19920,7 @@ BOX #if PACKETVER >= 20170628 /*20170628 to latest 다시하기 +File abusing detected. Please restart the client with clean files. */ MSG_ID_CA9 = 0xca9, /*20170628 to 20170809 @@ -20097,6 +20079,7 @@ map MSG_ID_CCC = 0xccc, /*20170809 to latest 변조된 파일이 발견되었습니다. 게임을 다시 실행시켜주세요. +File abusing detected. Please restart the client with clean files. */ MSG_ID_CCD = 0xccd, #endif @@ -20391,6 +20374,7 @@ TokenAgency 서버 연결 실패 MSG_ID_D0D = 0xd0d, /*20171025 to latest 삭제 +Delete */ MSG_ID_D0E = 0xd0e, /*20171025 to latest @@ -20581,6 +20565,7 @@ NPC가 있는 맵의 랜덤 좌표로 이동 됩니다. MSG_ID_D3B = 0xd3b, /*20171108 to latest 태권 +Taekwon */ MSG_ID_D3C = 0xd3c, #endif @@ -20623,10 +20608,12 @@ NPC가 있는 맵의 랜덤 좌표로 이동 됩니다. MSG_ID_D42 = 0xd42, /*20171115 to latest 차단 리스트가 없습니다 +Ignore-list is empty */ MSG_ID_D43 = 0xd43, /*20171115 to latest -차단 리스트- +Characters in ignore-list: */ MSG_ID_D44 = 0xd44, /*20171115 to latest @@ -20993,6 +20980,7 @@ This is not the current attendance check event MSG_ID_D93 = 0xd93, /*20180207 to latest 개인 상납 경험치가 max에 도달하여, 더 이상 길드 경험치를 누적할 수 없습니다. + */ MSG_ID_D94 = 0xd94, #endif @@ -21045,6 +21033,7 @@ Enter 4 english words and 2 chinese words MSG_ID_D9D = 0xd9d, /*20180404 to latest 50% 이상의 값을 입력할 수 없습니다. +The guild tax rate can't be set to more than 50%. */ MSG_ID_D9E = 0xd9e, /*20180404 to latest @@ -21267,20 +21256,24 @@ Emblem 테두리를 그려주지 않습니다 #if PACKETVER >= 20180718 /*20180718 to latest E X P : %.1f%% ( basic 100.0%% %s %.1f%%) +EXP: %.1f%% (basic: 100.0%%, %s: %.1f%%) */ MSG_ID_DCF = 0xdcf, /*20180718 to latest DROP : %.1f%% ( basic 100.0%% %s %.1f%%) +DROP: %.1f%% (basic: 100.0%%, %s: %.1f%%) */ MSG_ID_DD0 = 0xdd0, /*20180718 to latest DEATH : %.1f%% ( basic 100.0%% %s %.1f%%) +DEATH: %.1f%% (basic: 100.0%%, %s: %.1f%%) */ MSG_ID_DD1 = 0xdd1, #endif #if PACKETVER >= 20180829 /*20180829 to latest 영문이나 러시아어 단독으로만 사용이 가능합니다. +Forbidden symbols in character name. */ MSG_ID_DD2 = 0xdd2, /*20180829 to latest @@ -21289,28 +21282,34 @@ you must have an AccessTicket to login MSG_ID_DD3 = 0xdd3, /*20180829 to latest 창고를 불러오는 중입니다. +Loading.... */ MSG_ID_DD4 = 0xdd4, /*20180829 to latest NOW LOADING.. +Loading... */ MSG_ID_DD5 = 0xdd5, #endif #if PACKETVER >= 20181002 /*20181002 to latest 삭제 +Delete */ MSG_ID_DD6 = 0xdd6, /*20181002 to latest 답장 +Reply */ MSG_ID_DD7 = 0xdd7, /*20181002 to latest 전송 +Send */ MSG_ID_DD8 = 0xdd8, /*20181002 to latest 이름확인 +Name Check */ MSG_ID_DD9 = 0xdd9, /*20181002 to latest @@ -21453,6 +21452,7 @@ PvP #if PACKETVER >= 20190109 /*20190109 to latest Capture Monster +Taming monster */ MSG_ID_DF5 = 0xdf5, /*20190109 to latest @@ -21461,6 +21461,7 @@ message MSG_ID_DF6 = 0xdf6, /*20190109 to latest TITLE +Header */ MSG_ID_DF7 = 0xdf7, /*20190109 to latest @@ -21798,6 +21799,7 @@ AP가 부족합니다. MSG_ID_E3E = 0xe3e, /*20190731 to latest ∞ +? */ MSG_ID_E3F = 0xe3f, /*20190731 to latest @@ -21812,6 +21814,7 @@ Total : %s Zeny #if PACKETVER >= 20190821 /*20190821 to latest 계정한정판매 등록창 +Limited Account Registration Window */ MSG_ID_E42 = 0xe42, /*20190821 to latest @@ -21836,26 +21839,34 @@ Sale Start Time MSG_ID_E46 = 0xe46, /*20190821 to latest 판매 종료시간 +Sale end time */ MSG_ID_E47 = 0xe47, /*20190821 to latest 계정 한정 +Account only */ MSG_ID_E48 = 0xe48, /*20190821 to latest 판매기간 : %d월 %d일 %d시 %d분 +Sale period:% d month% d day% d hours% d */ MSG_ID_E49 = 0xe49, -/*20190821 to latest +/*20190821 to 20191002 구입가능 %d개 +% D available +20191016 to latest +계정당 구매가능 */ MSG_ID_E4A = 0xe4a, /*20190821 to latest %d개 한정 +limited to% d */ MSG_ID_E4B = 0xe4b, /*20190821 to latest >> ItemName : %s / 수량 : %d / 판매기간 : %d월:%d일:%d시:%d분 ~ %d월:%d일:%d시:%d분 +>> ItemName:% s / Quantity:% d / Sales Period:% d Month:% d Day:% d Hour:% d Minute ~% d Month:% d Day:% d Hour:% d Minute */ MSG_ID_E4C = 0xe4c, /*20190821 to latest @@ -21864,30 +21875,36 @@ Sold Out MSG_ID_E4D = 0xe4d, /*20190821 to latest [%s]은(는) 현재 소환할 수 없는 지역에 있습니다. +% s] is currently in a region that cannot be summoned. */ MSG_ID_E4E = 0xe4e, /*20190821 to latest ~ %d월 %d일 %d시 %d분 +% d min% d days% d days */ MSG_ID_E4F = 0xe4f, /*20190821 to latest 상품을 더이상 추가할 수 없습니다 +Can't add any more items */ MSG_ID_E50 = 0xe50, #endif #if PACKETVER >= 20190828 /*20190828 to latest 장착 중인 아이템은 교환할 수 없습니다. 장착을 해제한 뒤 시도해 주시길 바랍니다. +The item being mounted cannot be exchanged. Please unmount it and try again. */ MSG_ID_E51 = 0xe51, #endif #if PACKETVER >= 20190904 /*20190904 to latest 길드 창고 이용 중엔 캐릭터 선택창으로 이동 할 수 없습니다. +You can not move to the character selection window while using the Guild Warehouse. */ MSG_ID_E52 = 0xe52, /*20190904 to latest 아이템 태그가 포함되어 있어 사용할 수 없습니다. +Item tag is included and cannot be used. */ MSG_ID_E53 = 0xe53, /*20190904 to latest @@ -21942,14 +21959,18 @@ Balance: %s %c MSG_ID_E5F = 0xe5f, /*20190918 to latest ^ff0000본 아이템을 구매 후 7일 이내에는 청약 철회가 가능합니다. 다만, 7일이 지났거나 아이템을 개봉하시면 청약 철회 대상에서 제외 됩니다.또한 구매시 사용된 무료캐시는 청약철회시 반환되지 않습니다.^000000 정말로 아이템을 구매하시겠습니까? 구매하실 경우 %s캐시가 차감됩니다. +Do you really want to purchase this item? %s Money will be deducted from your total balance. */ MSG_ID_E60 = 0xe60, /*20190918 to latest ^ff0000본 아이템을 구매 후 7일 이내에는 청약 철회가 가능합니다. 다만, 7일이 지났거나 아이템을 개봉하시면 청약 철회 대상에서 제외 됩니다.또한 구매시 사용된 무료캐시는 청약철회시 반환되지 않습니다.^000000 정말로 아이템을 구매하시겠습니까? 구매하실 경우 일반 %s캐시, 무료 %s캐시가 차감됩니다. +Do you really want to purchase this item? %s Money and %s Free Points will be deducted from your total balance. */ MSG_ID_E61 = 0xe61, -/*20190918 to latest +/*20190918 to 20190918 [%s]의 호출이 거부되었습니다. +20190925 to latest +호출이 거부되었습니다. */ MSG_ID_E62 = 0xe62, /*20190918 to latest @@ -21961,6 +21982,34 @@ Balance: %s %c */ MSG_ID_E64 = 0xe64, #endif +#if PACKETVER >= 20191002 +/*20191002 to latest +판매 노점 아이템 리스트가 저장되었습니다. +*/ + MSG_ID_E65 = 0xe65, +/*20191002 to latest +구매 노점 아이템 리스트가 저장되었습니다. +*/ + MSG_ID_E66 = 0xe66, +/*20191002 to latest +VTC 인증에 실패하였습니다. +*/ + MSG_ID_E67 = 0xe67, +#endif +#if PACKETVER >= 20191016 +/*20191016 to latest +물물교환 중에는 장비를 착용할 수 없습니다. +*/ + MSG_ID_E68 = 0xe68, +/*20191016 to latest +교환하려는 품목 +*/ + MSG_ID_E69 = 0xe69, +/*20191016 to latest + 1차, 2차, 3차 직업 스킬 %d개를 더 올려 주십시오. +*/ + MSG_ID_E6A = 0xe6a, +#endif }; #endif /* MAP_MESSAGES_MAIN_H */ diff --git a/src/map/messages_re.h b/src/map/messages_re.h index 4ae3dee1d..84ccecc5e 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: 20190918 +Latest version: 20191016 */ enum clif_messages { @@ -752,7 +752,7 @@ Congratulations! You are the MVP! Your reward item is MSG_YOU_RECEIVE_MVP_ITEM = 0x8f, /*20080827 to latest !! -!! +! */ MSG_YOU_RECEIVE_MVP_ITEM2 = 0x90, /*20080827 to latest @@ -3914,7 +3914,6 @@ Mouse wheel skills for F7 and F8 are Disabled.[/q2 OFF] MSG_EXPLAIN_QUICKSPELL2 = 0x302, /*20080827 to latest /q3 : /quickspell (/q1) + /quickspell2 (/q2) -/q3: /quickspell (/q1) + /quickspell2 (/q2) */ MSG_EXPLAIN_QUICKSPELL3 = 0x303, /*20080827 to latest @@ -4967,7 +4966,7 @@ High Wizard MSG_WIZARD_H = 0x3da, /*20080827 to latest White Smith -WhiteSmith +MasterSmith */ MSG_BLACKSMITH_H = 0x3db, /*20080827 to latest @@ -6623,7 +6622,6 @@ Quest List MSG_QUESTWIN = 0x525, /*20080827 to latest RO SHOP -RO Shop */ MSG_RO_SHOP = 0x526, /*20080827 to latest @@ -10434,7 +10432,6 @@ ITEM MSG_MACRO_SKILL = 0x775, /*20110228 to 20110228 Next attack time : -Next attack time: 20110308 to latest TACTIC 20130807 to 20130814 @@ -10451,6 +10448,7 @@ TACTIC MSG_MACRO_ETC = 0x777, /*20110228 to 20110228 When invited to a party +When invited to the party 20110308 to latest COMBAT 20130807 to 20130814 @@ -10495,7 +10493,6 @@ ATTACK MSG_MACRO_ATTACK = 0x77d, /*20110308 to latest Next attack time : -Next attack time: 20130807 to 20130814 ATTACK */ @@ -10504,11 +10501,11 @@ ATTACK When died 20130807 to 20130814 Next attack time : -Next attack time: */ MSG_MACRO_WHEN_DIED = 0x77f, /*20110308 to latest When invited to a party +When invited to the party 20130807 to 20130814 When died */ @@ -10517,6 +10514,7 @@ When died Pickup Item 20130807 to 20130814 When invited to a party +When invited to the party */ MSG_MACRO_PICKUP_ITEM = 0x781, /*20110308 to latest @@ -10546,7 +10544,6 @@ Any work in progress (NPC dialog, manufacturing ...) quit and try again. ExMacro_SaveData%d 20110412 to latest SaveData_ExMacro%d -SaveData_ExMacro %d 20130807 to 20130814 몬스터 사냥을 통해 얻을 수 있는 Job경험치가 %d분간 %.2f배로 증가합니다. Monster Job hunting experience that you can get through the doubling of %d is %.2f minutes. @@ -10557,7 +10554,6 @@ Monster Job hunting experience that you can get through the doubling of %d is %. Settings for [%s] are stored in. 20130807 to 20130814 SaveData_ExMacro%d -SaveData_ExMacro %d */ MSG_MACRO_SAVE_DATA2 = 0x786, #endif @@ -10825,57 +10821,44 @@ Current location of the shop and chat room creation is disabled. MSG_REPLAY_ELAPSEDTIME = 0x7a3, /*20110816 to latest Speed : X 1/4 -Speed: X 1/4 20130807 to 20130814 Elapsed time: %d:%d:%d / %d:%d:%d */ MSG_REPLAY_SPEED1_4 = 0x7a4, /*20110816 to latest Speed : X 1/2 -Speed: X 1/2 20130807 to 20130814 Speed : X 1/4 -Speed: X 1/4 */ MSG_REPLAY_SPEED1_2 = 0x7a5, /*20110816 to latest Speed : X 1 -Speed: X 1 20130807 to 20130814 Speed : X 1/2 -Speed: X 1/2 */ MSG_REPLAY_SPEED1 = 0x7a6, /*20110816 to latest Speed : X 2 -Speed: X 2 20130807 to 20130814 Speed : X 1 -Speed: X 1 */ MSG_REPLAY_SPEED2 = 0x7a7, /*20110816 to latest Speed : X 4 -Speed: X 4 20130807 to 20130814 Speed : X 2 -Speed: X 2 */ MSG_REPLAY_SPEED4 = 0x7a8, /*20110816 to latest Speed : X 8 -Speed: X 8 20130807 to 20130814 Speed : X 4 -Speed: X 4 */ MSG_REPLAY_SPEED8 = 0x7a9, /*20110816 to latest Speed : X 16 -Speed: X 16 20130807 to 20130814 Speed : X 8 -Speed: X 8 */ MSG_REPLAY_SPEED16 = 0x7aa, /*20110816 to latest @@ -10883,12 +10866,10 @@ Speed : 알수없음 Speed: Unknown 20130807 to 20130814 Speed : X 16 -Speed: X 16 */ MSG_REPLAY_SPEEDUNKNOWN = 0x7ab, /*20110816 to latest Service Info : %s -Service Info: %s 20130807 to 20130814 Speed : 알수없음 Speed: Unknown @@ -10896,25 +10877,20 @@ Speed: Unknown MSG_REPLAY_CHRVICEINFO = 0x7ac, /*20110816 to latest Character Name : %s -Character Name: %s 20130807 to 20130814 Service Info : %s -Service Info: %s */ MSG_REPLAY_CHARACTERNAME = 0x7ad, /*20110816 to latest Map Name : %s -Map Name: %s 20130807 to 20130814 Character Name : %s -Character Name: %s */ MSG_REPLAY_MAPNAME = 0x7ae, /*20110816 to latest Record Time: %d-%01d-%01d %d: %02d: %02d 20130807 to 20130814 Map Name : %s -Map Name: %s */ MSG_REPLAY_RECORDTIME = 0x7af, /*20110816 to latest @@ -10997,20 +10973,24 @@ Stop MSG_REPLAY_START2 = 0x7bb, /*20110816 to latest Open Option +Open Options 20130807 to 20130814 Input FileName -> Start */ MSG_REPLAY_OPENOPTION = 0x7bc, /*20110816 to latest Close Option +Close Options 20130807 to 20130814 Open Option +Open Options */ MSG_REPLAY_CLOSEOPION = 0x7bd, /*20110816 to latest End 20130807 to 20130814 Close Option +Close Options */ MSG_REPLAY_END = 0x7be, /*20110816 to latest @@ -11075,6 +11055,7 @@ The same file exists already. MSG_REPLAY_RECORDSTART = 0x7c6, /*20110816 to latest is Saved. +Recording saved 20130807 to 20130814 Record Start */ @@ -11083,17 +11064,16 @@ Record Start #if PACKETVER >= 20110823 /*20110823 to latest Weight : %3d / %3d -Weight: %3d / %3d 20130807 to 20130814 is Saved. +Recording saved */ MSG_WEIGHT = 0x7c8, /*20110823 to latest Total : %s C -Total: %s C +Total: %s EUR 20130807 to 20130814 Weight : %3d / %3d -Weight: %3d / %3d */ MSG_TOTAL = 0x7c9, /*20110823 to latest @@ -11101,7 +11081,7 @@ Weight: %3d / %3d [Shuriken] must be equipped. 20130807 to 20130814 Total : %s C -Total: %s C +Total: %s EUR */ MSG_FAIL_NEED_EQUIPPED_SYURIKEN = 0x7ca, #endif @@ -11121,7 +11101,6 @@ Base Lv. %d MSG__BASIC_MSG_JOB = 0x7cc, /*20110831 to latest Zeny : %s -Zeny: %s 20130807 to 20130814 Job Lv. %d */ @@ -11130,7 +11109,6 @@ Job Lv. %d Trilinear 20130807 to 20130814 Zeny : %s -Zeny: %s */ MSG_GRAPHIC_MSG_TRILINEAR = 0x7ce, /*20110831 to latest @@ -11153,6 +11131,7 @@ skill MSG_GRAPHIC_MSG_ITEM = 0x7d1, /*20110831 to latest NoCtrl +Ctrl 20130807 to 20130814 item */ @@ -11162,10 +11141,12 @@ item More 20130807 to 20130814 NoCtrl +Ctrl */ MSG_GRAPHIC_MSG_BATTLE = 0x7d3, /*20110831 to latest (Character/Total Slot) +(Characters/Total slots) 20130807 to 20130814 전장 More @@ -11176,6 +11157,7 @@ Premium Service VIP Service 20130807 to 20130814 (Character/Total Slot) +(Characters/Total slots) */ MSG_CHARACTER_MSG_PREMIUMSERVICE = 0x7d5, /*20110831 to latest @@ -12514,6 +12496,7 @@ Move Combining items will be only one kind at a time. 20120320 to latest Make Character +Create Character 20130807 to 20130814 이름변경 Rename @@ -12526,6 +12509,7 @@ You cannot have more than 30,000 stacked items. http://ro.game.gnjoy.com/ 20130807 to 20130814 Make Character +Create Character */ MSG_UAE_URL = 0x877, #endif @@ -12847,7 +12831,6 @@ Change to Default UI MSG_NAVIGATION_HELP = 0x89d, /*20120417 to latest ALL -All 20130807 to 20130814 도움말 Help @@ -12857,7 +12840,6 @@ Help Map 20130807 to 20130814 ALL -All */ MSG_NAVIGATION_MAP = 0x89f, /*20120417 to latest @@ -14992,7 +14974,7 @@ You entered more than 1 Billion Zeny, the price will be set to 1 Billion Zeny. ErrorCode : %d, ErrorValue : %d 20130612 to latest ErrorCategory : %d, ErrorCode : %d (%d,%d,%d,%d) -ErrorCategory: %d, ErrorCode: %d (%d,%d,%d,%d) +ErrorCode : %d, ErrorValue : %d 20130807 to 20130814 AuthTicket is Not Vaild AuthTicket is Not Valid @@ -15007,7 +14989,7 @@ AuthTicket is Not Valid %d%% ( Basic 100%% + Premium %d%% + Internet cafe %d%% + %s Server %d%% ) 20130807 to 20130814 ErrorCategory : %d, ErrorCode : %d (%d,%d,%d,%d) -ErrorCategory: %d, ErrorCode: %d (%d,%d,%d,%d) +ErrorCode : %d, ErrorValue : %d */ MSG_BASIC_EXP_MSG_INDONESIA = 0x9a6, /*20130618 to 20130925 @@ -15040,7 +15022,6 @@ The price of^0000FF %s^000000 MSG_WARNING_PRICE1 = 0x9a9, /*20130626 to latest 100000000 -1000000000 20130807 to 20130814 %s 의 가격이 The price of^0000FF %s^000000 @@ -15051,7 +15032,6 @@ The price of^0000FF %s^000000 is over ^FF0000%d^0000FF Billion^000000 Zeny and 20130807 to 20130814 100000000 -1000000000 */ MSG_WARNING_PRICE3 = 0x9ab, /*20130626 to latest @@ -15828,7 +15808,7 @@ You can not open the mail. MSG_FAILED_TO_WRITE_MAIL = 0xa2c, /*20140416 to latest You are currently joined in CLan !! -You are currently joined in Clan !! +You currently belong to a clan. */ MSG_JOINED_IN_CLAN = 0xa2d, /*20140416 to latest @@ -15899,17 +15879,14 @@ The recipient's name does not exist. #if PACKETVER >= 20140430 /*20140430 to latest E X P : %.1f%% ( basic %.1f%% premium %.1f%% + %s %.1f%%) -EXP : %.1f%% (Basic %.1f%% Premium %.1f%% + %s %.1f%%) */ MSG_TAIWAN_PERSONALINFO_EXPMSG = 0xa38, /*20140430 to latest DROP : %.1f%% ( basic %.1f%% premium %.1f%% + %s %.1f%%) -DROP : %.1f%% (Basic %.1f%% Premium %.1f%% + %s %.1f%%) */ MSG_TAIWAN_PERSONALINFO_DROPMSG = 0xa39, /*20140430 to latest DEATH : %.1f%% ( basic %.1f%% premium %.1f%% + %s %.1f%%) -DEATH: %.1f%% (Basic %.1f%% Premium %.1f%% + %s %.1f%%) */ MSG_TAIWAN_PERSONALINFO_DEATHMSG = 0xa3a, #endif @@ -16160,7 +16137,6 @@ Adventure %s GD 20141001 to latest %s -%s */ MSG_CASH_GEDARE_MONEY = 0xa5f, /*20140723 to 20140723 @@ -16401,17 +16377,14 @@ Please empty at least 5 amount of possession in item window. MSG_NOT_ENOUGH_SPACE_IN_ITEM_BODY = 0xa85, /*20140917 to latest E X P : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%%) -EXP : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%% ) */ MSG_JPN_PERSONALINFO_EXPMSG = 0xa86, /*20140917 to latest DROP : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%%) -DROP : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%% ) */ MSG_JPN_PERSONALINFO_DROPMSG = 0xa87, /*20140917 to latest DEATH : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%%) -DEATH : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%% ) */ MSG_JPN_PERSONALINFO_DEATHMSG = 0xa88, /*20140917 to latest @@ -16857,12 +16830,10 @@ Withdraw MSG_ID_AD7 = 0xad7, /*20150304 to latest 1 z UP -1z UP */ MSG_ID_AD8 = 0xad8, /*20150304 to latest 1 z Down -1z Down */ MSG_ID_AD9 = 0xad9, /*20150304 to latest @@ -17037,17 +17008,14 @@ Send Mail #if PACKETVER >= 20150729 /*20150729 to latest E X P : %.1f%% ( basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) -E X P: %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) */ MSG_ID_AF9 = 0xaf9, /*20150729 to latest DROP : %.1f%% ( basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) -DROP : %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) */ MSG_ID_AFA = 0xafa, /*20150729 to latest DEATH : %.1f%% ( basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) -DEATH: %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) */ MSG_ID_AFB = 0xafb, #endif @@ -17057,6 +17025,7 @@ DEATH: %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) Name with this tag cannot be used. 20181002 to latest 해당 내용은 이름으로 사용하실 수 없습니다. +You cannot use the tag as a name. */ MSG_ID_AFC = 0xafc, #endif @@ -17279,7 +17248,6 @@ SNS통신 TWITTER 20160824 to latest Twitter -TWITTER */ MSG_ID_B1D = 0xb1d, /*20160224 to latest @@ -17643,7 +17611,6 @@ The [%s] is not present, the default AI will be used instead. %.1f%% ( Premium %.1f%% + %s %.1f%%) 20160706 to latest %.1f%% ( Basic 100.0%% + Premium %.1f%% + %s %.1f%%) -%.1f%% ( Basic 100.0%% + Premium %.1f%% + %s %.1f%%) */ MSG_ID_B62 = 0xb62, #endif @@ -18265,10 +18232,12 @@ Weight limit has reached toover 70%. Or less then 10 invenrory space. MSG_ID_BCE = 0xbce, /*20161123 to latest C +EUR */ MSG_ID_BCF = 0xbcf, /*20161123 to latest C +EUR */ MSG_ID_BD0 = 0xbd0, /*20161123 to latest @@ -18522,10 +18491,12 @@ SP MSG_ID_BFD = 0xbfd, /*20161228 to latest Lv +Lv. */ MSG_ID_BFE = 0xbfe, /*20161228 to latest Lv +Lv. */ MSG_ID_BFF = 0xbff, /*20161228 to latest @@ -18538,6 +18509,7 @@ Exp MSG_ID_C01 = 0xc01, /*20161228 to latest Play Replay Flie +Start replay */ MSG_ID_C02 = 0xc02, /*20161228 to latest @@ -18554,14 +18526,17 @@ Basicinfo MSG_ID_C05 = 0xc05, /*20161228 to latest Equip +Equipment */ MSG_ID_C06 = 0xc06, /*20161228 to latest Item +Items */ MSG_ID_C07 = 0xc07, /*20161228 to latest Skill +Skills */ MSG_ID_C08 = 0xc08, /*20161228 to latest @@ -18574,10 +18549,12 @@ Party MSG_ID_C0A = 0xc0a, /*20161228 to latest Chatting +Chat */ MSG_ID_C0B = 0xc0b, /*20161228 to latest Shortcut +Hotkeys */ MSG_ID_C0C = 0xc0c, /*20161228 to latest @@ -18586,15 +18563,16 @@ Status MSG_ID_C0D = 0xc0d, /*20161228 to latest ALL -All */ MSG_ID_C0E = 0xc0e, /*20161228 to latest User Defined File Name +Custom file name */ MSG_ID_C0F = 0xc0f, /*20161228 to latest Repeated File Check +Check file */ MSG_ID_C10 = 0xc10, /*20161228 to latest @@ -18603,10 +18581,12 @@ on MSG_ID_C11 = 0xc11, /*20161228 to latest <Basic Skin> +<Basic> */ MSG_ID_C12 = 0xc12, /*20161228 to latest Select Skin +Choose skin */ MSG_ID_C13 = 0xc13, #endif @@ -19156,6 +19136,7 @@ Loading the mailbox. MSG_ID_C76 = 0xc76, /*20170315 to latest NOW LOADING.. +Loading... */ MSG_ID_C77 = 0xc77, /*20170315 to latest @@ -19418,6 +19399,7 @@ BOX #if PACKETVER >= 20170628 /*20170628 to latest 다시하기 +File abusing detected. Please restart the client with clean files. */ MSG_ID_CA9 = 0xca9, /*20170628 to 20170809 @@ -19576,6 +19558,7 @@ map MSG_ID_CCC = 0xccc, /*20170809 to latest 변조된 파일이 발견되었습니다. 게임을 다시 실행시켜주세요. +File abusing detected. Please restart the client with clean files. */ MSG_ID_CCD = 0xccd, #endif @@ -19870,6 +19853,7 @@ TokenAgency 서버 연결 실패 MSG_ID_D0D = 0xd0d, /*20171025 to latest 삭제 +Delete */ MSG_ID_D0E = 0xd0e, /*20171025 to latest @@ -20060,6 +20044,7 @@ NPC가 있는 맵의 랜덤 좌표로 이동 됩니다. MSG_ID_D3B = 0xd3b, /*20171108 to latest 태권 +Taekwon */ MSG_ID_D3C = 0xd3c, /*20171108 to 20171115 @@ -20102,10 +20087,12 @@ NPC가 있는 맵의 랜덤 좌표로 이동 됩니다. MSG_ID_D42 = 0xd42, /*20171115 to latest 차단 리스트가 없습니다 +Ignore-list is empty */ MSG_ID_D43 = 0xd43, /*20171115 to latest -차단 리스트- +Characters in ignore-list: */ MSG_ID_D44 = 0xd44, /*20171115 to latest @@ -20472,6 +20459,7 @@ This is not the current attendance check event MSG_ID_D93 = 0xd93, /*20180207 to latest 개인 상납 경험치가 max에 도달하여, 더 이상 길드 경험치를 누적할 수 없습니다. + */ MSG_ID_D94 = 0xd94, #endif @@ -20524,6 +20512,7 @@ Enter 4 english words and 2 chinese words MSG_ID_D9D = 0xd9d, /*20180404 to latest 50% 이상의 값을 입력할 수 없습니다. +The guild tax rate can't be set to more than 50%. */ MSG_ID_D9E = 0xd9e, /*20180404 to latest @@ -20746,20 +20735,24 @@ Emblem 테두리를 그려주지 않습니다 #if PACKETVER >= 20180718 /*20180718 to latest E X P : %.1f%% ( basic 100.0%% %s %.1f%%) +EXP: %.1f%% (basic: 100.0%%, %s: %.1f%%) */ MSG_ID_DCF = 0xdcf, /*20180718 to latest DROP : %.1f%% ( basic 100.0%% %s %.1f%%) +DROP: %.1f%% (basic: 100.0%%, %s: %.1f%%) */ MSG_ID_DD0 = 0xdd0, /*20180718 to latest DEATH : %.1f%% ( basic 100.0%% %s %.1f%%) +DEATH: %.1f%% (basic: 100.0%%, %s: %.1f%%) */ MSG_ID_DD1 = 0xdd1, #endif #if PACKETVER >= 20180829 /*20180829 to latest 영문이나 러시아어 단독으로만 사용이 가능합니다. +Forbidden symbols in character name. */ MSG_ID_DD2 = 0xdd2, /*20180829 to latest @@ -20768,28 +20761,34 @@ you must have an AccessTicket to login MSG_ID_DD3 = 0xdd3, /*20180829 to latest 창고를 불러오는 중입니다. +Loading.... */ MSG_ID_DD4 = 0xdd4, /*20180829 to latest NOW LOADING.. +Loading... */ MSG_ID_DD5 = 0xdd5, #endif #if PACKETVER >= 20180919 /*20180919 to latest 삭제 +Delete */ MSG_ID_DD6 = 0xdd6, /*20180919 to latest 답장 +Reply */ MSG_ID_DD7 = 0xdd7, /*20180919 to latest 전송 +Send */ MSG_ID_DD8 = 0xdd8, /*20180919 to latest 이름확인 +Name Check */ MSG_ID_DD9 = 0xdd9, /*20180919 to latest @@ -20932,6 +20931,7 @@ PvP #if PACKETVER >= 20190109 /*20190109 to latest Capture Monster +Taming monster */ MSG_ID_DF5 = 0xdf5, /*20190109 to latest @@ -20940,6 +20940,7 @@ message MSG_ID_DF6 = 0xdf6, /*20190109 to latest TITLE +Header */ MSG_ID_DF7 = 0xdf7, /*20190109 to latest @@ -21277,6 +21278,7 @@ AP가 부족합니다. MSG_ID_E3E = 0xe3e, /*20190731 to latest ∞ +? */ MSG_ID_E3F = 0xe3f, /*20190731 to latest @@ -21291,6 +21293,7 @@ Total : %s Zeny #if PACKETVER >= 20190821 /*20190821 to latest 계정한정판매 등록창 +Limited Account Registration Window */ MSG_ID_E42 = 0xe42, /*20190821 to latest @@ -21315,26 +21318,34 @@ Sale Start Time MSG_ID_E46 = 0xe46, /*20190821 to latest 판매 종료시간 +Sale end time */ MSG_ID_E47 = 0xe47, /*20190821 to latest 계정 한정 +Account only */ MSG_ID_E48 = 0xe48, /*20190821 to latest 판매기간 : %d월 %d일 %d시 %d분 +Sale period:% d month% d day% d hours% d */ MSG_ID_E49 = 0xe49, -/*20190821 to latest +/*20190821 to 20191002 구입가능 %d개 +% D available +20191016 to latest +계정당 구매가능 */ MSG_ID_E4A = 0xe4a, /*20190821 to latest %d개 한정 +limited to% d */ MSG_ID_E4B = 0xe4b, /*20190821 to latest >> ItemName : %s / 수량 : %d / 판매기간 : %d월:%d일:%d시:%d분 ~ %d월:%d일:%d시:%d분 +>> ItemName:% s / Quantity:% d / Sales Period:% d Month:% d Day:% d Hour:% d Minute ~% d Month:% d Day:% d Hour:% d Minute */ MSG_ID_E4C = 0xe4c, /*20190821 to latest @@ -21343,30 +21354,36 @@ Sold Out MSG_ID_E4D = 0xe4d, /*20190821 to latest [%s]은(는) 현재 소환할 수 없는 지역에 있습니다. +% s] is currently in a region that cannot be summoned. */ MSG_ID_E4E = 0xe4e, /*20190821 to latest ~ %d월 %d일 %d시 %d분 +% d min% d days% d days */ MSG_ID_E4F = 0xe4f, /*20190821 to latest 상품을 더이상 추가할 수 없습니다 +Can't add any more items */ MSG_ID_E50 = 0xe50, #endif #if PACKETVER >= 20190828 /*20190828 to latest 장착 중인 아이템은 교환할 수 없습니다. 장착을 해제한 뒤 시도해 주시길 바랍니다. +The item being mounted cannot be exchanged. Please unmount it and try again. */ MSG_ID_E51 = 0xe51, #endif #if PACKETVER >= 20190904 /*20190904 to latest 길드 창고 이용 중엔 캐릭터 선택창으로 이동 할 수 없습니다. +You can not move to the character selection window while using the Guild Warehouse. */ MSG_ID_E52 = 0xe52, /*20190904 to latest 아이템 태그가 포함되어 있어 사용할 수 없습니다. +Item tag is included and cannot be used. */ MSG_ID_E53 = 0xe53, /*20190904 to latest @@ -21421,10 +21438,12 @@ Balance: %s %c MSG_ID_E5F = 0xe5f, /*20190918 to latest ^ff0000본 아이템을 구매 후 7일 이내에는 청약 철회가 가능합니다. 다만, 7일이 지났거나 아이템을 개봉하시면 청약 철회 대상에서 제외 됩니다.또한 구매시 사용된 무료캐시는 청약철회시 반환되지 않습니다.^000000 정말로 아이템을 구매하시겠습니까? 구매하실 경우 %s캐시가 차감됩니다. +Do you really want to purchase this item? %s Money will be deducted from your total balance. */ MSG_ID_E60 = 0xe60, /*20190918 to latest ^ff0000본 아이템을 구매 후 7일 이내에는 청약 철회가 가능합니다. 다만, 7일이 지났거나 아이템을 개봉하시면 청약 철회 대상에서 제외 됩니다.또한 구매시 사용된 무료캐시는 청약철회시 반환되지 않습니다.^000000 정말로 아이템을 구매하시겠습니까? 구매하실 경우 일반 %s캐시, 무료 %s캐시가 차감됩니다. +Do you really want to purchase this item? %s Money and %s Free Points will be deducted from your total balance. */ MSG_ID_E61 = 0xe61, /*20190918 to latest @@ -21440,6 +21459,34 @@ Balance: %s %c */ MSG_ID_E64 = 0xe64, #endif +#if PACKETVER >= 20191002 +/*20191002 to latest +판매 노점 아이템 리스트가 저장되었습니다. +*/ + MSG_ID_E65 = 0xe65, +/*20191002 to latest +구매 노점 아이템 리스트가 저장되었습니다. +*/ + MSG_ID_E66 = 0xe66, +/*20191002 to latest +VTC 인증에 실패하였습니다. +*/ + MSG_ID_E67 = 0xe67, +#endif +#if PACKETVER >= 20191016 +/*20191016 to latest +물물교환 중에는 장비를 착용할 수 없습니다. +*/ + MSG_ID_E68 = 0xe68, +/*20191016 to latest +교환하려는 품목 +*/ + MSG_ID_E69 = 0xe69, +/*20191016 to latest + 1차, 2차, 3차 직업 스킬 %d개를 더 올려 주십시오. +*/ + MSG_ID_E6A = 0xe6a, +#endif }; #endif /* MAP_MESSAGES_RE_H */ diff --git a/src/map/messages_zero.h b/src/map/messages_zero.h index 039d215ac..80e4c0de0 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: 20190918 +Latest version: 20191008 */ enum clif_messages { @@ -752,7 +752,7 @@ Congratulations! You are the MVP! Your reward item is MSG_YOU_RECEIVE_MVP_ITEM = 0x8f, /*20171018 to latest !! -!! +! */ MSG_YOU_RECEIVE_MVP_ITEM2 = 0x90, /*20171018 to latest @@ -3902,7 +3902,6 @@ Mouse wheel skills for F7 and F8 are Disabled.[/q2 OFF] MSG_EXPLAIN_QUICKSPELL2 = 0x302, /*20171018 to latest /q3 : /quickspell (/q1) + /quickspell2 (/q2) -/q3: /quickspell (/q1) + /quickspell2 (/q2) */ MSG_EXPLAIN_QUICKSPELL3 = 0x303, /*20171018 to latest @@ -4955,7 +4954,7 @@ High Wizard MSG_WIZARD_H = 0x3da, /*20171018 to latest White Smith -WhiteSmith +MasterSmith */ MSG_BLACKSMITH_H = 0x3db, /*20171018 to latest @@ -6577,7 +6576,6 @@ Quest List MSG_QUESTWIN = 0x525, /*20171018 to latest RO SHOP -RO Shop */ MSG_RO_SHOP = 0x526, /*20171018 to latest @@ -9558,7 +9556,6 @@ ATTACK MSG_MACRO_ATTACK = 0x77d, /*20171018 to latest Next attack time : -Next attack time: */ MSG_MACRO_NEXT_ATK_TIME = 0x77e, /*20171018 to latest @@ -9567,6 +9564,7 @@ When died MSG_MACRO_WHEN_DIED = 0x77f, /*20171018 to latest When invited to a party +When invited to the party */ MSG_MACRO_WHEN_INVITED_PARTY = 0x780, /*20171018 to latest @@ -9589,7 +9587,6 @@ Monster Job hunting experience that you can get through the doubling of %d is %. MSG_PLUSONLYJOBEXP2 = 0x784, /*20171018 to latest SaveData_ExMacro%d -SaveData_ExMacro %d */ MSG_MACRO_SAVE = 0x785, /*20171018 to latest @@ -9745,37 +9742,30 @@ Elapsed time: %d:%d:%d / %d:%d:%d MSG_REPLAY_ELAPSEDTIME = 0x7a3, /*20171018 to latest Speed : X 1/4 -Speed: X 1/4 */ MSG_REPLAY_SPEED1_4 = 0x7a4, /*20171018 to latest Speed : X 1/2 -Speed: X 1/2 */ MSG_REPLAY_SPEED1_2 = 0x7a5, /*20171018 to latest Speed : X 1 -Speed: X 1 */ MSG_REPLAY_SPEED1 = 0x7a6, /*20171018 to latest Speed : X 2 -Speed: X 2 */ MSG_REPLAY_SPEED2 = 0x7a7, /*20171018 to latest Speed : X 4 -Speed: X 4 */ MSG_REPLAY_SPEED4 = 0x7a8, /*20171018 to latest Speed : X 8 -Speed: X 8 */ MSG_REPLAY_SPEED8 = 0x7a9, /*20171018 to latest Speed : X 16 -Speed: X 16 */ MSG_REPLAY_SPEED16 = 0x7aa, /*20171018 to latest @@ -9785,17 +9775,14 @@ Speed: Unknown MSG_REPLAY_SPEEDUNKNOWN = 0x7ab, /*20171018 to latest Service Info : %s -Service Info: %s */ MSG_REPLAY_CHRVICEINFO = 0x7ac, /*20171018 to latest Character Name : %s -Character Name: %s */ MSG_REPLAY_CHARACTERNAME = 0x7ad, /*20171018 to latest Map Name : %s -Map Name: %s */ MSG_REPLAY_MAPNAME = 0x7ae, /*20171018 to latest @@ -9855,10 +9842,12 @@ Input FileName -> Start MSG_REPLAY_START2 = 0x7bb, /*20171018 to latest Open Option +Open Options */ MSG_REPLAY_OPENOPTION = 0x7bc, /*20171018 to latest Close Option +Close Options */ MSG_REPLAY_CLOSEOPION = 0x7bd, /*20171018 to latest @@ -9905,16 +9894,16 @@ Record Start MSG_REPLAY_RECORDSTART = 0x7c6, /*20171018 to latest is Saved. +Recording saved */ MSG_REPLAY_RECORDEND = 0x7c7, /*20171018 to latest Weight : %3d / %3d -Weight: %3d / %3d */ MSG_WEIGHT = 0x7c8, /*20171018 to latest Total : %s C -Total: %s C +Total: %s EUR */ MSG_TOTAL = 0x7c9, /*20171018 to latest @@ -9932,7 +9921,6 @@ Job Lv. %d MSG__BASIC_MSG_JOB = 0x7cc, /*20171018 to latest Zeny : %s -Zeny: %s */ MSG_BASIC_MSG_ZENY = 0x7cd, /*20171018 to latest @@ -9953,6 +9941,7 @@ item MSG_GRAPHIC_MSG_ITEM = 0x7d1, /*20171018 to latest NoCtrl +Ctrl */ MSG_GRAPHIC_MSG_NOCTRL = 0x7d2, /*20171018 to latest @@ -9962,6 +9951,7 @@ More MSG_GRAPHIC_MSG_BATTLE = 0x7d3, /*20171018 to latest (Character/Total Slot) +(Characters/Total slots) */ MSG_CHARACTER_MSG_CHARACTERTOTALSLOT = 0x7d4, /*20171018 to latest @@ -10761,6 +10751,7 @@ Rename MSG_CHANGE_CHARACTER_NAME = 0x875, /*20171018 to latest Make Character +Create Character */ MSG_MSG_MAKECHARCTER = 0x876, /*20171018 to latest @@ -10958,7 +10949,6 @@ Help MSG_NAVIGATION_HELP = 0x89d, /*20171018 to latest ALL -All */ MSG_NAVIGATION_ALL = 0x89e, /*20171018 to latest @@ -12223,7 +12213,7 @@ AuthTicket is Not Valid MSG_NOT_VALID_AUTH_TICKET = 0x9a4, /*20171018 to latest ErrorCategory : %d, ErrorCode : %d (%d,%d,%d,%d) -ErrorCategory: %d, ErrorCode: %d (%d,%d,%d,%d) +ErrorCode : %d, ErrorValue : %d */ MSG_STEAMAGENCY_ERROR = 0x9a5, /*20171018 to latest @@ -12248,7 +12238,6 @@ The price of^0000FF %s^000000 MSG_WARNING_PRICE1 = 0x9a9, /*20171018 to latest 100000000 -1000000000 */ MSG_WARNING_PRICE2 = 0x9aa, /*20171018 to latest @@ -12897,7 +12886,7 @@ You can not open the mail. MSG_FAILED_TO_WRITE_MAIL = 0xa2c, /*20171018 to latest You are currently joined in CLan !! -You are currently joined in Clan !! +You currently belong to a clan. */ MSG_JOINED_IN_CLAN = 0xa2d, /*20171018 to latest @@ -12952,17 +12941,14 @@ The recipient's name does not exist. MSG_FAILE_MAIL_RECIEVER_INFO = 0xa37, /*20171018 to latest E X P : %.1f%% ( basic %.1f%% premium %.1f%% + %s %.1f%%) -EXP : %.1f%% (Basic %.1f%% Premium %.1f%% + %s %.1f%%) */ MSG_TAIWAN_PERSONALINFO_EXPMSG = 0xa38, /*20171018 to latest DROP : %.1f%% ( basic %.1f%% premium %.1f%% + %s %.1f%%) -DROP : %.1f%% (Basic %.1f%% Premium %.1f%% + %s %.1f%%) */ MSG_TAIWAN_PERSONALINFO_DROPMSG = 0xa39, /*20171018 to latest DEATH : %.1f%% ( basic %.1f%% premium %.1f%% + %s %.1f%%) -DEATH: %.1f%% (Basic %.1f%% Premium %.1f%% + %s %.1f%%) */ MSG_TAIWAN_PERSONALINFO_DEATHMSG = 0xa3a, /*20171018 to latest @@ -13146,7 +13132,6 @@ Cracker is low. MSG_CASH_GEDARE_FAIL_MONEY = 0xa5e, /*20171018 to latest %s -%s */ MSG_CASH_GEDARE_MONEY = 0xa5f, /*20171018 to latest @@ -13341,17 +13326,14 @@ Please empty at least 5 amount of possession in item window. MSG_NOT_ENOUGH_SPACE_IN_ITEM_BODY = 0xa85, /*20171018 to latest E X P : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%%) -EXP : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%% ) */ MSG_JPN_PERSONALINFO_EXPMSG = 0xa86, /*20171018 to latest DROP : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%%) -DROP : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%% ) */ MSG_JPN_PERSONALINFO_DROPMSG = 0xa87, /*20171018 to latest DEATH : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%%) -DEATH : %.1f%% ( basic 100.0%% pccafe %.1f%% + %s %.1f%% ) */ MSG_JPN_PERSONALINFO_DEATHMSG = 0xa88, /*20171018 to latest @@ -13758,12 +13740,10 @@ Withdraw MSG_ID_AD7 = 0xad7, /*20171018 to latest 1 z UP -1z UP */ MSG_ID_AD8 = 0xad8, /*20171018 to latest 1 z Down -1z Down */ MSG_ID_AD9 = 0xad9, /*20171018 to latest @@ -13920,17 +13900,14 @@ Send Mail MSG_ID_AF8 = 0xaf8, /*20171018 to latest E X P : %.1f%% ( basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) -E X P: %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) */ MSG_ID_AF9 = 0xaf9, /*20171018 to latest DROP : %.1f%% ( basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) -DROP : %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) */ MSG_ID_AFA = 0xafa, /*20171018 to latest DEATH : %.1f%% ( basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) -DEATH: %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) */ MSG_ID_AFB = 0xafb, /*20171018 to 20180928 @@ -13938,6 +13915,7 @@ DEATH: %.1f%% (Basic 100.0%% VIP Bonus %.1f%% + %s %.1f%%) Name with this tag cannot be used. 20181010 to latest 해당 내용은 이름으로 사용하실 수 없습니다. +You cannot use the tag as a name. */ MSG_ID_AFC = 0xafc, /*20171018 to latest @@ -14105,7 +14083,6 @@ Screenshots are not attached MSG_ID_B1C = 0xb1c, /*20171018 to latest Twitter -TWITTER */ MSG_ID_B1D = 0xb1d, /*20171018 to latest @@ -14443,7 +14420,6 @@ The [%s] is not present, the default AI will be used instead. MSG_ID_B61 = 0xb61, /*20171018 to latest %.1f%% ( Basic 100.0%% + Premium %.1f%% + %s %.1f%%) -%.1f%% ( Basic 100.0%% + Premium %.1f%% + %s %.1f%%) */ MSG_ID_B62 = 0xb62, /*20171018 to latest @@ -15004,10 +14980,12 @@ Weight limit has reached toover 70%. Or less then 10 invenrory space. MSG_ID_BCE = 0xbce, /*20171018 to latest C +EUR */ MSG_ID_BCF = 0xbcf, /*20171018 to latest C +EUR */ MSG_ID_BD0 = 0xbd0, /*20171018 to latest @@ -15239,10 +15217,12 @@ SP MSG_ID_BFD = 0xbfd, /*20171018 to latest Lv +Lv. */ MSG_ID_BFE = 0xbfe, /*20171018 to latest Lv +Lv. */ MSG_ID_BFF = 0xbff, /*20171018 to latest @@ -15255,6 +15235,7 @@ Exp MSG_ID_C01 = 0xc01, /*20171018 to latest Play Replay Flie +Start replay */ MSG_ID_C02 = 0xc02, /*20171018 to latest @@ -15271,14 +15252,17 @@ Basicinfo MSG_ID_C05 = 0xc05, /*20171018 to latest Equip +Equipment */ MSG_ID_C06 = 0xc06, /*20171018 to latest Item +Items */ MSG_ID_C07 = 0xc07, /*20171018 to latest Skill +Skills */ MSG_ID_C08 = 0xc08, /*20171018 to latest @@ -15291,10 +15275,12 @@ Party MSG_ID_C0A = 0xc0a, /*20171018 to latest Chatting +Chat */ MSG_ID_C0B = 0xc0b, /*20171018 to latest Shortcut +Hotkeys */ MSG_ID_C0C = 0xc0c, /*20171018 to latest @@ -15303,15 +15289,16 @@ Status MSG_ID_C0D = 0xc0d, /*20171018 to latest ALL -All */ MSG_ID_C0E = 0xc0e, /*20171018 to latest User Defined File Name +Custom file name */ MSG_ID_C0F = 0xc0f, /*20171018 to latest Repeated File Check +Check file */ MSG_ID_C10 = 0xc10, /*20171018 to latest @@ -15320,10 +15307,12 @@ on MSG_ID_C11 = 0xc11, /*20171018 to latest <Basic Skin> +<Basic> */ MSG_ID_C12 = 0xc12, /*20171018 to latest Select Skin +Choose skin */ MSG_ID_C13 = 0xc13, /*20171018 to latest @@ -15836,6 +15825,7 @@ Loading the mailbox. MSG_ID_C76 = 0xc76, /*20171018 to latest NOW LOADING.. +Loading... */ MSG_ID_C77 = 0xc77, /*20171018 to latest @@ -16055,6 +16045,7 @@ BOX MSG_ID_CA8 = 0xca8, /*20171018 to latest 다시하기 +File abusing detected. Please restart the client with clean files. */ MSG_ID_CA9 = 0xca9, /*20171018 to latest @@ -16201,6 +16192,7 @@ map MSG_ID_CCC = 0xccc, /*20171018 to latest 변조된 파일이 발견되었습니다. 게임을 다시 실행시켜주세요. +File abusing detected. Please restart the client with clean files. */ MSG_ID_CCD = 0xccd, /*20171018 to latest @@ -16482,6 +16474,7 @@ TokenAgency 서버 연결 실패 MSG_ID_D0D = 0xd0d, /*20171023 to latest 삭제 +Delete */ MSG_ID_D0E = 0xd0e, /*20171023 to latest @@ -16676,6 +16669,7 @@ NPC가 있는 맵의 랜덤 좌표로 이동 됩니다. MSG_ID_D3B = 0xd3b, /*20171109 to latest 태권 +Taekwon */ MSG_ID_D3C = 0xd3c, /*20171109 to 20171117 @@ -16716,10 +16710,12 @@ NPC가 있는 맵의 랜덤 좌표로 이동 됩니다. MSG_ID_D42 = 0xd42, /*20171109 to latest 차단 리스트가 없습니다 +Ignore-list is empty */ MSG_ID_D43 = 0xd43, /*20171109 to latest -차단 리스트- +Characters in ignore-list: */ MSG_ID_D44 = 0xd44, #endif @@ -17096,6 +17092,7 @@ This is not the current attendance check event MSG_ID_D93 = 0xd93, /*20180207 to latest 개인 상납 경험치가 max에 도달하여, 더 이상 길드 경험치를 누적할 수 없습니다. + */ MSG_ID_D94 = 0xd94, #endif @@ -17146,6 +17143,7 @@ Enter 4 english words and 2 chinese words MSG_ID_D9D = 0xd9d, /*20180328 to latest 50% 이상의 값을 입력할 수 없습니다. +The guild tax rate can't be set to more than 50%. */ MSG_ID_D9E = 0xd9e, /*20180328 to latest @@ -17356,14 +17354,17 @@ Emblem 테두리를 그려주지 않습니다 #if PACKETVER >= 20180711 /*20180711 to latest E X P : %.1f%% ( basic 100.0%% %s %.1f%%) +EXP: %.1f%% (basic: 100.0%%, %s: %.1f%%) */ MSG_ID_DCF = 0xdcf, /*20180711 to latest DROP : %.1f%% ( basic 100.0%% %s %.1f%%) +DROP: %.1f%% (basic: 100.0%%, %s: %.1f%%) */ MSG_ID_DD0 = 0xdd0, /*20180711 to latest DEATH : %.1f%% ( basic 100.0%% %s %.1f%%) +DEATH: %.1f%% (basic: 100.0%%, %s: %.1f%%) */ MSG_ID_DD1 = 0xdd1, #endif @@ -17372,6 +17373,7 @@ DEATH : %.1f%% ( basic 100.0%% %s %.1f%%) ' 20180808 to latest 영문이나 러시아어 단독으로만 사용이 가능합니다. +Forbidden symbols in character name. */ MSG_ID_DD2 = 0xdd2, /*20180725 to 20180801 @@ -17384,30 +17386,36 @@ you must have an AccessTicket to login -- 20180905 to latest 창고를 불러오는 중입니다. +Loading.... */ MSG_ID_DD4 = 0xdd4, #endif #if PACKETVER >= 20180905 /*20180905 to latest NOW LOADING.. +Loading... */ MSG_ID_DD5 = 0xdd5, #endif #if PACKETVER >= 20180919 /*20180919 to latest 삭제 +Delete */ MSG_ID_DD6 = 0xdd6, /*20180919 to latest 답장 +Reply */ MSG_ID_DD7 = 0xdd7, /*20180919 to latest 전송 +Send */ MSG_ID_DD8 = 0xdd8, /*20180919 to latest 이름확인 +Name Check */ MSG_ID_DD9 = 0xdd9, /*20180919 to latest @@ -17534,6 +17542,7 @@ PvP #if PACKETVER >= 20181226 /*20181226 to latest Capture Monster +Taming monster */ MSG_ID_DF5 = 0xdf5, /*20181226 to latest @@ -17544,6 +17553,7 @@ message #if PACKETVER >= 20190116 /*20190116 to latest TITLE +Header */ MSG_ID_DF7 = 0xdf7, /*20190116 to latest @@ -17880,6 +17890,7 @@ AP가 부족합니다. #if PACKETVER >= 20190814 /*20190814 to latest ∞ +? */ MSG_ID_E3F = 0xe3f, /*20190814 to latest @@ -17892,6 +17903,7 @@ Total : %s Zeny MSG_ID_E41 = 0xe41, /*20190814 to latest 계정한정판매 등록창 +Limited Account Registration Window */ MSG_ID_E42 = 0xe42, /*20190814 to latest @@ -17916,28 +17928,36 @@ Sale Start Time MSG_ID_E46 = 0xe46, /*20190814 to latest 판매 종료시간 +Sale end time */ MSG_ID_E47 = 0xe47, /*20190814 to latest 계정 한정 +Account only */ MSG_ID_E48 = 0xe48, /*20190814 to 20190814 판매기간 : %d월 %d일 ~ %d월 %d일 20190828 to latest 판매기간 : %d월 %d일 %d시 %d분 +Sale period:% d month% d day% d hours% d */ MSG_ID_E49 = 0xe49, -/*20190814 to latest +/*20190814 to 20190925 구입가능 %d개 +% D available +20191008 to latest +계정당 구매가능 */ MSG_ID_E4A = 0xe4a, /*20190814 to latest %d개 한정 +limited to% d */ MSG_ID_E4B = 0xe4b, /*20190814 to latest >> ItemName : %s / 수량 : %d / 판매기간 : %d월:%d일:%d시:%d분 ~ %d월:%d일:%d시:%d분 +>> ItemName:% s / Quantity:% d / Sales Period:% d Month:% d Day:% d Hour:% d Minute ~% d Month:% d Day:% d Hour:% d Minute */ MSG_ID_E4C = 0xe4c, /*20190814 to latest @@ -17946,30 +17966,36 @@ Sold Out MSG_ID_E4D = 0xe4d, /*20190814 to latest [%s]은(는) 현재 소환할 수 없는 지역에 있습니다. +% s] is currently in a region that cannot be summoned. */ MSG_ID_E4E = 0xe4e, #endif #if PACKETVER >= 20190828 /*20190828 to latest ~ %d월 %d일 %d시 %d분 +% d min% d days% d days */ MSG_ID_E4F = 0xe4f, /*20190828 to latest 상품을 더이상 추가할 수 없습니다 +Can't add any more items */ MSG_ID_E50 = 0xe50, /*20190828 to latest 장착 중인 아이템은 교환할 수 없습니다. 장착을 해제한 뒤 시도해 주시길 바랍니다. +The item being mounted cannot be exchanged. Please unmount it and try again. */ MSG_ID_E51 = 0xe51, #endif #if PACKETVER >= 20190911 /*20190911 to latest 길드 창고 이용 중엔 캐릭터 선택창으로 이동 할 수 없습니다. +You can not move to the character selection window while using the Guild Warehouse. */ MSG_ID_E52 = 0xe52, /*20190911 to latest 아이템 태그가 포함되어 있어 사용할 수 없습니다. +Item tag is included and cannot be used. */ MSG_ID_E53 = 0xe53, /*20190911 to latest @@ -18022,15 +18048,17 @@ Balance: %s %c MSG_ID_E5F = 0xe5f, /*20190911 to latest ^ff0000본 아이템을 구매 후 7일 이내에는 청약 철회가 가능합니다. 다만, 7일이 지났거나 아이템을 개봉하시면 청약 철회 대상에서 제외 됩니다.또한 구매시 사용된 무료캐시는 청약철회시 반환되지 않습니다.^000000 정말로 아이템을 구매하시겠습니까? 구매하실 경우 %s캐시가 차감됩니다. +Do you really want to purchase this item? %s Money will be deducted from your total balance. */ MSG_ID_E60 = 0xe60, /*20190911 to latest ^ff0000본 아이템을 구매 후 7일 이내에는 청약 철회가 가능합니다. 다만, 7일이 지났거나 아이템을 개봉하시면 청약 철회 대상에서 제외 됩니다.또한 구매시 사용된 무료캐시는 청약철회시 반환되지 않습니다.^000000 정말로 아이템을 구매하시겠습니까? 구매하실 경우 일반 %s캐시, 무료 %s캐시가 차감됩니다. +Do you really want to purchase this item? %s Money and %s Free Points will be deducted from your total balance. */ MSG_ID_E61 = 0xe61, -/*20190911 to 20190911 +/*20190911 to latest 호출이 거부되었습니다. -20190918 to latest +20190918 to 20190918 [%s]의 호출이 거부되었습니다. */ MSG_ID_E62 = 0xe62, @@ -18045,6 +18073,34 @@ Balance: %s %c */ MSG_ID_E64 = 0xe64, #endif +#if PACKETVER >= 20190925 +/*20190925 to latest +판매 노점 아이템 리스트가 저장되었습니다. +*/ + MSG_ID_E65 = 0xe65, +/*20190925 to latest +구매 노점 아이템 리스트가 저장되었습니다. +*/ + MSG_ID_E66 = 0xe66, +#endif +#if PACKETVER >= 20191008 +/*20191008 to latest +VTC 인증에 실패하였습니다. +*/ + MSG_ID_E67 = 0xe67, +/*20191008 to latest +물물교환 중에는 장비를 착용할 수 없습니다. +*/ + MSG_ID_E68 = 0xe68, +/*20191008 to latest +교환하려는 품목 +*/ + MSG_ID_E69 = 0xe69, +/*20191008 to latest + 1차, 2차, 3차 직업 스킬 %d개를 더 올려 주십시오. +*/ + MSG_ID_E6A = 0xe6a, +#endif }; #endif /* MAP_MESSAGES_ZERO_H */ diff --git a/src/map/mob.c b/src/map/mob.c index a463e3b9c..2ea189c23 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -479,7 +479,7 @@ static bool mob_ksprotected(struct block_list *src, struct block_list *target) // Message to KS if( DIFF_TICK(sd->ks_floodprotect_tick, tick) <= 0 ) { - sprintf(output, "[KS Warning!! - Owner : %s]", pl_sd->status.name); + sprintf(output, msg_sd(sd, 890), pl_sd->status.name); // [KS Warning!! - Owner : %s] clif_disp_onlyself(sd, output); sd->ks_floodprotect_tick = tick + 2000; @@ -488,7 +488,7 @@ static bool mob_ksprotected(struct block_list *src, struct block_list *target) // Message to Owner if( DIFF_TICK(pl_sd->ks_floodprotect_tick, tick) <= 0 ) { - sprintf(output, "[Watch out! %s is trying to KS you!]", sd->status.name); + sprintf(output, msg_sd(pl_sd, 891), sd->status.name); // [Watch out! %s is trying to KS you!] clif_disp_onlyself(pl_sd, output); pl_sd->ks_floodprotect_tick = tick + 2000; @@ -1299,6 +1299,27 @@ static int mob_warpchase_sub(struct block_list *bl, va_list ap) } return 0; } + +/** + * Checks if a monster is currently involved in battle, + * may it be due to aggression or being attacked. + * @param bl: monster's bl + * @return true if in battle, false otherwise + */ +static bool mob_is_in_battle_state(const struct mob_data *md) +{ + nullpo_retr(false, md); + switch (md->state.skillstate) { + case MSS_BERSERK: + case MSS_ANGRY: + case MSS_RUSH: + case MSS_FOLLOW: + return true; + default: + return false; + } +} + /*========================================== * Processing of slave monsters *------------------------------------------*/ @@ -1343,8 +1364,11 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md, int64 tick) ) { short x = bl->x, y = bl->y; mob_stop_attack(md); - if(map->search_freecell(&md->bl, bl->m, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 1) - && unit->walktoxy(&md->bl, x, y, 0)) + const struct mob_data *m_md = BL_CCAST(BL_MOB, bl); + nullpo_retr(0, m_md); + if (map->search_freecell(&md->bl, bl->m, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 1) + && (battle_config.slave_chase_masters_chasetarget == 0 || !mob->is_in_battle_state(m_md)) + && unit->walktoxy(&md->bl, x, y, 0)) return 1; } } else if (bl->m != md->bl.m && map_flag_gvg(md->bl.m)) { @@ -1355,26 +1379,29 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md, int64 tick) //Avoid attempting to lock the master's target too often to avoid unnecessary overload. [Skotlex] if (DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME && !md->target_id) { - struct unit_data *ud = unit->bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); + struct mob_data *m_md = BL_CAST(BL_MOB, bl); + nullpo_retr(0, ud); + nullpo_retr(0, m_md); md->last_linktime = tick; - - if (ud) { - struct block_list *tbl=NULL; - if (ud->target && ud->state.attack_continue) - tbl=map->id2bl(ud->target); - else if (ud->skilltarget) { - tbl = map->id2bl(ud->skilltarget); - //Required check as skilltarget is not always an enemy. [Skotlex] - if (tbl && battle->check_target(&md->bl, tbl, BCT_ENEMY) <= 0) - tbl = NULL; - } - if (tbl && status->check_skilluse(&md->bl, tbl, 0, 0)) { - md->target_id=tbl->id; - md->min_chase=md->db->range3+distance_bl(&md->bl, tbl); - if(md->min_chase>MAX_MINCHASE) - md->min_chase=MAX_MINCHASE; - return 1; - } + struct block_list *tbl = NULL; + + if (battle_config.slave_chase_masters_chasetarget == 1 && m_md->target_id != 0) { // possibly chasing something + tbl = map->id2bl(m_md->target_id); + } else if (ud->target != 0 && ud->state.attack_continue != 0) { + tbl = map->id2bl(ud->target); + } else if (ud->skilltarget != 0) { + tbl = map->id2bl(ud->skilltarget); + //Required check as skilltarget is not always an enemy. [Skotlex] + if (tbl != NULL && battle->check_target(&md->bl, tbl, BCT_ENEMY) <= 0) + tbl = NULL; + } + if (tbl != NULL && status->check_skilluse(&md->bl, tbl, 0, 0) != 0) { + md->target_id = tbl->id; + md->min_chase = md->db->range3 + distance_bl(&md->bl, tbl); + if (md->min_chase > MAX_MINCHASE) + md->min_chase = MAX_MINCHASE; + return 1; } } return 0; @@ -1912,7 +1939,7 @@ static int mob_ai_hard(int tid, int64 tick, int id, intptr_t data) /** * Adds random options of a given options drop group into item. - * + * * @param item : item receiving random options * @param options : Random Option Drop Group to be used */ @@ -1920,7 +1947,7 @@ static void mob_setdropitem_options(struct item *item, struct optdrop_group *opt { nullpo_retv(item); nullpo_retv(options); - + for (int i = 0; i < options->optslot_count; i++) { if (rnd() % 10000 >= options->optslot_rate[i]) continue; @@ -1952,7 +1979,7 @@ static struct item_drop *mob_setdropitem(int nameid, struct optdrop_group *optio drop->item_data.nameid = nameid; drop->item_data.amount = qty; drop->item_data.identify = data ? itemdb->isidentified2(data) : itemdb->isidentified(nameid); - + // Set item options [KirieZ] if (options != NULL) mob->setdropitem_options(&drop->item_data, options); @@ -3936,7 +3963,7 @@ static bool mob_read_optdrops_option(struct config_setting_t *option, struct opt ShowWarning("mob_read_optdrops_option: Invalid option \"%s\" for option slot %d of %s group, skipping.\n", name, slot, group); return false; } - + int min = 0, max = 0, opt_rate = 0; if (config_setting_is_number(option)) { // OptionName: value @@ -3945,13 +3972,13 @@ static bool mob_read_optdrops_option(struct config_setting_t *option, struct opt // OptionName: [min, max] // OptionName: [min, max, rate] int slen = libconfig->setting_length(option); - + if (slen >= 2) { // [min, max,...] min = libconfig->setting_get_int_elem(option, 0); max = libconfig->setting_get_int_elem(option, 1); } - + if (slen == 3) { // [min, max, rate] opt_rate = libconfig->setting_get_int_elem(option, 2); @@ -3963,7 +3990,7 @@ static bool mob_read_optdrops_option(struct config_setting_t *option, struct opt if (max < min) max = min; - + entry->options[*idx].id = opt_id; entry->options[*idx].min = min; entry->options[*idx].max = max; @@ -3991,7 +4018,7 @@ static bool mob_read_optdrops_optslot(struct config_setting_t *optslot, int n, i nullpo_retr(false, group); Assert_retr(false, group_id >= 0 && group_id < mob->opt_drop_groups_count); Assert_retr(false, n >= 0 && n < MAX_ITEM_OPTIONS); - + // Structure: // { // Rate: chance of option 1 (int) @@ -4015,7 +4042,7 @@ static bool mob_read_optdrops_optslot(struct config_setting_t *optslot, int n, i struct optdrop_group_optslot *entry = &(mob->opt_drop_groups[group_id].optslot[n]); entry->options = aCalloc(sizeof(struct optdrop_group_option), count); - + int idx = 0; int i = 0; struct config_setting_t *opt = NULL; @@ -4027,7 +4054,7 @@ static bool mob_read_optdrops_optslot(struct config_setting_t *optslot, int n, i entry->option_count = idx; mob->opt_drop_groups[group_id].optslot_count++; mob->opt_drop_groups[group_id].optslot_rate[n] = drop_rate; - + // If there're empty rates, calculate them if (calc_rate == true) { for (int j = 0; j < idx; ++j) { @@ -4080,10 +4107,8 @@ static bool mob_read_optdrops_group(struct config_setting_t *group, int n) */ static bool mob_read_optdrops_db(void) { - const char *filename = "option_drop_groups.conf"; // FIXME hardcoded name - char filepath[256]; - safesnprintf(filepath, sizeof(filepath), "%s/%s", map->db_path, filename); + libconfig->format_db_path("option_drop_groups.conf", filepath, sizeof(filepath)); struct config_t option_groups; if (libconfig->load_file(&option_groups, filepath) == CONFIG_FALSE) { @@ -4196,7 +4221,7 @@ static uint32 mob_read_db_mode_sub(struct mob_db *entry, struct config_setting_t /** * Process an entry of mob/mvp drops that contains a random option drop group. - * + * * @param entry : mob db entry being read (used in error messages) * @param item_name : AegisName of the item in this entry (used in error messages) * @param drop : drop data entry @@ -4219,7 +4244,7 @@ static struct optdrop_group *mob_read_db_drops_option(struct mob_db *entry, cons int i32; if (mob->get_const(libconfig->setting_get_elem(drop, 0), &i32) && i32 >= 0) *drop_rate = i32; - + const char *group_name = libconfig->setting_get_string_elem(drop, 1); if (group_name == NULL || *group_name == '\0') { ShowError("mob_read_db_optdrops: Missing option drop group name on item \"%s\" in monster %d, skipping.\n", item_name, entry->mob_id); @@ -4264,7 +4289,7 @@ static void mob_read_db_mvpdrops_sub(struct mob_db *entry, struct config_setting i++; continue; } - + struct optdrop_group *drop_option = NULL; if (config_setting_is_number(drop)) { // Setting is a number, item doesn't contain options @@ -4344,7 +4369,7 @@ static void mob_read_db_drops_sub(struct mob_db *entry, struct config_setting_t // (Drop Rate, "Opt Drop Group") drop_option = mob->read_db_drops_option(entry, name, drop, &value); } - + if (value <= 0) { ShowWarning("mob_read_db: wrong drop chance %d for drop item %s in monster %d\n", value, name, entry->mob_id); i++; @@ -5672,7 +5697,7 @@ static void mob_destroy_drop_groups(void) { for (int i = 0; i < mob->opt_drop_groups_count; i++) { struct optdrop_group *group = &mob->opt_drop_groups[i]; - + for (int j = 0; j < group->optslot_count; j++) { aFree(group->optslot[j].options); } @@ -5807,6 +5832,7 @@ void mob_defaults(void) mob->ai_sub_hard_bg_ally = mob_ai_sub_hard_bg_ally; mob->ai_sub_hard_lootsearch = mob_ai_sub_hard_lootsearch; mob->warpchase_sub = mob_warpchase_sub; + mob->is_in_battle_state = mob_is_in_battle_state; mob->ai_sub_hard_slavemob = mob_ai_sub_hard_slavemob; mob->unlocktarget = mob_unlocktarget; mob->randomwalk = mob_randomwalk; diff --git a/src/map/mob.h b/src/map/mob.h index a48c4cc74..9b0f6ffe0 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -529,6 +529,7 @@ struct mob_interface { int (*ai_sub_hard_bg_ally) (struct block_list *bl, va_list ap); int (*ai_sub_hard_lootsearch) (struct block_list *bl, va_list ap); int (*warpchase_sub) (struct block_list *bl, va_list ap); + bool (*is_in_battle_state) (const struct mob_data *md); int (*ai_sub_hard_slavemob) (struct mob_data *md, int64 tick); int (*unlocktarget) (struct mob_data *md, int64 tick); int (*randomwalk) (struct mob_data *md, int64 tick); diff --git a/src/map/packets_keys_main.h b/src/map/packets_keys_main.h index b7f25a83d..d02e7f20d 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, 2019-08-28aRagexe, 2019-08-28aRagexeRE, 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-04bRagexeRE, 2019-09-18bRagexe, 2019-09-18cRagexeRE +// 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, 2019-09-25aRagexe, 2019-09-25aRagexeRE, 2019-09-25bRagexe, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexe, 2019-10-16fRagexeRE, 2019-10-16gRagexe, 2019-10-16gRagexeRE #if PACKETVER == 20101123 || \ PACKETVER == 20101124 || \ PACKETVER == 20101125 || \ @@ -165,7 +165,10 @@ PACKETVER == 20190821 || \ PACKETVER == 20190828 || \ PACKETVER == 20190904 || \ - PACKETVER >= 20190918 + PACKETVER == 20190918 || \ + PACKETVER == 20190925 || \ + PACKETVER == 20191002 || \ + PACKETVER >= 20191016 packetKeys(0x00000000,0x00000000,0x00000000); #endif diff --git a/src/map/packets_keys_zero.h b/src/map/packets_keys_zero.h index 2708d11e1..e4319817b 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, 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_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, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero #if PACKETVER == 20171018 || \ PACKETVER == 20171019 || \ PACKETVER == 20171023 || \ @@ -94,7 +94,9 @@ PACKETVER == 20190814 || \ PACKETVER == 20190828 || \ PACKETVER == 20190911 || \ - PACKETVER >= 20190918 + PACKETVER == 20190918 || \ + PACKETVER == 20190925 || \ + PACKETVER >= 20191008 packetKeys(0x00000000,0x00000000,0x00000000); #endif diff --git a/src/map/packets_shuffle_main.h b/src/map/packets_shuffle_main.h index e3e798dd1..ede178384 100644 --- a/src/map/packets_shuffle_main.h +++ b/src/map/packets_shuffle_main.h @@ -9794,9 +9794,12 @@ packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14 #endif -// 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-18bRagexe +// 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-18bRagexe, 2019-09-25aRagexe, 2019-09-25bRagexe, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-16fRagexe, 2019-10-16gRagexe #if PACKETVER == 20190904 || \ - PACKETVER == 20190918 + PACKETVER == 20190918 || \ + PACKETVER == 20190925 || \ + PACKETVER == 20191002 || \ + PACKETVER == 20191016 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 diff --git a/src/map/packets_shuffle_re.h b/src/map/packets_shuffle_re.h index f2a1b96ad..049d4808a 100644 --- a/src/map/packets_shuffle_re.h +++ b/src/map/packets_shuffle_re.h @@ -9744,9 +9744,12 @@ packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 14 #endif -// 2019-09-04bRagexeRE, 2019-09-18cRagexeRE +// 2019-09-04bRagexeRE, 2019-09-18cRagexeRE, 2019-09-25aRagexeRE, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexeRE, 2019-10-16gRagexeRE #if PACKETVER == 20190904 || \ - PACKETVER == 20190918 + PACKETVER == 20190918 || \ + PACKETVER == 20190925 || \ + PACKETVER == 20191002 || \ + PACKETVER == 20191016 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 diff --git a/src/map/packets_shuffle_zero.h b/src/map/packets_shuffle_zero.h index 4d6da7a8a..0259a9555 100644 --- a/src/map/packets_shuffle_zero.h +++ b/src/map/packets_shuffle_zero.h @@ -803,10 +803,12 @@ 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 +// 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero #if PACKETVER == 20190828 || \ PACKETVER == 20190911 || \ - PACKETVER == 20190918 + PACKETVER == 20190918 || \ + PACKETVER == 20190925 || \ + PACKETVER == 20191008 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 diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index 9c8c93865..c0d1054d7 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -1183,7 +1183,8 @@ struct ZC_STORE_ITEMLIST_NORMAL { struct NORMALITEM_INFO list[MAX_ITEMLIST]; } __attribute__((packed)); -struct ZC_INVENTORY_START { +#if PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002 +struct PACKET_ZC_INVENTORY_START { int16 packetType; #if PACKETVER_RE_NUM >= 20180919 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002 int16 packetLength; @@ -1197,14 +1198,19 @@ struct ZC_INVENTORY_START { char name[NAME_LENGTH]; #endif } __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_INVENTORY_START, 0x0b08); +#endif // PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002 -struct ZC_INVENTORY_END { +#if PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002 +struct PACKET_ZC_INVENTORY_END { int16 packetType; #if PACKETVER_RE_NUM >= 20180912 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002 uint8 invType; #endif char flag; } __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_INVENTORY_END, 0x0b0b); +#endif // PACKETVER_RE_NUM >= 20180829 || PACKETVER_ZERO_NUM >= 20180919 || PACKETVER_MAIN_NUM >= 20181002 struct ZC_STORE_ITEMLIST_EQUIP { int16 PacketType; @@ -3523,7 +3529,7 @@ DEFINE_PACKET_HEADER(ZC_HAT_EFFECT, 0x0a3b); #endif // [4144] this struct updated not in all packets in client -#if PACKETVER_RE_NUM >= 20190807 +#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190918 struct SKILLDATA { uint16 id; int inf; @@ -3549,7 +3555,7 @@ struct PACKET_ZC_ADD_SKILL { int16 packetType; struct SKILLDATA skill; } __attribute__((packed)); -#if PACKETVER_RE_NUM >= 20190807 +#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190918 DEFINE_PACKET_HEADER(ZC_ADD_SKILL, 0x0b31); #else DEFINE_PACKET_HEADER(ZC_ADD_SKILL, 0x0111); @@ -3560,13 +3566,13 @@ struct PACKET_ZC_SKILLINFO_LIST { int16 packetLength; struct SKILLDATA skills[]; } __attribute__((packed)); -#if PACKETVER_RE_NUM >= 20190807 +#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190918 DEFINE_PACKET_HEADER(ZC_SKILLINFO_LIST, 0x0b32); #else DEFINE_PACKET_HEADER(ZC_SKILLINFO_LIST, 0x010f); #endif -#if PACKETVER_RE_NUM >= 20190807 +#if PACKETVER_RE_NUM >= 20190807 || PACKETVER_ZERO_NUM >= 20190918 struct PACKET_ZC_SKILLINFO_UPDATE2 { int16 packetType; uint16 id; diff --git a/src/map/party.c b/src/map/party.c index 9fbe915f3..35ffe5636 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -695,6 +695,7 @@ static int party_broken(int party_id) if( p->data[i].sd!=NULL ) { clif->party_withdraw(p,p->data[i].sd,p->party.member[i].account_id,p->party.member[i].name,0x10); p->data[i].sd->status.party_id=0; + clif->charnameupdate(p->data[i].sd); } } diff --git a/src/map/pc.c b/src/map/pc.c index 2cefa7674..a8ff661e8 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4441,7 +4441,7 @@ static int pc_payzeny(struct map_session_data *sd, int zeny, enum e_log_pick_typ if (sd->state.showzeny) { char output[255]; - sprintf(output, "Removed %dz.", zeny); + sprintf(output, msg_sd(sd, 885), zeny); // Removed %dz. clif_disp_onlyself(sd, output); } } @@ -4580,7 +4580,7 @@ static int pc_getzeny(struct map_session_data *sd, int zeny, enum e_log_pick_typ if (sd->state.showzeny) { char output[255]; - sprintf(output, "Gained %dz.", zeny); + sprintf(output, msg_sd(sd, 886), zeny); // Gained %dz. clif_disp_onlyself(sd, output); } } @@ -5535,9 +5535,9 @@ static int pc_show_steal(struct block_list *bl, va_list ap) nullpo_ret(sd); if((item=itemdb->exists(itemid))==NULL) - sprintf(output,"%s stole an Unknown Item (id: %i).",sd->status.name, itemid); + sprintf(output, msg_sd(sd, 887), sd->status.name, itemid); // %s stole an Unknown Item (id: %i). else - sprintf(output,"%s stole %s.",sd->status.name,item->jname); + sprintf(output, msg_sd(sd, 888), sd->status.name, item->jname); // %s stole %s. clif->message(tsd->fd, output); return 0; @@ -7084,7 +7084,7 @@ static bool pc_gainexp(struct map_session_data *sd, struct block_list *src, uint if(sd->state.showexp) { char output[256]; sprintf(output, - "Experience Gained Base:%"PRIu64" (%.2f%%) Job:%"PRIu64" (%.2f%%)", + msg_sd(sd, 889), // Experience Gained Base:%"PRIu64" (%.2f%%) Job:%"PRIu64" (%.2f%%) base_exp, nextbp * (float)100, job_exp, nextjp * (float)100); clif_disp_onlyself(sd, output); } @@ -11533,12 +11533,9 @@ static bool pc_read_exp_db(void) struct config_t exp_db_conf; struct config_setting_t *edb = NULL; int entry_count = 0; - -#ifdef RENEWAL - const char *config_filename = "db/re/exp_group_db.conf"; -#else - const char *config_filename = "db/pre-re/exp_group_db.conf"; -#endif + char config_filename[256]; + + libconfig->format_db_path(DBPATH"exp_group_db.conf", config_filename, sizeof(config_filename)); if (!libconfig->load_file(&exp_db_conf, config_filename)) return false; diff --git a/src/map/script.c b/src/map/script.c index 0fe97574c..bd0fbb611 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -5150,7 +5150,8 @@ static uint8 script_add_language(const char *name) static void script_load_translations(void) { struct config_t translations_conf; - const char *config_filename = "db/translations.conf"; // FIXME hardcoded name + char config_filename[256]; + libconfig->format_db_path("translations.conf", config_filename, sizeof(config_filename)); struct config_setting_t *translations = NULL; int i, size; int total = 0; @@ -5189,8 +5190,8 @@ static void script_load_translations(void) size = libconfig->setting_length(translations); for(i = 0; i < size; i++) { - const char *translation_file = libconfig->setting_get_string_elem(translations, i); - total += script->load_translation(translation_file, ++lang_id); + const char *translation_dir = libconfig->setting_get_string_elem(translations, i); + total += script->load_translation(translation_dir, ++lang_id); } libconfig->destroy(&translations_conf); @@ -5227,39 +5228,39 @@ static void script_load_translations(void) } /** - * Generates a language name from a translation filename. + * Generates a language name from a translation directory name. * - * @param file The filename. + * @param directory The directory name. * @return The corresponding translation name. */ -static const char *script_get_translation_file_name(const char *file) +static const char *script_get_translation_dir_name(const char *directory) { const char *basename = NULL, *last_dot = NULL; - nullpo_retr("Unknown", file); + nullpo_retr("Unknown", directory); - basename = strrchr(file, '/');; + basename = strrchr(directory, '/'); #ifdef WIN32 { - const char *basename_windows = strrchr(file, '\\'); + const char *basename_windows = strrchr(directory, '\\'); if (basename_windows > basename) basename = basename_windows; } #endif // WIN32 if (basename == NULL) - basename = file; + basename = directory; else basename++; // Skip slash Assert_retr("Unknown", *basename != '\0'); last_dot = strrchr(basename, '.'); if (last_dot != NULL) { - static char file_name[200]; + static char dir_name[200]; if (last_dot == basename) return basename + 1; - safestrncpy(file_name, basename, last_dot - basename + 1); - return file_name; + safestrncpy(dir_name, basename, last_dot - basename + 1); + return dir_name; } return basename; @@ -5340,18 +5341,19 @@ static bool script_load_translation_addstring(const char *file, uint8 lang_id, c /** * Parses an individual translation file. * - * @param file The filename to parse. + * @param directory The directory structure to read. * @param lang_id The language identifier. * @return The amount of strings loaded. */ -static int script_load_translation(const char *file, uint8 lang_id) +static int script_load_translation_file(const char *file, uint8 lang_id) { - int translations = 0; char line[1024]; - char msgctxt[NAME_LENGTH*2+1] = { 0 }; - FILE *fp; - int lineno = 0; + char msgctxt[NAME_LENGTH*2+1] = ""; struct script_string_buf msgid, msgstr; + struct script_string_buf *msg_ptr; + int translations = 0; + int lineno = 0; + FILE *fp; nullpo_ret(file); @@ -5363,46 +5365,50 @@ static int script_load_translation(const char *file, uint8 lang_id) VECTOR_INIT(msgid); VECTOR_INIT(msgstr); - script->add_language(script->get_translation_file_name(file)); - if (lang_id >= atcommand->max_message_table) - atcommand->expand_message_table(); - while (fgets(line, sizeof(line), fp) != NULL) { int len = (int)strlen(line); int i; lineno++; - if(len <= 1) + if (len <= 1) { + if (VECTOR_LENGTH(msgid) > 0 && VECTOR_LENGTH(msgstr) > 0) { + // Add string + if (script->load_translation_addstring(file, lang_id, msgctxt, &msgid, &msgstr)) + translations++; + + msgctxt[0] = '\0'; + VECTOR_TRUNCATE(msgid); + VECTOR_TRUNCATE(msgstr); + } continue; + } if (line[0] == '#') continue; - if (VECTOR_LENGTH(msgid) > 0 && VECTOR_LENGTH(msgstr) > 0) { + if (VECTOR_LENGTH(msgid) > 0) { + if (VECTOR_LENGTH(msgstr) > 0) { + msg_ptr = &msgstr; + } else { + msg_ptr = &msgid; + } if (line[0] == '"') { // Continuation line - (void)VECTOR_POP(msgstr); // Pop final '\0' - for (i = 8; i < len - 2; i++) { - VECTOR_ENSURE(msgstr, 1, 512); + (void)VECTOR_POP(*msg_ptr); // Pop final '\0' + for (i = 1; i < len - 2; i++) { + VECTOR_ENSURE(*msg_ptr, 1, 512); if (line[i] == '\\' && line[i+1] == '"') { - VECTOR_PUSH(msgstr, '"'); + VECTOR_PUSH(*msg_ptr, '"'); i++; } else { - VECTOR_PUSH(msgstr, line[i]); + VECTOR_PUSH(*msg_ptr, line[i]); } } - VECTOR_ENSURE(msgstr, 1, 512); - VECTOR_PUSH(msgstr, '\0'); + VECTOR_ENSURE(*msg_ptr, 1, 512); + VECTOR_PUSH(*msg_ptr, '\0'); continue; } - // Add string - if (script->load_translation_addstring(file, lang_id, msgctxt, &msgid, &msgstr)) - translations++; - - msgctxt[0] = '\0'; - VECTOR_TRUNCATE(msgid); - VECTOR_TRUNCATE(msgstr); } if (strncasecmp(line,"msgctxt \"", 9) == 0) { @@ -5477,10 +5483,47 @@ static int script_load_translation(const char *file, uint8 lang_id) VECTOR_CLEAR(msgid); VECTOR_CLEAR(msgstr); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' translations in '"CL_WHITE"%s"CL_RESET"'.\n", translations, file); return translations; } +struct load_translation_data { + uint8 lang_id; + int translation_count; +}; + +static void script_load_translation_sub(const char *filename, void *context) +{ + nullpo_retv(context); + + struct load_translation_data *data = context; + + data->translation_count += script->load_translation_file(filename, data->lang_id); +} + +/** + * Loads a translations directory + * + * @param directory The directory structure to read. + * @param lang_id The language identifier. + * @return The amount of strings loaded. + */ +static int script_load_translation(const char *directory, uint8 lang_id) +{ + struct load_translation_data data = { 0 }; + data.lang_id = lang_id; + + nullpo_ret(directory); + + script->add_language(script->get_translation_dir_name(directory)); + if (lang_id >= atcommand->max_message_table) + atcommand->expand_message_table(); + + findfile(directory, ".po", script_load_translation_sub, &data); + + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' translations in '"CL_WHITE"%s"CL_RESET"'.\n", data.translation_count, directory); + return data.translation_count; +} + /** * **/ @@ -18494,10 +18537,12 @@ static BUILDIN(npcshopdelitem) unsigned int nameid = script_getnum(st,i); ARR_FIND(0, size, n, nd->u.shop.shop_item[n].nameid == nameid); - if (n < size) { - memmove(&nd->u.shop.shop_item[n], &nd->u.shop.shop_item[n+1], sizeof(nd->u.shop.shop_item[0])*(size-n)); - size--; + if (n == size) { + continue; + } else if (n < size - 1) { + memmove(&nd->u.shop.shop_item[n], &nd->u.shop.shop_item[n+1], sizeof(nd->u.shop.shop_item[0]) * (size - n - 1)); } + size--; } RECREATE(nd->u.shop.shop_item, struct npc_item_list, size); @@ -27512,12 +27557,13 @@ void script_defaults(void) script->string_dup = script_string_dup; script->load_translations = script_load_translations; script->load_translation_addstring = script_load_translation_addstring; + script->load_translation_file = script_load_translation_file; script->load_translation = script_load_translation; script->translation_db_destroyer = script_translation_db_destroyer; script->clear_translations = script_clear_translations; script->parse_cleanup_timer = script_parse_cleanup_timer; script->add_language = script_add_language; - script->get_translation_file_name = script_get_translation_file_name; + script->get_translation_dir_name = script_get_translation_dir_name; script->parser_clean_leftovers = script_parser_clean_leftovers; script->run_use_script = script_run_use_script; diff --git a/src/map/script.h b/src/map/script.h index 57652e77a..1cec02b97 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -1039,12 +1039,13 @@ struct script_interface { int (*string_dup) (char *str); void (*load_translations) (void); bool (*load_translation_addstring) (const char *file, uint8 lang_id, const char *msgctxt, const struct script_string_buf *msgid, const struct script_string_buf *msgstr); - int (*load_translation) (const char *file, uint8 lang_id); + int (*load_translation_file) (const char *file, uint8 lang_id); + int (*load_translation) (const char *directory, uint8 lang_id); int (*translation_db_destroyer) (union DBKey key, struct DBData *data, va_list ap); void (*clear_translations) (bool reload); int (*parse_cleanup_timer) (int tid, int64 tick, int id, intptr_t data); uint8 (*add_language) (const char *name); - const char *(*get_translation_file_name) (const char *file); + const char *(*get_translation_dir_name) (const char *directory); void (*parser_clean_leftovers) (void); 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); diff --git a/src/map/skill.c b/src/map/skill.c index ad27ef0e3..7451fbf41 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -3789,7 +3789,7 @@ static int skill_check_condition_mercenary(struct block_list *bl, int skill_id, if (itemid[i] < 1) continue; // No item index[i] = pc->search_inventory(sd, itemid[i]); if (index[i] == INDEX_NOT_FOUND || sd->status.inventory[index[i]].amount < amount[i]) { - clif->skill_fail(sd, skill_id, USESKILL_FAIL_NEED_ITEM, amount[i], itemid[i] << 16); + clif->skill_fail(sd, skill_id, USESKILL_FAIL_NEED_ITEM, amount[i], itemid[i]); return 0; } } @@ -6530,10 +6530,6 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * clif->skill_nodamage (src,src,skill_id,skill_lv,1); // Initiate 10% of your damage becomes fire element. sc_start4(src,src,SC_SUB_WEAPONPROPERTY,100,3,20,0,0,skill->get_time2(skill_id, skill_lv)); - if( sd ) - skill->blockpc_start(sd, skill_id, skill->get_time(skill_id, skill_lv)); - else if( bl->type == BL_MER ) - skill->blockmerc_start(BL_UCAST(BL_MER, bl), skill_id, skill->get_time(skill_id, skill_lv)); break; case TK_JUMPKICK: @@ -7205,7 +7201,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * // custom hack to make the mob display the skill, because these skills don't show the skill use text themselves //NOTE: mobs don't have the sprite animation that is used when performing this skill (will cause glitches) char temp[70]; - snprintf(temp, sizeof(temp), "%s : %s !!", md->name, skill->get_desc(skill_id)); + snprintf(temp, sizeof(temp), msg_txt(882), md->name, skill->get_desc(skill_id)); // %s : %s !! clif->disp_overhead(&md->bl, temp, AREA_CHAT_WOC, NULL); } break; @@ -8758,12 +8754,20 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * int r = rnd()%100; int target = (skill_lv-1)%5; int hp; - if(r<per[target][0]) //Self + if (r < per[target][0]) { //Self bl = src; - else if(r<per[target][1]) //Master + } else if (r < per[target][1]) { //Master bl = battle->get_master(src); - else //Enemy - bl = map->id2bl(battle->get_target(src)); + } else if ((per[target][1] - per[target][0]) < per[target][0] + && bl == battle->get_master(src)) { + /** + * Skill rolled for enemy, but there's nothing the Homunculus is attacking. + * So bl has been set to its master in unit->skilluse_id2. + * If it's more likely that it will heal itself, + * we let it heal itself. + */ + bl = src; + } if (!bl) bl = src; hp = skill->calc_heal(src, bl, skill_id, 1+rnd()%skill_lv, true); @@ -14669,7 +14673,7 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s if (map->foreachinrange(mob->count_sub, &sd->bl, skill->get_splash(skill_id, skill_lv), BL_MOB, MOBID_EMPELIUM, MOBID_S_EMPEL_1, MOBID_S_EMPEL_2)) { char output[128]; - sprintf(output, "You're too close to a stone or emperium to do this skill"); /* TODO official response? or message.conf it */ + sprintf(output, "%s", msg_txt(883)); /* TODO official response */ // You are too close to a stone or emperium to do this skill clif->messagecolor_self(sd->fd, COLOR_RED, output); return 0; } @@ -15116,7 +15120,7 @@ static int skill_check_condition_castend(struct map_session_data *sd, uint16 ski return 0; } else if( sd->status.inventory[i].amount < require.ammo_qty ) { char e_msg[100]; - sprintf(e_msg,"Skill Failed. [%s] requires %dx %s.", + sprintf(e_msg, msg_txt(884), // Skill Failed. [%s] requires %dx %s. skill->get_desc(skill_id), require.ammo_qty, itemdb_jname(sd->status.inventory[i].nameid)); @@ -21105,7 +21109,7 @@ static bool skill_read_skilldb(const char *filename) nullpo_retr(false, filename); - sprintf(filepath,"db/%s",filename); + libconfig->format_db_path(filename, filepath, sizeof(filepath)); if (!libconfig->load_file(&skilldb, filepath)) { return false; // Libconfig error report. diff --git a/src/map/status.c b/src/map/status.c index 71cce28c5..d2c67b84e 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -7515,7 +7515,7 @@ static void status_display_remove(struct map_session_data *sd, enum sc_type type } /** - * Starts a status change. + * Starts a status change with a set remaining time. * * @param src Status change source bl. * @param bl Status change target bl. @@ -7525,13 +7525,14 @@ static void status_display_remove(struct map_session_data *sd, enum sc_type type * @param val2 Additional value (meaning depends on type). * @param val3 Additional value (meaning depends on type). * @param val4 Additional value (meaning depends on type). - * @param tick Base duration (milliseconds). + * @param tick Remaining duration (miliseconds). (if flag doesn't contain SCFLAG_LOADED, it will become the final total_tick) + * @param total_tick Base duration (milliseconds). * @param flag Special flags (@see enum scstart_flag). * * @retval 0 if no status change happened. * @retval 1 if the status change was successfully applied. */ -static int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag) +static int status_change_start_sub(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int total_tick, int flag) { struct map_session_data *sd = NULL; struct status_change* sc; @@ -7545,7 +7546,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en st = status->get_status_data(bl); if (type <= SC_NONE || type >= SC_MAX) { - ShowError("status_change_start: invalid status change (%d)!\n", type); + ShowError("status_change_start_sub: invalid status change (%d)!\n", type); return 0; } @@ -7570,10 +7571,10 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en sd = BL_CAST(BL_PC, bl); - //Adjust tick according to status resistances + //Adjust total_tick according to status resistances if( !(flag&(SCFLAG_NOAVOID|SCFLAG_LOADED)) ) { - tick = status->get_sc_def(src, bl, type, rate, tick, flag); - if( !tick ) return 0; + total_tick = status->get_sc_def(src, bl, type, rate, total_tick, flag); + if( !total_tick ) return 0; } undead_flag = battle->check_undead(st->race, st->def_ele); @@ -7724,7 +7725,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en } if (!opt_flag) return 0; } - if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC + if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; case SC_NOEQUIPSHIELD: if (val2 == 1) { @@ -7740,7 +7741,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } } - if (tick == 1) + if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; case SC_NOEQUIPARMOR: @@ -7753,7 +7754,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en return 0; pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } - if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC + if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; case SC_NOEQUIPHELM: if (sd && !(flag&SCFLAG_LOADED)) { @@ -7765,7 +7766,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en return 0; pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } - if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC + if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; case SC_MER_FLEE: case SC_MER_ATK: @@ -7819,7 +7820,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en if( i < 0 ) return 0; } - if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC + if (total_tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; case SC_TOXIN: case SC_PARALYSE: @@ -7989,33 +7990,33 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en int i; for( i = 0; i < MAX_PC_DEVOTION; i++ ) { if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL) - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } else if (bl->type == BL_MER) { struct mercenary_data *mc = BL_UCAST(BL_MER, bl); if (mc->devotion_flag && (tsd = mc->master) != NULL) { - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } } //val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk) if (val4) - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; break; case SC_AUTOBERSERK: if (st->hp < st->max_hp>>2 && (!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0)) sc_start4(src,bl,SC_PROVOKE,100,10,1,0,0,60000); - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; break; case SC_CRUCIS: val2 = 10 + 4*val1; //Def reduction - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; clif->emotion(bl,E_SWT); break; case SC_MAXIMIZEPOWER: - tick_time = val2 = tick>0?tick:60000; - tick = INFINITE_DURATION; // duration sent to the client should be infinite + tick_time = val2 = total_tick>0?total_tick:60000; + total_tick = INFINITE_DURATION; // duration sent to the client should be infinite break; case SC_EDP: // [Celest] //Chance to Poison enemies. @@ -8026,7 +8027,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en #endif val3 = 50 * (val1 + 1); //Damage increase (+50 +50*lv%) if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds - tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000; + total_tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000; break; case SC_POISONREACT: val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex] @@ -8056,7 +8057,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en break; case SC_SACRIFICE: val2 = 5; //Lasts 5 hits - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; break; case SC_ENCHANTPOISON: val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate @@ -8093,12 +8094,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en int i; for( i = 0; i < MAX_PC_DEVOTION; i++ ) { if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL) - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } else if (bl->type == BL_MER) { struct mercenary_data *mc = BL_UCAST(BL_MER, bl); if (mc->devotion_flag && (tsd = mc->master) != NULL) { - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } } @@ -8177,9 +8178,9 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en //val3 : Brings the skill_lv (merged into val1 here) //val4 : Partner if (val1 == CG_MOONLIT) - clif->status_change(bl,SI_MOON,1,tick,0, 0, 0); + clif->status_change(bl,SI_MOON,1,total_tick,0, 0, 0); val1|= (val3<<16); - val3 = tick/1000; //Tick duration + val3 = total_tick/1000; //Tick duration tick_time = 1000; // [GodLesZ] tick time break; case SC_LONGING: @@ -8216,7 +8217,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en // mmocharstatus.manner, each negative point results in 1 minute with this status activated // This is done this way because the message that the client displays is hardcoded, and only // shows how many minutes are remaining. [Panikon] - tick = 60000; + total_tick = 60000; val1 = battle_config.manner_system; //Mute filters. if (sd) { @@ -8226,11 +8227,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en break; case SC_STONE: - val3 = tick/1000; //Petrified HP-damage iterations. + val3 = total_tick/1000; //Petrified HP-damage iterations. if(val3 < 1) val3 = 1; - tick = val4; //Petrifying time. + total_tick = val4; //Petrifying time. if(val4 > 500) // not with WL_SIENNAEXECRATE - tick = max(tick, 1000); //Min time + total_tick = max(total_tick, 1000); //Min time calc_flag = 0; //Actual status changes take effect on petrified state. break; @@ -8249,7 +8250,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en } // fall through case SC_POISON: - val3 = tick/1000; //Damage iterations + val3 = total_tick/1000; //Damage iterations if(val3 < 1) val3 = 1; tick_time = 1000; // [GodLesZ] tick time //val4: HP damage @@ -8263,7 +8264,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en clif->emotion(bl,E_WHAT); break; case SC_BLOODING: - val4 = tick/10000; + val4 = total_tick/10000; if (!val4) val4 = 1; tick_time = 10000; // [GodLesZ] tick time break; @@ -8276,7 +8277,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en // val2 = seconds between heals // val4 = total of heals if (val2 < 1) val2 = 1; - if ((val4 = tick / (val2 * 1000)) < 1) + if ((val4 = total_tick / (val2 * 1000)) < 1) val4 = 1; tick_time = val2 * 1000; // [GodLesZ] tick time break; @@ -8289,19 +8290,19 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en return 0; // No need to start SC } val1 = boss_md->bl.id; - if( (val4 = tick/1000) < 1 ) + if( (val4 = total_tick/1000) < 1 ) val4 = 1; tick_time = 1000; // [GodLesZ] tick time } break; case SC_HIDING: - val2 = tick/1000; + val2 = total_tick/1000; tick_time = 1000; // [GodLesZ] tick time val3 = 0; // unused, previously speed adjustment val4 = val1+3; //Seconds before SP substraction happen. break; case SC_CHASEWALK: - val2 = tick>0?tick:10000; //Interval at which SP is drained. + val2 = total_tick>0?total_tick:10000; //Interval at which SP is drained. val3 = 35 - 5 * val1; //Speed adjustment. if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE) val3 -= 40; @@ -8311,8 +8312,8 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en case SC_CLOAKING: if (!sd) //Monsters should be able to walk with no penalties. [Skotlex] val1 = 10; - tick_time = val2 = tick>0?tick:60000; //SP consumption rate. - tick = INFINITE_DURATION; // duration sent to the client should be infinite + tick_time = val2 = total_tick>0?total_tick:60000; //SP consumption rate. + total_tick = INFINITE_DURATION; // duration sent to the client should be infinite val3 = 0; // unused, previously walk speed adjustment //val4&1 signals the presence of a wall. //val4&2 makes cloak not end on normal attacks [Skotlex] @@ -8326,7 +8327,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en case SC_RUWACH: case SC_WZ_SIGHTBLASTER: val3 = skill->get_splash(val2, val1); //Val2 should bring the skill-id. - val2 = tick/20; + val2 = total_tick/20; tick_time = 20; // [GodLesZ] tick time break; @@ -8344,7 +8345,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en case SC_DODGE_READY: case SC_PUSH_CART: case SC_DAILYSENDMAILCNT: - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; break; case SC_AUTOGUARD: @@ -8360,12 +8361,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en if( sd ) { for( i = 0; i < MAX_PC_DEVOTION; i++ ) { if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL) - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } else if (bl->type == BL_MER) { struct mercenary_data *mc = BL_UCAST(BL_MER, bl); if (mc->devotion_flag && (tsd = mc->master) != NULL) { - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, total_tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } } @@ -8384,7 +8385,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en for (i = 0; i < MAX_PC_DEVOTION; i++) { //See if there are devoted characters, and pass the status to them. [Skotlex] if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL) - status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,SCFLAG_NOAVOID); + status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,total_tick,SCFLAG_NOAVOID); } } } @@ -8397,8 +8398,8 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en } val2 = 12; //SP cost val4 = 10000; //Decrease at 10secs intervals. - val3 = tick/val4; - tick = INFINITE_DURATION; // duration sent to the client should be infinite + val3 = total_tick/val4; + total_tick = INFINITE_DURATION; // duration sent to the client should be infinite tick_time = val4; // [GodLesZ] tick time break; case SC_PARRYING: @@ -8416,21 +8417,21 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en case SC_BERSERK: if( val3 == SC__BLOODYLUST ) - sc_start(src,bl,(sc_type)val3,100,val1,tick); + sc_start(src,bl,(sc_type)val3,100,val1,total_tick); if (!val3 && (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4)) - sc_start4(src, bl, SC_ENDURE, 100,10,0,0,2, tick); + sc_start4(src, bl, SC_ENDURE, 100,10,0,0,2, total_tick); //HP healing is performing after the calc_status call. //Val2 holds HP penalty if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1); if (!val4) val4 = 10000; //Val4 holds damage interval - val3 = tick/val4; //val3 holds skill duration + val3 = total_tick/val4; //val3 holds skill duration tick_time = val4; // [GodLesZ] tick time break; case SC_GOSPEL: if(val4 == BCT_SELF) { // self effect - val2 = tick/10000; + val2 = total_tick/10000; tick_time = 10000; // [GodLesZ] tick time status->change_clear_buffs(bl,3); //Remove buffs/debuffs } @@ -8494,12 +8495,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en case SC_SWORDREJECT: val2 = 15*val1; //Reflect chance val3 = 3; //Reflections - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; break; case SC_MEMORIZE: val2 = 5; //Memorized casts. - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; break; case SC_GRAVITATION: @@ -8553,11 +8554,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en struct status_change_entry *sce2 = sc2 ? sc2->data[SC_RG_CCONFINE_M] : NULL; if (src2 && sc2) { if (!sce2) //Start lock on caster. - sc_start4(src,src2,SC_RG_CCONFINE_M,100,val1,1,0,0,tick+1000); + sc_start4(src,src2,SC_RG_CCONFINE_M,100,val1,1,0,0,total_tick+1000); else { //Increase count of locked enemies and refresh time. (sce2->val2)++; timer->delete(sce2->timer, status->change_timer); - sce2->timer = timer->add(timer->gettick()+tick+1000, status->change_timer, src2->id, SC_RG_CCONFINE_M); + sce2->timer = timer->add(timer->gettick()+total_tick+1000, status->change_timer, src2->id, SC_RG_CCONFINE_M); } } else //Status failed. return 0; @@ -8593,13 +8594,13 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en //val4: TK: Combo time struct unit_data *ud = unit->bl2ud(bl); if( ud && (!val3 || val3 == 2) ) { - tick += 300 * battle_config.combo_delay_rate/100; - ud->attackabletime = timer->gettick()+tick; + total_tick += 300 * battle_config.combo_delay_rate/100; + ud->attackabletime = timer->gettick()+total_tick; if( !val3 ) - unit->set_walkdelay(bl, timer->gettick(), tick, 1); + unit->set_walkdelay(bl, timer->gettick(), total_tick, 1); } val3 = 0; - val4 = tick; + val4 = total_tick; break; } case SC_EARTHSCROLL: @@ -8613,7 +8614,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val3 = (int)(currenttick&0x00000000ffffffffLL); val4 = (int)((currenttick&0xffffffff00000000LL)>>32); } - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; break; case SC_KAAHI: val2 = 200*val1; //HP heal @@ -8628,7 +8629,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en break; case SC_TRICKDEAD: if (vd) vd->dead_sit = 1; - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; break; case SC_CONCENTRATION: val2 = 2 + val1; @@ -8646,7 +8647,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en //val2 holds if it was casted on self, or is bonus received from others val3 = 5*val1; //Power increase if(sd && pc->checkskill(sd,BS_HILTBINDING)>0) - tick += tick / 10; + total_tick += total_tick / 10; break; case SC_ADRENALINE2: case SC_ADRENALINE: @@ -8654,13 +8655,13 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en FALLTHROUGH case SC_WEAPONPERFECT: if(sd && pc->checkskill(sd,BS_HILTBINDING)>0) - tick += tick / 10; + total_tick += total_tick / 10; break; case SC_LKCONCENTRATION: val2 = 5*val1; //Batk/Watk Increase val3 = 10*val1; //Hit Increase val4 = 5*val1; //Def reduction - sc_start(src, bl, SC_ENDURE, 100, 1, tick); //Endure effect + sc_start(src, bl, SC_ENDURE, 100, 1, total_tick); //Endure effect break; case SC_ANGELUS: val2 = 5*val1; //def increase @@ -8730,7 +8731,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val3 = 12*val1; //mdef2 reduction. break; case SC_SKA: - val2 = tick/1000; + val2 = total_tick/1000; val3 = rnd()%100; //Def changes randomly every second... tick_time = 1000; // [GodLesZ] tick time break; @@ -8743,7 +8744,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en // When renewing status' information // val3 Return map_index // val4 return coordinates - tick = val1>0?1000:250; + total_tick = val1>0?1000:250; if (sd) { if (sd->mapindex != val2) @@ -8778,11 +8779,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en break; case SC_SWOO: if(st->mode&MD_BOSS) - tick /= 5; //TODO: Reduce skill's duration. But for how long? + total_tick /= 5; //TODO: Reduce skill's duration. But for how long? break; case SC_SPIDERWEB: if( bl->type == BL_PC ) - tick /= 2; + total_tick /= 2; break; case SC_ARMOR: //NPC_DEFENDER: @@ -8848,7 +8849,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val2 = 10*val1; //% of life to be revived with break; case SC_ARMORPROPERTY: - clif->status_change(bl, (val1 > 0 ? SI_RESIST_PROPERTY_WATER : (val2 > 0 ? SI_RESIST_PROPERTY_GROUND : (val3 > 0 ? SI_RESIST_PROPERTY_FIRE : (val4 > 0 ? SI_RESIST_PROPERTY_WIND : SI_BLANK)))), 1, tick, 0, 0, 0); + clif->status_change(bl, (val1 > 0 ? SI_RESIST_PROPERTY_WATER : (val2 > 0 ? SI_RESIST_PROPERTY_GROUND : (val3 > 0 ? SI_RESIST_PROPERTY_FIRE : (val4 > 0 ? SI_RESIST_PROPERTY_WIND : SI_BLANK)))), 1, total_tick, 0, 0, 0); break; // case SC_ARMOR_RESIST: // Mod your resistance against elements: @@ -8890,11 +8891,11 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en **/ case SC_FEAR: val2 = 2; - val4 = tick / 1000; + val4 = total_tick / 1000; tick_time = 1000; // [GodLesZ] tick time break; case SC_BURNING: - val4 = tick / 3000; // Total Ticks to Burn!! + val4 = total_tick / 3000; // Total Ticks to Burn!! tick_time = 3000; // [GodLesZ] tick time break; /** @@ -8908,14 +8909,14 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val1 = sd->status.job_level * pc->checkskill(sd, RK_RUNEMASTERY) / 4; //DEF/MDEF Increase break; case SC_ABUNDANCE: - val4 = tick / 10000; + val4 = total_tick / 10000; tick_time = 10000; // [GodLesZ] tick time break; /** * Arch Bishop **/ case SC_RENOVATIO: - val4 = tick / 5000; + val4 = total_tick / 5000; tick_time = 5000; break; case SC_SECRAMENT: @@ -8926,28 +8927,28 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en break; case SC_WEAPONBLOCKING: val2 = 10 + 2 * val1; // Chance - val4 = tick / 5000; + val4 = total_tick / 5000; tick_time = 5000; // [GodLesZ] tick time break; case SC_TOXIN: - val4 = tick / 10000; + val4 = total_tick / 10000; tick_time = 10000; // [GodLesZ] tick time break; case SC_MAGICMUSHROOM: - val4 = tick / 4000; + val4 = total_tick / 4000; tick_time = 4000; // [GodLesZ] tick time break; case SC_PYREXIA: status->change_start(src, bl,SC_BLIND,10000,val1,0,0,0,30000,SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE); // Blind status that last for 30 seconds - val4 = tick / 3000; + val4 = total_tick / 3000; tick_time = 3000; // [GodLesZ] tick time break; case SC_LEECHESEND: - val4 = tick / 1000; + val4 = total_tick / 1000; tick_time = 1000; // [GodLesZ] tick time break; case SC_OBLIVIONCURSE: - val4 = tick / 3000; + val4 = total_tick / 3000; tick_time = 3000; // [GodLesZ] tick time break; case SC_CLOAKINGEXCEED: @@ -8986,7 +8987,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en case SC_SUMMON3: case SC_SUMMON4: case SC_SUMMON5: - val4 = tick / 1000; + val4 = total_tick / 1000; if( val4 < 1 ) val4 = 1; tick_time = 1000; // [GodLesZ] tick time @@ -9001,19 +9002,19 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en } break; case SC_STEALTHFIELD_MASTER: - val4 = tick / 1000; + val4 = total_tick / 1000; tick_time = 2000 + (1000 * val1); break; case SC_ELECTRICSHOCKER: case SC_COLD: case SC_MEIKYOUSISUI: - val4 = tick / 1000; + val4 = total_tick / 1000; if( val4 < 1 ) val4 = 1; tick_time = 1000; // [GodLesZ] tick time break; case SC_CAMOUFLAGE: - val4 = tick/1000; + val4 = total_tick/1000; tick_time = 1000; // [GodLesZ] tick time break; case SC_WUGDASH: @@ -9024,17 +9025,17 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val3 = (int)(currenttick&0x00000000ffffffffLL); val4 = (int)((currenttick&0xffffffff00000000LL)>>32); } - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; break; case SC__REPRODUCE: - val4 = tick / 1000; + val4 = total_tick / 1000; tick_time = 1000; break; case SC__SHADOWFORM: { struct map_session_data * s_sd = map->id2sd(val2); if( s_sd ) s_sd->shadowform_id = bl->id; - val4 = tick / 1000; + val4 = total_tick / 1000; tick_time = 1000; // [GodLesZ] tick time } break; @@ -9045,7 +9046,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en case SC__INVISIBILITY: val2 = 50 - 10 * val1; // ASPD val3 = 200 * val1; // CRITICAL - val4 = tick / 1000; + val4 = total_tick / 1000; tick_time = 1000; // [GodLesZ] tick time break; case SC__ENERVATION: @@ -9087,8 +9088,8 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en case SC__WEAKNESS: val2 = 10 * val1; // bypasses coating protection and MADO - sc_start(src, bl,SC_NOEQUIPWEAPON,100,val1,tick); - sc_start(src, bl,SC_NOEQUIPSHIELD,100,val1,tick); + sc_start(src, bl,SC_NOEQUIPWEAPON,100,val1,total_tick); + sc_start(src, bl,SC_NOEQUIPSHIELD,100,val1,total_tick); break; case SC_GN_CARTBOOST: if( val1 < 3 ) @@ -9108,7 +9109,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en break; case SC_STRIKING: val1 = 6 - val1;//spcost = 6 - level (lvl1:5 ... lvl 5: 1) - val4 = tick / 1000; + val4 = total_tick / 1000; tick_time = 1000; // [GodLesZ] tick time break; case SC_BLOOD_SUCKER: @@ -9117,7 +9118,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val3 = 1; if(src2) val3 = 200 + 100 * val1 + status_get_int(src2); - val4 = tick / 1000; + val4 = total_tick / 1000; tick_time = 1000; // [GodLesZ] tick time } break; @@ -9138,22 +9139,22 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val2 = 5 + 5 * val1; break; case SC_SIREN: - val4 = tick / 2000; + val4 = total_tick / 2000; tick_time = 2000; // [GodLesZ] tick time break; case SC_DEEP_SLEEP: - val4 = tick / 2000; + val4 = total_tick / 2000; tick_time = 2000; // [GodLesZ] tick time break; case SC_SIRCLEOFNATURE: val2 = 40 * val1;//HP recovery val3 = 4 * val1;//SP drain - val4 = tick / 1000; + val4 = total_tick / 1000; tick_time = 1000; // [GodLesZ] tick time break; case SC_SONG_OF_MANA: val3 = 10 + 5 * val2; - val4 = tick/5000; + val4 = total_tick/5000; tick_time = 5000; // [GodLesZ] tick time break; case SC_SATURDAY_NIGHT_FEVER: @@ -9161,7 +9162,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en if ( val2 < 1000 ) val2 = 1000;//Added to prevent val3 from dividing by 0 when using level 6 or higher through commands. [Rytech] val3 = tick/val2;*/ - val3 = tick / 3000; + val3 = total_tick / 3000; tick_time = 3000;// [GodLesZ] tick time break; case SC_GLOOMYDAY: @@ -9197,7 +9198,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en break; case SC_MELODYOFSINK: val3 = val1 * (2 + val2);//INT Reduction. Formula Includes Caster And 2nd Performer. - val4 = tick/1000; + val4 = total_tick/1000; tick_time = 1000; break; case SC_BEYOND_OF_WARCRY: @@ -9215,13 +9216,13 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en case SC_LG_REFLECTDAMAGE: val2 = 15 + 5 * val1; val3 = 25 + 5 * val1; //Number of Reflects - val4 = tick/1000; + val4 = total_tick/1000; tick_time = 1000; // [GodLesZ] tick time break; case SC_FORCEOFVANGUARD: val2 = 8 + 12 * val1; // Chance val3 = 5 + 2 * val1; // Max rage counters - tick = INFINITE_DURATION; //endless duration in the client + total_tick = INFINITE_DURATION; //endless duration in the client break; case SC_EXEEDBREAK: if( sd ){ @@ -9244,7 +9245,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en tick_time = 5000; // [GodLesZ] tick time break; case SC_MAGNETICFIELD: - val3 = tick / 1000; + val3 = total_tick / 1000; tick_time = 1000; // [GodLesZ] tick time break; case SC_INSPIRATION: @@ -9252,7 +9253,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val2 = 40 * val1 + 3 * sd->status.job_level;// ATK bonus val3 = sd->status.base_level / 10 + sd->status.job_level / 5;// All stat bonus } - val4 = tick / 5000; + val4 = total_tick / 5000; tick_time = 5000; // [GodLesZ] tick time status->change_clear_buffs(bl,3); //Remove buffs/debuffs break; @@ -9263,7 +9264,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1; break; case SC_RAISINGDRAGON: - val3 = tick / 5000; + val3 = total_tick / 5000; tick_time = 5000; // [GodLesZ] tick time break; case SC_GENTLETOUCH_CHANGE: @@ -9373,7 +9374,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en case SC_STONE_SHIELD: val2 += 5; val3 += 1000; - val4 = tick; + val4 = total_tick; tick_time = val3; break; case SC_WATER_BARRIER: @@ -9396,18 +9397,18 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en break; case SC_STOMACHACHE: val3 = 8; // SP consume. - val4 = tick / 10000; + val4 = total_tick / 10000; tick_time = 10000; // [GodLesZ] tick time break; case SC_STEAMPACK: // [Frost] val3 = 100; // HP Consume. - val4 = tick / 10000; + val4 = total_tick / 10000; tick_time = 10000; - sc_start(src, bl, SC_ENDURE, 100, 10, tick); // Endure effect + sc_start(src, bl, SC_ENDURE, 100, 10, total_tick); // Endure effect break; case SC_MAGIC_CANDY: // [Frost] val3 = 90; // SP Consume. - val4 = tick / 10000; + val4 = total_tick / 10000; tick_time = 10000; break; case SC_PROMOTE_HEALTH_RESERCH: @@ -9446,7 +9447,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val3 = val1 * 2; FALLTHROUGH case SC_IZAYOI: - val2 = tick/1000; + val2 = total_tick/1000; tick_time = 1000; break; case SC_ZANGETSU: @@ -9486,12 +9487,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en case SC_ANGRIFFS_MODUS: val2 = 50 + 20 * val1; //atk bonus val3 = 40 + 20 * val1; // Flee reduction. - val4 = tick/1000; // hp/sp reduction timer + val4 = total_tick/1000; // hp/sp reduction timer tick_time = 1000; break; case SC_NEUTRALBARRIER: - tick_time = tick; - tick = INFINITE_DURATION; + tick_time = total_tick; + total_tick = INFINITE_DURATION; break; case SC_GOLDENE_FERSE: val2 = 10 + 10*val1; //max hp bonus @@ -9520,10 +9521,10 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val2 = 2*val1; //aspd reduction % val3 = 2*val1; //dmg reduction % if(sc->data[SC_NEEDLE_OF_PARALYZE]) - sc_start(src, bl, SC_ENDURE, 100, val1, tick); //start endure for same duration + sc_start(src, bl, SC_ENDURE, 100, val1, total_tick); //start endure for same duration break; case SC_STYLE_CHANGE: //[Lighta] need real info - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING; else val2 = MH_MD_FIGHTING; break; @@ -9531,12 +9532,12 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en status_percent_heal(bl,100,0); val2 = 7 - val1; tick_time = 1000; - val4 = tick / tick_time; + val4 = total_tick / tick_time; break; case SC_KINGS_GRACE: val2 = 3 + val1; tick_time = 1000; - val4 = tick / tick_time; + val4 = total_tick / tick_time; break; case SC_TELEKINESIS_INTENSE: val2 = 10 * val1; @@ -9549,7 +9550,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val2 = 5 * val1; val3 = (20 * val1) + 80; tick_time = 1000; - val4 = tick / tick_time; + val4 = total_tick / tick_time; break; case SC_DARKCROW: val2 = 30 * val1; @@ -9560,7 +9561,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en break; case SC_SPRITEMABLE: case SC_ALL_RIDING: - tick = INFINITE_DURATION; + total_tick = INFINITE_DURATION; break; case SC_FLASHCOMBO: /** @@ -9573,7 +9574,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en * Summoner */ case SC_FRESHSHRIMP: - val4 = tick / (10000 - ((val1 - 1) * 1000)); + val4 = total_tick / (10000 - ((val1 - 1) * 1000)); tick_time = 10000 - ((val1 - 1) * 1000); if (val4 <= 0) // Prevents a negeative value from happening val4 = 0; @@ -9589,7 +9590,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en break; case SC_BITESCAR: val2 = 2 * val1; // MHP% damage - val4 = tick / 1000; + val4 = total_tick / 1000; tick_time = 1000; break; case SC_SHRIMP: @@ -9600,7 +9601,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en val3 = 25 * val1; // Move speed reduction break; default: - if (status->change_start_unknown_sc(src, bl, type, calc_flag, rate, val1, val2, val3, val4, tick, flag)) { + if (status->change_start_unknown_sc(src, bl, type, calc_flag, rate, val1, val2, val3, val4, total_tick, flag)) { return 0; } } @@ -9670,13 +9671,15 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en } #endif - if(!(flag&SCFLAG_NOICON) && !(flag&SCFLAG_LOADED && status->dbs->DisplayType[type])) - clif->status_change(bl,status->dbs->IconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0); + if (!(flag & SCFLAG_LOADED)) + tick = total_tick; // When starting a new SC (not loading), its remaining duration is the same as the total + if(!(flag & SCFLAG_NOICON) && !(flag & SCFLAG_LOADED && status->dbs->DisplayType[type])) + clif->status_change_sub(bl, status->dbs->IconChangeTable[type], 1, tick, total_tick, (val_flag & 1) ? val1 : 1, (val_flag & 2) ? val2 : 0, (val_flag & 4) ? val3 : 0); /** * used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first. **/ - if( tick_time ) + if(tick_time) tick = tick_time; //Don't trust the previous sce assignment, in case the SC ended somewhere between there and here. @@ -9692,6 +9695,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en sce->val2 = val2; sce->val3 = val3; sce->val4 = val4; + sce->total_tick = total_tick; if (tick >= 0) { sce->timer = timer->add(timer->gettick() + tick, status->change_timer, bl->id, type); @@ -9800,7 +9804,7 @@ static int status_change_start(struct block_list *src, struct block_list *bl, en return 1; } -static bool status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int tick, int flag) +static bool status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag) { Assert_retr(false, type >= SC_NONE && type < SC_MAX); if (calc_flag == SCB_NONE && status->dbs->SkillChangeTable[type] == 0 && status->dbs->IconChangeTable[type] == 0) { @@ -9811,6 +9815,28 @@ static bool status_change_start_unknown_sc(struct block_list *src, struct block_ return false; } +/** + * Starts a status change in its full duration. + * + * @param src Status change source bl. + * @param bl Status change target bl. + * @param type Status change type. + * @param rate Base success rate. 1 means 0.01%, 10000 means 100%. + * @param val1 Additional value (meaning depends on type). + * @param val2 Additional value (meaning depends on type). + * @param val3 Additional value (meaning depends on type). + * @param val4 Additional value (meaning depends on type). + * @param tick Base duration (milliseconds). + * @param flag Special flags (@see enum scstart_flag). + * + * @retval 0 if no status change happened. + * @retval 1 if the status change was successfully applied. + */ +static int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag) +{ + return status->change_start_sub(src, bl, type, rate, val1, val2, val3, val4, 0, tick, flag); +} + static void status_change_start_display(struct map_session_data *sd, enum sc_type type, int val1, int val2, int val3, int val4) { Assert_retv(type >= SC_NONE && type < SC_MAX); @@ -10189,7 +10215,7 @@ static void status_change_start_stop_action(struct block_list *bl, enum sc_type switch (type) { case SC_VACUUM_EXTREME: if (!map_flag_gvg(bl->m)) - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); break; case SC_FREEZE: case SC_STUN: @@ -10742,9 +10768,7 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid, struct status_data *st; struct view_data *vd; int opt_flag=0, calc_flag; -#ifdef ANTI_MAYAP_CHEAT bool invisible = false; -#endif nullpo_ret(bl); @@ -10799,10 +10823,8 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid, status->display_remove(sd,type); } -#ifdef ANTI_MAYAP_CHEAT - if (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE)) + if ((sc->option & (OPTION_HIDE | OPTION_CLOAK | OPTION_INVISIBLE)) != 0) invisible = true; -#endif vd = status->get_viewdata(bl); calc_flag = status->dbs->ChangeFlagTable[type]; @@ -11429,6 +11451,12 @@ static int status_change_end_(struct block_list *bl, enum sc_type type, int tid, } #endif + // update HP bar when becoming visible again + if (invisible && (sc->option & (OPTION_HIDE | OPTION_CLOAK | OPTION_INVISIBLE)) == 0) { + if (sd != NULL && battle_config.party_hp_mode == 0 && sd->status.party_id != 0) + clif->party_hp(sd); + } + if (calc_flag&SCB_DYE) { //Restore DYE color if (vd && !vd->cloth_color && sce->val4) clif->changelook(bl,LOOK_CLOTHES_COLOR,sce->val4); @@ -13339,10 +13367,12 @@ static void status_read_job_db(void) int i = 0; struct config_t job_db_conf; struct config_setting_t *jdb = NULL; + char config_filename[256]; + #ifdef RENEWAL_ASPD - const char *config_filename = "db/re/job_db.conf"; + libconfig->format_db_path(DBPATH_RE"job_db.conf", config_filename, sizeof(config_filename)); #else - const char *config_filename = "db/pre-re/job_db.conf"; + libconfig->format_db_path(DBPATH_PRE"job_db.conf", config_filename, sizeof(config_filename)); #endif if (!libconfig->load_file(&job_db_conf, config_filename)) @@ -13633,6 +13663,7 @@ void status_defaults(void) status->get_sc_def = status_get_sc_def; status->change_start = status_change_start; + status->change_start_sub = status_change_start_sub; status->change_end_ = status_change_end_; status->kaahi_heal_timer = kaahi_heal_timer; status->change_timer = status_change_timer; diff --git a/src/map/status.h b/src/map/status.h index 536003d04..e2280e409 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -2138,6 +2138,7 @@ struct sc_display_entry { struct status_change_entry { int timer; + int total_tick; int val1,val2,val3,val4; bool infinite_duration; }; @@ -2306,6 +2307,7 @@ struct status_interface { int (*isimmune) (struct block_list *bl); int (*get_sc_def) (struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag); int (*change_start) (struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag); + int (*change_start_sub) (struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int total_tick, int flag); int (*change_end_) (struct block_list* bl, enum sc_type type, int tid, const char* file, int line); bool (*is_immune_to_status) (struct status_change* sc, enum sc_type type); bool (*is_boss_resist_sc) (enum sc_type type); @@ -2314,7 +2316,7 @@ struct status_interface { int (*change_start_set_option) (struct block_list *bl, struct status_change* sc, enum sc_type type, int val1, int val2, int val3, int val4); int (*get_val_flag) (enum sc_type type); void (*change_start_display) (struct map_session_data *sd, enum sc_type type, int val1, int val2, int val3, int val4); - bool (*change_start_unknown_sc) (struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int tick, int flag); + bool (*change_start_unknown_sc) (struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int total_tick, int flag); int (*kaahi_heal_timer) (int tid, int64 tick, int id, intptr_t data); int (*change_timer) (int tid, int64 tick, int id, intptr_t data); int (*change_timer_sub) (struct block_list* bl, va_list ap); diff --git a/src/map/stylist.c b/src/map/stylist.c index 7e7c13bf7..438302214 100644 --- a/src/map/stylist.c +++ b/src/map/stylist.c @@ -40,7 +40,8 @@ static bool stylist_read_db_libconfig(void) { struct config_t stylist_conf; struct config_setting_t *stylist_db = NULL, *it = NULL; - const char *config_filename = "db/stylist_db.conf"; // FIXME hardcoded name + char config_filename[256]; + libconfig->format_db_path("stylist_db.conf", config_filename, sizeof(config_filename)); int i = 0; if (!libconfig->load_file(&stylist_conf, config_filename)) diff --git a/src/map/unit.c b/src/map/unit.c index 45cb7dffd..1e9433eaf 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1328,6 +1328,12 @@ static int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill if (src->type==BL_HOM) switch(skill_id) { //Homun-auto-target skills. + case HVAN_CHAOTIC: + target_id = ud->target; // Choose attack target for now + target = map->id2bl(target_id); + if (target != NULL) + break; + FALLTHROUGH // Attacking nothing, choose master as default target instead case HLIF_HEAL: case HLIF_AVOID: case HAMI_DEFENCE: @@ -1410,13 +1416,6 @@ static int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill } } - if (src->type == BL_HOM) { - // In case of homunuculus, set the sd to the homunculus' master, as needed below - struct block_list *master = battle->get_master(src); - if (master) - sd = map->id2sd(master->id); - } - if (sd) { /* temporarily disabled, awaiting for kenpachi to detail this so we can make it work properly */ #if 0 |