Hier zeige ich euch wie ihr beim Kauf eines Autos ein zufälliges Kennzeichen bekommt und dieses dann auch immer angezeigt wird und später an der Garage geändert werden kann.
geht in eure fn_vehicleShopBuy.sqf dort tragt ihr vor
folgendes ein
_char1 = selectRandom ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
_char2 = selectRandom ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
_vehicle setPlateNumber format["NN-%1%2-%3",_char1,_char2,round(random(1000000))];
_vehicle allowDamage true;
private _plate = getPlateNumber _vehicle;
private _vehicleOwner = name player;
weiter unten ersetzt ihr die if-Abfrage mit folgendem
if (_mode) then {
if !(_className in LIFE_SETTINGS(getArray,"vehicleShop_rentalOnly")) then {
if (life_HC_isActive) then {
[(getPlayerUID player),playerSide,_vehicle,_colorIndex,_plate,_vehicleOwner] remoteExecCall ["HC_fnc_vehicleCreate",HC_Life];
} else {
[(getPlayerUID player),playerSide,_vehicle,_colorIndex,_plate,_vehicleOwner] remoteExecCall ["TON_fnc_vehicleCreate",RSERV];
};
};
};
danach geht ihr in euren life_server und ersetzt eure fn_vehicleCreate.sqf
/*
File: fn_vehicleCreate.sqf
Author: Bryan "Tonic" Boardwine
Description:
Answers the query request to create the vehicle in the database.
*/
params [
["_uid", "", [""]],
["_side", sideUnknown, [west]],
["_vehicle", objNull, [objNull]],
["_color", -1, [0]],
["_plate", "", [""]],
"_vehicleOwner"
];
diag_log format ["vehicleCreate %1",_plate];
//Error checks
if (_uid isEqualTo "" || {_side isEqualTo sideUnknown} || {isNull _vehicle}) exitWith {};
if (!alive _vehicle) exitWith {};
private _className = typeOf _vehicle;
private _type = switch (true) do {
case (_vehicle isKindOf "Car"): {"Car"};
case (_vehicle isKindOf "Air"): {"Air"};
case (_vehicle isKindOf "Ship"): {"Ship"};
};
_side = switch (_side) do {
case west:{"cop"};
case civilian: {"civ"};
case independent: {"med"};
default {"Error"};
};
[_uid, _side, _type, _classname, _color, _plate, _vehicleOwner] call DB_fnc_insertVehicle;
_vehicle setVariable ["dbInfo", [_uid, _plate], true];
Alles anzeigen
als nächstes gehen wir in die fn_insertVehicle.sqf welche auch in eurem life_server ist und ersetzten diese.
/*
File: fn_insertVehicle.sqf
Author: Bryan "Tonic" Boardwine
Description:
Inserts the vehicle into the database
*/
params [
"_uid",
"_side",
"_type",
"_className",
["_color",-1,[0]],
["_plate", "", [""]],
"_vehicleOwner"
];
//Stop bad data being passed.
if (_uid isEqualTo "" || {_side isEqualTo ""} || {_type isEqualTo ""} || {_className isEqualTo ""} || {_color isEqualTo -1} || {_plate isEqualTo ""} || {_vehicleOwner isEqualTo ""}) exitWith {};
private _query = format ["INSERT INTO vehicles (side, classname, type, pid, alive, active, inventory, color, plate, gear, damage, owner) VALUES ('%1', '%2', '%3', '%4', '1','1','""[[],0]""', '%5', '%6','""[]""','""[]""','%7')", _side, _className, _type, _uid, _color, _plate, _vehicleOwner];
[_query,1] call DB_fnc_asyncCall;
Alles anzeigen
vergesst nicht in eure DB den eintrag owner bei den Fahrzeugen zu machen.
CREATE TABLE IF NOT EXISTS `vehicles` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`side` varchar(16) NOT NULL,
`classname` varchar(64) NOT NULL,
`type` varchar(16) NOT NULL,
`pid` varchar(17) NOT NULL,
`alive` tinyint(1) NOT NULL DEFAULT '1',
`blacklist` tinyint(1) NOT NULL DEFAULT '0',
`active` tinyint(1) NOT NULL DEFAULT '0',
`plate` varchar(16) NOT NULL,
`owner` varchar(64) NOT NULL,
`color` int(20) NOT NULL,
`inventory` text NOT NULL,
`gear` text NOT NULL,
`fuel` double NOT NULL DEFAULT '1',
`damage` varchar(256) NOT NULL,
`insert_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `side` (`side`),
KEY `pid` (`pid`),
KEY `type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=2;
Alles anzeigen
in eurer Mission ergänzt ihr noch eure fn_impoundMenu.sqf
#include "..\..\script_macros.hpp"
/*
File: fn_impoundMenu.sqf
Author: Bryan "Tonic" Boardwine
Description:
Not actually a impound menu, may act as confusion to some but that is what I wanted.
The purpose of this menu is it is now called a 'Garage' where vehicles are stored (persistent ones).
*/
disableSerialization;
params[
["_vehicles",[],[[]]],
"_plate"
];
ctrlShow[2803,false];
ctrlShow[2830,false];
waitUntil {!isNull (findDisplay 2800)};
if (count _vehicles isEqualTo 0) exitWith {
ctrlSetText[2811,localize "STR_Garage_NoVehicles"];
};
private _control = CONTROL(2800,2802);
lbClear _control;
{
_vehicleInfo = [(_x select 2)] call life_fnc_fetchVehInfo;
_control lbAdd (_vehicleInfo select 3);
_tmp = [(_x select 2),(_x select 8),(_x select 7)];
_tmp = str(_tmp);
_control lbSetData [(lbSize _control)-1,_tmp];
_control lbSetPicture [(lbSize _control)-1,(_vehicleInfo select 2)];
_control lbSetValue [(lbSize _control)-1,(_x select 0)];
} forEach _vehicles;
ctrlShow[2810,false];
ctrlShow[2811,false];
Alles anzeigen
dann noch eure fn_garageLBChange.sqf
#include "..\..\script_macros.hpp"
/*
File: fn_garageLBChange.sqf
Author: Bryan "Tonic" Boardwine
Description:
Can't be bothered to answer it.. Already deleted it by accident..
*/
disableSerialization;
params[
"_control",
"_index"
];
//Fetch some information.
private _dataArr = CONTROL_DATAI(_control,_index);
_dataArr = call compile format ["%1",_dataArr];
private _className = (_dataArr select 0);
private _classNameLife = _className;
private _plate = (_dataArr select 2);
if (!isClass (missionConfigFile >> "LifeCfgVehicles" >> _classNameLife)) then {
_classNameLife = "Default"; //Use Default class if it doesn't exist
diag_log format ["%1: LifeCfgVehicles class doesn't exist",_className];
};
private _vehicleColor = ((M_CONFIG(getArray,"LifeCfgVehicles",_classNameLife,"textures") select (_dataArr select 1)) select 0);
if (isNil "_vehicleColor") then {_vehicleColor = "Default";};
private _vehicleInfo = [_className] call life_fnc_fetchVehInfo;
private _trunkSpace = [_className] call life_fnc_vehicleWeightCfg;
private _price = M_CONFIG(getNumber,"LifeCfgVehicles",_classNameLife,"price");
private _storageFee = LIFE_SETTINGS(getNumber,"vehicle_storage_fee_multiplier");
private "_sellMultiplier";
private "_purchasePrice";
switch (playerSide) do {
case civilian: {
_purchasePrice = _price * LIFE_SETTINGS(getNumber,"vehicle_purchase_multiplier_CIVILIAN");
_sellMultiplier = LIFE_SETTINGS(getNumber,"vehicle_sell_multiplier_CIVILIAN");
};
case west: {
_purchasePrice = _price * LIFE_SETTINGS(getNumber,"vehicle_purchase_multiplier_COP");
_sellMultiplier = LIFE_SETTINGS(getNumber,"vehicle_sell_multiplier_COP");
};
case independent: {
_purchasePrice = _price * LIFE_SETTINGS(getNumber,"vehicle_purchase_multiplier_MEDIC");
_sellMultiplier = LIFE_SETTINGS(getNumber,"vehicle_sell_multiplier_MEDIC");
};
case east: {
_purchasePrice = _price * LIFE_SETTINGS(getNumber,"vehicle_purchase_multiplier_OPFOR");
_sellMultiplier = LIFE_SETTINGS(getNumber,"vehicle_sell_multiplier_OPFOR");
};
};
private _retrievePrice = _purchasePrice * _storageFee;
private _sellPrice = _purchasePrice * _sellMultiplier;
if (!(_sellPrice isEqualType 0) || _sellPrice < 1) then {_sellPrice = 500;};
if (!(_retrievePrice isEqualType 0) || _retrievePrice < 1) then {_retrievePrice = 500;};
(CONTROL(2800,2803)) ctrlSetStructuredText parseText format [
(localize "STR_Shop_Veh_UI_RetrievalP")+ " <t color='#8cff9b'>$%1</t><br/>
" +(localize "STR_Shop_Veh_UI_SellP")+ " <t color='#8cff9b'>$%2</t><br/>
" +(localize "STR_Shop_Veh_UI_Color")+ " %8<br/>
Kennzeichen: %9<br/>
" +(localize "STR_Shop_Veh_UI_MaxSpeed")+ " %3 km/h<br/>
" +(localize "STR_Shop_Veh_UI_HPower")+ " %4<br/>
" +(localize "STR_Shop_Veh_UI_PSeats")+ " %5<br/>
" +(localize "STR_Shop_Veh_UI_Trunk")+ " %6<br/>
" +(localize "STR_Shop_Veh_UI_Fuel")+ " %7
",
[_retrievePrice] call life_fnc_numberText,
[_sellPrice] call life_fnc_numberText,
(_vehicleInfo select 8),
(_vehicleInfo select 11),
(_vehicleInfo select 10),
if (_trunkSpace isEqualTo -1) then {"None"} else {_trunkSpace},
(_vehicleInfo select 12),
_vehicleColor,
_plate
];
ctrlShow [2803,true];
ctrlShow [2830,true];
Alles anzeigen
nochmal in eurem life_server die fn_spawnVehicle.sqf
#include "\life_server\script_macros.hpp"
/*
File: fn_spawnVehicle.sqf
Author: Bryan "Tonic" Boardwine
Description:
Sends the query request to the database, if an array is returned then it creates
the vehicle if it's not in use or dead.
*/
params [
["_vid", -1, [0]],
["_pid", "", [""]],
["_sp", [], [[],""]],
["_unit", objNull, [objNull]],
["_price", 0, [0]],
["_dir", 0, [0]],
"_spawntext"
];
private _unit_return = _unit;
private _name = name _unit;
private _side = side _unit;
_unit = owner _unit;
if (_vid isEqualTo -1 || {_pid isEqualTo ""}) exitWith {};
if (_vid in serv_sv_use) exitWith {};
serv_sv_use pushBack _vid;
private _servIndex = serv_sv_use find _vid;
private _query = format ["SELECT id, side, classname, type, pid, alive, active, plate, color, inventory, gear, fuel, damage, blacklist, contravention FROM vehicles WHERE id='%1' AND pid='%2'",_vid,_pid];
private _tickTime = diag_tickTime;
private _queryResult = [_query,2] call DB_fnc_asyncCall;
if (EXTDB_SETTING(getNumber,"DebugMode") isEqualTo 1) then {
diag_log "------------- Client Query Request -------------";
diag_log format ["QUERY: %1",_query];
diag_log format ["Time to complete: %1 (in seconds)",(diag_tickTime - _tickTime)];
diag_log format ["Result: %1",_queryResult];
diag_log "------------------------------------------------";
};
if (_queryResult isEqualType "") exitWith {};
private _vInfo = _queryResult;
if (isNil "_vInfo") exitWith {serv_sv_use deleteAt _servIndex;};
if (count _vInfo isEqualTo 0) exitWith {serv_sv_use deleteAt _servIndex;};
if ((_vInfo select 5) isEqualTo 0) exitWith {
serv_sv_use deleteAt _servIndex;
[1,"STR_Garage_SQLError_Destroyed",true,[_vInfo select 2]] remoteExecCall ["life_fnc_broadcast",_unit];
};
if ((_vInfo select 6) isEqualTo 1) exitWith {
serv_sv_use deleteAt _servIndex;
[1,"STR_Garage_SQLError_Active",true,[_vInfo select 2]] remoteExecCall ["life_fnc_broadcast",_unit];
};
private "_nearVehicles";
if !(_sp isEqualType "") then {
_nearVehicles = nearestObjects[_sp,["Car","Air","Ship"],10];
} else {
_nearVehicles = [];
};
if (count _nearVehicles > 0) exitWith {
serv_sv_use deleteAt _servIndex;
[_price,_unit_return] remoteExecCall ["life_fnc_garageRefund",_unit];
[1,"STR_Garage_SpawnPointError",true] remoteExecCall ["life_fnc_broadcast",_unit];
};
_query = format ["UPDATE vehicles SET active='1',fourriere='0', damage='""[]""' WHERE pid='%1' AND id='%2'",_pid,_vid];
private _trunk = [(_vInfo select 9)] call DB_fnc_mresToArray;
private _gear = [(_vInfo select 10)] call DB_fnc_mresToArray;
private _damage = [call compile (_vInfo select 12)] call DB_fnc_mresToArray;
private _wasIllegal = _vInfo select 13;
_wasIllegal = if (_wasIllegal isEqualTo 1) then { true } else { false };
[_query,1] call DB_fnc_asyncCall;
private "_vehicle";
if (_sp isEqualType "") then {
_vehicle = createVehicle[(_vInfo select 2),[0,0,999],[],0,"NONE"];
waitUntil {!isNil "_vehicle" && {!isNull _vehicle}};
_vehicle allowDamage false;
_hs = nearestObjects[getMarkerPos _sp,["Land_Hospital_side2_F"],50] select 0;
_vehicle setPosATL (_hs modelToWorld [-0.4,-4,12.65]);
uiSleep 0.6;
} else {
_vehicle = createVehicle [(_vInfo select 2),_sp,[],0,"NONE"];
waitUntil {!isNil "_vehicle" && {!isNull _vehicle}};
_vehicle allowDamage false;
_vehicle setPos _sp;
_vehicle setVectorUp (surfaceNormal _sp);
_vehicle setDir _dir;
};
_vehicle allowDamage true;
//Send keys over the network.
[_vehicle] remoteExecCall ["life_fnc_addVehicle2Chain",_unit];
[_pid,_side,_vehicle,1] call TON_fnc_keyManagement;
_vehicle lock 2;
//Reskin the vehicle
[_vehicle,(_vInfo select 8)] remoteExecCall ["life_fnc_colorVehicle",_unit];
_vehicle setVariable ["vehicle_info_owners",[[_pid,_name]],true];
_vehicle setVariable ["dbInfo",[(_vInfo select 4),(_vInfo select 7)],true];
_vehicle disableTIEquipment true; //No Thermals.. They're cheap but addictive.
[_vehicle] call life_fnc_clearVehicleAmmo;
private _plate = _queryResult select 7;
_vehicle setPlateNumber _plate;
if (LIFE_SETTINGS(getNumber,"save_vehicle_virtualItems") isEqualTo 1) then {
_vehicle setVariable ["Trunk",_trunk,true];
if (_wasIllegal) then {
private _refPoint = if (_sp isEqualType "") then {getMarkerPos _sp;} else {_sp;};
private _distance = 100000;
private "_location";
{
private _tempLocation = nearestLocation [_refPoint, _x];
private _tempDistance = _refPoint distance _tempLocation;
if (_tempDistance < _distance) then {
_location = _tempLocation;
_distance = _tempDistance;
};
false
} count ["NameCityCapital", "NameCity", "NameVillage"];
_location = text _location;
[1,"STR_NOTF_BlackListedVehicle",true,[_location,_name]] remoteExecCall ["life_fnc_broadcast",west];
_query = format ["UPDATE vehicles SET blacklist='0' WHERE id='%1' AND pid='%2'",_vid,_pid];
[_query,1] call DB_fnc_asyncCall;
};
} else {
_vehicle setVariable ["Trunk",[[],0],true];
};
if (LIFE_SETTINGS(getNumber,"save_vehicle_fuel") isEqualTo 1) then {
_vehicle setFuel (_vInfo select 11);
}else{
_vehicle setFuel 1;
};
if (count _gear > 0 && (LIFE_SETTINGS(getNumber,"save_vehicle_inventory") isEqualTo 1)) then {
_items = _gear select 0;
_mags = _gear select 1;
_weapons = _gear select 2;
_backpacks = _gear select 3;
for "_i" from 0 to ((count (_items select 0)) - 1) do {
_vehicle addItemCargoGlobal [((_items select 0) select _i), ((_items select 1) select _i)];
};
for "_i" from 0 to ((count (_mags select 0)) - 1) do {
_vehicle addMagazineCargoGlobal [((_mags select 0) select _i), ((_mags select 1) select _i)];
};
for "_i" from 0 to ((count (_weapons select 0)) - 1) do {
_vehicle addWeaponCargoGlobal [((_weapons select 0) select _i), ((_weapons select 1) select _i)];
};
for "_i" from 0 to ((count (_backpacks select 0)) - 1) do {
_vehicle addBackpackCargoGlobal [((_backpacks select 0) select _i), ((_backpacks select 1) select _i)];
};
};
if (count _damage > 0 && (LIFE_SETTINGS(getNumber,"save_vehicle_damage") isEqualTo 1)) then {
_parts = getAllHitPointsDamage _vehicle;
for "_i" from 0 to ((count _damage) - 1) do {
_vehicle setHitPointDamage [format ["%1",((_parts select 0) select _i)],_damage select _i];
};
};
//Sets of animations
if ((_vInfo select 1) isEqualTo "civ" && (_vInfo select 2) isEqualTo "B_Heli_Light_01_F" && !((_vInfo select 8) isEqualTo 13)) then {
[_vehicle,"civ_littlebird",true] remoteExecCall ["life_fnc_vehicleAnimate",_unit];
};
if ((_vInfo select 1) isEqualTo "cop" && ((_vInfo select 2)) in ["C_Offroad_01_F","B_MRAP_01_F","C_SUV_01_F","C_Hatchback_01_sport_F","B_Heli_Light_01_F","B_Heli_Transport_01_F"]) then {
[_vehicle,"cop_offroad",true] remoteExecCall ["life_fnc_vehicleAnimate",_unit];
};
if ((_vInfo select 1) isEqualTo "med" && (_vInfo select 2) isEqualTo "C_Offroad_01_F") then {
[_vehicle,"med_offroad",true] remoteExecCall ["life_fnc_vehicleAnimate",_unit];
};
[1,_spawntext] remoteExecCall ["life_fnc_broadcast",_unit];
serv_sv_use deleteAt _servIndex;
_contrav = (_vInfo select 14);
if (count _contrav isEqualTo 3) then {
_vehicle setVariable ["vehicle_immobilised",[(_contrav select 0),(_contrav select 1),parseNumber (_contrav select 2)],true];
};
Alles anzeigen
in eurer impound.hpp folgendes eintragen
class kennzeichenButton: life_RscButtonMenu
{
idc = -1;
text = "Kennzeichen"; //--- ToDo: Localize;
onButtonClick = "call life_fnc_changePlate;";
x = 0.74;
y = 0.86;
w = 0.15625;
h = 0.04;
};
class RscEdit_1400: Life_RscEdit
{
idc = 2812;
text = "erster Teil"; //--- ToDo: Localize;
x = 0.1125;
y = 0.8;
w = 0.15;
h = 0.04;
};
class RscEdit_1401: Life_RscEdit
{
idc = 2813;
text = "zweiter Teil"; //--- ToDo: Localize;
x = 0.2625;
y = 0.8;
w = 0.15;
h = 0.04;
};
Alles anzeigen
neue datei erstellen fn_changePlate.sqf
/*
author: Risk
description: Ändert dein Kennzeichen in eines deiner Wünsche
returns: nothing
*/
_vid = lbValue[2802,(lbCurSel 2802)];
_Buchstabe = ctrlText 2812;
_Zahl = ctrlText 2813;
_zuAendern = format["NN-%1-%2", _Buchstabe, _Zahl];
_length = count (toArray(_zuAendern));
_chrByte = toArray (_zuAendern);
_allowed = toArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-");
if (_length > 15) exitWith {hint "Du kannst das Kennzeichen nicht größer als 15 machen!";};
_badChar = false;
{
if (!(_x in _allowed)) exitWith {
_badChar = true;
};
} forEach _chrByte;
if (_badChar) exitWith {hint localize "STR_GNOTF_IncorrectChar";};
_uid = getPlayerUID player;
closeDialog 0;
[_zuAendern,_uid,_vid] remoteExec ["TON_fnc_Plate",2];
Alles anzeigen
und dann noch die fn_plate.sqf erstellen
/*
author: Risk
description: Updatet das Kennzeichen
returns: nothing
*/
params[
"_plate",
"_uid",
"_vid"
];
private _query = format ["UPDATE vehicles SET plate = '%1' WHERE pid = '%2' AND id = ''%3", _plate, _uid, _vid];
[_query, 1] call DB_fnc_asyncCall;
Alles anzeigen
die fn_plate.sqf noch in die remoteExec eintragen.
Viel Spaß damit. Hoffentlich habe ich nichts vergessen.