Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial release item random option for monster drop #6

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
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
1 change: 1 addition & 0 deletions db/import-tmpl/item_randomopt_group.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// <randopt_groupid>,<rate>,<randopt_id1>,<randopt_value1>,<randopt_param1>{,<randopt_id2>,<randopt_value2>,<randopt_param2>,<randopt_id3>,<randopt_value3>,<randopt_param3>,<randopt_id4>,<randopt_value4>,<randopt_param4>,<randopt_id5>,<randopt_value5>,<randopt_param5>}
17 changes: 17 additions & 0 deletions db/import-tmpl/mob_drop.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Monster Drop Database
// Add drop item to monster
//
// Structure:
// <mobid>,<itemid>,<rate>{,<randopt_groupid>,<flag>}
//
// <mobid> : Monster ID. See db/[pre-]re/mob_db.txt
// <itemid> : Item ID.
// <rate> : 1 = 0.01%
// 100 = 1%
// 10000 = 100%
// Just like rate in mob_db.txt, adjusted by battle_config.
// To remove original drop from monster, use 0 as rate.
// Optional:
// <randopt_groupid> : If set, the dropped item will be modified by Random Option Group based on db/[pre-]re/item_randomopt_group.txt
// <flag> : 1 - The item is protected from steal.
// 2 - As MVP Reward
1 change: 1 addition & 0 deletions db/pre-re/item_randomopt_group.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// <randopt_groupid>,<rate>,<randopt_id1>,<randopt_value1>,<randopt_param1>{,<randopt_id2>,<randopt_value2>,<randopt_param2>,<randopt_id3>,<randopt_value3>,<randopt_param3>,<randopt_id4>,<randopt_value4>,<randopt_param4>,<randopt_id5>,<randopt_value5>,<randopt_param5>}
17 changes: 17 additions & 0 deletions db/pre-re/mob_drop.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Monster Drop Database
// Add drop item to monster
//
// Structure:
// <mobid>,<itemid>,<rate>{,<randopt_groupid>,<flag>}
//
// <mobid> : Monster ID. See db/[pre-]re/mob_db.txt
// <itemid> : Item ID.
// <rate> : 1 = 0.01%
// 100 = 1%
// 10000 = 100%
// Just like rate in mob_db.txt, adjusted by battle_config.
// To remove original drop from monster, use 0 as rate.
// Optional:
// <randopt_groupid> : If set, the dropped item will be modified by Random Option Group based on db/[pre-]re/item_randomopt_group.txt
// <flag> : 1 - The item is protected from steal.
// 2 - As MVP Reward
10 changes: 10 additions & 0 deletions db/re/item_randomopt_group.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// <randopt_groupid>,<rate>,<randopt_id1>,<randopt_value1>,<randopt_param1>{,<randopt_id2>,<randopt_value2>,<randopt_param2>,<randopt_id3>,<randopt_value3>,<randopt_param3>,<randopt_id4>,<randopt_value4>,<randopt_param4>,<randopt_id5>,<randopt_value5>,<randopt_param5>}

// Crimson Weapon
RDMOPTG_Crimson_Weapon,1,RDMOPT_WEAPON_ATTR_NOTHING,0,0
RDMOPTG_Crimson_Weapon,1,RDMOPT_WEAPON_ATTR_WATER,0,0
RDMOPTG_Crimson_Weapon,1,RDMOPT_WEAPON_ATTR_GROUND,0,0
RDMOPTG_Crimson_Weapon,1,RDMOPT_WEAPON_ATTR_FIRE,0,0
RDMOPTG_Crimson_Weapon,1,RDMOPT_WEAPON_ATTR_WIND,0,0
RDMOPTG_Crimson_Weapon,1,RDMOPT_WEAPON_ATTR_SAINT,0,0
RDMOPTG_Crimson_Weapon,1,RDMOPT_WEAPON_ATTR_DARKNESS,0,0
123 changes: 123 additions & 0 deletions db/re/mob_drop.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Monster Drop Database
// Add drop item to monster
//
// Structure:
// <mobid>,<itemid>,<rate>{,<randopt_groupid>,<flag>}
//
// <mobid> : Monster ID. See db/[pre-]re/mob_db.txt
// <itemid> : Item ID.
// <rate> : 1 = 0.01%
// 100 = 1%
// 10000 = 100%
// Just like rate in mob_db.txt, adjusted by battle_config.
// To remove original drop from monster, use 0 as rate.
// Optional:
// <randopt_groupid> : If set, the dropped item will be modified by Random Option Group based on db/[pre-]re/item_randomopt_group.txt
// <flag> : 1 - The item is protected from steal.
// 2 - As MVP Reward

