Plazierbares Fahrsilo

XPModder
Posts: 53
Joined: Thu Oct 30, 2014 2:45 pm

Plazierbares Fahrsilo

Post by XPModder »

Hallo,
Ich bin dabei ein Platzierbares Fahrsilo zu machen und bin auf ein Problem gestoßen.

Erstmal Infos zum Mod selbst:
Es soll fürs erste mal ein einfaches platzierbares Objekt ohne irgendeine Funktion werden. Ich habe ein Modell erstellt und die *.i3d exportiert. Es gibt auch keine Probleme bei der *.i3d oder der Textur. Das einzige was Probleme macht ist die Fahrsilo.xml. Genauer gesagt der clearAreas abschnitt. Laut log: Index out of Bounds. Und dann bekomme ich für jeden Index einen Lua call Stack.

Hier erstmal die Fahrsilo.xml:

Code: Select all

<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<placeable>
    <storeData>
        <name>Fahrsilo</name>
        <image>StoreIcon.dds</image>
        <price>7500</price>
        <dailyUpkeep>100</dailyUpkeep>
        <lifetime>1000</lifetime>
        <rotation>0</rotation>
        <brand>XPM</brand>
        <species>placeable</species>
        <category>placeables</category>
    </storeData>

    <placeableType>placeable</placeableType>
    <filename>Fahrsilo.i3d</filename>
    <placement testSizeX="50" testSizeZ="50" sizeX="50" sizeZ="50" useRandomYRotation="false" useManualYRotation="true" />
	
	<clearAreas>
        <clearArea startIndex="0>1|0" widthIndex="0>1|1" heightIndex="0>1|2"/>
    </clearAreas>

</placeable>
Und hier der Inhalt der log datei:

Code: Select all

GIANTS Engine Runtime 7.0.0 (13569) 64bit (Build Date: Oct 18 2016)
Copyright (c) 2008-2016, GIANTS Software GmbH (giants-software.com), All Rights Reserved.
Copyright (c) 2003-2016, Christian Ammann and Stefan Geiger, All Rights Reserved.
Application: FarmingSimulator2017
Main System
  CPU: AMD FX(tm)-8350 Eight-Core Processor           
  Memory: 16348 MB
  OS: Windows NT 10.0 64-bit
Physics System
  Version: 5.9.5
  Thread(s): 2
Input System
  Keyboard enabled
  Mouse enabled
  Gamepad/Joystick enabled
  Force Feedback disabled
Audio System
  Driver: OpenAL
  Version: 1.1
  Device: Generic Software
Render System
  Driver: Direct 3D 11
  Card Vendor: NVIDIA Corporation
  Renderer: NVIDIA GeForce GTX 970
  Revision: 161
  Feature level: DirectX 11 ON
Info: Effective window resolution 1920 x 1080
Started 4 threads for threadpool 'Render threadpool'
Hardware Profile
  Level: Very High (forced)
  View Distance Factor: 1.300000
  Shadow Quality: 2.000000 Size: 4096 Filter-Size: 16
  Shader Quality: 3
  Skip Mipmaps: 0
  LOD Distance Factor: 1.300000
  Terrain LOD Distance Factor: 2.000000
  Terrain Normal Mapping: Yes
  Foliage View Distance Factor: 1.600000
  Foliage Density: 0.500000
  Volume Mesh Tessellation Factor: 0.750000
  Tyre Tracks Segments Factor: 4.000000
  Max. Number of Shadow Lights: 5
  Max. Number of Lights: 512
  Max. Number of Lights Per Cluster: 32
  MSAA: 4
Farming Simulator 17
  Version: 1.2.0.0 1.2RC6
  Available Languages: en de jp pl cz fr es ru it pt hu nl cs ct br tr ro kr
  Language: de
  Time: 2016-11-06 13:20:15
  Register configuration 'inputAttacherJoint'
  Register configuration 'attacherJoint'
  Register configuration 'frontloader'
  Register configuration 'motor'
  Register configuration 'baseColor'
  Register configuration 'wheel'
  Register configuration 'rimColor'
  Register configuration 'design'
  Register configuration 'designColor'
  Register configuration 'vehicleType'
Game vehicle types loaded
Load mod: Fahrsilo
Load mod: Inactive
Error: Failed to open xml file 'D:/Users/Florian Sluiter/Documents/My Games/FarmingSimulator2017/mods/Inactive/modDesc.xml'.
Error: Missing descVersion attribute in mod Inactive
dataS/cameraPath01.i3d (0.13) ms
dataS/cameraPath02.i3d (0.12) ms
dataS/cameraPath03.i3d (0.08) ms
data/sky/sky_day_night.i3d (14.51) ms
data/sky/rain.i3d (3.18) ms
data/sky/hail.i3d (2.38) ms
data/sky/dust.i3d (1.84) ms
data/maps/map02.i3d (2495.21) ms
Disabled withering
data/vehicles/steerable/caseIH/caseIH1660.i3d (115.97) ms
data/vehicles/cutters/caseIH/caseIH1030Cutter.i3d (64.06) ms
data/vehicles/steerable/zetor/zetorProximaPower.i3d (79.07) ms
data/vehicles/trailers/metaltech/db8000.i3d (56.17) ms
data/vehicles/steerable/zetor/zetorForterraHD.i3d (65.97) ms
data/vehicles/tools/kverneland/kvernelandQualidisc3m.i3d (37.40) ms
data/vehicles/tools/kverneland/kvernelandAccordDL.i3d (39.15) ms
D:/Users/Florian Sluiter/Documents/My Games/FarmingSimulator2017/mods/Fahrsilo/Fahrsilo.i3d (250.13) ms
Error: index out of range
LUA call stack:
  =dataS/scripts/utils/Utils.lua (0) : printCallstack
  =dataS/scripts/utils/Utils.lua (0) : checkChildIndex
  =dataS/scripts/placeables/Placeable.lua (0) : indexToObject
  =dataS/scripts/placeables/Placeable.lua (0) : loadClearAreaFromXML
  =dataS/scripts/placeables/Placeable.lua (0) : load
  =dataS/scripts/missions/mission00.lua (0) : loadFromAttributesAndNodes
  =dataS/scripts/missions/mission00.lua (0) : loadVehiclesFinish
  =dataS/scripts/BaseMission.lua (0)
  =dataS/scripts/vehicles/Vehicle.lua (0)
  =dataS/scripts/utils/Utils.lua (0)
Index: 0>1|0
Error: index out of range
LUA call stack:
  =dataS/scripts/utils/Utils.lua (0) : printCallstack
  =dataS/scripts/utils/Utils.lua (0) : checkChildIndex
  =dataS/scripts/placeables/Placeable.lua (0) : indexToObject
  =dataS/scripts/placeables/Placeable.lua (0) : loadClearAreaFromXML
  =dataS/scripts/placeables/Placeable.lua (0) : load
  =dataS/scripts/missions/mission00.lua (0) : loadFromAttributesAndNodes
  =dataS/scripts/missions/mission00.lua (0) : loadVehiclesFinish
  =dataS/scripts/BaseMission.lua (0)
  =dataS/scripts/vehicles/Vehicle.lua (0)
  =dataS/scripts/utils/Utils.lua (0)
Index: 0>1|1
Error: index out of range
LUA call stack:
  =dataS/scripts/utils/Utils.lua (0) : printCallstack
  =dataS/scripts/utils/Utils.lua (0) : checkChildIndex
  =dataS/scripts/placeables/Placeable.lua (0) : indexToObject
  =dataS/scripts/placeables/Placeable.lua (0) : loadClearAreaFromXML
  =dataS/scripts/placeables/Placeable.lua (0) : load
  =dataS/scripts/missions/mission00.lua (0) : loadFromAttributesAndNodes
  =dataS/scripts/missions/mission00.lua (0) : loadVehiclesFinish
  =dataS/scripts/BaseMission.lua (0)
  =dataS/scripts/vehicles/Vehicle.lua (0)
  =dataS/scripts/utils/Utils.lua (0)
Index: 0>1|2
dataS2/character/player/player02.i3d (448.86) ms
Physics System
  Version: 5.9.5
  Thread(s): 2
Input System
  Keyboard enabled
  Mouse enabled
  Gamepad/Joystick enabled
  Force Feedback disabled
Audio System
  Driver: OpenAL
  Version: 1.1
  Device: Generic Software
