From 7d72060430134f33d3f4e6cb70d12b325dc695b5 Mon Sep 17 00:00:00 2001 From: Cahyadi Ramadhan Togihon Date: Wed, 4 Sep 2013 12:17:20 +0700 Subject: [PATCH] * Follow-up 15074d8 - Fix item restriction check that should only prevent the item script. ATK, DEF, and MATK for RE should be calculated (Thank Euphy) - Added item restriction check for combo items - Added some missing item restriction checks --- src/map/itemdb.h | 14 +++++++------- src/map/map.h | 2 +- src/map/pc.c | 23 ++++++++++++++++++----- src/map/pc.h | 8 ++++++++ src/map/skill.h | 2 +- src/map/status.c | 41 ++++++++++++++++++++++++++++++----------- 6 files changed, 65 insertions(+), 25 deletions(-) diff --git a/src/map/itemdb.h b/src/map/itemdb.h index d4a3690d0b..43472ca7f0 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -40,7 +40,7 @@ enum item_itemid { * Rune Knight **/ -enum { +enum rune_list { ITEMID_NAUTHIZ = 12725, ITEMID_RAIDO, ITEMID_BERKANA, @@ -50,12 +50,12 @@ enum { ITEMID_THURISAZ, ITEMID_WYRD, ITEMID_HAGALAZ, -} rune_list; +}; /** * Mechanic **/ -enum { +enum mecha_item_list { ITEMID_ACCELERATOR = 2800, ITEMID_HOVERING_BOOSTER, ITEMID_SUICIDAL_DEVICE, @@ -67,11 +67,11 @@ enum { ITEMID_CAMOUFLAGE_GENERATOR, ITEMID_HIGH_QUALITY_COOLER, ITEMID_SPECIAL_COOLER, -} mecha_item_list; +}; -enum { +enum item_nouse_list { NOUSE_SITTING = 0x01, -} item_nouse_list; +}; enum e_item_job { ITEMJ_NORMAL = 0x01, @@ -137,7 +137,7 @@ struct item_data { struct script_code *unequip_script;//Script executed once when unequipping. struct { unsigned available : 1; - short no_equip; + uint32 no_equip; unsigned no_refine : 1; // [celest] unsigned delay_consume : 1; // Signifies items that are not consumed immediately upon double-click [Skotlex] unsigned trade_restriction : 9; //Item restrictions mask [Skotlex] diff --git a/src/map/map.h b/src/map/map.h index da82c718ad..8454c4c2e0 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -612,7 +612,7 @@ struct map_data { struct spawn_data *moblist[MAX_MOB_LIST_PER_MAP]; // [Wizputer] int mob_delete_timer; // [Skotlex] - int zone; // zone number (for item/skill restrictions) + uint32 zone; // zone number (for item/skill restrictions) int nocommand; //Blocks @/# commands for non-gms. [Skotlex] struct { int jexp; // map experience multiplicator diff --git a/src/map/pc.c b/src/map/pc.c index 664039828e..87493373ed 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -8458,6 +8458,8 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { int index, idx, success = 0; for( i = 0; i < data->combos_count; i++ ) { + struct s_combo_pair *pair; + uint8 pair_idx = 0; /* ensure this isn't a duplicate combo */ if( sd->combos.bonus != NULL ) { @@ -8469,6 +8471,7 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { continue; } + CREATE(pair,struct s_combo_pair,1); for( j = 0; j < data->combos[i]->count; j++ ) { int id = data->combos[i]->nameid[j]; bool found = false; @@ -8488,6 +8491,8 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { continue; found = true; + pair->nameid[pair_idx] = id; + pair_idx ++; break; } else { //Cards if ( sd->inventory_data[index]->slot == 0 || itemdb_isspecial(sd->status.inventory[index].card[0]) ) @@ -8500,6 +8505,8 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { // We have found a match found = true; + pair->nameid[pair_idx] = id; + pair_idx ++; break; } } @@ -8515,22 +8522,24 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { continue; /* we got here, means all items in the combo are matching */ - idx = sd->combos.count; - if( sd->combos.bonus == NULL ) { CREATE(sd->combos.bonus, struct script_code *, 1); CREATE(sd->combos.id, unsigned short, 1); sd->combos.count = 1; + CREATE(sd->combos.pair, struct s_combo_pair *, 1); } else { RECREATE(sd->combos.bonus, struct script_code *, ++sd->combos.count); RECREATE(sd->combos.id, unsigned short, sd->combos.count); + RECREATE(sd->combos.pair, struct s_combo_pair *, sd->combos.count); } - /* we simply copy the pointer */ sd->combos.bonus[idx] = data->combos[i]->script; /* save this combo's id */ sd->combos.id[idx] = data->combos[i]->id; + /* store the items id that trigger this combo */ + memcpy(&sd->combos.pair[idx], pair, sizeof(pair)); + aFree(pair); success++; } @@ -8553,7 +8562,10 @@ int pc_removecombo(struct map_session_data *sd, struct item_data *data ) { sd->combos.bonus[x] = NULL; sd->combos.id[x] = 0; + sd->combos.pair[x] = NULL; retval++; + + /* move next value to empty slot */ for( j = 0, cursor = 0; j < sd->combos.count; j++ ) { if( sd->combos.bonus[j] == NULL ) continue; @@ -8561,8 +8573,8 @@ int pc_removecombo(struct map_session_data *sd, struct item_data *data ) { if( cursor != j ) { sd->combos.bonus[cursor] = sd->combos.bonus[j]; sd->combos.id[cursor] = sd->combos.id[j]; + sd->combos.pair[cursor] = sd->combos.pair[j]; } - cursor++; } @@ -8574,11 +8586,12 @@ int pc_removecombo(struct map_session_data *sd, struct item_data *data ) { if( (sd->combos.count = cursor) == 0 ) { aFree(sd->combos.bonus); aFree(sd->combos.id); + aFree(sd->combos.pair); sd->combos.bonus = NULL; sd->combos.id = NULL; + sd->combos.pair = NULL; return retval; /* we also can return at this point for we have no more combos to check */ } - } return retval; diff --git a/src/map/pc.h b/src/map/pc.h index 788d7432f1..a6753b4929 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -121,6 +121,13 @@ enum npc_timeout_type { NPCT_WAIT = 2, }; +/* + * Combo's items + */ +struct s_combo_pair { + uint16 nameid[MAX_ITEMS_PER_COMBO]; +}; + struct map_session_data { struct block_list bl; struct unit_data ud; @@ -504,6 +511,7 @@ struct map_session_data { struct script_code **bonus;/* the script */ unsigned short *id;/* array of combo ids */ unsigned char count; + struct s_combo_pair **pair; } combos; /** diff --git a/src/map/skill.h b/src/map/skill.h index 61fbbd5f57..cdfa5a2578 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -126,7 +126,7 @@ struct s_skill_db { int weapon,ammo,ammo_qty[MAX_SKILL_LEVEL],state,spiritball[MAX_SKILL_LEVEL]; int itemid[MAX_SKILL_ITEM_REQUIRE],amount[MAX_SKILL_ITEM_REQUIRE]; int castnodex[MAX_SKILL_LEVEL], delaynodex[MAX_SKILL_LEVEL]; - int nocast; + int32 nocast; int unit_id[2]; int unit_layout_type[MAX_SKILL_LEVEL]; int unit_range[MAX_SKILL_LEVEL]; diff --git a/src/map/status.c b/src/map/status.c index 8fec5cd47b..69347e6956 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2461,12 +2461,10 @@ int status_calc_pc_(struct map_session_data* sd, bool first) if(!sd->inventory_data[index]) continue; - if(!pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(sd->inventory_data[index],sd->bl.m)) // Items may be equipped, their effects however are nullified. - continue; - status->def += sd->inventory_data[index]->def; - if(first && sd->inventory_data[index]->equip_script) + // Items may be equipped, their effects however are nullified. + if(first && sd->inventory_data[index]->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(sd->inventory_data[index],sd->bl.m))) { //Execute equip-script on login run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0); if (!calculating) @@ -2506,7 +2504,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) wd->overrefine = refine_info[wlv].randombonus_max[r-1] / 100; wa->range += sd->inventory_data[index]->range; - if(sd->inventory_data[index]->script) { + if(sd->inventory_data[index]->script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(sd->inventory_data[index],sd->bl.m))) { if (wd == &sd->left_weapon) { sd->state.lr_flag = 1; run_script(sd->inventory_data[index]->script,0,sd->bl.id,0); @@ -2532,7 +2530,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) int r; if ( (r = sd->status.inventory[index].refine) ) refinedef += refine_info[REFINE_TYPE_ARMOR].bonus[r-1]; - if(sd->inventory_data[index]->script) { + if(sd->inventory_data[index]->script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(sd->inventory_data[index],sd->bl.m))) { if( i == EQI_HAND_L ) //Shield sd->state.lr_flag = 3; run_script(sd->inventory_data[index]->script,0,sd->bl.id,0); @@ -2557,9 +2555,31 @@ int status_calc_pc_(struct map_session_data* sd, bool first) } } - /* we've got combos to process */ + /* we've got combos to process and check */ if( sd->combos.count ) { - for( i = 0; i < sd->combos.count; i++ ) { + for (i = 0; i < sd->combos.count; i++) { + uint8 j; + bool no_run = false; + struct s_combo_pair *ids; + if (!sd->combos.bonus[i]) + continue; + /* check combo items */ + CREATE(ids,struct s_combo_pair,1); + memcpy(ids, &sd->combos.pair[i], sizeof(ids)); + for (j = 0; j < MAX_ITEMS_PER_COMBO; j++) { + uint16 nameid = ids->nameid[j]; + struct item_data *id = NULL; + if (!nameid || !(id = itemdb_exists(nameid))) + continue; + /* don't run the script if the items has restriction */ + if (!pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(id, sd->bl.m)) { + no_run = true; + break; + } + } + aFree(ids); + if (no_run) + continue; run_script(sd->combos.bonus[i],0,sd->bl.id,0); if (!calculating) //Abort, run_script retriggered this. return 1; @@ -2598,7 +2618,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) data = itemdb_exists(c); if(!data) continue; - if(first && data->equip_script) {//Execute equip-script on login + if(first && data->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(data,sd->bl.m))) {//Execute equip-script on login run_script(data->equip_script,0,sd->bl.id,0); if (!calculating) return 1; @@ -2607,8 +2627,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) continue; if(!pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(data,sd->bl.m)) //Card restriction checks. continue; - if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) - { //Left hand status. + if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) { //Left hand status. sd->state.lr_flag = 1; run_script(data->script,0,sd->bl.id,0); sd->state.lr_flag = 0;