* Follow up 51074a0: Remove ugly fixed array size! It increases memory usage too much!
* A little optimization on skill_db for skill requirement Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
parent
14a096a5a2
commit
5143c4c36f
126
src/map/itemdb.c
126
src/map/itemdb.c
@ -160,8 +160,8 @@ unsigned short itemdb_searchrandomid(int group_id, uint8 sub_group)
|
||||
ShowError("itemdb_searchrandomid: Invalid sub_group %d\n", sub_group+1);
|
||||
return UNKNOWN_ITEM_ID;
|
||||
}
|
||||
if (itemgroup_db[group_id].random_qty[sub_group])
|
||||
return itemgroup_db[group_id].random[sub_group][rnd()%itemgroup_db[group_id].random_qty[sub_group]].nameid;
|
||||
if (&itemgroup_db[group_id].random[sub_group] && itemgroup_db[group_id].random[sub_group].data_qty)
|
||||
return itemgroup_db[group_id].random[sub_group].data[rand()%itemgroup_db[group_id].random[sub_group].data_qty].nameid;
|
||||
|
||||
ShowError("itemdb_searchrandomid: No item entries for group id %d and sub group %d\n", group_id, sub_group+1);
|
||||
return UNKNOWN_ITEM_ID;
|
||||
@ -187,9 +187,11 @@ uint16 itemdb_get_randgroupitem_count(uint16 group_id, uint8 sub_group, uint16 n
|
||||
ShowError("itemdb_get_randgroupitem_count: Invalid sub_group id %d\n", group_id+1);
|
||||
return amt;
|
||||
}
|
||||
ARR_FIND(0,itemgroup_db[group_id].random_qty[sub_group],i,itemgroup_db[group_id].random[sub_group][i].nameid == nameid);
|
||||
if (i < MAX_ITEMGROUP_RAND)
|
||||
amt = itemgroup_db[group_id].random[sub_group][i].amount;
|
||||
if (!(&itemgroup_db[group_id].random[sub_group]) || !itemgroup_db[group_id].random[sub_group].data_qty)
|
||||
return amt;
|
||||
ARR_FIND(0,itemgroup_db[group_id].random[sub_group].data_qty,i,itemgroup_db[group_id].random[sub_group].data[i].nameid == nameid);
|
||||
if (i < itemgroup_db[group_id].random[sub_group].data_qty)
|
||||
amt = itemgroup_db[group_id].random[sub_group].data[i].amount;
|
||||
return amt;
|
||||
}
|
||||
|
||||
@ -251,23 +253,23 @@ char itemdb_pc_get_itemgroup(uint16 group_id, struct map_session_data *sd) {
|
||||
}
|
||||
|
||||
//Get the 'must' item(s)
|
||||
for (i = 0; i < itemgroup_db[group_id].must_qty; i++) {
|
||||
if (&itemgroup_db[group_id].must[i] && itemdb_exists(itemgroup_db[group_id].must[i].nameid))
|
||||
itemdb_pc_get_itemgroup_sub(sd,group_id,&itemgroup_db[group_id].must[i]);
|
||||
}
|
||||
if (itemgroup_db[group_id].must_qty)
|
||||
for (i = 0; i < itemgroup_db[group_id].must_qty; i++)
|
||||
if (&itemgroup_db[group_id].must[i] && itemdb_exists(itemgroup_db[group_id].must[i].nameid))
|
||||
itemdb_pc_get_itemgroup_sub(sd,group_id,&itemgroup_db[group_id].must[i]);
|
||||
|
||||
//Get the 'random' item each random group
|
||||
for (i = 0; i < MAX_ITEMGROUP_RANDGROUP; i++) {
|
||||
uint16 rand;
|
||||
if (!itemgroup_db[group_id].random_qty[i]) //Skip empty random group
|
||||
if (!(&itemgroup_db[group_id].random[i]) || !itemgroup_db[group_id].random[i].data_qty) //Skip empty random group
|
||||
continue;
|
||||
rand = rnd()%itemgroup_db[group_id].random_qty[i];
|
||||
rand = rnd()%itemgroup_db[group_id].random[i].data_qty;
|
||||
//Woops, why is the data empty? Every check should be done when load the item group! So this is bad day for the player :P
|
||||
if (!&itemgroup_db[group_id].random[i][rand] || !itemgroup_db[group_id].random[i][rand].nameid) {
|
||||
if (!&itemgroup_db[group_id].random[i].data[rand] || !itemgroup_db[group_id].random[i].data[rand].nameid) {
|
||||
continue;
|
||||
}
|
||||
if (itemdb_exists(itemgroup_db[group_id].random[i][rand].nameid))
|
||||
itemdb_pc_get_itemgroup_sub(sd,group_id,&itemgroup_db[group_id].random[i][rand]);
|
||||
if (itemdb_exists(itemgroup_db[group_id].random[i].data[rand].nameid))
|
||||
itemdb_pc_get_itemgroup_sub(sd,group_id,&itemgroup_db[group_id].random[i].data[rand]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -282,8 +284,8 @@ int itemdb_group_bonus(struct map_session_data* sd, int itemid)
|
||||
for (i=0; i < MAX_ITEMGROUP; i++) {
|
||||
if (!sd->itemgrouphealrate[i])
|
||||
continue;
|
||||
ARR_FIND( 0, itemgroup_db[i].random_qty[0], j, itemgroup_db[i].random[0][j].nameid == itemid );
|
||||
if( j < itemgroup_db[i].random_qty[0] )
|
||||
ARR_FIND(0,itemgroup_db[i].random[0].data_qty,j,itemgroup_db[i].random[0].data[j].nameid == itemid );
|
||||
if( j < itemgroup_db[i].random[0].data_qty )
|
||||
bonus += sd->itemgrouphealrate[i];
|
||||
}
|
||||
return bonus;
|
||||
@ -659,9 +661,10 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
|
||||
|
||||
while (fgets(line,sizeof(line),fp)) {
|
||||
uint16 nameid;
|
||||
int j, group_id, prob = 1, amt = 1, group = 1, announced = 0, dur = 0, named = 0, bound = 0;
|
||||
int j, group_id, prob = 1, amt = 1, rand_group = 1, announced = 0, dur = 0, named = 0, bound = 0;
|
||||
char *str[3], *p, w1[1024], w2[1024];
|
||||
bool found = false;
|
||||
struct s_item_group_random *random;
|
||||
|
||||
ln++;
|
||||
if (line[0] == '/' && line[1] == '/')
|
||||
@ -678,7 +681,7 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
|
||||
for (j = 0, p = line; j < 3 && p;j++) {
|
||||
str[j] = p;
|
||||
if (j == 2)
|
||||
sscanf(str[j],"%d,%d,%d,%d,%d,%d,%d",&prob,&amt,&group,&announced,&dur,&named,&bound);
|
||||
sscanf(str[j],"%d,%d,%d,%d,%d,%d,%d",&prob,&amt,&rand_group,&announced,&dur,&named,&bound);
|
||||
p = strchr(p,',');
|
||||
if (p) *p++=0;
|
||||
}
|
||||
@ -691,7 +694,8 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
|
||||
}
|
||||
|
||||
//Checking group_id
|
||||
if (atoi(str[0]))
|
||||
trim(str[0]);
|
||||
if (ISDIGIT(str[0][0]))
|
||||
group_id = atoi(str[0]);
|
||||
else //Try reads group id by const
|
||||
script_get_constant(trim(str[0]),&group_id);
|
||||
@ -701,13 +705,14 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
|
||||
}
|
||||
|
||||
//Checking sub group
|
||||
if (group > MAX_ITEMGROUP_RANDGROUP) {
|
||||
ShowWarning("itemdb_read_itemgroup: Invalid sub group %d for group id %d in %s:%d\n", group, group_id, filename, ln);
|
||||
if (rand_group > MAX_ITEMGROUP_RANDGROUP) {
|
||||
ShowWarning("itemdb_read_itemgroup: Invalid sub group %d for group id %d in %s:%d\n", rand_group, group_id, filename, ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
//Checking item
|
||||
if ((nameid = atoi(str[1])) && itemdb_exists(nameid))
|
||||
trim(str[1]);
|
||||
if (ISDIGIT(str[1][0]) && itemdb_exists((nameid = atoi(str[1]))))
|
||||
found = true;
|
||||
else if (itemdb_searchname(str[1])) {
|
||||
found = true;
|
||||
@ -718,20 +723,18 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
|
||||
continue;
|
||||
}
|
||||
|
||||
//Checking the capacity
|
||||
if ((group && itemgroup_db[group_id].random_qty[group-1]+prob >= MAX_ITEMGROUP_RAND) ||
|
||||
(!group && itemgroup_db[group_id].must_qty+1 >= MAX_ITEMGROUP_MUST))
|
||||
{
|
||||
ShowWarning("itemdb_read_itemgroup: Group id %d is overflow (%d entries) in %s:%d\n", group_id, (!group) ? MAX_ITEMGROUP_MUST : MAX_ITEMGROUP_RAND, filename, ln);
|
||||
continue;
|
||||
}
|
||||
|
||||
amt = cap_value(amt,1,MAX_AMOUNT);
|
||||
dur = cap_value(dur,0,UINT16_MAX);
|
||||
bound = cap_value(bound,0,4);
|
||||
|
||||
if (!group) {
|
||||
//Must item, place it here
|
||||
if (!rand_group) {
|
||||
uint16 idx = itemgroup_db[group_id].must_qty;
|
||||
if (!idx)
|
||||
CREATE(itemgroup_db[group_id].must,struct s_item_group,1);
|
||||
else
|
||||
RECREATE(itemgroup_db[group_id].must,struct s_item_group,idx+1);
|
||||
|
||||
itemgroup_db[group_id].must[idx].nameid = nameid;
|
||||
itemgroup_db[group_id].must[idx].amount = amt;
|
||||
itemgroup_db[group_id].must[idx].isAnnounced = announced;
|
||||
@ -739,25 +742,34 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent)
|
||||
itemgroup_db[group_id].must[idx].isNamed = named;
|
||||
itemgroup_db[group_id].must[idx].bound = bound;
|
||||
itemgroup_db[group_id].must_qty++;
|
||||
group = 1;
|
||||
rand_group = 1;
|
||||
}
|
||||
prob = max(prob,0);
|
||||
//Must item didn't set as random item, skip next process
|
||||
if (!prob) {
|
||||
entries++;
|
||||
continue;
|
||||
}
|
||||
group -= 1;
|
||||
for (j = 0; j < prob; j++) {
|
||||
uint16 idx;
|
||||
idx = itemgroup_db[group_id].random_qty[group];
|
||||
itemgroup_db[group_id].random[group][idx].nameid = nameid;
|
||||
itemgroup_db[group_id].random[group][idx].amount = amt;
|
||||
itemgroup_db[group_id].random[group][idx].isAnnounced = announced;
|
||||
itemgroup_db[group_id].random[group][idx].duration = dur;
|
||||
itemgroup_db[group_id].random[group][idx].isNamed = named;
|
||||
itemgroup_db[group_id].random[group][idx].bound = bound;
|
||||
itemgroup_db[group_id].random_qty[group]++;
|
||||
rand_group -= 1;
|
||||
random = &itemgroup_db[group_id].random[rand_group];
|
||||
|
||||
//Check, if the entry for this random group already created or not
|
||||
if (!random->data_qty) {
|
||||
CREATE(random->data,struct s_item_group,prob);
|
||||
random->data_qty = 0;
|
||||
}
|
||||
else
|
||||
RECREATE(random->data,struct s_item_group,random->data_qty+prob);
|
||||
//Now put the entry to its rand_group
|
||||
for (j = random->data_qty; j < random->data_qty+prob; j++) {
|
||||
random->data[j].nameid = nameid;
|
||||
random->data[j].amount = amt;
|
||||
random->data[j].isAnnounced = announced;
|
||||
random->data[j].duration = dur;
|
||||
random->data[j].isNamed = named;
|
||||
random->data[j].bound = bound;
|
||||
}
|
||||
random->data_qty += prob;
|
||||
entries++;
|
||||
}
|
||||
fclose(fp);
|
||||
@ -1621,6 +1633,19 @@ void itemdb_reload(void)
|
||||
if( itemdb_array[i] )
|
||||
destroy_item_data(itemdb_array[i], true);
|
||||
|
||||
for (i = 0; i < MAX_ITEMGROUP; i++) {
|
||||
uint8 j;
|
||||
if (!(&itemgroup_db[i]))
|
||||
continue;
|
||||
if (itemgroup_db[i].must_qty)
|
||||
aFree(itemgroup_db[i].must);
|
||||
for (j = 0; j < MAX_ITEMGROUP_RANDGROUP; j++) {
|
||||
if (!(&itemgroup_db[i].random[j]) || !itemgroup_db[i].random[j].data_qty)
|
||||
continue;
|
||||
aFree(itemgroup_db[i].random[j].data);
|
||||
}
|
||||
}
|
||||
|
||||
itemdb_other->clear(itemdb_other, itemdb_final_sub);
|
||||
db_clear(itemdb_combo);
|
||||
|
||||
@ -1687,6 +1712,19 @@ void do_final_itemdb(void)
|
||||
if( itemdb_array[i] )
|
||||
destroy_item_data(itemdb_array[i], true);
|
||||
|
||||
for (i = 0; i < MAX_ITEMGROUP; i++) {
|
||||
uint8 j;
|
||||
if (!(&itemgroup_db[i]))
|
||||
continue;
|
||||
if (itemgroup_db[i].must_qty)
|
||||
aFree(itemgroup_db[i].must);
|
||||
for (j = 0; j < MAX_ITEMGROUP_RANDGROUP; j++) {
|
||||
if (!(&itemgroup_db[i].random[j]) || !itemgroup_db[i].random[j].data_qty)
|
||||
continue;
|
||||
aFree(itemgroup_db[i].random[j].data);
|
||||
}
|
||||
}
|
||||
|
||||
itemdb_other->destroy(itemdb_other, itemdb_final_sub);
|
||||
destroy_item_data(&dummy_item, false);
|
||||
db_destroy(itemdb_combo);
|
||||
@ -1697,7 +1735,7 @@ int do_init_itemdb(void) {
|
||||
itemdb_other = idb_alloc(DB_OPT_BASE);
|
||||
itemdb_combo = idb_alloc(DB_OPT_BASE);
|
||||
create_dummy_data(); //Dummy data item.
|
||||
|
||||
itemdb_read();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,10 +26,8 @@
|
||||
#define IG_FINDINGORE 6
|
||||
#define IG_POTION 37
|
||||
|
||||
#define MAX_ITEMGROUP 390 ///The max. item group count (increase this when needed).
|
||||
#define MAX_ITEMGROUP 390 ///The max. item group count (increase this when needed). TODO: Remove this limit and use dynamic allocaton
|
||||
|
||||
#define MAX_ITEMGROUP_RAND 11000 ///Max item slots for random item group (increase this when needed).
|
||||
#define MAX_ITEMGROUP_MUST 15 ///Max item for 'must' item group (increase this when needed).
|
||||
#define MAX_ITEMGROUP_RANDGROUP 4 ///Max group for random item (increase this when needed).
|
||||
|
||||
#define CARD0_FORGE 0x00FF
|
||||
@ -310,6 +308,14 @@ enum e_item_job {
|
||||
ITEMJ_THIRD_BABY = 0x20,
|
||||
};
|
||||
|
||||
struct item_combo {
|
||||
struct script_code *script;
|
||||
unsigned short *nameid;/* nameid array */
|
||||
unsigned char count;
|
||||
unsigned short id;/* id of this combo */
|
||||
bool isRef;/* whether this struct is a reference or the master */
|
||||
};
|
||||
|
||||
struct item_data {
|
||||
uint16 nameid;
|
||||
char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH];
|
||||
@ -373,7 +379,7 @@ struct item_data {
|
||||
unsigned char combos_count;
|
||||
};
|
||||
|
||||
/* Struct of item group */
|
||||
/* Struct of item group entry */
|
||||
struct s_item_group {
|
||||
uint16 nameid, ///item id
|
||||
duration; ///duration if item as rental item
|
||||
@ -383,19 +389,17 @@ struct s_item_group {
|
||||
char bound; ///makes the item as bound item (according to bound type)
|
||||
};
|
||||
|
||||
/* Struct of item group that will be used for db */
|
||||
struct s_item_group_db {
|
||||
struct s_item_group must[MAX_ITEMGROUP_MUST];
|
||||
struct s_item_group random[MAX_ITEMGROUP_RANDGROUP][MAX_ITEMGROUP_RAND]; ///NOTE: Is this good?
|
||||
uint16 must_qty, random_qty[MAX_ITEMGROUP_RANDGROUP];
|
||||
/* Struct of random group */
|
||||
struct s_item_group_random {
|
||||
struct s_item_group *data;
|
||||
uint16 data_qty;
|
||||
};
|
||||
|
||||
struct item_combo {
|
||||
struct script_code *script;
|
||||
unsigned short *nameid;/* nameid array */
|
||||
unsigned char count;
|
||||
unsigned short id;/* id of this combo */
|
||||
bool isRef;/* whether this struct is a reference or the master */
|
||||
/* Struct of item group that will be used for db */
|
||||
struct s_item_group_db {
|
||||
struct s_item_group *must;
|
||||
uint16 must_qty;
|
||||
struct s_item_group_random random[MAX_ITEMGROUP_RANDGROUP]; //! TODO: Move this fixed array to dynamic allocation!
|
||||
};
|
||||
|
||||
struct item_data* itemdb_searchname(const char *name);
|
||||
|
117
src/map/skill.c
117
src/map/skill.c
@ -225,7 +225,7 @@ int skill_get_weapontype( uint16 skill_id ) { skill_get (skill_d
|
||||
int skill_get_ammotype( uint16 skill_id ) { skill_get (skill_db[skill_id].require.ammo, skill_id); }
|
||||
int skill_get_ammo_qty( uint16 skill_id, uint16 skill_lv ) { skill_get2 (skill_db[skill_id].require.ammo_qty[skill_lv-1], skill_id, skill_lv); }
|
||||
int skill_get_state( uint16 skill_id ) { skill_get (skill_db[skill_id].require.state, skill_id); }
|
||||
int skill_get_status( uint16 skill_id, int idx ) { skill_get3 (skill_db[skill_id].require.status[idx], skill_id, idx); }
|
||||
//int skill_get_status( uint16 skill_id, int idx ) { skill_get3 (skill_db[skill_id].require.status[idx], skill_id, idx); }
|
||||
int skill_get_status_count( uint16 skill_id ) { skill_get (skill_db[skill_id].require.status_count, skill_id); }
|
||||
int skill_get_spiritball( uint16 skill_id, uint16 skill_lv ){ skill_get2 (skill_db[skill_id].require.spiritball[skill_lv-1], skill_id, skill_lv); }
|
||||
int skill_get_itemid( uint16 skill_id, int idx ) { skill_get3 (skill_db[skill_id].require.itemid[idx], skill_id, idx); }
|
||||
@ -14053,15 +14053,17 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
|
||||
}
|
||||
|
||||
//check if equiped item
|
||||
for (i = 0; i < MAX_SKILL_EQUIP_REQUIRE; i++) {
|
||||
int reqeqit = require.eqItem[i];
|
||||
if(!reqeqit) break; //no more required item get out of here
|
||||
if (!pc_checkequip2(sd,reqeqit,EQI_ACC_L,EQI_MAX)) {
|
||||
char output[128];
|
||||
//clif_skill_fail(sd, skill_id, USESKILL_FAIL_NEED_EQUIPMENT, reqeqit);
|
||||
sprintf(output,"need to put on [%d] in order to use.",reqeqit);
|
||||
clif_colormes(sd,color_table[COLOR_RED],output);
|
||||
return 0;
|
||||
if (require.eqItem_count) {
|
||||
for (i = 0; i < require.eqItem_count; i++) {
|
||||
int reqeqit = require.eqItem[i];
|
||||
if(!reqeqit) break; //no more required item get out of here
|
||||
if (!pc_checkequip2(sd,reqeqit,EQI_ACC_L,EQI_MAX)) {
|
||||
char output[128];
|
||||
//clif_skill_fail(sd, skill_id, USESKILL_FAIL_NEED_EQUIPMENT, reqeqit);
|
||||
sprintf(output,"need to put on [%d] in order to use.",reqeqit);
|
||||
clif_colormes(sd,color_table[COLOR_RED],output);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14453,10 +14455,9 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
|
||||
}
|
||||
|
||||
req.status_count = skill_db[idx].require.status_count;
|
||||
memset(req.status,SC_NONE,sizeof(req.status));
|
||||
memcpy(req.status,skill_db[idx].require.status,sizeof(skill_db[idx].require.status));
|
||||
memset(req.eqItem,0,sizeof(req.eqItem));
|
||||
memcpy(req.eqItem,skill_db[idx].require.eqItem,sizeof(skill_db[idx].require.eqItem));
|
||||
req.status = skill_db[idx].require.status;
|
||||
req.eqItem_count = skill_db[idx].require.eqItem_count;
|
||||
req.eqItem = skill_db[idx].require.eqItem;
|
||||
|
||||
for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; i++ ) {
|
||||
if( (skill_id == AM_POTIONPITCHER || skill_id == CR_SLIMPITCHER || skill_id == CR_CULTIVATION) && i != skill_lv%11 - 1 )
|
||||
@ -14643,10 +14644,10 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
|
||||
if (req_opt&0x0040) req.weapon = 0;
|
||||
if (req_opt&0x0080) { req.ammo = 0; req.ammo_qty = 0; }
|
||||
if (req_opt&0x0100) req.state = ST_NONE;
|
||||
if (req_opt&0x0200) memset(req.status,SC_NONE,sizeof(req.status));
|
||||
if (req_opt&0x0200) req.status_count = 0;
|
||||
if (req_opt&0x0400) req.spiritball = 0;
|
||||
if (req_opt&0x0800) { memset(req.itemid,0,sizeof(req.itemid)); memset(req.amount,0,sizeof(req.amount)); }
|
||||
if (req_opt&0x1000) memset(req.eqItem,0,sizeof(req.eqItem));
|
||||
if (req_opt&0x1000) req.eqItem_count = 0;
|
||||
}
|
||||
|
||||
return req;
|
||||
@ -18553,6 +18554,44 @@ static bool skill_parse_row_skilldb(char* split[], int columns, int current)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Split string to int or constanta value (const.txt)
|
||||
* @param *str: String input
|
||||
* @param *val: Temporary storage
|
||||
* @param *delim: Delimiter (for multiple value support)
|
||||
* @param useConst: 'true' uses const.txt as reference, 'false' uses atoi()
|
||||
* @param min: Min value of each const. Example: SC has min value SC_NONE (-1), so the value that less or equal won't be counted
|
||||
* @return count: Number of success
|
||||
*/
|
||||
uint8 skill_split2(char *str, int *val, const char *delim, bool useConst, short min) {
|
||||
uint8 i = 0;
|
||||
char *p = strtok(str,delim);
|
||||
|
||||
while (p != NULL) {
|
||||
int n = -1;
|
||||
if (useConst)
|
||||
script_get_constant(trim(p),&n);
|
||||
else
|
||||
n = atoi(p);
|
||||
if (n > min) {
|
||||
val[i] = n;
|
||||
i++;
|
||||
}
|
||||
p = strtok(NULL,delim);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/// Clear status data from skill requirement
|
||||
static void skill_destroy_requirement(void) {
|
||||
uint16 i;
|
||||
for (i = 0; i < MAX_SKILL; i++) {
|
||||
if (skill_db[i].require.status_count)
|
||||
aFree(skill_db[i].require.status);
|
||||
if (skill_db[i].require.eqItem_count)
|
||||
aFree(skill_db[i].require.eqItem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read skill requirement from skill_require_db.txt
|
||||
**/
|
||||
@ -18618,42 +18657,36 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
|
||||
else if( strcmpi(split[10],"elementalspirit") == 0 ) skill_db[idx].require.state = ST_ELEMENTALSPIRIT;
|
||||
else if( strcmpi(split[10],"peco") == 0 ) skill_db[idx].require.state = ST_PECO;
|
||||
else skill_db[idx].require.state = ST_NONE; // Unknown or no state
|
||||
|
||||
|
||||
//Status requirements
|
||||
memset(skill_db[idx].require.status,SC_NONE,sizeof(skill_db[idx].require.status));
|
||||
skill_db[idx].require.status_count = 0;
|
||||
p = strtok(split[11],":");
|
||||
for( i = 0; i < MAX_SKILL_STATUS_REQUIRE && p != NULL; i++ ) {
|
||||
int status = SC_NONE;
|
||||
script_get_constant(trim(p),&status);
|
||||
if (status > SC_NONE) {
|
||||
skill_db[idx].require.status[skill_db[idx].require.status_count] = (enum sc_type)status;
|
||||
skill_db[idx].require.status_count++;
|
||||
trim(split[11]);
|
||||
if (split[11][0] != '\0') {
|
||||
int require[MAX_SKILL_STATUS_REQUIRE];
|
||||
if ((skill_db[idx].require.status_count = skill_split2(split[11],require,":",true,SC_NONE))) {
|
||||
skill_db[idx].require.status = aMalloc(skill_db[idx].require.status_count * sizeof(sc_type));
|
||||
for (i = 0; i < skill_db[idx].require.status_count; i++)
|
||||
skill_db[idx].require.status[i] = (sc_type)require[i];
|
||||
}
|
||||
p = strtok(NULL,":");
|
||||
}
|
||||
|
||||
|
||||
skill_split_atoi(split[12],skill_db[idx].require.spiritball);
|
||||
|
||||
|
||||
for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; i++ ) {
|
||||
skill_db[idx].require.itemid[i] = atoi(split[13+ 2*i]);
|
||||
skill_db[idx].require.amount[i] = atoi(split[14+ 2*i]);
|
||||
}
|
||||
|
||||
//require equiped
|
||||
memset(skill_db[idx].require.eqItem,0,sizeof(skill_db[idx].require.eqItem));
|
||||
p = strtok(split[33],":");
|
||||
for( i = 0; i < MAX_SKILL_EQUIP_REQUIRE && p != NULL; i++ ) {
|
||||
int itid = atoi(p);
|
||||
p = strtok(NULL,":"); //for easy continue don't read 'p' after this
|
||||
if(itid <= 0) continue; //silent
|
||||
if(itemdb_exists(itid)== NULL) {
|
||||
ShowWarning("Invalid reqIt=%d specified for skillid=%d\n",itid,skill_id);
|
||||
continue; //invalid id
|
||||
//Equipped Item requirements.
|
||||
//NOTE: We don't check the item is exist or not here
|
||||
trim(split[33]);
|
||||
if (split[33][0] != '\0') {
|
||||
int require[MAX_SKILL_EQUIP_REQUIRE];
|
||||
if ((skill_db[idx].require.eqItem_count = skill_split2(split[33],require,":",false,501))) {
|
||||
skill_db[idx].require.eqItem = aMalloc(skill_db[idx].require.eqItem_count * sizeof(short));
|
||||
for (i = 0; i < skill_db[idx].require.eqItem_count; i++)
|
||||
skill_db[idx].require.eqItem[i] = require[i];
|
||||
}
|
||||
skill_db[idx].require.eqItem[i] = itid;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -19046,6 +19079,7 @@ static void skill_readdb(void) {
|
||||
void skill_reload (void) {
|
||||
struct s_mapiterator *iter;
|
||||
struct map_session_data *sd;
|
||||
skill_destroy_requirement();
|
||||
skill_readdb();
|
||||
/* lets update all players skill tree : so that if any skill modes were changed they're properly updated */
|
||||
iter = mapit_getallusers();
|
||||
@ -19083,6 +19117,7 @@ int do_init_skill (void)
|
||||
|
||||
int do_final_skill(void)
|
||||
{
|
||||
skill_destroy_requirement();
|
||||
db_destroy(skilldb_name2id);
|
||||
db_destroy(group_db);
|
||||
db_destroy(skillunit_db);
|
||||
|
@ -119,10 +119,10 @@ struct skill_condition {
|
||||
state,
|
||||
spiritball,
|
||||
itemid[MAX_SKILL_ITEM_REQUIRE],
|
||||
amount[MAX_SKILL_ITEM_REQUIRE],
|
||||
eqItem[MAX_SKILL_EQUIP_REQUIRE]; //max eq_item
|
||||
uint8 status_count;
|
||||
enum sc_type status[MAX_SKILL_STATUS_REQUIRE];
|
||||
amount[MAX_SKILL_ITEM_REQUIRE];
|
||||
short *eqItem;
|
||||
enum sc_type *status;
|
||||
uint8 status_count, eqItem_count;
|
||||
};
|
||||
|
||||
struct s_skill_require {
|
||||
@ -138,10 +138,10 @@ struct s_skill_require {
|
||||
state,
|
||||
spiritball[MAX_SKILL_LEVEL],
|
||||
itemid[MAX_SKILL_ITEM_REQUIRE],
|
||||
amount[MAX_SKILL_ITEM_REQUIRE],
|
||||
eqItem[MAX_SKILL_EQUIP_REQUIRE]; //max eq_item
|
||||
uint8 status_count;
|
||||
enum sc_type status[MAX_SKILL_STATUS_REQUIRE];
|
||||
amount[MAX_SKILL_ITEM_REQUIRE];
|
||||
short *eqItem;
|
||||
enum sc_type *status;
|
||||
uint8 status_count, eqItem_count;
|
||||
};
|
||||
|
||||
/// Database skills
|
||||
@ -334,7 +334,7 @@ int skill_get_weapontype( uint16 skill_id );
|
||||
int skill_get_ammotype( uint16 skill_id );
|
||||
int skill_get_ammo_qty( uint16 skill_id, uint16 skill_lv );
|
||||
int skill_get_state(uint16 skill_id);
|
||||
int skill_get_status( uint16 skill_id, int idx );
|
||||
//int skill_get_status( uint16 skill_id, int idx );
|
||||
int skill_get_status_count( uint16 skill_id );
|
||||
int skill_get_spiritball( uint16 skill_id, uint16 skill_lv );
|
||||
int skill_get_itemid( uint16 skill_id, int idx );
|
||||
|
Loading…
x
Reference in New Issue
Block a user