Jump to content
Ilusionz

[Tutorial]Adaptive Debit Cards + Addons[5.0 - 4.4r3]

Recommended Posts

Adaptive Debit Cards

I've looked around for a debit card script previously, and either couldn't find one, it wasn't updated for the latest framework, or it was incomplete.  -- So I decided to give it a go myself.

If you haven't seen or used Debit Cards on Altis Life before, they essentially make the purchase of items much easier and faster by taking money straight from a player's bank account, instead of their on-hand cash.

 

From what I have also seen in the past, Debit Cards were forced upon the player, leading to problems such as Rebels not being able to rob people for their money, since it was safe and sound in their bank -- Which can easily ruin an economy. I've tried to help server owners out here by adding a few configuration options, including Taxing, setting a Tax amount, charging a custom amount for a Debit Card along with the disabling of debit cards in certain shops. This way, the player can decide weather or not to buy the card, and if they do, they will be charged extra for purchasing items with a Debit Card.

 

How Debit Cards work:

If the player is attempting to buy something from a shop, and they have enough money on-hand, the shop will take their cash. If they don't have that money on their person, but they have it in their bank account, that money is taken instead and they will also be charged extra in Tax (if it is enabled on the server).

Cash on hand takes priority before Bank balance when buying items.

If a player is attempting to sell an item and they have a Debit Card, the money made from the sale will go to their bank account. If they have no Debit Card it will be added to their on-hand cash.

 

DISCLAIMER:

These scripts were made on and tested on the most recent Altis Life Framework(v5.0.0) & 4.4r3. They may not work if you are attempting to use them on anything lower.

If you are using Altis Life 4.4r3 please make sure your fn_mresArray.sqf has been updated to this:

https://github.com/AsYetUntitled/Framework/commit/db66e545ef02faec2a2e9fd152eb5260b3deab8a

 

ADDONS/OPTIONAL UPDATES

Once you have finished this tutorial, feel free to install any of the updates below. They are 100% optional.

(This list is a work in progress)

Virtual Item:

 

Tutorial

Altis_Life.Altis

1. Download the file attached to this thread. 

2. In Altis_Life.Altis\functions.hpp create the following class inside Life_Client_Core:

class Debit {
    file = "core\debit";
    class buyClothesDebit {};
    class vehicleShopBuyDebit {};
    class virt_buyDebit {};
    class virt_sellDebit {};
    class weaponShopBuySellDebit {};
    class debitCheck {};
    class buyDebit {};
};

3. Open Config_Master.hpp, found in Altis_Life.Altis\config and add the following inside Life_Settings:

/* Debit Card Configuration */
debit_tax = true;	//Tax a player when they have used a Debit card to purchase something? - This is mainly a money sink in case everyone on your server owns a debit card, as they'll never have money on their person (so they can't be robbed) if they do.
debit_taxAmount = 0.15; // Tax the player pays when purchasing with a debit card. Tax = Price * debit_taxAmount. debit_tax must be true. Eg. - If an item is $45,000 and your tax is set to 0.15, amount paid after tax will be $51,750. (total tax paid $6750.)
debit_price = 75000; // Price of purchasing a debit card from the bank.
debit_weapons = true; // Allows the use of debit cards when purchasing/selling weapons.
debit_clothing = true; // Allows the use of debit cards when purchasing/selling clothing.
debit_vItems = true; // Allows the use of Debit Cards when purchasing/selling virtual items.
debit_vehicles = true; // Allows the use of Debit Cards when purchasing/renting/selling vehicles.

4. In Altis_Life.Altis\core open your configuration.sqf and add the following to Life VariablesIF YOU PLAN ON INSTALLING THE VIRTUAL ITEM ADDON FEEL FREE TO IGNORE THIS

life_has_debit = false;

5. Move the debit folder for your version of Altis Life found in the .rar you (should have) downloaded from step 1 in to Altis_Life.Altis\core 
 

6. Navigate to Altis_Life.Altis\dialog and open the following files:

bank.hpp

Find the following:

class CloseButtonKey: Life_RscButtonMenu {
    idc = -1;
    text = "$STR_Global_Close";
    onButtonClick = "closeDialog 0;";
    x = 0.35;
    y = 0.812;
    w = (6.25 / 40);
    h = (1 / 25);
};
class MainBackground: Life_RscText {
    colorBackground[] = {0, 0, 0, 0.7};
    idc = -1;
    x = 0.35;
    y = 0.2 + (11 / 250);
    w = 0.3;
    h = 0.652 - (22 / 250);
};

Change to:

class CloseButtonKey: Life_RscButtonMenu {
    idc = -1;
    text = "$STR_Global_Close";
    onButtonClick = "closeDialog 0;";
    x = 0.438125 * safezoneW + safezoneX;
    y = 0.7024 * safezoneH + safezoneY;
    w = 0.0644531 * safezoneW;
    h = 0.022 * safezoneH;
};
class MainBackground: Life_RscText {
    colorBackground[] = {0, 0, 0, 0.7};
    idc = -1;
    x = 0.438125 * safezoneW + safezoneX;
    y = 0.3592 * safezoneH + safezoneY;
    w = 0.12375 * safezoneW;
    h = 0.341 * safezoneH;
};

Also, add to class controls:

class buyDebit: Life_RscButtonMenu {
    idc = 57623;
    onButtonClick = "[] call life_fnc_buyDebit";
    colorBackground[] = {"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.3843])", "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.7019])", "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.8862])", 0.5};
    text = "$STR_Debit_PurchaseDebit";
    x = 0.444312 * safezoneW + safezoneX;
    y = 0.6672 * safezoneH + safezoneY;
    w = 0.113437 * safezoneW;
    h = 0.022 * safezoneH;
};

clothing.hpp

Find:

class BuyButtonKey: Life_RscButtonMenu {
    idc = -1;
    text = "$STR_Global_Buy";
    onButtonClick = "[] call life_fnc_buyClothes;";
    x = 0.0822359 * safezoneW + safezoneX;
    y = 0.489992 * safezoneH + safezoneY;
    w = (6.25 / 40);
    h = (1 / 25);
};

Change to:

class BuyButtonKey: Life_RscButtonMenu {
    idc = -1;
    text = "$STR_Global_Buy";
    onButtonClick = "[0] call life_fnc_debitCheck;";
    x = 0.0822359 * safezoneW + safezoneX;
    y = 0.489992 * safezoneH + safezoneY;
    w = (6.25 / 40);
    h = (1 / 25);
};

shop_items.hpp

Find:

class ButtonAddG: Life_RscButtonMenu {
    idc = -1;
    text = "$STR_VS_BuyItem";
    colorBackground[] = {"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.3843])", "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.7019])", "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.8862])", 0.5};
    onButtonClick = "[] spawn life_fnc_virt_buy;";
    x = 0.12 + (0.35 / 2) - ((6.25 / 40) / 2);
    y = 0.70;
    w = (6.25 / 40);
    h = (1 / 25);
};

class ButtonRemoveG: Life_RscButtonMenu {
    idc = -1;
    text = "$STR_VS_SellItem";
    colorBackground[] = {"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.3843])", "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.7019])", "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.8862])", 0.5};
    onButtonClick = "[] call life_fnc_virt_sell";
    x = 0.53 + (0.35 / 2) - ((6.25 / 40) / 2);
    y = 0.70;
    w = (6.25 / 40);
    h = (1 / 25);
};

Change to:

