809 | function SpeedMeterDisplay.createBackground(hudAtlasPath) |
810 | local width, height = getNormalizedScreenValues(unpack(SpeedMeterDisplay.SIZE.BACKGROUND)) |
811 | local posX, posY = SpeedMeterDisplay.getBackgroundPosition(1) -- scale of 1 for initialization |
812 | |
813 | -- local background = Overlay.new(hudAtlasPath, posX, posY, width, height) |
814 | -- background:setUVs(GuiUtils.getUVs(SpeedMeterDisplay.UV.SHADOW_BACKGROUND)) |
815 | -- background:setColor(unpack(SpeedMeterDisplay.COLOR.SHADOW_BACKGROUND)) |
816 | |
817 | local background = Overlay.new(nil, posX, posY, width, height) |
818 | -- background:setUVs(GuiUtils.getUVs({0,0,1024,1024})) |
819 | -- background:setColor(1,1,1,1) |
820 | |
821 | |
822 | return background |
823 | end |
116 | function SpeedMeterDisplay:createComponents(hudAtlasPath) |
117 | local baseX, baseY = self:getBasePosition() |
118 | self:storeScaledValues(baseX, baseY) |
119 | |
120 | -- create components in order of drawing: |
121 | -- self.speedGaugeSegmentElements, self.speedGaugeSegmentPartElements = self:createSpeedGaugeElements(hudAtlasPath, baseX, baseY) |
122 | |
123 | self.gaugeBackgroundElement = self:createGaugeBackground(hudAtlasPath, baseX, baseY) |
124 | |
125 | self.damageGaugeIconElement, self.fuelGaugeIconElement = self:createGaugeIconElements(hudAtlasPath, baseX, baseY) |
126 | |
127 | self.damageBarElement = self:createDamageBar(hudAtlasPath, baseX, baseY) |
128 | self.fuelBarElement = self:createFuelBar(hudAtlasPath, baseX, baseY) |
129 | self.fuelBarElementBlinkTimer = 0 |
130 | |
131 | self.gearElement = self:createGearIndicator(hudAtlasPath, baseX, baseY) |
132 | |
133 | self.speedIndicatorElement = self:createSpeedGaugeIndicator(hudAtlasPath, baseX, baseY) |
134 | |
135 | self.operatingTimeElement = self:createOperatingTimeElement(hudAtlasPath, baseX, baseY) |
136 | self.operatingTimeElement:setVisible(false) |
137 | self.cruiseControlElement = self:createCruiseControlElement(hudAtlasPath, baseX, baseY) |
138 | end |
975 | function SpeedMeterDisplay:createGaugeIconElements(hudAtlasPath, baseX, baseY) |
976 | local posX, posY = getNormalizedScreenValues(unpack(SpeedMeterDisplay.POSITION.DAMAGE_LEVEL_ICON)) |
977 | local width, height = getNormalizedScreenValues(unpack(SpeedMeterDisplay.SIZE.DAMAGE_LEVEL_ICON)) |
978 | local iconOverlay = Overlay.new(hudAtlasPath, baseX + posX, baseY + posY, width, height) |
979 | iconOverlay:setUVs(GuiUtils.getUVs(SpeedMeterDisplay.UV.DAMAGE_LEVEL_ICON)) |
980 | |
981 | local damageGaugeIconElement = HUDElement.new(iconOverlay) |
982 | self:addChild(damageGaugeIconElement) |
983 | |
984 | posX, posY = getNormalizedScreenValues(unpack(SpeedMeterDisplay.POSITION.FUEL_LEVEL_ICON)) |
985 | width, height = getNormalizedScreenValues(unpack(SpeedMeterDisplay.SIZE.FUEL_LEVEL_ICON)) |
986 | iconOverlay = Overlay.new(hudAtlasPath, baseX + posX, baseY + posY, width, height) |
987 | iconOverlay:setUVs(GuiUtils.getUVs(SpeedMeterDisplay.UV.FUEL_LEVEL_ICON)) |
988 | |
989 | local fuelGaugeIconElement = HUDElement.new(iconOverlay) |
990 | self:addChild(fuelGaugeIconElement) |
991 | |
992 | return damageGaugeIconElement, fuelGaugeIconElement |
993 | end |
1024 | function SpeedMeterDisplay:createSpeedGaugeIndicator(hudAtlasPath, baseX, baseY) |
1025 | local width, height = getNormalizedScreenValues(unpack(SpeedMeterDisplay.SIZE.GAUGE_INDICATOR_LARGE)) |
1026 | local indicatorOverlay = Overlay.new(hudAtlasPath, 0, 0, width, height) |
1027 | indicatorOverlay:setUVs(GuiUtils.getUVs(SpeedMeterDisplay.UV.GAUGE_INDICATOR_LARGE)) |
1028 | indicatorOverlay:setColor(unpack(SpeedMeterDisplay.COLOR.SPEED_GAUGE_INDICATOR)) |
1029 | |
1030 | local indicatorElement = HUDElement.new(indicatorOverlay) |
1031 | local pivotX, pivotY = self:normalizeUVPivot(SpeedMeterDisplay.PIVOT.GAUGE_INDICATOR_LARGE, SpeedMeterDisplay.SIZE.GAUGE_INDICATOR_LARGE, SpeedMeterDisplay.UV.GAUGE_INDICATOR_LARGE) |
1032 | indicatorElement:setRotationPivot(pivotX, pivotY) |
1033 | |
1034 | self:addChild(indicatorElement) |
1035 | return indicatorElement |
1036 | end |
498 | function SpeedMeterDisplay:drawGearText() |
499 | setTextAlignment(RenderText.ALIGN_CENTER) |
500 | setTextBold(true) |
501 | |
502 | local posX, posY = self.gearElement:getPosition() |
503 | posX = posX + self.gearElement:getWidth() * 0.5 |
504 | |
505 | -- If there is a gear group, draw it |
506 | renderText(posX, posY + self.gearGroupTextPositionY, self.gearTextSize, self.gearGroupText) |
507 | |
508 | -- Draw all the gear texts, always 3. Values can be empty strings though |
509 | for i = 1, 3 do |
510 | local alpha = 1 |
511 | if i == 2 then |
512 | alpha = math.abs(math.cos(self.gearWarningTime / 200)) |
513 | end |
514 | |
515 | if self.gearSelectedIndex == i and self.gearIsChanging then |
516 | local r, g, b, a = unpack(SpeedMeterDisplay.COLOR.GEAR_TEXT_CHANGE) |
517 | setTextColor(r, g, b, a * alpha) |
518 | else |
519 | local r, g, b, a = unpack(SpeedMeterDisplay.COLOR.GEAR_TEXT) |
520 | setTextColor(r, g, b, a * alpha) |
521 | end |
522 | |
523 | renderText(posX, posY + self.gearTextPositionY[i], self.gearTextSize, self.gearTexts[i]) |
524 | end |
525 | |
526 | setTextBold(false) |
527 | end |
561 | function SpeedMeterDisplay:drawSpeedText() |
562 | -- speed switches at 0.5 -> 0.5 - 1.5 = 1km/h; 1.5 - 2.5 = 2 km/h |
563 | -- gives a much more smoother display if the cruise control is set |
564 | local speedKmh = g_i18n:getSpeed(self.speedKmh) |
565 | local speed = math.floor(speedKmh) |
566 | if math.abs(speedKmh - speed) > 0.5 then |
567 | speed = speed + 1 |
568 | end |
569 | |
570 | local speedI18N = string.format("%1d", speed) |
571 | local speedUnit = utf8ToUpper(g_i18n:getSpeedMeasuringUnit()) |
572 | |
573 | local baseX, baseY = self.gaugeBackgroundElement:getPosition() |
574 | local centerPosX = baseX + self.gaugeBackgroundElement:getWidth() * 0.5 |
575 | |
576 | setTextColor(unpack(SpeedMeterDisplay.COLOR.SPEED_TEXT)) |
577 | setTextBold(false) |
578 | setTextAlignment(RenderText.ALIGN_CENTER) |
579 | |
580 | renderText(centerPosX, baseY + self.speedTextOffsetY, self.speedTextSize, speedI18N) |
581 | |
582 | setTextColor(unpack(SpeedMeterDisplay.COLOR.SPEED_UNIT)) |
583 | |
584 | renderText(centerPosX, baseY + self.speedUnitTextOffsetY, self.speedUnitTextSize, speedUnit) |
585 | |
586 | setTextVerticalAlignment(RenderText.VERTICAL_ALIGN_MIDDLE) |
587 | setTextColor(0.7, 0.7, 0.7, 0.65) |
588 | |
589 | for _, gaugeElement in pairs(self.speedGaugeElements) do |
590 | if gaugeElement.text ~= nil then |
591 | renderText(baseX + gaugeElement.textPosX, baseY + gaugeElement.textPosY, self.speedUnitTextSize, gaugeElement.text) |
592 | end |
593 | end |
594 | |
595 | if self.speedGaugeMode == SpeedMeterDisplay.GAUGE_MODE_RPM then |
596 | renderText(centerPosX - self.gaugeBackgroundElement:getWidth() * 0.25, baseY + self.rpmUnitTextOffsetY * 0.34, self.rpmUnitTextSize, self.rpmUnitText) |
597 | renderText(centerPosX + self.gaugeBackgroundElement:getWidth() * 0.25, baseY + self.rpmUnitTextOffsetY * 0.34, self.rpmUnitTextSize, "x100") |
598 | end |
599 | |
600 | setTextVerticalAlignment(RenderText.VERTICAL_ALIGN_BASELINE) |
601 | end |
389 | function SpeedMeterDisplay.getVehicleFuelLevelAndCapacity(vehicle) |
390 | local fuelType = FillType.DIESEL |
391 | local fillUnitIndex = vehicle:getConsumerFillUnitIndex(fuelType) |
392 | |
393 | if fillUnitIndex == nil then |
394 | fuelType = FillType.ELECTRICCHARGE |
395 | fillUnitIndex = vehicle:getConsumerFillUnitIndex(fuelType) |
396 | |
397 | if fillUnitIndex == nil then |
398 | fuelType = FillType.METHANE |
399 | fillUnitIndex = vehicle:getConsumerFillUnitIndex(fuelType) |
400 | end |
401 | end |
402 | |
403 | local level = vehicle:getFillUnitFillLevel(fillUnitIndex) |
404 | local capacity = vehicle:getFillUnitCapacity(fillUnitIndex) |
405 | |
406 | return level, capacity, fuelType |
407 | end |
19 | function SpeedMeterDisplay.new(hudAtlasPath) |
20 | local backgroundOverlay = SpeedMeterDisplay.createBackground(hudAtlasPath) |
21 | local self = SpeedMeterDisplay:superClass().new(backgroundOverlay, nil, SpeedMeterDisplay_mt) |
22 | |
23 | self.uiScale = 1.0 -- UI scale, only change after initialization and only using setScale() |
24 | |
25 | self.vehicle = nil -- currently controlled vehicle reference |
26 | self.isVehicleDrawSafe = false -- safety flag for drawing, must always run one update after setting a vehicle before drawing |
27 | |
28 | self.speedIndicatorElement = nil -- speed meter needle indicator element |
29 | self.speedGaugeSegmentElements = nil -- large gauge elements covering the area between two gauge notches |
30 | self.speedGaugeSegmentPartElements = nil -- small gauge elements for detailed display |
31 | self.speedIndicatorRadiusX = 0 |
32 | self.speedIndicatorRadiusY = 0 |
33 | self.speedTextOffsetY = 0 |
34 | self.speedUnitTextOffsetY = 0 |
35 | self.speedTextSize = 0 |
36 | self.speedUnitTextSize = 0 |
37 | self.speedKmh = 0 -- current vehicle velocity in km/h |
38 | |
39 | self.speedGaugeMode = g_gameSettings:getValue(GameSettings.SETTING.HUD_SPEED_GAUGE) |
40 | self.speedGaugeUseMiles = g_gameSettings:getValue(GameSettings.SETTING.USE_MILES) |
41 | self.rpmUnitTextOffsetY = 0 |
42 | self.rpmUnitTextSize = 0 |
43 | self.rpmUnitText = g_i18n:getText("unit_rpmShort") |
44 | |
45 | self.lastGaugeValue = 0 |
46 | |
47 | self.speedGaugeElements = {} |
48 | |
49 | self.damageGaugeBackgroundElement = nil |
50 | self.damageGaugeSegmentPartElements = nil |
51 | self.damageGaugeIconElement = nil |
52 | self.damageGaugeRadiusX = 0 |
53 | self.damageGaugeRadiusY = 0 |
54 | self.damageGaugeActive = false |
55 | |
56 | self.fuelGaugeBackgroundElement = nil |
57 | self.fuelIndicatorElement = nil |
58 | self.fuelGaugeSegmentPartElements = nil |
59 | self.fuelGaugeIconElement = nil |
60 | self.fuelIndicatorRadiusX = 0 |
61 | self.fuelIndicatorRadiusY = 0 |
62 | self.fuelGaugeRadiusX = 0 |
63 | self.fuelGaugeRadiusY = 0 |
64 | self.fuelGaugeActive = false |
65 | self.fuelGaugeUVsDiesel = GuiUtils.getUVs(SpeedMeterDisplay.UV.FUEL_LEVEL_ICON) |
66 | self.fuelGaugeUVsElectric = GuiUtils.getUVs(SpeedMeterDisplay.UV.FUEL_LEVEL_ICON_ELECTRIC) |
67 | self.fuelGaugeUVsMethane = GuiUtils.getUVs(SpeedMeterDisplay.UV.FUEL_LEVEL_ICON_METHANE) |
68 | |
69 | self.cruiseControlElement = nil |
70 | self.cruiseControlSpeed = 0 |
71 | self.cruiseControlColor = nil |
72 | self.cruiseControlTextOffsetX = 0 |
73 | self.cruiseControlTextOffsetY = 0 |
74 | |
75 | self.operatingTimeElement = nil |
76 | self.operatingTimeText = "" |
77 | self.operatingTimeTextSize = 1 |
78 | self.operatingTimeTextOffsetX = 0 |
79 | self.operatingTimeTextOffsetY = 0 |
80 | self.operatingTimeTextDrawPositionX = 0 |
81 | self.operatingTimeTextDrawPositionY = 0 |
82 | |
83 | self.gearTextPositionY = 0 |
84 | self.gearGroupTextPositionY = 0 |
85 | self.gearTextSize = 0 |
86 | self.gearTexts = {"A", "B", "C"} |
87 | self.gearGroupText = "" |
88 | self.gearSelectedIndex = 1 |
89 | self.gearHasGroup = false |
90 | self.gearIsChanging = false |
91 | self.gearWarningTime = 0 |
92 | |
93 | self.fadeFuelGaugeAnimation = TweenSequence.NO_SEQUENCE |
94 | self.fadeDamageGaugeAnimation = TweenSequence.NO_SEQUENCE |
95 | |
96 | self.hudAtlasPath = hudAtlasPath |
97 | self:createComponents(hudAtlasPath) |
98 | |
99 | return self |
100 | end |
755 | function SpeedMeterDisplay:onHudSpeedGaugeModeChanged() |
756 | self.speedGaugeMode = g_gameSettings:getValue(GameSettings.SETTING.HUD_SPEED_GAUGE) |
757 | |
758 | if self.vehicle ~= nil then |
759 | local motorizedSpec = self.vehicle.spec_motorized |
760 | if motorizedSpec ~= nil then |
761 | if motorizedSpec.forceSpeedHudDisplay then |
762 | self.speedGaugeMode = SpeedMeterDisplay.GAUGE_MODE_SPEED |
763 | elseif motorizedSpec.forceRpmHudDisplay then |
764 | self.speedGaugeMode = SpeedMeterDisplay.GAUGE_MODE_RPM |
765 | end |
766 | |
767 | local motor = motorizedSpec.motor |
768 | if self.speedGaugeMode == SpeedMeterDisplay.GAUGE_MODE_RPM then |
769 | self:setupSpeedGauge(self.gaugeBackgroundElement, motor:getMinRpm(), motor:getMaxRpm(), 200) |
770 | else |
771 | local scale = 1 |
772 | if self.speedGaugeUseMiles then |
773 | scale = 0.621371 |
774 | end |
775 | self:setupSpeedGauge(self.gaugeBackgroundElement, 0, motor:getMaximumForwardSpeed() * 3.6, 5, true, scale) |
776 | end |
777 | end |
778 | end |
779 | end |
674 | function SpeedMeterDisplay:setScale(uiScale) |
675 | SpeedMeterDisplay:superClass().setScale(self, uiScale, uiScale) |
676 | |
677 | self.uiScale = uiScale |
678 | |
679 | local currentVisibility = self:getVisible() |
680 | self:setVisible(true, false) |
681 | -- update anchored position based on scaled values: |
682 | local posX, posY = SpeedMeterDisplay.getBackgroundPosition(uiScale) |
683 | self:setPosition(posX, posY) |
684 | |
685 | self:storeOriginalPosition() |
686 | self:setVisible(currentVisibility, false) |
687 | |
688 | local baseX, baseY = self.gaugeBackgroundElement:getPosition() |
689 | self:storeScaledValues(baseX, baseY) |
690 | end |
143 | function SpeedMeterDisplay:setVehicle(vehicle) |
144 | local hadVehicle = self.vehicle ~= nil |
145 | self.vehicle = vehicle |
146 | |
147 | local hasVehicle = vehicle ~= nil |
148 | self.cruiseControlElement:setVisible(hasVehicle) |
149 | |
150 | local isMotorized = hasVehicle and vehicle.spec_motorized ~= nil |
151 | local needFuelGauge = true |
152 | -- enable/disable the fuel gauge based on the fuel tank capacity, i.e. if it consumes any fuel |
153 | if hasVehicle and isMotorized then |
154 | local _, capacity = SpeedMeterDisplay.getVehicleFuelLevelAndCapacity(vehicle) |
155 | needFuelGauge = capacity ~= nil |
156 | |
157 | if needFuelGauge then |
158 | local fuelType = SpeedMeterDisplay.getVehicleFuelType(vehicle) |
159 | local fuelGaugeIconUVs = self.fuelGaugeUVsDiesel |
160 | if fuelType == FillType.ELECTRICCHARGE then |
161 | fuelGaugeIconUVs = self.fuelGaugeUVsElectric |
162 | elseif fuelType == FillType.METHANE then |
163 | fuelGaugeIconUVs = self.fuelGaugeUVsMethane |
164 | end |
165 | self.fuelGaugeIconElement:setUVs(fuelGaugeIconUVs) |
166 | end |
167 | |
168 | self:onHudSpeedGaugeModeChanged() |
169 | end |
170 | |
171 | self.fuelGaugeActive = needFuelGauge |
172 | self:animateFuelGaugeToggle(needFuelGauge) |
173 | |
174 | local needDamageGauge = hasVehicle and vehicle.getDamageAmount ~= nil and vehicle:getDamageAmount() ~= nil |
175 | self.damageGaugeActive = needDamageGauge |
176 | self:animateDamageGaugeToggle(needDamageGauge) |
177 | |
178 | local hasOperatingTime = hasVehicle and vehicle.operatingTime ~= nil |
179 | self.operatingTimeElement:setVisible(hasOperatingTime) |
180 | |
181 | self.isVehicleDrawSafe = false -- use a safety flag here because setVehicle() can be called inbetween update and draw |
182 | |
183 | if hasVehicle and not hadVehicle then |
184 | g_messageCenter:subscribe(MessageType.SETTING_CHANGED[GameSettings.SETTING.HUD_SPEED_GAUGE], self.onHudSpeedGaugeModeChanged, self) |
185 | g_messageCenter:subscribe(MessageType.SETTING_CHANGED[GameSettings.SETTING.USE_MILES], self.onHudSpeedGaugeUseMilesChanged, self) |
186 | else |
187 | g_messageCenter:unsubscribeAll(self) |
188 | end |
189 | end |
696 | function SpeedMeterDisplay:storeGaugeCenterPosition(baseX, baseY) |
697 | -- local sizeRatioX = SpeedMeterDisplay.SIZE.GAUGE_BACKGROUND[1] / SpeedMeterDisplay.UV.GAUGE_BACKGROUND[3] |
698 | -- local sizeRatioY = SpeedMeterDisplay.SIZE.GAUGE_BACKGROUND[2] / SpeedMeterDisplay.UV.GAUGE_BACKGROUND[4] |
699 | -- local centerOffsetX = SpeedMeterDisplay.POSITION.GAUGE_CENTER[1] * sizeRatioX |
700 | -- local centerOffsetY = SpeedMeterDisplay.POSITION.GAUGE_CENTER[2] * sizeRatioY |
701 | -- local normOffsetX, normOffsetY = getNormalizedScreenValues(centerOffsetX, centerOffsetY) |
702 | |
703 | -- self.gaugeCenterX, self.gaugeCenterY = baseX + normOffsetX * self.uiScale, baseY + normOffsetY * self.uiScale |
704 | |
705 | local gaugeWidth, gaugeHeight = getNormalizedScreenValues(unpack(SpeedMeterDisplay.SIZE.GAUGE_BACKGROUND)) |
706 | self.gaugeCenterX, self.gaugeCenterY = baseX + gaugeWidth * 0.5 * self.uiScale, baseY + gaugeHeight * 0.5 * self.uiScale |
707 | end |
713 | function SpeedMeterDisplay:storeScaledValues(baseX, baseY) |
714 | self:storeGaugeCenterPosition(baseX, baseY) |
715 | |
716 | self.cruiseControlTextSize = self:scalePixelToScreenHeight(SpeedMeterDisplay.TEXT_SIZE.CRUISE_CONTROL) |
717 | self.cruiseControlTextOffsetX, self.cruiseControlTextOffsetY = self:scalePixelToScreenVector(SpeedMeterDisplay.POSITION.CRUISE_CONTROL_TEXT) |
718 | |
719 | self.operatingTimeTextSize = self:scalePixelToScreenHeight(SpeedMeterDisplay.TEXT_SIZE.OPERATING_TIME) |
720 | self.operatingTimeTextOffsetX, self.operatingTimeTextOffsetY = self:scalePixelToScreenVector(SpeedMeterDisplay.POSITION.OPERATING_TIME_TEXT) |
721 | |
722 | self.speedTextOffsetY = self:scalePixelToScreenHeight(SpeedMeterDisplay.POSITION.SPEED_TEXT[2]) |
723 | self.speedUnitTextOffsetY = self:scalePixelToScreenHeight(SpeedMeterDisplay.POSITION.SPEED_UNIT[2]) |
724 | self.speedTextSize = self:scalePixelToScreenHeight(SpeedMeterDisplay.TEXT_SIZE.SPEED) |
725 | self.speedUnitTextSize = self:scalePixelToScreenHeight(SpeedMeterDisplay.TEXT_SIZE.SPEED_UNIT) |
726 | |
727 | self.rpmUnitTextOffsetY = self:scalePixelToScreenHeight(SpeedMeterDisplay.POSITION.SPEED_UNIT_TEXT[2]) |
728 | self.rpmUnitTextSize = self:scalePixelToScreenHeight(SpeedMeterDisplay.TEXT_SIZE.RPM_UNIT) |
729 | |
730 | self.speedIndicatorRadiusX, self.speedIndicatorRadiusY = self:scalePixelToScreenVector(SpeedMeterDisplay.SIZE.GAUGE_INDICATOR_LARGE_RADIUS) |
731 | |
732 | self.gearTextPositionY = {} |
733 | self.gearTextPositionY[1] = self:scalePixelToScreenHeight(SpeedMeterDisplay.POSITION.GEAR_TEXT_1[2]) |
734 | self.gearTextPositionY[2] = self:scalePixelToScreenHeight(SpeedMeterDisplay.POSITION.GEAR_TEXT_2[2]) |
735 | self.gearTextPositionY[3] = self:scalePixelToScreenHeight(SpeedMeterDisplay.POSITION.GEAR_TEXT_3[2]) |
736 | self.gearGroupTextPositionY = self:scalePixelToScreenHeight(SpeedMeterDisplay.POSITION.GEAR_GROUP_TEXT[2]) |
737 | |
738 | |
739 | local circleHeight = self:scalePixelToScreenHeight(SpeedMeterDisplay.SIZE.GEAR_ICON_BG[2]) |
740 | local selectorHeight = self:scalePixelToScreenHeight(SpeedMeterDisplay.SIZE.GEAR_SELECTOR[2]) |
741 | |
742 | local _, selfY = self:getPosition() |
743 | local posY = selfY + self:scalePixelToScreenHeight(SpeedMeterDisplay.POSITION.GEAR_INDICATOR[2]) |
744 | self.gearGroupBgY = posY + self:scalePixelToScreenHeight(SpeedMeterDisplay.POSITION.GEAR_GROUP[2]) |
745 | self.gearIconBgY = posY + self:scalePixelToScreenHeight(SpeedMeterDisplay.POSITION.GEAR_ICON_BG[2]) |
746 | |
747 | local by = posY + (circleHeight - selectorHeight) / 2 |
748 | self.gearSelectorPositions = {by, by + selectorHeight, by + selectorHeight * 2} |
749 | |
750 | self.gearTextSize = self:scalePixelToScreenHeight(SpeedMeterDisplay.TEXT_SIZE.GEAR) |
751 | end |
361 | function SpeedMeterDisplay:updateDamageGauge(dt) |
362 | if not self.fadeDamageGaugeAnimation:getFinished() then |
363 | self.fadeDamageGaugeAnimation:update(dt) |
364 | end |
365 | |
366 | if self.damageGaugeActive then |
367 | local gaugeValue = 1 |
368 | |
369 | -- Show the most damage any item in the vehicle has |
370 | local vehicles = self.vehicle.rootVehicle.childVehicles |
371 | for i = 1, #vehicles do |
372 | local vehicle = vehicles[i] |
373 | if vehicle.getDamageShowOnHud ~= nil and vehicle:getDamageShowOnHud() then |
374 | gaugeValue = math.min(gaugeValue, 1 - vehicle:getDamageAmount()) |
375 | end |
376 | end |
377 | self.damageBarElement:setValue(gaugeValue, "DAMAGE") |
378 | |
379 | local neededColor = SpeedMeterDisplay.COLOR.DAMAGE_GAUGE |
380 | if gaugeValue < 0.2 then |
381 | neededColor = SpeedMeterDisplay.COLOR.DAMAGE_GAUGE_LOW |
382 | end |
383 | self.damageBarElement:setBarColor(neededColor[1], neededColor[2], neededColor[3]) |
384 | end |
385 | end |
425 | function SpeedMeterDisplay:updateFuelGauge(dt) |
426 | if not self.fadeFuelGaugeAnimation:getFinished() then |
427 | self.fadeFuelGaugeAnimation:update(dt) |
428 | end |
429 | |
430 | if self.fuelGaugeActive then |
431 | local level, capacity = SpeedMeterDisplay.getVehicleFuelLevelAndCapacity(self.vehicle) |
432 | |
433 | if capacity > 0 then |
434 | local levelPct = level / capacity |
435 | local alpha = 1 |
436 | local color = SpeedMeterDisplay.COLOR.FUEL_GAUGE |
437 | if levelPct < SpeedMeterDisplay.FUEL_LOW_PERCENTAGE then |
438 | color = SpeedMeterDisplay.COLOR.FUEL_GAUGE_LOW |
439 | self.fuelBarElementBlinkTimer = self.fuelBarElementBlinkTimer + dt |
440 | alpha = math.abs(math.cos(self.fuelBarElementBlinkTimer / 300)) |
441 | else |
442 | self.fuelBarElementBlinkTimer = 0 |
443 | end |
444 | |
445 | self.fuelBarElement:setBarColor(color[1], color[2], color[3]) |
446 | self.fuelBarElement:setBarAlpha(alpha) |
447 | self.fuelBarElement:setValue(levelPct, "FUEL") |
448 | else |
449 | self.fuelBarElement:setBarColor(SpeedMeterDisplay.COLOR.FUEL_GAUGE[1], SpeedMeterDisplay.COLOR.FUEL_GAUGE[2], SpeedMeterDisplay.COLOR.FUEL_GAUGE[3]) |
450 | self.fuelBarElement:setBarAlpha(1) |
451 | self.fuelBarElement:setValue(1) |
452 | end |
453 | end |
454 | end |
218 | function SpeedMeterDisplay:updateGearDisplay(dt) |
219 | local gearName, gearGroupName, gearsAvailable, isAutomatic, prevGearName, nextGearName, prevPrevGearName, nextNextGearName, isGearChanging, showNeutralWarning = self.vehicle:getGearInfoToDisplay() |
220 | |
221 | -- With gears (with or without group) and not automatic, set up the texts |
222 | if gearName ~= nil and not isAutomatic then |
223 | self.gearHasGroup = gearGroupName ~= nil |
224 | self.gearGroupText = gearGroupName or "" |
225 | |
226 | if nextGearName == nil and prevGearName == nil then |
227 | self.gearTexts[1] = "" |
228 | self.gearTexts[2] = gearName -- probably N |
229 | self.gearTexts[3] = "" |
230 | self.gearSelectedIndex = 2 |
231 | elseif nextGearName == nil then -- If there is no Next, this gear is the last gear |
232 | self.gearTexts[1] = prevPrevGearName or "" |
233 | self.gearTexts[2] = prevGearName |
234 | self.gearTexts[3] = gearName |
235 | self.gearSelectedIndex = 3 |
236 | elseif prevGearName == nil then -- if there is no Prev, this gear is the first gear |
237 | self.gearTexts[1] = gearName |
238 | self.gearTexts[2] = nextGearName |
239 | self.gearTexts[3] = nextNextGearName or "" |
240 | self.gearSelectedIndex = 1 |
241 | else -- Otherwise, we show it in the middle |
242 | self.gearTexts[1] = prevGearName |
243 | self.gearTexts[2] = gearName |
244 | self.gearTexts[3] = nextGearName |
245 | self.gearSelectedIndex = 2 |
246 | end |
247 | elseif gearName ~= nil and isAutomatic then |
248 | self.gearHasGroup = false |
249 | self.gearGroupText = "" |
250 | |
251 | -- Order is D N R so that when switching from D to R we move over N |
252 | self.gearTexts[1] = "R" |
253 | self.gearTexts[2] = "N" |
254 | self.gearTexts[3] = "D" |
255 | |
256 | if gearName == "N" then |
257 | self.gearSelectedIndex = 2 |
258 | elseif gearName == "D" then |
259 | self.gearSelectedIndex = 3 |
260 | elseif gearName == "R" then |
261 | self.gearSelectedIndex = 1 |
262 | end |
263 | end |
264 | |
265 | self.gearIsChanging = isGearChanging |
266 | |
267 | self:setGearGroupVisible(self.gearGroupText ~= "") |
268 | self.gearSelectorIcon:setPosition(nil, self.gearSelectorPositions[self.gearSelectedIndex]) |
269 | |
270 | if showNeutralWarning then |
271 | self.gearWarningTime = self.gearWarningTime + dt |
272 | else |
273 | self.gearWarningTime = 0 |
274 | end |
275 | end |
279 | function SpeedMeterDisplay:updateOperatingTime(dt) |
280 | if self.operatingTimeElement:getVisible() then |
281 | local minutes = self.vehicle.operatingTime / (1000 * 60) |
282 | local hours = math.floor(minutes / 60) |
283 | minutes = math.floor((minutes - hours * 60) / 6) |
284 | |
285 | self.operatingTimeText = string.format(g_i18n:getText("shop_operatingTime"), hours, minutes) |
286 | -- local textWidth = getTextWidth(self.operatingTimeTextSize, self.operatingTimeText) |
287 | -- local operatingTimeWidth = self.operatingTimeElement:getWidth() + self.operatingTimeTextOffsetX + textWidth |
288 | |
289 | local posX, posY = self.operatingTimeElement:getPosition() |
290 | -- local _, posY = self.operatingTimeElement:getPosition() |
291 | |
292 | -- posX = posX + (self:getWidth() - operatingTimeWidth) * 0.5 |
293 | |
294 | self.operatingTimeTextDrawPositionX = posX + self.operatingTimeElement:getWidth() + self.operatingTimeTextOffsetX |
295 | self.operatingTimeTextDrawPositionY = posY + self.operatingTimeTextOffsetY |
296 | |
297 | -- self.operatingTimeElement:setPosition(posX, nil) |
298 | self.operatingTimeIsSafe = true |
299 | end |
300 | end |
332 | function SpeedMeterDisplay:updateSpeedGauge(dt) |
333 | local lastSpeed = self.vehicle:getLastSpeed() |
334 | local kmh = math.max(0, lastSpeed * self.vehicle.spec_motorized.speedDisplayScale) |
335 | if kmh < 0.5 then |
336 | kmh = 0 |
337 | end |
338 | |
339 | self.speedKmh = kmh -- used again for drawing the speed text |
340 | |
341 | local gaugeValue |
342 | if self.speedGaugeMode == SpeedMeterDisplay.GAUGE_MODE_RPM then |
343 | gaugeValue = MathUtil.clamp((self.vehicle:getMotorRpmReal() - self.speedGaugeMinValue) / (self.speedGaugeMaxValue - self.speedGaugeMinValue), 0, 1) |
344 | else |
345 | local scale = 1 |
346 | if self.speedGaugeUseMiles then |
347 | scale = 0.621371 |
348 | end |
349 | |
350 | gaugeValue = MathUtil.clamp(((lastSpeed * scale) - self.speedGaugeMinValue) / (self.speedGaugeMaxValue - self.speedGaugeMinValue), 0, 1) |
351 | end |
352 | |
353 | self.lastGaugeValue = self.lastGaugeValue * 0.95 + gaugeValue * 0.05 |
354 | |
355 | local indicatorRotation = MathUtil.lerp(SpeedMeterDisplay.ANGLE.SPEED_GAUGE_MIN, SpeedMeterDisplay.ANGLE.SPEED_GAUGE_MAX, self.lastGaugeValue) |
356 | self:updateGaugeIndicator(self.speedIndicatorElement, self.speedIndicatorRadiusX, self.speedIndicatorRadiusY, indicatorRotation) |
357 | end |