Vorweg: Ich habe das Tutorial von @sebi1106 nur für die Version 4.4-5.0 angepasst.
Die Grundbasis wurde von EdgeKiller entworfen.
Daher poste ich auch hier seinen Header:
Hiermit untersage ich wie immer die Verbreitung dieser Daten und die des von mir verfassten Tutorials in anderen Foren ohne vorher mein Einverständnis dazu einzuholen.
Altes Tutorial:
Spoiler anzeigen
Schritt 1:
öffnet die Datei /Functions.hpp und fügt dort folgendes unter der "class action" ein ein:
und folgendes unter der "class Player_Menu":
und folgendes unter der "class config":
Schritt 2:
öffnet die Datei /dialog/MasterHandler.h und fügt dort folgendes ein:
Schritt 3:
öffnet die Datei /dialog/player_inv.hpp und fügt dort folgendes unter "class controls" ein:
class ButtonCraft : Life_RscButtonMenu {
idc = 2025;
text = "$STR_PM_Craft";
onButtonClick = "closeDialog 0; createDialog ""Life_craft"";";
x = 0.42 + (6.25 / 19.8) + (1 / 250 / (safezoneW / safezoneH));
y = 0.805;
w = (6.25 / 40);
h = (1 / 25);
};
Schritt 4:
öffnet die Datei /stringtable.xml und fügt dort folgendes ein:
<Package name="Craft">
<Key ID="STR_CRAFT_Title">
<Original>Baumenü</Original>
</Key>
<Key ID="STR_PM_CraftStats">
<Original>Sachen zum Bauen</Original>
</Key>
<Key ID="STR_PM_CraftMaterials">
<Original>Benötigte Sachen</Original>
</Key>
<Key ID="STR_CRAFT_Button">
<Original>Bauen!</Original>
</Key>
<Key ID="STR_PM_NoMaterial">
<Original>Du hast nicht alle Baumaterialen!</Original>
</Key>
<Key ID="STR_CRAFT_Process">
<Original>Du hast folgendes hergestellt: %1</Original>
</Key>
<Key ID="STR_CRAFT_FILTER_Weapon">
<Original>Waffen</Original>
</Key>
<Key ID="STR_CRAFT_FILTER_Uniform">
<Original>Kleidung</Original>
</Key>
<Key ID="STR_CRAFT_FILTER_Backpack">
<Original>Rucksäcke</Original>
</Key>
<Key ID="STR_CRAFT_FILTER_Item">
<Original>Items</Original>
</Key>
<Key ID="STR_CRAFT_AR_Backpack">
<Original>Du hast bereit einen Rucksack! Pack den alten erstmal weg.</Original>
</Key>
<Key ID="STR_CRAFT_AR_Uniform">
<Original>Du hast bereits etwas an! Mach dich nackt und versuch es nochmal.</Original>
</Key>
</Package>
Alles anzeigen
und das im Package "Player_Menu":
Schritt 5:
erstellt die Datei craft.hpp und fügt diese unter /dialog ein:
/*
File: craft.hpp
Description: Crafting System
Created by EdgeKiller
Coder: EdgeKiller
*/
class Life_craft {
idd = 666;
name= "life_craft";
movingEnable = false;
enableSimulation = true;
onLoad = "[] spawn life_fnc_craft";
class controlsBackground {
class Life_RscTitleBackground:Life_RscText {
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])", "(profilenamespace getvariable ['GUI_BCG_RGB_A',0.7])"};
idc = -1;
x = 0.1;
y = 0.2;
w = 0.8;
h = (1 / 25);
};
class MainBackground:Life_RscText {
colorBackground[] = {0, 0, 0, 0.7};
idc = -1;
x = 0.1;
y = 0.2 + (11 / 250);
w = 0.8;
h = 0.6 - (22 / 250);
};
};
class controls {
class Title : Life_RscTitle {
colorBackground[] = {0, 0, 0, 0};
idc = 667;
text = "$STR_CRAFT_Title";
x = 0.1;
y = 0.2;
w = 0.6;
h = (1 / 25);
};
class craftListHeader : Life_RscText {
idc = 668;
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_PM_CraftStats";
sizeEx = 0.04;
x = 0.105; y = 0.26;
w = 0.275; h = 0.04;
};
//Craft list
class craftList : life_RscListBox {
idc = 669;
sizeEx = 0.030;
onLBSelChanged = "[] spawn life_fnc_craft_update";
x = 0.105;
y = 0.31;
w = 0.275; h = 0.44;
};
//Materials list header
class materialListHeader : Life_RscText {
idc = 670;
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_PM_CraftMaterials";
sizeEx = 0.04;
x = 0.395; y = 0.26;
w = 0.275; h = 0.04;
};
//Materials list
class materialList : Life_RscControlsGroup {
idc = 671;
w = 0.275;
h = 0.44;
x = 0.395;
y = 0.30;
class Controls {
class mats : Life_RscStructuredText {
idc = 672;
sizeEx = 0.020;
text = "";
x = 0;
y = 0;
w = 0.27; h = 0.44;
};
};
};
//FILTER
class FilterList : Life_RscCombo {
idc = 673;
colorBackground[] = {0,0,0,0.7};
onLBSelChanged = "[] call life_fnc_craft_updateFilter";
x = 0.69;
y = 0.32;
w = (6.25 / 30);
h = (1 / 25);
};
//Craft button
class ButtonCraft : Life_RscButtonMenu {
idc = 674;
text = "$STR_CRAFT_Button";
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 = "if(!(life_is_processing && life_action_inUse)) then {[] spawn life_fnc_craftAction};";
x = 0.69;
y = 0.26;
w = (6.25 / 40);
h = (1 / 25);
};
class CloseButtonKey : Life_RscButtonMenu {
idc = -1;
text = "$STR_Global_Close";
onButtonClick = "closeDialog 0;";
x = 0.1;
y = 0.8 - (1 / 25);
w = (6.25 / 40);
h = (1 / 25);
};
};
};
Alles anzeigen
Schritt 6:
erstellt die Datei fn_craftAction.sqf und fügt diese unter /core/actions ein:
#include "..\..\script_macros.hpp"
/*
File: fn_craftAction.sqf
Author: EdgeKiller
Description:
Master handling for crafting an item.
*/
private["_dialog","_item","_itemInfo","_oldItem","_newItem","_upp","_itemName","_ui","_progress","_pgText","_cP","_allMaterial","_matsNeed","_invSize","_handledItem","_itemFilter","_backpackOldItems","_weight","_weightUsedItems"];
disableSerialization;
_dialog = findDisplay 666;
if((lbCurSel 669) == -1) exitWith {hint localize "STR_ISTR_SelectItemFirst";};
_item = lbData[669,(lbCurSel 669)];
_allMaterial = true;
_itemFilter = lbData[673,(lbCurSel 673)];
_matsNeed = 0;
_config = [_itemFilter] call life_fnc_craftCfg;
life_action_inUse = true;//Lock out other actions during processing.
{
if (_item == _x select 0)then {
_matsNeed = _x select 1;
_invSize = count _matsNeed;
for [{_i=0},{_i<_invSize-1},{_i=_i+2}] do {
_matsNum = _matsNeed select _i+1;
if ((ITEM_VALUE(_matsNeed select _i)) < _matsNum) then {_allMaterial = false;};
};
};
} foreach (_config);
_newItem = _item;
diag_log format ["%1",_allMaterial];
if (!_allMaterial) exitWith {hint localize "STR_PM_NoMaterial"; life_action_inUse = false;};
//Some checks
if ((count _matsNeed) == 0) exitWith {life_action_inUse = false;};
if (_itemFilter == "backpack" && backpack player != "") exitWith {
hint localize "STR_CRAFT_AR_Backpack";
life_action_inUse = false;
};
if (_itemFilter == "uniform" && uniform player != "") exitWith {
hint localize "STR_CRAFT_AR_Uniform";
life_action_inUse = false;
};
if (_itemFilter == "weapon") then {
if (!(player canAdd _newItem) || currentWeapon player != "") exitWith {
hint localize "STR_NOTF_NoRoom";
life_action_inUse = false;
};
};
if (_itemFilter == "item") then {
_weight = [_item] call life_fnc_itemWeight;
_weightUsedItems = 0;
for [{_i=0},{_i<(count _matsNeed)-1},{_i=_i+2}] do {
_matsNum = _matsNeed select _i+1;
_weightUsedItems = _weightUsedItems + (([(_matsNeed select _i)] call life_fnc_itemWeight) * _matsNum);
diag_log format ["%1 - %2",(_matsNeed select _i),_weightUsedItems];
};
if ((life_carryWeight - _weightUsedItems + _weight) > life_maxWeight) exitWith {
hint localize "STR_NOTF_NoRoom";
life_action_inUse = false;
};
};
_oldItem = _matsNeed;
if (_itemFilter == "item") then {
_itemName = localize M_CONFIG(getText,"VirtualItems",_newItem,"displayName");
} else {
_itemInfo = [_newItem] call life_fnc_fetchCfgDetails;
_itemName = _itemInfo select 1;
};
life_is_processing = true;
_upp = format["Baue %1",_itemName];
closeDialog 0;
//Setup our progress bar.
disableSerialization;
5 cutRsc ["life_progress","PLAIN"];
_ui = uiNameSpace getVariable "life_progress";
_progress = _ui displayCtrl 38201;
_pgText = _ui displayCtrl 38202;
_pgText ctrlSetText format["%2 (1%1)...","%",_upp];
_progress progressSetPosition 0.01;
_cP = 0.01;
_removeItemSuccess = true;
_invSize = count _oldItem;
for [{_i=0},{_i<_invSize-1},{_i=_i+2}] do {
_handledItem = (_oldItem select _i);
if(!([false,_handledItem,_oldItem select _i+1] call life_fnc_handleInv)) exitWith {_removeItemSuccess = false;};
};
if (!_removeItemSuccess) exitWith {5 cutText ["","PLAIN"]; life_is_processing = false; life_action_inUse = false;};
for "_i" from 0 to 1 step 0 do {
sleep 0.3;
_cP = _cP + 0.01;
_progress progressSetPosition _cP;
_pgText ctrlSetText format["%3 (%1%2)...",round(_cP * 100),"%",_upp];
if(_cP >= 1) exitWith {};
};
if (_itemFilter == "backpack") then {
if(backpack player == "") then {
player addBackpack _newItem;
} else {
hint localize "STR_CRAFT_AR_Backpack";
life_is_processing = false;
life_action_inUse = false;
};
};
if (_itemFilter == "uniform") then{
if(uniform player == "") then{
player addUniform _newItem;
} else {
hint localize "STR_CRAFT_AR_Uniform";
life_is_processing = false;
life_action_inUse = false;
};
};
if (_itemFilter == "weapon") then{
if(player canAdd _newItem) then{
player addItem _newItem;
} else {
if(currentWeapon player == "") then{
player addWeapon _newItem;
} else {
5 cutText ["","PLAIN"];
for [{_i=0},{_i<_invSize-1},{_i=_i+2}] do {
_handledItem = (_oldItem select _i);
[true,_handledItem,_oldItem select _i+1] call life_fnc_handleInv;
};
life_is_processing = false;
life_action_inUse = false;
};
};
};
if (_itemFilter == "item") then{
_handledItem = _newItem;
[true,_handledItem,1] call life_fnc_handleInv;
};
5 cutText ["","PLAIN"];
titleText[format[localize "STR_CRAFT_Process",_itemName],"PLAIN"];
[0] call SOCK_fnc_updatePartial;
life_is_processing = false;
life_action_inUse = false;
Alles anzeigen
Schritt 7:
erstellt die Datei fn_craft.sqf und fügt diese unter /core/pmenu ein:
/*
File: fn_craft.sqf
Description: Crafting System
Created by EdgeKiller
Coder: EdgeKiller
*/
private["_dialog","_inv","_itemInfo","_filter"]; //Declare all private variables
if(!dialog) then { //Verify if the window is open
createDialog "Life_craft";
};
disableSerialization; //Disable Serialization
if(life_is_processing) exitWith{
closeDialog 2001;
closeDialog 0;
};
_dialog = findDisplay 666; //find the craft dialog/window
_inv = _dialog displayCtrl 669; //find the listbox of items can be created
lbClear _inv; //clear the listbox
_filter = _dialog displayCtrl 673;
_filter lbAdd localize "STR_CRAFT_FILTER_Weapon";
_filter lbSetData[(lbSize _filter)-1,"weapon"];
_filter lbAdd localize "STR_CRAFT_FILTER_Uniform";
_filter lbSetData[(lbSize _filter)-1,"uniform"];
_filter lbAdd localize "STR_CRAFT_FILTER_Backpack";
_filter lbSetData[(lbSize _filter)-1,"backpack"];
_filter lbAdd localize "STR_CRAFT_FILTER_Item";
_filter lbSetData[(lbSize _filter)-1,"item"];
_filter lbSetCurSel 0;
Alles anzeigen
Schritt 8:
erstellt die Datei fn_craft_update.sqf und fügt diese unter /core/pmenu ein:
#include "..\..\script_macros.hpp"
/*
File: fn_craft_update.sqf
Description: Crafting System
Created by EdgeKiller
Coder: EdgeKiller
*/
private["_dialog","_inv","_mats","_item","_struct","_str","_invSize","_matsNeed","_matsNum","_config","_itemFilter"]; //Declare all private variables
disableSerialization; //Disable Serialization
_dialog = findDisplay 666; //find the craft dialog/window
_inv = _dialog displayCtrl 669; //find the listbox of items can be created
_mats = _dialog displayCtrl 672;
_struct = "";
if ((lbCurSel 669) == -1) exitWith {hint localize "STR_ISTR_SelectItemFirst";};
_item = lbData[669,(lbCurSel 669)];
_itemFilter = lbData[673,(lbCurSel 673)];
_config = [_itemFilter] call life_fnc_craftCfg;
{
if (_item == _x select 0) then {
_matsNeed = _x select 1;
_invSize = count _matsNeed;
for [{_i = 0},{_i < _invSize - 1},{_i = _i + 2}] do {
_str = M_CONFIG(getText,"VirtualItems",(_matsNeed select _i),"displayName");
_matsNum = _matsNeed select _i+1;
_struct = _struct + format["%1x %2<br/>",_matsNum,(localize _str)];
};
};
} foreach (_config);
if (_struct == "") then {
_struct = "Es wird nichts benötigt";
};
_mats ctrlSetStructuredText parseText format["
<t size='0.8px'>
%1
</t>
",_struct];
Alles anzeigen
Schritt 9:
erstellt die Datei fn_craft_updateFilter.sqf und fügt diese unter /core/pmenu ein:
#include "..\..\script_macros.hpp"
/*
File: fn_craft_updateFilter.sqf
Description: Crafting System
Created by EdgeKiller
Coder: EdgeKiller
*/
disableSerialization;
private["_list","_filter","_dialog","_inv","_mats","_filterBox","_item","_itemFilter"];
_dialog = findDisplay 666; //find the craft dialog/window
_inv = _dialog displayCtrl 669; //find the listbox of items can be created
_mats = _dialog displayCtrl 672;
_filterBox = _dialog displayCtrl 673;
_itemFilter = lbData[673,(lbCurSel 673)];
lbClear _inv;
_struct = "";
_config = [_itemFilter] call life_fnc_craftCfg;
{
if(_itemFilter == "item") then{
_str = localize M_CONFIG(getText,"VirtualItems",(_x select 0),"displayName");
_inv lbAdd format["%1",_str]; //add a gun to the listbox
_inv lbSetData[(lbSize _inv)-1,_x select 0]; //set the data of the gun
} else {
_itemInfo = [_x select 0] call life_fnc_fetchCfgDetails;
_inv lbAdd format["%1",_itemInfo select 1]; //add a gun to the listbox
_inv lbSetData[(lbSize _inv)-1,_itemInfo select 0]; //set the data of the gun
_inv lbSetPicture[(lbSize _inv)-1,_itemInfo select 2];
};
} foreach (_config);
_inv lbSetCurSel 0;
_item = lbData[669,(lbCurSel 669)];
_config = [_itemFilter] call life_fnc_craftCfg;
{
if(_item == _x select 0)then {
_matsNeed = _x select 1;
_invSize = count _matsNeed;
for [{_i = 0},{_i < _invSize - 1},{_i = _i + 2}] do {
_str = M_CONFIG(getText,"VirtualItems",(_matsNeed select _i),"displayName");
_matsNum = _matsNeed select _i+1;
_struct = _struct + format["%1x %2<br/>",_matsNum,(localize _str)];
};
};
} foreach (_config);
_mats ctrlSetStructuredText parseText format["
<t size='0.8px'>
%1
</t>
",_struct];
Alles anzeigen
Schritt 10:
erstellt die Datei fn_craftCfg.sqf und fügt diese unter /core/config ein:
#include "..\..\script_macros.hpp"
/*
File: fn_craftCfg.sqf
Author: EdgeKiller
Description:
Master configuration file for the crafting menu.
*/
private["_craft","_return"];
_craft = [_this,0,"",[""]] call BIS_fnc_param;
if(_craft == "") exitWith {closeDialog 0}; //Bad shop type passed.
switch(_craft) do {
case "weapon": {
_return = [
//[Object classname, [item #1,quantity item #1,item #2,quantity item #2]],]
["hgun_P07_F", ["diamond_cut",2,"copper_refined",1]]
];
if(FETCH_CONST(life_adminlevel) > 0) then {
_return pushBack
["SMG_01_F", ["copper_refined",3,"iron_refined",3,"diamond_cut",1]];
};
};
case "uniform": {
_return = [
//[Object classname, [item #1,quantity item #1,item #2,quantity item #2]],]
["U_IG_Guerilla1_1", ["copper_refined",1]]
];
};
case "backpack": {
_return = [
//[Object classname, [item #1,quantity item #1,item #2,quantity item #2]],]
["B_Carryall_oli", ["diamond_cut",1]]
];
};
case "item": {
_return = [
//[Object classname, [item #1,quantity item #1,item #2,quantity item #2]],]
["iron_refined", ["copper_refined",2]],
["diamond_cut", ["copper_refined",1,"iron_refined",1]]
];
};
};
_return;
Alles anzeigen
Neues Tutorial (Update):
1. Cation Systems installieren:
a) cation.zip entpacken und Ordner cation in <mission> einfügen.
b) CfgRemoteExec.hpp bearbeiten:
unter
#include "cation\cation_remoteExec.cpp"
einfügen.
c) description.ext bearbeiten:
unter
#include "cation\cation_functions.cpp"
einfügen und ganz am Ende der Datei
#include "cation\cation_master.cpp"
einfügen.
2. Crafting installieren:
a) craftingSystem.zip entpacken und Ordner crafting nach <mission>/cation kopieren
b) in <misson>/cation/cation_function.cpp:
#include "crafting\functions.cpp"
einfügen.
c) in <misson>/cation/cation_master.cpp:
#include "crafting\config.cpp"
einfügen.
d) in <misson>/cation/cation_remoteExec.cpp:
#include "crafting\remoteExec.cpp"
einfügen.
e) Init-Code zum hinzufügen der Craftingstation an ein bestimmtes Objekt / einen NPC:
this allowDamage false; this enableSimulation false; this addAction["Craften",{["Variablennamen"] spawn cat_crafting_fnc_craft}];
f) Code zu hinzufügen ins Z-Menü (Button):
onButtonClick = "closeDialog 0; [""Variablennamen""] spawn cat_crafting_fnc_craft;";
Variablennamen muss in der config.cpp in der craftingStations[] definiert seien.
Alle anderen Einstellungen und Texte werden in <misson>/cation/crafting/config.cpp geändert
Funktionieren sollte das für alle ArmA Life Versionen. Getestet wurde es mit der V4.4R4 und 5.0
3. Crafting durch Fahrzeugcrafting erweitern:
a) craftingVehicles.zip entpacken und fn_craftAction.sqf in den Ordner <mission>/cation/crafting kopieren bzw. alte Datei ersetzen.
b) <mission>/cation/crafting/config.cpp öffnen und nach category[]={
{
"landvehicle", // Variable nicht verändern
"Bodenfahrzeuge",
{"C_SUV_01_F","",{"copper_refined",1,"diamond_cut",2},"Dark Red","civ"}
},
{
"airvehicle", // Variable nicht verändern
"Luftfahrzeuge",
{"C_Heli_Light_01_civil_F","",{"copper_refined",1},"Civ Blue","civ"}
},
{
"watervehicle", // Variable nicht verändern
"Wasserfahrzeuge",
{"C_Rubberboat","",{"copper_refined",1},"",""}
},
Alles anzeigen
einfügen.
In der craftingVehicles.zip ist nochmals eine config.cpp zum Vergleichen ob der Schritt richtig durchgeführt wurde.
Fertig - viel Spaß!