class ButtonAddG: Life_RscButtonMenu {
    idc = -1;
    text = "$STR_VS_BuyItem";
    colorBackground[] = {"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.3843])", "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.7019])", "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.8862])", 0.5};
    onButtonClick = "[2] call life_fnc_debitCheck";
    x = 0.12 + (0.35 / 2) - ((6.25 / 40) / 2);
    y = 0.70;
    w = (6.25 / 40);
    h = (1 / 25);
};

class ButtonRemoveG: Life_RscButtonMenu {
    idc = -1;
    text = "$STR_VS_SellItem";
    colorBackground[] = {"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.3843])", "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.7019])", "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.8862])", 0.5};
    onButtonClick = "[4] call life_fnc_debitCheck";
    x = 0.53 + (0.35 / 2) - ((6.25 / 40) / 2);
    y = 0.70;
    w = (6.25 / 40);
    h = (1 / 25);
};

shops.hpp

Find:

class ButtonBuySell: Life_RscButtonMenu {
    idc = 38405;
    text = "$STR_Global_Buy";
    onButtonClick = "[] spawn life_fnc_weaponShopBuySell; true";
    x = 0.1;
    y = 0.8 - (1 / 25);
    w = (6.25 / 40);
    h = (1 / 25);
};

Change to:

class ButtonBuySell: Life_RscButtonMenu {
    idc = 38405;
    text = "$STR_Global_Buy";
    onButtonClick = "[1] call life_fnc_debitCheck;";
    x = 0.1;
    y = 0.8 - (1 / 25);
    w = (6.25 / 40);
    h = (1 / 25);
};

vehicleShop.hpp AND vehicleShop3D.hpp

Find:

class RentCar : Life_RscButtonMenu {
    idc = -1;
    text = "$STR_Global_RentVeh";
    onButtonClick = "[false] spawn life_fnc_vehicleShopBuy;";
    x = 0.1 + (6.25 / 40) + (1 / 250 / (safezoneW / safezoneH));
    y = 0.9 - (1 / 25);
    w = (6.25 / 40);
    h = (1 / 25);
};

class BuyCar : life_RscButtonMenu {
    idc = 2309;
    text = "$STR_Global_Buy";
    onButtonClick = "[true] spawn life_fnc_vehicleShopBuy;";
    x = 0.26 + (6.25 / 40) + (1 / 250 / (safezoneW / safezoneH));
    y = 0.9 - (1 / 25);
    w = (6.25 / 40);
    h = (1 / 25);
};

Change to:

class RentCar : Life_RscButtonMenu {
    idc = -1;
    text = "$STR_Global_RentVeh";
    onButtonClick = "[5] call life_fnc_debitCheck;";
    x = 0.1 + (6.25 / 40) + (1 / 250 / (safezoneW / safezoneH));
    y = 0.9 - (1 / 25);
    w = (6.25 / 40);
    h = (1 / 25);
};

class BuyCar : life_RscButtonMenu {
    idc = 2309;
    text = "$STR_Global_Buy";
    onButtonClick = "[3] call life_fnc_debitCheck;";
    x = 0.26 + (6.25 / 40) + (1 / 250 / (safezoneW / safezoneH));
    y = 0.9 - (1 / 25);
    w = (6.25 / 40);
    h = (1 / 25);
};

7. Go to Altis_Life.Altis\core\session and make changes to the following files -- IF YOU PLAN ON INSTALLING THE VIRTUAL ITEM ADDON FEEL FREE TO IGNORE THIS

fn_requestReceived.sqf - Find "switch (playerSide) do {" and add the following to it's respective class:

For Altis Life 5.0.0:

Spoiler

 

case west:

life_has_debit = _this select 12;

case civilian:

life_has_debit = _this select 13;

case independent:

life_has_debit = _this select 11;

 

 

 

For Altis Life 4.4r3:

Spoiler

 

Make the same changes above, but also:

Find:

life_houses = _this select 13;
life_gangData = _this select 14;
if (count (_this select 15) > 0) then {
    {life_vehicles pushBack _x;} forEach (_this select 15);
};

Change to:

life_houses = _this select 14;
life_gangData = _this select 15;
if (count (_this select 16) > 0) then {
    {life_vehicles pushBack _x;} forEach (_this select 16);
};

 

 

 

It should look like this (5.0.0):

case west: {
    life_has_debit = _this select 12;
    CONST(life_coplevel,(_this select 7));
    CONST(life_medicLevel,0);
    life_blacklisted = _this select 9;
    if (LIFE_SETTINGS(getNumber,"save_playerStats") isEqualTo 1) then {
    life_hunger = ((_this select 10) select 0);
    life_thirst = ((_this select 10) select 1);
    player setDamage ((_this select 10) select 2);
    };
};

fn_updatePartial.sqf - Add the following case below case 7. 

case 8: {
    _packet set[2,life_has_debit];
};

 

fn_updateRequest.sqf - Change the playerSide switch to:

switch (playerSide) do {
    case civilian: {
        _packet pushBack life_is_arrested;
        _packet pushBack _alive;
        _packet pushBack _position;
		_packet pushBack life_has_debit;
    };
	
	case west: {
		_packet pushBack life_has_debit;
	};
	
	case independent: {
		_packet pushBack life_has_debit;
	};
};

 

8. Open your stringtable.xml and create the following package:

Spoiler
<Package name="Debit_Cards">
  <Key ID="STR_Debit_PurchaseDebit">
    <Original>Purchase Debit Card</Original>
  </Key>
  <Key ID="STR_Debit_NotEnoughCash">
    <Original>Sorry, but you do not have enough money to purchase a Debit Card. Amont lacking: $%1.</Original>
  </Key>
  <Key ID="STR_Debit_AlreadyOwned">
    <Original>You already own a Debit Card.</Original>
  </Key>
  <Key ID="STR_Debit_Purchased">
    <Original>You have purchased a Debit Card for $%1.</Original>
  </Key>
  <Key ID="STR_Debit_Weapon_Sold">
    <Original>You sold a %1 for &lt;t color='#8cff9b'&gt;$%2.&lt;/t&gt; The money was added to your bank account since you own a debit card.</Original>
  </Key>
  <Key ID="STR_Debit_BoughtItemTax">
    <Original>You bought a %1 for &lt;t color='#8cff9b'&gt;$%2.&lt;/t&gt; You also paid &lt;t color='#8cff9b'&gt;$%3&lt;/t&gt; in tax for using your debit card.</Original>
  </Key>
  <Key ID="STR_Debit_BoughtItem">
    <Original>You bought a %1 for &lt;t color='#8cff9b'&gt;$%2.&lt;/t&gt; The money was taken from your bank account since you own a debit card.</Original>
  </Key>
  <Key ID="STR_Debit_UsedOnHandCash">
    <Original>You purchased a %1 with your on-hand cash since it was on your person. Total amount paid: &lt;t color='#8cff9b'&gt;$%2.&lt;/t&gt;</Original>
  </Key>
  <Key ID="STR_Debit_Clothing_BoughtItemTax">
    <Original>You purchased clothing for &lt;t color='#8cff9b'&gt;$%1.&lt;/t&gt; You also paid &lt;t color='#8cff9b'&gt;$%2&lt;/t&gt; in tax for using your debit card.</Original>
  </Key>
  <Key ID="STR_Debit_Clothing_BoughtItem">
    <Original>You purchased clothing for &lt;t color='#8cff9b'&gt;$%1.&lt;/t&gt; The money was taken from your bank account since you own a debit card.</Original>
  </Key>
  <Key ID="STR_Debit_Clothing_UsedOnHandCash">
    <Original>You purchased clothing with your on-hand cash since it was on your person. Total amount paid: &lt;t color='#8cff9b'&gt;$%1.&lt;/t&gt;</Original>
  </Key>
  <Key ID="STR_Debit_Virt_SellItem">
    <Original>You sold %1 %2(s) for &lt;t color='#8cff9b'&gt;$%3.&lt;/t&gt; The money was added to your bank account since you own a debit card.</Original>
  </Key>
  <Key ID="STR_Debit_Virt_BoughtItemTax">
    <Original>You bought %1 %2(s) for &lt;t color='#8cff9b'&gt;$%3.&lt;/t&gt; You also paid &lt;t color='#8cff9b'&gt;$%4&lt;/t&gt; in tax for using your debit card.</Original>
  </Key>
  <Key ID="STR_Debit_Virt_BoughtItem">
    <Original>You purchased %1 %2(s) for &lt;t color='#8cff9b'&gt;$%3.&lt;/t&gt; The money was taken from your bank account since you own a debit card.</Original>
  </Key>
  <Key ID="STR_Debit_Virt_UsedOnHandCash">
    <Original>You purchased %1 %2(s) with your on-hand cash since it was on your person. Total amount paid: &lt;t color='#8cff9b'&gt;$%3.&lt;/t&gt;</Original>
  </Key>
