Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/map/itemdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ struct hplugin_data_store;
#define MAX_ITEM_GRADE 7
#endif

#ifndef MAX_ITEMRATIO_MOBS
#define MAX_ITEMRATIO_MOBS 10
#endif

enum item_itemid {
ITEMID_RED_POTION = 501,
ITEMID_YELLOW_POTION = 503,
Expand Down Expand Up @@ -572,6 +576,8 @@ struct item_data {
unsigned short chance;
int id;
} mob[MAX_SEARCH]; ///< Holds the mobs that have the highest drop rate for this item. [Skotlex]
int drop_ratio; ///< Drop ratio for item-specific drop modifiers.
int mob_id[MAX_ITEMRATIO_MOBS]; ///< Mob IDs for which the drop ratio applies.
struct script_code *script; ///< Default script for everything.
struct script_code *equip_script; ///< Script executed once when equipping.
struct script_code *unequip_script; ///< Script executed once when unequipping.
Expand Down
112 changes: 23 additions & 89 deletions src/map/mob.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,6 @@ struct mob_interface *mob;
#define MAX_MINCHASE 30 //Max minimum chase value to use for mobs.
#define RUDE_ATTACKED_COUNT 2 //After how many rude-attacks should the skill be used?

//Dynamic item drop ratio database for per-item drop ratio modifiers overriding global drop ratios.
#define MAX_ITEMRATIO_MOBS 10
struct item_drop_ratio {
int drop_ratio;
int mob_id[MAX_ITEMRATIO_MOBS];
};
static struct item_drop_ratio *item_drop_ratio_db[MAX_ITEMDB];
static struct DBMap *item_drop_ratio_other_db = NULL;

static struct eri *item_drop_ers; //For loot drops delay structures.
static struct eri *item_drop_list_ers;

Expand Down Expand Up @@ -4211,27 +4202,7 @@ static unsigned int mob_drop_adjust(int baserate, int rate_adjust, unsigned shor
return (unsigned int)cap_value(rate,rate_min,rate_max);
}

static struct item_drop_ratio *mob_get_item_drop_ratio(int nameid)
{
Assert_retr(NULL, nameid > 0);
if (nameid < ARRAYLENGTH(item_drop_ratio_db)) {
return item_drop_ratio_db[nameid];
} else {
return (struct item_drop_ratio *)idb_get(item_drop_ratio_other_db, nameid);
}
}

static void mob_set_item_drop_ratio(int nameid, struct item_drop_ratio *ratio)
{
Assert_retv(nameid > 0);
if (nameid < ARRAYLENGTH(item_drop_ratio_db)) {
Assert_retv(item_drop_ratio_db[nameid] == NULL);
item_drop_ratio_db[nameid] = ratio;
} else {
Assert_retv(idb_get(item_drop_ratio_other_db, nameid) == NULL);
idb_put(item_drop_ratio_other_db, nameid, ratio);
}
}

/**
* Check if global item drop rate is overridden for given item
Expand All @@ -4242,19 +4213,24 @@ static void mob_set_item_drop_ratio(int nameid, struct item_drop_ratio *ratio)
*/
static void item_dropratio_adjust(int nameid, int mob_id, int *rate_adjust)
{
struct item_drop_ratio *dropRatio;
nullpo_retv(rate_adjust);

dropRatio = mob->get_item_drop_ratio(nameid);
if (dropRatio) {
if (dropRatio->mob_id[0] ) { // only for listed mobs
int i;
ARR_FIND(0, MAX_ITEMRATIO_MOBS, i, dropRatio->mob_id[i] == mob_id);
if (i < MAX_ITEMRATIO_MOBS) // found
*rate_adjust = dropRatio->drop_ratio;
struct item_data *item = itemdb->search(nameid);
if (item == NULL || item->drop_ratio == 0) {
*rate_adjust = 100; // Default to 100% if no custom ratio
return;
}
// Check if mob_id is in the mob_id array
int i;
for (i = 0; i < MAX_ITEMRATIO_MOBS && item->mob_id[i] != 0; i++) {
if (item->mob_id[i] == mob_id) {
*rate_adjust = item->drop_ratio;
return;
}
else // for all mobs
*rate_adjust = dropRatio->drop_ratio;
}
// If mob_id not found or mob_id[0] is 0 (all mobs), use drop_ratio
if (item->mob_id[0] == 0 || i == MAX_ITEMRATIO_MOBS) {
*rate_adjust = item->drop_ratio;
} else {
*rate_adjust = 100; // Default if mob not listed
}
}

Expand Down Expand Up @@ -5945,28 +5921,22 @@ static bool mob_readdb_race2(char *fields[], int columns, int current)
static bool mob_readdb_itemratio(char *str[], int columns, int current)
{
int nameid, ratio, i;
struct item_drop_ratio *dropRatio;
struct item_data *item;

nullpo_retr(false, str);
nameid = atoi(str[0]);

if( itemdb->exists(nameid) == NULL )
{
item = itemdb->search(nameid);
if (item == NULL) {
ShowWarning("itemdb_read_itemratio: Invalid item id %d.\n", nameid);
return false;
}

ratio = atoi(str[1]);
item->drop_ratio = ratio;

dropRatio = mob->get_item_drop_ratio(nameid);
if (dropRatio == NULL) {
dropRatio = (struct item_drop_ratio*)aCalloc(1, sizeof(struct item_drop_ratio));
mob->set_item_drop_ratio(nameid, dropRatio);
}

dropRatio->drop_ratio = ratio;
for (i = 0; i < columns - 2; i++)
dropRatio->mob_id[i] = atoi(str[i + 2]);
for (i = 0; i < columns - 2 && i < MAX_ITEMRATIO_MOBS; i++)
item->mob_id[i] = atoi(str[i + 2]);

return true;
}
Expand All @@ -5992,18 +5962,6 @@ static void mob_load(bool minimal)
sv->readdb(map->db_path, DBPATH"mob_race2_db.txt", ',', 2, 20, -1, mob->readdb_race2);
}

/**
* @see DBApply
*/
static int mob_final_ratio_sub(union DBKey key, struct DBData *data, va_list ap)
{
struct item_drop_ratio *ratio = DB->data2ptr(data);

if (ratio)
aFree(ratio);

return 0;
}

static int mob_reload_sub_mob(struct mob_data *md, va_list args)
{
Expand Down Expand Up @@ -6039,17 +5997,9 @@ static void mob_reload(void)
mob->db_data[i]->maxskill=0;
}

// Clear item_drop_ratio_db
for (i = 0; i < MAX_ITEMDB; i++) {
if (item_drop_ratio_db[i]) {
aFree(item_drop_ratio_db[i]);
item_drop_ratio_db[i] = NULL;
}
}
for (i = 0; i < MOBG_MAX_GROUP; i++) {
VECTOR_CLEAR(mob->mob_groups[i]);
}
mob->item_drop_ratio_other_db->clear(mob->item_drop_ratio_other_db, mob->final_ratio_sub);

mob->destroy_drop_groups();

Expand Down Expand Up @@ -6152,19 +6102,9 @@ static int do_final_mob(void)
mob->chat_db[i] = NULL;
}
}
for (i = 0; i < MAX_ITEMDB; i++)
{
if (item_drop_ratio_db[i] != NULL)
{
aFree(item_drop_ratio_db[i]);
item_drop_ratio_db[i] = NULL;
}
}
for (i = 0; i < MOBG_MAX_GROUP; i++) {
VECTOR_CLEAR(mob->mob_groups[i]);
}
mob->item_drop_ratio_other_db->clear(mob->item_drop_ratio_other_db, mob->final_ratio_sub);
db_destroy(mob->item_drop_ratio_other_db);
ers_destroy(item_drop_ers);
ers_destroy(item_drop_list_ers);
return 0;
Expand Down Expand Up @@ -6208,9 +6148,6 @@ void mob_defaults(void)
memcpy(mob->splendide, mob_splendide, sizeof(mob->splendide));
memcpy(mob->mora, mob_mora, sizeof(mob->mora));

item_drop_ratio_other_db = idb_alloc(DB_OPT_BASE);
mob->item_drop_ratio_db = item_drop_ratio_db;
mob->item_drop_ratio_other_db = item_drop_ratio_other_db;

/* */
mob->reload = mob_reload;
Expand Down Expand Up @@ -6325,9 +6262,6 @@ void mob_defaults(void)
mob->readdb_race2 = mob_readdb_race2;
mob->readdb_itemratio = mob_readdb_itemratio;
mob->load = mob_load;
mob->get_item_drop_ratio = mob_get_item_drop_ratio;
mob->set_item_drop_ratio = mob_set_item_drop_ratio;
mob->final_ratio_sub = mob_final_ratio_sub;
mob->clear_spawninfo = mob_clear_spawninfo;
mob->destroy_mob_db = mob_destroy_mob_db;
mob->destroy_drop_groups = mob_destroy_drop_groups;
Expand Down
7 changes: 0 additions & 7 deletions src/map/mob.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ struct hplugin_data_store;
// Disable this to make monsters not do any path search when looking for a target (old behavior).
#define ACTIVEPATHSEARCH

struct item_drop_ratio;

enum e_bosstype {
BTYPE_NONE = 0,
BTYPE_BOSS = 1,
Expand Down Expand Up @@ -504,8 +502,6 @@ struct mob_interface {
int manuk[8];
int splendide[5];
int mora[5];
struct item_drop_ratio **item_drop_ratio_db;
struct DBMap *item_drop_ratio_other_db;
/* */
int (*init) (bool mimimal);
int (*final) (void);
Expand Down Expand Up @@ -621,9 +617,6 @@ struct mob_interface {
bool (*readdb_itemratio) (char *str[], int columns, int current);
void (*load) (bool minimal);
void (*clear_spawninfo) (void);
struct item_drop_ratio *(*get_item_drop_ratio) (int nameid);
void (*set_item_drop_ratio) (int nameid, struct item_drop_ratio *ratio);
int (*final_ratio_sub) (union DBKey key, struct DBData *data, va_list ap);
void (*destroy_mob_db) (int index);
void (*destroy_drop_groups) (void);
bool (*skill_db_libconfig) (const char *filename, bool ignore_missing);
Expand Down
Loading