Self loading anti-recoil!

GPC script programming for Titan Two device. Code examples, how to, questions, requests.

Moderators: The_Rabid_Taco, pablosscripts, bonefisher

Re: Self loading anti-recoil!

Postby bonefisher » Mon Apr 15, 2019 1:45 pm

undazpoon wrote:Does anyone know why My Gtuner just crash when I compile this script?

There has been a known issue with the FFB's and yes mine does it every once in a while but I still love using this! :innocent_smile_1:
bonefisher
Major General
Major General
 
Posts: 5013
Joined: Thu Jan 29, 2015 10:49 am

Re: Self loading anti-recoil!

Postby Mochi » Mon Apr 15, 2019 2:18 pm

TrayDay wrote:
jelly44 wrote:Thank you for sharing it, TrayDay.

So just to see if I understand the beauty / logic of the script.

Each gun has a given FFB, that can be either 1 or 2 depending on the game, right? Or does the value varies per platform (PC, PS$, XB1) ? (Battlefield 5 gives values under 1 and 2, so I'm not sure what to do there.)

Is the value for STICK_1_X the vertical recoil and STICK_1_Y horizontal?

Correct, each gun have a distinct FBB, and when you check the gtuner you'll see the value of FBB_2 change when you shoot, FBB_1 will be 100 and FBB_2 will be the gun as each will vary, but you get a general idea of what the value is by hold R2/RT. While this also may depend on the controller you're using as well. But once you see the value, basically the way bonefisher have the script is any FBB values between > ...... < will be detected, the script will then use the Stick Value as you have correctly, STICK_1_X the vertical recoil and STICK_1_Y horizontal, it will be triggered. Also, you're right, I believe that's the next script bonefisher is working on, as he understands that dearly. As there's a gun in Apex that also uses both values, so I'm also interested as well.

EDIT: Also in the script I posted, I forgot to change the first value of the function, here are the correct values for them

Code: Select all
#pragma METAINFO("APEX LEGENDS rumble anti recoil", 1, 0, "bonefisher")
 
#define float  fix32
#define wait(a)  wait((int)a);
//Anti Recoil
bool bUseAntiRecoil = 1;
uint16 ARecoilDelay = 0;
float MinARecoilPercent = 20.0;
float StickNoise = 13.00;
 
main {
  //////////////////////////////////////////////////////////////////////////
    //Anti Recoil
    //////////////////////////////////////////////////////////////////////////
    if (bUseAntiRecoil)
    {
        if (get_actual(BUTTON_5) && time_active(BUTTON_5) >= ARecoilDelay)
        {
            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(ffb_get(FFB_2, NULL) > 25.0 && ffb_get(FFB_2, NULL) < 34.0)
        {
            if(get_actual(BUTTON_5))combo_run(RapidFire);
            AntiRecoil(STICK_1_X, 0.0);
            AntiRecoil(STICK_1_Y, 60.0);
        }
        if(ffb_get(FFB_2, NULL) > 35.0 && ffb_get(FFB_2, NULL) < 45.0)
        {
            if(get_actual(BUTTON_5))combo_run(RapidFire);
            AntiRecoil(STICK_1_X, 0.0);
            AntiRecoil(STICK_1_Y, 45.0);
        }
        if(ffb_get(FFB_2, NULL) > 50.0 && ffb_get(FFB_2, NULL) < 70.0)
        {
            if(get_actual(BUTTON_5))combo_run(RapidFire);
            AntiRecoil(STICK_1_X, 0.0);
            AntiRecoil(STICK_1_Y, 55.0);
        }
        if(ffb_get(FFB_2, NULL) > 39.0 && ffb_get(FFB_2, NULL) < 40.0)
        {
            if(get_actual(BUTTON_5))combo_run(RapidFire);
            AntiRecoil(STICK_1_X, 0.0);
            AntiRecoil(STICK_1_Y, 32.0);
        }
        }
    }
}
 
main{
if(get_actual(BUTTON_5))combo_run(RapidFire);
}
combo RapidFire
{
wait(30);
set_val(BUTTON_5, 0);
wait(30);
}
 
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_val(AxisToApply),-100.00,100.00 - MinARecoilToApply));
}
 
 


