Archmage
April 25th, 2008, 05:29
I've made what I think is a fairly workable Player to Player whispering system, which also includes GM review. I've seen lots of requests for such a thing, but no actual implementations (maybe I'm just not looking hard enough).
This has gone through about 12 hours of development and testing, and I haven't found any serious problems yet, but since this is the first release I'm considering it to be in a "beta" stage. So use at your own risk.
I'm attaching the modified Lua files, so if you are currently using the base d20 ruleset, you can just replace the existing files with those in the .zip file. If you've got other changes to your ruleset in either chatmanager.lua or chat_chat.lua, here's how to add this one.
1) Remove or comment out the processWhisper(params) function in your chatmanager.lua script
2) Copy and Paste the following code in its place.
-- Called from: chat_chat.onReceiveMessage()
function deliverWhisper(params)
local whisper = {};
local sepIndex = 0;
local recipient = "";
local sender = "";
-- parse sender string
sepIndex = string.find(tostring(params.sender), "¦");
recipient = string.sub(params.sender,4,sepIndex-1);
sender = string.sub(params.sender,sepIndex+1,string.len(par ams.sender)-1);
whisper.sender = "[w] " .. sender;
whisper.text = params.text;
whisper.font = "msgfont";
control.deliverMessage(whisper, recipient);
-- Convert username to label
local reciever = User.getCurrentIdentity(recipient);
reciever = User.getIdentityLabel(reciever);
local msg = {};
msg.text = "[w] " .. tostring(sender) .. " -> " .. reciever .. ": " .. params.text;
msg.font = "msgfont";
ChatManager.addMessage(msg);
end
function processWhisper(params)
local msg = {};
msg.font = "msgfont";
local spacepos = string.find(params, " ", 1, true);
if spacepos then
local recipient = string.sub(params, 1, spacepos-1);
local originalrecipient = recipient;
local message = string.sub(params, spacepos+1);
-- Find user
local user = nil;
for k, v in ipairs(User.getAllActiveIdentities()) do
local label = User.getIdentityLabel(v);
if string.lower(label) == string.lower(originalrecipient) then
-- Direct match
user = User.getIdentityOwner(v);
if user then
recipient = label;
break;
end
end
end
if user then
msg.text = message;
if User.isHost() then
msg.sender = "[w] GM";
control.deliverMessage(msg, user);
msg.sender = "[w] -> " .. recipient;
control.addMessage(msg);
else
--Use "<w>" as special tag for whispers. Gets picked up by
-- onRecieveMessage() in chat_chat.lua;
msg.sender = "<w>" .. user .. "¦" .. User.getIdentityLabel();
ChatManager.deliverMessage(msg, "");
msg.sender = "[w] -> " .. recipient;
control.addMessage(msg);
end
return;
end
if User.isHost() then
msg.font = "systemfont";
msg.text = "Recipient not found \rUsage: /w [recipient] [message]";
control.addMessage(msg);
else
ChatManager.processWhisperGM(params);
end
return;
else
ChatManager.processWhisperGM(params);
end
end
function processWhisperGM(params)
local msg = {};
msg.font = "msgfont";
if not User.isHost() then
msg.sender = "[w] " .. User.getIdentityLabel();
msg.text = params;
control.deliverMessage(msg, "");
msg.sender = "[w] -> GM";
control.addMessage(msg);
end
return;
end
-- end P2P whisper mod
3) Also in chatmanager.lua, add the following lines to the onInit() function
registerSlashHandler("/w", processWhisper);
registerSlashHandler("/wg", processWhisperGM);
4) In chat_chat.lua, add the following code at the bottom of the file. If you already have an onReceiveMessage(msg) function in your chat_chat.lua script (from some other ruleset or mod), simply add the bold lines to the top of the function.
function onReceiveMessage(msg)
if string.find(msg.sender, "<w>") == 1 then
ChatManager.deliverWhisper(msg);
return true;
end
return false;
end
Usage instructions
As the GM
If you are the host (aka GM), whispering works basically like it always did. Type /w [recipient] [message] to send the message to the specified recipient. They will see "[w] GM: message text" in their chat window.
Whenever a player sends a whisper to another player, you will see a chat message something like [w] Cat -> Dog: What's up. The sender is always listed first, and then the recipient, followed by the message.
As a player
If you are a client (aka a player), whispering to another player works much like the GM's whisper command. Type /w [recipient] [message] to send a message to the specified recipient. If you do not specify a valid recipient, the whisper will be sent to the GM.
For example:
If player Cat types /w Dog What's up. Dog will receive a whisper that says [w] Cat: What's up.
If Cat types /w What's up. The GM will see [w] Cat: What's up. This is because "What's" is not a valid recipient name.
Players should use the /wg command if they wish to whisper the GM, even though the normal whisper command will work. This is because if the first word of your message to the GM happens to be a valid recipient name, the /w command will send the message to that recipient instead of the GM. The /wg command always sends to the GM.
Important note
The auto-fill function for the recipient name no longer works. You can still type a partial match for the recipient name and then press tab to auto-complete the name. If the command does not specify a full valid character name, then the message will be sent to the GM.
For example:
Under the normal d20 ruleset, you could type /whisper D What's up, and your message would be sent to Dog (assuming Dog was the only valid character whose name starts with D). Because of the way this mod works, you must now type the "D" then press the tab key to auto-complete the name before you type the rest of the message, otherwise the message will go to the GM.
If anybody finds any repeatable problems, please let me know.
This has gone through about 12 hours of development and testing, and I haven't found any serious problems yet, but since this is the first release I'm considering it to be in a "beta" stage. So use at your own risk.
I'm attaching the modified Lua files, so if you are currently using the base d20 ruleset, you can just replace the existing files with those in the .zip file. If you've got other changes to your ruleset in either chatmanager.lua or chat_chat.lua, here's how to add this one.
1) Remove or comment out the processWhisper(params) function in your chatmanager.lua script
2) Copy and Paste the following code in its place.
-- Called from: chat_chat.onReceiveMessage()
function deliverWhisper(params)
local whisper = {};
local sepIndex = 0;
local recipient = "";
local sender = "";
-- parse sender string
sepIndex = string.find(tostring(params.sender), "¦");
recipient = string.sub(params.sender,4,sepIndex-1);
sender = string.sub(params.sender,sepIndex+1,string.len(par ams.sender)-1);
whisper.sender = "[w] " .. sender;
whisper.text = params.text;
whisper.font = "msgfont";
control.deliverMessage(whisper, recipient);
-- Convert username to label
local reciever = User.getCurrentIdentity(recipient);
reciever = User.getIdentityLabel(reciever);
local msg = {};
msg.text = "[w] " .. tostring(sender) .. " -> " .. reciever .. ": " .. params.text;
msg.font = "msgfont";
ChatManager.addMessage(msg);
end
function processWhisper(params)
local msg = {};
msg.font = "msgfont";
local spacepos = string.find(params, " ", 1, true);
if spacepos then
local recipient = string.sub(params, 1, spacepos-1);
local originalrecipient = recipient;
local message = string.sub(params, spacepos+1);
-- Find user
local user = nil;
for k, v in ipairs(User.getAllActiveIdentities()) do
local label = User.getIdentityLabel(v);
if string.lower(label) == string.lower(originalrecipient) then
-- Direct match
user = User.getIdentityOwner(v);
if user then
recipient = label;
break;
end
end
end
if user then
msg.text = message;
if User.isHost() then
msg.sender = "[w] GM";
control.deliverMessage(msg, user);
msg.sender = "[w] -> " .. recipient;
control.addMessage(msg);
else
--Use "<w>" as special tag for whispers. Gets picked up by
-- onRecieveMessage() in chat_chat.lua;
msg.sender = "<w>" .. user .. "¦" .. User.getIdentityLabel();
ChatManager.deliverMessage(msg, "");
msg.sender = "[w] -> " .. recipient;
control.addMessage(msg);
end
return;
end
if User.isHost() then
msg.font = "systemfont";
msg.text = "Recipient not found \rUsage: /w [recipient] [message]";
control.addMessage(msg);
else
ChatManager.processWhisperGM(params);
end
return;
else
ChatManager.processWhisperGM(params);
end
end
function processWhisperGM(params)
local msg = {};
msg.font = "msgfont";
if not User.isHost() then
msg.sender = "[w] " .. User.getIdentityLabel();
msg.text = params;
control.deliverMessage(msg, "");
msg.sender = "[w] -> GM";
control.addMessage(msg);
end
return;
end
-- end P2P whisper mod
3) Also in chatmanager.lua, add the following lines to the onInit() function
registerSlashHandler("/w", processWhisper);
registerSlashHandler("/wg", processWhisperGM);
4) In chat_chat.lua, add the following code at the bottom of the file. If you already have an onReceiveMessage(msg) function in your chat_chat.lua script (from some other ruleset or mod), simply add the bold lines to the top of the function.
function onReceiveMessage(msg)
if string.find(msg.sender, "<w>") == 1 then
ChatManager.deliverWhisper(msg);
return true;
end
return false;
end
Usage instructions
As the GM
If you are the host (aka GM), whispering works basically like it always did. Type /w [recipient] [message] to send the message to the specified recipient. They will see "[w] GM: message text" in their chat window.
Whenever a player sends a whisper to another player, you will see a chat message something like [w] Cat -> Dog: What's up. The sender is always listed first, and then the recipient, followed by the message.
As a player
If you are a client (aka a player), whispering to another player works much like the GM's whisper command. Type /w [recipient] [message] to send a message to the specified recipient. If you do not specify a valid recipient, the whisper will be sent to the GM.
For example:
If player Cat types /w Dog What's up. Dog will receive a whisper that says [w] Cat: What's up.
If Cat types /w What's up. The GM will see [w] Cat: What's up. This is because "What's" is not a valid recipient name.
Players should use the /wg command if they wish to whisper the GM, even though the normal whisper command will work. This is because if the first word of your message to the GM happens to be a valid recipient name, the /w command will send the message to that recipient instead of the GM. The /wg command always sends to the GM.
Important note
The auto-fill function for the recipient name no longer works. You can still type a partial match for the recipient name and then press tab to auto-complete the name. If the command does not specify a full valid character name, then the message will be sent to the GM.
For example:
Under the normal d20 ruleset, you could type /whisper D What's up, and your message would be sent to Dog (assuming Dog was the only valid character whose name starts with D). Because of the way this mod works, you must now type the "D" then press the tab key to auto-complete the name before you type the rest of the message, otherwise the message will go to the GM.
If anybody finds any repeatable problems, please let me know.