Post Reply 
 
Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Move speed formula
Author Message
Aimed
Apprentice
*

Posts: 20
Likes Given: 0
Likes Received: 4 in 3 posts
Joined: Apr 2015
Reputation: 0



Post: #1
Move speed formula
Hello Sphere devs!
I'm roaming in your core once again and I have a question about this:

Code:
    // TAG.OVERRIDE.MOVERATE
    INT64 tTick;
    CVarDefCont * pValue = GetKey("OVERRIDE.MOVERATE", true);
    if (pValue)
        tTick = pValue->GetValNum();    //Taking value from tag.override.moverate
    else
        tTick = pCharDef->m_iMoveRate;    //no tag.override.moverate, we get default moverate (created from ini's one).
    // END TAG.OVERRIDE.MOVERATE
    if (fRun)
    {
        if (IsStatFlag(STATF_Pet))    // pets run a little faster.
        {
            if (iDex < 75)
                iDex = 75;
        }
        iTickNext = TICK_PER_SEC / 4 + Calc_GetRandLLVal((100 - (iDex*tTick) / 100) / 5) * TICK_PER_SEC / 10;
    }
    else
        iTickNext = TICK_PER_SEC + Calc_GetRandLLVal((100 - (iDex*tTick) / 100) / 3) * TICK_PER_SEC / 10;

    if (iTickNext < 1)
        iTickNext = 1;
    else if (iTickNext > 50)
        iTickNext = 50;

    SetTimeout(iTickNext);
    EXC_CATCH;
    return 1;

Taken from CCharNPCAct.cpp start is at line 975 ( on git ).

SO my question is about TICK_PER_SEC. I've found a define in another file and there TICK_PER_SEC is 10.

You can not configure this anywhere else.
1)So does this mean that the last part of the formula with * TICK_PER_SEC / 10 is useless, as TICK_PER_SEC always equals 10?
2)SetTimeout(iTickNext) if iTickNext == 16, does it mean, that next *AI tick* for this object will be over 1.6 sec ?

Thanks in advance,

-Aimed
(This post was last modified: 10-23-2015 10:41 AM by Aimed.)
10-23-2015 10:37 AM
Find all posts by this user Like Post Quote this message in a reply
XuN
Sphere Developer
*****

Posts: 852
Likes Given: 102
Likes Received: 156 in 119 posts
Joined: Jul 2013
Reputation: 30



Post: #2
RE: Move speed formula
1) What if you change TICK_PER_SEC to 100 to have 100 ticks instead of 10?
2) Yes, SetTimeout will generate a timer that, on the next CChar::OnTick(), will call NPC_OnTickAction(). Think about this as ' it will take me X tenths of seconds to do this move, when I finish i'll think what to do next.
10-23-2015 06:57 PM
Find all posts by this user Like Post Quote this message in a reply
Aimed
Apprentice
*

Posts: 20
Likes Given: 0
Likes Received: 4 in 3 posts
Joined: Apr 2015
Reputation: 0



Post: #3
RE: Move speed formula
(10-23-2015 06:57 PM)XuN Wrote:  1) What if you change TICK_PER_SEC to 100 to have 100 ticks instead of 10?
2) Yes, SetTimeout will generate a timer that, on the next CChar::OnTick(), will call NPC_OnTickAction(). Think about this as ' it will take me X tenths of seconds to do this move, when I finish i'll think what to do next.

Hey XuN, thanks for your answers!


So this means that in my personal case * TICK_PER_SEC / 10 are 2 useless arithmetic operations.

We're re-writing our sphere 56b shard specificly to RunUO (actually it's just C#, there's not much left from RunUO atm) for nearly 2.5 years now, we're almost there( too bad Sphere was not open source back then Sad ). So I've copied this formula exactly like it is in sphere core. My AI Timer ticks every 100 miliseconds, the NPC's have the same dex and moverate amount converted and it still doesn't work as it should work on Sphere Sad
I suspend NPC decisions for the amount of ticks this formula generates and it just doesn't work...

For example, I have guards with 200 - 250 dex generated and 20 moverate ( overridden ).

Let's take this and calculate by using your formula:
run is true.
moverate is 20 (defind within the char def)
dex is 250

iTickNext = 10 / 4 + random((100-(250*20)/100)/ 5)
( I wont do this * 10 and /10 as it is pretty useless in my case)
so now we're getting 250*20= 5000, 5000/100 = 50, 100-50 =50, 50/5 = 10 and we take a random number from 0 to 10, I will take the avg = 5.
Therefore we get :
10/4 +5 which ends up as 7 ticks.
but the random factor is pretty huge here, we might get a number between 2 and 11, which is 0.2 sec or 1.1 sec and guards on our sphere shard have nearly same movementspeed as mounted players( achieved by doing 2 steps at the same time in sphere), which looks more like always 0.2 sec with this "double-step" feature.
They're running very fast and smooth, so the randomization can not be that huge.

By applying this formula as it is exactly here they're barely moving on our new platform...

Do you have any suggestions on this?
(This post was last modified: 10-23-2015 07:35 PM by Aimed.)
10-23-2015 07:34 PM
Find all posts by this user Like Post Quote this message in a reply
darksun84
Sir Spamalot
****

Posts: 1,687
Likes Given: 246
Likes Received: 162 in 151 posts
Joined: Mar 2012
Reputation: 35



