Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

New! Update 0.6.4 - Modding Changes

Discussion in 'Modding' started by Drui, Aug 28, 2018.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. Drui Keen Update Guy Staff

    Messages:
    1,389
    Modding Update Banner.jpg
    The new systems

    With 0.6.4 we are introducing a new way of managing visual inventory as well as subparts like doors. The new ModelAttachmentComponent, AttachmentAnimationComponent, and VisualInventoryComponent are replacing the old CubeBlockSubpartComponent, SubpartAnimationComponent, and StockpileComponent respectively. This guide provides the basic transition manual for changing your old blocks into the new format so that your mods are future proof. Please note that 0.6.4 will support both the old system and the new system at the same time. When we release 0.7 the old system will no longer be supported, and will be removed from the game.


    MyModelAttachmentComponent

    The first component that is being replaced is the MyCubeBlockSubpartComponent. It is superseded by the MyModelAttachmentComponent and the new definition looks like this:
    HTML:
    <Definition xsi:type="MyObjectBuilder_ModelAttachmentComponentDefinition">
    	<Id Type="ModelAttachmentComponent" Subtype="ExampleDefinition" />
    	<Attachment Name="Name_For_Attachment_Point" Bone="BoneName">
    		<Offset x="0.075" y="-0.117" z="-0.625" />
    		<Rotation x="23" y="0" z="0" />
    		<DefaultEntity Type="EntityBase" Subtype="DoorWoodRound" />
    	</Attachment>
    	<DisableDynamicPhysics>true</DisableDynamicPhysics>
    </Definition>
    It looks very similar, and that's because it is very similar. But don't let that fool you, the model attachment component while similar, is conceptually quite different.

    The first important difference is that the old MyCubeBlockSubpartComponent could only be added to blocks. The MyModelAttachmentComponent can be added to any entity. This allows us to attach anything to anything in a general fashion, rather than having to rely on different systems for different things.

    The second important difference is that it no longer automatically creates the subpart entities from a MyEntitySubpart, but instead primarily acts as a collection of attachment points for other entities to be attached to. You can still have it automatically create and attach an entity, but you will have to specify the entity to create.

    Note to scripters: Keep in mind that these entities are not replicated over the network! These entities only exist locally, so be mindful of this. The entity Id on a client will be different from the entity Id on another client or the server.


    Each attachment point has a couple of important values you can set. First, there is the Name attribute. This is the identifier for the attachment point, and this name should be unique for the component. Then, there is the Bone attribute. This is the bone in the model to put the attachment point onto. You can leave this blank, or not even specify it, in which case the attachment point will place itself to the center of whatever entity it is used for.

    Then it has three fields. First, Offset specifies in local coordinate meters the offset from the bone, or the center of the block if the bone is not specified. Second, there is Rotation, this is in degrees a rotation offset to the bone, or the center of the block if the bone is not specified. Finally, there is DefaultEntity, which will create a default entity and attaches it to the attachment point automatically.

    Last but not least, besides attachment points themselves, you can specify whether or not the entities should have physics when the parent object become dynamic. This is set to true by default, and this is very important. When you set this to false there is the possibility for the objects to collide with the parent, which can cause really inconsistent physics behaviour and flying castles. We recommend leaving this either unspecified (defaults to true) or set to true, but for the exceptional case where this is not a problem, you can set it to false.

    Examples: Each entity specified in the DefaultEntity field should be fully specified and referenced to its entity container definition. You can find an example in Contents/Data/CubeBlocks/Doors/DoorBase.sbc and Contents/Data/CubeBlocks/Doors/AnimatedParts.sbc, where we set up doors using our definition inheritance structure.


    MyAttachmentAnimationComponent

    Finally, the MySubpartAnimationComponent has been replaced by the MyAttachmentAnimationComponent. This component is also very similar, but there is an important change in how the animations are set up.
    HTML:
    <Definition xsi:type="MyObjectBuilder_AttachmentAnimationComponentDefinition">
    	<Id Type="AttachmentAnimationComponent" Subtype="ExampleAnimationDefinition" />
    	<Sequence Name="Open" WrapMode="Once">
    		<Event Time="0.0" Name="DoorOpening" />
    		<Event Time="0.1" Name="DoorMoving" />
    		<Event Time="1.2" Name="DoorOpened" />
    		
    		<Animation AttachmentPoint="Door">
    			<Key Time="0">
    				<Interpolation Method="QuadraticEaseIn" />
    				<OrientationEuler x="-90" y="0" z="0" />
    			</Key>
    			<Key Time="1.2">
    				<OrientationEuler x="0" y="0" z="0" />
    			</Key>
    		</Animation>
    	</Sequence>
    	<Sequence Name="Close" WrapMode="Once">
    		<Event Time="0.0" Name="DoorClosing" />
    		<Event Time="0.1" Name="DoorMoving" />
    		<Event Time="1.2" Name="DoorClosed" />
    		
    		<Animation AttachmentPoint="Door">
    			<Key Time="0">
    			<Interpolation Method="QuadraticEaseIn" />
    			<OrientationEuler x="0" y="0" z="0" />
    			</Key>
    			<Key Time="1.2">
    			<OrientationEuler x="-90" y="0" z="0" />
    			</Key>
    		</Animation>
    	</Sequence>
    </Definition>
    The main difference here is that the animations are now keyframed, rather than defined as translations and rotations. For each attachment point you wish to animate you have to create a set of keyframes with times and you can specify how it will interpolate during that key to the next key, what the final orientation will be like, and what the final position will be like.

    One obvious drawback to keyframed animations are full rotations. Rather than specifying a 360 degree rotation in one step, as was previously possible, you now specify the absolute rotation of the object. The game then interpolates between the keyframes, and if the absolute rotation is the same value for both keyframes, no rotation occurs. This situation occurs specifically for full rotations, an orientation of 0 degrees is mathematically identical to an orientation of 360 degrees, and so nothing will happen. The easiest way to resolve this is to break down the rotation into steps of less than 180 degrees, examples of this can be found in the mechanical blocks SBCs.

    Examples: Rather than explaining how this component is set up, as it has quite a few fields, it is best to look at examples from us, you can look into Content/Data/CubeBlocks/Doors/DoorBase.sbc for multiple examples.


    MyVisualInventoryComponent

    The next component that was changed is the MyStockpileComponent. It will now be called MyVisualInventoryComponent and it is very similar to the old component but provides a couple of little tweaks that allow greater freedom of functionality.
    HTML:
    <Definition xsi:type="MyObjectBuilder_VisualInventoryComponentDefinition">
    	<Id Type="VisualInventoryComponent" Subtype="ExampleDefinition" />
    	<Mapping Inventory="InventoryA" Slot="0" AttachmentPoint="Inventory_Slot_00" />
    	<Mapping Inventory="InventoryA" Slot="1" AttachmentPoint="Inventory_Slot_01" />
    	<Mapping Inventory="InventoryB" Slot="0" AttachmentPoint="Inventory_Slot_02" />
    </Definition>
    You no longer need to specify the name format, or the amount of objects. Instead, you create a mapping for inventory and inventory slot to attachment point. Each mapping has only 3 attributes, Inventory, Slot and AttachmentPoint. Inventory is the name of the inventory on the entity that you wish to use. If the entity has only 1 inventory you can leave this unspecified and it will use the default inventory. Slot is the index to the list of item slots in the inventory to map to. Finally, AttachmentPoint is the name of the attachment point as specified in the MyModelAttachmentComponent.

    If you specify default entities on the MyModelAttachmentComponent for attachment points specified by the MyVisualInventoryComponent it will try to use these. If it cannot find a MyModelComponent on this entity, or if there is no default entity, the MyVisualInventoryComponent will create a custom entity by itself that will only contain a model component.

    Examples: Examples can be found in Contents/Data/CubeBlocks/Storage, such as the ShelfWood.sbc and the WeaponRack.sbc. For an example with different inventories, look at Contents/Data/CubeBlocks/Production/Kiln.sbc or Contents/Data/CubeBlocks/Mechanical/Sinks/SawmillMechanical.sbc.


    Updated/Expanded systems

    Entity effects

    With 0.6.4 we also introduce several new effects. Some of these are very specific to solve design challenges we encountered, others have a more broad purpose and are, for sure, bound to be useful to the modding community as well.


    Entity Effect Base

    Some minor additions were made to the entity effects, they now support ActivationSound, DeactivationSound and ActivationMode.

    Here’s how it roughly fits together in a definition:
    HTML:
    <Definition xsi:type="MyObjectBuilder_EntityEffectDefinition">
    	<Id Type="EntityEffect" Subtype="ExampleEffect" />
    	<ActivationMode>Ignore</ActivationMode>
    	<ActivationSound RemoveOnDeactivate="true">HudStun</ActivationSound>
    	<DeactivationSound>HudStun</DeactivationSound>
    </Definition>
    ActivationMode supports 2 values, Ignore and ResetDuration. If left blank it will default to ResetDuration. If it is set to ResetDuration, adding this effect to a character multiple times will reset the duration every time it is applied. If you set it to Ignore applying the effect again will leave the original duration alone, resulting in no change to the character.
    ActivationSound and DeactivationSound are sound effects played only for the player controlling the character the effect is applied to. You can flag the ActivationSound to be stopped when the effect is ended by setting RemoveOnDeactivate to true, if left blank it defaults to false.


    Scaled Audio Effect

    Always wanted to play a sound that changes volume based on a stat? We did, so we added an effect for this. We are using it for the heartbeat sound when you gain adrenaline after a successful block in combat.

    The definition looks like this:
    HTML:
    <Definition xsi:type="MyObjectBuilder_ScaledAudioEffectDefinition">
    	<Id Type="ScaledAudioEffect" Subtype="AudioExample" />
    	<Public>false</Public>
    	<Stat>Stamina</Stat>
    	<AudioCue>GearRotor</AudioCue>
    	<VolumeMin>5</VolumeMin>
    	<VolumeMax>0</VolumeMax>
    	<Exponential>true</Exponential>
    </Definition>
    Stat is used to identify the stat it maps to.
    AudioCue is the audio cue that is played when this effect is activated. It is stopped when the effect is deactivated. We recommend you set a looping sound, otherwise the effect will not work well.
    VolumeMin is the minimum volume the sound will be played at, this will be when the stat percentage is at 0%.
    VolumeMax is the maximum volume the sound will be played at, this will be when the stat percentage is at 100%.
    Exponential is an additional setting that makes the percentage grow exponentially, creating a nice curve in volume. It is implemented as percentage * percentage, where the percentage goes from 0 to 1, rather than 0% to 100%.


    Scaled FOV Effect

    This effect functions very similar to the scaled audio effect. It applies FOV scaling to the first and third person camera according to the percentage of the stat.

    The definition looks like this:
    HTML:
    <Definition xsi:type="MyObjectBuilder_ScaledFOVEffectDefinition">
    	<Id Type="ScaledFOVEffect" Subtype="FOVExample" />
    	<Public>false</Public>
    	<Stat>Stamina</Stat>
    	<FOVMin>0.8</FOVMin>
    	<FOVMax>1.0</FOVMax>
    	<Exponential>true</Exponential>
    </Definition>
    Stat is used to identify the stat it maps to.
    FOVMin is the minimum fov multiplier that is sent to the camera controller, this will be when the stat percentage is at 0%.
    FOVMax is the maximum fov multiplier that is sent to the camera controller, this will be when the stat percentage is at 100%.
    Exponential is an additional setting that makes the percentage grow exponentially, creating a nice curve in fov. It is implemented as percentage * percentage, where the percentage goes from 0 to 1, rather than 0% to 100%.


    Scaled Tool Efficiency Effect

    Another one of the scaled effects, this one scales the tool efficiency multiplier to the percentage of the stat. It works similarly to the ToolEfficiencyEffect, but its strength scales to the stat.

    The definition looks like this:
    HTML:
    <Definition xsi:type="MyObjectBuilder_ScaledToolEfficiencyEffectDefinition">
    	<Id Type="ScaledToolEfficiencyEffect" Subtype="EfficiencyExample" />
    	<Public>false</Public>
    	<Stat>Stamina</Stat>
    	<AffectedTool>HammerBuilding</AffectedTool>
    	<AffectedTool>AxeCutting</AffectedTool>
    	<AffectedTool>Shovel</AffectedTool>
    	<AffectedTool>Pickaxe</AffectedTool>
    	<AffectedTool>WeaponMelee</AffectedTool>
    	<EfficiencyMin>2.0</EfficiencyMin>
    	<EfficiencyMax>1.0</EfficiencyMax>
    	<Exponential>true</Exponential>
    </Definition>
    Stat is used to identify the stat it maps to.
    AffectedTool can exist multiple times, and it describes a tag of a tool that the effect applies to.
    EfficiencyMin is the minimum efficiency multiplier applied to the equipped tools, this will be when the stat percentage is at 0%.
    EfficiencyMax is the maximum efficiency multiplier applied to the equipped tools, this will be when the stat percentage is at 100%.
    Exponential is an additional setting that makes the percentage grow exponentially, creating a nice curve in speed. It is implemented as percentage * percentage, where the percentage goes from 0 to 1, rather than 0% to 100%.


    Operation Trigger Effect

    Despite its funny name, the operation trigger effect allows some quite powerful tricks. It can allow you to trigger effects when other effects are triggered, introduce timed delays, or prevent the addition of specific effects.

    One obvious example is, an antidote that protects you against poison. By adding an Added effect trigger on the category poison you can remove effects with the poison category, and then remove the antidote effect itself as well.

    This effect is probably the most requested effect by the modders that have worked with the effects system, as it allows for really interesting effect interplay.

    The definition looks like this:
    HTML:
    <Definition xsi:type="MyObjectBuilder_OperationTriggerEffectDefinition">
    	<Id Type="OperationTriggerEffect" Subtype="OperationExample" />
    	<Public>false</Public>
     
    	<!-- Activation effects -->
    	<Activation Type="CompositeEntityEffect" Subtype="Stagger" Operation="Add" />
    	<Activation Type="HealthEffect" Subtype="AdrenalineGain" Operation="Add" />
     
    	<!-- Deactivation effects -->
    	<Deactivation Type="CompositeEntityEffect" Subtype="Stagger" Operation="Add" />
    	<Deactivation Type="HealthEffect" Subtype="AdrenalineGain" Operation="Add" />
     
    	<!-- Addition of effects -->
    	<Added>
    		<EffectId Type="HealthEffect" Subtype="AdrenalineGain" />
    		<Operation Type="CompositeEntityEffect" Subtype="Stagger" Operation="Add" />
    		<Operation Type="HealthEffect" Subtype="AdrenalineGain" Operation="Add" />
    	</Added>
    	<Added>
    		<EffectCategory>Adrenaline</EffectCategory>
    		<Operation Type="CompositeEntityEffect" Subtype="Stagger" Operation="Add" />
    		<Operation Type="HealthEffect" Subtype="AdrenalineGain" Operation="Add" />
    	</Added>
     
    	<!-- Removal of effects -->
    	<Removed>
    		<EffectId Type="HealthEffect" Subtype="AdrenalineGain" />
    		<Operation Type="CompositeEntityEffect" Subtype="Stagger" Operation="Add" />
    		<Operation Type="HealthEffect" Subtype="AdrenalineGain" Operation="Add" />
    	</Removed>
    	<Removed>
    		<EffectCategory>Adrenaline</EffectCategory>
    		<Operation Type="CompositeEntityEffect" Subtype="Stagger" Operation="Add" />
    		<Operation Type="HealthEffect" Subtype="AdrenalineGain" Operation="Add" />
    	</Removed>
    </Definition>
    Activation can exist multiple times, and it is an Effect Operation. These Activation operations are performed when the OperationTriggerEffect is added on a character.
    Deactivation can exist multiple times, and it is an Effect Operation. These Deactivation operations are performed when the EffectOperationEffect is removed from a character.
    Added can exist multiple times, and it is a special effect trigger. These Added triggers will be checked every time any effect is added to the character while the OperationTriggerEffect is active. It checks if the newly added effect matches either EffectId or EffectCategory, and if this is true it will perform all the listed Operations.
    Removed can exist multiple times, and it is a special effect trigger. These Removed triggers will be checked every time any effect is removed from the character while the OperationTriggerEffect is active. It checks if the removed effect matches either EffectId or EffectCategory, and if this is true it will perform all the listed Operations.

    Triggers have the following fields:
    EffectId indicates the specific effect to trigger on, if left blank it is not evaluated.
    EffectCategory indicates the effect category to trigger on, if left blank it is not evaluated.
    Operation can exist multiple times, and it is an Effect Operation. These effect operations are performed when the trigger meets its conditions.

    Since this effect is kind of complicated, let us show a couple of simplified examples:
    Performing operations when the operation trigger effect is applied:
    HTML:
    <Definition xsi:type="MyObjectBuilder_OperationTriggerEffectDefinition">
    	<Id Type="OperationTriggerEffect" Subtype="ActivationExample" />
    	<Activation Type="DamageOverTimeEffect" Subtype="Burning" Operation="Add" />
    	<Activation Type="DamageOverTimeEffect" Subtype="Bleeding" Operation="Remove" />
    </Definition>
    When "ActivationExample" gets activated, it adds "Burning" and removes "Bleeding".

    Performing operations when the operation trigger effect is removed:
    HTML:
    <Definition xsi:type="MyObjectBuilder_OperationTriggerEffectDefinition">
    	<Id Type="OperationTriggerEffect" Subtype="DeactivationExample" />
    	<Deactivation Type="DamageOverTimeEffect" Subtype="Bleeding" Operation="Add" />
    	<Deactivation Type="DamageOverTimeEffect" Subtype="Burning" Operation="Remove" />
    </Definition>
    When "DeactivationExample" gets removed, it adds "Bleeding" and removes "Burning".

    Performing operations when a specific effect is added while the operation trigger effect is active:
    HTML:
    <Definition xsi:type="MyObjectBuilder_OperationTriggerEffectDefinition">
    	<Id Type="OperationTriggerEffect" Subtype="AdditionExample1" />
    	<Added>
    		<EffectId Type="CompositeEntityEffect" Subtype="Stun" />
    		<Operation Type="DamageOverTimeEffect" Subtype="Bleeding" Operation="Add" />
    		<Operation Type="DamageOverTimeEffect" Subtype="Burning" Operation="Remove" />
    	</Added>
    </Definition>
    While "AdditionExample1" is applied to the character, it adds "Bleeding" and removes "Burning, when "Stun" gets activated.


    FOVEffect

    We also added an FOV effect, allowing you to alter the FOV of the camera when an effect is added to the character. We use this, for example, on the crossbow’s iron sight zoom mode.

    The definition looks like this:
    HTML:
    <Definition xsi:type="MyObjectBuilder_FOVEffectDefinition">
    	<Id Type="FOVEffect" Subtype="SprintFOV" />
    	<FirstPersonFOVMultiplier>1.05</FirstPersonFOVMultiplier>
    	<ThirdPersonFOVMultiplier>1.05</ThirdPersonFOVMultiplier>
    </Definition>
    FirstPersonFOVMultiplier is a multiplier on the players’ FOV settings, and applies only to the first person camera. If left blank the first person camera is not affected.
    ThirdPersonFOVMultiplier is a multiplier on the players’ FOV settings, and applies only to the third person camera. If left blank the third person camera is not affected.


    PreventionEffect

    The prevention effect allows you to prevent certain effects from being applied to an entity. We use this, for example, to create a protection from getting chain stunned.

    The definition looks like this:
    HTML:
    <Definition xsi:type="MyObjectBuilder_PreventionEffectDefinition">
      <Id Type="PreventionEffect" Subtype="StunResist" />
      <DisplayName>DisplayName_StatusEffect_StunResist</DisplayName>
      <Duration Seconds="5" />
      <PreventedEffect Type="CompositeEntityEffect" Subtype="Stun" />
      <PreventedCategory>Stun</PreventedCategory>
    </Definition>
    PreventedEffect allows you to prevent a specific effect from triggering on the entity.
    PreventedCategory allows you to prevent all effects with a shared category from triggering on the entity.



    Animation Effect

    With the combat we needed some more complicated animation support, like triggering the combat stance, or the stun animation. So we introduced the animation effect which allows you to set variables on the animation controller, as well as trigger triggers.

    The definition looks like this:
    HTML:
    <Definition xsi:type="MyObjectBuilder_AnimationEffectDefinition">
    	<Id Type="AnimationEffect" Subtype="ExampleAnimationEffect" />
    	<Public>false</Public>
    	<Variable>in_combat</Variable>
    	<ActivationValue>1</ActivationValue>
    	<DeactivationValue>0</DeactivationValue>
    	<ActivationTrigger>took_damage</ActivationTrigger>
    	<DeactivationTrigger>you_blocked_attack</DeactivationTrigger>
    </Definition>
    Variable contains the name of the variable to set on the animation controller of the entity whom this effect is added to. This field is optional, if it is not set no variable values will be set.
    ActivationValue is the numerical value set for the variable when the effect is added to the character. This field is optional, if it is not there the variable is not changed on activation.
    DeactivationValue is the numerical value set for the variable when the effect is removed from the character. This field is optional, if it is not there the variable is not changed on deactivation.
    ActivationTrigger is the name of the trigger to be triggered when the effect is added to the character. This field is optional, if it is not there no trigger is fired on activation.
    DeactivationTrigger is the name of the trigger to be triggered when the effect is removed from the character. This field is optional, if it is not there no trigger is fired on deactivation.


    Movement Speed Effect

    This effect was introduced in 0.6.3, but in 0.6.4 we updated it a bit further. It now supports affecting different movement states, such as only affecting the jog, or the sprint.


    Effect Operation

    In 0.6.3 we introduced effect operations, but these were never fully explained. So to give you the missing information, here is the full scoop on the Effect Operations. These are used, for example, on the phantom effect component on the campfire, the combat component’s staggered effects, and the operation trigger effect makes use of them as well.

    Effect operations perform the addition, removal or replacement of effects on a character, it is possible to specify the operation type (Add, Remove, Replace) and the effect or category to add, remove or replace.

    The definition entry looks something like this:
    HTML:
    <Operation Type="DamageOverTimeEffect" Subtype="Burning" Operation="Add" Chance="0.5">
    	<Delay Seconds="2" />
    	<ReplaceEffect Type="DamageOverTimeEffect" Subtype="BurningInFireplace"/>
    </Operation>
    I added all possible variables here for clarity, not all of them are required for this effect to function, in fact, most effect operations we created ourselves only contain some of them.

    The main Type and Subtype specify the effect to combine with the operation.
    Operation can be set to Add, Remove and Replace. Add simply adds the specified effect to the character. Remove removes the specified effect from the character, and Replace will try to remove the specified effect and if it succeeds it will add the effect specified by the ReplaceEffect child element.
    In addition to Type and Subtype, if you use the Remove or Replace operation you can instead specify Category, and remove, or replace, an effect from the specified category.
    Chance is a chance that this effect operation will be performed. If it is set to 0, there is no chance it will trigger, and if it is set to 1 it will guaranteed be triggered. Any value in between is a random chance it may happen. This field is optional, if you don’t specify it it will be considered as if you had set it to 1.
    Delay is a time definition and it will introduce a delayed time before the operation is performed. This field is optional, if you don’t specify it the operation will be performed immediately.

    Some examples to showcase various ways of using effect operations:

    Adding an effect:
    HTML:
    <Operation Type="DamageOverTimeEffect" Subtype="Burning" Operation="Add" />
    Adding an effect with a 2 second delay:
    HTML:
    <Operation Type="DamageOverTimeEffect" Subtype="Burning" Operation="Add">
    	<Delay Seconds="2" />
    </Operation>
    Adding an effect with a 50% chance:
    HTML:
    <Operation Type="DamageOverTimeEffect" Subtype="Burning" Operation="Add" Chance="0.5" />
    Removing a specific effect:
    HTML:
    <Operation Type="DamageOverTimeEffect" Subtype="Burning" Operation="Remove"/>
    Removing an effect by category:
    HTML:
    <Operation Category="Bleeding" Operation="Remove" />
    Removing an effect by category, with a 2 second delay:
    HTML:
    <Operation Category="Bleeding" Operation="Remove">
    	<Delay Seconds="2" />
    </Operation>
    Replacing a specific effect with another effect
    HTML:
    <Operation Type="DamageOverTimeEffect" Subtype="Burning" Operation="Replace">
    	<ReplaceEffect Type="DamageOverTimeEffect" Subtype="Bleeding" />
    </Operation>
    Replacing an effect by category with another effect
    HTML:
    <Operation Category="Bleeding" Operation="Replace">
    	<ReplaceEffect Type="DamageOverTimeEffect" Subtype="Burning" />
    </Operation>

    General Cleanup

    Projectiles

    Ammo Definition has been merged with Projectile Ammo Definition and no longer exists. Functionality was not removed, but unused variables have been cleaned up. Additionally, projectiles now deal damage based on their velocity, faster moving projectiles deal more damage. A velocity damage multiplier was added to the projectile ammo definition to change how much velocity affects the damage. Setting this value to 0 means projectiles deal 0 damage.

    Inventories

    Inventories now have to explicitly state they want to be used in Area Inventory. Add
    HTML:
    <SupportsAreaInventory>true</SupportsAreaInventory>
    to the inventory component definition to enable area inventory for that inventory.

    Please note that character inventories are not used in area inventory regardless of this setting.
     
Thread Status:
This last post in this thread was made more than 31 days old.