BUG comparing fix32 values, request for change

GPC2 script programming for Titan Two. Code examples, questions, requests.

BUG comparing fix32 values, request for change

Postby Kiriller1337 » Wed Aug 18, 2021 9:23 pm

Dear All,

I was playing around with GPC2 scripting and I found some strange issue when comparing fix32 values.

The issue is as following when you want to sum or substract decimal numbers.

For example:

float antirecoil_Y = 1.7;

when you do the following a couple of times:

antirecoil_Y += 0.1;

The output is as following when you set 6 decimals:
Image


This doesn't seem like a real problem, but the problem occurs when you are trying to do comparisons

1.800003
if(antirecoil_Y ==1.8) --> true
1.900009
if(antirecoil_Y ==1.9) --> false
2.000015
if(antirecoil_Y ==2.0) --> false

This is pretty annoying because there is no function for setting rounding on decimal places or setting a precision, basically what would be awesome if we get a function or a method for setting decimal precision so we won't get surprise numbers.

A simple solution could be the following reusing the printf("%.2f", x); function so we can write strings and compare these as following:

char number[24]; // dummy size, you should take care of the size!
sprintf(number, "%.2f", 37.777779);
User avatar
Kiriller1337
Private
Private
 
Posts: 1
Joined: Wed Aug 18, 2021 8:59 pm

Re: BUG comparing fix32 values, request for change

Postby bonefisher » Thu Aug 19, 2021 1:41 am

Code: Select all
 
/* *****************************************************************************
<cfgdesc>
 
[Rapidfire Settings]
color          = #008000
collapsible    = 2
shortdesc      = Enable Rapid Fire?
byteoffset     = 0
bitsize        = 1
bitoffset      = 7
control        = checkbox
default        = 1
item           = Rapidfire ON
 
[RAPID FIRE SETTINGS]
group          = true
shortdesc      = FIRE TRIGGER HOLD: Set to desired hold length in milliseconds.
byteoffset     = 1
bitsize        = 32
control        = spinboxf
default        = 633
minimum        = 0
maximum        = 10000
step           = 01
decimals       = 1
 
[Release Time Settings]
group          = true
shortdesc      = FIRE TRIGGER RELEASED: Set to desired release length in milliseconds.
byteoffset     = 5
bitsize        = 32
control        = spinboxf
default        = 167
minimum        = 0
maximum        = 10000
step           = 01
decimals       = 1
 
[Anti Recoil Settings]
color          = #008000
collapsible    = 2
shortdesc      = Enable Anti Recoil?
byteoffset     = 9
bitsize        = 1
bitoffset      = 7
control        = checkbox
default        = 1
item           = Anti Recoil ON
 
[Anti Recoil Delay]
group          = true
shortdesc      = Anti Recoil Delay (In MS) after fire button is pressed.
byteoffset     = 10
bitsize        = 16
control        = slider
default        = 0
minimum        = 0
maximum        = 1000
step           = 5
 
[Min Anti Recoil Percent]
group          = true
shortdesc      = Minimum Percentage of Anti Recoil to apply during aim stick movement.
byteoffset     = 12
bitsize        = 32
control        = spinboxf
default        = 200
minimum        = 0
maximum        = 1000
step           = 100
decimals       = 1
 
[Stick Noise Remover]
group          = true
shortdesc      = Stick Noise. Set to the resting dead zone values for your right stick.
byteoffset     = 16
bitsize        = 32
control        = spinboxf
default        = 650
minimum        = 0
maximum        = 10000
step           = 100
decimals       = 2
 
[Standing Anti Recoil Settings]
group          = true
shortdesc      = Anti Recoil: vertical pull force compensation.
byteoffset     = 20
bitsize        = 32
control        = spinboxf
default        = 1800
minimum        = -10000
maximum        = 10000
step           = 30
decimals       = 2
 
[Standing Anti Recoil H Settings]
group          = true
shortdesc      = Anti Recoil: horizontal pull force compensation.
byteoffset     = 24
bitsize        = 32
control        = spinboxf
default        = 00000
minimum        = -10000
maximum        = 10000
step           = 30
decimals       = 2
 
</cfgdesc>
***************************************************************************** */

