Functions in GPC Code

Tutorials, How-tos and FAQs for the Titan One device.

Functions in GPC Code

Postby The_Rabid_Taco » Sat Aug 20, 2016 4:52 pm

I made this to hopefully explain a little better how functions work in GPC code. Any feedback is appreciated!

The best way to explain how the functions work is that they are almost exactly like a combo with the exception that they can create their own variable within the parenthesis located in the name. These variables can only be used within the function and if you don't send the correct information for the definition it will fail in compilation. In the example below it is LED(a, b, c, d) and the a b c and d are the variables. In order to use the function you call it in the same way as a combo except that at the end of the call you need to include the values that will be passed into the function. LED(value for a, value for b, value for c, value for d). I've included trace variables in the function itself so you can easily see the values passed in from the calls in main. This can be used in many ways and tremendously reduces code duplication. It is not always a replacement for combos, and is best used only when you have multiple different values that may have to be used by the same code routine. For example if you have different fire rates for rapid fire, or different values for anti-recoil. This would be a time to use functions as you could easily pass the parameters to the function without having to re-write the code for the rapid fire or anti-recoil. Please let me know if there are any other questions or if I could make this small tutorial on how to use functions a little better.

Code: Select all
main {
    if(event_press(PS4_CROSS)) LED(0, 0, 0, 0);
    if(event_press(PS4_SQUARE)) LED(1, 0, 0, 0);
    if(event_press(PS4_CIRCLE)) LED(0, 1, 0, 0);
    if(event_press(PS4_TRIANGLE)) LED(0, 0, 1, 0);
    if(event_press(PS4_DOWN)) LED(0, 0, 0, 1);
    if(event_press(PS4_UP)) LED(1, 0, 1, 0);
    if(event_press(PS4_R1)) LED(0, 1, 1, 0);
    if(event_press(PS4_R2)) LED(1, 1, 1, 0);
}

function LED(a, b, c, d) {
    set_led(0, a);
    set_led(1, b);
    set_led(2, c);
    set_led(3, d);
   
    set_val(TRACE_1, a);
    set_val(TRACE_2, b);
    set_val(TRACE_3, c);
    set_val(TRACE_4, d);
}
User avatar
The_Rabid_Taco
Major
Major
 
Posts: 1066
Joined: Wed Mar 16, 2016 6:04 pm
Location: Pensacola, FL

Re: Functions in GPC Code

Postby bonefisher » Sat Aug 20, 2016 5:04 pm

Great info! :joia:
bonefisher
Lieutenant General
Lieutenant General
 
Posts: 5413
Joined: Thu Jan 29, 2015 10:49 am

Re: Functions in GPC Code

Postby Vendetta » Sat Aug 20, 2016 8:54 pm

yes, this is good. I want to learn more. Hopefully I've correctly "commented", so I can follow along. I may have the Off/On/Fast Blink/Slow Blink wrong in the function? Could you give us an example of what could be done with this. I realize the function replaces some combos and eliminates needing to use defines (ex: smaller byte code ). Please, further explain what the TRACE is doing, I put in the comments the Identifiers for TRACE, just as (4) is the identifier for the (PS4_R2).

:smile0310:

Code: Select all
main {
    if(event_press(PS4_CROSS)) LED(0, 0, 0, 0);  //Off
    if(event_press(PS4_SQUARE)) LED(1, 0, 0, 0);  //Blue
    if(event_press(PS4_CIRCLE)) LED(0, 1, 0, 0);  //Red
    if(event_press(PS4_TRIANGLE)) LED(0, 0, 1, 0);  //Green
    if(event_press(PS4_DOWN)) LED(0, 0, 0, 1);  //Pink
    if(event_press(PS4_UP)) LED(1, 0, 1, 0);  // Cyan
    if(event_press(PS4_R1)) LED(0, 1, 1, 0);  //Amber
    if(event_press(PS4_R2)) LED(1, 1, 1, 1);  //White
}

function LED(a, b, c, d) {
    set_led(0, a);  //Off
    set_led(1, b);  //On
    set_led(2, c);  // Fast Blink
    set_led(3, d);  // Slow Blink
   
    set_val(TRACE_1, a);  //(30)
    set_val(TRACE_2, b);  //(31)
    set_val(TRACE_3, c);  //(32)
    set_val(TRACE_4, d);  //(33)
}
    Playstation PS4, Astro A50 Gen 3, Elgato Game Capture HD60 S
    2x Benq 27” Gaming Monitors, Netduma R1 Gaming Router
    Titan One/Two Controller Input Device, Battle Beaver PS4 Controller, SCUF Infinity4PS Controller