</Package>

 

9. Open cfgRemoteExec.hpp and add the following Server Only Function: IF YOU PLAN ON INSTALLING THE VIRTUAL ITEM ADDON FEEL FREE TO IGNORE THIS

F(TON_fnc_debitBought,SERVER)

 

Life_Server

IF YOU PLAN ON INSTALLING THE VIRTUAL ITEM ADDON FEEL FREE TO IGNORE THIS SECTION

1. Open life_server\config.cpp and add the following class to class Systems:

class debitBought {};

 

2. Move fn_debitBought.sqf from your version of Altis Life you (should have) have downloaded from step 1 in to life_server\functions\systems

 

3. Go to life_server\Functions\MySQL and make the changes to the following files:

fn_queryRequest.sqf

For Altis Life 5.0.0:
 

Spoiler

Find:

_query = switch (_side) do {
    // West - 11 entries returned
    case west: {format ["SELECT pid, name, cash, bankacc, adminlevel, donorlevel, cop_licenses, coplevel, cop_gear, blacklist, cop_stats, playtime FROM players WHERE pid='%1'",_uid];};
    // Civilian - 12 entries returned
    case civilian: {format ["SELECT pid, name, cash, bankacc, adminlevel, donorlevel, civ_licenses, arrested, civ_gear, civ_stats, civ_alive, civ_position, playtime FROM players WHERE pid='%1'",_uid];};
    // Independent - 10 entries returned
    case independent: {format ["SELECT pid, name, cash, bankacc, adminlevel, donorlevel, med_licenses, mediclevel, med_gear, med_stats, playtime FROM players WHERE pid='%1'",_uid];};
};

Change to:

_query = switch (_side) do {
    // West - 12 entries returned
    case west: {format ["SELECT pid, name, cash, bankacc, adminlevel, donorlevel, cop_licenses, coplevel, cop_gear, blacklist, cop_stats, playtime, debit FROM players WHERE pid='%1'",_uid];};
    // Civilian - 13 entries returned
    case civilian: {format ["SELECT pid, name, cash, bankacc, adminlevel, donorlevel, civ_licenses, arrested, civ_gear, civ_stats, civ_alive, civ_position, playtime, debit FROM players WHERE pid='%1'",_uid];};
    // Independent - 11 entries returned
    case independent: {format ["SELECT pid, name, cash, bankacc, adminlevel, donorlevel, med_licenses, mediclevel, med_gear, med_stats, playtime, debit FROM players WHERE pid='%1'",_uid];};
};

Find:

