LUADOC - Farming Simulator 19

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
263function SpeakerDisplay.createBackground(hudAtlasPath)
264 local posX, posY = SpeakerDisplay.getBackgroundPosition(1)
265 local width, height = getNormalizedScreenValues(unpack(SpeakerDisplay.SIZE.SELF))
266 local overlay = Overlay:new(nil, posX, posY, width, height)
267 return overlay
268end

createComponents

Description
Create required display components.
Definition
createComponents()
Code
295function SpeakerDisplay:createComponents(hudAtlasPath)
296 local baseX, baseY = SpeakerDisplay.getBackgroundPosition(1)
297
298 -- add lines from bottom to top
299 local posY = baseY
300 for i = 1, self.maxNumPlayers do
301 self:createSpeakerElement(hudAtlasPath, baseX, posY, self.lineWidth, self.lineHeight, self.speakerLineElements)
302 posY = posY + self.lineHeight
303 end
304
305 -- add columns from left to right for menu display
306 local posX = baseX
307 for i = 1, self.maxNumPlayers do
308 self:createSpeakerElement(hudAtlasPath, posX, baseY, self.lineWidth, self.lineHeight, self.speakerColumnElements)
309 posX = posX + self.lineWidth
310 end
311end

createSpeakerElement

Description
Create a display element for an active speaker for HUD display.
Definition
createSpeakerElement()
Code
272function SpeakerDisplay:createSpeakerElement(hudAtlasPath, leftX, bottomY, width, height, elementArray)
273 -- background
274 local overlay = Overlay:new(hudAtlasPath, leftX, bottomY, width, height)
275 overlay:setUVs(getNormalizedUVs(SpeakerDisplay.UV.LINE))
276 overlay:setColor(unpack(SpeakerDisplay.COLOR.BACKGROUND))
277 local speakerElement = HUDElement:new(overlay)
278 self:addChild(speakerElement)
279 table.insert(elementArray, speakerElement)
280
281 -- speaker icon
282 local offX, offY = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.SPEAKER_ICON)
283 local iconWidth, iconHeight = self:scalePixelToScreenVector(SpeakerDisplay.SIZE.SPEAKER_ICON)
284 local posX = leftX + offX
285 local posY = bottomY + (height - iconHeight) * 0.5 + offY
286 overlay = Overlay:new(hudAtlasPath, posX, posY, iconWidth, iconHeight)
287 overlay:setUVs(getNormalizedUVs(SpeakerDisplay.UV.SPEAKER_ICON))
288 overlay:setColor(unpack(SpeakerDisplay.COLOR.SPEAKER_ICON))
289 local speakerIconElement = HUDElement:new(overlay)
290 speakerElement:addChild(speakerIconElement)
291end

draw

Description
Definition
draw()
Code
180function SpeakerDisplay:draw()
181 if self:getVisible() and #self.currentSpeakers > 0 then
182 -- make sure we draw on top of everything because this display is so important for PS4 technical requirements:
183 new2DLayer()
184
185 SpeakerDisplay:superClass().draw(self) -- draw HUD elements
186
187 setTextBold(true)
188 setTextAlignment(RenderText.ALIGN_LEFT)
189
190 local speakerElements = self.speakerLineElements
191 local offX, offY = self.textLineOffsetX, self.textLineOffsetY
192 if self.isMenuVisible and not self.isMenuMapVisible then
193 -- use horizontal elements as the base points when in the menu
194 speakerElements = self.speakerColumnElements
195 offX, offY = self.textColOffsetX, self.textColOffsetY
196 end
197
198 -- draw names
199 for i = 1, #self.currentSpeakers do
200 local speakerElement = speakerElements[i]
201 local lineX, lineY = speakerElement:getPosition()
202 local lineHeight = speakerElement:getHeight()
203
204 local posX = lineX + offX
205 local posY = lineY + (lineHeight - self.textSize) * 0.5 + offY + self.textOffsetY
206
207 -- render shadow
208 setTextColor(unpack(SpeakerDisplay.COLOR.NAME_SHADOW))
209 renderText(posX + self.shadowOffset, posY - self.shadowOffset, self.textSize, self.currentSpeakers[i])
210 -- render text
211 setTextColor(unpack(SpeakerDisplay.COLOR.NAME))
212 renderText(posX, posY, self.textSize, self.currentSpeakers[i])
213 end
214 end
215end