User avatar
Vendetta
Sergeant Major of the Army
Sergeant Major of the Army
 
Posts: 226
Joined: Fri Jul 31, 2015 8:40 pm

Re: Functions in GPC Code

Postby The_Rabid_Taco » Sat Aug 20, 2016 11:30 pm

The trace values in this function are just for use in the Device Monitor. It shows how the value changes in a, b, c, and d when different buttons are pressed and passing in the values. These should populate in the lower right corner of device monitor. I've updated the remarks a bit to help show the flow and how it all comes together.

Code: Select all
main {
    if(event_press(PS4_CROSS)) LED(0, 0, 0, 0);  //Off
    if(event_press(PS4_SQUARE)) LED(1, 0, 0, 0);  //Blue
    if(event_press(PS4_CIRCLE)) LED(0, 1, 0, 0);  //Red
    if(event_press(PS4_TRIANGLE)) LED(0, 0, 1, 0);  //Green
    if(event_press(PS4_DOWN)) LED(0, 0, 0, 1);  //Pink
    if(event_press(PS4_UP)) LED(1, 0, 1, 0);  // Cyan
    if(event_press(PS4_R1)) LED(0, 1, 1, 0);  //Amber
    if(event_press(PS4_R2)) LED(1, 1, 1, 1);  //White
}

function LED(a, b, c, d) {

    //Set led sets the state of each of the LED's.
    //There are four in total, this is why we pass four values in.

    set_led(0, a);  //Value one passed in, sets state of LED1 0 - off, 1 - on, 2 - fast blink, 3 - slow blink
    set_led(1, b);  //Value two passed in, sets state of LED2 0 - off, 1 - on, 2 - fast blink, 3 - slow blink
    set_led(2, c);  //Value three passed in, sets state of LED3 0 - off, 1 - on, 2 - fast blink, 3 - slow blink
    set_led(3, d);  //Value four passed in, sets state of LED4 0 - off, 1 - on, 2 - fast blink, 3 - slow blink
   
    // When viewed in device monitor, will show the values passed in from main.
    // The lower right hand corner has six trace values.  I've done this just
    // to make seeing when a button is pressed how the values get to this function
    // a bit easier.
   
    set_val(TRACE_1, a);  //(30) 
    set_val(TRACE_2, b);  //(31)
    set_val(TRACE_3, c);  //(32)
    set_val(TRACE_4, d);  //(33)
}
User avatar
The_Rabid_Taco
Major
Major
 
Posts: 1066
Joined: Wed Mar 16, 2016 6:04 pm
Location: Pensacola, FL

Re: Functions in GPC Code

Postby antithesis » Sun Aug 21, 2016 3:49 am

Thanks for putting this together :joia:

Do you have an example of how this can be applied to rapid-fire? I'm assuming it would be pretty easy, given the two variables are HoldTime and RestTime.

Code: Select all

combo RapidFire
{
    set_val(SHOOT, 100);
    wait(HoldTime);
    set_val(SHOOT, 0);
    wait(RestTime);
    set_val(SHOOT, 0);
}


Where things might get a bit more fun are combining anti-recoil and rapid-fire into one, such as this..

Code: Select all

combo AdvancedRapidFire {
    set_val(Shoot, 100);
    wait(FireRate);
    set_val(Shoot, 0);
    if(test_bit(GunFlags, 1)) {
        AntiRecoil(Primary_Anti_Recoil, PrimaryAntiRecoilHoldR, PrimaryAntiRecoilHoldL);
    } else if(test_bit(GunFlags, 2)) {
        AntiRecoil(Secondary_Anti_Recoil, SecondaryAntiRecoilHoldR, SecondaryAntiRecoilHoldL);
    }
    wait(FireRate);
}

function AntiRecoil(AntiRecoil_H, AntiRecoil_V)
{
    if (AntiRecoil_ON)
    {
        RightStick_X = get_val(RX_AXIS) + AntiRecoil_H;
        if (RightStick_X > 100)
        {RightStick_X = 100;}
        set_val(RX_AXIS, RightStick_X);
       
        RightStick_Y = get_val(RY_AXIS) + AntiRecoil_V;
        if (RightStick_Y > 100)
        {RightStick_Y = 100;}
        set_val(RY_AXIS, RightStick_Y);
    }
}


