Hinweis der Administration:
Mittlerweile ist V2 verfügbar! Diese beinhaltet diverse Verbesserungen & Erweiterungen. Zu ihr gelangst du hier: [KLICK MICH]
--------------------------
Hallo zusammen,
ich teile mit euch meine Personalausweis-Scripts.
Vorab soll was erwähnt sein:
- Getestet mit Standard Altis Life Versionen ohne weitere Änderungen
- Version 3.1.4.8 (mit extDB)
- 4.0 (danke an @Saturin78 Klick mich
- Version 4.4 irgendwas
- Version 4.5 (extDB2)
- Jeweilge @life_server von Version X und unter extDB, extDB2 und extDB3 (mit vorgefertigten SQL-Abfragen)
- Das Tutorial ist nicht zu 100% für die extDB3 geeignet
- Standarddatenbank, welche im Master-Framework beiligt
- Unterstützt derzeit keine ini-Datein (vorgefertigte Statements) und müssen selber angepasst werden
- DDL, DML und DQL wird jeweils vom sqf-Script ausgeführt (SQL-Abfragen/-Befehle)
- SpyGlass deaktiviert
- Leichte Konfigurierbarkeit
- Sprachen
- Logos für jeweilige Fraktion
- BattlEye-Filter müssen manuell angepasst werden
- Etwas Erfahrung solltest du besitzen
- Wie füge ich eine weitere Lizenz in der Altis Life Version X hinzu
- Klammern und Zeichensetzunh beachten
- Kleiner SQL-Umgang (Ausführen)
- Kein stumpfes Copy&Paste
- Angehängt sind die Altis Life Version 3.1.4.8 mit life_server sowie einzelne Dateien mit Hinweisen/Beispielen
- Es wurde nur die Perso-Funktion getestet. Weder Shops, Fahrzeugkauf oder Ähnliches... Sollten Fehler entstehen, probier ein wenig rum und oder poste die Fehlermeldungen
- Etwas funktioniert nicht? Dann brauche ich/brauchen wir die [lexicon='extDB'][/lexicon]-Logs, Client-Logs und Server-Logs (ggf. BattlEye-Logs)
- Angegebener Missionsname\Pfad kann abweichen
- Das ein oder andere ist eventuell überflüssig
- Weitere Versionen oder Änderungen? Weiß ich noch nicht...
- Der Personalausweis mit dem Scrollmenü dem Gegenüber gezeigt, bzw. kann angesehen werden, wenn der Gegenüber im gefesselten Zustand ist (bspw. für Kabelbinder, Handschellen etc.)
- Es stehen vorgefertigte Ortschaften und Straßen zur Verfügung (warum? Damit nicht Herr Peta Zwegaahht irgendwelche unpassende Ortschaften und oder Straßennamen angibt)
Die Nutzung dieses Pakets und die enthaltenen Scripts/Dateien erlaube ich nur, wenn die begefügte License-FvS.txt im Missionsordner liegt (oder in einem Verzeichnis wo weitere liegen) und dass die jeweiligen Punkte akzeptiert und eingehalten werden.
WICHTIG: Erstelle vor dem Einfügen der Personalausweis-Scripts ein Backup deiner Mission (Mission.Altis und life_server sowie der Datenbankstruktur und deren Inhalt)! Die Weiterverbreitung in anderen Foren untersage ich (eine Erlaubnis ist bei mir einzuholen).
(ein englisch-sprachiges Tutorial darf gerne für Native-Network erstellt werden!)
Lade dir nun das anghängte ZIP-Archiv herunter. Und los gehts...
Dialog anpassen und einfügen
Öffne das Verzeichnis Altis_life.Altis\dialog
- Füge die Personalausweis.hpp ind das geöffnete Verzeichnis ein
- Zu findem im Selben Verzeichnis von Perso_Paket.zip
- Öffne die MasterHandler.h
- Füge folgendes am Ende der Datei hinzu: #include "personalausweis.hpp"
- Öffne die player_inv.hpp und füge folgenden Knopf unter controls hinzu
C: player_inv.hpp
Alles anzeigenclass perso_idcard: Life_RscButtonMenu { onButtonClick = "private[""_rang_1""]; _rang_1 = switch(playerSide) do {case west: {str(call life_coplevel)};case independent: {str(call life_mediclevel)};case civilian: {""""};case east: {""""};}; [player,_rang_1] remoteExecCall [""fvs_fnc_zeigePerso"",player]; closeDialog 0;"; idc = -1; text = "ID CARD"; x = 0.738657; y = 0.849; w = 0.15625; h = 0.04; tooltip = "Meinen Personal-/Dienstausweis ansehen \/ Take a look on my ID card"; };
- Achte selbstständig auf die Klammern!
- Überprüfe nun die common.hpp ob es eine Klasse namens Life_Checkbox gibt
- Wenn ja, ok
- Wenn nein, füge folgendes am Ende der Datei hinzu
class Life_Checkbox
{
access = 0; // Control access (0 - ReadAndWrite, 1 - ReadAndCreate, 2 - ReadOnly, 3 - ReadOnlyVerified)
idc = -1; // Control identification (without it, the control won't be displayed)
type = 77; // Type
style = ST_LEFT + ST_MULTI; // Style
default = 0; // Control selected by default (only one within a display can be used)
blinkingPeriod = 0; // Time in which control will fade out and back in. Use 0 to disable the effect.
x = 0;
y = 0;
w = 1 * GUI_GRID_CENTER_W; // Width
h = 1 * GUI_GRID_CENTER_H; // Height
//Colors
color[] = { 1, 1, 1, 0.7 }; // Texture color
colorFocused[] = { 1, 1, 1, 1 }; // Focused texture color
colorHover[] = { 1, 1, 1, 1 }; // Mouse over texture color
colorPressed[] = { 1, 1, 1, 1 }; // Mouse pressed texture color
colorDisabled[] = { 1, 1, 1, 0.2 }; // Disabled texture color
//Background colors
colorBackground[] = { 0, 0, 0, 0 }; // Fill color
colorBackgroundFocused[] = { 0, 0, 0, 0 }; // Focused fill color
colorBackgroundHover[] = { 0, 0, 0, 0 }; // Mouse hover fill color
colorBackgroundPressed[] = { 0, 0, 0, 0 }; // Mouse pressed fill color
colorBackgroundDisabled[] = { 0, 0, 0, 0 }; // Disabled fill color
//Textures
textureChecked = "\A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_checked_ca.paa"; //Texture of checked CheckBox.
textureUnchecked = "\A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_unchecked_ca.paa"; //Texture of unchecked CheckBox.
textureFocusedChecked = "\A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_checked_ca.paa"; //Texture of checked focused CheckBox (Could be used for showing different texture when focused).
textureFocusedUnchecked = "\A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_unchecked_ca.paa"; //Texture of unchecked focused CheckBox.
textureHoverChecked = "\A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_checked_ca.paa";
textureHoverUnchecked = "\A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_unchecked_ca.paa";
texturePressedChecked = "\A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_checked_ca.paa";
texturePressedUnchecked = "\A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_unchecked_ca.paa";
textureDisabledChecked = "\A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_checked_ca.paa";
textureDisabledUnchecked = "\A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_unchecked_ca.paa";
tooltip = ""; // Tooltip text
tooltipColorShade[] = { 0, 0, 0, 1 }; // Tooltip background color
tooltipColorText[] = { 1, 1, 1, 1 }; // Tooltip text color
tooltipColorBox[] = { 1, 1, 1, 1 }; // Tooltip frame color
//Sounds
soundClick[] = { "\A3\ui_f\data\sound\RscButton\soundClick", 0.09, 1 }; // Sound played after control is activated in format {file, volume, pitch}
soundEnter[] = { "\A3\ui_f\data\sound\RscButton\soundEnter", 0.09, 1 }; // Sound played when mouse cursor enters the control
soundPush[] = { "\A3\ui_f\data\sound\RscButton\soundPush", 0.09, 1 }; // Sound played when the control is pushed down
soundEscape[] = { "\A3\ui_f\data\sound\RscButton\soundEscape", 0.09, 1 }; // Sound played when the control is released after pushing down
};
Alles anzeigen
- Füge nun die beigefügten Bilder und Icons in das jeweilige Verzeichnis ein. Falls ein Ordner nicht besteht, erstelle diesen (Ordnerstruktur bitte beibehalten wie in der ZIP!)
Hinzufügen einer neuen Lizenz für Zivilisten
Zivilisten benötigen diese Lizenz um ihre Daten auf dem Personalausweis selber (später) anpassen zu können.
Versionen 3.1.4.8 und weitere ohne Config_Licenses.hpp
- Öffne die configuration.sqf aus dem core-Verzeichnis (danke an @=Recon=, neue Lizenz wurde nicht gespeichert)
-
life_licenses erweitern mit:
- ["license_civ_einbuergerung","civ"]
- Achte selber auf KOMMA, da es einen Array darstellt!
-
life_licenses erweitern mit:
- Gehe in das Verzeichnis Altis_Life.Altis\core\config
- Öffne die Dateien fn_varToStr.sqf, fn_licenseType.sqf und fn_licensePrice.sqf
- fn_varToStr.sqf case "license_civ_einbuergerung": {localize "STR_License_einb"};
- fn_licenseType.sqf
- Switch-Case 0 case "einbuergerung": {_var ="license_civ_einbuergerung"};
- Switch-Case 1 case "license_civ_einbuergerung": {_var = "einbuergerung"};
- fn_licensePrice.sqf (Preis kann beliebig geändert werden)
- Neuer Case case "einbuergerung": {2500};
- Öffne die Dateien fn_varToStr.sqf, fn_licenseType.sqf und fn_licensePrice.sqf
Versionen über 4.0 mit Config_Licenses.hpp
- Füge folgendes neu in die class Licenses {} ein
class einbuergerung {
variable = "einbuergerung";
displayName = "STR_License_einb";
price = 2500;
illegal = false;
side = "civ";
};
- Der Lizenzname kann in der stringtable.xml angepasst werden
- Füge nun das beigefügte Übersetzungspaket (siehe Perso_paket.zip\Mission.Altis) in der Stringtable korrekt hinzu
- Orientiere dich an vorhandene
Funktionen/Scripts und Dialoge einbinden
- Öffne die Functions.h und füge folgenden Inhalt alleinstehend am Ende der Datei hinzu
class felixvonstudsinske
{
tag = "fvs";
class perso
{
file = "core\pmenu\perso";
class perso_laden {};
class persoCheck {};
class persoCheck_aenderung {};
class persoErgebnis {};
class persoNeu {};
class updateTag {};
class updateTagA {};
class updateMonat {};
class updateMonatA {};
class updateHsnr {};
class updateHsnrA {};
class updateStrasse {};
class updateStrasseA {};
class persoBeantragen {};
class persoBeantragenAenderung {};
class persoInteractionMenu {};
class zeigePerso {};
class updatePersoBild {};
class updatePersoBildA {};
class aenderePerso {};
};
};
Alles anzeigen
- Öffne nun die description.ext
- Füge bei class RscTitles folgendes hinzu #include "dialog\uiPerso.hpp"
- Füge alleinstehend dies hinzu #include "Config_Perso.hpp"
- Pfad kann bei eigener Struktur frei gewählt werden
- Füge in der class CfgDebriefing dieses hinzu (oder erstelle es, falls es nicht (mehr) existiert)
class falschprof
{
title = "Falscher Profilname";
subTitle = "";
description = "Dein aktuelles Profil (Name) stimmt nicht mit dem abgespeicherten Namen im Personalausweis überein! Bitte aendere dein Profil. Falls du deinen Namen nicht mehr kennst, melde dich bitte beim Support!";
pictureBackground = "";
picture = "";
pictureColor[] = {0,0.3,0.6,1};
};
class fehlerprof
{
title = "Fehler im Personalausweis";
subTitle = "";
description = "Bitte melde dich im Support und gebe den Fehler mit an!";
pictureBackground = "";
picture = "";
pictureColor[] = {0,0.3,0.6,1};
};
class persoA
{
title = "Personalausweis";
subTitle = "";
description = "Bitte aendere dein Profilnamen auf den Namen, den du vor 5 Minuten beim Buergeramt angegeben hast!";
pictureBackground = "";
picture = "";
pictureColor[] = {0,0.3,0.6,1};
};
class fformatprof
{
title = "Format Personalausweis";
subTitle = "";
description = "Bitte melde dich im Support und gebe den Fehler mit an!";
pictureBackground = "";
picture = "";
pictureColor[] = {0,0.3,0.6,1};
};
class dialogperso
{
title = "Personalausweisdialog geschlossen";
subTitle = "";
description = "Dialog des Personalausweises wurde geschlossen...";
pictureBackground = "";
picture = "";
pictureColor[] = {0,0.3,0.6,1};
};
Alles anzeigen
- Füge den Ordner perso in das Verzeichnis ein Altis_Life.Altis\core\pmenu
- Öffne die fn_setupActions.sqf aus Altis_Life.Altis\core und erweitere die Switch-Case-Anweisung, falls die jeweilige Fraktion nicht aufgeführt wird (west, independent, east, civilian)
- So könnte es aussehen (3.1.4.8)
/*
File: fn_setupActions.sqf
Description:
Master addAction file handler for all client-based actions.
*/
switch (playerSide) do
{
case civilian:
{
//Drop fishing net
life_actions = [player addAction[localize "STR_pAct_DropFishingNet",life_fnc_dropFishingNet,"",0,false,false,"",'
(surfaceisWater (getPos vehicle player)) && (vehicle player isKindOf "Ship") && life_carryWeight < life_maxWeight && speed (vehicle player) < 2 && speed (vehicle player) > -1 && !life_net_dropped ']];
//Rob person
life_actions = life_actions + [player addAction[localize "STR_pAct_RobPerson",life_fnc_robAction,"",0,false,false,"",'
!isNull cursorTarget && player distance cursorTarget < 3.5 && isPlayer cursorTarget && animationState cursorTarget == "Incapacitated" && !(cursorTarget getVariable["robbed",FALSE]) ']];
life_actions = life_actions + [player addAction["Personalausweis ansehen",{[cursorTarget] remoteExecCall ["fvs_fnc_zeigePerso",player];},"",0,false,false,"",'
isPlayer cursorTarget && alive cursorTarget && (player distance cursorTarget < 3) && (speed player < 1 && speed cursorTarget < 1) && !(player getVariable ["restrained",false]) && (cursorTarget getVariable ["restrained",false])']];
life_actions = life_actions + [player addAction["Personalausweis zeigen",{[player] remoteExecCall ["fvs_fnc_zeigePerso",cursorTarget];},"",0,false,false,"",'
isPlayer cursorTarget && alive cursorTarget && (player distance cursorTarget < 3) && (speed player < 1 && speed cursorTarget < 1)']];
};
case west:
{
life_actions = life_actions + [player addAction["Personalausweis ansehen",{[cursorTarget] remoteExecCall ["fvs_fnc_zeigePerso",player];},"",0,false,false,"",'
isPlayer cursorTarget && alive cursorTarget && (player distance cursorTarget < 3) && (speed player < 1 && speed cursorTarget < 1) && !(player getVariable ["restrained",false]) && (cursorTarget getVariable ["restrained",false])']];
life_actions = life_actions + [player addAction["Personalausweis zeigen",{[player] remoteExecCall ["fvs_fnc_zeigePerso",cursorTarget];},"",0,false,false,"",'
isPlayer cursorTarget && alive cursorTarget && (player distance cursorTarget < 3) && (speed player < 1 && speed cursorTarget < 1)']];
};
case independent:
{
life_actions = life_actions + [player addAction["Personalausweis ansehen",{[cursorTarget] remoteExecCall ["fvs_fnc_zeigePerso",player];},"",0,false,false,"",'
isPlayer cursorTarget && alive cursorTarget && (player distance cursorTarget < 3) && (speed player < 1 && speed cursorTarget < 1) && !(player getVariable ["restrained",false]) && (cursorTarget getVariable ["restrained",false])']];
life_actions = life_actions + [player addAction["Personalausweis zeigen",{[player] remoteExecCall ["fvs_fnc_zeigePerso",cursorTarget];},"",0,false,false,"",'
isPlayer cursorTarget && alive cursorTarget && (player distance cursorTarget < 3) && (speed player < 1 && speed cursorTarget < 1)']];
};
case east:
{
life_actions = life_actions + [player addAction["Personalausweis ansehen",{[cursorTarget] remoteExecCall ["fvs_fnc_zeigePerso",player];},"",0,false,false,"",'
isPlayer cursorTarget && alive cursorTarget && (player distance cursorTarget < 3) && (speed player < 1 && speed cursorTarget < 1) && !(player getVariable ["restrained",false]) && (cursorTarget getVariable ["restrained",false])']];
life_actions = life_actions + [player addAction["Personalausweis zeigen",{[player] remoteExecCall ["fvs_fnc_zeigePerso",cursorTarget];},"",0,false,false,"",'
isPlayer cursorTarget && alive cursorTarget && (player distance cursorTarget < 3) && (speed player < 1 && speed cursorTarget < 1)']];
};
};
Alles anzeigen
- Ohne Switch-Anweisung
life_actions = life_actions + [player addAction["Personalausweis zeigen",{[player] remoteExecCall ["fvs_fnc_zeigePerso",cursorTarget];},"",0,false,false,"",'isPlayer cursorTarget && alive cursorTarget && (player distance cursorTarget < 3) && (speed player < 1 && speed cursorTarget < 1)']];
life_actions = life_actions + [player addAction["Personalausweis ansehen",{[cursorTarget] remoteExecCall ["fvs_fnc_zeigePerso",player];},"",0,false,false,"",'isPlayer cursorTarget && alive cursorTarget && (player distance cursorTarget < 3) && (speed player < 1 && speed cursorTarget < 1) && !(player getVariable ["restrained",false]) && (cursorTarget getVariable ["restrained",false])']];
- Füge die beigefügte Config_Perso.hpp in das Missionshauptverzeichnis ein
- Hast du eine Kontrolle für Remote-Execution aktiv CfgRemoteExec.h/hpp, dann wird folgendes unter Funktionen benötigt
F(fvs_fnc_perso_laden,CLIENT) // Perso
F(fvs_fnc_persoBeantragen,CLIENT) // Perso
F(fvs_fnc_persoCheck,CLIENT) // Perso
F(fvs_fnc_persoErgebnis,CLIENT) // Perso
F(fvs_fnc_persoNeu,CLIENT) // Perso
F(fvs_fnc_updateMonat,CLIENT) // Perso
F(fvs_fnc_updateTag,CLIENT) // Perso
F(fvs_fnc_zeigePerso,CLIENT) // Perso
F(fvs_fnc_updatePersoBild,CLIENT) // Perso
F(DB_fnc_persoRequest,SERVER) // Perso
F(DB_fnc_persoInsert,SERVER) // Perso
F(DB_fnc_persoUpdate,SERVER) // Perso
Alles anzeigen
- Öffne die configurations.sqf aus Altis_Life.Altis\core und füge dies unter den Variablen hinzu
fvs_persoReady = false;
fvs_hakenregeln = false;
fvs_checking = false;
fvs_hakenrichtig = false;
fvs_namenInfo = false;
fvs_checking_a = false;
fvs_namen_a = false;
fvs_hakendaten = false;
- Öffne nun die init.sqf aus dem Verzeichnis Altis_Life.Altis\core und füge dies über der Switch-Case-Anweisung von den Fraktions-Inits hinzu
diag_log "::Client:: Pruefe Personalausweisdaten.";
0 cutText ["Ueberpruefe Daten des Personalausweises...","BLACK FADED"];
[] call fvs_fnc_perso_laden;
0 cutFadeOut 99999999;
waitUntil{fvs_persoReady};
- Öffne nun das Verzeichnis life_server\Functions\MySQL und füge den Ordner perso (Perso_Paket.zip\*versionen*) hinzu
- Öffne nun die fn_insertRequest.sqf und füge folgendes hinzu (waitUntil sollte bei Versionen mit extDB2 und extDB3 entfernt werden)
_query_2 = format["INSERT INTO perso(pid, persoCop, persoMed, persoCiv, persoEast) VALUES ('%1','""[]""','""[]""','""[]""','""[]""')",_uid];
waitUntil {!DB_Async_Active};
[_query_2,1] call DB_fnc_asyncCall;
- Öffne nun die config.cpp aus dem life_server-Ordner und füge dies in MySQL_Database aber nicht in MySQL hinzu
class perso
{
file = "\life_server\Functions\MySQL\perso";
class persoRequest {};
class persoInsert {};
class persoUpdate {};
};
Datenbank
- Füge folgenden SQL-Befehl in deiner Altislife-Datenbank aus
CREATE TABLE IF NOT EXISTS `perso` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`pid` varchar(50) NOT NULL DEFAULT '',
`persoCop` text NOT NULL,
`persoMed` text NOT NULL,
`persoCiv` text NOT NULL,
`persoEast` text NOT NULL,
`Erstellungsdatum` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`Aenderungsdatum` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`,`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Alles anzeigen
Optional - Karte editieren
- Erstelle ein Objekt auf deiner Missions-Karte und füge folgendes (oder abgeändert) in die Init des Objektes (z.B. Schild oder Laptop)
this allowDamage false;
this enableSimulation false;
this addAction[format["%1 ($%2)",["license_civ_einbuergerung"] call life_fnc_varToStr,[(["einbuergerung"] call life_fnc_licensePrice)] call life_fnc_numberText],life_fnc_buyLicense,"einbuergerung",0,false,false,"",' !license_civ_einbuergerung && playerSide == civilian '];
this addAction["Persoenliche Daten aendern (Kosten: $250.000)",fvs_fnc_aenderePerso,"",0,false,false,"",' license_civ_einbuergerung && playerSide == civilian '];
this allowDamage false;
this enableSimulation false;
this addAction[format["%1 fuer $%2 abholen",localize (getText(missionConfigFile >> "Licenses" >> "einbuergerung" >> "displayName")), [(getNumber(missionConfigFile >> "Licenses" >> "einbuergerung" >> "price"))] call life_fnc_numberText],life_fnc_buyLicense,"einbuergerung",0,false,false,"",' !license_civ_einbuergerung && playerSide == civilian '];
this addAction["Persoenliche Daten aendern (Kosten: $250.000)",fvs_fnc_aenderePerso,"",0,false,false,"",' license_civ_einbuergerung && playerSide == civilian '];
Das sollte es gewesen sein. Wenn ich etwas vergessen habe, werde ich das schnellsmöglichst ergänzen und Fehler natürlich korrigieren.
Sollten Fehler auftreten, dann bitte ich dich die jeweiligen Logs sowie die Dateien anzuhängen, in denen du etwas geändert hast.
Fragen? Raus damit
Grüße und viel Spaß damit
Rom