switch (_side) do {
    case west: {
        _queryResult set[9,([_queryResult select 9,1] call DB_fnc_bool)];
 case civilian: {
        _queryResult set[7,([_queryResult select 7,1] call DB_fnc_bool)];
    case independent: {
        //Parse Stats
        _new = [(_queryResult select 9)] call DB_fnc_mresToArray;

Change to:

switch (_side) do {
    case west: {
        _queryResult set[9,([_queryResult select 9,1] call DB_fnc_bool)];
        _queryResult set[12,([_queryResult select 12,1] call DB_fnc_bool)];
    case civilian: {
        _queryResult set[7,([_queryResult select 7,1] call DB_fnc_bool)];
        _queryResult set[13,([_queryResult select 13,1] call DB_fnc_bool)];
    case independent: {
        _queryResult set[11,([_queryResult select 11,1] call DB_fnc_bool)];
        //Parse Stats
        _new = [(_queryResult select 9)] call DB_fnc_mresToArray;

 

 

For Altis Life 4.4r3:

Spoiler

Find:

_query = switch (_side) do {
    // West - 11 entries returned
    case west: {format["SELECT playerid, name, cash, bankacc, adminlevel, donorlevel, cop_licenses, coplevel, cop_gear, blacklist, cop_stats, playtime FROM players WHERE playerid='%1'",_uid];};
    // Civilian - 12 entries returned
    case civilian: {format["SELECT playerid, name, cash, bankacc, adminlevel, donorlevel, civ_licenses, arrested, civ_gear, civ_stats, civ_alive, civ_position, playtime FROM players WHERE playerid='%1'",_uid];};
    // Independent - 10 entries returned
    case independent: {format["SELECT playerid, name, cash, bankacc, adminlevel, donorlevel, med_licenses, mediclevel, med_gear, med_stats, playtime FROM players WHERE playerid='%1'",_uid];};
};

Change to:

_query = switch (_side) do {
    // West - 11 entries returned
    case west: {format["SELECT playerid, name, cash, bankacc, adminlevel, donorlevel, cop_licenses, coplevel, cop_gear, blacklist, cop_stats, playtime, debit FROM players WHERE playerid='%1'",_uid];};
    // Civilian - 12 entries returned
    case civilian: {format["SELECT playerid, name, cash, bankacc, adminlevel, donorlevel, civ_licenses, arrested, civ_gear, civ_stats, civ_alive, civ_position, playtime, debit FROM players WHERE playerid='%1'",_uid];};
    // Independent - 10 entries returned
    case independent: {format["SELECT playerid, name, cash, bankacc, adminlevel, donorlevel, med_licenses, mediclevel, med_gear, med_stats, playtime, debit FROM players WHERE playerid='%1'",_uid];};
};

Find:

    case west: {
        _queryResult set[9,([_queryResult select 9,1] call DB_fnc_bool)];
    case civilian: {
        _queryResult set[7,([_queryResult select 7,1] call DB_fnc_bool)];
    case independent: {
        //Parse Stats
        _new = [(_queryResult select 9)] call DB_fnc_mresToArray;

Change to:

    case west: {
        _queryResult set[9,([_queryResult select 9,1] call DB_fnc_bool)];
        _queryResult set[12,([_queryResult select 12,1] call DB_fnc_bool)];
    case civilian: {
        _queryResult set[7,([_queryResult select 7,1] call DB_fnc_bool)];
        _queryResult set[13,([_queryResult select 13,1] call DB_fnc_bool)];
    case independent: {
        _queryResult set[11,([_queryResult select 11,1] call DB_fnc_bool)];
        //Parse Stats
        _new = [(_queryResult select 9)] call DB_fnc_mresToArray;

Find:

_keyArr = missionNamespace getVariable [format["%1_KEYS_%2",_uid,_side],[]];
_queryResult set[15,_keyArr];

Change to:

_keyArr = missionNamespace getVariable [format["%1_KEYS_%2",_uid,_side],[]];
_queryResult set[16,_keyArr];

 

 

fn_updatePartial.sqf

Find:

    case 7: {
        _array = [_this,2,[],[[]]] call BIS_fnc_param;
        [_uid,_side,_array,0] call TON_fnc_keyManagement;
    };

Add under:

For Altis Life 5.0.0:

    case 8: {
        _query = format ["UPDATE players SET debit='1' WHERE pid='%1'",_uid];
    };

For Altis Life 4.4r3:

	case 8: {
        _query = format ["UPDATE players SET debit='1' WHERE playerid='%1'",_uid];
    };

 

fn_updateRequest.sqf

Find:

private ["_uid","_side","_cash","_bank","_licenses","_gear","_stats","_name","_alive","_position","_query","_thread"];
_uid = [_this,0,"",[""]] call BIS_fnc_param;
_name = [_this,1,"",[""]] call BIS_fnc_param;
_side = [_this,2,sideUnknown,[civilian]] call BIS_fnc_param;
_cash = [_this,3,0,[0]] call BIS_fnc_param;
_bank = [_this,4,5000,[0]] call BIS_fnc_param;
_licenses = [_this,5,[],[[]]] call BIS_fnc_param;
_gear = [_this,6,[],[[]]] call BIS_fnc_param;
_stats = [_this,7,[100,100],[[]]] call BIS_fnc_param;
_alive = [_this,9,false,[true]] call BIS_fnc_param;
_position = [_this,10,[],[[]]] call BIS_fnc_param;

Add to the Private array & below _position = [_this,10,[],[[]]] call BIS_fnc_param; (Make sure you add it, do not overwrite what's currently there)

private ["_debitCiv","_debit"];
_debitCiv = [_this,11,false,[true]] call BIS_fnc_param;
_debit = [_this,8,false,[true]] call BIS_fnc_param;

For Altis Life 5.0.0:

Spoiler

 

Find:

switch (_side) do {
    case west: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', cop_gear='%4', cop_licenses='%5', cop_stats='%6', playtime='%7' WHERE pid='%8'",_name,_cash,_bank,_gear,_licenses,_stats,_playtime_update,_uid];};
    case civilian: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', civ_licenses='%4', civ_gear='%5', arrested='%6', civ_stats='%7', civ_alive='%8', civ_position='%9', playtime='%10' WHERE pid='%11'",_name,_cash,_bank,_licenses,_gear,[_this select 8] call DB_fnc_bool,_stats,[_alive] call DB_fnc_bool,_position,_playtime_update,_uid];};
    case independent: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', med_licenses='%4', med_gear='%5', med_stats='%6', playtime='%7' WHERE pid='%8'",_name,_cash,_bank,_licenses,_gear,_stats,_playtime_update,_uid];};
};

Change to:

switch (_side) do {
    case west: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', cop_gear='%4', cop_licenses='%5', cop_stats='%6', playtime='%7', debit='%8' WHERE pid='%9'",_name,_cash,_bank,_gear,_licenses,_stats,_playtime_update,[_debit] call DB_fnc_bool,_uid];};
    case civilian: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', civ_licenses='%4', civ_gear='%5', arrested='%6', civ_stats='%7', civ_alive='%8', civ_position='%9', playtime='%10', debit='%11' WHERE pid='%12'",_name,_cash,_bank,_licenses,_gear,[_this select 8] call DB_fnc_bool,_stats,[_alive] call DB_fnc_bool,_position,_playtime_update,[_debitCiv] call DB_fnc_bool,_uid];};
    case independent: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', med_licenses='%4', med_gear='%5', med_stats='%6', playtime='%7', debit='%8' WHERE pid='%9'",_name,_cash,_bank,_licenses,_gear,_stats,_playtime_update,[_debit] call DB_fnc_bool,_uid];};
};

 

 

 

For Altis Life 4.4r3:

Spoiler

 

Find:

switch (_side) do {
    case west: {_query = format["UPDATE players SET name='%1', cash='%2', bankacc='%3', cop_gear='%4', cop_licenses='%5', cop_stats='%6', playtime='%7' WHERE playerid='%8'",_name,_cash,_bank,_gear,_licenses,_stats,_playtime_update,_uid];};
    case civilian: {_query = format["UPDATE players SET name='%1', cash='%2', bankacc='%3', civ_licenses='%4', civ_gear='%5', arrested='%6', civ_stats='%7', civ_alive='%8', civ_position='%9', playtime='%10' WHERE playerid='%11'",_name,_cash,_bank,_licenses,_gear,[_this select 8] call DB_fnc_bool,_stats,[_this select 9] call DB_fnc_bool,_position,_playtime_update,_uid];};
    case independent: {_query = format["UPDATE players SET name='%1', cash='%2', bankacc='%3', med_licenses='%4', med_gear='%5', med_stats='%6', playtime='%7' WHERE playerid='%8'",_name,_cash,_bank,_licenses,_gear,_stats,_playtime_update,_uid];};
};

Change to:

switch (_side) do {
    case west: {_query = format["UPDATE players SET name='%1', cash='%2', bankacc='%3', cop_gear='%4', cop_licenses='%5', cop_stats='%6', playtime='%7', debit='%8' WHERE playerid='%9'",_name,_cash,_bank,_gear,_licenses,_stats,_playtime_update,[_debit] call DB_fnc_bool,_uid];};
    case civilian: {_query = format["UPDATE players SET name='%1', cash='%2', bankacc='%3', civ_licenses='%4', civ_gear='%5', arrested='%6', civ_stats='%7', civ_alive='%8', civ_position='%9', playtime='%10', debit='%11' WHERE playerid='%12'",_name,_cash,_bank,_licenses,_gear,[_this select 8] call DB_fnc_bool,_stats,[_this select 9] call DB_fnc_bool,_position,_playtime_update,[_debitCiv] call DB_fnc_bool,_uid];};
    case independent: {_query = format["UPDATE players SET name='%1', cash='%2', bankacc='%3', med_licenses='%4', med_gear='%5', med_stats='%6', playtime='%7', debit='%8' WHERE playerid='%9'",_name,_cash,_bank,_licenses,_gear,_stats,_playtime_update,[_debit] call DB_fnc_bool,_uid];};
};

 

 

 

Database Changes

IF YOU PLAN ON INSTALLING THE VIRTUAL ITEM ADDON FEEL FREE TO IGNORE THIS

Execute the following on your database:

ALTER TABLE `players` ADD (`debit` int(1) NOT NULL DEFAULT '0');

 

Battleye

Add the following to your remoteexec.txt in your Battleye working directory:

!TON_fnc_debitBought

 

All done! All you need to do now is configure the settings to your preference and you should be good to go! 

I will be revising the scripts on this thread at some point, but at the moment I just don't have the time to do it. I also plan on implementing addons in the future which work alongside debit cards, so keep a look out!

 

If you run in to a problem, don't hesitate to PM me or post on the thread.

 

 

 

Debit Cards.rar

Edited by Ilusionz
4.4r3 Fixes
  • Like 8

Share this post


Link to post
Share on other sites

Have this implemented on my server, and it works perfectly. My only issue I had was the bank.hpp settings made the Debit Button collide and mesh with the other buttons. Pretty sure I messed up the install myself. Instead I created a button in the player menu and just called it Debit Card, and this works better for me. So far I'm able to purchase the card itself, I've used it to purchase clothes and vehicles, and it works perfectly. Thank you very much for this genius script. An idea for improvements would be maybe a Virtual Item itself, with an icon that can be purchased from an NPC in a bank or something like that. Apart from that, I've got no complaints.

Cheers

  • Like 1

Share this post


Link to post
Share on other sites
10 minutes ago, Rubidium said:

Have this implemented on my server, and it works perfectly. My only issue I had was the bank.hpp settings made the Debit Button collide and mesh with the other buttons. Pretty sure I messed up the install myself. Instead I created a button in the player menu and just called it Debit Card, and this works better for me. So far I'm able to purchase the card itself, I've used it to purchase clothes and vehicles, and it works perfectly. Thank you very much for this genius script. An idea for improvements would be maybe a Virtual Item itself, with an icon that can be purchased from an NPC in a bank or something like that. Apart from that, I've got no complaints.

Cheers

 

Thanks for the positive feedback. In regards to the issue you're having with the button, could you please take a screenshot of it and send it to me in a PM along with a copy of your bank.hpp? That's something I'd like to fix ASAP but I don't have that issue on my local server.

 

Also, while making this I did think of adding a virtual item, or some sort of item that displays you own a debit card. However, I'd much prefer the debit card to be persistent (unless people actually want to lose it on death). If people want, when I'm making changes in the future I will certainly consider the virtual item addition (or at least something along those lines).

Edited by Ilusionz
  • Like 1

Share this post


Link to post
Share on other sites

Rly Nice Work!!!

But will it work @ 4.4R4? 

Because i do it exactly like the tutorial. But on spawn it stuck by the blackscreen with the playinformation query....

Edited by SowIeDO

Share this post


Link to post
Share on other sites
6 hours ago, SowIeDO said:

Rly Nice Work!!!

But will it work @ 4.4R4? 

Because i do it exactly like the tutorial. But on spawn it stuck by the blackscreen with the playinformation query....

Sorry you're having trouble with it. IIRC 4.4Rx uses different queries. When I get back from work on Thursday, I'll add compatibility. Keep in mind I didn't design this with 4.4Rx.

  • Like 2

Share this post


Link to post
Share on other sites
18 hours ago, Repentz said:

Great script, works perfectly. Might I suggest making the card a virtual item which can be lost on death?

I will be looking in to this as soon as I can. 

Edited by Ilusionz

Share this post


Link to post
Share on other sites

Virtual Item Update

If you are using Altis Life 4.4r3 this is not supported *yet*

A few people wanted a virtual item version of the debit card that can be lost on death. Here's a quick update on how to do that for people who already have the scripts on their server. 

When players purchase the debit card from the bank, instead of updating the database, a debit card will be added to the player's inventory -- This is completely optional, of course. Once in the player's inventory they get all of the benefits from the debit cards. However once the player dies they lose it. If a player also picks up a debit card from a dead body they will in turn get all of the benefits.

 

Let's get to it.

 

1. Open Altis_Life.Altis\config\Config_Master.hpp and add the following to your existing Debit Card configuration:

item_debit = true; // Enables/Disables virtual debit cards (life_inv_debitcard) that can be lost on player death.

 

2. Open Altis_Life.Altis\config\Config_vItems.hpp and create the following class (Don't add it to any stores unless you want players to be able to buy it from places other than ATMs):

class debitCard {
    variable = "debitcard";
    displayName = "STR_Debit_Card";
    weight = 1;
    buyPrice = -1;
    sellPrice = -1;
    illegal = false;
    edible = -1;
    icon = "icons\ico_debit.paa";
};

 

3. Open Altis_Life.Altis\core\debit\fn_debitCheck.sqf and replace the entire file with the following:

#include "..\..\script_macros.hpp"
/*
    File: fn_debitCheck.sqf
    Author: Ilusionz

    Description:
    Master file for script execution if a player does/doesn't have a debit card.
	There's probably better ways to do it, I know.
*/
private ["_mode"];
_mode = param [0,0,[0]];

switch (_mode) do {
	case 0: {
		if (LIFE_SETTINGS(getNumber,"debit_clothing") isEqualTo 1) then {
			if ((LIFE_SETTINGS(getNumber,"item_debit") isEqualTo 1) && (life_inv_debitcard > 0)) then {
				[] call life_fnc_buyClothesDebit;
			} else {
				if (life_has_debit isEqualTo true) then {
					[] call life_fnc_buyClothesDebit;
				} else {
					[] call life_fnc_buyClothes;
				};
			};
		} else {
			[] call life_fnc_buyClothes;
		};
	};
	
	case 1: {
		if (LIFE_SETTINGS(getNumber,"debit_weapons") isEqualTo 1) then {
			if ((LIFE_SETTINGS(getNumber,"item_debit") isEqualTo 1) && (life_inv_debitcard > 0)) then {
				[] spawn life_fnc_weaponShopBuySellDebit; true;
			} else {
				if (life_has_debit isEqualTo true) then {
					[] spawn life_fnc_weaponShopBuySellDebit; true;
				} else {
					[] spawn life_fnc_weaponShopBuySell; true;
				};
			};
		} else {
			[] spawn life_fnc_weaponShopBuySell; true;
		};
	};
	
	case 2: {
		if (LIFE_SETTINGS(getNumber,"debit_vItems") isEqualTo 1) then {
			if ((LIFE_SETTINGS(getNumber,"item_debit") isEqualTo 1) && (life_inv_debitcard > 0)) then {
				[] spawn life_fnc_virt_buyDebit;
			} else {
				if (life_has_debit isEqualTo true) then {
					[] spawn life_fnc_virt_buyDebit;
				} else {
					[] spawn life_fnc_virt_buy;
				};
			};
		} else {
			[] spawn life_fnc_virt_buy;
		};
	};
	
	case 3: {
		if (LIFE_SETTINGS(getNumber,"debit_vehicles") isEqualTo 1) then {
			if ((LIFE_SETTINGS(getNumber,"item_debit") isEqualTo 1) && (life_inv_debitcard > 0)) then {
				[true] spawn life_fnc_vehicleShopBuyDebit;
			} else {
				if (life_has_debit isEqualTo true) then {
					[true] spawn life_fnc_vehicleShopBuyDebit;
				} else {
					[true] spawn life_fnc_vehicleShopBuy;
				};
			};
		} else {
			[true] spawn life_fnc_vehicleShopBuy;
		};
	};
	
	case 4: {
		if (LIFE_SETTINGS(getNumber,"debit_vItems") isEqualTo 1) then {
			if ((LIFE_SETTINGS(getNumber,"item_debit") isEqualTo 1) && (life_inv_debitcard > 0)) then {
				[] spawn life_fnc_virt_sellDebit;
			} else {
				if (life_has_debit isEqualTo true) then {
					[] spawn life_fnc_virt_sellDebit;
				} else {
					[] spawn life_fnc_virt_sell;
				};
			};
		} else {
			[] spawn life_fnc_virt_sell;
		};
	};
	
	case 5: {
		if (LIFE_SETTINGS(getNumber,"debit_vehicles") isEqualTo 1) then {
			if ((LIFE_SETTINGS(getNumber,"item_debit") isEqualTo 1) && (life_inv_debitcard > 0)) then {
				[false] spawn life_fnc_vehicleShopBuyDebit;
			} else {
				if (life_has_debit isEqualTo true) then {
					[false] spawn life_fnc_vehicleShopBuyDebit;
				} else {
					[false] spawn life_fnc_vehicleShopBuy;
				};
			};
		} else {
			[false] spawn life_fnc_vehicleShopBuy;
		};
	};
};

 

4. Open Altis_Life.Altis\core\debit\fn_buyDebit.sqf and replace the entire file with the following:

#include "..\..\script_macros.hpp"
/*
    File: fn_buyDebit.sqf
    Author: Ilusionz

    Description:
    Handles the purchase of Debit Cards from the ATM Menu.
*/
private ["_debitPrice","_id"];
_id = getPlayerUID player;
_debitPrice = LIFE_SETTINGS(getNumber,"debit_price");
if (life_has_debit isEqualTo true) exitWith {hint localize "STR_Debit_AlreadyOwned"};
if ((LIFE_SETTINGS(getNumber,"item_debit") isEqualTo 1) && (life_inv_debitcard > 0)) exitWith {hint localize "STR_Debit_AlreadyOwned"};
if (_debitPrice > CASH) exitWith {hint format [localize "STR_Debit_NotEnoughCash",[_debitPrice - CASH] call life_fnc_numberText];};
CASH = CASH - _debitPrice;

if (life_HC_isActive) then {
    [_id] remoteExecCall ["HC_fnc_debitBought",HC_Life];
} else {
    [_id] remoteExecCall ["TON_fnc_debitBought",RSERV];
};

if (LIFE_SETTINGS(getNumber,"item_debit") isEqualTo 1) then {
	[true,"debitcard",1] call life_fnc_handleInv; 
	[3] call SOCK_fnc_updatePartial;
	[] call life_fnc_atmMenu;
} else {
	life_has_debit = true;
	[8] call SOCK_fnc_updatePartial;
	[] call life_fnc_atmMenu;
};

hint format [localize "STR_Debit_Purchased",[_debitPrice] call life_fnc_numberText];

 

5. Open Altis_Life.Altis\stringtable.xml and add the following string to the existing Debit Card package:

<Key ID="STR_Debit_Card">
    <Original>Debit Card</Original>
</Key>

 

6. Download the icon attached to this thread and move it to Altis_Life.Altis\icons

All done! 

 

If you run in to any issues, as always send me a PM or reply to the thread.

ico_debit.paa

Edited by Ilusionz
  • Like 2

Share this post


Link to post
Share on other sites
4 hours ago, altislifenoob said:

can someone try and test this on 4.4 or have a way to work for 4.4 please.  

I tested on 4.4R4 but it doesnt work. Without doubt its a rly great script. And a compatibility would be nice.

Edited by SowIeDO

Share this post


Link to post
Share on other sites

i keep getting 

14:06:19 Error in expression <licenses,_stats,_playtime_update,[_this select 11] call DB_fnc_bool,_uid];};
cas>
14:06:19   Error position: <select 11] call DB_fnc_bool,_uid];};
cas>
14:06:19   Error Zero divisor
14:06:19 File \life_server\Functions\MySQL\fn_updateRequest.sqf [DB_fnc_updateRequest], line 59

my updaterequest 

/*
    File: fn_updateRequest.sqf
    Author: Bryan "Tonic" Boardwine

    Description:
    Updates ALL player information in the database.
    Information gets passed here from the client side file: core\session\fn_updateRequest.sqf
*/
private ["_uid","_side","_cash","_bank","_licenses","_gear","_stats","_name","_alive","_position","_query","_thread","_debit"];
_uid = [_this,0,"",[""]] call BIS_fnc_param;
_name = [_this,1,"",[""]] call BIS_fnc_param;
_side = [_this,2,sideUnknown,[civilian]] call BIS_fnc_param;
_cash = [_this,3,0,[0]] call BIS_fnc_param;
_bank = [_this,4,5000,[0]] call BIS_fnc_param;
_licenses = [_this,5,[],[[]]] call BIS_fnc_param;
_gear = [_this,6,[],[[]]] call BIS_fnc_param;
_stats = [_this,7,[100,100],[[]]] call BIS_fnc_param;
_alive = [_this,9,false,[true]] call BIS_fnc_param;
_position = [_this,10,[],[[]]] call BIS_fnc_param;
_debit = [_this,11,false,[true]] call BIS_fnc_param;

//Get to those error checks.
if ((_uid isEqualTo "") || (_name isEqualTo "")) exitWith {};

//Parse and setup some data.
_name = [_name] call DB_fnc_mresString;
_gear = [_gear] call DB_fnc_mresArray;
_stats = [_stats] call DB_fnc_mresArray;
_cash = [_cash] call DB_fnc_numberSafe;
_bank = [_bank] call DB_fnc_numberSafe;
_position = if (_side isEqualTo civilian) then {[_position] call DB_fnc_mresArray} else {[]};

//Does something license related but I can't remember I only know it's important?
for "_i" from 0 to count(_licenses)-1 do {
    _bool = [(_licenses select _i) select 1] call DB_fnc_bool;
    _licenses set[_i,[(_licenses select _i) select 0,_bool]];
};

_licenses = [_licenses] call DB_fnc_mresArray;

//PLAYTIME
_playtime = [_uid] call TON_fnc_getPlayTime;
_playtime_update = [];
{
    if ((_x select 0) isEqualTo _uid) exitWith
    {
        _playtime_update pushBack [_x select 1];
    };
} forEach TON_fnc_playtime_values_request;
_playtime_update = (_playtime_update select 0) select 0;
switch (_side) do {
    case west: {_playtime_update set[0,_playtime];};
    case civilian: {_playtime_update set[2,_playtime];};
    case independent: {_playtime_update set[1,_playtime];};
};
_playtime_update = [_playtime_update] call DB_fnc_mresArray;

switch (_side) do {
    case west: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', cop_gear='%4', cop_licenses='%5', cop_stats='%6', playtime='%7', debit='%8' WHERE pid='%9'",_name,_cash,_bank,_gear,_licenses,_stats,_playtime_update,[_this select 11] call DB_fnc_bool,_uid];};
    case civilian: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', civ_licenses='%4', civ_gear='%5', arrested='%6', civ_stats='%7', civ_alive='%8', civ_position='%9', playtime='%10', debit='%11', WHERE pid='%12'",_name,_cash,_bank,_licenses,_gear,[_this select 8] call DB_fnc_bool,_stats,[_alive] call DB_fnc_bool,_position,_playtime_update,[_this select 11] call DB_fnc_bool,_uid];};
    case independent: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', med_licenses='%4', med_gear='%5', med_stats='%6', playtime='%7', debit='%8' WHERE pid='%9'",_name,_cash,_bank,_licenses,_gear,_stats,_playtime_update,[_this select 11] call DB_fnc_bool,_uid];};
};


_queryResult = [_query,1] call DB_fnc_asyncCall;

also EXTDB

[14:10:43:769945 +01:00] [Thread 6404] extDB3: SQL: Error MariaDBQueryException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'WHERE pid='76561198084588168'' at line 1
[14:10:43:770020 +01:00] [Thread 6404] extDB3: SQL: Error MariaDBQueryException: Input: UPDATE players SET name='SUPT Hunter', cash='0', bankacc='900000', civ_licenses='"[[`license_civ_driver`,0],[`license_civ_boat`,0],[`license_civ_pilot`,0],[`license_civ_trucking`,0],[`license_civ_gun`,0],[`license_civ_dive`,0],[`license_civ_bountyH`,0],[`license_civ_home`,0],[`license_civ_oil`,0],[`license_civ_diamond`,0],[`license_civ_salt`,0],[`license_civ_sand`,0],[`license_civ_iron`,0],[`license_civ_copper`,0],[`license_civ_cement`,0],[`license_civ_medmarijuana`,0],[`license_civ_cocaine`,0],[`license_civ_heroin`,0],[`license_civ_marijuana`,0],[`license_civ_rebel`,0],[`license_civ_uranium`,0]]"', civ_gear='"[`U_C_Poloshirt_burgundy`,``,``,``,``,[`ItemMap`,`ItemCompass`,`ItemWatch`,`NVGoggles`],``,``,[],[],[],[],[],[],[``,``,``,``],[``,``,``,``],[]]"', arrested='0', civ_stats='"[100,100,0]"', civ_alive='1', civ_position='"[3699.66,13115.4,1.48681]"', playtime='"[2441,0,1]"', debit='0', WHERE pid='76561198084588168'

 

Edited by armagod

Share this post


Link to post
Share on other sites
2 hours ago, armagod said:

i keep getting 

14:06:19 Error in expression <licenses,_stats,_playtime_update,[_this select 11] call DB_fnc_bool,_uid];};
cas>
14:06:19   Error position: <select 11] call DB_fnc_bool,_uid];};
cas>
14:06:19   Error Zero divisor
14:06:19 File \life_server\Functions\MySQL\fn_updateRequest.sqf [DB_fnc_updateRequest], line 59

my updaterequest 

/*
    File: fn_updateRequest.sqf
    Author: Bryan "Tonic" Boardwine

    Description:
    Updates ALL player information in the database.
    Information gets passed here from the client side file: core\session\fn_updateRequest.sqf
*/
private ["_uid","_side","_cash","_bank","_licenses","_gear","_stats","_name","_alive","_position","_query","_thread","_debit"];
_uid = [_this,0,"",[""]] call BIS_fnc_param;
_name = [_this,1,"",[""]] call BIS_fnc_param;
_side = [_this,2,sideUnknown,[civilian]] call BIS_fnc_param;
_cash = [_this,3,0,[0]] call BIS_fnc_param;
_bank = [_this,4,5000,[0]] call BIS_fnc_param;
_licenses = [_this,5,[],[[]]] call BIS_fnc_param;
_gear = [_this,6,[],[[]]] call BIS_fnc_param;
_stats = [_this,7,[100,100],[[]]] call BIS_fnc_param;
_alive = [_this,9,false,[true]] call BIS_fnc_param;
_position = [_this,10,[],[[]]] call BIS_fnc_param;
_debit = [_this,11,false,[true]] call BIS_fnc_param;

//Get to those error checks.
if ((_uid isEqualTo "") || (_name isEqualTo "")) exitWith {};

//Parse and setup some data.
_name = [_name] call DB_fnc_mresString;
_gear = [_gear] call DB_fnc_mresArray;
_stats = [_stats] call DB_fnc_mresArray;
_cash = [_cash] call DB_fnc_numberSafe;
_bank = [_bank] call DB_fnc_numberSafe;
_position = if (_side isEqualTo civilian) then {[_position] call DB_fnc_mresArray} else {[]};

//Does something license related but I can't remember I only know it's important?
for "_i" from 0 to count(_licenses)-1 do {
    _bool = [(_licenses select _i) select 1] call DB_fnc_bool;
    _licenses set[_i,[(_licenses select _i) select 0,_bool]];
};

_licenses = [_licenses] call DB_fnc_mresArray;

//PLAYTIME
_playtime = [_uid] call TON_fnc_getPlayTime;
_playtime_update = [];
{
    if ((_x select 0) isEqualTo _uid) exitWith
    {
        _playtime_update pushBack [_x select 1];
    };
} forEach TON_fnc_playtime_values_request;
_playtime_update = (_playtime_update select 0) select 0;
switch (_side) do {
    case west: {_playtime_update set[0,_playtime];};
    case civilian: {_playtime_update set[2,_playtime];};
    case independent: {_playtime_update set[1,_playtime];};
};
_playtime_update = [_playtime_update] call DB_fnc_mresArray;

switch (_side) do {
    case west: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', cop_gear='%4', cop_licenses='%5', cop_stats='%6', playtime='%7', debit='%8' WHERE pid='%9'",_name,_cash,_bank,_gear,_licenses,_stats,_playtime_update,[_this select 11] call DB_fnc_bool,_uid];};
    case civilian: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', civ_licenses='%4', civ_gear='%5', arrested='%6', civ_stats='%7', civ_alive='%8', civ_position='%9', playtime='%10', debit='%11', WHERE pid='%12'",_name,_cash,_bank,_licenses,_gear,[_this select 8] call DB_fnc_bool,_stats,[_alive] call DB_fnc_bool,_position,_playtime_update,[_this select 11] call DB_fnc_bool,_uid];};
    case independent: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', med_licenses='%4', med_gear='%5', med_stats='%6', playtime='%7', debit='%8' WHERE pid='%9'",_name,_cash,_bank,_licenses,_gear,_stats,_playtime_update,[_this select 11] call DB_fnc_bool,_uid];};
};


_queryResult = [_query,1] call DB_fnc_asyncCall;

also EXTDB

[14:10:43:769945 +01:00] [Thread 6404] extDB3: SQL: Error MariaDBQueryException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'WHERE pid='76561198084588168'' at line 1
[14:10:43:770020 +01:00] [Thread 6404] extDB3: SQL: Error MariaDBQueryException: Input: UPDATE players SET name='SUPT Hunter', cash='0', bankacc='900000', civ_licenses='"[[`license_civ_driver`,0],[`license_civ_boat`,0],[`license_civ_pilot`,0],[`license_civ_trucking`,0],[`license_civ_gun`,0],[`license_civ_dive`,0],[`license_civ_bountyH`,0],[`license_civ_home`,0],[`license_civ_oil`,0],[`license_civ_diamond`,0],[`license_civ_salt`,0],[`license_civ_sand`,0],[`license_civ_iron`,0],[`license_civ_copper`,0],[`license_civ_cement`,0],[`license_civ_medmarijuana`,0],[`license_civ_cocaine`,0],[`license_civ_heroin`,0],[`license_civ_marijuana`,0],[`license_civ_rebel`,0],[`license_civ_uranium`,0]]"', civ_gear='"[`U_C_Poloshirt_burgundy`,``,``,``,``,[`ItemMap`,`ItemCompass`,`ItemWatch`,`NVGoggles`],``,``,[],[],[],[],[],[],[``,``,``,``],[``,``,``,``],[]]"', arrested='0', civ_stats='"[100,100,0]"', civ_alive='1', civ_position='"[3699.66,13115.4,1.48681]"', playtime='"[2441,0,1]"', debit='0', WHERE pid='76561198084588168'

 

 

Do you use this by any chance? 

 

Share this post


Link to post
Share on other sites

Mandatory update if you're using database saving:

Fixed an issue where cop/medic debit cards weren't saving to the Database and were causing errors.

Also fixes this:

If you've already installed these scripts, please update the following files:

(tutorial has also been updated)

 

life_server\Functions\MySQL\fn_updateRequest.sqf

/*
    File: fn_updateRequest.sqf
    Author: Bryan "Tonic" Boardwine

    Description:
    Updates ALL player information in the database.
    Information gets passed here from the client side file: core\session\fn_updateRequest.sqf
*/
private ["_uid","_side","_cash","_bank","_licenses","_gear","_stats","_name","_alive","_position","_query","_thread","_debitCiv","_debit"];
_uid = [_this,0,"",[""]] call BIS_fnc_param;
_name = [_this,1,"",[""]] call BIS_fnc_param;
_side = [_this,2,sideUnknown,[civilian]] call BIS_fnc_param;
_cash = [_this,3,0,[0]] call BIS_fnc_param;
_bank = [_this,4,5000,[0]] call BIS_fnc_param;
_licenses = [_this,5,[],[[]]] call BIS_fnc_param;
_gear = [_this,6,[],[[]]] call BIS_fnc_param;
_stats = [_this,7,[100,100],[[]]] call BIS_fnc_param;
_alive = [_this,9,false,[true]] call BIS_fnc_param;
_position = [_this,10,[],[[]]] call BIS_fnc_param;
_debitCiv = [_this,11,false,[true]] call BIS_fnc_param;
_debit = [_this,8,false,[true]] call BIS_fnc_param;
switch (_side) do {
    case west: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', cop_gear='%4', cop_licenses='%5', cop_stats='%6', playtime='%7', debit='%8' WHERE pid='%9'",_name,_cash,_bank,_gear,_licenses,_stats,_playtime_update,[_debit] call DB_fnc_bool,_uid];};
    case civilian: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', civ_licenses='%4', civ_gear='%5', arrested='%6', civ_stats='%7', civ_alive='%8', civ_position='%9', playtime='%10', debit='%11' WHERE pid='%12'",_name,_cash,_bank,_licenses,_gear,[_this select 8] call DB_fnc_bool,_stats,[_alive] call DB_fnc_bool,_position,_playtime_update,[_debitCiv] call DB_fnc_bool,_uid];};
    case independent: {_query = format ["UPDATE players SET name='%1', cash='%2', bankacc='%3', med_licenses='%4', med_gear='%5', med_stats='%6', playtime='%7', debit='%8' WHERE pid='%9'",_name,_cash,_bank,_licenses,_gear,_stats,_playtime_update,[_debit] call DB_fnc_bool,_uid];};
};

 

Altis_Life.Altis\core\session\fn_updateRequest.sqf

#include "..\..\script_macros.hpp"
/*
    File: fn_updateRequest.sqf
    Author: Tonic

    Description:
    Passes ALL player information to the server to save player data to the database.
*/
private ["_packet","_array","_flag","_alive","_position"];
_packet = [getPlayerUID player,(profileName),playerSide,CASH,BANK];
_array = [];
_alive = alive player;
_position = getPosATL player;
_flag = switch (playerSide) do {case west: {"cop"}; case civilian: {"civ"}; case independent: {"med"};};

{
    _varName = LICENSE_VARNAME(configName _x,_flag);
    _array pushBack [_varName,LICENSE_VALUE(configName _x,_flag)];
} forEach (format ["getText(_x >> 'side') isEqualTo '%1'",_flag] configClasses (missionConfigFile >> "Licenses"));

_packet pushBack _array;

[] call life_fnc_saveGear;
_packet pushBack life_gear;

_array = [];
_array pushBack life_hunger;
_array pushBack life_thirst;
_array pushBack (damage player);
_packet pushBack _array;

switch (playerSide) do {
    case civilian: {
        _packet pushBack life_is_arrested;
        _packet pushBack _alive;
        _packet pushBack _position;
        _packet pushBack life_has_debit;
    };
	
    case west: {
        _packet pushBack life_has_debit;
    };
	
    case independent: {
        _packet pushBack life_has_debit;
    };
};

if (life_HC_isActive) then {
    _packet remoteExecCall ["HC_fnc_updateRequest",HC_Life];
} else {
    _packet remoteExecCall ["DB_fnc_updateRequest",RSERV];
};

 

Edited by Ilusionz

Share this post


Link to post
Share on other sites

Added compatibility for Altis Life 4.4r3.

Virtual Item Compatibility will be coming in the future.

 

Huge thanks to @CptGooch for helping out. Helped me avoid one hell of a headache.

  • Like 1

Share this post


Link to post
Share on other sites

Thanks for updating this on 4.4R4. It works!! But we have a little problem. Helicopters from the medic heli shop spawn on the roof of the hospital again. We have made other spawnpoints for this. And now they spawn on the standartspawnpoints. Do you know how to fix this?

And there a little errors after installing the script. If you buy something in a shop. 

Error Undefined variable in expression: ton_fnc_terrainsort
File core\debit\fn_virt_buyDebit.sqf [life_fnc_virt_buyDebit], line 77
Error in expression <isArray], ["Tanoa", _tanoaArray]]] call TON_fnc_terrainSort;
                               
Error position: <TON_fnc_terrainSort;
private _hideout = >
Error Undefined variable in expression: ton_fnc_terrainsort
File core\debit\fn_weaponShopBuySellDebit.sqf [life_fnc_weaponShopBuySellDebit], line 91
Error in expression <isArray], ["Tanoa", _tanoaArray]]] call TON_fnc_terrainSort;