Post: #4
RE: Move speed formula
In that formula, a moverate of 20 means that the NPC uses 20% of their actual dex for walking/runnin action.
In 56b. the formula was different, a lower value meant an higher speed, in 56c it's the opposite (100 moverate is default)
10-23-2015 10:34 PM
Find all posts by this user Like Post Quote this message in a reply
Aimed
Apprentice
*

Posts: 20
Likes Given: 0
Likes Received: 4 in 3 posts
Joined: Apr 2015
Reputation: 0



Post: #5
RE: Move speed formula
(10-23-2015 10:34 PM)darksun84 Wrote:  In that formula, a moverate of 20 means that the NPC uses 20% of their actual dex for walking/runnin action.
In 56b. the formula was different, a lower value meant an higher speed, in 56c it's the opposite (100 moverate is default)

Was it something like this?

Code:
if ( fRun )
   {
      if ( IsStatFlag( STATF_Pet ))   // pets run a little faster.
      {
         if ( iDex < 75 )
            iDex = 75;
      }
      iTickNext = TICK_PER_SEC/4 + Calc_GetRandVal( (100-iDex)/5 ) * TICK_PER_SEC / 10;
   }
   else
      iTickNext = TICK_PER_SEC + Calc_GetRandVal( (100-iDex)/3 ) * TICK_PER_SEC / 10;

   iTickNext = (iTickNext * pCharDef->m_iMoveRate)/100;
   if ( iTickNext < 1 )
      iTickNext = 1;
10-23-2015 10:51 PM
Find all posts by this user Like Post Quote this message in a reply
darksun84
Sir Spamalot
****

Posts: 1,687
Likes Given: 246
Likes Received: 162 in 151 posts
Joined: Mar 2012
Reputation: 35



Post: #6
RE: Move speed formula
Yes possible, in that formula, a lower moverate means a lower tickNext
10-23-2015 11:24 PM
Find all posts by this user Like Post Quote this message in a reply
XuN
Sphere Developer
*****

Posts: 852
Likes Given: 102
Likes Received: 156 in 119 posts
Joined: Jul 2013
Reputation: 30



Post: #7
RE: Move speed formula
Here you have the old formula, its a little different from the current one, it was added in 02/04/2014:

Code:
EXC_SET("Speed counting");
    // How fast can they move.
    INT64 iTickNext;
    if ( fRun )
    {
        if ( IsStatFlag( STATF_Pet ))    // pets run a little faster.
        {
            if ( iDex < 75 )
                iDex = 75;
        }
        iTickNext = TICK_PER_SEC/4 + Calc_GetRandVal( (100-iDex)/5 ) * TICK_PER_SEC / 10;
    }
    else
        iTickNext = TICK_PER_SEC + Calc_GetRandVal( (100-iDex)/3 ) * TICK_PER_SEC / 10;

// TAG.OVERRIDE.MOVERATE
    CVarDefCont * pValue = GetKey("OVERRIDE.MOVERATE",true);
    if ( pValue )
    {
        INT64 tTick = pValue->GetValNum();
        if ( tTick < 1 ) tTick=1;
        //g_Log.EventDebug("tag found: %d\n",tTick);
        iTickNext = ( iTickNext * tTick ) / 100;
    }
    else
    {
// END TAG.OVERRIDE.MOVERATE

        //g_Log.EventDebug("prop found: %d\n",pCharDef->m_iMoveRate);
        iTickNext = (iTickNext * pCharDef->m_iMoveRate)/100;

// TAG.OVERRIDE.MOVERATE
    }
// END TAG.OVERRIDE.MOVERATE

    if ( iTickNext < 1 )
        iTickNext = 1;

    SetTimeout(iTickNext);
10-24-2015 02:31 AM
Find all posts by this user Like Post Quote this message in a reply
Aimed
Apprentice
*

Posts: 20
Likes Given: 0
Likes Received: 4 in 3 posts
Joined: Apr 2015
Reputation: 0



Post: #8
RE: Move speed formula
Thank you guys.

So I've implemented everything right.

I guess there is some code somewhere else which limits the maximum speed for NPC's.

Here I can see that the limit speed is 1 tick but I'm pretty sure it's 2 ticks actually.
Because as soon as I made this 2 ticks limit, it worked!
Anyway, my problem is solved. Thank everyone Smile
10-26-2015 05:58 PM
Find all posts by this user Like Post Quote this message in a reply
Aimed
Apprentice
*

Posts: 20
Likes Given: 0
Likes Received: 4 in 3 posts
Joined: Apr 2015
Reputation: 0



Post: #9
RE: Move speed formula
Ah, I guess I've implemented the formula well right from the start. It's just that there is a limitation somewhere else in the core, which doesn't allow to move faster than once in 2 ticks, not 1 like here in the code.
10-29-2015 09:50 PM
Find all posts by this user Like Post Quote this message in a reply
XuN
Sphere Developer
*****

Posts: 852
Likes Given: 102
Likes Received: 156 in 119 posts
Joined: Jul 2013
Reputation: 30



Post: #10
RE: Move speed formula
What do you mean by 2 ticks? 2 ticks doesn't have to be the same than 0.2s, saturated servers can have some delay, did you try to log the difference between last move and this one? or log each movement to compare next ones, try: g_Log.EventDebug("Movement done at %lld\n",CServTime::GetCurrentTime().GetTimeRaw());
10-29-2015 10:35 PM
Find all posts by this user Like Post Quote this message in a reply
Post Reply 


Forum Jump:


User(s) browsing this thread: 1 Guest(s)