• 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 0.X Sources GetStorage. (Critical)

DukeeH

Active Member
Joined
Dec 6, 2010
Messages
550
Solutions
3
Reaction score
39
Hello, after some search I think that it isn't possible to make critical/dodge perfect by onstatschange using 0.3.7/otx2.

Problem: StatsChange Defenses (absorbPercentAll / armor)

So I'm trying to do it by sources by myself, using tfs default crit system part, because I don't use it, I got where to change, and what to do, but I don't know any c++ syntax or anything.

I got something like:
Code:
    double maxDamage = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
    std::string valor;
    player->getStorage(48901,valor);
    int32_t value = atoi(valor.c_str());
    if(value*5 >= random_range(1, 1000))
    {
        maxDamage = std::pow(maxDamage, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
        player->sendCritical();
    }

From what I've search, getstorage returns a string (don't know what it means) so I found this way to make int and do the rest of the thing.

Basically:
Storage 48901 = x% critical chance
It should work for any weapon and spells, but If i manage to fix this code, I can adapt for everything.

I know it would give errors, but still, i've just tried something and put everything together so it would be better than come here and ask for someone to do everything.

Errors from script above (it was a first test):
Code:
1>  weapons.cpp
1>..\weapons.cpp(364): error C2664: 'bool Creature::getStorage(const std::string &,std::string &) const': cannot convert argument 1 from 'int' to 'const std::string &'
1>  ..\weapons.cpp(364): note: Reason: cannot convert from 'int' to 'const std::string'
1>  ..\weapons.cpp(364): note: No constructor could take the source type, or constructor overload resolution was ambiguous
1>..\weapons.cpp(627): error C2039: 'String': is not a member of 'std'
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\iomanip(18): note: see declaration of 'std'
1>..\weapons.cpp(627): error C2065: 'String': undeclared identifier
1>..\weapons.cpp(627): error C2146: syntax error: missing ';' before identifier 'valor'
1>..\weapons.cpp(627): error C2065: 'valor': undeclared identifier
1>..\weapons.cpp(628): error C2065: 'valor': undeclared identifier
1>..\weapons.cpp(629): error C2065: 'valor': undeclared identifier
1>..\weapons.cpp(629): error C2228: left of '.c_str' must have class/struct/union
1>  ..\weapons.cpp(629): note: type is 'unknown-type'

Thanks.
 
