Skip to content

Commit 343baae

Browse files
committed
Added FillUnitExtension specialization
1 parent e2e0348 commit 343baae

3 files changed

Lines changed: 230 additions & 0 deletions

File tree

docs/FILLUNIT_EXTENSION.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# FillUnitExtension
2+
3+
## Add specialization to vehicle type
4+
5+
```xml
6+
<?xml version="1.0" encoding="utf-8" standalone="no"?>
7+
<modDesc version="...">
8+
...
9+
<vehicleTypes>
10+
<!-- Extend parent type, can be anything -->
11+
<type name="..." parent="..." className="..." filename="...">
12+
...
13+
<!-- Add entry after fillUnit specialization -->
14+
<specialization name="FS25_0_MaterialProcessor.fillUnitExtension" />
15+
</type>
16+
</vehicleTypes>
17+
...
18+
</modDesc>
19+
```
20+
21+
## FillUnit
22+
23+
```
24+
vehicle.fillUnitExtension.fillUnit(%)
25+
```
26+
27+
### Attributes
28+
| Name | Type | Required | Default | Description |
29+
|-----------|-------|----|-----------|------------------------------|
30+
| fillUnitIndex | integer | Yes | | |
31+
32+
33+
## Fill level object changes
34+
35+
```
36+
vehicle.fillUnitExtension.fillUnit(%).fillLevelObjectChanges
37+
```
38+
39+
Trigger object changes based on the fill level percentage.
40+
41+
### Attributes
42+
| Name | Type | Required | Default | Description |
43+
|-----------|-------|----|-----------|------------------------------|
44+
| threshold | float | No | ```0.9```| Defines at which fillUnit fill level percentage the object changes |
45+
46+
47+
### Example
48+
```xml
49+
<?xml version="1.0" encoding="utf-8" standalone="no"?>
50+
<vehicle>
51+
<fillUnitExtension>
52+
<fillUnit fillUnitIndex="3">
53+
<fillLevelObjectChanges threshold="0.85">
54+
<objectChange node="alarmBeacon" visibilityActive="true" visibilityInactive="false" />
55+
</fillLevelObjectChanges>
56+
</fillUnit>
57+
</fillUnitExtension>
58+
</vehicle>
59+
```
60+
61+
## Fill level sound
62+
63+
```
64+
vehicle.fillUnitExtension.fillUnit(%).fillLevelSound
65+
```
66+
67+
Play sound depending on the fill level percentage.
68+
Same as a normal vehicle sample entry, but with additional attributes.
69+
70+
### Attributes
71+
| Name | Type | Required | Default | Description |
72+
|-----------|-------|----|-----------|------------------------------|
73+
| threshold | float | No | ```0.9```| Defines at which fillUnit fill level percentage the sound is triggered |
74+
| thresholdIsGreater | boolean | No | ```true``` | If true the sound is triggered above threshold, if not then below threshold |
75+
| requiresPoweredOn | boolean | No | ```true``` | |
76+
| requiresTurnedOn | boolean | No | ```false``` | |
77+
78+
### Example
79+
```xml
80+
<?xml version="1.0" encoding="utf-8" standalone="no"?>
81+
<vehicle>
82+
<fillUnitExtension>
83+
<fillUnit fillUnitIndex="3">
84+
<fillLevelSound threshold="0.95" template="rollbeltAlarm" linkNode="alarmSoundNode" />
85+
</fillUnit>
86+
</fillUnitExtension>
87+
</vehicle>
88+
```

modDesc.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
</extraSourceFiles>
1717

1818
<specializations>
19+
<specialization name="fillUnitExtension" className="FillUnitExtension" filename="scripts/specializations/FillUnitExtension.lua" />
1920
<specialization name="materialProcessor" className="MaterialProcessor" filename="scripts/specializations/MaterialProcessor.lua" />
2021
</specializations>
2122

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
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

Comments
 (0)