Skip to content
Permalink
Browse files
RE:Initial release item random option for monster drop (#2065)
* Initial release item random option for monster drop
* To add item for monster with random option group, see 'db/[pre-]re/mob_drop.txt'
* To add item random option group with random option group, see 'db/[pre-]re/mob_item_randomopt_group.txt'
* Default entries for random options are follow iRO Crimson/Scarlet Weapon based on
  * "[Renewal] Episode 15.2 Crimson Weapon System", see http://www.playragnarok.com/news/updatedetail.aspx?id=280&p=1.
  * File uploaded by Oda (iRO's CM) on https://forums.warpportal.com/index.php?/topic/168763-fansitedb-information-distribution-and-request-station/?p=2495922

Signed-off-by: Cydh Ramdh <cydh@pservero.com>

* Follow up 3b7db36
* Moved `RDMOPTG_Crimson_Weapon` from const.txt to `enum Random_Option_Group` in `itemdb.h`.
* Removed `RDMOPT_WEAPON_ATTR_POISON`, `RDMOPT_WEAPON_ATTR_TELEKINESIS`, and `RDMOPT_WEAPON_ATTR_UNDEAD` from Crimson Weapon random group (`RDMOPTG_Crimson_Weapon`), thanks to @Atemo
* Added db header for impot-tmpl files, thanks to @secretdataz

Signed-off-by: Cydh Ramdh <cydh@pservero.com>

* Follow up ac0cdd8
* Fixed type on steal checking

Signed-off-by: Cydh Ramdh <cydh@pservero.com>

* Cleared some drop slot for crimson weapon
  • Loading branch information
cydh authored and Atemo committed Apr 27, 2017
1 parent cbc3b26 commit e59cdfff903c1f7ea920858eb62a6ce1b31db9c6
@@ -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>}
@@ -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
@@ -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>}
@@ -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
@@ -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

This comment has been minimized.

Copy link
@idamonli

idamonli May 5, 2017

How is the value of randopt_value1 random?

This comment has been minimized.

Copy link
@idamonli

This comment has been minimized.

Copy link
@idamonli

idamonli May 5, 2017

If the set of five random attributes appear together?

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

Large diffs are not rendered by default.

@@ -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
@@ -188,6 +188,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;
@@ -197,11 +203,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;
@@ -7229,7 +7229,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;
@@ -7266,7 +7266,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%
@@ -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]

@@ -1667,6 +1668,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
*/
@@ -1718,6 +1792,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);
}
@@ -1824,7 +1899,7 @@ void itemdb_reload_itemmob_data(void) {
struct mob_db *entry = mob_db(i);
int d, k;

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;
@@ -1855,6 +1930,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)
@@ -1899,6 +1975,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)
@@ -1913,6 +1990,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();

@@ -851,6 +851,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);
@@ -919,6 +937,7 @@ char itemdb_pc_get_itemgroup(uint16 group_id, struct map_session_data *sd);
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_itemmob_data(void);
void itemdb_reload(void);

4 comments on commit e59cdff

@padangyoesa
Copy link

@padangyoesa padangyoesa commented on e59cdff Sep 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i already did all of things above. still no option. can you help me sir?

@Anjuts
Copy link

@Anjuts Anjuts commented on e59cdff Oct 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

up. same problem sir. no random option. please help us..

@Jeybla
Copy link
Contributor

@Jeybla Jeybla commented on e59cdff Oct 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please checkout the current HEAD revision and retry it. We discourage from applying such big changes manually. If you can reproduce an issue on the current HEAD revision, please open an issue with detailed informations also following the issue template. Everything else is at your own risk. Thanks

@Malfrost
Copy link

@Malfrost Malfrost commented on e59cdff Jun 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, i just started to test those thing above and seen that monster doesn't drop the items and also when i'm using @mi command, monsters involved doesn't display the crimson items on monster details. Can someone help? thanks

Please sign in to comment.