Thank you for sharing your changes.

Just wondering, for your settings, which guns are for this subset?

if(ffb_get(FFB_2, NULL) > 39.0 && ffb_get(FFB_2, NULL) < 40.0)
User avatar
Mochi
Sergeant First Class
Sergeant First Class
 
Posts: 17
Joined: Wed Mar 20, 2019 8:02 am

Re: Self loading anti-recoil!

Postby Dannyeliya21 » Mon Apr 15, 2019 5:54 pm

Thanks for sharing this script Bonefisher, i tried it and with the help of @Buffy and @Don't i can confirm this script does not work for PUBG.
User avatar
Dannyeliya21
Private First Class
Private First Class
 
Posts: 3
Joined: Sun Apr 07, 2019 7:59 pm

Re: Self loading anti-recoil!

Postby bonefisher » Mon Apr 15, 2019 6:42 pm

Dannyeliya21 wrote:Thanks for sharing this script Bonefisher, i tried it and with the help of @Buffy and @Don't i can confirm this script does not work for PUBG.

Yeah didn't think it would work in all games! Thanks for info!
bonefisher
Major General
Major General
 
Posts: 5013
Joined: Thu Jan 29, 2015 10:49 am

Re: Self loading anti-recoil!

Postby TrayDay » Mon Apr 15, 2019 10:34 pm

Mochi wrote:
TrayDay wrote:
jelly44 wrote:Thank you for sharing it, TrayDay.

So just to see if I understand the beauty / logic of the script.

Each gun has a given FFB, that can be either 1 or 2 depending on the game, right? Or does the value varies per platform (PC, PS$, XB1) ? (Battlefield 5 gives values under 1 and 2, so I'm not sure what to do there.)

Is the value for STICK_1_X the vertical recoil and STICK_1_Y horizontal?

Correct, each gun have a distinct FBB, and when you check the gtuner you'll see the value of FBB_2 change when you shoot, FBB_1 will be 100 and FBB_2 will be the gun as each will vary, but you get a general idea of what the value is by hold R2/RT. While this also may depend on the controller you're using as well. But once you see the value, basically the way bonefisher have the script is any FBB values between > ...... < will be detected, the script will then use the Stick Value as you have correctly, STICK_1_X the vertical recoil and STICK_1_Y horizontal, it will be triggered. Also, you're right, I believe that's the next script bonefisher is working on, as he understands that dearly. As there's a gun in Apex that also uses both values, so I'm also interested as well.

EDIT: Also in the script I posted, I forgot to change the first value of the function, here are the correct values for them

Code: Select all
#pragma METAINFO("APEX LEGENDS rumble anti recoil", 1, 0, "bonefisher")
 
#define float  fix32
#define wait(a)  wait((int)a);
//Anti Recoil
bool bUseAntiRecoil = 1;
uint16 ARecoilDelay = 0;
float MinARecoilPercent = 20.0;
float StickNoise = 13.00;
 
main {
  //////////////////////////////////////////////////////////////////////////
    //Anti Recoil
    //////////////////////////////////////////////////////////////////////////
    if (bUseAntiRecoil)
    {
        if (get_actual(BUTTON_5) && time_active(BUTTON_5) >= ARecoilDelay)
        {
            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(ffb_get(FFB_2, NULL) > 25.0 && ffb_get(FFB_2, NULL) < 34.0)
        {
            if(get_actual(BUTTON_5))combo_run(RapidFire);
            AntiRecoil(STICK_1_X, 0.0);
            AntiRecoil(STICK_1_Y, 60.0);
        }
        if(ffb_get(FFB_2, NULL) > 35.0 && ffb_get(FFB_2, NULL) < 45.0)
        {
            if(get_actual(BUTTON_5))combo_run(RapidFire);
            AntiRecoil(STICK_1_X, 0.0);
            AntiRecoil(STICK_1_Y, 45.0);
        }
        if(ffb_get(FFB_2, NULL) > 50.0 && ffb_get(FFB_2, NULL) < 70.0)
        {
            if(get_actual(BUTTON_5))combo_run(RapidFire);
            AntiRecoil(STICK_1_X, 0.0);
            AntiRecoil(STICK_1_Y, 55.0);
        }
        if(ffb_get(FFB_2, NULL) > 39.0 && ffb_get(FFB_2, NULL) < 40.0)
        {
            if(get_actual(BUTTON_5))combo_run(RapidFire);
            AntiRecoil(STICK_1_X, 0.0);
            AntiRecoil(STICK_1_Y, 32.0);
        }
        }
    }
}
 
main{
if(get_actual(BUTTON_5))combo_run(RapidFire);
}
combo RapidFire
{
wait(30);
set_val(BUTTON_5, 0);
wait(30);
}
 
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_val(AxisToApply),-100.00,100.00 - MinARecoilToApply));
}
 
 