Last edited:
getstorage returns a string (don't know what it means).
String is a data type, where a variable holds "text" - just like this. Examples could be:
"text", "something", 'anything else' etc.
int is a data type, where a variable holds a number. Examples could be:
1, 2, 50, 90, 150.
There are more variable types, subtypes etc, but we're not going to focus on them right now.
If you're interested, you can start with variable types here for example C++ Variable Types

Please note how the string is saved with quotation marks when the integer is without.

Going towards your problem:
It seems like you're mixing both of them. And this is not allowed, at least not in C++.
that being said, for computer, variables
variableStr = "1";
variableInt = 1;
are way different than a human's brain might think.

I know very little about TFS 0.X, but with joint forces, I believe we can solve this.
At first,
Creature::getStorage(const std::string &,std::string &)
This tells you, that line player->getStorage(48901,valor); should receive const "string","string", but you give it int, "string", instead.

I'd adwise to change it to player->getStorage("48901",valor);

But I think this code has way more errors than this one. And my post doesn't bring you any closer.
To continue, could you please describe what's "valor", and why it does not have value at this point? Is it passed to function?
 
I need to get the value on storage 48901, I've saw some exemples and I don't get how to get the value of the key storage, so the examples I saw were like this.
I know it returns string, but I saw that thing to convert from string to int.

I want to get "how many" storage of key 48901 player got
Then multiply it by x, and check if it's bigger than a math random (make a chance)
Then if yes, crit.

Thanks for your time, at least I understood it better.
 
Last edited:
Oh, I see.
You went into trap actually.
About types, string and ints...
There is one type, which is "bool".
Boolean has only two values = True or False
getStorage(x,y)
is not question "how many y is in x storage" (answers could be 1,2,3,50,36 etc), but instead it's question "Does x's value == y?" (answers could be True, False).


In your scenario (and once again, I'm not familiar with TFS 0.x), I create a new function, because I'm assuming asking "if 1, if 2, if 3"... etc isn't enough (range of that crit might be 0-100, right? Asking each and every value of that would be... bad for optimization ;)).
So I would go to player.h, search for:
C++:
 bool getStorage(
or something like this (on my server it's like this but yours might be different so don't worry! and don't change that)
C++:
     bool getStorageValue(const uint32_t key, int32_t& value) const;
and just before this line, put:
C++:
    uint32_t getStorageIntValue(const uint32_t key);

Then go to definition of it (player.cpp most likely), once again search for something like this:
C++:
 bool Player::getStorage(
In my code it's
C++:
 bool Player::getStorageValue(const uint32_t key, int32_t& value) const{
but once again, don't panic ;) Don't change.

Just before, add this function:
C++:
 uint32_t Player::getStorageIntValue(uint32_t key) 
{
    StorageMap::const_iterator it;
    it = storageMap.find(key);
    if(it != storageMap.end()){
        value = it->second;
        return value;
    }
    else{
        value = -1;
        return value;
    }
}
And use it like this
C++:
 uint32_t crit_chance = player->getStorageIntValue(48901,valor);

But I haven't test it, and your functions might differ than mine. So if that doesn't work, could you please post me your code of getStorage (right click on it in code) -> go to definition & declaration)
 
Hello @ochmar, sorry for taking so long, wasn't able to login last days.

I didn't have getStorage on any of those files, so I did it before (bool Player::setStorage)

And the weapons (testing on fist) is like this:

Code:
bool Weapon::useFist(Player* player, Creature* target)
{
    const Position& playerPos = player->getPosition();
    const Position& targetPos = target->getPosition();
    if(!Position::areInRange<1,1>(playerPos, targetPos))
        return false;
    float attackFactor = player->getAttackFactor();
    int32_t attackSkill = player->getSkill(SKILL_FIST, SKILL_LEVEL), attackValue = g_config.getNumber(ConfigManager::FIST_BASE_ATTACK);
    double maxDamage = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
    uint32_t crit_chance = player->getStorageIntValue(48901);
    if(crit_chance*5 >= random_range(1, 1000))
    {
        maxDamage = std::pow(maxDamage, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
        player->sendCritical();
    }
    Vocation* vocation = player->getVocation();
    if(vocation && vocation->getMultiplier(MULTIPLIER_MELEE) != 1.0)
        maxDamage *= vocation->getMultiplier(MULTIPLIER_MELEE);
    maxDamage = std::floor(maxDamage);
    int32_t damage = -random_range(0, (int32_t)maxDamage, DISTRO_NORMAL);
    CombatParams fist;
    fist.blockedByArmor = true;
    fist.blockedByShield = true;
    fist.combatType = COMBAT_PHYSICALDAMAGE;
    Combat::doCombatHealth(player, target, damage, damage, fist);
    if(!player->hasFlag(PlayerFlag_NotGainSkill) && player->getAddAttackSkill())
        player->addSkillAdvance(SKILL_FIST, 1);
    return true;
}

the function to use on weapons should be:
Code:
 uint32_t crit_chance = player->getStorageIntValue(48901);
Without the valor, right? Just sending storage key, and it should return value.

Got some errors on player.cpp
Code:
1>..\player.cpp(833): error C2664: 'std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>> std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::find(const std::basic_string<char,std::char_traits<char>,std::allocator<char>> &) const': cannot convert argument 1 from 'uint32_t' to 'const std::basic_string<char,std::char_traits<char>,std::allocator<char>> &'
1>          with
1>          [
1>              _Kty=std::string,
1>              _Ty=std::string,
1>              _Pr=std::less<std::string>,
1>              _Alloc=std::allocator<std::pair<const std::string,std::string>>
1>          ]
1>  ..\player.cpp(833): note: Reason: cannot convert from 'uint32_t' to 'const std::basic_string<char,std::char_traits<char>,std::allocator<char>>'
1>  ..\player.cpp(833): note: No constructor could take the source type, or constructor overload resolution was ambiguous
1>..\player.cpp(835): error C2065: 'value': undeclared identifier
1>..\player.cpp(836): error C2065: 'value': undeclared identifier
1>..\player.cpp(839): error C2065: 'value': undeclared identifier
1>..\player.cpp(840): error C2065: 'value': undeclared identifier
 
Code:
std::string strValue;
    if (player->getStorage(48901, strValue)) {
        int32_t intValue = atoi(strValue.c_str());
        if (intValue) {
            if ((intValue * 3) <= random_range(0, 1000, DISTRO_NORMAL)) {
                maxDamage = std::pow(maxDamage, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
                player->sendCritical();
            }
        }
    }
 
Code:
std::string strValue;
    if (player->getStorage(48901, strValue)) {
        int32_t intValue = atoi(strValue.c_str());
        if (intValue) {
            if ((intValue * 3) <= random_range(0, 1000, DISTRO_NORMAL)) {
                maxDamage = std::pow(maxDamage, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
                player->sendCritical();
            }
        }
    }

Code:
1>  weapons.cpp
1>..\weapons.cpp(364): error C2664: 'bool Creature::getStorage(const std::string &,std::string &) const': cannot convert argument 1 from 'int' to 'const std::string &'
1>  ..\weapons.cpp(364): note: Reason: cannot convert from 'int' to 'const std::string'
1>  ..\weapons.cpp(364): note: No constructor could take the source type, or constructor overload resolution was ambiguous

From creature.cpp:
Code:
bool Creature::getStorage(const std::string& key, std::string& value) const
{
    StorageMap::const_iterator it = storageMap.find(key);
    if(it != storageMap.end())
    {
        value = it->second;
        return true;
    }
    value = "-1";
    return false;
}

The function getStorage is a bool? So we would need to create a new function to get value on x storage key?
Like @ochmar was doing, but that gave errors.
 
Last edited:
change int key X string key!
example: 48901 to "48901"
Code:
std::string strValue;
    if (player->getStorage("48901", strValue)) {
        int32_t intValue = atoi(strValue.c_str());
        if (intValue) {
            if ((intValue * 3) <= random_range(0, 1000, DISTRO_NORMAL)) {
                maxDamage = std::pow(maxDamage, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
                player->sendCritical();
            }
        }
    }
 
Back
Top