...but I suppose the principle is the same. I understand the anti-recoil part of the code, but I'm not sure how to apply a function to FireRate in this example.

My guess is the call to the function would be something like below, assuming the function is named RapidFire, but I'm not 100% clear on how to construct the RapidFire function, or whether a function can be called within another function.

Code: Select all

combo AdvancedRapidFire {
    set_val(Shoot, 100);
    wait(RapidFire(FireRate));
...
Last edited by antithesis on Sun Aug 21, 2016 9:23 am, edited 1 time in total.
Official Australian retailer for Titan One, Titan Two and XIM APEX at Mod Squad
User avatar
antithesis
Colonel
Colonel
 
Posts: 1912
Joined: Sat May 28, 2016 10:45 pm

Re: Functions in GPC Code

Postby The_Rabid_Taco » Sun Aug 21, 2016 7:49 am

Yea, I'll throw together an example of a rapid fire, a anti-recoil, and a mixed bag tomorrow. Getting some sleep now to clear the cobwebs, and should be able to put something together.
User avatar
The_Rabid_Taco
Major
Major
 
Posts: 1066
Joined: Wed Mar 16, 2016 6:04 pm
Location: Pensacola, FL

Re: Functions in GPC Code

Postby J2Kbr » Mon Aug 22, 2016 11:51 am

Great initiative The_Rabid_Taco, we should make a copy of this topic on the tutorials section!! :) (if you agree of course). thanks.
ConsoleTuner Support Team
User avatar
J2Kbr
General of the Army
General of the Army
 
Posts: 20322
Joined: Tue Mar 18, 2014 1:39 pm

Re: Functions in GPC Code

Postby The_Rabid_Taco » Mon Aug 22, 2016 1:33 pm

J2Kbr wrote:Great initiative The_Rabid_Taco, we should make a copy of this topic on the tutorials section!! :) (if you agree of course). thanks.


I'd have no issue with that at all!

Sorry, I didn't remember (honestly got lost in Witcher 3) and will make sure to do a example of Rapid Fire tonight after work.
User avatar
The_Rabid_Taco
Major
Major
 
Posts: 1066
Joined: Wed Mar 16, 2016 6:04 pm
Location: Pensacola, FL

Re: Functions in GPC Code

Postby J2Kbr » Mon Aug 22, 2016 1:42 pm

awesome thanks! :)
ConsoleTuner Support Team
User avatar
J2Kbr
General of the Army
General of the Army
 
Posts: 20322
Joined: Tue Mar 18, 2014 1:39 pm

Re: Functions in GPC Code

Postby The_Rabid_Taco » Wed Aug 24, 2016 1:53 pm

Ok, so here is an example where bit operator and function were able to reduce the code size by a few percent, and this is a small script. I used the function to handle all of the toggles for different mods. This can be a huge space saver for when you have a lot of different mods and want to be able to turn them all on and off. I figured out why I hadn't been using it for rapid fire, and it is because of the wait commands. They can not be ran from a function so being able to pass in the values does not work quite the same. There is a way to work around that in combo's so that you don't have to duplicate the code there either, but I'll save that for another post. I've got two scripts below that work identical, the first is the longer drawn out version and the second uses bit operators and a function to shorten the code, saves a few percent even on a small script like this and also makes it much more readable. Let me know if there are any questions as to how this works.

Longer code block:

Code: Select all
/* -----------------------------------------------------------------------------
 *  DEFINES
**/


// Modz Buttons
define WitcherSense = PS4_L2;
define Heavy = PS4_TRIANGLE;
define Light = PS4_SQUARE;
define Pickup = PS4_CROSS;
define Dodge = PS4_CIRCLE;

// Persistent Vars
define PVAR_WitcherSense = SPVAR_1;
define PVAR_TurboLightAttack = SPVAR_2;
define PVAR_TurboHeavyAttack = SPVAR_3;
define PVAR_TurboPickup = SPVAR_4;
define PVAR_TurboDodge = SPVAR_5;

/* -----------------------------------------------------------------------------
 *  VARIABLES
**/


// Variable used to store the flags used for toggles.
int WitcherSenseToggle = FALSE;
int LightMeleeToggle = FALSE;
int HeavyMeleeToggle = FALSE;
int TurboPickupToggle = FALSE;
int TurboDodgeToggle = FALSE;

/* -----------------------------------------------------------------------------
 *  INITIALIZATION
**/

