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

[WIP] Events: Add Chat #1090

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
https://github.com/nwnxee/unified/compare/build8193.16...HEAD

### Added
- Creature: targeted messages can now be sent on party or dm channel with updated SendMessage()
- Events: added skippable Acquire events to ItemEvents
- Events: added skippable Disarm event to CombatEvents
- Events: added `ACTION_RESULT` to Feat/Skill/Lock events for use in the _AFTER
- Events: added Spell Interruption events to SpellEvents
- Events: added skippable Chat events
- Tweaks: `NWNX_TWEAKS_HIDE_PLAYERS_ON_CHAR_LIST`
- Tweaks: `NWNX_TWEAKS_FIX_ARMOR_DEX_BONUS_UNDER_ONE`
- Tweaks: `NWNX_TWEAKS_FIX_ITEM_NULLPTR_IN_CITEMREPOSITORY`
Expand All @@ -28,9 +30,11 @@ The following plugins were added:
- Creature: {Get|Set}WalkAnimation()
- Creature: SetAttackRollOverride()
- Creature: SetParryAllAttacks()
- Creature: SendMessage()
- Feat: SetFeatModifier()
- Object: GetCurrentAnimation()
- Player: AddCustomJournalEntry() and GetJournalEntry()
- Player: {Get|Set}ChatHearingDistance()
- Race: SetFavoredEnemyFeat()
- Util: GetScriptParamIsSet()

Expand All @@ -46,6 +50,7 @@ The following plugins were added:
- We now only allow builds with the `CMAKE_BUILD_TYPE=RelWithDebInfo` configuration. `Debug` builds produce unexpected behaviour and `Release` builds are generally unnecessary and mess with Assert functionality.

### Deprecated
- Chat: NWNX_Chat has been deprecated and handled now through Chat Events (NWNX_ON_CHAT_SEND_*), NWNX_Creature_SendMessage() and NWNX_Player_{Get|Set}ChatHearingDistance().
- Tweaks: `NWNX_TWEAKS_HIDE_DMS_ON_CHAR_LIST` has been deprecated, use `NWNX_TWEAKS_HIDE_PLAYERS_ON_CHAR_LIST` now

### Removed
Expand Down
21 changes: 21 additions & 0 deletions Core/NWScript/nwnx_consts.nss
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
/// @ingroup nwnx
/// @addtogroup consts NWNX Constants
/// @brief Provides various NWScript <-> NWNX Constants Translation Table functions
/// as well as defining shared constants for multiple plugins
/// @{
/// @file nwnx_consts.nss

/// @name Chat Channels
/// @anchor chat_channels
///
/// Constants defining the various chat channels.
/// @{
const int NWNX_CHAT_CHANNEL_PLAYER_TALK = 1;
const int NWNX_CHAT_CHANNEL_PLAYER_SHOUT = 2;
const int NWNX_CHAT_CHANNEL_PLAYER_WHISPER = 3;
const int NWNX_CHAT_CHANNEL_PLAYER_TELL = 4;
const int NWNX_CHAT_CHANNEL_SERVER_MSG = 5;
const int NWNX_CHAT_CHANNEL_PLAYER_PARTY = 6;
const int NWNX_CHAT_CHANNEL_PLAYER_DM = 14;
const int NWNX_CHAT_CHANNEL_DM_TALK = 17;
const int NWNX_CHAT_CHANNEL_DM_SHOUT = 18;
const int NWNX_CHAT_CHANNEL_DM_WHISPER = 19;
const int NWNX_CHAT_CHANNEL_DM_TELL = 20;
const int NWNX_CHAT_CHANNEL_DM_PARTY = 22;
const int NWNX_CHAT_CHANNEL_DM_DM = 30;
/// @}

/// @brief Translates ANIMATION_LOOPING_* and ANIMATION_FIREFORGET_* constants to their NWNX equivalent.
/// @param nAnimation The nwn animation constant
/// @return The NWNX equivalent of the constant
Expand Down
20 changes: 17 additions & 3 deletions Plugins/Chat/Chat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ Chat::Chat(Services::ProxyServiceList* services)
m_hearingDistances[Constants::ChatChannel::DmWhisper] = 3.0f;
m_hearingDistances[Constants::ChatChannel::PlayerWhisper] = 3.0f;
m_customHearingDistances = false;

m_hook = GetServices()->m_hooks->RequestExclusiveHook<Functions::_ZN11CNWSMessage29SendServerToPlayerChatMessageEhj10CExoStringjRKS0_>(&Chat::SendServerToPlayerChatMessage);
LOG_INFO("NWNX_Chat has been deprecated. Please use NWNX_Creature_SendMessage(), "
"NWNX_Player_{Get|Set}ChatHearingDistance() and the NWNX_ON_CHAT_SEND_* event for chat functionality.");
//m_hook = GetServices()->m_hooks->RequestExclusiveHook<Functions::_ZN11CNWSMessage29SendServerToPlayerChatMessageEhj10CExoStringjRKS0_>(&Chat::SendServerToPlayerChatMessage);
}