Render System
  Driver: Direct 3D 11
  Card Vendor: NVIDIA Corporation
  Renderer: NVIDIA GeForce GTX 970
  Revision: 161
  Feature level: DirectX 11 ON
Info: Effective window resolution 1920 x 1080
Started 4 threads for threadpool 'Render threadpool'
Hardware Profile
  Level: Very High (forced)
  View Distance Factor: 1.300000
  Shadow Quality: 2.000000 Size: 4096 Filter-Size: 16
  Shader Quality: 3
  Skip Mipmaps: 0
  LOD Distance Factor: 1.300000
  Terrain LOD Distance Factor: 2.000000
  Terrain Normal Mapping: Yes
  Foliage View Distance Factor: 1.600000
  Foliage Density: 0.500000
  Volume Mesh Tessellation Factor: 0.750000
  Tyre Tracks Segments Factor: 4.000000
  Max. Number of Shadow Lights: 5
  Max. Number of Lights: 512
  Max. Number of Lights Per Cluster: 32
  MSAA: 4
Farming Simulator 17
  Version: 1.2.0.0 1.2RC6
  Available Languages: en de jp pl cz fr es ru it pt hu nl cs ct br tr ro kr
  Language: de
  Time: 2016-11-06 13:21:33
  Register configuration 'inputAttacherJoint'
  Register configuration 'attacherJoint'
  Register configuration 'frontloader'
  Register configuration 'motor'
  Register configuration 'baseColor'
  Register configuration 'wheel'
  Register configuration 'rimColor'
  Register configuration 'design'
  Register configuration 'designColor'
  Register configuration 'vehicleType'
Game vehicle types loaded
Load mod: Fahrsilo
Load mod: Inactive
Error: Failed to open xml file 'D:/Users/Florian Sluiter/Documents/My Games/FarmingSimulator2017/mods/Inactive/modDesc.xml'.
Error: Missing descVersion attribute in mod Inactive
Was den Ordner Inactive betrifft, so habe ich diesen erstellt da Ich noch andere Mods nutze und diese für die Tests deaktivieren wollte. Es handelt sich also einfach nur um einen Ordner mit anderen Mods drin, daher gibt es auch keine modDesk.xml.

Ich hoffe jemand hier kann mir helfen, da ich keine Ahnung habe was diese Fehler verursacht. Ich habe mir vergleichsweise die Xml-Dateien der plazierbaren Objekte die Teil vom LS sind angesehen und dort sind die gleichen Indizes verwendet.
Das Universum ist unvorstellbar groß und wir sind im Vergleich dazu winzig.

Daher kann mir jemand der unter uns Winzlingen Unterschiede in Hautfarbe oder Herkunft sucht, nur Leid tun, weil seine Sichtweise so begrenzt ist!

Fremdenfeindlichkeit ist Menschenfeindlichkeit!
User avatar
modelleicher
Posts: 1575
Joined: Fri Jul 09, 2010 11:10 pm
Location: Hessen
Contact:

Re: Plazierbares Fahrsilo

Post by modelleicher »

Index out of Range heißt du hast nen Index in der XML angegeben der in der i3d nicht existiert.. Also schauen ob es 0>1|0, 0>1|1 und 0>1|2 wirklich gibt..


LG
Eine Stunde oder Minute ist nur ein winziger Teil unseres gesamten Lebens. Und dennoch sind es die einzelnen Momente, die das Leben lebenswert machen.
XPModder
Posts: 53
Joined: Thu Oct 30, 2014 2:45 pm

Re: Plazierbares Fahrsilo

Post by XPModder »

Danke für die Antwort. Ich konnte das Problem beheben.

Ich versuche jetzt eine zweite Version der Fahrsilos zu erstellen, die man tatsächlich benutzen kann. Dafür habe ich die Transform Groups der BGA-Silos von der original Map exportiert und in mein Modell eingefügt. Ich habe die Trigger angepasst und auch die Transform Groups der bunkerSiloArea an die korrekten Positionen gesetzt. Dann habe ich in der *.i3d den FillTypes und fermentedFillTypes alle Fruchtsorten hinzugefügt, sodass sich die Silos auch als Lager eignen sollten.
Leider sind zwar die Trigger auch Ingame an der richtigen Stelle (mit F5 überprüft) doch sie funktionieren nicht. Ich kann nichts Abkippen und bekomme auch nicht die Füllstandsanzeige. Müssen dafür die Transform Groups der bunkerSiloArea auf der Bodenhöhe des Objekts sein oder brauche ich vielleicht ein Skript damit die Fahrsilos funktionieren? Sollte ich ein Skript brauchen, wo kann ich diese finden? Ich habe im Installationsordner vom LS bisher nur Shader aber keine Skripte gefunden...
Das Universum ist unvorstellbar groß und wir sind im Vergleich dazu winzig.

Daher kann mir jemand der unter uns Winzlingen Unterschiede in Hautfarbe oder Herkunft sucht, nur Leid tun, weil seine Sichtweise so begrenzt ist!

Fremdenfeindlichkeit ist Menschenfeindlichkeit!
agp8x
Posts: 589
Joined: Mon Sep 01, 2008 2:25 pm

Re: Plazierbares Fahrsilo

Post by agp8x »

Du wirst ein Skript brauchen, dass eine neue Instanz der Klasse für das Silo anlegt und im Spiel registriert
XPModder
Posts: 53
Joined: Thu Oct 30, 2014 2:45 pm

Re: Plazierbares Fahrsilo

Post by XPModder »

Ok. Also ein Skript.

Mit Skripten für LS hab ich gar keine Erfahrung.. :confusednew: Gibts da irgendwo Beispiele für oder könnte mir da jemand helfen?
Das Universum ist unvorstellbar groß und wir sind im Vergleich dazu winzig.

Daher kann mir jemand der unter uns Winzlingen Unterschiede in Hautfarbe oder Herkunft sucht, nur Leid tun, weil seine Sichtweise so begrenzt ist!

Fremdenfeindlichkeit ist Menschenfeindlichkeit!
User avatar
modelleicher
Posts: 1575
Joined: Fri Jul 09, 2010 11:10 pm
Location: Hessen
Contact:

Re: Plazierbares Fahrsilo

Post by modelleicher »

Das Script für die platzierbaren Fertilizer Trigger wäre ein gutes Vorbild, selbes Prinzip nur dass es dort um den FillTrigger geht während es beim Fahrsilo um das BunkerSilo geht
https://gdn.giants-software.com/documen ... class=1487


LG
Eine Stunde oder Minute ist nur ein winziger Teil unseres gesamten Lebens. Und dennoch sind es die einzelnen Momente, die das Leben lebenswert machen.
XPModder
Posts: 53
Joined: Thu Oct 30, 2014 2:45 pm

Re: Plazierbares Fahrsilo

Post by XPModder »

Danke. Das hat mir schonmal weitergeholfen, aber jetzt läuft der Code von der GDN-Seite nicht richtig.
Bekomme immer den Fehler, das GetUserAttribute() einen falschen Wert bekommt. Dieser Fehler bezieht sich auf diese Zeile:

Code: Select all

 local areaNode = Utils.indexToObject(nodeId, getUserAttribute(nodeId, "bunkerSiloArea"));
Das ist die Code-Zeile Nr.196 auf https://gdn.giants-software.com/documen ... class=1487

Woher kommt jetzt der Fehler?
Und viel wichtiger: Wie kann ich ihn beheben?

Danke nochmal für die bisherige Hilfe!!!

LG
Das Universum ist unvorstellbar groß und wir sind im Vergleich dazu winzig.

Daher kann mir jemand der unter uns Winzlingen Unterschiede in Hautfarbe oder Herkunft sucht, nur Leid tun, weil seine Sichtweise so begrenzt ist!

Fremdenfeindlichkeit ist Menschenfeindlichkeit!
agp8x
Posts: 589
Joined: Mon Sep 01, 2008 2:25 pm

Re: Plazierbares Fahrsilo

Post by agp8x »

Code: Select all

getUserAttribute(nodeId, "bunkerSiloArea")
Die I3D-Node braucht ein UserAttribute "bunkerSiloArea".

Code: Select all

 local areaNode = Utils.indexToObject(nodeId, getUserAttribute(nodeId, "bunkerSiloArea"));
Da drin sollte ein Index zur areaNode enthalten sein (ein Kind von der aktuellen Node)
derelky
Posts: 560
Joined: Tue Oct 19, 2010 6:24 pm

Re: Plazierbares Fahrsilo

Post by derelky »

