• 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!

TFS 1.X+ How to track how he typed spell with doCreatureSay

Lopaskurwa

Active Member
Joined
Oct 6, 2017
Messages
873
Solutions
2
Reaction score
49
Hi
So i only know the basic script of doCreatureSay so i wondering how to track how he typed that command i mean tracking the caps lock example lets say you type TeST SPELL so doCreatureSay will send that same style and etc... I cant find any information about it.
 
Solution
5zWZxkT.png


I managed to do it :D
I will share my spells functions from spells.cpp that I changed to achieve this results
Code:
TalkActionResult_t Spells::playerSaySpell(Player* player, std::string& words)
{
    std::string str_words = words;

    //strip trailing spaces
    trimString(str_words);

    InstantSpell* instantSpell = getInstantSpell(str_words);
    if (!instantSpell) {
        return TALKACTION_CONTINUE;
    }

    std::string param;
    size_t spellLen = instantSpell->getWords().length();
    size_t paramLen = str_words.length() - spellLen;
    std::string paramText = str_words.substr(spellLen, paramLen);
    if (!paramText.empty() && paramText.front() == ' ') {
        size_t loc1 =...
Hey, I still don't quite understand what you want. You must explain it better with own words ^^

Anyways I managed to accomplish this
U9gZvl7.png


But it's still not perfect yet, for example the spell will always be lowercased letters but I will try fixing it or I can share what I did right now if you are ok with the spell being lowercased letters.
 
Hey, I still don't quite understand what you want. You must explain it better with own words ^^

Anyways I managed to accomplish this
U9gZvl7.png


But it's still not perfect yet, for example the spell will always be lowercased letters but I will try fixing it or I can share what I did right now if you are ok with the spell being lowercased letters.
What i want is to track caps locks and let cast the spell even when you make something like this exevo "blablalbla or ExEvo "sdlftret this is what i mean.
 
5zWZxkT.png


I managed to do it :D
I will share my spells functions from spells.cpp that I changed to achieve this results
Code:
TalkActionResult_t Spells::playerSaySpell(Player* player, std::string& words)
{
    std::string str_words = words;

    //strip trailing spaces
    trimString(str_words);

    InstantSpell* instantSpell = getInstantSpell(str_words);
    if (!instantSpell) {
        return TALKACTION_CONTINUE;
    }

    std::string param;
    size_t spellLen = instantSpell->getWords().length();
    size_t paramLen = str_words.length() - spellLen;
    std::string paramText = str_words.substr(spellLen, paramLen);
    if (!paramText.empty() && paramText.front() == ' ') {
        size_t loc1 = paramText.find('"', 1);
        if (loc1 != std::string::npos) {
            size_t loc2 = paramText.find('"', loc1 + 1);
            if (loc2 == std::string::npos) {
                loc2 = paramText.length();
            } else if (paramText.find_last_not_of(' ') != loc2) {
                return TALKACTION_CONTINUE;
            }

            param = paramText.substr(loc1 + 1, loc2 - loc1 - 1);
        } else {
            trimString(paramText);
            loc1 = paramText.find(' ', 0);
            if (loc1 == std::string::npos) {
                param = paramText;
            } else {
                return TALKACTION_CONTINUE;
            }
        }
    }


    if (instantSpell->playerCastInstant(player, param)) {
        words = str_words.substr(0, spellLen);

        if (!param.empty()) {
            words += " \"" + param.substr(0, 30);
        }

        return TALKACTION_BREAK;
    }

    return TALKACTION_FAILED;
}

in this code you have "param.substr(0, 30);"
this puts a limit to how many letters can be after the spell, I put it as 30 but you can higher it if you want.

and you need change this too
Code:
InstantSpell* Spells::getInstantSpell(const std::string& words)
{
    InstantSpell* result = nullptr;

    for (const auto& it : instants) {
        InstantSpell* instantSpell = it.second;

        const std::string& instantSpellWords = instantSpell->getWords();
        size_t spellLen = instantSpellWords.length();
        if (strncasecmp(instantSpellWords.c_str(), words.c_str(), spellLen) == 0) {
            if (!result || spellLen > result->getWords().length()) {
                result = instantSpell;
                if (words.length() == spellLen) {
                    break;
                }
            }
        }
    }

    if (result) {
        const std::string& resultWords = result->getWords();
        if (words.length() > resultWords.length()) {

            size_t spellLen = resultWords.length();
            size_t paramLen = words.length() - spellLen;
            if (paramLen < 2 || words[spellLen] != ' ') {
                return nullptr;
            }
        }
        return result;
    }
    return nullptr;
}

Just replace ur old functions with the new ones and it should work if your using TFS 1.x
 
Solution
5zWZxkT.png


I managed to do it :D
I will share my spells functions from spells.cpp that I changed to achieve this results
Code:
TalkActionResult_t Spells::playerSaySpell(Player* player, std::string& words)
{
    std::string str_words = words;

    //strip trailing spaces
    trimString(str_words);

    InstantSpell* instantSpell = getInstantSpell(str_words);
    if (!instantSpell) {
        return TALKACTION_CONTINUE;
    }

    std::string param;
    size_t spellLen = instantSpell->getWords().length();
    size_t paramLen = str_words.length() - spellLen;
    std::string paramText = str_words.substr(spellLen, paramLen);
    if (!paramText.empty() && paramText.front() == ' ') {
        size_t loc1 = paramText.find('"', 1);
        if (loc1 != std::string::npos) {
            size_t loc2 = paramText.find('"', loc1 + 1);
            if (loc2 == std::string::npos) {
                loc2 = paramText.length();
            } else if (paramText.find_last_not_of(' ') != loc2) {
                return TALKACTION_CONTINUE;
            }

            param = paramText.substr(loc1 + 1, loc2 - loc1 - 1);
        } else {
            trimString(paramText);
            loc1 = paramText.find(' ', 0);
            if (loc1 == std::string::npos) {
                param = paramText;
            } else {
                return TALKACTION_CONTINUE;
            }
        }
    }


    if (instantSpell->playerCastInstant(player, param)) {
        words = str_words.substr(0, spellLen);

        if (!param.empty()) {
            words += " \"" + param.substr(0, 30);
        }

        return TALKACTION_BREAK;
    }

    return TALKACTION_FAILED;
}

in this code you have "param.substr(0, 30);"
this puts a limit to how many letters can be after the spell, I put it as 30 but you can higher it if you want.

and you need change this too
Code:
InstantSpell* Spells::getInstantSpell(const std::string& words)
{
    InstantSpell* result = nullptr;

    for (const auto& it : instants) {
        InstantSpell* instantSpell = it.second;

        const std::string& instantSpellWords = instantSpell->getWords();
        size_t spellLen = instantSpellWords.length();
        if (strncasecmp(instantSpellWords.c_str(), words.c_str(), spellLen) == 0) {
            if (!result || spellLen > result->getWords().length()) {
                result = instantSpell;
                if (words.length() == spellLen) {
                    break;
                }
            }
        }
    }

    if (result) {
        const std::string& resultWords = result->getWords();
        if (words.length() > resultWords.length()) {

            size_t spellLen = resultWords.length();
            size_t paramLen = words.length() - spellLen;
            if (paramLen < 2 || words[spellLen] != ' ') {
                return nullptr;
            }
        }
        return result;
    }
    return nullptr;
}

Just replace ur old functions with the new ones and it should work if your using TFS 1.x
Yea compiled everything without any errors but damn probably i'm making something wrong with spell .lua because it doesnt show any text for me :D
Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_EFFECT, 28)
setCombatParam(combat, COMBAT_PARAM_AGGRESSIVE, 0)

local condition = createConditionObject(CONDITION_HASTE)
setConditionParam(condition, CONDITION_PARAM_TICKS, 42000)
setConditionFormula(condition, 1.0, -56, 1.0, -56)
setCombatCondition(combat, condition)

function onCastSpell(cid, var)
   doCombat(cid, combat, var)
   return false
end
What do you see wrong in this script that can cause not showing the text?
 
Hello sir, I guess best idea would be to go back to your old spells.cpp file and share it with us. Maybe it wasn't the exactly same as I had and it's why it's not working for you. [On my server this is working perfect]
To fix it for youself u should check on the changes I made in the post above and try do adjust ur spells.cpp in the same way. If not just post ur old spells.cpp and i can probably fix it for u when i have time!
 
Hello sir, I guess best idea would be to go back to your old spells.cpp file and share it with us. Maybe it wasn't the exactly same as I had and it's why it's not working for you. [On my server this is working perfect]
To fix it for youself u should check on the changes I made in the post above and try do adjust ur spells.cpp in the same way. If not just post ur old spells.cpp and i can probably fix it for u when i have time!
Sorry it was my bad everything works perfect. I noticed that my config.lua emoteSpells always was false thats why it doesnt worked.
 
Back
Top