- Follow up a8a4425 (bugreport:9062)

- Added check for item group ID usage on item bonus
- Moved this '(sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id, MAPID_TAEKWON)' to a macro 'pc_is_taekwon_ranker(sd)'

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
Cydh Ramdh 2014-06-26 22:12:19 +07:00
parent fff4877004
commit e7b654aaab
7 changed files with 54 additions and 40 deletions

View File

@ -18,18 +18,28 @@
#include <stdlib.h>
#include <string.h>
struct item_data *dummy_item; /// This is the default dummy item used for non-existant items. [Skotlex]
static DBMap* itemdb; /// Item DB
static DBMap *itemdb; /// Item DB
static DBMap *itemdb_combo; /// Item Combo DB
static DBMap *itemdb_group; /// Item Group DB
DBMap * itemdb_get_combodb(){
return itemdb_combo;
struct item_data *dummy_item; /// This is the default dummy item used for non-existant items. [Skotlex]
/**
* Check if combo exists
* @param combo_id
* @return NULL if not exist, or struct item_combo*
*/
struct item_combo *itemdb_combo_exists(unsigned short combo_id) {
return (struct item_combo *)idb_get(itemdb_combo, combo_id);
}
DBMap * itemdb_get_groupdb() {
return itemdb_group;
/**
* Check if item group exists
* @param group_id
* @return NULL if not exist, or s_item_group_db *
*/
struct s_item_group_db *itemdb_group_exists(unsigned short group_id) {
return (struct s_item_group_db *)idb_get(itemdb_group, group_id);
}
/**
@ -44,17 +54,15 @@ static int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap)
str = va_arg(ap,char *);
dst = va_arg(ap,struct item_data **);
dst2 = va_arg(ap,struct item_data **);
if (item == dummy_item)
return 0;
//Absolute priority to Aegis code name.
if (*dst != NULL)
return 0;
if (strcmpi(item->name,str) == 0)
*dst = item;
//Second priority to Client displayed name.
if (*dst2 != NULL) return 0;
if (strcmpi(item->jname,str) == 0)
*dst2 = item;
return 0;
@ -67,8 +75,7 @@ static int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap)
*------------------------------------------*/
struct item_data* itemdb_searchname(const char *str)
{
struct item_data* item = NULL;
struct item_data* item2 = NULL;
struct item_data *item = NULL, * item2 = NULL;
itemdb->foreach(itemdb,itemdb_searchname_sub,str,&item,&item2);
return item ? item : item2;
@ -82,8 +89,10 @@ static int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap)
struct item_data *item = db_data2ptr(&data);
char *str;
str = va_arg(ap,char *);
if (item == dummy_item)
return 1; //Invalid item.
if (item && dummy_item)
return 1;
if (stristr(item->jname,str))
return 0;
if (stristr(item->name,str))
@ -369,8 +378,7 @@ static void itemdb_jobid2mapid(unsigned int *bclass, unsigned int jobmask)
/**
* Create dummy item data
*/
static void create_dummy_data(void)
{
static void create_dummy_data(void) {
CREATE(dummy_item, struct item_data, 1);
memset(dummy_item, 0, sizeof(struct item_data));
@ -381,6 +389,7 @@ static void create_dummy_data(void)
safestrncpy(dummy_item->name, "UNKNOWN_ITEM", sizeof(dummy_item->name));
safestrncpy(dummy_item->jname, "Unknown Item", sizeof(dummy_item->jname));
dummy_item->view_id = UNKNOWN_ITEM_ID;
idb_put(itemdb, dummy_item->nameid, dummy_item);
}
/*==========================================
@ -392,7 +401,8 @@ struct item_data* itemdb_search(unsigned short nameid) {
struct item_data* id = (struct item_data*)idb_get(itemdb, nameid);
if (id)
return id;
ShowWarning("itemdb_search: Item ID %hu does not exists in the item_db. Using dummy data.\n", nameid);
if (nameid != dummy_item->nameid) // Avoid previous item that assigned with dummy_item to shows this message again
ShowWarning("itemdb_search: Item ID %hu does not exists in the item_db. Using dummy data.\n", nameid);
return dummy_item;
}
@ -1674,10 +1684,10 @@ void itemdb_reload(void) {
* Finalizing Item DB
*/
void do_final_itemdb(void) {
db_destroy(itemdb_combo);
itemdb_group->destroy(itemdb_group, itemdb_group_free);
itemdb->destroy(itemdb, itemdb_final_sub);
destroy_item_data(dummy_item);
db_destroy(itemdb_combo);
}
/**
@ -1687,7 +1697,6 @@ void do_init_itemdb(void) {
itemdb = idb_alloc(DB_OPT_BASE);
itemdb_combo = idb_alloc(DB_OPT_BASE);
itemdb_group = idb_alloc(DB_OPT_BASE);
create_dummy_data(); //Dummy data item.
create_dummy_data(); //Dummy data item.
itemdb_read();
}

View File

@ -482,12 +482,12 @@ bool itemdb_isstackable2(struct item_data *id);
uint64 itemdb_unique_id(int8 flag, int64 value); // Unique Item ID
bool itemdb_isNoEquip(struct item_data *id, uint16 m);
struct item_combo *itemdb_combo_exists(unsigned short combo_id);
struct s_item_group_db *itemdb_group_exists(unsigned short group_id);
char itemdb_pc_get_itemgroup(uint16 group_id, struct map_session_data *sd);
uint16 itemdb_get_randgroupitem_count(uint16 group_id, uint8 sub_group, unsigned short nameid);
DBMap * itemdb_get_combodb();
DBMap * itemdb_get_groupdb();
void itemdb_reload(void);
void do_final_itemdb(void);

View File

@ -2436,7 +2436,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
for (i = 0; i < ARRAYLENGTH(sd->add_drop); i++) {
if (!&sd->add_drop[i] || (!sd->add_drop[i].nameid && !sd->add_drop[i].group))
continue;
if ((sd->add_drop[i].race < 0 && sd->add_drop[i].race == -md->mob_id) || //Race < 0, use mob_id
if ((sd->add_drop[i].race < RC_NONE_ && sd->add_drop[i].race == -md->mob_id) || //Race < 0, use mob_id
(sd->add_drop[i].race == RC_ALL || sd->add_drop[i].race == status->race) || //Matched race
(sd->add_drop[i].class_ == CLASS_ALL || sd->add_drop[i].class_ == status->class_)) //Matched class
{

View File

@ -401,7 +401,7 @@ void pc_addfame(struct map_session_data *sd,int count)
}
/**
* Check whether a player ID is in the fame rankers' list of its job, returns his/her position if so, 0 else
* Check whether a player ID is in the fame rankers list of its job, returns his/her position if so, 0 else
* @param sd
* @param job Job use enum e_mapid
* @return Rank
@ -1654,7 +1654,7 @@ void pc_calc_skilltree(struct map_session_data *sd)
}
} while(flag);
if( c > 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && sd->status.skill_point == 0 && pc_famerank(sd->status.char_id, MAPID_TAEKWON) ) {
if( c > 0 && sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) ) {
/* Taekwon Ranker Bonus Skill Tree
============================================
- Grant All Taekwon Tree, but only as Bonus Skills in case they drop from ranking.
@ -2031,10 +2031,16 @@ static void pc_bonus_addeff_onskill(struct s_addeffectonskill* effect, int max,
static void pc_bonus_item_drop(struct s_add_drop *drop, const short max, unsigned short nameid, uint16 group, int class_, short race, int rate)
{
uint8 i;
if (nameid && !group && !itemdb_exists(nameid)) {
struct s_item_group_db *group_ = NULL;
if (nameid && !itemdb_exists(nameid)) {
ShowWarning("pc_bonus_item_drop: Invalid item id %hu\n",nameid);
return;
}
if (!group || (group_ = itemdb_group_exists(group)) == NULL) {
ShowWarning("pc_bonus_item_drop: Invalid Item Group %hu\n",group);
return;
}
//Apply config rate adjustment settings.
if (rate >= 0) { //Absolute drop.
if (battle_config.item_rate_adddrop != 100)
@ -3382,8 +3388,7 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
case SP_ADD_ITEMGROUP_HEAL_RATE:
{
struct s_item_group_db *group = (struct s_item_group_db *) idb_get(itemdb_get_groupdb(), type2);
if (!group) {
if (!type2 || !itemdb_group_exists(type)) {
ShowError("pc_bonus2: SP_ADD_ITEMGROUP_HEAL_RATE Invalid item group with id %d\n", type2);
break;
}
@ -6624,7 +6629,7 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id)
sd->status.skill_point--;
if( !skill_get_inf(skill_id) )
status_calc_pc(sd,SCO_NONE); // Only recalculate for passive skills.
else if( sd->status.skill_point == 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id, MAPID_TAEKWON) )
else if( sd->status.skill_point == 0 && pc_is_taekwon_ranker(sd) )
pc_calc_skilltree(sd); // Required to grant all TK Ranker skills.
else
pc_check_skilltree(sd, skill_id); // Check if a new skill can Lvlup
@ -6866,11 +6871,10 @@ int pc_resetskill(struct map_session_data* sd, int flag)
return 0;
if( !(flag&2) ) { //Remove stuff lost when resetting skills.
/**
* It has been confirmed on official servers that when you reset skills with a ranked Taekwon your skills are not reset (because you have all of them anyway)
**/
if( (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id, MAPID_TAEKWON) )
if( pc_is_taekwon_ranker(sd) )
return 0;
if( pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd) )
@ -11012,8 +11016,8 @@ short pc_get_itemgroup_bonus(struct map_session_data* sd, unsigned short nameid)
return bonus;
for (i = 0; i < sd->itemgrouphealrate_count; i++) {
uint16 group_id = sd->itemgrouphealrate[i]->group_id, j;
struct s_item_group_db *group = (struct s_item_group_db *) idb_get(itemdb_get_groupdb(), group_id);
if (!group)
struct s_item_group_db *group = NULL;
if (!group_id || !(group = itemdb_group_exists(group_id)))
continue;
for (j = 0; j < group->random[0].data_qty; j++) {

View File

@ -1107,6 +1107,8 @@ short pc_get_itemgroup_bonus(struct map_session_data* sd, unsigned short nameid)
short pc_get_itemgroup_bonus_group(struct map_session_data* sd, uint16 group_id);
bool pc_is_same_equip_index(enum equip_index eqi, int *equip_index, int8 index);
/// Check if player is Taekwon Ranker and the level is >= 90 (battle_config.taekwon_ranker_min_lv)
#define pc_is_taekwon_ranker(sd) (((sd)->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && (sd)->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank((sd)->status.char_id,MAPID_TAEKWON))
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_class, int type);

View File

@ -13917,7 +13917,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER);
return false;
}
if(sc->data[SC_COMBO]->val1 != skill_id && !( sd && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id, MAPID_TAEKWON) )) { //Cancel combo wait.
if(sc->data[SC_COMBO]->val1 != skill_id && !pc_is_taekwon_ranker(sd)) { //Cancel combo wait.
unit_cancel_combo(&sd->bl);
return false;
}

View File

@ -2609,7 +2609,7 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
bonus -= 100; //Default hprate is 100, so it should be add 0%
//+200% for top ranking Taekwons over level 90.
if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id,MAPID_TAEKWON))
if (pc_is_taekwon_ranker(sd))
bonus += 200;
}
@ -2720,7 +2720,7 @@ static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) {
bonus += 2 * i;
//+200% for top ranking Taekwons over level 90.
if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= battle_config.taekwon_ranker_min_lv && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
if (pc_is_taekwon_ranker(sd))
bonus += 200;
}
@ -3050,13 +3050,12 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
// We've got combos to process and check
if( sd->combos.count ) {
DBMap *combo_db = itemdb_get_combodb();
for (i = 0; i < sd->combos.count; i++) {
uint8 j = 0;
bool no_run = false;
struct item_combo *combo = (struct item_combo *)idb_get(combo_db,sd->combos.id[i]);
struct item_combo *combo = NULL;
if (!sd->combos.bonus[i])
if (!sd->combos.bonus[i] || !(combo = itemdb_combo_exists(sd->combos.id[i])))
continue;
// Check combo items
while (j < combo->count) {