summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c2
-rw-r--r--src/char/inter.c12
-rw-r--r--src/common/mmo.h2
-rw-r--r--src/common/socket.c6
-rw-r--r--src/login/account_sql.c12
-rw-r--r--src/map/atcommand.c21
-rw-r--r--src/map/battle.c56
-rw-r--r--src/map/clif.c224
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/intif.c30
-rw-r--r--src/map/itemdb.h2
-rw-r--r--src/map/map.h23
-rw-r--r--src/map/mapreg_sql.c12
-rw-r--r--src/map/mob.c47
-rw-r--r--src/map/mob.h6
-rw-r--r--src/map/npc.c9
-rw-r--r--src/map/npc.h2
-rw-r--r--src/map/packets.h5
-rw-r--r--src/map/packets_struct.h61
-rw-r--r--src/map/pc.c70
-rw-r--r--src/map/pc.h2
-rw-r--r--src/map/script.c753
-rw-r--r--src/map/script.h6
-rw-r--r--src/map/skill.c51
-rw-r--r--src/map/status.c737
-rw-r--r--src/map/status.h79
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc16
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc107
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 ) {