Difference between revisions of "Talk:GetRandomPercent"

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search
imported>JOG
(Clarification for first example.)
imported>Quetzilla
(→‎Example: force float)
 
(11 intermediate revisions by 5 users not shown)
Line 1: Line 1:
== Morrowind's Random100 ==
Is this similar to ''Morrowind's'' Random100 function, or can it be used in the same manner? [[User:TheImperialDragon|The Imperial Dragon]] 12:58, 11 June 2006 (EDT)
Is this similar to ''Morrowind's'' Random100 function, or can it be used in the same manner? [[User:TheImperialDragon|The Imperial Dragon]] 12:58, 11 June 2006 (EDT)


----
:'''Random100''' (as one word) in Morrowind was a global that was set to 0-100 once per frame (in the script "Main")
 
'''Random100''' (as one word) in Morrowind was a global that was set to 0-100 once per frame (in the script "Main")


  set variable to GetRandomPercent  
  set variable to GetRandomPercent  
in Oblivion is the same as  
:in Oblivion is the same as  


  set variable to Random 100
  set variable to Random 100
in Morrowind and will return a new random number ranging from 0-99 whenever you call it.
:in Morrowind and will return a new random number ranging from 0-99 whenever you call it.
:--[[User:JOG|JOG]] 13:40, 11 June 2006 (EDT)
 
::I see, thank you. [[User:TheImperialDragon|The Imperial Dragon]] 13:44, 11 June 2006 (EDT)


--[[User:JOG|JOG]] 13:40, 11 June 2006 (EDT)
== Example ==


I see, thank you. [[User:TheImperialDragon|The Imperial Dragon]] 13:44, 11 June 2006 (EDT)
[[User:JOG|JOG]] 17:33, 29 July 2006 (EDT): Here's the math behind the first example:
 
short dice
set dice to 1 + 0.06 * GetRandompercent 
 
 
int(1 + 0.06 * '''00''') = int(1 + 0.00) = int(1.00) = '''1'''
 
int(1 + 0.06 * '''16''') = int(1 + 0.96) = int(1.96) = '''1''' => Chance: 17%
 
int(1 + 0.06 * '''17''') = int(1 + 1.02) = int(2.02) = '''2'''
 
int(1 + 0.06 * '''33''') = int(1 + 1.98) = int(2.98) = '''2''' => Chance: 17%
 
int(1 + 0.06 * '''34''') = int(1 + 2.02) = int(3.02) = '''3'''
 
int(1 + 0.06 * '''49''') = int(1 + 2.94) = int(3.94) = '''3''' => Chance: 16%
 
int(1 + 0.06 * '''50''') = int(1 + 3.00) = int(4.00) = '''4'''
 
int(1 + 0.06 * '''66''') = int(1 + 3.96) = int(4.96) = '''4''' => Chance: 17%
 
int(1 + 0.06 * '''67''') = int(1 + 4.02) = int(5.02) = '''5'''
 
int(1 + 0.06 * '''83''') = int(1 + 4.98) = int(5.98) = '''5''' => Chance: 17%
 
int(1 + 0.06 * '''84''') = int(1 + 5.04) = int(6.04) = '''6'''
 
int(1 + 0.06 * '''99''') = int(1 + 5.94) = int(6.94) = '''6''' => Chance: 16%


----


Here's the math behind the first example:


  short dice
  short dice
  set dice to 1 + 0.06 * GetRandompercent  
  set dice to 6.0/99 * GetRandompercent
 
 
Is the loaded variant and returns this:
 
 
int(6/99 * '''00''') = int(0.00) = '''0'''
 
int(6/99 * '''16''') = int(0.97) = '''0''' => Chance: 17%
 
int(5/99 * '''17''') = int(1.03) = '''1'''
 
int(5/99 * '''32''') = int(1.94) = '''1''' => Chance: 16%
 
int(5/99 * '''33''') = int(2.00) = '''2'''
 
int(5/99 * '''49''') = int(2.97) = '''2''' => Chance: 17%
 
int(5/99 * '''50''') = int(3.03) = '''3'''
 
int(5/99 * '''65''') = int(3.94) = '''3''' => Chance: 16%
 
int(5/99 * '''66''') = int(4.00) = '''4'''
 
int(5/99 * '''82''') = int(4.97) = '''4''' => Chance: 17%
 
int(5/99 * '''83''') = int(5.03) = '''5'''
 
int(5/99 * '''98''') = int(5.94) = '''5''' => Chance: 16%
 
int(5/99 * '''99''') = int(6.00) = '''6''' => Chance: 1%
 
== Alternative up to 50 ==
 
Seems to me that for Random Numbers up to 50 you can use this Syntax:
 
short var
  Set var to ( GetRandomPercent % <2..50> ) + 1
 
Where "Percent Sign" is the Modulus Operator...
 
Should effectively give every value 2 thru 50 an equal chance...
[[User:Dejunai|Dejunai]] 13:38, 31 August 2006 (EDT)
 
:Hehe, don't betray all the secrets of the "cryptic" coders :)--[[User:JOG|JOG]] 14:02, 31 August 2006 (EDT)


=>
== Algorithm ==