init {
    WitcherSenseToggle = get_pvar(PVAR_WitcherSense, 0, 1, 0);
    LightMeleeToggle = get_pvar(PVAR_TurboLightAttack, 0, 1, 0);
    HeavyMeleeToggle = get_pvar(PVAR_TurboHeavyAttack, 0, 1, 0);
    TurboPickupToggle = get_pvar(PVAR_TurboPickup, 0, 1, 0);
    TurboDodgeToggle = get_pvar(PVAR_TurboDodge, 0, 1, 0);
}

main {
   
    // For crossover support.  Use an XBox 1 controller on PS4.  Allows the
    // home button to be used for Touch and PS Home at the same time based on
    // the length of time it is held.
    if(get_controller() == PIO_XB1 && get_val(PS4_PS) && get_ptime(PS4_PS) > 500){
        set_val(PS4_PS, 100);
    } else if(get_controller() == PIO_XB1 && get_val(PS4_PS) && get_ptime(PS4_PS) <= 500){
        set_val(PS4_PS, 0);
        set_val(PS4_TOUCH, 100);
    }
   
    // Sets the hold toggle on the Witcher Sense.  Checks to see if the flag is
    // set to true or false.  Depending on which one it then reverses the flag
    // alternating whether or not the Witcher Sense is used or not.  It then sets
    // the value into the PVAR for persistent state between uses.
    if(event_press(WitcherSense)) {
        if(!WitcherSenseToggle){
            WitcherSenseToggle = TRUE;
        } else if(WitcherSenseToggle){
            WitcherSenseToggle = FALSE;
        }
       
        set_pvar(PVAR_WitcherSense, WitcherSenseToggle);
    }
   
    if(get_val(WitcherSense)) {
   
        // Sets the toggle on the light attack.  Checks to see if the flag is
        // set to true or false.  Depending on which one it then reverses the flag
        // alternating whether or not the turbo light melee combo is used or not.  It then sets
        // the value into the PVAR for persistent state between uses.
        if(event_press(Light)){           
            if(!LightMeleeToggle){
                LightMeleeToggle = TRUE;
                combo_run(RumbleNotifier);
            } else if(LightMeleeToggle){
                LightMeleeToggle = FALSE;
                combo_run(DoubleRumbleNotifier);
            }
           
            set_pvar(PVAR_TurboLightAttack, LightMeleeToggle);
        }
       
        // Sets the toggle on the heavy attack.  Checks to see if the flag is
        // set to true or false.  Depending on which one it then reverses the flag
        // alternating whether or not the turbo heavy melee combo is used or not.  It then sets
        // the value into the PVAR for persistent state between uses.
        if(event_press(Heavy)){
            if(!HeavyMeleeToggle){
                HeavyMeleeToggle = TRUE;
                combo_run(RumbleNotifier);
            } else if(HeavyMeleeToggle){
                HeavyMeleeToggle = FALSE;
                combo_run(DoubleRumbleNotifier);
            }
           
            set_pvar(PVAR_TurboHeavyAttack, HeavyMeleeToggle);
        }
       
        // Sets the toggle on the turbo pickup.  Checks to see if the flag is
        // set to true or false.  Depending on which one it then reverses the flag
        // alternating whether or not the turbo pickup combo is used or not.  It then sets
        // the value into the PVAR for persistent state between uses.
        if(event_press(Pickup)){         
            if(!TurboPickupToggle){
                TurboPickupToggle = TRUE;
                combo_run(RumbleNotifier);
            } else if(TurboPickupToggle){
                TurboPickupToggle = FALSE;
                combo_run(DoubleRumbleNotifier);
            }
           
            set_pvar(PVAR_TurboPickup, TurboPickupToggle);
        }
       
        // Sets the toggle on the turbo dodge.  Checks to see if the flag is
        // set to true or false.  Depending on which one it then reverses the flag
        // alternating whether or not the turbo dodge combo is used or not.  It then sets
        // the value into the PVAR for persistent state between uses.
        if(event_press(Dodge)){
            if(!TurboDodgeToggle){
                TurboDodgeToggle = TRUE;
                combo_run(RumbleNotifier);
            } else if(TurboDodgeToggle){
                TurboDodgeToggle = FALSE;
                combo_run(DoubleRumbleNotifier);
            }
           
            set_pvar(PVAR_TurboDodge, TurboDodgeToggle);
        }
    }
   
    // If the toggle is set to true then run the Witcher_Sense combo.
    if(WitcherSenseToggle) combo_run(Witcher_Sense);

    // If the toggle is set to true then when pressing Square or X turbo the button.
    if(get_val(Light) && LightMeleeToggle) combo_run(TurboLightAttack);
    // If the toggle is set to true then when pressing Triangle or Y turbo the button.
    if(get_val(Heavy) && HeavyMeleeToggle) combo_run(TurboHeavyAttack);
    // If the toggle is set to true then when pressing Cross or A turbo the button.
    if(get_val(Pickup) && TurboPickupToggle) combo_run(TurboLoot);
    // If the toggle is set to true then when pressing Circle or B turbo the button.
    if(get_val(Dodge) && TurboDodgeToggle) combo_run(QuickDodge);
}

