summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/script_commands.txt27
-rw-r--r--src/map/clif.c8
-rw-r--r--src/map/clif.h2
-rw-r--r--src/map/mob.c2
-rw-r--r--src/map/script.c27
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc12
7 files changed, 44 insertions, 38 deletions
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 1737f8796..ca7ebacca 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -4507,26 +4507,17 @@ changebase(Class); // Changes player back to default sprite.
---------------------------------------
-*classchange(<view id>, <type>)
+*classchange(<view id>, <type> {, <char id>})
This command is very ancient, it's origins are clouded in mystery.
-It will send a 'display id change' packet to everyone in the immediate
-area of the NPC object, which will supposedly make the NPC look like a
-different sprite, an NPC sprite ID, or a monster ID. This effect is not
-stored anywhere and will not persist (Which is odd, cause it would be
-relatively easy to make it do so) and most importantly, will not work at
-all since this command was broken with the introduction of advanced
-classes. The code is written with the assumption that the lowest sprite
-IDs are the job sprites and the anything beyond them is monster and NPC
-sprites, but since the advanced classes rolled in, they got the ID numbers
-on the other end of the number pool where monster sprites float.
-
-As a result it is currently impossible to call this command with a valid
-view id. It will do nothing whatsoever if the view ID is below 4047.
-Getting it to run will actually just crash the client.
-
-It could be a real gem if it can be gotten to actually do what it's
-supposed to do, but this will only happen in a later Git revision.
+It will send a 'display id change' packet to player with given char ID
+or to everyone in the immediate area of the NPC object if char ID is 0 or
+not passed, which will make the NPC look like a different sprite, an NPC
+sprite ID, or a monster ID. This effect is not stored anywhere and will
+not persist.
+Note that you can't send a Job sprite ID
+
+type is not used and should always be 0.
---------------------------------------
diff --git a/src/map/clif.c b/src/map/clif.c
index 674fbba1d..6897c357a 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1352,7 +1352,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
/// 01b0 <id>.L <type>.B <value>.L
/// type:
/// unused
-void clif_class_change(struct block_list *bl, int class_, int type)
+void clif_class_change(struct block_list *bl, int class_, int type, struct map_session_data *sd)
{
nullpo_retv(bl);
@@ -1363,7 +1363,11 @@ void clif_class_change(struct block_list *bl, int class_, int type)
WBUFL(buf,2)=bl->id;
WBUFB(buf,6)=type;
WBUFL(buf,7)=class_;
- clif->send(buf,packet_len(0x1b0),bl,AREA);
+
+ if (sd == NULL)
+ clif->send(buf, packet_len(0x1b0), bl, AREA);
+ else
+ clif->send(buf, packet_len(0x1b0), &sd->bl, SELF);
}
}
diff --git a/src/map/clif.h b/src/map/clif.h
index b27adb5be..aefba5974 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -671,7 +671,7 @@ struct clif_interface {
void (*changetraplook) (struct block_list *bl,int val);
void (*refreshlook) (struct block_list *bl,int id,int type,int val,enum send_target target);
void (*sendlook) (struct block_list *bl, int id, int type, int val, int val2, enum send_target target);
- void (*class_change) (struct block_list *bl,int class_,int type);
+ void (*class_change) (struct block_list *bl,int class_,int type, struct map_session_data *sd);
void (*skill_delunit) (struct skill_unit *su);
void (*skillunit_update) (struct block_list* bl);
int (*clearunit_delayed_sub) (int tid, int64 tick, int id, intptr_t data);
diff --git a/src/map/mob.c b/src/map/mob.c
index d5932f195..74d25b805 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -2832,7 +2832,7 @@ int mob_class_change (struct mob_data *md, int class_) {
mob_stop_walking(md, STOPWALKING_FLAG_NONE);
unit->skillcastcancel(&md->bl, 0);
status->set_viewdata(&md->bl, class_);
- clif->class_change(&md->bl, md->vd->class, 1);
+ clif->class_change(&md->bl, md->vd->class, 1, NULL);
status_calc_mob(md, SCO_FIRST);
md->ud.state.speed_changed = 1; //Speed change update.
diff --git a/src/map/script.c b/src/map/script.c
index ef63697a7..30295b8dc 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -13840,15 +13840,26 @@ BUILDIN(undisguise)
* Transform a bl to another class,
* @type unused
*------------------------------------------*/
-BUILDIN(classchange) {
- int class, type;
- struct block_list *bl=map->id2bl(st->oid);
+BUILDIN(classchange)
+{
+ int class, type, target;
+ struct block_list *bl = map->id2bl(st->oid);
- if(bl==NULL) return true;
+ if (bl == NULL)
+ return true;
- class = script_getnum(st,2);
- type=script_getnum(st,3);
- clif->class_change(bl, class, type);
+ class = script_getnum(st, 2);
+ type = script_getnum(st, 3);
+ target = script_hasdata(st, 4) ? script_getnum(st, 4) : 0;
+
+ if (target > 0) {
+ struct map_session_data *sd = script->charid2sd(st, target);
+ if (sd != NULL) {
+ clif->class_change(bl, class, type, sd);
+ }
+ } else {
+ clif->class_change(bl, class, type, NULL);
+ }
return true;
}
@@ -21032,7 +21043,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getcartinventorylist,""),
BUILDIN_DEF(getskilllist,""),
BUILDIN_DEF(clearitem,""),
- BUILDIN_DEF(classchange,"ii"),
+ BUILDIN_DEF(classchange,"ii?"),
BUILDIN_DEF(misceffect,"i"),
BUILDIN_DEF(playbgm,"s"),
BUILDIN_DEF(playbgmall,"s?????"),
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index 57abf25e0..82d310832 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -974,8 +974,8 @@ typedef void (*HPMHOOK_pre_clif_refreshlook) (struct block_list **bl, int *id, i
typedef void (*HPMHOOK_post_clif_refreshlook) (struct block_list *bl, int id, int type, int val, enum send_target target);
typedef void (*HPMHOOK_pre_clif_sendlook) (struct block_list **bl, int *id, int *type, int *val, int *val2, enum send_target *target);
typedef void (*HPMHOOK_post_clif_sendlook) (struct block_list *bl, int id, int type, int val, int val2, enum send_target target);
-typedef void (*HPMHOOK_pre_clif_class_change) (struct block_list **bl, int *class_, int *type);
-typedef void (*HPMHOOK_post_clif_class_change) (struct block_list *bl, int class_, int type);
+typedef void (*HPMHOOK_pre_clif_class_change) (struct block_list **bl, int *class_, int *type, struct map_session_data **sd);
+typedef void (*HPMHOOK_post_clif_class_change) (struct block_list *bl, int class_, int type, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_skill_delunit) (struct skill_unit **su);
typedef void (*HPMHOOK_post_clif_skill_delunit) (struct skill_unit *su);
typedef void (*HPMHOOK_pre_clif_skillunit_update) (struct block_list **bl);
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 654c902d8..800fb8c76 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -7917,14 +7917,14 @@ void HP_clif_sendlook(struct block_list *bl, int id, int type, int val, int val2
}
return;
}
-void HP_clif_class_change(struct block_list *bl, int class_, int type) {
+void HP_clif_class_change(struct block_list *bl, int class_, int type, struct map_session_data *sd) {
int hIndex = 0;
if( HPMHooks.count.HP_clif_class_change_pre ) {
- void (*preHookFunc) (struct block_list **bl, int *class_, int *type);
+ void (*preHookFunc) (struct block_list **bl, int *class_, int *type, struct map_session_data **sd);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_class_change_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_clif_class_change_pre[hIndex].func;
- preHookFunc(&bl, &class_, &type);
+ preHookFunc(&bl, &class_, &type, &sd);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -7932,13 +7932,13 @@ void HP_clif_class_change(struct block_list *bl, int class_, int type) {
}
}
{
- HPMHooks.source.clif.class_change(bl, class_, type);
+ HPMHooks.source.clif.class_change(bl, class_, type, sd);
}
if( HPMHooks.count.HP_clif_class_change_post ) {
- void (*postHookFunc) (struct block_list *bl, int class_, int type);
+ void (*postHookFunc) (struct block_list *bl, int class_, int type, struct map_session_data *sd);
for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_class_change_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_clif_class_change_post[hIndex].func;
- postHookFunc(bl, class_, type);
+ postHookFunc(bl, class_, type, sd);
}
}
return;