Thank you for sharing your changes.

Just wondering, for your settings, which guns are for this subset?

if(ffb_get(FFB_2, NULL) > 39.0 && ffb_get(FFB_2, NULL) < 40.0)


I didn't necessarily change anything for this value, I just did this to not interfere with my settings of the previous three. But I'm going to possibly change this for the longbow or triple take. Once I test them and find the values.
User avatar
TrayDay
First Sergeant
First Sergeant
 
Posts: 54
Joined: Wed Nov 02, 2016 11:12 pm

Re: Self loading anti-recoil!

Postby undazpoon » Tue Apr 16, 2019 9:10 am

As a just drag-and-drop guy, I'm trying to figure out how to use this script.
First, how to turn on rumble on T2? I'm using Xim apex(keyboard, mouse) with T2.

EDIT: Self-solution. I have to get rid of Xim apex and connect dual shock to T2 not through Xim apex.
Last edited by undazpoon on Tue Apr 16, 2019 12:25 pm, edited 1 time in total.
User avatar
undazpoon
Sergeant First Class
Sergeant First Class
 
Posts: 19
Joined: Fri Nov 18, 2016 2:52 am

Re: Self loading anti-recoil!

Postby DontAtMe » Tue Apr 16, 2019 10:32 am

Here is a script that detects all 6 weapon-groups in Apex Legends.
This will only work for Xbox One btw.

Code: Select all
const uint8 ads_button = BUTTON_8;
const uint8 fire_button = BUTTON_5;
 
