LUADOC - Farming Simulator 22

Script v1_7_1_0

Engine v1_7_1_0

Foundation Reference

SpeakerDisplay

Description
Player speaker display for consoles. Displays currently speaking players for consoles only. This display is used in place of the chat window.
Parent
HUDDisplayElement
Functions

createBackground

Description
Create the background overlay.
Definition
createBackground()
Code
303function SpeakerDisplay.createBackground(hudAtlasPath)
304 local posX, posY = SpeakerDisplay.getBackgroundPosition(1)
305 local width, height = getNormalizedScreenValues(unpack(SpeakerDisplay.SIZE.SELF))
306 local overlay = Overlay.new(nil, posX, posY, width, height)
307
308 return overlay
309end

createComponents

Description
Create required display components.
Definition
createComponents()
Code
313function SpeakerDisplay:createComponents(hudAtlasPath)
314 local baseX, baseY = SpeakerDisplay.getBackgroundPosition(1)
315
316 local offX, offY = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.SPEAKER_ICON)
317 local iconWidth, iconHeight = self:scalePixelToScreenVector(SpeakerDisplay.SIZE.SPEAKER_ICON)
318 local overlay = Overlay.new(hudAtlasPath, 0, 0, iconWidth, iconHeight)
319 overlay:setUVs(GuiUtils.getUVs(SpeakerDisplay.UV.SPEAKER_ICON))
320 overlay:setColor(unpack(SpeakerDisplay.COLOR.SPEAKER_ICON))
321 self.speakerIconOverlay = overlay
322
323 overlay = Overlay.new(hudAtlasPath, 0, 0, iconWidth, iconHeight)
324 overlay:setUVs(GuiUtils.getUVs(SpeakerDisplay.UV.SPEAKER_ICON_MUTED))
325 overlay:setColor(unpack(SpeakerDisplay.COLOR.SPEAKER_ICON_MUTED))
326 self.speakerIconOverlayMuted = overlay
327
328 overlay = Overlay.new(hudAtlasPath, 0, 0, iconWidth, iconHeight)
329 overlay:setUVs(GuiUtils.getUVs(SpeakerDisplay.UV.SPEAKER_ICON_AWAY))
330 overlay:setColor(unpack(SpeakerDisplay.COLOR.SPEAKER_ICON_AWAY))
331 self.speakerIconOverlayAway = overlay
332end

draw

Description
Definition
draw()
Code
201function SpeakerDisplay:draw()
202 if self:getVisible() then--and #self.currentSpeakers > 0 then
203 -- make sure we draw on top of everything because this display is so important for PS4 technical requirements:
204 new2DLayer()
205
206 SpeakerDisplay:superClass().draw(self) -- draw HUD elements
207
208 setTextBold(true)
209 setTextAlignment(RenderText.ALIGN_RIGHT)
210
211 local posX, posY = self:getPosition()
212
213 local function drawItem(index, user, isMuted, isAway)
214 local name = utf8ToUpper(user:getNickname())
215
216 local lineY = posY + (index - 1) * (self.lineHeight + self.lineSpacing)
217
218 -- Draw background rect
219 local width = getTextWidth(self.textSize, name) + math.abs(self.textOffsetX) + self.linePadding
220 drawFilledRect(posX - width, lineY, width, self.lineHeight, unpack(SpeakerDisplay.COLOR.BACKGROUND))
221
222 local textX = posX + self.textOffsetX
223 local textY = lineY + (self.lineHeight - self.textSize) * 0.5 + self.textOffsetY
224
225 -- Draw text shadow
226 setTextColor(unpack(SpeakerDisplay.COLOR.NAME_SHADOW))
227 renderText(textX + self.shadowOffset, textY - self.shadowOffset, self.textSize, name)
228
229 -- Draw text
230 setTextColor(unpack(SpeakerDisplay.COLOR.NAME))
231 renderText(textX, textY, self.textSize, name)
232
233 if isAway then
234 renderOverlay(self.speakerIconOverlayAway.overlayId, posX - self.linePadding - self.iconWidth, lineY + (self.lineHeight - self.iconHeight) * 0.5, self.iconWidth, self.iconHeight)
235 elseif isMuted then
236 renderOverlay(self.speakerIconOverlayMuted.overlayId, posX - self.linePadding - self.iconWidth, lineY + (self.lineHeight - self.iconHeight) * 0.5, self.iconWidth, self.iconHeight)
237 else
238 renderOverlay(self.speakerIconOverlay.overlayId, posX - self.linePadding - self.iconWidth, lineY + (self.lineHeight - self.iconHeight) * 0.5, self.iconWidth, self.iconHeight)
239 end
240 end
241
242 -- For each name
243 for i = 1, #self.currentSpeakers do
244 local user = self.currentSpeakers[i]
245 drawItem(i, user, user:getVoiceMuted(), false)
246 end
247
248 -- Add each away state
249 local i = #self.currentSpeakers
250 for user, _ in pairs(self.userAway) do
251 i = i + 1
252
253 drawItem(i, user, user:getVoiceMuted(), true)
254 end
255 end
256end