/* -----------------------------------------------------------------------------
 *  COMBOS
**/


// Sets the value of L2 or Left Trigger to 100 even when the button is released.
combo Witcher_Sense {
    set_val(WitcherSense, 100);
}

//  Turbo presses the Square / X button in 10ms intervals.
combo TurboLightAttack {
    set_val(Light, 100);
    wait(10);
    set_val(Light, 0);
    wait(10);
}

// Turbo presses the Triangle / Y button in 10ms intervals.
combo TurboHeavyAttack {
    set_val(Heavy, 100);
    wait(10);
    set_val(Heavy, 0);
    wait(10);
}

// Turbo presses the Cross / A button in 10ms intervals.
combo TurboLoot {
    set_val(Pickup, 100);
    wait(10);
    set_val(Pickup, 0);
    wait(10);
}

// Turbo presses the Circle / B button in 10ms intervals.
combo QuickDodge {
    set_val(Dodge, 100);
    wait(10);
    set_val(Dodge, 0);
    wait(10);
}

// Sends a single rumble for 300ms to the controller.  Used to indicate when
// a mod is enabled.
combo RumbleNotifier{
    set_rumble(RUMBLE_A, 100);
    wait(300);
    reset_rumble();
}

// Sends two consecutive rumbles to the controller the first for 300ms followed
// by a 300ms wait before sending a second rumble for 400ms to the controller.
// This is used to indicate when a mod has been disabled.
combo DoubleRumbleNotifier{
    set_rumble(RUMBLE_A, 100);
    wait(300);
    set_rumble  (RUMBLE_A, 0);
    wait(300);
    set_rumble(RUMBLE_A, 100);
    wait(400);
    reset_rumble();
}


Refactored Code Block:

Code: Select all
/* -----------------------------------------------------------------------------
 *  DEFINES
**/


// Modz Buttons
define WitcherSense = PS4_L2;
define Heavy = PS4_TRIANGLE;
define Light = PS4_SQUARE;
define Pickup = PS4_CROSS;
define Dodge = PS4_CIRCLE;

// Persistent Vars
define PVAR_WitcherFlags = SPVAR_1;

/* -----------------------------------------------------------------------------
 *  VARIABLES
**/


// Variable used to store the flags used for toggles.
int WitcherFlags;


/* -----------------------------------------------------------------------------
 *  INITIALIZATION
**/

init {
    WitcherFlags = get_pvar(PVAR_WitcherFlags, 0, 31, 0);
}

