SphereServer BugTracker - SphereServer
View Issue Details
0002521SphereServernew feature requestpublic21-06-15 15:1328-08-15 19:34
Shinaa 
XuN 
normalfeatureN/A
resolvedfixed 
 
0.56c Nightly 
Automated (specify build number)
None
None
0002521: A way to change the attackspeed formula
Changing SpeedScaleFactor is not really enough, because it is only one variable in the formula, it will always be affected by DEX (or Stam atm) in some uncontrollable way.
@HitTry is not working either, because setting ARGN1 to (example) 20 does not mean it's a 2.0 sec attack, in fact it will be something else dependend on Dex (Stam atm) and in some cases it will completely mess with the animation.

Something like TAG.Override.AttackDelay which is used instead of the internal Delay calculated with SpeedScaleFactor would be nice.
No tags attached.
Issue History
21-06-15 15:13ShinaaNew Issue
22-06-15 10:27RizzNote Added: 0002844
22-06-15 13:54ShinaaNote Added: 0002845
22-06-15 20:08XuNNote Added: 0002847
22-06-15 22:28RizzNote Added: 0002851
23-06-15 16:43ShinaaNote Added: 0002857
23-06-15 16:45ShinaaNote Edited: 0002857bug_revision_view_page.php?bugnote_id=0002857#r872
23-06-15 20:06RizzNote Added: 0002858
23-06-15 20:06RizzNote Edited: 0002858bug_revision_view_page.php?bugnote_id=0002858#r874
23-06-15 20:21XuNNote Added: 0002860
23-06-15 20:21XuNStatusnew => resolved
23-06-15 20:21XuNFixed in Version => 0.56c Nightly
23-06-15 20:21XuNResolutionopen => fixed
23-06-15 20:21XuNAssigned To => XuN
26-06-15 03:24ShinaaNote Added: 0002870
26-06-15 03:24ShinaaStatusresolved => feedback
26-06-15 03:24ShinaaResolutionfixed => reopened
27-06-15 09:48XuNNote Added: 0002873
27-06-15 12:31ShinaaNote Added: 0002876
27-06-15 12:31ShinaaStatusfeedback => assigned
27-06-15 12:44XuNNote Added: 0002881
27-06-15 12:44XuNStatusassigned => resolved
27-06-15 12:44XuNResolutionreopened => fixed
27-06-15 12:44XuNStatusresolved => feedback
27-06-15 12:44XuNResolutionfixed => reopened
27-06-15 12:44XuNStatusfeedback => new
27-06-15 13:49ShinaaNote Added: 0002882
27-06-15 13:50ShinaaNote Edited: 0002882bug_revision_view_page.php?bugnote_id=0002882#r880
27-06-15 15:37XuNNote Added: 0002883
27-06-15 17:10ShinaaNote Added: 0002884
27-06-15 17:26ShinaaNote Added: 0002885
08-07-15 10:41XuNNote Added: 0002905
09-07-15 17:06ShinaaNote Added: 0002909
09-07-15 17:08ShinaaNote Edited: 0002909bug_revision_view_page.php?bugnote_id=0002909#r895
10-07-15 08:10XuNNote Added: 0002911
11-07-15 12:38ShinaaNote Added: 0002914
11-07-15 16:05XuNNote Added: 0002915
28-08-15 19:34XuNNote Added: 0002953
28-08-15 19:34XuNStatusnew => resolved
28-08-15 19:34XuNResolutionreopened => fixed

Notes
(0002844)
Rizz   
22-06-15 10:27   
ARGN1 under hittry is the speed of animation.
I suggest you to bypass the formula, I did and it works well.
(0002845)
Shinaa   
22-06-15 13:54   
I know it is supposed to be, but it really isn't or at least not very precise.
Make a weapon with SPEED=50, SpeedScaleFactor=100000, set ARGN1 in HitTr to 20:
at 100 Stam you will hit every 2,0 sec, which would be fine.
at 150 Stam you will hit every 1,8 sec, without changing anything.

(values used from last test I did and still remember, but it never actually was ARGN1=DELAY for any SpeedScaleFactor with diffrent weaponspeeds and stats)

I know what I am talking about, I tested it for hours trying to find out how exactly attackspeed in Sphere works and as I said, at some point it would even look strange because the hit animation just started, triggering almost immediatly a hit and then finishing animation, repeat, for every hit.

If ARGN1 is supposed to be exactly the delay, it is bugged and needs work.
(0002847)
XuN   
22-06-15 20:08   
Is your problem the animation or the damage? In newer clients the animation works like that because the packet changed, there's nothing we can do with it.
(0002851)
Rizz   
22-06-15 22:28   
Set the SpeedScaleFactor to 1 and block the attack under @hittry with a TAG where you store the serv.time
This is the easiest way.
(0002857)
Shinaa   
23-06-15 16:43   
(edited on: 23-06-15 16:45)
My main problem is that ARGN1 in @HitTry is not really the delay before hit, it's modified by STAM and SPEED of the weapon, even if I set a value, like in the post above to 20, the result is diffrent for diffrent weapon speeds and STAM values.

