Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add script commands to generate some client <TAGS> #3300

Merged
merged 5 commits into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions doc/script_commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2612,6 +2612,79 @@ deleted.
// This would delete all elements of the array
deletearray(.@array);

---------------------------------------
//=====================================
1.1 - Message formatting commands (tags)
MishimaHaruna marked this conversation as resolved.
Show resolved Hide resolved
//=====================================
---------------------------------------

*mesnavigation("<label>", "<map>"{, <x>{, <y>{, <show_window>{, <mode>{, <services_flag>{, <monster_id>}}}}}});

Generates and returns a <NAVI> tag with the given parameters. A <NAVI> tag when written to certain windows,
such as the one from "mes" command, will create a highlighted and clickable text, which when clicked,
starts the navigation system for the specified values.

It is important to note that for most "<modes>" values, it is expected that your client has proper navigation
files which includes the target NPC/monster, or they will fail.

If the current client doesn't support NAVI tags, returns a fall back text which generally looks like:
<label> (<map_name> <x>, <y>)

Parameters:
- label: (string, required)
The visible and clickable text. (example: "Hat maker")

- map: (string, required)
Target map name. (example: "prontera")
Note: when service_flag is NAV_WINDOW_SEARCH (-222) this becomes the search string.

- x: (int, optional, defaults to 0)
Target map X position
Note: does nothing when used with modes NAV_MODE_MAP or NAV_MODE_MOB

- y: (int, optional, defaults to 0)
Target map Y position
Note: does nothing when used with modes NAV_MODE_MAP or NAV_MODE_MOB

- show_window: (bool, optional, defaults to false)
Whether to open the navigation UI (true) or not (false) when clicking the label.

- mode: (int, optional, defaults to NAV_MODE_ALL (0))
The kind of navigation being performed. This mainly affects the messages shown by the client when you reach the map.
- NAV_MODE_ALL (0): "You have reached your destination"
- NAV_MODE_MAP (1): "You have reached the target map"
- NAV_MODE_NPC (2): "You have reached the map the NPC is at" / "You have reached the target NPC"
Comment on lines +2655 to +2656
Copy link
Member Author

@guilherme-gm guilherme-gm Jun 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about making a mesmapnavi("label", "mapname") and mesnpcnavi("NPC Name"{, "label"}) which could check whether map or npc exists. But I don't remember seeing those being used in official scripts... so I am not sure if it is worth it.

- NAV_MODE_MOB (3): "You have reached the map where the monster appears"

Notes:
- NAV_MODE_NPC requires client navigation files to have a NPC in the exact position or an error is shown
- NAV_MODE_MOB requires client navigation files to have <monster_id> spawn in the given map or an error is shown.

- services_flag: (int, optional, defaults to NAV_KAFRA_AND_AIRSHIP (101))
The kinds of services that may be used when calculating the route.

The following values may be summed up:
- NAV_AIRSHIP_ONLY (1): Include airships
- NAV_SCROLL_ONLY (10): Include scrolls
- NAV_KAFRA_ONLY (100): Include kafras

Summed values:
- NAV_AIRSHIP_AND_SCROLL (11)
- NAV_KAFRA_AND_AIRSHIP (101)
- NAV_KAFRA_AND_SCROLL (110)
- NAV_ALL (111)

Special values:
- NAV_WINDOW_SEARCH (-222)
This is a special value that can't be summed with others and when used,
"map" becomes a search string in the navigation UI. And client performs a search
with the special keyword "$$DB".
It is only known to work together with mode = NAV_MODE_MOB and using monster Sprite Name
as "map".

- monster_id: (int, optional, defaults to 0)
To be used with mode = NAV_MODE_MOB. The ID of the monster being looked for.

---------------------------------------
//=====================================
1 - End of Basic-Related Commands
Expand Down
29 changes: 29 additions & 0 deletions npc/dev/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,32 @@ function script F_TestGetItemLink_FullWeapon {
return .@pass;
}

function script F_TestMesNavigation_Basic {
.@str$ = mesnavigation("Somewhere", "prt_fild08", 100, 105);

.@pass = false;
if (PACKETVER < 20111010) {
.@pass = (.@str$ == "Somewhere (prt_fild08 100, 105)");
} else {
.@pass = (.@str$ == "<NAVI>Somewhere<INFO>prt_fild08,100,105,</INFO></NAVI>");
}

return .@pass;
}

