|
| 1 | +---@class FillUnitEntry |
| 2 | +---@field fillUnitIndex number |
| 3 | +---@field soundThreshold number |
| 4 | +---@field soundThresholdIsGreater boolean |
| 5 | +---@field soundRequiresTurnedOn boolean |
| 6 | +---@field soundRequiresPoweredOn boolean |
| 7 | +---@field sample? table |
| 8 | +---@field fillLevelObjectChangeThreshold number |
| 9 | +---@field fillLevelObjectChanges? table |
| 10 | + |
| 11 | +---@class FillUnitExtension_spec |
| 12 | +---@field fillUnitEntries FillUnitEntry[] |
| 13 | + |
| 14 | +---@class FillUnitExtension : VehicleObject |
| 15 | +FillUnitExtension = {} |
| 16 | + |
| 17 | +---@type string |
| 18 | +FillUnitExtension.SPEC_NAME = 'spec_' .. g_currentModName .. '.fillUnitExtension' |
| 19 | +FillUnitExtension.MOD_NAME = g_currentModName |
| 20 | + |
| 21 | +function FillUnitExtension.prerequisitesPresent(specializations) |
| 22 | + return SpecializationUtil.hasSpecialization(FillUnit, specializations) |
| 23 | +end |
| 24 | + |
| 25 | +function FillUnitExtension.initSpecialization() |
| 26 | + ---@type XMLSchema |
| 27 | + local schema = Vehicle.xmlSchema |
| 28 | + local basePath = 'vehicle.fillUnitExtension.fillUnit(?)' |
| 29 | + schema:setXMLSpecializationType('FillUnitExtension') |
| 30 | + |
| 31 | + schema:register(XMLValueType.INT, basePath .. '#fillUnitIndex') |
| 32 | + |
| 33 | + SoundManager.registerSampleXMLPaths(schema, basePath, "fillLevelSound") |
| 34 | + schema:register(XMLValueType.BOOL, basePath .. '.fillLevelSound#requiresTurnedOn', '', false) |
| 35 | + schema:register(XMLValueType.BOOL, basePath .. '.fillLevelSound#requiresPoweredOn', '', true) |
| 36 | + schema:register(XMLValueType.FLOAT, basePath .. '.fillLevelSound#threshold', '', 0.9) |
| 37 | + schema:register(XMLValueType.BOOL, basePath .. '.fillLevelSound#thresholdIsGreater', '', true) |
| 38 | + |
| 39 | + schema:register(XMLValueType.FLOAT, basePath .. '.fillLevelObjectChanges#threshold', 'Defines at which fillUnit fill level percentage the object changes', 0.9) |
| 40 | + ObjectChangeUtil.registerObjectChangeXMLPaths(schema, basePath .. ".fillLevelObjectChanges") |
| 41 | + |
| 42 | + schema:setXMLSpecializationType() |
| 43 | +end |
| 44 | + |
| 45 | +function FillUnitExtension.registerEventListeners(vehicleType) |
| 46 | + SpecializationUtil.registerEventListener(vehicleType, 'onLoad', FillUnitExtension) |
| 47 | + SpecializationUtil.registerEventListener(vehicleType, 'onDelete', FillUnitExtension) |
| 48 | + SpecializationUtil.registerEventListener(vehicleType, 'onUpdateTick', FillUnitExtension) |
| 49 | +end |
| 50 | + |
| 51 | +function FillUnitExtension:onLoad() |
| 52 | + ---@type FillUnitExtension_spec |
| 53 | + local spec = self[FillUnitExtension.SPEC_NAME] |
| 54 | + |
| 55 | + spec.fillUnitEntries = {} |
| 56 | + |
| 57 | + ---@type XMLFile |
| 58 | + local xmlFile = self.xmlFile |
| 59 | + |
| 60 | + xmlFile:iterate('vehicle.fillUnitExtension.fillUnit', function (_, key) |
| 61 | + local entry = {} |
| 62 | + ---@cast entry FillUnitEntry |
| 63 | + |
| 64 | + entry.fillUnitIndex = xmlFile:getValue(key .. '#fillUnitIndex') |
| 65 | + |
| 66 | + if not self:getFillUnitExists(entry.fillUnitIndex) then |
| 67 | + Logging.xmlError(xmlFile, 'Invalid fillUnitIndex (%s)', key .. '#fillUnitIndex') |
| 68 | + return |
| 69 | + end |
| 70 | + |
| 71 | + entry.soundRequiresPoweredOn = xmlFile:getValue(key .. '.fillLevelSound#requiresPoweredOn', true) |
| 72 | + entry.soundRequiresTurnedOn = xmlFile:getValue(key .. '.fillLevelSound#requiresTurnedOn', false) |
| 73 | + entry.soundThreshold = xmlFile:getValue(key .. '.fillLevelSound#threshold', 0.9) |
| 74 | + entry.soundThresholdIsGreater = xmlFile:getValue(key .. '.fillLevelSound#thresholdIsGreater', true) |
| 75 | + entry.sample = g_soundManager:loadSampleFromXML(xmlFile, key, "fillLevelSound", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
| 76 | + |
| 77 | + entry.fillLevelObjectChanges = {} |
| 78 | + ObjectChangeUtil.loadObjectChangeFromXML(xmlFile, key .. '.fillLevelObjectChanges', entry.fillLevelObjectChanges, self.components, self) |
| 79 | + |
| 80 | + if #entry.fillLevelObjectChanges == 0 then |
| 81 | + entry.fillLevelObjectChanges = nil |
| 82 | + else |
| 83 | + entry.fillLevelObjectChangeThreshold = xmlFile:getValue(key .. '.fillLevelObjectChanges#threshold', 0.9) |
| 84 | + ObjectChangeUtil.setObjectChanges(entry.fillLevelObjectChanges, false, self, self.setMovingToolDirty) |
| 85 | + end |
| 86 | + |
| 87 | + table.insert(spec.fillUnitEntries, entry) |
| 88 | + end) |
| 89 | +end |
| 90 | + |
| 91 | +function FillUnitExtension:onDelete() |
| 92 | + ---@type FillUnitExtension_spec |
| 93 | + local spec = self[FillUnitExtension.SPEC_NAME] |
| 94 | + |
| 95 | + for _, entry in ipairs(spec.fillUnitEntries) do |
| 96 | + g_soundManager:deleteSample(entry.sample) |
| 97 | + end |
| 98 | +end |
| 99 | + |
| 100 | +function FillUnitExtension:onUpdateTick(dt) |
| 101 | + ---@type FillUnitExtension_spec |
| 102 | + local spec = self[FillUnitExtension.SPEC_NAME] |
| 103 | + |
| 104 | + for _, entry in ipairs(spec.fillUnitEntries) do |
| 105 | + if entry.fillLevelObjectChanges ~= nil then |
| 106 | + local fillLevelPct = self:getFillUnitFillLevelPercentage(entry.fillUnitIndex) or 0 |
| 107 | + ObjectChangeUtil.setObjectChanges(entry.fillLevelObjectChanges, fillLevelPct > entry.fillLevelObjectChangeThreshold, self, self.setMovingToolDirty) |
| 108 | + end |
| 109 | + |
| 110 | + FillUnitExtension.updateFillLevelSound(self, entry) |
| 111 | + |
| 112 | + if self.isClient then |
| 113 | + if entry.sample ~= nil and g_soundManager:getIsSamplePlaying(entry.sample) then |
| 114 | + self:raiseActive() |
| 115 | + end |
| 116 | + end |
| 117 | + end |
| 118 | +end |
| 119 | + |
| 120 | +---@param entry FillUnitEntry |
| 121 | +function FillUnitExtension:updateFillLevelSound(entry) |
| 122 | + if not self.isClient or not entry.sample then |
| 123 | + return |
| 124 | + end |
| 125 | + |
| 126 | + local fillLevelPct = self:getFillUnitFillLevelPercentage(entry.fillUnitIndex) or 0 |
| 127 | + local playSample = (entry.soundThresholdIsGreater and fillLevelPct > entry.soundThreshold) or (not entry.soundThresholdIsGreater and fillLevelPct < entry.soundThreshold) |
| 128 | + local isPlaying = g_soundManager:getIsSamplePlaying(entry.sample) |
| 129 | + |
| 130 | + if entry.soundRequiresTurnedOn and self.getIsTurnedOn ~= nil and not self:getIsTurnedOn() then |
| 131 | + playSample = false |
| 132 | + elseif entry.soundRequiresPoweredOn and not self:getIsPowered() then |
| 133 | + playSample = false |
| 134 | + end |
| 135 | + |
| 136 | + if playSample and not isPlaying then |
| 137 | + g_soundManager:playSample(entry.sample) |
| 138 | + elseif not playSample and isPlaying then |
| 139 | + g_soundManager:stopSample(entry.sample) |
| 140 | + end |
| 141 | +end |
0 commit comments