Das Problem wird aber sein dass der Filltrigger nunmal ein Trigger ist.


Ich habe mir gestern einfach das Fahrsilo plazierbar gemacht. bin dann aber auf folgendes Problem gestoßen.

Das Fahrsilo (Bunkersilo) ist ein Object was beim Mapladen geladen wird.
Ein "nachladen" über ein plazierbares Object ist mit dem Standard Script so nicht vorgesehen und es müsste mehr Script arbeit vorgenommen werden als bei den plazierbaren Filltriggern.

Ich habe es wieder gelöscht vielleicht geht es ja doch einfacher aber ich vermute ehr nicht.
XPModder
Posts: 53
Joined: Thu Oct 30, 2014 2:45 pm

Re: Plazierbares Fahrsilo

Post by XPModder »

Danke für die Antworten.

Das User Attribute "bunkerSiloArea" existiert und der Indexpfad ist auch korrekt aber aus irgendeinem Grund bekomme ich immer noch diesen Fehler:

Code: Select all

Warning (LUA): 'getUserAttribute': Argument 1 has wrong type. Expected: Int. Actual: String 
  ..\..\..\src\base\scripting\lua\LuaScriptSystem.cpp (557): expectedType == Value::VoidType || expectedType == Value::StringType || expectedType == Value::ByteArrayType
LUA call stack:
  =D:/Users/Florian Sluiter/Documents/My Games/FarmingSimulator2017/mods/Fahrsilo3/BunkerSilo.lua (141) : getUserAttribute
  =dataS/scripts/gui/PlacementScreen.lua (0) : load
  =dataS/scripts/gui/PlacementScreen.lua (0) : loadPlaceable
  =dataS/scripts/gui/elements/GuiElement.lua (0) : raiseCallback
  =dataS/scripts/gui/elements/Gui.lua (0) : onOpen
  =dataS/scripts/gui/ShopScreen.lua (0) : showGui
  =dataS/scripts/gui/ShopScreen.lua (0) : startPlacementMode
  =dataS/scripts/gui/ShopScreen.lua (0) : onBuy
  =dataS/scripts/gui/elements/ButtonElement.lua (0) : raiseCallback
  =dataS/scripts/gui/elements/GuiElement.lua (0) : mouseEvent
  =dataS/scripts/gui/elements/GuiElement.lua (0) : mouseEvent
  =dataS/scripts/gui/elements/GuiElement.lua (0) : mouseEvent
  =dataS/scripts/gui/elements/GuiElement.lua (0) : mouseEvent
  =dataS/scripts/gui/elements/Gui.lua (0) : mouseEvent
  =dataS/scripts/main.lua (0) : mouseEvent
Warning: BunkerSilo, could not resolve attribute 'bunkerSiloArea' into a valid node!
Error: Failed to load placeable 'D:/Users/Florian Sluiter/Documents/My Games/FarmingSimulator2017/mods/Fahrsilo3/Fahrsilo.xml'
Error: Running LUA method 'mouseEvent'.
dataS/scripts/placeables/Placeable.lua:0: bad argument #1 to 'pairs' (table expected, got nil)
Soweit ich das erkennen kann wird er Call Stack durch den Fehler beim 'getUserAttribute' verursacht. Was ich nicht verstehe ist folgendes: Warum erwartet 'getUserAttribute' einen Integer als Rückgabewert? Ich wüsste jedenfalls nicht wie ich den Indexpfad als Integer angeben soll....

Falls es irgendwie weiterhilft hier mal der Inhalt der i3d:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1"?>

<i3D name="Fahrsilo" version="1.6" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://i3d.giants.ch/schema/i3d-1.6.xsd">
  <Asset>
    <Export program="GIANTS Editor 64bit" version="7.0.2"/>
  </Asset>

  <Files>
    <File fileId="1" filename="Fahrsilo UV.dds" relativePath="true"/>
  </Files>


  <Materials>
    <Material name="lambert1" materialId="7" diffuseColor="0.494118 0.494118 0.494118 1" ambientColor="1 1 1">
    </Material>
    <Material name="lambert2" materialId="6" ambientColor="1 1 1">
      <Texture fileId="1"/>
    </Material>
  </Materials>


  <Shapes externalShapesFile="Fahrsilo.i3d.shapes">
  </Shapes>


  <Dynamics>
  </Dynamics>

  <Scene>
    <TransformGroup name="Fahrsilo" nodeId="11">
      <Shape shapeId="1" name="polySurface4" static="true" nodeId="12" materialIds="6" castsShadows="true" receiveShadows="true">
        <TransformGroup name="clearArea" nodeId="13">
          <TransformGroup name="start" translation="-18 0 35" nodeId="14"/>
          <TransformGroup name="width" translation="-18 0 -35" nodeId="15"/>
          <TransformGroup name="height" translation="55 0 35" nodeId="16"/>
        </TransformGroup>
      </Shape>
      <TransformGroup name="silo001" clipDistance="800" objectMask="65534" nodeId="17">
        <TransformGroup name="gameplay" clipDistance="400" nodeId="18">
          <Shape shapeId="2" name="interactionTrigger" static="true" trigger="true" collisionMask="15736832" nodeId="19" materialIds="7" castsShadows="true" receiveShadows="true" nonRenderable="true"/>
          <TransformGroup name="bunkerSiloArea" nodeId="20">
            <TransformGroup name="start" translation="3 0 -15" nodeId="21"/>
            <TransformGroup name="width" translation="9 0 -15" nodeId="22"/>
            <TransformGroup name="height" translation="3 0 15" nodeId="23"/>
          </TransformGroup>
        </TransformGroup>
      </TransformGroup>
      <TransformGroup name="silo002" clipDistance="800" objectMask="65534" nodeId="24">
        <TransformGroup name="gameplay" clipDistance="400" nodeId="25">
          <Shape shapeId="3" name="interactionTrigger" static="true" trigger="true" collisionMask="15736832" nodeId="26" materialIds="7" castsShadows="true" receiveShadows="true" nonRenderable="true"/>
          <TransformGroup name="bunkerSiloArea" nodeId="27">
            <TransformGroup name="start" translation="-4 0 -15" nodeId="28"/>
            <TransformGroup name="width" translation="3 0 -15" nodeId="29"/>
            <TransformGroup name="height" translation="-4 0 15" nodeId="30"/>
          </TransformGroup>
        </TransformGroup>
      </TransformGroup>
      <TransformGroup name="silo003" clipDistance="800" objectMask="65534" nodeId="31">
        <TransformGroup name="gameplay" clipDistance="400" nodeId="32">
          <Shape shapeId="4" name="interactionTrigger" static="true" trigger="true" collisionMask="15736832" nodeId="33" materialIds="7" castsShadows="true" receiveShadows="true" nonRenderable="true"/>
          <TransformGroup name="bunkerSiloArea" nodeId="34">
            <TransformGroup name="start" translation="-13.75 0 -15" nodeId="35"/>
            <TransformGroup name="width" translation="-4 0 -15" nodeId="36"/>
            <TransformGroup name="height" translation="-13.75 0 15" nodeId="37"/>
          </TransformGroup>
        </TransformGroup>
      </TransformGroup>
    </TransformGroup>
  </Scene>

  <UserAttributes>
    <UserAttribute nodeId="17">
      <Attribute name="bunkerSiloArea" type="string" value="0>0|1"/>
      <Attribute name="fermentedFillTypes" type="string" value="silage silage silage rape sunflower maize soybean potato barley wheat sugarBeet"/>
      <Attribute name="fillTypes" type="string" value="grass_windrow dryGrass_windrow chaff rape sunflower maize soybean potato barley wheat sugarBeet"/>
      <Attribute name="interactionTriggerIndex" type="string" value="0>0|0"/>
      <Attribute name="onCreate" type="scriptCallback" value="BunkerSilo.onCreate"/>
    </UserAttribute>
    <UserAttribute nodeId="24">
      <Attribute name="bunkerSiloArea" type="string" value="0>0|1"/>
      <Attribute name="fermentedFillTypes" type="string" value="silage silage silage rape sunflower maize soybean potato barley wheat sugarBeet"/>
      <Attribute name="fillTypes" type="string" value="grass_windrow dryGrass_windrow chaff rape sunflower maize soybean potato barley wheat sugarBeet"/>
      <Attribute name="interactionTriggerIndex" type="string" value="0>0|0"/>
      <Attribute name="onCreate" type="scriptCallback" value="BunkerSilo.onCreate"/>
    </UserAttribute>
    <UserAttribute nodeId="31">
      <Attribute name="bunkerSiloArea" type="string" value="0>0|1"/>
      <Attribute name="fermentedFillTypes" type="string" value="silage silage silage rape sunflower maize soybean potato barley wheat sugarBeet"/>
      <Attribute name="fillTypes" type="string" value="grass_windrow dryGrass_windrow chaff rape sunflower maize soybean potato barley wheat sugarBeet"/>
      <Attribute name="interactionTriggerIndex" type="string" value="0>0|0"/>
      <Attribute name="onCreate" type="scriptCallback" value="BunkerSilo.onCreate"/>
    </UserAttribute>
  </UserAttributes>