1063,1102,100,RDMOPTG_None // LUNATIC
2770,1102,500,RDMOPTG_None // C2_LUNATIC
2771,1102,500,RDMOPTG_None // C3_LUNATIC
2072,1839,50,RDMOPTG_Crimson_Weapon // JAGUAR
1584,21015,50,RDMOPTG_Crimson_Weapon // TAMRUAN
2639,21015,250,RDMOPTG_Crimson_Weapon // C4_TAMRUAN
1154,13454,50,RDMOPTG_Crimson_Weapon // PASANA
1154,28705,50,RDMOPTG_Crimson_Weapon // PASANA
2719,13454,250,RDMOPTG_Crimson_Weapon // C1_PASANA
2719,28705,250,RDMOPTG_Crimson_Weapon // C1_PASANA
1117,28604,50,RDMOPTG_Crimson_Weapon // EVIL_DRUID
1517,16040,50,RDMOPTG_Crimson_Weapon // LI_ME_MANG_RYANG
2071,28007,50,RDMOPTG_Crimson_Weapon // HEADLESS_MULE
2778,16040,250,RDMOPTG_Crimson_Weapon // C5_LI_ME_MANG_RYANG
2838,28604,50,RDMOPTG_Crimson_Weapon // C5_EVIL_DRUID
1613,13127,50,RDMOPTG_None // METALING
1386,28705,50,RDMOPTG_Crimson_Weapon // SLEEPER
2655,28705,250,RDMOPTG_Crimson_Weapon // C5_SLEEPER
2656,28705,250,RDMOPTG_Crimson_Weapon // C1_SLEEPER
2755,13127,250,RDMOPTG_None // C2_METALING
2756,13127,250,RDMOPTG_None // C3_METALING
1631,1839,50,RDMOPTG_Crimson_Weapon // CHUNG_E_
1215,1443,50,RDMOPTG_Crimson_Weapon // STEM_WORM
2641,1443,250,RDMOPTG_Crimson_Weapon // C1_STEM_WORM
1404,1939,50,RDMOPTG_Crimson_Weapon // MIYABI_NINGYO
1628,13127,50,RDMOPTG_None // MOLE
1619,28705,50,RDMOPTG_Crimson_Weapon // PORCELLIO
2700,28705,250,RDMOPTG_Crimson_Weapon // C2_PORCELLIO
2745,13127,250,RDMOPTG_None // C2_MOLE
2746,1939,250,RDMOPTG_Crimson_Weapon // C3_MIYABI_NINGYO
1102,2009,50,RDMOPTG_None // BATHORY
1155,16040,50,RDMOPTG_Crimson_Weapon // PETIT
2714,16040,250,RDMOPTG_Crimson_Weapon // C1_PETIT
2715,16040,250,RDMOPTG_Crimson_Weapon // C2_PETIT
2885,2009,250,RDMOPTG_None // C4_BATHORY
2199,28705,50,RDMOPTG_Crimson_Weapon // SIORAVA
1143,16040,50,RDMOPTG_Crimson_Weapon // MARIONETTE
1413,1995,50,RDMOPTG_Crimson_Weapon // WILD_GINSENG
2761,16040,250,RDMOPTG_Crimson_Weapon // C3_MARIONETTE
1320,1498,50,RDMOPTG_Crimson_Weapon // OWL_DUKE
1320,2025,50,RDMOPTG_None // OWL_DUKE
1316,16040,50,RDMOPTG_Crimson_Weapon // SOLIDER
2647,16040,250,RDMOPTG_Crimson_Weapon // C2_SOLIDER
2721,1498,250,RDMOPTG_Crimson_Weapon // C3_OWL_DUKE
2721,2025,250,RDMOPTG_None // C3_OWL_DUKE
1408,1839,50,RDMOPTG_Crimson_Weapon // BLOOD_BUTTERFLY
2883,1839,250,RDMOPTG_Crimson_Weapon // C1_BLOOD_BUTTERFLY
1257,28007,50,RDMOPTG_Crimson_Weapon // INJUSTICE
2792,28007,250,RDMOPTG_Crimson_Weapon // C4_INJUSTICE
1302,21015,50,RDMOPTG_Crimson_Weapon // DARK_ILLUSION
1416,1939,50,RDMOPTG_Crimson_Weapon // WICKED_NYMPH
1416,1995,50,RDMOPTG_Crimson_Weapon // WICKED_NYMPH
2617,1939,250,RDMOPTG_Crimson_Weapon // C5_WICKED_NYMPH
2617,1995,250,RDMOPTG_Crimson_Weapon // C5_WICKED_NYMPH
1405,13327,50,RDMOPTG_Crimson_Weapon // TENGU
1030,1498,50,RDMOPTG_Crimson_Weapon // ANACONDAQ
2904,1498,250,RDMOPTG_Crimson_Weapon // C4_ANACONDAQ
1205,13454,50,RDMOPTG_Crimson_Weapon // EXECUTIONER
1135,28106,50,RDMOPTG_Crimson_Weapon // KOBOLD_3
1106,28705,50,RDMOPTG_Crimson_Weapon // DESERT_WOLF
1259,1498,250,RDMOPTG_Crimson_Weapon // GRYPHON
1310,28106,50,RDMOPTG_Crimson_Weapon // MAJORUROS
2767,28106,250,RDMOPTG_Crimson_Weapon // C4_MAJORUROS
1736,1839,50,RDMOPTG_Crimson_Weapon // ALIOT
1296,16040,50,RDMOPTG_Crimson_Weapon // KOBOLD_LEADER
1204,28705,50,RDMOPTG_Crimson_Weapon // TIRFING
1204,13454,50,RDMOPTG_Crimson_Weapon // TIRFING
1993,1443,50,RDMOPTG_Crimson_Weapon // NAGA
1390,1939,50,RDMOPTG_Crimson_Weapon // VIOLY
2621,1939,250,RDMOPTG_Crimson_Weapon // C5_VIOLY
2622,1939,250,RDMOPTG_Crimson_Weapon // C1_VIOLY
2623,1939,250,RDMOPTG_Crimson_Weapon // C2_VIOLY
1295,18130,50,RDMOPTG_None // OWL_BARON
1303,2025,50,RDMOPTG_None // GIANT_HONET
2821,2025,250,RDMOPTG_None // C3_GIANT_HONET
1702,21015,50,RDMOPTG_Crimson_Weapon // RETRIBUTION
2353,28106,50,RDMOPTG_Crimson_Weapon // N_MINOROUS
2684,21015,250,RDMOPTG_Crimson_Weapon // C4_RETRIBUTION
2685,21015,250,RDMOPTG_Crimson_Weapon // C5_RETRIBUTION
2686,21015,250,RDMOPTG_Crimson_Weapon // C1_RETRIBUTION
1219,21015,50,RDMOPTG_Crimson_Weapon // KNIGHT_OF_ABYSS
1703,1939,50,RDMOPTG_Crimson_Weapon // SOLACE
2650,1939,250,RDMOPTG_Crimson_Weapon // C5_SOLACE
2041,28705,50,RDMOPTG_Crimson_Weapon // MYSTELTAINN
2041,13454,50,RDMOPTG_Crimson_Weapon // MYSTELTAINN
2041,21015,50,RDMOPTG_Crimson_Weapon // MYSTELTAINN
1830,18130,50,RDMOPTG_None // BOW_GUARDIAN
1653,28705,50,RDMOPTG_Crimson_Weapon // WHIKEBAIN
1655,1839,50,RDMOPTG_Crimson_Weapon // EREND
1655,16040,50,RDMOPTG_Crimson_Weapon // EREND
1657,2009,50,RDMOPTG_None // RAWREL
1829,21015,50,RDMOPTG_Crimson_Weapon // SWORD_GUARDIAN
2692,2009,250,RDMOPTG_None // C3_RAWREL
1654,13454,50,RDMOPTG_Crimson_Weapon // ARMAIA
1654,28106,50,RDMOPTG_Crimson_Weapon // ARMAIA
1656,1939,50,RDMOPTG_Crimson_Weapon // KAVAC
1656,18130,50,RDMOPTG_None // KAVAC
1652,13454,50,RDMOPTG_Crimson_Weapon // YGNIZEM
1652,21015,50,RDMOPTG_Crimson_Weapon // YGNIZEM
1290,28705,50,RDMOPTG_Crimson_Weapon // SKELETON_GENERAL
2658,28705,250,RDMOPTG_Crimson_Weapon // C3_SKELETON_GENERAL
2659,28705,250,RDMOPTG_Crimson_Weapon // C4_SKELETON_GENERAL
1658,21015,500,RDMOPTG_Crimson_Weapon // B_YGNIZEM
1301,16040,50,RDMOPTG_Crimson_Weapon // AM_MUT
2362,28604,50,RDMOPTG_Crimson_Weapon // N_AMON_RA
12 changes: 7 additions & 5 deletions src/common/mmo.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ struct quest {
enum quest_state state; ///< Current quest state
};