getBackgroundPosition

Description
Get this element's base background position.
Definition
getBackgroundPosition(float uiScale)
Arguments
floatuiScaleCurrent UI scale factor
Code
231function SpeakerDisplay.getBackgroundPosition(uiScale)
232 local offX, offY = getNormalizedScreenValues(unpack(SpeakerDisplay.POSITION.SELF))
233 -- make sure that the text is displayed within the center 90% of the screen (PS4 technical requirement):
234 -- 0.051 -> 5% in from the bottom (plus safety margin)
235 return g_safeFrameOffsetX + offX, math.max(0.51, g_safeFrameOffsetY + offY)
236end

getHeight

Description
Definition
getHeight()
Code
90function SpeakerDisplay:getHeight()
91 return #self.currentSpeakers * self.lineHeight
92end

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(SpeakerDisplay_mt, backgroundOverlay, nil)
26
27 self.ingameMap = ingameMap
28
29 self.maxNumPlayers = g_serverMaxCapacity
30 self.users = {}
31
32 self.isMenuVisible = true
33 self.isMenuMapVisible = false
34 self.isChatVisible = false
35
36 self.userSpeaking = {} -- {"full online ID" = bool}
37 self.currentSpeakers = {} -- {i = "full online ID"}
38 self.speakerLineElements = {} -- {i = HUDElement}
39 self.speakerColumnElements = {} -- {i = HUDElement}
40
41 self.mapOffsetX, self.mapOffsetY = 0, 0
42 self.positionHorizontalX, self.positionHorizontalY = 0, 0
43 self.lineWidth, self.lineHeight = 0, 0
44 self.textLineOffsetX, self.textLineOffsetY = 0, 0
45 self.textSize = 0
46 self.textOffsetY = 0
47 self.shadowOffset = 0
48
49 self:storeScaledValues()
50 self:createComponents(hudAtlasPath)
51
52 return self
53end

onChatVisibilityChange

Description
Handle chat message visibility state change
Definition
onChatVisibilityChange()
Code
82function SpeakerDisplay:onChatVisibilityChange(isChatVisible)
83 self.isChatVisible = isChatVisible
84
85 self:updateVisibility()
86end

onMapVisibilityChange

Description
Handle map visibility change. The in-game menu map needs this display to be showing speakers in regular vertical layouting mode, therefore we need to know when it is active.
Definition
onMapVisibilityChange()
Code
66function SpeakerDisplay:onMapVisibilityChange(isMapVisible)
67 self.isMenuMapVisible = isMapVisible
68 self:updateVisibility()
69end

onMenuVisibilityChange

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

setScale

Description
Set this element's UI scale.
Definition
setScale()
Code
223function SpeakerDisplay:setScale(uiScale)
224 SpeakerDisplay:superClass().setScale(self, uiScale)
225 self:storeScaledValues()
226end

storeScaledValues