getBackgroundPosition

Description
Get this element's base background position.
Definition
getBackgroundPosition(float uiScale)
Arguments
floatuiScaleCurrent UI scale factor
Code
272function SpeakerDisplay.getBackgroundPosition(uiScale)
273 local offX, offY = getNormalizedScreenValues(unpack(SpeakerDisplay.POSITION.SELF))
274
275 -- make sure that the text is displayed within the center 90% of the screen (PS4 technical requirement):
276 -- 0.051 -> 5% in from the bottom (plus safety margin)
277 return (1 - g_safeFrameMajorOffsetX) + offX, g_safeFrameMajorOffsetY + offY
278end

getHeight

Description
Definition
getHeight()
Code
93function SpeakerDisplay:getHeight()
94 return #self.currentSpeakers * (self.lineHeight + self.lineSpacing)
95end

new

Description
Create a new SpeakerDisplay.
Definition
new(string hudAtlasPath, table ingameMap)
Arguments
stringhudAtlasPathPath to the HUD atlas texture.
tableingameMapIngameMap reference for positioning
Return Values
tableSpeakerDisplayinstance
Code
23function SpeakerDisplay.new(hudAtlasPath, ingameMap)
24 local backgroundOverlay = SpeakerDisplay.createBackground(hudAtlasPath)
25 local self = SpeakerDisplay:superClass().new(backgroundOverlay, nil, SpeakerDisplay_mt)
26
27 self.ingameMap = ingameMap
28
29 self.maxNumPlayers = g_serverMaxClientCapacity
30 self.users = {}
31
32 self.isMenuVisible = true
33 self.isInfoWindowVisible = false
34 self.isSpeedometerVisible = false
35
36 self.userSpeaking = {} -- {"full online ID" = bool}
37 self.userAway = {} -- {"full online ID" = bool}
38 self.userTiming = {} -- {"full online ID" = int}
39 self.userVisibility = {}
40 self.currentSpeakers = {} -- {i = "full online ID"}
41 self.lastVoiceState = {}
42
43 self.mapOffsetX, self.mapOffsetY = 0, 0
44 self.lineWidth, self.lineHeight = 0, 0
45 self.textLineOffsetX, self.textLineOffsetY = 0, 0
46 self.textSize = 0
47 self.textOffsetY = 0
48 self.shadowOffset = 0
49
50 self:storeScaledValues()
51 self:createComponents(hudAtlasPath)
52
53 return self
54end

onMenuVisibilityChange

Description
Handle menu visibility state change.
Definition
onMenuVisibilityChange()
Code
77function SpeakerDisplay:onMenuVisibilityChange(isMenuVisible, isOverlayMenu)
78 self.isMenuVisible = isMenuVisible and not isOverlayMenu
79 self.isMenuMapVisible = self.isMenuMapVisible and isMenuVisible
80
81 self:updateVisibility() -- makes sure there is no one-frame delay for the re-ordering (vertical/horizontal)
82end

setScale

Description
Set this element's UI scale.
Definition
setScale()
Code
264function SpeakerDisplay:setScale(uiScale)
265 SpeakerDisplay:superClass().setScale(self, uiScale)
266 self:storeScaledValues()
267end

storeScaledValues