int8 group,weapon_group, bcount, flag1, temp;
main {
#define ffb_get_actual(a) ffb_get_actual(a, 0)
  static unsigned long int timer_0;
 
  ffb_capture(ffb_get_actual(FFB_2));
  set_val(20, flag1);
 
  if (event_release(ads_button)) flag1 = 0;
 
  if (is_active(fire_button)) {
    timer_0 += elapsed_time();
  } else timer_0 = 0;
 
  if (is_active(fire_button) && is_active(ads_button)) {
    if (get_val(20) == 75f && !temp) {
      ++bcount;
      if (timer_0 > 200) goto skip_print;
      switch (group) {
      case 1:
        printf("<center><pre><font size='+2'><b>Group 1 = </b></font>ALTERNATOR, PROWLER, R-99<font size='+2'><b><font size='+2'><b><br>   Round(s) Fired: <font color='red'><b>%-02d</b></font> | Last Round Fired <font color='blue'>%-03d</font>ms ago</font>", bcount, bcount == 1 ? 0 : timer_0);
        break;
      case 2:
        printf("<center><pre><font size='+2'><b>Group 2 = </b></font>DEVOTION, FLATLINE, HAVOC, HEMLOCK, R-301, SPITFIRE<font size='+2'><b><font size='+2'><b><br>   Round(s) Fired: <font color='red'><b>%-02d</b></font> | Last Round Fired <font color='blue'>%-03d</font>ms ago</font>", bcount, bcount == 1 ? 0 : timer_0);
        break;
      case 3:
        printf("<center><pre><font size='+2'><b>Group 3 = </b></font>PP2020, RE-45<font size='+2'><b><font size='+2'><b><br>   Round(s) Fired: <font color='red'><b>%-02d</b></font> | Last Round Fired <font color='blue'>%-03d</font>ms ago</font>", bcount, bcount == 1 ? 0 : timer_0);
        break;
      case 4:
        printf("<center><pre><font size='+2'><b>Group 4 = </b></font>Eva-B AUTO, PACEKEEPER<font size='+2'><b><font size='+2'><b><br>   Round(s) Fired: <font color='red'><b>%-02d</b></font> | Last Round Fired <font color='blue'>%-03d</font>ms ago</font>", bcount, bcount == 1 ? 0 : timer_0);
        break;
      case 5:
        printf("<center><pre><font size='+2'><b>Group 5 = </b></font>MOZAMBIQUE, WINGMAN<font size='+2'><b><font size='+2'><b><br>   Round(s) Fired: <font color='red'><b>%-02d</b></font> | Last Round Fired <font color='blue'>%-03d</font>ms ago</font>", bcount, bcount == 1 ? 0 : timer_0);
        break;
      case 6:
        printf("<center><pre><font size='+2'><b>Group 6 = </b></font>G7 SCOUTE, KRABER, LONGBOW, TRIPPLE TAKE");
 
      }
      skip_print: timer_0 = 0;
      temp = TRUE;
    } else if (temp && get_val(20) != 75f) temp = FALSE;
 
  } else bcount = FALSE;
 
  if (ffb_get_actual(FFB_3) == 0.00) weapon_group = 0;
 
  if (is_active(fire_button)) {
    if (check_active(ads_button, time_active(ads_button) - time_active(fire_button))) {
        detect_weapon();
    } else weapon_group = 0;
  }
 
  static unsigned long int ts3,ts,prev_ts;
  static uint8 pcount;
  if (bcount) {
    if (bcount != pcount) {
      ts = time_active(fire_button) < 0 ? 0 : time_active(fire_button);
      ts = ts - prev_ts < 0 ? 0 : ts;
      if (ts3 != system_time()) {
        ts3 = system_time();
      }
      prev_ts = ts;
      pcount = bcount;
    }
  }
}
 
void ffb_capture(fix32 val) {
  static fix32 lval;
 
  if (val) {
    if (lval != val) {
      if (lval > val) {
        flag1 = 75;
      } else if (lval < val) {
        flag1 = 0;
      }
      lval = val;
    }
  }
}
 
void detect_weapon() {
 
  fix32 captured_ffb = (ffb_get_actual(FFB_3) * 255f / 100f) * 10f;
 
  if (!weapon_group) {
    switch (detect_group(captured_ffb)) {
    case 1:
      weapon_group = 1;
      break;
    case 2:
      weapon_group = 2;
      break;
    case 3:
      weapon_group = 3;
      break;
    case 4:
      weapon_group = 4;
      break;
    case 5:
      weapon_group = 5;
      break;
    case 6:
      weapon_group = 6;
      break;
    default:;
    }
  } else {
    static int oldw;
    if (oldw != weapon_group)
      oldw = group = weapon_group;
    if (event_active((13)))
      weapon_group = 0;
  }
}
 
uint8 detect_group(fix32 v) {
  if (v > 80f) return 5;
  else if (v > 65f) return 4;
  else if (v > 55f && ffb_get_actual(FFB_1) > 39f) return 6;
  else if (v > 55f) return 3;
  else if (v > 35f) return 2;
  else if (v > 25f) return 1;
  return 0;
}
 