Chat::~Chat()
Expand Down Expand Up @@ -101,6 +102,7 @@ void Chat::SendServerToPlayerChatMessage(CNWSMessage* thisPtr, Constants::ChatCh

if (plugin.m_depth > 0 || !plugin.m_skipMessage)
{
// TODO: Only keep this functionality after deprecation period, it may make sense to just put it in Player
if (g_plugin->m_customHearingDistances)
{
auto server = Globals::AppManager()->m_pServerExoApp;
Expand Down Expand Up @@ -204,7 +206,7 @@ Events::ArgumentStack Chat::SendMessage(Events::ArgumentStack&& args)
if (playerId != Constants::PLAYERID_INVALIDID)
{
bool sentMessage = false;
CNWSMessage* messageDispatch = static_cast<CNWSMessage*>(Globals::AppManager()->m_pServerExoApp->GetNWSMessage());
auto* messageDispatch = static_cast<CNWSMessage*>(Globals::AppManager()->m_pServerExoApp->GetNWSMessage());

if (hasManualPlayerId)
{
Expand Down Expand Up @@ -236,6 +238,16 @@ Events::ArgumentStack Chat::SendMessage(Events::ArgumentStack&& args)
messageDispatch->SendServerToPlayerChat_DM_Whisper(playerId, speaker, message.c_str());
sentMessage = true;
}
else if (channel == Constants::ChatChannel::PlayerParty)
{
messageDispatch->SendServerToPlayerChat_Party(playerId, speaker, message.c_str());
sentMessage = true;
}
else if (channel == Constants::ChatChannel::DmParty)
{
messageDispatch->SendServerToPlayerChat_Party(playerId, speaker, message.c_str());
sentMessage = true;
}
}

if (!sentMessage)
Expand All @@ -249,6 +261,7 @@ Events::ArgumentStack Chat::SendMessage(Events::ArgumentStack&& args)
return Events::Arguments(retVal);
}

// TODO: Remove next six functions after deprecation period
Events::ArgumentStack Chat::RegisterChatScript(Events::ArgumentStack&& args)
{
m_chatScript = Events::ExtractArgument<std::string>(args);
Expand Down Expand Up @@ -281,6 +294,7 @@ Events::ArgumentStack Chat::GetTarget(Events::ArgumentStack&&)
return Events::Arguments(m_activeTargetObjectId);
}

// TODO Should these be moved to Player after deprecation period?
Events::ArgumentStack Chat::SetChatHearingDistance(Events::ArgumentStack&& args)
{
const auto distance = Services::Events::ExtractArgument<float>(args);
Expand Down
100 changes: 49 additions & 51 deletions Plugins/Chat/NWScript/nwnx_chat.nss
Original file line number Diff line number Diff line change
Expand Up @@ -3,65 +3,53 @@
/// @{
/// @file nwnx_chat.nss
#include "nwnx"
#include "nwnx_consts"

const string NWNX_Chat = "NWNX_Chat"; ///< @private

/// @name Chat Channels
/// @anchor chat_channels
///
/// Constants defining the various chat channels.
/// @{
const int NWNX_CHAT_CHANNEL_PLAYER_TALK = 1;
const int NWNX_CHAT_CHANNEL_PLAYER_SHOUT = 2;
const int NWNX_CHAT_CHANNEL_PLAYER_WHISPER = 3;
const int NWNX_CHAT_CHANNEL_PLAYER_TELL = 4;
const int NWNX_CHAT_CHANNEL_SERVER_MSG = 5;
const int NWNX_CHAT_CHANNEL_PLAYER_PARTY = 6;
const int NWNX_CHAT_CHANNEL_PLAYER_DM = 14;
const int NWNX_CHAT_CHANNEL_DM_TALK = 17;
const int NWNX_CHAT_CHANNEL_DM_SHOUT = 18;
const int NWNX_CHAT_CHANNEL_DM_WHISPER = 19;
const int NWNX_CHAT_CHANNEL_DM_TELL = 20;
const int NWNX_CHAT_CHANNEL_DM_PARTY = 22;
const int NWNX_CHAT_CHANNEL_DM_DM = 30;
/// @}

/// @brief Sends a chat message.
/// @remark If no target is provided, then it broadcasts to all eligible targets.
/// @param channel The @ref chat_channels "channel" to send the message.
/// @param message The message to send.
/// @param sender The sender of the message.
/// @param target The receiver of the message.
/// @return TRUE if successful, FALSE otherwise.
/// @deprecated Please use NWNX_Creature_SendMessage()
int NWNX_Chat_SendMessage(int channel, string message, object sender = OBJECT_SELF, object target = OBJECT_INVALID);

/// @brief Registers the script which receives all chat messages.
/// @note If a script was previously registered, this one will take over.
/// @param script The script name to handle the chat events.
/// @deprecated Please use the events system (NWNX_ON_CHAT_SEND_*)
void NWNX_Chat_RegisterChatScript(string script);

/// @brief Skips a chat message
/// @note Must be called from a chat or system script handler.
/// @deprecated Please use the events system (NWNX_ON_CHAT_SEND_*) and NWNX_Events_SkipEvent()
void NWNX_Chat_SkipMessage();

/// @brief Gets the chat @ref chat_channels "channel".
/// @note Must be called from a chat or system script handler.
/// @return The @ref chat_channels "channel" the message is sent.
/// @deprecated Please use the events system (NWNX_ON_CHAT_SEND_*) and NWNX_Events_GetEventData("CHANNEL")
int NWNX_Chat_GetChannel();

/// @brief Gets the message.
/// @note Must be called from a chat or system script handler.
/// @return The message sent.
/// @deprecated Please use the events system (NWNX_ON_CHAT_SEND_*) and NWNX_Events_GetEventData("MESSAGE")
string NWNX_Chat_GetMessage();

/// @brief Gets the sender of the message.
/// @note Must be called from a chat or system script handler.
/// @return The object sending the message.
/// @deprecated Please use the events system (NWNX_ON_CHAT_SEND_*) OBJECT_SELF
object NWNX_Chat_GetSender();

/// @brief Gets the target of the message.
/// @note Must be called from an chat or system script handler.
/// @return The target of the message or OBJECT_INVALID if no target.
/// @deprecated Please use the events system (NWNX_ON_CHAT_SEND_*) and NWNX_Events_GetEventData("TARGET")
object NWNX_Chat_GetTarget();

/// @brief Sets the distance with which the player hears talks or whispers.
Expand All @@ -80,79 +68,89 @@ float NWNX_Chat_GetChatHearingDistance(object listener = OBJECT_INVALID, int cha

int NWNX_Chat_SendMessage(int channel, string message, object sender = OBJECT_SELF, object target = OBJECT_INVALID)
{
WriteTimestampedLogEntry("NWNX_Chat: NWNX_Chat_SendMessage() is deprecated. Please use NWNX_Creature_SendMessage() now. Note the argument order has changed");
string sFunc = "SendMessage";
NWNX_PushArgumentObject("NWNX_Creature", sFunc, target);
NWNX_PushArgumentInt("NWNX_Creature", sFunc, channel);
NWNX_PushArgumentString("NWNX_Creature", sFunc, message);
NWNX_PushArgumentObject("NWNX_Creature", sFunc, sender);
NWNX_CallFunction("NWNX_Creature", sFunc);

NWNX_PushArgumentObject(NWNX_Chat, sFunc, target);
NWNX_PushArgumentObject(NWNX_Chat, sFunc, sender);
NWNX_PushArgumentString(NWNX_Chat, sFunc, message);
NWNX_PushArgumentInt(NWNX_Chat, sFunc, channel);
NWNX_CallFunction(NWNX_Chat, sFunc);
return NWNX_GetReturnValueInt(NWNX_Chat, sFunc);
return NWNX_GetReturnValueInt("NWNX_Creature", sFunc);
}

void NWNX_Chat_RegisterChatScript(string script)
{
string sFunc = "RegisterChatScript";
WriteTimestampedLogEntry("NWNX_Chat: RegisterChatScript() is deprecated. Please use the event system (NWNX_ON_CHAT_SEND_*)");

NWNX_PushArgumentString(NWNX_Chat, sFunc, script);
NWNX_CallFunction(NWNX_Chat, sFunc);
NWNX_PushArgumentString("NWNX_Events", "SubscribeEvent", script);
NWNX_PushArgumentString("NWNX_Events", "SubscribeEvent", "NWNX_ON_CHAT_SEND_BEFORE");
NWNX_CallFunction("NWNX_Events", "SubscribeEvent");
}

void NWNX_Chat_SkipMessage()
{
string sFunc = "SkipMessage";
WriteTimestampedLogEntry("NWNX_Chat: SkipMessage() is deprecated. Please use the event system (NWNX_ON_CHAT_SEND_*)");

NWNX_CallFunction(NWNX_Chat, sFunc);
NWNX_CallFunction("NWNX_Events", "SkipEvent");
}

int NWNX_Chat_GetChannel()
{
string sFunc = "GetChannel";
WriteTimestampedLogEntry("NWNX_Chat: GetChannel() is deprecated. Please use the event system (NWNX_ON_CHAT_SEND_*)");

NWNX_CallFunction(NWNX_Chat, sFunc);
return NWNX_GetReturnValueInt(NWNX_Chat, sFunc);
NWNX_PushArgumentString("NWNX_Events", "GetEventData", "CHANNEL");
NWNX_CallFunction("NWNX_Events", "GetEventData");
return StringToInt(NWNX_GetReturnValueString("NWNX_Events", "GetEventData"));
}

string NWNX_Chat_GetMessage()
{
string sFunc = "GetMessage";
WriteTimestampedLogEntry("NWNX_Chat: GetMessage() is deprecated. Please use the event system (NWNX_ON_CHAT_SEND_*)");

NWNX_CallFunction(NWNX_Chat, sFunc);
return NWNX_GetReturnValueString(NWNX_Chat, sFunc);
NWNX_PushArgumentString("NWNX_Events", "GetEventData", "MESSAGE");
NWNX_CallFunction("NWNX_Events", "GetEventData");
return NWNX_GetReturnValueString("NWNX_Events", "GetEventData");
}

object NWNX_Chat_GetSender()
{
string sFunc = "GetSender";
WriteTimestampedLogEntry("NWNX_Chat: GetSender() is deprecated. Please use the event system (NWNX_ON_CHAT_SEND_*)");

NWNX_CallFunction(NWNX_Chat, sFunc);
return NWNX_GetReturnValueObject(NWNX_Chat, sFunc);
NWNX_PushArgumentString("NWNX_Events", "GetEventData", "SENDER");
NWNX_CallFunction("NWNX_Events", "GetEventData");
return StringToObject(NWNX_GetReturnValueString("NWNX_Events", "GetEventData"));
}

object NWNX_Chat_GetTarget()
{
string sFunc = "GetTarget";
WriteTimestampedLogEntry("NWNX_Chat: GetTarget() is deprecated. Please use the event system (NWNX_ON_CHAT_SEND_*)");

NWNX_CallFunction(NWNX_Chat, sFunc);
return NWNX_GetReturnValueObject(NWNX_Chat, sFunc);
NWNX_PushArgumentString("NWNX_Events", "GetEventData", "TARGET");
NWNX_CallFunction("NWNX_Events", "GetEventData");
return StringToObject(NWNX_GetReturnValueString("NWNX_Events", "GetEventData"));
}

void NWNX_Chat_SetChatHearingDistance(float distance, object listener = OBJECT_INVALID, int channel = NWNX_CHAT_CHANNEL_PLAYER_TALK)
{
WriteTimestampedLogEntry("NWNX_Chat: SetChatHearingDistance() is deprecated. This function has been moved to NWNX_Player. Note the argument order has changed");

string sFunc = "SetChatHearingDistance";

NWNX_PushArgumentInt(NWNX_Chat, sFunc, channel);
NWNX_PushArgumentObject(NWNX_Chat, sFunc, listener);
NWNX_PushArgumentFloat(NWNX_Chat, sFunc, distance);
NWNX_CallFunction(NWNX_Chat, sFunc);
NWNX_PushArgumentInt("NWNX_Player", sFunc, channel);
NWNX_PushArgumentFloat("NWNX_Player", sFunc, distance);
NWNX_PushArgumentObject("NWNX_Player", sFunc, listener);
NWNX_CallFunction("NWNX_Player", sFunc);
}

float NWNX_Chat_GetChatHearingDistance(object listener = OBJECT_INVALID, int channel = NWNX_CHAT_CHANNEL_PLAYER_TALK)
{
WriteTimestampedLogEntry("NWNX_Chat: GetChatHearingDistance() is deprecated. This function has been moved to NWNX_Player. Note the argument order has changed.");

string sFunc = "GetChatHearingDistance";

NWNX_PushArgumentInt(NWNX_Chat, sFunc, channel);
NWNX_PushArgumentObject(NWNX_Chat, sFunc, listener);
NWNX_CallFunction(NWNX_Chat, sFunc);
return NWNX_GetReturnValueFloat(NWNX_Chat, sFunc);
NWNX_PushArgumentInt("NWNX_Player", sFunc, channel);
NWNX_PushArgumentObject("NWNX_Player", sFunc, listener);
NWNX_CallFunction("NWNX_Player", sFunc);
return NWNX_GetReturnValueFloat("NWNX_Player", sFunc);
}
4 changes: 3 additions & 1 deletion Plugins/Chat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

Allows chat events to be captured, skipped, and manual chat messages to be dispatched.

@note The functionality of this plugin has been deprecated and reduced to the sending of manual chat messages and altering chat distances for which players can hear. Please use the Events plugin for capturing and skipping chat messages now.

## Environment Variables

| Variable Name | Value | Notes |
| ------------- | :---: | ----- |
| `NWNX_CHAT_CHAT_SCRIPT` | string | Set the nwscript that receives all the chat messages
| `NWNX_CHAT_CHAT_SCRIPT` | string | Set the nwscript that receives all the chat messages @deprecated
Loading