summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/clif.c29
-rw-r--r--src/map/npc.c17
-rw-r--r--src/map/npc.h3
-rw-r--r--src/map/script.c48
-rw-r--r--src/map/script.h2
-rw-r--r--src/map/status.c12
6 files changed, 95 insertions, 16 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 1b7d94ca9..4dc36be6d 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -293,7 +293,11 @@ unsigned char clif_bl_type(struct block_list *bl)
case BL_NPC:
vd = status->get_viewdata(bl);
nullpo_retr(CLUT_NPC, vd);
+#if PACKETVER >= 20170726
+ return CLUT_EVENT;
+#else
return pc->db_checkid(vd->class) ? CLUT_PC : CLUT_EVENT;
+#endif
case BL_PET:
vd = status->get_viewdata(bl);
nullpo_retr(CLUT_NPC, vd);
@@ -3341,17 +3345,22 @@ void clif_changelook(struct block_list *bl,int type,int val)
#if PACKETVER < 4
clif->sendlook(bl, bl->id, type, val, 0, target);
#else
- if(type == LOOK_WEAPON || type == LOOK_SHIELD) {
- nullpo_retv(vd);
- type = LOOK_WEAPON;
- val = vd->weapon;
- val2 = vd->shield;
- }
- if (clif->isdisguised(bl)) {
- clif->sendlook(bl, bl->id, type, val, val2, AREA_WOS);
- clif->sendlook(bl, -bl->id, type, val, val2, SELF);
+ if (bl->type != BL_NPC) {
+ if(type == LOOK_WEAPON || type == LOOK_SHIELD) {
+ nullpo_retv(vd);
+ type = LOOK_WEAPON;
+ val = vd->weapon;
+ val2 = vd->shield;
+ }
+ if (clif->isdisguised(bl)) {
+ clif->sendlook(bl, bl->id, type, val, val2, AREA_WOS);
+ clif->sendlook(bl, -bl->id, type, val, val2, SELF);
+ } else {
+ clif->sendlook(bl, bl->id, type, val, val2, target);
+ }
} else {
- clif->sendlook(bl, bl->id, type, val, val2, target);
+ struct npc_data *nd = BL_UCAST(BL_NPC, bl);
+ npc->refresh(nd);
}
#endif
}
diff --git a/src/map/npc.c b/src/map/npc.c
index de5335302..0702b2525 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -114,6 +114,8 @@ bool npc_db_checkid(int id)
return true;
if (id >= MAX_NPC_CLASS2_START && id < MAX_NPC_CLASS2_END) // Second range
return true;
+ if (pc->db_checkid(id))
+ return true;
// Anything else is invalid
return false;
}
@@ -2706,6 +2708,7 @@ struct npc_data *npc_create_npc(enum npc_subtype subtype, int m, int x, int y, u
nd->area_size = AREA_SIZE + 1;
nd->class_ = class_;
nd->speed = 200;
+ nd->vd.class = 0;
return nd;
}
@@ -3656,6 +3659,18 @@ void npc_setclass(struct npc_data* nd, short class_) {
clif->spawn(&nd->bl);// fade in
}
+void npc_refresh(struct npc_data* nd)
+{
+ nullpo_retv(nd);
+
+ if (map->list[nd->bl.m].users) {
+ // using here CLR_TRICKDEAD because other flags show effects.
+ // probably need use other flag or other way to refresh npc.
+ clif->clearunit_area(&nd->bl, CLR_TRICKDEAD); // fade out
+ clif->spawn(&nd->bl); // fade in
+ }
+}
+
// @commands (script based)
int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const char* message, const char* eventname)
{
@@ -4999,7 +5014,6 @@ int do_init_npc(bool minimal) {
npc_viewdb[i].class = i;
for( i = MAX_NPC_CLASS2_START; i < MAX_NPC_CLASS2_END; i++ )
npc_viewdb2[i - MAX_NPC_CLASS2_START].class = i;
-
npc->ev_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, EVENT_NAME_LENGTH);
npc->ev_label_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, NAME_LENGTH);
npc->name_db = strdb_alloc(DB_OPT_BASE, NAME_LENGTH);
@@ -5194,4 +5208,5 @@ void npc_defaults(void) {
npc->market_delfromsql = npc_market_delfromsql;
npc->market_delfromsql_sub = npc_market_delfromsql_sub;
npc->db_checkid = npc_db_checkid;
+ npc->refresh = npc_refresh;
}
diff --git a/src/map/npc.h b/src/map/npc.h
index 3bd11d536..8bb38f252 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -70,7 +70,7 @@ struct npc_parse;
struct npc_data {
struct block_list bl;
struct unit_data *ud;
- struct view_data *vd;
+ struct view_data vd;
unsigned int option;
struct npc_data *master_nd;
short class_;
@@ -309,6 +309,7 @@ struct npc_interface {
void (*market_delfromsql) (struct npc_data *nd, unsigned short index);
void (*market_delfromsql_sub) (const char *npcname, unsigned short index);
bool (*db_checkid) (const int id);
+ void (*refresh) (struct npc_data* nd);
/**
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
**/
diff --git a/src/map/script.c b/src/map/script.c
index 2d4f60f37..5773457a7 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -18217,6 +18217,8 @@ BUILDIN(setunitdata)
case UDT_INTIMACY:
case UDT_LIFETIME:
case UDT_MERC_KILLCOUNT:
+ case UDT_ROBE:
+ case UDT_BODY2:
setunitdata_check_min(4, 0);
break;
case UDT_MASTERAID:
@@ -19155,6 +19157,40 @@ BUILDIN(setunitdata)
case UDT_DMOTION:
nd->status.dmotion = (unsigned short) val;
break;
+ case UDT_SEX:
+ nd->vd.sex = (char)val;
+ npc->refresh(nd);
+ break;
+ case UDT_HAIRSTYLE:
+ clif->changelook(bl, LOOK_HAIR, val);
+ break;
+ case UDT_HAIRCOLOR:
+ clif->changelook(bl, LOOK_HAIR_COLOR, val);
+ break;
+ case UDT_HEADBOTTOM:
+ clif->changelook(bl, LOOK_HEAD_BOTTOM, val);
+ break;
+ case UDT_HEADMIDDLE:
+ clif->changelook(bl, LOOK_HEAD_MID, val);
+ break;
+ case UDT_HEADTOP:
+ clif->changelook(bl, LOOK_HEAD_TOP, val);
+ break;
+ case UDT_CLOTHCOLOR:
+ clif->changelook(bl, LOOK_CLOTHES_COLOR, val);
+ break;
+ case UDT_SHIELD:
+ clif->changelook(bl, LOOK_SHIELD, val);
+ break;
+ case UDT_WEAPON:
+ clif->changelook(bl, LOOK_WEAPON, val);
+ break;
+ case UDT_ROBE:
+ clif->changelook(bl, LOOK_ROBE, val);
+ break;
+ case UDT_BODY2:
+ clif->changelook(bl, LOOK_BODY2, val);
+ break;
default:
ShowWarning("buildin_setunitdata: Invalid data type '%s' for NPC unit.\n", udtype);
script_pushint(st, 0);
@@ -19565,6 +19601,18 @@ BUILDIN(getunitdata)
case UDT_AMOTION: script_pushint(st, nd->status.amotion); break;
case UDT_ADELAY: script_pushint(st, nd->status.adelay); break;
case UDT_DMOTION: script_pushint(st, nd->status.dmotion); break;
+ case UDT_SEX: script_pushint(st, nd->vd.sex); break;
+ case UDT_CLASS: script_pushint(st, nd->vd.class); break;
+ case UDT_HAIRSTYLE: script_pushint(st, nd->vd.hair_style); break;
+ case UDT_HAIRCOLOR: script_pushint(st, nd->vd.hair_color); break;
+ case UDT_HEADBOTTOM: script_pushint(st, nd->vd.head_bottom); break;
+ case UDT_HEADMIDDLE: script_pushint(st, nd->vd.head_mid); break;
+ case UDT_HEADTOP: script_pushint(st, nd->vd.head_top); break;
+ case UDT_CLOTHCOLOR: script_pushint(st, nd->vd.cloth_color); break;
+ case UDT_SHIELD: script_pushint(st, nd->vd.shield); break;
+ case UDT_WEAPON: script_pushint(st, nd->vd.weapon); break;
+ case UDT_ROBE: script_pushint(st, nd->vd.robe); break;
+ case UDT_BODY2: script_pushint(st, nd->vd.body_style); break;
default:
ShowWarning("buildin_getunitdata: Invalid data type '%s' for NPC unit.\n", udtype);
script_pushint(st, 0);
diff --git a/src/map/script.h b/src/map/script.h
index 283afa496..b2ab7510c 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -423,6 +423,8 @@ enum script_unit_data_types {
UDT_LIFETIME,
UDT_MERC_KILLCOUNT,
UDT_STATPOINT,
+ UDT_ROBE,
+ UDT_BODY2,
UDT_MAX
};
diff --git a/src/map/status.c b/src/map/status.c
index e0893aa36..ccd1e6b11 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -6809,7 +6809,7 @@ struct view_data *status_get_viewdata(struct block_list *bl)
case BL_PC: return &BL_UCAST(BL_PC, bl)->vd;
case BL_MOB: return BL_UCAST(BL_MOB, bl)->vd;
case BL_PET: return &BL_UCAST(BL_PET, bl)->vd;
- case BL_NPC: return BL_UCAST(BL_NPC, bl)->vd;
+ case BL_NPC: return &BL_UCAST(BL_NPC, bl)->vd;
case BL_HOM: return BL_UCAST(BL_HOM, bl)->vd;
case BL_MER: return BL_UCAST(BL_MER, bl)->vd;
case BL_ELEM: return BL_UCAST(BL_ELEM, bl)->vd;
@@ -6927,10 +6927,14 @@ void status_set_viewdata(struct block_list *bl, int class_)
case BL_NPC:
{
struct npc_data *nd = BL_UCAST(BL_NPC, bl);
- if (vd != NULL)
- nd->vd = vd;
- else
+ if (vd != NULL) {
+ memcpy(&nd->vd, vd, sizeof(struct view_data));
+ } else if (pc->db_checkid(class_)) {
+ memset(&nd->vd, 0, sizeof(struct view_data));
+ nd->vd.class = class_;
+ } else {
ShowError("status_set_viewdata (NPC): No view data for class %d (name=%s)\n", class_, nd->name);
+ }
}
break;
case BL_HOM: //[blackhole89]