From 5000a9d8875970167aef5bde50eb0fe5a7c5f7de Mon Sep 17 00:00:00 2001 From: AdamPlenty <58278560+AdamPlenty@users.noreply.github.com> Date: Mon, 18 Jan 2021 09:36:37 +0000 Subject: [PATCH] Script commands for units to send chat messages (#930) Commands send a chat message from a specific creature/player. Also accepts 'None' to have no icon. QUICK_MESSAGE([message_ID], "[message text]", [creature/playername]) DISPLAY_MESSAGE([string number], [creature/playername]) --- src/config_campaigns.h | 1 + src/gui_msgs.c | 26 ++++++++++++-- src/gui_msgs.h | 2 +- src/lvl_script.c | 77 ++++++++++++++++++++++++++++++++++++++++++ src/lvl_script.h | 3 ++ 5 files changed, 105 insertions(+), 4 deletions(-) diff --git a/src/config_campaigns.h b/src/config_campaigns.h index 32ea390138..3a76317cb0 100644 --- a/src/config_campaigns.h +++ b/src/config_campaigns.h @@ -154,6 +154,7 @@ extern struct CampaignsList mappacks_list; extern const struct NamedCommand cmpgn_map_commands[]; extern const struct NamedCommand cmpgn_map_cmnds_options[]; extern const struct NamedCommand cmpgn_map_cmnds_kind[]; +extern const struct NamedCommand cmpgn_human_player_options[]; /******************************************************************************/ TbBool load_campaign(const char *cmpgn_fname,struct GameCampaign *campgn,unsigned short flags, short fgroup); TbBool free_campaign(struct GameCampaign *campgn); diff --git a/src/gui_msgs.c b/src/gui_msgs.c index 97b220d732..b34cf0418e 100644 --- a/src/gui_msgs.c +++ b/src/gui_msgs.c @@ -22,7 +22,7 @@ #include "globals.h" #include "bflib_basics.h" #include "bflib_sprfnt.h" - +#include "creature_graphics.h" #include "gui_draw.h" #include "frontend.h" #include "game_legacy.h" @@ -30,6 +30,7 @@ #include "keeperfx.hpp" /******************************************************************************/ + void message_draw(void) { SYNCDBG(7,"Starting"); @@ -41,15 +42,34 @@ void message_draw(void) ps_units_per_px = (22 * units_per_pixel) / spr->SHeight; } int h = LbTextLineHeight(); - long x = 148 * units_per_pixel / 16; long y = 28 * units_per_pixel / 16; for (int i = 0; i < game.active_messages_count; i++) { + long x = 148 * units_per_pixel / 16; LbTextSetWindow(0, 0, MyScreenWidth, MyScreenHeight); set_flag_word(&lbDisplay.DrawFlags,Lb_TEXT_ONE_COLOR,false); LbTextDrawResized(x+32*units_per_pixel/16, y, tx_units_per_px, gameadd.messages[i].text); - draw_gui_panel_sprite_left(x, y, ps_units_per_px, 488+gameadd.messages[i].plyr_idx); + unsigned long spr_idx; + TbBool NotPlayer = ((char)gameadd.messages[i].plyr_idx < 0); + if (NotPlayer) + { + x -= (7 * units_per_pixel / 16); + y -= (20 * units_per_pixel / 16); + spr_idx = get_creature_model_graphics(((~gameadd.messages[i].plyr_idx) + 1), CGI_HandSymbol); + } + else + { + spr_idx = 488+gameadd.messages[i].plyr_idx; + } + if (gameadd.messages[i].plyr_idx != 127) + { + draw_gui_panel_sprite_left(x, y, ps_units_per_px, spr_idx); + } y += h*units_per_pixel/16; + if (NotPlayer) + { + y += (20 * units_per_pixel / 16); + } } } diff --git a/src/gui_msgs.h b/src/gui_msgs.h index 45cb123ce0..03dd6e2157 100644 --- a/src/gui_msgs.h +++ b/src/gui_msgs.h @@ -34,7 +34,7 @@ extern "C" { struct GuiMessage { // sizeof = 0x45 (69) char text[64]; -unsigned char plyr_idx; +PlayerNumber plyr_idx; unsigned long creation_turn; }; diff --git a/src/lvl_script.c b/src/lvl_script.c index 3844e69edd..9d9970a312 100644 --- a/src/lvl_script.c +++ b/src/lvl_script.c @@ -41,7 +41,9 @@ #include "config_trapdoor.h" #include "creature_states_mood.h" #include "creature_control.h" +#include "gui_msgs.h" #include "gui_soundmsgs.h" +#include "gui_topmsg.h" #include "frontmenu_ingame_tabs.h" #include "player_instances.h" #include "player_data.h" @@ -2931,6 +2933,33 @@ void command_message(const char *msgtext, unsigned char kind) SCRPTWRNLOG("Command '%s' is only supported in Dungeon Keeper Beta", cmd); } +void command_quick_message(int idx, const char *msgtext, const char *range_id) +{ + if ((idx < 0) || (idx >= QUICK_MESSAGES_COUNT)) + { + SCRPTERRLOG("Invalid information ID number (%d)", idx); + return; + } + if (strlen(msgtext) > MESSAGE_TEXT_LEN) + { + SCRPTWRNLOG("Information TEXT too long; truncating to %d characters", MESSAGE_TEXT_LEN-1); + } + if ((gameadd.quick_messages[idx][0] != '\0') && (strcmp(gameadd.quick_messages[idx],msgtext) != 0)) + { + SCRPTWRNLOG("Quick Message no %d overwritten by different text", idx); + } + strncpy(gameadd.quick_messages[idx], msgtext, MESSAGE_TEXT_LEN-1); + gameadd.quick_messages[idx][MESSAGE_TEXT_LEN-1] = '\0'; + char id = get_player_number_from_value(range_id); + command_add_value(Cmd_QUICK_MESSAGE, 0, id, idx, 0); +} + +void command_display_message(int msg_num, const char *range_id) +{ + char id = get_player_number_from_value(range_id); + command_add_value(Cmd_DISPLAY_MESSAGE, 0, id, msg_num, 0); +} + void command_swap_creature(const char *ncrt_name, const char *crtr_name) { long ncrt_id = get_rid(newcrtr_desc, ncrt_name); @@ -3505,6 +3534,12 @@ void script_add_command(const struct CommandDesc *cmd_desc, const struct ScriptL case Cmd_PRINT: command_message(scline->tp[0],80); break; + case Cmd_QUICK_MESSAGE: + command_quick_message(scline->np[0], scline->tp[1], scline->tp[2]); + break; + case Cmd_DISPLAY_MESSAGE: + command_display_message(scline->np[0], scline->tp[1]); + break; case Cmd_MESSAGE: command_message(scline->tp[0],68); break; @@ -6214,6 +6249,16 @@ void script_process_value(unsigned long var_index, unsigned long plr_range_id, l intralvl.campaign_flags[i][val4] = get_condition_value(i, val2, val3); } break; + case Cmd_QUICK_MESSAGE: + { + message_add_fmt(val2, "%s", gameadd.quick_messages[val3]); + break; + } + case Cmd_DISPLAY_MESSAGE: + { + message_add_fmt(val2, "%s", get_string(val3)); + break; + } case Cmd_SET_GAME_RULE: switch (val2) { @@ -6458,6 +6503,36 @@ void find_location_pos(long location, PlayerNumber plyr_idx, struct Coord3d *pos } SYNCDBG(15,"From %s; Location %ld, pos(%ld,%ld)",func_name, location, pos->x.stl.num, pos->y.stl.num); } + +char get_player_number_from_value(const char* txt) +{ + char id; + if (strcasecmp(txt, "None") == 0) + { + id = 127; + } + else + { + id = get_rid(player_desc, txt); + } + if (id == -1) + { + id = get_rid(cmpgn_human_player_options, txt); + if (id == -1) + { + id = get_rid(creature_desc, txt); + if (id == -1) + { + id = atoi(txt); + } + else + { + id = (~id) + 1; + } + } + } + return id; +} /******************************************************************************/ /** * Descriptions of script commands for parser. @@ -6562,6 +6637,8 @@ const struct CommandDesc command_desc[] = { {"CREATE_EFFECTS_LINE", "LLNNNN ", Cmd_CREATE_EFFECTS_LINE, &create_effects_line_check, &create_effects_line_process}, {"IF_SLAB_OWNER", "NNP ", Cmd_IF_SLAB_OWNER, NULL, NULL}, {"IF_SLAB_TYPE", "NNS ", Cmd_IF_SLAB_TYPE, NULL, NULL}, + {"QUICK_MESSAGE", "NAA ", Cmd_QUICK_MESSAGE, NULL, NULL}, + {"DISPLAY_MESSAGE", "NA ", Cmd_DISPLAY_MESSAGE, NULL, NULL}, {NULL, " ", Cmd_NONE, NULL, NULL}, }; diff --git a/src/lvl_script.h b/src/lvl_script.h index 04cadb6be3..f003203aaf 100644 --- a/src/lvl_script.h +++ b/src/lvl_script.h @@ -143,6 +143,8 @@ enum TbScriptCommands { Cmd_SET_BOX_TOOLTIP = 122, Cmd_SET_BOX_TOOLTIP_ID = 123, Cmd_CREATE_EFFECTS_LINE = 124, + Cmd_DISPLAY_MESSAGE = 125, + Cmd_QUICK_MESSAGE = 126, }; enum ScriptVariables { @@ -466,6 +468,7 @@ void process_win_and_lose_conditions(PlayerNumber plyr_idx); void script_process_new_creatures(PlayerNumber plyr_idx, long crtr_breed, long location, long copies_num, long carried_gold, long crtr_level); void process_check_new_creature_partys(void); void process_check_new_tunneller_partys(void); +char get_player_number_from_value(const char* txt); /******************************************************************************/ #ifdef __cplusplus }