summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md43
-rw-r--r--conf/common/map-index.conf34
-rw-r--r--conf/map/battle/monster.conf5
-rw-r--r--src/char/char.c7
-rw-r--r--src/char/char.h2
-rw-r--r--src/char/geoip.c5
-rw-r--r--src/char/int_guild.c2
-rw-r--r--src/char/int_party.c7
-rw-r--r--src/common/conf.c30
-rw-r--r--src/common/conf.h4
-rw-r--r--src/common/console.c17
-rw-r--r--src/common/mapindex.c57
-rw-r--r--src/common/mapindex.h4
-rw-r--r--src/config/const.h7
-rw-r--r--src/map/achievement.c6
-rw-r--r--src/map/battle.c3
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/clif.c9
-rw-r--r--src/map/guild.c11
-rw-r--r--src/map/itemdb.c24
-rw-r--r--src/map/map.c14
-rw-r--r--src/map/mob.c119
-rw-r--r--src/map/mob.h1
-rw-r--r--src/map/party.c1
-rw-r--r--src/map/pc.c9
-rw-r--r--src/map/script.c3
-rw-r--r--src/map/skill.c20
-rw-r--r--src/map/status.c6
-rw-r--r--src/map/stylist.c3
-rw-r--r--src/map/unit.c13
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc10
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc16
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.Hooks.inc106
-rw-r--r--src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc8
-rw-r--r--src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc2
-rw-r--r--src/plugins/HPMHooking/HPMHooking_login.Hooks.inc52
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc20
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc5
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc133
40 files changed, 713 insertions, 110 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 798269c0f..7d46dbcbc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,48 @@ and this project does not adhere to [Semantic Versioning](http://semver.org/spec
If you are reading this in a text editor, simply ignore this section
-->
+### [v2019.10.20] `October 20 2019`
+
+### Added
+
+- Added/updated packets, encryption keys and message tables for clients up to 2019-10-02. (#2537)
+- Added a new config file `conf/common/map-index.conf` to customize the location of the `map_index.txt` file. (part of #2547)
+
+### Changed
+
+- Moved several hardcoded messages to `messages.conf`. (#2152, issue #1282)
+- Updated the `@dropall` command to correctly show the amount of dropped (and skipped) items. (#2545)
+- Split the HULD generated translations into smaller (and easier to manage) files. A translation will now consist of a folder, with one .po (.pot) file per script. Third party translations may need to be updated to match this change. (#2492)
+- Changed the slave monsters' behavior to react to chase the same target as their master, to match the official behavior. A configuration setting `slave_chase_masters_chasetarget` has been provided in `battle/monster.conf` for those that wish to keep using the old custom behavior. (#2561)
+- De-hardcoded the path to the `db` folder, now using `map_configuration.database.db_path` and `char_configuration.database.db_path` in the map and char server respectively. This allows the user to customize the location of the db folder. (#2547)
+
+### Fixed
+
+- Fixed an exploitable issue in the Izlude Arena party mode script. (#2538)
+- Fixed a buffer overflow in the `buildin_npcshopdelitem()`. (#2540)
+- Fixed a potentially exploitable issue in the Ore Downgrade script. (#1935, issue #1934)
+- Corrected the item bonus for `Drooping_Kitty_C`. (#2543)
+- Corrected the display of the Sense skill to cap to 0 the negative resistance values instead of underflowing them. (#2544)
+- Fixed compilation warning with gcc-9. (part of #2537)
+- Fixed the HP bar of party members not showing when they unhide. (#2549)
+- Fixed the status change timers not showing the correct values in the client, after relogging. This requires a database migration. (#2551, issue #2018)
+- Corrected Magnum Break's 2 second delay to be an after-cast delay (reducible by Bragi's Poem) instead of a cooldown. (#2553)
+- Fixed an issue that prevented players from closing their own vending shop. (#2555, issue #2554)
+- Fixed the Homunculus skill requirements being applied to the master as well. (#2556)
+- Fixed the Homunculus skill failure message not displaying any required items (part of #2556)
+- Fixed the Chaotic Blessings skill from Vanilmirth never picking the enemy as its random target to heal. (part of #2556)
+- Fixed an issue that caused the saved character data to retain the old party ID after leaving or getting kicked. (#2562)
+- Fixed some possible crashes or memory corruption caused by dangling pointers to guilds in the character data. (part of #2562, related to issue #1266)
+- Fixed the party name not getting removed from all affected characters (clientside) when a party is disbanded. (part of #2562)
+- Fixed a crash in the console command parser when a line consisting only of spaces is executed. (#2563)
+- Fixed the argument string passed to console commands when the input starts with multiple adjacent spaces. (part of #2563)
+- Fixed the mapindex value not getting updated in the `gm:info` console command. (part of #2563)
+- Fixed an issue that caused aggressive monsters with ranged attack to be unable to attack from above a cliff. (#2550)
+
+### Removed
+
+- Removed the legacy, unused, `castle_defense_rate` option from `battle/guild.conf`. (#2552)
+
### [v2019.09.22] `September 22 2019`
### Added
@@ -931,6 +973,7 @@ If you are reading this in a text editor, simply ignore this section
- New versioning scheme and project changelogs/release notes (#1853)
[Unreleased]: https://github.com/HerculesWS/Hercules/compare/stable...master
+[v2019.10.20]: https://github.com/HerculesWS/Hercules/compare/v2019.09.22...v2019.10.20
[v2019.09.22]: https://github.com/HerculesWS/Hercules/compare/v2019.08.25...v2019.09.22
[v2019.08.25]: https://github.com/HerculesWS/Hercules/compare/v2019.07.28...v2019.08.25
[v2019.07.28]: https://github.com/HerculesWS/Hercules/compare/v2019.06.30...v2019.07.28
diff --git a/conf/common/map-index.conf b/conf/common/map-index.conf
new file mode 100644
index 000000000..b3a1b4e8f
--- /dev/null
+++ b/conf/common/map-index.conf
@@ -0,0 +1,34 @@
+//================= Hercules Configuration ================================
+//= _ _ _
+//= | | | | | |
+//= | |_| | ___ _ __ ___ _ _| | ___ ___
+//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __|
+//= | | | | __/ | | (__| |_| | | __/\__ \
+//= \_| |_/\___|_| \___|\__,_|_|\___||___/
+//================= License ===============================================
+//= This file is part of Hercules.
+//= http://herc.ws - http://github.com/HerculesWS/Hercules
+//=
+//= Copyright (C) 2014-2019 Hercules Dev Team
+//=
+//= Hercules is free software: you can redistribute it and/or modify
+//= it under the terms of the GNU General Public License as published by
+//= the Free Software Foundation, either version 3 of the License, or
+//= (at your option) any later version.
+//=
+//= This program is distributed in the hope that it will be useful,
+//= but WITHOUT ANY WARRANTY; without even the implied warranty of
+//= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//= GNU General Public License for more details.
+//=
+//= You should have received a copy of the GNU General Public License
+//= along with this program. If not, see <http://www.gnu.org/licenses/>.
+//=========================================================================
+//= Map Index configuration file.
+//=========================================================================
+
+mapindex_configuration: {
+ // Full path to the map_index.txt file
+ // Default: db/map_index.txt
+ file_path: "db/map_index.txt"
+}
diff --git a/conf/map/battle/monster.conf b/conf/map/battle/monster.conf
index 8f969dc48..389bdc5c7 100644
--- a/conf/map/battle/monster.conf
+++ b/conf/map/battle/monster.conf
@@ -269,3 +269,8 @@ boss_icewall_walk_block: 1
// only have a range of 9. If you put a number higher than 0, their range will
// be increased by that number.
monster_eye_range_bonus: 0
+
+// Should slaves chase after what their master is chasing?
+// false: Don't chase after what master is chasing. (old behavior)
+// true: Chase after what master is chasing. (official, default)
+slave_chase_masters_chasetarget: true
diff --git a/src/char/char.c b/src/char/char.c
index 37db77300..66bfdd4ee 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -120,8 +120,6 @@ char char_achievement_db[256] = "char_achievements";
static struct char_interface char_s;
struct char_interface *chr;
-char db_path[1024] = "db";
-
static char wisp_server_name[NAME_LENGTH] = "Server";
static char login_ip_str[128];
static uint32 login_ip = 0;
@@ -5792,7 +5790,8 @@ static bool char_config_read_database(const char *filename, const struct config_
if (autosave_interval <= 0)
autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
}
- libconfig->setting_lookup_mutable_string(setting, "db_path", db_path, sizeof(db_path));
+ libconfig->setting_lookup_mutable_string(setting, "db_path", chr->db_path, sizeof(chr->db_path));
+ libconfig->set_db_path(chr->db_path);
libconfig->setting_lookup_bool_real(setting, "log_char", &chr->enable_logs);
return true;
}
@@ -6454,6 +6453,8 @@ void char_defaults(void)
chr = &char_s;
memset(chr->server, 0, sizeof(chr->server));
+ sprintf(chr->db_path, "db");
+ libconfig->set_db_path(chr->db_path);
chr->login_fd = 0;
chr->char_fd = -1;
diff --git a/src/char/char.h b/src/char/char.h
index 5de3e2a80..3b8bcff2e 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -124,6 +124,8 @@ struct char_interface {
bool show_save_log; ///< Show loading/saving messages.
bool enable_logs; ///< Whether to log char server operations.
+ char db_path[256]; //< Database directory (db)
+
int (*waiting_disconnect) (int tid, int64 tick, int id, intptr_t data);
int (*delete_char_sql) (int char_id);
struct DBData (*create_online_char_data) (union DBKey key, va_list args);
diff --git a/src/char/geoip.c b/src/char/geoip.c
index 2870e5f0c..67c057aff 100644
--- a/src/char/geoip.c
+++ b/src/char/geoip.c
@@ -23,6 +23,7 @@
#include "geoip.h"
#include "common/cbasetypes.h"
+#include "common/conf.h"
#include "common/memmgr.h"
#include "common/showmsg.h"
@@ -141,7 +142,9 @@ static void geoip_init(void)
geoip->data->active = true;
- db = fopen("./db/GeoIP.dat","rb");
+ char file_path[256];
+ libconfig->format_db_path("GeoIP.dat", file_path, sizeof(file_path));
+ db = fopen(file_path, "rb");
if (db == NULL) {
ShowError("geoip_readdb: Error reading GeoIP.dat!\n");
geoip->final(false);
diff --git a/src/char/int_guild.c b/src/char/int_guild.c
index 87cb3bee0..3e9d50f8d 100644
--- a/src/char/int_guild.c
+++ b/src/char/int_guild.c
@@ -747,7 +747,7 @@ static int inter_guild_sql_init(void)
inter_guild->castle_db = idb_alloc(DB_OPT_RELEASE_DATA);
//Read exp file
- sv->readdb("db", DBPATH"exp_guild.txt", ',', 1, 1, MAX_GUILDLEVEL, inter_guild->exp_parse_row);
+ sv->readdb(chr->db_path, DBPATH"exp_guild.txt", ',', 1, 1, MAX_GUILDLEVEL, inter_guild->exp_parse_row);
timer->add_func_list(inter_guild->save_timer, "inter_guild->save_timer");
timer->add(timer->gettick() + 10000, inter_guild->save_timer, 0, 0);
diff --git a/src/char/int_party.c b/src/char/int_party.c
index c27d708f2..bf680c816 100644
--- a/src/char/int_party.c
+++ b/src/char/int_party.c
@@ -118,7 +118,6 @@ static void inter_party_calc_state(struct party_data *p)
p->party.exp = 0; //Set off even share.
mapif->party_optionchanged(0, &p->party, 0, 0);
}
- return;
}
// Save party to mysql
@@ -472,8 +471,11 @@ static bool inter_party_leave(int party_id, int account_id, int char_id)
mapif->party_withdraw(party_id, account_id, char_id);
j = p->party.member[i].lv;
- if (p->party.member[i].online > 0)
+ if (p->party.member[i].online > 0) {
+ p->party.member[i].online = 0;
p->party.count--;
+ }
+ inter_party->tosql(&p->party, PS_DELMEMBER, i);
memset(&p->party.member[i], 0, sizeof(struct party_member));
p->size--;
if (j == p->min_lv || j == p->max_lv || p->family) {
@@ -482,7 +484,6 @@ static bool inter_party_leave(int party_id, int account_id, int char_id)
}
if (inter_party->check_empty(p) == 0) {
- inter_party->tosql(&p->party, PS_DELMEMBER, i);
mapif->party_info(-1, &p->party, 0);
}
return true;
diff --git a/src/common/conf.c b/src/common/conf.c
index 0ad350057..d81a6636b 100644
--- a/src/common/conf.c
+++ b/src/common/conf.c
@@ -22,6 +22,7 @@
#include "conf.h"
+#include "common/nullpo.h" // nullpo_retv
#include "common/showmsg.h" // ShowError
#include "common/strlib.h" // safestrncpy
#include "common/utils.h" // exists
@@ -33,6 +34,31 @@ static struct libconfig_interface libconfig_s;
struct libconfig_interface *libconfig;
/**
+ * Sets the server's db_path to be used by config_format_db_path
+ * @param db_path path to the folder where the db files are at
+ */
+static void config_set_db_path(const char *db_path)
+{
+ nullpo_retv(db_path);
+ safestrncpy(libconfig->db_path, db_path, sizeof(libconfig->db_path));
+}
+
+/**
+ * Writes into path_buf the fullpath to the db file in filename.
+ * Basically this prepends map->db_path to filename.
+ * @param filename File name to format (e.g. re/item_db.conf)
+ * @param path_buf Where to save the path to
+ * @param buffer_len Maximun length of path_buf
+ */
+static void config_format_db_path(const char *filename, char *path_buf, int buffer_len)
+{
+ nullpo_retv(filename);
+ nullpo_retv(path_buf);
+
+ safesnprintf(path_buf, buffer_len, "%s/%s", libconfig->db_path, filename);
+}
+
+/**
* Initializes 'config' and loads a configuration file.
*
* Shows error and destroys 'config' in case of failure.
@@ -450,6 +476,10 @@ static int config_lookup_int64_real(const struct config_t *config, const char *f
void libconfig_defaults(void) {
libconfig = &libconfig_s;
+ snprintf(libconfig->db_path, sizeof(libconfig->db_path), "db");
+ libconfig->set_db_path = config_set_db_path;
+ libconfig->format_db_path = config_format_db_path;
+ /* */
libconfig->read = config_read;
libconfig->write = config_write;
/* */
diff --git a/src/common/conf.h b/src/common/conf.h
index 66960c0ec..ccab6dc17 100644
--- a/src/common/conf.h
+++ b/src/common/conf.h
@@ -29,6 +29,10 @@
* The libconfig interface -- specially for plugins, but we enforce it throughout the core to be consistent
**/
struct libconfig_interface {
+ char db_path[256];
+ void (*set_db_path) (const char *db_path);
+ void (*format_db_path) (const char *filename, char *path_buf, int buffer_len);
+ /* */
int (*read) (struct config_t *config, FILE *stream);
void (*write) (const struct config_t *config, FILE *stream);
/* */
diff --git a/src/common/console.c b/src/common/console.c
index a990d86b3..0075ac2a1 100644
--- a/src/common/console.c
+++ b/src/common/console.c
@@ -322,6 +322,7 @@ static void console_parse_create(char *name, CParseFunc func)
nullpo_retv(name);
safestrncpy(sublist, name, CP_CMD_LENGTH * 5);
tok = strtok(sublist,":");
+ nullpo_retv(tok);
ARR_FIND(0, VECTOR_LENGTH(console->input->command_list), i, strcmpi(tok, VECTOR_INDEX(console->input->command_list, i)->cmd) == 0);
@@ -404,6 +405,10 @@ static void console_parse_sub(char *line)
nullpo_retv(line);
memcpy(bline, line, 200);
tok = strtok(line, " ");
+ if (tok == NULL) {
+ // Ignore empty commands
+ return;
+ }
ARR_FIND(0, VECTOR_LENGTH(console->input->command_list), i, strcmpi(tok, VECTOR_INDEX(console->input->command_list, i)->cmd) == 0);
if (i == VECTOR_LENGTH(console->input->command_list)) {
@@ -417,6 +422,12 @@ static void console_parse_sub(char *line)
if (cmd->type == CPET_FUNCTION) {
tok = strtok(NULL, "");
+ if (tok != NULL) {
+ while (tok[0] == ' ')
+ tok++;
+ if (tok[0] == '\0')
+ tok = NULL;
+ }
cmd->u.func(tok);
return;
}
@@ -444,6 +455,12 @@ static void console_parse_sub(char *line)
entry = VECTOR_INDEX(cmd->u.children, i);
if (entry->type == CPET_FUNCTION) {
tok = strtok(NULL, "");
+ if (tok != NULL) {
+ while (tok[0] == ' ')
+ tok++;
+ if (tok[0] == '\0')
+ tok = NULL;
+ }
entry->u.func(tok);
return;
}
diff --git a/src/common/mapindex.c b/src/common/mapindex.c
index d5cda5c22..f6097bb06 100644
--- a/src/common/mapindex.c
+++ b/src/common/mapindex.c
@@ -23,6 +23,7 @@
#include "mapindex.h"
#include "common/cbasetypes.h"
+#include "common/conf.h"
#include "common/db.h"
#include "common/mmo.h"
#include "common/nullpo.h"
@@ -159,8 +160,61 @@ static const char *mapindex_id2name_sub(uint16 id, const char *file, int line, c
return mapindex->list[id].name;
}
+/**
+ * Reads the db_path config of mapindex configuration file
+ * @param filename File being read (used when displaying errors)
+ * @param config Config structure being read
+ * @returns true if it read the all the configs, false otherwise
+ */
+static bool mapindex_config_read_dbpath(const char *filename, const struct config_t *config)
+{
+ nullpo_retr(false, config);
+
+ const struct config_setting_t *setting = NULL;
+
+ if ((setting = libconfig->lookup(config, "mapindex_configuration")) == NULL) {
+ ShowError("mapindex_config_read: mapindex_configuration was not found in %s!\n", filename);
+ return false;
+ }
+
+ // mapindex_configuration/file_path
+ if (libconfig->setting_lookup_mutable_string(setting, "file_path", mapindex->config_file, sizeof(mapindex->config_file)) == CONFIG_TRUE) {
+ ShowInfo("map_index file %s\n", mapindex->config_file);
+ } else {
+ ShowInfo("Failed to load map_index path, defaulting to db/map_index.txt\n");
+ safestrncpy(mapindex->config_file, "db/map_index.txt", sizeof(mapindex->config_file));
+ }
+
+ return true;
+}
+
+/**
+ * Reads conf/common/map-index.conf config file
+ * @returns true if it successfully read the file and configs, false otherwise
+ */
+static bool mapindex_config_read(void)
+{
+ struct config_t config;
+ const char *filename = "conf/common/map-index.conf";
+
+ if (!libconfig->load_file(&config, filename))
+ return false; // Error message is already shown by libconfig->load_file
+
+ if (!mapindex_config_read_dbpath(filename, &config)) {
+ libconfig->destroy(&config);
+ return false;
+ }
+
+ ShowInfo("Done reading %s.\n", filename);
+ libconfig->destroy(&config);
+ return true;
+}
+
static int mapindex_init(void)
{
+ if (!mapindex_config_read())
+ ShowError("Failed to load map_index configuration. Continuing with default values...\n");
+
FILE *fp;
char line[1024];
int last_index = -1;
@@ -234,6 +288,9 @@ void mapindex_defaults(void)
memset (&mapindex->list, 0, sizeof (mapindex->list));
/* */
+ mapindex->config_read = mapindex_config_read;
+ mapindex->config_read_dbpath = mapindex_config_read_dbpath;
+ /* */
mapindex->init = mapindex_init;
mapindex->final = mapindex_final;
/* */
diff --git a/src/common/mapindex.h b/src/common/mapindex.h
index 27cbc5e37..b7e02447d 100644
--- a/src/common/mapindex.h
+++ b/src/common/mapindex.h
@@ -21,6 +21,7 @@
#ifndef COMMON_MAPINDEX_H
#define COMMON_MAPINDEX_H
+#include "common/conf.h"
#include "common/hercules.h"
#include "common/mmo.h"
@@ -98,6 +99,9 @@ struct mapindex_interface {
char name[MAP_NAME_LENGTH];
} list[MAX_MAPINDEX];
/* */
+ bool (*config_read_dbpath) (const char *filename, const struct config_t *config);
+ bool (*config_read) (void);
+ /* */
int (*init) (void);
void (*final) (void);
/* */
diff --git a/src/config/const.h b/src/config/const.h
index 4767b5721..df8c07b67 100644
--- a/src/config/const.h
+++ b/src/config/const.h
@@ -49,10 +49,13 @@
/**
* Path within the /db folder to (non-)renewal specific db files
**/
+#define DBPATH_RE "re/"
+#define DBPATH_PRE "pre-re/"
+
#ifdef RENEWAL
- #define DBPATH "re/"
+ #define DBPATH DBPATH_RE
#else
- #define DBPATH "pre-re/"
+ #define DBPATH DBPATH_PRE
#endif
/**
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/battle.c b/src/map/battle.c
index 726547c66..7fb5355e6 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -4338,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;
@@ -7315,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 e9bc6b258..dd6265b1e 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -404,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/clif.c b/src/map/clif.c
index 42f4f49d9..5c86edcaa 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -19830,7 +19830,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);
@@ -21101,7 +21102,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++ ) {
@@ -22585,7 +22587,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))
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/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 f3fc9d46b..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");
diff --git a/src/map/mob.c b/src/map/mob.c
index 215f82f5f..ca1ce3585 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -1173,13 +1173,15 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl, va_list ap)
battle->check_range(&md->bl,bl,md->db->range2)
) { //Pick closest target?
#ifdef ACTIVEPATHSEARCH
- struct walkpath_data wpd;
- if (!path->search(&wpd, &md->bl, md->bl.m, md->bl.x, md->bl.y, bl->x, bl->y, 0, CELL_CHKNOPASS)) // Count walk path cells
- return 0;
- //Standing monsters use range2, walking monsters use range3
- if ((md->ud.walktimer == INVALID_TIMER && wpd.path_len > md->db->range2)
- || (md->ud.walktimer != INVALID_TIMER && wpd.path_len > md->db->range3))
- return 0;
+ struct walkpath_data wpd;
+ bool is_standing = (md->ud.walktimer == INVALID_TIMER);
+ if (!path->search(&wpd, &md->bl, md->bl.m, md->bl.x, md->bl.y, bl->x, bl->y, 0, CELL_CHKNOPASS) // Count walk path cells
+ || (is_standing && wpd.path_len > md->db->range2) //Standing monsters use range2, walking monsters use range3
+ || (!is_standing && wpd.path_len > md->db->range3)) {
+ if (!check_distance_bl(&md->bl, bl, md->status.rhw.range)
+ || !path->search_long(NULL, &md->bl, md->bl.m, md->bl.x, md->bl.y, bl->x, bl->y, CELL_CHKWALL))
+ return 0;
+ }
#endif
(*target) = bl;
md->target_id=bl->id;
@@ -1297,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
*------------------------------------------*/
@@ -1341,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); // Can be NULL due to master being BL_PC
+ // If master is BL_MOB and in battle, lock & chase to master's target instead, unless configured not to.
+ if ((battle_config.slave_chase_masters_chasetarget == 0 || (m_md != NULL && !mob->is_in_battle_state(m_md)))
+ && map->search_freecell(&md->bl, bl->m, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 1)
+ && unit->walktoxy(&md->bl, x, y, 0))
return 1;
}
} else if (bl->m != md->bl.m && map_flag_gvg(md->bl.m)) {
@@ -1353,26 +1379,28 @@ 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); // Can be NULL due to master being BL_PC
+ nullpo_retr(0, ud);
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 != NULL && 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;
@@ -1910,7 +1938,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
*/
@@ -1918,7 +1946,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;
@@ -1950,7 +1978,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);
@@ -3934,7 +3962,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
@@ -3943,13 +3971,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);
@@ -3961,7 +3989,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;
@@ -3989,7 +4017,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)
@@ -4013,7 +4041,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;
@@ -4025,7 +4053,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) {
@@ -4078,10 +4106,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) {
@@ -4194,7 +4220,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
@@ -4217,7 +4243,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);
@@ -4262,7 +4288,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
@@ -4342,7 +4368,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++;
@@ -5670,7 +5696,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);
}
@@ -5805,6 +5831,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/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 5eccfbaf6..a8ff661e8 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -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 ab7513ede..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;
diff --git a/src/map/skill.c b/src/map/skill.c
index dae075927..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;
}
}
@@ -8754,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);
@@ -21101,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 96a02c023..d2c67b84e 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -13367,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))
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
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index 0f76ba4b0..389d273e3 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -4180,6 +4180,10 @@ typedef enum parsefunc_rcode (*HPMHOOK_pre_PRIV__lclif_parse_CA_CHARSERVERCONNEC
typedef enum parsefunc_rcode (*HPMHOOK_post_PRIV__lclif_parse_CA_CHARSERVERCONNECT) (enum parsefunc_rcode retVal___, int fd, struct login_session_data *sd);
#endif // LOGIN_LCLIF_P_H
#ifdef COMMON_CONF_H /* libconfig */
+typedef void (*HPMHOOK_pre_libconfig_set_db_path) (const char **db_path);
+typedef void (*HPMHOOK_post_libconfig_set_db_path) (const char *db_path);
+typedef void (*HPMHOOK_pre_libconfig_format_db_path) (const char **filename, char **path_buf, int *buffer_len);
+typedef void (*HPMHOOK_post_libconfig_format_db_path) (const char *filename, char *path_buf, int buffer_len);
typedef int (*HPMHOOK_pre_libconfig_read) (struct config_t **config, FILE **stream);
typedef int (*HPMHOOK_post_libconfig_read) (int retVal___, struct config_t *config, FILE *stream);
typedef void (*HPMHOOK_pre_libconfig_write) (const struct config_t **config, FILE **stream);
@@ -5146,6 +5150,10 @@ typedef int (*HPMHOOK_pre_mapif_parse_ClanMemberCount) (int *fd, int *clan_id, i
typedef int (*HPMHOOK_post_mapif_parse_ClanMemberCount) (int retVal___, int fd, int clan_id, int kick_interval);
#endif // CHAR_MAPIF_H
#ifdef COMMON_MAPINDEX_H /* mapindex */
+typedef bool (*HPMHOOK_pre_mapindex_config_read_dbpath) (const char **filename, const struct config_t **config);
+typedef bool (*HPMHOOK_post_mapindex_config_read_dbpath) (bool retVal___, const char *filename, const struct config_t *config);
+typedef bool (*HPMHOOK_pre_mapindex_config_read) (void);
+typedef bool (*HPMHOOK_post_mapindex_config_read) (bool retVal___);
typedef int (*HPMHOOK_pre_mapindex_init) (void);
typedef int (*HPMHOOK_post_mapindex_init) (int retVal___);
typedef void (*HPMHOOK_pre_mapindex_final) (void);
@@ -5348,6 +5356,8 @@ typedef int (*HPMHOOK_pre_mob_ai_sub_hard_lootsearch) (struct block_list **bl, v
typedef int (*HPMHOOK_post_mob_ai_sub_hard_lootsearch) (int retVal___, struct block_list *bl, va_list ap);
typedef int (*HPMHOOK_pre_mob_warpchase_sub) (struct block_list **bl, va_list ap);
typedef int (*HPMHOOK_post_mob_warpchase_sub) (int retVal___, struct block_list *bl, va_list ap);
+typedef bool (*HPMHOOK_pre_mob_is_in_battle_state) (const struct mob_data **md);
+typedef bool (*HPMHOOK_post_mob_is_in_battle_state) (bool retVal___, const struct mob_data *md);
typedef int (*HPMHOOK_pre_mob_ai_sub_hard_slavemob) (struct mob_data **md, int64 *tick);
typedef int (*HPMHOOK_post_mob_ai_sub_hard_slavemob) (int retVal___, struct mob_data *md, int64 tick);
typedef int (*HPMHOOK_pre_mob_unlocktarget) (struct mob_data **md, int64 *tick);
diff --git a/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc
index a5f65654e..cdba77e09 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.HPMHooksCore.inc
@@ -778,6 +778,10 @@ struct {
struct HPMHookPoint *HP_inter_storage_parse_frommap_post;
struct HPMHookPoint *HP_inter_storage_retrieve_bound_items_pre;
struct HPMHookPoint *HP_inter_storage_retrieve_bound_items_post;
+ struct HPMHookPoint *HP_libconfig_set_db_path_pre;
+ struct HPMHookPoint *HP_libconfig_set_db_path_post;
+ struct HPMHookPoint *HP_libconfig_format_db_path_pre;
+ struct HPMHookPoint *HP_libconfig_format_db_path_post;
struct HPMHookPoint *HP_libconfig_read_pre;
struct HPMHookPoint *HP_libconfig_read_post;
struct HPMHookPoint *HP_libconfig_write_pre;
@@ -1252,6 +1256,10 @@ struct {
struct HPMHookPoint *HP_mapif_parse_ClanMemberKick_post;
struct HPMHookPoint *HP_mapif_parse_ClanMemberCount_pre;
struct HPMHookPoint *HP_mapif_parse_ClanMemberCount_post;
+ struct HPMHookPoint *HP_mapindex_config_read_dbpath_pre;
+ struct HPMHookPoint *HP_mapindex_config_read_dbpath_post;
+ struct HPMHookPoint *HP_mapindex_config_read_pre;
+ struct HPMHookPoint *HP_mapindex_config_read_post;
struct HPMHookPoint *HP_mapindex_init_pre;
struct HPMHookPoint *HP_mapindex_init_post;
struct HPMHookPoint *HP_mapindex_final_pre;
@@ -2391,6 +2399,10 @@ struct {
int HP_inter_storage_parse_frommap_post;
int HP_inter_storage_retrieve_bound_items_pre;
int HP_inter_storage_retrieve_bound_items_post;
+ int HP_libconfig_set_db_path_pre;
+ int HP_libconfig_set_db_path_post;
+ int HP_libconfig_format_db_path_pre;
+ int HP_libconfig_format_db_path_post;
int HP_libconfig_read_pre;
int HP_libconfig_read_post;
int HP_libconfig_write_pre;
@@ -2865,6 +2877,10 @@ struct {
int HP_mapif_parse_ClanMemberKick_post;
int HP_mapif_parse_ClanMemberCount_pre;
int HP_mapif_parse_ClanMemberCount_post;
+ int HP_mapindex_config_read_dbpath_pre;
+ int HP_mapindex_config_read_dbpath_post;
+ int HP_mapindex_config_read_pre;
+ int HP_mapindex_config_read_post;
int HP_mapindex_init_pre;
int HP_mapindex_init_post;
int HP_mapindex_final_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc
index efd72b670..a6043756d 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.HookingPoints.inc
@@ -425,6 +425,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(inter_storage->parse_frommap, HP_inter_storage_parse_frommap) },
{ HP_POP(inter_storage->retrieve_bound_items, HP_inter_storage_retrieve_bound_items) },
/* libconfig_interface */
+ { HP_POP(libconfig->set_db_path, HP_libconfig_set_db_path) },
+ { HP_POP(libconfig->format_db_path, HP_libconfig_format_db_path) },
{ HP_POP(libconfig->read, HP_libconfig_read) },
{ HP_POP(libconfig->write, HP_libconfig_write) },
{ HP_POP(libconfig->set_options, HP_libconfig_set_options) },
@@ -665,6 +667,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(mapif->parse_ClanMemberKick, HP_mapif_parse_ClanMemberKick) },
{ HP_POP(mapif->parse_ClanMemberCount, HP_mapif_parse_ClanMemberCount) },
/* mapindex_interface */
+ { HP_POP(mapindex->config_read_dbpath, HP_mapindex_config_read_dbpath) },
+ { HP_POP(mapindex->config_read, HP_mapindex_config_read) },
{ HP_POP(mapindex->init, HP_mapindex_init) },
{ HP_POP(mapindex->final, HP_mapindex_final) },
{ HP_POP(mapindex->addmap, HP_mapindex_addmap) },
diff --git a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
index 7ce54d288..b25025b1d 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
@@ -10116,6 +10116,58 @@ bool HP_inter_storage_retrieve_bound_items(int char_id, int account_id, int guil
return retVal___;
}
/* libconfig_interface */
+void HP_libconfig_set_db_path(const char *db_path) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_libconfig_set_db_path_pre > 0) {
+ void (*preHookFunc) (const char **db_path);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_set_db_path_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_libconfig_set_db_path_pre[hIndex].func;
+ preHookFunc(&db_path);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.libconfig.set_db_path(db_path);
+ }
+ if (HPMHooks.count.HP_libconfig_set_db_path_post > 0) {
+ void (*postHookFunc) (const char *db_path);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_set_db_path_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_libconfig_set_db_path_post[hIndex].func;
+ postHookFunc(db_path);
+ }
+ }
+ return;
+}
+void HP_libconfig_format_db_path(const char *filename, char *path_buf, int buffer_len) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_libconfig_format_db_path_pre > 0) {
+ void (*preHookFunc) (const char **filename, char **path_buf, int *buffer_len);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_format_db_path_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_libconfig_format_db_path_pre[hIndex].func;
+ preHookFunc(&filename, &path_buf, &buffer_len);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.libconfig.format_db_path(filename, path_buf, buffer_len);
+ }
+ if (HPMHooks.count.HP_libconfig_format_db_path_post > 0) {
+ void (*postHookFunc) (const char *filename, char *path_buf, int buffer_len);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_format_db_path_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_libconfig_format_db_path_post[hIndex].func;
+ postHookFunc(filename, path_buf, buffer_len);
+ }
+ }
+ return;
+}
int HP_libconfig_read(struct config_t *config, FILE *stream) {
int hIndex = 0;
int retVal___ = 0;
@@ -16415,6 +16467,60 @@ int HP_mapif_parse_ClanMemberCount(int fd, int clan_id, int kick_interval) {
return retVal___;
}
/* mapindex_interface */
+bool HP_mapindex_config_read_dbpath(const char *filename, const struct config_t *config) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_mapindex_config_read_dbpath_pre > 0) {
+ bool (*preHookFunc) (const char **filename, const struct config_t **config);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapindex_config_read_dbpath_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mapindex_config_read_dbpath_pre[hIndex].func;
+ retVal___ = preHookFunc(&filename, &config);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mapindex.config_read_dbpath(filename, config);
+ }
+ if (HPMHooks.count.HP_mapindex_config_read_dbpath_post > 0) {
+ bool (*postHookFunc) (bool retVal___, const char *filename, const struct config_t *config);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapindex_config_read_dbpath_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mapindex_config_read_dbpath_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, filename, config);
+ }
+ }
+ return retVal___;
+}
+bool HP_mapindex_config_read(void) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_mapindex_config_read_pre > 0) {
+ bool (*preHookFunc) (void);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapindex_config_read_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mapindex_config_read_pre[hIndex].func;
+ retVal___ = preHookFunc();
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mapindex.config_read();
+ }
+ if (HPMHooks.count.HP_mapindex_config_read_post > 0) {
+ bool (*postHookFunc) (bool retVal___);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapindex_config_read_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mapindex_config_read_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___);
+ }
+ }
+ return retVal___;
+}
int HP_mapindex_init(void) {
int hIndex = 0;
int retVal___ = 0;
diff --git a/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc
index ba0fe05c2..556757d76 100644
--- a/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_login.HPMHooksCore.inc
@@ -212,6 +212,10 @@ struct {
struct HPMHookPoint *HP_PRIV__lclif_parse_CA_REQ_HASH_post;
struct HPMHookPoint *HP_PRIV__lclif_parse_CA_CHARSERVERCONNECT_pre;
struct HPMHookPoint *HP_PRIV__lclif_parse_CA_CHARSERVERCONNECT_post;
+ struct HPMHookPoint *HP_libconfig_set_db_path_pre;
+ struct HPMHookPoint *HP_libconfig_set_db_path_post;
+ struct HPMHookPoint *HP_libconfig_format_db_path_pre;
+ struct HPMHookPoint *HP_libconfig_format_db_path_post;
struct HPMHookPoint *HP_libconfig_read_pre;
struct HPMHookPoint *HP_libconfig_read_post;
struct HPMHookPoint *HP_libconfig_write_pre;
@@ -1013,6 +1017,10 @@ struct {
int HP_PRIV__lclif_parse_CA_REQ_HASH_post;
int HP_PRIV__lclif_parse_CA_CHARSERVERCONNECT_pre;
int HP_PRIV__lclif_parse_CA_CHARSERVERCONNECT_post;
+ int HP_libconfig_set_db_path_pre;
+ int HP_libconfig_set_db_path_post;
+ int HP_libconfig_format_db_path_pre;
+ int HP_libconfig_format_db_path_post;
int HP_libconfig_read_pre;
int HP_libconfig_read_post;
int HP_libconfig_write_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc
index 1e3548621..65680e072 100644
--- a/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_login.HookingPoints.inc
@@ -131,6 +131,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(lclif->p->parse_CA_REQ_HASH, HP_PRIV__lclif_parse_CA_REQ_HASH) },
{ HP_POP(lclif->p->parse_CA_CHARSERVERCONNECT, HP_PRIV__lclif_parse_CA_CHARSERVERCONNECT) },
/* libconfig_interface */
+ { HP_POP(libconfig->set_db_path, HP_libconfig_set_db_path) },
+ { HP_POP(libconfig->format_db_path, HP_libconfig_format_db_path) },
{ HP_POP(libconfig->read, HP_libconfig_read) },
{ HP_POP(libconfig->write, HP_libconfig_write) },
{ HP_POP(libconfig->set_options, HP_libconfig_set_options) },
diff --git a/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc
index 080fb75ff..8f6076e2a 100644
--- a/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_login.Hooks.inc
@@ -2518,6 +2518,58 @@ enum parsefunc_rcode HP_PRIV__lclif_parse_CA_CHARSERVERCONNECT(int fd, struct lo
return retVal___;
}
/* libconfig_interface */
+void HP_libconfig_set_db_path(const char *db_path) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_libconfig_set_db_path_pre > 0) {
+ void (*preHookFunc) (const char **db_path);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_set_db_path_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_libconfig_set_db_path_pre[hIndex].func;
+ preHookFunc(&db_path);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.libconfig.set_db_path(db_path);
+ }
+ if (HPMHooks.count.HP_libconfig_set_db_path_post > 0) {
+ void (*postHookFunc) (const char *db_path);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_set_db_path_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_libconfig_set_db_path_post[hIndex].func;
+ postHookFunc(db_path);
+ }
+ }
+ return;
+}
+void HP_libconfig_format_db_path(const char *filename, char *path_buf, int buffer_len) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_libconfig_format_db_path_pre > 0) {
+ void (*preHookFunc) (const char **filename, char **path_buf, int *buffer_len);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_format_db_path_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_libconfig_format_db_path_pre[hIndex].func;
+ preHookFunc(&filename, &path_buf, &buffer_len);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.libconfig.format_db_path(filename, path_buf, buffer_len);
+ }
+ if (HPMHooks.count.HP_libconfig_format_db_path_post > 0) {
+ void (*postHookFunc) (const char *filename, char *path_buf, int buffer_len);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_format_db_path_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_libconfig_format_db_path_post[hIndex].func;
+ postHookFunc(filename, path_buf, buffer_len);
+ }
+ }
+ return;
+}
int HP_libconfig_read(struct config_t *config, FILE *stream) {
int hIndex = 0;
int retVal___ = 0;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index 266ca74f3..1196e3a99 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -3288,6 +3288,10 @@ struct {
struct HPMHookPoint *HP_itemdb_read_libconfig_lapineddukddak_sub_post;
struct HPMHookPoint *HP_itemdb_read_libconfig_lapineddukddak_sub_sources_pre;
struct HPMHookPoint *HP_itemdb_read_libconfig_lapineddukddak_sub_sources_post;
+ struct HPMHookPoint *HP_libconfig_set_db_path_pre;
+ struct HPMHookPoint *HP_libconfig_set_db_path_post;
+ struct HPMHookPoint *HP_libconfig_format_db_path_pre;
+ struct HPMHookPoint *HP_libconfig_format_db_path_post;
struct HPMHookPoint *HP_libconfig_read_pre;
struct HPMHookPoint *HP_libconfig_read_post;
struct HPMHookPoint *HP_libconfig_write_pre;
@@ -3758,6 +3762,10 @@ struct {
struct HPMHookPoint *HP_map_merge_zone_post;
struct HPMHookPoint *HP_map_zone_clear_single_pre;
struct HPMHookPoint *HP_map_zone_clear_single_post;
+ struct HPMHookPoint *HP_mapindex_config_read_dbpath_pre;
+ struct HPMHookPoint *HP_mapindex_config_read_dbpath_post;
+ struct HPMHookPoint *HP_mapindex_config_read_pre;
+ struct HPMHookPoint *HP_mapindex_config_read_post;
struct HPMHookPoint *HP_mapindex_init_pre;
struct HPMHookPoint *HP_mapindex_init_post;
struct HPMHookPoint *HP_mapindex_final_pre;
@@ -3950,6 +3958,8 @@ struct {
struct HPMHookPoint *HP_mob_ai_sub_hard_lootsearch_post;
struct HPMHookPoint *HP_mob_warpchase_sub_pre;
struct HPMHookPoint *HP_mob_warpchase_sub_post;
+ struct HPMHookPoint *HP_mob_is_in_battle_state_pre;
+ struct HPMHookPoint *HP_mob_is_in_battle_state_post;
struct HPMHookPoint *HP_mob_ai_sub_hard_slavemob_pre;
struct HPMHookPoint *HP_mob_ai_sub_hard_slavemob_post;
struct HPMHookPoint *HP_mob_unlocktarget_pre;
@@ -10107,6 +10117,10 @@ struct {
int HP_itemdb_read_libconfig_lapineddukddak_sub_post;
int HP_itemdb_read_libconfig_lapineddukddak_sub_sources_pre;
int HP_itemdb_read_libconfig_lapineddukddak_sub_sources_post;
+ int HP_libconfig_set_db_path_pre;
+ int HP_libconfig_set_db_path_post;
+ int HP_libconfig_format_db_path_pre;
+ int HP_libconfig_format_db_path_post;
int HP_libconfig_read_pre;
int HP_libconfig_read_post;
int HP_libconfig_write_pre;
@@ -10577,6 +10591,10 @@ struct {
int HP_map_merge_zone_post;
int HP_map_zone_clear_single_pre;
int HP_map_zone_clear_single_post;
+ int HP_mapindex_config_read_dbpath_pre;
+ int HP_mapindex_config_read_dbpath_post;
+ int HP_mapindex_config_read_pre;
+ int HP_mapindex_config_read_post;
int HP_mapindex_init_pre;
int HP_mapindex_init_post;
int HP_mapindex_final_pre;
@@ -10769,6 +10787,8 @@ struct {
int HP_mob_ai_sub_hard_lootsearch_post;
int HP_mob_warpchase_sub_pre;
int HP_mob_warpchase_sub_post;
+ int HP_mob_is_in_battle_state_pre;
+ int HP_mob_is_in_battle_state_post;
int HP_mob_ai_sub_hard_slavemob_pre;
int HP_mob_ai_sub_hard_slavemob_post;
int HP_mob_unlocktarget_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 712cd4168..da72b688a 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -1684,6 +1684,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(itemdb->read_libconfig_lapineddukddak_sub, HP_itemdb_read_libconfig_lapineddukddak_sub) },
{ HP_POP(itemdb->read_libconfig_lapineddukddak_sub_sources, HP_itemdb_read_libconfig_lapineddukddak_sub_sources) },
/* libconfig_interface */
+ { HP_POP(libconfig->set_db_path, HP_libconfig_set_db_path) },
+ { HP_POP(libconfig->format_db_path, HP_libconfig_format_db_path) },
{ HP_POP(libconfig->read, HP_libconfig_read) },
{ HP_POP(libconfig->write, HP_libconfig_write) },
{ HP_POP(libconfig->set_options, HP_libconfig_set_options) },
@@ -1923,6 +1925,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(map->merge_zone, HP_map_merge_zone) },
{ HP_POP(map->zone_clear_single, HP_map_zone_clear_single) },
/* mapindex_interface */
+ { HP_POP(mapindex->config_read_dbpath, HP_mapindex_config_read_dbpath) },
+ { HP_POP(mapindex->config_read, HP_mapindex_config_read) },
{ HP_POP(mapindex->init, HP_mapindex_init) },
{ HP_POP(mapindex->final, HP_mapindex_final) },
{ HP_POP(mapindex->addmap, HP_mapindex_addmap) },
@@ -2024,6 +2028,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(mob->ai_sub_hard_bg_ally, HP_mob_ai_sub_hard_bg_ally) },
{ HP_POP(mob->ai_sub_hard_lootsearch, HP_mob_ai_sub_hard_lootsearch) },
{ HP_POP(mob->warpchase_sub, HP_mob_warpchase_sub) },
+ { HP_POP(mob->is_in_battle_state, HP_mob_is_in_battle_state) },
{ HP_POP(mob->ai_sub_hard_slavemob, HP_mob_ai_sub_hard_slavemob) },
{ HP_POP(mob->unlocktarget, HP_mob_unlocktarget) },
{ HP_POP(mob->randomwalk, HP_mob_randomwalk) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 7a817f45d..c331d66a9 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -43260,6 +43260,58 @@ bool HP_itemdb_read_libconfig_lapineddukddak_sub_sources(struct config_setting_t
return retVal___;
}
/* libconfig_interface */
+void HP_libconfig_set_db_path(const char *db_path) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_libconfig_set_db_path_pre > 0) {
+ void (*preHookFunc) (const char **db_path);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_set_db_path_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_libconfig_set_db_path_pre[hIndex].func;
+ preHookFunc(&db_path);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.libconfig.set_db_path(db_path);
+ }
+ if (HPMHooks.count.HP_libconfig_set_db_path_post > 0) {
+ void (*postHookFunc) (const char *db_path);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_set_db_path_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_libconfig_set_db_path_post[hIndex].func;
+ postHookFunc(db_path);
+ }
+ }
+ return;
+}
+void HP_libconfig_format_db_path(const char *filename, char *path_buf, int buffer_len) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_libconfig_format_db_path_pre > 0) {
+ void (*preHookFunc) (const char **filename, char **path_buf, int *buffer_len);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_format_db_path_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_libconfig_format_db_path_pre[hIndex].func;
+ preHookFunc(&filename, &path_buf, &buffer_len);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.libconfig.format_db_path(filename, path_buf, buffer_len);
+ }
+ if (HPMHooks.count.HP_libconfig_format_db_path_post > 0) {
+ void (*postHookFunc) (const char *filename, char *path_buf, int buffer_len);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_libconfig_format_db_path_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_libconfig_format_db_path_post[hIndex].func;
+ postHookFunc(filename, path_buf, buffer_len);
+ }
+ }
+ return;
+}
int HP_libconfig_read(struct config_t *config, FILE *stream) {
int hIndex = 0;
int retVal___ = 0;
@@ -49689,6 +49741,60 @@ void HP_map_zone_clear_single(struct map_zone_data *zone) {
return;
}
/* mapindex_interface */
+bool HP_mapindex_config_read_dbpath(const char *filename, const struct config_t *config) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_mapindex_config_read_dbpath_pre > 0) {
+ bool (*preHookFunc) (const char **filename, const struct config_t **config);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapindex_config_read_dbpath_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mapindex_config_read_dbpath_pre[hIndex].func;
+ retVal___ = preHookFunc(&filename, &config);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mapindex.config_read_dbpath(filename, config);
+ }
+ if (HPMHooks.count.HP_mapindex_config_read_dbpath_post > 0) {
+ bool (*postHookFunc) (bool retVal___, const char *filename, const struct config_t *config);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapindex_config_read_dbpath_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mapindex_config_read_dbpath_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, filename, config);
+ }
+ }
+ return retVal___;
+}
+bool HP_mapindex_config_read(void) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_mapindex_config_read_pre > 0) {
+ bool (*preHookFunc) (void);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapindex_config_read_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mapindex_config_read_pre[hIndex].func;
+ retVal___ = preHookFunc();
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mapindex.config_read();
+ }
+ if (HPMHooks.count.HP_mapindex_config_read_post > 0) {
+ bool (*postHookFunc) (bool retVal___);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mapindex_config_read_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mapindex_config_read_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___);
+ }
+ }
+ return retVal___;
+}
int HP_mapindex_init(void) {
int hIndex = 0;
int retVal___ = 0;
@@ -52322,6 +52428,33 @@ int HP_mob_warpchase_sub(struct block_list *bl, va_list ap) {
}
return retVal___;
}
+bool HP_mob_is_in_battle_state(const struct mob_data *md) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if (HPMHooks.count.HP_mob_is_in_battle_state_pre > 0) {
+ bool (*preHookFunc) (const struct mob_data **md);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_is_in_battle_state_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_mob_is_in_battle_state_pre[hIndex].func;
+ retVal___ = preHookFunc(&md);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.mob.is_in_battle_state(md);
+ }
+ if (HPMHooks.count.HP_mob_is_in_battle_state_post > 0) {
+ bool (*postHookFunc) (bool retVal___, const struct mob_data *md);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_mob_is_in_battle_state_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_mob_is_in_battle_state_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, md);
+ }
+ }
+ return retVal___;
+}
int HP_mob_ai_sub_hard_slavemob(struct mob_data *md, int64 tick) {
int hIndex = 0;
int retVal___ = 0;