diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 753c667536..45435831d3 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7977,6 +7977,20 @@ Returns "Unknown" if unit is not found. --------------------------------------- +*setunittitle ,; + +Apply a <title> to the given <GID>. + +Note: This only works on non-player types. It also will only work on mobs if battle_config.show_mob_info is not enabled. + +--------------------------------------- + +*getunittitle <GID>; + +Returns the title of the given <GID>. + +--------------------------------------- + *getunitdata <GID>,<arrayname>; *setunitdata <GID>,<parameter>,<new value>; @@ -8043,6 +8057,7 @@ Parameters (indexes) for monsters are: UMOB_TARGETID UMOB_ROBE UMOB_BODY2 + UMOB_GROUP_ID ----- @@ -8087,6 +8102,7 @@ Parameter (indexes) for homunculi are: UHOM_ADELAY UHOM_DMOTION UHOM_TARGETID + UHOM_GROUP_ID ----- @@ -8128,6 +8144,7 @@ Parameter (indexes) for pets are: UPET_AMOTION UPET_ADELAY UPET_DMOTION + UPET_GROUP_ID ----- @@ -8169,6 +8186,7 @@ Parameter (indexes) for mercenaries are: UMER_ADELAY UMER_DMOTION UMER_TARGETID + UMER_GROUP_ID ----- @@ -8212,6 +8230,7 @@ Parameter (indexes) for elementals are: UELE_ADELAY UELE_DMOTION UELE_TARGETID + UELE_GROUP_ID ----- @@ -8261,6 +8280,7 @@ Parameter (indexes) for NPCs are: UNPC_ROBE UNPC_BODY2 UNPC_DEADSIT + UNPC_GROUP_ID *Notes: - *_SIZE: small (0); medium (1); large (2) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index e02c74da73..99d31c2d22 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -9644,15 +9644,14 @@ void clif_name( struct block_list* src, struct block_list *bl, send_target targe nullpo_retv( src ); nullpo_retv( bl ); - struct PACKET_ZC_ACK_REQNAMEALL packet = { 0 }; - - packet.packet_id = HEADER_ZC_ACK_REQNAMEALL; - packet.gid = bl->id; - switch( bl->type ){ case BL_PC: { - struct map_session_data *sd = (struct map_session_data *)bl; - struct party_data *p = NULL; + PACKET_ZC_ACK_REQNAMEALL packet = { 0 }; + + packet.packet_id = HEADER_ZC_ACK_REQNAMEALL; + packet.gid = bl->id; + + map_session_data *sd = (map_session_data *)bl; //Requesting your own "shadow" name. [Skotlex] if( src == bl && target == SELF && sd->disguise ){ @@ -9661,11 +9660,14 @@ void clif_name( struct block_list* src, struct block_list *bl, send_target targe if( sd->fakename[0] ) { safestrncpy( packet.name, sd->fakename, NAME_LENGTH ); - break; + clif_send( &packet, sizeof(packet), src, target ); + return; } safestrncpy( packet.name, sd->status.name, NAME_LENGTH ); + party_data *p; + if( sd->status.party_id ){ p = party_search( sd->status.party_id ); } @@ -9690,30 +9692,71 @@ void clif_name( struct block_list* src, struct block_list *bl, send_target targe #if PACKETVER_MAIN_NUM >= 20150225 || PACKETVER_RE_NUM >= 20141126 || defined( PACKETVER_ZERO ) packet.title_id = sd->status.title_id; // Title ID #endif - } - break; - //[blackhole89] - case BL_HOM: - safestrncpy( packet.name, ((TBL_HOM*)bl)->homunculus.name, NAME_LENGTH ); - break; - case BL_MER: - safestrncpy( packet.name, ((TBL_MER*)bl)->db->name, NAME_LENGTH ); - break; - case BL_PET: - safestrncpy( packet.name, ((TBL_PET*)bl)->pet.name, NAME_LENGTH ); - break; - case BL_NPC: - safestrncpy( packet.name, ((TBL_NPC*)bl)->name, NAME_LENGTH ); - break; - case BL_MOB: { - struct mob_data *md = (struct mob_data *)bl; - safestrncpy( packet.name, md->name, NAME_LENGTH ); + clif_send(&packet, sizeof(packet), src, target); + } + break; + //[blackhole89] + case BL_HOM: + case BL_MER: + case BL_PET: + case BL_NPC: + case BL_ELEM: { + PACKET_ZC_ACK_REQNAME_TITLE packet = { 0 }; + + packet.packet_id = HEADER_ZC_ACK_REQNAME_TITLE; + packet.gid = bl->id; + + switch (bl->type) { + case BL_HOM: + memcpy(packet.name, ((TBL_HOM *)bl)->homunculus.name, NAME_LENGTH); + break; + case BL_MER: + memcpy(packet.name, ((TBL_MER *)bl)->db->name, NAME_LENGTH); + break; + case BL_PET: + safestrncpy(packet.name, ((TBL_PET *)bl)->pet.name, NAME_LENGTH); + break; + case BL_NPC: + safestrncpy(packet.name, ((TBL_NPC *)bl)->name, NAME_LENGTH); + break; + case BL_ELEM: + safestrncpy(packet.name, ((TBL_ELEM *)bl)->db->name, NAME_LENGTH); + break; + } + +#if PACKETVER_MAIN_NUM >= 20180207 || PACKETVER_RE_NUM >= 20171129 || PACKETVER_ZERO_NUM >= 20171130 + unit_data *ud = unit_bl2ud(bl); + + if (ud != nullptr) { + memcpy(packet.title, ud->title, NAME_LENGTH); + packet.groupId = ud->group_id; + } +#endif + + clif_send(&packet, sizeof(packet), src, target); + } + break; + case BL_MOB: { + mob_data *md = (mob_data *)bl; if( md->guardian_data && md->guardian_data->guild_id ){ + PACKET_ZC_ACK_REQNAMEALL packet = { 0 }; + + packet.packet_id = HEADER_ZC_ACK_REQNAMEALL; + packet.gid = bl->id; + safestrncpy( packet.name, md->name, NAME_LENGTH ); safestrncpy( packet.guild_name, md->guardian_data->guild_name, NAME_LENGTH ); safestrncpy( packet.position_name, md->guardian_data->castle->castle_name, NAME_LENGTH ); + + clif_send(&packet, sizeof(packet), src, target); }else if( battle_config.show_mob_info ){ + PACKET_ZC_ACK_REQNAMEALL packet = { 0 }; + + packet.packet_id = HEADER_ZC_ACK_REQNAMEALL; + packet.gid = bl->id; + safestrncpy( packet.name, md->name, NAME_LENGTH ); + char mobhp[50], *str_p = mobhp; if( battle_config.show_mob_info&4 ){ @@ -9733,25 +9776,36 @@ void clif_name( struct block_list* src, struct block_list *bl, send_target targe *(str_p-3) = '\0'; //Remove trailing space + pipe. safestrncpy( packet.party_name, mobhp, NAME_LENGTH ); } + + clif_send(&packet, sizeof(packet), src, target); + } else { + PACKET_ZC_ACK_REQNAME_TITLE packet = { 0 }; + + packet.packet_id = HEADER_ZC_ACK_REQNAME_TITLE; + packet.gid = bl->id; + safestrncpy(packet.name, md->name, NAME_LENGTH); + +#if PACKETVER_MAIN_NUM >= 20180207 || PACKETVER_RE_NUM >= 20171129 || PACKETVER_ZERO_NUM >= 20171130 + unit_data *ud = unit_bl2ud(bl); + + if (ud != nullptr) { + memcpy(packet.title, ud->title, NAME_LENGTH); + packet.groupId = ud->group_id; + } +#endif + + clif_send(&packet, sizeof(packet), src, target); } } - break; - case BL_CHAT: //FIXME: Clients DO request this... what should be done about it? The chat's title may not fit... [Skotlex] -// safestrncpy(WBUFP(buf,6), (struct chat*)->title, NAME_LENGTH); -// break; - return; - case BL_ELEM: - safestrncpy( packet.name, ((TBL_ELEM*)bl)->db->name, NAME_LENGTH ); - break; - case BL_SKILL: - // Newer clients request this, but do not need an answer - return; - default: - ShowError("clif_name: bad type %d(%d)\n", bl->type, bl->id); - return; + break; + case BL_CHAT: + case BL_SKILL: + // Newer clients request this, but do not need an answer + return; + default: + ShowError("clif_name: bad type %d(%d)\n", bl->type, bl->id); + return; } - - clif_send( &packet, sizeof( packet ), src, target ); } /// Taekwon Jump (TK_HIGHJUMP) effect (ZC_HIGHJUMP). diff --git a/src/map/clif_packetdb.hpp b/src/map/clif_packetdb.hpp index 5caffc8c08..cbf20a8a26 100644 --- a/src/map/clif_packetdb.hpp +++ b/src/map/clif_packetdb.hpp @@ -59,7 +59,7 @@ packet(0x0092,28); packet(0x0093,2); parseable_packet(0x0094,6,clif_parse_GetCharNameRequest,2); - packet(0x0095,30); + packet( HEADER_ZC_ACK_REQNAME_TITLE, sizeof( PACKET_ZC_ACK_REQNAME_TITLE ) ); parseable_packet(0x0096,-1,clif_parse_WisMessage,2,4,28); packet(0x0097,-1); packet(0x0098,3); @@ -315,7 +315,7 @@ packet(0x0192,24); parseable_packet(0x0193,6,clif_parse_SolveCharName,2); packet(0x0194,30); - packet(0x0195,102); + packet( HEADER_ZC_ACK_REQNAMEALL, sizeof( struct PACKET_ZC_ACK_REQNAMEALL ) ); packet(0x0196,9); parseable_packet(0x0197,4,clif_parse_ResetChar,2); parseable_packet(0x0198,8,clif_parse_GMChangeMapType,2,4,6); @@ -2294,7 +2294,6 @@ // Title System parseable_packet(0x0A2E,6,clif_parse_change_title,0); // CZ_REQ_CHANGE_TITLE packet(0x0A2F,7); // ZC_ACK_CHANGE_TITLE - packet(0x0A30,106); // ZC_ACK_REQNAMEALL2 // Quest UI packet(0x08FE,-1); // ZC_HUNTING_QUEST_INFO diff --git a/src/map/script.cpp b/src/map/script.cpp index b042153729..5a79697e5f 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -17786,6 +17786,7 @@ BUILDIN_FUNC(getunitdata) getunitdata_sub(UMOB_TARGETID, md->target_id); getunitdata_sub(UMOB_ROBE, md->vd->robe); getunitdata_sub(UMOB_BODY2, md->vd->body_style); + getunitdata_sub(UMOB_GROUP_ID, md->ud.group_id); break; case BL_HOM: @@ -17833,6 +17834,7 @@ BUILDIN_FUNC(getunitdata) getunitdata_sub(UHOM_ADELAY, hd->battle_status.adelay); getunitdata_sub(UHOM_DMOTION, hd->battle_status.dmotion); getunitdata_sub(UHOM_TARGETID, hd->ud.target); + getunitdata_sub(UHOM_GROUP_ID, hd->ud.group_id); break; case BL_PET: @@ -17877,6 +17879,7 @@ BUILDIN_FUNC(getunitdata) getunitdata_sub(UPET_AMOTION, pd->status.amotion); getunitdata_sub(UPET_ADELAY, pd->status.adelay); getunitdata_sub(UPET_DMOTION, pd->status.dmotion); + getunitdata_sub(UPET_GROUP_ID, pd->ud.group_id); break; case BL_MER: @@ -17921,6 +17924,7 @@ BUILDIN_FUNC(getunitdata) getunitdata_sub(UMER_ADELAY, mc->base_status.adelay); getunitdata_sub(UMER_DMOTION, mc->base_status.dmotion); getunitdata_sub(UMER_TARGETID, mc->ud.target); + getunitdata_sub(UMER_GROUP_ID, mc->ud.group_id); break; case BL_ELEM: @@ -17967,6 +17971,7 @@ BUILDIN_FUNC(getunitdata) getunitdata_sub(UELE_ADELAY, ed->base_status.adelay); getunitdata_sub(UELE_DMOTION, ed->base_status.dmotion); getunitdata_sub(UELE_TARGETID, ed->ud.target); + getunitdata_sub(UELE_GROUP_ID, ed->ud.group_id); break; case BL_NPC: @@ -18019,6 +18024,7 @@ BUILDIN_FUNC(getunitdata) getunitdata_sub(UNPC_ROBE, nd->vd.robe); getunitdata_sub(UNPC_BODY2, nd->vd.body_style); getunitdata_sub(UNPC_DEADSIT, nd->vd.dead_sit); + getunitdata_sub(UNPC_GROUP_ID, nd->ud.group_id); break; default: @@ -18180,6 +18186,7 @@ BUILDIN_FUNC(setunitdata) } case UMOB_ROBE: clif_changelook(bl, LOOK_ROBE, (unsigned short)value); break; case UMOB_BODY2: clif_changelook(bl, LOOK_BODY2, (unsigned short)value); break; + case UMOB_GROUP_ID: md->ud.group_id = value; unit_refresh(bl); break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_MOB.\n", type); return SCRIPT_CMD_FAILURE; @@ -18242,6 +18249,7 @@ BUILDIN_FUNC(setunitdata) unit_attack(&hd->bl, target->id, 1); break; } + case UHOM_GROUP_ID: hd->ud.group_id = value; unit_refresh(bl); break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_HOM.\n", type); return SCRIPT_CMD_FAILURE; @@ -18293,6 +18301,7 @@ BUILDIN_FUNC(setunitdata) case UPET_AMOTION: pd->status.amotion = (short)value; break; case UPET_ADELAY: pd->status.adelay = (short)value; break; case UPET_DMOTION: pd->status.dmotion = (short)value; break; + case UPET_GROUP_ID: pd->ud.group_id = value; unit_refresh(bl); break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_PET.\n", type); return SCRIPT_CMD_FAILURE; @@ -18350,6 +18359,7 @@ BUILDIN_FUNC(setunitdata) unit_attack(&mc->bl, target->id, 1); break; } + case UMER_GROUP_ID: mc->ud.group_id = value; unit_refresh(bl); break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_MER.\n", type); return SCRIPT_CMD_FAILURE; @@ -18412,6 +18422,7 @@ BUILDIN_FUNC(setunitdata) unit_attack(&ed->bl, target->id, 1); break; } + case UELE_GROUP_ID: ed->ud.group_id = value; unit_refresh(bl); break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_ELEM.\n", type); return SCRIPT_CMD_FAILURE; @@ -18470,6 +18481,7 @@ BUILDIN_FUNC(setunitdata) case UNPC_ROBE: clif_changelook(bl, LOOK_ROBE, (unsigned short)value); break; case UNPC_BODY2: clif_changelook(bl, LOOK_BODY2, (unsigned short)value); break; case UNPC_DEADSIT: nd->vd.dead_sit = (char)value; unit_refresh(bl); break; + case UNPC_GROUP_ID: nd->ud.group_id = value; unit_refresh(bl); break; default: ShowError("buildin_setunitdata: Unknown data identifier %d for BL_NPC.\n", type); return SCRIPT_CMD_FAILURE; @@ -18578,6 +18590,57 @@ BUILDIN_FUNC(setunitname) return SCRIPT_CMD_SUCCESS; } +/** + * Sets a unit's title. + * setunittitle <GID>,<title>; + */ +BUILDIN_FUNC(setunittitle) +{ + int gid = script_getnum(st, 2); + block_list *bl = map_id2bl(gid); + + if (bl == nullptr) { + ShowWarning("buildin_setunittitle: Unable to find object with given game ID %d!\n", gid); + return SCRIPT_CMD_FAILURE; + } + + unit_data *ud = unit_bl2ud(bl); + + if (ud == nullptr) { + ShowWarning("buildin_setunittitle: Unable to find unit_data for given game ID %d!\n", gid); + return SCRIPT_CMD_FAILURE; + } + + safestrncpy(ud->title, script_getstr(st, 3), NAME_LENGTH); + clif_name_area(bl); + return SCRIPT_CMD_SUCCESS; +} + +/** + * Gets a unit's title. + * getunittitle <GID>; + */ +BUILDIN_FUNC(getunittitle) +{ + int gid = script_getnum(st, 2); + block_list *bl = map_id2bl(gid); + + if (bl == nullptr) { + ShowWarning("buildin_getunittitle: Unable to find object with given game ID %d!\n", gid); + return SCRIPT_CMD_FAILURE; + } + + unit_data *ud = unit_bl2ud(bl); + + if (ud == nullptr) { + ShowWarning("buildin_getunittitle: Unable to find unit_data for given game ID %d!\n", gid); + return SCRIPT_CMD_FAILURE; + } + + script_pushstrcopy(st, ud->title); + return SCRIPT_CMD_SUCCESS; +} + /// Makes the unit walk to target position or map. /// Returns if it was successful. /// @@ -25118,6 +25181,8 @@ struct script_function buildin_func[] = { BUILDIN_DEF(getunittype,"i"), BUILDIN_DEF(getunitname,"i"), BUILDIN_DEF(setunitname,"is"), + BUILDIN_DEF(setunittitle,"is"), + BUILDIN_DEF(getunittitle,"i"), BUILDIN_DEF(getunitdata,"i*"), BUILDIN_DEF(setunitdata,"iii"), BUILDIN_DEF(unitwalk,"iii?"), diff --git a/src/map/script.hpp b/src/map/script.hpp index b52cebd440..7c1663f109 100644 --- a/src/map/script.hpp +++ b/src/map/script.hpp @@ -478,6 +478,7 @@ enum unitdata_mobtypes { UMOB_TARGETID, UMOB_ROBE, UMOB_BODY2, + UMOB_GROUP_ID, }; enum unitdata_homuntypes { @@ -521,6 +522,7 @@ enum unitdata_homuntypes { UHOM_ADELAY, UHOM_DMOTION, UHOM_TARGETID, + UHOM_GROUP_ID, }; enum unitdata_pettypes { @@ -561,6 +563,7 @@ enum unitdata_pettypes { UPET_AMOTION, UPET_ADELAY, UPET_DMOTION, + UPET_GROUP_ID, }; enum unitdata_merctypes { @@ -601,6 +604,7 @@ enum unitdata_merctypes { UMER_ADELAY, UMER_DMOTION, UMER_TARGETID, + UMER_GROUP_ID, }; enum unitdata_elemtypes { @@ -643,6 +647,7 @@ enum unitdata_elemtypes { UELE_ADELAY, UELE_DMOTION, UELE_TARGETID, + UELE_GROUP_ID, }; enum unitdata_npctypes { @@ -691,6 +696,7 @@ enum unitdata_npctypes { UNPC_ROBE, UNPC_BODY2, UNPC_DEADSIT, + UNPC_GROUP_ID, }; enum navigation_service { diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index bb702d269d..66a1090919 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -4147,6 +4147,7 @@ export_constant(UMOB_TARGETID); export_constant(UMOB_ROBE); export_constant(UMOB_BODY2); + export_constant(UMOB_GROUP_ID); /* unit control - homunculus */ export_constant(UHOM_SIZE); @@ -4189,6 +4190,7 @@ export_constant(UHOM_ADELAY); export_constant(UHOM_DMOTION); export_constant(UHOM_TARGETID); + export_constant(UHOM_GROUP_ID); /* unit control - pet */ export_constant(UPET_SIZE); @@ -4228,6 +4230,7 @@ export_constant(UPET_AMOTION); export_constant(UPET_ADELAY); export_constant(UPET_DMOTION); + export_constant(UPET_GROUP_ID); /* unit control - mercenary */ export_constant(UMER_SIZE); @@ -4267,6 +4270,7 @@ export_constant(UMER_ADELAY); export_constant(UMER_DMOTION); export_constant(UMER_TARGETID); + export_constant(UMER_GROUP_ID); /* unit control - elemental */ export_constant(UELE_SIZE); @@ -4308,6 +4312,7 @@ export_constant(UELE_ADELAY); export_constant(UELE_DMOTION); export_constant(UELE_TARGETID); + export_constant(UELE_GROUP_ID); /* unit control - NPC */ export_deprecated_constant3("UNPC_DISPLAY", UNPC_CLASS, "UNPC_CLASS"); @@ -4356,6 +4361,7 @@ export_constant(UNPC_ROBE); export_constant(UNPC_BODY2); export_constant(UNPC_DEADSIT); + export_constant(UNPC_GROUP_ID); export_constant(NAV_NONE); export_constant(NAV_AIRSHIP_ONLY); diff --git a/src/map/unit.hpp b/src/map/unit.hpp index 3c1cf17d42..f2b718f156 100644 --- a/src/map/unit.hpp +++ b/src/map/unit.hpp @@ -59,6 +59,8 @@ struct unit_data { unsigned blockedskill : 1; } state; char walk_done_event[EVENT_NAME_LENGTH]; + char title[NAME_LENGTH]; + int32 group_id; }; struct view_data {