From e8346ea6e4019fc98a97cbe3e0c4dad028df1652 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 2 Nov 2017 02:25:38 +0300 Subject: Allow each npc use own view_data structure. Allow npc to use player classes (for older than 20170726 npc visible as players). View_data structure can be copied from predefined view_data lists created new if npc using player type. --- src/map/clif.c | 4 ++++ src/map/npc.c | 4 +++- src/map/npc.h | 2 +- src/map/status.c | 12 ++++++++---- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 1b7d94ca9..f17ee14e6 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); diff --git a/src/map/npc.c b/src/map/npc.c index de5335302..c9edb2595 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; } @@ -4999,7 +5002,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); diff --git a/src/map/npc.h b/src/map/npc.h index 3bd11d536..68ab18820 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_; 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] -- cgit v1.2.3-70-g09d2 From ca0128cacba1117bacad99f4b5b325caa52b43d5 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 2 Nov 2017 18:13:13 +0300 Subject: Add view_data related fields to npc into setunitdata/getunitdata. --- src/map/script.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/map/script.c b/src/map/script.c index 2d4f60f37..729aa549e 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -19155,6 +19155,33 @@ BUILDIN(setunitdata) case UDT_DMOTION: nd->status.dmotion = (unsigned short) val; break; + case UDT_SEX: + nd->vd.sex = (char) val; + 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; default: ShowWarning("buildin_setunitdata: Invalid data type '%s' for NPC unit.\n", udtype); script_pushint(st, 0); @@ -19565,6 +19592,16 @@ 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; default: ShowWarning("buildin_getunitdata: Invalid data type '%s' for NPC unit.\n", udtype); script_pushint(st, 0); -- cgit v1.2.3-70-g09d2 From 497a25b19d58ace8e450614f0b6cab433a040428 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 2 Nov 2017 18:56:19 +0300 Subject: Add into setunitdata/getunitdata new options UDT_ROBE and UDT_BODY2. --- db/constants.conf | 2 ++ src/map/script.c | 10 ++++++++++ src/map/script.h | 2 ++ 3 files changed, 14 insertions(+) diff --git a/db/constants.conf b/db/constants.conf index 921acbeaf..eda877671 100644 --- a/db/constants.conf +++ b/db/constants.conf @@ -3870,4 +3870,6 @@ constants_db: { UDT_LIFETIME: 52 UDT_MERC_KILLCOUNT: 53 UDT_STATADD: 54 + UDT_ROBE: 55 + UDT_BODY2: 56 } diff --git a/src/map/script.c b/src/map/script.c index 729aa549e..bbaa5f6ed 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: @@ -19182,6 +19184,12 @@ BUILDIN(setunitdata) 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); @@ -19602,6 +19610,8 @@ BUILDIN(getunitdata) 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 }; -- cgit v1.2.3-70-g09d2 From ff898b1d949aac48c9017e89d5f7ba5e18d65870 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 2 Nov 2017 19:30:00 +0300 Subject: Refresh npc after changing fields in setunitdata. --- src/map/clif.c | 25 +++++++++++++++---------- src/map/npc.c | 13 +++++++++++++ src/map/npc.h | 1 + src/map/script.c | 3 ++- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index f17ee14e6..4dc36be6d 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -3345,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 c9edb2595..0702b2525 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -3659,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) { @@ -5196,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 68ab18820..8bb38f252 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -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 bbaa5f6ed..5773457a7 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -19158,7 +19158,8 @@ BUILDIN(setunitdata) nd->status.dmotion = (unsigned short) val; break; case UDT_SEX: - nd->vd.sex = (char) val; + nd->vd.sex = (char)val; + npc->refresh(nd); break; case UDT_HAIRSTYLE: clif->changelook(bl, LOOK_HAIR, val); -- cgit v1.2.3-70-g09d2