Description
Store scaled positioning, size and offset values.
Definition
storeScaledValues()
Code
282function SpeakerDisplay:storeScaledValues()
283 self.positionXHUD, self.positionYHUD = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.SELF)
284 self.positionXMenu, self.positionYMenu = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.SELF_MENU)
285
286 self.lineWidth, self.lineHeight = self:scalePixelToScreenVector(SpeakerDisplay.SIZE.LINE)
287 self.lineSpacing = self:scalePixelToScreenHeight(SpeakerDisplay.POSITION.LINE_SPACING[2])
288 self.linePadding = self:scalePixelToScreenWidth(SpeakerDisplay.POSITION.LINE_PADDING[1])
289
290 self.iconWidth, self.iconHeight = self:scalePixelToScreenVector(SpeakerDisplay.SIZE.SPEAKER_ICON)
291
292 self.textOffsetX, self.textOffsetY = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.NAME)
293 self.textSize = self:scalePixelToScreenHeight(SpeakerDisplay.TEXT_SIZE.NAME)
294 self.shadowOffset = SpeakerDisplay.SHADOW_OFFSET_FACTOR * self.textSize
295end

update

Description
Update the display state each frame.
Definition
update()
Code
174function SpeakerDisplay:update(dt)
175 SpeakerDisplay:superClass().update(self, dt)
176
177 self:updateSpeakingState(dt)
178 self:updateVisibility()
179
180
181 if not self.isMenuVisible then
182 if self.isSpeedometerVisible then
183 local _, y = g_currentMission.hud.speedMeter:getPosition()
184 local h = g_currentMission.hud.speedMeter:getHeight()
185 self:setPosition(nil, y + h)
186 else
187 local h = g_currentMission.hud.infoDisplay:getDisplayHeight()
188 self:setPosition(nil, g_safeFrameMajorOffsetY + h)
189 end
190 else
191 self:setPosition(nil, g_safeFrameMajorOffsetY)
192 end
193end

updateSpeakingState

Description
Update current speaking state for all connected users.
Definition
updateSpeakingState()
Code
103function SpeakerDisplay:updateSpeakingState(dt)
104 for _, user in pairs(self.users) do
105 local uuid = user:getUniqueUserId()
106 local wasSpeakingLastFrame = self.userSpeaking[uuid]
107 local isSpeakingNow = VoiceChatUtil.getIsSpeakerActive(uuid) and not user:getIsBlocked()
108
109 -- When removing, wait 500ms to hide
110 -- When adding, wait 250ms to show
111
112 if wasSpeakingLastFrame and not isSpeakingNow then
113 self.userTiming[uuid] = 500
114 elseif isSpeakingNow and not wasSpeakingLastFrame then
115 self.userTiming[uuid] = 250
116 end
117
118 self.userSpeaking[uuid] = isSpeakingNow
119
120 if self.userTiming[uuid] ~= nil then
121 self.userTiming[uuid] = self.userTiming[uuid] - dt
122
123 if self.userTiming[uuid] <= 0 then
124 self.userTiming[uuid] = nil
125
126 if self.userSpeaking[uuid] and not self.userVisibility[uuid] then
127 table.insert(self.currentSpeakers, user)
128 self.userVisibility[uuid] = true
129 elseif not self.userSpeaking[uuid] and self.userVisibility[uuid] then
130 table.removeElement(self.currentSpeakers, user)
131 self.userVisibility[uuid] = false
132 end
133 end
134 end
135
136 if Platform.isStadia then
137 local state = voiceChatGetConnectionStatus(uuid)
138 if self.lastVoiceState ~= state then
139 if state == VoiceChatConnectionStatus.UNAVAILABLE then
140 -- Add on-change
141 self.userAway[user] = 2000
142
143 -- Hide from active speakers so player doesnt show twice
144 table.removeElement(self.currentSpeakers, user)
145 self.userVisibility[uuid] = false
146 else
147 -- Directly remove when mic was enabled
148 self.userAway[user] = nil
149 end
150
151 self.lastVoiceState[uuid] = state
152 end
153
154 -- Countdown timer to hide
155 if self.userAway[user] ~= nil then
156 self.userAway[user] = self.userAway[user] - dt
157
158 if self.userAway[user] <= 0 then
159 self.userAway[user] = nil
160 end
161 end
162 end
163 end
164end

updateVisibility

Description
Update visibility states based on active speakers.
Definition
updateVisibility()
Code
168function SpeakerDisplay:updateVisibility()
169 self:setVisible(true)
170end