* 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
This commit is contained in:
Cahyadi Ramadhan Togihon 2013-09-04 12:17:20 +07:00
parent a705e67684
commit 7d72060430
6 changed files with 65 additions and 25 deletions

View File

@ -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]

View File

@ -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

View File

@ -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;

View File

@ -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;
/**

View File

@ -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];

View File

@ -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;