</i3D>
Ich glaube nicht das es daran liegt, das die Silos mit ihren Triggern nicht dafür gedacht sind als plazierbares Objekt genutzt zu werden. Das sollte zumindest nicht so einen Lua-Fehler hervorrufen.

LG
Das Universum ist unvorstellbar groß und wir sind im Vergleich dazu winzig.

Daher kann mir jemand der unter uns Winzlingen Unterschiede in Hautfarbe oder Herkunft sucht, nur Leid tun, weil seine Sichtweise so begrenzt ist!

Fremdenfeindlichkeit ist Menschenfeindlichkeit!
agp8x
Posts: 589
Joined: Mon Sep 01, 2008 2:25 pm

Re: Plazierbares Fahrsilo

Post by agp8x »

Zeig mal deine Lua
XPModder
Posts: 53
Joined: Thu Oct 30, 2014 2:45 pm

Re: Plazierbares Fahrsilo

Post by XPModder »

Hier ist die Lua:

Code: Select all

-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.

BunkerSilo = {};

BunkerSilo_mt = Class(BunkerSilo, Placeable);

InitObjectClass(BunkerSilo, "BunkerSilo");

function BunkerSilo:onCreate(id)
    local object = BunkerSilo:new(g_server ~= nil, g_client ~= nil);
    if object:load(id) then
        g_currentMission:addOnCreateLoadedObject(object);
        g_currentMission:addOnCreateLoadedObjectToSave(object);
        object:register(true);
    else
        object:delete();
   end;
end;

function BunkerSilo:new(isServer, isClient, customMt)
    local mt = customMt;
    if mt == nil then
        mt = BunkerSilo_mt;
    end;

    local self = Object:new(isServer, isClient, mt);
    self.nodeId = 0;

    self.acceptedFillTypes = {};
    self.inputFillType = FillUtil.FILLTYPE_CHAFF;
    self.fermentingFillType = FillUtil.FILLTYPE_TARP;
    self.outputFillType = FillUtil.FILLTYPE_SILAGE;

    self.fillLevel = 0;
    self.compactedFillLevel = 0;
    self.compactedPercent = 0;

    self.emptyThreshold = 100;

    self.fermentingTime = 0;
    self.fermentingDuration = 6*60*60; -- 6hours (ingame)
    self.fermentingPercent = 0;

    self.isOpenedAtFront = false;
    self.isOpenedAtBack = false;

    self.distanceToCompactedFillLevel = 100;

    self.interactionTriggerId = nil;

    self.playerInRange = false;
    self.vehiclesInRange = {};
    self.numVehiclesInRange = 0;

    self.bunkerSiloArea = {};
    self.bunkerSiloArea.offsetFront = 0;
    self.bunkerSiloArea.offsetBack = 0

    self.siloIsFullWarningTimer = 0;
    self.siloIsFullWarningDuration = 2000;

    self.activatable = BunkerSiloActivatable:new(self);

    self.state = BunkerSilo.STATE_FILL;

    self.bunkerSiloDirtyFlag = self:getNextDirtyFlag();
    return self;
end;

function BunkerSilo:delete()
    g_currentMission:removeOnCreateLoadedObjectToSave(self);
    if self.interactionTriggerId ~= nil then
        removeTrigger(self.interactionTriggerId);
    end;
    if self.nodeId ~= 0 then
        g_currentMission:removeNodeObject(self.nodeId);
    end;
    g_currentMission:removeActivatableObject(self.activatable);
    BunkerSilo:superClass().delete(self);
end;

function BunkerSilo:readStream(streamId, connection)
    BunkerSilo:superClass().readStream(self, streamId, connection);
    if connection:getIsServer() then
        local state = streamReadUIntN(streamId, 3);
        self:setState(state);
        self.isOpenedAtFront = streamReadBool(streamId);
        self.isOpenedAtBack = streamReadBool(streamId);
        self.fillLevel = streamReadFloat32(streamId);
        self.compactedPercent = math.floor( (streamReadUIntN(streamId, 8) / 2.55) + 0.5);
        self.fermentingPercent = math.floor( (streamReadUIntN(streamId, 8) / 2.55) + 0.5);
    end;
end;

function BunkerSilo:writeStream(streamId, connection)
    BunkerSilo:superClass().writeStream(self, streamId, connection);
    if not connection:getIsServer() then
        streamWriteUIntN(streamId, self.state, 3);
        streamWriteBool(streamId, self.isOpenedAtFront);
        streamWriteBool(streamId, self.isOpenedAtBack);
        streamWriteFloat32(streamId, self.fillLevel);
        streamWriteUIntN(streamId, 2.55*self.compactedPercent, 8);
        streamWriteUIntN(streamId, 2.55*self.fermentingPercent, 8);
    end;
end;

function BunkerSilo:readUpdateStream(streamId, timestamp, connection)
    BunkerSilo:superClass().readUpdateStream(self, streamId, timestamp, connection)
    if connection:getIsServer() then
        if streamReadBool(streamId) then
            local state = streamReadUIntN(streamId, 3);
            if state ~= self.state then
                self:setState(state, true);
            end

            self.fillLevel = streamReadFloat32(streamId);
            self.isOpenedAtFront = streamReadBool(streamId);
            self.isOpenedAtBack = streamReadBool(streamId);

            if self.state == BunkerSilo.STATE_FILL then
                self.compactedPercent =  math.floor( (streamReadUIntN(streamId, 8) / 2.55) + 0.5);
            elseif self.state == BunkerSilo.STATE_CLOSED or self.state == BunkerSilo.STATE_FERMENTED then
                self.fermentingPercent =  math.floor( (streamReadUIntN(streamId, 8) / 2.55) + 0.5);
            end
        end
    end;
end;

function BunkerSilo:writeUpdateStream(streamId, connection, dirtyMask)
    BunkerSilo:superClass().writeUpdateStream(self, streamId, connection, dirtyMask)
    if not connection:getIsServer() then
        if streamWriteBool(streamId, bitAND(dirtyMask, self.bunkerSiloDirtyFlag) ~= 0) then
            streamWriteUIntN(streamId, self.state, 3);

            streamWriteFloat32(streamId, self.fillLevel);
            streamWriteBool(streamId, self.isOpenedAtFront);
            streamWriteBool(streamId, self.isOpenedAtBack);

            if self.state == BunkerSilo.STATE_FILL then
                streamWriteUIntN(streamId, 2.55*self.compactedPercent, 8);
            elseif self.state == BunkerSilo.STATE_CLOSED or self.state == BunkerSilo.STATE_FERMENTED then
                streamWriteUIntN(streamId, 2.55*self.fermentingPercent, 8);
            end
        end
    end;
end;

