Skip to content

Commit 66d1872

Browse files
committed
Add proper UI for "Comms Sabotaged"
Fixes #25
1 parent 284257b commit 66d1872

6 files changed

Lines changed: 305 additions & 63 deletions

File tree

Lines changed: 305 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,305 @@
1-
comms = {
2-
Init: (data) =>
3-
@Base.Init @, data
4-
5-
if SERVER
6-
@SetMajor true
7-
@SetPersistent true
8-
9-
OnStart: =>
10-
@Base.OnStart @
11-
if SERVER
12-
GAMEMODE\SetCommunicationsDisabled true
13-
14-
local btn
15-
for ent in *ents.GetAll!
16-
if ent.GetSabotageName and ent\GetSabotageName! == @GetHandler!
17-
btn = ent
18-
break
19-
20-
if btn
21-
@SetActivationButtons btn
22-
23-
OnButtonUse: (playerTable, button) =>
24-
if SERVER
25-
GAMEMODE\Sabotage_OpenVGUI playerTable, @, button
26-
27-
OnSubmit: =>
28-
@End!
29-
30-
OnEnd: =>
31-
@Base.OnEnd @
32-
if SERVER
33-
GAMEMODE\SetCommunicationsDisabled false
34-
@SetActivationButtons!
35-
}
36-
37-
if CLIENT
38-
with comms
39-
.CreateVGUI = =>
40-
base = vgui.Create "AmongUsSabotageBase"
41-
42-
with base
43-
\SetSabotage @
44-
\Setup with vgui.Create "DPanel"
45-
max_size = ScrH! * 0.7
46-
47-
\SetSize max_size, max_size * 0.55
48-
49-
\SetBackgroundColor Color 64, 64, 64
50-
with \Add "DButton"
51-
margin = ScrH! * 0.01
52-
\DockMargin margin * 4, 0, margin * 4, margin * 4
53-
\SetTall ScrH! * 0.05
54-
\SetFont "NMW AU PlaceholderText"
55-
\Dock BOTTOM
56-
\SetText "Submit"
57-
.DoClick = ->
58-
base\Submit!
59-
\Popup!
60-
61-
return base
62-
63-
return comms
1+
comms = {
2+
Init: (data) =>
3+
@Base.Init @, data
4+
5+
if SERVER
6+
@SetMajor true
7+
@SetPersistent true
8+
@SetNetworkable "Position"
9+
10+
OnStart: =>
11+
@Base.OnStart @
12+
if SERVER
13+
@SetPosition math.random -110, 110
14+
GAMEMODE\SetCommunicationsDisabled true
15+
16+
local btn
17+
for ent in *ents.GetAll!
18+
if ent.GetSabotageName and ent\GetSabotageName! == @GetHandler!
19+
btn = ent
20+
break
21+
22+
if btn
23+
@SetActivationButtons btn
24+
25+
OnButtonUse: (playerTable, button) =>
26+
if SERVER
27+
GAMEMODE\Sabotage_OpenVGUI playerTable, @, button
28+
29+
OnSubmit: =>
30+
@End!
31+
32+
OnEnd: =>
33+
@Base.OnEnd @
34+
if SERVER
35+
GAMEMODE\SetCommunicationsDisabled false
36+
@SetActivationButtons!
37+
38+
SetPosition: (value) =>
39+
@__position = value
40+
if SERVER
41+
@SetDirty!
42+
43+
GetPosition: => @__position or 0
44+
}
45+
46+
if CLIENT
47+
ROTATION_MATRIX = Matrix!
48+
49+
COLOR_ACTIVE = Color 0, 255, 0
50+
COLOR_INACTIVE = Color 255, 0, 0
51+
52+
COMMONS = {asset, Material("au/gui/sabotages/common/#{asset}.png", "smooth") for asset in *{
53+
"light"
54+
"lightshine"
55+
}}
56+
57+
ASSETS = {asset, Material("au/gui/sabotages/comms/#{asset}.png", "smooth") for asset in *{
58+
"radio"
59+
"headphones"
60+
"dial"
61+
}}
62+
63+
-- Swiggity swooty.
64+
comms.SetPosition = (value) =>
65+
@__position = value
66+
@__theta = nil
67+
68+
OSCIL_COUNT = 200
69+
comms.CreateVGUI = (data) =>
70+
base = vgui.Create "AmongUsSabotageBase"
71+
72+
-- Create sounds and attach them to the button (radio).
73+
sounds =
74+
radio: CreateSound data.button, "au/panel_comms_radio.wav"
75+
static: CreateSound data.button, "au/panel_comms_static.wav"
76+
77+
sounds.radio\PlayEx 0, 100
78+
79+
sounds.static\PlayEx 0.25, 100
80+
81+
-- Set up a hook to catch and clean sounds up.
82+
hook.Add "Think", "GMAU Comms Thinker", ->
83+
for _, sound in pairs sounds
84+
continue if not sound
85+
if sound\IsPlaying! and not IsValid base
86+
sound\Stop!
87+
88+
if not IsValid base
89+
hook.Remove "Think", "GMAU Comms Thinker"
90+
91+
with base
92+
\SetSabotage @
93+
\Setup with vgui.Create "DImage"
94+
if not @__theta
95+
validPositions = {}
96+
-- You know what? This is the definition of jank.
97+
-- I didn't want to implement proper weighted random.
98+
for i = -110, 110, 10
99+
if 10 < math.abs @GetPosition! - i
100+
table.insert validPositions, i
101+
102+
@__theta = table.Random validPositions
103+
104+
correct = false
105+
accumulator = 0
106+
submitted = false
107+
108+
.Think = ->
109+
-- Determine whether we should increment/decrement the accumulator.
110+
changed = if correct and accumulator < 1.25
111+
accumulator = math.min 1.25, accumulator + FrameTime! * 0.5
112+
true
113+
114+
elseif not correct and accumulator > 0
115+
accumulator = math.max 0, accumulator - FrameTime! * 0.5
116+
true
117+
118+
-- If the accumulator value was changed earlier...
119+
if changed
120+
clamped = math.Clamp accumulator, 0, 1
121+
122+
-- Modulate sounds.
123+
sounds.static\ChangeVolume 0.25 * (1 - clamped)
124+
sounds.radio\ChangeVolume 0.25 * clamped
125+
126+
-- Submit.
127+
if accumulator == 1.25 and not submitted
128+
submitted = true
129+
base\Submit!
130+
131+
max_size = ScrH! * 0.75
132+
\SetSize max_size, (max_size / 505) * 349
133+
\SetMaterial ASSETS.radio
134+
135+
oscilWidth = (max_size / 505) * 196
136+
oscilHeight = (max_size / 505) * 121
137+
138+
leftOscilX = (max_size / 505) * 37
139+
rightOscilX = (max_size / 505) * 276
140+
oscilY = (max_size / 505) * 37
141+
142+
headphonesWidth = (max_size / 505) * 577
143+
headphonesHeight = (max_size / 505) * 486
144+
145+
headphonesOffsetX = (max_size / 505) * -72
146+
headphonesOffsetY = (max_size / 505) * -136
147+
148+
-- Override Paint and draw headphones behind the panel.
149+
-- Hacky but gets the job done.
150+
oldPaint = .Paint
151+
.Paint = (w, h) =>
152+
old = DisableClipping true
153+
154+
surface.SetDrawColor 255, 255, 255
155+
surface.SetMaterial ASSETS.headphones
156+
surface.DrawTexturedRect headphonesOffsetX, headphonesOffsetY,
157+
headphonesWidth, headphonesHeight
158+
159+
DisableClipping old
160+
161+
oldPaint @, w, h
162+
163+
-- Left oscillator.
164+
-- Fast sin.
165+
with \Add "Panel"
166+
\SetPos leftOscilX, oscilY
167+
\SetSize oscilWidth, oscilHeight
168+
.Paint = (_, w, h) ->
169+
surface.SetDrawColor 0, 255, 0
170+
171+
local prev
172+
for i = 1, OSCIL_COUNT
173+
value = 0.5 + (math.sin CurTime! * 15 + i * 0.1) * 0.2
174+
if prev
175+
-- Multiply and flip the values.
176+
cy = h - h * value
177+
py = h - h * prev
178+
179+
-- Flip the values again.
180+
cx = w - w * ((i - 1) / (OSCIL_COUNT - 1))
181+
px = w - w * ((i - 2) / (OSCIL_COUNT - 1))
182+
183+
-- This will probably look horrible for 4K players.
184+
-- But oh well!
185+
surface.DrawLine cx, cy, px, py
186+
187+
prev = value
188+
189+
-- Right oscillator.
190+
-- Fast sin with noise.
191+
with \Add "Panel"
192+
\SetPos rightOscilX, oscilY
193+
\SetSize oscilWidth, oscilHeight
194+
.Paint = (_, w, h) ->
195+
surface.SetDrawColor 0, 255, 0
196+
197+
local prev
198+
for i = 1, OSCIL_COUNT
199+
distortion = math.abs(@GetPosition! - @__theta) / 110
200+
201+
value = 0.5 + (math.sin CurTime! * 15 + i * 0.1) * 0.2 +
202+
((math.random! * 2) - 1) * 0.1 * distortion +
203+
((math.random! * 2) - 1) * 0.01
204+
205+
if prev
206+
-- Multiply and flip the values.
207+
cy = h - h * value
208+
py = h - h * prev
209+
210+
cx = w * ((i - 1) / (OSCIL_COUNT - 1))
211+
px = w * ((i - 2) / (OSCIL_COUNT - 1))
212+
213+
-- This will probably look horrible for 4K players.
214+
-- But oh well!
215+
surface.DrawLine cx, cy, px, py
216+
217+
prev = value
218+
219+
dialX = (max_size / 505) * 381
220+
dialY = (max_size / 505) * 252
221+
dialWidth = (max_size / 505) * 122
222+
dialHeight = (max_size / 505) * 137
223+
dialMax = math.max dialWidth, dialHeight
224+
225+
dialOriginX = (max_size / 505) * 122 / 2
226+
dialOriginY = (max_size / 505) * 79
227+
228+
-- Dial.
229+
with \Add "Button"
230+
\SetPos dialX - dialMax/2, dialY - dialMax/2
231+
\SetSize dialMax, dialMax
232+
\SetText ""
233+
.Paint = (_, w, h) ->
234+
-- If the player is holding the dial,
235+
-- point it towards the cursor.
236+
if \IsDown!
237+
cursorX, cursorY = \LocalCursorPos!
238+
239+
@__theta = math.Clamp (math.NormalizeAngle -90 + math.deg(
240+
math.atan2 dialOriginY - cursorY, dialOriginX - cursorX
241+
)), -110, 110
242+
243+
correct = 8 > math.abs @GetPosition! - @__theta
244+
245+
-- Prepare the rotation matrix.
246+
ltsx, ltsy = _\LocalToScreen 0, 0
247+
v = Vector ltsx + dialOriginX, ltsy + dialOriginY
248+
249+
with ROTATION_MATRIX
250+
\Identity!
251+
\Translate v
252+
\Rotate Angle 0, @__theta, 0
253+
\Translate -v
254+
255+
surface.DisableClipping true
256+
cam.PushModelMatrix ROTATION_MATRIX, true
257+
258+
surface.SetDrawColor 255, 255, 255
259+
260+
-- Draw the dial.
261+
surface.SetMaterial ASSETS.dial
262+
surface.DrawTexturedRect 0, 0,
263+
dialWidth, dialHeight
264+
265+
cam.PopModelMatrix!
266+
surface.DisableClipping false
267+
268+
lightWidth = (max_size / 505) * 24
269+
lightHeight = (max_size / 505) * 24
270+
lightOffsetX = (max_size / 505) * 476
271+
lightOffsetY = (max_size / 505) * 166
272+
273+
-- Right LED.
274+
-- Becomes greener the longer the dial is held at the correct position.
275+
with \Add "Panel"
276+
\SetSize lightWidth, lightHeight
277+
\SetPos lightOffsetX - lightWidth, lightOffsetY
278+
279+
.Paint = (_, w, h) ->
280+
surface.SetDrawColor 0, 255 * math.min(accumulator, 1), 0
281+
surface.SetMaterial COMMONS.light
282+
surface.DrawTexturedRect 0, 0, w, h
283+
284+
with \Add "DImage"
285+
\Dock FILL
286+
\SetMaterial COMMONS.lightshine
287+
288+
-- LED.
289+
--
290+
with \Add "Panel"
291+
\SetSize lightWidth, lightHeight
292+
\SetPos lightOffsetX - lightWidth * 2 - lightWidth / 4, lightOffsetY
293+
294+
.Paint = (_, w, h) ->
295+
surface.SetDrawColor (accumulator > 1) and COLOR_ACTIVE or COLOR_INACTIVE
296+
surface.SetMaterial COMMONS.light
297+
surface.DrawTexturedRect 0, 0, w, h
298+
299+
with \Add "DImage"
300+
\Dock FILL
301+
\SetMaterial COMMONS.lightshine
302+
303+
\Popup!
304+
305+
return comms
9.94 KB
Loading
26.4 KB
Loading
25.6 KB
Loading

src/sound/au/panel_comms_radio.wav

3.09 MB
Binary file not shown.
173 KB
Binary file not shown.

0 commit comments

Comments
 (0)