Implemented official ammo equip behavior (#3438)
* Fixes #1155. * Added specific checks for weapons when equipping ammo. * Ammo is removed if the required weapon is removed. * Added battle configs to disable behavior. Thanks to @Atemo, @exneval, and @benching!
This commit is contained in:
parent
618fc37eab
commit
d3d8f3c5a7
@ -141,6 +141,14 @@ delay_battle_damage: yes
|
||||
// skills should consume ammo when it's acquired via a card or plagiarize)
|
||||
arrow_decrement: 1
|
||||
|
||||
// Should ammo be unequipped when unequipping a weapon?
|
||||
// Official behavior is "yes".
|
||||
ammo_unequip: yes
|
||||
|
||||
// Should a suitable weapon be equipped when equipping ammo?
|
||||
// Official behavior is "yes".
|
||||
ammo_check_weapon: yes
|
||||
|
||||
// Should the item script bonus 'Autospell' check for range/obstacles before casting?
|
||||
// Official behavior is "no", setting this to "yes" will make skills use their defined
|
||||
// range. For example, Sonic Blow requires a 2 cell distance before autocasting is allowed.
|
||||
|
@ -8141,6 +8141,8 @@ static const struct _battle_data {
|
||||
{ "natural_heal_weight_rate", &battle_config.natural_heal_weight_rate, 50, 0, 100 },
|
||||
{ "natural_heal_weight_rate_renewal", &battle_config.natural_heal_weight_rate_renewal,70, 0, 100 },
|
||||
{ "arrow_decrement", &battle_config.arrow_decrement, 1, 0, 2, },
|
||||
{ "ammo_unequip", &battle_config.ammo_unequip, 1, 0, 1, },
|
||||
{ "ammo_check_weapon", &battle_config.ammo_check_weapon, 1, 0, 1, },
|
||||
{ "max_aspd", &battle_config.max_aspd, 190, 100, 199, },
|
||||
{ "max_third_aspd", &battle_config.max_third_aspd, 193, 100, 199, },
|
||||
{ "max_walk_speed", &battle_config.max_walk_speed, 300, 100, 100*DEFAULT_WALK_SPEED, },
|
||||
|
@ -263,6 +263,8 @@ struct Battle_Config
|
||||
int natural_heal_weight_rate;
|
||||
int natural_heal_weight_rate_renewal;
|
||||
int arrow_decrement;
|
||||
int ammo_unequip;
|
||||
int ammo_check_weapon;
|
||||
int max_aspd;
|
||||
int max_walk_speed; //Maximum walking speed after buffs [Skotlex]
|
||||
int max_hp_lv99;
|
||||
|
@ -491,25 +491,29 @@ enum clif_messages : uint16_t {
|
||||
SKILL_CANT_USE_AREA = 0x536,
|
||||
ITEM_CANT_USE_AREA = 0x537,
|
||||
VIEW_EQUIP_FAIL = 0x54d,
|
||||
ITEM_NEED_MADOGEAR = 0x59b,
|
||||
ITEM_NEED_CART = 0x5ef,
|
||||
RUNE_CANT_CREATE = 0x61b,
|
||||
ITEM_CANT_COMBINE = 0x623,
|
||||
INVENTORY_SPACE_FULL = 0x625,
|
||||
ITEM_PRODUCE_SUCCESS = 0x627,
|
||||
ITEM_PRODUCE_FAIL = 0x628,
|
||||
ITEM_UNIDENTIFIED = 0x62d,
|
||||
ITEM_NEED_BOW = 0x69b,
|
||||
ITEM_REUSE_LIMIT = 0x746,
|
||||
WORK_IN_PROGRESS = 0x783,
|
||||
NEED_REINS_OF_MOUNT = 0x78c,
|
||||
PARTY_MASTER_CHANGE_SAME_MAP = 0x82e, ///< "It is only possible to change the party leader while on the same map."
|
||||
MERGE_ITEM_NOT_AVAILABLE = 0x887,
|
||||
GUILD_MASTER_WOE = 0xb93, /// <"Currently in WoE hours, unable to delegate Guild leader"
|
||||
GUILD_MASTER_DELAY = 0xb94, /// <"You have to wait for one day before delegating a new Guild leader"
|
||||
ITEM_BULLET_EQUIP_FAIL = 0x9bd,
|
||||
SKILL_NEED_GATLING = 0x9fa,
|
||||
SKILL_NEED_SHOTGUN = 0x9fb,
|
||||
SKILL_NEED_RIFLE = 0x9fc,
|
||||
SKILL_NEED_REVOLVER = 0x9fd,
|
||||
SKILL_NEED_HOLY_BULLET = 0x9fe,
|
||||
SKILL_NEED_GRENADE = 0xa01,
|
||||
GUILD_MASTER_WOE = 0xb93, /// <"Currently in WoE hours, unable to delegate Guild leader"
|
||||
GUILD_MASTER_DELAY = 0xb94, /// <"You have to wait for one day before delegating a new Guild leader"
|
||||
MSG_ATTENDANCE_DISABLED = 0xd92,
|
||||
};
|
||||
|
||||
|
304
src/map/pc.cpp
304
src/map/pc.cpp
@ -1122,6 +1122,51 @@ uint8 pc_isequip(struct map_session_data *sd,int n)
|
||||
if (!battle_config.allow_equip_restricted_item && itemdb_isNoEquip(item, sd->bl.m))
|
||||
return ITEM_EQUIP_ACK_FAIL;
|
||||
|
||||
if (item->equip&EQP_AMMO) {
|
||||
switch (item->look) {
|
||||
case AMMO_ARROW:
|
||||
if (battle_config.ammo_check_weapon && sd->status.weapon != W_BOW && sd->status.weapon != W_MUSICAL && sd->status.weapon != W_WHIP) {
|
||||
clif_msg(sd, ITEM_NEED_BOW);
|
||||
return ITEM_EQUIP_ACK_FAIL;
|
||||
}
|
||||
break;
|
||||
case AMMO_THROWABLE_DAGGER:
|
||||
if (!pc_checkskill(sd, AS_VENOMKNIFE))
|
||||
return ITEM_EQUIP_ACK_FAIL;
|
||||
break;
|
||||
case AMMO_BULLET:
|
||||
case AMMO_SHELL:
|
||||
if (battle_config.ammo_check_weapon && sd->status.weapon != W_REVOLVER && sd->status.weapon != W_RIFLE && sd->status.weapon != W_GATLING && sd->status.weapon != W_SHOTGUN
|
||||
#ifdef RENEWAL
|
||||
&& sd->status.weapon != W_GRENADE
|
||||
#endif
|
||||
) {
|
||||
clif_msg(sd, ITEM_BULLET_EQUIP_FAIL);
|
||||
return ITEM_EQUIP_ACK_FAIL;
|
||||
}
|
||||
break;
|
||||
#ifndef RENEWAL
|
||||
case AMMO_GRENADE:
|
||||
if (battle_config.ammo_check_weapon && sd->status.weapon != W_GRENADE) {
|
||||
clif_msg(sd, ITEM_BULLET_EQUIP_FAIL);
|
||||
return ITEM_EQUIP_ACK_FAIL;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case AMMO_CANNONBALL:
|
||||
if (!pc_ismadogear(sd) && (sd->status.class_ == JOB_MECHANIC_T || sd->status.class_ == JOB_MECHANIC)) {
|
||||
clif_msg(sd, ITEM_NEED_MADOGEAR); // Item can only be used when Mado Gear is mounted.
|
||||
return ITEM_EQUIP_ACK_FAIL;
|
||||
}
|
||||
if (sd->state.active && !pc_iscarton(sd) && //Check if sc data is already loaded
|
||||
(sd->status.class_ == JOB_GENETIC_T || sd->status.class_ == JOB_GENETIC)) {
|
||||
clif_msg(sd, ITEM_NEED_CART); // Only available when cart is mounted.
|
||||
return ITEM_EQUIP_ACK_FAIL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sd->sc.count) {
|
||||
if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_STRIPWEAPON]) // Also works with left-hand weapons [DracoRPG]
|
||||
return ITEM_EQUIP_ACK_FAIL;
|
||||
@ -9875,38 +9920,6 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((sd->class_&MAPID_BASEMASK) == MAPID_GUNSLINGER) {
|
||||
/** Failing condition:
|
||||
* 1. Always failed to equip ammo if no weapon equipped yet
|
||||
* 2. Grenade only can be equipped if weapon is Grenade Launcher
|
||||
* 3. Bullet cannot be equipped if the weapon is Grenade Launcher
|
||||
* (4. The rest is relying on item job/class restriction).
|
||||
**/
|
||||
if (id->type == IT_AMMO) {
|
||||
int w_idx = sd->equip_index[EQI_HAND_R];
|
||||
enum weapon_type w_type = (w_idx != -1) ? (enum weapon_type)sd->inventory_data[w_idx]->look : W_FIST;
|
||||
if (w_idx == -1 ||
|
||||
(id->look == A_GRENADE && w_type != W_GRENADE) ||
|
||||
(id->look != A_GRENADE && w_type == W_GRENADE))
|
||||
{
|
||||
clif_equipitemack(sd, 0, 0, ITEM_EQUIP_ACK_FAIL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (id->type == IT_WEAPON && id->look >= W_REVOLVER && id->look <= W_GRENADE) {
|
||||
int a_idx = sd->equip_index[EQI_AMMO];
|
||||
if (a_idx != -1) {
|
||||
enum ammo_type a_type = (enum ammo_type)sd->inventory_data[a_idx]->look;
|
||||
if ((a_type == A_GRENADE && id->look != W_GRENADE) ||
|
||||
(a_type != A_GRENADE && id->look == W_GRENADE))
|
||||
{
|
||||
clif_equipitemack(sd, 0, 0, ITEM_EQUIP_ACK_FAIL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (id->flag.bindOnEquip && !sd->inventory.u.items_inventory[n].bound) {
|
||||
sd->inventory.u.items_inventory[n].bound = (char)battle_config.default_bind_on_equip;
|
||||
clif_notify_bindOnEquip(sd,n);
|
||||
@ -9947,7 +9960,7 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos)
|
||||
for(i=0;i<EQI_MAX;i++) {
|
||||
if(pos & equip_bitmask[i]) {
|
||||
if(sd->equip_index[i] >= 0) //Slot taken, remove item from there.
|
||||
pc_unequipitem(sd,sd->equip_index[i],2);
|
||||
pc_unequipitem(sd,sd->equip_index[i],2 | 4);
|
||||
|
||||
sd->equip_index[i] = n;
|
||||
}
|
||||
@ -9990,6 +10003,34 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos)
|
||||
if(pos & EQP_SHOES)
|
||||
clif_changelook(&sd->bl,LOOK_SHOES,0);
|
||||
|
||||
if (battle_config.ammo_unequip && (pos&EQP_ARMS) && id->type == IT_WEAPON) {
|
||||
short idx = sd->equip_index[EQI_AMMO];
|
||||
|
||||
if (idx >= 0) {
|
||||
switch (sd->inventory_data[idx]->look) {
|
||||
case AMMO_ARROW:
|
||||
if (id->look != W_BOW && id->look != W_MUSICAL && id->look != W_WHIP)
|
||||
pc_unequipitem(sd, idx, 2 | 4);
|
||||
break;
|
||||
case AMMO_BULLET:
|
||||
case AMMO_SHELL:
|
||||
if (id->look != W_REVOLVER && id->look != W_RIFLE && id->look != W_GATLING && id->look != W_SHOTGUN
|
||||
#ifdef RENEWAL
|
||||
&& id->look != W_GRENADE
|
||||
#endif
|
||||
)
|
||||
pc_unequipitem(sd, idx, 2 | 4);
|
||||
break;
|
||||
#ifndef RENEWAL
|
||||
case AMMO_GRENADE:
|
||||
if (id->look != W_GRENADE)
|
||||
pc_unequipitem(sd, idx, 2 | 4);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pc_set_costume_view(sd);
|
||||
|
||||
pc_checkallowskill(sd); //Check if status changes should be halted.
|
||||
@ -10040,25 +10081,101 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Called when attemting to unequip an item from player
|
||||
* type:
|
||||
* 0 - only unequip
|
||||
* 1 - calculate status after unequipping
|
||||
* 2 - force unequip
|
||||
* return: false - fail; true - success
|
||||
*------------------------------------------*/
|
||||
bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
|
||||
/**
|
||||
* Recalculate player status on unequip
|
||||
* @param sd: Player data
|
||||
* @param n: Item inventory index
|
||||
* @param flag: Whether to recalculate a player's status or not
|
||||
* @return True on success or false on failure
|
||||
*/
|
||||
static void pc_unequipitem_sub(struct map_session_data *sd, int n, int flag) {
|
||||
int i, iflag;
|
||||
bool status_calc = false;
|
||||
|
||||
if (sd->state.autobonus&sd->inventory.u.items_inventory[n].equip)
|
||||
sd->state.autobonus &= ~sd->inventory.u.items_inventory[n].equip; //Check for activated autobonus [Inkfish]
|
||||
|
||||
sd->inventory.u.items_inventory[n].equip = 0;
|
||||
pc_checkallowskill(sd);
|
||||
iflag = sd->npc_item_flag;
|
||||
|
||||
/* check for combos (MUST be before status_calc_pc) */
|
||||
if (sd->inventory_data[n]) {
|
||||
if (sd->inventory_data[n]->combos_count) {
|
||||
if (pc_removecombo(sd, sd->inventory_data[n]))
|
||||
status_calc = true;
|
||||
}
|
||||
if (itemdb_isspecial(sd->inventory.u.items_inventory[n].card[0]))
|
||||
; //No cards
|
||||
else {
|
||||
for (i = 0; i < MAX_SLOTS; i++) {
|
||||
struct item_data *data;
|
||||
|
||||
if (!sd->inventory.u.items_inventory[n].card[i])
|
||||
continue;
|
||||
if ((data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i])) != NULL) {
|
||||
if (data->combos_count) {
|
||||
if (pc_removecombo(sd, data))
|
||||
status_calc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status_calc)
|
||||
status_calc_pc(sd, SCO_NONE);
|
||||
|
||||
if (sd->sc.data[SC_SIGNUMCRUCIS] && !battle_check_undead(sd->battle_status.race, sd->battle_status.def_ele))
|
||||
status_change_end(&sd->bl, SC_SIGNUMCRUCIS, INVALID_TIMER);
|
||||
|
||||
//OnUnEquip script [Skotlex]
|
||||
if (sd->inventory_data[n]) {
|
||||
if (sd->inventory_data[n]->unequip_script)
|
||||
run_script(sd->inventory_data[n]->unequip_script, 0, sd->bl.id, fake_nd->bl.id);
|
||||
if (itemdb_isspecial(sd->inventory.u.items_inventory[n].card[0]))
|
||||
; //No cards
|
||||
else {
|
||||
for (i = 0; i < MAX_SLOTS; i++) {
|
||||
struct item_data *data;
|
||||
if (!sd->inventory.u.items_inventory[n].card[i])
|
||||
continue;
|
||||
|
||||
if ((data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i])) != NULL) {
|
||||
if (data->unequip_script)
|
||||
run_script(data->unequip_script, 0, sd->bl.id, fake_nd->bl.id);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag & 1)
|
||||
status_calc_pc(sd, SCO_FORCE);
|
||||
sd->npc_item_flag = iflag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when attempting to unequip an item from a player
|
||||
* @param sd: Player data
|
||||
* @param n: Item inventory index
|
||||
* @param flag: Type of unequip
|
||||
* 0 - only unequip
|
||||
* 1 - calculate status after unequipping
|
||||
* 2 - force unequip
|
||||
* 4 - unequip by switching equipment
|
||||
* @return True on success or false on failure
|
||||
*/
|
||||
bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
|
||||
int i, pos;
|
||||
|
||||
nullpo_retr(false,sd);
|
||||
|
||||
if (n < 0 || n >= MAX_INVENTORY) {
|
||||
clif_unequipitemack(sd,0,0,0);
|
||||
return false;
|
||||
}
|
||||
if (!sd->inventory.u.items_inventory[n].equip) {
|
||||
if (!(pos = sd->inventory.u.items_inventory[n].equip)) {
|
||||
clif_unequipitemack(sd,n,0,0);
|
||||
return false; //Nothing to unequip
|
||||
}
|
||||
@ -10076,18 +10193,14 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
|
||||
}
|
||||
|
||||
if (battle_config.battle_log)
|
||||
ShowInfo("unequip %d %x:%x\n",n,pc_equippoint(sd,n),sd->inventory.u.items_inventory[n].equip);
|
||||
ShowInfo("unequip %d %x:%x\n",n,pc_equippoint(sd,n),pos);
|
||||
|
||||
if (!sd->inventory.u.items_inventory[n].equip) { //Nothing to unequip
|
||||
clif_unequipitemack(sd, n, 0, 0);
|
||||
return false;
|
||||
}
|
||||
for(i = 0; i < EQI_MAX; i++) {
|
||||
if (sd->inventory.u.items_inventory[n].equip & equip_bitmask[i])
|
||||
if (pos & equip_bitmask[i])
|
||||
sd->equip_index[i] = -1;
|
||||
}
|
||||
|
||||
if(sd->inventory.u.items_inventory[n].equip & EQP_HAND_R) {
|
||||
if(pos & EQP_HAND_R) {
|
||||
sd->weapontype1 = 0;
|
||||
sd->status.weapon = sd->weapontype2;
|
||||
pc_calcweapontype(sd);
|
||||
@ -10095,7 +10208,7 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
|
||||
if( !battle_config.dancing_weaponswitch_fix )
|
||||
status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); // Unequipping => stop dancing.
|
||||
}
|
||||
if(sd->inventory.u.items_inventory[n].equip & EQP_HAND_L) {
|
||||
if(pos & EQP_HAND_L) {
|
||||
if (sd->status.shield && battle_getcurrentskill(&sd->bl) == LG_SHIELDSPELL)
|
||||
unit_skillcastcancel(&sd->bl, 0); // Cancel Shield Spell if player swaps shields.
|
||||
|
||||
@ -10104,15 +10217,36 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
|
||||
clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
|
||||
}
|
||||
|
||||
if(sd->inventory.u.items_inventory[n].equip & EQP_SHOES)
|
||||
if(pos & EQP_SHOES)
|
||||
clif_changelook(&sd->bl,LOOK_SHOES,0);
|
||||
|
||||
clif_unequipitemack(sd,n,sd->inventory.u.items_inventory[n].equip,1);
|
||||
clif_unequipitemack(sd,n,pos,1);
|
||||
pc_set_costume_view(sd);
|
||||
|
||||
status_change_end(&sd->bl,SC_HEAT_BARREL,INVALID_TIMER);
|
||||
// On weapon change (right and left hand)
|
||||
if ((sd->inventory.u.items_inventory[n].equip & EQP_ARMS) && sd->inventory_data[n]->type == IT_WEAPON) {
|
||||
if ((pos & EQP_ARMS) && sd->inventory_data[n]->type == IT_WEAPON) {
|
||||
if (battle_config.ammo_unequip && !(flag & 4)) {
|
||||
switch (sd->inventory_data[n]->look) {
|
||||
case W_BOW:
|
||||
case W_MUSICAL:
|
||||
case W_WHIP:
|
||||
case W_REVOLVER:
|
||||
case W_RIFLE:
|
||||
case W_GATLING:
|
||||
case W_SHOTGUN:
|
||||
case W_GRENADE: {
|
||||
short idx = sd->equip_index[EQI_AMMO];
|
||||
|
||||
if (idx >= 0) {
|
||||
sd->equip_index[EQI_AMMO] = -1;
|
||||
clif_unequipitemack(sd, idx, sd->inventory.u.items_inventory[idx].equip, 1);
|
||||
pc_unequipitem_sub(sd, idx, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!sd->sc.data[SC_SEVENWIND] || sd->sc.data[SC_ASPERSIO]) //Check for seven wind (but not level seven!)
|
||||
skill_enchant_elemental_end(&sd->bl, SC_NONE);
|
||||
status_change_end(&sd->bl, SC_FEARBREEZE, INVALID_TIMER);
|
||||
@ -10120,7 +10254,7 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
|
||||
}
|
||||
|
||||
// On armor change
|
||||
if (sd->inventory.u.items_inventory[n].equip & EQP_ARMOR) {
|
||||
if (pos & EQP_ARMOR) {
|
||||
if (sd->sc.data[SC_HOVERING] && sd->inventory_data[n]->nameid == ITEMID_HOVERING_BOOSTER)
|
||||
status_change_end(&sd->bl, SC_HOVERING, INVALID_TIMER);
|
||||
//status_change_end(&sd->bl, SC_BENEDICTIO, INVALID_TIMER); // No longer is removed? Need confirmation
|
||||
@ -10131,65 +10265,7 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) {
|
||||
if (sd->inventory_data[n]->type == IT_AMMO && (sd->inventory_data[n]->nameid != ITEMID_SILVER_BULLET || sd->inventory_data[n]->nameid != ITEMID_PURIFICATION_BULLET || sd->inventory_data[n]->nameid != ITEMID_SILVER_BULLET_))
|
||||
status_change_end(&sd->bl, SC_P_ALTER, INVALID_TIMER);
|
||||
|
||||
if (sd->state.autobonus&sd->inventory.u.items_inventory[n].equip)
|
||||
sd->state.autobonus &= ~sd->inventory.u.items_inventory[n].equip; //Check for activated autobonus [Inkfish]
|
||||
|
||||
sd->inventory.u.items_inventory[n].equip = 0;
|
||||
iflag = sd->npc_item_flag;
|
||||
|
||||
/* check for combos (MUST be before status_calc_pc) */
|
||||
if ( sd->inventory_data[n] ) {
|
||||
if( sd->inventory_data[n]->combos_count ) {
|
||||
if( pc_removecombo(sd,sd->inventory_data[n]) )
|
||||
status_calc = true;
|
||||
}
|
||||
if(itemdb_isspecial(sd->inventory.u.items_inventory[n].card[0]))
|
||||
; //No cards
|
||||
else {
|
||||
for( i = 0; i < MAX_SLOTS; i++ ) {
|
||||
struct item_data *data;
|
||||
|
||||
if (!sd->inventory.u.items_inventory[n].card[i])
|
||||
continue;
|
||||
if ( ( data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i]) ) != NULL ) {
|
||||
if( data->combos_count ) {
|
||||
if( pc_removecombo(sd,data) )
|
||||
status_calc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(flag&1 || status_calc) {
|
||||
pc_checkallowskill(sd);
|
||||
status_calc_pc(sd,SCO_NONE);
|
||||
}
|
||||
|
||||
if(sd->sc.data[SC_SIGNUMCRUCIS] && !battle_check_undead(sd->battle_status.race,sd->battle_status.def_ele))
|
||||
status_change_end(&sd->bl, SC_SIGNUMCRUCIS, INVALID_TIMER);
|
||||
|
||||
//OnUnEquip script [Skotlex]
|
||||
if (sd->inventory_data[n]) {
|
||||
if (sd->inventory_data[n]->unequip_script)
|
||||
run_script(sd->inventory_data[n]->unequip_script,0,sd->bl.id,fake_nd->bl.id);
|
||||
if(itemdb_isspecial(sd->inventory.u.items_inventory[n].card[0]))
|
||||
; //No cards
|
||||
else {
|
||||
for( i = 0; i < MAX_SLOTS; i++ ) {
|
||||
struct item_data *data;
|
||||
if (!sd->inventory.u.items_inventory[n].card[i])
|
||||
continue;
|
||||
|
||||
if ( ( data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i]) ) != NULL ) {
|
||||
if( data->unequip_script )
|
||||
run_script(data->unequip_script,0,sd->bl.id,fake_nd->bl.id);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
sd->npc_item_flag = iflag;
|
||||
pc_unequipitem_sub(sd, n, flag);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user