2[
WorkbenchPluginAttribute(name:
"Generate Controls Scheme", wbModules: {
"ResourceManager" }, awesomeFontCode: 0xF11B)]
3class SCR_GenerateControlsSchemePlugin : WorkbenchPlugin
5 [
Attribute(
desc:
"A list of contexts to be exported. Actions from all contexts will be merged into one image.")]
6 protected ref array<string> m_aContextNames;
8 [
Attribute(defvalue:
"$profile:GenerateControlsScheme/",
desc:
"Directory at which the scheme will be saved")]
12 protected SCR_EGenerateControlsSchemeType
m_eType = SCR_EGenerateControlsSchemeType.GAMEPAD;
14 [
Attribute(defvalue:
"1",
desc:
"Font size multiplier. Use a smaller font when action names are too long and overflow from the image.")]
15 protected float m_fFontSize;
17 [
Attribute(defvalue:
"1",
desc:
"True to label actions that are not used in given contexts. Unassigned actions will be shown in faded color.")]
18 protected bool m_bShowUnassigned;
22 bool ProcessBinding_Gamepad(
map<
string, ref array<string>> allBindings,
string fullPath,
string contextTitle)
24 bool didCopy =
FileIO.CopyFile(
"scripts/WorkbenchGame/GenerateControlsScheme_Gamepad.txt", fullPath);
27 Print(
string.Format(
"Cannot copy header to '%1'!", fullPath),
LogLevel.ERROR);
34 Print(
string.Format(
"Cannot open file at '%1'!", fullPath),
LogLevel.ERROR);
38 const float tL1 = 280;
39 const float lL1 = 290;
40 const float lL2 = 370;
42 const float tR1 = 800;
43 const float lR1 = 790;
44 const float lR2 = 710;
47 labels.Insert(
"gamepad0:view",
new SCR_GenerateControlsSchemeGamepadLabel(
"end", 500, 040, 510, 510, 035, 510, 245));
48 labels.Insert(
"gamepad0:menu",
new SCR_GenerateControlsSchemeGamepadLabel(
"start", 580, 040, 572, 572, 035, 572, 245));
50 labels.Insert(
"gamepad0:left_trigger",
new SCR_GenerateControlsSchemeGamepadLabel(
"end", tL1, 070, lL1, lL2, 065, 450, 171));
51 labels.Insert(
"gamepad0:shoulder_left",
new SCR_GenerateControlsSchemeGamepadLabel(
"end", tL1, 130, lL1, lL2, 125, 420, 185));
52 labels.Insert(
"gamepad0:left_thumb_horizontal",
new SCR_GenerateControlsSchemeGamepadLabel(
"end", tL1, 250, lL1, lL2, 275, 420, 250,
"⭤"));
53 labels.Insert(
"gamepad0:left_thumb_vertical",
new SCR_GenerateControlsSchemeGamepadLabel(
"end", tL1, 280, lL1, lL2, 275, 420, 250,
"⭥"));
54 labels.Insert(
"gamepad0:thumb_left",
new SCR_GenerateControlsSchemeGamepadLabel(
"end", tL1, 310, lL1, lL2, 275, 420, 250,
"●"));
55 labels.Insert(
"gamepad0:pad_up",
new SCR_GenerateControlsSchemeGamepadLabel(
"end", tL1, 360, lL1, lL2, 400, 460, 320,
"▲"));
56 labels.Insert(
"gamepad0:pad_left",
new SCR_GenerateControlsSchemeGamepadLabel(
"end", tL1, 390, lL1, lL2, 400, 460, 320,
"◄"));
57 labels.Insert(
"gamepad0:pad_right",
new SCR_GenerateControlsSchemeGamepadLabel(
"end", tL1, 420, lL1, lL2, 400, 460, 320,
"►"));
58 labels.Insert(
"gamepad0:pad_down",
new SCR_GenerateControlsSchemeGamepadLabel(
"end", tL1, 450, lL1, lL2, 400, 460, 320,
"▼"));
60 labels.Insert(
"gamepad0:right_trigger",
new SCR_GenerateControlsSchemeGamepadLabel(
"start", tR1, 070, lR1, lR2, 065, 630, 171));
61 labels.Insert(
"gamepad0:shoulder_right",
new SCR_GenerateControlsSchemeGamepadLabel(
"start", tR1, 130, lR1, lR2, 125, 660, 185));
62 labels.Insert(
"gamepad0:y",
new SCR_GenerateControlsSchemeGamepadLabel(
"start", tR1, 190, lR1, lR2, 185, 660, 220));
63 labels.Insert(
"gamepad0:x",
new SCR_GenerateControlsSchemeGamepadLabel(
"start", tR1, 220, lR1, lR2, 215, 630, 250));
64 labels.Insert(
"gamepad0:b",
new SCR_GenerateControlsSchemeGamepadLabel(
"start", tR1, 250, lR1, lR2, 245, 690, 250));
65 labels.Insert(
"gamepad0:a",
new SCR_GenerateControlsSchemeGamepadLabel(
"start", tR1, 280, lR1, lR2, 275, 660, 280));
66 labels.Insert(
"gamepad0:right_thumb_horizontal",
new SCR_GenerateControlsSchemeGamepadLabel(
"start", tR1, 360, lR1, lR2, 385, 610, 320,
"⭤"));
67 labels.Insert(
"gamepad0:right_thumb_vertical",
new SCR_GenerateControlsSchemeGamepadLabel(
"start", tR1, 390, lR1, lR2, 385, 610, 320,
"⭥"));
68 labels.Insert(
"gamepad0:thumb_right",
new SCR_GenerateControlsSchemeGamepadLabel(
"start", tR1, 420, lR1, lR2, 385, 610, 320,
"●"));
70 string texts =
string.Format(
"<text x='20' y='570' text-anchor='start' font-size='25' font-weight='bold'>%1</text>\n", contextTitle);
74 SCR_GenerateControlsSchemeGamepadLabel label;
75 array<string> bindings;
76 for (
int l, countL = labels.Count(); l < countL; l++)
78 label = labels.GetElement(l);
79 if (allBindings.Find(labels.GetKey(l), bindings))
81 label.AddText(texts, bindings[0]);
82 label.AddLines(lines);
84 else if (m_bShowUnassigned)
86 label.AddText(textsDisabled,
"N/A");
87 label.AddLines(linesDisabled);
91 file.WriteLine(
string.Format(
"<g font-family='Roboto' font-size='%1' fill='#ccc'>", 20 * m_fFontSize));
92 file.WriteLine(textsDisabled);
93 file.WriteLine(
"</g>");
95 file.WriteLine(
string.Format(
"<g font-family='Roboto' font-size='%1' fill='black'>", 20 * m_fFontSize));
96 file.WriteLine(texts);
97 file.WriteLine(
"</g>");
99 file.WriteLine(
"<g stroke='black' stroke-width='2' opacity='0.1' transform='translate(0.5,0.5)'>");
100 file.WriteLine(linesDisabled);
101 file.WriteLine(
"</g>");
103 file.WriteLine(
"<g stroke='black' stroke-width='2' opacity='1' transform='translate(0.5,0.5)'>");
104 file.WriteLine(lines);
105 file.WriteLine(
"</g>");
107 file.WriteLine(
"</svg>");
116 protected bool ProcessBinding_Keyboard(
map<
string, ref array<string>> allBindings,
string fileName,
string contextTitle)
123 protected bool ProcessBinding_Mouse(
map<
string, ref array<string>> allBindings,
string fileName,
string contextTitle)
132 if (!m_aContextNames)
138 array<string> whitelist = {};
141 case SCR_EGenerateControlsSchemeType.KEYBOARD:
144 case SCR_EGenerateControlsSchemeType.MOUSE:
147 case SCR_EGenerateControlsSchemeType.GAMEPAD:
148 whitelist.Insert(
"gamepad0:menu");
149 whitelist.Insert(
"gamepad0:view");
150 whitelist.Insert(
"gamepad0:a");
151 whitelist.Insert(
"gamepad0:b");
152 whitelist.Insert(
"gamepad0:x");
153 whitelist.Insert(
"gamepad0:y");
154 whitelist.Insert(
"gamepad0:pad_up");
155 whitelist.Insert(
"gamepad0:pad_down");
156 whitelist.Insert(
"gamepad0:pad_left");
157 whitelist.Insert(
"gamepad0:pad_right");
158 whitelist.Insert(
"gamepad0:shoulder_left");
159 whitelist.Insert(
"gamepad0:shoulder_right");
160 whitelist.Insert(
"gamepad0:thumb_left");
161 whitelist.Insert(
"gamepad0:thumb_right");
162 whitelist.Insert(
"gamepad0:left_thumb_horizontal");
163 whitelist.Insert(
"gamepad0:left_thumb_vertical");
164 whitelist.Insert(
"gamepad0:right_thumb_horizontal");
165 whitelist.Insert(
"gamepad0:right_thumb_vertical");
166 whitelist.Insert(
"gamepad0:left_trigger");
167 whitelist.Insert(
"gamepad0:right_trigger");
174 foreach (
string contextName : m_aContextNames)
179 Print(
string.Format(
"Context '%1' not found!", contextName),
LogLevel.ERROR);
183 array<string> actionNames = {};
184 if (!context.Get(
"ActionRefs", actionNames))
187 foreach (
string actionName : actionNames)
189 array<string> bindings = {};
190 if (!input.GetBindings(actionName, bindings, EInputDeviceType.MOUSE))
193 if (!input.GetBindings(actionName, bindings, EInputDeviceType.KEYBOARD))
196 if (!input.GetBindings(actionName, bindings, EInputDeviceType.GAMEPAD))
199 if (!input.GetBindings(actionName, bindings, EInputDeviceType.JOYSTICK))
202 foreach (
string binding : bindings)
204 if (whitelist.Find(binding) < 0)
207 array<string> currentBindings;
208 allBindings.Find(binding, currentBindings);
209 if (!currentBindings)
210 currentBindings = {};
212 currentBindings.Insert(actionName);
213 allBindings.Insert(binding, currentBindings);
217 if (contextTitle !=
"")
218 contextTitle +=
", ";
220 contextTitle += contextName;
224 foreach (
string contextName : m_aContextNames)
226 fileName +=
"_" + contextName;
230 if (!directoryLocal.EndsWith(
"/"))
231 directoryLocal +=
"/";
237 case SCR_EGenerateControlsSchemeType.KEYBOARD:
239 fullPath = directoryLocal +
"keyboard" + fileName +
".svg";
240 succeeded = ProcessBinding_Keyboard(allBindings, fullPath, contextTitle);
243 case SCR_EGenerateControlsSchemeType.MOUSE:
245 fullPath = directoryLocal +
"mouse" + fileName +
".svg";
246 succeeded = ProcessBinding_Mouse(allBindings, fullPath, contextTitle);
249 case SCR_EGenerateControlsSchemeType.GAMEPAD:
251 fullPath = directoryLocal +
"gamepad" + fileName +
".svg";
252 succeeded = ProcessBinding_Gamepad(allBindings, fullPath, contextTitle);
258 Print(
string.Format(
"Controls scheme generated in '%1'", fullPath),
LogLevel.DEBUG);
268 if (Workbench.ScriptDialog(
"Generate Controls Scheme",
"Generate a *.svg file which lists all actions in given contexts.\nThe file can be attached to Confluence page to showcase a control scheme.",
this))
287enum SCR_EGenerateControlsSchemeType
294class SCR_GenerateControlsSchemeGamepadLabel
296 protected string m_sAnchor;
297 protected float m_fTextX;
298 protected float m_fTextY;
299 protected float m_fLineX1;
300 protected float m_fLineX2;
301 protected float m_fLineY;
302 protected float m_fTargetX;
303 protected float m_fTargetY;
304 protected string m_sSymbol;
317 void SCR_GenerateControlsSchemeGamepadLabel(
string anchor,
float textX,
float textY,
float lineX1,
float lineX2,
float lineY,
float targetX,
float targetY,
string symbol =
"")
325 m_fTargetX = targetX;
326 m_fTargetY = targetY;
334 void AddText(out
string text,
string binding)
338 if (m_sAnchor ==
"end")
339 binding = binding +
" " + m_sSymbol;
341 binding = m_sSymbol +
" " + binding;
344 text +=
string.Format(
"<text x='%3' y='%4' text-anchor='%2'>%1</text>\n", binding, m_sAnchor, m_fTextX, m_fTextY);
350 void AddLines(out
string text)
353 text +=
string.Format(
"<line x1='%1' x2='%2' y1='%3' y2='%3' />\n", m_fLineX1, m_fLineX2, m_fLineY, m_fTargetX, m_fTargetY);
354 text +=
string.Format(
"<line x1='%2' x2='%4' y1='%3' y2='%5' />\n", m_fLineX1, m_fLineX2, m_fLineY, m_fTargetX, m_fTargetY);
ArmaReforgerScripted GetGame()
SCR_ECampaignBaseType m_eType
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
class WorkbenchDialog_AbortRetryIgnore ButtonAttribute("OK", true)
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
SCR_FieldOfViewSettings Attribute
FileMode
Mode for opening file. See FileSystem::Open.