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/login/account_sql.c12
-rw-r--r--src/map/atcommand.c15
-rw-r--r--src/map/clif.c190
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/intif.c30
-rw-r--r--src/map/map.h3
-rw-r--r--src/map/mapreg_sql.c12
-rw-r--r--src/map/mob.c15
-rw-r--r--src/map/npc.c2
-rw-r--r--src/map/packets.h5
-rw-r--r--src/map/packets_struct.h61
-rw-r--r--src/map/pc.c26
-rw-r--r--src/map/script.c31
-rw-r--r--src/map/script.h3
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc1
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc26
20 files changed, 313 insertions, 140 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/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 b284323fd..d90b4af55 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -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"
diff --git a/src/map/clif.c b/src/map/clif.c
index 687303e38..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 && battle_config.show_monster_hp_bar) {
+#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 && battle_config.show_monster_hp_bar) {
+#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 && battle_config.show_monster_hp_bar) {
+#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).
@@ -17476,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
@@ -18523,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 ) {
@@ -19578,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/map.h b/src/map/map.h
index bc479cdcf..d31b1c5d3 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -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]
@@ -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 d0073d01b..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.
@@ -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/npc.c b/src/map/npc.c
index 9af6de518..09e5c0f46 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -4292,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/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 59232cc7b..d697cd9f4 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -9415,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.
@@ -9423,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
@@ -9431,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;
@@ -9447,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
@@ -9490,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/script.c b/src/map/script.c
index 7a5292159..af790ccf5 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -2726,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);
@@ -3142,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;
@@ -11696,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;
}
}
@@ -11812,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;
}
}
@@ -11898,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;
}
}
@@ -18984,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));
@@ -19136,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);
@@ -19163,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;
@@ -19263,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);
@@ -19304,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);
@@ -19338,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);
@@ -19369,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);
diff --git a/src/map/script.h b/src/map/script.h
index 36b7edef3..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
};
/**
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index 92b2d4bd5..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;
@@ -7671,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;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 4a18d529d..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) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 8f6ec125b..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;