function script F_TestMesNavigation_Complete {
.@str$ = mesnavigation("Some NPC", "prt_fild08", 175, 370, true, NAV_MODE_ALL, NAV_NONE);

.@pass = false;
if (PACKETVER < 20111010) {
.@pass = (.@str$ == "Some NPC (prt_fild08 175, 370)");
} else {
.@pass = (.@str$ == "<NAVI>Some NPC<INFO>prt_fild08,175,370,0,0,1,0</INFO></NAVI>");
}

return .@pass;
}

function script HerculesSelfTestHelper {
if (.once > 0)
return .errors;
Expand Down Expand Up @@ -978,6 +1004,9 @@ function script HerculesSelfTestHelper {
callsub(OnCheck, "getitemlink: basic weapon tag", F_TestGetItemLink_BaseWeapon(), true);
callsub(OnCheck, "getitemlink: complete weapon tag", F_TestGetItemLink_FullWeapon(), true);

callsub(OnCheck, "mesnavigation: basic destination", F_TestMesNavigation_Basic(), true);
callsub(OnCheck, "mesnavigation: all params", F_TestMesNavigation_Complete(), true);

if (.errors) {
consolemes(CONSOLEMES_DEBUG, "Script engine self-test [ \033[0;31mFAILED\033[0m ]");
consolemes(CONSOLEMES_DEBUG, "**** The test was completed with " + .errors + " errors. ****");
Expand Down
36 changes: 36 additions & 0 deletions src/map/clif.c
Original file line number Diff line number Diff line change
Expand Up @@ -26126,6 +26126,41 @@ static void clif_format_itemlink(StringBuf *buf, const struct item *it)
#undef get_padded_value
}

/**
* Creates a "navigation" tag (<NAVI>) string into buf based on the given parameters.
* The resulting format and feature support is client-specific (newer clients supports more).
*
* @param buf buffer where the string will be written to
* @param label label of the navigation
* @param mapname name of the map
* @param x x coordinate
* @param y y coordinate
* @param mode navigation mode
* @param services_flag navigation services flag
* @param show_window show window flag
* @param monster_id monster id
*/
static void clif_format_navigation(StringBuf *buf, const char *label, const char *mapname, int x, int y, enum navigation_mode mode, enum navigation_service services_flag, bool show_window, int monster_id)
{
nullpo_retv(buf);
nullpo_retv(label);
nullpo_retv(mapname);

#if PACKETVER >= 20111010
StrBuf->Printf(buf, "<NAVI>%s<INFO>%s,%d,%d,", label, mapname, x, y);

if (mode == 0 && services_flag == NAV_KAFRA_AND_AIRSHIP && !show_window && monster_id == 0) {
StrBuf->Printf(buf, "</INFO></NAVI>");
return;
}

StrBuf->Printf(buf, "%d,%d,%d,%d</INFO></NAVI>", (int) mode, (int) services_flag, show_window ? 1 : 0, monster_id);
#else
// Unsupported feature, fallback to a basic text
StrBuf->Printf(buf, "%s (%s %d, %d)", label, mapname, x, y);
#endif
}

/*==========================================
* Main client packet processing function
*------------------------------------------*/
Expand Down Expand Up @@ -27498,4 +27533,5 @@ void clif_defaults(void)
clif->pAdventuterAgencyJoinResult = clif_parse_adventuterAgencyJoinResult;

clif->format_itemlink = clif_format_itemlink;
clif->format_navigation = clif_format_navigation;
}
3 changes: 3 additions & 0 deletions src/map/clif.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ enum macro_report_status;
enum grade_level;
enum grade_ui_result;
enum item_reform_status;
enum navigation_mode;
enum navigation_service;

/**
* Defines
Expand Down Expand Up @@ -963,6 +965,7 @@ struct clif_interface {
unsigned short (*decrypt_cmd) ( int cmd, struct map_session_data *sd );
/* client-specific logic */
void (*format_itemlink) (struct StringBuf *buf, const struct item *it);
void (*format_navigation) (struct StringBuf *buf, const char *label, const char *mapname, int x, int y, enum navigation_mode mode, enum navigation_service services_flag, bool show_window, int monster_id);
/* auth */
void (*authok) (struct map_session_data *sd);
void (*auth_error) (int fd, int errorCode);
Expand Down
62 changes: 62 additions & 0 deletions src/map/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -27331,6 +27331,59 @@ static BUILDIN(navigateto)
#endif
}

