28 | function Roller.initSpecialization() |
29 | g_configurationManager:addConfigurationType("roller", g_i18n:getText("configuration_design"), "roller", nil, nil, nil, ConfigurationUtil.SELECTOR_MULTIOPTION) |
30 | g_workAreaTypeManager:addWorkAreaType("roller", false) |
31 | |
32 | local schema = Vehicle.xmlSchema |
33 | schema:setXMLSpecializationType("Roller") |
34 | |
35 | Roller.registerRollerXMLPaths(schema, "vehicle.roller") |
36 | Roller.registerRollerXMLPaths(schema, "vehicle.roller.rollerConfigurations.rollerConfiguration(?).roller") |
37 | |
38 | ObjectChangeUtil.registerObjectChangeXMLPaths(schema, "vehicle.roller.rollerConfigurations.rollerConfiguration(?)") |
39 | |
40 | schema:setXMLSpecializationType() |
41 | end |
90 | function Roller:onLoad(savegame) |
91 | local spec = self.spec_roller |
92 | |
93 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.rollerSound", "vehicle.roller.sounds.work") --FS17 to FS19 |
94 | XMLUtil.checkDeprecatedXMLElements(self.xmlFile, "vehicle.onlyActiveWhenLowered#value", "vehicle.roller#onlyActiveWhenLowered") --FS17 to FS19 |
95 | |
96 | local rollerConfigurationId = Utils.getNoNil(self.configurations["roller"], 1) |
97 | local configKey = string.format("vehicle.roller.rollerConfigurations.rollerConfiguration(%d).roller", rollerConfigurationId - 1) |
98 | ObjectChangeUtil.updateObjectChanges(self.xmlFile, "vehicle.roller.rollerConfigurations.rollerConfiguration", rollerConfigurationId, self.components, self) |
99 | |
100 | if not self.xmlFile:hasProperty(configKey) then |
101 | configKey = "vehicle.roller" |
102 | end |
103 | |
104 | spec.directionNode = self.xmlFile:getValue(configKey .. ".directionNode#node", self.components[1].node, self.components, self.i3dMappings) |
105 | |
106 | if self.isClient then |
107 | spec.samples = {} |
108 | spec.isWorkSamplePlaying = false |
109 | spec.samples.work = g_soundManager:loadSampleFromXML(self.xmlFile, configKey .. ".sounds", "work", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self) |
110 | end |
111 | |
112 | spec.isSoilRoller = self.xmlFile:getValue(configKey .. "#isSoilRoller") |
113 | spec.isGrassRoller = self.xmlFile:getValue(configKey .. "#isGrassRoller") |
114 | if spec.isSoilRoller == nil and spec.isGrassRoller == nil then |
115 | spec.isSoilRoller = true |
116 | spec.isGrassRoller = false |
117 | else |
118 | if spec.isGrassRoller == nil then |
119 | spec.isGrassRoller = false |
120 | end |
121 | if spec.isSoilRoller == nil then |
122 | spec.isSoilRoller = false |
123 | end |
124 | end |
125 | |
126 | spec.grassFruitTypes = {FruitType.GRASS, FruitType.MEADOW} |
127 | |
128 | spec.usingAIRequirements = self.xmlFile:getValue(configKey .. "#usingAIRequirements", true) |
129 | spec.onlyActiveWhenLowered = self.xmlFile:getValue(configKey .. "#onlyActiveWhenLowered", true) |
130 | spec.startActivationTimeout = 2000 |
131 | spec.startActivationTime = 0 |
132 | spec.isWorking = false |
133 | spec.angle = 0 |
134 | |
135 | self:updateRollerAIRequirements() |
136 | |
137 | spec.dirtyFlag = self:getNextDirtyFlag() |
138 | end |
149 | function Roller:processRollerArea(workArea, dt) |
150 | local spec = self.spec_roller |
151 | |
152 | local xs,_,zs = getWorldTranslation(workArea.start) |
153 | local xw,_,zw = getWorldTranslation(workArea.width) |
154 | local xh,_,zh = getWorldTranslation(workArea.height) |
155 | |
156 | local realArea |
157 | if spec.isGrassRoller then |
158 | realArea, _ = FSDensityMapUtil.updateGrassRollerArea(xs, zs, xw, zw, xh, zh, not spec.isSoilRoller) |
159 | end |
160 | if spec.isSoilRoller then |
161 | realArea, _ = FSDensityMapUtil.updateRollerArea(xs, zs, xw, zw, xh, zh, spec.angle) |
162 | end |
163 | |
164 | FSDensityMapUtil.eraseTireTrack(xs, zs, xw, zw, xh, zh) |
165 | |
166 | spec.isWorking = self:getLastSpeed() > 0.5 |
167 | |
168 | return realArea |
169 | end |
79 | function Roller.registerEventListeners(vehicleType) |
80 | SpecializationUtil.registerEventListener(vehicleType, "onLoad", Roller) |
81 | SpecializationUtil.registerEventListener(vehicleType, "onDelete", Roller) |
82 | SpecializationUtil.registerEventListener(vehicleType, "onPostAttach", Roller) |
83 | SpecializationUtil.registerEventListener(vehicleType, "onDeactivate", Roller) |
84 | SpecializationUtil.registerEventListener(vehicleType, "onStartWorkAreaProcessing", Roller) |
85 | SpecializationUtil.registerEventListener(vehicleType, "onEndWorkAreaProcessing", Roller) |
86 | end |
69 | function Roller.registerOverwrittenFunctions(vehicleType) |
70 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "doCheckSpeedLimit", Roller.doCheckSpeedLimit) |
71 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDoGroundManipulation", Roller.getDoGroundManipulation) |
72 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getDirtMultiplier", Roller.getDirtMultiplier) |
73 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getWearMultiplier", Roller.getWearMultiplier) |
74 | SpecializationUtil.registerOverwrittenFunction(vehicleType, "getIsWorkAreaActive", Roller.getIsWorkAreaActive) |
75 | end |
45 | function Roller.registerRollerXMLPaths(schema, basePath) |
46 | schema:register(XMLValueType.NODE_INDEX, basePath .. ".directionNode#node", "Roller direction node") |
47 | schema:register(XMLValueType.BOOL, basePath .. "#onlyActiveWhenLowered", "Only active when lowered", true) |
48 | schema:register(XMLValueType.BOOL, basePath .. "#isSoilRoller", "If roller is for soil", true) |
49 | schema:register(XMLValueType.BOOL, basePath .. "#isGrassRoller", "If roller is for grassland", false) |
50 | schema:register(XMLValueType.BOOL, basePath .. "#usingAIRequirements", "Tool using roller ai requirements", true) |
51 | SoundManager.registerSampleXMLPaths(schema, basePath .. ".sounds", "work") |
52 | end |
173 | function Roller:updateRollerAIRequirements() |
174 | if self.clearAITerrainDetailRequiredRange ~= nil then |
175 | local spec = self.spec_roller |
176 | |
177 | if not spec.usingAIRequirements then |
178 | return |
179 | end |
180 | |
181 | local hasSowingMachine = false |
182 | if SpecializationUtil.hasSpecialization(SowingMachine, self.specializations) then |
183 | if self:getUseSowingMachineAIRequirements() then |
184 | hasSowingMachine = true |
185 | end |
186 | end |
187 | |
188 | self:clearAIFruitRequirements() |
189 | self:clearAIFruitProhibitions() |
190 | self:clearAITerrainDetailRequiredRange() |
191 | |
192 | -- if we also have a active sowing machine attached the sowingMachine is fully handling it |
193 | if not hasSowingMachine then |
194 | if spec.isGrassRoller and not spec.isSoilRoller then |
195 | self:addAIGroundTypeRequirements(Roller.AI_REQUIRED_GROUND_TYPES_GRASS) |
196 | |
197 | for i=1, #spec.grassFruitTypes do |
198 | local fruitTypeDesc = g_fruitTypeManager:getFruitTypeByIndex(spec.grassFruitTypes[i]) |
199 | if fruitTypeDesc.terrainDataPlaneId ~= nil then |
200 | self:addAIFruitRequirement(fruitTypeDesc.index, 2, fruitTypeDesc.cutState + 1) |
201 | end |
202 | end |
203 | end |
204 | |
205 | if spec.isSoilRoller then |
206 | self:addAIGroundTypeRequirements(Roller.AI_REQUIRED_GROUND_TYPES) |
207 | |
208 | for fruitTypeIndex, fruitType in pairs(g_fruitTypeManager:getFruitTypes()) do |
209 | if fruitType.terrainDataPlaneId ~= nil then |
210 | if not spec.isGrassRoller or fruitTypeIndex ~= FruitType.GRASS then |
211 | -- rolling only allowed in first growth state |
212 | self:addAIFruitProhibitions(fruitType.index, 2, 15) |
213 | end |
214 | end |
215 | end |
216 | |
217 | -- for combined tools we allow working on all grass states |
218 | if spec.isGrassRoller then |
219 | self:addAIGroundTypeRequirements(Roller.AI_REQUIRED_GROUND_TYPES_GRASS) |
220 | |
221 | for i=1, #spec.grassFruitTypes do |
222 | local fruitTypeDesc = g_fruitTypeManager:getFruitTypeByIndex(spec.grassFruitTypes[i]) |
223 | if fruitTypeDesc.terrainDataPlaneId ~= nil then |
224 | self:addAIFruitProhibitions(fruitTypeDesc.index, 1, 1) |
225 | end |
226 | end |
227 | end |
228 | end |
229 | end |
230 | end |
231 | end |