diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/char/char.c | 2 | ||||
-rw-r--r-- | src/char/inter.c | 12 | ||||
-rw-r--r-- | src/common/mmo.h | 2 | ||||
-rw-r--r-- | src/common/socket.c | 6 | ||||
-rw-r--r-- | src/login/account_sql.c | 12 | ||||
-rw-r--r-- | src/map/atcommand.c | 21 | ||||
-rw-r--r-- | src/map/battle.c | 56 | ||||
-rw-r--r-- | src/map/clif.c | 224 | ||||
-rw-r--r-- | src/map/clif.h | 1 | ||||
-rw-r--r-- | src/map/intif.c | 30 | ||||
-rw-r--r-- | src/map/itemdb.h | 2 | ||||
-rw-r--r-- | src/map/map.h | 23 | ||||
-rw-r--r-- | src/map/mapreg_sql.c | 12 | ||||
-rw-r--r-- | src/map/mob.c | 47 | ||||
-rw-r--r-- | src/map/mob.h | 6 | ||||
-rw-r--r-- | src/map/npc.c | 9 | ||||
-rw-r--r-- | src/map/npc.h | 2 | ||||
-rw-r--r-- | src/map/packets.h | 5 | ||||
-rw-r--r-- | src/map/packets_struct.h | 61 | ||||
-rw-r--r-- | src/map/pc.c | 70 | ||||
-rw-r--r-- | src/map/pc.h | 2 | ||||
-rw-r--r-- | src/map/script.c | 753 | ||||
-rw-r--r-- | src/map/script.h | 6 | ||||
-rw-r--r-- | src/map/skill.c | 51 | ||||
-rw-r--r-- | src/map/status.c | 737 | ||||
-rw-r--r-- | src/map/status.h | 79 | ||||
-rw-r--r-- | src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc | 16 | ||||
-rw-r--r-- | src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc | 4 | ||||
-rw-r--r-- | src/plugins/HPMHooking/HPMHooking_map.Hooks.inc | 107 |
29 files changed, 1519 insertions, 839 deletions
diff --git a/src/char/char.c b/src/char/char.c index 91d0870d1..e991aafcc 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -2117,7 +2117,7 @@ void char_mmo_char_send_slots_info(int fd, struct char_session_data* sd) { WFIFOW(fd,2) = 29; WFIFOB(fd,4) = sd->char_slots; WFIFOB(fd,5) = MAX_CHARS - sd->char_slots; - WFIFOB(fd,6) = MAX_CHARS - sd->char_slots; + WFIFOB(fd,6) = 0; WFIFOB(fd,7) = sd->char_slots; WFIFOB(fd,8) = sd->char_slots; memset(WFIFOP(fd,9), 0, 20); // unused bytes diff --git a/src/char/inter.c b/src/char/inter.c index 5b81a4732..87ecb4e6a 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -1186,7 +1186,7 @@ int mapif_parse_Registry(int fd) if( count ) { int cursor = 14, i; - char key[32], sval[254]; + char key[SCRIPT_VARNAME_LENGTH+1], sval[254]; bool isLoginActive = sockt->session_is_active(chr->login_fd); if( isLoginActive ) @@ -1194,8 +1194,9 @@ int mapif_parse_Registry(int fd) for(i = 0; i < count; i++) { unsigned int index; - safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); - cursor += RFIFOB(fd, cursor) + 1; + int len = RFIFOB(fd, cursor); + safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), min((int)sizeof(key), len)); + cursor += len + 1; index = RFIFOL(fd, cursor); cursor += 4; @@ -1211,8 +1212,9 @@ int mapif_parse_Registry(int fd) break; /* str */ case 2: - safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); - cursor += RFIFOB(fd, cursor) + 1; + len = RFIFOB(fd, cursor); + safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len)); + cursor += len + 1; inter->savereg(account_id,char_id,key,index,(intptr_t)sval,true); break; case 3: diff --git a/src/common/mmo.h b/src/common/mmo.h index cb8a75b24..8444a8d67 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -214,6 +214,8 @@ #define JOBL_BABY 0x2000 //8192 #define JOBL_THIRD 0x4000 //16384 +#define SCRIPT_VARNAME_LENGTH 32 ///< Maximum length of a script variable + struct hplugin_data_store; enum item_types { diff --git a/src/common/socket.c b/src/common/socket.c index 87575f5c3..f67c3d074 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -254,7 +254,11 @@ fd_set readfds; // Maximum packet size in bytes, which the client is able to handle. // Larger packets cause a buffer overflow and stack corruption. -static size_t socket_max_client_packet = 24576; +#if PACKETVER >= 20131223 +static size_t socket_max_client_packet = 0xFFFF; +#else +static size_t socket_max_client_packet = 0x6000; +#endif #ifdef SHOW_SERVER_STATS // Data I/O statistics diff --git a/src/login/account_sql.c b/src/login/account_sql.c index 89f4aaaab..1de0fb5e9 100644 --- a/src/login/account_sql.c +++ b/src/login/account_sql.c @@ -714,12 +714,13 @@ void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id) { sql_handle = db->accounts; if (count) { int cursor = 14, i; - char key[32], sval[254]; + char key[SCRIPT_VARNAME_LENGTH+1], sval[254]; for (i = 0; i < count; i++) { unsigned int index; - safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); - cursor += RFIFOB(fd, cursor) + 1; + int len = RFIFOB(fd, cursor); + safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), min((int)sizeof(key), len)); + cursor += len + 1; index = RFIFOL(fd, cursor); cursor += 4; @@ -737,8 +738,9 @@ void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id) { break; /* str */ case 2: - safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); - cursor += RFIFOB(fd, cursor) + 1; + len = RFIFOB(fd, cursor); + safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len)); + cursor += len + 1; if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", db->global_acc_reg_str_db, account_id, key, index, sval) ) Sql_ShowDebug(sql_handle); break; diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 889deac49..d90b4af55 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -1531,7 +1531,7 @@ ACMD(help) { } // Display help contents - clif->message(fd, tinfo->help); + clif->messageln(fd, tinfo->help); return true; } @@ -3889,6 +3889,8 @@ ACMD(mapinfo) { strcat(atcmd_output, msg_fd(fd,1096)); // PartyLock | if (map->list[m_id].flag.guildlock) strcat(atcmd_output, msg_fd(fd,1097)); // GuildLock | + if (map->list[m_id].flag.noviewid) + strcat(atcmd_output, msg_fd(fd,1079)); // NoViewID | clif->message(fd, atcmd_output); switch (list) { @@ -7540,7 +7542,7 @@ ACMD(mapflag) { CHECKFLAG(nojobexp); CHECKFLAG(nomobloot); CHECKFLAG(nomvploot); CHECKFLAG(nightenabled); CHECKFLAG(nodrop); CHECKFLAG(novending); CHECKFLAG(loadevent); CHECKFLAG(nochat); CHECKFLAG(partylock); CHECKFLAG(guildlock); CHECKFLAG(src4instance); - CHECKFLAG(notomb); CHECKFLAG(nocashshop); + CHECKFLAG(notomb); CHECKFLAG(nocashshop); CHECKFLAG(noviewid); clif->message(sd->fd," "); clif->message(sd->fd,msg_fd(fd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On) clif->message(sd->fd,msg_fd(fd,1313)); // Type "@mapflag available" to list the available mapflags. @@ -7577,7 +7579,7 @@ ACMD(mapflag) { SETFLAG(nojobexp); SETFLAG(nomobloot); SETFLAG(nomvploot); SETFLAG(nightenabled); SETFLAG(nodrop); SETFLAG(novending); SETFLAG(loadevent); SETFLAG(nochat); SETFLAG(partylock); SETFLAG(guildlock); SETFLAG(src4instance); - SETFLAG(notomb); SETFLAG(nocashshop); + SETFLAG(notomb); SETFLAG(nocashshop); SETFLAG(noviewid); clif->message(sd->fd,msg_fd(fd,1314)); // Invalid flag name or flag. clif->message(sd->fd,msg_fd(fd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On) @@ -7589,7 +7591,7 @@ ACMD(mapflag) { clif->message(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,"); clif->message(sd->fd,"fog, fireworks, sakura, leaves, nobaseexp, nojobexp, nomobloot,"); clif->message(sd->fd,"nomvploot, nightenabled, nodrop, novending, loadevent, nochat, partylock,"); - clif->message(sd->fd,"guildlock, src4instance, notomb, nocashshop"); + clif->message(sd->fd,"guildlock, src4instance, notomb, nocashshop, noviewid"); #undef CHECKFLAG #undef SETFLAG @@ -8436,14 +8438,15 @@ ACMD(accinfo) { } /* [Ind] */ -ACMD(set) { - char reg[32], val[128]; +ACMD(set) +{ + char reg[SCRIPT_VARNAME_LENGTH+1], val[254]; struct script_data* data; int toset = 0; bool is_str = false; size_t len; - if (!*message || (toset = sscanf(message, "%31s %127[^\n]s", reg, val)) < 1) { + if (!*message || (toset = sscanf(message, "%32s %253[^\n]", reg, val)) < 1) { clif->message(fd, msg_fd(fd,1367)); // Usage: @set <variable name> <value> clif->message(fd, msg_fd(fd,1368)); // Usage: ex. "@set PoringCharVar 50" clif->message(fd, msg_fd(fd,1369)); // Usage: ex. "@set PoringCharVarSTR$ Super Duper String" @@ -10092,8 +10095,8 @@ void atcommand_config_read(const char* config_filename) { if( commandinfo->help == NULL ) { const char *str = libconfig->setting_get_string(command); size_t len = strlen(str); - commandinfo->help = aMalloc( len * sizeof(char) ); - safestrncpy(commandinfo->help, str, len); + commandinfo->help = aMalloc(len + 1); + safestrncpy(commandinfo->help, str, len + 1); } } } diff --git a/src/map/battle.c b/src/map/battle.c index 51de87a4a..1c3817a31 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1188,9 +1188,9 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ else if( cardfix != 1000 ) damage = damage * cardfix / 1000; #else - if ( (cflag & 1) && cardfix_ != 100 ) - damage += damage * (cardfix - 100) / 100; - else if ( cardfix != 100 ) + if ((cflag & 1) && cardfix_ != 100) + damage += damage * (cardfix_ - 100) / 100; + else if (cardfix != 100) damage += damage * (cardfix - 100) / 100; #endif } @@ -3327,16 +3327,16 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam * Calculates BG related damage adjustments. *------------------------------------------*/ // FIXME: flag is undocumented -int64 battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int64 damage, int div_, uint16 skill_id, uint16 skill_lv, int flag) -{ - if( !damage ) +int64 battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int64 damage, int div_, uint16 skill_id, uint16 skill_lv, int flag) { + + if (!damage) return 0; nullpo_retr(damage, bl); - if( bl->type == BL_MOB ) { + if (bl->type == BL_MOB) { struct mob_data* md = BL_CAST(BL_MOB, bl); - if( flag&BF_SKILL && (md->class_ == MOBID_BLUE_CRYST || md->class_ == MOBID_PINK_CRYST) ) + if (flag&BF_SKILL && (md->class_ == MOBID_BLUE_CRYSTAL || md->class_ == MOBID_PINK_CRYSTAL)) return 0; // Crystal cannot receive skill damage on battlegrounds } @@ -4905,7 +4905,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if(flag.cri && sd->bonus.crit_atk_rate) ATK_ADDRATE(sd->bonus.crit_atk_rate); if(flag.cri && sc && sc->data[SC_MTF_CRIDAMAGE]) - ATK_ADDRATE(25);// temporary it should be 'bonus.crit_atk_rate' + ATK_ADDRATE(sc->data[SC_MTF_CRIDAMAGE]->val1);// temporary it should be 'bonus.crit_atk_rate' #ifndef RENEWAL if(sd->status.party_id && (temp=pc->checkskill(sd,TK_POWER)) > 0){ @@ -5218,7 +5218,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if( wd.flag&BF_LONG ) ATK_ADDRATE(sd->bonus.long_attack_atk_rate); if( sc && sc->data[SC_MTF_RANGEATK] ) - ATK_ADDRATE(25);// temporary it should be 'bonus.long_attack_atk_rate' + ATK_ADDRATE(sc->data[SC_MTF_RANGEATK]->val1);// temporary it should be 'bonus.long_attack_atk_rate' #endif if( (i=pc->checkskill(sd,AB_EUCHARISTICA)) > 0 && (tstatus->race == RC_DEMON || tstatus->def_ele == ELE_DARK) ) @@ -5668,11 +5668,18 @@ struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct bl } else // Some skills like Weaponry Research will cause damage even if attack is dodged d.dmg_lv = ATK_DEF; - if(sd && d.damage+d.damage2>1) { - if(sd->bonus.sp_vanish_rate && sd->bonus.sp_vanish_trigger && rnd()%10000<sd->bonus.sp_vanish_rate && - ( (d.flag&sd->bonus.sp_vanish_trigger&BF_WEAPONMASK) || (d.flag&sd->bonus.sp_vanish_trigger&BF_RANGEMASK) - || (d.flag&sd->bonus.sp_vanish_trigger&BF_SKILLMASK) )) - status_percent_damage(&sd->bl,target,0,-sd->bonus.sp_vanish_per,false); + if (sd && d.damage + d.damage2 > 1) { + // HPVanishRate + if (sd->bonus.hp_vanish_rate && sd->bonus.hp_vanish_trigger && rnd() % 1000 < sd->bonus.hp_vanish_rate && + ((d.flag&sd->bonus.hp_vanish_trigger&BF_WEAPONMASK) || (d.flag&sd->bonus.hp_vanish_trigger&BF_RANGEMASK) + || (d.flag&sd->bonus.hp_vanish_trigger&BF_SKILLMASK))) + status_percent_damage(&sd->bl, target, -sd->bonus.hp_vanish_per, 0, false); + + // SPVanishRate + if (sd->bonus.sp_vanish_rate && sd->bonus.sp_vanish_trigger && rnd() % 1000 < sd->bonus.sp_vanish_rate && + ((d.flag&sd->bonus.sp_vanish_trigger&BF_WEAPONMASK) || (d.flag&sd->bonus.sp_vanish_trigger&BF_RANGEMASK) + || (d.flag&sd->bonus.sp_vanish_trigger&BF_SKILLMASK))) + status_percent_damage(&sd->bl, target, 0, -sd->bonus.sp_vanish_per, false); } return d; } @@ -5902,7 +5909,7 @@ void battle_drain(TBL_PC *sd, struct block_list *tbl, int64 rdamage, int64 ldama if (i == 0 || i == 2) type = race; else - type = boss?RC_BOSS:RC_NONBOSS; + type = boss ? RC_BOSS : RC_NONBOSS; hp = wd->hp_drain[type].value; if (wd->hp_drain[type].rate) @@ -5912,6 +5919,14 @@ void battle_drain(TBL_PC *sd, struct block_list *tbl, int64 rdamage, int64 ldama if (wd->sp_drain[type].rate) sp += battle->calc_drain(*damage, wd->sp_drain[type].rate, wd->sp_drain[type].per); + // HPVanishRate + if (sd->bonus.hp_vanish_rate && rnd() % 1000 < sd->bonus.hp_vanish_rate && !sd->bonus.hp_vanish_trigger) + status_percent_damage(&sd->bl, tbl, (unsigned char)sd->bonus.hp_vanish_per, 0, false); + + // SPVanishRate + if (sd->bonus.sp_vanish_rate && rnd() % 1000 < sd->bonus.sp_vanish_rate && !sd->bonus.sp_vanish_trigger) + status_percent_damage(&sd->bl, tbl, 0, (unsigned char)sd->bonus.sp_vanish_per, false); + if (hp) { if (wd->hp_drain[type].type) rhp += hp; @@ -5924,17 +5939,14 @@ void battle_drain(TBL_PC *sd, struct block_list *tbl, int64 rdamage, int64 ldama } } - if (sd->bonus.sp_vanish_rate && rnd()%1000 < sd->bonus.sp_vanish_rate && !sd->bonus.sp_vanish_trigger) - status_percent_damage(&sd->bl, tbl, 0, (unsigned char)sd->bonus.sp_vanish_per, false); - - if( sd->sp_gain_race_attack[race] ) + if (sd->sp_gain_race_attack[race]) tsp += sd->sp_gain_race_attack[race]; - if( sd->hp_gain_race_attack[race] ) + if (sd->hp_gain_race_attack[race]) thp += sd->hp_gain_race_attack[race]; if (!thp && !tsp) return; - status->heal(&sd->bl, thp, tsp, battle_config.show_hp_sp_drain?3:1); + status->heal(&sd->bl, thp, tsp, battle_config.show_hp_sp_drain ? 3 : 1); if (rhp || rsp) status_zap(tbl, rhp, rsp); diff --git a/src/map/clif.c b/src/map/clif.c index 6fb7dd04e..a26fece79 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1004,7 +1004,12 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu p.PacketLength = sizeof(p); p.objecttype = clif_bl_type(bl); #endif +#if PACKETVER >= 20131223 + p.AID = bl->id; + p.GID = (sd) ? sd->status.char_id : 0; // CCODE +#else p.GID = bl->id; +#endif p.speed = status->get_speed(bl); p.bodyState = (sc) ? sc->opt1 : 0; p.healthState = (sc) ? sc->opt2 : 0; @@ -1042,8 +1047,8 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu #if PACKETVER >= 20080102 p.font = (sd) ? sd->status.font : 0; #endif -#if PACKETVER >= 20150000 //actual 20120221 - if( bl->type == BL_MOB ) { +#if PACKETVER >= 20120221 + if (battle_config.show_monster_hp_bar && bl->type == BL_MOB && status_get_hp(bl) < status_get_max_hp(bl)) { p.maxHP = status_get_max_hp(bl); p.HP = status_get_hp(bl); p.isBoss = ( ((TBL_MOB*)bl)->spawn && ((TBL_MOB*)bl)->spawn->state.boss ) ? 1 : 0; @@ -1053,6 +1058,9 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu p.isBoss = 0; } #endif +#if PACKETVER >= 20150513 + p.body = 0; +#endif clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target); @@ -1136,7 +1144,12 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) { p.PacketLength = sizeof(p); p.objecttype = clif_bl_type(bl); #endif +#if PACKETVER >= 20131223 + p.AID = bl->id; + p.GID = (sd) ? sd->status.char_id : 0; // CCODE +#else p.GID = bl->id; +#endif p.speed = status->get_speed(bl); p.bodyState = (sc) ? sc->opt1 : 0; p.healthState = (sc) ? sc->opt2 : 0; @@ -1173,8 +1186,8 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) { #if PACKETVER >= 20080102 p.font = (sd) ? sd->status.font : 0; #endif -#if PACKETVER >= 20150000 //actual 20120221 - if( bl->type == BL_MOB ) { +#if PACKETVER >= 20120221 + if (battle_config.show_monster_hp_bar && bl->type == BL_MOB && status_get_hp(bl) < status_get_max_hp(bl)) { p.maxHP = status_get_max_hp(bl); p.HP = status_get_hp(bl); p.isBoss = ( ((TBL_MOB*)bl)->spawn && ((TBL_MOB*)bl)->spawn->state.boss ) ? 1 : 0; @@ -1184,6 +1197,9 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) { p.isBoss = 0; } #endif +#if PACKETVER >= 20150513 + p.body = 0; +#endif if( disguised(bl) ) { nullpo_retv(sd); if( sd->status.class_ != sd->disguise ) @@ -1222,7 +1238,12 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd, #if PACKETVER >= 20071106 p.objecttype = clif_bl_type(bl); #endif +#if PACKETVER >= 20131223 + p.AID = bl->id; + p.GID = (tsd) ? tsd->status.char_id : 0; // CCODE +#else p.GID = bl->id; +#endif p.speed = status->get_speed(bl); p.bodyState = (sc) ? sc->opt1 : 0; p.healthState = (sc) ? sc->opt2 : 0; @@ -1255,8 +1276,8 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd, #if PACKETVER >= 20080102 p.font = (sd) ? sd->status.font : 0; #endif -#if PACKETVER >= 20150000 //actual 20120221 - if( bl->type == BL_MOB ) { +#if PACKETVER >= 20120221 + if (battle_config.show_monster_hp_bar && bl->type == BL_MOB && status_get_hp(bl) < status_get_max_hp(bl)) { p.maxHP = status_get_max_hp(bl); p.HP = status_get_hp(bl); p.isBoss = ( ((TBL_MOB*)bl)->spawn && ((TBL_MOB*)bl)->spawn->state.boss ) ? 1 : 0; @@ -1266,6 +1287,9 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd, p.isBoss = 0; } #endif +#if PACKETVER >= 20150513 + p.body = 0; +#endif clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target); @@ -4173,7 +4197,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) { clif->specialeffect_single(bl,423,sd->fd); else if(md->special_state.size==SZ_MEDIUM) clif->specialeffect_single(bl,421,sd->fd); -#if PACKETVER >= 20120404 +#if (PACKETVER >= 20120404 && PACKETVER < 20131223) if (battle_config.show_monster_hp_bar && !(md->status.mode&MD_BOSS)) { int i; for(i = 0; i < DAMAGELOG_SIZE; i++) {// must show hp bar to all char who already hit the mob. @@ -4224,6 +4248,7 @@ int clif_calc_walkdelay(struct block_list *bl,int delay, int type, int damage, i /// Sends a 'damage' packet (src performs action on dst) /// 008a <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.W <div>.W <type>.B <damage2>.W (ZC_NOTIFY_ACT) /// 02e1 <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.L <div>.W <type>.B <damage2>.L (ZC_NOTIFY_ACT2) +/// 08c8 <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.L <IsSPDamage>.B <div>.W <type>.B <damage2>.L (ZC_NOTIFY_ACT2) /// type: @see enum battle_dmg_type /// for BDT_NORMAL: [ damage: total damage, div: amount of hits, damage2: assassin dual-wield damage ] int clif_damage(struct block_list* src, struct block_list* dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type, int64 in_damage2) { @@ -4271,6 +4296,9 @@ int clif_damage(struct block_list* src, struct block_list* dst, int sdelay, int p.damage = damage; p.leftDamage = damage2; } +#if PACKETVER >= 20131223 + p.is_sp_damaged = 0; // [ToDo] IsSPDamage - Displays blue digits. +#endif if(disguised(dst)) { clif->send(&p,sizeof(p),dst,AREA_WOS); @@ -4953,84 +4981,92 @@ int clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick nullpo_ret(src); nullpo_ret(dst); - damage = (int)cap_value(in_damage,INT_MIN,INT_MAX); - type = clif_calc_delay(type,div,damage,ddelay); + damage = (int)cap_value(in_damage, INT_MIN, INT_MAX); + type = clif_calc_delay(type, div, damage, ddelay); #if PACKETVER >= 20131223 - if( type == 6 ) type = 8; //bugreport:8263 + if (type == BDT_SKILL) type = BDT_MULTIHIT; //bugreport:8263 #endif - if( ( sc = status->get_sc(dst) ) && sc->count ) { - if(sc->data[SC_ILLUSION] && damage) - damage = damage*(sc->data[SC_ILLUSION]->val2) + rnd()%100; + if ((sc = status->get_sc(dst)) && sc->count) { + if (sc->data[SC_ILLUSION] && damage) + damage = damage * (sc->data[SC_ILLUSION]->val2) + rnd() % 100; } #if PACKETVER < 3 - WBUFW(buf,0)=0x114; - WBUFW(buf,2)=skill_id; - WBUFL(buf,4)=src->id; - WBUFL(buf,8)=dst->id; - WBUFL(buf,12)=(uint32)tick; - WBUFL(buf,16)=sdelay; - WBUFL(buf,20)=ddelay; + WBUFW(buf, 0) = 0x114; + WBUFW(buf, 2) = skill_id; + WBUFL(buf, 4) = src->id; + WBUFL(buf, 8) = dst->id; + WBUFL(buf, 12) = (uint32)tick; + WBUFL(buf, 16) = sdelay; + WBUFL(buf, 20) = ddelay; if (battle_config.hide_woe_damage && map_flag_gvg2(src->m)) { - WBUFW(buf,24)=damage?div:0; + WBUFW(buf, 24) = damage ? div : 0; } else { - WBUFW(buf,24)=damage; + WBUFW(buf, 24) = damage; } - WBUFW(buf,26)=skill_lv; - WBUFW(buf,28)=div; - WBUFB(buf,30)=type; + WBUFW(buf, 26) = skill_lv; + WBUFW(buf, 28) = div; + WBUFB(buf, 30) = type; if (disguised(dst)) { - clif->send(buf,packet_len(0x114),dst,AREA_WOS); - WBUFL(buf,8)=-dst->id; - clif->send(buf,packet_len(0x114),dst,SELF); + clif->send(buf, packet_len(0x114), dst, AREA_WOS); + WBUFL(buf, 8) = -dst->id; + clif->send(buf, packet_len(0x114), dst, SELF); } else - clif->send(buf,packet_len(0x114),dst,AREA); + clif->send(buf, packet_len(0x114), dst, AREA); - if(disguised(src)) { - WBUFL(buf,4)=-src->id; + if (disguised(src)) { + WBUFL(buf, 4) = -src->id; if (disguised(dst)) - WBUFL(buf,8)=dst->id; - if(damage > 0) - WBUFW(buf,24)=-1; - clif->send(buf,packet_len(0x114),src,SELF); + WBUFL(buf, 8) = dst->id; + if (damage > 0) + WBUFW(buf, 24) = -1; + clif->send(buf, packet_len(0x114), src, SELF); } #else - WBUFW(buf,0)=0x1de; - WBUFW(buf,2)=skill_id; - WBUFL(buf,4)=src->id; - WBUFL(buf,8)=dst->id; - WBUFL(buf,12)=(uint32)tick; - WBUFL(buf,16)=sdelay; - WBUFL(buf,20)=ddelay; + WBUFW(buf, 0) = 0x1de; + WBUFW(buf, 2) = skill_id; + WBUFL(buf, 4) = src->id; + WBUFL(buf, 8) = dst->id; + WBUFL(buf, 12) = (uint32)tick; + WBUFL(buf, 16) = sdelay; + WBUFL(buf, 20) = ddelay; if (battle_config.hide_woe_damage && map_flag_gvg2(src->m)) { - WBUFL(buf,24)=damage?div:0; + WBUFL(buf, 24) = damage ? div : 0; } else { - WBUFL(buf,24)=damage; - } - WBUFW(buf,28)=skill_lv; - WBUFW(buf,30)=div; - WBUFB(buf,32)=type; + WBUFL(buf, 24) = damage; + } + WBUFW(buf, 28) = skill_lv; + WBUFW(buf, 30) = div; + // For some reason, late 2013 and newer clients have + // a issue that causes players and monsters to endure + // type 6 (ACTION_SKILL) skills. So we have to do a small + // hack to set all type 6 to be sent as type 8 ACTION_ATTACK_MULTIPLE +#if PACKETVER < 20131223 + WBUFB(buf, 32) = type; +#else + WBUFB(buf, 32) = (type == BDT_SKILL) ? BDT_MULTIHIT : type; +#endif if (disguised(dst)) { - clif->send(buf,packet_len(0x1de),dst,AREA_WOS); + clif->send(buf, packet_len(0x1de), dst, AREA_WOS); WBUFL(buf,8)=-dst->id; - clif->send(buf,packet_len(0x1de),dst,SELF); + clif->send(buf, packet_len(0x1de), dst, SELF); } else - clif->send(buf,packet_len(0x1de),dst,AREA); + clif->send(buf, packet_len(0x1de), dst, AREA); - if(disguised(src)) { - WBUFL(buf,4)=-src->id; + if (disguised(src)) { + WBUFL(buf, 4) = -src->id; if (disguised(dst)) - WBUFL(buf,8)=dst->id; - if(damage > 0) - WBUFL(buf,24)=-1; - clif->send(buf,packet_len(0x1de),src,SELF); + WBUFL(buf, 8) = dst->id; + if (damage > 0) + WBUFL(buf, 24) = -1; + clif->send(buf, packet_len(0x1de), src, SELF); } #endif //Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex] - return clif->calc_walkdelay(dst,ddelay,type,damage,div); + return clif->calc_walkdelay(dst, ddelay, type, damage, div); } /// Ground skill attack effect and damage (ZC_NOTIFY_SKILL_POSITION). @@ -6738,29 +6774,30 @@ void clif_pet_roulette(struct map_session_data *sd,int data) /// Presents a list of pet eggs that can be hatched (ZC_PETEGG_LIST). /// 01a6 <packet len>.W { <index>.W }* -void clif_sendegg(struct map_session_data *sd) -{ - int i,n=0,fd; +void clif_sendegg(struct map_session_data *sd) { + int i, n, fd; nullpo_retv(sd); - fd=sd->fd; + fd = sd->fd; if (battle_config.pet_no_gvg && map_flag_gvg2(sd->bl.m)) { //Disable pet hatching in GvG grounds during Guild Wars [Skotlex] - clif->message(fd, msg_sd(sd,866)); // "Pets are not allowed in Guild Wars." + clif->message(fd, msg_sd(sd, 866)); // "Pets are not allowed in Guild Wars." return; } + WFIFOHEAD(fd, MAX_INVENTORY * 2 + 4); - WFIFOW(fd,0)=0x1a6; - for(i=0,n=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid<=0 || sd->inventory_data[i] == NULL || - sd->inventory_data[i]->type!=IT_PETEGG || - sd->status.inventory[i].amount<=0) + WFIFOW(fd,0) = 0x1a6; + for (i = n = 0; i < MAX_INVENTORY; i++) { + if (sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL || sd->inventory_data[i]->type!=IT_PETEGG || sd->status.inventory[i].amount <= 0) continue; - WFIFOW(fd,n*2+4)=i+2; + WFIFOW(fd, n * 2 + 4) = i + 2; n++; } - WFIFOW(fd,2)=4+n*2; - WFIFOSET(fd,WFIFOW(fd,2)); + + if (!n) return; + + WFIFOW(fd, 2) = 4 + n * 2; + WFIFOSET(fd, WFIFOW(fd, 2)); sd->menuskill_id = SA_TAMINGMONSTER; sd->menuskill_val = -1; @@ -9969,6 +10006,9 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, break; } + if (sd->sc.data[SC_SITDOWN_FORCE] || sd->sc.data[SC_BANANA_BOMB_SITDOWN_POSTDELAY]) + return; + if(pc_issit(sd)) { //Bugged client? Just refresh them. clif->sitting(&sd->bl); @@ -9992,6 +10032,10 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, clif->sitting(&sd->bl); break; case 0x03: // standup + + if (sd->sc.data[SC_SITDOWN_FORCE] || sd->sc.data[SC_BANANA_BOMB_SITDOWN_POSTDELAY]) + return; + if (!pc_issit(sd)) { //Bugged client? Just refresh them. clif->standing(&sd->bl); @@ -17468,18 +17512,18 @@ void clif_maptypeproperty2(struct block_list *bl,enum send_target t) { p.PacketType = maptypeproperty2Type; p.type = 0x28; - p.flag.party = map->list[bl->m].flag.pvp ? 1 : 0; - p.flag.guild = (map->list[bl->m].flag.battleground || map_flag_gvg(bl->m)) ? 1 : 0; - p.flag.siege = (map->list[bl->m].flag.battleground || map_flag_gvg2(bl->m)) ? 1: 0; - p.flag.mineffect = map_flag_gvg(bl->m) ? 1 : ( (sd && sd->state.lesseffect) ? 1 : 0); // Forcing /mineffect in castles during WoE (probably redundant? I'm not sure) - p.flag.nolockon = 0; // TODO - p.flag.countpk = map->list[bl->m].flag.pvp ? 1 : 0; - p.flag.nopartyformation = map->list[bl->m].flag.partylock ? 1 : 0; - p.flag.bg = map->list[bl->m].flag.battleground ? 1 : 0; - p.flag.noitemconsumption = 0; // TODO - p.flag.summonstarmiracle = 0; // TODO - p.flag.usecart = 1; // TODO - p.flag.SpareBits = 0; + p.flag.party = map->list[bl->m].flag.pvp ? 1 : 0; //PARTY + p.flag.guild = (map->list[bl->m].flag.battleground || map_flag_gvg(bl->m)) ? 1 : 0; // GUILD + p.flag.siege = (map->list[bl->m].flag.battleground || map_flag_gvg2(bl->m)) ? 1: 0; // SIEGE + p.flag.mineffect = map_flag_gvg(bl->m) ? 1 : ( (sd && sd->state.lesseffect) ? 1 : 0); // USE_SIMPLE_EFFECT - Forcing /mineffect in castles during WoE (probably redundant? I'm not sure) + p.flag.nolockon = 0; // DISABLE_LOCKON - TODO + p.flag.countpk = map->list[bl->m].flag.pvp ? 1 : 0; // COUNT_PK + p.flag.nopartyformation = map->list[bl->m].flag.partylock ? 1 : 0; // NO_PARTY_FORMATION + p.flag.bg = map->list[bl->m].flag.battleground ? 1 : 0; // BATTLEFIELD + p.flag.nocostume = (map->list[bl->m].flag.noviewid & EQP_COSTUME) ? 1 : 0; // DISABLE_COSTUMEITEM - Disables Costume Sprite + p.flag.usecart = 1; // USECART - TODO + p.flag.summonstarmiracle = 0; // SUNMOONSTAR_MIRACLE - TODO + p.flag.SpareBits = 0; // UNUSED clif->send(&p,sizeof(p),bl,t); #endif @@ -18515,6 +18559,19 @@ void clif_cancelmergeitem (int fd, struct map_session_data *sd) return; } +void clif_dressroom_open(struct map_session_data *sd, int view) +{ + int fd; + + nullpo_retv(sd); + + fd = sd->fd; + WFIFOHEAD(fd,packet_len(0xa02)); + WFIFOW(fd,0)=0xa02; + WFIFOW(fd,2)=view; + WFIFOSET(fd,packet_len(0xa02)); +} + /* */ unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) { if( sd ) { @@ -19570,4 +19627,5 @@ void clif_defaults(void) { /* */ clif->add_random_options = clif_add_random_options; clif->pHotkeyRowShift = clif_parse_HotkeyRowShift; + clif->dressroom_open = clif_dressroom_open; } diff --git a/src/map/clif.h b/src/map/clif.h index cbf34d0d0..5a6b01d31 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -1337,6 +1337,7 @@ struct clif_interface { /* */ void (*add_random_options) (unsigned char* buf, struct item* item); void (*pHotkeyRowShift) (int fd, struct map_session_data *sd); + void (*dressroom_open) (struct map_session_data *sd, int view); }; #ifdef HERCULES_CORE diff --git a/src/map/intif.c b/src/map/intif.c index 06b910d54..016b4f7d3 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -333,6 +333,10 @@ int intif_saveregistry(struct map_session_data *sd) { if( varname[0] == '@' ) /* @string$ can get here, so we skip */ continue; + if (strlen(varname) > SCRIPT_VARNAME_LENGTH) { + ShowError("Variable name too big: %s\n", varname); + continue; + } src = DB->data2ptr(data); /* no need! */ @@ -1077,8 +1081,8 @@ void intif_parse_Registers(int fd) /* have it not complain about insertion of vars before loading, and not set those vars as new or modified */ pc->reg_load = true; - if( RFIFOW(fd, 14) ) { - char key[32]; + if (RFIFOW(fd, 14) != 0) { + char key[SCRIPT_VARNAME_LENGTH+1]; unsigned int index; int max = RFIFOW(fd, 14), cursor = 16, i; @@ -1091,16 +1095,18 @@ void intif_parse_Registers(int fd) * { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) } **/ if (type) { - for(i = 0; i < max; i++) { - char sval[254]; - safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); - cursor += RFIFOB(fd, cursor) + 1; + char sval[254]; + for (i = 0; i < max; i++) { + int len = RFIFOB(fd, cursor); + safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), min((int)sizeof(key), len)); + cursor += len + 1; index = RFIFOL(fd, cursor); cursor += 4; - safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); - cursor += RFIFOB(fd, cursor) + 1; + len = RFIFOB(fd, cursor); + safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len)); + cursor += len + 1; script->set_reg(NULL,sd,reference_uid(script->add_str(key), index), key, (void*)sval, NULL); } @@ -1111,10 +1117,12 @@ void intif_parse_Registers(int fd) * { keyLength(B), key(<keyLength>), index(L), value(L) } **/ } else { - for(i = 0; i < max; i++) { + for (i = 0; i < max; i++) { int ival; - safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); - cursor += RFIFOB(fd, cursor) + 1; + + int len = RFIFOB(fd, cursor); + safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), min((int)sizeof(key), len)); + cursor += len + 1; index = RFIFOL(fd, cursor); cursor += 4; diff --git a/src/map/itemdb.h b/src/map/itemdb.h index c804e4b4f..f508f5c1d 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -535,6 +535,8 @@ struct item_data { #define itemdb_iscashfood(n) ((n) >= ITEMID_STR_DISH10_ && (n) <= ITEMID_VIT_DISH10_) #define itemdb_is_GNbomb(n) ((n) >= ITEMID_APPLE_BOMB && (n) <= ITEMID_VERY_HARD_LUMP) #define itemdb_is_GNthrowable(n) ((n) >= ITEMID_MYSTERIOUS_POWDER && (n) <= ITEMID_BLACK_THING_TO_THROW) +#define itemdb_is_shadowequip(n) ((n) & (EQP_SHADOW_ARMOR|EQP_SHADOW_WEAPON|EQP_SHADOW_SHIELD|EQP_SHADOW_SHOES|EQP_SHADOW_ACC_R|EQP_SHADOW_ACC_L)) +#define itemdb_is_costumeequip(n) ((n) & (EQP_COSTUME_HEAD_TOP|EQP_COSTUME_HEAD_MID|EQP_COSTUME_HEAD_LOW|EQP_COSTUME_GARMENT)) //Item trade restrictions [Skotlex] #define itemdb_isdropable(item, gmlv) (itemdb->isrestricted((item), (gmlv), 0, itemdb->isdropable_sub)) diff --git a/src/map/map.h b/src/map/map.h index 84af04f77..d31b1c5d3 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -66,17 +66,17 @@ enum E_MAPSERVER_ST { // Added definitions for WoESE objects. [L0ne_W0lf] enum MOBID { MOBID_EMPERIUM = 1288, - MOBID_TREAS01 = 1324, - MOBID_TREAS40 = 1363, + MOBID_TREASURE_01 = 1324, + MOBID_TREASURE_40 = 1363, MOBID_BARRICADE1 = 1905, MOBID_BARRICADE2, - MOBID_GUARIDAN_STONE1, - MOBID_GUARIDAN_STONE2, - MOBID_FOOD_STOR, - MOBID_BLUE_CRYST = 1914, - MOBID_PINK_CRYST, - MOBID_TREAS41 = 1938, - MOBID_TREAS49 = 1946, + MOBID_GUARDIAN_STONE1, + MOBID_GUARDIAN_STONE2, + MOBID_FOOD_STORAGE, + MOBID_BLUE_CRYSTAL = 1914, + MOBID_PINK_CRYSTAL, + MOBID_TREASURE_41 = 1938, + MOBID_TREASURE_49 = 1946, MOBID_SILVERSNIPER = 2042, MOBID_MAGICDECOY_WIND = 2046, }; @@ -243,6 +243,8 @@ enum { #define map_flag_gvg2(m) (map->list[m].flag.gvg || map->list[m].flag.gvg_castle) // No Kill Steal Protection #define map_flag_ks(m) (map->list[m].flag.town || map->list[m].flag.pvp || map->list[m].flag.gvg || map->list[m].flag.battleground) +// No ViewID +#define map_no_view(m, view) (map->list[m].flag.noviewid & (view)) //This stackable implementation does not means a BL can be more than one type at a time, but it's // meant to make it easier to check for multiple types at a time on invocations such as map_foreach* calls [Skotlex] @@ -465,7 +467,7 @@ enum status_point_types { SP_WEAPON_ATK,SP_WEAPON_ATK_RATE, // 1081-1082 SP_DELAYRATE,SP_HP_DRAIN_RATE_RACE,SP_SP_DRAIN_RATE_RACE, // 1083-1085 SP_IGNORE_MDEF_RATE,SP_IGNORE_DEF_RATE,SP_SKILL_HEAL2,SP_ADDEFF_ONSKILL, //1086-1089 - SP_ADD_HEAL_RATE,SP_ADD_HEAL2_RATE, //1090-1091 + SP_ADD_HEAL_RATE, SP_ADD_HEAL2_RATE, SP_HP_VANISH_RATE, //1090-1092 SP_RESTART_FULL_RECOVER=2000,SP_NO_CASTCANCEL,SP_NO_SIZEFIX,SP_NO_MAGIC_DAMAGE,SP_NO_WEAPON_DAMAGE,SP_NO_GEMSTONE, // 2000-2005 SP_NO_CASTCANCEL2,SP_NO_MISC_DAMAGE,SP_UNBREAKABLE_WEAPON,SP_UNBREAKABLE_ARMOR, SP_UNBREAKABLE_HELM, // 2006-2010 @@ -732,6 +734,7 @@ struct map_data { unsigned noknockback : 1; unsigned notomb : 1; unsigned nocashshop : 1; + unsigned noviewid : 22; } flag; struct point save; struct npc_data *npc[MAX_NPC_PER_MAP]; diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c index ddd259651..9bf67196e 100644 --- a/src/map/mapreg_sql.c +++ b/src/map/mapreg_sql.c @@ -94,9 +94,9 @@ bool mapreg_setreg(int64 uid, int val) { m->save = false; m->is_string = false; - if(name[1] != '@' && !mapreg->skip_insert) {// write new variable to database - char tmp_str[32*2+1]; - SQL->EscapeStringLen(map->mysql_handle, tmp_str, name, strnlen(name, 32)); + if (name[1] != '@' && !mapreg->skip_insert) {// write new variable to database + char tmp_str[(SCRIPT_VARNAME_LENGTH+1)*2+1]; + SQL->EscapeStringLen(map->mysql_handle, tmp_str, name, strnlen(name, SCRIPT_VARNAME_LENGTH+1)); if( SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%d')", mapreg->table, tmp_str, i, val) ) Sql_ShowDebug(map->mysql_handle); } @@ -166,9 +166,9 @@ bool mapreg_setregstr(int64 uid, const char* str) { m->is_string = true; if(name[1] != '@' && !mapreg->skip_insert) { //put returned null, so we must insert. - char tmp_str[32*2+1]; + char tmp_str[(SCRIPT_VARNAME_LENGTH+1)*2+1]; char tmp_str2[255*2+1]; - SQL->EscapeStringLen(map->mysql_handle, tmp_str, name, strnlen(name, 32)); + SQL->EscapeStringLen(map->mysql_handle, tmp_str, name, strnlen(name, SCRIPT_VARNAME_LENGTH+1)); SQL->EscapeStringLen(map->mysql_handle, tmp_str2, str, strnlen(str, 255)); if( SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%s')", mapreg->table, tmp_str, i, tmp_str2) ) Sql_ShowDebug(map->mysql_handle); @@ -191,7 +191,7 @@ void script_load_mapreg(void) { +-------------------------+ */ SqlStmt* stmt = SQL->StmtMalloc(map->mysql_handle); - char varname[32+1]; + char varname[SCRIPT_VARNAME_LENGTH+1]; int index; char value[255+1]; uint32 length; diff --git a/src/map/mob.c b/src/map/mob.c index 0d6055b13..d8fefa61a 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2068,11 +2068,17 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage) { if (battle_config.show_mob_info&3) clif->charnameack (0, &md->bl); + +#if PACKETVER >= 20131223 + // Resend ZC_NOTIFY_MOVEENTRY to Update the HP + if (battle_config.show_monster_hp_bar) + clif->set_unit_walking(&md->bl, NULL, unit->bl2ud(&md->bl), AREA); +#endif if (!src) return; -#if PACKETVER >= 20120404 +#if (PACKETVER >= 20120404 && PACKETVER < 20131223) if (battle_config.show_monster_hp_bar && !(md->status.mode&MD_BOSS)) { int i; for(i = 0; i < DAMAGELOG_SIZE; i++){ // must show hp bar to all char who already hit the mob. @@ -2741,39 +2747,39 @@ int mob_random_class (int *value, size_t count) /*========================================== * Change mob base class *------------------------------------------*/ -int mob_class_change (struct mob_data *md, int class_) -{ +int mob_class_change (struct mob_data *md, int class_) { + int64 tick = timer->gettick(), c = 0; int i, hp_rate; nullpo_ret(md); - if( md->bl.prev == NULL ) + if (md->bl.prev == NULL) return 0; - //Disable class changing for some targets... + // Disable class changing for some targets... if (md->guardian_data) - return 0; //Guardians/Emperium + return 0; // Guardians/Emperium - if( mob_is_treasure(md) ) - return 0; //Treasure Boxes + if (mob_is_treasure(md)) + return 0; // Treasure Boxes - if( md->special_state.ai > AI_ATTACK ) - return 0; //Marine Spheres and Floras. + if (md->special_state.ai > AI_ATTACK) + return 0; // Marine Spheres and Floras. - if( mob->is_clone(md->class_) ) - return 0; //Clones + if (mob->is_clone(md->class_)) + return 0; // Clones - if( md->class_ == class_ ) - return 0; //Nothing to change. + if (md->class_ == class_) + return 0; // Nothing to change. hp_rate = get_percentage(md->status.hp, md->status.max_hp); md->class_ = class_; md->db = mob->db(class_); - if (battle_config.override_mob_names==1) - memcpy(md->name,md->db->name,NAME_LENGTH); + if (battle_config.override_mob_names == 1) + memcpy(md->name, md->db->name, NAME_LENGTH); else - memcpy(md->name,md->db->jname,NAME_LENGTH); + memcpy(md->name, md->db->jname, NAME_LENGTH); mob_stop_attack(md); mob_stop_walking(md, STOPWALKING_FLAG_NONE); @@ -2813,8 +2819,13 @@ void mob_heal(struct mob_data *md, unsigned int heal) { if (battle_config.show_mob_info&3) clif->charnameack (0, &md->bl); +#if PACKETVER >= 20131223 + // Resend ZC_NOTIFY_MOVEENTRY to Update the HP + if (battle_config.show_monster_hp_bar) + clif->set_unit_walking(&md->bl, NULL, unit->bl2ud(&md->bl), AREA); +#endif -#if PACKETVER >= 20120404 +#if (PACKETVER >= 20120404 && PACKETVER < 20131223) if (battle_config.show_monster_hp_bar && !(md->status.mode&MD_BOSS)) { int i; for(i = 0; i < DAMAGELOG_SIZE; i++){ // must show hp bar to all char who already hit the mob. diff --git a/src/map/mob.h b/src/map/mob.h index 6267c0e8c..48b44aab3 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -283,9 +283,9 @@ struct item_drop_list { #define mob_stop_walking(md, type) (unit->stop_walking(&(md)->bl, (type))) #define mob_stop_attack(md) (unit->stop_attack(&(md)->bl)) -#define mob_is_battleground(md) (map->list[(md)->bl.m].flag.battleground && ((md)->class_ == MOBID_BARRICADE2 || ((md)->class_ >= MOBID_FOOD_STOR && (md)->class_ <= MOBID_PINK_CRYST))) -#define mob_is_gvg(md) (map->list[(md)->bl.m].flag.gvg_castle && ( (md)->class_ == MOBID_EMPERIUM || (md)->class_ == MOBID_BARRICADE1 || (md)->class_ == MOBID_GUARIDAN_STONE1 || (md)->class_ == MOBID_GUARIDAN_STONE2)) -#define mob_is_treasure(md) (((md)->class_ >= MOBID_TREAS01 && (md)->class_ <= MOBID_TREAS40) || ((md)->class_ >= MOBID_TREAS41 && (md)->class_ <= MOBID_TREAS49)) +#define mob_is_battleground(md) (map->list[(md)->bl.m].flag.battleground && ((md)->class_ == MOBID_BARRICADE2 || ((md)->class_ >= MOBID_FOOD_STORAGE && (md)->class_ <= MOBID_PINK_CRYSTAL))) +#define mob_is_gvg(md) (map->list[(md)->bl.m].flag.gvg_castle && ( (md)->class_ == MOBID_EMPERIUM || (md)->class_ == MOBID_BARRICADE1 || (md)->class_ == MOBID_GUARDIAN_STONE1 || (md)->class_ == MOBID_GUARDIAN_STONE2)) +#define mob_is_treasure(md) (((md)->class_ >= MOBID_TREASURE_01 && (md)->class_ <= MOBID_TREASURE_40) || ((md)->class_ >= MOBID_TREASURE_41 && (md)->class_ <= MOBID_TREASURE_49)) struct mob_interface { // Dynamic mob database, allows saving of memory when there's big gaps in the mob_db [Skotlex] diff --git a/src/map/npc.c b/src/map/npc.c index 82365efba..09e5c0f46 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -313,8 +313,13 @@ int npc_rr_secure_timeout_timer(int tid, int64 tick, int id, intptr_t data) { * This guy's been idle for longer than allowed, close him. **/ clif->scriptclose(sd,sd->npc_id); - clif->scriptclear(sd,sd->npc_id); sd->npc_idle_timer = INVALID_TIMER; + /** + * We will end the script ourselves, client will request to end it again if it have dialog, + * however it will be ignored, workaround for client stuck if NPC have no dialog. [hemagx] + **/ + sd->state.dialog = 0; + npc->scriptcont(sd, sd->npc_id, true); } else //Create a new instance of ourselves to continue sd->npc_idle_timer = timer->add(timer->gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc->secure_timeout_timer,sd->bl.id,0); #endif @@ -4287,6 +4292,8 @@ const char *npc_parse_mapflag(const char *w1, const char *w2, const char *w3, co map->list[m].flag.src4instance = (state) ? 1 : 0; } else if ( !strcmpi(w3,"nocashshop") ) { map->list[m].flag.nocashshop = (state) ? 1 : 0; + } else if (!strcmpi(w3,"noviewid")) { + map->list[m].flag.noviewid = (state) ? atoi(w4) : 0; } else { npc->parse_unknown_mapflag(mapname, w3, w4, start, buffer, filepath, retval); } diff --git a/src/map/npc.h b/src/map/npc.h index 6f288d722..0b2729bcf 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -138,7 +138,7 @@ enum actor_classes { #define MAX_NPC_CLASS 1000 // New NPC range #define MAX_NPC_CLASS2_START 10001 -#define MAX_NPC_CLASS2_END 10174 +#define MAX_NPC_CLASS2_END 10178 //Script NPC events. enum npce_event { diff --git a/src/map/packets.h b/src/map/packets.h index 0efdcb1ec..9b9c7945f 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -2910,8 +2910,9 @@ packet(0x96e,-1,clif->ackmergeitems); packet(0x08A8,26,clif->pFriendsListAdd,2); packet(0x0817,5,clif->pHomMenu,2,4); packet(0x0923,36,clif->pStoragePassword,0); - packet(0x09e8,11,clif->pDull); //CZ_OPEN_MAILBOX - packet(0x0a2e,6,clif->pDull); //TITLE + packet(0x09e8,11,clif->pDull); // CZ_OPEN_MAILBOX + packet(0x0a2e,6,clif->pDull); // TITLE + packet(0x0a02,4); // ZC_DRESSROOM_OPEN #endif /* PacketKeys: http://herc.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */ diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index a9ccc019d..43ff0737f 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -84,10 +84,14 @@ enum packet_headers { idle_unitType = 0x2ee, #elif PACKETVER < 20101124 idle_unitType = 0x7f9, -#elif PACKETVER < 20150000 //actual 20120221 +#elif PACKETVER < 20120221 idle_unitType = 0x857, -#else +#elif PACKETVER < 20131223 idle_unitType = 0x915, +#elif PACKETVER < 20150513 + idle_unitType = 0x9dd, +#else + idle_unitType = 0x9ff, #endif #if PACKETVER >= 20120618 status_changeType = 0x983, @@ -104,8 +108,10 @@ enum packet_headers { #endif #if PACKETVER < 20071113 damageType = 0x8a, -#else +#elif PACKETVER < 20131223 damageType = 0x2e1, +#else + damageType = 0x8c8, #endif #if PACKETVER < 4 spawn_unitType = 0x79, @@ -117,10 +123,14 @@ enum packet_headers { spawn_unitType = 0x2ed, #elif PACKETVER < 20101124 spawn_unitType = 0x7f8, -#elif PACKETVER < 20150000 //actual 20120221 +#elif PACKETVER < 20120221 spawn_unitType = 0x858, -#else +#elif PACKETVER < 20131223 spawn_unitType = 0x90f, +#elif PACKETVER < 20150513 + spawn_unitType = 0x9dc, +#else + spawn_unitType = 0x9fe, #endif #if PACKETVER < 20080102 authokType = 0x73, @@ -142,10 +152,14 @@ enum packet_headers { unit_walkingType = 0x2ec, #elif PACKETVER < 20101124 unit_walkingType = 0x7f7, -#elif PACKETVER < 20150000 //actual 20120221 +#elif PACKETVER < 20120221 unit_walkingType = 0x856, -#else +#elif PACKETVER < 20131223 unit_walkingType = 0x914, +#elif PACKETVER < 20150513 + unit_walkingType = 0x9db, +#else + unit_walkingType = 0x9fd, #endif bgqueue_ackType = 0x8d8, bgqueue_notice_deleteType = 0x8db, @@ -253,7 +267,9 @@ enum packet_headers { #else unequipitemackType = 0xac, #endif -#if PACKETVER >= 20120925 +#if PACKETVER >= 20150226 + viewequipackType = 0xa2d, +#elif PACKETVER >= 20120925 viewequipackType = 0x997, #elif PACKETVER >= 20101124 viewequipackType = 0x859, @@ -513,6 +529,9 @@ struct packet_spawn_unit { short PacketLength; unsigned char objecttype; #endif +#if PACKETVER >= 20131223 + unsigned int AID; +#endif unsigned int GID; short speed; short bodyState; @@ -558,11 +577,14 @@ struct packet_spawn_unit { #if PACKETVER >= 20080102 short font; #endif -#if PACKETVER >= 20150000 //actual 20120221 +#if PACKETVER >= 20120221 int maxHP; int HP; unsigned char isBoss; #endif +#if PACKETVER >= 20150513 + short body; +#endif } __attribute__((packed)); struct packet_unit_walking { @@ -573,6 +595,9 @@ struct packet_unit_walking { #if PACKETVER > 20071106 unsigned char objecttype; #endif +#if PACKETVER >= 20131223 + unsigned int AID; +#endif unsigned int GID; short speed; short bodyState; @@ -619,11 +644,14 @@ struct packet_unit_walking { #if PACKETVER >= 20080102 short font; #endif -#if PACKETVER >= 20150000 //actual 20120221 +#if PACKETVER >= 20120221 int maxHP; int HP; unsigned char isBoss; #endif +#if PACKETVER >= 20150513 + short body; +#endif } __attribute__((packed)); struct packet_idle_unit { @@ -632,6 +660,9 @@ struct packet_idle_unit { short PacketLength; unsigned char objecttype; #endif +#if PACKETVER >= 20131223 + unsigned int AID; +#endif unsigned int GID; short speed; short bodyState; @@ -678,11 +709,14 @@ struct packet_idle_unit { #if PACKETVER >= 20080102 short font; #endif -#if PACKETVER >= 20150000 //actual 20120221 +#if PACKETVER >= 20120221 int maxHP; int HP; unsigned char isBoss; #endif +#if PACKETVER >= 20150513 + short body; +#endif } __attribute__((packed)); struct packet_status_change { @@ -731,7 +765,7 @@ struct packet_maptypeproperty2 { unsigned int countpk : 1; /// Show the PvP counter unsigned int nopartyformation : 1; /// Prevent party creation/modification unsigned int bg : 1; // TODO: What does this do? Probably related to Battlegrounds, but I'm not sure on the effect - unsigned int noitemconsumption : 1; // TODO: What does this do? (shows a "Nothing found in the selected map" message when set) + unsigned int nocostume : 1; /// Does not show costume sprite. unsigned int usecart : 1; /// Allow opening cart inventory unsigned int summonstarmiracle : 1; // TODO: What does this do? Related to Taekwon Masters, but I have no idea. unsigned int SpareBits : 15; /// Currently ignored, reserved for future updates @@ -1044,6 +1078,9 @@ struct packet_damage { #else int damage; #endif +#if PACKETVER >= 20131223 + unsigned char is_sp_damaged; +#endif short count; unsigned char action; #if PACKETVER < 20071113 diff --git a/src/map/pc.c b/src/map/pc.c index 567348d20..d697cd9f4 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -928,6 +928,11 @@ int pc_isequip(struct map_session_data *sd,int n) if(item == NULL) return 0; +#if PACKETVER <= 20100707 + if (itemdb_is_shadowequip(item->equip) || itemdb_is_costumeequip(item->equip)) + return 0; +#endif + if(pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT)) return 1; @@ -3163,11 +3168,18 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) sd->left_weapon.sp_drain[RC_BOSS].type = val; } break; + case SP_HP_VANISH_RATE: + if (sd->state.lr_flag != 2) { + sd->bonus.hp_vanish_rate += type2; + sd->bonus.hp_vanish_per = max(sd->bonus.hp_vanish_per, val); + sd->bonus.hp_vanish_trigger = 0; + } + break; case SP_SP_VANISH_RATE: - if(sd->state.lr_flag != 2) { + if (sd->state.lr_flag != 2) { sd->bonus.sp_vanish_rate += type2; - sd->bonus.sp_vanish_per = max(sd->bonus.sp_vanish_per,val); - sd->bonus.sp_vanish_trigger=0; + sd->bonus.sp_vanish_per = max(sd->bonus.sp_vanish_per, val); + sd->bonus.sp_vanish_trigger = 0; } break; case SP_GET_ZENY_NUM: @@ -3807,11 +3819,18 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) } } break; + case SP_HP_VANISH_RATE: + if (sd->state.lr_flag != 2) { + sd->bonus.hp_vanish_rate += type2; + sd->bonus.hp_vanish_per = max(sd->bonus.hp_vanish_per, type3); + sd->bonus.hp_vanish_trigger = val; + } + break; case SP_SP_VANISH_RATE: - if(sd->state.lr_flag != 2) { + if (sd->state.lr_flag != 2) { sd->bonus.sp_vanish_rate += type2; - sd->bonus.sp_vanish_per = max(sd->bonus.sp_vanish_per,type3); - sd->bonus.sp_vanish_trigger=val; + sd->bonus.sp_vanish_per = max(sd->bonus.sp_vanish_per, type3); + sd->bonus.sp_vanish_trigger = val; } break; @@ -5241,7 +5260,7 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil sd_status= status->get_status_data(&sd->bl); md_status= status->get_status_data(bl); - if( md->master_id || md_status->mode&MD_BOSS || mob_is_treasure(md) || + if (md->master_id || md_status->mode&MD_BOSS || mob_is_treasure(md) || map->list[bl->m].flag.nomobloot || // check noloot map flag [Lorky] (battle_config.skill_steal_max_tries && //Reached limit of steal attempts. [Lupus] md->state.steal_flag++ >= battle_config.skill_steal_max_tries) @@ -5307,20 +5326,21 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil int pc_steal_coin(struct map_session_data *sd, struct block_list *target) { int rate, skill_lv; struct mob_data *md; - if(!sd || !target || target->type != BL_MOB) + + if (!sd || !target || target->type != BL_MOB) return 0; md = (TBL_MOB*)target; - if( md->state.steal_coin_flag || md->sc.data[SC_STONE] || md->sc.data[SC_FREEZE] || md->status.mode&MD_BOSS ) + if (md->state.steal_coin_flag || md->sc.data[SC_STONE] || md->sc.data[SC_FREEZE] || md->status.mode&MD_BOSS) return 0; - if( mob_is_treasure(md) ) + if (mob_is_treasure(md)) return 0; skill_lv = pc->checkskill(sd, RG_STEALCOIN); - rate = skill_lv*10 + (sd->status.base_level - md->level)*2 + sd->battle_status.dex/2 + sd->battle_status.luk/2; + rate = skill_lv * 10 + (sd->status.base_level - md->level) * 2 + sd->battle_status.dex / 2 + sd->battle_status.luk / 2; if(rnd()%1000 < rate) { - int amount = md->level * skill_lv / 10 + md->level*8 + rnd()%(md->level*2 + 1); // mob_lv * skill_lv / 10 + random [mob_lv*8; mob_lv*10] + int amount = md->level * skill_lv / 10 + md->level * 8 + rnd()%(md->level * 2 + 1); // mob_lv * skill_lv / 10 + random [mob_lv*8; mob_lv*10] pc->getzeny(sd, amount, LOG_TYPE_STEAL, NULL); md->state.steal_coin_flag = 1; @@ -9395,7 +9415,7 @@ int pc_load_combo(struct map_session_data *sd) { } /** -* Equip item ad given position. +* Equip item at given position. * @param sd the affected player structure. Must be checked before. * @param id item structure for equip. Must be checked before. * @param n inventory item position. Must be checked before. @@ -9403,7 +9423,8 @@ int pc_load_combo(struct map_session_data *sd) { **/ void pc_equipitem_pos(struct map_session_data *sd, struct item_data *id, int n, int pos) { - if (pos & (EQP_HAND_R|EQP_SHADOW_WEAPON)) { + 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 @@ -9411,7 +9432,8 @@ void pc_equipitem_pos(struct map_session_data *sd, struct item_data *id, int n, pc->calcweapontype(sd); clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); } - if (pos & (EQP_HAND_L|EQP_SHADOW_SHIELD)) { + 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; @@ -9427,42 +9449,42 @@ void pc_equipitem_pos(struct map_session_data *sd, struct item_data *id, int n, } //Added check to prevent sending the same look on multiple slots -> //causes client to redraw item on top of itself. (suggested by Lupus) - if (pos & EQP_HEAD_LOW && pc->checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) { + 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; else sd->status.head_bottom = 0; clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); } - if (pos & EQP_HEAD_TOP && pc->checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) { + 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; else sd->status.head_top = 0; clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); } - if (pos & EQP_HEAD_MID && pc->checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) { + 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; else sd->status.head_mid = 0; clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); } - if (pos & EQP_COSTUME_HEAD_TOP) { + if (!map_no_view(sd->bl.m,EQP_COSTUME_HEAD_TOP) && pos & EQP_COSTUME_HEAD_TOP) { if (id){ sd->status.head_top = id->look; } else sd->status.head_top = 0; clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); } - if (pos & EQP_COSTUME_HEAD_MID) { + 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; } else sd->status.head_mid = 0; clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); } - if (pos & EQP_COSTUME_HEAD_LOW) { + 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; } else @@ -9470,14 +9492,14 @@ void pc_equipitem_pos(struct map_session_data *sd, struct item_data *id, int n, clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); } - if (pos & EQP_SHOES) + if (!map_no_view(sd->bl.m,EQP_SHOES) && pos & EQP_SHOES) clif->changelook(&sd->bl,LOOK_SHOES,0); - if (pos&EQP_GARMENT && pc->checkequip(sd,EQP_COSTUME_GARMENT) == -1) { + 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); } - if (pos & EQP_COSTUME_GARMENT) { + 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); } diff --git a/src/map/pc.h b/src/map/pc.h index 93173f6c8..97f339bf6 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -377,6 +377,8 @@ BEGIN_ZEROED_BLOCK; // this block will be globally zeroed at the beginning of st short add_steal_rate; short add_heal_rate, add_heal2_rate; short sp_gain_value, hp_gain_value, magic_sp_gain_value, magic_hp_gain_value; + short hp_vanish_rate; + short hp_vanish_per, hp_vanish_trigger; short sp_vanish_rate; short sp_vanish_per, sp_vanish_trigger; unsigned short unbreakable; // chance to prevent ANY equipment breaking [celest] diff --git a/src/map/script.c b/src/map/script.c index 401b0308a..af790ccf5 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -2644,6 +2644,36 @@ TBL_PC *script_rid2sd(struct script_state *st) { return sd; } +TBL_PC *script_id2sd(struct script_state *st, int account_id) { + TBL_PC *sd; + if ((sd = map->id2sd(account_id)) == NULL) { + ShowWarning("script_id2sd: Player with account ID '%d' not found!\n", account_id); + script->reportfunc(st); + script->reportsrc(st); + } + return sd; +} + +TBL_PC *script_charid2sd(struct script_state *st, int char_id) { + TBL_PC *sd; + if ((sd = map->charid2sd(char_id)) == NULL) { + ShowWarning("script_charid2sd: Player with char ID '%d' not found!\n", char_id); + script->reportfunc(st); + script->reportsrc(st); + } + return sd; +} + +TBL_PC *script_nick2sd(struct script_state *st, const char *name) { + TBL_PC *sd; + if ((sd = map->nick2sd(name)) == NULL) { + ShowWarning("script_nick2sd: Player name '%s' not found!\n", name); + script->reportfunc(st); + script->reportsrc(st); + } + return sd; +} + char *get_val_npcscope_str(struct script_state* st, struct reg_db *n, struct script_data* data) { if (n) return (char*)i64db_get(n->vars, reference_getuid(data)); @@ -2696,6 +2726,13 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) { prefix = name[0]; postfix = name[strlen(name) - 1]; + if (strlen(name) > SCRIPT_VARNAME_LENGTH) { + ShowError("script_get_val: variable name too long. '%s'\n", name); + script->reportsrc(st); + st->state = END; + return data; + } + //##TODO use reference_tovariable(data) when it's confirmed that it works [FlavioJS] if( !reference_toconstant(data) && not_server_variable(prefix) ) { sd = script->rid2sd(st); @@ -3112,6 +3149,13 @@ void set_reg_instance_num(struct script_state* st, int64 num, const char* name, int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, const void* value, struct reg_db *ref) { char prefix = name[0]; + if (strlen(name) > SCRIPT_VARNAME_LENGTH) { + ShowError("script:set_reg: variable name too long. '%s'\n", name); + script->reportsrc(st); + st->state = END; + return 0; + } + if( is_string_variable(name) ) {// string variable const char *str = (const char*)value; @@ -5928,8 +5972,8 @@ BUILDIN(warpchar) { y=script_getnum(st,4); a=script_getnum(st,5); - sd = map->charid2sd(a); - if( sd == NULL ) + sd = script->charid2sd(st, a); + if (sd == NULL) return true; if(strcmp(str, "Random") == 0) @@ -6975,8 +7019,8 @@ BUILDIN(checkweight2) TBL_PC *sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; data_it = script_getdata(st, 2); data_nb = script_getdata(st, 3); @@ -7117,12 +7161,12 @@ BUILDIN(getitem) { offset += 1; } - if( script_hasdata(st,4+offset) ) - sd=map->id2sd(script_getnum(st,4+offset)); // <Account ID> + if (script_hasdata(st,4+offset)) + sd = script->id2sd(st, script_getnum(st,4+offset)); // <Account ID> else sd=script->rid2sd(st); // Attached player - if( sd == NULL ) // no target + if (sd == NULL) // no target return true; //Check if it's stackable. @@ -7163,12 +7207,12 @@ BUILDIN(getitem2) offset += 1; } - if( script_hasdata(st,11+offset) ) - sd=map->id2sd(script_getnum(st,11+offset)); // <Account ID> + if (script_hasdata(st,11+offset)) + sd = script->id2sd(st, script_getnum(st,11+offset)); // <Account ID> else sd=script->rid2sd(st); // Attached player - if( sd == NULL ) // no target + if (sd == NULL) // no target return true; if( script_isstringtype(st, 2) ) { @@ -7334,12 +7378,12 @@ BUILDIN(getnameditem) { return true; } - if( script_isstringtype(st, 3) ) //Char Name - tsd=map->nick2sd(script_getstr(st, 3)); + if (script_isstringtype(st, 3)) //Char Name + tsd = script->nick2sd(st, script_getstr(st, 3)); else //Char Id was given - tsd=map->charid2sd(script_getnum(st, 3)); + tsd = script->charid2sd(st, script_getnum(st, 3)); - if( tsd == NULL ) { + if (tsd == NULL) { //Failed script_pushint(st,0); return true; @@ -7583,11 +7627,10 @@ BUILDIN(delitem) { if (script_hasdata(st,4)) { int account_id = script_getnum(st,4); - sd = map->id2sd(account_id); // <account id> + sd = script->id2sd(st, account_id); // <account id> if (sd == NULL) { - ShowError("script:delitem: player not found (AID=%d).\n", account_id); st->state = END; - return false; + return true; } } else { sd = script->rid2sd(st);// attached player @@ -7640,11 +7683,10 @@ BUILDIN(delitem2) { if (script_hasdata(st,11)) { int account_id = script_getnum(st,11); - sd = map->id2sd(account_id); // <account id> + sd = script->id2sd(st, account_id); // <account id> if (sd == NULL) { - ShowError("script:delitem2: player not found (AID=%d).\n", account_id); st->state = END; - return false; + return true; } } else { sd = script->rid2sd(st);// attached player @@ -7724,12 +7766,12 @@ BUILDIN(readparam) { TBL_PC *sd; type=script_getnum(st,2); - if( script_hasdata(st,3) ) - sd=map->nick2sd(script_getstr(st,3)); + if (script_hasdata(st,3)) + sd = script->nick2sd(st, script_getstr(st,3)); else sd=script->rid2sd(st); - if(sd==NULL) { + if (sd == NULL) { script_pushint(st,-1); return true; } @@ -8936,8 +8978,8 @@ BUILDIN(guildskill) { struct guild_skill gd_skill; sd = script->rid2sd(st); - if( sd == NULL ) - return false; // no player attached, report source + if (sd == NULL) + return true; // no player attached, report source if( (gd = sd->guild) == NULL ) return true; @@ -9035,7 +9077,7 @@ BUILDIN(getgroupid) sd = script->rid2sd(st); if (sd == NULL) - return false; // no player attached, report source + return true; // no player attached, report source script_pushint(st, pc_get_group_id(sd)); return true; @@ -9414,8 +9456,8 @@ BUILDIN(savepoint) { TBL_PC* sd; sd = script->rid2sd(st); - if( sd == NULL ) - return false;// no player attached, report source + if (sd == NULL) + return true; // no player attached, report source str = script_getstr(st,2); x = script_getnum(st,3); @@ -9699,9 +9741,9 @@ BUILDIN(guildchangegm) { guild_id = script_getnum(st,2); name = script_getstr(st,3); - sd=map->nick2sd(name); + sd = script->nick2sd(st, name); - if (!sd) + if (sd == NULL) script_pushint(st,0); else script_pushint(st,guild->gm_change(guild_id, sd)); @@ -10020,16 +10062,16 @@ BUILDIN(clone) { m = map->mapname2mapid(mapname); if (m < 0) return true; - sd = map->charid2sd(char_id); + sd = script->charid2sd(st, char_id); if (master_id) { msd = map->charid2sd(master_id); - if (msd) + if (msd != NULL) master_id = msd->bl.id; else master_id = 0; } - if (sd) //Return ID of newly crafted clone. + if (sd != NULL) //Return ID of newly crafted clone. script_pushint(st,mob->clone_spawn(sd, m, x, y, event, master_id, mode, flag, 1000*duration)); else //Failed to create clone. script_pushint(st,0); @@ -10266,16 +10308,14 @@ BUILDIN(getnpctimer) { switch( type ) { case 0: val = (int)npc->gettimerevent_tick(nd); break; // FIXME: change this to int64 when we'll support 64 bit script values case 1: - if( nd->u.scr.rid ) { - sd = map->id2sd(nd->u.scr.rid); - if( !sd ) { - ShowError("buildin_getnpctimer: Attached player not found!\n"); + if (nd->u.scr.rid) { + sd = script->id2sd(st, nd->u.scr.rid); + if (sd == NULL) break; - } val = (sd->npc_timer_id != INVALID_TIMER); - } - else + } else { val = (nd->u.scr.timerid != INVALID_TIMER); + } break; case 2: val = nd->u.scr.timeramount; break; } @@ -10321,16 +10361,14 @@ BUILDIN(attachnpctimer) { return false; } - if( script_hasdata(st,2) ) - sd = map->nick2sd(script_getstr(st,2)); + if (script_hasdata(st,2)) + sd = script->nick2sd(st, script_getstr(st,2)); else sd = script->rid2sd(st); - if( !sd ) - { + if (sd == NULL) { script_pushint(st,1); - ShowWarning("attachnpctimer: Invalid player.\n"); - return false; + return true; } nd->u.scr.rid = sd->bl.id; @@ -10438,8 +10476,8 @@ BUILDIN(itemeffect) { struct item_data *item_data; sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; nd = (TBL_NPC *)map->id2bl(sd->npc_id); if( nd == NULL ) @@ -10639,9 +10677,9 @@ BUILDIN(getareausers) idx = 3; } else { TBL_PC *sd = script->rid2sd(st); - if (!sd) { + if (sd == NULL) { script_pushint(st, -1); - return false; + return true; } m = sd->bl.m; } @@ -11195,10 +11233,9 @@ BUILDIN(resetlvl) *------------------------------------------*/ BUILDIN(resetstatus) { - TBL_PC *sd; - sd=script->rid2sd(st); - if( sd == NULL ) - return false; + TBL_PC *sd = script->rid2sd(st); + if (sd == NULL) + return true; pc->resetstate(sd); return true; } @@ -11206,11 +11243,11 @@ BUILDIN(resetstatus) /*========================================== * script command resetskill *------------------------------------------*/ -BUILDIN(resetskill) { - TBL_PC *sd; - sd=script->rid2sd(st); - if( sd == NULL ) - return false; +BUILDIN(resetskill) +{ + TBL_PC *sd = script->rid2sd(st); + if (sd == NULL) + return true; pc->resetskill(sd, PCRESETSKILL_RESYNC); return true; } @@ -11218,11 +11255,11 @@ BUILDIN(resetskill) { /*========================================== * Counts total amount of skill points. *------------------------------------------*/ -BUILDIN(skillpointcount) { - TBL_PC *sd; - sd=script->rid2sd(st); - if( sd == NULL ) - return false; +BUILDIN(skillpointcount) +{ + TBL_PC *sd = script->rid2sd(st); + if (sd == NULL) + return true; script_pushint(st,sd->status.skill_point + pc->resetskill(sd, PCRESETSKILL_RECOUNT)); return true; } @@ -11234,12 +11271,12 @@ BUILDIN(changebase) { TBL_PC *sd=NULL; int vclass; - if( script_hasdata(st,3) ) - sd=map->id2sd(script_getnum(st,3)); + if (script_hasdata(st,3)) + sd = script->id2sd(st, script_getnum(st,3)); else sd=script->rid2sd(st); - if(sd == NULL) + if (sd == NULL) return true; vclass = script_getnum(st,2); @@ -11279,7 +11316,7 @@ BUILDIN(changesex) { TBL_PC *sd = prepareChangeSex(st); if (sd == NULL) - return false; + return true; chrif->changesex(sd, true); return true; } @@ -11291,7 +11328,7 @@ BUILDIN(changecharsex) { TBL_PC *sd = prepareChangeSex(st); if (sd == NULL) - return false; + return true; chrif->changesex(sd, false); return true; } @@ -11673,6 +11710,7 @@ BUILDIN(getmapflag) case MF_RESET: script_pushint(st,map->list[m].flag.reset); break; case MF_NOTOMB: script_pushint(st,map->list[m].flag.notomb); break; case MF_NOCASHSHOP: script_pushint(st,map->list[m].flag.nocashshop); break; + case MF_NOVIEWID: script_pushint(st,map->list[m].flag.noviewid); break; } } @@ -11789,6 +11827,7 @@ BUILDIN(setmapflag) { case MF_RESET: map->list[m].flag.reset = 1; break; case MF_NOTOMB: map->list[m].flag.notomb = 1; break; case MF_NOCASHSHOP: map->list[m].flag.nocashshop = 1; break; + case MF_NOVIEWID: map->list[m].flag.noviewid = (val <= 0) ? 0 : val; break; } } @@ -11875,6 +11914,7 @@ BUILDIN(removemapflag) { case MF_RESET: map->list[m].flag.reset = 0; break; case MF_NOTOMB: map->list[m].flag.notomb = 0; break; case MF_NOCASHSHOP: map->list[m].flag.nocashshop = 0; break; + case MF_NOVIEWID: map->list[m].flag.noviewid = 0; break; } } @@ -12019,13 +12059,13 @@ BUILDIN(emotion) { if( script_hasdata(st,3) ) player=script_getnum(st,3); - if (player) { + if (player != 0) { TBL_PC *sd = NULL; - if( script_hasdata(st,4) ) - sd = map->nick2sd(script_getstr(st,4)); + if (script_hasdata(st,4)) + sd = script->nick2sd(st, script_getstr(st,4)); else sd = script->rid2sd(st); - if (sd) + if (sd != NULL) clif->emotion(&sd->bl,type); } else if( script_hasdata(st,4) ) { TBL_NPC *nd = npc->name2id(script_getstr(st,4)); @@ -12250,10 +12290,10 @@ BUILDIN(getequipcardcnt) int count; num=script_getnum(st,2); - sd=script->rid2sd(st); + sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); @@ -12285,11 +12325,11 @@ BUILDIN(successremovecards) { int i=-1,c,cardflag=0; - TBL_PC* sd = script->rid2sd(st); + TBL_PC *sd = script->rid2sd(st); int num = script_getnum(st,2); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); @@ -12356,12 +12396,12 @@ BUILDIN(failedremovecards) { int i=-1,c,cardflag=0; - TBL_PC* sd = script->rid2sd(st); + TBL_PC *sd = script->rid2sd(st); int num = script_getnum(st,2); int typefail = script_getnum(st,3); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); @@ -12509,8 +12549,8 @@ BUILDIN(mobcount) { if( strcmp(mapname, "this") == 0 ) { struct map_session_data *sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; m = sd->bl.m; } else if( (m = map->mapname2mapid(mapname)) < 0 ) { @@ -12531,9 +12571,9 @@ BUILDIN(mobcount) { BUILDIN(marriage) { const char *partner=script_getstr(st,2); TBL_PC *sd=script->rid2sd(st); - TBL_PC *p_sd=map->nick2sd(partner); + TBL_PC *p_sd = script->nick2sd(st, partner); - if(sd==NULL || p_sd==NULL || pc->marriage(sd,p_sd) < 0) { + if (sd == NULL || p_sd == NULL || pc->marriage(sd,p_sd) < 0) { script_pushint(st,0); return true; } @@ -12541,11 +12581,11 @@ BUILDIN(marriage) { return true; } BUILDIN(wedding_effect) { - TBL_PC *sd=script->rid2sd(st); + TBL_PC *sd = script->rid2sd(st); struct block_list *bl; - if( sd == NULL ) - return false; //bl=map->id2bl(st->oid); + if (sd == NULL) + return true; //bl=map->id2bl(st->oid); bl=&sd->bl; clif->wedding_effect(bl); @@ -12575,28 +12615,31 @@ BUILDIN(ispartneron) { return true; } -BUILDIN(getpartnerid) { - TBL_PC *sd=script->rid2sd(st); - if( sd == NULL ) - return false; +BUILDIN(getpartnerid) +{ + TBL_PC *sd = script->rid2sd(st); + if (sd == NULL) + return true; script_pushint(st,sd->status.partner_id); return true; } -BUILDIN(getchildid) { - TBL_PC *sd=script->rid2sd(st); - if( sd == NULL ) - return false; +BUILDIN(getchildid) +{ + TBL_PC *sd = script->rid2sd(st); + if (sd == NULL) + return true; script_pushint(st,sd->status.child); return true; } -BUILDIN(getmotherid) { - TBL_PC *sd=script->rid2sd(st); - if( sd == NULL ) - return false; +BUILDIN(getmotherid) +{ + TBL_PC *sd = script->rid2sd(st); + if (sd == NULL) + return true; script_pushint(st,sd->status.mother); return true; @@ -12605,7 +12648,7 @@ BUILDIN(getmotherid) { BUILDIN(getfatherid) { TBL_PC *sd=script->rid2sd(st); if( sd == NULL ) - return false; + return true; script_pushint(st,sd->status.father); return true; @@ -12619,8 +12662,8 @@ BUILDIN(warppartner) TBL_PC *sd=script->rid2sd(st); TBL_PC *p_sd=NULL; - if ( sd==NULL || !pc->ismarried(sd) - || (p_sd=map->charid2sd(sd->status.partner_id)) == NULL) { + if (sd == NULL || !pc->ismarried(sd) + || (p_sd = script->charid2sd(st, sd->status.partner_id)) == NULL) { script_pushint(st,0); return true; } @@ -12929,10 +12972,10 @@ BUILDIN(getequipcardid) num=script_getnum(st,2); slot=script_getnum(st,3); - sd=script->rid2sd(st); + sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); @@ -13439,10 +13482,10 @@ BUILDIN(skilleffect) { uint16 skill_id=( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); uint16 skill_lv=script_getnum(st,3); - sd=script->rid2sd(st); + sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; /* ensure we're standing because the following packet causes the client to virtually set the char to stand, * which leaves the server thinking it still is sitting. */ @@ -13511,12 +13554,12 @@ BUILDIN(specialeffect2) { int type = script_getnum(st,2); enum send_target target = script_hasdata(st,3) ? (send_target)script_getnum(st,3) : AREA; - if( script_hasdata(st,4) ) - sd = map->nick2sd(script_getstr(st,4)); + if (script_hasdata(st,4)) + sd = script->nick2sd(st, script_getstr(st,4)); else sd = script->rid2sd(st); - if (sd) + if (sd != NULL) clif->specialeffect(&sd->bl, type, target); return true; @@ -13560,8 +13603,8 @@ BUILDIN(atcommand) { if (st->rid) { sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; fd = sd->fd; } else { //Use a dummy character. sd = dummy_sd = pc->get_dummy_sd(); @@ -13584,16 +13627,28 @@ BUILDIN(atcommand) { return ret; } -/*========================================== - * Displays a message for the player only (like system messages like "you got an apple" ) - *------------------------------------------*/ +/** + * Displays a message for the player only (like system messages like "you got an apple") + * + * @code + * dispbottom "<message>"{,<color>}; + * @endcode + */ BUILDIN(dispbottom) { - TBL_PC *sd=script->rid2sd(st); - const char *message; - message=script_getstr(st,2); - if(sd) - clif_disp_onlyself(sd,message,(int)strlen(message)); + TBL_PC *sd = script->rid2sd(st); + const char *message = script_getstr(st,2); + + if (sd == NULL) + return true; + + if (script_hasdata(st,3)) { + int color = script_getnum(st,3); + clif->messagecolor_self(sd->fd, color, message); + } else { + clif_disp_onlyself(sd, message, (int)strlen(message)); + } + return true; } @@ -13698,10 +13753,9 @@ BUILDIN(getmercinfo) if (script_hasdata(st,3)) { int char_id = script_getnum(st,3); - if ((sd = map->charid2sd(char_id)) == NULL) { - ShowError("buildin_getmercinfo: No such character (char_id=%d).\n", char_id); + if ((sd = script->charid2sd(st, char_id)) == NULL) { script_pushnil(st); - return false; + return true; } } else { if ((sd = script->rid2sd(st)) == NULL) @@ -13742,10 +13796,10 @@ BUILDIN(getmercinfo) BUILDIN(checkequipedcard) { int n,i,c=0; - TBL_PC *sd=script->rid2sd(st); + TBL_PC *sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; c = script_getnum(st,2); @@ -13809,16 +13863,21 @@ BUILDIN(movenpc) { /*========================================== * message [MouseJstr] *------------------------------------------*/ -BUILDIN(message) { - const char *msg,*player; - TBL_PC *pl_sd = NULL; +BUILDIN(message) +{ + const char *message; + TBL_PC *sd = NULL; - player = script_getstr(st,2); - msg = script_getstr(st,3); + if (script_isstringtype(st,2)) + sd = script->nick2sd(st, script_getstr(st,2)); + else + sd = script->id2sd(st, script_getnum(st,2)); - if((pl_sd=map->nick2sd((char *) player)) == NULL) + if (sd == NULL) return true; - clif->message(pl_sd->fd, msg); + + message = script_getstr(st,3); + clif->message(sd->fd, message); return true; } @@ -14009,14 +14068,12 @@ BUILDIN(getnpcclass) *------------------------------------------*/ BUILDIN(getlook) { - int type,val; - TBL_PC *sd; - sd=script->rid2sd(st); - if( sd == NULL ) - return false; + int type,val = -1; + TBL_PC *sd = script->rid2sd(st); + if (sd == NULL) + return true; type=script_getnum(st,2); - val = -1; switch(type) { case LOOK_HAIR: val = sd->status.hair; break; //1 case LOOK_WEAPON: val = sd->status.weapon; break; //2 @@ -14039,12 +14096,11 @@ BUILDIN(getlook) *------------------------------------------*/ BUILDIN(getsavepoint) { - TBL_PC* sd; int type; + TBL_PC *sd = script->rid2sd(st); - sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; type = script_getnum(st,2); @@ -14132,58 +14188,95 @@ BUILDIN(getmapxy) switch (type) { case 0: //Get Character Position - if( script_hasdata(st,6) ) - sd=map->nick2sd(script_getstr(st,6)); - else - sd=script->rid2sd(st); + if (script_hasdata(st,6)) { + if (script_isstringtype(st,6)) + sd = map->nick2sd(script_getstr(st,6)); + else + sd = map->id2sd(script_getnum(st,6)); + } else { + sd = script->rid2sd(st); + } if (sd) bl = &sd->bl; break; case 1: //Get NPC Position - if( script_hasdata(st,6) ) - { + if (script_hasdata(st,6)) { struct npc_data *nd; - nd=npc->name2id(script_getstr(st,6)); + if (script_isstringtype(st,6)) + nd = npc->name2id(script_getstr(st,6)); + else + nd = map->id2nd(script_getnum(st,6)); if (nd) bl = &nd->bl; - } else //In case the origin is not an npc? - bl=map->id2bl(st->oid); + } else { + //In case the origin is not an npc? + bl = map->id2bl(st->oid); + } break; case 2: //Get Pet Position - if(script_hasdata(st,6)) - sd=map->nick2sd(script_getstr(st,6)); - else - sd=script->rid2sd(st); + if (script_hasdata(st,6)) { + if (script_isstringtype(st,6)) + sd = map->nick2sd(script_getstr(st,6)); + else { + bl = map->id2bl(script_getnum(st,6)); + break; + } + } else { + sd = script->rid2sd(st); + } if (sd && sd->pd) bl = &sd->pd->bl; break; case 3: //Get Mob Position - break; //Not supported? + if (script_hasdata(st,6)) { + if (script_isstringtype(st,6)) + break; + bl = map->id2bl(script_getnum(st,6)); + } + break; case 4: //Get Homun Position - if(script_hasdata(st,6)) - sd=map->nick2sd(script_getstr(st,6)); - else - sd=script->rid2sd(st); + if (script_hasdata(st,6)) { + if (script_isstringtype(st,6)) { + sd = map->nick2sd(script_getstr(st,6)); + } else { + bl = map->id2bl(script_getnum(st,6)); + break; + } + } else { + sd = script->rid2sd(st); + } if (sd && sd->hd) bl = &sd->hd->bl; break; case 5: //Get Mercenary Position - if(script_hasdata(st,6)) - sd=map->nick2sd(script_getstr(st,6)); - else - sd=script->rid2sd(st); + if (script_hasdata(st,6)) { + if (script_isstringtype(st,6)) { + sd = map->nick2sd(script_getstr(st,6)); + } else { + bl = map->id2bl(script_getnum(st,6)); + break; + } + } else { + sd = script->rid2sd(st); + } if (sd && sd->md) bl = &sd->md->bl; break; case 6: //Get Elemental Position - if(script_hasdata(st,6)) - sd=map->nick2sd(script_getstr(st,6)); - else - sd=script->rid2sd(st); + if (script_hasdata(st,6)) { + if (script_isstringtype(st,6)) { + sd = map->nick2sd(script_getstr(st,6)); + } else { + bl = map->id2bl(script_getnum(st,6)); + break; + } + } else { + sd = script->rid2sd(st); + } if (sd && sd->ed) bl = &sd->ed->bl; @@ -14246,11 +14339,10 @@ BUILDIN(getmapxy) BUILDIN(logmes) { const char *str; - TBL_PC* sd; + TBL_PC *sd = script->rid2sd(st); - sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; str = script_getstr(st,2); logs->npc(sd,str); @@ -14307,13 +14399,12 @@ BUILDIN(isnight) { *------------------------------------------------*/ BUILDIN(isequippedcnt) { - TBL_PC *sd; int i, j, k, id = 1; int ret = 0; + TBL_PC *sd = script->rid2sd(st); - sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; for (i=0; id!=0; i++) { script_fetch(st,i+2, id); @@ -14357,17 +14448,15 @@ BUILDIN(isequippedcnt) *------------------------------------------------*/ BUILDIN(isequipped) { - TBL_PC *sd; int i, j, k, id = 1; int index, flag; int ret = -1; //Original hash to reverse it when full check fails. unsigned int setitem_hash = 0, setitem_hash2 = 0; + TBL_PC *sd = script->rid2sd(st); - sd = script->rid2sd(st); - - if( sd == NULL ) - return false; + if (sd == NULL) + return true; setitem_hash = sd->bonus.setitem_hash; setitem_hash2 = sd->bonus.setitem_hash2; @@ -14437,16 +14526,15 @@ BUILDIN(isequipped) * Check how many given inserted cards in the CURRENT * weapon - used for 2/15's cards patch [Lupus] *------------------------------------------------*/ -BUILDIN(cardscnt) { - TBL_PC *sd; +BUILDIN(cardscnt) +{ int i, k, id = 1; int ret = 0; int index; + TBL_PC *sd = script->rid2sd(st); - sd = script->rid2sd(st); - - if( sd == NULL ) - return false; + if (sd == NULL) + return true; for (i=0; id!=0; i++) { script_fetch(st,i+2, id); @@ -14480,12 +14568,12 @@ BUILDIN(cardscnt) { * Returns the refined number of the current item, or an * item with inventory index specified *-------------------------------------------------------*/ -BUILDIN(getrefine) { - TBL_PC *sd; +BUILDIN(getrefine) +{ + TBL_PC *sd = script->rid2sd(st); - sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; script_pushint(st,sd->status.inventory[status->current_equip_item_index].refine); return true; @@ -14575,11 +14663,9 @@ BUILDIN(equip2) { int i,nameid,ref,attr,c0,c1,c2,c3; struct item_data *item_data; - TBL_PC *sd; - - sd = script->rid2sd(st); + TBL_PC *sd = script->rid2sd(st); - if ( sd == NULL ) { + if (sd == NULL) { script_pushint(st,0); return true; } @@ -14866,17 +14952,14 @@ BUILDIN(explode) const char delimiter = script_getstr(st, 4)[0]; int32 id; size_t len = strlen(str); - int i = 0, j = 0; + int i = 0, j = 0, k = 0; int start; - char *temp; - const char* name; + char *temp = NULL; + const char *name; TBL_PC* sd = NULL; - temp = (char*)aMalloc(len + 1); - - if( !data_isreference(data) ) - { + if (!data_isreference(data)) { ShowError("script:explode: not a variable\n"); script->reportdata(data); st->state = END; @@ -14887,36 +14970,39 @@ BUILDIN(explode) start = reference_getindex(data); name = reference_getname(data); - if( !is_string_variable(name) ) - { + if (!is_string_variable(name)) { ShowError("script:explode: not string array\n"); script->reportdata(data); st->state = END; return false;// data type mismatch } - if( not_server_variable(*name) ) - { + if (not_server_variable(*name)) { sd = script->rid2sd(st); - if( sd == NULL ) + if (sd == NULL) return true;// no player attached } - while(str[i] != '\0') { - if(str[i] == delimiter && start < SCRIPT_MAX_ARRAYSIZE-1) { //break at delimiter but ignore after reaching last array index + temp = aMalloc(len + 1); + + for (i = 0; str[i] != '\0'; i++) { + if (str[i] == delimiter && (int64)start + k < (int64)(SCRIPT_MAX_ARRAYSIZE-1)) { // FIXME[Haru]: SCRIPT_MAX_ARRAYSIZE should really be unsigned (and INT32_MAX) + //break at delimiter but ignore after reaching last array index temp[j] = '\0'; - script->set_reg(st, sd, reference_uid(id, start++), name, (void*)temp, reference_getref(data)); + script->set_reg(st, sd, reference_uid(id, start + k), name, (void*)temp, reference_getref(data)); + k++; j = 0; - ++i; } else { - temp[j++] = str[i++]; + temp[j++] = str[i]; } } //set last string temp[j] = '\0'; - script->set_reg(st, sd, reference_uid(id, start), name, (void*)temp, reference_getref(data)); + script->set_reg(st, sd, reference_uid(id, start + k), name, (void*)temp, reference_getref(data)); aFree(temp); + + script_pushint(st, k + 1); return true; } @@ -15814,13 +15900,13 @@ BUILDIN(petstat) BUILDIN(callshop) { - TBL_PC *sd = NULL; struct npc_data *nd; const char *shopname; int flag = 0; - sd = script->rid2sd(st); - if( sd == NULL ) - return false; + TBL_PC *sd = script->rid2sd(st); + + if (sd == NULL) + return true; shopname = script_getstr(st, 2); if( script_hasdata(st,3) ) flag = script_getnum(st,3); @@ -16174,12 +16260,12 @@ BUILDIN(checkvending) // check vending [Nab4] { TBL_PC *sd = NULL; - if(script_hasdata(st,2)) - sd = map->nick2sd(script_getstr(st,2)); + if (script_hasdata(st,2)) + sd = script->nick2sd(st, script_getstr(st,2)); else sd = script->rid2sd(st); - if(sd) + if (sd != NULL) script_pushint(st, sd->state.autotrade ? 2 : sd->state.vending); else script_pushint(st,0); @@ -16191,12 +16277,12 @@ BUILDIN(checkvending) // check vending [Nab4] BUILDIN(checkchatting) { TBL_PC *sd = NULL; - if(script_hasdata(st,2)) - sd = map->nick2sd(script_getstr(st,2)); + if (script_hasdata(st,2)) + sd = script->nick2sd(st, script_getstr(st,2)); else sd = script->rid2sd(st); - if(sd) + if (sd != NULL) script_pushint(st,(sd->chatID != 0)); else script_pushint(st,0); @@ -16208,11 +16294,11 @@ BUILDIN(checkidle) { TBL_PC *sd = NULL; if (script_hasdata(st, 2)) - sd = map->nick2sd(script_getstr(st, 2)); + sd = script->nick2sd(st, script_getstr(st, 2)); else sd = script->rid2sd(st); - if (sd) + if (sd != NULL) script_pushint(st, DIFF_TICK32(sockt->last_tick, sd->idletime)); // TODO: change this to int64 when we'll support 64 bit script values else script_pushint(st, 0); @@ -16313,12 +16399,12 @@ BUILDIN(pcblockmove) { id = script_getnum(st,2); flag = script_getnum(st,3); - if(id) - sd = map->id2sd(id); + if (id != 0) + sd = script->id2sd(st, id); else sd = script->rid2sd(st); - if(sd) + if (sd != NULL) sd->state.blockedmove = flag > 0; return true; @@ -16331,12 +16417,12 @@ BUILDIN(pcfollow) { id = script_getnum(st,2); targetid = script_getnum(st,3); - if(id) - sd = map->id2sd(id); + if (id != 0) + sd = script->id2sd(st, id); else sd = script->rid2sd(st); - if(sd) + if (sd != NULL) pc->follow(sd, targetid); return true; @@ -16349,12 +16435,12 @@ BUILDIN(pcstopfollow) id = script_getnum(st,2); - if(id) - sd = map->id2sd(id); + if (id != 0) + sd = script->id2sd(st, id); else sd = script->rid2sd(st); - if(sd) + if (sd != NULL) pc->stop_following(sd); return true; @@ -16363,6 +16449,33 @@ BUILDIN(pcstopfollow) // [zBuffer] List of mob control commands ---> //## TODO always return if the request/whatever was successfull [FlavioJS] +BUILDIN(getunittype) { + struct block_list* bl; + int value; + + bl = map->id2bl(script_getnum(st,2)); + + if (!bl) { + ShowWarning("buildin_getunittype: Error in finding object GID %d!\n", script_getnum(st,2)); + script_pushint(st,-1); + return false; + } + + switch (bl->type) { + case BL_PC: value = 0; break; + case BL_NPC: value = 1; break; + case BL_PET: value = 2; break; + case BL_MOB: value = 3; break; + case BL_HOM: value = 4; break; + case BL_MER: value = 5; break; + case BL_ELEM: value = 6; break; + default: value = -1; break; + } + + script_pushint(st, value); + return true; +} + /// Makes the unit walk to target position or target id /// Returns if it was successfull /// @@ -16460,12 +16573,13 @@ BUILDIN(unitattack) { return true; } - if( script_isstringtype(st, 3) ) { - TBL_PC* sd = map->nick2sd(script_getstr(st, 3)); - if( sd != NULL ) + if (script_isstringtype(st, 3)) { + TBL_PC* sd = script->nick2sd(st, script_getstr(st, 3)); + if (sd != NULL) target_bl = &sd->bl; - } else + } else { target_bl = map->id2bl(script_getnum(st, 3)); + } // request the attack if( target_bl == NULL ) { @@ -17130,13 +17244,14 @@ BUILDIN(questinfo) return true; } -BUILDIN(setquest) { - struct map_session_data *sd = script->rid2sd(st); +BUILDIN(setquest) +{ unsigned short i; int quest_id; + struct map_session_data *sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; quest_id = script_getnum(st, 2); @@ -17161,8 +17276,8 @@ BUILDIN(erasequest) { struct map_session_data *sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; if (script_hasdata(st, 3)) { int quest_id; @@ -17184,8 +17299,8 @@ BUILDIN(completequest) { struct map_session_data *sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; if (script_hasdata(st, 3)) { int quest_id; @@ -17203,23 +17318,24 @@ BUILDIN(completequest) return true; } -BUILDIN(changequest) { +BUILDIN(changequest) +{ struct map_session_data *sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; quest->change(sd, script_getnum(st, 2),script_getnum(st, 3)); return true; } -BUILDIN(questactive) { +BUILDIN(questactive) +{ struct map_session_data *sd = script->rid2sd(st); int qid, i; if (sd == NULL) { - ShowError("questactive: no player attached!"); - return false; + return true; } qid = script_getnum(st, 2); @@ -17239,13 +17355,14 @@ BUILDIN(questactive) { return true; } -BUILDIN(questprogress) { +BUILDIN(questprogress) +{ struct map_session_data *sd = script->rid2sd(st); enum quest_check_type type = HAVEQUEST; int quest_progress = 0; if (sd == NULL) - return false; + return true; if (script_hasdata(st, 3)) type = (enum quest_check_type)script_getnum(st, 3); @@ -18282,20 +18399,27 @@ BUILDIN(getcharip) { struct map_session_data* sd = NULL; /* check if a character name is specified */ - if( script_hasdata(st, 2) ) { + if (script_hasdata(st, 2)) { if (script_isstringtype(st, 2)) { sd = map->nick2sd(script_getstr(st, 2)); } else { int id = script_getnum(st, 2); sd = (map->id2sd(id) ? map->id2sd(id) : map->charid2sd(id)); } - } else { - sd = script->rid2sd(st); + } else if ((sd = script->rid2sd(st)) == NULL) { + script_pushconststr(st, ""); + return true; } - /* check for sd and IP */ - if (!sd || !sockt->session[sd->fd]->client_addr) - { + if (sd == NULL) { + ShowWarning("buildin_getcharip: Player not found!\n"); + script_pushconststr(st, ""); + script->reportfunc(st); + return false; + } + + /* check for IP */ + if (!sockt->session[sd->fd]->client_addr) { script_pushconststr(st, ""); return true; } @@ -18346,13 +18470,13 @@ BUILDIN(freeloop) { BUILDIN(sit) { struct map_session_data *sd = NULL; - if( script_hasdata(st, 2) ) - sd = map->nick2sd(script_getstr(st, 2)); + if (script_hasdata(st, 2)) + sd = script->nick2sd(st, script_getstr(st, 2)); else sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; if (!pc_issit(sd)) { @@ -18366,13 +18490,13 @@ BUILDIN(sit) { BUILDIN(stand) { struct map_session_data *sd = NULL; - if( script_hasdata(st, 2) ) - sd = map->nick2sd(script_getstr(st, 2)); + if (script_hasdata(st, 2)) + sd = script->nick2sd(st, script_getstr(st, 2)); else sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; if (pc_issit(sd)) { @@ -18386,13 +18510,13 @@ BUILDIN(stand) { BUILDIN(issit) { struct map_session_data *sd = NULL; - if( script_hasdata(st, 2) ) - sd = map->nick2sd(script_getstr(st, 2)); + if (script_hasdata(st, 2)) + sd = script->nick2sd(st, script_getstr(st, 2)); else sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; if (pc_issit(sd)) script_pushint(st, 1); @@ -18502,10 +18626,10 @@ BUILDIN(useatcmd) { cmd = script_getstr(st,2); - if( st->rid ) { + if (st->rid) { sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; fd = sd->fd; } else { // Use a dummy character. @@ -18683,21 +18807,17 @@ BUILDIN(cleanmap) /* Cast a skill on the attached player. * npcskill <skill id>, <skill lvl>, <stat point>, <NPC level>; * npcskill "<skill name>", <skill lvl>, <stat point>, <NPC level>; */ -BUILDIN(npcskill) { - uint16 skill_id; - unsigned short skill_level; - unsigned int stat_point; - unsigned int npc_level; +BUILDIN(npcskill) +{ struct npc_data *nd; - struct map_session_data *sd; - - skill_id = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2); - skill_level = script_getnum(st, 3); - stat_point = script_getnum(st, 4); - npc_level = script_getnum(st, 5); + uint16 skill_id = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2); + unsigned short skill_level = script_getnum(st, 3); + unsigned int stat_point = script_getnum(st, 4); + unsigned int npc_level = script_getnum(st, 5); + struct map_session_data *sd = script->rid2sd(st); - if( !(sd = script->rid2sd(st)) ) - return false; + if (sd == NULL) + return true; nd = (struct npc_data *)map->id2bl(sd->npc_id); @@ -18783,12 +18903,12 @@ BUILDIN(montransform) { if (script_hasdata(st, 8)) val4 = script_getnum(st, 8); - if( tick != 0 ) { - struct map_session_data *sd = map->id2sd(bl->id); + if (tick != 0) { + struct map_session_data *sd = script->id2sd(st, bl->id); struct mob_db *monster = mob->db(mob_id); char msg[CHAT_SIZE_MAX]; - if( !sd ) + if (sd == NULL) return true; if( battle_config.mon_trans_disable_in_gvg && map_flag_gvg2(sd->bl.m) ) { @@ -18881,7 +19001,7 @@ BUILDIN(queuesize) if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || !VECTOR_INDEX(script->hq, idx).valid) { ShowWarning("buildin_queuesize: unknown queue id %d\n",idx); script_pushint(st, 0); - return true; + return false; } script_pushint(st, VECTOR_LENGTH(VECTOR_INDEX(script->hq, idx).entries)); @@ -19033,7 +19153,7 @@ BUILDIN(queueopt) if (idx < 0 || idx >= VECTOR_LENGTH(script->hq) || !VECTOR_INDEX(script->hq, idx).valid) { ShowWarning("buildin_queueopt: unknown queue id %d\n",idx); script_pushint(st, 0); - return true; + return false; } queue = &VECTOR_INDEX(script->hq, idx); @@ -19060,7 +19180,7 @@ BUILDIN(queueopt) default: ShowWarning("buildin_queueopt: unsupported optionType %d\n",var); script_pushint(st, 0); - return true; + return false; } script_pushint(st, 1); return true; @@ -19160,7 +19280,7 @@ BUILDIN(queueiterator) if (qid < 0 || qid >= VECTOR_LENGTH(script->hq) || !VECTOR_INDEX(script->hq, qid).valid || !(queue = script->queue(qid))) { ShowWarning("queueiterator: invalid queue id %d\n",qid); script_pushint(st, -1); - return true; + return false; } ARR_FIND(0, VECTOR_LENGTH(script->hqi), i, !VECTOR_INDEX(script->hqi, i).valid); @@ -19201,7 +19321,7 @@ BUILDIN(qiget) if (idx < 0 || idx >= VECTOR_LENGTH(script->hqi) || !VECTOR_INDEX(script->hqi, idx).valid) { ShowWarning("buildin_qiget: unknown queue iterator id %d\n",idx); script_pushint(st, 0); - return true; + return false; } it = &VECTOR_INDEX(script->hqi, idx); @@ -19235,7 +19355,7 @@ BUILDIN(qicheck) if (idx < 0 || idx >= VECTOR_LENGTH(script->hqi) || !VECTOR_INDEX(script->hqi, idx).valid) { ShowWarning("buildin_qicheck: unknown queue iterator id %d\n",idx); script_pushint(st, 0); - return true; + return false; } it = &VECTOR_INDEX(script->hqi, idx); @@ -19266,7 +19386,7 @@ BUILDIN(qiclear) if (idx < 0 || idx >= VECTOR_LENGTH(script->hqi) || !VECTOR_INDEX(script->hqi, idx).valid) { ShowWarning("buildin_qiclear: unknown queue iterator id %d\n",idx); script_pushint(st, 0); - return true; + return false; } it = &VECTOR_INDEX(script->hqi, idx); @@ -19348,12 +19468,12 @@ BUILDIN(bg_join_team) { struct map_session_data *sd; int team_id = script_getnum(st, 2); - if( script_hasdata(st, 3) ) - sd = map->id2sd(script_getnum(st, 3)); + if (script_hasdata(st, 3)) + sd = script->id2sd(st, script_getnum(st, 3)); else sd = script->rid2sd(st); - if( !sd ) + if (sd == NULL) script_pushint(st, -1); else script_pushint(st,bg->team_join(team_id, sd)?0:1); @@ -19373,10 +19493,10 @@ BUILDIN(bg_join_team) { BUILDIN(countbound) { int i, type, j=0, k=0; - TBL_PC *sd; + TBL_PC *sd = script->rid2sd(st); - if( (sd = script->rid2sd(st)) == NULL ) - return false; + if (sd == NULL) + return true; type = script_hasdata(st,2)?script_getnum(st,2):0; @@ -19409,11 +19529,10 @@ BUILDIN(checkbound) { int i, nameid = script_getnum(st,2); int bound_type = 0; - TBL_PC *sd; + TBL_PC *sd = script->rid2sd(st); - sd = script->rid2sd(st); - if( sd == NULL ) - return false; + if (sd == NULL) + return true; if( !(itemdb->exists(nameid)) ){ ShowError("script_checkbound: Invalid item ID = %d\n", nameid); @@ -20273,7 +20392,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(atcommand,"s"), // [MouseJstr] BUILDIN_DEF2(atcommand,"charcommand","s"), // [MouseJstr] BUILDIN_DEF(movenpc,"sii?"), // [MouseJstr] - BUILDIN_DEF(message,"ss"), // [MouseJstr] + BUILDIN_DEF(message,"vs"), // [MouseJstr] BUILDIN_DEF(npctalk,"s?"), // [Valaris] BUILDIN_DEF(mobcount,"ss"), BUILDIN_DEF(getlook,"i"), @@ -20306,7 +20425,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(deletepset,"i"), // Delete a pattern set [MouseJstr] BUILDIN_DEF(pcre_match,"ss"), #endif - BUILDIN_DEF(dispbottom,"s"), //added from jA [Lupus] + BUILDIN_DEF(dispbottom,"s?"), //added from jA [Lupus] BUILDIN_DEF(getusersname,""), BUILDIN_DEF(recovery,""), BUILDIN_DEF(getpetinfo,"i"), @@ -20382,6 +20501,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(pcblockmove,"ii"), // <--- [zBuffer] List of player cont commands // [zBuffer] List of mob control commands ---> + BUILDIN_DEF(getunittype,"i"), BUILDIN_DEF(unitwalk,"ii?"), BUILDIN_DEF(unitkill,"i"), BUILDIN_DEF(unitwarp,"isii"), @@ -20790,6 +20910,9 @@ void script_defaults(void) { script->conv_num = conv_num; script->conv_str = conv_str; script->rid2sd = script_rid2sd; + script->id2sd = script_id2sd; + script->charid2sd = script_charid2sd; + script->nick2sd = script_nick2sd; script->detach_rid = script_detach_rid; script->push_val = push_val; script->get_val = get_val; diff --git a/src/map/script.h b/src/map/script.h index c47956eeb..b3e16b1b4 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -336,7 +336,8 @@ enum { MF_BATTLEGROUND, MF_RESET, MF_NOTOMB, - MF_NOCASHSHOP + MF_NOCASHSHOP, + MF_NOVIEWID }; /** @@ -647,6 +648,9 @@ struct script_interface { int (*conv_num) (struct script_state *st,struct script_data *data); const char* (*conv_str) (struct script_state *st,struct script_data *data); TBL_PC *(*rid2sd) (struct script_state *st); + TBL_PC *(*id2sd) (struct script_state *st, int account_id); + TBL_PC *(*charid2sd) (struct script_state *st, int char_id); + TBL_PC *(*nick2sd) (struct script_state *st, const char *name); void (*detach_rid) (struct script_state* st); struct script_data* (*push_val)(struct script_stack* stack, enum c_op type, int64 val, struct reg_db *ref); struct script_data *(*get_val) (struct script_state* st, struct script_data* data); diff --git a/src/map/skill.c b/src/map/skill.c index 8d97409fb..72363b9e3 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -5401,19 +5401,18 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin int heal = skill->calc_heal(src, bl, (skill_id == AB_HIGHNESSHEAL)?AL_HEAL:skill_id, (skill_id == AB_HIGHNESSHEAL)?10:skill_lv, true); int heal_get_jobexp; //Highness Heal: starts at 1.7 boost + 0.3 for each level - if( skill_id == AB_HIGHNESSHEAL ) { - heal = heal * ( 17 + 3 * skill_lv ) / 10; + if (skill_id == AB_HIGHNESSHEAL) { + heal = heal * (17 + 3 * skill_lv) / 10; } - if( status->isimmune(bl) || - (dstmd && (dstmd->class_ == MOBID_EMPERIUM || mob_is_battleground(dstmd))) ) - heal=0; + if (status->isimmune(bl) || (dstmd && (dstmd->class_ == MOBID_EMPERIUM || mob_is_battleground(dstmd)))) + heal = 0; - if( sd && dstsd && sd->status.partner_id == dstsd->status.char_id && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.sex == 0 ) - heal = heal*2; + if (sd && dstsd && sd->status.partner_id == dstsd->status.char_id && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.sex == 0) + heal = heal * 2; - if( tsc && tsc->count ) + if (tsc && tsc->count) { - if( tsc->data[SC_KAITE] && !(sstatus->mode&MD_BOSS) ) + if (tsc->data[SC_KAITE] && !(sstatus->mode&MD_BOSS)) { //Bounce back heal if (--tsc->data[SC_KAITE]->val2 <= 0) status_change_end(bl, SC_KAITE, INVALID_TIMER); @@ -7383,9 +7382,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; case NPC_AGIUP: - sc_start(src,bl,SC_MOVHASTE_INFINITY,100,skill_lv,skill->get_time(skill_id, skill_lv)); - clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(src,bl,type,100,100,skill->get_time(skill_id, skill_lv))); + sc_start(src, bl, SC_MOVHASTE_INFINITY, 100, 100, skill->get_time(skill_id, skill_lv)); // Fix 100% movement speed in all levels. [Frost] + clif->skill_nodamage(src, bl, skill_id, skill_lv, + sc_start(src, bl, type, 100, 100, skill->get_time(skill_id, skill_lv))); break; case NPC_INVISIBLE: @@ -7623,7 +7622,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin // Slim Pitcher case CR_SLIMPITCHER: // Updated to block Slim Pitcher from working on barricades and guardian stones. - if( dstmd && (dstmd->class_ == MOBID_EMPERIUM || (dstmd->class_ >= MOBID_BARRICADE1 && dstmd->class_ <= MOBID_GUARIDAN_STONE2)) ) + if (dstmd && (dstmd->class_ == MOBID_EMPERIUM || (dstmd->class_ >= MOBID_BARRICADE1 && dstmd->class_ <= MOBID_GUARDIAN_STONE2))) break; if (script->potion_hp || script->potion_sp) { int hp = script->potion_hp, sp = script->potion_sp; @@ -7703,9 +7702,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin map->freeblock_unlock(); return 0; } - if( rnd() % 100 > skill_lv * 8 || (dstmd && ((dstmd->guardian_data && dstmd->class_ == MOBID_EMPERIUM) || mob_is_battleground(dstmd))) ) { - if( sd ) - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + if (rnd() % 100 > skill_lv * 8 || (dstmd && ((dstmd->guardian_data && dstmd->class_ == MOBID_EMPERIUM) || mob_is_battleground(dstmd)))) { + if (sd) + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); map->freeblock_unlock(); return 0; @@ -11911,24 +11910,24 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 int heal = skill->calc_heal(ss,bl,sg->skill_id,sg->skill_lv,true); struct mob_data *md = BL_CAST(BL_MOB, bl); #ifdef RENEWAL - if( md && md->class_ == MOBID_EMPERIUM ) + if (md && md->class_ == MOBID_EMPERIUM) break; #endif - if( md && mob_is_battleground(md) ) + if (md && mob_is_battleground(md)) break; - if( tstatus->hp >= tstatus->max_hp ) + if (tstatus->hp >= tstatus->max_hp) break; - if( status->isimmune(bl) ) + if (status->isimmune(bl)) heal = 0; clif->skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1); - if( tsc && tsc->data[SC_AKAITSUKI] && heal ) + if (tsc && tsc->data[SC_AKAITSUKI] && heal) heal = ~heal + 1; status->heal(bl, heal, 0, 0); - if( diff >= 500 ) + if (diff >= 500) sg->val1--; } - if( sg->val1 <= 0 ) - skill->del_unitgroup(sg,ALC_MARK); + if (sg->val1 <= 0) + skill->del_unitgroup(sg, ALC_MARK); break; case UNT_EVILLAND: @@ -13667,7 +13666,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id case SR_CURSEDCIRCLE: if (map_flag_gvg2(sd->bl.m)) { if (map->foreachinrange(mob->count_sub, &sd->bl, skill->get_splash(skill_id, skill_lv), BL_MOB, - MOBID_EMPERIUM, MOBID_GUARIDAN_STONE1, MOBID_GUARIDAN_STONE2)) { + MOBID_EMPERIUM, MOBID_GUARDIAN_STONE1, MOBID_GUARDIAN_STONE2)) { char output[128]; sprintf(output, "You're too close to a stone or emperium to do this skill"); /* TODO official response? or message.conf it */ clif->messagecolor_self(sd->fd, COLOR_RED, output); @@ -14778,6 +14777,8 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16 } if (sc->data[SC_FENRIR_CARD]) fixcast_r = max(fixcast_r, sc->data[SC_FENRIR_CARD]->val2); + if (sc->data[SC_MAGIC_CANDY]) + fixcast_r = max(fixcast_r, sc->data[SC_MAGIC_CANDY]->val2); // Fixed cast non percentage bonuses if( sc->data[SC_MANDRAGORA] ) diff --git a/src/map/status.c b/src/map/status.c index ba64087e4..c7ce2c9c0 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -796,9 +796,11 @@ void initChangeTables(void) { status->dbs->IconChangeTable[SC_ATTHASTE_POTION1] = SI_ATTHASTE_POTION1; status->dbs->IconChangeTable[SC_ATTHASTE_POTION2] = SI_ATTHASTE_POTION2; status->dbs->IconChangeTable[SC_ATTHASTE_POTION3] = SI_ATTHASTE_POTION3; + status->dbs->IconChangeTable[SC_MOVHASTE_POTION] = SI_MOVHASTE_POTION; status->dbs->IconChangeTable[SC_ATTHASTE_INFINITY] = SI_ATTHASTE_INFINITY; status->dbs->IconChangeTable[SC_MOVHASTE_HORSE] = SI_MOVHASTE_HORSE; status->dbs->IconChangeTable[SC_MOVHASTE_INFINITY] = SI_MOVHASTE_INFINITY; + status->dbs->IconChangeTable[SC_MOVESLOW_POTION] = SI_MOVESLOW_POTION; status->dbs->IconChangeTable[SC_CHASEWALK2] = SI_INCSTR; status->dbs->IconChangeTable[SC_MIRACLE] = SI_SOULLINK; status->dbs->IconChangeTable[SC_CLAIRVOYANCE] = SI_CLAIRVOYANCE; @@ -820,6 +822,8 @@ void initChangeTables(void) { status->dbs->IconChangeTable[SC_PLUSMAGICPOWER] = SI_PLUSMAGICPOWER; status->dbs->IconChangeTable[SC_FOOD_CRITICALSUCCESSVALUE] = SI_FOOD_CRITICALSUCCESSVALUE; status->dbs->IconChangeTable[SC_MORA_BUFF] = SI_MORA_BUFF; + status->dbs->IconChangeTable[SC_BUCHEDENOEL] = SI_BUCHEDENOEL; + status->dbs->IconChangeTable[SC_PHI_DEMON] = SI_PHI_DEMON; // Cash Items status->dbs->IconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH; @@ -848,6 +852,16 @@ void initChangeTables(void) { status->dbs->IconChangeTable[SC_ATKER_MOVESPEED] = SI_ATKER_MOVESPEED; status->dbs->IconChangeTable[SC_CUP_OF_BOZA] = SI_CUP_OF_BOZA; status->dbs->IconChangeTable[SC_OVERLAPEXPUP] = SI_OVERLAPEXPUP; + status->dbs->IconChangeTable[SC_GM_BATTLE] = SI_GM_BATTLE; + status->dbs->IconChangeTable[SC_GM_BATTLE2] = SI_GM_BATTLE2; + status->dbs->IconChangeTable[SC_2011RWC] = SI_2011RWC; + status->dbs->IconChangeTable[SC_STR_SCROLL] = SI_STR_SCROLL; + status->dbs->IconChangeTable[SC_INT_SCROLL] = SI_INT_SCROLL; + status->dbs->IconChangeTable[SC_STEAMPACK] = SI_STEAMPACK; + status->dbs->IconChangeTable[SC_MAGIC_CANDY] = SI_MAGIC_CANDY; + status->dbs->IconChangeTable[SC_M_LIFEPOTION] = SI_M_LIFEPOTION; + status->dbs->IconChangeTable[SC_G_LIFEPOTION] = SI_G_LIFEPOTION; + status->dbs->IconChangeTable[SC_MYSTICPOWDER] = SI_MYSTICPOWDER; // Eden Crystal Synthesis status->dbs->IconChangeTable[SC_QUEST_BUFF1] = SI_QUEST_BUFF1; @@ -889,11 +903,13 @@ void initChangeTables(void) { status->dbs->IconChangeTable[SC_SPELLBOOK6] = SI_SPELLBOOK6; status->dbs->IconChangeTable[SC_SPELLBOOK7] = SI_SPELLBOOK7; + // Mechanic status icon status->dbs->IconChangeTable[SC_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER; status->dbs->IconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER; status->dbs->IconChangeTable[SC_OVERHEAT] = SI_OVERHEAT; status->dbs->IconChangeTable[SC_OVERHEAT_LIMITPOINT] = SI_OVERHEAT_LIMITPOINT; + // Guillotine Cross status icons status->dbs->IconChangeTable[SC_HALLUCINATIONWALK_POSTDELAY] = SI_HALLUCINATIONWALK_POSTDELAY; status->dbs->IconChangeTable[SC_TOXIN] = SI_TOXIN; status->dbs->IconChangeTable[SC_PARALYSE] = SI_PARALYSE; @@ -904,27 +920,22 @@ void initChangeTables(void) { status->dbs->IconChangeTable[SC_OBLIVIONCURSE] = SI_OBLIVIONCURSE; status->dbs->IconChangeTable[SC_LEECHESEND] = SI_LEECHESEND; + // Royal Guard status icons status->dbs->IconChangeTable[SC_SHIELDSPELL_DEF] = SI_SHIELDSPELL_DEF; status->dbs->IconChangeTable[SC_SHIELDSPELL_MDEF] = SI_SHIELDSPELL_MDEF; status->dbs->IconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF; status->dbs->IconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE; + // Sura status icon status->dbs->IconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER; - status->dbs->IconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE; - status->dbs->IconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER; - status->dbs->IconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB; - status->dbs->IconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB; - status->dbs->IconChangeTable[SC_BANANA_BOMB_SITDOWN_POSTDELAY] = SI_BANANA_BOMB_SITDOWN_POSTDELAY; - - // Genetics New Food Items Status Icons + // Genetics Food items / Throwable items status icons status->dbs->IconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK; status->dbs->IconChangeTable[SC_COCKTAIL_WARG_BLOOD] = SI_COCKTAIL_WARG_BLOOD; status->dbs->IconChangeTable[SC_MINOR_BBQ] = SI_MINOR_BBQ; status->dbs->IconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA; status->dbs->IconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED; status->dbs->IconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES; - status->dbs->IconChangeTable[SC_BOOST500] |= SI_BOOST500; status->dbs->IconChangeTable[SC_FULL_SWING_K] |= SI_FULL_SWING_K; status->dbs->IconChangeTable[SC_MANA_PLUS] |= SI_MANA_PLUS; @@ -933,6 +944,13 @@ void initChangeTables(void) { status->dbs->IconChangeTable[SC_EXTRACT_WHITE_POTION_Z] |= SI_EXTRACT_WHITE_POTION_Z; status->dbs->IconChangeTable[SC_VITATA_500] |= SI_VITATA_500; status->dbs->IconChangeTable[SC_EXTRACT_SALAMINE_JUICE] |= SI_EXTRACT_SALAMINE_JUICE; + status->dbs->IconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE; + status->dbs->IconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER; + status->dbs->IconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB; + status->dbs->IconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB; + status->dbs->IconChangeTable[SC_BANANA_BOMB_SITDOWN_POSTDELAY] = SI_BANANA_BOMB_SITDOWN_POSTDELAY; + status->dbs->IconChangeTable[SC_PROMOTE_HEALTH_RESERCH] = SI_PROMOTE_HEALTH_RESERCH; + status->dbs->IconChangeTable[SC_ENERGY_DRINK_RESERCH] = SI_ENERGY_DRINK_RESERCH; // Elemental Spirit's 'side' status change icons. status->dbs->IconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE; @@ -959,23 +977,36 @@ void initChangeTables(void) { status->dbs->IconChangeTable[SC_REBOUND] = SI_REBOUND; status->dbs->IconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING; status->dbs->IconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM; + + // Costumes status->dbs->IconChangeTable[SC_MOONSTAR] = SI_MOONSTAR; status->dbs->IconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR; status->dbs->IconChangeTable[SC_STRANGELIGHTS] = SI_STRANGELIGHTS; status->dbs->IconChangeTable[SC_DECORATION_OF_MUSIC] = SI_DECORATION_OF_MUSIC; status->dbs->IconChangeTable[SC_LJOSALFAR] = SI_LJOSALFAR; status->dbs->IconChangeTable[SC_MERMAID_LONGING] = SI_MERMAID_LONGING; - + status->dbs->IconChangeTable[SC_HAT_EFFECT] = SI_HAT_EFFECT; + status->dbs->IconChangeTable[SC_FLOWERSMOKE] = SI_FLOWERSMOKE; + status->dbs->IconChangeTable[SC_FSTONE] = SI_FSTONE; + status->dbs->IconChangeTable[SC_HAPPINESS_STAR] = SI_HAPPINESS_STAR; + status->dbs->IconChangeTable[SC_MAPLE_FALLS] = SI_MAPLE_FALLS; + status->dbs->IconChangeTable[SC_TIME_ACCESSORY] = SI_TIME_ACCESSORY; + status->dbs->IconChangeTable[SC_MAGICAL_FEATHER] = SI_MAGICAL_FEATHER; + status->dbs->IconChangeTable[SC_BLOSSOM_FLUTTERING] = SI_BLOSSOM_FLUTTERING; + // Other SC which are not necessarily associated to skills. - status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION1] = SCB_ASPD; - status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION2] = SCB_ASPD; - status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION3] = SCB_ASPD; - status->dbs->ChangeFlagTable[SC_ATTHASTE_INFINITY] = SCB_ASPD; - status->dbs->ChangeFlagTable[SC_MOVHASTE_HORSE] = SCB_SPEED; - status->dbs->ChangeFlagTable[SC_MOVHASTE_INFINITY] = SCB_SPEED; - status->dbs->ChangeFlagTable[SC_PLUSATTACKPOWER] = SCB_BATK; - status->dbs->ChangeFlagTable[SC_PLUSMAGICPOWER] = SCB_MATK; - status->dbs->ChangeFlagTable[SC_INCALLSTATUS] |= SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK; + status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION1] |= SCB_ASPD; + status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION2] |= SCB_ASPD; + status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION3] |= SCB_ASPD; + status->dbs->ChangeFlagTable[SC_MOVHASTE_POTION] |= SCB_SPEED; + status->dbs->ChangeFlagTable[SC_ATTHASTE_INFINITY] |= SCB_ASPD; + status->dbs->ChangeFlagTable[SC_MOVHASTE_HORSE] |= SCB_SPEED; + status->dbs->ChangeFlagTable[SC_MOVHASTE_INFINITY] |= SCB_SPEED; + status->dbs->ChangeFlagTable[SC_MOVESLOW_POTION] |= SCB_SPEED; + status->dbs->ChangeFlagTable[SC_SLOWDOWN] |= SCB_SPEED; + status->dbs->ChangeFlagTable[SC_PLUSATTACKPOWER] |= SCB_BATK; + status->dbs->ChangeFlagTable[SC_PLUSMAGICPOWER] |= SCB_MATK; + status->dbs->ChangeFlagTable[SC_INCALLSTATUS] |= SCB_STR | SCB_AGI | SCB_VIT | SCB_INT | SCB_DEX | SCB_LUK; status->dbs->ChangeFlagTable[SC_CHASEWALK2] |= SCB_STR; status->dbs->ChangeFlagTable[SC_INCAGI] |= SCB_AGI; status->dbs->ChangeFlagTable[SC_INCVIT] |= SCB_VIT; @@ -986,17 +1017,14 @@ void initChangeTables(void) { status->dbs->ChangeFlagTable[SC_INCHITRATE] |= SCB_HIT; status->dbs->ChangeFlagTable[SC_INCFLEE] |= SCB_FLEE; status->dbs->ChangeFlagTable[SC_INCFLEERATE] |= SCB_FLEE; - status->dbs->ChangeFlagTable[SC_MTF_HITFLEE] |= SCB_HIT|SCB_FLEE; status->dbs->ChangeFlagTable[SC_CRITICALPERCENT] |= SCB_CRI; status->dbs->ChangeFlagTable[SC_INCASPDRATE] |= SCB_ASPD; status->dbs->ChangeFlagTable[SC_PLUSAVOIDVALUE] |= SCB_FLEE2; status->dbs->ChangeFlagTable[SC_INCMHPRATE] |= SCB_MAXHP; status->dbs->ChangeFlagTable[SC_INCMSPRATE] |= SCB_MAXSP; status->dbs->ChangeFlagTable[SC_INCMHP] |= SCB_MAXHP; - status->dbs->ChangeFlagTable[SC_MTF_MHP] |= SCB_MAXHP; status->dbs->ChangeFlagTable[SC_INCMSP] |= SCB_MAXSP; - status->dbs->ChangeFlagTable[SC_MTF_MSP] |= SCB_MAXSP; - status->dbs->ChangeFlagTable[SC_INCATKRATE] |= SCB_BATK|SCB_WATK; + status->dbs->ChangeFlagTable[SC_INCATKRATE] |= SCB_BATK | SCB_WATK; status->dbs->ChangeFlagTable[SC_INCMATKRATE] |= SCB_MATK; status->dbs->ChangeFlagTable[SC_INCDEFRATE] |= SCB_DEF; status->dbs->ChangeFlagTable[SC_FOOD_STR] |= SCB_STR; @@ -1010,6 +1038,8 @@ void initChangeTables(void) { status->dbs->ChangeFlagTable[SC_BATKFOOD] |= SCB_BATK; status->dbs->ChangeFlagTable[SC_WATKFOOD] |= SCB_WATK; status->dbs->ChangeFlagTable[SC_MATKFOOD] |= SCB_MATK; + status->dbs->ChangeFlagTable[SC_ALL_RIDING] |= SCB_SPEED; + status->dbs->ChangeFlagTable[SC_WEDDING] |= SCB_SPEED; status->dbs->ChangeFlagTable[SC_ARMORPROPERTY] |= SCB_ALL; status->dbs->ChangeFlagTable[SC_ARMOR_RESIST] |= SCB_ALL; status->dbs->ChangeFlagTable[SC_ATKER_BLOOD] |= SCB_ALL; @@ -1018,16 +1048,27 @@ void initChangeTables(void) { status->dbs->ChangeFlagTable[SC_TARGET_ASPD] |= SCB_MAXSP; status->dbs->ChangeFlagTable[SC_ATKER_ASPD] |= SCB_MAXHP | SCB_ALL; status->dbs->ChangeFlagTable[SC_ATKER_MOVESPEED] |= SCB_MAXSP | SCB_ALL; + status->dbs->ChangeFlagTable[SC_ACARAJE] |= SCB_HIT | SCB_ASPD; status->dbs->ChangeFlagTable[SC_FOOD_CRITICALSUCCESSVALUE] |= SCB_CRI; status->dbs->ChangeFlagTable[SC_CUP_OF_BOZA] |= SCB_VIT | SCB_ALL; + status->dbs->ChangeFlagTable[SC_GM_BATTLE] |= SCB_BATK | SCB_MATK | SCB_MAXHP | SCB_MAXSP; + status->dbs->ChangeFlagTable[SC_GM_BATTLE2] |= SCB_BATK | SCB_MATK | SCB_MAXHP | SCB_MAXSP; + status->dbs->ChangeFlagTable[SC_2011RWC] |= SCB_STR | SCB_AGI | SCB_VIT | SCB_INT | SCB_DEX | SCB_LUK | SCB_BATK | SCB_MATK; + status->dbs->ChangeFlagTable[SC_STR_SCROLL] |= SCB_STR; + status->dbs->ChangeFlagTable[SC_INT_SCROLL] |= SCB_INT; + status->dbs->ChangeFlagTable[SC_STEAMPACK] |= SCB_BATK | SCB_ASPD | SCB_ALL; + status->dbs->ChangeFlagTable[SC_BUCHEDENOEL] |= SCB_REGEN | SCB_HIT | SCB_CRI; + status->dbs->ChangeFlagTable[SC_PHI_DEMON] |= SCB_ALL; + status->dbs->ChangeFlagTable[SC_MAGIC_CANDY] |= SCB_MATK | SCB_ALL; + status->dbs->ChangeFlagTable[SC_MYSTICPOWDER] |= SCB_FLEE | SCB_LUK; // Cash Items - status->dbs->ChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR; - status->dbs->ChangeFlagTable[SC_FOOD_AGI_CASH] = SCB_AGI; - status->dbs->ChangeFlagTable[SC_FOOD_VIT_CASH] = SCB_VIT; - status->dbs->ChangeFlagTable[SC_FOOD_DEX_CASH] = SCB_DEX; - status->dbs->ChangeFlagTable[SC_FOOD_INT_CASH] = SCB_INT; - status->dbs->ChangeFlagTable[SC_FOOD_LUK_CASH] = SCB_LUK; + status->dbs->ChangeFlagTable[SC_FOOD_STR_CASH] |= SCB_STR; + status->dbs->ChangeFlagTable[SC_FOOD_AGI_CASH] |= SCB_AGI; + status->dbs->ChangeFlagTable[SC_FOOD_VIT_CASH] |= SCB_VIT; + status->dbs->ChangeFlagTable[SC_FOOD_DEX_CASH] |= SCB_DEX; + status->dbs->ChangeFlagTable[SC_FOOD_INT_CASH] |= SCB_INT; + status->dbs->ChangeFlagTable[SC_FOOD_LUK_CASH] |= SCB_LUK; // Mercenary Bonus Effects status->dbs->ChangeFlagTable[SC_MER_FLEE] |= SCB_FLEE; @@ -1037,20 +1078,26 @@ void initChangeTables(void) { status->dbs->ChangeFlagTable[SC_MER_HIT] |= SCB_HIT; // Guillotine Cross Poison Effects - status->dbs->ChangeFlagTable[SC_PARALYSE] |= SCB_FLEE|SCB_SPEED|SCB_ASPD; + status->dbs->ChangeFlagTable[SC_PARALYSE] |= SCB_FLEE | SCB_SPEED | SCB_ASPD; status->dbs->ChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP; status->dbs->ChangeFlagTable[SC_MAGICMUSHROOM] |= SCB_REGEN; status->dbs->ChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN; - status->dbs->ChangeFlagTable[SC_PYREXIA] |= SCB_HIT|SCB_FLEE; + status->dbs->ChangeFlagTable[SC_PYREXIA] |= SCB_HIT | SCB_FLEE; status->dbs->ChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN; - // RG status + // Royal Guard status status->dbs->ChangeFlagTable[SC_SHIELDSPELL_DEF] |= SCB_WATK; status->dbs->ChangeFlagTable[SC_SHIELDSPELL_REF] |= SCB_DEF; - // Meca status + // Mechanic status status->dbs->ChangeFlagTable[SC_STEALTHFIELD_MASTER] |= SCB_SPEED; + // Other skills status + status->dbs->ChangeFlagTable[SC_REBOUND] |= SCB_SPEED | SCB_REGEN; + status->dbs->ChangeFlagTable[SC_DEFSET] |= SCB_DEF | SCB_DEF2; + status->dbs->ChangeFlagTable[SC_MDEFSET] |= SCB_MDEF | SCB_MDEF2; + + // Geneticist Foods / Throwable items status->dbs->ChangeFlagTable[SC_SAVAGE_STEAK] |= SCB_STR; status->dbs->ChangeFlagTable[SC_COCKTAIL_WARG_BLOOD] |= SCB_INT; status->dbs->ChangeFlagTable[SC_MINOR_BBQ] |= SCB_VIT; @@ -1065,30 +1112,29 @@ void initChangeTables(void) { status->dbs->ChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN; status->dbs->ChangeFlagTable[SC_VITATA_500] |= SCB_REGEN | SCB_MAXSP; status->dbs->ChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD; - status->dbs->ChangeFlagTable[SC_REBOUND] |= SCB_SPEED | SCB_REGEN; - status->dbs->ChangeFlagTable[SC_DEFSET] |= SCB_DEF | SCB_DEF2; - status->dbs->ChangeFlagTable[SC_MDEFSET] |= SCB_MDEF | SCB_MDEF2; status->dbs->ChangeFlagTable[SC_MYSTERIOUS_POWDER] |= SCB_MAXHP; - status->dbs->ChangeFlagTable[SC_ACARAJE] |= SCB_HIT | SCB_ASPD; status->dbs->ChangeFlagTable[SC_STOMACHACHE] |= SCB_STR | SCB_AGI | SCB_VIT | SCB_INT | SCB_DEX | SCB_LUK | SCB_SPEED; + status->dbs->ChangeFlagTable[SC_PROMOTE_HEALTH_RESERCH] |= SCB_MAXHP | SCB_ALL; + status->dbs->ChangeFlagTable[SC_ENERGY_DRINK_RESERCH] |= SCB_MAXSP | SCB_ALL; // Geffen Scrolls status->dbs->ChangeFlagTable[SC_SKELSCROLL] |= SCB_ALL; status->dbs->ChangeFlagTable[SC_DISTRUCTIONSCROLL] |= SCB_ALL; status->dbs->ChangeFlagTable[SC_ROYALSCROLL] |= SCB_ALL; status->dbs->ChangeFlagTable[SC_IMMUNITYSCROLL] |= SCB_ALL; - status->dbs->ChangeFlagTable[SC_MYSTICSCROLL] |= SCB_MATK; + status->dbs->ChangeFlagTable[SC_MYSTICSCROLL] |= SCB_MATK | SCB_ALL; status->dbs->ChangeFlagTable[SC_BATTLESCROLL] |= SCB_BATK | SCB_ASPD; status->dbs->ChangeFlagTable[SC_ARMORSCROLL] |= SCB_DEF | SCB_FLEE; status->dbs->ChangeFlagTable[SC_FREYJASCROLL] |= SCB_MDEF | SCB_FLEE2; status->dbs->ChangeFlagTable[SC_SOULSCROLL] |= SCB_MAXHP | SCB_MAXSP; - status->dbs->ChangeFlagTable[SC_ALL_RIDING] = SCB_SPEED; - status->dbs->ChangeFlagTable[SC_WEDDING] = SCB_SPEED; - - status->dbs->ChangeFlagTable[SC_MTF_ASPD] = SCB_ASPD | SCB_HIT; - status->dbs->ChangeFlagTable[SC_MTF_MATK] = SCB_MATK; + // Monster Transform + status->dbs->ChangeFlagTable[SC_MTF_ASPD] |= SCB_ASPD | SCB_HIT; + status->dbs->ChangeFlagTable[SC_MTF_MATK] |= SCB_MATK; status->dbs->ChangeFlagTable[SC_MTF_MLEATKED] |= SCB_ALL; + status->dbs->ChangeFlagTable[SC_MTF_HITFLEE] |= SCB_HIT | SCB_FLEE; + status->dbs->ChangeFlagTable[SC_MTF_MHP] |= SCB_MAXHP; + status->dbs->ChangeFlagTable[SC_MTF_MSP] |= SCB_MAXSP; // Eden Crystal Synthesis status->dbs->ChangeFlagTable[SC_QUEST_BUFF1] |= SCB_BATK | SCB_MATK; @@ -1107,13 +1153,21 @@ void initChangeTables(void) { status->dbs->ChangeFlagTable[SC_MVPCARD_ORCHERO] |= SCB_ALL; status->dbs->ChangeFlagTable[SC_MVPCARD_ORCLORD] |= SCB_ALL; - // Costume + // Costumes status->dbs->ChangeFlagTable[SC_MOONSTAR] |= SCB_NONE; status->dbs->ChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE; status->dbs->ChangeFlagTable[SC_STRANGELIGHTS] |= SCB_NONE; status->dbs->ChangeFlagTable[SC_DECORATION_OF_MUSIC] |= SCB_NONE; status->dbs->ChangeFlagTable[SC_LJOSALFAR] |= SCB_NONE; status->dbs->ChangeFlagTable[SC_MERMAID_LONGING] |= SCB_NONE; + status->dbs->ChangeFlagTable[SC_HAT_EFFECT] |= SCB_NONE; + status->dbs->ChangeFlagTable[SC_FLOWERSMOKE] |= SCB_NONE; + status->dbs->ChangeFlagTable[SC_FSTONE] |= SCB_NONE; + status->dbs->ChangeFlagTable[SC_HAPPINESS_STAR] |= SCB_NONE; + status->dbs->ChangeFlagTable[SC_MAPLE_FALLS] |= SCB_NONE; + status->dbs->ChangeFlagTable[SC_TIME_ACCESSORY] |= SCB_NONE; + status->dbs->ChangeFlagTable[SC_MAGICAL_FEATHER] |= SCB_NONE; + status->dbs->ChangeFlagTable[SC_BLOSSOM_FLUTTERING] |= SCB_NONE; /* status->dbs->DisplayType Table [Ind/Hercules] */ status->dbs->DisplayType[SC_ALL_RIDING] = true; @@ -1138,12 +1192,22 @@ void initChangeTables(void) { status->dbs->DisplayType[SC_BLOOD_SUCKER] = true; status->dbs->DisplayType[SC__SHADOWFORM] = true; status->dbs->DisplayType[SC_MONSTER_TRANSFORM] = true; + + // Costumes status->dbs->DisplayType[SC_MOONSTAR] = true; status->dbs->DisplayType[SC_SUPER_STAR] = true; status->dbs->DisplayType[SC_STRANGELIGHTS] = true; status->dbs->DisplayType[SC_DECORATION_OF_MUSIC] = true; status->dbs->DisplayType[SC_LJOSALFAR] = true; status->dbs->DisplayType[SC_MERMAID_LONGING] = true; + status->dbs->DisplayType[SC_HAT_EFFECT] = true; + status->dbs->DisplayType[SC_FLOWERSMOKE] = true; + status->dbs->DisplayType[SC_FSTONE] = true; + status->dbs->DisplayType[SC_HAPPINESS_STAR] = true; + status->dbs->DisplayType[SC_MAPLE_FALLS] = true; + status->dbs->DisplayType[SC_TIME_ACCESSORY] = true; + status->dbs->DisplayType[SC_MAGICAL_FEATHER] = true; + status->dbs->DisplayType[SC_BLOSSOM_FLUTTERING] = true; if( !battle_config.display_hallucination ) //Disable Hallucination. status->dbs->IconChangeTable[SC_ILLUSION] = SI_BLANK; @@ -3026,7 +3090,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { sd->subele[ELE_FIRE] -= i; } if (sc->data[SC_MTF_MLEATKED]) - sd->subele[ELE_NEUTRAL] += 2; + sd->subele[ELE_NEUTRAL] += sc->data[SC_MTF_MLEATKED]->val1; if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3) sd->magic_addele[ELE_FIRE] += 25; if (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3) @@ -3078,6 +3142,10 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { } if (sc->data[SC_CUP_OF_BOZA]) sd->subele[ELE_FIRE] += sc->data[SC_CUP_OF_BOZA]->val2; + if (sc->data[SC_PHI_DEMON]) { + sd->right_weapon.addrace[RC_DEMON] += sc->data[SC_PHI_DEMON]->val1; + sd->left_weapon.addrace[RC_DEMON] += sc->data[SC_PHI_DEMON]->val1; + } } status_cpy(&sd->battle_status, bstatus); @@ -3459,6 +3527,8 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str regen->rate.hp *= 2; if (sc->data[SC_VITALITYACTIVATION]) regen->flag &=~RGN_SP; + + // Recovery Items if (sc->data[SC_EXTRACT_WHITE_POTION_Z]) regen->rate.hp += regen->rate.hp * sc->data[SC_EXTRACT_WHITE_POTION_Z]->val1 / 100; if (sc->data[SC_VITATA_500]) @@ -3467,6 +3537,10 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str regen->rate.hp += regen->rate.hp * sc->data[SC_ATKER_ASPD]->val2 / 100; if (sc->data[SC_ATKER_MOVESPEED]) regen->rate.sp += regen->rate.sp * sc->data[SC_ATKER_MOVESPEED]->val2 / 100; + if (sc->data[SC_BUCHEDENOEL]) { + regen->rate.hp += regen->rate.hp * sc->data[SC_BUCHEDENOEL]->val1 / 100; + regen->rate.sp += regen->rate.sp * sc->data[SC_BUCHEDENOEL]->val2 / 100; + } } /// Recalculates parts of an object's battle status according to the specified flags. /// @param flag bitfield of values from enum scb_flag @@ -4321,6 +4395,10 @@ unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, str -= sc->data[SC_STOMACHACHE]->val1; if(sc->data[SC_KYOUGAKU]) str -= sc->data[SC_KYOUGAKU]->val3; + if (sc->data[SC_2011RWC]) + str += sc->data[SC_2011RWC]->val1; + if (sc->data[SC_STR_SCROLL]) + str += sc->data[SC_STR_SCROLL]->val1; return (unsigned short)cap_value(str,0,USHRT_MAX); } @@ -4376,6 +4454,8 @@ unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, agi -= sc->data[SC_STOMACHACHE]->val1; if(sc->data[SC_KYOUGAKU]) agi -= sc->data[SC_KYOUGAKU]->val3; + if (sc->data[SC_2011RWC]) + agi += sc->data[SC_2011RWC]->val1; if(sc->data[SC_MARSHOFABYSS]) agi -= agi * sc->data[SC_MARSHOFABYSS]->val2 / 100; @@ -4428,6 +4508,8 @@ unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc, vit -= vit * sc->data[SC_NOEQUIPARMOR]->val2 / 100; if (sc->data[SC_CUP_OF_BOZA]) vit += sc->data[SC_CUP_OF_BOZA]->val1; + if (sc->data[SC_2011RWC]) + vit += sc->data[SC_2011RWC]->val1; return (unsigned short)cap_value(vit,0,USHRT_MAX); } @@ -4483,6 +4565,10 @@ unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int_ -= sc->data[SC_STOMACHACHE]->val1; if(sc->data[SC_KYOUGAKU]) int_ -= sc->data[SC_KYOUGAKU]->val3; + if (sc->data[SC_2011RWC]) + int_ += sc->data[SC_2011RWC]->val1; + if (sc->data[SC_INT_SCROLL]) + int_ += sc->data[SC_INT_SCROLL]->val1; if(bl->type != BL_PC){ if(sc->data[SC_NOEQUIPHELM]) @@ -4545,6 +4631,8 @@ unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, dex -= sc->data[SC_STOMACHACHE]->val1; if(sc->data[SC_KYOUGAKU]) dex -= sc->data[SC_KYOUGAKU]->val3; + if (sc->data[SC_2011RWC]) + dex += sc->data[SC_2011RWC]->val1; if(sc->data[SC_MARSHOFABYSS]) dex -= dex * sc->data[SC_MARSHOFABYSS]->val2 / 100; @@ -4554,54 +4642,57 @@ unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, return (unsigned short)cap_value(dex,0,USHRT_MAX); } -unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk) -{ - if(!sc || !sc->count) - return cap_value(luk,0,USHRT_MAX); +unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk) { - if(sc->data[SC_FULL_THROTTLE]) + if (!sc || !sc->count) + return cap_value(luk, 0, USHRT_MAX); + + if (sc->data[SC_FULL_THROTTLE]) luk += luk * 20 / 100; - if(sc->data[SC_HARMONIZE]) { + if (sc->data[SC_HARMONIZE]) { luk -= sc->data[SC_HARMONIZE]->val2; - return (unsigned short)cap_value(luk,0,USHRT_MAX); + return (unsigned short)cap_value(luk, 0, USHRT_MAX); } - if(sc->data[SC_CURSE]) + if (sc->data[SC_CURSE]) return 0; - if(sc->data[SC_INCALLSTATUS]) + if (sc->data[SC_INCALLSTATUS]) luk += sc->data[SC_INCALLSTATUS]->val1; - if(sc->data[SC_INCLUK]) + if (sc->data[SC_INCLUK]) luk += sc->data[SC_INCLUK]->val1; - if(sc->data[SC_FOOD_LUK]) + if (sc->data[SC_FOOD_LUK]) luk += sc->data[SC_FOOD_LUK]->val1; - if(sc->data[SC_FOOD_LUK_CASH]) + if (sc->data[SC_FOOD_LUK_CASH]) luk += sc->data[SC_FOOD_LUK_CASH]->val1; - if(sc->data[SC_TRUESIGHT]) + if (sc->data[SC_TRUESIGHT]) luk += 5; - if(sc->data[SC_GLORIA]) + if (sc->data[SC_GLORIA]) luk += 30; - if(sc->data[SC_MARIONETTE_MASTER]) + if (sc->data[SC_MARIONETTE_MASTER]) luk -= sc->data[SC_MARIONETTE_MASTER]->val4&0xFF; - if(sc->data[SC_MARIONETTE]) + if (sc->data[SC_MARIONETTE]) luk += sc->data[SC_MARIONETTE]->val4&0xFF; - if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH) + if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH) luk += sc->data[SC_SOULLINK]->val4&0xFF; - if(sc->data[SC_PUTTI_TAILS_NOODLES]) + if (sc->data[SC_PUTTI_TAILS_NOODLES]) luk += sc->data[SC_PUTTI_TAILS_NOODLES]->val1; - if(sc->data[SC_INSPIRATION]) + if (sc->data[SC_INSPIRATION]) luk += sc->data[SC_INSPIRATION]->val3; - if(sc->data[SC_STOMACHACHE]) + if (sc->data[SC_STOMACHACHE]) luk -= sc->data[SC_STOMACHACHE]->val1; - if(sc->data[SC_KYOUGAKU]) + if (sc->data[SC_KYOUGAKU]) luk -= sc->data[SC_KYOUGAKU]->val3; - if(sc->data[SC_LAUDARAMUS]) + if (sc->data[SC_LAUDARAMUS]) luk += 4 + sc->data[SC_LAUDARAMUS]->val1; - - if(sc->data[SC__STRIPACCESSARY] && bl->type != BL_PC) + if (sc->data[SC__STRIPACCESSARY] && bl->type != BL_PC) luk -= luk * sc->data[SC__STRIPACCESSARY]->val2 / 100; - if(sc->data[SC_BANANA_BOMB]) + if (sc->data[SC_BANANA_BOMB]) luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100; + if (sc->data[SC_2011RWC]) + luk += sc->data[SC_2011RWC]->val1; + if (sc->data[SC_MYSTICPOWDER]) + luk += sc->data[SC_MYSTICPOWDER]->val2; - return (unsigned short)cap_value(luk,0,USHRT_MAX); + return (unsigned short)cap_value(luk, 0, USHRT_MAX); } unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk, bool viewable) { @@ -4675,6 +4766,8 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, batk -= batk * sc->data[SC__ENERVATION]->val2 / 100; if(sc->data[SC_SATURDAY_NIGHT_FEVER]) batk += 100 * sc->data[SC_SATURDAY_NIGHT_FEVER]->val1; + if (sc->data[SC_BATTLESCROLL]) + batk += batk * sc->data[SC_BATTLESCROLL]->val1 / 100; // Eden Crystal Synthesis if (sc->data[SC_QUEST_BUFF1]) @@ -4684,6 +4777,15 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, if (sc->data[SC_QUEST_BUFF3]) batk += sc->data[SC_QUEST_BUFF3]->val1; + if (sc->data[SC_GM_BATTLE]) + batk += batk * sc->data[SC_GM_BATTLE]->val1 / 100; + if (sc->data[SC_GM_BATTLE2]) + batk += batk * sc->data[SC_GM_BATTLE2]->val1 / 100; + if (sc->data[SC_2011RWC]) + batk += batk * sc->data[SC_2011RWC]->val2 / 100; + if (sc->data[SC_STEAMPACK]) + batk += sc->data[SC_STEAMPACK]->val1; + return (unsigned short)cap_value(batk,0,USHRT_MAX); } @@ -4806,16 +4908,16 @@ unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc return 0; #endif } -unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk, bool viewable) -{ - if(!sc || !sc->count) +unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk, bool viewable) { + + if (!sc || !sc->count) return cap_value(matk,0,USHRT_MAX); - if( !viewable ){ + if (!viewable) { /* some statuses that are hidden in the status window */ if (sc->data[SC_MINDBREAKER]) - matk += matk * sc->data[SC_MINDBREAKER]->val2/100; - return (unsigned short)cap_value(matk,0,USHRT_MAX); + matk += matk * sc->data[SC_MINDBREAKER]->val2 / 100; + return (unsigned short)cap_value(matk, 0, USHRT_MAX); } #ifndef RENEWAL @@ -4830,7 +4932,7 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, matk += sc->data[SC_AQUAPLAY_OPTION]->val2; if (sc->data[SC_CHILLY_AIR_OPTION]) matk += sc->data[SC_CHILLY_AIR_OPTION]->val2; - if(sc->data[SC_COOLER_OPTION]) + if (sc->data[SC_COOLER_OPTION]) matk += sc->data[SC_COOLER_OPTION]->val2; if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3) matk += 50; @@ -4839,16 +4941,16 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, if (sc->data[SC_IZAYOI]) matk += 25 * sc->data[SC_IZAYOI]->val1; #endif - if( sc->data[SC_ZANGETSU] ) + if (sc->data[SC_ZANGETSU]) matk += sc->data[SC_ZANGETSU]->val3; if (sc->data[SC_MAGICPOWER] && sc->data[SC_MAGICPOWER]->val4) - matk += matk * sc->data[SC_MAGICPOWER]->val3/100; + matk += matk * sc->data[SC_MAGICPOWER]->val3 / 100; if (sc->data[SC_INCMATKRATE]) - matk += matk * sc->data[SC_INCMATKRATE]->val1/100; + matk += matk * sc->data[SC_INCMATKRATE]->val1 / 100; if (sc->data[SC_MOONLIT_SERENADE]) - matk += matk * sc->data[SC_MOONLIT_SERENADE]->val2/100; + matk += matk * sc->data[SC_MOONLIT_SERENADE]->val2 / 100; if (sc->data[SC_MTF_MATK]) - matk += matk * 25 / 100; + matk += matk * sc->data[SC_MTF_MATK]->val1 / 100; if (sc->data[SC_MYSTICSCROLL]) matk += matk * sc->data[SC_MYSTICSCROLL]->val1 / 100; @@ -4864,17 +4966,26 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, if (sc->data[SC_FENRIR_CARD]) matk += sc->data[SC_FENRIR_CARD]->val1; - return (unsigned short)cap_value(matk,0,USHRT_MAX); + if (sc->data[SC_GM_BATTLE]) + matk += matk * sc->data[SC_GM_BATTLE]->val1 / 100; + if (sc->data[SC_GM_BATTLE2]) + matk += matk * sc->data[SC_GM_BATTLE2]->val1 / 100; + if (sc->data[SC_2011RWC]) + matk += matk * sc->data[SC_2011RWC]->val2 / 100; + if (sc->data[SC_MAGIC_CANDY]) + matk += sc->data[SC_MAGIC_CANDY]->val1; + + return (unsigned short)cap_value(matk, 0, USHRT_MAX); } signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical, bool viewable) { - if(!sc || !sc->count) - return cap_value(critical,10,SHRT_MAX); + if (!sc || !sc->count) + return cap_value(critical, 10, SHRT_MAX); - if( !viewable ){ + if (!viewable) { /* some statuses that are hidden in the status window */ - return (short)cap_value(critical,10,SHRT_MAX); + return (short)cap_value(critical, 10, SHRT_MAX); } if (sc->data[SC_CRITICALPERCENT]) @@ -4887,170 +4998,175 @@ signed short status_calc_critical(struct block_list *bl, struct status_change *s critical += sc->data[SC_FORTUNE]->val2; if (sc->data[SC_TRUESIGHT]) critical += sc->data[SC_TRUESIGHT]->val2; - if(sc->data[SC_CLOAKING]) + if (sc->data[SC_CLOAKING]) critical += critical; - if(sc->data[SC_STRIKING]) + if (sc->data[SC_STRIKING]) critical += sc->data[SC_STRIKING]->val1; #ifdef RENEWAL if (sc->data[SC_SPEARQUICKEN]) - critical += 3*sc->data[SC_SPEARQUICKEN]->val1*10; + critical += 3*sc->data[SC_SPEARQUICKEN]->val1 * 10; #endif - if(sc->data[SC__INVISIBILITY]) + if (sc->data[SC__INVISIBILITY]) critical += sc->data[SC__INVISIBILITY]->val3; - if(sc->data[SC__UNLUCKY]) + if (sc->data[SC__UNLUCKY]) critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100; - if(sc->data[SC_BEYOND_OF_WARCRY]) - critical += 10 * sc->data[SC_BEYOND_OF_WARCRY]->val3; + if (sc->data[SC_BEYOND_OF_WARCRY]) + critical += sc->data[SC_BEYOND_OF_WARCRY]->val3 * 10; + if (sc->data[SC_BUCHEDENOEL]) + critical += sc->data[SC_BUCHEDENOEL]->val4 * 10; - return (short)cap_value(critical,10,SHRT_MAX); + return (short)cap_value(critical, 10, SHRT_MAX); } signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit, bool viewable) { - if(!sc || !sc->count) - return cap_value(hit,1,SHRT_MAX); + if (!sc || !sc->count) + return cap_value(hit, 1, SHRT_MAX); - if( !viewable ){ + if (!viewable) { /* some statuses that are hidden in the status window */ - if(sc->data[SC_MTF_ASPD]) - hit += 5; - return (short)cap_value(hit,1,SHRT_MAX); + if (sc->data[SC_MTF_ASPD]) + hit += sc->data[SC_MTF_ASPD]->val2; + return (short)cap_value(hit, 1, SHRT_MAX); } - if(sc->data[SC_INCHIT]) + if (sc->data[SC_INCHIT]) hit += sc->data[SC_INCHIT]->val1; - if(sc->data[SC_MTF_HITFLEE]) + if (sc->data[SC_MTF_HITFLEE]) hit += sc->data[SC_MTF_HITFLEE]->val1; - if(sc->data[SC_FOOD_BASICHIT]) + if (sc->data[SC_FOOD_BASICHIT]) hit += sc->data[SC_FOOD_BASICHIT]->val1; - if(sc->data[SC_TRUESIGHT]) + if (sc->data[SC_TRUESIGHT]) hit += sc->data[SC_TRUESIGHT]->val3; - if(sc->data[SC_HUMMING]) + if (sc->data[SC_HUMMING]) hit += sc->data[SC_HUMMING]->val2; - if(sc->data[SC_LKCONCENTRATION]) + if (sc->data[SC_LKCONCENTRATION]) hit += sc->data[SC_LKCONCENTRATION]->val3; - if(sc->data[SC_INSPIRATION]) + if (sc->data[SC_INSPIRATION]) hit += 5 * sc->data[SC_INSPIRATION]->val1 + 25; - if(sc->data[SC_GS_ADJUSTMENT]) + if (sc->data[SC_GS_ADJUSTMENT]) hit -= 30; - if(sc->data[SC_GS_ACCURACY]) + if (sc->data[SC_GS_ACCURACY]) hit += 20; // RockmanEXE; changed based on updated [Reddozen] - if(sc->data[SC_MER_HIT]) + if (sc->data[SC_MER_HIT]) hit += sc->data[SC_MER_HIT]->val2; - - if(sc->data[SC_INCHITRATE]) + if (sc->data[SC_INCHITRATE]) hit += hit * sc->data[SC_INCHITRATE]->val1/100; - if(sc->data[SC_BLIND]) + if (sc->data[SC_BLIND]) hit -= hit * 25/100; - if(sc->data[SC_FIRE_EXPANSION_TEAR_GAS]) + if (sc->data[SC_FIRE_EXPANSION_TEAR_GAS]) hit -= hit * 50 / 100; - if(sc->data[SC__GROOMY]) + if (sc->data[SC__GROOMY]) hit -= hit * sc->data[SC__GROOMY]->val3 / 100; - if(sc->data[SC_FEAR]) + if (sc->data[SC_FEAR]) hit -= hit * 20 / 100; if (sc->data[SC_VOLCANIC_ASH]) hit /= 2; - if(sc->data[SC_ILLUSIONDOPING]) + if (sc->data[SC_ILLUSIONDOPING]) hit -= hit * (5 + sc->data[SC_ILLUSIONDOPING]->val1) / 100; //custom if (sc->data[SC_ACARAJE]) hit += sc->data[SC_ACARAJE]->val1; + if (sc->data[SC_BUCHEDENOEL]) + hit += sc->data[SC_BUCHEDENOEL]->val3; - return (short)cap_value(hit,1,SHRT_MAX); + return (short)cap_value(hit, 1, SHRT_MAX); } signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee, bool viewable) { - if( bl->type == BL_PC ) { - if( map_flag_gvg2(bl->m) ) - flee -= flee * battle_config.gvg_flee_penalty/100; + + if (bl->type == BL_PC) { + if (map_flag_gvg2(bl->m)) + flee -= flee * battle_config.gvg_flee_penalty / 100; else if( map->list[bl->m].flag.battleground ) - flee -= flee * battle_config.bg_flee_penalty/100; + flee -= flee * battle_config.bg_flee_penalty / 100; } - if(!sc || !sc->count) - return cap_value(flee,1,SHRT_MAX); + if (!sc || !sc->count) + return cap_value(flee, 1, SHRT_MAX); - if( !viewable ){ + if (!viewable) { /* some statuses that are hidden in the status window */ - return (short)cap_value(flee,1,SHRT_MAX); + return (short)cap_value(flee, 1, SHRT_MAX); } - if(sc->data[SC_INCFLEE]) + if (sc->data[SC_INCFLEE]) flee += sc->data[SC_INCFLEE]->val1; - if(sc->data[SC_MTF_HITFLEE]) + if (sc->data[SC_MTF_HITFLEE]) flee += sc->data[SC_MTF_HITFLEE]->val2; - if(sc->data[SC_FOOD_BASICAVOIDANCE]) + if (sc->data[SC_FOOD_BASICAVOIDANCE]) flee += sc->data[SC_FOOD_BASICAVOIDANCE]->val1; - if(sc->data[SC_WHISTLE]) + if (sc->data[SC_WHISTLE]) flee += sc->data[SC_WHISTLE]->val2; - if(sc->data[SC_WINDWALK]) + if (sc->data[SC_WINDWALK]) flee += sc->data[SC_WINDWALK]->val2; - if(sc->data[SC_VIOLENTGALE]) + if (sc->data[SC_VIOLENTGALE]) flee += sc->data[SC_VIOLENTGALE]->val2; - if(sc->data[SC_MOON_COMFORT]) //SG skill [Komurka] + if (sc->data[SC_MOON_COMFORT]) // SG skill [Komurka] flee += sc->data[SC_MOON_COMFORT]->val2; - if(sc->data[SC_RG_CCONFINE_M]) + if (sc->data[SC_RG_CCONFINE_M]) flee += 10; if (sc->data[SC_ANGRIFFS_MODUS]) flee -= sc->data[SC_ANGRIFFS_MODUS]->val3; - if(sc->data[SC_GS_ADJUSTMENT]) + if (sc->data[SC_GS_ADJUSTMENT]) flee += 30; - if(sc->data[SC_HLIF_SPEED]) + if (sc->data[SC_HLIF_SPEED]) flee += 10 + sc->data[SC_HLIF_SPEED]->val1 * 10; - if(sc->data[SC_GS_GATLINGFEVER]) + if (sc->data[SC_GS_GATLINGFEVER]) flee -= sc->data[SC_GS_GATLINGFEVER]->val4; - if(sc->data[SC_PARTYFLEE]) + if (sc->data[SC_PARTYFLEE]) flee += sc->data[SC_PARTYFLEE]->val1 * 10; - if(sc->data[SC_MER_FLEE]) + if (sc->data[SC_MER_FLEE]) flee += sc->data[SC_MER_FLEE]->val2; - if( sc->data[SC_HALLUCINATIONWALK] ) + if (sc->data[SC_HALLUCINATIONWALK]) flee += sc->data[SC_HALLUCINATIONWALK]->val2; - if( sc->data[SC_WATER_BARRIER] ) + if (sc->data[SC_WATER_BARRIER]) flee -= sc->data[SC_WATER_BARRIER]->val3; #ifdef RENEWAL - if( sc->data[SC_SPEARQUICKEN] ) - flee += 2 * sc->data[SC_SPEARQUICKEN]->val1; + if (sc->data[SC_SPEARQUICKEN]) + flee += sc->data[SC_SPEARQUICKEN]->val1 * 2; #endif - - if(sc->data[SC_INCFLEERATE]) - flee += flee * sc->data[SC_INCFLEERATE]->val1/100; - if(sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1) - flee -= flee * 50/100; + if (sc->data[SC_INCFLEERATE]) + flee += flee * sc->data[SC_INCFLEERATE]->val1 / 100; + if (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1) + flee -= flee * 50 / 100; if (sc->data[SC_BERSERK]) - flee -= flee * 50/100; - if(sc->data[SC_BLIND]) - flee -= flee * 25/100; - if(sc->data[SC_FEAR]) + flee -= flee * 50 / 100; + if (sc->data[SC_BLIND]) + flee -= flee * 25 / 100; + if (sc->data[SC_FEAR]) flee -= flee * 20 / 100; - if(sc->data[SC_PARALYSE]) + if (sc->data[SC_PARALYSE]) flee -= flee / 10; // 10% Flee reduction - if(sc->data[SC_INFRAREDSCAN]) + if (sc->data[SC_INFRAREDSCAN]) flee -= flee * 30 / 100; - if( sc->data[SC__LAZINESS] ) + if (sc->data[SC__LAZINESS]) flee -= flee * sc->data[SC__LAZINESS]->val3 / 100; - if( sc->data[SC_GLOOMYDAY] ) + if (sc->data[SC_GLOOMYDAY]) flee -= flee * ( 20 + 5 * sc->data[SC_GLOOMYDAY]->val1 ) / 100; - if( sc->data[SC_SATURDAY_NIGHT_FEVER] ) + if (sc->data[SC_SATURDAY_NIGHT_FEVER]) flee -= flee * (40 + 10 * sc->data[SC_SATURDAY_NIGHT_FEVER]->val1) / 100; - if ( sc->data[SC_FIRE_EXPANSION_SMOKE_POWDER] ) + if (sc->data[SC_FIRE_EXPANSION_SMOKE_POWDER]) flee += flee * 20 / 100; - if ( sc->data[SC_FIRE_EXPANSION_TEAR_GAS] ) + if (sc->data[SC_FIRE_EXPANSION_TEAR_GAS]) flee -= flee * 50 / 100; - if( sc->data[SC_WIND_STEP_OPTION] ) + if (sc->data[SC_WIND_STEP_OPTION]) flee += flee * sc->data[SC_WIND_STEP_OPTION]->val2 / 100; - if( sc->data[SC_ZEPHYR] ) + if (sc->data[SC_ZEPHYR]) flee += sc->data[SC_ZEPHYR]->val2; - if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){ //mob - if(status_get_element(bl) == ELE_WATER) //water type + if (sc->data[SC_VOLCANIC_ASH] && (bl->type == BL_MOB)) { // mob + if(status_get_element(bl) == ELE_WATER) // water type flee /= 2; } - if( sc->data[SC_OVERED_BOOST] ) // should be final and unmodifiable by any means + if (sc->data[SC_OVERED_BOOST]) // should be final and unmodifiable by any means flee = sc->data[SC_OVERED_BOOST]->val2; if (sc->data[SC_ARMORSCROLL]) flee += sc->data[SC_ARMORSCROLL]->val2; + if (sc->data[SC_MYSTICPOWDER]) + flee += sc->data[SC_MYSTICPOWDER]->val2; - return (short)cap_value(flee,1,SHRT_MAX); + return (short)cap_value(flee, 1, SHRT_MAX); } signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2, bool viewable) @@ -5425,8 +5541,10 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc val = max( val, sc->data[SC_CLOAKING]->val1 < 3 ? 300 : 30 - 3 * sc->data[SC_CLOAKING]->val1 ); if( sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY ) val = max( val, 75 ); - if( sc->data[SC_SLOWDOWN] ) // Slow Potion - val = max( val, 100 ); + if (sc->data[SC_SLOWDOWN]) + val = max(val, 100); + if (sc->data[SC_MOVESLOW_POTION]) // Used by Slow_Down_Potion [Frost] + val = max(val, sc->data[SC_MOVESLOW_POTION]->val1); if( sc->data[SC_GS_GATLINGFEVER] ) val = max( val, 100 ); if( sc->data[SC_NJ_SUITON] ) @@ -5457,6 +5575,11 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc if( sc->data[SC_MARSHOFABYSS] ) // It stacks to other statuses so always put this at the end. val = max( 50, val + 10 * sc->data[SC_MARSHOFABYSS]->val1 ); + if (sc->data[SC_MOVHASTE_POTION]) { // Doesn't affect the movement speed by Quagmire, Decrease Agi, Slow Grace [Frost] + if (sc->data[SC_DEC_AGI] || sc->data[SC_QUAGMIRE] || sc->data[SC_DONTFORGETME]) + return 0; + } + if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate > 0 ) // permanent item-based speedup val = max( val, sd->bonus.speed_rate + sd->bonus.speed_add_rate ); } @@ -5468,8 +5591,10 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc { int val = 0; - if( sc->data[SC_MOVHASTE_INFINITY] ) //FIXME: used both by NPC_AGIUP and Speed Potion script - val = max( val, 50 ); + if (sc->data[SC_MOVHASTE_INFINITY]) // Used by NPC_AGIUP [Frost] + val = max(val, sc->data[SC_MOVHASTE_INFINITY]->val1); + if (sc->data[SC_MOVHASTE_POTION]) // Used by Speed_Up_Potion and Guyak_Pudding [Frost] + val = max(val, sc->data[SC_MOVHASTE_POTION]->val1); if( sc->data[SC_INC_AGI] ) val = max( val, 25 ); if( sc->data[SC_WINDWALK] ) @@ -5500,9 +5625,8 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc val = max( val, sc->data[SC_WIND_STEP_OPTION]->val2 ); if( sc->data[SC_FULL_THROTTLE] ) val = max( val, 25); - //FIXME: official items use a single bonus for this [ultramage] - if( sc->data[SC_MOVHASTE_HORSE] ) // temporary item-based speedup - val = max( val, 25 ); + if (sc->data[SC_MOVHASTE_HORSE]) + val = max(val, sc->data[SC_MOVHASTE_HORSE]->val1); if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate < 0 ) // permanent item-based speedup val = max( val, -(sd->bonus.speed_rate + sd->bonus.speed_add_rate) ); @@ -5658,6 +5782,8 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl bonus += sc->data[SC_ACARAJE]->val2; if (sc->data[SC_BATTLESCROLL]) bonus += sc->data[SC_BATTLESCROLL]->val1; + if (sc->data[SC_STEAMPACK]) + bonus += sc->data[SC_STEAMPACK]->val2; } return (bonus + pots); @@ -5676,7 +5802,7 @@ short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int if (sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2) aspd -= (bl->type==BL_PC?pc->checkskill((TBL_PC *)bl, RK_RUNEMASTERY):10) / 10 * 40; if (sc->data[SC_MTF_ASPD]) - aspd -= 10; + aspd -= sc->data[SC_MTF_ASPD]->val1; if (sc->data[SC_OVERED_BOOST]) // should be final and unmodifiable by any means aspd = (200 - sc->data[SC_OVERED_BOOST]->val3) * 10; @@ -5823,6 +5949,8 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate += sc->data[SC_ACARAJE]->val2 * 10; if (sc->data[SC_BATTLESCROLL]) aspd_rate += sc->data[SC_BATTLESCROLL]->val1 * 10; + if (sc->data[SC_STEAMPACK]) + aspd_rate += sc->data[SC_STEAMPACK]->val2 * 10; return (short)cap_value(aspd_rate,0,SHRT_MAX); } @@ -5843,68 +5971,70 @@ unsigned short status_calc_dmotion(struct block_list *bl, struct status_change * return (unsigned short)cap_value(dmotion,0,USHRT_MAX); } -unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, uint64 maxhp) -{ - if(!sc || !sc->count) - return (unsigned int)cap_value(maxhp,1,UINT_MAX); +unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, uint64 maxhp) { - if(sc->data[SC_INCMHPRATE]) - maxhp += maxhp * sc->data[SC_INCMHPRATE]->val1/100; - if(sc->data[SC_INCMHP]) + if (!sc || !sc->count) + return (unsigned int)cap_value(maxhp, 1, UINT_MAX); + + if (sc->data[SC_INCMHPRATE]) + maxhp += maxhp * sc->data[SC_INCMHPRATE]->val1 / 100; + if (sc->data[SC_INCMHP]) maxhp += (sc->data[SC_INCMHP]->val1); - if(sc->data[SC_MTF_MHP]) + if (sc->data[SC_MTF_MHP]) maxhp += (sc->data[SC_MTF_MHP]->val1); - if(sc->data[SC_APPLEIDUN]) - maxhp += maxhp * sc->data[SC_APPLEIDUN]->val2/100; - if(sc->data[SC_DELUGE]) - maxhp += maxhp * sc->data[SC_DELUGE]->val2/100; - if(sc->data[SC_BERSERK]) + if (sc->data[SC_APPLEIDUN]) + maxhp += maxhp * sc->data[SC_APPLEIDUN]->val2 / 100; + if (sc->data[SC_DELUGE]) + maxhp += maxhp * sc->data[SC_DELUGE]->val2 / 100; + if (sc->data[SC_BERSERK]) maxhp += maxhp * 2; - if(sc->data[SC_MARIONETTE_MASTER]) + if (sc->data[SC_MARIONETTE_MASTER]) maxhp -= 1000; - if(sc->data[SC_SOLID_SKIN_OPTION]) - maxhp += 2000;// Fix amount. - if(sc->data[SC_POWER_OF_GAIA]) + if (sc->data[SC_SOLID_SKIN_OPTION]) + maxhp += 2000; // Fix amount. + if (sc->data[SC_POWER_OF_GAIA]) maxhp += 3000; - if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2) + if (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2) maxhp += 500; - if(sc->data[SC_MER_HP]) - maxhp += maxhp * sc->data[SC_MER_HP]->val2/100; - if(sc->data[SC_EPICLESIS]) + if (sc->data[SC_MER_HP]) + maxhp += maxhp * sc->data[SC_MER_HP]->val2 / 100; + if (sc->data[SC_EPICLESIS]) maxhp += maxhp * 5 * sc->data[SC_EPICLESIS]->val1 / 100; - if(sc->data[SC_VENOMBLEED]) + if (sc->data[SC_VENOMBLEED]) maxhp -= maxhp * 15 / 100; - if(sc->data[SC__WEAKNESS]) + if (sc->data[SC__WEAKNESS]) maxhp -= maxhp * sc->data[SC__WEAKNESS]->val2 / 100; - if(sc->data[SC_LERADS_DEW]) + if (sc->data[SC_LERADS_DEW]) maxhp += sc->data[SC_LERADS_DEW]->val3; - if(sc->data[SC_BEYOND_OF_WARCRY]) + if (sc->data[SC_BEYOND_OF_WARCRY]) maxhp -= maxhp * sc->data[SC_BEYOND_OF_WARCRY]->val4 / 100; - if(sc->data[SC_FORCEOFVANGUARD]) + if (sc->data[SC_FORCEOFVANGUARD]) maxhp += maxhp * 3 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100; - if(sc->data[SC_INSPIRATION]) + if (sc->data[SC_INSPIRATION]) maxhp += maxhp * 5 * sc->data[SC_INSPIRATION]->val1 / 100 + 600 * sc->data[SC_INSPIRATION]->val1; - if(sc->data[SC_RAISINGDRAGON]) + if (sc->data[SC_RAISINGDRAGON]) maxhp += maxhp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100; - if(sc->data[SC_GENTLETOUCH_CHANGE]) // Max HP decrease: [Skill Level x 4] % + if (sc->data[SC_GENTLETOUCH_CHANGE]) // Max HP decrease: [Skill Level x 4] % maxhp -= maxhp * (4 * sc->data[SC_GENTLETOUCH_CHANGE]->val1) / 100; - if(sc->data[SC_GENTLETOUCH_REVITALIZE])// Max HP increase: [Skill Level x 2] % + if (sc->data[SC_GENTLETOUCH_REVITALIZE])// Max HP increase: [Skill Level x 2] % maxhp += maxhp * (2 * sc->data[SC_GENTLETOUCH_REVITALIZE]->val1) / 100; - if(sc->data[SC_MUSTLE_M]) - maxhp += maxhp * sc->data[SC_MUSTLE_M]->val1/100; - if(sc->data[SC_MYSTERIOUS_POWDER]) - maxhp -= sc->data[SC_MYSTERIOUS_POWDER]->val1 / 100; - if(sc->data[SC_PETROLOGY_OPTION]) + if (sc->data[SC_MUSTLE_M]) + maxhp += maxhp * sc->data[SC_MUSTLE_M]->val1 / 100; + if (sc->data[SC_PROMOTE_HEALTH_RESERCH]) + maxhp += sc->data[SC_PROMOTE_HEALTH_RESERCH]->val3; + if (sc->data[SC_MYSTERIOUS_POWDER]) + maxhp -= maxhp * sc->data[SC_MYSTERIOUS_POWDER]->val1 / 100; + if (sc->data[SC_PETROLOGY_OPTION]) maxhp += maxhp * sc->data[SC_PETROLOGY_OPTION]->val2 / 100; - if(sc->data[SC_CURSED_SOIL_OPTION]) + if (sc->data[SC_CURSED_SOIL_OPTION]) maxhp += maxhp * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100; - if(sc->data[SC_UPHEAVAL_OPTION]) + if (sc->data[SC_UPHEAVAL_OPTION]) maxhp += maxhp * sc->data[SC_UPHEAVAL_OPTION]->val3 / 100; if (sc->data[SC_ANGRIFFS_MODUS]) maxhp += maxhp * 5 * sc->data[SC_ANGRIFFS_MODUS]->val1 /100; if (sc->data[SC_GOLDENE_FERSE]) maxhp += maxhp * sc->data[SC_GOLDENE_FERSE]->val2 / 100; - if(sc->data[SC_FRIGG_SONG]) + if (sc->data[SC_FRIGG_SONG]) maxhp += maxhp * sc->data[SC_FRIGG_SONG]->val2 / 100; if (sc->data[SC_SOULSCROLL]) maxhp += maxhp * sc->data[SC_SOULSCROLL]->val1 / 100; @@ -5912,41 +6042,51 @@ unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, maxhp += maxhp * sc->data[SC_ATKER_ASPD]->val1 / 100; if (sc->data[SC_MVPCARD_TAOGUNKA]) maxhp += maxhp * sc->data[SC_MVPCARD_TAOGUNKA]->val1 / 100; + if (sc->data[SC_GM_BATTLE]) + maxhp -= maxhp * sc->data[SC_GM_BATTLE]->val1 / 100; + if (sc->data[SC_GM_BATTLE2]) + maxhp -= maxhp * sc->data[SC_GM_BATTLE2]->val1 / 100; - return (unsigned int)cap_value(maxhp,1,UINT_MAX); + return (unsigned int)cap_value(maxhp, 1, UINT_MAX); } -unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc, unsigned int maxsp) -{ - if(!sc || !sc->count) - return cap_value(maxsp,1,UINT_MAX); +unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc, unsigned int maxsp) { + + if (!sc || !sc->count) + return cap_value(maxsp, 1, UINT_MAX); - if(sc->data[SC_INCMSPRATE]) - maxsp += maxsp * sc->data[SC_INCMSPRATE]->val1/100; - if(sc->data[SC_INCMSP]) + if (sc->data[SC_INCMSPRATE]) + maxsp += maxsp * sc->data[SC_INCMSPRATE]->val1 / 100; + if (sc->data[SC_INCMSP]) maxsp += (sc->data[SC_INCMSP]->val1); - if(sc->data[SC_MTF_MSP]) + if (sc->data[SC_MTF_MSP]) maxsp += (sc->data[SC_MTF_MSP]->val1); - if(sc->data[SC_SERVICEFORYOU]) - maxsp += maxsp * sc->data[SC_SERVICEFORYOU]->val2/100; - if(sc->data[SC_MER_SP]) - maxsp += maxsp * sc->data[SC_MER_SP]->val2/100; - if(sc->data[SC_RAISINGDRAGON]) + if (sc->data[SC_SERVICEFORYOU]) + maxsp += maxsp * sc->data[SC_SERVICEFORYOU]->val2 / 100; + if (sc->data[SC_MER_SP]) + maxsp += maxsp * sc->data[SC_MER_SP]->val2 / 100; + if (sc->data[SC_RAISINGDRAGON]) maxsp += maxsp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100; - if(sc->data[SC_LIFE_FORCE_F]) - maxsp += maxsp * sc->data[SC_LIFE_FORCE_F]->val1/100; - if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3) + if (sc->data[SC_LIFE_FORCE_F]) + maxsp += maxsp * sc->data[SC_LIFE_FORCE_F]->val1 / 100; + if (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3) maxsp += 50; if (sc->data[SC_VITATA_500]) maxsp += maxsp * sc->data[SC_VITATA_500]->val2 / 100; + if (sc->data[SC_ENERGY_DRINK_RESERCH]) + maxsp += maxsp * sc->data[SC_ENERGY_DRINK_RESERCH]->val3 / 100; if (sc->data[SC_TARGET_ASPD]) maxsp += maxsp * sc->data[SC_TARGET_ASPD]->val1 / 100; if (sc->data[SC_SOULSCROLL]) maxsp += maxsp * sc->data[SC_SOULSCROLL]->val1 / 100; if (sc->data[SC_ATKER_MOVESPEED]) maxsp += maxsp * sc->data[SC_ATKER_MOVESPEED]->val1 / 100; + if (sc->data[SC_GM_BATTLE]) + maxsp -= maxsp * sc->data[SC_GM_BATTLE]->val1 / 100; + if (sc->data[SC_GM_BATTLE2]) + maxsp -= maxsp * sc->data[SC_GM_BATTLE2]->val1 / 100; - return cap_value(maxsp,1,UINT_MAX); + return cap_value(maxsp, 1, UINT_MAX); } unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element) @@ -6940,23 +7080,23 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t sc = status->get_sc(bl); st = status->get_status_data(bl); - if( type <= SC_NONE || type >= SC_MAX ) { + if (type <= SC_NONE || type >= SC_MAX) { ShowError("status_change_start: invalid status change (%d)!\n", type); return 0; } - if( !sc ) + if (!sc) return 0; //Unable to receive status changes - if( status->isdead(bl) && type != SC_NOCHAT ) // SC_NOCHAT should work even on dead characters + if (status->isdead(bl) && type != SC_NOCHAT) // SC_NOCHAT should work even on dead characters return 0; - if( bl->type == BL_MOB) { - struct mob_data *md = BL_CAST(BL_MOB,bl); - if(md && (md->class_ == MOBID_EMPERIUM || mob_is_battleground(md)) && type != SC_SAFETYWALL && type != SC_PNEUMA) + if (bl->type == BL_MOB) { + struct mob_data *md = BL_CAST(BL_MOB, bl); + if (md && (md->class_ == MOBID_EMPERIUM || mob_is_battleground(md)) && type != SC_SAFETYWALL && type != SC_PNEUMA) return 0; //Emperium/BG Monsters can't be afflicted by status changes #if 0 - if(md && mob_is_gvg(md) && status->sc2scb_flag(type)&SCB_MAXHP) + if (md && mob_is_gvg(md) && status->sc2scb_flag(type)&SCB_MAXHP) return 0; //prevent status addinh hp to gvg mob (like bloodylust=hp*3 etc... #endif // 0 } @@ -7073,25 +7213,20 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t if((type == SC_FREEZE || type == SC_FROSTMISTY || type == SC_COLD) && sc->data[SC_WARMER]) return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie] break; - - //There all like berserk, do not everlap each other - case SC_BERSERK: - if( sc->data[SC__BLOODYLUST] ) + case SC_BERSERK: // There all like berserk, do not everlap each other + if (sc->data[SC__BLOODYLUST]) return 0; break; - case SC_BURNING: - if(sc->opt1 || sc->data[SC_FROSTMISTY]) + if (sc->opt1 || sc->data[SC_FROSTMISTY]) return 0; break; - - case SC_CRUCIS: - //Only affects demons and undead element (but not players) - if((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC) + case SC_CRUCIS: // Only affects demons and undead element (but not players) + if ((!undead_flag && st->race != RC_DEMON) || bl->type == BL_PC) return 0; break; case SC_LEXAETERNA: - if( (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE] ) + if ((sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE]) return 0; break; case SC_KYRIE: @@ -7100,46 +7235,40 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t break; case SC_OVERTHRUST: if (sc->data[SC_OVERTHRUSTMAX]) - return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex] + return 0; // Overthrust can't take effect if under Max Overthrust. [Skotlex] case SC_OVERTHRUSTMAX: - if( sc->option&OPTION_MADOGEAR ) - return 0; //Overthrust and Overthrust Max cannot be used on Mado Gear [Ind] + if (sc->option&OPTION_MADOGEAR) + return 0; // Overthrust and Overthrust Max cannot be used on Mado Gear [Ind] break; case SC_ADRENALINE: - if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE))) + if (sd && !pc_check_weapontype(sd, skill->get_weapontype(BS_ADRENALINE))) return 0; - if (sc->data[SC_QUAGMIRE] || - sc->data[SC_DEC_AGI] || - sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind] - ) + if (sc->data[SC_QUAGMIRE] || sc->data[SC_DEC_AGI] || sc->option&OPTION_MADOGEAR) // Adrenaline doesn't affect Mado Gear [Ind] return 0; break; case SC_ADRENALINE2: - if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE2))) + if (sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE2))) return 0; - if (sc->data[SC_QUAGMIRE] || - sc->data[SC_DEC_AGI] - ) + if (sc->data[SC_QUAGMIRE] || sc->data[SC_DEC_AGI]) return 0; break; case SC_MAGNIFICAT: - if( sc->data[SC_OFFERTORIUM] || sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat + if (sc->data[SC_OFFERTORIUM] || sc->option&OPTION_MADOGEAR) // Mado is immune to magnificat return 0; break; case SC_ONEHANDQUICKEN: case SC_MER_QUICKEN: case SC_TWOHANDQUICKEN: - if(sc->data[SC_DEC_AGI]) + if (sc->data[SC_DEC_AGI]) return 0; - case SC_CONCENTRATION: case SC_SPEARQUICKEN: case SC_TRUESIGHT: case SC_WINDWALK: case SC_CARTBOOST: case SC_ASSNCROS: - if(sc->option&OPTION_MADOGEAR) - return 0; //Mado is immune to wind walk, cart boost, etc (others above) [Ind] + if (sc->option&OPTION_MADOGEAR) + return 0; // Mado is immune to wind walk, cart boost, etc (others above) [Ind] case SC_INC_AGI: if (sc->data[SC_QUAGMIRE]) return 0; @@ -7525,6 +7654,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t case SC_FOOD_LUK_CASH: status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER); break; + case SC_GM_BATTLE: + status_change_end(bl, SC_GM_BATTLE2, INVALID_TIMER); + break; + case SC_GM_BATTLE2: + status_change_end(bl, SC_GM_BATTLE, INVALID_TIMER); + break; case SC_ENDURE: if( val4 == 1 ) status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER); @@ -7634,6 +7769,8 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t break; case SC_S_LIFEPOTION: case SC_L_LIFEPOTION: + case SC_M_LIFEPOTION: + case SC_G_LIFEPOTION: case SC_CASH_BOSS_ALARM: case SC_STUN: case SC_SLEEP: @@ -8018,12 +8155,14 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t break; case SC_S_LIFEPOTION: case SC_L_LIFEPOTION: - if( val1 == 0 ) return 0; + case SC_M_LIFEPOTION: + case SC_G_LIFEPOTION: + if (val1 == 0) return 0; // val1 = heal percent/amout // val2 = seconds between heals // val4 = total of heals - if( val2 < 1 ) val2 = 1; - if( (val4 = tick/(val2 * 1000)) < 1 ) + if (val2 < 1) val2 = 1; + if ((val4 = tick / (val2 * 1000)) < 1) val4 = 1; tick_time = val2 * 1000; // [GodLesZ] tick time break; @@ -9136,6 +9275,41 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t val4 = tick / 10000; tick_time = 10000; // [GodLesZ] tick time break; + case SC_STEAMPACK: // [Frost] + val3 = 100; // HP Consume. + val4 = tick / 10000; + tick_time = 10000; + sc_start(src, bl, SC_ENDURE, 100, 10, tick); // Endure effect + break; + case SC_MAGIC_CANDY: // [Frost] + val3 = 90; // SP Consume. + val4 = tick / 10000; + tick_time = 10000; + break; + case SC_PROMOTE_HEALTH_RESERCH: + // Val1: 1 = Regular Potion, 2 = Thrown Potion + // Val2: 1 = Small Potion, 2 = Medium Potion, 3 = Large Potion + // Val3: MaxHP Increase By Fixed Amount + // Val4: HP Heal Percentage + if (val1 == 1) // If potion was normally used, take the user's BaseLv. + val3 = 1000 * val2 - 500 + status->get_lv(bl) * 10 / 3; + else if (val1 == 2) // If potion was thrown at someone, take the thrower's BaseLv. + val3 = 1000 * val2 - 500 + status->get_lv(src) * 10 / 3; + if (val3 <= 0) // Prevents a negeative value from happening. + val3 = 0; + break; + case SC_ENERGY_DRINK_RESERCH: + // Val1: 1 = Regular Potion, 2 = Thrown Potion + // Val2: 1 = Small Potion, 2 = Medium Potion, 3 = Large Potion + // Val3: MaxSP Increase By Fixed Amount + // Val4: SP Heal Percentage + if (val1 == 1) // If potion was normally used, take the user's BaseLv. + val3 = status->get_lv(bl) / 10 + 5 * val2 - 10; + else if (val1 == 2) // If potion was thrown at someone, take the thrower's BaseLv. + val3 = status->get_lv(src) / 10 + 5 * val2 - 10; + if (val3 <= 0) // Prevents a negeative value from happening. + val3 = 0; + break; case SC_KYOUGAKU: { int min = val1*2; int max = val1*3; @@ -9760,6 +9934,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t case SC_MER_SP: status_percent_heal(bl, 0, 100); // Recover Full SP break; + case SC_PROMOTE_HEALTH_RESERCH: + status_percent_heal(bl, sce->val4, 0); + break; + case SC_ENERGY_DRINK_RESERCH: + status_percent_heal(bl, 0, sce->val4); + break; /** * Ranger **/ @@ -10824,10 +11004,12 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { case SC_S_LIFEPOTION: case SC_L_LIFEPOTION: - if( sd && --(sce->val4) >= 0 ) { + case SC_M_LIFEPOTION: + case SC_G_LIFEPOTION: + if (sd && --(sce->val4) >= 0) { // val1 < 0 = per max% | val1 > 0 = exact amount int hp = 0; - if( st->hp < st->max_hp ) + if (st->hp < st->max_hp) hp = (sce->val1 < 0) ? (int)(sd->status.max_hp * -1 * sce->val1 / 100.) : sce->val1 ; status->heal(bl, hp, 0, 2); sc_timer_next((sce->val2 * 1000) + tick, status->change_timer, bl->id, data); @@ -11421,10 +11603,9 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { if (bl->type == BL_ELEM) elemental->change_mode(BL_CAST(BL_ELEM,bl),MAX_ELESKILLTREE); break; - case SC_STOMACHACHE: if (--(sce->val4) > 0) { - status->charge(bl, 0, sce->val3); // Reduce 8 every 10 seconds. + status->charge(bl, 0, sce->val3); // Reduce 8 SP every 10 seconds. if (sd && !pc_issit(sd)) { // Force to sit every 10 seconds. pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS | STOPWALKING_FLAG_NEXTCELL); pc_stop_attack(sd); @@ -11435,6 +11616,18 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { return 0; } break; + case SC_STEAMPACK: + if (--(sce->val4) > 0) { + status->charge(bl, sce->val3, 0); // Reduce 100 HP every 10 seconds. + sc_timer_next(10000 + tick, status->change_timer, bl->id, data); + } + break; + case SC_MAGIC_CANDY: + if (--(sce->val4) > 0) { + status->charge(bl, 0, sce->val3); // Reduce 90 SP every 10 seconds. + sc_timer_next(10000 + tick, status->change_timer, bl->id, data); + } + break; case SC_LEADERSHIP: case SC_GLORYWOUNDS: case SC_SOULCOLD: diff --git a/src/map/status.h b/src/map/status.h index d44cc9bca..5996e8c2e 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -800,6 +800,32 @@ typedef enum sc_type { SC_MVPCARD_ORCHERO, SC_MVPCARD_ORCLORD, + SC_HAT_EFFECT, + SC_FLOWERSMOKE, + SC_FSTONE, // 620 + SC_HAPPINESS_STAR, + SC_MAPLE_FALLS, + SC_TIME_ACCESSORY, + SC_MAGICAL_FEATHER, + SC_BLOSSOM_FLUTTERING, + + SC_GM_BATTLE, + SC_GM_BATTLE2, + SC_2011RWC, + SC_STR_SCROLL, + SC_INT_SCROLL, // 630 + SC_STEAMPACK, + SC_MOVHASTE_POTION, + SC_MOVESLOW_POTION, + SC_BUCHEDENOEL, + SC_PHI_DEMON, + SC_PROMOTE_HEALTH_RESERCH, + SC_ENERGY_DRINK_RESERCH, + SC_MAGIC_CANDY, + SC_M_LIFEPOTION, + SC_G_LIFEPOTION, // 640 + SC_MYSTICPOWDER, + SC_MAX, //Automatically updated max, used in for's to check we are within bounds. } sc_type; @@ -995,7 +1021,7 @@ enum si_type { SI_INCSTR = 182, //SI_NOT_EXTREMITYFIST = 183, SI_CLAIRVOYANCE = 184, - //SI_MOVESLOW_POTION = 185, + SI_MOVESLOW_POTION = 185, SI_DOUBLECASTING = 186, //SI_GRAVITATION = 187, SI_OVERTHRUSTMAX = 188, @@ -1118,7 +1144,7 @@ enum si_type { SI_ARMOR_PROPERTY = 302, //SI_REUSE_LIMIT_A = 303, SI_HELLPOWER = 304, - //SI_STEAMPACK = 305, + SI_STEAMPACK = 305, //SI_REUSE_LIMIT_B = 306, //SI_REUSE_LIMIT_C = 307, //SI_REUSE_LIMIT_D = 308, @@ -1404,7 +1430,16 @@ enum si_type { SI_ODINS_POWER = 583, SI_STYLE_CHANGE = 584, SI_SONIC_CLAW_POSTDELAY = 585, - /* IDs 586 - 595 Currently Unused */ + //SI_ = 586, + //SI_ = 587, + //SI_ = 588, + //SI_ = 589, + //SI_ = 590, + //SI_ = 591, + //SI_ = 592, + //SI_ = 593, + //SI_ = 594, + //SI_ = 595, SI_SILVERVEIN_RUSH_POSTDELAY = 596, SI_MIDNIGHT_FRENZY_POSTDELAY = 597, SI_GOLDENE_FERSE = 598, @@ -1635,7 +1670,10 @@ enum si_type { //SI_MTF_RANGEATK2 = 818, //SI_MTF_ASPD2 = 819, //SI_MTF_MATK2 = 820, - /* IDs 821 - 824 Currently Unused */ + //SI_SHOW_NPCHPBAR = 821, + SI_FLOWERSMOKE = 822, + SI_FSTONE = 823, + //SI_DAILYSENDMAILCNT = 824, //SI_QSCARABA = 825, SI_LJOSALFAR = 826, //SI_PAD_READER_KNIGHT = 827, @@ -1656,18 +1694,35 @@ enum si_type { //SI_PAD_READER_GUNSLINGER = 842, //SI_PAD_READER_SUPERNOVICE = 843, //SI_ESSENCE_OF_TIME = 844, - - /* IDs 845 - 859 Currently Unused */ + //SI_MINIGAME_ROULETTE = 845, + //SI_MINIGAME_GOLD_POINT = 846, + //SI_MINIGAME_SILVER_POINT = 847, + //SI_MINIGAME_BRONZE_POINT = 848, + SI_HAPPINESS_STAR = 849, + + //SI_SUMMEREVENT01 = 850, + //SI_SUMMEREVENT02 = 851, + //SI_SUMMEREVENT03 = 852, + //SI_SUMMEREVENT04 = 853, + //SI_SUMMEREVENT05 = 854, + //SI_MINIGAME_ROULETTE_BONUS_ITEM = 855, + //SI_DRESS_UP = 856, + SI_MAPLE_FALLS = 857, + //SI_ALL_NIFLHEIM_RECALL = 858, + //SI_ = 859, //SI_MTF_MARIONETTE = 860, //SI_MTF_LUDE = 861, //SI_MTF_CRUISER = 862, SI_MERMAID_LONGING = 863, - /* IDs 864 Currently Unused */ + SI_MAGICAL_FEATHER = 864, //SI_DRACULA_CARD = 865, - /* ID 866 Currently Unused */ + //SI_ = 866, //SI_LIMIT_POWER_BOOSTER = 867, - /* IDs 868 - 871 Currently Unused */ - //SI_TIME_ACCESSORY = 872, + //SI_ = 868, + //SI_ = 869, + //SI_ = 870, + //SI_ = 871, + SI_TIME_ACCESSORY = 872, //SI_EP16_DEF = 873, //SI_NORMAL_ATKED_SP = 874, //SI_BODYSTATE_STONECURSE = 875, @@ -1690,7 +1745,7 @@ enum si_type { //SI_CHERRY_BLOSSOM_CAKE = 892, //SI_SU_STOOP = 893, //SI_CATNIPPOWDER = 894, - /* ID 895 Currently Unused */ + SI_BLOSSOM_FLUTTERING = 895, //SI_SV_ROOTTWIST = 896, //SI_ATTACK_PROPERTY_NOTHING = 897, //SI_ATTACK_PROPERTY_WATER = 898, @@ -1730,7 +1785,7 @@ enum si_type { //SI_HELM_ASIR = 931, //SI_HELM_URJ = 932, //SI_SUHIDE = 933, - /* ID 934 Currently Unused */ + //SI_ = 934, //SI_DORAM_BUF_01 = 935, //SI_DORAM_BUF_02 = 936, //SI_SPRITEMABLE = 937, diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index 59844e766..c725cdf4a 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -1846,6 +1846,8 @@ struct { struct HPMHookPoint *HP_clif_add_random_options_post; struct HPMHookPoint *HP_clif_pHotkeyRowShift_pre; struct HPMHookPoint *HP_clif_pHotkeyRowShift_post; + struct HPMHookPoint *HP_clif_dressroom_open_pre; + struct HPMHookPoint *HP_clif_dressroom_open_post; struct HPMHookPoint *HP_cmdline_init_pre; struct HPMHookPoint *HP_cmdline_init_post; struct HPMHookPoint *HP_cmdline_final_pre; @@ -4456,6 +4458,12 @@ struct { struct HPMHookPoint *HP_script_conv_str_post; struct HPMHookPoint *HP_script_rid2sd_pre; struct HPMHookPoint *HP_script_rid2sd_post; + struct HPMHookPoint *HP_script_id2sd_pre; + struct HPMHookPoint *HP_script_id2sd_post; + struct HPMHookPoint *HP_script_charid2sd_pre; + struct HPMHookPoint *HP_script_charid2sd_post; + struct HPMHookPoint *HP_script_nick2sd_pre; + struct HPMHookPoint *HP_script_nick2sd_post; struct HPMHookPoint *HP_script_detach_rid_pre; struct HPMHookPoint *HP_script_detach_rid_post; struct HPMHookPoint *HP_script_push_val_pre; @@ -7665,6 +7673,8 @@ struct { int HP_clif_add_random_options_post; int HP_clif_pHotkeyRowShift_pre; int HP_clif_pHotkeyRowShift_post; + int HP_clif_dressroom_open_pre; + int HP_clif_dressroom_open_post; int HP_cmdline_init_pre; int HP_cmdline_init_post; int HP_cmdline_final_pre; @@ -10275,6 +10285,12 @@ struct { int HP_script_conv_str_post; int HP_script_rid2sd_pre; int HP_script_rid2sd_post; + int HP_script_id2sd_pre; + int HP_script_id2sd_post; + int HP_script_charid2sd_pre; + int HP_script_charid2sd_post; + int HP_script_nick2sd_pre; + int HP_script_nick2sd_post; int HP_script_detach_rid_pre; int HP_script_detach_rid_post; int HP_script_push_val_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index bc78fe8b4..456f2985f 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -943,6 +943,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(clif->pNPCMarketPurchase, HP_clif_pNPCMarketPurchase) }, { HP_POP(clif->add_random_options, HP_clif_add_random_options) }, { HP_POP(clif->pHotkeyRowShift, HP_clif_pHotkeyRowShift) }, + { HP_POP(clif->dressroom_open, HP_clif_dressroom_open) }, /* cmdline */ { HP_POP(cmdline->init, HP_cmdline_init) }, { HP_POP(cmdline->final, HP_cmdline_final) }, @@ -2282,6 +2283,9 @@ struct HookingPointData HookingPoints[] = { { HP_POP(script->conv_num, HP_script_conv_num) }, { HP_POP(script->conv_str, HP_script_conv_str) }, { HP_POP(script->rid2sd, HP_script_rid2sd) }, + { HP_POP(script->id2sd, HP_script_id2sd) }, + { HP_POP(script->charid2sd, HP_script_charid2sd) }, + { HP_POP(script->nick2sd, HP_script_nick2sd) }, { HP_POP(script->detach_rid, HP_script_detach_rid) }, { HP_POP(script->push_val, HP_script_push_val) }, { HP_POP(script->get_val, HP_script_get_val) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 4c828dc56..ad9d96f03 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -24041,6 +24041,32 @@ void HP_clif_pHotkeyRowShift(int fd, struct map_session_data *sd) { } return; } +void HP_clif_dressroom_open(struct map_session_data *sd, int view) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_dressroom_open_pre ) { + void (*preHookFunc) (struct map_session_data *sd, int *view); + *HPMforce_return = false; + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_dressroom_open_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_dressroom_open_pre[hIndex].func; + preHookFunc(sd, &view); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.dressroom_open(sd, view); + } + if( HPMHooks.count.HP_clif_dressroom_open_post ) { + void (*postHookFunc) (struct map_session_data *sd, int *view); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_dressroom_open_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_dressroom_open_post[hIndex].func; + postHookFunc(sd, &view); + } + } + return; +} /* cmdline */ void HP_cmdline_init(void) { int hIndex = 0; @@ -59445,6 +59471,87 @@ TBL_PC* HP_script_rid2sd(struct script_state *st) { } return retVal___; } +TBL_PC* HP_script_id2sd(struct script_state *st, int account_id) { + int hIndex = 0; + TBL_PC* retVal___ = NULL; + if( HPMHooks.count.HP_script_id2sd_pre ) { + TBL_PC* (*preHookFunc) (struct script_state *st, int *account_id); + *HPMforce_return = false; + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_id2sd_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_id2sd_pre[hIndex].func; + retVal___ = preHookFunc(st, &account_id); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.id2sd(st, account_id); + } + if( HPMHooks.count.HP_script_id2sd_post ) { + TBL_PC* (*postHookFunc) (TBL_PC* retVal___, struct script_state *st, int *account_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_id2sd_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_id2sd_post[hIndex].func; + retVal___ = postHookFunc(retVal___, st, &account_id); + } + } + return retVal___; +} +TBL_PC* HP_script_charid2sd(struct script_state *st, int char_id) { + int hIndex = 0; + TBL_PC* retVal___ = NULL; + if( HPMHooks.count.HP_script_charid2sd_pre ) { + TBL_PC* (*preHookFunc) (struct script_state *st, int *char_id); + *HPMforce_return = false; + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_charid2sd_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_charid2sd_pre[hIndex].func; + retVal___ = preHookFunc(st, &char_id); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.charid2sd(st, char_id); + } + if( HPMHooks.count.HP_script_charid2sd_post ) { + TBL_PC* (*postHookFunc) (TBL_PC* retVal___, struct script_state *st, int *char_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_charid2sd_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_charid2sd_post[hIndex].func; + retVal___ = postHookFunc(retVal___, st, &char_id); + } + } + return retVal___; +} +TBL_PC* HP_script_nick2sd(struct script_state *st, const char *name) { + int hIndex = 0; + TBL_PC* retVal___ = NULL; + if( HPMHooks.count.HP_script_nick2sd_pre ) { + TBL_PC* (*preHookFunc) (struct script_state *st, const char *name); + *HPMforce_return = false; + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_nick2sd_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_nick2sd_pre[hIndex].func; + retVal___ = preHookFunc(st, name); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.nick2sd(st, name); + } + if( HPMHooks.count.HP_script_nick2sd_post ) { + TBL_PC* (*postHookFunc) (TBL_PC* retVal___, struct script_state *st, const char *name); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_nick2sd_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_nick2sd_post[hIndex].func; + retVal___ = postHookFunc(retVal___, st, name); + } + } + return retVal___; +} void HP_script_detach_rid(struct script_state *st) { int hIndex = 0; if( HPMHooks.count.HP_script_detach_rid_pre ) { |