• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

C++ Loot Channel System

maas

New Member
Joined
Nov 23, 2008
Messages
20
Reaction score
2
Guys im using a loot channel system that was made by one moderator of otland.

that do not works in my tfs 1.3

HELP PLEASE!

data/chatchannels/chatchannels.xml
Code:
<channel id="9" name="Loot" public="1" script="loot.lua" />

data/chatchannels/scripts/loot.lua
Code:
function onSpeak(player, type, message)
    return false
end

sources/const.h
below
Code:
#define CHANNEL_PARTY 0x01

add
Code:
#define CHANNEL_LOOT 0x09

sources/monsters.cpp
below the two instances of
Code:
if (owner->getParty()) {
    owner->getParty()->broadcastPartyLoot(ss.str());
} else {
    owner->sendTextMessage(MESSAGE_INFO_DESCR, ss.str());
}

add
Code:
owner->sendChannelMessage("", ss.str(), TALKTYPE_CHANNEL_Y, CHANNEL_LOOT);

For the party members:
sources/party.cpp
Go to
Code:
void Party::broadcastPartyLoot(const std::string& loot)
{
    leader->sendTextMessage(MESSAGE_INFO_DESCR, loot);
    for (Player* member : memberList) {
        member->sendTextMessage(MESSAGE_INFO_DESCR, loot);
    }
}

Below
Code:
member->sendTextMessage(MESSAGE_INFO_DESCR, loot);

Add
Code:
member->sendChannelMessage("", loot, TALKTYPE_CHANNEL_Y, CHANNEL_LOOT);


NO HAVE CONSOLE ERRORS, JUST DO NOT WORK, DONT SEND ANY MESSAGE IN THE LOOT CHANNEL.
 
its very easy, you just need to create a custom channel at chatchannels.xml and add this:

Lua:
sendChannelMessage(your_channel_id_here, TALKTYPE_CHANNEL_O, text)

after line 25 here and after line 34

So this events/scripts, script right ? :)

It has to look like this ?

Lua:
local ec = EventCallback

ec.onDropLoot = function(self, corpse)
    if configManager.getNumber(configKeys.RATE_LOOT) == 0 then
        return
    end

    local player = Player(corpse:getCorpseOwner())
    local mType = self:getType()
    if not player or player:getStamina() > 840 then
        local monsterLoot = mType:getLoot()
        for i = 1, #monsterLoot do
            local item = corpse:createLootItem(monsterLoot[i])
            if not item then
                print('[Warning] DropLoot:', 'Could not add loot item to corpse.')
            end
        end

        if player then
            local text = ("Loot of %s: %s"):format(mType:getNameDescription(), corpse:getContentDescription())
            local party = player:getParty()
            if party then
                party:broadcastPartyLoot(text)
            else
                player:sendTextMessage(MESSAGE_INFO_DESCR, text)
                sendChannelMessage(your_channel_id_here, TALKTYPE_CHANNEL_O, text)
            end
        end
    else
        local text = ("Loot of %s: nothing (due to low stamina)"):format(mType:getNameDescription())
        local party = player:getParty()
        if party then
            party:broadcastPartyLoot(text)
        else
            sendChannelMessage(your_channel_id_here, TALKTYPE_CHANNEL_O, text)
            player:sendTextMessage(MESSAGE_INFO_DESCR, text)
        end
    end
end

ec:register()
 
So this events/scripts, script right ? :)

It has to look like this ?

Lua:
local ec = EventCallback

ec.onDropLoot = function(self, corpse)
    if configManager.getNumber(configKeys.RATE_LOOT) == 0 then
        return
    end

    local player = Player(corpse:getCorpseOwner())
    local mType = self:getType()
    if not player or player:getStamina() > 840 then
        local monsterLoot = mType:getLoot()
        for i = 1, #monsterLoot do
            local item = corpse:createLootItem(monsterLoot[i])
            if not item then
                print('[Warning] DropLoot:', 'Could not add loot item to corpse.')
            end
        end

        if player then
            local text = ("Loot of %s: %s"):format(mType:getNameDescription(), corpse:getContentDescription())
            local party = player:getParty()
            if party then
                party:broadcastPartyLoot(text)
            else
                player:sendTextMessage(MESSAGE_INFO_DESCR, text)
                sendChannelMessage(your_channel_id_here, TALKTYPE_CHANNEL_O, text)
            end
        end
    else
        local text = ("Loot of %s: nothing (due to low stamina)"):format(mType:getNameDescription())
        local party = player:getParty()
        if party then
            party:broadcastPartyLoot(text)
        else
            sendChannelMessage(your_channel_id_here, TALKTYPE_CHANNEL_O, text)
            player:sendTextMessage(MESSAGE_INFO_DESCR, text)
        end
    end