I did not include any anti-recoil with this yet, I was only interested in capturing each weapon group.
I also implement a bullet tracking feature, which can help narrow down the exact weapon being fired.
User avatar
DontAtMe
Master Sergeant
Master Sergeant
 
Posts: 39
Joined: Tue Oct 02, 2018 4:49 am

Re: Self loading anti-recoil!

Postby bonefisher » Tue Apr 16, 2019 2:32 pm

DontAtMe wrote:Here is a script that detects all 6 weapon-groups in Apex Legends.
This will only work for Xbox One btw.

Code: Select all
const uint8 ads_button = BUTTON_8;
const uint8 fire_button = BUTTON_5;
 
int8 group,weapon_group, bcount, flag1, temp;
main {
#define ffb_get_actual(a) ffb_get_actual(a, 0)
  static unsigned long int timer_0;
 
  ffb_capture(ffb_get_actual(FFB_2));
  set_val(20, flag1);
 
  if (event_release(ads_button)) flag1 = 0;
 
  if (is_active(fire_button)) {
    timer_0 += elapsed_time();
  } else timer_0 = 0;
 
  if (is_active(fire_button) && is_active(ads_button)) {
    if (get_val(20) == 75f && !temp) {
      ++bcount;
      if (timer_0 > 200) goto skip_print;
      switch (group) {
      case 1:
        printf("<center><pre><font size='+2'><b>Group 1 = </b></font>ALTERNATOR, PROWLER, R-99<font size='+2'><b><font size='+2'><b><br>   Round(s) Fired: <font color='red'><b>%-02d</b></font> | Last Round Fired <font color='blue'>%-03d</font>ms ago</font>", bcount, bcount == 1 ? 0 : timer_0);
        break;
      case 2:
        printf("<center><pre><font size='+2'><b>Group 2 = </b></font>DEVOTION, FLATLINE, HAVOC, HEMLOCK, R-301, SPITFIRE<font size='+2'><b><font size='+2'><b><br>   Round(s) Fired: <font color='red'><b>%-02d</b></font> | Last Round Fired <font color='blue'>%-03d</font>ms ago</font>", bcount, bcount == 1 ? 0 : timer_0);
        break;
      case 3:
        printf("<center><pre><font size='+2'><b>Group 3 = </b></font>PP2020, RE-45<font size='+2'><b><font size='+2'><b><br>   Round(s) Fired: <font color='red'><b>%-02d</b></font> | Last Round Fired <font color='blue'>%-03d</font>ms ago</font>", bcount, bcount == 1 ? 0 : timer_0);
        break;
      case 4:
        printf("<center><pre><font size='+2'><b>Group 4 = </b></font>Eva-B AUTO, PACEKEEPER<font size='+2'><b><font size='+2'><b><br>   Round(s) Fired: <font color='red'><b>%-02d</b></font> | Last Round Fired <font color='blue'>%-03d</font>ms ago</font>", bcount, bcount == 1 ? 0 : timer_0);
        break;
      case 5:
        printf("<center><pre><font size='+2'><b>Group 5 = </b></font>MOZAMBIQUE, WINGMAN<font size='+2'><b><font size='+2'><b><br>   Round(s) Fired: <font color='red'><b>%-02d</b></font> | Last Round Fired <font color='blue'>%-03d</font>ms ago</font>", bcount, bcount == 1 ? 0 : timer_0);
        break;
      case 6:
        printf("<center><pre><font size='+2'><b>Group 6 = </b></font>G7 SCOUTE, KRABER, LONGBOW, TRIPPLE TAKE");
 
      }
      skip_print: timer_0 = 0;
      temp = TRUE;
    } else if (temp && get_val(20) != 75f) temp = FALSE;
 
  } else bcount = FALSE;
 
  if (ffb_get_actual(FFB_3) == 0.00) weapon_group = 0;
 
  if (is_active(fire_button)) {
    if (check_active(ads_button, time_active(ads_button) - time_active(fire_button))) {
        detect_weapon();
    } else weapon_group = 0;
  }
 
  static unsigned long int ts3,ts,prev_ts;
  static uint8 pcount;
  if (bcount) {
    if (bcount != pcount) {
      ts = time_active(fire_button) < 0 ? 0 : time_active(fire_button);
      ts = ts - prev_ts < 0 ? 0 : ts;
      if (ts3 != system_time()) {
        ts3 = system_time();
      }
      prev_ts = ts;
      pcount = bcount;
    }
  }
}
 