struct s_item_randomoption {
short id;
short value;
char param;
};

struct item {
int id;
unsigned short nameid;
Expand All @@ -192,11 +198,7 @@ struct item {
char refine;
char attribute;
unsigned short card[MAX_SLOTS];
struct {
short id;
short value;
char param;
} option[MAX_ITEM_RDM_OPT]; // max of 5 random options can be supported.
struct s_item_randomoption option[MAX_ITEM_RDM_OPT]; // max of 5 random options can be supported.
unsigned int expire_time;
char favorite, bound;
uint64 unique_id;
Expand Down
4 changes: 2 additions & 2 deletions src/map/atcommand.c
Original file line number Diff line number Diff line change
Expand Up @@ -7181,7 +7181,7 @@ ACMD_FUNC(mobinfo)
clif_displaymessage(fd, msg_txt(sd,1245)); // Drops:
strcpy(atcmd_output, " ");
j = 0;
for (i = 0; i < MAX_MOB_DROP; i++) {
for (i = 0; i < MAX_MOB_DROP_TOTAL; i++) {
int droprate;
if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL)
continue;
Expand Down Expand Up @@ -7218,7 +7218,7 @@ ACMD_FUNC(mobinfo)
strcpy(atcmd_output, msg_txt(sd,1248)); // MVP Items:
mvpremain = 100.0; //Remaining drop chance for official mvp drop mode
j = 0;
for (i = 0; i < MAX_MVP_DROP; i++) {
for (i = 0; i < MAX_MVP_DROP_TOTAL; i++) {
if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_exists(mob->mvpitem[i].nameid)) == NULL)
continue;
//Because if there are 3 MVP drops at 50%, the first has a chance of 50%, the second 25% and the third 12.5%
Expand Down
80 changes: 79 additions & 1 deletion src/map/itemdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ static DBMap *itemdb; /// Item DB
static DBMap *itemdb_combo; /// Item Combo DB
static DBMap *itemdb_group; /// Item Group DB
static DBMap *itemdb_randomopt; /// Random option DB
static DBMap *itemdb_randomopt_group; /// Random option group DB

struct item_data *dummy_item; /// This is the default dummy item used for non-existant items. [Skotlex]

Expand Down Expand Up @@ -1649,6 +1650,79 @@ static bool itemdb_read_randomopt(const char* basedir, bool silent) {
return true;
}

/**
* Clear Item Random Option Group from memory
* @author [Cydh]
**/
static int itemdb_randomopt_group_free(DBKey key, DBData *data, va_list ap) {
struct s_random_opt_group *g = (struct s_random_opt_group *)db_data2ptr(data);
if (!g)
return 0;
if (g->entries)
aFree(g->entries);
g->entries = NULL;
aFree(g);
return 1;
}

/**
* Get Item Random Option Group from itemdb_randomopt_group MapDB
* @param id Random Option Group
* @return Random Option Group data or NULL if not found
* @author [Cydh]
**/
struct s_random_opt_group *itemdb_randomopt_group_exists(int id) {
return (struct s_random_opt_group *)uidb_get(itemdb_randomopt_group, id);
}

/**
* Read Item Random Option Group from db file
* @author [Cydh]
**/
static bool itemdb_read_randomopt_group(char* str[], int columns, int current) {
int id = 0, i;
unsigned short rate = (unsigned short)strtoul(str[1], NULL, 10);
struct s_random_opt_group *g = NULL;

if (!script_get_constant(str[0], &id)) {
ShowError("itemdb_read_randomopt_group: Invalid ID for Random Option Group '%s'.\n", str[0]);
return false;
}

if ((columns-2)%3 != 0) {
ShowError("itemdb_read_randomopt_group: Invalid column entries '%d'.\n", columns);
return false;
}

if (!(g = (struct s_random_opt_group *)uidb_get(itemdb_randomopt_group, id))) {
CREATE(g, struct s_random_opt_group, 1);
g->id = id;
g->total = 0;
g->entries = NULL;
uidb_put(itemdb_randomopt_group, g->id, g);
}

RECREATE(g->entries, struct s_random_opt_group_entry, g->total + rate);

for (i = g->total; i < (g->total + rate); i++) {
int j, k;
memset(&g->entries[i].option, 0, sizeof(g->entries[i].option));
for (j = 0, k = 2; k < columns && j < MAX_ITEM_RDM_OPT; k+=3) {
int randid = 0;
if (!script_get_constant(str[k], &randid) || !itemdb_randomopt_exists(randid)) {
ShowError("itemdb_read_randomopt_group: Invalid random group id '%s' in column %d!\n", str[k], k+1);
continue;
}
g->entries[i].option[j].id = randid;
g->entries[i].option[j].value = (short)strtoul(str[k+1], NULL, 10);
g->entries[i].option[j].param = (char)strtoul(str[k+2], NULL, 10);
j++;
}
}
g->total += rate;
return true;
}

/**
* Read all item-related databases
*/
Expand Down Expand Up @@ -1700,6 +1774,7 @@ static void itemdb_read(void) {
sv_readdb(dbsubpath2, "item_delay.txt", ',', 2, 3, -1, &itemdb_read_itemdelay, i);
sv_readdb(dbsubpath2, "item_buyingstore.txt", ',', 1, 1, -1, &itemdb_read_buyingstore, i);
sv_readdb(dbsubpath2, "item_flag.txt", ',', 2, 2, -1, &itemdb_read_flag, i);
sv_readdb(dbsubpath2, "item_randomopt_group.txt", ',', 5, 2+5*MAX_ITEM_RDM_OPT, -1, &itemdb_read_randomopt_group, i);
aFree(dbsubpath1);
aFree(dbsubpath2);
}
Expand Down Expand Up @@ -1793,6 +1868,7 @@ void itemdb_reload(void) {

itemdb_group->clear(itemdb_group, itemdb_group_free);
itemdb_randomopt->clear(itemdb_randomopt, itemdb_randomopt_free);
itemdb_randomopt_group->clear(itemdb_randomopt_group, itemdb_randomopt_group_free);
itemdb->clear(itemdb, itemdb_final_sub);
db_clear(itemdb_combo);
if (battle_config.feature_roulette)
Expand All @@ -1810,7 +1886,7 @@ void itemdb_reload(void) {
for( i = 0; i < MAX_MOB_DB; i++ ) {
struct mob_db *entry = mob_db(i);

for(d = 0; d < MAX_MOB_DROP; d++) {
for(d = 0; d < MAX_MOB_DROP_TOTAL; d++) {
struct item_data *id;
if( !entry->dropitem[d].nameid )
continue;
Expand Down Expand Up @@ -1861,6 +1937,7 @@ void do_final_itemdb(void) {
db_destroy(itemdb_combo);
itemdb_group->destroy(itemdb_group, itemdb_group_free);
itemdb_randomopt->destroy(itemdb_randomopt, itemdb_randomopt_free);
itemdb_randomopt_group->destroy(itemdb_randomopt_group, itemdb_randomopt_group_free);
itemdb->destroy(itemdb, itemdb_final_sub);
destroy_item_data(dummy_item);
if (battle_config.feature_roulette)
Expand All @@ -1875,6 +1952,7 @@ void do_init_itemdb(void) {
itemdb_combo = uidb_alloc(DB_OPT_BASE);
itemdb_group = uidb_alloc(DB_OPT_BASE);
itemdb_randomopt = uidb_alloc(DB_OPT_BASE);
itemdb_randomopt_group = uidb_alloc(DB_OPT_BASE);
itemdb_create_dummy();
itemdb_read();

Expand Down
19 changes: 19 additions & 0 deletions src/map/itemdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,24 @@ struct s_random_opt_data
struct script_code *script;
};

/// Enum for Random Option Groups
enum Random_Option_Group {
RDMOPTG_None = 0,
RDMOPTG_Crimson_Weapon,
};

/// Struct for random option group entry
struct s_random_opt_group_entry {
struct s_item_randomoption option[MAX_ITEM_RDM_OPT];
};

/// Struct for Random Option Group
struct s_random_opt_group {
uint8 id;
struct s_random_opt_group_entry *entries;
uint16 total;
};

struct item_data* itemdb_searchname(const char *name);
int itemdb_searchname_array(struct item_data** data, int size, const char *str);
struct item_data* itemdb_search(unsigned short nameid);
Expand Down Expand Up @@ -536,6 +554,7 @@ uint16 itemdb_get_randgroupitem_count(uint16 group_id, uint8 sub_group, unsigned
bool itemdb_parse_roulette_db(void);

struct s_random_opt_data *itemdb_randomopt_exists(short id);
struct s_random_opt_group *itemdb_randomopt_group_exists(int id);

void itemdb_reload(void);

Expand Down
Loading