end

ec:register()

Yes, but change your_channel_id_here to the actual channel ID you've created in chatchannels.xml as @Evil Puncker said.
 
its very easy, you just need to create a custom channel at chatchannels.xml and add this:

Lua:
sendChannelMessage(your_channel_id_here, TALKTYPE_CHANNEL_O, text)

after line 25 here and after line 34
That sends the loot messages to all participants of the channel. Maybe it can be fixed in a lua code that is getting refered to in chatchannels.xml, I'm still noob. But this is my solution:

Lua:
                doPlayerSendChannelMessage(player, player, text, TALKTYPE_CHANNEL_O, your_channel_id_here)
The xml is just

XML:
<channel id="9" name="Loot" public="1" script="loot.lua" />

and the lua is (to prevent speaking in the channel)
Lua:
function onSpeak(player, type, message)
    return
end

It's an ugly solution, because the channel itself is still global, so you still get the "player joined the channel." messages. But since there was no answer to this before, I posted what I could come up with. Hopefully it could help someone else.

Add that piece of code after line 25 and after line 34

I couldn't get the party messages to work. I'll update my post if I fix it, but I don't care as much about the party function. I think the broadcast message is enough personally.
 
Last edited:
That sends the loot messages to all participants of the channel. Maybe it can be fixed in a lua code that is getting refered to in chatchannels.xml, I'm still noob. But this is my solution:

Lua:
                doPlayerSendChannelMessage(player, player, text, TALKTYPE_CHANNEL_O, your_channel_id_here)
The xml is just

XML:
<channel id="9" name="Loot" public="1" script="loot.lua" />

and the lua is (to prevent speaking in the channel)
Lua:
function onSpeak(player, type, message)
    return
end

It's an ugly solution, because the channel itself is still global, so you still get the "player joined the channel." messages. But since there was no answer to this before, I posted what I could come up with. Hopefully it could help someone else.

Add that piece of code after line 25 and after line 34

I couldn't get the party messages to work. I'll update my post if I fix it, but I don't care as much about the party function. I think the broadcast message is enough personally.

In chatchannels.xml, there is a public attribute for each channel. Disabling the public attribute will solve your issue.
 
In chatchannels.xml, there is a public attribute for each channel. Disabling the public attribute will solve your issue.
Oh. In that case there is something wrong with the public attribute on my TFS 1.4, because sendChannelMessage(your_channel_id_here, TALKTYPE_CHANNEL_O, text) always shows for all players. I need to use doPlayerSendChannelMessage(player, player, text, TALKTYPE_CHANNEL_O, your_channel_id_here)

nope.png


*edit I just realized that it's probably not wrong on my end, because why would both gamemaster and tutor channels be private channels? Link to chatchannels.xml on GitHub
 

Attachments

  • joining channel still shows.png
    joining channel still shows.png
    2 MB · Views: 53 · VirusTotal
Last edited:
Oh. In that case there is something wrong with the public attribute on my TFS 1.4, because sendChannelMessage(your_channel_id_here, TALKTYPE_CHANNEL_O, text) always shows for all players. I need to use doPlayerSendChannelMessage(player, player, text, TALKTYPE_CHANNEL_O, your_channel_id_here)

View attachment 63858


*edit I just realized that it's probably not wrong on my end, because why would both gamemaster and tutor channels be private channels? Link to chatchannels.xml on GitHub

@krafttomten Good point, after seeing what you wrote, it seems the public attribute means just anyone can view/open the channel and not just a local/global attribute.

I'm sure the solution @Sarah Wesker is the best option. She knows her stuff. @Lbtg
 
This is how it is done to send a private message on a specific channel of a player

Lua:
player:sendTextMessage(type, text, channelId)
Is there any advantage to using player:sendTextMessage instead of using doPlayerSendChannelMessage? Because I cannot get player:sendTextMessage to work, and I don't know why I should bother when doPlayerSendChannelMessage works just fine..