/**
* Common function for script commands that generates NAVI tags.
*/
static bool script_format_navigation(struct script_state *st, const char *label, const char *mapname, int x, int y, enum navigation_mode mode, enum navigation_service services_flag, bool show_window, int monster_id)
{
nullpo_retr(false, st);
nullpo_retr(false, label);
nullpo_retr(false, mapname);

const char *command_name = script->getfuncname(st);

if (mode < NAV_MODE_ALL || mode >= NAV_MODE_MAX) {
ShowError("script:%s: unknown mode (%u). See valid values for NAV_MODE_* constants\n", command_name, mode);
script_pushconststr(st, "");
return false;
}

if (monster_id != 0 && mob->db(monster_id) == NULL) {
ShowError("script:%s: unknown monster id (%d).\n", command_name, monster_id);
script_pushconststr(st, "");
return false;
}

StringBuf buf;
StrBuf->Init(&buf);

clif->format_navigation(&buf, label, mapname, x, y, mode, services_flag, show_window, monster_id);
script_pushstrcopy(st, StrBuf->Value(&buf));

StrBuf->Destroy(&buf);
return true;
}

/**
* Generates a <NAVI> tag with the given parameters (if supported by the client).
* If unsupported, returns a fall back text.
*
* mesnavigation("<label>", "<map>"{, <x>{, <y>{, <show_window>{, <mode>{, <services_flag>{, <monster_id>}}}}}})
*/
static BUILDIN(mesnavigation)
{
const char *label = script_getstr(st, 2);
const char *mapname = script_getstr(st, 3);
int x = script_hasdata(st, 4) ? script_getnum(st, 4) : 0;
int y = script_hasdata(st, 5) ? script_getnum(st, 5) : 0;
bool showWindow = script_hasdata(st, 6) ? (script_getnum(st, 6) == 1) : false;
enum navigation_mode mode = script_hasdata(st, 7) ? script_getnum(st, 7) : NAV_MODE_ALL;
enum navigation_service services = script_hasdata(st, 8) ? script_getnum(st, 8) : NAV_KAFRA_AND_AIRSHIP;
int monster_id = script_hasdata(st, 9) ? script_getnum(st, 9) : 0;

return script->format_navigation(st, label, mapname, x, y, mode, services, showWindow, monster_id);
}