Not sure what blocking HitTry should accomplish, last time that just resulted in firing the trigger over and over.

(0002858)
Rizz   
23-06-15 20:06   
@hittry will always fire over and over when you are in range to attack.
You can define your new dex formula, manually block and unblock the attack (@hittry will continue to trigger anyway) as you want using return 1 and a TAG to store serv.time

IF serv.time > (serv.time - your new delay)
return 1
else
argn1=0.3
endif

This is just an example

otherwise you can edit spere_combat... good luck xD

(0002860)
XuN   
23-06-15 20:21   
I found the problem, somehow it was being calculated again after the trigger.
(0002870)
Shinaa   
26-06-15 03:24   
This is not fixed. :(
Sphereserver: Jun 25 2015 (17:00:57) [build 2357]
Speedscalefactor = 80000
ARGN1 in @HitTry set to fix value: 30 (40)

Weapon A with SPEED=50
At 1 Stam: 3.2 (3.6)
At 100 Stam: 2.4 (2.8)
At 150 Stam: 2.2 (2.6)

Weapon B with SPEED=30
At 1 Stam: 4.6 (5.0)
At 100 Stam: 3.0 (3.4)
At 150 Stam: 2.6 (3.0)

Changing ARGN1 does affect the attackspeed somehow, I cannot in any way see what exactly the value represents (going from 40 to 30 increases speed by 0.4 sec, but why?), it's not tenth of seconds for anything and is still affected by current STAM and SPEED of the weapon after the trigger.
(0002873)
XuN   
27-06-15 09:48   
I have to invest why ... but right now the delay after the trigger is Delay / 2, so if you have 3.0, the delay to hit will be 1.5. This is absolute, i'm testing it right now with logs inside the source and it works.

realDelay = 37
Argn1 = 50

And I get this:
09:46:DEBUG:iTime = 37
09:46:DEBUG:HitTry: iTime = 37 , Argn1 = 87
09:46:DEBUG:TimeOut = 43 <-- this is the time you are waiting to hit.

As I said, I have ti check why is this divided by 2, until that you can simply 'normalize' it with a simple argn1 *=2.
(0002876)
Shinaa   
27-06-15 12:31   
That clears ARGN1, since speed can only be a multitude of 0.2, 10 / 2 = 5 rounded down to the nearest would be 0.4.

Now if it would not be affected by current STAM atleast (SPEED could be worked around I guess by setting all weapons to same speed and using a TAG for actual speed) after the trigger, one could work with it.
(0002881)
XuN   
27-06-15 12:44   
As I said, i'm going to see why is this happening (it must be a reason). This is a major change, I must first check out if this should happen before changing it.
(0002882)
Shinaa   
27-06-15 13:49   
(edited on: 27-06-15 13:50)
I already know why, run some tests after seeing the formula you posted in the other report. HitTry is triggered exactly between SwingStart and @Hit, which makes changing the real delay and the animationspeed impossible, because the animation is already playing. All you can do is increase or decrease the time until @Hit is fired by ARGN1/2 (min 0.2 sec), rounded to multitude of 0.2 (so 2.5 speed is not even possible).

Also the internal calculations of Sphere are nowhere near the calculations linked in the other report for attackspeed (http://uo.stratics.com/content/arms-armor/combat.php [^]), since it was liked why it uses STAM, I did some tests too:
1. SPEED is not the actual weapon speed like it is there. Tried bit and for a 2.5 Weapon Speed at 0 STAM I found SPEED=65 the closest thing (Real Speed 2.4, ARGN1=25).
2. Increasing STAM to 30 should have increased my attackspeed to 2.25, instead it jumped to 1.6 (ARGN1=17).
3. At STAM=60 it was already maxed out to 1.2 speed (ARGN1=12), which is the limit (correctly), but it should actually be at 150 STAM.

I see only two ways to actually fix that problem:
1. Make a function that is called, similar to the server functions, right after the internal calculations, if it returns a value, use it instead of the calculated one.

2. Change HitTry to actually fire after the calculations so it's values are really used for the attackspeed and animationspeed. This might of course break some things, especially if the trigger has a return 1.

(0002883)
XuN   
27-06-15 15:37   
Maybe the formula must be checked again, however it has nothing to do with the rest. It is working fine, you can modify the delay exactly to whatever you want ...you are going to loose 0.1 sometimes because of rounding, yes, but this is why I said that I'm going to look at this.

And for the anim delay, revisions.txt:

10-10-2014, XuN
Added local.anim and local.animDelay (this last one only working for classic clients) to @HitTry, so animations can be disabled and fired later in @hit (to remove the odd behaviour with new animation packets, which doesn't have delay).


local.AnimDelay is, by default, <argn1>/10.
This is the only relation they share until this point, so if you change argn1 the local.animdelay is not checked for changes anymore, to prevent problems if you want to have them different values, so you'll have to modify both.

For your both solutions:
1: There's actually a function retrieving the delay. There's no need to have such 'calculated one plus another one calculating it too', if the formula is not working fine then it should be checked again ... and, as I said 5 times, it's going to be.

2: HitTry actually fires AFTER the calculations: Calcs are stored in a variable, this variable is passed to @HitTry, value resulted from the trigger is stored in the variable again, the variable is used to set the timeout (yes, it's doing a weird /2 but i'm going to check it further).
(0002884)
Shinaa   
27-06-15 17:10   
Well the local.anim and local.animDelay helped with the animations, thats really cool, thanks. :)

After some more testing and using those variables I finally found a way to actually make HitTry do exactly the speed I want to, maybe it will help find the issue:

ON=@HITTRY
    ACTDIFF=100 //make it always hit for testing
    IF (<TAG0.MySpeed>)//Desired Speed set in a Tag
        LOCAL.RestSpeed=<EVAL <TAG0.MySpeed>-(<ARGN1>/2)>
        ARGN1=<EVAL <LOCAL.RestSpeed>*2>
        LOCAL.AnimDelay=<EVAL <ARGN1>/10>
    ENDIF

Of course this will have problems if ARGN1 becomes negative, but it's a test only and shows what actually happens:
The actual speed is somehow divided into two equal parts, the first part is not changeable in any way and will be influenced by STAM and SPEED of the weapon but is always unmodified ARGN1/2, the second part is ARGN1/2 after the trigger has been fired.
The second part is also the time between @HitTry and @Hit.
(0002885)
Shinaa   
27-06-15 17:26   
I just realized something: Could it be that the delay is recalculated in or after @Hit is fired? That would make total sense why it behaves like that and why I thought HitTry is fired later.
@HitTry --- ARGN1/2 time passes ---> @Hit is triggered ---> Sphere recalculates the rest of the delay but instead of using ARGN1 it recalculates it using the internal formula/2 ----> @HitTry Triggers
(0002905)
XuN   
08-07-15 10:41   
Should be fixed: https://www.dropbox.com/s/k1aqepw37wytzn9/SphereSvr.exe?dl=0 [^] , read latest changelog for the changes :)
(0002909)
Shinaa   
09-07-15 17:06   
(edited on: 09-07-15 17:08)
Nice addition, thank you. :)
But there seems to be a bug:
The second half of the speed is somehow lost now, it's always 0,2 sec (I assume its actually 0, because 0,2 is probably the tick time and I had exactly that results by setting speedscalefactor to 0 in previous build).
This makes all weapons faster and ARGN1 in @HitTry still incorrect.
It also makes no diffrence if ARGN1 is set in @HitTry or not, result is the same.
Ex: ARGN1=24
@HitTry fires --- 1,2 sec ---> @Hit fires --- 0,2 sec ---> @HitTry fires
No matter your stats or weapon, the right side will always be 0,2 sec while it should be ARGN1 - Time Passed.
While the left side is always correctly ARGN1/2 rounded up to the nearest multiple of 0,2.
Note: It can't be simply ARGN1/2 because if you have ARGN1=30, ARGN1/2 is 15, in the left part it will result in a 1,6 sec delay, because of the 0,2 sec ticks.

(0002911)
XuN   
10-07-15 08:10   
Nice find, i'll sustract a tick from the resulting delay.

There was a weird code in SpeedEras 2 & 3 adding a +25% delay, removed it, here you have the link with both fixes added: https://www.dropbox.com/s/k1aqepw37wytzn9/SphereSvr.exe?dl=0 [^]
(0002914)
Shinaa   
11-07-15 12:38   
Still same problem. :/
Second half after @Hit always 0.2 sec.
Tested with CombatSpeedEra=0 and 3.
(0002915)
XuN   
11-07-15 16:05   
iDelay = 0 = will prepare character to hit in next tick, so it's working fine.

If you want it to be instant you can just force it with something like this:
ON=@Hit
src.damage=<argn1>,<argn2>,<uid>
argn1=0 // argn1=0 instead of return 1 to let sphere do some other checks like skillgain.
(0002953)
XuN   
28-08-15 19:34   
Closing this as it's been solved, note that in latest builds AnimDelay is reduced by 7 to match OSI 'hit-and-wait' style, so to retrieve the old style just add:
local.AnimDelay = (<argn1>/10)-7
if (<local.animDelay> < 1 )
 local.AnimDelay = 1
endif