I thought I was clear about this before, but doPlayerSendChannelMessage works, no problem. I didn't post here because I had a problem with my code. But I noticed there was a problem with the solution posted above. Then I saw that there was like 50 billion unsolved threads about this issue, so I figured I could try to help out :rolleyes:

edit*

I made it work with party too using this code:

Lua:
            if party then
                party:broadcastPartyLoot(text)
                for _, member in ipairs(getPartyMembers(player)) do
                    doPlayerSendChannelMessage(member, player, text, TALKTYPE_CHANNEL_O, 9)
                end
            end

just replace line 22 and 23 with this code
 
Last edited:
For anyone that will look for some answers in the future. TFS 1.4.2, and probably most of 1.X

  1. Make sure that you have public="1" in chatchannels.xml, just to avoid "Player joined the channel"
    XML:
    <channel id="9" name="Loot" public="1" script="loot.lua" />
  2. In order for the message to appear correctly in your loot channel, in data/scripts/eventcallbacks/monster/default_onDropLoot.lua under
    Lua:
    player:sendTextMessage(MESSAGE_LOOT, text)
    put
    Lua:
    player:sendChannelMessage("", text, TALKTYPE_CHANNEL_O, 9) --9 is the channel ID, yours might be different
    You need to do this twice in that file
  3. Your script in chatchannels/scripts/loot.lua can look like posted above me, so:
    Lua:
    function onSpeak(player, type, message)
        return false
    end
  4. If you want the channel to be opened when the player logs in, then in data/creaturescripts/scripts/login.lua add
    Lua:
    player:openChannel(9)
    somewhere inside the function, before
    Lua:
    return true
  5. And lastly, message to everyone in the party, go to lib/core/paty.lua and make sure you got the lines 3 and 9 from the script below, or just copy the whole script:
    Lua:
    function Party.broadcastPartyLoot(self, text)
        self:getLeader():sendTextMessage(MESSAGE_INFO_DESCR, text)
        self:getLeader():sendChannelMessage("", text, TALKTYPE_CHANNEL_O, 9)
        local membersList = self:getMembers()
        for i = 1, #membersList do
            local player = membersList[i]
            if player then
                player:sendTextMessage(MESSAGE_INFO_DESCR, text)
                player:sendChannelMessage("", text, TALKTYPE_CHANNEL_O, 9)
            end
        end
    end

And now everything should work correctly. Hope that saves some time.
 
For anyone that will look for some answers in the future. TFS 1.4.2, and probably most of 1.X

  1. Make sure that you have public="1" in chatchannels.xml, just to avoid "Player joined the channel"
    XML:
    <channel id="9" name="Loot" public="1" script="loot.lua" />
  2. In order for the message to appear correctly in your loot channel, in data/scripts/eventcallbacks/monster/default_onDropLoot.lua under
    Lua:
    player:sendTextMessage(MESSAGE_LOOT, text)
    put
    Lua:
    player:sendChannelMessage("", text, TALKTYPE_CHANNEL_O, 9) --9 is the channel ID, yours might be different
    You need to do this twice in that file
  3. Your script in chatchannels/scripts/loot.lua can look like posted above me, so:
    Lua:
    function onSpeak(player, type, message)
        return false
    end
  4. If you want the channel to be opened when the player logs in, then in data/creaturescripts/scripts/login.lua add
    Lua:
    player:openChannel(9)
    somewhere inside the function, before
    Lua:
    return true
  5. And lastly, message to everyone in the party, go to lib/core/paty.lua and make sure you got the lines 3 and 9 from the script below, or just copy the whole script:
    Lua:
    function Party.broadcastPartyLoot(self, text)
        self:getLeader():sendTextMessage(MESSAGE_INFO_DESCR, text)
        self:getLeader():sendChannelMessage("", text, TALKTYPE_CHANNEL_O, 9)
        local membersList = self:getMembers()
        for i = 1, #membersList do
            local player = membersList[i]
            if player then
                player:sendTextMessage(MESSAGE_INFO_DESCR, text)
                player:sendChannelMessage("", text, TALKTYPE_CHANNEL_O, 9)
            end
        end
    end

And now everything should work correctly. Hope that saves some time.

This should work, I have tested it for you. Enjoy!
 
Back
Top