Description
Store scaled positioning, size and offset values.
Definition
storeScaledValues()
Code
240function SpeakerDisplay:storeScaledValues()
241 self.mapOffsetX, self.mapOffsetY = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.SELF)
242 self.positionHorizontalX, self.positionHorizontalY = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.SELF_HORIZONTAL)
243 self.lineWidth, self.lineHeight = self:scalePixelToScreenVector(SpeakerDisplay.SIZE.LINE)
244
245 self.textLineOffsetX, self.textLineOffsetY = self:scalePixelToScreenVector(SpeakerDisplay.POSITION.NAME)
246 self.textColOffsetX, self.textColOffsetY = self.textLineOffsetX, self.textLineOffsetY
247 local selfLeftX = self:getPosition()
248 -- make sure that the text is displayed within the center 90% of the screen (PS4 technical requirement):
249 -- 0.051 -> 5% in from the left (plus safety margin), subtract display position because we are changing an offset
250 self.textLineOffsetX = math.max(0.051 - selfLeftX, self.textLineOffsetX)
251
252 self.textSize = self:scalePixelToScreenHeight(SpeakerDisplay.TEXT_SIZE.NAME)
253 self.textOffsetY = self.textSize * 0.15
254 self.shadowOffset = SpeakerDisplay.SHADOW_OFFSET_FACTOR * self.textSize
255end

update

Description
Update the display state each frame.
Definition
update()
Code
149function SpeakerDisplay:update(dt)
150 SpeakerDisplay:superClass().update(self, dt)
151
152 self:updateSpeakingState()
153 self:updateVisibility()
154
155 -- update position based on mini-map, this display must never be obstructed or obstruct anything else (PS4 requirement)
156 if not self.isMenuVisible or self.isMenuMapVisible then
157 local mapHeight = 0
158 local offsetY = (1 - self:getHeight()) * 0.5
159 if not self.isMenuMapVisible then
160 mapHeight = self.ingameMap:getHeight()
161 offsetY = mapHeight > 0 and self.mapOffsetY or 0 -- only add offset if the HUD map is visible (height > 0)
162 end
163
164 local posX = g_safeFrameOffsetX + self.mapOffsetX
165 local posY = math.max(0.051, g_safeFrameOffsetY + mapHeight + offsetY) -- always within 90% of screen
166 self:setPosition(posX, posY)
167 else
168 local posX = math.max(0.051, self.positionHorizontalX)
169 local posY = math.max(0.051, self.positionHorizontalY)
170 self:setPosition(posX, posY)
171 end
172end

updateSpeakingState

Description
Update current speaking state for all connected users.
Definition
updateSpeakingState()
Code
100function SpeakerDisplay:updateSpeakingState()
101 for _, user in pairs(self.users) do
102 local wasSpeakingLastFrame = self.userSpeaking[user:getPlatformUserId()]
103 local isSpeakingNow = meshNetworkGetNodeStatusForApp(user:getPlatformNodeId() or "", "voice") > 0
104
105 if wasSpeakingLastFrame and not isSpeakingNow then
106 for i, userId in ipairs(self.currentSpeakers) do
107 if userId == user:getNickname() then
108 table.remove(self.currentSpeakers, i)
109 break
110 end
111 end
112 elseif isSpeakingNow and not wasSpeakingLastFrame then
113 table.insert(self.currentSpeakers, user:getNickname())
114 end
115
116 self.userSpeaking[user:getPlatformUserId()] = isSpeakingNow
117 end
118end

updateVisibility

Description
Update visibility states based on active speakers.
Definition
updateVisibility()
Code
122function SpeakerDisplay:updateVisibility()
123 local useLines = not self.isMenuVisible or self.isMenuMapVisible
124 local anyVisible = false
125 for i = 1, self.maxNumPlayers do
126 local lineVisible = i <= #self.currentSpeakers
127 self.speakerLineElements[i]:setVisible(lineVisible and useLines)
128 self.speakerColumnElements[i]:setVisible(lineVisible and not useLines)
129
130 anyVisible = anyVisible or lineVisible
131 end
132
133 self:setVisible(anyVisible)
134
135 if anyVisible then
136 local color = SpeakerDisplay.COLOR.BACKGROUND
137 if self.isMenuMapVisible or self.isChatVisible then
138 color = SpeakerDisplay.COLOR.BACKGROUND_HIGH_CONTRAST
139 end
140
141 for _, lineElement in pairs(self.speakerLineElements) do
142 lineElement:setColor(unpack(color))
143 end
144 end
145end