PDA

View Full Version : Trouble with Languages



Valarian
November 20th, 2007, 10:08
Another attempt by me to get to grips with the Lua scripts. Without much success so far.

I'm trying to add in a slash listener on the Chat Window that will allow players and the GM to add a language to their message. The idea is that, eventually, the option will check each player's language list and display the message text only if they have the language being spoken.

The idea is that the following slash command can be used:

/language [language] [message]
/l [language] [message]

I've modified the chatmanager.lua script with the following code, unfortunately it's not working as planned. Even at this stage.
Problem: It works fine for a single player, but I'm having problems with player to player message passing. When more than one player is connected, the message is not received by the other players and the GM gets a number of messages equal to the number of players connected. Am I able to use the commands I'm using from the player side? If not, is there a way to make the GM act as a message hub to distribute the messages? I want to do something similar to the /mood command, but with the addition of making the message text blank if the language is not spoken by the character.
Question: I'm can't find how to get hold of the character sheet entries for the players to check the languages. There doesn't seem to be anything that returns me a top-level database node for a named user. How can I reference the languagelist within the charsheet_main.xml file to loop through the available languages for each player?

Any guidance from more experienced Lua users would be appreciated. Help!

chatmanager.lua


-- IMK - Language Processing
function processLanguage(params)
local msg = {};
local sender = {};

if User.isHost() then
sender, isgm = GmIdentityManager.getCurrent();
if isgm then
msg.font = "dmfont";
else
msg.font = "npcchatfont";
end
else
sender = User.getIdentityLabel();
msg.font = "chatitalicfont";
end

if control then
local spacepos = string.find(params, " ", 1, true);
if spacepos then
local language = string.sub(params, 1, spacepos-1);
local message = string.sub(params, spacepos+1);

msg.text = message;
if sender then
for k, v in ipairs(User.getAllActiveIdentities()) do
user = User.getIdentityOwner(v);
if user then
msg.sender = sender .. " <speaks in " .. language .. ">";
control.deliverMessage(msg, user);
end
end

msg.sender = sender .. " <in " .. language .. ">";
control.addMessage(msg);
else
msg.sender = "<could not find sender>";
control.addMessage(msg);
end

else
msg.font = "systemfont";
msg.text = "Usage: /language [language] [message]";
control.addMessage(msg);
end
end

return;
end
-- End Language Processing

-- Initialization
function onInit()
registerSlashHandler("/language", processLanguage); -- IMK - Language Processing
registerSlashHandler("/whisper", processWhisper);
registerSlashHandler("/die", processDie);
end


charsheet_main.xml


<windowlist name="languagelist">
<anchored>
<to>languageframe</to>
<position>over</position>
<offset>-12,-9</offset>
<top>
<parent>languageframe</parent>
<offset>25</offset>
</top>
</anchored>
<datasource>.languagelist</datasource>
<class>charsheet_languagelistitem</class>
<allowcreate />
<script>
function onSortCompare(w1, w2)
if w1.name.getValue() == "" then
return true;
elseif w2.name.getValue() == "" then
return false;
end

return w1.name.getValue() &gt; w2.name.getValue();
end

function onClickDown(button, x, y)
if not getNextWindow(nil) then
createWindow().name.setFocus();
return true;
end
end
</script>
</windowlist>

Dachannien
November 20th, 2007, 22:34
Here's how I would do it:

In your / command handler, make sure you check to see if User.isHost(). If the user isn't the host (i.e., the server), just have it deliver the chat message once. Don't let it do the language check on the client side, because you won't be able to get the database entries for the other characters anyway when you get around to adding that part.

You may need to modify the chat message in some way to provide a keyword that the server can find so that it knows that this is a special "language-specific" chat rather than a normal one. The way I handled this with another ruleset mod was to put the speaker's name as part of the message's "text" field, and then change the message's "sender" field to a uniform keyword that can later be recognized.

Doing it this way would mean that the speaker would end up receiving their own message back if you didn't parse the chat message to check for their character name. Of course, this may be a good thing - if you format the chat text right, and you don't put an addMessage on the client's / command handler, then the clients can use the server-delivered message as "confirmation" that the message was delivered.

On the server, you need to have a handler for the onReceiveMessage() event. This should go in the chat_chat.lua file, since that file is attached to the chatwindow object. This function should also check to see if User.isHost() because you only want the server screwing around with the message.

It should then check to see if the message's "sender" field is the special indicator that says this is a language-specific message. If it's not (meaning it's a normal chat message), have the function return false immediately, which will let FG handle it in the default manner (dispatching the message to all the clients).

If it is a language-specific message, then it should run through the active identity list, fetch the corresponding DB node (I think other folks have done this and know more about it than I do), compare against the language list, and determine what message ("X says Y" or "X says something you don't understand") to dispatch to a particular client. Use deliverMessage to send these messages, and you may need to add an addMessage on the server to let the DM know what happened. The function should then return true so that the message isn't processed as a normal chat message.

If I wrote this confusingly (which I probably did), let me know if you have any questions :)

Valarian
November 21st, 2007, 22:25
Thanks, the principle sounds as if I need to do it using the host as a hub for the messages from the client. What you've said makes sense. From what you've told me here, I don't think what I am trying to do is possible from the client side. I'll have to give this method a go instead. Thanks again for your help.

Dachannien
November 22nd, 2007, 04:46
Sure thing. Good luck! :)

Hamish
November 22nd, 2007, 09:13
It is possible to grant users permissions to parts of another PCs character sheet. I did it here (https://www.fantasygrounds.com/forums/showthread.php?t=7511) for example (look at the onIdentityActivation function in characterlist.lua). This is for a custom branch of the character sheet node (not shown in the UI) named "init" that I create, but you could do the same for the languages spoken.
That way, you should be able to do it all on the client side.