/* Special credits goes out to AryanX for a awesome anti-recoil script!*/
 
#define float  fix32
#define wait(a)  wait((int)a);
bool bUseRapidFire;
//Anti Recoil
bool bUseAntiRecoil;
float ARecoil_H;
float ARecoil_V;
uint16 ARecoilDelay;
float MinARecoilPercent;
float StickNoise;
int hold_time, rest_time;
 
init
{
    pmem_load();
bUseRapidFire = (pmem_read(0) >> 7) & 0b1;
pmem_read(1, &hold_time);
pmem_read(5, &rest_time);
 
bUseAntiRecoil = (pmem_read(9) >> 7) & 0b1;
pmem_read(10, &ARecoilDelay);
pmem_read(12, &MinARecoilPercent);
pmem_read(16, &StickNoise);
pmem_read(20, &ARecoil_V);
pmem_read(24, &ARecoil_H);
}
 
main {
            if (abs(get_actual(STICK_1_X)) < StickNoise) set_val(STICK_1_X, 0.0);
            if (abs(get_actual(STICK_1_Y)) < StickNoise) set_val(STICK_1_Y, 0.0);
            if (abs(get_actual(STICK_2_X)) < StickNoise) set_val(STICK_2_X, 0.0);
            if (abs(get_actual(STICK_2_Y)) < StickNoise) set_val(STICK_2_Y, 0.0);
 
    if(bUseRapidFire)
    {
    if(get_val(BUTTON_5))
    {
      combo_run(RapidFire);
    }
    else if(RapidFire)
    {
        combo_stop(RapidFire);
    }
    }
  //////////////////////////////////////////////////////////////////////////
    //Anti Recoil
    //////////////////////////////////////////////////////////////////////////
    if (bUseAntiRecoil)
    {
 
        if (get_actual(BUTTON_5) && time_active(BUTTON_5) >= ARecoilDelay)
        {
 
        if (get_val(BUTTON_5))
        {
 
            AntiRecoil(STICK_1_X, ARecoil_H);
            AntiRecoil(STICK_1_Y, ARecoil_V);
        }
        }
    }
}
 
combo RapidFire
{
    set_val(BUTTON_5, hold_time ? 100.0 : 0.0);
    wait(hold_time);
    set_val(BUTTON_5, rest_time ? 0.0 : 100.0);
    wait(rest_time);
    set_val(BUTTON_5, rest_time ? 0.0 : 100.0);
}
 
void AntiRecoil(uint8 AxisToApply, float ARecoilToApply)
{
    float CurrentX = get_val(STICK_1_X);
    float CurrentY = get_val(STICK_1_Y);
    float MinARecoilFactor = MinARecoilPercent / 100.0;
    float MinARecoilToApply = MinARecoilFactor * ARecoilToApply;
    //This sets the ARecoil to be dependent on both X and Y axis movement. With more emphasis on Y
    float MovementARecoilToApply = (1.0 - MinARecoilFactor) * ((ARecoilToApply * (100.0 - sqrt(CurrentX*CurrentX + CurrentY*CurrentY))) / (100.0 + abs(CurrentX) + (CurrentY*CurrentY*0.5)));
    set_val(AxisToApply,clamp(MinARecoilToApply + MovementARecoilToApply + get_actual(AxisToApply),-100.00,100.00));
}
 

you can set it up in Interactive Configurations how you want it! Hope this helps! :smile0517:
bonefisher
Lieutenant General
Lieutenant General
 
Posts: 5413
Joined: Thu Jan 29, 2015 10:49 am


Return to GPC2 Script Programming

Who is online

Users browsing this forum: midg3t2, trezor and 118 guests