static bool buildin_rodex_sendmail_sub(struct script_state *st, struct rodex_message *msg)
{
const char *sender_name, *title, *body;
Expand Down Expand Up @@ -29253,6 +29306,7 @@ static void script_parse_builtin(void)

/* Navigation */
BUILDIN_DEF(navigateto, "s??????"),
BUILDIN_DEF(mesnavigation, "ss??????"),

/* Clan System */
BUILDIN_DEF(clan_join,"i?"),
Expand Down Expand Up @@ -29494,6 +29548,12 @@ static void script_hardcoded_constants(void)
script->constdb_comment("Maximum Item Options");
script->set_constant("MAX_ITEM_OPTIONS", MAX_ITEM_OPTIONS, false, false);

script->constdb_comment("Navigation mode constants, use with *mesnavigation*");
script->set_constant("NAV_MODE_ALL", NAV_MODE_ALL, false, false);
script->set_constant("NAV_MODE_MAP", NAV_MODE_MAP, false, false);
script->set_constant("NAV_MODE_NPC", NAV_MODE_NPC, false, false);
script->set_constant("NAV_MODE_MOB", NAV_MODE_MOB, false, false);

script->constdb_comment("Navigation constants, use with *navigateto*");
script->set_constant("NAV_NONE", NAV_NONE, false, false);
script->set_constant("NAV_AIRSHIP_ONLY", NAV_AIRSHIP_ONLY, false, false);
Expand All @@ -29503,6 +29563,7 @@ static void script_hardcoded_constants(void)
script->set_constant("NAV_KAFRA_AND_AIRSHIP", NAV_KAFRA_AND_AIRSHIP, false, false);
script->set_constant("NAV_KAFRA_AND_SCROLL", NAV_KAFRA_AND_SCROLL, false, false);
script->set_constant("NAV_ALL", NAV_ALL, false, false);
script->set_constant("NAV_WINDOW_SEARCH", NAV_WINDOW_SEARCH, false, false);

script->constdb_comment("BL types");
script->set_constant("BL_PC",BL_PC,false, false);
Expand Down Expand Up @@ -30565,6 +30626,7 @@ void script_defaults(void)
script->buildin_query_sql_sub = buildin_query_sql_sub;
script->buildin_instance_warpall_sub = buildin_instance_warpall_sub;
script->buildin_mobuseskill_sub = buildin_mobuseskill_sub;
script->format_navigation = script_format_navigation;
script->buildin_rodex_sendmail_sub = buildin_rodex_sendmail_sub;
script->cleanfloor_sub = script_cleanfloor_sub;
script->run_func = run_func;
Expand Down
19 changes: 18 additions & 1 deletion src/map/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,19 @@ enum {
MF_NOSENDMAIL,
};

enum navigation_mode {
NAV_MODE_ALL = 0,
NAV_MODE_MAP = 1,
NAV_MODE_NPC = 2,
NAV_MODE_MOB = 3,
/**
* 4 is in client accepted range but it is not implemented
* So also marking it as "MAX" so we prevent code from sending bad values.
*/
NAV_MODE_UNKNOWN = 4,
NAV_MODE_MAX = 4,
};

enum navigation_service {
NAV_NONE = 0,
NAV_AIRSHIP_ONLY = 1,
Expand All @@ -365,7 +378,10 @@ enum navigation_service {
NAV_KAFRA_ONLY = 100,
NAV_KAFRA_AND_AIRSHIP = NAV_KAFRA_ONLY + NAV_AIRSHIP_ONLY, // 101
NAV_KAFRA_AND_SCROLL = NAV_KAFRA_ONLY + NAV_SCROLL_ONLY, // 110
NAV_ALL = NAV_AIRSHIP_ONLY + NAV_SCROLL_ONLY + NAV_KAFRA_ONLY // 111-255
NAV_ALL = NAV_AIRSHIP_ONLY + NAV_SCROLL_ONLY + NAV_KAFRA_ONLY, // 111-255

/** Special value that simply opens the window with a $$DB search instead of a real navigation */
NAV_WINDOW_SEARCH = -222,
};

/**
Expand Down Expand Up @@ -1080,6 +1096,7 @@ struct script_interface {
int (*buildin_query_sql_sub) (struct script_state *st, struct Sql *handle);
int (*buildin_instance_warpall_sub) (struct block_list *bl, va_list ap);
int (*buildin_mobuseskill_sub) (struct block_list *bl, va_list ap);
bool (*format_navigation) (struct script_state *st, const char *label, const char *mapname, int x, int y, enum navigation_mode mode, enum navigation_service services_flag, bool show_window, int monster_id);
bool (*buildin_rodex_sendmail_sub) (struct script_state *st, struct rodex_message *msg);
int (*cleanfloor_sub) (struct block_list *bl, va_list ap);
int (*run_func) (struct script_state *st);
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/HPMHooking/HPMHooking.Defs.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1336,6 +1336,8 @@ typedef unsigned short (*HPMHOOK_pre_clif_decrypt_cmd) (int *cmd, struct map_ses
typedef unsigned short (*HPMHOOK_post_clif_decrypt_cmd) (unsigned short retVal___, int cmd, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_format_itemlink) (struct StringBuf **buf, const struct item **it);
typedef void (*HPMHOOK_post_clif_format_itemlink) (struct StringBuf *buf, const struct item *it);
typedef void (*HPMHOOK_pre_clif_format_navigation) (struct StringBuf **buf, const char **label, const char **mapname, int *x, int *y, enum navigation_mode *mode, enum navigation_service *services_flag, bool *show_window, int *monster_id);
typedef void (*HPMHOOK_post_clif_format_navigation) (struct StringBuf *buf, const char *label, const char *mapname, int x, int y, enum navigation_mode mode, enum navigation_service services_flag, bool show_window, int monster_id);
typedef void (*HPMHOOK_pre_clif_authok) (struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_authok) (struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_auth_error) (int *fd, int *errorCode);
Expand Down Expand Up @@ -8152,6 +8154,8 @@ typedef int (*HPMHOOK_pre_script_buildin_instance_warpall_sub) (struct block_lis
typedef int (*HPMHOOK_post_script_buildin_instance_warpall_sub) (int retVal___, struct block_list *bl, va_list ap);
typedef int (*HPMHOOK_pre_script_buildin_mobuseskill_sub) (struct block_list **bl, va_list ap);
typedef int (*HPMHOOK_post_script_buildin_mobuseskill_sub) (int retVal___, struct block_list *bl, va_list ap);
typedef bool (*HPMHOOK_pre_script_format_navigation) (struct script_state **st, const char **label, const char **mapname, int *x, int *y, enum navigation_mode *mode, enum navigation_service *services_flag, bool *show_window, int *monster_id);
typedef bool (*HPMHOOK_post_script_format_navigation) (bool retVal___, struct script_state *st, const char *label, const char *mapname, int x, int y, enum navigation_mode mode, enum navigation_service services_flag, bool show_window, int monster_id);
typedef bool (*HPMHOOK_pre_script_buildin_rodex_sendmail_sub) (struct script_state **st, struct rodex_message **msg);
typedef bool (*HPMHOOK_post_script_buildin_rodex_sendmail_sub) (bool retVal___, struct script_state *st, struct rodex_message *msg);
typedef int (*HPMHOOK_pre_script_cleanfloor_sub) (struct block_list **bl, va_list ap);
Expand Down
8 changes: 8 additions & 0 deletions src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,8 @@ struct {
struct HPMHookPoint *HP_clif_decrypt_cmd_post;
struct HPMHookPoint *HP_clif_format_itemlink_pre;
struct HPMHookPoint *HP_clif_format_itemlink_post;
struct HPMHookPoint *HP_clif_format_navigation_pre;
struct HPMHookPoint *HP_clif_format_navigation_post;
struct HPMHookPoint *HP_clif_authok_pre;
struct HPMHookPoint *HP_clif_authok_post;
struct HPMHookPoint *HP_clif_auth_error_pre;
Expand Down Expand Up @@ -6080,6 +6082,8 @@ struct {
struct HPMHookPoint *HP_script_buildin_instance_warpall_sub_post;
struct HPMHookPoint *HP_script_buildin_mobuseskill_sub_pre;
struct HPMHookPoint *HP_script_buildin_mobuseskill_sub_post;
struct HPMHookPoint *HP_script_format_navigation_pre;
struct HPMHookPoint *HP_script_format_navigation_post;
struct HPMHookPoint *HP_script_buildin_rodex_sendmail_sub_pre;
struct HPMHookPoint *HP_script_buildin_rodex_sendmail_sub_post;
struct HPMHookPoint *HP_script_cleanfloor_sub_pre;
Expand Down Expand Up @@ -8271,6 +8275,8 @@ struct {
int HP_clif_decrypt_cmd_post;
int HP_clif_format_itemlink_pre;
int HP_clif_format_itemlink_post;
int HP_clif_format_navigation_pre;
int HP_clif_format_navigation_post;
int HP_clif_authok_pre;
int HP_clif_authok_post;
int HP_clif_auth_error_pre;
Expand Down Expand Up @@ -13657,6 +13663,8 @@ struct {
int HP_script_buildin_instance_warpall_sub_post;
int HP_script_buildin_mobuseskill_sub_pre;
int HP_script_buildin_mobuseskill_sub_post;
int HP_script_format_navigation_pre;
int HP_script_format_navigation_post;
int HP_script_buildin_rodex_sendmail_sub_pre;
int HP_script_buildin_rodex_sendmail_sub_post;
int HP_script_cleanfloor_sub_pre;
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->parse_cmd, HP_clif_parse_cmd) },
{ HP_POP(clif->decrypt_cmd, HP_clif_decrypt_cmd) },
{ HP_POP(clif->format_itemlink, HP_clif_format_itemlink) },
{ HP_POP(clif->format_navigation, HP_clif_format_navigation) },
{ HP_POP(clif->authok, HP_clif_authok) },
{ HP_POP(clif->auth_error, HP_clif_auth_error) },
{ HP_POP(clif->authrefuse, HP_clif_authrefuse) },
Expand Down Expand Up @@ -3113,6 +3114,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(script->buildin_query_sql_sub, HP_script_buildin_query_sql_sub) },
{ HP_POP(script->buildin_instance_warpall_sub, HP_script_buildin_instance_warpall_sub) },
{ HP_POP(script->buildin_mobuseskill_sub, HP_script_buildin_mobuseskill_sub) },
{ HP_POP(script->format_navigation, HP_script_format_navigation) },
{ HP_POP(script->buildin_rodex_sendmail_sub, HP_script_buildin_rodex_sendmail_sub) },
{ HP_POP(script->cleanfloor_sub, HP_script_cleanfloor_sub) },
{ HP_POP(script->run_func, HP_script_run_func) },
Expand Down
Loading