function BunkerSilo:load(nodeId)

    self.nodeId = nodeId;

    local areaNode = Utils.indexToObject(nodeId, getUserAttribute(nodeId, "bunkerSiloArea"));
    if areaNode == nil then
        print("Warning: BunkerSilo, could not resolve attribute 'bunkerSiloArea' into a valid node!");
       return false;
    end
    self.bunkerSiloArea.start = getChildAt(areaNode, 0);
    self.bunkerSiloArea.width = getChildAt(areaNode, 1);
    self.bunkerSiloArea.height = getChildAt(areaNode, 2);

    self.bunkerSiloArea.sx, self.bunkerSiloArea.sy, self.bunkerSiloArea.sz = getWorldTranslation(self.bunkerSiloArea.start);
    self.bunkerSiloArea.wx, self.bunkerSiloArea.wy, self.bunkerSiloArea.wz = getWorldTranslation(self.bunkerSiloArea.width);
    self.bunkerSiloArea.hx, self.bunkerSiloArea.hy, self.bunkerSiloArea.hz = getWorldTranslation(self.bunkerSiloArea.height);

    self.bunkerSiloArea.dhx = self.bunkerSiloArea.hx - self.bunkerSiloArea.sx;
    self.bunkerSiloArea.dhy = self.bunkerSiloArea.hy - self.bunkerSiloArea.sy;
    self.bunkerSiloArea.dhz = self.bunkerSiloArea.hz - self.bunkerSiloArea.sz;
    local dhLength = Utils.vector3Length(self.bunkerSiloArea.dhx, self.bunkerSiloArea.dhy, self.bunkerSiloArea.dhz);
    self.bunkerSiloArea.dhx_norm = self.bunkerSiloArea.dhx / dhLength;
    self.bunkerSiloArea.dhy_norm = self.bunkerSiloArea.dhy / dhLength;
    self.bunkerSiloArea.dhz_norm = self.bunkerSiloArea.dhz / dhLength;

    self.bunkerSiloArea.dwx = self.bunkerSiloArea.wx - self.bunkerSiloArea.sx;
    self.bunkerSiloArea.dwy = self.bunkerSiloArea.wy - self.bunkerSiloArea.sy;
    self.bunkerSiloArea.dwz = self.bunkerSiloArea.wz - self.bunkerSiloArea.sz;
    local dwLength = Utils.vector3Length(self.bunkerSiloArea.dwx, self.bunkerSiloArea.dwy, self.bunkerSiloArea.dwz);
    self.bunkerSiloArea.dwx_norm = self.bunkerSiloArea.dwx / dwLength;
    self.bunkerSiloArea.dwy_norm = self.bunkerSiloArea.dwy / dwLength;
    self.bunkerSiloArea.dwz_norm = self.bunkerSiloArea.dwz / dwLength;
	
	
    self.acceptedFillTypes = {};
    local dataString = Utils.getNoNil(getUserAttribute(nodeId, "acceptedFillTypes"), "chaff grass_windrow dryGrass_windrow");
    local data = Utils.splitString(" ", dataString);
    for i=1,table.getn(data) do
        local fillType = FillUtil.fillTypeNameToInt[data[i] ];
        if fillType ~= nil then
            self.acceptedFillTypes[fillType] = true;
        else
            print("Warning: BunkerSilo has an invalid fillType (acceptedFillTypes): "..tostring(data[i]));
        end
    end

    local dataString = Utils.getNoNil(getUserAttribute(nodeId, "inputFillType"), "chaff");
    local fillType = FillUtil.fillTypeNameToInt[dataString];
    if fillType ~= nil then
        self.inputFillType = fillType;
    else
        print("Warning: BunkerSilo has an invalid fillType (inputFillType): "..tostring(dataString));
    end

    local dataString = Utils.getNoNil(getUserAttribute(nodeId, "outputFillType"), "silage");
    local fillType = FillUtil.fillTypeNameToInt[dataString];
    if fillType ~= nil then
        self.outputFillType = fillType;
    else
        print("Warning: BunkerSilo has an invalid fillType (outputFillType): "..tostring(dataString));
    end

    if self.isServer then
        TipUtil.setConvertingFillTypeAreas(self.bunkerSiloArea, self.acceptedFillTypes, self.inputFillType);
    end


    local distanceToCompactedFillLevelStr = getUserAttribute(nodeId, "distanceToCompactedFillLevel");
    if distanceToCompactedFillLevelStr ~= nil then
        self.distanceToCompactedFillLevel = Utils.getNoNil(tonumber(distanceToCompactedFillLevelStr), self.distanceToCompactedFillLevel);
    end;

    local fermentingDurationStr = getUserAttribute(nodeId, "fermentingDuration");
    if fermentingDurationStr ~= nil then
        self.fermentingDuration = Utils.getNoNil(tonumber(fermentingDurationStr), self.fermentingDuration);
    end;

    self.fillLevel = 0;
	
    local interactionTriggerIndex = getUserAttribute(nodeId, "interactionTriggerIndex");
    if interactionTriggerIndex ~= nil then
        self.interactionTriggerId = Utils.indexToObject(nodeId, interactionTriggerIndex);
        if self.interactionTriggerId ~= nil then
            addTrigger(self.interactionTriggerId, "interactionTriggerCallback", self);
        end;
    end;

    self.openingLength = Utils.getNoNil(getUserAttribute(nodeId, "openingLength"), 5);

    -- adjust timings to difficulty
    local difficultyMultiplier = g_currentMission.missionInfo.difficulty;
    self.fermentingDuration = self.fermentingDuration*difficultyMultiplier;
    self.distanceToCompactedFillLevel = self.distanceToCompactedFillLevel/difficultyMultiplier;
	
    -- just for tutorial 12 (feeder)
    self.isTutorialSilo = Utils.getNoNil( getUserAttribute(nodeId, "isTutorialSilo"), false );

    self.saveId = Utils.getNoNil( getUserAttribute(nodeId, "saveId"), "BunkerSilo_"..getName(nodeId) );
	
    g_currentMission:addNodeObject(self.nodeId, self);
	
    self:setState(BunkerSilo.STATE_FILL);

	
    return true;
end;

function BunkerSilo:loadFromAttributesAndNodes(xmlFile, key)
	
    local state = getXMLInt(xmlFile, key.."#state");
    if state ~= nil then
        if state >= 0 and state < BunkerSilo.NUM_STATES then
            self:setState(state);
        end;
    end;
	
    local fillLevel = getXMLFloat(xmlFile, key.."#fillLevel");
    if fillLevel ~= nil then
        self.fillLevel = fillLevel;
    end;
    local compactedFillLevel = getXMLFloat(xmlFile, key.."#compactedFillLevel");
    if compactedFillLevel ~= nil then
        self.compactedFillLevel = Utils.clamp(compactedFillLevel, 0, self.fillLevel);
    end;
	
    local fermentingTime = getXMLFloat(xmlFile, key.."#fermentingTime");
    if fermentingTime ~= nil then
        self.fermentingTime = Utils.clamp(fermentingTime, 0, self.fermentingDuration);
    end;
    local fermentingPercent = getXMLFloat(xmlFile, key.."#fermentingPercent");
    if fermentingPercent ~= nil then
        self.fermentingPercent = Utils.clamp(fermentingPercent, 0, 100);
    end;
	
    self.isOpenedAtFront = Utils.getNoNil(getXMLBool(xmlFile, key.."#openedAtFront"), false);
    self.isOpenedAtBack = Utils.getNoNil(getXMLBool(xmlFile, key.."#openedAtBack"), false);

    if self.isOpenedAtFront then
        self.bunkerSiloArea.offsetFront = self:getBunkerAreaOffset(true, 0, self.outputFillType);
    else
        self.bunkerSiloArea.offsetFront = self:getBunkerAreaOffset(true, 0, self.fermentingFillType);
    end
    if self.isOpenedAtBack then
        self.bunkerSiloArea.offsetBack = self:getBunkerAreaOffset(false, 0, self.outputFillType);
    else
        self.bunkerSiloArea.offsetFront = self:getBunkerAreaOffset(false, 0, self.fermentingFillType);
    end

    return true;
end;

function BunkerSilo:getSaveAttributesAndNodes(nodeIdent)
	
    local attributes = 'state="'..self.state..'" fillLevel="'..self.fillLevel..'" compactedFillLevel="'..self.compactedFillLevel..'"';
    attributes = attributes .. ' fermentingTime="'..self.fermentingTime..'" fermentingPercent="'..self.fermentingPercent..'"';
    attributes = attributes .. ' openedAtFront="' .. tostring(self.isOpenedAtFront) ..'" openedAtBack="' .. tostring(self.isOpenedAtBack) .. '"';
    local nodes = "";

    return attributes, nodes;
end;

