diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index 78617190..217b3721 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -568,6 +568,97 @@ static cell AMX_NATIVE_CALL show_hudmessage(AMX *amx, cell *params) /* 2 param * return len; } +static cell AMX_NATIVE_CALL set_dhudmessage(AMX *amx, cell *params) /* 10 param */ +{ + g_hudset.a1 = 0; + g_hudset.a2 = 0; + g_hudset.r2 = 255; + g_hudset.g2 = 255; + g_hudset.b2 = 250; + g_hudset.r1 = static_cast(params[1]); + g_hudset.g1 = static_cast(params[2]); + g_hudset.b1 = static_cast(params[3]); + g_hudset.x = amx_ctof(params[4]); + g_hudset.y = amx_ctof(params[5]); + g_hudset.effect = params[6];; + g_hudset.fxTime = amx_ctof(params[7]); + g_hudset.holdTime = amx_ctof(params[8]); + g_hudset.fadeinTime = amx_ctof(params[9]); + g_hudset.fadeoutTime = amx_ctof(params[10]); + g_hudset.channel = -1; + + return 1; +} + +static cell AMX_NATIVE_CALL show_dhudmessage(AMX *amx, cell *params) /* 2 param */ +{ + int len = 0; + int index = params[1]; + char *message; + + if (!index) + { + for (int i = 1; i <= gpGlobals->maxClients; ++i) + { + CPlayer *pPlayer = GET_PLAYER_POINTER_I(i); + + if (pPlayer->ingame && !pPlayer->IsBot()) + { + g_langMngr.SetDefLang(i); + message = format_amxstring(amx, params, 2, len); + + if (len > 127) // Client truncates after byte 127. + { + len = 127; + + // Don't truncate a double-byte character + if (((message[len - 1] & 0xFF) >= 0xC2) && ((message[len - 1] & 0xFF) <= 0xEF)) + { + len--; + } + + message[len] = 0; + } + + UTIL_DHudMessage(pPlayer->pEdict, g_hudset, message, len); + } + } + } + else + { + if (index < 1 || index > gpGlobals->maxClients) + { + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + + if (pPlayer->ingame && !pPlayer->IsBot()) + { + g_langMngr.SetDefLang(index); + message = format_amxstring(amx, params, 2, len); + + if (len > 127) // Client truncates after byte 127. + { + len = 127; + + // Don't truncate a double-byte character + if (((message[len - 1] & 0xFF) >= 0xC2) && ((message[len - 1] & 0xFF) <= 0xEF)) + { + --len; + } + + message[len] = 0; + } + + UTIL_DHudMessage(pPlayer->pEdict, g_hudset, message, len); + } + } + + return len; +} + static cell AMX_NATIVE_CALL get_user_name(AMX *amx, cell *params) /* 3 param */ { int index = params[1]; @@ -4925,6 +5016,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] = {"set_cvar_num", set_cvar_num}, {"set_cvar_string", set_cvar_string}, {"set_fail_state", set_fail_state}, + {"set_dhudmessage", set_dhudmessage}, {"set_hudmessage", set_hudmessage}, {"set_localinfo", set_localinfo}, {"set_pcvar_flags", set_pcvar_flags}, @@ -4936,6 +5028,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] = {"set_user_info", set_user_info}, {"set_xvar_float", set_xvar_num}, {"set_xvar_num", set_xvar_num}, + {"show_dhudmessage", show_dhudmessage}, {"show_hudmessage", show_hudmessage}, {"show_menu", show_menu}, {"show_motd", show_motd}, diff --git a/amxmodx/amxmodx.h b/amxmodx/amxmodx.h index 26d092ad..04316b9b 100755 --- a/amxmodx/amxmodx.h +++ b/amxmodx/amxmodx.h @@ -140,6 +140,7 @@ void UTIL_ClientPrint(edict_t *pEntity, int msg_dest, char *msg); void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1 = NULL, const char *arg2 = NULL); void UTIL_GetFlags(char* flags, int flag); void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage); +void UTIL_DHudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage, unsigned int length); void UTIL_IntToString(int value, char *output); void UTIL_ShowMOTD(edict_t *client, char *motd, int mlen, const char *name); void UTIL_ShowMenu(edict_t* pEntity, int slots, int time, char *menu, int mlen); diff --git a/amxmodx/util.cpp b/amxmodx/util.cpp index 9236981d..ed5b7bf5 100755 --- a/amxmodx/util.cpp +++ b/amxmodx/util.cpp @@ -273,6 +273,29 @@ void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const ch MESSAGE_END(); } +void UTIL_DHudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage, unsigned int length) +{ + #define DRC_CMD_MESSAGE 6 + + if (pEntity) + MESSAGE_BEGIN(MSG_ONE_UNRELIABLE, SVC_DIRECTOR, NULL, pEntity); + else + MESSAGE_BEGIN(MSG_BROADCAST, SVC_DIRECTOR); + + WRITE_BYTE(length + 31); // message length (counting WRITE size) + WRITE_BYTE(DRC_CMD_MESSAGE); + WRITE_BYTE(textparms.effect); + WRITE_LONG(textparms.b1 + (textparms.g1 << 8) + (textparms.r1 << 16)); // pack color. + WRITE_LONG(amx_ftoc(textparms.x)); + WRITE_LONG(amx_ftoc(textparms.y)); + WRITE_LONG(amx_ftoc(textparms.fadeinTime)); + WRITE_LONG(amx_ftoc(textparms.fadeoutTime)); + WRITE_LONG(amx_ftoc(textparms.holdTime)); + WRITE_LONG(amx_ftoc(textparms.fxTime)); + WRITE_STRING(pMessage); // max length: 128. Truncated on the client. + MESSAGE_END(); +} + /* warning - buffer of msg must be longer than 190 chars! (here in AMX it is always longer) */ void UTIL_ClientPrint(edict_t *pEntity, int msg_dest, char *msg) diff --git a/plugins/include/amxmodx.inc b/plugins/include/amxmodx.inc index 99e666ae..6478ef94 100755 --- a/plugins/include/amxmodx.inc +++ b/plugins/include/amxmodx.inc @@ -179,6 +179,43 @@ native set_hudmessage(red=200, green=100, blue=0, Float:x=-1.0, Float:y=0.35, ef /* Displays HUD message to given player. */ native show_hudmessage(index,const message[],any:...); +/** + * Sets the Director HUD parameters for drawing text. + * + * These parameters are stored globally, although nothing other than this function and set_hudmessage modify them. + * You must call this function before drawing text. If you are drawing text to multiple clients, you can set the + * parameters once, since they won't be modified. However, as soon as you pass control back to other plugins, + * you must reset the parameters next time you draw. + * + * @param red The red color value. + * @param green The green color value. + * @param blue The blue color value. + * @param x The x coordinate (abscissa). From 0,0 to 1.0. -1.0 is the center. + * @param y The y coordinate (ordinate). From 0,0 to 1.0. - 1.0 is the center. + * @param effects The effect value. 0 = fade in/fade out, 1 is flickery credits, 2 is write out (training room). + * @param fxtime The duration of chosen effect (may not apply to all effects). + * @param holdtime The Number of seconds to hold the text. + * @param fadeintime The number of seconds to spend fading in. + * @param fadeoutime The number of seconds to spend fading out. + */ +native set_dhudmessage(red=200, green=100, blue=0, Float:x=-1.0, Float:y=0.35, effects=0, Float:fxtime=6.0, Float:holdtime=12.0, Float:fadeintime=0.1, Float:fadeouttime=0.2); + +/** + * Shows a Director HUD message to a client. Usually such message has a bigger letter size. + * Ideally used to show static/persistent message. + * + * Unlike classic HUD message which is channel-based, Director HUD message is stack-based. Don't expect same behavior. + * You can have up to 8 messages displatying at once. If you try more, the first will be overwritten, then second, etc. + * Each message is limited to 128 characters. This will be automatically truncated by the native. + * Due to its way for working, there is no native to clear a specific message. + * + * @param index THe client index to send the message to. Use 0 to send to all connected clients. + * @param message The message text or formatting rules. + * @param ... The message formatting parameters. + * @return On success, the formatted message length. Otherwise 0. + */ +native show_dhudmessage(index, const message[], any:...); + /* Displays menu. Keys have bit values (key 1 is (1<<0), key 5 is (1<<4) etc.). */ native show_menu(index,keys,const menu[], time = -1, const title[] = "");