main {
   
    // For crossover support.  Use an XBox 1 controller on PS4.  Allows the
    // home button to be used for Touch and PS Home at the same time based on
    // the length of time it is held.
    if(get_controller() == PIO_XB1 && get_val(PS4_PS) && get_ptime(PS4_PS) > 500){
        set_val(PS4_PS, 100);
    } else if(get_controller() == PIO_XB1 && get_val(PS4_PS) && get_ptime(PS4_PS) <= 500){
        set_val(PS4_PS, 0);
        set_val(PS4_TOUCH, 100);
    }
   
    // Sets the hold toggle on the Witcher Sense.  This calls the function and
    // passes the value of 1 telling it to look at the first bit in the bit
    // flags.  If it is set then clear it.  If not set then set it.
    if(event_press(WitcherSense)) {
        SetToggle(1);
    }
   
    // Checks to see if the L2 / Left Trigger is being held.  If it is and one
    // of the other buttons is pressed then toggle the turbo on that particular
    // button.
    if(get_val(WitcherSense)) {
       
        // If PS4 Square or XBox X is pressed then call the function and tell
        // it to look at the second bit.  Again if set then clear it, and if not
        // set then set it.
        if(event_press(Light)){           
            SetToggle(2);
        }
       
        // If PS4 Triangle or XBox Y is pressed then call the function and tell
        // it to look at the second bit.  Again if set then clear it, and if not
        // set then set it.
        if(event_press(Heavy)){
            SetToggle(3);
        }
       
        // If PS4 Cross or XBox A is pressed then call the function and tell
        // it to look at the second bit.  Again if set then clear it, and if not
        // set then set it.
        if(event_press(Pickup)){         
            SetToggle(4);
        }
       
        // If PS4 Circle or XBox B is pressed then call the function and tell
        // it to look at the second bit.  Again if set then clear it, and if not
        // set then set it.
        if(event_press(Dodge)){
            SetToggle(5);
        }
    }
   
    // If the first bit is set then run the Witcher_Sense combo.
    if(test_bit(WitcherFlags, 1)) combo_run(Witcher_Sense);
   
    // If the second bit is set then when pressing Square or X turbo the button.
    if(get_val(Light) && test_bit(WitcherFlags, 2)) combo_run(TurboLightAttack);
    // If the third bit is set then when pressing Triangle or Y turbo the button.
    if(get_val(Heavy) && test_bit(WitcherFlags, 3)) combo_run(TurboHeavyAttack);
    // If the fourth bit is set then when pressing Cross or A turbo the button.
    if(get_val(Pickup) && test_bit(WitcherFlags, 4)) combo_run(TurboLoot);
    // If the fifth bit is set then when pressing Circle or B turbo the button.
    if(get_val(Dodge) && test_bit(WitcherFlags, 5)) combo_run(QuickDodge);
}

/* -----------------------------------------------------------------------------
 *  COMBOS
**/


// Sets the value of L2 or Left Trigger to 100 even when the button is released.
combo Witcher_Sense {
    set_val(WitcherSense, 100);
}

//  Turbo presses the Square / X button in 10ms intervals.
combo TurboLightAttack {
    set_val(Light, 100);
    wait(10);
    set_val(Light, 0);
    wait(10);
}

// Turbo presses the Triangle / Y button in 10ms intervals.
combo TurboHeavyAttack {
    set_val(Heavy, 100);
    wait(10);
    set_val(Heavy, 0);
    wait(10);
}

// Turbo presses the Cross / A button in 10ms intervals.
combo TurboLoot {
    set_val(Pickup, 100);
    wait(10);
    set_val(Pickup, 0);
    wait(10);
}

// Turbo presses the Circle / B button in 10ms intervals.
combo QuickDodge {
    set_val(Dodge, 100);
    wait(10);
    set_val(Dodge, 0);
    wait(10);
}

// Sends a single rumble for 300ms to the controller.  Used to indicate when
// a mod is enabled.
combo RumbleNotifier{
    set_rumble(RUMBLE_A, 100);
    wait(300);
    reset_rumble();
}

// Sends two consecutive rumbles to the controller the first for 300ms followed
// by a 300ms wait before sending a second rumble for 400ms to the controller.
// This is used to indicate when a mod has been disabled.
combo DoubleRumbleNotifier{
    set_rumble(RUMBLE_A, 100);
    wait(300);
    set_rumble  (RUMBLE_A, 0);
    wait(300);
    set_rumble(RUMBLE_A, 100);
    wait(400);
    reset_rumble();
}

/* -----------------------------------------------------------------------------
 *  FUNCTIONS
**/


// This is the function to set the flags on the options.  FlagLocation is a variable
// that accepts the value passed into it from main.  This is then used to distinguish
// which flag we want to look at.  If the flag is enabled (set) then we clear it out.
// If the flag is disabled (cleared) then we set it to enable that particular mod.
// The flags are then stored in a pvar to enable persistence between uses.
function SetToggle(FlagLocation) {
    if(test_bit(WitcherFlags, FlagLocation)) {
        clear_bit(WitcherFlags, FlagLocation);
        combo_run(DoubleRumbleNotifier);
    } else {
        set_bit(WitcherFlags, FlagLocation);
        combo_run(RumbleNotifier);
    }
   
    set_pvar(PVAR_WitcherFlags, WitcherFlags);
}
User avatar
The_Rabid_Taco
Major
Major
 
Posts: 1066
Joined: Wed Mar 16, 2016 6:04 pm
Location: Pensacola, FL

Next

Return to Tutorials and FAQs

Who is online

Users browsing this forum: No registered users and 3 guests