function BunkerSilo:update(dt)
	
    if self:getCanInteract(true) then
        local fillType = self.inputFillType;
        if self.state == BunkerSilo.STATE_CLOSED or self.state == BunkerSilo.STATE_FERMENTED or self.state == BunkerSilo.STATE_DRAIN then
            fillType = self.outputFillType;
        end
        local fillTypeName = "";
        if FillUtil.fillTypeIndexToDesc[fillType] ~= nil then
            fillTypeName = FillUtil.fillTypeIndexToDesc[fillType].nameI18N;
        end
        if self.state == BunkerSilo.STATE_FILL then
            g_currentMission:addExtraPrintText(g_i18n:getText("info_fillLevel")..string.format(" %s: %d", fillTypeName, self.fillLevel));
            g_currentMission:addExtraPrintText(g_i18n:getText("info_compacting")..string.format(" %d%%", self.compactedPercent));
        elseif self.state == BunkerSilo.STATE_CLOSED or self.state == BunkerSilo.STATE_FERMENTED then
            g_currentMission:addExtraPrintText(g_i18n:getText("info_fermenting")..string.format(" %s: %d%%", fillTypeName, self.fermentingPercent));
        elseif self.state == BunkerSilo.STATE_DRAIN then
            g_currentMission:addExtraPrintText(g_i18n:getText("info_fillLevel")..string.format(" %s: %d", fillTypeName, self.fillLevel));
        end;
    end;

    if self.state == BunkerSilo.STATE_CLOSED then
        if self.isServer then
            self.fermentingTime = math.min(self.fermentingDuration, self.fermentingTime + dt*0.001*g_currentMission.missionInfo.timeScale);
            local fermentingPercent = Utils.getFlooredPercent(self.fermentingTime, self.fermentingDuration);
            if fermentingPercent ~= self.fermentingPercent then
                self.fermentingPercent = fermentingPercent;
                self:raiseDirtyFlags(self.bunkerSiloDirtyFlag);
            end
            if self.fermentingTime >= self.fermentingDuration then
                self:setState(BunkerSilo.STATE_FERMENTED, true);
            end;
        end;
    end;
	
    if self.isServer then
        if self.state == BunkerSilo.STATE_FILL then
            for vehicle,state in pairs(self.vehiclesInRange) do
                if state then
                    if vehicle:getIsActive() then
                        local distance = vehicle.lastMovedDistance;
                        if distance > 0 then
                            local mass = vehicle:getTotalMass(false);

                            local refNode = vehicle.bunkerSiloCompactingRefNode;
                            if refNode == nil then
                                refNode = vehicle.components[1].node;
                            end
                            local scale = (mass / BunkerSilo.COMPACTING_BASE_MASS) * Utils.getNoNil(vehicle.bunkerSiloCompactingScale, 1);

                            local deltaCompact = distance*scale*self.distanceToCompactedFillLevel;

                            local numWheels = table.getn(vehicle.wheels);
                            if numWheels > 0 then
                                local activeWheels = 0;
                                for i=1,numWheels do
                                    local wheel = vehicle.wheels[i];
                                    if wheel.contact == Vehicle.WHEEL_GROUND_HEIGHT_CONTACT then
                                        activeWheels = activeWheels + 1;
                                    end
                                end
                                deltaCompact = deltaCompact * (activeWheels / numWheels);
                            end

                            local compactedFillLevel = math.min(self.compactedFillLevel + deltaCompact, self.fillLevel);
                            if compactedFillLevel ~= self.compactedFillLevel then
                                self.compactedFillLevel = compactedFillLevel;
                                self.compactedPercent = Utils.getFlooredPercent(math.min(self.compactedFillLevel, self.fillLevel), self.fillLevel);
                                self:raiseDirtyFlags(self.bunkerSiloDirtyFlag);
                            end
                        end;
                    end;
                end
            end;
        end;
    end;

    -- for chaff tutorial: always take the highest fill level of all bunker silos
    if g_currentMission ~= nil and g_currentMission.bunkerScore ~= nil then
        if g_currentMission.bunkerScore < self.fillLevel then
            g_currentMission.bunkerScore = self.fillLevel;
        end;
    end;
end;

function BunkerSilo:updateTick(dt)
    if self.isServer then

        local dirty = false;
        local area = self.bunkerSiloArea;
        local fillLevel = self.fillLevel;
        local fillType = self.inputFillType;

        if self.inputFillType == FillUtil.FILLTYPE_UNKNOWN then

        elseif self.state == BunkerSilo.STATE_FILL then
            fillLevel = TipUtil.getFillLevelAtArea(fillType, area.sx,area.sz, area.wx,area.wz, area.hx,area.hz);
        elseif self.state == BunkerSilo.STATE_CLOSED then
            fillLevel = TipUtil.getFillLevelAtArea(self.fermentingFillType, area.sx,area.sz, area.wx,area.wz, area.hx,area.hz)
        elseif self.state == BunkerSilo.STATE_FERMENTED then
            fillLevel1 = TipUtil.getFillLevelAtArea(self.fermentingFillType, area.sx,area.sz, area.wx,area.wz, area.hx,area.hz)
            fillLevel2 = TipUtil.getFillLevelAtArea(self.outputFillType, area.sx,area.sz, area.wx,area.wz, area.hx,area.hz)
            fillLevel = fillLevel1 + fillLevel2;
        elseif self.state == BunkerSilo.STATE_DRAIN then
            fillLevel1 = TipUtil.getFillLevelAtArea(self.fermentingFillType, area.sx,area.sz, area.wx,area.wz, area.hx,area.hz)
            fillLevel2 = TipUtil.getFillLevelAtArea(self.outputFillType, area.sx,area.sz, area.wx,area.wz, area.hx,area.hz)
            fillLevel = fillLevel1 + fillLevel2;
            if fillLevel < self.emptyThreshold then
                TipUtil.removeFromGroundByArea(area.sx,area.sz, area.wx,area.wz, area.hx,area.hz, self.fermentingFillType);
                TipUtil.removeFromGroundByArea(area.sx,area.sz, area.wx,area.wz, area.hx,area.hz, self.outputFillType);
                self:setState(BunkerSilo.STATE_FILL, true);
            end
        end

        dirty = fillLevel ~= self.fillLevel;

        if dirty then
            self.fillLevel = fillLevel;
            self:raiseDirtyFlags(self.bunkerSiloDirtyFlag);
        end;
    end;
end;

function BunkerSilo:setState(state, showNotification)

    if state ~= self.state then

        if state == BunkerSilo.STATE_FILL then

            self.fermentingTime = 0;
            self.compactedFillLevel = 0;
            self.isOpenedAtFront = false;
            self.isOpenedAtBack = false;
            self.bunkerSiloArea.offsetFront = 0;
            self.bunkerSiloArea.offsetBack = 0;

            if showNotification then
                g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_INFO, g_i18n:getText("ingameNotification_bunkerSiloIsEmpty"));
            end

            if self.isServer then
                TipUtil.removeFixedFillTypesArea(self.bunkerSiloArea);
                TipUtil.setConvertingFillTypeAreas(self.bunkerSiloArea, self.acceptedFillTypes, self.inputFillType);
            end
	
        elseif state == BunkerSilo.STATE_CLOSED then
	
            if self.isServer then
                -- change fillType
                local area = self.bunkerSiloArea;
                local offsetFront = self:getBunkerAreaOffset(true, 0, self.inputFillType);
                local offsetBack = self:getBunkerAreaOffset(false, 0, self.inputFillType);

                local x0 = area.sx + (offsetFront * area.dhx_norm);
                local z0 = area.sz + (offsetFront * area.dhz_norm);
                local x1 = x0 + area.dwx;
                local z1 = z0 + area.dwz;
                local x2 = area.sx + area.dhx - (offsetBack * area.dhx_norm);
                local z2 = area.sz + area.dhz - (offsetBack * area.dhz_norm);

                local changed = TipUtil.changeFillTypeAtArea(x0,z0, x1,z1, x2,z2, self.inputFillType, self.fermentingFillType);

                if self.isServer then
                    TipUtil.removeFixedFillTypesArea(self.bunkerSiloArea);
                    TipUtil.removeConvertingFillTypeAreas(self.bunkerSiloArea);
                end
            end

            if showNotification then
                g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_INFO, g_i18n:getText("ingameNotification_bunkerSiloCovered"));
            end

        elseif state == BunkerSilo.STATE_FERMENTED then

            if showNotification then
                g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_INFO, g_i18n:getText("ingameNotification_bunkerSiloDoneFermenting"));
            end

        elseif state == BunkerSilo.STATE_DRAIN then

            self.bunkerSiloArea.offsetFront = 0;
            self.bunkerSiloArea.offsetBack = 0;

            if showNotification then
                g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_INFO, g_i18n:getText("ingameNotification_bunkerSiloOpened"));
            end

            if self.isServer then
                TipUtil.removeConvertingFillTypeAreas(self.bunkerSiloArea);
                local fillTypes = {};
                fillTypes[self.outputFillType] = true;
                TipUtil.setFixedFillTypesArea(self.bunkerSiloArea, fillTypes);
            end

        end;

        self.state = state;
        if self.isServer then
            self:raiseDirtyFlags(self.bunkerSiloDirtyFlag);
        end;
    end;
