Hard formula needed! (call udg_AllTheHelper.netExperts)

Pharaoh_

The epic journey will soon begin... Prepare!
Reaction score
136
Hm, time to get things kinda hard. I need a formula, which seems to be difficult.
So, what i want:

A unit casts a skill on an enemy.
The system will count the Intelligence of the units.
So, we have INT1 (as of Intelligence of casting unit) and INT2 (as of Intelligence of target unit). The system will also count the level of the casting unit (let's name it z1) and the level of the target unit (let's name it z2). If their difference is a positive number, it means that z1>z2, but if we get a negative number, it means that z2>z1, so, the target unit has higher level than the casting unit.
The more INT the casting unit has (INT1), the greater the chance for the skill to have an actual effect on the target unit. But, the more INT the target unit has (INT2), the less the chance it becomes. Also, the levels: z1-z2. If this returns a positive value, the higher the value is, the greater the chance for the skill to work, but, if it returns a negative value, the greater the negative value, the less chance to work.

Now, those are the basic stuff. In order for the casted skill to work on the target unit, we get an x% chance to work.
The thing is i cannot combine those 3 factors: z1-z2, INT1, INT2 to finally make up the x% chance. I told you what are the factors and how they should work.

I have tried many methods, e.g. [(INT1/INT2) + (z1 - z2)] * 10, but, what happens is that the "x"(%) returns a greater value, when it comes to high-leveld units and low value when it comes to low-leveld units, even if the analogies are the same (e.g. 2 levels difference); it should for example work like:

Wrong result:
(Unit1) (Unit2)
INT 72 170
LVL 10 20

With the formula above ([(INT1/INT2) + (z1-z2)] * 10), it should become: (72/170) + (-10) = -95.76% chance. Well, it shouldn't have this result, cause the formula itself is wrong. But have a look for the same formula, with lower leveled units and of course, lower INT values.

Wrong result2:
(Unit1) (Unit2)
INT 23 69
LVL 1 10

Again, [(23/69) + (1-10)] * 10 = -86,6% chance. Oh well, how come? Because i have lower numbers, i get lower x%. I want the formula to have analogy!

Ideas on how to combine the factors needed or the formula itself! +Rep to helpful answers.
 

Pharaoh_

The epic journey will soon begin... Prepare!
Reaction score
136
Exactly, since i am going to use the Random Integer between and 0 and 100. So, i need this raw x value (forget the %). Limit of level is 40 and limit of Intelligence none, i guess. By the way, wc3's stat limit equals to 100? If so, damn, keep that in mind as well for the final formula formation.
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
(INT1 - INT2) + (LEV1 - LEV2) * some factor

example:

in first case, your caster has 50 intelligence and level 10, target has 40 intelligence and level 8:

( (50 - 40) + (10 - 8) ) * 1 = 12

in second case, your caster has 40 intelligence level 8, target 50 int, 10 lvl:

( (40 - 50) + (8 - 10) ) * 1 = -12

so you can use that returned value in this:

random integer number between 1 and 100 less than or equal to 15 + returned value

so in first case chance will be 27%, in second chance will be 3%

dunno if that's what you want though

EDIT: yeah the problem will be if the value gets to high, like Acehart said..

so if lets say value gets bellow -14 set it to -14 (because you don't want 0% chance) or if gets over +84 set it to 84 (cause you don't want perma effect, although 99% is close enough :p)

EDIT2: ok I tried
 

Pharaoh_

The epic journey will soon begin... Prepare!
Reaction score
136
This is not analogy, actually, and thank you for your try. This example just contains reversed data. On the first hand it has X intelligence and Y level for unit1 and S Intelligence and Z level for unit 2, when they become S & Z for unit1 and X & Y for unit2 afterwards. What i search for is that a 30 level hero has for example 20% chance to make the skill work on a 50 level hero, but a 10 level unit has an additional 20% chance to make the skill work on a 30 level hero. This was an example.
 

No_exit

Regular User (What is Custom User Title?)
Reaction score
40
You probably need a good ArcTangent function, it takes a number (which can be extremely high or low) and will return a number between -Pi/2 and +Pi/2. This function can be found in Jass under Atan (not Atan2).

So you are looking for something like

JASS:
constant real LEV_FACTOR = .35 
constant real INT_FACTOR = .015
constant real CENTER = 25. //These constant belong in a global block ofcourse

set resist = Atan(LEV_FACTOR * (LEV1 - LEV2) + INT_FACTOR * (INT1 - INT2) + Tan(bj_PI / 100. * (CENTER-50.))) * 100. / bj_PI + 50.)


will give you a number between 0 and 100. The LEV_FACTOR and INT_FACTOR can be changed according to how strong the int/level to have effect on the outcome of the resistance.

It will always give CENTER percent (here 25%) if both int's and level's are the same. Important: The center has to be between 0 and 100 and is not allowed to be 0 or 100.

Notice that Tan(bj_PI / 200. * (CENTER-50.)) is actually a constant so you can either cache it or just calculate it and display on screen and then replace the Tan by the value you seen displayed on the screen. If you want the center to be 50 then you can drop it altogether.

P.S.: The Atan function looks like this to give you a very rough idea of what the values will be like:
440px-Arctangent.svg.png


I hope this is what you need ;).

Edit:
I noticed that the above formula is not very nice for very high or very low centers (anything outside of the interval 30%-70% but the worst results is those you get in the really edges; for example 5% or 98%).

So a way of fixing this is the following:
JASS:
constant real LEV_FACTOR = .35 
constant real INT_FACTOR = .015
constant real CENTER = 25. //These constant belong in a global block ofcourse

set resist = Atan(LEV_FACTOR * (LEV1 - LEV2) + INT_FACTOR * (INT1 - INT2)) * 100. / bj_PI + 50.)
if CENTER > resist then
    set resist = resist * CENTER / 50.
else
    set resist = resist * (100. - CENTER) / 50. - 2*(50.-CENTER)
endif


Now what I do is stretch the "upperside" and the "lowerside" of the Atan function. For example if the center is now 10% then the lower part of the graph is scaled to 1/5 of it's original size and the upperpart is scaled to 9/5 of it's original size.

Do notice that changing the center now will influence the effect on the INT and LEV differences, so if you change the center then you might have to adapt the INT_FACTOR and LEV_FACTOR too.

Tell me if this is what you needed.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top