1 + int(0.06 * '''0''') = 1 + 0 = 1
Here's the hex of the function
1 + int(0.06 * '''99''') = 1 + int(5.94) ) 1 + 5 = 6
<pre>call    sub_47DDA0; returns system time? calls GetSystemTimeAsFileTime
mov    edi, eax
mov    eax, 0AE147AE1h; or some other constant
imul    edi
sar    edx, 5
mov    eax, edx
shr    eax, 1Fh
add    eax, edx
imul    eax, 64h
add    edi, eax</pre>
From Ian Patterson "That function is a wrapper around MS' stdlib rand that calls srand(time(NULL)) if it hasn't been seeded yet. It only uses the system timer once. The rest of the code is just some modular arithmetic done in fixed point."--[[User:Haama|Haama]] 13:42, 25 May 2008 (EDT)
: Should add that Ian's point was, GetRandomPercent is not especially random. Use [[rand]] instead if that is important. [[User:Scruggs|Scruggs]] 23:33, 13 August 2008 (EDT)

Latest revision as of 16:41, 20 December 2008

Morrowind's Random100[edit source]

Is this similar to Morrowind's Random100 function, or can it be used in the same manner? The Imperial Dragon 12:58, 11 June 2006 (EDT)

Random100 (as one word) in Morrowind was a global that was set to 0-100 once per frame (in the script "Main")
set variable to GetRandomPercent 
in Oblivion is the same as
set variable to Random 100
in Morrowind and will return a new random number ranging from 0-99 whenever you call it.
--JOG 13:40, 11 June 2006 (EDT)
I see, thank you. The Imperial Dragon 13:44, 11 June 2006 (EDT)

Example[edit source]

JOG 17:33, 29 July 2006 (EDT): Here's the math behind the first example:

short dice
set dice to 1 + 0.06 * GetRandompercent  


int(1 + 0.06 * 00) = int(1 + 0.00) = int(1.00) = 1

int(1 + 0.06 * 16) = int(1 + 0.96) = int(1.96) = 1 => Chance: 17%

int(1 + 0.06 * 17) = int(1 + 1.02) = int(2.02) = 2

int(1 + 0.06 * 33) = int(1 + 1.98) = int(2.98) = 2 => Chance: 17%

int(1 + 0.06 * 34) = int(1 + 2.02) = int(3.02) = 3

int(1 + 0.06 * 49) = int(1 + 2.94) = int(3.94) = 3 => Chance: 16%

int(1 + 0.06 * 50) = int(1 + 3.00) = int(4.00) = 4

int(1 + 0.06 * 66) = int(1 + 3.96) = int(4.96) = 4 => Chance: 17%

int(1 + 0.06 * 67) = int(1 + 4.02) = int(5.02) = 5

int(1 + 0.06 * 83) = int(1 + 4.98) = int(5.98) = 5 => Chance: 17%

int(1 + 0.06 * 84) = int(1 + 5.04) = int(6.04) = 6

int(1 + 0.06 * 99) = int(1 + 5.94) = int(6.94) = 6 => Chance: 16%


short dice
set dice to 6.0/99 * GetRandompercent 


Is the loaded variant and returns this:


int(6/99 * 00) = int(0.00) = 0

int(6/99 * 16) = int(0.97) = 0 => Chance: 17%

int(5/99 * 17) = int(1.03) = 1

int(5/99 * 32) = int(1.94) = 1 => Chance: 16%

int(5/99 * 33) = int(2.00) = 2

int(5/99 * 49) = int(2.97) = 2 => Chance: 17%

int(5/99 * 50) = int(3.03) = 3

int(5/99 * 65) = int(3.94) = 3 => Chance: 16%

int(5/99 * 66) = int(4.00) = 4

int(5/99 * 82) = int(4.97) = 4 => Chance: 17%

int(5/99 * 83) = int(5.03) = 5

int(5/99 * 98) = int(5.94) = 5 => Chance: 16%

int(5/99 * 99) = int(6.00) = 6 => Chance: 1%

Alternative up to 50[edit source]

Seems to me that for Random Numbers up to 50 you can use this Syntax:

short var
Set var to ( GetRandomPercent % <2..50> ) + 1

Where "Percent Sign" is the Modulus Operator...

Should effectively give every value 2 thru 50 an equal chance... Dejunai 13:38, 31 August 2006 (EDT)

Hehe, don't betray all the secrets of the "cryptic" coders :)--JOG 14:02, 31 August 2006 (EDT)

Algorithm[edit source]

Here's the hex of the function

call    sub_47DDA0; returns system time? calls GetSystemTimeAsFileTime
mov     edi, eax
mov     eax, 0AE147AE1h; or some other constant
imul    edi
sar     edx, 5
mov     eax, edx
shr     eax, 1Fh
add     eax, edx
imul    eax, 64h
add     edi, eax

From Ian Patterson "That function is a wrapper around MS' stdlib rand that calls srand(time(NULL)) if it hasn't been seeded yet. It only uses the system timer once. The rest of the code is just some modular arithmetic done in fixed point."--Haama 13:42, 25 May 2008 (EDT)

Should add that Ian's point was, GetRandomPercent is not especially random. Use rand instead if that is important. Scruggs 23:33, 13 August 2008 (EDT)