end;

function BunkerSilo:openSilo(px,py,pz)
    self:setState(BunkerSilo.STATE_DRAIN, true);

    self.bunkerSiloArea.offsetFront = self:getBunkerAreaOffset(true, 0, self.fermentingFillType);
    self.bunkerSiloArea.offsetBack = self:getBunkerAreaOffset(false, 0, self.fermentingFillType);

    -- check which side is closer to player
    local openedAtFront = self.isOpenedAtFront;
    local openedAtBack = self.isOpenedAtBack;
    local openAtFront = self:getIsCloserToFront(px,py,pz);
    if openAtFront and not self.isOpenedAtFront then
        self:switchFillTypeAtOffset(true, self.bunkerSiloArea.offsetFront, self.openingLength);
        self.isOpenedAtFront = true;
        self:raiseDirtyFlags(self.bunkerSiloDirtyFlag);
    elseif not self.isOpenedAtBack then
        self:switchFillTypeAtOffset(false, self.bunkerSiloArea.offsetBack, self.openingLength);
        self.isOpenedAtBack = true;
        self:raiseDirtyFlags(self.bunkerSiloDirtyFlag);
    end;
end;

function BunkerSilo:getBunkerAreaOffset(updateAtFront, offset, fillType)
    local area = self.bunkerSiloArea;

    local hx, hy, hz = area.dhx_norm, area.dhy_norm, area.dhz_norm;
    if not updateAtFront then
        hx, hy, hz = -area.dhx_norm, -area.dhy_norm, -area.dhz_norm;
    end
    local hl = Utils.vector3Length(area.dhx, area.dhy, area.dhz);

    local a0x, a0z = nil, nil;
    local a1x, a1z = nil, nil;
    local a2x, a2z = nil, nil;

    local i = offset;
    while i < (hl - 1) do
        local d1x,d1y,d1z = i*hx, i*hy, i*hz;
        local d2x,d2y,d2z = (i+1)*hx, (i+1)*hy, (i+1)*hz;

        if updateAtFront then
            a0x, a0z = area.sx + d1x, area.sz + d1z;
            a1x, a1z = area.wx + d1x, area.wz + d1z;
            a2x, a2z = area.sx + d2x, area.sz + d2z;
        else
            a0x, a0z = area.hx + d1x, area.hz + d1z;
            a1x, a1z = area.hx + d1x + area.dwx, area.hz + d1z + area.dwz;
            a2x, a2z = area.hx + d2x, area.hz + d2z;
        end

        local fillLevel = TipUtil.getFillLevelAtArea(fillType, a0x,a0z, a1x,a1z, a2x,a2z);
        if fillLevel > 0 then
            offset = i;
            break;
        end
        i = i + 1;
    end

    return offset;
end

function BunkerSilo:switchFillTypeAtOffset(switchAtFront, offset, length)

    local fillType = self.fermentingFillType;
    local newFillType = self.outputFillType;

    local a0x, a0z = nil, nil;
    local a1x, a1z = nil, nil;
    local a2x, a2z = nil, nil;

    local area = self.bunkerSiloArea;

    if switchAtFront then
        a0x, a0z = area.sx + (offset * area.dhx_norm), area.sz + (offset * area.dhz_norm);
        a1x, a1z = a0x + area.dwx, a0z + area.dwz;
        a2x, a2z = area.sx + ((offset + length) * area.dhx_norm), area.sz + ((offset + length) * area.dhz_norm);
    else
        a0x, a0z = area.hx - (offset * area.dhx_norm), area.hz - (offset * area.dhz_norm);
        a1x, a1z = a0x + area.dwx, a0z + area.dwz;
        a2x, a2z = area.hx - ((offset + length) * area.dhx_norm), area.hz - ((offset + length) * area.dhz_norm);
    end

    TipUtil.changeFillTypeAtArea(a0x,a0z, a1x,a1z, a2x,a2z, fillType, newFillType);
    if switchAtFront then
        TipUtil.removeEmptyFillTypeAtArea(area.sx,area.sz, area.wx,area.wz, a2x,a2z, fillType);
    else
        TipUtil.removeEmptyFillTypeAtArea(area.hx,area.hz, area.hx+area.dwx,area.hz+area.dwz, a2x,a2z, fillType);
    end

end

function BunkerSilo:getIsCloserToFront(ix,iy,iz)
    local area = self.bunkerSiloArea;

    local x = area.sx + (0.5*area.dwx) + (area.offsetFront * area.dhx_norm);
    local y = area.sy + (0.5*area.dwy) + (area.offsetFront * area.dhy_norm);
    local z = area.sz + (0.5*area.dwz) + (area.offsetFront * area.dhz_norm);
    local distFront = Utils.vector3Length(x-ix, y-iy, z-iz);

    local x = area.sx + (0.5*area.dwx) + area.dhx - (area.offsetBack * area.dhx_norm);
    local y = area.sy + (0.5*area.dwy) + area.dhy - (area.offsetBack * area.dhy_norm);
    local z = area.sz + (0.5*area.dwz) + area.dhz - (area.offsetBack * area.dhz_norm);
    local distBack = Utils.vector3Length(x-ix, y-iy, z-iz);

    return distFront < distBack;
end

function BunkerSilo:getCanInteract(showInformationOnly)
    if showInformationOnly then
        if (g_currentMission.controlPlayer and self.playerInRange) then
            return true;
        end;
        if not g_currentMission.controlPlayer then
            for vehicle in pairs(self.vehiclesInRange) do
                if vehicle:getIsActiveForInput(false) then
                    return true;
                end;
            end;
        end;
    else
        if (g_currentMission.controlPlayer and self.playerInRange) then
            --if next(self.vehiclesInRange) == nil then
                return true;
            --end
        end;
    end
    return false;
end;

function BunkerSilo:getCanCloseSilo()
    return self.state == BunkerSilo.STATE_FILL and self.fillLevel > 0 and self.compactedPercent >= 100;
end;

function BunkerSilo:getCanOpenSilo()
    if not (self.state == BunkerSilo.STATE_FERMENTED or self.state == BunkerSilo.STATE_DRAIN) then
        return false;
    end
    local ix,iy,iz = self:getInteractionPosition();
    if ix ~= nil then
        local closerToFront = self:getIsCloserToFront(ix,iy,iz);
        if closerToFront and not self.isOpenedAtFront then
            return true;
        end
        if not closerToFront and not self.isOpenedAtBack then
            return true;
        end
    end
    return false;
end

function BunkerSilo:getInteractionPosition()
    if g_currentMission.controlPlayer and self.playerInRange then
        return getWorldTranslation(g_currentMission.player.rootNode);
    else
        if self.vehiclesInRange[g_currentMission.currentVehicle] ~= nil then
            return getWorldTranslation(self.vehiclesInRange[g_currentMission.currentVehicle].components[1].node);
        end
    end
    return nil;
end

