• 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++ Fast Attack

metiu11

Member
Joined
Mar 26, 2011
Messages
94
Solutions
2
Reaction score
5
Hello guys,

I want to create fast attack skill in my server.
So i was used this:
Code:
uint32_t Player::getAttackSpeed()
{
        uint32_t attackSpeed = vocation->getAttackSpeed();
        uint32_t skilll = getSkill(SKILL_AXE, SKILL_LEVEL);
        Item* weapon = getWeapon();

        if(skilll > 190)
                        skilll = 190;

        if(weapon && weapon->getAttackSpeed() != 0)
                        attackSpeed = weapon->getAttackSpeed();

        return attackSpeed - (skilll * 10);
}

Code:
#define EVENT_CREATURECOUNT 1
#define EVENT_CREATURE_THINK_INTERVAL 100

It works but i think its too slow. I got 190 FA skill. so its 2000- 190*10=2000-1900=100
I was change score to 1 and still too slow... I saw a lot of servers with faster AS.
Can i change it somewhere? to be faster? please help :)
 
Solution
If you want it faster just put:

#define EVENT_CREATURE_THINK_INTERVAL 50

Put your axe skill 150 and test it.

Remember to put your vocation attack speed 2000.
you can change attack speed in vocations.xml &/or in items.xml by adding attribute "attackSpeed" with a value
 
Yea i saw it. But there i can give my vocation starting value attack speed and then when i got attack speed skills. This value going down and i will hit faster. Original value without "attackSpeed" its 2000.
So anyway when I gived my character 1000 fast attack in vocations and 110 FA skill. 1000-110*10=-100. So my character stop hitting because value= -100
 
Hmm i saw now something strange, when i moved my attack speed going faster but when i stand and dont move attack speed going slower. Lags or what??
Can i repair it somewhere?

I found this


TFS has an function called "doAttacking" that runs every 500 ms.
Then TFS also checks if you can attack when you move.
And lastly TFS checks if you can attack when you select a target.

This means, standing still, without spamming the red attack box on a target, the fastest you can attack would be 500ms. (twice a second).

If you move, you can attack each time you move, and if you spam the attack box (red box) you can attack faster than that.

There is no good way to get faster than 500ms attackspeed without source edits.

BUT, if you "must have" faster attackspeed and you don't want to edit sources you could make a new script in weapons.xml that repeats, and add it to all the weapons in your game.


He said function like "doAttacking" someone know where can i find it??
 
Last edited:
EDIT: @metiu11
C++:
uint32_t Player::getAttackSpeed()
{
    uint32_t attackSpeed = vocation->getAttackSpeed();
    uint32_t skilll = getSkill(SKILL_AXE, SKILL_LEVEL);

    Item* weapon = getWeapon();
    if(skilll > 190)
        skilll = 190;
    if(weapon && weapon->getAttackSpeed() != 0)
        attackSpeed = weapon->getAttackSpeed();
    return attackSpeed - attackSpeed * (skilll/2/100);
}

note the above "(skill/2/100)"
2*100 would be your "skillcap" in other words when atkspd skill is at 200 atkspd would reach 0

some examples:
Code:
65 skill
2000 - 2000 * (65/2/100) = 1350
1500 - 1500 * (65/2/100) = 1012
1000 - 1000 * (65/2/100) = 675

110 skill
2000 - 2000 * (110/2/100) = 900
1500 - 1500 * (110/2/100) = 675
1000 - 1000 * (110/2/100) = 450

180 skill
2000 - 2000 * (180/2/100) = 200
1500 - 1500 * (180/2/100) = 150
1000 - 1000 * (180/2/100) = 100
doAttacking is in player.cpp
 
Last edited:
That's because of timed events. It's like the character "thinks" every X ms & every time you perform an action (moving for example) you reset the timer.
For the calculation you could do something like
Code:
baseatkspeed - baseatkspeed / (skilldecimal * 2)
Ex. 2000 - 2000 / (1.1 * 2) = 1090 (2k is base vocation atkspeed, 1.1 is 110 skill. "* 2" is just to increase intensity)

1090? why :D Can u show me how u calculated this?
 
I was change my script
Code:
uint32_t Player::getAttackSpeed()
{
    Item* weapon = getWeapon();
    int32_t attackSpeedzik;
    if(weapon && weapon->getAttackSpeed() != 0)
        attackSpeedzik = vocation->getAttackSpeed() - (getSkill(SKILL_AXE, SKILL_LEVEL) * 13) - weapon->getAttackSpeed();
    else
        attackSpeedzik = vocation->getAttackSpeed() - (getSkill(SKILL_AXE, SKILL_LEVEL) * 13);
    if(attackSpeedzik > 0)
        return (uint32_t) attackSpeedzik;
    else
        return 1;
}