EDIT: OK we fixed at this moment the problem with the Helispawnpoint. But the Errors still there.

Edited by SowIeDO

Share this post


Link to post
Share on other sites
3 hours ago, SowIeDO said:

Thanks for updating this on 4.4R4. It works!! But we have a little problem. Helicopters from the medic heli shop spawn on the roof of the hospital again. We have made other spawnpoints for this. And now they spawn on the standartspawnpoints. Do you know how to fix this?

And there a little errors after installing the script. If you buy something in a shop. 

Error Undefined variable in expression: ton_fnc_terrainsort
File core\debit\fn_virt_buyDebit.sqf [life_fnc_virt_buyDebit], line 77
Error in expression <isArray], ["Tanoa", _tanoaArray]]] call TON_fnc_terrainSort;
                               
Error position: <TON_fnc_terrainSort;
private _hideout = >
Error Undefined variable in expression: ton_fnc_terrainsort
File core\debit\fn_weaponShopBuySellDebit.sqf [life_fnc_weaponShopBuySellDebit], line 91
Error in expression <isArray], ["Tanoa", _tanoaArray]]] call TON_fnc_terrainSort;

EDIT: OK we fixed at this moment the problem with the Helispawnpoint. But the Errors still there.

 

Fixed.

Please re-download the .rar file, and move the new fn_weaponShopBuySellDebit.sqf and fn_virt_buyDebit.sqf over to your server and over-write the old files.

Apologies for any inconvenience.

If anyone else is also having the same issue, please do the same (this is for 4.4r3 only).

 

Also, if anyone is having issues with players respawning with no gear, or licenses, please check your fn_mresArray.sqf is updated with the following fix: (4.4r3 only)

https://github.com/AsYetUntitled/Framework/commit/db66e545ef02faec2a2e9fd152eb5260b3deab8a

Thanks again @Jason_000!

  • Like 2

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...