void ffb_capture(fix32 val) {
  static fix32 lval;
 
  if (val) {
    if (lval != val) {
      if (lval > val) {
        flag1 = 75;
      } else if (lval < val) {
        flag1 = 0;
      }
      lval = val;
    }
  }
}
 
void detect_weapon() {
 
  fix32 captured_ffb = (ffb_get_actual(FFB_3) * 255f / 100f) * 10f;
 
  if (!weapon_group) {
    switch (detect_group(captured_ffb)) {
    case 1:
      weapon_group = 1;
      break;
    case 2:
      weapon_group = 2;
      break;
    case 3:
      weapon_group = 3;
      break;
    case 4:
      weapon_group = 4;
      break;
    case 5:
      weapon_group = 5;
      break;
    case 6:
      weapon_group = 6;
      break;
    default:;
    }
  } else {
    static int oldw;
    if (oldw != weapon_group)
      oldw = group = weapon_group;
    if (event_active((13)))
      weapon_group = 0;
  }
}
 
uint8 detect_group(fix32 v) {
  if (v > 80f) return 5;
  else if (v > 65f) return 4;
  else if (v > 55f && ffb_get_actual(FFB_1) > 39f) return 6;
  else if (v > 55f) return 3;
  else if (v > 35f) return 2;
  else if (v > 25f) return 1;
  return 0;
}
 

I did not include any anti-recoil with this yet, I was only interested in capturing each weapon group.
I also implement a bullet tracking feature, which can help narrow down the exact weapon being fired.

Great work! :joia:
bonefisher
Major General
Major General
 
Posts: 5013
Joined: Thu Jan 29, 2015 10:49 am

Re: Self loading anti-recoil!

Postby jelly44 » Wed Apr 17, 2019 10:55 am

Hi bonefisher, I went through all the BFV weapons last night and found out that on PS4 with the normal dual shock 2 controller, a group of weapons can have the same FFB_1 with different FFB_2, or vice-versa, or even have the same values for FFB_1 and FFB_2.

I'm trying to work on your script so that I can account for this.

Would it be correct to amend the script like this:

From:

Code: Select all
if(ffb_get(FFB_2, NULL) > 25.0 && ffb_get(FFB_2, NULL) < 34.0)


To:

Code: Select all
if(ffb_get(FFB_2, NULL) > 25.0 && ffb_get(FFB_2, NULL) < 34.0 && ffb_get(FFB_1, NULL) > 25.0 && ffb_get(FFB_1, NULL) < 34.0 )


Basically, my plan is to try to evolve your script so that I can basically have one script which suits most of the guns and hopefully, use one slot in the T2 :smile0208: It will take me ages, but it's a challenge I'm willing to take!
User avatar
jelly44
First Sergeant
First Sergeant
 
Posts: 58
Joined: Tue Feb 05, 2019 3:49 pm

Re: Self loading anti-recoil!

Postby undazpoon » Wed Apr 17, 2019 2:53 pm

Does anyone have good weapon groups for ps4 apex legends? Can I request it? Thanks.
User avatar
undazpoon
Sergeant First Class
Sergeant First Class
 
Posts: 19
Joined: Fri Nov 18, 2016 2:52 am

PreviousNext

Return to GPC Script Programming (Titan Two)

Who is online

Users browsing this forum: Hibility and 5 guests