diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 45 | ||||
-rw-r--r-- | src/map/clif.c | 20 | ||||
-rw-r--r-- | src/map/itemdb.c | 117 | ||||
-rw-r--r-- | src/map/itemdb.h | 12 | ||||
-rw-r--r-- | src/map/pc.c | 246 | ||||
-rw-r--r-- | src/map/pc.h | 14 | ||||
-rw-r--r-- | src/map/script.c | 239 | ||||
-rw-r--r-- | src/map/skill.c | 14 | ||||
-rw-r--r-- | src/map/status.c | 51 |
9 files changed, 488 insertions, 270 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index b5ad62407..2861599b8 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -875,7 +875,7 @@ int64 battle_calc_masteryfix(struct block_list *src, struct block_list *target, } #else if( skill_id != ASC_BREAKER && weapon ) // Adv Katar Mastery is does not applies to ASC_BREAKER, but other masteries DO apply >_> - if( sd->status.weapon == W_KATAR && (skill2_lv=pc->checkskill(sd,ASC_KATAR)) > 0 ) + if (sd->weapontype == W_KATAR && (skill2_lv=pc->checkskill(sd,ASC_KATAR)) > 0) damage += damage * (10 + 2 * skill2_lv) / 100; #endif @@ -2032,7 +2032,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += 100 + 100 * skill_lv + 100 * (skill_lv / 2); break; case RG_BACKSTAP: - if( sd && sd->status.weapon == W_BOW && battle_config.backstab_bow_penalty ) + if (sd != NULL && sd->weapontype == W_BOW && battle_config.backstab_bow_penalty) skillratio += (200 + 40 * skill_lv) / 2; else skillratio += 200 + 40 * skill_lv; @@ -2053,10 +2053,10 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block case CR_HOLYCROSS: { int ratio = 35 * skill_lv; - #ifdef RENEWAL - if(sd && sd->status.weapon == W_2HSPEAR) - ratio *= 2; - #endif +#ifdef RENEWAL + if (sd != NULL && sd->weapontype == W_2HSPEAR) + ratio *= 2; +#endif skillratio += ratio; break; } @@ -2714,7 +2714,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += 2*sc->data[SC_TRUESIGHT]->val1; if( sc->data[SC_LKCONCENTRATION] ) skillratio += sc->data[SC_LKCONCENTRATION]->val2; - if( sd && sd->status.weapon == W_KATAR && (i=pc->checkskill(sd,ASC_KATAR)) > 0 ) + if (sd != NULL && sd->weapontype == W_KATAR && (i=pc->checkskill(sd,ASC_KATAR)) > 0) skillratio += skillratio * (10 + 2 * i) / 100; #endif if( (!skill_id || skill_id == KN_AUTOCOUNTER) && sc->data[SC_CRUSHSTRIKE] ){ @@ -3023,7 +3023,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam status_change_end(bl,SC_DEEP_SLEEP,INVALID_TIMER); } if( s_sd && t_sd && sc->data[SC_COLD] && flag&BF_WEAPON ){ - switch(s_sd->status.weapon){ + switch (s_sd->weapontype) { case W_MACE: case W_2HMACE: case W_1HAXE: @@ -3165,7 +3165,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam if( (sce = sc->data[SC_STONEHARDSKIN]) && flag&(BF_SHORT|BF_WEAPON) && damage > 0 ) { sce->val2 -= (int)cap_value(damage,INT_MIN,INT_MAX); if( src->type == BL_PC ) { - if (s_sd && s_sd->status.weapon != W_BOW) + if (s_sd != NULL && s_sd->weapontype != W_BOW) skill->break_equip(src, EQP_WEAPON, 3000, BCT_SELF); } else skill->break_equip(src, EQP_WEAPON, 3000, BCT_SELF); @@ -4575,8 +4575,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if(!skill_id) { //Skills ALWAYS use ONLY your right-hand weapon (tested on Aegis 10.2) - if (sd && sd->weapontype1 == 0 && sd->weapontype2 > 0) - { + if (sd && sd->weapontype1 == W_FIST && sd->weapontype2 != W_FIST) { flag.rh=0; flag.lh=1; } @@ -4649,7 +4648,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list short cri = sstatus->cri; if (sd != NULL) { // if show_katar_crit_bonus is enabled, it already done the calculation in status.c - if (!battle_config.show_katar_crit_bonus && sd->status.weapon == W_KATAR) { + if (!battle_config.show_katar_crit_bonus && sd->weapontype == W_KATAR) { cri <<= 1; } @@ -4822,8 +4821,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if ((temp = pc->checkskill(sd,BS_WEAPONRESEARCH)) > 0) hitrate += hitrate * ( 2 * temp ) / 100; - if( (sd->status.weapon == W_1HSWORD || sd->status.weapon == W_DAGGER) && - (temp = pc->checkskill(sd, GN_TRAINING_SWORD))>0 ) + if ((sd->weapontype == W_1HSWORD || sd->weapontype == W_DAGGER) && (temp = pc->checkskill(sd, GN_TRAINING_SWORD)) > 0) hitrate += 3 * temp; } @@ -4957,7 +4955,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list (!skill_id && sc && sc->data[SC_HLIF_CHANGE]?4:0)| (sc && sc->data[SC_WEAPONPERFECT]?8:0); if (flag.arrow && sd) - switch(sd->status.weapon) { + switch (sd->weapontype) { case W_BOW: case W_REVOLVER: case W_GATLING: @@ -5583,7 +5581,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if(wd.damage < 1) wd.damage = 1; if(wd.damage2 < 1) wd.damage2 = 1; #endif - } else if(sd->status.weapon == W_KATAR && !skill_id) { //Katars (offhand damage only applies to normal attacks, tested on Aegis 10.2) + } else if (sd->weapontype == W_KATAR && skill_id == 0) { + // Katars (offhand damage only applies to normal attacks, tested on Aegis 10.2) temp = pc->checkskill(sd,TF_DOUBLE); wd.damage2 = wd.damage * (1 + (temp * 2))/100; @@ -5702,7 +5701,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list } //Reject Sword bugreport:4493 by Daegaladh if (wd.damage != 0 && tsc != NULL && tsc->data[SC_SWORDREJECT] != NULL - && (sd == NULL || sd->weapontype1 == W_DAGGER || sd->weapontype1 == W_1HSWORD || sd->status.weapon == W_2HSWORD) + && (sd == NULL || sd->weapontype1 == W_DAGGER || sd->weapontype1 == W_1HSWORD || sd->weapontype == W_2HSWORD) && rnd()%100 < tsc->data[SC_SWORDREJECT]->val2 ) { ATK_RATER(50); @@ -6100,9 +6099,9 @@ bool battle_check_arrows(struct map_session_data *sd) } //Ammo check by Ishizu-chan if (sd->inventory_data[index]) { - switch (sd->status.weapon) { + switch (sd->weapontype) { case W_BOW: - if (sd->inventory_data[index]->look != A_ARROW) { + if (sd->inventory_data[index]->subtype != A_ARROW) { clif->arrow_fail(sd, 0); return false; } @@ -6111,13 +6110,13 @@ bool battle_check_arrows(struct map_session_data *sd) case W_RIFLE: case W_GATLING: case W_SHOTGUN: - if (sd->inventory_data[index]->look != A_BULLET) { + if (sd->inventory_data[index]->subtype != A_BULLET) { clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0); return false; } break; case W_GRENADE: - if (sd->inventory_data[index]->look != A_GRENADE) { + if (sd->inventory_data[index]->subtype != A_GRENADE) { clif->skill_fail(sd, 0, USESKILL_FAIL_NEED_MORE_BULLET, 0); return false; } @@ -6161,7 +6160,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t if (sd) { - sd->state.arrow_atk = (sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)); + sd->state.arrow_atk = (sd->weapontype == W_BOW || (sd->weapontype >= W_REVOLVER && sd->weapontype <= W_GRENADE)); if (sd->state.arrow_atk) { if (battle->check_arrows(sd) == false) @@ -6187,7 +6186,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t return ATK_BLOCK; } } - if( tsc && tsc->data[SC_BLADESTOP_WAIT] && !is_boss(src) && (src->type == BL_PC || tsd == NULL || distance_bl(src, target) <= (tsd->status.weapon == W_FIST ? 1 : 2)) ) + if( tsc && tsc->data[SC_BLADESTOP_WAIT] && !is_boss(src) && (src->type == BL_PC || tsd == NULL || distance_bl(src, target) <= (tsd->weapontype == W_FIST ? 1 : 2)) ) { uint16 skill_lv = tsc->data[SC_BLADESTOP_WAIT]->val1; int duration = skill->get_time2(MO_BLADESTOP,skill_lv); diff --git a/src/map/clif.c b/src/map/clif.c index 1731e88ca..07f394da4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -888,8 +888,8 @@ void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, un } #if PACKETVER < 4 - *rhand = sd->status.weapon; - *lhand = sd->status.shield; + *rhand = sd->status.look.weapon; + *lhand = sd->status.look.shield; #else if (sd->equip_index[EQI_HAND_R] >= 0 && sd->inventory_data[sd->equip_index[EQI_HAND_R]]) @@ -1491,8 +1491,8 @@ bool clif_spawn(struct block_list *bl) } if (sd->charm_type != CHARM_TYPE_NONE && sd->charm_count > 0) clif->spiritcharm(sd); - if (sd->status.robe) - clif->refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA); + if (sd->status.look.robe != 0) + clif->refreshlook(bl, bl->id, LOOK_ROBE, sd->status.look.robe, AREA); } break; case BL_MOB: @@ -2597,7 +2597,7 @@ void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *it, struc #endif #if PACKETVER >= 20100629 - p->wItemSpriteNumber = (id->equip&EQP_VISIBLE) ? id->look : 0; + p->wItemSpriteNumber = (id->equip&EQP_VISIBLE) ? id->view_sprite : 0; #endif #if PACKETVER >= 20120925 @@ -3527,7 +3527,7 @@ void clif_equipitemack(struct map_session_data *sd,int n,int pos,enum e_EQUIP_IT p.wearLocation = pos; #if PACKETVER >= 20100629 if (result == EIA_SUCCESS && sd->inventory_data[n]->equip&EQP_VISIBLE) - p.wItemSpriteNumber = sd->inventory_data[n]->look; + p.wItemSpriteNumber = sd->inventory_data[n]->view_sprite; else p.wItemSpriteNumber = 0; #endif @@ -4309,8 +4309,8 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) { clif->specialeffect_single(bl,421,sd->fd); if (tsd->bg_id != 0 && map->list[tsd->bl.m].flag.battleground) clif->sendbgemblem_single(sd->fd,tsd); - if (tsd->status.robe) - clif->refreshlook(&sd->bl,bl->id,LOOK_ROBE,tsd->status.robe,SELF); + if (tsd->status.look.robe != 0) + clif->refreshlook(&sd->bl, bl->id, LOOK_ROBE, tsd->status.look.robe, SELF); } break; case BL_MER: // Devotion Effects @@ -9449,8 +9449,8 @@ void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) { // Character Looks #if PACKETVER < 4 - clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); - clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); + clif->changelook(&sd->bl, LOOK_WEAPON, sd->status.look.weapon); + clif->changelook(&sd->bl, LOOK_SHIELD, sd->status.look.shield); #else clif->changelook(&sd->bl,LOOK_WEAPON,0); #endif diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 2b0847e1a..96eced725 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -1638,9 +1638,9 @@ int itemdb_gendercheck(struct item_data *id) return 1; if (id->nameid == WEDDING_RING_F) //Bride Ring return 0; - if (id->look == W_MUSICAL && id->type == IT_WEAPON) //Musical instruments are always male-only + if (id->subtype == W_MUSICAL && id->type == IT_WEAPON) //Musical instruments are always male-only return 1; - if (id->look == W_WHIP && id->type == IT_WEAPON) //Whips are always female-only + if (id->subtype == W_WHIP && id->type == IT_WEAPON) //Whips are always female-only return 0; return (battle_config.ignore_items_gender) ? 2 : id->sex; @@ -1788,10 +1788,14 @@ int itemdb_validate_entry(struct item_data *entry, int n, const char *source) { memset(&entry->stack, '\0', sizeof(entry->stack)); } - if (entry->type == IT_WEAPON && (entry->look < 0 || entry->look >= MAX_SINGLE_WEAPON_TYPE)) { - ShowWarning("itemdb_validate_entry: Invalid View for weapon items. View value %d for item %d (%s) in '%s', defaulting to 1.\n", - entry->look, entry->nameid, entry->jname, source); - entry->look = 1; + if (entry->type == IT_WEAPON && (entry->subtype <= 0 || entry->subtype >= MAX_SINGLE_WEAPON_TYPE)) { + ShowWarning("itemdb_validate_entry: Invalid View for weapon items. View value %d for item %d (%s) in '%s', defaulting to W_DAGGER.\n", + entry->subtype, entry->nameid, entry->jname, source); + entry->subtype = W_DAGGER; + } else if (entry->type == IT_AMMO && (entry->subtype <= 0 || entry->subtype >= MAX_AMMO_TYPE)) { + ShowWarning("itemdb_validate_entry: Invalid View for ammunition items. View value %d for item %d (%s) in '%s', defaulting to A_ARROW.\n", + entry->subtype, entry->nameid, entry->jname, source); + entry->subtype = A_ARROW; } entry->wlv = cap_value(entry->wlv, REFINE_TYPE_ARMOR, REFINE_TYPE_MAX); @@ -1986,6 +1990,14 @@ int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const char * else if( !inherit ) id.type = IT_ETC; + if (itemdb->lookup_const(it, "Subtype", &i32) && i32 >= 0) { + if (id.type == IT_WEAPON || id.type == IT_AMMO) + id.subtype = i32; + else + ShowWarning("itemdb_readdb_libconfig_sub: Field 'Subtype' is only allowed for IT_WEAPON or IT_AMMO (Item #%d: %s). Ignoring.\n", + id.nameid, id.name); + } + if( itemdb->lookup_const(it, "Buy", &i32) ) id.value_buy = i32; else if( !inherit ) @@ -2025,7 +2037,7 @@ int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const char * itemdb->jobmask2mapid(id.class_base, UINT64_MAX); } - if( itemdb->lookup_const(it, "Upper", &i32) && i32 >= 0 ) + if (itemdb->lookup_const_mask(it, "Upper", &i32) && i32 >= 0) id.class_upper = (unsigned int)i32; else if( !inherit ) id.class_upper = ITEMUPPER_ALL; @@ -2035,7 +2047,7 @@ int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const char * else if( !inherit ) id.sex = 2; - if( itemdb->lookup_const(it, "Loc", &i32) && i32 >= 0 ) + if (itemdb->lookup_const_mask(it, "Loc", &i32) && i32 >= 0) id.equip = i32; if( itemdb->lookup_const(it, "WeaponLv", &i32) && i32 >= 0 ) @@ -2058,8 +2070,23 @@ int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const char * if ((t = libconfig->setting_get_member(it, "DisableOptions"))) id.flag.no_options = libconfig->setting_get_bool(t) ? 1 : 0; - if( itemdb->lookup_const(it, "View", &i32) && i32 >= 0 ) - id.look = i32; + if (itemdb->lookup_const(it, "ViewSprite", &i32) && i32 >= 0) + id.view_sprite = i32; + + if (itemdb->lookup_const(it, "View", &i32) && i32 >= 0) { // TODO: Remove (Deprecated - 2016-09-04 [Haru]) + if ((id.type == IT_WEAPON || id.type == IT_AMMO) && id.subtype == 0) { + ShowWarning("itemdb_readdb_libconfig_sub: The 'View' field is deprecated. Please rename it to 'Subtype' (or 'ViewSprite'). (Item #%d: %s)\n", + id.nameid, id.name); + id.subtype = i32; + } else if ((id.type != IT_WEAPON && id.type != IT_AMMO) && id.view_sprite == 0) { + ShowWarning("itemdb_readdb_libconfig_sub: The 'View' field is deprecated. Please rename it to 'ViewSprite' (or 'Subtype'). (Item #%d: %s)\n", + id.nameid, id.name); + id.view_sprite = i32; + } else { + ShowWarning("itemdb_readdb_libconfig_sub: The 'View' field is deprecated. Please rename it to 'Subtype' or 'ViewSprite'. (Item #%d: %s)\n", + id.nameid, id.name); + } + } if( (t = libconfig->setting_get_member(it, "BindOnEquip")) ) id.flag.bindonequip = libconfig->setting_get_bool(t) ? 1 : 0; @@ -2197,21 +2224,76 @@ int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const char * bool itemdb_lookup_const(const struct config_setting_t *it, const char *name, int *value) { + const char *str = NULL; + nullpo_retr(false, name); nullpo_retr(false, value); - if (libconfig->setting_lookup_int(it, name, value)) - { + + if (libconfig->setting_lookup_int(it, name, value)) { return true; } - else - { + + if (libconfig->setting_lookup_string(it, name, &str)) { + if (*str && script->get_constant(str, value)) + return true; + } + + return false; +} + +bool itemdb_lookup_const_mask(const struct config_setting_t *it, const char *name, int *value) +{ + const struct config_setting_t *t = NULL; + + nullpo_retr(false, it); + nullpo_retr(false, name); + nullpo_retr(false, value); + + if ((t = libconfig->setting_get_member(it, name)) == NULL) { + return false; + } + + if (config_setting_is_scalar(t)) { const char *str = NULL; - if (libconfig->setting_lookup_string(it, name, &str)) - { - if (*str && script->get_constant(str, value)) + + if (config_setting_is_number(t)) { + *value = libconfig->setting_get_int(t); + return true; + } + + if ((str = libconfig->setting_get_string(t)) != NULL) { + int i32 = -1; + if (script->get_constant(str, &i32) && i32 >= 0) { + *value = i32; return true; + } } + + return false; } + + if (config_setting_is_aggregate(t) && libconfig->setting_length(t) >= 1) { + const struct config_setting_t *elem = NULL; + int i = 0; + + *value = 0; + + while ((elem = libconfig->setting_get_elem(t, i++)) != NULL) { + const char *str = libconfig->setting_get_string(elem); + int i32 = -1; + + if (str == NULL) + return false; + + if (!script->get_constant(str, &i32) || i32 < 0) + return false; + + *value |= i32; + } + + return true; + } + return false; } @@ -2637,4 +2719,5 @@ void itemdb_defaults(void) { itemdb->id2combo = itemdb_id2combo; itemdb->is_item_usable = itemdb_is_item_usable; itemdb->lookup_const = itemdb_lookup_const; + itemdb->lookup_const_mask = itemdb_lookup_const_mask; } diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 35cd154cb..d2d3b6c73 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -337,7 +337,7 @@ enum item_class_upper { ITEMUPPER_UPPER = 0x02, ITEMUPPER_BABY = 0x04, ITEMUPPER_THIRD = 0x08, - ITEMUPPER_THURDUPPER = 0x10, + ITEMUPPER_THIRDUPPER = 0x10, ITEMUPPER_THIRDBABY = 0x20, ITEMUPPER_ALL = 0x3f, // Sum of all the above }; @@ -454,10 +454,10 @@ struct item_data { uint16 nameid; char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH]; - //Do not add stuff between value_buy and view_id (see how getiteminfo works) int value_buy; int value_sell; int type; + int subtype; int maxchance; //For logs, for external game info, for scripts: Max drop chance of this item (e.g. 0.01% , etc.. if it = 0, then monsters don't drop it, -1 denotes items sold in shops only) [Lupus] int sex; int equip; @@ -466,7 +466,7 @@ struct item_data { int def; int range; int slot; - int look; + int view_sprite; int elv; int wlv; int view_id; @@ -474,8 +474,6 @@ struct item_data { int elvmax;/* maximum level for this item */ int delay; -//Lupus: I rearranged order of these fields due to compatibility with ITEMINFO script command -// some script commands should be revised as well... uint64 class_base[3]; ///< Specifies if the base can wear this item (split in 3 indexes per type: 1-1, 2-1, 2-2) unsigned class_upper : 6; ///< Specifies if the upper-type can equip it (bitfield, 0x01: normal, 0x02: upper, 0x04: baby normal, 0x08: third normal, 0x10: third upper, 0x20: third baby) struct { @@ -524,7 +522,8 @@ struct item_data { #define itemdb_type(n) (itemdb->search(n)->type) #define itemdb_atk(n) (itemdb->search(n)->atk) #define itemdb_def(n) (itemdb->search(n)->def) -#define itemdb_look(n) (itemdb->search(n)->look) +#define itemdb_subtype(n) (itemdb->search(n)->subtype) +#define itemdb_sprite(n) (itemdb->search(n)->view_sprite) #define itemdb_weight(n) (itemdb->search(n)->weight) #define itemdb_equip(n) (itemdb->search(n)->equip) #define itemdb_usescript(n) (itemdb->search(n)->script) @@ -648,6 +647,7 @@ struct itemdb_interface { struct item_combo * (*id2combo) (unsigned short id); bool (*is_item_usable) (struct item_data *item); bool (*lookup_const) (const struct config_setting_t *it, const char *name, int *value); + bool (*lookup_const_mask) (const struct config_setting_t *it, const char *name, int *value); }; #ifdef HERCULES_CORE diff --git a/src/map/pc.c b/src/map/pc.c index f332feea8..609a4ec56 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -765,9 +765,9 @@ int pc_equippoint(struct map_session_data *sd,int n) return 0; //Not equippable by players. ep = sd->inventory_data[n]->equip; - if (sd->inventory_data[n]->look == W_DAGGER - || sd->inventory_data[n]->look == W_1HSWORD - || sd->inventory_data[n]->look == W_1HAXE + if (sd->inventory_data[n]->subtype == W_DAGGER + || sd->inventory_data[n]->subtype == W_1HSWORD + || sd->inventory_data[n]->subtype == W_1HAXE ) { if (pc->checkskill(sd,AS_LEFT) > 0 || (sd->job & MAPID_UPPERMASK) == MAPID_ASSASSIN @@ -794,9 +794,9 @@ int pc_item_equippoint(struct map_session_data *sd, struct item_data* id) return 0; //Not equippable by players. ep = id->equip; - if (id->look == W_DAGGER || - id->look == W_1HSWORD || - id->look == W_1HAXE) { + if (id->subtype == W_DAGGER || + id->subtype == W_1HSWORD || + id->subtype == W_1HAXE) { if (pc->checkskill(sd, AS_LEFT) > 0 || (sd->job & MAPID_UPPERMASK) == MAPID_ASSASSIN || (sd->job & MAPID_UPPERMASK) == MAPID_KAGEROUOBORO) { @@ -829,40 +829,40 @@ int pc_calcweapontype(struct map_session_data *sd) // single-hand if(sd->weapontype2 == W_FIST) { - sd->status.weapon = sd->weapontype1; + sd->weapontype = sd->weapontype1; return 1; } if(sd->weapontype1 == W_FIST) { - sd->status.weapon = sd->weapontype2; + sd->weapontype = sd->weapontype2; return 1; } // dual-wield - sd->status.weapon = 0; + sd->weapontype = W_FIST; switch (sd->weapontype1){ case W_DAGGER: switch (sd->weapontype2) { - case W_DAGGER: sd->status.weapon = W_DOUBLE_DD; break; - case W_1HSWORD: sd->status.weapon = W_DOUBLE_DS; break; - case W_1HAXE: sd->status.weapon = W_DOUBLE_DA; break; + case W_DAGGER: sd->weapontype = W_DOUBLE_DD; break; + case W_1HSWORD: sd->weapontype = W_DOUBLE_DS; break; + case W_1HAXE: sd->weapontype = W_DOUBLE_DA; break; } break; case W_1HSWORD: switch (sd->weapontype2) { - case W_DAGGER: sd->status.weapon = W_DOUBLE_DS; break; - case W_1HSWORD: sd->status.weapon = W_DOUBLE_SS; break; - case W_1HAXE: sd->status.weapon = W_DOUBLE_SA; break; + case W_DAGGER: sd->weapontype = W_DOUBLE_DS; break; + case W_1HSWORD: sd->weapontype = W_DOUBLE_SS; break; + case W_1HAXE: sd->weapontype = W_DOUBLE_SA; break; } break; case W_1HAXE: switch (sd->weapontype2) { - case W_DAGGER: sd->status.weapon = W_DOUBLE_DA; break; - case W_1HSWORD: sd->status.weapon = W_DOUBLE_SA; break; - case W_1HAXE: sd->status.weapon = W_DOUBLE_AA; break; + case W_DAGGER: sd->weapontype = W_DOUBLE_DA; break; + case W_1HSWORD: sd->weapontype = W_DOUBLE_SA; break; + case W_1HAXE: sd->weapontype = W_DOUBLE_AA; break; } } // unknown, default to right hand type - if (!sd->status.weapon) - sd->status.weapon = sd->weapontype1; + if (sd->weapontype == W_FIST) + sd->weapontype = sd->weapontype1; return 2; } @@ -884,20 +884,30 @@ int pc_setequipindex(struct map_session_data *sd) if(sd->status.inventory[i].equip & pc->equip_pos[j]) sd->equip_index[j] = i; - if(sd->status.inventory[i].equip & EQP_HAND_R) - { - if(sd->inventory_data[i]) - sd->weapontype1 = sd->inventory_data[i]->look; - else - sd->weapontype1 = 0; + if (sd->status.inventory[i].equip & EQP_HAND_R) { + if (sd->inventory_data[i]) { + sd->weapontype1 = sd->inventory_data[i]->subtype; + sd->status.look.weapon = sd->inventory_data[i]->view_sprite; + } else { + sd->weapontype1 = W_FIST; + sd->status.look.weapon = 0; + } } - if( sd->status.inventory[i].equip & EQP_HAND_L ) - { - if( sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON ) - sd->weapontype2 = sd->inventory_data[i]->look; - else - sd->weapontype2 = 0; + if (sd->status.inventory[i].equip & EQP_HAND_L) { + if (sd->inventory_data[i] != NULL) { + if (sd->inventory_data[i]->type == IT_WEAPON) + sd->weapontype2 = sd->inventory_data[i]->subtype; + else + sd->weapontype2 = W_FIST; + if (sd->inventory_data[i]->type == IT_ARMOR) + sd->has_shield = true; + else + sd->has_shield = false; + } else { + sd->weapontype2 = W_FIST; + sd->has_shield = false; + } } } } @@ -1088,13 +1098,13 @@ int pc_isequip(struct map_session_data *sd,int n) return 1; //Can equip all helms if (sd->status.base_level > 96 && item->equip & EQP_ARMS && item->type == IT_WEAPON) - switch(item->look) { //In weapons, the look determines type of weapon. - case W_DAGGER: //Level 4 Knives are equippable.. this means all knives, I'd guess? - case W_1HSWORD: //All 1H swords - case W_1HAXE: //All 1H Axes - case W_MACE: //All 1H Maces - case W_STAFF: //All 1H Staves - return 1; + switch (item->subtype) { //In weapons, the look determines type of weapon. + case W_DAGGER: //Level 4 Knives are equippable.. this means all knives, I'd guess? + case W_1HSWORD: //All 1H swords + case W_1HAXE: //All 1H Axes + case W_MACE: //All 1H Maces + case W_STAFF: //All 1H Staves + return 1; } } } @@ -2488,7 +2498,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val) { } switch (sd->state.lr_flag) { case 2: - switch (sd->status.weapon) { + switch (sd->weapontype) { case W_BOW: case W_REVOLVER: case W_RIFLE: @@ -2555,7 +2565,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val) { case SP_ATTACKRANGE: switch (sd->state.lr_flag) { case 2: - switch (sd->status.weapon) { + switch (sd->weapontype) { case W_BOW: case W_REVOLVER: case W_RIFLE: @@ -5022,7 +5032,7 @@ int pc_isUseitem(struct map_session_data *sd,int n) break; } // Upper third classes - if ((item->class_upper & ITEMUPPER_THURDUPPER) != 0) { + if ((item->class_upper & ITEMUPPER_THIRDUPPER) != 0) { if ((sd->job & JOBL_THIRD) != 0 && (sd->job & JOBL_UPPER) != 0) break; } @@ -5942,11 +5952,11 @@ int pc_checkallowskill(struct map_session_data *sd) status_change_end(&sd->bl, scw_list[i], INVALID_TIMER); } - if(sd->sc.data[SC_STRUP] && sd->status.weapon) + if(sd->sc.data[SC_STRUP] && sd->weapontype != W_FIST) // Spurt requires bare hands (feet, in fact xD) status_change_end(&sd->bl, SC_STRUP, INVALID_TIMER); - if(sd->status.shield <= 0) { // Skills requiring a shield + if (!sd->has_shield) { // Skills requiring a shield for (i = 0; i < ARRAYLENGTH(scs_list); i++) if(sd->sc.data[scs_list[i]]) status_change_end(&sd->bl, scs_list[i], INVALID_TIMER); @@ -8825,10 +8835,10 @@ int pc_equiplookall(struct map_session_data *sd) clif->changelook(&sd->bl,LOOK_WEAPON,0); clif->changelook(&sd->bl,LOOK_SHOES,0); - clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); - clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); - clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); - clif->changelook(&sd->bl,LOOK_ROBE, sd->status.robe); + clif->changelook(&sd->bl, LOOK_HEAD_BOTTOM, sd->status.look.head_bottom); + clif->changelook(&sd->bl, LOOK_HEAD_TOP, sd->status.look.head_top); + clif->changelook(&sd->bl, LOOK_HEAD_MID, sd->status.look.head_mid); + clif->changelook(&sd->bl, LOOK_ROBE, sd->status.look.robe); return 0; } @@ -8844,7 +8854,7 @@ int pc_changelook(struct map_session_data *sd,int type,int val) case LOOK_BASE: status->set_viewdata(&sd->bl, val); clif->changelook(&sd->bl, LOOK_BASE, sd->vd.class); - clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); + clif->changelook(&sd->bl, LOOK_WEAPON, sd->status.look.weapon); if (sd->vd.cloth_color) clif->changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color); if (sd->vd.body_style) @@ -8863,16 +8873,16 @@ int pc_changelook(struct map_session_data *sd,int type,int val) } break; case LOOK_WEAPON: - sd->status.weapon=val; + sd->status.look.weapon = val; break; case LOOK_HEAD_BOTTOM: - sd->status.head_bottom=val; + sd->status.look.head_bottom = val; break; case LOOK_HEAD_TOP: - sd->status.head_top=val; + sd->status.look.head_top = val; break; case LOOK_HEAD_MID: - sd->status.head_mid=val; + sd->status.look.head_mid = val; break; case LOOK_HAIR_COLOR: //Use the battle_config limits! [Skotlex] val = cap_value(val, MIN_HAIR_COLOR, MAX_HAIR_COLOR); @@ -8890,12 +8900,12 @@ int pc_changelook(struct map_session_data *sd,int type,int val) sd->status.clothes_color=val; break; case LOOK_SHIELD: - sd->status.shield=val; + sd->status.look.shield = val; break; case LOOK_SHOES: break; case LOOK_ROBE: - sd->status.robe = val; + sd->status.look.robe = val; break; case LOOK_BODY2: val = cap_value(val, MIN_BODY_STYLE, MAX_BODY_STYLE); @@ -9757,83 +9767,91 @@ void pc_equipitem_pos(struct map_session_data *sd, struct item_data *id, int n, nullpo_retv(sd); if ((!map_no_view(sd->bl.m,EQP_SHADOW_WEAPON) && pos & EQP_SHADOW_WEAPON) || (pos & EQP_HAND_R)) { - if(id) - sd->weapontype1 = id->look; - else - sd->weapontype1 = 0; + if (id != NULL) { + sd->weapontype1 = id->subtype; + sd->status.look.weapon = id->view_sprite; + } else { + sd->weapontype1 = W_FIST; + sd->status.look.weapon = 0; + } pc->calcweapontype(sd); - clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); + clif->changelook(&sd->bl, LOOK_WEAPON, sd->status.look.weapon); } if ((!map_no_view(sd->bl.m,EQP_SHADOW_SHIELD) && pos & EQP_SHADOW_SHIELD) || (pos & EQP_HAND_L)) { - if (id) { - if(id->type == IT_WEAPON) { - sd->status.shield = 0; - sd->weapontype2 = id->look; - } else if(id->type == IT_ARMOR) { - sd->status.shield = id->look; - sd->weapontype2 = 0; + if (id != NULL) { + if (id->type == IT_WEAPON) { + sd->has_shield = false; + sd->status.look.shield = 0; + sd->weapontype2 = id->subtype; + } else if (id->type == IT_ARMOR) { + sd->has_shield = true; + sd->status.look.shield = id->view_sprite; + sd->weapontype2 = W_FIST; } - } else - sd->status.shield = sd->weapontype2 = 0; + } else { + sd->has_shield = false; + sd->status.look.shield = 0; + sd->weapontype2 = W_FIST; + } pc->calcweapontype(sd); - clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); + clif->changelook(&sd->bl, LOOK_SHIELD, sd->status.look.shield); } //Added check to prevent sending the same look on multiple slots -> //causes client to redraw item on top of itself. (suggested by Lupus) if (!map_no_view(sd->bl.m,EQP_HEAD_LOW) && pos & EQP_HEAD_LOW && pc->checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) { if (id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID))) - sd->status.head_bottom = id->look; + sd->status.look.head_bottom = id->view_sprite; else - sd->status.head_bottom = 0; - clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); + sd->status.look.head_bottom = 0; + clif->changelook(&sd->bl, LOOK_HEAD_BOTTOM, sd->status.look.head_bottom); } if (!map_no_view(sd->bl.m,EQP_HEAD_TOP) && pos & EQP_HEAD_TOP && pc->checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) { if (id) - sd->status.head_top = id->look; + sd->status.look.head_top = id->view_sprite; else - sd->status.head_top = 0; - clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); + sd->status.look.head_top = 0; + clif->changelook(&sd->bl, LOOK_HEAD_TOP, sd->status.look.head_top); } if (!map_no_view(sd->bl.m,EQP_HEAD_MID) && pos & EQP_HEAD_MID && pc->checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) { if (id && !(pos&EQP_HEAD_TOP)) - sd->status.head_mid = id->look; + sd->status.look.head_mid = id->view_sprite; else - sd->status.head_mid = 0; - clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); + sd->status.look.head_mid = 0; + clif->changelook(&sd->bl, LOOK_HEAD_MID, sd->status.look.head_mid); } if (!map_no_view(sd->bl.m,EQP_COSTUME_HEAD_TOP) && pos & EQP_COSTUME_HEAD_TOP) { if (id){ - sd->status.head_top = id->look; + sd->status.look.head_top = id->view_sprite; } else - sd->status.head_top = 0; - clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); + sd->status.look.head_top = 0; + clif->changelook(&sd->bl, LOOK_HEAD_TOP, sd->status.look.head_top); } if (!map_no_view(sd->bl.m,EQP_COSTUME_HEAD_MID) && pos & EQP_COSTUME_HEAD_MID) { if(id && !(pos&EQP_HEAD_TOP)){ - sd->status.head_mid = id->look; + sd->status.look.head_mid = id->view_sprite; } else - sd->status.head_mid = 0; - clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); + sd->status.look.head_mid = 0; + clif->changelook(&sd->bl, LOOK_HEAD_MID, sd->status.look.head_mid); } if (!map_no_view(sd->bl.m,EQP_COSTUME_HEAD_LOW) && pos & EQP_COSTUME_HEAD_LOW) { if (id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID))){ - sd->status.head_bottom = id->look; + sd->status.look.head_bottom = id->view_sprite; } else - sd->status.head_bottom = 0; - clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); + sd->status.look.head_bottom = 0; + clif->changelook(&sd->bl, LOOK_HEAD_BOTTOM, sd->status.look.head_bottom); } if (!map_no_view(sd->bl.m,EQP_SHOES) && pos & EQP_SHOES) clif->changelook(&sd->bl,LOOK_SHOES,0); if (!map_no_view(sd->bl.m,EQP_GARMENT) && pos&EQP_GARMENT && pc->checkequip(sd,EQP_COSTUME_GARMENT) == -1) { - sd->status.robe = id ? id->look : 0; - clif->changelook(&sd->bl, LOOK_ROBE, sd->status.robe); + sd->status.look.robe = id ? id->view_sprite : 0; + clif->changelook(&sd->bl, LOOK_ROBE, sd->status.look.robe); } if (!map_no_view(sd->bl.m,EQP_COSTUME_GARMENT) && pos & EQP_COSTUME_GARMENT) { - sd->status.robe = id ? id->look : 0; - clif->changelook(&sd->bl,LOOK_ROBE,sd->status.robe); + sd->status.look.robe = id ? id->view_sprite : 0; + clif->changelook(&sd->bl, LOOK_ROBE, sd->status.look.robe); } } @@ -9987,57 +10005,59 @@ void pc_unequipitem_pos(struct map_session_data *sd, int n, int pos) { nullpo_retv(sd); if (pos & EQP_HAND_R) { - sd->weapontype1 = 0; - sd->status.weapon = sd->weapontype2; + sd->weapontype1 = W_FIST; pc->calcweapontype(sd); - clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); + sd->status.look.weapon = 0; + clif->changelook(&sd->bl, LOOK_WEAPON, sd->status.look.weapon); if (!battle_config.dancing_weaponswitch_fix) status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); // Unequipping => stop dancing. } if (pos & EQP_HAND_L) { - sd->status.shield = sd->weapontype2 = 0; + sd->has_shield = false; + sd->status.look.shield = 0; + sd->weapontype2 = W_FIST; pc->calcweapontype(sd); - clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); + clif->changelook(&sd->bl, LOOK_SHIELD, sd->status.look.shield); } if (pos & EQP_HEAD_LOW && pc->checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) { - sd->status.head_bottom = 0; - clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); + sd->status.look.head_bottom = 0; + clif->changelook(&sd->bl, LOOK_HEAD_BOTTOM, sd->status.look.head_bottom); } if (pos & EQP_HEAD_TOP && pc->checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) { - sd->status.head_top = 0; - clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); + sd->status.look.head_top = 0; + clif->changelook(&sd->bl, LOOK_HEAD_TOP, sd->status.look.head_top); } if (pos & EQP_HEAD_MID && pc->checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) { - sd->status.head_mid = 0; - clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); + sd->status.look.head_mid = 0; + clif->changelook(&sd->bl, LOOK_HEAD_MID, sd->status.look.head_mid); } if (pos & EQP_COSTUME_HEAD_TOP) { - sd->status.head_top = ( pc->checkequip(sd,EQP_HEAD_TOP) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_TOP)]->look : 0; - clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); + sd->status.look.head_top = ( pc->checkequip(sd,EQP_HEAD_TOP) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_TOP)]->view_sprite : 0; + clif->changelook(&sd->bl, LOOK_HEAD_TOP, sd->status.look.head_top); } if (pos & EQP_COSTUME_HEAD_MID) { - sd->status.head_mid = ( pc->checkequip(sd,EQP_HEAD_MID) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_MID)]->look : 0; - clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); + sd->status.look.head_mid = ( pc->checkequip(sd,EQP_HEAD_MID) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_MID)]->view_sprite : 0; + clif->changelook(&sd->bl, LOOK_HEAD_MID, sd->status.look.head_mid); } if (pos & EQP_COSTUME_HEAD_LOW) { - sd->status.head_bottom = ( pc->checkequip(sd,EQP_HEAD_LOW) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_LOW)]->look : 0; - clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); + sd->status.look.head_bottom = ( pc->checkequip(sd,EQP_HEAD_LOW) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_LOW)]->view_sprite : 0; + clif->changelook(&sd->bl, LOOK_HEAD_BOTTOM, sd->status.look.head_bottom); } if (pos & EQP_SHOES) clif->changelook(&sd->bl,LOOK_SHOES,0); if (pos & EQP_GARMENT && pc->checkequip(sd,EQP_COSTUME_GARMENT) == -1) { - sd->status.robe = 0; + sd->status.look.robe = 0; clif->changelook(&sd->bl, LOOK_ROBE, 0); } if (pos & EQP_COSTUME_GARMENT) { - sd->status.robe = ( pc->checkequip(sd,EQP_GARMENT) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_GARMENT)]->look : 0; - clif->changelook(&sd->bl,LOOK_ROBE,sd->status.robe); + sd->status.look.robe = ( pc->checkequip(sd,EQP_GARMENT) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_GARMENT)]->view_sprite : 0; + clif->changelook(&sd->bl, LOOK_ROBE, sd->status.look.robe); } } @@ -10091,7 +10111,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) clif->unequipitemack(sd, n, pos, UIA_SUCCESS); if ((pos & EQP_ARMS) && - sd->weapontype1 == 0 && sd->weapontype2 == 0 && (sd->sc.data[SC_TK_SEVENWIND] == 0 || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!) + sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST && (sd->sc.data[SC_TK_SEVENWIND] == NULL || sd->sc.data[SC_ASPERSIO] != NULL)) //Check for seven wind (but not level seven!) skill->enchant_elemental_end(&sd->bl, -1); if (pos & EQP_ARMOR) { diff --git a/src/map/pc.h b/src/map/pc.h index c94ec6099..8615f00f2 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -308,7 +308,10 @@ struct map_session_data { short nameid; int64 tick; } item_delay[MAX_ITEMDELAYS]; // [Paradox924X] - short weapontype1,weapontype2; + bool has_shield; ///< Whether the character is wearing a shield. + int16 weapontype; ///< Weapon type considering both hands (@see enum weapon_type). + int16 weapontype1; ///< Weapon type in the right/primary hand (@see enum weapon_type). + int16 weapontype2; ///< Weapon type in the left/secondary hand (@see enum weapon_type). short disguise; // [Valaris] struct weapon_data right_weapon, left_weapon; @@ -685,8 +688,13 @@ END_ZEROED_BLOCK; #define pc_stop_attack(sd) (unit->stop_attack(&(sd)->bl)) //Weapon check considering dual wielding. -#define pc_check_weapontype(sd, type) ((type)&((sd)->status.weapon < MAX_SINGLE_WEAPON_TYPE? \ - 1<<(sd)->status.weapon:(1<<(sd)->weapontype1)|(1<<(sd)->weapontype2)|(1<<(sd)->status.weapon))) +#define pc_check_weapontype(sd, type) ( \ + (type) & ( \ + (sd)->weapontype < MAX_SINGLE_WEAPON_TYPE ? \ + 1 << (sd)->weapontype : \ + (1 << (sd)->weapontype1) | (1 << (sd)->weapontype2) \ + ) \ + ) // clientside display macros (values to the left/right of the "+") #ifdef RENEWAL diff --git a/src/map/script.c b/src/map/script.c index 8722fcdbe..7dcebd6f6 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -13982,43 +13982,70 @@ BUILDIN(getitemslots) return true; } -// TODO: add matk here if needed/once we get rid of RENEWAL +// TODO: add matk here if needed /*========================================== * Returns some values of an item [Lupus] * Price, Weight, etc... - * getiteminfo(itemID,n), where n - * 0 value_buy; - * 1 value_sell; - * 2 type; - * 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc.. - * if = 0, then monsters don't drop it at all (rare or a quest item) - * if = -1, then this item is sold in NPC shops only - * 4 sex; - * 5 equip; - * 6 weight; - * 7 atk; - * 8 def; - * 9 range; - * 10 slot; - * 11 look; - * 12 elv; - * 13 wlv; - * 14 view id *------------------------------------------*/ BUILDIN(getiteminfo) { - int item_id,n; - struct item_data *i_data; + int item_id = script_getnum(st, 2); + int n = script_getnum(st, 3); + struct item_data *it = itemdb->exists(item_id); - item_id = script_getnum(st,2); - n = script_getnum(st,3); - i_data = itemdb->exists(item_id); + if (it == NULL) { + script_pushint(st, -1); + return true; + } - if (i_data && n>=0 && n<=14) { - int *item_arr = (int*)&i_data->value_buy; - script_pushint(st,item_arr[n]); - } else { + switch (n) { + case 0: + script_pushint(st, it->value_buy); + break; + case 1: + script_pushint(st, it->value_sell); + break; + case 2: + script_pushint(st, it->type); + break; + case 3: + script_pushint(st, it->maxchance); + break; + case 4: + script_pushint(st, it->sex); + break; + case 5: + script_pushint(st, it->equip); + break; + case 6: + script_pushint(st, it->weight); + break; + case 7: + script_pushint(st, it->atk); + break; + case 8: + script_pushint(st, it->def); + break; + case 9: + script_pushint(st, it->range); + break; + case 10: + script_pushint(st, it->slot); + break; + case 11: + script_pushint(st, it->subtype); + break; + case 12: + script_pushint(st, it->elv); + break; + case 13: + script_pushint(st, it->wlv); + break; + case 14: + script_pushint(st, it->view_id); + break; + default: script_pushint(st,-1); } return true; @@ -14211,43 +14238,71 @@ BUILDIN(setequipoption) /*========================================== * Set some values of an item [Lupus] * Price, Weight, etc... - * setiteminfo(itemID,n,Value), where n - * 0 value_buy; - * 1 value_sell; - * 2 type; - * 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc.. - * if = 0, then monsters don't drop it at all (rare or a quest item) - * if = -1, then this item is sold in NPC shops only - * 4 sex; - * 5 equip; - * 6 weight; - * 7 atk; - * 8 def; - * 9 range; - * 10 slot; - * 11 look; - * 12 elv; - * 13 wlv; - * 14 view id - * Returns Value or -1 if the wrong field's been set *------------------------------------------*/ BUILDIN(setiteminfo) { - int item_id,n,value; - struct item_data *i_data; + // TODO: Validate data in a similar way as during database load + int item_id = script_getnum(st, 2); + int n = script_getnum(st, 3); + int value = script_getnum(st,4); + struct item_data *it = itemdb->exists(item_id); - item_id = script_getnum(st,2); - n = script_getnum(st,3); - value = script_getnum(st,4); - i_data = itemdb->exists(item_id); + if (it == NULL) { + script_pushint(st, -1); + return true; + } - if (i_data && n>=0 && n<=14) { - int *item_arr = (int*)&i_data->value_buy; - item_arr[n] = value; - script_pushint(st,value); - } else { + switch (n) { + case 0: + it->value_buy = value; + break; + case 1: + it->value_sell = value; + break; + case 2: + it->type = value; + break; + case 3: + it->maxchance = value; + break; + case 4: + it->sex = value; + break; + case 5: + it->equip = value; + break; + case 6: + it->weight = value; + break; + case 7: + it->atk = value; + break; + case 8: + it->def = value; + break; + case 9: + it->range = value; + break; + case 10: + it->slot = value; + break; + case 11: + it->subtype = value; + break; + case 12: + it->elv = value; + break; + case 13: + it->wlv = value; + break; + case 14: + it->view_id = value; + break; + default: script_pushint(st,-1); + return true; } + script_pushint(st,value); return true; } @@ -15464,15 +15519,15 @@ BUILDIN(getlook) type=script_getnum(st,2); switch(type) { case LOOK_HAIR: val = sd->status.hair; break; //1 - case LOOK_WEAPON: val = sd->status.weapon; break; //2 - case LOOK_HEAD_BOTTOM: val = sd->status.head_bottom; break; //3 - case LOOK_HEAD_TOP: val = sd->status.head_top; break; //4 - case LOOK_HEAD_MID: val = sd->status.head_mid; break; //5 + case LOOK_WEAPON: val = sd->status.look.weapon; break; //2 + case LOOK_HEAD_BOTTOM: val = sd->status.look.head_bottom; break; //3 + case LOOK_HEAD_TOP: val = sd->status.look.head_top; break; //4 + case LOOK_HEAD_MID: val = sd->status.look.head_mid; break; //5 case LOOK_HAIR_COLOR: val = sd->status.hair_color; break; //6 case LOOK_CLOTHES_COLOR: val = sd->status.clothes_color; break; //7 - case LOOK_SHIELD: val = sd->status.shield; break; //8 + case LOOK_SHIELD: val = sd->status.look.shield; break; //8 case LOOK_SHOES: break; //9 - case LOOK_ROBE: val = sd->status.robe; break; //12 + case LOOK_ROBE: val = sd->status.look.robe; break; //12 case LOOK_BODY2: val=sd->status.body; break; //13 } @@ -24404,6 +24459,15 @@ void script_hardcoded_constants(void) script->set_constant("EQP_SHADOW_SHOES", EQP_SHADOW_SHOES, false, false); script->set_constant("EQP_SHADOW_ACC_R", EQP_SHADOW_ACC_R, false, false); script->set_constant("EQP_SHADOW_ACC_L", EQP_SHADOW_ACC_L, false, false); + // Synonyms and combined values + script->set_constant("EQP_WEAPON", EQP_WEAPON, false, false); + script->set_constant("EQP_SHIELD", EQP_SHIELD, false, false); + script->set_constant("EQP_ARMS", EQP_ARMS, false, false); + script->set_constant("EQP_HELM", EQP_HELM, false, false); + script->set_constant("EQP_ACC", EQP_ACC, false, false); + script->set_constant("EQP_COSTUME", EQP_COSTUME, false, false); + script->set_constant("EQP_SHADOW_ACC", EQP_SHADOW_ACC, false, false); + script->set_constant("EQP_SHADOW_ARMS", EQP_SHADOW_ARMS, false, false); script->constdb_comment("Item Option Types"); script->set_constant("IT_OPT_INDEX", IT_OPT_INDEX, false, false); @@ -24480,6 +24544,53 @@ void script_hardcoded_constants(void) script->set_constant("DATATYPE_VAR", DATATYPE_VAR, false, false); script->set_constant("DATATYPE_LABEL", DATATYPE_LABEL, false, false); + script->constdb_comment("Item Subtypes (Weapon types)"); + script->set_constant("W_FIST", W_FIST, false, false); + script->set_constant("W_DAGGER", W_DAGGER, false, false); + script->set_constant("W_1HSWORD", W_1HSWORD, false, false); + script->set_constant("W_2HSWORD", W_2HSWORD, false, false); + script->set_constant("W_1HSPEAR", W_1HSPEAR, false, false); + script->set_constant("W_2HSPEAR", W_2HSPEAR, false, false); + script->set_constant("W_1HAXE", W_1HAXE, false, false); + script->set_constant("W_2HAXE", W_2HAXE, false, false); + script->set_constant("W_MACE", W_MACE, false, false); + script->set_constant("W_2HMACE", W_2HMACE, false, false); + script->set_constant("W_STAFF", W_STAFF, false, false); + script->set_constant("W_BOW", W_BOW, false, false); + script->set_constant("W_KNUCKLE", W_KNUCKLE, false, false); + script->set_constant("W_MUSICAL", W_MUSICAL, false, false); + script->set_constant("W_WHIP", W_WHIP, false, false); + script->set_constant("W_BOOK", W_BOOK, false, false); + script->set_constant("W_KATAR", W_KATAR, false, false); + script->set_constant("W_REVOLVER", W_REVOLVER, false, false); + script->set_constant("W_RIFLE", W_RIFLE, false, false); + script->set_constant("W_GATLING", W_GATLING, false, false); + script->set_constant("W_SHOTGUN", W_SHOTGUN, false, false); + script->set_constant("W_GRENADE", W_GRENADE, false, false); + script->set_constant("W_HUUMA", W_HUUMA, false, false); + script->set_constant("W_2HSTAFF", W_2HSTAFF, false, false); + + script->constdb_comment("Item Subtypes (Ammunition types)"); + script->set_constant("A_ARROW", A_ARROW, false, false); + script->set_constant("A_DAGGER", A_DAGGER, false, false); + script->set_constant("A_BULLET", A_BULLET, false, false); + script->set_constant("A_SHELL", A_SHELL, false, false); + script->set_constant("A_GRENADE", A_GRENADE, false, false); + script->set_constant("A_SHURIKEN", A_SHURIKEN, false, false); + script->set_constant("A_KUNAI", A_KUNAI, false, false); + script->set_constant("A_CANNONBALL", A_CANNONBALL, false, false); + script->set_constant("A_THROWWEAPON", A_THROWWEAPON, false, false); + + script->constdb_comment("Item Upper Masks"); + script->set_constant("ITEMUPPER_NONE", ITEMUPPER_NONE, false, false); + script->set_constant("ITEMUPPER_NORMAL", ITEMUPPER_NORMAL, false, false); + script->set_constant("ITEMUPPER_UPPER", ITEMUPPER_UPPER, false, false); + script->set_constant("ITEMUPPER_BABY", ITEMUPPER_BABY, false, false); + script->set_constant("ITEMUPPER_THIRD", ITEMUPPER_THIRD, false, false); + script->set_constant("ITEMUPPER_THIRDUPPER", ITEMUPPER_THIRDUPPER, false, false); + script->set_constant("ITEMUPPER_THIRDBABY", ITEMUPPER_THIRDBABY, false, false); + script->set_constant("ITEMUPPER_ALL", ITEMUPPER_ALL, false, false); + script->constdb_comment("Renewal"); #ifdef RENEWAL script->set_constant("RENEWAL", 1, false, false); diff --git a/src/map/skill.c b/src/map/skill.c index e187b7e8b..25d85e746 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -806,7 +806,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 break; // If a normal attack is a skill, it's splash damage. [Inkfish] if(sd) { // Automatic trigger of Blitz Beat - if (pc_isfalcon(sd) && sd->status.weapon == W_BOW && (temp=pc->checkskill(sd,HT_BLITZBEAT))>0 && + if (pc_isfalcon(sd) && sd->weapontype == W_BOW && (temp=pc->checkskill(sd,HT_BLITZBEAT))>0 && rnd()%1000 <= sstatus->luk*3 ) { rate = sd->status.job_level / 10 + 1; skill->castend_damage_id(src,bl,HT_BLITZBEAT,(temp<rate)?temp:rate,tick,SD_LEVEL); @@ -815,7 +815,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 if( pc_iswug(sd) && (temp=pc->checkskill(sd,RA_WUGSTRIKE)) > 0 && rnd()%1000 <= sstatus->luk*3 ) skill->castend_damage_id(src,bl,RA_WUGSTRIKE,temp,tick,0); // Gank - if(dstmd && sd->status.weapon != W_BOW && + if(dstmd && sd->weapontype != W_BOW && (temp=pc->checkskill(sd,RG_SNATCHER)) > 0 && (temp*15 + 55) + pc->checkskill(sd,TF_STEAL)*10 > rnd()%1000) { if(pc->steal_item(sd,bl,pc->checkskill(sd,TF_STEAL))) @@ -2012,7 +2012,7 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in if (sd->bonus.unbreakable) rate -= rate*sd->bonus.unbreakable/100; if (where&EQP_WEAPON) { - switch (sd->status.weapon) { + switch (sd->weapontype) { case W_FIST: //Bare fists should not break :P case W_1HAXE: case W_2HAXE: @@ -5917,7 +5917,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case SA_LIGHTNINGLOADER: case SA_SEISMICWEAPON: if (dstsd) { - if(dstsd->status.weapon == W_FIST || + if (dstsd->weapontype == W_FIST || (dstsd->sc.count && !dstsd->sc.data[type] && ( //Allow re-enchanting to lengthen time. [Skotlex] dstsd->sc.data[SC_PROPERTYFIRE] || @@ -13391,7 +13391,7 @@ int skill_isammotype (struct map_session_data *sd, int skill_id) nullpo_ret(sd); return ( battle_config.arrow_decrement==2 && - (sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)) && + (sd->weapontype == W_BOW || (sd->weapontype >= W_REVOLVER && sd->weapontype <= W_GRENADE)) && skill_id != HT_PHANTASMIC && skill->get_type(skill_id) == BF_WEAPON && !(skill->get_nk(skill_id)&NK_NO_DAMAGE) && @@ -14245,7 +14245,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id } break; case ST_SHIELD: - if(sd->status.shield <= 0) { + if (!sd->has_shield) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } @@ -14555,7 +14555,7 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id, clif->messagecolor_self(sd->fd, COLOR_RED, e_msg); return 0; } - if (!(require.ammo&1<<sd->inventory_data[i]->look)) { //Ammo type check. Send the "wrong weapon type" message + if (!(require.ammo&1<<sd->inventory_data[i]->subtype)) { //Ammo type check. Send the "wrong weapon type" message //which is the closest we have to wrong ammo type. [Skotlex] clif->arrow_fail(sd,0); //Haplo suggested we just send the equip-arrows message instead. [Skotlex] //clif->skill_fail(sd,skill_id,USESKILL_FAIL_THIS_WEAPON,0); diff --git a/src/map/status.c b/src/map/status.c index c98857736..e04769e3f 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2713,9 +2713,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) sd->left_weapon.atkmods[1] = status->dbs->atkmods[1][sd->weapontype2]; sd->left_weapon.atkmods[2] = status->dbs->atkmods[2][sd->weapontype2]; - if ((pc_isridingpeco(sd) || pc_isridingdragon(sd)) - && (sd->status.weapon==W_1HSPEAR || sd->status.weapon==W_2HSPEAR) - ) { + if ((pc_isridingpeco(sd) || pc_isridingdragon(sd)) && (sd->weapontype == W_1HSPEAR || sd->weapontype == W_2HSPEAR)) { //When Riding with spear, damage modifier to mid-class becomes //same as versus large size. sd->right_weapon.atkmods[1] = sd->right_weapon.atkmods[2]; @@ -2779,8 +2777,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) // Base batk value is set on status->calc_misc // weapon-type bonus (FIXME: Why is the weapon_atk bonus applied to base attack?) - if (sd->status.weapon < MAX_SINGLE_WEAPON_TYPE && sd->weapon_atk[sd->status.weapon]) - bstatus->batk += sd->weapon_atk[sd->status.weapon]; + if (sd->weapontype < MAX_SINGLE_WEAPON_TYPE && sd->weapon_atk[sd->weapontype]) + bstatus->batk += sd->weapon_atk[sd->weapontype]; // Absolute modifiers from passive skills #ifndef RENEWAL if((skill_lv=pc->checkskill(sd,BS_HILTBINDING))>0) // it doesn't work in RE. @@ -2928,10 +2926,10 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) #ifndef RENEWAL bstatus->hit += skill_lv; #endif - if(sd->status.weapon == W_BOW) + if (sd->weapontype == W_BOW) bstatus->rhw.range += skill_lv; } - if(sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE) { + if (sd->weapontype >= W_REVOLVER && sd->weapontype <= W_GRENADE) { if((skill_lv=pc->checkskill(sd,GS_SINGLEACTION))>0) bstatus->hit += 2*skill_lv; if((skill_lv=pc->checkskill(sd,GS_SNAKEEYE))>0) { @@ -2939,9 +2937,9 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) bstatus->rhw.range += skill_lv; } } - if( (sd->status.weapon == W_1HAXE || sd->status.weapon == W_2HAXE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0 ) + if ((sd->weapontype == W_1HAXE || sd->weapontype == W_2HAXE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0) bstatus->hit += 3*skill_lv; - if((sd->status.weapon == W_MACE || sd->status.weapon == W_2HMACE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0) + if ((sd->weapontype == W_MACE || sd->weapontype == W_2HMACE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0) bstatus->hit += 2*skill_lv; if (pc->checkskill(sd, SU_POWEROFLIFE) > 0) bstatus->hit += 20; @@ -3001,12 +2999,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) // Relative modifiers from passive skills #ifndef RENEWAL_ASPD - if((skill_lv=pc->checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK) + if (sd->weapontype == W_BOOK && (skill_lv=pc->checkskill(sd,SA_ADVANCEDBOOK)) > 0) bstatus->aspd_rate -= 5*skill_lv; if((skill_lv = pc->checkskill(sd,SG_DEVIL)) > 0 && !pc->nextjobexp(sd)) bstatus->aspd_rate -= 30*skill_lv; - if((skill_lv=pc->checkskill(sd,GS_SINGLEACTION))>0 && - (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)) + if (sd->weapontype >= W_REVOLVER && sd->weapontype <= W_GRENADE && (skill_lv=pc->checkskill(sd,GS_SINGLEACTION)) > 0) bstatus->aspd_rate -= ((skill_lv+1)/2) * 10; if (pc_isridingpeco(sd)) bstatus->aspd_rate += 500-100*pc->checkskill(sd,KN_CAVALIERMASTERY); @@ -3896,7 +3893,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) } else { st->cri = status->calc_critical(bl, sc, bst->cri + 3*(st->luk - bst->luk), true); } - if (battle_config.show_katar_crit_bonus && bl->type == BL_PC && BL_UCAST(BL_PC, bl)->status.weapon == W_KATAR) { + if (battle_config.show_katar_crit_bonus && bl->type == BL_PC && BL_UCAST(BL_PC, bl)->weapontype == W_KATAR) { st->cri *= 2; } } @@ -4327,11 +4324,11 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) nullpo_ret(st); amotion = status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype1]; - if ( sd->status.weapon > MAX_SINGLE_WEAPON_TYPE) + if (sd->weapontype > MAX_SINGLE_WEAPON_TYPE) amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype2] / 4; - if ( sd->status.shield ) + if (sd->has_shield) amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class)][MAX_SINGLE_WEAPON_TYPE]; - switch ( sd->status.weapon ) { + switch (sd->weapontype) { case W_BOW: case W_MUSICAL: case W_WHIP: @@ -4346,15 +4343,15 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) temp = st->dex * st->dex / 5.0f + st->agi * st->agi * 0.5f; } temp = (float)(sqrt(temp) * 0.25f) + 0xc4; - if ( (skill_lv = pc->checkskill(sd, SA_ADVANCEDBOOK)) > 0 && sd->status.weapon == W_BOOK ) + if (sd->weapontype == W_BOOK && (skill_lv = pc->checkskill(sd, SA_ADVANCEDBOOK)) > 0) val += (skill_lv - 1) / 2 + 1; if ( (skill_lv = pc->checkskill(sd, GS_SINGLEACTION)) > 0 ) val += ((skill_lv + 1) / 2); amotion = ((int)(temp + ((float)(status->calc_aspd(&sd->bl, &sd->sc, 1) + val) * st->agi / 200)) - min(amotion, 200)); #else // base weapon delay - amotion = (sd->status.weapon < MAX_SINGLE_WEAPON_TYPE) - ? (status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->status.weapon]) // single weapon + amotion = (sd->weapontype < MAX_SINGLE_WEAPON_TYPE) + ? (status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype]) // single weapon : (status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype1] + status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype2]) * 7 / 10; // dual-wield // percentual delay reduction from stats @@ -4381,7 +4378,7 @@ unsigned short status_base_atk(const struct block_list *bl, const struct status_ return 0; if (bl->type == BL_PC) { - switch (BL_UCCAST(BL_PC, bl)->status.weapon) { + switch (BL_UCCAST(BL_PC, bl)->weapontype) { case W_BOW: case W_MUSICAL: case W_WHIP: @@ -5942,7 +5939,7 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl if (bl->type != BL_PC) { bonus = sc->data[SC_ASSNCROS]->val2; } else { - switch (BL_UCCAST(BL_PC, bl)->status.weapon) { + switch (BL_UCCAST(BL_PC, bl)->weapontype) { case W_BOW: case W_REVOLVER: case W_RIFLE: @@ -6103,7 +6100,7 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int if (bl->type != BL_PC) { max = sc->data[SC_ASSNCROS]->val2; } else { - switch (BL_UCCAST(BL_PC, bl)->status.weapon) { + switch (BL_UCCAST(BL_PC, bl)->weapontype) { case W_BOW: case W_REVOLVER: case W_RIFLE: @@ -6867,13 +6864,13 @@ void status_set_viewdata(struct block_list *bl, int class_) } sd->vd.class = class_; clif->get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield); - sd->vd.head_top = sd->status.head_top; - sd->vd.head_mid = sd->status.head_mid; - sd->vd.head_bottom = sd->status.head_bottom; + sd->vd.head_top = sd->status.look.head_top; + sd->vd.head_mid = sd->status.look.head_mid; + sd->vd.head_bottom = sd->status.look.head_bottom; sd->vd.hair_style = cap_value(sd->status.hair,0,battle_config.max_hair_style); sd->vd.hair_color = cap_value(sd->status.hair_color,0,battle_config.max_hair_color); sd->vd.cloth_color = cap_value(sd->status.clothes_color,0,battle_config.max_cloth_color); - sd->vd.robe = sd->status.robe; + sd->vd.robe = sd->status.look.robe; sd->vd.body_style = sd->status.body; sd->vd.sex = sd->status.sex; @@ -10747,7 +10744,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const } if (begin_spurt && sce->val1 >= 7 && DIFF_TICK(timer->gettick(), starttick) <= 1000 - && (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0)) + && (!sd || (sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST)) ) sc_start(bl, bl,SC_STRUP,100,sce->val1,skill->get_time2(status->sc2skill(type), sce->val1)); } |