Compare commits

2 Commits

8 changed files with 486 additions and 3 deletions
-3
View File
@@ -1,3 +0,0 @@
#LS25-Mod
Eigenes Ls25-Mod Projekt.
Entwickelt von Dystroyer8
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<modDesc descVersion="95">
<author>Dystroyer8</author>
<version>1.0.0.0</version>
<title>
<en>LS25 Mine</en>
<de>LS25 Mine</de>
</title>
<description>
<en>Mine production for LS25</en>
<de>Minenproduktion für LS25</de>
</description>
<extraSourceFiles>
<sourceFile filename="scripts/produktion.lua"/>
</extraSourceFiles>
<placeableSpecializations>
<specialization name="produktion" className="Produktion" filename="scripts/produktion.lua"/>
</placeableSpecializations>
<placeableTypes>
<type name="mineSilo" parent="silo" className="Placeable" filename="$dataS/scripts/placeables/Placeable.lua">
<specialization name="produktion"/>
</type>
</placeableTypes>
<storeItems>
<storeItem xmlFilename="placeables/mine/mine.xml"/>
</storeItems>
</modDesc>
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<i3D name="farmSilo" version="1.6" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://i3d.giants.ch/schema/i3d-1.6.xsd">
<Files>
<File fileId="7" filename="$data/maps/textures/shared/snow_diffuse.png" />
<File fileId="8" filename="$data/maps/textures/shared/snow_normal.png" />
<File fileId="9" filename="$data/maps/textures/shared/snow_specular.png" />
<File fileId="1" filename="$data/placeables/mapUS/farmSilo/farmSilo_diffuse.png" />
<File fileId="6" filename="$data/placeables/mapUS/farmSilo/farmSilo_height.png" />
<File fileId="5" filename="$data/placeables/mapUS/farmSilo/farmSilo_mask.png" />
<File fileId="2" filename="$data/placeables/mapUS/farmSilo/farmSilo_normal.png" />
<File fileId="3" filename="$data/placeables/mapUS/farmSilo/farmSilo_specular.png" />
<File fileId="4" filename="$data/shaders/buildingShader.xml" />
<File fileId="10" filename="$data/shaders/snowHeapShader.xml" />
<File fileId="12" filename="$data/shared/default_normal.png" />
<File fileId="11" filename="$data/shared/sparkles_normal.png" />
</Files>
<Materials>
<Material name="lambert1" materialId="1" diffuseColor="0.5 0.5 0.5 1">
</Material>
<Material name="farmSilo_mat" materialId="3" customShaderId="4" customShaderVariation="customParallax">
<CustomParameter name="dirtMossMix" value="1.0 1.0"/>
<CustomParameter name="dirtMossSmoothness" value="0.12 0.12"/>
<Custommap name="mMaskMap" fileId="5"/>
<Custommap name="mParallaxMap" fileId="6"/>
<Texture fileId="1"/>
<Normalmap fileId="2"/>
<Glossmap fileId="3"/>
</Material>
<Material name="snow_mat" materialId="4" customShaderId="10">
<Custommap name="mSparklesNormal" fileId="11"/>
<Texture fileId="7"/>
<Normalmap fileId="8" bumpDepth="0.5"/>
<Glossmap fileId="9"/>
</Material>
<Material name="lambert2" materialId="2" diffuseColor="0.5 0.5 0.5 1">
<Normalmap fileId="12"/>
</Material>
</Materials>
<Shapes externalShapesFile="mine.shapes">
</Shapes>
<Scene>
<TransformGroup name="farmSilo" nodeId="1">
<TransformGroup name="clearAreas" nodeId="2">
<TransformGroup name="clearAreaStart01" translation="-7 0 -6.5" nodeId="3">
<TransformGroup name="clearAreaWidth01" translation="0.000015 0 10.5" nodeId="4"/>
<TransformGroup name="clearAreaHeight01" translation="14 0 0" nodeId="5"/>
</TransformGroup>
</TransformGroup>
<TransformGroup name="levelAreas" nodeId="6">
<TransformGroup name="levelAreaStart01" translation="-8 0 -7.5" nodeId="7">
<TransformGroup name="levelAreaWidth01" translation="0.000015 0 12.5" nodeId="8"/>
<TransformGroup name="levelAreaHeight01" translation="16 0 0" nodeId="9"/>
</TransformGroup>
</TransformGroup>
<TransformGroup name="testAreas" nodeId="10">
<TransformGroup name="testAreaStart01" translation="-7 0 -6.5" nodeId="11">
<TransformGroup name="testAreaEnd01" translation="14 12 7" nodeId="12"/>
</TransformGroup>
<TransformGroup name="testAreaStart02" translation="-3 0 0" nodeId="13">
<TransformGroup name="testAreaEnd02" translation="6 8 7" nodeId="14"/>
</TransformGroup>
</TransformGroup>
<TransformGroup name="tipOcclusionUpdateAreas" nodeId="15">
<TransformGroup name="tipOcclusionUpdateAreaStart01" translation="-7 0 -7" nodeId="16">
<TransformGroup name="tipOcclusionUpdateAreaEnd01" translation="14 0 11" nodeId="17"/>
</TransformGroup>
</TransformGroup>
<TransformGroup name="loadingStation" translation="-0.01187 4.262771 1.365761" nodeId="18">
<TransformGroup name="loadingTriggers" translation="0 -0.215055 0" nodeId="19">
<Shape name="loadingTrigger" translation="0.002711 0.495517 0.44969" shapeId="1" static="true" trigger="true" collisionFilterGroup="0x20000000" collisionFilterMask="0x40000000" castsShadows="true" receiveShadows="true" nonRenderable="true" materialIds="1" nodeId="20"/>
<TransformGroup name="dischargeNode" nodeId="21"/>
<TransformGroup name="dischargeEffect" translation="0 -0.105872 0.450763" nodeId="22">
<Shape name="pipeEffect" translation="0 0.700242 0" rotation="90 0 0" shapeId="2" castsShadows="true" receiveShadows="true" materialIds="2" clipDistance="300" nodeId="23"/>
<Shape name="pipeEffectSmoke" translation="0 -2.567325 0" shapeId="3" castsShadows="true" receiveShadows="true" materialIds="2" clipDistance="100" nodeId="24"/>
</TransformGroup>
<TransformGroup name="aiLoadingNode" translation="0 -3.702972 0.537158" rotation="0 -90 0" nodeId="25"/>
</TransformGroup>
<TransformGroup name="markerLoading" translation="0.01187 -4.262771 0.056003" rotation="0 -90 0" nodeId="26"/>
</TransformGroup>
<TransformGroup name="unloadingStation" translation="-0.005935 0.159928 5.85394" nodeId="27">
<Shape name="exactFillRootNode" translation="0.005935 -0.184815 -4.029284" shapeId="4" kinematic="true" compound="true" collisionFilterGroup="0x40000000" collisionFilterMask="0x20000000" castsShadows="true" receiveShadows="true" nonRenderable="true" materialIds="1" nodeId="28"/>
<TransformGroup name="grainGutterLinkNode" translation="0.005935 -0.159928 -4.029284" scale="0.65 0.65 0.65" collision="false" density="0" nodeId="29"/>
<TransformGroup name="aiUnloadingNode" translation="0.005935 -0.159928 -4.029284" rotation="0 -90 0" nodeId="30"/>
<TransformGroup name="markerUnloading" translation="-1.493347 -0.159928 -4.029284" rotation="0 -90 0" nodeId="31"/>
</TransformGroup>
<TransformGroup name="mapPosition" translation="-0.178355 0 1.903775" nodeId="32"/>
<TransformGroup name="storage" nodeId="33"/>
<Shape name="infoTrigger" translation="0 0 -4.5" shapeId="5" static="true" trigger="true" collisionFilterGroup="0x20000000" collisionFilterMask="0x100000" castsShadows="true" receiveShadows="true" nonRenderable="true" materialIds="1" nodeId="34"/>
<Shape name="aiSpline" translation="0.87703 0 1.729941" shapeId="6" nodeId="35"/>
<TransformGroup name="teleportNode" translation="3.665936 0 1.657377" rotation="0 -21.6537 0" nodeId="36"/>
<TransformGroup name="visuals" nodeId="37">
<TransformGroup name="visuals_lod" translation="0 0 -3.25" lodDistance="0 100" collision="false" density="0" nodeId="38">
<Shape name="farmSilo_lod0" translation="-3.5 0 0" rotation="0 12.5 0" shapeId="7" castsShadows="true" receiveShadows="true" materialIds="3" clipDistance="300" nodeId="39">
<Shape name="pipe" rotation="0 120 0" shapeId="8" castsShadows="true" receiveShadows="true" materialIds="3" clipDistance="300" nodeId="40"/>
<Shape name="farmSilo_lod4" translation="9.997885 4 2.24553" shapeId="9" castsShadows="true" receiveShadows="true" materialIds="3" clipDistance="300" nodeId="41"/>
<Shape name="farmSilo_lod2" translation="9.997885 4.083839 2.24553" shapeId="10" castsShadows="true" receiveShadows="true" materialIds="3" clipDistance="300" nodeId="42"/>
</Shape>
<Shape name="farmSilo_lod1" translation="-3.5 0 0" rotation="0 12.5 0" shapeId="11" castsShadows="true" receiveShadows="true" materialIds="3" clipDistance="500" nodeId="43"/>
</TransformGroup>
<TransformGroup name="winter" translation="-3.5 4 -3.25" rotation="0 12.5 0" nodeId="44" weatherRequiredMask="0x400">
<Shape name="snow" shapeId="12" castsShadows="true" receiveShadows="true" materialIds="4" clipDistance="200" nodeId="45"/>
</TransformGroup>
</TransformGroup>
<TransformGroup name="collision" nodeId="46">
<Shape name="tipCollision" translation="0.000003 0 0.517693" shapeId="13" static="true" collisionFilterGroup="0x8" collisionFilterMask="0x1" castsShadows="true" receiveShadows="true" nonRenderable="true" materialIds="1" nodeId="47"/>
<Shape name="collision" translation="-3.499999 5.553098 -3.249999" rotation="0 13.523356 0" shapeId="14" static="true" collisionFilterGroup="0x1034" collisionFilterMask="0xfffffbff" castsShadows="true" receiveShadows="true" nonRenderable="true" materialIds="1" nodeId="48"/>
</TransformGroup>
<Shape name="occluderMesh" translation="-3.499999 4 -3.249999" shapeId="15" castsShadows="true" receiveShadows="true" nonRenderable="true" occluder="true" materialIds="1" clipDistance="250" nodeId="49"/>
</TransformGroup>
</Scene>
<UserAttributes>
</UserAttributes>
</i3D>
Binary file not shown.
+135
View File
@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<placeable type="mineSilo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../shared/xml/schema/placeable.xsd">
<storeData>
<name>LS25 Mine</name>
<functions>
<function>Mine produziert PAYDIRT</function>
</functions>
<image>placeables/mine/store_mine.dds</image>
<price>80000</price>
<dailyUpkeep>120</dailyUpkeep>
<lifetime>1000</lifetime>
<rotation>0</rotation>
<brand>NONE</brand>
<species>PLACEABLE</species>
<category>silos</category>
<brush>
<type>placeable</type>
<category>buildings</category>
<tab>silos</tab>
</brush>
<vertexBufferMemoryUsage>314112</vertexBufferMemoryUsage>
<indexBufferMemoryUsage>78848</indexBufferMemoryUsage>
<textureMemoryUsage>786432</textureMemoryUsage>
<instanceVertexBufferMemoryUsage>0</instanceVertexBufferMemoryUsage>
<instanceIndexBufferMemoryUsage>0</instanceIndexBufferMemoryUsage>
<audioMemoryUsage>0</audioMemoryUsage>
</storeData>
<base>
<filename>placeables/mine/mine.i3d</filename>
<canBeRenamed>true</canBeRenamed>
</base>
<placement useRandomYRotation="false" useManualYRotation="true" >
<testAreas>
<testArea startNode="testAreaStart01" endNode="testAreaEnd01" />
<testArea startNode="testAreaStart02" endNode="testAreaEnd02" />
</testAreas>
<sounds>
<place template="siloImp" />
</sounds>
</placement>
<clearAreas>
<clearArea startNode="clearAreaStart01" widthNode="clearAreaWidth01" heightNode="clearAreaHeight01"/>
</clearAreas>
<leveling requireLeveling="true" maxSmoothDistance="1" maxSlope="75" maxEdgeAngle="30">
<levelAreas>
<levelArea startNode="levelAreaStart01" widthNode="levelAreaWidth01" heightNode="levelAreaHeight01" groundType="asphalt"/>
</levelAreas>
</leveling>
<indoorAreas/>
<tipOcclusionUpdateAreas>
<tipOcclusionUpdateArea startNode="tipOcclusionUpdateAreaStart01" endNode="tipOcclusionUpdateAreaEnd01" />
</tipOcclusionUpdateAreas>
<ai>
<updateAreas>
<updateArea startNode="tipOcclusionUpdateAreaStart01" endNode="tipOcclusionUpdateAreaEnd01" />
</updateAreas>
<splines>
<spline node="aiSpline" />
</splines>
</ai>
<dynamicallyLoadedParts>
<dynamicallyLoadedPart filename="$data/placeables/shared/sellingStationGeneric/sellingStationGenericNoCover.i3d" node="0" linkNode="grainGutterLinkNode" />
</dynamicallyLoadedParts>
<infoTrigger triggerNode="infoTrigger"/>
<silo>
<loadingStation node="loadingTrigger" supportsExtension="true" storageRadius="50">
<loadTrigger triggerNode="loadingTrigger" fillLitersPerSecond="2000" dischargeNode="dischargeNode" fillTypes="PAYDIRT" aiNode="aiLoadingNode">
<effectNode effectClass="PipeEffect" effectNode="pipeEffect" materialType="pipe" fadeTime="0.5" maxBending="0" controlPoint="4.8 0 0 0" />
<effectNode effectNode="pipeEffectSmoke" materialType="unloadingSmoke" fadeTime="0.5" />
<sounds>
<loading template="silosActive" />
</sounds>
</loadTrigger>
</loadingStation>
<!-- <unloadingStation supportsExtension="true" storageRadius="50">
<unloadTrigger exactFillRootNode="exactFillRootNode" fillTypes="PAYDIRT" aiNode="aiUnloadingNode"/>
</unloadingStation> -->
<storages>
<storage node="storage" fillTypes="PAYDIRT" capacity="200000" isExtension="false"/>
</storages>
</silo>
<!--<hotspots>
<hotspot type="UNLOADING" linkNode="mapPosition" teleportNode="teleportNode"/>
</hotspots>-->
<triggerMarkers>
<triggerMarker node="markerLoading" filename="$data/shared/assets/marker/markerIconLoad.i3d" />
<!--<triggerMarker node="markerUnloading" filename="$data/shared/assets/marker/markerIconUnload.i3d" />-->
</triggerMarkers>
<i3dMappings>
<i3dMapping id="clearAreaStart01" node="0>0|0" />
<i3dMapping id="clearAreaWidth01" node="0>0|0|0" />
<i3dMapping id="clearAreaHeight01" node="0>0|0|1" />
<i3dMapping id="levelAreaStart01" node="0>1|0" />
<i3dMapping id="levelAreaWidth01" node="0>1|0|0" />
<i3dMapping id="levelAreaHeight01" node="0>1|0|1" />
<i3dMapping id="testAreaStart01" node="0>2|0" />
<i3dMapping id="testAreaEnd01" node="0>2|0|0" />
<i3dMapping id="testAreaStart02" node="0>2|1" />
<i3dMapping id="testAreaEnd02" node="0>2|1|0" />
<i3dMapping id="tipOcclusionUpdateAreaStart01" node="0>3|0" />
<i3dMapping id="tipOcclusionUpdateAreaEnd01" node="0>3|0|0" />
<i3dMapping id="loadingTrigger" node="0>4|0|0" />
<i3dMapping id="dischargeNode" node="0>4|0|1" />
<i3dMapping id="dischargeEffect" node="0>4|0|2" />
<i3dMapping id="pipeEffect" node="0>4|0|2|0" />
<i3dMapping id="pipeEffectSmoke" node="0>4|0|2|1" />
<i3dMapping id="aiLoadingNode" node="0>4|0|3" />
<i3dMapping id="markerLoading" node="0>4|1" />
<i3dMapping id="exactFillRootNode" node="0>5|0" />
<i3dMapping id="grainGutterLinkNode" node="0>5|1" />
<i3dMapping id="aiUnloadingNode" node="0>5|2" />
<i3dMapping id="markerUnloading" node="0>5|3" />
<i3dMapping id="mapPosition" node="0>6" />
<i3dMapping id="storage" node="0>7" />
<i3dMapping id="infoTrigger" node="0>8" />
<i3dMapping id="aiSpline" node="0>9" />
<i3dMapping id="teleportNode" node="0>10" />
</i3dMappings>
</placeable>
Binary file not shown.
+197
View File
@@ -0,0 +1,197 @@
-- Variablen
Produktion = {}
Produktion.debug = true
Produktion.debugPrefix = "[LS25-Mine] "
Produktion.fillType = "PAYDIRT"
Produktion.amountPerHour = 40000
Produktion.animationAcceleration = 0.25
Produktion.animationSpeedMax = 1.0
-- Registrierung
function Produktion.prerequisitesPresent(specializations)
return true
end
function Produktion.registerFunctions(placeableType)
SpecializationUtil.registerFunction(placeableType, "produce", Produktion.produce)
SpecializationUtil.registerFunction(placeableType, "updateAnimationState", Produktion.updateAnimationState)
end
function Produktion.registerEventListeners(placeableType)
SpecializationUtil.registerEventListener(placeableType, "onLoad", Produktion)
SpecializationUtil.registerEventListener(placeableType, "onUpdate", Produktion)
SpecializationUtil.registerEventListener(placeableType, "onFinalizePlacement", Produktion)
end
-- Initialisierung
function Produktion:onLoad(savegame)
self.produktionFirstUpdatePrinted = false
self.produktionAnimationSpeed = 0
self.produktionAnimationTargetSpeed = 0
self.produktionWasFull = false
self.produktionBuffer = 0
if self.raiseActive ~= nil then
self:raiseActive()
end
if Produktion.debug then
print(Produktion.debugPrefix .. "Produktion.lua wurde geladen")
end
end
function Produktion:onFinalizePlacement()
if self.raiseActive ~= nil then
self:raiseActive()
end
if Produktion.debug then
print(Produktion.debugPrefix .. "Mine platziert, Produktion aktiv")
end
end
-- Update
function Produktion:onUpdate(dt)
if self.produktionFirstUpdatePrinted ~= true then
self.produktionFirstUpdatePrinted = true
if Produktion.debug then
print(Produktion.debugPrefix .. "onUpdate läuft")
end
end
local timeScale = 1
if g_currentMission ~= nil and g_currentMission.missionInfo ~= nil and g_currentMission.missionInfo.timeScale ~= nil then
timeScale = g_currentMission.missionInfo.timeScale
end
local gameTimeHours = (dt * timeScale) / 3600000
local amountToProduce = Produktion.amountPerHour * gameTimeHours
self.produktionBuffer = self.produktionBuffer + amountToProduce
local producedAmount = 0
if self.produktionBuffer >= 1 then
producedAmount = self:produce(self.produktionBuffer)
self.produktionBuffer = self.produktionBuffer - producedAmount
if self.produktionBuffer > 1000 then
self.produktionBuffer = 1000
end
end
if producedAmount > 0 then
self:updateAnimationState(true, dt)
else
self:updateAnimationState(false, dt)
end
if self.raiseActive ~= nil then
self:raiseActive()
end
end
-- Produktion
function Produktion:produce(amount)
if self.isServer == false then
return 0
end
local spec = self.spec_silo
if spec == nil or spec.storages == nil then
if Produktion.debug then
print(Produktion.debugPrefix .. "Kein Silo-Speicher gefunden")
end
return 0
end
local fillTypeIndex = g_fillTypeManager:getFillTypeIndexByName(Produktion.fillType)
if fillTypeIndex == nil then
if Produktion.debug then
print(Produktion.debugPrefix .. "FillType nicht gefunden: " .. Produktion.fillType)
end
return 0
end
local remainingAmount = amount
local producedAmount = 0
local hasFreeCapacity = false
for _, storage in ipairs(spec.storages) do
local freeCapacity = storage:getFreeCapacity(fillTypeIndex)
if freeCapacity > 0 then
hasFreeCapacity = true
local movedAmount = math.min(remainingAmount, freeCapacity)
local oldFillLevel = storage:getFillLevel(fillTypeIndex) or 0
storage:setFillLevel(oldFillLevel + movedAmount, fillTypeIndex)
remainingAmount = remainingAmount - movedAmount
producedAmount = producedAmount + movedAmount
end
if remainingAmount <= 0.001 then
break
end
end
if Produktion.debug then
if producedAmount > 0 then
self.produktionWasFull = false
if producedAmount >= 1 then
print(Produktion.debugPrefix .. "Produziert: " .. tostring(math.floor(producedAmount)) .. " L " .. Produktion.fillType)
end
elseif hasFreeCapacity == false and self.produktionWasFull ~= true then
self.produktionWasFull = true
print(Produktion.debugPrefix .. "Speicher voll, Produktion gestoppt")
end
end
return producedAmount
end
-- Animation vorbereitet
function Produktion:updateAnimationState(isProducing, dt)
if isProducing then
self.produktionAnimationTargetSpeed = Produktion.animationSpeedMax
else
self.produktionAnimationTargetSpeed = 0
end
local step = Produktion.animationAcceleration * (dt / 1000)
if self.produktionAnimationSpeed < self.produktionAnimationTargetSpeed then
self.produktionAnimationSpeed = math.min(self.produktionAnimationSpeed + step, self.produktionAnimationTargetSpeed)
elseif self.produktionAnimationSpeed > self.produktionAnimationTargetSpeed then
self.produktionAnimationSpeed = math.max(self.produktionAnimationSpeed - step, self.produktionAnimationTargetSpeed)
end
-- Hier kommt später die echte Animation rein.
-- Beispiel später:
-- self:setAnimationTime("mineWorkAnimation", self.produktionAnimationSpeed, true)
-- oder:
-- setRotation(self.animationNode, 0, self.produktionAnimationSpeed, 0)
end
View File