<?xml version="1.0" encoding="utf-8"?>
<scriptDocumentation script="AnimatedLivestockTrailer.lua" version="1.0.0.0" game="Farming Simulator 25">
    <summary>
        <description>
            AnimatedLivestockTrailer extends the Giants LivestockTrailer specialization.
            The Giants livestock system is still used for animal clusters, loading, unloading,
            savegame handling and multiplayer sync. This script replaces the static posed animal
            visuals with animated animal visuals that are resolved from the current AnimalSystem.
        </description>
        <mainUseCases>
            <useCase>Normal livestock trailer with animated idle animals.</useCase>
            <useCase>Cattle drovers wagon where animals visually walk on the ground while the vehicle moves.</useCase>
            <useCase>Custom map animal types, as long as they are registered in the map AnimalSystem.</useCase>
        </mainUseCases>
        <importantNotes>
            <note>The normal vehicle.livestockTrailer block must stay in the vehicle XML.</note>
            <note>The vehicle type must include both livestockTrailer and animatedLivestockTrailer specializations.</note>
            <note>Animated animals are visual slot followers, not real moving navmesh husbandry animals.</note>
            <note>Custom animal types are resolved via g_currentMission.animalSystem and their animals.xml data.</note>
        </importantNotes>
    </summary>

    <modDescSetup>
        <specialization name="animatedLivestockTrailer" className="AnimatedLivestockTrailer" filename="scripts/AnimatedLivestockTrailer.lua"/>
        <vehicleTypeExample name="livestockTrailerSpecial" parent="baseTipper">
            <specialization name="livestockTrailer"/>
            <specialization name="animatedLivestockTrailer"/>
        </vehicleTypeExample>
        <vehicleTypeExample name="cattleDroversWagon" parent="baseAttachable">
            <specialization name="livestockTrailer"/>
            <specialization name="animatedLivestockTrailer"/>
        </vehicleTypeExample>
        <vehicleTypeExample name="livestockTrailerPushable" parent="baseDrivable">
            <specialization name="livestockTrailer"/>
            <specialization name="animatedLivestockTrailer"/>
        </vehicleTypeExample>
    </modDescSetup>

    <vehicleXml>
        <requiredBlock name="livestockTrailer">
            <description>
                This is the standard Giants block. It defines loadable animal types, slot nodes and capacities.
                AnimatedLivestockTrailer reads these entries for shop display and visual slot creation.
            </description>
            <attribute path="vehicle.livestockTrailer.animal(?)#type" type="string" required="true">
                <description>Animal type name, for example cow, sheep, pig, horse, chicken, goose, bull, alpaca, milkcow.</description>
            </attribute>
            <attribute path="vehicle.livestockTrailer.animal(?)#node" type="node" required="true">
                <description>Slot root node used by Giants LivestockTrailer. The animated visuals are placed on the same slot nodes.</description>
            </attribute>
            <attribute path="vehicle.livestockTrailer.animal(?)#numSlots" type="integer" required="true">
                <description>Capacity shown in shop and used by Giants livestock logic.</description>
            </attribute>
            <attribute path="vehicle.livestockTrailer.animal(?)#shopTitle" type="string" required="false">
                <description>
                    Optional shop display title or l10n key for this animal type. If missing, the script uses
                    animalType.groupTitle from the current AnimalSystem. FillType titles are only a fallback.
                </description>
                <example><![CDATA[<animal type="alpaca" node="alpacas" numSlots="1" shopTitle="$l10n_shopAnimal_alpacas"/>]]></example>
            </attribute>
        </requiredBlock>

        <requiredBlock name="animatedLivestockTrailer">
            <description>
                Main configuration block for animated visuals, HUD display, sounds, speed animations,
                terrain alignment, age limits and speed limits.
            </description>
            <attribute path="vehicle.animatedLivestockTrailer#enabled" type="bool" default="true">
                <description>Enables or disables animated animal visuals for this vehicle.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#showOnHud" type="bool" default="true">
                <description>Shows animal load information in the right HUD fill level area.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#hudText" type="string" default="">
                <description>Optional HUD text or l10n key. If missing, the script uses a Giants animal text fallback.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#maxLoadedSpeed" type="float" default="">
                <description>Optional maximum vehicle speed in kph while animals are loaded.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#minimumLoadAge" type="integer" default="0">
                <description>Minimum animal age in months. Use 7 to block animals from 0 to 6 months.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#maximumLoadAge" type="integer" default="0">
                <description>Maximum animal age in months. Use 6 to allow only animals from 0 to 6 months.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#filterMissingAnimalTypes" type="bool" default="true">
                <description>Skips livestockTrailer animal entries and per-animal overrides when the current map does not register that animal type.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#unsupportedAgeWarningText" type="l10nString" default="$l10n_warning_animalAgeNotSupportedByTrailer">
                <description>Warning shown when a player tries to load an unsupported animal age.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#alignToTerrain" type="bool" default="true">
                <description>If true, animal visuals are aligned to terrain height instead of staying fixed at slot node height.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#alignToGroundCollisions" type="bool" default="false">
                <description>If true, static collision raycasts are used before falling back to terrain height. Useful for bridges and driveable static surfaces.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#groundRaycastOffset" type="float" default="4">
                <description>Start height above the animal slot for the downward ground collision raycast.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#groundRaycastDistance" type="float" default="12">
                <description>Maximum downward distance for bridge and static collision detection.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#useSpeedAnimations" type="bool" default="true">
                <description>Switches idle, walk and run clips based on vehicle speed. Disable for normal parked-style trailers.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#randomIdleStart" type="bool" default="true">
                <description>Starts idle clips at random offsets so animals do not move synchronously.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#randomMovementStart" type="bool" default="true">
                <description>Starts walk and run clips at random offsets while moving.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#reverseMovementAnimations" type="bool" default="true">
                <description>Plays walk and run animations backwards while reversing.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#groundOffset" type="float" default="0">
                <description>Additional height offset above terrain or slot position.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#walkSpeed" type="float" default="0.5">
                <description>Vehicle speed in kph where the walk animation starts.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#runSpeed" type="float" default="9">
                <description>Vehicle speed in kph where the run animation starts.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#idleClip" type="string" default="idle1Source">
                <description>Default idle clip name.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#walkClip" type="string" default="walkFwdLSource">
                <description>Default walk clip name.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#runClip" type="string" default="runFwdLSource">
                <description>Default run clip name.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#animationSourcePath" type="string" default="">
                <description>Optional node path inside animation i3d used as source character set.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#playbackScale" type="float" default="1">
                <description>Global animation playback multiplier.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#referenceWalkSpeed" type="float" default="4">
                <description>Vehicle speed in kph that maps to 1x walk animation playback.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#referenceRunSpeed" type="float" default="12">
                <description>Vehicle speed in kph that maps to 1x run animation playback.</description>
            </attribute>
        </requiredBlock>

        <animalOverrideBlock name="animatedLivestockTrailer.animal">
            <description>
                Optional per-animal overrides. These entries are only needed when an animal type needs different
                files, clip names, playback settings, HUD text, cage visuals or animation source paths.
            </description>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#type" type="string" required="true">
                <description>Animal type name matching the livestockTrailer animal type.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#filename" type="string" required="false">
                <description>Override animated animal i3d filename.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#animationFilename" type="string" required="false">
                <description>Override animation i3d filename.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#hudText" type="string" required="false">
                <description>Optional animal-specific HUD text or l10n key.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#clipRootPath" type="string" required="false">
                <description>Override node path inside loaded animal i3d that owns the character set.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#animationSourcePath" type="string" required="false">
                <description>Node path inside animation i3d used as source character set.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#idleClip" type="string" default="idle1Source">
                <description>Idle clip for this animal type.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#walkClip" type="string" default="walkFwdLSource">
                <description>Walk clip for this animal type.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#runClip" type="string" default="runFwdLSource">
                <description>Run clip for this animal type.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#randomIdleStart" type="bool" default="true">
                <description>Overrides random idle start for this animal type.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#randomMovementStart" type="bool" default="true">
                <description>Overrides random walk/run start for this animal type.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#reverseMovementAnimations" type="bool" default="true">
                <description>Overrides reverse movement animation behavior for this animal type.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#playbackScale" type="float" default="1">
                <description>Playback multiplier for this animal type.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#referenceWalkSpeed" type="float" default="4">
                <description>Walk reference speed for this animal type.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#referenceRunSpeed" type="float" default="12">
                <description>Run reference speed for this animal type.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#visualMode" type="string" default="animal">
                <description>Use animal for normal per-slot visuals or cage for grouped poultry cage visuals.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#cageFilename" type="filename" required="false">
                <description>Cage i3d filename, resolved relative to the mod directory.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#cageSlotNode" type="node" required="false">
                <description>Optional vehicle transform group containing cage placement slots. If missing, normal livestock slots are used with cageSlotStep.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#cageAnimalSlotsPath" type="string" default="animalSlots">
                <description>Node path inside the loaded cage i3d that contains the inner animal slots.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#animalsPerCage" type="integer" default="4">
                <description>Number of real loaded animals represented by one visible cage.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#cageSlotStep" type="integer" default="4">
                <description>Fallback spacing between normal livestock slots used as cage positions when no cageSlotNode is configured.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer.animal(?)#cageAnimalMode" type="string" default="animated">
                <description>Use animated to load idle animals into the cage, or none to show only the cage.</description>
            </attribute>
            <example><![CDATA[<animatedLivestockTrailer alignToTerrain="false">
    <animal type="chicken"
            visualMode="cage"
            cageFilename="objects/poultryBox.i3d"
            cageAnimalSlotsPath="animalSlots"
            animalsPerCage="4"
            cageSlotStep="4"
            cageAnimalMode="animated"/>
</animatedLivestockTrailer>]]></example>
        </animalOverrideBlock>

        <soundOptions>
            <attribute path="vehicle.animatedLivestockTrailer#useAnimalSounds" type="bool" default="true">
                <description>Plays random animal voice samples while animals are loaded.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#animalSoundNode" type="node" default="">
                <description>Optional shared sound source node. If missing, the trailer root is used.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#animalSoundVolumeScale" type="float" default="0.25">
                <description>Volume scale for random animal voice samples.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#animalSoundMinInterval" type="integer" default="8000">
                <description>Fallback minimum random animal voice interval in milliseconds.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#animalSoundMaxInterval" type="integer" default="22000">
                <description>Fallback maximum random animal voice interval in milliseconds.</description>
            </attribute>
            <attribute path="vehicle.animatedLivestockTrailer#animalSoundMinimumInterval" type="integer" default="3500">
                <description>Hard minimum interval after crowd scaling in milliseconds.</description>
            </attribute>
        </soundOptions>

        <beddingOptions>
            <description>
                Bedding logic from the former LivestockTrailerSpecial script is integrated in AnimatedLivestockTrailer.
                Straw bales can be converted to a configured fill type while animals are loaded.
            </description>
            <attribute path="vehicle.livestockTrailer.baleTrigger#node" type="node" required="false">
                <description>Bale trigger node.</description>
            </attribute>
            <attribute path="vehicle.livestockTrailer.baleTrigger#inputLitresPerSecond" type="float" default="100">
                <description>Bale delete litres per second.</description>
            </attribute>
            <attribute path="vehicle.livestockTrailer.baleTrigger#fillUnitIndex" type="integer" default="1">
                <description>Target fill unit index.</description>
            </attribute>
            <attribute path="vehicle.livestockTrailer.bedding#minimumAnimals" type="integer" default="1">
                <description>Minimum number of animals needed to start conversion.</description>
            </attribute>
            <attribute path="vehicle.livestockTrailer.bedding#conversionSeconds" type="integer" default="60">
                <description>Conversion time in seconds when carrying the minimum number of animals.</description>
            </attribute>
            <attribute path="vehicle.livestockTrailer.bedding#fillType" type="string" default="STRAW">
                <description>Input bedding fill type.</description>
            </attribute>
            <attribute path="vehicle.livestockTrailer.bedding#convertedFillType" type="string" default="MANURE">
                <description>Output fill type.</description>
            </attribute>
        </beddingOptions>
    </vehicleXml>

    <shopDisplay>
        <description>
            The script patches the shop detail display. Static white Giants animal icons are removed for animated
            trailers and replaced with the animal FillType HUD icons. The capacity text is shown below the animal title.
        </description>
        <titleResolutionOrder>
            <step>vehicle.livestockTrailer.animal(?)#shopTitle, if defined.</step>
            <step>animalType.groupTitle from g_currentMission.animalSystem.</step>
            <step>FillType title of the first registered subtype.</step>
            <step>The raw animal type name.</step>
        </titleResolutionOrder>
        <iconResolution>
            <step>Resolve animal type via g_currentMission.animalSystem:getTypeByName(type).</step>
            <step>Use the first subtype's fillTypeIndex.</step>
            <step>Use g_fillTypeManager:getFillTypeByIndex(fillTypeIndex).hudOverlayFilename.</step>
            <step>Fallback to g_fillTypeManager:getFillTypeIndexByName(string.upper(type)).</step>
        </iconResolution>
    </shopDisplay>

    <hudDisplay>
        <description>
            The script appends an animal fill-level entry to the right HUD fill display. It behaves similar to a FillUnit
            entry, using an animal/filltype icon and a filled-count against total-capacity ratio.
        </description>
        <unitText>Uses Giants unit_pieces text for counts.</unitText>
        <textSource>Uses configured hudText, animal-specific hudText or Giants/localized animal text fallback.</textSource>
    </hudDisplay>

    <animalAssetResolution>
        <description>
            The script uses the current AnimalSystem, so map-specific animal types and subtypes can work without
            hard-coded type lists. Visuals are resolved through the current animal visual for the loaded animal age.
        </description>
        <requirements>
            <requirement>The animal type must be registered in g_currentMission.animalSystem.</requirement>
            <requirement>The standard livestockTrailer entry must use that animal type.</requirement>
            <requirement>The animal config filename must point to an animals.xml style file.</requirement>
            <requirement>Visual entries should provide assets#filename, assets#filenamePosed, assets#animation and assets#skeletonIndex.</requirement>
            <requirement>locomotion#filename should reference a locomotion XML that references an animation XML.</requirement>
        </requirements>
        <clipFallbacks>
            <clipGroup name="idle">idle1Source, idleSource, idle01Source, idleBabySource</clipGroup>
            <clipGroup name="walk">walkFwdLSource, walkFwdSource, walkFwdLBabySource, walkFwdBabySource, trotFwdLSource, trotFwdSource, trotFwdLBabySource, trotFwdBabySource, trotFwdBabyLSource</clipGroup>
            <clipGroup name="run">runFwdLSource, runFwdSource, runFwdLBabySource, runFwdBabySource, trotFwdLSource, trotFwdSource, trotFwdLBabySource, trotFwdBabySource, trotFwdBabyLSource, walkFwdLSource, walkFwdSource, walkFwdLBabySource, walkFwdBabySource</clipGroup>
        </clipFallbacks>
    </animalAssetResolution>

    <ageRules>
        <description>
            Age rules are checked when animals are moved from dealer, farm husbandry or trailer source lists.
            A blocked animal shows unsupportedAgeWarningText.
        </description>
        <example name="cattleDroversWagonOnlyOlderAnimals">
            <code><![CDATA[
<animatedLivestockTrailer minimumLoadAge="7"
                          unsupportedAgeWarningText="$l10n_warning_animalAgeNotSupportedByTrailer"/>
            ]]></code>
        </example>
        <example name="oldAnimalTrailerOnlyYoungAnimals">
            <code><![CDATA[
<animatedLivestockTrailer maximumLoadAge="6"
                          unsupportedAgeWarningText="$l10n_warning_animalAgeNotSupportedByTrailer"/>
            ]]></code>
        </example>
        <rule>minimumLoadAge less than or equal to 0 means no minimum age check.</rule>
        <rule>maximumLoadAge less than or equal to 0 means no maximum age check.</rule>
        <rule>If both are set, the animal age must be inside the inclusive range.</rule>
    </ageRules>

    <examples>
        <example name="normalTrailerIdleAnimals">
            <description>Recommended for normal livestock trailers where animals should be animated but not walk with vehicle speed.</description>
            <code><![CDATA[
<livestockTrailer>
    <animal type="cow" node="cows" numSlots="5"/>
    <animal type="sheep" node="sheeps" numSlots="12"/>
</livestockTrailer>

<animatedLivestockTrailer alignToTerrain="false"
                          useSpeedAnimations="false"
                          randomIdleStart="true"
                          showOnHud="true"
                          useAnimalSounds="true"/>
            ]]></code>
        </example>
        <example name="cattleDroversWagon">
            <description>Recommended for the cattle drovers wagon where animals run visually on the ground.</description>
            <code><![CDATA[
<livestockTrailer>
    <animal type="cow" node="cows" numSlots="6"/>
    <animal type="sheep" node="sheeps" numSlots="12"/>
    <animal type="horse" node="horses" numSlots="6"/>
</livestockTrailer>

<animatedLivestockTrailer alignToTerrain="true"
                          alignToGroundCollisions="true"
                          groundRaycastOffset="4"
                          groundRaycastDistance="12"
                          useSpeedAnimations="true"
                          randomIdleStart="true"
                          randomMovementStart="true"
                          reverseMovementAnimations="true"
                          minimumLoadAge="7"
                          maxLoadedSpeed="7"
                          groundOffset="0.00"
                          walkSpeed="0.5"
                          runSpeed="9"
                          referenceWalkSpeed="4"
                          referenceRunSpeed="12"/>
            ]]></code>
        </example>
        <example name="oldAnimalTrailerYoungAnimalsOnly">
            <description>Recommended for the old small animal trailer where only young animals up to 6 months should fit.</description>
            <code><![CDATA[
<animatedLivestockTrailer alignToTerrain="false"
                          useSpeedAnimations="false"
                          maximumLoadAge="6"
                          unsupportedAgeWarningText="$l10n_warning_animalAgeNotSupportedByTrailer"
                          randomIdleStart="true"
                          showOnHud="true"
                          useAnimalSounds="true"/>
            ]]></code>
        </example>
        <example name="perAnimalOverride">
            <description>Use when a custom animal type needs special clips, files or title text.</description>
            <code><![CDATA[
<livestockTrailer>
    <animal type="alpaca" node="alpacas" numSlots="1" shopTitle="$l10n_shopAnimal_alpacas"/>
</livestockTrailer>

<animatedLivestockTrailer useSpeedAnimations="true">
    <animal type="alpaca"
            idleClip="idle1Source"
            walkClip="walkFwdLSource"
            runClip="runFwdLSource"
            referenceWalkSpeed="4"
            referenceRunSpeed="12"/>
</animatedLivestockTrailer>
            ]]></code>
        </example>
    </examples>

    <runtimeBehavior>
        <flow name="load">
            <step>onLoad reads vehicle.animatedLivestockTrailer options.</step>
            <step>The script maps normal livestockTrailer animal entries to current AnimalSystem type indices.</step>
            <step>Animal visual configs are loaded lazily per visual filename and cached.</step>
        </flow>
        <flow name="updateAnimals">
            <step>When Giants LivestockTrailer updates clusters, the script clears old animated visuals.</step>
            <step>For each occupied slot, the script resolves the animal visual by age and subtype.</step>
            <step>The animated i3d is loaded and placed on the slot node.</step>
            <step>On each update, visuals follow their slot node and optionally terrain height.</step>
            <step>Animation state switches between idle, walk and run depending on vehicle speed.</step>
        </flow>
        <flow name="sounds">
            <step>Sound groups are read from the animal animals.xml.</step>
            <step>The script chooses the configured yell sound group or a voice/yell/call fallback group.</step>
            <step>One shared random sound source is used instead of one sound per slot.</step>
        </flow>
    </runtimeBehavior>

    <knownLimitations>
        <limitation>Animals do not navigate independently. They visually follow slot positions.</limitation>
        <limitation>Bad or missing animal XML data can still require per-animal overrides.</limitation>
        <limitation>Shop icons depend on the animal FillType having a valid hud icon.</limitation>
        <limitation>Shop title uses animalType.groupTitle by default, not the specific FillType breed/color title.</limitation>
    </knownLimitations>
</scriptDocumentation>