Now my character doesn't stop hitting when i got 200+ Fast Attack skill. But speed its the same like with old script. Its like 2shots per second. Where can i change that?
If 2000 AS --- 1 shot per 2 sec
so 100 AS --- 1 shot per 0.1 sec
but it doesn't work... maximum 2shots per 1 sec
 
I was change my script
Code:
uint32_t Player::getAttackSpeed()
{
    Item* weapon = getWeapon();
    int32_t attackSpeedzik;
    if(weapon && weapon->getAttackSpeed() != 0)
        attackSpeedzik = vocation->getAttackSpeed() - (getSkill(SKILL_AXE, SKILL_LEVEL) * 13) - weapon->getAttackSpeed();
    else
        attackSpeedzik = vocation->getAttackSpeed() - (getSkill(SKILL_AXE, SKILL_LEVEL) * 13);
    if(attackSpeedzik > 0)
        return (uint32_t) attackSpeedzik;
    else
        return 1;
}

Now my character doesn't stop hitting when i got 200+ Fast Attack skill. But speed its the same like with old script. Its like 2shots per second. Where can i change that?
If 2000 AS --- 1 shot per 2 sec
so 100 AS --- 1 shot per 0.1 sec
but it doesn't work... maximum 2shots per 1 sec
If you set the value of a signed integer (int32_t) to a negative value and then cast it to an unsgined int (uint32_t) then the value which is suppose to be stored in the uint32_t will be set to its max value and that isn't something you want.
You can test this theory with any compiler:
C++:
#include <iostream>
#include <string>

int main()
{
  int a = -2000;
  unsigned int b = 0;
  b = *(uint32_t*)&a;
  std::cout << a << " " << b << std::endl;
}
C++:
-2000 4294965296
So what you want to do is check the value before its casted from int32_t to uint32_t
C++:
  b = (a > -1) ? *(uint32_t*)&a : 0;
C++:
#include <iostream>
#include <string>

int main()
{
  int a = -2000;
  unsigned int b = 0;
  b = (a > -1) ? *(uint32_t*)&a : 0;
  std::cout << a << " " << b  << std::endl;
}
C++:
-2000 0
So to answer your question.
C++:
uint32_t Player::getAttackSpeed()
{
    Item* weapon = getWeapon();
    int32_t attackSpeedzik;
    if(weapon && weapon->getAttackSpeed() != 0){
        attackSpeedzik = vocation->getAttackSpeed() - (getSkill(SKILL_AXE, SKILL_LEVEL) * 13) - weapon->getAttackSpeed();
    }else{
        attackSpeedzik = vocation->getAttackSpeed() - (getSkill(SKILL_AXE, SKILL_LEVEL) * 13);
    }
    return (attackSpeedzik > -1) ? *(uint32_t*)&attackSpeedzik : 1;
}
 
Last edited:
If you set the value of a signed integer (int32_t) to a negative value and then cast it to an unsgined int (uint32_t) then the value which is suppose to be stored in the uint32_t will be set to its max value and that isn't something you want.
You can test this theory with any compiler:
C++:
#include <iostream>
#include <string>

int main()
{
  int a = -2000;
  unsigned int b = 0;
  b = *(uint32_t*)&a;
  std::cout << a << " " << b << std::endl;
}
C++:
-2000 4294965296
So what you want to do is check the value before its casted from int32_t to uint32_t
C++:
  b = (a > -1) ? *(uint32_t*)&a : 0;
C++:
#include <iostream>
#include <string>

int main()
{
  int a = -2000;
  unsigned int b = 0;
  b = (a > -1) ? *(uint32_t*)&a : 0;
  std::cout << a << " " << b  << std::endl;
}
C++:
-2000 0

}[/code]


I dont get it :D Too hard for me i think... Where i must add this scripts? I was change only this:
Code:
uint32_t Player::getAttackSpeed()
{
    Item* weapon = getWeapon();
    int32_t attackSpeedzik;
    if(weapon && weapon->getAttackSpeed() != 0){
        attackSpeedzik = vocation->getAttackSpeed() - (getSkill(SKILL_AXE, SKILL_LEVEL) * 13) - weapon->getAttackSpeed();
    }else{
        attackSpeedzik = vocation->getAttackSpeed() - (getSkill(SKILL_AXE, SKILL_LEVEL) * 13);
    }
    return (attackSpeedzik > -1) ? *(uint32_t*)&attackSpeedzik : 1;
}

And it doesn't work.
Can u tell me where i must add other lines?
 
hey, did you read my edited post? let me know if it helps.
yea i read it, but it doesnt work
Its only 2 shots per 1 sec.. Idk how to unblocked it... pls help

EDIT: I removed script and changed Attack speed in vocation.xml to 10.
And its only 2 shots per 1 sec... So where can i change it ?
 
Last edited:
I don't either :/ While you wait for an answer you can go through the tedious task of trail & error.
That's what I usually do and in most cases I figure it out shortly after. I've found that going through trail & error helps tremendously in understanding code.
 
Back
Top