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

Things you didn't know about TFS (A Series by Flatlander)

Flatlander

Species Developer
Joined
Feb 17, 2009
Messages
2,461
Solutions
3
Reaction score
1,364
Location
Texas
If you have any requests or questions NOT related to the tutorials in this thread, send them in a private message, do not post on this thread.
Thank You


Hi Everyone!
I am starting this series to inform people about many things I have found out about TFS that are not common knowledge.

There are many things that are coded into the source of TFS that most people might not know, or would want changed if they did know about it.

I will make a new post for each edition of this "Series". and I will show you where in the source it is, and how to add it so you can change it in the config.lua.

I will be showing you how to add things into configmanager.cpp and configmanager.h so that you can have a much better and more configurable version of TFS.

I will make instructions for both TFS 1.0, and TFS 0.3~.

Table of Contents:
  1. Full Defense Exhaust
 
Last edited:
1. Full Defense Exhaust

The first thing we will be looking at is Full Defense Exhaust.

This is located in players.cpp and I don't think many people notice that this is coded into the source.
Code:
float Player::getDefenseFactor() const
{
   switch (fightMode) {
    case FIGHTMODE_ATTACK:
    return 1.0f;

    case FIGHTMODE_BALANCED:
    return 1.2f;

    case FIGHTMODE_DEFENSE: {
     if ((OTSYS_TIME() - lastAttack) < getAttackSpeed()) {
      return 1.0f;
     }

    return 2.0f;
    }

   default:
   return 1.0f;
   }
}

If we look at getDefenseFactor, this is used when getting your shielding multiplier when you are on either Full Attack, Balanced, or Full Defense mode.


If we look at these lines:
Code:
    case FIGHTMODE_DEFENSE: {
     if ((OTSYS_TIME() - lastAttack) < getAttackSpeed()) {
      return 1.0f;
     }

    return 2.0f;
    }
It says "If the player is in Full Defense, and has attacked, return 1.0 instead of 2.0"
Originally, 2.0 would double your defense (Multiplies it by 2) but if are attacking while on full defense, you are then given 1.0 (no bonus defense).

This literally makes it so if you are attacking on full defense, you have HALF the attack, and normal defense. I suspect most people would think being in full defense would make you more defensive while attacking... but this is not the case, it just makes you hit less, and take the same damage.

So, in my personal opinion it should be changed, but some people might want the original system, or maybe you want to configure how much defense you gain when in balanced and defense modes. So the best thing to do would be to add this into the config.lua so you can change it whenever you want.

Tutorial: Adding Variables to Config.lua
To fix the above, I would suggest adding it to the config, rather than just changing the values.

First, I would add what variables you want to the configmanager.
So first we should add the True/False (or Yes/No) in configmanager.h
For TFS: 1.0:
Add a line in this Table:
Code:
enum boolean_config_t {
Right before the end (Add the next number in line)
Code:
DEFENSE_EXHAUST = 15, //Added here (You can name it whatever you want)
LAST_BOOLEAN_CONFIG /* this must be the last one */
};
For TFS 0.3
Add a line in this table:
Code:
    enum bool_config_t
    {
Right before the end again:
Code:
      DEFENSE_EXHAUST, //No number needed for TFS 0.3
      LAST_BOOL_CONFIG /* this must be the last one */
     };

Then we will add in the numbers.
For TFS 1.0:
Add 6 lines to this table:
Code:
enum integer_config_t {
You can name them whatever you want, but make sure you number them in order.
Code:
STANCE_A_ATTACK = 31, //Attack Stance AttackFactor
STANCE_B_ATTACK = 32, //Balanced Stance AttackFactor
STANCE_D_ATTACK = 33, //Defense Stance AttackFactor
STANCE_A_DEFENSE = 34, //Attack Stance DefenseFactor
STANCE_B_DEFENSE = 35, //Balanced Stance DefenseFactor
STANCE_D_DEFENSE = 36, //Defense Stance DefenseFactor
LAST_INTEGER_CONFIG /* this must be the last one */
};
For TFS 0.3
Put your lines in the Table:
Code:
    enum double_config_t
    {
Add the 6 lines to the end of this table:
Code:
       STANCE_A_ATTACK, //Attack Stance AttackFactor
       STANCE_B_ATTACK, //Balanced Stance AttackFactor
       STANCE_D_ATTACK, //Defense Stance AttackFactor
       STANCE_A_DEFENSE, //Attack Stance DefenseFactor
       STANCE_B_DEFENSE, //Balanced Stance DefenseFactor
       STANCE_D_DEFENSE, //Defense Stance DefenseFactor
       LAST_DOUBLE_CONFIG /* this must be the last one */
     };
Now we have to add these into configmanager.cpp
For TFS 1.0:
Add after this line:
Code:
m_confBoolean[STAMINA_SYSTEM] = booleanString(getGlobalString(L, "staminaSystem", "yes"));
m_confBoolean[DEFENSE_EXHAUST] = booleanString(getGlobalString(L, "defenseExhaust", "yes"));
And add your 6 numbers after this line:
Code:
m_confInteger[MAX_PACKETS_PER_SECOND] = getGlobalNumber(L, "maxPacketsPerSecond", 40);
m_confInteger[STANCE_A_ATTACK] = getGlobalNumber(L, "stanceAAttack", 1.0);
m_confInteger[STANCE_B_ATTACK] = getGlobalNumber(L, "stanceBAttack", 1.2);
m_confInteger[STANCE_D_ATTACK] = getGlobalNumber(L, "stanceDAttack", 2.0);
m_confInteger[STANCE_A_DEFENSE] = getGlobalNumber(L, "stanceADefense", 1.0);
m_confInteger[STANCE_B_DEFENSE] = getGlobalNumber(L, "stanceBDefense", 1.2);
m_confInteger[STANCE_D_DEFENSE] = getGlobalNumber(L, "stanceDDefense", 2.0);
For TFS 0.3:
A little different but we do the same things:
Add everything at the "end":
Code:
  m_confBool[DEFENSE_EXHAUST] = getGlobalBool("defenseExhaust", true);
  m_confDouble[STANCE_A_ATTACK] = getGlobalDouble("stanceAAttack", 1.0);
  m_confDouble[STANCE_B_ATTACK] = getGlobalDouble("stanceBAttack", 1.2);
  m_confDouble[STANCE_D_ATTACK] = getGlobalDouble("stanceDAttack", 2.0);
  m_confDouble[STANCE_A_DEFENSE] = getGlobalDouble("stanceADefense", 1.0);
  m_confDouble[STANCE_B_DEFENSE] = getGlobalDouble("stanceBDefense", 1.2);
  m_confDouble[STANCE_D_DEFENSE] = getGlobalDouble("stanceDDefense", 2.0);

  //Add Above this
   m_loaded = true;
   return true;
}

Now we need to add these variables into players.cpp.
For TFS 1.0:
Change:
Code:
float Player::getAttackFactor() const
{
switch (fightMode) {
case FIGHTMODE_ATTACK:
return 1.0f;

case FIGHTMODE_BALANCED:
return 1.2f;

case FIGHTMODE_DEFENSE:
return 2.0f;

default:
return 1.0f;
}
}

float Player::getDefenseFactor() const
{
switch (fightMode) {
case FIGHTMODE_ATTACK:
return 1.0f;

case FIGHTMODE_BALANCED:
return 1.2f;

case FIGHTMODE_DEFENSE: {
if ((OTSYS_TIME() - lastAttack) < getAttackSpeed()) {
return 1.0f;
}

return 2.0f;
}

default:
return 1.0f;
}
}
To:
Code:
float Player::getAttackFactor() const
{
   float aFactor;
   switch (fightMode) {
     case FIGHTMODE_ATTACK:
       aFactor = (float)g_config.getNumber(ConfigManager::STANCE_A_ATTACK);

     case FIGHTMODE_BALANCED:
       aFactor = (float)g_config.getNumber(ConfigManager::STANCE_B_ATTACK);

     case FIGHTMODE_DEFENSE:
       aFactor = (float)g_config.getNumber(ConfigManager::STANCE_D_ATTACK);

     default:
       aFactor = (float)g_config.getNumber(ConfigManager::STANCE_A_ATTACK);
   }
   return aFactor;
}


float Player::getDefenseFactor() const
{
   float dFactor;
   switch (fightMode) {
     case FIGHTMODE_ATTACK:
       dFactor = (float)g_config.getNumber(ConfigManager::STANCE_A_DEFENSE);

     case FIGHTMODE_BALANCED:
       dFactor = (float)g_config.getNumber(ConfigManager::STANCE_B_DEFENSE);

     case FIGHTMODE_DEFENSE: {
       if (((OTSYS_TIME() - lastAttack) < getAttackSpeed()) && g_config.getBoolean(ConfigManager::DEFENSE_EXHAUST)) {
         dFactor = (float)g_config.getNumber(ConfigManager::STANCE_A_DEFENSE);
       }

       dFactor = (float)g_config.getNumber(ConfigManager::STANCE_D_DEFENSE);
     }

     default:
       dFactor = (float)g_config.getNumber(ConfigManager::STANCE_A_DEFENSE);
   }
   return dFactor;
}

For TFS 0.3:Change them both to:
Code:
float Player::getAttackFactor() const
{
   float aFactor;
   switch(fightMode)
   {
     case FIGHTMODE_BALANCED:
       aFactor = (float)g_config.getDouble(ConfigManager::STANCE_A_ATTACK);

     case FIGHTMODE_DEFENSE:
       aFactor = (float)g_config.getDouble(ConfigManager::STANCE_B_ATTACK);

     case FIGHTMODE_ATTACK:
       aFactor = (float)g_config.getDouble(ConfigManager::STANCE_D_ATTACK);
      
     default:
       aFactor = (float)g_config.getDouble(ConfigManager::STANCE_A_ATTACK);
   }

   return aFactor;
}

float Player::getDefenseFactor() const
{
   float dFactor;
   switch(fightMode)
   {
     case FIGHTMODE_BALANCED:
       dFactor = (float)g_config.getDouble(ConfigManager::STANCE_B_DEFENSE);

     case FIGHTMODE_DEFENSE:
     {
       if (((OTSYS_TIME() - lastAttack) < getAttackSpeed()) && g_config.getBool(ConfigManager::DEFENSE_EXHAUST)) {
         dFactor = (float)g_config.getNumber(ConfigManager::STANCE_A_DEFENSE);
       }
       dFactor = (float)g_config.getDouble(ConfigManager::STANCE_D_DEFENSE);
     }
     case FIGHTMODE_ATTACK:
       dFactor = (float)g_config.getDouble(ConfigManager::STANCE_A_DEFENSE);
    
     default:
       dFactor = (float)g_config.getDouble(ConfigManager::STANCE_A_DEFENSE);
   }

   return dFactor;
}

Now you can change this in your config.lua, and it will work :).
Example:
Code:
--Stance Config
defenseExhaust = true --(Or Yes for TFS 1.0)
stanceAAttack = 1.0
stanceBAttack = 1.2
stanceDAttack = 2.0
stanceADefense = 1.0
stanceBDefense = 1.2
stanceDDefense = 2.0

If you have any issues or get any errors let me know and I will fix them. It is possible I made mistakes, I made this tutorial without a copy of TFS to test it on, because I just reformatted my computer.
 
Last edited:
Tell about combats too =) Who code this? :D
Code:
enum CombatType_t
{
COMBAT_NONE    = 0x00,
COMBAT_ALL    = COMBAT_NONE, /* for internal use only.*/
COMBAT_PHYSICALDAMAGE = 1 << 0,
COMBAT_ENERGYDAMAGE  = 1 << 1,
COMBAT_EARTHDAMAGE  = 1 << 2,
COMBAT_FIREDAMAGE  = 1 << 3,
COMBAT_UNDEFINEDDAMAGE = 1 << 4,
COMBAT_LIFEDRAIN  = 1 << 5,
COMBAT_MANADRAIN  = 1 << 6,
COMBAT_HEALING  = 1 << 7,
COMBAT_DROWNDAMAGE  = 1 << 8,
COMBAT_ICEDAMAGE  = 1 << 9,
COMBAT_HOLYDAMAGE  = 1 << 10,
COMBAT_DEATHDAMAGE  = 1 << 11,
COMBAT_FIRST  = COMBAT_NONE,
COMBAT_LAST    = COMBAT_DEATHDAMAGE
};

okay, but WTF?

Code:
int16_t elementDamage, absorb[COMBAT_LAST + 1], increment[INCREMENT_LAST + 1],
  reflect[REFLECT_LAST + 1][COMBAT_LAST + 1], fieldAbsorb[COMBAT_LAST + 1];

Also, good thread, but all this things known for developers... But thread usefull for newcomers!
 
If i could request, i would like to learn about exhaustion system that was introduced after 8.6. One of the reasons why there are so many 8.6 servers is that nobody really seems to understand the exhaustion. There are some weird delays between different spells, like there is huge exhaust between exura gran san and exori san. Changing exhaustion in spells doesn't seem to fix it. Also there is problem with attacking while using spell.
 
Completed the Tutorial. (I hope it all works, I didn't test it yet)

@Above, if you have requests, or questions, send them to my inbox instead of posting here. (I will only consider requests sent by PM)
 
Wow, i really like you job, i wish that some day i can have your knowledge in C++ to do modificatiosn and understand things, and you are right, is weird, i will change it, also i like the method to add it in config.lua, is softly to modify it
 
Wow, i really like you job, i wish that some day i can have your knowledge in C++ to do modificatiosn and understand things, and you are right, is weird, i will change it, also i like the method to add it in config.lua, is softly to modify it

Thanks :), Just wait till I release my customized versions of TFS 0.3 and TFS 1.0.

I hope it will change OTLand to be more fun with more diverse servers than what we currently have :).
 
That is why I made this :), there are many things in TFS that are pretty... weird.
if there are more let me know mate! if there is any possibility you would teach me c++ then i would be sooo happy (craig voice)
I just have no words for it hehe
 
if there are more let me know mate! if there is any possibility you would teach me c++ then i would be sooo happy (craig voice)
I just have no words for it hehe
I will continue this series when I have time :) as for teaching you C++, the best way to learn is practice :)
 
If i could request, i would like to learn about exhaustion system that was introduced after 8.6. One of the reasons why there are so many 8.6 servers is that nobody really seems to understand the exhaustion. There are some weird delays between different spells, like there is huge exhaust between exura gran san and exori san. Changing exhaustion in spells doesn't seem to fix it. Also there is problem with attacking while using spell.

Yup, there is a delay between offensive spell and basic attack/healing spell, if i'm not wrong, i can't confirm it because my ed is deleted.

I remember when I had to use my exori flam after wand's hit to exp faster or use exori san when assasin star hits the target to don't get "delay" for next basic attack..
 
I will continue this series when I have time :) as for teaching you C++, the best way to learn is practice :)
Thats true the same way i did it with LUA and HTML and graphic design
however.. i cannot find any sense in c++ which makes it hard for me to read and understand the meaning of all those tokens..

thats why i ask for tutorial because to me i have to know how and why its there you know...
 
Yup, there is a delay between offensive spell and basic attack/healing spell, if i'm not wrong, i can't confirm it because my ed is deleted.

I remember when I had to use my exori flam after wand's hit to exp faster or use exori san when assasin star hits the target to don't get "delay" for next basic attack..

I think you are right on this, there is a exhaust to normal attacks after casting a spell.
It MIGHT have something to do with timebetweenactions and timebetweenexactions in the config.lua. But I doubt it.

I will look into it later this week.
 
I may be confused on the configuration you have it setup as. But in the example config.lua is it not where normal defense normal attack for attack mode, your balanced mode has 1.2 for attack and defense, and then your defense mode has 2.0 for its attack and defense?
 
When on
I may be confused on the configuration you have it setup as. But in the example config.lua is it not where normal defense normal attack for attack mode, your balanced mode has 1.2 for attack and defense, and then your defense mode has 2.0 for its attack and defense?

It divides your attack and multiplies your defense.
so 2.0 for both, means Attack/2 and Defense*2

It is confusing at first but that's how TFS does it and is pretty easy to manage.
 
The defense should be changed to work as you mentioned in basic TFS 1.0 servers.

Kind Regards,
Eldin.
 
Real Tibia failed a long time ago so OT should be a basis from it as Tibia still made this possible as well as Mark and CO. Most of use came from real Tibia so all credits to CIP, but we should move in our own direction. An option or script to simplify things like the defense one should be open if not implented from start.

Kind Regards,
Eldin.
 
Real Tibia failed a long time ago so OT should be a basis from it as Tibia still made this possible as well as Mark and CO. Most of use came from real Tibia so all credits to CIP, but we should move in our own direction. An option or script to simplify things like the defense one should be open if not implented from start.

Kind Regards,
Eldin.

I completely agree with you. But TFS is MADE to be a CIP Copy Machine right now.
It literally is built to simply do everything tibia does, the same way tibia does it.

My personal goal is to change it into more of a generic MMO Maker, so people can actually make great custom 2d MMOs.
 
Back
Top