function BunkerSilo:interactionTriggerCallback(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
    if onEnter or onLeave then
        if g_currentMission.player ~= nil and otherId == g_currentMission.player.rootNode then
            if onEnter then
                self.playerInRange = true;
                g_currentMission:removeActivatableObject(self.activatable); -- make sure it is not added twice
                g_currentMission:addActivatableObject(self.activatable);
            else
                self.playerInRange = false;
                if self.numVehiclesInRange == 0 then
                    g_currentMission:removeActivatableObject(self.activatable);
                end;
            end;
        else
            --local vehicle = g_currentMission.nodeToVehicle[otherId];
            local vehicle = g_currentMission.nodeToVehicle[otherShapeId];
            if vehicle ~= nil then
                if onEnter then
                    if self.vehiclesInRange[vehicle] == nil then
                        self.vehiclesInRange[vehicle] = true;
                        self.numVehiclesInRange = self.numVehiclesInRange + 1;
	
                        g_currentMission:removeActivatableObject(self.activatable); -- make sure it is not added twice
                        g_currentMission:addActivatableObject(self.activatable);

                        -- add callback if shovel
                        if vehicle.setChangedFillLevelCallback ~= nil then
                            vehicle:setChangedFillLevelCallback(BunkerSilo.onChangedFillLevelCallback, self);
                        end
                    end;
                else
                    if self.vehiclesInRange[vehicle] then
                        self.vehiclesInRange[vehicle] = nil;
                        self.numVehiclesInRange = self.numVehiclesInRange - 1;

                        if self.numVehiclesInRange == 0 and not self.playerInRange then
                            g_currentMission:removeActivatableObject(self.activatable);
                        end;

                        -- remove callback if shovel
                        if vehicle.setChangedFillLevelCallback ~= nil then
                            vehicle:setChangedFillLevelCallback(nil);
                        end
                    end;
                end;
            end;
        end;
    end;
end;

function BunkerSilo.onChangedFillLevelCallback(self, shovel, fillDelta, fillType)
    if fillDelta >= 0 then
        return;
    end

    local area = self.bunkerSiloArea;

    local x,y,z;
    if shovel.pickUp.node ~= nil then
        x,y,z = localToWorld(shovel.pickUp.node, 0, 0, shovel.pickUp.length);
    else
        x,y,z = getWorldTranslation(shovel.components[1].node);
    end;

    local closerToFront = self:getIsCloserToFront(x,y,z);

    local length = self.openingLength;

    if closerToFront then
        if self.isOpenedAtFront then
            local p1 = Utils.getProjectOnLineParameter(x,z, area.sx,area.sz, area.dhx_norm,area.dhz_norm);
            p1 = math.floor(p1 + 0.5);
            if p1 > area.offsetFront - length then
                local offset = self:getBunkerAreaOffset(true, area.offsetFront, self.fermentingFillType);

                local targetOffset = math.max(p1 + length, offset);
                local length = targetOffset - area.offsetFront;

                self:switchFillTypeAtOffset(true, area.offsetFront, length);
                area.offsetFront = area.offsetFront + length;
            end
        end
    else
        if self.isOpenedAtBack then
            local p1 = Utils.getProjectOnLineParameter(x,z, area.hx,area.hz, -area.dhx_norm,-area.dhz_norm);
            p1 = math.floor(p1 + 0.5);
            if p1 > area.offsetBack - length then
                local offset = self:getBunkerAreaOffset(true, area.offsetBack, self.fermentingFillType);

                local targetOffset = math.max(p1 + length, offset);
                local length = targetOffset - area.offsetBack;

                self:switchFillTypeAtOffset(false, area.offsetBack, length);
                area.offsetBack = area.offsetBack + length;
            end
        end
    end
end


registerPlaceableType("BunkerSilo", BunkerSilo);
LG
Das Universum ist unvorstellbar groß und wir sind im Vergleich dazu winzig.

Daher kann mir jemand der unter uns Winzlingen Unterschiede in Hautfarbe oder Herkunft sucht, nur Leid tun, weil seine Sichtweise so begrenzt ist!

Fremdenfeindlichkeit ist Menschenfeindlichkeit!
User avatar
modelleicher
Posts: 1575
Joined: Fri Jul 09, 2010 11:10 pm
Location: Hessen
Contact:

Re: Plazierbares Fahrsilo

Post by modelleicher »

Moin...

Hier ein "funktionierendes" Silo.. In Anführungszeichen deshalb, weil es Callstacks wirft sobald man was drin abkippen muss. Hänge es jetzt trotzdem mal hier an vielleicht kommst du damit ja weiter.. Ansonsten werde ich selbst die Tage mal schauen was den Callstack verursacht, sicher nur ne Kleinigkeit ;)

http://www.file-upload.net/download-120 ... e.zip.html

EDIT:
Ok, doch nicht so einfach wie es scheint.. :confusednew:


LG
Eine Stunde oder Minute ist nur ein winziger Teil unseres gesamten Lebens. Und dennoch sind es die einzelnen Momente, die das Leben lebenswert machen.
XPModder
Posts: 53
Joined: Thu Oct 30, 2014 2:45 pm

Re: Plazierbares Fahrsilo

Post by XPModder »

So. Ich habe entzwischen das Problem gefunden doch ich weiß nicht wie ich es beheben soll. Aber erstmal das Problem:

Alle Befehle die als Parameter den Index von einem Objekt benutzen, benötigen diesen Index als Integer, also als Ganzzahl. Ein Index-Pfad ist aber ein String, da es ja ein Pfad ist und nicht einfach nur der Index des Objekts. Ich schätze mal die Funktionen sollten eigentlich in der Lage sein den Index aus einem Index-Pfad heraus zu lesen und damit um zu gehen, aber das scheint irgendwie nicht zu funktionieren. Es dürfte aber auch schwierig sein den Index selbst an zu geben, da das Objekt sich ja innerhalb einer Transform Group befindet. Man müsste also erst in die Übergeordnete Transform Group rein und den Befehl quasi innerhalb dieser ausführen.
Ich habe jetzt versucht die Transform Groups zwischen der des Silo (also der die das Skript überhaupt erst aufruft) und der "bunkerSiloArea" zu entfernen wodurch "bunkerSiloArea" zu einem direkten Kind der silo Group wird. Dann habe ich den Index direkt als Zahl in der Lua eingegeben, doch ich bekomme immer noch einen Fehler.

Code: Select all

Warning (LUA): 'getNumOfChildren': Argument 1 has wrong type. Expected: Int. Actual: String 
  ..\..\..\src\base\scripting\lua\LuaScriptSystem.cpp (557): expectedType == Value::VoidType || expectedType == Value::StringType || expectedType == Value::ByteArrayType
LUA call stack:
  =dataS/scripts/utils/Utils.lua (0) : getNumOfChildren
  =dataS/scripts/utils/Utils.lua (0) : checkChildIndex
  =D:/Users/Florian Sluiter/Documents/My Games/FarmingSimulator2017/mods/Fahrsilo3/BunkerSilo.lua (152) : indexToObject
  =dataS/scripts/gui/PlacementScreen.lua (0) : load
  =dataS/scripts/gui/PlacementScreen.lua (0) : loadPlaceable
  =dataS/scripts/gui/elements/GuiElement.lua (0) : raiseCallback
  =dataS/scripts/gui/elements/Gui.lua (0) : onOpen
  =dataS/scripts/gui/ShopScreen.lua (0) : showGui
  =dataS/scripts/gui/ShopScreen.lua (0) : startPlacementMode
  =dataS/scripts/gui/ShopScreen.lua (0) : onBuy
  =dataS/scripts/gui/ShopScreen.lua (0) : onClickOk
  =dataS/scripts/gui/elements/ListElement.lua (0) : raiseCallback
  =dataS/scripts/gui/elements/GuiElement.lua (0) : mouseEvent
  =dataS/scripts/gui/elements/GuiElement.lua (0) : mouseEvent
  =dataS/scripts/gui/elements/GuiElement.lua (0) : mouseEvent
  =dataS/scripts/gui/elements/GuiElement.lua (0) : mouseEvent
  =dataS/scripts/gui/elements/Gui.lua (0) : mouseEvent
  =dataS/scripts/main.lua (0) : mouseEvent
Error: Running LUA method 'mouseEvent'.
Merkwürdig ist auch das der Befehl "getNumOfChildren" gar nicht ausgeführt wird und dieser auch eine nodeId als Parameter nimmt und nicht einen Index.
Ich weiß wirklich nicht was da schief läuft....
Spätestens nach den Änderungen die ich vorgenommen habe sind jetzt wirklich alle Parameter die der Befehl "indexToObject" bekommt im korrekten Format.

Hoffe ihr könnt mir weiterhelfen!

LG
Das Universum ist unvorstellbar groß und wir sind im Vergleich dazu winzig.

Daher kann mir jemand der unter uns Winzlingen Unterschiede in Hautfarbe oder Herkunft sucht, nur Leid tun, weil seine Sichtweise so begrenzt ist!

Fremdenfeindlichkeit ist Menschenfeindlichkeit!
User avatar
modelleicher
Posts: 1575
Joined: Fri Jul 09, 2010 11:10 pm
Location: Hessen
Contact:

Re: Plazierbares Fahrsilo

Post by modelleicher »

Der Index ist der Pfad.. Alle Funktionen später nutzen die Objekt ID, daher gibt es ja die Utils.indexToObject Funktion.

local ObjectID = Utils.indexToObject(Root Transform, index pfad);

Die root Transform ist in dem Fall die Transform (Angabe als object ID) von der der Index-Pfad ausgeht, und der Index Pfad eben der Pfad als String. Rückgabe ist dann die Objekt ID des im Index Pfad angegebenen ;)
Eine Stunde oder Minute ist nur ein winziger Teil unseres gesamten Lebens. Und dennoch sind es die einzelnen Momente, die das Leben lebenswert machen.
Post Reply