summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/HPMmap.c54
-rw-r--r--src/map/HPMmap.h2
-rw-r--r--src/map/atcommand.c93
-rw-r--r--src/map/battle.c17
-rw-r--r--src/map/battleground.c16
-rw-r--r--src/map/battleground.h6
-rw-r--r--src/map/channel.c2
-rw-r--r--src/map/chat.c2
-rw-r--r--src/map/chrif.c24
-rw-r--r--src/map/clif.c35
-rw-r--r--src/map/clif.h6
-rw-r--r--src/map/elemental.c2
-rw-r--r--src/map/guild.c25
-rw-r--r--src/map/homunculus.c2
-rw-r--r--src/map/instance.c16
-rw-r--r--src/map/instance.h7
-rw-r--r--src/map/intif.c2
-rw-r--r--src/map/irc-bot.c2
-rw-r--r--src/map/itemdb.c185
-rw-r--r--src/map/itemdb.h9
-rw-r--r--src/map/map.c93
-rw-r--r--src/map/map.h25
-rw-r--r--src/map/mapreg_sql.c2
-rw-r--r--src/map/mercenary.c2
-rw-r--r--src/map/mob.c855
-rw-r--r--src/map/mob.h26
-rw-r--r--src/map/npc.c13
-rw-r--r--src/map/npc.h6
-rw-r--r--src/map/npc_chat.c2
-rw-r--r--src/map/party.c25
-rw-r--r--src/map/party.h7
-rw-r--r--src/map/path.c4
-rw-r--r--src/map/pc.c64
-rw-r--r--src/map/pc.h9
-rw-r--r--src/map/pc_groups.c2
-rw-r--r--src/map/pet.c2
-rw-r--r--src/map/quest.c4
-rw-r--r--src/map/script.c234
-rw-r--r--src/map/script.h16
-rw-r--r--src/map/searchstore.c2
-rw-r--r--src/map/skill.c2
-rw-r--r--src/map/status.c165
-rw-r--r--src/map/status.h3
-rw-r--r--src/map/storage.c2
-rw-r--r--src/map/unit.c26
45 files changed, 1065 insertions, 1033 deletions
diff --git a/src/map/HPMmap.c b/src/map/HPMmap.c
index ac78e8c84..ade685bf7 100644
--- a/src/map/HPMmap.c
+++ b/src/map/HPMmap.c
@@ -15,7 +15,7 @@
#include "common/db.h"
#include "common/des.h"
#include "common/ers.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/mapindex.h"
#include "common/mmo.h"
#include "common/nullpo.h"
@@ -85,57 +85,31 @@ struct HPM_atcommand_list {
struct HPM_atcommand_list *atcommand_list = NULL;
unsigned int atcommand_list_items = 0;
-bool HPM_map_grabHPData(struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr) {
- /* record address */
- switch( type ) {
+/**
+ * HPM plugin data store validator sub-handler (map-server)
+ *
+ * @see HPM_interface::data_store_validate
+ */
+bool HPM_map_data_store_validate(enum HPluginDataTypes type, struct hplugin_data_store **storeptr, bool initialize)
+{
+ switch (type) {
case HPDT_MSD:
- ret->HPDataSRCPtr = (void**)(&((struct map_session_data *)ptr)->hdata);
- ret->hdatac = &((struct map_session_data *)ptr)->hdatac;
- break;
case HPDT_NPCD:
- ret->HPDataSRCPtr = (void**)(&((struct npc_data *)ptr)->hdata);
- ret->hdatac = &((struct npc_data *)ptr)->hdatac;
- break;
case HPDT_MAP:
- ret->HPDataSRCPtr = (void**)(&((struct map_data *)ptr)->hdata);
- ret->hdatac = &((struct map_data *)ptr)->hdatac;
- break;
case HPDT_PARTY:
- ret->HPDataSRCPtr = (void**)(&((struct party_data *)ptr)->hdata);
- ret->hdatac = &((struct party_data *)ptr)->hdatac;
- break;
case HPDT_GUILD:
- ret->HPDataSRCPtr = (void**)(&((struct guild *)ptr)->hdata);
- ret->hdatac = &((struct guild *)ptr)->hdatac;
- break;
case HPDT_INSTANCE:
- ret->HPDataSRCPtr = (void**)(&((struct instance_data *)ptr)->hdata);
- ret->hdatac = &((struct instance_data *)ptr)->hdatac;
- break;
case HPDT_MOBDB:
- ret->HPDataSRCPtr = (void**)(&((struct mob_db *)ptr)->hdata);
- ret->hdatac = &((struct mob_db *)ptr)->hdatac;
- break;
case HPDT_MOBDATA:
- ret->HPDataSRCPtr = (void**)(&((struct mob_data *)ptr)->hdata);
- ret->hdatac = &((struct mob_data *)ptr)->hdatac;
- break;
case HPDT_ITEMDATA:
- ret->HPDataSRCPtr = (void**)(&((struct item_data *)ptr)->hdata);
- ret->hdatac = &((struct item_data *)ptr)->hdatac;
- break;
case HPDT_BGDATA:
- ret->HPDataSRCPtr = (void**)(&((struct battleground_data *)ptr)->hdata);
- ret->hdatac = &((struct battleground_data *)ptr)->hdatac;
- break;
case HPDT_AUTOTRADE_VEND:
- ret->HPDataSRCPtr = (void**)(&((struct autotrade_vending *)ptr)->hdata);
- ret->hdatac = &((struct autotrade_vending *)ptr)->hdatac;
- break;
+ // Initialized by the caller.
+ return true;
default:
- return false;
+ break;
}
- return true;
+ return false;
}
void HPM_map_plugin_load_sub(struct hplugin *plugin) {
@@ -188,7 +162,7 @@ void HPM_map_add_group_permission(unsigned int pluginID, char *name, unsigned in
void HPM_map_do_init(void) {
HPM->load_sub = HPM_map_plugin_load_sub;
- HPM->grabHPDataSub = HPM_map_grabHPData;
+ HPM->data_store_validate_sub = HPM_map_data_store_validate;
HPM->datacheck_init(HPMDataCheck, HPMDataCheckLen, HPMDataCheckVer);
HPM_shared_symbols(SERVER_TYPE_MAP);
}
diff --git a/src/map/HPMmap.h b/src/map/HPMmap.h
index 00a8f43c3..b1957b139 100644
--- a/src/map/HPMmap.h
+++ b/src/map/HPMmap.h
@@ -15,7 +15,7 @@
struct hplugin;
struct map_session_data;
-bool HPM_map_grabHPData(struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr);
+bool HPM_map_data_store_validate(enum HPluginDataTypes type, struct hplugin_data_store **storeptr, bool initialize);
bool HPM_map_add_atcommand(char *name, AtCommandFunc func);
void HPM_map_atcommands(void);
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index beeccaddd..ff88f2c63 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -41,7 +41,7 @@
#include "common/cbasetypes.h"
#include "common/conf.h"
#include "common/core.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/mmo.h" // MAX_CARTS
#include "common/nullpo.h"
#include "common/random.h"
@@ -242,16 +242,16 @@ ACMD(send)
}\
} while(0) //define GET_VALUE
- if (type > 0 && type < MAX_PACKET_DB) {
+ if (type >= MIN_PACKET_DB && type <= MAX_PACKET_DB) {
int off = 2;
if (len) {
// show packet length
- safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,904), type, packet_db[type].len); // Packet 0x%x length: %d
+ safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,904), type, clif->packet(type)->len); // Packet 0x%x length: %d
clif->message(fd, atcmd_output);
return true;
}
- len=packet_db[type].len;
+ len = clif->packet(type)->len;
if (len == 0) {
// unknown packet - ERROR
safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,905), type); // Unknown packet: 0x%x
@@ -402,7 +402,7 @@ ACMD(send)
SKIP_VALUE(message);
}
- if(packet_db[type].len == -1) {// send dynamic packet
+ if (clif->packet(type)->len == -1) { // send dynamic packet
WFIFOW(sd->fd,2)=TOW(off);
WFIFOSET(sd->fd,off);
} else {// send static packet
@@ -967,65 +967,64 @@ ACMD(hide) {
/*==========================================
* Changes a character's class
*------------------------------------------*/
-ACMD(jobchange) {
+ACMD(jobchange)
+{
int job = 0, upper = 0;
- const char* text;
-
- if (!*message || sscanf(message, "%12d %12d", &job, &upper) < 1) {
- upper = 0;
-
- if (*message) {
- int i;
- bool found = false;
+ bool found = false;
- // Normal Jobs
- for( i = JOB_NOVICE; i < JOB_MAX_BASIC && !found; i++ ) {
- if (strncmpi(message, pc->job_name(i), 16) == 0) {
- job = i;
- found = true;
- }
- }
+ if (*message == '\0') { // No message, just show the list
+ found = false;
+ } else if (sscanf(message, "%12d %12d", &job, &upper) >= 1) { // Numeric job ID
+ found = true;
+ } else { // Job name
+ int i;
- // High Jobs, Babies and Third
- for( i = JOB_NOVICE_HIGH; i < JOB_MAX && !found; i++ ){
- if (strncmpi(message, pc->job_name(i), 16) == 0) {
- job = i;
- found = true;
- }
+ // Normal Jobs
+ for (i = JOB_NOVICE; !found && i < JOB_MAX_BASIC; i++) {
+ if (strncmpi(message, pc->job_name(i), 16) == 0) {
+ job = i;
+ found = true;
+ break;
}
+ }
- if (!found) {
- text = atcommand_help_string(info);
- if (text)
- clif->messageln(fd, text);
- return false;
+ // High Jobs, Babies and Third
+ for (i = JOB_NOVICE_HIGH; !found && i < JOB_MAX; i++) {
+ if (strncmpi(message, pc->job_name(i), 16) == 0) {
+ job = i;
+ found = true;
+ break;
}
}
}
- /* WHY DO WE LIST THEM THEN? */
+
+ if (!found || !pc->db_checkid(job)) {
+ const char *text = atcommand_help_string(info);
+ if (text)
+ clif->messageln(fd, text);
+ return false;
+ }
+
// Deny direct transformation into dummy jobs
- if (job == JOB_KNIGHT2 || job == JOB_CRUSADER2 || job == JOB_WEDDING || job == JOB_XMAS || job == JOB_SUMMER
- || job == JOB_LORD_KNIGHT2 || job == JOB_PALADIN2 || job == JOB_BABY_KNIGHT2 || job == JOB_BABY_CRUSADER2 || job == JOB_STAR_GLADIATOR2
- || (job >= JOB_RUNE_KNIGHT2 && job <= JOB_MECHANIC_T2) || (job >= JOB_BABY_RUNE2 && job <= JOB_BABY_MECHANIC2)
+ if (job == JOB_KNIGHT2 || job == JOB_CRUSADER2
+ || job == JOB_WEDDING || job == JOB_XMAS || job == JOB_SUMMER
+ || job == JOB_LORD_KNIGHT2 || job == JOB_PALADIN2
+ || job == JOB_BABY_KNIGHT2 || job == JOB_BABY_CRUSADER2
+ || job == JOB_STAR_GLADIATOR2
+ || (job >= JOB_RUNE_KNIGHT2 && job <= JOB_MECHANIC_T2)
+ || (job >= JOB_BABY_RUNE2 && job <= JOB_BABY_MECHANIC2)
) {
+ /* WHY DO WE LIST THEM THEN? */
clif->message(fd, msg_fd(fd,923)); //"You can not change to this job by command."
return true;
}
- if (pc->db_checkid(job)) {
- if (pc->jobchange(sd, job, upper) == 0)
- clif->message(fd, msg_fd(fd,12)); // Your job has been changed.
- else {
- clif->message(fd, msg_fd(fd,155)); // You are unable to change your job.
- return false;
- }
- } else {
- text = atcommand_help_string(info);
- if (text)
- clif->messageln(fd, text);
+ if (pc->jobchange(sd, job, upper) != 0) {
+ clif->message(fd, msg_fd(fd,155)); // You are unable to change your job.
return false;
}
+ clif->message(fd, msg_fd(fd,12)); // Your job has been changed.
return true;
}
diff --git a/src/map/battle.c b/src/map/battle.c
index e2f85e988..be508dae0 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -26,7 +26,7 @@
#include "common/HPM.h"
#include "common/cbasetypes.h"
#include "common/ers.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
@@ -2814,7 +2814,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
}
if( sc->data[SC__MAELSTROM] && (flag&BF_MAGIC) && skill_id && (skill->get_inf(skill_id)&INF_GROUND_SKILL) ) {
// {(Maelstrom Skill LevelxAbsorbed Skill Level)+(Caster's Job/5)}/2
- int sp = (sc->data[SC__MAELSTROM]->val1 * skill_lv + sd->status.job_level / 5) / 2;
+ int sp = (sc->data[SC__MAELSTROM]->val1 * skill_lv + (sd ? sd->status.job_level / 5 : 0)) / 2;
status->heal(bl, 0, sp, 3);
d->dmg_lv = ATK_BLOCK;
return 0;
@@ -7157,14 +7157,14 @@ void Hercules_report(char* date, char *time_c) {
C_RENEWAL_EDP = 0x0400,
C_RENEWAL_ASPD = 0x0800,
C_SECURE_NPCTIMEOUT = 0x1000,
- C_SQL_DB_ITEM = 0x2000,
+ //C_SQL_DB_ITEM = 0x2000,
C_SQL_LOGS = 0x4000,
C_MEMWATCH = 0x8000,
C_DMALLOC = 0x10000,
C_GCOLLECT = 0x20000,
C_SEND_SHORTLIST = 0x40000,
- C_SQL_DB_MOB = 0x80000,
- C_SQL_DB_MOBSKILL = 0x100000,
+ //C_SQL_DB_MOB = 0x80000,
+ //C_SQL_DB_MOBSKILL = 0x100000,
C_PACKETVER_RE = 0x200000,
};
@@ -7229,13 +7229,6 @@ void Hercules_report(char* date, char *time_c) {
#endif
/* non-define part */
- if( map->db_use_sql_item_db )
- config |= C_SQL_DB_ITEM;
- if( map->db_use_sql_mob_db )
- config |= C_SQL_DB_MOB;
- if( map->db_use_sql_mob_skill_db )
- config |= C_SQL_DB_MOBSKILL;
-
if( logs->config.sql_logs )
config |= C_SQL_LOGS;
diff --git a/src/map/battleground.c b/src/map/battleground.c
index 5df05d301..cc5384d21 100644
--- a/src/map/battleground.c
+++ b/src/map/battleground.c
@@ -21,7 +21,7 @@
#include "common/cbasetypes.h"
#include "common/conf.h"
#include "common/HPM.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/showmsg.h"
#include "common/socket.h"
@@ -880,17 +880,9 @@ void do_init_battleground(bool minimal) {
*/
int bg_team_db_final(DBKey key, DBData *data, va_list ap) {
struct battleground_data* bgd = DB->data2ptr(data);
- int i;
- nullpo_ret(bgd);
- for(i = 0; i < bgd->hdatac; i++ ) {
- if( bgd->hdata[i]->flag.free ) {
- aFree(bgd->hdata[i]->data);
- }
- aFree(bgd->hdata[i]);
- }
- if( bgd->hdata )
- aFree(bgd->hdata);
-
+
+ HPM->data_store_destroy(&bgd->hdata);
+
return 0;
}
diff --git a/src/map/battleground.h b/src/map/battleground.h
index 094037f43..dcf92d6d8 100644
--- a/src/map/battleground.h
+++ b/src/map/battleground.h
@@ -10,7 +10,7 @@
#include "common/db.h"
#include "common/mmo.h" // struct party
-struct HPluginData;
+struct hplugin_data_store;
struct block_list;
struct map_session_data;
@@ -53,9 +53,7 @@ struct battleground_data {
// Logout Event
char logout_event[EVENT_NAME_LENGTH];
char die_event[EVENT_NAME_LENGTH];
- /* HPM Custom Struct */
- struct HPluginData **hdata;
- unsigned int hdatac;
+ struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
struct bg_arena {
diff --git a/src/map/channel.c b/src/map/channel.c
index 196e5f770..023d22c06 100644
--- a/src/map/channel.c
+++ b/src/map/channel.c
@@ -14,7 +14,7 @@
#include "common/cbasetypes.h"
#include "common/conf.h"
#include "common/db.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
diff --git a/src/map/chat.c b/src/map/chat.c
index 976b1ce8e..aaf34a6f9 100644
--- a/src/map/chat.c
+++ b/src/map/chat.c
@@ -14,7 +14,7 @@
#include "map/pc.h"
#include "map/skill.h" // ext_skill_unit_onplace()
#include "common/cbasetypes.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/mmo.h"
#include "common/nullpo.h"
#include "common/showmsg.h"
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 1e376e3bc..62ef52dbd 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -26,7 +26,7 @@
#include "common/HPM.h"
#include "common/cbasetypes.h"
#include "common/ers.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/showmsg.h"
#include "common/socket.h"
@@ -1351,7 +1351,7 @@ void chrif_skillid2idx(int fd) {
*
*------------------------------------------*/
int chrif_parse(int fd) {
- int packet_len, cmd, r;
+ int packet_len, cmd;
// only process data from the char-server
if ( fd != chrif->fd ) {
@@ -1375,22 +1375,22 @@ int chrif_parse(int fd) {
}
}
- while ( RFIFOREST(fd) >= 2 ) {
-
- if( HPM->packetsc[hpChrif_Parse] ) {
- if( (r = HPM->parse_packets(fd,hpChrif_Parse)) ) {
- if( r == 1 ) continue;
- if( r == 2 ) return 0;
- }
+ while (RFIFOREST(fd) >= 2) {
+ if (VECTOR_LENGTH(HPM->packets[hpChrif_Parse]) > 0) {
+ int result = HPM->parse_packets(fd,hpChrif_Parse);
+ if (result == 1)
+ continue;
+ if (result == 2)
+ return 0;
}
cmd = RFIFOW(fd,0);
if (cmd < 0x2af8 || cmd >= 0x2af8 + ARRAYLENGTH(chrif->packet_len_table) || chrif->packet_len_table[cmd-0x2af8] == 0) {
- r = intif->parse(fd); // Passed on to the intif
+ int result = intif->parse(fd); // Passed on to the intif
- if (r == 1) continue; // Treated in intif
- if (r == 2) return 0; // Didn't have enough data (len==-1)
+ if (result == 1) continue; // Treated in intif
+ if (result == 2) return 0; // Didn't have enough data (len==-1)
ShowWarning("chrif_parse: session #%d, intif->parse failed (unrecognized command 0x%.4x).\n", fd, cmd);
sockt->eof(fd);
diff --git a/src/map/clif.c b/src/map/clif.c
index 0d25be0a6..d499cf67f 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -42,7 +42,7 @@
#include "common/conf.h"
#include "common/ers.h"
#include "common/grfio.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/mmo.h" // NEW_CARTS
#include "common/nullpo.h"
#include "common/random.h"
@@ -10130,6 +10130,9 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
clif->message(fd, msg_fd(fd,1402));
}
return;
+ } else if (strcmpi(&chname[1], channel->config->ally_name) == 0) {
+ clif->message(fd, msg_fd(fd,1294)); // You're not allowed to talk on this channel
+ return;
}
}
@@ -18362,7 +18365,7 @@ void clif_openmergeitem(int fd, struct map_session_data *sd)
for (i = 0; i < MAX_INVENTORY; i++) {
struct item *item_data = &sd->status.inventory[i];
- if (item_data->nameid == 0 || !itemdb->isstackable(item_data->nameid))
+ if (item_data->nameid == 0 || !itemdb->isstackable(item_data->nameid) || item_data->bound != IBT_NONE)
continue;
merge_items[n].nameid = item_data->nameid;
@@ -18436,7 +18439,7 @@ void clif_ackmergeitems(int fd, struct map_session_data *sd)
it = &sd->status.inventory[idx];
- if (it->nameid == 0 || !itemdb->isstackable(it->nameid))
+ if (it->nameid == 0 || !itemdb->isstackable(it->nameid) || it->bound != IBT_NONE)
continue;
if (nameid == 0)
@@ -18578,12 +18581,12 @@ int clif_parse(int fd) {
if (RFIFOREST(fd) < 2)
return 0;
- if( HPM->packetsc[hpClif_Parse] ) {
- int r;
- if( (r = HPM->parse_packets(fd,hpClif_Parse)) ) {
- if( r == 1 ) continue;
- if( r == 2 ) return 0;
- }
+ if (VECTOR_LENGTH(HPM->packets[hpClif_Parse]) > 0) {
+ int result = HPM->parse_packets(fd,hpClif_Parse);
+ if (result == 1)
+ continue;
+ if (result == 2)
+ return 0;
}
if( sd )
@@ -18680,6 +18683,19 @@ int clif_parse(int fd) {
return 0;
}
+/**
+ * Returns information about the given packet ID.
+ *
+ * @param packet_id The packet ID.
+ * @return The corresponding packet_db entry, if any.
+ */
+const struct s_packet_db *clif_packet(int packet_id)
+{
+ if (packet_id < MIN_PACKET_DB || packet_id > MAX_PACKET_DB || packet_db[packet_id].len == 0)
+ return NULL;
+ return &packet_db[packet_id];
+}
+
static void __attribute__ ((unused)) packetdb_addpacket(short cmd, int len, ...) {
va_list va;
int i;
@@ -18815,6 +18831,7 @@ void clif_defaults(void) {
clif->parse = clif_parse;
clif->parse_cmd = clif_parse_cmd_optional;
clif->decrypt_cmd = clif_decrypt_cmd;
+ clif->packet = clif_packet;
/* auth */
clif->authok = clif_authok;
clif->authrefuse = clif_authrefuse;
diff --git a/src/map/clif.h b/src/map/clif.h
index f6f0d4fe7..40610b7c1 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -597,6 +597,7 @@ struct clif_interface {
int (*send_sub) (struct block_list *bl, va_list ap);
int (*send_actual) (int fd, void *buf, int len);
int (*parse) (int fd);
+ const struct s_packet_db *(*packet) (int packet_id);
unsigned short (*parse_cmd) ( int fd, struct map_session_data *sd );
unsigned short (*decrypt_cmd) ( int cmd, struct map_session_data *sd );
/* auth */
@@ -1323,11 +1324,6 @@ struct clif_interface {
};
#ifdef HERCULES_CORE
-/**
- * Vars
- **/
-extern struct s_packet_db packet_db[MAX_PACKET_DB + 1];
-
void clif_defaults(void);
#endif // HERCULES_CORE
diff --git a/src/map/elemental.c b/src/map/elemental.c
index b629275e5..1ab93f6c5 100644
--- a/src/map/elemental.c
+++ b/src/map/elemental.c
@@ -26,7 +26,7 @@
#include "map/trade.h"
#include "map/unit.h"
#include "common/cbasetypes.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/mmo.h"
#include "common/nullpo.h"
#include "common/random.h"
diff --git a/src/map/guild.c b/src/map/guild.c
index 7a187b625..6360e3e1f 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -23,7 +23,7 @@
#include "common/HPM.h"
#include "common/cbasetypes.h"
#include "common/ers.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/mapindex.h"
#include "common/nullpo.h"
#include "common/showmsg.h"
@@ -1763,16 +1763,7 @@ int guild_broken(int guild_id,int flag)
if( g->instance )
aFree(g->instance);
- if( g->hdata )
- {
- for( i = 0; i < g->hdatac; i++ ) {
- if( g->hdata[i]->flag.free ) {
- aFree(g->hdata[i]->data);
- }
- aFree(g->hdata[i]);
- }
- aFree(g->hdata);
- }
+ HPM->data_store_destroy(&g->hdata);
idb_remove(guild->db,guild_id);
return 0;
@@ -2250,7 +2241,6 @@ void do_init_guild(bool minimal) {
void do_final_guild(void) {
DBIterator *iter = db_iterator(guild->db);
struct guild *g;
- int i;
for( g = dbi_first(iter); dbi_exists(iter); g = dbi_next(iter) ) {
if( g->channel != NULL )
@@ -2259,16 +2249,7 @@ void do_final_guild(void) {
aFree(g->instance);
g->instance = NULL;
}
- if( g->hdata )
- {
- for( i = 0; i < g->hdatac; i++ ) {
- if( g->hdata[i]->flag.free ) {
- aFree(g->hdata[i]->data);
- }
- aFree(g->hdata[i]);
- }
- aFree(g->hdata);
- }
+ HPM->data_store_destroy(&g->hdata);
}
dbi_destroy(iter);
diff --git a/src/map/homunculus.c b/src/map/homunculus.c
index d0a4f6679..874d26fdb 100644
--- a/src/map/homunculus.c
+++ b/src/map/homunculus.c
@@ -27,7 +27,7 @@
#include "map/trade.h"
#include "map/unit.h"
#include "common/cbasetypes.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/mmo.h"
#include "common/nullpo.h"
#include "common/random.h"
diff --git a/src/map/instance.c b/src/map/instance.c
index 300247fe7..545ffe1e7 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -17,7 +17,7 @@
#include "common/HPM.h"
#include "common/cbasetypes.h"
#include "common/db.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/showmsg.h"
#include "common/socket.h"
@@ -588,19 +588,7 @@ void instance_destroy(int instance_id) {
instance->list[instance_id].state = INSTANCE_FREE;
instance->list[instance_id].num_map = 0;
- if (instance->list[instance_id].hdata)
- {
- for( j = 0; j < instance->list[instance_id].hdatac; j++ ) {
- if( instance->list[instance_id].hdata[j]->flag.free ) {
- aFree(instance->list[instance_id].hdata[j]->data);
- }
- aFree(instance->list[instance_id].hdata[j]);
- }
- aFree(instance->list[instance_id].hdata);
- }
-
- instance->list[instance_id].hdata = NULL;
- instance->list[instance_id].hdatac = 0;
+ HPM->data_store_destroy(&instance->list[instance_id].hdata);
}
/*--------------------------------------
diff --git a/src/map/instance.h b/src/map/instance.h
index 589e1a511..058cd2c3d 100644
--- a/src/map/instance.h
+++ b/src/map/instance.h
@@ -9,7 +9,7 @@
#include "common/hercules.h"
#include "common/mmo.h" // struct point
-struct HPluginData;
+struct hplugin_data_store;
struct block_list;
struct map_session_data;
@@ -52,10 +52,7 @@ struct instance_data {
unsigned int original_progress_timeout;
struct point respawn; ///< reload spawn
-
- /** HPM Custom Struct */
- struct HPluginData **hdata;
- unsigned int hdatac;
+ struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
struct instance_interface {
diff --git a/src/map/intif.c b/src/map/intif.c
index 1795055c4..1664a8a09 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -22,7 +22,7 @@
#include "map/pet.h"
#include "map/quest.h"
#include "map/storage.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/showmsg.h"
#include "common/socket.h"
diff --git a/src/map/irc-bot.c b/src/map/irc-bot.c
index f89bd2f1c..164242ff8 100644
--- a/src/map/irc-bot.c
+++ b/src/map/irc-bot.c
@@ -10,7 +10,7 @@
#include "map/map.h"
#include "map/pc.h"
#include "common/cbasetypes.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/random.h"
#include "common/showmsg.h"
#include "common/socket.h"
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index ccedee72a..efa9b18e5 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -14,7 +14,7 @@
#include "map/script.h" // item script processing
#include "common/HPM.h"
#include "common/conf.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
@@ -1502,112 +1502,8 @@ void itemdb_readdb_additional_fields(int itemid, config_setting_t *it, int n, co
}
/**
- * Processes one itemdb entry from the sql backend, loading and inserting it
- * into the item database.
- *
- * @param *handle MySQL connection handle. It is expected to have data
- * available (i.e. already queried) and it won't be freed (it
- * is care of the caller to do so)
- * @param n Ordinal number of the entry, to be displayed in case of
- * validation errors.
- * @param *source Source of the entry (table name), to be displayed in case of
- * validation errors.
- * @return Nameid of the validated entry, or 0 in case of failure.
- */
-int itemdb_readdb_sql_sub(Sql *handle, int n, const char *source) {
- struct item_data id = { 0 };
- char *data = NULL;
-
- /*
- * `id` smallint(5) unsigned NOT NULL DEFAULT '0'
- * `name_english` varchar(50) NOT NULL DEFAULT ''
- * `name_japanese` varchar(50) NOT NULL DEFAULT ''
- * `type` tinyint(2) unsigned NOT NULL DEFAULT '0'
- * `price_buy` mediumint(10) DEFAULT NULL
- * `price_sell` mediumint(10) DEFAULT NULL
- * `weight` smallint(5) unsigned DEFAULT NULL
- * `atk` smallint(5) unsigned DEFAULT NULL
- * `matk` smallint(5) unsigned DEFAULT NULL
- * `defence` smallint(5) unsigned DEFAULT NULL
- * `range` tinyint(2) unsigned DEFAULT NULL
- * `slots` tinyint(2) unsigned DEFAULT NULL
- * `equip_jobs` int(12) unsigned DEFAULT NULL
- * `equip_upper` tinyint(8) unsigned DEFAULT NULL
- * `equip_genders` tinyint(2) unsigned DEFAULT NULL
- * `equip_locations` smallint(4) unsigned DEFAULT NULL
- * `weapon_level` tinyint(2) unsigned DEFAULT NULL
- * `equip_level_min` smallint(5) unsigned DEFAULT NULL
- * `equip_level_max` smallint(5) unsigned DEFAULT NULL
- * `refineable` tinyint(1) unsigned DEFAULT NULL
- * `view` smallint(3) unsigned DEFAULT NULL
- * `bindonequip` tinyint(1) unsigned DEFAULT NULL
- * `buyingstore` tinyint(1) NOT NULL DEFAULT NULL
- * `delay` mediumint(9) NOT NULL DEFAULT NULL
- * `trade_flag` smallint(4) NOT NULL DEFAULT NULL
- * `trade_group` smallint(4) NOT NULL DEFAULT NULL
- * `nouse_flag` smallint(4) NOT NULL DEFAULT NULL
- * `nouse_group` smallint(4) NOT NULL DEFAULT NULL
- * `stack_amount` mediumint(6) NOT NULL DEFAULT NULL
- * `stack_flag` smallint(2) NOT NULL DEFAULT NULL
- * `sprite` mediumint(6) NOT NULL DEFAULT NULL
- * `script` text
- * `equip_script` text
- * `unequip_script` text
- */
- SQL->GetData(handle, 0, &data, NULL); id.nameid = (uint16)atoi(data);
- SQL->GetData(handle, 1, &data, NULL); safestrncpy(id.name, data, sizeof(id.name));
- SQL->GetData(handle, 2, &data, NULL); safestrncpy(id.jname, data, sizeof(id.jname));
- SQL->GetData(handle, 3, &data, NULL); id.type = atoi(data);
- SQL->GetData(handle, 4, &data, NULL); id.value_buy = data ? atoi(data) : -1; // Using invalid price -1 when missing, it'll be validated later
- SQL->GetData(handle, 5, &data, NULL); id.value_sell = data ? atoi(data) : -1;
- SQL->GetData(handle, 6, &data, NULL); id.weight = data ? atoi(data) : 0;
- SQL->GetData(handle, 7, &data, NULL); id.atk = data ? atoi(data) : 0;
- SQL->GetData(handle, 8, &data, NULL); id.matk = data ? atoi(data) : 0;
- SQL->GetData(handle, 9, &data, NULL); id.def = data ? atoi(data) : 0;
- SQL->GetData(handle, 10, &data, NULL); id.range = data ? atoi(data) : 0;
- SQL->GetData(handle, 11, &data, NULL); id.slot = data ? atoi(data) : 0;
- SQL->GetData(handle, 12, &data, NULL); itemdb->jobid2mapid(id.class_base, data ? (unsigned int)strtoul(data,NULL,0) : UINT_MAX);
- SQL->GetData(handle, 13, &data, NULL); id.class_upper = data ? (unsigned int)atoi(data) : ITEMUPPER_ALL;
- SQL->GetData(handle, 14, &data, NULL); id.sex = data ? atoi(data) : 2;
- SQL->GetData(handle, 15, &data, NULL); id.equip = data ? atoi(data) : 0;
- SQL->GetData(handle, 16, &data, NULL); id.wlv = data ? atoi(data) : 0;
- SQL->GetData(handle, 17, &data, NULL); id.elv = data ? atoi(data) : 0;
- SQL->GetData(handle, 18, &data, NULL); id.elvmax = data ? atoi(data) : 0;
- SQL->GetData(handle, 19, &data, NULL); id.flag.no_refine = data && atoi(data) ? 0 : 1;
- SQL->GetData(handle, 20, &data, NULL); id.look = data ? atoi(data) : 0;
- SQL->GetData(handle, 21, &data, NULL); id.flag.bindonequip = data && atoi(data) ? 1 : 0;
- SQL->GetData(handle, 22, &data, NULL); id.flag.force_serial = data && atoi(data) ? 1 : 0;
- SQL->GetData(handle, 23, &data, NULL); id.flag.buyingstore = data && atoi(data) ? 1 : 0;
- SQL->GetData(handle, 24, &data, NULL); id.delay = data ? atoi(data) : 0;
- SQL->GetData(handle, 25, &data, NULL); id.flag.trade_restriction = data ? atoi(data) : ITR_NONE;
- SQL->GetData(handle, 26, &data, NULL); id.gm_lv_trade_override = data ? atoi(data) : 0;
- SQL->GetData(handle, 27, &data, NULL); id.item_usage.flag = data ? atoi(data) : INR_NONE;
- SQL->GetData(handle, 28, &data, NULL); id.item_usage.override = data ? atoi(data) : 0;
- SQL->GetData(handle, 29, &data, NULL); id.stack.amount = data ? atoi(data) : 0;
- SQL->GetData(handle, 30, &data, NULL);
- if (data) {
- int stack_flag = atoi(data);
- id.stack.inventory = (stack_flag&1)!=0;
- id.stack.cart = (stack_flag&2)!=0;
- id.stack.storage = (stack_flag&4)!=0;
- id.stack.guildstorage = (stack_flag&8)!=0;
- }
- SQL->GetData(handle, 31, &data, NULL);
- if (data) {
- id.view_id = atoi(data);
- if (id.view_id)
- id.flag.available = 1;
- }
- SQL->GetData(handle, 32, &data, NULL); id.script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
- SQL->GetData(handle, 33, &data, NULL); id.equip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
- SQL->GetData(handle, 34, &data, NULL); id.unequip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
-
- return itemdb->validate_entry(&id, n, source);
-}
-
-/**
- * Processes one itemdb entry from the sql backend, loading and inserting it
- * into the item database.
+ * Processes one itemdb entry from the libconfig backend, loading and inserting
+ * it into the item database.
*
* @param *it Libconfig setting entry. It is expected to be valid and it
* won't be freed (it is care of the caller to do so if
@@ -1974,45 +1870,6 @@ int itemdb_readdb_libconfig(const char *filename) {
return count;
}
-/**
- * Reads from a sql itemdb table and inserts the found entries into the item
- * database, overwriting duplicate ones (i.e. item_db2 overriding item_db.)
- *
- * @param *tablename Table name to query.
- * @return The number of found entries.
- */
-int itemdb_readdb_sql(const char *tablename) {
- int i = 0, count = 0;
-
- // retrieve all rows from the item database
- if( SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT `id`, `name_english`, `name_japanese`, `type`,"
- " `price_buy`, `price_sell`, `weight`, `atk`,"
- " `matk`, `defence`, `range`, `slots`,"
- " `equip_jobs`, `equip_upper`, `equip_genders`, `equip_locations`,"
- " `weapon_level`, `equip_level_min`, `equip_level_max`, `refineable`,"
- " `view`, `bindonequip`, `forceserial`, `buyingstore`, `delay`,"
- " `trade_flag`, `trade_group`, `nouse_flag`, `nouse_group`,"
- " `stack_amount`, `stack_flag`, `sprite`, `script`,"
- " `equip_script`, `unequip_script`"
- "FROM `%s`", tablename) ) {
- Sql_ShowDebug(map->mysql_handle);
- return 0;
- }
-
- // process rows one by one
- while( SQL_SUCCESS == SQL->NextRow(map->mysql_handle) ) {
- if( itemdb->readdb_sql_sub(map->mysql_handle, i++, tablename) )
- count++;
- }
-
- // free the query result
- SQL->FreeResult(map->mysql_handle);
-
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, tablename);
-
- return count;
-}
-
/*==========================================
* Unique item ID function
* Only one operation by once
@@ -2029,22 +1886,12 @@ void itemdb_read(bool minimal) {
int i;
DBData prev;
- if (map->db_use_sql_item_db) {
- const char* item_db_name[] = {
- map->item_db_db,
- map->item_db2_db
- };
- for(i = 0; i < ARRAYLENGTH(item_db_name); i++)
- itemdb->readdb_sql(item_db_name[i]);
- } else {
- const char* filename[] = {
- DBPATH"item_db.conf",
- "item_db2.conf",
- };
-
- for(i = 0; i < ARRAYLENGTH(filename); i++)
- itemdb->readdb_libconfig(filename[i]);
- }
+ const char *filename[] = {
+ DBPATH"item_db.conf",
+ "item_db2.conf",
+ };
+ for (i = 0; i < ARRAYLENGTH(filename); i++)
+ itemdb->readdb_libconfig(filename[i]);
for( i = 0; i < ARRAYLENGTH(itemdb->array); ++i ) {
if( itemdb->array[i] ) {
@@ -2100,17 +1947,7 @@ void destroy_item_data(struct item_data* self, int free_self)
script->free_code(self->unequip_script);
if( self->combos )
aFree(self->combos);
- if (self->hdata)
- {
- int i;
- for (i = 0; i < self->hdatac; i++ ) {
- if (self->hdata[i]->flag.free ) {
- aFree(self->hdata[i]->data);
- }
- aFree(self->hdata[i]);
- }
- aFree(self->hdata);
- }
+ HPM->data_store_destroy(&self->hdata);
#if defined(DEBUG)
// trash item
memset(self, 0xDD, sizeof(struct item_data));
@@ -2369,10 +2206,8 @@ void itemdb_defaults(void) {
itemdb->gendercheck = itemdb_gendercheck;
itemdb->validate_entry = itemdb_validate_entry;
itemdb->readdb_additional_fields = itemdb_readdb_additional_fields;
- itemdb->readdb_sql_sub = itemdb_readdb_sql_sub;
itemdb->readdb_libconfig_sub = itemdb_readdb_libconfig_sub;
itemdb->readdb_libconfig = itemdb_readdb_libconfig;
- itemdb->readdb_sql = itemdb_readdb_sql;
itemdb->unique_id = itemdb_unique_id;
itemdb->read = itemdb_read;
itemdb->destroy_item_data = destroy_item_data;
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index a3edd451e..7b35e1ae1 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -10,9 +10,9 @@
#include "common/conf.h"
#include "common/db.h"
#include "common/mmo.h" // ITEM_NAME_LENGTH
-#include "common/sql.h"
struct script_code;
+struct hplugin_data_store;
/**
* Defines
@@ -488,10 +488,7 @@ struct item_data {
/* TODO add a pointer to some sort of (struct extra) and gather all the not-common vals into it to save memory */
struct item_group *group;
struct item_package *package;
-
- /* HPM Custom Struct */
- struct HPluginData **hdata;
- unsigned int hdatac;
+ struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
#define itemdb_name(n) (itemdb->search(n)->name)
@@ -604,10 +601,8 @@ struct itemdb_interface {
int (*gendercheck) (struct item_data *id);
int (*validate_entry) (struct item_data *entry, int n, const char *source);
void (*readdb_additional_fields) (int itemid, config_setting_t *it, int n, const char *source);
- int (*readdb_sql_sub) (Sql *handle, int n, const char *source);
int (*readdb_libconfig_sub) (config_setting_t *it, int n, const char *source);
int (*readdb_libconfig) (const char *filename);
- int (*readdb_sql) (const char *tablename);
uint64 (*unique_id) (struct map_session_data *sd);
void (*read) (bool minimal);
void (*destroy_item_data) (struct item_data *self, int free_self);
diff --git a/src/map/map.c b/src/map/map.c
index fe0922063..cd2ba17c2 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -48,7 +48,7 @@
#include "common/core.h"
#include "common/ers.h"
#include "common/grfio.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
@@ -3239,16 +3239,7 @@ void do_final_maps(void) {
if( map->list[i].qi_data )
aFree(map->list[i].qi_data);
- if( map->list[i].hdata )
- {
- for( v = 0; v < map->list[i].hdatac; v++ ) {
- if( map->list[i].hdata[v]->flag.free ) {
- aFree(map->list[i].hdata[v]->data);
- }
- aFree(map->list[i].hdata[v]);
- }
- aFree(map->list[i].hdata);
- }
+ HPM->data_store_destroy(&map->list[i].hdata);
}
map->zone_db_clear();
@@ -3711,21 +3702,8 @@ int inter_config_read(char *cfgName) {
if (sscanf(line,"%1023[^:]: %1023[^\r\n]", w1, w2) < 2)
continue;
- /* table names */
- if(strcmpi(w1,"item_db_db")==0)
- safestrncpy(map->item_db_db, w2, sizeof(map->item_db_db));
- else if(strcmpi(w1,"mob_db_db")==0)
- safestrncpy(map->mob_db_db, w2, sizeof(map->mob_db_db));
- else if(strcmpi(w1,"item_db2_db")==0)
- safestrncpy(map->item_db2_db, w2, sizeof(map->item_db2_db));
- else if(strcmpi(w1,"mob_db2_db")==0)
- safestrncpy(map->mob_db2_db, w2, sizeof(map->mob_db2_db));
- else if(strcmpi(w1, "mob_skill_db_db") == 0)
- safestrncpy(map->mob_skill_db_db, w2, sizeof(map->mob_skill_db_db));
- else if(strcmpi(w1,"mob_skill_db2_db")==0)
- safestrncpy(map->mob_skill_db2_db, w2, sizeof(map->mob_skill_db2_db));
/* map sql stuff */
- else if(strcmpi(w1,"map_server_ip")==0)
+ if(strcmpi(w1,"map_server_ip")==0)
safestrncpy(map->server_ip, w2, sizeof(map->server_ip));
else if(strcmpi(w1,"map_server_port")==0)
map->server_port=atoi(w2);
@@ -3737,42 +3715,6 @@ int inter_config_read(char *cfgName) {
safestrncpy(map->server_db, w2, sizeof(map->server_db));
else if(strcmpi(w1,"default_codepage")==0)
safestrncpy(map->default_codepage, w2, sizeof(map->default_codepage));
- else if(strcmpi(w1,"use_sql_item_db")==0) {
- map->db_use_sql_item_db = config_switch(w2);
- ShowStatus ("Using item database as SQL: '%s'\n", w2);
- if (map->db_use_sql_item_db) {
- // Deprecated 2015-08-09 [Haru]
- ShowWarning("Support for the SQL item database is deprecated and it will removed in future versions. "
- "Please upgrade to the non-sql version as soon as possible. "
- "Bug reports or pull requests concerning the SQL item database are no longer accepted.\n");
- ShowInfo("Resuming in 10 seconds...\n");
- HSleep(10);
- }
- }
- else if(strcmpi(w1,"use_sql_mob_db")==0) {
- map->db_use_sql_mob_db = config_switch(w2);
- ShowStatus ("Using monster database as SQL: '%s'\n", w2);
- if (map->db_use_sql_mob_db) {
- // Deprecated 2015-08-09 [Haru]
- ShowWarning("Support for the SQL monster database is deprecated and it will removed in future versions. "
- "Please upgrade to the non-sql version as soon as possible. "
- "Bug reports or pull requests concerning the SQL monster database are no longer accepted.\n");
- ShowInfo("Resuming in 10 seconds...\n");
- HSleep(10);
- }
- }
- else if(strcmpi(w1,"use_sql_mob_skill_db")==0) {
- map->db_use_sql_mob_skill_db = config_switch(w2);
- ShowStatus ("Using monster skill database as SQL: '%s'\n", w2);
- if (map->db_use_sql_mob_skill_db) {
- // Deprecated 2015-08-09 [Haru]
- ShowWarning("Support for the SQL monster skill database is deprecated and it will removed in future versions. "
- "Please upgrade to the non-sql version as soon as possible. "
- "Bug reports or pull requests concerning the SQL monster skill database are no longer accepted.\n");
- ShowInfo("Resuming in 10 seconds...\n");
- HSleep(10);
- }
- }
else if(strcmpi(w1,"autotrade_merchants_db")==0)
safestrncpy(map->autotrade_merchants_db, w2, sizeof(map->autotrade_merchants_db));
else if(strcmpi(w1,"autotrade_data_db")==0)
@@ -3854,6 +3796,7 @@ struct map_zone_data *map_merge_zone(struct map_zone_data *main, struct map_zone
CREATE(zone, struct map_zone_data, 1);
safestrncpy(zone->name, newzone, MAP_ZONE_NAME_LENGTH);
+ zone->merge_type = MZMT_NEVERMERGE;
zone->disabled_skills_count = main->disabled_skills_count + other->disabled_skills_count;
zone->disabled_items_count = main->disabled_items_count + other->disabled_items_count;
zone->mapflags_count = main->mapflags_count + other->mapflags_count;
@@ -3930,7 +3873,7 @@ struct map_zone_data *map_merge_zone(struct map_zone_data *main, struct map_zone
memcpy(zone->capped_skills[cursor], other->capped_skills[i], sizeof(struct map_zone_skill_damage_cap_entry));
}
- zone->info.special = 2;
+ zone->info.merged = 1;
strdb_put(map->zone_db, newzone, zone);
return zone;
}
@@ -3941,13 +3884,13 @@ void map_zone_change2(int m, struct map_zone_data *zone) {
if( map->list[m].zone == zone )
return;
- if( map->list[m].zone->info.special != 2 ) /* we don't update it for merged zones! */
+ if( !map->list[m].zone->info.merged ) /* we don't update it for merged zones! */
map->list[m].prev_zone = map->list[m].zone;
if( map->list[m].zone_mf_count )
map->zone_remove(m);
- if( zone->info.special ) {
+ if( zone->merge_type == MZMT_MERGEABLE && map->list[m].prev_zone->merge_type != MZMT_NEVERMERGE ) {
zone = map->merge_zone(zone,map->list[m].prev_zone);
}
@@ -4899,12 +4842,15 @@ void read_map_zone_db(void) {
/* is this the global template? */
if( strncmpi(zonename,MAP_ZONE_NORMAL_NAME,MAP_ZONE_NAME_LENGTH) == 0 ) {
zone = &map->zone_all;
+ zone->merge_type = MZMT_NEVERMERGE;
is_all = true;
} else if( strncmpi(zonename,MAP_ZONE_PK_NAME,MAP_ZONE_NAME_LENGTH) == 0 ) {
zone = &map->zone_pk;
+ zone->merge_type = MZMT_NEVERMERGE;
is_all = true;
} else {
CREATE( zone, struct map_zone_data, 1 );
+ zone->merge_type = MZMT_NORMAL;
zone->disabled_skills_count = 0;
zone->disabled_items_count = 0;
}
@@ -5257,11 +5203,11 @@ void read_map_zone_db(void) {
/* post-load processing */
if( (zone = strdb_get(map->zone_db, MAP_ZONE_PVP_NAME)) )
- zone->info.special = 1;
+ zone->merge_type = MZMT_MERGEABLE;
if( (zone = strdb_get(map->zone_db, MAP_ZONE_GVG_NAME)) )
- zone->info.special = 1;
+ zone->merge_type = MZMT_MERGEABLE;
if( (zone = strdb_get(map->zone_db, MAP_ZONE_BG_NAME)) )
- zone->info.special = 1;
+ zone->merge_type = MZMT_MERGEABLE;
}
/* not supposed to go in here but in skill_final whatever */
libconfig->destroy(&map_zone_db);
@@ -5879,7 +5825,7 @@ int do_init(int argc, char *argv[])
map->nick_db = idb_alloc(DB_OPT_BASE);
map->charid_db = idb_alloc(DB_OPT_BASE);
map->regen_db = idb_alloc(DB_OPT_BASE); // efficient status_natural_heal processing
- map->iwall_db = strdb_alloc(DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls
+ map->iwall_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, 2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls
map->zone_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAP_ZONE_NAME_LENGTH);
map->iterator_ers = ers_new(sizeof(struct s_mapiterator),"map.c::map_iterator_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK);
@@ -6024,17 +5970,6 @@ void map_defaults(void) {
map->night_flag = 0; // 0=day, 1=night [Yor]
map->enable_spy = 0; //To enable/disable @spy commands, which consume too much cpu time when sending packets. [Skotlex]
- map->db_use_sql_item_db = 0;
- map->db_use_sql_mob_db = 0;
- map->db_use_sql_mob_skill_db = 0;
-
- sprintf(map->item_db_db, "item_db");
- sprintf(map->item_db2_db, "item_db2");
- sprintf(map->mob_db_db, "mob_db");
- sprintf(map->mob_db2_db, "mob_db2");
- sprintf(map->mob_skill_db_db, "mob_skill_db");
- sprintf(map->mob_skill_db2_db, "mob_skill_db2");
-
map->INTER_CONF_NAME="conf/inter-server.conf";
map->LOG_CONF_NAME="conf/logs.conf";
map->MAP_CONF_NAME = "conf/map-server.conf";
diff --git a/src/map/map.h b/src/map/map.h
index 39af13de8..974fbc4ba 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -19,6 +19,7 @@
struct mob_data;
struct npc_data;
struct channel_data;
+struct hplugin_data_store;
enum E_MAPSERVER_ST {
MAPSERVER_ST_RUNNING = CORE_ST_LAST,
@@ -549,6 +550,12 @@ struct map_zone_skill_damage_cap_entry {
enum map_zone_skill_subtype subtype;
};
+enum map_zone_merge_type {
+ MZMT_NORMAL = 0, ///< MZMT_MERGEABLE zones can merge *into* MZMT_NORMAL zones (but not the converse).
+ MZMT_MERGEABLE, ///< Can merge with other MZMT_MERGEABLE zones and *into* MZMT_NORMAL zones.
+ MZMT_NEVERMERGE, ///< Cannot merge with any zones.
+};
+
#define MAP_ZONE_NAME_LENGTH 60
#define MAP_ZONE_ALL_NAME "All"
#define MAP_ZONE_NORMAL_NAME "Normal"
@@ -560,6 +567,7 @@ struct map_zone_skill_damage_cap_entry {
struct map_zone_data {
char name[MAP_ZONE_NAME_LENGTH];/* 20'd */
+ enum map_zone_merge_type merge_type;
struct map_zone_disabled_skill_entry **disabled_skills;
int disabled_skills_count;
int *disabled_items;
@@ -573,7 +581,7 @@ struct map_zone_data {
struct map_zone_skill_damage_cap_entry **capped_skills;
int capped_skills_count;
struct {
- unsigned int special : 2;/* 1: whether this is a mergeable zone; 2: whether it is a merged zone */
+ unsigned int merged : 1;
} info;
};
@@ -729,10 +737,7 @@ struct map_data {
/* speeds up clif_updatestatus processing by causing hpmeter to run only when someone with the permission can view it */
unsigned short hpmeter_visible;
-
- /* HPM Custom Struct */
- struct HPluginData **hdata;
- unsigned int hdatac;
+ struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
/// Stores information about a remote map (for multi-mapserver setups).
@@ -853,16 +858,6 @@ struct map_interface {
char *MSG_CONF_NAME;
char *GRF_PATH_FILENAME;
- int db_use_sql_item_db;
- int db_use_sql_mob_db;
- int db_use_sql_mob_skill_db;
-
- char item_db_db[32];
- char item_db2_db[32];
- char mob_db_db[32];
- char mob_db2_db[32];
- char mob_skill_db_db[32];
- char mob_skill_db2_db[32];
char autotrade_merchants_db[32];
char autotrade_data_db[32];
char npc_market_data_db[32];
diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c
index 37c830e2e..93ac52f33 100644
--- a/src/map/mapreg_sql.c
+++ b/src/map/mapreg_sql.c
@@ -11,7 +11,7 @@
#include "common/cbasetypes.h"
#include "common/db.h"
#include "common/ers.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/showmsg.h"
#include "common/sql.h"
#include "common/strlib.h"
diff --git a/src/map/mercenary.c b/src/map/mercenary.c
index b26876d39..59a6f7a44 100644
--- a/src/map/mercenary.c
+++ b/src/map/mercenary.c
@@ -26,7 +26,7 @@
#include "map/trade.h"
#include "map/unit.h"
#include "common/cbasetypes.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/mmo.h"
#include "common/nullpo.h"
#include "common/random.h"
diff --git a/src/map/mob.c b/src/map/mob.c
index 2fe9fe8fb..2b519462d 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -32,7 +32,7 @@
#include "common/cbasetypes.h"
#include "common/db.h"
#include "common/ers.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
@@ -3646,77 +3646,382 @@ void item_dropratio_adjust(int nameid, int mob_id, int *rate_adjust)
*rate_adjust = item_drop_ratio_db[nameid]->drop_ratio;
}
}
+
/* (mob_parse_dbrow)_cap_value */
static inline int mob_parse_dbrow_cap_value(int class_, int min, int max, int value) {
if( value > max ) {
- ShowError("mob_parse_dbrow: for class '%d', field value '%d' is higher than the maximum '%d'! capping...\n", class_, value, max);
+ ShowError("mob_parse_dbrow_cap_value: for class '%d', field value '%d' is higher than the maximum '%d'! capping...\n", class_, value, max);
return max;
} else if ( value < min ) {
- ShowError("mob_parse_dbrow: for class '%d', field value '%d' is lower than the minimum '%d'! capping...\n", class_, value, min);
+ ShowError("mob_parse_dbrow_cap_value: for class '%d', field value '%d' is lower than the minimum '%d'! capping...\n", class_, value, min);
return min;
}
return value;
}
+
+void mob_read_db_stats_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t)
+{
+ int i32;
+ if (mob->lookup_const(t, "Str", &i32) && i32 >= 0) {
+ mstatus->str = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ }
+ if (mob->lookup_const(t, "Agi", &i32) && i32 >= 0) {
+ mstatus->agi = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ }
+ if (mob->lookup_const(t, "Vit", &i32) && i32 >= 0) {
+ mstatus->vit = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ }
+ if (mob->lookup_const(t, "Int", &i32) && i32 >= 0) {
+ mstatus->int_ = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ }
+ if (mob->lookup_const(t, "Dex", &i32) && i32 >= 0) {
+ mstatus->dex = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ }
+ if (mob->lookup_const(t, "Luk", &i32) && i32 >= 0) {
+ mstatus->luk = mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ }
+}
+
+int mob_read_db_mode_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t)
+{
+ int mode = 0;
+ config_setting_t *t2;
+
+ if ((t2 = libconfig->setting_get_member(t, "CanMove")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_CANMOVE : 0;
+ if ((t2 = libconfig->setting_get_member(t, "Looter")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_LOOTER : 0;
+ if ((t2 = libconfig->setting_get_member(t, "Aggressive")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_AGGRESSIVE : 0;
+ if ((t2 = libconfig->setting_get_member(t, "Assist")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_ASSIST : 0;
+ if ((t2 = libconfig->setting_get_member(t, "CastSensorIdle")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_CASTSENSOR_IDLE : 0;
+ if ((t2 = libconfig->setting_get_member(t, "Boss")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_BOSS : 0;
+ if ((t2 = libconfig->setting_get_member(t, "Plant")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_PLANT : 0;
+ if ((t2 = libconfig->setting_get_member(t, "CanAttack")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_CANATTACK : 0;
+ if ((t2 = libconfig->setting_get_member(t, "Detector")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_DETECTOR : 0;
+ if ((t2 = libconfig->setting_get_member(t, "CastSensorChase")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_CASTSENSOR_CHASE : 0;
+ if ((t2 = libconfig->setting_get_member(t, "ChangeChase")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_CHANGECHASE : 0;
+ if ((t2 = libconfig->setting_get_member(t, "Angry")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_ANGRY : 0;
+ if ((t2 = libconfig->setting_get_member(t, "ChangeTargetMelee")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_CHANGETARGET_MELEE : 0;
+ if ((t2 = libconfig->setting_get_member(t, "ChangeTargetChase")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_CHANGETARGET_CHASE : 0;
+ if ((t2 = libconfig->setting_get_member(t, "TargetWeak")))
+ mode |= libconfig->setting_get_bool(t2) ? MD_TARGETWEAK : 0;
+
+ return mode;
+}
+
+void mob_read_db_mvpdrops_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t)
+{
+ config_setting_t *drop;
+ int i = 0;
+ int idx = 0;
+ int i32;
+
+ while (idx < MAX_MVP_DROP && (drop = libconfig->setting_get_elem(t, i))) {
+ const char *name = config_setting_name(drop);
+ int rate_adjust = battle_config.item_rate_mvp;
+ struct item_data* id = itemdb->search_name(name);
+ int value = 0;
+ if (!id)
+ {
+ ShowWarning("mob_read_db: mvp drop item %s not found in monster %d\n", name, class_);
+ i ++;
+ continue;
+ }
+ if (mob->get_const(drop, &i32) && i32 >= 0) {
+ value = i32;
+ }
+ if (value <= 0)
+ {
+ ShowWarning("mob_read_db: wrong drop chance %d for mvp drop item %s in monster %d\n", value, name, class_);
+ i ++;
+ continue;
+ }
+ entry->mvpitem[idx].nameid = id->nameid;
+ if (!entry->mvpitem[idx].nameid) {
+ entry->mvpitem[idx].p = 0; //No item....
+ i ++;
+ continue;
+ }
+ mob->item_dropratio_adjust(entry->mvpitem[idx].nameid, class_, &rate_adjust);
+ entry->mvpitem[idx].p = mob->drop_adjust(value, rate_adjust, battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
+
+ //calculate and store Max available drop chance of the MVP item
+ if (entry->mvpitem[idx].p) {
+ if (id->maxchance == -1 || (id->maxchance < entry->mvpitem[idx].p/10 + 1) ) {
+ //item has bigger drop chance or sold in shops
+ id->maxchance = entry->mvpitem[idx].p/10 + 1; //reduce MVP drop info to not spoil common drop rate
+ }
+ }
+ i++;
+ idx++;
+ }
+ if (idx == MAX_MVP_DROP && libconfig->setting_get_elem(t, i)) {
+ ShowWarning("mob_read_db: Too many mvp drops in mob %d\n", class_);
+ }
+}
+
+void mob_read_db_drops_sub(struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t)
+{
+ config_setting_t *drop;
+ int i = 0;
+ int idx = 0;
+ int i32;
+ int k;
+
+ while (idx < MAX_MOB_DROP && (drop = libconfig->setting_get_elem(t, i))) {
+ const char *name = config_setting_name(drop);
+ int rate_adjust, type;
+ unsigned short ratemin, ratemax;
+ struct item_data* id = itemdb->search_name(name);
+ int value = 0;
+ if (!id)
+ {
+ ShowWarning("mob_read_db: drop item %s not found in monster %d\n", name, class_);
+ i ++;
+ continue;
+ }
+ if (mob->get_const(drop, &i32) && i32 >= 0) {
+ value = i32;
+ }
+ if (value <= 0)
+ {
+ ShowWarning("mob_read_db: wrong drop chance %d for drop item %s in monster %d\n", value, name, class_);
+ i ++;
+ continue;
+ }
+
+ entry->dropitem[idx].nameid = id->nameid;
+ if (!entry->dropitem[idx].nameid) {
+ entry->dropitem[idx].p = 0; //No drop.
+ i ++;
+ continue;
+ }
+ type = id->type;
+ if ((class_ >= 1324 && class_ <= 1363) || (class_ >= 1938 && class_ <= 1946)) {
+ //Treasure box drop rates [Skotlex]
+ rate_adjust = battle_config.item_rate_treasure;
+ ratemin = battle_config.item_drop_treasure_min;
+ ratemax = battle_config.item_drop_treasure_max;
+ }
+ else switch (type)
+ { // Added support to restrict normal drops of MVP's [Reddozen]
+ case IT_HEALING:
+ rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_heal_boss : battle_config.item_rate_heal;
+ ratemin = battle_config.item_drop_heal_min;
+ ratemax = battle_config.item_drop_heal_max;
+ break;
+ case IT_USABLE:
+ case IT_CASH:
+ rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_use_boss : battle_config.item_rate_use;
+ ratemin = battle_config.item_drop_use_min;
+ ratemax = battle_config.item_drop_use_max;
+ break;
+ case IT_WEAPON:
+ case IT_ARMOR:
+ case IT_PETARMOR:
+ rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_equip_boss : battle_config.item_rate_equip;
+ ratemin = battle_config.item_drop_equip_min;
+ ratemax = battle_config.item_drop_equip_max;
+ break;
+ case IT_CARD:
+ rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_card_boss : battle_config.item_rate_card;
+ ratemin = battle_config.item_drop_card_min;
+ ratemax = battle_config.item_drop_card_max;
+ break;
+ default:
+ rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_common_boss : battle_config.item_rate_common;
+ ratemin = battle_config.item_drop_common_min;
+ ratemax = battle_config.item_drop_common_max;
+ break;
+ }
+ mob->item_dropratio_adjust(id->nameid, class_, &rate_adjust);
+ entry->dropitem[idx].p = mob->drop_adjust(value, rate_adjust, ratemin, ratemax);
+
+ //calculate and store Max available drop chance of the item
+ if (entry->dropitem[idx].p && (class_ < 1324 || class_ > 1363) && (class_ < 1938 || class_ > 1946))
+ { //Skip treasure chests.
+ if (id->maxchance == -1 || (id->maxchance < entry->dropitem[idx].p) ) {
+ id->maxchance = entry->dropitem[idx].p; //item has bigger drop chance or sold in shops
+ }
+ for (k = 0; k< MAX_SEARCH; k++) {
+ if (id->mob[k].chance <= entry->dropitem[idx].p)
+ break;
+ }
+ if (k == MAX_SEARCH)
+ {
+ i++;
+ idx++;
+ continue;
+ }
+
+ if (id->mob[k].id != class_ && k != MAX_SEARCH - 1)
+ memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
+ id->mob[k].chance = entry->dropitem[idx].p;
+ id->mob[k].id = class_;
+ }
+ i++;
+ idx++;
+ }
+ if (idx == MAX_MOB_DROP && libconfig->setting_get_elem(t, i)) {
+ ShowWarning("mob_read_db: Too many drops in mob %d\n", class_);
+ }
+}
+
/*==========================================
* processes one mobdb entry
*------------------------------------------*/
-bool mob_parse_dbrow(char** str) {
- struct mob_db *db, entry;
+bool mob_read_db_sub(config_setting_t *mobt, int id, const char *source)
+{
+ struct mob_db *entry = NULL, tmpEntry;
+ config_setting_t *t = NULL;
+ int i32 = 0, value = 0, class_ = 0;
struct status_data *mstatus;
- int class_, i;
- double exp, maxhp;
struct mob_data data;
-
- class_ = atoi(str[0]);
+ const char *str = NULL;
+ double maxhp;
+ double exp;
+ bool inherit = false;
+ bool range2Updated = false;
+ bool range3Updated = false;
+ bool dmotionUpdated = false;
+ bool maxhpUpdated = false;
+ bool maxspUpdated = false;
+
+ entry = &tmpEntry;
+ if (!libconfig->setting_lookup_int(mobt, "Id", &class_)) {
+ ShowWarning("mob_read_db_sub: Missing id in \"%s\", entry #%d, skipping.\n", source, class_);
+ return false;
+ }
if (class_ <= 1000 || class_ > MAX_MOB_DB) {
- ShowError("mob_parse_dbrow: Invalid monster ID %d, must be in range %d-%d.\n", class_, 1000, MAX_MOB_DB);
+ ShowError("mob_read_db_sub: Invalid monster ID %d, must be in range %d-%d.\n", class_, 1000, MAX_MOB_DB);
return false;
}
if (pc->db_checkid(class_)) {
- ShowError("mob_parse_dbrow: Invalid monster ID %d, reserved for player classes.\n", class_);
+ ShowError("mob_read_db_sub: Invalid monster ID %d, reserved for player classes.\n", class_);
return false;
}
if (class_ >= MOB_CLONE_START && class_ < MOB_CLONE_END) {
- ShowError("mob_parse_dbrow: Invalid monster ID %d. Range %d-%d is reserved for player clones. Please increase MAX_MOB_DB (%d).\n", class_, MOB_CLONE_START, MOB_CLONE_END-1, MAX_MOB_DB);
+ ShowError("mob_read_db_sub: Invalid monster ID %d. Range %d-%d is reserved for player clones. Please increase MAX_MOB_DB (%d).\n", class_, MOB_CLONE_START, MOB_CLONE_END-1, MAX_MOB_DB);
return false;
}
- memset(&entry, 0, sizeof(entry));
+ if ((t = libconfig->setting_get_member(mobt, "Inherit")) && (inherit = libconfig->setting_get_bool(t))) {
+ if (!mob->db_data[class_]) {
+ ShowWarning("mob_read_db_sub: Trying to inherit nonexistent mob %d, default values will be used instead.\n", class_);
+ inherit = false;
+ } else {
+ // Use old entry as default
+ struct mob_db *old_entry = mob->db_data[class_];
+ memcpy(entry, old_entry, sizeof(struct mob_db));
+ inherit = true;
+ }
+ }
+ if (!inherit) {
+ memset(&tmpEntry, 0, sizeof(tmpEntry));
+ }
- db = &entry;
- mstatus = &db->status;
+ mstatus = &entry->status;
- db->vd.class_ = class_;
- safestrncpy(db->sprite, str[1], sizeof(db->sprite));
- safestrncpy(db->jname, str[2], sizeof(db->jname));
- safestrncpy(db->name, str[3], sizeof(db->name));
- db->lv = atoi(str[4]);
- db->lv = cap_value(db->lv, 1, USHRT_MAX);
- mstatus->max_hp = atoi(str[5]);
- mstatus->max_sp = atoi(str[6]);
+ entry->vd.class_ = class_;
- exp = (double)atoi(str[7]) * (double)battle_config.base_exp_rate / 100.;
- db->base_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+ if (!libconfig->setting_lookup_string(mobt, "SpriteName", &str) || !*str ) {
+ if (!inherit) {
+ ShowWarning("mob_read_db_sub: Missing SpriteName in mob %d of \"%s\", skipping.\n", class_, source);
+ return false;
+ }
+ } else {
+ safestrncpy(entry->sprite, str, sizeof(entry->sprite));
+ }
- exp = (double)atoi(str[8]) * (double)battle_config.job_exp_rate / 100.;
- db->job_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+ if (!libconfig->setting_lookup_string(mobt, "Name", &str) || !*str ) {
+ if (!inherit) {
+ ShowWarning("mob_read_db_sub: Missing Name in mob %d of \"%s\", skipping.\n", class_, source);
+ return false;
+ }
+ } else {
+ safestrncpy(entry->name, str, sizeof(entry->name));
+ safestrncpy(entry->jname, str, sizeof(entry->jname));
+ }
+
+ if (mob->lookup_const(mobt, "Lv", &i32) && i32 >= 0) {
+ entry->lv = i32;
+ entry->lv = cap_value(entry->lv, 1, USHRT_MAX);
+ } else if (!inherit) {
+ entry->lv = 1;
+ }
+
+ if (mob->lookup_const(mobt, "Hp", &i32) && i32 >= 0) {
+ mstatus->max_hp = i32;
+ maxhpUpdated = true;
+ } else if (!inherit) {
+ mstatus->max_hp = 1;
+ maxhpUpdated = true;
+ }
+
+ if (mob->lookup_const(mobt, "Sp", &i32) && i32 >= 0) {
+ mstatus->max_sp = i32;
+ maxspUpdated = true;
+ } else if (!inherit) {
+ maxspUpdated = true;
+ }
+
+ if (mob->lookup_const(mobt, "Exp", &i32) && i32 >= 0) {
+ exp = (double)(i32) * (double)battle_config.base_exp_rate / 100.;
+ entry->base_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+ }
- mstatus->rhw.range = atoi(str[9]);
+ if (mob->lookup_const(mobt, "JExp", &i32) && i32 >= 0) {
+ exp = (double)(i32) * (double)battle_config.job_exp_rate / 100.;
+ entry->job_exp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+ }
- mstatus->rhw.atk = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[10]));
- mstatus->rhw.atk2 = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[11]));
+ if (mob->lookup_const(mobt, "AttackRange", &i32) && i32 >= 0) {
+ mstatus->rhw.range = i32;
+ } else {
+ mstatus->rhw.range = 1;
+ }
+
+ if ((t = libconfig->setting_get_member(mobt, "Attack"))) {
+ if (config_setting_is_aggregate(t)) {
+ if (libconfig->setting_length(t) >= 2)
+ mstatus->rhw.atk2 = libconfig->setting_get_int_elem(t, 1);
+ if (libconfig->setting_length(t) >= 1)
+ mstatus->rhw.atk = libconfig->setting_get_int_elem(t, 0);
+ } else if (mob->lookup_const(mobt, "Attack", &i32) && i32 >= 0) {
+ mstatus->rhw.atk = i32;
+ mstatus->rhw.atk2 = i32;
+ }
+ }
- mstatus->def = mob_parse_dbrow_cap_value(class_,DEFTYPE_MIN,DEFTYPE_MAX,atoi(str[12]));
- mstatus->mdef = mob_parse_dbrow_cap_value(class_,DEFTYPE_MIN,DEFTYPE_MAX,atoi(str[13]));
+ if (mob->lookup_const(mobt, "Def", &i32) && i32 >= 0) {
+ mstatus->def = mob_parse_dbrow_cap_value(class_, DEFTYPE_MIN, DEFTYPE_MAX, i32);
+ }
+ if (mob->lookup_const(mobt, "Mdef", &i32) && i32 >= 0) {
+ mstatus->mdef = mob_parse_dbrow_cap_value(class_, DEFTYPE_MIN, DEFTYPE_MAX, i32);
+ }
- mstatus->str = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[14]));
- mstatus->agi = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[15]));
- mstatus->vit = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[16]));
- mstatus->int_ = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[17]));
- mstatus->dex = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[18]));
- mstatus->luk = mob_parse_dbrow_cap_value(class_,UINT16_MIN,UINT16_MAX,atoi(str[19]));
+ if ((t = libconfig->setting_get_member(mobt, "Stats"))) {
+ if (config_setting_is_group(t)) {
+ mob->read_db_stats_sub(entry, mstatus, class_, t);
+ } else if (mob->lookup_const(mobt, "Stats", &i32) && i32 >= 0) {
+ mstatus->str = mstatus->agi = mstatus->vit = mstatus->int_ = mstatus->dex = mstatus->luk =
+ mob_parse_dbrow_cap_value(class_, UINT16_MIN, UINT16_MAX, i32);
+ }
+ }
/*
* Disabled for renewal since difference of 0 and 1 still has an impact in the formulas
@@ -3733,265 +4038,253 @@ bool mob_parse_dbrow(char** str) {
#endif
//Tests showed that chase range is effectively 2 cells larger than expected [Playtester]
- if (db->range3 > 0)
- db->range3 += 2;
+ if (entry->range3 > 0)
+ entry->range3 += 2;
+
+ if (mob->lookup_const(mobt, "ViewRange", &i32) && i32 >= 0) {
+ entry->range2 = i32;
+ range2Updated = true;
+ } else if (!inherit) {
+ entry->range2 = 1;
+ range2Updated = true;
+ }
+
+ if (mob->lookup_const(mobt, "ChaseRange", &i32) && i32 >= 0) {
+ entry->range3 = i32;
+ range3Updated = true;
+ } else if (!inherit) {
+ entry->range3 = 1;
+ range3Updated = true;
+ }
+ if (range2Updated) {
+ if (battle_config.view_range_rate != 100) {
+ entry->range2 = entry->range2 * battle_config.view_range_rate / 100;
+ if (entry->range2 < 1)
+ entry->range2 = 1;
+ }
+ }
+ if (range3Updated) {
+ if (battle_config.chase_range_rate != 100) {
+ entry->range3 = entry->range3 * battle_config.chase_range_rate / 100;
+ if (entry->range3 < entry->range2)
+ entry->range3 = entry->range2;
+ }
+ }
- db->range2 = atoi(str[20]);
- db->range3 = atoi(str[21]);
- if (battle_config.view_range_rate != 100) {
- db->range2 = db->range2 * battle_config.view_range_rate / 100;
- if (db->range2 < 1)
- db->range2 = 1;
+ if (mob->lookup_const(mobt, "Size", &i32) && i32 >= 0) {
+ mstatus->size = i32;
+ mstatus->size = cap_value(mstatus->size, 0, 2);
+ } else if (!inherit) {
+ mstatus->size = 0;
}
- if (battle_config.chase_range_rate != 100) {
- db->range3 = db->range3 * battle_config.chase_range_rate / 100;
- if (db->range3 < db->range2)
- db->range3 = db->range2;
+
+ if (mob->lookup_const(mobt, "Race", &i32) && i32 >= 0) {
+ mstatus->race = i32;
+ mstatus->race = cap_value(mstatus->race, 0, RC_MAX - 1);
+ } else if (!inherit) {
+ mstatus->race = 0;
}
- mstatus->size = atoi(str[22]);
- mstatus->race = atoi(str[23]);
+ if ((t = libconfig->setting_get_member(mobt, "Element")) && config_setting_is_list(t)) {
+ if (mob->get_const(libconfig->setting_get_elem(t, 0), &i32) && mob->get_const(libconfig->setting_get_elem(t, 1), &value)) {
+ mstatus->def_ele = i32;
+ mstatus->ele_lv = value;
+ }
+ } else {
+ if (!inherit) {
+ ShowError("mob_read_db_sub: Missing element for monster ID %d.\n", class_);
+ return false;
+ }
+ }
- i = atoi(str[24]); //Element
- mstatus->def_ele = i%10;
- mstatus->ele_lv = i/20;
if (mstatus->def_ele >= ELE_MAX) {
- ShowError("mob_parse_dbrow: Invalid element type %d for monster ID %d (max=%d).\n", mstatus->def_ele, class_, ELE_MAX-1);
- return false;
+ if (!inherit) {
+ ShowError("mob_read_db_sub: Invalid element type %d for monster ID %d (max=%d).\n", mstatus->def_ele, class_, ELE_MAX-1);
+ return false;
+ }
}
if (mstatus->ele_lv < 1 || mstatus->ele_lv > 4) {
- ShowError("mob_parse_dbrow: Invalid element level %d for monster ID %d, must be in range 1-4.\n", mstatus->ele_lv, class_);
- return false;
+ if (!inherit) {
+ ShowError("mob_read_db_sub: Invalid element level %d for monster ID %d, must be in range 1-4.\n", mstatus->ele_lv, class_);
+ return false;
+ }
+ }
+
+ if ((t = libconfig->setting_get_member(mobt, "Mode"))) {
+ if (config_setting_is_group(t)) {
+ mstatus->mode = mob->read_db_mode_sub(entry, mstatus, class_, t);
+ } else if (mob->lookup_const(mobt, "Mode", &i32) && i32 >= 0) {
+ mstatus->mode = i32;
+ }
}
- mstatus->mode = (int)strtol(str[25], NULL, 0);
if (!battle_config.monster_active_enable)
mstatus->mode &= ~MD_AGGRESSIVE;
- mstatus->speed = atoi(str[26]);
+ if (mob->lookup_const(mobt, "MoveSpeed", &i32) && i32 >= 0) {
+ mstatus->speed = i32;
+ }
+
mstatus->aspd_rate = 1000;
- i = atoi(str[27]);
- mstatus->adelay = cap_value(i, battle_config.monster_max_aspd*2, 4000);
- i = atoi(str[28]);
- mstatus->amotion = cap_value(i, battle_config.monster_max_aspd, 2000);
+
+ if (mob->lookup_const(mobt, "AttackDelay", &i32) && i32 >= 0) {
+ mstatus->adelay = cap_value(i32, battle_config.monster_max_aspd*2, 4000);
+ } else if (!inherit) {
+ mstatus->adelay = 4000;
+ }
+
+ if (mob->lookup_const(mobt, "AttackMotion", &i32) && i32 >= 0) {
+ mstatus->amotion = cap_value(i32, battle_config.monster_max_aspd, 2000);
+ } else if (!inherit) {
+ mstatus->amotion = 2000;
+ }
+
//If the attack animation is longer than the delay, the client crops the attack animation!
//On aegis there is no real visible effect of having a recharge-time less than amotion anyway.
if (mstatus->adelay < mstatus->amotion)
mstatus->adelay = mstatus->amotion;
- mstatus->dmotion = atoi(str[29]);
- if(battle_config.monster_damage_delay_rate != 100)
+
+ if (mob->lookup_const(mobt, "DamageMotion", &i32) && i32 >= 0) {
+ mstatus->dmotion = i32;
+ dmotionUpdated = true;
+ } else if (!inherit) {
+ dmotionUpdated = true;
+ }
+
+ if (dmotionUpdated && battle_config.monster_damage_delay_rate != 100)
mstatus->dmotion = mstatus->dmotion * battle_config.monster_damage_delay_rate / 100;
// Fill in remaining status data by using a dummy monster.
data.bl.type = BL_MOB;
- data.level = db->lv;
+ data.level = entry->lv;
memcpy(&data.status, mstatus, sizeof(struct status_data));
- status->calc_misc(&data.bl, mstatus, db->lv);
+ status->calc_misc(&data.bl, mstatus, entry->lv);
// MVP EXP Bonus: MEXP
// Some new MVP's MEXP multiple by high exp-rate cause overflow. [LuzZza]
- exp = (double)atoi(str[30]) * (double)battle_config.mvp_exp_rate / 100.;
- db->mexp = (unsigned int)cap_value(exp, 0, UINT_MAX);
-
- //Now that we know if it is an mvp or not, apply battle_config modifiers [Skotlex]
- maxhp = (double)mstatus->max_hp;
- if (db->mexp > 0) { //Mvp
- if (battle_config.mvp_hp_rate != 100)
- maxhp = maxhp * (double)battle_config.mvp_hp_rate / 100.;
- } else //Normal mob
- if (battle_config.monster_hp_rate != 100)
- maxhp = maxhp * (double)battle_config.monster_hp_rate / 100.;
-
- mstatus->max_hp = (unsigned int)cap_value(maxhp, 1, UINT_MAX);
- if(mstatus->max_sp < 1) mstatus->max_sp = 1;
+ if (mob->lookup_const(mobt, "MvpExp", &i32) && i32 >= 0) {
+ exp = (double)i32 * (double)battle_config.mvp_exp_rate / 100.;
+ entry->mexp = (unsigned int)cap_value(exp, 0, UINT_MAX);
+ } else if (!inherit) {
+ exp = 0;
+ }
+
+ if (maxhpUpdated) {
+ //Now that we know if it is an mvp or not, apply battle_config modifiers [Skotlex]
+ maxhp = (double)mstatus->max_hp;
+ if (entry->mexp > 0) { //Mvp
+ if (battle_config.mvp_hp_rate != 100)
+ maxhp = maxhp * (double)battle_config.mvp_hp_rate / 100.;
+ } else { //Normal mob
+ if (battle_config.monster_hp_rate != 100)
+ maxhp = maxhp * (double)battle_config.monster_hp_rate / 100.;
+ }
+ mstatus->max_hp = (unsigned int)cap_value(maxhp, 1, UINT_MAX);
+ }
+ if (maxspUpdated) {
+ if(mstatus->max_sp < 1) mstatus->max_sp = 1;
+ }
//Since mobs always respawn with full life...
mstatus->hp = mstatus->max_hp;
mstatus->sp = mstatus->max_sp;
- // MVP Drops: MVP1id,MVP1per,MVP2id,MVP2per,MVP3id,MVP3per
- for(i = 0; i < MAX_MVP_DROP; i++) {
- int rate_adjust = battle_config.item_rate_mvp;;
- db->mvpitem[i].nameid = atoi(str[31+i*2]);
- if (!db->mvpitem[i].nameid) {
- db->mvpitem[i].p = 0; //No item....
- continue;
- }
- mob->item_dropratio_adjust(db->mvpitem[i].nameid, class_, &rate_adjust);
- db->mvpitem[i].p = mob->drop_adjust(atoi(str[32+i*2]), rate_adjust, battle_config.item_drop_mvp_min, battle_config.item_drop_mvp_max);
-
- //calculate and store Max available drop chance of the MVP item
- if (db->mvpitem[i].p) {
- struct item_data *id;
- id = itemdb->search(db->mvpitem[i].nameid);
- if (id->maxchance == -1 || (id->maxchance < db->mvpitem[i].p/10 + 1) ) {
- //item has bigger drop chance or sold in shops
- id->maxchance = db->mvpitem[i].p/10 + 1; //reduce MVP drop info to not spoil common drop rate
- }
+ if ((t = libconfig->setting_get_member(mobt, "MvpDrops"))) {
+ if (config_setting_is_group(t)) {
+ mob->read_db_mvpdrops_sub(entry, mstatus, class_, t);
}
}
- for(i = 0; i < MAX_MOB_DROP; i++) {
- int rate = 0, rate_adjust, type;
- unsigned short ratemin, ratemax;
- struct item_data *id;
- int k = 31 + MAX_MVP_DROP*2 + i*2;
- db->dropitem[i].nameid = atoi(str[k]);
- if (!db->dropitem[i].nameid) {
- db->dropitem[i].p = 0; //No drop.
- continue;
- }
- id = itemdb->search(db->dropitem[i].nameid);
- type = id->type;
- rate = atoi(str[k+1]);
- if( (class_ >= 1324 && class_ <= 1363) || (class_ >= 1938 && class_ <= 1946) ) {
- //Treasure box drop rates [Skotlex]
- rate_adjust = battle_config.item_rate_treasure;
- ratemin = battle_config.item_drop_treasure_min;
- ratemax = battle_config.item_drop_treasure_max;
- }
- else switch (type)
- { // Added support to restrict normal drops of MVP's [Reddozen]
- case IT_HEALING:
- rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_heal_boss : battle_config.item_rate_heal;
- ratemin = battle_config.item_drop_heal_min;
- ratemax = battle_config.item_drop_heal_max;
- break;
- case IT_USABLE:
- case IT_CASH:
- rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_use_boss : battle_config.item_rate_use;
- ratemin = battle_config.item_drop_use_min;
- ratemax = battle_config.item_drop_use_max;
- break;
- case IT_WEAPON:
- case IT_ARMOR:
- case IT_PETARMOR:
- rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_equip_boss : battle_config.item_rate_equip;
- ratemin = battle_config.item_drop_equip_min;
- ratemax = battle_config.item_drop_equip_max;
- break;
- case IT_CARD:
- rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_card_boss : battle_config.item_rate_card;
- ratemin = battle_config.item_drop_card_min;
- ratemax = battle_config.item_drop_card_max;
- break;
- default:
- rate_adjust = (mstatus->mode&MD_BOSS) ? battle_config.item_rate_common_boss : battle_config.item_rate_common;
- ratemin = battle_config.item_drop_common_min;
- ratemax = battle_config.item_drop_common_max;
- break;
- }
- mob->item_dropratio_adjust(id->nameid, class_, &rate_adjust);
- db->dropitem[i].p = mob->drop_adjust(rate, rate_adjust, ratemin, ratemax);
-
- //calculate and store Max available drop chance of the item
- if( db->dropitem[i].p && (class_ < 1324 || class_ > 1363) && (class_ < 1938 || class_ > 1946) )
- { //Skip treasure chests.
- if (id->maxchance == -1 || (id->maxchance < db->dropitem[i].p) ) {
- id->maxchance = db->dropitem[i].p; //item has bigger drop chance or sold in shops
- }
- for (k = 0; k< MAX_SEARCH; k++) {
- if (id->mob[k].chance <= db->dropitem[i].p)
- break;
- }
- if (k == MAX_SEARCH)
- continue;
-
- if (id->mob[k].id != class_ && k != MAX_SEARCH - 1)
- memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
- id->mob[k].chance = db->dropitem[i].p;
- id->mob[k].id = class_;
+ if ((t = libconfig->setting_get_member(mobt, "Drops"))) {
+ if (config_setting_is_group(t)) {
+ mob->read_db_drops_sub(entry, mstatus, class_, t);
}
}
+
+ mob->read_db_additional_fields(entry, class_, mobt, id, source);
// Finally insert monster's data into the database.
if (mob->db_data[class_] == NULL)
mob->db_data[class_] = (struct mob_db*)aMalloc(sizeof(struct mob_db));
else
//Copy over spawn data
- memcpy(&db->spawn, mob->db_data[class_]->spawn, sizeof(db->spawn));
+ memcpy(&entry->spawn, mob->db_data[class_]->spawn, sizeof(entry->spawn));
- memcpy(mob->db_data[class_], db, sizeof(struct mob_db));
+ memcpy(mob->db_data[class_], entry, sizeof(struct mob_db));
return true;
}
-/*==========================================
- * mob_db.txt reading
- *------------------------------------------*/
-bool mob_readdb_sub(char* fields[], int columns, int current) {
- return mob->parse_dbrow(fields);
+void mob_read_db_additional_fields(struct mob_db *entry, int class_, config_setting_t *it, int n, const char *source)
+{
+ // do nothing. plugins can do own work
}
-void mob_readdb(void) {
- const char* filename[] = {
- DBPATH"mob_db.txt",
- "mob_db2.txt" };
- int fi;
-
- for( fi = 0; fi < ARRAYLENGTH(filename); ++fi ) {
- if(fi > 0) {
- char filepath[256];
- sprintf(filepath, "%s/%s", map->db_path, filename[fi]);
- if(!exists(filepath)) {
- continue;
- }
+bool mob_lookup_const(const config_setting_t *it, const char *name, int *value)
+{
+ if (libconfig->setting_lookup_int(it, name, value))
+ {
+ return true;
+ }
+ else
+ {
+ const char *str = NULL;
+ if (libconfig->setting_lookup_string(it, name, &str))
+ {
+ if (*str && script->get_constant(str, value))
+ return true;
}
-
- sv->readdb(map->db_path, filename[fi], ',', 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP, 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP, -1, mob->readdb_sub);
}
- mob->name_constants();
+ return false;
}
-/*==========================================
- * mob_db table reading
- *------------------------------------------*/
-int mob_read_sqldb(void) {
- const char* mob_db_name[] = {
- map->mob_db_db,
- map->mob_db2_db
- };
- int fi;
-
- for( fi = 0; fi < ARRAYLENGTH(mob_db_name); ++fi ) {
- uint32 lines = 0, count = 0;
+bool mob_get_const(const config_setting_t *it, int *value)
+{
+ const char *str = config_setting_get_string(it);
+ if (str && *str && script->get_constant(str, value))
+ return true;
- // retrieve all rows from the mob database
- if( SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT * FROM `%s`", mob_db_name[fi]) ) {
- Sql_ShowDebug(map->mysql_handle);
- continue;
- }
+ *value = libconfig->setting_get_int(it);
+ return true;
+}
- // process rows one by one
- while( SQL_SUCCESS == SQL->NextRow(map->mysql_handle) ) {
- // wrap the result into a TXT-compatible format
- char line[1024];
- char* str[31+2*MAX_MVP_DROP+2*MAX_MOB_DROP];
- char* p;
- int i;
+/*==========================================
+ * mob_db.txt reading
+ *------------------------------------------*/
+void mob_readdb(void) {
+ const char* filename[] = {
+ DBPATH"mob_db.conf",
+ "mob_db2.conf" };
+ int i;
- lines++;
- for(i = 0, p = line; i < 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP; i++)
- {
- char* data;
- size_t len;
- SQL->GetData(map->mysql_handle, i, &data, &len);
+ for (i = 0; i < ARRAYLENGTH(filename); ++i) {
+ mob->read_libconfig(filename[i], i > 0 ? true : false);
+ }
+ mob->name_constants();
+}
- strcpy(p, data);
- str[i] = p;
- p+= len + 1;
- }
+int mob_read_libconfig(const char *filename, bool ignore_missing)
+{
+ config_t mob_db_conf;
+ char filepath[256];
+ config_setting_t *mdb;
+ config_setting_t *t;
+ int i = 0;
- if (!mob->parse_dbrow(str))
- continue;
+ nullpo_ret(filename);
+ sprintf(filepath, "%s/%s", map->db_path, filename);
- count++;
- }
+ if (ignore_missing && !exists(filepath))
+ return 0;
- // free the query result
- SQL->FreeResult(map->mysql_handle);
+ if (libconfig->read_file(&mob_db_conf, filepath) || !(mdb = libconfig->setting_get_member(mob_db_conf.root, "mob_db"))) {
+ ShowError("can't read %s\n", filepath);
+ return -1;
+ }
- ShowStatus("Done reading '"CL_WHITE"%"PRIu32""CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, mob_db_name[fi]);
+ while ((t = libconfig->setting_get_elem(mdb, i++))) {
+ mob->read_db_sub(t, i - 1, filepath);
}
- mob->name_constants();
+ libconfig->destroy(&mob_db_conf);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, filepath);
return 0;
}
@@ -4515,59 +4808,6 @@ void mob_readskilldb(void) {
}
}
-/**
- * mob_skill_db table reading [CalciumKid]
- * not overly sure if this is all correct
- * seems to work though...
- */
-int mob_read_sqlskilldb(void) {
- const char* mob_skill_db_name[] = {
- map->mob_skill_db_db,
- map->mob_skill_db2_db
- };
- int fi;
-
- if( battle_config.mob_skill_rate == 0 ) {
- ShowStatus("Mob skill use disabled. Not reading mob skills.\n");
- return 0;
- }
-
- for( fi = 0; fi < ARRAYLENGTH(mob_skill_db_name); ++fi ) {
- uint32 lines = 0, count = 0;
-
- // retrieve all rows from the mob skill database
- if( SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT * FROM `%s`", mob_skill_db_name[fi]) ) {
- Sql_ShowDebug(map->mysql_handle);
- continue;
- }
-
- // process rows one by one
- while( SQL_SUCCESS == SQL->NextRow(map->mysql_handle) ) {
- // wrap the result into a TXT-compatible format
- char* str[19];
- char* dummy = "";
- int i;
- ++lines;
- for( i = 0; i < 19; ++i )
- {
- SQL->GetData(map->mysql_handle, i, &str[i], NULL);
- if( str[i] == NULL ) str[i] = dummy; // get rid of NULL columns
- }
-
- if (!mob->parse_row_mobskilldb(str, 19, count))
- continue;
-
- count++;
- }
-
- // free the query result
- SQL->FreeResult(map->mysql_handle);
-
- ShowStatus("Done reading '"CL_WHITE"%"PRIu32""CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, mob_skill_db_name[fi]);
- }
- return 0;
-}
-
/*==========================================
* mob_race2_db.txt reading
*------------------------------------------*/
@@ -4630,15 +4870,8 @@ void mob_load(bool minimal) {
}
sv->readdb(map->db_path, "mob_item_ratio.txt", ',', 2, 2+MAX_ITEMRATIO_MOBS, -1, mob->readdb_itemratio); // must be read before mobdb
mob->readchatdb();
- if (map->db_use_sql_mob_db) {
- mob->read_sqldb();
- }
- if (map->db_use_sql_mob_skill_db) {
- mob->read_sqlskilldb();
- } else {
- mob->readdb();
- mob->readskilldb();
- }
+ mob->readdb();
+ mob->readskilldb();
sv->readdb(map->db_path, "mob_avail.txt", ',', 2, 12, -1, mob->readdb_mobavail);
mob->read_randommonster();
sv->readdb(map->db_path, DBPATH"mob_race2_db.txt", ',', 2, 20, -1, mob->readdb_race2);
@@ -4708,16 +4941,7 @@ int do_init_mob(bool minimal) {
void mob_destroy_mob_db(int index)
{
struct mob_db *data = mob->db_data[index];
- if (data->hdata) {
- int i;
- for (i = 0; i < data->hdatac; i++) {
- if (data->hdata[i]->flag.free ) {
- aFree(data->hdata[i]->data);
- }
- aFree(data->hdata[i]);
- }
- aFree(data->hdata);
- }
+ HPM->data_store_destroy(&data->hdata);
aFree(data);
mob->db_data[index] = NULL;
}
@@ -4856,10 +5080,16 @@ void mob_defaults(void) {
mob->clone_delete = mob_clone_delete;
mob->drop_adjust = mob_drop_adjust;
mob->item_dropratio_adjust = item_dropratio_adjust;
- mob->parse_dbrow = mob_parse_dbrow;
- mob->readdb_sub = mob_readdb_sub;
+ mob->lookup_const = mob_lookup_const;
+ mob->get_const = mob_get_const;
mob->readdb = mob_readdb;
- mob->read_sqldb = mob_read_sqldb;
+ mob->read_libconfig = mob_read_libconfig;
+ mob->read_db_additional_fields = mob_read_db_additional_fields;
+ mob->read_db_sub = mob_read_db_sub;
+ mob->read_db_drops_sub = mob_read_db_drops_sub;
+ mob->read_db_mvpdrops_sub = mob_read_db_mvpdrops_sub;
+ mob->read_db_mode_sub = mob_read_db_mode_sub;
+ mob->read_db_stats_sub = mob_read_db_stats_sub;
mob->name_constants = mob_name_constants;
mob->readdb_mobavail = mob_readdb_mobavail;
mob->read_randommonster = mob_read_randommonster;
@@ -4867,7 +5097,6 @@ void mob_defaults(void) {
mob->readchatdb = mob_readchatdb;
mob->parse_row_mobskilldb = mob_parse_row_mobskilldb;
mob->readskilldb = mob_readskilldb;
- mob->read_sqlskilldb = mob_read_sqlskilldb;
mob->readdb_race2 = mob_readdb_race2;
mob->readdb_itemratio = mob_readdb_itemratio;
mob->load = mob_load;
diff --git a/src/map/mob.h b/src/map/mob.h
index 4b8a054b5..f7e071261 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -11,6 +11,8 @@
#include "common/hercules.h"
#include "common/mmo.h" // struct item
+struct hplugin_data_store;
+
#define MAX_RANDOMMONSTER 5
// Change this to increase the table size in your mob_db to accommodate a larger mob database.
@@ -138,10 +140,7 @@ struct mob_db {
int maxskill;
struct mob_skill skill[MAX_MOBSKILL];
struct spawn_info spawn[10];
-
- /* HPM Custom Struct */
- struct HPluginData **hdata;
- unsigned int hdatac;
+ struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
struct mob_data {
@@ -208,14 +207,10 @@ struct mob_data {
* MvP Tombstone NPC ID
**/
int tomb_nid;
-
- /* HPM Custom Struct */
- struct HPluginData **hdata;
- unsigned int hdatac;
+ struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
-
enum {
MST_TARGET = 0,
MST_RANDOM, //Random Target!
@@ -368,10 +363,16 @@ struct mob_interface {
int (*clone_delete) (struct mob_data *md);
unsigned int (*drop_adjust) (int baserate, int rate_adjust, unsigned short rate_min, unsigned short rate_max);
void (*item_dropratio_adjust) (int nameid, int mob_id, int *rate_adjust);
- bool (*parse_dbrow) (char **str);
- bool (*readdb_sub) (char *fields[], int columns, int current);
void (*readdb) (void);
- int (*read_sqldb) (void);
+ bool (*lookup_const) (const config_setting_t *it, const char *name, int *value);
+ bool (*get_const) (const config_setting_t *it, int *value);
+ int (*read_libconfig) (const char *filename, bool ignore_missing);
+ void (*read_db_additional_fields) (struct mob_db *entry, int class_, config_setting_t *it, int n, const char *source);
+ bool (*read_db_sub) (config_setting_t *mobt, int id, const char *source);
+ void (*read_db_drops_sub) (struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t);
+ void (*read_db_mvpdrops_sub) (struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t);
+ int (*read_db_mode_sub) (struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t);
+ void (*read_db_stats_sub) (struct mob_db *entry, struct status_data *mstatus, int class_, config_setting_t *t);
void (*name_constants) (void);
bool (*readdb_mobavail) (char *str[], int columns, int current);
int (*read_randommonster) (void);
@@ -379,7 +380,6 @@ struct mob_interface {
void (*readchatdb) (void);
bool (*parse_row_mobskilldb) (char **str, int columns, int current);
void (*readskilldb) (void);
- int (*read_sqlskilldb) (void);
bool (*readdb_race2) (char *fields[], int columns, int current);
bool (*readdb_itemratio) (char *str[], int columns, int current);
void (*load) (bool minimal);
diff --git a/src/map/npc.c b/src/map/npc.c
index a0c14a058..7044fefcf 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -27,7 +27,7 @@
#include "common/cbasetypes.h"
#include "common/db.h"
#include "common/ers.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/showmsg.h"
#include "common/socket.h"
@@ -2321,16 +2321,7 @@ int npc_unload(struct npc_data* nd, bool single)
nd->ud = NULL;
}
- if (nd->hdata) {
- unsigned int i;
- for (i = 0; i < nd->hdatac; i++) {
- if (nd->hdata[i]->flag.free) {
- aFree(nd->hdata[i]->data);
- }
- aFree(nd->hdata[i]);
- }
- aFree(nd->hdata);
- }
+ HPM->data_store_destroy(&nd->hdata);
aFree(nd);
diff --git a/src/map/npc.h b/src/map/npc.h
index 14b89d128..bf3d1494d 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -11,7 +11,7 @@
#include "common/hercules.h"
#include "common/db.h"
-struct HPluginData;
+struct hplugin_data_store;
struct view_data;
enum npc_parse_options {
@@ -102,9 +102,7 @@ struct npc_data {
char killer_name[NAME_LENGTH];
} tomb;
} u;
- /* HPData Support for npc_data */
- struct HPluginData **hdata;
- unsigned int hdatac;
+ struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c
index 503dbd845..edcd755bc 100644
--- a/src/map/npc_chat.c
+++ b/src/map/npc_chat.c
@@ -11,7 +11,7 @@
#include "map/mob.h" // struct mob_data
#include "map/pc.h" // struct map_session_data
#include "map/script.h" // set_var()
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/showmsg.h"
#include "common/strlib.h"
diff --git a/src/map/party.c b/src/map/party.c
index db285a4b4..3a0b6d518 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -21,7 +21,7 @@
#include "map/status.h"
#include "common/HPM.h"
#include "common/cbasetypes.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
@@ -103,16 +103,7 @@ int party_db_final(DBKey key, DBData *data, va_list ap) {
if (p->instance)
aFree(p->instance);
- if (p->hdata) {
- int i;
- for (i = 0; i < p->hdatac; i++) {
- if (p->hdata[i]->flag.free) {
- aFree(p->hdata[i]->data);
- }
- aFree(p->hdata[i]);
- }
- aFree(p->hdata);
- }
+ HPM->data_store_destroy(&p->hdata);
}
return 0;
}
@@ -608,16 +599,8 @@ int party_broken(int party_id)
if( p->instance )
aFree(p->instance);
- if( p->hdata )
- {
- for( j = 0; j < p->hdatac; j++ ) {
- if( p->hdata[j]->flag.free ) {
- aFree(p->hdata[j]->data);
- }
- aFree(p->hdata[j]);
- }
- aFree(p->hdata);
- }
+ HPM->data_store_destroy(&p->hdata);
+
idb_remove(party->db,party_id);
return 0;
}
diff --git a/src/map/party.h b/src/map/party.h
index c7893add2..df7c03f05 100644
--- a/src/map/party.h
+++ b/src/map/party.h
@@ -15,7 +15,7 @@
#define PARTY_BOOKING_JOBS 6
#define PARTY_BOOKING_RESULTS 10
-struct HPluginData;
+struct hplugin_data_store;
struct party_member_data {
struct map_session_data *sd;
@@ -35,10 +35,7 @@ struct party_data {
unsigned snovice :1; ///< There's a Super Novice
unsigned tk : 1; ///< There's a taekwon
} state;
-
- /* HPM Custom Struct */
- struct HPluginData **hdata;
- unsigned int hdatac;
+ struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
#define PB_NOTICE_LENGTH (36 + 1)
diff --git a/src/map/path.c b/src/map/path.c
index a482fc473..6d9b48837 100644
--- a/src/map/path.c
+++ b/src/map/path.c
@@ -10,7 +10,7 @@
#include "map/map.h"
#include "common/cbasetypes.h"
#include "common/db.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
@@ -45,7 +45,7 @@ struct path_node {
};
/// Binary heap of path nodes
-BHEAP_STRUCT_DECL(node_heap, struct path_node*);
+BHEAP_STRUCT_DECL(node_heap, struct path_node *);
/// Comparator for binary heap of path nodes (minimum cost at top)
#define NODE_MINTOPCMP(i,j) ((i)->f_cost - (j)->f_cost)
diff --git a/src/map/pc.c b/src/map/pc.c
index dc7014701..4d4f41521 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -41,7 +41,7 @@
#include "common/conf.h"
#include "common/core.h" // get_svn_revision()
#include "common/HPM.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/mmo.h" // NAME_LENGTH, MAX_CARTS, NEW_CARTS
#include "common/nullpo.h"
#include "common/random.h"
@@ -2984,7 +2984,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
case 0: //Right hand
ARR_FIND(0, ARRAYLENGTH(sd->right_weapon.add_dmg), i, sd->right_weapon.add_dmg[i].rate == 0 || sd->right_weapon.add_dmg[i].class_ == type2);
if (i == ARRAYLENGTH(sd->right_weapon.add_dmg)) {
- ShowWarning("pc_bonus2: Reached max (%"PRIuS") number of add Class dmg bonuses per character!\n",
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n",
ARRAYLENGTH(sd->right_weapon.add_dmg));
break;
}
@@ -2998,7 +2998,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
case 1: //Left hand
ARR_FIND(0, ARRAYLENGTH(sd->left_weapon.add_dmg), i, sd->left_weapon.add_dmg[i].rate == 0 || sd->left_weapon.add_dmg[i].class_ == type2);
if (i == ARRAYLENGTH(sd->left_weapon.add_dmg)) {
- ShowWarning("pc_bonus2: Reached max (%"PRIuS") number of add Class dmg bonuses per character!\n",
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n",
ARRAYLENGTH(sd->left_weapon.add_dmg));
break;
}
@@ -3016,7 +3016,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
ARR_FIND(0, ARRAYLENGTH(sd->add_mdmg), i, sd->add_mdmg[i].rate == 0 || sd->add_mdmg[i].class_ == type2);
if (i == ARRAYLENGTH(sd->add_mdmg)) {
- ShowWarning("pc_bonus2: Reached max (%"PRIuS") number of add Class magic dmg bonuses per character!\n", ARRAYLENGTH(sd->add_mdmg));
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class magic dmg bonuses per character!\n", ARRAYLENGTH(sd->add_mdmg));
break;
}
sd->add_mdmg[i].class_ = type2;
@@ -3029,7 +3029,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
ARR_FIND(0, ARRAYLENGTH(sd->add_def), i, sd->add_def[i].rate == 0 || sd->add_def[i].class_ == type2);
if (i == ARRAYLENGTH(sd->add_def)) {
- ShowWarning("pc_bonus2: Reached max (%"PRIuS") number of add Class def bonuses per character!\n", ARRAYLENGTH(sd->add_def));
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class def bonuses per character!\n", ARRAYLENGTH(sd->add_def));
break;
}
sd->add_def[i].class_ = type2;
@@ -3042,7 +3042,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
ARR_FIND(0, ARRAYLENGTH(sd->add_mdef), i, sd->add_mdef[i].rate == 0 || sd->add_mdef[i].class_ == type2);
if (i == ARRAYLENGTH(sd->add_mdef)) {
- ShowWarning("pc_bonus2: Reached max (%"PRIuS") number of add Class mdef bonuses per character!\n", ARRAYLENGTH(sd->add_mdef));
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class mdef bonuses per character!\n", ARRAYLENGTH(sd->add_mdef));
break;
}
sd->add_mdef[i].class_ = type2;
@@ -3205,7 +3205,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id == 0 || sd->skillatk[i].id == type2);
if (i == ARRAYLENGTH(sd->skillatk)) {
//Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("script->run: bonus2 bSkillAtk reached it's limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 bSkillAtk reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
ARRAYLENGTH(sd->skillatk), type2, val);
break;
}
@@ -3222,7 +3222,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == 0 || sd->skillheal[i].id == type2);
if (i == ARRAYLENGTH(sd->skillheal)) {
// Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("script->run: bonus2 bSkillHeal reached it's limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 bSkillHeal reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
ARRAYLENGTH(sd->skillheal), type2, val);
break;
}
@@ -3239,7 +3239,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == 0 || sd->skillheal2[i].id == type2);
if (i == ARRAYLENGTH(sd->skillheal2)) {
// Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("script->run: bonus2 bSkillHeal2 reached it's limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 bSkillHeal2 reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
ARRAYLENGTH(sd->skillheal2), type2, val);
break;
}
@@ -3256,7 +3256,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
ARR_FIND(0, ARRAYLENGTH(sd->skillblown), i, sd->skillblown[i].id == 0 || sd->skillblown[i].id == type2);
if (i == ARRAYLENGTH(sd->skillblown)) {
//Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("script->run: bonus2 bSkillBlown reached it's limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 bSkillBlown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
ARRAYLENGTH(sd->skillblown), type2, val);
break;
}
@@ -3276,7 +3276,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
if (i == ARRAYLENGTH(sd->skillcast)) {
//Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("script->run: bonus2 %s reached its limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 %s reached its limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
type == SP_CASTRATE ? "bCastRate" : "bVariableCastrate",
ARRAYLENGTH(sd->skillcast), type2, val);
break;
@@ -3296,7 +3296,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
ARR_FIND(0, ARRAYLENGTH(sd->skillfixcastrate), i, sd->skillfixcastrate[i].id == 0 || sd->skillfixcastrate[i].id == type2);
if (i == ARRAYLENGTH(sd->skillfixcastrate)) {
- ShowDebug("script->run: bonus2 bFixedCastrate reached it's limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 bFixedCastrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
ARRAYLENGTH(sd->skillfixcastrate), type2, val);
break;
}
@@ -3347,7 +3347,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
//Standard item bonus.
for(i=0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid && sd->itemhealrate[i].nameid != type2; i++);
if (i == ARRAYLENGTH(sd->itemhealrate)) {
- ShowWarning("pc_bonus2: Reached max (%"PRIuS") number of item heal bonuses per character!\n", ARRAYLENGTH(sd->itemhealrate));
+ ShowWarning("pc_bonus2: Reached max (%d) number of item heal bonuses per character!\n", ARRAYLENGTH(sd->itemhealrate));
break;
}
sd->itemhealrate[i].nameid = type2;
@@ -3524,7 +3524,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
ARR_FIND(0, ARRAYLENGTH(sd->skillusesprate), i, sd->skillusesprate[i].id == 0 || sd->skillusesprate[i].id == type2);
if (i == ARRAYLENGTH(sd->skillusesprate)) {
- ShowDebug("script->run: bonus2 bSkillUseSPrate reached it's limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 bSkillUseSPrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
ARRAYLENGTH(sd->skillusesprate), type2, val);
break;
}
@@ -3540,7 +3540,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
ARR_FIND(0, ARRAYLENGTH(sd->skillcooldown), i, sd->skillcooldown[i].id == 0 || sd->skillcooldown[i].id == type2);
if (i == ARRAYLENGTH(sd->skillcooldown)) {
- ShowDebug("script->run: bonus2 bSkillCoolDown reached it's limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 bSkillCoolDown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
ARRAYLENGTH(sd->skillcooldown), type2, val);
break;
}
@@ -3556,7 +3556,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
ARR_FIND(0, ARRAYLENGTH(sd->skillfixcast), i, sd->skillfixcast[i].id == 0 || sd->skillfixcast[i].id == type2);
if (i == ARRAYLENGTH(sd->skillfixcast)) {
- ShowDebug("script->run: bonus2 bSkillFixedCast reached it's limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 bSkillFixedCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
ARRAYLENGTH(sd->skillfixcast), type2, val);
break;
}
@@ -3572,7 +3572,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
ARR_FIND(0, ARRAYLENGTH(sd->skillvarcast), i, sd->skillvarcast[i].id == 0 || sd->skillvarcast[i].id == type2);
if (i == ARRAYLENGTH(sd->skillvarcast)) {
- ShowDebug("script->run: bonus2 bSkillVariableCast reached it's limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 bSkillVariableCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
ARRAYLENGTH(sd->skillvarcast), type2, val);
break;
}
@@ -3589,7 +3589,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
if (i == ARRAYLENGTH(sd->skillcast)) {
- ShowDebug("script->run: bonus2 bVariableCastrate reached it's limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 bVariableCastrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
ARRAYLENGTH(sd->skillcast), type2, val);
break;
}
@@ -3606,7 +3606,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
ARR_FIND(0, ARRAYLENGTH(sd->skillusesp), i, sd->skillusesp[i].id == 0 || sd->skillusesp[i].id == type2);
if (i == ARRAYLENGTH(sd->skillusesp)) {
- ShowDebug("script->run: bonus2 bSkillUseSP reached it's limit (%"PRIuS" skills per character), bonus skill %d (+%d%%) lost.\n",
+ ShowDebug("script->run: bonus2 bSkillUseSP reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
ARRAYLENGTH(sd->skillusesp), type2, val);
break;
}
@@ -4112,7 +4112,10 @@ bool pc_can_insert_card(struct map_session_data* sd, int idx_card)
}
/*==========================================
- * Append a card to an item ?
+ * Attempt to insert card into item.
+ * Return:
+ * 0 = fail
+ * 1 = success
*------------------------------------------*/
int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
{
@@ -4143,6 +4146,7 @@ int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
sd->status.inventory[idx_equip].card[i] = nameid;
logs->pick_pc(sd, LOG_TYPE_OTHER, 1, &sd->status.inventory[idx_equip],sd->inventory_data[idx_equip]);
clif->insert_card(sd,idx_equip,idx_card,0);
+ return 1;
}
return 0;
@@ -11332,14 +11336,7 @@ void pc_autotrade_populate(struct map_session_data *sd) {
pc->autotrade_update(sd,PAUC_START);
- for(i = 0; i < data->hdatac; i++ ) {
- if( data->hdata[i]->flag.free ) {
- aFree(data->hdata[i]->data);
- }
- aFree(data->hdata[i]);
- }
- if( data->hdata )
- aFree(data->hdata);
+ HPM->data_store_destroy(&data->hdata);
idb_remove(pc->at_db, sd->status.char_id);
}
@@ -11349,16 +11346,7 @@ void pc_autotrade_populate(struct map_session_data *sd) {
*/
int pc_autotrade_final(DBKey key, DBData *data, va_list ap) {
struct autotrade_vending* at_v = DB->data2ptr(data);
- int i;
- for(i = 0; i < at_v->hdatac; i++ ) {
- if( at_v->hdata[i]->flag.free ) {
- aFree(at_v->hdata[i]->data);
- }
- aFree(at_v->hdata[i]);
- }
- if( at_v->hdata )
- aFree(at_v->hdata);
-
+ HPM->data_store_destroy(&at_v->hdata);
return 0;
}
diff --git a/src/map/pc.h b/src/map/pc.h
index e6e95978d..2c8b24acf 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -539,10 +539,7 @@ END_ZEROED_BLOCK;
unsigned short (*parse_cmd_func)(int fd, struct map_session_data *sd); ///< parse_cmd_func used by this player
unsigned char delayed_damage;//ref. counter bugreport:7307 [Ind/Hercules]
-
- /* HPM Custom Struct */
- struct HPluginData **hdata;
- unsigned int hdatac;
+ struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
/* expiration_time timer id */
int expiration_tid;
@@ -757,9 +754,7 @@ struct autotrade_vending {
struct item list[MAX_VENDING];
struct s_vending vending[MAX_VENDING];
unsigned char vend_num;
- /* HPM Custom Struct */
- struct HPluginData **hdata;
- unsigned int hdatac;
+ struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
/*=====================================
diff --git a/src/map/pc_groups.c b/src/map/pc_groups.c
index 7efcd7e26..f9633571c 100644
--- a/src/map/pc_groups.c
+++ b/src/map/pc_groups.c
@@ -13,7 +13,7 @@
#include "common/cbasetypes.h"
#include "common/conf.h"
#include "common/db.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/showmsg.h"
#include "common/strlib.h" // strcmp
diff --git a/src/map/pet.c b/src/map/pet.c
index 2865cc901..aed49df63 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -25,7 +25,7 @@
#include "map/unit.h"
#include "common/db.h"
#include "common/ers.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
diff --git a/src/map/quest.c b/src/map/quest.c
index fe4014ae5..790e96253 100644
--- a/src/map/quest.c
+++ b/src/map/quest.c
@@ -21,7 +21,7 @@
#include "map/unit.h"
#include "common/cbasetypes.h"
#include "common/conf.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
@@ -507,7 +507,7 @@ int quest_read_db(void)
const char *filename = "quest_db.conf";
sprintf(filepath, "%s/%s", map->db_path, filename);
- if (libconfig->read_file(&quest_db_conf, filepath) || !(qdb = libconfig->setting_get_member(quest_db_conf.root, filename))) {
+ if (libconfig->read_file(&quest_db_conf, filepath) || !(qdb = libconfig->setting_get_member(quest_db_conf.root, "quest_db"))) {
ShowError("can't read %s\n", filepath);
return -1;
}
diff --git a/src/map/script.c b/src/map/script.c
index face34d30..54d8d338d 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -39,7 +39,7 @@
#include "map/storage.h"
#include "map/unit.h"
#include "common/cbasetypes.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/md5calc.h"
#include "common/mmo.h" // NEW_CARTS
#include "common/nullpo.h"
@@ -2628,6 +2628,38 @@ TBL_PC *script_rid2sd(struct script_state *st) {
return sd;
}
+char *get_val_npcscope_str(struct script_state* st, struct reg_db *n, struct script_data* data) {
+ if (n)
+ return (char*)i64db_get(n->vars, reference_getuid(data));
+ else
+ return NULL;
+}
+
+char *get_val_instance_str(struct script_state* st, const char* name, struct script_data* data) {
+ if (st->instance_id >= 0) {
+ return (char*)i64db_get(instance->list[st->instance_id].regs.vars, reference_getuid(data));
+ } else {
+ ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to \"\"\n", name);
+ return NULL;
+ }
+}
+
+int get_val_npcscope_num(struct script_state* st, struct reg_db *n, struct script_data* data) {
+ if (n)
+ return (int)i64db_iget(n->vars, reference_getuid(data));
+ else
+ return 0;
+}
+
+int get_val_instance_num(struct script_state* st, const char* name, struct script_data* data) {
+ if (st->instance_id >= 0)
+ return (int)i64db_iget(instance->list[st->instance_id].regs.vars, reference_getuid(data));
+ else {
+ ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to 0\n", name);
+ return 0;
+ }
+}
+
/**
* Dereferences a variable/constant, replacing it with a copy of the value.
*
@@ -2681,24 +2713,15 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
data->u.str = pc_readaccountregstr(sd, data->u.num);// local
break;
case '.':
- {
- struct DBMap* n = data->ref ?
- data->ref->vars : name[1] == '@' ?
- st->stack->scope.vars : // instance/scope variable
- st->script->local.vars; // npc variable
- if( n )
- data->u.str = (char*)i64db_get(n,reference_getuid(data));
- else
- data->u.str = NULL;
- }
+ if (data->ref)
+ data->u.str = script->get_val_ref_str(st, data->ref, data);
+ else if (name[1] == '@')
+ data->u.str = script->get_val_scope_str(st, &st->stack->scope, data);
+ else
+ data->u.str = script->get_val_npc_str(st, &st->script->local, data);
break;
case '\'':
- if ( st->instance_id >= 0 ) {
- data->u.str = (char*)i64db_get(instance->list[st->instance_id].regs.vars, reference_getuid(data));
- } else {
- ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to \"\"\n", name);
- data->u.str = NULL;
- }
+ data->u.str = script->get_val_instance_str(st, name, data);
break;
default:
data->u.str = pc_readglobalreg_str(sd, data->u.num);
@@ -2736,24 +2759,15 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
data->u.num = pc_readaccountreg(sd, data->u.num);// local
break;
case '.':
- {
- struct DBMap* n = data->ref ?
- data->ref->vars : name[1] == '@' ?
- st->stack->scope.vars : // instance/scope variable
- st->script->local.vars; // npc variable
- if( n )
- data->u.num = (int)i64db_iget(n,reference_getuid(data));
- else
- data->u.num = 0;
- }
+ if (data->ref)
+ data->u.num = script->get_val_ref_num(st, data->ref, data);
+ else if (name[1] == '@')
+ data->u.num = script->get_val_scope_num(st, &st->stack->scope, data);
+ else
+ data->u.num = script->get_val_npc_num(st, &st->script->local, data);
break;
case '\'':
- if( st->instance_id >= 0 )
- data->u.num = (int)i64db_iget(instance->list[st->instance_id].regs.vars, reference_getuid(data));
- else {
- ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to 0\n", name);
- data->u.num = 0;
- }
+ data->u.num = script->get_val_instance_num(st, name, data);
break;
default:
data->u.num = pc_readglobalreg(sd, data->u.num);
@@ -2998,6 +3012,73 @@ void script_array_update(struct reg_db *src, int64 num, bool empty) {
}
}
+void set_reg_npcscope_str(struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str)
+{
+ if (n)
+ {
+ if (str[0]) {
+ i64db_put(n->vars, num, aStrdup(str));
+ if (script_getvaridx(num))
+ script->array_update(n, num, false);
+ } else {
+ i64db_remove(n->vars, num);
+ if (script_getvaridx(num))
+ script->array_update(n, num, true);
+ }
+ }
+}
+
+void set_reg_npcscope_num(struct script_state* st, struct reg_db *n, int64 num, const char* name, int val)
+{
+ if (n) {
+ if (val != 0) {
+ i64db_iput(n->vars, num, val);
+ if (script_getvaridx(num))
+ script->array_update(n, num, false);
+ } else {
+ i64db_remove(n->vars, num);
+ if (script_getvaridx(num))
+ script->array_update(n, num, true);
+ }
+ }
+}
+
+void set_reg_instance_str(struct script_state* st, int64 num, const char* name, const char *str)
+{
+ if (st->instance_id >= 0) {
+ if (str[0]) {
+ i64db_put(instance->list[st->instance_id].regs.vars, num, aStrdup(str));
+ if (script_getvaridx(num))
+ script->array_update(&instance->list[st->instance_id].regs, num, false);
+ } else {
+ i64db_remove(instance->list[st->instance_id].regs.vars, num);
+ if (script_getvaridx(num))
+ script->array_update(&instance->list[st->instance_id].regs, num, true);
+ }
+ } else {
+ ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name);
+ script->reportsrc(st);
+ }
+}
+
+void set_reg_instance_num(struct script_state* st, int64 num, const char* name, int val)
+{
+ if (st->instance_id >= 0) {
+ if (val != 0) {
+ i64db_iput(instance->list[st->instance_id].regs.vars, num, val);
+ if (script_getvaridx(num))
+ script->array_update(&instance->list[st->instance_id].regs, num, false);
+ } else {
+ i64db_remove(instance->list[st->instance_id].regs.vars, num);
+ if (script_getvaridx(num))
+ script->array_update(&instance->list[st->instance_id].regs, num, true);
+ }
+ } else {
+ ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name);
+ script->reportsrc(st);
+ }
+}
+
/**
* Stores the value of a script variable
*
@@ -3029,36 +3110,15 @@ int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, co
pc_setaccountreg2str(sd, num, str) :
pc_setaccountregstr(sd, num, str);
case '.':
- {
- struct reg_db *n = (ref) ? ref : (name[1] == '@') ? &st->stack->scope : &st->script->local;
- if( n ) {
- if (str[0]) {
- i64db_put(n->vars, num, aStrdup(str));
- if( script_getvaridx(num) )
- script->array_update(n, num, false);
- } else {
- i64db_remove(n->vars, num);
- if( script_getvaridx(num) )
- script->array_update(n, num, true);
- }
- }
- }
+ if (ref)
+ script->set_reg_ref_str(st, ref, num, name, str);
+ else if (name[1] == '@')
+ script->set_reg_scope_str(st, &st->stack->scope, num, name, str);
+ else
+ script->set_reg_npc_str(st, &st->script->local, num, name, str);
return 1;
case '\'':
- if( st->instance_id >= 0 ) {
- if( str[0] ) {
- i64db_put(instance->list[st->instance_id].regs.vars, num, aStrdup(str));
- if( script_getvaridx(num) )
- script->array_update(&instance->list[st->instance_id].regs, num, false);
- } else {
- i64db_remove(instance->list[st->instance_id].regs.vars, num);
- if( script_getvaridx(num) )
- script->array_update(&instance->list[st->instance_id].regs, num, true);
- }
- } else {
- ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name);
- script->reportsrc(st);
- }
+ set_reg_instance_str(st, num, name, str);
return 1;
default:
return pc_setglobalreg_str(sd, num, str);
@@ -3095,36 +3155,15 @@ int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, co
pc_setaccountreg2(sd, num, val) :
pc_setaccountreg(sd, num, val);
case '.':
- {
- struct reg_db *n = (ref) ? ref : (name[1] == '@') ? &st->stack->scope : &st->script->local;
- if( n ) {
- if( val != 0 ) {
- i64db_iput(n->vars, num, val);
- if( script_getvaridx(num) )
- script->array_update(n, num, false);
- } else {
- i64db_remove(n->vars, num);
- if( script_getvaridx(num) )
- script->array_update(n, num, true);
- }
- }
- }
+ if (ref)
+ script->set_reg_ref_num(st, ref, num, name, val);
+ else if (name[1] == '@')
+ script->set_reg_scope_num(st, &st->stack->scope, num, name, val);
+ else
+ script->set_reg_npc_num(st, &st->script->local, num, name, val);
return 1;
case '\'':
- if( st->instance_id >= 0 ) {
- if( val != 0 ) {
- i64db_iput(instance->list[st->instance_id].regs.vars, num, val);
- if( script_getvaridx(num) )
- script->array_update(&instance->list[st->instance_id].regs, num, false);
- } else {
- i64db_remove(instance->list[st->instance_id].regs.vars, num);
- if( script_getvaridx(num) )
- script->array_update(&instance->list[st->instance_id].regs, num, true);
- }
- } else {
- ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name);
- script->reportsrc(st);
- }
+ set_reg_instance_num(st, num, name, val);
return 1;
default:
return pc_setglobalreg(sd, num, val);
@@ -20613,6 +20652,14 @@ void script_defaults(void) {
script->push_val = push_val;
script->get_val = get_val;
script->get_val2 = get_val2;
+ script->get_val_ref_str = get_val_npcscope_str;
+ script->get_val_scope_str = get_val_npcscope_str;
+ script->get_val_npc_str = get_val_npcscope_str;
+ script->get_val_instance_str = get_val_instance_str;
+ script->get_val_ref_num = get_val_npcscope_num;
+ script->get_val_scope_num = get_val_npcscope_num;
+ script->get_val_npc_num = get_val_npcscope_num;
+ script->get_val_instance_num = get_val_instance_num;
script->push_str = push_str;
script->push_copy = push_copy;
script->pop_stack = pop_stack;
@@ -20679,6 +20726,15 @@ void script_defaults(void) {
script->print_line = script_print_line;
script->errorwarning_sub = script_errorwarning_sub;
script->set_reg = set_reg;
+ script->set_reg_ref_str = set_reg_npcscope_str;
+ script->set_reg_scope_str = set_reg_npcscope_str;
+ script->set_reg_npc_str = set_reg_npcscope_str;
+ script->set_reg_instance_str = set_reg_instance_str;
+ script->set_reg_ref_num = set_reg_npcscope_num;
+ script->set_reg_scope_num = set_reg_npcscope_num;
+ script->set_reg_npc_num = set_reg_npcscope_num;
+ script->set_reg_instance_num = set_reg_instance_num;
+
script->stack_expand = stack_expand;
script->push_retinfo = push_retinfo;
script->op_3 = op_3;
diff --git a/src/map/script.h b/src/map/script.h
index ad8ae82cb..ff660dec8 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -629,6 +629,14 @@ struct script_interface {
void (*detach_rid) (struct script_state* st);
struct script_data* (*push_val)(struct script_stack* stack, enum c_op type, int64 val, struct reg_db *ref);
struct script_data *(*get_val) (struct script_state* st, struct script_data* data);
+ char* (*get_val_ref_str) (struct script_state* st, struct reg_db *n, struct script_data* data);
+ char* (*get_val_scope_str) (struct script_state* st, struct reg_db *n, struct script_data* data);
+ char* (*get_val_npc_str) (struct script_state* st, struct reg_db *n, struct script_data* data);
+ char* (*get_val_instance_str) (struct script_state* st, const char* name, struct script_data* data);
+ int (*get_val_ref_num) (struct script_state* st, struct reg_db *n, struct script_data* data);
+ int (*get_val_scope_num) (struct script_state* st, struct reg_db *n, struct script_data* data);
+ int (*get_val_npc_num) (struct script_state* st, struct reg_db *n, struct script_data* data);
+ int (*get_val_instance_num) (struct script_state* st, const char* name, struct script_data* data);
void* (*get_val2) (struct script_state* st, int64 uid, struct reg_db *ref);
struct script_data* (*push_str) (struct script_stack* stack, enum c_op type, char* str);
struct script_data* (*push_copy) (struct script_stack* stack, int pos);
@@ -696,6 +704,14 @@ struct script_interface {
const char* (*print_line) (StringBuf *buf, const char *p, const char *mark, int line);
void (*errorwarning_sub) (StringBuf *buf, const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos);
int (*set_reg) (struct script_state *st, TBL_PC *sd, int64 num, const char *name, const void *value, struct reg_db *ref);
+ void (*set_reg_ref_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str);
+ void (*set_reg_scope_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str);
+ void (*set_reg_npc_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str);
+ void (*set_reg_instance_str) (struct script_state* st, int64 num, const char* name, const char *str);
+ void (*set_reg_ref_num) (struct script_state* st, struct reg_db *n, int64 num, const char* name, int val);
+ void (*set_reg_scope_num) (struct script_state* st, struct reg_db *n, int64 num, const char* name, int val);
+ void (*set_reg_npc_num) (struct script_state* st, struct reg_db *n, int64 num, const char* name, int val);
+ void (*set_reg_instance_num) (struct script_state* st, int64 num, const char* name, int val);
void (*stack_expand) (struct script_stack *stack);
struct script_data* (*push_retinfo) (struct script_stack *stack, struct script_retinfo *ri, struct reg_db *ref);
void (*op_3) (struct script_state *st, int op);
diff --git a/src/map/searchstore.c b/src/map/searchstore.c
index 46b102ad5..cdcf51b0e 100644
--- a/src/map/searchstore.c
+++ b/src/map/searchstore.c
@@ -10,7 +10,7 @@
#include "map/clif.h" // clif-"open_search_store_info, clif-"search_store_info_*
#include "map/pc.h" // struct map_session_data
#include "common/cbasetypes.h"
-#include "common/malloc.h" // aMalloc, aRealloc, aFree
+#include "common/memmgr.h" // aMalloc, aRealloc, aFree
#include "common/showmsg.h" // ShowError, ShowWarning
#include "common/strlib.h" // safestrncpy
diff --git a/src/map/skill.c b/src/map/skill.c
index a9ebf6998..cdf1c031f 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -31,7 +31,7 @@
#include "map/unit.h"
#include "common/cbasetypes.h"
#include "common/ers.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
diff --git a/src/map/status.c b/src/map/status.c
index 3ba80e531..7a7a4f415 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -28,13 +28,14 @@
#include "map/vending.h"
#include "common/cbasetypes.h"
#include "common/ers.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
#include "common/strlib.h"
#include "common/timer.h"
#include "common/utils.h"
+#include "common/conf.h"
#include <math.h>
#include <memory.h>
@@ -8960,6 +8961,9 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
{
int hp = status_get_hp(bl), sp = status_get_sp(bl), lv = 5;
+ if (sp < 1) sp = 1;
+ if (hp < 1) hp = 1;
+
if( rnd()%100 > (25 + 10 * val1) - status_get_int(bl) / 2)
return 0;
@@ -12263,38 +12267,136 @@ bool status_readdb_sizefix(char* fields[], int columns, int current)
return true;
}
-bool status_readdb_refine(char* fields[], int columns, int current)
+/**
+ * Processes a refine_db.conf entry.
+ *
+ * @param *r Libconfig setting entry. It is expected to be valid and it
+ * won't be freed (it is care of the caller to do so if
+ * necessary)
+ * @param n Ordinal number of the entry, to be displayed in case of
+ * validation errors.
+ * @param *source Source of the entry (file name), to be displayed in case of
+ * validation errors.
+ * @return # of the validated entry, or 0 in case of failure.
+ */
+int status_readdb_refine_libconfig_sub(config_setting_t *r, const char *name, const char *source)
{
- int i, bonus_per_level, random_bonus, random_bonus_start_level;
-
- current = atoi(fields[0]);
-
- if (current < 0 || current >= REFINE_TYPE_MAX)
- return false;
-
- bonus_per_level = atoi(fields[1]);
- random_bonus_start_level = atoi(fields[2]);
- random_bonus = atoi(fields[3]);
-
- for(i = 0; i < MAX_REFINE; i++)
- {
- char* delim;
-
- if (!(delim = strchr(fields[4+i], ':')))
- return false;
-
- *delim = '\0';
-
- status->dbs->refine_info[current].chance[i] = atoi(fields[4+i]);
+ config_setting_t *rate = NULL;
+ int type = REFINE_TYPE_ARMOR, bonus_per_level = 0, rnd_bonus_v = 0, rnd_bonus_lv = 0;
+ char lv[4];
+ nullpo_ret(r);
+ nullpo_ret(name);
+ nullpo_ret(source);
+
+ if (strncmp(name, "Armors", 6) == 0) {
+ type = REFINE_TYPE_ARMOR;
+ } else if (strncmp(name, "WeaponLevel", 11) != 0 || !strspn(&name[strlen(name)-1], "0123456789") || (type = atoi(strncpy(lv, name+11, 2))) == REFINE_TYPE_ARMOR) {
+ ShowError("status_readdb_refine_libconfig_sub: Invalid key name for entry '%s' in \"%s\", skipping.\n", name, source);
+ return 0;
+ }
+ if (type < REFINE_TYPE_ARMOR || type >= REFINE_TYPE_MAX) {
+ ShowError("status_readdb_refine_libconfig_sub: Out of range level for entry '%s' in \"%s\", skipping.\n", name, source);
+ return 0;
+ }
+ if (!libconfig->setting_lookup_int(r, "StatsPerLevel", &bonus_per_level)) {
+ ShowWarning("status_readdb_refine_libconfig_sub: Missing StatsPerLevel for entry '%s' in \"%s\", skipping.\n", name, source);
+ return 0;
+ }
+ if (!libconfig->setting_lookup_int(r, "RandomBonusStartLevel", &rnd_bonus_lv)) {
+ ShowWarning("status_readdb_refine_libconfig_sub: Missing RandomBonusStartLevel for entry '%s' in \"%s\", skipping.\n", name, source);
+ return 0;
+ }
+ if (!libconfig->setting_lookup_int(r, "RandomBonusValue", &rnd_bonus_v)) {
+ ShowWarning("status_readdb_refine_libconfig_sub: Missing RandomBonusValue for entry '%s' in \"%s\", skipping.\n", name, source);
+ return 0;
+ }
- if (i >= random_bonus_start_level - 1)
- status->dbs->refine_info[current].randombonus_max[i] = random_bonus * (i - random_bonus_start_level + 2);
+ if ((rate=libconfig->setting_get_member(r, "Rates")) != NULL && config_setting_is_group(rate)) {
+ config_setting_t *t = NULL;
+ bool duplicate[MAX_REFINE];
+ int bonus[MAX_REFINE], rnd_bonus[MAX_REFINE], chance[MAX_REFINE];
+ int i;
+ memset(&duplicate, 0, sizeof(duplicate));
+ memset(&bonus, 0, sizeof(bonus));
+ memset(&rnd_bonus, 0, sizeof(rnd_bonus));
+
+ for (i = 0; i < MAX_REFINE; i++) {
+ chance[i] = 100;
+ }
+ i = 0;
+ while ((t = libconfig->setting_get_elem(rate,i++)) != NULL && config_setting_is_group(t)) {
+ int level = 0, i32;
+ char *rlvl = config_setting_name(t);
+ memset(&lv, 0, sizeof(lv));
+ if (!strspn(&rlvl[strlen(rlvl)-1], "0123456789") || (level = atoi(strncpy(lv, rlvl+2, 3))) <= 0) {
+ ShowError("status_readdb_refine_libconfig_sub: Invalid refine level format '%s' for entry %s in \"%s\"... skipping.\n", rlvl, name, source);
+ continue;
+ }
+ if (level <= 0 || level > MAX_REFINE) {
+ ShowError("status_readdb_refine_libconfig_sub: Out of range refine level '%s' for entry %s in \"%s\"... skipping.\n", rlvl, name, source);
+ continue;
+ }
+ level--;
+ if (duplicate[level]) {
+ ShowWarning("status_readdb_refine_libconfig_sub: duplicate rate '%s' for entry %s in \"%s\", overwriting previous entry...\n", rlvl, name, source);
+ } else {
+ duplicate[level] = true;
+ }
+ if (libconfig->setting_lookup_int(t, "Chance", &i32))
+ chance[level] = i32;
+ else
+ chance[level] = 100;
+ if (libconfig->setting_lookup_int(t, "Bonus", &i32))
+ bonus[level] += i32;
+ if (level >= rnd_bonus_lv - 1)
+ rnd_bonus[level] = rnd_bonus_v * (level - rnd_bonus_lv + 2);
+ }
+ for (i = 0; i < MAX_REFINE; i++) {
+ status->dbs->refine_info[type].chance[i] = chance[i];
+ status->dbs->refine_info[type].randombonus_max[i] = rnd_bonus[i];
+ bonus[i] += bonus_per_level + (i > 0 ? bonus[i-1] : 0);
+ status->dbs->refine_info[type].bonus[i] = bonus[i];
+ }
+ } else {
+ ShowWarning("status_readdb_refine_libconfig_sub: Missing refine rates for entry '%s' in \"%s\", skipping.\n", name, source);
+ return 0;
+ }
+ return type+1;
+}
- status->dbs->refine_info[current].bonus[i] = bonus_per_level + atoi(delim+1);
- if (i > 0)
- status->dbs->refine_info[current].bonus[i] += status->dbs->refine_info[current].bonus[i-1];
+/**
+ * Reads from a libconfig-formatted refine_db.conf file.
+ *
+ * @param *filename File name, relative to the database path.
+ * @return The number of found entries.
+ */
+int status_readdb_refine_libconfig(const char *filename) {
+ bool duplicate[REFINE_TYPE_MAX];
+ config_t refine_db_conf;
+ config_setting_t *r;
+ char filepath[256];
+ int i = 0, count = 0,type = 0;
+
+ sprintf(filepath, "%s/%s", map->db_path, filename);
+ memset(&duplicate,0,sizeof(duplicate));
+ if( libconfig->read_file(&refine_db_conf, filepath) ) {
+ ShowError("can't read %s\n", filepath);
+ return 0;
}
- return true;
+
+ while((r = libconfig->setting_get_elem(refine_db_conf.root,i++))) {
+ char *name = config_setting_name(r);
+ if((type=status->readdb_refine_libconfig_sub(r, name, filename))) {
+ if( duplicate[type-1] ) {
+ ShowWarning("status_readdb_refine_libconfig: duplicate entry for %s in \"%s\", overwriting previous entry...\n", name, filename);
+ } else duplicate[type-1] = true;
+ count++;
+ }
+ }
+ libconfig->destroy(&refine_db_conf);
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename);
+
+ return count;
}
bool status_readdb_scconfig(char* fields[], int columns, int current) {
@@ -12357,7 +12459,7 @@ int status_readdb(void)
//
sv->readdb(map->db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, status->readdb_job2);
sv->readdb(map->db_path, DBPATH"size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(status->dbs->atkmods), status->readdb_sizefix);
- sv->readdb(map->db_path, DBPATH"refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(status->dbs->refine_info), status->readdb_refine);
+ status->readdb_refine_libconfig(DBPATH"refine_db.conf");
sv->readdb(map->db_path, "sc_config.txt", ',', 2, 2, SC_MAX, status->readdb_scconfig);
status->read_job_db();
@@ -12532,7 +12634,8 @@ void status_defaults(void) {
status->natural_heal_timer = status_natural_heal_timer;
status->readdb_job2 = status_readdb_job2;
status->readdb_sizefix = status_readdb_sizefix;
- status->readdb_refine = status_readdb_refine;
+ status->readdb_refine_libconfig = status_readdb_refine_libconfig;
+ status->readdb_refine_libconfig_sub = status_readdb_refine_libconfig_sub;
status->readdb_scconfig = status_readdb_scconfig;
status->read_job_db = status_read_job_db;
status->read_job_db_sub = status_read_job_db_sub;
diff --git a/src/map/status.h b/src/map/status.h
index 274c64c5b..d49bca8b4 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -2077,7 +2077,8 @@ struct status_interface {
int (*natural_heal_timer) (int tid, int64 tick, int id, intptr_t data);
bool (*readdb_job2) (char *fields[], int columns, int current);
bool (*readdb_sizefix) (char *fields[], int columns, int current);
- bool (*readdb_refine) (char *fields[], int columns, int current);
+ int (*readdb_refine_libconfig) (const char *filename);
+ int (*readdb_refine_libconfig_sub) (config_setting_t *r, const char *name, const char *source);
bool (*readdb_scconfig) (char *fields[], int columns, int current);
void (*read_job_db) (void);
void (*read_job_db_sub) (int idx, const char *name, config_setting_t *jdb);
diff --git a/src/map/storage.c b/src/map/storage.c
index fb6e2ed45..29f44f5e7 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -18,7 +18,7 @@
#include "map/pc.h"
#include "common/cbasetypes.h"
#include "common/db.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include <stdio.h>
diff --git a/src/map/unit.c b/src/map/unit.c
index 04a8befc2..7c253c5c2 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -34,7 +34,7 @@
#include "map/vending.h"
#include "common/HPM.h"
#include "common/db.h"
-#include "common/malloc.h"
+#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
#include "common/showmsg.h"
@@ -2654,17 +2654,7 @@ int unit_free(struct block_list *bl, clr_type clrtype) {
sd->quest_log = NULL;
sd->num_quests = sd->avail_quests = 0;
}
-
- if (sd->hdata) {
- unsigned int k;
- for( k = 0; k < sd->hdatac; k++ ) {
- if( sd->hdata[k]->flag.free ) {
- aFree(sd->hdata[k]->data);
- }
- aFree(sd->hdata[k]);
- }
- aFree(sd->hdata);
- }
+ HPM->data_store_destroy(&sd->hdata);
break;
}
case BL_PET:
@@ -2775,17 +2765,7 @@ int unit_free(struct block_list *bl, clr_type clrtype) {
if( md->tomb_nid )
mob->mvptomb_destroy(md);
- if (md->hdata)
- {
- unsigned int k;
- for (k = 0; k < md->hdatac; k++) {
- if( md->hdata[k]->flag.free ) {
- aFree(md->hdata[k]->data);
- }
- aFree(md->hdata[k]);
- }
- aFree(md->hdata);
- }
+ HPM->data_store_destroy(&md->hdata);
break;
}
case BL_HOM: